Windows global stuff:
[krb5.git] / src / util / et / compile_et.c
1 /*
2  *
3  * Copyright 1986, 1987, 1988
4  * by MIT Student Information Processing Board.
5  *
6  * For copyright info, see "mit-sipb-copyright.h".
7  *
8  */
9
10 #include <stdio.h>
11 #include <sys/types.h>
12 #include <sys/file.h>
13 #include <string.h>
14 #include <sys/param.h>
15 #include "mit-sipb-copyright.h"
16 #include "compiler.h"
17
18 #ifndef lint
19 static const char copyright[] =
20     "Copyright 1987,1988 by MIT Student Information Processing Board";
21 #endif
22
23 extern char *gensym();
24 extern char *current_token;
25 extern int table_number, current;
26 char buffer[BUFSIZ];
27 char *table_name = (char *)NULL;
28 FILE *hfile, *cfile;
29
30 /* C library */
31 extern char *malloc();
32 extern int errno;
33
34 /* lex stuff */
35 extern FILE *yyin;
36 extern int yylineno;
37
38 char * xmalloc (size) unsigned int size; {
39     char * p = malloc (size);
40     if (!p) {
41         perror (whoami);
42         exit (1);
43     }
44     return p;
45 }
46
47 static int check_arg (str_list, arg) char const *const *str_list, *arg; {
48     while (*str_list)
49         if (!strcmp(arg, *str_list++))
50             return 1;
51     return 0;
52 }
53
54 static const char *const debug_args[] = {
55     "d",
56     "debug",
57     0,
58 };
59
60 static const char *const lang_args[] = {
61     "lang",
62     "language",
63     0,
64 };
65
66 static const char *const language_names[] = {
67     "C",
68     "K&R C",
69     "C++",
70     0,
71 };
72
73 static const char * const c_src_prolog[] = {
74     "static const char * const text[] = {\n",
75     0,
76 };
77
78 static const char * const krc_src_prolog[] = {
79     "#if defined(__STDC__) || defined(_WINDOWS)\n",
80     "#define NOARGS void\n",
81     "#else\n",
82     "#define NOARGS\n",
83     "#define const\n",
84     "#endif\n\n",
85     "static const char * const text[] = {\n",
86     0,
87 };
88
89 static const char *const struct_def[] = {
90     "struct error_table {\n",
91     "    char const * const * msgs;\n",
92     "    long base;\n",
93     "    int n_msgs;\n",
94     "};\n",
95     "struct et_list {\n",
96     "    struct et_list *next;\n",
97     "    const struct error_table * table;\n",
98     "};\n",
99     "extern struct et_list *_et_list;\n",
100     "\n", 0,
101 };
102
103 static const char warning[] =
104     "/*\n * %s:\n * This file is automatically generated; please do not edit it.\n */\n";
105
106 /* pathnames */
107 char c_file[MAXPATHLEN];        /* output file */
108 char h_file[MAXPATHLEN];        /* output */
109
110 static void usage () {
111     fprintf (stderr, "%s: usage: %s ERROR_TABLE\n",
112              whoami, whoami);
113     exit (1);
114 }
115
116 static void dup_err (type, one, two) char const *type, *one, *two; {
117     fprintf (stderr, "%s: multiple %s specified: `%s' and `%s'\n",
118              whoami, type, one, two);
119     usage ();
120 }
121
122 int main (argc, argv) int argc; char **argv; {
123     char *p, *ename;
124     int len;
125     char const * const *cpp;
126     int got_language = 0;
127
128     /* argument parsing */
129     debug = 0;
130     filename = 0;
131     whoami = argv[0];
132     p = strrchr (whoami, '/');
133     if (p)
134         whoami = p+1;
135     while (argv++, --argc) {
136         char *arg = *argv;
137         if (arg[0] != '-') {
138             if (filename)
139                 dup_err ("filenames", filename, arg);
140             filename = arg;
141         }
142         else {
143             arg++;
144             if (check_arg (debug_args, arg))
145                 debug++;
146             else if (check_arg (lang_args, arg)) {
147                 got_language++;
148                 arg = *++argv, argc--;
149                 if (!arg)
150                     usage ();
151                 if (language)
152                     dup_err ("languanges", language_names[(int)language], arg);
153 #define check_lang(x,v) else if (!strcasecmp(arg,x)) language = v
154                 check_lang ("c", lang_C);
155                 check_lang ("ansi_c", lang_C);
156                 check_lang ("ansi-c", lang_C);
157                 check_lang ("krc", lang_KRC);
158                 check_lang ("kr_c", lang_KRC);
159                 check_lang ("kr-c", lang_KRC);
160                 check_lang ("k&r-c", lang_KRC);
161                 check_lang ("k&r_c", lang_KRC);
162                 check_lang ("c++", lang_CPP);
163                 check_lang ("cplusplus", lang_CPP);
164                 check_lang ("c-plus-plus", lang_CPP);
165 #undef check_lang
166                 else {
167                     fprintf (stderr, "%s: unknown language name `%s'\n",
168                              whoami, arg);
169                     fprintf (stderr, "\tpick one of: C K&R-C\n");
170                     exit (1);
171                 }
172             }
173             else {
174                 fprintf (stderr, "%s: unknown control argument -`%s'\n",
175                          whoami, arg);
176                 usage ();
177             }
178         }
179     }
180     if (!filename)
181         usage ();
182     if (!got_language)
183         language = lang_KRC;
184     else if (language == lang_CPP) {
185         fprintf (stderr, "%s: Sorry, C++ support is not yet finished.\n",
186                  whoami);
187         exit (1);
188     }
189
190     p = xmalloc (strlen (filename) + 5);
191     strcpy (p, filename);
192     filename = p;
193     p = strrchr(filename, '/');
194     if (p == (char *)NULL)
195         p = filename;
196     else
197         p++;
198     ename = p;
199     len = strlen (ename);
200     p += len - 3;
201     if (strcmp (p, ".et"))
202         p += 3;
203     *p++ = '.';
204     /* now p points to where "et" suffix should start */
205     /* generate new filenames */
206     strcpy (p, "c");
207     strcpy (c_file, ename);
208     *p = 'h';
209     strcpy (h_file, ename);
210     strcpy (p, "et");
211
212     yyin = fopen(filename, "r");
213     if (!yyin) {
214         perror(filename);
215         exit(1);
216     }
217
218     hfile = fopen(h_file, "w");
219     if (hfile == (FILE *)NULL) {
220         perror(h_file);
221         exit(1);
222     }
223     fprintf (hfile, warning, h_file);
224
225     cfile = fopen(c_file, "w");
226     if (cfile == (FILE *)NULL) {
227         perror(c_file);
228         exit(1);
229     }
230     fprintf (cfile, warning, c_file);
231
232     /* prologue */
233     if (language == lang_C)
234         cpp = c_src_prolog;
235     else if (language == lang_KRC)
236         cpp = krc_src_prolog;
237     else
238         abort ();
239     while (*cpp)
240         fputs (*cpp++, cfile);
241
242     /* parse it */
243     yyparse();
244     fclose(yyin);               /* bye bye input file */
245
246     fputs ("    0\n};\n\n", cfile);
247     for (cpp = struct_def; *cpp; cpp++)
248         fputs (*cpp, cfile);
249     fprintf(cfile,
250             "static const struct error_table et = { text, %ldL, %d };\n\n",
251             table_number, current);
252     fputs("static struct et_list link = { 0, 0 };\n\n",
253           cfile);
254     fprintf(cfile, "void initialize_%s_error_table (%s) {\n",
255             table_name, (language == lang_C) ? "void" : "NOARGS");
256     fputs("    if (!link.table) {\n", cfile);
257     fputs("        link.next = _et_list;\n", cfile);
258     fputs("        link.table = &et;\n", cfile);
259     fputs("        _et_list = &link;\n", cfile);
260     fputs("    }\n", cfile);
261     fputs("}\n", cfile);
262     fclose(cfile);
263
264     fprintf (hfile, "extern void initialize_%s_error_table ();\n",
265              table_name);
266     fprintf (hfile, "#define ERROR_TABLE_BASE_%s (%ldL)\n",
267              table_name, table_number);
268     /* compatibility... */
269     fprintf (hfile, "\n/* for compatibility with older versions... */\n");
270     fprintf (hfile, "#define init_%s_err_tbl initialize_%s_error_table\n",
271              table_name, table_name);
272     fprintf (hfile, "#define %s_err_base ERROR_TABLE_BASE_%s\n", table_name,
273              table_name);
274     fclose(hfile);              /* bye bye include file */
275
276     return 0;
277 }
278
279 int yyerror(s) char *s; {
280     fputs(s, stderr);
281 #ifdef NO_YYLINENO
282     fprintf(stderr, "\nLast token was '%s'\n", current_token);
283 #else
284     fprintf(stderr, "\nLine number %d; last token was '%s'\n",
285             yylineno, current_token);
286 #endif
287 }
288
289 #ifdef NEED_STRCASECMP
290 /* Need strcasecmp for this machine */
291 /*
292  * Copyright (c) 1987 Regents of the University of California.
293  * All rights reserved.  The Berkeley software License Agreement
294  * specifies the terms and conditions for redistribution.
295  */
296
297 /* based on @(#)strcasecmp.c    1.3 (Berkeley) 8/3/87 */
298
299 /*
300  * This array is designed for mapping upper and lower case letter
301  * together for a case independent comparison.  The mappings are
302  * based upon ascii character sequences.
303  */
304 static char charmap[] = {
305         '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
306         '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
307         '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
308         '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
309         '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
310         '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
311         '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
312         '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
313         '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
314         '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
315         '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
316         '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
317         '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
318         '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
319         '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
320         '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
321         '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
322         '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
323         '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
324         '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
325         '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
326         '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
327         '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
328         '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
329         '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
330         '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
331         '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
332         '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
333         '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
334         '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
335         '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
336         '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
337 };
338
339 strcasecmp(s1, s2)
340         register char *s1, *s2;
341 {
342         register char *cm = charmap;
343
344         while (cm[*s1] == cm[*s2++])
345                 if (*s1++ == '\0')
346                         return(0);
347         return(cm[*s1] - cm[*--s2]);
348 }
349
350 #endif