Don't use undef value in Config::myconfig
[p5sagit/p5-mst-13.2.git] / x2p / walk.c
index 959527d..cb40073 100644 (file)
@@ -1,20 +1,16 @@
-/* $Header: walk.c,v 3.0 89/10/18 15:35:48 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 3.0  89/10/18  15:35:48  lwall
- * 3.0 baseline
- * 
  */
 
-#include "handy.h"
 #include "EXTERN.h"
-#include "util.h"
 #include "a2p.h"
+#include "util.h"
 
 bool exitval = FALSE;
 bool realexit = FALSE;
@@ -22,12 +18,24 @@ 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;
 
+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;
@@ -49,7 +57,6 @@ int minprec;                  /* minimum precedence without parens */
     int numeric = FALSE;
     STR *fstr;
     int prec = P_MAX;          /* assume no parens needed */
-    char *index();
 
     if (!node) {
        *numericptr = 0;
@@ -60,6 +67,20 @@ int minprec;                 /* minimum precedence without parens */
     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);
@@ -78,7 +99,7 @@ int minprec;                  /* minimum precedence without parens */
            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);
@@ -115,20 +136,6 @@ int minprec;                       /* minimum precedence without parens */
                str_cat(str,"chop;\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);
@@ -138,8 +145,8 @@ int minprec;                        /* minimum precedence without parens */
            if (saw_FNR)
                str_cat(str,"continue {\n    $FNRbase = $. if eof;\n}\n");
        }
-       else
-           str_cat(str,"# (no line actions)\n");
+       else if (old_awk)
+           str_cat(str,"while (<>) { }         # (no line actions)\n");
        if (ops[node+4].ival) {
            realexit = TRUE;
            str_cat(str,"\n");
@@ -149,7 +156,7 @@ int minprec;                        /* minimum precedence without parens */
            str_cat(str,"\n");
        }
        if (exitval)
-           str_cat(str,"exit ExitValue;\n");
+           str_cat(str,"exit $ExitValue;\n");
        if (subs->str_ptr) {
            str_cat(str,"\n");
            str_scat(str,subs);
@@ -170,7 +177,7 @@ int minprec;                        /* minimum precedence without parens */
                            str_cat(str,"    $FNRbase = $. if eof;\n");
                    }
                    if (len & 1)
-                       str_cat(str,"    local($_)\n");
+                       str_cat(str,"    local($_);\n");
                    if (len & 2)
                        str_cat(str,
                          "    if ($getline_ok = (($_ = <$fh>) ne ''))");
@@ -202,11 +209,8 @@ int minprec;                       /* minimum precedence without parens */
            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\
 ");
        }
@@ -315,6 +319,16 @@ sub Pick {\n\
        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,"(");
