📄 eval.c
字号:
if (!str) goto say_undef; break; case O_LHASH: str->str_nok = str->str_pok = 0; str->str_u.str_stab = arg[1].arg_ptr.arg_stab; str->str_state = SS_HASH; break; case O_HASH: if (gimme == G_ARRAY) { /* array wanted */ sp = do_kv(str,stab_hash(arg[1].arg_ptr.arg_stab), optype, gimme,arglast); goto array_return; } else { tmpstab = arg[1].arg_ptr.arg_stab; if (!stab_hash(tmpstab)->tbl_fill) goto say_zero; sprintf(buf,"%d/%d",stab_hash(tmpstab)->tbl_fill, stab_hash(tmpstab)->tbl_max+1); str_set(str,buf); } break; case O_HELEM: tmpstab = arg[1].arg_ptr.arg_stab; tmps = str_get(st[2]); str = hfetch(stab_hash(tmpstab),tmps,st[2]->str_cur,FALSE); break; case O_LAELEM: anum = ((int)str_gnum(st[2])) - arybase; str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,TRUE); if (!str || str == &str_undef) fatal("Assignment to non-creatable value, subscript %d",anum); break; case O_LHELEM: tmpstab = arg[1].arg_ptr.arg_stab; tmps = str_get(st[2]); anum = st[2]->str_cur; str = hfetch(stab_hash(tmpstab),tmps,anum,TRUE); if (!str || str == &str_undef) fatal("Assignment to non-creatable value, subscript \"%s\"",tmps); if (tmpstab == envstab) /* heavy wizardry going on here */ str_magic(str, tmpstab, 'E', tmps, anum); /* str is now magic */ /* he threw the brick up into the air */ else if (tmpstab == sigstab) str_magic(str, tmpstab, 'S', tmps, anum);#ifdef SOME_DBM else if (stab_hash(tmpstab)->tbl_dbm) str_magic(str, tmpstab, 'D', tmps, anum);#endif else if (tmpstab == DBline) str_magic(str, tmpstab, 'L', tmps, anum); break; case O_LSLICE: anum = 2; argtype = FALSE; goto do_slice_already; case O_ASLICE: anum = 1; argtype = FALSE; goto do_slice_already; case O_HSLICE: anum = 0; argtype = FALSE; goto do_slice_already; case O_LASLICE: anum = 1; argtype = TRUE; goto do_slice_already; case O_LHSLICE: anum = 0; argtype = TRUE; do_slice_already: sp = do_slice(arg[1].arg_ptr.arg_stab,str,anum,argtype, gimme,arglast); goto array_return; case O_SPLICE: sp = do_splice(stab_array(arg[1].arg_ptr.arg_stab),gimme,arglast); goto array_return; case O_PUSH: if (arglast[2] - arglast[1] != 1) str = do_push(stab_array(arg[1].arg_ptr.arg_stab),arglast); else { str = Str_new(51,0); /* must copy the STR */ str_sset(str,st[2]); (void)apush(stab_array(arg[1].arg_ptr.arg_stab),str); } break; case O_POP: str = apop(ary = stab_array(arg[1].arg_ptr.arg_stab)); goto staticalization; case O_SHIFT: str = ashift(ary = stab_array(arg[1].arg_ptr.arg_stab)); staticalization: if (!str) goto say_undef; if (ary->ary_flags & ARF_REAL) (void)str_2mortal(str); break; case O_UNPACK: sp = do_unpack(str,gimme,arglast); goto array_return; case O_SPLIT: value = str_gnum(st[3]); sp = do_split(str, arg[2].arg_ptr.arg_spat, (int)value, gimme,arglast); goto array_return; case O_LENGTH: if (maxarg < 1) value = (double)str_len(stab_val(defstab)); else value = (double)str_len(st[1]); goto donumset; case O_SPRINTF: do_sprintf(str, sp-arglast[0], st+1); break; case O_SUBSTR: anum = ((int)str_gnum(st[2])) - arybase; /* anum=where to start*/ tmps = str_get(st[1]); /* force conversion to string */ /*SUPPRESS 560*/ if (argtype = (str == st[1])) str = arg->arg_ptr.arg_str; if (anum < 0) anum += st[1]->str_cur + arybase; if (anum < 0 || anum > st[1]->str_cur) str_nset(str,"",0); else { optype = maxarg < 3 ? st[1]->str_cur : (int)str_gnum(st[3]); if (optype < 0) optype = 0; tmps += anum; anum = st[1]->str_cur - anum; /* anum=how many bytes left*/ if (anum > optype) anum = optype; str_nset(str, tmps, anum); if (argtype) { /* it's an lvalue! */ lstr = (struct lstring*)str; str->str_magic = st[1]; st[1]->str_rare = 's'; lstr->lstr_offset = tmps - str_get(st[1]); lstr->lstr_len = anum; } } break; case O_PACK: /*SUPPRESS 701*/ (void)do_pack(str,arglast); break; case O_GREP: sp = do_grep(arg,str,gimme,arglast); goto array_return; case O_JOIN: do_join(str,arglast); break; case O_SLT: tmps = str_get(st[1]); value = (double) (str_cmp(st[1],st[2]) < 0); goto donumset; case O_SGT: tmps = str_get(st[1]); value = (double) (str_cmp(st[1],st[2]) > 0); goto donumset; case O_SLE: tmps = str_get(st[1]); value = (double) (str_cmp(st[1],st[2]) <= 0); goto donumset; case O_SGE: tmps = str_get(st[1]); value = (double) (str_cmp(st[1],st[2]) >= 0); goto donumset; case O_SEQ: tmps = str_get(st[1]); value = (double) str_eq(st[1],st[2]); goto donumset; case O_SNE: tmps = str_get(st[1]); value = (double) !str_eq(st[1],st[2]); goto donumset; case O_SCMP: tmps = str_get(st[1]); value = (double) str_cmp(st[1],st[2]); goto donumset; case O_SUBR: sp = do_subr(arg,gimme,arglast); st = stack->ary_array + arglast[0]; /* maybe realloced */ goto array_return; case O_DBSUBR: sp = do_subr(arg,gimme,arglast); st = stack->ary_array + arglast[0]; /* maybe realloced */ goto array_return; case O_CALLER: sp = do_caller(arg,maxarg,gimme,arglast); st = stack->ary_array + arglast[0]; /* maybe realloced */ goto array_return; case O_SORT: sp = do_sort(str,arg, gimme,arglast); goto array_return; case O_REVERSE: if (gimme == G_ARRAY) sp = do_reverse(arglast); else sp = do_sreverse(str, arglast); goto array_return; case O_WARN: if (arglast[2] - arglast[1] != 1) { do_join(str,arglast); tmps = str_get(str); } else { str = st[2]; tmps = str_get(st[2]); } if (!tmps || !*tmps) tmps = "Warning: something's wrong"; warn("%s",tmps); goto say_yes; case O_DIE: if (arglast[2] - arglast[1] != 1) { do_join(str,arglast); tmps = str_get(str); } else { str = st[2]; tmps = str_get(st[2]); } if (!tmps || !*tmps) tmps = "Died"; fatal("%s",tmps); goto say_zero; case O_PRTF: case O_PRINT: if ((arg[1].arg_type & A_MASK) == A_WORD) stab = arg[1].arg_ptr.arg_stab; else stab = stabent(str_get(st[1]),TRUE); if (!stab) stab = defoutstab; if (!stab_io(stab)) { if (dowarn) warn("Filehandle never opened"); goto say_zero; } if (!(fp = stab_io(stab)->ofp)) { if (dowarn) { if (stab_io(stab)->ifp) warn("Filehandle opened only for input"); else warn("Print on closed filehandle"); } goto say_zero; } else { if (optype == O_PRTF || arglast[2] - arglast[1] != 1) value = (double)do_aprint(arg,fp,arglast); else { value = (double)do_print(st[2],fp); if (orslen && optype == O_PRINT) if (fwrite(ors, 1, orslen, fp) == 0) goto say_zero; } if (stab_io(stab)->flags & IOF_FLUSH) if (fflush(fp) == EOF) goto say_zero; } goto donumset; case O_CHDIR: if (maxarg < 1) tmps = Nullch; else tmps = str_get(st[1]); if (!tmps || !*tmps) { tmpstr = hfetch(stab_hash(envstab),"HOME",4,FALSE); tmps = str_get(tmpstr); } if (!tmps || !*tmps) { tmpstr = hfetch(stab_hash(envstab),"LOGDIR",6,FALSE); tmps = str_get(tmpstr); }#ifdef TAINT taintproper("Insecure dependency in chdir");#endif value = (double)(chdir(tmps) >= 0); goto donumset; case O_EXIT: if (maxarg < 1) anum = 0; else anum = (int)str_gnum(st[1]); exit(anum); goto say_zero; case O_RESET: if (maxarg < 1) tmps = ""; else tmps = str_get(st[1]); str_reset(tmps,curcmd->c_stash); value = 1.0; goto donumset; case O_LIST: if (gimme == G_ARRAY) goto array_return; if (maxarg > 0) str = st[sp - arglast[0]]; /* unwanted list, return last item */ else str = &str_undef; break; case O_EOF: if (maxarg <= 0) stab = last_in_stab; else if ((arg[1].arg_type & A_MASK) == A_WORD) stab = arg[1].arg_ptr.arg_stab; else stab = stabent(str_get(st[1]),TRUE); str_set(str, do_eof(stab) ? Yes : No); STABSET(str); break; case O_GETC: if (maxarg <= 0) stab = stdinstab; else if ((arg[1].arg_type & A_MASK) == A_WORD) stab = arg[1].arg_ptr.arg_stab; else stab = stabent(str_get(st[1]),TRUE); if (!stab) stab = argvstab; if (!stab || do_eof(stab)) /* make sure we have fp with something */ goto say_undef; else {#ifdef TAINT tainted = 1;#endif str_set(str," "); *str->str_ptr = getc(stab_io(stab)->ifp); /* should never be EOF */ } STABSET(str); break; case O_TELL: if (maxarg <= 0) stab = last_in_stab; else if ((arg[1].arg_type & A_MASK) == A_WORD) stab = arg[1].arg_ptr.arg_stab; else stab = stabent(str_get(st[1]),TRUE);#ifndef lint value = (double)do_tell(stab);#else (void)do_tell(stab);#endif goto donumset; case O_RECV: case O_READ: case O_SYSREAD: if ((arg[1].arg_type & A_MASK) == A_WORD) stab = arg[1].arg_ptr.arg_stab; else stab = stabent(str_get(st[1]),TRUE); tmps = str_get(st[2]); anum = (int)str_gnum(st[3]); errno = 0; maxarg = sp - arglast[0]; if (maxarg > 4) warn("Too many args on read"); if (maxarg == 4) maxarg = (int)str_gnum(st[4]); else maxarg = 0; if (!stab_io(stab) || !stab_io(stab)->ifp) goto say_undef;#ifdef HAS_SOCKET if (optype == O_RECV) { argtype = sizeof buf; STR_GROW(st[2], anum+1), (tmps = str_get(st[2])); /* sneaky */ anum = recvfrom(fileno(stab_io(stab)->ifp), tmps, anum, maxarg, buf, &argtype); if (anum >= 0) { st[2]->str_cur = anum; st[2]->str_ptr[anum] = '\0'; str_nset(str,buf,argtype); } else str_sset(str,&str_undef); break; }#else if (optype == O_RECV) goto badsock;#endif STR_GROW(st[2], anum+maxarg+1), (tmps = str_get(st[2])); /* sneaky */ if (optype == O_SYSREAD) { anum = read(fileno(stab_io(stab)->ifp), tmps+maxarg, anum); } else#ifdef HAS_SOCKET if (stab_io(stab)->type == 's') { argtype = sizeof buf; anum = recvfrom(fileno(stab_io(stab)->ifp), tmps+maxarg, anum, 0, buf, &argtype); } else#endif anum = fread(tmps+maxarg, 1, anum, stab_io(stab)->ifp); if (anum < 0) goto say_undef; st[2]->str_cur = anum+maxarg; st[2]->str_ptr[anum+maxarg] = '\0'; value = (double)anum; goto donumset; case O_SYSWRITE: case O_SEND: if ((arg[1].arg_type & A_MASK) == A_WORD) stab = arg[1].arg_ptr.arg_stab; else stab = stabent(str_get(st[1]),TRUE); tmps = str_get(st[2]); anum = (int)str_gnum(st[3]); errno = 0; stio = stab_io(stab); maxarg = sp - arglast[0]; if (!stio || !stio->ifp) { anum = -1; if (dowarn) { if (optype == O_SYSWRITE) warn("Syswrite on closed filehandle"); else warn("Send on closed socket"); } } else if (optype == O_SYSWRITE) { if (maxarg > 4) warn("Too many args on syswrite"); if (maxarg == 4) optype = (int)str_gnum(st[4]); else optype = 0; anum = write(fileno(stab_io(stab)->ifp), tmps+optype, anum); }#ifdef HAS_SOCKET else if (maxarg >= 4) { if (maxarg > 4) warn("Too many args on send"); tmps2 = str_get(st[4]); anum = sendto(fileno(stab_io(stab)->ifp), tmps, st[2]->str_cur, anum, tmps2, st[4]->str_cur); } else anum = send(fileno(stab_io(stab)->ifp), tmps, st[2]->str_cur, anum);#else else goto badsock;#endif if (anum < 0) goto say_undef; value = (double)anum; goto donumset; case O_SEEK: if ((arg[1].arg_type & A_MASK) == A_WORD) stab = arg[1].arg_ptr.arg_stab; else stab = stabent(str_get(st[1]),TRUE); value = str_gnum(st[2]); str_set(str, do_seek(stab, (long)value, (int)str_gnum(st[3]) ) ? Yes : No); STABSET(str); break; case O_RETURN: tmps = "_SUB_"; /* just fake up a "last _SUB_" */ optype = O_LAST; if (curcsv && curcsv->wantarray == G_ARRAY) { lastretstr = Nullstr; lastspbase = arglast[1]; lastsize = arglast[2] - arglast[1]; } else lastretstr = str_mortal(st[arglast[2] - arglast[0]]); goto dopop; case O_REDO: case O_NEXT: case O_LAST: tmps = Nullch; if (maxarg > 0) { tmps = str_get(arg[1].arg_ptr.arg_str); dopop: while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label || strNE(tmps,loop_stack[loop_ptr].loop_label) )) {#ifdef DEBUGGING if (debug & 4) { deb("(Skipping label #%d %s)\n",loop_ptr, loop_stack[loop_ptr].loop_label); }#endif loop_ptr--; }#ifdef DEBUGGING if (debug & 4) { deb("(Found label #%d %s)\n",loop_ptr, loop_stack[loop_ptr].loop_label); }#endif } if (loop_ptr < 0) { if (tmps && strEQ(tmps, "_SUB_")) fatal("Can't return outside a subroutine"); fatal("Bad label: %s", maxarg > 0 ? tmps : "<null>"); } if (!lastretstr && optype == O_LAST && lastsize) { st -= arglast[0]; st += lastspbase + 1; optype = loop_stack[loop_ptr].loop_sp - lastspbase; /* negative */ if (optype) { for (anum = lastsize; anum > 0; anum--,st++) st[optype] = str_mortal(st[0]); } longjmp(loop_stack[loop_ptr].loop_env, O_LAST); } longjmp(loop_stack[loop_ptr].loop_env, optype); case O_DUMP: case O_GOTO:/* shudder */ goto_targ = str_get(arg[1].arg_ptr.arg_str); if (!*goto_targ) goto_targ = Nullch; /* just restart from top */ if (optype == O_DUMP) { do_undump = 1; my_unexec(); } longjmp(top_env, 1); case O_INDEX: tmps = str_get(st[1]); if (maxarg < 3) anum = 0; else { anum = (int) str_gnum(st[3]) - arybase; if (anum < 0) anum = 0; else if (anum > st[1]->str_cur) anum = st[1]->str_cur; }#ifndef lint if (!(tmps2 = fbminstr((unsigned char*)tmps + anum, (unsigned char*)tmps + st[1]->str_cur, st[2])))#else if (tmps2 = fbminstr(Null(unsigned char*),Null(unsigned char*),Nullstr))#endif value = (double)(-1 + arybase); else value = (double)(tmps2 - tmps + arybase); goto donumset; case O_RINDEX: tmps = str_get(st[1]); tmps2 = str_get(st[2]); if (maxarg < 3)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -