⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eval.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 + -