void macro_substitute(TokenStream& tok,char *str, char *buff) { char *p = str, *q = buff; while (*p) { // found a token if (iscsymf(*p)) poss_macro_expand(tok,q,p); else if (*p == '\"') copy_quote(q,p); else *q++ = *p++; } *q = '\0'; }
char *massage_subst_string(char *buff, char **args, char *str) { char *p = str, *q = buff; int i; char token[MAX_IDEN_SIZE]; while (*p) { // *fix 1.2.2 Argument may begin with '_' as well as a letter! while (*p && !iscsymf(*p)) { // *fix 1.2.2 (Eric)..quoted strings are copied verbatim if (*p == '\"') { copy_quote(q,p); break; } if (p[0] == '#' && p[1] == '#') { // *fix 1.2.2 (Eric) Skip whitespace before and after the ## while (q > buff && isspace(q[-1])) --q; // *change 1.2.2 keep token-pasting operator... *q++ = *p++; *q++ = *p++; while (isspace(*p)) ++p; } else *q++ = *p++; } if (*p == 0) break; //...pick up the identifier, and check it against the map p = copy_token(p,token); i = index_into(args,token); i++; //...if it is indeed a formal argument, then encode as the byte index, //...otherwise just copy to output buffer. // *change 1.2.2b (Eric) encode as unique macro-arg marker followed by byte index if (i > 0) { *q++ = ARG_MARKER; *q++ = (char)i; } else q = copy_chars(q,token); } *q = '\0'; return buff; }
UBYTE *tokenize_word(register UBYTE *line,/* (in) -> current line position */ register UBYTE *word,/* (in) -> output token buffer */ UBYTE *qstring, /* (in) -> quoted string o/p buffer*/ SHORT *plen, /* (out) # of bytes put in word buf */ SHORT *ttype, /* (out) token type */ Boolean quote /* (in) preserve quotes on string? */ ) { UBYTE *wrkptr; UBYTE *sword = word; int toklen; SHORT toktype; register unsigned int c; UBYTE c1; UBYTE c2; /*---------------------------------------------------------------------------- * Skip leading whitespace, get the first character, return NULL if no char. *--------------------------------------------------------------------------*/ while (isspace(*line) ) ++line; if ('\0' == (c = *line)) { line = NULL; goto OUT; } /*---------------------------------------------------------------------------- * Handle keywords, types, symbols *--------------------------------------------------------------------------*/ if (iscsymf(c)) { line = po_chop_csym(line, word, MAX_SYM_LEN-1, &wrkptr); word = wrkptr; toktype = TOK_UNDEF; } #ifdef DEADWOOD else if (iscsymf(c)) { toktype = TOK_UNDEF; *word++ = c; ++line; toklen = MAX_SYM_LEN; for (;;) { c = *line; if (iscsym(c)) { ++line; if (toklen) { *word++ = c; --toklen; } } else break; } } #endif /* DEADWOOD */ /*---------------------------------------------------------------------------- * Handle numeric constants *--------------------------------------------------------------------------*/ else if (isdigit(c)) { toklen = get_digits(line,word,&toktype); line += toklen; word += toklen; } /*---------------------------------------------------------------------------- * Handle C operators and string/char constants... * This processes non-alphanumeric characters. Most will be passed through * as single character tokens. Some, like ==, !=, >= and <= are easier to * handle here than in parser (which only has a one-token look-ahead). * Also, quoted strings and chars are now handled in this switch statement. *--------------------------------------------------------------------------*/ else { c1 = line[1]; /* lookahead characters */ c2 = line[2]; switch (c) { case '"': /* note: a shortcut in this loop */ /* assumes that a quoted string */ if (qstring != NULL) /* could never be longer than */ sword = word = qstring; /* SZTOKE-3 chars. */ toktype = TOK_QUO; if (quote) *word++ = '"'; ++line; toklen = SZTOKE-3; /* room for nullterm and two quotes */ while(--toklen) { c = *line++; if (c == 0) break; else if (c == '\\') { if (quote) { *word++ = c; *word++ = *line++; } else { wrkptr = line; *word++ = translate_escape(&wrkptr); line = wrkptr; } } else if (c == '\"') { break; } else { *word++ = c; } } if (quote) *word++ = '"'; break; case '\'': if (quote) *word++ = '\''; toktype = TOK_SQUO; ++line; for (;;) { c = *line++; if (c == 0) break; else if (c == '\\') { if (quote) { *word++ = c; *word++ = *line++; } else { wrkptr = line; *word++ = translate_escape(&wrkptr); line = wrkptr; } } else if (c == '\'') { break; } else { *word++ = c; } } if (quote) *word++ = '\''; break; case '.': if (c1 == '.' && c2 == '.') { toktype = TOK_UNDEF; goto THREECHAR; } else goto SIMPLE; case '%': if (c1 == '=') /* mod-equals */ { toktype = TOK_MOD_EQUALS; goto TWOCHAR; } else goto SIMPLE; case '/': if (c1 == '=') /* div-equals */ { toktype = TOK_DIV_EQUALS; goto TWOCHAR; } else goto SIMPLE; case '*': if (c1 == '=') { toktype = TOK_MUL_EQUALS; goto TWOCHAR; } else goto SIMPLE; case '+': if (c1 == '+') { toktype = TOK_PLUS_PLUS; goto TWOCHAR; } else if (c1 == '=') { toktype = TOK_PLUS_EQUALS; goto TWOCHAR; } else goto SIMPLE; case '-': if (c1 == '-') { toktype = TOK_MINUS_MINUS; goto TWOCHAR; } else if (c1 == '=') { toktype = TOK_MINUS_EQUALS; goto TWOCHAR; } else if (c1 == '>') { toktype = TOK_ARROW; goto TWOCHAR; } else goto SIMPLE; case '=': if (c1 == '=') /* double equals */ { toktype = TOK_EQ; goto TWOCHAR; } else goto SIMPLE; case '!': if (c1 == '=') /* != */ { toktype = TOK_NE; goto TWOCHAR; } else goto SIMPLE; case '<': if (c1 == '=') /* <= */ { toktype = TOK_LE; goto TWOCHAR; } else if (c1 == '<') /* << */ { if (c2 == '=') { toktype = TOK_LSHIFT_EQUALS; goto THREECHAR; } else { toktype = TOK_LSHIFT; goto TWOCHAR; } } else goto SIMPLE; case '>': if (c1 == '=') /* >= */ { toktype = TOK_GE; goto TWOCHAR; } else if (c1 == '>') /* >> */ { if (c2 == '=') { toktype = TOK_RSHIFT_EQUALS; goto THREECHAR; } else { toktype = TOK_RSHIFT; goto TWOCHAR; } } else goto SIMPLE; case '&': if (c1 == '&') /* logical and - && */ { toktype = TOK_LAND; goto TWOCHAR; } else if (c1 == '=') { toktype = TOK_AND_EQUALS; goto TWOCHAR; } else goto SIMPLE; case '|': if (c1 == '|') /* logical or - || */ { toktype = TOK_LOR; goto TWOCHAR; } else if (c1 == '=') { toktype = TOK_OR_EQUALS; goto TWOCHAR; } else goto SIMPLE; case '^': if (c1 == '=') { toktype = TOK_XOR_EQUALS; goto TWOCHAR; } else goto SIMPLE; default: SIMPLE: toktype = *word++ = c; ++line; break; } } OUT: *ttype = toktype; *word = 0; if (plen != NULL) *plen = word - sword; return line; TWOCHAR: *word++ = c; *word++ = c1; line += 2; goto OUT; THREECHAR: *word++ = c; *word++ = c1; *word++ = c2; line += 3; goto OUT; }