1: /* $Header: walk.c,v 1.0 87/12/18 13:07:40 root Exp $
   2:  *
   3:  * $Log:	walk.c,v $
   4:  * Revision 1.0  87/12/18  13:07:40  root
   5:  * Initial revision
   6:  *
   7:  */
   8: 
   9: #include "handy.h"
  10: #include "EXTERN.h"
  11: #include "util.h"
  12: #include "a2p.h"
  13: 
  14: bool exitval = FALSE;
  15: bool realexit = FALSE;
  16: int maxtmp = 0;
  17: 
  18: STR *
  19: walk(useval,level,node,numericptr)
  20: int useval;
  21: int level;
  22: register int node;
  23: int *numericptr;
  24: {
  25:     register int len;
  26:     register STR *str;
  27:     register int type;
  28:     register int i;
  29:     register STR *tmpstr;
  30:     STR *tmp2str;
  31:     char *t;
  32:     char *d, *s;
  33:     int numarg;
  34:     int numeric = FALSE;
  35:     STR *fstr;
  36:     char *index();
  37: 
  38:     if (!node) {
  39:     *numericptr = 0;
  40:     return str_make("");
  41:     }
  42:     type = ops[node].ival;
  43:     len = type >> 8;
  44:     type &= 255;
  45:     switch (type) {
  46:     case OPROG:
  47:     str = walk(0,level,ops[node+1].ival,&numarg);
  48:     opens = str_new(0);
  49:     if (do_split && need_entire && !absmaxfld)
  50:         split_to_array = TRUE;
  51:     if (do_split && split_to_array)
  52:         set_array_base = TRUE;
  53:     if (set_array_base) {
  54:         str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
  55:     }
  56:     if (fswitch && !const_FS)
  57:         const_FS = fswitch;
  58:     if (saw_FS > 1 || saw_RS)
  59:         const_FS = 0;
  60:     if (saw_ORS && need_entire)
  61:         do_chop = TRUE;
  62:     if (fswitch) {
  63:         str_cat(str,"$FS = '");
  64:         if (index("*+?.[]()|^$\\",fswitch))
  65:         str_cat(str,"\\");
  66:         sprintf(tokenbuf,"%c",fswitch);
  67:         str_cat(str,tokenbuf);
  68:         str_cat(str,"';\t\t# field separator from -F switch\n");
  69:     }
  70:     else if (saw_FS && !const_FS) {
  71:         str_cat(str,"$FS = '[ \\t\\n]+';\t\t# default field separator\n");
  72:     }
  73:     if (saw_OFS) {
  74:         str_cat(str,"$, = ' ';\t\t# default output field separator\n");
  75:     }
  76:     if (saw_ORS) {
  77:         str_cat(str,"$\\ = \"\\n\";\t\t# default output record separator\n");
  78:     }
  79:     if (str->str_cur > 20)
  80:         str_cat(str,"\n");
  81:     if (ops[node+2].ival) {
  82:         str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
  83:         str_free(fstr);
  84:         str_cat(str,"\n\n");
  85:     }
  86:     if (saw_line_op)
  87:         str_cat(str,"line: ");
  88:     str_cat(str,"while (<>) {\n");
  89:     tab(str,++level);
  90:     if (saw_FS && !const_FS)
  91:         do_chop = TRUE;
  92:     if (do_chop) {
  93:         str_cat(str,"chop;\t# strip record separator\n");
  94:         tab(str,level);
  95:     }
  96:     arymax = 0;
  97:     if (namelist) {
  98:         while (isalpha(*namelist)) {
  99:         for (d = tokenbuf,s=namelist;
 100:           isalpha(*s) || isdigit(*s) || *s == '_';
 101:           *d++ = *s++) ;
 102:         *d = '\0';
 103:         while (*s && !isalpha(*s)) s++;
 104:         namelist = s;
 105:         nameary[++arymax] = savestr(tokenbuf);
 106:         }
 107:     }
 108:     if (maxfld < arymax)
 109:         maxfld = arymax;
 110:     if (do_split)
 111:         emit_split(str,level);
 112:     str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
 113:     str_free(fstr);
 114:     fixtab(str,--level);
 115:     str_cat(str,"}\n");
 116:     if (ops[node+4].ival) {
 117:         realexit = TRUE;
 118:         str_cat(str,"\n");
 119:         tab(str,level);
 120:         str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg));
 121:         str_free(fstr);
 122:         str_cat(str,"\n");
 123:     }
 124:     if (exitval)
 125:         str_cat(str,"exit ExitValue;\n");
 126:     if (do_fancy_opens) {
 127:         str_cat(str,"\n\
 128: sub Pick {\n\
 129:     ($name) = @_;\n\
 130:     $fh = $opened{$name};\n\
 131:     if (!$fh) {\n\
 132: 	$nextfh == 0 && open(fh_0,$name);\n\
 133: 	$nextfh == 1 && open(fh_1,$name);\n\
 134: 	$nextfh == 2 && open(fh_2,$name);\n\
 135: 	$nextfh == 3 && open(fh_3,$name);\n\
 136: 	$nextfh == 4 && open(fh_4,$name);\n\
 137: 	$nextfh == 5 && open(fh_5,$name);\n\
 138: 	$nextfh == 6 && open(fh_6,$name);\n\
 139: 	$nextfh == 7 && open(fh_7,$name);\n\
 140: 	$nextfh == 8 && open(fh_8,$name);\n\
 141: 	$nextfh == 9 && open(fh_9,$name);\n\
 142: 	$fh = $opened{$name} = 'fh_' . $nextfh++;\n\
 143:     }\n\
 144:     select($fh);\n\
 145: }\n\
 146: ");
 147:     }
 148:     break;
 149:     case OHUNKS:
 150:     str = walk(0,level,ops[node+1].ival,&numarg);
 151:     str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
 152:     str_free(fstr);
 153:     if (len == 3) {
 154:         str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
 155:         str_free(fstr);
 156:     }
 157:     else {
 158:     }
 159:     break;
 160:     case ORANGE:
 161:     str = walk(1,level,ops[node+1].ival,&numarg);
 162:     str_cat(str," .. ");
 163:     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
 164:     str_free(fstr);
 165:     break;
 166:     case OPAT:
 167:     goto def;
 168:     case OREGEX:
 169:     str = str_new(0);
 170:     str_set(str,"/");
 171:     tmpstr=walk(0,level,ops[node+1].ival,&numarg);
 172:     /* translate \nnn to [\nnn] */
 173:     for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
 174:         if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])) {
 175:         *d++ = '[';
 176:         *d++ = *s++;
 177:         *d++ = *s++;
 178:         *d++ = *s++;
 179:         *d++ = *s;
 180:         *d = ']';
 181:         }
 182:         else
 183:         *d = *s;
 184:     }
 185:     *d = '\0';
 186:     str_cat(str,tokenbuf);
 187:     str_free(tmpstr);
 188:     str_cat(str,"/");
 189:     break;
 190:     case OHUNK:
 191:     if (len == 1) {
 192:         str = str_new(0);
 193:         str = walk(0,level,oper1(OPRINT,0),&numarg);
 194:         str_cat(str," if ");
 195:         str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg));
 196:         str_free(fstr);
 197:         str_cat(str,";");
 198:     }
 199:     else {
 200:         tmpstr = walk(0,level,ops[node+1].ival,&numarg);
 201:         if (*tmpstr->str_ptr) {
 202:         str = str_new(0);
 203:         str_set(str,"if (");
 204:         str_scat(str,tmpstr);
 205:         str_cat(str,") {\n");
 206:         tab(str,++level);
 207:         str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
 208:         str_free(fstr);
 209:         fixtab(str,--level);
 210:         str_cat(str,"}\n");
 211:         tab(str,level);
 212:         }
 213:         else {
 214:         str = walk(0,level,ops[node+2].ival,&numarg);
 215:         }
 216:     }
 217:     break;
 218:     case OPPAREN:
 219:     str = str_new(0);
 220:     str_set(str,"(");
 221:     str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg));
 222:     str_free(fstr);
 223:     str_cat(str,")");
 224:     break;
 225:     case OPANDAND:
 226:     str = walk(1,level,ops[node+1].ival,&numarg);
 227:     str_cat(str," && ");
 228:     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
 229:     str_free(fstr);
 230:     break;
 231:     case OPOROR:
 232:     str = walk(1,level,ops[node+1].ival,&numarg);
 233:     str_cat(str," || ");
 234:     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
 235:     str_free(fstr);
 236:     break;
 237:     case OPNOT:
 238:     str = str_new(0);
 239:     str_set(str,"!");
 240:     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
 241:     str_free(fstr);
 242:     break;
 243:     case OCPAREN:
 244:     str = str_new(0);
 245:     str_set(str,"(");
 246:     str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg));
 247:     str_free(fstr);
 248:     numeric |= numarg;
 249:     str_cat(str,")");
 250:     break;
 251:     case OCANDAND:
 252:     str = walk(1,level,ops[node+1].ival,&numarg);
 253:     numeric = 1;
 254:     str_cat(str," && ");
 255:     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
 256:     str_free(fstr);
 257:     break;
 258:     case OCOROR:
 259:     str = walk(1,level,ops[node+1].ival,&numarg);
 260:     numeric = 1;
 261:     str_cat(str," || ");
 262:     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
 263:     str_free(fstr);
 264:     break;
 265:     case OCNOT:
 266:     str = str_new(0);
 267:     str_set(str,"!");
 268:     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
 269:     str_free(fstr);
 270:     numeric = 1;
 271:     break;
 272:     case ORELOP:
 273:     str = walk(1,level,ops[node+2].ival,&numarg);
 274:     numeric |= numarg;
 275:     tmpstr = walk(0,level,ops[node+1].ival,&numarg);
 276:     tmp2str = walk(1,level,ops[node+3].ival,&numarg);
 277:     numeric |= numarg;
 278:     if (!numeric) {
 279:         t = tmpstr->str_ptr;
 280:         if (strEQ(t,"=="))
 281:         str_set(tmpstr,"eq");
 282:         else if (strEQ(t,"!="))
 283:         str_set(tmpstr,"ne");
 284:         else if (strEQ(t,"<"))
 285:         str_set(tmpstr,"lt");
 286:         else if (strEQ(t,"<="))
 287:         str_set(tmpstr,"le");
 288:         else if (strEQ(t,">"))
 289:         str_set(tmpstr,"gt");
 290:         else if (strEQ(t,">="))
 291:         str_set(tmpstr,"ge");
 292:         if (!index(tmpstr->str_ptr,'\'') && !index(tmpstr->str_ptr,'"') &&
 293:           !index(tmp2str->str_ptr,'\'') && !index(tmp2str->str_ptr,'"') )
 294:         numeric |= 2;
 295:     }
 296:     if (numeric & 2) {
 297:         if (numeric & 1)        /* numeric is very good guess */
 298:         str_cat(str," ");
 299:         else
 300:         str_cat(str,"\377");
 301:         numeric = 1;
 302:     }
 303:     else
 304:         str_cat(str," ");
 305:     str_scat(str,tmpstr);
 306:     str_free(tmpstr);
 307:     str_cat(str," ");
 308:     str_scat(str,tmp2str);
 309:     str_free(tmp2str);
 310:     numeric = 1;
 311:     break;
 312:     case ORPAREN:
 313:     str = str_new(0);
 314:     str_set(str,"(");
 315:     str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg));
 316:     str_free(fstr);
 317:     numeric |= numarg;
 318:     str_cat(str,")");
 319:     break;
 320:     case OMATCHOP:
 321:     str = walk(1,level,ops[node+2].ival,&numarg);
 322:     str_cat(str," ");
 323:     tmpstr = walk(0,level,ops[node+1].ival,&numarg);
 324:     if (strEQ(tmpstr->str_ptr,"~"))
 325:         str_cat(str,"=~");
 326:     else {
 327:         str_scat(str,tmpstr);
 328:         str_free(tmpstr);
 329:     }
 330:     str_cat(str," ");
 331:     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg));
 332:     str_free(fstr);
 333:     numeric = 1;
 334:     break;
 335:     case OMPAREN:
 336:     str = str_new(0);
 337:     str_set(str,"(");
 338:     str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg));
 339:     str_free(fstr);
 340:     numeric |= numarg;
 341:     str_cat(str,")");
 342:     break;
 343:     case OCONCAT:
 344:     str = walk(1,level,ops[node+1].ival,&numarg);
 345:     str_cat(str," . ");
 346:     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
 347:     str_free(fstr);
 348:     break;
 349:     case OASSIGN:
 350:     str = walk(0,level,ops[node+2].ival,&numarg);
 351:     str_cat(str," ");
 352:     tmpstr = walk(0,level,ops[node+1].ival,&numarg);
 353:     str_scat(str,tmpstr);
 354:     if (str_len(tmpstr) > 1)
 355:         numeric = 1;
 356:     str_free(tmpstr);
 357:     str_cat(str," ");
 358:     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg));
 359:     str_free(fstr);
 360:     numeric |= numarg;
 361:     if (strEQ(str->str_ptr,"$FS = '\240'"))
 362:         str_set(str,"$FS = '[\240\\n\\t]+'");
 363:     break;
 364:     case OADD:
 365:     str = walk(1,level,ops[node+1].ival,&numarg);
 366:     str_cat(str," + ");
 367:     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
 368:     str_free(fstr);
 369:     numeric = 1;
 370:     break;
 371:     case OSUB:
 372:     str = walk(1,level,ops[node+1].ival,&numarg);
 373:     str_cat(str," - ");
 374:     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
 375:     str_free(fstr);
 376:     numeric = 1;
 377:     break;
 378:     case OMULT:
 379:     str = walk(1,level,ops[node+1].ival,&numarg);
 380:     str_cat(str," * ");
 381:     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
 382:     str_free(fstr);
 383:     numeric = 1;
 384:     break;
 385:     case ODIV:
 386:     str = walk(1,level,ops[node+1].ival,&numarg);
 387:     str_cat(str," / ");
 388:     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
 389:     str_free(fstr);
 390:     numeric = 1;
 391:     break;
 392:     case OMOD:
 393:     str = walk(1,level,ops[node+1].ival,&numarg);
 394:     str_cat(str," % ");
 395:     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
 396:     str_free(fstr);
 397:     numeric = 1;
 398:     break;
 399:     case OPOSTINCR:
 400:     str = walk(1,level,ops[node+1].ival,&numarg);
 401:     str_cat(str,"++");
 402:     numeric = 1;
 403:     break;
 404:     case OPOSTDECR:
 405:     str = walk(1,level,ops[node+1].ival,&numarg);
 406:     str_cat(str,"--");
 407:     numeric = 1;
 408:     break;
 409:     case OPREINCR:
 410:     str = str_new(0);
 411:     str_set(str,"++");
 412:     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
 413:     str_free(fstr);
 414:     numeric = 1;
 415:     break;
 416:     case OPREDECR:
 417:     str = str_new(0);
 418:     str_set(str,"--");
 419:     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
 420:     str_free(fstr);
 421:     numeric = 1;
 422:     break;
 423:     case OUMINUS:
 424:     str = str_new(0);
 425:     str_set(str,"-");
 426:     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
 427:     str_free(fstr);
 428:     numeric = 1;
 429:     break;
 430:     case OUPLUS:
 431:     numeric = 1;
 432:     goto def;
 433:     case OPAREN:
 434:     str = str_new(0);
 435:     str_set(str,"(");
 436:     str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg));
 437:     str_free(fstr);
 438:     str_cat(str,")");
 439:     numeric |= numarg;
 440:     break;
 441:     case OGETLINE:
 442:     str = str_new(0);
 443:     str_set(str,"$_ = <>;\n");
 444:     tab(str,level);
 445:     if (do_chop) {
 446:         str_cat(str,"chop;\t# strip record separator\n");
 447:         tab(str,level);
 448:     }
 449:     if (do_split)
 450:         emit_split(str,level);
 451:     break;
 452:     case OSPRINTF:
 453:     str = str_new(0);
 454:     str_set(str,"sprintf(");
 455:     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
 456:     str_free(fstr);
 457:     str_cat(str,")");
 458:     break;
 459:     case OSUBSTR:
 460:     str = str_new(0);
 461:     str_set(str,"substr(");
 462:     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
 463:     str_free(fstr);
 464:     str_cat(str,", ");
 465:     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
 466:     str_free(fstr);
 467:     str_cat(str,", ");
 468:     if (len == 3) {
 469:         str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg));
 470:         str_free(fstr);
 471:     }
 472:     else
 473:         str_cat(str,"999999");
 474:     str_cat(str,")");
 475:     break;
 476:     case OSTRING:
 477:     str = str_new(0);
 478:     str_set(str,ops[node+1].cval);
 479:     break;
 480:     case OSPLIT:
 481:     str = str_new(0);
 482:     numeric = 1;
 483:     tmpstr = walk(1,level,ops[node+2].ival,&numarg);
 484:     if (useval)
 485:         str_set(str,"(@");
 486:     else
 487:         str_set(str,"@");
 488:     str_scat(str,tmpstr);
 489:     str_cat(str," = split(");
 490:     if (len == 3) {
 491:         fstr = walk(1,level,ops[node+3].ival,&numarg);
 492:         if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
 493:         i = fstr->str_ptr[1] & 127;
 494:         if (index("*+?.[]()|^$\\",i))
 495:             sprintf(tokenbuf,"/\\%c/",i);
 496:         else
 497:             sprintf(tokenbuf,"/%c/",i);
 498:         str_cat(str,tokenbuf);
 499:         }
 500:         else
 501:         str_scat(str,fstr);
 502:         str_free(fstr);
 503:     }
 504:     else if (const_FS) {
 505:         sprintf(tokenbuf,"/[%c\\n]/",const_FS);
 506:         str_cat(str,tokenbuf);
 507:     }
 508:     else if (saw_FS)
 509:         str_cat(str,"$FS");
 510:     else
 511:         str_cat(str,"/[ \\t\\n]+/");
 512:     str_cat(str,", ");
 513:     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
 514:     str_free(fstr);
 515:     str_cat(str,")");
 516:     if (useval) {
 517:         str_cat(str,")");
 518:     }
 519:     str_free(tmpstr);
 520:     break;
 521:     case OINDEX:
 522:     str = str_new(0);
 523:     str_set(str,"index(");
 524:     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
 525:     str_free(fstr);
 526:     str_cat(str,", ");
 527:     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
 528:     str_free(fstr);
 529:     str_cat(str,")");
 530:     numeric = 1;
 531:     break;
 532:     case ONUM:
 533:     str = walk(1,level,ops[node+1].ival,&numarg);
 534:     numeric = 1;
 535:     break;
 536:     case OSTR:
 537:     tmpstr = walk(1,level,ops[node+1].ival,&numarg);
 538:     s = "'";
 539:     for (t = tmpstr->str_ptr; *t; t++) {
 540:         if (*t == '\\' || *t == '\'')
 541:         s = "\"";
 542:         *t += 128;
 543:     }
 544:     str = str_new(0);
 545:     str_set(str,s);
 546:     str_scat(str,tmpstr);
 547:     str_free(tmpstr);
 548:     str_cat(str,s);
 549:     break;
 550:     case OVAR:
 551:     str = str_new(0);
 552:     str_set(str,"$");
 553:     str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg));
 554:     if (len == 1) {
 555:         tmp2str = hfetch(symtab,tmpstr->str_ptr);
 556:         if (tmp2str && atoi(tmp2str->str_ptr))
 557:         numeric = 2;
 558:         if (strEQ(str->str_ptr,"$NR")) {
 559:         numeric = 1;
 560:         str_set(str,"$.");
 561:         }
 562:         else if (strEQ(str->str_ptr,"$NF")) {
 563:         numeric = 1;
 564:         str_set(str,"$#Fld");
 565:         }
 566:         else if (strEQ(str->str_ptr,"$0"))
 567:         str_set(str,"$_");
 568:     }
 569:     else {
 570:         str_cat(tmpstr,"[]");
 571:         tmp2str = hfetch(symtab,tmpstr->str_ptr);
 572:         if (tmp2str && atoi(tmp2str->str_ptr))
 573:         str_cat(str,"[");
 574:         else
 575:         str_cat(str,"{");
 576:         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
 577:         str_free(fstr);
 578:         if (tmp2str && atoi(tmp2str->str_ptr))
 579:         strcpy(tokenbuf,"]");
 580:         else
 581:         strcpy(tokenbuf,"}");
 582:         *tokenbuf += 128;
 583:         str_cat(str,tokenbuf);
 584:     }
 585:     str_free(tmpstr);
 586:     break;
 587:     case OFLD:
 588:     str = str_new(0);
 589:     if (split_to_array) {
 590:         str_set(str,"$Fld");
 591:         str_cat(str,"[");
 592:         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
 593:         str_free(fstr);
 594:         str_cat(str,"]");
 595:     }
 596:     else {
 597:         i = atoi(walk(1,level,ops[node+1].ival,&numarg)->str_ptr);
 598:         if (i <= arymax)
 599:         sprintf(tokenbuf,"$%s",nameary[i]);
 600:         else
 601:         sprintf(tokenbuf,"$Fld%d",i);
 602:         str_set(str,tokenbuf);
 603:     }
 604:     break;
 605:     case OVFLD:
 606:     str = str_new(0);
 607:     str_set(str,"$Fld[");
 608:     i = ops[node+1].ival;
 609:     if ((ops[i].ival & 255) == OPAREN)
 610:         i = ops[i+1].ival;
 611:     tmpstr=walk(1,level,i,&numarg);
 612:     str_scat(str,tmpstr);
 613:     str_free(tmpstr);
 614:     str_cat(str,"]");
 615:     break;
 616:     case OJUNK:
 617:     goto def;
 618:     case OSNEWLINE:
 619:     str = str_new(2);
 620:     str_set(str,";\n");
 621:     tab(str,level);
 622:     break;
 623:     case ONEWLINE:
 624:     str = str_new(1);
 625:     str_set(str,"\n");
 626:     tab(str,level);
 627:     break;
 628:     case OSCOMMENT:
 629:     str = str_new(0);
 630:     str_set(str,";");
 631:     tmpstr = walk(0,level,ops[node+1].ival,&numarg);
 632:     for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
 633:         *s += 128;
 634:     str_scat(str,tmpstr);
 635:     str_free(tmpstr);
 636:     tab(str,level);
 637:     break;
 638:     case OCOMMENT:
 639:     str = str_new(0);
 640:     tmpstr = walk(0,level,ops[node+1].ival,&numarg);
 641:     for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
 642:         *s += 128;
 643:     str_scat(str,tmpstr);
 644:     str_free(tmpstr);
 645:     tab(str,level);
 646:     break;
 647:     case OCOMMA:
 648:     str = walk(1,level,ops[node+1].ival,&numarg);
 649:     str_cat(str,", ");
 650:     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
 651:     str_free(fstr);
 652:     break;
 653:     case OSEMICOLON:
 654:     str = str_new(1);
 655:     str_set(str,"; ");
 656:     break;
 657:     case OSTATES:
 658:     str = walk(0,level,ops[node+1].ival,&numarg);
 659:     str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
 660:     str_free(fstr);
 661:     break;
 662:     case OSTATE:
 663:     str = str_new(0);
 664:     if (len >= 1) {
 665:         str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg));
 666:         str_free(fstr);
 667:         if (len >= 2) {
 668:         tmpstr = walk(0,level,ops[node+2].ival,&numarg);
 669:         if (*tmpstr->str_ptr == ';') {
 670:             addsemi(str);
 671:             str_cat(str,tmpstr->str_ptr+1);
 672:         }
 673:         str_free(tmpstr);
 674:         }
 675:     }
 676:     break;
 677:     case OPRINTF:
 678:     case OPRINT:
 679:     str = str_new(0);
 680:     if (len == 3) {     /* output redirection */
 681:         tmpstr = walk(1,level,ops[node+3].ival,&numarg);
 682:         tmp2str = walk(1,level,ops[node+2].ival,&numarg);
 683:         if (!do_fancy_opens) {
 684:         t = tmpstr->str_ptr;
 685:         if (*t == '"' || *t == '\'')
 686:             t = cpytill(tokenbuf,t+1,*t);
 687:         else
 688:             fatal("Internal error: OPRINT");
 689:         d = savestr(t);
 690:         s = savestr(tokenbuf);
 691:         for (t = tokenbuf; *t; t++) {
 692:             *t &= 127;
 693:             if (!isalpha(*t) && !isdigit(*t))
 694:             *t = '_';
 695:         }
 696:         if (!index(tokenbuf,'_'))
 697:             strcpy(t,"_fh");
 698:         str_cat(opens,"open(");
 699:         str_cat(opens,tokenbuf);
 700:         str_cat(opens,", ");
 701:         d[1] = '\0';
 702:         str_cat(opens,d);
 703:         str_scat(opens,tmp2str);
 704:         str_cat(opens,tmpstr->str_ptr+1);
 705:         if (*tmp2str->str_ptr == '|')
 706:             str_cat(opens,") || die 'Cannot pipe to \"");
 707:         else
 708:             str_cat(opens,") || die 'Cannot create file \"");
 709:         if (*d == '"')
 710:             str_cat(opens,"'.\"");
 711:         str_cat(opens,s);
 712:         if (*d == '"')
 713:             str_cat(opens,"\".'");
 714:         str_cat(opens,"\".';\n");
 715:         str_free(tmpstr);
 716:         str_free(tmp2str);
 717:         safefree(s);
 718:         safefree(d);
 719:         }
 720:         else {
 721:         sprintf(tokenbuf,"do Pick('%s' . (%s)) &&\n",
 722:            tmp2str->str_ptr, tmpstr->str_ptr);
 723:         str_cat(str,tokenbuf);
 724:         tab(str,level+1);
 725:         *tokenbuf = '\0';
 726:         str_free(tmpstr);
 727:         str_free(tmp2str);
 728:         }
 729:     }
 730:     else
 731:         strcpy(tokenbuf,"stdout");
 732:     if (type == OPRINTF)
 733:         str_cat(str,"printf");
 734:     else
 735:         str_cat(str,"print");
 736:     if (len == 3 || do_fancy_opens) {
 737:         if (*tokenbuf)
 738:         str_cat(str," ");
 739:         str_cat(str,tokenbuf);
 740:     }
 741:     tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg);
 742:     if (!*tmpstr->str_ptr && lval_field) {
 743:         t = saw_OFS ? "$," : "' '";
 744:         if (split_to_array) {
 745:         sprintf(tokenbuf,"join(%s,@Fld)",t);
 746:         str_cat(tmpstr,tokenbuf);
 747:         }
 748:         else {
 749:         for (i = 1; i < maxfld; i++) {
 750:             if (i <= arymax)
 751:             sprintf(tokenbuf,"$%s, ",nameary[i]);
 752:             else
 753:             sprintf(tokenbuf,"$Fld%d, ",i);
 754:             str_cat(tmpstr,tokenbuf);
 755:         }
 756:         if (maxfld <= arymax)
 757:             sprintf(tokenbuf,"$%s",nameary[maxfld]);
 758:         else
 759:             sprintf(tokenbuf,"$Fld%d",maxfld);
 760:         str_cat(tmpstr,tokenbuf);
 761:         }
 762:     }
 763:     if (*tmpstr->str_ptr) {
 764:         str_cat(str," ");
 765:         str_scat(str,tmpstr);
 766:     }
 767:     else {
 768:         str_cat(str," $_");
 769:     }
 770:     str_free(tmpstr);
 771:     break;
 772:     case OLENGTH:
 773:     str = str_make("length(");
 774:     goto maybe0;
 775:     case OLOG:
 776:     str = str_make("log(");
 777:     goto maybe0;
 778:     case OEXP:
 779:     str = str_make("exp(");
 780:     goto maybe0;
 781:     case OSQRT:
 782:     str = str_make("sqrt(");
 783:     goto maybe0;
 784:     case OINT:
 785:     str = str_make("int(");
 786:       maybe0:
 787:     numeric = 1;
 788:     if (len > 0)
 789:         tmpstr = walk(1,level,ops[node+1].ival,&numarg);
 790:     else
 791:         tmpstr = str_new(0);;
 792:     if (!*tmpstr->str_ptr) {
 793:         if (lval_field) {
 794:         t = saw_OFS ? "$," : "' '";
 795:         if (split_to_array) {
 796:             sprintf(tokenbuf,"join(%s,@Fld)",t);
 797:             str_cat(tmpstr,tokenbuf);
 798:         }
 799:         else {
 800:             sprintf(tokenbuf,"join(%s, ",t);
 801:             str_cat(tmpstr,tokenbuf);
 802:             for (i = 1; i < maxfld; i++) {
 803:             if (i <= arymax)
 804:                 sprintf(tokenbuf,"$%s,",nameary[i]);
 805:             else
 806:                 sprintf(tokenbuf,"$Fld%d,",i);
 807:             str_cat(tmpstr,tokenbuf);
 808:             }
 809:             if (maxfld <= arymax)
 810:             sprintf(tokenbuf,"$%s)",nameary[maxfld]);
 811:             else
 812:             sprintf(tokenbuf,"$Fld%d)",maxfld);
 813:             str_cat(tmpstr,tokenbuf);
 814:         }
 815:         }
 816:         else
 817:         str_cat(tmpstr,"$_");
 818:     }
 819:     if (strEQ(tmpstr->str_ptr,"$_")) {
 820:         if (type == OLENGTH && !do_chop) {
 821:         str = str_make("(length(");
 822:         str_cat(tmpstr,") - 1");
 823:         }
 824:     }
 825:     str_scat(str,tmpstr);
 826:     str_free(tmpstr);
 827:     str_cat(str,")");
 828:     break;
 829:     case OBREAK:
 830:     str = str_new(0);
 831:     str_set(str,"last");
 832:     break;
 833:     case ONEXT:
 834:     str = str_new(0);
 835:     str_set(str,"next line");
 836:     break;
 837:     case OEXIT:
 838:     str = str_new(0);
 839:     if (realexit) {
 840:         str_set(str,"exit");
 841:         if (len == 1) {
 842:         str_cat(str," ");
 843:         exitval = TRUE;
 844:         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
 845:         str_free(fstr);
 846:         }
 847:     }
 848:     else {
 849:         if (len == 1) {
 850:         str_set(str,"ExitValue = ");
 851:         exitval = TRUE;
 852:         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
 853:         str_free(fstr);
 854:         str_cat(str,"; ");
 855:         }
 856:         str_cat(str,"last line");
 857:     }
 858:     break;
 859:     case OCONTINUE:
 860:     str = str_new(0);
 861:     str_set(str,"next");
 862:     break;
 863:     case OREDIR:
 864:     goto def;
 865:     case OIF:
 866:     str = str_new(0);
 867:     str_set(str,"if (");
 868:     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
 869:     str_free(fstr);
 870:     str_cat(str,") ");
 871:     str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
 872:     str_free(fstr);
 873:     if (len == 3) {
 874:         i = ops[node+3].ival;
 875:         if (i) {
 876:         if ((ops[i].ival & 255) == OBLOCK) {
 877:             i = ops[i+1].ival;
 878:             if (i) {
 879:             if ((ops[i].ival & 255) != OIF)
 880:                 i = 0;
 881:             }
 882:         }
 883:         else
 884:             i = 0;
 885:         }
 886:         if (i) {
 887:         str_cat(str,"els");
 888:         str_scat(str,fstr=walk(0,level,i,&numarg));
 889:         str_free(fstr);
 890:         }
 891:         else {
 892:         str_cat(str,"else ");
 893:         str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
 894:         str_free(fstr);
 895:         }
 896:     }
 897:     break;
 898:     case OWHILE:
 899:     str = str_new(0);
 900:     str_set(str,"while (");
 901:     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
 902:     str_free(fstr);
 903:     str_cat(str,") ");
 904:     str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
 905:     str_free(fstr);
 906:     break;
 907:     case OFOR:
 908:     str = str_new(0);
 909:     str_set(str,"for (");
 910:     str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg));
 911:     i = numarg;
 912:     if (i) {
 913:         t = s = tmpstr->str_ptr;
 914:         while (isalpha(*t) || isdigit(*t) || *t == '$' || *t == '_')
 915:         t++;
 916:         i = t - s;
 917:         if (i < 2)
 918:         i = 0;
 919:     }
 920:     str_cat(str,"; ");
 921:     fstr=walk(1,level,ops[node+2].ival,&numarg);
 922:     if (i && (t = index(fstr->str_ptr,0377))) {
 923:         if (strnEQ(fstr->str_ptr,s,i))
 924:         *t = ' ';
 925:     }
 926:     str_scat(str,fstr);
 927:     str_free(fstr);
 928:     str_free(tmpstr);
 929:     str_cat(str,"; ");
 930:     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg));
 931:     str_free(fstr);
 932:     str_cat(str,") ");
 933:     str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg));
 934:     str_free(fstr);
 935:     break;
 936:     case OFORIN:
 937:     tmpstr=walk(0,level,ops[node+2].ival,&numarg);
 938:     str = str_new(0);
 939:     str_sset(str,tmpstr);
 940:     str_cat(str,"[]");
 941:     tmp2str = hfetch(symtab,str->str_ptr);
 942:     if (tmp2str && atoi(tmp2str->str_ptr)) {
 943:         maxtmp++;
 944:         fstr=walk(1,level,ops[node+1].ival,&numarg);
 945:         sprintf(tokenbuf,
 946:           "for ($T_%d = 1; ($%s = $%s[$T_%d]) || $T_%d <= $#%s; $T_%d++)%c",
 947:           maxtmp,
 948:           fstr->str_ptr,
 949:           tmpstr->str_ptr,
 950:           maxtmp,
 951:           maxtmp,
 952:           tmpstr->str_ptr,
 953:           maxtmp,
 954:           0377);
 955:         str_set(str,tokenbuf);
 956:         str_free(fstr);
 957:         str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
 958:         str_free(fstr);
 959:     }
 960:     else {
 961:         str_set(str,"while (($junkkey,$");
 962:         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
 963:         str_free(fstr);
 964:         str_cat(str,") = each(");
 965:         str_scat(str,tmpstr);
 966:         str_cat(str,")) ");
 967:         str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
 968:         str_free(fstr);
 969:     }
 970:     str_free(tmpstr);
 971:     break;
 972:     case OBLOCK:
 973:     str = str_new(0);
 974:     str_set(str,"{");
 975:     if (len == 2) {
 976:         str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
 977:         str_free(fstr);
 978:     }
 979:     fixtab(str,++level);
 980:     str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg));
 981:     str_free(fstr);
 982:     addsemi(str);
 983:     fixtab(str,--level);
 984:     str_cat(str,"}\n");
 985:     tab(str,level);
 986:     break;
 987:     default:
 988:       def:
 989:     if (len) {
 990:         if (len > 5)
 991:         fatal("Garbage length in walk");
 992:         str = walk(0,level,ops[node+1].ival,&numarg);
 993:         for (i = 2; i<= len; i++) {
 994:         str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg));
 995:         str_free(fstr);
 996:         }
 997:     }
 998:     else {
 999:         str = Nullstr;
1000:     }
1001:     break;
1002:     }
1003:     if (!str)
1004:     str = str_new(0);
1005:     *numericptr = numeric;
1006: #ifdef DEBUGGING
1007:     if (debug & 4) {
1008:     printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
1009:     for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
1010:         if (*t == '\n')
1011:         printf("\\n");
1012:         else if (*t == '\t')
1013:         printf("\\t");
1014:         else
1015:         putchar(*t);
1016:     putchar('\n');
1017:     }
1018: #endif
1019:     return str;
1020: }
1021: 
1022: tab(str,lvl)
1023: register STR *str;
1024: register int lvl;
1025: {
1026:     while (lvl > 1) {
1027:     str_cat(str,"\t");
1028:     lvl -= 2;
1029:     }
1030:     if (lvl)
1031:     str_cat(str,"    ");
1032: }
1033: 
1034: fixtab(str,lvl)
1035: register STR *str;
1036: register int lvl;
1037: {
1038:     register char *s;
1039: 
1040:     /* strip trailing white space */
1041: 
1042:     s = str->str_ptr+str->str_cur - 1;
1043:     while (s >= str->str_ptr && (*s == ' ' || *s == '\t'))
1044:     s--;
1045:     s[1] = '\0';
1046:     str->str_cur = s + 1 - str->str_ptr;
1047:     if (s >= str->str_ptr && *s != '\n')
1048:     str_cat(str,"\n");
1049: 
1050:     tab(str,lvl);
1051: }
1052: 
1053: addsemi(str)
1054: register STR *str;
1055: {
1056:     register char *s;
1057: 
1058:     s = str->str_ptr+str->str_cur - 1;
1059:     while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1060:     s--;
1061:     if (s >= str->str_ptr && *s != ';' && *s != '}')
1062:     str_cat(str,";");
1063: }
1064: 
1065: emit_split(str,level)
1066: register STR *str;
1067: int level;
1068: {
1069:     register int i;
1070: 
1071:     if (split_to_array)
1072:     str_cat(str,"@Fld");
1073:     else {
1074:     str_cat(str,"(");
1075:     for (i = 1; i < maxfld; i++) {
1076:         if (i <= arymax)
1077:         sprintf(tokenbuf,"$%s,",nameary[i]);
1078:         else
1079:         sprintf(tokenbuf,"$Fld%d,",i);
1080:         str_cat(str,tokenbuf);
1081:     }
1082:     if (maxfld <= arymax)
1083:         sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1084:     else
1085:         sprintf(tokenbuf,"$Fld%d)",maxfld);
1086:     str_cat(str,tokenbuf);
1087:     }
1088:     if (const_FS) {
1089:     sprintf(tokenbuf," = split(/[%c\\n]/);\n",const_FS);
1090:     str_cat(str,tokenbuf);
1091:     }
1092:     else if (saw_FS)
1093:     str_cat(str," = split($FS);\n");
1094:     else
1095:     str_cat(str," = split;\n");
1096:     tab(str,level);
1097: }
1098: 
1099: prewalk(numit,level,node,numericptr)
1100: int numit;
1101: int level;
1102: register int node;
1103: int *numericptr;
1104: {
1105:     register int len;
1106:     register int type;
1107:     register int i;
1108:     char *t;
1109:     char *d, *s;
1110:     int numarg;
1111:     int numeric = FALSE;
1112: 
1113:     if (!node) {
1114:     *numericptr = 0;
1115:     return 0;
1116:     }
1117:     type = ops[node].ival;
1118:     len = type >> 8;
1119:     type &= 255;
1120:     switch (type) {
1121:     case OPROG:
1122:     prewalk(0,level,ops[node+1].ival,&numarg);
1123:     if (ops[node+2].ival) {
1124:         prewalk(0,level,ops[node+2].ival,&numarg);
1125:     }
1126:     ++level;
1127:     prewalk(0,level,ops[node+3].ival,&numarg);
1128:     --level;
1129:     if (ops[node+3].ival) {
1130:         prewalk(0,level,ops[node+4].ival,&numarg);
1131:     }
1132:     break;
1133:     case OHUNKS:
1134:     prewalk(0,level,ops[node+1].ival,&numarg);
1135:     prewalk(0,level,ops[node+2].ival,&numarg);
1136:     if (len == 3) {
1137:         prewalk(0,level,ops[node+3].ival,&numarg);
1138:     }
1139:     break;
1140:     case ORANGE:
1141:     prewalk(1,level,ops[node+1].ival,&numarg);
1142:     prewalk(1,level,ops[node+2].ival,&numarg);
1143:     break;
1144:     case OPAT:
1145:     goto def;
1146:     case OREGEX:
1147:     prewalk(0,level,ops[node+1].ival,&numarg);
1148:     break;
1149:     case OHUNK:
1150:     if (len == 1) {
1151:         prewalk(0,level,ops[node+1].ival,&numarg);
1152:     }
1153:     else {
1154:         i = prewalk(0,level,ops[node+1].ival,&numarg);
1155:         if (i) {
1156:         ++level;
1157:         prewalk(0,level,ops[node+2].ival,&numarg);
1158:         --level;
1159:         }
1160:         else {
1161:         prewalk(0,level,ops[node+2].ival,&numarg);
1162:         }
1163:     }
1164:     break;
1165:     case OPPAREN:
1166:     prewalk(0,level,ops[node+1].ival,&numarg);
1167:     break;
1168:     case OPANDAND:
1169:     prewalk(0,level,ops[node+1].ival,&numarg);
1170:     prewalk(0,level,ops[node+2].ival,&numarg);
1171:     break;
1172:     case OPOROR:
1173:     prewalk(0,level,ops[node+1].ival,&numarg);
1174:     prewalk(0,level,ops[node+2].ival,&numarg);
1175:     break;
1176:     case OPNOT:
1177:     prewalk(0,level,ops[node+1].ival,&numarg);
1178:     break;
1179:     case OCPAREN:
1180:     prewalk(0,level,ops[node+1].ival,&numarg);
1181:     numeric |= numarg;
1182:     break;
1183:     case OCANDAND:
1184:     prewalk(0,level,ops[node+1].ival,&numarg);
1185:     numeric = 1;
1186:     prewalk(0,level,ops[node+2].ival,&numarg);
1187:     break;
1188:     case OCOROR:
1189:     prewalk(0,level,ops[node+1].ival,&numarg);
1190:     numeric = 1;
1191:     prewalk(0,level,ops[node+2].ival,&numarg);
1192:     break;
1193:     case OCNOT:
1194:     prewalk(0,level,ops[node+1].ival,&numarg);
1195:     numeric = 1;
1196:     break;
1197:     case ORELOP:
1198:     prewalk(0,level,ops[node+2].ival,&numarg);
1199:     numeric |= numarg;
1200:     prewalk(0,level,ops[node+1].ival,&numarg);
1201:     prewalk(0,level,ops[node+3].ival,&numarg);
1202:     numeric |= numarg;
1203:     numeric = 1;
1204:     break;
1205:     case ORPAREN:
1206:     prewalk(0,level,ops[node+1].ival,&numarg);
1207:     numeric |= numarg;
1208:     break;
1209:     case OMATCHOP:
1210:     prewalk(0,level,ops[node+2].ival,&numarg);
1211:     prewalk(0,level,ops[node+1].ival,&numarg);
1212:     prewalk(0,level,ops[node+3].ival,&numarg);
1213:     numeric = 1;
1214:     break;
1215:     case OMPAREN:
1216:     prewalk(0,level,ops[node+1].ival,&numarg);
1217:     numeric |= numarg;
1218:     break;
1219:     case OCONCAT:
1220:     prewalk(0,level,ops[node+1].ival,&numarg);
1221:     prewalk(0,level,ops[node+2].ival,&numarg);
1222:     break;
1223:     case OASSIGN:
1224:     prewalk(0,level,ops[node+2].ival,&numarg);
1225:     prewalk(0,level,ops[node+1].ival,&numarg);
1226:     prewalk(0,level,ops[node+3].ival,&numarg);
1227:     if (numarg || strlen(ops[ops[node+1].ival+1].cval) > 1) {
1228:         numericize(ops[node+2].ival);
1229:         if (!numarg)
1230:         numericize(ops[node+3].ival);
1231:     }
1232:     numeric |= numarg;
1233:     break;
1234:     case OADD:
1235:     prewalk(1,level,ops[node+1].ival,&numarg);
1236:     prewalk(1,level,ops[node+2].ival,&numarg);
1237:     numeric = 1;
1238:     break;
1239:     case OSUB:
1240:     prewalk(1,level,ops[node+1].ival,&numarg);
1241:     prewalk(1,level,ops[node+2].ival,&numarg);
1242:     numeric = 1;
1243:     break;
1244:     case OMULT:
1245:     prewalk(1,level,ops[node+1].ival,&numarg);
1246:     prewalk(1,level,ops[node+2].ival,&numarg);
1247:     numeric = 1;
1248:     break;
1249:     case ODIV:
1250:     prewalk(1,level,ops[node+1].ival,&numarg);
1251:     prewalk(1,level,ops[node+2].ival,&numarg);
1252:     numeric = 1;
1253:     break;
1254:     case OMOD:
1255:     prewalk(1,level,ops[node+1].ival,&numarg);
1256:     prewalk(1,level,ops[node+2].ival,&numarg);
1257:     numeric = 1;
1258:     break;
1259:     case OPOSTINCR:
1260:     prewalk(1,level,ops[node+1].ival,&numarg);
1261:     numeric = 1;
1262:     break;
1263:     case OPOSTDECR:
1264:     prewalk(1,level,ops[node+1].ival,&numarg);
1265:     numeric = 1;
1266:     break;
1267:     case OPREINCR:
1268:     prewalk(1,level,ops[node+1].ival,&numarg);
1269:     numeric = 1;
1270:     break;
1271:     case OPREDECR:
1272:     prewalk(1,level,ops[node+1].ival,&numarg);
1273:     numeric = 1;
1274:     break;
1275:     case OUMINUS:
1276:     prewalk(1,level,ops[node+1].ival,&numarg);
1277:     numeric = 1;
1278:     break;
1279:     case OUPLUS:
1280:     prewalk(1,level,ops[node+1].ival,&numarg);
1281:     numeric = 1;
1282:     break;
1283:     case OPAREN:
1284:     prewalk(0,level,ops[node+1].ival,&numarg);
1285:     numeric |= numarg;
1286:     break;
1287:     case OGETLINE:
1288:     break;
1289:     case OSPRINTF:
1290:     prewalk(0,level,ops[node+1].ival,&numarg);
1291:     break;
1292:     case OSUBSTR:
1293:     prewalk(0,level,ops[node+1].ival,&numarg);
1294:     prewalk(1,level,ops[node+2].ival,&numarg);
1295:     if (len == 3) {
1296:         prewalk(1,level,ops[node+3].ival,&numarg);
1297:     }
1298:     break;
1299:     case OSTRING:
1300:     break;
1301:     case OSPLIT:
1302:     numeric = 1;
1303:     prewalk(0,level,ops[node+2].ival,&numarg);
1304:     if (len == 3)
1305:         prewalk(0,level,ops[node+3].ival,&numarg);
1306:     prewalk(0,level,ops[node+1].ival,&numarg);
1307:     break;
1308:     case OINDEX:
1309:     prewalk(0,level,ops[node+1].ival,&numarg);
1310:     prewalk(0,level,ops[node+2].ival,&numarg);
1311:     numeric = 1;
1312:     break;
1313:     case ONUM:
1314:     prewalk(0,level,ops[node+1].ival,&numarg);
1315:     numeric = 1;
1316:     break;
1317:     case OSTR:
1318:     prewalk(0,level,ops[node+1].ival,&numarg);
1319:     break;
1320:     case OVAR:
1321:     prewalk(0,level,ops[node+1].ival,&numarg);
1322:     if (len == 1) {
1323:         if (numit)
1324:         numericize(node);
1325:     }
1326:     else {
1327:         prewalk(0,level,ops[node+2].ival,&numarg);
1328:     }
1329:     break;
1330:     case OFLD:
1331:     prewalk(0,level,ops[node+1].ival,&numarg);
1332:     break;
1333:     case OVFLD:
1334:     i = ops[node+1].ival;
1335:     prewalk(0,level,i,&numarg);
1336:     break;
1337:     case OJUNK:
1338:     goto def;
1339:     case OSNEWLINE:
1340:     break;
1341:     case ONEWLINE:
1342:     break;
1343:     case OSCOMMENT:
1344:     break;
1345:     case OCOMMENT:
1346:     break;
1347:     case OCOMMA:
1348:     prewalk(0,level,ops[node+1].ival,&numarg);
1349:     prewalk(0,level,ops[node+2].ival,&numarg);
1350:     break;
1351:     case OSEMICOLON:
1352:     break;
1353:     case OSTATES:
1354:     prewalk(0,level,ops[node+1].ival,&numarg);
1355:     prewalk(0,level,ops[node+2].ival,&numarg);
1356:     break;
1357:     case OSTATE:
1358:     if (len >= 1) {
1359:         prewalk(0,level,ops[node+1].ival,&numarg);
1360:         if (len >= 2) {
1361:         prewalk(0,level,ops[node+2].ival,&numarg);
1362:         }
1363:     }
1364:     break;
1365:     case OPRINTF:
1366:     case OPRINT:
1367:     if (len == 3) {     /* output redirection */
1368:         prewalk(0,level,ops[node+3].ival,&numarg);
1369:         prewalk(0,level,ops[node+2].ival,&numarg);
1370:     }
1371:     prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
1372:     break;
1373:     case OLENGTH:
1374:     goto maybe0;
1375:     case OLOG:
1376:     goto maybe0;
1377:     case OEXP:
1378:     goto maybe0;
1379:     case OSQRT:
1380:     goto maybe0;
1381:     case OINT:
1382:       maybe0:
1383:     numeric = 1;
1384:     if (len > 0)
1385:         prewalk(type != OLENGTH,level,ops[node+1].ival,&numarg);
1386:     break;
1387:     case OBREAK:
1388:     break;
1389:     case ONEXT:
1390:     break;
1391:     case OEXIT:
1392:     if (len == 1) {
1393:         prewalk(1,level,ops[node+1].ival,&numarg);
1394:     }
1395:     break;
1396:     case OCONTINUE:
1397:     break;
1398:     case OREDIR:
1399:     goto def;
1400:     case OIF:
1401:     prewalk(0,level,ops[node+1].ival,&numarg);
1402:     prewalk(0,level,ops[node+2].ival,&numarg);
1403:     if (len == 3) {
1404:         prewalk(0,level,ops[node+3].ival,&numarg);
1405:     }
1406:     break;
1407:     case OWHILE:
1408:     prewalk(0,level,ops[node+1].ival,&numarg);
1409:     prewalk(0,level,ops[node+2].ival,&numarg);
1410:     break;
1411:     case OFOR:
1412:     prewalk(0,level,ops[node+1].ival,&numarg);
1413:     prewalk(0,level,ops[node+2].ival,&numarg);
1414:     prewalk(0,level,ops[node+3].ival,&numarg);
1415:     prewalk(0,level,ops[node+4].ival,&numarg);
1416:     break;
1417:     case OFORIN:
1418:     prewalk(0,level,ops[node+2].ival,&numarg);
1419:     prewalk(0,level,ops[node+1].ival,&numarg);
1420:     prewalk(0,level,ops[node+3].ival,&numarg);
1421:     break;
1422:     case OBLOCK:
1423:     if (len == 2) {
1424:         prewalk(0,level,ops[node+2].ival,&numarg);
1425:     }
1426:     ++level;
1427:     prewalk(0,level,ops[node+1].ival,&numarg);
1428:     --level;
1429:     break;
1430:     default:
1431:       def:
1432:     if (len) {
1433:         if (len > 5)
1434:         fatal("Garbage length in prewalk");
1435:         prewalk(0,level,ops[node+1].ival,&numarg);
1436:         for (i = 2; i<= len; i++) {
1437:         prewalk(0,level,ops[node+i].ival,&numarg);
1438:         }
1439:     }
1440:     break;
1441:     }
1442:     *numericptr = numeric;
1443:     return 1;
1444: }
1445: 
1446: numericize(node)
1447: register int node;
1448: {
1449:     register int len;
1450:     register int type;
1451:     register int i;
1452:     STR *tmpstr;
1453:     STR *tmp2str;
1454:     int numarg;
1455: 
1456:     type = ops[node].ival;
1457:     len = type >> 8;
1458:     type &= 255;
1459:     if (type == OVAR && len == 1) {
1460:     tmpstr=walk(0,0,ops[node+1].ival,&numarg);
1461:     tmp2str = str_make("1");
1462:     hstore(symtab,tmpstr->str_ptr,tmp2str);
1463:     }
1464: }

Defined functions

addsemi defined in line 1053; used 2 times
emit_split defined in line 1065; used 2 times
fixtab defined in line 1034; used 4 times
numericize defined in line 1446; used 3 times
prewalk defined in line 1099; used 99 times
tab defined in line 1022; used 15 times
walk defined in line 18; used 109 times

Defined variables

maxtmp defined in line 16; used 5 times
Last modified: 1988-01-31
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 6403
Valid CSS Valid XHTML 1.0 Strict