Print this page
3731 Update nawk to version 20121220

@@ -22,42 +22,65 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-/*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/*        All Rights Reserved   */
+/*
+ * Copyright (C) Lucent Technologies 1997
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice appear in all
+ * copies and that both that the copyright notice and this
+ * permission notice and warranty disclaimer appear in supporting
+ * documentation, and that the name Lucent Technologies or any of
+ * its entities not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.
+ *
+ * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+ * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
 
-#include <stdio.h>
-#include <ctype.h>
 #include <signal.h>
 #include <locale.h>
-#include <libintl.h>
 #include <stdarg.h>
 #include <errno.h>
 #include <values.h>
 #include <langinfo.h>
 #include "awk.h"
 #include "y.tab.h"
 
-char    *version = "version Oct 11, 1989";
+char    *version = "version 20121220";
 
 int     dbg     = 0;
+Awkfloat        srand_seed = 1;
 uchar   *cmdname;       /* gets argv[0] for error messages */
 uchar   *lexprog;       /* points to program argument if it exists */
 int     compile_time = 2;       /* for error printing: */
                                 /* 2 = cmdline, 1 = compile, 0 = running */
 char    radixpoint = '.';
 
-static uchar    **pfile = NULL; /* program filenames from -f's */
+#define MAX_PFILE       20      /* max number of -f's */
+
+static uchar    *pfile[MAX_PFILE];      /* program filenames from -f's */
 static int      npfile = 0;     /* number of filenames */
 static int      curpfile = 0;   /* current filename */
 
+int     safe = 0;       /* 1 => "safe" mode */
+
 int
 main(int argc, char *argv[], char *envp[])
 {
-        uchar *fs = NULL;
+        const uchar *fs = NULL;
         char    *nl_radix;
         /*
          * At this point, numbers are still scanned as in
          * the POSIX locale.
          * (POSIX.2, volume 2, P867, L4742-4757)

@@ -74,85 +97,117 @@
                     "Usage: %s [-f programfile | 'program'] [-Ffieldsep] "
                     "[-v var=value] [files]\n"), cmdname);
                 exit(1);
         }
         (void) signal(SIGFPE, fpecatch);
+
+        srand_seed = 1;
+        srand((unsigned int)srand_seed);
+
         yyin = NULL;
-        syminit();
+        symtab = makesymtab(NSYMTAB/NSYMTAB);
         while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
-                if (strcmp(argv[1], "--") == 0) {
+                if (strcmp(argv[1], "-version") == 0 ||
+                    strcmp(argv[1], "--version") == 0) {
+                        (void) printf("awk %s\n", version);
+                        exit(0);
+                        break;
+                }
+                if (strncmp(argv[1], "--", 2) == 0) {
                         /* explicit end of args */
                         argc--;
                         argv++;
                         break;
                 }
                 switch (argv[1][1]) {
+                case 's':
+                        if (strcmp(argv[1], "-safe") == 0)
+                                safe = 1;
+                        break;
                 case 'f':       /* next argument is program filename */
-                        argc--;
-                        argv++;
+                        if (argv[1][2] != 0) {  /* arg is -fsomething */
+                                if (npfile >= MAX_PFILE - 1)
+                                        FATAL("too many -f options");
+                                pfile[npfile++] = (uchar *)&argv[1][2];
+                        } else {                /* arg is -f something */
+                                argc--; argv++;
                         if (argc <= 1)
-                                ERROR "no program filename" FATAL;
-                        pfile = realloc(pfile, sizeof (uchar *) * (npfile + 1));
-                        if (pfile == NULL)
-                                ERROR "out of space in main" FATAL;
+                                        FATAL("no program filename");
+                                if (npfile >= MAX_PFILE - 1)
+                                        FATAL("too many -f options");
                         pfile[npfile++] = (uchar *)argv[1];
+                        }
                         break;
                 case 'F':       /* set field separator */
                         if (argv[1][2] != 0) {  /* arg is -Fsomething */
                                 /* wart: t=>\t */
                                 if (argv[1][2] == 't' && argv[1][3] == 0)
                                         fs = (uchar *) "\t";
                                 else if (argv[1][2] != 0)
                                         fs = (uchar *)&argv[1][2];
                         } else {                /* arg is -F something */
                                 argc--; argv++;
-                                if (argc > 1) {
                                         /* wart: t=>\t */
-                                        if (argv[1][0] == 't' &&
+                                if (argc > 1 && argv[1][0] == 't' &&
                                             argv[1][1] == 0)
                                                 fs = (uchar *) "\t";
-                                        else if (argv[1][0] != 0)
+                                else if (argc > 1 && argv[1][0] != 0)
                                                 fs = (uchar *)&argv[1][0];
                                 }
-                        }
                         if (fs == NULL || *fs == '\0')
-                                ERROR "field separator FS is empty" WARNING;
+                                WARNING("field separator FS is empty");
                         break;
                 case 'v':       /* -v a=1 to be done NOW.  one -v for each */
-                        if (argv[1][2] == '\0' && --argc > 1 &&
-                            isclvar((uchar *)(++argv)[1]))
+                        if (argv[1][2] != 0) {  /* arg is -vsomething */
+                                if (isclvar((uchar *)&argv[1][2]))
+                                        setclvar((uchar *)&argv[1][2]);
+                                else
+                                        FATAL(
+                                "invalid -v option argument: %s", &argv[1][2]);
+                        } else {        /* arg is -v something */
+                                argc--; argv++;
+                                if (argc <= 1)
+                                        FATAL("no variable name");
+                                if (isclvar((uchar *)argv[1]))
                                 setclvar((uchar *)argv[1]);
+                                else
+                                        FATAL(
+                                "invalid -v option argument: %s", argv[1]);
+                        }
                         break;
                 case 'd':
                         dbg = atoi(&argv[1][2]);
                         if (dbg == 0)
                                 dbg = 1;
                         (void) printf("awk %s\n", version);
                         break;
                 default:
-                        ERROR "unknown option %s ignored", argv[1] WARNING;
+                        WARNING("unknown option %s ignored", argv[1]);
                         break;
                 }
                 argc--;
                 argv++;
         }
         /* argv[1] is now the first argument */
         if (npfile == 0) {      /* no -f; first argument is program */
                 if (argc <= 1) {
                         if (dbg)
                                 exit(0);
-                        ERROR "no program given" FATAL;
+                        FATAL("no program given");
                 }
                 dprintf(("program = |%s|\n", argv[1]));
                 lexprog = (uchar *)argv[1];
                 argc--;
                 argv++;
         }
