From c9541a9d4f01e190ffefc20ce07896c7f04d9557 Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Wed, 19 Jul 2017 15:27:06 -0500 Subject: [PATCH] Fixed IREPT blocks to not corrupt memory on 64-bit hosts. --- direct.c | 75 +++++++++++++++++++++++++ direct.h | 4 ++ macro.c | 95 ++++++++++++++++--------------- macro.h | 2 +- procln.c | 91 +++++------------------------- procln.h | 7 +-- rmac.c | 4 +- symbol.h | 29 +++++----- token.c | 165 ++++++++++++++++++++++++++++++------------------------ token.h | 12 ++-- version.h | 4 +- 11 files changed, 264 insertions(+), 224 deletions(-) diff --git a/direct.c b/direct.c index 5714def..c9a82d9 100644 --- a/direct.c +++ b/direct.c @@ -1843,3 +1843,78 @@ int d_opt(void) return OK; } + +// +// .if, Start conditional assembly +// +int d_if(void) +{ + WORD eattr; + VALUE eval; + SYM * esym; + IFENT * rif = f_ifent; + + // Alloc an IFENTRY + if (rif == NULL) + rif = (IFENT *)malloc(sizeof(IFENT)); + else + f_ifent = rif->if_prev; + + rif->if_prev = ifent; + ifent = rif; + + if (!disabled) + { + if (expr(exprbuf, &eval, &eattr, &esym) != OK) + return 0; + + if ((eattr & DEFINED) == 0) + return error(undef_error); + + disabled = !eval; + } + + rif->if_state = (WORD)disabled; + return 0; +} + + +// +// .else, Do alternate case for .if +// +int d_else(void) +{ + IFENT * rif = ifent; + + if (rif->if_prev == NULL) + return error("mismatched .else"); + + if (disabled) + disabled = rif->if_prev->if_state; + else + disabled = 1; + + rif->if_state = (WORD)disabled; + return 0; +} + + +// +// .endif, End of conditional assembly block +// This is also called by fpop() to pop levels of IFENTs in case a macro or +// include file exits early with `exitm' or `end'. +// +int d_endif(void) +{ + IFENT * rif = ifent; + + if (rif->if_prev == NULL) + return error("mismatched .endif"); + + ifent = rif->if_prev; + disabled = rif->if_prev->if_state; + rif->if_prev = f_ifent; + f_ifent = rif; + return 0; +} + diff --git a/direct.h b/direct.h index a4ab5ba..654c580 100644 --- a/direct.h +++ b/direct.h @@ -29,5 +29,9 @@ int d_phrase(void); int d_dphrase(void); int d_qphrase(void); +int d_if(void); +int d_else(void); +int d_endif(void); + #endif // __DIRECT_H__ diff --git a/macro.c b/macro.c index 23d8797..6b592d1 100644 --- a/macro.c +++ b/macro.c @@ -26,8 +26,8 @@ static LONG macuniq; // Unique-per-macro number static SYM * curmac; // Macro currently being defined static VALUE argno; // Formal argument count -static LONG * firstrpt; // First .rept line -static LONG * nextrpt; // Last .rept line +static LLIST * firstrpt; // First .rept line +static LLIST * nextrpt; // Last .rept line static int rptlevel; // .rept nesting level // Function prototypes @@ -55,7 +55,6 @@ void InitMacro(void) int ExitMacro(void) { WARNING(!!! Bad macro exiting !!!) - /* This is a problem. Currently, the argument logic just keeps the current arguments and doesn't save anything if a new macro is called in the middle @@ -91,12 +90,10 @@ of another (nested macros). Need to fix that somehow. // int defmac2(char * argname) { - SYM * arg; - if (lookup(argname, MACARG, (int)curmac->sattr) != NULL) return error("multiple formal argument definition"); - arg = NewSymbol(argname, MACARG, (int)curmac->sattr); + SYM * arg = NewSymbol(argname, MACARG, (int)curmac->sattr); arg->svalue = argno++; return OK; @@ -154,14 +151,14 @@ safety features of the language. Seems like we can do better here. #else if (curmac->lineList == NULL) { - curmac->lineList = malloc(sizeof(struct LineList)); + curmac->lineList = malloc(sizeof(LLIST)); curmac->lineList->next = NULL; curmac->lineList->line = strdup(ln); curmac->last = curmac->lineList; } else { - curmac->last->next = malloc(sizeof(struct LineList)); + curmac->last->next = malloc(sizeof(LLIST)); curmac->last->next->next = NULL; curmac->last->next->line = strdup(ln); curmac->last = curmac->last->next; @@ -227,53 +224,63 @@ int DefineMacro(void) // // Add lines to a .rept definition // -int defr1(char * ln, int kwno) +int defr1(char * line, int kwno) { if (list_flag) { - listeol(); // Flush previous source line - lstout('#'); // Mark this a 'rept' block + listeol(); // Flush previous source line + lstout('#'); // Mark this a 'rept' block } - switch (kwno) + if (kwno == 0) // .endr { - case 0: // .endr if (--rptlevel == 0) return 0; - - break; - case 1: // .rept - rptlevel++; } + else if (kwno == 1) // .rept + rptlevel++; +//DEBUG { printf(" defr1: line=\"%s\", kwno=%d, rptlevel=%d\n", line, kwno, rptlevel); } + +#if 0 //MORE stupidity here... WARNING("!!! Casting (char *) as LONG !!!") // Allocate length of line + 1('\0') + LONG - LONG len = strlen(ln) + 1 + sizeof(LONG); - LONG * p = (LONG *)malloc(len); + LONG * p = (LONG *)malloc(strlen(line) + 1 + sizeof(LONG)); *p = 0; - - strcpy((char *)(p + 1), ln); + strcpy((char *)(p + 1), line); if (nextrpt == NULL) - { firstrpt = p; // First line of rept statement - } else - { *nextrpt = (LONG)p; - } nextrpt = p; +#else + if (firstrpt == NULL) + { + firstrpt = malloc(sizeof(LLIST)); + firstrpt->next = NULL; + firstrpt->line = strdup(line); + nextrpt = firstrpt; + } + else + { + nextrpt->next = malloc(sizeof(LLIST)); + nextrpt->next->next = NULL; + nextrpt->next->line = strdup(line); + nextrpt = nextrpt->next; + } +#endif return rptlevel; } // -// Define a .rept block, this gets hairy because they can be nested +// Handle a .rept block; this gets hairy because they can be nested // -int DefineRept(void) +int HandleRept(void) { VALUE eval; @@ -287,6 +294,7 @@ int DefineRept(void) rptlevel = 1; LNCatch(defr1, "endr rept "); +//DEBUG { printf("HandleRept: firstrpt=$%X\n", firstrpt); } // Alloc and init input object if (firstrpt) { @@ -303,12 +311,11 @@ int DefineRept(void) // // Hand off lines of text to the function 'lnfunc' until a line containing one -// of the directives in 'dirlist' is encountered. Return the number of the -// keywords encountered (0..n) +// of the directives in 'dirlist' is encountered. // -// 'dirlist' contains null-seperated terminated keywords. A final null -// terminates the list. Directives are compared to the keywords without regard -// to case. +// 'dirlist' contains space-separated terminated keywords. A final space +// terminates the list. Directives are case-insensitively compared to the +// keywords. // // If 'lnfunc' is NULL, then lines are simply skipped. // If 'lnfunc' returns an error, processing is stopped. @@ -319,13 +326,10 @@ int DefineRept(void) // static int LNCatch(int (* lnfunc)(), char * dirlist) { - char * p; - int k; - if (lnfunc != NULL) lnsave++; // Tell tokenizer to keep lines - for(;;) + while (1) { if (TokenizeLine() == TKEOF) { @@ -336,25 +340,28 @@ static int LNCatch(int (* lnfunc)(), char * dirlist) // Test for end condition. Two cases to handle: // // symbol: - p = NULL; - k = -1; + char * p = NULL; + int k = -1; if (*tok == SYMBOL) { + // A string followed by a colon or double colon is a symbol and + // *not* a directive, see if we can find the directive after it if ((tok[2] == ':' || tok[2] == DCOLON)) { - if (tok[3] == SYMBOL) // label: symbol + if (tok[3] == SYMBOL) p = string[tok[4]]; } else { - p = string[tok[1]]; // Symbol + // Otherwise, just grab the directive + p = string[tok[1]]; } } if (p != NULL) { - if (*p == '.') // ignore leading '.'s + if (*p == '.') // Ignore leading periods p++; k = KWMatch(p, dirlist); @@ -366,7 +373,7 @@ static int LNCatch(int (* lnfunc)(), char * dirlist) if (lnfunc != NULL) k = (*lnfunc)(lnbuf, k); - if (!k) + if (k == 0) break; } @@ -378,8 +385,8 @@ static int LNCatch(int (* lnfunc)(), char * dirlist) // -// See if the string `kw' matches one of the keywords in `kwlist'. If so, -// return the number of the keyword matched. Return -1 if there was no match. +// See if the string `kw' matches one of the keywords in `kwlist'. If so, +// return the number of the keyword matched. Return -1 if there was no match. // Strings are compared without regard for case. // static int KWMatch(char * kw, char * kwlist) diff --git a/macro.h b/macro.h index 1a06713..0062314 100644 --- a/macro.h +++ b/macro.h @@ -19,7 +19,7 @@ extern TOKEN * argPtrs[]; void InitMacro(void); int ExitMacro(void); int DefineMacro(void); -int DefineRept(void); +int HandleRept(void); int InvokeMacro(SYM *, WORD); #endif // __MACRO_H__ diff --git a/procln.c b/procln.c index 600aaa0..ab6cf3a 100644 --- a/procln.c +++ b/procln.c @@ -36,8 +36,8 @@ IFENT * ifent; // Current ifent static IFENT ifent0; // Root ifent -static IFENT * f_ifent; // Freelist of ifents -static int disabled; // Assembly conditionally disabled +IFENT * f_ifent; // Freelist of ifents +int disabled; // Assembly conditionally disabled int just_bss; // 1, ds.b in microprocessor mode VALUE pcloc; // Value of "PC" at beginning of line SYM * lab_sym; // Label on line (or NULL) @@ -294,13 +294,16 @@ as68label: { case MN_IF: d_if(); - goto loop; + goto loop; + case MN_ELSE: d_else(); goto loop; + case MN_ENDIF: d_endif(); goto loop; + case MN_IIF: // .iif --- immediate if if (disabled || expr(exprbuf, &eval, &eattr, &esym) != OK) goto loop; @@ -321,6 +324,7 @@ as68label: goto loop; goto loop1; + case MN_MACRO: // .macro --- macro definition if (!disabled) { @@ -332,6 +336,7 @@ as68label: } goto loop; + case MN_EXITM: // .exitm --- exit macro case MN_ENDM: // .endm --- same as .exitm if (!disabled) @@ -343,6 +348,7 @@ as68label: } goto loop; + case MN_REPT: if (!disabled) { @@ -353,10 +359,11 @@ as68label: goto loop; } - DefineRept(); + HandleRept(); } goto loop; + case MN_ENDR: if (!disabled) error("mis-nested .endr"); @@ -775,6 +782,8 @@ int HandleLabel(char * label, int labelType) lab_sym = symbol; + // Yes, our CS professors told us to write checks for equality this way, + // but damn, it hurts my brain every time I look at it. :-/ if (0 == environment) curenv++; @@ -791,77 +800,3 @@ int HandleLabel(char * label, int labelType) } -// -// .if, Start conditional assembly -// -int d_if(void) -{ - IFENT * rif; - WORD eattr; - VALUE eval; - SYM * esym; - - // Alloc an IFENTRY - if ((rif = f_ifent) == NULL) - rif = (IFENT *)malloc(sizeof(IFENT)); - else - f_ifent = rif->if_prev; - - rif->if_prev = ifent; - ifent = rif; - - if (!disabled) - { - if (expr(exprbuf, &eval, &eattr, &esym) != OK) - return 0; - - if ((eattr & DEFINED) == 0) - return error(undef_error); - - disabled = !eval; - } - - rif->if_state = (WORD)disabled; - return 0; -} - - -// -// .else, Do alternate case for .if -// -int d_else(void) -{ - IFENT * rif = ifent; - - if (rif->if_prev == NULL) - return error("mismatched .else"); - - if (disabled) - disabled = rif->if_prev->if_state; - else - disabled = 1; - - rif->if_state = (WORD)disabled; - return 0; -} - - -// -// .endif, End of conditional assembly block -// This is also called by fpop() to pop levels of IFENTs in case a macro or -// include file exits early with `exitm' or `end'. -// -int d_endif (void) -{ - IFENT * rif = ifent; - - if (rif->if_prev == NULL) - return error("mismatched .endif"); - - ifent = rif->if_prev; - disabled = rif->if_prev->if_state; - rif->if_prev = f_ifent; - f_ifent = rif; - return 0; -} - diff --git a/procln.h b/procln.h index c611e5b..c8c89cb 100644 --- a/procln.h +++ b/procln.h @@ -13,7 +13,6 @@ #include "token.h" // Exported variables -extern IFENT * ifent; extern const char comma_error[]; extern const char locgl_error[]; extern const char syntax_error[]; @@ -22,13 +21,13 @@ extern int just_bss; extern VALUE pcloc; extern SYM * lab_sym; extern LONG amsktab[]; +extern IFENT * ifent; +extern IFENT * f_ifent; +extern int disabled; // Exported functions void InitLineProcessor(void); void Assemble(void); -int d_if(void); -int d_else(void); -int d_endif(void); #endif // __PROCLN_H__ diff --git a/rmac.c b/rmac.c index 739925c..3dc0f07 100644 --- a/rmac.c +++ b/rmac.c @@ -401,7 +401,7 @@ int Process(int argc, char ** argv) default: printf("-p: syntax error\n"); - ++errcnt; + errcnt++; return errcnt; } @@ -449,7 +449,7 @@ int Process(int argc, char ** argv) if (pagelen < 10) { printf("-y: bad page length\n"); - ++errcnt; + errcnt++; return errcnt; } diff --git a/symbol.h b/symbol.h index b7350e0..3dc930f 100644 --- a/symbol.h +++ b/symbol.h @@ -12,9 +12,10 @@ #include // Line lists -struct LineList +#define LLIST struct _llist +LLIST { - struct LineList * next; + LLIST * next; uint8_t * line; }; @@ -22,18 +23,18 @@ struct LineList #define SYM struct _sym SYM { - SYM * snext; // * -> Next symbol on hash-chain - SYM * sorder; // * -> Next sym in order of reference - SYM * sdecl; // * -> Next sym in order of declaration - uint8_t stype; // Symbol type - uint16_t sattr; // Attribute bits - uint32_t sattre; // Extended attribute bits - uint16_t senv; // Enviroment number - uint32_t svalue; // Symbol value - uint8_t * sname; // * -> Symbol's print-name - struct LineList * lineList; // * -> Macro's linked list of lines - struct LineList * last; // * -> end of macro linked list - uint32_t uid; // Symbol's unique ID + SYM * snext; // * -> Next symbol on hash-chain + SYM * sorder; // * -> Next sym in order of reference + SYM * sdecl; // * -> Next sym in order of declaration + uint8_t stype; // Symbol type + uint16_t sattr; // Attribute bits + uint32_t sattre; // Extended attribute bits + uint16_t senv; // Enviroment number + uint32_t svalue; // Symbol value + uint8_t * sname; // * -> Symbol's print-name + LLIST * lineList; // * -> Macro's linked list of lines + LLIST * last; // * -> end of macro linked list + uint32_t uid; // Symbol's unique ID }; // Exported variables diff --git a/token.c b/token.c index 6f42cca..27eedc3 100644 --- a/token.c +++ b/token.c @@ -282,6 +282,7 @@ INOBJ * a_inobj(int typ) inobj->inobj.ifile = ifile; break; + case SRC_IMACRO: // Alloc and init an IMACRO if (f_imacro == NULL) imacro = malloc(sizeof(IMACRO)); @@ -293,6 +294,7 @@ INOBJ * a_inobj(int typ) inobj->inobj.imacro = imacro; break; + case SRC_IREPT: // Alloc and init an IREPT inobj->inobj.irept = malloc(sizeof(IREPT)); DEBUG { printf("alloc IREPT\n"); } @@ -680,7 +682,7 @@ char * GetNextMacroLine(void) { IMACRO * imacro = cur_inobj->inobj.imacro; // LONG * strp = imacro->im_nextln; - struct LineList * strp = imacro->im_nextln; + LLIST * strp = imacro->im_nextln; if (strp == NULL) // End-of-macro return NULL; @@ -699,10 +701,11 @@ char * GetNextMacroLine(void) char * GetNextRepeatLine(void) { IREPT * irept = cur_inobj->inobj.irept; - LONG * strp = irept->ir_nextln; // initial null +// LONG * strp = irept->ir_nextln; // initial null // Do repeat at end of .rept block's string list - if (strp == NULL) +// if (strp == NULL) + if (irept->ir_nextln == NULL) { DEBUG { printf("back-to-top-of-repeat-block count=%d\n", (int)irept->ir_count); } irept->ir_nextln = irept->ir_firstln; // copy first line @@ -713,12 +716,14 @@ char * GetNextRepeatLine(void) return NULL; } - strp = irept->ir_nextln; +// strp = irept->ir_nextln; } - strcpy(irbuf, (char *)(irept->ir_nextln + 1)); - DEBUG printf("repeat line='%s'\n", irbuf); - irept->ir_nextln = (LONG *)*strp; +// strcpy(irbuf, (char *)(irept->ir_nextln + 1)); + strcpy(irbuf, irept->ir_nextln->line); + DEBUG { printf("repeat line='%s'\n", irbuf); } +// irept->ir_nextln = (LONG *)*strp; + irept->ir_nextln = irept->ir_nextln->next; return irbuf; } @@ -736,16 +741,16 @@ int include(int handle, char * fname) INOBJ * inobj = a_inobj(SRC_IFILE); IFILE * ifile = inobj->inobj.ifile; - ifile->ifhandle = handle; // Setup file handle - ifile->ifind = ifile->ifcnt = 0; // Setup buffer indices - ifile->ifoldlineno = curlineno; // Save old line number - ifile->ifoldfname = curfname; // Save old filename - ifile->ifno = cfileno; // Save old file number + ifile->ifhandle = handle; // Setup file handle + ifile->ifind = ifile->ifcnt = 0; // Setup buffer indices + ifile->ifoldlineno = curlineno; // Save old line number + ifile->ifoldfname = curfname; // Save old filename + ifile->ifno = cfileno; // Save old file number // NB: This *must* be preincrement, we're adding one to the filecount here! - cfileno = ++filecount; // Compute NEW file number - curfname = strdup(fname); // Set current filename (alloc storage) - curlineno = 0; // Start on line zero + cfileno = ++filecount; // Compute NEW file number + curfname = strdup(fname); // Set current filename (alloc storage) + curlineno = 0; // Start on line zero // Add another file to the file-record FILEREC * fr = (FILEREC *)malloc(sizeof(FILEREC)); @@ -753,9 +758,9 @@ int include(int handle, char * fname) fr->frec_name = curfname; if (last_fr == NULL) - filerec = fr; // Add first filerec + filerec = fr; // Add first filerec else - last_fr->frec_next = fr; // Append to list of filerecs + last_fr->frec_next = fr; // Append to list of filerecs last_fr = fr; DEBUG { printf("[include: curfname: %s, cfileno=%u]\n", curfname, cfileno); } @@ -769,73 +774,85 @@ int include(int handle, char * fname) // int fpop(void) { - IFILE * ifile; - IMACRO * imacro; - LONG * p, * p1; INOBJ * inobj = cur_inobj; - if (inobj != NULL) - { - // Pop IFENT levels until we reach the conditional assembly context we - // were at when the input object was entered. - int numUnmatched = 0; + if (inobj == NULL) + return 0; - while (ifent != inobj->in_ifent) - { - if (d_endif() != 0) // Something bad happened during endif parsing? - return -1; // If yes, bail instead of getting stuck in a loop + // Pop IFENT levels until we reach the conditional assembly context we + // were at when the input object was entered. + int numUnmatched = 0; - numUnmatched++; - } + while (ifent != inobj->in_ifent) + { + if (d_endif() != 0) // Something bad happened during endif parsing? + return -1; // If yes, bail instead of getting stuck in a loop - // Give a warning to the user that we had to wipe their bum for them - if (numUnmatched > 0) - warn("missing %d .endif(s)", numUnmatched); + numUnmatched++; + } - tok = inobj->in_otok; // Restore tok and otok - etok = inobj->in_etok; + // Give a warning to the user that we had to wipe their bum for them + if (numUnmatched > 0) + warn("missing %d .endif(s)", numUnmatched); - switch (inobj->in_type) - { - case SRC_IFILE: // Pop and release an IFILE - DEBUG { printf("[Leaving: %s]\n", curfname); } + tok = inobj->in_otok; // Restore tok and otok + etok = inobj->in_etok; + + switch (inobj->in_type) + { + case SRC_IFILE: // Pop and release an IFILE + { + DEBUG { printf("[Leaving: %s]\n", curfname); } - ifile = inobj->inobj.ifile; - ifile->if_link = f_ifile; - f_ifile = ifile; - close(ifile->ifhandle); // Close source file + IFILE * ifile = inobj->inobj.ifile; + ifile->if_link = f_ifile; + f_ifile = ifile; + close(ifile->ifhandle); // Close source file DEBUG { printf("[fpop (pre): curfname=%s]\n", curfname); } - curfname = ifile->ifoldfname; // Set current filename + curfname = ifile->ifoldfname; // Set current filename DEBUG { printf("[fpop (post): curfname=%s]\n", curfname); } DEBUG { printf("[fpop: (pre) cfileno=%d ifile->ifno=%d]\n", (int)cfileno, (int)ifile->ifno); } - curlineno = ifile->ifoldlineno; // Set current line# - DEBUG printf("cfileno=%d ifile->ifno=%d\n", (int)cfileno, (int)ifile->ifno); - cfileno = ifile->ifno; // Restore current file number + curlineno = ifile->ifoldlineno; // Set current line# + DEBUG { printf("cfileno=%d ifile->ifno=%d\n", (int)cfileno, (int)ifile->ifno); } + cfileno = ifile->ifno; // Restore current file number DEBUG { printf("[fpop: (post) cfileno=%d ifile->ifno=%d]\n", (int)cfileno, (int)ifile->ifno); } - break; - case SRC_IMACRO: // Pop and release an IMACRO - imacro = inobj->inobj.imacro; - imacro->im_link = f_imacro; - f_imacro = imacro; - break; - case SRC_IREPT: // Pop and release an IREPT - DEBUG printf("dealloc IREPT\n"); - p = inobj->inobj.irept->ir_firstln; + break; + } - while (p != NULL) - { - p1 = (LONG *)*p; - p = p1; - } + case SRC_IMACRO: // Pop and release an IMACRO + { + IMACRO * imacro = inobj->inobj.imacro; + imacro->im_link = f_imacro; + f_imacro = imacro; + break; + } - break; + case SRC_IREPT: // Pop and release an IREPT + { + DEBUG { printf("dealloc IREPT\n"); } +// LONG * p = inobj->inobj.irept->ir_firstln; + LLIST * p = inobj->inobj.irept->ir_firstln; + + // Deallocate repeat lines + while (p != NULL) + { +// Shamus: ggn confirmed that this will cause a segfault on 64-bit versions of +// RMAC. This is just stupid and wrong anyway, so we need to fix crapola +// like this... +// LONG * p1 = (LONG *)*p; +// p = p1; + free(p->line); + p = p->next; } - cur_inobj = inobj->in_link; - inobj->in_link = f_inobj; - f_inobj = inobj; + break; + } } + cur_inobj = inobj->in_link; + inobj->in_link = f_inobj; + f_inobj = inobj; + return 0; } @@ -971,7 +988,7 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } goto retry; // Try for more lines else { - ifent->if_prev = (IFENT *) - 1; //Signal Assemble() that we have reached EOF with unbalanced if/endifs + ifent->if_prev = (IFENT *)-1; //Signal Assemble() that we have reached EOF with unbalanced if/endifs return TKEOF; } } @@ -1000,20 +1017,22 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } } break; + // Macro-block: // o Handle end-of-macro; // o tag the listing-line with an at (@) sign. case SRC_IMACRO: if ((ln = GetNextMacroLine()) == NULL) { - if (ExitMacro() == 0) // Exit macro (pop args, do fpop(), etc) - goto retry; // Try for more lines... + if (ExitMacro() == 0) // Exit macro (pop args, do fpop(), etc) + goto retry; // Try for more lines... else - return TKEOF; // Oops, we got a non zero return code, signal EOF + return TKEOF; // Oops, we got a non zero return code, signal EOF } lntag = '@'; break; + // Repeat-block: // o Handle end-of-repeat-block; // o tag the listing-line with a pound (#) sign. @@ -1029,13 +1048,13 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); } break; } - // Save text of the line. We only do this during listings and within + // Save text of the line. We only do this during listings and within // macro-type blocks, since it is expensive to unconditionally copy every // line. if (lnsave) strcpy(lnbuf, ln); - // General house-keeping + // General housekeeping tok = tokeol; // Set "tok" to EOL in case of error tk = etok; // Reset token ptr stuffnull = 0; // Don't stuff nulls @@ -1603,7 +1622,7 @@ int d_goto(WORD unused) return error("goto not in macro"); IMACRO * imacro = cur_inobj->inobj.imacro; - struct LineList * defln = imacro->im_macro->lineList; + LLIST * defln = imacro->im_macro->lineList; // Attempt to find the label, starting with the first line. for(; defln!=NULL; defln=defln->next) diff --git a/token.h b/token.h index 65b5b83..52ff8cb 100644 --- a/token.h +++ b/token.h @@ -90,7 +90,7 @@ IFENT { WORD if_state; // 0:enabled, 1:disabled }; -// Pointer to IFILE or IMACRO +// Pointer to IFILE or IMACRO or IREPT IUNION { IFILE * ifile; IMACRO * imacro; @@ -99,12 +99,12 @@ IUNION { // Ptr to IFILEs, IMACROs, and so on; back-ptr to previous input objects INOBJ { - WORD in_type; // 0=IFILE, 1=IMACRO ... + WORD in_type; // 0=IFILE, 1=IMACRO, 2=IREPT IFENT * in_ifent; // Pointer to .if context on entry INOBJ * in_link; // Pointer to previous INOBJ TOKEN * in_otok; // Old `tok' value TOKEN * in_etok; // Old `etok' value - IUNION inobj; // IFILE or IMACRO ... + IUNION inobj; // IFILE or IMACRO or IREPT }; // Information about a file @@ -128,7 +128,7 @@ TOKENSTREAM { // Information about a macro invocation IMACRO { IMACRO * im_link; // Pointer to ancient IMACROs - struct LineList * im_nextln; // Next line to include + LLIST * im_nextln; // Next line to include WORD im_nargs; // # of arguments supplied on invocation WORD im_siz; // Size suffix supplied on invocation LONG im_olduniq; // Old value of 'macuniq' @@ -140,8 +140,8 @@ IMACRO { // Information about a .rept invocation IREPT { - LONG * ir_firstln; // Pointer to first line - LONG * ir_nextln; // Pointer to next line + LLIST * ir_firstln; // Pointer to first line + LLIST * ir_nextln; // Pointer to next line VALUE ir_count; // Repeat count (decrements) }; diff --git a/version.h b/version.h index 4db56ce..7228b2d 100644 --- a/version.h +++ b/version.h @@ -14,8 +14,8 @@ // Release Information #define MAJOR 1 // Major version number -#define MINOR 7 // Minor version number -#define PATCH 2 // Patch release number +#define MINOR 8 // Minor version number +#define PATCH 0 // Patch release number #endif // __VERSION_H__ -- 2.37.2