static enum token t_lex(char *s, struct exists_data *ed) { struct t_op const *op; ed->no_op = 0; if (s == NULL) { ed->t_wp_op = NULL; return EOI; } if ((op = findop(s)) != NULL) { if (!((op->op_type == UNOP && isoperand(ed)) || (op->op_num == LPAREN && *(ed->t_wp+1) == 0))) { ed->t_wp_op = op; return (enum token)op->op_num; } } if (strlen(*(ed->t_wp)) > 0 && !op && !ed->t_wp_op) { ed->t_wp_op = findop("-N"); ed->no_op = 1; return (enum token)ed->t_wp_op->op_num; } else { ed->t_wp_op = NULL; } return OPERAND; }
static int isoperand(void) { struct t_op const *op; char *s, *t; if ((s = *(t_wp+1)) == 0) return 1; if ((t = *(t_wp+2)) == 0) return 0; if ((op = findop(s)) != NULL) return op->op_type == BINOP && (t[0] != ')' || t[1] != '\0'); return 0; }
static int isoperand(struct exists_data *ed) { struct t_op const *op; char *s, *t; if ((s = *((ed->t_wp)+1)) == 0) return 1; if ((t = *((ed->t_wp)+2)) == 0) return 0; if ((op = findop(s)) != NULL) return op->op_type == BINOP && (t[0] != ')' || t[1] != '\0'); return 0; }
static enum token t_lex(char *s) { struct t_op const *op; if (s == NULL) { t_wp_op = NULL; return EOI; } if ((op = findop(s)) != NULL) { if (!((op->op_type == UNOP && isoperand()) || (op->op_num == LPAREN && *(t_wp+1) == 0))) { t_wp_op = op; return op->op_num; } } t_wp_op = NULL; return OPERAND; }
/* here's where mawk really becomes awka */ void awka_insertop(int op, char *cval, char *carg, int minst, char *file, int line) { char *val = NULL, *arg = NULL; if (cval) { val = (char *) malloc((strlen(cval)*2)+10); strcpy(val, cval); } if (carg) { arg = (char *) malloc((strlen(carg)*2)+10); strcpy(arg, carg); } if (prog_no == prog_allc) { prog_allc += 40; progcode = (struct pc *) realloc(progcode, prog_allc * sizeof(struct pc)); } if (op == _BUILTIN) { if (!(op = findop(val))) return; free(val); val = NULL; } progcode[prog_no].op = op; progcode[prog_no].inst = prog_no; progcode[prog_no].minst = minst; progcode[prog_no].line = line; progcode[prog_no].file = file; progcode[prog_no].val = val; progcode[prog_no].arg = arg; progcode[prog_no].endloop = 0; progcode[prog_no].foreverloop = 0; progcode[prog_no].doloop = FALSE; progcode[prog_no].label = FALSE; progcode[prog_no].jumpfrom = progcode[prog_no].jumpto = -1; progcode[prog_no].ljumpfrom = -1; progcode[prog_no].prevcat = progcode[prog_no].prev2 = -1; progcode[prog_no].context = _NUL; progcode[prog_no].code = NULL; progcode[prog_no].code0 = NULL; progcode[prog_no].code_used = progcode[prog_no].code_allc = 0; progcode[prog_no].code0_used = progcode[prog_no].code0_allc = 0; progcode[prog_no].done = FALSE; progcode[prog_no].printed = FALSE; progcode[prog_no].earliest = -1; progcode[prog_no].ftype = code[op-1].ftype; if (op >= CODE_MIN && op <= BI_MAX) { progcode[prog_no].func = code[op-1].func; progcode[prog_no].pop = code[op-1].pop; progcode[prog_no].varidx = code[op-1].varidx; } else { progcode[prog_no].func = NULL; progcode[prog_no].pop = FALSE; progcode[prog_no].varidx = -1; } if (val && op == _PUSHS) { progcode[prog_no].val = fixbackslashes(progcode[prog_no].val, op); /* double_backslashes(progcode[prog_no].val); */ } if (arg) { if (!strncmp(val, "repl", 4)) { progcode[prog_no].arg = fixbackslashes(progcode[prog_no].arg, _PUSHS); /* double_backslashes(progcode[prog_no].arg); */ } else progcode[prog_no].arg = fixbackslashes(progcode[prog_no].arg, op); } prog_no++; }
int yylex(void) { int scanstate; char *thistokstart = NULL; register char nextchar; int charset; int consaccum = 0, consbase = 0; if (!fryybuf || fryy_bs < 4096) { free(fryybuf); fryy_bs = 4096; fryybuf = (char *)calloc(fryy_bs, 1); frainptr = fryybuf; } if(currtok >= intokcnt) { again: switch(nextreadact) { case Nra_new: /* access next file */ emit_entering_file(infilestk[++currfstk].fnm); yyin = infilestk[currfstk].fpt; nextreadact = Nra_normal; case Nra_normal: if(frareadrec()) { /* EOF */; return 0; } break; case Nra_end: /* pop file and access previous */ if(currfstk > 0) { fclose(yyin); yyin = infilestk[--currfstk].fpt; emit_exiting_file(infilestk[currfstk].fnm); if(frareadrec()) { /* EOF */; return 0; } else { nextreadact = Nra_normal; } } else { /* EOF */; return 0; } break; } if(listflag) emit_listed_line(fryybuf); else emit_unlisted_line(); if (fraignore) goto again; /* don't scan it! */ /* resize our parsing buffers if the incoming line buffer got huge */ if (fryy_bs + 2 > sq_size) { free(scanqueue ); free(tempstrpool); scanqueue = (sq_type *)malloc((fryy_bs + 2) * sizeof(sq_type)); tempstrpool = (char *)malloc((fryy_bs + 2) * 2); sq_size = fryy_bs + 2; } /* Scan a line */ frainptr = fryybuf; currtok = intokcnt = 0; nexttokload = & scanqueue[0]; tptrstr = &tempstrpool[0]; scanstate = 0; whichsym = Symopcode; labelarray = LAno; while( (nextchar = *frainptr++) != '\0' ) { charset = chartrantab[nextchar & 0x7f]; do { thisact = & characttab [scanstate][charset]; #if DEBUG if(isprint(nextchar)) printf("%c ", nextchar); else printf("0x%2.2X ", nextchar); printf("%-18s %-33s %-11s %2.2d\n", statelab[scanstate], actlab[thisact->action], thisact->contin ? "Continue" : "Swallow", thisact->nextstate); #endif switch(thisact->action) { case 0: /* skip/no op */ break; case 1: /* load EOL token */ nexttokload->lvalv.longv = 0; nexttokload->tokv = EOL; nexttokload->errtype = Yetunprint; nexttokload++; intokcnt++; break; case 2: /* start string */ thistokstart = tptrstr; nexttokload->textstrt = frainptr; break; case 3: /* process label */ { struct symel *tempsym; labelarray = LAmaybe; *tptrstr++ = '\0'; tempsym = symbentry(thistokstart, SYMBOL); if((tempsym->seg) != SSG_RESV) { nexttokload->tokv = LABEL; nexttokload->errtype = Yetsymbol; nexttokload->lvalv.symb = tempsym; } else { nexttokload->tokv = tempsym->tok; nexttokload->errtype = Yetreserved; nexttokload->lvalv.intv = tempsym->value; } nexttokload->textend = frainptr; nexttokload++; intokcnt++; } break; case 4: /* save string char */ *tptrstr++ = nextchar; break; case 5: /* load single char token */ if (labelarray == LAmaybe && nextchar == '[' && whichsym == Symopcode) { labelarray = LAyes; whichsym = Symsym; } if (labelarray == LAyes && nextchar == ']') { labelarray = LAno; whichsym = Symopcode; } nexttokload->lvalv.longv = 0; nexttokload->tokv = nextchar; nexttokload->errtype = Yetprint; nexttokload++; intokcnt++; break; case 6: /* load EQ token */ nexttokload->lvalv.longv = 0; nexttokload->tokv = KEOP_EQ; nexttokload->errtype = Yetunprint; nexttokload++; intokcnt++; break; case 7: /* process symbol */ { register struct symel *symp; register char *ytp; int tempov; *tptrstr++ = '\0'; if(whichsym == Symopcode) { for(ytp = thistokstart; *ytp != '\0'; ytp++) { if(islower(*ytp)) { *ytp = toupper(*ytp); } } nexttokload->lvalv.intv = tempov = findop(thistokstart); nexttokload->tokv = optab[tempov].token; nexttokload->errtype = Yetopcode; whichsym = Symsym; } else { symp = symbentry(thistokstart,SYMBOL); if(symp->seg != SSG_RESV) { nexttokload->lvalv.symb = symp; nexttokload->errtype = Yetsymbol; } else { nexttokload->lvalv.intv = symp->value; nexttokload->errtype = Yetreserved; } nexttokload->tokv = symp->tok; } nexttokload->textend = frainptr; nexttokload++; intokcnt++; } break; case 8: /* load $ token */ nexttokload->lvalv.longv = 0; nexttokload->tokv = '$'; nexttokload->errtype = Yetprint; nexttokload++; intokcnt++; break; case 9: /* setup for $hex */ consbase = 16; consaccum = 0; break; case 10: /* accumulate 0-9 constant */ consaccum = (consaccum * consbase) + (nextchar - '0'); break; case 11: /* accumulate A-F constant */ consaccum = (consaccum * consbase) + (nextchar - 'A' + 10); break; case 12: /* accumulate a-f constant */ consaccum = (consaccum * consbase) + (nextchar - 'a' + 10); break; case 13: /* load Constant token */ nexttokload->lvalv.longv = consaccum; nexttokload->tokv = CONSTANT; nexttokload->errtype = Yetconstant; nexttokload->textend = frainptr; nexttokload++; intokcnt++; break; case 14: /* load @ token */ nexttokload->lvalv.longv = 0; nexttokload->tokv = '@'; nexttokload->errtype = Yetprint; nexttokload++; intokcnt++; break; case 15: /* setup for @octal */ consbase = 8; consaccum = 0; break; case 16: /* setup for %binary */ consbase = 2; consaccum = 0; break; case 17: /* load % token */ nexttokload->lvalv.longv = 0; nexttokload->tokv = '%'; nexttokload->errtype = Yetprint; nexttokload++; intokcnt++; break; case 18: /* load String token (double quoted) */ *tptrstr++ = '\0'; nexttokload->lvalv.strng = thistokstart; nexttokload->tokv = STRING; nexttokload->errtype = Yetstring; nexttokload->textend = frainptr; nexttokload++; intokcnt++; break; case 35: /* load String token (single quoted) */ *tptrstr++ = '\0'; if (tptrstr == thistokstart + 2) { nexttokload->lvalv.longv = *thistokstart & 0xFF; nexttokload->tokv = QCHAR; nexttokload->errtype = Yetconstant; } else { nexttokload->lvalv.strng = thistokstart; nexttokload->tokv = STRING; nexttokload->errtype = Yetstring; } nexttokload->textend = frainptr; nexttokload++; intokcnt++; break; case 19: /* load GE token */ nexttokload->lvalv.longv = 0; nexttokload->tokv = KEOP_GE; nexttokload->errtype = Yetunprint; nexttokload++; intokcnt++; break; case 20: /* load GT token */ nexttokload->lvalv.longv = 0; nexttokload->tokv = KEOP_GT; nexttokload->errtype = Yetunprint; nexttokload++; intokcnt++; break; case 21: /* load LE token */ nexttokload->lvalv.longv = 0; nexttokload->tokv = KEOP_LE; nexttokload->errtype = Yetunprint; nexttokload++; intokcnt++; break; case 22: /* load NE token */ nexttokload->lvalv.longv = 0; nexttokload->tokv = KEOP_NE; nexttokload->errtype = Yetunprint; nexttokload++; intokcnt++; break; case 23: /* load LT token */ nexttokload->lvalv.longv = 0; nexttokload->tokv = KEOP_LT; nexttokload->errtype = Yetunprint; nexttokload++; intokcnt++; break; case 24: /* save numeric char 0-9 */ *tptrstr++ = nextchar - '0'; break; case 25: /* save numeric char A-F */ *tptrstr++ = nextchar - 'A' + 10; break; case 26: /* save numeric char a-f */ *tptrstr++ = nextchar - 'a' + 10; break; case 27: /* convert numeric string base 2 */ { consaccum = 0; while(thistokstart < tptrstr) { consaccum = (consaccum * 2) + *thistokstart++; } nexttokload->lvalv.longv = consaccum; nexttokload->tokv = CONSTANT; nexttokload->errtype = Yetconstant; nexttokload->textend = frainptr; nexttokload++; intokcnt++; } break; case 28: /* convert numeric string base 8 */ { consaccum = 0; while(thistokstart < tptrstr) { consaccum = (consaccum * 8) + *thistokstart++; } nexttokload->lvalv.longv = consaccum; nexttokload->tokv = CONSTANT; nexttokload->errtype = Yetconstant; nexttokload->textend = frainptr; nexttokload++; intokcnt++; } break; case 29: /* convert numeric string base 10 */ { consaccum = 0; while(thistokstart < tptrstr) { consaccum = (consaccum * 10) + *thistokstart++; } nexttokload->lvalv.longv = consaccum; nexttokload->tokv = CONSTANT; nexttokload->errtype = Yetconstant; nexttokload->textend = frainptr; nexttokload++; intokcnt++; } break; case 30: /* convert numeric string base 16 */ { consaccum = 0; while(thistokstart < tptrstr) { consaccum = (consaccum * 16) + *thistokstart++; } nexttokload->lvalv.longv = consaccum; nexttokload->tokv = CONSTANT; nexttokload->errtype = Yetconstant; nexttokload->textend = frainptr; nexttokload++; intokcnt++; } break; case 31: /* save numeric 0xb */ *tptrstr++ = 0xb; break; case 32: /* save numeric 0xd */ *tptrstr++ = 0xd; break; case 33: /* set text start */ nexttokload->textstrt = frainptr; break; case 34: /* token choke */ nexttokload->lvalv.longv = 0L; nexttokload->tokv = KTK_invalid; nexttokload->errtype = Yetinvalid; nexttokload->textend = frainptr; nexttokload++; intokcnt++; break; } scanstate = thisact->nextstate; } while( thisact->contin); } if(intokcnt <= 0) { /* no tokens in line (comment or whitespace overlength) */ scanqueue[0].tokv = EOL; scanqueue[0].errtype = Yetunprint; scanqueue[0].lvalv.longv = 0; intokcnt = 1; } if(scanstate != 0) { /* no EOL */ fraerror("Overlength/Unterminated Line"); } } lasttokfetch = &scanqueue[currtok++]; yylval = lasttokfetch->lvalv; return lasttokfetch->tokv; }
char * demangle(char *c) { volatile int i = 0; extern jmp_buf jbuf; static mutex_t mlock = DEFAULTMUTEX; NOTE(MUTEX_PROTECTS_DATA(mlock, String)) (void) mutex_lock(&mlock); if (setjmp(jbuf)) { (void) mutex_unlock(&mlock); return (0); } hold = c; s = mk_String(s); s = set_String(s, MSG_ORIG(MSG_STR_EMPTY)); if (c == 0 || *c == 0) { c = hold; (void) mutex_unlock(&mlock); return (c); } if (strncmp(c, MSG_ORIG(MSG_STR_DBLUNDBAR), 2) != 0) { /* * If a name does not begin with a __ * but it does contain one, it is either * a member or an overloaded function. */ while (c[i] && strncmp(c+i, MSG_ORIG(MSG_STR_DBLUNDBAR), 2)) i++; if (c[i]) { /* Advance to first non-underscore */ while (c[i+2] == '_') i++; } if (strncmp(c+i, MSG_ORIG(MSG_STR_DBLUNDBAR), 2) == 0) { /* Copy the simple name */ s = napp_String(s, c, i); /* Process the signature */ c = second(c+i); (void) mutex_unlock(&mlock); return (c); } else { c = hold; (void) mutex_unlock(&mlock); return (c); } } else { const char *x; int oplen; c += 2; /* * For automatic variables, or internal static * variables, a __(number) is prepended to the * name. If this is encountered, strip this off * and return. */ if (isdigit(*c)) { while (isdigit(*c)) c++; (void) mutex_unlock(&mlock); return (c); } /* * Handle operator functions -- this * automatically calls second, since * all operator functions are overloaded. */ if (x = findop(c, &oplen)) { s = app_String(s, MSG_ORIG(MSG_STR_OPERATOR_1)); s = app_String(s, x); c += oplen; c = second(c); (void) mutex_unlock(&mlock); return (c); } /* * Operator cast does not fit the mould * of the other operators. Its type name * is encoded. The cast function must * take a void as an argument. */ if (strncmp(c, MSG_ORIG(MSG_STR_OP), 2) == 0) { int r; s = app_String(s, MSG_ORIG(MSG_STR_OPERATOR_2)); c += 2; r = demangle_doarg(&s, c); if (r < 0) { c = hold; (void) mutex_unlock(&mlock); return (c); } c += r; c = second(c); (void) mutex_unlock(&mlock); return (c); } /* * Constructors and Destructors are also * a special case of operator name. Note * that the destructor, while overloaded, * must always take the same arguments -- * none. */ if ((*c == 'c' || *c == 'd') && strncmp(c+1, MSG_ORIG(MSG_STR_TDBLUNDBAR), 3) == 0) { int n; char *c2 = c+2; char cx = c[0]; c += 4; n = getint(&c); if (n == 0) { c = hold; (void) mutex_unlock(&mlock); return (c); } s = napp_String(s, c, n); if (cx == 'd') s = prep_String(MSG_ORIG(MSG_STR_TILDE), s); c = second(c2); (void) mutex_unlock(&mlock); return (c); } c = hold; (void) mutex_unlock(&mlock); return (c); } }