+        recinit(record_size);
+        syminit();
         compile_time = 1;
         argv[0] = (char *)cmdname;      /* put prog name at front of arglist */
         dprintf(("argc=%d, argv[0]=%s\n", argc, argv[0]));
         arginit(argc, (uchar **)argv);
+        if (!safe)
         envinit((uchar **)envp);
         (void) yyparse();
         if (fs)
                 *FS = qstring(fs, '\0');
         dprintf(("errorflag=%d\n", errorflag));

@@ -171,27 +226,37 @@
                 bracecheck();
         return (errorflag);
 }
 
 int
-pgetc(void)             /* get program character */
+pgetc(void)             /* get 1 character from awk program */
 {
         int c;
 
         for (;;) {
                 if (yyin == NULL) {
                         if (curpfile >= npfile)
                                 return (EOF);
-                        yyin = (strcmp((char *)pfile[curpfile], "-") == 0) ?
-                            stdin : fopen((char *)pfile[curpfile], "r");
-                        if (yyin == NULL) {
-                                ERROR "can't open file %s",
-                                    pfile[curpfile] FATAL;
-                        }
+                        if (strcmp((char *)pfile[curpfile], "-") == 0)
+                                yyin = stdin;
+                        else if ((yyin = fopen(
+                            (char *)pfile[curpfile], "r")) == NULL)
+                                FATAL("can't open file %s", pfile[curpfile]);
+                        lineno = 1;
                 }
                 if ((c = getc(yyin)) != EOF)
                         return (c);
+                if (yyin != stdin)
                 (void) fclose(yyin);
                 yyin = NULL;
                 curpfile++;
         }
 }
+
+uchar *
+cursource(void)         /* current source file name */
+{
+        if (npfile > 0)
+                return (pfile[curpfile]);
+        else
+                return (NULL);
+}