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
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]
23 * Copyright (c) 1994, by Sun Microsytems, Inc.
26 #pragma ident "%Z%%M% %I% %E% SMI"
39 #include <sys/types.h>
40 #include <sys/param.h>
51 typedef struct source
{
66 #define PREXRC ".prexrc"
73 static queue_node_t stack
;
78 * source_init() - initializes the source stack
90 /* initialize the stack queue head */
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
;
99 new_p
->isatty
= isatty(fileno(new_p
->instream
));
101 (void) queue_prepend(&stack
, &new_p
->qn
);
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
);
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
);
124 } /* end source_init */
128 * source_file() - pushes a new source onto the stack
132 source_file(char *path
)
137 newfile
= fopen(path
, "r");
139 semantic_err(gettext("cannot open \"%s\""), path
);
142 new_p
= new(source_t
);
143 queue_init(&new_p
->qn
);
144 new_p
->path
= strdup(path
);
145 new_p
->instream
= newfile
;
147 new_p
->isatty
= isatty(fileno(new_p
->instream
));
149 (void) queue_prepend(&stack
, &new_p
->qn
);
152 } /* end source_file */
156 * source_input() - lexical analyzer input routine
159 extern void quit(boolean_t
, boolean_t
);
169 c
= getc(top
->instream
);
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 *
177 if (top
->instream
== stdin
) {
182 quit(B_TRUE
, B_TRUE
);
184 /* we've exhausted the current stream, pop it, delete it ... */
187 (void) fclose(top
->instream
);
188 (void) queue_remove(&top
->qn
);
191 /* point to the new top level i/o stream */
192 top
= (source_t
*) queue_next(&stack
, &stack
);
197 /* trigger a prompt if neccessary */
199 return (source_input());
203 } /* end source_input */
207 * source_unput() - lexical analyzer unput routine
214 (void) ungetc(c
, top
->instream
);
216 } /* end source_unput */
220 * source_output() - lexical analyzer output routine
226 (void) putc(c
, stdout
);
228 } /* end source_output */
232 * source_nl() - increment the line counter
241 } /* end source_nl */
248 extern char yytext
[];
249 extern int g_linenum
;
254 (void) fprintf(stderr
,
255 gettext("\"%s\", line %d: %s on or before \"%s\"\n"),
256 top
->path
, top
->linenum
, s
, yytext
);
277 extern char **g_argv
;
282 if (top
&& top
->isatty
)
283 (void) printf("%s> ", g_argv
[0]);
289 * semantic_err() - reports a semantic error
293 semantic_err(char *format
, ...)
297 va_start(ap
, format
);
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 */