📄 eval.c
字号:
anum = st[1]->str_cur; else { anum = (int) str_gnum(st[3]) - arybase + st[2]->str_cur; if (anum < 0) anum = 0; else if (anum > st[1]->str_cur) anum = st[1]->str_cur; }#ifndef lint if (!(tmps2 = rninstr(tmps, tmps + anum, tmps2, tmps2 + st[2]->str_cur)))#else if (tmps2 = rninstr(Nullch,Nullch,Nullch,Nullch))#endif value = (double)(-1 + arybase); else value = (double)(tmps2 - tmps + arybase); goto donumset; case O_TIME:#ifndef lint value = (double) time(Null(long*));#endif goto donumset; case O_TMS: sp = do_tms(str,gimme,arglast); goto array_return; case O_LOCALTIME: if (maxarg < 1) (void)time(&when); else when = (time_t)str_gnum(st[1]); sp = do_time(str,localtime(&when), gimme,arglast); goto array_return; case O_GMTIME: if (maxarg < 1) (void)time(&when); else when = (time_t)str_gnum(st[1]); sp = do_time(str,gmtime(&when), gimme,arglast); goto array_return; case O_TRUNCATE: sp = do_truncate(str,arg, gimme,arglast); goto array_return; case O_LSTAT: case O_STAT: sp = do_stat(str,arg, gimme,arglast); goto array_return; case O_CRYPT:#ifdef HAS_CRYPT tmps = str_get(st[1]);#ifdef FCRYPT str_set(str,fcrypt(tmps,str_get(st[2])));#else str_set(str,crypt(tmps,str_get(st[2])));#endif#else fatal( "The crypt() function is unimplemented due to excessive paranoia.");#endif break; case O_ATAN2: value = str_gnum(st[1]); value = atan2(value,str_gnum(st[2])); goto donumset; case O_SIN: if (maxarg < 1) value = str_gnum(stab_val(defstab)); else value = str_gnum(st[1]); value = sin(value); goto donumset; case O_COS: if (maxarg < 1) value = str_gnum(stab_val(defstab)); else value = str_gnum(st[1]); value = cos(value); goto donumset; case O_RAND: if (maxarg < 1) value = 1.0; else value = str_gnum(st[1]); if (value == 0.0) value = 1.0;#if RANDBITS == 31 value = rand() * value / 2147483648.0;#else#if RANDBITS == 16 value = rand() * value / 65536.0;#else#if RANDBITS == 15 value = rand() * value / 32768.0;#else value = rand() * value / (double)(((unsigned long)1) << RANDBITS);#endif#endif#endif goto donumset; case O_SRAND: if (maxarg < 1) { (void)time(&when); anum = when; } else anum = (int)str_gnum(st[1]); (void)srand(anum); goto say_yes; case O_EXP: if (maxarg < 1) value = str_gnum(stab_val(defstab)); else value = str_gnum(st[1]); value = exp(value); goto donumset; case O_LOG: if (maxarg < 1) value = str_gnum(stab_val(defstab)); else value = str_gnum(st[1]); if (value <= 0.0) fatal("Can't take log of %g\n", value); value = log(value); goto donumset; case O_SQRT: if (maxarg < 1) value = str_gnum(stab_val(defstab)); else value = str_gnum(st[1]); if (value < 0.0) fatal("Can't take sqrt of %g\n", value); value = sqrt(value); goto donumset; case O_INT: if (maxarg < 1) value = str_gnum(stab_val(defstab)); else value = str_gnum(st[1]); if (value >= 0.0) (void)modf(value,&value); else { (void)modf(-value,&value); value = -value; } goto donumset; case O_ORD: if (maxarg < 1) tmps = str_get(stab_val(defstab)); else tmps = str_get(st[1]);#ifndef I286 value = (double) (*tmps & 255);#else anum = (int) *tmps; value = (double) (anum & 255);#endif goto donumset; case O_ALARM:#ifdef HAS_ALARM if (maxarg < 1) tmps = str_get(stab_val(defstab)); else tmps = str_get(st[1]); if (!tmps) tmps = "0"; anum = alarm((unsigned int)atoi(tmps)); if (anum < 0) goto say_undef; value = (double)anum; goto donumset;#else fatal("Unsupported function alarm"); break;#endif case O_SLEEP: if (maxarg < 1) tmps = Nullch; else tmps = str_get(st[1]); (void)time(&when); if (!tmps || !*tmps) sleep((32767<<16)+32767); else sleep((unsigned int)atoi(tmps));#ifndef lint value = (double)when; (void)time(&when); value = ((double)when) - value;#endif goto donumset; case O_RANGE: sp = do_range(gimme,arglast); goto array_return; case O_F_OR_R: if (gimme == G_ARRAY) { /* it's a range */ /* can we optimize to constant array? */ if ((arg[1].arg_type & A_MASK) == A_SINGLE && (arg[2].arg_type & A_MASK) == A_SINGLE) { st[2] = arg[2].arg_ptr.arg_str; sp = do_range(gimme,arglast); st = stack->ary_array; maxarg = sp - arglast[0]; str_free(arg[1].arg_ptr.arg_str); arg[1].arg_ptr.arg_str = Nullstr; str_free(arg[2].arg_ptr.arg_str); arg[2].arg_ptr.arg_str = Nullstr; arg->arg_type = O_ARRAY; arg[1].arg_type = A_STAB|A_DONT; arg->arg_len = 1; stab = arg[1].arg_ptr.arg_stab = aadd(genstab()); ary = stab_array(stab); afill(ary,maxarg - 1); anum = maxarg; st += arglast[0]+1; while (maxarg-- > 0) ary->ary_array[maxarg] = str_smake(st[maxarg]); st -= arglast[0]+1; goto array_return; } arg->arg_type = optype = O_RANGE; maxarg = arg->arg_len = 2; anum = 2; arg[anum].arg_flags &= ~AF_ARYOK; argflags = arg[anum].arg_flags; argtype = arg[anum].arg_type & A_MASK; arg[anum].arg_type = argtype; argptr = arg[anum].arg_ptr; sp = arglast[0]; st -= sp; sp++; goto re_eval; } arg->arg_type = O_FLIP; /* FALL THROUGH */ case O_FLIP: if ((arg[1].arg_type & A_MASK) == A_SINGLE ? last_in_stab && (int)str_gnum(st[1]) == stab_io(last_in_stab)->lines : str_true(st[1]) ) { arg[2].arg_type &= ~A_DONT; arg[1].arg_type |= A_DONT; arg->arg_type = optype = O_FLOP; if (arg->arg_flags & AF_COMMON) { str_numset(str,0.0); anum = 2; argflags = arg[2].arg_flags; argtype = arg[2].arg_type & A_MASK; argptr = arg[2].arg_ptr; sp = arglast[0]; st -= sp++; goto re_eval; } else { str_numset(str,1.0); break; } } str_set(str,""); break; case O_FLOP: str_inc(str); if ((arg[2].arg_type & A_MASK) == A_SINGLE ? last_in_stab && (int)str_gnum(st[2]) == stab_io(last_in_stab)->lines : str_true(st[2]) ) { arg->arg_type = O_FLIP; arg[1].arg_type &= ~A_DONT; arg[2].arg_type |= A_DONT; str_cat(str,"E0"); } break; case O_FORK:#ifdef HAS_FORK anum = fork(); if (anum < 0) goto say_undef; if (!anum) { /*SUPPRESS 560*/ if (tmpstab = stabent("$",allstabs)) str_numset(STAB_STR(tmpstab),(double)getpid()); hclear(pidstatus, FALSE); /* no kids, so don't wait for 'em */ } value = (double)anum; goto donumset;#else fatal("Unsupported function fork"); break;#endif case O_WAIT:#ifdef HAS_WAIT#ifndef lint anum = wait(&argflags); if (anum > 0) pidgone(anum,argflags); value = (double)anum;#endif statusvalue = (unsigned short)argflags; goto donumset;#else fatal("Unsupported function wait"); break;#endif case O_WAITPID:#ifdef HAS_WAIT#ifndef lint anum = (int)str_gnum(st[1]); optype = (int)str_gnum(st[2]); anum = wait4pid(anum, &argflags,optype); value = (double)anum;#endif statusvalue = (unsigned short)argflags; goto donumset;#else fatal("Unsupported function wait"); break;#endif case O_SYSTEM:#ifdef HAS_FORK#ifdef TAINT if (arglast[2] - arglast[1] == 1) { taintenv(); tainted |= st[2]->str_tainted; taintproper("Insecure dependency in system"); }#endif while ((anum = vfork()) == -1) { if (errno != EAGAIN) { value = -1.0; goto donumset; } sleep(5); } if (anum > 0) {#ifndef lint ihand = signal(SIGINT, SIG_IGN); qhand = signal(SIGQUIT, SIG_IGN); argtype = wait4pid(anum, &argflags, 0);#else ihand = qhand = 0;#endif (void)signal(SIGINT, ihand); (void)signal(SIGQUIT, qhand); statusvalue = (unsigned short)argflags; if (argtype < 0) value = -1.0; else { value = (double)((unsigned int)argflags & 0xffff); } do_execfree(); /* free any memory child malloced on vfork */ goto donumset; } if ((arg[1].arg_type & A_MASK) == A_STAB) value = (double)do_aexec(st[1],arglast); else if (arglast[2] - arglast[1] != 1) value = (double)do_aexec(Nullstr,arglast); else { value = (double)do_exec(str_get(str_mortal(st[2]))); } _exit(-1);#else /* ! FORK */ if ((arg[1].arg_type & A_MASK) == A_STAB) value = (double)do_aspawn(st[1],arglast); else if (arglast[2] - arglast[1] != 1) value = (double)do_aspawn(Nullstr,arglast); else { value = (double)do_spawn(str_get(str_mortal(st[2]))); } goto donumset;#endif /* FORK */ case O_EXEC_OP: if ((arg[1].arg_type & A_MASK) == A_STAB) value = (double)do_aexec(st[1],arglast); else if (arglast[2] - arglast[1] != 1) value = (double)do_aexec(Nullstr,arglast); else {#ifdef TAINT taintenv(); tainted |= st[2]->str_tainted; taintproper("Insecure dependency in exec");#endif value = (double)do_exec(str_get(str_mortal(st[2]))); } goto donumset; case O_HEX: if (maxarg < 1) tmps = str_get(stab_val(defstab)); else tmps = str_get(st[1]); value = (double)scanhex(tmps, 99, &argtype); goto donumset; case O_OCT: if (maxarg < 1) tmps = str_get(stab_val(defstab)); else tmps = str_get(st[1]); while (*tmps && (isSPACE(*tmps) || *tmps == '0')) tmps++; if (*tmps == 'x') value = (double)scanhex(++tmps, 99, &argtype); else value = (double)scanoct(tmps, 99, &argtype); goto donumset;/* These common exits are hidden here in the middle of the switches for the benefit of those machines with limited branch addressing. Sigh. */array_return:#ifdef DEBUGGING if (debug) { dlevel--; if (debug & 8) { anum = sp - arglast[0]; switch (anum) { case 0: deb("%s RETURNS ()\n",opname[optype]); break; case 1: deb("%s RETURNS (\"%s\")\n",opname[optype], st[1] ? str_get(st[1]) : ""); break; default: tmps = st[1] ? str_get(st[1]) : ""; deb("%s RETURNS %d ARGS (\"%s\",%s\"%s\")\n",opname[optype], anum,tmps,anum==2?"":"...,", st[anum] ? str_get(st[anum]) : ""); break; } } }#endif return sp;say_yes: str = &str_yes; goto normal_return;say_no: str = &str_no; goto normal_return;say_undef: str = &str_undef; goto normal_return;say_zero: value = 0.0; /* FALL THROUGH */donumset: str_numset(str,value); STABSET(str); st[1] = str;#ifdef DEBUGGING if (debug) { dlevel--; if (debug & 8) deb("%s RETURNS \"%f\"\n",opname[optype],value); }#endif return arglast[0] + 1;#ifdef SMALLSWITCHES } else switch (optype) {#endif case O_CHOWN:#ifdef HAS_CHOWN value = (double)apply(optype,arglast); goto donumset;#else fatal("Unsupported function chown"); break;#endif case O_KILL:#ifdef HAS_KILL value = (double)apply(optype,arglast); goto donumset;#else fatal("Unsupported function kill"); break;#endif case O_UNLINK: case O_CHMOD: case O_UTIME: value = (double)apply(optype,arglast); goto donumset; case O_UMASK:#ifdef HAS_UMASK if (maxarg < 1) { anum = umask(0); (void)umask(anum); } else anum = umask((int)str_gnum(st[1])); value = (double)anum;#ifdef TAINT taintproper("Insecure dependency in umask");#endif goto donumset;#else fatal("Unsupported function umask"); break;#endif#if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM) case O_MSGGET: case O_SHMGET: case O_SEMGET: if ((anum = do_ipcget(optype, arglast)) == -1) goto say_undef; value = (double)anum; goto donumset; case O_MSGCTL: case O_SHMCTL: case O_SEMCTL: anum = do_ipcctl(optype, arglast); if (anum == -1) goto say_undef; if (anum != 0) { value = (double)anum; goto donumset; } str_set(str,"0 but true"); STABSET(str); break; case O_MSGSND: value = (double)(do_msgsnd(arglast) >= 0); goto donumset; case O_MSGRCV: value = (double)(do_msgrcv(arglast) >= 0); goto donumset; case O_SEMOP: value = (double)(do_semop(arglast) >= 0); goto donumset; case O_SHMREAD: case O_SHMWRITE: value = (double)(do_shmio(optype, arglast) >= 0); goto donumset;#else /* not SYSVIPC */ case O_MSGGET: case O_MSGCTL: case O_MSGSND: case O_MSGRCV: case O_SEMGET: case O_SEMCTL: case O_SEMOP: case O_SHMGET:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -