📄 cmd.c
字号:
break; if (DBtrace->str_u.str_nval != 0) break; goto next_cmd; } /* we have tried to make this normal case as abnormal as possible */ doeval: if (gimme == G_ARRAY) { lastretstr = Nullstr; lastspbase = sp; lastsize = newsp - sp; if (lastsize < 0) lastsize = 0; } else lastretstr = retstr; while (tmps_max > tmps_base) { /* clean up after last eval */ str_free(tmps_list[tmps_max]); tmps_list[tmps_max--] = Nullstr; } newsp = eval(cmd->c_expr, gimme && (cmdflags & CF_TERM) && cmd->c_type == C_EXPR && !cmd->ucmd.acmd.ac_expr, sp); st = stack->ary_array; /* possibly reallocated */ retstr = st[newsp]; if (newsp > sp && retstr) match = str_true(retstr); else match = FALSE; goto maybe; /* if flipflop was true, flop it */ flipmaybe: if (match && cmdflags & CF_FLIP) { while (tmps_max > tmps_base) { /* clean up after last eval */ str_free(tmps_list[tmps_max]); tmps_list[tmps_max--] = Nullstr; } if (cmd->c_expr->arg_type == O_FLOP) { /* currently toggled? */ newsp = eval(cmd->c_expr,G_SCALAR,sp);/*let eval undo it*/ cmdflags = copyopt(cmd,cmd->c_expr[3].arg_ptr.arg_cmd); } else { newsp = eval(cmd->c_expr,G_SCALAR,sp);/* let eval do it */ if (cmd->c_expr->arg_type == O_FLOP) /* still toggled? */ cmdflags = copyopt(cmd,cmd->c_expr[4].arg_ptr.arg_cmd); } } else if (cmdflags & CF_FLIP) { if (cmd->c_expr->arg_type == O_FLOP) { /* currently toggled? */ match = TRUE; /* force on */ } } /* at this point, match says whether our expression was true */ maybe: if (cmdflags & CF_INVERT) match = !match; if (!match) goto next_cmd; }#ifdef TAINT tainted = 0; /* modifier doesn't affect regular expression */#endif /* now to do the actual command, if any */ switch (cmd->c_type) { case C_NULL: fatal("panic: cmd_exec"); case C_EXPR: /* evaluated for side effects */ if (cmd->ucmd.acmd.ac_expr) { /* more to do? */ if (gimme == G_ARRAY) { lastretstr = Nullstr; lastspbase = sp; lastsize = newsp - sp; if (lastsize < 0) lastsize = 0; } else lastretstr = retstr; while (tmps_max > tmps_base) { /* clean up after last eval */ str_free(tmps_list[tmps_max]); tmps_list[tmps_max--] = Nullstr; } newsp = eval(cmd->ucmd.acmd.ac_expr,gimme && (cmdflags&CF_TERM),sp); st = stack->ary_array; /* possibly reallocated */ retstr = st[newsp]; } break; case C_NSWITCH: { double value = str_gnum(STAB_STR(cmd->c_stab)); match = (int)value; if (value < 0.0) { if (((double)match) > value) --match; /* was fractional--truncate other way */ } } goto doswitch; case C_CSWITCH: if (multiline) { cmd = cmd->c_next; /* can't assume anything */ goto tail_recursion_entry; } match = *(str_get(STAB_STR(cmd->c_stab))) & 255; doswitch: match -= cmd->ucmd.scmd.sc_offset; if (match < 0) match = 0; else if (match > cmd->ucmd.scmd.sc_max) match = cmd->ucmd.scmd.sc_max; cmd = cmd->ucmd.scmd.sc_next[match]; goto tail_recursion_entry; case C_NEXT: cmd = cmd->ucmd.ccmd.cc_alt; goto tail_recursion_entry; case C_ELSIF: fatal("panic: ELSIF"); case C_IF: oldspat = curspat; oldsave = savestack->ary_fill;#ifdef DEBUGGING olddlevel = dlevel;#endif retstr = &str_yes; newsp = -2; if (cmd->ucmd.ccmd.cc_true) {#ifdef DEBUGGING if (debug) { debname[dlevel] = 't'; debdelim[dlevel] = '_'; if (++dlevel >= dlmax) grow_dlevel(); }#endif newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp); st = stack->ary_array; /* possibly reallocated */ retstr = st[newsp]; } curspat = oldspat; if (savestack->ary_fill > oldsave) restorelist(oldsave);#ifdef DEBUGGING dlevel = olddlevel;#endif cmd = cmd->ucmd.ccmd.cc_alt; goto tail_recursion_entry; case C_ELSE: oldspat = curspat; oldsave = savestack->ary_fill;#ifdef DEBUGGING olddlevel = dlevel;#endif retstr = &str_undef; newsp = -2; if (cmd->ucmd.ccmd.cc_true) {#ifdef DEBUGGING if (debug) { debname[dlevel] = 'e'; debdelim[dlevel] = '_'; if (++dlevel >= dlmax) grow_dlevel(); }#endif newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp); st = stack->ary_array; /* possibly reallocated */ retstr = st[newsp]; } curspat = oldspat; if (savestack->ary_fill > oldsave) restorelist(oldsave);#ifdef DEBUGGING dlevel = olddlevel;#endif break; case C_BLOCK: case C_WHILE: if (!(cmdflags & CF_ONCE)) { /* first time through here? */ cmdflags |= CF_ONCE; if (++loop_ptr >= loop_max) { loop_max += 128; Renew(loop_stack, loop_max, struct loop); } loop_stack[loop_ptr].loop_label = cmd->c_label; loop_stack[loop_ptr].loop_sp = sp;#ifdef DEBUGGING if (debug & 4) { deb("(Pushing label #%d %s)\n", loop_ptr, cmd->c_label ? cmd->c_label : ""); }#endif }#ifdef JMPCLOBBER cmdparm = cmd;#endif match = setjmp(loop_stack[loop_ptr].loop_env); if (match) { st = stack->ary_array; /* possibly reallocated */#ifdef JMPCLOBBER cmd = cmdparm; cmdflags = cmd->c_flags|CF_ONCE; go_to = goto_targ;#endif if (savestack->ary_fill > oldsave) restorelist(oldsave); switch (match) { default: fatal("longjmp returned bad value (%d)",match); case O_LAST: if (lastretstr) { retstr = lastretstr; newsp = -2; } else { newsp = sp + lastsize; retstr = st[newsp]; } curspat = oldspat; goto next_cmd; case O_NEXT:#ifdef JMPCLOBBER newsp = -2; retstr = &str_undef;#endif goto next_iter; case O_REDO:#ifdef DEBUGGING dlevel = olddlevel;#endif#ifdef JMPCLOBBER newsp = -2; retstr = &str_undef;#endif goto doit; } } oldspat = curspat; oldsave = savestack->ary_fill;#ifdef DEBUGGING olddlevel = dlevel;#endif doit: if (cmd->ucmd.ccmd.cc_true) {#ifdef DEBUGGING if (debug) { debname[dlevel] = 't'; debdelim[dlevel] = '_'; if (++dlevel >= dlmax) grow_dlevel(); }#endif newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp); st = stack->ary_array; /* possibly reallocated */ retstr = st[newsp]; } /* actually, this spot is rarely reached anymore since the above * cmd_exec() returns through longjmp(). Hooray for structure. */ next_iter:#ifdef DEBUGGING dlevel = olddlevel;#endif if (cmd->ucmd.ccmd.cc_alt) {#ifdef DEBUGGING if (debug) { debname[dlevel] = 'a'; debdelim[dlevel] = '_'; if (++dlevel >= dlmax) grow_dlevel(); }#endif newsp = cmd_exec(cmd->ucmd.ccmd.cc_alt,gimme && (cmdflags & CF_TERM),sp); st = stack->ary_array; /* possibly reallocated */ retstr = st[newsp]; } finish_while: curspat = oldspat; if (savestack->ary_fill > oldsave) { if (cmdflags & CF_TERM) { for (match = sp + 1; match <= newsp; match++) st[match] = str_mortal(st[match]); retstr = st[newsp]; } restorelist(oldsave); }#ifdef DEBUGGING dlevel = olddlevel - 1;#endif if (cmd->c_type != C_BLOCK) goto until_loop; /* go back and evaluate conditional again */ } if (cmdflags & CF_LOOP) { cmdflags |= CF_COND; /* now test the condition */#ifdef DEBUGGING dlevel = entdlevel;#endif goto until_loop; } next_cmd: if (cmdflags & CF_ONCE) {#ifdef DEBUGGING if (debug & 4) { tmps = loop_stack[loop_ptr].loop_label; deb("(Popping label #%d %s)\n",loop_ptr, tmps ? tmps : ""); }#endif loop_ptr--; if ((cmdflags & CF_OPTIMIZE) == CFT_ARRAY && savestack->ary_fill > aryoptsave) restorelist(aryoptsave); } cmd = cmd->c_next; goto tail_recursion_entry;}#ifdef DEBUGGING# ifndef I_VARARGS/*VARARGS1*/void deb(pat,a1,a2,a3,a4,a5,a6,a7,a8)char *pat;{ register int i; fprintf(stderr,"%-4ld",(long)curcmd->c_line); for (i=0; i<dlevel; i++) fprintf(stderr,"%c%c ",debname[i],debdelim[i]); fprintf(stderr,pat,a1,a2,a3,a4,a5,a6,a7,a8);}# else/*VARARGS1*/void deb(va_alist)va_dcl{ va_list args; char *pat; register int i; va_start(args); fprintf(stderr,"%-4ld",(long)curcmd->c_line); for (i=0; i<dlevel; i++) fprintf(stderr,"%c%c ",debname[i],debdelim[i]); pat = va_arg(args, char *); (void) vfprintf(stderr,pat,args); va_end( args );}# endif#endifintcopyopt(cmd,which)register CMD *cmd;register CMD *which;{ cmd->c_flags &= CF_ONCE|CF_COND|CF_LOOP; cmd->c_flags |= which->c_flags; cmd->c_short = which->c_short; cmd->c_slen = which->c_slen; cmd->c_stab = which->c_stab; return cmd->c_flags;}ARRAY *saveary(stab)STAB *stab;{ register STR *str; str = Str_new(10,0); str->str_state = SS_SARY; str->str_u.str_stab = stab; if (str->str_ptr) { Safefree(str->str_ptr); str->str_ptr = Nullch; str->str_len = 0; } str->str_ptr = (char*)stab_array(stab); (void)apush(savestack,str); /* save array ptr */ stab_xarray(stab) = Null(ARRAY*); return stab_xarray(aadd(stab));}HASH *savehash(stab)STAB *stab;{ register STR *str; str = Str_new(11,0); str->str_state = SS_SHASH; str->str_u.str_stab = stab; if (str->str_ptr) { Safefree(str->str_ptr); str->str_ptr = Nullch; str->str_len = 0; } str->str_ptr = (char*)stab_hash(stab); (void)apush(savestack,str); /* save hash ptr */ stab_xhash(stab) = Null(HASH*); return stab_xhash(hadd(stab));}voidsaveitem(item)register STR *item;{ register STR *str; (void)apush(savestack,item); /* remember the pointer */ str = Str_new(12,0); str_sset(str,item); (void)apush(savestack,str); /* remember the value */}voidsaveint(intp)int *intp;{ register STR *str; str = Str_new(13,0); str->str_state = SS_SINT; str->str_u.str_useful = (long)*intp; /* remember value */ if (str->str_ptr) { Safefree(str->str_ptr); str->str_len = 0; } str->str_ptr = (char*)intp; /* remember pointer */ (void)apush(savestack,str);}voidsavelong(longp)long *longp;{ register STR *str; str = Str_new(14,0); str->str_state = SS_SLONG; str->str_u.str_useful = *longp; /* remember value */ if (str->str_ptr) { Safefree(str->str_ptr); str->str_len = 0; } str->str_ptr = (char*)longp; /* remember pointer */ (void)apush(savestack,str);}voidsavesptr(sptr)STR **sptr;{ register STR *str; str = Str_new(15,0); str->str_state = SS_SSTRP; str->str_magic = *sptr; /* remember value */ if (str->str_ptr) { Safefree(str->str_ptr); str->str_len = 0; } str->str_ptr = (char*)sptr; /* remember pointer */ (void)apush(savestack,str);}voidsavenostab(stab)STAB *stab;{ register STR *str; str = Str_new(16,0); str->str_state = SS_SNSTAB; str->str_magic = (STR*)stab; /* remember which stab to free */ (void)apush(savestack,str);}voidsavehptr(hptr)HASH **hptr;{ register STR *str; str = Str_new(17,0); str->str_state = SS_SHPTR; str->str_u.str_hash = *hptr; /* remember value */ if (str->str_ptr) { Safefree(str->str_ptr); str->str_len = 0; } str->str_ptr = (char*)hptr; /* remember pointer */ (void)apush(savestack,str);}voidsaveaptr(aptr)ARRAY **aptr;{ register STR *str; str = Str_new(17,0); str->str_state = SS_SAPTR; str->str_u.str_array = *aptr; /* remember value */ if (str->str_ptr) { Safefree(str->str_ptr); str->str_len = 0; } str->str_ptr = (char*)aptr; /* remember pointer */ (void)apush(savestack,str);}voidsavelist(sarg,maxsarg)register STR **sarg;int maxsarg;{ register STR *str; register int i; for (i = 1; i <= maxsarg; i++) { (void)apush(savestack,sarg[i]); /* remember the pointer */ str = Str_new(18,0); str_sset(str,sarg[i]); (void)apush(savestack,str); /* remember the value */ sarg[i]->str_u.str_useful = -1; }}voidrestorelist(base)int base;{ register STR *str; register STR *value; register STAB *stab; if (base < -1) fatal("panic: corrupt saved stack index"); while (savestack->ary_fill > base) { value = apop(savestack); switch (value->str_state) { case SS_NORM: /* normal string */ case SS_INCR: str = apop(savestack); str_replace(str,value); STABSET(str); break; case SS_SARY: /* array reference */ stab = value->str_u.str_stab; afree(stab_xarray(stab)); stab_xarray(stab) = (ARRAY*)value->str_ptr; value->str_ptr = Nullch; str_free(value); break; case SS_SHASH: /* hash reference */ stab = value->str_u.str_stab; (void)hfree(stab_xhash(stab), FALSE); stab_xhash(stab) = (HASH*)value->str_ptr; value->str_ptr = Nullch; str_free(value); break; case SS_SINT: /* int reference */ *((int*)value->str_ptr) = (int)value->str_u.str_useful; value->str_ptr = Nullch; str_free(value); break; case SS_SLONG: /* long reference */ *((long*)value->str_ptr) = value->str_u.str_useful; value->str_ptr = Nullch; str_free(value); break; case SS_SSTRP: /* STR* reference */ *((STR**)value->str_ptr) = value->str_magic; value->str_magic = Nullstr; value->str_ptr = Nullch; str_free(value); break; case SS_SHPTR: /* HASH* reference */ *((HASH**)value->str_ptr) = value->str_u.str_hash; value->str_ptr = Nullch; str_free(value); break; case SS_SAPTR: /* ARRAY* reference */ *((ARRAY**)value->str_ptr) = value->str_u.str_array; value->str_ptr = Nullch; str_free(value); break; case SS_SNSTAB: stab = (STAB*)value->str_magic; value->str_magic = Nullstr; (void)stab_clear(stab); str_free(value); break; case SS_SCSV: /* callsave structure */ { CSV *csv = (CSV*) value->str_ptr; curcmd = csv->curcmd; curcsv = csv->curcsv; csv->sub->depth = csv->depth; if (csv->hasargs) { /* put back old @_ */ afree(csv->argarray); stab_xarray(defstab) = csv->savearray; } str_free(value); } break; default: fatal("panic: restorelist inconsistency"); } }}#ifdef DEBUGGINGvoidgrow_dlevel(){ dlmax += 128; Renew(debname, dlmax, char); Renew(debdelim, dlmax, char);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -