1*86d7f5d3SJohn Marino /* lexical analysis of RCS files */
2*86d7f5d3SJohn Marino
3*86d7f5d3SJohn Marino /******************************************************************************
4*86d7f5d3SJohn Marino * Lexical Analysis.
5*86d7f5d3SJohn Marino * hashtable, Lexinit, nextlex, getlex, getkey,
6*86d7f5d3SJohn Marino * getid, getnum, readstring, printstring, savestring,
7*86d7f5d3SJohn Marino * checkid, fatserror, error, faterror, warn, diagnose
8*86d7f5d3SJohn Marino * Testprogram: define LEXDB
9*86d7f5d3SJohn Marino ******************************************************************************
10*86d7f5d3SJohn Marino */
11*86d7f5d3SJohn Marino
12*86d7f5d3SJohn Marino /* Copyright 1982, 1988, 1989 Walter Tichy
13*86d7f5d3SJohn Marino Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
14*86d7f5d3SJohn Marino Distributed under license by the Free Software Foundation, Inc.
15*86d7f5d3SJohn Marino
16*86d7f5d3SJohn Marino This file is part of RCS.
17*86d7f5d3SJohn Marino
18*86d7f5d3SJohn Marino RCS is free software; you can redistribute it and/or modify
19*86d7f5d3SJohn Marino it under the terms of the GNU General Public License as published by
20*86d7f5d3SJohn Marino the Free Software Foundation; either version 2, or (at your option)
21*86d7f5d3SJohn Marino any later version.
22*86d7f5d3SJohn Marino
23*86d7f5d3SJohn Marino RCS is distributed in the hope that it will be useful,
24*86d7f5d3SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
25*86d7f5d3SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26*86d7f5d3SJohn Marino GNU General Public License for more details.
27*86d7f5d3SJohn Marino
28*86d7f5d3SJohn Marino You should have received a copy of the GNU General Public License
29*86d7f5d3SJohn Marino along with RCS; see the file COPYING.
30*86d7f5d3SJohn Marino If not, write to the Free Software Foundation,
31*86d7f5d3SJohn Marino 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32*86d7f5d3SJohn Marino
33*86d7f5d3SJohn Marino Report problems and direct all questions to:
34*86d7f5d3SJohn Marino
35*86d7f5d3SJohn Marino rcs-bugs@cs.purdue.edu
36*86d7f5d3SJohn Marino
37*86d7f5d3SJohn Marino */
38*86d7f5d3SJohn Marino
39*86d7f5d3SJohn Marino
40*86d7f5d3SJohn Marino
41*86d7f5d3SJohn Marino /*
42*86d7f5d3SJohn Marino * $FreeBSD: src/gnu/usr.bin/rcs/lib/rcslex.c,v 1.8 1999/08/27 23:36:47 peter Exp $
43*86d7f5d3SJohn Marino * $DragonFly: src/gnu/usr.bin/rcs/lib/rcslex.c,v 1.2 2003/06/17 04:25:47 dillon Exp $
44*86d7f5d3SJohn Marino *
45*86d7f5d3SJohn Marino * Revision 5.19 1995/06/16 06:19:24 eggert
46*86d7f5d3SJohn Marino * Update FSF address.
47*86d7f5d3SJohn Marino *
48*86d7f5d3SJohn Marino * Revision 5.18 1995/06/01 16:23:43 eggert
49*86d7f5d3SJohn Marino * (map_fd_deallocate,mmap_deallocate,read_deallocate,nothing_to_deallocate):
50*86d7f5d3SJohn Marino * New functions.
51*86d7f5d3SJohn Marino * (Iclose): If large_memory and maps_memory, use them to deallocate mapping.
52*86d7f5d3SJohn Marino * (fd2RILE): Use map_fd if available.
53*86d7f5d3SJohn Marino * If one mapping method fails, try the next instead of giving up;
54*86d7f5d3SJohn Marino * if they all fail, fall back on ordinary read.
55*86d7f5d3SJohn Marino * Work around bug: root mmap over NFS succeeds, but accessing dumps core.
56*86d7f5d3SJohn Marino * Use MAP_FAILED macro for mmap failure, and `char *' instead of caddr_t.
57*86d7f5d3SJohn Marino * (advise_access): Use madvise only if this instance used mmap.
58*86d7f5d3SJohn Marino * (Iopen): Use fdSafer to get safer file descriptor.
59*86d7f5d3SJohn Marino * (aflush): Moved here from rcsedit.c.
60*86d7f5d3SJohn Marino *
61*86d7f5d3SJohn Marino * Revision 5.17 1994/03/20 04:52:58 eggert
62*86d7f5d3SJohn Marino * Don't worry if madvise fails. Add Orewind. Remove lint.
63*86d7f5d3SJohn Marino *
64*86d7f5d3SJohn Marino * Revision 5.16 1993/11/09 17:55:29 eggert
65*86d7f5d3SJohn Marino * Fix `label: }' typo.
66*86d7f5d3SJohn Marino *
67*86d7f5d3SJohn Marino * Revision 5.15 1993/11/03 17:42:27 eggert
68*86d7f5d3SJohn Marino * Improve quality of diagnostics by putting file names in them more often.
69*86d7f5d3SJohn Marino * Don't discard ignored phrases.
70*86d7f5d3SJohn Marino *
71*86d7f5d3SJohn Marino * Revision 5.14 1992/07/28 16:12:44 eggert
72*86d7f5d3SJohn Marino * Identifiers may now start with a digit and (unless they are symbolic names)
73*86d7f5d3SJohn Marino * may contain `.'. Avoid `unsigned'. Statement macro names now end in _.
74*86d7f5d3SJohn Marino *
75*86d7f5d3SJohn Marino * Revision 5.13 1992/02/17 23:02:27 eggert
76*86d7f5d3SJohn Marino * Work around NFS mmap SIGBUS problem.
77*86d7f5d3SJohn Marino *
78*86d7f5d3SJohn Marino * Revision 5.12 1992/01/06 02:42:34 eggert
79*86d7f5d3SJohn Marino * Use OPEN_O_BINARY if mode contains 'b'.
80*86d7f5d3SJohn Marino *
81*86d7f5d3SJohn Marino * Revision 5.11 1991/11/03 03:30:44 eggert
82*86d7f5d3SJohn Marino * Fix porting bug to ancient hosts lacking vfprintf.
83*86d7f5d3SJohn Marino *
84*86d7f5d3SJohn Marino * Revision 5.10 1991/10/07 17:32:46 eggert
85*86d7f5d3SJohn Marino * Support piece tables even if !has_mmap.
86*86d7f5d3SJohn Marino *
87*86d7f5d3SJohn Marino * Revision 5.9 1991/09/24 00:28:42 eggert
88*86d7f5d3SJohn Marino * Don't export errsay().
89*86d7f5d3SJohn Marino *
90*86d7f5d3SJohn Marino * Revision 5.8 1991/08/19 03:13:55 eggert
91*86d7f5d3SJohn Marino * Add eoflex(), mmap support. Tune.
92*86d7f5d3SJohn Marino *
93*86d7f5d3SJohn Marino * Revision 5.7 1991/04/21 11:58:26 eggert
94*86d7f5d3SJohn Marino * Add MS-DOS support.
95*86d7f5d3SJohn Marino *
96*86d7f5d3SJohn Marino * Revision 5.6 1991/02/25 07:12:42 eggert
97*86d7f5d3SJohn Marino * Work around fputs bug. strsave -> str_save (DG/UX name clash)
98*86d7f5d3SJohn Marino *
99*86d7f5d3SJohn Marino * Revision 5.5 1990/12/04 05:18:47 eggert
100*86d7f5d3SJohn Marino * Use -I for prompts and -q for diagnostics.
101*86d7f5d3SJohn Marino *
102*86d7f5d3SJohn Marino * Revision 5.4 1990/11/19 20:05:28 hammer
103*86d7f5d3SJohn Marino * no longer gives warning about unknown keywords if -q is specified
104*86d7f5d3SJohn Marino *
105*86d7f5d3SJohn Marino * Revision 5.3 1990/11/01 05:03:48 eggert
106*86d7f5d3SJohn Marino * When ignoring unknown phrases, copy them to the output RCS file.
107*86d7f5d3SJohn Marino *
108*86d7f5d3SJohn Marino * Revision 5.2 1990/09/04 08:02:27 eggert
109*86d7f5d3SJohn Marino * Count RCS lines better.
110*86d7f5d3SJohn Marino *
111*86d7f5d3SJohn Marino * Revision 5.1 1990/08/29 07:14:03 eggert
112*86d7f5d3SJohn Marino * Work around buggy compilers with defective argument promotion.
113*86d7f5d3SJohn Marino *
114*86d7f5d3SJohn Marino * Revision 5.0 1990/08/22 08:12:55 eggert
115*86d7f5d3SJohn Marino * Remove compile-time limits; use malloc instead.
116*86d7f5d3SJohn Marino * Report errno-related errors with perror().
117*86d7f5d3SJohn Marino * Ansify and Posixate. Add support for ISO 8859.
118*86d7f5d3SJohn Marino * Use better hash function.
119*86d7f5d3SJohn Marino *
120*86d7f5d3SJohn Marino * Revision 4.6 89/05/01 15:13:07 narten
121*86d7f5d3SJohn Marino * changed copyright header to reflect current distribution rules
122*86d7f5d3SJohn Marino *
123*86d7f5d3SJohn Marino * Revision 4.5 88/08/28 15:01:12 eggert
124*86d7f5d3SJohn Marino * Don't loop when writing error messages to a full filesystem.
125*86d7f5d3SJohn Marino * Flush stderr/stdout when mixing output.
126*86d7f5d3SJohn Marino * Yield exit status compatible with diff(1).
127*86d7f5d3SJohn Marino * Shrink stdio code size; allow cc -R; remove lint.
128*86d7f5d3SJohn Marino *
129*86d7f5d3SJohn Marino * Revision 4.4 87/12/18 11:44:47 narten
130*86d7f5d3SJohn Marino * fixed to use "varargs" in "fprintf"; this is required if it is to
131*86d7f5d3SJohn Marino * work on a SPARC machine such as a Sun-4
132*86d7f5d3SJohn Marino *
133*86d7f5d3SJohn Marino * Revision 4.3 87/10/18 10:37:18 narten
134*86d7f5d3SJohn Marino * Updating version numbers. Changes relative to 1.1 actually relative
135*86d7f5d3SJohn Marino * to version 4.1
136*86d7f5d3SJohn Marino *
137*86d7f5d3SJohn Marino * Revision 1.3 87/09/24 14:00:17 narten
138*86d7f5d3SJohn Marino * Sources now pass through lint (if you ignore printf/sprintf/fprintf
139*86d7f5d3SJohn Marino * warnings)
140*86d7f5d3SJohn Marino *
141*86d7f5d3SJohn Marino * Revision 1.2 87/03/27 14:22:33 jenkins
142*86d7f5d3SJohn Marino * Port to suns
143*86d7f5d3SJohn Marino *
144*86d7f5d3SJohn Marino * Revision 4.1 83/03/25 18:12:51 wft
145*86d7f5d3SJohn Marino * Only changed $Header to $Id.
146*86d7f5d3SJohn Marino *
147*86d7f5d3SJohn Marino * Revision 3.3 82/12/10 16:22:37 wft
148*86d7f5d3SJohn Marino * Improved error messages, changed exit status on error to 1.
149*86d7f5d3SJohn Marino *
150*86d7f5d3SJohn Marino * Revision 3.2 82/11/28 21:27:10 wft
151*86d7f5d3SJohn Marino * Renamed ctab to map and included EOFILE; ctab is now a macro in rcsbase.h.
152*86d7f5d3SJohn Marino * Added fflsbuf(), fputs(), and fprintf(), which abort the RCS operations
153*86d7f5d3SJohn Marino * properly in case there is an IO-error (e.g., file system full).
154*86d7f5d3SJohn Marino *
155*86d7f5d3SJohn Marino * Revision 3.1 82/10/11 19:43:56 wft
156*86d7f5d3SJohn Marino * removed unused label out:;
157*86d7f5d3SJohn Marino * made sure all calls to getc() return into an integer, not a char.
158*86d7f5d3SJohn Marino */
159*86d7f5d3SJohn Marino
160*86d7f5d3SJohn Marino
161*86d7f5d3SJohn Marino /*
162*86d7f5d3SJohn Marino #define LEXDB
163*86d7f5d3SJohn Marino */
164*86d7f5d3SJohn Marino /* version LEXDB is for testing the lexical analyzer. The testprogram
165*86d7f5d3SJohn Marino * reads a stream of lexemes, enters the revision numbers into the
166*86d7f5d3SJohn Marino * hashtable, and prints the recognized tokens. Keywords are recognized
167*86d7f5d3SJohn Marino * as identifiers.
168*86d7f5d3SJohn Marino */
169*86d7f5d3SJohn Marino
170*86d7f5d3SJohn Marino
171*86d7f5d3SJohn Marino
172*86d7f5d3SJohn Marino #include "rcsbase.h"
173*86d7f5d3SJohn Marino
174*86d7f5d3SJohn Marino libId(lexId, "$DragonFly: src/gnu/usr.bin/rcs/lib/rcslex.c,v 1.2 2003/06/17 04:25:47 dillon Exp $")
175*86d7f5d3SJohn Marino
176*86d7f5d3SJohn Marino static char *checkidentifier P((char*,int,int));
177*86d7f5d3SJohn Marino static void errsay P((char const*));
178*86d7f5d3SJohn Marino static void fatsay P((char const*));
179*86d7f5d3SJohn Marino static void lookup P((char const*));
180*86d7f5d3SJohn Marino static void startsay P((const char*,const char*));
181*86d7f5d3SJohn Marino static void warnsay P((char const*));
182*86d7f5d3SJohn Marino
183*86d7f5d3SJohn Marino static struct hshentry *nexthsh; /*pointer to next hash entry, set by lookup*/
184*86d7f5d3SJohn Marino
185*86d7f5d3SJohn Marino enum tokens nexttok; /*next token, set by nextlex */
186*86d7f5d3SJohn Marino
187*86d7f5d3SJohn Marino int hshenter; /*if true, next suitable lexeme will be entered */
188*86d7f5d3SJohn Marino /*into the symbol table. Handle with care. */
189*86d7f5d3SJohn Marino int nextc; /*next input character, initialized by Lexinit */
190*86d7f5d3SJohn Marino
191*86d7f5d3SJohn Marino long rcsline; /*current line-number of input */
192*86d7f5d3SJohn Marino int nerror; /*counter for errors */
193*86d7f5d3SJohn Marino int quietflag; /*indicates quiet mode */
194*86d7f5d3SJohn Marino RILE * finptr; /*input file descriptor */
195*86d7f5d3SJohn Marino
196*86d7f5d3SJohn Marino FILE * frewrite; /*file descriptor for echoing input */
197*86d7f5d3SJohn Marino
198*86d7f5d3SJohn Marino FILE * foutptr; /* copy of frewrite, but 0 to suppress echo */
199*86d7f5d3SJohn Marino
200*86d7f5d3SJohn Marino static struct buf tokbuf; /* token buffer */
201*86d7f5d3SJohn Marino
202*86d7f5d3SJohn Marino char const * NextString; /* next token */
203*86d7f5d3SJohn Marino
204*86d7f5d3SJohn Marino /*
205*86d7f5d3SJohn Marino * Our hash algorithm is h[0] = 0, h[i+1] = 4*h[i] + c,
206*86d7f5d3SJohn Marino * so hshsize should be odd.
207*86d7f5d3SJohn Marino * See B J McKenzie, R Harries & T Bell, Selecting a hashing algorithm,
208*86d7f5d3SJohn Marino * Software--practice & experience 20, 2 (Feb 1990), 209-224.
209*86d7f5d3SJohn Marino */
210*86d7f5d3SJohn Marino #ifndef hshsize
211*86d7f5d3SJohn Marino # define hshsize 511
212*86d7f5d3SJohn Marino #endif
213*86d7f5d3SJohn Marino
214*86d7f5d3SJohn Marino static struct hshentry *hshtab[hshsize]; /*hashtable */
215*86d7f5d3SJohn Marino
216*86d7f5d3SJohn Marino static int ignored_phrases; /* have we ignored phrases in this RCS file? */
217*86d7f5d3SJohn Marino
218*86d7f5d3SJohn Marino void
warnignore()219*86d7f5d3SJohn Marino warnignore()
220*86d7f5d3SJohn Marino {
221*86d7f5d3SJohn Marino if (!ignored_phrases) {
222*86d7f5d3SJohn Marino ignored_phrases = true;
223*86d7f5d3SJohn Marino rcswarn("Unknown phrases like `%s ...;' are present.", NextString);
224*86d7f5d3SJohn Marino }
225*86d7f5d3SJohn Marino }
226*86d7f5d3SJohn Marino
227*86d7f5d3SJohn Marino
228*86d7f5d3SJohn Marino
229*86d7f5d3SJohn Marino static void
lookup(str)230*86d7f5d3SJohn Marino lookup(str)
231*86d7f5d3SJohn Marino char const *str;
232*86d7f5d3SJohn Marino /* Function: Looks up the character string pointed to by str in the
233*86d7f5d3SJohn Marino * hashtable. If the string is not present, a new entry for it is created.
234*86d7f5d3SJohn Marino * In any case, the address of the corresponding hashtable entry is placed
235*86d7f5d3SJohn Marino * into nexthsh.
236*86d7f5d3SJohn Marino */
237*86d7f5d3SJohn Marino {
238*86d7f5d3SJohn Marino register unsigned ihash; /* index into hashtable */
239*86d7f5d3SJohn Marino register char const *sp;
240*86d7f5d3SJohn Marino register struct hshentry *n, **p;
241*86d7f5d3SJohn Marino
242*86d7f5d3SJohn Marino /* calculate hash code */
243*86d7f5d3SJohn Marino sp = str;
244*86d7f5d3SJohn Marino ihash = 0;
245*86d7f5d3SJohn Marino while (*sp)
246*86d7f5d3SJohn Marino ihash = (ihash<<2) + *sp++;
247*86d7f5d3SJohn Marino ihash %= hshsize;
248*86d7f5d3SJohn Marino
249*86d7f5d3SJohn Marino for (p = &hshtab[ihash]; ; p = &n->nexthsh)
250*86d7f5d3SJohn Marino if (!(n = *p)) {
251*86d7f5d3SJohn Marino /* empty slot found */
252*86d7f5d3SJohn Marino *p = n = ftalloc(struct hshentry);
253*86d7f5d3SJohn Marino n->num = fstr_save(str);
254*86d7f5d3SJohn Marino n->nexthsh = 0;
255*86d7f5d3SJohn Marino # ifdef LEXDB
256*86d7f5d3SJohn Marino VOID printf("\nEntered: %s at %u ", str, ihash);
257*86d7f5d3SJohn Marino # endif
258*86d7f5d3SJohn Marino break;
259*86d7f5d3SJohn Marino } else if (strcmp(str, n->num) == 0)
260*86d7f5d3SJohn Marino /* match found */
261*86d7f5d3SJohn Marino break;
262*86d7f5d3SJohn Marino nexthsh = n;
263*86d7f5d3SJohn Marino NextString = n->num;
264*86d7f5d3SJohn Marino }
265*86d7f5d3SJohn Marino
266*86d7f5d3SJohn Marino
267*86d7f5d3SJohn Marino
268*86d7f5d3SJohn Marino
269*86d7f5d3SJohn Marino
270*86d7f5d3SJohn Marino
271*86d7f5d3SJohn Marino void
Lexinit()272*86d7f5d3SJohn Marino Lexinit()
273*86d7f5d3SJohn Marino /* Function: Initialization of lexical analyzer:
274*86d7f5d3SJohn Marino * initializes the hashtable,
275*86d7f5d3SJohn Marino * initializes nextc, nexttok if finptr != 0
276*86d7f5d3SJohn Marino */
277*86d7f5d3SJohn Marino { register int c;
278*86d7f5d3SJohn Marino
279*86d7f5d3SJohn Marino for (c = hshsize; 0 <= --c; ) {
280*86d7f5d3SJohn Marino hshtab[c] = 0;
281*86d7f5d3SJohn Marino }
282*86d7f5d3SJohn Marino
283*86d7f5d3SJohn Marino nerror = 0;
284*86d7f5d3SJohn Marino if (finptr) {
285*86d7f5d3SJohn Marino foutptr = 0;
286*86d7f5d3SJohn Marino hshenter = true;
287*86d7f5d3SJohn Marino ignored_phrases = false;
288*86d7f5d3SJohn Marino rcsline = 1;
289*86d7f5d3SJohn Marino bufrealloc(&tokbuf, 2);
290*86d7f5d3SJohn Marino Iget_(finptr, nextc)
291*86d7f5d3SJohn Marino nextlex(); /*initial token*/
292*86d7f5d3SJohn Marino }
293*86d7f5d3SJohn Marino }
294*86d7f5d3SJohn Marino
295*86d7f5d3SJohn Marino
296*86d7f5d3SJohn Marino
297*86d7f5d3SJohn Marino
298*86d7f5d3SJohn Marino
299*86d7f5d3SJohn Marino
300*86d7f5d3SJohn Marino
301*86d7f5d3SJohn Marino void
nextlex()302*86d7f5d3SJohn Marino nextlex()
303*86d7f5d3SJohn Marino
304*86d7f5d3SJohn Marino /* Function: Reads the next token and sets nexttok to the next token code.
305*86d7f5d3SJohn Marino * Only if hshenter is set, a revision number is entered into the
306*86d7f5d3SJohn Marino * hashtable and a pointer to it is placed into nexthsh.
307*86d7f5d3SJohn Marino * This is useful for avoiding that dates are placed into the hashtable.
308*86d7f5d3SJohn Marino * For ID's and NUM's, NextString is set to the character string.
309*86d7f5d3SJohn Marino * Assumption: nextc contains the next character.
310*86d7f5d3SJohn Marino */
311*86d7f5d3SJohn Marino { register int c;
312*86d7f5d3SJohn Marino declarecache;
313*86d7f5d3SJohn Marino register FILE *frew;
314*86d7f5d3SJohn Marino register char * sp;
315*86d7f5d3SJohn Marino char const *limit;
316*86d7f5d3SJohn Marino register enum tokens d;
317*86d7f5d3SJohn Marino register RILE *fin;
318*86d7f5d3SJohn Marino
319*86d7f5d3SJohn Marino fin=finptr; frew=foutptr;
320*86d7f5d3SJohn Marino setupcache(fin); cache(fin);
321*86d7f5d3SJohn Marino c = nextc;
322*86d7f5d3SJohn Marino
323*86d7f5d3SJohn Marino for (;;) { switch ((d = ctab[c])) {
324*86d7f5d3SJohn Marino
325*86d7f5d3SJohn Marino default:
326*86d7f5d3SJohn Marino fatserror("unknown character `%c'", c);
327*86d7f5d3SJohn Marino /*NOTREACHED*/
328*86d7f5d3SJohn Marino
329*86d7f5d3SJohn Marino case NEWLN:
330*86d7f5d3SJohn Marino ++rcsline;
331*86d7f5d3SJohn Marino # ifdef LEXDB
332*86d7f5d3SJohn Marino afputc('\n',stdout);
333*86d7f5d3SJohn Marino # endif
334*86d7f5d3SJohn Marino /* Note: falls into next case */
335*86d7f5d3SJohn Marino
336*86d7f5d3SJohn Marino case SPACE:
337*86d7f5d3SJohn Marino GETC_(frew, c)
338*86d7f5d3SJohn Marino continue;
339*86d7f5d3SJohn Marino
340*86d7f5d3SJohn Marino case IDCHAR:
341*86d7f5d3SJohn Marino case LETTER:
342*86d7f5d3SJohn Marino case Letter:
343*86d7f5d3SJohn Marino d = ID;
344*86d7f5d3SJohn Marino /* fall into */
345*86d7f5d3SJohn Marino case DIGIT:
346*86d7f5d3SJohn Marino case PERIOD:
347*86d7f5d3SJohn Marino sp = tokbuf.string;
348*86d7f5d3SJohn Marino limit = sp + tokbuf.size;
349*86d7f5d3SJohn Marino *sp++ = c;
350*86d7f5d3SJohn Marino for (;;) {
351*86d7f5d3SJohn Marino GETC_(frew, c)
352*86d7f5d3SJohn Marino switch (ctab[c]) {
353*86d7f5d3SJohn Marino case IDCHAR:
354*86d7f5d3SJohn Marino case LETTER:
355*86d7f5d3SJohn Marino case Letter:
356*86d7f5d3SJohn Marino d = ID;
357*86d7f5d3SJohn Marino /* fall into */
358*86d7f5d3SJohn Marino case DIGIT:
359*86d7f5d3SJohn Marino case PERIOD:
360*86d7f5d3SJohn Marino *sp++ = c;
361*86d7f5d3SJohn Marino if (limit <= sp)
362*86d7f5d3SJohn Marino sp = bufenlarge(&tokbuf, &limit);
363*86d7f5d3SJohn Marino continue;
364*86d7f5d3SJohn Marino
365*86d7f5d3SJohn Marino default:
366*86d7f5d3SJohn Marino break;
367*86d7f5d3SJohn Marino }
368*86d7f5d3SJohn Marino break;
369*86d7f5d3SJohn Marino }
370*86d7f5d3SJohn Marino *sp = 0;
371*86d7f5d3SJohn Marino if (d == DIGIT || d == PERIOD) {
372*86d7f5d3SJohn Marino d = NUM;
373*86d7f5d3SJohn Marino if (hshenter) {
374*86d7f5d3SJohn Marino lookup(tokbuf.string);
375*86d7f5d3SJohn Marino break;
376*86d7f5d3SJohn Marino }
377*86d7f5d3SJohn Marino }
378*86d7f5d3SJohn Marino NextString = fstr_save(tokbuf.string);
379*86d7f5d3SJohn Marino break;
380*86d7f5d3SJohn Marino
381*86d7f5d3SJohn Marino case SBEGIN: /* long string */
382*86d7f5d3SJohn Marino d = STRING;
383*86d7f5d3SJohn Marino /* note: only the initial SBEGIN has been read*/
384*86d7f5d3SJohn Marino /* read the string, and reset nextc afterwards*/
385*86d7f5d3SJohn Marino break;
386*86d7f5d3SJohn Marino
387*86d7f5d3SJohn Marino case COLON:
388*86d7f5d3SJohn Marino case SEMI:
389*86d7f5d3SJohn Marino GETC_(frew, c)
390*86d7f5d3SJohn Marino break;
391*86d7f5d3SJohn Marino } break; }
392*86d7f5d3SJohn Marino nextc = c;
393*86d7f5d3SJohn Marino nexttok = d;
394*86d7f5d3SJohn Marino uncache(fin);
395*86d7f5d3SJohn Marino }
396*86d7f5d3SJohn Marino
397*86d7f5d3SJohn Marino int
eoflex()398*86d7f5d3SJohn Marino eoflex()
399*86d7f5d3SJohn Marino /*
400*86d7f5d3SJohn Marino * Yield true if we look ahead to the end of the input, false otherwise.
401*86d7f5d3SJohn Marino * nextc becomes undefined at end of file.
402*86d7f5d3SJohn Marino */
403*86d7f5d3SJohn Marino {
404*86d7f5d3SJohn Marino register int c;
405*86d7f5d3SJohn Marino declarecache;
406*86d7f5d3SJohn Marino register FILE *fout;
407*86d7f5d3SJohn Marino register RILE *fin;
408*86d7f5d3SJohn Marino
409*86d7f5d3SJohn Marino c = nextc;
410*86d7f5d3SJohn Marino fin = finptr;
411*86d7f5d3SJohn Marino fout = foutptr;
412*86d7f5d3SJohn Marino setupcache(fin); cache(fin);
413*86d7f5d3SJohn Marino
414*86d7f5d3SJohn Marino for (;;) {
415*86d7f5d3SJohn Marino switch (ctab[c]) {
416*86d7f5d3SJohn Marino default:
417*86d7f5d3SJohn Marino nextc = c;
418*86d7f5d3SJohn Marino uncache(fin);
419*86d7f5d3SJohn Marino return false;
420*86d7f5d3SJohn Marino
421*86d7f5d3SJohn Marino case NEWLN:
422*86d7f5d3SJohn Marino ++rcsline;
423*86d7f5d3SJohn Marino /* fall into */
424*86d7f5d3SJohn Marino case SPACE:
425*86d7f5d3SJohn Marino cachegeteof_(c, {uncache(fin);return true;})
426*86d7f5d3SJohn Marino break;
427*86d7f5d3SJohn Marino }
428*86d7f5d3SJohn Marino if (fout)
429*86d7f5d3SJohn Marino aputc_(c, fout)
430*86d7f5d3SJohn Marino }
431*86d7f5d3SJohn Marino }
432*86d7f5d3SJohn Marino
433*86d7f5d3SJohn Marino
getlex(token)434*86d7f5d3SJohn Marino int getlex(token)
435*86d7f5d3SJohn Marino enum tokens token;
436*86d7f5d3SJohn Marino /* Function: Checks if nexttok is the same as token. If so,
437*86d7f5d3SJohn Marino * advances the input by calling nextlex and returns true.
438*86d7f5d3SJohn Marino * otherwise returns false.
439*86d7f5d3SJohn Marino * Doesn't work for strings and keywords; loses the character string for ids.
440*86d7f5d3SJohn Marino */
441*86d7f5d3SJohn Marino {
442*86d7f5d3SJohn Marino if (nexttok==token) {
443*86d7f5d3SJohn Marino nextlex();
444*86d7f5d3SJohn Marino return(true);
445*86d7f5d3SJohn Marino } else return(false);
446*86d7f5d3SJohn Marino }
447*86d7f5d3SJohn Marino
448*86d7f5d3SJohn Marino int
getkeyopt(key)449*86d7f5d3SJohn Marino getkeyopt(key)
450*86d7f5d3SJohn Marino char const *key;
451*86d7f5d3SJohn Marino /* Function: If the current token is a keyword identical to key,
452*86d7f5d3SJohn Marino * advances the input by calling nextlex and returns true;
453*86d7f5d3SJohn Marino * otherwise returns false.
454*86d7f5d3SJohn Marino */
455*86d7f5d3SJohn Marino {
456*86d7f5d3SJohn Marino if (nexttok==ID && strcmp(key,NextString) == 0) {
457*86d7f5d3SJohn Marino /* match found */
458*86d7f5d3SJohn Marino ffree1(NextString);
459*86d7f5d3SJohn Marino nextlex();
460*86d7f5d3SJohn Marino return(true);
461*86d7f5d3SJohn Marino }
462*86d7f5d3SJohn Marino return(false);
463*86d7f5d3SJohn Marino }
464*86d7f5d3SJohn Marino
465*86d7f5d3SJohn Marino void
getkey(key)466*86d7f5d3SJohn Marino getkey(key)
467*86d7f5d3SJohn Marino char const *key;
468*86d7f5d3SJohn Marino /* Check that the current input token is a keyword identical to key,
469*86d7f5d3SJohn Marino * and advance the input by calling nextlex.
470*86d7f5d3SJohn Marino */
471*86d7f5d3SJohn Marino {
472*86d7f5d3SJohn Marino if (!getkeyopt(key))
473*86d7f5d3SJohn Marino fatserror("missing '%s' keyword", key);
474*86d7f5d3SJohn Marino }
475*86d7f5d3SJohn Marino
476*86d7f5d3SJohn Marino void
getkeystring(key)477*86d7f5d3SJohn Marino getkeystring(key)
478*86d7f5d3SJohn Marino char const *key;
479*86d7f5d3SJohn Marino /* Check that the current input token is a keyword identical to key,
480*86d7f5d3SJohn Marino * and advance the input by calling nextlex; then look ahead for a string.
481*86d7f5d3SJohn Marino */
482*86d7f5d3SJohn Marino {
483*86d7f5d3SJohn Marino getkey(key);
484*86d7f5d3SJohn Marino if (nexttok != STRING)
485*86d7f5d3SJohn Marino fatserror("missing string after '%s' keyword", key);
486*86d7f5d3SJohn Marino }
487*86d7f5d3SJohn Marino
488*86d7f5d3SJohn Marino
489*86d7f5d3SJohn Marino char const *
getid()490*86d7f5d3SJohn Marino getid()
491*86d7f5d3SJohn Marino /* Function: Checks if nexttok is an identifier. If so,
492*86d7f5d3SJohn Marino * advances the input by calling nextlex and returns a pointer
493*86d7f5d3SJohn Marino * to the identifier; otherwise returns 0.
494*86d7f5d3SJohn Marino * Treats keywords as identifiers.
495*86d7f5d3SJohn Marino */
496*86d7f5d3SJohn Marino {
497*86d7f5d3SJohn Marino register char const *name;
498*86d7f5d3SJohn Marino if (nexttok==ID) {
499*86d7f5d3SJohn Marino name = NextString;
500*86d7f5d3SJohn Marino nextlex();
501*86d7f5d3SJohn Marino return name;
502*86d7f5d3SJohn Marino } else
503*86d7f5d3SJohn Marino return 0;
504*86d7f5d3SJohn Marino }
505*86d7f5d3SJohn Marino
506*86d7f5d3SJohn Marino
getnum()507*86d7f5d3SJohn Marino struct hshentry * getnum()
508*86d7f5d3SJohn Marino /* Function: Checks if nexttok is a number. If so,
509*86d7f5d3SJohn Marino * advances the input by calling nextlex and returns a pointer
510*86d7f5d3SJohn Marino * to the hashtable entry. Otherwise returns 0.
511*86d7f5d3SJohn Marino * Doesn't work if hshenter is false.
512*86d7f5d3SJohn Marino */
513*86d7f5d3SJohn Marino {
514*86d7f5d3SJohn Marino register struct hshentry * num;
515*86d7f5d3SJohn Marino if (nexttok==NUM) {
516*86d7f5d3SJohn Marino num=nexthsh;
517*86d7f5d3SJohn Marino nextlex();
518*86d7f5d3SJohn Marino return num;
519*86d7f5d3SJohn Marino } else
520*86d7f5d3SJohn Marino return 0;
521*86d7f5d3SJohn Marino }
522*86d7f5d3SJohn Marino
523*86d7f5d3SJohn Marino struct cbuf
getphrases(key)524*86d7f5d3SJohn Marino getphrases(key)
525*86d7f5d3SJohn Marino char const *key;
526*86d7f5d3SJohn Marino /*
527*86d7f5d3SJohn Marino * Get a series of phrases that do not start with KEY. Yield resulting buffer.
528*86d7f5d3SJohn Marino * Stop when the next phrase starts with a token that is not an identifier,
529*86d7f5d3SJohn Marino * or is KEY. Copy input to foutptr if it is set. Unlike ignorephrases(),
530*86d7f5d3SJohn Marino * this routine assumes nextlex() has already been invoked before we start.
531*86d7f5d3SJohn Marino */
532*86d7f5d3SJohn Marino {
533*86d7f5d3SJohn Marino declarecache;
534*86d7f5d3SJohn Marino register int c;
535*86d7f5d3SJohn Marino register char const *kn;
536*86d7f5d3SJohn Marino struct cbuf r;
537*86d7f5d3SJohn Marino register RILE *fin;
538*86d7f5d3SJohn Marino register FILE *frew;
539*86d7f5d3SJohn Marino # if large_memory
540*86d7f5d3SJohn Marino # define savech_(c) ;
541*86d7f5d3SJohn Marino # else
542*86d7f5d3SJohn Marino register char *p;
543*86d7f5d3SJohn Marino char const *limit;
544*86d7f5d3SJohn Marino struct buf b;
545*86d7f5d3SJohn Marino # define savech_(c) {if (limit<=p)p=bufenlarge(&b,&limit); *p++ =(c);}
546*86d7f5d3SJohn Marino # endif
547*86d7f5d3SJohn Marino
548*86d7f5d3SJohn Marino if (nexttok!=ID || strcmp(NextString,key) == 0)
549*86d7f5d3SJohn Marino clear_buf(&r);
550*86d7f5d3SJohn Marino else {
551*86d7f5d3SJohn Marino warnignore();
552*86d7f5d3SJohn Marino fin = finptr;
553*86d7f5d3SJohn Marino frew = foutptr;
554*86d7f5d3SJohn Marino setupcache(fin); cache(fin);
555*86d7f5d3SJohn Marino # if large_memory
556*86d7f5d3SJohn Marino r.string = (char const*)cacheptr() - strlen(NextString) - 1;
557*86d7f5d3SJohn Marino # else
558*86d7f5d3SJohn Marino bufautobegin(&b);
559*86d7f5d3SJohn Marino bufscpy(&b, NextString);
560*86d7f5d3SJohn Marino p = b.string + strlen(b.string);
561*86d7f5d3SJohn Marino limit = b.string + b.size;
562*86d7f5d3SJohn Marino # endif
563*86d7f5d3SJohn Marino ffree1(NextString);
564*86d7f5d3SJohn Marino c = nextc;
565*86d7f5d3SJohn Marino for (;;) {
566*86d7f5d3SJohn Marino for (;;) {
567*86d7f5d3SJohn Marino savech_(c)
568*86d7f5d3SJohn Marino switch (ctab[c]) {
569*86d7f5d3SJohn Marino default:
570*86d7f5d3SJohn Marino fatserror("unknown character `%c'", c);
571*86d7f5d3SJohn Marino /*NOTREACHED*/
572*86d7f5d3SJohn Marino case NEWLN:
573*86d7f5d3SJohn Marino ++rcsline;
574*86d7f5d3SJohn Marino /* fall into */
575*86d7f5d3SJohn Marino case COLON: case DIGIT: case LETTER: case Letter:
576*86d7f5d3SJohn Marino case PERIOD: case SPACE:
577*86d7f5d3SJohn Marino GETC_(frew, c)
578*86d7f5d3SJohn Marino continue;
579*86d7f5d3SJohn Marino case SBEGIN: /* long string */
580*86d7f5d3SJohn Marino for (;;) {
581*86d7f5d3SJohn Marino for (;;) {
582*86d7f5d3SJohn Marino GETC_(frew, c)
583*86d7f5d3SJohn Marino savech_(c)
584*86d7f5d3SJohn Marino switch (c) {
585*86d7f5d3SJohn Marino case '\n':
586*86d7f5d3SJohn Marino ++rcsline;
587*86d7f5d3SJohn Marino /* fall into */
588*86d7f5d3SJohn Marino default:
589*86d7f5d3SJohn Marino continue;
590*86d7f5d3SJohn Marino
591*86d7f5d3SJohn Marino case SDELIM:
592*86d7f5d3SJohn Marino break;
593*86d7f5d3SJohn Marino }
594*86d7f5d3SJohn Marino break;
595*86d7f5d3SJohn Marino }
596*86d7f5d3SJohn Marino GETC_(frew, c)
597*86d7f5d3SJohn Marino if (c != SDELIM)
598*86d7f5d3SJohn Marino break;
599*86d7f5d3SJohn Marino savech_(c)
600*86d7f5d3SJohn Marino }
601*86d7f5d3SJohn Marino continue;
602*86d7f5d3SJohn Marino case SEMI:
603*86d7f5d3SJohn Marino cacheget_(c)
604*86d7f5d3SJohn Marino if (ctab[c] == NEWLN) {
605*86d7f5d3SJohn Marino if (frew)
606*86d7f5d3SJohn Marino aputc_(c, frew)
607*86d7f5d3SJohn Marino ++rcsline;
608*86d7f5d3SJohn Marino savech_(c)
609*86d7f5d3SJohn Marino cacheget_(c)
610*86d7f5d3SJohn Marino }
611*86d7f5d3SJohn Marino # if large_memory
612*86d7f5d3SJohn Marino r.size = (char const*)cacheptr() - 1 - r.string;
613*86d7f5d3SJohn Marino # endif
614*86d7f5d3SJohn Marino for (;;) {
615*86d7f5d3SJohn Marino switch (ctab[c]) {
616*86d7f5d3SJohn Marino case NEWLN:
617*86d7f5d3SJohn Marino ++rcsline;
618*86d7f5d3SJohn Marino /* fall into */
619*86d7f5d3SJohn Marino case SPACE:
620*86d7f5d3SJohn Marino cacheget_(c)
621*86d7f5d3SJohn Marino continue;
622*86d7f5d3SJohn Marino
623*86d7f5d3SJohn Marino default: break;
624*86d7f5d3SJohn Marino }
625*86d7f5d3SJohn Marino break;
626*86d7f5d3SJohn Marino }
627*86d7f5d3SJohn Marino if (frew)
628*86d7f5d3SJohn Marino aputc_(c, frew)
629*86d7f5d3SJohn Marino break;
630*86d7f5d3SJohn Marino }
631*86d7f5d3SJohn Marino break;
632*86d7f5d3SJohn Marino }
633*86d7f5d3SJohn Marino if (ctab[c] == Letter) {
634*86d7f5d3SJohn Marino for (kn = key; c && *kn==c; kn++)
635*86d7f5d3SJohn Marino GETC_(frew, c)
636*86d7f5d3SJohn Marino if (!*kn)
637*86d7f5d3SJohn Marino switch (ctab[c]) {
638*86d7f5d3SJohn Marino case DIGIT: case LETTER: case Letter:
639*86d7f5d3SJohn Marino case IDCHAR: case PERIOD:
640*86d7f5d3SJohn Marino break;
641*86d7f5d3SJohn Marino default:
642*86d7f5d3SJohn Marino nextc = c;
643*86d7f5d3SJohn Marino NextString = fstr_save(key);
644*86d7f5d3SJohn Marino nexttok = ID;
645*86d7f5d3SJohn Marino uncache(fin);
646*86d7f5d3SJohn Marino goto returnit;
647*86d7f5d3SJohn Marino }
648*86d7f5d3SJohn Marino # if !large_memory
649*86d7f5d3SJohn Marino {
650*86d7f5d3SJohn Marino register char const *ki;
651*86d7f5d3SJohn Marino for (ki=key; ki<kn; )
652*86d7f5d3SJohn Marino savech_(*ki++)
653*86d7f5d3SJohn Marino }
654*86d7f5d3SJohn Marino # endif
655*86d7f5d3SJohn Marino } else {
656*86d7f5d3SJohn Marino nextc = c;
657*86d7f5d3SJohn Marino uncache(fin);
658*86d7f5d3SJohn Marino nextlex();
659*86d7f5d3SJohn Marino break;
660*86d7f5d3SJohn Marino }
661*86d7f5d3SJohn Marino }
662*86d7f5d3SJohn Marino returnit:;
663*86d7f5d3SJohn Marino # if !large_memory
664*86d7f5d3SJohn Marino return bufremember(&b, (size_t)(p - b.string));
665*86d7f5d3SJohn Marino # endif
666*86d7f5d3SJohn Marino }
667*86d7f5d3SJohn Marino return r;
668*86d7f5d3SJohn Marino }
669*86d7f5d3SJohn Marino
670*86d7f5d3SJohn Marino
671*86d7f5d3SJohn Marino void
readstring()672*86d7f5d3SJohn Marino readstring()
673*86d7f5d3SJohn Marino /* skip over characters until terminating single SDELIM */
674*86d7f5d3SJohn Marino /* If foutptr is set, copy every character read to foutptr. */
675*86d7f5d3SJohn Marino /* Does not advance nextlex at the end. */
676*86d7f5d3SJohn Marino { register int c;
677*86d7f5d3SJohn Marino declarecache;
678*86d7f5d3SJohn Marino register FILE *frew;
679*86d7f5d3SJohn Marino register RILE *fin;
680*86d7f5d3SJohn Marino fin=finptr; frew=foutptr;
681*86d7f5d3SJohn Marino setupcache(fin); cache(fin);
682*86d7f5d3SJohn Marino for (;;) {
683*86d7f5d3SJohn Marino GETC_(frew, c)
684*86d7f5d3SJohn Marino switch (c) {
685*86d7f5d3SJohn Marino case '\n':
686*86d7f5d3SJohn Marino ++rcsline;
687*86d7f5d3SJohn Marino break;
688*86d7f5d3SJohn Marino
689*86d7f5d3SJohn Marino case SDELIM:
690*86d7f5d3SJohn Marino GETC_(frew, c)
691*86d7f5d3SJohn Marino if (c != SDELIM) {
692*86d7f5d3SJohn Marino /* end of string */
693*86d7f5d3SJohn Marino nextc = c;
694*86d7f5d3SJohn Marino uncache(fin);
695*86d7f5d3SJohn Marino return;
696*86d7f5d3SJohn Marino }
697*86d7f5d3SJohn Marino break;
698*86d7f5d3SJohn Marino }
699*86d7f5d3SJohn Marino }
700*86d7f5d3SJohn Marino }
701*86d7f5d3SJohn Marino
702*86d7f5d3SJohn Marino
703*86d7f5d3SJohn Marino void
printstring()704*86d7f5d3SJohn Marino printstring()
705*86d7f5d3SJohn Marino /* Function: copy a string to stdout, until terminated with a single SDELIM.
706*86d7f5d3SJohn Marino * Does not advance nextlex at the end.
707*86d7f5d3SJohn Marino */
708*86d7f5d3SJohn Marino {
709*86d7f5d3SJohn Marino register int c;
710*86d7f5d3SJohn Marino declarecache;
711*86d7f5d3SJohn Marino register FILE *fout;
712*86d7f5d3SJohn Marino register RILE *fin;
713*86d7f5d3SJohn Marino fin=finptr;
714*86d7f5d3SJohn Marino fout = stdout;
715*86d7f5d3SJohn Marino setupcache(fin); cache(fin);
716*86d7f5d3SJohn Marino for (;;) {
717*86d7f5d3SJohn Marino cacheget_(c)
718*86d7f5d3SJohn Marino switch (c) {
719*86d7f5d3SJohn Marino case '\n':
720*86d7f5d3SJohn Marino ++rcsline;
721*86d7f5d3SJohn Marino break;
722*86d7f5d3SJohn Marino case SDELIM:
723*86d7f5d3SJohn Marino cacheget_(c)
724*86d7f5d3SJohn Marino if (c != SDELIM) {
725*86d7f5d3SJohn Marino nextc=c;
726*86d7f5d3SJohn Marino uncache(fin);
727*86d7f5d3SJohn Marino return;
728*86d7f5d3SJohn Marino }
729*86d7f5d3SJohn Marino break;
730*86d7f5d3SJohn Marino }
731*86d7f5d3SJohn Marino aputc_(c,fout)
732*86d7f5d3SJohn Marino }
733*86d7f5d3SJohn Marino }
734*86d7f5d3SJohn Marino
735*86d7f5d3SJohn Marino
736*86d7f5d3SJohn Marino
737*86d7f5d3SJohn Marino struct cbuf
savestring(target)738*86d7f5d3SJohn Marino savestring(target)
739*86d7f5d3SJohn Marino struct buf *target;
740*86d7f5d3SJohn Marino /* Copies a string terminated with SDELIM from file finptr to buffer target.
741*86d7f5d3SJohn Marino * Double SDELIM is replaced with SDELIM.
742*86d7f5d3SJohn Marino * If foutptr is set, the string is also copied unchanged to foutptr.
743*86d7f5d3SJohn Marino * Does not advance nextlex at the end.
744*86d7f5d3SJohn Marino * Yield a copy of *TARGET, except with exact length.
745*86d7f5d3SJohn Marino */
746*86d7f5d3SJohn Marino {
747*86d7f5d3SJohn Marino register int c;
748*86d7f5d3SJohn Marino declarecache;
749*86d7f5d3SJohn Marino register FILE *frew;
750*86d7f5d3SJohn Marino register char *tp;
751*86d7f5d3SJohn Marino register RILE *fin;
752*86d7f5d3SJohn Marino char const *limit;
753*86d7f5d3SJohn Marino struct cbuf r;
754*86d7f5d3SJohn Marino
755*86d7f5d3SJohn Marino fin=finptr; frew=foutptr;
756*86d7f5d3SJohn Marino setupcache(fin); cache(fin);
757*86d7f5d3SJohn Marino tp = target->string; limit = tp + target->size;
758*86d7f5d3SJohn Marino for (;;) {
759*86d7f5d3SJohn Marino GETC_(frew, c)
760*86d7f5d3SJohn Marino switch (c) {
761*86d7f5d3SJohn Marino case '\n':
762*86d7f5d3SJohn Marino ++rcsline;
763*86d7f5d3SJohn Marino break;
764*86d7f5d3SJohn Marino case SDELIM:
765*86d7f5d3SJohn Marino GETC_(frew, c)
766*86d7f5d3SJohn Marino if (c != SDELIM) {
767*86d7f5d3SJohn Marino /* end of string */
768*86d7f5d3SJohn Marino nextc=c;
769*86d7f5d3SJohn Marino r.string = target->string;
770*86d7f5d3SJohn Marino r.size = tp - r.string;
771*86d7f5d3SJohn Marino uncache(fin);
772*86d7f5d3SJohn Marino return r;
773*86d7f5d3SJohn Marino }
774*86d7f5d3SJohn Marino break;
775*86d7f5d3SJohn Marino }
776*86d7f5d3SJohn Marino if (tp == limit)
777*86d7f5d3SJohn Marino tp = bufenlarge(target, &limit);
778*86d7f5d3SJohn Marino *tp++ = c;
779*86d7f5d3SJohn Marino }
780*86d7f5d3SJohn Marino }
781*86d7f5d3SJohn Marino
782*86d7f5d3SJohn Marino
783*86d7f5d3SJohn Marino static char *
checkidentifier(id,delimiter,dotok)784*86d7f5d3SJohn Marino checkidentifier(id, delimiter, dotok)
785*86d7f5d3SJohn Marino register char *id;
786*86d7f5d3SJohn Marino int delimiter;
787*86d7f5d3SJohn Marino register int dotok;
788*86d7f5d3SJohn Marino /* Function: check whether the string starting at id is an */
789*86d7f5d3SJohn Marino /* identifier and return a pointer to the delimiter*/
790*86d7f5d3SJohn Marino /* after the identifier. White space, delim and 0 */
791*86d7f5d3SJohn Marino /* are legal delimiters. Aborts the program if not*/
792*86d7f5d3SJohn Marino /* a legal identifier. Useful for checking commands*/
793*86d7f5d3SJohn Marino /* If !delim, the only delimiter is 0. */
794*86d7f5d3SJohn Marino /* Allow '.' in identifier only if DOTOK is set. */
795*86d7f5d3SJohn Marino {
796*86d7f5d3SJohn Marino register char *temp;
797*86d7f5d3SJohn Marino register char c;
798*86d7f5d3SJohn Marino register char delim = delimiter;
799*86d7f5d3SJohn Marino int isid = false;
800*86d7f5d3SJohn Marino
801*86d7f5d3SJohn Marino temp = id;
802*86d7f5d3SJohn Marino for (;; id++) {
803*86d7f5d3SJohn Marino switch (ctab[(unsigned char)(c = *id)]) {
804*86d7f5d3SJohn Marino case IDCHAR:
805*86d7f5d3SJohn Marino case LETTER:
806*86d7f5d3SJohn Marino case Letter:
807*86d7f5d3SJohn Marino isid = true;
808*86d7f5d3SJohn Marino continue;
809*86d7f5d3SJohn Marino
810*86d7f5d3SJohn Marino case DIGIT:
811*86d7f5d3SJohn Marino continue;
812*86d7f5d3SJohn Marino
813*86d7f5d3SJohn Marino case PERIOD:
814*86d7f5d3SJohn Marino if (dotok)
815*86d7f5d3SJohn Marino continue;
816*86d7f5d3SJohn Marino break;
817*86d7f5d3SJohn Marino
818*86d7f5d3SJohn Marino default:
819*86d7f5d3SJohn Marino break;
820*86d7f5d3SJohn Marino }
821*86d7f5d3SJohn Marino break;
822*86d7f5d3SJohn Marino }
823*86d7f5d3SJohn Marino if ( ! isid
824*86d7f5d3SJohn Marino || (c && (!delim || (c!=delim && c!=' ' && c!='\t' && c!='\n')))
825*86d7f5d3SJohn Marino ) {
826*86d7f5d3SJohn Marino /* append \0 to end of id before error message */
827*86d7f5d3SJohn Marino while ((c = *id) && c!=' ' && c!='\t' && c!='\n' && c!=delim)
828*86d7f5d3SJohn Marino id++;
829*86d7f5d3SJohn Marino *id = '\0';
830*86d7f5d3SJohn Marino faterror("invalid %s `%s'",
831*86d7f5d3SJohn Marino dotok ? "identifier" : "symbol", temp
832*86d7f5d3SJohn Marino );
833*86d7f5d3SJohn Marino }
834*86d7f5d3SJohn Marino return id;
835*86d7f5d3SJohn Marino }
836*86d7f5d3SJohn Marino
837*86d7f5d3SJohn Marino char *
checkid(id,delimiter)838*86d7f5d3SJohn Marino checkid(id, delimiter)
839*86d7f5d3SJohn Marino char *id;
840*86d7f5d3SJohn Marino int delimiter;
841*86d7f5d3SJohn Marino {
842*86d7f5d3SJohn Marino return checkidentifier(id, delimiter, true);
843*86d7f5d3SJohn Marino }
844*86d7f5d3SJohn Marino
845*86d7f5d3SJohn Marino char *
checksym(sym,delimiter)846*86d7f5d3SJohn Marino checksym(sym, delimiter)
847*86d7f5d3SJohn Marino char *sym;
848*86d7f5d3SJohn Marino int delimiter;
849*86d7f5d3SJohn Marino {
850*86d7f5d3SJohn Marino return checkidentifier(sym, delimiter, false);
851*86d7f5d3SJohn Marino }
852*86d7f5d3SJohn Marino
853*86d7f5d3SJohn Marino void
checksid(id)854*86d7f5d3SJohn Marino checksid(id)
855*86d7f5d3SJohn Marino char *id;
856*86d7f5d3SJohn Marino /* Check whether the string ID is an identifier. */
857*86d7f5d3SJohn Marino {
858*86d7f5d3SJohn Marino VOID checkid(id, 0);
859*86d7f5d3SJohn Marino }
860*86d7f5d3SJohn Marino
861*86d7f5d3SJohn Marino void
checkssym(sym)862*86d7f5d3SJohn Marino checkssym(sym)
863*86d7f5d3SJohn Marino char *sym;
864*86d7f5d3SJohn Marino {
865*86d7f5d3SJohn Marino VOID checksym(sym, 0);
866*86d7f5d3SJohn Marino }
867*86d7f5d3SJohn Marino
868*86d7f5d3SJohn Marino
869*86d7f5d3SJohn Marino #if !large_memory
870*86d7f5d3SJohn Marino # define Iclose(f) fclose(f)
871*86d7f5d3SJohn Marino #else
872*86d7f5d3SJohn Marino # if !maps_memory
873*86d7f5d3SJohn Marino static int Iclose P((RILE *));
874*86d7f5d3SJohn Marino static int
Iclose(f)875*86d7f5d3SJohn Marino Iclose(f)
876*86d7f5d3SJohn Marino register RILE *f;
877*86d7f5d3SJohn Marino {
878*86d7f5d3SJohn Marino tfree(f->base);
879*86d7f5d3SJohn Marino f->base = 0;
880*86d7f5d3SJohn Marino return fclose(f->stream);
881*86d7f5d3SJohn Marino }
882*86d7f5d3SJohn Marino # else
883*86d7f5d3SJohn Marino static int Iclose P((RILE *));
884*86d7f5d3SJohn Marino static int
Iclose(f)885*86d7f5d3SJohn Marino Iclose(f)
886*86d7f5d3SJohn Marino register RILE *f;
887*86d7f5d3SJohn Marino {
888*86d7f5d3SJohn Marino (* f->deallocate) (f);
889*86d7f5d3SJohn Marino f->base = 0;
890*86d7f5d3SJohn Marino return close(f->fd);
891*86d7f5d3SJohn Marino }
892*86d7f5d3SJohn Marino
893*86d7f5d3SJohn Marino # if has_map_fd
894*86d7f5d3SJohn Marino static void map_fd_deallocate P((RILE *));
895*86d7f5d3SJohn Marino static void
map_fd_deallocate(f)896*86d7f5d3SJohn Marino map_fd_deallocate(f)
897*86d7f5d3SJohn Marino register RILE *f;
898*86d7f5d3SJohn Marino {
899*86d7f5d3SJohn Marino if (vm_deallocate(
900*86d7f5d3SJohn Marino task_self(),
901*86d7f5d3SJohn Marino (vm_address_t) f->base,
902*86d7f5d3SJohn Marino (vm_size_t) (f->lim - f->base)
903*86d7f5d3SJohn Marino ) != KERN_SUCCESS)
904*86d7f5d3SJohn Marino efaterror("vm_deallocate");
905*86d7f5d3SJohn Marino }
906*86d7f5d3SJohn Marino # endif
907*86d7f5d3SJohn Marino # if has_mmap
908*86d7f5d3SJohn Marino static void mmap_deallocate P((RILE *));
909*86d7f5d3SJohn Marino static void
mmap_deallocate(f)910*86d7f5d3SJohn Marino mmap_deallocate(f)
911*86d7f5d3SJohn Marino register RILE *f;
912*86d7f5d3SJohn Marino {
913*86d7f5d3SJohn Marino if (munmap((char *) f->base, (size_t) (f->lim - f->base)) != 0)
914*86d7f5d3SJohn Marino efaterror("munmap");
915*86d7f5d3SJohn Marino }
916*86d7f5d3SJohn Marino # endif
917*86d7f5d3SJohn Marino static void read_deallocate P((RILE *));
918*86d7f5d3SJohn Marino static void
read_deallocate(f)919*86d7f5d3SJohn Marino read_deallocate(f)
920*86d7f5d3SJohn Marino RILE *f;
921*86d7f5d3SJohn Marino {
922*86d7f5d3SJohn Marino tfree(f->base);
923*86d7f5d3SJohn Marino }
924*86d7f5d3SJohn Marino
925*86d7f5d3SJohn Marino static void nothing_to_deallocate P((RILE *));
926*86d7f5d3SJohn Marino static void
nothing_to_deallocate(f)927*86d7f5d3SJohn Marino nothing_to_deallocate(f)
928*86d7f5d3SJohn Marino RILE *f;
929*86d7f5d3SJohn Marino {
930*86d7f5d3SJohn Marino }
931*86d7f5d3SJohn Marino # endif
932*86d7f5d3SJohn Marino #endif
933*86d7f5d3SJohn Marino
934*86d7f5d3SJohn Marino
935*86d7f5d3SJohn Marino #if large_memory && maps_memory
936*86d7f5d3SJohn Marino static RILE *fd2_RILE P((int,char const*,struct stat*));
937*86d7f5d3SJohn Marino static RILE *
fd2_RILE(fd,name,status)938*86d7f5d3SJohn Marino fd2_RILE(fd, name, status)
939*86d7f5d3SJohn Marino #else
940*86d7f5d3SJohn Marino static RILE *fd2RILE P((int,char const*,char const*,struct stat*));
941*86d7f5d3SJohn Marino static RILE *
942*86d7f5d3SJohn Marino fd2RILE(fd, name, type, status)
943*86d7f5d3SJohn Marino char const *type;
944*86d7f5d3SJohn Marino #endif
945*86d7f5d3SJohn Marino int fd;
946*86d7f5d3SJohn Marino char const *name;
947*86d7f5d3SJohn Marino register struct stat *status;
948*86d7f5d3SJohn Marino {
949*86d7f5d3SJohn Marino struct stat st;
950*86d7f5d3SJohn Marino
951*86d7f5d3SJohn Marino if (!status)
952*86d7f5d3SJohn Marino status = &st;
953*86d7f5d3SJohn Marino if (fstat(fd, status) != 0)
954*86d7f5d3SJohn Marino efaterror(name);
955*86d7f5d3SJohn Marino if (!S_ISREG(status->st_mode)) {
956*86d7f5d3SJohn Marino error("`%s' is not a regular file", name);
957*86d7f5d3SJohn Marino VOID close(fd);
958*86d7f5d3SJohn Marino errno = EINVAL;
959*86d7f5d3SJohn Marino return 0;
960*86d7f5d3SJohn Marino } else {
961*86d7f5d3SJohn Marino
962*86d7f5d3SJohn Marino # if !(large_memory && maps_memory)
963*86d7f5d3SJohn Marino FILE *stream;
964*86d7f5d3SJohn Marino if (!(stream = fdopen(fd, type)))
965*86d7f5d3SJohn Marino efaterror(name);
966*86d7f5d3SJohn Marino # endif
967*86d7f5d3SJohn Marino
968*86d7f5d3SJohn Marino # if !large_memory
969*86d7f5d3SJohn Marino return stream;
970*86d7f5d3SJohn Marino # else
971*86d7f5d3SJohn Marino # define RILES 3
972*86d7f5d3SJohn Marino {
973*86d7f5d3SJohn Marino static RILE rilebuf[RILES];
974*86d7f5d3SJohn Marino
975*86d7f5d3SJohn Marino register RILE *f;
976*86d7f5d3SJohn Marino size_t s = status->st_size;
977*86d7f5d3SJohn Marino
978*86d7f5d3SJohn Marino if (s != status->st_size)
979*86d7f5d3SJohn Marino faterror("%s: too large", name);
980*86d7f5d3SJohn Marino for (f = rilebuf; f->base; f++)
981*86d7f5d3SJohn Marino if (f == rilebuf+RILES)
982*86d7f5d3SJohn Marino faterror("too many RILEs");
983*86d7f5d3SJohn Marino # if maps_memory
984*86d7f5d3SJohn Marino f->deallocate = nothing_to_deallocate;
985*86d7f5d3SJohn Marino # endif
986*86d7f5d3SJohn Marino if (!s) {
987*86d7f5d3SJohn Marino static unsigned char nothing;
988*86d7f5d3SJohn Marino f->base = ¬hing; /* Any nonzero address will do. */
989*86d7f5d3SJohn Marino } else {
990*86d7f5d3SJohn Marino f->base = 0;
991*86d7f5d3SJohn Marino # if has_map_fd
992*86d7f5d3SJohn Marino map_fd(
993*86d7f5d3SJohn Marino fd, (vm_offset_t)0, (vm_address_t*) &f->base,
994*86d7f5d3SJohn Marino TRUE, (vm_size_t)s
995*86d7f5d3SJohn Marino );
996*86d7f5d3SJohn Marino f->deallocate = map_fd_deallocate;
997*86d7f5d3SJohn Marino # endif
998*86d7f5d3SJohn Marino # if has_mmap
999*86d7f5d3SJohn Marino if (!f->base) {
1000*86d7f5d3SJohn Marino catchmmapints();
1001*86d7f5d3SJohn Marino f->base = (unsigned char *) mmap(
1002*86d7f5d3SJohn Marino (char *)0, s, PROT_READ, MAP_SHARED,
1003*86d7f5d3SJohn Marino fd, (off_t)0
1004*86d7f5d3SJohn Marino );
1005*86d7f5d3SJohn Marino # ifndef MAP_FAILED
1006*86d7f5d3SJohn Marino # define MAP_FAILED (-1)
1007*86d7f5d3SJohn Marino # endif
1008*86d7f5d3SJohn Marino if (f->base == (unsigned char *) MAP_FAILED)
1009*86d7f5d3SJohn Marino f->base = 0;
1010*86d7f5d3SJohn Marino else {
1011*86d7f5d3SJohn Marino # if has_NFS && mmap_signal
1012*86d7f5d3SJohn Marino /*
1013*86d7f5d3SJohn Marino * On many hosts, the superuser
1014*86d7f5d3SJohn Marino * can mmap an NFS file it can't read.
1015*86d7f5d3SJohn Marino * So access the first page now, and print
1016*86d7f5d3SJohn Marino * a nice message if a bus error occurs.
1017*86d7f5d3SJohn Marino */
1018*86d7f5d3SJohn Marino readAccessFilenameBuffer(name, f->base);
1019*86d7f5d3SJohn Marino # endif
1020*86d7f5d3SJohn Marino }
1021*86d7f5d3SJohn Marino f->deallocate = mmap_deallocate;
1022*86d7f5d3SJohn Marino }
1023*86d7f5d3SJohn Marino # endif
1024*86d7f5d3SJohn Marino if (!f->base) {
1025*86d7f5d3SJohn Marino f->base = tnalloc(unsigned char, s);
1026*86d7f5d3SJohn Marino # if maps_memory
1027*86d7f5d3SJohn Marino {
1028*86d7f5d3SJohn Marino /*
1029*86d7f5d3SJohn Marino * We can't map the file into memory for some reason.
1030*86d7f5d3SJohn Marino * Read it into main memory all at once; this is
1031*86d7f5d3SJohn Marino * the simplest substitute for memory mapping.
1032*86d7f5d3SJohn Marino */
1033*86d7f5d3SJohn Marino char *bufptr = (char *) f->base;
1034*86d7f5d3SJohn Marino size_t bufsiz = s;
1035*86d7f5d3SJohn Marino do {
1036*86d7f5d3SJohn Marino ssize_t r = read(fd, bufptr, bufsiz);
1037*86d7f5d3SJohn Marino switch (r) {
1038*86d7f5d3SJohn Marino case -1:
1039*86d7f5d3SJohn Marino efaterror(name);
1040*86d7f5d3SJohn Marino
1041*86d7f5d3SJohn Marino case 0:
1042*86d7f5d3SJohn Marino /* The file must have shrunk! */
1043*86d7f5d3SJohn Marino status->st_size = s -= bufsiz;
1044*86d7f5d3SJohn Marino bufsiz = 0;
1045*86d7f5d3SJohn Marino break;
1046*86d7f5d3SJohn Marino
1047*86d7f5d3SJohn Marino default:
1048*86d7f5d3SJohn Marino bufptr += r;
1049*86d7f5d3SJohn Marino bufsiz -= r;
1050*86d7f5d3SJohn Marino break;
1051*86d7f5d3SJohn Marino }
1052*86d7f5d3SJohn Marino } while (bufsiz);
1053*86d7f5d3SJohn Marino if (lseek(fd, (off_t)0, SEEK_SET) == -1)
1054*86d7f5d3SJohn Marino efaterror(name);
1055*86d7f5d3SJohn Marino f->deallocate = read_deallocate;
1056*86d7f5d3SJohn Marino }
1057*86d7f5d3SJohn Marino # endif
1058*86d7f5d3SJohn Marino }
1059*86d7f5d3SJohn Marino }
1060*86d7f5d3SJohn Marino f->ptr = f->base;
1061*86d7f5d3SJohn Marino f->lim = f->base + s;
1062*86d7f5d3SJohn Marino f->fd = fd;
1063*86d7f5d3SJohn Marino # if !maps_memory
1064*86d7f5d3SJohn Marino f->readlim = f->base;
1065*86d7f5d3SJohn Marino f->stream = stream;
1066*86d7f5d3SJohn Marino # endif
1067*86d7f5d3SJohn Marino if_advise_access(s, f, MADV_SEQUENTIAL);
1068*86d7f5d3SJohn Marino return f;
1069*86d7f5d3SJohn Marino }
1070*86d7f5d3SJohn Marino # endif
1071*86d7f5d3SJohn Marino }
1072*86d7f5d3SJohn Marino }
1073*86d7f5d3SJohn Marino
1074*86d7f5d3SJohn Marino #if !maps_memory && large_memory
1075*86d7f5d3SJohn Marino int
Igetmore(f)1076*86d7f5d3SJohn Marino Igetmore(f)
1077*86d7f5d3SJohn Marino register RILE *f;
1078*86d7f5d3SJohn Marino {
1079*86d7f5d3SJohn Marino register fread_type r;
1080*86d7f5d3SJohn Marino register size_t s = f->lim - f->readlim;
1081*86d7f5d3SJohn Marino
1082*86d7f5d3SJohn Marino if (BUFSIZ < s)
1083*86d7f5d3SJohn Marino s = BUFSIZ;
1084*86d7f5d3SJohn Marino if (!(r = Fread(f->readlim, sizeof(*f->readlim), s, f->stream))) {
1085*86d7f5d3SJohn Marino testIerror(f->stream);
1086*86d7f5d3SJohn Marino f->lim = f->readlim; /* The file might have shrunk! */
1087*86d7f5d3SJohn Marino return 0;
1088*86d7f5d3SJohn Marino }
1089*86d7f5d3SJohn Marino f->readlim += r;
1090*86d7f5d3SJohn Marino return 1;
1091*86d7f5d3SJohn Marino }
1092*86d7f5d3SJohn Marino #endif
1093*86d7f5d3SJohn Marino
1094*86d7f5d3SJohn Marino #if has_madvise && has_mmap && large_memory
1095*86d7f5d3SJohn Marino void
advise_access(f,advice)1096*86d7f5d3SJohn Marino advise_access(f, advice)
1097*86d7f5d3SJohn Marino register RILE *f;
1098*86d7f5d3SJohn Marino int advice;
1099*86d7f5d3SJohn Marino {
1100*86d7f5d3SJohn Marino if (f->deallocate == mmap_deallocate)
1101*86d7f5d3SJohn Marino VOID madvise((char *)f->base, (size_t)(f->lim - f->base), advice);
1102*86d7f5d3SJohn Marino /* Don't worry if madvise fails; it's only advisory. */
1103*86d7f5d3SJohn Marino }
1104*86d7f5d3SJohn Marino #endif
1105*86d7f5d3SJohn Marino
1106*86d7f5d3SJohn Marino RILE *
1107*86d7f5d3SJohn Marino #if large_memory && maps_memory
I_open(name,status)1108*86d7f5d3SJohn Marino I_open(name, status)
1109*86d7f5d3SJohn Marino #else
1110*86d7f5d3SJohn Marino Iopen(name, type, status)
1111*86d7f5d3SJohn Marino char const *type;
1112*86d7f5d3SJohn Marino #endif
1113*86d7f5d3SJohn Marino char const *name;
1114*86d7f5d3SJohn Marino struct stat *status;
1115*86d7f5d3SJohn Marino /* Open NAME for reading, yield its descriptor, and set *STATUS. */
1116*86d7f5d3SJohn Marino {
1117*86d7f5d3SJohn Marino int fd = fdSafer(open(name, O_RDONLY
1118*86d7f5d3SJohn Marino # if OPEN_O_BINARY
1119*86d7f5d3SJohn Marino | (strchr(type,'b') ? OPEN_O_BINARY : 0)
1120*86d7f5d3SJohn Marino # endif
1121*86d7f5d3SJohn Marino ));
1122*86d7f5d3SJohn Marino
1123*86d7f5d3SJohn Marino if (fd < 0)
1124*86d7f5d3SJohn Marino return 0;
1125*86d7f5d3SJohn Marino # if large_memory && maps_memory
1126*86d7f5d3SJohn Marino return fd2_RILE(fd, name, status);
1127*86d7f5d3SJohn Marino # else
1128*86d7f5d3SJohn Marino return fd2RILE(fd, name, type, status);
1129*86d7f5d3SJohn Marino # endif
1130*86d7f5d3SJohn Marino }
1131*86d7f5d3SJohn Marino
1132*86d7f5d3SJohn Marino
1133*86d7f5d3SJohn Marino static int Oerrloop;
1134*86d7f5d3SJohn Marino
1135*86d7f5d3SJohn Marino void
Oerror()1136*86d7f5d3SJohn Marino Oerror()
1137*86d7f5d3SJohn Marino {
1138*86d7f5d3SJohn Marino if (Oerrloop)
1139*86d7f5d3SJohn Marino exiterr();
1140*86d7f5d3SJohn Marino Oerrloop = true;
1141*86d7f5d3SJohn Marino efaterror("output error");
1142*86d7f5d3SJohn Marino }
1143*86d7f5d3SJohn Marino
Ieof()1144*86d7f5d3SJohn Marino void Ieof() { fatserror("unexpected end of file"); }
Ierror()1145*86d7f5d3SJohn Marino void Ierror() { efaterror("input error"); }
testIerror(f)1146*86d7f5d3SJohn Marino void testIerror(f) FILE *f; { if (ferror(f)) Ierror(); }
testOerror(o)1147*86d7f5d3SJohn Marino void testOerror(o) FILE *o; { if (ferror(o)) Oerror(); }
1148*86d7f5d3SJohn Marino
Ifclose(f)1149*86d7f5d3SJohn Marino void Ifclose(f) RILE *f; { if (f && Iclose(f)!=0) Ierror(); }
Ofclose(f)1150*86d7f5d3SJohn Marino void Ofclose(f) FILE *f; { if (f && fclose(f)!=0) Oerror(); }
Izclose(p)1151*86d7f5d3SJohn Marino void Izclose(p) RILE **p; { Ifclose(*p); *p = 0; }
Ozclose(p)1152*86d7f5d3SJohn Marino void Ozclose(p) FILE **p; { Ofclose(*p); *p = 0; }
1153*86d7f5d3SJohn Marino
1154*86d7f5d3SJohn Marino #if !large_memory
1155*86d7f5d3SJohn Marino void
testIeof(f)1156*86d7f5d3SJohn Marino testIeof(f)
1157*86d7f5d3SJohn Marino FILE *f;
1158*86d7f5d3SJohn Marino {
1159*86d7f5d3SJohn Marino testIerror(f);
1160*86d7f5d3SJohn Marino if (feof(f))
1161*86d7f5d3SJohn Marino Ieof();
1162*86d7f5d3SJohn Marino }
Irewind(f)1163*86d7f5d3SJohn Marino void Irewind(f) FILE *f; { if (fseek(f,0L,SEEK_SET) != 0) Ierror(); }
1164*86d7f5d3SJohn Marino #endif
1165*86d7f5d3SJohn Marino
Orewind(f)1166*86d7f5d3SJohn Marino void Orewind(f) FILE *f; { if (fseek(f,0L,SEEK_SET) != 0) Oerror(); }
1167*86d7f5d3SJohn Marino
aflush(f)1168*86d7f5d3SJohn Marino void aflush(f) FILE *f; { if (fflush(f) != 0) Oerror(); }
eflush()1169*86d7f5d3SJohn Marino void eflush() { if (fflush(stderr)!=0 && !Oerrloop) Oerror(); }
oflush()1170*86d7f5d3SJohn Marino void oflush()
1171*86d7f5d3SJohn Marino {
1172*86d7f5d3SJohn Marino if (fflush(workstdout ? workstdout : stdout) != 0 && !Oerrloop)
1173*86d7f5d3SJohn Marino Oerror();
1174*86d7f5d3SJohn Marino }
1175*86d7f5d3SJohn Marino
1176*86d7f5d3SJohn Marino void
fatcleanup(already_newline)1177*86d7f5d3SJohn Marino fatcleanup(already_newline)
1178*86d7f5d3SJohn Marino int already_newline;
1179*86d7f5d3SJohn Marino {
1180*86d7f5d3SJohn Marino VOID fprintf(stderr, already_newline+"\n%s aborted\n", cmdid);
1181*86d7f5d3SJohn Marino exiterr();
1182*86d7f5d3SJohn Marino }
1183*86d7f5d3SJohn Marino
1184*86d7f5d3SJohn Marino static void
startsay(s,t)1185*86d7f5d3SJohn Marino startsay(s, t)
1186*86d7f5d3SJohn Marino const char *s, *t;
1187*86d7f5d3SJohn Marino {
1188*86d7f5d3SJohn Marino oflush();
1189*86d7f5d3SJohn Marino if (s)
1190*86d7f5d3SJohn Marino aprintf(stderr, "%s: %s: %s", cmdid, s, t);
1191*86d7f5d3SJohn Marino else
1192*86d7f5d3SJohn Marino aprintf(stderr, "%s: %s", cmdid, t);
1193*86d7f5d3SJohn Marino }
1194*86d7f5d3SJohn Marino
1195*86d7f5d3SJohn Marino static void
fatsay(s)1196*86d7f5d3SJohn Marino fatsay(s)
1197*86d7f5d3SJohn Marino char const *s;
1198*86d7f5d3SJohn Marino {
1199*86d7f5d3SJohn Marino startsay(s, "");
1200*86d7f5d3SJohn Marino }
1201*86d7f5d3SJohn Marino
1202*86d7f5d3SJohn Marino static void
errsay(s)1203*86d7f5d3SJohn Marino errsay(s)
1204*86d7f5d3SJohn Marino char const *s;
1205*86d7f5d3SJohn Marino {
1206*86d7f5d3SJohn Marino fatsay(s);
1207*86d7f5d3SJohn Marino nerror++;
1208*86d7f5d3SJohn Marino }
1209*86d7f5d3SJohn Marino
1210*86d7f5d3SJohn Marino static void
warnsay(s)1211*86d7f5d3SJohn Marino warnsay(s)
1212*86d7f5d3SJohn Marino char const *s;
1213*86d7f5d3SJohn Marino {
1214*86d7f5d3SJohn Marino startsay(s, "warning: ");
1215*86d7f5d3SJohn Marino }
1216*86d7f5d3SJohn Marino
eerror(s)1217*86d7f5d3SJohn Marino void eerror(s) char const *s; { enerror(errno,s); }
1218*86d7f5d3SJohn Marino
1219*86d7f5d3SJohn Marino void
enerror(e,s)1220*86d7f5d3SJohn Marino enerror(e,s)
1221*86d7f5d3SJohn Marino int e;
1222*86d7f5d3SJohn Marino char const *s;
1223*86d7f5d3SJohn Marino {
1224*86d7f5d3SJohn Marino errsay((char const*)0);
1225*86d7f5d3SJohn Marino errno = e;
1226*86d7f5d3SJohn Marino perror(s);
1227*86d7f5d3SJohn Marino eflush();
1228*86d7f5d3SJohn Marino }
1229*86d7f5d3SJohn Marino
efaterror(s)1230*86d7f5d3SJohn Marino void efaterror(s) char const *s; { enfaterror(errno,s); }
1231*86d7f5d3SJohn Marino
1232*86d7f5d3SJohn Marino void
enfaterror(e,s)1233*86d7f5d3SJohn Marino enfaterror(e,s)
1234*86d7f5d3SJohn Marino int e;
1235*86d7f5d3SJohn Marino char const *s;
1236*86d7f5d3SJohn Marino {
1237*86d7f5d3SJohn Marino fatsay((char const*)0);
1238*86d7f5d3SJohn Marino errno = e;
1239*86d7f5d3SJohn Marino perror(s);
1240*86d7f5d3SJohn Marino fatcleanup(true);
1241*86d7f5d3SJohn Marino }
1242*86d7f5d3SJohn Marino
1243*86d7f5d3SJohn Marino #if has_prototypes
1244*86d7f5d3SJohn Marino void
error(char const * format,...)1245*86d7f5d3SJohn Marino error(char const *format,...)
1246*86d7f5d3SJohn Marino #else
1247*86d7f5d3SJohn Marino /*VARARGS1*/ void error(format, va_alist) char const *format; va_dcl
1248*86d7f5d3SJohn Marino #endif
1249*86d7f5d3SJohn Marino /* non-fatal error */
1250*86d7f5d3SJohn Marino {
1251*86d7f5d3SJohn Marino va_list args;
1252*86d7f5d3SJohn Marino errsay((char const*)0);
1253*86d7f5d3SJohn Marino vararg_start(args, format);
1254*86d7f5d3SJohn Marino fvfprintf(stderr, format, args);
1255*86d7f5d3SJohn Marino va_end(args);
1256*86d7f5d3SJohn Marino afputc('\n',stderr);
1257*86d7f5d3SJohn Marino eflush();
1258*86d7f5d3SJohn Marino }
1259*86d7f5d3SJohn Marino
1260*86d7f5d3SJohn Marino #if has_prototypes
1261*86d7f5d3SJohn Marino void
rcserror(char const * format,...)1262*86d7f5d3SJohn Marino rcserror(char const *format,...)
1263*86d7f5d3SJohn Marino #else
1264*86d7f5d3SJohn Marino /*VARARGS1*/ void rcserror(format, va_alist) char const *format; va_dcl
1265*86d7f5d3SJohn Marino #endif
1266*86d7f5d3SJohn Marino /* non-fatal RCS file error */
1267*86d7f5d3SJohn Marino {
1268*86d7f5d3SJohn Marino va_list args;
1269*86d7f5d3SJohn Marino errsay(RCSname);
1270*86d7f5d3SJohn Marino vararg_start(args, format);
1271*86d7f5d3SJohn Marino fvfprintf(stderr, format, args);
1272*86d7f5d3SJohn Marino va_end(args);
1273*86d7f5d3SJohn Marino afputc('\n',stderr);
1274*86d7f5d3SJohn Marino eflush();
1275*86d7f5d3SJohn Marino }
1276*86d7f5d3SJohn Marino
1277*86d7f5d3SJohn Marino #if has_prototypes
1278*86d7f5d3SJohn Marino void
workerror(char const * format,...)1279*86d7f5d3SJohn Marino workerror(char const *format,...)
1280*86d7f5d3SJohn Marino #else
1281*86d7f5d3SJohn Marino /*VARARGS1*/ void workerror(format, va_alist) char const *format; va_dcl
1282*86d7f5d3SJohn Marino #endif
1283*86d7f5d3SJohn Marino /* non-fatal working file error */
1284*86d7f5d3SJohn Marino {
1285*86d7f5d3SJohn Marino va_list args;
1286*86d7f5d3SJohn Marino errsay(workname);
1287*86d7f5d3SJohn Marino vararg_start(args, format);
1288*86d7f5d3SJohn Marino fvfprintf(stderr, format, args);
1289*86d7f5d3SJohn Marino va_end(args);
1290*86d7f5d3SJohn Marino afputc('\n',stderr);
1291*86d7f5d3SJohn Marino eflush();
1292*86d7f5d3SJohn Marino }
1293*86d7f5d3SJohn Marino
1294*86d7f5d3SJohn Marino #if has_prototypes
1295*86d7f5d3SJohn Marino void
fatserror(char const * format,...)1296*86d7f5d3SJohn Marino fatserror(char const *format,...)
1297*86d7f5d3SJohn Marino #else
1298*86d7f5d3SJohn Marino /*VARARGS1*/ void
1299*86d7f5d3SJohn Marino fatserror(format, va_alist) char const *format; va_dcl
1300*86d7f5d3SJohn Marino #endif
1301*86d7f5d3SJohn Marino /* fatal RCS file syntax error */
1302*86d7f5d3SJohn Marino {
1303*86d7f5d3SJohn Marino va_list args;
1304*86d7f5d3SJohn Marino oflush();
1305*86d7f5d3SJohn Marino VOID fprintf(stderr, "%s: %s:%ld: ", cmdid, RCSname, rcsline);
1306*86d7f5d3SJohn Marino vararg_start(args, format);
1307*86d7f5d3SJohn Marino fvfprintf(stderr, format, args);
1308*86d7f5d3SJohn Marino va_end(args);
1309*86d7f5d3SJohn Marino fatcleanup(false);
1310*86d7f5d3SJohn Marino }
1311*86d7f5d3SJohn Marino
1312*86d7f5d3SJohn Marino #if has_prototypes
1313*86d7f5d3SJohn Marino void
faterror(char const * format,...)1314*86d7f5d3SJohn Marino faterror(char const *format,...)
1315*86d7f5d3SJohn Marino #else
1316*86d7f5d3SJohn Marino /*VARARGS1*/ void faterror(format, va_alist)
1317*86d7f5d3SJohn Marino char const *format; va_dcl
1318*86d7f5d3SJohn Marino #endif
1319*86d7f5d3SJohn Marino /* fatal error, terminates program after cleanup */
1320*86d7f5d3SJohn Marino {
1321*86d7f5d3SJohn Marino va_list args;
1322*86d7f5d3SJohn Marino fatsay((char const*)0);
1323*86d7f5d3SJohn Marino vararg_start(args, format);
1324*86d7f5d3SJohn Marino fvfprintf(stderr, format, args);
1325*86d7f5d3SJohn Marino va_end(args);
1326*86d7f5d3SJohn Marino fatcleanup(false);
1327*86d7f5d3SJohn Marino }
1328*86d7f5d3SJohn Marino
1329*86d7f5d3SJohn Marino #if has_prototypes
1330*86d7f5d3SJohn Marino void
rcsfaterror(char const * format,...)1331*86d7f5d3SJohn Marino rcsfaterror(char const *format,...)
1332*86d7f5d3SJohn Marino #else
1333*86d7f5d3SJohn Marino /*VARARGS1*/ void rcsfaterror(format, va_alist)
1334*86d7f5d3SJohn Marino char const *format; va_dcl
1335*86d7f5d3SJohn Marino #endif
1336*86d7f5d3SJohn Marino /* fatal RCS file error, terminates program after cleanup */
1337*86d7f5d3SJohn Marino {
1338*86d7f5d3SJohn Marino va_list args;
1339*86d7f5d3SJohn Marino fatsay(RCSname);
1340*86d7f5d3SJohn Marino vararg_start(args, format);
1341*86d7f5d3SJohn Marino fvfprintf(stderr, format, args);
1342*86d7f5d3SJohn Marino va_end(args);
1343*86d7f5d3SJohn Marino fatcleanup(false);
1344*86d7f5d3SJohn Marino }
1345*86d7f5d3SJohn Marino
1346*86d7f5d3SJohn Marino #if has_prototypes
1347*86d7f5d3SJohn Marino void
warn(char const * format,...)1348*86d7f5d3SJohn Marino warn(char const *format,...)
1349*86d7f5d3SJohn Marino #else
1350*86d7f5d3SJohn Marino /*VARARGS1*/ void warn(format, va_alist) char const *format; va_dcl
1351*86d7f5d3SJohn Marino #endif
1352*86d7f5d3SJohn Marino /* warning */
1353*86d7f5d3SJohn Marino {
1354*86d7f5d3SJohn Marino va_list args;
1355*86d7f5d3SJohn Marino if (!quietflag) {
1356*86d7f5d3SJohn Marino warnsay((char *)0);
1357*86d7f5d3SJohn Marino vararg_start(args, format);
1358*86d7f5d3SJohn Marino fvfprintf(stderr, format, args);
1359*86d7f5d3SJohn Marino va_end(args);
1360*86d7f5d3SJohn Marino afputc('\n', stderr);
1361*86d7f5d3SJohn Marino eflush();
1362*86d7f5d3SJohn Marino }
1363*86d7f5d3SJohn Marino }
1364*86d7f5d3SJohn Marino
1365*86d7f5d3SJohn Marino #if has_prototypes
1366*86d7f5d3SJohn Marino void
rcswarn(char const * format,...)1367*86d7f5d3SJohn Marino rcswarn(char const *format,...)
1368*86d7f5d3SJohn Marino #else
1369*86d7f5d3SJohn Marino /*VARARGS1*/ void rcswarn(format, va_alist) char const *format; va_dcl
1370*86d7f5d3SJohn Marino #endif
1371*86d7f5d3SJohn Marino /* RCS file warning */
1372*86d7f5d3SJohn Marino {
1373*86d7f5d3SJohn Marino va_list args;
1374*86d7f5d3SJohn Marino if (!quietflag) {
1375*86d7f5d3SJohn Marino warnsay(RCSname);
1376*86d7f5d3SJohn Marino vararg_start(args, format);
1377*86d7f5d3SJohn Marino fvfprintf(stderr, format, args);
1378*86d7f5d3SJohn Marino va_end(args);
1379*86d7f5d3SJohn Marino afputc('\n', stderr);
1380*86d7f5d3SJohn Marino eflush();
1381*86d7f5d3SJohn Marino }
1382*86d7f5d3SJohn Marino }
1383*86d7f5d3SJohn Marino
1384*86d7f5d3SJohn Marino #if has_prototypes
1385*86d7f5d3SJohn Marino void
workwarn(char const * format,...)1386*86d7f5d3SJohn Marino workwarn(char const *format,...)
1387*86d7f5d3SJohn Marino #else
1388*86d7f5d3SJohn Marino /*VARARGS1*/ void workwarn(format, va_alist) char const *format; va_dcl
1389*86d7f5d3SJohn Marino #endif
1390*86d7f5d3SJohn Marino /* working file warning */
1391*86d7f5d3SJohn Marino {
1392*86d7f5d3SJohn Marino va_list args;
1393*86d7f5d3SJohn Marino if (!quietflag) {
1394*86d7f5d3SJohn Marino warnsay(workname);
1395*86d7f5d3SJohn Marino vararg_start(args, format);
1396*86d7f5d3SJohn Marino fvfprintf(stderr, format, args);
1397*86d7f5d3SJohn Marino va_end(args);
1398*86d7f5d3SJohn Marino afputc('\n', stderr);
1399*86d7f5d3SJohn Marino eflush();
1400*86d7f5d3SJohn Marino }
1401*86d7f5d3SJohn Marino }
1402*86d7f5d3SJohn Marino
1403*86d7f5d3SJohn Marino void
redefined(c)1404*86d7f5d3SJohn Marino redefined(c)
1405*86d7f5d3SJohn Marino int c;
1406*86d7f5d3SJohn Marino {
1407*86d7f5d3SJohn Marino warn("redefinition of -%c option", c);
1408*86d7f5d3SJohn Marino }
1409*86d7f5d3SJohn Marino
1410*86d7f5d3SJohn Marino #if has_prototypes
1411*86d7f5d3SJohn Marino void
diagnose(char const * format,...)1412*86d7f5d3SJohn Marino diagnose(char const *format,...)
1413*86d7f5d3SJohn Marino #else
1414*86d7f5d3SJohn Marino /*VARARGS1*/ void diagnose(format, va_alist) char const *format; va_dcl
1415*86d7f5d3SJohn Marino #endif
1416*86d7f5d3SJohn Marino /* prints a diagnostic message */
1417*86d7f5d3SJohn Marino /* Unlike the other routines, it does not append a newline. */
1418*86d7f5d3SJohn Marino /* This lets some callers suppress the newline, and is faster */
1419*86d7f5d3SJohn Marino /* in implementations that flush stderr just at the end of each printf. */
1420*86d7f5d3SJohn Marino {
1421*86d7f5d3SJohn Marino va_list args;
1422*86d7f5d3SJohn Marino if (!quietflag) {
1423*86d7f5d3SJohn Marino oflush();
1424*86d7f5d3SJohn Marino vararg_start(args, format);
1425*86d7f5d3SJohn Marino fvfprintf(stderr, format, args);
1426*86d7f5d3SJohn Marino va_end(args);
1427*86d7f5d3SJohn Marino eflush();
1428*86d7f5d3SJohn Marino }
1429*86d7f5d3SJohn Marino }
1430*86d7f5d3SJohn Marino
1431*86d7f5d3SJohn Marino
1432*86d7f5d3SJohn Marino
1433*86d7f5d3SJohn Marino void
afputc(c,f)1434*86d7f5d3SJohn Marino afputc(c, f)
1435*86d7f5d3SJohn Marino /* afputc(c,f); acts like aputc_(c,f) but is smaller and slower. */
1436*86d7f5d3SJohn Marino int c;
1437*86d7f5d3SJohn Marino register FILE *f;
1438*86d7f5d3SJohn Marino {
1439*86d7f5d3SJohn Marino aputc_(c,f)
1440*86d7f5d3SJohn Marino }
1441*86d7f5d3SJohn Marino
1442*86d7f5d3SJohn Marino
1443*86d7f5d3SJohn Marino void
aputs(s,iop)1444*86d7f5d3SJohn Marino aputs(s, iop)
1445*86d7f5d3SJohn Marino char const *s;
1446*86d7f5d3SJohn Marino FILE *iop;
1447*86d7f5d3SJohn Marino /* Function: Put string s on file iop, abort on error.
1448*86d7f5d3SJohn Marino */
1449*86d7f5d3SJohn Marino {
1450*86d7f5d3SJohn Marino #if has_fputs
1451*86d7f5d3SJohn Marino if (fputs(s, iop) < 0)
1452*86d7f5d3SJohn Marino Oerror();
1453*86d7f5d3SJohn Marino #else
1454*86d7f5d3SJohn Marino awrite(s, strlen(s), iop);
1455*86d7f5d3SJohn Marino #endif
1456*86d7f5d3SJohn Marino }
1457*86d7f5d3SJohn Marino
1458*86d7f5d3SJohn Marino
1459*86d7f5d3SJohn Marino
1460*86d7f5d3SJohn Marino void
1461*86d7f5d3SJohn Marino #if has_prototypes
fvfprintf(FILE * stream,char const * format,va_list args)1462*86d7f5d3SJohn Marino fvfprintf(FILE *stream, char const *format, va_list args)
1463*86d7f5d3SJohn Marino #else
1464*86d7f5d3SJohn Marino fvfprintf(stream,format,args) FILE *stream; char *format; va_list args;
1465*86d7f5d3SJohn Marino #endif
1466*86d7f5d3SJohn Marino /* like vfprintf, except abort program on error */
1467*86d7f5d3SJohn Marino {
1468*86d7f5d3SJohn Marino #if has_vfprintf
1469*86d7f5d3SJohn Marino if (vfprintf(stream, format, args) < 0)
1470*86d7f5d3SJohn Marino Oerror();
1471*86d7f5d3SJohn Marino #else
1472*86d7f5d3SJohn Marino # if has__doprintf
1473*86d7f5d3SJohn Marino _doprintf(stream, format, args);
1474*86d7f5d3SJohn Marino # else
1475*86d7f5d3SJohn Marino # if has__doprnt
1476*86d7f5d3SJohn Marino _doprnt(format, args, stream);
1477*86d7f5d3SJohn Marino # else
1478*86d7f5d3SJohn Marino int *a = (int *)args;
1479*86d7f5d3SJohn Marino VOID fprintf(stream, format,
1480*86d7f5d3SJohn Marino a[0], a[1], a[2], a[3], a[4],
1481*86d7f5d3SJohn Marino a[5], a[6], a[7], a[8], a[9]
1482*86d7f5d3SJohn Marino );
1483*86d7f5d3SJohn Marino # endif
1484*86d7f5d3SJohn Marino # endif
1485*86d7f5d3SJohn Marino if (ferror(stream))
1486*86d7f5d3SJohn Marino Oerror();
1487*86d7f5d3SJohn Marino #endif
1488*86d7f5d3SJohn Marino }
1489*86d7f5d3SJohn Marino
1490*86d7f5d3SJohn Marino #if has_prototypes
1491*86d7f5d3SJohn Marino void
aprintf(FILE * iop,char const * fmt,...)1492*86d7f5d3SJohn Marino aprintf(FILE *iop, char const *fmt, ...)
1493*86d7f5d3SJohn Marino #else
1494*86d7f5d3SJohn Marino /*VARARGS2*/ void
1495*86d7f5d3SJohn Marino aprintf(iop, fmt, va_alist)
1496*86d7f5d3SJohn Marino FILE *iop;
1497*86d7f5d3SJohn Marino char const *fmt;
1498*86d7f5d3SJohn Marino va_dcl
1499*86d7f5d3SJohn Marino #endif
1500*86d7f5d3SJohn Marino /* Function: formatted output. Same as fprintf in stdio,
1501*86d7f5d3SJohn Marino * but aborts program on error
1502*86d7f5d3SJohn Marino */
1503*86d7f5d3SJohn Marino {
1504*86d7f5d3SJohn Marino va_list ap;
1505*86d7f5d3SJohn Marino vararg_start(ap, fmt);
1506*86d7f5d3SJohn Marino fvfprintf(iop, fmt, ap);
1507*86d7f5d3SJohn Marino va_end(ap);
1508*86d7f5d3SJohn Marino }
1509*86d7f5d3SJohn Marino
1510*86d7f5d3SJohn Marino
1511*86d7f5d3SJohn Marino
1512*86d7f5d3SJohn Marino #ifdef LEXDB
1513*86d7f5d3SJohn Marino /* test program reading a stream of lexemes and printing the tokens.
1514*86d7f5d3SJohn Marino */
1515*86d7f5d3SJohn Marino
1516*86d7f5d3SJohn Marino
1517*86d7f5d3SJohn Marino
1518*86d7f5d3SJohn Marino int
main(argc,argv)1519*86d7f5d3SJohn Marino main(argc,argv)
1520*86d7f5d3SJohn Marino int argc; char * argv[];
1521*86d7f5d3SJohn Marino {
1522*86d7f5d3SJohn Marino cmdid="lextest";
1523*86d7f5d3SJohn Marino if (argc<2) {
1524*86d7f5d3SJohn Marino aputs("No input file\n",stderr);
1525*86d7f5d3SJohn Marino exitmain(EXIT_FAILURE);
1526*86d7f5d3SJohn Marino }
1527*86d7f5d3SJohn Marino if (!(finptr=Iopen(argv[1], FOPEN_R, (struct stat*)0))) {
1528*86d7f5d3SJohn Marino faterror("can't open input file %s",argv[1]);
1529*86d7f5d3SJohn Marino }
1530*86d7f5d3SJohn Marino Lexinit();
1531*86d7f5d3SJohn Marino while (!eoflex()) {
1532*86d7f5d3SJohn Marino switch (nexttok) {
1533*86d7f5d3SJohn Marino
1534*86d7f5d3SJohn Marino case ID:
1535*86d7f5d3SJohn Marino VOID printf("ID: %s",NextString);
1536*86d7f5d3SJohn Marino break;
1537*86d7f5d3SJohn Marino
1538*86d7f5d3SJohn Marino case NUM:
1539*86d7f5d3SJohn Marino if (hshenter)
1540*86d7f5d3SJohn Marino VOID printf("NUM: %s, index: %d",nexthsh->num, nexthsh-hshtab);
1541*86d7f5d3SJohn Marino else
1542*86d7f5d3SJohn Marino VOID printf("NUM, unentered: %s",NextString);
1543*86d7f5d3SJohn Marino hshenter = !hshenter; /*alternate between dates and numbers*/
1544*86d7f5d3SJohn Marino break;
1545*86d7f5d3SJohn Marino
1546*86d7f5d3SJohn Marino case COLON:
1547*86d7f5d3SJohn Marino VOID printf("COLON"); break;
1548*86d7f5d3SJohn Marino
1549*86d7f5d3SJohn Marino case SEMI:
1550*86d7f5d3SJohn Marino VOID printf("SEMI"); break;
1551*86d7f5d3SJohn Marino
1552*86d7f5d3SJohn Marino case STRING:
1553*86d7f5d3SJohn Marino readstring();
1554*86d7f5d3SJohn Marino VOID printf("STRING"); break;
1555*86d7f5d3SJohn Marino
1556*86d7f5d3SJohn Marino case UNKN:
1557*86d7f5d3SJohn Marino VOID printf("UNKN"); break;
1558*86d7f5d3SJohn Marino
1559*86d7f5d3SJohn Marino default:
1560*86d7f5d3SJohn Marino VOID printf("DEFAULT"); break;
1561*86d7f5d3SJohn Marino }
1562*86d7f5d3SJohn Marino VOID printf(" | ");
1563*86d7f5d3SJohn Marino nextlex();
1564*86d7f5d3SJohn Marino }
1565*86d7f5d3SJohn Marino exitmain(EXIT_SUCCESS);
1566*86d7f5d3SJohn Marino }
1567*86d7f5d3SJohn Marino
exiterr()1568*86d7f5d3SJohn Marino void exiterr() { _exit(EXIT_FAILURE); }
1569*86d7f5d3SJohn Marino
1570*86d7f5d3SJohn Marino
1571*86d7f5d3SJohn Marino #endif
1572