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

Defined functions

addsemi defined in line 1060; used 2 times
emit_split defined in line 1072; used 2 times
fixtab defined in line 1041; used 4 times
numericize defined in line 1453; used 3 times
prewalk defined in line 1106; used 99 times
tab defined in line 1029; used 15 times
walk defined in line 27; used 109 times

Defined variables

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