2 Copyright (C) 1995 Free Software Foundation, Inc.
3 Contributed by James Craig Burley (burley@gnu.org).
5 This file is part of GNU Fortran.
7 GNU Fortran is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Fortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Fortran; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 #define MAXNAMELEN 100
29 typedef struct _name_ *name;
39 char kwname[MAXNAMELEN];
40 char name_uc[MAXNAMELEN];
41 char name_lc[MAXNAMELEN];
42 char name_ic[MAXNAMELEN];
61 static char prefix[32];
62 static char postfix[32];
63 static char storage[32];
100 "\t\t\t\t ", /* 33 */
101 "\t\t\t\t ", /* 34 */
102 "\t\t\t\t ", /* 35 */
103 "\t\t\t\t ", /* 36 */
104 "\t\t\t\t ", /* 37 */
105 "\t\t\t\t ", /* 38 */
106 "\t\t\t\t ", /* 39 */
107 "\t\t\t\t\t", /* 40 */
108 "\t\t\t\t\t ", /* 41 */
109 "\t\t\t\t\t ", /* 42 */
110 "\t\t\t\t\t ", /* 43 */
111 "\t\t\t\t\t ", /* 44 */
112 "\t\t\t\t\t ", /* 45 */
113 "\t\t\t\t\t ", /* 46 */
114 "\t\t\t\t\t ", /* 47 */
115 "\t\t\t\t\t\t", /* 48 */
116 "\t\t\t\t\t\t ", /* 49 */
117 "\t\t\t\t\t\t ", /* 50 */
118 "\t\t\t\t\t\t ", /* 51 */
119 "\t\t\t\t\t\t ", /* 52 */
120 "\t\t\t\t\t\t ", /* 53 */
121 "\t\t\t\t\t\t ", /* 54 */
122 "\t\t\t\t\t\t ", /* 55 */
123 "\t\t\t\t\t\t\t", /* 56 */
124 "\t\t\t\t\t\t\t ", /* 57 */
125 "\t\t\t\t\t\t\t ", /* 58 */
126 "\t\t\t\t\t\t\t ", /* 59 */
127 "\t\t\t\t\t\t\t ", /* 60 */
128 "\t\t\t\t\t\t\t ", /* 61 */
129 "\t\t\t\t\t\t\t ", /* 62 */
130 "\t\t\t\t\t\t\t ", /* 63 */
131 "\t\t\t\t\t\t\t\t", /* 64 */
132 "\t\t\t\t\t\t\t\t ", /* 65 */
133 "\t\t\t\t\t\t\t\t ", /* 66 */
134 "\t\t\t\t\t\t\t\t ", /* 67 */
135 "\t\t\t\t\t\t\t\t ", /* 68 */
136 "\t\t\t\t\t\t\t\t ", /* 69 */
137 "\t\t\t\t\t\t\t\t ", /* 70 */
138 "\t\t\t\t\t\t\t\t ", /* 71 */
139 "\t\t\t\t\t\t\t\t\t", /* 72 */
140 "\t\t\t\t\t\t\t\t\t ", /* 73 */
141 "\t\t\t\t\t\t\t\t\t ", /* 74 */
142 "\t\t\t\t\t\t\t\t\t ", /* 75 */
143 "\t\t\t\t\t\t\t\t\t ", /* 76 */
144 "\t\t\t\t\t\t\t\t\t ", /* 77 */
145 "\t\t\t\t\t\t\t\t\t ", /* 78 */
146 "\t\t\t\t\t\t\t\t\t ", /* 79 */
147 "\t\t\t\t\t\t\t\t\t\t", /* 80 */
148 "\t\t\t\t\t\t\t\t\t\t ", /* 81 */
149 "\t\t\t\t\t\t\t\t\t\t ", /* 82 */
150 "\t\t\t\t\t\t\t\t\t\t ", /* 83 */
151 "\t\t\t\t\t\t\t\t\t\t ", /* 84 */
152 "\t\t\t\t\t\t\t\t\t\t ", /* 85 */
153 "\t\t\t\t\t\t\t\t\t\t ", /* 86 */
154 "\t\t\t\t\t\t\t\t\t\t ",/* 87 */
155 "\t\t\t\t\t\t\t\t\t\t\t", /* 88 */
156 "\t\t\t\t\t\t\t\t\t\t\t ", /* 89 */
157 "\t\t\t\t\t\t\t\t\t\t\t ", /* 90 */
158 "\t\t\t\t\t\t\t\t\t\t\t ", /* 91 */
159 "\t\t\t\t\t\t\t\t\t\t\t ", /* 92 */
160 "\t\t\t\t\t\t\t\t\t\t\t ",/* 93 */
161 "\t\t\t\t\t\t\t\t\t\t\t ", /* 94 */
162 "\t\t\t\t\t\t\t\t\t\t\t ", /* 95 */
163 "\t\t\t\t\t\t\t\t\t\t\t\t", /* 96 */
164 "\t\t\t\t\t\t\t\t\t\t\t\t ", /* 97 */
165 "\t\t\t\t\t\t\t\t\t\t\t\t ", /* 98 */
166 "\t\t\t\t\t\t\t\t\t\t\t\t ",/* 99 */
167 "\t\t\t\t\t\t\t\t\t\t\t\t ", /* 100 */
168 "\t\t\t\t\t\t\t\t\t\t\t\t ", /* 101 */
169 "\t\t\t\t\t\t\t\t\t\t\t\t ", /* 102 */
170 "\t\t\t\t\t\t\t\t\t\t\t\t ", /* 103 */
171 "\t\t\t\t\t\t\t\t\t\t\t\t\t", /* 104 */
172 "\t\t\t\t\t\t\t\t\t\t\t\t\t ",/* 105 */
173 "\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 106 */
174 "\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 107 */
175 "\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 108 */
176 "\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 109 */
177 "\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 110 */
178 "\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 111 */
179 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t", /* 112 */
180 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 113 */
181 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 114 */
182 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 115 */
183 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 116 */
184 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 117 */
185 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 118 */
186 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 119 */
187 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t", /* 120 */
188 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 121 */
189 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 122 */
190 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 123 */
191 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 124 */
192 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 125 */
193 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 126 */
194 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 127 */
195 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t", /* 128 */
196 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 129 */
197 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 130 */
198 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 131 */
199 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 132 */
200 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 133 */
201 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 134 */
202 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 135 */
203 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t", /* 136 */
204 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 137 */
205 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 138 */
206 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 139 */
207 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 140 */
208 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 141 */
209 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 142 */
210 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 143 */
211 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t", /* 144 */
212 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 145 */
213 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 146 */
214 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 147 */
215 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 148 */
216 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 149 */
217 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 150 */
218 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 151 */
219 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t", /* 152 */
220 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 153 */
221 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 154 */
222 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 155 */
223 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 156 */
224 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 157 */
225 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 158 */
226 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 159 */
229 void testname (bool nested, int indent, name first, name last);
230 void testnames (bool nested, int indent, int len, name first, name last);
233 main (int argc, char **argv)
235 char buf[MAXNAMELEN];
236 char last_buf[MAXNAMELEN] = "";
237 char kwname[MAXNAMELEN];
243 struct _name_root_ names[200];
244 struct _name_alpha_ names_alpha;
253 int do_name; /* TRUE if token may be NAME. */
254 int do_names; /* TRUE if token may be NAMES. */
256 bool do_exit = FALSE;
258 for (i = 0; ((size_t) i) < ARRAY_SIZE (names); ++i)
259 { /* Initialize length/name ordered list roots. */
260 names[i].first = (name) &names[i];
261 names[i].last = (name) &names[i];
263 names_alpha.first = (name) &names_alpha; /* Initialize name order. */
264 names_alpha.last = (name) &names_alpha;
268 fprintf (stderr, "Command form: fini input output-code output-include\n");
272 input_name = argv[1];
273 output_name = argv[2];
274 include_name = argv[3];
276 in = fopen (input_name, "r");
279 fprintf (stderr, "Cannot open \"%s\"\n", input_name);
282 out = fopen (output_name, "w");
286 fprintf (stderr, "Cannot open \"%s\"\n", output_name);
289 incl = fopen (include_name, "w");
293 fprintf (stderr, "Cannot open \"%s\"\n", include_name);
297 /* Get past the initial block-style comment (man, this parsing code is just
298 _so_ lame, but I'm too lazy to improve it). */
305 while (((cc = getc (in)) != '}') && (cc != EOF))
310 while (((cc = getc (in)) != EOF) && (! ISALNUM (cc)))
317 assert ("EOF too soon!" == NULL);
322 fscanf (in, "%s %s %s %s %s %d %d", prefix, postfix, storage, type, routine,
323 &do_name, &do_names);
325 if (storage[0] == '\0')
328 /* Assume string is quoted somehow, replace ending quote with space. */
330 if (storage[2] == '\0')
333 storage[strlen (storage) - 1] = ' ';
336 if (postfix[0] == '\0')
338 else /* Assume string is quoted somehow, strip off
340 postfix[strlen (postfix) - 1] = '\0';
342 for (i = 1; storage[i] != '\0'; ++i)
343 storage[i - 1] = storage[i];
344 storage[i - 1] = '\0';
346 for (i = 1; postfix[i] != '\0'; ++i)
347 postfix[i - 1] = postfix[i];
348 postfix[i - 1] = '\0';
350 fixlengths = strlen (prefix) + strlen (postfix);
354 count = fscanf (in, "%s %s", buf, kwname);
359 continue; /* Skip empty lines. */
361 continue; /* Skip commented-out lines. */
362 for (i = strlen (buf) - 1; i > 0; --i)
365 /* Make new name object to store name and its keyword. */
367 newname = (name) malloc (sizeof (*newname));
368 newname->namelen = strlen (buf);
369 newname->kwlen = strlen (kwname);
370 total_length = newname->kwlen + fixlengths;
371 if (total_length >= 32) /* Else resulting keyword name too long. */
373 fprintf (stderr, "%s: %s%s%s is 31+%d chars long\n", input_name,
374 prefix, kwname, postfix, total_length - 31);
377 strcpy (newname->kwname, kwname);
378 for (i = 0; i < newname->namelen; ++i)
383 newname->name_uc[i] = toupper (cc);
384 newname->name_lc[i] = tolower (cc);
385 newname->name_ic[i] = cc;
388 newname->name_uc[i] = newname->name_lc[i] = newname->name_ic[i]
391 newname->name_uc[i] = newname->name_lc[i] = newname->name_ic[i] = '\0';
393 /* Warn user if names aren't alphabetically ordered. */
395 if ((last_buf[0] != '\0')
396 && (strcmp (last_buf, newname->name_uc) >= 0))
398 fprintf (stderr, "%s: \"%s\" precedes \"%s\"\n", input_name,
399 last_buf, newname->name_uc);
402 strcpy (last_buf, newname->name_uc);
404 /* Append name to end of alpha-sorted list (assumes names entered in
405 alpha order wrt name, not kwname, even though kwname is output from
408 n = names_alpha.last;
409 newname->next_alpha = n->next_alpha;
410 newname->previous_alpha = n;
411 n->next_alpha->previous_alpha = newname;
412 n->next_alpha = newname;
414 /* Insert name in appropriate length/name ordered list. */
416 n = (name) &names[len];
417 while ((n->next != (name) &names[len])
418 && (strcmp (buf, n->next->name_uc) > 0))
420 if (strcmp (buf, n->next->name_uc) == 0)
422 fprintf (stderr, "%s: extraneous \"%s\"\n", input_name, buf);
425 newname->next = n->next;
426 newname->previous = n;
427 n->next->previous = newname;
432 for (len = 0; len < ARRAY_SIZE (name); ++len)
434 if (names[len].first == (name) &names[len])
436 printf ("Length %d:\n", len);
437 for (n = names[len].first; n != (name) &names[len]; n = n->next)
438 printf (" %s %s %s\n", n->name_uc, n->name_lc, n->name_ic);
445 /* First output the #include file. */
447 for (n = names_alpha.first; n != (name) &names_alpha; n = n->next_alpha)
449 fprintf (incl, "#define %sl%s%s %d\n", prefix, n->kwname, postfix,
460 type, prefix, postfix);
462 for (n = names_alpha.first; n != (name) &names_alpha; n = n->next_alpha)
468 prefix, n->kwname, postfix);
475 typedef enum %s_ %s;\n\
477 prefix, postfix, type, type);
479 /* Now output the C program. */
484 %s (ffelexToken t)\n\
489 p = ffelex_token_text (t);\n\
492 storage, type, routine, '{');
499 if (ffelex_token_type (t) == FFELEX_typeNAME)\n\
501 switch (ffelex_token_length (t))\n\
508 assert (ffelex_token_type (t) == FFELEX_typeNAME);\n\
510 switch (ffelex_token_length (t))\n\
515 /* Now output the length as a case, followed by the binary search within that length. */
517 for (len = 0; ((size_t) len) < ARRAY_SIZE (names); ++len)
519 if (names[len].first != (name) &names[len])
533 testname (FALSE, do_names ? 10 : 6, names[len].first, names[len].last);
572 assert (ffelex_token_type (t) == FFELEX_typeNAMES);\n\
574 switch (ffelex_token_length (t))\n\
580 /* Find greatest non-empty length list. */
582 for (len = ARRAY_SIZE (names) - 1;
583 names[len].first == (name) &names[len];
587 /* Now output the length as a case, followed by the binary search within that length. */
591 for (; len != 0; --len)
598 if (names[len].first != (name) &names[len])
599 testnames (FALSE, 6, len, names[len].first, names[len].last);
601 if (names[1].first == (name) &names[1])
606 ); /* Need empty statement after an empty case
630 testname (bool nested, int indent, name first, name last)
637 assert (!nested || indent >= 2);
638 assert (((size_t) indent) + 4 < ARRAY_SIZE (spaces));
642 for (n = first, nhalf = first; n != last->next; n = n->next)
644 if ((++num & 1) == 0)
660 %sif ((c = ffesrc_strcmp_2c (ffe_case_match (), p, \"%s\", \"%s\", \"%s\")) == 0)\n\
663 spaces[indent], nhalf->name_uc, nhalf->name_lc, nhalf->name_ic,
664 spaces[indent + 2], prefix, nhalf->kwname, postfix);
681 testname (TRUE, indent + 4, first, nhalf->previous);
683 if (num - numhalf > 1)
691 testname (TRUE, indent + 4, nhalf->next, last);
704 testnames (bool nested, int indent, int len, name first, name last)
711 assert (!nested || indent >= 2);
712 assert (((size_t) indent) + 4 < ARRAY_SIZE (spaces));
716 for (n = first, nhalf = first; n != last->next; n = n->next)
718 if ((++num & 1) == 0)
734 %sif ((c = ffesrc_strncmp_2c (ffe_case_match (), p, \"%s\", \"%s\", \"%s\", %d)) == 0)\n\
737 spaces[indent], nhalf->name_uc, nhalf->name_lc, nhalf->name_ic,
738 len, spaces[indent + 2], prefix, nhalf->kwname, postfix);
755 testnames (TRUE, indent + 4, len, first, nhalf->previous);
757 if (num - numhalf > 1)
765 testnames (TRUE, indent + 4, len, nhalf->next, last);