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 <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#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 36class KeywordExt_Factory : public Keyword_Factory 37{ 38virtual Keyword * create_keyword (const char *allchars, int allchars_length, 39 const char *rest); 40}; 41 42Keyword * 43KeywordExt_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 50int 51main (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