15476Slinton %{
2*22762Smckusick /*
3*22762Smckusick  * Copyright (c) 1982 Regents of the University of California.
4*22762Smckusick  * All rights reserved.  The Berkeley software License Agreement
5*22762Smckusick  * specifies the terms and conditions for redistribution.
6*22762Smckusick  */
75476Slinton 
8*22762Smckusick #ifndef lint
9*22762Smckusick static char sccsid[] = "@(#)token.l	5.1 (Berkeley) 06/07/85";
10*22762Smckusick #endif not lint
115476Slinton 
125476Slinton /*
135476Slinton  * Token definitions for pdx scanner.
145476Slinton  */
155476Slinton 
165476Slinton #include "defs.h"
175476Slinton #include "command.h"
185476Slinton #include "y.tab.h"
195624Slinton #include "main.h"
205476Slinton #include "symtab.h"
215476Slinton #include "sym.h"
225476Slinton #include "process.h"
235476Slinton #include "process/pxinfo.h"
245476Slinton 
255476Slinton char *initfile = ".pdxinit";
265476Slinton 
275476Slinton /*
285476Slinton  * This is a silly "lex" thing.
295476Slinton  */
305476Slinton 
315476Slinton #define yywrap()	(1)
325476Slinton 
335476Slinton /*
345476Slinton  * Override Lex default input macros.
355476Slinton  */
365476Slinton 
375476Slinton #undef  input
385476Slinton #undef  unput
395476Slinton 
405476Slinton #define unput(c)	ungetc(c, yyin)
415476Slinton 
425476Slinton %}
435476Slinton 
445476Slinton blank		[ \t]
455476Slinton white		{blank}+
465476Slinton alpha		[a-zA-Z]
475476Slinton digit		[0-9]
485476Slinton n		{digit}+
495476Slinton h		[0-9a-fA-F]+
505476Slinton e		(("e"|"E")("+"|"-")?{n})
515476Slinton alphanum	[a-zA-Z0-9]
525476Slinton ident		{alpha}{alphanum}*
535476Slinton filenm		[^ \t\n"<>!*"]+
545476Slinton qfilenm		{filenm}/":"
555476Slinton string		'[^']+'('[^']*')*
565476Slinton newline		"\n"
575476Slinton char		.
585476Slinton 
595476Slinton %Start file sh
605476Slinton 
615476Slinton %%
625476Slinton 
635476Slinton {white}		;
645476Slinton ^sh{white}.*$	{ BEGIN 0; yylval.y_string = &yytext[3]; return(SH); }
655476Slinton ^sh		{ BEGIN 0; yylval.y_string = NIL; return(SH); }
665476Slinton ^{ident}	{ return(findcmd(yytext)); }
675608Slinton <file>{filenm}	{ yylval.y_string = strdup(yytext); return(FILENAME); }
685608Slinton {qfilenm}	{ yylval.y_string = strdup(yytext); return(FILENAME); }
695476Slinton {n}?\.{n}{e}?	{ yylval.y_real = atof(yytext); return(REAL); }
705476Slinton 0{n}		{ yylval.y_long = octal(yytext); return(INT); }
715476Slinton 0x{h}		{ yylval.y_long = hex(yytext); return(INT); }
725476Slinton {n}		{ yylval.y_long = atol(yytext); return(INT); }
735476Slinton at		{ return(AT); }
745476Slinton {ident}		{ return(ident(yytext)); }
755476Slinton {string}	{ yylval.y_string = yytext; return(STRING); }
765476Slinton "%dp"		{ yylval.y_long = (long) DP; return(INT); }
775476Slinton {newline}	{ BEGIN 0; nlflag = TRUE; return('\n'); }
785476Slinton {char}		{ return(yylval.y_int = yytext[0]); }
795476Slinton 
805476Slinton %%
815476Slinton 
825476Slinton LOCAL SYMTAB *dbtab, *specialtab;
835476Slinton 
845476Slinton /*
855476Slinton  * Look for the given string in the debugger keyword table.
865476Slinton  * If it's there, return the associated token, otherwise report an error.
875476Slinton  */
885476Slinton 
895476Slinton LOCAL int findcmd(s)
905476Slinton char *s;
915476Slinton {
925476Slinton 	register SYM *p;
935476Slinton 
945476Slinton 	if ((p = st_lookup(dbtab, s)) == NIL) {
955476Slinton 		error("\"%s\" is not a command", s);
965476Slinton 	}
975476Slinton 	yylval.y_int = tokval(p);
985476Slinton 	switch (toknum(p)) {
995476Slinton 		case ALIAS:
1005476Slinton 		case DUMP:
1015476Slinton 		case EDIT:
1025476Slinton 		case CHFILE:
1035476Slinton 		case RUN:
1045476Slinton 		case SOURCE:
1055476Slinton 		case STATUS:
1065476Slinton 			BEGIN file;
1075476Slinton 			break;
1085476Slinton 
1095476Slinton 		default:
1105476Slinton 			/* do nothing */;
1115476Slinton 	}
1125476Slinton 	return(toknum(p));
1135476Slinton }
1145476Slinton 
1155476Slinton /*
1165476Slinton  * Look for a symbol, first in the special table (if, in, etc.)
1175476Slinton  * then in the symbol table.  If it's there, return the SYM pointer,
1185476Slinton  * otherwise it's an error.
1195476Slinton  */
1205476Slinton 
1215476Slinton LOCAL int ident(s)
1225476Slinton char *s;
1235476Slinton {
1245476Slinton 	register SYM *p;
1255476Slinton 
1265476Slinton 	if ((p = st_lookup(specialtab, s)) != NIL) {
1275476Slinton 		yylval.y_sym = p;
1285476Slinton 		return(toknum(p));
1295476Slinton 	}
1305476Slinton 	p = st_lookup(symtab, s);
1315476Slinton 	if (p == NIL) {
1325476Slinton 		if (strcmp(s, "nil") == 0) {
1335476Slinton 			yylval.y_long = 0L;
1345476Slinton 			return(INT);
1355476Slinton 		} else {
1365476Slinton 			error("\"%s\" is not defined", s);
1375476Slinton 		}
1385476Slinton 	}
1395476Slinton 	yylval.y_sym = p;
1405476Slinton 	return(NAME);
1415476Slinton }
1425476Slinton 
1435476Slinton /*
1445476Slinton  * Convert a string to octal.  No check that digits are less than 8.
1455476Slinton  */
1465476Slinton 
1475476Slinton LOCAL int octal(s)
1485476Slinton char *s;
1495476Slinton {
1505476Slinton 	register char *p;
1515476Slinton 	register int n;
1525476Slinton 
1535476Slinton 	n = 0;
1545476Slinton 	for (p = s; *p != '\0'; p++) {
1555476Slinton 		n = 8*n + (*p - '0');
1565476Slinton 	}
1575476Slinton 	return(n);
1585476Slinton }
1595476Slinton 
1605476Slinton /*
1615476Slinton  * Convert a string to hex.
1625476Slinton  */
1635476Slinton 
1645476Slinton LOCAL int hex(s)
1655476Slinton char *s;
1665476Slinton {
1675476Slinton 	register char *p;
1685476Slinton 	register int n;
1695476Slinton 
1705476Slinton 	n = 0;
1715476Slinton 	for (p = s+2; *p != '\0'; p++) {
1725476Slinton 		n *= 16;
1735476Slinton 		if (*p >= 'a' && *p <= 'f') {
1745476Slinton 			n += (*p - 'a' + 10);
1755476Slinton 		} else if (*p >= 'A' && *p <= 'F') {
1765476Slinton 			n += (*p - 'A' + 10);
1775476Slinton 		} else {
1785476Slinton 			n += (*p - '0');
1795476Slinton 		}
1805476Slinton 	}
1815476Slinton 	return(n);
1825476Slinton }
1835476Slinton 
1845476Slinton /*
1855476Slinton  * Initialize the debugger keyword table (dbtab) and special symbol
1865476Slinton  * table (specialtab).
1875476Slinton  */
1885476Slinton 
1895476Slinton #define db_keyword(nm, n)	make_keyword(dbtab, nm, n)
1905476Slinton #define sp_keyword(nm, n)	make_keyword(specialtab, nm, n)
1915476Slinton 
1925476Slinton lexinit()
1935476Slinton {
1945476Slinton 	dbtab = st_creat(150);
1955476Slinton 	db_keyword("alias", ALIAS);
1965476Slinton 	db_keyword("assign", ASSIGN);
1975476Slinton 	db_keyword("call", CALL);
1985476Slinton 	db_keyword("cont", CONT);
1995476Slinton 	db_keyword("delete", DELETE);
2005476Slinton 	db_keyword("dump", DUMP);
2015476Slinton 	db_keyword("edit", EDIT);
2025476Slinton 	db_keyword("file", CHFILE);
2035476Slinton 	db_keyword("gripe", GRIPE);
2045476Slinton 	db_keyword("help", HELP);
2055476Slinton 	db_keyword("list", LIST);
2065476Slinton 	db_keyword("next", NEXT);
2075476Slinton 	db_keyword("pi", REMAKE);
2085476Slinton 	db_keyword("print", PRINT);
2095476Slinton 	db_keyword("quit", QUIT);
2105476Slinton 	db_keyword("run", RUN);
2115476Slinton 	db_keyword("sh", SH);
2125476Slinton 	db_keyword("source", SOURCE);
2135476Slinton 	db_keyword("status", STATUS);
2145476Slinton 	db_keyword("step", STEP);
2155476Slinton 	db_keyword("stop", STOP);
2165476Slinton 	db_keyword("stopi", STOPI);
2175476Slinton 	db_keyword("trace", TRACE);
2185476Slinton 	db_keyword("tracei", TRACEI);
2195476Slinton 	db_keyword("whatis", WHATIS);
2205476Slinton 	db_keyword("where", WHERE);
2215476Slinton 	db_keyword("which", WHICH);
2225476Slinton 	db_keyword("xd", XD);
2235476Slinton 	db_keyword("xi", XI);
2245476Slinton 
2255476Slinton 	specialtab = st_creat(10);
2265476Slinton 	sp_keyword("div", DIV);
2275476Slinton 	sp_keyword("mod", MOD);
2285476Slinton 	sp_keyword("in", IN);
2295476Slinton 	sp_keyword("if", IF);
2305476Slinton 	sp_keyword("and", AND);
2315476Slinton 	sp_keyword("or", OR);
2325476Slinton }
2335476Slinton 
2345476Slinton /*
2355476Slinton  * Send an alias directive over to the symbol table manager.
2365476Slinton  */
2375476Slinton 
2385476Slinton alias(new, old)
2395476Slinton char *new, *old;
2405476Slinton {
2415476Slinton 	if (old == NIL) {
2425476Slinton 		print_alias(dbtab, new);
2435476Slinton 	} else {
2445476Slinton 		enter_alias(dbtab, new, old);
2455476Slinton 	}
2465476Slinton }
2475476Slinton 
2485476Slinton /*
2495476Slinton  * Input file management routines, "yyin" is Lex's idea of
2505476Slinton  * where the input comes from.
2515476Slinton  */
2525476Slinton 
2535476Slinton #define MAXINPUT 10
2545476Slinton 
2555476Slinton LOCAL FILE *infp[MAXINPUT];
2565476Slinton LOCAL FILE **curfp = &infp[0];
2575476Slinton 
2585476Slinton LOCAL BOOLEAN isnewfile;
2595624Slinton LOCAL BOOLEAN firsttime;
2605476Slinton 
2615476Slinton /*
2625476Slinton  * Initially, we set the input to the initfile if it exists.
2635476Slinton  * If it does exist, we play a game or two to avoid generating
2645476Slinton  * multiple prompts.
2655476Slinton  */
2665476Slinton 
2675476Slinton initinput()
2685476Slinton {
2695476Slinton 	FILE *fp;
2705476Slinton 
2715624Slinton 	firsttime = FALSE;
2725476Slinton 	fp = fopen(initfile, "r");
2735476Slinton 	if (fp != NIL) {
2745476Slinton 		fclose(fp);
2755476Slinton 		setinput(initfile);
2765624Slinton 		if (!option('r')) {
2775624Slinton 			firsttime = TRUE;
2785624Slinton 		}
2795476Slinton 	}
2805476Slinton 	nlflag = TRUE;
2815476Slinton }
2825476Slinton 
2835476Slinton /*
2845476Slinton  * Set the input to the named file.  It is expected that the file exists
2855476Slinton  * and is readable.
2865476Slinton  */
2875476Slinton 
2885476Slinton setinput(filename)
2895476Slinton char *filename;
2905476Slinton {
2915476Slinton 	register FILE *fp;
2925476Slinton 
2935476Slinton 	if ((fp = fopen(filename, "r")) == NIL) {
2945476Slinton 		error("can't open %s", filename);
2955476Slinton 	}
2965476Slinton 	if (curfp >= &infp[MAXINPUT]) {
2975476Slinton 		error("unreasonable input nesting on %s", filename);
2985476Slinton 	}
2995476Slinton 	*curfp++ = yyin;
3005476Slinton 	yyin = fp;
3015476Slinton 	isnewfile = TRUE;
3025476Slinton }
3035476Slinton 
3045476Slinton BOOLEAN isstdin()
3055476Slinton {
3065476Slinton 	return((BOOLEAN) (yyin == stdin));
3075476Slinton }
3085476Slinton 
3095476Slinton LOCAL int input()
3105476Slinton {
3115476Slinton 	register int c;
3125476Slinton 
3135476Slinton 	if (isnewfile) {
3145476Slinton 		isnewfile = FALSE;
3155476Slinton 		return('\n');
3165476Slinton 	}
3175476Slinton 	while ((c = getc(yyin)) == EOF) {
3185476Slinton 		if (curfp == &infp[0]) {
3195476Slinton 			return(0);
3205476Slinton 		} else {
3215476Slinton 			fclose(yyin);
3225476Slinton 			yyin = *--curfp;
3235476Slinton 			if (yyin == stdin) {
3245624Slinton 				if (firsttime) {
3255624Slinton 					firsttime = FALSE;
3265624Slinton 				} else {
3275624Slinton 					prompt();
3285624Slinton 				}
3295476Slinton 			}
3305476Slinton 		}
3315476Slinton 	}
3325476Slinton 	return(c);
3335476Slinton }
3345476Slinton 
3355476Slinton /*
3365476Slinton  * Handle an input string by stripping the quotes and converting
3375476Slinton  * two interior quotes to one.  Copy to newly allocated space and
3385476Slinton  * return a pointer to it.
3395476Slinton  *
3405476Slinton  * The handling of strings here is not particularly efficient,
3415476Slinton  * nor need it be.
3425476Slinton  */
3435476Slinton 
3445476Slinton LOCAL char *pstring(p)
3455476Slinton char *p;
3465476Slinton {
3475476Slinton 	int i, len;
3485476Slinton 	char *r, *newp;
3495476Slinton 
3505476Slinton 	len = strlen(p);
3515476Slinton 	r = newp = alloc(len - 2 + 1, char);
3525476Slinton 	for (i = 1; i < len - 1; i++) {
3535476Slinton 		if (p[i] == '\'' && p[i+1] == '\'') {
3545476Slinton 			i++;
3555476Slinton 		}
3565476Slinton 		*newp++ = p[i];
3575476Slinton 	}
3585476Slinton 	*newp = '\0';
3595476Slinton 	return(r);
3605476Slinton }
3615476Slinton 
3625476Slinton /*
3635476Slinton  * prompt for a command
3645476Slinton  */
3655476Slinton 
3665476Slinton prompt()
3675476Slinton {
3685476Slinton 	nlflag = FALSE;
3695476Slinton 	if (yyin == stdin) {
3705476Slinton 		printf("> ");
3715476Slinton 		fflush(stdout);
3725476Slinton 	}
3735476Slinton }
374