]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/awk/main.c
merge default
[plan9front.git] / sys / src / cmd / awk / main.c
1 /****************************************************************
2 Copyright (C) Lucent Technologies 1997
3 All Rights Reserved
4
5 Permission to use, copy, modify, and distribute this software and
6 its documentation for any purpose and without fee is hereby
7 granted, provided that the above copyright notice appear in all
8 copies and that both that the copyright notice and this
9 permission notice and warranty disclaimer appear in supporting
10 documentation, and that the name Lucent Technologies or any of
11 its entities not be used in advertising or publicity pertaining
12 to distribution of the software without specific, written prior
13 permission.
14
15 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
17 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
18 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
20 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
22 THIS SOFTWARE.
23 ****************************************************************/
24
25 char    *version = "version 19990602";
26
27 #include <u.h>
28 #include <libc.h>
29 #include <bio.h>
30 #include "awk.h"
31 #include "y.tab.h"
32
33 extern  int     nfields;
34
35 Biobuf stdin;
36 Biobuf stdout;
37 Biobuf stderr;
38
39 int     dbg     = 0;
40 char    *cmdname;       /* gets argv[0] for error messages */
41 extern  Biobuf  *yyin;  /* lex input file */
42 char    *lexprog;       /* points to program argument if it exists */
43 extern  int errorflag;  /* non-zero if any syntax errors; set by yyerror */
44 int     compile_time = 2;       /* for error printing: */
45                                 /* 2 = cmdline, 1 = compile, 0 = running */
46
47 char    *pfile[20];     /* program filenames from -f's */
48 int     npfile = 0;     /* number of filenames */
49 int     curpfile = 0;   /* current filename */
50
51 int     safe    = 0;    /* 1 => "safe" mode */
52
53 void main(int argc, char *argv[])
54 {
55         char *fs = nil, *marg;
56         int temp;
57
58         Binit(&stdin, 0, OREAD);
59         Binit(&stdout, 1, OWRITE);
60         Binit(&stderr, 2, OWRITE);
61
62         cmdname = argv[0];
63         if (argc == 1) {
64                 Bprint(&stderr, "Usage: %s [-F fieldsep] [-mf n] [-mr n] [-v var=value] [-f programfile | 'program'] [file ...]\n", cmdname);
65                 exits("usage");
66         }
67
68         atnotify(handler, 1);
69         yyin = nil;
70         symtab = makesymtab(NSYMTAB);
71         while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
72                 if (strcmp(argv[1], "--") == 0) {       /* explicit end of args */
73                         argc--;
74                         argv++;
75                         break;
76                 }
77                 switch (argv[1][1]) {
78                 case 's':
79                         if (strcmp(argv[1], "-safe") == 0)
80                                 safe = 1;
81                         break;
82                 case 'f':       /* next argument is program filename */
83                         argc--;
84                         argv++;
85                         if (argc <= 1)
86                                 FATAL("no program filename");
87                         pfile[npfile++] = argv[1];
88                         break;
89                 case 'F':       /* set field separator */
90                         if (argv[1][2] != 0) {  /* arg is -Fsomething */
91                                 if (argv[1][2] == 't' && argv[1][3] == 0)       /* wart: t=>\t */
92                                         fs = "\t";
93                                 else if (argv[1][2] != 0)
94                                         fs = &argv[1][2];
95                         } else {                /* arg is -F something */
96                                 argc--; argv++;
97                                 if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)   /* wart: t=>\t */
98                                         fs = "\t";
99                                 else if (argc > 1 && argv[1][0] != 0)
100                                         fs = &argv[1][0];
101                         }
102                         if (fs == nil || *fs == '\0')
103                                 WARNING("field separator FS is empty");
104                         break;
105                 case 'v':       /* -v a=1 to be done NOW.  one -v for each */
106                         if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
107                                 setclvar(argv[1]);
108                         break;
109                 case 'm':       /* more memory: -mr=record, -mf=fields */
110                                 /* no longer needed */
111                         marg = argv[1];
112                         if (argv[1][3])
113                                 temp = atoi(&argv[1][3]);
114                         else {
115                                 argv++; argc--;
116                                 temp = atoi(&argv[1][0]);
117                         }
118                         switch (marg[2]) {
119                         case 'r':       recsize = temp; break;
120                         case 'f':       nfields = temp; break;
121                         default: FATAL("unknown option %s\n", marg);
122                         }
123                         break;
124                 case 'd':
125                         dbg = atoi(&argv[1][2]);
126                         if (dbg == 0)
127                                 dbg = 1;
128                         print("awk %s\n", version);
129                         break;
130                 case 'V':       /* added for exptools "standard" */
131                         print("awk %s\n", version);
132                         exits(0);
133                         break;
134                 default:
135                         WARNING("unknown option %s ignored", argv[1]);
136                         break;
137                 }
138                 argc--;
139                 argv++;
140         }
141         /* argv[1] is now the first argument */
142         if (npfile == 0) {      /* no -f; first argument is program */
143                 if (argc <= 1) {
144                         if (dbg)
145                                 exits(0);
146                         FATAL("no program given");
147                 }
148                    dprint( ("program = |%s|\n", argv[1]) );
149                 lexprog = argv[1];
150                 argc--;
151                 argv++;
152         }
153         recinit(recsize);
154         syminit();
155         compile_time = 1;
156         argv[0] = cmdname;      /* put prog name at front of arglist */
157            dprint( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
158         arginit(argc, argv);
159         yyparse();
160         if (fs)
161                 *FS = qstring(fs, '\0');
162            dprint( ("errorflag=%d\n", errorflag) );
163         if (errorflag == 0) {
164                 compile_time = 0;
165                 run(winner);
166         } else
167                 bracecheck();
168         if(errorflag)
169                 exits("error");
170         exits(0);
171 }
172
173 int pgetc(void)         /* get 1 character from awk program */
174 {
175         int c;
176
177         for (;;) {
178                 if (yyin == nil) {
179                         if (curpfile >= npfile)
180                                 return Beof;
181                         if (strcmp(pfile[curpfile], "-") == 0)
182                                 yyin = &stdin;
183                         else if ((yyin = Bopen(pfile[curpfile], OREAD)) == nil)
184                                 FATAL("can't open file %s", pfile[curpfile]);
185                         lineno = 1;
186                 }
187                 if ((c = Bgetc(yyin)) != Beof)
188                         return c;
189                 if (yyin != &stdin)
190                         Bterm(yyin);
191                 yyin = nil;
192                 curpfile++;
193         }
194 }
195
196 char *cursource(void)   /* current source file name */
197 {
198         if (npfile > 0)
199                 return pfile[curpfile];
200         else
201                 return nil;
202 }