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

📄 walk.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
/* $RCSfile: walk.c,v $$Revision: 4.0.1.3 $$Date: 92/06/08 17:33:46 $ * *    Copyright (c) 1991, Larry Wall * *    You may distribute under the terms of either the GNU General Public *    License or the Artistic License, as specified in the README file. * * $Log:	walk.c,v $ * Revision 4.0.1.3  92/06/08  17:33:46  lwall * patch20: in a2p, simplified the filehandle model * patch20: in a2p, made RS="" translate to $/ = "\n\n" * patch20: in a2p, do {...} while ... was missing some reconstruction code * patch20: in a2p, getline should allow variable to be array element *  * Revision 4.0.1.2  91/11/05  19:25:09  lwall * patch11: in a2p, split on whitespace produced extra null field *  * Revision 4.0.1.1  91/06/07  12:22:04  lwall * patch4: new copyright notice * patch4: a2p didn't correctly implement -n switch *  * Revision 4.0  91/03/20  01:58:36  lwall * 4.0 baseline. *  */#include "handy.h"#include "EXTERN.h"#include "util.h"#include "a2p.h"bool exitval = FALSE;bool realexit = FALSE;bool saw_getline = FALSE;bool subretnum = FALSE;bool saw_FNR = FALSE;bool saw_argv0 = FALSE;bool saw_fh = FALSE;int maxtmp = 0;char *lparen;char *rparen;char *limit;STR *subs;STR *curargs = Nullstr;STR *walk(useval,level,node,numericptr,minprec)int useval;int level;register int node;int *numericptr;int minprec;			/* minimum precedence without parens */{    register int len;    register STR *str;    register int type;    register int i;    register STR *tmpstr;    STR *tmp2str;    STR *tmp3str;    char *t;    char *d, *s;    int numarg;    int numeric = FALSE;    STR *fstr;    int prec = P_MAX;		/* assume no parens needed */    char *index();    if (!node) {	*numericptr = 0;	return str_make("");    }    type = ops[node].ival;    len = type >> 8;    type &= 255;    switch (type) {    case OPROG:	arymax = 0;	if (namelist) {	    while (isalpha(*namelist)) {		for (d = tokenbuf,s=namelist;		  isalpha(*s) || isdigit(*s) || *s == '_';		  *d++ = *s++) ;		*d = '\0';		while (*s && !isalpha(*s)) s++;		namelist = s;		nameary[++arymax] = savestr(tokenbuf);	    }	}	if (maxfld < arymax)	    maxfld = arymax;	opens = str_new(0);	subs = str_new(0);	str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);	if (do_split && need_entire && !absmaxfld)	    split_to_array = TRUE;	if (do_split && split_to_array)	    set_array_base = TRUE;	if (set_array_base) {	    str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");	}	if (fswitch && !const_FS)	    const_FS = fswitch;	if (saw_FS > 1 || saw_RS)	    const_FS = 0;	if (saw_ORS && need_entire)	    do_chop = TRUE;	if (fswitch) {	    str_cat(str,"$FS = '");	    if (index("*+?.[]()|^$\\",fswitch))		str_cat(str,"\\");	    sprintf(tokenbuf,"%c",fswitch);	    str_cat(str,tokenbuf);	    str_cat(str,"';\t\t# field separator from -F switch\n");	}	else if (saw_FS && !const_FS) {	    str_cat(str,"$FS = ' ';\t\t# set field separator\n");	}	if (saw_OFS) {	    str_cat(str,"$, = ' ';\t\t# set output field separator\n");	}	if (saw_ORS) {	    str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");	}	if (saw_argv0) {	    str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");	}	if (str->str_cur > 20)	    str_cat(str,"\n");	if (ops[node+2].ival) {	    str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));	    str_free(fstr);	    str_cat(str,"\n\n");	}	fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);	if (*fstr->str_ptr) {	    if (saw_line_op)		str_cat(str,"line: ");	    str_cat(str,"while (<>) {\n");	    tab(str,++level);	    if (saw_FS && !const_FS)		do_chop = TRUE;	    if (do_chop) {		str_cat(str,"chop;\t# strip record separator\n");		tab(str,level);	    }	    if (do_split)		emit_split(str,level);	    str_scat(str,fstr);	    str_free(fstr);	    fixtab(str,--level);	    str_cat(str,"}\n");	    if (saw_FNR)		str_cat(str,"continue {\n    $FNRbase = $. if eof;\n}\n");	}	else	    str_cat(str,"while (<>) { }		# (no line actions)\n");	if (ops[node+4].ival) {	    realexit = TRUE;	    str_cat(str,"\n");	    tab(str,level);	    str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));	    str_free(fstr);	    str_cat(str,"\n");	}	if (exitval)	    str_cat(str,"exit $ExitValue;\n");	if (subs->str_ptr) {	    str_cat(str,"\n");	    str_scat(str,subs);	}	if (saw_getline) {	    for (len = 0; len < 4; len++) {		if (saw_getline & (1 << len)) {		    sprintf(tokenbuf,"\nsub Getline%d {\n",len);		    str_cat(str, tokenbuf);		    if (len & 2) {			if (do_fancy_opens)			    str_cat(str,"    &Pick('',@_);\n");			else			    str_cat(str,"    ($fh) = @_;\n");		    }		    else {			if (saw_FNR)			    str_cat(str,"    $FNRbase = $. if eof;\n");		    }		    if (len & 1)			str_cat(str,"    local($_);\n");		    if (len & 2)			str_cat(str,			  "    if ($getline_ok = (($_ = <$fh>) ne ''))");		    else			str_cat(str,			  "    if ($getline_ok = (($_ = <>) ne ''))");		    str_cat(str, " {\n");		    level += 2;		    tab(str,level);		    i = 0;		    if (do_chop) {			i++;			str_cat(str,"chop;\t# strip record separator\n");			tab(str,level);		    }		    if (do_split && !(len & 1)) {			i++;			emit_split(str,level);		    }		    if (!i)			str_cat(str,";\n");		    fixtab(str,--level);		    str_cat(str,"}\n    $_;\n}\n");		    --level;		}	    }	}	if (do_fancy_opens) {	    str_cat(str,"\n\sub Pick {\n\    local($mode,$name,$pipe) = @_;\n\    $fh = $name;\n\    open($name,$mode.$name.$pipe) unless $opened{$name}++;\n\}\n\");	}	break;    case OHUNKS:	str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);	str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));	str_free(fstr);	if (len == 3) {	    str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));	    str_free(fstr);	}	else {	}	break;    case ORANGE:	prec = P_DOTDOT;	str = walk(1,level,ops[node+1].ival,&numarg,prec+1);	str_cat(str," .. ");	str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));	str_free(fstr);	break;    case OPAT:	goto def;    case OREGEX:	str = str_new(0);	str_set(str,"/");	tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);	/* translate \nnn to [\nnn] */	for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {	    if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])){		*d++ = '[';		*d++ = *s++;		*d++ = *s++;		*d++ = *s++;		*d++ = *s;		*d = ']';	    }	    else		*d = *s;	}	*d = '\0';	for (d=tokenbuf; *d; d++)	    *d += 128;	str_cat(str,tokenbuf);	str_free(tmpstr);	str_cat(str,"/");	break;    case OHUNK:	if (len == 1) {	    str = str_new(0);	    str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);	    str_cat(str," if ");	    str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));	    str_free(fstr);	    str_cat(str,";");	}	else {	    tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);	    if (*tmpstr->str_ptr) {		str = str_new(0);		str_set(str,"if (");		str_scat(str,tmpstr);		str_cat(str,") {\n");		tab(str,++level);		str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));		str_free(fstr);		fixtab(str,--level);		str_cat(str,"}\n");		tab(str,level);	    }	    else {		str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);	    }	}	break;    case OPPAREN:	str = str_new(0);	str_set(str,"(");	str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));	str_free(fstr);	str_cat(str,")");	break;    case OPANDAND:	prec = P_ANDAND;	str = walk(1,level,ops[node+1].ival,&numarg,prec);	str_cat(str," && ");	str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));	str_free(fstr);	str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));	str_free(fstr);	break;    case OPOROR:	prec = P_OROR;	str = walk(1,level,ops[node+1].ival,&numarg,prec);	str_cat(str," || ");	str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));	str_free(fstr);	str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));	str_free(fstr);	break;    case OPNOT:	prec = P_UNARY;	str = str_new(0);	str_set(str,"!");	str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));	str_free(fstr);	break;    case OCOND:	prec = P_COND;	str = walk(1,level,ops[node+1].ival,&numarg,prec);	str_cat(str," ? ");	str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));	str_free(fstr);	str_cat(str," : ");	str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));	str_free(fstr);	break;    case OCPAREN:	str = str_new(0);	str_set(str,"(");	str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));	str_free(fstr);	numeric |= numarg;	str_cat(str,")");	break;    case OCANDAND:	prec = P_ANDAND;	str = walk(1,level,ops[node+1].ival,&numarg,prec);	numeric = 1;	str_cat(str," && ");	str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));	str_free(fstr);	str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));	str_free(fstr);	break;    case OCOROR:	prec = P_OROR;	str = walk(1,level,ops[node+1].ival,&numarg,prec);	numeric = 1;	str_cat(str," || ");	str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));	str_free(fstr);	str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));	str_free(fstr);	break;    case OCNOT:	prec = P_UNARY;	str = str_new(0);	str_set(str,"!");	str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));	str_free(fstr);	numeric = 1;	break;    case ORELOP:	prec = P_REL;	str = walk(1,level,ops[node+2].ival,&numarg,prec+1);	numeric |= numarg;	tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);	tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);	numeric |= numarg;	if (!numeric ||	 (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {	    t = tmpstr->str_ptr;	    if (strEQ(t,"=="))		str_set(tmpstr,"eq");	    else if (strEQ(t,"!="))		str_set(tmpstr,"ne");	    else if (strEQ(t,"<"))		str_set(tmpstr,"lt");	    else if (strEQ(t,"<="))		str_set(tmpstr,"le");	    else if (strEQ(t,">"))		str_set(tmpstr,"gt");	    else if (strEQ(t,">="))		str_set(tmpstr,"ge");	    if (!index(tmpstr->str_ptr,'\'') && !index(tmpstr->str_ptr,'"') &&	      !index(tmp2str->str_ptr,'\'') && !index(tmp2str->str_ptr,'"') )		numeric |= 2;	}	if (numeric & 2) {	    if (numeric & 1)		/* numeric is very good guess */		str_cat(str," ");	    else		str_cat(str,"\377");	    numeric = 1;	}	else	    str_cat(str," ");	str_scat(str,tmpstr);	str_free(tmpstr);	str_cat(str," ");	str_scat(str,tmp2str);	str_free(tmp2str);	numeric = 1;	break;    case ORPAREN:	str = str_new(0);	str_set(str,"(");	str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));	str_free(fstr);	numeric |= numarg;	str_cat(str,")");	break;    case OMATCHOP:	prec = P_MATCH;	str = walk(1,level,ops[node+2].ival,&numarg,prec+1);	str_cat(str," ");	tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);	if (strEQ(tmpstr->str_ptr,"~"))	    str_cat(str,"=~");	else {	    str_scat(str,tmpstr);	    str_free(tmpstr);	}	str_cat(str," ");	str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));	str_free(fstr);	numeric = 1;	break;    case OMPAREN:	str = str_new(0);	str_set(str,"(");	str_scat(str,	  fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));	str_free(fstr);	numeric |= numarg;	str_cat(str,")");	break;    case OCONCAT:	prec = P_ADD;	type = ops[ops[node+1].ival].ival & 255;	str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));	str_cat(str," . ");	type = ops[ops[node+2].ival].ival & 255;	str_scat(str,	  fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));	str_free(fstr);	break;    case OASSIGN:	prec = P_ASSIGN;	str = walk(0,level,ops[node+2].ival,&numarg,prec+1);	str_cat(str," ");	tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);	str_scat(str,tmpstr);	if (str_len(tmpstr) > 1)	    numeric = 1;	str_free(tmpstr);	str_cat(str," ");	str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));	str_free(fstr);	numeric |= numarg;	if (strEQ(str->str_ptr,"$/ = ''"))	    str_set(str, "$/ = \"\\n\\n\"");	break;    case OADD:	prec = P_ADD;	str = walk(1,level,ops[node+1].ival,&numarg,prec);	str_cat(str," + ");	str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));	str_free(fstr);	numeric = 1;	break;    case OSUBTRACT:	prec = P_ADD;	str = walk(1,level,ops[node+1].ival,&numarg,prec);	str_cat(str," - ");	str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));	str_free(fstr);	numeric = 1;	break;    case OMULT:	prec = P_MUL;	str = walk(1,level,ops[node+1].ival,&numarg,prec);	str_cat(str," * ");	str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));	str_free(fstr);	numeric = 1;	break;    case ODIV:	prec = P_MUL;	str = walk(1,level,ops[node+1].ival,&numarg,prec);	str_cat(str," / ");	str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));	str_free(fstr);	numeric = 1;	break;    case OPOW:	prec = P_POW;	str = walk(1,level,ops[node+1].ival,&numarg,prec+1);	str_cat(str," ** ");	str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));	str_free(fstr);	numeric = 1;	break;    case OMOD:	prec = P_MUL;	str = walk(1,level,ops[node+1].ival,&numarg,prec);	str_cat(str," % ");	str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));

⌨️ 快捷键说明

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