home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.ee.lbl.gov
/
2014.05.ftp.ee.lbl.gov.tar
/
ftp.ee.lbl.gov
/
bmd-1.0beta.tar.Z
/
bmd-1.0beta.tar
/
bmd-1.0beta
/
app
/
omtd
/
readline.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-17
|
7KB
|
363 lines
/*
* Copyright (c) 1990 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Lawrence Berkeley Laboratory,
* Berkeley, CA. The name of the University may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
* File: lexical.c
*
* String table routines for Prescript compiler.
* Van Jacobson, January, 1988
*/
/*
* Copyright (c) 1988 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Lawrence Berkeley Laboratory,
* Berkeley, CA. The name of the University may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static char rcsid[] =
"@(#) $Header: readline.c,v 1.3 91/01/13 20:14:14 mccanne Locked $ (LBL)";
static char copyright[] =
"Copyright (c) 1988, Regents of the University of California";
#endif lint
#include <stdio.h>
#include <sys/types.h>
#include "readline.h"
extern char *malloc();
extern char *realloc();
#define MODULUS 16001
static u_char *idTable[MODULUS];
static u_char *stringTable;
static u_char *stNext;
static int stSize = 2048;
static int stLeft = 2048;
rl_init()
{
/* get the initial string table space */
stNext = stringTable = (u_char *)malloc (stSize);
if (stringTable == 0)
error("out of memory");
}
/* "hashpjw" from Aho, Sethi & Ullman, p.436 */
static int
hash(str, len)
register u_char *str;
register int len;
{
register unsigned int h = 0, g;
while (--len >= 0) {
h = (h << 4) + *str++;
if (g = h & 0xf0000000) {
h = h ^ (g >> 24);
h = h ^ g;
}
}
return (h % MODULUS);
}
static char *
EnterString(str, len)
u_char *str;
int len;
{
register int h = hash (str, len);
while (idTable[h]) {
if (bcmp(str, idTable[h], len) == 0)
return (char *)idTable[h];
h = ++h % MODULUS;
}
/* didn't find string in table - add it */
if ((stLeft -= len + 1) <= 0) {
register u_char *cp = stringTable;
stLeft += stSize;
stSize *= 2;
stringTable = (u_char *)realloc(cp, stSize);
if (stringTable == 0)
error("out of memory");
if (cp != stringTable) {
/*
* realloc moved our table -- fix up the
* pointers in idTable.
*/
register int i = MODULUS;
register int j = stringTable - cp;
stNext += j;
for (i = 0; i < MODULUS; i++)
if (idTable[i])
idTable[i] += j;
}
}
idTable[h] = stNext;
strncpy(stNext, str, len);
stNext += len;
*stNext++ = 0;
return (char *)idTable[h];
}
#define MAXLINE 512
#define MAXTOKENS 256
struct token tokens[MAXTOKENS];
struct token *tok_vector[MAXTOKENS];
static int curtoken;
#define RESET_TOKEN curtoken = 0
#define NEXT_TOKEN &tokens[curtoken++]
char *
rl_id(p, cp)
struct token **p;
char *cp;
{
struct token *tp = NEXT_TOKEN;
char *str = cp;
while (isalpha(*cp) || *cp == '_' || isdigit(*cp))
++cp;
tp->t_id = TK_IDENT;
tp->t_str = EnterString(str, cp - str);
*p = tp;
return cp;
}
char *
intern(s)
char *s;
{
return EnterString(s, strlen(s));
}
/* Hex digit to integer. */
static inline int
xdtoi(c)
{
if (isdigit(c))
return c - '0';
else if (islower(c))
return c - 'a' + 10;
else
return c - 'A' + 10;
}
char *
rl_num(p, cp)
struct token **p;
char *cp;
{
struct token *tp = NEXT_TOKEN;
int m = 0, base;
float f, b;
tp = NEXT_TOKEN;
if (*cp == '0') {
if (cp[1] == 'x') {
base = 16;
cp += 2;
} else {
base = 8;
cp += 1;
}
} else
base = 10;
while (isxdigit(*cp))
m = base * m + xdtoi(*cp++);
if (*cp != '.') {
tp->t_id = TK_INT;
tp->t_int = m;
} else {
++cp;
f = m;
b = 0.1;
while (isdigit(*cp)) {
f += (*cp++ - '0') * b;
b *= 0.1;
}
tp->t_id = TK_REAL;
tp->t_real = f;
}
*p = tp;
return cp;
}
char *
rl_misc(p, cp)
struct token **p;
char *cp;
{
struct token *tp = NEXT_TOKEN;
tp->t_id = *cp++ & 0xff;
*p = tp;
return cp;
}
char *
rl_str(p, cp)
struct token **p;
char *cp;
{
char *str = ++cp;
struct token *tp = NEXT_TOKEN;
while (*cp != '"')
if (*cp == 0)
return 0;
else
++cp;
tp->t_id = TK_IDENT;
tp->t_str = EnterString(str, cp - str);
*p = tp;
return cp + 1;
}
char *
rl_scan(p, cp)
struct token **p;
char *cp;
{
while (*cp && isspace(*cp))
++cp;
if (isalpha(*cp))
return rl_id(p, cp);
if (isdigit(*cp) || *cp == '.')
return rl_num(p, cp);
if (*cp == '\"')
return rl_str(p, cp);
if (*cp == 0)
return 0;
return rl_misc(p, cp);
}
/*
* Read a line of input from 'f' and return the corresponding tokens
* in a null-teminated array.
*/
struct token *
readline(f, prompt)
FILE *f;
char *prompt;
{
struct token **p, *tp;
char line[MAXLINE];
if (prompt) {
printf("%s", prompt);
fflush(stdout);
}
RESET_TOKEN;
if (fgets(line, sizeof line, f) == 0) {
tp = NEXT_TOKEN;
tp->t_id = TK_EOF;
tp->next = 0;
} else {
char *cp = line;
p = &tp;
while (cp = rl_scan(p, cp))
p = &(*p)->next;
*p = 0;
}
return tp;
}
ptokens(tp)
struct token *tp;
{
for (; tp != 0; tp = tp->next) {
switch (tp->t_id) {
default:
printf("misc %d '%c'\n", tp->t_id,
isprint(tp->t_id) ? tp->t_id : '?');
break;
case TK_IDENT:
printf("ident: \"%s\"\n", tp->t_str);
break;
case TK_INT:
printf("int: %d 0x%x 0%o\n", tp->t_int,
tp->t_int, tp->t_int);
break;
case TK_REAL:
printf("real: %f\n", tp->t_real);
break;
case TK_EOF:
printf("eof\n");
break;
}
}
}
/* XXX Try yo look up if a name. */
u_long
tokint(tp)
struct token *tp;
{
if (tp->t_id != TK_INT)
return 0;
return tp->t_int;
}
char *
token_string(tp)
struct token *tp;
{
char buf[80], *cp = buf;
for (; tp != 0; tp = tp->next)
*cp++ = tp->t_id;
return EnterString(buf, cp - buf);
}