8354 sync regcomp(3C) with upstream (fix make catalog)
[unleashed/tickless.git] / usr / src / cmd / tnf / prex / source.c
blob140c2bcecdafa8708f99b6da447e2f5958d57c01
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright (c) 1994, by Sun Microsytems, Inc.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 * Includes
32 #include <unistd.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <stdarg.h>
36 #include <string.h>
37 #include <libintl.h>
38 #include <sys/stat.h>
39 #include <sys/types.h>
40 #include <sys/param.h>
42 #include "new.h"
43 #include "queue.h"
44 #include "source.h"
48 * Typedefs
51 typedef struct source {
52 queue_node_t qn;
53 char *path;
54 FILE *instream;
55 int linenum;
56 boolean_t isatty;
58 } source_t;
62 * Defines
65 #define HOME "HOME"
66 #define PREXRC ".prexrc"
70 * Globals
73 static queue_node_t stack;
74 static source_t *top;
78 * source_init() - initializes the source stack
81 void
82 source_init(void)
84 source_t *new_p;
85 struct stat statbuf;
86 char *home;
87 int retval;
90 /* initialize the stack queue head */
91 queue_init(&stack);
93 /* stick the standard input on the bottom of the stack */
94 new_p = new(source_t);
95 queue_init(&new_p->qn);
96 new_p->path = strdup("<STDIN>");
97 new_p->instream = stdin;
98 new_p->linenum = 1;
99 new_p->isatty = isatty(fileno(new_p->instream));
101 (void) queue_prepend(&stack, &new_p->qn);
102 top = new_p;
105 * since we are pushing onto a stack, we invert the search order *
106 * and push the prexrc in the current directory on next.
108 retval = stat(PREXRC, &statbuf);
109 if (retval != -1) {
110 source_file(PREXRC);
112 home = getenv(HOME);
113 if (home) {
114 char path[MAXPATHLEN];
116 if ((strlen(home) + strlen(PREXRC) + 2) < (size_t) MAXPATHLEN) {
117 (void) sprintf(path, "%s/%s", home, PREXRC);
118 retval = stat(path, &statbuf);
119 if (retval != -1) {
120 source_file(path);
124 } /* end source_init */
128 * source_file() - pushes a new source onto the stack
131 void
132 source_file(char *path)
134 FILE *newfile;
135 source_t *new_p;
137 newfile = fopen(path, "r");
138 if (!newfile) {
139 semantic_err(gettext("cannot open \"%s\""), path);
140 return;
142 new_p = new(source_t);
143 queue_init(&new_p->qn);
144 new_p->path = strdup(path);
145 new_p->instream = newfile;
146 new_p->linenum = 1;
147 new_p->isatty = isatty(fileno(new_p->instream));
149 (void) queue_prepend(&stack, &new_p->qn);
150 top = new_p;
152 } /* end source_file */
156 * source_input() - lexical analyzer input routine
159 extern void quit(boolean_t, boolean_t);
162 source_input(void)
164 int c;
166 if (!top)
167 return (0);
169 c = getc(top->instream);
171 if (c == EOF) {
173 * If we get an EOF at the top level, we quit if we are *
174 * non-interactive, pretend we saw a new-line if we are *
175 * interactive.
177 if (top->instream == stdin) {
178 if (top->isatty) {
179 source_output('\n');
180 return ('\n');
181 } else
182 quit(B_TRUE, B_TRUE);
184 /* we've exhausted the current stream, pop it, delete it ... */
185 if (top->path)
186 free(top->path);
187 (void) fclose(top->instream);
188 (void) queue_remove(&top->qn);
189 free(top);
191 /* point to the new top level i/o stream */
192 top = (source_t *) queue_next(&stack, &stack);
194 if (!top)
195 return (0);
197 /* trigger a prompt if neccessary */
198 prompt();
199 return (source_input());
201 return (c);
203 } /* end source_input */
207 * source_unput() - lexical analyzer unput routine
210 void
211 source_unput(int c)
213 if (top)
214 (void) ungetc(c, top->instream);
216 } /* end source_unput */
220 * source_output() - lexical analyzer output routine
223 void
224 source_output(int c)
226 (void) putc(c, stdout);
228 } /* end source_output */
232 * source_nl() - increment the line counter
235 void
236 source_nl(void)
238 if (top)
239 top->linenum++;
241 } /* end source_nl */
245 * yyerror() -
248 extern char yytext[];
249 extern int g_linenum;
251 void
252 yyerror(char *s)
254 (void) fprintf(stderr,
255 gettext("\"%s\", line %d: %s on or before \"%s\"\n"),
256 top->path, top->linenum, s, yytext);
262 * yywrap() -
266 yywrap()
268 return (1);
270 } /* end yywrap */
274 * prompt() -
277 extern char **g_argv;
279 void
280 prompt(void)
282 if (top && top->isatty)
283 (void) printf("%s> ", g_argv[0]);
285 } /* end g_prompt */
289 * semantic_err() - reports a semantic error
292 void
293 semantic_err(char *format, ...)
295 va_list ap;
297 va_start(ap, format);
299 if (!top)
300 return;
302 (void) fprintf(stderr, gettext("\"%s\", line %d: semantic error: "),
303 top->path, top->linenum);
304 (void) vfprintf(stderr, format, ap);
305 (void) fprintf(stderr, gettext("\n"));
307 } /* end semantic_err */