source: vendor/bash/3.1-p17/mksyntax.c

Last change on this file was 3231, checked in by bird, 18 years ago

eol style.

  • Property svn:eol-style set to native
File size: 6.9 KB
Line 
1/*
2 * mksyntax.c - construct shell syntax table for fast char attribute lookup.
3 */
4
5/* Copyright (C) 2000-2002 Free Software Foundation, Inc.
6
7 This file is part of GNU Bash, the Bourne Again SHell.
8
9 Bash is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
12 version.
13
14 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License along
20 with Bash; see the file COPYING. If not, write to the Free Software
21 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
22
23#include "config.h"
24
25#include <stdio.h>
26#include "bashansi.h"
27#include "chartypes.h"
28#include <errno.h>
29
30#ifdef HAVE_UNISTD_H
31# include <unistd.h>
32#endif
33
34#include "syntax.h"
35
36extern int optind;
37extern char *optarg;
38
39#ifndef errno
40extern int errno;
41#endif
42
43#ifndef HAVE_STRERROR
44extern char *strerror();
45#endif
46
47struct wordflag {
48 int flag;
49 char *fstr;
50} wordflags[] = {
51 { CWORD, "CWORD" },
52 { CSHMETA, "CSHMETA" },
53 { CSHBRK, "CSHBRK" },
54 { CBACKQ, "CBACKQ" },
55 { CQUOTE, "CQUOTE" },
56 { CSPECL, "CSPECL" },
57 { CEXP, "CEXP" },
58 { CBSDQUOTE, "CBSDQUOTE" },
59 { CBSHDOC, "CBSHDOC" },
60 { CGLOB, "CGLOB" },
61 { CXGLOB, "CXGLOB" },
62 { CXQUOTE, "CXQUOTE" },
63 { CSPECVAR, "CSPECVAR" },
64 { CSUBSTOP, "CSUBSTOP" },
65};
66
67#define N_WFLAGS (sizeof (wordflags) / sizeof (wordflags[0]))
68#define SYNSIZE 256
69
70int lsyntax[SYNSIZE];
71int debug;
72char *progname;
73
74char preamble[] = "\
75/*\n\
76 * This file was generated by mksyntax. DO NOT EDIT.\n\
77 */\n\
78\n";
79
80char includes[] = "\
81#include \"config.h\"\n\
82#include \"stdc.h\"\n\
83#include \"syntax.h\"\n\n";
84
85static void
86usage()
87{
88 fprintf (stderr, "%s: usage: %s [-d] [-o filename]\n", progname, progname);
89 exit (2);
90}
91
92#ifdef INCLUDE_UNUSED
93static int
94getcflag (s)
95 char *s;
96{
97 int i;
98
99 for (i = 0; i < N_WFLAGS; i++)
100 if (strcmp (s, wordflags[i].fstr) == 0)
101 return wordflags[i].flag;
102 return -1;
103}
104#endif
105
106static char *
107cdesc (i)
108 int i;
109{
110 static char xbuf[16];
111
112 if (i == ' ')
113 return "SPC";
114 else if (ISPRINT (i))
115 {
116 xbuf[0] = i;
117 xbuf[1] = '\0';
118 return (xbuf);
119 }
120 else if (i == CTLESC)
121 return "CTLESC";
122 else if (i == CTLNUL)
123 return "CTLNUL";
124 else if (i == '\033') /* ASCII */
125 return "ESC";
126
127 xbuf[0] = '\\';
128 xbuf[2] = '\0';
129
130 switch (i)
131 {
132#ifdef __STDC__
133 case '\a': xbuf[1] = 'a'; break;
134 case '\v': xbuf[1] = 'v'; break;
135#else
136 case '\007': xbuf[1] = 'a'; break;
137 case 0x0B: xbuf[1] = 'v'; break;
138#endif
139 case '\b': xbuf[1] = 'b'; break;
140 case '\f': xbuf[1] = 'f'; break;
141 case '\n': xbuf[1] = 'n'; break;
142 case '\r': xbuf[1] = 'r'; break;
143 case '\t': xbuf[1] = 't'; break;
144 default: sprintf (xbuf, "%d", i); break;
145 }
146
147 return xbuf;
148}
149
150static char *
151getcstr (f)
152 int f;
153{
154 int i;
155
156 for (i = 0; i < N_WFLAGS; i++)
157 if (f == wordflags[i].flag)
158 return (wordflags[i].fstr);
159 return ((char *)NULL);
160}
161
162static void
163addcstr (str, flag)
164 char *str;
165 int flag;
166{
167 char *s, *fstr;
168 unsigned char uc;
169
170 for (s = str; s && *s; s++)
171 {
172 uc = *s;
173
174 if (debug)
175 {
176 fstr = getcstr (flag);
177 fprintf(stderr, "added %s for character %s\n", fstr, cdesc(uc));
178 }
179
180 lsyntax[uc] |= flag;
181 }
182}
183
184static void
185addcchar (c, flag)
186 unsigned char c;
187 int flag;
188{
189 char *fstr;
190
191 if (debug)
192 {
193 fstr = getcstr (flag);
194 fprintf (stderr, "added %s for character %s\n", fstr, cdesc(c));
195 }
196 lsyntax[c] |= flag;
197}
198
199/* load up the correct flag values in lsyntax */
200static void
201load_lsyntax ()
202{
203 /* shell metacharacters */
204 addcstr (shell_meta_chars, CSHMETA);
205
206 /* shell word break characters */
207 addcstr (shell_break_chars, CSHBRK);
208
209 addcchar ('`', CBACKQ);
210
211 addcstr (shell_quote_chars, CQUOTE);
212
213 addcchar (CTLESC, CSPECL);
214 addcchar (CTLNUL, CSPECL);
215
216 addcstr (shell_exp_chars, CEXP);
217
218 addcstr (slashify_in_quotes, CBSDQUOTE);
219 addcstr (slashify_in_here_document, CBSHDOC);
220
221 addcstr (shell_glob_chars, CGLOB);
222
223#if defined (EXTENDED_GLOB)
224 addcstr (ext_glob_chars, CXGLOB);
225#endif
226
227 addcstr (shell_quote_chars, CXQUOTE);
228 addcchar ('\\', CXQUOTE);
229
230 addcstr ("@*#?-$!", CSPECVAR); /* omits $0...$9 and $_ */
231
232 addcstr ("-=?+", CSUBSTOP); /* OP in ${paramOPword} */
233}
234
235static void
236dump_lflags (fp, ind)
237 FILE *fp;
238 int ind;
239{
240 int xflags, first, i;
241
242 xflags = lsyntax[ind];
243 first = 1;
244
245 if (xflags == 0)
246 fputs (wordflags[0].fstr, fp);
247 else
248 {
249 for (i = 1; i < N_WFLAGS; i++)
250 if (xflags & wordflags[i].flag)
251 {
252 if (first)
253 first = 0;
254 else
255 putc ('|', fp);
256 fputs (wordflags[i].fstr, fp);
257 }
258 }
259}
260
261static void
262wcomment (fp, i)
263 FILE *fp;
264 int i;
265{
266 fputs ("\t\t/* ", fp);
267
268 fprintf (fp, "%s", cdesc(i));
269
270 fputs (" */", fp);
271}
272
273static void
274dump_lsyntax (fp)
275 FILE *fp;
276{
277 int i;
278
279 fprintf (fp, "int sh_syntabsiz = %d;\n", SYNSIZE);
280 fprintf (fp, "int sh_syntaxtab[%d] = {\n", SYNSIZE);
281
282 for (i = 0; i < SYNSIZE; i++)
283 {
284 putc ('\t', fp);
285 dump_lflags (fp, i);
286 putc (',', fp);
287 wcomment (fp, i);
288 putc ('\n', fp);
289 }
290
291 fprintf (fp, "};\n");
292}
293
294int
295main(argc, argv)
296 int argc;
297 char **argv;
298{
299 int opt, i;
300 char *filename;
301 FILE *fp;
302
303 if ((progname = strrchr (argv[0], '/')) == 0)
304 progname = argv[0];
305 else
306 progname++;
307
308 filename = (char *)NULL;
309 debug = 0;
310
311 while ((opt = getopt (argc, argv, "do:")) != EOF)
312 {
313 switch (opt)
314 {
315 case 'd':
316 debug = 1;
317 break;
318 case 'o':
319 filename = optarg;
320 break;
321 default:
322 usage();
323 }
324 }
325
326 argc -= optind;
327 argv += optind;
328
329 if (filename)
330 {
331 fp = fopen (filename, "w");
332 if (fp == 0)
333 {
334 fprintf (stderr, "%s: %s: cannot open: %s\n", progname, filename, strerror(errno));
335 exit (1);
336 }
337 }
338 else
339 {
340 filename = "stdout";
341 fp = stdout;
342 }
343
344
345 for (i = 0; i < SYNSIZE; i++)
346 lsyntax[i] = CWORD;
347
348 load_lsyntax ();
349
350 fprintf (fp, "%s\n", preamble);
351 fprintf (fp, "%s\n", includes);
352
353 dump_lsyntax (fp);
354
355 if (fp != stdout)
356 fclose (fp);
357 exit (0);
358}
359
360
361#if !defined (HAVE_STRERROR)
362
363#include <bashtypes.h>
364#ifndef _MINIX
365# include <sys/param.h>
366#endif
367
368#if defined (HAVE_UNISTD_H)
369# include <unistd.h>
370#endif
371
372/* Return a string corresponding to the error number E. From
373 the ANSI C spec. */
374#if defined (strerror)
375# undef strerror
376#endif
377
378char *
379strerror (e)
380 int e;
381{
382 static char emsg[40];
383#if defined (HAVE_SYS_ERRLIST)
384 extern int sys_nerr;
385 extern char *sys_errlist[];
386
387 if (e > 0 && e < sys_nerr)
388 return (sys_errlist[e]);
389 else
390#endif /* HAVE_SYS_ERRLIST */
391 {
392 sprintf (emsg, "Unknown system error %d", e);
393 return (&emsg[0]);
394 }
395}
396#endif /* HAVE_STRERROR */
Note: See TracBrowser for help on using the repository browser.