]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/awk/main.c
ip/cifsd: dont return garbage in upper 32 bit of unix extension stat fields
[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 int     compile_time = 2;       /* for error printing: */
44                                 /* 2 = cmdline, 1 = compile, 0 = running */
45
46 char    *pfile[20];     /* program filenames from -f's */
47 int     npfile = 0;     /* number of filenames */
48 int     curpfile = 0;   /* current filename */
49
50 int     safe    = 0;    /* 1 => "safe" mode */
51
52 void main(int argc, char *argv[])
53 {
54         char *fs = nil, *marg;
55         int temp;
56
57         setfcr(getfcr() & ~FPINVAL);
58
59         Binit(&stdin, 0, OREAD);
60         Binit(&stdout, 1, OWRITE);
61         Binit(&stderr, 2, OWRITE);
62
63         cmdname = argv[0];
64         if (argc == 1) {
65                 Bprint(&stderr, "Usage: %s [-F fieldsep] [-mf n] [-mr n] [-v var=value] [-f programfile | 'program'] [file ...]\n", cmdname);
66                 exits("usage");
67         }
68
69         atnotify(handler, 1);
70         yyin = nil;
71         symtab = makesymtab(NSYMTAB);
72         while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
73                 if (strcmp(argv[1], "--") == 0) {       /* explicit end of args */
74                         argc--;
75                         argv++;
76                         break;
77                 }
78                 switch (argv[1][1]) {
79                 case 's':
80                         if (strcmp(argv[1], "-safe") == 0)
81                                 safe = 1;
82                         break;
83                 case 'f':       /* next argument is program filename */
84                         argc--;
85                         argv++;
86                         if (argc <= 1)
87                                 FATAL("no program filename");
88                         pfile[npfile++] = argv[1];
89                         break;
90                 case 'F':       /* set field separator */
91                         if (argv[1][2] != 0) {  /* arg is -Fsomething */
92                                 if (argv[1][2] == 't' && argv[1][3] == 0)       /* wart: t=>\t */
93                                         fs = "\t";
94                                 else if (argv[1][2] != 0)
95                                         fs = &argv[1][2];
96                         } else {                /* arg is -F something */
97                                 argc--; argv++;
98                                 if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)   /* wart: t=>\t */
99                                         fs = "\t";
100                                 else if (argc > 1 && argv[1][0] != 0)
101                                         fs = &argv[1][0];
102                         }
103                         if (fs == nil || *fs == '\0')
104                                 WARNING("field separator FS is empty");
105                         break;
106                 case 'v':       /* -v a=1 to be done NOW.  one -v for each */
107                         if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
108                                 setclvar(argv[1]);
109                         break;
110                 case 'm':       /* more memory: -mr=record, -mf=fields */
111                                 /* no longer needed */
112                         marg = argv[1];
113                         if (argv[1][3])
114                                 temp = atoi(&argv[1][3]);
115                         else {
116                                 argv++; argc--;
117                                 temp = atoi(&argv[1][0]);
118                         }
119                         switch (marg[2]) {
120                         case 'r':       recsize = temp; break;
121                         case 'f':       nfields = temp; break;
122                         default: FATAL("unknown option %s\n", marg);
123                         }
124                         break;
125                 case 'd':
126                         dbg = atoi(&argv[1][2]);
127                         if (dbg == 0)
128                                 dbg = 1;
129                         print("awk %s\n", version);
130                         break;
131                 case 'V':       /* added for exptools "standard" */
132                         print("awk %s\n", version);
133                         exits(0);
134                         break;
135                 default:
136                         WARNING("unknown option %s ignored", argv[1]);
137                         break;
138                 }
139                 argc--;
140                 argv++;
141         }
142         /* argv[1] is now the first argument */
143         if (npfile == 0) {      /* no -f; first argument is program */
144                 if (argc <= 1) {
145                         if (dbg)
146                                 exits(0);
147                         FATAL("no program given");
148                 }
149                    dprint( ("program = |%s|\n", argv[1]) );
150                 lexprog = argv[1];
151                 argc--;
152                 argv++;
153         }
154         recinit(recsize);
155         syminit();
156         compile_time = 1;
157         argv[0] = cmdname;      /* put prog name at front of arglist */
158            dprint( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
159         arginit(argc, argv);
160         yyparse();
161         if (fs)
162                 *FS = qstring(fs, '\0');
163            dprint( ("exitstatus=%s\n", exitstatus) );
164         if (exitstatus == nil) {
165                 compile_time = 0;
166                 run(winner);
167         } else
168                 bracecheck();
169         exits(exitstatus);
170 }
171
172 int pgetc(void)         /* get 1 character from awk program */
173 {
174         int c;
175
176         for (;;) {
177                 if (yyin == nil) {
178                         if (curpfile >= npfile)
179                                 return Beof;
180                         if (strcmp(pfile[curpfile], "-") == 0)
181                                 yyin = &stdin;
182                         else if ((yyin = Bopen(pfile[curpfile], OREAD)) == nil)
183                                 FATAL("can't open file %s", pfile[curpfile]);
184                         lineno = 1;
185                 }
186                 if ((c = Bgetc(yyin)) != Beof)
187                         return c;
188                 if (yyin != &stdin)
189                         Bterm(yyin);
190                 yyin = nil;
191                 curpfile++;
192         }
193 }
194
195 char *cursource(void)   /* current source file name */
196 {
197         if (npfile > 0)
198                 return pfile[curpfile];
199         else
200                 return nil;
201 }