1
0
mirror of https://github.com/rfivet/uemacs.git synced 2024-12-25 10:36:34 -05:00

Make sure directive keywords are followed by EOS, comment or space separator.

This commit is contained in:
Renaud 2021-09-13 12:33:32 +08:00
parent eff9b64f1d
commit 991283b912

110
exec.c
View File

@ -29,19 +29,28 @@
static char *execstr = NULL ; /* pointer to string to execute */ static char *execstr = NULL ; /* pointer to string to execute */
boolean clexec = FALSE ; /* command line execution flag */ boolean clexec = FALSE ; /* command line execution flag */
/* Directive definitions */
#define DFORCE 0 /* Directive definitions */
#define DGOTO 1 #define DBREAK 0
#define DGOSUB 2 #define DELSE 1
#define DIF 3 #define DENDIF 2
#define DWHILE 4 #define DENDM 3
#define DBREAK 5 #define DENDWHILE 4
#define DELSE 6 #define DFORCE 5
#define DENDIF 7 #define DGOTO 6
#define DENDM 8 #define DGOSUB 7
#define DENDWHILE 9 #define DIF 8
#define DRETURN 10 #define DRETURN 9
#define DWHILE 10
/* directive name table: holds the names of all the directives.... */
static const char *dname[] = {
"break", "else", "endif", "endm", "endwhile",
"force", "goto", "gosub", "if", "return",
"while"
} ;
#define NUMDIRS ARRAY_SIZE( dname)
typedef struct caller { typedef struct caller {
@ -64,16 +73,6 @@ typedef struct while_block {
#define BTWHILE 1 #define BTWHILE 1
#define BTBREAK 2 #define BTBREAK 2
/* directive name table: holds the names of all the directives.... */
static const char *dname[] = {
"force", "goto", "gosub", "if", "while",
"break", "else", "endif", "endm", "endwhile",
"return"
} ;
#define NUMDIRS ARRAY_SIZE( dname)
static char golabel[ NSTRING] = "" ; /* current line to go to */ static char golabel[ NSTRING] = "" ; /* current line to go to */
static buffer_p bstore = NULL ; /* buffer to store macro text to */ static buffer_p bstore = NULL ; /* buffer to store macro text to */
static int storing_f = FALSE ; /* storing text to macro flag */ static int storing_f = FALSE ; /* storing text to macro flag */
@ -696,20 +695,28 @@ static int dobuf( buffer_p bp) {
caller_p returnto = NULL ; caller_p returnto = NULL ;
line_p lp = hlp->l_fp ; line_p lp = hlp->l_fp ;
for( ; lp != hlp ; lp = lp->l_fp) { for( ; lp != hlp ; lp = lp->l_fp) {
/* allocate eline and copy macro line to it */ /* turns macro line into a string pointed by eline */
int linlen = lp->l_used ; int length = lp->l_used ;
if( esize <= linlen) { if( length < lp->l_size) {
esize = linlen + 1 ; /* there is space for EOS, let's use the line */
einit = realloc( einit, esize) ; eline = lp->l_text ;
if( einit == NULL) { } else {
/* make a copy using (pre-)allocated storage */
if( esize <= length) {
esize = length + 1 ;
char *newbuf = realloc( einit, esize) ;
if( newbuf == NULL) {
status = mloutfail( "%%Out of Memory during macro execution") ; status = mloutfail( "%%Out of Memory during macro execution") ;
break ; break ;
} } else
einit = newbuf ;
} }
eline = einit ; eline = einit ;
memcpy( eline, lp->l_text, linlen) ; memcpy( eline, lp->l_text, length) ;
eline[ linlen] = 0 ; }
eline[ length] = 0 ;
#if DEBUGM #if DEBUGM
/* if $debug == TRUE, every line to execute /* if $debug == TRUE, every line to execute
@ -752,32 +759,27 @@ static int dobuf( buffer_p bp) {
/* Parse directives here.... */ /* Parse directives here.... */
if( *eline == '!') { if( *eline == '!') {
unsigned dirnum ; /* directive index */
/* Find out which directive this is */ /* Find out which directive this is */
++eline ; ++eline ;
for( dirnum = 0 ; dirnum < NUMDIRS ; dirnum++) int dirnum = NUMDIRS ;
if( !strncmp( eline, dname[ dirnum], strlen( dname[ dirnum]))) while( --dirnum >= 0) {
break ; length = strlen( dname[ dirnum]) ;
if( !strncmp( eline, dname[ dirnum], length )) {
eline += length ;
/* either EOS, comment, space separator or FAIL */
if( !*eline || *eline == ';' || *eline == '#')
;
else if( *eline == ' ' || *eline == '\t') {
eline += 1 ;
} else
dirnum = -1 ;
/* and bitch if it's illegal */ execstr = eline ; /* set source of token() and macarg() */
if( dirnum == NUMDIRS) {
status = mloutfail( "%%Unknown Directive") ;
break ; break ;
} }
}
/* now, execute directives */ /* now, execute directives */
/* skip past the directives that takes arguments */
if( dirnum <= DWHILE) {
while( *eline && *eline != ' ' && *eline != '\t')
++eline ;
while( *eline && (*eline == ' ' || *eline == '\t'))
++eline ;
execstr = eline ;
}
switch( dirnum) { switch( dirnum) {
case DENDM: case DENDM:
if( execlevel == 0) if( execlevel == 0)
@ -855,11 +857,11 @@ static int dobuf( buffer_p bp) {
/* grab label to jump to */ /* grab label to jump to */
eline = token( eline, golabel, sizeof golabel) ; eline = token( eline, golabel, sizeof golabel) ;
linlen = strlen( golabel) ; length = strlen( golabel) ;
for( glp = firstlbl ; glp != eolbl ; glp = glp->l_fp) { for( glp = firstlbl ; glp != eolbl ; glp = glp->l_fp) {
char c = *glp->l_text ; char c = *glp->l_text ;
if( (c == '*' || c == ':') if( (c == '*' || c == ':')
&& !strncmp( &glp->l_text[ 1], golabel, linlen)) { && !strncmp( &glp->l_text[ 1], golabel, length)) {
if( dirnum == DGOSUB) { if( dirnum == DGOSUB) {
caller_p cp = malloc( sizeof *cp) ; caller_p cp = malloc( sizeof *cp) ;
if( cp == NULL) { if( cp == NULL) {
@ -902,6 +904,10 @@ static int dobuf( buffer_p bp) {
case DFORCE: /* FORCE directive */ case DFORCE: /* FORCE directive */
if( execlevel == 0) if( execlevel == 0)
docmd( eline) ; /* execute ignoring returned status */ docmd( eline) ; /* execute ignoring returned status */
break ;
default:
status = mloutfail( "%%Unknown Directive") ;
} }
} else if( execlevel == 0) } else if( execlevel == 0)
status = docmd( eline) ; /* execute the statement */ status = docmd( eline) ; /* execute the statement */