xref: /freebsd/contrib/one-true-awk/main.c (revision 6780ab54325a71e7e70112b11657973edde8655e)
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 const char	*version = "version 20021213";
26 
27 #define DEBUG
28 #include <stdio.h>
29 #include <ctype.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <signal.h>
33 #include "awk.h"
34 #include "ytab.h"
35 
36 extern	char	**environ;
37 extern	int	nfields;
38 
39 int	dbg	= 0;
40 char	*cmdname;	/* gets argv[0] for error messages */
41 extern	FILE	*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 int main(int argc, char *argv[])
54 {
55 	const char *fs = NULL;
56 
57 	cmdname = argv[0];
58 	if (argc == 1) {
59 		fprintf(stderr, "Usage: %s [-f programfile | 'program'] [-Ffieldsep] [-v var=value] [files]\n", cmdname);
60 		exit(1);
61 	}
62 	signal(SIGFPE, fpecatch);
63 	yyin = NULL;
64 	symtab = makesymtab(NSYMTAB);
65 	while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
66 		if (strcmp(argv[1], "--") == 0) {	/* explicit end of args */
67 			argc--;
68 			argv++;
69 			break;
70 		}
71 		switch (argv[1][1]) {
72 		case 's':
73 			if (strcmp(argv[1], "-safe") == 0)
74 				safe = 1;
75 			break;
76 		case 'f':	/* next argument is program filename */
77 			argc--;
78 			argv++;
79 			if (argc <= 1)
80 				FATAL("no program filename");
81 			pfile[npfile++] = argv[1];
82 			break;
83 		case 'F':	/* set field separator */
84 			if (argv[1][2] != 0) {	/* arg is -Fsomething */
85 				if (argv[1][2] == 't' && argv[1][3] == 0)	/* wart: t=>\t */
86 					fs = "\t";
87 				else if (argv[1][2] != 0)
88 					fs = &argv[1][2];
89 			} else {		/* arg is -F something */
90 				argc--; argv++;
91 				if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)	/* wart: t=>\t */
92 					fs = "\t";
93 				else if (argc > 1 && argv[1][0] != 0)
94 					fs = &argv[1][0];
95 			}
96 			if (fs == NULL || *fs == '\0')
97 				WARNING("field separator FS is empty");
98 			break;
99 		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
100 			if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
101 				setclvar(argv[1]);
102 			break;
103 		case 'm':	/* more memory: -mr=record, -mf=fields */
104 				/* no longer supported */
105 			WARNING("obsolete option %s ignored", argv[1]);
106 			break;
107 		case 'd':
108 			dbg = atoi(&argv[1][2]);
109 			if (dbg == 0)
110 				dbg = 1;
111 			printf("awk %s\n", version);
112 			break;
113 		case 'V':	/* added for exptools "standard" */
114 			printf("awk %s\n", version);
115 			exit(0);
116 			break;
117 		default:
118 			WARNING("unknown option %s ignored", argv[1]);
119 			break;
120 		}
121 		argc--;
122 		argv++;
123 	}
124 	/* argv[1] is now the first argument */
125 	if (npfile == 0) {	/* no -f; first argument is program */
126 		if (argc <= 1) {
127 			if (dbg)
128 				exit(0);
129 			FATAL("no program given");
130 		}
131 		   dprintf( ("program = |%s|\n", argv[1]) );
132 		lexprog = argv[1];
133 		argc--;
134 		argv++;
135 	}
136 	recinit(recsize);
137 	syminit();
138 	compile_time = 1;
139 	argv[0] = cmdname;	/* put prog name at front of arglist */
140 	   dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
141 	arginit(argc, argv);
142 	if (!safe)
143 		envinit(environ);
144 	yyparse();
145 	if (fs)
146 		*FS = qstring(fs, '\0');
147 	   dprintf( ("errorflag=%d\n", errorflag) );
148 	if (errorflag == 0) {
149 		compile_time = 0;
150 		run(winner);
151 	} else
152 		bracecheck();
153 	return(errorflag);
154 }
155 
156 int pgetc(void)		/* get 1 character from awk program */
157 {
158 	int c;
159 
160 	for (;;) {
161 		if (yyin == NULL) {
162 			if (curpfile >= npfile)
163 				return EOF;
164 			if (strcmp(pfile[curpfile], "-") == 0)
165 				yyin = stdin;
166 			else if ((yyin = fopen(pfile[curpfile], "r")) == NULL)
167 				FATAL("can't open file %s", pfile[curpfile]);
168 			lineno = 1;
169 		}
170 		if ((c = getc(yyin)) != EOF)
171 			return c;
172 		if (yyin != stdin)
173 			fclose(yyin);
174 		yyin = NULL;
175 		curpfile++;
176 	}
177 }
178 
179 char *cursource(void)	/* current source file name */
180 {
181 	if (npfile > 0)
182 		return pfile[curpfile];
183 	else
184 		return NULL;
185 }
186