1230237Sbapt/* Driver program for the hash function generator 2230237Sbapt Copyright (C) 1989-1998, 2000, 2002-2003 Free Software Foundation, Inc. 3230237Sbapt Written by Douglas C. Schmidt <schmidt@ics.uci.edu> 4230237Sbapt and Bruno Haible <bruno@clisp.org>. 558551Skris 6230237Sbapt This file is part of GNU GPERF. 758551Skris 8230237Sbapt GNU GPERF is free software; you can redistribute it and/or modify 9230237Sbapt it under the terms of the GNU General Public License as published by 10230237Sbapt the Free Software Foundation; either version 2, or (at your option) 11230237Sbapt any later version. 1258551Skris 13230237Sbapt GNU GPERF is distributed in the hope that it will be useful, 14230237Sbapt but WITHOUT ANY WARRANTY; without even the implied warranty of 15230237Sbapt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16230237Sbapt GNU General Public License for more details. 1758551Skris 18230237Sbapt You should have received a copy of the GNU General Public License 19230237Sbapt along with this program; see the file COPYING. 20230237Sbapt If not, write to the Free Software Foundation, Inc., 21230237Sbapt 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 2258551Skris 2358551Skris#include <stdio.h> 24230237Sbapt#include <stdlib.h> 25230237Sbapt#include <string.h> 2658551Skris#include "options.h" 27230237Sbapt#include "input.h" 28230237Sbapt#include "search.h" 29230237Sbapt#include "output.h" 3058551Skris 31230237Sbapt 32230237Sbapt/* ------------------------------------------------------------------------- */ 33230237Sbapt 34230237Sbapt/* This Keyword factory produces KeywordExt instances. */ 35230237Sbapt 36230237Sbaptclass KeywordExt_Factory : public Keyword_Factory 37230237Sbapt{ 38230237Sbaptvirtual Keyword * create_keyword (const char *allchars, int allchars_length, 39230237Sbapt const char *rest); 40230237Sbapt}; 41230237Sbapt 42230237SbaptKeyword * 43230237SbaptKeywordExt_Factory::create_keyword (const char *allchars, int allchars_length, const char *rest) 44230237Sbapt{ 45230237Sbapt return new KeywordExt (allchars, allchars_length, rest); 46230237Sbapt} 47230237Sbapt 48230237Sbapt/* ------------------------------------------------------------------------- */ 49230237Sbapt 5058551Skrisint 5158551Skrismain (int argc, char *argv[]) 5258551Skris{ 53230237Sbapt int exitcode; 5458551Skris 55230237Sbapt /* Set the Options. Open the input file and assign stdin to it. */ 56230237Sbapt option.parse_options (argc, argv); 57230237Sbapt 58230237Sbapt /* Open the input file. */ 59230237Sbapt if (option.get_input_file_name ()) 60230237Sbapt if (!freopen (option.get_input_file_name (), "r", stdin)) 61230237Sbapt { 62230237Sbapt fprintf (stderr, "Cannot open input file '%s'\n", 63230237Sbapt option.get_input_file_name ()); 64230237Sbapt exit (1); 65230237Sbapt } 66230237Sbapt 6758551Skris { 68230237Sbapt /* Initialize the keyword list. */ 69230237Sbapt KeywordExt_Factory factory; 70230237Sbapt Input inputter (stdin, &factory); 71230237Sbapt inputter.read_input (); 72230237Sbapt /* We can cast the keyword list to KeywordExt_List* because its list 73230237Sbapt elements were created by KeywordExt_Factory. */ 74230237Sbapt KeywordExt_List* list = static_cast<KeywordExt_List*>(inputter._head); 7558551Skris 76230237Sbapt { 77230237Sbapt /* Search for a good hash function. */ 78230237Sbapt Search searcher (list); 79230237Sbapt searcher.optimize (); 80230237Sbapt list = searcher._head; 8158551Skris 82230237Sbapt /* Open the output file. */ 83230237Sbapt if (option.get_output_file_name ()) 84230237Sbapt if (strcmp (option.get_output_file_name (), "-") != 0) 85230237Sbapt if (!freopen (option.get_output_file_name (), "w", stdout)) 86230237Sbapt { 87230237Sbapt fprintf (stderr, "Cannot open output file '%s'\n", 88230237Sbapt option.get_output_file_name ()); 89230237Sbapt exit (1); 90230237Sbapt } 9158551Skris 92230237Sbapt { 93230237Sbapt /* Output the hash function code. */ 94230237Sbapt Output outputter (searcher._head, 95230237Sbapt inputter._struct_decl, 96230237Sbapt inputter._struct_decl_lineno, 97230237Sbapt inputter._return_type, 98230237Sbapt inputter._struct_tag, 99230237Sbapt inputter._verbatim_declarations, 100230237Sbapt inputter._verbatim_declarations_end, 101230237Sbapt inputter._verbatim_declarations_lineno, 102230237Sbapt inputter._verbatim_code, 103230237Sbapt inputter._verbatim_code_end, 104230237Sbapt inputter._verbatim_code_lineno, 105230237Sbapt inputter._charset_dependent, 106230237Sbapt searcher._total_keys, 107230237Sbapt searcher._max_key_len, 108230237Sbapt searcher._min_key_len, 109230237Sbapt searcher._key_positions, 110230237Sbapt searcher._alpha_inc, 111230237Sbapt searcher._total_duplicates, 112230237Sbapt searcher._alpha_size, 113230237Sbapt searcher._asso_values); 114230237Sbapt outputter.output (); 11558551Skris 116230237Sbapt /* Check for write error on stdout. */ 117230237Sbapt exitcode = 0; 118230237Sbapt if (fflush (stdout) || ferror (stdout)) 119230237Sbapt { 120230237Sbapt fprintf (stderr, "error while writing output file\n"); 121230237Sbapt exitcode = 1; 122230237Sbapt } 12367064Sobrien 124230237Sbapt /* Here we run the Output destructor. */ 125230237Sbapt } 126230237Sbapt /* Here we run the Search destructor. */ 127230237Sbapt } 128230237Sbapt 129230237Sbapt /* Also delete the list that was allocated inside Input and reordered 130230237Sbapt inside Search. */ 131230237Sbapt for (KeywordExt_List *ptr = list; ptr; ptr = ptr->rest()) 132230237Sbapt { 133230237Sbapt KeywordExt *keyword = ptr->first(); 134230237Sbapt do 135230237Sbapt { 136230237Sbapt KeywordExt *next_keyword = keyword->_duplicate_link; 137230237Sbapt delete[] const_cast<unsigned int *>(keyword->_selchars); 138230237Sbapt if (keyword->_rest != empty_string) 139230237Sbapt delete[] const_cast<char*>(keyword->_rest); 140230237Sbapt if (!(keyword->_allchars >= inputter._input 141230237Sbapt && keyword->_allchars < inputter._input_end)) 142230237Sbapt delete[] const_cast<char*>(keyword->_allchars); 143230237Sbapt delete keyword; 144230237Sbapt keyword = next_keyword; 145230237Sbapt } 146230237Sbapt while (keyword != NULL); 147230237Sbapt } 148230237Sbapt delete_list (list); 149230237Sbapt 150230237Sbapt /* Here we run the Input destructor. */ 151230237Sbapt } 152230237Sbapt 153230237Sbapt /* Don't use exit() here, it skips the destructors. */ 154230237Sbapt return exitcode; 15558551Skris} 156