]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/gperf/src/output.cc
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / gperf / src / output.cc
1 /* Output routines.
2    Copyright (C) 1989-1998, 2000, 2002-2004, 2006-2007 Free Software Foundation, Inc.
3    Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
4    and Bruno Haible <bruno@clisp.org>.
5
6    This file is part of GNU GPERF.
7
8    GNU GPERF is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2, or (at your option)
11    any later version.
12
13    GNU GPERF is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; see the file COPYING.
20    If not, write to the Free Software Foundation, Inc.,
21    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
22
23 /* Specification. */
24 #include "output.h"
25
26 #include <stdio.h>
27 #include <string.h> /* declares strncpy(), strchr() */
28 #include <ctype.h>  /* declares isprint() */
29 #include <assert.h> /* defines assert() */
30 #include <limits.h> /* defines SCHAR_MAX etc. */
31 #include "options.h"
32 #include "version.h"
33
34 /* The "const " qualifier.  */
35 static const char *const_always;
36
37 /* The "const " qualifier, for read-only arrays.  */
38 static const char *const_readonly_array;
39
40 /* The "const " qualifier, for the array type.  */
41 static const char *const_for_struct;
42
43 /* Returns the smallest unsigned C type capable of holding integers
44    up to N.  */
45
46 static const char *
47 smallest_integral_type (int n)
48 {
49   if (n <= UCHAR_MAX) return "unsigned char";
50   if (n <= USHRT_MAX) return "unsigned short";
51   return "unsigned int";
52 }
53
54 /* Returns the smallest signed C type capable of holding integers
55    from MIN to MAX.  */
56
57 static const char *
58 smallest_integral_type (int min, int max)
59 {
60   if (option[ANSIC] | option[CPLUSPLUS])
61     if (min >= SCHAR_MIN && max <= SCHAR_MAX) return "signed char";
62   if (min >= SHRT_MIN && max <= SHRT_MAX) return "short";
63   return "int";
64 }
65
66 /* ------------------------------------------------------------------------- */
67
68 /* Constructor.
69    Note about the keyword list starting at head:
70    - The list is ordered by increasing _hash_value.  This has been achieved
71      by Search::sort().
72    - Duplicates, i.e. keywords with the same _selchars set, are chained
73      through the _duplicate_link pointer.  Only one representative per
74      duplicate equivalence class remains on the linear keyword list.
75    - Accidental duplicates, i.e. keywords for which the _asso_values[] search
76      couldn't achieve different hash values, cannot occur on the linear
77      keyword list.  Search::optimize would catch this mistake.
78  */
79 Output::Output (KeywordExt_List *head, const char *struct_decl,
80                 unsigned int struct_decl_lineno, const char *return_type,
81                 const char *struct_tag, const char *verbatim_declarations,
82                 const char *verbatim_declarations_end,
83                 unsigned int verbatim_declarations_lineno,
84                 const char *verbatim_code, const char *verbatim_code_end,
85                 unsigned int verbatim_code_lineno, bool charset_dependent,
86                 int total_keys, int max_key_len, int min_key_len,
87                 const Positions& positions, const unsigned int *alpha_inc,
88                 int total_duplicates, unsigned int alpha_size,
89                 const int *asso_values)
90   : _head (head), _struct_decl (struct_decl),
91     _struct_decl_lineno (struct_decl_lineno), _return_type (return_type),
92     _struct_tag (struct_tag),
93     _verbatim_declarations (verbatim_declarations),
94     _verbatim_declarations_end (verbatim_declarations_end),
95     _verbatim_declarations_lineno (verbatim_declarations_lineno),
96     _verbatim_code (verbatim_code),
97     _verbatim_code_end (verbatim_code_end),
98     _verbatim_code_lineno (verbatim_code_lineno),
99     _charset_dependent (charset_dependent),
100     _total_keys (total_keys),
101     _max_key_len (max_key_len), _min_key_len (min_key_len),
102     _key_positions (positions), _alpha_inc (alpha_inc),
103     _total_duplicates (total_duplicates), _alpha_size (alpha_size),
104     _asso_values (asso_values)
105 {
106 }
107
108 /* ------------------------------------------------------------------------- */
109
110 /* Computes the minimum and maximum hash values, and stores them
111    in _min_hash_value and _max_hash_value.  */
112
113 void
114 Output::compute_min_max ()
115 {
116   /* Since the list is already sorted by hash value all we need to do is
117      to look at the first and the last element of the list.  */
118
119   _min_hash_value = _head->first()->_hash_value;
120
121   KeywordExt_List *temp;
122   for (temp = _head; temp->rest(); temp = temp->rest())
123     ;
124   _max_hash_value = temp->first()->_hash_value;
125 }
126
127 /* ------------------------------------------------------------------------- */
128
129 /* Returns the number of different hash values.  */
130
131 int
132 Output::num_hash_values () const
133 {
134   /* Since the list is already sorted by hash value and doesn't contain
135      duplicates, we can simply count the number of keywords on the list.  */
136   int count = 0;
137   for (KeywordExt_List *temp = _head; temp; temp = temp->rest())
138     count++;
139   return count;
140 }
141
142 /* -------------------- Output_Constants and subclasses -------------------- */
143
144 /* This class outputs an enumeration defining some constants.  */
145
146 struct Output_Constants
147 {
148   virtual void          output_start () = 0;
149   virtual void          output_item (const char *name, int value) = 0;
150   virtual void          output_end () = 0;
151                         Output_Constants () {}
152   virtual               ~Output_Constants () {}
153 };
154
155 /* This class outputs an enumeration in #define syntax.  */
156
157 struct Output_Defines : public Output_Constants
158 {
159   virtual void          output_start ();
160   virtual void          output_item (const char *name, int value);
161   virtual void          output_end ();
162                         Output_Defines () {}
163   virtual               ~Output_Defines () {}
164 };
165
166 void Output_Defines::output_start ()
167 {
168   printf ("\n");
169 }
170
171 void Output_Defines::output_item (const char *name, int value)
172 {
173   printf ("#define %s %d\n", name, value);
174 }
175
176 void Output_Defines::output_end ()
177 {
178 }
179
180 /* This class outputs an enumeration using 'enum'.  */
181
182 struct Output_Enum : public Output_Constants
183 {
184   virtual void          output_start ();
185   virtual void          output_item (const char *name, int value);
186   virtual void          output_end ();
187                         Output_Enum (const char *indent)
188                           : _indentation (indent) {}
189   virtual               ~Output_Enum () {}
190 private:
191   const char *_indentation;
192   bool _pending_comma;
193 };
194
195 void Output_Enum::output_start ()
196 {
197   printf ("%senum\n"
198           "%s  {\n",
199           _indentation, _indentation);
200   _pending_comma = false;
201 }
202
203 void Output_Enum::output_item (const char *name, int value)
204 {
205   if (_pending_comma)
206     printf (",\n");
207   printf ("%s    %s = %d", _indentation, name, value);
208   _pending_comma = true;
209 }
210
211 void Output_Enum::output_end ()
212 {
213   if (_pending_comma)
214     printf ("\n");
215   printf ("%s  };\n\n", _indentation);
216 }
217
218 /* Outputs the maximum and minimum hash values etc.  */
219
220 void
221 Output::output_constants (struct Output_Constants& style) const
222 {
223   style.output_start ();
224   style.output_item ("TOTAL_KEYWORDS", _total_keys);
225   style.output_item ("MIN_WORD_LENGTH", _min_key_len);
226   style.output_item ("MAX_WORD_LENGTH", _max_key_len);
227   style.output_item ("MIN_HASH_VALUE", _min_hash_value);
228   style.output_item ("MAX_HASH_VALUE", _max_hash_value);
229   style.output_end ();
230 }
231
232 /* ------------------------------------------------------------------------- */
233
234 /* We use a downcase table because when called repeatedly, the code
235        gperf_downcase[c]
236    is faster than
237        if (c >= 'A' && c <= 'Z')
238          c += 'a' - 'A';
239  */
240 #define USE_DOWNCASE_TABLE 1
241
242 #if USE_DOWNCASE_TABLE
243
244 /* Output gperf's ASCII-downcase table.  */
245
246 static void
247 output_upperlower_table ()
248 {
249   unsigned int c;
250
251   printf ("#ifndef GPERF_DOWNCASE\n"
252           "#define GPERF_DOWNCASE 1\n"
253           "static unsigned char gperf_downcase[256] =\n"
254           "  {");
255   for (c = 0; c < 256; c++)
256     {
257       if ((c % 15) == 0)
258         printf ("\n   ");
259       printf (" %3d", c >= 'A' && c <= 'Z' ? c + 'a' - 'A' : c);
260       if (c < 255)
261         printf (",");
262     }
263   printf ("\n"
264           "  };\n"
265           "#endif\n\n");
266 }
267
268 #endif
269
270 /* Output gperf's ASCII-case insensitive strcmp replacement.  */
271
272 static void
273 output_upperlower_strcmp ()
274 {
275   printf ("#ifndef GPERF_CASE_STRCMP\n"
276           "#define GPERF_CASE_STRCMP 1\n"
277           "static int\n"
278           "gperf_case_strcmp ");
279   printf (option[KRC] ?
280                "(s1, s2)\n"
281           "     register char *s1;\n"
282           "     register char *s2;\n" :
283           option[C] ?
284                "(s1, s2)\n"
285           "     register const char *s1;\n"
286           "     register const char *s2;\n" :
287           option[ANSIC] | option[CPLUSPLUS] ?
288                "(register const char *s1, register const char *s2)\n" :
289           "");
290   #if USE_DOWNCASE_TABLE
291   printf ("{\n"
292           "  for (;;)\n"
293           "    {\n"
294           "      unsigned char c1 = gperf_downcase[(unsigned char)*s1++];\n"
295           "      unsigned char c2 = gperf_downcase[(unsigned char)*s2++];\n"
296           "      if (c1 != 0 && c1 == c2)\n"
297           "        continue;\n"
298           "      return (int)c1 - (int)c2;\n"
299           "    }\n"
300           "}\n");
301   #else
302   printf ("{\n"
303           "  for (;;)\n"
304           "    {\n"
305           "      unsigned char c1 = *s1++;\n"
306           "      unsigned char c2 = *s2++;\n"
307           "      if (c1 >= 'A' && c1 <= 'Z')\n"
308           "        c1 += 'a' - 'A';\n"
309           "      if (c2 >= 'A' && c2 <= 'Z')\n"
310           "        c2 += 'a' - 'A';\n"
311           "      if (c1 != 0 && c1 == c2)\n"
312           "        continue;\n"
313           "      return (int)c1 - (int)c2;\n"
314           "    }\n"
315           "}\n");
316   #endif
317   printf ("#endif\n\n");
318 }
319
320 /* Output gperf's ASCII-case insensitive strncmp replacement.  */
321
322 static void
323 output_upperlower_strncmp ()
324 {
325   printf ("#ifndef GPERF_CASE_STRNCMP\n"
326           "#define GPERF_CASE_STRNCMP 1\n"
327           "static int\n"
328           "gperf_case_strncmp ");
329   printf (option[KRC] ?
330                "(s1, s2, n)\n"
331           "     register char *s1;\n"
332           "     register char *s2;\n"
333           "     register unsigned int n;\n" :
334           option[C] ?
335                "(s1, s2, n)\n"
336           "     register const char *s1;\n"
337           "     register const char *s2;\n"
338           "     register unsigned int n;\n" :
339           option[ANSIC] | option[CPLUSPLUS] ?
340                "(register const char *s1, register const char *s2, register unsigned int n)\n" :
341           "");
342   #if USE_DOWNCASE_TABLE
343   printf ("{\n"
344           "  for (; n > 0;)\n"
345           "    {\n"
346           "      unsigned char c1 = gperf_downcase[(unsigned char)*s1++];\n"
347           "      unsigned char c2 = gperf_downcase[(unsigned char)*s2++];\n"
348           "      if (c1 != 0 && c1 == c2)\n"
349           "        {\n"
350           "          n--;\n"
351           "          continue;\n"
352           "        }\n"
353           "      return (int)c1 - (int)c2;\n"
354           "    }\n"
355           "  return 0;\n"
356           "}\n");
357   #else
358   printf ("{\n"
359           "  for (; n > 0;)\n"
360           "    {\n"
361           "      unsigned char c1 = *s1++;\n"
362           "      unsigned char c2 = *s2++;\n"
363           "      if (c1 >= 'A' && c1 <= 'Z')\n"
364           "        c1 += 'a' - 'A';\n"
365           "      if (c2 >= 'A' && c2 <= 'Z')\n"
366           "        c2 += 'a' - 'A';\n"
367           "      if (c1 != 0 && c1 == c2)\n"
368           "        {\n"
369           "          n--;\n"
370           "          continue;\n"
371           "        }\n"
372           "      return (int)c1 - (int)c2;\n"
373           "    }\n"
374           "  return 0;\n"
375           "}\n");
376   #endif
377   printf ("#endif\n\n");
378 }
379
380 /* Output gperf's ASCII-case insensitive memcmp replacement.  */
381
382 static void
383 output_upperlower_memcmp ()
384 {
385   printf ("#ifndef GPERF_CASE_MEMCMP\n"
386           "#define GPERF_CASE_MEMCMP 1\n"
387           "static int\n"
388           "gperf_case_memcmp ");
389   printf (option[KRC] ?
390                "(s1, s2, n)\n"
391           "     register char *s1;\n"
392           "     register char *s2;\n"
393           "     register unsigned int n;\n" :
394           option[C] ?
395                "(s1, s2, n)\n"
396           "     register const char *s1;\n"
397           "     register const char *s2;\n"
398           "     register unsigned int n;\n" :
399           option[ANSIC] | option[CPLUSPLUS] ?
400                "(register const char *s1, register const char *s2, register unsigned int n)\n" :
401           "");
402   #if USE_DOWNCASE_TABLE
403   printf ("{\n"
404           "  for (; n > 0;)\n"
405           "    {\n"
406           "      unsigned char c1 = gperf_downcase[(unsigned char)*s1++];\n"
407           "      unsigned char c2 = gperf_downcase[(unsigned char)*s2++];\n"
408           "      if (c1 == c2)\n"
409           "        {\n"
410           "          n--;\n"
411           "          continue;\n"
412           "        }\n"
413           "      return (int)c1 - (int)c2;\n"
414           "    }\n"
415           "  return 0;\n"
416           "}\n");
417   #else
418   printf ("{\n"
419           "  for (; n > 0;)\n"
420           "    {\n"
421           "      unsigned char c1 = *s1++;\n"
422           "      unsigned char c2 = *s2++;\n"
423           "      if (c1 >= 'A' && c1 <= 'Z')\n"
424           "        c1 += 'a' - 'A';\n"
425           "      if (c2 >= 'A' && c2 <= 'Z')\n"
426           "        c2 += 'a' - 'A';\n"
427           "      if (c1 == c2)\n"
428           "        {\n"
429           "          n--;\n"
430           "          continue;\n"
431           "        }\n"
432           "      return (int)c1 - (int)c2;\n"
433           "    }\n"
434           "  return 0;\n"
435           "}\n");
436   #endif
437   printf ("#endif\n\n");
438 }
439
440 /* ------------------------------------------------------------------------- */
441
442 /* Outputs a keyword, as a string: enclosed in double quotes, escaping
443    backslashes, double quote and unprintable characters.  */
444
445 static void
446 output_string (const char *key, int len)
447 {
448   putchar ('"');
449   for (; len > 0; len--)
450     {
451       unsigned char c = static_cast<unsigned char>(*key++);
452       if (isprint (c))
453         {
454           if (c == '"' || c == '\\')
455             putchar ('\\');
456           putchar (c);
457         }
458       else
459         {
460           /* Use octal escapes, not hexadecimal escapes, because some old
461              C compilers didn't understand hexadecimal escapes, and because
462              hexadecimal escapes are not limited to 2 digits, thus needing
463              special care if the following character happens to be a digit.  */
464           putchar ('\\');
465           putchar ('0' + ((c >> 6) & 7));
466           putchar ('0' + ((c >> 3) & 7));
467           putchar ('0' + (c & 7));
468         }
469     }
470   putchar ('"');
471 }
472
473 /* ------------------------------------------------------------------------- */
474
475 /* Outputs a #line directive, referring to the given line number.  */
476
477 static void
478 output_line_directive (unsigned int lineno)
479 {
480   const char *file_name = option.get_input_file_name ();
481   if (file_name != NULL)
482     {
483       printf ("#line %u ", lineno);
484       output_string (file_name, strlen (file_name));
485       printf ("\n");
486     }
487 }
488
489 /* ------------------------------------------------------------------------- */
490
491 /* Outputs a type and a const specifier (i.e. "const " or "").
492    The output is terminated with a space.  */
493
494 static void
495 output_const_type (const char *const_string, const char *type_string)
496 {
497   if (type_string[strlen(type_string)-1] == '*')
498     /* For pointer types, put the 'const' after the type.  */
499     printf ("%s %s", type_string, const_string);
500   else
501     /* For scalar or struct types, put the 'const' before the type.  */
502     printf ("%s%s ", const_string, type_string);
503 }
504
505 /* ----------------------- Output_Expr and subclasses ----------------------- */
506
507 /* This class outputs a general expression.  */
508
509 struct Output_Expr
510 {
511   virtual void          output_expr () const = 0;
512                         Output_Expr () {}
513   virtual               ~Output_Expr () {}
514 };
515
516 /* This class outputs an expression formed by a single string.  */
517
518 struct Output_Expr1 : public Output_Expr
519 {
520   virtual void          output_expr () const;
521                         Output_Expr1 (const char *piece1) : _p1 (piece1) {}
522   virtual               ~Output_Expr1 () {}
523 private:
524   const char *_p1;
525 };
526
527 void Output_Expr1::output_expr () const
528 {
529   printf ("%s", _p1);
530 }
531
532 #if 0 /* unused */
533
534 /* This class outputs an expression formed by the concatenation of two
535    strings.  */
536
537 struct Output_Expr2 : public Output_Expr
538 {
539   virtual void          output_expr () const;
540                         Output_Expr2 (const char *piece1, const char *piece2)
541                           : _p1 (piece1), _p2 (piece2) {}
542   virtual               ~Output_Expr2 () {}
543 private:
544   const char *_p1;
545   const char *_p2;
546 };
547
548 void Output_Expr2::output_expr () const
549 {
550   printf ("%s%s", _p1, _p2);
551 }
552
553 #endif
554
555 /* --------------------- Output_Compare and subclasses --------------------- */
556
557 /* This class outputs a comparison expression.  */
558
559 struct Output_Compare
560 {
561   /* Outputs the comparison expression.
562      expr1 outputs a simple expression of type 'const char *' referring to
563      the string being looked up.  expr2 outputs a simple expression of type
564      'const char *' referring to the constant string stored in the gperf
565      generated hash table.  */
566   virtual void          output_comparison (const Output_Expr& expr1,
567                                            const Output_Expr& expr2) const = 0;
568   /* Outputs the comparison expression for the first byte.
569      Returns true if the this comparison is complete.  */
570   bool                  output_firstchar_comparison (const Output_Expr& expr1,
571                                                      const Output_Expr& expr2) const;
572                         Output_Compare () {}
573   virtual               ~Output_Compare () {}
574 };
575
576 bool Output_Compare::output_firstchar_comparison (const Output_Expr& expr1,
577                                                   const Output_Expr& expr2) const
578 {
579   /* First, we emit a comparison of the first byte of the two strings.
580      This catches most cases where the string being looked up is not in the
581      hash table but happens to have the same hash code as an element of the
582      hash table.  */
583   if (option[UPPERLOWER])
584     {
585       /* Incomplete comparison, just for speedup.  */
586       printf ("(((unsigned char)*");
587       expr1.output_expr ();
588       printf (" ^ (unsigned char)*");
589       expr2.output_expr ();
590       printf (") & ~32) == 0");
591       return false;
592     }
593   else
594     {
595       /* Complete comparison.  */
596       printf ("*");
597       expr1.output_expr ();
598       printf (" == *");
599       expr2.output_expr ();
600       return true;
601     }
602 }
603
604 /* This class outputs a comparison using strcmp.  */
605
606 struct Output_Compare_Strcmp : public Output_Compare
607 {
608   virtual void          output_comparison (const Output_Expr& expr1,
609                                            const Output_Expr& expr2) const;
610                         Output_Compare_Strcmp () {}
611   virtual               ~Output_Compare_Strcmp () {}
612 };
613
614 void Output_Compare_Strcmp::output_comparison (const Output_Expr& expr1,
615                                                const Output_Expr& expr2) const
616 {
617   bool firstchar_done = output_firstchar_comparison (expr1, expr2);
618   printf (" && !");
619   if (option[UPPERLOWER])
620     printf ("gperf_case_");
621   printf ("strcmp (");
622   if (firstchar_done)
623     {
624       expr1.output_expr ();
625       printf (" + 1, ");
626       expr2.output_expr ();
627       printf (" + 1");
628     }
629   else
630     {
631       expr1.output_expr ();
632       printf (", ");
633       expr2.output_expr ();
634     }
635   printf (")");
636 }
637
638 /* This class outputs a comparison using strncmp.
639    Note that the length of expr1 will be available through the local variable
640    'len'.  */
641
642 struct Output_Compare_Strncmp : public Output_Compare
643 {
644   virtual void          output_comparison (const Output_Expr& expr1,
645                                            const Output_Expr& expr2) const;
646                         Output_Compare_Strncmp () {}
647   virtual               ~Output_Compare_Strncmp () {}
648 };
649
650 void Output_Compare_Strncmp::output_comparison (const Output_Expr& expr1,
651                                                 const Output_Expr& expr2) const
652 {
653   bool firstchar_done = output_firstchar_comparison (expr1, expr2);
654   printf (" && !");
655   if (option[UPPERLOWER])
656     printf ("gperf_case_");
657   printf ("strncmp (");
658   if (firstchar_done)
659     {
660       expr1.output_expr ();
661       printf (" + 1, ");
662       expr2.output_expr ();
663       printf (" + 1, len - 1");
664     }
665   else
666     {
667       expr1.output_expr ();
668       printf (", ");
669       expr2.output_expr ();
670       printf (", len");
671     }
672   printf (") && ");
673   expr2.output_expr ();
674   printf ("[len] == '\\0'");
675 }
676
677 /* This class outputs a comparison using memcmp.
678    Note that the length of expr1 (available through the local variable 'len')
679    must be verified to be equal to the length of expr2 prior to this
680    comparison.  */
681
682 struct Output_Compare_Memcmp : public Output_Compare
683 {
684   virtual void          output_comparison (const Output_Expr& expr1,
685                                            const Output_Expr& expr2) const;
686                         Output_Compare_Memcmp () {}
687   virtual               ~Output_Compare_Memcmp () {}
688 };
689
690 void Output_Compare_Memcmp::output_comparison (const Output_Expr& expr1,
691                                                const Output_Expr& expr2) const
692 {
693   bool firstchar_done = output_firstchar_comparison (expr1, expr2);
694   printf (" && !");
695   if (option[UPPERLOWER])
696     printf ("gperf_case_");
697   printf ("memcmp (");
698   if (firstchar_done)
699     {
700       expr1.output_expr ();
701       printf (" + 1, ");
702       expr2.output_expr ();
703       printf (" + 1, len - 1");
704     }
705   else
706     {
707       expr1.output_expr ();
708       printf (", ");
709       expr2.output_expr ();
710       printf (", len");
711     }
712   printf (")");
713 }
714
715 /* ------------------------------------------------------------------------- */
716
717 /* Generates a C expression for an asso_values[] reference.  */
718
719 void
720 Output::output_asso_values_ref (int pos) const
721 {
722   printf ("asso_values[");
723   /* Always cast to unsigned char.  This is necessary when the alpha_inc
724      is nonzero, and also avoids a gcc warning "subscript has type 'char'".  */
725   printf ("(unsigned char)");
726   if (pos == Positions::LASTCHAR)
727     printf ("str[len - 1]");
728   else
729     {
730       printf ("str[%d]", pos);
731       if (_alpha_inc[pos])
732         printf ("+%u", _alpha_inc[pos]);
733     }
734   printf ("]");
735 }
736
737 /* Generates C code for the hash function that returns the
738    proper encoding for each keyword.
739    The hash function has the signature
740      unsigned int <hash> (const char *str, unsigned int len).  */
741
742 void
743 Output::output_hash_function () const
744 {
745   /* Output the function's head.  */
746   if (option[CPLUSPLUS])
747     printf ("inline ");
748   else if (option[KRC] | option[C] | option[ANSIC])
749     printf ("#ifdef __GNUC__\n"
750             "__inline\n"
751             "#else\n"
752             "#ifdef __cplusplus\n"
753             "inline\n"
754             "#endif\n"
755             "#endif\n");
756
757   if (/* The function does not use the 'str' argument?  */
758       _key_positions.get_size() == 0
759       || /* The function uses 'str', but not the 'len' argument?  */
760          (option[NOLENGTH]
761           && _key_positions[0] < _min_key_len
762           && _key_positions[_key_positions.get_size() - 1] != Positions::LASTCHAR))
763     /* Pacify lint.  */
764     printf ("/*ARGSUSED*/\n");
765
766   if (option[KRC] | option[C] | option[ANSIC])
767     printf ("static ");
768   printf ("unsigned int\n");
769   if (option[CPLUSPLUS])
770     printf ("%s::", option.get_class_name ());
771   printf ("%s ", option.get_hash_name ());
772   printf (option[KRC] ?
773                  "(str, len)\n"
774             "     register char *str;\n"
775             "     register unsigned int len;\n" :
776           option[C] ?
777                  "(str, len)\n"
778             "     register const char *str;\n"
779             "     register unsigned int len;\n" :
780           option[ANSIC] | option[CPLUSPLUS] ?
781                  "(register const char *str, register unsigned int len)\n" :
782           "");
783
784   /* Note that when the hash function is called, it has already been verified
785      that  min_key_len <= len <= max_key_len.  */
786
787   /* Output the function's body.  */
788   printf ("{\n");
789
790   /* First the asso_values array.  */
791   if (_key_positions.get_size() > 0)
792     {
793       printf ("  static %s%s asso_values[] =\n"
794               "    {",
795               const_readonly_array,
796               smallest_integral_type (_max_hash_value + 1));
797
798       const int columns = 10;
799
800       /* Calculate maximum number of digits required for MAX_HASH_VALUE.  */
801       int field_width = 2;
802       for (int trunc = _max_hash_value; (trunc /= 10) > 0;)
803         field_width++;
804
805       for (unsigned int count = 0; count < _alpha_size; count++)
806         {
807           if (count > 0)
808             printf (",");
809           if ((count % columns) == 0)
810             printf ("\n     ");
811           printf ("%*d", field_width, _asso_values[count]);
812         }
813
814       printf ("\n"
815               "    };\n");
816     }
817
818   if (_key_positions.get_size() == 0)
819     {
820       /* Trivial case: No key positions at all.  */
821       printf ("  return %s;\n",
822               option[NOLENGTH] ? "0" : "len");
823     }
824   else
825     {
826       /* Iterate through the key positions.  Remember that Positions::sort()
827          has sorted them in decreasing order, with Positions::LASTCHAR coming
828          last.  */
829       PositionIterator iter = _key_positions.iterator(_max_key_len);
830       int key_pos;
831
832       /* Get the highest key position.  */
833       key_pos = iter.next ();
834
835       if (key_pos == Positions::LASTCHAR || key_pos < _min_key_len)
836         {
837           /* We can perform additional optimizations here:
838              Write it out as a single expression. Note that the values
839              are added as 'int's even though the asso_values array may
840              contain 'unsigned char's or 'unsigned short's.  */
841
842           printf ("  return %s",
843                   option[NOLENGTH] ? "" : "len + ");
844
845           if (_key_positions.get_size() == 2
846               && _key_positions[0] == 0
847               && _key_positions[1] == Positions::LASTCHAR)
848             /* Optimize special case of "-k 1,$".  */
849             {
850               output_asso_values_ref (Positions::LASTCHAR);
851               printf (" + ");
852               output_asso_values_ref (0);
853             }
854           else
855             {
856               for (; key_pos != Positions::LASTCHAR; )
857                 {
858                   output_asso_values_ref (key_pos);
859                   if ((key_pos = iter.next ()) != PositionIterator::EOS)
860                     printf (" + ");
861                   else
862                     break;
863                 }
864
865               if (key_pos == Positions::LASTCHAR)
866                 output_asso_values_ref (Positions::LASTCHAR);
867             }
868
869           printf (";\n");
870         }
871       else
872         {
873           /* We've got to use the correct, but brute force, technique.  */
874           printf ("  register int hval = %s;\n\n"
875                   "  switch (%s)\n"
876                   "    {\n"
877                   "      default:\n",
878                   option[NOLENGTH] ? "0" : "len",
879                   option[NOLENGTH] ? "len" : "hval");
880
881           while (key_pos != Positions::LASTCHAR && key_pos >= _max_key_len)
882             if ((key_pos = iter.next ()) == PositionIterator::EOS)
883               break;
884
885           if (key_pos != PositionIterator::EOS && key_pos != Positions::LASTCHAR)
886             {
887               int i = key_pos;
888               do
889                 {
890                   if (i > key_pos)
891                     printf ("      /*FALLTHROUGH*/\n"); /* Pacify lint.  */
892                   for ( ; i > key_pos; i--)
893                     printf ("      case %d:\n", i);
894
895                   printf ("        hval += ");
896                   output_asso_values_ref (key_pos);
897                   printf (";\n");
898
899                   key_pos = iter.next ();
900                 }
901               while (key_pos != PositionIterator::EOS && key_pos != Positions::LASTCHAR);
902
903               if (i >= _min_key_len)
904                 printf ("      /*FALLTHROUGH*/\n"); /* Pacify lint.  */
905               for ( ; i >= _min_key_len; i--)
906                 printf ("      case %d:\n", i);
907             }
908
909           printf ("        break;\n"
910                   "    }\n"
911                   "  return hval");
912           if (key_pos == Positions::LASTCHAR)
913             {
914               printf (" + ");
915               output_asso_values_ref (Positions::LASTCHAR);
916             }
917           printf (";\n");
918         }
919     }
920   printf ("}\n\n");
921 }
922
923 /* ------------------------------------------------------------------------- */
924
925 /* Prints out a table of keyword lengths, for use with the
926    comparison code in generated function 'in_word_set'.
927    Only called if option[LENTABLE].  */
928
929 void
930 Output::output_keylength_table () const
931 {
932   const int columns = 14;
933   const char * const indent = option[GLOBAL] ? "" : "  ";
934
935   printf ("%sstatic %s%s %s[] =\n"
936           "%s  {",
937           indent, const_readonly_array,
938           smallest_integral_type (_max_key_len),
939           option.get_lengthtable_name (),
940           indent);
941
942   /* Generate an array of lengths, similar to output_keyword_table.  */
943   int index;
944   int column;
945   KeywordExt_List *temp;
946
947   column = 0;
948   for (temp = _head, index = 0; temp; temp = temp->rest())
949     {
950       KeywordExt *keyword = temp->first();
951
952       /* If generating a switch statement, and there is no user defined type,
953          we generate non-duplicates directly in the code.  Only duplicates go
954          into the table.  */
955       if (option[SWITCH] && !option[TYPE] && !keyword->_duplicate_link)
956         continue;
957
958       if (index < keyword->_hash_value && !option[SWITCH] && !option[DUP])
959         {
960           /* Some blank entries.  */
961           for ( ; index < keyword->_hash_value; index++)
962             {
963               if (index > 0)
964                 printf (",");
965               if ((column++ % columns) == 0)
966                 printf ("\n%s   ", indent);
967               printf ("%3d", 0);
968             }
969         }
970
971       if (index > 0)
972         printf (",");
973       if ((column++ % columns) == 0)
974         printf("\n%s   ", indent);
975       printf ("%3d", keyword->_allchars_length);
976       index++;
977
978       /* Deal with duplicates specially.  */
979       if (keyword->_duplicate_link) // implies option[DUP]
980         for (KeywordExt *links = keyword->_duplicate_link; links; links = links->_duplicate_link)
981           {
982             printf (",");
983             if ((column++ % columns) == 0)
984               printf("\n%s   ", indent);
985             printf ("%3d", links->_allchars_length);
986             index++;
987           }
988     }
989
990   printf ("\n%s  };\n", indent);
991   if (option[GLOBAL])
992     printf ("\n");
993 }
994
995 /* ------------------------------------------------------------------------- */
996
997 /* Prints out the string pool, containing the strings of the keyword table.
998    Only called if option[SHAREDLIB].  */
999
1000 void
1001 Output::output_string_pool () const
1002 {
1003   const char * const indent = option[TYPE] || option[GLOBAL] ? "" : "  ";
1004   int index;
1005   KeywordExt_List *temp;
1006
1007   printf ("%sstruct %s_t\n"
1008           "%s  {\n",
1009           indent, option.get_stringpool_name (), indent);
1010   for (temp = _head, index = 0; temp; temp = temp->rest())
1011     {
1012       KeywordExt *keyword = temp->first();
1013
1014       /* If generating a switch statement, and there is no user defined type,
1015          we generate non-duplicates directly in the code.  Only duplicates go
1016          into the table.  */
1017       if (option[SWITCH] && !option[TYPE] && !keyword->_duplicate_link)
1018         continue;
1019
1020       if (!option[SWITCH] && !option[DUP])
1021         index = keyword->_hash_value;
1022
1023       printf ("%s    char %s_str%d[sizeof(",
1024               indent, option.get_stringpool_name (), index);
1025       output_string (keyword->_allchars, keyword->_allchars_length);
1026       printf (")];\n");
1027
1028       /* Deal with duplicates specially.  */
1029       if (keyword->_duplicate_link) // implies option[DUP]
1030         for (KeywordExt *links = keyword->_duplicate_link; links; links = links->_duplicate_link)
1031           if (!(links->_allchars_length == keyword->_allchars_length
1032                 && memcmp (links->_allchars, keyword->_allchars,
1033                            keyword->_allchars_length) == 0))
1034             {
1035               index++;
1036               printf ("%s    char %s_str%d[sizeof(",
1037                       indent, option.get_stringpool_name (), index);
1038               output_string (links->_allchars, links->_allchars_length);
1039               printf (")];\n");
1040             }
1041
1042       index++;
1043     }
1044   printf ("%s  };\n",
1045           indent);
1046
1047   printf ("%sstatic %sstruct %s_t %s_contents =\n"
1048           "%s  {\n",
1049           indent, const_readonly_array, option.get_stringpool_name (),
1050           option.get_stringpool_name (), indent);
1051   for (temp = _head, index = 0; temp; temp = temp->rest())
1052     {
1053       KeywordExt *keyword = temp->first();
1054
1055       /* If generating a switch statement, and there is no user defined type,
1056          we generate non-duplicates directly in the code.  Only duplicates go
1057          into the table.  */
1058       if (option[SWITCH] && !option[TYPE] && !keyword->_duplicate_link)
1059         continue;
1060
1061       if (index > 0)
1062         printf (",\n");
1063
1064       if (!option[SWITCH] && !option[DUP])
1065         index = keyword->_hash_value;
1066
1067       printf ("%s    ",
1068               indent);
1069       output_string (keyword->_allchars, keyword->_allchars_length);
1070
1071       /* Deal with duplicates specially.  */
1072       if (keyword->_duplicate_link) // implies option[DUP]
1073         for (KeywordExt *links = keyword->_duplicate_link; links; links = links->_duplicate_link)
1074           if (!(links->_allchars_length == keyword->_allchars_length
1075                 && memcmp (links->_allchars, keyword->_allchars,
1076                            keyword->_allchars_length) == 0))
1077             {
1078               index++;
1079               printf (",\n");
1080               printf ("%s    ",
1081                       indent);
1082               output_string (links->_allchars, links->_allchars_length);
1083             }
1084
1085       index++;
1086     }
1087   if (index > 0)
1088     printf ("\n");
1089   printf ("%s  };\n",
1090           indent);
1091   printf ("%s#define %s ((%schar *) &%s_contents)\n",
1092           indent, option.get_stringpool_name (), const_always,
1093           option.get_stringpool_name ());
1094   if (option[GLOBAL])
1095     printf ("\n");
1096 }
1097
1098 /* ------------------------------------------------------------------------- */
1099
1100 static void
1101 output_keyword_entry (KeywordExt *temp, int stringpool_index, const char *indent)
1102 {
1103   if (option[TYPE])
1104     output_line_directive (temp->_lineno);
1105   printf ("%s    ", indent);
1106   if (option[TYPE])
1107     printf ("{");
1108   if (option[SHAREDLIB])
1109     printf("offsetof(struct %s_t, %s_str%d)", option.get_stringpool_name (), option.get_stringpool_name (), stringpool_index);
1110   else
1111     output_string (temp->_allchars, temp->_allchars_length);
1112   if (option[TYPE])
1113     {
1114       if (strlen (temp->_rest) > 0)
1115         printf (",%s", temp->_rest);
1116       printf ("}");
1117     }
1118   if (option[DEBUG])
1119     printf (" /* hash value = %d, index = %d */",
1120             temp->_hash_value, temp->_final_index);
1121 }
1122
1123 static void
1124 output_keyword_blank_entries (int count, const char *indent)
1125 {
1126   int columns;
1127   if (option[TYPE])
1128     {
1129       columns = 58 / (4 + (option[SHAREDLIB] ? 2 : option[NULLSTRINGS] ? 8 : 2)
1130                         + strlen (option.get_initializer_suffix()));
1131       if (columns == 0)
1132         columns = 1;
1133     }
1134   else
1135     {
1136       columns = (option[SHAREDLIB] ? 9 : option[NULLSTRINGS] ? 4 : 9);
1137     }
1138   int column = 0;
1139   for (int i = 0; i < count; i++)
1140     {
1141       if ((column % columns) == 0)
1142         {
1143           if (i > 0)
1144             printf (",\n");
1145           printf ("%s    ", indent);
1146         }
1147       else
1148         {
1149           if (i > 0)
1150             printf (", ");
1151         }
1152       if (option[TYPE])
1153         printf ("{");
1154       if (option[SHAREDLIB])
1155         printf ("-1");
1156       else
1157         {
1158           if (option[NULLSTRINGS])
1159             printf ("(char*)0");
1160           else
1161             printf ("\"\"");
1162         }
1163       if (option[TYPE])
1164         printf ("%s}", option.get_initializer_suffix());
1165       column++;
1166     }
1167 }
1168
1169 /* Prints out the array containing the keywords for the hash function.  */
1170
1171 void
1172 Output::output_keyword_table () const
1173 {
1174   const char *indent  = option[GLOBAL] ? "" : "  ";
1175   int index;
1176   KeywordExt_List *temp;
1177
1178   printf ("%sstatic ",
1179           indent);
1180   output_const_type (const_readonly_array, _wordlist_eltype);
1181   printf ("%s[] =\n"
1182           "%s  {\n",
1183           option.get_wordlist_name (),
1184           indent);
1185
1186   /* Generate an array of reserved words at appropriate locations.  */
1187
1188   for (temp = _head, index = 0; temp; temp = temp->rest())
1189     {
1190       KeywordExt *keyword = temp->first();
1191
1192       /* If generating a switch statement, and there is no user defined type,
1193          we generate non-duplicates directly in the code.  Only duplicates go
1194          into the table.  */
1195       if (option[SWITCH] && !option[TYPE] && !keyword->_duplicate_link)
1196         continue;
1197
1198       if (index > 0)
1199         printf (",\n");
1200
1201       if (index < keyword->_hash_value && !option[SWITCH] && !option[DUP])
1202         {
1203           /* Some blank entries.  */
1204           output_keyword_blank_entries (keyword->_hash_value - index, indent);
1205           printf (",\n");
1206           index = keyword->_hash_value;
1207         }
1208
1209       keyword->_final_index = index;
1210
1211       output_keyword_entry (keyword, index, indent);
1212
1213       /* Deal with duplicates specially.  */
1214       if (keyword->_duplicate_link) // implies option[DUP]
1215         for (KeywordExt *links = keyword->_duplicate_link; links; links = links->_duplicate_link)
1216           {
1217             links->_final_index = ++index;
1218             printf (",\n");
1219             int stringpool_index =
1220               (links->_allchars_length == keyword->_allchars_length
1221                && memcmp (links->_allchars, keyword->_allchars,
1222                           keyword->_allchars_length) == 0
1223                ? keyword->_final_index
1224                : links->_final_index);
1225             output_keyword_entry (links, stringpool_index, indent);
1226           }
1227
1228       index++;
1229     }
1230   if (index > 0)
1231     printf ("\n");
1232
1233   printf ("%s  };\n\n", indent);
1234 }
1235
1236 /* ------------------------------------------------------------------------- */
1237
1238 /* Generates the large, sparse table that maps hash values into
1239    the smaller, contiguous range of the keyword table.  */
1240
1241 void
1242 Output::output_lookup_array () const
1243 {
1244   if (option[DUP])
1245     {
1246       const int DEFAULT_VALUE = -1;
1247
1248       /* Because of the way output_keyword_table works, every duplicate set is
1249          stored contiguously in the wordlist array.  */
1250       struct duplicate_entry
1251         {
1252           int hash_value; /* Hash value for this particular duplicate set.  */
1253           int index;      /* Index into the main keyword storage array.  */
1254           int count;      /* Number of consecutive duplicates at this index.  */
1255         };
1256
1257       duplicate_entry *duplicates = new duplicate_entry[_total_duplicates];
1258       int *lookup_array = new int[_max_hash_value + 1 + 2*_total_duplicates];
1259       int lookup_array_size = _max_hash_value + 1;
1260       duplicate_entry *dup_ptr = &duplicates[0];
1261       int *lookup_ptr = &lookup_array[_max_hash_value + 1 + 2*_total_duplicates];
1262
1263       while (lookup_ptr > lookup_array)
1264         *--lookup_ptr = DEFAULT_VALUE;
1265
1266       /* Now dup_ptr = &duplicates[0] and lookup_ptr = &lookup_array[0].  */
1267
1268       for (KeywordExt_List *temp = _head; temp; temp = temp->rest())
1269         {
1270           int hash_value = temp->first()->_hash_value;
1271           lookup_array[hash_value] = temp->first()->_final_index;
1272           if (option[DEBUG])
1273             fprintf (stderr, "keyword = %.*s, index = %d\n",
1274                      temp->first()->_allchars_length, temp->first()->_allchars, temp->first()->_final_index);
1275           if (temp->first()->_duplicate_link)
1276             {
1277               /* Start a duplicate entry.  */
1278               dup_ptr->hash_value = hash_value;
1279               dup_ptr->index = temp->first()->_final_index;
1280               dup_ptr->count = 1;
1281
1282               for (KeywordExt *ptr = temp->first()->_duplicate_link; ptr; ptr = ptr->_duplicate_link)
1283                 {
1284                   dup_ptr->count++;
1285                   if (option[DEBUG])
1286                     fprintf (stderr,
1287                              "static linked keyword = %.*s, index = %d\n",
1288                              ptr->_allchars_length, ptr->_allchars, ptr->_final_index);
1289                 }
1290               assert (dup_ptr->count >= 2);
1291               dup_ptr++;
1292             }
1293         }
1294
1295       while (dup_ptr > duplicates)
1296         {
1297           dup_ptr--;
1298
1299           if (option[DEBUG])
1300             fprintf (stderr,
1301                      "dup_ptr[%td]: hash_value = %d, index = %d, count = %d\n",
1302                      dup_ptr - duplicates,
1303                      dup_ptr->hash_value, dup_ptr->index, dup_ptr->count);
1304
1305           int i;
1306           /* Start searching for available space towards the right part
1307              of the lookup array.  */
1308           for (i = dup_ptr->hash_value; i < lookup_array_size-1; i++)
1309             if (lookup_array[i] == DEFAULT_VALUE
1310                 && lookup_array[i + 1] == DEFAULT_VALUE)
1311               goto found_i;
1312           /* If we didn't find it to the right look to the left instead...  */
1313           for (i = dup_ptr->hash_value-1; i >= 0; i--)
1314             if (lookup_array[i] == DEFAULT_VALUE
1315                 && lookup_array[i + 1] == DEFAULT_VALUE)
1316               goto found_i;
1317           /* Append to the end of lookup_array.  */
1318           i = lookup_array_size;
1319           lookup_array_size += 2;
1320         found_i:
1321           /* Put in an indirection from dup_ptr->_hash_value to i.
1322              At i and i+1 store dup_ptr->_final_index and dup_ptr->count.  */
1323           assert (lookup_array[dup_ptr->hash_value] == dup_ptr->index);
1324           lookup_array[dup_ptr->hash_value] = - 1 - _total_keys - i;
1325           lookup_array[i] = - _total_keys + dup_ptr->index;
1326           lookup_array[i + 1] = - dup_ptr->count;
1327           /* All these three values are <= -2, distinct from DEFAULT_VALUE.  */
1328         }
1329
1330       /* The values of the lookup array are now known.  */
1331
1332       int min = INT_MAX;
1333       int max = INT_MIN;
1334       lookup_ptr = lookup_array + lookup_array_size;
1335       while (lookup_ptr > lookup_array)
1336         {
1337           int val = *--lookup_ptr;
1338           if (min > val)
1339             min = val;
1340           if (max < val)
1341             max = val;
1342         }
1343
1344       const char *indent = option[GLOBAL] ? "" : "  ";
1345       printf ("%sstatic %s%s lookup[] =\n"
1346               "%s  {",
1347               indent, const_readonly_array, smallest_integral_type (min, max),
1348               indent);
1349
1350       int field_width;
1351       /* Calculate maximum number of digits required for MIN..MAX.  */
1352       {
1353         field_width = 2;
1354         for (int trunc = max; (trunc /= 10) > 0;)
1355           field_width++;
1356       }
1357       if (min < 0)
1358         {
1359           int neg_field_width = 2;
1360           for (int trunc = -min; (trunc /= 10) > 0;)
1361             neg_field_width++;
1362           neg_field_width++; /* account for the minus sign */
1363           if (field_width < neg_field_width)
1364             field_width = neg_field_width;
1365         }
1366
1367       const int columns = 42 / field_width;
1368       int column;
1369
1370       column = 0;
1371       for (int i = 0; i < lookup_array_size; i++)
1372         {
1373           if (i > 0)
1374             printf (",");
1375           if ((column++ % columns) == 0)
1376             printf("\n%s   ", indent);
1377           printf ("%*d", field_width, lookup_array[i]);
1378         }
1379       printf ("\n%s  };\n\n", indent);
1380
1381       delete[] duplicates;
1382       delete[] lookup_array;
1383     }
1384 }
1385
1386 /* ------------------------------------------------------------------------- */
1387
1388 /* Generate all pools needed for the lookup function.  */
1389
1390 void
1391 Output::output_lookup_pools () const
1392 {
1393   if (option[SWITCH])
1394     {
1395       if (option[TYPE] || (option[DUP] && _total_duplicates > 0))
1396         output_string_pool ();
1397     }
1398   else
1399     {
1400       output_string_pool ();
1401     }
1402 }
1403
1404 /* Generate all the tables needed for the lookup function.  */
1405
1406 void
1407 Output::output_lookup_tables () const
1408 {
1409   if (option[SWITCH])
1410     {
1411       /* Use the switch in place of lookup table.  */
1412       if (option[LENTABLE] && (option[DUP] && _total_duplicates > 0))
1413         output_keylength_table ();
1414       if (option[TYPE] || (option[DUP] && _total_duplicates > 0))
1415         output_keyword_table ();
1416     }
1417   else
1418     {
1419       /* Use the lookup table, in place of switch.  */
1420       if (option[LENTABLE])
1421         output_keylength_table ();
1422       output_keyword_table ();
1423       output_lookup_array ();
1424     }
1425 }
1426
1427 /* ------------------------------------------------------------------------- */
1428
1429 /* Output a single switch case (including duplicates).  Advance list.  */
1430
1431 static KeywordExt_List *
1432 output_switch_case (KeywordExt_List *list, int indent, int *jumps_away)
1433 {
1434   if (option[DEBUG])
1435     printf ("%*s/* hash value = %4d, keyword = \"%.*s\" */\n",
1436             indent, "", list->first()->_hash_value, list->first()->_allchars_length, list->first()->_allchars);
1437
1438   if (option[DUP] && list->first()->_duplicate_link)
1439     {
1440       if (option[LENTABLE])
1441         printf ("%*slengthptr = &%s[%d];\n",
1442                 indent, "", option.get_lengthtable_name (), list->first()->_final_index);
1443       printf ("%*swordptr = &%s[%d];\n",
1444               indent, "", option.get_wordlist_name (), list->first()->_final_index);
1445
1446       int count = 0;
1447       for (KeywordExt *links = list->first(); links; links = links->_duplicate_link)
1448         count++;
1449
1450       printf ("%*swordendptr = wordptr + %d;\n"
1451               "%*sgoto multicompare;\n",
1452               indent, "", count,
1453               indent, "");
1454       *jumps_away = 1;
1455     }
1456   else
1457     {
1458       if (option[LENTABLE])
1459         {
1460           printf ("%*sif (len == %d)\n"
1461                   "%*s  {\n",
1462                   indent, "", list->first()->_allchars_length,
1463                   indent, "");
1464           indent += 4;
1465         }
1466       printf ("%*sresword = ",
1467               indent, "");
1468       if (option[TYPE])
1469         printf ("&%s[%d]", option.get_wordlist_name (), list->first()->_final_index);
1470       else
1471         output_string (list->first()->_allchars, list->first()->_allchars_length);
1472       printf (";\n");
1473       printf ("%*sgoto compare;\n",
1474               indent, "");
1475       if (option[LENTABLE])
1476         {
1477           indent -= 4;
1478           printf ("%*s  }\n",
1479                   indent, "");
1480         }
1481       else
1482         *jumps_away = 1;
1483     }
1484
1485   return list->rest();
1486 }
1487
1488 /* Output a total of size cases, grouped into num_switches switch statements,
1489    where 0 < num_switches <= size.  */
1490
1491 static void
1492 output_switches (KeywordExt_List *list, int num_switches, int size, int min_hash_value, int max_hash_value, int indent)
1493 {
1494   if (option[DEBUG])
1495     printf ("%*s/* know %d <= key <= %d, contains %d cases */\n",
1496             indent, "", min_hash_value, max_hash_value, size);
1497
1498   if (num_switches > 1)
1499     {
1500       int part1 = num_switches / 2;
1501       int part2 = num_switches - part1;
1502       int size1 = static_cast<int>(static_cast<double>(size) / static_cast<double>(num_switches) * static_cast<double>(part1) + 0.5);
1503       int size2 = size - size1;
1504
1505       KeywordExt_List *temp = list;
1506       for (int count = size1; count > 0; count--)
1507         temp = temp->rest();
1508
1509       printf ("%*sif (key < %d)\n"
1510               "%*s  {\n",
1511               indent, "", temp->first()->_hash_value,
1512               indent, "");
1513
1514       output_switches (list, part1, size1, min_hash_value, temp->first()->_hash_value-1, indent+4);
1515
1516       printf ("%*s  }\n"
1517               "%*selse\n"
1518               "%*s  {\n",
1519               indent, "", indent, "", indent, "");
1520
1521       output_switches (temp, part2, size2, temp->first()->_hash_value, max_hash_value, indent+4);
1522
1523       printf ("%*s  }\n",
1524               indent, "");
1525     }
1526   else
1527     {
1528       /* Output a single switch.  */
1529       int lowest_case_value = list->first()->_hash_value;
1530       if (size == 1)
1531         {
1532           int jumps_away = 0;
1533           assert (min_hash_value <= lowest_case_value);
1534           assert (lowest_case_value <= max_hash_value);
1535           if (min_hash_value == max_hash_value)
1536             output_switch_case (list, indent, &jumps_away);
1537           else
1538             {
1539               printf ("%*sif (key == %d)\n"
1540                       "%*s  {\n",
1541                       indent, "", lowest_case_value,
1542                       indent, "");
1543               output_switch_case (list, indent+4, &jumps_away);
1544               printf ("%*s  }\n",
1545                       indent, "");
1546             }
1547         }
1548       else
1549         {
1550           if (lowest_case_value == 0)
1551             printf ("%*sswitch (key)\n", indent, "");
1552           else
1553             printf ("%*sswitch (key - %d)\n", indent, "", lowest_case_value);
1554           printf ("%*s  {\n",
1555                   indent, "");
1556           for (; size > 0; size--)
1557             {
1558               int jumps_away = 0;
1559               printf ("%*s    case %d:\n",
1560                       indent, "", list->first()->_hash_value - lowest_case_value);
1561               list = output_switch_case (list, indent+6, &jumps_away);
1562               if (!jumps_away)
1563                 printf ("%*s      break;\n",
1564                         indent, "");
1565             }
1566           printf ("%*s  }\n",
1567                   indent, "");
1568         }
1569     }
1570 }
1571
1572 /* Generates C code to perform the keyword lookup.  */
1573
1574 void
1575 Output::output_lookup_function_body (const Output_Compare& comparison) const
1576 {
1577   printf ("  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)\n"
1578           "    {\n"
1579           "      register int key = %s (str, len);\n\n",
1580           option.get_hash_name ());
1581
1582   if (option[SWITCH])
1583     {
1584       int switch_size = num_hash_values ();
1585       int num_switches = option.get_total_switches ();
1586       if (num_switches > switch_size)
1587         num_switches = switch_size;
1588
1589       printf ("      if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)\n"
1590               "        {\n");
1591       if (option[DUP] && _total_duplicates > 0)
1592         {
1593           if (option[LENTABLE])
1594             printf ("          register %s%s *lengthptr;\n",
1595                     const_always, smallest_integral_type (_max_key_len));
1596           printf ("          register ");
1597           output_const_type (const_readonly_array, _wordlist_eltype);
1598           printf ("*wordptr;\n");
1599           printf ("          register ");
1600           output_const_type (const_readonly_array, _wordlist_eltype);
1601           printf ("*wordendptr;\n");
1602         }
1603       if (option[TYPE])
1604         {
1605           printf ("          register ");
1606           output_const_type (const_readonly_array, _struct_tag);
1607           printf ("*resword;\n\n");
1608         }
1609       else
1610         printf ("          register %sresword;\n\n",
1611                 _struct_tag);
1612
1613       output_switches (_head, num_switches, switch_size, _min_hash_value, _max_hash_value, 10);
1614
1615       printf ("          return 0;\n");
1616       if (option[DUP] && _total_duplicates > 0)
1617         {
1618           int indent = 8;
1619           printf ("%*smulticompare:\n"
1620                   "%*s  while (wordptr < wordendptr)\n"
1621                   "%*s    {\n",
1622                   indent, "", indent, "", indent, "");
1623           if (option[LENTABLE])
1624             {
1625               printf ("%*s      if (len == *lengthptr)\n"
1626                       "%*s        {\n",
1627                       indent, "", indent, "");
1628               indent += 4;
1629             }
1630           printf ("%*s      register %schar *s = ",
1631                   indent, "", const_always);
1632           if (option[TYPE])
1633             printf ("wordptr->%s", option.get_slot_name ());
1634           else
1635             printf ("*wordptr");
1636           if (option[SHAREDLIB])
1637             printf (" + %s",
1638                     option.get_stringpool_name ());
1639           printf (";\n\n"
1640                   "%*s      if (",
1641                   indent, "");
1642           comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s"));
1643           printf (")\n"
1644                   "%*s        return %s;\n",
1645                   indent, "",
1646                   option[TYPE] ? "wordptr" : "s");
1647           if (option[LENTABLE])
1648             {
1649               indent -= 4;
1650               printf ("%*s        }\n",
1651                       indent, "");
1652             }
1653           if (option[LENTABLE])
1654             printf ("%*s      lengthptr++;\n",
1655                     indent, "");
1656           printf ("%*s      wordptr++;\n"
1657                   "%*s    }\n"
1658                   "%*s  return 0;\n",
1659                   indent, "", indent, "", indent, "");
1660         }
1661       printf ("        compare:\n");
1662       if (option[TYPE])
1663         {
1664           printf ("          {\n"
1665                   "            register %schar *s = resword->%s",
1666                   const_always, option.get_slot_name ());
1667           if (option[SHAREDLIB])
1668             printf (" + %s",
1669                     option.get_stringpool_name ());
1670           printf (";\n\n"
1671                   "            if (");
1672           comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s"));
1673           printf (")\n"
1674                   "              return resword;\n"
1675                   "          }\n");
1676         }
1677       else
1678         {
1679           printf ("          if (");
1680           comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("resword"));
1681           printf (")\n"
1682                   "            return resword;\n");
1683         }
1684       printf ("        }\n");
1685     }
1686   else
1687     {
1688       printf ("      if (key <= MAX_HASH_VALUE && key >= 0)\n");
1689
1690       if (option[DUP])
1691         {
1692           int indent = 8;
1693           printf ("%*s{\n"
1694                   "%*s  register int index = lookup[key];\n\n"
1695                   "%*s  if (index >= 0)\n",
1696                   indent, "", indent, "", indent, "");
1697           if (option[LENTABLE])
1698             {
1699               printf ("%*s    {\n"
1700                       "%*s      if (len == %s[index])\n",
1701                       indent, "", indent, "", option.get_lengthtable_name ());
1702               indent += 4;
1703             }
1704           printf ("%*s    {\n"
1705                   "%*s      register %schar *s = %s[index]",
1706                   indent, "",
1707                   indent, "", const_always, option.get_wordlist_name ());
1708           if (option[TYPE])
1709             printf (".%s", option.get_slot_name ());
1710           if (option[SHAREDLIB])
1711             printf (" + %s",
1712                     option.get_stringpool_name ());
1713           printf (";\n\n"
1714                   "%*s      if (",
1715                   indent, "");
1716           comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s"));
1717           printf (")\n"
1718                   "%*s        return ",
1719                   indent, "");
1720           if (option[TYPE])
1721             printf ("&%s[index]", option.get_wordlist_name ());
1722           else
1723             printf ("s");
1724           printf (";\n"
1725                   "%*s    }\n",
1726                   indent, "");
1727           if (option[LENTABLE])
1728             {
1729               indent -= 4;
1730               printf ("%*s    }\n", indent, "");
1731             }
1732           if (_total_duplicates > 0)
1733             {
1734               printf ("%*s  else if (index < -TOTAL_KEYWORDS)\n"
1735                       "%*s    {\n"
1736                       "%*s      register int offset = - 1 - TOTAL_KEYWORDS - index;\n",
1737                       indent, "", indent, "", indent, "");
1738               if (option[LENTABLE])
1739                 printf ("%*s      register %s%s *lengthptr = &%s[TOTAL_KEYWORDS + lookup[offset]];\n",
1740                         indent, "", const_always, smallest_integral_type (_max_key_len),
1741                         option.get_lengthtable_name ());
1742               printf ("%*s      register ",
1743                       indent, "");
1744               output_const_type (const_readonly_array, _wordlist_eltype);
1745               printf ("*wordptr = &%s[TOTAL_KEYWORDS + lookup[offset]];\n",
1746                       option.get_wordlist_name ());
1747               printf ("%*s      register ",
1748                       indent, "");
1749               output_const_type (const_readonly_array, _wordlist_eltype);
1750               printf ("*wordendptr = wordptr + -lookup[offset + 1];\n\n");
1751               printf ("%*s      while (wordptr < wordendptr)\n"
1752                       "%*s        {\n",
1753                       indent, "", indent, "");
1754               if (option[LENTABLE])
1755                 {
1756                   printf ("%*s          if (len == *lengthptr)\n"
1757                           "%*s            {\n",
1758                           indent, "", indent, "");
1759                   indent += 4;
1760                 }
1761               printf ("%*s          register %schar *s = ",
1762                       indent, "", const_always);
1763               if (option[TYPE])
1764                 printf ("wordptr->%s", option.get_slot_name ());
1765               else
1766                 printf ("*wordptr");
1767               if (option[SHAREDLIB])
1768                 printf (" + %s",
1769                         option.get_stringpool_name ());
1770               printf (";\n\n"
1771                       "%*s          if (",
1772                       indent, "");
1773               comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s"));
1774               printf (")\n"
1775                       "%*s            return %s;\n",
1776                       indent, "",
1777                       option[TYPE] ? "wordptr" : "s");
1778               if (option[LENTABLE])
1779                 {
1780                   indent -= 4;
1781                   printf ("%*s            }\n",
1782                           indent, "");
1783                 }
1784               if (option[LENTABLE])
1785                 printf ("%*s          lengthptr++;\n",
1786                         indent, "");
1787               printf ("%*s          wordptr++;\n"
1788                       "%*s        }\n"
1789                       "%*s    }\n",
1790                       indent, "", indent, "", indent, "");
1791             }
1792           printf ("%*s}\n",
1793                   indent, "");
1794         }
1795       else
1796         {
1797           int indent = 8;
1798           if (option[LENTABLE])
1799             {
1800               printf ("%*sif (len == %s[key])\n",
1801                       indent, "", option.get_lengthtable_name ());
1802               indent += 2;
1803             }
1804
1805           if (option[SHAREDLIB])
1806             {
1807               if (!option[LENTABLE])
1808                 {
1809                   printf ("%*s{\n"
1810                           "%*s  register int o = %s[key]",
1811                           indent, "",
1812                           indent, "", option.get_wordlist_name ());
1813                   if (option[TYPE])
1814                     printf (".%s", option.get_slot_name ());
1815                   printf (";\n"
1816                           "%*s  if (o >= 0)\n"
1817                           "%*s    {\n",
1818                           indent, "",
1819                           indent, "");
1820                   indent += 4;
1821                   printf ("%*s  register %schar *s = o",
1822                           indent, "", const_always);
1823                 }
1824               else
1825                 {
1826                   /* No need for the (o >= 0) test, because the
1827                      (len == lengthtable[key]) test already guarantees that
1828                      key points to nonempty table entry.  */
1829                   printf ("%*s{\n"
1830                           "%*s  register %schar *s = %s[key]",
1831                           indent, "",
1832                           indent, "", const_always,
1833                           option.get_wordlist_name ());
1834                   if (option[TYPE])
1835                     printf (".%s", option.get_slot_name ());
1836                 }
1837               printf (" + %s",
1838                       option.get_stringpool_name ());
1839             }
1840           else
1841             {
1842               printf ("%*s{\n"
1843                       "%*s  register %schar *s = %s[key]",
1844                       indent, "",
1845                       indent, "", const_always, option.get_wordlist_name ());
1846               if (option[TYPE])
1847                 printf (".%s", option.get_slot_name ());
1848             }
1849
1850           printf (";\n\n"
1851                   "%*s  if (",
1852                   indent, "");
1853           if (!option[SHAREDLIB] && option[NULLSTRINGS])
1854             printf ("s && ");
1855           comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s"));
1856           printf (")\n"
1857                   "%*s    return ",
1858                   indent, "");
1859           if (option[TYPE])
1860             printf ("&%s[key]", option.get_wordlist_name ());
1861           else
1862             printf ("s");
1863           printf (";\n");
1864           if (option[SHAREDLIB] && !option[LENTABLE])
1865             {
1866               indent -= 4;
1867               printf ("%*s    }\n",
1868                       indent, "");
1869             }
1870           printf ("%*s}\n",
1871                   indent, "");
1872         }
1873     }
1874   printf ("    }\n"
1875           "  return 0;\n");
1876 }
1877
1878 /* Generates C code for the lookup function.  */
1879
1880 void
1881 Output::output_lookup_function () const
1882 {
1883   /* Output the function's head.  */
1884   if (option[KRC] | option[C] | option[ANSIC])
1885     /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
1886        inline semantics, unless -fgnu89-inline is used.  It defines a macro
1887        __GNUC_STDC_INLINE__ to indicate this situation.  */
1888     printf ("#ifdef __GNUC__\n"
1889             "__inline\n"
1890             "#ifdef __GNUC_STDC_INLINE__\n"
1891             "__attribute__ ((__gnu_inline__))\n"
1892             "#endif\n"
1893             "#endif\n");
1894
1895   printf ("%s%s\n",
1896           const_for_struct, _return_type);
1897   if (option[CPLUSPLUS])
1898     printf ("%s::", option.get_class_name ());
1899   printf ("%s ", option.get_function_name ());
1900   printf (option[KRC] ?
1901                  "(str, len)\n"
1902             "     register char *str;\n"
1903             "     register unsigned int len;\n" :
1904           option[C] ?
1905                  "(str, len)\n"
1906             "     register const char *str;\n"
1907             "     register unsigned int len;\n" :
1908           option[ANSIC] | option[CPLUSPLUS] ?
1909                  "(register const char *str, register unsigned int len)\n" :
1910           "");
1911
1912   /* Output the function's body.  */
1913   printf ("{\n");
1914
1915   if (option[ENUM] && !option[GLOBAL])
1916     {
1917       Output_Enum style ("  ");
1918       output_constants (style);
1919     }
1920
1921   if (option[SHAREDLIB] && !(option[GLOBAL] || option[TYPE]))
1922     output_lookup_pools ();
1923   if (!option[GLOBAL])
1924     output_lookup_tables ();
1925
1926   if (option[LENTABLE])
1927     output_lookup_function_body (Output_Compare_Memcmp ());
1928   else
1929     {
1930       if (option[COMP])
1931         output_lookup_function_body (Output_Compare_Strncmp ());
1932       else
1933         output_lookup_function_body (Output_Compare_Strcmp ());
1934     }
1935
1936   printf ("}\n");
1937 }
1938
1939 /* ------------------------------------------------------------------------- */
1940
1941 /* Generates the hash function and the key word recognizer function
1942    based upon the user's Options.  */
1943
1944 void
1945 Output::output ()
1946 {
1947   compute_min_max ();
1948
1949   if (option[C] | option[ANSIC] | option[CPLUSPLUS])
1950     {
1951       const_always = "const ";
1952       const_readonly_array = (option[CONST] ? "const " : "");
1953       const_for_struct = ((option[CONST] && option[TYPE]) ? "const " : "");
1954     }
1955   else
1956     {
1957       const_always = "";
1958       const_readonly_array = "";
1959       const_for_struct = "";
1960     }
1961
1962   if (!option[TYPE])
1963     {
1964       _return_type = (const_always[0] ? "const char *" : "char *");
1965       _struct_tag = (const_always[0] ? "const char *" : "char *");
1966     }
1967
1968   _wordlist_eltype = (option[SHAREDLIB] && !option[TYPE] ? "int" : _struct_tag);
1969
1970   printf ("/* ");
1971   if (option[KRC])
1972     printf ("KR-C");
1973   else if (option[C])
1974     printf ("C");
1975   else if (option[ANSIC])
1976     printf ("ANSI-C");
1977   else if (option[CPLUSPLUS])
1978     printf ("C++");
1979   printf (" code produced by gperf version %s */\n", version_string);
1980   option.print_options ();
1981   printf ("\n");
1982   if (!option[POSITIONS])
1983     {
1984       printf ("/* Computed positions: -k'");
1985       _key_positions.print();
1986       printf ("' */\n");
1987     }
1988   printf ("\n");
1989
1990   if (_charset_dependent
1991       && (_key_positions.get_size() > 0 || option[UPPERLOWER]))
1992     {
1993       /* The generated tables assume that the execution character set is
1994          based on ISO-646, not EBCDIC.  */
1995       printf ("#if !((' ' == 32) && ('!' == 33) && ('\"' == 34) && ('#' == 35) \\\n"
1996               "      && ('%%' == 37) && ('&' == 38) && ('\\'' == 39) && ('(' == 40) \\\n"
1997               "      && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \\\n"
1998               "      && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \\\n"
1999               "      && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \\\n"
2000               "      && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \\\n"
2001               "      && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \\\n"
2002               "      && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \\\n"
2003               "      && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \\\n"
2004               "      && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \\\n"
2005               "      && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \\\n"
2006               "      && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \\\n"
2007               "      && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \\\n"
2008               "      && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \\\n"
2009               "      && ('Z' == 90) && ('[' == 91) && ('\\\\' == 92) && (']' == 93) \\\n"
2010               "      && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \\\n"
2011               "      && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \\\n"
2012               "      && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \\\n"
2013               "      && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \\\n"
2014               "      && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \\\n"
2015               "      && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \\\n"
2016               "      && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \\\n"
2017               "      && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))\n"
2018               "/* The character set is not based on ISO-646.  */\n");
2019       printf ("%s \"gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>.\"\n", option[KRC] || option[C] ? "error" : "#error");
2020       printf ("#endif\n\n");
2021     }
2022
2023   if (_verbatim_declarations < _verbatim_declarations_end)
2024     {
2025       output_line_directive (_verbatim_declarations_lineno);
2026       fwrite (_verbatim_declarations, 1,
2027               _verbatim_declarations_end - _verbatim_declarations, stdout);
2028     }
2029
2030   if (option[TYPE] && !option[NOTYPE]) /* Output type declaration now, reference it later on.... */
2031     {
2032       output_line_directive (_struct_decl_lineno);
2033       printf ("%s\n", _struct_decl);
2034     }
2035
2036   if (option[INCLUDE]) {
2037     printf ("#include <string.h>\n"); /* Declare strlen(), strcmp(), strncmp(). */
2038     if (option[SHAREDLIB])
2039       printf("#include <stddef.h>\n"); /* Declare offsetof() */
2040   }
2041
2042   if (!option[ENUM])
2043     {
2044       Output_Defines style;
2045       output_constants (style);
2046     }
2047   else if (option[GLOBAL])
2048     {
2049       Output_Enum style ("");
2050       output_constants (style);
2051     }
2052
2053   printf ("/* maximum key range = %d, duplicates = %d */\n\n",
2054           _max_hash_value - _min_hash_value + 1, _total_duplicates);
2055
2056   if (option[UPPERLOWER])
2057     {
2058       #if USE_DOWNCASE_TABLE
2059       output_upperlower_table ();
2060       #endif
2061
2062       if (option[LENTABLE])
2063         output_upperlower_memcmp ();
2064       else
2065         {
2066           if (option[COMP])
2067             output_upperlower_strncmp ();
2068           else
2069             output_upperlower_strcmp ();
2070         }
2071     }
2072
2073   if (option[CPLUSPLUS])
2074     printf ("class %s\n"
2075             "{\n"
2076             "private:\n"
2077             "  static inline unsigned int %s (const char *str, unsigned int len);\n"
2078             "public:\n"
2079             "  static %s%s%s (const char *str, unsigned int len);\n"
2080             "};\n"
2081             "\n",
2082             option.get_class_name (), option.get_hash_name (),
2083             const_for_struct, _return_type, option.get_function_name ());
2084
2085   output_hash_function ();
2086
2087   if (option[SHAREDLIB] && (option[GLOBAL] || option[TYPE]))
2088     output_lookup_pools ();
2089   if (option[GLOBAL])
2090     output_lookup_tables ();
2091
2092   output_lookup_function ();
2093
2094   if (_verbatim_code < _verbatim_code_end)
2095     {
2096       output_line_directive (_verbatim_code_lineno);
2097       fwrite (_verbatim_code, 1, _verbatim_code_end - _verbatim_code, stdout);
2098     }
2099
2100   fflush (stdout);
2101 }