# 2.11BSD#431 - /usr/src/new/PORT/perl.1.0.10/cmd.c

##### Functions

    cmd_exec          X
    copyopt           X
    deb               X

       1: /* $Header: cmd.c,v 1.0.1.1 88/01/21 21:24:16 root Exp $
       2:  *
       3:  * $Log:	cmd.c,v $
       4:  * Revision 1.0.1.1  88/01/21  21:24:16  root
       5:  * The redo cmd got a segmentation fault because trace context stack overflowed.
       6:  *
       7:  * Revision 1.0  87/12/18  13:04:51  root
       8:  * Initial revision
       9:  *
      10:  */
      11:
      12: #include "handy.h"
      13: #include "EXTERN.h"
      14: #include "search.h"
      15: #include "util.h"
      16: #include "perl.h"
      17:
      18: static STR str_chop;
      19:
      20: /* This is the main command loop.  We try to spend as much time in this loop
      21:  * as possible, so lots of optimizations do their activities in here.  This
      22:  * means things get a little sloppy.
      23:  */
      24:
      25: STR *
      26: cmd_exec(cmd)
      27: register CMD *cmd;
      28: {
      29:     SPAT *oldspat;
      30: #ifdef DEBUGGING
      31:     int olddlevel;
      32:     int entdlevel;
      33: #endif
      34:     register STR *retstr;
      35:     register char *tmps;
      36:     register int cmdflags;
      37:     register bool match;
      38:     register char *go_to = goto_targ;
      39:     ARG *arg;
      40:     FILE *fp;
      41:
      42:     retstr = &str_no;
      43: #ifdef DEBUGGING
      44:     entdlevel = dlevel;
      45: #endif
      46: tail_recursion_entry:
      47: #ifdef DEBUGGING
      48:     dlevel = entdlevel;
      49: #endif
      50:     if (cmd == Nullcmd)
      51:     return retstr;
      52:     cmdflags = cmd->c_flags;    /* hopefully load register */
      53:     if (go_to) {
      54:     if (cmd->c_label && strEQ(go_to,cmd->c_label))
      55:         goto_targ = go_to = Nullch;     /* here at last */
      56:     else {
      57:         switch (cmd->c_type) {
      58:         case C_IF:
      59:         oldspat = curspat;
      60: #ifdef DEBUGGING
      61:         olddlevel = dlevel;
      62: #endif
      63:         retstr = &str_yes;
      64:         if (cmd->ucmd.ccmd.cc_true) {
      65: #ifdef DEBUGGING
      66:             debname[dlevel] = 't';
      67:             debdelim[dlevel++] = '_';
      68: #endif
      69:             retstr = cmd_exec(cmd->ucmd.ccmd.cc_true);
      70:         }
      71:         if (!goto_targ) {
      72:             go_to = Nullch;
      73:         } else {
      74:             retstr = &str_no;
      75:             if (cmd->ucmd.ccmd.cc_alt) {
      76: #ifdef DEBUGGING
      77:             debname[dlevel] = 'e';
      78:             debdelim[dlevel++] = '_';
      79: #endif
      80:             retstr = cmd_exec(cmd->ucmd.ccmd.cc_alt);
      81:             }
      82:         }
      83:         if (!goto_targ)
      84:             go_to = Nullch;
      85:         curspat = oldspat;
      86: #ifdef DEBUGGING
      87:         dlevel = olddlevel;
      88: #endif
      89:         break;
      90:         case C_BLOCK:
      91:         case C_WHILE:
      92:         if (!(cmdflags & CF_ONCE)) {
      93:             cmdflags |= CF_ONCE;
      94:             loop_ptr++;
      95:             loop_stack[loop_ptr].loop_label = cmd->c_label;
      96: #ifdef DEBUGGING
      97:             if (debug & 4) {
      98:             deb("(Pushing label #%d %s)\n",
      99:               loop_ptr,cmd->c_label);
     100:             }
     101: #endif
     102:         }
     103:         switch (setjmp(loop_stack[loop_ptr].loop_env)) {
     104:         case O_LAST:    /* not done unless go_to found */
     105:             go_to = Nullch;
     106:             retstr = &str_no;
     107: #ifdef DEBUGGING
     108:             olddlevel = dlevel;
     109: #endif
     110:             curspat = oldspat;
     111: #ifdef DEBUGGING
     112:             if (debug & 4) {
     113:             deb("(Popping label #%d %s)\n",loop_ptr,
     114:                 loop_stack[loop_ptr].loop_label);
     115:             }
     116: #endif
     117:             loop_ptr--;
     118:             cmd = cmd->c_next;
     119:             goto tail_recursion_entry;
     120:         case O_NEXT:    /* not done unless go_to found */
     121:             go_to = Nullch;
     122:             goto next_iter;
     123:         case O_REDO:    /* not done unless go_to found */
     124:             go_to = Nullch;
     125:             goto doit;
     126:         }
     127:         oldspat = curspat;
     128: #ifdef DEBUGGING
     129:         olddlevel = dlevel;
     130: #endif
     131:         if (cmd->ucmd.ccmd.cc_true) {
     132: #ifdef DEBUGGING
     133:             debname[dlevel] = 't';
     134:             debdelim[dlevel++] = '_';
     135: #endif
     136:             cmd_exec(cmd->ucmd.ccmd.cc_true);
     137:         }
     138:         if (!goto_targ) {
     139:             go_to = Nullch;
     140:             goto next_iter;
     141:         }
     142: #ifdef DEBUGGING
     143:         dlevel = olddlevel;
     144: #endif
     145:         if (cmd->ucmd.ccmd.cc_alt) {
     146: #ifdef DEBUGGING
     147:             debname[dlevel] = 'a';
     148:             debdelim[dlevel++] = '_';
     149: #endif
     150:             cmd_exec(cmd->ucmd.ccmd.cc_alt);
     151:         }
     152:         if (goto_targ)
     153:             break;
     154:         go_to = Nullch;
     155:         goto finish_while;
     156:         }
     157:         cmd = cmd->c_next;
     158:         if (cmd && cmd->c_head == cmd)  /* reached end of while loop */
     159:         return retstr;      /* targ isn't in this block */
     160:         goto tail_recursion_entry;
     161:     }
     162:     }
     163:
     164: until_loop:
     165:
     166: #ifdef DEBUGGING
     167:     if (debug & 2) {
     168:     deb("%s	(%lx)	r%lx	t%lx	a%lx	n%lx	cs%lx\n",
     169:         cmdname[cmd->c_type],cmd,cmd->c_expr,
     170:         cmd->ucmd.ccmd.cc_true,cmd->ucmd.ccmd.cc_alt,cmd->c_next,curspat);
     171:     }
     172:     debname[dlevel] = cmdname[cmd->c_type][0];
     173:     debdelim[dlevel++] = '!';
     174: #endif
     175:     while (tmps_max >= 0)       /* clean up after last eval */
     176:     str_free(tmps_list[tmps_max--]);
     177:
     178:     /* Here is some common optimization */
     179:
     180:     if (cmdflags & CF_COND) {
     181:     switch (cmdflags & CF_OPTIMIZE) {
     182:
     183:     case CFT_FALSE:
     184:         retstr = cmd->c_first;
     185:         match = FALSE;
     186:         if (cmdflags & CF_NESURE)
     187:         goto maybe;
     188:         break;
     189:     case CFT_TRUE:
     190:         retstr = cmd->c_first;
     191:         match = TRUE;
     192:         if (cmdflags & CF_EQSURE)
     193:         goto flipmaybe;
     194:         break;
     195:
     196:     case CFT_REG:
     197:         retstr = STAB_STR(cmd->c_stab);
     198:         match = str_true(retstr);   /* => retstr = retstr, c2 should fix */
     199:         if (cmdflags & (match ? CF_EQSURE : CF_NESURE))
     200:         goto flipmaybe;
     201:         break;
     202:
     203:     case CFT_ANCHOR:    /* /^pat/ optimization */
     204:         if (multiline) {
     205:         if (*cmd->c_first->str_ptr && !(cmdflags & CF_EQSURE))
     206:             goto scanner;   /* just unanchor it */
     207:         else
     208:             break;      /* must evaluate */
     209:         }
     210:         /* FALL THROUGH */
     211:     case CFT_STROP:     /* string op optimization */
     212:         retstr = STAB_STR(cmd->c_stab);
     213:         if (*cmd->c_first->str_ptr == *str_get(retstr) &&
     214:             strnEQ(cmd->c_first->str_ptr, str_get(retstr),
     215:               cmd->c_flen) ) {
     216:         if (cmdflags & CF_EQSURE) {
     217:             match = !(cmdflags & CF_FIRSTNEG);
     218:             retstr = &str_yes;
     219:             goto flipmaybe;
     220:         }
     221:         }
     222:         else if (cmdflags & CF_NESURE) {
     223:         match = cmdflags & CF_FIRSTNEG;
     224:         retstr = &str_no;
     225:         goto flipmaybe;
     226:         }
     227:         break;          /* must evaluate */
     228:
     229:     case CFT_SCAN:          /* non-anchored search */
     230:       scanner:
     231:         retstr = STAB_STR(cmd->c_stab);
     232:         if (instr(str_get(retstr),cmd->c_first->str_ptr)) {
     233:         if (cmdflags & CF_EQSURE) {
     234:             match = !(cmdflags & CF_FIRSTNEG);
     235:             retstr = &str_yes;
     236:             goto flipmaybe;
     237:         }
     238:         }
     239:         else if (cmdflags & CF_NESURE) {
     240:         match = cmdflags & CF_FIRSTNEG;
     241:         retstr = &str_no;
     242:         goto flipmaybe;
     243:         }
     244:         break;          /* must evaluate */
     245:
     246:     case CFT_GETS:          /* really a while (<file>) */
     247:         last_in_stab = cmd->c_stab;
     248:         fp = last_in_stab->stab_io->fp;
     249:         retstr = defstab->stab_val;
     250:         if (fp && str_gets(retstr, fp)) {
     251:         last_in_stab->stab_io->lines++;
     252:         match = TRUE;
     253:         }
     254:         else if (last_in_stab->stab_io->flags & IOF_ARGV)
     255:         goto doeval;    /* doesn't necessarily count as EOF yet */
     256:         else {
     257:         retstr = &str_no;
     258:         match = FALSE;
     259:         }
     260:         goto flipmaybe;
     261:     case CFT_EVAL:
     262:         break;
     263:     case CFT_UNFLIP:
     264:         retstr = eval(cmd->c_expr,Null(char***));
     265:         match = str_true(retstr);
     266:         if (cmd->c_expr->arg_type == O_FLIP)    /* undid itself? */
     267:         cmdflags = copyopt(cmd,cmd->c_expr[3].arg_ptr.arg_cmd);
     268:         goto maybe;
     269:     case CFT_CHOP:
     270:         retstr = cmd->c_stab->stab_val;
     271:         match = (retstr->str_cur != 0);
     272:         tmps = str_get(retstr);
     273:         tmps += retstr->str_cur - match;
     274:         str_set(&str_chop,tmps);
     275:         *tmps = '\0';
     276:         retstr->str_nok = 0;
     277:         retstr->str_cur = tmps - retstr->str_ptr;
     278:         retstr = &str_chop;
     279:         goto flipmaybe;
     280:     }
     281:
     282:     /* we have tried to make this normal case as abnormal as possible */
     283:
     284:     doeval:
     285:     retstr = eval(cmd->c_expr,Null(char***));
     286:     match = str_true(retstr);
     287:     goto maybe;
     288:
     289:     /* if flipflop was true, flop it */
     290:
     291:     flipmaybe:
     292:     if (match && cmdflags & CF_FLIP) {
     293:         if (cmd->c_expr->arg_type == O_FLOP) {  /* currently toggled? */
     294:         retstr = eval(cmd->c_expr,Null(char***)); /* let eval undo it */
     295:         cmdflags = copyopt(cmd,cmd->c_expr[3].arg_ptr.arg_cmd);
     296:         }
     297:         else {
     298:         retstr = eval(cmd->c_expr,Null(char***)); /* let eval do it */
     299:         if (cmd->c_expr->arg_type == O_FLOP)    /* still toggled? */
     300:             cmdflags = copyopt(cmd,cmd->c_expr[4].arg_ptr.arg_cmd);
     301:         }
     302:     }
     303:     else if (cmdflags & CF_FLIP) {
     304:         if (cmd->c_expr->arg_type == O_FLOP) {  /* currently toggled? */
     305:         match = TRUE;               /* force on */
     306:         }
     307:     }
     308:
     309:     /* at this point, match says whether our expression was true */
     310:
     311:     maybe:
     312:     if (cmdflags & CF_INVERT)
     313:         match = !match;
     314:     if (!match && cmd->c_type != C_IF) {
     315:         cmd = cmd->c_next;
     316:         goto tail_recursion_entry;
     317:     }
     318:     }
     319:
     320:     /* now to do the actual command, if any */
     321:
     322:     switch (cmd->c_type) {
     323:     case C_NULL:
     324:     fatal("panic: cmd_exec\n");
     325:     case C_EXPR:            /* evaluated for side effects */
     326:     if (cmd->ucmd.acmd.ac_expr) {   /* more to do? */
     327:         retstr = eval(cmd->ucmd.acmd.ac_expr,Null(char***));
     328:     }
     329:     break;
     330:     case C_IF:
     331:     oldspat = curspat;
     332: #ifdef DEBUGGING
     333:     olddlevel = dlevel;
     334: #endif
     335:     if (match) {
     336:         retstr = &str_yes;
     337:         if (cmd->ucmd.ccmd.cc_true) {
     338: #ifdef DEBUGGING
     339:         debname[dlevel] = 't';
     340:         debdelim[dlevel++] = '_';
     341: #endif
     342:         retstr = cmd_exec(cmd->ucmd.ccmd.cc_true);
     343:         }
     344:     }
     345:     else {
     346:         retstr = &str_no;
     347:         if (cmd->ucmd.ccmd.cc_alt) {
     348: #ifdef DEBUGGING
     349:         debname[dlevel] = 'e';
     350:         debdelim[dlevel++] = '_';
     351: #endif
     352:         retstr = cmd_exec(cmd->ucmd.ccmd.cc_alt);
     353:         }
     354:     }
     355:     curspat = oldspat;
     356: #ifdef DEBUGGING
     357:     dlevel = olddlevel;
     358: #endif
     359:     break;
     360:     case C_BLOCK:
     361:     case C_WHILE:
     362:     if (!(cmdflags & CF_ONCE)) {    /* first time through here? */
     363:         cmdflags |= CF_ONCE;
     364:         loop_ptr++;
     365:         loop_stack[loop_ptr].loop_label = cmd->c_label;
     366: #ifdef DEBUGGING
     367:         if (debug & 4) {
     368:         deb("(Pushing label #%d %s)\n",
     369:           loop_ptr,cmd->c_label);
     370:         }
     371: #endif
     372:     }
     373:     switch (setjmp(loop_stack[loop_ptr].loop_env)) {
     374:     case O_LAST:
     375:         retstr = &str_no;
     376:         curspat = oldspat;
     377: #ifdef DEBUGGING
     378:         if (debug & 4) {
     379:         deb("(Popping label #%d %s)\n",loop_ptr,
     380:             loop_stack[loop_ptr].loop_label);
     381:         }
     382: #endif
     383:         loop_ptr--;
     384:         cmd = cmd->c_next;
     385:         goto tail_recursion_entry;
     386:     case O_NEXT:
     387:         goto next_iter;
     388:     case O_REDO:
     389: #ifdef DEBUGGING
     390:         dlevel = olddlevel;
     391: #endif
     392:         goto doit;
     393:     }
     394:     oldspat = curspat;
     395: #ifdef DEBUGGING
     396:     olddlevel = dlevel;
     397: #endif
     398:     doit:
     399:     if (cmd->ucmd.ccmd.cc_true) {
     400: #ifdef DEBUGGING
     401:         debname[dlevel] = 't';
     402:         debdelim[dlevel++] = '_';
     403: #endif
     404:         cmd_exec(cmd->ucmd.ccmd.cc_true);
     405:     }
     406:     /* actually, this spot is never reached anymore since the above
     407: 	 * cmd_exec() returns through longjmp().  Hooray for structure.
     408: 	 */
     409:       next_iter:
     410: #ifdef DEBUGGING
     411:     dlevel = olddlevel;
     412: #endif
     413:     if (cmd->ucmd.ccmd.cc_alt) {
     414: #ifdef DEBUGGING
     415:         debname[dlevel] = 'a';
     416:         debdelim[dlevel++] = '_';
     417: #endif
     418:         cmd_exec(cmd->ucmd.ccmd.cc_alt);
     419:     }
     420:       finish_while:
     421:     curspat = oldspat;
     422: #ifdef DEBUGGING
     423:     dlevel = olddlevel - 1;
     424: #endif
     425:     if (cmd->c_type != C_BLOCK)
     426:         goto until_loop;    /* go back and evaluate conditional again */
     427:     }
     428:     if (cmdflags & CF_LOOP) {
     429:     cmdflags |= CF_COND;        /* now test the condition */
     430:     goto until_loop;
     431:     }
     432:     cmd = cmd->c_next;
     433:     goto tail_recursion_entry;
     434: }
     435:
     436: #ifdef DEBUGGING
     437: /*VARARGS1*/
     438: deb(pat,a1,a2,a3,a4,a5,a6,a7,a8)
     439: char *pat;
     440: {
     441:     register int i;
     442:
     443:     for (i=0; i<dlevel; i++)
     444:     fprintf(stderr,"%c%c ",debname[i],debdelim[i]);
     445:     fprintf(stderr,pat,a1,a2,a3,a4,a5,a6,a7,a8);
     446: }
     447: #endif
     448:
     449: copyopt(cmd,which)
     450: register CMD *cmd;
     451: register CMD *which;
     452: {
     453:     cmd->c_flags &= CF_ONCE|CF_COND|CF_LOOP;
     454:     cmd->c_flags |= which->c_flags;
     455:     cmd->c_first = which->c_first;
     456:     cmd->c_flen = which->c_flen;
     457:     cmd->c_stab = which->c_stab;
     458:     return cmd->c_flags;
     459: }

#### Defined functions

cmd_exec defined in line 25; used 14 times

- in line 69, 80, 136, 150, 342, 352, 404, 418
- in /usr/src/new/PORT/perl.1.0.10/arg.c line 949, 1275
- in /usr/src/new/PORT/perl.1.0.10/cmd.h line 126
- in /usr/src/new/PORT/perl.1.0.10/perly.c line 219, 2516
- in /usr/src/new/PORT/perl.1.0.10/stab.c line 286

copyopt defined in line 449; used 3 times

- in line 267, 295-300(2)

deb defined in line 438; used 24 times

- in line 98, 113, 168, 368, 379
- in /usr/src/new/PORT/perl.1.0.10/arg.c line 44, 52-56(2), 79, 126, 133, 188, 225, 232, 1242, 1263, 1272, 1290, 1419, 1895, 1903, 2108, 2118, 2141

#### Defined variables

str_chop defined in line 18; used 2 times

- in line 274-278(2)

Last modified: 1988-02-03 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2049 |