Pod typos, pod2man bugs, and miscellaneous installation comments
[p5sagit/p5-mst-13.2.git] / x2p / walk.c
index 555e13c..403d686 100644 (file)
@@ -1,40 +1,16 @@
-/* $Header: walk.c,v 3.0.1.6 90/10/16 11:35:51 lwall Locked $
+/* $RCSfile: walk.c,v $$Revision: 4.1 $$Date: 92/08/07 18:29:31 $
  *
- *    Copyright (c) 1989, Larry Wall
+ *    Copyright (c) 1991, 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.1.6  90/10/16  11:35:51  lwall
- * patch29: a2p mistranslated certain weird field separators
- * 
- * Revision 3.0.1.5  90/08/09  05:55:01  lwall
- * patch19: a2p emited local($_) without a semicolon
- * patch19: a2p didn't make explicit split on whitespace skip leading whitespace
- * patch19: foreach on a normal array was iterating on values instead of indexes
- * 
- * Revision 3.0.1.4  90/03/01  10:32:45  lwall
- * patch9: a2p didn't put a $ on ExitValue
- * 
- * Revision 3.0.1.3  89/12/21  20:32:35  lwall
- * patch7: in a2p, user-defined functions didn't work on some machines
- * 
- * Revision 3.0.1.2  89/11/17  15:53:00  lwall
- * patch5: on Pyramids, index(s, '}' + 128) doesn't find meta-}
- * 
- * Revision 3.0.1.1  89/11/11  05:09:33  lwall
- * patch2: in a2p, awk script with no line actions still needs main loop
- * 
- * 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;
@@ -42,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;
@@ -69,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;
@@ -80,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);
@@ -98,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);
@@ -135,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);
@@ -222,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\
 ");
        }
@@ -403,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) {
@@ -479,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;
@@ -581,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);
@@ -604,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;
@@ -683,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)
@@ -695,7 +683,7 @@ 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,"' '");
@@ -713,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,", 9999)");
+       str_cat(str,limit);
        if (useval) {
            str_cat(str,")");
        }
@@ -938,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;
@@ -1130,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);
        }
@@ -1165,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(");
@@ -1215,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);
@@ -1244,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," $_");
@@ -1290,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) {
@@ -1408,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 (");
@@ -1423,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 = ' ';
        }
@@ -1439,12 +1454,12 @@ 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';
@@ -1540,6 +1555,7 @@ sub Pick {\n\
     return str;
 }
 
+static void
 tab(str,lvl)
 register STR *str;
 register int lvl;
@@ -1552,6 +1568,7 @@ register int lvl;
        str_cat(str,"    ");
 }
 
+static void
 fixtab(str,lvl)
 register STR *str;
 register int lvl;
@@ -1571,6 +1588,7 @@ register int lvl;
     tab(str,lvl);
 }
 
+static void
 addsemi(str)
 register STR *str;
 {
@@ -1583,6 +1601,7 @@ register STR *str;
        str_cat(str,";");
 }
 
+static void
 emit_split(str,level)
 register STR *str;
 int level;
@@ -1617,6 +1636,7 @@ int level;
     tab(str,level);
 }
 
+int
 prewalk(numit,level,node,numericptr)
 int numit;
 int level;
@@ -1626,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;
@@ -1747,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);
@@ -2039,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;