// Parse out the arguments and set them up correctly
TOKEN * p = imacro->argument[nargs].token;
int stringNum = 0;
+ int numTokens = 0;
while (*tok != EOL)
{
if (*tok == ACONST)
{
+ // Sanity checking (it's numTokens + 1 because we need an EOL
+ // if we successfully parse this argument)
+ if ((numTokens + 3) >= TS_MAXTOKENS)
+ return error("Too many tokens in argument #%d in MACRO invocation", nargs + 1);
+
for(int i=0; i<3; i++)
*p++ = *tok++;
+
+ numTokens += 3;
}
else if (*tok == CONST) // Constants are 64-bits
{
+ // Sanity checking (it's numTokens + 1 because we need an EOL
+ // if we successfully parse this argument)
+ if ((numTokens + 3) >= TS_MAXTOKENS)
+ return error("Too many tokens in argument #%d in MACRO invocation", nargs + 1);
+
*p++ = *tok++; // Token
uint64_t *p64 = (uint64_t *)p;
uint64_t *tok64 = (uint64_t *)tok;
*p64++ = *tok64++;
tok = (TOKEN *)tok64;
p = (uint32_t *)p64;
+ numTokens += 3;
}
else if ((*tok == STRING) || (*tok == SYMBOL))
{
+ // Sanity checking (it's numTokens + 1 because we need an EOL
+ // if we successfully parse this argument)
+ if (stringNum >= TS_MAXSTRINGS)
+ return error("Too many strings in argument #%d in MACRO invocation", nargs + 1);
+
+ if ((numTokens + 2) >= TS_MAXTOKENS)
+ return error("Too many tokens in argument #%d in MACRO invocation", nargs + 1);
+
*p++ = *tok++;
imacro->argument[nargs].string[stringNum] = strdup(string[*tok++]);
*p++ = stringNum++;
+ numTokens += 2;
}
else if (*tok == ',')
{
+ // Sanity checking
+ if ((nargs + 1) >= TS_MAXARGS)
+ return error("Too many arguments in MACRO invocation");
+
// Comma delimiter was found, so set up for next argument
*p++ = EOL;
tok++;
stringNum = 0;
+ numTokens = 0;
nargs++;
p = imacro->argument[nargs].token;
}
else
{
+ // Sanity checking (it's numTokens + 1 because we need an EOL
+ // if we successfully parse this argument)
+ if ((numTokens + 1) >= TS_MAXTOKENS)
+ return error("Too many tokens in argument #%d in MACRO invocation", nargs + 1);
+
*p++ = *tok++;
+ numTokens++;
}
}
return 0x04;
else if (strcmp(scratchbuf, "RELEASE") == 0)
return 0x08;
+
return 0;
}
char * GetNextMacroLine(void)
{
IMACRO * imacro = cur_inobj->inobj.imacro;
-// LONG * strp = imacro->im_nextln;
LLIST * strp = imacro->im_nextln;
if (strp == NULL) // End-of-macro
#define SRC_IREPT 2 // Input source is IREPT
// Macros
-#define INOBJ struct _inobj
-#define IUNION union _iunion
-#define IFILE struct _incldfile
-#define IMACRO struct _imacro
-#define IREPT struct _irept
-#define IFENT struct _ifent
+#define INOBJ struct _inobj
+#define IUNION union _iunion
+#define IFILE struct _incldfile
+#define TOKENSTREAM struct _tokenstream
+#define IMACRO struct _imacro
+#define IREPT struct _irept
+#define IFENT struct _ifent
// Tunable definitions
#define LNSIZ 1024 // Maximum size of a line of text
char ifbuf[LNBUFSIZ]; // Line buffer
};
-#define TOKENSTREAM struct _tokenstream
+// Consts for maximums in TOKENSTREAM
+#define TS_MAXTOKENS 64 // 32 ought to be enough for anybody (including XiA!)
+#define TS_MAXSTRINGS 32 // same for attached strings
+#define TS_MAXARGS 20 // Assume no more than 20 arguments in an invocation
+
TOKENSTREAM {
- TOKEN token[32]; // 32 ought to be enough for anybody (including XiA!)
- char * string[32]; // same for attached strings
+ TOKEN token[TS_MAXTOKENS];
+ char * string[TS_MAXSTRINGS];
};
// Information about a macro invocation
LONG im_olduniq; // Old value of 'macuniq'
SYM * im_macro; // Pointer to macro we're in
char im_lnbuf[LNSIZ]; // Line buffer
- TOKENSTREAM argument[20]; // Assume no more than 20 arguments in an invocation
+ TOKENSTREAM argument[TS_MAXARGS];
};
// Information about a .rept invocation
#define MAJOR 2 // Major version number
#define MINOR 0 // Minor version number
-#define PATCH 21 // Patch release number
+#define PATCH 22 // Patch release number
#endif // __VERSION_H__