mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-30 08:19:09 +00:00
This commit was generated by cvs2svn to compensate for changes in r18214,
which included commits to RCS files with non-trunk default branches.
This commit is contained in:
commit
b5a85b5ef7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=18215
249
contrib/gperf/COPYING
Normal file
249
contrib/gperf/COPYING
Normal file
@ -0,0 +1,249 @@
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 1, February 1989
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The license agreements of most software companies try to keep users
|
||||
at the mercy of those companies. By contrast, our General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. The
|
||||
General Public License applies to the Free Software Foundation's
|
||||
software and to any other program whose authors commit to using it.
|
||||
You can use it for your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Specifically, the General Public License is designed to make
|
||||
sure that you have the freedom to give away or sell copies of free
|
||||
software, that you receive source code or can get it if you want it,
|
||||
that you can change the software or use pieces of it in new free
|
||||
programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of a such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must tell them their rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any program or other work which
|
||||
contains a notice placed by the copyright holder saying it may be
|
||||
distributed under the terms of this General Public License. The
|
||||
"Program", below, refers to any such program or work, and a "work based
|
||||
on the Program" means either the Program or any work containing the
|
||||
Program or a portion of it, either verbatim or with modifications. Each
|
||||
licensee is addressed as "you".
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's source
|
||||
code as you receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice and
|
||||
disclaimer of warranty; keep intact all the notices that refer to this
|
||||
General Public License and to the absence of any warranty; and give any
|
||||
other recipients of the Program a copy of this General Public License
|
||||
along with the Program. You may charge a fee for the physical act of
|
||||
transferring a copy.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion of
|
||||
it, and copy and distribute such modifications under the terms of Paragraph
|
||||
1 above, provided that you also do the following:
|
||||
|
||||
a) cause the modified files to carry prominent notices stating that
|
||||
you changed the files and the date of any change; and
|
||||
|
||||
b) cause the whole of any work that you distribute or publish, that
|
||||
in whole or in part contains the Program or any part thereof, either
|
||||
with or without modifications, to be licensed at no charge to all
|
||||
third parties under the terms of this General Public License (except
|
||||
that you may choose to grant warranty protection to some or all
|
||||
third parties, at your option).
|
||||
|
||||
c) If the modified program normally reads commands interactively when
|
||||
run, you must cause it, when started running for such interactive use
|
||||
in the simplest and most usual way, to print or display an
|
||||
announcement including an appropriate copyright notice and a notice
|
||||
that there is no warranty (or else, saying that you provide a
|
||||
warranty) and that users may redistribute the program under these
|
||||
conditions, and telling the user how to view a copy of this General
|
||||
Public License.
|
||||
|
||||
d) You may charge a fee for the physical act of transferring a
|
||||
copy, and you may at your option offer warranty protection in
|
||||
exchange for a fee.
|
||||
|
||||
Mere aggregation of another independent work with the Program (or its
|
||||
derivative) on a volume of a storage or distribution medium does not bring
|
||||
the other work under the scope of these terms.
|
||||
|
||||
3. You may copy and distribute the Program (or a portion or derivative of
|
||||
it, under Paragraph 2) in object code or executable form under the terms of
|
||||
Paragraphs 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of
|
||||
Paragraphs 1 and 2 above; or,
|
||||
|
||||
b) accompany it with a written offer, valid for at least three
|
||||
years, to give any third party free (except for a nominal charge
|
||||
for the cost of distribution) a complete machine-readable copy of the
|
||||
corresponding source code, to be distributed under the terms of
|
||||
Paragraphs 1 and 2 above; or,
|
||||
|
||||
c) accompany it with the information you received as to where the
|
||||
corresponding source code may be obtained. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form alone.)
|
||||
|
||||
Source code for a work means the preferred form of the work for making
|
||||
modifications to it. For an executable file, complete source code means
|
||||
all the source code for all modules it contains; but, as a special
|
||||
exception, it need not include source code for modules which are standard
|
||||
libraries that accompany the operating system on which the executable
|
||||
file runs, or for standard header files or definitions files that
|
||||
accompany that operating system.
|
||||
|
||||
4. You may not copy, modify, sublicense, distribute or transfer the
|
||||
Program except as expressly provided under this General Public License.
|
||||
Any attempt otherwise to copy, modify, sublicense, distribute or transfer
|
||||
the Program is void, and will automatically terminate your rights to use
|
||||
the Program under this License. However, parties who have received
|
||||
copies, or rights to use copies, from you under this General Public
|
||||
License will not have their licenses terminated so long as such parties
|
||||
remain in full compliance.
|
||||
|
||||
5. By copying, distributing or modifying the Program (or any work based
|
||||
on the Program) you indicate your acceptance of this license to do so,
|
||||
and all its terms and conditions.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the original
|
||||
licensor to copy, distribute or modify the Program subject to these
|
||||
terms and conditions. You may not impose any further restrictions on the
|
||||
recipients' exercise of the rights granted herein.
|
||||
|
||||
7. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of the license which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
the license, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
8. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to humanity, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these
|
||||
terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest to
|
||||
attach them to the start of each source file to most effectively convey
|
||||
the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19xx name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the
|
||||
appropriate parts of the General Public License. Of course, the
|
||||
commands you use may be called something other than `show w' and `show
|
||||
c'; they could even be mouse-clicks or menu items--whatever suits your
|
||||
program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
program `Gnomovision' (a program to direct compilers to make passes
|
||||
at assemblers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
375
contrib/gperf/ChangeLog
Normal file
375
contrib/gperf/ChangeLog
Normal file
@ -0,0 +1,375 @@
|
||||
Sat Nov 11 13:43:17 1989 Doug Schmidt (schmidt at zola.ics.uci.edu)
|
||||
|
||||
* Modified options by changing macro TOTAL_POSITIONS to GET_CHARSET_SIZE
|
||||
and SET_CHARSET_SIZE. These two routines now either return
|
||||
the total charset size *or* the length of the largest keyword
|
||||
if the user specifies the -k'*' (ALLCHARS) option. This change
|
||||
cleans up client code.
|
||||
|
||||
Fri Nov 10 15:21:19 1989 Doug Schmidt (schmidt at zola.ics.uci.edu)
|
||||
|
||||
* Made sure to explicitly initialize perfect.fewest_collisions to
|
||||
0.
|
||||
|
||||
Wed Nov 1 21:39:54 1989 Doug Schmidt (schmidt at zola.ics.uci.edu)
|
||||
|
||||
* Upgraded the version number to 2.0, reflecting all the
|
||||
major recent changes!
|
||||
|
||||
* Rearranged code so that fewer source lines are greater than 80 columns.
|
||||
|
||||
* Cleaned up some loose ends noticed by Nels Olson.
|
||||
1. Removed `if (collisions <= perfect.fewest_collisions)'
|
||||
from affects_prev () since it was superfluous.
|
||||
2. Removed the fields best_char_value and best_asso_value
|
||||
from PERFECT. There were also unnecessary.
|
||||
3. Fixed a braino in boolarray.c's bool_array_reset ()
|
||||
function. Since iteration numbers can never be zero
|
||||
the `if (bool_array.iteration_number++ == 0)' must be
|
||||
`if (++bool_array.iteration_number == 0).'
|
||||
4. Broke the -h help options string into 3 pieces. This
|
||||
should silence broken C compilers for a while!
|
||||
5. Modified `report_error ()' so that it correctly handled
|
||||
"%%".
|
||||
|
||||
Tue Oct 31 23:01:11 1989 Doug Schmidt (schmidt at siam.ics.uci.edu)
|
||||
|
||||
* It is important to note that -D no longer enables -S.
|
||||
There is a good reason for this change, which will become
|
||||
manifested in the next release... (suspense!).
|
||||
|
||||
* Made some subtle changes to print_switch so that if finally
|
||||
seems to work correctly. Needs more stress testing, however...
|
||||
|
||||
Mon Oct 30 15:06:59 1989 Doug Schmidt (schmidt at zola.ics.uci.edu)
|
||||
|
||||
* Made a major change to the keylist.c's print_switch () function.
|
||||
The user can now specify the number of switch statements to generate
|
||||
via an argument to the -S option, i.e., -S1 means `generate 1
|
||||
switch statement with all keywords in it,' -S2 means generate
|
||||
2 switch statements with 1/2 the elements in each one, etc.
|
||||
Hopefully this will fix the problem with C compilers not being
|
||||
able to generate code for giant switch statements (but don't
|
||||
hold your breath!)
|
||||
|
||||
* Changed keylist.c's length () function to keyword_list_length ().
|
||||
Also put an extern decl for this function and max_key_length ()
|
||||
into the keylist.h file (don't know why it wasn't already there...).
|
||||
|
||||
Sun Oct 29 08:55:29 1989 Doug Schmidt (schmidt at siam.ics.uci.edu)
|
||||
|
||||
* Added a feature to main.c that prints out the starting wall-clock
|
||||
time before the program begins and prints out the ending wall-clock
|
||||
time when the program is finished.
|
||||
|
||||
* Added the GATHER_STATISTICS code in hashtable.c so we can
|
||||
keep track of how well double hashing is doing. Eventually,
|
||||
GATHER_STATISTICS will be added so that all instrumentation
|
||||
code can be conditionally compiled in.
|
||||
|
||||
* Modified xmalloc.c's buffered_malloc () routine so that it
|
||||
rounded the SIZE byte requests up to the correct alignment
|
||||
size for the target machine.
|
||||
|
||||
Sat Oct 28 11:17:36 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu)
|
||||
|
||||
* Fixed a stupid bug in keylist.c's print_switch () routine. This
|
||||
was necessary to make sure the generated switch statement worked
|
||||
correctly when *both* `natural,' i.e., static links and dynamic
|
||||
links, i.e., unresolved duplicates, hash to the same value.
|
||||
|
||||
* Modified LIST_NODE so that the char *char_set field is redeclared
|
||||
as char char_set[1] and placed at the bottom of the struct. This
|
||||
enables us to play the old `variable-length string in the struct
|
||||
trick' (third time I fell for it this week, chief!). The
|
||||
main purpose of this is to remove n calls to buffered_malloc,
|
||||
where n is the number of keywords.
|
||||
|
||||
* Added a new function to xmalloc.c called buffered_malloc. This
|
||||
reduces the number of calls to malloc by grabbing large chunks
|
||||
of memory and doling them out in small pieces. Almost all uses
|
||||
of xmalloc were replaced with calls to buffered_malloc ().
|
||||
|
||||
* Modified boolarray.c's bool_array_destroy () function so that
|
||||
it now frees the bool_array.storage_array when it is no longer
|
||||
needed. Since this array is generally very large it makes sense
|
||||
to return the memory to the freelist when it is no longer in use.
|
||||
|
||||
* Changed the interface to hash_table_init. This function is
|
||||
now passed a pointer to a power-of-two sized buffer that serves
|
||||
as storage for the hash table. Although this weakens information
|
||||
hiding a little bit it greatly reduces dynamic memory fragmentation,
|
||||
since we can now obtain the memory via a call to alloca, rather
|
||||
than malloc. This change modified keylist.c's read_keys () calling
|
||||
interface.
|
||||
|
||||
* Since alloca is now being used more aggressively a conditional
|
||||
compilation section was added to the init_all () routine in main.c.
|
||||
Taken from GNU GCC, this code gets rid of any avoidable limit
|
||||
on stack size so that alloca does not fail. It is only used
|
||||
if the -DRLIMIT_STACK symbol is defined when gperf is compiled.
|
||||
|
||||
* Moved the `destructor' for bool_array from destroy_all () in
|
||||
main.c into perfect_generate () in perfect.c. This enables
|
||||
us to get free up the large dynamic memory as soon as it is no
|
||||
longer necessary. Also moved the hash_table destructor from
|
||||
destroy_all into read_keys () from keylist.c. This accomplishes
|
||||
the same purpose, i.e., we can free up the space immediately.
|
||||
|
||||
* Added warnings in option.c so that user's would be informed
|
||||
that -r superceeds -i on the command-line.
|
||||
|
||||
* Rewrote affects_prev () from perfect.c. First, the code structure
|
||||
was cleaned up considerably (removing the need for a dreaded
|
||||
goto!). Secondly, a major change occurred so that affects_prev ()
|
||||
returns FALSE (success) when fewest_hits gets down to whatever
|
||||
it was after inserting the previous key (instead of waiting for
|
||||
it to reach 0). In other words, it stops trying if it can
|
||||
resolve the new collisions added by a key, even if there are
|
||||
still other old, unresolved collisions. This modification was
|
||||
suggested by Nels Olson and seems to *greatly* increase the
|
||||
speed of gperf for large keyfiles. Thanks Nels!
|
||||
|
||||
* In a similar vein, inside the change () routine from perfect.c
|
||||
the variable `perfect.fewest_collisions is no longer initialized
|
||||
with the length of the keyword list. Instead it starts out at
|
||||
0 and is incremented by 1 every time change () is called.
|
||||
The rationale for this behavior is that there are times when a
|
||||
collision causes the number of duplicates (collisions) to
|
||||
increase by a large amount when it would presumably just have
|
||||
gone up by 1 if none of the asso_values were changed. That is,
|
||||
at the beginning of change(), you could initialize fewest_hits
|
||||
to 1+(previous value of fewest_hits) instead of to the number of
|
||||
keys. Thanks again, Nels.
|
||||
|
||||
* Replaced alloca with xmalloc in perfect.c's change () function.
|
||||
This should eliminate some overhead at the expense of a little
|
||||
extra memory that is never reclaimed.
|
||||
|
||||
* Renamed perfect.c's merge_sets () to compute_disjoint_union ()
|
||||
to reflect the change in behavior.
|
||||
|
||||
Fri Oct 27 10:12:27 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu)
|
||||
|
||||
* Added the -e option so users can supply a string containing
|
||||
the characters used to separate keywords from their attributes.
|
||||
The default behavior is ",\n".
|
||||
|
||||
* Removed the char *uniq_set field from LIST_NODE and modified
|
||||
uses of uniq_set in perfect.c and keylist.c. Due to changes
|
||||
to perfect.c's merge_set () described below this field was
|
||||
no longer necessary, and its removal makes the program
|
||||
smaller and potentially faster.
|
||||
|
||||
* Added lots of changes/fixes suggested by Nels Olson
|
||||
(umls.UUCP!olson@mis.ucsf.edu). In particular:
|
||||
1. Changed BOOL_ARRAY so that it would dynamically create
|
||||
an array of unsigned shorts rather than ints if the
|
||||
LO_CAL symbol was defined during program compilation.
|
||||
This cuts the amount of dynamic memory usage in half,
|
||||
which is important for large keyfile input.
|
||||
2. Added some additional debugging statements that print extra
|
||||
info to stderr when the -d option is enabled.
|
||||
3. Fixed a really stupid bug in the print_switch () from keylist.c.
|
||||
A right paren was placed at the wrong location.
|
||||
4. Fixed a subtle problem with printing case values when keylinks
|
||||
appear. The logic failed to account for the fact that there
|
||||
can be keylinks *and* regular node info also!
|
||||
5. Finally split the huge help string into two parts. This keeps
|
||||
breaking compilers with static limits on the length of tokens...
|
||||
6. Modified the -j option so that -j 0 means `try random values
|
||||
when searching for a way to resolve collisions.'
|
||||
7. Added a field `num_done' to the PERFECT struct. This is used
|
||||
to report information collected when trying to resolve
|
||||
hash collisions.
|
||||
8. Modified the merge_sets algorithm to perform a disjoint
|
||||
union of two multisets. This ensures that subsequent
|
||||
processing in perfect.c function affect_prev () doesn't
|
||||
waste time trying to change an associated value that is
|
||||
shared between two conflicting keywords.
|
||||
9. Modified affects_prev so that it doesn't try random jump
|
||||
values unless the -j 0 option is enabled.
|
||||
10. Fixed a silly bug in perfect.c change ().
|
||||
This problem caused gperf to seg fault when
|
||||
the -k* option was given and the keyfile file had long
|
||||
keywords.
|
||||
11. Changed the behavior of keylist.c's read_keys () routine
|
||||
so that it would honor -D unequivocally, i.e., it doesn't
|
||||
try to turn off dup handling if the user requests it, even
|
||||
if there are no immediate links in the keyfile input.
|
||||
|
||||
Mon Oct 16 19:58:08 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu)
|
||||
|
||||
* Fixed a number of small bugs kindly brought to my attention by
|
||||
Adam de Boor (bsw!adam@uunet.UU.NET). Thanks Adam! In particular,
|
||||
changed the behavior for the -a (ANSI) option so that the
|
||||
generated prototypes use int rather than size_t for the LEN
|
||||
parameter. It was too ugly having to #include <stddef.h> all
|
||||
over the place...
|
||||
|
||||
* Added a majorly neat hack to Bool_Array, suggested by rfg.
|
||||
The basic idea was to throw away the Ullman array technique.
|
||||
The Ullman array was used to remove the need to reinitialize all
|
||||
the Bool_Array elements to zero everytime we needed to determine
|
||||
whether there were duplicate hash values in the keyword list.
|
||||
The current trick uses an `iteration number' scheme, which takes
|
||||
about 1/3 the space and reduces the overall program running a
|
||||
time by about 20 percent for large input! The hack works as
|
||||
follows:
|
||||
|
||||
1. Dynamically allocate 1 boolean array of size k.
|
||||
2. Initialize the boolean array to zeros, and consider the first
|
||||
iteration to be iteration 1.
|
||||
2. Then on all subsequent iterations we `reset' the bool array by
|
||||
kicking the iteration count by 1.
|
||||
3. When it comes time to check whether a hash value is currently
|
||||
in the boolean array we simply check its index location. If
|
||||
the value stored there is *not* equal to the current iteration
|
||||
number then the item is clearly *not* in the set. In that
|
||||
case we assign the iteration number to that array's index
|
||||
location for future reference. Otherwise, if the item at
|
||||
the index location *is* equal to the iteration number we've
|
||||
found a duplicate. No muss, no fuss!
|
||||
|
||||
Thu Oct 12 18:08:43 1989 Doug Schmidt (schmidt at zola.ics.uci.edu)
|
||||
|
||||
* Updated the version number to 1.9.
|
||||
|
||||
* Added support for the -C option. This makes the contents of
|
||||
all generated tables `readonly'.
|
||||
|
||||
* Changed the handling of generated switches so that there is
|
||||
only one call to str[n]?cmp. This *greatly* reduces the size of
|
||||
the generated assembly code on all compilers I've seen.
|
||||
|
||||
* Fixed a subtle bug that occurred when the -l and -S option
|
||||
was given. Code produced looked something like:
|
||||
|
||||
if (len != key_len || !strcmp (s1, resword->name)) return resword;
|
||||
|
||||
which doesn't make any sense. Clearly, this should be:
|
||||
|
||||
if (len == key_len && !strcmp (s1, resword->name)) return resword;
|
||||
|
||||
Sat Sep 30 12:55:24 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu)
|
||||
|
||||
* Fixed a stupid bug in Key_List::print_hash_function that manifested
|
||||
itself if the `-k$' option was given (i.e., only use the key[length]
|
||||
character in the hash function).
|
||||
|
||||
Mon Jul 24 17:09:46 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu)
|
||||
|
||||
* Fixed a bug in PRINT_MIN_MAX that resulted in MAX_INT being printed
|
||||
for the MIN_KEY_LEN if there was only 1 keyword in the input file
|
||||
(yeah, that's a pretty unlikely occurrence, I agree!).
|
||||
|
||||
* Fixed PRINT_HASH_FUNCTION and PRINT_LOOKUP_FUNCTION in keylist.c
|
||||
so that the generated functions take an unsigned int length argument.
|
||||
If -a is enabled the prototype is (const char *str, size_t len).
|
||||
|
||||
Fri Jul 21 13:06:15 1989 Doug Schmidt (schmidt at zola.ics.uci.edu)
|
||||
|
||||
* Fixed a horrible typo in PRINT_KEYWORD_TABLE in keylist.cc
|
||||
that prevented links from being printed correctly.
|
||||
|
||||
Sun Jul 9 17:53:28 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu)
|
||||
|
||||
* Changed the ./tests subdirectory Makefile so that it
|
||||
uses $(CC) instead of gcc.
|
||||
|
||||
Sun Jul 2 12:14:04 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu)
|
||||
|
||||
* Moved comment handling from keylist.c to readline.c. This
|
||||
simplifies the code and reduces the number of malloc calls.
|
||||
|
||||
* Fixed a number of subtle bugs that occurred when -S was
|
||||
combined with various and sundry options.
|
||||
|
||||
* Added the -G option, that makes the generated keyword table
|
||||
a global static variable, rather than hiding it inside
|
||||
the lookup function. This allows other functions to directly
|
||||
access the contents in this table.
|
||||
|
||||
Sat Jul 1 10:12:21 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu)
|
||||
|
||||
* Added the "#" feature, that allows comments inside the keyword
|
||||
list from the input file.
|
||||
|
||||
* Also added the -H option (user can give the name of the hash
|
||||
function) and the -T option (prevents the transfer of the type decl
|
||||
to the output file, which is useful if the type is already defined
|
||||
elsewhere).
|
||||
|
||||
Fri Jun 30 18:22:35 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu)
|
||||
|
||||
* Added Adam de Boor's changes. Created an UNSET_OPTION macro.
|
||||
|
||||
Sat Jun 17 10:56:00 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu)
|
||||
|
||||
* Modified option.h and option.c so that all mixed operations
|
||||
between integers and enumerals are cast correctly to int.
|
||||
This prevents errors in some brain-damaged C compilers.
|
||||
|
||||
Fri Jun 16 14:13:15 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu)
|
||||
|
||||
* Modified the -f (FAST) option. This now takes an argument.
|
||||
The argument corresponds to the number of iterations used
|
||||
to resolve collisions. -f 0 uses the length of the
|
||||
keyword list (which is what -f did before). This makes
|
||||
life much easier when dealing with large keyword files.
|
||||
|
||||
Wed Jun 7 23:07:13 1989 Doug Schmidt (schmidt at zola.ics.uci.edu)
|
||||
|
||||
* Updated to version 1.8 in preparation to release to Doug Lea
|
||||
and FSF.
|
||||
|
||||
* Added the -c (comparison) option. Enabling this
|
||||
will use the strncmp function for string comparisons.
|
||||
The default is to use strcmp.
|
||||
|
||||
Tue Jun 6 16:32:09 1989 Doug Schmidt (schmidt at zola.ics.uci.edu)
|
||||
|
||||
* Fixed another stupid typo in xmalloc.c (XMALLOC). I accidentally
|
||||
left the ANSI-fied prototype in place. This obviously
|
||||
fails on old-style C compilers.
|
||||
|
||||
* Fixed stupid typos in PRINT_SWITCH from the keylist.c. This
|
||||
caused the -D option to produce incorrect output when used
|
||||
in conjunction with -p and -t.
|
||||
|
||||
* Replaced the use of STRCMP with STRNCMP for the generated
|
||||
C output code.
|
||||
|
||||
Fri Jun 2 23:16:01 1989 Doug Schmidt (schmidt at trinite.ics.uci.edu)
|
||||
|
||||
* Added a new function (XMALLOC) and file (xmalloc.c). All
|
||||
calls to MALLOC were replaced by calls to XMALLOC. This
|
||||
will complain when virtual memory runs out (don't laugh,
|
||||
this has happened!)
|
||||
|
||||
Thu Jun 1 21:10:10 1989 Doug Schmidt (schmidt at zola.ics.uci.edu)
|
||||
|
||||
* Fixed a typo in options.c that prevented the -f option
|
||||
from being given on the command-line.
|
||||
|
||||
Wed May 3 17:48:02 1989 Doug Schmidt (schmidt at zola.ics.uci.edu)
|
||||
|
||||
* Updated to version 1.7. This reflects the recent major changes
|
||||
and the new C port.
|
||||
|
||||
* Fixed a typo in perfect.c perfect_destroy that prevented the actual
|
||||
maximum hash table size from being printed.
|
||||
|
||||
* Added support for the -f option. This generates the perfect
|
||||
hash function ``fast.'' It reduces the execution time of
|
||||
gperf, at the cost of minimizing the range of hash values.
|
||||
|
||||
Tue May 2 16:23:29 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu)
|
||||
|
||||
* Enabled the diagnostics dump if the debugging option is enabled.
|
||||
|
||||
* Removed all calls to FREE (silly to do this at program termination).
|
||||
|
||||
* Ported gperf to C. From now on both K&R C and GNU G++ versions
|
||||
will be supported.
|
||||
|
41
contrib/gperf/Makefile
Normal file
41
contrib/gperf/Makefile
Normal file
@ -0,0 +1,41 @@
|
||||
# Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
# written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
#
|
||||
# This file is part of GNU GPERF.
|
||||
#
|
||||
# GNU GPERF is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 1, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU GPERF is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GNU GPERF; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
GPERF = ../src/gperf
|
||||
|
||||
all: gperf tests
|
||||
|
||||
gperf:
|
||||
(cd src; $(MAKE))
|
||||
|
||||
tests: gperf
|
||||
(cd tests; $(MAKE) GPERF=$(GPERF))
|
||||
|
||||
distrib:
|
||||
(cd ..; rm -f cperf.tar.Z; tar cvf cperf.tar cperf; compress cperf.tar; uuencode cperf.tar.Z < cperf.tar.Z > CSHAR)
|
||||
|
||||
clean:
|
||||
(cd src; $(MAKE) clean)
|
||||
(cd tests; $(MAKE) clean)
|
||||
|
||||
realclean:
|
||||
(cd src; $(MAKE) realclean)
|
||||
(cd tests; $(MAKE) clean)
|
||||
-rm -f gperf.info* gperf.?? gperf.??s gperf.log gperf.toc \
|
||||
gperf.*aux *inset.c *out gperf
|
28
contrib/gperf/README
Normal file
28
contrib/gperf/README
Normal file
@ -0,0 +1,28 @@
|
||||
While teaching a data structures course at University of California,
|
||||
Irvine, I developed a program called GPERF that generates perfect hash
|
||||
functions for sets of key words. A perfect hash function is simply:
|
||||
|
||||
A hash function and a data structure that allows
|
||||
recognition of a key word in a set of words using
|
||||
exactly 1 probe into the data structure.
|
||||
|
||||
The gperf.texinfo file explains how the program works, the form of the
|
||||
input, what options are available, and hints on choosing the best
|
||||
options for particular key word sets. The texinfo file is readable
|
||||
both via the GNU emacs `info' command, and is also suitable for
|
||||
typesetting with TeX. The texinfo.tex macros needed to run
|
||||
gperf.texinfo through TeX are available in the GNU GCC release. If
|
||||
you don't have access to these please email me and I'll send them to
|
||||
you (about 75k).
|
||||
|
||||
The enclosed Makefile creates the executable program ``gperf'' and
|
||||
also runs some tests.
|
||||
|
||||
Output from the GPERF program is used to recognize reserved words in
|
||||
the GNU C, GNU C++, and GNU Pascal compilers, as well as with the GNU
|
||||
indent program.
|
||||
|
||||
Happy hacking!
|
||||
|
||||
Douglas C. Schmidt
|
||||
schmidt@ics.uci.edu
|
8
contrib/gperf/README-FIRST
Normal file
8
contrib/gperf/README-FIRST
Normal file
@ -0,0 +1,8 @@
|
||||
Note: Just for clarification, this version of `gperf' is written in
|
||||
portable K&R C. The `gperf' supplied in the top-level libg++ directory on
|
||||
this distribution tape is written in C++. Either will generate output for
|
||||
C or C++, so which one to compile is up to you.
|
||||
|
||||
--Noah Friedman, GNU tape distribution maintainer.
|
||||
friedman@prep.ai.mit.edu
|
||||
December 24, 1991
|
23
contrib/gperf/gperf.1
Normal file
23
contrib/gperf/gperf.1
Normal file
@ -0,0 +1,23 @@
|
||||
.TH GPERF 1 "December 16, 1988
|
||||
.UC 4
|
||||
.SH NAME
|
||||
gperf \- generate a perfect hash function from a key set
|
||||
.SH SYNOPSIS
|
||||
.B gperf
|
||||
[
|
||||
.B \-adghijklnoprsStv
|
||||
] [
|
||||
.I keyfile
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
|
||||
\fIgperf\fP reads a set of ``keys'' from \fIkeyfile\fP (or, by
|
||||
default, from the standard input) and attempts to find a non-minimal
|
||||
perfect hashing function that recognizes a member of the key set in
|
||||
constant, i.e., O(1), time. If such a function is found the program
|
||||
generates a pair of \fIC\fP source code routines that perform the
|
||||
hashing and table lookup. All generated code is directed to the
|
||||
standard output.
|
||||
|
||||
Please refer to the \fIgperf.texinfo\fP file for more information.
|
||||
This file is distributed with \fIgperf\fP release.
|
1129
contrib/gperf/gperf.texinfo
Normal file
1129
contrib/gperf/gperf.texinfo
Normal file
File diff suppressed because it is too large
Load Diff
77
contrib/gperf/src/Makefile
Normal file
77
contrib/gperf/src/Makefile
Normal file
@ -0,0 +1,77 @@
|
||||
# Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
# written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
#
|
||||
# This file is part of GNU GPERF.
|
||||
#
|
||||
# GNU GPERF is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 1, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU GPERF is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GNU GPERF; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
CC = gcc
|
||||
DFLAGS= -DLO_CAL -DGATHER_STATISTICS #-DRLIMIT_STACK
|
||||
OFLAGS= -O -p -g -fstrength-reduce -fomit-frame-pointer -fdelayed-branch -finline-functions # gcc options
|
||||
CFLAGS= $(DFLAGS) $(OFLAGS)
|
||||
OBJS = options.o iterator.o main.o perfect.o keylist.o listnode.o xmalloc.o \
|
||||
hashtable.o boolarray.o readline.o stderr.o version.o getopt.o
|
||||
SOURCES = options.c iterator.c main.c perfect.c keylist.c listnode.c xmalloc.c \
|
||||
hashtable.c boolarray.c readline.c stderr.c version.c getopt.c
|
||||
|
||||
all: gperf
|
||||
|
||||
gperf: $(OBJS)
|
||||
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
|
||||
|
||||
clean:
|
||||
-rm -f *.o core *~ #*#
|
||||
|
||||
realclean: clean
|
||||
-rm -f gperf
|
||||
|
||||
# dependencies
|
||||
# DO NOT DELETE THIS LINE -- mkdep uses it.
|
||||
# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
|
||||
|
||||
boolarray.o: boolarray.c /usr/include/stdio.h boolarray.h prototype.h options.h
|
||||
boolarray.o: /usr/include/stdio.h prototype.h
|
||||
getopt.o: getopt.c /usr/include/stdio.h
|
||||
hashtable.o: hashtable.c /usr/include/stdio.h hashtable.h keylist.h
|
||||
hashtable.o: /usr/include/stdio.h listnode.h prototype.h prototype.h options.h
|
||||
hashtable.o: /usr/include/stdio.h prototype.h
|
||||
iterator.o: iterator.c /usr/include/stdio.h /usr/include/ctype.h iterator.h
|
||||
iterator.o: prototype.h
|
||||
keylist.o: keylist.c /usr/include/assert.h /usr/include/stdio.h options.h
|
||||
keylist.o: /usr/include/stdio.h prototype.h readline.h prototype.h keylist.h
|
||||
keylist.o: /usr/include/stdio.h listnode.h prototype.h hashtable.h keylist.h
|
||||
keylist.o: prototype.h stderr.h prototype.h /usr/include/varargs.h
|
||||
listnode.o: listnode.c /usr/include/stdio.h options.h /usr/include/stdio.h
|
||||
listnode.o: prototype.h listnode.h prototype.h stderr.h prototype.h
|
||||
listnode.o: /usr/include/varargs.h
|
||||
main.o: main.c /usr/include/stdio.h stderr.h prototype.h /usr/include/varargs.h
|
||||
main.o: options.h /usr/include/stdio.h prototype.h perfect.h prototype.h
|
||||
main.o: keylist.h /usr/include/stdio.h listnode.h prototype.h boolarray.h
|
||||
main.o: prototype.h
|
||||
options.o: options.c /usr/include/stdio.h /usr/include/assert.h options.h
|
||||
options.o: /usr/include/stdio.h prototype.h iterator.h prototype.h stderr.h
|
||||
options.o: prototype.h /usr/include/varargs.h
|
||||
perfect.o: perfect.c /usr/include/stdio.h /usr/include/assert.h
|
||||
perfect.o: /usr/include/ctype.h options.h /usr/include/stdio.h prototype.h
|
||||
perfect.o: perfect.h prototype.h keylist.h /usr/include/stdio.h listnode.h
|
||||
perfect.o: prototype.h boolarray.h prototype.h stderr.h prototype.h
|
||||
perfect.o: /usr/include/varargs.h
|
||||
readline.o: readline.c /usr/include/stdio.h readline.h prototype.h
|
||||
stderr.o: stderr.c /usr/include/stdio.h stderr.h prototype.h
|
||||
stderr.o: /usr/include/varargs.h
|
||||
version.o: version.c
|
||||
xmalloc.o: xmalloc.c /usr/include/stdio.h
|
||||
|
||||
# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
|
90
contrib/gperf/src/boolarray.c
Normal file
90
contrib/gperf/src/boolarray.c
Normal file
@ -0,0 +1,90 @@
|
||||
/* Fast lookup table abstraction implemented as a Guilmette Array
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "boolarray.h"
|
||||
#include "options.h"
|
||||
|
||||
/* Locally visible BOOL_ARRAY object. */
|
||||
|
||||
static BOOL_ARRAY bool_array;
|
||||
|
||||
/* Prints out debugging diagnostics. */
|
||||
|
||||
void
|
||||
bool_array_destroy ()
|
||||
{
|
||||
if (OPTION_ENABLED (option, DEBUG))
|
||||
fprintf (stderr, "\ndumping boolean array information\niteration number = %d\nend of array dump\n",
|
||||
bool_array.iteration_number);
|
||||
free ((char *) bool_array.storage_array);
|
||||
}
|
||||
|
||||
void
|
||||
bool_array_init (size)
|
||||
int size;
|
||||
{
|
||||
STORAGE_TYPE *xmalloc ();
|
||||
bool_array.iteration_number = 1;
|
||||
bool_array.size = size;
|
||||
bool_array.storage_array = xmalloc (size * sizeof *bool_array.storage_array);
|
||||
bzero (bool_array.storage_array, size * sizeof *bool_array.storage_array);
|
||||
if (OPTION_ENABLED (option, DEBUG))
|
||||
fprintf (stderr, "\nbool array size = %d, total bytes = %d\n",
|
||||
bool_array.size, bool_array.size * sizeof *bool_array.storage_array);
|
||||
}
|
||||
|
||||
bool
|
||||
lookup (index)
|
||||
int index;
|
||||
{
|
||||
if (bool_array.storage_array[index] == bool_array.iteration_number)
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
bool_array.storage_array[index] = bool_array.iteration_number;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Simple enough to reset, eh?! */
|
||||
|
||||
void
|
||||
bool_array_reset ()
|
||||
{
|
||||
/* If we wrap around it's time to zero things out again! */
|
||||
|
||||
|
||||
if (++bool_array.iteration_number == 0)
|
||||
{
|
||||
if (OPTION_ENABLED (option, DEBUG))
|
||||
{
|
||||
fprintf (stderr, "(re-initializing bool_array)...");
|
||||
fflush (stderr);
|
||||
}
|
||||
bool_array.iteration_number = 1;
|
||||
bzero (bool_array.storage_array, bool_array.size * sizeof *bool_array.storage_array);
|
||||
if (OPTION_ENABLED (option, DEBUG))
|
||||
{
|
||||
fprintf (stderr, "done\n");
|
||||
fflush (stderr);
|
||||
}
|
||||
}
|
||||
}
|
48
contrib/gperf/src/boolarray.h
Normal file
48
contrib/gperf/src/boolarray.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* Simple lookup table abstraction implemented as a Guilmette Array.
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Define and implement a simple boolean array abstraction,
|
||||
uses a Guilmette array implementation to save on initialization time. */
|
||||
|
||||
#ifndef _boolarray_h
|
||||
#define _boolarray_h
|
||||
#include "prototype.h"
|
||||
|
||||
#ifdef LO_CAL
|
||||
/* If we are on a memory diet then we'll only make these use a limited
|
||||
amount of storage space. */
|
||||
typedef unsigned short STORAGE_TYPE;
|
||||
#else
|
||||
typedef int STORAGE_TYPE;
|
||||
#endif
|
||||
typedef struct bool_array
|
||||
{
|
||||
STORAGE_TYPE *storage_array; /* Initialization of the index space. */
|
||||
STORAGE_TYPE iteration_number; /* Keep track of the current iteration. */
|
||||
int size; /* Size of the entire array (dynamically initialized). */
|
||||
} BOOL_ARRAY;
|
||||
|
||||
extern void bool_array_init P ((int size));
|
||||
extern void bool_array_destroy P ((void));
|
||||
extern bool lookup P ((int hash_value));
|
||||
extern void bool_array_reset P ((void));
|
||||
|
||||
#endif /* _boolarray_h */
|
413
contrib/gperf/src/getopt.c
Normal file
413
contrib/gperf/src/getopt.c
Normal file
@ -0,0 +1,413 @@
|
||||
/* Getopt for GNU.
|
||||
Copyright (C) 1987, 1989 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
|
||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||
but it behaves differently for the user, since it allows the user
|
||||
to intersperse the options with the other arguments.
|
||||
|
||||
As `getopt' works, it permutes the elements of `argv' so that,
|
||||
when it is done, all the options precede everything else. Thus
|
||||
all application programs are extended to handle flexible argument order.
|
||||
|
||||
Setting the environment variable _POSIX_OPTION_ORDER disables permutation.
|
||||
Then the behavior is completely standard.
|
||||
|
||||
GNU application programs can use a third alternative mode in which
|
||||
they can distinguish the relative order of options and other arguments. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef sparc
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#ifdef USG
|
||||
#define bcopy(s, d, l) memcpy((d), (s), (l))
|
||||
#endif
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
char *optarg = 0;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
int optind = 0;
|
||||
|
||||
/* The next char to be scanned in the option-element
|
||||
in which the last option character we returned was found.
|
||||
This allows us to pick up the scan where we left off.
|
||||
|
||||
If this is zero, or a null string, it means resume the scan
|
||||
by advancing to the next ARGV-element. */
|
||||
|
||||
static char *nextchar;
|
||||
|
||||
/* Callers store zero here to inhibit the error message
|
||||
for unrecognized options. */
|
||||
|
||||
int opterr = 1;
|
||||
|
||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
||||
|
||||
UNSPECIFIED means the caller did not specify anything;
|
||||
the default is then REQUIRE_ORDER if the environment variable
|
||||
_OPTIONS_FIRST is defined, PERMUTE otherwise.
|
||||
|
||||
REQUIRE_ORDER means don't recognize them as options.
|
||||
Stop option processing when the first non-option is seen.
|
||||
This is what Unix does.
|
||||
|
||||
PERMUTE is the default. We permute the contents of `argv' as we scan,
|
||||
so that eventually all the options are at the end. This allows options
|
||||
to be given in any order, even with programs that were not written to
|
||||
expect this.
|
||||
|
||||
RETURN_IN_ORDER is an option available to programs that were written
|
||||
to expect options and other ARGV-elements in any order and that care about
|
||||
the ordering of the two. We describe each non-option ARGV-element
|
||||
as if it were the argument of an option with character code zero.
|
||||
Using `-' as the first character of the list of option characters
|
||||
requests this mode of operation.
|
||||
|
||||
The special argument `--' forces an end of option-scanning regardless
|
||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
|
||||
|
||||
static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering;
|
||||
|
||||
/* Handle permutation of arguments. */
|
||||
|
||||
/* Describe the part of ARGV that contains non-options that have
|
||||
been skipped. `first_nonopt' is the index in ARGV of the first of them;
|
||||
`last_nonopt' is the index after the last of them. */
|
||||
|
||||
static int first_nonopt;
|
||||
static int last_nonopt;
|
||||
|
||||
/* Exchange two adjacent subsequences of ARGV.
|
||||
One subsequence is elements [first_nonopt,last_nonopt)
|
||||
which contains all the non-options that have been skipped so far.
|
||||
The other is elements [last_nonopt,optind), which contains all
|
||||
the options processed since those non-options were skipped.
|
||||
|
||||
`first_nonopt' and `last_nonopt' are relocated so that they describe
|
||||
the new indices of the non-options in ARGV after they are moved. */
|
||||
|
||||
static void
|
||||
exchange (argv)
|
||||
char **argv;
|
||||
{
|
||||
int nonopts_size
|
||||
= (last_nonopt - first_nonopt) * sizeof (char *);
|
||||
char **temp = (char **) alloca (nonopts_size);
|
||||
|
||||
/* Interchange the two blocks of data in argv. */
|
||||
|
||||
bcopy (&argv[first_nonopt], temp, nonopts_size);
|
||||
bcopy (&argv[last_nonopt], &argv[first_nonopt],
|
||||
(optind - last_nonopt) * sizeof (char *));
|
||||
bcopy (temp, &argv[first_nonopt + optind - last_nonopt],
|
||||
nonopts_size);
|
||||
|
||||
/* Update records for the slots the non-options now occupy. */
|
||||
|
||||
first_nonopt += (optind - last_nonopt);
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||
given in OPTSTRING.
|
||||
|
||||
If an element of ARGV starts with '-', and is not exactly "-" or "--",
|
||||
then it is an option element. The characters of this element
|
||||
(aside from the initial '-') are option characters. If `getopt'
|
||||
is called repeatedly, it returns successively each of theoption characters
|
||||
from each of the option elements.
|
||||
|
||||
If `getopt' finds another option character, it returns that character,
|
||||
updating `optind' and `nextchar' so that the next call to `getopt' can
|
||||
resume the scan with the following option character or ARGV-element.
|
||||
|
||||
If there are no more option characters, `getopt' returns `EOF'.
|
||||
Then `optind' is the index in ARGV of the first ARGV-element
|
||||
that is not an option. (The ARGV-elements have been permuted
|
||||
so that those that are not options now come last.)
|
||||
|
||||
OPTSTRING is a string containing the legitimate option characters.
|
||||
A colon in OPTSTRING means that the previous character is an option
|
||||
that wants an argument. The argument is taken from the rest of the
|
||||
current ARGV-element, or from the following ARGV-element,
|
||||
and returned in `optarg'.
|
||||
|
||||
If an option character is seen that is not listed in OPTSTRING,
|
||||
return '?' after printing an error message. If you set `opterr' to
|
||||
zero, the error message is suppressed but we still return '?'.
|
||||
|
||||
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
|
||||
so the following text in the same ARGV-element, or the text of the following
|
||||
ARGV-element, is returned in `optarg. Two colons mean an option that
|
||||
wants an optional arg; if there is text in the current ARGV-element,
|
||||
it is returned in `optarg'.
|
||||
|
||||
If OPTSTRING starts with `-', it requests a different method of handling the
|
||||
non-option ARGV-elements. See the comments about RETURN_IN_ORDER, above. */
|
||||
|
||||
int
|
||||
getopt (argc, argv, optstring)
|
||||
int argc;
|
||||
char **argv;
|
||||
char *optstring;
|
||||
{
|
||||
/* Initialize the internal data when the first call is made.
|
||||
Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
|
||||
if (optind == 0)
|
||||
{
|
||||
first_nonopt = last_nonopt = optind = 1;
|
||||
|
||||
nextchar = 0;
|
||||
|
||||
/* Determine how to handle the ordering of options and nonoptions. */
|
||||
|
||||
if (optstring[0] == '-')
|
||||
ordering = RETURN_IN_ORDER;
|
||||
else if (getenv ("_POSIX_OPTION_ORDER") != 0)
|
||||
ordering = REQUIRE_ORDER;
|
||||
else
|
||||
ordering = PERMUTE;
|
||||
}
|
||||
|
||||
if (nextchar == 0 || *nextchar == 0)
|
||||
{
|
||||
if (ordering == PERMUTE)
|
||||
{
|
||||
/* If we have just processed some options following some non-options,
|
||||
exchange them so that the options come first. */
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange (argv);
|
||||
else if (last_nonopt != optind)
|
||||
first_nonopt = optind;
|
||||
|
||||
/* Now skip any additional non-options
|
||||
and extend the range of non-options previously skipped. */
|
||||
|
||||
while (optind < argc
|
||||
&& (argv[optind][0] != '-'
|
||||
|| argv[optind][1] == 0))
|
||||
optind++;
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* Special ARGV-element `--' means premature end of options.
|
||||
Skip it like a null option,
|
||||
then exchange with previous non-options as if it were an option,
|
||||
then skip everything else like a non-option. */
|
||||
|
||||
if (optind != argc && !strcmp (argv[optind], "--"))
|
||||
{
|
||||
optind++;
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange (argv);
|
||||
else if (first_nonopt == last_nonopt)
|
||||
first_nonopt = optind;
|
||||
last_nonopt = argc;
|
||||
|
||||
optind = argc;
|
||||
}
|
||||
|
||||
/* If we have done all the ARGV-elements, stop the scan
|
||||
and back over any non-options that we skipped and permuted. */
|
||||
|
||||
if (optind == argc)
|
||||
{
|
||||
/* Set the next-arg-index to point at the non-options
|
||||
that we previously skipped, so the caller will digest them. */
|
||||
if (first_nonopt != last_nonopt)
|
||||
optind = first_nonopt;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* If we have come to a non-option and did not permute it,
|
||||
either stop the scan or describe it to the caller and pass it by. */
|
||||
|
||||
if (argv[optind][0] != '-' || argv[optind][1] == 0)
|
||||
{
|
||||
if (ordering == REQUIRE_ORDER)
|
||||
return EOF;
|
||||
optarg = argv[optind++];
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We have found another option-ARGV-element.
|
||||
Start decoding its characters. */
|
||||
|
||||
nextchar = argv[optind] + 1;
|
||||
}
|
||||
|
||||
/* Look at and handle the next option-character. */
|
||||
|
||||
{
|
||||
char c = *nextchar++;
|
||||
char *temp = (char *) index (optstring, c);
|
||||
|
||||
/* Increment `optind' when we start to process its last character. */
|
||||
if (*nextchar == 0)
|
||||
optind++;
|
||||
|
||||
if (temp == 0 || c == ':')
|
||||
{
|
||||
if (opterr != 0)
|
||||
{
|
||||
if (c < 040 || c >= 0177)
|
||||
fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
|
||||
argv[0], c);
|
||||
else
|
||||
fprintf (stderr, "%s: unrecognized option `-%c'\n",
|
||||
argv[0], c);
|
||||
}
|
||||
return '?';
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (temp[2] == ':')
|
||||
{
|
||||
/* This is an option that accepts an argument optionally. */
|
||||
if (*nextchar != 0)
|
||||
{
|
||||
optarg = nextchar;
|
||||
optind++;
|
||||
}
|
||||
else
|
||||
optarg = 0;
|
||||
nextchar = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
if (*nextchar != 0)
|
||||
{
|
||||
optarg = nextchar;
|
||||
/* If we end this ARGV-element by taking the rest as an arg,
|
||||
we must advance to the next element now. */
|
||||
optind++;
|
||||
}
|
||||
else if (optind == argc)
|
||||
{
|
||||
if (opterr != 0)
|
||||
fprintf (stderr, "%s: no argument for `-%c' option\n",
|
||||
argv[0], c);
|
||||
c = '?';
|
||||
}
|
||||
else
|
||||
/* We already incremented `optind' once;
|
||||
increment it again when taking next ARGV-elt as argument. */
|
||||
optarg = argv[optind++];
|
||||
nextchar = 0;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/* Compile with -DTEST to make an executable for use in testing
|
||||
the above definition of `getopt'. */
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
char c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind;
|
||||
if ((c = getopt (argc, argv, "abc:d:0123456789")) == EOF)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
22
contrib/gperf/src/gperf-to-do
Normal file
22
contrib/gperf/src/gperf-to-do
Normal file
@ -0,0 +1,22 @@
|
||||
1. provide output diagnostics that explain how many input keys total,
|
||||
how many after dealing with static links, and finally, after the
|
||||
algorithm is complete, how many dynamic duplicates do we now
|
||||
have.
|
||||
2. fix up GATHER_STATISTICS for all instrumentation.
|
||||
3. Useful idea:
|
||||
|
||||
a. Generate the wordlist as a contiguous block of keywords, as before.
|
||||
This wordlist *must* be sorted by hash value.
|
||||
|
||||
b. generate the lookup_array, which are an array of signed {chars,shorts,ints},
|
||||
which ever allows full coverage of the wordlist dimensions. If the
|
||||
value v, where v = lookup_array[hash(str,len)], is >= 0, then we
|
||||
simply use this result as a direct access into wordlist to snag
|
||||
the keyword for comparison.
|
||||
|
||||
c. Otherwise, if v is < 0 this is an indication that we'll need to
|
||||
search through some number of duplicates hash values. Using a
|
||||
hash linking scheme we'd then index into a duplicate_address
|
||||
table that would provide the starting index and total length of
|
||||
the duplicate entries to consider sequentially.
|
||||
|
132
contrib/gperf/src/hashtable.c
Normal file
132
contrib/gperf/src/hashtable.c
Normal file
@ -0,0 +1,132 @@
|
||||
/* Hash table for checking keyword links. Implemented using double hashing.
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "hashtable.h"
|
||||
#include "options.h"
|
||||
|
||||
#ifdef GATHER_STATISTICS
|
||||
/* Find out how well our double hashing is working! */
|
||||
static collisions = 0;
|
||||
#endif
|
||||
|
||||
/* Locally visible hash table. */
|
||||
static HASH_TABLE hash_table;
|
||||
|
||||
/* Basically the algorithm from the Dragon book. */
|
||||
|
||||
static unsigned
|
||||
hash_pjw (str)
|
||||
char *str;
|
||||
{
|
||||
char *temp;
|
||||
unsigned g, h = 0;
|
||||
|
||||
for (temp = str; *temp; temp++)
|
||||
{
|
||||
h = (h << 4) + (*temp * 13);
|
||||
if (g = h & 0xf0000000)
|
||||
{
|
||||
h ^= (g >> 24);
|
||||
h ^= g;
|
||||
}
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
/* The size of the hash table is always the smallest power of 2 >= the size
|
||||
indicated by the user. This allows several optimizations, including
|
||||
the use of double hashing and elimination of the mod instruction.
|
||||
Note that the size had better be larger than the number of items
|
||||
in the hash table, else there's trouble!!! Note that the memory
|
||||
for the hash table is allocated *outside* the intialization routine.
|
||||
This compromises information hiding somewhat, but greatly reduces
|
||||
memory fragmentation, since we can now use alloca! */
|
||||
|
||||
void
|
||||
hash_table_init (table, s)
|
||||
LIST_NODE **table;
|
||||
int s;
|
||||
{
|
||||
hash_table.size = s;
|
||||
hash_table.table = table;
|
||||
bzero ((char *) hash_table.table, hash_table.size * sizeof *hash_table.table);
|
||||
}
|
||||
|
||||
/* Frees the dynamically allocated table. Note that since we don't
|
||||
really need this space anymore, and since it is potentially quite
|
||||
big it is best to return it when we are done. */
|
||||
|
||||
void
|
||||
hash_table_destroy ()
|
||||
{
|
||||
if (OPTION_ENABLED (option, DEBUG))
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf (stderr, "\ndumping the hash table\ntotal elements = %d, bytes = %d\n",
|
||||
hash_table.size, hash_table.size * sizeof *hash_table.table);
|
||||
|
||||
for (i = hash_table.size - 1; i >= 0; i--)
|
||||
if (hash_table.table[i])
|
||||
fprintf (stderr, "location[%d] has charset \"%s\" and keyword \"%s\"\n",
|
||||
i, hash_table.table[i]->char_set, hash_table.table[i]->key);
|
||||
|
||||
#ifdef GATHER_STATISTICS
|
||||
fprintf (stderr, "\ntotal collisions during hashing = %d\n", collisions);
|
||||
#endif
|
||||
fprintf (stderr, "end dumping hash table\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* If the ITEM is already in the hash table return the item found
|
||||
in the table. Otherwise inserts the ITEM, and returns FALSE.
|
||||
Uses double hashing. */
|
||||
|
||||
LIST_NODE *
|
||||
retrieve (item, ignore_length)
|
||||
LIST_NODE *item;
|
||||
int ignore_length;
|
||||
{
|
||||
unsigned hash_val = hash_pjw (item->char_set);
|
||||
int probe = hash_val & hash_table.size - 1;
|
||||
int increment = (hash_val ^ item->length | 1) & hash_table.size - 1;
|
||||
|
||||
while (hash_table.table[probe]
|
||||
&& (strcmp (hash_table.table[probe]->char_set, item->char_set)
|
||||
|| (!ignore_length && hash_table.table[probe]->length != item->length)))
|
||||
{
|
||||
#ifdef GATHER_STATISTICS
|
||||
collisions++;
|
||||
#endif
|
||||
probe = probe + increment & hash_table.size - 1;
|
||||
}
|
||||
|
||||
if (hash_table.table[probe])
|
||||
return hash_table.table[probe];
|
||||
else
|
||||
{
|
||||
hash_table.table[probe] = item;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
37
contrib/gperf/src/hashtable.h
Normal file
37
contrib/gperf/src/hashtable.h
Normal file
@ -0,0 +1,37 @@
|
||||
/* Hash table used to check for duplicate keyword entries.
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _hashtable_h
|
||||
#define _hashtable_h
|
||||
#include "keylist.h"
|
||||
#include "prototype.h"
|
||||
|
||||
typedef struct hash_table
|
||||
{
|
||||
LIST_NODE **table; /* Vector of pointers to linked lists of List_Node's. */
|
||||
int size; /* Size of the vector. */
|
||||
} HASH_TABLE;
|
||||
|
||||
extern void hash_table_init P ((LIST_NODE **table, int size));
|
||||
extern void hash_table_destroy P ((void));
|
||||
extern LIST_NODE *retrieve P ((LIST_NODE *item, int ignore_length));
|
||||
|
||||
#endif /* _hashtable_h */
|
106
contrib/gperf/src/iterator.c
Normal file
106
contrib/gperf/src/iterator.c
Normal file
@ -0,0 +1,106 @@
|
||||
/* Provides an Iterator for keyword characters.
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "iterator.h"
|
||||
|
||||
/* Locally visible ITERATOR object. */
|
||||
|
||||
ITERATOR iterator;
|
||||
|
||||
/* Constructor for ITERATOR. */
|
||||
|
||||
void
|
||||
iterator_init (s, lo, hi, word_end, bad_val, key_end)
|
||||
char *s;
|
||||
int lo;
|
||||
int hi;
|
||||
int word_end;
|
||||
int bad_val;
|
||||
int key_end;
|
||||
{
|
||||
iterator.end = key_end;
|
||||
iterator.error_value = bad_val;
|
||||
iterator.end_word = word_end;
|
||||
iterator.str = s;
|
||||
iterator.hi_bound = hi;
|
||||
iterator.lo_bound = lo;
|
||||
}
|
||||
|
||||
/* Define several useful macros to clarify subsequent code. */
|
||||
#define ISPOSDIGIT(X) ((X)<='9'&&(X)>'0')
|
||||
#define TODIGIT(X) ((X)-'0')
|
||||
|
||||
/* Provide an Iterator, returning the ``next'' value from
|
||||
the list of valid values given in the constructor. */
|
||||
|
||||
int
|
||||
next ()
|
||||
{
|
||||
/* Variables to record the Iterator's status when handling ranges, e.g., 3-12. */
|
||||
|
||||
static int size;
|
||||
static int curr_value;
|
||||
static int upper_bound;
|
||||
|
||||
if (size)
|
||||
{
|
||||
if (++curr_value >= upper_bound)
|
||||
size = 0;
|
||||
return curr_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*iterator.str)
|
||||
{
|
||||
if (*iterator.str == ',')
|
||||
iterator.str++;
|
||||
else if (*iterator.str == '$')
|
||||
{
|
||||
iterator.str++;
|
||||
return iterator.end_word;
|
||||
}
|
||||
else if (ISPOSDIGIT (*iterator.str))
|
||||
{
|
||||
|
||||
for (curr_value = 0; isdigit (*iterator.str); iterator.str++)
|
||||
curr_value = curr_value * 10 + *iterator.str - '0';
|
||||
|
||||
if (*iterator.str == '-')
|
||||
{
|
||||
|
||||
for (size = 1, upper_bound = 0;
|
||||
isdigit (*++iterator.str);
|
||||
upper_bound = upper_bound * 10 + *iterator.str - '0');
|
||||
|
||||
if (upper_bound <= curr_value || upper_bound > iterator.hi_bound)
|
||||
return iterator.error_value;
|
||||
}
|
||||
return curr_value >= iterator.lo_bound && curr_value <= iterator.hi_bound
|
||||
? curr_value : iterator.error_value;
|
||||
}
|
||||
else
|
||||
return iterator.error_value;
|
||||
}
|
||||
|
||||
return iterator.end;
|
||||
}
|
||||
}
|
47
contrib/gperf/src/iterator.h
Normal file
47
contrib/gperf/src/iterator.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* Provides an Iterator for keyword characters.
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Provides an Iterator that expands and decodes a control string containing digits
|
||||
and ranges, returning an integer every time the generator function is called.
|
||||
This is used to decode the user's key position requests. For example:
|
||||
"-k 1,2,5-10,$" will return 1, 2, 5, 6, 7, 8, 9, 10, and 0 ( representing
|
||||
the abstract ``last character of the key'' on successive calls to the
|
||||
member function operator ().
|
||||
No errors are handled in these routines, they are passed back to the
|
||||
calling routines via a user-supplied Error_Value */
|
||||
|
||||
#ifndef _iterator_h
|
||||
#define _iterator_h
|
||||
#include "prototype.h"
|
||||
|
||||
typedef struct iterator
|
||||
{
|
||||
char *str; /* A pointer to the string provided by the user. */
|
||||
int end; /* Value returned after last key is processed. */
|
||||
int end_word; /* A value marking the abstract ``end of word'' ( usually '$'). */
|
||||
int error_value; /* Error value returned when input is syntactically erroneous. */
|
||||
int hi_bound; /* Greatest possible value, inclusive. */
|
||||
int lo_bound; /* Smallest possible value, inclusive. */
|
||||
} ITERATOR;
|
||||
|
||||
extern void iterator_init P ((char *s, int lo, int hi, int word_end, int bad_val, int key_end));
|
||||
extern int next P ((void));
|
||||
#endif /* _iterator_h */
|
1033
contrib/gperf/src/keylist.c
Normal file
1033
contrib/gperf/src/keylist.c
Normal file
File diff suppressed because it is too large
Load Diff
54
contrib/gperf/src/keylist.h
Normal file
54
contrib/gperf/src/keylist.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* Data and function member declarations for the keyword list class.
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* The key word list is a useful abstraction that keeps track of
|
||||
various pieces of information that enable that fast generation
|
||||
of the Perfect.hash function. A Key_List is a singly-linked
|
||||
list of List_Nodes. */
|
||||
|
||||
#ifndef _keylist_h
|
||||
#define _keylist_h
|
||||
#include <stdio.h>
|
||||
#include "listnode.h"
|
||||
|
||||
typedef struct key_list
|
||||
{
|
||||
LIST_NODE *head; /* Points to the head of the linked list. */
|
||||
char *array_type; /* Pointer to the type for word list. */
|
||||
char *return_type; /* Pointer to return type for lookup function. */
|
||||
char *struct_tag; /* Shorthand for user-defined struct tag type. */
|
||||
char *include_src; /* C source code to be included verbatim. */
|
||||
int list_len; /* Length of head's Key_List, not counting duplicates. */
|
||||
int total_keys; /* Total number of keys, counting duplicates. */
|
||||
int max_key_len; /* Maximum length of the longest keyword. */
|
||||
int min_key_len; /* Minimum length of the shortest keyword. */
|
||||
bool occurrence_sort; /* True if sorting by occurrence. */
|
||||
bool hash_sort; /* True if sorting by hash value. */
|
||||
bool additional_code; /* True if any additional C code is included. */
|
||||
} KEY_LIST;
|
||||
|
||||
extern void key_list_init P ((void));
|
||||
extern void key_list_destroy P ((void));
|
||||
extern void print_output P ((void));
|
||||
extern int keyword_list_length P ((void));
|
||||
extern int max_key_length P ((void));
|
||||
extern KEY_LIST key_list;
|
||||
#endif /* _keylist_h */
|
111
contrib/gperf/src/listnode.c
Normal file
111
contrib/gperf/src/listnode.c
Normal file
@ -0,0 +1,111 @@
|
||||
/* Creates and initializes a new list node.
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "options.h"
|
||||
#include "listnode.h"
|
||||
#include "stderr.h"
|
||||
|
||||
/* See comments in perfect.cc. */
|
||||
extern int occurrences[ALPHABET_SIZE];
|
||||
|
||||
/* Sorts the key set alphabetically to speed up subsequent operations.
|
||||
Uses insertion sort since the set is probably quite small. */
|
||||
|
||||
static void
|
||||
set_sort (base, len)
|
||||
char *base;
|
||||
int len;
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0, j = len - 1; i < j; i++)
|
||||
{
|
||||
char curr, tmp;
|
||||
|
||||
for (curr = i + 1, tmp = base[curr]; curr > 0 && tmp < base[curr-1]; curr--)
|
||||
base[curr] = base[curr - 1];
|
||||
|
||||
base[curr] = tmp;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Initializes a List_Node. This requires obtaining memory for the KEY_SET
|
||||
initializing them using the information stored in the
|
||||
KEY_POSITIONS array in Options, and checking for simple errors.
|
||||
It's important to note that KEY and REST are both pointers to
|
||||
the different offsets into the same block of dynamic memory pointed to
|
||||
by parameter K. The data member REST is used to store any additional fields
|
||||
of the input file (it is set to the "" string if Option[TYPE] is not enabled).
|
||||
This is useful if the user wishes to incorporate a lookup structure,
|
||||
rather than just an array of keys. */
|
||||
|
||||
LIST_NODE *
|
||||
make_list_node (k, len)
|
||||
char *k;
|
||||
int len;
|
||||
{
|
||||
LIST_NODE *buffered_malloc ();
|
||||
int char_set_size = OPTION_ENABLED (option, ALLCHARS) ? len : GET_CHARSET_SIZE (option) + 1;
|
||||
LIST_NODE *temp = buffered_malloc (sizeof (LIST_NODE) + char_set_size);
|
||||
char *ptr = temp->char_set;
|
||||
|
||||
k[len] = '\0'; /* Null terminate KEY to separate it from REST. */
|
||||
temp->key = k;
|
||||
temp->next = 0;
|
||||
temp->index = 0;
|
||||
temp->length = len;
|
||||
temp->link = 0;
|
||||
temp->rest = OPTION_ENABLED (option, TYPE) ? k + len + 1 : "";
|
||||
|
||||
if (OPTION_ENABLED (option, ALLCHARS)) /* Use all the character position in the KEY. */
|
||||
|
||||
for (; *k; k++, ptr++)
|
||||
++occurrences[*ptr = *k];
|
||||
|
||||
else /* Only use those character positions specified by the user. */
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Iterate thru the list of key_positions, initializing occurrences table
|
||||
and temp->char_set (via char * pointer ptr). */
|
||||
|
||||
for(RESET (option); (i = GET (option)) != EOS; )
|
||||
{
|
||||
if (i == WORD_END) /* Special notation for last KEY position, i.e. '$'. */
|
||||
*ptr = temp->key[len - 1];
|
||||
else if (i <= len) /* Within range of KEY length, so we'll keep it. */
|
||||
*ptr = temp->key[i - 1];
|
||||
else /* Out of range of KEY length, so we'll just skip it. */
|
||||
continue;
|
||||
++occurrences[*ptr++];
|
||||
}
|
||||
|
||||
if (ptr == temp->char_set) /* Didn't get any hits, i.e., no usable positions. */
|
||||
report_error ("can't hash keyword %s with chosen key positions\n%a", temp->key);
|
||||
}
|
||||
|
||||
*ptr = '\0'; /* Terminate this bastard.... */
|
||||
/* Sort the KEY_SET items alphabetically. */
|
||||
set_sort (temp->char_set, ptr - temp->char_set);
|
||||
|
||||
return temp;
|
||||
}
|
43
contrib/gperf/src/listnode.h
Normal file
43
contrib/gperf/src/listnode.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* Data and function members for defining values and operations of a list node.
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _listnode_h
|
||||
#define _listnode_h
|
||||
#include "prototype.h"
|
||||
|
||||
#define ALPHABET_SIZE 128
|
||||
|
||||
typedef struct list_node
|
||||
{
|
||||
struct list_node *link; /* TRUE if key has an identical KEY_SET as another key. */
|
||||
struct list_node *next; /* Points to next element on the list. */
|
||||
int length; /* Length of the key. */
|
||||
int hash_value; /* Hash value for the key. */
|
||||
int occurrence; /* A metric for frequency of key set occurrences. */
|
||||
int index; /* Position of this node relative to other nodes. */
|
||||
char *key; /* Key string. */
|
||||
char *rest; /* Additional information for building hash function. */
|
||||
char char_set[1]; /* Set of characters to hash, specified by user. */
|
||||
} LIST_NODE;
|
||||
|
||||
extern LIST_NODE *make_list_node P ((char *k, int len));
|
||||
|
||||
#endif _listnode_h
|
96
contrib/gperf/src/main.c
Normal file
96
contrib/gperf/src/main.c
Normal file
@ -0,0 +1,96 @@
|
||||
/* Driver program for the Perfect hash function generator.
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Simple driver program for the Perfect.hash function generator.
|
||||
Most of the hard work is done in class Perfect and its class methods. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include "stderr.h"
|
||||
#include "options.h"
|
||||
#include "perfect.h"
|
||||
|
||||
/* Calls the appropriate intialization routines for each
|
||||
ADT. Note that certain initialization routines require
|
||||
initialization *after* certain values are computed. Therefore,
|
||||
they cannot be called here. */
|
||||
|
||||
static void
|
||||
init_all (argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
#ifdef RLIMIT_STACK
|
||||
/* Get rid of any avoidable limit on stack size. */
|
||||
{
|
||||
struct rlimit rlim;
|
||||
|
||||
/* Set the stack limit huge so that alloca does not fail. */
|
||||
getrlimit (RLIMIT_STACK, &rlim);
|
||||
rlim.rlim_cur = rlim.rlim_max;
|
||||
setrlimit (RLIMIT_STACK, &rlim);
|
||||
}
|
||||
#endif /* RLIMIT_STACK */
|
||||
|
||||
options_init (argc, argv);
|
||||
key_list_init ();
|
||||
perfect_init ();
|
||||
}
|
||||
|
||||
/* Calls appropriate destruction routines for each ADT. These
|
||||
routines print diagnostics if the debugging option is enabled. */
|
||||
|
||||
static void
|
||||
destroy_all ()
|
||||
{
|
||||
options_destroy ();
|
||||
key_list_destroy ();
|
||||
perfect_destroy ();
|
||||
}
|
||||
|
||||
/* Driver for perfect hash function generation. */
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
struct tm *tm;
|
||||
time_t clock;
|
||||
int status;
|
||||
|
||||
time (&clock);
|
||||
tm = localtime (&clock);
|
||||
|
||||
fprintf (stderr, "/* starting time is %d:%d:%d */\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
/* Sets the options. */
|
||||
init_all (argc, argv);
|
||||
|
||||
/* Generates the perfect hash table.
|
||||
Also prints generated code neatly to the output. */
|
||||
status = perfect_generate ();
|
||||
destroy_all ();
|
||||
|
||||
time (&clock);
|
||||
tm = localtime (&clock);
|
||||
fprintf (stderr, "/* ending time is %d:%d:%d */\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
return status;
|
||||
}
|
444
contrib/gperf/src/options.c
Normal file
444
contrib/gperf/src/options.c
Normal file
@ -0,0 +1,444 @@
|
||||
/* Handles parsing the Options provided to the user.
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "options.h"
|
||||
#include "iterator.h"
|
||||
#include "stderr.h"
|
||||
|
||||
/* Current program version. */
|
||||
extern char *version_string;
|
||||
|
||||
/* Size to jump on a collision. */
|
||||
#define DEFAULT_JUMP_VALUE 5
|
||||
|
||||
/* Default name for generated lookup function. */
|
||||
#define DEFAULT_NAME "in_word_set"
|
||||
|
||||
/* Default name for the key component. */
|
||||
#define DEFAULT_KEY "name"
|
||||
|
||||
/* Default name for generated hash function. */
|
||||
#define DEFAULT_HASH_NAME "hash"
|
||||
|
||||
/* Globally visible OPTIONS object. */
|
||||
OPTIONS option;
|
||||
|
||||
/* Default delimiters that separate keywords from their attributes. */
|
||||
#define DEFAULT_DELIMITERS ",\n"
|
||||
|
||||
/* Prints program usage to standard error stream. */
|
||||
|
||||
void
|
||||
usage ()
|
||||
{
|
||||
report_error ("usage: %n [-acCdDef[num]gGhH<hashname>i<init>jk<keys>\
|
||||
K<keyname>lnN<name>oprs<size>S<switches>tTv].\n(type %n -h for help)\n");
|
||||
}
|
||||
|
||||
/* Sorts the key positions *IN REVERSE ORDER!!*
|
||||
This makes further routines more efficient. Especially when generating code.
|
||||
Uses a simple Insertion Sort since the set is probably ordered.
|
||||
Returns 1 if there are no duplicates, 0 otherwise. */
|
||||
|
||||
static int
|
||||
key_sort (base, len)
|
||||
char *base;
|
||||
int len;
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0, j = len - 1; i < j; i++)
|
||||
{
|
||||
int curr, tmp;
|
||||
|
||||
for (curr = i + 1,tmp = base[curr]; curr > 0 && tmp >= base[curr - 1]; curr--)
|
||||
if ((base[curr] = base[curr - 1]) == tmp) /* oh no, a duplicate!!! */
|
||||
return 0;
|
||||
|
||||
base[curr] = tmp;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Dumps option status when debug is set. */
|
||||
|
||||
void
|
||||
options_destroy ()
|
||||
{
|
||||
if (OPTION_ENABLED (option, DEBUG))
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
fprintf (stderr, "\ndumping Options:\nDEBUG is.......: %s\nORDER is.......: %s\
|
||||
\nANSI is........: %s\nTYPE is........: %s\nGNU is.........: %s\nRANDOM is......: %s\
|
||||
\nDEFAULTCHARS is: %s\nSWITCH is......: %s\nPOINTER is.....: %s\nNOLENGTH is....: %s\
|
||||
\nLENTABLE is....: %s\nDUP is.........: %s\nCOMP is........: %s\nFAST is........: %s\
|
||||
\nNOTYPE is......: %s\nGLOBAL is......: %s\nCONST is.......: %s\niterations = %d\
|
||||
\nlookup function name = %s\nhash function name = %s\nkey name = %s\
|
||||
\njump value = %d\nmax associcated value = %d\ninitial associated value = %d\
|
||||
\ndelimiters = %s\nnumber of switch statements = %d\napproximate switch statement size = %d\n",
|
||||
OPTION_ENABLED (option, DEBUG) ? "enabled" : "disabled",
|
||||
OPTION_ENABLED (option, ORDER) ? "enabled" : "disabled",
|
||||
OPTION_ENABLED (option, ANSI) ? "enabled" : "disabled",
|
||||
OPTION_ENABLED (option, TYPE) ? "enabled" : "disabled",
|
||||
OPTION_ENABLED (option, GNU) ? "enabled" : "disabled",
|
||||
OPTION_ENABLED (option, RANDOM) ? "enabled" : "disabled",
|
||||
OPTION_ENABLED (option, DEFAULTCHARS) ? "enabled" : "disabled",
|
||||
OPTION_ENABLED (option, SWITCH) ? "enabled" : "disabled",
|
||||
OPTION_ENABLED (option, POINTER) ? "enabled" : "disabled",
|
||||
OPTION_ENABLED (option, NOLENGTH) ? "enabled" : "disabled",
|
||||
OPTION_ENABLED (option, LENTABLE) ? "enabled" : "disabled",
|
||||
OPTION_ENABLED (option, DUP) ? "enabled" : "disabled",
|
||||
OPTION_ENABLED (option, COMP) ? "enabled" : "disabled",
|
||||
OPTION_ENABLED (option, FAST) ? "enabled" : "disabled",
|
||||
OPTION_ENABLED (option, NOTYPE) ? "enabled" : "disabled",
|
||||
OPTION_ENABLED (option, GLOBAL) ? "enabled" : "disabled",
|
||||
OPTION_ENABLED (option, CONST) ? "enabled" : "disabled",
|
||||
option.iterations, option.function_name, option.hash_name,
|
||||
option.key_name, option.jump, option.size - 1,
|
||||
option.initial_asso_value, option.delimiters, option.total_switches,
|
||||
keyword_list_length () / option.total_switches);
|
||||
|
||||
if (OPTION_ENABLED (option, ALLCHARS))
|
||||
fprintf (stderr, "all characters are used in the hash function\n");
|
||||
fprintf (stderr, "maximum charset size = %d\nkey positions are: \n",
|
||||
option.total_charset_size);
|
||||
|
||||
for (ptr = option.key_positions; *ptr != EOS; ptr++)
|
||||
if (*ptr == WORD_END)
|
||||
fprintf (stderr, "$\n");
|
||||
else
|
||||
fprintf (stderr, "%d\n", *ptr);
|
||||
|
||||
fprintf (stderr, "finished dumping Options\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Parses the command line Options and sets appropriate flags in option.option_word. */
|
||||
|
||||
void
|
||||
options_init (argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
int option_char;
|
||||
|
||||
option.key_positions[0] = WORD_START;
|
||||
option.key_positions[1] = WORD_END;
|
||||
option.key_positions[2] = EOS;
|
||||
option.total_charset_size = 2;
|
||||
option.jump = DEFAULT_JUMP_VALUE;
|
||||
option.option_word = (int) DEFAULTCHARS;
|
||||
option.function_name = DEFAULT_NAME;
|
||||
option.hash_name = DEFAULT_HASH_NAME;
|
||||
option.key_name = DEFAULT_KEY;
|
||||
option.delimiters = DEFAULT_DELIMITERS;
|
||||
option.initial_asso_value = option.size = option.iterations = 0;
|
||||
option.total_switches = 1;
|
||||
option.argument_count = argc;
|
||||
option.argument_vector = argv;
|
||||
set_program_name (argv[0]);
|
||||
|
||||
while ((option_char = getopt (argc, argv, "adcCDe:f:gGhH:i:j:k:K:lnN:oprs:S:tTv")) != EOF)
|
||||
{
|
||||
switch (option_char)
|
||||
{
|
||||
case 'a': /* Generated coded uses the ANSI prototype format. */
|
||||
{
|
||||
SET_OPTION (option, ANSI);
|
||||
break;
|
||||
}
|
||||
case 'c': /* Generate strncmp rather than strcmp. */
|
||||
{
|
||||
SET_OPTION (option, COMP);
|
||||
break;
|
||||
}
|
||||
case 'C': /* Make the generated tables readonly (const). */
|
||||
{
|
||||
SET_OPTION (option, CONST);
|
||||
break;
|
||||
}
|
||||
case 'd': /* Enable debugging option. */
|
||||
{
|
||||
SET_OPTION (option, DEBUG);
|
||||
report_error ("starting program %n, version %s, with debuggin on.\n",
|
||||
version_string);
|
||||
break;
|
||||
}
|
||||
case 'D': /* Enable duplicate option. */
|
||||
{
|
||||
SET_OPTION (option, DUP);
|
||||
break;
|
||||
}
|
||||
case 'e': /* Allows user to provide keyword/attribute separator */
|
||||
{
|
||||
SET_DELIMITERS (option, optarg);
|
||||
break;
|
||||
}
|
||||
case 'f': /* Generate the hash table ``fast.'' */
|
||||
{
|
||||
SET_OPTION (option, FAST);
|
||||
if ((option.iterations = atoi (optarg)) < 0)
|
||||
{
|
||||
report_error ("iterations value must not be negative, assuming 0\n");
|
||||
option.iterations = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'g': /* Use the ``inline'' keyword for generated sub-routines. */
|
||||
{
|
||||
SET_OPTION (option, GNU);
|
||||
break;
|
||||
}
|
||||
case 'G': /* Make the keyword table a global variable. */
|
||||
{
|
||||
SET_OPTION (option, GLOBAL);
|
||||
break;
|
||||
}
|
||||
case 'h': /* Displays a list of helpful Options to the user. */
|
||||
{
|
||||
report_error (
|
||||
"-a\tGenerate ANSI standard C output code, i.e., function prototypes.\n\
|
||||
-c\tGenerate comparison code using strncmp rather than strcmp.\n\
|
||||
-C\tMake the contents of generated lookup tables constant, i.e., readonly.\n\
|
||||
-d\tEnables the debugging option (produces verbose output to Std_Err).\n\
|
||||
-D\tHandle keywords that hash to duplicate values. This is useful\n\
|
||||
\tfor certain highly redundant keyword sets. It enables the -S option.\n\
|
||||
-e\tAllow user to provide a string containing delimiters used to separate\n\
|
||||
\tkeywords from their attributes. Default is \",\\n\"\n\
|
||||
-f\tGenerate the perfect hash function ``fast.'' This decreases GPERF's\n\
|
||||
\trunning time at the cost of minimizing generated table-size.\n\
|
||||
\tThe numeric argument represents the number of times to iterate when\n\
|
||||
\tresolving a collision. `0' means ``iterate by the number of keywords''.\n\
|
||||
-g\tAssume a GNU compiler, e.g., g++ or gcc. This makes all generated\n\
|
||||
\troutines use the ``inline'' keyword to remove cost of function calls.\n\
|
||||
-G\tGenerate the static table of keywords as a static global variable,\n\
|
||||
\trather than hiding it inside of the lookup function (which is the\n\
|
||||
\tdefault behavior).\n\
|
||||
-h\tPrints this mesage.\n");
|
||||
report_error (
|
||||
"-H\tAllow user to specify name of generated hash function. Default is `hash'.\n\
|
||||
-i\tProvide an initial value for the associate values array. Default is 0.\n\
|
||||
\tSetting this value larger helps inflate the size of the final table.\n\
|
||||
-j\tAffects the ``jump value,'' i.e., how far to advance the associated\n\
|
||||
\tcharacter value upon collisions. Must be an odd number, default is %d.\n\
|
||||
-k\tAllows selection of the key positions used in the hash function.\n\
|
||||
\tThe allowable choices range between 1-%d, inclusive. The positions\n\
|
||||
\tare separated by commas, ranges may be used, and key positions may\n\
|
||||
\toccur in any order. Also, the meta-character '*' causes the generated\n\
|
||||
\thash function to consider ALL key positions, and $ indicates the\n\
|
||||
\t``final character'' of a key, e.g., $,1,2,4,6-10.\n\
|
||||
-K\tAllow user to select name of the keyword component in the keyword structure.\n\
|
||||
-l\tCompare key lengths before trying a string comparison. This helps\n\
|
||||
\tcut down on the number of string comparisons made during the lookup.\n\
|
||||
-n\tDo not include the length of the keyword when computing the hash function\n\
|
||||
-N\tAllow user to specify name of generated lookup function. Default\n\
|
||||
\tname is `in_word_set.'\n\
|
||||
-o\tReorders input keys by frequency of occurrence of the key sets.\n\
|
||||
\tThis should decrease the search time dramatically.\n\
|
||||
-p\tChanges the return value of the generated function ``in_word_set''\n\
|
||||
\tfrom its default boolean value (i.e., 0 or 1), to type ``pointer\n\
|
||||
\tto wordlist array'' This is most useful when the -t option, allowing\n\
|
||||
\tuser-defined structs, is used.\n",
|
||||
DEFAULT_JUMP_VALUE, MAX_KEY_POS - 1);
|
||||
report_error (
|
||||
"-r\tUtilizes randomness to initialize the associated values table.\n\
|
||||
-s\tAffects the size of the generated hash table. The numeric argument\n\
|
||||
\tfor this option indicates ``how many times larger'' the table range\n\
|
||||
\tshould be, in relationship to the number of keys, e.g. a value of 3\n\
|
||||
\tmeans ``make the table about 3 times larger than the number of input\n\
|
||||
\tkeys.'' A larger table should decrease the time required for an\n\
|
||||
\tunsuccessful search, at the expense of extra table space. Default\n\
|
||||
\tvalue is 1. This actual table size may vary somewhat.\n\
|
||||
-S\tCauses the generated C code to use a switch statement scheme, rather\n\
|
||||
\tthan an array lookup table. This can lead to a reduction in both\n\
|
||||
\ttime and space requirements for some keyfiles. The argument to\n\
|
||||
\tthis option determines how many switch statements are generated.\n\
|
||||
\tA value of 1 generates 1 switch containing all the elements, a value of 2\n\
|
||||
\tgenerates 2 tables with 1/2 the elements in each table, etc. This\n\
|
||||
\tis useful since many C compilers cannot correctly generate code for\n\
|
||||
\tlarge switch statements.\n\
|
||||
\tthe expense of longer time for each lookup. Mostly important for\n\
|
||||
\t*large* input sets, i.e., greater than around 100 items or so.\n\
|
||||
-t\tAllows the user to include a structured type declaration for \n\
|
||||
\tgenerated code. Any text before %%%% is consider part of the type\n\
|
||||
\tdeclaration. Key words and additional fields may follow this, one\n\
|
||||
\tgroup of fields per line.\n\
|
||||
-T\tPrevents the transfer of the type declaration to the output file.\n\
|
||||
\tUse this option if the type is already defined elsewhere.\n\
|
||||
-v\tPrints out the current version number\n%e%a\n",
|
||||
usage);
|
||||
}
|
||||
case 'H': /* Sets the name for the hash function */
|
||||
{
|
||||
option.hash_name = optarg;
|
||||
break;
|
||||
}
|
||||
case 'i': /* Sets the initial value for the associated values array. */
|
||||
{
|
||||
if ((option.initial_asso_value = atoi (optarg)) < 0)
|
||||
report_error ("initial value %d must be non-zero, ignoring and continuing\n",
|
||||
option.initial_asso_value);
|
||||
if (OPTION_ENABLED (option, RANDOM))
|
||||
report_error ("warning, -r option superceeds -i, ignoring -i option and continuing\n");
|
||||
break;
|
||||
}
|
||||
case 'j': /* Sets the jump value, must be odd for later algorithms. */
|
||||
{
|
||||
if ((option.jump = atoi (optarg)) < 0)
|
||||
report_error ("jump value %d must be a positive number\n%e%a",
|
||||
option.jump, usage);
|
||||
else if (option.jump && EVEN (option.jump))
|
||||
report_error ("jump value %d should be odd, adding 1 and continuing...\n",
|
||||
option.jump++);
|
||||
break;
|
||||
}
|
||||
case 'k': /* Sets key positions used for hash function. */
|
||||
{
|
||||
int BAD_VALUE = -1;
|
||||
int value;
|
||||
|
||||
iterator_init (optarg, 1, MAX_KEY_POS - 1, WORD_END, BAD_VALUE, EOS);
|
||||
|
||||
if (*optarg == '*') /* Use all the characters for hashing!!!! */
|
||||
{
|
||||
UNSET_OPTION (option, DEFAULTCHARS);
|
||||
SET_OPTION (option, ALLCHARS);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *key_pos;
|
||||
|
||||
for (key_pos = option.key_positions; (value = next ()) != EOS; key_pos++)
|
||||
if (value == BAD_VALUE)
|
||||
report_error ("illegal key value or range, use 1,2,3-%d,'$' or '*'.\n%e%a",
|
||||
(MAX_KEY_POS - 1),usage);
|
||||
else
|
||||
*key_pos = value;;
|
||||
|
||||
*key_pos = EOS;
|
||||
|
||||
if (! (option.total_charset_size = (key_pos - option.key_positions)))
|
||||
report_error ("no keys selected\n%e%a", usage);
|
||||
else if (! key_sort (option.key_positions, option.total_charset_size))
|
||||
report_error ("duplicate keys selected\n%e%a", usage);
|
||||
|
||||
if (option.total_charset_size != 2
|
||||
|| (option.key_positions[0] != 1 || option.key_positions[1] != WORD_END))
|
||||
UNSET_OPTION (option, DEFAULTCHARS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'K': /* Make this the keyname for the keyword component field. */
|
||||
{
|
||||
option.key_name = optarg;
|
||||
break;
|
||||
}
|
||||
case 'l': /* Create length table to avoid extra string compares. */
|
||||
{
|
||||
SET_OPTION (option, LENTABLE);
|
||||
break;
|
||||
}
|
||||
case 'n': /* Don't include the length when computing hash function. */
|
||||
{
|
||||
SET_OPTION (option, NOLENGTH);
|
||||
break;
|
||||
}
|
||||
case 'N': /* Make generated lookup function name be optarg */
|
||||
{
|
||||
option.function_name = optarg;
|
||||
break;
|
||||
}
|
||||
case 'o': /* Order input by frequency of key set occurrence. */
|
||||
{
|
||||
SET_OPTION (option, ORDER);
|
||||
break;
|
||||
}
|
||||
case 'p': /* Generated lookup function now a pointer instead of int. */
|
||||
{
|
||||
SET_OPTION (option, POINTER);
|
||||
break;
|
||||
}
|
||||
case 'r': /* Utilize randomness to initialize the associated values table. */
|
||||
{
|
||||
SET_OPTION (option, RANDOM);
|
||||
if (option.initial_asso_value != 0)
|
||||
report_error ("warning, -r option superceeds -i, disabling -i option and continuing\n");
|
||||
break;
|
||||
}
|
||||
case 's': /* Range of associated values, determines size of final table. */
|
||||
{
|
||||
if ((option.size = atoi (optarg)) <= 0)
|
||||
report_error ("improper range argument %s\n%e%a", optarg, usage);
|
||||
else if (option.size > 50)
|
||||
report_error ("%d is excessive, did you really mean this?! (type %n -h for help)\n",
|
||||
option.size);
|
||||
break;
|
||||
}
|
||||
case 'S': /* Generate switch statement output, rather than lookup table. */
|
||||
{
|
||||
SET_OPTION (option, SWITCH);
|
||||
if ((option.total_switches = atoi (optarg)) <= 0)
|
||||
report_error ("number of switches %s must be a positive number\n%e%a", optarg, usage);
|
||||
break;
|
||||
}
|
||||
case 't': /* Enable the TYPE mode, allowing arbitrary user structures. */
|
||||
{
|
||||
SET_OPTION (option, TYPE);
|
||||
break;
|
||||
}
|
||||
case 'T': /* Don't print structure definition. */
|
||||
{
|
||||
SET_OPTION (option, NOTYPE);
|
||||
break;
|
||||
}
|
||||
case 'v': /* Print out the version and quit. */
|
||||
report_error ("%n: version %s\n%e%a\n", version_string, usage);
|
||||
default:
|
||||
report_error ("%e%a", usage);
|
||||
}
|
||||
}
|
||||
|
||||
if (argv[optind] && ! freopen (argv[optind], "r", stdin))
|
||||
report_error ("unable to read key word file %s\n%e%a", argv[optind], usage);
|
||||
|
||||
if (++optind < argc)
|
||||
report_error ("extra trailing arguments to %n\n%e%a", usage);
|
||||
}
|
||||
|
||||
/* Output command-line Options. */
|
||||
void
|
||||
print_options ()
|
||||
{
|
||||
int i;
|
||||
|
||||
printf ("/* Command-line: ");
|
||||
|
||||
for (i = 0; i < option.argument_count; i++)
|
||||
printf ("%s ", option.argument_vector[i]);
|
||||
|
||||
printf (" */\n\n");
|
||||
}
|
||||
|
153
contrib/gperf/src/options.h
Normal file
153
contrib/gperf/src/options.h
Normal file
@ -0,0 +1,153 @@
|
||||
/* Handles parsing the Options provided to the user.
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* This module provides a uniform interface to the various Options available
|
||||
to a user of the Perfect.hash function generator. In addition to the
|
||||
run-time Options, found in the Option_Type below, there is also the
|
||||
hash table Size and the Keys to be used in the hashing.
|
||||
The overall design of this module was an experiment in using C++
|
||||
classes as a mechanism to enhance centralization of option and
|
||||
and error handling, which tend to get out of hand in a C program. */
|
||||
|
||||
#ifndef _options_h
|
||||
#define _options_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include "prototype.h"
|
||||
|
||||
/* Enumerate the potential debugging Options. */
|
||||
|
||||
enum option_type
|
||||
{
|
||||
DEBUG = 01, /* Enable debugging (prints diagnostics to Std_Err). */
|
||||
ORDER = 02, /* Apply ordering heuristic to speed-up search time. */
|
||||
ANSI = 04, /* Generate ANSI prototypes. */
|
||||
ALLCHARS = 010, /* Use all characters in hash function. */
|
||||
GNU = 020, /* Assume GNU extensions (primarily function inline). */
|
||||
TYPE = 040, /* Handle user-defined type structured keyword input. */
|
||||
RANDOM = 0100, /* Randomly initialize the associated values table. */
|
||||
DEFAULTCHARS = 0200, /* Make default char positions be 1,$ (end of keyword). */
|
||||
SWITCH = 0400, /* Generate switch output to save space. */
|
||||
POINTER = 01000, /* Have in_word_set function return pointer, not boolean. */
|
||||
NOLENGTH = 02000, /* Don't include keyword length in hash computations. */
|
||||
LENTABLE = 04000, /* Generate a length table for string comparison. */
|
||||
DUP = 010000, /* Handle duplicate hash values for keywords. */
|
||||
FAST = 020000, /* Generate the hash function ``fast.'' */
|
||||
NOTYPE = 040000, /* Don't include user-defined type definition
|
||||
in output -- it's already defined elsewhere. */
|
||||
COMP = 0100000, /* Generate strncmp rather than strcmp. */
|
||||
GLOBAL = 0200000, /* Make the keyword table a global variable. */
|
||||
CONST = 0400000, /* Make the generated tables readonly (const). */
|
||||
};
|
||||
|
||||
/* Define some useful constants. */
|
||||
|
||||
/* Max size of each word's key set. */
|
||||
#define MAX_KEY_POS (128 - 1)
|
||||
|
||||
/* Signals the start of a word. */
|
||||
#define WORD_START 1
|
||||
|
||||
/* Signals the end of a word. */
|
||||
#define WORD_END 0
|
||||
|
||||
/* Signals end of the key list. */
|
||||
#define EOS MAX_KEY_POS
|
||||
|
||||
/* Returns TRUE if option O is enabled. */
|
||||
#define OPTION_ENABLED(OW,O) (OW.option_word & (int)O)
|
||||
|
||||
/* Enables option O in OPTION_WORD. */
|
||||
#define SET_OPTION(OW,O) (OW.option_word |= (int)O)
|
||||
|
||||
/* Disable option O in OPTION_WORD. */
|
||||
#define UNSET_OPTION(OW,O) (OW.option_word &= ~(int)(O))
|
||||
|
||||
/* Returns total distinct key positions. */
|
||||
#define GET_CHARSET_SIZE(O) (O.total_charset_size)
|
||||
|
||||
/* Set the total distinct key positions. */
|
||||
#define SET_CHARSET_SIZE(O,S) (O.total_charset_size = (S))
|
||||
|
||||
/* Initializes the key Iterator. */
|
||||
#define RESET(O) (O.key_pos = 0)
|
||||
|
||||
/* Returns current key_position and advances index. */
|
||||
#define GET(O) (O.key_positions[O.key_pos++])
|
||||
|
||||
/* Sets the size of the table size. */
|
||||
#define SET_ASSO_MAX(O,R) (O.size = (R))
|
||||
|
||||
/* Returns the size of the table size. */
|
||||
#define GET_ASSO_MAX(O) (O.size)
|
||||
|
||||
/* Returns the jump value. */
|
||||
#define GET_JUMP(O) (O.jump)
|
||||
|
||||
/* Returns the iteration value. */
|
||||
#define GET_ITERATIONS(O) (O.iterations)
|
||||
|
||||
/* Returns the lookup function name. */
|
||||
#define GET_FUNCTION_NAME(O) (O.function_name)
|
||||
|
||||
/* Returns the keyword key name. */
|
||||
#define GET_KEY_NAME(O) (O.key_name)
|
||||
|
||||
/* Returns the hash function name. */
|
||||
#define GET_HASH_NAME(O) (O.hash_name)
|
||||
|
||||
/* Returns the initial associated character value. */
|
||||
#define INITIAL_VALUE(O) (O.initial_asso_value)
|
||||
|
||||
/* Returns the string used to delimit keywords from other attributes. */
|
||||
#define GET_DELIMITER(O) (O.delimiters)
|
||||
|
||||
/* Sets the keyword/attribute delimiters with value of D. */
|
||||
#define SET_DELIMITERS(O,D) (O.delimiters = (D))
|
||||
|
||||
/* Gets the total number of switch statements to generate. */
|
||||
#define GET_TOTAL_SWITCHES(O) (O.total_switches)
|
||||
|
||||
/* Class manager for gperf program options. */
|
||||
|
||||
typedef struct options
|
||||
{
|
||||
int option_word; /* Holds the user-specified Options. */
|
||||
int total_charset_size; /* Total number of distinct key_positions. */
|
||||
int size; /* Range of the hash table. */
|
||||
int key_pos; /* Tracks current key position for Iterator. */
|
||||
int jump; /* Jump length when trying alternative values. */
|
||||
int initial_asso_value; /* Initial value for asso_values table. */
|
||||
int argument_count; /* Records count of command-line arguments. */
|
||||
int iterations; /* Amount to iterate when a collision occurs. */
|
||||
int total_switches; /* Number of switch statements to generate. */
|
||||
char **argument_vector; /* Stores a pointer to command-line vector. */
|
||||
char *function_name; /* Name used for generated lookup function. */
|
||||
char *key_name; /* Name used for keyword key. */
|
||||
char *hash_name; /* Name used for generated hash function. */
|
||||
char *delimiters; /* Separates keywords from other attributes. */
|
||||
char key_positions[MAX_KEY_POS]; /* Contains user-specified key choices. */
|
||||
} OPTIONS;
|
||||
|
||||
extern void options_init P ((int argc, char *argv[]));
|
||||
extern void options_destroy P ((void));
|
||||
extern OPTIONS option;
|
||||
#endif /* _options_h */
|
350
contrib/gperf/src/perfect.c
Normal file
350
contrib/gperf/src/perfect.c
Normal file
@ -0,0 +1,350 @@
|
||||
/* Provides high-level routines to manipulate the keywork list
|
||||
structures the code generation output.
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include "options.h"
|
||||
#include "perfect.h"
|
||||
#include "stderr.h"
|
||||
|
||||
/* Current release version. */
|
||||
extern char *version_string;
|
||||
|
||||
/* Counts occurrences of each key set character. */
|
||||
int occurrences[ALPHABET_SIZE];
|
||||
|
||||
/* Value associated with each character. */
|
||||
int asso_values[ALPHABET_SIZE];
|
||||
|
||||
/* Locally visible PERFECT object. */
|
||||
PERFECT perfect;
|
||||
|
||||
/* Efficiently returns the least power of two greater than or equal to X! */
|
||||
#define POW(X) ((!X)?1:(X-=1,X|=X>>1,X|=X>>2,X|=X>>4,X|=X>>8,X|=X>>16,(++X)))
|
||||
|
||||
/* Reads input keys, possibly applies the reordering heuristic, sets the
|
||||
maximum associated value size (rounded up to the nearest power of 2),
|
||||
may initialize the associated values array, and determines the maximum
|
||||
hash table size. Note: using the random numbers is often helpful,
|
||||
though not as deterministic, of course! */
|
||||
|
||||
void
|
||||
perfect_init ()
|
||||
{
|
||||
int asso_value_max;
|
||||
int len;
|
||||
|
||||
perfect.num_done = 1;
|
||||
perfect.fewest_collisions = 0;
|
||||
read_keys ();
|
||||
if (OPTION_ENABLED (option, ORDER))
|
||||
reorder ();
|
||||
asso_value_max = GET_ASSO_MAX (option);
|
||||
len = keyword_list_length ();
|
||||
asso_value_max = (asso_value_max ? asso_value_max * len : len);
|
||||
SET_ASSO_MAX (option, POW (asso_value_max));
|
||||
|
||||
if (OPTION_ENABLED (option, RANDOM))
|
||||
{
|
||||
int i;
|
||||
|
||||
srandom (time (0));
|
||||
|
||||
for (i = 0; i < ALPHABET_SIZE; i++)
|
||||
asso_values[i] = (random () & asso_value_max - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int asso_value = INITIAL_VALUE (option);
|
||||
if (asso_value) /* Initialize array if user requests non-zero default. */
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = ALPHABET_SIZE - 1; i >= 0; i--)
|
||||
asso_values[i] = asso_value & GET_ASSO_MAX (option) - 1;
|
||||
}
|
||||
}
|
||||
perfect.max_hash_value = max_key_length () + GET_ASSO_MAX (option) *
|
||||
GET_CHARSET_SIZE (option);
|
||||
|
||||
printf ("/* C code produced by gperf version %s */\n", version_string);
|
||||
print_options ();
|
||||
|
||||
if (OPTION_ENABLED (option, DEBUG))
|
||||
{
|
||||
int i;
|
||||
fprintf (stderr, "\nnumber of keys = %d\nmaximum associated value is %d\
|
||||
\nmaximum possible size of generated hash table is %d\n",
|
||||
len, asso_value_max, perfect.max_hash_value);
|
||||
}
|
||||
}
|
||||
|
||||
/* Merge two hash key multisets to form the ordered disjoint union of the sets.
|
||||
(In a multiset, an element can occur multiple times). Precondition: both
|
||||
set_1 and set_2 must be ordered. Returns the length of the combined set. */
|
||||
|
||||
static int
|
||||
compute_disjoint_union (set_1, set_2, set_3)
|
||||
char *set_1;
|
||||
char *set_2;
|
||||
char *set_3;
|
||||
{
|
||||
char *base = set_3;
|
||||
|
||||
while (*set_1 && *set_2)
|
||||
if (*set_1 == *set_2)
|
||||
set_1++, set_2++;
|
||||
else
|
||||
{
|
||||
*set_3 = *set_1 < *set_2 ? *set_1++ : *set_2++;
|
||||
if (set_3 == base || *set_3 != *(set_3-1)) set_3++;
|
||||
}
|
||||
|
||||
while (*set_1)
|
||||
{
|
||||
*set_3 = *set_1++;
|
||||
if (set_3 == base || *set_3 != *(set_3-1)) set_3++;
|
||||
}
|
||||
|
||||
while (*set_2)
|
||||
{
|
||||
*set_3 = *set_2++;
|
||||
if (set_3 == base || *set_3 != *(set_3-1)) set_3++;
|
||||
}
|
||||
*set_3 = '\0';
|
||||
return set_3 - base;
|
||||
}
|
||||
|
||||
/* Sort the UNION_SET in increasing frequency of occurrence.
|
||||
This speeds up later processing since we may assume the resulting
|
||||
set (Set_3, in this case), is ordered. Uses insertion sort, since
|
||||
the UNION_SET is typically short. */
|
||||
|
||||
static void
|
||||
sort_set (union_set, len)
|
||||
char *union_set;
|
||||
int len;
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0, j = len - 1; i < j; i++)
|
||||
{
|
||||
char curr, tmp;
|
||||
|
||||
for (curr = i+1, tmp = union_set[curr];
|
||||
curr > 0 && occurrences[tmp] < occurrences[union_set[curr-1]];
|
||||
curr--)
|
||||
union_set[curr] = union_set[curr - 1];
|
||||
|
||||
union_set[curr] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate a key set's hash value. */
|
||||
|
||||
static int
|
||||
hash (key_node)
|
||||
LIST_NODE *key_node;
|
||||
{
|
||||
int sum = OPTION_ENABLED (option, NOLENGTH) ? 0 : key_node->length;
|
||||
char *ptr;
|
||||
|
||||
for (ptr = key_node->char_set; *ptr; ptr++)
|
||||
sum += asso_values[*ptr];
|
||||
|
||||
return key_node->hash_value = sum;
|
||||
}
|
||||
|
||||
/* Find out how associated value changes affect successfully hashed items.
|
||||
Returns FALSE if no other hash values are affected, else returns TRUE.
|
||||
Note that because GET_ASSO_MAX (option) is a power of two we can guarantee
|
||||
that all legal ASSO_VALUES are visited without repetition since
|
||||
GET_JUMP (option) was forced to be an odd value! */
|
||||
|
||||
static bool
|
||||
affects_prev (c, curr)
|
||||
char c;
|
||||
LIST_NODE *curr;
|
||||
{
|
||||
int original_char = asso_values[c];
|
||||
int i = !OPTION_ENABLED (option, FAST) ? GET_ASSO_MAX (option) :
|
||||
GET_ITERATIONS (option) == 0 ? key_list.list_len : GET_ITERATIONS (option);
|
||||
|
||||
/* Try all asso_values. */
|
||||
|
||||
while (--i >= 0)
|
||||
{
|
||||
int collisions = 0;
|
||||
LIST_NODE *ptr;
|
||||
|
||||
asso_values[c] = asso_values[c] + (GET_JUMP (option) ? GET_JUMP (option) : random ())
|
||||
& GET_ASSO_MAX (option) - 1;
|
||||
bool_array_reset ();
|
||||
|
||||
/* See how this asso_value change affects previous keywords. If
|
||||
it does better than before we'll take it! */
|
||||
|
||||
for (ptr = key_list.head;
|
||||
!lookup (hash (ptr)) || ++collisions < perfect.fewest_collisions;
|
||||
ptr = ptr->next)
|
||||
if (ptr == curr)
|
||||
{
|
||||
perfect.fewest_collisions = collisions;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
asso_values[c] = original_char; /* Restore original values, no more tries. */
|
||||
return TRUE; /* If we're this far it's time to try the next character.... */
|
||||
}
|
||||
|
||||
/* Change a character value, try least-used characters first. */
|
||||
|
||||
static void
|
||||
change (prior, curr)
|
||||
LIST_NODE *prior;
|
||||
LIST_NODE *curr;
|
||||
{
|
||||
char *xmalloc ();
|
||||
static char *union_set = 0;
|
||||
char *temp;
|
||||
LIST_NODE *ptr;
|
||||
|
||||
if (!union_set)
|
||||
union_set = xmalloc (2 * GET_CHARSET_SIZE (option) + 1);
|
||||
|
||||
if (OPTION_ENABLED (option, DEBUG)) /* Very useful for debugging. */
|
||||
{
|
||||
fprintf (stderr, "collision on keyword #%d, prior=\"%s\", curr=\"%s\", hash=%d\n",
|
||||
perfect.num_done, prior->key, curr->key, curr->hash_value);
|
||||
fflush (stderr);
|
||||
}
|
||||
sort_set (union_set, compute_disjoint_union (prior->char_set, curr->char_set, union_set));
|
||||
|
||||
/* Try changing some values, if change doesn't alter other values continue normal action. */
|
||||
|
||||
perfect.fewest_collisions++;
|
||||
|
||||
for (temp = union_set; *temp; temp++)
|
||||
if (!affects_prev (*temp, curr))
|
||||
{
|
||||
if (OPTION_ENABLED (option, DEBUG))
|
||||
{
|
||||
fprintf (stderr, "- resolved by changing asso_value['%c'] (char #%d) to %d\n",
|
||||
*temp, temp - union_set + 1, asso_values[*temp]);
|
||||
fflush (stderr);
|
||||
}
|
||||
return; /* Good, doesn't affect previous hash values, we'll take it. */
|
||||
}
|
||||
|
||||
for (ptr = key_list.head; ptr != curr; ptr = ptr->next)
|
||||
hash (ptr);
|
||||
|
||||
hash (curr);
|
||||
|
||||
if (OPTION_ENABLED (option, DEBUG))
|
||||
{
|
||||
fprintf (stderr, "** collision not resolved, %d duplicates remain, continuing...\n",
|
||||
perfect.fewest_collisions);
|
||||
fflush (stderr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Does the hard stuff....
|
||||
Initializes the Iteration Number boolean array, and then trys to find a
|
||||
perfect function that will hash all the key words without getting any
|
||||
duplications. This is made much easier since we aren't attempting
|
||||
to generate *minimum* functions, only perfect ones.
|
||||
If we can't generate a perfect function in one pass *and* the user
|
||||
hasn't enabled the DUP option, we'll inform the user to try the
|
||||
randomization option, use -D, or choose alternative key positions.
|
||||
The alternatives (e.g., back-tracking) are too time-consuming, i.e,
|
||||
exponential in the number of keys. */
|
||||
|
||||
int
|
||||
perfect_generate ()
|
||||
{
|
||||
LIST_NODE *curr;
|
||||
bool_array_init (perfect.max_hash_value);
|
||||
|
||||
for (curr = key_list.head; curr; curr = curr->next)
|
||||
{
|
||||
LIST_NODE *ptr;
|
||||
hash (curr);
|
||||
|
||||
for (ptr = key_list.head; ptr != curr; ptr = ptr->next)
|
||||
if (ptr->hash_value == curr->hash_value)
|
||||
{
|
||||
change (ptr, curr);
|
||||
break;
|
||||
}
|
||||
perfect.num_done++;
|
||||
}
|
||||
|
||||
|
||||
/* Make one final check, just to make sure nothing weird happened.... */
|
||||
bool_array_reset ();
|
||||
|
||||
for (curr = key_list.head; curr; curr = curr->next)
|
||||
if (lookup (hash (curr)))
|
||||
if (OPTION_ENABLED (option, DUP)) /* We'll try to deal with this later..... */
|
||||
break;
|
||||
else /* Yow, big problems. we're outta here! */
|
||||
{
|
||||
report_error ("\nInternal error, duplicate value %d:\n\
|
||||
try options -D or -r, or use new key positions.\n\n",
|
||||
hash (curr));
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool_array_destroy ();
|
||||
|
||||
/* First sorts the key word list by hash value, and the outputs the
|
||||
list to the proper ostream. The generated hash table code is only
|
||||
output if the early stage of processing turned out O.K. */
|
||||
|
||||
sort ();
|
||||
print_output ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Prints out some diagnostics upon completion. */
|
||||
|
||||
void
|
||||
perfect_destroy ()
|
||||
{
|
||||
if (OPTION_ENABLED (option, DEBUG))
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf (stderr, "\ndumping occurrence and associated values tables\n");
|
||||
|
||||
for (i = 0; i < ALPHABET_SIZE; i++)
|
||||
if (occurrences[i])
|
||||
fprintf (stderr, "asso_values[%c] = %3d, occurrences[%c] = %3d\n",
|
||||
i, asso_values[i], i, occurrences[i]);
|
||||
|
||||
fprintf (stderr, "end table dumping\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
45
contrib/gperf/src/perfect.h
Normal file
45
contrib/gperf/src/perfect.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* Provides high-level routines to manipulate the keyword list
|
||||
structures the code generation output.
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _perfect_h
|
||||
#define _perfect_h
|
||||
|
||||
#include "prototype.h"
|
||||
#include "keylist.h"
|
||||
#include "boolarray.h"
|
||||
|
||||
typedef struct perfect
|
||||
{
|
||||
KEY_LIST list; /* List of key words provided by the user. */
|
||||
BOOL_ARRAY duplicate; /* Speeds up check for redundant hash values. */
|
||||
int max_hash_value; /* Maximum possible hash value. */
|
||||
int fewest_collisions; /* Records fewest # of collisions for asso value. */
|
||||
int num_done; /* Number of keywords processed without a collision. */
|
||||
} PERFECT;
|
||||
|
||||
extern void perfect_init P ((void));
|
||||
extern void perfect_destroy P ((void));
|
||||
extern int perfect_generate P ((void));
|
||||
extern void perfect_print P ((void));
|
||||
#endif /* _perfect_h */
|
||||
|
||||
|
15
contrib/gperf/src/prototype.h
Normal file
15
contrib/gperf/src/prototype.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef _prototype_h
|
||||
#define _prototype_h
|
||||
#ifdef __STDC__
|
||||
#define P(X) X
|
||||
#else
|
||||
#define P(X) ()
|
||||
#endif
|
||||
|
||||
typedef char bool;
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define ODD(X) ((X) & 1)
|
||||
#define EVEN(X) (!((X) & 1))
|
||||
#endif /* _prototype_h */
|
87
contrib/gperf/src/readline.c
Normal file
87
contrib/gperf/src/readline.c
Normal file
@ -0,0 +1,87 @@
|
||||
/* Correctly reads an arbitrarily size string.
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "readline.h"
|
||||
|
||||
/* Size of each chunk. */
|
||||
#define CHUNK_SIZE BUFSIZ
|
||||
|
||||
/* Recursively fills up the buffer. */
|
||||
|
||||
static char *
|
||||
readln_aux (chunks)
|
||||
int chunks;
|
||||
{
|
||||
char *buffered_malloc ();
|
||||
char buf[CHUNK_SIZE];
|
||||
register char *bufptr = buf;
|
||||
register char *ptr;
|
||||
int c;
|
||||
|
||||
while ((c = getchar ()) != EOF && c != '\n') /* fill the current buffer */
|
||||
{
|
||||
*bufptr++ = c;
|
||||
if (bufptr - buf >= CHUNK_SIZE) /* prepend remainder to ptr buffer */
|
||||
{
|
||||
if (ptr = readln_aux (chunks + 1))
|
||||
|
||||
for (; bufptr != buf; *--ptr = *--bufptr);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == EOF && bufptr == buf)
|
||||
return NULL;
|
||||
|
||||
c = (chunks * CHUNK_SIZE + bufptr - buf) + 1;
|
||||
|
||||
if (ptr = buffered_malloc (c))
|
||||
{
|
||||
|
||||
for (*(ptr += (c - 1)) = '\0'; bufptr != buf; *--ptr = *--bufptr)
|
||||
;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Returns the ``next'' line, ignoring comments beginning with '#'. */
|
||||
|
||||
char *read_line ()
|
||||
{
|
||||
int c;
|
||||
if ((c = getchar ()) == '#')
|
||||
{
|
||||
while ((c = getchar ()) != '\n' && c != EOF)
|
||||
;
|
||||
|
||||
return c != EOF ? read_line () : NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ungetc (c, stdin);
|
||||
return readln_aux (0);
|
||||
}
|
||||
}
|
31
contrib/gperf/src/readline.h
Normal file
31
contrib/gperf/src/readline.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* Reads arbitrarily long string from input file, returning it as a dynamic buffer.
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Returns a pointer to an arbitrary length string. Returns NULL on error or EOF
|
||||
The storage for the string is dynamically allocated by new. */
|
||||
|
||||
#ifndef _readline_h
|
||||
#define _readline_h
|
||||
#include "prototype.h"
|
||||
|
||||
extern char *read_line P ((void));
|
||||
#endif /* _readline_h */
|
||||
|
90
contrib/gperf/src/stderr.c
Normal file
90
contrib/gperf/src/stderr.c
Normal file
@ -0,0 +1,90 @@
|
||||
/* Provides a useful variable-length argument error handling abstraction.
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "stderr.h"
|
||||
|
||||
/* Holds the name of the currently active program. */
|
||||
static char *program_name;
|
||||
|
||||
/* Sets name of program. */
|
||||
|
||||
void
|
||||
set_program_name (prog_name)
|
||||
char *prog_name;
|
||||
{
|
||||
program_name = prog_name;
|
||||
}
|
||||
|
||||
/* Valid Options (prefixed by '%', as in printf format strings) include:
|
||||
'a': exit the program at this point
|
||||
'c': print a character
|
||||
'd': print a decimal number
|
||||
'e': call the function pointed to by the corresponding argument
|
||||
'f','g': print a double
|
||||
'n': print the name of the program (NULL if not set in constructor or elsewhere)
|
||||
'p': print out the appropriate errno value from sys_errlist
|
||||
's': print out a character string
|
||||
'%': print out a single percent sign, '%' */
|
||||
|
||||
void
|
||||
report_error (va_alist)
|
||||
va_dcl
|
||||
{
|
||||
extern int errno, sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
typedef void (*PTF)();
|
||||
typedef char *CHARP;
|
||||
va_list argp;
|
||||
int abort = 0;
|
||||
char *format;
|
||||
|
||||
va_start (argp);
|
||||
|
||||
for (format = va_arg (argp, char *); *format; format++)
|
||||
{
|
||||
if (*format != '%')
|
||||
putc (*format, stderr);
|
||||
else
|
||||
{
|
||||
switch(*++format)
|
||||
{
|
||||
case '%' : putc ('%', stderr); break;
|
||||
case 'a' : abort = 1; break;
|
||||
case 'c' : putc (va_arg (argp, int), stderr); break;
|
||||
case 'd' : fprintf (stderr, "%d", va_arg (argp, int)); break;
|
||||
case 'e' : (*va_arg (argp, PTF))(); break;
|
||||
case 'f' : fprintf (stderr, "%g", va_arg (argp, double)); break;
|
||||
case 'n' : fputs (program_name ? program_name : "error", stderr); break;
|
||||
case 'p' :
|
||||
if (errno < sys_nerr)
|
||||
fprintf (stderr, "%s: %s", va_arg (argp, CHARP), sys_errlist[errno]);
|
||||
else
|
||||
fprintf (stderr, "<unknown error> %d", errno);
|
||||
break;
|
||||
case 's' : fputs (va_arg (argp, CHARP), stderr); break;
|
||||
}
|
||||
}
|
||||
if (abort)
|
||||
exit (1);
|
||||
}
|
||||
va_end (argp);
|
||||
}
|
29
contrib/gperf/src/stderr.h
Normal file
29
contrib/gperf/src/stderr.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* Provides a useful variable-length argument error handling abstraction.
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _stderr_h
|
||||
#define _stderr_h
|
||||
#include "prototype.h"
|
||||
#include <varargs.h>
|
||||
|
||||
extern void set_program_name P ((char *prog_name));
|
||||
extern void report_error ();
|
||||
#endif /* _stderr_h */
|
22
contrib/gperf/src/version.c
Normal file
22
contrib/gperf/src/version.c
Normal file
@ -0,0 +1,22 @@
|
||||
/* Current program version number.
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
char *version_string = "2.1 (K&R C version)";
|
78
contrib/gperf/src/xmalloc.c
Normal file
78
contrib/gperf/src/xmalloc.c
Normal file
@ -0,0 +1,78 @@
|
||||
/* Provide a useful malloc sanity checker and an efficient buffered memory
|
||||
allocator that reduces calls to malloc.
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
|
||||
This file is part of GNU GPERF.
|
||||
|
||||
GNU GPERF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU GPERF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU GPERF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Grabs SIZE bytes of dynamic memory or dies trying! */
|
||||
|
||||
char *
|
||||
xmalloc (size)
|
||||
int size;
|
||||
{
|
||||
char *malloc ();
|
||||
char *temp = malloc (size);
|
||||
|
||||
if (temp == 0)
|
||||
{
|
||||
fprintf (stderr, "out of virtual memory\n");
|
||||
exit (1);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* Determine default alignment. If your C compiler does not
|
||||
like this then try something like #define DEFAULT_ALIGNMENT 8. */
|
||||
struct fooalign {char x; double d;};
|
||||
#define ALIGNMENT ((char *)&((struct fooalign *) 0)->d - (char *)0)
|
||||
|
||||
/* Provide an abstraction that cuts down on the number of
|
||||
calls to MALLOC by buffering the memory pool from which
|
||||
items are allocated. */
|
||||
|
||||
char *
|
||||
buffered_malloc (size)
|
||||
int size;
|
||||
{
|
||||
char *temp;
|
||||
static char *buf_start = 0; /* Large array used to reduce calls to NEW. */
|
||||
static char *buf_end = 0; /* Indicates end of BUF_START. */
|
||||
static int buf_size = 4 * BUFSIZ; /* Size of buffer pointed to by BUF_START. */
|
||||
|
||||
/* Align this on correct boundaries, just to be safe... */
|
||||
size = ((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT;
|
||||
|
||||
/* If we are about to overflow our buffer we'll just grab another
|
||||
chunk of memory. Since we never free the original memory it
|
||||
doesn't matter that no one points to the beginning of that
|
||||
chunk. Furthermore, as a heuristic, we double the
|
||||
size of the new buffer! */
|
||||
|
||||
if (buf_start + size >= buf_end)
|
||||
{
|
||||
buf_size = buf_size * 2 > size ? buf_size * 2 : size;
|
||||
buf_start = xmalloc (buf_size);
|
||||
buf_end = buf_start + buf_size;
|
||||
}
|
||||
|
||||
temp = buf_start;
|
||||
buf_start += size;
|
||||
return temp;
|
||||
}
|
65
contrib/gperf/tests/Makefile
Normal file
65
contrib/gperf/tests/Makefile
Normal file
@ -0,0 +1,65 @@
|
||||
# Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
# written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
||||
#
|
||||
# This file is part of GNU GPERF.
|
||||
#
|
||||
# GNU GPERF is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 1, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU GPERF is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GNU GPERF; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
GPERF = gperf
|
||||
CC = gcc
|
||||
|
||||
all: test
|
||||
|
||||
test:
|
||||
@echo "performing some tests of the perfect hash generator"
|
||||
$(CC) -c -O test.c
|
||||
$(GPERF) -p -c -l -S1 -C -o c.gperf > cinset.c
|
||||
$(CC) -O -o cout cinset.c test.o
|
||||
@echo "testing ANSI C reserved words, all items should be found in the set"
|
||||
./cout -v < c.gperf
|
||||
$(GPERF) -k1,4,'$$' ada.gperf > adainset.c
|
||||
# double '$$' is only there since make gets confused; program wants only 1 '$'
|
||||
$(CC) -O -o aout adainset.c test.o
|
||||
@echo "testing Ada reserved words,all items should be found in the set"
|
||||
./aout -v < ada.gperf
|
||||
$(GPERF) -p -D -S1 -k1,'$$' -s 2 -o adapredefined.gperf > preinset.c
|
||||
$(CC) -O -o preout preinset.c test.o
|
||||
@echo "testing Ada predefined words, all items should be found in the set"
|
||||
./preout -v < adapredefined.gperf
|
||||
$(GPERF) -k1,2,'$$' -o modula3.gperf > m3inset.c
|
||||
$(CC) -O -o m3out m3inset.c test.o
|
||||
@echo "testing Modula3 reserved words, all items should be found in the set"
|
||||
./m3out -v < modula3.gperf
|
||||
$(GPERF) -o -S1 -p < pascal.gperf > pinset.c
|
||||
$(CC) -O -o pout pinset.c test.o
|
||||
@echo "testing Pascal reserved words, all items should be found in the set"
|
||||
./pout -v < pascal.gperf
|
||||
$(GPERF) -o -S2 -j1 -D -p -t < c++.gperf > c++inset.c
|
||||
$(CC) -O -o c++out c++inset.c test.o
|
||||
@echo "testing C++ reserved words, all items should be found in the set"
|
||||
tail -47 c++.gperf | ./c++out -v
|
||||
# these next 5 are demos that show off the generated code
|
||||
$(GPERF) -p -j1 -g -o -t -N is_reserved_word -k1,3,'$$' c-parse.gperf
|
||||
$(GPERF) -n -k1-8 -l modula2.gperf
|
||||
$(GPERF) -p -j 1 -o -a -g -t -k1,4,$$ gplus.gperf
|
||||
$(GPERF) -D -p -t < c-parse.gperf
|
||||
$(GPERF) -g -o -j1 -t -p -N is_reserved_word gpc.gperf
|
||||
# prints out the help message
|
||||
-$(GPERF) -h
|
||||
@echo "only if, do, for, case, goto, else, while, and return should be found "
|
||||
./aout -v < c.gperf
|
||||
|
||||
clean:
|
||||
-rm -f *.o core *~ *inset.c *out #*#
|
63
contrib/gperf/tests/ada.gperf
Normal file
63
contrib/gperf/tests/ada.gperf
Normal file
@ -0,0 +1,63 @@
|
||||
else
|
||||
exit
|
||||
terminate
|
||||
type
|
||||
raise
|
||||
range
|
||||
reverse
|
||||
declare
|
||||
end
|
||||
record
|
||||
exception
|
||||
not
|
||||
then
|
||||
return
|
||||
separate
|
||||
select
|
||||
digits
|
||||
renames
|
||||
subtype
|
||||
elsif
|
||||
function
|
||||
for
|
||||
package
|
||||
procedure
|
||||
private
|
||||
while
|
||||
when
|
||||
new
|
||||
entry
|
||||
delay
|
||||
case
|
||||
constant
|
||||
at
|
||||
abort
|
||||
accept
|
||||
and
|
||||
delta
|
||||
access
|
||||
abs
|
||||
pragma
|
||||
array
|
||||
use
|
||||
out
|
||||
do
|
||||
others
|
||||
of
|
||||
or
|
||||
all
|
||||
limited
|
||||
loop
|
||||
null
|
||||
task
|
||||
in
|
||||
is
|
||||
if
|
||||
rem
|
||||
mod
|
||||
begin
|
||||
body
|
||||
xor
|
||||
goto
|
||||
generic
|
||||
with
|
54
contrib/gperf/tests/adapredefined.gperf
Normal file
54
contrib/gperf/tests/adapredefined.gperf
Normal file
@ -0,0 +1,54 @@
|
||||
boolean
|
||||
character
|
||||
constraint_error
|
||||
false
|
||||
float
|
||||
integer
|
||||
natural
|
||||
numeric_error
|
||||
positive
|
||||
program_error
|
||||
storage_error
|
||||
string
|
||||
tasking_error
|
||||
true
|
||||
address
|
||||
aft
|
||||
base
|
||||
callable
|
||||
constrained
|
||||
count
|
||||
delta
|
||||
digits
|
||||
emax
|
||||
epsilon
|
||||
first
|
||||
firstbit
|
||||
fore
|
||||
image
|
||||
large
|
||||
last
|
||||
lastbit
|
||||
length
|
||||
machine_emax
|
||||
machine_emin
|
||||
machine_mantissa
|
||||
machine_overflows
|
||||
machine_radix
|
||||
machine_rounds
|
||||
mantissa
|
||||
pos
|
||||
position
|
||||
pred
|
||||
range
|
||||
safe_emax
|
||||
safe_large
|
||||
safe_small
|
||||
size
|
||||
small
|
||||
storage_size
|
||||
succ
|
||||
terminated
|
||||
val
|
||||
value
|
||||
width
|
49
contrib/gperf/tests/c++.gperf
Normal file
49
contrib/gperf/tests/c++.gperf
Normal file
@ -0,0 +1,49 @@
|
||||
struct resword {char *name;};
|
||||
%%
|
||||
asm
|
||||
auto
|
||||
break
|
||||
case
|
||||
catch
|
||||
char
|
||||
class
|
||||
const
|
||||
continue
|
||||
default
|
||||
delete
|
||||
do
|
||||
double
|
||||
else
|
||||
enum
|
||||
extern
|
||||
float
|
||||
for
|
||||
friend
|
||||
goto
|
||||
if
|
||||
inline
|
||||
int
|
||||
long
|
||||
new
|
||||
operator
|
||||
overload
|
||||
private
|
||||
protected
|
||||
public
|
||||
register
|
||||
return
|
||||
short
|
||||
signed
|
||||
sizeof
|
||||
static
|
||||
struct
|
||||
switch
|
||||
template
|
||||
this
|
||||
typedef
|
||||
union
|
||||
unsigned
|
||||
virtual
|
||||
void
|
||||
volatile
|
||||
while
|
56
contrib/gperf/tests/c-parse.gperf
Normal file
56
contrib/gperf/tests/c-parse.gperf
Normal file
@ -0,0 +1,56 @@
|
||||
%{
|
||||
/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */
|
||||
%}
|
||||
struct resword { char *name; short token; enum rid rid; };
|
||||
%%
|
||||
__alignof, ALIGNOF, NORID
|
||||
__alignof__, ALIGNOF, NORID
|
||||
__asm, ASM, NORID
|
||||
__asm__, ASM, NORID
|
||||
__attribute, ATTRIBUTE, NORID
|
||||
__attribute__, ATTRIBUTE, NORID
|
||||
__const, TYPE_QUAL, RID_CONST
|
||||
__const__, TYPE_QUAL, RID_CONST
|
||||
__inline, SCSPEC, RID_INLINE
|
||||
__inline__, SCSPEC, RID_INLINE
|
||||
__signed, TYPESPEC, RID_SIGNED
|
||||
__signed__, TYPESPEC, RID_SIGNED
|
||||
__typeof, TYPEOF, NORID
|
||||
__typeof__, TYPEOF, NORID
|
||||
__volatile, TYPE_QUAL, RID_VOLATILE
|
||||
__volatile__, TYPE_QUAL, RID_VOLATILE
|
||||
asm, ASM, NORID
|
||||
auto, SCSPEC, RID_AUTO
|
||||
break, BREAK, NORID
|
||||
case, CASE, NORID
|
||||
char, TYPESPEC, RID_CHAR
|
||||
const, TYPE_QUAL, RID_CONST
|
||||
continue, CONTINUE, NORID
|
||||
default, DEFAULT, NORID
|
||||
do, DO, NORID
|
||||
double, TYPESPEC, RID_DOUBLE
|
||||
else, ELSE, NORID
|
||||
enum, ENUM, NORID
|
||||
extern, SCSPEC, RID_EXTERN
|
||||
float, TYPESPEC, RID_FLOAT
|
||||
for, FOR, NORID
|
||||
goto, GOTO, NORID
|
||||
if, IF, NORID
|
||||
inline, SCSPEC, RID_INLINE
|
||||
int, TYPESPEC, RID_INT
|
||||
long, TYPESPEC, RID_LONG
|
||||
register, SCSPEC, RID_REGISTER
|
||||
return, RETURN, NORID
|
||||
short, TYPESPEC, RID_SHORT
|
||||
signed, TYPESPEC, RID_SIGNED
|
||||
sizeof, SIZEOF, NORID
|
||||
static, SCSPEC, RID_STATIC
|
||||
struct, STRUCT, NORID
|
||||
switch, SWITCH, NORID
|
||||
typedef, SCSPEC, RID_TYPEDEF
|
||||
typeof, TYPEOF, NORID
|
||||
union, UNION, NORID
|
||||
unsigned, TYPESPEC, RID_UNSIGNED
|
||||
void, TYPESPEC, RID_VOID
|
||||
volatile, TYPE_QUAL, RID_VOLATILE
|
||||
while, WHILE, NORID
|
32
contrib/gperf/tests/c.gperf
Normal file
32
contrib/gperf/tests/c.gperf
Normal file
@ -0,0 +1,32 @@
|
||||
if
|
||||
do
|
||||
int
|
||||
for
|
||||
case
|
||||
char
|
||||
auto
|
||||
goto
|
||||
else
|
||||
long
|
||||
void
|
||||
enum
|
||||
float
|
||||
short
|
||||
union
|
||||
break
|
||||
while
|
||||
const
|
||||
double
|
||||
static
|
||||
extern
|
||||
struct
|
||||
return
|
||||
sizeof
|
||||
switch
|
||||
signed
|
||||
typedef
|
||||
default
|
||||
unsigned
|
||||
continue
|
||||
register
|
||||
volatile
|
48
contrib/gperf/tests/gpc.gperf
Normal file
48
contrib/gperf/tests/gpc.gperf
Normal file
@ -0,0 +1,48 @@
|
||||
%{
|
||||
/* ISO Pascal 7185 reserved words.
|
||||
*
|
||||
* For GNU Pascal compiler (GPC) by jtv@hut.fi
|
||||
*
|
||||
* run this through the Doug Schmidt's gperf program
|
||||
* with command
|
||||
* gperf -g -o -j1 -t -p -N is_reserved_word
|
||||
*
|
||||
*/
|
||||
%}
|
||||
struct resword { char *name; short token; short iclass;};
|
||||
%%
|
||||
And, AND, PASCAL_ISO
|
||||
Array, ARRAY, PASCAL_ISO
|
||||
Begin, BEGIN_, PASCAL_ISO
|
||||
Case, CASE, PASCAL_ISO
|
||||
Const, CONST, PASCAL_ISO
|
||||
Div, DIV, PASCAL_ISO
|
||||
Do, DO, PASCAL_ISO
|
||||
Downto, DOWNTO, PASCAL_ISO
|
||||
Else, ELSE, PASCAL_ISO
|
||||
End, END, PASCAL_ISO
|
||||
File, FILE_, PASCAL_ISO
|
||||
For, FOR, PASCAL_ISO
|
||||
Function, FUNCTION, PASCAL_ISO
|
||||
Goto, GOTO, PASCAL_ISO
|
||||
If, IF, PASCAL_ISO
|
||||
In, IN, PASCAL_ISO
|
||||
Label, LABEL, PASCAL_ISO
|
||||
Mod, MOD, PASCAL_ISO
|
||||
Nil, NIL, PASCAL_ISO
|
||||
Not, NOT, PASCAL_ISO
|
||||
Of, OF, PASCAL_ISO
|
||||
Or, OR, PASCAL_ISO
|
||||
Packed, PACKED, PASCAL_ISO
|
||||
Procedure, PROCEDURE, PASCAL_ISO
|
||||
Program,PROGRAM,PASCAL_ISO
|
||||
Record, RECORD, PASCAL_ISO
|
||||
Repeat, REPEAT, PASCAL_ISO
|
||||
Set, SET, PASCAL_ISO
|
||||
Then, THEN, PASCAL_ISO
|
||||
To, TO, PASCAL_ISO
|
||||
Type, TYPE, PASCAL_ISO
|
||||
Until, UNTIL, PASCAL_ISO
|
||||
Var, VAR, PASCAL_ISO
|
||||
While, WHILE, PASCAL_ISO
|
||||
With, WITH, PASCAL_ISO
|
76
contrib/gperf/tests/gplus.gperf
Normal file
76
contrib/gperf/tests/gplus.gperf
Normal file
@ -0,0 +1,76 @@
|
||||
%{
|
||||
/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$ gplus.gperf */
|
||||
%}
|
||||
struct resword { char *name; short token; enum rid rid;};
|
||||
%%
|
||||
__alignof, ALIGNOF, NORID
|
||||
__alignof__, ALIGNOF, NORID
|
||||
__asm, ASM, NORID
|
||||
__asm__, ASM, NORID
|
||||
__attribute, ATTRIBUTE, NORID
|
||||
__attribute__, ATTRIBUTE, NORID
|
||||
__const, TYPE_QUAL, RID_CONST
|
||||
__const__, TYPE_QUAL, RID_CONST
|
||||
__inline, SCSPEC, RID_INLINE
|
||||
__inline__, SCSPEC, RID_INLINE
|
||||
__signed, TYPESPEC, RID_SIGNED
|
||||
__signed__, TYPESPEC, RID_SIGNED
|
||||
__typeof, TYPEOF, NORID
|
||||
__typeof__, TYPEOF, NORID
|
||||
__volatile, TYPE_QUAL, RID_VOLATILE
|
||||
__volatile__, TYPE_QUAL, RID_VOLATILE
|
||||
all, ALL, NORID /* Extension */,
|
||||
except, EXCEPT, NORID /* Extension */,
|
||||
exception, AGGR, RID_EXCEPTION /* Extension */,
|
||||
raise, RAISE, NORID /* Extension */,
|
||||
raises, RAISES, NORID /* Extension */,
|
||||
reraise, RERAISE, NORID /* Extension */,
|
||||
try, TRY, NORID /* Extension */,
|
||||
asm, ASM, NORID,
|
||||
auto, SCSPEC, RID_AUTO,
|
||||
break, BREAK, NORID,
|
||||
case, CASE, NORID,
|
||||
catch, CATCH, NORID,
|
||||
char, TYPESPEC, RID_CHAR,
|
||||
class, AGGR, RID_CLASS,
|
||||
const, TYPE_QUAL, RID_CONST,
|
||||
continue, CONTINUE, NORID,
|
||||
default, DEFAULT, NORID,
|
||||
delete, DELETE, NORID,
|
||||
do, DO, NORID,
|
||||
double, TYPESPEC, RID_DOUBLE,
|
||||
dynamic, DYNAMIC, NORID,
|
||||
else, ELSE, NORID,
|
||||
enum, ENUM, NORID,
|
||||
extern, SCSPEC, RID_EXTERN,
|
||||
float, TYPESPEC, RID_FLOAT,
|
||||
for, FOR, NORID,
|
||||
friend, SCSPEC, RID_FRIEND,
|
||||
goto, GOTO, NORID,
|
||||
if, IF, NORID,
|
||||
inline, SCSPEC, RID_INLINE,
|
||||
int, TYPESPEC, RID_INT,
|
||||
long, TYPESPEC, RID_LONG,
|
||||
new, NEW, NORID,
|
||||
operator, OPERATOR, NORID,
|
||||
overload, OVERLOAD, NORID,
|
||||
private, PRIVATE, NORID,
|
||||
protected, PROTECTED, NORID,
|
||||
public, PUBLIC, NORID,
|
||||
register, SCSPEC, RID_REGISTER,
|
||||
return, RETURN, NORID,
|
||||
short, TYPESPEC, RID_SHORT,
|
||||
signed, TYPESPEC, RID_SIGNED,
|
||||
sizeof, SIZEOF, NORID,
|
||||
static, SCSPEC, RID_STATIC,
|
||||
struct, AGGR, RID_RECORD,
|
||||
switch, SWITCH, NORID,
|
||||
this, THIS, NORID,
|
||||
typedef, SCSPEC, RID_TYPEDEF,
|
||||
typeof, TYPEOF, NORID,
|
||||
union, AGGR, RID_UNION,
|
||||
unsigned, TYPESPEC, RID_UNSIGNED,
|
||||
virtual, SCSPEC, RID_VIRTUAL,
|
||||
void, TYPESPEC, RID_VOID,
|
||||
volatile, TYPE_QUAL, RID_VOLATILE,
|
||||
while, WHILE, NORID,
|
40
contrib/gperf/tests/modula2.gperf
Normal file
40
contrib/gperf/tests/modula2.gperf
Normal file
@ -0,0 +1,40 @@
|
||||
AND
|
||||
ARRAY
|
||||
BEGIN
|
||||
BY
|
||||
CASE
|
||||
CONST
|
||||
DEFINITION
|
||||
DIV
|
||||
DO
|
||||
ELSE
|
||||
ELSIF
|
||||
END
|
||||
EXIT
|
||||
EXPORT
|
||||
FOR
|
||||
FROM
|
||||
IF
|
||||
IMPLEMENTATION
|
||||
IMPORT
|
||||
IN
|
||||
LOOP
|
||||
MOD
|
||||
MODULE
|
||||
NOT
|
||||
OF
|
||||
OR
|
||||
POINTER
|
||||
PROCEDURE
|
||||
QUALIFIED
|
||||
RECORD
|
||||
REPEAT
|
||||
RETURN
|
||||
SET
|
||||
THEN
|
||||
TO
|
||||
TYPE
|
||||
UNTIL
|
||||
VAR
|
||||
WHILE
|
||||
WITH
|
106
contrib/gperf/tests/modula3.gperf
Normal file
106
contrib/gperf/tests/modula3.gperf
Normal file
@ -0,0 +1,106 @@
|
||||
AND
|
||||
ARRAY
|
||||
BEGIN
|
||||
BITS
|
||||
BY
|
||||
CASE
|
||||
CONST
|
||||
DIV
|
||||
DO
|
||||
ELSE
|
||||
ELSIF
|
||||
END
|
||||
EVAL
|
||||
EXCEPT
|
||||
EXCEPTION
|
||||
EXIT
|
||||
EXPORTS
|
||||
FINALLY
|
||||
FOR
|
||||
FROM
|
||||
IF
|
||||
IMPORT
|
||||
INTERFACE
|
||||
IN
|
||||
INLINE
|
||||
LOCK
|
||||
METHODS
|
||||
MOD
|
||||
MODULE
|
||||
NOT
|
||||
OBJECT
|
||||
OF
|
||||
OR
|
||||
PROCEDURE
|
||||
RAISES
|
||||
READONLY
|
||||
RECORD
|
||||
REF
|
||||
REPEAT
|
||||
RETURN
|
||||
SET
|
||||
THEN
|
||||
TO
|
||||
TRY
|
||||
TYPE
|
||||
TYPECASE
|
||||
UNSAFE
|
||||
UNTIL
|
||||
UNTRACED
|
||||
VALUE
|
||||
VAR
|
||||
WHILE
|
||||
WITH
|
||||
and
|
||||
array
|
||||
begin
|
||||
bits
|
||||
by
|
||||
case
|
||||
const
|
||||
div
|
||||
do
|
||||
else
|
||||
elsif
|
||||
end
|
||||
eval
|
||||
except
|
||||
exception
|
||||
exit
|
||||
exports
|
||||
finally
|
||||
for
|
||||
from
|
||||
if
|
||||
import
|
||||
interface
|
||||
in
|
||||
inline
|
||||
lock
|
||||
methods
|
||||
mod
|
||||
module
|
||||
not
|
||||
object
|
||||
of
|
||||
or
|
||||
procedure
|
||||
raises
|
||||
readonly
|
||||
record
|
||||
ref
|
||||
repeat
|
||||
return
|
||||
set
|
||||
then
|
||||
to
|
||||
try
|
||||
type
|
||||
typecase
|
||||
unsafe
|
||||
until
|
||||
untraced
|
||||
value
|
||||
var
|
||||
while
|
||||
with
|
36
contrib/gperf/tests/pascal.gperf
Normal file
36
contrib/gperf/tests/pascal.gperf
Normal file
@ -0,0 +1,36 @@
|
||||
with
|
||||
array
|
||||
and
|
||||
function
|
||||
case
|
||||
var
|
||||
const
|
||||
until
|
||||
then
|
||||
set
|
||||
record
|
||||
program
|
||||
procedure
|
||||
or
|
||||
packed
|
||||
not
|
||||
nil
|
||||
label
|
||||
in
|
||||
repeat
|
||||
of
|
||||
goto
|
||||
forward
|
||||
for
|
||||
while
|
||||
file
|
||||
else
|
||||
downto
|
||||
do
|
||||
div
|
||||
to
|
||||
type
|
||||
end
|
||||
mod
|
||||
begin
|
||||
if
|
32
contrib/gperf/tests/test.c
Normal file
32
contrib/gperf/tests/test.c
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
Tests the generated perfect has function.
|
||||
The -v option prints diagnostics as to whether a word is in
|
||||
the set or not. Without -v the program is useful for timing.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAX_LEN 80
|
||||
|
||||
#ifdef __STDC__
|
||||
int in_word_set (char *, unsigned int);
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
#else
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
#endif
|
||||
{
|
||||
int verbose = argc > 1 ? 1 : 0;
|
||||
char buf[MAX_LEN];
|
||||
|
||||
while (gets (buf))
|
||||
if (in_word_set (buf, strlen (buf)) && verbose)
|
||||
printf ("in word set %s\n", buf);
|
||||
else if (verbose)
|
||||
printf ("NOT in word set %s\n", buf);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user