From f8c405f5010a8475eb60af708f958f9ec0958d7c Mon Sep 17 00:00:00 2001 From: Renaud Fivet Date: Fri, 9 Jan 2015 17:53:29 +0800 Subject: [PATCH] Limit visibility of token types to eval. --- eval.c | 23 +- eval.h | 16 +- exec.c | 1548 ++++++++++++++++++++++++++++---------------------------- 3 files changed, 796 insertions(+), 791 deletions(-) diff --git a/eval.c b/eval.c index 0d11292..f09c139 100644 --- a/eval.c +++ b/eval.c @@ -34,6 +34,22 @@ #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) +/* Macro argument token types */ + +#define TKNUL 0 /* end-of-string */ +#define TKARG 1 /* interactive argument */ +#define TKBUF 2 /* buffer argument */ +#define TKVAR 3 /* user variables */ +#define TKENV 4 /* environment variables */ +#define TKFUN 5 /* function.... */ +#define TKDIR 6 /* directive */ +#define TKLBL 7 /* line label */ +#define TKLIT 8 /* numeric literal */ +#define TKSTR 9 /* quoted string literal */ +#define TKCMD 10 /* command name */ + +static int gettyp( char *token) ; + #if DEBUGM /* vars needed for macro debugging output */ char outline[ NSTRING] ; /* global string to hold debug line text */ @@ -1093,8 +1109,7 @@ char *i_to_a(int i) * * char *token; token to analyze */ -int gettyp(char *token) -{ +static int gettyp( char *token) { char c; /* first char in token */ /* grab the first char (this is all we need) */ @@ -1132,6 +1147,10 @@ int gettyp(char *token) } } +int is_it_cmd( char *token) { + return TKCMD == gettyp( token) ; +} + /* * find the value of a token * diff --git a/eval.h b/eval.h index 2a8d603..710b333 100644 --- a/eval.h +++ b/eval.h @@ -22,21 +22,7 @@ extern int flickcode ; /* do flicker supression? */ extern int rval ; /* return value of a subprocess */ extern long envram ; /* # of bytes current in use by malloc */ -/* Macro argument token types */ - -#define TKNUL 0 /* end-of-string */ -#define TKARG 1 /* interactive argument */ -#define TKBUF 2 /* buffer argument */ -#define TKVAR 3 /* user variables */ -#define TKENV 4 /* environment variables */ -#define TKFUN 5 /* function.... */ -#define TKDIR 6 /* directive */ -#define TKLBL 7 /* line label */ -#define TKLIT 8 /* numeric literal */ -#define TKSTR 9 /* quoted string literal */ -#define TKCMD 10 /* command name */ - -int gettyp( char *token) ; +int is_it_cmd( char *token) ; void varinit( void) ; int setvar( int f, int n) ; diff --git a/exec.c b/exec.c index 5864d79..7b72a88 100644 --- a/exec.c +++ b/exec.c @@ -1,13 +1,13 @@ /* exec.c -- implements exec.h */ #include "exec.h" -/* exec.c +/* exec.c * - * This file is for functions dealing with execution of - * commands, command lines, buffers, files and startup files. + * This file is for functions dealing with execution of + * commands, command lines, buffers, files and startup files. * - * written 1986 by Daniel Lawrence - * modified by Petri Kutvonen + * written 1986 by Daniel Lawrence + * modified by Petri Kutvonen */ #include @@ -27,25 +27,25 @@ #include "window.h" -char *execstr = NULL ; /* pointer to string to execute */ -boolean clexec = FALSE ; /* command line execution flag */ +char *execstr = NULL ; /* pointer to string to execute */ +boolean clexec = FALSE ; /* command line execution flag */ -/* Directive definitions */ +/* Directive definitions */ -#define DIF 0 -#define DELSE 1 -#define DENDIF 2 -#define DGOTO 3 -#define DRETURN 4 -#define DENDM 5 -#define DWHILE 6 -#define DENDWHILE 7 -#define DBREAK 8 -#define DFORCE 9 +#define DIF 0 +#define DELSE 1 +#define DENDIF 2 +#define DGOTO 3 +#define DRETURN 4 +#define DENDM 5 +#define DWHILE 6 +#define DENDWHILE 7 +#define DBREAK 8 +#define DFORCE 9 -#define NUMDIRS 10 +#define NUMDIRS 10 /* The !WHILE directive in the execution language needs to * stack references to pending whiles. These are stored linked @@ -53,40 +53,40 @@ boolean clexec = FALSE ; /* command line execution flag */ * the following structure. */ struct while_block { - struct line *w_begin; /* ptr to !while statement */ - struct line *w_end; /* ptr to the !endwhile statement */ - int w_type; /* block type */ - struct while_block *w_next; /* next while */ + struct line *w_begin; /* ptr to !while statement */ + struct line *w_end; /* ptr to the !endwhile statement */ + int w_type; /* block type */ + struct while_block *w_next; /* next while */ }; -#define BTWHILE 1 -#define BTBREAK 2 +#define BTWHILE 1 +#define BTBREAK 2 /* directive name table: - This holds the names of all the directives.... */ + This holds the names of all the directives.... */ static const char *dname[] = { - "if", "else", "endif", - "goto", "return", "endm", - "while", "endwhile", "break", - "force" + "if", "else", "endif", + "goto", "return", "endm", + "while", "endwhile", "break", + "force" }; -static char golabel[ NSTRING] = "" ; /* current line to go to */ -static int execlevel = 0 ; /* execution IF level */ -static struct buffer *bstore = NULL ; /* buffer to store macro text to */ -static int mstore = FALSE ; /* storing text to macro flag */ +static char golabel[ NSTRING] = "" ; /* current line to go to */ +static int execlevel = 0 ; /* execution IF level */ +static struct buffer *bstore = NULL ; /* buffer to store macro text to */ +static int mstore = FALSE ; /* storing text to macro flag */ static int dobuf( struct buffer *bp) ; static void freewhile( struct while_block *wp) ; void ue_system( const char *cmd) { - int ret ; + int ret ; - ret = system( cmd) ; - if( ret == -1) { - /* some actual handling needed here */ - } + ret = system( cmd) ; + if( ret == -1) { + /* some actual handling needed here */ + } } /* @@ -94,1129 +94,1129 @@ void ue_system( const char *cmd) { */ int namedcmd(int f, int n) { - fn_t kfunc; /* ptr to the requexted function to bind to */ + fn_t kfunc; /* ptr to the requexted function to bind to */ - /* prompt the user to type a named command */ - mlwrite(": "); + /* prompt the user to type a named command */ + mlwrite(": "); - /* and now get the function name to execute */ - kfunc = getname(); - if (kfunc == NULL) { - mlwrite("(No such function)"); - return FALSE; - } + /* and now get the function name to execute */ + kfunc = getname(); + if (kfunc == NULL) { + mlwrite("(No such function)"); + return FALSE; + } - /* and then execute the command */ - return kfunc(f, n); + /* and then execute the command */ + return kfunc(f, n); } static int docmd( char *cline) ; /* * execcmd: - * Execute a command line command to be typed in - * by the user + * Execute a command line command to be typed in + * by the user * - * int f, n; default Flag and Numeric argument + * int f, n; default Flag and Numeric argument */ int execcmd(int f, int n) { - int status; /* status return */ - char cmdstr[NSTRING]; /* string holding command to execute */ + int status; /* status return */ + char cmdstr[NSTRING]; /* string holding command to execute */ - /* get the line wanted */ - if ((status = mlreply(": ", cmdstr, NSTRING)) != TRUE) - return status; + /* get the line wanted */ + if ((status = mlreply(": ", cmdstr, NSTRING)) != TRUE) + return status; - execlevel = 0; - return docmd(cmdstr); + execlevel = 0; + return docmd(cmdstr); } /* * docmd: - * take a passed string as a command line and translate - * it to be executed as a command. This function will be - * used by execute-command-line and by all source and - * startup files. Lastflag/thisflag is also updated. + * take a passed string as a command line and translate + * it to be executed as a command. This function will be + * used by execute-command-line and by all source and + * startup files. Lastflag/thisflag is also updated. * - * format of the command line is: + * format of the command line is: * - * {# arg} {} + * {# arg} {} * - * char *cline; command line to execute + * char *cline; command line to execute */ static int docmd( char *cline) { - int f; /* default argument flag */ - int n; /* numeric repeat value */ - fn_t fnc; /* function to execute */ - int status; /* return status of function */ - boolean oldcle ; /* old contents of clexec flag */ - char *oldestr; /* original exec string */ - char tkn[NSTRING]; /* next token off of command line */ + int f; /* default argument flag */ + int n; /* numeric repeat value */ + fn_t fnc; /* function to execute */ + int status; /* return status of function */ + boolean oldcle ; /* old contents of clexec flag */ + char *oldestr; /* original exec string */ + char tkn[NSTRING]; /* next token off of command line */ - /* if we are scanning and not executing..go back here */ - if (execlevel) - return TRUE; + /* if we are scanning and not executing..go back here */ + if (execlevel) + return TRUE; - oldestr = execstr; /* save last ptr to string to execute */ - execstr = cline; /* and set this one as current */ + oldestr = execstr; /* save last ptr to string to execute */ + execstr = cline; /* and set this one as current */ - /* first set up the default command values */ - f = FALSE; - n = 1; - lastflag = thisflag; - thisflag = 0; + /* first set up the default command values */ + f = FALSE; + n = 1; + lastflag = thisflag; + thisflag = 0; - status = macarg( tkn, sizeof tkn) ; - if( status != TRUE) { /* and grab the first token */ - execstr = oldestr; - return status; - } + status = macarg( tkn, sizeof tkn) ; + if( status != TRUE) { /* and grab the first token */ + execstr = oldestr; + return status; + } - /* process leadin argument */ - if (gettyp(tkn) != TKCMD) { - f = TRUE; - strcpy(tkn, getval(tkn)); - n = atoi(tkn); + /* process leadin argument */ + if( !is_it_cmd( tkn)) { + f = TRUE; + strcpy(tkn, getval(tkn)); + n = atoi(tkn); - /* and now get the command to execute */ - status = macarg( tkn, sizeof tkn) ; - if( status != TRUE) { - execstr = oldestr; - return status; - } - } + /* and now get the command to execute */ + status = macarg( tkn, sizeof tkn) ; + if( status != TRUE) { + execstr = oldestr; + return status; + } + } - /* and match the token to see if it exists */ - if ((fnc = fncmatch(tkn)) == NULL) { - mlwrite("(No such Function)"); - execstr = oldestr; - return FALSE; - } + /* and match the token to see if it exists */ + if ((fnc = fncmatch(tkn)) == NULL) { + mlwrite("(No such Function)"); + execstr = oldestr; + return FALSE; + } - /* save the arguments and go execute the command */ - oldcle = clexec; /* save old clexec flag */ - clexec = TRUE; /* in cline execution */ - status = (*fnc) (f, n); /* call the function */ - cmdstatus = status; /* save the status */ - clexec = oldcle; /* restore clexec flag */ - execstr = oldestr; - return status; + /* save the arguments and go execute the command */ + oldcle = clexec; /* save old clexec flag */ + clexec = TRUE; /* in cline execution */ + status = (*fnc) (f, n); /* call the function */ + cmdstatus = status; /* save the status */ + clexec = oldcle; /* restore clexec flag */ + execstr = oldestr; + return status; } /* * token: - * chop a token off a string - * return a pointer past the token + * chop a token off a string + * return a pointer past the token * - * char *src, *tok; source string, destination token string - * int size; maximum size of token + * char *src, *tok; source string, destination token string + * int size; maximum size of token */ char *token(char *src, char *tok, int size) { - int quotef; /* is the current string quoted? */ - char c; /* temporary character */ + int quotef; /* is the current string quoted? */ + char c; /* temporary character */ - /* first scan past any whitespace in the source string */ - while (*src == ' ' || *src == '\t') - ++src; + /* first scan past any whitespace in the source string */ + while (*src == ' ' || *src == '\t') + ++src; - /* scan through the source string */ - quotef = FALSE; - while (*src) { - /* process special characters */ - if (*src == '~') { - ++src; - if (*src == 0) - break; - switch (*src++) { - case 'r': - c = 13; - break; - case 'n': - c = 10; - break; - case 't': - c = 9; - break; - case 'b': - c = 8; - break; - case 'f': - c = 12; - break; - default: - c = *(src - 1); - } - if (--size > 0) { - *tok++ = c; - } - } else { - /* check for the end of the token */ - if (quotef) { - if (*src == '"') - break; - } else { - if (*src == ' ' || *src == '\t') - break; - } + /* scan through the source string */ + quotef = FALSE; + while (*src) { + /* process special characters */ + if (*src == '~') { + ++src; + if (*src == 0) + break; + switch (*src++) { + case 'r': + c = 13; + break; + case 'n': + c = 10; + break; + case 't': + c = 9; + break; + case 'b': + c = 8; + break; + case 'f': + c = 12; + break; + default: + c = *(src - 1); + } + if (--size > 0) { + *tok++ = c; + } + } else { + /* check for the end of the token */ + if (quotef) { + if (*src == '"') + break; + } else { + if (*src == ' ' || *src == '\t') + break; + } - /* set quote mode if quote found */ - if (*src == '"') - quotef = TRUE; + /* set quote mode if quote found */ + if (*src == '"') + quotef = TRUE; - /* record the character */ - c = *src++; - if (--size > 0) - *tok++ = c; - } - } + /* record the character */ + c = *src++; + if (--size > 0) + *tok++ = c; + } + } - /* terminate the token and exit */ - if (*src) - ++src; - *tok = 0; - return src; + /* terminate the token and exit */ + if (*src) + ++src; + *tok = 0; + return src; } /* * get a macro line argument * - * char *tok; buffer to place argument + * char *tok; buffer to place argument */ int macarg( char *tok, int toksz) { - boolean savcle ; /* buffer to store original clexec */ - int status; + boolean savcle ; /* buffer to store original clexec */ + int status; - savcle = clexec; /* save execution mode */ - clexec = TRUE; /* get the argument */ - status = nextarg("", tok, toksz, ctoec('\n')); - clexec = savcle; /* restore execution mode */ - return status; + savcle = clexec; /* save execution mode */ + clexec = TRUE; /* get the argument */ + status = nextarg("", tok, toksz, ctoec('\n')); + clexec = savcle; /* restore execution mode */ + return status; } /* * nextarg: - * get the next argument + * get the next argument * - * const char *prompt; prompt to use if we must be interactive - * char *buffer; buffer to put token into - * int size; size of the buffer - * int terminator; terminating char to be used on interactive fetch + * const char *prompt; prompt to use if we must be interactive + * char *buffer; buffer to put token into + * int size; size of the buffer + * int terminator; terminating char to be used on interactive fetch */ int nextarg(const char *prompt, char *buffer, int size, int terminator) { - /* if we are interactive, go get it! */ - if (clexec == FALSE) - return getstring(prompt, buffer, size, terminator); + /* if we are interactive, go get it! */ + if (clexec == FALSE) + return getstring(prompt, buffer, size, terminator); - /* grab token and advance past */ - execstr = token(execstr, buffer, size); + /* grab token and advance past */ + execstr = token(execstr, buffer, size); - /* evaluate it */ - strncpy( buffer, getval( buffer), size - 1) ; - buffer[ size - 1] = '\0' ; - return TRUE; + /* evaluate it */ + strncpy( buffer, getval( buffer), size - 1) ; + buffer[ size - 1] = '\0' ; + return TRUE; } /* * storemac: - * Set up a macro buffer and flag to store all - * executed command lines there + * Set up a macro buffer and flag to store all + * executed command lines there * - * int f; default flag - * int n; macro number to use + * int f; default flag + * int n; macro number to use */ int storemac(int f, int n) { - struct buffer *bp; /* pointer to macro buffer */ - bname_t bname ; /* name of buffer to use */ + struct buffer *bp; /* pointer to macro buffer */ + bname_t bname ; /* name of buffer to use */ - /* must have a numeric argument to this function */ - if (f == FALSE) { - mlwrite("No macro specified"); - return FALSE; - } + /* must have a numeric argument to this function */ + if (f == FALSE) { + mlwrite("No macro specified"); + return FALSE; + } - /* range check the macro number */ - if (n < 1 || n > 40) { - mlwrite("Macro number out of range"); - return FALSE; - } + /* range check the macro number */ + if (n < 1 || n > 40) { + mlwrite("Macro number out of range"); + return FALSE; + } - /* construct the macro buffer name */ - strcpy(bname, "*Macro xx*"); - bname[7] = '0' + (n / 10); - bname[8] = '0' + (n % 10); + /* construct the macro buffer name */ + strcpy(bname, "*Macro xx*"); + bname[7] = '0' + (n / 10); + bname[8] = '0' + (n % 10); - /* set up the new macro buffer */ - if ((bp = bfind(bname, TRUE, BFINVS)) == NULL) { - mlwrite("Can not create macro"); - return FALSE; - } + /* set up the new macro buffer */ + if ((bp = bfind(bname, TRUE, BFINVS)) == NULL) { + mlwrite("Can not create macro"); + return FALSE; + } - /* and make sure it is empty */ - bclear(bp); + /* and make sure it is empty */ + bclear(bp); - /* and set the macro store pointers to it */ - mstore = TRUE; - bstore = bp; - return TRUE; + /* and set the macro store pointers to it */ + mstore = TRUE; + bstore = bp; + return TRUE; } -#if PROC +#if PROC /* * storeproc: - * Set up a procedure buffer and flag to store all - * executed command lines there + * Set up a procedure buffer and flag to store all + * executed command lines there * - * int f; default flag - * int n; macro number to use + * int f; default flag + * int n; macro number to use */ int storeproc(int f, int n) { - struct buffer *bp; /* pointer to macro buffer */ - int status; /* return status */ - bname_t bname ; /* name of buffer to use */ + struct buffer *bp; /* pointer to macro buffer */ + int status; /* return status */ + bname_t bname ; /* name of buffer to use */ - /* a numeric argument means its a numbered macro */ - if (f == TRUE) - return storemac(f, n); + /* a numeric argument means its a numbered macro */ + if (f == TRUE) + return storemac(f, n); - /* get the name of the procedure */ - if ((status = - mlreply("Procedure name: ", &bname[1], sizeof bname - 2)) != TRUE) - return status; + /* get the name of the procedure */ + if ((status = + mlreply("Procedure name: ", &bname[1], sizeof bname - 2)) != TRUE) + return status; - /* construct the macro buffer name */ - bname[0] = '*'; - strcat(bname, "*"); + /* construct the macro buffer name */ + bname[0] = '*'; + strcat(bname, "*"); - /* set up the new macro buffer */ - if ((bp = bfind(bname, TRUE, BFINVS)) == NULL) { - mlwrite("Can not create macro"); - return FALSE; - } + /* set up the new macro buffer */ + if ((bp = bfind(bname, TRUE, BFINVS)) == NULL) { + mlwrite("Can not create macro"); + return FALSE; + } - /* and make sure it is empty */ - bclear(bp); + /* and make sure it is empty */ + bclear(bp); - /* and set the macro store pointers to it */ - mstore = TRUE; - bstore = bp; - return TRUE; + /* and set the macro store pointers to it */ + mstore = TRUE; + bstore = bp; + return TRUE; } /* * execproc: - * Execute a procedure + * Execute a procedure * - * int f, n; default flag and numeric arg + * int f, n; default flag and numeric arg */ int execproc(int f, int n) { - struct buffer *bp; /* ptr to buffer to execute */ - int status; /* status return */ - char bufn[NBUFN + 2]; /* name of buffer to execute */ + struct buffer *bp; /* ptr to buffer to execute */ + int status; /* status return */ + char bufn[NBUFN + 2]; /* name of buffer to execute */ - /* find out what buffer the user wants to execute */ - if ((status = - mlreply("Execute procedure: ", &bufn[1], NBUFN)) != TRUE) - return status; + /* find out what buffer the user wants to execute */ + if ((status = + mlreply("Execute procedure: ", &bufn[1], NBUFN)) != TRUE) + return status; - /* construct the buffer name */ - bufn[0] = '*'; - strcat(bufn, "*"); + /* construct the buffer name */ + bufn[0] = '*'; + strcat(bufn, "*"); - /* find the pointer to that buffer */ - if ((bp = bfind(bufn, FALSE, 0)) == NULL) { - mlwrite("No such procedure"); - return FALSE; - } + /* find the pointer to that buffer */ + if ((bp = bfind(bufn, FALSE, 0)) == NULL) { + mlwrite("No such procedure"); + return FALSE; + } - /* and now execute it as asked */ - while (n-- > 0) - if ((status = dobuf(bp)) != TRUE) - return status; - return TRUE; + /* and now execute it as asked */ + while (n-- > 0) + if ((status = dobuf(bp)) != TRUE) + return status; + return TRUE; } #endif /* * execbuf: - * Execute the contents of a buffer of commands + * Execute the contents of a buffer of commands * - * int f, n; default flag and numeric arg + * int f, n; default flag and numeric arg */ int execbuf(int f, int n) { - struct buffer *bp; /* ptr to buffer to execute */ - int status; /* status return */ - bname_t bufn ; /* name of buffer to execute */ + struct buffer *bp; /* ptr to buffer to execute */ + int status; /* status return */ + bname_t bufn ; /* name of buffer to execute */ - /* find out what buffer the user wants to execute */ - if ((status = mlreply("Execute buffer: ", bufn, sizeof bufn)) != TRUE) - return status; + /* find out what buffer the user wants to execute */ + if ((status = mlreply("Execute buffer: ", bufn, sizeof bufn)) != TRUE) + return status; - /* find the pointer to that buffer */ - if ((bp = bfind(bufn, FALSE, 0)) == NULL) { - mlwrite("No such buffer"); - return FALSE; - } + /* find the pointer to that buffer */ + if ((bp = bfind(bufn, FALSE, 0)) == NULL) { + mlwrite("No such buffer"); + return FALSE; + } - /* and now execute it as asked */ - while (n-- > 0) - if ((status = dobuf(bp)) != TRUE) - return status; - return TRUE; + /* and now execute it as asked */ + while (n-- > 0) + if ((status = dobuf(bp)) != TRUE) + return status; + return TRUE; } /* * dobuf: - * execute the contents of the buffer pointed to - * by the passed BP + * execute the contents of the buffer pointed to + * by the passed BP * - * Directives start with a "!" and include: + * Directives start with a "!" and include: * - * !endm End a macro - * !if (cond) conditional execution - * !else - * !endif - * !return Return (terminating current macro) - * !goto