// RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
// Source utilised with the kind permission of Landon Dyer
//
#include "token.h"
// RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
// Source utilised with the kind permission of Landon Dyer
//
#include "token.h"
#include "kwtab.h" // Incl generated keyword tables & defs
int lnsave; // 1; strcpy() text of current line
#include "kwtab.h" // Incl generated keyword tables & defs
int lnsave; // 1; strcpy() text of current line
int totlines; // Total # of lines
int mjump_align = 0; // mjump alignment flag
char lntag; // Line tag
char * curfname; // Current filename
int totlines; // Total # of lines
int mjump_align = 0; // mjump alignment flag
char lntag; // Line tag
char * curfname; // Current filename
char dotxtab[128]; // Table for ".b", ".s", etc.
char irbuf[LNSIZ]; // Text for .rept block line
char lnbuf[LNSIZ]; // Text of current line
char dotxtab[128]; // Table for ".b", ".s", etc.
char irbuf[LNSIZ]; // Text for .rept block line
char lnbuf[LNSIZ]; // Text of current line
- ILLEG, ILLEG, ILLEG, ILLEG, // NUL SOH STX ETX
- ILLEG, ILLEG, ILLEG, ILLEG, // EOT ENQ ACK BEL
- ILLEG, WHITE, ILLEG, ILLEG, // BS HT LF VT
- WHITE, ILLEG, ILLEG, ILLEG, // FF CR SO SI
+ ILLEG, ILLEG, ILLEG, ILLEG, // NUL SOH STX ETX
+ ILLEG, ILLEG, ILLEG, ILLEG, // EOT ENQ ACK BEL
+ ILLEG, WHITE, ILLEG, ILLEG, // BS HT LF VT
+ WHITE, ILLEG, ILLEG, ILLEG, // FF CR SO SI
- ILLEG, ILLEG, ILLEG, ILLEG, // DLE DC1 DC2 DC3
- ILLEG, ILLEG, ILLEG, ILLEG, // DC4 NAK SYN ETB
- ILLEG, ILLEG, ILLEG, ILLEG, // CAN EM SUB ESC
- ILLEG, ILLEG, ILLEG, ILLEG, // FS GS RS US
+ ILLEG, ILLEG, ILLEG, ILLEG, // DLE DC1 DC2 DC3
+ ILLEG, ILLEG, ILLEG, ILLEG, // DC4 NAK SYN ETB
+ ILLEG, ILLEG, ILLEG, ILLEG, // CAN EM SUB ESC
+ ILLEG, ILLEG, ILLEG, ILLEG, // FS GS RS US
WHITE, MULTX, MULTX, SELF, // SP ! " #
MULTX+CTSYM, MULTX, SELF, MULTX, // $ % & '
SELF, SELF, SELF, SELF, // ( ) * +
SELF, SELF, STSYM, SELF, // , - . /
WHITE, MULTX, MULTX, SELF, // SP ! " #
MULTX+CTSYM, MULTX, SELF, MULTX, // $ % & '
SELF, SELF, SELF, SELF, // ( ) * +
SELF, SELF, STSYM, SELF, // , - . /
- DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 0 1
- DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 2 3
- DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 4 5
- DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 6 7
- DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 8 9
- MULTX, MULTX, // : ;
- MULTX, MULTX, MULTX, STSYM+CTSYM, // < = > ?
+ DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 0 1
+ DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 2 3
+ DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 4 5
+ DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 6 7
+ DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 8 9
+ MULTX, MULTX, // : ;
+ MULTX, MULTX, MULTX, STSYM+CTSYM, // < = > ?
MULTX, STSYM+CTSYM+HDIGIT, // @ A
(char)((BYTE)DOT)+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // B C
MULTX, STSYM+CTSYM+HDIGIT, // @ A
(char)((BYTE)DOT)+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // B C
STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // h i j k
(char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // l m n o
STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // h i j k
(char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // l m n o
- STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // p q r s
- STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // t u v w
- STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF, // x y z {
- SELF, SELF, SELF, ILLEG // | } ~ DEL
+ STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // p q r s
+ STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // t u v w
+ STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF, // x y z {
+ SELF, SELF, SELF, ILLEG // | } ~ DEL
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
sprintf(numbuf, "%d", (int)imacro->im_nargs);
goto copystr;
case '!': // \! size suffix supplied on invocation
sprintf(numbuf, "%d", (int)imacro->im_nargs);
goto copystr;
case '!': // \! size suffix supplied on invocation
-// Shamus: Changing the format specifier from %lx to %ux caused
-// the assembler to choke on legitimate code... Need to investigate
-// this further before changing anything else here!
+// Shamus: Changing the format specifier from %lx to %ux caused the assembler
+// to choke on legitimate code... Need to investigate this further
+// before changing anything else here!
IMACRO * imacro = cur_inobj->inobj.imacro;
// LONG * strp = imacro->im_nextln;
struct LineList * strp = imacro->im_nextln;
IMACRO * imacro = cur_inobj->inobj.imacro;
// LONG * strp = imacro->im_nextln;
struct LineList * strp = imacro->im_nextln;
imacro->im_nextln = strp->next;
// ExpandMacro((char *)(strp + 1), imacro->im_lnbuf, LNSIZ);
ExpandMacro(strp->line, imacro->im_lnbuf, LNSIZ);
imacro->im_nextln = strp->next;
// ExpandMacro((char *)(strp + 1), imacro->im_lnbuf, LNSIZ);
ExpandMacro(strp->line, imacro->im_lnbuf, LNSIZ);
printf("[include: %s, cfileno=%u]\n", fname, cfileno);
// Alloc and initialize include-descriptors
printf("[include: %s, cfileno=%u]\n", fname, cfileno);
// Alloc and initialize include-descriptors
ifile->ifhandle = handle; // Setup file handle
ifile->ifind = ifile->ifcnt = 0; // Setup buffer indices
ifile->ifhandle = handle; // Setup file handle
ifile->ifind = ifile->ifcnt = 0; // Setup buffer indices
// 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
// Add another file to the file-record
// 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
// Add another file to the file-record
last_fr = fr;
DEBUG printf("[include: curfname: %s, cfileno=%u]\n", curfname, cfileno);
last_fr = fr;
DEBUG printf("[include: curfname: %s, cfileno=%u]\n", curfname, cfileno);
{
// Pop IFENT levels until we reach the conditional assembly context we
// were at when the input object was entered.
{
// Pop IFENT levels until we reach the conditional assembly context we
// were at when the input object was entered.
- if (d_endif() != 0) // Something bad happened during endif parsing?
- return -1; // If yes, bail instead of getting stuck in a loop
+ if (d_endif() != 0) // Something bad happened during endif parsing?
+ return -1; // If yes, bail instead of getting stuck in a loop
+
+ numUnmatched++;
- tok = inobj->in_otok; // Restore tok and otok
+ // Give a warning to the user that we had to wipe their bum for them
+ if (numUnmatched > 0)
+ warni("missing %d .endif(s)", numUnmatched);
+
+ tok = inobj->in_otok; // Restore tok and otok
printf("[Leaving: %s]\n", curfname);
ifile = inobj->inobj.ifile;
ifile->if_link = f_ifile;
f_ifile = ifile;
close(ifile->ifhandle); // Close source file
printf("[Leaving: %s]\n", curfname);
ifile = inobj->inobj.ifile;
ifile->if_link = f_ifile;
f_ifile = ifile;
close(ifile->ifhandle); // Close source file
-if (verb_flag) printf("[fpop (post): curfname=%s]\n", curfname);
-if (verb_flag) printf("[fpop: (pre) cfileno=%d ifile->ifno=%d]\n", (int)cfileno, (int)ifile->ifno);
- curlineno = ifile->ifoldlineno; // Set current line#
+if (debug) printf("[fpop (post): curfname=%s]\n", curfname);
+if (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
DEBUG printf("cfileno=%d ifile->ifno=%d\n", (int)cfileno, (int)ifile->ifno);
cfileno = ifile->ifno; // Restore current file number
-if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n");
- fpop(); // Pop input level
- goto retry; // Try for more lines
+if (debug) printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n");
+ if (fpop() == 0) // Pop input level
+ goto retry; // Try for more lines
+ else
+ {
+ ifent->if_prev = (IFENT *) - 1; //Signal Assemble() that we have reached EOF with unbalanced if/endifs
+ return TKEOF;
+ }
+
+ // In some cases, we need to check for a DOTx at the *beginning*
+ // of a symbol, as the "start" of the line we're currently looking
+ // at could be somewhere in the middle of that line!
+ if (*ln == '.')
+ {
+ // Make sure that it's *only* a .[bwsl] following, and not the
+ // start of a local symbol:
+ if ((chrtab[*(ln + 1)] & DOT)
+ && (dotxtab[*(ln + 1)] != 0)
+ && !(chrtab[*(ln + 2)] & CTSYM))
+ {
+ // We found a legitimate DOTx construct, so add it to the
+ // token stream:
+ ln++;
+ stuffnull = 0;
+ *tk++ = (TOKEN)dotxtab[*ln++];
+ continue;
+ }
+ }
+
p = nullspot = ln++; // Nullspot -> start of this symbol
// Find end of symbol (and compute its length)
p = nullspot = ln++; // Nullspot -> start of this symbol
// Find end of symbol (and compute its length)
// Character following the `.' must have a DOT attribute, and
// the chararacter after THAT one must not have a start-symbol
// attribute (to prevent symbols that look like, for example,
// "zingo.barf", which might be a good idea anyway....)
// Character following the `.' must have a DOT attribute, and
// the chararacter after THAT one must not have a start-symbol
// attribute (to prevent symbols that look like, for example,
// "zingo.barf", which might be a good idea anyway....)
- if ((((int)chrtab[*ln] & DOT) == 0) || ((int)dotxtab[*ln] <= 0))
- return error("[bwsl] must follow `.' in symbol");
+ if (((chrtab[*ln] & DOT) == 0) || (dotxtab[*ln] == 0))
+ return error("[bwsl] must follow '.' in symbol");
- if ((int)chrtab[*ln] & CTSYM)
- return error("misuse of `.', not allowed in symbols");
+ if (chrtab[*ln] & CTSYM)
+ return error("misuse of '.', not allowed in symbols");
v = (v << 4) + (int)hextab[*ln++];
// ggn: Okay, some comments here are in order I think....
v = (v << 4) + (int)hextab[*ln++];
// ggn: Okay, some comments here are in order I think....
// The label is searched for starting from the first line of the current,
// enclosing macro definition. If no enclosing macro exists, an error is
// generated.
// The label is searched for starting from the first line of the current,
// enclosing macro definition. If no enclosing macro exists, an error is
// generated.
// The colon must appear in column 1. The label is stripped prior to macro
// expansion, and is NOT subject to macro expansion. The whitespace may also
// be EOL.
//
// The colon must appear in column 1. The label is stripped prior to macro
// expansion, and is NOT subject to macro expansion. The whitespace may also
// be EOL.
//
- // This string compare is not right. Doesn't check for lengths.
- // (actually it does, but in a crappy, unclear way.)
-WARNING(!!!! Bad string comparison !!!)
- s1 = sym;
-// s2 = (char *)(defln + 1) + 1;
- s2 = defln->line;
-
- while (*s1 == *s2)
+ char * s1 = sym;
+ char * s2 = defln->line;
+
+ // Either we will match the strings to EOS on both, or we will
+ // match EOS on string 1 to whitespace on string 2. Otherwise, we
+ // have no match.
+ while ((*s1 == *s2) || ((*s1 == EOS) && (chrtab[*s2] & WHITE)))