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

Defined functions

addsemi defined in line 1056; used 2 times
emit_split defined in line 1068; used 2 times
fixtab defined in line 1037; used 4 times
numericize defined in line 1449; used 3 times
prewalk defined in line 1102; used 99 times
tab defined in line 1025; used 15 times
walk defined in line 21; used 109 times

Defined variables

maxtmp defined in line 19; used 5 times
Last modified: 1988-02-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 6736
Valid CSS Valid XHTML 1.0 Strict