@@ -373,8 +387,8 @@ sub Pick {\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) {
@@ -449,6 +463,8 @@ sub Pick {\n\
        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;
@@ -551,10 +567,9 @@ sub Pick {\n\
        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);
@@ -574,11 +589,13 @@ sub Pick {\n\
                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;
@@ -653,6 +670,7 @@ sub Pick {\n\
        break;
     case OSPLIT:
        str = str_new(0);
+       limit = ", 9999)";
        numeric = 1;
        tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
        if (useval)
@@ -665,8 +683,10 @@ sub Pick {\n\
            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
                    sprintf(tokenbuf,"/%c/",i);
                str_cat(str,tokenbuf);
@@ -681,12 +701,14 @@ sub Pick {\n\
        }
        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,", 999)");
+       str_cat(str,limit);
        if (useval) {
            str_cat(str,")");
        }
@@ -906,7 +928,7 @@ sub Pick {\n\
                s = "\"";
                *d++ = *t++ + 128;
                switch (*t) {
-               case '\\': case '"': case 'n': case 't':
+               case '\\': case '"': case 'n': case 't': case '$':
                    break;
                default:        /* hide this from perl */
                    *d++ = '\\' + 128;
@@ -1098,19 +1120,21 @@ sub Pick {\n\
            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);
        }
@@ -1133,11 +1157,13 @@ sub Pick {\n\
                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(");
@@ -1183,9 +1209,12 @@ sub Pick {\n\
            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);
@@ -1212,7 +1241,13 @@ sub Pick {\n\
        }
        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," $_");
@@ -1258,7 +1293,7 @@ sub Pick {\n\
            tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
        else
            tmpstr = str_new(0);;
-       if (!*tmpstr->str_ptr) {
+       if (!tmpstr->str_ptr || !*tmpstr->str_ptr) {
            if (lval_field) {
                t = saw_OFS ? "$," : "' '";
                if (split_to_array) {
@@ -1318,7 +1353,7 @@ sub Pick {\n\
        }
        else {
            if (len == 1) {
-               str_set(str,"ExitValue = ");
+               str_set(str,"$ExitValue = ");
                exitval = TRUE;
                str_scat(str,
                  fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
@@ -1376,6 +1411,18 @@ sub Pick {\n\
        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 (");
@@ -1391,7 +1438,7 @@ sub Pick {\n\
        }
        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 = ' ';
        }
@@ -1407,19 +1454,21 @@ sub Pick {\n\
        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';
-       t = index(s,'}' + 128);
-       if (!t)
-           t = index(s,']' + 128);
-       if (t)
+       for (t = s; i = *t; t++) {
+           i &= 127;
+           if (i == '}' || i == ']')
+               break;
+       }
+       if (*t)
            *t = '\0';
        str = str_new(0);
        str_set(str,d+1);
@@ -1427,7 +1476,7 @@ sub Pick {\n\
        tmp2str = hfetch(symtab,str->str_ptr);
        if (tmp2str && atoi(tmp2str->str_ptr)) {
            sprintf(tokenbuf,
-             "foreach %s (@%s) ",
+             "foreach %s ($[ .. $#%s) ",
              s,
              d+1);
        }
@@ -1506,6 +1555,7 @@ sub Pick {\n\
     return str;
 }
 
+static void
 tab(str,lvl)
 register STR *str;
 register int lvl;
@@ -1518,6 +1568,7 @@ register int lvl;
        str_cat(str,"    ");
 }
 
+static void
 fixtab(str,lvl)
 register STR *str;
 register int lvl;
@@ -1537,6 +1588,7 @@ register int lvl;
     tab(str,lvl);
 }
 
+static void
 addsemi(str)
 register STR *str;
 {
@@ -1549,6 +1601,7 @@ register STR *str;
        str_cat(str,";");
 }
 
+static void
 emit_split(str,level)
 register STR *str;
 int level;
@@ -1573,16 +1626,17 @@ int level;
        str_cat(str,tokenbuf);
     }
     if (const_FS) {
-       sprintf(tokenbuf," = split(/[%c\\n]/, $_, 999);\n",const_FS);
+       sprintf(tokenbuf," = split(/[%c\\n]/, $_, 9999);\n",const_FS);
        str_cat(str,tokenbuf);
     }
     else if (saw_FS)
-       str_cat(str," = split($FS, $_, 999);\n");
+       str_cat(str," = split($FS, $_, 9999);\n");
     else
-       str_cat(str," = split(' ', $_, 999);\n");
+       str_cat(str," = split(' ', $_, 9999);\n");
     tab(str,level);
 }
 
+int
 prewalk(numit,level,node,numericptr)
 int numit;
 int level;
@@ -1592,8 +1646,6 @@ int *numericptr;
     register int len;
     register int type;
     register int i;
-    char *t;
-    char *d, *s;
     int numarg;
     int numeric = FALSE;
     STR *tmpstr;
@@ -1713,7 +1765,7 @@ int *numericptr;
        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);
@@ -1836,7 +1888,7 @@ int *numericptr;
     case OUSERFUN:
        tmp2str = str_new(0);
        str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
-       fixrargs(tmpstr->str_ptr,ops[node+2],0);
+       fixrargs(tmpstr->str_ptr,ops[node+2].ival,0);
        str_free(tmpstr);
        str_cat(tmp2str,"(");
        tmpstr = hfetch(symtab,tmp2str->str_ptr);
@@ -2005,12 +2057,12 @@ int *numericptr;
     return 1;
 }
 
+static void
 numericize(node)
 register int node;
 {
     register int len;
     register int type;
-    register int i;
     STR *tmpstr;
     STR *tmp2str;
     int numarg;