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

📄 consarg.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	{	    int  zapc;	    char *zaps;	    zaps = str_get(s1);	    zapc = (int) *zaps;	    str_numset(str,(double)(zapc));	}#endif	break;    }    arg->arg_type = O_ITEM;	/* note arg1 type is already SINGLE */    str_free(s1);    arg[1].arg_ptr.arg_str = str;    if (s2) {	str_free(s2);	arg[2].arg_ptr.arg_str = Nullstr;	arg[2].arg_type = A_NULL;    }    str = Nullstr;    return arg;}ARG *l(arg)register ARG *arg;{    register int i;    register ARG *arg1;    register ARG *arg2;    SPAT *spat;    int arghog = 0;    i = arg[1].arg_type & A_MASK;    arg->arg_flags |= AF_COMMON;	/* assume something in common */					/* which forces us to copy things */    if (i == A_ARYLEN) {	arg[1].arg_type = A_LARYLEN;	return arg;    }    if (i == A_ARYSTAB) {	arg[1].arg_type = A_LARYSTAB;	return arg;    }    /* see if it's an array reference */    if (i == A_EXPR || i == A_LEXPR) {	arg1 = arg[1].arg_ptr.arg_arg;	if (arg1->arg_type == O_LIST || arg1->arg_type == O_ITEM) {						/* assign to list */	    if (arg->arg_len > 1) {		dehoist(arg,2);		arg2 = arg[2].arg_ptr.arg_arg;		if (nothing_in_common(arg1,arg2))		    arg->arg_flags &= ~AF_COMMON;		if (arg->arg_type == O_ASSIGN) {		    if (arg1->arg_flags & AF_LOCAL)			arg->arg_flags |= AF_LOCAL;		    arg[1].arg_flags |= AF_ARYOK;		    arg[2].arg_flags |= AF_ARYOK;		}	    }	    else if (arg->arg_type != O_CHOP)		arg->arg_type = O_ASSIGN;	/* possible local(); */	    for (i = arg1->arg_len; i >= 1; i--) {		switch (arg1[i].arg_type) {		case A_STAR: case A_LSTAR:		    arg1[i].arg_type = A_LSTAR;		    break;		case A_STAB: case A_LVAL:		    arg1[i].arg_type = A_LVAL;		    break;		case A_ARYLEN: case A_LARYLEN:		    arg1[i].arg_type = A_LARYLEN;		    break;		case A_ARYSTAB: case A_LARYSTAB:		    arg1[i].arg_type = A_LARYSTAB;		    break;		case A_EXPR: case A_LEXPR:		    arg1[i].arg_type = A_LEXPR;		    switch(arg1[i].arg_ptr.arg_arg->arg_type) {		    case O_ARRAY: case O_LARRAY:			arg1[i].arg_ptr.arg_arg->arg_type = O_LARRAY;			arghog = 1;			break;		    case O_AELEM: case O_LAELEM:			arg1[i].arg_ptr.arg_arg->arg_type = O_LAELEM;			break;		    case O_HASH: case O_LHASH:			arg1[i].arg_ptr.arg_arg->arg_type = O_LHASH;			arghog = 1;			break;		    case O_HELEM: case O_LHELEM:			arg1[i].arg_ptr.arg_arg->arg_type = O_LHELEM;			break;		    case O_ASLICE: case O_LASLICE:			arg1[i].arg_ptr.arg_arg->arg_type = O_LASLICE;			break;		    case O_HSLICE: case O_LHSLICE:			arg1[i].arg_ptr.arg_arg->arg_type = O_LHSLICE;			break;		    case O_SUBSTR: case O_VEC:			(void)l(arg1[i].arg_ptr.arg_arg);			Renewc(arg1[i].arg_ptr.arg_arg->arg_ptr.arg_str, 1,			  struct lstring, STR);			    /* grow string struct to hold an lstring struct */			break;		    default:			goto ill_item;		    }		    break;		default:		  ill_item:		    (void)sprintf(tokenbuf, "Illegal item (%s) as lvalue",		      argname[arg1[i].arg_type&A_MASK]);		    yyerror(tokenbuf);		}	    }	    if (arg->arg_len > 1) {		if (arg2->arg_type == O_SPLIT && !arg2[3].arg_type && !arghog) {		    arg2[3].arg_type = A_SINGLE;		    arg2[3].arg_ptr.arg_str =		      str_nmake((double)arg1->arg_len + 1); /* limit split len*/		}	    }	}	else if (arg1->arg_type == O_AELEM || arg1->arg_type == O_LAELEM)	    if (arg->arg_type == O_DEFINED)		arg1->arg_type = O_AELEM;	    else		arg1->arg_type = O_LAELEM;	else if (arg1->arg_type == O_ARRAY || arg1->arg_type == O_LARRAY) {	    arg1->arg_type = O_LARRAY;	    if (arg->arg_len > 1) {		dehoist(arg,2);		arg2 = arg[2].arg_ptr.arg_arg;		if (arg2->arg_type == O_SPLIT) { /* use split's builtin =?*/		    spat = arg2[2].arg_ptr.arg_spat;		    if (!(spat->spat_flags & SPAT_ONCE) &&		      nothing_in_common(arg1,spat->spat_repl)) {			spat->spat_repl[1].arg_ptr.arg_stab =			    arg1[1].arg_ptr.arg_stab;			arg1[1].arg_ptr.arg_stab = Nullstab;			spat->spat_flags |= SPAT_ONCE;			arg_free(arg1);	/* recursive */			arg[1].arg_ptr.arg_arg = Nullarg;			free_arg(arg);	/* non-recursive */			return arg2;	/* split has builtin assign */		    }		}		else if (nothing_in_common(arg1,arg2))		    arg->arg_flags &= ~AF_COMMON;		if (arg->arg_type == O_ASSIGN) {		    arg[1].arg_flags |= AF_ARYOK;		    arg[2].arg_flags |= AF_ARYOK;		}	    }	    else if (arg->arg_type == O_ASSIGN)		arg[1].arg_flags |= AF_ARYOK;	}	else if (arg1->arg_type == O_HELEM || arg1->arg_type == O_LHELEM)	    if (arg->arg_type == O_DEFINED)		arg1->arg_type = O_HELEM;	/* avoid creating one */	    else		arg1->arg_type = O_LHELEM;	else if (arg1->arg_type == O_HASH || arg1->arg_type == O_LHASH) {	    arg1->arg_type = O_LHASH;	    if (arg->arg_len > 1) {		dehoist(arg,2);		arg2 = arg[2].arg_ptr.arg_arg;		if (nothing_in_common(arg1,arg2))		    arg->arg_flags &= ~AF_COMMON;		if (arg->arg_type == O_ASSIGN) {		    arg[1].arg_flags |= AF_ARYOK;		    arg[2].arg_flags |= AF_ARYOK;		}	    }	    else if (arg->arg_type == O_ASSIGN)		arg[1].arg_flags |= AF_ARYOK;	}	else if (arg1->arg_type == O_ASLICE) {	    arg1->arg_type = O_LASLICE;	    if (arg->arg_type == O_ASSIGN) {		dehoist(arg,2);		arg[1].arg_flags |= AF_ARYOK;		arg[2].arg_flags |= AF_ARYOK;	    }	}	else if (arg1->arg_type == O_HSLICE) {	    arg1->arg_type = O_LHSLICE;	    if (arg->arg_type == O_ASSIGN) {		dehoist(arg,2);		arg[1].arg_flags |= AF_ARYOK;		arg[2].arg_flags |= AF_ARYOK;	    }	}	else if ((arg->arg_type == O_DEFINED || arg->arg_type == O_UNDEF) &&	  (arg1->arg_type == (perldb ? O_DBSUBR : O_SUBR)) ) {	    arg[1].arg_type |= A_DONT;	}	else if (arg1->arg_type == O_SUBSTR || arg1->arg_type == O_VEC) {	    (void)l(arg1);	    Renewc(arg1->arg_ptr.arg_str, 1, struct lstring, STR);			/* grow string struct to hold an lstring struct */	}	else if (arg1->arg_type == O_ASSIGN)	    /*SUPPRESS 530*/	    ;	else {	    (void)sprintf(tokenbuf,	      "Illegal expression (%s) as lvalue",opname[arg1->arg_type]);	    yyerror(tokenbuf);	    return arg;	}	arg[1].arg_type = A_LEXPR | (arg[1].arg_type & A_DONT);	if (arg->arg_type == O_ASSIGN && (arg1[1].arg_flags & AF_ARYOK)) {	    arg[1].arg_flags |= AF_ARYOK;	    if (arg->arg_len > 1)		arg[2].arg_flags |= AF_ARYOK;	}#ifdef DEBUGGING	if (debug & 16)	    fprintf(stderr,"lval LEXPR\n");#endif	return arg;    }    if (i == A_STAR || i == A_LSTAR) {	arg[1].arg_type = A_LSTAR | (arg[1].arg_type & A_DONT);	return arg;    }    /* not an array reference, should be a register name */    if (i != A_STAB && i != A_LVAL) {	(void)sprintf(tokenbuf,	  "Illegal item (%s) as lvalue",argname[arg[1].arg_type&A_MASK]);	yyerror(tokenbuf);	return arg;    }    arg[1].arg_type = A_LVAL | (arg[1].arg_type & A_DONT);#ifdef DEBUGGING    if (debug & 16)	fprintf(stderr,"lval LVAL\n");#endif    return arg;}ARG *fixl(type,arg)int type;ARG *arg;{    if (type == O_DEFINED || type == O_UNDEF) {	if (arg->arg_type != O_ITEM)	    arg = hide_ary(arg);	if (arg->arg_type == O_ITEM) {	    type = arg[1].arg_type & A_MASK;	    if (type == A_EXPR || type == A_LEXPR)		arg[1].arg_type = A_LEXPR|A_DONT;	}    }    return arg;}voiddehoist(arg,i)ARG *arg;{    ARG *tmparg;    if (arg[i].arg_type != A_EXPR) {	/* dehoist */	tmparg = make_op(O_ITEM,1,Nullarg,Nullarg,Nullarg);	tmparg[1] = arg[i];	arg[i].arg_ptr.arg_arg = tmparg;	arg[i].arg_type = A_EXPR;    }}ARG *addflags(i,flags,arg)register ARG *arg;{    arg[i].arg_flags |= flags;    return arg;}ARG *hide_ary(arg)ARG *arg;{    if (arg->arg_type == O_ARRAY || arg->arg_type == O_HASH)	return make_op(O_ITEM,1,arg,Nullarg,Nullarg);    return arg;}/* maybe do a join on multiple array dimensions */ARG *jmaybe(arg)register ARG *arg;{    if (arg && arg->arg_type == O_COMMA) {	arg = listish(arg);	arg = make_op(O_JOIN, 2,	    stab2arg(A_STAB,stabent(";",TRUE)),	    make_list(arg),	    Nullarg);    }    return arg;}ARG *make_list(arg)register ARG *arg;{    register int i;    register ARG *node;    register ARG *nxtnode;    register int j;    STR *tmpstr;    if (!arg) {	arg = op_new(0);	arg->arg_type = O_LIST;    }    if (arg->arg_type != O_COMMA) {	if (arg->arg_type != O_ARRAY)	    arg->arg_flags |= AF_LISTISH;	/* see listish() below */	    arg->arg_flags |= AF_LISTISH;	/* see listish() below */	return arg;    }    for (i = 2, node = arg; ; i++) {	if (node->arg_len < 2)	    break;        if (node[1].arg_type != A_EXPR)	    break;	node = node[1].arg_ptr.arg_arg;	if (node->arg_type != O_COMMA)	    break;    }    if (i > 2) {	node = arg;	arg = op_new(i);	tmpstr = arg->arg_ptr.arg_str;	StructCopy(node, arg, ARG);	/* copy everything except the STR */	arg->arg_ptr.arg_str = tmpstr;	for (j = i; ; ) {	    StructCopy(node+2, arg+j, ARG);	    arg[j].arg_flags |= AF_ARYOK;	    --j;		/* Bug in Xenix compiler */	    if (j < 2) {		StructCopy(node+1, arg+1, ARG);		free_arg(node);		break;	    }	    nxtnode = node[1].arg_ptr.arg_arg;	    free_arg(node);	    node = nxtnode;	}    }    arg[1].arg_flags |= AF_ARYOK;    arg[2].arg_flags |= AF_ARYOK;    arg->arg_type = O_LIST;    arg->arg_len = i;    str_free(arg->arg_ptr.arg_str);    arg->arg_ptr.arg_str = Nullstr;    return arg;}/* turn a single item into a list */ARG *listish(arg)ARG *arg;{    if (arg && arg->arg_flags & AF_LISTISH)	arg = make_op(O_LIST,1,arg,Nullarg,Nullarg);    return arg;}ARG *maybelistish(optype, arg)int optype;ARG *arg;{    ARG *tmparg = arg;    if (optype == O_RETURN && arg->arg_type == O_ITEM &&      arg[1].arg_type == A_EXPR && (tmparg = arg[1].arg_ptr.arg_arg) &&      ((tmparg->arg_flags & AF_LISTISH) || (tmparg->arg_type == O_ARRAY) )) {	tmparg = listish(tmparg);	free_arg(arg);	arg = tmparg;    }    else if (optype == O_PRTF ||      (arg->arg_type == O_ASLICE || arg->arg_type == O_HSLICE ||       arg->arg_type == O_F_OR_R) )	arg = listish(arg);    return arg;}/* mark list of local variables */ARG *localize(arg)ARG *arg;{    arg->arg_flags |= AF_LOCAL;    return arg;}ARG *rcatmaybe(arg)ARG *arg;{    ARG *arg2;    if (arg->arg_type == O_CONCAT && arg[2].arg_type == A_EXPR) {	arg2 = arg[2].arg_ptr.arg_arg;	if (arg2->arg_type == O_ITEM && arg2[1].arg_type == A_READ) {	    arg->arg_type = O_RCAT;		    arg[2].arg_type = arg2[1].arg_type;	    arg[2].arg_ptr = arg2[1].arg_ptr;	    free_arg(arg2);	}    }    return arg;}ARG *stab2arg(atype,stab)int atype;register STAB *stab;{    register ARG *arg;    arg = op_new(1);    arg->arg_type = O_ITEM;    arg[1].arg_type = atype;    arg[1].arg_ptr.arg_stab = stab;    return arg;}ARG *cval_to_arg(cval)register char *cval;{    register ARG *arg;    arg = op_new(1);    arg->arg_type = O_ITEM;    arg[1].arg_type = A_SINGLE;    arg[1].arg_ptr.arg_str = str_make(cval,0);    Safefree(cval);    return arg;}ARG *op_new(numargs)int numargs;{    register ARG *arg;    Newz(203,arg, numargs + 1, ARG);    arg->arg_ptr.arg_str = Str_new(21,0);    arg->arg_len = numargs;    return arg;}voidfree_arg(arg)ARG *arg;{    str_free(arg->arg_ptr.arg_str);    Safefree(arg);}ARG *make_match(type,expr,spat)int type;ARG *expr;SPAT *spat;{    register ARG *arg;    arg = make_op(type,2,expr,Nullarg,Nullarg);    arg[2].arg_type = A_SPAT|A_DONT;    arg[2].arg_ptr.arg_spat = spat;#ifdef DEBUGGING    if (debug & 16)	fprintf(stderr,"make_match SPAT=%lx\n",(long)spat);#endif    if (type == O_SUBST || type == O_NSUBST) {	if (arg[1].arg_type != A_STAB) {	    yyerror("Illegal lvalue");	}	arg[1].arg_type = A_LVAL;    }    return arg;}ARG *cmd_to_arg(cmd)CMD *cmd;{    register ARG *arg;    arg = op_new(1);    arg->arg_type = O_ITEM;    arg[1].arg_type = A_CMD;    arg[1].arg_ptr.arg_cmd = cmd;    return arg;}/* Check two expressions to see if there is any identifier in common */static intnothing_in_common(arg1,arg2)ARG *arg1;ARG *arg2;{    static int thisexpr = 0;	/* I don't care if this wraps */    thisexpr++;    if (arg_common(arg1,thisexpr,1))	return 0;	/* hit eval or do {} */    stab_lastexpr(defstab) = thisexpr;		/* pretend to hit @_ */    if (arg_common(arg2,thisexpr,0))	return 0;	/* hit identifier again */    return 1;}/* Recursively descend an expression and mark any identifier or check * it to see if it was marked already. */static intarg_common(arg,exprnum,marking)register ARG *arg;int exprnum;int marking;{    register int i;    if (!arg)	return 0;    for (i = arg->arg_len; i >= 1; i--) {	switch (arg[i].arg_type & A_MASK) {	case A_NULL:	    break;	case A_LEXPR:	case A_EXPR:	    if (arg_common(arg[i].arg_ptr.arg_arg,exprnum,marking))		return 1;	    break;	case A_CMD:	    return 1;		/* assume hanky panky */	case A_STAR:	case A_LSTAR:	case A_STAB:	case A_LVAL:	case A_ARYLEN:	case A_LARYLEN:	    if (marking)		stab_lastexpr(arg[i].arg_ptr.arg_stab) = exprnum;	    else if (stab_lastexpr(arg[i].arg_ptr.arg_stab) == exprnum)		return 1;	    break;	case A_DOUBLE:	case A_BACKTICK:	    {		register char *s = arg[i].arg_ptr.arg_str->str_ptr;		register char *send = s + arg[i].arg_ptr.arg_str->str_cur;		register STAB *stab;		while (*s) {		    if (*s == '$' && s[1]) {			s = scanident(s,send,tokenbuf);			stab = stabent(tokenbuf,TRUE);			if (marking)			    stab_lastexpr(stab) = exprnum;			else if (stab_lastexpr(stab) == exprnum)			    return 1;			continue;		    }		    else if (*s == '\\' && s[1])			s++;		    s++;		}	    }	    break;	case A_SPAT:	    if (spat_common(arg[i].arg_ptr.arg_spat,exprnum,marking))		return 1;	    break;	case A_READ:	case A_INDREAD:	case A_GLOB:	case A_WORD:	case A_SINGLE:	    break;	}    }    switch (arg->arg_type) {    case O_ARRAY:    case O_LARRAY:	if ((arg[1].arg_type & A_MASK) == A_STAB)	    (void)aadd(arg[1].arg_ptr.arg_stab);	break;    case O_HASH:    case O_LHASH:	if ((arg[1].arg_type & A_MASK) == A_STAB)	    (void)hadd(arg[1].arg_ptr.arg_stab);	break;    case O_EVAL:    case O_SUBR:    case O_DBSUBR:	return 1;    }    return 0;}static intspat_common(spat,exprnum,marking)register SPAT *spat;int exprnum;int marking;{    if (spat->spat_runtime)	if (arg_common(spat->spat_runtime,exprnum,marking))	    return 1;    if (spat->spat_repl) {	if (arg_common(spat->spat_repl,exprnum,marking))	    return 1;    }    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -