Merge from vendor branch GCC:
[dragonfly.git] / contrib / gcc-3.4 / 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_BCONFIG
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 *const 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   last_buf[0] = '\0';
260   
261   for (i = 0; ((size_t) i) < ARRAY_SIZE (names); ++i)
262     {                           /* Initialize length/name ordered list roots. */
263       names[i].first = (name) &names[i];
264       names[i].last = (name) &names[i];
265     }
266   names_alpha.first = (name) &names_alpha;      /* Initialize name order. */
267   names_alpha.last = (name) &names_alpha;
268
269   if (argc != 4)
270     {
271       fprintf (stderr, "Command form: fini input output-code output-include\n");
272       return (1);
273     }
274
275   input_name = argv[1];
276   output_name = argv[2];
277   include_name = argv[3];
278
279   in = fopen (input_name, "r");
280   if (in == NULL)
281     {
282       fprintf (stderr, "Cannot open \"%s\"\n", input_name);
283       return (1);
284     }
285   out = fopen (output_name, "w");
286   if (out == NULL)
287     {
288       fclose (in);
289       fprintf (stderr, "Cannot open \"%s\"\n", output_name);
290       return (1);
291     }
292   incl = fopen (include_name, "w");
293   if (incl == NULL)
294     {
295       fclose (in);
296       fprintf (stderr, "Cannot open \"%s\"\n", include_name);
297       return (1);
298     }
299
300   /* Get past the initial block-style comment (man, this parsing code is just
301      _so_ lame, but I'm too lazy to improve it).  */
302
303   for (;;)
304     {
305       cc = getc (in);
306       if (cc == '{')
307         {
308           while (((cc = getc (in)) != '}') && (cc != EOF))
309             ;
310         }
311       else if (cc != EOF)
312         {
313           while (((cc = getc (in)) != EOF) && (! ISALNUM (cc)))
314             ;
315           ungetc (cc, in);
316           break;
317         }
318       else
319         {
320           assert ("EOF too soon!" == NULL);
321           return (1);
322         }
323     }
324
325   fscanf (in, "%s %s %s %s %s %d %d", prefix, postfix, storage, type, routine,
326           &do_name, &do_names);
327
328   if (storage[0] == '\0')
329     storage[1] = '\0';
330   else
331     /* Assume string is quoted somehow, replace ending quote with space. */
332     {
333       if (storage[2] == '\0')
334         storage[1] = '\0';
335       else
336         storage[strlen (storage) - 1] = ' ';
337     }
338
339   if (postfix[0] == '\0')
340     postfix[1] = '\0';
341   else                          /* Assume string is quoted somehow, strip off
342                                    ending quote. */
343     postfix[strlen (postfix) - 1] = '\0';
344
345   for (i = 1; storage[i] != '\0'; ++i)
346     storage[i - 1] = storage[i];
347   storage[i - 1] = '\0';
348
349   for (i = 1; postfix[i] != '\0'; ++i)
350     postfix[i - 1] = postfix[i];
351   postfix[i - 1] = '\0';
352
353   fixlengths = strlen (prefix) + strlen (postfix);
354
355   while (TRUE)
356     {
357       count = fscanf (in, "%s %s", buf, kwname);
358       if (count == EOF)
359         break;
360       len = strlen (buf);
361       if (len == 0)
362         continue;               /* Skip empty lines. */
363       if (buf[0] == ';')
364         continue;               /* Skip commented-out lines. */
365       for (i = strlen (buf) - 1; i > 0; --i)
366         cc = buf[i];
367
368       /* Make new name object to store name and its keyword. */
369
370       newname = xmalloc (sizeof (*newname));
371       newname->namelen = strlen (buf);
372       newname->kwlen = strlen (kwname);
373       total_length = newname->kwlen + fixlengths;
374       if (total_length >= 32)   /* Else resulting keyword name too long. */
375         {
376           fprintf (stderr, "%s: %s%s%s is 31+%d chars long\n", input_name,
377                    prefix, kwname, postfix, total_length - 31);
378           do_exit = TRUE;
379         }
380       strcpy (newname->kwname, kwname);
381       for (i = 0; i < newname->namelen; ++i)
382         {
383           cc = buf[i];
384           newname->name_uc[i] = TOUPPER (cc);
385           newname->name_lc[i] = TOLOWER (cc);
386           newname->name_ic[i] = cc;
387         }
388       newname->name_uc[i] = newname->name_lc[i] = newname->name_ic[i] = '\0';
389
390       /* Warn user if names aren't alphabetically ordered. */
391
392       if ((last_buf[0] != '\0')
393           && (strcmp (last_buf, newname->name_uc) >= 0))
394         {
395           fprintf (stderr, "%s: \"%s\" precedes \"%s\"\n", input_name,
396                    last_buf, newname->name_uc);
397           do_exit = TRUE;
398         }
399       strcpy (last_buf, newname->name_uc);
400
401       /* Append name to end of alpha-sorted list (assumes names entered in
402          alpha order wrt name, not kwname, even though kwname is output from
403          this list). */
404
405       n = names_alpha.last;
406       newname->next_alpha = n->next_alpha;
407       newname->previous_alpha = n;
408       n->next_alpha->previous_alpha = newname;
409       n->next_alpha = newname;
410
411       /* Insert name in appropriate length/name ordered list. */
412
413       n = (name) &names[len];
414       while ((n->next != (name) &names[len])
415              && (strcmp (buf, n->next->name_uc) > 0))
416         n = n->next;
417       if (strcmp (buf, n->next->name_uc) == 0)
418         {
419           fprintf (stderr, "%s: extraneous \"%s\"\n", input_name, buf);
420           do_exit = TRUE;
421         }
422       newname->next = n->next;
423       newname->previous = n;
424       n->next->previous = newname;
425       n->next = newname;
426     }
427
428 #if 0
429   for (len = 0; len < ARRAY_SIZE (name); ++len)
430     {
431       if (names[len].first == (name) &names[len])
432         continue;
433       printf ("Length %d:\n", len);
434       for (n = names[len].first; n != (name) &names[len]; n = n->next)
435         printf ("    %s %s %s\n", n->name_uc, n->name_lc, n->name_ic);
436     }
437 #endif
438
439   if (do_exit)
440     return (1);
441
442   /* First output the #include file. */
443
444   for (n = names_alpha.first; n != (name) &names_alpha; n = n->next_alpha)
445     {
446       fprintf (incl, "#define %sl%s%s %d\n", prefix, n->kwname, postfix,
447                n->namelen);
448     }
449
450   fprintf (incl,
451            "\
452 \n\
453 enum %s_\n\
454 {\n\
455 %sNone%s,\n\
456 ",
457            type, prefix, postfix);
458
459   for (n = names_alpha.first; n != (name) &names_alpha; n = n->next_alpha)
460     {
461       fprintf (incl,
462                "\
463 %s%s%s,\n\
464 ",
465                prefix, n->kwname, postfix);
466     }
467
468   fprintf (incl,
469            "\
470 %s%s\n\
471 };\n\
472 typedef enum %s_ %s;\n\
473 ",
474            prefix, postfix, type, type);
475
476   /* Now output the C program. */
477
478   fprintf (out,
479            "\
480 %s%s\n\
481 %s (ffelexToken t)\n\
482 %c\n\
483   char *p;\n\
484   int c;\n\
485 \n\
486   p = ffelex_token_text (t);\n\
487 \n\
488 ",
489            storage, type, routine, '{');
490
491   if (do_name)
492     {
493       if (do_names)
494         fprintf (out,
495                  "\
496   if (ffelex_token_type (t) == FFELEX_typeNAME)\n\
497     {\n\
498       switch (ffelex_token_length (t))\n\
499 \t{\n\
500 "
501           );
502       else
503         fprintf (out,
504                  "\
505   assert (ffelex_token_type (t) == FFELEX_typeNAME);\n\
506 \n\
507   switch (ffelex_token_length (t))\n\
508     {\n\
509 "
510           );
511
512 /* Now output the length as a case, followed by the binary search within that length.  */
513
514       for (len = 0; ((size_t) len) < ARRAY_SIZE (names); ++len)
515         {
516           if (names[len].first != (name) &names[len])
517             {
518               if (do_names)
519                 fprintf (out,
520                          "\
521 \tcase %d:\n\
522 ",
523                          len);
524               else
525                 fprintf (out,
526                          "\
527     case %d:\n\
528 ",
529                          len);
530               testname (FALSE, do_names ? 10 : 6, names[len].first, names[len].last);
531               if (do_names)
532                 fprintf (out,
533                          "\
534 \t  break;\n\
535 "
536                   );
537               else
538                 fprintf (out,
539                          "\
540       break;\n\
541 "
542                   );
543             }
544         }
545
546       if (do_names)
547         fprintf (out,
548                  "\
549 \t}\n\
550       return %sNone%s;\n\
551     }\n\
552 \n\
553 ",
554                  prefix, postfix);
555       else
556         fprintf (out,
557                  "\
558     }\n\
559 \n\
560   return %sNone%s;\n\
561 }\n\
562 ",
563                  prefix, postfix);
564     }
565
566   if (do_names)
567     {
568       fputs ("\
569   assert (ffelex_token_type (t) == FFELEX_typeNAMES);\n\
570 \n\
571   switch (ffelex_token_length (t))\n\
572     {\n\
573     default:\n\
574 ",
575              out);
576
577       /* Find greatest non-empty length list. */
578
579       for (len = ARRAY_SIZE (names) - 1;
580            names[len].first == (name) &names[len];
581            --len)
582         ;
583
584 /* Now output the length as a case, followed by the binary search within that length. */
585
586       if (len > 0)
587         {
588           for (; len != 0; --len)
589             {
590               fprintf (out,
591                        "\
592     case %d:\n\
593 ",
594                        len);
595               if (names[len].first != (name) &names[len])
596                 testnames (FALSE, 6, len, names[len].first, names[len].last);
597             }
598           if (names[1].first == (name) &names[1])
599             fprintf (out,
600                      "\
601       ;\n\
602 "
603               );                /* Need empty statement after an empty case
604                                    1:  */
605         }
606
607       fprintf (out,
608                "\
609     }\n\
610 \n\
611   return %sNone%s;\n\
612 }\n\
613 ",
614                prefix, postfix);
615     }
616
617   if (out != stdout)
618     fclose (out);
619   if (incl != stdout)
620     fclose (incl);
621   if (in != stdin)
622     fclose (in);
623   return (0);
624 }
625
626 void
627 testname (bool nested, int indent, name first, name last)
628 {
629   name n;
630   name nhalf;
631   int num;
632   int numhalf;
633
634   assert (!nested || indent >= 2);
635   assert (((size_t) indent) + 4 < ARRAY_SIZE (xspaces));
636
637   num = 0;
638   numhalf = 0;
639   for (n = first, nhalf = first; n != last->next; n = n->next)
640     {
641       if ((++num & 1) == 0)
642         {
643           nhalf = nhalf->next;
644           ++numhalf;
645         }
646     }
647
648   if (nested)
649     fprintf (out,
650              "\
651 %s{\n\
652 ",
653              xspaces[indent - 2]);
654
655   fprintf (out,
656            "\
657 %sif ((c = ffesrc_strcmp_2c (ffe_case_match (), p, \"%s\", \"%s\", \"%s\")) == 0)\n\
658 %sreturn %s%s%s;\n\
659 ",
660            xspaces[indent], nhalf->name_uc, nhalf->name_lc, nhalf->name_ic,
661            xspaces[indent + 2], prefix, nhalf->kwname, postfix);
662
663   if (num != 1)
664     {
665       fprintf (out,
666                "\
667 %selse if (c < 0)\n\
668 ",
669                xspaces[indent]);
670
671       if (numhalf == 0)
672         fprintf (out,
673                  "\
674 %s;\n\
675 ",
676                  xspaces[indent + 2]);
677       else
678         testname (TRUE, indent + 4, first, nhalf->previous);
679
680       if (num - numhalf > 1)
681         {
682           fprintf (out,
683                    "\
684 %selse\n\
685 ",
686                    xspaces[indent]);
687
688           testname (TRUE, indent + 4, nhalf->next, last);
689         }
690     }
691
692   if (nested)
693     fprintf (out,
694              "\
695 %s}\n\
696 ",
697              xspaces[indent - 2]);
698 }
699
700 void
701 testnames (bool nested, int indent, int len, name first, name last)
702 {
703   name n;
704   name nhalf;
705   int num;
706   int numhalf;
707
708   assert (!nested || indent >= 2);
709   assert (((size_t) indent) + 4 < ARRAY_SIZE (xspaces));
710
711   num = 0;
712   numhalf = 0;
713   for (n = first, nhalf = first; n != last->next; n = n->next)
714     {
715       if ((++num & 1) == 0)
716         {
717           nhalf = nhalf->next;
718           ++numhalf;
719         }
720     }
721
722   if (nested)
723     fprintf (out,
724              "\
725 %s{\n\
726 ",
727              xspaces[indent - 2]);
728
729   fprintf (out,
730            "\
731 %sif ((c = ffesrc_strncmp_2c (ffe_case_match (), p, \"%s\", \"%s\", \"%s\", %d)) == 0)\n\
732 %sreturn %s%s%s;\n\
733 ",
734            xspaces[indent], nhalf->name_uc, nhalf->name_lc, nhalf->name_ic,
735            len, xspaces[indent + 2], prefix, nhalf->kwname, postfix);
736
737   if (num != 1)
738     {
739       fprintf (out,
740                "\
741 %selse if (c < 0)\n\
742 ",
743                xspaces[indent]);
744
745       if (numhalf == 0)
746         fprintf (out,
747                  "\
748 %s;\n\
749 ",
750                  xspaces[indent + 2]);
751       else
752         testnames (TRUE, indent + 4, len, first, nhalf->previous);
753
754       if (num - numhalf > 1)
755         {
756           fprintf (out,
757                    "\
758 %selse\n\
759 ",
760                    xspaces[indent]);
761
762           testnames (TRUE, indent + 4, len, nhalf->next, last);
763         }
764     }
765
766   if (nested)
767     fprintf (out,
768              "\
769 %s}\n\
770 ",
771              xspaces[indent - 2]);
772 }