Fixed IREPT blocks to not corrupt memory on 64-bit hosts.
authorShamus Hammons <jlhamm@acm.org>
Wed, 19 Jul 2017 20:27:06 +0000 (15:27 -0500)
committerShamus Hammons <jlhamm@acm.org>
Wed, 19 Jul 2017 20:27:06 +0000 (15:27 -0500)
direct.c
direct.h
macro.c
macro.h
procln.c
procln.h
rmac.c
symbol.h
token.c
token.h
version.h

index 5714def294d89aa5dc21f9e3adb1c9d8ce7be97e..c9a82d938714730471728f4868820e47ace156c0 100644 (file)
--- 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;
+}
+
index a4ab5ba7e9508379c54cb3de7906a8ec8164d175..654c580bf1ff0542db14f65466228e6ce0885a5f 100644 (file)
--- 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 23d879719d7d47ad45d6ecd99c010033effa0a4f..6b592d114aedacc3c6a48321e04c351bfaa241bf 100644 (file)
--- 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:
                //            <directive>
                //    symbol: <directive>
-               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 1a067130a64faef7fec8c2c9dfd0fdc6639dedf6..00623143ee27f559976d7e7713bea60ec7c352b5 100644 (file)
--- 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__
index 600aaa0e9685438bdf0504032ac73fe7f8ef7a53..ab6cf3a5cfd24371ebf74e891858f661ab24b02d 100644 (file)
--- 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;
-}
-
index c611e5b5cb3492b0d06a29ea6751f41c5651621a..c8c89cb0f00117a4e178a6aca4b21262b41fbd89 100644 (file)
--- 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 739925ca7d23a40d3da27749abc62141d83049f6..3dc0f078a2a1b17ed49045602e8849ba9b0135b4 100644 (file)
--- 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;
                                }
 
index b7350e0adf6373702b59a1511070fb67b8764d58..3dc930f6f94b45629aa9d9764fc9a7c1d5b48dd0 100644 (file)
--- a/symbol.h
+++ b/symbol.h
 #include <inttypes.h>
 
 // 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 6f42cca5d8f5306904c387e23f4f615bd928bfae..27eedc3d849b500d57305740b9d8d910cba6f476 100644 (file)
--- 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 65b5b831a7dc1d5c126d28c8c7198009a0814dd4..52ff8cb2d39154791fbc7b6351dfb65e87427613 100644 (file)
--- 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)
 };
 
index 4db56ceb5440889dbacda0948dfa6e94bffd0799..7228b2dcc5585679038b3d9f0032102cc3dafe0b 100644 (file)
--- 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__