diff options
Diffstat (limited to 'contrib/gperf')
91 files changed, 25156 insertions, 0 deletions
diff --git a/contrib/gperf/AUTHORS b/contrib/gperf/AUTHORS new file mode 100644 index 0000000..3429c03 --- /dev/null +++ b/contrib/gperf/AUTHORS @@ -0,0 +1,2 @@ +Douglas C. Schmidt <schmidt@ics.uci.edu> +Bruno Haible <haible@clisp.cons.org> diff --git a/contrib/gperf/COPYING b/contrib/gperf/COPYING new file mode 100644 index 0000000..bab08af --- /dev/null +++ b/contrib/gperf/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307, + USA. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU 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. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), 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 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 show them these terms so they know 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. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + 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 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 derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 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 License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +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. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary 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 + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 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 Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing 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 for copying, distributing or modifying +the Program or works based on it. + + 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. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. 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 this 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 +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. 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 + + 11. 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. + + 12. 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 the public, 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) <year> <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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, 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) year 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 is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/contrib/gperf/ChangeLog b/contrib/gperf/ChangeLog new file mode 100644 index 0000000..95ba1fe --- /dev/null +++ b/contrib/gperf/ChangeLog @@ -0,0 +1,1718 @@ +2000-09-26 Bruno Haible <bruno@linuix.math.u-bordeaux.fr> + + * gperf-2.7.2 released. + + * doc/gperf.texi: Add a second bug report address + <gperf-bugs@lists.sourceforge.net>. + * README: Updated. + +2000-08-28 Bruno Haible <bruno@linuix.math.u-bordeaux.fr> + + * lib/getopt.h (struct option): Use "const" also when compiling in + C++ mode. Avoids warnings from Sun CC and HP-UX aCC. + + * doc/Makefile.in (docdir): Change from $(datadir)/doc/@PACKAGE@ to + $(prefix)/doc/@PACKAGE@, following the newest GNU standards. + +2000-08-20 Bruno Haible <bruno@linuix.math.u-bordeaux.fr> + + * src/version.cc: Bump version number to 2.7.2. + * doc/gperf.texi: Likewise. + + * doc/texinfo.tex: Update to post-texinfo-4.0 version. @code in the + title page now chooses a larger font. The overall layout of the + text is denser. + + * AUTHORS: New file. + + * tests/Makefile.in (all): Add check-lang-utf8 and check-lang-ucs2. + (check-lang-utf8, check-lang-ucs2): New targets. + (clean): Remove lu8out and lu2out. + * tests/lang-utf8.gperf, tests/lang-utf8.exp: New files. + * tests/lang-ucs2.gperf, tests/test2.c, tests/lang-ucs2.in, + tests/lang-ucs2.exp: New files. + + Allow the use of embedded NULs in keys. + * lib/hash.h (hashpjw): Add a length argument. + * lib/hash.cc (hashpjw): Likewise. Don't stop when encountering a NUL + character. + * src/hash-table.h (Hash_Table constructor): Add ignore_len argument. + (Hash_Table::ignore_length): New field. + (Hash_Table::insert): Renamed from Hash_Table::operator(). Remove + ignore_length argument. + * src/hash-table.cc (NIL): Remove macro. + (Hash_Table constructor): Add ignore_len argument. Use it to + initialize ignore_length. + (Hash_Table destructor): Specify explicit length of char_set and + key. + (Hash_Table::insert): Renamed from Hash_Table::operator(). Remove + ignore_length argument. Pass explicit length to hashpjw. Compare + char_set using memcmp, not strcmp. + * src/list-node.h (List_Node): Rename field length to key_length. + New field char_set_length. + (List_Node constructor): Accept key and rest, not the entire line. + * src/list-node.cc (List_Node constructor): Accept key and rest, not + the entire line. Don't NUL terminate key and char_set. Specify + explicit length of key. Initialize char_set_length field. + * src/key-list.cc: Include <ctype.h>. + (parse_line): New function. + (Key_List::read_keys): Call parse_line instead of new List_Node. + Pass option[NOLENGTH] to Hash_Table constructor, not + Hash_Table::insert. Specify explicit length of key and char_set. + (Key_List::get_occurrence): Use explicit length of char_set. + (Key_List::set_determined): Likewise. + (Key_List::already_determined): Likewise. + (output_string): Add length argument. Output unprintable characters + using octal escape sequence. + (output_keyword_entry): Use explicit length of key. + (Key_List::output_lookup_array): Specify explicit length of key. + (output_switch_case): Likewise. + (Key_List::dump): Likewise. + * src/gen-perf.h (Gen_Perf::compute_disjoint_union): Add two length + arguments. + * src/gen-perf.cc (Gen_Perf::compute_disjoint_union): Likewise. Don't + stop when encountering NUL characters. Don't NUL terminate the + result. + (Gen_Perf::hash): Use explicit length of char_set. + (Gen_Perf::change): Specify explicit length of key. + * doc/gperf.texi: Document it. + + * doc/help2man: New file, help2man version 1.022. + * Makefile.devel (all): Add doc/gperf.1. + (doc/gperf.1): New target. + * doc/gperf.1: Automatically generated. + + * mkinstalldirs: New file, from automake-1.4, grep-2.4.1, guile-1.4, + libtool-1.3.3, make-3.79.1, tar-1.13. + * src/Makefile.in (MKINSTALLDIRS): New variable. + (install, installdirs): Use it instead of mkdir. + * doc/Makefile.in (MKINSTALLDIRS): New variable. + (install, installdirs): Use it instead of mkdir. + + * INSTALL: Update. + +2000-08-19 Bruno Haible <bruno@linuix.math.u-bordeaux.fr> + + * src/key-list.cc (Output_Compare_Memcmp): New class. + (Key_List::output_lookup_function): When option -l is given, use + memcmp instead of strcmp or strncmp. + + * doc/gperf.texi: The bug report address is <bug-gnu-utils@gnu.org>. + The download address is ftp.gnu.org. Remove mention of -a and -g + options (now nops). Explain effect of -c option. + + * doc/configure.in (PACKAGE): New variable. + * doc/Makefile.in (datadir, docdir): New variables. + (dvidir, htmldir): Change values. + (install, installdirs): Update. + + * src/configure.in: Rename cache variable gp_cxx_throw_decl to + gp_cv_cxx_throw_decl. + + * src/key-list.cc (Key_List::output_hash_function): When outputting + __inline, take advantage of C++ compilers which have inline. + + * src/key-list.cc (Output_Compare_Strncmp::output_comparison): + After the call to strncmp, verify that expr2 is not longer than + `len'. + Reported by Carlo Wood <carlo@runaway.xs4all.nl>. + + * src/key-list.cc (Key_List::output_lookup_function_body): Avoid + emitting the loop for dealing with duplicates if + total_duplicates == 0. + + * src/key-list.cc (Key_List::read_keys): Don't accept an empty key. + + * src/Makefile.in (install, installdirs, uninstall): Respect + $(DESTDIR). + * doc/Makefile.in (install, installdirs, uninstall): Likewise. + + * src/options.cc (Options::print_options): Escape the arguments which + contain special characters. + + * tests/c-parse.gperf: Updated from gcc-2.95.2/gcc/c-parse.gperf. + * tests/objc.gperf: New file, from gcc-2.95.2/gcc/objc/objc.gperf. + * tests/chill.gperf: New file, from gcc-2.95.2/gcc/ch/gperf. + * tests/cplusplus.gperf: New file, from gcc-2.95.2/gcc/cp/gxx.gperf. + * tests/gplus.gperf: Remove file. + * tests/java.gperf: New file, from gcc-2.95.2/gcc/java/keyword.gperf. + * tests/Makefile: Check them all. + * tests/c-parse.exp: Renamed from tests/test-1.exp. + * tests/modula2.exp: Renamed from tests/test-2.exp. + * tests/cplusplus.exp: Renamed from tests/test-3.exp. + * tests/gpc.exp: Renamed from tests/test-5.exp. + + * src/key-list.cc (output_switch_case): Add trailing semicolon to + lengthptr assignment line. Fixes bug with -D and -S. + From Reini Urban <rurban@sbox.tu-graz.ac.at>. Also reported by + David Hunter. + * tests/Makefile.in (check-lang-syntax): Perform each test with -D + once without and once with duplicates. + + * src/key-list.cc (output_keyword_entry): Avoid outputting a struct + initializer of the form {"key",}. + + * src/iterator.cc: Don't include <stream.h>. + From Michael Deutschmann <ldeutsch@mail.netshop.net>. + + * tests/Makefile.in (VALIDATE, check-lang-syntax): Use $(srcdir) where + appropriate. + Reported by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>. + + * tests/validate: Don't run -traditional tests by default. + + * src/main.cc (main): Check for write error on stdout before returning. + + * src/Makefile.in (LDFLAGS): New definition, to catch the value given + at configure time. + + Make the structure initializers customizable. Based on a patch by + Kaveh R. Ghazi <ghazi@caip.rutgers.edu>. + * src/options.h (Options::get_initializer_suffix, + Options::initializer_suffix): New declarations. + * src/options.icc (Options::get_initializer_suffix): New function. + * src/options.cc (DEFAULT_INITIALIZER_SUFFIX): New constant. + (Options::initializer_suffix): New variable. + (Options::short_usage): Document option "-F". + (Options::long_usage): Document option "-F". + (Options constructor): Initialize initializer_suffix. + (Options destructor): Dump initializer_suffix. + (long_options): Add option "-F". + (Options::operator()): Accept option "-F". Sets initializer_suffix. + * src/key-list.cc (output_keyword_blank_entries): Output + initializer_suffix. + * doc/gperf.texi: Document option "-F". + + * COPYING: Replace with GPL version 2 (with new FSF address and Y2K + safe year format). + + * doc/gpl.texinfo: New file. + * doc/gperf.texi: Document it. + * doc/Makefile.in (gperf.info, gperf.dvi, gperf.html, gperf_toc.html): + Update dependencies. + + * doc/Makefile.in (MAKEINFO): Unset LANG while running makeinfo. + +1998-05-20 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> + + * doc/Makefile.in (gperf.dvi, clean): Remove gperf.cps. + (install, installdirs, uninstall): Don't install gperf.dvi. The + info and HTML documentations are sufficient for on-line use, and + users who wish to print the documentation (in PS or DVI format) + can do this directly off the source distribution. + (DVIPS): Use "-D600" instead of "-Pljfour", for portability. + +1998-05-20 Akim Demaille <demaille@inf.enst.fr> + + * doc/gperf.texi: Many modifications: + (Output Format): Declare `hash' and `in_word_set' as functions. + (Concept Index): New section. + (Title page): Use standard presentation. + (Top): Use @top instead of @unnumbered so that automatic master + update works. + (Motivation): Avoid spaces in @var. + (Options): Use the standard name ``Invoking ...''. + (Options): Declare also the long form of the options. + (Options): Remove redundant @itemize when @table is used. + +1998-05-08 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * aclocal.m4 (CL_PROG_INSTALL): Set cl_cv_path_install, not + ac_cv_path_install. + +Sat May 2 13:20:54 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> + + * gperf-2.7 released. + +Sat May 2 12:31:51 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> + + * src/version.cc (version_string): Remove the "(C++ version)" suffix. + It's redundant: the early C versions of gperf are called cperf. + Reported by Karl Berry. + * src/option.cc (Options::operator()): Trim the output of "gperf -v". + +Thu Apr 16 13:22:16 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> + + * lib/Makefile.in, src/Makefile.in: Don't use $(TARGET_ARCH). + Solaris "make" sets it to a value not understood by "cc". + +Wed Apr 15 23:52:14 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> + + * lib/Makefile.in, src/Makefile.in: Don't use implicit rules. Don't + use $<. AIX "make" and OSF/1 "make" have problems with both. + * src/gen-perf.cc, src/key-list.cc: Cast free() argument to char*, + otherwise it doesn't compile on SunOS 4. + * src/key-list.h: Declare structs outside of other declarations, + needed for OSF/1 cxx 5.5. + * lib/getopt.h: Use prototypes if __STDC__ || __cplusplus. + Don't give a prototype for getopt(), to avoid error on SunOS 4. + * lib/getopt.c: Declare strncmp, to avoid warnings. + +Tue Apr 14 23:24:07 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> + + * lib/GetOpt.{h,cc}: Remove files. + * lib/getopt.{h,c}, lib/getopt1.c: New files, from GNU libc. + * lib/configure.in (AC_INIT): Search for hash.cc, not GetOpt.cc. + * lib/Makefile.in (OBJECTS): Remove GetOpt.o, add getopt.o, getopt1.o. + (getopt.o, getopt1.o, hash.o): Use explicit building rules. Some + "make"s don't support to have both implicit rules for "%.o : %.c" + and "%.o : %.cc" in the same Makefile. + * lib/hash.{h,cc}: Remove #pragma; there are no templates here. + * src/option.h (Options::usage): Remove. + (Options::short_usage, Options::long_usage): Declare. + * src/option.cc (Options::usage): Remove. + (Options::short_usage, Options::long_usage): New functions. + (long_options): New array. + (Options::operator()): Use getopt_long instead of GetOpt::operator(), + change all references to GetOpt members. + + * src/std-err.{h,cc}: Remove files. + * src/gen-perf.cc, src/key-list.cc, list-node.cc, new.cc, options.cc: + Call fprintf(stderr) instead of Std_Err::report_error(). + * src/key-list.h, src/list-node.h, src/options.h: Don't use class + Std_Err any more. + * src/option.cc (program_name): New variable. + * src/Makefile.in: Remove STD_ERR_H. + (OBJECTS): Remove std-err.o. + +Mon Mar 23 01:03:35 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> + + * aclocal.m4, {lib,src,tests}/configure.in: Remove CL_CC_WORKS and + CL_CXX_WORKS, already contained in autoconf 2.12. + + * src/gen-perf.cc, src/key-list.cc: Move some code from + Gen_Perf::Gen_Perf() to Key_List::output(). + * src/Makefile.in: Update dependencies. + + * src/options.{h,cc}: Remove option "-p". + * src/key-list.cc (Key_List::set_output_types): Rewrite. + (default_array_type, default_return_type): Remove. + * src/key-list.cc: Adjust "const" handling. + + With option "-t" [TYPE], don't emit wrong code if there is no + space before the struct's opening brace. + +Sun Mar 22 16:59:15 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> + + * src/key-list.{h,cc}: Completely reorganized the output routines. + Rewrote from scratch the output_switch() function. Use classes + (Output_Constants, Output_Expr, Output_Compare) for abstraction. + In particular: + + Don't emit trailing whitespace and spurious blank lines. + + Adjust indentation of the arrays. + + Don't emit commas at the end of array initializers and + struct initializers. + + With option "-l" [LENTABLE], compare the length before + fetching the word from memory. + + With option "-S" [SWITCH], emit the comparison code just once, + not once in every switch statement. + + With option "-S" [SWITCH], choose the right switch statement + through a binary search, not a linear search. + + With option "-S" [SWITCH], emit straightforward comparisons + instead of switch statements with just one "case" label. + + With options "-S -p -t" [SWITCH, POINTER, TYPE], don't emit + spurious empty elements at the beginning of the wordlist array. + + With option "-D" [DUP] and not option "-S" [SWITCH], if there + is no more room for duplicate entries in the lookup array, + don't call `assert (i != 0)'. Instead, make the array larger :-) + + With option "-D" [DUP], if there are no duplicates, don't + automatically fall back to the non-"-D" algorithm. If the user + wants the non-"-D" algorithm, he can just not specify "-D". + + With option "-D" [DUP] and either options "-p -t" [POINTER, TYPE] + or not option "-S" [SWITCH], don't emit spurious empty elements + at the beginning of the wordlist array. + + With option "-D" [DUP], simplify the detection and processing + of duplicate entries in the lookup array. + + With options "-D -l" [DUP, LENTABLE] and not option "-S" [SWITCH], + don't forget to emit the lengthtable array. + + With options "-D -l -S" [DUP, LENTABLE, SWITCH], don't forget to + compare the lengths before comparing the strings. + + * src/gen-perf.cc: No need to include <assert.h>. + * src/options.cc: Likewise. + + * src/options.cc: Don't use `errno' after freopen failed. + * src/std-err.cc: `report_error' doesn't call strerror(errno) any + more. No need to include <string.h> and <errno.h>. + + * tests/Makefile.in (check-*): Any difference between .exp and .out + is a failure. Don't ignore whitespace differences. + + * tests/Makefile.in (check-lang-syntax): Add some more checks. + +Fri Mar 20 00:54:54 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> + + * tests/jscript.gperf: Renamed from tests/javascript.gperf, because + of Minix and SVR2 14-character filename limit. + * src/key-list.cc (output_string): New function. + (Key_List::output_switch, Key_List::output_keyword_table): Call it. + + * src/options.{h,icc,cc} (get_wordlist_name): New function. Add + option -W. + * src/key-list.cc (Key_List::output_switch, + Key_List::output_keyword_table, Key_List::output_lookup_function): + Use it. + Patch from William Bader <wbader@CSEE.Lehigh.Edu>. + + * src/version.cc: Bump version number directly from 2.5 to 2.7, + because Schmidt's last release from 1991 carries version number 2.6. + +Tue Jul 30 00:02:39 1991 Douglas C. Schmidt (schmidt at net4.ics.uci.edu) + + * Fixed a small bug in the Key_List::output_keyword_table routine + that caused an extra newline to be printed if there where no + leading blank entries... (who cares, right?!) + +Mon Jul 29 22:05:40 1991 Douglas C. Schmidt (schmidt at net4.ics.uci.edu) + + * Modified the handling of the -E (emit enums rather than + #defines) option in conjunction with the -G option. Now, if -G + and -E are given the enums are generated outside the lookup + function, rather than within it! + +Mon Apr 8 18:17:04 1991 Doug Schmidt (schmidt at net4.ics.uci.edu) + + * Yucko, there was a bug in the handling of -c (and of course the + new -I command in key-list.cc). Apparently when I added the + super-duper hack that provided support for duplicate keys I + forgot to update the strcmp output... + +Mon Mar 9 02:19:04 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> + + * Moved the documentation to doc/, put the stuff borrowed from + libg++ into lib/. + * Rewrote all Makefile.in's for better compliance with GNU standards. + * Autoconf based configuration. Rewrote all configure.in's. Added + aclocal.m4, with macros from CLISP and CLN. Added Makefile.devel. + * src/depend: Removed. Dependencies are now in src/Makefile.in. + + * src/bool-array.icc: New file, contains inline functions, from both + src/bool-array.h and src/bool-array.cc. + * src/options.icc: New file, contains inline functions, from both + src/options.h and src/options.cc. + * src/read-line.icc: New file, contains inline functions, from both + src/read-line.h and src/read-line.cc. + + * src/bool-array.h: Don't include <std.h>. + * src/bool-array.cc: Include <string.h>. + * src/gen-perf.cc: No need to include <ctype.h>. Don't include + <_G_config.h>. + * src/hash-table.cc: Don't include <std.h> and <builtin.h>. Include + <string.h> and lib/hash.h instead. + * src/iterator.cc: Don't include <std.h>. + * src/key-list.cc: Don't include <builtin.h>. Include <string.h> and + <stdlib.h> instead. + * src/list-node.cc: Don't include <std.h>. Include <stdlib.h> instead. + Remove `index' hack. + * src/main.cc: Don't include <_G_config.h>. + * src/new.cc: Don't include <std.h>. Include <stdlib.h> instead. + * src/options.cc: Don't include <builtin.h>. Include <string.h> and + <stdlib.h> instead. + * src/read-line.cc: Don't include <builtin.h>. Include <stdlib.h> + instead. + * src/std-err.cc: Don't include <std.h>. Include <string.h> (for Irix). + * src/vectors.h: No need to include <stdio.h>. + * src/version.cc: No need to include <stdio.h>. + + * src/bool-array.h: Change `STORAGE_TYPE' from int to unsigned int. + * src/bool-array.{h,cc}: Change type of `Bool_Array::size' from int + to unsigned int. + * src/bool-array.{h,cc}: Change type of `Bool_Array::init' argument + from STORAGE_TYPE to unsigned int. + * src/gen-perf.{h,cc}: Change two `Gen_Perf::compute_disjoint_union' + argument types from `char *' to `const char *'. + * src/iterator.h: Change type of `Iterator::str' and argument of + `Iterator::Iterator' from `char *' to `const char *'. + * src/iterator.cc: Cast to `unsigned char' before calling `isdigit'. + * src/key-list.{h,cc}: Change type of `Key_List::array_type', + `Key_List::return_type', `Key_List::struct_tag', + `Key_List::include_src', `default_array_type', `default_return_type' + and return type of `Key_List::get_array_type', + `Key_List::get_special_input', `Key_List::save_include_src' from + `char *' to `const char *'. + * src/key-list.cc: Change "pretty gross" assignment. + * src/key-list.cc: Don't use `alloca', HP-UX CC lacks it. + * lib/GetOpt.cc: Likewise. + * src/key-list.cc (merge): Use iteration instead of recursion. + * src/list-node.{h,cc}: Change type of `List_Node::key', + `List_Node::rest', `List_Node::char_set' from `char *' to + `const char *'. + * src/new.cc: Don't use BUFSIZ. Conditionalize the throw() declaration. + * src/read-line.h: Don't use BUFSIZ. + * src/read-line.cc: Make CHUNK_SIZE a constant, and use allocate the + buffers on the stack by default. Use memcpy for copying buffers. + Include <string.h>. + * src/read-line.icc (get_line): Use iteration instead of tail recursion. + Don't call ungetc(EOF,stdin). + * src/std-err.{h,cc}: Change type of `Std_Err::program_name' and of + argument `Std_Err::report_error' from `char *' to `const char *'. + * src/std-err.cc: `report_error' doesn't call `exit' any more. All + callers changed to do that themselves. + * src/trace.h: Make constructor/destructor calls non-inline. + + * src/key-list.cc (output_hash_function): If option[CPLUSPLUS], + always make the hash function inline. + (output): Declare the hash function inline, with the right name. + * src/options.{h,cc}, src/gen-perf.cc, src/key-list.cc: Remove + options -g, making it on by default. Remove option -a. Instead, + introduce "-L KR-C", "-L C", "-L ANSI-C", "-L C++". + * src/options.{h,cc}, src/key-list.cc: Add option -I. + * src/key-list.cc: Don't emit "const" if compiling in mode "-L KR-C". + * src/key-list.cc: Don't emit a comma at the end of an enum list. + * src/main.cc: Remove COUNT_TIME code. + * src/vectors.h, src/key-list.cc, src/options.cc, src/list-node.cc: + ALPHA_SIZE defaults to 256 now. Add option -7. + + * tests/javascript.gperf: New file. + * tests/jstest*.gperf, tests/validate: New tests. + +Sat Jan 31 01:38:11 1998 Alexandre Oliva <oliva@dcc.unicamp.br> + + * src/Makefile.in ($(TARGETPROG)): Add $(CFLAGS). + +Wed Jan 28 01:56:00 1998 Manfred Hollstein <manfred@s-direktnet.de> + + * configure.in (package_makefile_rules_frag): New and + redirect stderr from ${srcdir}/config.shared to + ${package_makefile_rules_frag}. + * src/configure.in: Ditto. + * tests/configure.in: Ditto. + +Fri Jan 23 08:00:41 1998 H.J. Lu (hjl@gnu.org) + + * gperf.texi (@ichapter): Changed to @chapter. + +Wed Jan 14 09:16:48 1998 H.J. Lu (hjl@gnu.org) + + * src/key-list.cc, src/key-list.h (Key_List::strcspn): Don't + define if strcspn is defined. + +Fri Jan 24 13:23:47 1997 Mike Stump <mrs@cygnus.com> + + * src/new.cc (operator delete): Add the exception specification. + +Mon Feb 5 19:29:16 1996 Per Bothner <bothner@kalessin.cygnus.com> + + * src/read-line.cc (Read_Line::readln_aux): Handle EOF if last line + has a length which is an exact multiple of CHUNK_SIZE. (Used to throw + away the line's contents.) From Bruno Haible <haible@ilog.ilog.fr>. + * src/Makefile.in ($(TARGETPROG)): Add -lm to link line. + +Tue Jun 11 13:43:50 1996 Brendan Kehoe <brendan@lisa.cygnus.com> + + * src/list-node.cc (List_Node): Reorder init of nodes to + match declaration order. + * src/hash-table.cc (Hash_Table): Likewise. + +Tue Oct 10 16:37:28 1995 Mike Stump <mrs@cygnus.com> + + * src/new.cc: Since malloc/delete are not paired, we cannot call + free. + +Wed Jan 4 12:40:14 1995 Per Bothner <bothner@kalessin.cygnus.com> + + * src/Makefile.in ($(TARGETPROG)): Link with $(LDFLAGS). + Patch from John Interrante <interran@uluru.stanford.edu>. + +Sat Nov 5 19:12:48 1994 Jason Merrill (jason@phydeaux.cygnus.com) + + * src/Makefile.in (LIBS): Remove. + +Tue Oct 18 17:51:14 1994 Per Bothner <bothner@kalessin.cygnus.com> + + * src/std-err.cc: Use stderror, instead of the non-standard + sys_nerr and sys_errlist. + +Sat Sep 17 22:02:13 1994 Per Bothner (bothner@kalessin.cygnus.com) + + * src/key-list.cc (output_hash_function): + Patch from William Bader <wbader@CSEE.Lehigh.Edu>. + +Fri Jul 15 09:38:11 1994 Per Bothner (bothner@cygnus.com) + + * src/std-err.cc: #include <errno.h>, and only declare + extern int errno if errno is not a macro. + +Mon May 30 17:29:34 1994 Per Bothner (bothner@kalessin.cygnus.com) + + * Makefile.in (src_all, install): Make sure to add '/' after + `pwd` in $rootme, as expected by FLAGS_TO_PASS. + +Wed May 11 00:47:22 1994 Jason Merrill (jason@deneb.cygnus.com) + + Make libg++ build with gcc -ansi -pedantic-errors + * src/options.h: Lose commas at end of enumerator lists. + +Sun Dec 5 19:16:40 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * src/hash-table.cc (Hash_Table::~Hash_Table): Don't pass an + argument to fprintf, since it's not expecting one. + +Fri Nov 26 19:03:18 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * src/list-node.cc: #undef index, for the sake of broken NeXT, + +Thu Nov 4 11:16:03 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * Makefile.in (install): Use INSTALL_DATA for gperf.1. + +Mon Oct 25 18:40:51 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * src/key-list.cc (Key_List::read_keys): Use POW macro + to increase hash table size to power of 2. + + * options.h (LARGE_STACK_ARRAYS): New flag. Defaults to zero. + * gen-perf.cc, key-list.cc, read-line.cc: + Only stack-allocate large arrays if LARGE_STACK_ARRAYS is set. + * main.cc (main): Only call setrlimit (RLIMIT_STACK, ...) + if LARGE_STACK_ARRAYS. + +Mon Oct 4 17:45:08 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * src/gen-perf.cc: Always use ANSI rand/srand instead of BSDisms. + +Wed Aug 18 12:19:53 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * Makefile.in (src_all): Make less verbose output. + +Fri May 28 14:01:18 1993 Per Bothner (bothner@rtl.cygnus.com) + + * src/gen-perf.cc (Gen_Perf::change): Don't use gcc-specific + 2-operand conditional expression. + * src/key-list.cc (Key_List::output_lookup_array): + Don't use variable-size stack arrays, unless compiled by g++. + +Tue May 4 14:08:44 1993 Per Bothner (bothner@cygnus.com) + + Changes (mostly from Peter Schauer) to permit compilation + using cfront 3.0 and otherwise be ARM-conforming. + * src/key-list.h: class Key_List must use public derivation + of base class Std_Err (because Gen_Perf::operator() in gen-perf.cc + calls Std_Err::report_error). + * src/gen-perf.cc (Gen_Perf::affects_prev), src/hash-table.cc + (Hash_Table::operator()): Don't use gcc-specific 2-operand + conditional expression. + * src/iterator.cc (Iterator::operator()): Don't use gcc-specific + range construct in case label. + * key-list.cc (Key_List::output_lookup_array, Key_List::read_keys), + src/gen-perf.cc (Gen_Perf::operator(), src/read-line.cc + (Read_Line::readln_aux): If not gcc, don't allocate + variable-sized arrays on stack. + * src/new.cc (operator new): Argument type should be size_t. + * key-list.cc (Key_List::output_lookup_array, Key_List::read_keys), + new/cc (::operator new): Don't use non-standard >?= operator. + +Tue Apr 27 20:11:30 1993 Per Bothner (bothner@cygnus.com) + + * src/Makefile.in: Define TARGETPROG, and use it. + +Mon Apr 19 00:29:18 1993 Per Bothner (bothner@cygnus.com) + + * Makefile.in, configure.in: Re-vamped configure scheme. + * gperf.texinfo: Renamed to gperf.texi. + * src/bool-array.{h,cc}: ANSIfy bzero->memset. + +Sat Jan 30 20:21:28 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * tests/Makefile.in (mostlyclean): Also delete aout, cout, m3out, + pout, and preout. + +Tue Dec 29 08:58:17 1992 Ian Lance Taylor (ian@cygnus.com) + + * Makefile.in: pass $(FLAGS_TO_PASS) to all calls to make. + (FLAGS_TO_PASS): added INSTALL, INSTALL_DATA, INSTALL_PROGRAM. + +Mon Dec 21 18:46:46 1992 Per Bothner (bothner@rtl.cygnus.com) + + * tests/expected.* renamed to *.exp to fit in 14 chars. + * tests/Makefile.in: Update accordingly. + Also rename output.* to *.out. + * src/Makefile.in (clean): Remove gperf program. + +Wed Dec 9 14:33:34 1992 Per Bothner (bothner@cygnus.com) + + * src/hash-table.cc, src/bool-array.h: ANSIfy bzero->memset. + +Thu Dec 3 19:34:12 1992 Per Bothner (bothner@cygnus.com) + + * Makefile.in (distclean, realclean): Don't delete + Makefile before recursing. + +Fri Nov 6 13:41:49 1992 Per Bothner (bothner@rtl.cygnus.com) + + * key-list.{h,cc}: Remove MAX_INT (and similar) constant + fields from Key_List class, and use INT_MAX (etc) from limits.h. + * key-list.{h,cc}, options.{h,cc}, vectors.h: Removed all + uses of initialized const fields, as they are non-standard + - and their use was easy to do away with. Mostly, just + made the constants static non-fields in the .cc file. + +Mon Nov 2 13:10:11 1992 Per Bothner (bothner@cygnus.com) + + * tests/Makefile.in: When generating cinset.c, don't pass -C, + since -C assumes an ANSI compiler. Add the -C flag (with -a) + when generating test.out.3 instead. + * tests/expected.out.3: Update accordingly. + +Wed Aug 12 11:47:54 1992 Per Bothner (bothner@cygnus.com) + + * Makefile.in: Factor out common flags into $(FLAGS_TO_PASS). + * Makefile.in: 'install-info' depends on gperf.info. + +Mon Aug 10 11:39:52 1992 Ian Lance Taylor (ian@dumbest.cygnus.com) + + * Makefile.in, src/Makefile.in: always create installation + directories. + +Mon Jul 20 15:33:21 1992 Mike Stump (mrs@cygnus.com) + + * src/new.cc (operator new): Add cast from void * to char *, + since it is not a standard conversion. + +Wed Jun 17 16:25:30 1992 Per Bothner (bothner@rtl.cygnus.com) + + * src/gen-perf.cc: #include <_G_config.h> for _G_SYSV. + * src/key-list.cc: alloca() hair. + * src/main.cc (main): Only call getrlimit if _G_HAVE_SYS_RESOURCE. + * Makefile,in, {src,test}/Makefile.in: Fix *clean rules. + +Fri May 29 13:21:13 1992 Per Bothner (bothner@rtl.cygnus.com) + + * src/gen-perf.cc: Replace USG -> _G_SYSV. + +Thu May 14 13:58:36 1992 Per Bothner (bothner@rtl.cygnus.com) + + * src/Makefile.in: Don't pass obsolete flag -DUNLIMIT_STACK. + * tests/Makefile.in (clean): Fix. + +Sat Mar 7 00:03:56 1992 K. Richard Pixley (rich@rtl.cygnus.com) + + * gperf.texinfo: added menu item hook. + +Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com) + + * Makefile.in, configure.in: removed traces of namesubdir, + -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced + copyrights to '92, changed some from Cygnus to FSF. + +Sun Jan 26 19:21:58 1992 Per Bothner (bothner at cygnus.com) + + * tests/Makefile.in: Use re-directed stdin instead of file + name in argv. This allows us to remove the filename + from the output, the expected output, and hence the diffs. + (Note that the input file is in $(srcdir), which we cannot + place in the expected out files.) + * tests/expected.out.[1235]: Edit out input filename, + to match new output. + +Thu Jun 28 16:17:27 1990 Doug Schmidt (schmidt at brilliant) + + * Wow, first fix on the new job! There was a dumb error + in Key_List::output_lookup_function, where I printed the + string "&wordlist[key]" instead of the correct "&wordlist[index]". + + * Added a couple of #ifdefs for USG support. + +Sun Jun 3 17:16:36 1990 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Updated the version number to 2.5 and sent to Doug Lea for release + with the latest GNU libg++. + + * Changed the error handling when a keyword file cannot be opened + (now calls perror). + +Wed May 30 14:49:40 1990 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Instrumented the source code with trace statements automagically + inserted using my new automated trace instrumentation tool! + +Wed May 9 11:47:41 1990 Doug Schmidt (schmidt at siam.ics.uci.edu) + + * Really fixed the previous bug. Turns out that a small amount + of logic had to be duplicated to handle static links that occur + as part of dynamic link chains. What a pain!!! + +Tue May 8 23:11:44 1990 Doug Schmidt (schmidt at siam.ics.uci.edu) + + * Fixed a stupid bug in Key_List::output_lookup_array that was + causing incorrect counts to be generated when there were both + static and dynamic links occurring for the same hash value. + Also simplified the code that performs the logic in this routine. + +Mon Apr 30 17:37:24 1990 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Fixed stupid bug in Key_List::output_lookup_array that was + making the generated lookup[] array contain `chars' even + when the values stored in the chars are greater than 127! + + * Changed the behavior of the -G (global table) option so that it + will output the `length[]' array in the global scope along with + the `word_list[]' array. + + * Fixed a stupid bug in Key_List::output_lookup_function that + would always output the complicated `duplicate-handling' lookup + logic, even when there were no duplicates in the input! + + * Yikes, had to modify a bunch of stuff in key-list.cc to correctly + handle duplicate entries. Changed the generated code so that + the MIN_HASH_VALUE is no longer subtracted off when calculating + the hash value for a keyword. This required changing some other + code by substituting MAX_HASH_VALUE for TOTAL_KEYS in several places. + Finally, this means that the generated tables may contain leading + null entries, but I suppose it is better to trade-off space to get + faster performance... + +Mon Mar 26 13:08:43 1990 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Updated version number to 2.4 to reflect the latest changes. + + * Changed the main program so that it always prints out gperf's + execution timings to the generated output file. + +Sun Mar 25 12:39:30 1990 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Added the -Z option so that users can specify the name of the + generated class explicitly. Updated documentation to reflect + this change. + + * Modified the generated C++ class interface so that the functions + are declared static (to remove the overhead of passing the `this' + pointer). This means that operator()() can no longer be used, + since it only works on non-static member functions. + Also changed things so that there is no constructor (why waste + the extra call, when it doesn't do anything, eh?) + + * Modified the behavior of Key_List::output when the -L C++ option + is enabled. Previously the code generated use const data members + to record MIN_WORD_LENGTH, MIN_HASH_VALUE, etc. However, as + pointed out by James Clark this may result in suboptimal behavior + on the part of C++ compilers that can't inline these values. + Therefore, the new behavior is identical to what happens with + -L C, i.e., either #defines or function-specific enums are used. + Why sacrifice speed for some abstract notion of `code purity?' ;-) + +Tue Mar 6 18:17:42 1990 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Added the -E option that defines constant values using an enum + local to the lookup function rather than with #defines. This + also means that different lookup functions can reside in the + same file. Thanks to James Clark (jjc@ai.mit.edu). + +Sat Mar 3 20:19:00 1990 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Added a special case to key_list::output_switch that doesn't + generate extra comparisons when the `-S' is given an argument + of 1 (the normal case). This should speed up the generated + code output a tad... + +Fri Feb 23 14:21:28 1990 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Renamed all instances of member function get_keysig_size + to get_max_keysig_size, since this is more precise... + + * Changed all occurrences of charset to keysig (stands for ``key + signature'') to reflect the new naming convention used in the + USENIX paper. + +Thu Feb 22 11:28:36 1990 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Changed the name of the generated associated values table from + asso_value to asso_values to reflect conventions in the USENIX + C++ paper. + +Thu Feb 15 23:29:03 1990 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Updated the gperf.texinfo file to fix some formatting problems + that had crept in since last time. + +Wed Feb 14 23:27:24 1990 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Fixed stupid bug in key-list.cc (get_special_input), wher + gperf replaced each '%' with the succeeding character. + + * Added support for multiple target language generation. Currently + handled languages are C and C++, with C as the default. Updated + documentation and option handler to reflect the changes. + + * Added a global destructor to new.cc and removed the #ifdef, since + the bloody thing now works with libg++. + +Mon Feb 14 13:00:00 1990 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Found out that my gperf paper was accepted at the upcoming + USENIX C++ Conference in San Francisco. Yow! + +Tue Jan 30 09:00:29 1990 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * #ifdef'd out the new.cc memory allocator, since there are + problems with this and the libg++ stuff. + + * Changed key-list.h so that class Vectors is a public (rather + than private) base class for class Key_List. The previous + form was illegal C++, but wasn't being caught by the old + g++ compiler. Should work now... ;-) + +Sun Dec 10 14:08:23 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added several changes from rfg@ics.uci.edu. These changes + help to automate the build process. + +Wed Nov 15 15:49:33 1989 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Removed conditional compilation for GATHER_STATISTICS. There's + really no good reason to avoid collecting this info at run-time, + since that section of code is *hardly* the bottleneck... ;-) + + * Simplified the C output routines in Key_List::set_output_types + and Key_List::output_keyword_table a bit in order to + speed-up and clean up the code generation. + + * Modified function Key_List::get_special_input so that it does + not try to `delete' a buffer that turned out to be too short. + This is important since the new memory management scheme + does not handle deletions. However, adding a small amount of + garbage won't hurt anything, since we generally don't do this + operation more than a couple times *at most*! + + * Created a new file (new.cc) which includes my own overloaded + operator new. This function should dramatically reduce the + number of calls to malloc since it grabs large chunks and + doles them out in small pieces. As a result of this change + the class-specific `operator new' was removed from class List_Node. + +Tue Nov 14 21:45:30 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Continued to refine the great hack. The latest trick is to + try and replace most uses of dynamic memory (i.e., calls to + new) with uses of gcc dynamic arrays (i.e., an alloca solution). + This makes life much easier for the overall process-size, since + it reduces the amount of overhead for memory management. As a + side-effect from this change there is no reason to have the + Bool_Array::dispose member function, so it's outta here! + + * Fixed a stupid bug that was an disaster waiting to happen... + Instead of making the boolean array large enough to index + max_hash_value it was only large enough to index max_hash_value + - 1. Once again, an off-by-one mistake in C/C++!!!! + +Mon Nov 13 19:38:27 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added the final great hack! This allows us to generate hash tables + for near-perfect hash functions that contain duplicates, *without* + having to use switch statements! Since many compilers die on large + switch statements this feature is essential. Furthermore, it appears + that the generated code is often *smaller* than that put out by + compilers, even though a large, sparse array must be created. + Here's the general idea: + + a. Generate the wordlist as a contiguous block of keywords, + just as before when using a switch statement. This + wordlist *must* be sorted by hash value. + + b. Generate the lookup array, which is an array of signed + {chars,shorts,ints}, (which ever allows full coverage of + the wordlist dimensions). If the value v, where v = + lookup[hash(str,len)], is >= 0 and < TOTAL_KEYWORDS, then we + simply use this result as a direct access into the wordlist + array to snag the keyword for comparison. + + c. Otherwise, if v is < -TOTAL_KEYWORDS or > TOTAL_KEYWORDS + 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 different part of + the hash table that provides the starting index and total + length of the duplicate entries to find via linear search! + +Sun Nov 12 13:48:10 1989 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Simplified Key_List::output_min_max considerably by recognizing + that since the keyword list was already sorted by hash value finding + the min and max values is trivial! + + * Improved the debugging diagnostics considerably in classes Key_List, + Hash_Table, and Gen_Perf. + + * Modified the `-s' option so that a negative argument is now + interpreted to mean `allow the maximum associated value to be + about x times *smaller* than the number of input keys.' This + should help prevent massive explosion of generated hash table + size for large keysets. + +Sat Nov 11 11:31:13 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added a field in class Key_List that counts the total number + of duplicate keywords, both static and dynamic. + + * Added a new member function Bool_Array that deletes the dynamic + memory allocated to Bool_Array::storage_array. This space may + be needed for subsequent options, so it made sense to free it as + soon as possible... + + * Renamed file/class Alpha_Vectors to Vectors, to avoid problems + with 14 character length filenames on SYSV. Also changed file + adapredefined.gperf to adadefs.gperf in the ./tests directory. + + * Modified class Options by changing the member function + Options::total_positions to Options::get_charset_size and + Options::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. + + * Merged all the cperf changes into gperf. + + * Made sure to explicitly initialize perfect.fewest_collisions to + 0. + + * Cleaned up some loose ends noticed by Nels Olson. + 1. Removed `if (collisions <= perfect.fewest_collisions)' + from Gen_Perf::affects_prev since it was superfluous. + 2. Removed the fields best_char_value and best_asso_value + from Gen_Perf. There were also unnecessary. + 3. Fixed a braino in the Bool_Array::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. Modified Std_Err::report_error so that it correctly handles + "%%". + + * 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 Key_List::print_switch so that if finally + seems to work correctly. Needs more stress testing, however... + + * Made a major change to the Key_List::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 Key_List::length function to Key_List::keyword_list_length. + + * 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 hash-table.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. + + * Fixed a stupid bug in Key_List::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 Bool_Array::~Bool_Array destructor 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 constructor Hash_Table::Hash_Table. This + constructor now passed a pointer to a power-of-two sized buffer that + serve 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 Key_List::read_keys calling + interface. + + * Since alloca is now being used more aggressively a conditional + compilation section was added 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. + + * Added warnings in option.c so that user's would be informed + that -r superceeds -i on the command-line. + + * Rewrote Gen_Perf::affects_prev. First, the code structure + was cleaned up considerably (removing the need for a dreaded + goto!). Secondly, a major change occurred so that Gen_Perf::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 Gen_Perf::change routine + 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 new in the Gen_Perf::change function. + This should eliminate some overhead at the expense of a little + extra memory that is never reclaimed. + + * Renamed Gen_Perf::merge_sets to Gen_Perf::compute_disjoint_union + to reflect the change in behavior. + + * 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 Gen_Perf::compute_disjoint_sets 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 Key_List::print_switch + A right paren was placed at the wrong location, which broke + strlen (). + 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. Changed the behavior of Key_List::read_keys 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. + 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 Gen_Perf 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 Gen_Perf::affect_prev doesn't + waste time trying to change an associated value that is + shared between two conflicting keywords. + 9. Modified Gen_Perf::affects_prev so that it doesn't try + random jump values unless the -j 0 option is enabled. + 10. Fixed a silly bug in Gen_Perf::change. This problem caused + gperf to seg fault when the -k* option was given and the + keyfile file had long keywords. + +Sun Oct 29 00:18:55 1989 Doug Schmidt (schmidt at siam.ics.uci.edu) + + * Modified class-specific new operations for Read_Line and + List_Node so they don't fail if SIZE is larger than twice + the previous buffer size. Note we double buffer size + everytime the previous buffer runs out, as a heuristic + to reduce future calls to malloc. + +Sun Oct 22 13:49:43 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Updated gperf version number to 2.0. Send to Doug Lea for + incorporation into the long-awaited `official' libg++ 1.36 + release! + + * Thanks to Nels Olson a silly bug in Gen_Perf::change () + was fixed. This problem caused gperf to seg fault when + the -k* option was given and the keyfile file had long + keywords. + + * Modified Key_List::print_hash_function so that it output + max_hash_value + 1 (rather than just max_hash_value) for + any associated value entries that don't correspond to + keyword charset characters. This should speed up rejection + of non-keyword strings a little in some cases. + +Sat Oct 21 19:28:36 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Fixed Key_List::print_hash_function so that it no longer output + things like `return 0 + ...' Although this probably gets + optimized away by even the worst C compilers there isn't any + point tempting fate... ;-) + + * Fixed class List_Node's constructor so that it wouldn't a priori + refuse to consider trying to hash keys whose length is less + than the smallest user-specified key position. It turns out + this is not a problem unless the user also specifies the -n + (NOLENGTH) option, in which case such keys most likely + don't have a prayer of being hashed correctly! + + * Changed the name of the generated lookup table from `Hash_Table' + to `asso_value' to be consistent with the gperf paper. + +Tue Oct 17 14:19:48 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added a flag GATHER_STATISTICS in the Makefile. If defined + during compilation this turns on certain collection facilities + that track the performance of gperf during its execution. In + particular, I want to see how many collisions occur for the + double hashing Hash_Table. + + * Added a safety check so that we don't screw up if the total + number of `resets' of the Bool_Array exceeds MAX_INT. Since + this number is around 2^31 it is unlikely that this would ever + occur for most input, but why take the risk? + + * 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... + +Mon Oct 16 11:00:35 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Continued to work on the gperf paper for the USENIX C++ + conference. At some point this will be merged back into + the gperf documentation... + +Sat Oct 14 20:29:43 1989 Doug Schmidt (schmidt at siam.ics.uci.edu) + + * 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 allocation 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! + +Mon Oct 2 12:30:54 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Changed some consts in options.h to enumerals, since g++ + doesn't seem to like them at the moment! + +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). + + * 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; + +Tue Sep 26 10:36:50 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Changed class Read_Line's definition so that it no longer + needs to know about the buffering scheme used to speed up + dynamic memory allocation of input keywords and their + associated attributes. This means that operator new is no longer + a friend of Read_Line. + +Mon Sep 25 23:17:10 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Decided that Obstacks had too much overhead, so they were + removed in favor of super-efficient, low-overhead buffered + storage allocation hacks in Read_Line and List_Node. + + * No longer try to inline functions that g++ complains about + (Key_List::Merge and Key_List::Merge_Sort). + +Sun Sep 24 13:11:24 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Changed classes Read_Line and List_Node to use Obstacks in order + to cache memory allocation for keyword strings and List_Nodes. + + * Continued to experiment with inheritance schemes. + + * Added a new file `alpha.h', that declares static data shared + (i.e., inherited) between classes List_Node and Key_List. + +Tue Sep 12 16:14:41 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Made numerous changes to incorporate multiple inheritance in + gperf. + +Wed Aug 16 23:04:08 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added the -DCOMPILER_FIXED flag to the ./src/Makefile. This + implies that people trying to compile gperf need to have a + working version of the new g++ compiler (1.36.0). + + * Removed some extra spaces that were being added in the generated + C code. + +Mon Jul 24 17:09:46 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * 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 typo in PRINT_KEYWORD_TABLE in keylist.cc that prevented + the indentation from working correctly. + + * Fixed a horrible typo in PRINT_KEYWORD_TABLE in keylist.cc + that prevented links from being printed correctly. + +Tue Jul 18 16:04:31 1989 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Fixed up readline.cc and readline.h so that they work OK + with g++ compilers that aren't completely up-to-date. + If symbol COMPILER_FIXED is defined then the behavior + that works on my more recent version of g++ is enabled. + +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 21:52:15 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * 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. + + * Added the "#" feature, that allows comments inside the keyword + list from the input file. Comment handling takes place in readline.c. + This simplifies the code and reduces the number of malloc calls. + + * 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). + +Thu Jun 22 20:39:39 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Modified many classes so that they would inherit Std_Err as + a base class. This makes things more abstract... + +Fri Jun 16 14:23:00 1989 Doug Schmidt (schmidt at zola.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. + +Tue Jun 6 17:53:27 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added the -c (comparison) option. Enabling this + will use the strncmp function for string comparisons. + The default is to use strcmp. + + * Fixed a typo in key_list.cc (PRINT_SWITCH). This caused + faulty C code to be generated when the -D, -p, and -t + options were all enabled. + +Thu May 25 14:07:21 1989 Doug Schmidt (schmidt at siam.ics.uci.edu) + + * Once again, changed class Read_Line to overload global operator + new. Hopefully, this will work...! + +Sun May 21 01:51:45 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Modified Key_List::print_hash_function () so that it properly + formats the associated values in the hash table according to + the maximum number of digits required to represent the largest + value. + + * Removed the named return value from class Hash_Table's + operator (), since this causes a seg fault when -O is enabled. + No sense tripping subtle g++ bugs if we don't have to.... ;-) + + * Removed the operator new hack from Read_Line, since this seemed + to create horrible bus error problems. + + * Changed many class member functions and data members to be `static', + if they don't manipulate this! + +Fri May 12 23:06:56 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Changed class Std_Err to use static member functions, a la + Ada or Modula 2. This eliminates the need for an explicit + error-handler class object. + + * Added the ``named return value'' feature to Hash_Table::operator () + and Bool_Array::operator [], just for the heck of it.... ;-) + + * Changed the previous hack in Read_Line so that we now use + the overloaded global `new' instead of NEW_STRING! + +Wed May 3 17:36:55 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. + + * Modified the GNU getopt.cc routine to have a class-based interface. + + * Fixed a typo in Perfect.cc ~Perfect that prevented the actual maximum + hash table size from being printed (maybe the stream classes + weren't so bad after all.... ;-). + + * 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) + + * Added an efficiency hack to Read_Line. Instead of making + a call to operator NEW (a.k.a. malloc) for each input string + a new member function NEW_STRING stores a large buffer from + which new strings are carved out, growing the buffer if + necessary. It might be useful to add this throughout the + program.... + + * Removed all unnecessary calls to DELETE. If the program is about + to exit it is silly to waste time freeing memory. + + * Added the GNU getopt program to the distribution. This makes + GPERF portable to systems that don't include getopt in libc. + + * Added a strcspn member to class Key_List. This also increases + portability. + + * Added the get_include_src function from keylist.c as a member + function in class Key_List. Hopefully every function is + now associated with a class. This aids abstraction and + modularity. + + * Ported gperf to C. From now on both K&R C and GNU G++ versions + will be supported. There will be two ChangeLog files, one + for each version of the program. + +Mon May 1 16:41:45 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Fixed a bug with -k'*'. This now prints out *all* the cases + up to the length of the longest word in the keyword set. + +Sun Apr 30 12:15:25 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Removed all use of the stream classes. Too ugly, slow, and + not handled by the c++-mode formatter.... + + * Modified the handling of links (i.e., keywords that have + identical hash values as other keywords). This should + speed up hash function generation for keyword sets with + many duplicate entries. The trick is to treat duplicate + values as equivalence classes, so that each set of duplicate + values is represented only once in the main list processing. + + * Fixed some capitialization typos and indentations mistakes in + Key_List::print_hash_function. + +Sat Apr 29 12:04:03 1989 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Fixed a typo/logico in Key_List::print_switch that prevented + the last keyword in the keyword list to be print out. This + requires further examination..... + + * Fixed a stupid bug in List_Node::List_node. If the -k'*' option + was enabled the KEY_SET string wasn't getting terminated with + '\0'! + +Fri Apr 28 12:38:35 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Renamed strexp.h and strexp.cc to iterator.h and iterator.cc. + Also changed the strexp class to iterator. Continued to work + on style... + + * Updated the version number to 1.6. This reflects all the + recent changes. + +Thu Apr 27 00:14:51 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added the -D option that properly handles keyword sets that + contain duplicate hash values. + + * Continued the stylistic changes. Added the #pragma once + directive to all the *.h files. Removed all #defines and + replaced them with static consts. Also moved the key_sort + routine from options.cc into the options class as a + member function. + +Mon Apr 3 13:26:55 1989 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Made massive stylistic changes to bring source code into + conformance with GNU style guidelines. + +Thu Mar 30 23:28:45 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Fixed up the output routines so that they generate code + corresponding to the GNU style guidelines. + +Sat Mar 11 13:12:37 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Fixed Stderr constructors so that they wouldn't try to + use the base class initializer syntax for the static + class variable Program_Name. G++ 1.34 is stricter in + enforcing the rules! + +Fri Mar 10 11:24:14 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Removed -v and ``| more'' from the Makefile to keep rfg happy... + +Thu Mar 2 12:37:30 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Sent latest GNU gperf version 1.5 to Doug Lea for inclusion + into libg++ 1.34. Note that there is a small bug with + the new %{ ... %} source inclusion facility, since it doesn't + understand comments and will barf if %{ or %} appear nested + inside the outermost delimiters. This is too trivial of + a defect to fix at the moment... + +Tue Feb 28 11:19:58 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added the -K option, which allows the user to provide a + alternative name for the keyword structure component. + The default is still ``name.'' + + * Added the LEX and YACC-like ability to include arbitrary + text at the beginning of the generated C source code output. + This required two new functions Get_Special_Input, + Key_List::Save_Include_Src; + + * Fixed memory allocation bug in Key_List::Set_Types. + Variable Return_Type needs 1 additional location + to store the "*" if the -p option is used. + + * Added code to NULL terminate both Struct_Tag and Return_Type, + *after* the strncpy (stupid mistake). + +Mon Feb 27 14:39:51 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added a new option -N. This allows the user to specify the + name to be used for the generated lookup function. The + default name is still ``in_word_set.'' This makes it + possible to completely automate the perfect hash function + generation process! + +Mon Feb 20 23:33:14 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Corrected the Hash_Table::operator () function so that + *it* is responsible for deciding when a new key has the + same signature as a previously seen key. The key length + information is now used internally to this function to + decide whether to add to the hash table those keys with + the same key sets, but different lengths. Before, this + was handled by the Key_List::Read_Keys function. However, + this failed to work for certain duplicate keys, since + they weren't being entered into the hash table properly. + +Sun Feb 19 16:02:51 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Modified class Options by moving the enum Option_Type out + of the class. This is to satisfy the new enumeration + scope rules in C++. + +Sun Jan 15 15:12:09 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Incremented the version number upto 1.4 to reflect the new + options that affect the generated code. Send the new + distribution off to Michael for use with g++ 1.33. + + * Added a fix to Key_List::Read_Keys so that it checks for links + properly when the -n option is used. Previously, it didn't + catch obvious links, which caused it to spend large amount + of time searching for a solution that could never occur! + + * Modified the Key_List data structure to record *both* the + minimum and the maximum key lengths. This information + is now computed in Key_List::Read_Keys, and thus + Key_List::Print_Min_Max doesn't need to bother. + + * Modifed the key position iterator scheme in options.cc to + eliminate the need for member function Options::Advance. + Now, the Options::Get function performs the advancement + automatically, obviating the need for an extra function call. + + * Added the new function Options::Print_Options, to print out + the user-specified command line options to generated C + output file. + + * Added a new function, Key_List::Print_Keylength_Table, + which creates a table of lengths for use in speeding + up the keyword search. This also meant that a new + option, -l (LENTABLE) is recognized. It controls + whether the length table is printed and the comparison + made in the generated function ``in_word_set.'' + + * Added a comment at the top of the generated C code + output file that tells what version of gperf was used. + Next, I'll also dump out the command line options + as a comment too. Thanks to Michael Tiemann for the + feedback on this. + + * Fixed the -n option to make it work correctly with + other parts of the program (most notably the Perfect::Hash + function and the computation of minimum and maximum lengths. + +Fri Jan 13 21:25:27 1989 Doug Schmidt (schmidt at siam.ics.uci.edu) + + * Realized the the need to add a test that will enable + optimziation of the generated C code in the ``hash'' function + by checking whether all the requested key positions are + guaranteed to exist due to the comparison in `in_word_set.'' + I'll put this in soon.... + +Thu Jan 12 20:09:21 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added pascal, modula3, and modula2 tests inputs to the + Makefile + + * Recognised that there is a bug with the -n option. However + I'm too busy to fix it properly, right now. The problem + is that the generated #define end up being 0, since that's + my hack to make -n work. This needs complete rethinking! + +Tue Jan 10 00:08:16 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Added a new option, -n, that instructs gperf to not use the + length of an identifier when computing the hash functions. + I'm not sure how useful this is! + + * Retransmitted the distribution to rocky.oswego.edu. Hopefully, + this will work! + + * Began fixing the indentation and capitalization to conform + to the GNU coding guidelines. + +Mon Jan 9 22:23:18 1989 Doug Schmidt (schmidt at pompe.ics.uci.edu) + + * Fixed horrible bug in Read_Line::Readln_Aux. This was + a subtle and pernicous off-by-1 error, that overwrote + past the last character of the input string buffer. I + think this fault was killing the vax! + + * Yow, fixed an oversight in List_Node::List_Node, where the + pointer field Next was uninitialized. Luckily, the new routine + seems to return 0 filled objects the first time through! + +Sun Jan 8 13:43:14 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Modified the ``key linked'' diagnostic in Key_List::Read_Keys + to be more helpful and easy to read. + + * Fixed the List_Node::List_Node so that it would ignore trailing + fields if the -t option was not enabled. + + * Moved the List_Node declarations out of keylist.h and + into a file of its own, called listnode.cc and listnode.h + Made Set_Sort a member function of class List_Node. + + * Massively updated the documentation in the gperf.texinfo file. + + * Polished off the major revision to the print functions, + added a few new tests in the Makefile to check for the + validity of the program and ftp'ed the entire distribution + off to Doug Lea for libg++. ( changed it to + 1.3 to reflect the major changes with the generated + C code ). + + * Fixed Key_List::Print_Switch to deal with the -p and -t options. + This meant that the ``still-born'' function Key_List:: + Print_Type_Switch was superflous, so I removed it. + Also, removed the restriction in Option that the -p and + -t options couldn't be used simultaneously. + + * Modified List_Node::List_Node, to perform only 1 call to + ``new'' when dynamically allocating memory for the Key_Set + and the Uniq_Set. + +Sat Jan 7 14:10:51 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Fixed a big bug with the new policy of nesting the + wordlist inside of generated function ``in_word_set.'' + I'd forgotten to declare the wordlist array as static! + ( arrgh ). + + * Added a new function Key_List::Set_Types, that figures out + the return type for generated function ``in_word_set,'' + the user-defined ``struct tag,'' if one is used, and also + formates the array type for the static local array. + + * Changed the print routines to take advantage of the + new -p option. + + * Began adding the hooks to allow the return of a pointer + to a user defined struct location from the generated + ``in_word_set'' function instead of the current 0 or 1 + return value. Created function Key_List::Print_Type_Switch + and added option -p to class Option, allowing the user to + request generation of the aforementioned pointers returned + instead of booleans. + + * Put in checks in class Option to make sure that -S and -t + options are not used simultaneously. This restriction + will be removed in subsequent releases, once I decide on + a clean way to implement it. + + * Sent version 1.2 to Doug Lea for possible inclusion into + the libg++ distribution. + + * Moved the static word_list array inside the generated function + in_word_set. This supports better data hiding. + + * Added a texinfo file, gperf.texinfo + + * Revised the Makefile to cleanup the droppings from texinfo + and changed the name of gperf.cc and gperf.h to perfect.cc + and perfect.h. + +Fri Jan 6 13:04:45 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Implemented the switch statement output format. Much better + for large datasets in terms of space used. + + * Added new functions to break up the Key_List::Output function. + Functions added were Key_List::Print_Switch, Key_List::Print_Min_Max, + Key_List::Print_Keyword_Table, Key_List::Print_Hash_Function, + and Key_List::Print_Lookup_Function. This simplifies the + big mess in Key_List::Output considerably! + + * Added switch statement option to Options, which potentially + trades time for space in the generated lookup code. + +Thu Jan 5 22:46:34 1989 Doug Schmidt (schmidt at siam.ics.uci.edu) + + * Released version 1.1 + + * Fixed a bug with Gperf::Merge_Set, it was skipping letters shared + between the Set_1 and Set_2. + + * Added the optimal min/max algorithm in Key_List::Output. This + runs in O ( 3n/2 ), rather than O ( 2n ) time. + + * Changed Gperf::Sort_Set to use insertion sort, rather than + bubble sort. + + * Added a check in Key_List::Output for the special case where + the keys used are 1,$. It is possible to generate more + efficient C code in this case. diff --git a/contrib/gperf/FREEBSD-Xlist b/contrib/gperf/FREEBSD-Xlist new file mode 100644 index 0000000..393d55c --- /dev/null +++ b/contrib/gperf/FREEBSD-Xlist @@ -0,0 +1,8 @@ +$FreeBSD$ +*/*.dvi +*/*.html +*/*.info +*/*.ps +*/texinfo.tex +*/tests +*/getopt* diff --git a/contrib/gperf/INSTALL b/contrib/gperf/INSTALL new file mode 100644 index 0000000..350b32f --- /dev/null +++ b/contrib/gperf/INSTALL @@ -0,0 +1,183 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes a while. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/contrib/gperf/Makefile.devel b/contrib/gperf/Makefile.devel new file mode 100644 index 0000000..cd6b628 --- /dev/null +++ b/contrib/gperf/Makefile.devel @@ -0,0 +1,38 @@ +# This is the developer's makefile, not the user's makefile. +# Don't use it unless you know exactly what you do! + +SHELL = /bin/sh +MAKE = make + +all : configures src/config.h.in doc/gperf.1 + +CONFIGURES = configure lib/configure src/configure tests/configure doc/configure + +configures : $(CONFIGURES) + +configure : configure.in aclocal.m4 + autoconf -l . + +lib/configure : lib/configure.in aclocal.m4 + cd lib && autoconf -l .. + +src/configure : src/configure.in aclocal.m4 + cd src && autoconf -l .. + +tests/configure : tests/configure.in aclocal.m4 + cd tests && autoconf -l .. + +doc/configure : doc/configure.in aclocal.m4 + cd doc && autoconf -l .. + +check-configures : $(CONFIGURES) + set -e; for f in $(CONFIGURES); do bash -x -n $$f; done + +src/config.h.in : src/configure.in aclocal.m4 + cd src && autoheader -l .. + +doc/gperf.1 : force + prog=`PATH=build/src:src:$$PATH which gperf`; if test -n "$$prog"; then doc/help2man --name='generate a perfect hash function from a key set' --section=1 $$prog > doc/gperf.1; fi + +force : + diff --git a/contrib/gperf/Makefile.in b/contrib/gperf/Makefile.in new file mode 100644 index 0000000..1d9336a --- /dev/null +++ b/contrib/gperf/Makefile.in @@ -0,0 +1,62 @@ +# Makefile for gperf + +# Copyright (C) 1989, 1992, 1993, 1998 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 +# Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#### Start of system configuration section. #### + +# Programs used by "make": +RM = rm -f +@SET_MAKE@ + +#### End of system configuration section. #### + +SHELL = /bin/sh + +all : force + cd @subdir@; $(MAKE) all + +install : force + cd @subdir@; $(MAKE) install + +installdirs : force + cd @subdir@; $(MAKE) installdirs + +uninstall : force + cd @subdir@; $(MAKE) uninstall + +check : force + cd @subdir@; $(MAKE) check + +mostlyclean : force + cd @subdir@; $(MAKE) mostlyclean + +clean : force + cd @subdir@; $(MAKE) clean + +distclean : force + cd @subdir@; if test -f Makefile; then $(MAKE) distclean; fi + $(RM) config.status config.log config.cache Makefile + +maintainer-clean : force + cd @subdir@; if test -f Makefile; then $(MAKE) maintainer-clean; fi + $(RM) config.status config.log config.cache Makefile + +force : + diff --git a/contrib/gperf/NEWS b/contrib/gperf/NEWS new file mode 100644 index 0000000..9a2877f --- /dev/null +++ b/contrib/gperf/NEWS @@ -0,0 +1,21 @@ +New in 2.7.2: + +* Keywords may now be enclosed in double quotes; this permits the use of + '#', ',', space or NUL inside keywords. +* Bug fixes. + +New in 2.7.1: + +* Added option "-F" for gcc. + +New in 2.7: + +* gperf is now a stand-alone package, untied from libg++. +* Autoconfiguring. +* Removed the "-a" and "-g" options, extended the "-L" option instead. +* Removed the "-p" option, it is the default. +* Added long options ("--help", "--version" etc.). +* 8-bit cleanliness is now the default; use "-7" to get the old behaviour. +* Compiles with any C++ compiler. +* Numerous small improvements. + diff --git a/contrib/gperf/README b/contrib/gperf/README new file mode 100644 index 0000000..92ec7d2 --- /dev/null +++ b/contrib/gperf/README @@ -0,0 +1,29 @@ +This is GNU gperf. It is a program that generates perfect hash +functions for sets of key words. A perfect hash function is: + + 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 doc/gperf.html 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 words set. + +See the file NEWS for a list of major changes in the current release. + +See the file INSTALL for compilation and installation instructions. + +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. + +For general documentation on the coding and usage standards +this distribution follows, see the GNU standards document +ftp://ftp.gnu.org/pub/gnu/standards.*, especially the 'Makefile +Conventions', 'Configuration', and 'User Interfaces' sections. + +Mail suggestions and bug reports to both <bug-gnu-utils@gnu.org> and +<gperf-bugs@lists.sourceforge.net>. When reporting bugs, please +include in the subject line the package name and version (output of +'gperf --version') for which you found a problem. + diff --git a/contrib/gperf/acconfig.h b/contrib/gperf/acconfig.h new file mode 100644 index 0000000..cd040d4 --- /dev/null +++ b/contrib/gperf/acconfig.h @@ -0,0 +1,4 @@ + +/* Define if the C++ compiler supports "throw ()" declarations. */ +#undef HAVE_THROW_DECL + diff --git a/contrib/gperf/aclocal.m4 b/contrib/gperf/aclocal.m4 new file mode 100644 index 0000000..bb22edc --- /dev/null +++ b/contrib/gperf/aclocal.m4 @@ -0,0 +1,71 @@ +AC_PREREQ(2.12) + +AC_DEFUN(CL_PROG_RANLIB, [AC_CHECK_PROG(RANLIB, ranlib, ranlib, true)]) + +AC_DEFUN(CL_PROG_INSTALL, +[dnl This is mostly copied from AC_PROG_INSTALL. +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +AC_MSG_CHECKING(for a BSD compatible install) +if test -z "$INSTALL"; then +AC_CACHE_VAL(cl_cv_path_install, +[ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + for ac_prog in ginstall installbsd scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + # OSF/1 installbsd also uses dspmsg, but is usable. + : + else + if test $ac_prog = installbsd && + grep src/bos $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX installbsd doesn't work without option "-g". + : + else + cl_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + fi + done + ;; + esac + done + IFS="$ac_save_ifs" + # As a last resort, use cp. + test -z "$cl_cv_path_install" && cl_cv_path_install="cp" +])dnl + INSTALL="$cl_cv_path_install" +fi +dnl We do special magic for INSTALL instead of AC_SUBST, to get +dnl relative paths right. +AC_MSG_RESULT($INSTALL) +AC_SUBST(INSTALL)dnl +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='$(INSTALL)' +AC_SUBST(INSTALL_PROGRAM)dnl +if test -z "$INSTALL_DATA"; then + case "$INSTALL" in + cp | */cp ) INSTALL_DATA='$(INSTALL)' ;; + * ) INSTALL_DATA='$(INSTALL) -m 644' ;; + esac +fi +AC_SUBST(INSTALL_DATA)dnl +]) + diff --git a/contrib/gperf/configure b/contrib/gperf/configure new file mode 100755 index 0000000..7712380 --- /dev/null +++ b/contrib/gperf/configure @@ -0,0 +1,914 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=doc/gperf.1 + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:526: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +extrasub="$extrasub"' +/@subdir@/{ +h +g +s/@subdir@/lib/ +p +g +s/@subdir@/src/ +p +g +s/@subdir@/tests/ +p +g +s/@subdir@/doc/ +p +d +} +' +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@SET_MAKE@%$SET_MAKE%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <<EOF + +EOF +cat >> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + + +if test "$no_recursion" != yes; then + + # Remove --cache-file and --srcdir arguments so they do not pile up. + ac_sub_configure_args= + ac_prev= + for ac_arg in $ac_configure_args; do + if test -n "$ac_prev"; then + ac_prev= + continue + fi + case "$ac_arg" in + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + ;; + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + ;; + *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;; + esac + done + + for ac_config_dir in lib src tests doc; do + + # Do not complain, so a configure script can configure whichever + # parts of a large source tree are present. + if test ! -d $srcdir/$ac_config_dir; then + continue + fi + + echo configuring in $ac_config_dir + + case "$srcdir" in + .) ;; + *) + if test -d ./$ac_config_dir || mkdir ./$ac_config_dir; then :; + else + { echo "configure: error: can not create `pwd`/$ac_config_dir" 1>&2; exit 1; } + fi + ;; + esac + + ac_popdir=`pwd` + cd $ac_config_dir + + # A "../" for each directory in /$ac_config_dir. + ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'` + + case "$srcdir" in + .) # No --srcdir option. We are building in place. + ac_sub_srcdir=$srcdir ;; + /*) # Absolute path. + ac_sub_srcdir=$srcdir/$ac_config_dir ;; + *) # Relative path. + ac_sub_srcdir=$ac_dots$srcdir/$ac_config_dir ;; + esac + + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_sub_srcdir/configure; then + ac_sub_configure=$ac_sub_srcdir/configure + elif test -f $ac_sub_srcdir/configure.in; then + ac_sub_configure=$ac_configure + else + echo "configure: warning: no configuration information is in $ac_config_dir" 1>&2 + ac_sub_configure= + fi + + # The recursion is here. + if test -n "$ac_sub_configure"; then + + # Make the cache file name correct relative to the subdirectory. + case "$cache_file" in + /*) ac_sub_cache_file=$cache_file ;; + *) # Relative path. + ac_sub_cache_file="$ac_dots$cache_file" ;; + esac + + echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir" + # The eval makes quoting arguments work. + if eval ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir + then : + else + { echo "configure: error: $ac_sub_configure failed for $ac_config_dir" 1>&2; exit 1; } + fi + fi + + cd $ac_popdir + done +fi + diff --git a/contrib/gperf/configure.in b/contrib/gperf/configure.in new file mode 100644 index 0000000..5ac1499 --- /dev/null +++ b/contrib/gperf/configure.in @@ -0,0 +1,46 @@ +dnl autoconf configuration for gperf + +dnl Copyright (C) 1998 Free Software Foundation, Inc. +dnl written by Douglas C. Schmidt (schmidt@ics.uci.edu) +dnl +dnl This file is part of GNU GPERF. +dnl +dnl GNU GPERF is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 1, or (at your option) +dnl any later version. +dnl +dnl GNU GPERF is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU GPERF; see the file COPYING. If not, write to the +dnl Free Software Foundation, 59 Temple Place - Suite 330, Boston, +dnl MA 02111-1307, USA. + +AC_INIT(doc/gperf.1) +AC_PROG_MAKE_SET +dnl This piece of sed script replaces every line containing '@subdir@' +dnl by several consecutive lines, each referencing one subdir. +extrasub="$extrasub"' +/@subdir@/{ +h +g +s/@subdir@/lib/ +p +g +s/@subdir@/src/ +p +g +s/@subdir@/tests/ +p +g +s/@subdir@/doc/ +p +d +} +' +AC_OUTPUT(Makefile) +AC_OUTPUT_SUBDIRS(lib src tests doc) diff --git a/contrib/gperf/doc/Makefile.in b/contrib/gperf/doc/Makefile.in new file mode 100644 index 0000000..99ac03d --- /dev/null +++ b/contrib/gperf/doc/Makefile.in @@ -0,0 +1,135 @@ +# Makefile for gperf/doc + +# Copyright (C) 1998, 2000 Free Software Foundation, Inc. +# +# 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. + +#### Start of system configuration section. #### + +# Directories used by "make": +srcdir = @srcdir@ + +# Directories used by "make install": +prefix = @prefix@ +local_prefix = /usr/local +exec_prefix = @exec_prefix@ +datadir = @datadir@ +infodir = @infodir@ +mandir = @mandir@ +man1dir = $(mandir)/man1 +docdir = $(prefix)/doc/@PACKAGE@ +dvidir = $(docdir) +psdir = $(docdir) +htmldir = $(docdir) + +# Programs used by "make": +RM = rm -f +@SET_MAKE@ + +# Programs used by "make" if you have changed the documentation files: +TEX = tex +TEXI2DVI = texi2dvi +DVIPS = dvips -D600 +MAKEINFO = LANG= LANGUAGE= makeinfo +TEXI2HTML = texi2html + +# Programs used by "make install": +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +MKINSTALLDIRS = $(SHELL) $(srcdir)/../mkinstalldirs + +#### End of system configuration section. #### + +SHELL = /bin/sh + +VPATH = $(srcdir) + +all : info dvi ps html + + +info : $(srcdir)/gperf.info + +$(srcdir)/gperf.info : $(srcdir)/gperf.texi $(srcdir)/gpl.texinfo + cd $(srcdir) && $(MAKEINFO) --no-split gperf.texi + + +dvi : $(srcdir)/gperf.dvi + +$(srcdir)/gperf.dvi : $(srcdir)/gperf.texi $(srcdir)/gpl.texinfo + cd $(srcdir) && $(RM) gperf.aux gperf.toc gperf.cp gperf.fn gperf.ky gperf.pg gperf.tp gperf.vr gperf.log gperf.cps + cd $(srcdir) && $(TEXI2DVI) gperf.texi + cd $(srcdir) && $(RM) gperf.aux gperf.toc gperf.cp gperf.fn gperf.ky gperf.pg gperf.tp gperf.vr gperf.log gperf.cps + + +ps : $(srcdir)/gperf.ps + +$(srcdir)/gperf.ps : $(srcdir)/gperf.dvi + $(DVIPS) -o $@ $< + + +html : gperf.html gperf_toc.html + +gperf.html : $(srcdir)/gperf.texi $(srcdir)/gpl.texinfo + cd $(srcdir) && $(TEXI2HTML) -expandinfo -number -monolithic gperf.texi + +gperf_toc.html : $(srcdir)/gperf.texi $(srcdir)/gpl.texinfo + cd $(srcdir) && $(RM) gperf_*.html + cd $(srcdir) && $(TEXI2HTML) -expandinfo -number -split_chapter gperf.texi + + +install : all force + $(MKINSTALLDIRS) $(DESTDIR)$(infodir) + $(INSTALL_DATA) $(srcdir)/gperf.info $(DESTDIR)$(infodir)/gperf.info + $(MKINSTALLDIRS) $(DESTDIR)$(man1dir) + $(INSTALL_DATA) $(srcdir)/gperf.1 $(DESTDIR)$(man1dir)/gperf.1 +# $(MKINSTALLDIRS) $(DESTDIR)$(dvidir) +# $(INSTALL_DATA) $(srcdir)/gperf.dvi $(DESTDIR)$(dvidir)/gperf.dvi +# $(MKINSTALLDIRS) $(DESTDIR)$(psdir) +# $(INSTALL_DATA) $(srcdir)/gperf.ps $(DESTDIR)$(dvidir)/gperf.ps + $(MKINSTALLDIRS) $(DESTDIR)$(htmldir) + $(INSTALL_DATA) $(srcdir)/gperf.html $(DESTDIR)$(htmldir)/gperf.html + +installdirs : force + $(MKINSTALLDIRS) $(DESTDIR)$(infodir) + $(MKINSTALLDIRS) $(DESTDIR)$(man1dir) +# $(MKINSTALLDIRS) $(DESTDIR)$(dvidir) +# $(MKINSTALLDIRS) $(DESTDIR)$(psdir) + $(MKINSTALLDIRS) $(DESTDIR)$(htmldir) + +uninstall : force + $(RM) $(DESTDIR)$(infodir)/gperf.info + $(RM) $(DESTDIR)$(man1dir)/gperf.1 +# $(RM) $(DESTDIR)$(dvidir)/gperf.dvi +# $(RM) $(DESTDIR)$(psdir)/gperf.ps + $(RM) $(DESTDIR)$(htmldir)/gperf.html + +check : all + +mostlyclean : clean + +clean : force + $(RM) *~ *.aux *.toc *.cp *.fn *.ky *.pg *.tp *.vr *.my *.log *.cps core + +distclean : clean + $(RM) config.status config.log config.cache Makefile + +maintainer-clean : distclean + $(RM) *.info *.dvi *.ps *.html + +force : + diff --git a/contrib/gperf/doc/configure b/contrib/gperf/doc/configure new file mode 100755 index 0000000..a10049f --- /dev/null +++ b/contrib/gperf/doc/configure @@ -0,0 +1,871 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=gperf.1 + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + +PACKAGE=gperf + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:528: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:565: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'cl_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + for ac_prog in ginstall installbsd scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + # OSF/1 installbsd also uses dspmsg, but is usable. + : + else + if test $ac_prog = installbsd && + grep src/bos $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX installbsd doesn't work without option "-g". + : + else + cl_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + fi + done + ;; + esac + done + IFS="$ac_save_ifs" + # As a last resort, use cp. + test -z "$cl_cv_path_install" && cl_cv_path_install="cp" + +fi + INSTALL="$cl_cv_path_install" +fi +echo "$ac_t""$INSTALL" 1>&6 +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='$(INSTALL)' +if test -z "$INSTALL_DATA"; then + case "$INSTALL" in + cp | */cp ) INSTALL_DATA='$(INSTALL)' ;; + * ) INSTALL_DATA='$(INSTALL) -m 644' ;; + esac +fi + + trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@PACKAGE@%$PACKAGE%g +s%@SET_MAKE@%$SET_MAKE%g +s%@INSTALL@%$INSTALL%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_DATA@%$INSTALL_DATA%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <<EOF + +EOF +cat >> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/contrib/gperf/doc/configure.in b/contrib/gperf/doc/configure.in new file mode 100644 index 0000000..944b862 --- /dev/null +++ b/contrib/gperf/doc/configure.in @@ -0,0 +1,35 @@ +dnl autoconf configuration for gperf/doc + +dnl Copyright (C) 1998, 2000 Free Software Foundation, Inc. +dnl written by Douglas C. Schmidt (schmidt@ics.uci.edu) +dnl +dnl This file is part of GNU GPERF. +dnl +dnl GNU GPERF is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 1, or (at your option) +dnl any later version. +dnl +dnl GNU GPERF is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU GPERF; see the file COPYING. If not, write to the +dnl Free Software Foundation, 59 Temple Place - Suite 330, Boston, +dnl MA 02111-1307, USA. + +AC_INIT(gperf.1) +PACKAGE=gperf +AC_SUBST(PACKAGE) +AC_PROG_MAKE_SET +dnl +dnl checks for programs +dnl +CL_PROG_INSTALL + dnl sets variables INSTALL, INSTALL_DATA, INSTALL_PROGRAM +dnl +dnl That's it. +dnl +AC_OUTPUT(Makefile) diff --git a/contrib/gperf/doc/gperf.1 b/contrib/gperf/doc/gperf.1 new file mode 100644 index 0000000..dd425e0 --- /dev/null +++ b/contrib/gperf/doc/gperf.1 @@ -0,0 +1,187 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.022. +.TH GPERF "1" "September 2000" "GNU gperf 2.7.2" FSF +.SH NAME +gperf \- generate a perfect hash function from a key set +.SH SYNOPSIS +.B gperf +[\fIOPTION\fR]... [\fIINPUT-FILE\fR] +.SH DESCRIPTION +GNU `gperf' generates perfect hash functions. +.PP +If a long option shows an argument as mandatory, then it is mandatory +for the equivalent short option also. +.SS "Input file interpretation:" +.TP +\fB\-e\fR, \fB\-\-delimiters\fR=\fIDELIMITER\-LIST\fR +Allow user to provide a string containing delimiters +used to separate keywords from their attributes. +Default is ",\en". +.TP +\fB\-t\fR, \fB\-\-struct\-type\fR +Allows the user to include a structured type +declaration for generated code. Any text before %% +is considered part of the type declaration. Key +words and additional fields may follow this, one +group of fields per line. +.SS "Language for the output code:" +.TP +\fB\-L\fR, \fB\-\-language\fR=\fILANGUAGE\-NAME\fR +Generates code in the specified language. Languages +handled are currently C++, ANSI-C, C, and KR-C. The +default is C. +.SS "Details in the output code:" +.TP +\fB\-K\fR, \fB\-\-slot\-name\fR=\fINAME\fR +Select name of the keyword component in the keyword +structure. +.TP +\fB\-F\fR, \fB\-\-initializer\-suffix\fR=\fIINITIALIZERS\fR +Initializers for additional components in the keyword +structure. +.TP +\fB\-H\fR, \fB\-\-hash\-fn\-name\fR=\fINAME\fR +Specify name of generated hash function. Default is +`hash'. +.TP +\fB\-N\fR, \fB\-\-lookup\-fn\-name\fR=\fINAME\fR +Specify name of generated lookup function. Default +name is `in_word_set'. +.TP +\fB\-Z\fR, \fB\-\-class\-name\fR=\fINAME\fR +Specify name of generated C++ class. Default name is +`Perfect_Hash'. +.TP +\fB\-7\fR, \fB\-\-seven\-bit\fR +Assume 7-bit characters. +.TP +\fB\-c\fR, \fB\-\-compare\-strncmp\fR +Generate comparison code using strncmp rather than +strcmp. +.TP +\fB\-C\fR, \fB\-\-readonly\-tables\fR +Make the contents of generated lookup tables +constant, i.e., readonly. +.TP +\fB\-E\fR, \fB\-\-enum\fR +Define constant values using an enum local to the +lookup function rather than with defines. +.TP +\fB\-I\fR, \fB\-\-includes\fR +Include the necessary system include file <string.h> +at the beginning of the code. +.TP +\fB\-G\fR, \fB\-\-global\fR +Generate the static table of keywords as a static +global variable, rather than hiding it inside of the +lookup function (which is the default behavior). +.TP +\fB\-W\fR, \fB\-\-word\-array\-name\fR=\fINAME\fR +Specify name of word list array. Default name is +`wordlist'. +.TP +\fB\-S\fR, \fB\-\-switch\fR=\fICOUNT\fR +Causes the generated C code to use a switch +statement scheme, rather than an array lookup table. +This can lead to a reduction in both time and space +requirements for some keyfiles. The COUNT argument +determines how many switch statements are generated. +A value of 1 generates 1 switch containing all the +elements, a value of 2 generates 2 tables with 1/2 +the elements in each table, etc. If COUNT is very +large, say 1000000, the generated C code does a +binary search. +.TP +\fB\-T\fR, \fB\-\-omit\-struct\-type\fR +Prevents the transfer of the type declaration to the +output file. Use this option if the type is already +defined elsewhere. +.SS "Algorithm employed by gperf:" +.TP +\fB\-k\fR, \fB\-\-key\-positions\fR=\fIKEYS\fR +Select the key positions used in the hash function. +The allowable choices range between 1-126, inclusive. +The positions are separated by commas, ranges may be +used, and key positions may occur in any order. +Also, the meta-character '*' causes the generated +hash function to consider ALL key positions, and $ +indicates the ``final character'' of a key, e.g., +$,1,2,4,6-10. +.TP +\fB\-l\fR, \fB\-\-compare\-strlen\fR +Compare key lengths before trying a string +comparison. This helps cut down on the number of +string comparisons made during the lookup. +.TP +\fB\-D\fR, \fB\-\-duplicates\fR +Handle keywords that hash to duplicate values. This +is useful for certain highly redundant keyword sets. +.TP +\fB\-f\fR, \fB\-\-fast\fR=\fIITERATIONS\fR +Generate the gen-perf.hash function ``fast''. This +decreases gperf's running time at the cost of +minimizing generated table size. The numeric +argument represents the number of times to iterate +when resolving a collision. `0' means ``iterate by +the number of keywords''. +.TP +\fB\-i\fR, \fB\-\-initial\-asso\fR=\fIN\fR +Provide an initial value for the associate values +array. Default is 0. Setting this value larger helps +inflate the size of the final table. +.TP +\fB\-j\fR, \fB\-\-jump\fR=\fIJUMP\-VALUE\fR +Affects the ``jump value'', i.e., how far to advance +the associated character value upon collisions. Must +be an odd number, default is 5. +.TP +\fB\-n\fR, \fB\-\-no\-strlen\fR +Do not include the length of the keyword when +computing the hash function. +.TP +\fB\-o\fR, \fB\-\-occurrence\-sort\fR +Reorders input keys by frequency of occurrence of +the key sets. This should decrease the search time +dramatically. +.TP +\fB\-r\fR, \fB\-\-random\fR +Utilizes randomness to initialize the associated +values table. +.TP +\fB\-s\fR, \fB\-\-size\-multiple\fR=\fIN\fR +Affects the size of the generated hash table. The +numeric argument N indicates ``how many times larger +or smaller'' the associated value range should be, +in relationship to the number of keys, e.g. a value +of 3 means ``allow the maximum associated value to +be about 3 times larger than the number of input +keys.'' Conversely, a value of \fB\-3\fR means ``make the +maximum associated value about 3 times smaller than +the number of input keys. A larger table should +decrease the time required for an unsuccessful +search, at the expense of extra table space. Default +value is 1. +.SS "Informative output:" +.TP +\fB\-h\fR, \fB\-\-help\fR +Print this message. +.TP +\fB\-v\fR, \fB\-\-version\fR +Print the gperf version number. +.TP +\fB\-d\fR, \fB\-\-debug\fR +Enables the debugging option (produces verbose +output to the standard error). +.SH "REPORTING BUGS" +Report bugs to <bug-gnu-utils@gnu.org>. +.SH "SEE ALSO" +The full documentation for +.B gperf +is maintained as a Texinfo manual. If the +.B info +and +.B gperf +programs are properly installed at your site, the command +.IP +.B info gperf +.PP +should give you access to the complete manual. diff --git a/contrib/gperf/doc/gperf.texi b/contrib/gperf/doc/gperf.texi new file mode 100644 index 0000000..e510ac9 --- /dev/null +++ b/contrib/gperf/doc/gperf.texi @@ -0,0 +1,1051 @@ +\input texinfo @c -*- texinfo -*- +@c %**start of header +@setfilename gperf.info +@settitle Perfect Hash Function Generator +@c @setchapternewpage odd +@c %**end of header + +@c some day we should @include version.texi instead of defining +@c these values at hand. +@set UPDATED 26 September 2000 +@set EDITION 2.7.2 +@set VERSION 2.7.2 +@c --------------------- + +@c remove the black boxes generated in the GPL appendix. +@finalout + +@c Merge functions into the concept index +@syncodeindex fn cp +@c @synindex pg cp + +@dircategory Programming Tools +@direntry +* Gperf: (gperf). Perfect Hash Function Generator. +@end direntry + +@ifinfo +This file documents the features of the GNU Perfect Hash Function +Generator @value{VERSION}. + +Copyright @copyright{} 1989-2000 Free Software Foundation, Inc. + +Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries a copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). + +@end ignore + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +section entitled ``GNU General Public License'' is included exactly as +in the original, and provided that the entire resulting derived work is +distributed under the terms of a permission notice identical to this +one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that the section entitled ``GNU General Public License'' and this +permission notice may be included in translations approved by the Free +Software Foundation instead of in the original English. + +@end ifinfo + +@titlepage +@title User's Guide to @code{gperf} @value{VERSION} +@subtitle The GNU Perfect Hash Function Generator +@subtitle Edition @value{EDITION}, @value{UPDATED} +@author Douglas C. Schmidt + +@page +@vskip 0pt plus 1filll +Copyright @copyright{} 1989-2000 Free Software Foundation, Inc. + + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +section entitled ``GNU General Public License'' is included +exactly as in the original, and provided that the entire resulting +derived work is distributed under the terms of a permission notice +identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that the section entitled ``GNU General Public License'' may be +included in a translation approved by the author instead of in the +original English. +@end titlepage + +@ifinfo +@node Top, Copying, (dir), (dir) +@top Introduction + +This manual documents the GNU @code{gperf} perfect hash function generator +utility, focusing on its features and how to use them, and how to report +bugs. + +@menu +* Copying:: GNU @code{gperf} General Public License says + how you can copy and share @code{gperf}. +* Contributors:: People who have contributed to @code{gperf}. +* Motivation:: Static search structures and GNU GPERF. +* Search Structures:: Static search structures and GNU @code{gperf} +* Description:: High-level discussion of how GPERF functions. +* Options:: A description of options to the program. +* Bugs:: Known bugs and limitations with GPERF. +* Projects:: Things still left to do. +* Implementation:: Implementation Details for GNU GPERF. +* Bibliography:: Material Referenced in this Report. + +* Concept Index:: + +@detailmenu --- The Detailed Node Listing --- + +High-Level Description of GNU @code{gperf} + +* Input Format:: Input Format to @code{gperf} +* Output Format:: Output Format for Generated C Code with @code{gperf} +* Binary Strings:: Use of NUL characters + +Input Format to @code{gperf} + +* Declarations:: @code{struct} Declarations and C Code Inclusion. +* Keywords:: Format for Keyword Entries. +* Functions:: Including Additional C Functions. + +Invoking @code{gperf} + +* Input Details:: Options that affect Interpretation of the Input File +* Output Language:: Specifying the Language for the Output Code +* Output Details:: Fine tuning Details in the Output Code +* Algorithmic Details:: Changing the Algorithms employed by @code{gperf} +* Verbosity:: Informative Output + +@end detailmenu +@end menu + +@end ifinfo + +@node Copying, Contributors, Top, Top +@unnumbered GNU GENERAL PUBLIC LICENSE +@include gpl.texinfo + +@node Contributors, Motivation, Copying, Top +@unnumbered Contributors to GNU @code{gperf} Utility + +@itemize @bullet +@item +@cindex Bugs +The GNU @code{gperf} perfect hash function generator utility was +originally written in GNU C++ by Douglas C. Schmidt. It is now also +available in a highly-portable ``old-style'' C version. The general +idea for the perfect hash function generator was inspired by Keith +Bostic's algorithm written in C, and distributed to net.sources around +1984. The current program is a heavily modified, enhanced, and extended +implementation of Keith's basic idea, created at the University of +California, Irvine. Bugs, patches, and suggestions should be reported +to both @code{<bug-gnu-utils@@gnu.org>} and +@code{<gperf-bugs@@lists.sourceforge.net>}. + +@item +Special thanks is extended to Michael Tiemann and Doug Lea, for +providing a useful compiler, and for giving me a forum to exhibit my +creation. + +In addition, Adam de Boor and Nels Olson provided many tips and insights +that greatly helped improve the quality and functionality of @code{gperf}. + +@item +A testsuite was added by Bruno Haible. He also rewrote the output +routines for better reliability. +@end itemize + +@node Motivation, Search Structures, Contributors, Top +@chapter Introduction + +@code{gperf} is a perfect hash function generator written in C++. It +transforms an @var{n} element user-specified keyword set @var{W} into a +perfect hash function @var{F}. @var{F} uniquely maps keywords in +@var{W} onto the range 0..@var{k}, where @var{k} >= @var{n}. If @var{k} += @var{n} then @var{F} is a @emph{minimal} perfect hash function. +@code{gperf} generates a 0..@var{k} element static lookup table and a +pair of C functions. These functions determine whether a given +character string @var{s} occurs in @var{W}, using at most one probe into +the lookup table. + +@code{gperf} currently generates the reserved keyword recognizer for +lexical analyzers in several production and research compilers and +language processing tools, including GNU C, GNU C++, GNU Pascal, GNU +Modula 3, and GNU indent. Complete C++ source code for @code{gperf} is +available via anonymous ftp from @code{ftp://ftp.gnu.org/pub/gnu/gperf/}. +A paper describing @code{gperf}'s design and implementation in greater +detail is available in the Second USENIX C++ Conference proceedings. + +@node Search Structures, Description, Motivation, Top +@chapter Static search structures and GNU @code{gperf} +@cindex Static search structure + +A @dfn{static search structure} is an Abstract Data Type with certain +fundamental operations, e.g., @emph{initialize}, @emph{insert}, +and @emph{retrieve}. Conceptually, all insertions occur before any +retrievals. In practice, @code{gperf} generates a @code{static} array +containing search set keywords and any associated attributes specified +by the user. Thus, there is essentially no execution-time cost for the +insertions. It is a useful data structure for representing @emph{static +search sets}. Static search sets occur frequently in software system +applications. Typical static search sets include compiler reserved +words, assembler instruction opcodes, and built-in shell interpreter +commands. Search set members, called @dfn{keywords}, are inserted into +the structure only once, usually during program initialization, and are +not generally modified at run-time. + +Numerous static search structure implementations exist, e.g., +arrays, linked lists, binary search trees, digital search tries, and +hash tables. Different approaches offer trade-offs between space +utilization and search time efficiency. For example, an @var{n} element +sorted array is space efficient, though the average-case time +complexity for retrieval operations using binary search is +proportional to log @var{n}. Conversely, hash table implementations +often locate a table entry in constant time, but typically impose +additional memory overhead and exhibit poor worst case performance. + +@cindex Minimal perfect hash functions +@emph{Minimal perfect hash functions} provide an optimal solution for a +particular class of static search sets. A minimal perfect hash +function is defined by two properties: + +@itemize @bullet +@item +It allows keyword recognition in a static search set using at most +@emph{one} probe into the hash table. This represents the ``perfect'' +property. +@item +The actual memory allocated to store the keywords is precisely large +enough for the keyword set, and @emph{no larger}. This is the +``minimal'' property. +@end itemize + +For most applications it is far easier to generate @emph{perfect} hash +functions than @emph{minimal perfect} hash functions. Moreover, +non-minimal perfect hash functions frequently execute faster than +minimal ones in practice. This phenomena occurs since searching a +sparse keyword table increases the probability of locating a ``null'' +entry, thereby reducing string comparisons. @code{gperf}'s default +behavior generates @emph{near-minimal} perfect hash functions for +keyword sets. However, @code{gperf} provides many options that permit +user control over the degree of minimality and perfection. + +Static search sets often exhibit relative stability over time. For +example, Ada's 63 reserved words have remained constant for nearly a +decade. It is therefore frequently worthwhile to expend concerted +effort building an optimal search structure @emph{once}, if it +subsequently receives heavy use multiple times. @code{gperf} removes +the drudgery associated with constructing time- and space-efficient +search structures by hand. It has proven a useful and practical tool +for serious programming projects. Output from @code{gperf} is currently +used in several production and research compilers, including GNU C, GNU +C++, GNU Pascal, and GNU Modula 3. The latter two compilers are not yet +part of the official GNU distribution. Each compiler utilizes +@code{gperf} to automatically generate static search structures that +efficiently identify their respective reserved keywords. + +@node Description, Options, Search Structures, Top +@chapter High-Level Description of GNU @code{gperf} + +@menu +* Input Format:: Input Format to @code{gperf} +* Output Format:: Output Format for Generated C Code with @code{gperf} +* Binary Strings:: Use of NUL characters +@end menu + +The perfect hash function generator @code{gperf} reads a set of +``keywords'' from a @dfn{keyfile} (or from the standard input by +default). It attempts to derive a perfect hashing function that +recognizes a member of the @dfn{static keyword set} with at most a +single probe into the lookup table. If @code{gperf} succeeds in +generating such a function it produces a pair of C source code routines +that perform hashing and table lookup recognition. All generated C code +is directed to the standard output. Command-line options described +below allow you to modify the input and output format to @code{gperf}. + +By default, @code{gperf} attempts to produce time-efficient code, with +less emphasis on efficient space utilization. However, several options +exist that permit trading-off execution time for storage space and vice +versa. In particular, expanding the generated table size produces a +sparse search structure, generally yielding faster searches. +Conversely, you can direct @code{gperf} to utilize a C @code{switch} +statement scheme that minimizes data space storage size. Furthermore, +using a C @code{switch} may actually speed up the keyword retrieval time +somewhat. Actual results depend on your C compiler, of course. + +In general, @code{gperf} assigns values to the characters it is using +for hashing until some set of values gives each keyword a unique value. +A helpful heuristic is that the larger the hash value range, the easier +it is for @code{gperf} to find and generate a perfect hash function. +Experimentation is the key to getting the most from @code{gperf}. + +@node Input Format, Output Format, Description, Description +@section Input Format to @code{gperf} +@cindex Format +@cindex Declaration section +@cindex Keywords section +@cindex Functions section +You can control the input keyfile format by varying certain command-line +arguments, in particular the @samp{-t} option. The input's appearance +is similar to GNU utilities @code{flex} and @code{bison} (or UNIX +utilities @code{lex} and @code{yacc}). Here's an outline of the general +format: + +@example +@group +declarations +%% +keywords +%% +functions +@end group +@end example + +@emph{Unlike} @code{flex} or @code{bison}, all sections of +@code{gperf}'s input are optional. The following sections describe the +input format for each section. + +@menu +* Declarations:: @code{struct} Declarations and C Code Inclusion. +* Keywords:: Format for Keyword Entries. +* Functions:: Including Additional C Functions. +@end menu + +@node Declarations, Keywords, Input Format, Input Format +@subsection @code{struct} Declarations and C Code Inclusion + +The keyword input file optionally contains a section for including +arbitrary C declarations and definitions, as well as provisions for +providing a user-supplied @code{struct}. If the @samp{-t} option +@emph{is} enabled, you @emph{must} provide a C @code{struct} as the last +component in the declaration section from the keyfile file. The first +field in this struct must be a @code{char *} or @code{const char *} +identifier called @samp{name}, although it is possible to modify this +field's name with the @samp{-K} option described below. + +Here is a simple example, using months of the year and their attributes as +input: + +@example +@group +struct months @{ char *name; int number; int days; int leap_days; @}; +%% +january, 1, 31, 31 +february, 2, 28, 29 +march, 3, 31, 31 +april, 4, 30, 30 +may, 5, 31, 31 +june, 6, 30, 30 +july, 7, 31, 31 +august, 8, 31, 31 +september, 9, 30, 30 +october, 10, 31, 31 +november, 11, 30, 30 +december, 12, 31, 31 +@end group +@end example + +@cindex @samp{%%} +Separating the @code{struct} declaration from the list of keywords and +other fields are a pair of consecutive percent signs, @samp{%%}, +appearing left justified in the first column, as in the UNIX utility +@code{lex}. + +@cindex @samp{%@{} +@cindex @samp{%@}} +Using a syntax similar to GNU utilities @code{flex} and @code{bison}, it +is possible to directly include C source text and comments verbatim into +the generated output file. This is accomplished by enclosing the region +inside left-justified surrounding @samp{%@{}, @samp{%@}} pairs. Here is +an input fragment based on the previous example that illustrates this +feature: + +@example +@group +%@{ +#include <assert.h> +/* This section of code is inserted directly into the output. */ +int return_month_days (struct months *months, int is_leap_year); +%@} +struct months @{ char *name; int number; int days; int leap_days; @}; +%% +january, 1, 31, 31 +february, 2, 28, 29 +march, 3, 31, 31 +... +@end group +@end example + +It is possible to omit the declaration section entirely. In this case +the keyfile begins directly with the first keyword line, e.g.: + +@example +@group +january, 1, 31, 31 +february, 2, 28, 29 +march, 3, 31, 31 +april, 4, 30, 30 +... +@end group +@end example + +@node Keywords, Functions, Declarations, Input Format +@subsection Format for Keyword Entries + +The second keyfile format section contains lines of keywords and any +associated attributes you might supply. A line beginning with @samp{#} +in the first column is considered a comment. Everything following the +@samp{#} is ignored, up to and including the following newline. + +The first field of each non-comment line is always the key itself. It +can be given in two ways: as a simple name, i.e., without surrounding +string quotation marks, or as a string enclosed in double-quotes, in +C syntax, possibly with backslash escapes like @code{\"} or @code{\234} +or @code{\xa8}. In either case, it must start right at the beginning +of the line, without leading whitespace. +In this context, a ``field'' is considered to extend up to, but +not include, the first blank, comma, or newline. Here is a simple +example taken from a partial list of C reserved words: + +@example +@group +# These are a few C reserved words, see the c.gperf file +# for a complete list of ANSI C reserved words. +unsigned +sizeof +switch +signed +if +default +for +while +return +@end group +@end example + +Note that unlike @code{flex} or @code{bison} the first @samp{%%} marker +may be elided if the declaration section is empty. + +Additional fields may optionally follow the leading keyword. Fields +should be separated by commas, and terminate at the end of line. What +these fields mean is entirely up to you; they are used to initialize the +elements of the user-defined @code{struct} provided by you in the +declaration section. If the @samp{-t} option is @emph{not} enabled +these fields are simply ignored. All previous examples except the last +one contain keyword attributes. + +@node Functions, , Keywords, Input Format +@subsection Including Additional C Functions + +The optional third section also corresponds closely with conventions +found in @code{flex} and @code{bison}. All text in this section, +starting at the final @samp{%%} and extending to the end of the input +file, is included verbatim into the generated output file. Naturally, +it is your responsibility to ensure that the code contained in this +section is valid C. + +@node Output Format, Binary Strings, Input Format, Description +@section Output Format for Generated C Code with @code{gperf} +@cindex hash table + +Several options control how the generated C code appears on the standard +output. Two C function are generated. They are called @code{hash} and +@code{in_word_set}, although you may modify their names with a command-line +option. Both functions require two arguments, a string, @code{char *} +@var{str}, and a length parameter, @code{int} @var{len}. Their default +function prototypes are as follows: + +@deftypefun {unsigned int} hash (const char * @var{str}, unsigned int @var{len}) +By default, the generated @code{hash} function returns an integer value +created by adding @var{len} to several user-specified @var{str} key +positions indexed into an @dfn{associated values} table stored in a +local static array. The associated values table is constructed +internally by @code{gperf} and later output as a static local C array +called @samp{hash_table}; its meaning and properties are described below +(@pxref{Implementation}). The relevant key positions are specified via +the @samp{-k} option when running @code{gperf}, as detailed in the +@emph{Options} section below(@pxref{Options}). +@end deftypefun + +@deftypefun {} in_word_set (const char * @var{str}, unsigned int @var{len}) +If @var{str} is in the keyword set, returns a pointer to that +keyword. More exactly, if the option @samp{-t} was given, it returns +a pointer to the matching keyword's structure. Otherwise it returns +@code{NULL}. +@end deftypefun + +If the option @samp{-c} is not used, @var{str} must be a NUL terminated +string of exactly length @var{len}. If @samp{-c} is used, @var{str} must +simply be an array of @var{len} characters and does not need to be NUL +terminated. + +The code generated for these two functions is affected by the following +options: + +@table @samp +@item -t +@itemx --struct-type +Make use of the user-defined @code{struct}. + +@item -S @var{total-switch-statements} +@itemx --switch=@var{total-switch-statements} +@cindex @code{switch} +Generate 1 or more C @code{switch} statement rather than use a large, +(and potentially sparse) static array. Although the exact time and +space savings of this approach vary according to your C compiler's +degree of optimization, this method often results in smaller and faster +code. +@end table + +If the @samp{-t} and @samp{-S} options are omitted, the default action +is to generate a @code{char *} array containing the keys, together with +additional null strings used for padding the array. By experimenting +with the various input and output options, and timing the resulting C +code, you can determine the best option choices for different keyword +set characteristics. + +@node Binary Strings, , Output Format, Description +@section Use of NUL characters +@cindex NUL + +By default, the code generated by @code{gperf} operates on zero +terminated strings, the usual representation of strings in C. This means +that the keywords in the input file must not contain NUL characters, +and the @var{str} argument passed to @code{hash} or @code{in_word_set} +must be NUL terminated and have exactly length @var{len}. + +If option @samp{-c} is used, then the @var{str} argument does not need +to be NUL terminated. The code generated by @code{gperf} will only +access the first @var{len}, not @var{len+1}, bytes starting at @var{str}. +However, the keywords in the input file still must not contain NUL +characters. + +If option @samp{-l} is used, then the hash table performs binary +comparison. The keywords in the input file may contain NUL characters, +written in string syntax as @code{\000} or @code{\x00}, and the code +generated by @code{gperf} will treat NUL like any other character. +Also, in this case the @samp{-c} option is ignored. + +@node Options, Bugs, Description, Top +@chapter Invoking @code{gperf} + +There are @emph{many} options to @code{gperf}. They were added to make +the program more convenient for use with real applications. ``On-line'' +help is readily available via the @samp{-h} option. Here is the +complete list of options. + +@menu +* Input Details:: Options that affect Interpretation of the Input File +* Output Language:: Specifying the Language for the Output Code +* Output Details:: Fine tuning Details in the Output Code +* Algorithmic Details:: Changing the Algorithms employed by @code{gperf} +* Verbosity:: Informative Output +@end menu + +@node Input Details, Output Language, Options, Options +@section Options that affect Interpretation of the Input File + +@table @samp +@item -e @var{keyword-delimiter-list} +@itemx --delimiters=@var{keyword-delimiter-list} +@cindex Delimiters +Allows the user to provide a string containing delimiters used to +separate keywords from their attributes. The default is ",\n". This +option is essential if you want to use keywords that have embedded +commas or newlines. One useful trick is to use -e'TAB', where TAB is +the literal tab character. + +@item -t +@itemx --struct-type +Allows you to include a @code{struct} type declaration for generated +code. Any text before a pair of consecutive @samp{%%} is considered +part of the type declaration. Keywords and additional fields may follow +this, one group of fields per line. A set of examples for generating +perfect hash tables and functions for Ada, C, C++, Pascal, Modula 2, +Modula 3 and JavaScript reserved words are distributed with this release. +@end table + +@node Output Language, Output Details, Input Details, Options +@section Options to specify the Language for the Output Code + +@table @samp +@item -L @var{generated-language-name} +@itemx --language=@var{generated-language-name} +Instructs @code{gperf} to generate code in the language specified by the +option's argument. Languages handled are currently: + +@table @samp +@item KR-C +Old-style K&R C. This language is understood by old-style C compilers and +ANSI C compilers, but ANSI C compilers may flag warnings (or even errors) +because of lacking @samp{const}. + +@item C +Common C. This language is understood by ANSI C compilers, and also by +old-style C compilers, provided that you @code{#define const} to empty +for compilers which don't know about this keyword. + +@item ANSI-C +ANSI C. This language is understood by ANSI C compilers and C++ compilers. + +@item C++ +C++. This language is understood by C++ compilers. +@end table + +The default is C. + +@item -a +This option is supported for compatibility with previous releases of +@code{gperf}. It does not do anything. + +@item -g +This option is supported for compatibility with previous releases of +@code{gperf}. It does not do anything. +@end table + +@node Output Details, Algorithmic Details, Output Language, Options +@section Options for fine tuning Details in the Output Code + +@table @samp +@item -K @var{key-name} +@itemx --slot-name=@var{key-name} +@cindex Slot name +This option is only useful when option @samp{-t} has been given. +By default, the program assumes the structure component identifier for +the keyword is @samp{name}. This option allows an arbitrary choice of +identifier for this component, although it still must occur as the first +field in your supplied @code{struct}. + +@item -F @var{initializers} +@itemx --initializer-suffix=@var{initializers} +@cindex Initializers +This option is only useful when option @samp{-t} has been given. +It permits to specify initializers for the structure members following +@var{key name} in empty hash table entries. The list of initializers +should start with a comma. By default, the emitted code will +zero-initialize structure members following @var{key name}. + +@item -H @var{hash-function-name} +@itemx --hash-fn-name=@var{hash-function-name} +Allows you to specify the name for the generated hash function. Default +name is @samp{hash}. This option permits the use of two hash tables in +the same file. + +@item -N @var{lookup-function-name} +@itemx --lookup-fn-name=@var{lookup-function-name} +Allows you to specify the name for the generated lookup function. +Default name is @samp{in_word_set}. This option permits completely +automatic generation of perfect hash functions, especially when multiple +generated hash functions are used in the same application. + +@item -Z @var{class-name} +@itemx --class-name=@var{class-name} +@cindex Class name +This option is only useful when option @samp{-L C++} has been given. It +allows you to specify the name of generated C++ class. Default name is +@code{Perfect_Hash}. + +@item -7 +@itemx --seven-bit +This option specifies that all strings that will be passed as arguments +to the generated hash function and the generated lookup function will +solely consist of 7-bit ASCII characters (characters in the range 0..127). +(Note that the ANSI C functions @code{isalnum} and @code{isgraph} do +@emph{not} guarantee that a character is in this range. Only an explicit +test like @samp{c >= 'A' && c <= 'Z'} guarantees this.) This was the +default in versions of @code{gperf} earlier than 2.7; now the default is +to assume 8-bit characters. + +@item -c +@itemx --compare-strncmp +Generates C code that uses the @code{strncmp} function to perform +string comparisons. The default action is to use @code{strcmp}. + +@item -C +@itemx --readonly-tables +Makes the contents of all generated lookup tables constant, i.e., +``readonly''. Many compilers can generate more efficient code for this +by putting the tables in readonly memory. + +@item -E +@itemx --enum +Define constant values using an enum local to the lookup function rather +than with #defines. This also means that different lookup functions can +reside in the same file. Thanks to James Clark @code{<jjc@@ai.mit.edu>}. + +@item -I +@itemx --includes +Include the necessary system include file, @code{<string.h>}, at the +beginning of the code. By default, this is not done; the user must +include this header file himself to allow compilation of the code. + +@item -G +@itemx --global +Generate the static table of keywords as a static global variable, +rather than hiding it inside of the lookup function (which is the +default behavior). + +@item -W @var{hash-table-array-name} +@itemx --word-array-name=@var{hash-table-array-name} +@cindex Array name +Allows you to specify the name for the generated array containing the +hash table. Default name is @samp{wordlist}. This option permits the +use of two hash tables in the same file, even when the option @samp{-G} +is given. + +@item -S @var{total-switch-statements} +@itemx --switch=@var{total-switch-statements} +@cindex @code{switch} +Causes the generated C code to use a @code{switch} statement scheme, +rather than an array lookup table. This can lead to a reduction in both +time and space requirements for some keyfiles. The argument to this +option determines how many @code{switch} statements are generated. A +value of 1 generates 1 @code{switch} containing all the elements, a +value of 2 generates 2 tables with 1/2 the elements in each +@code{switch}, etc. This is useful since many C compilers cannot +correctly generate code for large @code{switch} statements. This option +was inspired in part by Keith Bostic's original C program. + +@item -T +@itemx --omit-struct-type +Prevents the transfer of the type declaration to the output file. Use +this option if the type is already defined elsewhere. + +@item -p +This option is supported for compatibility with previous releases of +@code{gperf}. It does not do anything. +@end table + +@node Algorithmic Details, Verbosity, Output Details, Options +@section Options for changing the Algorithms employed by @code{gperf} + +@table @samp +@item -k @var{keys} +@itemx --key-positions=@var{keys} +Allows selection of the character key positions used in the keywords' +hash function. The allowable choices range between 1-126, inclusive. +The positions are separated by commas, e.g., @samp{-k 9,4,13,14}; +ranges may be used, e.g., @samp{-k 2-7}; and positions may occur +in any order. Furthermore, the meta-character '*' causes the generated +hash function to consider @strong{all} character positions in each key, +whereas '$' instructs the hash function to use the ``final character'' +of a key (this is the only way to use a character position greater than +126, incidentally). + +For instance, the option @samp{-k 1,2,4,6-10,'$'} generates a hash +function that considers positions 1,2,4,6,7,8,9,10, plus the last +character in each key (which may differ for each key, obviously). Keys +with length less than the indicated key positions work properly, since +selected key positions exceeding the key length are simply not +referenced in the hash function. + +@item -l +@itemx --compare-strlen +Compare key lengths before trying a string comparison. This might cut +down on the number of string comparisons made during the lookup, since +keys with different lengths are never compared via @code{strcmp}. +However, using @samp{-l} might greatly increase the size of the +generated C code if the lookup table range is large (which implies that +the switch option @samp{-S} is not enabled), since the length table +contains as many elements as there are entries in the lookup table. +This option is mandatory for binary comparisons (@pxref{Binary Strings}). + +@item -D +@itemx --duplicates +@cindex Duplicates +Handle keywords whose key position sets hash to duplicate values. +Duplicate hash values occur for two reasons: + +@itemize @bullet +@item +Since @code{gperf} does not backtrack it is possible for it to process +all your input keywords without finding a unique mapping for each word. +However, frequently only a very small number of duplicates occur, and +the majority of keys still require one probe into the table. + +@item +Sometimes a set of keys may have the same names, but possess different +attributes. With the -D option @code{gperf} treats all these keys as +part of an equivalence class and generates a perfect hash function with +multiple comparisons for duplicate keys. It is up to you to completely +disambiguate the keywords by modifying the generated C code. However, +@code{gperf} helps you out by organizing the output. +@end itemize + +Option @samp{-D} is extremely useful for certain large or highly +redundant keyword sets, e.g., assembler instruction opcodes. +Using this option usually means that the generated hash function is no +longer perfect. On the other hand, it permits @code{gperf} to work on +keyword sets that it otherwise could not handle. + +@item -f @var{iteration-amount} +@itemx --fast=@var{iteration-amount} +Generate the perfect hash function ``fast''. This decreases +@code{gperf}'s running time at the cost of minimizing generated +table-size. The iteration amount represents the number of times to +iterate when resolving a collision. `0' means iterate by the number of +keywords. This option is probably most useful when used in conjunction +with options @samp{-D} and/or @samp{-S} for @emph{large} keyword sets. + +@item -i @var{initial-value} +@itemx --initial-asso=@var{initial-value} +Provides an initial @var{value} for the associate values array. Default +is 0. Increasing the initial value helps inflate the final table size, +possibly leading to more time efficient keyword lookups. Note that this +option is not particularly useful when @samp{-S} is used. Also, +@samp{-i} is overridden when the @samp{-r} option is used. + +@item -j @var{jump-value} +@itemx --jump=@var{jump-value} +@cindex Jump value +Affects the ``jump value'', i.e., how far to advance the associated +character value upon collisions. @var{Jump-value} is rounded up to an +odd number, the default is 5. If the @var{jump-value} is 0 @code{gperf} +jumps by random amounts. + +@item -n +@itemx --no-strlen +Instructs the generator not to include the length of a keyword when +computing its hash value. This may save a few assembly instructions in +the generated lookup table. + +@item -o +@itemx --occurrence-sort +Reorders the keywords by sorting the keywords so that frequently +occuring key position set components appear first. A second reordering +pass follows so that keys with ``already determined values'' are placed +towards the front of the keylist. This may decrease the time required +to generate a perfect hash function for many keyword sets, and also +produce more minimal perfect hash functions. The reason for this is +that the reordering helps prune the search time by handling inevitable +collisions early in the search process. On the other hand, if the +number of keywords is @emph{very} large using @samp{-o} may +@emph{increase} @code{gperf}'s execution time, since collisions will +begin earlier and continue throughout the remainder of keyword +processing. See Cichelli's paper from the January 1980 Communications +of the ACM for details. + +@item -r +@itemx --random +Utilizes randomness to initialize the associated values table. This +frequently generates solutions faster than using deterministic +initialization (which starts all associated values at 0). Furthermore, +using the randomization option generally increases the size of the +table. If @code{gperf} has difficultly with a certain keyword set try using +@samp{-r} or @samp{-D}. + +@item -s @var{size-multiple} +@itemx --size-multiple=@var{size-multiple} +Affects the size of the generated hash table. The numeric argument for +this option indicates ``how many times larger or smaller'' the maximum +associated value range should be, in relationship to the number of keys. +If the @var{size-multiple} is negative the maximum associated value is +calculated by @emph{dividing} it into the total number of keys. For +example, a value of 3 means ``allow the maximum associated value to be +about 3 times larger than the number of input keys''. + +Conversely, a value of -3 means ``allow the maximum associated value to +be about 3 times smaller than the number of input keys''. Negative +values are useful for limiting the overall size of the generated hash +table, though this usually increases the number of duplicate hash +values. + +If `generate switch' option @samp{-S} is @emph{not} enabled, the maximum +associated value influences the static array table size, and a larger +table should decrease the time required for an unsuccessful search, at +the expense of extra table space. + +The default value is 1, thus the default maximum associated value about +the same size as the number of keys (for efficiency, the maximum +associated value is always rounded up to a power of 2). The actual +table size may vary somewhat, since this technique is essentially a +heuristic. In particular, setting this value too high slows down +@code{gperf}'s runtime, since it must search through a much larger range +of values. Judicious use of the @samp{-f} option helps alleviate this +overhead, however. +@end table + +@node Verbosity, , Algorithmic Details, Options +@section Informative Output + +@table @samp +@item -h +@itemx --help +Prints a short summary on the meaning of each program option. Aborts +further program execution. + +@item -v +@itemx --version +Prints out the current version number. + +@item -d +@itemx --debug +Enables the debugging option. This produces verbose diagnostics to +``standard error'' when @code{gperf} is executing. It is useful both for +maintaining the program and for determining whether a given set of +options is actually speeding up the search for a solution. Some useful +information is dumped at the end of the program when the @samp{-d} +option is enabled. +@end table + +@node Bugs, Projects, Options, Top +@chapter Known Bugs and Limitations with @code{gperf} + +The following are some limitations with the current release of +@code{gperf}: + +@itemize @bullet +@item +The @code{gperf} utility is tuned to execute quickly, and works quickly +for small to medium size data sets (around 1000 keywords). It is +extremely useful for maintaining perfect hash functions for compiler +keyword sets. Several recent enhancements now enable @code{gperf} to +work efficiently on much larger keyword sets (over 15,000 keywords). +When processing large keyword sets it helps greatly to have over 8 megs +of RAM. + +However, since @code{gperf} does not backtrack no guaranteed solution +occurs on every run. On the other hand, it is usually easy to obtain a +solution by varying the option parameters. In particular, try the +@samp{-r} option, and also try changing the default arguments to the +@samp{-s} and @samp{-j} options. To @emph{guarantee} a solution, use +the @samp{-D} and @samp{-S} options, although the final results are not +likely to be a @emph{perfect} hash function anymore! Finally, use the +@samp{-f} option if you want @code{gperf} to generate the perfect hash +function @emph{fast}, with less emphasis on making it minimal. + +@item +The size of the generate static keyword array can get @emph{extremely} +large if the input keyword file is large or if the keywords are quite +similar. This tends to slow down the compilation of the generated C +code, and @emph{greatly} inflates the object code size. If this +situation occurs, consider using the @samp{-S} option to reduce data +size, potentially increasing keyword recognition time a negligible +amount. Since many C compilers cannot correctly generated code for +large switch statements it is important to qualify the @var{-S} option +with an appropriate numerical argument that controls the number of +switch statements generated. + +@item +The maximum number of key positions selected for a given key has an +arbitrary limit of 126. This restriction should be removed, and if +anyone considers this a problem write me and let me know so I can remove +the constraint. +@end itemize + +@node Projects, Implementation, Bugs, Top +@chapter Things Still Left to Do + +It should be ``relatively'' easy to replace the current perfect hash +function algorithm with a more exhaustive approach; the perfect hash +module is essential independent from other program modules. Additional +worthwhile improvements include: + +@itemize @bullet +@item +Make the algorithm more robust. At present, the program halts with an +error diagnostic if it can't find a direct solution and the @samp{-D} +option is not enabled. A more comprehensive, albeit computationally +expensive, approach would employ backtracking or enable alternative +options and retry. It's not clear how helpful this would be, in +general, since most search sets are rather small in practice. + +@item +Another useful extension involves modifying the program to generate +``minimal'' perfect hash functions (under certain circumstances, the +current version can be rather extravagant in the generated table size). +Again, this is mostly of theoretical interest, since a sparse table +often produces faster lookups, and use of the @samp{-S} @code{switch} +option can minimize the data size, at the expense of slightly longer +lookups (note that the gcc compiler generally produces good code for +@code{switch} statements, reducing the need for more complex schemes). + +@item +In addition to improving the algorithm, it would also be useful to +generate a C++ class or Ada package as the code output, in addition to +the current C routines. +@end itemize + +@node Implementation, Bibliography, Projects, Top +@chapter Implementation Details of GNU @code{gperf} + +A paper describing the high-level description of the data structures and +algorithms used to implement @code{gperf} will soon be available. This +paper is useful not only from a maintenance and enhancement perspective, +but also because they demonstrate several clever and useful programming +techniques, e.g., `Iteration Number' boolean arrays, double +hashing, a ``safe'' and efficient method for reading arbitrarily long +input from a file, and a provably optimal algorithm for simultaneously +determining both the minimum and maximum elements in a list. + +@page + +@node Bibliography, Concept Index, Implementation, Top +@chapter Bibliography + +[1] Chang, C.C.: @i{A Scheme for Constructing Ordered Minimal Perfect +Hashing Functions} Information Sciences 39(1986), 187-195. + +[2] Cichelli, Richard J. @i{Author's Response to ``On Cichelli's Minimal Perfect Hash +Functions Method''} Communications of the ACM, 23, 12(December 1980), 729. + +[3] Cichelli, Richard J. @i{Minimal Perfect Hash Functions Made Simple} +Communications of the ACM, 23, 1(January 1980), 17-19. + +[4] Cook, C. R. and Oldehoeft, R.R. @i{A Letter Oriented Minimal +Perfect Hashing Function} SIGPLAN Notices, 17, 9(September 1982), 18-27. + +[5] Cormack, G. V. and Horspool, R. N. S. and Kaiserwerth, M. +@i{Practical Perfect Hashing} Computer Journal, 28, 1(January 1985), 54-58. + +[6] Jaeschke, G. @i{Reciprocal Hashing: A Method for Generating Minimal +Perfect Hashing Functions} Communications of the ACM, 24, 12(December +1981), 829-833. + +[7] Jaeschke, G. and Osterburg, G. @i{On Cichelli's Minimal Perfect +Hash Functions Method} Communications of the ACM, 23, 12(December 1980), +728-729. + +[8] Sager, Thomas J. @i{A Polynomial Time Generator for Minimal Perfect +Hash Functions} Communications of the ACM, 28, 5(December 1985), 523-532 + +[9] Schmidt, Douglas C. @i{GPERF: A Perfect Hash Function Generator} +Second USENIX C++ Conference Proceedings, April 1990. + +[10] Sebesta, R.W. and Taylor, M.A. @i{Minimal Perfect Hash Functions +for Reserved Word Lists} SIGPLAN Notices, 20, 12(September 1985), 47-53. + +[11] Sprugnoli, R. @i{Perfect Hashing Functions: A Single Probe +Retrieving Method for Static Sets} Communications of the ACM, 20 +11(November 1977), 841-850. + +[12] Stallman, Richard M. @i{Using and Porting GNU CC} Free Software Foundation, +1988. + +[13] Stroustrup, Bjarne @i{The C++ Programming Language.} Addison-Wesley, 1986. + +[14] Tiemann, Michael D. @i{User's Guide to GNU C++} Free Software +Foundation, 1989. + +@node Concept Index, , Bibliography, Top +@unnumbered Concept Index + +@printindex cp + +@contents +@bye diff --git a/contrib/gperf/doc/gpl.texinfo b/contrib/gperf/doc/gpl.texinfo new file mode 100644 index 0000000..be2dc25 --- /dev/null +++ b/contrib/gperf/doc/gpl.texinfo @@ -0,0 +1,398 @@ +@c This GPL is meant to be included from other files. +@c To format a standalone GPL, use license.texi. + +@center Version 2, June 1991 + +@display +Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc., +59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +@end display + +@unnumberedsec Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU 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. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), 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 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 show them these terms so they know 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. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + +@iftex +@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +@end iftex +@ifinfo +@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +@end ifinfo + +@enumerate 0 +@item +This License 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 derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term ``modification''.) Each licensee is addressed as ``you''. + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + +@item +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 License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +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. + +@item +You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + +@enumerate a +@item +You must cause the modified files to carry prominent notices +stating that you changed the files and the date of any change. + +@item +You must cause any work that you distribute or publish, that in +whole or in part contains or is derived from the Program or any +part thereof, to be licensed as a whole at no charge to all third +parties under the terms of this License. + +@item +If the modified program normally reads commands interactively +when run, you must cause it, when started running for such +interactive use in the most ordinary 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 +License. (Exception: if the Program itself is interactive but +does not normally print such an announcement, your work based on +the Program is not required to print an announcement.) +@end enumerate + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +@item +You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + +@enumerate a +@item +Accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of Sections +1 and 2 above on a medium customarily used for software interchange; or, + +@item +Accompany it with a written offer, valid for at least three +years, to give any third party, for a charge no more than your +cost of physically performing source distribution, a complete +machine-readable copy of the corresponding source code, to be +distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, + +@item +Accompany it with the information you received as to the offer +to distribute corresponding source code. (This alternative is +allowed only for noncommercial distribution and only if you +received the program in object code or executable form with such +an offer, in accord with Subsection b above.) +@end enumerate + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + +@item +You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + +@item +You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing 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 for copying, distributing or modifying +the Program or works based on it. + +@item +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. +You are not responsible for enforcing compliance by third parties to +this License. + +@item +If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +@item +If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + +@item +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 this 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 +this License, you may choose any version ever published by the Free Software +Foundation. + +@item +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. + +@iftex +@vskip -@baselineskip +@vskip -@baselineskip +@heading NO WARRANTY +@end iftex +@ifinfo +@center NO WARRANTY +@end ifinfo + +@item +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. + +@item +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 enumerate + +@iftex +@heading END OF TERMS AND CONDITIONS +@end iftex +@ifinfo +@center END OF TERMS AND CONDITIONS +@end ifinfo + +@page +@unnumberedsec 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 the public, 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. + +@smallexample +@var{one line to give the program's name and an idea of what it does.} +Copyright (C) @var{year} @var{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 2 +of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +@end smallexample + +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: + +@smallexample +Gnomovision version 69, Copyright (C) @var{year} @var{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. +@end smallexample + +The hypothetical commands @samp{show w} and @samp{show c} should show +the appropriate parts of the General Public License. Of course, the +commands you use may be called something other than @samp{show w} and +@samp{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 is a sample; alter the names: + +@example +@group +Yoyodyne, Inc., hereby disclaims all copyright +interest in the program `Gnomovision' +(which makes passes at compilers) written +by James Hacker. + +@var{signature of Ty Coon}, 1 April 1989 +Ty Coon, President of Vice +@end group +@end example + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/contrib/gperf/doc/help2man b/contrib/gperf/doc/help2man new file mode 100755 index 0000000..2c81647 --- /dev/null +++ b/contrib/gperf/doc/help2man @@ -0,0 +1,513 @@ +#!/usr/bin/perl -w + +# Generate a short man page from --help and --version output. +# Copyright © 1997, 1998, 1999, 2000 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 2, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Written by Brendan O'Dea <bod@compusol.com.au> +# Available from ftp://ftp.gnu.org/gnu/help2man/ + +use 5.004; +use strict; +use Getopt::Long; +use Text::Tabs qw(expand); +use POSIX qw(strftime setlocale LC_TIME); + +my $this_program = 'help2man'; +my $this_version = '1.022'; +my $version_info = <<EOT; +GNU $this_program $this_version + +Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Written by Brendan O'Dea <bod\@compusol.com.au> +EOT + +my $help_info = <<EOT; +`$this_program' generates a man page out of `--help' and `--version' output. + +Usage: $this_program [OPTION]... EXECUTABLE + + -n, --name=STRING use `STRING' as the description for the NAME paragraph + -s, --section=SECTION use `SECTION' as the section for the man page + -i, --include=FILE include material from `FILE' + -I, --opt-include=FILE include material from `FILE' if it exists + -o, --output=FILE send output to `FILE' + -N, --no-info suppress pointer to Texinfo manual + --help print this help, then exit + --version print version number, then exit + +EXECUTABLE should accept `--help' and `--version' options. + +Report bugs to <bug-help2man\@gnu.org>. +EOT + +my $section = 1; +my ($opt_name, @opt_include, $opt_output, $opt_no_info); + +# Parse options. +Getopt::Long::config('bundling'); +GetOptions ( + 'n|name=s' => \$opt_name, + 's|section=s' => \$section, + 'i|include=s' => sub { push @opt_include, [ pop, 1 ] }, + 'I|opt-include=s' => sub { push @opt_include, [ pop, 0 ] }, + 'o|output=s' => \$opt_output, + 'N|no-info' => \$opt_no_info, + help => sub { print $help_info; exit }, + version => sub { print $version_info; exit }, +) or die $help_info; + +die $help_info unless @ARGV == 1; + +my %include = (); +my %append = (); +my @include = (); # retain order given in include file + +# Provide replacement `quote-regex' operator for pre-5.005. +BEGIN { eval q(sub qr { '' =~ $_[0]; $_[0] }) if $] < 5.005 } + +# Process include file (if given). Format is: +# +# [section name] +# verbatim text +# +# or +# +# /pattern/ +# verbatim text +# + +for (@opt_include) +{ + my ($inc, $required) = @$_; + + next unless -f $inc or $required; + die "$this_program: can't open `$inc' ($!)\n" + unless open INC, $inc; + + my $key; + my $hash = \%include; + + while (<INC>) + { + # [section] + if (/^\[([^]]+)\]/) + { + $key = uc $1; + $key =~ s/^\s+//; + $key =~ s/\s+$//; + $hash = \%include; + push @include, $key unless $include{$key}; + next; + } + + # /pattern/ + if (m!^/(.*)/([ims]*)!) + { + my $pat = $2 ? "(?$2)$1" : $1; + + # Check pattern. + eval { $key = qr($pat) }; + if ($@) + { + $@ =~ s/ at .*? line \d.*//; + die "$inc:$.:$@"; + } + + $hash = \%append; + next; + } + + # Silently ignore anything before the first + # section--allows for comments and revision info. + next unless $key; + + $hash->{$key} ||= ''; + $hash->{$key} .= $_; + } + + close INC; + + die "$this_program: no valid information found in `$inc'\n" + unless $key; +} + +# Compress trailing blank lines. +for my $hash (\(%include, %append)) +{ + for (keys %$hash) { $hash->{$_} =~ s/\n+$/\n/ } +} + +# Turn off localisation of executable's ouput. +@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; + +# Turn off localisation of date (for strftime). +setlocale LC_TIME, 'C'; + +# Grab help and version info from executable. +my ($help_text, $version_text) = map { + join '', map { s/ +$//; expand $_ } `$ARGV[0] --$_ 2>/dev/null` + or die "$this_program: can't get `--$_' info from $ARGV[0]\n" +} qw(help version); + +my $date = strftime "%B %Y", localtime; +(my $program = $ARGV[0]) =~ s!.*/!!; +my $package = $program; +my $version; + +if ($opt_output) +{ + unlink $opt_output + or die "$this_program: can't unlink $opt_output ($!)\n" + if -e $opt_output; + + open STDOUT, ">$opt_output" + or die "$this_program: can't create $opt_output ($!)\n"; +} + +# The first line of the --version information is assumed to be in one +# of the following formats: +# +# <version> +# <program> <version> +# {GNU,Free} <program> <version> +# <program> ({GNU,Free} <package>) <version> +# <program> - {GNU,Free} <package> <version> +# +# and seperated from any copyright/author details by a blank line. + +($_, $version_text) = split /\n+/, $version_text, 2; + +if (/^(\S+) +\(((?:GNU|Free) +[^)]+)\) +(.*)/ or + /^(\S+) +- *((?:GNU|Free) +\S+) +(.*)/) +{ + $program = $1; + $package = $2; + $version = $3; +} +elsif (/^((?:GNU|Free) +)?(\S+) +(.*)/) +{ + $program = $2; + $package = $1 ? "$1$2" : $2; + $version = $3; +} +else +{ + $version = $_; +} + +$program =~ s!.*/!!; + +# No info for `info' itself. +$opt_no_info = 1 if $program eq 'info'; + +# --name overrides --include contents. +$include{NAME} = "$program \\- $opt_name\n" if $opt_name; + +# Default (useless) NAME paragraph. +$include{NAME} ||= "$program \\- manual page for $program $version\n"; + +# Man pages traditionally have the page title in caps. +my $PROGRAM = uc $program; + +# Extract usage clause(s) [if any] for SYNOPSIS. +if ($help_text =~ s/^Usage:( +(\S+))(.*)((?:\n(?: {6}\1| *or: +\S).*)*)//m) +{ + my @syn = $2 . $3; + + if ($_ = $4) + { + s/^\n//; + for (split /\n/) { s/^ *(or: +)?//; push @syn, $_ } + } + + my $synopsis = ''; + for (@syn) + { + $synopsis .= ".br\n" if $synopsis; + s!^\S*/!!; + s/^(\S+) *//; + $synopsis .= ".B $1\n"; + s/\s+$//; + s/(([][]|\.\.+)+)/\\fR$1\\fI/g; + s/^/\\fI/ unless s/^\\fR//; + $_ .= '\fR'; + s/(\\fI)( *)/$2$1/g; + s/\\fI\\fR//g; + s/^\\fR//; + s/\\fI$//; + s/^\./\\&./; + + $synopsis .= "$_\n"; + } + + $include{SYNOPSIS} ||= $synopsis; +} + +# Process text, initial section is DESCRIPTION. +my $sect = 'DESCRIPTION'; +$_ = "$help_text\n\n$version_text"; + +# Normalise paragraph breaks. +s/^\n+//; +s/\n*$/\n/; +s/\n\n+/\n\n/g; + +# Temporarily exchange leading dots and backslashes for tokens. +s/^\./\x80/mg; +s/\\/\x81/g; + +# Start a new paragraph (if required) for these. +s/([^\n])\n(Report +bugs|Email +bug +reports +to|Written +by)/$1\n\n$2/g; + +sub convert_option; + +while (length) +{ + # Convert some standard paragraph names. + if (s/^(Options|Examples): *\n//) + { + $sect = uc $1; + next; + } + + # Copyright section + if (/^Copyright +[(\xa9]/) + { + $sect = 'COPYRIGHT'; + $include{$sect} ||= ''; + $include{$sect} .= ".PP\n" if $include{$sect}; + + my $copy; + ($copy, $_) = split /\n\n/, $_, 2; + + for ($copy) + { + # Add back newline + s/\n*$/\n/; + + # Convert iso9959-1 copyright symbol or (c) to nroff + # character. + s/^Copyright +(?:\xa9|\([Cc]\))/Copyright \\(co/mg; + + # Insert line breaks before additional copyright messages + # and the disclaimer. + s/(.)\n(Copyright |This +is +free +software)/$1\n.br\n$2/g; + + # Join hyphenated lines. + s/([A-Za-z])-\n */$1/g; + } + + $include{$sect} .= $copy; + $_ ||= ''; + next; + } + + # Catch bug report text. + if (/^(Report +bugs|Email +bug +reports +to) /) + { + $sect = 'REPORTING BUGS'; + } + + # Author section. + elsif (/^Written +by/) + { + $sect = 'AUTHOR'; + } + + # Examples, indicated by an indented leading $, % or > are + # rendered in a constant width font. + if (/^( +)([\$\%>] )\S/) + { + my $indent = $1; + my $prefix = $2; + my $break = '.IP'; + $include{$sect} ||= ''; + while (s/^$indent\Q$prefix\E(\S.*)\n*//) + { + $include{$sect} .= "$break\n\\f(CW$prefix$1\\fR\n"; + $break = '.br'; + } + + next; + } + + my $matched = ''; + $include{$sect} ||= ''; + + # Sub-sections have a trailing colon and the second line indented. + if (s/^(\S.*:) *\n / /) + { + $matched .= $& if %append; + $include{$sect} .= qq(.SS "$1"\n); + } + + my $indent = 0; + my $content = ''; + + # Option with description. + if (s/^( {1,10}([+-]\S.*?))(?:( +)|\n( {20,}))(\S.*)\n//) + { + $matched .= $& if %append; + $indent = length ($4 || "$1$3"); + $content = ".TP\n\x82$2\n\x82$5\n"; + unless ($4) + { + # Indent may be different on second line. + $indent = length $& if /^ {20,}/; + } + } + + # Option without description. + elsif (s/^ {1,10}([+-]\S.*)\n//) + { + $matched .= $& if %append; + $content = ".HP\n\x82$1\n"; + $indent = 80; # not continued + } + + # Indented paragraph with tag. + elsif (s/^( +(\S.*?) +)(\S.*)\n//) + { + $matched .= $& if %append; + $indent = length $1; + $content = ".TP\n\x82$2\n\x82$3\n"; + } + + # Indented paragraph. + elsif (s/^( +)(\S.*)\n//) + { + $matched .= $& if %append; + $indent = length $1; + $content = ".IP\n\x82$2\n"; + } + + # Left justified paragraph. + else + { + s/(.*)\n//; + $matched .= $& if %append; + $content = ".PP\n" if $include{$sect}; + $content .= "$1\n"; + } + + # Append continuations. + while (s/^ {$indent}(\S.*)\n//) + { + $matched .= $& if %append; + $content .= "\x82$1\n" + } + + # Move to next paragraph. + s/^\n+//; + + for ($content) + { + # Leading dot protection. + s/\x82\./\x80/g; + s/\x82//g; + + # Convert options. + s/(^| )(-[][\w=-]+)/$1 . convert_option $2/mge; + } + + # Check if matched paragraph contains /pat/. + if (%append) + { + for my $pat (keys %append) + { + if ($matched =~ $pat) + { + $content .= ".PP\n" unless $append{$pat} =~ /^\./; + $content .= $append{$pat}; + } + } + } + + $include{$sect} .= $content; +} + +# Refer to the real documentation. +unless ($opt_no_info) +{ + $sect = 'SEE ALSO'; + $include{$sect} ||= ''; + $include{$sect} .= ".PP\n" if $include{$sect}; + $include{$sect} .= <<EOT; +The full documentation for +.B $program +is maintained as a Texinfo manual. If the +.B info +and +.B $program +programs are properly installed at your site, the command +.IP +.B info $program +.PP +should give you access to the complete manual. +EOT +} + +# Output header. +print <<EOT; +.\\" DO NOT MODIFY THIS FILE! It was generated by $this_program $this_version. +.TH $PROGRAM "$section" "$date" "$package $version" FSF +EOT + +# Section ordering. +my @pre = qw(NAME SYNOPSIS DESCRIPTION OPTIONS EXAMPLES); +my @post = ('AUTHOR', 'REPORTING BUGS', 'COPYRIGHT', 'SEE ALSO'); +my $filter = join '|', @pre, @post; + +# Output content. +for (@pre, (grep ! /^($filter)$/o, @include), @post) +{ + if ($include{$_}) + { + my $quote = /\W/ ? '"' : ''; + print ".SH $quote$_$quote\n"; + + for ($include{$_}) + { + # Replace leading dot an backslash tokens. + s/\x80/\\&./g; + s/\x81/\\e/g; + print; + } + } +} + +exit; + +# Convert option dashes to \- to stop nroff from hyphenating 'em, and +# embolden. Option arguments get italicised. +sub convert_option +{ + local $_ = '\fB' . shift; + + s/-/\\-/g; + unless (s/\[=(.*)\]$/\\fR[=\\fI$1\\fR]/) + { + s/=(.)/\\fR=\\fI$1/; + s/ (.)/ \\fI$1/; + $_ .= '\fR'; + } + + $_; +} diff --git a/contrib/gperf/doc/texinfo.tex b/contrib/gperf/doc/texinfo.tex new file mode 100644 index 0000000..faad86b --- /dev/null +++ b/contrib/gperf/doc/texinfo.tex @@ -0,0 +1,5999 @@ +% texinfo.tex -- TeX macros to handle Texinfo files. +% +% Load plain if necessary, i.e., if running under initex. +\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi +% +\def\texinfoversion{2000-05-28.15} +% +% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 +% Free Software Foundation, Inc. +% +% This texinfo.tex file 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 2, or (at +% your option) any later version. +% +% This texinfo.tex file 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 texinfo.tex file; see the file COPYING. If not, write +% to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +% In other words, you are welcome to use, share and improve this program. +% You are forbidden to forbid anyone else to use, share and improve +% what you give them. Help stamp out software-hoarding! +% +% Please try the latest version of texinfo.tex before submitting bug +% reports; you can get the latest version from: +% ftp://ftp.gnu.org/gnu/texinfo.tex +% (and all GNU mirrors, see http://www.gnu.org/order/ftp.html) +% ftp://texinfo.org/tex/texinfo.tex +% ftp://us.ctan.org/macros/texinfo/texinfo.tex +% (and all CTAN mirrors, finger ctan@us.ctan.org for a list). +% /home/gd/gnu/doc/texinfo.tex on the GNU machines. +% The texinfo.tex in any given Texinfo distribution could well be out +% of date, so if that's what you're using, please check. +% Texinfo has a small home page at http://texinfo.org/. +% +% Send bug reports to bug-texinfo@gnu.org. Please include including a +% complete document in each bug report with which we can reproduce the +% problem. Patches are, of course, greatly appreciated. +% +% To process a Texinfo manual with TeX, it's most reliable to use the +% texi2dvi shell script that comes with the distribution. For a simple +% manual foo.texi, however, you can get away with this: +% tex foo.texi +% texindex foo.?? +% tex foo.texi +% tex foo.texi +% dvips foo.dvi -o # or whatever, to process the dvi file; this makes foo.ps. +% The extra runs of TeX get the cross-reference information correct. +% Sometimes one run after texindex suffices, and sometimes you need more +% than two; texi2dvi does it as many times as necessary. +% +% It is possible to adapt texinfo.tex for other languages. You can get +% the existing language-specific files from ftp://ftp.gnu.org/gnu/texinfo/. + +\message{Loading texinfo [version \texinfoversion]:} + +% If in a .fmt file, print the version number +% and turn on active characters that we couldn't do earlier because +% they might have appeared in the input file name. +\everyjob{\message{[Texinfo version \texinfoversion]}% + \catcode`+=\active \catcode`\_=\active} + +% Save some parts of plain tex whose names we will redefine. +\let\ptexb=\b +\let\ptexbullet=\bullet +\let\ptexc=\c +\let\ptexcomma=\, +\let\ptexdot=\. +\let\ptexdots=\dots +\let\ptexend=\end +\let\ptexequiv=\equiv +\let\ptexexclam=\! +\let\ptexi=\i +\let\ptexlbrace=\{ +\let\ptexrbrace=\} +\let\ptexstar=\* +\let\ptext=\t + +% We never want plain's outer \+ definition in Texinfo. +% For @tex, we can use \tabalign. +\let\+ = \relax + +\message{Basics,} +\chardef\other=12 + +% If this character appears in an error message or help string, it +% starts a new line in the output. +\newlinechar = `^^J + +% Set up fixed words for English if not already set. +\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi +\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi +\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi +\ifx\putwordin\undefined \gdef\putwordin{in}\fi +\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi +\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi +\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi +\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi +\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi +\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi +\ifx\putwordof\undefined \gdef\putwordof{of}\fi +\ifx\putwordon\undefined \gdef\putwordon{on}\fi +\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi +\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi +\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi +\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi +\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi +\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi +\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi +% +\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi +\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi +\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi +\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi +\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi +\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi +\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi +\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi +\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi +\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi +\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi +\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi +% +\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi +\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi +\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi +\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi +\ifx\putwordDeftypevar\undefined\gdef\putwordDeftypevar{Variable}\fi +\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi +\ifx\putwordDeftypefun\undefined\gdef\putwordDeftypefun{Function}\fi + +% Ignore a token. +% +\def\gobble#1{} + +\hyphenation{ap-pen-dix} +\hyphenation{mini-buf-fer mini-buf-fers} +\hyphenation{eshell} +\hyphenation{white-space} + +% Margin to add to right of even pages, to left of odd pages. +\newdimen \bindingoffset +\newdimen \normaloffset +\newdimen\pagewidth \newdimen\pageheight + +% Sometimes it is convenient to have everything in the transcript file +% and nothing on the terminal. We don't just call \tracingall here, +% since that produces some useless output on the terminal. +% +\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% +\ifx\eTeXversion\undefined +\def\loggingall{\tracingcommands2 \tracingstats2 + \tracingpages1 \tracingoutput1 \tracinglostchars1 + \tracingmacros2 \tracingparagraphs1 \tracingrestores1 + \showboxbreadth\maxdimen\showboxdepth\maxdimen +}% +\else +\def\loggingall{\tracingcommands3 \tracingstats2 + \tracingpages1 \tracingoutput1 \tracinglostchars1 + \tracingmacros2 \tracingparagraphs1 \tracingrestores1 + \tracingscantokens1 \tracingassigns1 \tracingifs1 + \tracinggroups1 \tracingnesting2 + \showboxbreadth\maxdimen\showboxdepth\maxdimen +}% +\fi + +% For @cropmarks command. +% Do @cropmarks to get crop marks. +% +\newif\ifcropmarks +\let\cropmarks = \cropmarkstrue +% +% Dimensions to add cropmarks at corners. +% Added by P. A. MacKay, 12 Nov. 1986 +% +\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines +\newdimen\cornerlong \cornerlong=1pc +\newdimen\cornerthick \cornerthick=.3pt +\newdimen\topandbottommargin \topandbottommargin=.75in + +% Main output routine. +\chardef\PAGE = 255 +\output = {\onepageout{\pagecontents\PAGE}} + +\newbox\headlinebox +\newbox\footlinebox + +% \onepageout takes a vbox as an argument. Note that \pagecontents +% does insertions, but you have to call it yourself. +\def\onepageout#1{% + \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi + % + \ifodd\pageno \advance\hoffset by \bindingoffset + \else \advance\hoffset by -\bindingoffset\fi + % + % Do this outside of the \shipout so @code etc. will be expanded in + % the headline as they should be, not taken literally (outputting ''code). + \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% + \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% + % + {% + % Have to do this stuff outside the \shipout because we want it to + % take effect in \write's, yet the group defined by the \vbox ends + % before the \shipout runs. + % + \escapechar = `\\ % use backslash in output files. + \indexdummies % don't expand commands in the output. + \normalturnoffactive % \ in index entries must not stay \, e.g., if + % the page break happens to be in the middle of an example. + \shipout\vbox{% + % Do this early so pdf references go to the beginning of the page. + \ifpdfmakepagedest \pdfmkdest{\the\pageno} \fi + % + \ifcropmarks \vbox to \outervsize\bgroup + \hsize = \outerhsize + \vskip-\topandbottommargin + \vtop to0pt{% + \line{\ewtop\hfil\ewtop}% + \nointerlineskip + \line{% + \vbox{\moveleft\cornerthick\nstop}% + \hfill + \vbox{\moveright\cornerthick\nstop}% + }% + \vss}% + \vskip\topandbottommargin + \line\bgroup + \hfil % center the page within the outer (page) hsize. + \ifodd\pageno\hskip\bindingoffset\fi + \vbox\bgroup + \fi + % + \unvbox\headlinebox + \pagebody{#1}% + \ifdim\ht\footlinebox > 0pt + % Only leave this space if the footline is nonempty. + % (We lessened \vsize for it in \oddfootingxxx.) + % The \baselineskip=24pt in plain's \makefootline has no effect. + \vskip 2\baselineskip + \unvbox\footlinebox + \fi + % + \ifcropmarks + \egroup % end of \vbox\bgroup + \hfil\egroup % end of (centering) \line\bgroup + \vskip\topandbottommargin plus1fill minus1fill + \boxmaxdepth = \cornerthick + \vbox to0pt{\vss + \line{% + \vbox{\moveleft\cornerthick\nsbot}% + \hfill + \vbox{\moveright\cornerthick\nsbot}% + }% + \nointerlineskip + \line{\ewbot\hfil\ewbot}% + }% + \egroup % \vbox from first cropmarks clause + \fi + }% end of \shipout\vbox + }% end of group with \turnoffactive + \advancepageno + \ifnum\outputpenalty>-20000 \else\dosupereject\fi +} + +\newinsert\margin \dimen\margin=\maxdimen + +\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} +{\catcode`\@ =11 +\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi +% marginal hacks, juha@viisa.uucp (Juha Takala) +\ifvoid\margin\else % marginal info is present + \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi +\dimen@=\dp#1 \unvbox#1 +\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi +\ifr@ggedbottom \kern-\dimen@ \vfil \fi} +} + +% Here are the rules for the cropmarks. Note that they are +% offset so that the space between them is truly \outerhsize or \outervsize +% (P. A. MacKay, 12 November, 1986) +% +\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} +\def\nstop{\vbox + {\hrule height\cornerthick depth\cornerlong width\cornerthick}} +\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} +\def\nsbot{\vbox + {\hrule height\cornerlong depth\cornerthick width\cornerthick}} + +% Parse an argument, then pass it to #1. The argument is the rest of +% the input line (except we remove a trailing comment). #1 should be a +% macro which expects an ordinary undelimited TeX argument. +% +\def\parsearg#1{% + \let\next = #1% + \begingroup + \obeylines + \futurelet\temp\parseargx +} + +% If the next token is an obeyed space (from an @example environment or +% the like), remove it and recurse. Otherwise, we're done. +\def\parseargx{% + % \obeyedspace is defined far below, after the definition of \sepspaces. + \ifx\obeyedspace\temp + \expandafter\parseargdiscardspace + \else + \expandafter\parseargline + \fi +} + +% Remove a single space (as the delimiter token to the macro call). +{\obeyspaces % + \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} + +{\obeylines % + \gdef\parseargline#1^^M{% + \endgroup % End of the group started in \parsearg. + % + % First remove any @c comment, then any @comment. + % Result of each macro is put in \toks0. + \argremovec #1\c\relax % + \expandafter\argremovecomment \the\toks0 \comment\relax % + % + % Call the caller's macro, saved as \next in \parsearg. + \expandafter\next\expandafter{\the\toks0}% + }% +} + +% Since all \c{,omment} does is throw away the argument, we can let TeX +% do that for us. The \relax here is matched by the \relax in the call +% in \parseargline; it could be more or less anything, its purpose is +% just to delimit the argument to the \c. +\def\argremovec#1\c#2\relax{\toks0 = {#1}} +\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} + +% \argremovec{,omment} might leave us with trailing spaces, though; e.g., +% @end itemize @c foo +% will have two active spaces as part of the argument with the +% `itemize'. Here we remove all active spaces from #1, and assign the +% result to \toks0. +% +% This loses if there are any *other* active characters besides spaces +% in the argument -- _ ^ +, for example -- since they get expanded. +% Fortunately, Texinfo does not define any such commands. (If it ever +% does, the catcode of the characters in questionwill have to be changed +% here.) But this means we cannot call \removeactivespaces as part of +% \argremovec{,omment}, since @c uses \parsearg, and thus the argument +% that \parsearg gets might well have any character at all in it. +% +\def\removeactivespaces#1{% + \begingroup + \ignoreactivespaces + \edef\temp{#1}% + \global\toks0 = \expandafter{\temp}% + \endgroup +} + +% Change the active space to expand to nothing. +% +\begingroup + \obeyspaces + \gdef\ignoreactivespaces{\obeyspaces\let =\empty} +\endgroup + + +\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} + +%% These are used to keep @begin/@end levels from running away +%% Call \inENV within environments (after a \begingroup) +\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} +\def\ENVcheck{% +\ifENV\errmessage{Still within an environment; press RETURN to continue} +\endgroup\fi} % This is not perfect, but it should reduce lossage + +% @begin foo is the same as @foo, for now. +\newhelp\EMsimple{Press RETURN to continue.} + +\outer\def\begin{\parsearg\beginxxx} + +\def\beginxxx #1{% +\expandafter\ifx\csname #1\endcsname\relax +{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else +\csname #1\endcsname\fi} + +% @end foo executes the definition of \Efoo. +% +\def\end{\parsearg\endxxx} +\def\endxxx #1{% + \removeactivespaces{#1}% + \edef\endthing{\the\toks0}% + % + \expandafter\ifx\csname E\endthing\endcsname\relax + \expandafter\ifx\csname \endthing\endcsname\relax + % There's no \foo, i.e., no ``environment'' foo. + \errhelp = \EMsimple + \errmessage{Undefined command `@end \endthing'}% + \else + \unmatchedenderror\endthing + \fi + \else + % Everything's ok; the right environment has been started. + \csname E\endthing\endcsname + \fi +} + +% There is an environment #1, but it hasn't been started. Give an error. +% +\def\unmatchedenderror#1{% + \errhelp = \EMsimple + \errmessage{This `@end #1' doesn't have a matching `@#1'}% +} + +% Define the control sequence \E#1 to give an unmatched @end error. +% +\def\defineunmatchedend#1{% + \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% +} + + +% Single-spacing is done by various environments (specifically, in +% \nonfillstart and \quotations). +\newskip\singlespaceskip \singlespaceskip = 12.5pt +\def\singlespace{% + % Why was this kern here? It messes up equalizing space above and below + % environments. --karl, 6may93 + %{\advance \baselineskip by -\singlespaceskip + %\kern \baselineskip}% + \setleading \singlespaceskip +} + +%% Simple single-character @ commands + +% @@ prints an @ +% Kludge this until the fonts are right (grr). +\def\@{{\tt\char64}} + +% This is turned off because it was never documented +% and you can use @w{...} around a quote to suppress ligatures. +%% Define @` and @' to be the same as ` and ' +%% but suppressing ligatures. +%\def\`{{`}} +%\def\'{{'}} + +% Used to generate quoted braces. +\def\mylbrace {{\tt\char123}} +\def\myrbrace {{\tt\char125}} +\let\{=\mylbrace +\let\}=\myrbrace +\begingroup + % Definitions to produce actual \{ & \} command in an index. + \catcode`\{ = 12 \catcode`\} = 12 + \catcode`\[ = 1 \catcode`\] = 2 + \catcode`\@ = 0 \catcode`\\ = 12 + @gdef@lbracecmd[\{]% + @gdef@rbracecmd[\}]% +@endgroup + +% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent +% Others are defined by plain TeX: @` @' @" @^ @~ @= @v @H. +\let\, = \c +\let\dotaccent = \. +\def\ringaccent#1{{\accent23 #1}} +\let\tieaccent = \t +\let\ubaraccent = \b +\let\udotaccent = \d + +% Other special characters: @questiondown @exclamdown +% Plain TeX defines: @AA @AE @O @OE @L (and lowercase versions) @ss. +\def\questiondown{?`} +\def\exclamdown{!`} + +% Dotless i and dotless j, used for accents. +\def\imacro{i} +\def\jmacro{j} +\def\dotless#1{% + \def\temp{#1}% + \ifx\temp\imacro \ptexi + \else\ifx\temp\jmacro \j + \else \errmessage{@dotless can be used only with i or j}% + \fi\fi +} + +% Be sure we're in horizontal mode when doing a tie, since we make space +% equivalent to this in @example-like environments. Otherwise, a space +% at the beginning of a line will start with \penalty -- and +% since \penalty is valid in vertical mode, we'd end up putting the +% penalty on the vertical list instead of in the new paragraph. +{\catcode`@ = 11 + % Avoid using \@M directly, because that causes trouble + % if the definition is written into an index file. + \global\let\tiepenalty = \@M + \gdef\tie{\leavevmode\penalty\tiepenalty\ } +} + +% @: forces normal size whitespace following. +\def\:{\spacefactor=1000 } + +% @* forces a line break. +\def\*{\hfil\break\hbox{}\ignorespaces} + +% @. is an end-of-sentence period. +\def\.{.\spacefactor=3000 } + +% @! is an end-of-sentence bang. +\def\!{!\spacefactor=3000 } + +% @? is an end-of-sentence query. +\def\?{?\spacefactor=3000 } + +% @w prevents a word break. Without the \leavevmode, @w at the +% beginning of a paragraph, when TeX is still in vertical mode, would +% produce a whole line of output instead of starting the paragraph. +\def\w#1{\leavevmode\hbox{#1}} + +% @group ... @end group forces ... to be all on one page, by enclosing +% it in a TeX vbox. We use \vtop instead of \vbox to construct the box +% to keep its height that of a normal line. According to the rules for +% \topskip (p.114 of the TeXbook), the glue inserted is +% max (\topskip - \ht (first item), 0). If that height is large, +% therefore, no glue is inserted, and the space between the headline and +% the text is small, which looks bad. +% +\def\group{\begingroup + \ifnum\catcode13=\active \else + \errhelp = \groupinvalidhelp + \errmessage{@group invalid in context where filling is enabled}% + \fi + % + % The \vtop we start below produces a box with normal height and large + % depth; thus, TeX puts \baselineskip glue before it, and (when the + % next line of text is done) \lineskip glue after it. (See p.82 of + % the TeXbook.) Thus, space below is not quite equal to space + % above. But it's pretty close. + \def\Egroup{% + \egroup % End the \vtop. + \endgroup % End the \group. + }% + % + \vtop\bgroup + % We have to put a strut on the last line in case the @group is in + % the midst of an example, rather than completely enclosing it. + % Otherwise, the interline space between the last line of the group + % and the first line afterwards is too small. But we can't put the + % strut in \Egroup, since there it would be on a line by itself. + % Hence this just inserts a strut at the beginning of each line. + \everypar = {\strut}% + % + % Since we have a strut on every line, we don't need any of TeX's + % normal interline spacing. + \offinterlineskip + % + % OK, but now we have to do something about blank + % lines in the input in @example-like environments, which normally + % just turn into \lisppar, which will insert no space now that we've + % turned off the interline space. Simplest is to make them be an + % empty paragraph. + \ifx\par\lisppar + \edef\par{\leavevmode \par}% + % + % Reset ^^M's definition to new definition of \par. + \obeylines + \fi + % + % Do @comment since we are called inside an environment such as + % @example, where each end-of-line in the input causes an + % end-of-line in the output. We don't want the end-of-line after + % the `@group' to put extra space in the output. Since @group + % should appear on a line by itself (according to the Texinfo + % manual), we don't worry about eating any user text. + \comment +} +% +% TeX puts in an \escapechar (i.e., `@') at the beginning of the help +% message, so this ends up printing `@group can only ...'. +% +\newhelp\groupinvalidhelp{% +group can only be used in environments such as @example,^^J% +where each line of input produces a line of output.} + +% @need space-in-mils +% forces a page break if there is not space-in-mils remaining. + +\newdimen\mil \mil=0.001in + +\def\need{\parsearg\needx} + +% Old definition--didn't work. +%\def\needx #1{\par % +%% This method tries to make TeX break the page naturally +%% if the depth of the box does not fit. +%{\baselineskip=0pt% +%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak +%\prevdepth=-1000pt +%}} + +\def\needx#1{% + % Ensure vertical mode, so we don't make a big box in the middle of a + % paragraph. + \par + % + % If the @need value is less than one line space, it's useless. + \dimen0 = #1\mil + \dimen2 = \ht\strutbox + \advance\dimen2 by \dp\strutbox + \ifdim\dimen0 > \dimen2 + % + % Do a \strut just to make the height of this box be normal, so the + % normal leading is inserted relative to the preceding line. + % And a page break here is fine. + \vtop to #1\mil{\strut\vfil}% + % + % TeX does not even consider page breaks if a penalty added to the + % main vertical list is 10000 or more. But in order to see if the + % empty box we just added fits on the page, we must make it consider + % page breaks. On the other hand, we don't want to actually break the + % page after the empty box. So we use a penalty of 9999. + % + % There is an extremely small chance that TeX will actually break the + % page at this \penalty, if there are no other feasible breakpoints in + % sight. (If the user is using lots of big @group commands, which + % almost-but-not-quite fill up a page, TeX will have a hard time doing + % good page breaking, for example.) However, I could not construct an + % example where a page broke at this \penalty; if it happens in a real + % document, then we can reconsider our strategy. + \penalty9999 + % + % Back up by the size of the box, whether we did a page break or not. + \kern -#1\mil + % + % Do not allow a page break right after this kern. + \nobreak + \fi +} + +% @br forces paragraph break + +\let\br = \par + +% @dots{} output an ellipsis using the current font. +% We do .5em per period so that it has the same spacing in a typewriter +% font as three actual period characters. +% +\def\dots{% + \leavevmode + \hbox to 1.5em{% + \hskip 0pt plus 0.25fil minus 0.25fil + .\hss.\hss.% + \hskip 0pt plus 0.5fil minus 0.5fil + }% +} + +% @enddots{} is an end-of-sentence ellipsis. +% +\def\enddots{% + \leavevmode + \hbox to 2em{% + \hskip 0pt plus 0.25fil minus 0.25fil + .\hss.\hss.\hss.% + \hskip 0pt plus 0.5fil minus 0.5fil + }% + \spacefactor=3000 +} + + +% @page forces the start of a new page +% +\def\page{\par\vfill\supereject} + +% @exdent text.... +% outputs text on separate line in roman font, starting at standard page margin + +% This records the amount of indent in the innermost environment. +% That's how much \exdent should take out. +\newskip\exdentamount + +% This defn is used inside fill environments such as @defun. +\def\exdent{\parsearg\exdentyyy} +\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} + +% This defn is used inside nofill environments such as @example. +\def\nofillexdent{\parsearg\nofillexdentyyy} +\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount +\leftline{\hskip\leftskip{\rm#1}}}} + +% @inmargin{TEXT} puts TEXT in the margin next to the current paragraph. + +\def\inmargin#1{% +\strut\vadjust{\nobreak\kern-\strutdepth + \vtop to \strutdepth{\baselineskip\strutdepth\vss + \llap{\rightskip=\inmarginspacing \vbox{\noindent #1}}\null}}} +\newskip\inmarginspacing \inmarginspacing=1cm +\def\strutdepth{\dp\strutbox} + +%\hbox{{\rm#1}}\hfil\break}} + +% @include file insert text of that file as input. +% Allow normal characters that we make active in the argument (a file name). +\def\include{\begingroup + \catcode`\\=12 + \catcode`~=12 + \catcode`^=12 + \catcode`_=12 + \catcode`|=12 + \catcode`<=12 + \catcode`>=12 + \catcode`+=12 + \parsearg\includezzz} +% Restore active chars for included file. +\def\includezzz#1{\endgroup\begingroup + % Read the included file in a group so nested @include's work. + \def\thisfile{#1}% + \input\thisfile +\endgroup} + +\def\thisfile{} + +% @center line outputs that line, centered + +\def\center{\parsearg\centerzzz} +\def\centerzzz #1{{\advance\hsize by -\leftskip +\advance\hsize by -\rightskip +\centerline{#1}}} + +% @sp n outputs n lines of vertical space + +\def\sp{\parsearg\spxxx} +\def\spxxx #1{\vskip #1\baselineskip} + +% @comment ...line which is ignored... +% @c is the same as @comment +% @ignore ... @end ignore is another way to write a comment + +\def\comment{\begingroup \catcode`\^^M=\other% +\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% +\commentxxx} +{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} + +\let\c=\comment + +% @paragraphindent NCHARS +% We'll use ems for NCHARS, close enough. +% We cannot implement @paragraphindent asis, though. +% +\def\asisword{asis} % no translation, these are keywords +\def\noneword{none} +% +\def\paragraphindent{\parsearg\doparagraphindent} +\def\doparagraphindent#1{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \defaultparindent = 0pt + \else + \defaultparindent = #1em + \fi + \fi + \parindent = \defaultparindent +} + +% @exampleindent NCHARS +% We'll use ems for NCHARS like @paragraphindent. +% It seems @exampleindent asis isn't necessary, but +% I preserve it to make it similar to @paragraphindent. +\def\exampleindent{\parsearg\doexampleindent} +\def\doexampleindent#1{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \lispnarrowing = 0pt + \else + \lispnarrowing = #1em + \fi + \fi +} + +% @asis just yields its argument. Used with @table, for example. +% +\def\asis#1{#1} + +% @math means output in math mode. +% We don't use $'s directly in the definition of \math because control +% sequences like \math are expanded when the toc file is written. Then, +% we read the toc file back, the $'s will be normal characters (as they +% should be, according to the definition of Texinfo). So we must use a +% control sequence to switch into and out of math mode. +% +% This isn't quite enough for @math to work properly in indices, but it +% seems unlikely it will ever be needed there. +% +\let\implicitmath = $ +\def\math#1{\implicitmath #1\implicitmath} + +% @bullet and @minus need the same treatment as @math, just above. +\def\bullet{\implicitmath\ptexbullet\implicitmath} +\def\minus{\implicitmath-\implicitmath} + +% @refill is a no-op. +\let\refill=\relax + +% If working on a large document in chapters, it is convenient to +% be able to disable indexing, cross-referencing, and contents, for test runs. +% This is done with @novalidate (before @setfilename). +% +\newif\iflinks \linkstrue % by default we want the aux files. +\let\novalidate = \linksfalse + +% @setfilename is done at the beginning of every texinfo file. +% So open here the files we need to have open while reading the input. +% This makes it possible to make a .fmt file for texinfo. +\def\setfilename{% + \iflinks + \readauxfile + \fi % \openindices needs to do some work in any case. + \openindices + \fixbackslash % Turn off hack to swallow `\input texinfo'. + \global\let\setfilename=\comment % Ignore extra @setfilename cmds. + % + % If texinfo.cnf is present on the system, read it. + % Useful for site-wide @afourpaper, etc. + % Just to be on the safe side, close the input stream before the \input. + \openin 1 texinfo.cnf + \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi + \closein1 + \temp + % + \comment % Ignore the actual filename. +} + +% Called from \setfilename. +% +\def\openindices{% + \newindex{cp}% + \newcodeindex{fn}% + \newcodeindex{vr}% + \newcodeindex{tp}% + \newcodeindex{ky}% + \newcodeindex{pg}% +} + +% @bye. +\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} + + +\message{pdf,} +% adobe `portable' document format +\newcount\tempnum +\newcount\lnkcount +\newtoks\filename +\newcount\filenamelength +\newcount\pgn +\newtoks\toksA +\newtoks\toksB +\newtoks\toksC +\newtoks\toksD +\newbox\boxA +\newcount\countA +\newif\ifpdf +\newif\ifpdfmakepagedest + +\ifx\pdfoutput\undefined + \pdffalse + \let\pdfmkdest = \gobble + \let\pdfurl = \gobble + \let\endlink = \relax + \let\linkcolor = \relax + \let\pdfmakeoutlines = \relax +\else + \pdftrue + \pdfoutput = 1 + \input pdfcolor + \def\dopdfimage#1#2#3{% + \def\imagewidth{#2}% + \def\imageheight{#3}% + \ifnum\pdftexversion < 14 + \pdfimage + \else + \pdfximage + \fi + \ifx\empty\imagewidth\else width \imagewidth \fi + \ifx\empty\imageheight\else height \imageheight \fi + {#1.pdf}% + \ifnum\pdftexversion < 14 \else + \pdfrefximage \pdflastximage + \fi} + \def\pdfmkdest#1{\pdfdest name{#1@} xyz} + \def\pdfmkpgn#1{#1@} + \let\linkcolor = \Blue % was Cyan, but that seems light? + \def\endlink{\Black\pdfendlink} + % Adding outlines to PDF; macros for calculating structure of outlines + % come from Petr Olsak + \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% + \else \csname#1\endcsname \fi} + \def\advancenumber#1{\tempnum=\expnumber{#1}\relax + \advance\tempnum by1 + \expandafter\xdef\csname#1\endcsname{\the\tempnum}} + \def\pdfmakeoutlines{{% + \openin 1 \jobname.toc + \ifeof 1\else\bgroup + \closein 1 + \indexnofonts + \def\tt{} + \let\_ = \normalunderscore + % Thanh's hack / proper braces in bookmarks + \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace + \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace + % + \def\chapentry ##1##2##3{} + \def\unnumbchapentry ##1##2{} + \def\secentry ##1##2##3##4{\advancenumber{chap##2}} + \def\unnumbsecentry ##1##2{} + \def\subsecentry ##1##2##3##4##5{\advancenumber{sec##2.##3}} + \def\unnumbsubsecentry ##1##2{} + \def\subsubsecentry ##1##2##3##4##5##6{\advancenumber{subsec##2.##3.##4}} + \def\unnumbsubsubsecentry ##1##2{} + \input \jobname.toc + \def\chapentry ##1##2##3{% + \pdfoutline goto name{\pdfmkpgn{##3}}count-\expnumber{chap##2}{##1}} + \def\unnumbchapentry ##1##2{% + \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} + \def\secentry ##1##2##3##4{% + \pdfoutline goto name{\pdfmkpgn{##4}}count-\expnumber{sec##2.##3}{##1}} + \def\unnumbsecentry ##1##2{% + \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} + \def\subsecentry ##1##2##3##4##5{% + \pdfoutline goto name{\pdfmkpgn{##5}}count-\expnumber{subsec##2.##3.##4}{##1}} + \def\unnumbsubsecentry ##1##2{% + \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} + \def\subsubsecentry ##1##2##3##4##5##6{% + \pdfoutline goto name{\pdfmkpgn{##6}}{##1}} + \def\unnumbsubsubsecentry ##1##2{% + \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} + \input \jobname.toc + \egroup\fi + }} + \def\makelinks #1,{% + \def\params{#1}\def\E{END}% + \ifx\params\E + \let\nextmakelinks=\relax + \else + \let\nextmakelinks=\makelinks + \ifnum\lnkcount>0,\fi + \picknum{#1}% + \startlink attr{/Border [0 0 0]} + goto name{\pdfmkpgn{\the\pgn}}% + \linkcolor #1% + \advance\lnkcount by 1% + \endlink + \fi + \nextmakelinks + } + \def\picknum#1{\expandafter\pn#1} + \def\pn#1{% + \def\p{#1}% + \ifx\p\lbrace + \let\nextpn=\ppn + \else + \let\nextpn=\ppnn + \def\first{#1} + \fi + \nextpn + } + \def\ppn#1{\pgn=#1\gobble} + \def\ppnn{\pgn=\first} + \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\skipspaces#1{\def\PP{#1}\def\D{|}% + \ifx\PP\D\let\nextsp\relax + \else\let\nextsp\skipspaces + \ifx\p\space\else\addtokens{\filename}{\PP}% + \advance\filenamelength by 1 + \fi + \fi + \nextsp} + \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} + \ifnum\pdftexversion < 14 + \let \startlink \pdfannotlink + \else + \let \startlink \pdfstartlink + \fi + \def\pdfurl#1{% + \begingroup + \normalturnoffactive\def\@{@}% + \leavevmode\Red + \startlink attr{/Border [0 0 0]}% + user{/Subtype /Link /A << /S /URI /URI (#1) >>}% + % #1 + \endgroup} + \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} + \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} + \def\maketoks{% + \expandafter\poptoks\the\toksA|ENDTOKS| + \ifx\first0\adn0 + \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 + \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 + \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 + \else + \ifnum0=\countA\else\makelink\fi + \ifx\first.\let\next=\done\else + \let\next=\maketoks + \addtokens{\toksB}{\the\toksD} + \ifx\first,\addtokens{\toksB}{\space}\fi + \fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \next} + \def\makelink{\addtokens{\toksB}% + {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} + \def\pdflink#1{% + \startlink attr{/Border [0 0 0]} goto name{\mkpgn{#1}} + \linkcolor #1\endlink} + \def\mkpgn#1{#1@} + \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} +\fi % \ifx\pdfoutput + + +\message{fonts,} +% Font-change commands. + +% Texinfo sort of supports the sans serif font style, which plain TeX does not. +% So we set up a \sf analogous to plain's \rm, etc. +\newfam\sffam +\def\sf{\fam=\sffam \tensf} +\let\li = \sf % Sometimes we call it \li, not \sf. + +% We don't need math for this one. +\def\ttsl{\tenttsl} + +% Use Computer Modern fonts at \magstephalf (11pt). +\newcount\mainmagstep +\mainmagstep=\magstephalf + +% Set the font macro #1 to the font named #2, adding on the +% specified font prefix (normally `cm'). +% #3 is the font's design size, #4 is a scale factor +\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} + +% Use cm as the default font prefix. +% To specify the font prefix, you must define \fontprefix +% before you read in texinfo.tex. +\ifx\fontprefix\undefined +\def\fontprefix{cm} +\fi +% Support font families that don't use the same naming scheme as CM. +\def\rmshape{r} +\def\rmbshape{bx} %where the normal face is bold +\def\bfshape{b} +\def\bxshape{bx} +\def\ttshape{tt} +\def\ttbshape{tt} +\def\ttslshape{sltt} +\def\itshape{ti} +\def\itbshape{bxti} +\def\slshape{sl} +\def\slbshape{bxsl} +\def\sfshape{ss} +\def\sfbshape{ss} +\def\scshape{csc} +\def\scbshape{csc} + +\ifx\bigger\relax +\let\mainmagstep=\magstep1 +\setfont\textrm\rmshape{12}{1000} +\setfont\texttt\ttshape{12}{1000} +\else +\setfont\textrm\rmshape{10}{\mainmagstep} +\setfont\texttt\ttshape{10}{\mainmagstep} +\fi +% Instead of cmb10, you many want to use cmbx10. +% cmbx10 is a prettier font on its own, but cmb10 +% looks better when embedded in a line with cmr10. +\setfont\textbf\bfshape{10}{\mainmagstep} +\setfont\textit\itshape{10}{\mainmagstep} +\setfont\textsl\slshape{10}{\mainmagstep} +\setfont\textsf\sfshape{10}{\mainmagstep} +\setfont\textsc\scshape{10}{\mainmagstep} +\setfont\textttsl\ttslshape{10}{\mainmagstep} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep + +% A few fonts for @defun, etc. +\setfont\defbf\bxshape{10}{\magstep1} %was 1314 +\setfont\deftt\ttshape{10}{\magstep1} +\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} + +% Fonts for indices, footnotes, small examples (9pt). +\setfont\smallrm\rmshape{9}{1000} +\setfont\smalltt\ttshape{9}{1000} +\setfont\smallbf\bfshape{10}{900} +\setfont\smallit\itshape{9}{1000} +\setfont\smallsl\slshape{9}{1000} +\setfont\smallsf\sfshape{9}{1000} +\setfont\smallsc\scshape{10}{900} +\setfont\smallttsl\ttslshape{10}{900} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 + +% Fonts for title page: +\setfont\titlerm\rmbshape{12}{\magstep3} +\setfont\titleit\itbshape{10}{\magstep4} +\setfont\titlesl\slbshape{10}{\magstep4} +\setfont\titlett\ttbshape{12}{\magstep3} +\setfont\titlettsl\ttslshape{10}{\magstep4} +\setfont\titlesf\sfbshape{17}{\magstep1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\authorrm{\secrm} + +% Chapter (and unnumbered) fonts (17.28pt). +\setfont\chaprm\rmbshape{12}{\magstep2} +\setfont\chapit\itbshape{10}{\magstep3} +\setfont\chapsl\slbshape{10}{\magstep3} +\setfont\chaptt\ttbshape{12}{\magstep2} +\setfont\chapttsl\ttslshape{10}{\magstep3} +\setfont\chapsf\sfbshape{17}{1000} +\let\chapbf=\chaprm +\setfont\chapsc\scbshape{10}{\magstep3} +\font\chapi=cmmi12 scaled \magstep2 +\font\chapsy=cmsy10 scaled \magstep3 + +% Section fonts (14.4pt). +\setfont\secrm\rmbshape{12}{\magstep1} +\setfont\secit\itbshape{10}{\magstep2} +\setfont\secsl\slbshape{10}{\magstep2} +\setfont\sectt\ttbshape{12}{\magstep1} +\setfont\secttsl\ttslshape{10}{\magstep2} +\setfont\secsf\sfbshape{12}{\magstep1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep2} +\font\seci=cmmi12 scaled \magstep1 +\font\secsy=cmsy10 scaled \magstep2 + +% \setfont\ssecrm\bxshape{10}{\magstep1} % This size an font looked bad. +% \setfont\ssecit\itshape{10}{\magstep1} % The letters were too crowded. +% \setfont\ssecsl\slshape{10}{\magstep1} +% \setfont\ssectt\ttshape{10}{\magstep1} +% \setfont\ssecsf\sfshape{10}{\magstep1} + +%\setfont\ssecrm\bfshape{10}{1315} % Note the use of cmb rather than cmbx. +%\setfont\ssecit\itshape{10}{1315} % Also, the size is a little larger than +%\setfont\ssecsl\slshape{10}{1315} % being scaled magstep1. +%\setfont\ssectt\ttshape{10}{1315} +%\setfont\ssecsf\sfshape{10}{1315} + +%\let\ssecbf=\ssecrm + +% Subsection fonts (13.15pt). +\setfont\ssecrm\rmbshape{12}{\magstephalf} +\setfont\ssecit\itbshape{10}{1315} +\setfont\ssecsl\slbshape{10}{1315} +\setfont\ssectt\ttbshape{12}{\magstephalf} +\setfont\ssecttsl\ttslshape{10}{1315} +\setfont\ssecsf\sfbshape{12}{\magstephalf} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{\magstep1} +\font\sseci=cmmi12 scaled \magstephalf +\font\ssecsy=cmsy10 scaled 1315 +% The smallcaps and symbol fonts should actually be scaled \magstep1.5, +% but that is not a standard magnification. + +% In order for the font changes to affect most math symbols and letters, +% we have to define the \textfont of the standard families. Since +% texinfo doesn't allow for producing subscripts and superscripts, we +% don't bother to reset \scriptfont and \scriptscriptfont (which would +% also require loading a lot more fonts). +% +\def\resetmathfonts{% + \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy + \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf + \textfont\ttfam = \tentt \textfont\sffam = \tensf +} + + +% The font-changing commands redefine the meanings of \tenSTYLE, instead +% of just \STYLE. We do this so that font changes will continue to work +% in math mode, where it is the current \fam that is relevant in most +% cases, not the current font. Plain TeX does \def\bf{\fam=\bffam +% \tenbf}, for example. By redefining \tenbf, we obviate the need to +% redefine \bf itself. +\def\textfonts{% + \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl + \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc + \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl + \resetmathfonts} +\def\titlefonts{% + \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl + \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc + \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy + \let\tenttsl=\titlettsl + \resetmathfonts \setleading{25pt}} +\def\titlefont#1{{\titlefonts\rm #1}} +\def\chapfonts{% + \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl + \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc + \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl + \resetmathfonts \setleading{19pt}} +\def\secfonts{% + \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl + \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc + \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl + \resetmathfonts \setleading{16pt}} +\def\subsecfonts{% + \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl + \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc + \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl + \resetmathfonts \setleading{15pt}} +\let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? +\def\smallfonts{% + \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl + \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc + \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy + \let\tenttsl=\smallttsl + \resetmathfonts \setleading{11pt}} + +% Set up the default fonts, so we can use them for creating boxes. +% +\textfonts + +% Define these so they can be easily changed for other fonts. +\def\angleleft{$\langle$} +\def\angleright{$\rangle$} + +% Count depth in font-changes, for error checks +\newcount\fontdepth \fontdepth=0 + +% Fonts for short table of contents. +\setfont\shortcontrm\rmshape{12}{1000} +\setfont\shortcontbf\bxshape{12}{1000} +\setfont\shortcontsl\slshape{12}{1000} + +%% Add scribe-like font environments, plus @l for inline lisp (usually sans +%% serif) and @ii for TeX italic + +% \smartitalic{ARG} outputs arg in italics, followed by an italic correction +% unless the following character is such as not to need one. +\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi} +\def\smartslanted#1{{\sl #1}\futurelet\next\smartitalicx} +\def\smartitalic#1{{\it #1}\futurelet\next\smartitalicx} + +\let\i=\smartitalic +\let\var=\smartslanted +\let\dfn=\smartslanted +\let\emph=\smartitalic +\let\cite=\smartslanted + +\def\b#1{{\bf #1}} +\let\strong=\b + +% We can't just use \exhyphenpenalty, because that only has effect at +% the end of a paragraph. Restore normal hyphenation at the end of the +% group within which \nohyphenation is presumably called. +% +\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} +\def\restorehyphenation{\hyphenchar\font = `- } + +\def\t#1{% + {\tt \rawbackslash \frenchspacing #1}% + \null +} +\let\ttfont=\t +\def\samp#1{`\tclose{#1}'\null} +\setfont\keyrm\rmshape{8}{1000} +\font\keysy=cmsy9 +\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% + \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% + \vbox{\hrule\kern-0.4pt + \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% + \kern-0.4pt\hrule}% + \kern-.06em\raise0.4pt\hbox{\angleright}}}} +% The old definition, with no lozenge: +%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} +\def\ctrl #1{{\tt \rawbackslash \hat}#1} + +% @file, @option are the same as @samp. +\let\file=\samp +\let\option=\samp + +% @code is a modification of @t, +% which makes spaces the same size as normal in the surrounding text. +\def\tclose#1{% + {% + % Change normal interword space to be same as for the current font. + \spaceskip = \fontdimen2\font + % + % Switch to typewriter. + \tt + % + % But `\ ' produces the large typewriter interword space. + \def\ {{\spaceskip = 0pt{} }}% + % + % Turn off hyphenation. + \nohyphenation + % + \rawbackslash + \frenchspacing + #1% + }% + \null +} + +% We *must* turn on hyphenation at `-' and `_' in \code. +% Otherwise, it is too hard to avoid overfull hboxes +% in the Emacs manual, the Library manual, etc. + +% Unfortunately, TeX uses one parameter (\hyphenchar) to control +% both hyphenation at - and hyphenation within words. +% We must therefore turn them both off (\tclose does that) +% and arrange explicitly to hyphenate at a dash. +% -- rms. +{ + \catcode`\-=\active + \catcode`\_=\active + % + \global\def\code{\begingroup + \catcode`\-=\active \let-\codedash + \catcode`\_=\active \let_\codeunder + \codex + } + % + % If we end up with any active - characters when handling the index, + % just treat them as a normal -. + \global\def\indexbreaks{\catcode`\-=\active \let-\realdash} +} + +\def\realdash{-} +\def\codedash{-\discretionary{}{}{}} +\def\codeunder{\ifusingtt{\normalunderscore\discretionary{}{}{}}{\_}} +\def\codex #1{\tclose{#1}\endgroup} + +%\let\exp=\tclose %Was temporary + +% @kbd is like @code, except that if the argument is just one @key command, +% then @kbd has no effect. + +% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), +% `example' (@kbd uses ttsl only inside of @example and friends), +% or `code' (@kbd uses normal tty font always). +\def\kbdinputstyle{\parsearg\kbdinputstylexxx} +\def\kbdinputstylexxx#1{% + \def\arg{#1}% + \ifx\arg\worddistinct + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% + \else\ifx\arg\wordexample + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% + \else\ifx\arg\wordcode + \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% + \fi\fi\fi +} +\def\worddistinct{distinct} +\def\wordexample{example} +\def\wordcode{code} + +% Default is kbdinputdistinct. (Too much of a hassle to call the macro, +% the catcodes are wrong for parsearg to work.) +\gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl} + +\def\xkey{\key} +\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% +\ifx\one\xkey\ifx\threex\three \key{#2}% +\else{\tclose{\kbdfont\look}}\fi +\else{\tclose{\kbdfont\look}}\fi} + +% For @url, @env, @command quotes seem unnecessary, so use \code. +\let\url=\code +\let\env=\code +\let\command=\code + +% @uref (abbreviation for `urlref') takes an optional (comma-separated) +% second argument specifying the text to display and an optional third +% arg as text to display instead of (rather than in addition to) the url +% itself. First (mandatory) arg is the url. Perhaps eventually put in +% a hypertex \special here. +% +\def\uref#1{\douref #1,,,\finish} +\def\douref#1,#2,#3,#4\finish{\begingroup + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \ifpdf + \unhbox0 % PDF: 2nd arg given, show only it + \else + \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url + \fi + \else + \code{#1}% only url given, so show it + \fi + \fi + \endlink +\endgroup} + +% rms does not like angle brackets --karl, 17may97. +% So now @email is just like @uref, unless we are pdf. +% +%\def\email#1{\angleleft{\tt #1}\angleright} +\ifpdf + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} +\else + \let\email=\uref +\fi + +% Check if we are currently using a typewriter font. Since all the +% Computer Modern typewriter fonts have zero interword stretch (and +% shrink), and it is reasonable to expect all typewriter fonts to have +% this property, we can check that font parameter. +% +\def\ifmonospace{\ifdim\fontdimen3\font=0pt } + +% Typeset a dimension, e.g., `in' or `pt'. The only reason for the +% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. +% +\def\dmn#1{\thinspace #1} + +\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} + +% @l was never documented to mean ``switch to the Lisp font'', +% and it is not used as such in any manual I can find. We need it for +% Polish suppressed-l. --karl, 22sep96. +%\def\l#1{{\li #1}\null} + +% Explicit font changes: @r, @sc, undocumented @ii. +\def\r#1{{\rm #1}} % roman font +\def\sc#1{{\smallcaps#1}} % smallcaps font +\def\ii#1{{\it #1}} % italic font + +% @acronym downcases the argument and prints in smallcaps. +\def\acronym#1{{\smallcaps \lowercase{#1}}} + +% @pounds{} is a sterling sign. +\def\pounds{{\it\$}} + + +\message{page headings,} + +\newskip\titlepagetopglue \titlepagetopglue = 1.5in +\newskip\titlepagebottomglue \titlepagebottomglue = 2pc + +% First the title page. Must do @settitle before @titlepage. +\newif\ifseenauthor +\newif\iffinishedtitlepage + +% Do an implicit @contents or @shortcontents after @end titlepage if the +% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. +% +\newif\ifsetcontentsaftertitlepage + \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue +\newif\ifsetshortcontentsaftertitlepage + \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue + +\def\shorttitlepage{\parsearg\shorttitlepagezzz} +\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} + +\def\titlepage{\begingroup \parindent=0pt \textfonts + \let\subtitlerm=\tenrm + \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% + % + \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}% + % + % Leave some space at the very top of the page. + \vglue\titlepagetopglue + % + % Now you can print the title using @title. + \def\title{\parsearg\titlezzz}% + \def\titlezzz##1{\leftline{\titlefonts\rm ##1} + % print a rule at the page bottom also. + \finishedtitlepagefalse + \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% + % No rule at page bottom unless we print one at the top with @title. + \finishedtitlepagetrue + % + % Now you can put text using @subtitle. + \def\subtitle{\parsearg\subtitlezzz}% + \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% + % + % @author should come last, but may come many times. + \def\author{\parsearg\authorzzz}% + \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi + {\authorfont \leftline{##1}}}% + % + % Most title ``pages'' are actually two pages long, with space + % at the top of the second. We don't want the ragged left on the second. + \let\oldpage = \page + \def\page{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + \oldpage + \let\page = \oldpage + \hbox{}}% +% \def\page{\oldpage \hbox{}} +} + +\def\Etitlepage{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + % It is important to do the page break before ending the group, + % because the headline and footline are only empty inside the group. + % If we use the new definition of \page, we always get a blank page + % after the title page, which we certainly don't want. + \oldpage + \endgroup + % + % If they want short, they certainly want long too. + \ifsetshortcontentsaftertitlepage + \shortcontents + \contents + \global\let\shortcontents = \relax + \global\let\contents = \relax + \fi + % + \ifsetcontentsaftertitlepage + \contents + \global\let\contents = \relax + \global\let\shortcontents = \relax + \fi + % + \ifpdf \pdfmakepagedesttrue \fi + % + \HEADINGSon +} + +\def\finishtitlepage{% + \vskip4pt \hrule height 2pt width \hsize + \vskip\titlepagebottomglue + \finishedtitlepagetrue +} + +%%% Set up page headings and footings. + +\let\thispage=\folio + +\newtoks\evenheadline % headline on even pages +\newtoks\oddheadline % headline on odd pages +\newtoks\evenfootline % footline on even pages +\newtoks\oddfootline % footline on odd pages + +% Now make Tex use those variables +\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline + \else \the\evenheadline \fi}} +\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline + \else \the\evenfootline \fi}\HEADINGShook} +\let\HEADINGShook=\relax + +% Commands to set those variables. +% For example, this is what @headings on does +% @evenheading @thistitle|@thispage|@thischapter +% @oddheading @thischapter|@thispage|@thistitle +% @evenfooting @thisfile|| +% @oddfooting ||@thisfile + +\def\evenheading{\parsearg\evenheadingxxx} +\def\oddheading{\parsearg\oddheadingxxx} +\def\everyheading{\parsearg\everyheadingxxx} + +\def\evenfooting{\parsearg\evenfootingxxx} +\def\oddfooting{\parsearg\oddfootingxxx} +\def\everyfooting{\parsearg\everyfootingxxx} + +{\catcode`\@=0 % + +\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} +\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% +\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} +\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% +\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% + +\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} +\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% +\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} +\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% + \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% + % + % Leave some space for the footline. Hopefully ok to assume + % @evenfooting will not be used by itself. + \global\advance\pageheight by -\baselineskip + \global\advance\vsize by -\baselineskip +} + +\gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} +% +}% unbind the catcode of @. + +% @headings double turns headings on for double-sided printing. +% @headings single turns headings on for single-sided printing. +% @headings off turns them off. +% @headings on same as @headings double, retained for compatibility. +% @headings after turns on double-sided headings after this page. +% @headings doubleafter turns on double-sided headings after this page. +% @headings singleafter turns on single-sided headings after this page. +% By default, they are off at the start of a document, +% and turned `on' after @end titlepage. + +\def\headings #1 {\csname HEADINGS#1\endcsname} + +\def\HEADINGSoff{ +\global\evenheadline={\hfil} \global\evenfootline={\hfil} +\global\oddheadline={\hfil} \global\oddfootline={\hfil}} +\HEADINGSoff +% When we turn headings on, set the page number to 1. +% For double-sided printing, put current file name in lower left corner, +% chapter name on inside top of right hand pages, document +% title on inside top of left hand pages, and page numbers on outside top +% edge of all pages. +\def\HEADINGSdouble{ +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} +\let\contentsalignmacro = \chappager + +% For single-sided printing, chapter title goes across top left of page, +% page number on top right. +\def\HEADINGSsingle{ +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} +\def\HEADINGSon{\HEADINGSdouble} + +\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} +\let\HEADINGSdoubleafter=\HEADINGSafter +\def\HEADINGSdoublex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} + +\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} +\def\HEADINGSsinglex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} + +% Subroutines used in generating headings +% This produces Day Month Year style of output. +% Only define if not already defined, in case a txi-??.tex file has set +% up a different format (e.g., txi-cs.tex does this). +\ifx\today\undefined +\def\today{% + \number\day\space + \ifcase\month + \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr + \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug + \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec + \fi + \space\number\year} +\fi + +% @settitle line... specifies the title of the document, for headings. +% It generates no output of its own. +\def\thistitle{\putwordNoTitle} +\def\settitle{\parsearg\settitlezzz} +\def\settitlezzz #1{\gdef\thistitle{#1}} + + +\message{tables,} +% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). + +% default indentation of table text +\newdimen\tableindent \tableindent=.8in +% default indentation of @itemize and @enumerate text +\newdimen\itemindent \itemindent=.3in +% margin between end of table item and start of table text. +\newdimen\itemmargin \itemmargin=.1in + +% used internally for \itemindent minus \itemmargin +\newdimen\itemmax + +% Note @table, @vtable, and @vtable define @item, @itemx, etc., with +% these defs. +% They also define \itemindex +% to index the item name in whatever manner is desired (perhaps none). + +\newif\ifitemxneedsnegativevskip + +\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} + +\def\internalBitem{\smallbreak \parsearg\itemzzz} +\def\internalBitemx{\itemxpar \parsearg\itemzzz} + +\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} +\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} + +\def\internalBkitem{\smallbreak \parsearg\kitemzzz} +\def\internalBkitemx{\itemxpar \parsearg\kitemzzz} + +\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% + \itemzzz {#1}} + +\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% + \itemzzz {#1}} + +\def\itemzzz #1{\begingroup % + \advance\hsize by -\rightskip + \advance\hsize by -\tableindent + \setbox0=\hbox{\itemfont{#1}}% + \itemindex{#1}% + \nobreak % This prevents a break before @itemx. + % + % If the item text does not fit in the space we have, put it on a line + % by itself, and do not allow a page break either before or after that + % line. We do not start a paragraph here because then if the next + % command is, e.g., @kindex, the whatsit would get put into the + % horizontal list on a line by itself, resulting in extra blank space. + \ifdim \wd0>\itemmax + % + % Make this a paragraph so we get the \parskip glue and wrapping, + % but leave it ragged-right. + \begingroup + \advance\leftskip by-\tableindent + \advance\hsize by\tableindent + \advance\rightskip by0pt plus1fil + \leavevmode\unhbox0\par + \endgroup + % + % We're going to be starting a paragraph, but we don't want the + % \parskip glue -- logically it's part of the @item we just started. + \nobreak \vskip-\parskip + % + % Stop a page break at the \parskip glue coming up. Unfortunately + % we can't prevent a possible page break at the following + % \baselineskip glue. + \nobreak + \endgroup + \itemxneedsnegativevskipfalse + \else + % The item text fits into the space. Start a paragraph, so that the + % following text (if any) will end up on the same line. + \noindent + % Do this with kerns and \unhbox so that if there is a footnote in + % the item text, it can migrate to the main vertical list and + % eventually be printed. + \nobreak\kern-\tableindent + \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 + \unhbox0 + \nobreak\kern\dimen0 + \endgroup + \itemxneedsnegativevskiptrue + \fi +} + +\def\item{\errmessage{@item while not in a table}} +\def\itemx{\errmessage{@itemx while not in a table}} +\def\kitem{\errmessage{@kitem while not in a table}} +\def\kitemx{\errmessage{@kitemx while not in a table}} +\def\xitem{\errmessage{@xitem while not in a table}} +\def\xitemx{\errmessage{@xitemx while not in a table}} + +% Contains a kludge to get @end[description] to work. +\def\description{\tablez{\dontindex}{1}{}{}{}{}} + +% @table, @ftable, @vtable. +\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} +{\obeylines\obeyspaces% +\gdef\tablex #1^^M{% +\tabley\dontindex#1 \endtabley}} + +\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} +{\obeylines\obeyspaces% +\gdef\ftablex #1^^M{% +\tabley\fnitemindex#1 \endtabley +\def\Eftable{\endgraf\afterenvbreak\endgroup}% +\let\Etable=\relax}} + +\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} +{\obeylines\obeyspaces% +\gdef\vtablex #1^^M{% +\tabley\vritemindex#1 \endtabley +\def\Evtable{\endgraf\afterenvbreak\endgroup}% +\let\Etable=\relax}} + +\def\dontindex #1{} +\def\fnitemindex #1{\doind {fn}{\code{#1}}}% +\def\vritemindex #1{\doind {vr}{\code{#1}}}% + +{\obeyspaces % +\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% +\tablez{#1}{#2}{#3}{#4}{#5}{#6}}} + +\def\tablez #1#2#3#4#5#6{% +\aboveenvbreak % +\begingroup % +\def\Edescription{\Etable}% Necessary kludge. +\let\itemindex=#1% +\ifnum 0#3>0 \advance \leftskip by #3\mil \fi % +\ifnum 0#4>0 \tableindent=#4\mil \fi % +\ifnum 0#5>0 \advance \rightskip by #5\mil \fi % +\def\itemfont{#2}% +\itemmax=\tableindent % +\advance \itemmax by -\itemmargin % +\advance \leftskip by \tableindent % +\exdentamount=\tableindent +\parindent = 0pt +\parskip = \smallskipamount +\ifdim \parskip=0pt \parskip=2pt \fi% +\def\Etable{\endgraf\afterenvbreak\endgroup}% +\let\item = \internalBitem % +\let\itemx = \internalBitemx % +\let\kitem = \internalBkitem % +\let\kitemx = \internalBkitemx % +\let\xitem = \internalBxitem % +\let\xitemx = \internalBxitemx % +} + +% This is the counter used by @enumerate, which is really @itemize + +\newcount \itemno + +\def\itemize{\parsearg\itemizezzz} + +\def\itemizezzz #1{% + \begingroup % ended by the @end itemize + \itemizey {#1}{\Eitemize} +} + +\def\itemizey #1#2{% +\aboveenvbreak % +\itemmax=\itemindent % +\advance \itemmax by -\itemmargin % +\advance \leftskip by \itemindent % +\exdentamount=\itemindent +\parindent = 0pt % +\parskip = \smallskipamount % +\ifdim \parskip=0pt \parskip=2pt \fi% +\def#2{\endgraf\afterenvbreak\endgroup}% +\def\itemcontents{#1}% +\let\item=\itemizeitem} + +% Set sfcode to normal for the chars that usually have another value. +% These are `.?!:;,' +\def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000 + \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 } + +% \splitoff TOKENS\endmark defines \first to be the first token in +% TOKENS, and \rest to be the remainder. +% +\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% + +% Allow an optional argument of an uppercase letter, lowercase letter, +% or number, to specify the first label in the enumerated list. No +% argument is the same as `1'. +% +\def\enumerate{\parsearg\enumeratezzz} +\def\enumeratezzz #1{\enumeratey #1 \endenumeratey} +\def\enumeratey #1 #2\endenumeratey{% + \begingroup % ended by the @end enumerate + % + % If we were given no argument, pretend we were given `1'. + \def\thearg{#1}% + \ifx\thearg\empty \def\thearg{1}\fi + % + % Detect if the argument is a single token. If so, it might be a + % letter. Otherwise, the only valid thing it can be is a number. + % (We will always have one token, because of the test we just made. + % This is a good thing, since \splitoff doesn't work given nothing at + % all -- the first parameter is undelimited.) + \expandafter\splitoff\thearg\endmark + \ifx\rest\empty + % Only one token in the argument. It could still be anything. + % A ``lowercase letter'' is one whose \lccode is nonzero. + % An ``uppercase letter'' is one whose \lccode is both nonzero, and + % not equal to itself. + % Otherwise, we assume it's a number. + % + % We need the \relax at the end of the \ifnum lines to stop TeX from + % continuing to look for a <number>. + % + \ifnum\lccode\expandafter`\thearg=0\relax + \numericenumerate % a number (we hope) + \else + % It's a letter. + \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax + \lowercaseenumerate % lowercase letter + \else + \uppercaseenumerate % uppercase letter + \fi + \fi + \else + % Multiple tokens in the argument. We hope it's a number. + \numericenumerate + \fi +} + +% An @enumerate whose labels are integers. The starting integer is +% given in \thearg. +% +\def\numericenumerate{% + \itemno = \thearg + \startenumeration{\the\itemno}% +} + +% The starting (lowercase) letter is in \thearg. +\def\lowercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more lowercase letters in @enumerate; get a bigger + alphabet}% + \fi + \char\lccode\itemno + }% +} + +% The starting (uppercase) letter is in \thearg. +\def\uppercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more uppercase letters in @enumerate; get a bigger + alphabet} + \fi + \char\uccode\itemno + }% +} + +% Call itemizey, adding a period to the first argument and supplying the +% common last two arguments. Also subtract one from the initial value in +% \itemno, since @item increments \itemno. +% +\def\startenumeration#1{% + \advance\itemno by -1 + \itemizey{#1.}\Eenumerate\flushcr +} + +% @alphaenumerate and @capsenumerate are abbreviations for giving an arg +% to @enumerate. +% +\def\alphaenumerate{\enumerate{a}} +\def\capsenumerate{\enumerate{A}} +\def\Ealphaenumerate{\Eenumerate} +\def\Ecapsenumerate{\Eenumerate} + +% Definition of @item while inside @itemize. + +\def\itemizeitem{% +\advance\itemno by 1 +{\let\par=\endgraf \smallbreak}% +\ifhmode \errmessage{In hmode at itemizeitem}\fi +{\parskip=0in \hskip 0pt +\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% +\vadjust{\penalty 1200}}% +\flushcr} + +% @multitable macros +% Amy Hendrickson, 8/18/94, 3/6/96 +% +% @multitable ... @end multitable will make as many columns as desired. +% Contents of each column will wrap at width given in preamble. Width +% can be specified either with sample text given in a template line, +% or in percent of \hsize, the current width of text on page. + +% Table can continue over pages but will only break between lines. + +% To make preamble: +% +% Either define widths of columns in terms of percent of \hsize: +% @multitable @columnfractions .25 .3 .45 +% @item ... +% +% Numbers following @columnfractions are the percent of the total +% current hsize to be used for each column. You may use as many +% columns as desired. + + +% Or use a template: +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item ... +% using the widest term desired in each column. +% +% For those who want to use more than one line's worth of words in +% the preamble, break the line within one argument and it +% will parse correctly, i.e., +% +% @multitable {Column 1 template} {Column 2 template} {Column 3 +% template} +% Not: +% @multitable {Column 1 template} {Column 2 template} +% {Column 3 template} + +% Each new table line starts with @item, each subsequent new column +% starts with @tab. Empty columns may be produced by supplying @tab's +% with nothing between them for as many times as empty columns are needed, +% ie, @tab@tab@tab will produce two empty columns. + +% @item, @tab, @multitable or @end multitable do not need to be on their +% own lines, but it will not hurt if they are. + +% Sample multitable: + +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item first col stuff @tab second col stuff @tab third col +% @item +% first col stuff +% @tab +% second col stuff +% @tab +% third col +% @item first col stuff @tab second col stuff +% @tab Many paragraphs of text may be used in any column. +% +% They will wrap at the width determined by the template. +% @item@tab@tab This will be in third column. +% @end multitable + +% Default dimensions may be reset by user. +% @multitableparskip is vertical space between paragraphs in table. +% @multitableparindent is paragraph indent in table. +% @multitablecolmargin is horizontal space to be left between columns. +% @multitablelinespace is space to leave between table items, baseline +% to baseline. +% 0pt means it depends on current normal line spacing. +% +\newskip\multitableparskip +\newskip\multitableparindent +\newdimen\multitablecolspace +\newskip\multitablelinespace +\multitableparskip=0pt +\multitableparindent=6pt +\multitablecolspace=12pt +\multitablelinespace=0pt + +% Macros used to set up halign preamble: +% +\let\endsetuptable\relax +\def\xendsetuptable{\endsetuptable} +\let\columnfractions\relax +\def\xcolumnfractions{\columnfractions} +\newif\ifsetpercent + +% #1 is the part of the @columnfraction before the decimal point, which +% is presumably either 0 or the empty string (but we don't check, we +% just throw it away). #2 is the decimal part, which we use as the +% percent of \hsize for this column. +\def\pickupwholefraction#1.#2 {% + \global\advance\colcount by 1 + \expandafter\xdef\csname col\the\colcount\endcsname{.#2\hsize}% + \setuptable +} + +\newcount\colcount +\def\setuptable#1{% + \def\firstarg{#1}% + \ifx\firstarg\xendsetuptable + \let\go = \relax + \else + \ifx\firstarg\xcolumnfractions + \global\setpercenttrue + \else + \ifsetpercent + \let\go\pickupwholefraction + \else + \global\advance\colcount by 1 + \setbox0=\hbox{#1\unskip }% Add a normal word space as a separator; + % typically that is always in the input, anyway. + \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% + \fi + \fi + \ifx\go\pickupwholefraction + % Put the argument back for the \pickupwholefraction call, so + % we'll always have a period there to be parsed. + \def\go{\pickupwholefraction#1}% + \else + \let\go = \setuptable + \fi% + \fi + \go +} + +% This used to have \hskip1sp. But then the space in a template line is +% not enough. That is bad. So let's go back to just & until we +% encounter the problem it was intended to solve again. +% --karl, nathan@acm.org, 20apr99. +\def\tab{&} + +% @multitable ... @end multitable definitions: +% +\def\multitable{\parsearg\dotable} +\def\dotable#1{\bgroup + \vskip\parskip + \let\item\crcr + \tolerance=9500 + \hbadness=9500 + \setmultitablespacing + \parskip=\multitableparskip + \parindent=\multitableparindent + \overfullrule=0pt + \global\colcount=0 + \def\Emultitable{\global\setpercentfalse\cr\egroup\egroup}% + % + % To parse everything between @multitable and @item: + \setuptable#1 \endsetuptable + % + % \everycr will reset column counter, \colcount, at the end of + % each line. Every column entry will cause \colcount to advance by one. + % The table preamble + % looks at the current \colcount to find the correct column width. + \everycr{\noalign{% + % + % \filbreak%% keeps underfull box messages off when table breaks over pages. + % Maybe so, but it also creates really weird page breaks when the table + % breaks over pages. Wouldn't \vfil be better? Wait until the problem + % manifests itself, so it can be fixed for real --karl. + \global\colcount=0\relax}}% + % + % This preamble sets up a generic column definition, which will + % be used as many times as user calls for columns. + % \vtop will set a single line and will also let text wrap and + % continue for many paragraphs if desired. + \halign\bgroup&\global\advance\colcount by 1\relax + \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname + % + % In order to keep entries from bumping into each other + % we will add a \leftskip of \multitablecolspace to all columns after + % the first one. + % + % If a template has been used, we will add \multitablecolspace + % to the width of each template entry. + % + % If the user has set preamble in terms of percent of \hsize we will + % use that dimension as the width of the column, and the \leftskip + % will keep entries from bumping into each other. Table will start at + % left margin and final column will justify at right margin. + % + % Make sure we don't inherit \rightskip from the outer environment. + \rightskip=0pt + \ifnum\colcount=1 + % The first column will be indented with the surrounding text. + \advance\hsize by\leftskip + \else + \ifsetpercent \else + % If user has not set preamble in terms of percent of \hsize + % we will advance \hsize by \multitablecolspace. + \advance\hsize by \multitablecolspace + \fi + % In either case we will make \leftskip=\multitablecolspace: + \leftskip=\multitablecolspace + \fi + % Ignoring space at the beginning and end avoids an occasional spurious + % blank line, when TeX decides to break the line at the space before the + % box from the multistrut, so the strut ends up on a line by itself. + % For example: + % @multitable @columnfractions .11 .89 + % @item @code{#} + % @tab Legal holiday which is valid in major parts of the whole country. + % Is automatically provided with highlighting sequences respectively marking + % characters. + \noindent\ignorespaces##\unskip\multistrut}\cr +} + +\def\setmultitablespacing{% test to see if user has set \multitablelinespace. +% If so, do nothing. If not, give it an appropriate dimension based on +% current baselineskip. +\ifdim\multitablelinespace=0pt +\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip +\global\advance\multitablelinespace by-\ht0 +%% strut to put in table in case some entry doesn't have descenders, +%% to keep lines equally spaced +\let\multistrut = \strut +\else +%% FIXME: what is \box0 supposed to be? +\gdef\multistrut{\vrule height\multitablelinespace depth\dp0 +width0pt\relax} \fi +%% Test to see if parskip is larger than space between lines of +%% table. If not, do nothing. +%% If so, set to same dimension as multitablelinespace. +\ifdim\multitableparskip>\multitablelinespace +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. +\fi% +\ifdim\multitableparskip=0pt +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. +\fi} + + +\message{conditionals,} +% Prevent errors for section commands. +% Used in @ignore and in failing conditionals. +\def\ignoresections{% + \let\chapter=\relax + \let\unnumbered=\relax + \let\top=\relax + \let\unnumberedsec=\relax + \let\unnumberedsection=\relax + \let\unnumberedsubsec=\relax + \let\unnumberedsubsection=\relax + \let\unnumberedsubsubsec=\relax + \let\unnumberedsubsubsection=\relax + \let\section=\relax + \let\subsec=\relax + \let\subsubsec=\relax + \let\subsection=\relax + \let\subsubsection=\relax + \let\appendix=\relax + \let\appendixsec=\relax + \let\appendixsection=\relax + \let\appendixsubsec=\relax + \let\appendixsubsection=\relax + \let\appendixsubsubsec=\relax + \let\appendixsubsubsection=\relax + \let\contents=\relax + \let\smallbook=\relax + \let\titlepage=\relax +} + +% Used in nested conditionals, where we have to parse the Texinfo source +% and so want to turn off most commands, in case they are used +% incorrectly. +% +\def\ignoremorecommands{% + \let\defcodeindex = \relax + \let\defcv = \relax + \let\deffn = \relax + \let\deffnx = \relax + \let\defindex = \relax + \let\defivar = \relax + \let\defmac = \relax + \let\defmethod = \relax + \let\defop = \relax + \let\defopt = \relax + \let\defspec = \relax + \let\deftp = \relax + \let\deftypefn = \relax + \let\deftypefun = \relax + \let\deftypeivar = \relax + \let\deftypeop = \relax + \let\deftypevar = \relax + \let\deftypevr = \relax + \let\defun = \relax + \let\defvar = \relax + \let\defvr = \relax + \let\ref = \relax + \let\xref = \relax + \let\printindex = \relax + \let\pxref = \relax + \let\settitle = \relax + \let\setchapternewpage = \relax + \let\setchapterstyle = \relax + \let\everyheading = \relax + \let\evenheading = \relax + \let\oddheading = \relax + \let\everyfooting = \relax + \let\evenfooting = \relax + \let\oddfooting = \relax + \let\headings = \relax + \let\include = \relax + \let\lowersections = \relax + \let\down = \relax + \let\raisesections = \relax + \let\up = \relax + \let\set = \relax + \let\clear = \relax + \let\item = \relax +} + +% Ignore @ignore ... @end ignore. +% +\def\ignore{\doignore{ignore}} + +% Ignore @ifinfo, @ifhtml, @ifnottex, @html, @menu, and @direntry text. +% +\def\ifinfo{\doignore{ifinfo}} +\def\ifhtml{\doignore{ifhtml}} +\def\ifnottex{\doignore{ifnottex}} +\def\html{\doignore{html}} +\def\menu{\doignore{menu}} +\def\direntry{\doignore{direntry}} + +% @dircategory CATEGORY -- specify a category of the dir file +% which this file should belong to. Ignore this in TeX. +\let\dircategory = \comment + +% Ignore text until a line `@end #1'. +% +\def\doignore#1{\begingroup + % Don't complain about control sequences we have declared \outer. + \ignoresections + % + % Define a command to swallow text until we reach `@end #1'. + % This @ is a catcode 12 token (that is the normal catcode of @ in + % this texinfo.tex file). We change the catcode of @ below to match. + \long\def\doignoretext##1@end #1{\enddoignore}% + % + % Make sure that spaces turn into tokens that match what \doignoretext wants. + \catcode32 = 10 + % + % Ignore braces, too, so mismatched braces don't cause trouble. + \catcode`\{ = 9 + \catcode`\} = 9 + % + % We must not have @c interpreted as a control sequence. + \catcode`\@ = 12 + % + % Make the letter c a comment character so that the rest of the line + % will be ignored. This way, the document can have (for example) + % @c @end ifinfo + % and the @end ifinfo will be properly ignored. + % (We've just changed @ to catcode 12.) + \catcode`\c = 14 + % + % And now expand that command. + \doignoretext +} + +% What we do to finish off ignored text. +% +\def\enddoignore{\endgroup\ignorespaces}% + +\newif\ifwarnedobs\warnedobsfalse +\def\obstexwarn{% + \ifwarnedobs\relax\else + % We need to warn folks that they may have trouble with TeX 3.0. + % This uses \immediate\write16 rather than \message to get newlines. + \immediate\write16{} + \immediate\write16{WARNING: for users of Unix TeX 3.0!} + \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} + \immediate\write16{If you are running another version of TeX, relax.} + \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.} + \immediate\write16{ Then upgrade your TeX installation if you can.} + \immediate\write16{ (See ftp://ftp.gnu.org/pub/gnu/TeX.README.)} + \immediate\write16{If you are stuck with version 3.0, run the} + \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} + \immediate\write16{ to use a workaround.} + \immediate\write16{} + \global\warnedobstrue + \fi +} + +% **In TeX 3.0, setting text in \nullfont hangs tex. For a +% workaround (which requires the file ``dummy.tfm'' to be installed), +% uncomment the following line: +%%%%%\font\nullfont=dummy\let\obstexwarn=\relax + +% Ignore text, except that we keep track of conditional commands for +% purposes of nesting, up to an `@end #1' command. +% +\def\nestedignore#1{% + \obstexwarn + % We must actually expand the ignored text to look for the @end + % command, so that nested ignore constructs work. Thus, we put the + % text into a \vbox and then do nothing with the result. To minimize + % the change of memory overflow, we follow the approach outlined on + % page 401 of the TeXbook: make the current font be a dummy font. + % + \setbox0 = \vbox\bgroup + % Don't complain about control sequences we have declared \outer. + \ignoresections + % + % Define `@end #1' to end the box, which will in turn undefine the + % @end command again. + \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% + % + % We are going to be parsing Texinfo commands. Most cause no + % trouble when they are used incorrectly, but some commands do + % complicated argument parsing or otherwise get confused, so we + % undefine them. + % + % We can't do anything about stray @-signs, unfortunately; + % they'll produce `undefined control sequence' errors. + \ignoremorecommands + % + % Set the current font to be \nullfont, a TeX primitive, and define + % all the font commands to also use \nullfont. We don't use + % dummy.tfm, as suggested in the TeXbook, because not all sites + % might have that installed. Therefore, math mode will still + % produce output, but that should be an extremely small amount of + % stuff compared to the main input. + % + \nullfont + \let\tenrm=\nullfont \let\tenit=\nullfont \let\tensl=\nullfont + \let\tenbf=\nullfont \let\tentt=\nullfont \let\smallcaps=\nullfont + \let\tensf=\nullfont + % Similarly for index fonts (mostly for their use in smallexample). + \let\smallrm=\nullfont \let\smallit=\nullfont \let\smallsl=\nullfont + \let\smallbf=\nullfont \let\smalltt=\nullfont \let\smallsc=\nullfont + \let\smallsf=\nullfont + % + % Don't complain when characters are missing from the fonts. + \tracinglostchars = 0 + % + % Don't bother to do space factor calculations. + \frenchspacing + % + % Don't report underfull hboxes. + \hbadness = 10000 + % + % Do minimal line-breaking. + \pretolerance = 10000 + % + % Do not execute instructions in @tex + \def\tex{\doignore{tex}}% + % Do not execute macro definitions. + % `c' is a comment character, so the word `macro' will get cut off. + \def\macro{\doignore{ma}}% +} + +% @set VAR sets the variable VAR to an empty value. +% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. +% +% Since we want to separate VAR from REST-OF-LINE (which might be +% empty), we can't just use \parsearg; we have to insert a space of our +% own to delimit the rest of the line, and then take it out again if we +% didn't need it. Make sure the catcode of space is correct to avoid +% losing inside @example, for instance. +% +\def\set{\begingroup\catcode` =10 + \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. + \parsearg\setxxx} +\def\setxxx#1{\setyyy#1 \endsetyyy} +\def\setyyy#1 #2\endsetyyy{% + \def\temp{#2}% + \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty + \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. + \fi + \endgroup +} +% Can't use \xdef to pre-expand #2 and save some time, since \temp or +% \next or other control sequences that we've defined might get us into +% an infinite loop. Consider `@set foo @cite{bar}'. +\def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} + +% @clear VAR clears (i.e., unsets) the variable VAR. +% +\def\clear{\parsearg\clearxxx} +\def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} + +% @value{foo} gets the text saved in variable foo. +{ + \catcode`\_ = \active + % + % We might end up with active _ or - characters in the argument if + % we're called from @code, as @code{@value{foo-bar_}}. So \let any + % such active characters to their normal equivalents. + \gdef\value{\begingroup + \catcode`\-=12 \catcode`\_=12 + \indexbreaks \let_\normalunderscore + \valuexxx} +} +\def\valuexxx#1{\expandablevalue{#1}\endgroup} + +% We have this subroutine so that we can handle at least some @value's +% properly in indexes (we \let\value to this in \indexdummies). Ones +% whose names contain - or _ still won't work, but we can't do anything +% about that. The command has to be fully expandable, since the result +% winds up in the index file. This means that if the variable's value +% contains other Texinfo commands, it's almost certain it will fail +% (although perhaps we could fix that with sufficient work to do a +% one-level expansion on the result, instead of complete). +% +\def\expandablevalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + {[No value for ``#1'']}% + \else + \csname SET#1\endcsname + \fi +} + +% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined +% with @set. +% +\def\ifset{\parsearg\ifsetxxx} +\def\ifsetxxx #1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \expandafter\ifsetfail + \else + \expandafter\ifsetsucceed + \fi +} +\def\ifsetsucceed{\conditionalsucceed{ifset}} +\def\ifsetfail{\nestedignore{ifset}} +\defineunmatchedend{ifset} + +% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been +% defined with @set, or has been undefined with @clear. +% +\def\ifclear{\parsearg\ifclearxxx} +\def\ifclearxxx #1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \expandafter\ifclearsucceed + \else + \expandafter\ifclearfail + \fi +} +\def\ifclearsucceed{\conditionalsucceed{ifclear}} +\def\ifclearfail{\nestedignore{ifclear}} +\defineunmatchedend{ifclear} + +% @iftex, @ifnothtml, @ifnotinfo always succeed; we read the text +% following, through the first @end iftex (etc.). Make `@end iftex' +% (etc.) valid only after an @iftex. +% +\def\iftex{\conditionalsucceed{iftex}} +\def\ifnothtml{\conditionalsucceed{ifnothtml}} +\def\ifnotinfo{\conditionalsucceed{ifnotinfo}} +\defineunmatchedend{iftex} +\defineunmatchedend{ifnothtml} +\defineunmatchedend{ifnotinfo} + +% We can't just want to start a group at @iftex (for example) and end it +% at @end iftex, since then @set commands inside the conditional have no +% effect (they'd get reverted at the end of the group). So we must +% define \Eiftex to redefine itself to be its previous value. (We can't +% just define it to fail again with an ``unmatched end'' error, since +% the @ifset might be nested.) +% +\def\conditionalsucceed#1{% + \edef\temp{% + % Remember the current value of \E#1. + \let\nece{prevE#1} = \nece{E#1}% + % + % At the `@end #1', redefine \E#1 to be its previous value. + \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}% + }% + \temp +} + +% We need to expand lots of \csname's, but we don't want to expand the +% control sequences after we've constructed them. +% +\def\nece#1{\expandafter\noexpand\csname#1\endcsname} + +% @defininfoenclose. +\let\definfoenclose=\comment + + +\message{indexing,} +% Index generation facilities + +% Define \newwrite to be identical to plain tex's \newwrite +% except not \outer, so it can be used within \newindex. +{\catcode`\@=11 +\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} + +% \newindex {foo} defines an index named foo. +% It automatically defines \fooindex such that +% \fooindex ...rest of line... puts an entry in the index foo. +% It also defines \fooindfile to be the number of the output channel for +% the file that accumulates this index. The file's extension is foo. +% The name of an index should be no more than 2 characters long +% for the sake of vms. +% +\def\newindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 % Open the file + \fi + \expandafter\xdef\csname#1index\endcsname{% % Define @#1index + \noexpand\doindex{#1}} +} + +% @defindex foo == \newindex{foo} + +\def\defindex{\parsearg\newindex} + +% Define @defcodeindex, like @defindex except put all entries in @code. + +\def\newcodeindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 + \fi + \expandafter\xdef\csname#1index\endcsname{% + \noexpand\docodeindex{#1}} +} + +\def\defcodeindex{\parsearg\newcodeindex} + +% @synindex foo bar makes index foo feed into index bar. +% Do this instead of @defindex foo if you don't want it as a separate index. +% The \closeout helps reduce unnecessary open files; the limit on the +% Acorn RISC OS is a mere 16 files. +\def\synindex#1 #2 {% + \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname + \expandafter\closeout\csname#1indfile\endcsname + \expandafter\let\csname#1indfile\endcsname=\synindexfoo + \expandafter\xdef\csname#1index\endcsname{% define \xxxindex + \noexpand\doindex{#2}}% +} + +% @syncodeindex foo bar similar, but put all entries made for index foo +% inside @code. +\def\syncodeindex#1 #2 {% + \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname + \expandafter\closeout\csname#1indfile\endcsname + \expandafter\let\csname#1indfile\endcsname=\synindexfoo + \expandafter\xdef\csname#1index\endcsname{% define \xxxindex + \noexpand\docodeindex{#2}}% +} + +% Define \doindex, the driver for all \fooindex macros. +% Argument #1 is generated by the calling \fooindex macro, +% and it is "foo", the name of the index. + +% \doindex just uses \parsearg; it calls \doind for the actual work. +% This is because \doind is more useful to call from other macros. + +% There is also \dosubind {index}{topic}{subtopic} +% which makes an entry in a two-level index such as the operation index. + +\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} +\def\singleindexer #1{\doind{\indexname}{#1}} + +% like the previous two, but they put @code around the argument. +\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} +\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} + +\def\indexdummies{% +\def\ { }% +% Take care of the plain tex accent commands. +\def\"{\realbackslash "}% +\def\`{\realbackslash `}% +\def\'{\realbackslash '}% +\def\^{\realbackslash ^}% +\def\~{\realbackslash ~}% +\def\={\realbackslash =}% +\def\b{\realbackslash b}% +\def\c{\realbackslash c}% +\def\d{\realbackslash d}% +\def\u{\realbackslash u}% +\def\v{\realbackslash v}% +\def\H{\realbackslash H}% +% Take care of the plain tex special European modified letters. +\def\oe{\realbackslash oe}% +\def\ae{\realbackslash ae}% +\def\aa{\realbackslash aa}% +\def\OE{\realbackslash OE}% +\def\AE{\realbackslash AE}% +\def\AA{\realbackslash AA}% +\def\o{\realbackslash o}% +\def\O{\realbackslash O}% +\def\l{\realbackslash l}% +\def\L{\realbackslash L}% +\def\ss{\realbackslash ss}% +% Take care of texinfo commands likely to appear in an index entry. +% (Must be a way to avoid doing expansion at all, and thus not have to +% laboriously list every single command here.) +\def\@{@}% will be @@ when we switch to @ as escape char. +% Need these in case \tex is in effect and \{ is a \delimiter again. +% But can't use \lbracecmd and \rbracecmd because texindex assumes +% braces and backslashes are used only as delimiters. +\let\{ = \mylbrace +\let\} = \myrbrace +\def\_{{\realbackslash _}}% +\def\w{\realbackslash w }% +\def\bf{\realbackslash bf }% +%\def\rm{\realbackslash rm }% +\def\sl{\realbackslash sl }% +\def\sf{\realbackslash sf}% +\def\tt{\realbackslash tt}% +\def\gtr{\realbackslash gtr}% +\def\less{\realbackslash less}% +\def\hat{\realbackslash hat}% +\def\TeX{\realbackslash TeX}% +\def\dots{\realbackslash dots }% +\def\result{\realbackslash result}% +\def\equiv{\realbackslash equiv}% +\def\expansion{\realbackslash expansion}% +\def\print{\realbackslash print}% +\def\error{\realbackslash error}% +\def\point{\realbackslash point}% +\def\copyright{\realbackslash copyright}% +\def\tclose##1{\realbackslash tclose {##1}}% +\def\code##1{\realbackslash code {##1}}% +\def\uref##1{\realbackslash uref {##1}}% +\def\url##1{\realbackslash url {##1}}% +\def\env##1{\realbackslash env {##1}}% +\def\command##1{\realbackslash command {##1}}% +\def\option##1{\realbackslash option {##1}}% +\def\dotless##1{\realbackslash dotless {##1}}% +\def\samp##1{\realbackslash samp {##1}}% +\def\,##1{\realbackslash ,{##1}}% +\def\t##1{\realbackslash t {##1}}% +\def\r##1{\realbackslash r {##1}}% +\def\i##1{\realbackslash i {##1}}% +\def\b##1{\realbackslash b {##1}}% +\def\sc##1{\realbackslash sc {##1}}% +\def\cite##1{\realbackslash cite {##1}}% +\def\key##1{\realbackslash key {##1}}% +\def\file##1{\realbackslash file {##1}}% +\def\var##1{\realbackslash var {##1}}% +\def\kbd##1{\realbackslash kbd {##1}}% +\def\dfn##1{\realbackslash dfn {##1}}% +\def\emph##1{\realbackslash emph {##1}}% +\def\acronym##1{\realbackslash acronym {##1}}% +% +% Handle some cases of @value -- where the variable name does not +% contain - or _, and the value does not contain any +% (non-fully-expandable) commands. +\let\value = \expandablevalue +% +\unsepspaces +% Turn off macro expansion +\turnoffmacros +} + +% If an index command is used in an @example environment, any spaces +% therein should become regular spaces in the raw index file, not the +% expansion of \tie (\\leavevmode \penalty \@M \ ). +{\obeyspaces + \gdef\unsepspaces{\obeyspaces\let =\space}} + +% \indexnofonts no-ops all font-change commands. +% This is used when outputting the strings to sort the index by. +\def\indexdummyfont#1{#1} +\def\indexdummytex{TeX} +\def\indexdummydots{...} + +\def\indexnofonts{% +% Just ignore accents. +\let\,=\indexdummyfont +\let\"=\indexdummyfont +\let\`=\indexdummyfont +\let\'=\indexdummyfont +\let\^=\indexdummyfont +\let\~=\indexdummyfont +\let\==\indexdummyfont +\let\b=\indexdummyfont +\let\c=\indexdummyfont +\let\d=\indexdummyfont +\let\u=\indexdummyfont +\let\v=\indexdummyfont +\let\H=\indexdummyfont +\let\dotless=\indexdummyfont +% Take care of the plain tex special European modified letters. +\def\oe{oe}% +\def\ae{ae}% +\def\aa{aa}% +\def\OE{OE}% +\def\AE{AE}% +\def\AA{AA}% +\def\o{o}% +\def\O{O}% +\def\l{l}% +\def\L{L}% +\def\ss{ss}% +\let\w=\indexdummyfont +\let\t=\indexdummyfont +\let\r=\indexdummyfont +\let\i=\indexdummyfont +\let\b=\indexdummyfont +\let\emph=\indexdummyfont +\let\strong=\indexdummyfont +\let\cite=\indexdummyfont +\let\sc=\indexdummyfont +%Don't no-op \tt, since it isn't a user-level command +% and is used in the definitions of the active chars like <, >, |... +%\let\tt=\indexdummyfont +\let\tclose=\indexdummyfont +\let\code=\indexdummyfont +\let\url=\indexdummyfont +\let\uref=\indexdummyfont +\let\env=\indexdummyfont +\let\acronym=\indexdummyfont +\let\command=\indexdummyfont +\let\option=\indexdummyfont +\let\file=\indexdummyfont +\let\samp=\indexdummyfont +\let\kbd=\indexdummyfont +\let\key=\indexdummyfont +\let\var=\indexdummyfont +\let\TeX=\indexdummytex +\let\dots=\indexdummydots +\def\@{@}% +} + +% To define \realbackslash, we must make \ not be an escape. +% We must first make another character (@) an escape +% so we do not become unable to do a definition. + +{\catcode`\@=0 \catcode`\\=\other + @gdef@realbackslash{\}} + +\let\indexbackslash=0 %overridden during \printindex. +\let\SETmarginindex=\relax % put index entries in margin (undocumented)? + +% For \ifx comparisons. +\def\emptymacro{\empty} + +% Most index entries go through here, but \dosubind is the general case. +% +\def\doind#1#2{\dosubind{#1}{#2}\empty} + +% Workhorse for all \fooindexes. +% #1 is name of index, #2 is stuff to put there, #3 is subentry -- +% \empty if called from \doind, as we usually are. The main exception +% is with defuns, which call us directly. +% +\def\dosubind#1#2#3{% + % Put the index entry in the margin if desired. + \ifx\SETmarginindex\relax\else + \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% + \fi + {% + \count255=\lastpenalty + {% + \indexdummies % Must do this here, since \bf, etc expand at this stage + \escapechar=`\\ + {% + \let\folio = 0% We will expand all macros now EXCEPT \folio. + \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now + % so it will be output as is; and it will print as backslash. + % + \def\thirdarg{#3}% + % + % If third arg is present, precede it with space in sort key. + \ifx\thirdarg\emptymacro + \let\subentry = \empty + \else + \def\subentry{ #3}% + \fi + % + % First process the index entry with all font commands turned + % off to get the string to sort by. + {\indexnofonts \xdef\indexsorttmp{#2\subentry}}% + % + % Now the real index entry with the fonts. + \toks0 = {#2}% + % + % If third (subentry) arg is present, add it to the index + % string. And include a space. + \ifx\thirdarg\emptymacro \else + \toks0 = \expandafter{\the\toks0 \space #3}% + \fi + % + % Set up the complete index entry, with both the sort key + % and the original text, including any font commands. We write + % three arguments to \entry to the .?? file, texindex reduces to + % two when writing the .??s sorted result. + \edef\temp{% + \write\csname#1indfile\endcsname{% + \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}% + }% + % + % If a skip is the last thing on the list now, preserve it + % by backing up by \lastskip, doing the \write, then inserting + % the skip again. Otherwise, the whatsit generated by the + % \write will make \lastskip zero. The result is that sequences + % like this: + % @end defun + % @tindex whatever + % @defun ... + % will have extra space inserted, because the \medbreak in the + % start of the @defun won't see the skip inserted by the @end of + % the previous defun. + % + % But don't do any of this if we're not in vertical mode. We + % don't want to do a \vskip and prematurely end a paragraph. + % + % Avoid page breaks due to these extra skips, too. + % + \iflinks + \ifvmode + \skip0 = \lastskip + \ifdim\lastskip = 0pt \else \nobreak\vskip-\lastskip \fi + \fi + % + \temp % do the write + % + % + \ifvmode \ifdim\skip0 = 0pt \else \nobreak\vskip\skip0 \fi \fi + \fi + }% + }% + \penalty\count255 + }% +} + +% The index entry written in the file actually looks like +% \entry {sortstring}{page}{topic} +% or +% \entry {sortstring}{page}{topic}{subtopic} +% The texindex program reads in these files and writes files +% containing these kinds of lines: +% \initial {c} +% before the first topic whose initial is c +% \entry {topic}{pagelist} +% for a topic that is used without subtopics +% \primary {topic} +% for the beginning of a topic that is used with subtopics +% \secondary {subtopic}{pagelist} +% for each subtopic. + +% Define the user-accessible indexing commands +% @findex, @vindex, @kindex, @cindex. + +\def\findex {\fnindex} +\def\kindex {\kyindex} +\def\cindex {\cpindex} +\def\vindex {\vrindex} +\def\tindex {\tpindex} +\def\pindex {\pgindex} + +\def\cindexsub {\begingroup\obeylines\cindexsub} +{\obeylines % +\gdef\cindexsub "#1" #2^^M{\endgroup % +\dosubind{cp}{#2}{#1}}} + +% Define the macros used in formatting output of the sorted index material. + +% @printindex causes a particular index (the ??s file) to get printed. +% It does not print any chapter heading (usually an @unnumbered). +% +\def\printindex{\parsearg\doprintindex} +\def\doprintindex#1{\begingroup + \dobreak \chapheadingskip{10000}% + % + \smallfonts \rm + \tolerance = 9500 + \indexbreaks + % + % See if the index file exists and is nonempty. + % Change catcode of @ here so that if the index file contains + % \initial {@} + % as its first line, TeX doesn't complain about mismatched braces + % (because it thinks @} is a control sequence). + \catcode`\@ = 11 + \openin 1 \jobname.#1s + \ifeof 1 + % \enddoublecolumns gets confused if there is no text in the index, + % and it loses the chapter title and the aux file entries for the + % index. The easiest way to prevent this problem is to make sure + % there is some text. + \putwordIndexNonexistent + \else + % + % If the index file exists but is empty, then \openin leaves \ifeof + % false. We have to make TeX try to read something from the file, so + % it can discover if there is anything in it. + \read 1 to \temp + \ifeof 1 + \putwordIndexIsEmpty + \else + % Index files are almost Texinfo source, but we use \ as the escape + % character. It would be better to use @, but that's too big a change + % to make right now. + \def\indexbackslash{\rawbackslashxx}% + \catcode`\\ = 0 + \escapechar = `\\ + \begindoublecolumns + \input \jobname.#1s + \enddoublecolumns + \fi + \fi + \closein 1 +\endgroup} + +% These macros are used by the sorted index file itself. +% Change them to control the appearance of the index. + +\def\initial#1{{% + % Some minor font changes for the special characters. + \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt + % + % Remove any glue we may have, we'll be inserting our own. + \removelastskip + % + % We like breaks before the index initials, so insert a bonus. + \penalty -300 + % + % Typeset the initial. Making this add up to a whole number of + % baselineskips increases the chance of the dots lining up from column + % to column. It still won't often be perfect, because of the stretch + % we need before each entry, but it's better. + % + % No shrink because it confuses \balancecolumns. + \vskip 1.67\baselineskip plus .5\baselineskip + \leftline{\secbf #1}% + \vskip .33\baselineskip plus .1\baselineskip + % + % Do our best not to break after the initial. + \nobreak +}} + +% This typesets a paragraph consisting of #1, dot leaders, and then #2 +% flush to the right margin. It is used for index and table of contents +% entries. The paragraph is indented by \leftskip. +% +\def\entry#1#2{\begingroup + % + % Start a new paragraph if necessary, so our assignments below can't + % affect previous text. + \par + % + % Do not fill out the last line with white space. + \parfillskip = 0in + % + % No extra space above this paragraph. + \parskip = 0in + % + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % \hangindent is only relevant when the entry text and page number + % don't both fit on one line. In that case, bob suggests starting the + % dots pretty far over on the line. Unfortunately, a large + % indentation looks wrong when the entry text itself is broken across + % lines. So we use a small indentation and put up with long leaders. + % + % \hangafter is reset to 1 (which is the value we want) at the start + % of each paragraph, so we need not do anything with that. + \hangindent = 2em + % + % When the entry text needs to be broken, just fill out the first line + % with blank space. + \rightskip = 0pt plus1fil + % + % A bit of stretch before each entry for the benefit of balancing columns. + \vskip 0pt plus1pt + % + % Start a ``paragraph'' for the index entry so the line breaking + % parameters we've set above will have an effect. + \noindent + % + % Insert the text of the index entry. TeX will do line-breaking on it. + #1% + % The following is kludged to not output a line of dots in the index if + % there are no page numbers. The next person who breaks this will be + % cursed by a Unix daemon. + \def\tempa{{\rm }}% + \def\tempb{#2}% + \edef\tempc{\tempa}% + \edef\tempd{\tempb}% + \ifx\tempc\tempd\ \else% + % + % If we must, put the page number on a line of its own, and fill out + % this line with blank space. (The \hfil is overwhelmed with the + % fill leaders glue in \indexdotfill if the page number does fit.) + \hfil\penalty50 + \null\nobreak\indexdotfill % Have leaders before the page number. + % + % The `\ ' here is removed by the implicit \unskip that TeX does as + % part of (the primitive) \par. Without it, a spurious underfull + % \hbox ensues. + \ifpdf + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \else + \ #2% The page number ends the paragraph. + \fi + \fi% + \par +\endgroup} + +% Like \dotfill except takes at least 1 em. +\def\indexdotfill{\cleaders + \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill} + +\def\primary #1{\line{#1\hfil}} + +\newskip\secondaryindent \secondaryindent=0.5cm + +\def\secondary #1#2{ +{\parfillskip=0in \parskip=0in +\hangindent =1in \hangafter=1 +\noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par +}} + +% Define two-column mode, which we use to typeset indexes. +% Adapted from the TeXbook, page 416, which is to say, +% the manmac.tex format used to print the TeXbook itself. +\catcode`\@=11 + +\newbox\partialpage +\newdimen\doublecolumnhsize + +\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns + % Grab any single-column material above us. + \output = {% + % + % Here is a possibility not foreseen in manmac: if we accumulate a + % whole lot of material, we might end up calling this \output + % routine twice in a row (see the doublecol-lose test, which is + % essentially a couple of indexes with @setchapternewpage off). In + % that case we just ship out what is in \partialpage with the normal + % output routine. Generally, \partialpage will be empty when this + % runs and this will be a no-op. See the indexspread.tex test case. + \ifvoid\partialpage \else + \onepageout{\pagecontents\partialpage}% + \fi + % + \global\setbox\partialpage = \vbox{% + % Unvbox the main output page. + \unvbox\PAGE + \kern-\topskip \kern\baselineskip + }% + }% + \eject % run that output routine to set \partialpage + % + % Use the double-column output routine for subsequent pages. + \output = {\doublecolumnout}% + % + % Change the page size parameters. We could do this once outside this + % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 + % format, but then we repeat the same computation. Repeating a couple + % of assignments once per index is clearly meaningless for the + % execution time, so we may as well do it in one place. + % + % First we halve the line length, less a little for the gutter between + % the columns. We compute the gutter based on the line length, so it + % changes automatically with the paper format. The magic constant + % below is chosen so that the gutter has the same value (well, +-<1pt) + % as it did when we hard-coded it. + % + % We put the result in a separate register, \doublecolumhsize, so we + % can restore it in \pagesofar, after \hsize itself has (potentially) + % been clobbered. + % + \doublecolumnhsize = \hsize + \advance\doublecolumnhsize by -.04154\hsize + \divide\doublecolumnhsize by 2 + \hsize = \doublecolumnhsize + % + % Double the \vsize as well. (We don't need a separate register here, + % since nobody clobbers \vsize.) + \advance\vsize by -\ht\partialpage + \vsize = 2\vsize +} + +% The double-column output routine for all double-column pages except +% the last. +% +\def\doublecolumnout{% + \splittopskip=\topskip \splitmaxdepth=\maxdepth + % Get the available space for the double columns -- the normal + % (undoubled) page height minus any material left over from the + % previous page. + \dimen@ = \vsize + \divide\dimen@ by 2 + % + % box0 will be the left-hand column, box2 the right. + \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ + \onepageout\pagesofar + \unvbox255 + \penalty\outputpenalty +} +\def\pagesofar{% + % Re-output the contents of the output page -- any previous material, + % followed by the two boxes we just split, in box0 and box2. + \unvbox\partialpage + % + \hsize = \doublecolumnhsize + \wd0=\hsize \wd2=\hsize + \hbox to\pagewidth{\box0\hfil\box2}% +} +\def\enddoublecolumns{% + \output = {% + % Split the last of the double-column material. Leave it on the + % current page, no automatic page break. + \balancecolumns + % + % If we end up splitting too much material for the current page, + % though, there will be another page break right after this \output + % invocation ends. Having called \balancecolumns once, we do not + % want to call it again. Therefore, reset \output to its normal + % definition right away. (We hope \balancecolumns will never be + % called on to balance too much material, but if it is, this makes + % the output somewhat more palatable.) + \global\output = {\onepageout{\pagecontents\PAGE}}% + }% + \eject + \endgroup % started in \begindoublecolumns + % + % \pagegoal was set to the doubled \vsize above, since we restarted + % the current page. We're now back to normal single-column + % typesetting, so reset \pagegoal to the normal \vsize (after the + % \endgroup where \vsize got restored). + \pagegoal = \vsize +} +\def\balancecolumns{% + % Called at the end of the double column material. + \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. + \dimen@ = \ht0 + \advance\dimen@ by \topskip + \advance\dimen@ by-\baselineskip + \divide\dimen@ by 2 % target to split to + %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% + \splittopskip = \topskip + % Loop until we get a decent breakpoint. + {% + \vbadness = 10000 + \loop + \global\setbox3 = \copy0 + \global\setbox1 = \vsplit3 to \dimen@ + \ifdim\ht3>\dimen@ + \global\advance\dimen@ by 1pt + \repeat + }% + %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% + \setbox0=\vbox to\dimen@{\unvbox1}% + \setbox2=\vbox to\dimen@{\unvbox3}% + % + \pagesofar +} +\catcode`\@ = \other + + +\message{sectioning,} +% Chapters, sections, etc. + +\newcount\chapno +\newcount\secno \secno=0 +\newcount\subsecno \subsecno=0 +\newcount\subsubsecno \subsubsecno=0 + +% This counter is funny since it counts through charcodes of letters A, B, ... +\newcount\appendixno \appendixno = `\@ +% \def\appendixletter{\char\the\appendixno} +% We do the following for the sake of pdftex, which needs the actual +% letter in the expansion, not just typeset. +\def\appendixletter{% + \ifnum\appendixno=`A A% + \else\ifnum\appendixno=`B B% + \else\ifnum\appendixno=`C C% + \else\ifnum\appendixno=`D D% + \else\ifnum\appendixno=`E E% + \else\ifnum\appendixno=`F F% + \else\ifnum\appendixno=`G G% + \else\ifnum\appendixno=`H H% + \else\ifnum\appendixno=`I I% + \else\ifnum\appendixno=`J J% + \else\ifnum\appendixno=`K K% + \else\ifnum\appendixno=`L L% + \else\ifnum\appendixno=`M M% + \else\ifnum\appendixno=`N N% + \else\ifnum\appendixno=`O O% + \else\ifnum\appendixno=`P P% + \else\ifnum\appendixno=`Q Q% + \else\ifnum\appendixno=`R R% + \else\ifnum\appendixno=`S S% + \else\ifnum\appendixno=`T T% + \else\ifnum\appendixno=`U U% + \else\ifnum\appendixno=`V V% + \else\ifnum\appendixno=`W W% + \else\ifnum\appendixno=`X X% + \else\ifnum\appendixno=`Y Y% + \else\ifnum\appendixno=`Z Z% + % The \the is necessary, despite appearances, because \appendixletter is + % expanded while writing the .toc file. \char\appendixno is not + % expandable, thus it is written literally, thus all appendixes come out + % with the same letter (or @) in the toc without it. + \else\char\the\appendixno + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + +% Each @chapter defines this as the name of the chapter. +% page headings and footings can use it. @section does likewise. +\def\thischapter{} +\def\thissection{} + +\newcount\absseclevel % used to calculate proper heading level +\newcount\secbase\secbase=0 % @raise/lowersections modify this count + +% @raisesections: treat @section as chapter, @subsection as section, etc. +\def\raisesections{\global\advance\secbase by -1} +\let\up=\raisesections % original BFox name + +% @lowersections: treat @chapter as section, @section as subsection, etc. +\def\lowersections{\global\advance\secbase by 1} +\let\down=\lowersections % original BFox name + +% Choose a numbered-heading macro +% #1 is heading level if unmodified by @raisesections or @lowersections +% #2 is text for heading +\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \chapterzzz{#2} +\or + \seczzz{#2} +\or + \numberedsubseczzz{#2} +\or + \numberedsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \chapterzzz{#2} + \else + \numberedsubsubseczzz{#2} + \fi +\fi +} + +% like \numhead, but chooses appendix heading levels +\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \appendixzzz{#2} +\or + \appendixsectionzzz{#2} +\or + \appendixsubseczzz{#2} +\or + \appendixsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \appendixzzz{#2} + \else + \appendixsubsubseczzz{#2} + \fi +\fi +} + +% like \numhead, but chooses numberless heading levels +\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \unnumberedzzz{#2} +\or + \unnumberedseczzz{#2} +\or + \unnumberedsubseczzz{#2} +\or + \unnumberedsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \unnumberedzzz{#2} + \else + \unnumberedsubsubseczzz{#2} + \fi +\fi +} + +% @chapter, @appendix, @unnumbered. +\def\thischaptername{No Chapter Title} +\outer\def\chapter{\parsearg\chapteryyy} +\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz +\def\chapterzzz #1{% +\secno=0 \subsecno=0 \subsubsecno=0 +\global\advance \chapno by 1 \message{\putwordChapter\space \the\chapno}% +\chapmacro {#1}{\the\chapno}% +\gdef\thissection{#1}% +\gdef\thischaptername{#1}% +% We don't substitute the actual chapter name into \thischapter +% because we don't want its macros evaluated now. +\xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}% + {\the\chapno}}}% +\temp +\donoderef +\global\let\section = \numberedsec +\global\let\subsection = \numberedsubsec +\global\let\subsubsection = \numberedsubsubsec +} + +\outer\def\appendix{\parsearg\appendixyyy} +\def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz +\def\appendixzzz #1{% +\secno=0 \subsecno=0 \subsubsecno=0 +\global\advance \appendixno by 1 +\message{\putwordAppendix\space \appendixletter}% +\chapmacro {#1}{\putwordAppendix{} \appendixletter}% +\gdef\thissection{#1}% +\gdef\thischaptername{#1}% +\xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}% + {\putwordAppendix{} \appendixletter}}}% +\temp +\appendixnoderef +\global\let\section = \appendixsec +\global\let\subsection = \appendixsubsec +\global\let\subsubsection = \appendixsubsubsec +} + +% @centerchap is like @unnumbered, but the heading is centered. +\outer\def\centerchap{\parsearg\centerchapyyy} +\def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}} + +% @top is like @unnumbered. +\outer\def\top{\parsearg\unnumberedyyy} + +\outer\def\unnumbered{\parsearg\unnumberedyyy} +\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz +\def\unnumberedzzz #1{% +\secno=0 \subsecno=0 \subsubsecno=0 +% +% This used to be simply \message{#1}, but TeX fully expands the +% argument to \message. Therefore, if #1 contained @-commands, TeX +% expanded them. For example, in `@unnumbered The @cite{Book}', TeX +% expanded @cite (which turns out to cause errors because \cite is meant +% to be executed, not expanded). +% +% Anyway, we don't want the fully-expanded definition of @cite to appear +% as a result of the \message, we just want `@cite' itself. We use +% \the<toks register> to achieve this: TeX expands \the<toks> only once, +% simply yielding the contents of <toks register>. (We also do this for +% the toc entries.) +\toks0 = {#1}\message{(\the\toks0)}% +% +\unnumbchapmacro {#1}% +\gdef\thischapter{#1}\gdef\thissection{#1}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash unnumbchapentry{\the\toks0}}}% +\temp +\unnumbnoderef +\global\let\section = \unnumberedsec +\global\let\subsection = \unnumberedsubsec +\global\let\subsubsection = \unnumberedsubsubsec +} + +% Sections. +\outer\def\numberedsec{\parsearg\secyyy} +\def\secyyy #1{\numhead1{#1}} % normally calls seczzz +\def\seczzz #1{% +\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % +\gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}% + {\the\chapno}{\the\secno}}}% +\temp +\donoderef +\nobreak +} + +\outer\def\appendixsection{\parsearg\appendixsecyyy} +\outer\def\appendixsec{\parsearg\appendixsecyyy} +\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz +\def\appendixsectionzzz #1{% +\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % +\gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}% + {\appendixletter}{\the\secno}}}% +\temp +\appendixnoderef +\nobreak +} + +\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} +\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz +\def\unnumberedseczzz #1{% +\plainsecheading {#1}\gdef\thissection{#1}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash unnumbsecentry{\the\toks0}}}% +\temp +\unnumbnoderef +\nobreak +} + +% Subsections. +\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} +\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz +\def\numberedsubseczzz #1{% +\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % +\subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}% + {\the\chapno}{\the\secno}{\the\subsecno}}}% +\temp +\donoderef +\nobreak +} + +\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} +\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz +\def\appendixsubseczzz #1{% +\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % +\subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}% + {\appendixletter}{\the\secno}{\the\subsecno}}}% +\temp +\appendixnoderef +\nobreak +} + +\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} +\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz +\def\unnumberedsubseczzz #1{% +\plainsubsecheading {#1}\gdef\thissection{#1}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsecentry% + {\the\toks0}}}% +\temp +\unnumbnoderef +\nobreak +} + +% Subsubsections. +\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} +\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz +\def\numberedsubsubseczzz #1{% +\gdef\thissection{#1}\global\advance \subsubsecno by 1 % +\subsubsecheading {#1} + {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}% + {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}% +\temp +\donoderef +\nobreak +} + +\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} +\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz +\def\appendixsubsubseczzz #1{% +\gdef\thissection{#1}\global\advance \subsubsecno by 1 % +\subsubsecheading {#1} + {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}% + {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}% +\temp +\appendixnoderef +\nobreak +} + +\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} +\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz +\def\unnumberedsubsubseczzz #1{% +\plainsubsubsecheading {#1}\gdef\thissection{#1}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsubsecentry% + {\the\toks0}}}% +\temp +\unnumbnoderef +\nobreak +} + +% These are variants which are not "outer", so they can appear in @ifinfo. +% Actually, they should now be obsolete; ordinary section commands should work. +\def\infotop{\parsearg\unnumberedzzz} +\def\infounnumbered{\parsearg\unnumberedzzz} +\def\infounnumberedsec{\parsearg\unnumberedseczzz} +\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} +\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} + +\def\infoappendix{\parsearg\appendixzzz} +\def\infoappendixsec{\parsearg\appendixseczzz} +\def\infoappendixsubsec{\parsearg\appendixsubseczzz} +\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} + +\def\infochapter{\parsearg\chapterzzz} +\def\infosection{\parsearg\sectionzzz} +\def\infosubsection{\parsearg\subsectionzzz} +\def\infosubsubsection{\parsearg\subsubsectionzzz} + +% These macros control what the section commands do, according +% to what kind of chapter we are in (ordinary, appendix, or unnumbered). +% Define them by default for a numbered chapter. +\global\let\section = \numberedsec +\global\let\subsection = \numberedsubsec +\global\let\subsubsection = \numberedsubsubsec + +% Define @majorheading, @heading and @subheading + +% NOTE on use of \vbox for chapter headings, section headings, and such: +% 1) We use \vbox rather than the earlier \line to permit +% overlong headings to fold. +% 2) \hyphenpenalty is set to 10000 because hyphenation in a +% heading is obnoxious; this forbids it. +% 3) Likewise, headings look best if no \parindent is used, and +% if justification is not attempted. Hence \raggedright. + + +\def\majorheading{\parsearg\majorheadingzzz} +\def\majorheadingzzz #1{% +{\advance\chapheadingskip by 10pt \chapbreak }% +{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\penalty 200} + +\def\chapheading{\parsearg\chapheadingzzz} +\def\chapheadingzzz #1{\chapbreak % +{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\penalty 200} + +% @heading, @subheading, @subsubheading. +\def\heading{\parsearg\plainsecheading} +\def\subheading{\parsearg\plainsubsecheading} +\def\subsubheading{\parsearg\plainsubsubsecheading} + +% These macros generate a chapter, section, etc. heading only +% (including whitespace, linebreaking, etc. around it), +% given all the information in convenient, parsed form. + +%%% Args are the skip and penalty (usually negative) +\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} + +\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} + +%%% Define plain chapter starts, and page on/off switching for it +% Parameter controlling skip before chapter headings (if needed) + +\newskip\chapheadingskip + +\def\chapbreak{\dobreak \chapheadingskip {-4000}} +\def\chappager{\par\vfill\supereject} +\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} + +\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} + +\def\CHAPPAGoff{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chapbreak +\global\let\pagealignmacro=\chappager} + +\def\CHAPPAGon{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chappager +\global\let\pagealignmacro=\chappager +\global\def\HEADINGSon{\HEADINGSsingle}} + +\def\CHAPPAGodd{ +\global\let\contentsalignmacro = \chapoddpage +\global\let\pchapsepmacro=\chapoddpage +\global\let\pagealignmacro=\chapoddpage +\global\def\HEADINGSon{\HEADINGSdouble}} + +\CHAPPAGon + +\def\CHAPFplain{ +\global\let\chapmacro=\chfplain +\global\let\unnumbchapmacro=\unnchfplain +\global\let\centerchapmacro=\centerchfplain} + +% Plain chapter opening. +% #1 is the text, #2 the chapter number or empty if unnumbered. +\def\chfplain#1#2{% + \pchapsepmacro + {% + \chapfonts \rm + \def\chapnum{#2}% + \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}% + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright + \hangindent = \wd0 \centerparametersmaybe + \unhbox0 #1\par}% + }% + \nobreak\bigskip % no page break after a chapter title + \nobreak +} + +% Plain opening for unnumbered. +\def\unnchfplain#1{\chfplain{#1}{}} + +% @centerchap -- centered and unnumbered. +\let\centerparametersmaybe = \relax +\def\centerchfplain#1{{% + \def\centerparametersmaybe{% + \advance\rightskip by 3\rightskip + \leftskip = \rightskip + \parfillskip = 0pt + }% + \chfplain{#1}{}% +}} + +\CHAPFplain % The default + +\def\unnchfopen #1{% +\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\nobreak +} + +\def\chfopen #1#2{\chapoddpage {\chapfonts +\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% +\par\penalty 5000 % +} + +\def\centerchfopen #1{% +\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt + \hfill {\rm #1}\hfill}}\bigskip \par\nobreak +} + +\def\CHAPFopen{ +\global\let\chapmacro=\chfopen +\global\let\unnumbchapmacro=\unnchfopen +\global\let\centerchapmacro=\centerchfopen} + + +% Section titles. +\newskip\secheadingskip +\def\secheadingbreak{\dobreak \secheadingskip {-1000}} +\def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}} +\def\plainsecheading#1{\sectionheading{sec}{}{#1}} + +% Subsection titles. +\newskip \subsecheadingskip +\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} +\def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}} +\def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}} + +% Subsubsection titles. +\let\subsubsecheadingskip = \subsecheadingskip +\let\subsubsecheadingbreak = \subsecheadingbreak +\def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}} +\def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}} + + +% Print any size section title. +% +% #1 is the section type (sec/subsec/subsubsec), #2 is the section +% number (maybe empty), #3 the text. +\def\sectionheading#1#2#3{% + {% + \expandafter\advance\csname #1headingskip\endcsname by \parskip + \csname #1headingbreak\endcsname + }% + {% + % Switch to the right set of fonts. + \csname #1fonts\endcsname \rm + % + % Only insert the separating space if we have a section number. + \def\secnum{#2}% + \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}% + % + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright + \hangindent = \wd0 % zero if no section number + \unhbox0 #3}% + }% + \ifdim\parskip<10pt \nobreak\kern10pt\nobreak\kern-\parskip\fi \nobreak +} + + +\message{toc,} +% Table of contents. +\newwrite\tocfile + +% Write an entry to the toc file, opening it if necessary. +% Called from @chapter, etc. We supply {\folio} at the end of the +% argument, which will end up as the last argument to the \...entry macro. +% +% We open the .toc file here instead of at @setfilename or any other +% given time so that @contents can be put in the document anywhere. +% +\newif\iftocfileopened +\def\writetocentry#1{% + \iftocfileopened\else + \immediate\openout\tocfile = \jobname.toc + \global\tocfileopenedtrue + \fi + \iflinks \write\tocfile{#1{\folio}}\fi +} + +\newskip\contentsrightmargin \contentsrightmargin=1in +\newcount\savepageno +\newcount\lastnegativepageno \lastnegativepageno = -1 + +% Finish up the main text and prepare to read what we've written +% to \tocfile. +% +\def\startcontents#1{% + % If @setchapternewpage on, and @headings double, the contents should + % start on an odd page, unlike chapters. Thus, we maintain + % \contentsalignmacro in parallel with \pagealignmacro. + % From: Torbjorn Granlund <tege@matematik.su.se> + \contentsalignmacro + \immediate\closeout\tocfile + % + % Don't need to put `Contents' or `Short Contents' in the headline. + % It is abundantly clear what they are. + \unnumbchapmacro{#1}\def\thischapter{}% + \savepageno = \pageno + \begingroup % Set up to handle contents files properly. + \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 + % We can't do this, because then an actual ^ in a section + % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. + %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi + \raggedbottom % Worry more about breakpoints than the bottom. + \advance\hsize by -\contentsrightmargin % Don't use the full line length. + % + % Roman numerals for page numbers. + \ifnum \pageno>0 \pageno = \lastnegativepageno \fi +} + + +% Normal (long) toc. +\def\contents{% + \startcontents{\putwordTOC}% + \openin 1 \jobname.toc + \ifeof 1 \else + \closein 1 + \input \jobname.toc + \fi + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \pdfmakeoutlines + \endgroup + \lastnegativepageno = \pageno + \pageno = \savepageno +} + +% And just the chapters. +\def\summarycontents{% + \startcontents{\putwordShortTOC}% + % + \let\chapentry = \shortchapentry + \let\unnumbchapentry = \shortunnumberedentry + % We want a true roman here for the page numbers. + \secfonts + \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl + \rm + \hyphenpenalty = 10000 + \advance\baselineskip by 1pt % Open it up a little. + \def\secentry ##1##2##3##4{} + \def\unnumbsecentry ##1##2{} + \def\subsecentry ##1##2##3##4##5{} + \def\unnumbsubsecentry ##1##2{} + \def\subsubsecentry ##1##2##3##4##5##6{} + \def\unnumbsubsubsecentry ##1##2{} + \openin 1 \jobname.toc + \ifeof 1 \else + \closein 1 + \input \jobname.toc + \fi + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \endgroup + \lastnegativepageno = \pageno + \pageno = \savepageno +} +\let\shortcontents = \summarycontents + +\ifpdf + \pdfcatalog{/PageMode /UseOutlines}% +\fi + +% These macros generate individual entries in the table of contents. +% The first argument is the chapter or section name. +% The last argument is the page number. +% The arguments in between are the chapter number, section number, ... + +% Chapter-level things, for both the long and short contents. +\def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} + +% See comments in \dochapentry re vbox and related settings +\def\shortchapentry#1#2#3{% + \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#3\egroup}% +} + +% Typeset the label for a chapter or appendix for the short contents. +% The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter. +% We could simplify the code here by writing out an \appendixentry +% command in the toc file for appendices, instead of using \chapentry +% for both, but it doesn't seem worth it. +% +\newdimen\shortappendixwidth +% +\def\shortchaplabel#1{% + % Compute width of word "Appendix", may change with language. + \setbox0 = \hbox{\shortcontrm \putwordAppendix}% + \shortappendixwidth = \wd0 + % + % We typeset #1 in a box of constant width, regardless of the text of + % #1, so the chapter titles will come out aligned. + \setbox0 = \hbox{#1}% + \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi + % + % This space should be plenty, since a single number is .5em, and the + % widest letter (M) is 1em, at least in the Computer Modern fonts. + % (This space doesn't include the extra space that gets added after + % the label; that gets put in by \shortchapentry above.) + \advance\dimen0 by 1.1em + \hbox to \dimen0{#1\hfil}% +} + +\def\unnumbchapentry#1#2{\dochapentry{#1}{#2}} +\def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno\bgroup#2\egroup}} + +% Sections. +\def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} +\def\unnumbsecentry#1#2{\dosecentry{#1}{#2}} + +% Subsections. +\def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} +\def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}} + +% And subsubsections. +\def\subsubsecentry#1#2#3#4#5#6{% + \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} +\def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}} + +% This parameter controls the indentation of the various levels. +\newdimen\tocindent \tocindent = 3pc + +% Now for the actual typesetting. In all these, #1 is the text and #2 is the +% page number. +% +% If the toc has to be broken over pages, we want it to be at chapters +% if at all possible; hence the \penalty. +\def\dochapentry#1#2{% + \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip + \begingroup + \chapentryfonts + \tocentry{#1}{\dopageno\bgroup#2\egroup}% + \endgroup + \nobreak\vskip .25\baselineskip plus.1\baselineskip +} + +\def\dosecentry#1#2{\begingroup + \secentryfonts \leftskip=\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsecentry#1#2{\begingroup + \subsecentryfonts \leftskip=2\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsubsecentry#1#2{\begingroup + \subsubsecentryfonts \leftskip=3\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +% Final typesetting of a toc entry; we use the same \entry macro as for +% the index entries, but we want to suppress hyphenation here. (We +% can't do that in the \entry macro, since index entries might consist +% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) +\def\tocentry#1#2{\begingroup + \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks + % Do not use \turnoffactive in these arguments. Since the toc is + % typeset in cmr, so characters such as _ would come out wrong; we + % have to do the usual translation tricks. + \entry{#1}{#2}% +\endgroup} + +% Space between chapter (or whatever) number and the title. +\def\labelspace{\hskip1em \relax} + +\def\dopageno#1{{\rm #1}} +\def\doshortpageno#1{{\rm #1}} + +\def\chapentryfonts{\secfonts \rm} +\def\secentryfonts{\textfonts} +\let\subsecentryfonts = \textfonts +\let\subsubsecentryfonts = \textfonts + + +\message{environments,} +% @foo ... @end foo. + +% Since these characters are used in examples, it should be an even number of +% \tt widths. Each \tt character is 1en, so two makes it 1em. +% Furthermore, these definitions must come after we define our fonts. +\newbox\dblarrowbox \newbox\longdblarrowbox +\newbox\pushcharbox \newbox\bullbox +\newbox\equivbox \newbox\errorbox + +%{\tentt +%\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil} +%\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil} +%\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil} +%\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil} +% Adapted from the manmac format (p.420 of TeXbook) +%\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex +% depth .1ex\hfil} +%} + +% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. +\def\point{$\star$} +\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} +\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} +\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} +\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} + +% Adapted from the TeXbook's \boxit. +{\tentt \global\dimen0 = 3em}% Width of the box. +\dimen2 = .55pt % Thickness of rules +% The text. (`r' is open on the right, `e' somewhat less so on the left.) +\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} + +\global\setbox\errorbox=\hbox to \dimen0{\hfil + \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. + \advance\hsize by -2\dimen2 % Rules. + \vbox{ + \hrule height\dimen2 + \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. + \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. + \kern3pt\vrule width\dimen2}% Space to right. + \hrule height\dimen2} + \hfil} + +% The @error{} command. +\def\error{\leavevmode\lower.7ex\copy\errorbox} + +% @tex ... @end tex escapes into raw Tex temporarily. +% One exception: @ is still an escape character, so that @end tex works. +% But \@ or @@ will get a plain tex @ character. + +\def\tex{\begingroup + \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 + \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 + \catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie + \catcode `\%=14 + \catcode 43=12 % plus + \catcode`\"=12 + \catcode`\==12 + \catcode`\|=12 + \catcode`\<=12 + \catcode`\>=12 + \escapechar=`\\ + % + \let\b=\ptexb + \let\bullet=\ptexbullet + \let\c=\ptexc + \let\,=\ptexcomma + \let\.=\ptexdot + \let\dots=\ptexdots + \let\equiv=\ptexequiv + \let\!=\ptexexclam + \let\i=\ptexi + \let\{=\ptexlbrace + \let\+=\tabalign + \let\}=\ptexrbrace + \let\*=\ptexstar + \let\t=\ptext + % + \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% + \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% + \def\@{@}% +\let\Etex=\endgroup} + +% Define @lisp ... @endlisp. +% @lisp does a \begingroup so it can rebind things, +% including the definition of @endlisp (which normally is erroneous). + +% Amount to narrow the margins by for @lisp. +\newskip\lispnarrowing \lispnarrowing=0.4in + +% This is the definition that ^^M gets inside @lisp, @example, and other +% such environments. \null is better than a space, since it doesn't +% have any width. +\def\lisppar{\null\endgraf} + +% Make each space character in the input produce a normal interword +% space in the output. Don't allow a line break at this space, as this +% is used only in environments like @example, where each line of input +% should produce a line of output anyway. +% +{\obeyspaces % +\gdef\sepspaces{\obeyspaces\let =\tie}} + +% Define \obeyedspace to be our active space, whatever it is. This is +% for use in \parsearg. +{\sepspaces% +\global\let\obeyedspace= } + +% This space is always present above and below environments. +\newskip\envskipamount \envskipamount = 0pt + +% Make spacing and below environment symmetrical. We use \parskip here +% to help in doing that, since in @example-like environments \parskip +% is reset to zero; thus the \afterenvbreak inserts no space -- but the +% start of the next paragraph will insert \parskip +% +\def\aboveenvbreak{{\advance\envskipamount by \parskip +\endgraf \ifdim\lastskip<\envskipamount +\removelastskip \penalty-50 \vskip\envskipamount \fi}} + +\let\afterenvbreak = \aboveenvbreak + +% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. +\let\nonarrowing=\relax + +% @cartouche ... @end cartouche: draw rectangle w/rounded corners around +% environment contents. +\font\circle=lcircle10 +\newdimen\circthick +\newdimen\cartouter\newdimen\cartinner +\newskip\normbskip\newskip\normpskip\newskip\normlskip +\circthick=\fontdimen8\circle +% +\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth +\def\ctr{{\hskip 6pt\circle\char'010}} +\def\cbl{{\circle\char'012\hskip -6pt}} +\def\cbr{{\hskip 6pt\circle\char'011}} +\def\carttop{\hbox to \cartouter{\hskip\lskip + \ctl\leaders\hrule height\circthick\hfil\ctr + \hskip\rskip}} +\def\cartbot{\hbox to \cartouter{\hskip\lskip + \cbl\leaders\hrule height\circthick\hfil\cbr + \hskip\rskip}} +% +\newskip\lskip\newskip\rskip + +\long\def\cartouche{% +\begingroup + \lskip=\leftskip \rskip=\rightskip + \leftskip=0pt\rightskip=0pt %we want these *outside*. + \cartinner=\hsize \advance\cartinner by-\lskip + \advance\cartinner by-\rskip + \cartouter=\hsize + \advance\cartouter by 18.4pt % allow for 3pt kerns on either +% side, and for 6pt waste from +% each corner char, and rule thickness + \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip + % Flag to tell @lisp, etc., not to narrow margin. + \let\nonarrowing=\comment + \vbox\bgroup + \baselineskip=0pt\parskip=0pt\lineskip=0pt + \carttop + \hbox\bgroup + \hskip\lskip + \vrule\kern3pt + \vbox\bgroup + \hsize=\cartinner + \kern3pt + \begingroup + \baselineskip=\normbskip + \lineskip=\normlskip + \parskip=\normpskip + \vskip -\parskip +\def\Ecartouche{% + \endgroup + \kern3pt + \egroup + \kern3pt\vrule + \hskip\rskip + \egroup + \cartbot + \egroup +\endgroup +}} + + +% This macro is called at the beginning of all the @example variants, +% inside a group. +\def\nonfillstart{% + \aboveenvbreak + \inENV % This group ends at the end of the body + \hfuzz = 12pt % Don't be fussy + \sepspaces % Make spaces be word-separators rather than space tokens. + \singlespace + \let\par = \lisppar % don't ignore blank lines + \obeylines % each line of input is a line of output + \parskip = 0pt + \parindent = 0pt + \emergencystretch = 0pt % don't try to avoid overfull boxes + % @cartouche defines \nonarrowing to inhibit narrowing + % at next level down. + \ifx\nonarrowing\relax + \advance \leftskip by \lispnarrowing + \exdentamount=\lispnarrowing + \let\exdent=\nofillexdent + \let\nonarrowing=\relax + \fi +} + +% Define the \E... control sequence only if we are inside the particular +% environment, so the error checking in \end will work. +% +% To end an @example-like environment, we first end the paragraph (via +% \afterenvbreak's vertical glue), and then the group. That way we keep +% the zero \parskip that the environments set -- \parskip glue will be +% inserted at the beginning of the next paragraph in the document, after +% the environment. +% +\def\nonfillfinish{\afterenvbreak\endgroup} + +% @lisp: indented, narrowed, typewriter font. +\def\lisp{\begingroup + \nonfillstart + \let\Elisp = \nonfillfinish + \tt + \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. + \gobble % eat return +} + +% @example: Same as @lisp. +\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} + +% @small... is usually equivalent to the non-small (@smallbook +% redefines). We must call \example (or whatever) last in the +% definition, since it reads the return following the @example (or +% whatever) command. +% +% This actually allows (for example) @end display inside an +% @smalldisplay. Too bad, but makeinfo will catch the error anyway. +% +\def\smalldisplay{\begingroup\def\Esmalldisplay{\nonfillfinish\endgroup}\display} +\def\smallexample{\begingroup\def\Esmallexample{\nonfillfinish\endgroup}\lisp} +\def\smallformat{\begingroup\def\Esmallformat{\nonfillfinish\endgroup}\format} +\def\smalllisp{\begingroup\def\Esmalllisp{\nonfillfinish\endgroup}\lisp} + +% Real @smallexample and @smalllisp (when @smallbook): use smaller fonts. +% Originally contributed by Pavel@xerox. +\def\smalllispx{\begingroup + \def\Esmalllisp{\nonfillfinish\endgroup}% + \def\Esmallexample{\nonfillfinish\endgroup}% + \smallfonts + \lisp +} + +% @display: same as @lisp except keep current font. +% +\def\display{\begingroup + \nonfillstart + \let\Edisplay = \nonfillfinish + \gobble +} + +% @smalldisplay (when @smallbook): @display plus smaller fonts. +% +\def\smalldisplayx{\begingroup + \def\Esmalldisplay{\nonfillfinish\endgroup}% + \smallfonts \rm + \display +} + +% @format: same as @display except don't narrow margins. +% +\def\format{\begingroup + \let\nonarrowing = t + \nonfillstart + \let\Eformat = \nonfillfinish + \gobble +} + +% @smallformat (when @smallbook): @format plus smaller fonts. +% +\def\smallformatx{\begingroup + \def\Esmallformat{\nonfillfinish\endgroup}% + \smallfonts \rm + \format +} + +% @flushleft (same as @format). +% +\def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format} + +% @flushright. +% +\def\flushright{\begingroup + \let\nonarrowing = t + \nonfillstart + \let\Eflushright = \nonfillfinish + \advance\leftskip by 0pt plus 1fill + \gobble +} + +% @quotation does normal linebreaking (hence we can't use \nonfillstart) +% and narrows the margins. +% +\def\quotation{% + \begingroup\inENV %This group ends at the end of the @quotation body + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \singlespace + \parindent=0pt + % We have retained a nonzero parskip for the environment, since we're + % doing normal filling. So to avoid extra space below the environment... + \def\Equotation{\parskip = 0pt \nonfillfinish}% + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \advance\rightskip by \lispnarrowing + \exdentamount = \lispnarrowing + \let\nonarrowing = \relax + \fi +} + + +\message{defuns,} +% @defun etc. + +% Allow user to change definition object font (\df) internally +\def\setdeffont #1 {\csname DEF#1\endcsname} + +\newskip\defbodyindent \defbodyindent=.4in +\newskip\defargsindent \defargsindent=50pt +\newskip\deftypemargin \deftypemargin=12pt +\newskip\deflastargmargin \deflastargmargin=18pt + +\newcount\parencount +% define \functionparens, which makes ( and ) and & do special things. +% \functionparens affects the group it is contained in. +\def\activeparens{% +\catcode`\(=\active \catcode`\)=\active \catcode`\&=\active +\catcode`\[=\active \catcode`\]=\active} + +% Make control sequences which act like normal parenthesis chars. +\let\lparen = ( \let\rparen = ) + +{\activeparens % Now, smart parens don't turn on until &foo (see \amprm) + +% Be sure that we always have a definition for `(', etc. For example, +% if the fn name has parens in it, \boldbrax will not be in effect yet, +% so TeX would otherwise complain about undefined control sequence. +\global\let(=\lparen \global\let)=\rparen +\global\let[=\lbrack \global\let]=\rbrack + +\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } +\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} +% This is used to turn on special parens +% but make & act ordinary (given that it's active). +\gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} + +% Definitions of (, ) and & used in args for functions. +% This is the definition of ( outside of all parentheses. +\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested + \global\advance\parencount by 1 +} +% +% This is the definition of ( when already inside a level of parens. +\gdef\opnested{\char`\(\global\advance\parencount by 1 } +% +\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. + % also in that case restore the outer-level definition of (. + \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi + \global\advance \parencount by -1 } +% If we encounter &foo, then turn on ()-hacking afterwards +\gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } +% +\gdef\normalparens{\boldbrax\let&=\ampnr} +} % End of definition inside \activeparens +%% These parens (in \boldbrax) actually are a little bolder than the +%% contained text. This is especially needed for [ and ] +\def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } +\def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } +\let\ampnr = \& +\def\lbrb{{\bf\char`\[}} +\def\rbrb{{\bf\char`\]}} + +% Active &'s sneak into the index arguments, so make sure it's defined. +{ + \catcode`& = 13 + \global\let& = \ampnr +} + +% First, defname, which formats the header line itself. +% #1 should be the function name. +% #2 should be the type of definition, such as "Function". + +\def\defname #1#2{% +% Get the values of \leftskip and \rightskip as they were +% outside the @def... +\dimen2=\leftskip +\advance\dimen2 by -\defbodyindent +\noindent +\setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}% +\dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line +\dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations +\parshape 2 0in \dimen0 \defargsindent \dimen1 +% Now output arg 2 ("Function" or some such) +% ending at \deftypemargin from the right margin, +% but stuck inside a box of width 0 so it does not interfere with linebreaking +{% Adjust \hsize to exclude the ambient margins, +% so that \rightline will obey them. +\advance \hsize by -\dimen2 +\rlap{\rightline{{\rm #2}\hskip -1.25pc }}}% +% Make all lines underfull and no complaints: +\tolerance=10000 \hbadness=10000 +\advance\leftskip by -\defbodyindent +\exdentamount=\defbodyindent +{\df #1}\enskip % Generate function name +} + +% Actually process the body of a definition +% #1 should be the terminating control sequence, such as \Edefun. +% #2 should be the "another name" control sequence, such as \defunx. +% #3 should be the control sequence that actually processes the header, +% such as \defunheader. + +\def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2{\begingroup\obeylines\activeparens\spacesplit#3}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup % +\catcode 61=\active % 61 is `=' +\obeylines\activeparens\spacesplit#3} + +% #1 is the \E... control sequence to end the definition (which we define). +% #2 is the \...x control sequence for consecutive fns (which we define). +% #3 is the control sequence to call to resume processing. +% #4, delimited by the space, is the class name. +% +\def\defmethparsebody#1#2#3#4 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup\obeylines\activeparens\spacesplit{#3{#4}}} + +% Used for @deftypemethod and @deftypeivar. +% #1 is the \E... control sequence to end the definition (which we define). +% #2 is the \...x control sequence for consecutive fns (which we define). +% #3 is the control sequence to call to resume processing. +% #4, delimited by a space, is the class name. +% #5 is the method's return type. +% +\def\deftypemethparsebody#1#2#3#4 #5 {\begingroup\inENV + \medbreak + \def#1{\endgraf\endgroup\medbreak}% + \def#2##1 ##2 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}{##2}}}% + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup\obeylines\activeparens\spacesplit{#3{#4}{#5}}} + +% Used for @deftypeop. The change from \deftypemethparsebody is an +% extra argument at the beginning which is the `category', instead of it +% being the hardwired string `Method' or `Instance Variable'. We have +% to account for this both in the \...x definition and in parsing the +% input at hand. Thus also need a control sequence (passed as #5) for +% the \E... definition to assign the category name to. +% +\def\deftypeopparsebody#1#2#3#4#5 #6 {\begingroup\inENV + \medbreak + \def#1{\endgraf\endgroup\medbreak}% + \def#2##1 ##2 ##3 {% + \def#4{##1}% + \begingroup\obeylines\activeparens\spacesplit{#3{##2}{##3}}}% + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup\obeylines\activeparens\spacesplit{#3{#5}{#6}}} + +\def\defopparsebody #1#2#3#4#5 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 ##2 {\def#4{##1}% +\begingroup\obeylines\activeparens\spacesplit{#3{##2}}}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup\obeylines\activeparens\spacesplit{#3{#5}}} + +% These parsing functions are similar to the preceding ones +% except that they do not make parens into active characters. +% These are used for "variables" since they have no arguments. + +\def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2{\begingroup\obeylines\spacesplit#3}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup % +\catcode 61=\active % +\obeylines\spacesplit#3} + +% This is used for \def{tp,vr}parsebody. It could probably be used for +% some of the others, too, with some judicious conditionals. +% +\def\parsebodycommon#1#2#3{% + \begingroup\inENV % + \medbreak % + % Define the end token that this defining construct specifies + % so that it will exit this group. + \def#1{\endgraf\endgroup\medbreak}% + \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup\obeylines +} + +\def\defvrparsebody#1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \spacesplit{#3{#4}}% +} + +% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the +% type is just `struct', because we lose the braces in `{struct +% termios}' when \spacesplit reads its undelimited argument. Sigh. +% \let\deftpparsebody=\defvrparsebody +% +% So, to get around this, we put \empty in with the type name. That +% way, TeX won't find exactly `{...}' as an undelimited argument, and +% won't strip off the braces. +% +\def\deftpparsebody #1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \spacesplit{\parsetpheaderline{#3{#4}}}\empty +} + +% Fine, but then we have to eventually remove the \empty *and* the +% braces (if any). That's what this does. +% +\def\removeemptybraces\empty#1\relax{#1} + +% After \spacesplit has done its work, this is called -- #1 is the final +% thing to call, #2 the type name (which starts with \empty), and #3 +% (which might be empty) the arguments. +% +\def\parsetpheaderline#1#2#3{% + #1{\removeemptybraces#2\relax}{#3}% +}% + +\def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 ##2 {\def#4{##1}% +\begingroup\obeylines\spacesplit{#3{##2}}}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup\obeylines\spacesplit{#3{#5}}} + +% Split up #2 at the first space token. +% call #1 with two arguments: +% the first is all of #2 before the space token, +% the second is all of #2 after that space token. +% If #2 contains no space token, all of it is passed as the first arg +% and the second is passed as empty. + +{\obeylines +\gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}% +\long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{% +\ifx\relax #3% +#1{#2}{}\else #1{#2}{#3#4}\fi}} + +% So much for the things common to all kinds of definitions. + +% Define @defun. + +% First, define the processing that is wanted for arguments of \defun +% Use this to expand the args and terminate the paragraph they make up + +\def\defunargs#1{\functionparens \sl +% Expand, preventing hyphenation at `-' chars. +% Note that groups don't affect changes in \hyphenchar. +% Set the font temporarily and use \font in case \setfont made \tensl a macro. +{\tensl\hyphenchar\font=0}% +#1% +{\tensl\hyphenchar\font=45}% +\ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% +\interlinepenalty=10000 +\advance\rightskip by 0pt plus 1fil +\endgraf\nobreak\vskip -\parskip\nobreak +} + +\def\deftypefunargs #1{% +% Expand, preventing hyphenation at `-' chars. +% Note that groups don't affect changes in \hyphenchar. +% Use \boldbraxnoamp, not \functionparens, so that & is not special. +\boldbraxnoamp +\tclose{#1}% avoid \code because of side effects on active chars +\interlinepenalty=10000 +\advance\rightskip by 0pt plus 1fil +\endgraf\nobreak\vskip -\parskip\nobreak +} + +% Do complete processing of one @defun or @defunx line already parsed. + +% @deffn Command forward-char nchars + +\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} + +\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% +\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defun == @deffn Function + +\def\defun{\defparsebody\Edefun\defunx\defunheader} + +\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{\putwordDeffunc}% +\defunargs {#2}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @deftypefun int foobar (int @var{foo}, float @var{bar}) + +\def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} + +% #1 is the data type. #2 is the name and args. +\def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} +% #1 is the data type, #2 the name, #3 the args. +\def\deftypefunheaderx #1#2 #3\relax{% +\doind {fn}{\code{#2}}% Make entry in function index +\begingroup\defname {\defheaderxcond#1\relax$$$#2}{\putwordDeftypefun}% +\deftypefunargs {#3}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) + +\def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} + +% \defheaderxcond#1\relax$$$ +% puts #1 in @code, followed by a space, but does nothing if #1 is null. +\def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi} + +% #1 is the classification. #2 is the data type. #3 is the name and args. +\def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} +% #1 is the classification, #2 the data type, #3 the name, #4 the args. +\def\deftypefnheaderx #1#2#3 #4\relax{% +\doind {fn}{\code{#3}}% Make entry in function index +\begingroup +\normalparens % notably, turn off `&' magic, which prevents +% at least some C++ text from working +\defname {\defheaderxcond#2\relax$$$#3}{#1}% +\deftypefunargs {#4}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defmac == @deffn Macro + +\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} + +\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{\putwordDefmac}% +\defunargs {#2}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defspec == @deffn Special Form + +\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} + +\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{\putwordDefspec}% +\defunargs {#2}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defop CATEGORY CLASS OPERATION ARG... +% +\def\defop #1 {\def\defoptype{#1}% +\defopparsebody\Edefop\defopx\defopheader\defoptype} +% +\def\defopheader#1#2#3{% +\dosubind {fn}{\code{#2}}{\putwordon\ #1}% Make entry in function index +\begingroup\defname {#2}{\defoptype\ \putwordon\ #1}% +\defunargs {#3}\endgroup % +} + +% @deftypeop CATEGORY CLASS TYPE OPERATION ARG... +% +\def\deftypeop #1 {\def\deftypeopcategory{#1}% + \deftypeopparsebody\Edeftypeop\deftypeopx\deftypeopheader + \deftypeopcategory} +% +% #1 is the class name, #2 the data type, #3 the operation name, #4 the args. +\def\deftypeopheader#1#2#3#4{% + \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index + \begingroup + \defname{\defheaderxcond#2\relax$$$#3} + {\deftypeopcategory\ \putwordon\ \code{#1}}% + \deftypefunargs{#4}% + \endgroup +} + +% @deftypemethod CLASS TYPE METHOD ARG... +% +\def\deftypemethod{% + \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} +% +% #1 is the class name, #2 the data type, #3 the method name, #4 the args. +\def\deftypemethodheader#1#2#3#4{% + \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index + \begingroup + \defname{\defheaderxcond#2\relax$$$#3}{\putwordMethodon\ \code{#1}}% + \deftypefunargs{#4}% + \endgroup +} + +% @deftypeivar CLASS TYPE VARNAME +% +\def\deftypeivar{% + \deftypemethparsebody\Edeftypeivar\deftypeivarx\deftypeivarheader} +% +% #1 is the class name, #2 the data type, #3 the variable name. +\def\deftypeivarheader#1#2#3{% + \dosubind{vr}{\code{#3}}{\putwordof\ \code{#1}}% entry in variable index + \begingroup + \defname{\defheaderxcond#2\relax$$$#3} + {\putwordInstanceVariableof\ \code{#1}}% + \defvarargs{#3}% + \endgroup +} + +% @defmethod == @defop Method +% +\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} +% +% #1 is the class name, #2 the method name, #3 the args. +\def\defmethodheader#1#2#3{% + \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index + \begingroup + \defname{#2}{\putwordMethodon\ \code{#1}}% + \defunargs{#3}% + \endgroup +} + +% @defcv {Class Option} foo-class foo-flag + +\def\defcv #1 {\def\defcvtype{#1}% +\defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} + +\def\defcvarheader #1#2#3{% +\dosubind {vr}{\code{#2}}{\putwordof\ #1}% Make entry in var index +\begingroup\defname {#2}{\defcvtype\ \putwordof\ #1}% +\defvarargs {#3}\endgroup % +} + +% @defivar CLASS VARNAME == @defcv {Instance Variable} CLASS VARNAME +% +\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} +% +\def\defivarheader#1#2#3{% + \dosubind {vr}{\code{#2}}{\putwordof\ #1}% entry in var index + \begingroup + \defname{#2}{\putwordInstanceVariableof\ #1}% + \defvarargs{#3}% + \endgroup +} + +% @defvar +% First, define the processing that is wanted for arguments of @defvar. +% This is actually simple: just print them in roman. +% This must expand the args and terminate the paragraph they make up +\def\defvarargs #1{\normalparens #1% +\interlinepenalty=10000 +\endgraf\nobreak\vskip -\parskip\nobreak} + +% @defvr Counter foo-count + +\def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} + +\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% +\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} + +% @defvar == @defvr Variable + +\def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} + +\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index +\begingroup\defname {#1}{\putwordDefvar}% +\defvarargs {#2}\endgroup % +} + +% @defopt == @defvr {User Option} + +\def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} + +\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index +\begingroup\defname {#1}{\putwordDefopt}% +\defvarargs {#2}\endgroup % +} + +% @deftypevar int foobar + +\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} + +% #1 is the data type. #2 is the name, perhaps followed by text that +% is actually part of the data type, which should not be put into the index. +\def\deftypevarheader #1#2{% +\dovarind#2 \relax% Make entry in variables index +\begingroup\defname {\defheaderxcond#1\relax$$$#2}{\putwordDeftypevar}% +\interlinepenalty=10000 +\endgraf\nobreak\vskip -\parskip\nobreak +\endgroup} +\def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} + +% @deftypevr {Global Flag} int enable + +\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} + +\def\deftypevrheader #1#2#3{\dovarind#3 \relax% +\begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1} +\interlinepenalty=10000 +\endgraf\nobreak\vskip -\parskip\nobreak +\endgroup} + +% Now define @deftp +% Args are printed in bold, a slight difference from @defvar. + +\def\deftpargs #1{\bf \defvarargs{#1}} + +% @deftp Class window height width ... + +\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} + +\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% +\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} + +% These definitions are used if you use @defunx (etc.) +% anywhere other than immediately after a @defun or @defunx. +% +\def\defcvx#1 {\errmessage{@defcvx in invalid context}} +\def\deffnx#1 {\errmessage{@deffnx in invalid context}} +\def\defivarx#1 {\errmessage{@defivarx in invalid context}} +\def\defmacx#1 {\errmessage{@defmacx in invalid context}} +\def\defmethodx#1 {\errmessage{@defmethodx in invalid context}} +\def\defoptx #1 {\errmessage{@defoptx in invalid context}} +\def\defopx#1 {\errmessage{@defopx in invalid context}} +\def\defspecx#1 {\errmessage{@defspecx in invalid context}} +\def\deftpx#1 {\errmessage{@deftpx in invalid context}} +\def\deftypefnx#1 {\errmessage{@deftypefnx in invalid context}} +\def\deftypefunx#1 {\errmessage{@deftypefunx in invalid context}} +\def\deftypeivarx#1 {\errmessage{@deftypeivarx in invalid context}} +\def\deftypemethodx#1 {\errmessage{@deftypemethodx in invalid context}} +\def\deftypeopx#1 {\errmessage{@deftypeopx in invalid context}} +\def\deftypevarx#1 {\errmessage{@deftypevarx in invalid context}} +\def\deftypevrx#1 {\errmessage{@deftypevrx in invalid context}} +\def\defunx#1 {\errmessage{@defunx in invalid context}} +\def\defvarx#1 {\errmessage{@defvarx in invalid context}} +\def\defvrx#1 {\errmessage{@defvrx in invalid context}} + + +\message{macros,} +% @macro. + +% To do this right we need a feature of e-TeX, \scantokens, +% which we arrange to emulate with a temporary file in ordinary TeX. +\ifx\eTeXversion\undefined + \newwrite\macscribble + \def\scanmacro#1{% + \begingroup \newlinechar`\^^M + % Undo catcode changes of \startcontents and \doprintindex + \catcode`\@=0 \catcode`\\=12 \escapechar=`\@ + % Append \endinput to make sure that TeX does not see the ending newline. + \toks0={#1\endinput}% + \immediate\openout\macscribble=\jobname.tmp + \immediate\write\macscribble{\the\toks0}% + \immediate\closeout\macscribble + \let\xeatspaces\eatspaces + \input \jobname.tmp + \endgroup +} +\else +\def\scanmacro#1{% +\begingroup \newlinechar`\^^M +% Undo catcode changes of \startcontents and \doprintindex +\catcode`\@=0 \catcode`\\=12 \escapechar=`\@ +\let\xeatspaces\eatspaces\scantokens{#1\endinput}\endgroup} +\fi + +\newcount\paramno % Count of parameters +\newtoks\macname % Macro name +\newif\ifrecursive % Is it recursive? +\def\macrolist{} % List of all defined macros in the form + % \do\macro1\do\macro2... + +% Utility routines. +% Thisdoes \let #1 = #2, except with \csnames. +\def\cslet#1#2{% +\expandafter\expandafter +\expandafter\let +\expandafter\expandafter +\csname#1\endcsname +\csname#2\endcsname} + +% Trim leading and trailing spaces off a string. +% Concepts from aro-bend problem 15 (see CTAN). +{\catcode`\@=11 +\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} +\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} +\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} +\def\unbrace#1{#1} +\unbrace{\gdef\trim@@@ #1 } #2@{#1} +} + +% Trim a single trailing ^^M off a string. +{\catcode`\^^M=12\catcode`\Q=3% +\gdef\eatcr #1{\eatcra #1Q^^MQ}% +\gdef\eatcra#1^^MQ{\eatcrb#1Q}% +\gdef\eatcrb#1Q#2Q{#1}% +} + +% Macro bodies are absorbed as an argument in a context where +% all characters are catcode 10, 11 or 12, except \ which is active +% (as in normal texinfo). It is necessary to change the definition of \. + +% It's necessary to have hard CRs when the macro is executed. This is +% done by making ^^M (\endlinechar) catcode 12 when reading the macro +% body, and then making it the \newlinechar in \scanmacro. + +\def\macrobodyctxt{% + \catcode`\~=12 + \catcode`\^=12 + \catcode`\_=12 + \catcode`\|=12 + \catcode`\<=12 + \catcode`\>=12 + \catcode`\+=12 + \catcode`\{=12 + \catcode`\}=12 + \catcode`\@=12 + \catcode`\^^M=12 + \usembodybackslash} + +\def\macroargctxt{% + \catcode`\~=12 + \catcode`\^=12 + \catcode`\_=12 + \catcode`\|=12 + \catcode`\<=12 + \catcode`\>=12 + \catcode`\+=12 + \catcode`\@=12 + \catcode`\\=12} + +% \mbodybackslash is the definition of \ in @macro bodies. +% It maps \foo\ => \csname macarg.foo\endcsname => #N +% where N is the macro parameter number. +% We define \csname macarg.\endcsname to be \realbackslash, so +% \\ in macro replacement text gets you a backslash. + +{\catcode`@=0 @catcode`@\=@active + @gdef@usembodybackslash{@let\=@mbodybackslash} + @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} +} +\expandafter\def\csname macarg.\endcsname{\realbackslash} + +\def\macro{\recursivefalse\parsearg\macroxxx} +\def\rmacro{\recursivetrue\parsearg\macroxxx} + +\def\macroxxx#1{% + \getargs{#1}% now \macname is the macname and \argl the arglist + \ifx\argl\empty % no arguments + \paramno=0% + \else + \expandafter\parsemargdef \argl;% + \fi + \if1\csname ismacro.\the\macname\endcsname + \message{Warning: redefining \the\macname}% + \else + \expandafter\ifx\csname \the\macname\endcsname \relax + \else \errmessage{The name \the\macname\space is reserved}\fi + \global\cslet{macsave.\the\macname}{\the\macname}% + \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% + % Add the macroname to \macrolist + \toks0 = \expandafter{\macrolist\do}% + \xdef\macrolist{\the\toks0 + \expandafter\noexpand\csname\the\macname\endcsname}% + \fi + \begingroup \macrobodyctxt + \ifrecursive \expandafter\parsermacbody + \else \expandafter\parsemacbody + \fi} + +\def\unmacro{\parsearg\unmacroxxx} +\def\unmacroxxx#1{% + \if1\csname ismacro.#1\endcsname + \global\cslet{#1}{macsave.#1}% + \global\expandafter\let \csname ismacro.#1\endcsname=0% + % Remove the macro name from \macrolist + \begingroup + \edef\tempa{\expandafter\noexpand\csname#1\endcsname}% + \def\do##1{% + \def\tempb{##1}% + \ifx\tempa\tempb + % remove this + \else + \toks0 = \expandafter{\newmacrolist\do}% + \edef\newmacrolist{\the\toks0\expandafter\noexpand\tempa}% + \fi}% + \def\newmacrolist{}% + % Execute macro list to define \newmacrolist + \macrolist + \global\let\macrolist\newmacrolist + \endgroup + \else + \errmessage{Macro #1 not defined}% + \fi +} + +% This makes use of the obscure feature that if the last token of a +% <parameter list> is #, then the preceding argument is delimited by +% an opening brace, and that opening brace is not consumed. +\def\getargs#1{\getargsxxx#1{}} +\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} +\def\getmacname #1 #2\relax{\macname={#1}} +\def\getmacargs#1{\def\argl{#1}} + +% Parse the optional {params} list. Set up \paramno and \paramlist +% so \defmacro knows what to do. Define \macarg.blah for each blah +% in the params list, to be ##N where N is the position in that list. +% That gets used by \mbodybackslash (above). + +% We need to get `macro parameter char #' into several definitions. +% The technique used is stolen from LaTeX: let \hash be something +% unexpandable, insert that wherever you need a #, and then redefine +% it to # just before using the token list produced. +% +% The same technique is used to protect \eatspaces till just before +% the macro is used. + +\def\parsemargdef#1;{\paramno=0\def\paramlist{}% + \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} +\def\parsemargdefxxx#1,{% + \if#1;\let\next=\relax + \else \let\next=\parsemargdefxxx + \advance\paramno by 1% + \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname + {\xeatspaces{\hash\the\paramno}}% + \edef\paramlist{\paramlist\hash\the\paramno,}% + \fi\next} + +% These two commands read recursive and nonrecursive macro bodies. +% (They're different since rec and nonrec macros end differently.) + +\long\def\parsemacbody#1@end macro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% +\long\def\parsermacbody#1@end rmacro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% + +% This defines the macro itself. There are six cases: recursive and +% nonrecursive macros of zero, one, and many arguments. +% Much magic with \expandafter here. +% \xdef is used so that macro definitions will survive the file +% they're defined in; @include reads the file inside a group. +\def\defmacro{% + \let\hash=##% convert placeholders to macro parameter chars + \ifrecursive + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\scanmacro{\temp}}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup\noexpand\scanmacro{\temp}}% + \else % many + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{\egroup\noexpand\scanmacro{\temp}}% + \fi + \else + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \else % many + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \expandafter\noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \fi + \fi} + +\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} + +% \braceorline decides whether the next nonwhitespace character is a +% {. If so it reads up to the closing }, if not, it reads the whole +% line. Whatever was read is then fed to the next control sequence +% as an argument (by \parsebrace or \parsearg) +\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx} +\def\braceorlinexxx{% + \ifx\nchar\bgroup\else + \expandafter\parsearg + \fi \next} + +% We mant to disable all macros during \shipout so that they are not +% expanded by \write. +\def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}% + \edef\next{\macrolist}\expandafter\endgroup\next} + + +% @alias. +% We need some trickery to remove the optional spaces around the equal +% sign. Just make them active and then expand them all to nothing. +\def\alias{\begingroup\obeyspaces\parsearg\aliasxxx} +\def\aliasxxx #1{\aliasyyy#1\relax} +\def\aliasyyy #1=#2\relax{\ignoreactivespaces +\edef\next{\global\let\expandafter\noexpand\csname#1\endcsname=% + \expandafter\noexpand\csname#2\endcsname}% +\expandafter\endgroup\next} + + +\message{cross references,} +% @xref etc. + +\newwrite\auxfile + +\newif\ifhavexrefs % True if xref values are known. +\newif\ifwarnedxrefs % True if we warned once that they aren't known. + +% @inforef is relatively simple. +\def\inforef #1{\inforefzzz #1,,,,**} +\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, + node \samp{\ignorespaces#1{}}} + +% @node's job is to define \lastnode. +\def\node{\ENVcheck\parsearg\nodezzz} +\def\nodezzz#1{\nodexxx [#1,]} +\def\nodexxx[#1,#2]{\gdef\lastnode{#1}} +\let\nwnode=\node +\let\lastnode=\relax + +% The sectioning commands (@chapter, etc.) call these. +\def\donoderef{% + \ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\setref{\lastnode}% + {Ysectionnumberandtype}% + \global\let\lastnode=\relax + \fi +} +\def\unnumbnoderef{% + \ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\setref{\lastnode}{Ynothing}% + \global\let\lastnode=\relax + \fi +} +\def\appendixnoderef{% + \ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\setref{\lastnode}% + {Yappendixletterandtype}% + \global\let\lastnode=\relax + \fi +} + + +% @anchor{NAME} -- define xref target at arbitrary point. +% +\newcount\savesfregister +\gdef\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} +\gdef\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} +\gdef\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} + +% \setref{NAME}{SNT} defines a cross-reference point NAME, namely +% NAME-title, NAME-pg, and NAME-SNT. Called from \foonoderef. We have +% to set \indexdummies so commands such as @code in a section title +% aren't expanded. It would be nicer not to expand the titles in the +% first place, but there's so many layers that that is hard to do. +% +\def\setref#1#2{{% + \indexdummies + \pdfmkdest{#1}% + \dosetq{#1-title}{Ytitle}% + \dosetq{#1-pg}{Ypagenumber}% + \dosetq{#1-snt}{#2}% +}} + +% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is +% the node name, #2 the name of the Info cross-reference, #3 the printed +% node name, #4 the name of the Info file, #5 the name of the printed +% manual. All but the node name can be omitted. +% +\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} +\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} +\def\ref#1{\xrefX[#1,,,,,,,]} +\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup + \unsepspaces + \def\printedmanual{\ignorespaces #5}% + \def\printednodename{\ignorespaces #3}% + \setbox1=\hbox{\printedmanual}% + \setbox0=\hbox{\printednodename}% + \ifdim \wd0 = 0pt + % No printed node name was explicitly given. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax + % Use the node name inside the square brackets. + \def\printednodename{\ignorespaces #1}% + \else + % Use the actual chapter/section title appear inside + % the square brackets. Use the real section title if we have it. + \ifdim \wd1 > 0pt + % It is in another manual, so we don't have it. + \def\printednodename{\ignorespaces #1}% + \else + \ifhavexrefs + % We know the real title if we have the xref values. + \def\printednodename{\refx{#1-title}{}}% + \else + % Otherwise just copy the Info node name. + \def\printednodename{\ignorespaces #1}% + \fi% + \fi + \fi + \fi + % + % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not + % insert empty discretionaries after hyphens, which means that it will + % not find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, this + % is a loss. Therefore, we give the text of the node name again, so it + % is as if TeX is seeing it for the first time. + \ifpdf + \leavevmode + \getfilename{#4}% + \ifnum\filenamelength>0 + \startlink attr{/Border [0 0 0]}% + goto file{\the\filename.pdf} name{#1@}% + \else + \startlink attr{/Border [0 0 0]}% + goto name{#1@}% + \fi + \linkcolor + \fi + % + \ifdim \wd1 > 0pt + \putwordsection{} ``\printednodename'' \putwordin{} \cite{\printedmanual}% + \else + % _ (for example) has to be the character _ for the purposes of the + % control sequence corresponding to the node, but it has to expand + % into the usual \leavevmode...\vrule stuff for purposes of + % printing. So we \turnoffactive for the \refx-snt, back on for the + % printing, back off for the \refx-pg. + {\normalturnoffactive + % Only output a following space if the -snt ref is nonempty; for + % @unnumbered and @anchor, it won't be. + \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% + \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi + }% + % [mynode], + [\printednodename],\space + % page 3 + \turnoffactive \putwordpage\tie\refx{#1-pg}{}% + \fi + \endlink +\endgroup} + +% \dosetq is the interface for calls from other macros + +% Use \normalturnoffactive so that punctuation chars such as underscore +% and backslash work in node names. (\turnoffactive doesn't do \.) +\def\dosetq#1#2{% + {\let\folio=0% + \normalturnoffactive + \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}% + \iflinks + \next + \fi + }% +} + +% \internalsetq {foo}{page} expands into +% CHARACTERS 'xrdef {foo}{...expansion of \Ypage...} +% When the aux file is read, ' is the escape character + +\def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}} + +% Things to be expanded by \internalsetq + +\def\Ypagenumber{\folio} + +\def\Ytitle{\thissection} + +\def\Ynothing{} + +\def\Ysectionnumberandtype{% +\ifnum\secno=0 \putwordChapter\xreftie\the\chapno % +\else \ifnum \subsecno=0 \putwordSection\xreftie\the\chapno.\the\secno % +\else \ifnum \subsubsecno=0 % +\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno % +\else % +\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno % +\fi \fi \fi } + +\def\Yappendixletterandtype{% +\ifnum\secno=0 \putwordAppendix\xreftie'char\the\appendixno{}% +\else \ifnum \subsecno=0 \putwordSection\xreftie'char\the\appendixno.\the\secno % +\else \ifnum \subsubsecno=0 % +\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno % +\else % +\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % +\fi \fi \fi } + +\gdef\xreftie{'tie} + +% Use TeX 3.0's \inputlineno to get the line number, for better error +% messages, but if we're using an old version of TeX, don't do anything. +% +\ifx\inputlineno\thisisundefined + \let\linenumber = \empty % Non-3.0. +\else + \def\linenumber{\the\inputlineno:\space} +\fi + +% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. +% If its value is nonempty, SUFFIX is output afterward. + +\def\refx#1#2{% + \expandafter\ifx\csname X#1\endcsname\relax + % If not defined, say something at least. + \angleleft un\-de\-fined\angleright + \iflinks + \ifhavexrefs + \message{\linenumber Undefined cross reference `#1'.}% + \else + \ifwarnedxrefs\else + \global\warnedxrefstrue + \message{Cross reference values unknown; you must run TeX again.}% + \fi + \fi + \fi + \else + % It's defined, so just use it. + \csname X#1\endcsname + \fi + #2% Output the suffix in any case. +} + +% This is the macro invoked by entries in the aux file. +% +\def\xrdef#1{\begingroup + % Reenable \ as an escape while reading the second argument. + \catcode`\\ = 0 + \afterassignment\endgroup + \expandafter\gdef\csname X#1\endcsname +} + +% Read the last existing aux file, if any. No error if none exists. +\def\readauxfile{\begingroup + \catcode`\^^@=\other + \catcode`\^^A=\other + \catcode`\^^B=\other + \catcode`\^^C=\other + \catcode`\^^D=\other + \catcode`\^^E=\other + \catcode`\^^F=\other + \catcode`\^^G=\other + \catcode`\^^H=\other + \catcode`\^^K=\other + \catcode`\^^L=\other + \catcode`\^^N=\other + \catcode`\^^P=\other + \catcode`\^^Q=\other + \catcode`\^^R=\other + \catcode`\^^S=\other + \catcode`\^^T=\other + \catcode`\^^U=\other + \catcode`\^^V=\other + \catcode`\^^W=\other + \catcode`\^^X=\other + \catcode`\^^Z=\other + \catcode`\^^[=\other + \catcode`\^^\=\other + \catcode`\^^]=\other + \catcode`\^^^=\other + \catcode`\^^_=\other + \catcode`\@=\other + \catcode`\^=\other + % It was suggested to define this as 7, which would allow ^^e4 etc. + % in xref tags, i.e., node names. But since ^^e4 notation isn't + % supported in the main text, it doesn't seem desirable. Furthermore, + % that is not enough: for node names that actually contain a ^ + % character, we would end up writing a line like this: 'xrdef {'hat + % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first + % argument, and \hat is not an expandable control sequence. It could + % all be worked out, but why? Either we support ^^ or we don't. + % + % The other change necessary for this was to define \auxhat: + % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter + % and then to call \auxhat in \setq. + % + \catcode`\~=\other + \catcode`\[=\other + \catcode`\]=\other + \catcode`\"=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\$=\other + \catcode`\#=\other + \catcode`\&=\other + \catcode`+=\other % avoid \+ for paranoia even though we've turned it off + % Make the characters 128-255 be printing characters + {% + \count 1=128 + \def\loop{% + \catcode\count 1=\other + \advance\count 1 by 1 + \ifnum \count 1<256 \loop \fi + }% + }% + % The aux file uses ' as the escape (for now). + % Turn off \ as an escape so we do not lose on + % entries which were dumped with control sequences in their names. + % For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^ + % Reference to such entries still does not work the way one would wish, + % but at least they do not bomb out when the aux file is read in. + \catcode`\{=1 + \catcode`\}=2 + \catcode`\%=\other + \catcode`\'=0 + \catcode`\\=\other + % + \openin 1 \jobname.aux + \ifeof 1 \else + \closein 1 + \input \jobname.aux + \global\havexrefstrue + \global\warnedobstrue + \fi + % Open the new aux file. TeX will close it automatically at exit. + \openout\auxfile=\jobname.aux +\endgroup} + + +% Footnotes. + +\newcount \footnoteno + +% The trailing space in the following definition for supereject is +% vital for proper filling; pages come out unaligned when you do a +% pagealignmacro call if that space before the closing brace is +% removed. (Generally, numeric constants should always be followed by a +% space to prevent strange expansion errors.) +\def\supereject{\par\penalty -20000\footnoteno =0 } + +% @footnotestyle is meaningful for info output only. +\let\footnotestyle=\comment + +\let\ptexfootnote=\footnote + +{\catcode `\@=11 +% +% Auto-number footnotes. Otherwise like plain. +\gdef\footnote{% + \global\advance\footnoteno by \@ne + \edef\thisfootno{$^{\the\footnoteno}$}% + % + % In case the footnote comes at the end of a sentence, preserve the + % extra spacing after we do the footnote number. + \let\@sf\empty + \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi + % + % Remove inadvertent blank space before typesetting the footnote number. + \unskip + \thisfootno\@sf + \footnotezzz +}% + +% Don't bother with the trickery in plain.tex to not require the +% footnote text as a parameter. Our footnotes don't need to be so general. +% +% Oh yes, they do; otherwise, @ifset and anything else that uses +% \parseargline fail inside footnotes because the tokens are fixed when +% the footnote is read. --karl, 16nov96. +% +\long\gdef\footnotezzz{\insert\footins\bgroup + % We want to typeset this text as a normal paragraph, even if the + % footnote reference occurs in (for example) a display environment. + % So reset some parameters. + \interlinepenalty\interfootnotelinepenalty + \splittopskip\ht\strutbox % top baseline for broken footnotes + \splitmaxdepth\dp\strutbox + \floatingpenalty\@MM + \leftskip\z@skip + \rightskip\z@skip + \spaceskip\z@skip + \xspaceskip\z@skip + \parindent\defaultparindent + % + \smallfonts \rm + % + % Hang the footnote text off the number. + \hang + \textindent{\thisfootno}% + % + % Don't crash into the line above the footnote text. Since this + % expands into a box, it must come within the paragraph, lest it + % provide a place where TeX can split the footnote. + \footstrut + \futurelet\next\fo@t +} +\def\fo@t{\ifcat\bgroup\noexpand\next \let\next\f@@t + \else\let\next\f@t\fi \next} +\def\f@@t{\bgroup\aftergroup\@foot\let\next} +\def\f@t#1{#1\@foot} +\def\@foot{\strut\par\egroup} + +}%end \catcode `\@=11 + +% Set the baselineskip to #1, and the lineskip and strut size +% correspondingly. There is no deep meaning behind these magic numbers +% used as factors; they just match (closely enough) what Knuth defined. +% +\def\lineskipfactor{.08333} +\def\strutheightpercent{.70833} +\def\strutdepthpercent {.29167} +% +\def\setleading#1{% + \normalbaselineskip = #1\relax + \normallineskip = \lineskipfactor\normalbaselineskip + \normalbaselines + \setbox\strutbox =\hbox{% + \vrule width0pt height\strutheightpercent\baselineskip + depth \strutdepthpercent \baselineskip + }% +} + +% @| inserts a changebar to the left of the current line. It should +% surround any changed text. This approach does *not* work if the +% change spans more than two lines of output. To handle that, we would +% have adopt a much more difficult approach (putting marks into the main +% vertical list for the beginning and end of each change). +% +\def\|{% + % \vadjust can only be used in horizontal mode. + \leavevmode + % + % Append this vertical mode material after the current line in the output. + \vadjust{% + % We want to insert a rule with the height and depth of the current + % leading; that is exactly what \strutbox is supposed to record. + \vskip-\baselineskip + % + % \vadjust-items are inserted at the left edge of the type. So + % the \llap here moves out into the left-hand margin. + \llap{% + % + % For a thicker or thinner bar, change the `1pt'. + \vrule height\baselineskip width1pt + % + % This is the space between the bar and the text. + \hskip 12pt + }% + }% +} + +% For a final copy, take out the rectangles +% that mark overfull boxes (in case you have decided +% that the text looks ok even though it passes the margin). +% +\def\finalout{\overfullrule=0pt} + +% @image. We use the macros from epsf.tex to support this. +% If epsf.tex is not installed and @image is used, we complain. +% +% Check for and read epsf.tex up front. If we read it only at @image +% time, we might be inside a group, and then its definitions would get +% undone and the next image would fail. +\openin 1 = epsf.tex +\ifeof 1 \else + \closein 1 + % Do not bother showing banner with post-v2.7 epsf.tex (available in + % doc/epsf.tex until it shows up on ctan). + \def\epsfannounce{\toks0 = }% + \input epsf.tex +\fi +% +% We will only complain once about lack of epsf.tex. +\newif\ifwarnednoepsf +\newhelp\noepsfhelp{epsf.tex must be installed for images to + work. It is also included in the Texinfo distribution, or you can get + it from ftp://tug.org/tex/epsf.tex.} +% +\def\image#1{% + \ifx\epsfbox\undefined + \ifwarnednoepsf \else + \errhelp = \noepsfhelp + \errmessage{epsf.tex not found, images will be ignored}% + \global\warnednoepsftrue + \fi + \else + \imagexxx #1,,,\finish + \fi +} +% +% Arguments to @image: +% #1 is (mandatory) image filename; we tack on .eps extension. +% #2 is (optional) width, #3 is (optional) height. +% #4 is just the usual extra ignored arg for parsing this stuff. +\def\imagexxx#1,#2,#3,#4\finish{% + \ifpdf + \centerline{\dopdfimage{#1}{#2}{#3}}% + \else + % \epsfbox itself resets \epsf?size at each figure. + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi + \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi + \begingroup + \catcode`\^^M = 5 % in case we're inside an example + % If the image is by itself, center it. + \ifvmode + \nobreak\bigskip + % Usually we'll have text after the image which will insert + % \parskip glue, so insert it here too to equalize the space + % above and below. + \nobreak\vskip\parskip + \nobreak + \centerline{\epsfbox{#1.eps}}% + \bigbreak + \else + % In the middle of a paragraph, no extra space. + \epsfbox{#1.eps}% + \fi + \endgroup + \fi +} + + +\message{localization,} +% and i18n. + +% @documentlanguage is usually given very early, just after +% @setfilename. If done too late, it may not override everything +% properly. Single argument is the language abbreviation. +% It would be nice if we could set up a hyphenation file here. +% +\def\documentlanguage{\parsearg\dodocumentlanguage} +\def\dodocumentlanguage#1{% + \tex % read txi-??.tex file in plain TeX. + % Read the file if it exists. + \openin 1 txi-#1.tex + \ifeof1 + \errhelp = \nolanghelp + \errmessage{Cannot read language file txi-#1.tex}% + \let\temp = \relax + \else + \def\temp{\input txi-#1.tex }% + \fi + \temp + \endgroup +} +\newhelp\nolanghelp{The given language definition file cannot be found or +is empty. Maybe you need to install it? In the current directory +should work if nowhere else does.} + + +% @documentencoding should change something in TeX eventually, most +% likely, but for now just recognize it. +\let\documentencoding = \comment + + +% Page size parameters. +% +\newdimen\defaultparindent \defaultparindent = 15pt + +\chapheadingskip = 15pt plus 4pt minus 2pt +\secheadingskip = 12pt plus 3pt minus 2pt +\subsecheadingskip = 9pt plus 2pt minus 2pt + +% Prevent underfull vbox error messages. +\vbadness = 10000 + +% Don't be so finicky about underfull hboxes, either. +\hbadness = 2000 + +% Following George Bush, just get rid of widows and orphans. +\widowpenalty=10000 +\clubpenalty=10000 + +% Use TeX 3.0's \emergencystretch to help line breaking, but if we're +% using an old version of TeX, don't do anything. We want the amount of +% stretch added to depend on the line length, hence the dependence on +% \hsize. We call this whenever the paper size is set. +% +\def\setemergencystretch{% + \ifx\emergencystretch\thisisundefined + % Allow us to assign to \emergencystretch anyway. + \def\emergencystretch{\dimen0}% + \else + \emergencystretch = .15\hsize + \fi +} + +% Parameters in order: 1) textheight; 2) textwidth; 3) voffset; +% 4) hoffset; 5) binding offset; 6) topskip. Then whoever calls us can +% set \parskip and call \setleading for \baselineskip. +% +\def\internalpagesizes#1#2#3#4#5#6{% + \voffset = #3\relax + \topskip = #6\relax + \splittopskip = \topskip + % + \vsize = #1\relax + \advance\vsize by \topskip + \outervsize = \vsize + \advance\outervsize by 2\topandbottommargin + \pageheight = \vsize + % + \hsize = #2\relax + \outerhsize = \hsize + \advance\outerhsize by 0.5in + \pagewidth = \hsize + % + \normaloffset = #4\relax + \bindingoffset = #5\relax + % + \parindent = \defaultparindent + \setemergencystretch +} + +% @letterpaper (the default). +\def\letterpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \setleading{13.2pt}% + % + % If page is nothing but text, make it come out even. + \internalpagesizes{46\baselineskip}{6in}{\voffset}{.25in}{\bindingoffset}{36pt}% +}} + +% Use @smallbook to reset parameters for 7x9.5 (or so) format. +\def\smallbook{{\globaldefs = 1 + \parskip = 2pt plus 1pt + \setleading{12pt}% + % + \internalpagesizes{7.5in}{5.in}{\voffset}{.25in}{\bindingoffset}{16pt}% + % + \lispnarrowing = 0.3in + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \deftypemargin = 0pt + \defbodyindent = .5cm + % + \let\smalldisplay = \smalldisplayx + \let\smallexample = \smalllispx + \let\smallformat = \smallformatx + \let\smalllisp = \smalllispx +}} + +% Use @afourpaper to print on European A4 paper. +\def\afourpaper{{\globaldefs = 1 + \setleading{12pt}% + \parskip = 3pt plus 2pt minus 1pt + % + \internalpagesizes{53\baselineskip}{160mm}{\voffset}{4mm}{\bindingoffset}{44pt}% + % + \tolerance = 700 + \hfuzz = 1pt +}} + +% A specific text layout, 24x15cm overall, intended for A4 paper. Top margin +% 29mm, hence bottom margin 28mm, nominal side margin 3cm. +\def\afourlatex{{\globaldefs = 1 + \setleading{13.6pt}% + % + \afourpaper + \internalpagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm}% + % + \globaldefs = 0 +}} + +% Use @afourwide to print on European A4 paper in wide format. +\def\afourwide{% + \afourpaper + \internalpagesizes{6.5in}{9.5in}{\hoffset}{\normaloffset}{\bindingoffset}{7mm}% + % + \globaldefs = 0 +} + +% @pagesizes TEXTHEIGHT[,TEXTWIDTH] +% Perhaps we should allow setting the margins, \topskip, \parskip, +% and/or leading, also. Or perhaps we should compute them somehow. +% +\def\pagesizes{\parsearg\pagesizesxxx} +\def\pagesizesxxx#1{\pagesizesyyy #1,,\finish} +\def\pagesizesyyy#1,#2,#3\finish{{% + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi + \globaldefs = 1 + % + \parskip = 3pt plus 2pt minus 1pt + \setleading{13.2pt}% + % + \internalpagesizes{#1}{\hsize}{\voffset}{\normaloffset}{\bindingoffset}{44pt}% +}} + +% Set default to letter. +% +\letterpaper + + +\message{and turning on texinfo input format.} + +% Define macros to output various characters with catcode for normal text. +\catcode`\"=\other +\catcode`\~=\other +\catcode`\^=\other +\catcode`\_=\other +\catcode`\|=\other +\catcode`\<=\other +\catcode`\>=\other +\catcode`\+=\other +\catcode`\$=\other +\def\normaldoublequote{"} +\def\normaltilde{~} +\def\normalcaret{^} +\def\normalunderscore{_} +\def\normalverticalbar{|} +\def\normalless{<} +\def\normalgreater{>} +\def\normalplus{+} +\def\normaldollar{$} + +% This macro is used to make a character print one way in ttfont +% where it can probably just be output, and another way in other fonts, +% where something hairier probably needs to be done. +% +% #1 is what to print if we are indeed using \tt; #2 is what to print +% otherwise. Since all the Computer Modern typewriter fonts have zero +% interword stretch (and shrink), and it is reasonable to expect all +% typewriter fonts to have this, we can check that font parameter. +% +\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} + +% Same as above, but check for italic font. Actually this also catches +% non-italic slanted fonts since it is impossible to distinguish them from +% italic fonts. But since this is only used by $ and it uses \sl anyway +% this is not a problem. +\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} + +% Turn off all special characters except @ +% (and those which the user can use as if they were ordinary). +% Most of these we simply print from the \tt font, but for some, we can +% use math or other variants that look better in normal text. + +\catcode`\"=\active +\def\activedoublequote{{\tt\char34}} +\let"=\activedoublequote +\catcode`\~=\active +\def~{{\tt\char126}} +\chardef\hat=`\^ +\catcode`\^=\active +\def^{{\tt \hat}} + +\catcode`\_=\active +\def_{\ifusingtt\normalunderscore\_} +% Subroutine for the previous macro. +\def\_{\leavevmode \kern.06em \vbox{\hrule width.3em height.1ex}} + +\catcode`\|=\active +\def|{{\tt\char124}} +\chardef \less=`\< +\catcode`\<=\active +\def<{{\tt \less}} +\chardef \gtr=`\> +\catcode`\>=\active +\def>{{\tt \gtr}} +\catcode`\+=\active +\def+{{\tt \char 43}} +\catcode`\$=\active +\def${\ifusingit{{\sl\$}}\normaldollar} +%\catcode 27=\active +%\def^^[{$\diamondsuit$} + +% Set up an active definition for =, but don't enable it most of the time. +{\catcode`\==\active +\global\def={{\tt \char 61}}} + +\catcode`+=\active +\catcode`\_=\active + +% If a .fmt file is being used, characters that might appear in a file +% name cannot be active until we have parsed the command line. +% So turn them off again, and have \everyjob (or @setfilename) turn them on. +% \otherifyactive is called near the end of this file. +\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} + +\catcode`\@=0 + +% \rawbackslashxx output one backslash character in current font +\global\chardef\rawbackslashxx=`\\ +%{\catcode`\\=\other +%@gdef@rawbackslashxx{\}} + +% \rawbackslash redefines \ as input to do \rawbackslashxx. +{\catcode`\\=\active +@gdef@rawbackslash{@let\=@rawbackslashxx }} + +% \normalbackslash outputs one backslash in fixed width font. +\def\normalbackslash{{\tt\rawbackslashxx}} + +% \catcode 17=0 % Define control-q +\catcode`\\=\active + +% Used sometimes to turn off (effectively) the active characters +% even after parsing them. +@def@turnoffactive{@let"=@normaldoublequote +@let\=@realbackslash +@let~=@normaltilde +@let^=@normalcaret +@let_=@normalunderscore +@let|=@normalverticalbar +@let<=@normalless +@let>=@normalgreater +@let+=@normalplus +@let$=@normaldollar} + +@def@normalturnoffactive{@let"=@normaldoublequote +@let\=@normalbackslash +@let~=@normaltilde +@let^=@normalcaret +@let_=@normalunderscore +@let|=@normalverticalbar +@let<=@normalless +@let>=@normalgreater +@let+=@normalplus +@let$=@normaldollar} + +% Make _ and + \other characters, temporarily. +% This is canceled by @fixbackslash. +@otherifyactive + +% If a .fmt file is being used, we don't want the `\input texinfo' to show up. +% That is what \eatinput is for; after that, the `\' should revert to printing +% a backslash. +% +@gdef@eatinput input texinfo{@fixbackslash} +@global@let\ = @eatinput + +% On the other hand, perhaps the file did not have a `\input texinfo'. Then +% the first `\{ in the file would cause an error. This macro tries to fix +% that, assuming it is called before the first `\' could plausibly occur. +% Also back turn on active characters that might appear in the input +% file name, in case not using a pre-dumped format. +% +@gdef@fixbackslash{% + @ifx\@eatinput @let\ = @normalbackslash @fi + @catcode`+=@active + @catcode`@_=@active +} + +% Say @foo, not \foo, in error messages. +@escapechar = `@@ + +% These look ok in all fonts, so just make them not special. +@catcode`@& = @other +@catcode`@# = @other +@catcode`@% = @other + +@c Set initial fonts. +@textfonts +@rm + + +@c Local variables: +@c eval: (add-hook 'write-file-hooks 'time-stamp) +@c page-delimiter: "^\\\\message" +@c time-stamp-start: "def\\\\texinfoversion{" +@c time-stamp-format: "%:y-%02m-%02d.%02H" +@c time-stamp-end: "}" +@c End: diff --git a/contrib/gperf/lib/Makefile.in b/contrib/gperf/lib/Makefile.in new file mode 100644 index 0000000..3b1ee9d --- /dev/null +++ b/contrib/gperf/lib/Makefile.in @@ -0,0 +1,109 @@ +# Makefile for gperf/lib + +# Copyright (C) 1989, 1992, 1993, 1998 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. + +#### Start of system configuration section. #### + +# Directories used by "make": +srcdir = @srcdir@ + +# Directories used by "make install": +prefix = @prefix@ +local_prefix = /usr/local +exec_prefix = @exec_prefix@ + +# Programs used by "make": +# C compiler +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +# C++ compiler +CXX = @CXX@ +CXXFLAGS = @CXXFLAGS@ +CXXCPP = @CXXCPP@ +# Other +AR = ar +AR_FLAGS = rc +RANLIB = @RANLIB@ +MV = mv +LN = ln +RM = rm -f +@SET_MAKE@ + +# Programs used by "make install": +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +#### End of system configuration section. #### + +SHELL = /bin/sh + +VPATH = $(srcdir) + +OBJECTS = getopt.o getopt1.o hash.o +CPPFLAGS = -I$(srcdir) + +TARGETLIB = libgp.a + +all : $(TARGETLIB) + +$(TARGETLIB): $(OBJECTS) + $(RM) $@ + $(AR) $(AR_FLAGS) $@ $(OBJECTS) + $(RANLIB) $@ + +# Don't use implicit rules, since AIX "make" and OSF/1 "make" don't always +# expand $< correctly in this context. +# +#%.o : %.c +# $(CC) $(CFLAGS) $(CPPFLAGS) -c $< +# +#%.o : %.cc +# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< + +getopt.o : getopt.c getopt.h + $(CC) $(CFLAGS) $(CPPFLAGS) -c $(srcdir)/getopt.c + +getopt1.o : getopt1.c getopt.h + $(CC) $(CFLAGS) $(CPPFLAGS) -c $(srcdir)/getopt1.c + +hash.o : hash.cc hash.h + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/hash.cc + +install : all + +installdirs : + +uninstall : + +check : all + +mostlyclean : clean + +clean : force + $(RM) *~ *.s *.o *.a $(TARGETLIB) core + +distclean : clean + $(RM) config.status config.log config.cache Makefile + +maintainer-clean : distclean + +force : diff --git a/contrib/gperf/lib/configure b/contrib/gperf/lib/configure new file mode 100755 index 0000000..80fa25b --- /dev/null +++ b/contrib/gperf/lib/configure @@ -0,0 +1,1391 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=hash.cc + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:526: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:555: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:585: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:636: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:668: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 679 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:684: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:710: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:715: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:724: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:743: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + + echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:775: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext <<EOF +#line 790 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:796: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext <<EOF +#line 807 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:813: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext <<EOF +#line 824 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:830: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + + for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:859: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CXX="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CXX="$ac_cv_prog_CXX" +if test -n "$CXX"; then + echo "$ac_t""$CXX" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$CXX" && break +done +test -n "$CXX" || CXX="gcc" + + +echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:891: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 + +ac_ext=C +# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cxx_cross + +cat > conftest.$ac_ext << EOF + +#line 902 "configure" +#include "confdefs.h" + +int main(){return(0);} +EOF +if { (eval echo configure:907: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cxx_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cxx_cross=no + else + ac_cv_prog_cxx_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cxx_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6 +if test $ac_cv_prog_cxx_works = no; then + { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:933: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6 +cross_compiling=$ac_cv_prog_cxx_cross + +echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 +echo "configure:938: checking whether we are using GNU C++" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.C <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:947: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gxx=yes +else + ac_cv_prog_gxx=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gxx" 1>&6 + +if test $ac_cv_prog_gxx = yes; then + GXX=yes +else + GXX= +fi + +ac_test_CXXFLAGS="${CXXFLAGS+set}" +ac_save_CXXFLAGS="$CXXFLAGS" +CXXFLAGS= +echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 +echo "configure:966: checking whether ${CXX-g++} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.cc +if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then + ac_cv_prog_cxx_g=yes +else + ac_cv_prog_cxx_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6 +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS="$ac_save_CXXFLAGS" +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi + + echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6 +echo "configure:998: checking how to run the C++ preprocessor" >&5 +if test -z "$CXXCPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_ext=C +# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cxx_cross + CXXCPP="${CXX-g++} -E" + cat > conftest.$ac_ext <<EOF +#line 1011 "configure" +#include "confdefs.h" +#include <stdlib.h> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1016: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CXXCPP=/lib/cpp +fi +rm -f conftest* + ac_cv_prog_CXXCPP="$CXXCPP" +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross +fi +fi +CXXCPP="$ac_cv_prog_CXXCPP" +echo "$ac_t""$CXXCPP" 1>&6 + + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1043: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB="true" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1081: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'cl_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + for ac_prog in ginstall installbsd scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + # OSF/1 installbsd also uses dspmsg, but is usable. + : + else + if test $ac_prog = installbsd && + grep src/bos $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX installbsd doesn't work without option "-g". + : + else + cl_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + fi + done + ;; + esac + done + IFS="$ac_save_ifs" + # As a last resort, use cp. + test -z "$cl_cv_path_install" && cl_cv_path_install="cp" + +fi + INSTALL="$cl_cv_path_install" +fi +echo "$ac_t""$INSTALL" 1>&6 +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='$(INSTALL)' +if test -z "$INSTALL_DATA"; then + case "$INSTALL" in + cp | */cp ) INSTALL_DATA='$(INSTALL)' ;; + * ) INSTALL_DATA='$(INSTALL) -m 644' ;; + esac +fi + + trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@CXX@%$CXX%g +s%@CXXCPP@%$CXXCPP%g +s%@RANLIB@%$RANLIB%g +s%@INSTALL@%$INSTALL%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_DATA@%$INSTALL_DATA%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <<EOF + +EOF +cat >> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/contrib/gperf/lib/configure.in b/contrib/gperf/lib/configure.in new file mode 100644 index 0000000..98266a1 --- /dev/null +++ b/contrib/gperf/lib/configure.in @@ -0,0 +1,43 @@ +dnl autoconf configuration for gperf/lib + +dnl Copyright (C) 1998 Free Software Foundation, Inc. +dnl written by Douglas C. Schmidt (schmidt@ics.uci.edu) +dnl +dnl This file is part of GNU GPERF. +dnl +dnl GNU GPERF is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 1, or (at your option) +dnl any later version. +dnl +dnl GNU GPERF is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU GPERF; see the file COPYING. If not, write to the +dnl Free Software Foundation, 59 Temple Place - Suite 330, Boston, +dnl MA 02111-1307, USA. + +AC_INIT(hash.cc) +AC_PROG_MAKE_SET +dnl +dnl checks for programs +dnl +AC_PROG_CC + dnl sets variable CC +AC_PROG_CPP + dnl sets variable CPP +AC_PROG_CXX + dnl sets variable CXX +AC_PROG_CXXCPP + dnl sets variable CXXCPP +CL_PROG_RANLIB + dnl sets variable RANLIB +CL_PROG_INSTALL + dnl sets variables INSTALL, INSTALL_DATA, INSTALL_PROGRAM +dnl +dnl That's it. +dnl +AC_OUTPUT(Makefile) diff --git a/contrib/gperf/lib/hash.cc b/contrib/gperf/lib/hash.cc new file mode 100644 index 0000000..b5bb4ad --- /dev/null +++ b/contrib/gperf/lib/hash.cc @@ -0,0 +1,27 @@ +/* +Copyright (C) 1990, 2000 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) +*/ + +#include <hash.h> + +/* + Some useful hash function. + It's not a particularly good hash function (<< 5 would be better than << 4), + but people believe in it because it comes from Dragon book. +*/ + +unsigned int +hashpjw (const char *x, unsigned int len) // From Dragon book, p436 +{ + unsigned int h = 0; + unsigned int g; + + for (; len > 0; len--) + { + h = (h << 4) + (unsigned char) *x++; + if ((g = h & 0xf0000000) != 0) + h = (h ^ (g >> 24)) ^ g; + } + return h; +} diff --git a/contrib/gperf/lib/hash.h b/contrib/gperf/lib/hash.h new file mode 100644 index 0000000..5dbc92b --- /dev/null +++ b/contrib/gperf/lib/hash.h @@ -0,0 +1,15 @@ +// This may look like C code, but it is really -*- C++ -*- + +/* +Copyright (C) 1988, 1992, 2000 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) +*/ + +#ifndef _hash_h +#define _hash_h 1 + +/* a hash function for char[] arrays using the + method described in Aho, Sethi, & Ullman, p 436. */ +extern unsigned int hashpjw (const char *string, unsigned int len); + +#endif diff --git a/contrib/gperf/mkinstalldirs b/contrib/gperf/mkinstalldirs new file mode 100755 index 0000000..4f58503 --- /dev/null +++ b/contrib/gperf/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman <friedman@prep.ai.mit.edu> +# Created: 1993-05-16 +# Public domain + +# $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/contrib/gperf/src/Makefile.in b/contrib/gperf/src/Makefile.in new file mode 100644 index 0000000..60f73c7 --- /dev/null +++ b/contrib/gperf/src/Makefile.in @@ -0,0 +1,146 @@ +# Makefile for gperf/src + +# Copyright (C) 1989, 1992, 1993, 1998, 2000 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. + +#### Start of system configuration section. #### + +# Directories used by "make": +srcdir = @srcdir@ + +# Directories used by "make install": +prefix = @prefix@ +local_prefix = /usr/local +exec_prefix = @exec_prefix@ +bindir = @bindir@ + +# Programs used by "make": +# C compiler +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +# C++ compiler +CXX = @CXX@ +CXXFLAGS = @CXXFLAGS@ +CXXCPP = @CXXCPP@ +# Both C and C++ compiler +LDFLAGS = @LDFLAGS@ +# Other +MV = mv +LN = ln +RM = rm -f +@SET_MAKE@ + +# Programs used by "make install": +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +MKINSTALLDIRS = $(SHELL) $(srcdir)/../mkinstalldirs + +#### End of system configuration section. #### + +SHELL = /bin/sh + +VPATH = $(srcdir) + +OBJECTS = new.o options.o iterator.o main.o gen-perf.o key-list.o list-node.o \ + hash-table.o bool-array.o read-line.o trace.o vectors.o version.o +LIBS = ../lib/libgp.a -lm +CPPFLAGS = -I. -I$(srcdir)/../lib + +TARGETPROG = gperf + +all : $(TARGETPROG) + +$(TARGETPROG): $(OBJECTS) + $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBS) + +# Don't use implicit rules, since AIX "make" and OSF/1 "make" don't always +# expand $< correctly in this context. +# +#%.o : %.c +# $(CC) $(CFLAGS) $(CPPFLAGS) -c $< +# +#%.o : %.cc +# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< + +# Dependencies. +CONFIG_H = config.h +VERSION_H = version.h +VECTORS_H = vectors.h +TRACE_H = trace.h +READ_LINE_H = read-line.h read-line.icc $(TRACE_H) +OPTIONS_H = options.h options.icc $(TRACE_H) +LIST_NODE_H = list-node.h $(VECTORS_H) +KEY_LIST_H = key-list.h $(LIST_NODE_H) $(VECTORS_H) $(READ_LINE_H) +ITERATOR_H = iterator.h +HASH_TABLE_H = hash-table.h $(LIST_NODE_H) +BOOL_ARRAY_H = bool-array.h bool-array.icc $(TRACE_H) $(OPTIONS_H) +GEN_PERF_H = gen-perf.h $(KEY_LIST_H) $(BOOL_ARRAY_H) + +bool-array.o : bool-array.cc $(BOOL_ARRAY_H) $(OPTIONS_H) $(TRACE_H) + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/bool-array.cc +gen-perf.o : gen-perf.cc $(GEN_PERF_H) $(OPTIONS_H) $(TRACE_H) + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/gen-perf.cc +hash-table.o : hash-table.cc $(HASH_TABLE_H) $(OPTIONS_H) $(TRACE_H) + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/hash-table.cc +iterator.o : iterator.cc $(ITERATOR_H) $(TRACE_H) + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/iterator.cc +key-list.o : key-list.cc $(KEY_LIST_H) $(OPTIONS_H) $(READ_LINE_H) $(HASH_TABLE_H) $(TRACE_H) $(VERSION_H) + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/key-list.cc +list-node.o : list-node.cc $(LIST_NODE_H) $(OPTIONS_H) $(TRACE_H) + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/list-node.cc +main.o : main.cc $(OPTIONS_H) $(GEN_PERF_H) $(TRACE_H) $(CONFIG_H) + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/main.cc +new.o : new.cc $(TRACE_H) $(CONFIG_H) + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/new.cc +options.o : options.cc $(OPTIONS_H) $(ITERATOR_H) $(TRACE_H) $(VECTORS_H) $(VERSION_H) + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/options.cc +read-line.o : read-line.cc $(READ_LINE_H) $(OPTIONS_H) $(TRACE_H) + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/read-line.cc +trace.o : trace.cc $(TRACE_H) + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/trace.cc +vectors.o : vectors.cc $(VECTORS_H) + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/vectors.cc +version.o : version.cc $(VERSION_H) + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/version.cc + +install : all force + $(MKINSTALLDIRS) $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) $(TARGETPROG) $(DESTDIR)$(bindir)/$(TARGETPROG) + +installdirs : force + $(MKINSTALLDIRS) $(DESTDIR)$(bindir) + +uninstall : force + $(RM) $(DESTDIR)$(bindir)/$(TARGETPROG) + +check : all + +mostlyclean : clean + +clean : force + $(RM) *~ *.s *.o *.a $(TARGETPROG) core + +distclean : clean + $(RM) config.status config.log config.cache Makefile config.h + +maintainer-clean : distclean + +force : diff --git a/contrib/gperf/src/bool-array.cc b/contrib/gperf/src/bool-array.cc new file mode 100644 index 0000000..0774b2d --- /dev/null +++ b/contrib/gperf/src/bool-array.cc @@ -0,0 +1,49 @@ +/* Fast lookup table abstraction implemented as an Iteration Number Array + Copyright (C) 1989-1998 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "bool-array.h" + +#include <stdio.h> +#include <string.h> +#include "options.h" +#include "trace.h" + +STORAGE_TYPE * Bool_Array::storage_array; +STORAGE_TYPE Bool_Array::iteration_number; +unsigned int Bool_Array::size; + +/* Prints out debugging diagnostics. */ + +Bool_Array::~Bool_Array (void) +{ + T (Trace t ("Bool_Array::~Bool_Array");) + if (option[DEBUG]) + fprintf (stderr, "\ndumping boolean array information\n" + "size = %d\niteration number = %d\nend of array dump\n", + size, iteration_number); +} + +#ifndef __OPTIMIZE__ + +#define INLINE /* not inline */ +#include "bool-array.icc" +#undef INLINE + +#endif /* not defined __OPTIMIZE__ */ diff --git a/contrib/gperf/src/bool-array.h b/contrib/gperf/src/bool-array.h new file mode 100644 index 0000000..8330fcd --- /dev/null +++ b/contrib/gperf/src/bool-array.h @@ -0,0 +1,66 @@ +/* This may look like C code, but it is really -*- C++ -*- */ + +/* Simple lookup table abstraction implemented as an Iteration Number Array. + + Copyright (C) 1989-1998 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* Define and implement a simple boolean array abstraction, + uses an Iteration Numbering implementation to save on initialization time. */ + +#ifndef bool_array_h +#define bool_array_h 1 + +#include "trace.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 unsigned int STORAGE_TYPE; +#endif + +class Bool_Array +{ +private: + static STORAGE_TYPE *storage_array; /* Initialization of the index space. */ + static STORAGE_TYPE iteration_number; /* Keep track of the current iteration. */ + static unsigned int size; /* Keep track of array size. */ + +public: + Bool_Array (void); + ~Bool_Array (void); + static void init (STORAGE_TYPE *buffer, unsigned int s); + static int find (int hash_value); + static void reset (void); +}; + +#ifdef __OPTIMIZE__ /* efficiency hack! */ + +#include <stdio.h> +#include <string.h> +#include "options.h" +#define INLINE inline +#include "bool-array.icc" +#undef INLINE + +#endif + +#endif diff --git a/contrib/gperf/src/bool-array.icc b/contrib/gperf/src/bool-array.icc new file mode 100644 index 0000000..6de6f23 --- /dev/null +++ b/contrib/gperf/src/bool-array.icc @@ -0,0 +1,85 @@ +/* Inline Functions for bool-array.{h,cc}. + + Copyright (C) 1989-1998 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +// This needs: +//#include <stdio.h> +//#include <string.h> +//#include "options.h" +//#include "trace.h" + +INLINE +Bool_Array::Bool_Array (void) +{ + T (Trace t ("Bool_Array::Bool_Array");) + storage_array = 0; + iteration_number = size = 0; +} + +INLINE void +Bool_Array::init (STORAGE_TYPE *buffer, unsigned int s) +{ + T (Trace t ("Bool_Array::init");) + size = s; + iteration_number = 1; + storage_array = buffer; + memset (storage_array, 0, s * sizeof (*storage_array)); + if (option[DEBUG]) + fprintf (stderr, "\nbool array size = %d, total bytes = %d\n", + size, (unsigned int) (size * sizeof (*storage_array))); +} + +INLINE int +Bool_Array::find (int index) +{ + T (Trace t ("Bool_Array::find");) + if (storage_array[index] == iteration_number) + return 1; + else + { + storage_array[index] = iteration_number; + return 0; + } +} + +INLINE void +Bool_Array::reset (void) +{ + T (Trace t ("Bool_Array::reset");) + /* If we wrap around it's time to zero things out again! However, this only + occurs once about every 2^31 or 2^15 iterations, so it should probably + never happen! */ + + if (++iteration_number == 0) + { + if (option[DEBUG]) + { + fprintf (stderr, "(re-initializing bool_array)..."); + fflush (stderr); + } + iteration_number = 1; + memset (storage_array, 0, size * sizeof (*storage_array)); + if (option[DEBUG]) + { + fprintf (stderr, "done\n"); + fflush (stderr); + } + } +} diff --git a/contrib/gperf/src/config.h.in b/contrib/gperf/src/config.h.in new file mode 100644 index 0000000..4d3d762 --- /dev/null +++ b/contrib/gperf/src/config.h.in @@ -0,0 +1,19 @@ +/* config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define if the C++ compiler supports "throw ()" declarations. */ +#undef HAVE_THROW_DECL + +/* Define if you have the getrlimit function. */ +#undef HAVE_GETRLIMIT + +/* Define if you have the setrlimit function. */ +#undef HAVE_SETRLIMIT + +/* Define if you have the <sys/resource.h> header file. */ +#undef HAVE_SYS_RESOURCE_H + +/* Define if you have the <sys/time.h> header file. */ +#undef HAVE_SYS_TIME_H + +/* Define if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H diff --git a/contrib/gperf/src/configure b/contrib/gperf/src/configure new file mode 100755 index 0000000..edd1fd7 --- /dev/null +++ b/contrib/gperf/src/configure @@ -0,0 +1,1660 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=gen-perf.cc + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:527: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:556: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:586: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:637: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:669: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 680 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:685: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:711: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:716: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:725: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:744: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + + echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:776: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext <<EOF +#line 791 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:797: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext <<EOF +#line 808 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:814: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext <<EOF +#line 825 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:831: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + + for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:860: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CXX="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CXX="$ac_cv_prog_CXX" +if test -n "$CXX"; then + echo "$ac_t""$CXX" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$CXX" && break +done +test -n "$CXX" || CXX="gcc" + + +echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:892: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 + +ac_ext=C +# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cxx_cross + +cat > conftest.$ac_ext << EOF + +#line 903 "configure" +#include "confdefs.h" + +int main(){return(0);} +EOF +if { (eval echo configure:908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cxx_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cxx_cross=no + else + ac_cv_prog_cxx_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cxx_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6 +if test $ac_cv_prog_cxx_works = no; then + { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:934: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6 +cross_compiling=$ac_cv_prog_cxx_cross + +echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 +echo "configure:939: checking whether we are using GNU C++" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.C <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:948: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gxx=yes +else + ac_cv_prog_gxx=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gxx" 1>&6 + +if test $ac_cv_prog_gxx = yes; then + GXX=yes +else + GXX= +fi + +ac_test_CXXFLAGS="${CXXFLAGS+set}" +ac_save_CXXFLAGS="$CXXFLAGS" +CXXFLAGS= +echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 +echo "configure:967: checking whether ${CXX-g++} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.cc +if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then + ac_cv_prog_cxx_g=yes +else + ac_cv_prog_cxx_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6 +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS="$ac_save_CXXFLAGS" +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi + + echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6 +echo "configure:999: checking how to run the C++ preprocessor" >&5 +if test -z "$CXXCPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_ext=C +# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cxx_cross + CXXCPP="${CXX-g++} -E" + cat > conftest.$ac_ext <<EOF +#line 1012 "configure" +#include "confdefs.h" +#include <stdlib.h> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1017: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CXXCPP=/lib/cpp +fi +rm -f conftest* + ac_cv_prog_CXXCPP="$CXXCPP" +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross +fi +fi +CXXCPP="$ac_cv_prog_CXXCPP" +echo "$ac_t""$CXXCPP" 1>&6 + + # Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1052: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'cl_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + for ac_prog in ginstall installbsd scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + # OSF/1 installbsd also uses dspmsg, but is usable. + : + else + if test $ac_prog = installbsd && + grep src/bos $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX installbsd doesn't work without option "-g". + : + else + cl_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + fi + done + ;; + esac + done + IFS="$ac_save_ifs" + # As a last resort, use cp. + test -z "$cl_cv_path_install" && cl_cv_path_install="cp" + +fi + INSTALL="$cl_cv_path_install" +fi +echo "$ac_t""$INSTALL" 1>&6 +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='$(INSTALL)' +if test -z "$INSTALL_DATA"; then + case "$INSTALL" in + cp | */cp ) INSTALL_DATA='$(INSTALL)' ;; + * ) INSTALL_DATA='$(INSTALL) -m 644' ;; + esac +fi + + echo $ac_n "checking for working throw()""... $ac_c" 1>&6 +echo "configure:1105: checking for working throw()" >&5 +if eval "test \"`echo '$''{'gp_cv_cxx_throw_decl'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + +ac_ext=C +# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cxx_cross + +cat > conftest.$ac_ext <<EOF +#line 1119 "configure" +#include "confdefs.h" +#include <stdlib.h> +void operator delete (void* ptr) throw() {} +int main() { + +; return 0; } +EOF +if { (eval echo configure:1127: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + gp_cv_cxx_throw_decl=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + gp_cv_cxx_throw_decl=no +fi +rm -f conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + + +fi + +echo "$ac_t""$gp_cv_cxx_throw_decl" 1>&6 +if test $gp_cv_cxx_throw_decl = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_THROW_DECL 1 +EOF + +fi +for ac_hdr in unistd.h sys/time.h sys/resource.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1158: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1163 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1168: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + if test $ac_cv_header_sys_resource_h = yes; then +for ac_func in getrlimit +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1198: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1203 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1226: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + if test $ac_cv_func_getrlimit = yes; then +for ac_func in setrlimit +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1254: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1259 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1282: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + fi +fi +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir + +trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@CXX@%$CXX%g +s%@CXXCPP@%$CXXCPP%g +s%@INSTALL@%$INSTALL%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_DATA@%$INSTALL_DATA%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <<EOF + CONFIG_HEADERS="config.h" +EOF +cat >> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <<EOF + +EOF +cat >> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/contrib/gperf/src/configure.in b/contrib/gperf/src/configure.in new file mode 100644 index 0000000..e8880d5 --- /dev/null +++ b/contrib/gperf/src/configure.in @@ -0,0 +1,71 @@ +dnl autoconf configuration for gperf/src + +dnl Copyright (C) 1998, 2000 Free Software Foundation, Inc. +dnl written by Douglas C. Schmidt (schmidt@ics.uci.edu) +dnl +dnl This file is part of GNU GPERF. +dnl +dnl GNU GPERF is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 1, or (at your option) +dnl any later version. +dnl +dnl GNU GPERF is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU GPERF; see the file COPYING. If not, write to the +dnl Free Software Foundation, 59 Temple Place - Suite 330, Boston, +dnl MA 02111-1307, USA. + +AC_INIT(gen-perf.cc) +AC_CONFIG_HEADER(config.h) +AC_PROG_MAKE_SET +dnl +dnl checks for programs +dnl +AC_PROG_CC + dnl sets variable CC +AC_PROG_CPP + dnl sets variable CPP +AC_PROG_CXX + dnl sets variable CXX +AC_PROG_CXXCPP + dnl sets variable CXXCPP +CL_PROG_INSTALL + dnl sets variables INSTALL, INSTALL_DATA, INSTALL_PROGRAM +dnl +dnl checks for compiler characteristics +dnl +AC_MSG_CHECKING([for working throw()]) +AC_CACHE_VAL(gp_cv_cxx_throw_decl,[ +AC_LANG_SAVE() +AC_LANG_CPLUSPLUS() +AC_TRY_COMPILE([#include <stdlib.h> +void operator delete (void* ptr) throw() {}], [], +gp_cv_cxx_throw_decl=yes, gp_cv_cxx_throw_decl=no) +AC_LANG_RESTORE() +]) +AC_MSG_RESULT([$]gp_cv_cxx_throw_decl) +if test [$]gp_cv_cxx_throw_decl = yes; then + AC_DEFINE(HAVE_THROW_DECL) +fi +dnl +dnl checks for functions and declarations +dnl +AC_CHECK_HEADERS(unistd.h sys/time.h sys/resource.h) + dnl DEFs HAVE_UNISTD_H, HAVE_SYS_TIME_H, HAVE_SYS_RESOURCE_H +if test $ac_cv_header_sys_resource_h = yes; then +AC_CHECK_FUNCS(getrlimit) + dnl DEFS HAVE_GETRLIMIT +if test $ac_cv_func_getrlimit = yes; then +AC_CHECK_FUNCS(setrlimit) + dnl DEFS HAVE_SETRLIMIT +fi +fi +dnl +dnl That's it. +dnl +AC_OUTPUT(Makefile) diff --git a/contrib/gperf/src/gen-perf.cc b/contrib/gperf/src/gen-perf.cc new file mode 100644 index 0000000..0b5109d --- /dev/null +++ b/contrib/gperf/src/gen-perf.cc @@ -0,0 +1,359 @@ +/* Provides high-level routines to manipulate the keywork list + structures the code generation output. + Copyright (C) 1989-1998, 2000 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include <stdio.h> +#include <stdlib.h> /* declares rand(), srand() */ +#include <time.h> /* declares time() */ +#include "options.h" +#include "gen-perf.h" +#include "trace.h" + +/* 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! */ + +Gen_Perf::Gen_Perf (void) +{ + T (Trace t ("Gen_Perf::Gen_Perf");) + int asso_value_max; + int non_linked_length; + + Key_List::read_keys (); + if (option[ORDER]) + reorder (); + asso_value_max = option.get_asso_max (); + non_linked_length = Key_List::keyword_list_length (); + num_done = 1; + fewest_collisions = 0; + if (asso_value_max == 0) + asso_value_max = non_linked_length; + else if (asso_value_max > 0) + asso_value_max *= non_linked_length; + else /* if (asso_value_max < 0) */ + asso_value_max = non_linked_length / -asso_value_max; + option.set_asso_max (POW (asso_value_max)); + + if (option[RANDOM]) + { + srand ((long) time (0)); + + for (int i = 0; i < ALPHA_SIZE; i++) + asso_values[i] = (rand () & asso_value_max - 1); + } + else + { + int asso_value = option.initial_value (); + + if (asso_value) /* Initialize array if user requests non-zero default. */ + for (int i = ALPHA_SIZE - 1; i >= 0; i--) + asso_values[i] = asso_value & option.get_asso_max () - 1; + } + max_hash_value = Key_List::max_key_length () + option.get_asso_max () * + option.get_max_keysig_size (); + + if (option[DEBUG]) + fprintf (stderr, "total non-linked keys = %d\nmaximum associated value is %d" + "\nmaximum size of generated hash table is %d\n", + non_linked_length, asso_value_max, max_hash_value); +} + +/* Merge two disjoint 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. */ + +inline int +Gen_Perf::compute_disjoint_union (const char *set_1, int size_1, const char *set_2, int size_2, char *set_3) +{ + T (Trace t ("Gen_Perf::compute_disjoint_union");) + char *base = set_3; + + while (size_1 > 0 && size_2 > 0) + if (*set_1 == *set_2) + set_1++, size_1--, set_2++, size_2--; + else + { + char next; + if (*set_1 < *set_2) + next = *set_1++, size_1--; + else + next = *set_2++, size_2--; + if (set_3 == base || next != set_3[-1]) + *set_3++ = next; + } + + while (size_1 > 0) + { + char next; + next = *set_1++, size_1--; + if (set_3 == base || next != set_3[-1]) + *set_3++ = next; + } + + while (size_2 > 0) + { + char next; + next = *set_2++, size_2--; + if (set_3 == base || next != set_3[-1]) + *set_3++ = next; + } + 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. */ + +inline void +Gen_Perf::sort_set (char *union_set, int len) +{ + T (Trace t ("Gen_Perf::sort_set");) + int i, j; + + for (i = 0, j = len - 1; i < j; i++) + { + int curr; + char tmp; + + for (curr = i + 1, tmp = union_set[curr]; + curr > 0 && occurrences[(unsigned char)tmp] < occurrences[(unsigned char)(union_set[curr-1])]; + curr--) + union_set[curr] = union_set[curr - 1]; + + union_set[curr] = tmp; + } +} + +/* Generate a key set's hash value. */ + +inline int +Gen_Perf::hash (List_Node *key_node) +{ + T (Trace t ("Gen_Perf::hash");) + int sum = option[NOLENGTH] ? 0 : key_node->key_length; + + const char *p = key_node->char_set; + int i = key_node->char_set_length; + for (; i > 0; p++, i--) + sum += asso_values[(unsigned char)(*p)]; + + return key_node->hash_value = sum; +} + +/* Find out how character value change affects successfully hashed items. + Returns FALSE if no other hash values are affected, else returns TRUE. + Note that because Option.Get_Asso_Max is a power of two we can guarantee + that all legal Asso_Values are visited without repetition since + Option.Get_Jump was forced to be an odd value! */ + +inline int +Gen_Perf::affects_prev (char c, List_Node *curr) +{ + T (Trace t ("Gen_Perf::affects_prev");) + int original_char = asso_values[(unsigned char)c]; + int total_iterations = !option[FAST] + ? option.get_asso_max () : option.get_iterations () ? option.get_iterations () : keyword_list_length (); + + /* Try all legal associated values. */ + + for (int i = total_iterations - 1; i >= 0; i--) + { + int collisions = 0; + + asso_values[(unsigned char)c] = + (asso_values[(unsigned char)c] + (option.get_jump () ? option.get_jump () : rand ())) + & (option.get_asso_max () - 1); + + /* Iteration Number array is a win, O(1) intialization time! */ + reset (); + + /* See how this asso_value change affects previous keywords. If + it does better than before we'll take it! */ + + for (List_Node *ptr = head; + !Bool_Array::find (hash (ptr)) || ++collisions < fewest_collisions; + ptr = ptr->next) + if (ptr == curr) + { + fewest_collisions = collisions; + if (option[DEBUG]) + fprintf (stderr, "- resolved after %d iterations", total_iterations - i); + return 0; + } + } + + /* Restore original values, no more tries. */ + asso_values[(unsigned char)c] = original_char; + /* If we're this far it's time to try the next character.... */ + return 1; +} + +/* Change a character value, try least-used characters first. */ + +void +Gen_Perf::change (List_Node *prior, List_Node *curr) +{ + T (Trace t ("Gen_Perf::change");) + static char *union_set; + int union_set_length; + + if (!union_set) + union_set = new char [2 * option.get_max_keysig_size ()]; + + if (option[DEBUG]) + { + fprintf (stderr, "collision on keyword #%d, prior = \"%.*s\", curr = \"%.*s\" hash = %d\n", + num_done, + prior->key_length, prior->key, + curr->key_length, curr->key, + curr->hash_value); + fflush (stderr); + } + union_set_length = compute_disjoint_union (prior->char_set, prior->char_set_length, curr->char_set, curr->char_set_length, union_set); + sort_set (union_set, union_set_length); + + /* Try changing some values, if change doesn't alter other values continue normal action. */ + fewest_collisions++; + + const char *p = union_set; + int i = union_set_length; + for (; i > 0; p++, i--) + if (!affects_prev (*p, curr)) + { + if (option[DEBUG]) + { + fprintf (stderr, " by changing asso_value['%c'] (char #%d) to %d\n", + *p, p - union_set + 1, asso_values[(unsigned char)(*p)]); + fflush (stderr); + } + return; /* Good, doesn't affect previous hash values, we'll take it. */ + } + + for (List_Node *ptr = head; ptr != curr; ptr = ptr->next) + hash (ptr); + + hash (curr); + + if (option[DEBUG]) + { + fprintf (stderr, "** collision not resolved after %d iterations, %d duplicates remain, continuing...\n", + !option[FAST] ? option.get_asso_max () : option.get_iterations () ? option.get_iterations () : keyword_list_length (), + fewest_collisions + total_duplicates); + fflush (stderr); + } +} + +/* Does the hard stuff.... + Initializes the Iteration Number array, and attempts 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 +Gen_Perf::operator() (void) +{ + T (Trace t ("Gen_Perf::operator()");) +#if LARGE_STACK_ARRAYS + STORAGE_TYPE buffer[max_hash_value + 1]; +#else + // Note: we don't use new, because that invokes a custom operator new. + STORAGE_TYPE *buffer + = (STORAGE_TYPE*) malloc (sizeof(STORAGE_TYPE) * (max_hash_value + 1)); + if (buffer == NULL) + abort (); +#endif + + Bool_Array::init (buffer, max_hash_value + 1); + + List_Node *curr; + for (curr = head; curr; curr = curr->next) + { + hash (curr); + + for (List_Node *ptr = head; ptr != curr; ptr = ptr->next) + if (ptr->hash_value == curr->hash_value) + { + change (ptr, curr); + break; + } + num_done++; + } + + /* Make one final check, just to make sure nothing weird happened.... */ + + Bool_Array::reset (); + + for (curr = head; curr; curr = curr->next) + if (Bool_Array::find (hash (curr))) + if (option[DUP]) /* Keep track of this number... */ + total_duplicates++; + else /* Yow, big problems. we're outta here! */ + { + fprintf (stderr, "\nInternal error, duplicate value %d:\n" + "try options -D or -r, or use new key positions.\n\n", hash (curr)); +#if !LARGE_STACK_ARRAYS + free ((char *) buffer); +#endif + return 1; + } + + /* Sorts the key word list by hash value, and then outputs the list. + The generated hash table code is only output if the early stage of + processing turned out O.K. */ + + sort (); + output (); +#if !LARGE_STACK_ARRAYS + free ((char *) buffer); +#endif + return 0; +} + +/* Prints out some diagnostics upon completion. */ + +Gen_Perf::~Gen_Perf (void) +{ + T (Trace t ("Gen_Perf::~Gen_Perf");) + if (option[DEBUG]) + { + fprintf (stderr, "\ndumping occurrence and associated values tables\n"); + + for (int i = 0; i < ALPHA_SIZE; i++) + if (occurrences[i]) + fprintf (stderr, "asso_values[%c] = %6d, occurrences[%c] = %6d\n", + i, asso_values[i], i, occurrences[i]); + + fprintf (stderr, "end table dumping\n"); + + } +} + diff --git a/contrib/gperf/src/gen-perf.h b/contrib/gperf/src/gen-perf.h new file mode 100644 index 0000000..602d160 --- /dev/null +++ b/contrib/gperf/src/gen-perf.h @@ -0,0 +1,50 @@ +/* This may look like C code, but it is really -*- C++ -*- */ + +/* Provides high-level routines to manipulate the keyword list + structures the code generation output. + + Copyright (C) 1989-1998, 2000 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#ifndef gen_perf_h +#define gen_perf_h 1 + +#include "key-list.h" +#include "bool-array.h" + +class Gen_Perf : private Key_List, private Bool_Array +{ +private: + 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. */ + + void change (List_Node *prior, List_Node *curr); + int affects_prev (char c, List_Node *curr); + static int hash (List_Node *key_node); + static int compute_disjoint_union (const char *set_1, int size_1, const char *set_2, int size_2, char *set_3); + static void sort_set (char *union_set, int len); + +public: + Gen_Perf (void); + ~Gen_Perf (void); + int operator () (void); +}; + +#endif diff --git a/contrib/gperf/src/hash-table.cc b/contrib/gperf/src/hash-table.cc new file mode 100644 index 0000000..a147674 --- /dev/null +++ b/contrib/gperf/src/hash-table.cc @@ -0,0 +1,95 @@ +/* Hash table for checking keyword links. Implemented using double hashing. + Copyright (C) 1989-1998, 2000 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "hash-table.h" + +#include <stdio.h> +#include <string.h> /* declares memset(), strcmp() */ +#include <hash.h> +#include "options.h" +#include "trace.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! */ + +Hash_Table::Hash_Table (List_Node **table_ptr, int s, int ignore_len): + table (table_ptr), size (s), collisions (0), ignore_length (ignore_len) +{ + T (Trace t ("Hash_Table::Hash_Table");) + memset ((char *) table, 0, size * sizeof (*table)); +} + +Hash_Table::~Hash_Table (void) +{ + T (Trace t ("Hash_Table::~Hash_Table");) + if (option[DEBUG]) + { + int field_width = option.get_max_keysig_size (); + + fprintf (stderr, + "\ndumping the hash table\n" + "total available table slots = %d, total bytes = %d, total collisions = %d\n" + "location, %*s, keyword\n", + size, size * (int) sizeof (*table), collisions, + field_width, "keysig"); + + for (int i = size - 1; i >= 0; i--) + if (table[i]) + fprintf (stderr, "%8d, %*.*s, %.*s\n", + i, + field_width, table[i]->char_set_length, table[i]->char_set, + table[i]->key_length, table[i]->key); + + fprintf (stderr, "\nend 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 * +Hash_Table::insert (List_Node *item) +{ + T (Trace t ("Hash_Table::operator()");) + unsigned hash_val = hashpjw (item->char_set, item->char_set_length); + int probe = hash_val & (size - 1); + int increment = ((hash_val ^ item->key_length) | 1) & (size - 1); + + while (table[probe]) + { + if (table[probe]->char_set_length == item->char_set_length + && memcmp (table[probe]->char_set, item->char_set, item->char_set_length) == 0 + && (ignore_length || table[probe]->key_length == item->key_length)) + return table[probe]; + + collisions++; + probe = (probe + increment) & (size - 1); + } + + table[probe] = item; + return (List_Node *) 0; +} diff --git a/contrib/gperf/src/hash-table.h b/contrib/gperf/src/hash-table.h new file mode 100644 index 0000000..86438d0 --- /dev/null +++ b/contrib/gperf/src/hash-table.h @@ -0,0 +1,43 @@ +/* This may look like C code, but it is really -*- C++ -*- */ + +/* Hash table used to check for duplicate keyword entries. + + Copyright (C) 1989-1998, 2000 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#ifndef hash_table_h +#define hash_table_h 1 + +#include "list-node.h" + +class Hash_Table +{ +private: + List_Node **table; /* Vector of pointers to linked lists of List_Node's. */ + int size; /* Size of the vector. */ + int collisions; /* Find out how well our double hashing is working! */ + int ignore_length; + +public: + Hash_Table (List_Node **t, int s, int ignore_len); + ~Hash_Table (void); + List_Node *insert (List_Node *item); +}; + +#endif diff --git a/contrib/gperf/src/iterator.cc b/contrib/gperf/src/iterator.cc new file mode 100644 index 0000000..ca66bbb --- /dev/null +++ b/contrib/gperf/src/iterator.cc @@ -0,0 +1,87 @@ +/* Provides an Iterator for keyword characters. + Copyright (C) 1989-1998, 2000 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "iterator.h" + +#include <ctype.h> +#include "trace.h" + +/* Constructor for Iterator. */ + +Iterator::Iterator (const char *s, int lo, int hi, int word_end, int bad_val, int key_end) +{ + T (Trace t ("Iterator::Iterator");) + end = key_end; + error_value = bad_val; + end_word = word_end; + str = s; + hi_bound = hi; + lo_bound = lo; +} + +/* Provide an Iterator, returning the ``next'' value from + the list of valid values given in the constructor. */ + +int +Iterator::operator() (void) +{ + T (Trace t ("Iterator::operator()");) +/* 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 (*str) + switch (*str) + { + default: return error_value; + case ',': str++; break; + case '$': str++; return end_word; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + for (curr_value = 0; isdigit ((unsigned char)(*str)); str++) + curr_value = curr_value * 10 + (*str - '0'); + + if (*str == '-') + { + + for (size = 1, upper_bound = 0; + isdigit ((unsigned char)(*++str)); + upper_bound = upper_bound * 10 + (*str - '0')); + + if (upper_bound <= curr_value || upper_bound > hi_bound) + return error_value; + } + return curr_value >= lo_bound && curr_value <= hi_bound + ? curr_value : error_value; + } + + return end; + } +} diff --git a/contrib/gperf/src/iterator.h b/contrib/gperf/src/iterator.h new file mode 100644 index 0000000..d5138ab --- /dev/null +++ b/contrib/gperf/src/iterator.h @@ -0,0 +1,51 @@ +/* This may look like C code, but it is really -*- C++ -*- */ + +/* Provides an Iterator for keyword characters. + + Copyright (C) 1989-1998 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 1 + +class Iterator +{ +private: + const 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. */ + +public: + Iterator (const char *s, int lo, int hi, int word_end, int bad_val, int key_end); + int operator () (void); +}; + +#endif diff --git a/contrib/gperf/src/key-list.cc b/contrib/gperf/src/key-list.cc new file mode 100644 index 0000000..1c941a4 --- /dev/null +++ b/contrib/gperf/src/key-list.cc @@ -0,0 +1,2184 @@ +/* Routines for building, ordering, and printing the keyword list. + Copyright (C) 1989-1998, 2000 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include <stdio.h> +#include <string.h> /* declares strncpy(), strchr() */ +#include <stdlib.h> /* declares malloc(), free(), abs(), exit(), abort() */ +#include <ctype.h> /* declares isprint() */ +#include <assert.h> /* defines assert() */ +#include <limits.h> /* defines SCHAR_MAX etc. */ +#include "options.h" +#include "read-line.h" +#include "hash-table.h" +#include "key-list.h" +#include "trace.h" +#include "version.h" + +/* Make the hash table 8 times larger than the number of keyword entries. */ +static const int TABLE_MULTIPLE = 10; + +/* 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))) + +int Key_List::determined[MAX_ALPHA_SIZE]; + +/* Destructor dumps diagnostics during debugging. */ + +Key_List::~Key_List (void) +{ + T (Trace t ("Key_List::~Key_List");) + if (option[DEBUG]) + { + fprintf (stderr, "\nDumping key list information:\ntotal non-static linked keywords = %d" + "\ntotal keywords = %d\ntotal duplicates = %d\nmaximum key length = %d\n", + list_len, total_keys, total_duplicates, max_key_len); + dump (); + fprintf (stderr, "End dumping list.\n\n"); + } +} + +/* Gathers the input stream into a buffer until one of two things occur: + + 1. We read a '%' followed by a '%' + 2. We read a '%' followed by a '}' + + The first symbolizes the beginning of the keyword list proper, + The second symbolizes the end of the C source code to be generated + verbatim in the output file. + + I assume that the keys are separated from the optional preceding struct + declaration by a consecutive % followed by either % or } starting in + the first column. The code below uses an expandible buffer to scan off + and return a pointer to all the code (if any) appearing before the delimiter. */ + +const char * +Key_List::get_special_input (char delimiter) +{ + T (Trace t ("Key_List::get_special_input");) + int size = 80; + char *buf = new char[size]; + int c, i; + + for (i = 0; (c = getchar ()) != EOF; i++) + { + if (c == '%') + { + if ((c = getchar ()) == delimiter) + { + + while ((c = getchar ()) != '\n') + ; /* discard newline */ + + if (i == 0) + return ""; + else + { + buf[delimiter == '%' && buf[i - 2] == ';' ? i - 2 : i - 1] = '\0'; + return buf; + } + } + else + buf[i++] = '%'; + } + else if (i >= size) /* Yikes, time to grow the buffer! */ + { + char *temp = new char[size *= 2]; + int j; + + for (j = 0; j < i; j++) + temp[j] = buf[j]; + + buf = temp; + } + buf[i] = c; + } + + return 0; /* Problem here. */ +} + +/* Stores any C text that must be included verbatim into the + generated code output. */ + +const char * +Key_List::save_include_src (void) +{ + T (Trace t ("Key_List::save_include_src");) + int c; + + if ((c = getchar ()) != '%') + ungetc (c, stdin); + else if ((c = getchar ()) != '{') + { + fprintf (stderr, "internal error, %c != '{' on line %d in file %s", c, __LINE__, __FILE__); + exit (1); + } + else + return get_special_input ('}'); + return ""; +} + +/* Determines from the input file whether the user wants to build a table + from a user-defined struct, or whether the user is content to simply + use the default array of keys. */ + +const char * +Key_List::get_array_type (void) +{ + T (Trace t ("Key_List::get_array_type");) + return get_special_input ('%'); +} + +/* strcspn - find length of initial segment of S consisting entirely + of characters not from REJECT (borrowed from Henry Spencer's + ANSI string package, when GNU libc comes out I'll replace this...). */ + +#ifndef strcspn +inline int +Key_List::strcspn (const char *s, const char *reject) +{ + T (Trace t ("Key_List::strcspn");) + const char *scan; + const char *rej_scan; + int count = 0; + + for (scan = s; *scan; scan++) + { + + for (rej_scan = reject; *rej_scan; rej_scan++) + if (*scan == *rej_scan) + return count; + + count++; + } + + return count; +} +#endif + +/* Sets up the Return_Type, the Struct_Tag type and the Array_Type + based upon various user Options. */ + +void +Key_List::set_output_types (void) +{ + T (Trace t ("Key_List::set_output_types");) + if (option[TYPE]) + { + array_type = get_array_type (); + if (!array_type) + /* Something's wrong, but we'll catch it later on, in read_keys()... */ + return; + /* Yow, we've got a user-defined type... */ + int i = strcspn (array_type, "{\n\0"); + /* Remove trailing whitespace. */ + while (i > 0 && strchr (" \t", array_type[i-1])) + i--; + int struct_tag_length = i; + + /* Set `struct_tag' to a naked "struct something". */ + char *structtag = new char[struct_tag_length + 1]; + strncpy (structtag, array_type, struct_tag_length); + structtag[struct_tag_length] = '\0'; + struct_tag = structtag; + + /* The return type of the lookup function is "struct something *". + No "const" here, because if !option[CONST], some user code might want + to modify the structure. */ + char *rettype = new char[struct_tag_length + 3]; + strncpy (rettype, array_type, struct_tag_length); + rettype[struct_tag_length] = ' '; + rettype[struct_tag_length + 1] = '*'; + rettype[struct_tag_length + 2] = '\0'; + return_type = rettype; + } +} + +/* Extracts a key from an input line and creates a new List_Node for it. */ + +static List_Node * +parse_line (const char *line, const char *delimiters) +{ + if (*line == '"') + { + /* Parse a string in ANSI C syntax. */ + char *key = new char[strlen(line)]; + char *kp = key; + const char *lp = line + 1; + + for (; *lp;) + { + char c = *lp; + + if (c == '\0') + { + fprintf (stderr, "unterminated string: %s\n", line); + exit (1); + } + else if (c == '\\') + { + c = *++lp; + switch (c) + { + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + { + int code = 0; + int count = 0; + while (count < 3 && *lp >= '0' && *lp <= '7') + { + code = (code << 3) + (*lp - '0'); + lp++; + count++; + } + if (code > UCHAR_MAX) + fprintf (stderr, "octal escape out of range: %s\n", line); + *kp = (char) code; + break; + } + case 'x': + { + int code = 0; + int count = 0; + lp++; + while ((*lp >= '0' && *lp <= '9') + || (*lp >= 'A' && *lp <= 'F') + || (*lp >= 'a' && *lp <= 'f')) + { + code = (code << 4) + + (*lp >= 'A' && *lp <= 'F' ? *lp - 'A' + 10 : + *lp >= 'a' && *lp <= 'f' ? *lp - 'a' + 10 : + *lp - '0'); + lp++; + count++; + } + if (count == 0) + fprintf (stderr, "hexadecimal escape without any hex digits: %s\n", line); + if (code > UCHAR_MAX) + fprintf (stderr, "hexadecimal escape out of range: %s\n", line); + *kp = (char) code; + break; + } + case '\\': case '\'': case '"': + *kp = c; + lp++; + break; + case 'n': + *kp = '\n'; + lp++; + break; + case 't': + *kp = '\t'; + lp++; + break; + case 'r': + *kp = '\r'; + lp++; + break; + case 'f': + *kp = '\f'; + lp++; + break; + case 'b': + *kp = '\b'; + lp++; + break; + case 'a': + *kp = '\a'; + lp++; + break; + case 'v': + *kp = '\v'; + lp++; + break; + default: + fprintf (stderr, "invalid escape sequence in string: %s\n", line); + exit (1); + } + } + else if (c == '"') + break; + else + { + *kp = c; + lp++; + } + kp++; + } + lp++; + if (*lp != '\0') + { + if (strchr (delimiters, *lp) == NULL) + { + fprintf (stderr, "string not followed by delimiter: %s\n", line); + exit (1); + } + lp++; + } + return new List_Node (key, kp - key, option[TYPE] ? lp : ""); + } + else + { + /* Not a string. Look for the delimiter. */ + int len = strcspn (line, delimiters); + const char *rest; + + if (line[len] == '\0') + rest = ""; + else + /* Skip the first delimiter. */ + rest = &line[len + 1]; + return new List_Node (line, len, option[TYPE] ? rest : ""); + } +} + +/* Reads in all keys from standard input and creates a linked list pointed + to by Head. This list is then quickly checked for ``links,'' i.e., + unhashable elements possessing identical key sets and lengths. */ + +void +Key_List::read_keys (void) +{ + T (Trace t ("Key_List::read_keys");) + char *ptr; + + include_src = save_include_src (); + set_output_types (); + + /* Oops, problem with the input file. */ + if (! (ptr = Read_Line::get_line ())) + { + fprintf (stderr, "No words in input file, did you forget to prepend %s or use -t accidentally?\n", "%%"); + exit (1); + } + + /* Read in all the keywords from the input file. */ + else + { + const char *delimiter = option.get_delimiter (); + List_Node *temp, *trail = 0; + + head = parse_line (ptr, delimiter); + + for (temp = head; + (ptr = Read_Line::get_line ()) && strcmp (ptr, "%%"); + temp = temp->next) + { + temp->next = parse_line (ptr, delimiter); + total_keys++; + } + + /* See if any additional C code is included at end of this file. */ + if (ptr) + additional_code = 1; + + /* Hash table this number of times larger than keyword number. */ + int table_size = (list_len = total_keys) * TABLE_MULTIPLE; + +#if LARGE_STACK_ARRAYS + /* By allocating the memory here we save on dynamic allocation overhead. + Table must be a power of 2 for the hash function scheme to work. */ + List_Node *table[POW (table_size)]; +#else + // Note: we don't use new, because that invokes a custom operator new. + int malloc_size = POW (table_size) * sizeof(List_Node*); + if (malloc_size == 0) malloc_size = 1; + List_Node **table = (List_Node**)malloc(malloc_size); + if (table == NULL) + abort (); +#endif + + /* Make large hash table for efficiency. */ + Hash_Table found_link (table, table_size, option[NOLENGTH]); + + /* Test whether there are any links and also set the maximum length of + an identifier in the keyword list. */ + + for (temp = head; temp; temp = temp->next) + { + List_Node *ptr = found_link.insert (temp); + + /* Check for links. We deal with these by building an equivalence class + of all duplicate values (i.e., links) so that only 1 keyword is + representative of the entire collection. This *greatly* simplifies + processing during later stages of the program. */ + + if (ptr) + { + total_duplicates++; + list_len--; + trail->next = temp->next; + temp->link = ptr->link; + ptr->link = temp; + + /* Complain if user hasn't enabled the duplicate option. */ + if (!option[DUP] || option[DEBUG]) + fprintf (stderr, "Key link: \"%.*s\" = \"%.*s\", with key set \"%.*s\".\n", + temp->key_length, temp->key, + ptr->key_length, ptr->key, + temp->char_set_length, temp->char_set); + } + else + trail = temp; + + /* Update minimum and maximum keyword length, if needed. */ + if (max_key_len < temp->key_length) + max_key_len = temp->key_length; + if (min_key_len > temp->key_length) + min_key_len = temp->key_length; + } + +#if !LARGE_STACK_ARRAYS + free ((char *) table); +#endif + + /* Exit program if links exists and option[DUP] not set, since we can't continue */ + if (total_duplicates) + { + if (option[DUP]) + fprintf (stderr, "%d input keys have identical hash values, examine output carefully...\n", + total_duplicates); + else + { + fprintf (stderr, "%d input keys have identical hash values,\ntry different key positions or use option -D.\n", + total_duplicates); + exit (1); + } + } + /* Exit program if an empty string is used as key, since the comparison + expressions don't work correctly for looking up an empty string. */ + if (min_key_len == 0) + { + fprintf (stderr, "Empty input key is not allowed.\nTo recognize an empty input key, your code should check for\nlen == 0 before calling the gperf generated lookup function.\n"); + exit (1); + } + if (option[ALLCHARS]) + option.set_keysig_size (max_key_len); + } +} + +/* Recursively merges two sorted lists together to form one sorted list. The + ordering criteria is by frequency of occurrence of elements in the key set + or by the hash value. This is a kludge, but permits nice sharing of + almost identical code without incurring the overhead of a function + call comparison. */ + +List_Node * +Key_List::merge (List_Node *list1, List_Node *list2) +{ + T (Trace t ("Key_List::merge");) + List_Node *result; + List_Node **resultp = &result; + for (;;) + { + if (!list1) + { + *resultp = list2; + break; + } + if (!list2) + { + *resultp = list1; + break; + } + if (occurrence_sort && list1->occurrence < list2->occurrence + || hash_sort && list1->hash_value > list2->hash_value) + { + *resultp = list2; + resultp = &list2->next; list2 = list1; list1 = *resultp; + } + else + { + *resultp = list1; + resultp = &list1->next; list1 = *resultp; + } + } + return result; +} + +/* Applies the merge sort algorithm to recursively sort the key list by + frequency of occurrence of elements in the key set. */ + +List_Node * +Key_List::merge_sort (List_Node *head) +{ + T (Trace t ("Key_List::merge_sort");) + if (!head || !head->next) + return head; + else + { + List_Node *middle = head; + List_Node *temp = head->next->next; + + while (temp) + { + temp = temp->next; + middle = middle->next; + if (temp) + temp = temp->next; + } + + temp = middle->next; + middle->next = 0; + return merge (merge_sort (head), merge_sort (temp)); + } +} + +/* Returns the frequency of occurrence of elements in the key set. */ + +inline int +Key_List::get_occurrence (List_Node *ptr) +{ + T (Trace t ("Key_List::get_occurrence");) + int value = 0; + + const char *p = ptr->char_set; + unsigned int i = ptr->char_set_length; + for (; i > 0; p++, i--) + value += occurrences[(unsigned char)(*p)]; + + return value; +} + +/* Enables the index location of all key set elements that are now + determined. */ + +inline void +Key_List::set_determined (List_Node *ptr) +{ + T (Trace t ("Key_List::set_determined");) + + const char *p = ptr->char_set; + unsigned int i = ptr->char_set_length; + for (; i > 0; p++, i--) + determined[(unsigned char)(*p)] = 1; +} + +/* Returns TRUE if PTR's key set is already completely determined. */ + +inline int +Key_List::already_determined (List_Node *ptr) +{ + T (Trace t ("Key_List::already_determined");) + int is_determined = 1; + + const char *p = ptr->char_set; + unsigned int i = ptr->char_set_length; + for (; is_determined && i > 0; p++, i--) + is_determined = determined[(unsigned char)(*p)]; + + return is_determined; +} + +/* Reorders the table by first sorting the list so that frequently occuring + keys appear first, and then the list is reorded so that keys whose values + are already determined will be placed towards the front of the list. This + helps prune the search time by handling inevitable collisions early in the + search process. See Cichelli's paper from Jan 1980 JACM for details.... */ + +void +Key_List::reorder (void) +{ + T (Trace t ("Key_List::reorder");) + List_Node *ptr; + for (ptr = head; ptr; ptr = ptr->next) + ptr->occurrence = get_occurrence (ptr); + + hash_sort = 0; + occurrence_sort = 1; + + for (ptr = head = merge_sort (head); ptr->next; ptr = ptr->next) + { + set_determined (ptr); + + if (already_determined (ptr->next)) + continue; + else + { + List_Node *trail_ptr = ptr->next; + List_Node *run_ptr = trail_ptr->next; + + for (; run_ptr; run_ptr = trail_ptr->next) + { + + if (already_determined (run_ptr)) + { + trail_ptr->next = run_ptr->next; + run_ptr->next = ptr->next; + ptr = ptr->next = run_ptr; + } + else + trail_ptr = run_ptr; + } + } + } +} + +/* ============================ Output routines ============================ */ + +/* The "const " qualifier. */ +static const char *const_always; + +/* The "const " qualifier, for read-only arrays. */ +static const char *const_readonly_array; + +/* The "const " qualifier, for the array type. */ +static const char *const_for_struct; + +/* Returns the smallest unsigned C type capable of holding integers up to N. */ + +static const char * +smallest_integral_type (int n) +{ + if (n <= UCHAR_MAX) return "unsigned char"; + if (n <= USHRT_MAX) return "unsigned short"; + return "unsigned int"; +} + +/* Returns the smallest signed C type capable of holding integers + from MIN to MAX. */ + +static const char * +smallest_integral_type (int min, int max) +{ + if (option[ANSIC] | option[CPLUSPLUS]) + if (min >= SCHAR_MIN && max <= SCHAR_MAX) return "signed char"; + if (min >= SHRT_MIN && max <= SHRT_MAX) return "short"; + return "int"; +} + +/* A cast from `char' to a valid array index. */ +static const char *char_to_index; + +/* ------------------------------------------------------------------------- */ + +/* Computes the maximum and minimum hash values. Since the + list is already sorted by hash value all we need to do is + find the final item! */ + +void +Key_List::compute_min_max (void) +{ + T (Trace t ("Key_List::compute_min_max");) + List_Node *temp; + for (temp = head; temp->next; temp = temp->next) + ; + + min_hash_value = head->hash_value; + max_hash_value = temp->hash_value; +} + +/* ------------------------------------------------------------------------- */ + +/* Returns the number of different hash values. */ + +int +Key_List::num_hash_values (void) +{ + T (Trace t ("Key_List::num_hash_values");) + int count = 1; + List_Node *temp; + int value; + + for (temp = head, value = temp->hash_value; temp->next; ) + { + temp = temp->next; + if (value != temp->hash_value) + { + value = temp->hash_value; + count++; + } + } + return count; +} + +/* -------------------- Output_Constants and subclasses -------------------- */ + +/* This class outputs an enumeration defining some constants. */ + +struct Output_Constants +{ + virtual void output_start () = 0; + virtual void output_item (const char *name, int value) = 0; + virtual void output_end () = 0; + Output_Constants () {} + virtual ~Output_Constants () {} +}; + +/* This class outputs an enumeration in #define syntax. */ + +struct Output_Defines : public Output_Constants +{ + virtual void output_start (); + virtual void output_item (const char *name, int value); + virtual void output_end (); + Output_Defines () {} + virtual ~Output_Defines () {} +}; + +void Output_Defines::output_start () +{ + T (Trace t ("Output_Defines::output_start");) + printf ("\n"); +} + +void Output_Defines::output_item (const char *name, int value) +{ + T (Trace t ("Output_Defines::output_item");) + printf ("#define %s %d\n", name, value); +} + +void Output_Defines::output_end () +{ + T (Trace t ("Output_Defines::output_end");) +} + +/* This class outputs an enumeration using `enum'. */ + +struct Output_Enum : public Output_Constants +{ + virtual void output_start (); + virtual void output_item (const char *name, int value); + virtual void output_end (); + Output_Enum (const char *indent) : indentation (indent) {} + virtual ~Output_Enum () {} +private: + const char *indentation; + int pending_comma; +}; + +void Output_Enum::output_start () +{ + T (Trace t ("Output_Enum::output_start");) + printf ("%senum\n" + "%s {\n", + indentation, indentation); + pending_comma = 0; +} + +void Output_Enum::output_item (const char *name, int value) +{ + T (Trace t ("Output_Enum::output_item");) + if (pending_comma) + printf (",\n"); + printf ("%s %s = %d", indentation, name, value); + pending_comma = 1; +} + +void Output_Enum::output_end () +{ + T (Trace t ("Output_Enum::output_end");) + if (pending_comma) + printf ("\n"); + printf ("%s };\n\n", indentation); +} + +/* Outputs the maximum and minimum hash values etc. */ + +void +Key_List::output_constants (struct Output_Constants& style) +{ + T (Trace t ("Key_List::output_constants");) + + style.output_start (); + style.output_item ("TOTAL_KEYWORDS", total_keys); + style.output_item ("MIN_WORD_LENGTH", min_key_len); + style.output_item ("MAX_WORD_LENGTH", max_key_len); + style.output_item ("MIN_HASH_VALUE", min_hash_value); + style.output_item ("MAX_HASH_VALUE", max_hash_value); + style.output_end (); +} + +/* ------------------------------------------------------------------------- */ + +/* Outputs a keyword, as a string: enclosed in double quotes, escaping + backslashes, double quote and unprintable characters. */ + +static void +output_string (const char *key, int len) +{ + T (Trace t ("output_string");) + + putchar ('"'); + for (; len > 0; len--) + { + unsigned char c = (unsigned char) *key++; + if (isprint (c)) + { + if (c == '"' || c == '\\') + putchar ('\\'); + putchar (c); + } + else + { + /* Use octal escapes, not hexadecimal escapes, because some old + C compilers didn't understand hexadecimal escapes, and because + hexadecimal escapes are not limited to 2 digits, thus needing + special care if the following character happens to be a digit. */ + putchar ('\\'); + putchar ('0' + ((c >> 6) & 7)); + putchar ('0' + ((c >> 3) & 7)); + putchar ('0' + (c & 7)); + } + } + putchar ('"'); +} + +/* ------------------------------------------------------------------------- */ + +/* Outputs a type and a const specifier. + The output is terminated with a space. */ + +static void +output_const_type (const char *const_string, const char *type_string) +{ + if (type_string[strlen(type_string)-1] == '*') + printf ("%s %s", type_string, const_string); + else + printf ("%s%s ", const_string, type_string); +} + +/* ----------------------- Output_Expr and subclasses ----------------------- */ + +/* This class outputs a general expression. */ + +struct Output_Expr +{ + virtual void output_expr () const = 0; + Output_Expr () {} + virtual ~Output_Expr () {} +}; + +/* This class outputs an expression formed by a single string. */ + +struct Output_Expr1 : public Output_Expr +{ + virtual void output_expr () const; + Output_Expr1 (const char *piece1) : p1 (piece1) {} + virtual ~Output_Expr1 () {} +private: + const char *p1; +}; + +void Output_Expr1::output_expr () const +{ + T (Trace t ("Output_Expr1::output_expr");) + printf ("%s", p1); +} + +#if 0 /* unused */ + +/* This class outputs an expression formed by the concatenation of two + strings. */ + +struct Output_Expr2 : public Output_Expr +{ + virtual void output_expr () const; + Output_Expr2 (const char *piece1, const char *piece2) + : p1 (piece1), p2 (piece2) {} + virtual ~Output_Expr2 () {} +private: + const char *p1; + const char *p2; +}; + +void Output_Expr2::output_expr () const +{ + T (Trace t ("Output_Expr2::output_expr");) + printf ("%s%s", p1, p2); +} + +#endif + +/* --------------------- Output_Compare and subclasses --------------------- */ + +/* This class outputs a comparison expression. */ + +struct Output_Compare +{ + virtual void output_comparison (const Output_Expr& expr1, + const Output_Expr& expr2) const = 0; + Output_Compare () {} + virtual ~Output_Compare () {} +}; + +/* This class outputs a comparison using strcmp. */ + +struct Output_Compare_Strcmp : public Output_Compare +{ + virtual void output_comparison (const Output_Expr& expr1, + const Output_Expr& expr2) const; + Output_Compare_Strcmp () {} + virtual ~Output_Compare_Strcmp () {} +}; + +void Output_Compare_Strcmp::output_comparison (const Output_Expr& expr1, + const Output_Expr& expr2) const +{ + T (Trace t ("Output_Compare_Strcmp::output_comparison");) + printf ("*"); + expr1.output_expr (); + printf (" == *"); + expr2.output_expr (); + printf (" && !strcmp ("); + expr1.output_expr (); + printf (" + 1, "); + expr2.output_expr (); + printf (" + 1)"); +} + +/* This class outputs a comparison using strncmp. + Note that the length of expr1 will be available through the local variable + `len'. */ + +struct Output_Compare_Strncmp : public Output_Compare +{ + virtual void output_comparison (const Output_Expr& expr1, + const Output_Expr& expr2) const; + Output_Compare_Strncmp () {} + virtual ~Output_Compare_Strncmp () {} +}; + +void Output_Compare_Strncmp::output_comparison (const Output_Expr& expr1, + const Output_Expr& expr2) const +{ + T (Trace t ("Output_Compare_Strncmp::output_comparison");) + printf ("*"); + expr1.output_expr (); + printf (" == *"); + expr2.output_expr (); + printf (" && !strncmp ("); + expr1.output_expr (); + printf (" + 1, "); + expr2.output_expr (); + printf (" + 1, len - 1) && "); + expr2.output_expr (); + printf ("[len] == '\\0'"); +} + +/* This class outputs a comparison using memcmp. + Note that the length of expr1 (available through the local variable `len') + must be verified to be equal to the length of expr2 prior to this + comparison. */ + +struct Output_Compare_Memcmp : public Output_Compare +{ + virtual void output_comparison (const Output_Expr& expr1, + const Output_Expr& expr2) const; + Output_Compare_Memcmp () {} + virtual ~Output_Compare_Memcmp () {} +}; + +void Output_Compare_Memcmp::output_comparison (const Output_Expr& expr1, + const Output_Expr& expr2) const +{ + T (Trace t ("Output_Compare_Memcmp::output_comparison");) + printf ("*"); + expr1.output_expr (); + printf (" == *"); + expr2.output_expr (); + printf (" && !memcmp ("); + expr1.output_expr (); + printf (" + 1, "); + expr2.output_expr (); + printf (" + 1, len - 1)"); +} + +/* ------------------------------------------------------------------------- */ + +/* Generates C code for the hash function that returns the + proper encoding for each key word. */ + +void +Key_List::output_hash_function (void) +{ + T (Trace t ("Key_List::output_hash_function");) + const int max_column = 10; + int field_width; + + /* Calculate maximum number of digits required for MAX_HASH_VALUE. */ + field_width = 2; + for (int trunc = max_hash_value; (trunc /= 10) > 0;) + field_width++; + + /* Output the function's head. */ + if (option[CPLUSPLUS]) + printf ("inline "); + else if (option[KRC] | option[C] | option[ANSIC]) + printf ("#ifdef __GNUC__\n" + "__inline\n" + "#else\n" + "#ifdef __cplusplus\n" + "inline\n" + "#endif\n" + "#endif\n"); + + if (option[KRC] | option[C] | option[ANSIC]) + printf ("static "); + printf ("unsigned int\n"); + if (option[CPLUSPLUS]) + printf ("%s::", option.get_class_name ()); + printf ("%s ", option.get_hash_name ()); + printf (option[KRC] ? + "(str, len)\n" + " register char *str;\n" + " register unsigned int len;\n" : + option[C] ? + "(str, len)\n" + " register const char *str;\n" + " register unsigned int len;\n" : + option[ANSIC] | option[CPLUSPLUS] ? + "(register const char *str, register unsigned int len)\n" : + ""); + + /* Note that when the hash function is called, it has already been verified + that min_key_len <= len <= max_key_len. */ + + /* Output the function's body. */ + printf ("{\n"); + + /* First the asso_values array. */ + printf (" static %s%s asso_values[] =\n" + " {", + const_readonly_array, + smallest_integral_type (max_hash_value + 1)); + + for (int count = 0; count < ALPHA_SIZE; count++) + { + if (count > 0) + printf (","); + if (!(count % max_column)) + printf ("\n "); + printf ("%*d", field_width, + occurrences[count] ? asso_values[count] : max_hash_value + 1); + } + + printf ("\n" + " };\n"); + + /* Optimize special case of ``-k 1,$'' */ + if (option[DEFAULTCHARS]) + printf (" return %sasso_values[%sstr[len - 1]] + asso_values[%sstr[0]];\n", + option[NOLENGTH] ? "" : "len + ", + char_to_index, char_to_index); + else + { + int key_pos; + + option.reset (); + + /* Get first (also highest) key position. */ + key_pos = option.get (); + + if (!option[ALLCHARS] && (key_pos == WORD_END || key_pos <= min_key_len)) + { + /* We can perform additional optimizations here: + Write it out as a single expression. Note that the values + are added as `int's even though the asso_values array may + contain `unsigned char's or `unsigned short's. */ + + printf (" return %s", + option[NOLENGTH] ? "" : "len + "); + + for (; key_pos != WORD_END; ) + { + printf ("asso_values[%sstr[%d]]", char_to_index, key_pos - 1); + if ((key_pos = option.get ()) != EOS) + printf (" + "); + else + break; + } + + if (key_pos == WORD_END) + printf ("asso_values[%sstr[len - 1]]", char_to_index); + + printf (";\n"); + } + else + { + /* We've got to use the correct, but brute force, technique. */ + printf (" register int hval = %s;\n\n" + " switch (%s)\n" + " {\n" + " default:\n", + option[NOLENGTH] ? "0" : "len", + option[NOLENGTH] ? "len" : "hval"); + + /* User wants *all* characters considered in hash. */ + if (option[ALLCHARS]) + { + for (int i = max_key_len; i > 0; i--) + printf (" case %d:\n" + " hval += asso_values[%sstr[%d]];\n", + i, char_to_index, i - 1); + + printf (" break;\n" + " }\n" + " return hval;\n"); + } + else /* do the hard part... */ + { + while (key_pos != WORD_END && key_pos > max_key_len) + if ((key_pos = option.get ()) == EOS) + break; + + if (key_pos != EOS && key_pos != WORD_END) + { + int i = key_pos; + do + { + for ( ; i >= key_pos; i--) + printf (" case %d:\n", i); + + printf (" hval += asso_values[%sstr[%d]];\n", + char_to_index, key_pos - 1); + + key_pos = option.get (); + } + while (key_pos != EOS && key_pos != WORD_END); + + for ( ; i >= min_key_len; i--) + printf (" case %d:\n", i); + } + + printf (" break;\n" + " }\n" + " return hval"); + if (key_pos == WORD_END) + printf (" + asso_values[%sstr[len - 1]]", char_to_index); + printf (";\n"); + } + } + } + printf ("}\n\n"); +} + +/* ------------------------------------------------------------------------- */ + +/* Prints out a table of keyword lengths, for use with the + comparison code in generated function ``in_word_set''. */ + +void +Key_List::output_keylength_table (void) +{ + T (Trace t ("Key_List::output_keylength_table");) + const int columns = 14; + int index; + int column; + const char *indent = option[GLOBAL] ? "" : " "; + List_Node *temp; + + printf ("%sstatic %s%s lengthtable[] =\n%s {", + indent, const_readonly_array, + smallest_integral_type (max_key_len), + indent); + + /* Generate an array of lengths, similar to output_keyword_table. */ + + column = 0; + for (temp = head, index = 0; temp; temp = temp->next) + { + if (option[SWITCH] && !option[TYPE] + && !(temp->link + || (temp->next && temp->hash_value == temp->next->hash_value))) + continue; + + if (index < temp->hash_value && !option[SWITCH] && !option[DUP]) + { + /* Some blank entries. */ + for ( ; index < temp->hash_value; index++) + { + if (index > 0) + printf (","); + if ((column++ % columns) == 0) + printf ("\n%s ", indent); + printf ("%3d", 0); + } + } + + if (index > 0) + printf (","); + if ((column++ % columns) == 0) + printf("\n%s ", indent); + printf ("%3d", temp->key_length); + + /* Deal with links specially. */ + if (temp->link) // implies option[DUP] + for (List_Node *links = temp->link; links; links = links->link) + { + ++index; + printf (","); + if ((column++ % columns) == 0) + printf("\n%s ", indent); + printf ("%3d", links->key_length); + } + + index++; + } + + printf ("\n%s };\n", indent); + if (option[GLOBAL]) + printf ("\n"); +} + +/* ------------------------------------------------------------------------- */ + +static void +output_keyword_entry (List_Node *temp, const char *indent) +{ + printf ("%s ", indent); + if (option[TYPE]) + printf ("{"); + output_string (temp->key, temp->key_length); + if (option[TYPE]) + { + if (strlen (temp->rest) > 0) + printf (",%s", temp->rest); + printf ("}"); + } + if (option[DEBUG]) + printf (" /* hash value = %d, index = %d */", + temp->hash_value, temp->index); +} + +static void +output_keyword_blank_entries (int count, const char *indent) +{ + int columns; + if (option[TYPE]) + { + columns = 58 / (6 + strlen (option.get_initializer_suffix())); + if (columns == 0) + columns = 1; + } + else + { + columns = 9; + } + int column = 0; + for (int i = 0; i < count; i++) + { + if ((column % columns) == 0) + { + if (i > 0) + printf (",\n"); + printf ("%s ", indent); + } + else + { + if (i > 0) + printf (", "); + } + if (option[TYPE]) + printf ("{\"\"%s}", option.get_initializer_suffix()); + else + printf ("\"\""); + column++; + } +} + +/* Prints out the array containing the key words for the hash function. */ + +void +Key_List::output_keyword_table (void) +{ + T (Trace t ("Key_List::output_keyword_table");) + const char *indent = option[GLOBAL] ? "" : " "; + int index; + List_Node *temp; + + printf ("%sstatic ", + indent); + output_const_type (const_readonly_array, struct_tag); + printf ("%s[] =\n" + "%s {\n", + option.get_wordlist_name (), + indent); + + /* Generate an array of reserved words at appropriate locations. */ + + for (temp = head, index = 0; temp; temp = temp->next) + { + if (option[SWITCH] && !option[TYPE] + && !(temp->link + || (temp->next && temp->hash_value == temp->next->hash_value))) + continue; + + if (index > 0) + printf (",\n"); + + if (index < temp->hash_value && !option[SWITCH] && !option[DUP]) + { + /* Some blank entries. */ + output_keyword_blank_entries (temp->hash_value - index, indent); + printf (",\n"); + index = temp->hash_value; + } + + temp->index = index; + + output_keyword_entry (temp, indent); + + /* Deal with links specially. */ + if (temp->link) // implies option[DUP] + for (List_Node *links = temp->link; links; links = links->link) + { + links->index = ++index; + printf (",\n"); + output_keyword_entry (links, indent); + } + + index++; + } + if (index > 0) + printf ("\n"); + + printf ("%s };\n\n", indent); +} + +/* ------------------------------------------------------------------------- */ + +/* Generates the large, sparse table that maps hash values into + the smaller, contiguous range of the keyword table. */ + +void +Key_List::output_lookup_array (void) +{ + T (Trace t ("Key_List::output_lookup_array");) + if (option[DUP]) + { + const int DEFAULT_VALUE = -1; + + /* Because of the way output_keyword_table works, every duplicate set is + stored contiguously in the wordlist array. */ + struct duplicate_entry + { + int hash_value; /* Hash value for this particular duplicate set. */ + int index; /* Index into the main keyword storage array. */ + int count; /* Number of consecutive duplicates at this index. */ + }; + +#if LARGE_STACK_ARRAYS + duplicate_entry duplicates[total_duplicates]; + int lookup_array[max_hash_value + 1 + 2*total_duplicates]; +#else + // Note: we don't use new, because that invokes a custom operator new. + duplicate_entry *duplicates = (duplicate_entry *) + malloc (total_duplicates * sizeof(duplicate_entry) + 1); + int *lookup_array = (int *) + malloc ((max_hash_value + 1 + 2*total_duplicates) * sizeof(int)); + if (duplicates == NULL || lookup_array == NULL) + abort(); +#endif + int lookup_array_size = max_hash_value + 1; + duplicate_entry *dup_ptr = &duplicates[0]; + int *lookup_ptr = &lookup_array[max_hash_value + 1 + 2*total_duplicates]; + + while (lookup_ptr > lookup_array) + *--lookup_ptr = DEFAULT_VALUE; + + /* Now dup_ptr = &duplicates[0] and lookup_ptr = &lookup_array[0]. */ + + for (List_Node *temp = head; temp; temp = temp->next) + { + int hash_value = temp->hash_value; + lookup_array[hash_value] = temp->index; + if (option[DEBUG]) + fprintf (stderr, "keyword = %.*s, index = %d\n", + temp->key_length, temp->key, temp->index); + if (temp->link + || (temp->next && hash_value == temp->next->hash_value)) + { + /* Start a duplicate entry. */ + dup_ptr->hash_value = hash_value; + dup_ptr->index = temp->index; + dup_ptr->count = 1; + + for (;;) + { + for (List_Node *ptr = temp->link; ptr; ptr = ptr->link) + { + dup_ptr->count++; + if (option[DEBUG]) + fprintf (stderr, + "static linked keyword = %.*s, index = %d\n", + ptr->key_length, ptr->key, ptr->index); + } + + if (!(temp->next && hash_value == temp->next->hash_value)) + break; + + temp = temp->next; + + dup_ptr->count++; + if (option[DEBUG]) + fprintf (stderr, "dynamic linked keyword = %.*s, index = %d\n", + temp->key_length, temp->key, temp->index); + } + assert (dup_ptr->count >= 2); + dup_ptr++; + } + } + + while (dup_ptr > duplicates) + { + dup_ptr--; + + if (option[DEBUG]) + fprintf (stderr, + "dup_ptr[%d]: hash_value = %d, index = %d, count = %d\n", + dup_ptr - duplicates, + dup_ptr->hash_value, dup_ptr->index, dup_ptr->count); + + int i; + /* Start searching for available space towards the right part + of the lookup array. */ + for (i = dup_ptr->hash_value; i < lookup_array_size-1; i++) + if (lookup_array[i] == DEFAULT_VALUE + && lookup_array[i + 1] == DEFAULT_VALUE) + goto found_i; + /* If we didn't find it to the right look to the left instead... */ + for (i = dup_ptr->hash_value-1; i >= 0; i--) + if (lookup_array[i] == DEFAULT_VALUE + && lookup_array[i + 1] == DEFAULT_VALUE) + goto found_i; + /* Append to the end of lookup_array. */ + i = lookup_array_size; + lookup_array_size += 2; + found_i: + /* Put in an indirection from dup_ptr->hash_value to i. + At i and i+1 store dup_ptr->index and dup_ptr->count. */ + assert (lookup_array[dup_ptr->hash_value] == dup_ptr->index); + lookup_array[dup_ptr->hash_value] = - 1 - total_keys - i; + lookup_array[i] = - total_keys + dup_ptr->index; + lookup_array[i + 1] = - dup_ptr->count; + /* All these three values are <= -2, distinct from DEFAULT_VALUE. */ + } + + /* The values of the lookup array are now known. */ + + int min = INT_MAX; + int max = INT_MIN; + lookup_ptr = lookup_array + lookup_array_size; + while (lookup_ptr > lookup_array) + { + int val = *--lookup_ptr; + if (min > val) + min = val; + if (max < val) + max = val; + } + + const char *indent = option[GLOBAL] ? "" : " "; + printf ("%sstatic %s%s lookup[] =\n" + "%s {", + indent, const_readonly_array, smallest_integral_type (min, max), + indent); + + int field_width; + /* Calculate maximum number of digits required for MIN..MAX. */ + { + field_width = 2; + for (int trunc = max; (trunc /= 10) > 0;) + field_width++; + } + if (min < 0) + { + int neg_field_width = 2; + for (int trunc = -min; (trunc /= 10) > 0;) + neg_field_width++; + neg_field_width++; /* account for the minus sign */ + if (field_width < neg_field_width) + field_width = neg_field_width; + } + + const int columns = 42 / field_width; + int column; + + column = 0; + for (int i = 0; i < lookup_array_size; i++) + { + if (i > 0) + printf (","); + if ((column++ % columns) == 0) + printf("\n%s ", indent); + printf ("%*d", field_width, lookup_array[i]); + } + printf ("\n%s };\n\n", indent); + +#if !LARGE_STACK_ARRAYS + free ((char *) duplicates); + free ((char *) lookup_array); +#endif + } +} + +/* ------------------------------------------------------------------------- */ + +/* Generate all the tables needed for the lookup function. */ + +void +Key_List::output_lookup_tables (void) +{ + T (Trace t ("Key_List::output_lookup_tables");) + + if (option[SWITCH]) + { + /* Use the switch in place of lookup table. */ + if (option[LENTABLE] && (option[DUP] && total_duplicates > 0)) + output_keylength_table (); + if (option[TYPE] || (option[DUP] && total_duplicates > 0)) + output_keyword_table (); + } + else + { + /* Use the lookup table, in place of switch. */ + if (option[LENTABLE]) + output_keylength_table (); + output_keyword_table (); + output_lookup_array (); + } +} + +/* ------------------------------------------------------------------------- */ + +/* Output a single switch case (including duplicates). Advance list. */ + +static List_Node * +output_switch_case (List_Node *list, int indent, int *jumps_away) +{ + T (Trace t ("output_switch_case");) + + if (option[DEBUG]) + printf ("%*s/* hash value = %4d, keyword = \"%.*s\" */\n", + indent, "", list->hash_value, list->key_length, list->key); + + if (option[DUP] + && (list->link + || (list->next && list->hash_value == list->next->hash_value))) + { + if (option[LENTABLE]) + printf ("%*slengthptr = &lengthtable[%d];\n", + indent, "", list->index); + printf ("%*swordptr = &%s[%d];\n", + indent, "", option.get_wordlist_name (), list->index); + + int count = 0; + for (List_Node *temp = list; ; temp = temp->next) + { + for (List_Node *links = temp; links; links = links->link) + count++; + if (!(temp->next && temp->hash_value == temp->next->hash_value)) + break; + } + + printf ("%*swordendptr = wordptr + %d;\n" + "%*sgoto multicompare;\n", + indent, "", count, + indent, ""); + *jumps_away = 1; + } + else + { + if (option[LENTABLE]) + { + printf ("%*sif (len == %d)\n" + "%*s {\n", + indent, "", list->key_length, + indent, ""); + indent += 4; + } + printf ("%*sresword = ", + indent, ""); + if (option[TYPE]) + printf ("&%s[%d]", option.get_wordlist_name (), list->index); + else + output_string (list->key, list->key_length); + printf (";\n"); + printf ("%*sgoto compare;\n", + indent, ""); + if (option[LENTABLE]) + { + indent -= 4; + printf ("%*s }\n", + indent, ""); + } + else + *jumps_away = 1; + } + + while (list->next && list->hash_value == list->next->hash_value) + list = list->next; + list = list->next; + return list; +} + +/* Output a total of size cases, grouped into num_switches switch statements, + where 0 < num_switches <= size. */ + +static void +output_switches (List_Node *list, int num_switches, int size, int min_hash_value, int max_hash_value, int indent) +{ + T (Trace t ("output_switches");) + + if (option[DEBUG]) + printf ("%*s/* know %d <= key <= %d, contains %d cases */\n", + indent, "", min_hash_value, max_hash_value, size); + + if (num_switches > 1) + { + int part1 = num_switches / 2; + int part2 = num_switches - part1; + int size1 = (int)((double)size / (double)num_switches * (double)part1 + 0.5); + int size2 = size - size1; + + List_Node *temp = list; + for (int count = size1; count > 0; count--) + { + while (temp->hash_value == temp->next->hash_value) + temp = temp->next; + temp = temp->next; + } + + printf ("%*sif (key < %d)\n" + "%*s {\n", + indent, "", temp->hash_value, + indent, ""); + + output_switches (list, part1, size1, min_hash_value, temp->hash_value-1, indent+4); + + printf ("%*s }\n" + "%*selse\n" + "%*s {\n", + indent, "", indent, "", indent, ""); + + output_switches (temp, part2, size2, temp->hash_value, max_hash_value, indent+4); + + printf ("%*s }\n", + indent, ""); + } + else + { + /* Output a single switch. */ + int lowest_case_value = list->hash_value; + if (size == 1) + { + int jumps_away = 0; + assert (min_hash_value <= lowest_case_value); + assert (lowest_case_value <= max_hash_value); + if (min_hash_value == max_hash_value) + output_switch_case (list, indent, &jumps_away); + else + { + printf ("%*sif (key == %d)\n" + "%*s {\n", + indent, "", lowest_case_value, + indent, ""); + output_switch_case (list, indent+4, &jumps_away); + printf ("%*s }\n", + indent, ""); + } + } + else + { + if (lowest_case_value == 0) + printf ("%*sswitch (key)\n", indent, ""); + else + printf ("%*sswitch (key - %d)\n", indent, "", lowest_case_value); + printf ("%*s {\n", + indent, ""); + for (; size > 0; size--) + { + int jumps_away = 0; + printf ("%*s case %d:\n", + indent, "", list->hash_value - lowest_case_value); + list = output_switch_case (list, indent+6, &jumps_away); + if (!jumps_away) + printf ("%*s break;\n", + indent, ""); + } + printf ("%*s }\n", + indent, ""); + } + } +} + +/* Generates C code to perform the keyword lookup. */ + +void +Key_List::output_lookup_function_body (const Output_Compare& comparison) +{ + T (Trace t ("Key_List::output_lookup_function_body");) + + printf (" if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)\n" + " {\n" + " register int key = %s (str, len);\n\n", + option.get_hash_name ()); + + if (option[SWITCH]) + { + int switch_size = num_hash_values (); + int num_switches = option.get_total_switches (); + if (num_switches > switch_size) + num_switches = switch_size; + + printf (" if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)\n" + " {\n"); + if (option[DUP]) + { + if (option[LENTABLE]) + printf (" register %s%s *lengthptr;\n", + const_always, smallest_integral_type (max_key_len)); + printf (" register "); + output_const_type (const_readonly_array, struct_tag); + printf ("*wordptr;\n"); + printf (" register "); + output_const_type (const_readonly_array, struct_tag); + printf ("*wordendptr;\n"); + } + if (option[TYPE]) + { + printf (" register "); + output_const_type (const_readonly_array, struct_tag); + printf ("*resword;\n\n"); + } + else + printf (" register %sresword;\n\n", + struct_tag); + + output_switches (head, num_switches, switch_size, min_hash_value, max_hash_value, 10); + + if (option[DUP]) + { + int indent = 8; + printf ("%*s return 0;\n" + "%*smulticompare:\n" + "%*s while (wordptr < wordendptr)\n" + "%*s {\n", + indent, "", indent, "", indent, "", indent, ""); + if (option[LENTABLE]) + { + printf ("%*s if (len == *lengthptr)\n" + "%*s {\n", + indent, "", indent, ""); + indent += 4; + } + printf ("%*s register %schar *s = ", + indent, "", const_always); + if (option[TYPE]) + printf ("wordptr->%s", option.get_key_name ()); + else + printf ("*wordptr"); + printf (";\n\n" + "%*s if (", + indent, ""); + comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s")); + printf (")\n" + "%*s return %s;\n", + indent, "", + option[TYPE] ? "wordptr" : "s"); + if (option[LENTABLE]) + { + indent -= 4; + printf ("%*s }\n", + indent, ""); + } + if (option[LENTABLE]) + printf ("%*s lengthptr++;\n", + indent, ""); + printf ("%*s wordptr++;\n" + "%*s }\n", + indent, "", indent, ""); + } + printf (" return 0;\n" + " compare:\n"); + if (option[TYPE]) + { + printf (" {\n" + " register %schar *s = resword->%s;\n\n" + " if (", + const_always, option.get_key_name ()); + comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s")); + printf (")\n" + " return resword;\n" + " }\n"); + } + else + { + printf (" if ("); + comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("resword")); + printf (")\n" + " return resword;\n"); + } + printf (" }\n"); + } + else + { + printf (" if (key <= MAX_HASH_VALUE && key >= 0)\n"); + + if (option[DUP]) + { + int indent = 8; + printf ("%*s{\n" + "%*s register int index = lookup[key];\n\n" + "%*s if (index >= 0)\n", + indent, "", indent, "", indent, ""); + if (option[LENTABLE]) + { + printf ("%*s {\n" + "%*s if (len == lengthtable[index])\n", + indent, "", indent, ""); + indent += 4; + } + printf ("%*s {\n" + "%*s register %schar *s = %s[index]", + indent, "", + indent, "", const_always, option.get_wordlist_name ()); + if (option[TYPE]) + printf (".%s", option.get_key_name ()); + printf (";\n\n" + "%*s if (", + indent, ""); + comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s")); + printf (")\n" + "%*s return ", + indent, ""); + if (option[TYPE]) + printf ("&%s[index]", option.get_wordlist_name ()); + else + printf ("s"); + printf (";\n" + "%*s }\n", + indent, ""); + if (option[LENTABLE]) + { + indent -= 4; + printf ("%*s }\n", indent, ""); + } + if (total_duplicates > 0) + { + printf ("%*s else if (index < -TOTAL_KEYWORDS)\n" + "%*s {\n" + "%*s register int offset = - 1 - TOTAL_KEYWORDS - index;\n", + indent, "", indent, "", indent, ""); + if (option[LENTABLE]) + printf ("%*s register %s%s *lengthptr = &lengthtable[TOTAL_KEYWORDS + lookup[offset]];\n", + indent, "", const_always, smallest_integral_type (max_key_len)); + printf ("%*s register ", + indent, ""); + output_const_type (const_readonly_array, struct_tag); + printf ("*wordptr = &%s[TOTAL_KEYWORDS + lookup[offset]];\n", + option.get_wordlist_name ()); + printf ("%*s register ", + indent, ""); + output_const_type (const_readonly_array, struct_tag); + printf ("*wordendptr = wordptr + -lookup[offset + 1];\n\n"); + printf ("%*s while (wordptr < wordendptr)\n" + "%*s {\n", + indent, "", indent, ""); + if (option[LENTABLE]) + { + printf ("%*s if (len == *lengthptr)\n" + "%*s {\n", + indent, "", indent, ""); + indent += 4; + } + printf ("%*s register %schar *s = ", + indent, "", const_always); + if (option[TYPE]) + printf ("wordptr->%s", option.get_key_name ()); + else + printf ("*wordptr"); + printf (";\n\n" + "%*s if (", + indent, ""); + comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s")); + printf (")\n" + "%*s return %s;\n", + indent, "", + option[TYPE] ? "wordptr" : "s"); + if (option[LENTABLE]) + { + indent -= 4; + printf ("%*s }\n", + indent, ""); + } + if (option[LENTABLE]) + printf ("%*s lengthptr++;\n", + indent, ""); + printf ("%*s wordptr++;\n" + "%*s }\n" + "%*s }\n", + indent, "", indent, "", indent, ""); + } + printf ("%*s}\n", + indent, ""); + } + else + { + int indent = 8; + if (option[LENTABLE]) + { + printf ("%*sif (len == lengthtable[key])\n", + indent, ""); + indent += 2; + } + + printf ("%*s{\n" + "%*s register %schar *s = %s[key]", + indent, "", + indent, "", const_always, option.get_wordlist_name ()); + + if (option[TYPE]) + printf (".%s", option.get_key_name ()); + + printf (";\n\n" + "%*s if (", + indent, ""); + comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s")); + printf (")\n" + "%*s return ", + indent, ""); + if (option[TYPE]) + printf ("&%s[key]", option.get_wordlist_name ()); + else + printf ("s"); + printf (";\n" + "%*s}\n", + indent, ""); + } + } + printf (" }\n" + " return 0;\n"); +} + +/* Generates C code for the lookup function. */ + +void +Key_List::output_lookup_function (void) +{ + T (Trace t ("Key_List::output_lookup_function");) + + /* Output the function's head. */ + if (option[KRC] | option[C] | option[ANSIC]) + printf ("#ifdef __GNUC__\n" + "__inline\n" + "#endif\n"); + + printf ("%s%s\n", + const_for_struct, return_type); + if (option[CPLUSPLUS]) + printf ("%s::", option.get_class_name ()); + printf ("%s ", option.get_function_name ()); + printf (option[KRC] ? + "(str, len)\n" + " register char *str;\n" + " register unsigned int len;\n" : + option[C] ? + "(str, len)\n" + " register const char *str;\n" + " register unsigned int len;\n" : + option[ANSIC] | option[CPLUSPLUS] ? + "(register const char *str, register unsigned int len)\n" : + ""); + + /* Output the function's body. */ + printf ("{\n"); + + if (option[ENUM] && !option[GLOBAL]) + { + Output_Enum style (" "); + output_constants (style); + } + + if (!option[GLOBAL]) + output_lookup_tables (); + + if (option[LENTABLE]) + output_lookup_function_body (Output_Compare_Memcmp ()); + else + { + if (option[COMP]) + output_lookup_function_body (Output_Compare_Strncmp ()); + else + output_lookup_function_body (Output_Compare_Strcmp ()); + } + + printf ("}\n"); +} + +/* ------------------------------------------------------------------------- */ + +/* Generates the hash function and the key word recognizer function + based upon the user's Options. */ + +void +Key_List::output (void) +{ + T (Trace t ("Key_List::output");) + + compute_min_max (); + + if (option[C] | option[ANSIC] | option[CPLUSPLUS]) + { + const_always = "const "; + const_readonly_array = (option[CONST] ? "const " : ""); + const_for_struct = ((option[CONST] && option[TYPE]) ? "const " : ""); + } + else + { + const_always = ""; + const_readonly_array = ""; + const_for_struct = ""; + } + + if (!option[TYPE]) + { + return_type = (const_always[0] ? "const char *" : "char *"); + struct_tag = (const_always[0] ? "const char *" : "char *"); + } + + char_to_index = (option[SEVENBIT] ? "" : "(unsigned char)"); + + printf ("/* "); + if (option[KRC]) + printf ("KR-C"); + else if (option[C]) + printf ("C"); + else if (option[ANSIC]) + printf ("ANSI-C"); + else if (option[CPLUSPLUS]) + printf ("C++"); + printf (" code produced by gperf version %s */\n", version_string); + Options::print_options (); + + printf ("%s\n", include_src); + + if (option[TYPE] && !option[NOTYPE]) /* Output type declaration now, reference it later on.... */ + printf ("%s;\n", array_type); + + if (option[INCLUDE]) + printf ("#include <string.h>\n"); /* Declare strlen(), strcmp(), strncmp(). */ + + if (!option[ENUM]) + { + Output_Defines style; + output_constants (style); + } + else if (option[GLOBAL]) + { + Output_Enum style (""); + output_constants (style); + } + + printf ("/* maximum key range = %d, duplicates = %d */\n\n", + max_hash_value - min_hash_value + 1, total_duplicates); + + if (option[CPLUSPLUS]) + printf ("class %s\n" + "{\n" + "private:\n" + " static inline unsigned int %s (const char *str, unsigned int len);\n" + "public:\n" + " static %s%s%s (const char *str, unsigned int len);\n" + "};\n" + "\n", + option.get_class_name (), option.get_hash_name (), + const_for_struct, return_type, option.get_function_name ()); + + output_hash_function (); + + if (option[GLOBAL]) + output_lookup_tables (); + + output_lookup_function (); + + if (additional_code) + for (int c; (c = getchar ()) != EOF; putchar (c)) + ; + + fflush (stdout); +} + +/* ========================= End of Output routines ========================= */ + +/* Sorts the keys by hash value. */ + +void +Key_List::sort (void) +{ + T (Trace t ("Key_List::sort");) + hash_sort = 1; + occurrence_sort = 0; + + head = merge_sort (head); +} + +/* Dumps the key list to stderr stream. */ + +void +Key_List::dump () +{ + T (Trace t ("Key_List::dump");) + int field_width = option.get_max_keysig_size (); + + fprintf (stderr, "\nList contents are:\n(hash value, key length, index, %*s, keyword):\n", + field_width, "char_set"); + + for (List_Node *ptr = head; ptr; ptr = ptr->next) + fprintf (stderr, "%11d,%11d,%6d, %*.*s, %.*s\n", + ptr->hash_value, ptr->key_length, ptr->index, + field_width, ptr->char_set_length, ptr->char_set, + ptr->key_length, ptr->key); +} + +/* Simple-minded constructor action here... */ + +Key_List::Key_List (void) +{ + T (Trace t ("Key_List::Key_List");) + total_keys = 1; + max_key_len = INT_MIN; + min_key_len = INT_MAX; + array_type = 0; + return_type = 0; + struct_tag = 0; + head = 0; + total_duplicates = 0; + additional_code = 0; +} + +/* Returns the length of entire key list. */ + +int +Key_List::keyword_list_length (void) +{ + T (Trace t ("Key_List::keyword_list_length");) + return list_len; +} + +/* Returns length of longest key read. */ + +int +Key_List::max_key_length (void) +{ + T (Trace t ("Key_List::max_key_length");) + return max_key_len; +} + diff --git a/contrib/gperf/src/key-list.h b/contrib/gperf/src/key-list.h new file mode 100644 index 0000000..98b8fa5 --- /dev/null +++ b/contrib/gperf/src/key-list.h @@ -0,0 +1,96 @@ +/* This may look like C code, but it is really -*- C++ -*- */ + +/* Data and function member declarations for the keyword list class. + + Copyright (C) 1989-1998 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +/* The key word list is a useful abstraction that keeps track of + various pieces of information that enable that fast generation + of the Gen_Perf.hash function. A Key_List is a singly-linked + list of List_Nodes. */ + +#ifndef key_list_h +#define key_list_h 1 + +#include "list-node.h" +#include "vectors.h" +#include "read-line.h" + +/* OSF/1 cxx needs these forward declarations. */ +struct Output_Constants; +struct Output_Compare; + +class Key_List : private Read_Line, public Vectors +{ +private: + const char *array_type; /* Pointer to the type for word list. */ + const char *return_type; /* Pointer to return type for lookup function. */ + const char *struct_tag; /* Shorthand for user-defined struct tag type. */ + const char *include_src; /* C source code to be included verbatim. */ + int max_key_len; /* Maximum length of the longest keyword. */ + int min_key_len; /* Minimum length of the shortest keyword. */ + int min_hash_value; /* Minimum hash value for all keywords. */ + int max_hash_value; /* Maximum hash value for all keywords. */ + int occurrence_sort; /* True if sorting by occurrence. */ + int hash_sort; /* True if sorting by hash value. */ + int additional_code; /* True if any additional C code is included. */ + int list_len; /* Length of head's Key_List, not counting duplicates. */ + int total_keys; /* Total number of keys, counting duplicates. */ + static int determined[MAX_ALPHA_SIZE]; /* Used in function reorder, below. */ + static int get_occurrence (List_Node *ptr); +#ifndef strcspn + static int strcspn (const char *s, const char *reject); +#endif + static int already_determined (List_Node *ptr); + static void set_determined (List_Node *ptr); + void compute_min_max (void); + int num_hash_values (void); + void output_constants (struct Output_Constants&); + void output_hash_function (void); + void output_keylength_table (void); + void output_keyword_table (void); + void output_lookup_array (void); + void output_lookup_tables (void); + void output_lookup_function_body (const struct Output_Compare&); + void output_lookup_function (void); + void set_output_types (void); + void dump (void); + const char *get_array_type (void); + const char *save_include_src (void); + const char *get_special_input (char delimiter); + List_Node *merge (List_Node *list1, List_Node *list2); + List_Node *merge_sort (List_Node *head); + +protected: + List_Node *head; /* Points to the head of the linked list. */ + int total_duplicates; /* Total number of duplicate hash values. */ + +public: + Key_List (void); + ~Key_List (void); + int keyword_list_length (void); + int max_key_length (void); + void reorder (void); + void sort (void); + void read_keys (void); + void output (void); +}; + +#endif diff --git a/contrib/gperf/src/list-node.cc b/contrib/gperf/src/list-node.cc new file mode 100644 index 0000000..57a04a0 --- /dev/null +++ b/contrib/gperf/src/list-node.cc @@ -0,0 +1,102 @@ +/* Creates and initializes a new list node. + Copyright (C) 1989-1998, 2000 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "list-node.h" + +#include <stdio.h> +#include <stdlib.h> /* declares exit() */ +#include "options.h" +#include "trace.h" + +/* Sorts the key set alphabetically to speed up subsequent operations. + Uses insertion sort since the set is probably quite small. */ + +inline void +List_Node::set_sort (char *base, int len) +{ + T (Trace t ("List_Node::set_sort");) + 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 CHAR_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. Finally, KEY_NUMBER contains a count + of the total number of keys seen so far. This is used to initialize + the INDEX field to some useful value. */ + +List_Node::List_Node (const char *k, int len, const char *r): + link (0), next (0), key (k), key_length (len), rest (r), index (0) +{ + T (Trace t ("List_Node::List_Node");) + char *key_set = new char[(option[ALLCHARS] ? len : option.get_max_keysig_size ())]; + char *ptr = key_set; + int i; + + if (option[ALLCHARS]) /* Use all the character positions in the KEY. */ + for (i = len; i > 0; k++, ptr++, i--) + ++occurrences[(unsigned char)(*ptr = *k)]; + else /* Only use those character positions specified by the user. */ + { + /* Iterate through the list of key_positions, initializing occurrences table + and char_set (via char * pointer ptr). */ + + for (option.reset (); (i = option.get ()) != EOS; ) + { + if (i == WORD_END) /* Special notation for last KEY position, i.e. '$'. */ + *ptr = key[len - 1]; + else if (i <= len) /* Within range of KEY length, so we'll keep it. */ + *ptr = key[i - 1]; + else /* Out of range of KEY length, so we'll just skip it. */ + continue; + ++occurrences[(unsigned char)(*ptr++)]; + } + + /* Didn't get any hits and user doesn't want to consider the + keylength, so there are essentially no usable hash positions! */ + if (ptr == char_set && option[NOLENGTH]) + { + fprintf (stderr, "Can't hash keyword %.*s with chosen key positions.\n", + key_length, key); + exit (1); + } + } + + /* Sort the KEY_SET items alphabetically. */ + set_sort (key_set, ptr - key_set); + + char_set = key_set; + char_set_length = ptr - key_set; +} diff --git a/contrib/gperf/src/list-node.h b/contrib/gperf/src/list-node.h new file mode 100644 index 0000000..3bd21b3 --- /dev/null +++ b/contrib/gperf/src/list-node.h @@ -0,0 +1,46 @@ +/* This may look like C code, but it is really -*- C++ -*- */ + +/* Data and function members for defining values and operations of a list node. + + Copyright (C) 1989-1998, 2000 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#ifndef list_node_h +#define list_node_h 1 + +#include "vectors.h" + +struct List_Node : private Vectors +{ + List_Node *link; /* TRUE if key has an identical KEY_SET as another key. */ + List_Node *next; /* Points to next element on the list. */ + const char *key; /* Each keyword string stored here. */ + int key_length; /* Length of the key. */ + const char *rest; /* Additional information for building hash function. */ + const char *char_set; /* Set of characters to hash, specified by user. */ + int char_set_length; /* Length of char_set. */ + 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. */ + + List_Node (const char *key, int len, const char *rest); + static void set_sort (char *base, int len); +}; + +#endif diff --git a/contrib/gperf/src/main.cc b/contrib/gperf/src/main.cc new file mode 100644 index 0000000..03b6c7e --- /dev/null +++ b/contrib/gperf/src/main.cc @@ -0,0 +1,76 @@ +/* Driver program for the Gen_Perf hash function generator + Copyright (C) 1989-1998, 2000 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +/* Simple driver program for the Gen_Perf.hash function generator. + Most of the hard work is done in class Gen_Perf and its class methods. */ + +#include "config.h" +#include <sys/types.h> +#if LARGE_STACK_ARRAYS && defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#ifdef HAVE_SYS_RESOURCE_H +#include <sys/resource.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#endif + +#include <stdio.h> +#include "options.h" +#include "gen-perf.h" +#include "trace.h" + +int +main (int argc, char *argv[]) +{ + T (Trace t ("main");) + +#if LARGE_STACK_ARRAYS && defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) && defined(RLIMIT_STACK) + /* Get rid of any avoidable limit on stack size. */ + { + struct rlimit rlim; + if (getrlimit (RLIMIT_STACK, &rlim) == 0) + if (rlim.rlim_cur < rlim.rlim_max) + { + rlim.rlim_cur = rlim.rlim_max; + setrlimit (RLIMIT_STACK, &rlim); + } + } +#endif /* RLIMIT_STACK */ + + /* Sets the Options. */ + option (argc, argv); + + /* Initializes the key word list. */ + Gen_Perf generate_table; + + /* Generates and prints the Gen_Perf hash table. */ + int status = generate_table (); + + /* Check for write error on stdout. */ + if (fflush (stdout) || ferror (stdout)) + status = 1; + + /* Don't use exit() here, it skips the destructors. */ + return status; +} diff --git a/contrib/gperf/src/new.cc b/contrib/gperf/src/new.cc new file mode 100644 index 0000000..8c6728e --- /dev/null +++ b/contrib/gperf/src/new.cc @@ -0,0 +1,87 @@ +/* Defines a buffered memory allocation abstraction that reduces calls to + malloc. + Copyright (C) 1989-1998 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "config.h" +#include <stdio.h> +#include <stdlib.h> /* declares malloc(), exit() */ +#include "trace.h" + +/* 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;}; +const int ALIGNMENT = ((char *)&((struct fooalign *) 0)->d - (char *)0); + +/* Provide an abstraction that cuts down on the number of + calls to NEW by buffering the memory pool from which + strings are allocated. */ + +void * +operator new (size_t size) +{ + T (Trace t ("operator new");) + static char *buf_start = 0; /* Large array used to reduce calls to NEW. */ + static char *buf_end = 0; /* Indicates end of BUF_START. */ + static size_t buf_size = 4096; /* Size of buffer pointed to by BUF_START. */ + char *temp; + + /* 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. Note we use a heuristic that grows the buffer either by + size of the request or by twice the previous size, whichever is + larger. */ + + if (buf_start + size >= buf_end) + { + buf_size *= 2; + if (buf_size < size) + buf_size = size; + if ((buf_start = (char *)malloc (buf_size)) != (char *)0) + buf_end = buf_start + buf_size; + else + { + fprintf (stderr, "Virtual memory exhausted in `operator new'\n"); + exit (1); + } + } + + temp = buf_start; + buf_start += size; + return temp; +} + +/* We need this deletion operator in order to make the linker happy. + Because `operator new' and `operator delete' always come together. */ + +void +operator delete (void *ptr) +#ifdef HAVE_THROW_DECL + throw() +#endif +{ + T (Trace t ("operator delete");) + // We cannot call free here, as it doesn't match the mallocs. + // free ((char *) ptr); + (void) ptr; +} diff --git a/contrib/gperf/src/options.cc b/contrib/gperf/src/options.cc new file mode 100644 index 0000000..d15e21c --- /dev/null +++ b/contrib/gperf/src/options.cc @@ -0,0 +1,727 @@ +/* Handles parsing the Options provided to the user. + Copyright (C) 1989-1998, 2000 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include <stdio.h> +#include <stdlib.h> /* declares atoi(), abs(), exit() */ +#include <string.h> /* declares strcmp() */ +#include "getopt.h" +#include "options.h" +#include "iterator.h" +#include "trace.h" +#include "vectors.h" +#include "version.h" + +/* Global option coordinator for the entire program. */ +Options option; + +/* Records the program name. */ +const char *program_name; + +/* Size to jump on a collision. */ +static const int DEFAULT_JUMP_VALUE = 5; + +/* Default name for generated lookup function. */ +static const char *const DEFAULT_NAME = "in_word_set"; + +/* Default name for the key component. */ +static const char *const DEFAULT_KEY = "name"; + +/* Default struct initializer suffix. */ +static const char *const DEFAULT_INITIALIZER_SUFFIX = ""; + +/* Default name for the generated class. */ +static const char *const DEFAULT_CLASS_NAME = "Perfect_Hash"; + +/* Default name for generated hash function. */ +static const char *const DEFAULT_HASH_NAME = "hash"; + +/* Default name for generated hash table array. */ +static const char *const DEFAULT_WORDLIST_NAME = "wordlist"; + +/* Default delimiters that separate keywords from their attributes. */ +static const char *const DEFAULT_DELIMITERS = ",\n"; + +int Options::option_word; +int Options::total_switches; +int Options::total_keysig_size; +int Options::size; +int Options::key_pos; +int Options::jump; +int Options::initial_asso_value; +int Options::argument_count; +int Options::iterations; +char **Options::argument_vector; +const char *Options::function_name; +const char *Options::key_name; +const char *Options::initializer_suffix; +const char *Options::class_name; +const char *Options::hash_name; +const char *Options::wordlist_name; +const char *Options::delimiters; +char Options::key_positions[MAX_KEY_POS]; + +/* Prints program usage to given stream. */ + +void +Options::short_usage (FILE * strm) +{ + T (Trace t ("Options::short_usage");) + fprintf (strm, "Usage: %s [-cCdDef[num]F<initializers>GhH<hashname>i<init>Ijk<keys>K<keyname>lL<language>nN<function name>ors<size>S<switches>tTvW<wordlistname>Z<class name>7] [input-file]\n" + "Try `%s --help' for more information.\n", + program_name, program_name); +} + +void +Options::long_usage (FILE * strm) +{ + T (Trace t ("Options::long_usage");) + fprintf (strm, + "GNU `gperf' generates perfect hash functions.\n" + "\n" + "Usage: %s [OPTION]... [INPUT-FILE]\n" + "\n" + "If a long option shows an argument as mandatory, then it is mandatory\n" + "for the equivalent short option also.\n" + "\n" + "Input file interpretation:\n" + " -e, --delimiters=DELIMITER-LIST\n" + " Allow user to provide a string containing delimiters\n" + " used to separate keywords from their attributes.\n" + " Default is \",\\n\".\n" + " -t, --struct-type Allows the user to include a structured type\n" + " declaration for generated code. Any text before %%%%\n" + " is considered part of the type declaration. Key\n" + " words and additional fields may follow this, one\n" + " group of fields per line.\n" + "\n" + "Language for the output code:\n" + " -L, --language=LANGUAGE-NAME\n" + " Generates code in the specified language. Languages\n" + " handled are currently C++, ANSI-C, C, and KR-C. The\n" + " default is C.\n" + "\n" + "Details in the output code:\n" + " -K, --slot-name=NAME Select name of the keyword component in the keyword\n" + " structure.\n" + " -F, --initializer-suffix=INITIALIZERS\n" + " Initializers for additional components in the keyword\n" + " structure.\n" + " -H, --hash-fn-name=NAME\n" + " Specify name of generated hash function. Default is\n" + " `hash'.\n" + " -N, --lookup-fn-name=NAME\n" + " Specify name of generated lookup function. Default\n" + " name is `in_word_set'.\n" + " -Z, --class-name=NAME Specify name of generated C++ class. Default name is\n" + " `Perfect_Hash'.\n" + " -7, --seven-bit Assume 7-bit characters.\n" + " -c, --compare-strncmp Generate comparison code using strncmp rather than\n" + " strcmp.\n" + " -C, --readonly-tables Make the contents of generated lookup tables\n" + " constant, i.e., readonly.\n" + " -E, --enum Define constant values using an enum local to the\n" + " lookup function rather than with defines.\n" + " -I, --includes Include the necessary system include file <string.h>\n" + " at the beginning of the code.\n" + " -G, --global Generate the static table of keywords as a static\n" + " global variable, rather than hiding it inside of the\n" + " lookup function (which is the default behavior).\n" + " -W, --word-array-name=NAME\n" + " Specify name of word list array. Default name is\n" + " `wordlist'.\n" + " -S, --switch=COUNT Causes the generated C code to use a switch\n" + " statement scheme, rather than an array lookup table.\n" + " This can lead to a reduction in both time and space\n" + " requirements for some keyfiles. The COUNT argument\n" + " determines how many switch statements are generated.\n" + " A value of 1 generates 1 switch containing all the\n" + " elements, a value of 2 generates 2 tables with 1/2\n" + " the elements in each table, etc. If COUNT is very\n" + " large, say 1000000, the generated C code does a\n" + " binary search.\n" + " -T, --omit-struct-type\n" + " Prevents the transfer of the type declaration to the\n" + " output file. Use this option if the type is already\n" + " defined elsewhere.\n" + "\n" + "Algorithm employed by gperf:\n" + " -k, --key-positions=KEYS\n" + " Select the key positions used in the hash function.\n" + " The allowable choices range between 1-%d, inclusive.\n" + " The positions are separated by commas, ranges may be\n" + " used, and key positions may occur in any order.\n" + " Also, the meta-character '*' causes the generated\n" + " hash function to consider ALL key positions, and $\n" + " indicates the ``final character'' of a key, e.g.,\n" + " $,1,2,4,6-10.\n" + " -l, --compare-strlen Compare key lengths before trying a string\n" + " comparison. This helps cut down on the number of\n" + " string comparisons made during the lookup.\n" + " -D, --duplicates Handle keywords that hash to duplicate values. This\n" + " is useful for certain highly redundant keyword sets.\n" + " -f, --fast=ITERATIONS Generate the gen-perf.hash function ``fast''. This\n" + " decreases gperf's running time at the cost of\n" + " minimizing generated table size. The numeric\n" + " argument represents the number of times to iterate\n" + " when resolving a collision. `0' means ``iterate by\n" + " the number of keywords''.\n" + " -i, --initial-asso=N Provide an initial value for the associate values\n" + " array. Default is 0. Setting this value larger helps\n" + " inflate the size of the final table.\n" + " -j, --jump=JUMP-VALUE Affects the ``jump value'', i.e., how far to advance\n" + " the associated character value upon collisions. Must\n" + " be an odd number, default is %d.\n" + " -n, --no-strlen Do not include the length of the keyword when\n" + " computing the hash function.\n" + " -o, --occurrence-sort Reorders input keys by frequency of occurrence of\n" + " the key sets. This should decrease the search time\n" + " dramatically.\n" + " -r, --random Utilizes randomness to initialize the associated\n" + " values table.\n" + " -s, --size-multiple=N Affects the size of the generated hash table. The\n" + " numeric argument N indicates ``how many times larger\n" + " or smaller'' the associated value range should be,\n" + " in relationship to the number of keys, e.g. a value\n" + " of 3 means ``allow the maximum associated value to\n" + " be about 3 times larger than the number of input\n" + " keys.'' Conversely, a value of -3 means ``make the\n" + " maximum associated value about 3 times smaller than\n" + " the number of input keys. A larger table should\n" + " decrease the time required for an unsuccessful\n" + " search, at the expense of extra table space. Default\n" + " value is 1.\n" + "\n" + "Informative output:\n" + " -h, --help Print this message.\n" + " -v, --version Print the gperf version number.\n" + " -d, --debug Enables the debugging option (produces verbose\n" + " output to the standard error).\n" + "\n" + "Report bugs to <bug-gnu-utils@gnu.org>.\n" + , program_name, MAX_KEY_POS - 1, DEFAULT_JUMP_VALUE); +} + +/* Output command-line Options. */ + +void +Options::print_options (void) +{ + T (Trace t ("Options::print_options");) + int i; + + printf ("/* Command-line: "); + + for (i = 0; i < argument_count; i++) + { + const char *arg = argument_vector[i]; + + /* Escape arg if it contains shell metacharacters. */ + if (*arg == '-') + { + putchar (*arg); + arg++; + if (*arg >= 'A' && *arg <= 'Z' || *arg >= 'a' && *arg <= 'z') + { + putchar (*arg); + arg++; + } + } + if (strpbrk (arg, "\t\n !\"#$&'()*;<>?[\\]`{|}~") != NULL) + { + if (strchr (arg, '\'') != NULL) + { + putchar ('"'); + for (; *arg; arg++) + { + if (*arg == '\"' || *arg == '\\' || *arg == '$') + putchar ('\\'); + putchar (*arg); + } + putchar ('"'); + } + else + { + putchar ('\''); + for (; *arg; arg++) + { + if (*arg == '\\') + putchar ('\\'); + putchar (*arg); + } + putchar ('\''); + } + } + else + printf ("%s", arg); + + printf (" "); + } + + printf (" */"); +} + +/* 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. */ + +inline int +Options::key_sort (char *base, int len) +{ + T (Trace t ("Options::key_sort");) + 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; +} + +/* Sets the default Options. */ + +Options::Options (void) +{ + T (Trace t ("Options::Options");) + key_positions[0] = WORD_START; + key_positions[1] = WORD_END; + key_positions[2] = EOS; + total_keysig_size = 2; + delimiters = DEFAULT_DELIMITERS; + jump = DEFAULT_JUMP_VALUE; + option_word = DEFAULTCHARS | C; + function_name = DEFAULT_NAME; + key_name = DEFAULT_KEY; + initializer_suffix = DEFAULT_INITIALIZER_SUFFIX; + hash_name = DEFAULT_HASH_NAME; + wordlist_name = DEFAULT_WORDLIST_NAME; + class_name = DEFAULT_CLASS_NAME; + total_switches = size = 1; + initial_asso_value = iterations = 0; +} + +/* Dumps option status when debug is set. */ + +Options::~Options (void) +{ + T (Trace t ("Options::~Options");) + if (option_word & DEBUG) + { + char *ptr; + + fprintf (stderr, "\ndumping Options:" + "\nDEBUG is.......: %s" + "\nORDER is.......: %s" + "\nTYPE is........: %s" + "\nRANDOM is......: %s" + "\nDEFAULTCHARS is: %s" + "\nSWITCH is......: %s" + "\nNOLENGTH is....: %s" + "\nLENTABLE is....: %s" + "\nDUP is.........: %s" + "\nFAST is........: %s" + "\nCOMP is........: %s" + "\nNOTYPE is......: %s" + "\nGLOBAL is......: %s" + "\nCONST is.......: %s" + "\nKRC is.........: %s" + "\nC is...........: %s" + "\nANSIC is.......: %s" + "\nCPLUSPLUS is...: %s" + "\nENUM is........: %s" + "\nINCLUDE is.....: %s" + "\nSEVENBIT is....: %s" + "\niterations = %d" + "\nlookup function name = %s" + "\nhash function name = %s" + "\nword list name = %s" + "\nkey name = %s" + "\ninitializer suffix = %s" + "\njump value = %d" + "\nmax associated value = %d" + "\ninitial associated value = %d" + "\ndelimiters = %s" + "\nnumber of switch statements = %d\n", + option_word & DEBUG ? "enabled" : "disabled", + option_word & ORDER ? "enabled" : "disabled", + option_word & TYPE ? "enabled" : "disabled", + option_word & RANDOM ? "enabled" : "disabled", + option_word & DEFAULTCHARS ? "enabled" : "disabled", + option_word & SWITCH ? "enabled" : "disabled", + option_word & NOLENGTH ? "enabled" : "disabled", + option_word & LENTABLE ? "enabled" : "disabled", + option_word & DUP ? "enabled" : "disabled", + option_word & FAST ? "enabled" : "disabled", + option_word & COMP ? "enabled" : "disabled", + option_word & NOTYPE ? "enabled" : "disabled", + option_word & GLOBAL ? "enabled" : "disabled", + option_word & CONST ? "enabled" : "disabled", + option_word & KRC ? "enabled" : "disabled", + option_word & C ? "enabled" : "disabled", + option_word & ANSIC ? "enabled" : "disabled", + option_word & CPLUSPLUS ? "enabled" : "disabled", + option_word & ENUM ? "enabled" : "disabled", + option_word & INCLUDE ? "enabled" : "disabled", + option_word & SEVENBIT ? "enabled" : "disabled", + iterations, + function_name, hash_name, wordlist_name, key_name, + initializer_suffix, jump, size - 1, initial_asso_value, + delimiters, total_switches); + if (option_word & ALLCHARS) + fprintf (stderr, "all characters are used in the hash function\n"); + + fprintf (stderr, "maximum keysig size = %d\nkey positions are: \n", + total_keysig_size); + + for (ptr = 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_word. */ + +static const struct option long_options[] = +{ + { "delimiters", required_argument, 0, 'e' }, + { "struct-type", no_argument, 0, 't' }, + { "language", required_argument, 0, 'L' }, + { "slot-name", required_argument, 0, 'K' }, + { "initializer-suffix", required_argument, 0, 'F' }, + { "hash-fn-name", required_argument, 0, 'H' }, + { "lookup-fn-name", required_argument, 0, 'N' }, + { "class-name", required_argument, 0, 'Z' }, + { "seven-bit", no_argument, 0, '7' }, + { "compare-strncmp", no_argument, 0, 'c' }, + { "readonly-tables", no_argument, 0, 'C' }, + { "enum", no_argument, 0, 'E' }, + { "includes", no_argument, 0, 'I' }, + { "global", no_argument, 0, 'G' }, + { "word-array-name", required_argument, 0, 'W' }, + { "switch", required_argument, 0, 'S' }, + { "omit-struct-type", no_argument, 0, 'T' }, + { "key-positions", required_argument, 0, 'k' }, + { "compare-strlen", no_argument, 0, 'l' }, + { "duplicates", no_argument, 0, 'D' }, + { "fast", required_argument, 0, 'f' }, + { "initial-asso", required_argument, 0, 'i' }, + { "jump", required_argument, 0, 'j' }, + { "no-strlen", no_argument, 0, 'n' }, + { "occurrence-sort", no_argument, 0, 'o' }, + { "random", no_argument, 0, 'r' }, + { "size-multiple", required_argument, 0, 's' }, + { "help", no_argument, 0, 'h' }, + { "version", no_argument, 0, 'v' }, + { "debug", no_argument, 0, 'd' }, + { 0, no_argument, 0, 0 } +}; + +void +Options::operator() (int argc, char *argv[]) +{ + T (Trace t ("Options::operator()");) + int option_char; + + program_name = argv[0]; + argument_count = argc; + argument_vector = argv; + + while ((option_char = + getopt_long (argument_count, argument_vector, + "adcCDe:Ef:F:gGhH:i:Ij:k:K:lL:nN:oprs:S:tTvW:Z:7", + long_options, (int *)0)) + != -1) + { + switch (option_char) + { + case 'a': /* Generated code uses the ANSI prototype format. */ + break; /* This is now the default. */ + case 'c': /* Generate strncmp rather than strcmp. */ + { + option_word |= COMP; + break; + } + case 'C': /* Make the generated tables readonly (const). */ + { + option_word |= CONST; + break; + } + case 'd': /* Enable debugging option. */ + { + option_word |= DEBUG; + fprintf (stderr, "Starting program %s, version %s, with debugging on.\n", + program_name, version_string); + break; + } + case 'D': /* Enable duplicate option. */ + { + option_word |= DUP; + break; + } + case 'e': /* Allows user to provide keyword/attribute separator */ + { + option.delimiters = /*getopt*/optarg; + break; + } + case 'E': + { + option_word |= ENUM; + break; + } + case 'f': /* Generate the hash table ``fast.'' */ + { + option_word |= FAST; + if ((iterations = atoi (/*getopt*/optarg)) < 0) + { + fprintf (stderr, "iterations value must not be negative, assuming 0\n"); + iterations = 0; + } + break; + } + case 'F': + { + initializer_suffix = /*getopt*/optarg; + break; + } + case 'g': /* Use the ``inline'' keyword for generated sub-routines, ifdef __GNUC__. */ + break; /* This is now the default. */ + case 'G': /* Make the keyword table a global variable. */ + { + option_word |= GLOBAL; + break; + } + case 'h': /* Displays a list of helpful Options to the user. */ + { + long_usage (stdout); + exit (0); + } + case 'H': /* Sets the name for the hash function */ + { + hash_name = /*getopt*/optarg; + break; + } + case 'i': /* Sets the initial value for the associated values array. */ + { + if ((initial_asso_value = atoi (/*getopt*/optarg)) < 0) + fprintf (stderr, "Initial value %d should be non-zero, ignoring and continuing.\n", initial_asso_value); + if (option[RANDOM]) + fprintf (stderr, "warning, -r option superceeds -i, ignoring -i option and continuing\n"); + break; + } + case 'I': /* Enable #include statements. */ + { + option_word |= INCLUDE; + break; + } + case 'j': /* Sets the jump value, must be odd for later algorithms. */ + { + if ((jump = atoi (/*getopt*/optarg)) < 0) + { + fprintf (stderr, "Jump value %d must be a positive number.\n", jump); + short_usage (stderr); + exit (1); + } + else if (jump && ((jump % 2) == 0)) + fprintf (stderr, "Jump value %d should be odd, adding 1 and continuing...\n", jump++); + break; + } + case 'k': /* Sets key positions used for hash function. */ + { + const int BAD_VALUE = -1; + int value; + Iterator expand (/*getopt*/optarg, 1, MAX_KEY_POS - 1, WORD_END, BAD_VALUE, EOS); + + if (/*getopt*/optarg [0] == '*') /* Use all the characters for hashing!!!! */ + option_word = (option_word & ~DEFAULTCHARS) | ALLCHARS; + else + { + char *key_pos; + + for (key_pos = key_positions; (value = expand ()) != EOS; key_pos++) + if (value == BAD_VALUE) + { + fprintf (stderr, "Illegal key value or range, use 1,2,3-%d,'$' or '*'.\n", + MAX_KEY_POS - 1); + short_usage (stderr); + exit (1); + } + else + *key_pos = value;; + + *key_pos = EOS; + + if (! (total_keysig_size = (key_pos - key_positions))) + { + fprintf (stderr, "No keys selected.\n"); + short_usage (stderr); + exit (1); + } + else if (! key_sort (key_positions, total_keysig_size)) + { + fprintf (stderr, "Duplicate keys selected\n"); + short_usage (stderr); + exit (1); + } + + if (total_keysig_size != 2 + || (key_positions[0] != 1 || key_positions[1] != WORD_END)) + option_word &= ~DEFAULTCHARS; + } + break; + } + case 'K': /* Make this the keyname for the keyword component field. */ + { + key_name = /*getopt*/optarg; + break; + } + case 'l': /* Create length table to avoid extra string compares. */ + { + option_word |= LENTABLE; + break; + } + case 'L': /* Deal with different generated languages. */ + { + option_word &= ~(KRC | C | ANSIC | CPLUSPLUS); + if (!strcmp (/*getopt*/optarg, "KR-C")) + option_word |= KRC; + else if (!strcmp (/*getopt*/optarg, "C")) + option_word |= C; + else if (!strcmp (/*getopt*/optarg, "ANSI-C")) + option_word |= ANSIC; + else if (!strcmp (/*getopt*/optarg, "C++")) + option_word |= CPLUSPLUS; + else + { + fprintf (stderr, "unsupported language option %s, defaulting to C\n", /*getopt*/optarg); + option_word |= C; + } + break; + } + case 'n': /* Don't include the length when computing hash function. */ + { + option_word |= NOLENGTH; + break; + } + case 'N': /* Make generated lookup function name be optarg */ + { + function_name = /*getopt*/optarg; + break; + } + case 'o': /* Order input by frequency of key set occurrence. */ + { + option_word |= ORDER; + break; + } + case 'p': /* Generated lookup function a pointer instead of int. */ + break; /* This is now the default. */ + case 'r': /* Utilize randomness to initialize the associated values table. */ + { + option_word |= RANDOM; + if (option.initial_asso_value != 0) + fprintf (stderr, "warning, -r option superceeds -i, disabling -i option and continuing\n"); + break; + } + case 's': /* Range of associated values, determines size of final table. */ + { + if (abs (size = atoi (/*getopt*/optarg)) > 50) + fprintf (stderr, "%d is excessive, did you really mean this?! (try `%s --help' for help)\n", size, program_name); + break; + } + case 'S': /* Generate switch statement output, rather than lookup table. */ + { + option_word |= SWITCH; + if ((option.total_switches = atoi (/*getopt*/optarg)) <= 0) + { + fprintf (stderr, "number of switches %s must be a positive number\n", /*getopt*/optarg); + short_usage (stderr); + exit (1); + } + break; + } + case 't': /* Enable the TYPE mode, allowing arbitrary user structures. */ + { + option_word |= TYPE; + break; + } + case 'T': /* Don't print structure definition. */ + { + option_word |= NOTYPE; + break; + } + case 'v': /* Print out the version and quit. */ + fprintf (stdout, "GNU gperf %s\n", version_string); + exit (0); + case 'W': /* Sets the name for the hash table array */ + { + wordlist_name = /*getopt*/optarg; + break; + } + case 'Z': /* Set the class name. */ + { + class_name = /*getopt*/optarg; + break; + } + case '7': /* Assume 7-bit characters. */ + { + option_word |= SEVENBIT; + Vectors::ALPHA_SIZE = 128; + break; + } + default: + short_usage (stderr); + exit (1); + } + + } + + if (argv[/*getopt*/optind] && ! freopen (argv[/*getopt*/optind], "r", stdin)) + { + fprintf (stderr, "Cannot open keyword file `%s'\n", argv[/*getopt*/optind]); + short_usage (stderr); + exit (1); + } + + if (++/*getopt*/optind < argc) + { + fprintf (stderr, "Extra trailing arguments to %s.\n", program_name); + short_usage (stderr); + exit (1); + } +} + +#ifndef __OPTIMIZE__ + +#define INLINE /* not inline */ +#include "options.icc" +#undef INLINE + +#endif /* not defined __OPTIMIZE__ */ diff --git a/contrib/gperf/src/options.h b/contrib/gperf/src/options.h new file mode 100644 index 0000000..9025c86 --- /dev/null +++ b/contrib/gperf/src/options.h @@ -0,0 +1,159 @@ +/* This may look like C code, but it is really -*- C++ -*- */ + +/* Handles parsing the Options provided to the user. + + Copyright (C) 1989-1998, 2000 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +/* This module provides a uniform interface to the various options available + to a user of the gperf 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 1 + +#include <stdio.h> + +/* Enumerate the potential debugging Options. */ + +enum Option_Type +{ + DEBUG = 01, /* Enable debugging (prints diagnostics to stderr). */ + ORDER = 02, /* Apply ordering heuristic to speed-up search time. */ + ALLCHARS = 04, /* Use all characters in hash function. */ + TYPE = 010, /* Handle user-defined type structured keyword input. */ + RANDOM = 020, /* Randomly initialize the associated values table. */ + DEFAULTCHARS = 040, /* Make default char positions be 1,$ (end of keyword). */ + SWITCH = 0100, /* Generate switch output to save space. */ + NOLENGTH = 0200, /* Don't include keyword length in hash computations. */ + LENTABLE = 0400, /* Generate a length table for string comparison. */ + DUP = 01000, /* Handle duplicate hash values for keywords. */ + FAST = 02000, /* Generate the hash function ``fast.'' */ + NOTYPE = 04000, /* Don't include user-defined type definition in output -- it's already defined elsewhere. */ + COMP = 010000, /* Generate strncmp rather than strcmp. */ + GLOBAL = 020000, /* Make the keyword table a global variable. */ + CONST = 040000, /* Make the generated tables readonly (const). */ + KRC = 0100000, /* Generate K&R C code: no prototypes, no const. */ + C = 0200000, /* Generate C code: no prototypes, but const (user can #define it away). */ + ANSIC = 0400000, /* Generate ISO/ANSI C code: prototypes and const, but no class. */ + CPLUSPLUS = 01000000, /* Generate C++ code: prototypes, const, class, inline, enum. */ + ENUM = 02000000, /* Use enum for constants. */ + INCLUDE = 04000000, /* Generate #include statements. */ + SEVENBIT = 010000000 /* Assume 7-bit, not 8-bit, characters. */ +}; + +/* Define some useful constants (these don't really belong here, but I'm + not sure where else to put them!). These should be consts, but g++ + doesn't seem to do the right thing with them at the moment... ;-( */ + +enum +{ + MAX_KEY_POS = 128 - 1, /* Max size of each word's key set. */ + WORD_START = 1, /* Signals the start of a word. */ + WORD_END = 0, /* Signals the end of a word. */ + EOS = MAX_KEY_POS /* Signals end of the key list. */ +}; + +/* Class manager for gperf program Options. */ + +class Options +{ +public: + Options (void); + ~Options (void); + int operator[] (Option_Type option); + void operator() (int argc, char *argv[]); + void operator= (enum Option_Type); + void operator!= (enum Option_Type); + static void print_options (void); + static void set_asso_max (int r); + static int get_asso_max (void); + static void reset (void); + static int get (void); + static int get_iterations (void); + static int get_max_keysig_size (void); + static void set_keysig_size (int); + static int get_jump (void); + static int initial_value (void); + static int get_total_switches (void); + static const char *get_function_name (void); + static const char *get_key_name (void); + static const char *get_initializer_suffix (void); + static const char *get_class_name (void); + static const char *get_hash_name (void); + static const char *get_wordlist_name (void); + static const char *get_delimiter (void); + +private: + static int option_word; /* Holds the user-specified Options. */ + static int total_switches; /* Number of switch statements to generate. */ + static int total_keysig_size; /* Total number of distinct key_positions. */ + static int size; /* Range of the hash table. */ + static int key_pos; /* Tracks current key position for Iterator. */ + static int jump; /* Jump length when trying alternative values. */ + static int initial_asso_value; /* Initial value for asso_values table. */ + static int argument_count; /* Records count of command-line arguments. */ + static int iterations; /* Amount to iterate when a collision occurs. */ + static char **argument_vector; /* Stores a pointer to command-line vector. */ + static const char *function_name; /* Names used for generated lookup function. */ + static const char *key_name; /* Name used for keyword key. */ + static const char *initializer_suffix; /* Suffix for empty struct initializers. */ + static const char *class_name; /* Name used for generated C++ class. */ + static const char *hash_name; /* Name used for generated hash function. */ + static const char *wordlist_name; /* Name used for hash table array. */ + static const char *delimiters; /* Separates keywords from other attributes. */ + static char key_positions[MAX_KEY_POS]; /* Contains user-specified key choices. */ + static int key_sort (char *base, int len); /* Sorts key positions in REVERSE order. */ + static void short_usage (FILE * strm); /* Prints proper program usage. */ + static void long_usage (FILE * strm); /* Prints proper program usage. */ +}; + +/* Global option coordinator for the entire program. */ +extern Options option; + +/* Set to 1 if your want to stack-allocate some large arrays. + This requires compiler support for variable-size arrays on the stack + (not ANSI). */ +#ifndef LARGE_STACK_ARRAYS +#if defined(__GNUG__) && !defined(__STRICT_ANSI__) +#define LARGE_STACK_ARRAYS 1 +#else +#define LARGE_STACK_ARRAYS 0 +#endif +#endif + +/* Set to 1 if the stack is large enough for holding a text line. */ +#ifndef LARGE_STACK +#define LARGE_STACK 1 +#endif + +#ifdef __OPTIMIZE__ + +#include "trace.h" +#define INLINE inline +#include "options.icc" +#undef INLINE + +#endif + +#endif diff --git a/contrib/gperf/src/options.icc b/contrib/gperf/src/options.icc new file mode 100644 index 0000000..82fe537 --- /dev/null +++ b/contrib/gperf/src/options.icc @@ -0,0 +1,183 @@ +/* Inline Functions for options.{h,cc}. + + Copyright (C) 1989-1998, 2000 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +// This needs: +//#include "trace.h" + +/* TRUE if option enable, else FALSE. */ +INLINE int +Options::operator[] (Option_Type option) +{ + T (Trace t ("Options::operator[]");) + return option_word & option; +} + +/* Enables option OPT. */ +INLINE void +Options::operator = (enum Option_Type opt) +{ + T (Trace t ("Options::operator=");) + option_word |= opt; +} + +/* Disables option OPT. */ +INLINE void +Options::operator != (enum Option_Type opt) +{ + T (Trace t ("Options::operator!=");) + option_word &= ~opt; +} + +/* Initializes the key Iterator. */ +INLINE void +Options::reset (void) +{ + T (Trace t ("Options::reset");) + key_pos = 0; +} + +/* Returns current key_position and advance index. */ +INLINE int +Options::get (void) +{ + T (Trace t ("Options::get");) + return key_positions[key_pos++]; +} + +/* Sets the size of the table size. */ +INLINE void +Options::set_asso_max (int r) +{ + T (Trace t ("Options::set_asso_max");) + size = r; +} + +/* Returns the size of the table size. */ +INLINE int +Options::get_asso_max (void) +{ + T (Trace t ("Options::get_asso_max");) + return size; +} + +/* Returns total distinct key positions. */ +INLINE int +Options::get_max_keysig_size (void) +{ + T (Trace t ("Options::get_max_keysig_size");) + return total_keysig_size; +} + +/* Sets total distinct key positions. */ +INLINE void +Options::set_keysig_size (int size) +{ + T (Trace t ("Options::set_keysig_size");) + total_keysig_size = size; +} + +/* Returns the jump value. */ +INLINE int +Options::get_jump (void) +{ + T (Trace t ("Options::get_jump");) + return jump; +} + +/* Returns the generated function name. */ +INLINE const char * +Options::get_function_name (void) +{ + T (Trace t ("Options::get_function_name");) + return function_name; +} + +/* Returns the keyword key name. */ +INLINE const char * +Options::get_key_name (void) +{ + T (Trace t ("Options::get_key_name");) + return key_name; +} + +/* Returns the struct initializer suffix. */ +INLINE const char * +Options::get_initializer_suffix (void) +{ + T (Trace t ("Options::get_initializer_suffix");) + return initializer_suffix; +} + +/* Returns the hash function name. */ +INLINE const char * +Options::get_hash_name (void) +{ + T (Trace t ("Options::get_hash_name");) + return hash_name; +} + +/* Returns the hash table array name. */ +INLINE const char * +Options::get_wordlist_name (void) +{ + T (Trace t ("Options::get_wordlist_name");) + return wordlist_name; +} + +/* Returns the generated class name. */ +INLINE const char * +Options::get_class_name (void) +{ + T (Trace t ("Options::get_class_name");) + return class_name; +} + +/* Returns the initial associated character value. */ +INLINE int +Options::initial_value (void) +{ + T (Trace t ("Options::initial_value");) + return initial_asso_value; +} + +/* Returns the iterations value. */ +INLINE int +Options::get_iterations (void) +{ + T (Trace t ("Options::get_iterations");) + return iterations; +} + +/* Returns the string used to delimit keywords from other attributes. */ +INLINE const char * +Options::get_delimiter () +{ + T (Trace t ("Options::get_delimiter");) + return delimiters; +} + +/* Gets the total number of switch statements to generate. */ +INLINE int +Options::get_total_switches () +{ + T (Trace t ("Options::get_total_switches");) + return total_switches; +} diff --git a/contrib/gperf/src/read-line.cc b/contrib/gperf/src/read-line.cc new file mode 100644 index 0000000..8cb0971 --- /dev/null +++ b/contrib/gperf/src/read-line.cc @@ -0,0 +1,97 @@ +/* Correctly reads an arbitrarily size string. + + Copyright (C) 1989-1998 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "read-line.h" + +#include <stdlib.h> +#include <string.h> /* declares memcpy() */ +#include "options.h" +#include "trace.h" + +/* Recursively fills up the buffer. */ + +#define CHUNK_SIZE 4096 + +/* CHUNKS is the number of chunks (each of size CHUNK_SIZE) which have + already been read and which are temporarily stored on the stack. + This function reads the remainder of the line, allocates a buffer + for the entire line, fills the part beyond &buffer[chunks*CHUNK_SIZE], + and returns &buffer[chunks*CHUNK_SIZE]. */ + +char * +Read_Line::readln_aux (int chunks) +{ + T (Trace t ("Read_Line::readln_aux");) +#if LARGE_STACK + char buf[CHUNK_SIZE]; +#else + // Note: we don't use new, because that invokes a custom operator new. + char *buf = (char*)malloc(CHUNK_SIZE); + if (buf == NULL) + abort (); +#endif + char *bufptr = buf; + char *ptr; + int c; + + while (c = getc (fp), c != EOF && c != '\n') /* fill the current buffer */ + { + *bufptr++ = c; + if (bufptr - buf == CHUNK_SIZE) + { + if ((ptr = readln_aux (chunks + 1)) != NULL) + + /* prepend remainder to ptr buffer */ + { + ptr -= CHUNK_SIZE; + memcpy (ptr, buf, CHUNK_SIZE); + } + + goto done; + } + } + if (c == EOF && bufptr == buf && chunks == 0) + ptr = NULL; + else + { + size_t s1 = chunks * CHUNK_SIZE; + size_t s2 = bufptr - buf; + + ptr = new char[s1+s2+1]; + ptr += s1; + ptr[s2] = '\0'; + memcpy (ptr, buf, s2); + } + done: +#if !LARGE_STACK + free (buf); +#endif + + return ptr; +} + +#ifndef __OPTIMIZE__ + +#define INLINE /* not inline */ +#include "read-line.icc" +#undef INLINE + +#endif /* not defined __OPTIMIZE__ */ diff --git a/contrib/gperf/src/read-line.h b/contrib/gperf/src/read-line.h new file mode 100644 index 0000000..b243c84 --- /dev/null +++ b/contrib/gperf/src/read-line.h @@ -0,0 +1,53 @@ +/* This may look like C code, but it is really -*- C++ -*- */ + +/* Reads arbitrarily long string from input file, returning it as a + dynamically allocated buffer. + + Copyright (C) 1989-1998 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, 59 Temple Place - Suite 330, Boston, MA 02111, 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 read_line_h +#define read_line_h 1 + +#include <stdio.h> + +class Read_Line +{ +private: + char *readln_aux (int chunks); + FILE *fp; /* FILE pointer to the input stream. */ + +public: + Read_Line (FILE *stream = stdin) : fp (stream) {} + char *get_line (void); +}; + +#ifdef __OPTIMIZE__ + +#include "trace.h" +#define INLINE inline +#include "read-line.icc" +#undef INLINE + +#endif + +#endif diff --git a/contrib/gperf/src/read-line.icc b/contrib/gperf/src/read-line.icc new file mode 100644 index 0000000..cdb5bf6 --- /dev/null +++ b/contrib/gperf/src/read-line.icc @@ -0,0 +1,47 @@ +/* Inline Functions for read-line.{h,cc}. + + Copyright (C) 1989-1998 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +// This needs: +//#include <stdio.h> +//#include "trace.h" + +/* Returns the ``next'' line, ignoring comments beginning with '#'. */ +INLINE char * +Read_Line::get_line (void) +{ + T (Trace t ("Read_Line::get_line");) + int c; + + while ((c = getc (fp)) == '#') + { + while (c = getc (fp), c != EOF && c != '\n') + ; + + if (c == EOF) + return (char *)0; + } + + if (c == EOF) + return (char *)0; + + ungetc (c, stdin); + return readln_aux (0); +} diff --git a/contrib/gperf/src/trace.cc b/contrib/gperf/src/trace.cc new file mode 100644 index 0000000..e571aba --- /dev/null +++ b/contrib/gperf/src/trace.cc @@ -0,0 +1,35 @@ +/* Tracing function calls. + Copyright (C) 1989-1998 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "trace.h" + +#include <stdio.h> + +int Trace::nesting = 0; + +Trace::Trace (const char *n) +{ + fprintf (stderr, "%*scalling %s\n", 3 * nesting++, "", name = n); +} + +Trace::~Trace (void) +{ + fprintf (stderr, "%*sleaving %s\n", 3 * --nesting, "", name); +} diff --git a/contrib/gperf/src/trace.h b/contrib/gperf/src/trace.h new file mode 100644 index 0000000..f16fcc5 --- /dev/null +++ b/contrib/gperf/src/trace.h @@ -0,0 +1,40 @@ +/* Tracing function calls. + Copyright (C) 1989-1998 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#ifndef trace_h +#define trace_h 1 + +#ifdef TRACE +#define T(X) X +#else +#define T(X) +#endif + +class Trace +{ +private: + static int nesting; + const char *name; +public: + Trace (const char *n); + ~Trace (void); +}; + +#endif diff --git a/contrib/gperf/src/vectors.cc b/contrib/gperf/src/vectors.cc new file mode 100644 index 0000000..1da014d --- /dev/null +++ b/contrib/gperf/src/vectors.cc @@ -0,0 +1,25 @@ +/* Static class data members that are shared between several classes. + Copyright (C) 1989-1998 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "vectors.h" + +int Vectors::ALPHA_SIZE = MAX_ALPHA_SIZE; +int Vectors::occurrences[MAX_ALPHA_SIZE]; +int Vectors::asso_values[MAX_ALPHA_SIZE]; diff --git a/contrib/gperf/src/vectors.h b/contrib/gperf/src/vectors.h new file mode 100644 index 0000000..28a1053 --- /dev/null +++ b/contrib/gperf/src/vectors.h @@ -0,0 +1,37 @@ +/* This may look like C code, but it is really -*- C++ -*- */ + +/* Static class data members that are shared between several classes via + inheritance. + + Copyright (C) 1989-1998 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#ifndef vectors_h +#define vectors_h 1 + +static const int MAX_ALPHA_SIZE = 256; + +struct Vectors +{ + static int ALPHA_SIZE; /* Size of alphabet. */ + static int occurrences[MAX_ALPHA_SIZE]; /* Counts occurrences of each key set character. */ + static int asso_values[MAX_ALPHA_SIZE]; /* Value associated with each character. */ +}; + +#endif diff --git a/contrib/gperf/src/version.cc b/contrib/gperf/src/version.cc new file mode 100644 index 0000000..8f07c69 --- /dev/null +++ b/contrib/gperf/src/version.cc @@ -0,0 +1,22 @@ +/* Current program version number. + + Copyright (C) 1989-1998, 2000 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +const char *version_string = "2.7.2"; diff --git a/contrib/gperf/src/version.h b/contrib/gperf/src/version.h new file mode 100644 index 0000000..4ffba2e --- /dev/null +++ b/contrib/gperf/src/version.h @@ -0,0 +1,23 @@ +/* Current program version number. + + Copyright (C) 1989-1998 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +/* Current release version. */ +extern const char *version_string; diff --git a/contrib/gperf/tests/Makefile.in b/contrib/gperf/tests/Makefile.in new file mode 100644 index 0000000..a7e3be0 --- /dev/null +++ b/contrib/gperf/tests/Makefile.in @@ -0,0 +1,232 @@ +# Makefile for gperf/tests + +# Copyright (C) 1989, 1992, 1993, 1995, 1998 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, 59 Temple Place - Suite 330, Boston, MA 02111, USA. + +#### Start of system configuration section. #### + +# Directories used by "make": +srcdir = @srcdir@ + +# Programs used by "make": +# C compiler +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +# C++ compiler +CXX = @CXX@ +CXXFLAGS = @CXXFLAGS@ +CXXCPP = @CXXCPP@ +# Other +MV = mv +LN = ln +RM = rm -f +@SET_MAKE@ + +#### End of system configuration section. #### + +SHELL = /bin/sh + +VPATH = $(srcdir) + +GPERF = ../src/gperf + +all : + +install : all + +installdirs : + +uninstall : + +check : check-link-c check-link-c++ check-c check-ada check-modula3 check-pascal check-test + @true + +extracheck : @CHECK_LANG_SYNTAX@ + @true + +check-link-c: force + @echo "performing some tests of the perfect hash generator" + $(CC) -c $(CFLAGS) $(srcdir)/test.c + $(GPERF) -p -c -l -S1 -o $(srcdir)/c.gperf > cinset.c + $(CC) $(CFLAGS) -o cout cinset.c test.o + +check-link-c++: force + +check-c: + @echo "testing ANSI C reserved words, all items should be found in the set" + ./cout -v < $(srcdir)/c.gperf > c.out + diff $(srcdir)/c.exp c.out + +check-ada: + $(GPERF) -k1,4,'$$' $(srcdir)/ada.gperf > adainset.c +# double '$$' is only there since make gets confused; program wants only 1 '$' + $(CC) $(CFLAGS) -o aout adainset.c test.o + @echo "testing Ada reserved words, all items should be found in the set" + ./aout -v < $(srcdir)/ada.gperf > ada-res.out + diff $(srcdir)/ada-res.exp ada-res.out + $(GPERF) -p -D -k1,'$$' -s 2 -o $(srcdir)/adadefs.gperf > preinset.c + $(CC) $(CFLAGS) -o preout preinset.c test.o + @echo "testing Ada predefined words, all items should be found in the set" + ./preout -v < $(srcdir)/adadefs.gperf > ada-pred.out + diff $(srcdir)/ada-pred.exp ada-pred.out + +check-modula3: + $(GPERF) -k1,2,'$$' -o $(srcdir)/modula3.gperf > m3inset.c + $(CC) $(CFLAGS) -o m3out m3inset.c test.o + @echo "testing Modula3 reserved words, all items should be found in the set" + ./m3out -v < $(srcdir)/modula3.gperf > modula.out + diff $(srcdir)/modula.exp modula.out + +check-pascal: + $(GPERF) -o -S2 -p < $(srcdir)/pascal.gperf > pinset.c + $(CC) $(CFLAGS) -o pout pinset.c test.o + @echo "testing Pascal reserved words, all items should be found in the set" + ./pout -v < $(srcdir)/pascal.gperf > pascal.out + diff $(srcdir)/pascal.exp pascal.out + +# these next 5 are demos that show off the generated code +check-test: + $(GPERF) -p -j1 -g -o -t -N is_reserved_word -k1,3,'$$' < $(srcdir)/c-parse.gperf > test-1.out + diff $(srcdir)/test-1.exp test-1.out + $(GPERF) -n -k1-8 -l < $(srcdir)/modula2.gperf > test-2.out + diff $(srcdir)/test-2.exp test-2.out + $(GPERF) -p -j 1 -o -a -C -g -t -k1,4,$$ < $(srcdir)/gplus.gperf > test-3.out + diff $(srcdir)/test-3.exp test-3.out + $(GPERF) -D -p -t < $(srcdir)/c-parse.gperf > test-4.out + diff $(srcdir)/test-4.exp test-4.out + $(GPERF) -g -o -j1 -t -p -N is_reserved_word < $(srcdir)/gpc.gperf > test-5.out + diff $(srcdir)/test-5.exp test-5.out +# prints out the help message + -$(GPERF) -h > test-6.out 2>&1 + diff $(srcdir)/test-6.exp test-6.out + @echo "only if, do, for, case, goto, else, while, and return should be found " + ./aout -v < $(srcdir)/c.gperf > test-7.out + diff $(srcdir)/test-7.exp test-7.out + +# The following validates valid language syntax with different parameters. +# Works only with gcc and g++, and only on platforms where "gcc -ansi" is +# usable. (There are still platforms where gcc-2.8.0's fixincludes does not +# work well enough.) + +VALIDATE = CC='$(CC)' CFLAGS='$(CFLAGS)' CXX='$(CXX)' CXXFLAGS='$(CXXFLAGS)' GPERF='$(GPERF)' ./validate + +check-lang-syntax : force + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -c + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -C + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -E + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -G + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -G -C + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -G -E + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -l + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -D + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -D -l + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -S 10 + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -S 10 -c + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -S 10 -C + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -S 10 -E + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -S 10 -G + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -S 10 -l + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -S 10 -D + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -S 10 -D -l + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -S 1000 + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -p + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -p -C + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -p -l + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -p -D + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -p -D -l + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -p -S 10 + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -p -S 10 -C + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -p -S 10 -l + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -p -S 10 -D + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -p -S 10 -D -l + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -p -S 1000 + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -K key_name + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -H hash_function_name + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest1.gperf -W word_list_name + sed -e 's,in_word_set,lookup_function_name,g' < jstest1.gperf > tmp-jstest1.gperf && \ + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 tmp-jstest1.gperf -N lookup_function_name + sed -e 's,Perfect_Hash,class_name,g' < jstest1.gperf > tmp-jstest1.gperf && \ + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 tmp-jstest1.gperf -Z class_name + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -c + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -C + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -E + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -G + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -G -C + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -G -E + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -l + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -D + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -D -l + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -S 10 + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -S 10 -c + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -S 10 -C + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -S 10 -E + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -S 10 -G + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -S 10 -l + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -S 10 -D + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -S 10 -D -l + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -S 1000 + sed -e 's,name,key_name,g' < jstest2.gperf > tmp-jstest2.gperf && \ + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 tmp-jstest2.gperf -t -p -K key_name + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 jstest2.gperf -t -p -H hash_function_name + sed -e 's,in_word_set,lookup_function_name,g' < jstest2.gperf > tmp-jstest2.gperf && \ + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 tmp-jstest2.gperf -t -p -N lookup_function_name + sed -e 's,Perfect_Hash,class_name,g' < jstest2.gperf > tmp-jstest2.gperf && \ + $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 tmp-jstest2.gperf -t -p -Z class_name + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -c + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -C + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -E + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -G + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -G -C + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -G -E + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -l + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -D + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -D -l + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -S 10 + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -S 10 -c + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -S 10 -C + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -S 10 -E + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -S 10 -G + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -S 10 -l + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -S 10 -D + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -S 10 -D -l + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -S 1000 + sed -e 's,name,key_name,g' < jstest3.gperf > tmp-jstest3.gperf && \ + $(VALIDATE) C,ANSI-C,C++ -k1,2 tmp-jstest3.gperf -t -p -K key_name + $(VALIDATE) C,ANSI-C,C++ -k1,2 jstest3.gperf -t -p -H hash_function_name + sed -e 's,in_word_set,lookup_function_name,g' < jstest3.gperf > tmp-jstest3.gperf && \ + $(VALIDATE) C,ANSI-C,C++ -k1,2 tmp-jstest3.gperf -t -p -N lookup_function_name + sed -e 's,Perfect_Hash,class_name,g' < jstest3.gperf > tmp-jstest3.gperf && \ + $(VALIDATE) C,ANSI-C,C++ -k1,2 tmp-jstest3.gperf -t -p -Z class_name + +mostlyclean : clean + +clean : force + $(RM) *.o core *inset.c output.* *.out aout cout m3out pout preout tmp-* valitest* + +distclean : clean + $(RM) config.status config.log config.cache Makefile + +maintainer-clean : distclean + +force : + diff --git a/contrib/gperf/tests/ada-pred.exp b/contrib/gperf/tests/ada-pred.exp new file mode 100644 index 0000000..33caaa3 --- /dev/null +++ b/contrib/gperf/tests/ada-pred.exp @@ -0,0 +1,54 @@ +in word set boolean +in word set character +in word set constraint_error +in word set false +in word set float +in word set integer +in word set natural +in word set numeric_error +in word set positive +in word set program_error +in word set storage_error +in word set string +in word set tasking_error +in word set true +in word set address +in word set aft +in word set base +in word set callable +in word set constrained +in word set count +in word set delta +in word set digits +in word set emax +in word set epsilon +in word set first +in word set firstbit +in word set fore +in word set image +in word set large +in word set last +in word set lastbit +in word set length +in word set machine_emax +in word set machine_emin +in word set machine_mantissa +in word set machine_overflows +in word set machine_radix +in word set machine_rounds +in word set mantissa +in word set pos +in word set position +in word set pred +in word set range +in word set safe_emax +in word set safe_large +in word set safe_small +in word set size +in word set small +in word set storage_size +in word set succ +in word set terminated +in word set val +in word set value +in word set width diff --git a/contrib/gperf/tests/ada-res.exp b/contrib/gperf/tests/ada-res.exp new file mode 100644 index 0000000..8134fe8 --- /dev/null +++ b/contrib/gperf/tests/ada-res.exp @@ -0,0 +1,63 @@ +in word set else +in word set exit +in word set terminate +in word set type +in word set raise +in word set range +in word set reverse +in word set declare +in word set end +in word set record +in word set exception +in word set not +in word set then +in word set return +in word set separate +in word set select +in word set digits +in word set renames +in word set subtype +in word set elsif +in word set function +in word set for +in word set package +in word set procedure +in word set private +in word set while +in word set when +in word set new +in word set entry +in word set delay +in word set case +in word set constant +in word set at +in word set abort +in word set accept +in word set and +in word set delta +in word set access +in word set abs +in word set pragma +in word set array +in word set use +in word set out +in word set do +in word set others +in word set of +in word set or +in word set all +in word set limited +in word set loop +in word set null +in word set task +in word set in +in word set is +in word set if +in word set rem +in word set mod +in word set begin +in word set body +in word set xor +in word set goto +in word set generic +in word set with diff --git a/contrib/gperf/tests/ada.gperf b/contrib/gperf/tests/ada.gperf new file mode 100644 index 0000000..332bdc7 --- /dev/null +++ b/contrib/gperf/tests/ada.gperf @@ -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 diff --git a/contrib/gperf/tests/adadefs.gperf b/contrib/gperf/tests/adadefs.gperf new file mode 100644 index 0000000..875be69 --- /dev/null +++ b/contrib/gperf/tests/adadefs.gperf @@ -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 diff --git a/contrib/gperf/tests/c++.gperf b/contrib/gperf/tests/c++.gperf new file mode 100644 index 0000000..650d32d --- /dev/null +++ b/contrib/gperf/tests/c++.gperf @@ -0,0 +1,47 @@ +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 diff --git a/contrib/gperf/tests/c-parse.gperf b/contrib/gperf/tests/c-parse.gperf new file mode 100644 index 0000000..d11788c --- /dev/null +++ b/contrib/gperf/tests/c-parse.gperf @@ -0,0 +1,56 @@ +%{ +/* Command-line: gperf -p -j1 -i 1 -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 diff --git a/contrib/gperf/tests/c.exp b/contrib/gperf/tests/c.exp new file mode 100644 index 0000000..10c8b7f --- /dev/null +++ b/contrib/gperf/tests/c.exp @@ -0,0 +1,32 @@ +in word set if +in word set do +in word set int +in word set for +in word set case +in word set char +in word set auto +in word set goto +in word set else +in word set long +in word set void +in word set enum +in word set float +in word set short +in word set union +in word set break +in word set while +in word set const +in word set double +in word set static +in word set extern +in word set struct +in word set return +in word set sizeof +in word set switch +in word set signed +in word set typedef +in word set default +in word set unsigned +in word set continue +in word set register +in word set volatile diff --git a/contrib/gperf/tests/c.gperf b/contrib/gperf/tests/c.gperf new file mode 100644 index 0000000..8672d6c --- /dev/null +++ b/contrib/gperf/tests/c.gperf @@ -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 diff --git a/contrib/gperf/tests/configure b/contrib/gperf/tests/configure new file mode 100755 index 0000000..1c715de --- /dev/null +++ b/contrib/gperf/tests/configure @@ -0,0 +1,1214 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.12 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.12" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=c-parse.gperf + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:523: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:552: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:581: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + ac_prog_rejected=no + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:629: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext <<EOF +#line 639 "configure" +#include "confdefs.h" +main(){return(0);} +EOF +if { (eval echo configure:643: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:663: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:668: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:677: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes + ac_test_CFLAGS="${CFLAGS+set}" + ac_save_CFLAGS="$CFLAGS" + CFLAGS= + echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:692: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 + if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" + elif test $ac_cv_prog_cc_g = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-O2" + fi +else + GCC= + test "${CFLAGS+set}" = set || CFLAGS="-g" +fi + + echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:720: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext <<EOF +#line 735 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:741: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext <<EOF +#line 752 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:758: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + + for ac_prog in $CCC c++ g++ gcc CC cxx cc++ +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:785: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CXX="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CXX="$ac_cv_prog_CXX" +if test -n "$CXX"; then + echo "$ac_t""$CXX" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$CXX" && break +done +test -n "$CXX" || CXX="gcc" + + +echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:816: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 + +ac_ext=C +# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CXX-g++} -o conftest $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cxx_cross + +cat > conftest.$ac_ext <<EOF +#line 826 "configure" +#include "confdefs.h" +main(){return(0);} +EOF +if { (eval echo configure:830: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + ac_cv_prog_cxx_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cxx_cross=no + else + ac_cv_prog_cxx_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cxx_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6 +if test $ac_cv_prog_cxx_works = no; then + { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:856: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6 +cross_compiling=$ac_cv_prog_cxx_cross + +echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 +echo "configure:861: checking whether we are using GNU C++" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.C <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:870: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gxx=yes +else + ac_cv_prog_gxx=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gxx" 1>&6 + +if test $ac_cv_prog_gxx = yes; then + GXX=yes + ac_test_CXXFLAGS="${CXXFLAGS+set}" + ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS= + echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 +echo "configure:885: checking whether ${CXX-g++} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.cc +if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then + ac_cv_prog_cxx_g=yes +else + ac_cv_prog_cxx_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6 + if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS="$ac_save_CXXFLAGS" + elif test $ac_cv_prog_cxx_g = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-O2" + fi +else + GXX= + test "${CXXFLAGS+set}" = set || CXXFLAGS="-g" +fi + + echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6 +echo "configure:913: checking how to run the C++ preprocessor" >&5 +if test -z "$CXXCPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_ext=C +# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CXX-g++} -o conftest $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cxx_cross + CXXCPP="${CXX-g++} -E" + cat > conftest.$ac_ext <<EOF +#line 926 "configure" +#include "confdefs.h" +#include <stdlib.h> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:931: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CXXCPP=/lib/cpp +fi +rm -f conftest* + ac_cv_prog_CXXCPP="$CXXCPP" +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross +fi +fi +CXXCPP="$ac_cv_prog_CXXCPP" +echo "$ac_t""$CXXCPP" 1>&6 + + if test $ac_cv_prog_gcc = yes -a $ac_cv_prog_gxx = yes; then + CHECK_LANG_SYNTAX='check-lang-syntax' +else + CHECK_LANG_SYNTAX='' +fi + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.12" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@CXX@%$CXX%g +s%@CXXCPP@%$CXXCPP%g +s%@CHECK_LANG_SYNTAX@%$CHECK_LANG_SYNTAX%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <<EOF + +EOF +cat >> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/contrib/gperf/tests/configure.in b/contrib/gperf/tests/configure.in new file mode 100644 index 0000000..a62450d --- /dev/null +++ b/contrib/gperf/tests/configure.in @@ -0,0 +1,45 @@ +dnl autoconf configuration for gperf/tests + +dnl Copyright (C) 1998 Free Software Foundation, Inc. +dnl written by Douglas C. Schmidt (schmidt@ics.uci.edu) +dnl +dnl This file is part of GNU GPERF. +dnl +dnl GNU GPERF is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 1, or (at your option) +dnl any later version. +dnl +dnl GNU GPERF is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU GPERF; see the file COPYING. If not, write to the +dnl Free Software Foundation, 59 Temple Place - Suite 330, Boston, +dnl MA 02111-1307, USA. + +AC_INIT(c-parse.gperf) +AC_PROG_MAKE_SET +dnl +dnl checks for programs +dnl +AC_PROG_CC + dnl sets variable CC +AC_PROG_CPP + dnl sets variable CPP +AC_PROG_CXX + dnl sets variable CXX +AC_PROG_CXXCPP + dnl sets variable CXXCPP +if test $ac_cv_prog_gcc = yes -a $ac_cv_prog_gxx = yes; then + CHECK_LANG_SYNTAX='check-lang-syntax' +else + CHECK_LANG_SYNTAX='' +fi +AC_SUBST(CHECK_LANG_SYNTAX) +dnl +dnl That's it. +dnl +AC_OUTPUT(Makefile) diff --git a/contrib/gperf/tests/gpc.gperf b/contrib/gperf/tests/gpc.gperf new file mode 100644 index 0000000..8fb469e --- /dev/null +++ b/contrib/gperf/tests/gpc.gperf @@ -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 diff --git a/contrib/gperf/tests/gplus.gperf b/contrib/gperf/tests/gplus.gperf new file mode 100644 index 0000000..4a93315 --- /dev/null +++ b/contrib/gperf/tests/gplus.gperf @@ -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, diff --git a/contrib/gperf/tests/irc.gperf b/contrib/gperf/tests/irc.gperf new file mode 100644 index 0000000..afe53c5 --- /dev/null +++ b/contrib/gperf/tests/irc.gperf @@ -0,0 +1,63 @@ +%{ +extern int m_text(), m_private(), m_who(), m_whois(), m_user(), m_list(); +extern int m_topic(), m_invite(), m_channel(), m_version(), m_quit(); +extern int m_server(), m_kill(), m_info(), m_links(), m_summon(), m_stats(); +extern int m_users(), m_nick(), m_error(), m_help(), m_whoreply(); +extern int m_squit(), m_restart(), m_away(), m_die(), m_connect(); +extern int m_ping(), m_pong(), m_oper(), m_pass(), m_wall(), m_trace(); +extern int m_time(), m_rehash(), m_names(), m_namreply(), m_admin(); +extern int m_linreply(), m_notice(), m_lusers(), m_voice(), m_grph(); +extern int m_xtra(), m_motd(); +%} +struct Message { + char *cmd; + int (* func)(); + int count; + int parameters; +}; +%% +NICK, m_nick, 0, 1 +MSG, m_text, 0, 1 +PRIVMSG, m_private, 0, 2 +WHO, m_who, 0, 1 +WHOIS, m_whois, 0, 4 +USER, m_user, 0, 4 +SERVER, m_server, 0, 2 +LIST, m_list, 0, 1 +TOPIC, m_topic, 0, 1 +INVITE, m_invite, 0, 2 +CHANNEL, m_channel, 0, 1 +VERSION, m_version, 0, 1 +QUIT, m_quit, 0, 2 +SQUIT, m_squit, 0, 2 +KILL, m_kill, 0, 2 +INFO, m_info, 0, 1 +LINKS, m_links, 0, 1 +SUMMON, m_summon, 0, 1 +STATS, m_stats, 0, 1 +USERS, m_users, 0, 1 +RESTART, m_restart, 0, 1 +WHOREPLY,m_whoreply, 0, 7 +HELP, m_help, 0, 2 +ERROR, m_error, 0, 1 +AWAY, m_away, 0, 1 +DIE, m_die, 0, 1 +CONNECT, m_connect, 0, 3 +PING, m_ping, 0, 2 +PONG, m_pong, 0, 3 +OPER, m_oper, 0, 3 +PASS, m_pass, 0, 2 +WALL, m_wall, 0, 1 +TIME, m_time, 0, 1 +REHASH, m_rehash, 0, 1 +NAMES, m_names, 0, 1 +NAMREPLY,m_namreply, 0, 3 +ADMIN, m_admin, 0, 1 +TRACE, m_trace, 0, 1 +LINREPLY,m_linreply, 0, 2 +NOTICE, m_notice, 0, 2 +LUSERS, m_lusers, 0, 1 +VOICE, m_voice, 0, 2 +GRPH, m_grph, 0, 2 +XTRA, m_xtra, 0, 2 +MOTD, m_motd, 0, 2 diff --git a/contrib/gperf/tests/jscript.gperf b/contrib/gperf/tests/jscript.gperf new file mode 100644 index 0000000..6f420d8 --- /dev/null +++ b/contrib/gperf/tests/jscript.gperf @@ -0,0 +1,73 @@ +%{ +/* Command-line: gperf -k'1,2,$' -t -p -K 'name' -H 'js_kw_hash' -N 'js_kw_lookup' -a -g jscript.gperf */ +%} +struct js_keyword { + char * name; + int token; +} + +%% +# Javascript reserved words, see "keywords.html" +abstract, TK_ABSTRACT +boolean, TK_BOOLEAN +break, TK_BREAK +byte, TK_BYTE +case, TK_CASE +catch, TK_CATCH +char, TK_CHAR +class, TK_CLASS +const, TK_CONST +continue, TK_CONTINUE +default, TK_DEFAULT +do, TK_DO +double, TK_DOUBLE +else, TK_ELSE +extends, TK_EXTENDS +false, TK_FALSE +final, TK_FINAL +finally, TK_FINALLY +float, TK_FLOAT +for, TK_FOR +function, TK_FUNCTION +goto, TK_GOTO +if, TK_IF +implements, TK_IMPLEMENTS +import, TK_IMPORT +in, TK_IN +instanceof, TK_INSTANCEOF +int, TK_INT +interface, TK_INTERFACE +long, TK_LONG +native, TK_NATIVE +new, TK_NEW +null, TK_NULL +package, TK_PACKAGE +private, TK_PRIVATE +protected, TK_PROTECTED +public, TK_PUBLIC +return, TK_RETURN +short, TK_SHORT +static, TK_STATIC +super, TK_SUPER +switch, TK_SWITCH +synchronized, TK_SYNCHRONIZED +this, TK_THIS +throw, TK_THROW +throws, TK_THROWS +transient, TK_TRANSIENT +true, TK_TRUE +try, TK_TRY +var, TK_VAR +void, TK_VOID +while, TK_WHILE +with, TK_WITH +%% + +int js_keyword_lookup (register const char *str, register int len) +{ + struct js_keyword * keyword = js_kw_lookup(str,len); + if (keyword) + return keyword->token; + else + return TK_IDENT; +} diff --git a/contrib/gperf/tests/jstest1.gperf b/contrib/gperf/tests/jstest1.gperf new file mode 100644 index 0000000..f6696b1 --- /dev/null +++ b/contrib/gperf/tests/jstest1.gperf @@ -0,0 +1,142 @@ +abstract +boolean +break +byte +case +catch +char +class +const +continue +default +do +double +else +extends +false +final +finally +float +for +function +goto +if +implements +import +in +instanceof +int +interface +long +native +new +null +package +private +protected +public +return +short +static +super +switch +synchronized +this +throw +throws +transient +true +try +var +void +while +with +%% +#include <stdlib.h> +#include <string.h> +#if defined(__STDC__) || defined(__cplusplus) +#define CONST const +#else +#define CONST +#endif +static CONST char* testdata[] = { + "bogus", + "abstract", + "boolean", + "break", + "byte", + "case", + "catch", + "char", + "class", + "const", + "continue", + "default", + "do", + "double", + "else", + "extends", + "false", + "final", + "finally", + "float", + "for", + "function", + "goto", + "if", + "implements", + "import", + "in", + "instanceof", + "int", + "interface", + "long", + "native", + "new", + "null", + "package", + "private", + "protected", + "public", + "return", + "short", + "static", + "super", + "switch", + "synchronized", + "this", + "throw", + "throws", + "transient", + "true", + "try", + "var", + "void", + "while", + "with" +}; +int main () +{ + int i; + for (i = 0; i < sizeof(testdata)/sizeof(testdata[0]); i++) + { +#ifdef CPLUSPLUS_TEST + CONST char * resword = Perfect_Hash::in_word_set(testdata[i],strlen(testdata[i])); +#else + CONST char * resword = in_word_set(testdata[i],strlen(testdata[i])); +#endif + if (i > 0) + { + if (!resword) + exit (1); + if (strcmp(testdata[i],resword)) + exit (1); + } + else + { + if (resword) + exit (1); + } + } + return 0; +} diff --git a/contrib/gperf/tests/jstest2.gperf b/contrib/gperf/tests/jstest2.gperf new file mode 100644 index 0000000..ee0fa7f --- /dev/null +++ b/contrib/gperf/tests/jstest2.gperf @@ -0,0 +1,147 @@ +struct js_keyword { + char * name; + int token; +} +%% +abstract, 1 +boolean, 2 +break, 3 +byte, 4 +case, 5 +catch, 6 +char, 7 +class, 8 +const, 9 +continue, 10 +default, 11 +do, 12 +double, 13 +else, 14 +extends, 15 +false, 16 +final, 17 +finally, 18 +float, 19 +for, 20 +function, 21 +goto, 22 +if, 23 +implements, 24 +import, 25 +in, 26 +instanceof, 27 +int, 28 +interface, 29 +long, 30 +native, 31 +new, 32 +null, 33 +package, 34 +private, 35 +protected, 36 +public, 37 +return, 38 +short, 39 +static, 40 +super, 41 +switch, 42 +synchronized, 43 +this, 44 +throw, 45 +throws, 46 +transient, 47 +true, 48 +try, 49 +var, 50 +void, 51 +while, 52 +with, 53 +%% +#include <stdlib.h> +#include <string.h> +#if defined(__STDC__) || defined(__cplusplus) +#define CONST const +#else +#define CONST +#endif +static CONST char* testdata[] = { + "bogus", + "abstract", + "boolean", + "break", + "byte", + "case", + "catch", + "char", + "class", + "const", + "continue", + "default", + "do", + "double", + "else", + "extends", + "false", + "final", + "finally", + "float", + "for", + "function", + "goto", + "if", + "implements", + "import", + "in", + "instanceof", + "int", + "interface", + "long", + "native", + "new", + "null", + "package", + "private", + "protected", + "public", + "return", + "short", + "static", + "super", + "switch", + "synchronized", + "this", + "throw", + "throws", + "transient", + "true", + "try", + "var", + "void", + "while", + "with" +}; +int main () +{ + int i; + for (i = 0; i < sizeof(testdata)/sizeof(testdata[0]); i++) + { +#ifdef CPLUSPLUS_TEST + CONST struct js_keyword * resword = Perfect_Hash::in_word_set(testdata[i],strlen(testdata[i])); +#else + CONST struct js_keyword * resword = in_word_set(testdata[i],strlen(testdata[i])); +#endif + if (i > 0) + { + if (!resword) + exit (1); + if (strcmp(testdata[i],resword->name)) + exit (1); + } + else + { + if (resword) + exit (1); + } + } + return 0; +} diff --git a/contrib/gperf/tests/jstest3.gperf b/contrib/gperf/tests/jstest3.gperf new file mode 100644 index 0000000..54d37ce --- /dev/null +++ b/contrib/gperf/tests/jstest3.gperf @@ -0,0 +1,147 @@ +struct js_keyword { + const char * name; + int token; +} +%% +abstract, 1 +boolean, 2 +break, 3 +byte, 4 +case, 5 +catch, 6 +char, 7 +class, 8 +const, 9 +continue, 10 +default, 11 +do, 12 +double, 13 +else, 14 +extends, 15 +false, 16 +final, 17 +finally, 18 +float, 19 +for, 20 +function, 21 +goto, 22 +if, 23 +implements, 24 +import, 25 +in, 26 +instanceof, 27 +int, 28 +interface, 29 +long, 30 +native, 31 +new, 32 +null, 33 +package, 34 +private, 35 +protected, 36 +public, 37 +return, 38 +short, 39 +static, 40 +super, 41 +switch, 42 +synchronized, 43 +this, 44 +throw, 45 +throws, 46 +transient, 47 +true, 48 +try, 49 +var, 50 +void, 51 +while, 52 +with, 53 +%% +#include <stdlib.h> +#include <string.h> +#if defined(__STDC__) || defined(__cplusplus) +#define CONST const +#else +#define CONST +#endif +static CONST char* testdata[] = { + "bogus", + "abstract", + "boolean", + "break", + "byte", + "case", + "catch", + "char", + "class", + "const", + "continue", + "default", + "do", + "double", + "else", + "extends", + "false", + "final", + "finally", + "float", + "for", + "function", + "goto", + "if", + "implements", + "import", + "in", + "instanceof", + "int", + "interface", + "long", + "native", + "new", + "null", + "package", + "private", + "protected", + "public", + "return", + "short", + "static", + "super", + "switch", + "synchronized", + "this", + "throw", + "throws", + "transient", + "true", + "try", + "var", + "void", + "while", + "with" +}; +int main () +{ + int i; + for (i = 0; i < sizeof(testdata)/sizeof(testdata[0]); i++) + { +#ifdef CPLUSPLUS_TEST + CONST struct js_keyword * resword = Perfect_Hash::in_word_set(testdata[i],strlen(testdata[i])); +#else + CONST struct js_keyword * resword = in_word_set(testdata[i],strlen(testdata[i])); +#endif + if (i > 0) + { + if (!resword) + exit (1); + if (strcmp(testdata[i],resword->name)) + exit (1); + } + else + { + if (resword) + exit (1); + } + } + return 0; +} diff --git a/contrib/gperf/tests/makeinfo.gperf b/contrib/gperf/tests/makeinfo.gperf new file mode 100644 index 0000000..1488b8e --- /dev/null +++ b/contrib/gperf/tests/makeinfo.gperf @@ -0,0 +1,116 @@ +COMMAND; +%% +!, cm_force_sentence_end, false +', insert_self, false +*, cm_asterisk, false +., cm_force_sentence_end, false +:, cm_force_abbreviated_whitespace, false +?, cm_force_sentence_end, false +@, insert_self, false +TeX, cm_TeX, true +`, insert_self, false +appendix, cm_appendix, false +appendixsec, cm_appendixsec, false +appendixsubsec, cm_appendixsubsec, false +asis, cm_asis, true +b, cm_bold, true +br, cm_br, false +bullet, cm_bullet, true +bye, cm_bye, false +c, cm_comment, false +center, cm_center, false +chapter, cm_chapter, false +cindex, cm_cindex, false +cite, cm_cite, true +code, cm_code, true +comment, cm_comment, false +contents, do_nothing, false +copyright, cm_copyright, true +ctrl, cm_ctrl, true +defcodeindex, cm_defindex, false +defindex, cm_defindex, false +dfn, cm_dfn, true +display, cm_display, false +dots, cm_dots, true +emph, cm_emph, true +end, cm_end, false +enumerate, cm_enumerate, false +equiv, cm_equiv, true +error, cm_error, true +example, cm_example, false +exdent, cm_exdent, false +expansion, cm_expansion, true +file, cm_file, true +findex, cm_findex, false +format, cm_format, false +group, cm_group, false +i, cm_italic, true +iappendix, cm_appendix, false +iappendixsec, cm_appendixsec, false +iappendixsubsec, cm_appendixsubsec, false +ichapter, cm_chapter, false +ifinfo, cm_ifinfo, false +iftex, cm_iftex, false +ignore, cm_ignore, false +include, cm_include, false +inforef, cm_inforef, true +input, cm_include, false +isection, cm_section, false +isubsection, cm_subsection, false +isubsubsection, cm_subsubsection, false +item, cm_item, false +itemize, cm_itemize, false +itemx, cm_itemx, false +iunnumbered, cm_unnumbered, false +iunnumberedsec, cm_unnumberedsec, false +iunnumberedsubsec, cm_unnumberedsubsec, false +kbd, cm_kbd, true +key, cm_key, true +kindex, cm_kindex, false +lisp, cm_lisp, false +menu, cm_menu +minus, cm_minus, true +need, cm_need, false +node, cm_node, false +noindent, cm_noindent, false +page, do_nothing, false +pindex, cm_pindex, false +point, cm_point, true +print, cm_print, true +printindex, cm_printindex, false +pxref, cm_pxref, true +quotation, cm_quotation, false +r, cm_roman, true +ref, cm_xref, true +refill, cm_refill, false +result, cm_result, true +samp, cm_samp, true +sc, cm_sc, true +section, cm_section, false +setchapternewpage, cm_setchapternewpage, false +setfilename, cm_setfilename, false +settitle, cm_settitle, false +smallexample, cm_smallexample, false +sp, cm_sp, false +strong, cm_strong, true +subsection, cm_subsection, false +subsubsection, cm_subsubsection, false +summarycontents, do_nothing, false +syncodeindex, cm_synindex, false +synindex, cm_synindex, false +t, cm_title, true +table, cm_table, false +tex, cm_tex, false +tindex, cm_tindex, false +titlepage, cm_titlepage, false +unnumbered, cm_unnumbered, false +unnumberedsec, cm_unnumberedsec, false +unnumberedsubsec, cm_unnumberedsubsec, false +var, cm_var, true +vindex, cm_vindex, false +w, cm_w, true +xref, cm_xref, true +{, insert_self, false +}, insert_self, false +infoinclude, cm_infoinclude, false +footnote, cm_footnote, false diff --git a/contrib/gperf/tests/modula.exp b/contrib/gperf/tests/modula.exp new file mode 100644 index 0000000..cef7d5a --- /dev/null +++ b/contrib/gperf/tests/modula.exp @@ -0,0 +1,106 @@ +in word set AND +in word set ARRAY +in word set BEGIN +in word set BITS +in word set BY +in word set CASE +in word set CONST +in word set DIV +in word set DO +in word set ELSE +in word set ELSIF +in word set END +in word set EVAL +in word set EXCEPT +in word set EXCEPTION +in word set EXIT +in word set EXPORTS +in word set FINALLY +in word set FOR +in word set FROM +in word set IF +in word set IMPORT +in word set INTERFACE +in word set IN +in word set INLINE +in word set LOCK +in word set METHODS +in word set MOD +in word set MODULE +in word set NOT +in word set OBJECT +in word set OF +in word set OR +in word set PROCEDURE +in word set RAISES +in word set READONLY +in word set RECORD +in word set REF +in word set REPEAT +in word set RETURN +in word set SET +in word set THEN +in word set TO +in word set TRY +in word set TYPE +in word set TYPECASE +in word set UNSAFE +in word set UNTIL +in word set UNTRACED +in word set VALUE +in word set VAR +in word set WHILE +in word set WITH +in word set and +in word set array +in word set begin +in word set bits +in word set by +in word set case +in word set const +in word set div +in word set do +in word set else +in word set elsif +in word set end +in word set eval +in word set except +in word set exception +in word set exit +in word set exports +in word set finally +in word set for +in word set from +in word set if +in word set import +in word set interface +in word set in +in word set inline +in word set lock +in word set methods +in word set mod +in word set module +in word set not +in word set object +in word set of +in word set or +in word set procedure +in word set raises +in word set readonly +in word set record +in word set ref +in word set repeat +in word set return +in word set set +in word set then +in word set to +in word set try +in word set type +in word set typecase +in word set unsafe +in word set until +in word set untraced +in word set value +in word set var +in word set while +in word set with diff --git a/contrib/gperf/tests/modula2.gperf b/contrib/gperf/tests/modula2.gperf new file mode 100644 index 0000000..5ef9c75 --- /dev/null +++ b/contrib/gperf/tests/modula2.gperf @@ -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 diff --git a/contrib/gperf/tests/modula3.gperf b/contrib/gperf/tests/modula3.gperf new file mode 100644 index 0000000..d024346 --- /dev/null +++ b/contrib/gperf/tests/modula3.gperf @@ -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 diff --git a/contrib/gperf/tests/pascal.exp b/contrib/gperf/tests/pascal.exp new file mode 100644 index 0000000..765e44c --- /dev/null +++ b/contrib/gperf/tests/pascal.exp @@ -0,0 +1,36 @@ +in word set with +in word set array +in word set and +in word set function +in word set case +in word set var +in word set const +in word set until +in word set then +in word set set +in word set record +in word set program +in word set procedure +in word set or +in word set packed +in word set not +in word set nil +in word set label +in word set in +in word set repeat +in word set of +in word set goto +in word set forward +in word set for +in word set while +in word set file +in word set else +in word set downto +in word set do +in word set div +in word set to +in word set type +in word set end +in word set mod +in word set begin +in word set if diff --git a/contrib/gperf/tests/pascal.gperf b/contrib/gperf/tests/pascal.gperf new file mode 100644 index 0000000..fed3fbb --- /dev/null +++ b/contrib/gperf/tests/pascal.gperf @@ -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 diff --git a/contrib/gperf/tests/test-1.exp b/contrib/gperf/tests/test-1.exp new file mode 100644 index 0000000..462fea5 --- /dev/null +++ b/contrib/gperf/tests/test-1.exp @@ -0,0 +1,153 @@ +/* C code produced by gperf version 2.7 */ +/* Command-line: ../src/gperf -p -j1 -g -o -t -N is_reserved_word -k1,3,$ */ +/* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */ +struct resword { char *name; short token; enum rid rid; }; + +#define TOTAL_KEYWORDS 51 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 13 +#define MIN_HASH_VALUE 8 +#define MAX_HASH_VALUE 82 +/* maximum key range = 75, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#endif +static unsigned int +hash (str, len) + register const char *str; + register unsigned int len; +{ + static unsigned char asso_values[] = + { + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 0, 83, 1, 2, 34, + 19, 6, 11, 29, 0, 17, 83, 0, 23, 28, + 26, 30, 31, 83, 15, 1, 0, 28, 13, 4, + 83, 83, 5, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83 + }; + register int hval = len; + + switch (hval) + { + default: + case 3: + hval += asso_values[(unsigned char)str[2]]; + case 2: + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +#ifdef __GNUC__ +__inline +#endif +struct resword * +is_reserved_word (str, len) + register const char *str; + register unsigned int len; +{ + static struct resword wordlist[] = + { + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {"__asm__", ASM, NORID}, + {""}, + {"__typeof__", TYPEOF, NORID}, + {"__signed__", TYPESPEC, RID_SIGNED}, + {"__alignof__", ALIGNOF, NORID}, + {"break", BREAK, NORID}, + {"__attribute__", ATTRIBUTE, NORID}, + {""}, {""}, + {"else", ELSE, NORID}, + {"__attribute", ATTRIBUTE, NORID}, + {"__typeof", TYPEOF, NORID}, + {"int", TYPESPEC, RID_INT}, + {"__alignof", ALIGNOF, NORID}, + {"struct", STRUCT, NORID}, + {"sizeof", SIZEOF, NORID}, + {"switch", SWITCH, NORID}, + {"__volatile__", TYPE_QUAL, RID_VOLATILE}, + {""}, + {"__inline__", SCSPEC, RID_INLINE}, + {"__signed", TYPESPEC, RID_SIGNED}, + {"__volatile", TYPE_QUAL, RID_VOLATILE}, + {"if", IF, NORID}, + {"__inline", SCSPEC, RID_INLINE}, + {"while", WHILE, NORID}, + {""}, + {"__asm", ASM, NORID}, + {"auto", SCSPEC, RID_AUTO}, + {"short", TYPESPEC, RID_SHORT}, + {"default", DEFAULT, NORID}, + {"extern", SCSPEC, RID_EXTERN}, + {""}, {""}, + {"__const", TYPE_QUAL, RID_CONST}, + {"static", SCSPEC, RID_STATIC}, + {"__const__", TYPE_QUAL, RID_CONST}, + {"for", FOR, NORID}, + {"case", CASE, NORID}, + {"float", TYPESPEC, RID_FLOAT}, + {"return", RETURN, NORID}, + {"typeof", TYPEOF, NORID}, + {"typedef", SCSPEC, RID_TYPEDEF}, + {"volatile", TYPE_QUAL, RID_VOLATILE}, + {"do", DO, NORID}, + {"inline", SCSPEC, RID_INLINE}, + {"void", TYPESPEC, RID_VOID}, + {"char", TYPESPEC, RID_CHAR}, + {"signed", TYPESPEC, RID_SIGNED}, + {"unsigned", TYPESPEC, RID_UNSIGNED}, + {""}, {""}, + {"double", TYPESPEC, RID_DOUBLE}, + {"asm", ASM, NORID}, + {""}, {""}, + {"goto", GOTO, NORID}, + {""}, + {"const", TYPE_QUAL, RID_CONST}, + {"enum", ENUM, NORID}, + {"register", SCSPEC, RID_REGISTER}, + {""}, {""}, {""}, {""}, {""}, {""}, + {"continue", CONTINUE, NORID}, + {""}, + {"union", UNION, NORID}, + {""}, {""}, {""}, {""}, {""}, + {"long", TYPESPEC, RID_LONG} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register const char *s = wordlist[key].name; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return &wordlist[key]; + } + } + return 0; +} diff --git a/contrib/gperf/tests/test-2.exp b/contrib/gperf/tests/test-2.exp new file mode 100644 index 0000000..3b9e7b0 --- /dev/null +++ b/contrib/gperf/tests/test-2.exp @@ -0,0 +1,202 @@ +/* C code produced by gperf version 2.7 */ +/* Command-line: ../src/gperf -n -k1-8 -l */ + +#define TOTAL_KEYWORDS 40 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 14 +#define MIN_HASH_VALUE 1 +#define MAX_HASH_VALUE 256 +/* maximum key range = 256, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#endif +static unsigned int +hash (str, len) + register const char *str; + register unsigned int len; +{ + static unsigned short asso_values[] = + { + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 25, 30, 35, 21, 0, + 30, 15, 30, 45, 257, 257, 0, 5, 45, 0, + 10, 0, 1, 20, 25, 15, 30, 40, 15, 5, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257 + }; + register int hval = 0; + + switch (len) + { + default: + case 8: + hval += asso_values[(unsigned char)str[7]]; + case 7: + hval += asso_values[(unsigned char)str[6]]; + case 6: + hval += asso_values[(unsigned char)str[5]]; + case 5: + hval += asso_values[(unsigned char)str[4]]; + case 4: + hval += asso_values[(unsigned char)str[3]]; + case 3: + hval += asso_values[(unsigned char)str[2]]; + case 2: + hval += asso_values[(unsigned char)str[1]]; + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval; +} + +#ifdef __GNUC__ +__inline +#endif +const char * +in_word_set (str, len) + register const char *str; + register unsigned int len; +{ + static unsigned char lengthtable[] = + { + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 2, 0, 0, 0, 2, 3, 0, + 0, 0, 2, 3, 0, 0, 0, 2, 4, 0, 0, 0, 4, 6, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 3, 5, 6, 0, 0, 6, 0, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 0, 9, + 0, 4, 6, 6, 0, 0, 2, 3, 0, 0, 0, 5, 3, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 7, 0, 0, 0, 5, 0, 0, 0, 0, 5, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10 + }; + static const char * wordlist[] = + { + "", + "OR", + "", "", "", "", "", "", "", "", + "LOOP", + "", "", "", "", "", "", "", "", "", + "ELSE", + "DO", + "", "", "", + "TO", + "MOD", + "", "", "", + "OF", + "FOR", + "", "", "", + "BY", + "FROM", + "", "", "", + "TYPE", + "MODULE", + "", "", "", + "SET", + "", "", "", "", "", + "EXPORT", + "", "", "", "", + "VAR", + "ARRAY", + "RECORD", + "", "", + "REPEAT", + "", "", "", "", + "END", + "", "", "", + "NOT", + "", "", "", "", + "IF", + "", "", "", "", + "CASE", + "", "", + "PROCEDURE", + "", + "EXIT", + "IMPORT", + "RETURN", + "", "", + "IN", + "AND", + "", "", "", + "ELSIF", + "DIV", + "", "", "", + "THEN", + "", "", "", "", "", "", "", "", "", + "IMPLEMENTATION", + "", "", "", "", + "WHILE", + "", "", "", "", "", "", "", "", "", + "CONST", + "POINTER", + "", "", "", + "UNTIL", + "", "", "", "", + "BEGIN", + "", "", "", "", + "WITH", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", + "QUALIFIED", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", + "DEFINITION" + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + if (len == lengthtable[key]) + { + register const char *s = wordlist[key]; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return s; + } + } + return 0; +} diff --git a/contrib/gperf/tests/test-3.exp b/contrib/gperf/tests/test-3.exp new file mode 100644 index 0000000..fe0a1a6d --- /dev/null +++ b/contrib/gperf/tests/test-3.exp @@ -0,0 +1,186 @@ +/* C code produced by gperf version 2.7 */ +/* Command-line: ../src/gperf -p -j 1 -o -a -C -g -t -k1,4,$ */ +/* 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;}; + +#define TOTAL_KEYWORDS 71 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 13 +#define MIN_HASH_VALUE 4 +#define MAX_HASH_VALUE 147 +/* maximum key range = 144, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#endif +static unsigned int +hash (str, len) + register const char *str; + register unsigned int len; +{ + static const unsigned char asso_values[] = + { + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 0, 148, 19, 6, 27, + 37, 0, 12, 1, 15, 63, 148, 4, 0, 56, + 20, 15, 42, 148, 31, 5, 26, 39, 32, 10, + 148, 40, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148 + }; + register int hval = len; + + switch (hval) + { + default: + case 4: + hval += asso_values[(unsigned char)str[3]]; + case 3: + case 2: + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +#ifdef __GNUC__ +__inline +#endif +const struct resword * +in_word_set (str, len) + register const char *str; + register unsigned int len; +{ + static const struct resword wordlist[] = + { + {""}, {""}, {""}, {""}, + {"else", ELSE, NORID,}, + {""}, + {"long", TYPESPEC, RID_LONG,}, + {""}, {""}, {""}, {""}, + {"__alignof__", ALIGNOF, NORID}, + {"__asm__", ASM, NORID}, + {""}, {""}, + {"while", WHILE, NORID,}, + {""}, {""}, {""}, {""}, {""}, + {"__alignof", ALIGNOF, NORID}, + {"all", ALL, NORID /* Extension */,}, + {"sizeof", SIZEOF, NORID,}, + {"__const__", TYPE_QUAL, RID_CONST}, + {"__volatile", TYPE_QUAL, RID_VOLATILE}, + {"extern", SCSPEC, RID_EXTERN,}, + {"__volatile__", TYPE_QUAL, RID_VOLATILE}, + {"__inline", SCSPEC, RID_INLINE}, + {"exception", AGGR, RID_EXCEPTION /* Extension */,}, + {"__inline__", SCSPEC, RID_INLINE}, + {"case", CASE, NORID,}, + {"except", EXCEPT, NORID /* Extension */,}, + {"new", NEW, NORID,}, + {"break", BREAK, NORID,}, + {"goto", GOTO, NORID,}, + {""}, + {"__attribute", ATTRIBUTE, NORID}, + {""}, + {"__attribute__", ATTRIBUTE, NORID}, + {"this", THIS, NORID,}, + {"raise", RAISE, NORID /* Extension */,}, + {"class", AGGR, RID_CLASS,}, + {"delete", DELETE, NORID,}, + {"typeof", TYPEOF, NORID,}, + {"typedef", SCSPEC, RID_TYPEDEF,}, + {"for", FOR, NORID,}, + {"raises", RAISES, NORID /* Extension */,}, + {"__const", TYPE_QUAL, RID_CONST}, + {"double", TYPESPEC, RID_DOUBLE,}, + {"__typeof__", TYPEOF, NORID}, + {""}, + {"switch", SWITCH, NORID,}, + {"auto", SCSPEC, RID_AUTO,}, + {"do", DO, NORID,}, + {"friend", SCSPEC, RID_FRIEND,}, + {""}, + {"reraise", RERAISE, NORID /* Extension */,}, + {""}, + {"volatile", TYPE_QUAL, RID_VOLATILE,}, + {"__typeof", TYPEOF, NORID}, + {"continue", CONTINUE, NORID,}, + {"float", TYPESPEC, RID_FLOAT,}, + {"const", TYPE_QUAL, RID_CONST,}, + {"static", SCSPEC, RID_STATIC,}, + {"virtual", SCSPEC, RID_VIRTUAL,}, + {"__asm", ASM, NORID}, + {"short", TYPESPEC, RID_SHORT,}, + {"signed", TYPESPEC, RID_SIGNED,}, + {"try", TRY, NORID /* Extension */,}, + {""}, {""}, {""}, + {"__signed__", TYPESPEC, RID_SIGNED}, + {"catch", CATCH, NORID,}, + {"public", PUBLIC, NORID,}, + {"struct", AGGR, RID_RECORD,}, + {"if", IF, NORID,}, + {"asm", ASM, NORID,}, + {"union", AGGR, RID_UNION,}, + {""}, + {"private", PRIVATE, NORID,}, + {""}, {""}, {""}, + {"operator", OPERATOR, NORID,}, + {""}, {""}, {""}, + {"default", DEFAULT, NORID,}, + {"dynamic", DYNAMIC, NORID,}, + {"overload", OVERLOAD, NORID,}, + {"int", TYPESPEC, RID_INT,}, + {"char", TYPESPEC, RID_CHAR,}, + {""}, {""}, + {"return", RETURN, NORID,}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, + {"__signed", TYPESPEC, RID_SIGNED}, + {""}, + {"void", TYPESPEC, RID_VOID,}, + {""}, {""}, {""}, + {"protected", PROTECTED, NORID,}, + {""}, + {"enum", ENUM, NORID,}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, + {"inline", SCSPEC, RID_INLINE,}, + {"register", SCSPEC, RID_REGISTER,}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, + {"unsigned", TYPESPEC, RID_UNSIGNED,} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register const char *s = wordlist[key].name; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return &wordlist[key]; + } + } + return 0; +} diff --git a/contrib/gperf/tests/test-4.exp b/contrib/gperf/tests/test-4.exp new file mode 100644 index 0000000..b527968 --- /dev/null +++ b/contrib/gperf/tests/test-4.exp @@ -0,0 +1,162 @@ +/* C code produced by gperf version 2.7 */ +/* Command-line: ../src/gperf -D -p -t */ +/* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */ +struct resword { char *name; short token; enum rid rid; }; + +#define TOTAL_KEYWORDS 51 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 13 +#define MIN_HASH_VALUE 4 +#define MAX_HASH_VALUE 82 +/* maximum key range = 79, duplicates = 2 */ + +#ifdef __GNUC__ +__inline +#endif +static unsigned int +hash (str, len) + register const char *str; + register unsigned int len; +{ + static unsigned char asso_values[] = + { + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 0, 83, 40, 20, 50, + 25, 10, 30, 0, 0, 50, 83, 0, 15, 0, + 35, 0, 83, 83, 20, 0, 10, 40, 5, 15, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83 + }; + return len + asso_values[(unsigned char)str[len - 1]] + asso_values[(unsigned char)str[0]]; +} + +#ifdef __GNUC__ +__inline +#endif +struct resword * +in_word_set (str, len) + register const char *str; + register unsigned int len; +{ + static struct resword wordlist[] = + { + {"goto", GOTO, NORID}, + {"__asm", ASM, NORID}, + {"switch", SWITCH, NORID}, + {"__asm__", ASM, NORID}, + {"__const__", TYPE_QUAL, RID_CONST}, + {"__inline__", SCSPEC, RID_INLINE}, + {"__typeof__", TYPEOF, NORID}, + {"__signed__", TYPESPEC, RID_SIGNED}, + {"__alignof__", ALIGNOF, NORID}, + {"__volatile__", TYPE_QUAL, RID_VOLATILE}, + {"__attribute__", ATTRIBUTE, NORID}, + {"enum", ENUM, NORID}, + {"short", TYPESPEC, RID_SHORT}, + {"struct", STRUCT, NORID}, + {"__const", TYPE_QUAL, RID_CONST}, + {"__inline", SCSPEC, RID_INLINE}, + {"long", TYPESPEC, RID_LONG}, + {"__volatile", TYPE_QUAL, RID_VOLATILE}, + {"__attribute", ATTRIBUTE, NORID}, + {"volatile", TYPE_QUAL, RID_VOLATILE}, + {"else", ELSE, NORID}, + {"break", BREAK, NORID}, + {"do", DO, NORID}, + {"while", WHILE, NORID}, + {"signed", TYPESPEC, RID_SIGNED}, + {"__signed", TYPESPEC, RID_SIGNED}, + {"void", TYPESPEC, RID_VOID}, + {"sizeof", SIZEOF, NORID}, + {"__typeof", TYPEOF, NORID}, + {"__alignof", ALIGNOF, NORID}, + {"double", TYPESPEC, RID_DOUBLE}, + {"default", DEFAULT, NORID}, + {"asm", ASM, NORID}, + {"auto", SCSPEC, RID_AUTO}, + {"float", TYPESPEC, RID_FLOAT}, + {"typeof", TYPEOF, NORID}, + {"typedef", SCSPEC, RID_TYPEDEF}, + {"register", SCSPEC, RID_REGISTER}, + {"extern", SCSPEC, RID_EXTERN}, + {"for", FOR, NORID}, + {"static", SCSPEC, RID_STATIC}, + {"return", RETURN, NORID}, + {"int", TYPESPEC, RID_INT}, + {"case", CASE, NORID}, + {"const", TYPE_QUAL, RID_CONST}, + {"inline", SCSPEC, RID_INLINE}, + {"continue", CONTINUE, NORID}, + {"unsigned", TYPESPEC, RID_UNSIGNED}, + {"char", TYPESPEC, RID_CHAR}, + {"union", UNION, NORID}, + {"if", IF, NORID} + }; + + static short lookup[] = + { + -1, -1, -1, -1, 0, 1, 2, 3, -1, 4, + -80, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, -1, 19, 20, 21, -1, 22, -46, -3, + 23, 24, -1, 25, 26, -1, 27, -1, 28, 29, + -1, 30, 31, 32, 33, 34, 35, 36, 37, -1, + -1, 38, -1, 39, -1, -1, 40, -1, -1, -1, + -1, 41, -1, 42, 43, 44, 45, -1, 46, -1, + -1, -1, -1, 47, 48, -1, -1, -1, -1, -1, + 49, -1, 50 + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int index = lookup[key]; + + if (index >= 0) + { + register const char *s = wordlist[index].name; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return &wordlist[index]; + } + else if (index < -TOTAL_KEYWORDS) + { + register int offset = - 1 - TOTAL_KEYWORDS - index; + register struct resword *wordptr = &wordlist[TOTAL_KEYWORDS + lookup[offset]]; + register struct resword *wordendptr = wordptr + -lookup[offset + 1]; + + while (wordptr < wordendptr) + { + register const char *s = wordptr->name; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return wordptr; + wordptr++; + } + } + } + } + return 0; +} diff --git a/contrib/gperf/tests/test-5.exp b/contrib/gperf/tests/test-5.exp new file mode 100644 index 0000000..8f4d9ab --- /dev/null +++ b/contrib/gperf/tests/test-5.exp @@ -0,0 +1,124 @@ +/* C code produced by gperf version 2.7 */ +/* Command-line: ../src/gperf -g -o -j1 -t -p -N is_reserved_word */ +/* 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;}; + +#define TOTAL_KEYWORDS 35 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 9 +#define MIN_HASH_VALUE 2 +#define MAX_HASH_VALUE 43 +/* maximum key range = 42, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#endif +static unsigned int +hash (str, len) + register const char *str; + register unsigned int len; +{ + static unsigned char asso_values[] = + { + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 18, 29, 14, 6, 7, + 10, 20, 44, 28, 44, 44, 28, 19, 22, 15, + 0, 44, 9, 23, 0, 23, 26, 2, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 0, 0, 13, 44, 30, 44, 44, 44, 0, 25, + 1, 0, 44, 44, 0, 44, 1, 44, 25, 44, + 44, 0, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44 + }; + return len + asso_values[(unsigned char)str[len - 1]] + asso_values[(unsigned char)str[0]]; +} + +#ifdef __GNUC__ +__inline +#endif +struct resword * +is_reserved_word (str, len) + register const char *str; + register unsigned int len; +{ + static struct resword wordlist[] = + { + {""}, {""}, + {"To", TO, PASCAL_ISO}, + {""}, + {"Type", TYPE, PASCAL_ISO}, + {"Then", THEN, PASCAL_ISO}, + {"Packed", PACKED, PASCAL_ISO}, + {"While", WHILE, PASCAL_ISO}, + {"Do", DO, PASCAL_ISO}, + {"Procedure", PROCEDURE, PASCAL_ISO}, + {"End", END, PASCAL_ISO}, + {"Else", ELSE, PASCAL_ISO}, + {"Downto", DOWNTO, PASCAL_ISO}, + {"For", FOR, PASCAL_ISO}, + {"File", FILE_, PASCAL_ISO}, + {"Record", RECORD, PASCAL_ISO}, + {"Repeat", REPEAT, PASCAL_ISO}, + {"Or", OR, PASCAL_ISO}, + {"Case", CASE, PASCAL_ISO}, + {"Function", FUNCTION, PASCAL_ISO}, + {"Const", CONST, PASCAL_ISO}, + {"And", AND, PASCAL_ISO}, + {"Mod", MOD, PASCAL_ISO}, + {"Array", ARRAY, PASCAL_ISO}, + {"Goto", GOTO, PASCAL_ISO}, + {"Nil", NIL, PASCAL_ISO}, + {"Not", NOT, PASCAL_ISO}, + {"Set", SET, PASCAL_ISO}, + {"Until", UNTIL, PASCAL_ISO}, + {"Var", VAR, PASCAL_ISO}, + {"Of", OF, PASCAL_ISO}, + {"In", IN, PASCAL_ISO}, + {"Program",PROGRAM,PASCAL_ISO}, + {"Label", LABEL, PASCAL_ISO}, + {"Div", DIV, PASCAL_ISO}, + {"Begin", BEGIN_, PASCAL_ISO}, + {"With", WITH, PASCAL_ISO}, + {""}, {""}, {""}, {""}, {""}, {""}, + {"If", IF, PASCAL_ISO} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register const char *s = wordlist[key].name; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return &wordlist[key]; + } + } + return 0; +} diff --git a/contrib/gperf/tests/test-6.exp b/contrib/gperf/tests/test-6.exp new file mode 100644 index 0000000..3521f13 --- /dev/null +++ b/contrib/gperf/tests/test-6.exp @@ -0,0 +1,119 @@ +GNU `gperf' generates perfect hash functions. + +Usage: ../src/gperf [OPTION]... [INPUT-FILE] + +If a long option shows an argument as mandatory, then it is mandatory +for the equivalent short option also. + +Input file interpretation: + -e, --delimiters=DELIMITER-LIST + Allow user to provide a string containing delimiters + used to separate keywords from their attributes. + Default is ",\n". + -t, --struct-type Allows the user to include a structured type + declaration for generated code. Any text before %% + is considered part of the type declaration. Key + words and additional fields may follow this, one + group of fields per line. + +Language for the output code: + -L, --language=LANGUAGE-NAME + Generates code in the specified language. Languages + handled are currently C++, ANSI-C, C, and KR-C. The + default is C. + +Details in the output code: + -K, --slot-name=NAME Select name of the keyword component in the keyword + structure. + -H, --hash-fn-name=NAME + Specify name of generated hash function. Default is + `hash'. + -N, --lookup-fn-name=NAME + Specify name of generated lookup function. Default + name is `in_word_set'. + -Z, --class-name=NAME Specify name of generated C++ class. Default name is + `Perfect_Hash'. + -7, --seven-bit Assume 7-bit characters. + -c, --compare-strncmp Generate comparison code using strncmp rather than + strcmp. + -C, --readonly-tables Make the contents of generated lookup tables + constant, i.e., readonly. + -E, --enum Define constant values using an enum local to the + lookup function rather than with defines. + -I, --includes Include the necessary system include file <string.h> + at the beginning of the code. + -G, --global Generate the static table of keywords as a static + global variable, rather than hiding it inside of the + lookup function (which is the default behavior). + -W, --word-array-name=NAME + Specify name of word list array. Default name is + `wordlist'. + -S, --switch=COUNT Causes the generated C code to use a switch + statement scheme, rather than an array lookup table. + This can lead to a reduction in both time and space + requirements for some keyfiles. The COUNT argument + determines how many switch statements are generated. + A value of 1 generates 1 switch containing all the + elements, a value of 2 generates 2 tables with 1/2 + the elements in each table, etc. If COUNT is very + large, say 1000000, the generated C code does a + binary search. + -T, --omit-struct-type + Prevents the transfer of the type declaration to the + output file. Use this option if the type is already + defined elsewhere. + +Algorithm employed by gperf: + -k, --key-positions=KEYS + Select the key positions used in the hash function. + The allowable choices range between 1-126, inclusive. + The positions are separated by commas, ranges may be + used, and key positions may occur in any order. + Also, the meta-character '*' causes the generated + hash function to consider ALL key positions, and $ + indicates the ``final character'' of a key, e.g., + $,1,2,4,6-10. + -l, --compare-strlen Compare key lengths before trying a string + comparison. This helps cut down on the number of + string comparisons made during the lookup. + -D, --duplicates Handle keywords that hash to duplicate values. This + is useful for certain highly redundant keyword sets. + -f, --fast=ITERATIONS Generate the gen-perf.hash function ``fast''. This + decreases gperf's running time at the cost of + minimizing generated table size. The numeric + argument represents the number of times to iterate + when resolving a collision. `0' means ``iterate by + the number of keywords''. + -i, --initial-asso=N Provide an initial value for the associate values + array. Default is 0. Setting this value larger helps + inflate the size of the final table. + -j, --jump=JUMP-VALUE Affects the ``jump value'', i.e., how far to advance + the associated character value upon collisions. Must + be an odd number, default is 5. + -n, --no-strlen Do not include the length of the keyword when + computing the hash function. + -o, --occurrence-sort Reorders input keys by frequency of occurrence of + the key sets. This should decrease the search time + dramatically. + -r, --random Utilizes randomness to initialize the associated + values table. + -s, --size-multiple=N Affects the size of the generated hash table. The + numeric argument N indicates ``how many times larger + or smaller'' the associated value range should be, + in relationship to the number of keys, e.g. a value + of 3 means ``allow the maximum associated value to + be about 3 times larger than the number of input + keys.'' Conversely, a value of -3 means ``make the + maximum associated value about 3 times smaller than + the number of input keys. A larger table should + decrease the time required for an unsuccessful + search, at the expense of extra table space. Default + value is 1. + +Informative output: + -h, --help Print this message. + -v, --version Print the gperf version number. + -d, --debug Enables the debugging option (produces verbose + output to the standard error). + +Report bugs to <bug-gnu-utils@gnu.org>. diff --git a/contrib/gperf/tests/test-7.exp b/contrib/gperf/tests/test-7.exp new file mode 100644 index 0000000..c5c942c --- /dev/null +++ b/contrib/gperf/tests/test-7.exp @@ -0,0 +1,32 @@ +in word set if +in word set do +NOT in word set int +in word set for +in word set case +NOT in word set char +NOT in word set auto +in word set goto +in word set else +NOT in word set long +NOT in word set void +NOT in word set enum +NOT in word set float +NOT in word set short +NOT in word set union +NOT in word set break +in word set while +NOT in word set const +NOT in word set double +NOT in word set static +NOT in word set extern +NOT in word set struct +in word set return +NOT in word set sizeof +NOT in word set switch +NOT in word set signed +NOT in word set typedef +NOT in word set default +NOT in word set unsigned +NOT in word set continue +NOT in word set register +NOT in word set volatile diff --git a/contrib/gperf/tests/test.c b/contrib/gperf/tests/test.c new file mode 100644 index 0000000..5d78156 --- /dev/null +++ b/contrib/gperf/tests/test.c @@ -0,0 +1,26 @@ +/* + Tests the generated perfect hash 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 + +int +main (argc, argv) + int argc; + char *argv[]; +{ + 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; +} diff --git a/contrib/gperf/tests/validate b/contrib/gperf/tests/validate new file mode 100755 index 0000000..a4813ab --- /dev/null +++ b/contrib/gperf/tests/validate @@ -0,0 +1,54 @@ +#! /bin/sh +# Validate gperf's operation on a given input file. +# Usage: validate languages input.gperf [more gperf options] +# Uses the environment variables GPERF, CC, CFLAGS, CXX, CXXFLAGS. +# Supposes gcc and g++. + +# Exit on error +set -e + +verbose () { + echo "$@" + "$@" +} + +languages=$1 +shift + +for lang in `echo $languages | sed -e 's/,/ /g'`; do + case "$lang" in + KR-C ) + echo "${GPERF} -I -L KR-C $@ > valitest.c" + ${GPERF} -I -L KR-C "$@" > valitest.c + grep -n ' const ' valitest.c /dev/null && exit 1 + verbose ${CC} ${CFLAGS} -traditional valitest.c -o valitest + ./valitest + verbose ${CC} ${CFLAGS} -ansi -pedantic valitest.c -o valitest + ./valitest + ;; + C ) + echo "${GPERF} -I -L C $@ > valitest.c" + ${GPERF} -I -L C "$@" > valitest.c + verbose ${CC} ${CFLAGS} -traditional -Dconst= valitest.c -o valitest + ./valitest + verbose ${CC} ${CFLAGS} -ansi -pedantic -pedantic-errors valitest.c -o valitest + ./valitest + ;; + ANSI-C ) + echo "${GPERF} -I -L ANSI-C $@ > valitest.c" + ${GPERF} -I -L ANSI-C "$@" > valitest.c + verbose ${CC} ${CFLAGS} -ansi -pedantic -pedantic-errors valitest.c -o valitest + ./valitest + verbose ${CXX} ${CXXFLAGS} -ansi -pedantic -pedantic-errors valitest.c -o valitest + ./valitest + ;; + "C++" ) + echo "${GPERF} -I -L C++ $@ > valitest.c" + ${GPERF} -I -L C++ "$@" > valitest.c + verbose ${CXX} ${CXXFLAGS} -ansi -pedantic -pedantic-errors -DCPLUSPLUS_TEST valitest.c -o valitest + ./valitest + ;; + esac +done + +exit 0 |