Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / gcc / f / fini.c
1 /* fini.c
2    Copyright (C) 1995 Free Software Foundation, Inc.
3    Contributed by James Craig Burley.
4
5 This file is part of GNU Fortran.
6
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)
10 any later version.
11
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.
16
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
20 02111-1307, USA.  */
21
22 #define USE_HCONFIG
23
24 #include "proj.h"
25 #include "malloc.h"
26
27 #undef MAXNAMELEN
28 #define MAXNAMELEN 100
29
30 typedef struct _name_ *name;
31
32 struct _name_
33   {
34     name next;
35     name previous;
36     name next_alpha;
37     name previous_alpha;
38     int namelen;
39     int kwlen;
40     char kwname[MAXNAMELEN];
41     char name_uc[MAXNAMELEN];
42     char name_lc[MAXNAMELEN];
43     char name_ic[MAXNAMELEN];
44   };
45
46 struct _name_root_
47   {
48     name first;
49     name last;
50   };
51
52 struct _name_alpha_
53   {
54     name ign1;
55     name ign2;
56     name first;
57     name last;
58   };
59
60 static FILE *in;
61 static FILE *out;
62 static char prefix[32];
63 static char postfix[32];
64 static char storage[32];
65 static const char *xspaces[]
66 =
67 {
68   "",                           /* 0 */
69   " ",                          /* 1 */
70   "  ",                         /* 2 */
71   "   ",                        /* 3 */
72   "    ",                       /* 4 */
73   "     ",                      /* 5 */
74   "      ",                     /* 6 */
75   "       ",                    /* 7 */
76   "\t",                         /* 8 */
77   "\t ",                        /* 9 */
78   "\t  ",                       /* 10 */
79   "\t   ",                      /* 11 */
80   "\t    ",                     /* 12 */
81   "\t     ",                    /* 13 */
82   "\t      ",                   /* 14 */
83   "\t       ",                  /* 15 */
84   "\t\t",                       /* 16 */
85   "\t\t ",                      /* 17 */
86   "\t\t  ",                     /* 18 */
87   "\t\t   ",                    /* 19 */
88   "\t\t    ",                   /* 20 */
89   "\t\t     ",                  /* 21 */
90   "\t\t      ",                 /* 22 */
91   "\t\t       ",                /* 23 */
92   "\t\t\t",                     /* 24 */
93   "\t\t\t ",                    /* 25 */
94   "\t\t\t  ",                   /* 26 */
95   "\t\t\t   ",                  /* 27 */
96   "\t\t\t    ",                 /* 28 */
97   "\t\t\t     ",                /* 29 */
98   "\t\t\t      ",               /* 30 */
99   "\t\t\t       ",              /* 31 */
100   "\t\t\t\t",                   /* 32 */
101   "\t\t\t\t ",                  /* 33 */
102   "\t\t\t\t  ",                 /* 34 */
103   "\t\t\t\t   ",                /* 35 */
104   "\t\t\t\t    ",               /* 36 */
105   "\t\t\t\t     ",              /* 37 */
106   "\t\t\t\t      ",             /* 38 */
107   "\t\t\t\t       ",            /* 39 */
108   "\t\t\t\t\t",                 /* 40 */
109   "\t\t\t\t\t ",                /* 41 */
110   "\t\t\t\t\t  ",               /* 42 */
111   "\t\t\t\t\t   ",              /* 43 */
112   "\t\t\t\t\t    ",             /* 44 */
113   "\t\t\t\t\t     ",            /* 45 */
114   "\t\t\t\t\t      ",           /* 46 */
115   "\t\t\t\t\t       ",          /* 47 */
116   "\t\t\t\t\t\t",               /* 48 */
117   "\t\t\t\t\t\t ",              /* 49 */
118   "\t\t\t\t\t\t  ",             /* 50 */
119   "\t\t\t\t\t\t   ",            /* 51 */
120   "\t\t\t\t\t\t    ",           /* 52 */
121   "\t\t\t\t\t\t     ",          /* 53 */
122   "\t\t\t\t\t\t      ",         /* 54 */
123   "\t\t\t\t\t\t       ",        /* 55 */
124   "\t\t\t\t\t\t\t",             /* 56 */
125   "\t\t\t\t\t\t\t ",            /* 57 */
126   "\t\t\t\t\t\t\t  ",           /* 58 */
127   "\t\t\t\t\t\t\t   ",          /* 59 */
128   "\t\t\t\t\t\t\t    ",         /* 60 */
129   "\t\t\t\t\t\t\t     ",        /* 61 */
130   "\t\t\t\t\t\t\t      ",       /* 62 */
131   "\t\t\t\t\t\t\t       ",      /* 63 */
132   "\t\t\t\t\t\t\t\t",           /* 64 */
133   "\t\t\t\t\t\t\t\t ",          /* 65 */
134   "\t\t\t\t\t\t\t\t  ",         /* 66 */
135   "\t\t\t\t\t\t\t\t   ",        /* 67 */
136   "\t\t\t\t\t\t\t\t    ",       /* 68 */
137   "\t\t\t\t\t\t\t\t     ",      /* 69 */
138   "\t\t\t\t\t\t\t\t      ",     /* 70 */
139   "\t\t\t\t\t\t\t\t       ",    /* 71 */
140   "\t\t\t\t\t\t\t\t\t",         /* 72 */
141   "\t\t\t\t\t\t\t\t\t ",        /* 73 */
142   "\t\t\t\t\t\t\t\t\t  ",       /* 74 */
143   "\t\t\t\t\t\t\t\t\t   ",      /* 75 */
144   "\t\t\t\t\t\t\t\t\t    ",     /* 76 */
145   "\t\t\t\t\t\t\t\t\t     ",    /* 77 */
146   "\t\t\t\t\t\t\t\t\t      ",   /* 78 */
147   "\t\t\t\t\t\t\t\t\t       ",  /* 79 */
148   "\t\t\t\t\t\t\t\t\t\t",       /* 80 */
149   "\t\t\t\t\t\t\t\t\t\t ",      /* 81 */
150   "\t\t\t\t\t\t\t\t\t\t  ",     /* 82 */
151   "\t\t\t\t\t\t\t\t\t\t   ",    /* 83 */
152   "\t\t\t\t\t\t\t\t\t\t    ",   /* 84 */
153   "\t\t\t\t\t\t\t\t\t\t     ",  /* 85 */
154   "\t\t\t\t\t\t\t\t\t\t      ", /* 86 */
155   "\t\t\t\t\t\t\t\t\t\t       ",/* 87 */
156   "\t\t\t\t\t\t\t\t\t\t\t",     /* 88 */
157   "\t\t\t\t\t\t\t\t\t\t\t ",    /* 89 */
158   "\t\t\t\t\t\t\t\t\t\t\t  ",   /* 90 */
159   "\t\t\t\t\t\t\t\t\t\t\t   ",  /* 91 */
160   "\t\t\t\t\t\t\t\t\t\t\t    ", /* 92 */
161   "\t\t\t\t\t\t\t\t\t\t\t     ",/* 93 */
162   "\t\t\t\t\t\t\t\t\t\t\t      ",       /* 94 */
163   "\t\t\t\t\t\t\t\t\t\t\t       ",      /* 95 */
164   "\t\t\t\t\t\t\t\t\t\t\t\t",   /* 96 */
165   "\t\t\t\t\t\t\t\t\t\t\t\t ",  /* 97 */
166   "\t\t\t\t\t\t\t\t\t\t\t\t  ", /* 98 */
167   "\t\t\t\t\t\t\t\t\t\t\t\t   ",/* 99 */
168   "\t\t\t\t\t\t\t\t\t\t\t\t    ",       /* 100 */
169   "\t\t\t\t\t\t\t\t\t\t\t\t     ",      /* 101 */
170   "\t\t\t\t\t\t\t\t\t\t\t\t      ",     /* 102 */
171   "\t\t\t\t\t\t\t\t\t\t\t\t       ",    /* 103 */
172   "\t\t\t\t\t\t\t\t\t\t\t\t\t", /* 104 */
173   "\t\t\t\t\t\t\t\t\t\t\t\t\t ",/* 105 */
174   "\t\t\t\t\t\t\t\t\t\t\t\t\t  ",       /* 106 */
175   "\t\t\t\t\t\t\t\t\t\t\t\t\t   ",      /* 107 */
176   "\t\t\t\t\t\t\t\t\t\t\t\t\t    ",     /* 108 */
177   "\t\t\t\t\t\t\t\t\t\t\t\t\t     ",    /* 109 */
178   "\t\t\t\t\t\t\t\t\t\t\t\t\t      ",   /* 110 */
179   "\t\t\t\t\t\t\t\t\t\t\t\t\t       ",  /* 111 */
180   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t",       /* 112 */
181   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",      /* 113 */
182   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t  ",     /* 114 */
183   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t   ",    /* 115 */
184   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t    ",   /* 116 */
185   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t     ",  /* 117 */
186   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t      ", /* 118 */
187   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t       ",        /* 119 */
188   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t",     /* 120 */
189   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",    /* 121 */
190   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  ",   /* 122 */
191   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   ",  /* 123 */
192   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t    ", /* 124 */
193   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t     ",        /* 125 */
194   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t      ",       /* 126 */
195   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t       ",      /* 127 */
196   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t",   /* 128 */
197   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",  /* 129 */
198   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  ", /* 130 */
199   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   ",        /* 131 */
200   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t    ",       /* 132 */
201   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t     ",      /* 133 */
202   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t      ",     /* 134 */
203   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t       ",    /* 135 */
204   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t", /* 136 */
205   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",        /* 137 */
206   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  ",       /* 138 */
207   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   ",      /* 139 */
208   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t    ",     /* 140 */
209   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t     ",    /* 141 */
210   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t      ",   /* 142 */
211   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t       ",  /* 143 */
212   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t",       /* 144 */
213   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",      /* 145 */
214   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  ",     /* 146 */
215   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   ",    /* 147 */
216   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t    ",   /* 148 */
217   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t     ",  /* 149 */
218   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t      ", /* 150 */
219   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t       ",        /* 151 */
220   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t",     /* 152 */
221   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",    /* 153 */
222   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  ",   /* 154 */
223   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   ",  /* 155 */
224   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t    ", /* 156 */
225   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t     ",        /* 157 */
226   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t      ",       /* 158 */
227   "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t       ",      /* 159 */
228 };
229
230 void testname (bool nested, int indent, name first, name last);
231 void testnames (bool nested, int indent, int len, name first, name last);
232
233 int
234 main (int argc, char **argv)
235 {
236   char buf[MAXNAMELEN];
237   char last_buf[MAXNAMELEN] = "";
238   char kwname[MAXNAMELEN];
239   char routine[32];
240   char type[32];
241   int i;
242   int count;
243   int len;
244   struct _name_root_ names[200];
245   struct _name_alpha_ names_alpha;
246   name n;
247   name newname;
248   char *input_name;
249   char *output_name;
250   char *include_name;
251   FILE *incl;
252   int fixlengths;
253   int total_length;
254   int do_name;                  /* TRUE if token may be NAME. */
255   int do_names;                 /* TRUE if token may be NAMES. */
256   int cc;
257   bool do_exit = FALSE;
258
259   for (i = 0; ((size_t) i) < ARRAY_SIZE (names); ++i)
260     {                           /* Initialize length/name ordered list roots. */
261       names[i].first = (name) &names[i];
262       names[i].last = (name) &names[i];
263     }
264   names_alpha.first = (name) &names_alpha;      /* Initialize name order. */
265   names_alpha.last = (name) &names_alpha;
266
267   if (argc != 4)
268     {
269       fprintf (stderr, "Command form: fini input output-code output-include\n");
270       exit (1);
271     }
272
273   input_name = argv[1];
274   output_name = argv[2];
275   include_name = argv[3];
276
277   in = fopen (input_name, "r");
278   if (in == NULL)
279     {
280       fprintf (stderr, "Cannot open \"%s\"\n", input_name);
281       exit (1);
282     }
283   out = fopen (output_name, "w");
284   if (out == NULL)
285     {
286       fclose (in);
287       fprintf (stderr, "Cannot open \"%s\"\n", output_name);
288       exit (1);
289     }
290   incl = fopen (include_name, "w");
291   if (incl == NULL)
292     {
293       fclose (in);
294       fprintf (stderr, "Cannot open \"%s\"\n", include_name);
295       exit (1);
296     }
297
298   /* Get past the initial block-style comment (man, this parsing code is just
299      _so_ lame, but I'm too lazy to improve it).  */
300
301   for (;;)
302     {
303       cc = getc (in);
304       if (cc == '{')
305         {
306           while (((cc = getc (in)) != '}') && (cc != EOF))
307             ;
308         }
309       else if (cc != EOF)
310         {
311           while (((cc = getc (in)) != EOF) && (! ISALNUM (cc)))
312             ;
313           ungetc (cc, in);
314           break;
315         }
316       else
317         {
318           assert ("EOF too soon!" == NULL);
319           exit (1);
320         }
321     }
322
323   fscanf (in, "%s %s %s %s %s %d %d", prefix, postfix, storage, type, routine,
324           &do_name, &do_names);
325
326   if (storage[0] == '\0')
327     storage[1] = '\0';
328   else
329     /* Assume string is quoted somehow, replace ending quote with space. */
330     {
331       if (storage[2] == '\0')
332         storage[1] = '\0';
333       else
334         storage[strlen (storage) - 1] = ' ';
335     }
336
337   if (postfix[0] == '\0')
338     postfix[1] = '\0';
339   else                          /* Assume string is quoted somehow, strip off
340                                    ending quote. */
341     postfix[strlen (postfix) - 1] = '\0';
342
343   for (i = 1; storage[i] != '\0'; ++i)
344     storage[i - 1] = storage[i];
345   storage[i - 1] = '\0';
346
347   for (i = 1; postfix[i] != '\0'; ++i)
348     postfix[i - 1] = postfix[i];
349   postfix[i - 1] = '\0';
350
351   fixlengths = strlen (prefix) + strlen (postfix);
352
353   while (TRUE)
354     {
355       count = fscanf (in, "%s %s", buf, kwname);
356       if (count == EOF)
357         break;
358       len = strlen (buf);
359       if (len == 0)
360         continue;               /* Skip empty lines. */
361       if (buf[0] == ';')
362         continue;               /* Skip commented-out lines. */
363       for (i = strlen (buf) - 1; i > 0; --i)
364         cc = buf[i];
365
366       /* Make new name object to store name and its keyword. */
367
368       newname = (name) malloc (sizeof (*newname));
369       newname->namelen = strlen (buf);
370       newname->kwlen = strlen (kwname);
371       total_length = newname->kwlen + fixlengths;
372       if (total_length >= 32)   /* Else resulting keyword name too long. */
373         {
374           fprintf (stderr, "%s: %s%s%s is 31+%d chars long\n", input_name,
375                    prefix, kwname, postfix, total_length - 31);
376           do_exit = TRUE;
377         }
378       strcpy (newname->kwname, kwname);
379       for (i = 0; i < newname->namelen; ++i)
380         {
381           cc = buf[i];
382           if (ISALPHA (cc))
383             {
384               newname->name_uc[i] = toupper (cc);
385               newname->name_lc[i] = tolower (cc);
386               newname->name_ic[i] = cc;
387             }
388           else
389             newname->name_uc[i] = newname->name_lc[i] = newname->name_ic[i]
390               = cc;
391         }
392       newname->name_uc[i] = newname->name_lc[i] = newname->name_ic[i] = '\0';
393
394       /* Warn user if names aren't alphabetically ordered. */
395
396       if ((last_buf[0] != '\0')
397           && (strcmp (last_buf, newname->name_uc) >= 0))
398         {
399           fprintf (stderr, "%s: \"%s\" precedes \"%s\"\n", input_name,
400                    last_buf, newname->name_uc);
401           do_exit = TRUE;
402         }
403       strcpy (last_buf, newname->name_uc);
404
405       /* Append name to end of alpha-sorted list (assumes names entered in
406          alpha order wrt name, not kwname, even though kwname is output from
407          this list). */
408
409       n = names_alpha.last;
410       newname->next_alpha = n->next_alpha;
411       newname->previous_alpha = n;
412       n->next_alpha->previous_alpha = newname;
413       n->next_alpha = newname;
414
415       /* Insert name in appropriate length/name ordered list. */
416
417       n = (name) &names[len];
418       while ((n->next != (name) &names[len])
419              && (strcmp (buf, n->next->name_uc) > 0))
420         n = n->next;
421       if (strcmp (buf, n->next->name_uc) == 0)
422         {
423           fprintf (stderr, "%s: extraneous \"%s\"\n", input_name, buf);
424           do_exit = TRUE;
425         }
426       newname->next = n->next;
427       newname->previous = n;
428       n->next->previous = newname;
429       n->next = newname;
430     }
431
432 #if 0
433   for (len = 0; len < ARRAY_SIZE (name); ++len)
434     {
435       if (names[len].first == (name) &names[len])
436         continue;
437       printf ("Length %d:\n", len);
438       for (n = names[len].first; n != (name) &names[len]; n = n->next)
439         printf ("    %s %s %s\n", n->name_uc, n->name_lc, n->name_ic);
440     }
441 #endif
442
443   if (do_exit)
444     exit (1);
445
446   /* First output the #include file. */
447
448   for (n = names_alpha.first; n != (name) &names_alpha; n = n->next_alpha)
449     {
450       fprintf (incl, "#define %sl%s%s %d\n", prefix, n->kwname, postfix,
451                n->namelen);
452     }
453
454   fprintf (incl,
455            "\
456 \n\
457 enum %s_\n\
458 {\n\
459 %sNone%s,\n\
460 ",
461            type, prefix, postfix);
462
463   for (n = names_alpha.first; n != (name) &names_alpha; n = n->next_alpha)
464     {
465       fprintf (incl,
466                "\
467 %s%s%s,\n\
468 ",
469                prefix, n->kwname, postfix);
470     }
471
472   fprintf (incl,
473            "\
474 %s%s\n\
475 };\n\
476 typedef enum %s_ %s;\n\
477 ",
478            prefix, postfix, type, type);
479
480   /* Now output the C program. */
481
482   fprintf (out,
483            "\
484 %s%s\n\
485 %s (ffelexToken t)\n\
486 %c\n\
487   char *p;\n\
488   int c;\n\
489 \n\
490   p = ffelex_token_text (t);\n\
491 \n\
492 ",
493            storage, type, routine, '{');
494
495   if (do_name)
496     {
497       if (do_names)
498         fprintf (out,
499                  "\
500   if (ffelex_token_type (t) == FFELEX_typeNAME)\n\
501     {\n\
502       switch (ffelex_token_length (t))\n\
503 \t{\n\
504 "
505           );
506       else
507         fprintf (out,
508                  "\
509   assert (ffelex_token_type (t) == FFELEX_typeNAME);\n\
510 \n\
511   switch (ffelex_token_length (t))\n\
512     {\n\
513 "
514           );
515
516 /* Now output the length as a case, followed by the binary search within that length.  */
517
518       for (len = 0; ((size_t) len) < ARRAY_SIZE (names); ++len)
519         {
520           if (names[len].first != (name) &names[len])
521             {
522               if (do_names)
523                 fprintf (out,
524                          "\
525 \tcase %d:\n\
526 ",
527                          len);
528               else
529                 fprintf (out,
530                          "\
531     case %d:\n\
532 ",
533                          len);
534               testname (FALSE, do_names ? 10 : 6, names[len].first, names[len].last);
535               if (do_names)
536                 fprintf (out,
537                          "\
538 \t  break;\n\
539 "
540                   );
541               else
542                 fprintf (out,
543                          "\
544       break;\n\
545 "
546                   );
547             }
548         }
549
550       if (do_names)
551         fprintf (out,
552                  "\
553 \t}\n\
554       return %sNone%s;\n\
555     }\n\
556 \n\
557 ",
558                  prefix, postfix);
559       else
560         fprintf (out,
561                  "\
562     }\n\
563 \n\
564   return %sNone%s;\n\
565 }\n\
566 ",
567                  prefix, postfix);
568     }
569
570   if (do_names)
571     {
572       fputs ("\
573   assert (ffelex_token_type (t) == FFELEX_typeNAMES);\n\
574 \n\
575   switch (ffelex_token_length (t))\n\
576     {\n\
577     default:\n\
578 ",
579              out);
580
581       /* Find greatest non-empty length list. */
582
583       for (len = ARRAY_SIZE (names) - 1;
584            names[len].first == (name) &names[len];
585            --len)
586         ;
587
588 /* Now output the length as a case, followed by the binary search within that length. */
589
590       if (len > 0)
591         {
592           for (; len != 0; --len)
593             {
594               fprintf (out,
595                        "\
596     case %d:\n\
597 ",
598                        len);
599               if (names[len].first != (name) &names[len])
600                 testnames (FALSE, 6, len, names[len].first, names[len].last);
601             }
602           if (names[1].first == (name) &names[1])
603             fprintf (out,
604                      "\
605       ;\n\
606 "
607               );                /* Need empty statement after an empty case
608                                    1:  */
609         }
610
611       fprintf (out,
612                "\
613     }\n\
614 \n\
615   return %sNone%s;\n\
616 }\n\
617 ",
618                prefix, postfix);
619     }
620
621   if (out != stdout)
622     fclose (out);
623   if (incl != stdout)
624     fclose (incl);
625   if (in != stdin)
626     fclose (in);
627   exit (0);
628 }
629
630 void
631 testname (bool nested, int indent, name first, name last)
632 {
633   name n;
634   name nhalf;
635   int num;
636   int numhalf;
637
638   assert (!nested || indent >= 2);
639   assert (((size_t) indent) + 4 < ARRAY_SIZE (xspaces));
640
641   num = 0;
642   numhalf = 0;
643   for (n = first, nhalf = first; n != last->next; n = n->next)
644     {
645       if ((++num & 1) == 0)
646         {
647           nhalf = nhalf->next;
648           ++numhalf;
649         }
650     }
651
652   if (nested)
653     fprintf (out,
654              "\
655 %s{\n\
656 ",
657              xspaces[indent - 2]);
658
659   fprintf (out,
660            "\
661 %sif ((c = ffesrc_strcmp_2c (ffe_case_match (), p, \"%s\", \"%s\", \"%s\")) == 0)\n\
662 %sreturn %s%s%s;\n\
663 ",
664            xspaces[indent], nhalf->name_uc, nhalf->name_lc, nhalf->name_ic,
665            xspaces[indent + 2], prefix, nhalf->kwname, postfix);
666
667   if (num != 1)
668     {
669       fprintf (out,
670                "\
671 %selse if (c < 0)\n\
672 ",
673                xspaces[indent]);
674
675       if (numhalf == 0)
676         fprintf (out,
677                  "\
678 %s;\n\
679 ",
680                  xspaces[indent + 2]);
681       else
682         testname (TRUE, indent + 4, first, nhalf->previous);
683
684       if (num - numhalf > 1)
685         {
686           fprintf (out,
687                    "\
688 %selse\n\
689 ",
690                    xspaces[indent]);
691
692           testname (TRUE, indent + 4, nhalf->next, last);
693         }
694     }
695
696   if (nested)
697     fprintf (out,
698              "\
699 %s}\n\
700 ",
701              xspaces[indent - 2]);
702 }
703
704 void
705 testnames (bool nested, int indent, int len, name first, name last)
706 {
707   name n;
708   name nhalf;
709   int num;
710   int numhalf;
711
712   assert (!nested || indent >= 2);
713   assert (((size_t) indent) + 4 < ARRAY_SIZE (xspaces));
714
715   num = 0;
716   numhalf = 0;
717   for (n = first, nhalf = first; n != last->next; n = n->next)
718     {
719       if ((++num & 1) == 0)
720         {
721           nhalf = nhalf->next;
722           ++numhalf;
723         }
724     }
725
726   if (nested)
727     fprintf (out,
728              "\
729 %s{\n\
730 ",
731              xspaces[indent - 2]);
732
733   fprintf (out,
734            "\
735 %sif ((c = ffesrc_strncmp_2c (ffe_case_match (), p, \"%s\", \"%s\", \"%s\", %d)) == 0)\n\
736 %sreturn %s%s%s;\n\
737 ",
738            xspaces[indent], nhalf->name_uc, nhalf->name_lc, nhalf->name_ic,
739            len, xspaces[indent + 2], prefix, nhalf->kwname, postfix);
740
741   if (num != 1)
742     {
743       fprintf (out,
744                "\
745 %selse if (c < 0)\n\
746 ",
747                xspaces[indent]);
748
749       if (numhalf == 0)
750         fprintf (out,
751                  "\
752 %s;\n\
753 ",
754                  xspaces[indent + 2]);
755       else
756         testnames (TRUE, indent + 4, len, first, nhalf->previous);
757
758       if (num - numhalf > 1)
759         {
760           fprintf (out,
761                    "\
762 %selse\n\
763 ",
764                    xspaces[indent]);
765
766           testnames (TRUE, indent + 4, len, nhalf->next, last);
767         }
768     }
769
770   if (nested)
771     fprintf (out,
772              "\
773 %s}\n\
774 ",
775              xspaces[indent - 2]);
776 }