1 /* Driver program for the hash function generator
2 Copyright (C) 1989-1998, 2000, 2002-2003 Free Software Foundation, Inc.
3 Written by Douglas C. Schmidt <[email protected]>
4 and Bruno Haible <[email protected]>.
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 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include "options.h"
27 #include "input.h"
28 #include "search.h"
29 #include "output.h"
30
31
32 /* ------------------------------------------------------------------------- */
33
34 /* This Keyword factory produces KeywordExt instances. */
35
36 class KeywordExt_Factory : public Keyword_Factory
37 {
38 virtual Keyword * create_keyword (const char *allchars, int allchars_length,
39 const char *rest);
40 };
41
42 Keyword *
create_keyword(const char * allchars,int allchars_length,const char * rest)43 KeywordExt_Factory::create_keyword (const char *allchars, int allchars_length, const char *rest)
44 {
45 return new KeywordExt (allchars, allchars_length, rest);
46 }
47
48 /* ------------------------------------------------------------------------- */
49
50 int
main(int argc,char * argv[])51 main (int argc, char *argv[])
52 {
53 int exitcode;
54
55 /* Set the Options. Open the input file and assign stdin to it. */
56 option.parse_options (argc, argv);
57
58 /* Open the input file. */
59 if (option.get_input_file_name ())
60 if (!freopen (option.get_input_file_name (), "r", stdin))
61 {
62 fprintf (stderr, "Cannot open input file '%s'\n",
63 option.get_input_file_name ());
64 exit (1);
65 }
66
67 {
68 /* Initialize the keyword list. */
69 KeywordExt_Factory factory;
70 Input inputter (stdin, &factory);
71 inputter.read_input ();
72 /* We can cast the keyword list to KeywordExt_List* because its list
73 elements were created by KeywordExt_Factory. */
74 KeywordExt_List* list = static_cast<KeywordExt_List*>(inputter._head);
75
76 {
77 /* Search for a good hash function. */
78 Search searcher (list);
79 searcher.optimize ();
80 list = searcher._head;
81
82 /* Open the output file. */
83 if (option.get_output_file_name ())
84 if (strcmp (option.get_output_file_name (), "-") != 0)
85 if (!freopen (option.get_output_file_name (), "w", stdout))
86 {
87 fprintf (stderr, "Cannot open output file '%s'\n",
88 option.get_output_file_name ());
89 exit (1);
90 }
91
92 {
93 /* Output the hash function code. */
94 Output outputter (searcher._head,
95 inputter._struct_decl,
96 inputter._struct_decl_lineno,
97 inputter._return_type,
98 inputter._struct_tag,
99 inputter._verbatim_declarations,
100 inputter._verbatim_declarations_end,
101 inputter._verbatim_declarations_lineno,
102 inputter._verbatim_code,
103 inputter._verbatim_code_end,
104 inputter._verbatim_code_lineno,
105 inputter._charset_dependent,
106 searcher._total_keys,
107 searcher._max_key_len,
108 searcher._min_key_len,
109 searcher._key_positions,
110 searcher._alpha_inc,
111 searcher._total_duplicates,
112 searcher._alpha_size,
113 searcher._asso_values);
114 outputter.output ();
115
116 /* Check for write error on stdout. */
117 exitcode = 0;
118 if (fflush (stdout) || ferror (stdout))
119 {
120 fprintf (stderr, "error while writing output file\n");
121 exitcode = 1;
122 }
123
124 /* Here we run the Output destructor. */
125 }
126 /* Here we run the Search destructor. */
127 }
128
129 /* Also delete the list that was allocated inside Input and reordered
130 inside Search. */
131 for (KeywordExt_List *ptr = list; ptr; ptr = ptr->rest())
132 {
133 KeywordExt *keyword = ptr->first();
134 do
135 {
136 KeywordExt *next_keyword = keyword->_duplicate_link;
137 delete[] const_cast<unsigned int *>(keyword->_selchars);
138 if (keyword->_rest != empty_string)
139 delete[] const_cast<char*>(keyword->_rest);
140 if (!(keyword->_allchars >= inputter._input
141 && keyword->_allchars < inputter._input_end))
142 delete[] const_cast<char*>(keyword->_allchars);
143 delete keyword;
144 keyword = next_keyword;
145 }
146 while (keyword != NULL);
147 }
148 delete_list (list);
149
150 /* Here we run the Input destructor. */
151 }
152
153 /* Don't use exit() here, it skips the destructors. */
154 return exitcode;
155 }
156