-/* $Header: walk.c,v 4.0 91/03/20 01:58:36 lwall Locked $
+/* $RCSfile: walk.c,v $$Revision: 4.1 $$Date: 92/08/07 18:29:31 $
*
- * Copyright (c) 1989, Larry Wall
+ * Copyright (c) 1991-1997, Larry Wall
*
- * You may distribute under the terms of the GNU General Public License
- * as specified in the README file that comes with the perl 3.0 kit.
+ * 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 91/03/20 01:58:36 lwall
- * 4.0 baseline.
- *
*/
-#include "handy.h"
#include "EXTERN.h"
-#include "util.h"
#include "a2p.h"
+#include "util.h"
bool exitval = FALSE;
bool realexit = 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;
+static void addsemi _(( STR *str ));
+static void emit_split _(( STR *str, int level ));
+static void fixtab _(( STR *str, int lvl ));
+static void numericize _(( int node ));
+static void tab _(( STR *str, int lvl ));
+
+int prewalk _(( int numit, int level, int node, int *numericptr ));
+STR * walk _(( int useval, int level, int node, int *numericptr, int minprec ));
+
+
STR *
-walk(useval,level,node,numericptr,minprec)
-int useval;
-int level;
-register int node;
-int *numericptr;
-int minprec; /* minimum precedence without parens */
+walk(int useval, int level, register int node, int *numericptr, int minprec)
+
+
+
+
+ /* minimum precedence without parens */
{
register int len;
register STR *str;
int numeric = FALSE;
STR *fstr;
int prec = P_MAX; /* assume no parens needed */
- char *index();
if (!node) {
*numericptr = 0;
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);
do_chop = TRUE;
if (fswitch) {
str_cat(str,"$FS = '");
- if (index("*+?.[]()|^$\\",fswitch))
+ if (strchr("*+?.[]()|^$\\",fswitch))
str_cat(str,"\\");
sprintf(tokenbuf,"%c",fswitch);
str_cat(str,tokenbuf);
if (saw_FS && !const_FS)
do_chop = TRUE;
if (do_chop) {
- str_cat(str,"chop;\t# strip record separator\n");
+ str_cat(str,"chomp;\t# strip record separator\n");
tab(str,level);
}
- 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;
if (do_split)
emit_split(str,level);
str_scat(str,fstr);
if (saw_FNR)
str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n");
}
- else
+ else if (old_awk)
str_cat(str,"while (<>) { } # (no line actions)\n");
if (ops[node+4].ival) {
realexit = TRUE;
i = 0;
if (do_chop) {
i++;
- str_cat(str,"chop;\t# strip record separator\n");
+ str_cat(str,"chomp;\t# strip record separator\n");
tab(str,level);
}
if (do_split && !(len & 1)) {
str_cat(str,"\n\
sub Pick {\n\
local($mode,$name,$pipe) = @_;\n\
- $fh = $opened{$name};\n\
- if (!$fh) {\n\
- $fh = $opened{$name} = 'fh_' . ($nextfh++ + 0);\n\
- open($fh,$mode.$name.$pipe);\n\
- }\n\
+ $fh = $name;\n\
+ open($name,$mode.$name.$pipe) unless $opened{$name}++;\n\
}\n\
");
}
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,'"') )
+ if (!strchr(tmpstr->str_ptr,'\'') && !strchr(tmpstr->str_ptr,'"') &&
+ !strchr(tmp2str->str_ptr,'\'') && !strchr(tmp2str->str_ptr,'"') )
numeric |= 2;
}
if (numeric & 2) {
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;
if (useval)
str_cat(str,"(");
if (len > 0) {
- str_cat(str,"$");
str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
if (!*fstr->str_ptr) {
- str_cat(str,"_");
+ str_cat(str,"$_");
len = 2; /* a legal fiction */
}
str_free(fstr);
s = savestr(tokenbuf);
for (t = tokenbuf; *t; t++) {
*t &= 127;
+ if (islower(*t))
+ *t = toupper(*t);
if (!isalpha(*t) && !isdigit(*t))
*t = '_';
}
- if (!index(tokenbuf,'_'))
- strcpy(t,"_fh");
+ if (!strchr(tokenbuf,'_'))
+ strcpy(t,"_FH");
tmp3str = hfetch(symtab,tokenbuf);
if (!tmp3str) {
do_opens = TRUE;
break;
case OSPLIT:
str = str_new(0);
+ limit = ", 9999)";
numeric = 1;
tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
if (useval)
fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
i = fstr->str_ptr[1] & 127;
- if (index("*+?.[]()|^$\\",i))
+ if (strchr("*+?.[]()|^$\\",i))
sprintf(tokenbuf,"/\\%c/",i);
else if (i == ' ')
sprintf(tokenbuf,"' '");
}
else if (saw_FS)
str_cat(str,"$FS");
- else
+ else {
str_cat(str,"' '");
+ limit = ")";
+ }
str_cat(str,", ");
str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
str_free(fstr);
- str_cat(str,", 9999)");
+ str_cat(str,limit);
if (useval) {
str_cat(str,")");
}
s = savestr(tokenbuf);
for (t = tokenbuf; *t; t++) {
*t &= 127;
+ if (islower(*t))
+ *t = toupper(*t);
if (!isalpha(*t) && !isdigit(*t))
*t = '_';
}
- if (!index(tokenbuf,'_'))
- strcpy(t,"_fh");
+ if (!strchr(tokenbuf,'_'))
+ strcpy(t,"_FH");
str_free(tmpstr);
safefree(s);
str_set(str,"close ");
str_cat(str,tokenbuf);
}
else {
- sprintf(tokenbuf,"$fh = delete $opened{%s} && close($fh)",
- tmpstr->str_ptr);
+ sprintf(tokenbuf,"delete $opened{%s} && close(%s)",
+ tmpstr->str_ptr, tmpstr->str_ptr);
str_free(tmpstr);
str_set(str,tokenbuf);
}
s = savestr(tokenbuf);
for (t = tokenbuf; *t; t++) {
*t &= 127;
+ if (islower(*t))
+ *t = toupper(*t);
if (!isalpha(*t) && !isdigit(*t))
*t = '_';
}
- if (!index(tokenbuf,'_'))
- strcpy(t,"_fh");
+ if (!strchr(tokenbuf,'_'))
+ strcpy(t,"_FH");
tmp3str = hfetch(symtab,tokenbuf);
if (!tmp3str) {
str_cat(opens,"open(");
str_cat(str,"printf");
else
str_cat(str,"print");
+ saw_fh = 0;
if (len == 3 || do_fancy_opens) {
- if (*tokenbuf)
+ if (*tokenbuf) {
str_cat(str," ");
+ saw_fh = 1;
+ }
str_cat(str,tokenbuf);
}
tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
}
if (*tmpstr->str_ptr) {
str_cat(str," ");
- str_scat(str,tmpstr);
+ if (!saw_fh && *tmpstr->str_ptr == '(') {
+ str_cat(str,"(");
+ str_scat(str,tmpstr);
+ str_cat(str,")");
+ }
+ else
+ str_scat(str,tmpstr);
}
else {
str_cat(str," $_");
str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
str_free(fstr);
break;
+ case ODO:
+ str = str_new(0);
+ str_set(str,"do ");
+ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
+ str_free(fstr);
+ if (str->str_ptr[str->str_cur - 1] == '\n')
+ --str->str_cur;;
+ str_cat(str," while (");
+ str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
+ str_free(fstr);
+ str_cat(str,");");
+ break;
case OFOR:
str = str_new(0);
str_set(str,"for (");
}
str_cat(str,"; ");
fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
- if (i && (t = index(fstr->str_ptr,0377))) {
+ if (i && (t = strchr(fstr->str_ptr,0377))) {
if (strnEQ(fstr->str_ptr,s,i))
*t = ' ';
}
break;
case OFORIN:
tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
- d = index(tmpstr->str_ptr,'$');
+ d = strchr(tmpstr->str_ptr,'$');
if (!d)
fatal("Illegal for loop: %s",tmpstr->str_ptr);
- s = index(d,'{');
+ s = strchr(d,'{');
if (!s)
- s = index(d,'[');
+ s = strchr(d,'[');
if (!s)
fatal("Illegal for loop: %s",d);
*s++ = '\0';
return str;
}
-tab(str,lvl)
-register STR *str;
-register int lvl;
+static void
+tab(register STR *str, register int lvl)
{
while (lvl > 1) {
str_cat(str,"\t");
str_cat(str," ");
}
-fixtab(str,lvl)
-register STR *str;
-register int lvl;
+static void
+fixtab(register STR *str, register int lvl)
{
register char *s;
tab(str,lvl);
}
-addsemi(str)
-register STR *str;
+static void
+addsemi(register STR *str)
{
register char *s;
str_cat(str,";");
}
-emit_split(str,level)
-register STR *str;
-int level;
+static void
+emit_split(register STR *str, int level)
{
register int i;
tab(str,level);
}
-prewalk(numit,level,node,numericptr)
-int numit;
-int level;
-register int node;
-int *numericptr;
+int
+prewalk(int numit, int level, register int node, int *numericptr)
{
register int len;
register int type;
register int i;
- char *t;
- char *d, *s;
int numarg;
int numeric = FALSE;
STR *tmpstr;
prewalk(0,level,ops[node+2].ival,&numarg);
prewalk(0,level,ops[node+1].ival,&numarg);
prewalk(0,level,ops[node+3].ival,&numarg);
- if (numarg || strlen(ops[ops[node+1].ival+1].cval) > 1) {
+ if (numarg || strlen(ops[ops[node+1].ival+1].cval) > (Size_t)1) {
numericize(ops[node+2].ival);
if (!numarg)
numericize(ops[node+3].ival);
return 1;
}
-numericize(node)
-register int node;
+static void
+numericize(register int node)
{
register int len;
register int type;
- register int i;
STR *tmpstr;
STR *tmp2str;
int numarg;