diff options
author | Bruno Haible <bruno@clisp.org> | 2003-04-10 10:26:05 +0000 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2003-04-10 10:26:05 +0000 |
commit | f619dea2f545f3e3a0265912249c09f58671cb5e (patch) | |
tree | c9354c30ed5155ad439212d39df23a3cd7673759 | |
parent | bfefa088aa22eb8f026e93ee1c372fe18c3fa3a1 (diff) | |
download | gperf-f619dea2f545f3e3a0265912249c09f58671cb5e.tar.gz |
Portability: Use stack-allocated arrays only if the compiler supports them.
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | src/Makefile.in | 2 | ||||
-rw-r--r-- | src/config.h.in | 4 | ||||
-rw-r--r-- | src/configure.in | 13 | ||||
-rw-r--r-- | src/search.cc | 40 |
5 files changed, 61 insertions, 6 deletions
@@ -1,5 +1,13 @@ 2002-12-12 Bruno Haible <bruno@clisp.org> + * src/configure.in: Add test for stack-allocated variable-size arrays. + * src/config.h.in: Regenerated. + * src/search.cc: Include config.h. + (DYNAMIC_ARRAY, FREE_DYNAMIC_ARRAY): New macros. + (Search::find_alpha_inc, Search::count_possible_collisions, + Search::find_asso_values): Use them. + * src/Makefile.in (search.o): Depend on config.h. + * src/search.h (Search::keyword_list_length, Search::max_key_length, Search::get_max_keysig_size, Search::prepare): Remove declarations. (Search::prepare): Renamed from Search::preprepare. diff --git a/src/Makefile.in b/src/Makefile.in index 8774371..fd6d872 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -111,7 +111,7 @@ bool-array.o : bool-array.cc $(BOOL_ARRAY_H) $(OPTIONS_H) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/bool-array.cc hash-table.o : hash-table.cc $(HASH_TABLE_H) $(OPTIONS_H) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/hash-table.cc -search.o : search.cc $(SEARCH_H) $(OPTIONS_H) $(HASH_TABLE_H) +search.o : search.cc $(SEARCH_H) $(OPTIONS_H) $(HASH_TABLE_H) $(CONFIG_H) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/search.cc output.o : output.cc $(OUTPUT_H) $(OPTIONS_H) $(VERSION_H) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/output.cc diff --git a/src/config.h.in b/src/config.h.in index 4d3d762..3b55444 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -1,5 +1,9 @@ /* config.h.in. Generated automatically from configure.in by autoheader. */ +/* Define if the C++ compiler supports stack-allocated variable-size arrays. + */ +#undef HAVE_DYNAMIC_ARRAY + /* Define if the C++ compiler supports "throw ()" declarations. */ #undef HAVE_THROW_DECL diff --git a/src/configure.in b/src/configure.in index b80d48e..3a42d13 100644 --- a/src/configure.in +++ b/src/configure.in @@ -40,6 +40,19 @@ CL_PROG_INSTALL dnl dnl checks for compiler characteristics dnl +AC_MSG_CHECKING([for stack-allocated variable-size arrays]) +AC_CACHE_VAL(gp_cv_cxx_dynamic_array, [ +AC_LANG_SAVE() +AC_LANG_CPLUSPLUS() +AC_TRY_COMPILE([int func (int n) { int dynamic_array[n]; }], [], +gp_cv_cxx_dynamic_array=yes, gp_cv_cxx_dynamic_array=no) +AC_LANG_RESTORE() +]) +AC_MSG_RESULT($gp_cv_cxx_dynamic_array) +if test $gp_cv_cxx_dynamic_array = yes; then + AC_DEFINE(HAVE_DYNAMIC_ARRAY, 1, + [Define if the C++ compiler supports stack-allocated variable-size arrays.]) +fi dnl dnl checks for functions and declarations dnl diff --git a/src/search.cc b/src/search.cc index 04608c1..a1e3d70 100644 --- a/src/search.cc +++ b/src/search.cc @@ -31,9 +31,33 @@ #include <limits.h> /* defines INT_MIN, INT_MAX, UINT_MAX */ #include "options.h" #include "hash-table.h" +#include "config.h" + +/* ============================== Portability ============================== */ + /* Assume ISO C++ 'for' scoping rule. */ #define for if (0) ; else for +/* Dynamically allocated array with dynamic extent: + + Example: + DYNAMIC_ARRAY (my_array, int, n); + ... + FREE_DYNAMIC_ARRAY (my_array); + + Attention: depending on your implementation my_array is either the array + itself or a pointer to the array! Always use my_array only as expression! + */ +#if HAVE_DYNAMIC_ARRAY + #define DYNAMIC_ARRAY(var,eltype,size) eltype var[size] + #define FREE_DYNAMIC_ARRAY(var) +#else + #define DYNAMIC_ARRAY(var,eltype,size) eltype *var = new eltype[size] + #define FREE_DYNAMIC_ARRAY(var) delete[] var +#endif + +/* ================================ Theory ================================= */ + /* The most general form of the hash function is hash (keyword) = sum (asso_values[keyword[i] + alpha_inc[i]] : i in Pos) @@ -589,7 +613,7 @@ Search::find_alpha_inc () } } - unsigned int indices[nindices]; + DYNAMIC_ARRAY (indices, unsigned int, nindices); { unsigned int j = 0; PositionIterator iter = _key_positions.iterator(_max_key_len); @@ -608,8 +632,8 @@ Search::find_alpha_inc () /* Perform several rounds of searching for a good alpha increment. Each round reduces the number of artificial collisions by adding an increment in a single key position. */ - unsigned int best[_max_key_len]; - unsigned int tryal[_max_key_len]; + DYNAMIC_ARRAY (best, unsigned int, _max_key_len); + DYNAMIC_ARRAY (tryal, unsigned int, _max_key_len); do { /* An increment of 1 is not always enough. Try higher increments @@ -644,6 +668,8 @@ Search::find_alpha_inc () } } while (current_duplicates_count > duplicates_goal); + FREE_DYNAMIC_ARRAY (tryal); + FREE_DYNAMIC_ARRAY (best); if (option[DEBUG]) { @@ -661,6 +687,7 @@ Search::find_alpha_inc () } fprintf (stderr, "\n"); } + FREE_DYNAMIC_ARRAY (indices); } _alpha_inc = current; @@ -1003,7 +1030,7 @@ Search::count_possible_collisions (EquivalenceClass *partition, unsigned int c) Return the sum of this expression over all equivalence classes. */ unsigned int sum = 0; unsigned int m = _max_selchars_length; - unsigned int split_cardinalities[m+1]; + DYNAMIC_ARRAY (split_cardinalities, unsigned int, m + 1); for (EquivalenceClass *cls = partition; cls; cls = cls->_next) { for (unsigned int i = 0; i <= m; i++) @@ -1025,6 +1052,7 @@ Search::count_possible_collisions (EquivalenceClass *partition, unsigned int c) for (unsigned int i = 0; i <= m; i++) sum -= split_cardinalities[i] * split_cardinalities[i]; } + FREE_DYNAMIC_ARRAY (split_cardinalities); return sum; } @@ -1231,7 +1259,7 @@ Search::find_asso_values () } unsigned int iterations = 0; - unsigned int iter[k]; + DYNAMIC_ARRAY (iter, unsigned int, k); for (unsigned int i = 0; i < k; i++) iter[i] = 0; unsigned int ii = (_jump != 0 ? k - 1 : 0); @@ -1384,6 +1412,8 @@ Search::find_asso_values () ii = 0; } } + FREE_DYNAMIC_ARRAY (iter); + if (option[DEBUG]) { fprintf (stderr, "Step %u chose _asso_values[", stepno); |