2 Copyright (C) 1989-1998, 2000, 2002-2003 Free Software Foundation, Inc.
3 Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
4 and Bruno Haible <bruno@clisp.org>.
6 This file is part of GNU GPERF.
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)
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.
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 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
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. */
34 /* The "const " qualifier. */
35 static const char *const_always
;
37 /* The "const " qualifier, for read-only arrays. */
38 static const char *const_readonly_array
;
40 /* The "const " qualifier, for the array type. */
41 static const char *const_for_struct
;
43 /* Returns the smallest unsigned C type capable of holding integers
47 smallest_integral_type (int n
)
49 if (n
<= UCHAR_MAX
) return "unsigned char";
50 if (n
<= USHRT_MAX
) return "unsigned short";
51 return "unsigned int";
54 /* Returns the smallest signed C type capable of holding integers
58 smallest_integral_type (int min
, int max
)
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";
66 /* ------------------------------------------------------------------------- */
69 Note about the keyword list starting at head:
70 - The list is ordered by increasing _hash_value. This has been achieved
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.
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
)
108 /* ------------------------------------------------------------------------- */
110 /* Computes the minimum and maximum hash values, and stores them
111 in _min_hash_value and _max_hash_value. */
114 Output::compute_min_max ()
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. */
119 _min_hash_value
= _head
->first()->_hash_value
;
121 KeywordExt_List
*temp
;
122 for (temp
= _head
; temp
->rest(); temp
= temp
->rest())
124 _max_hash_value
= temp
->first()->_hash_value
;
127 /* ------------------------------------------------------------------------- */
129 /* Returns the number of different hash values. */
132 Output::num_hash_values () const
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. */
137 for (KeywordExt_List
*temp
= _head
; temp
; temp
= temp
->rest())
142 /* -------------------- Output_Constants and subclasses -------------------- */
144 /* This class outputs an enumeration defining some constants. */
146 struct Output_Constants
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 () {}
155 /* This class outputs an enumeration in #define syntax. */
157 struct Output_Defines
: public Output_Constants
159 virtual void output_start ();
160 virtual void output_item (const char *name
, int value
);
161 virtual void output_end ();
163 virtual ~Output_Defines () {}
166 void Output_Defines::output_start ()
171 void Output_Defines::output_item (const char *name
, int value
)
173 printf ("#define %s %d\n", name
, value
);
176 void Output_Defines::output_end ()
180 /* This class outputs an enumeration using 'enum'. */
182 struct Output_Enum
: public Output_Constants
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 () {}
191 const char *_indentation
;
195 void Output_Enum::output_start ()
199 _indentation
, _indentation
);
200 _pending_comma
= false;
203 void Output_Enum::output_item (const char *name
, int value
)
207 printf ("%s %s = %d", _indentation
, name
, value
);
208 _pending_comma
= true;
211 void Output_Enum::output_end ()
215 printf ("%s };\n\n", _indentation
);
218 /* Outputs the maximum and minimum hash values etc. */
221 Output::output_constants (struct Output_Constants
& style
) const
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
);
232 /* ------------------------------------------------------------------------- */
234 /* We use a downcase table because when called repeatedly, the code
237 if (c >= 'A' && c <= 'Z')
240 #define USE_DOWNCASE_TABLE 1
242 #if USE_DOWNCASE_TABLE
244 /* Output gperf's ASCII-downcase table. */
247 output_upperlower_table ()
251 printf ("#ifndef GPERF_DOWNCASE\n"
252 "#define GPERF_DOWNCASE 1\n"
253 "static unsigned char gperf_downcase[256] =\n"
255 for (c
= 0; c
< 256; c
++)
259 printf (" %3d", c
>= 'A' && c
<= 'Z' ? c
+ 'a' - 'A' : c
);
270 /* Output gperf's ASCII-case insensitive strcmp replacement. */
273 output_upperlower_strcmp ()
275 printf ("#ifndef GPERF_CASE_STRCMP\n"
276 "#define GPERF_CASE_STRCMP 1\n"
278 "gperf_case_strcmp ");
279 printf (option
[KRC
] ?
281 " register char *s1;\n"
282 " register char *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" :
290 #if USE_DOWNCASE_TABLE
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"
298 " return (int)c1 - (int)c2;\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"
313 " return (int)c1 - (int)c2;\n"
317 printf ("#endif\n\n");
320 /* Output gperf's ASCII-case insensitive strncmp replacement. */
323 output_upperlower_strncmp ()
325 printf ("#ifndef GPERF_CASE_STRNCMP\n"
326 "#define GPERF_CASE_STRNCMP 1\n"
328 "gperf_case_strncmp ");
329 printf (option
[KRC
] ?
331 " register char *s1;\n"
332 " register char *s2;\n"
333 " register unsigned int 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" :
342 #if USE_DOWNCASE_TABLE
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"
353 " return (int)c1 - (int)c2;\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"
372 " return (int)c1 - (int)c2;\n"
377 printf ("#endif\n\n");
380 /* Output gperf's ASCII-case insensitive memcmp replacement. */
383 output_upperlower_memcmp ()
385 printf ("#ifndef GPERF_CASE_MEMCMP\n"
386 "#define GPERF_CASE_MEMCMP 1\n"
388 "gperf_case_memcmp ");
389 printf (option
[KRC
] ?
391 " register char *s1;\n"
392 " register char *s2;\n"
393 " register unsigned int 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" :
402 #if USE_DOWNCASE_TABLE
406 " unsigned char c1 = gperf_downcase[(unsigned char)*s1++];\n"
407 " unsigned char c2 = gperf_downcase[(unsigned char)*s2++];\n"
413 " return (int)c1 - (int)c2;\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"
432 " return (int)c1 - (int)c2;\n"
437 printf ("#endif\n\n");
440 /* ------------------------------------------------------------------------- */
442 /* Outputs a keyword, as a string: enclosed in double quotes, escaping
443 backslashes, double quote and unprintable characters. */
446 output_string (const char *key
, int len
)
449 for (; len
> 0; len
--)
451 unsigned char c
= static_cast<unsigned char>(*key
++);
454 if (c
== '"' || c
== '\\')
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. */
465 putchar ('0' + ((c
>> 6) & 7));
466 putchar ('0' + ((c
>> 3) & 7));
467 putchar ('0' + (c
& 7));
473 /* ------------------------------------------------------------------------- */
475 /* Outputs a type and a const specifier (i.e. "const " or "").
476 The output is terminated with a space. */
479 output_const_type (const char *const_string
, const char *type_string
)
481 if (type_string
[strlen(type_string
)-1] == '*')
482 /* For pointer types, put the 'const' after the type. */
483 printf ("%s %s", type_string
, const_string
);
485 /* For scalar or struct types, put the 'const' before the type. */
486 printf ("%s%s ", const_string
, type_string
);
489 /* ----------------------- Output_Expr and subclasses ----------------------- */
491 /* This class outputs a general expression. */
495 virtual void output_expr () const = 0;
497 virtual ~Output_Expr () {}
500 /* This class outputs an expression formed by a single string. */
502 struct Output_Expr1
: public Output_Expr
504 virtual void output_expr () const;
505 Output_Expr1 (const char *piece1
) : _p1 (piece1
) {}
506 virtual ~Output_Expr1 () {}
511 void Output_Expr1::output_expr () const
518 /* This class outputs an expression formed by the concatenation of two
521 struct Output_Expr2
: public Output_Expr
523 virtual void output_expr () const;
524 Output_Expr2 (const char *piece1
, const char *piece2
)
525 : _p1 (piece1
), _p2 (piece2
) {}
526 virtual ~Output_Expr2 () {}
532 void Output_Expr2::output_expr () const
534 printf ("%s%s", _p1
, _p2
);
539 /* --------------------- Output_Compare and subclasses --------------------- */
541 /* This class outputs a comparison expression. */
543 struct Output_Compare
545 /* Outputs the comparison expression.
546 expr1 outputs a simple expression of type 'const char *' referring to
547 the string being looked up. expr2 outputs a simple expression of type
548 'const char *' referring to the constant string stored in the gperf
549 generated hash table. */
550 virtual void output_comparison (const Output_Expr
& expr1
,
551 const Output_Expr
& expr2
) const = 0;
552 /* Outputs the comparison expression for the first byte.
553 Returns true if the this comparison is complete. */
554 bool output_firstchar_comparison (const Output_Expr
& expr1
,
555 const Output_Expr
& expr2
) const;
557 virtual ~Output_Compare () {}
560 bool Output_Compare::output_firstchar_comparison (const Output_Expr
& expr1
,
561 const Output_Expr
& expr2
) const
563 /* First, we emit a comparison of the first byte of the two strings.
564 This catches most cases where the string being looked up is not in the
565 hash table but happens to have the same hash code as an element of the
567 if (option
[UPPERLOWER
])
569 /* Incomplete comparison, just for speedup. */
570 printf ("(((unsigned char)*");
571 expr1
.output_expr ();
572 printf (" ^ (unsigned char)*");
573 expr2
.output_expr ();
574 printf (") & ~32) == 0");
579 /* Complete comparison. */
581 expr1
.output_expr ();
583 expr2
.output_expr ();
588 /* This class outputs a comparison using strcmp. */
590 struct Output_Compare_Strcmp
: public Output_Compare
592 virtual void output_comparison (const Output_Expr
& expr1
,
593 const Output_Expr
& expr2
) const;
594 Output_Compare_Strcmp () {}
595 virtual ~Output_Compare_Strcmp () {}
598 void Output_Compare_Strcmp::output_comparison (const Output_Expr
& expr1
,
599 const Output_Expr
& expr2
) const
601 bool firstchar_done
= output_firstchar_comparison (expr1
, expr2
);
603 if (option
[UPPERLOWER
])
604 printf ("gperf_case_");
608 expr1
.output_expr ();
610 expr2
.output_expr ();
615 expr1
.output_expr ();
617 expr2
.output_expr ();
622 /* This class outputs a comparison using strncmp.
623 Note that the length of expr1 will be available through the local variable
626 struct Output_Compare_Strncmp
: public Output_Compare
628 virtual void output_comparison (const Output_Expr
& expr1
,
629 const Output_Expr
& expr2
) const;
630 Output_Compare_Strncmp () {}
631 virtual ~Output_Compare_Strncmp () {}
634 void Output_Compare_Strncmp::output_comparison (const Output_Expr
& expr1
,
635 const Output_Expr
& expr2
) const
637 bool firstchar_done
= output_firstchar_comparison (expr1
, expr2
);
639 if (option
[UPPERLOWER
])
640 printf ("gperf_case_");
641 printf ("strncmp (");
644 expr1
.output_expr ();
646 expr2
.output_expr ();
647 printf (" + 1, len - 1");
651 expr1
.output_expr ();
653 expr2
.output_expr ();
657 expr2
.output_expr ();
658 printf ("[len] == '\\0'");
661 /* This class outputs a comparison using memcmp.
662 Note that the length of expr1 (available through the local variable 'len')
663 must be verified to be equal to the length of expr2 prior to this
666 struct Output_Compare_Memcmp
: public Output_Compare
668 virtual void output_comparison (const Output_Expr
& expr1
,
669 const Output_Expr
& expr2
) const;
670 Output_Compare_Memcmp () {}
671 virtual ~Output_Compare_Memcmp () {}
674 void Output_Compare_Memcmp::output_comparison (const Output_Expr
& expr1
,
675 const Output_Expr
& expr2
) const
677 bool firstchar_done
= output_firstchar_comparison (expr1
, expr2
);
679 if (option
[UPPERLOWER
])
680 printf ("gperf_case_");
684 expr1
.output_expr ();
686 expr2
.output_expr ();
687 printf (" + 1, len - 1");
691 expr1
.output_expr ();
693 expr2
.output_expr ();
699 /* ------------------------------------------------------------------------- */
701 /* Generates a C expression for an asso_values[] reference. */
704 Output::output_asso_values_ref (int pos
) const
706 printf ("asso_values[");
707 /* Always cast to unsigned char. This is necessary when the alpha_inc
708 is nonzero, and also avoids a gcc warning "subscript has type 'char'". */
709 printf ("(unsigned char)");
710 if (pos
== Positions::LASTCHAR
)
711 printf ("str[len - 1]");
714 printf ("str[%d]", pos
);
716 printf ("+%u", _alpha_inc
[pos
]);
721 /* Generates C code for the hash function that returns the
722 proper encoding for each keyword.
723 The hash function has the signature
724 unsigned int <hash> (const char *str, unsigned int len). */
727 Output::output_hash_function () const
729 /* Output the function's head. */
730 if (option
[CPLUSPLUS
])
732 else if (option
[KRC
] | option
[C
] | option
[ANSIC
])
733 printf ("#ifdef __GNUC__\n"
736 "#ifdef __cplusplus\n"
741 if (/* The function does not use the 'str' argument? */
742 _key_positions
.get_size() == 0
743 || /* The function uses 'str', but not the 'len' argument? */
745 && _key_positions
[0] < _min_key_len
746 && _key_positions
[_key_positions
.get_size() - 1] != Positions::LASTCHAR
))
748 printf ("/*ARGSUSED*/\n");
750 if (option
[KRC
] | option
[C
] | option
[ANSIC
])
752 printf ("unsigned int\n");
753 if (option
[CPLUSPLUS
])
754 printf ("%s::", option
.get_class_name ());
755 printf ("%s ", option
.get_hash_name ());
756 printf (option
[KRC
] ?
758 " register char *str;\n"
759 " register unsigned int len;\n" :
762 " register const char *str;\n"
763 " register unsigned int len;\n" :
764 option
[ANSIC
] | option
[CPLUSPLUS
] ?
765 "(register const char *str, register unsigned int len)\n" :
768 /* Note that when the hash function is called, it has already been verified
769 that min_key_len <= len <= max_key_len. */
771 /* Output the function's body. */
774 /* First the asso_values array. */
775 if (_key_positions
.get_size() > 0)
777 printf (" static %s%s asso_values[] =\n"
779 const_readonly_array
,
780 smallest_integral_type (_max_hash_value
+ 1));
782 const int columns
= 10;
784 /* Calculate maximum number of digits required for MAX_HASH_VALUE. */
786 for (int trunc
= _max_hash_value
; (trunc
/= 10) > 0;)
789 for (unsigned int count
= 0; count
< _alpha_size
; count
++)
793 if ((count
% columns
) == 0)
795 printf ("%*d", field_width
, _asso_values
[count
]);
802 if (_key_positions
.get_size() == 0)
804 /* Trivial case: No key positions at all. */
805 printf (" return %s;\n",
806 option
[NOLENGTH
] ? "0" : "len");
810 /* Iterate through the key positions. Remember that Positions::sort()
811 has sorted them in decreasing order, with Positions::LASTCHAR coming
813 PositionIterator iter
= _key_positions
.iterator(_max_key_len
);
816 /* Get the highest key position. */
817 key_pos
= iter
.next ();
819 if (key_pos
== Positions::LASTCHAR
|| key_pos
< _min_key_len
)
821 /* We can perform additional optimizations here:
822 Write it out as a single expression. Note that the values
823 are added as 'int's even though the asso_values array may
824 contain 'unsigned char's or 'unsigned short's. */
826 printf (" return %s",
827 option
[NOLENGTH
] ? "" : "len + ");
829 if (_key_positions
.get_size() == 2
830 && _key_positions
[0] == 0
831 && _key_positions
[1] == Positions::LASTCHAR
)
832 /* Optimize special case of "-k 1,$". */
834 output_asso_values_ref (Positions::LASTCHAR
);
836 output_asso_values_ref (0);
840 for (; key_pos
!= Positions::LASTCHAR
; )
842 output_asso_values_ref (key_pos
);
843 if ((key_pos
= iter
.next ()) != PositionIterator::EOS
)
849 if (key_pos
== Positions::LASTCHAR
)
850 output_asso_values_ref (Positions::LASTCHAR
);
857 /* We've got to use the correct, but brute force, technique. */
858 printf (" register int hval = %s;\n\n"
862 option
[NOLENGTH
] ? "0" : "len",
863 option
[NOLENGTH
] ? "len" : "hval");
865 while (key_pos
!= Positions::LASTCHAR
&& key_pos
>= _max_key_len
)
866 if ((key_pos
= iter
.next ()) == PositionIterator::EOS
)
869 if (key_pos
!= PositionIterator::EOS
&& key_pos
!= Positions::LASTCHAR
)
875 printf (" /*FALLTHROUGH*/\n"); /* Pacify lint. */
876 for ( ; i
> key_pos
; i
--)
877 printf (" case %d:\n", i
);
879 printf (" hval += ");
880 output_asso_values_ref (key_pos
);
883 key_pos
= iter
.next ();
885 while (key_pos
!= PositionIterator::EOS
&& key_pos
!= Positions::LASTCHAR
);
887 if (i
>= _min_key_len
)
888 printf (" /*FALLTHROUGH*/\n"); /* Pacify lint. */
889 for ( ; i
>= _min_key_len
; i
--)
890 printf (" case %d:\n", i
);
896 if (key_pos
== Positions::LASTCHAR
)
899 output_asso_values_ref (Positions::LASTCHAR
);
907 /* ------------------------------------------------------------------------- */
909 /* Prints out a table of keyword lengths, for use with the
910 comparison code in generated function 'in_word_set'.
911 Only called if option[LENTABLE]. */
914 Output::output_keylength_table () const
916 const int columns
= 14;
917 const char * const indent
= option
[GLOBAL
] ? "" : " ";
919 printf ("%sstatic %s%s lengthtable[] =\n%s {",
920 indent
, const_readonly_array
,
921 smallest_integral_type (_max_key_len
),
924 /* Generate an array of lengths, similar to output_keyword_table. */
927 KeywordExt_List
*temp
;
930 for (temp
= _head
, index
= 0; temp
; temp
= temp
->rest())
932 KeywordExt
*keyword
= temp
->first();
934 /* If generating a switch statement, and there is no user defined type,
935 we generate non-duplicates directly in the code. Only duplicates go
937 if (option
[SWITCH
] && !option
[TYPE
] && !keyword
->_duplicate_link
)
940 if (index
< keyword
->_hash_value
&& !option
[SWITCH
] && !option
[DUP
])
942 /* Some blank entries. */
943 for ( ; index
< keyword
->_hash_value
; index
++)
947 if ((column
++ % columns
) == 0)
948 printf ("\n%s ", indent
);
955 if ((column
++ % columns
) == 0)
956 printf("\n%s ", indent
);
957 printf ("%3d", keyword
->_allchars_length
);
960 /* Deal with duplicates specially. */
961 if (keyword
->_duplicate_link
) // implies option[DUP]
962 for (KeywordExt
*links
= keyword
->_duplicate_link
; links
; links
= links
->_duplicate_link
)
965 if ((column
++ % columns
) == 0)
966 printf("\n%s ", indent
);
967 printf ("%3d", links
->_allchars_length
);
972 printf ("\n%s };\n", indent
);
977 /* ------------------------------------------------------------------------- */
979 /* Prints out the string pool, containing the strings of the keyword table.
980 Only called if option[SHAREDLIB]. */
983 Output::output_string_pool () const
985 const char * const indent
= option
[TYPE
] || option
[GLOBAL
] ? "" : " ";
987 KeywordExt_List
*temp
;
989 printf ("%sstruct %s_t\n"
991 indent
, option
.get_stringpool_name (), indent
);
992 for (temp
= _head
, index
= 0; temp
; temp
= temp
->rest())
994 KeywordExt
*keyword
= temp
->first();
996 /* If generating a switch statement, and there is no user defined type,
997 we generate non-duplicates directly in the code. Only duplicates go
999 if (option
[SWITCH
] && !option
[TYPE
] && !keyword
->_duplicate_link
)
1002 if (!option
[SWITCH
] && !option
[DUP
])
1003 index
= keyword
->_hash_value
;
1005 printf ("%s char %s_str%d[sizeof(",
1006 indent
, option
.get_stringpool_name (), index
);
1007 output_string (keyword
->_allchars
, keyword
->_allchars_length
);
1010 /* Deal with duplicates specially. */
1011 if (keyword
->_duplicate_link
) // implies option[DUP]
1012 for (KeywordExt
*links
= keyword
->_duplicate_link
; links
; links
= links
->_duplicate_link
)
1013 if (!(links
->_allchars_length
== keyword
->_allchars_length
1014 && memcmp (links
->_allchars
, keyword
->_allchars
,
1015 keyword
->_allchars_length
) == 0))
1018 printf ("%s char %s_str%d[sizeof(",
1019 indent
, option
.get_stringpool_name (), index
);
1020 output_string (links
->_allchars
, links
->_allchars_length
);
1029 printf ("%sstatic %sstruct %s_t %s_contents =\n"
1031 indent
, const_readonly_array
, option
.get_stringpool_name (),
1032 option
.get_stringpool_name (), indent
);
1033 for (temp
= _head
, index
= 0; temp
; temp
= temp
->rest())
1035 KeywordExt
*keyword
= temp
->first();
1037 /* If generating a switch statement, and there is no user defined type,
1038 we generate non-duplicates directly in the code. Only duplicates go
1040 if (option
[SWITCH
] && !option
[TYPE
] && !keyword
->_duplicate_link
)
1046 if (!option
[SWITCH
] && !option
[DUP
])
1047 index
= keyword
->_hash_value
;
1051 output_string (keyword
->_allchars
, keyword
->_allchars_length
);
1053 /* Deal with duplicates specially. */
1054 if (keyword
->_duplicate_link
) // implies option[DUP]
1055 for (KeywordExt
*links
= keyword
->_duplicate_link
; links
; links
= links
->_duplicate_link
)
1056 if (!(links
->_allchars_length
== keyword
->_allchars_length
1057 && memcmp (links
->_allchars
, keyword
->_allchars
,
1058 keyword
->_allchars_length
) == 0))
1064 output_string (links
->_allchars
, links
->_allchars_length
);
1073 printf ("%s#define %s ((%schar *) &%s_contents)\n",
1074 indent
, option
.get_stringpool_name (), const_always
,
1075 option
.get_stringpool_name ());
1080 /* ------------------------------------------------------------------------- */
1083 output_keyword_entry (KeywordExt
*temp
, int stringpool_index
, const char *indent
)
1085 if (option
[TYPE
] && option
.get_input_file_name ())
1086 printf ("#line %u \"%s\"\n",
1087 temp
->_lineno
, option
.get_input_file_name ());
1088 printf ("%s ", indent
);
1091 if (option
[SHAREDLIB
])
1092 printf ("(int)(long)&((struct %s_t *)0)->%s_str%d",
1093 option
.get_stringpool_name (), option
.get_stringpool_name (),
1096 output_string (temp
->_allchars
, temp
->_allchars_length
);
1099 if (strlen (temp
->_rest
) > 0)
1100 printf (",%s", temp
->_rest
);
1104 printf (" /* hash value = %d, index = %d */",
1105 temp
->_hash_value
, temp
->_final_index
);
1109 output_keyword_blank_entries (int count
, const char *indent
)
1114 columns
= 58 / (4 + (option
[SHAREDLIB
] ? 2 : option
[NULLSTRINGS
] ? 8 : 2)
1115 + strlen (option
.get_initializer_suffix()));
1121 columns
= (option
[SHAREDLIB
] ? 9 : option
[NULLSTRINGS
] ? 4 : 9);
1124 for (int i
= 0; i
< count
; i
++)
1126 if ((column
% columns
) == 0)
1130 printf ("%s ", indent
);
1139 if (option
[SHAREDLIB
])
1143 if (option
[NULLSTRINGS
])
1144 printf ("(char*)0");
1149 printf ("%s}", option
.get_initializer_suffix());
1154 /* Prints out the array containing the keywords for the hash function. */
1157 Output::output_keyword_table () const
1159 const char *indent
= option
[GLOBAL
] ? "" : " ";
1161 KeywordExt_List
*temp
;
1163 printf ("%sstatic ",
1165 output_const_type (const_readonly_array
, _wordlist_eltype
);
1168 option
.get_wordlist_name (),
1171 /* Generate an array of reserved words at appropriate locations. */
1173 for (temp
= _head
, index
= 0; temp
; temp
= temp
->rest())
1175 KeywordExt
*keyword
= temp
->first();
1177 /* If generating a switch statement, and there is no user defined type,
1178 we generate non-duplicates directly in the code. Only duplicates go
1180 if (option
[SWITCH
] && !option
[TYPE
] && !keyword
->_duplicate_link
)
1186 if (index
< keyword
->_hash_value
&& !option
[SWITCH
] && !option
[DUP
])
1188 /* Some blank entries. */
1189 output_keyword_blank_entries (keyword
->_hash_value
- index
, indent
);
1191 index
= keyword
->_hash_value
;
1194 keyword
->_final_index
= index
;
1196 output_keyword_entry (keyword
, index
, indent
);
1198 /* Deal with duplicates specially. */
1199 if (keyword
->_duplicate_link
) // implies option[DUP]
1200 for (KeywordExt
*links
= keyword
->_duplicate_link
; links
; links
= links
->_duplicate_link
)
1202 links
->_final_index
= ++index
;
1204 int stringpool_index
=
1205 (links
->_allchars_length
== keyword
->_allchars_length
1206 && memcmp (links
->_allchars
, keyword
->_allchars
,
1207 keyword
->_allchars_length
) == 0
1208 ? keyword
->_final_index
1209 : links
->_final_index
);
1210 output_keyword_entry (links
, stringpool_index
, indent
);
1218 printf ("%s };\n\n", indent
);
1221 /* ------------------------------------------------------------------------- */
1223 /* Generates the large, sparse table that maps hash values into
1224 the smaller, contiguous range of the keyword table. */
1227 Output::output_lookup_array () const
1231 const int DEFAULT_VALUE
= -1;
1233 /* Because of the way output_keyword_table works, every duplicate set is
1234 stored contiguously in the wordlist array. */
1235 struct duplicate_entry
1237 int hash_value
; /* Hash value for this particular duplicate set. */
1238 int index
; /* Index into the main keyword storage array. */
1239 int count
; /* Number of consecutive duplicates at this index. */
1242 duplicate_entry
*duplicates
= new duplicate_entry
[_total_duplicates
];
1243 int *lookup_array
= new int[_max_hash_value
+ 1 + 2*_total_duplicates
];
1244 int lookup_array_size
= _max_hash_value
+ 1;
1245 duplicate_entry
*dup_ptr
= &duplicates
[0];
1246 int *lookup_ptr
= &lookup_array
[_max_hash_value
+ 1 + 2*_total_duplicates
];
1248 while (lookup_ptr
> lookup_array
)
1249 *--lookup_ptr
= DEFAULT_VALUE
;
1251 /* Now dup_ptr = &duplicates[0] and lookup_ptr = &lookup_array[0]. */
1253 for (KeywordExt_List
*temp
= _head
; temp
; temp
= temp
->rest())
1255 int hash_value
= temp
->first()->_hash_value
;
1256 lookup_array
[hash_value
] = temp
->first()->_final_index
;
1258 fprintf (stderr
, "keyword = %.*s, index = %d\n",
1259 temp
->first()->_allchars_length
, temp
->first()->_allchars
, temp
->first()->_final_index
);
1260 if (temp
->first()->_duplicate_link
)
1262 /* Start a duplicate entry. */
1263 dup_ptr
->hash_value
= hash_value
;
1264 dup_ptr
->index
= temp
->first()->_final_index
;
1267 for (KeywordExt
*ptr
= temp
->first()->_duplicate_link
; ptr
; ptr
= ptr
->_duplicate_link
)
1272 "static linked keyword = %.*s, index = %d\n",
1273 ptr
->_allchars_length
, ptr
->_allchars
, ptr
->_final_index
);
1275 assert (dup_ptr
->count
>= 2);
1280 while (dup_ptr
> duplicates
)
1286 "dup_ptr[%d]: hash_value = %d, index = %d, count = %d\n",
1287 dup_ptr
- duplicates
,
1288 dup_ptr
->hash_value
, dup_ptr
->index
, dup_ptr
->count
);
1291 /* Start searching for available space towards the right part
1292 of the lookup array. */
1293 for (i
= dup_ptr
->hash_value
; i
< lookup_array_size
-1; i
++)
1294 if (lookup_array
[i
] == DEFAULT_VALUE
1295 && lookup_array
[i
+ 1] == DEFAULT_VALUE
)
1297 /* If we didn't find it to the right look to the left instead... */
1298 for (i
= dup_ptr
->hash_value
-1; i
>= 0; i
--)
1299 if (lookup_array
[i
] == DEFAULT_VALUE
1300 && lookup_array
[i
+ 1] == DEFAULT_VALUE
)
1302 /* Append to the end of lookup_array. */
1303 i
= lookup_array_size
;
1304 lookup_array_size
+= 2;
1306 /* Put in an indirection from dup_ptr->_hash_value to i.
1307 At i and i+1 store dup_ptr->_final_index and dup_ptr->count. */
1308 assert (lookup_array
[dup_ptr
->hash_value
] == dup_ptr
->index
);
1309 lookup_array
[dup_ptr
->hash_value
] = - 1 - _total_keys
- i
;
1310 lookup_array
[i
] = - _total_keys
+ dup_ptr
->index
;
1311 lookup_array
[i
+ 1] = - dup_ptr
->count
;
1312 /* All these three values are <= -2, distinct from DEFAULT_VALUE. */
1315 /* The values of the lookup array are now known. */
1319 lookup_ptr
= lookup_array
+ lookup_array_size
;
1320 while (lookup_ptr
> lookup_array
)
1322 int val
= *--lookup_ptr
;
1329 const char *indent
= option
[GLOBAL
] ? "" : " ";
1330 printf ("%sstatic %s%s lookup[] =\n"
1332 indent
, const_readonly_array
, smallest_integral_type (min
, max
),
1336 /* Calculate maximum number of digits required for MIN..MAX. */
1339 for (int trunc
= max
; (trunc
/= 10) > 0;)
1344 int neg_field_width
= 2;
1345 for (int trunc
= -min
; (trunc
/= 10) > 0;)
1347 neg_field_width
++; /* account for the minus sign */
1348 if (field_width
< neg_field_width
)
1349 field_width
= neg_field_width
;
1352 const int columns
= 42 / field_width
;
1356 for (int i
= 0; i
< lookup_array_size
; i
++)
1360 if ((column
++ % columns
) == 0)
1361 printf("\n%s ", indent
);
1362 printf ("%*d", field_width
, lookup_array
[i
]);
1364 printf ("\n%s };\n\n", indent
);
1366 delete[] duplicates
;
1367 delete[] lookup_array
;
1371 /* ------------------------------------------------------------------------- */
1373 /* Generate all pools needed for the lookup function. */
1376 Output::output_lookup_pools () const
1380 if (option
[TYPE
] || (option
[DUP
] && _total_duplicates
> 0))
1381 output_string_pool ();
1385 output_string_pool ();
1389 /* Generate all the tables needed for the lookup function. */
1392 Output::output_lookup_tables () const
1396 /* Use the switch in place of lookup table. */
1397 if (option
[LENTABLE
] && (option
[DUP
] && _total_duplicates
> 0))
1398 output_keylength_table ();
1399 if (option
[TYPE
] || (option
[DUP
] && _total_duplicates
> 0))
1400 output_keyword_table ();
1404 /* Use the lookup table, in place of switch. */
1405 if (option
[LENTABLE
])
1406 output_keylength_table ();
1407 output_keyword_table ();
1408 output_lookup_array ();
1412 /* ------------------------------------------------------------------------- */
1414 /* Output a single switch case (including duplicates). Advance list. */
1416 static KeywordExt_List
*
1417 output_switch_case (KeywordExt_List
*list
, int indent
, int *jumps_away
)
1420 printf ("%*s/* hash value = %4d, keyword = \"%.*s\" */\n",
1421 indent
, "", list
->first()->_hash_value
, list
->first()->_allchars_length
, list
->first()->_allchars
);
1423 if (option
[DUP
] && list
->first()->_duplicate_link
)
1425 if (option
[LENTABLE
])
1426 printf ("%*slengthptr = &lengthtable[%d];\n",
1427 indent
, "", list
->first()->_final_index
);
1428 printf ("%*swordptr = &%s[%d];\n",
1429 indent
, "", option
.get_wordlist_name (), list
->first()->_final_index
);
1432 for (KeywordExt
*links
= list
->first(); links
; links
= links
->_duplicate_link
)
1435 printf ("%*swordendptr = wordptr + %d;\n"
1436 "%*sgoto multicompare;\n",
1443 if (option
[LENTABLE
])
1445 printf ("%*sif (len == %d)\n"
1447 indent
, "", list
->first()->_allchars_length
,
1451 printf ("%*sresword = ",
1454 printf ("&%s[%d]", option
.get_wordlist_name (), list
->first()->_final_index
);
1456 output_string (list
->first()->_allchars
, list
->first()->_allchars_length
);
1458 printf ("%*sgoto compare;\n",
1460 if (option
[LENTABLE
])
1470 return list
->rest();
1473 /* Output a total of size cases, grouped into num_switches switch statements,
1474 where 0 < num_switches <= size. */
1477 output_switches (KeywordExt_List
*list
, int num_switches
, int size
, int min_hash_value
, int max_hash_value
, int indent
)
1480 printf ("%*s/* know %d <= key <= %d, contains %d cases */\n",
1481 indent
, "", min_hash_value
, max_hash_value
, size
);
1483 if (num_switches
> 1)
1485 int part1
= num_switches
/ 2;
1486 int part2
= num_switches
- part1
;
1487 int size1
= static_cast<int>(static_cast<double>(size
) / static_cast<double>(num_switches
) * static_cast<double>(part1
) + 0.5);
1488 int size2
= size
- size1
;
1490 KeywordExt_List
*temp
= list
;
1491 for (int count
= size1
; count
> 0; count
--)
1492 temp
= temp
->rest();
1494 printf ("%*sif (key < %d)\n"
1496 indent
, "", temp
->first()->_hash_value
,
1499 output_switches (list
, part1
, size1
, min_hash_value
, temp
->first()->_hash_value
-1, indent
+4);
1504 indent
, "", indent
, "", indent
, "");
1506 output_switches (temp
, part2
, size2
, temp
->first()->_hash_value
, max_hash_value
, indent
+4);
1513 /* Output a single switch. */
1514 int lowest_case_value
= list
->first()->_hash_value
;
1518 assert (min_hash_value
<= lowest_case_value
);
1519 assert (lowest_case_value
<= max_hash_value
);
1520 if (min_hash_value
== max_hash_value
)
1521 output_switch_case (list
, indent
, &jumps_away
);
1524 printf ("%*sif (key == %d)\n"
1526 indent
, "", lowest_case_value
,
1528 output_switch_case (list
, indent
+4, &jumps_away
);
1535 if (lowest_case_value
== 0)
1536 printf ("%*sswitch (key)\n", indent
, "");
1538 printf ("%*sswitch (key - %d)\n", indent
, "", lowest_case_value
);
1541 for (; size
> 0; size
--)
1544 printf ("%*s case %d:\n",
1545 indent
, "", list
->first()->_hash_value
- lowest_case_value
);
1546 list
= output_switch_case (list
, indent
+6, &jumps_away
);
1548 printf ("%*s break;\n",
1557 /* Generates C code to perform the keyword lookup. */
1560 Output::output_lookup_function_body (const Output_Compare
& comparison
) const
1562 printf (" if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)\n"
1564 " register int key = %s (str, len);\n\n",
1565 option
.get_hash_name ());
1569 int switch_size
= num_hash_values ();
1570 int num_switches
= option
.get_total_switches ();
1571 if (num_switches
> switch_size
)
1572 num_switches
= switch_size
;
1574 printf (" if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)\n"
1576 if (option
[DUP
] && _total_duplicates
> 0)
1578 if (option
[LENTABLE
])
1579 printf (" register %s%s *lengthptr;\n",
1580 const_always
, smallest_integral_type (_max_key_len
));
1581 printf (" register ");
1582 output_const_type (const_readonly_array
, _wordlist_eltype
);
1583 printf ("*wordptr;\n");
1584 printf (" register ");
1585 output_const_type (const_readonly_array
, _wordlist_eltype
);
1586 printf ("*wordendptr;\n");
1590 printf (" register ");
1591 output_const_type (const_readonly_array
, _struct_tag
);
1592 printf ("*resword;\n\n");
1595 printf (" register %sresword;\n\n",
1598 output_switches (_head
, num_switches
, switch_size
, _min_hash_value
, _max_hash_value
, 10);
1600 printf (" return 0;\n");
1601 if (option
[DUP
] && _total_duplicates
> 0)
1604 printf ("%*smulticompare:\n"
1605 "%*s while (wordptr < wordendptr)\n"
1607 indent
, "", indent
, "", indent
, "");
1608 if (option
[LENTABLE
])
1610 printf ("%*s if (len == *lengthptr)\n"
1612 indent
, "", indent
, "");
1615 printf ("%*s register %schar *s = ",
1616 indent
, "", const_always
);
1618 printf ("wordptr->%s", option
.get_slot_name ());
1620 printf ("*wordptr");
1621 if (option
[SHAREDLIB
])
1623 option
.get_stringpool_name ());
1627 comparison
.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s"));
1631 option
[TYPE
] ? "wordptr" : "s");
1632 if (option
[LENTABLE
])
1638 if (option
[LENTABLE
])
1639 printf ("%*s lengthptr++;\n",
1641 printf ("%*s wordptr++;\n"
1644 indent
, "", indent
, "", indent
, "");
1646 printf (" compare:\n");
1650 " register %schar *s = resword->%s",
1651 const_always
, option
.get_slot_name ());
1652 if (option
[SHAREDLIB
])
1654 option
.get_stringpool_name ());
1657 comparison
.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s"));
1659 " return resword;\n"
1665 comparison
.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("resword"));
1667 " return resword;\n");
1673 printf (" if (key <= MAX_HASH_VALUE && key >= 0)\n");
1679 "%*s register int index = lookup[key];\n\n"
1680 "%*s if (index >= 0)\n",
1681 indent
, "", indent
, "", indent
, "");
1682 if (option
[LENTABLE
])
1685 "%*s if (len == lengthtable[index])\n",
1686 indent
, "", indent
, "");
1690 "%*s register %schar *s = %s[index]",
1692 indent
, "", const_always
, option
.get_wordlist_name ());
1694 printf (".%s", option
.get_slot_name ());
1695 if (option
[SHAREDLIB
])
1697 option
.get_stringpool_name ());
1701 comparison
.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s"));
1706 printf ("&%s[index]", option
.get_wordlist_name ());
1712 if (option
[LENTABLE
])
1715 printf ("%*s }\n", indent
, "");
1717 if (_total_duplicates
> 0)
1719 printf ("%*s else if (index < -TOTAL_KEYWORDS)\n"
1721 "%*s register int offset = - 1 - TOTAL_KEYWORDS - index;\n",
1722 indent
, "", indent
, "", indent
, "");
1723 if (option
[LENTABLE
])
1724 printf ("%*s register %s%s *lengthptr = &lengthtable[TOTAL_KEYWORDS + lookup[offset]];\n",
1725 indent
, "", const_always
, smallest_integral_type (_max_key_len
));
1726 printf ("%*s register ",
1728 output_const_type (const_readonly_array
, _wordlist_eltype
);
1729 printf ("*wordptr = &%s[TOTAL_KEYWORDS + lookup[offset]];\n",
1730 option
.get_wordlist_name ());
1731 printf ("%*s register ",
1733 output_const_type (const_readonly_array
, _wordlist_eltype
);
1734 printf ("*wordendptr = wordptr + -lookup[offset + 1];\n\n");
1735 printf ("%*s while (wordptr < wordendptr)\n"
1737 indent
, "", indent
, "");
1738 if (option
[LENTABLE
])
1740 printf ("%*s if (len == *lengthptr)\n"
1742 indent
, "", indent
, "");
1745 printf ("%*s register %schar *s = ",
1746 indent
, "", const_always
);
1748 printf ("wordptr->%s", option
.get_slot_name ());
1750 printf ("*wordptr");
1751 if (option
[SHAREDLIB
])
1753 option
.get_stringpool_name ());
1757 comparison
.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s"));
1761 option
[TYPE
] ? "wordptr" : "s");
1762 if (option
[LENTABLE
])
1768 if (option
[LENTABLE
])
1769 printf ("%*s lengthptr++;\n",
1771 printf ("%*s wordptr++;\n"
1774 indent
, "", indent
, "", indent
, "");
1782 if (option
[LENTABLE
])
1784 printf ("%*sif (len == lengthtable[key])\n",
1789 if (option
[SHAREDLIB
])
1791 if (!option
[LENTABLE
])
1794 "%*s register int o = %s[key]",
1796 indent
, "", option
.get_wordlist_name ());
1798 printf (".%s", option
.get_slot_name ());
1805 printf ("%*s register %schar *s = o",
1806 indent
, "", const_always
);
1810 /* No need for the (o >= 0) test, because the
1811 (len == lengthtable[key]) test already guarantees that
1812 key points to nonempty table entry. */
1814 "%*s register %schar *s = %s[key]",
1816 indent
, "", const_always
,
1817 option
.get_wordlist_name ());
1819 printf (".%s", option
.get_slot_name ());
1822 option
.get_stringpool_name ());
1827 "%*s register %schar *s = %s[key]",
1829 indent
, "", const_always
, option
.get_wordlist_name ());
1831 printf (".%s", option
.get_slot_name ());
1837 if (!option
[SHAREDLIB
] && option
[NULLSTRINGS
])
1839 comparison
.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s"));
1844 printf ("&%s[key]", option
.get_wordlist_name ());
1848 if (option
[SHAREDLIB
] && !option
[LENTABLE
])
1862 /* Generates C code for the lookup function. */
1865 Output::output_lookup_function () const
1867 /* Output the function's head. */
1868 if (option
[KRC
] | option
[C
] | option
[ANSIC
])
1869 printf ("#ifdef __GNUC__\n"
1874 const_for_struct
, _return_type
);
1875 if (option
[CPLUSPLUS
])
1876 printf ("%s::", option
.get_class_name ());
1877 printf ("%s ", option
.get_function_name ());
1878 printf (option
[KRC
] ?
1880 " register char *str;\n"
1881 " register unsigned int len;\n" :
1884 " register const char *str;\n"
1885 " register unsigned int len;\n" :
1886 option
[ANSIC
] | option
[CPLUSPLUS
] ?
1887 "(register const char *str, register unsigned int len)\n" :
1890 /* Output the function's body. */
1893 if (option
[ENUM
] && !option
[GLOBAL
])
1895 Output_Enum
style (" ");
1896 output_constants (style
);
1899 if (option
[SHAREDLIB
] && !(option
[GLOBAL
] || option
[TYPE
]))
1900 output_lookup_pools ();
1901 if (!option
[GLOBAL
])
1902 output_lookup_tables ();
1904 if (option
[LENTABLE
])
1905 output_lookup_function_body (Output_Compare_Memcmp ());
1909 output_lookup_function_body (Output_Compare_Strncmp ());
1911 output_lookup_function_body (Output_Compare_Strcmp ());
1917 /* ------------------------------------------------------------------------- */
1919 /* Generates the hash function and the key word recognizer function
1920 based upon the user's Options. */
1927 if (option
[C
] | option
[ANSIC
] | option
[CPLUSPLUS
])
1929 const_always
= "const ";
1930 const_readonly_array
= (option
[CONST
] ? "const " : "");
1931 const_for_struct
= ((option
[CONST
] && option
[TYPE
]) ? "const " : "");
1936 const_readonly_array
= "";
1937 const_for_struct
= "";
1942 _return_type
= (const_always
[0] ? "const char *" : "char *");
1943 _struct_tag
= (const_always
[0] ? "const char *" : "char *");
1946 _wordlist_eltype
= (option
[SHAREDLIB
] && !option
[TYPE
] ? "int" : _struct_tag
);
1953 else if (option
[ANSIC
])
1955 else if (option
[CPLUSPLUS
])
1957 printf (" code produced by gperf version %s */\n", version_string
);
1958 option
.print_options ();
1960 if (!option
[POSITIONS
])
1962 printf ("/* Computed positions: -k'");
1963 _key_positions
.print();
1968 if (_charset_dependent
1969 && (_key_positions
.get_size() > 0 || option
[UPPERLOWER
]))
1971 /* The generated tables assume that the execution character set is
1972 based on ISO-646, not EBCDIC. */
1973 printf ("#if !((' ' == 32) && ('!' == 33) && ('\"' == 34) && ('#' == 35) \\\n"
1974 " && ('%%' == 37) && ('&' == 38) && ('\\'' == 39) && ('(' == 40) \\\n"
1975 " && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \\\n"
1976 " && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \\\n"
1977 " && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \\\n"
1978 " && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \\\n"
1979 " && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \\\n"
1980 " && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \\\n"
1981 " && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \\\n"
1982 " && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \\\n"
1983 " && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \\\n"
1984 " && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \\\n"
1985 " && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \\\n"
1986 " && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \\\n"
1987 " && ('Z' == 90) && ('[' == 91) && ('\\\\' == 92) && (']' == 93) \\\n"
1988 " && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \\\n"
1989 " && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \\\n"
1990 " && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \\\n"
1991 " && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \\\n"
1992 " && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \\\n"
1993 " && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \\\n"
1994 " && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \\\n"
1995 " && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))\n"
1996 "/* The character set is not based on ISO-646. */\n");
1997 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");
1998 printf ("#endif\n\n");
2001 if (_verbatim_declarations
< _verbatim_declarations_end
)
2003 if (option
.get_input_file_name ())
2004 printf ("#line %u \"%s\"\n",
2005 _verbatim_declarations_lineno
, option
.get_input_file_name ());
2006 fwrite (_verbatim_declarations
, 1,
2007 _verbatim_declarations_end
- _verbatim_declarations
, stdout
);
2010 if (option
[TYPE
] && !option
[NOTYPE
]) /* Output type declaration now, reference it later on.... */
2012 if (option
.get_input_file_name ())
2013 printf ("#line %u \"%s\"\n",
2014 _struct_decl_lineno
, option
.get_input_file_name ());
2015 printf ("%s\n", _struct_decl
);
2018 if (option
[INCLUDE
])
2019 printf ("#include <string.h>\n"); /* Declare strlen(), strcmp(), strncmp(). */
2023 Output_Defines style
;
2024 output_constants (style
);
2026 else if (option
[GLOBAL
])
2028 Output_Enum
style ("");
2029 output_constants (style
);
2032 printf ("/* maximum key range = %d, duplicates = %d */\n\n",
2033 _max_hash_value
- _min_hash_value
+ 1, _total_duplicates
);
2035 if (option
[UPPERLOWER
])
2037 #if USE_DOWNCASE_TABLE
2038 output_upperlower_table ();
2041 if (option
[LENTABLE
])
2042 output_upperlower_memcmp ();
2046 output_upperlower_strncmp ();
2048 output_upperlower_strcmp ();
2052 if (option
[CPLUSPLUS
])
2053 printf ("class %s\n"
2056 " static inline unsigned int %s (const char *str, unsigned int len);\n"
2058 " static %s%s%s (const char *str, unsigned int len);\n"
2061 option
.get_class_name (), option
.get_hash_name (),
2062 const_for_struct
, _return_type
, option
.get_function_name ());
2064 output_hash_function ();
2066 if (option
[SHAREDLIB
] && (option
[GLOBAL
] || option
[TYPE
]))
2067 output_lookup_pools ();
2069 output_lookup_tables ();
2071 output_lookup_function ();
2073 if (_verbatim_code
< _verbatim_code_end
)
2075 if (option
.get_input_file_name ())
2076 printf ("#line %u \"%s\"\n",
2077 _verbatim_code_lineno
, option
.get_input_file_name ());
2078 fwrite (_verbatim_code
, 1, _verbatim_code_end
- _verbatim_code
, stdout
);