diff options
Diffstat (limited to 'apps/gperf')
62 files changed, 0 insertions, 16617 deletions
diff --git a/apps/gperf/COPYING b/apps/gperf/COPYING deleted file mode 100644 index 9a170375811..00000000000 --- a/apps/gperf/COPYING +++ /dev/null @@ -1,249 +0,0 @@ - - GNU GENERAL PUBLIC LICENSE - Version 1, February 1989 - - Copyright (C) 1989 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The license agreements of most software companies try to keep users -at the mercy of those companies. By contrast, our General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. The -General Public License applies to the Free Software Foundation's -software and to any other program whose authors commit to using it. -You can use it for your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Specifically, the General Public License is designed to make -sure that you have the freedom to give away or sell copies of free -software, that you receive source code or can get it if you want it, -that you can change the software or use pieces of it in new free -programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of a such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must tell them their rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any program or other work which -contains a notice placed by the copyright holder saying it may be -distributed under the terms of this General Public License. The -"Program", below, refers to any such program or work, and a "work based -on the Program" means either the Program or any work containing the -Program or a portion of it, either verbatim or with modifications. Each -licensee is addressed as "you". - - 1. You may copy and distribute verbatim copies of the Program's source -code as you receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice and -disclaimer of warranty; keep intact all the notices that refer to this -General Public License and to the absence of any warranty; and give any -other recipients of the Program a copy of this General Public License -along with the Program. You may charge a fee for the physical act of -transferring a copy. - - 2. You may modify your copy or copies of the Program or any portion of -it, and copy and distribute such modifications under the terms of Paragraph -1 above, provided that you also do the following: - - a) cause the modified files to carry prominent notices stating that - you changed the files and the date of any change; and - - b) cause the whole of any work that you distribute or publish, that - in whole or in part contains the Program or any part thereof, either - with or without modifications, to be licensed at no charge to all - third parties under the terms of this General Public License (except - that you may choose to grant warranty protection to some or all - third parties, at your option). - - c) If the modified program normally reads commands interactively when - run, you must cause it, when started running for such interactive use - in the simplest and most usual way, to print or display an - announcement including an appropriate copyright notice and a notice - that there is no warranty (or else, saying that you provide a - warranty) and that users may redistribute the program under these - conditions, and telling the user how to view a copy of this General - Public License. - - d) You may charge a fee for the physical act of transferring a - copy, and you may at your option offer warranty protection in - exchange for a fee. - -Mere aggregation of another independent work with the Program (or its -derivative) on a volume of a storage or distribution medium does not bring -the other work under the scope of these terms. - - 3. You may copy and distribute the Program (or a portion or derivative of -it, under Paragraph 2) in object code or executable form under the terms of -Paragraphs 1 and 2 above provided that you also do one of the following: - - a) accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of - Paragraphs 1 and 2 above; or, - - b) accompany it with a written offer, valid for at least three - years, to give any third party free (except for a nominal charge - for the cost of distribution) a complete machine-readable copy of the - corresponding source code, to be distributed under the terms of - Paragraphs 1 and 2 above; or, - - c) accompany it with the information you received as to where the - corresponding source code may be obtained. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form alone.) - -Source code for a work means the preferred form of the work for making -modifications to it. For an executable file, complete source code means -all the source code for all modules it contains; but, as a special -exception, it need not include source code for modules which are standard -libraries that accompany the operating system on which the executable -file runs, or for standard header files or definitions files that -accompany that operating system. - - 4. You may not copy, modify, sublicense, distribute or transfer the -Program except as expressly provided under this General Public License. -Any attempt otherwise to copy, modify, sublicense, distribute or transfer -the Program is void, and will automatically terminate your rights to use -the Program under this License. However, parties who have received -copies, or rights to use copies, from you under this General Public -License will not have their licenses terminated so long as such parties -remain in full compliance. - - 5. By copying, distributing or modifying the Program (or any work based -on the Program) you indicate your acceptance of this license to do so, -and all its terms and conditions. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the original -licensor to copy, distribute or modify the Program subject to these -terms and conditions. You may not impose any further restrictions on the -recipients' exercise of the rights granted herein. - - 7. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of the license which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -the license, you may choose any version ever published by the Free Software -Foundation. - - 8. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to humanity, the best way to achieve this is to make it -free software which everyone can redistribute and change under these -terms. - - To do so, attach the following notices to the program. It is safest to -attach them to the start of each source file to most effectively convey -the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) 19yy <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 1, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19xx name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the -appropriate parts of the General Public License. Of course, the -commands you use may be called something other than `show w' and `show -c'; they could even be mouse-clicks or menu items--whatever suits your -program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - program `Gnomovision' (a program to direct compilers to make passes - at assemblers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/apps/gperf/ChangeLog b/apps/gperf/ChangeLog deleted file mode 100644 index 80c845d381a..00000000000 --- a/apps/gperf/ChangeLog +++ /dev/null @@ -1,1728 +0,0 @@ -Mon Nov 9 23:37:09 1998 Vishal Kachroo <vishal@cs.wustl.edu> - - * src/Key_List.cpp: Fixed the problem with Binary and Linear - Search code. - -Sat Oct 10 18:40:56 1998 Vishal Kachroo <vishal@merengue.cs.wustl.edu> - - * tests/test-6.exp (Usage): copied the output of gperf -h option - into test-6.exp. This test was failing because it didn't have - the -b option previously. Thanks to David for reporting the failure - of tests. - - * src/Options.cpp : Changed the option case 'h' to include the - following line " -b/t Code for Linear Search". - -Fri Oct 9 01:06:56 1998 Alexander Babu Arulanthu <alex@cs.wustl.edu> - - * src/Options.cpp : - * src/Key_List.cpp (output_linear_search_function): - Changed option -z to -b for generating linear search. Removed - <len> parameter from the lookup code. We dont need <len> in the - generated code in the case of linear/binary search options. - -Thu Oct 8 17:40:19 1998 Vishal Kachroo <vishal@merengue.cs.wustl.edu> - - * src/Gen_Perf.cpp (run): added the linear search changes. - * src/Gen_Perf.h : added the linear search changes. - * src/Options.cpp : added the linear search changes. - * src/Options.h : added the linear search changes. - * src/Key_List.cpp : added the linear search changes. - * src/Key_List.h : added the linear search changes. - - -Wed Oct 7 01:20:35 1998 Alexander Babu Arulanthu <alex@cs.wustl.edu> - - * tests/test-6.exp: - Updated thif file to the current help message. Thanks to Hans - for reporting this. - - -Tue Oct 6 11:51:47 1998 Alexander Babu Arulanthu <alex@cs.wustl.edu> - - * src/Key_List.cpp (Key_List): Fixed g++ warnings. - -Tue Oct 6 02:48:37 1998 Alexander Babu Arulanthu <alex@cs.wustl.edu> - - Thanks to Vishal the following things have been done to get Binary - Search code generated from GPERF. - - * src/Options.cpp (parse_args): Added the -B option for the binary - search. - - * src/Options.h (enum Option_Type): Added the BINARYSEARCH in the - enumeration. - - * src/Key_List.cpp : Added the function output_binary_search_function - (void). Changed the output function to include the Binary Search option. - Used option[BINARYSEARCH] to distinguish the binary search case from the - hashing case. - - * src/Key_List.h : Added the prototype for output_binary_search_function. - Also added the key_sort variable to enable sorting based on key values. - - -Mon Oct 5 18:24:15 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - - * src/Gen_Perf: Created a new function that allows us to split the - binary search and perfect hash logic apart. Thanks to Vishal - and Alex for reporting this. - - * src/Key_List.cpp (dump): Fixed the unsigned problems with line - 1502 YET again... Thanks to David/Darrell for reporting this. - -Sun Oct 4 20:42:56 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - - * src: Fixed yet another problem with switching from array-based - lookups to switch-based lookups. Thanks to Carlos for reporting - this. - -Sat Oct 3 19:36:52 1998 Alexander Babu Arulanthu <alex@cs.wustl.edu> - - * src/Options.h: - * src/Options.cpp: - * src/Key_List.h: - * src/Key_List.cpp: - Reverted all the changes done for Binary Search. - -Sat Oct 3 17:51:10 1998 Carlos O'Ryan <coryan@cs.wustl.edu> - - * tests/test-6.exp: - Added the new -B option. - -Sat Oct 3 13:47:40 1998 Alexander Babu Arulanthu <alex@cs.wustl.edu> - - * src/Key_List.cpp (output_binary_search_function): Added a new - line after binary search code. - -Sat Oct 3 10:11:15 1998 Alexander Babu Arulanthu <alex@cs.wustl.edu> - - * src/Options.cpp (parse_args): Changed the option for binary - search to '-B' - -Fri Oct 2 21:38:54 1998 Vishal Kachroo <vishal@merengue.cs.wustl.edu> - - * src/Options.cpp (parse_args): Added the -b option for the binary - search. - - * src/Options.h (enum Option_Type): Added the BINARYSEARCH in the - enumeration. - - * src/Key_List.cpp : Added the function output_binary_search_function - (void). Changed the output function to include the Binary Search option. - Used option[BINARYSEARCH] to distinguish the binary search case from the - hashing case. - - * src/Key_List.h : Added the prototype for output_binary_search_function. - Also added the key_sort variable to enable sorting based on key values. - - -Thu Oct 1 12:40:59 1998 Alexander Babu Arulanthu <alex@cs.wustl.edu> - - * src/Options.cpp (parse_args): Comments for Vishal to incorporate - Binary Seach on to GPERF. - -Wed Sep 30 16:55:53 1998 Carlos O'Ryan <coryan@cs.wustl.edu> - - * tests/Makefile: - Updated dependencies, added a realclean target to remove the - output from the tests. - -Wed Sep 30 12:41:29 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - - * src/Key_List.cpp (dump): Fixed another signed/unsigned int - mismatch. Thanks to David Levine for reporting this. - -Mon Sep 28 13:18:05 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - - * tests: Updated all the test-*.exp files to reflect the - latest "unsigned" changes. - - * src/Key_List.cpp (output_hash_function): Fixed another use of - int to be unsigned int. - - * tests/test.cpp: Fixed the signature of in_word_set() to be - consistent with the new gperf. Thanks to David Levine and - Carlos O'Ryan for this fix. - -Sun Sep 27 00:04:18 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - - * src/Key_List.cpp (dump): Reverted back to using int for - keyword_width to keep certain compilers happy. Thanks to David - Levine for reporting this. - - * src/Key_List: MAke sure that we don't generate the lookup table - twice if we're forced to change to the switch format. - - * src/Key_List: Replaced the use of "int" with "unsigned int" for - parameters and hash values. - - * src/Key_List: Fixed the code so that if we change over to using - the switch statement then we use the already generated keyword - table appropriately. This prevents unnecessary warnings from - some C++ compilers. Thanks to David Levine for reporting this. - - * src/Key_List.cpp (output): If it's not possible to use the - lookup_array implementation of -D (e.g., because there aren't - enough empty slots in the lookup_array), then default to using - -S1 option... This fixes a nasty bug that's been in gperf for - years.... - - * src/Key_List.cpp: (output_lookup_array): Added a "return 0" to - make the C++ compiler happy. Thanks to David for noticing this. - - * tests/c++-res.exp: Added a new test for C++ keywords. - - * tests/corba.gperf: Added a proper test for CORBA keywords. - -Sat Sep 26 15:32:56 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - - * src/Hash_Table.cpp (find): Fixed a bug in the increment - computation that arose if the -n option was given. - - * src: Removed all set_ and get_ prefixes to be more consistent - with ACE programming guidelines. - - * src: GPERF now Purifies cleanly. - - * src/Gen_Perf: Cleaned up the code so that if errors occur they - get handled properly. - - * src/List_Node: Added a destructor to remove the memory when - we're done. - - * src: Continued to tidy up the source code so that it is better - designed and Purifies cleanly on shutdown. - - * src/Makefile: Removed the need for libGperf.{a,so}. - - * src/Key_List: Changed read_keys() to return a value so that we - can check for errors. - -Fri Sep 25 08:54:41 1998 David L. Levine <levine@cs.wustl.edu> - - * src/Key_List.cpp (Key_List ctor): reordered initializers to - match declaration order. - -Thu Sep 24 18:20:36 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - - * src/Key_List: Changed char_set field to keysig to be consistent - with the paper. - - * src/Hash_Table: Renamed operator() to find(). What the heck was - I thinking in '92?! - - * src/gperf.cpp (main): Removed the LARGE_STACK_ARRAYS option. - This was annoying... - -Tue Sep 22 21:30:59 1998 David L. Levine <levine@cs.wustl.edu> - - * tests/corba.exp: added this file, it hadn't been checked in. - -Tue Sep 22 18:02:01 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - - * tests/Makefile: Added a new test for CORBA keywords. - - * tests: Added a new test for the type of input that is causing - problems with TAO's IDL compiler. - - * src/Key_List.cpp (output_lookup_array): Changed the assertion - from assert (i != 0) to assert (i >= 0) since I think that's - correct... (ah, so THAT's why comments are important thinks the - '92 Doug... ;-)). - - * src/Options: Improved the comments for the '-h' option to - reflect current reality... - -Thu Sep 17 11:42:53 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - - * src/Key_List.cpp (output_lookup_array): Put 'signed' keyword - before 'char lookup' to avoid problems on platforms where char - is defined as unsigned. Thanks to Margherita Vittone Wiersma - <vittone@fndaub.fnal.gov> for reporting this. - -Wed Sep 16 19:08:13 1998 David L. Levine <levine@cs.wustl.edu> - - * Makefile: don't run build/run tests on CROSS-COMPILE platforms. - Thanks to Raja Ati <rati@montereynets.com> for reporting this - problem. - -Wed Sep 16 18:18:41 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - - * tests/Makefile: Changed CFLAGS to CCFLAGS to make aCC happy on - HP/UX. Thanks to John Mulhern for reporting this. - -Tue Sep 15 18:14:08 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - - * tests/test-6.exp (Usage): Fixed the usage so diff should no - longer complain... Thanks to David for reporting this. - -Tue Sep 15 21:54:07 1998 David L. Levine <levine@cs.wustl.edu> - - * tests/Makefile: filter timestamps from test output so that - diffs will pass. - -Tue Sep 15 18:14:08 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - - * tests: Updated the expected output to look for 2.7 vs 2.6 - of gperf. - -Thu Sep 10 16:50:21 1998 Carlos O'Ryan <coryan@cs.wustl.edu> - - * tests/Makefile: - The test programs were not linking against ACE. - -Tue Sep 8 12:45:53 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - - * tests/test.cpp: Added #include "ace/OS.h" so that the ACE_RCSID - macro is defined. Thanks to Arturo Montes - <mitosys@colomsat.net.co> for reporting this. - -Sat Aug 22 08:44:15 1998 Alexander Babu Arulanthu <alex@cs.wustl.edu> - - * src/Options.cpp : Fixed the typo (-V instead of -v) under 'case - h' print string. - -Fri Aug 21 11:57:57 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - - * src/Key_List.cpp (set_output_types): Make sure that we leave an - extra space between the struct tag and the wordlist so the - compiler doesn't complain. Thanks to Andy Gokhale for reporting - this. - - * src/gperf.cpp: Modified the main() program so that it doesn't - print the starting time until AFTER we've parsed the arguments. - - * src/Version.cpp: Updated the version to 2.7 to reflect the - new changes. - - * src/Options.cpp (operator): Added a new -V option, which just - exits with a value of 0. This is useful for checking if gperf - exists in the search path. We use the feature in TAO. - - * src: Removed the globally overloaded new operator. This was a - portability pain and didn't really improve performance very - much. - - * src/Options.cpp (operator): Fixed '%e' to be '%r' to come up to - speed with ACE changes. - -Sat Aug 15 07:59:58 1998 David L. Levine <levine@cs.wustl.edu> - - * src/gperf.cpp (main): added ACE_UNUSED_ARGS for argc and - argv if ! ACE_HAS_GPERF. - -Fri Aug 14 13:47:00 1998 David L. Levine <levine@cs.wustl.edu> - - * src/new.cpp (delete): aded ACE_UNUSED_ARG (ptr). - -Fri Jul 31 18:28:45 1998 Gonzalo Diethelm <gonzo@tango.cs.wustl.edu> - - * src/Bool_Array.cpp: - * src/Gen_Perf.cpp: - * src/Hash_Table.cpp: - * src/Iterator.cpp: - * src/Key_List.cpp: - * src/List_Node.cpp: - * src/Options.cpp: - * src/Vectors.cpp: - * src/Version.cpp: - * src/gperf.cpp: - * src/new.cpp: - * tests/test.cpp: - Added ACE_RCSID to these files. - -Tue Jul 21 09:30:51 1998 David L. Levine <levine@cs.wustl.edu> - - * src/gperf.cpp (main): added a trivial main () if ! ACE_HAS_GPERF, - so that the link succeeds. - -Mon Jul 20 16:02:18 1998 David L. Levine <levine@cs.wustl.edu> - - * src/Makefile: fixed INSTALL. It works with the latest - $ACE_ROOT/include/makeinclude/rules.lib.GNU. - -Mon Jul 20 15:35:59 1998 Alexander Babu Arulanthu <alex@cs.wustl.edu> - - * Wrapped all the files with "#if defined (ACE_HAS_GPERF)" so that - it compiles on appropriate platforms. - -Sun Jul 19 22:21:17 1998 David L. Levine <levine@cs.wustl.edu> - - * src/new.cpp (new): wrapped assignment with parens where used - as a conditional. - - * src/Iterator.cpp (Iterator), List_Node.cpp (List_Node), - Hash_Table.cpp (Hash_Table): - reordered initializers to match declaration order. - - * src/Hash_Table.cpp (~Hash_Table), - * src/Bool_Array.cpp (init): cast sizeof - to int to avoid compiler (g++/Linux alpha) warning about - mismatch with %d format specifier. - - * src/new.cpp (new): use ACE_THROW_SPEC instead of - _RWSTD_THROW_SPEC. - -Sun Jul 19 13:11:59 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - - * src/new.cpp: Added support for the _RWSTD_THROW_SPEC macro for - DEC UNIX. Thanks to David Levine for reporting this. - - * src/Key_List.cpp: Fixed one of those nasty "for loop counter - scoping glitches. Again, thanks to David Levine and DEC C++ for - catching this. * src/Key_List.cpp (reorder): Clarified the code - so that we don't write horrible C-style hacks. Thanks to David - Levine and the DEC C++ compiler for finding this one! - -Tue Jun 30 15:43:16 1998 Alexander Babu Arulanthu <alex@cs.wustl.edu> - - * src/Options.h : - * src/Options.cpp : - * src/Key_List.cpp : Added the following options to gperf. - - "-m" To mute warnings. (If -D option is enabled, - gperf doesnt say anything about duplicate hash - values etc. - - "-M" To skip class definition while in C++ mode. - - "-J" To skip the line "#include <string.h>" in the - output. - -Thu May 14 16:37:39 1998 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> - - * src: ACE'ifed most of the gperf source code, yow! - -Sun Apr 14 14:31:10 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) - - * src: Changed things so that there's no longer any use of the - Read_Line and Std_Err code. All of this has been pushed into - the ACE components, which is where it belongs... - - * src: Changed things so that there's no longer any use of the - pointless inheritance in the code. This was a result of my not - understanding inheritance back in 1989... ;-) - - * Began to integrate GNU gperf into the ACE release. Started off - by bringing the standard GNU version up to date wrt to the - changes I made back in 1991! - -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. - -Mon Nov 4 15:04:41 1991 Douglas C. Schmidt (schmidt at bastille.ics.uci.edu) - - * Need to do something about the end-of-line marker being - hard-coded to '\n'... - - * Need to do something about the comment character being - hard-coded to '#'... - -Fri Sep 27 09:30:15 1991 Douglas C. Schmidt (schmidt at net4.ics.uci.edu) - - * Fixed a stupid problem with printout out a local enum with the - -E option (I forgot to check for the case of 0 duplicates, so it - was saying 1 duplicate instead!). - -Mon Aug 19 00:39:40 1991 Douglas C. Schmidt (schmidt at javel.ics.uci.edu) - - * Yow, all finished making gperf run with cfront/Saber C++. Not - really all that hard, actually, though did need to remove some - GNU specific hacks, like dynamically sized arrays and - initializing class data members in their declarations, etc. - - * Bumped up the version # to reflect the recent changes. - -Sun Aug 18 22:25:32 1991 Douglas C. Schmidt (schmidt at javel.ics.uci.edu) - - * Changed passage of Options::usage function in Options.C to have - a leading `&' so that Saber C++ wouldn't complain... - - * Added a new header file called gperf.h that includes system-wide - info. - - * Hacked up the release to work with Saber C++! Changed all *.cc - files to *.C. - -Mon Aug 5 21:18:47 1991 Douglas C. Schmidt (schmidt at net1.ics.uci.edu) - - * Yow, hacked in the nifty changes to the Std_Err error handling - abstraction. This now adds format string support for printing - out signals and the name of the function when things go wrong. - Make changes throughout the source to make use of the new - facilities and also to make sure all previous uses of - Std_Err::report_error are now prefixed by the name of the class. - -Tue Jul 30 00:02:39 1991 Douglas C. Schmidt (schmidt at net4.ics.uci.edu) - - * Make sure to add 1 to the Key_List::total_duplicates value when - printing it out since any time we have more than zero duplicates - we really have two or more duplicates! - - * Added support for the -O (optimize option). This option - optimizes the generated lookup function by assuming that all - input keywords are members of the keyset from the keyfile. - - * Added #define DUPLICATES and #define HASH_VALUE_RANGE (and of - course the enum equivalent) to the generated output. Don't know - how useful this will be, but it allows us to determine at a - glance whether we've got a minimal perfect hash function (in - which case TOTAL_KEYWORDS = HASH_VALUE_RANGE, and DUPLICATES = - 0). - - * 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! - - * Yow, as part of my Software Practice and Experience submission - writeup I realized I needed to make the # comment character work - correctly. Now if you put a backslash character ('\') in front - of the # it treats the first character as a #. Naturally, to - put a '\' character on the front of the line you need to escape - it also, i.e., - \\I'm a line that starts with only one \ - # I'm a comment line - \#define I'm walking a fine line... ;-) - -Wed Jun 26 11:21:02 1991 Douglas C. Schmidt (schmidt at bastille.ics.uci.edu) - - * Changed all uses of the identifier `iteration_number' to - `generation_number' (also updated the paper!). - -Tue Apr 9 07:59:42 1991 Doug Schmidt (schmidt at net4.ics.uci.edu) - - * Had to change a whole bunch of little thangs in key-list.cc and - list-node.cc to make the -I option work. - - * Changed an alloca statement in key-list.cc to reflect the - strncasecmp modification (i.e., we now need to be able to - allocate a longer buffer if the -I option is used). - -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... - - * Boy, it has been a *long* time since I hacked this puppy. Let's - see, I'm about to add long-overdue support for case-insensitive - string comparisons to gperf's generated output code. We are - going to employ the hitherto unused option -I to indicte this! - -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/apps/gperf/Makefile b/apps/gperf/Makefile deleted file mode 100644 index bd1932f4f94..00000000000 --- a/apps/gperf/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -#---------------------------------------------------------------------------- -# -# $Id$ -# -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -INFO = README - -DIRS = src - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU - -ifeq ($(CROSS-COMPILE),) - DIRS += tests -endif # ! CROSS-COMPILE - -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nolocal.GNU diff --git a/apps/gperf/README b/apps/gperf/README deleted file mode 100644 index 11768b81f94..00000000000 --- a/apps/gperf/README +++ /dev/null @@ -1,29 +0,0 @@ -While teaching a data structures course at University of California, -Irvine, I developed a program called GPERF that generates perfect hash -functions for sets of key words. A perfect hash function is: - - A hash function and a data structure that allows - recognition of a key word in a set of words using - exactly 1 probe into the data structure. - -The gperf.texinfo file explains how the program works, the form of the -input, what options are available, and hints on choosing the best -options for particular key word sets. The texinfo file is readable -both via the GNU emacs `info' command and is also suitable for -typesetting with TeX. - -The enclosed Makefile creates the executable program ``gperf'' and -also runs the regression tests. - -Output from the GPERF program is used to recognize reserved words in -the GNU C, GNU C++, and GNU Pascal compilers. In addition, it is used -by TAO'd IDL compiler to generate operation dispatching tables. - -For more information on GPERF, please see - -http://www.cs.wustl.edu/~schmidt/C++-USENIX-90.ps.gz - -Happy hacking! - -Douglas C. Schmidt -schmidt@cs.wustl.edu diff --git a/apps/gperf/gperf.1 b/apps/gperf/gperf.1 deleted file mode 100644 index 5673c80062a..00000000000 --- a/apps/gperf/gperf.1 +++ /dev/null @@ -1,23 +0,0 @@ -.TH GPERF 1 "December 16, 1988 -.UC 4 -.SH NAME -gperf \- generate a perfect hash function from a key set -.SH SYNOPSIS -.B gperf -[ -.B \-adghijklnoprsStv -] [ -.I keyfile -] -.SH DESCRIPTION - -\fIgperf\fP reads a set of ``keys'' from \fIkeyfile\fP (or, by -default, from the standard input) and attempts to find a non-minimal -perfect hashing function that recognizes a member of the key set in -constant, i.e., O(1), time. If such a function is found the program -generates a pair of \fIC\fP source code routines that perform the -hashing and table lookup. All generated code is directed to the -standard output. - -Please refer to the \fIgperf.texinfo\fP file for more information. -This file is distributed with \fIgperf\fP release. diff --git a/apps/gperf/gperf.info b/apps/gperf/gperf.info deleted file mode 100644 index c553953d2c5..00000000000 --- a/apps/gperf/gperf.info +++ /dev/null @@ -1,1130 +0,0 @@ -This is Info file gperf.info, produced by Makeinfo version 1.68 from -the input file gperf.texi. - -START-INFO-DIR-ENTRY -* Gperf: (gperf). Perfect Hash Function Generator. -END-INFO-DIR-ENTRY - - This file documents the features of the GNU Perfect Hash Function -Generator - - Copyright (C) 1989 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 `gperf' General Public -License" an d this permission notice may be included in translations -approved by the Free Software Foundation instead of in the original -English. - - -File: gperf.info, Node: Top, Next: Copying, Prev: (dir), Up: (dir) - -GNU GPERF Utility -***************** - -Introduction -************ - - This manual documents the GNU `gperf' perfect hash function generator -utility, focusing on its features and how to use them, and how to report -bugs. - -* Menu: - -* Copying:: GNU `gperf' General Public License says - how you can copy and share `gperf'. -* Contributors:: People who have contributed to `gperf'. -* Motivation:: Static search structures and GNU GPERF. -* Search Structures:: Static search structures and GNU `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. - - -- The Detailed Node Listing -- - -High-Level Description of GNU `gperf' - -* Input Format:: Input Format to `gperf' -* Output Format:: Output Format for Generated C Code with `gperf' - -Input Format to `gperf' - -* Declarations:: `struct' Declarations and C Code Inclusion. -* Keywords:: Format for Keyword Entries. -* Functions:: Including Additional C Functions. - - -File: gperf.info, Node: Copying, Next: Contributors, Prev: Top, Up: Top - -GNU GENERAL PUBLIC LICENSE -************************** - - Version 1, February 1989 - - Copyright (C) 1989 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -Preamble -======== - - The license agreements of most software companies try to keep users -at the mercy of those companies. By contrast, our General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. The -General Public License applies to the Free Software Foundation's -software and to any other program whose authors commit to using it. -You can use it for your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Specifically, the General Public License is designed to make -sure that you have the freedom to give away or sell copies of free -software, that you receive source code or can get it if you want it, -that you can change the software or use pieces of it in new free -programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of a such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must tell them their rights. - - We protect your rights with two steps: (1) copyright the software, -and (2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 1. This License Agreement applies to any program or other work which - contains a notice placed by the copyright holder saying it may be - distributed under the terms of this General Public License. The - "Program", below, refers to any such program or work, and a "work - based on the Program" means either the Program or any work - containing the Program or a portion of it, either verbatim or with - modifications. Each licensee is addressed as "you". - - 2. You may copy and distribute verbatim copies of the Program's source - code as you receive it, in any medium, provided that you - conspicuously and appropriately publish on each copy an - appropriate copyright notice and disclaimer of warranty; keep - intact all the notices that refer to this General Public License - and to the absence of any warranty; and give any other recipients - of the Program a copy of this General Public License along with - the Program. You may charge a fee for the physical act of - transferring a copy. - - 3. You may modify your copy or copies of the Program or any portion of - it, and copy and distribute such modifications under the terms of - Paragraph 1 above, provided that you also do the following: - - * cause the modified files to carry prominent notices stating - that you changed the files and the date of any change; and - - * cause the whole of any work that you distribute or publish, - that in whole or in part contains the Program or any part - thereof, either with or without modifications, to be licensed - at no charge to all third parties under the terms of this - General Public License (except that you may choose to grant - warranty protection to some or all third parties, at your - option). - - * If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the simplest and most usual way, to print - or display an announcement including an appropriate copyright - notice and a notice that there is no warranty (or else, - saying that you provide a warranty) and that users may - redistribute the program under these conditions, and telling - the user how to view a copy of this General Public License. - - * You may charge a fee for the physical act of transferring a - copy, and you may at your option offer warranty protection in - exchange for a fee. - - Mere aggregation of another independent work with the Program (or - its derivative) on a volume of a storage or distribution medium - does not bring the other work under the scope of these terms. - - 4. You may copy and distribute the Program (or a portion or - derivative of it, under Paragraph 2) in object code or executable - form under the terms of Paragraphs 1 and 2 above provided that you - also do one of the following: - - * accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of - Paragraphs 1 and 2 above; or, - - * accompany it with a written offer, valid for at least three - years, to give any third party free (except for a nominal - charge for the cost of distribution) a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Paragraphs 1 and 2 above; or, - - * accompany it with the information you received as to where the - corresponding source code may be obtained. (This alternative - is allowed only for noncommercial distribution and only if you - received the program in object code or executable form alone.) - - Source code for a work means the preferred form of the work for - making modifications to it. For an executable file, complete - source code means all the source code for all modules it contains; - but, as a special exception, it need not include source code for - modules which are standard libraries that accompany the operating - system on which the executable file runs, or for standard header - files or definitions files that accompany that operating system. - - 5. You may not copy, modify, sublicense, distribute or transfer the - Program except as expressly provided under this General Public - License. Any attempt otherwise to copy, modify, sublicense, - distribute or transfer the Program is void, and will automatically - terminate your rights to use the Program under this License. - However, parties who have received copies, or rights to use - copies, from you under this General Public License will not have - their licenses terminated so long as such parties remain in full - compliance. - - 6. By copying, distributing or modifying the Program (or any work - based on the Program) you indicate your acceptance of this license - to do so, and all its terms and conditions. - - 7. 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. - - 8. The Free Software Foundation may publish revised and/or new - versions of the General Public License from time to time. Such - new versions will be similar in spirit to the present version, but - may differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the - Program specifies a version number of the license which applies to - it and "any later version", you have the option of following the - terms and conditions either of that version or of any later - version published by the Free Software Foundation. If the Program - does not specify a version number of the license, you may choose - any version ever published by the Free Software Foundation. - - 9. 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 - - 10. 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. - - 11. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN - WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY - MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE - LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, - INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR - INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF - DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU - OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY - OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - -Appendix: How to Apply These Terms to Your New Programs -======================================================= - - If you develop a new program, and you want it to be of the greatest -possible use to humanity, the best way to achieve this is to make it -free software which everyone can redistribute and change under these -terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES. - Copyright (C) 19YY NAME OF AUTHOR - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 1, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 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) 19YY NAME OF AUTHOR - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - - The hypothetical commands `show w' and `show c' should show the -appropriate parts of the General Public License. Of course, the -commands you use may be called something other than `show w' and `show -c'; they could even be mouse-clicks or menu items--whatever suits your -program. - - You should also get your employer (if you work as a programmer) or -your school, if any, to sign a "copyright disclaimer" for the program, -if necessary. Here a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - program `Gnomovision' (a program to direct compilers to make passes - at assemblers) written by James Hacker. - - SIGNATURE OF TY COON, 1 April 1989 - Ty Coon, President of Vice - - That's all there is to it! - - -File: gperf.info, Node: Contributors, Next: Motivation, Prev: Copying, Up: Top - -Contributors to GNU `gperf' Utility -*********************************** - - * The GNU `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 schmidt at - ics.uci.edu. - - * 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 `gperf'. - - -File: gperf.info, Node: Motivation, Next: Search Structures, Prev: Contributors, Up: Top - -Introduction -************ - - `gperf' is a perfect hash function generator written in C++. It -transforms an *n* element user-specified keyword set *W* into a perfect -hash function *F*. *F* uniquely maps keywords in *W* onto the range -0..*k*, where *k* >= *n*. If *k = n* then *F* is a *minimal* perfect -hash function. `gperf' generates a 0..*k* element static lookup table -and a pair of C functions. These functions determine whether a given -character string *s* occurs in *W*, using at most one probe into the -lookup table. - - `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 `gperf' is -available via anonymous ftp from ics.uci.edu. `gperf' also is -distributed along with the GNU libg++ library. A highly portable, -functionally equivalent K&R C version of `gperf' is archived in -comp.sources.unix, volume 20. Finally, a paper describing `gperf''s -design and implementation in greater detail is available in the Second -USENIX C++ Conference proceedings. - - -File: gperf.info, Node: Search Structures, Next: Description, Prev: Motivation, Up: Top - -Static search structures and GNU `gperf' -**************************************** - - A "static search structure" is an Abstract Data Type with certain -fundamental operations, *e.g.*, *initialize*, *insert*, and *retrieve*. -Conceptually, all insertions occur before any retrievals. In -practice, `gperf' generates a `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 *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 "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 *n* element -sorted array is space efficient, though the average-case time -complexity for retrieval operations using binary search is proportional -to log *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. - - *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: - - * It allows keyword recognition in a static search set using at most - *one* probe into the hash table. This represents the "perfect" - property. - - * The actual memory allocated to store the keywords is precisely - large enough for the keyword set, and *no larger*. This is the - "minimal" property. - - For most applications it is far easier to generate *perfect* hash -functions than *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. `gperf''s default behavior generates -*near-minimal* perfect hash functions for keyword sets. However, -`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 *once*, if it subsequently -receives heavy use multiple times. `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 `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 `gperf' -to automatically generate static search structures that efficiently -identify their respective reserved keywords. - - -File: gperf.info, Node: Description, Next: Options, Prev: Search Structures, Up: Top - -High-Level Description of GNU `gperf' -************************************* - -* Menu: - -* Input Format:: Input Format to `gperf' -* Output Format:: Output Format for Generated C Code with `gperf' - - The perfect hash function generator `gperf' reads a set of -"keywords" from a "keyfile" (or from the standard input by default). -It attempts to derive a perfect hashing function that recognizes a -member of the "static keyword set" with at most a single probe into the -lookup table. If `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 `gperf'. - - By default, `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 `gperf' to utilize a C `switch' statement -scheme that minimizes data space storage size. Furthermore, using a C -`switch' may actually speed up the keyword retrieval time somewhat. -Actual results depend on your C compiler, of course. - - In general, `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 `gperf' to find and generate a perfect hash function. -Experimentation is the key to getting the most from `gperf'. - - -File: gperf.info, Node: Input Format, Next: Output Format, Prev: Description, Up: Description - -Input Format to `gperf' -======================= - - You can control the input keyfile format by varying certain -command-line arguments, in particular the `-t' option. The input's -appearance is similar to GNU utilities `flex' and `bison' (or UNIX -utilities `lex' and `yacc'). Here's an outline of the general format: - - declarations - %% - keywords - %% - functions - - *Unlike* `flex' or `bison', all sections of `gperf''s input are -optional. The following sections describe the input format for each -section. - -* Menu: - -* Declarations:: `struct' Declarations and C Code Inclusion. -* Keywords:: Format for Keyword Entries. -* Functions:: Including Additional C Functions. - - -File: gperf.info, Node: Declarations, Next: Keywords, Prev: Input Format, Up: Input Format - -`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 `struct'. If the `-t' option *is* enabled, -you *must* provide a C `struct' as the last component in the -declaration section from the keyfile file. The first field in this -struct must be a `char *' identifier called "name," although it is -possible to modify this field's name with the `-K' option described -below. - - Here is simple example, using months of the year and their -attributes as input: - - 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 - - Separating the `struct' declaration from the list of key words and -other fields are a pair of consecutive percent signs, `%%', appearing -left justified in the first column, as in the UNIX utility `lex'. - - Using a syntax similar to GNU utilities `flex' and `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 `%{', `%}' pairs. Here is an input -fragment based on the previous example that illustrates this feature: - - %{ - #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 - ... - - It is possible to omit the declaration section entirely. In this -case the keyfile begins directly with the first keyword line, *e.g.*: - - january, 1, 31, 31 - february, 2, 28, 29 - march, 3, 31, 31 - april, 4, 30, 30 - ... - - -File: gperf.info, Node: Keywords, Next: Functions, Prev: Declarations, Up: Input Format - -Format for Keyword Entries --------------------------- - - The second keyfile format section contains lines of keywords and any -associated attributes you might supply. A line beginning with `#' in -the first column is considered a comment. Everything following the `#' -is ignored, up to and including the following newline. - - The first field of each non-comment line is always the key itself. -It should be given as a simple name, *i.e.*, without surrounding string -quotation marks, and be left-justified flush against the first column. -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: - - # 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 - - Note that unlike `flex' or `bison' the first `%%' 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 `struct' provided by you in the -declaration section. If the `-t' option is *not* enabled these fields -are simply ignored. All previous examples except the last one contain -keyword attributes. - - -File: gperf.info, Node: Functions, Prev: Keywords, Up: Input Format - -Including Additional C Functions --------------------------------- - - The optional third section also corresponds closely with conventions -found in `flex' and `bison'. All text in this section, starting at the -final `%%' 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. - - -File: gperf.info, Node: Output Format, Prev: Input Format, Up: Description - -Output Format for Generated C Code with `gperf' -=============================================== - - Several options control how the generated C code appears on the -standard output. Two C function are generated. They are called `hash' -and `in_word_set', although you may modify the name for `in_word_set' -with a command-line option. Both functions require two arguments, a -string, `char *' STR, and a length parameter, `int' LEN. Their default -function prototypes are as follows: - - static int hash (char *str, int len); - int in_word_set (char *str, int len); - - By default, the generated `hash' function returns an integer value -created by adding LEN to several user-specified STR key positions -indexed into an "associated values" table stored in a local static -array. The associated values table is constructed internally by -`gperf' and later output as a static local C array called HASH_TABLE; -its meaning and properties are described below. *Note -Implementation::. The relevant key positions are specified via the `-k' -option when running `gperf', as detailed in the *Options* section -below. *Note Options::. - - Two options, `-g' (assume you are compiling with GNU C and its -`inline' feature) and `-a' (assume ANSI C-style function prototypes), -alter the content of both the generated `hash' and `in_word_set' -routines. However, function `in_word_set' may be modified more -extensively, in response to your option settings. The options that -affect the `in_word_set' structure are: - - `-p' - Have function `in_word_set' return a pointer rather than a - boolean. - - `-t' - Make use of the user-defined `struct'. - - `-S TOTAL SWITCH STATEMENTS' - Generate 1 or more C `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. - - If the `-t', `-S', and `-p' options are omitted the default action -is to generate a `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. - - -File: gperf.info, Node: Options, Next: Bugs, Prev: Description, Up: Top - -Options to the `gperf' Utility -****************************** - - There are *many* options to `gperf'. They were added to make the -program more convenient for use with real applications. "On-line" help -is readily available via the `-h' option. Other options include: - - `-a' - Generate ANSI Standard C code using function prototypes. The - default is to use "classic" K&R C function declaration syntax. - - `-c' - Generates C code that uses the `strncmp' function to perform - string comparisons. The default action is to use `strcmp'. - - `-C' - 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. - - `-d' - Enables the debugging option. This produces verbose - diagnostics to "standard error" when `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 `-d' - option is enabled. - - `-D' - Handle keywords whose key position sets hash to duplicate - values. Duplicate hash values occur for two reasons: - - * Since `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. - - * Sometimes a set of keys may have the same names, but - possess different attributes. With the -D option - `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, `gperf' helps you out by - organizing the output. - - Option `-D' is extremely useful for certain large or highly - redundant keyword sets, *i.e.*, assembler instruction opcodes. - Using this option usually means that the generated hash - function is no longer perfect. On the other hand, it permits - `gperf' to work on keyword sets that it otherwise could not - handle. - - `-e KEYWORD DELIMITER LIST' - 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. - - `-E' - 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 (jjc at ai.mit.edu). - - `-f ITERATION AMOUNT' - Generate the perfect hash function "fast." This decreases - `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 `-D' and/or - `-S' for *large* keyword sets. - - `-g' - Assume a GNU compiler, *e.g.*, `g++' or `gcc'. This makes - all generated routines use the "inline" keyword to remove the - cost of function calls. Note that `-g' does *not* imply - `-a', since other non-ANSI C compilers may have provisions - for a function `inline' feature. - - `-G' - 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). - - `-h' - Prints a short summary on the meaning of each program option. - Aborts further program execution. - - `-H HASH FUNCTION NAME' - Allows you to specify the name for the generated hash - function. Default name is `hash.' This option permits the - use of two hash tables in the same file. - - `-i INITIAL VALUE' - Provides an initial 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 `-S' is used. Also, `-i' is overriden when the - `-r' option is used. - - `-j JUMP VALUE' - Affects the "jump value," *i.e.*, how far to advance the - associated character value upon collisions. JUMP VALUE is - rounded up to an odd number, the default is 5. If the JUMP - VALUE is 0 `gper f' jumps by random amounts. - - `-k 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.*, `-k 9,4,13,14'; ranges may be used, *e.g.*, `-k 2-7'; - and positions may occur in any order. Furthermore, the - meta-character '*' causes the generated hash function to - consider *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 `-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. - - `-K KEY NAME' - By default, the program assumes the structure component - identifier for the keyword is "name." This option allows an - arbitrary choice of identifier for this component, although - it still must occur as the first field in your supplied - `struct'. - - `-l' - 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 `strcmp'. However, using `-l' might - greatly increase the size of the generated C code if the - lookup table range is large (which implies that the switch - option `-S' is not enabled), since the length table contains - as many elements as there are entries in the lookup table. - - `-L GENERATED LANGUAGE NAME' - Instructs `gperf' to generate code in the language specified - by the option's argument. Languages handled are currently - C++ and C. The default is C. - - `-n' - 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. - - `-N LOOKUP FUNCTION NAME' - Allows you to specify the name for the generated lookup - function. Default name is `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. - - `-o' - 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 *very* large using - `-o' may *increase* `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. - - `-p' - Changes the return value of the generated function - `in_word_set' from boolean (*i.e.*, 0 or 1), to either type - "pointer to user-defined struct," (if the `-t' option is - enabled), or simply to `char *', if `-t' is not enabled. - This option is most useful when the `-t' option (allowing - user-defined structs) is used. For example, it is possible - to automatically generate the GNU C reserved word lookup - routine with the options `-p' and `-t'. - - `-r' - 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 `gperf' has - difficultly with a certain keyword set try using `-r' or `-D'. - - `-s 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 SIZE-MULTIPLE is - negative the maximum associated value is calculated by - *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 `-S' is *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 `gperf''s - runtime, since it must search through a much larger range of - values. Judicious use of the `-f' option helps alleviate this - overhead, however. - - `-S TOTAL SWITCH STATEMENTS' - 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 argument to this option 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 `switch', etc. This - is useful since many C compilers cannot correctly generate - code for large `switch' statements. This option was inspired - in part by Keith Bostic's original C program. - - `-t' - Allows you to include a `struct' type declaration for - generated code. Any text before a pair of consecutive %% is - consider part of the type declaration. Key words 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, and G++, Pascal, and Modula 2 and 3 - reserved words are distributed with this release. - - `-T' - Prevents the transfer of the type declaration to the output - file. Use this option if the type is already defined - elsewhere. - - `-v' - Prints out the current version number. - - `-Z CLASS NAME' - Allow user to specify name of generated C++ class. Default - name is `Perfect_Hash'. - - -File: gperf.info, Node: Bugs, Next: Projects, Prev: Options, Up: Top - -Known Bugs and Limitations with `gperf' -*************************************** - - The following are some limitations with the current release of -`gperf': - - * The `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 - `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 `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 `-r' option, and also try changing the default - arguments to the `-s' and `-j' options. To *guarantee* a - solution, use the `-D' and `-S' options, although the final - results are not likely to be a *perfect* hash function anymore! - Finally, use the `-f' option if you want `gperf' to generate the - perfect hash function *fast*, with less emphasis on making it - minimal. - - * The size of the generate static keyword array can get *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 *greatly* inflates the object code size. If - this situation occurs, consider using the `-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 -S option with an appropriate numerical argument that - controls the number of switch statements generated. - - * 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. - - * The C++ source code only compiles correctly with GNU G++, version - 1.36 (and hopefully later versions). Porting to AT&T cfront would - be tedious, but possible (and desirable). There is also a K&R C - version available now. This should compile without change on most - BSD systems, but may require a bit of work to run on SYSV, since - `gperf' uses ALLOCA in several places. Send mail to schmidt at - ics.uci.edu for information. - - -File: gperf.info, Node: Projects, Next: Implementation, Prev: Bugs, Up: Top - -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: - - * Make the algorithm more robust. At present, the program halts - with an error diagnostic if it can't find a direct solution and - the `-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. - - * 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 `-S' - `switch' option can minimize the data size, at the expense of - slightly longer lookups (note that the gcc compiler generally - produces good code for `switch' statements, reducing the need for - more complex schemes). - - * 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. - - -File: gperf.info, Node: Implementation, Next: Bibliography, Prev: Projects, Up: Top - -Implementation Details of GNU `gperf' -************************************* - - A paper describing the high-level description of the data structures -and algorithms used to implement `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. - - -File: gperf.info, Node: Bibliography, Prev: Implementation, Up: Top - -Bibliography -************ - - [1] Chang, C.C.: A Scheme for Constructing Ordered Minimal Perfect -Hashing Functions Information Sciences 39(1986), 187-195. - - [2] Cichelli, Richard J. Author's Response to "On Cichelli's Minimal -Perfec t Hash Functions Method" Communications of the ACM, 23, -12(December 1980), 729. - - [3] Cichelli, Richard J. Minimal Perfect Hash Functions Made Simple -Communications of the ACM, 23, 1(January 1980), 17-19. - - [4] Cook, C. R. and Oldehoeft, R.R. 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. -Practical Perfect Hashing Computer Journal, 28, 1(January 1985), 54-58. - - [6] Jaeschke, G. 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. On Cichelli's Minimal Perfect -Hash Functions Method Communications of the ACM, 23, 12(December 1980), -728-729. - - [8] Sager, Thomas J. A Polynomial Time Generator for Minimal Perfect -Hash Functions Communications of the ACM, 28, 5(December 1985), 523-532 - - [9] Schmidt, Douglas C. GPERF: A Perfect Hash Function Generator -Second USENIX C++ Conference Proceedings, April 1990. - - [10] Sebesta, R.W. and Taylor, M.A. Minimal Perfect Hash Functions -for Reserved Word Lists SIGPLAN Notices, 20, 12(September 1985), 47-53. - - [11] Sprugnoli, R. 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. Using and Porting GNU CC Free Software -Foundation, 1988. - - [13] Stroustrup, Bjarne The C++ Programming Language. -Addison-Wesley, 1986. - - [14] Tiemann, Michael D. User's Guide to GNU C++ Free Software -Foundation, 1989. - - - -Tag Table: -Node: Top1224 -Node: Copying2499 -Node: Contributors15802 -Node: Motivation16902 -Node: Search Structures18169 -Node: Description21722 -Node: Input Format23542 -Node: Declarations24337 -Node: Keywords26644 -Node: Functions28235 -Node: Output Format28729 -Node: Options31199 -Node: Bugs44569 -Node: Projects47256 -Node: Implementation48833 -Node: Bibliography49552 - -End Tag Table diff --git a/apps/gperf/gperf.texi b/apps/gperf/gperf.texi deleted file mode 100644 index c80f227e956..00000000000 --- a/apps/gperf/gperf.texi +++ /dev/null @@ -1,1188 +0,0 @@ -\input texinfo @c -*-texinfo-*- - -@c $Id$ - -@include version.texi - -@c %**start of header -@settitle User's Guide to @code{gperf} -@setfilename gperf.info -@c %**end of header - -@ifinfo -@format -START-INFO-DIR-ENTRY -* Gperf: (gperf). Perfect Hash Function Generator. -END-INFO-DIR-ENTRY -@end format -@end ifinfo - -@ifinfo -This file documents the features of the GNU Perfect Hash Function Generator - -Copyright (C) 1989 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 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 @code{gperf} General Public License'' an -d -this permission notice may be included in translations approved by the -Free Software Foundation instead of in the original English. -@end ifinfo - -@setchapternewpage odd - -@titlepage -@title GNU GPERF Utility -@subtitle User's Guide -@subtitle Last updated @value{UPDATED} -@subtitle For GPERF version @value{VERSION} -@author Douglas C. Schmidt - -@c The following two commands -@c start the copyright page. -@page -@vskip 0pt plus 1filll -Copyright @copyright{} 1989 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 @code{gperf} General Public License'' is included exactl -y 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 @code{gperf} General Public License'' ma -y be -included in a translation approved by the author instead of in the original -English. -@end titlepage - -@ifinfo -@node Top, Copying, (dir), (dir) -@top GNU GPERF Utility -@chapter 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. - -@end ifinfo -@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. - - --- 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} - -Input Format to @code{gperf} - -* Declarations:: @code{struct} Declarations and C Code Inclusion. -* Keywords:: Format for Keyword Entries. -* Functions:: Including Additional C Functions. -@end menu - -@node Copying, Contributors, Top, Top -@unnumbered GNU GENERAL PUBLIC LICENSE -@center Version 1, February 1989 - -@display -Copyright @copyright{} 1989 Free Software Foundation, Inc. -675 Mass Ave, Cambridge, MA 02139, USA - -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. -@end display - -@unnumberedsec Preamble - - The license agreements of most software companies try to keep users -at the mercy of those companies. By contrast, our General Public -License is intended to guarantee your freedom to share and change free -software---to make sure the software is free for all its users. The -General Public License applies to the Free Software Foundation's -software and to any other program whose authors commit to using it. -You can use it for your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Specifically, the General Public License is designed to make -sure that you have the freedom to give away or sell copies of free -software, that you receive source code or can get it if you want it, -that you can change the software or use pieces of it in new free -programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of a such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must tell them their rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - The precise terms and conditions for copying, distribution and -modification follow. - -@iftex -@unnumberedsec TERMS AND CONDITIONS -@end iftex -@ifinfo -@center TERMS AND CONDITIONS -@end ifinfo - -@enumerate -@item -This License Agreement applies to any program or other work which -contains a notice placed by the copyright holder saying it may be -distributed under the terms of this General Public License. The -``Program'', below, refers to any such program or work, and a ``work based -on the Program'' means either the Program or any work containing the -Program or a portion of it, either verbatim or with modifications. Each -licensee is addressed as ``you''. - -@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 -General Public License and to the absence of any warranty; and give any -other recipients of the Program a copy of this General Public License -along with the Program. You may charge a fee for the physical act of -transferring a copy. - -@item -You may modify your copy or copies of the Program or any portion of -it, and copy and distribute such modifications under the terms of Paragraph -1 above, provided that you also do the following: - -@itemize @bullet -@item -cause the modified files to carry prominent notices stating that -you changed the files and the date of any change; and - -@item -cause the whole of any work that you distribute or publish, that -in whole or in part contains the Program or any part thereof, either -with or without modifications, to be licensed at no charge to all -third parties under the terms of this General Public License (except -that you may choose to grant warranty protection to some or all -third parties, at your option). - -@item -If the modified program normally reads commands interactively when -run, you must cause it, when started running for such interactive use -in the simplest and most usual way, to print or display an -announcement including an appropriate copyright notice and a notice -that there is no warranty (or else, saying that you provide a -warranty) and that users may redistribute the program under these -conditions, and telling the user how to view a copy of this General -Public License. - -@item -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. -@end itemize - -Mere aggregation of another independent work with the Program (or its -derivative) on a volume of a storage or distribution medium does not bring -the other work under the scope of these terms. - -@item -You may copy and distribute the Program (or a portion or derivative of -it, under Paragraph 2) in object code or executable form under the terms of -Paragraphs 1 and 2 above provided that you also do one of the following: - -@itemize @bullet -@item -accompany it with the complete corresponding machine-readable -source code, which must be distributed under the terms of -Paragraphs 1 and 2 above; or, - -@item -accompany it with a written offer, valid for at least three -years, to give any third party free (except for a nominal charge -for the cost of distribution) a complete machine-readable copy of the -corresponding source code, to be distributed under the terms of -Paragraphs 1 and 2 above; or, - -@item -accompany it with the information you received as to where the -corresponding source code may be obtained. (This alternative is -allowed only for noncommercial distribution and only if you -received the program in object code or executable form alone.) -@end itemize - -Source code for a work means the preferred form of the work for making -modifications to it. For an executable file, complete source code means -all the source code for all modules it contains; but, as a special -exception, it need not include source code for modules which are standard -libraries that accompany the operating system on which the executable -file runs, or for standard header files or definitions files that -accompany that operating system. - -@item -You may not copy, modify, sublicense, distribute or transfer the -Program except as expressly provided under this General Public License. -Any attempt otherwise to copy, modify, sublicense, distribute or transfer -the Program is void, and will automatically terminate your rights to use -the Program under this License. However, parties who have received -copies, or rights to use copies, from you under this General Public -License will not have their licenses terminated so long as such parties -remain in full compliance. - -@item -By copying, distributing or modifying the Program (or any work based -on the Program) you indicate your acceptance of this license to do so, -and all its terms and conditions. - -@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. - -@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 the license which applies to it and ``any -later version'', you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -the license, you may choose any version ever published by the Free Software -Foundation. - -@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 -@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 Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to humanity, the best way to achieve this is to make it -free software which everyone can redistribute and change under these -terms. - - To do so, attach the following notices to the program. It is safest to -attach them to the start of each source file to most effectively convey -the exclusion of warranty; and each file should have at least the -``copyright'' line and a pointer to where the full notice is found. - -@smallexample -@var{one line to give the program's name and a brief idea of what it does.} -Copyright (C) 19@var{yy} @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 1, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 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) 19@var{yy} @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 `show w' and `show c' should show the -appropriate parts of the General Public License. Of course, the -commands you use may be called something other than `show w' and `show -c'; they could even be mouse-clicks or menu items---whatever suits your -program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a ``copyright disclaimer'' for the program, if -necessary. Here a sample; alter the names: - -@example -Yoyodyne, Inc., hereby disclaims all copyright interest in the -program `Gnomovision' (a program to direct compilers to make passes -at assemblers) written by James Hacker. - -@var{signature of Ty Coon}, 1 April 1989 -Ty Coon, President of Vice -@end example - -That's all there is to it! - -@node Contributors, Motivation, Copying, Top -@unnumbered Contributors to GNU @code{gperf} Utility - -@itemize @bullet -@item -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 schmidt at ics.uci.edu. - -@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}. -@end itemize - -@node Motivation, Search Structures, Contributors, Top -@chapter Introduction - -@code{gperf} is a perfect hash function generator written in C++. It -transforms an @emph{n} element user-specified keyword set @emph{W} into -a perfect hash function @emph{F}. @emph{F} uniquely maps keywords in -@emph{W} onto the range 0..@emph{k}, where @emph{k} >= @emph{n}. If -@emph{k = n} then @emph{F} is a @emph{minimal} perfect hash function. -@code{gperf} generates a 0..@emph{k} element static lookup table and a -pair of C functions. These functions determine whether a given -character string @emph{s} occurs in @emph{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 ics.uci.edu. @code{gperf} also is -distributed along with the GNU libg++ library. A highly portable, -functionally equivalent K&R C version of @code{gperf} is archived in -comp.sources.unix, volume 20. Finally, 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} - -A @dfn{static search structure} is an Abstract Data Type with certain -fundamental operations, @emph{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, @emph{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 @emph{n} element -sorted array is space efficient, though the average-case time -complexity for retrieval operations using binary search is -proportional to log @emph{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. - - -@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} -@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} - -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 *} identifier called ``name,'' -although it is possible to modify this field's name with the @samp{-K} -option described below. - -Here is 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 - -Separating the @code{struct} declaration from the list of key words and -other fields are a pair of consecutive percent signs, @code{%%}, -appearing left justified in the first column, as in the UNIX utility -@code{lex}. - -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 @code{%@{}, @code{%@}} 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, @emph{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 -should be given as a simple name, @emph{i.e.}, without surrounding -string quotation marks, and be left-justified flush against the first -column. 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.@code{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 @code{%%} 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 @code{%%} 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, , Input Format, Description -@section Output Format for Generated C Code with @code{gperf} - -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 the name for -@code{in_word_set} 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: - -@example -@group -static int hash (char *str, int len); -int in_word_set (char *str, int len); -@end group -@end example - -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 -@var{hash_table}; its meaning and properties are described below. -@xref{Implementation}. The relevant key positions are specified via the -@samp{-k} option when running @code{gperf}, as detailed in the @emph{Options} -section below. @xref{Options}. - -Two options, @samp{-g} (assume you are compiling with GNU C and its -@code{inline} feature) and @samp{-a} (assume ANSI C-style function -prototypes), alter the content of both the generated @code{hash} and -@code{in_word_set} routines. However, function @code{in_word_set} may -be modified more extensively, in response to your option settings. The -options that affect the @code{in_word_set} structure are: - -@itemize @bullet -@table @samp -@item -p -Have function @code{in_word_set} return a pointer rather than a boolean. - -@item -t -Make use of the user-defined @code{struct}. - -@item -S @var{total switch statements} -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 -@end itemize - -If the @samp{-t}, @samp{-S}, and @samp{-p} 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 Options, Bugs, Description, Top -@chapter Options to the @code{gperf} Utility - -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. Other options -include: - -@itemize @bullet -@table @samp -@item -a -Generate ANSI Standard C code using function prototypes. The default is -to use ``classic'' K&R C function declaration syntax. - -@item -c -Generates C code that uses the @code{strncmp} function to perform -string comparisons. The default action is to use @code{strcmp}. - -@item -C -Makes the contents of all generated lookup tables constant, @emph{i.e.}, -``readonly.'' Many compilers can generate more efficient code for this -by putting the tables in readonly memory. - -@item -d -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. - -@item -D -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, @emph{i.e.}, 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 -e @var{keyword delimiter list} -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 -E -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 (jjc at ai.mit.edu). - -@item -f @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 -g -Assume a GNU compiler, @emph{e.g.}, @code{g++} or @code{gcc}. This -makes all generated routines use the ``inline'' keyword to remove the -cost of function calls. Note that @samp{-g} does @emph{not} imply -@samp{-a}, since other non-ANSI C compilers may have provisions for a -function @code{inline} feature. - -@item -G -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 -h -Prints a short summary on the meaning of each program option. Aborts -further program execution. - -@item -H @var{hash function name} -Allows you to specify the name for the generated hash function. Default -name is `hash.' This option permits the use of two hash tables in the -same file. - -@item -i @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 overriden when the @samp{-r} option is used. - -@item -j @var{jump value} -Affects the ``jump value,'' @emph{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{gper -f} -jumps by random amounts. - -@item -k @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, @emph{e.g.}, @samp{-k 9,4,13,14}; -ranges may be used, @emph{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 -K @var{key name} -By default, the program assumes the structure component identifier for -the keyword is ``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 -l -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. - -@item -L @var{generated language name} -Instructs @code{gperf} to generate code in the language specified by the -option's argument. Languages handled are currently C++ and C. The -default is C. - -@item -n -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 -N @var{lookup function name} -Allows you to specify the name for the generated lookup function. -Default name is `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 -o -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 -p -Changes the return value of the generated function @code{in_word_set} -from boolean (@emph{i.e.}, 0 or 1), to either type ``pointer to -user-defined struct,'' (if the @samp{-t} option is enabled), or simply -to @code{char *}, if @samp{-t} is not enabled. This option is most -useful when the @samp{-t} option (allowing user-defined structs) is -used. For example, it is possible to automatically generate the GNU C -reserved word lookup routine with the options @samp{-p} and @samp{-t}. - -@item -r -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} -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. - -@item -S @var{total switch statements} -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 -Allows you to include a @code{struct} type declaration for generated -code. Any text before a pair of consecutive %% is consider part of the -type declaration. Key words 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, and G++, Pascal, and Modula 2 and 3 -reserved words are distributed with this release. - -@item -T -Prevents the transfer of the type declaration to the output file. Use -this option if the type is already defined elsewhere. - -@item -v -Prints out the current version number. - -@item -Z @var{class name} -Allow user to specify name of generated C++ class. Default name is -@code{Perfect_Hash}. -@end table -@end itemize - -@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. - -@item -The C++ source code only compiles correctly with GNU G++, version 1.36 -(and hopefully later versions). Porting to AT&T cfront would be -tedious, but possible (and desirable). There is also a K&R C version -available now. This should compile without change on most BSD systems, -but may require a bit of work to run on SYSV, since @code{gperf} uses -@var{alloca} in several places. Send mail to schmidt at ics.uci.edu for -information. -@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, @emph{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, , 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 Perfec -t 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. - -@contents -@bye diff --git a/apps/gperf/src/Bool_Array.cpp b/apps/gperf/src/Bool_Array.cpp deleted file mode 100644 index d45da07c905..00000000000 --- a/apps/gperf/src/Bool_Array.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// $Id$ - -/* Fast lookup table abstraction implemented as an Iteration Number Array - - Copyright (C) 1989 Free Software Foundation, Inc. - written by Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) -any later version. - -GNU GPERF is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ - -#include "Bool_Array.h" - -ACE_RCSID(src, Bool_Array, "$Id$") - -#if defined (ACE_HAS_GPERF) - -// Prints out debugging diagnostics. - -Bool_Array::~Bool_Array (void) -{ - if (option[DEBUG]) - ACE_DEBUG ((LM_DEBUG, - "\ndumping boolean array information\n" - "size = %u\niteration number = %u\nend of array dump\n", - size_, - generation_number_)); - delete [] this->storage_array_; -} - -Bool_Array::Bool_Array (void) - : storage_array_ (0), - generation_number_ (0), - size_ (0) -{ -} - -int -Bool_Array::open (u_long s) -{ - this->generation_number_ = 1; - this->size_ = s; - - ACE_NEW_RETURN (storage_array_, - u_long[s], - -1); - - ACE_OS::memset (storage_array_, - 0, - s * sizeof *storage_array_); - - if (option[DEBUG]) - ACE_DEBUG ((LM_DEBUG, - "\nbool array size = %u, total bytes = %u\n", - size_, - size_ * (int) sizeof *storage_array_)); - return 0; -} - -int -Bool_Array::find (u_long index) -{ - if (storage_array_[index] == generation_number_) - return 1; - else - { - storage_array_[index] = generation_number_; - return 0; - } -} - -void -Bool_Array::reset (void) -{ - if (++generation_number_ == 0) - { - if (option[DEBUG]) - ACE_DEBUG ((LM_DEBUG, - "(re-initializing bool_array)...")); - - this->generation_number_ = 1; - ACE_OS::memset (storage_array_, - 0, - size_ * sizeof *storage_array_); - if (option[DEBUG]) - ACE_DEBUG ((LM_DEBUG, - "done\n")); - } -} - -#endif /* ACE_HAS_GPERF */ diff --git a/apps/gperf/src/Bool_Array.h b/apps/gperf/src/Bool_Array.h deleted file mode 100644 index 0e869b1a128..00000000000 --- a/apps/gperf/src/Bool_Array.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -/* Copyright (C) 1989 Free Software Foundation, Inc. - written by Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 1, or (at your option) any -later version. - -GNU GPERF is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA.*/ - -#ifndef BOOL_ARRAY_H -#define BOOL_ARRAY_H - -#include "ace/OS.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "Options.h" - -#if defined (ACE_HAS_GPERF) - -class Bool_Array -{ - // = TITLE - // Efficient lookup table abstraction implemented as a "Generation - // Number" Array. - // - // = DESCRIPTION - // Uses a "Generation Numbering" implementation to minimize - // initialization time. -public: - // = Initialization and termination methods. - Bool_Array (void); - // Constructor - - int open (u_long); - // Initialize the array (requires O(n) time). - - ~Bool_Array (void); - // Destructor. - - int find (u_long value); - // Locate the <value> in the array (requires O(1) time). - - void reset (void); - // Reinitializes the array (requires O(1) time). - -private: - u_long *storage_array_; - // Initialization of the index space. - - u_long generation_number_; - // Keep track of the current Generation. - - u_long size_; - // Keep track of array size. -}; - -#endif /* ACE_HAS_GPERF */ -#endif /* BOOL_ARRAY_H */ - diff --git a/apps/gperf/src/Gen_Perf.cpp b/apps/gperf/src/Gen_Perf.cpp deleted file mode 100644 index 0e7fe834556..00000000000 --- a/apps/gperf/src/Gen_Perf.cpp +++ /dev/null @@ -1,453 +0,0 @@ -// $Id$ - -/* Copyright (C) 1989 Free Software Foundation, Inc. - written by Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 1, or (at your option) any -later version. - -GNU GPERF is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, -USA. */ - -#include "Gen_Perf.h" - -ACE_RCSID(src, Gen_Perf, "$Id$") - -#if defined (ACE_HAS_GPERF) - -#include "Vectors.h" - -// Current release version. -extern char *version_string; - -// 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) - : fewest_collisions (0), - num_done (1) -{ -} - -// 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 set1 and set2 must be -// ordered. Returns the length of the combined set. - -int -Gen_Perf::compute_disjoint_union (char *set1, char *set2, char *set3) -{ - char *base = set3; - - while (*set1 && *set2) - if (*set1 == *set2) - set1++, set2++; - else - { - *set3 = *set1 < *set2 ? *set1++ : *set2++; - if (set3 == base || *set3 != *(set3 - 1)) - set3++; - } - - while (*set1) - { - *set3 = *set1++; - if (set3 == base || *set3 != *(set3 - 1)) - set3++; - } - - while (*set2) - { - *set3 = *set2++; - if (set3 == base || *set3 != *(set3 - 1)) - set3++; - } - *set3 = '\0'; - return set3 - 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. - -void -Gen_Perf::sort_set (char *union_set, int len) -{ - for (int i = 0, j = len - 1; i < j; i++) - { - char curr, tmp; - - for (curr = i + 1, tmp = union_set[curr]; - curr > 0 - && Vectors::occurrences[tmp] < Vectors::occurrences[union_set[curr-1]]; - curr--) - union_set[curr] = union_set[curr - 1]; - - union_set[curr] = tmp; - } -} - -// Generate a keysig's hash value. - -int -Gen_Perf::hash (List_Node *key_node) -{ - int sum = option[NOLENGTH] ? 0 : key_node->length; - - for (char *ptr = key_node->keysig; *ptr; ptr++) - sum += Vectors::asso_values[*ptr]; - - key_node->hash_value = sum; - return sum; -} - -// Find out how character value change affects successfully hash -// 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 Vectors::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) -{ - int original_char = Vectors::asso_values[c]; - int total_iterations; - - if (!option[FAST]) - total_iterations = option.asso_max (); - else - { - total_iterations = option.iterations (); - - if (total_iterations == 0) - total_iterations = this->key_list.keyword_list_length (); - } - - // Try all legal associated values. - - for (int i = total_iterations - 1; i >= 0; i--) - { - int collisions = 0; - - Vectors::asso_values[c] = Vectors::asso_values[c] + - (option.jump () ? option.jump () : ACE_OS::rand ()) & option.asso_max () - 1; - - // Iteration Number array is a win, O(1) intialization time! - this->char_search.reset (); - - // See how this asso_value change affects previous keywords. If - // it does better than before we'll take it! - - for (List_Node *ptr = this->key_list.head; - this->char_search.find (this->hash (ptr)) == 0 - || ++collisions < fewest_collisions; - ptr = ptr->next) - if (ptr == curr) - { - fewest_collisions = collisions; - if (option[DEBUG]) - ACE_DEBUG ((LM_DEBUG, - "- resolved after %d iterations", - total_iterations - i)); - return 0; - } - } - - // Restore original values, no more tries. - Vectors::asso_values[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. - -int -Gen_Perf::change (List_Node *prior, List_Node *curr) -{ - if (option[DEBUG]) - ACE_DEBUG ((LM_DEBUG, - "collision on keyword #%d, prior = \"%s\", curr = \"%s\" hash = %d\n", - num_done, - prior->key, - curr->key, - curr->hash_value)); - Gen_Perf::sort_set (this->union_set, - compute_disjoint_union (prior->keysig, - curr->keysig, - this->union_set)); - - // Try changing some values, if change doesn't alter other values - // continue normal action. - fewest_collisions++; - - for (char *temp = union_set; *temp != '\0'; temp++) - if (affects_prev (*temp, curr) == 0) - { - if (option[DEBUG]) - ACE_DEBUG ((LM_DEBUG, - " by changing asso_value['%c'] (char #%d) to %d\n", - *temp, - temp - union_set + 1, - Vectors::asso_values[*temp])); - // Good, doesn't affect previous hash values, we'll take it. - return 0; - } - - for (List_Node *ptr = this->key_list.head; - ptr != curr; - ptr = ptr->next) - this->hash (ptr); - - this->hash (curr); - - if (option[DEBUG]) - ACE_DEBUG ((LM_DEBUG, - "** collision not resolved after %d iterations, %d duplicates remain, continuing...\n", - !option[FAST] ? option.asso_max () : option.iterations () ? option.iterations () : this->key_list.keyword_list_length (), - fewest_collisions + this->key_list.total_duplicates)); - return 0; -} - -int -Gen_Perf::open (void) -{ - if (this->key_list.read_keys () == -1) - return -1; - - if (option[ORDER]) - this->key_list.reorder (); - - int asso_value_max = option.asso_max (); - int non_linked_length = this->key_list.keyword_list_length (); - - 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.asso_max (ACE_POW (asso_value_max)); - - if (option[RANDOM]) - { - ACE_OS::srand (ACE_OS::time (0)); - - for (int i = 0; i < Vectors::ALPHA_SIZE; i++) - Vectors::asso_values[i] = (ACE_OS::rand () & asso_value_max - 1); - } - else - { - int asso_value = option.initial_value (); - - // Initialize array if user requests non-zero default. - if (asso_value) - for (int i = Vectors::ALPHA_SIZE - 1; i >= 0; i--) - Vectors::asso_values[i] = asso_value & option.asso_max () - 1; - } - - this->max_hash_value = this->key_list.max_key_length () - + option.asso_max () - * option.max_keysig_size (); - - ACE_NEW_RETURN (this->union_set, - char[2 * option.max_keysig_size () + 1], - -1); - printf ("/* "); - - if (option[C]) - printf ("C"); - - else if (option[CPLUSPLUS]) - printf ("C++"); - - printf (" code produced by gperf version %s */\n", - version_string); - Options::print_options (); - - if (option[DEBUG]) - ACE_DEBUG ((LM_DEBUG, - "total non-linked keys = %d\n" - "total duplicates = %d\n" - "maximum associated value is %d\n" - "maximum size of generated hash table is %d\n", - non_linked_length, - this->key_list.total_duplicates, - asso_value_max, - max_hash_value)); - if (this->char_search.open (max_hash_value + 1) == -1) - return -1; - return 0; -} - -// For binary search, do normal string sort on the keys, and then -// assign hash values from 0 to N-1. Then go ahead with the normal -// logic that is there for perfect hashing. -int -Gen_Perf::compute_binary_search (void) -{ - // Do a string sort. - this->key_list.string_sort (); - - // Assign hash values. - List_Node *curr; - int hash_value; - for (hash_value = 0, curr = this->key_list.head; - curr != 0; - curr = curr->next, hash_value++) - { - curr->hash_value = hash_value; - } - - return 0; -} - -int -Gen_Perf::compute_linear_search (void) -{ - // Convert the list of keys to a linear list without - // equivalence classes. - this->key_list.string_sort (); - - // Assign hash values. - List_Node *curr; - int hash_value; - for (hash_value = 0, curr = this->key_list.head; - curr != 0; - curr = curr->next, hash_value++) - { - curr->hash_value = hash_value; - } - return 0; -} - -int -Gen_Perf::compute_perfect_hash (void) -{ - List_Node *curr; - - for (curr = this->key_list.head; - curr != 0; - curr = curr->next) - { - this->hash (curr); - - for (List_Node *ptr = this->key_list.head; - ptr != curr; - ptr = ptr->next) - if (ptr->hash_value == curr->hash_value) - { - if (this->change (ptr, curr) == -1) - return -1; - break; - } - num_done++; - } - - // Make one final check, just to make sure nothing weird happened... - - this->char_search.reset (); - - for (curr = this->key_list.head; - curr; - curr = curr->next) - if (this->char_search.find (this->hash (curr)) != 0) - if (option[DUP]) - // Keep track of the number of "dynamic" links (i.e., keys - // that hash to the same value) so that we can use it later - // when generating the output. - this->key_list.total_duplicates++; - else - { - // Yow, big problems. we're outta here! - ACE_ERROR ((LM_ERROR, - "\nInternal error, duplicate value %d:\n" - "try options -D or -r, or use new key positions.\n\n", - this->hash (curr))); - return -1; - } - - return 0; -} - -// Does the hard stuff.... Initializes the Bool 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::run (void) -{ - if (this->open () == -1) - return 1; - - if (option[BINARYSEARCH]) - { - if (this->compute_binary_search () == -1) - return 1; - } - else if (option[LINEARSEARCH]) - { - if (this->compute_linear_search () == -1) - return 1; - } - else - { - if (this->compute_perfect_hash () == -1) - 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. - this->key_list.sort (); - } - - this->key_list.output (); - return 0; -} - -// Prints out some diagnostics upon completion. - -Gen_Perf::~Gen_Perf (void) -{ - if (option[DEBUG]) - { - ACE_DEBUG ((LM_DEBUG, - "\ndumping occurrence and associated values tables\n")); - for (int i = 0; i < Vectors::ALPHA_SIZE; i++) - if (Vectors::occurrences[i]) - ACE_DEBUG ((LM_DEBUG, - "Vectors::asso_values[%c] = %6d, Vectors::occurrences[%c] = %6d\n", - i, - Vectors::asso_values[i], - i, - Vectors::occurrences[i])); - ACE_DEBUG ((LM_DEBUG, - "end table dumping\n")); - } - - delete [] this->union_set; -} - -#endif /* ACE_HAS_GPERF */ diff --git a/apps/gperf/src/Gen_Perf.h b/apps/gperf/src/Gen_Perf.h deleted file mode 100644 index 6d93b1c653f..00000000000 --- a/apps/gperf/src/Gen_Perf.h +++ /dev/null @@ -1,80 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -/* Copyright (C) 1989 Free Software Foundation, Inc. - written by Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) -any later version. - -GNU GPERF is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ - -#ifndef GEN_PERF_H -#define GEN_PERF_H - -#include "Options.h" -#include "Key_List.h" -#include "Bool_Array.h" - -#if defined (ACE_HAS_GPERF) - -class Gen_Perf -{ - // = TITLE - // Provides high-level routines to manipulate the keyword list - // structures the code generation output. -public: - // = Initialization and termination methods. - Gen_Perf (void); - // Constructor. - - ~Gen_Perf (void); - // Destructor - - int run (void); - // Attempt to generate a perfect hash function. - -private: - int open (void); - int change (List_Node *prior, List_Node *curr); - int affects_prev (char c, List_Node *curr); - int compute_perfect_hash (void); - int compute_binary_search (void); - int compute_linear_search (void); - static int hash (List_Node *key_node); - static int compute_disjoint_union (char *s1, char *s2, char *s3); - static void sort_set (char *union_set, int len); - - 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. - - char *union_set; - // Disjoint union. - - Key_List key_list; - // List of the keys we're trying to map into a perfect hash - // function. - - Bool_Array char_search; - // Table that keeps track of key collisions. -}; - -#endif /* ACE_HAS_GPERF */ -#endif /* GEN_PERF_H */ diff --git a/apps/gperf/src/Hash_Table.cpp b/apps/gperf/src/Hash_Table.cpp deleted file mode 100644 index ce4fe30b15a..00000000000 --- a/apps/gperf/src/Hash_Table.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// $Id$ - -/* Copyright (C) 1989 Free Software Foundation, Inc. - written by Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 1, or (at your option) any -later version. - -GNU GPERF is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, -USA. */ - -#include "Hash_Table.h" - -ACE_RCSID(src, Hash_Table, "$Id$") - -#if defined (ACE_HAS_GPERF) - -#include "ace/ACE.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!!! - -Hash_Table::Hash_Table (size_t s) - : size_ (ACE_POW (s)), - collisions_ (0) -{ - if (this->size_ == 0) - this->size_ = 1; - ACE_NEW (this->table_, - List_Node*[this->size_]); - ACE_OS::memset ((char *) this->table_, - 0, - this->size_ * sizeof *this->table_); -} - -Hash_Table::~Hash_Table (void) -{ - if (option[DEBUG]) - { - u_int keysig_width = option.max_keysig_size () > ACE_OS::strlen ("keysig") - ? option.max_keysig_size () - : ACE_OS::strlen ("keysig"); - - ACE_DEBUG ((LM_DEBUG, - "\ndumping the hash table\ntotal available table slots = %d, total bytes = %d, total collisions = %d\n" - "location, %*s, keyword\n", - this->size_, - this->size_ * (int) sizeof *this->table_, - this->collisions_, - keysig_width, - "keysig")); - - for (int i = this->size_ - 1; i >= 0; i--) - if (this->table_[i]) - ACE_DEBUG ((LM_DEBUG, - "%8d, %*s, %s\n", - i, - keysig_width, - this->table_[i]->keysig, - this->table_[i]->key)); - ACE_DEBUG ((LM_DEBUG, - "end dumping hash table\n\n")); - } - - delete [] this->table_; -} - -// 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::find (List_Node *item, - int ignore_length) -{ - u_int hash_val = ACE::hash_pjw (item->keysig); - // The following works since the hash table size_ is always a power - // of 2... - size_t size = this->size_ - 1; - int probe; - int increment = (hash_val ^ (ignore_length == 0 ? item->length : 0) | 1) & size; - - for (probe = hash_val & size; - this->table_[probe] - && (ACE_OS::strcmp (this->table_[probe]->keysig, item->keysig) != 0 - || (ignore_length == 0 && this->table_[probe]->length != item->length)); - probe = probe + increment & size) - this->collisions_++; - - if (this->table_[probe]) - return this->table_[probe]; - else - { - this->table_[probe] = item; - return 0; - } -} - -#endif /* ACE_HAS_GPERF */ diff --git a/apps/gperf/src/Hash_Table.h b/apps/gperf/src/Hash_Table.h deleted file mode 100644 index 5234f94ce26..00000000000 --- a/apps/gperf/src/Hash_Table.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -/* Copyright (C) 1989 Free Software Foundation, Inc. - written by Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 1, or (at your option) any -later version. - -GNU GPERF is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, -USA. */ - -#ifndef HASH_TABLE_H -#define HASH_TABLE_H - -#include "ace/OS.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "Options.h" -#include "List_Node.h" - -#if defined (ACE_HAS_GPERF) -// @@ This class should be replaced by something in ACE, e.g., -// ACE_Hash_Map_Manager. Perhaps we should implement a new -// ACE_Hash_Map that uses double hashing, however! -class Hash_Table -{ - // = TITLE - // Hash table used to check for duplicate keyword entries. - // - // = DESCRIPTION - // This implementation uses "double hashing." -public: - Hash_Table (size_t s); - - ~Hash_Table (void); - - List_Node *find (List_Node *item, int ignore_length); - -private: - List_Node **table_; - // Vector of pointers to linked lists of List_Node's. - - size_t size_; - // Size of the vector. - - int collisions_; - // Find out how well our double hashing is working! -}; - -#endif /* ACE_HAS_GPERF */ -#endif /* HASH_TABLE_H */ diff --git a/apps/gperf/src/Iterator.cpp b/apps/gperf/src/Iterator.cpp deleted file mode 100644 index d2491faa5ab..00000000000 --- a/apps/gperf/src/Iterator.cpp +++ /dev/null @@ -1,96 +0,0 @@ -// $Id$ - -/* Copyright (C) 1989 Free Software Foundation, Inc. - written by Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 1, or (at your option) any -later version. - -GNU GPERF is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, -USA. */ - -#include "Iterator.h" - -ACE_RCSID(src, Iterator, "$Id$") - -#if defined (ACE_HAS_GPERF) - -// Constructor for Iterator. - -Iterator::Iterator (char *s, - int lo, - int hi, - int word_end, - int bad_val, - int key_end) - : str (s), - end (key_end), - end_word (word_end), - error_value (bad_val), - 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) -{ - // 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 (*str); str++) - curr_value = curr_value * 10 + *str - '0'; - - if (*str == '-') - { - - for (size = 1, upper_bound = 0; - isdigit (*++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; - } -} - -#endif /* ACE_HAS_GPERF */ diff --git a/apps/gperf/src/Iterator.h b/apps/gperf/src/Iterator.h deleted file mode 100644 index fc150efdc72..00000000000 --- a/apps/gperf/src/Iterator.h +++ /dev/null @@ -1,80 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -/* Copyright (C) 1989 Free Software Foundation, Inc. - written by Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 1, or (at your option) any -later version. - -GNU GPERF is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef ITERATOR_H -#define ITERATOR_H - -#include "ace/OS.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "Options.h" - -#if defined (ACE_HAS_GPERF) -class Iterator -{ - // = TITLE - // Provides an Iterator that expands and decodes a control string - // containing digits and ranges, returning an integer every time the - // generator function is called. - // - // = DESCRIPTION - // This class 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 */ -public: - Iterator (char *s, - int lo, - int hi, - int word_end, - int bad_val, - int key_end); - int operator () (void); - -private: - 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. -}; - -#endif /* ACE_HAS_GPERF */ -#endif /* ITERATOR_H */ diff --git a/apps/gperf/src/Key_List.cpp b/apps/gperf/src/Key_List.cpp deleted file mode 100644 index 63492aaaac1..00000000000 --- a/apps/gperf/src/Key_List.cpp +++ /dev/null @@ -1,1820 +0,0 @@ -// $Id$ - -/* Copyright (C) 1989 Free Software Foundation, Inc. - written by Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 1, or (at your option) any -later version. - -GNU GPERF is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, -USA. */ - -#include "Key_List.h" - -ACE_RCSID(src, Key_List, "$Id$") - -#if defined (ACE_HAS_GPERF) - -#include "ace/Read_Buffer.h" -#include "Hash_Table.h" - -// Default type for generated code. -char *const Key_List::default_array_type = "char *"; - -// in_word_set return type, by default. -char *const Key_List::default_return_type = "char *"; - -// How wide the printed field width must be to contain the maximum -// hash value. -int Key_List::field_width = 0; -int Key_List::determined_[Vectors::ALPHA_SIZE]; - -// Destructor dumps diagnostics during debugging. - -Key_List::~Key_List (void) -{ - if (option[DEBUG]) - this->dump (); - - // Free up all the nodes in the list. - while (this->head != 0) - { - List_Node *temp; - - // Make sure to delete the linked nodes, as well. - for (List_Node *ptr = this->head->link; - ptr != 0; - ptr = temp) - { - temp = ptr->link; - delete ptr; - } - - temp = this->head->next; - delete this->head; - this->head = temp; - } -} - -// 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. - -char * -Key_List::special_input (char delimiter) -{ - int size = 80; - char *buf; - ACE_NEW_RETURN (buf, - char[size], - 0); - int c; - - for (int i = 0; (c = getchar ()) != EOF; i++) - { - if (c == '%') - { - c = getchar (); - if (c == delimiter) - { - // Discard newline... - while ((c = getchar ()) != '\n') - continue; - - 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; - ACE_NEW_RETURN (temp, - char[size *= 2], - 0); - for (int j = 0; j < i; j++) - temp[j] = buf[j]; - - delete [] buf; - buf = temp; - } - buf[i] = c; - } - - return 0; -} - -// Stores any C/C++ source code that must be included verbatim into -// the generated code output. - -char * -Key_List::save_include_src (void) -{ - int c = getchar (); - - if (c != '%') - ungetc (c, stdin); - else if ((c = getchar ()) != '{') - ACE_ERROR_RETURN ((LM_ERROR, - "internal error, %c != '{' on line %l in file %N", - c), - 0); - else - return 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. - -char * -Key_List::array_type (void) -{ - return special_input ('%'); -} - -// Sets up the Return_Type, the Struct_Tag type and the Array_Type -// based upon various user Options. - -int -Key_List::output_types (void) -{ - if (option[TYPE]) - { - array_type_ = array_type (); - if (array_type_ == 0) - // Something's wrong, but we'll catch it later on.... - return -1; - else - { - // Yow, we've got a user-defined type... - int struct_tag_length = ACE_OS::strcspn (array_type_, - "{\n\0"); - if (option[POINTER]) // And it must return a pointer... - { - ACE_NEW_RETURN (return_type, - char[struct_tag_length + 2], - -1); - ACE_OS::strncpy (return_type, - array_type_, - struct_tag_length); - return_type[struct_tag_length] = '*'; - return_type[struct_tag_length + 1] = '\0'; - } - - ACE_NEW_RETURN (struct_tag, - char[struct_tag_length + 2], - -1); - ACE_OS::strncpy (struct_tag, - array_type_, - struct_tag_length); - if (struct_tag[struct_tag_length] != ' ') - { - struct_tag[struct_tag_length] = ' '; - struct_tag_length++; - } - struct_tag[struct_tag_length] = '\0'; - } - } - else if (option[POINTER]) // Return a char *. - return_type = Key_List::default_array_type; - return 0; -} - -// 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. - -int -Key_List::read_keys (void) -{ - this->include_src = this->save_include_src (); - if (this->include_src == 0) - return -1; - else if (this->output_types () == -1) - return -1; - else - { - ACE_Read_Buffer input (stdin); - - char *buffer = input.read ('\n'); - - if (buffer == 0) - ACE_ERROR_RETURN ((LM_ERROR, - "No words in input file, did you forget to prepend %%%%" - " or use -t accidentally?\n"), - -1); - // Read in all the keywords from the input file. - else - { - List_Node *temp; - const char *delimiter = option.delimiter (); - ACE_NEW_RETURN (this->head, - List_Node (buffer, - ACE_OS::strcspn (buffer, - delimiter)), - -1); - for (temp = this->head; - (buffer = input.read ('\n')) - && ACE_OS::strcmp (buffer, "%%"); - temp = temp->next) - { - ACE_NEW_RETURN (temp->next, - List_Node (buffer, - ACE_OS::strcspn (buffer, - delimiter)), - -1); - this->total_keys++; - } - - // See if any additional source code is included at end of - // this file. - if (buffer) - additional_code = 1; - - this->list_len = this->total_keys; - - // Make large hash table for efficiency. - Hash_Table table (this->list_len * Key_List::TABLE_MULTIPLE); - List_Node *trail = 0; - - // Test whether there are any links and also set the maximum - // length an identifier in the keyword list. - - for (temp = head; - temp != 0; - temp = temp->next) - { - List_Node *ptr = table.find (temp, option[NOLENGTH]); - - // 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 == 0) - trail = temp; - else - { - 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]) - ACE_ERROR ((LM_ERROR, - "Key link: \"%s\" = \"%s\", with key set \"%s\".\n", - temp->key, - ptr->key, - temp->keysig)); - } - - // Update minimum and maximum keyword length, if needed. - if (max_key_len < temp->length) - max_key_len = temp->length; - if (min_key_len > temp->length) - min_key_len = temp->length; - } - } - - // Exit program if links exists and option[DUP] not set, since - // we can't continue. - if (total_duplicates) - { - if (option[DUP]) - { - if (!option[MUTE]) - ACE_ERROR_RETURN ((LM_ERROR, - "%d input keysigs have identical hash values, examine output carefully...\n", - total_duplicates), - 0); - } - else - ACE_ERROR_RETURN ((LM_ERROR, - "%d input keysigs have identical hash values,\ntry different key positions or use option -D.\n", - total_duplicates), - -1); - } - if (option[ALLCHARS]) - option.keysig_size (max_key_len); - } - - return 0; -} - -// 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) -{ - if (!list1) - return list2; - else if (!list2) - return list1; - else if (occurrence_sort && list1->occurrence < list2->occurrence - || hash_sort && list1->hash_value > list2->hash_value - || key_sort && strcmp (list1->key, list2->key) >= 0) - { - list2->next = merge (list2->next, list1); - return list2; - } - else - { - list1->next = merge (list1->next, list2); - return list1; - } -} - -// 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 *a_head) -{ - if (!a_head || !a_head->next) - return a_head; - else - { - List_Node *middle = a_head; - List_Node *temp = a_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 (a_head), merge_sort (temp)); - } -} - -// Returns the frequency of occurrence of elements in the key set. - -inline int -Key_List::occurrence (List_Node *ptr) -{ - int value = 0; - - for (char *temp = ptr->keysig; *temp; temp++) - value += Vectors::occurrences[*temp]; - - return value; -} - -// Sets the index location for all keysig characters that are now -// determined. - -inline void -Key_List::determined (List_Node *ptr) -{ - for (char *temp = ptr->keysig; *temp; temp++) - Key_List::determined_[*temp] = 1; -} - -// Returns TRUE if PTR's key set is already completely determined. - -inline int -Key_List::already_determined (List_Node *ptr) -{ - int is_determined = 1; - - for (char *temp = ptr->keysig; is_determined && *temp; temp++) - is_determined = determined_[*temp]; - - 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) -{ - List_Node *ptr; - - for (ptr = head; ptr; ptr = ptr->next) - ptr->occurrence = occurrence (ptr); - - // Switch to sorting by occurrence. - hash_sort = 0; - occurrence_sort = 1; - - for (ptr = head = merge_sort (head); ptr->next; ptr = ptr->next) - { - 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; - } - } - } -} - -// Outputs 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::output_min_max (void) -{ - List_Node *temp; - for (temp = head; temp->next; temp = temp->next) - continue; - - min_hash_value = head->hash_value; - max_hash_value = temp->hash_value; - - if (!option[ENUM]) - ACE_OS::printf ("\n#define TOTAL_KEYWORDS %d\n#define MIN_WORD_LENGTH %d" - "\n#define MAX_WORD_LENGTH %d\n#define MIN_HASH_VALUE %d" - "\n#define MAX_HASH_VALUE %d\n#define HASH_VALUE_RANGE %d" - "\n#define DUPLICATES %d\n\n", - total_keys, min_key_len, max_key_len, min_hash_value, - max_hash_value, max_hash_value - min_hash_value + 1, - total_duplicates ? total_duplicates + 1 : 0); - else if (option[GLOBAL]) - ACE_OS::printf ("enum\n{\n" - " TOTAL_KEYWORDS = %d,\n" - " MIN_WORD_LENGTH = %d,\n" - " MAX_WORD_LENGTH = %d,\n" - " MIN_HASH_VALUE = %d,\n" - " MAX_HASH_VALUE = %d,\n" - " HASH_VALUE_RANGE = %d,\n" - " DUPLICATES = %d\n};\n\n", - total_keys, min_key_len, max_key_len, min_hash_value, - max_hash_value, max_hash_value - min_hash_value + 1, - total_duplicates ? total_duplicates + 1 : 0); -} - -// Generates the output using a C switch. This trades increased -// search time for decreased table space (potentially *much* less -// space for sparse tables). It the user has specified their own -// struct in the keyword file *and* they enable the POINTER option we -// have extra work to do. The solution here is to maintain a local -// static array of user defined struct's, as with the -// Output_Lookup_Function. Then we use for switch statements to -// perform either a strcmp or strncmp, returning 0 if the str fails to -// match, and otherwise returning a pointer to appropriate index -// location in the local static array. - -void -Key_List::output_switch (int use_keyword_table) -{ - if (!option[GLOBAL] && use_keyword_table == 0) - { - if (option[LENTABLE] && option[DUP]) - output_keylength_table (); - if (option[POINTER] && option[TYPE]) - output_keyword_table (); - } - - char *comp_buffer; - List_Node *curr = head; - int pointer_and_type_enabled = option[POINTER] && option[TYPE]; - int total_switches = option.total_switches (); - int switch_size = keyword_list_length () / total_switches; - - if (pointer_and_type_enabled) - { - // Keep track of the longest string we'll need! - const char *s = "charmap[*str] == *resword->%s && !strncasecmp (str + 1, resword->%s + 1, len - 1)"; - comp_buffer = - new char [strlen (s) + 2 * strlen (option.key_name ()) + 1]; - if (option[COMP]) - sprintf (comp_buffer, "%s == *resword->%s && !%s (str + 1, resword->%s + 1, len - 1)", - option[STRCASECMP] ? "charmap[*str]" : "*str", option.key_name (), - option[STRCASECMP] ? "strncasecmp" : "strncmp", option.key_name ()); - else - sprintf (comp_buffer, "%s == *resword->%s && !%s (str + 1, resword->%s + 1)", - option[STRCASECMP] ? "charmap[*str]" : "*str", option.key_name (), - option[STRCASECMP] ? "strcasecmp" : "strcmp", option.key_name ()); - } - else - { - if (option[COMP]) - comp_buffer = option[STRCASECMP] - ? "charmap[*str] == *resword && !strncasecmp (str + 1, resword + 1, len - 1)" - : "*str == *resword && !strncmp (str + 1, resword + 1, len - 1)"; - else - comp_buffer = option[STRCASECMP] - ? "charmap[*str] == *resword && !strncasecmp (str + 1, resword + 1, len - 1)" - : "*str == *resword && !strcmp (str + 1, resword + 1)"; - } - if (!option[OPTIMIZE]) - ACE_OS::printf (" if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)\n {\n"); - ACE_OS::printf (" unsigned int key = %s (str, len);\n\n", option.hash_name ()); - if (!option[OPTIMIZE]) - ACE_OS::printf (" if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)\n"); - - ACE_OS::printf (" {\n"); - - // Properly deal with user's who request multiple switch statements. - - while (curr) - { - List_Node *temp = curr; - int lowest_case_value = curr->hash_value; - int number_of_cases = 0; - - // Figure out a good cut point to end this switch. - - for (; temp && ++number_of_cases < switch_size; temp = temp->next) - if (temp->next && temp->hash_value == temp->next->hash_value) - while (temp->next && temp->hash_value == temp->next->hash_value) - temp = temp->next; - - if (temp && total_switches != 1) - ACE_OS::printf (" if (key <= %d)\n {\n", temp->hash_value); - else - ACE_OS::printf (" {\n"); - - // Output each keyword as part of a switch statement indexed by - // hash value. - - if (option[POINTER] || option[DUP] || use_keyword_table) - { - int i = 0; - - ACE_OS::printf (" %s%s *resword; %s\n\n", - option[CONSTANT] ? "const " : "", - pointer_and_type_enabled ? struct_tag : "char", - option[LENTABLE] && !option[DUP] ? "unsigned int key_len;" : ""); - if (total_switches == 1) - { - ACE_OS::printf (" switch (key)\n {\n"); - lowest_case_value = 0; - } - else - ACE_OS::printf (" switch (key - %d)\n {\n", lowest_case_value); - - for (temp = curr; temp && ++i <= number_of_cases; temp = temp->next) - { - ACE_OS::printf (" case %*d:\n", - Key_List::field_width, - temp->hash_value - lowest_case_value); - - // Handle `static links,' i.e., those that occur during - // the initial preprocessing. - - if (temp->link == 0) - { - if (option[DEBUG]) - ACE_OS::printf (" /* hash value = %4d, keyword = \"%s\" */\n", - temp->hash_value, - temp->key); - } - else - { - List_Node *links; - - for (links = temp; links; links = links->link) - { - if (option[DEBUG]) - ACE_OS::printf (" /* hash value = %4d, keyword = \"%s\" */\n", - temp->hash_value, - links->key); - if (pointer_and_type_enabled) - ACE_OS::printf (" resword = &wordlist[%d];\n", links->index); - else if (use_keyword_table) - ACE_OS::printf (" resword = wordlist[%d];\n", links->index); - else - ACE_OS::printf (" resword = \"%s\";\n", links->key); - ACE_OS::printf (" if (%s) return resword;\n", comp_buffer); - } - } - - // Handle unresolved duplicate hash values. These are - // guaranteed to be adjacent since we sorted the keyword - // list by increasing hash values. - if (temp->next && temp->hash_value == temp->next->hash_value) - { - - for ( ; temp->next && temp->hash_value == temp->next->hash_value; - temp = temp->next) - { - if (pointer_and_type_enabled) - ACE_OS::printf (" resword = &wordlist[%d];\n", temp->index); - else if (use_keyword_table) - ACE_OS::printf (" resword = wordlist[%d];", temp->index); - else - ACE_OS::printf (" resword = \"%s\";\n", temp->key); - ACE_OS::printf (" if (%s) return resword;\n", comp_buffer); - } - if (pointer_and_type_enabled) - ACE_OS::printf (" resword = &wordlist[%d];\n", temp->index); - else if (use_keyword_table) - ACE_OS::printf (" resword = wordlist[%d];", temp->index); - else - ACE_OS::printf (" resword = \"%s\";\n", temp->key); - ACE_OS::printf (" return %s ? resword : 0;\n", comp_buffer); - } - else if (temp->link) - ACE_OS::printf (" return 0;\n"); - else - { - if (pointer_and_type_enabled) - ACE_OS::printf (" resword = &wordlist[%d];", temp->index); - else if (use_keyword_table) - ACE_OS::printf (" resword = wordlist[%d];", temp->index); - else - ACE_OS::printf (" resword = \"%s\";", temp->key); - if (option[LENTABLE] && !option[DUP]) - ACE_OS::printf (" key_len = %d;", temp->length); - ACE_OS::printf (" break;\n"); - } - } - ACE_OS::printf (" default: return 0;\n }\n"); - if (option[OPTIMIZE]) - ACE_OS::printf (" return resword;\n"); - else - { - ACE_OS::printf (option[LENTABLE] && !option[DUP] - ? " if (len == key_len && %s)\n return resword;\n" - : " if (%s)\n return resword;\n", comp_buffer); - ACE_OS::printf (" return 0;\n"); - } - ACE_OS::printf (" }\n"); - curr = temp; - } - else // Nothing special required here. - { - int i = 0; - ACE_OS::printf (" char *s;\n\n switch (key - %d)\n {\n", - lowest_case_value); - - for (temp = curr; temp && ++i <= number_of_cases; temp = temp->next) - if (option[LENTABLE]) - ACE_OS::printf (" case %*d: if (len == %d) s = \"%s\"; else return 0; break;\n", - Key_List::field_width, - temp->hash_value - lowest_case_value, - temp->length, - temp->key); - else - ACE_OS::printf (" case %*d: s = \"%s\"; break;\n", - Key_List::field_width, - temp->hash_value - lowest_case_value, - temp->key); - - ACE_OS::printf (" default: return 0;\n }\n "); - if (option[COMP]) - ACE_OS::printf ("return %s == *s && !%s;\n }\n", - option[STRCASECMP] ? "charmap[*str]" : "*str", - option[STRCASECMP] ? "strncasecmp (s + 1, str + 1, len - 1)" : "strcmp (s + 1, str + 1)"); - else - ACE_OS::printf ("return %s == *s && !%s;\n }\n", - option[STRCASECMP] ? "charmap[*str]" : "*str", - option[STRCASECMP] ? "strcasecmp (s + 1, str + 1, len - 1)" : "strcmp (s + 1, str + 1)"); - curr = temp; - } - } - ACE_OS::printf (" }\n %s\n}\n", option[OPTIMIZE] ? "" : "}\n return 0;"); -} - -// 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) -{ - const int max_column = 15; - int index = 0; - int column = 0; - char *indent = option[GLOBAL] ? "" : " "; - List_Node *temp; - - if (!option[DUP] && !option[SWITCH]) - { - ACE_OS::printf ("\n%sstatic %sunsigned %s lengthtable[] =\n%s%s{\n ", - indent, option[CONSTANT] ? "const " : "", - max_key_len <= UCHAR_MAX ? "char" : (max_key_len <= USHRT_MAX ? "short" : "long"), - indent, indent); - - for (temp = head; temp; temp = temp->next, index++) - { - - if (index < temp->hash_value) - for ( ; index < temp->hash_value; index++) - ACE_OS::printf ("%3d,%s", 0, ++column % (max_column - 1) ? "" : "\n "); - - ACE_OS::printf ("%3d,%s", temp->length, ++column % (max_column - 1 ) ? "" : "\n "); - } - - ACE_OS::printf ("\n%s%s};\n", indent, indent); - } -} - -// Prints out the array containing the key words for the Gen_Perf hash -// function. - -void -Key_List::output_keyword_table (void) -{ - char *l_brace = *head->rest ? "{" : ""; - char *r_brace = *head->rest ? "}," : ""; - char *indent = option[GLOBAL] ? "" : " "; - int index = 0; - List_Node *temp; - - ACE_OS::printf ("%sstatic %s%swordlist[] =\n%s%s{\n", - indent, - option[CONSTANT] ? "const " : "", - struct_tag, - indent, - indent); - - // Skip over leading blank entries if there are no duplicates. - - if (0 < head->hash_value) - ACE_OS::printf (" "); - - - int column; - - for (column = 1; index < head->hash_value; column++) - { - ACE_OS::printf ("%s\"\",%s %s", l_brace, r_brace, column % 9 ? "" : "\n "); - index++; - } - - if (0 < head->hash_value && column % 10) - ACE_OS::printf ("\n"); - - // Generate an array of reserved words at appropriate locations. - - for (temp = head ; temp; temp = temp->next, index++) - { - temp->index = index; - - if (!option[SWITCH] && (total_duplicates == 0 || !option[DUP]) && index < temp->hash_value) - { - int column; - - ACE_OS::printf (" "); - - for (column = 1; index < temp->hash_value; index++, column++) - ACE_OS::printf ("%s\"\",%s %s", l_brace, r_brace, column % 9 ? "" : "\n "); - - if (column % 10) - ACE_OS::printf ("\n"); - else - { - ACE_OS::printf ("%s\"%s\", %s%s", l_brace, temp->key, temp->rest, r_brace); - if (option[DEBUG]) - ACE_OS::printf (" /* hash value = %d, index = %d */", - temp->hash_value, - temp->index); - putchar ('\n'); - continue; - } - } - - ACE_OS::printf (" %s\"%s\", %s%s", l_brace, temp->key, temp->rest, r_brace); - if (option[DEBUG]) - ACE_OS::printf (" /* hash value = %d, index = %d */", - temp->hash_value, - temp->index); - putchar ('\n'); - - // Deal with links specially. - if (temp->link) - for (List_Node *links = temp->link; links; links = links->link) - { - links->index = ++index; - ACE_OS::printf (" %s\"%s\", %s%s", l_brace, links->key, links->rest, r_brace); - if (option[DEBUG]) - ACE_OS::printf (" /* hash value = %d, index = %d */", - links->hash_value, - links->index); - putchar ('\n'); - } - - } - ACE_OS::printf ("%s%s};\n\n", indent, indent); -} - -// Generates C code for the binary search algorithm that returns -// the proper encoding for each key word - -int -Key_List::output_binary_search_function (void) -{ - ACE_OS::printf ("%s\n", include_src); - - // Get prototype for strncmp() and strcmp(). - if (!option[SKIPSTRINGH]) - ACE_OS::printf ("#include <string.h>\n"); - - // Output type declaration now, reference it later on.... - if (option[TYPE] && !option[NOTYPE]) - ACE_OS::printf ("%s;\n", - array_type_); - - output_min_max (); - - if (option[STRCASECMP]) - output_strcasecmp (); - - // Class definition if -M is *not* enabled. - if (option[CPLUSPLUS] && !option[SKIPCLASS]) - ACE_OS::printf ("class %s {\npublic:\n" - " static %s%s%s (const char *str);\n};\n\n", - option.class_name (), - option[CONSTANT] ? "const " : "", - return_type, - option.function_name ()); - - // Use the inline keyword to remove function overhead. - if (option[INLINE]) - ACE_OS::printf ("inline\n"); - - ACE_OS::printf ("%s%s\n", option[CONSTANT] ? "const " : "", return_type); - if (option[CPLUSPLUS]) - ACE_OS::printf ("%s::", option.class_name ()); - - ACE_OS::printf (option[ANSI] - ? "%s (const char *str)\n{\n" - : "%s (str)\n char *str;\n{\n", - option.function_name ()); - -// Use the switch in place of lookup table. - - if (option[SWITCH]) - output_switch (); - - // Use the lookup table, in place of switch. - else - { - if (!option[GLOBAL]) - { - if (option[LENTABLE]) - output_keylength_table (); - output_keyword_table (); - } - } - - // Logic to handle the Binary Search. - - ACE_OS::printf ("int first = 0, last = 0, middle;\n"); - ACE_OS::printf ("%s*base;\n",struct_tag); - ACE_OS::printf ("\nlast = %d;\n",total_keys - 1); - ACE_OS::printf ("while (last >= first)\n"); - ACE_OS::printf ("\t{\n"); - ACE_OS::printf ("\t middle = (last + first) / 2;\n"); - ACE_OS::printf ("\t if (strcmp (wordlist[middle].opname_, str) == 0)\n break;\n"); - ACE_OS::printf ("\t if (strcmp (wordlist[middle].opname_, str) < 0)\n first = middle + 1;\n"); - ACE_OS::printf ("\t else last = middle - 1;\n"); - ACE_OS::printf ("\t}\n"); - ACE_OS::printf ("if (last < first)\n return 0;\n"); - ACE_OS::printf ("else\n return (&wordlist[middle]);\n}\n"); - - if (additional_code) - { - for (;;) - { - int c = getchar (); - - if (c == EOF) - break; - else - putchar (c); - } - } - - fflush(stdout); - - return 0; - -} - -// Generates C code for the linear search algorithm that returns -// the proper encoding for each key word - -int -Key_List::output_linear_search_function (void) -{ - ACE_OS::printf ("%s\n", include_src); - - // Get prototype for strncmp() and strcmp(). - if (!option[SKIPSTRINGH]) - ACE_OS::printf ("#include <string.h>\n"); - - // Output type declaration now, reference it later on.... - if (option[TYPE] && !option[NOTYPE]) - ACE_OS::printf ("%s;\n", - array_type_); - - output_min_max (); - - if (option[STRCASECMP]) - output_strcasecmp (); - - // Class definition if -M is *not* enabled. - if (option[CPLUSPLUS] && !option[SKIPCLASS]) - ACE_OS::printf ("class %s {\npublic:\n" - " static %s%s%s (const char *str);\n};\n\n", - option.class_name (), - option[CONSTANT] ? "const " : "", - return_type, - option.function_name ()); - - // Use the inline keyword to remove function overhead. - if (option[INLINE]) - ACE_OS::printf ("inline\n"); - - ACE_OS::printf ("%s%s\n", - option[CONSTANT] ? "const " : "", - return_type); - if (option[CPLUSPLUS]) - ACE_OS::printf ("%s::", option.class_name ()); - - ACE_OS::printf (option[ANSI] - ? "%s (const char *str)\n{\n" - : "%s (str)\n char *str;\n{\n", - option.function_name ()); - - // Use the switch in place of lookup table. - - if (option[SWITCH]) - output_switch (); - // Use the lookup table, in place of switch. - else - { - if (!option[GLOBAL]) - { - if (option[LENTABLE]) - output_keylength_table (); - output_keyword_table (); - } - } - - // Logic to handle the Linear Search. - - ACE_OS::printf ("for (int i=0; i<=%d; i++)",total_keys-1); - ACE_OS::printf ("\t{\n"); - ACE_OS::printf ("\t if (strcmp (wordlist[i].opname_, str) == 0)\n"); - ACE_OS::printf ("\t return &wordlist[i];\n"); - ACE_OS::printf ("\t}\n"); - ACE_OS::printf ("return 0;\n}\n"); - - if (additional_code) - { - for (;;) - { - int c = getchar (); - - if (c == EOF) - break; - else - putchar (c); - } - } - - ACE_OS::fflush (stdout); - - return 0; - -} -// Generates C code for the hash function that returns the proper -// encoding for each key word. - -void -Key_List::output_hash_function (void) -{ - const int max_column = 10; - int count = max_hash_value; - - // Calculate maximum number of digits required for MAX_HASH_VALUE. - - for (Key_List::field_width = 2; - (count /= 10) > 0; - Key_List::field_width++) - continue; - - if (option[INLINE]) - ACE_OS::printf ("inline\n"); - - if (option[C]) - ACE_OS::printf ("static "); - ACE_OS::printf ("unsigned int\n"); - if (option[CPLUSPLUS]) - ACE_OS::printf ("%s::", option.class_name ()); - - ACE_OS::printf (option[ANSI] - ? "%s (const char *str, unsigned int len)\n{\n static %sunsigned %s asso_values[] =\n {" - : "%s (str, len)\n char *str;\n unsigned int len;\n{\n static %sunsigned %s asso_values[] =\n {", - option.hash_name (), option[CONSTANT] ? "const " : "", - max_hash_value <= UCHAR_MAX ? "char" : (max_hash_value <= USHRT_MAX ? "short" : "int")); - - for (count = 0; count < Vectors::ALPHA_SIZE; ++count) - { - if (!(count % max_column)) - ACE_OS::printf ("\n "); - - ACE_OS::printf ("%*d,", - Key_List::field_width, - Vectors::occurrences[count] ? Vectors::asso_values[count] : max_hash_value + 1); - } - - // Optimize special case of ``-k 1,$'' - if (option[DEFAULTCHARS]) - { - if (option[STRCASECMP]) - ACE_OS::printf ("\n };\n return %sasso_values[charmap[str[len - 1]]] + asso_values[charmap[str[0]]];\n}\n\n", - option[NOLENGTH] ? "" : "len + "); - else - ACE_OS::printf ("\n };\n return %sasso_values[str[len - 1]] + asso_values[str[0]];\n}\n\n", - option[NOLENGTH] ? "" : "len + "); - } - else - { - int key_pos; - - option.reset (); - - // Get first (also highest) key position. - key_pos = option.get (); - - // We can perform additional optimizations here. - if (!option[ALLCHARS] && key_pos <= min_key_len) - { - ACE_OS::printf ("\n };\n return %s", option[NOLENGTH] ? "" : "len + "); - - for (; key_pos != WORD_END; ) - { - ACE_OS::printf (option[STRCASECMP] ? "asso_values[charmap[str[%d]]]" : "asso_values[str[%d]]", key_pos - 1); - if ((key_pos = option.get ()) != EOS) - ACE_OS::printf (" + "); - else - break; - } - - ACE_OS::printf ("%s;\n}\n\n", key_pos == WORD_END - ? (option[STRCASECMP] ? "asso_values[charmap[str[len - 1]]]" : "asso_values[str[len - 1]]") - : ""); - } - - // We've got to use the correct, but brute force, technique. - else - { - ACE_OS::printf ("\n };\n unsigned 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]) - { - int i; - - // Break these options up for speed (gee, is this misplaced efficiency or what?! - if (option[STRCASECMP]) - - for (i = max_key_len; i > 0; i--) - ACE_OS::printf (" case %d:\n hval += asso_values[charmap[str[%d]]];\n", i, i - 1); - - else - - for (i = max_key_len; i > 0; i--) - ACE_OS::printf (" case %d:\n hval += asso_values[str[%d]];\n", i, i - 1); - - ACE_OS::printf (" }\n return hval;\n}\n\n"); - } - else // do the hard part... - { - count = key_pos + 1; - - do - { - - while (--count > key_pos) - ACE_OS::printf (" case %d:\n", count); - - ACE_OS::printf (option[STRCASECMP] - ? " case %d:\n hval += asso_values[charmap[str[%d]]];\n" - : " case %d:\n hval += asso_values[str[%d]];\n", - key_pos, key_pos - 1); - } - while ((key_pos = option.get ()) != EOS && key_pos != WORD_END); - - ACE_OS::printf (" }\n return hval%s;\n}\n\n", - key_pos == WORD_END - ? (option[STRCASECMP] ? " + asso_values[charmap[str[len - 1]]]" : " + asso_values[str[len - 1]]") - : ""); - } - } - } -} - -int -Key_List::count_duplicates (List_Node *link, - const char *type) -{ - int count = 0; - - // Count the number of "static" duplicates for this hash value. - for (List_Node *ptr = link; - ptr != 0; - ptr = ptr->link) - { - count++; - - if (option[DEBUG]) - ACE_DEBUG ((LM_DEBUG, - "%s linked keyword = %s, index = %d, hash_value = %d\n", - type, - ptr->key, - ptr->index, - ptr->hash_value)); - } - - return count; -} - -void -Key_List::update_lookup_array (int lookup_array[], - int i1, - int i2, - Duplicate_Entry *dup_ptr, - int value) -{ - lookup_array[i1] = -dup_ptr->index; - lookup_array[i2] = -dup_ptr->count; - lookup_array[dup_ptr->hash_value] = value; -} - -// Generates the large, sparse table that maps hash values in the -// smaller, contiguous range of the keyword table. - -int -Key_List::output_lookup_array (void) -{ - if (total_duplicates > 0) - { - const int DEFAULT_VALUE = -1; - - Duplicate_Entry *duplicates; - ACE_NEW_RETURN (duplicates, - Duplicate_Entry[total_duplicates], - -1); - - int *lookup_array; - ACE_NEW_RETURN (lookup_array, - int[max_hash_value + 1], - -1); - - Duplicate_Entry *dup_ptr = duplicates; - int *lookup_ptr = lookup_array + max_hash_value + 1; - - // Initialize the lookup array to the DEFAULT_VALUE (-1). - while (lookup_ptr > lookup_array) - *--lookup_ptr = DEFAULT_VALUE; - - // Iterate through the keylist and handle the static and dynamic - // duplicate entries. - for (List_Node *temp = head; temp; temp = temp->next) - { - int hash_value = temp->hash_value; - // Store the keyword's index location into the - // <lookup_array> at the <hash_value>. If this is a - // non-duplicate, then this value will point directly to the - // keyword. - lookup_array[hash_value] = temp->index; - - if (option[DEBUG]) - ACE_DEBUG ((LM_DEBUG, - "keyword = %s, index = %d, hash_value = %d, lookup_array[hash_value] = %d\n", - temp->key, - temp->index, - temp->hash_value, - lookup_array[temp->hash_value])); - - if (temp->link == 0 && - (temp->next == 0 || hash_value != temp->next->hash_value)) - // This isn't a duplicate. Note that we know this because - // we sorted the keys by their hash value. - continue; - else - { - // We'll handle the duplicates here. - dup_ptr->hash_value = hash_value; - dup_ptr->index = temp->index; - dup_ptr->count = 1; - - // Count the number of "static" duplicates, i.e., - // keywords that had the same keysig when the keyfile - // was first read. - dup_ptr->count += this->count_duplicates (temp->link, - "static"); - - // Count the number of "dynamic" duplicates, i.e., - // keywords that ended up with the same hash value as a - // result of the <asso_values> contents. - for (; - temp->next && hash_value == temp->next->hash_value; - temp = temp->next) - dup_ptr->count += this->count_duplicates (temp->next, - "dynamic"); - dup_ptr++; - } - } - - // Compute the values in the lookup array. - while (--dup_ptr >= duplicates) - { - if (option[DEBUG]) - ACE_DEBUG ((LM_DEBUG, - "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; - - // Look to the left first. - for (i = dup_ptr->hash_value; i > 0; i--) - if (lookup_array[i] == DEFAULT_VALUE && lookup_array[i - 1] == DEFAULT_VALUE) - { - this->update_lookup_array (lookup_array, - i - 1, - i, - dup_ptr, - -(max_hash_value + (dup_ptr->hash_value - i + 1))); - break; - } - - // If we didn't find it to the left look to the right - // instead... - if (i == 0) - { - for (i = dup_ptr->hash_value; i < max_hash_value; i++) - if (lookup_array[i] == DEFAULT_VALUE && lookup_array[i + 1] == DEFAULT_VALUE) - { - this->update_lookup_array (lookup_array, - i, - i + 1, - dup_ptr, - max_hash_value + (i - dup_ptr->hash_value)); - break; - } - - // If this happens, we can't use the output array scheme... - if (i >= max_hash_value) - { - option = SWITCH; - ACE_DEBUG ((LM_DEBUG, - "Automatically changing to -S1 switch option\n")); - // Since we've already generated the keyword table - // we need to use it! - this->output_switch (1); - return 1; // 1 indicates that we've changed our mind... - } - } - } - - int max = INT_MIN; - lookup_ptr = lookup_array + max_hash_value + 1; - - while (lookup_ptr > lookup_array) - { - int val = abs (*--lookup_ptr); - if (max < val) - max = val; - } - - char *indent = option[GLOBAL] ? "" : " "; - - ACE_OS::printf ("%sstatic %ssigned %s lookup[] =\n%s%s{\n ", indent, option[CONSTANT] ? "const " : "", - max <= SCHAR_MAX ? "char" : (max <= SHRT_MAX ? "short" : "int"), - indent, indent); - - int count = max; - - // Calculate maximum number of digits required for - // MAX_HASH_VALUE. - - for (Key_List::field_width = 2; (count /= 10) > 0; Key_List::field_width++) - continue; - - const int max_column = 15; - int column = 0; - - for (lookup_ptr = lookup_array; - lookup_ptr < lookup_array + max_hash_value + 1; - lookup_ptr++) - ACE_OS::printf ("%*d, %s", - Key_List::field_width, - *lookup_ptr, - ++column % (max_column - 1) ? "" : "\n "); - - ACE_OS::printf ("\n%s%s};\n\n", indent, indent); - - delete [] duplicates; - delete [] lookup_array; - } - return 0; -} - -// Generates C code to perform the keyword lookup. - -void -Key_List::output_lookup_function (void) -{ - if (!option[OPTIMIZE]) - ACE_OS::printf (" if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)\n {\n"); - ACE_OS::printf (" unsigned int key = %s (str, len);\n\n", option.hash_name ()); - if (!option[OPTIMIZE]) - ACE_OS::printf (" if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)\n"); - ACE_OS::printf (" {\n"); - - if (option[DUP] && total_duplicates > 0) - { - ACE_OS::printf (" int index = lookup[key];\n\n" - " if (index >= 0 && index < MAX_HASH_VALUE)\n"); - if (option[OPTIMIZE]) - ACE_OS::printf (" return %swordlist[index];\n", option[TYPE] && option[POINTER] ? "&" : ""); - else - { - ACE_OS::printf (" {\n" - " %schar *s = wordlist[index]", option[CONSTANT] ? "const " : ""); - if (array_type_ != Key_List::default_array_type) - ACE_OS::printf (".%s", option.key_name ()); - - ACE_OS::printf (";\n\n if (%s%s == *s && !%s)\n return %s;\n }\n", - option[LENTABLE] ? "len == lengthtable[key]\n && " : "", - option[STRCASECMP] ? "charmap[*str]" : "*str", - option[COMP] ? (option[STRCASECMP] ? "strncasecmp (str + 1, s + 1, len - 1)" : "strncmp (str + 1, s + 1, len - 1)") - : (option[STRCASECMP] ? "strcasecmp (str + 1, s + 1)" : "strcmp (str + 1, s + 1)"), - option[TYPE] && option[POINTER] ? "&wordlist[index]" : "s"); - ACE_OS::printf (" else if (index < 0 && index >= -MAX_HASH_VALUE)\n" - " return 0;\n"); - } - ACE_OS::printf (" else\n {\n" - " unsigned int offset = key + index + (index > 0 ? -MAX_HASH_VALUE : MAX_HASH_VALUE);\n" - " %s%s*base = &wordlist[-lookup[offset]];\n" - " %s%s*ptr = base + -lookup[offset + 1];\n\n" - " while (--ptr >= base)\n ", - option[CONSTANT] ? "const " : "", struct_tag, - option[CONSTANT] ? "const " : "", struct_tag); - if (array_type_ != Key_List::default_array_type) - { - if (option[COMP]) - ACE_OS::printf ("if (%s == *ptr->%s && !%s (str + 1, ptr->%s + 1, len - 1", - option[STRCASECMP] ? "charmap[*str]" : "*str", option.key_name (), - option[STRCASECMP] ? "strncasecmp" : "strncmp", option.key_name ()); - else - ACE_OS::printf ("if (%s == *ptr->%s && !%s (str + 1, ptr->%s + 1", - option[STRCASECMP] ? "charmap[*str]" : "*str", option.key_name (), - option[STRCASECMP] ? "strcasecmp" : "strcmp", option.key_name ()); - } - else - ACE_OS::printf (option[STRCASECMP] ? "if (charmap[*str] == **ptr && !%s" : "if (*str == **ptr && !%s", - option[COMP] - ? (option[STRCASECMP] ? "strncasecmp (str + 1, *ptr + 1, len - 1" : "strncmp (str + 1, *ptr + 1, len - 1") - : (option[STRCASECMP] ? "strcasecmp (str + 1, *ptr + 1" : "strcmp (str + 1, *ptr + 1")); - ACE_OS::printf ("))\n return %sptr;" - "\n }\n }\n %s\n}\n", array_type_ == - Key_List::default_array_type ? "*" : "", option[OPTIMIZE] ? "" : "}\n return 0;"); - } - else - { - if (option[OPTIMIZE]) - ACE_OS::printf (" return %swordlist[key]", option[TYPE] && option[POINTER] ? "&" : ""); - else - { - ACE_OS::printf (" %schar *s = wordlist[key]", option[CONSTANT] ? "const " : ""); - - if (array_type_ != Key_List::default_array_type) - ACE_OS::printf (".%s", option.key_name ()); - - ACE_OS::printf (";\n\n if (%s%s == *s && !%s)\n return %s", - option[LENTABLE] ? "len == lengthtable[key]\n && " : "", - option[STRCASECMP] ? "charmap[*str]" : "*str", - option[COMP] - ? (option[STRCASECMP] ? "strncasecmp (str + 1, s + 1, len - 1)" : "strncmp (str + 1, s + 1, len - 1)") - : (option[STRCASECMP] ? "strcasecmp (str + 1, s + 1)" : "strcmp (str + 1, s + 1)"), - option[TYPE] && option[POINTER] ? "&wordlist[key]" : "s"); - } - ACE_OS::printf (";\n }\n %s\n}\n", option[OPTIMIZE] ? "" : "}\n return 0;"); - } -} - -// Output the table and the functions that map upper case into lower case! - -void -Key_List::output_strcasecmp (void) -{ - ACE_OS::printf ("%s", - "/* This array is designed for mapping upper and lower case letter\n" - " * together for a case independent comparison. The mappings are\n" - " * based upon ascii character sequences.\n */" - "static char charmap[] = {\n" - " '\\000', '\\001', '\\002', '\\003', '\\004', '\\005', '\\006', '\\007',\n" - " '\\010', '\\011', '\\012', '\\013', '\\014', '\\015', '\\016', '\\017',\n" - " '\\020', '\\021', '\\022', '\\023', '\\024', '\\025', '\\026', '\\027',\n" - " '\\030', '\\031', '\\032', '\\033', '\\034', '\\035', '\\036', '\\037',\n" - " '\\040', '\\041', '\\042', '\\043', '\\044', '\\045', '\\046', '\\047',\n" - " '\\050', '\\051', '\\052', '\\053', '\\054', '\\055', '\\056', '\\057',\n" - " '\\060', '\\061', '\\062', '\\063', '\\064', '\\065', '\\066', '\\067',\n" - " '\\070', '\\071', '\\072', '\\073', '\\074', '\\075', '\\076', '\\077',\n" - " '\\100', '\\141', '\\142', '\\143', '\\144', '\\145', '\\146', '\\147',\n" - " '\\150', '\\151', '\\152', '\\153', '\\154', '\\155', '\\156', '\\157',\n" - " '\\160', '\\161', '\\162', '\\163', '\\164', '\\165', '\\166', '\\167',\n" - " '\\170', '\\171', '\\172', '\\133', '\\134', '\\135', '\\136', '\\137',\n" - " '\\140', '\\141', '\\142', '\\143', '\\144', '\\145', '\\146', '\\147',\n" - " '\\150', '\\151', '\\152', '\\153', '\\154', '\\155', '\\156', '\\157',\n" - " '\\160', '\\161', '\\162', '\\163', '\\164', '\\165', '\\166', '\\167',\n" - " '\\170', '\\171', '\\172', '\\173', '\\174', '\\175', '\\176', '\\177',\n" - " '\\200', '\\201', '\\202', '\\203', '\\204', '\\205', '\\206', '\\207',\n" - " '\\210', '\\211', '\\212', '\\213', '\\214', '\\215', '\\216', '\\217',\n" - " '\\220', '\\221', '\\222', '\\223', '\\224', '\\225', '\\226', '\\227',\n" - " '\\230', '\\231', '\\232', '\\233', '\\234', '\\235', '\\236', '\\237',\n" - " '\\240', '\\241', '\\242', '\\243', '\\244', '\\245', '\\246', '\\247',\n" - " '\\250', '\\251', '\\252', '\\253', '\\254', '\\255', '\\256', '\\257',\n" - " '\\260', '\\261', '\\262', '\\263', '\\264', '\\265', '\\266', '\\267',\n" - " '\\270', '\\271', '\\272', '\\273', '\\274', '\\275', '\\276', '\\277',\n" - " '\\300', '\\341', '\\342', '\\343', '\\344', '\\345', '\\346', '\\347',\n" - " '\\350', '\\351', '\\352', '\\353', '\\354', '\\355', '\\356', '\\357',\n" - " '\\360', '\\361', '\\362', '\\363', '\\364', '\\365', '\\366', '\\367',\n" - " '\\370', '\\371', '\\372', '\\333', '\\334', '\\335', '\\336', '\\337',\n" - " '\\340', '\\341', '\\342', '\\343', '\\344', '\\345', '\\346', '\\347',\n" - " '\\350', '\\351', '\\352', '\\353', '\\354', '\\355', '\\356', '\\357',\n" - " '\\360', '\\361', '\\362', '\\363', '\\364', '\\365', '\\366', '\\367',\n" - " '\\370', '\\371', '\\372', '\\373', '\\374', '\\375', '\\376', '\\377',\n};\n\nstatic int\n"); - if (option[COMP]) - { - ACE_OS::printf ("%s", option[ANSI] - ? "strncasecmp (char *s1, char *s2, int n)" - : "strncasecmp (s1, s2, n)\n char *s1, *s2;\n int n;"); - ACE_OS::printf ("\n{\n char *cm = charmap;\n\n while (--n >= 0 && cm[*s1] == cm[*s2++])\n" - " if (*s1++ == '\\0')\n return 0;\n" - "\n return n < 0 ? 0 : cm[*s1] - cm[*--s2];\n}\n\n"); - } - else - { - ACE_OS::printf ("%s", option[ANSI] - ? "strcasecmp (char *s1, char *s2)" - : "strcasecmp (s1, s2)\n char *s1, *s2;"); - ACE_OS::printf ("\n{\n char *cm = charmap;\n\n while (cm[*s1] == cm[*s2++])\n" - " if (*s1++ == '\\0')\n return 0;\n" - "\n return cm[*s1] - cm[*--s2];\n}\n\n"); - } -} - -// Generates the hash function and the key word recognizer function -// based upon the user's Options. - -int -Key_List::output (void) -{ - if (option[BINARYSEARCH]) - // Generate code binary search. - this->output_binary_search_function (); - else if (option[LINEARSEARCH]) - // Generate code for linear search. - this->output_linear_search_function (); - else - { - // Generate the usual GPERF things. - ACE_OS::printf ("%s\n", include_src); - - // Get prototype for strncmp() and strcmp(). - if (!option[SKIPSTRINGH]) - ACE_OS::printf ("#include <string.h>\n"); - - // Output type declaration now, reference it later on.... - if (option[TYPE] && !option[NOTYPE]) - ACE_OS::printf ("%s;\n", - array_type_); - - output_min_max (); - - if (option[STRCASECMP]) - output_strcasecmp (); - - // Class definition if -M is *not* enabled. - if (option[CPLUSPLUS] && !option[SKIPCLASS]) - ACE_OS::printf ("class %s\n{\nprivate:\n" - " static unsigned int %s (const char *str, unsigned int len);\npublic:\n" - " static %s%s%s (const char *str, unsigned int len);\n};\n\n", - option.class_name (), - option.hash_name (), - option[CONSTANT] ? "const " : "", - return_type, - option.function_name ()); - - output_hash_function (); - - if (option[GLOBAL]) - if (option[SWITCH]) - { - if (option[LENTABLE] && option[DUP]) - output_keylength_table (); - if (option[POINTER] && option[TYPE]) - output_keyword_table (); - } - else - { - if (option[LENTABLE]) - output_keylength_table (); - output_keyword_table (); - if (output_lookup_array () == -1) - ACE_ERROR_RETURN ((LM_DEBUG, - "%p\n", - "output_lookup_array"), - -1); - } - - // Use the inline keyword to remove function overhead. - if (option[INLINE]) - ACE_OS::printf ("inline\n"); - - ACE_OS::printf ("%s%s\n", option[CONSTANT] ? "const " : "", return_type); - if (option[CPLUSPLUS]) - ACE_OS::printf ("%s::", option.class_name ()); - - ACE_OS::printf (option[ANSI] - ? "%s (const char *str, unsigned int len)\n{\n" - : "%s (str, len)\n char *str;\n unsigned int len;\n{\n", - option.function_name ()); - - if (option[ENUM] && !option[GLOBAL]) - ACE_OS::printf (" enum\n {\n" - " TOTAL_KEYWORDS = %d,\n" - " MIN_WORD_LENGTH = %d,\n" - " MAX_WORD_LENGTH = %d,\n" - " MIN_HASH_VALUE = %d,\n" - " MAX_HASH_VALUE = %d,\n" - " HASH_VALUE_RANGE = %d,\n" - " DUPLICATES = %d\n };\n\n", - total_keys, min_key_len, max_key_len, min_hash_value, - max_hash_value, max_hash_value - min_hash_value + 1, - total_duplicates ? total_duplicates + 1 : 0); - // Use the switch in place of lookup table. - if (option[SWITCH]) - output_switch (); - // Use the lookup table, in place of switch. - else - { - if (!option[GLOBAL]) - { - if (option[LENTABLE]) - output_keylength_table (); - output_keyword_table (); - } - if (!option[GLOBAL]) - { - switch (output_lookup_array ()) - { - case -1: - ACE_ERROR_RETURN ((LM_DEBUG, - "%p\n", - "output_lookup_array"), - -1); - /* NOTREACHED */ - case 0: - output_lookup_function (); - break; - /* NOTREACHED */ - default: - break; - /* NOTREACHED */ - } - } - } - - if (additional_code) - { - for (;;) - { - int c = getchar (); - - if (c == EOF) - break; - else - putchar (c); - } - } - fflush (stdout); - } - return 0; - } - -// Sorts the keys by hash value. - -void -Key_List::sort (void) -{ - // By default, we sort via hashing. - hash_sort = 1; - occurrence_sort = 0; - - this->head = merge_sort (this->head); -} - -// Sorts the keys by normal strcmp. -void -Key_List::string_sort (void) -{ - - // Flatten the equivalence class list to a linear list. - - List_Node *ptr; - for(ptr=head;ptr;ptr=ptr->next) - { - List_Node *curr; - if(ptr->link) - { - List_Node *last_node = 0; - - for(curr = ptr->link; curr; curr = curr->link) - { - // Chnage the link to next pointer. - curr->next = curr->link; - - // Save the pointer for the last node. - if (curr->link == 0) - last_node = curr; - } - - // Set the pointers, correctly. - last_node->next = ptr->next; - ptr->next = ptr->link; - ptr = last_node; - } - } - - // Set all links to Null. - - for(ptr=head;ptr;ptr=ptr->next) - { - ptr->link = 0; - } - - // Set the sorting options. - - key_sort = 1; - hash_sort = 0; - occurrence_sort = 0; - - // Sort. - - this->head = merge_sort (head); - key_sort = 0; -} - - -// Dumps the key list to stderr stream. - -void -Key_List::dump (void) -{ - ACE_DEBUG ((LM_DEBUG, - "\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 ? total_duplicates + 1 : 0, - max_key_len)); - - u_int keysig_width = option.max_keysig_size () > ACE_OS::strlen ("keysig") - ? option.max_keysig_size () - : ACE_OS::strlen ("keysig"); - - u_int key_length = this->max_key_length (); - u_int keyword_width = key_length > ACE_OS::strlen ("keysig") - ? key_length - : ACE_OS::strlen ("keysig"); - - ACE_DEBUG ((LM_DEBUG, - "\nList contents are:\n(hash value, key length, index, %*s, %*s, duplicates):\n", - keysig_width, - "keysig", - keyword_width, - "keyword")); - - for (List_Node *ptr = head; ptr; ptr = ptr->next) - { - ACE_DEBUG ((LM_DEBUG, - "%11d,%11d,%6d, %*s, %*s", - ptr->hash_value, - ptr->length, - ptr->index, - keysig_width, - ptr->keysig, - keyword_width, - ptr->key)); - - List_Node *dup = ptr->link; - if (dup) - { - for (; - dup != 0; - dup = dup->link) - ACE_DEBUG ((LM_DEBUG, - " %s", - dup->key)); - } - ACE_DEBUG ((LM_DEBUG, - "\n")); - } - ACE_DEBUG ((LM_DEBUG, - "End dumping list.\n\n")); -} - -// Simple-minded constructor action here... - -Key_List::Key_List (void) - : head (0), - total_duplicates (0), - array_type_ (Key_List::default_array_type), - return_type (Key_List::default_return_type), - struct_tag (Key_List::default_array_type), - max_key_len (INT_MIN), - min_key_len (INT_MAX), - key_sort (0), - additional_code (0), - total_keys (1) -{ -} - -// Returns the length of entire key list. - -int -Key_List::keyword_list_length (void) -{ - return list_len; -} - -// Returns length of longest key read. - -int -Key_List::max_key_length (void) -{ - return max_key_len; -} - -#endif /* ACE_HAS_GPERF */ diff --git a/apps/gperf/src/Key_List.h b/apps/gperf/src/Key_List.h deleted file mode 100644 index 1a2d30421a9..00000000000 --- a/apps/gperf/src/Key_List.h +++ /dev/null @@ -1,173 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -/* Copyright (C) 1989 Free Software Foundation, Inc. - written by Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 1, or (at your option) any -later version. - -GNU GPERF is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, -USA. */ - -#ifndef KEY_LIST_H -#define KEY_LIST_H - -#include "Options.h" -#include "List_Node.h" -#include "Vectors.h" - -#if defined (ACE_HAS_GPERF) - -class Duplicate_Entry -{ - // = TITLE - // Describes a duplicate entry. - // - // = DESCRIPTION - // This is used for generating code by the <Key_List>. -public: - 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. -}; - -class Key_List -{ - // = TITLE - // Data and function member declarations for the keyword list class. - // - // = DESCRIPTION - // 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. -public: - Key_List (void); - ~Key_List (void); - int keyword_list_length (void); - int max_key_length (void); - void reorder (void); - void sort (void); - void string_sort (void); - int read_keys (void); - int output (void); - - List_Node *head; - // Points to the head of the linked list. - - int total_duplicates; - // Total number of duplicate hash values. - -private: - // = Make hash table 10 times larger than # of keyword entries. - enum - { - TABLE_MULTIPLE = 10 - }; - - static int occurrence (List_Node *ptr); - static int already_determined (List_Node *ptr); - static void determined (List_Node *ptr); - - // @@ All of the following methods should be factored out and - // replaced by the use of the Strategy/Bridge pattern so that we can - // easily add new languages. - void output_min_max (void); - void output_switch (int use_keyword_table = 0); - void output_keyword_table (void); - void output_keylength_table (void); - void output_hash_function (void); - void output_lookup_function (void); - int output_binary_search_function(void); - int output_linear_search_function (void); - int output_lookup_array (void); - void output_strcasecmp (void); - int output_types (void); - void dump (void); - char *array_type (void); - char *save_include_src (void); - char *special_input (char delimiter); - List_Node *merge (List_Node *list1, List_Node *list2); - List_Node *merge_sort (List_Node *head); - int count_duplicates (List_Node *link, const char *type); - void update_lookup_array (int lookup_array[], - int i1, - int i2, - Duplicate_Entry *dup_ptr, - int value); - char *array_type_; - // Pointer to the type for word list. - - char *return_type; - // Pointer to return type for lookup function. - - char *struct_tag; - // Shorthand for user-defined struct tag type. - - char *include_src; - // C source code to be included verbatim. - - int 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 key_sort; - // True if sorting by key 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 char *const default_array_type; - // Default type for generated code. - - static char *const default_return_type; - // in_word_set return type, by default. - - static int field_width; - // How wide the printed field width must be to contain the maximum - // hash value. - - static int determined_[Vectors::ALPHA_SIZE]; - // Sets the index location for all keysig characters that are now - // determined. -}; - -#endif /* ACE_HAS_GPERF */ -#endif /* KEY_LIST_H */ diff --git a/apps/gperf/src/List_Node.cpp b/apps/gperf/src/List_Node.cpp deleted file mode 100644 index ef51182ad71..00000000000 --- a/apps/gperf/src/List_Node.cpp +++ /dev/null @@ -1,132 +0,0 @@ -// $Id$ - -/* Copyright (C) 1989 Free Software Foundation, Inc. - written by Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 1, or (at your option) any -later version. - -GNU GPERF is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, -USA. */ - -#include "List_Node.h" - -ACE_RCSID(src, List_Node, "$Id$") - -#if defined (ACE_HAS_GPERF) - -#include "Vectors.h" - -// Defined as a macro in string.h on some systems, which causes -// conflicts. -#undef index - -// Sorts the key set alphabetically to speed up subsequent operation -// Uses insertion sort since the set is probably quite small. - -inline void -List_Node::sort (char *base, int len) -{ - int i, j; - - for (i = 0, j = len - 1; i < j; i++) - { - char curr, tmp; - - for (curr = i + 1, tmp = base[curr]; - curr > 0 && tmp < base[curr-1]; - curr--) - base[curr] = base[curr - 1]; - - base[curr] = tmp; - - } -} - -// Initializes a List_Node. This requires obtaining memory for the -// 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 (char *k, int len) - : link (0), - next (0), - key (k), - rest (option[TYPE] ? k + len + 1 : ""), - length (len), - index (0) -{ - char *ptr = new char[(option[ALLCHARS] ? len : option.max_keysig_size ()) + 1]; - keysig = ptr; - k[len] = '\0'; // Null terminate KEY to separate it from REST. - - // Lower case if STRCASECMP option is enabled. - if (option[STRCASECMP]) - for (char *p = k; *p; p++) - if (isupper (*p)) - *p = tolower (*p); - - if (option[ALLCHARS]) // Use all the character position in the KEY. - for (; *k; k++, ptr++) - ++Vectors::occurrences[*ptr = *k]; - else - { - // Only use those character positions specified by the user. - - option.reset (); - - // Iterate thru the list of key_positions, initializing - // occurrences table and keysig (via char * pointer ptr). - - for (int i; (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; - ++Vectors::occurrences[*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 == keysig && option[NOLENGTH]) - ACE_ERROR ((LM_ERROR, - "Can't hash keyword %s with chosen key positions.\n%a", - key, - 1)); - } - // Terminate this string. - *ptr = '\0'; - - // Sort the KEYSIG items alphabetically. - sort (keysig, ptr - keysig); -} - -List_Node::~List_Node (void) -{ - delete [] this->key; - delete [] this->keysig; -} - -#endif /* ACE_HAS_GPERF */ diff --git a/apps/gperf/src/List_Node.h b/apps/gperf/src/List_Node.h deleted file mode 100644 index 59ca19ed1a8..00000000000 --- a/apps/gperf/src/List_Node.h +++ /dev/null @@ -1,80 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -/* Copyright (C) 1989 Free Software Foundation, Inc. - written by Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 1, or (at your option) any -later version. - -GNU GPERF is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, -USA. */ - -#ifndef LIST_NODE_H -#define LIST_NODE_H - -#include "ace/OS.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "Options.h" - -#if defined (ACE_HAS_GPERF) -class List_Node -{ - // = TITLE - // Data and function members for defining values and operations of - // a list node. -public: - // = Initialization and termination methods. - List_Node (char *key, int len); - // Constructor. - - ~List_Node (void); - // Destructor. - - static void sort (char *base, int len); - - List_Node *link; - // TRUE if key has an identical KEY_SET as another key. - - List_Node *next; - // Points to next element on the list. - - char *key; - // Each keyword string stored here. - - char *rest; - // Additional information for building hash function. - - char *keysig; - // Set of characters to hash, specified by user. - - int length; - // Length of the key. - - int hash_value; - // Hash value for the key. - - int occurrence; - // A metric for frequency of key set occurrences. - - int index; - // Position of this node relative to other nodes. -}; - -#endif /* ACE_HAS_GPERF */ -#endif /* LIST_NODE_H */ diff --git a/apps/gperf/src/Makefile b/apps/gperf/src/Makefile deleted file mode 100644 index 7d8c442ad27..00000000000 --- a/apps/gperf/src/Makefile +++ /dev/null @@ -1,274 +0,0 @@ -#---------------------------------------------------------------------------- -# $Id$ -# -# Makefile for GPERF release -#---------------------------------------------------------------------------- - -BIN = gperf -INSBIN = $ACE_ROOT/bin/gperf - -FILES = Options \ - Iterator \ - Gen_Perf \ - Key_List \ - List_Node \ - Hash_Table \ - Bool_Array \ - Vectors \ - Version - -SRC = $(addsuffix .cpp,$(FILES)) -OBJ = $(addsuffix .o,$(FILES)) - -BUILD = $(VBIN) - -INSTALL = $(VBIN:%=$(INSBIN)/%) - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.lib.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -# DO NOT DELETE THIS LINE -- g++dep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. - -.obj/Options.o .obj/Options.so .shobj/Options.o .shobj/Options.so: Options.cpp Options.h \ - $(ACE_ROOT)/ace/Log_Msg.h \ - $(ACE_ROOT)/ace/Log_Record.h \ - $(ACE_ROOT)/ace/ACE.h \ - $(ACE_ROOT)/ace/OS.h \ - $(ACE_ROOT)/ace/inc_user_config.h \ - $(ACE_ROOT)/ace/config.h \ - $(ACE_ROOT)/ace/config-sunos5.5.h \ - $(ACE_ROOT)/ace/config-g++-common.h \ - $(ACE_ROOT)/ace/streams.h \ - $(ACE_ROOT)/ace/Basic_Types.h \ - $(ACE_ROOT)/ace/Basic_Types.i \ - $(ACE_ROOT)/ace/OS.i \ - $(ACE_ROOT)/ace/Trace.h \ - $(ACE_ROOT)/ace/ACE.i \ - $(ACE_ROOT)/ace/Log_Priority.h \ - $(ACE_ROOT)/ace/SString.h \ - $(ACE_ROOT)/ace/SString.i \ - $(ACE_ROOT)/ace/Malloc_Base.h \ - $(ACE_ROOT)/ace/Log_Record.i \ - $(ACE_ROOT)/ace/Get_Opt.h \ - $(ACE_ROOT)/ace/Get_Opt.i Iterator.h -.obj/Iterator.o .obj/Iterator.so .shobj/Iterator.o .shobj/Iterator.so: Iterator.cpp Iterator.h \ - $(ACE_ROOT)/ace/OS.h \ - $(ACE_ROOT)/ace/inc_user_config.h \ - $(ACE_ROOT)/ace/config.h \ - $(ACE_ROOT)/ace/config-sunos5.5.h \ - $(ACE_ROOT)/ace/config-g++-common.h \ - $(ACE_ROOT)/ace/streams.h \ - $(ACE_ROOT)/ace/Basic_Types.h \ - $(ACE_ROOT)/ace/Basic_Types.i \ - $(ACE_ROOT)/ace/OS.i \ - $(ACE_ROOT)/ace/Trace.h \ - $(ACE_ROOT)/ace/Log_Msg.h \ - $(ACE_ROOT)/ace/Log_Record.h \ - $(ACE_ROOT)/ace/ACE.h \ - $(ACE_ROOT)/ace/ACE.i \ - $(ACE_ROOT)/ace/Log_Priority.h \ - $(ACE_ROOT)/ace/SString.h \ - $(ACE_ROOT)/ace/SString.i \ - $(ACE_ROOT)/ace/Malloc_Base.h \ - $(ACE_ROOT)/ace/Log_Record.i Options.h -.obj/Gen_Perf.o .obj/Gen_Perf.so .shobj/Gen_Perf.o .shobj/Gen_Perf.so: Gen_Perf.cpp Gen_Perf.h Options.h \ - $(ACE_ROOT)/ace/Log_Msg.h \ - $(ACE_ROOT)/ace/Log_Record.h \ - $(ACE_ROOT)/ace/ACE.h \ - $(ACE_ROOT)/ace/OS.h \ - $(ACE_ROOT)/ace/inc_user_config.h \ - $(ACE_ROOT)/ace/config.h \ - $(ACE_ROOT)/ace/config-sunos5.5.h \ - $(ACE_ROOT)/ace/config-g++-common.h \ - $(ACE_ROOT)/ace/streams.h \ - $(ACE_ROOT)/ace/Basic_Types.h \ - $(ACE_ROOT)/ace/Basic_Types.i \ - $(ACE_ROOT)/ace/OS.i \ - $(ACE_ROOT)/ace/Trace.h \ - $(ACE_ROOT)/ace/ACE.i \ - $(ACE_ROOT)/ace/Log_Priority.h \ - $(ACE_ROOT)/ace/SString.h \ - $(ACE_ROOT)/ace/SString.i \ - $(ACE_ROOT)/ace/Malloc_Base.h \ - $(ACE_ROOT)/ace/Log_Record.i \ - Key_List.h List_Node.h Vectors.h Bool_Array.h -.obj/Key_List.o .obj/Key_List.so .shobj/Key_List.o .shobj/Key_List.so: Key_List.cpp Key_List.h Options.h \ - $(ACE_ROOT)/ace/Log_Msg.h \ - $(ACE_ROOT)/ace/Log_Record.h \ - $(ACE_ROOT)/ace/ACE.h \ - $(ACE_ROOT)/ace/OS.h \ - $(ACE_ROOT)/ace/inc_user_config.h \ - $(ACE_ROOT)/ace/config.h \ - $(ACE_ROOT)/ace/config-sunos5.5.h \ - $(ACE_ROOT)/ace/config-g++-common.h \ - $(ACE_ROOT)/ace/streams.h \ - $(ACE_ROOT)/ace/Basic_Types.h \ - $(ACE_ROOT)/ace/Basic_Types.i \ - $(ACE_ROOT)/ace/OS.i \ - $(ACE_ROOT)/ace/Trace.h \ - $(ACE_ROOT)/ace/ACE.i \ - $(ACE_ROOT)/ace/Log_Priority.h \ - $(ACE_ROOT)/ace/SString.h \ - $(ACE_ROOT)/ace/SString.i \ - $(ACE_ROOT)/ace/Malloc_Base.h \ - $(ACE_ROOT)/ace/Log_Record.i \ - List_Node.h Vectors.h \ - $(ACE_ROOT)/ace/Read_Buffer.h \ - $(ACE_ROOT)/ace/Malloc.h \ - $(ACE_ROOT)/ace/Malloc.i \ - $(ACE_ROOT)/ace/Malloc_T.h \ - $(ACE_ROOT)/ace/Synch.h \ - $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ - $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ - $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ - $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ - $(ACE_ROOT)/ace/Synch.i \ - $(ACE_ROOT)/ace/Synch_T.h \ - $(ACE_ROOT)/ace/Event_Handler.h \ - $(ACE_ROOT)/ace/Event_Handler.i \ - $(ACE_ROOT)/ace/Synch_T.i \ - $(ACE_ROOT)/ace/Thread.h \ - $(ACE_ROOT)/ace/Thread.i \ - $(ACE_ROOT)/ace/Atomic_Op.i \ - $(ACE_ROOT)/ace/Synch_T.cpp \ - $(ACE_ROOT)/ace/Free_List.h \ - $(ACE_ROOT)/ace/Free_List.i \ - $(ACE_ROOT)/ace/Free_List.cpp \ - $(ACE_ROOT)/ace/Malloc_T.i \ - $(ACE_ROOT)/ace/Malloc_T.cpp \ - $(ACE_ROOT)/ace/Memory_Pool.h \ - $(ACE_ROOT)/ace/Signal.h \ - $(ACE_ROOT)/ace/Containers.h \ - $(ACE_ROOT)/ace/Containers.i \ - $(ACE_ROOT)/ace/Containers_T.h \ - $(ACE_ROOT)/ace/Containers_T.i \ - $(ACE_ROOT)/ace/Containers_T.cpp \ - $(ACE_ROOT)/ace/Signal.i \ - $(ACE_ROOT)/ace/Object_Manager.h \ - $(ACE_ROOT)/ace/Object_Manager.i \ - $(ACE_ROOT)/ace/Managed_Object.h \ - $(ACE_ROOT)/ace/Managed_Object.i \ - $(ACE_ROOT)/ace/Managed_Object.cpp \ - $(ACE_ROOT)/ace/Mem_Map.h \ - $(ACE_ROOT)/ace/Mem_Map.i \ - $(ACE_ROOT)/ace/Memory_Pool.i \ - $(ACE_ROOT)/ace/Read_Buffer.i \ - Hash_Table.h -.obj/List_Node.o .obj/List_Node.so .shobj/List_Node.o .shobj/List_Node.so: List_Node.cpp List_Node.h \ - $(ACE_ROOT)/ace/OS.h \ - $(ACE_ROOT)/ace/inc_user_config.h \ - $(ACE_ROOT)/ace/config.h \ - $(ACE_ROOT)/ace/config-sunos5.5.h \ - $(ACE_ROOT)/ace/config-g++-common.h \ - $(ACE_ROOT)/ace/streams.h \ - $(ACE_ROOT)/ace/Basic_Types.h \ - $(ACE_ROOT)/ace/Basic_Types.i \ - $(ACE_ROOT)/ace/OS.i \ - $(ACE_ROOT)/ace/Trace.h \ - $(ACE_ROOT)/ace/Log_Msg.h \ - $(ACE_ROOT)/ace/Log_Record.h \ - $(ACE_ROOT)/ace/ACE.h \ - $(ACE_ROOT)/ace/ACE.i \ - $(ACE_ROOT)/ace/Log_Priority.h \ - $(ACE_ROOT)/ace/SString.h \ - $(ACE_ROOT)/ace/SString.i \ - $(ACE_ROOT)/ace/Malloc_Base.h \ - $(ACE_ROOT)/ace/Log_Record.i Options.h \ - Vectors.h -.obj/Hash_Table.o .obj/Hash_Table.so .shobj/Hash_Table.o .shobj/Hash_Table.so: Hash_Table.cpp Hash_Table.h \ - $(ACE_ROOT)/ace/OS.h \ - $(ACE_ROOT)/ace/inc_user_config.h \ - $(ACE_ROOT)/ace/config.h \ - $(ACE_ROOT)/ace/config-sunos5.5.h \ - $(ACE_ROOT)/ace/config-g++-common.h \ - $(ACE_ROOT)/ace/streams.h \ - $(ACE_ROOT)/ace/Basic_Types.h \ - $(ACE_ROOT)/ace/Basic_Types.i \ - $(ACE_ROOT)/ace/OS.i \ - $(ACE_ROOT)/ace/Trace.h \ - $(ACE_ROOT)/ace/Log_Msg.h \ - $(ACE_ROOT)/ace/Log_Record.h \ - $(ACE_ROOT)/ace/ACE.h \ - $(ACE_ROOT)/ace/ACE.i \ - $(ACE_ROOT)/ace/Log_Priority.h \ - $(ACE_ROOT)/ace/SString.h \ - $(ACE_ROOT)/ace/SString.i \ - $(ACE_ROOT)/ace/Malloc_Base.h \ - $(ACE_ROOT)/ace/Log_Record.i Options.h \ - List_Node.h -.obj/Bool_Array.o .obj/Bool_Array.so .shobj/Bool_Array.o .shobj/Bool_Array.so: Bool_Array.cpp Bool_Array.h \ - $(ACE_ROOT)/ace/OS.h \ - $(ACE_ROOT)/ace/inc_user_config.h \ - $(ACE_ROOT)/ace/config.h \ - $(ACE_ROOT)/ace/config-sunos5.5.h \ - $(ACE_ROOT)/ace/config-g++-common.h \ - $(ACE_ROOT)/ace/streams.h \ - $(ACE_ROOT)/ace/Basic_Types.h \ - $(ACE_ROOT)/ace/Basic_Types.i \ - $(ACE_ROOT)/ace/OS.i \ - $(ACE_ROOT)/ace/Trace.h \ - $(ACE_ROOT)/ace/Log_Msg.h \ - $(ACE_ROOT)/ace/Log_Record.h \ - $(ACE_ROOT)/ace/ACE.h \ - $(ACE_ROOT)/ace/ACE.i \ - $(ACE_ROOT)/ace/Log_Priority.h \ - $(ACE_ROOT)/ace/SString.h \ - $(ACE_ROOT)/ace/SString.i \ - $(ACE_ROOT)/ace/Malloc_Base.h \ - $(ACE_ROOT)/ace/Log_Record.i Options.h -.obj/Vectors.o .obj/Vectors.so .shobj/Vectors.o .shobj/Vectors.so: Vectors.cpp Vectors.h \ - $(ACE_ROOT)/ace/OS.h \ - $(ACE_ROOT)/ace/inc_user_config.h \ - $(ACE_ROOT)/ace/config.h \ - $(ACE_ROOT)/ace/config-sunos5.5.h \ - $(ACE_ROOT)/ace/config-g++-common.h \ - $(ACE_ROOT)/ace/streams.h \ - $(ACE_ROOT)/ace/Basic_Types.h \ - $(ACE_ROOT)/ace/Basic_Types.i \ - $(ACE_ROOT)/ace/OS.i \ - $(ACE_ROOT)/ace/Trace.h \ - $(ACE_ROOT)/ace/Log_Msg.h \ - $(ACE_ROOT)/ace/Log_Record.h \ - $(ACE_ROOT)/ace/ACE.h \ - $(ACE_ROOT)/ace/ACE.i \ - $(ACE_ROOT)/ace/Log_Priority.h \ - $(ACE_ROOT)/ace/SString.h \ - $(ACE_ROOT)/ace/SString.i \ - $(ACE_ROOT)/ace/Malloc_Base.h \ - $(ACE_ROOT)/ace/Log_Record.i -.obj/Version.o .obj/Version.so .shobj/Version.o .shobj/Version.so: Version.cpp \ - $(ACE_ROOT)/ace/ACE.h \ - $(ACE_ROOT)/ace/OS.h \ - $(ACE_ROOT)/ace/inc_user_config.h \ - $(ACE_ROOT)/ace/config.h \ - $(ACE_ROOT)/ace/config-sunos5.5.h \ - $(ACE_ROOT)/ace/config-g++-common.h \ - $(ACE_ROOT)/ace/streams.h \ - $(ACE_ROOT)/ace/Basic_Types.h \ - $(ACE_ROOT)/ace/Basic_Types.i \ - $(ACE_ROOT)/ace/OS.i \ - $(ACE_ROOT)/ace/Trace.h \ - $(ACE_ROOT)/ace/Log_Msg.h \ - $(ACE_ROOT)/ace/Log_Record.h \ - $(ACE_ROOT)/ace/ACE.i \ - $(ACE_ROOT)/ace/Log_Priority.h \ - $(ACE_ROOT)/ace/SString.h \ - $(ACE_ROOT)/ace/SString.i \ - $(ACE_ROOT)/ace/Malloc_Base.h \ - $(ACE_ROOT)/ace/Log_Record.i - -# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/apps/gperf/src/Options.cpp b/apps/gperf/src/Options.cpp deleted file mode 100644 index 53523f70596..00000000000 --- a/apps/gperf/src/Options.cpp +++ /dev/null @@ -1,812 +0,0 @@ -// $Id$ - -// Handles parsing the Options provided to the user. - -/* Copyright (C) 1989 Free Software Foundation, Inc. - written by Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 1, or (at your option) any -later version. - -GNU GPERF is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, -USA. */ - -#include "Options.h" - -ACE_RCSID(src, Options, "$Id$") - -#if defined (ACE_HAS_GPERF) - -#include "ace/Get_Opt.h" -#include "Iterator.h" - -// Global option coordinator for the entire program. -Options option; - -// Current program version. -extern char *version_string; - -// 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 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 delimiters that separate keywords from their attributes. -static const char *const DEFAULT_DELIMITERS = ",\n"; - -int Options::option_word_; -int Options::total_switches_; -u_int Options::total_keysig_size_; -int Options::size_; -int Options::key_pos_; -int Options::jump_; -int Options::initial_asso_value_; -int Options::argc_; -char **Options::argv_; -int Options::iterations_; -const char *Options::function_name_; -const char *Options::key_name_; -const char *Options::class_name_; -const char *Options::hash_name_; -const char *Options::delimiters_; -char Options::key_positions_[MAX_KEY_POS]; - -// Prints program usage to standard error stream. - -void -Options::usage (void) -{ - ACE_ERROR ((LM_ERROR, - "Usage: %n [-abBcCdDef[num]gGhH<hashname>i<init>IjJ" - "k<keys>K<keyname>lL<language>mMnN<function name>o" - "Oprs<size>S<switches>tTvVZ<class name>].\n" - "(type %n -h for help)\n")); -} - -// Output command-line Options. - -void -Options::print_options (void) -{ - int i; - - ACE_OS::printf ("/* Command-line: "); - - for (i = 0; i < argc_; i++) - ACE_OS::printf ("%s ", - argv_[i]); - - ACE_OS::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. - -int -Options::key_sort (char *base, int len) -{ - int i, j; - - for (i = 0, j = len - 1; i < j; i++) - { - int curr, tmp; - - for (curr = i + 1, tmp = base[curr]; - curr > 0 && tmp >= base[curr - 1]; - curr--) - if ((base[curr] = base[curr - 1]) == tmp) - // Oh no, a duplicate!!! - return 0; - - base[curr] = tmp; - } - - return 1; -} - -// Sets the default Options. - -Options::Options (void) -{ - 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; - hash_name_ = DEFAULT_HASH_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) -{ - if (ACE_BIT_ENABLED (option_word_, DEBUG)) - { - char *ptr; - - ACE_OS::fprintf (stderr, "\ndumping Options:\nDEBUG is.......: %s\nORDER is.......: %s" - "\nANSI is........: %s\nTYPE is........: %s\nINLINE is......: %s" - "\nRANDOM is......: %s\nDEFAULTCHARS is: %s\nSWITCH is......: %s" - "\nPOINTER is.....: %s\nNOLENGTH is....: %s\nLENTABLE is....: %s" - "\nDUP is.........: %s\nFAST is........: %s\nCOMP is........: %s" - "\nNOTYPE is......: %s\nGLOBAL is......: %s\nCONSTANT is....: %s" - "\nCPLUSPLUS is...: %s\nC is...........: %s\nENUM is........: %s" - "\nSTRCASECMP is..: %s\nOPTIMIZE is....: %s\nLINEARSEARCH is: %s" - "\nBINARYSEARCH is: %s" - "\niterations = %d\nlookup function name = %s\nhash function name = %s" - "\nkey name = %s\njump value = %d\nmax associcated value = %d" - "\ninitial associated value = %d\ndelimiters = %s\nnumber of switch statements = %d\n", - ACE_BIT_ENABLED (option_word_, DEBUG) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, ORDER) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, ANSI) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, TYPE) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, INLINE) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, RANDOM) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, DEFAULTCHARS) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, SWITCH) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, POINTER) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, NOLENGTH) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, LENTABLE) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, DUP) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, FAST) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, COMP) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, NOTYPE) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, GLOBAL) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, CONSTANT) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, CPLUSPLUS) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, C) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, ENUM) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, STRCASECMP) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, OPTIMIZE) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, LINEARSEARCH) ? "enabled" : "disabled", - ACE_BIT_ENABLED (option_word_, BINARYSEARCH) ? "enabled" : "disabled", - iterations_, - function_name_, - hash_name_, - key_name_, - jump_, - size_ - 1, - initial_asso_value_, - delimiters_, - total_switches_); - if (ACE_BIT_ENABLED (option_word_, ALLCHARS)) - ACE_OS::fprintf (stderr, - "all characters are used in the hash function\n"); - - ACE_OS::fprintf (stderr, - "maximum keysig size = %d\nkey positions are: \n", - total_keysig_size_); - - for (ptr = key_positions_; *ptr != EOS; ptr++) - if (*ptr == WORD_END) - ACE_OS::fprintf (stderr, "$\n"); - else - ACE_OS::fprintf (stderr, "%d\n", *ptr); - - ACE_OS::fprintf (stderr, "finished dumping Options\n"); - } -} - -// Parses the command line Options and sets appropriate flags in -// option_word_. - -int -Options::parse_args (int argc, char *argv[]) -{ - if (ACE_LOG_MSG->open (argv[0]) == -1) - return -1; - - ACE_Get_Opt getopt (argc, argv, "abBcCdDe:Ef:gGhH:i:IJj:k:K:lL:mMnN:oOprs:S:tTvVZ:"); - int option_char; - - argc_ = argc; - argv_ = argv; - - while ((option_char = getopt ()) != -1) - { - switch (option_char) - { - // Generated coded uses the ANSI prototype format. - case 'a': - { - ACE_SET_BITS (option_word_, ANSI); - break; - } - // Generate code for Linear Search. - case 'b': - { - ACE_SET_BITS (option_word_, LINEARSEARCH); - break; - } - // Generate code for Binary Search. - case 'B': - { - ACE_SET_BITS (option_word_, BINARYSEARCH); - break; - } - // Generate strncmp rather than strcmp. - case 'c': - { - ACE_SET_BITS (option_word_, COMP); - break; - } - // Make the generated tables readonly (const). - case 'C': - { - ACE_SET_BITS (option_word_, CONSTANT); - break; - } - // Enable debugging option. - case 'd': - { - ACE_SET_BITS (option_word_, DEBUG); - ACE_ERROR ((LM_ERROR, - "Starting program %n, version %s, with debuggin on.\n", - version_string)); - break; - } - // Enable duplicate option. - case 'D': - { - ACE_SET_BITS (option_word_, DUP); - break; - } - // Allows user to provide keyword/attribute separator - case 'e': - { - delimiters_ = getopt.optarg; - break; - } - case 'E': - { - ACE_SET_BITS (option_word_, ENUM); - break; - } - // Generate the hash table ``fast.'' - case 'f': - { - ACE_SET_BITS (option_word_, FAST); - iterations_ = atoi (getopt.optarg); - if (iterations_ < 0) - { - ACE_ERROR ((LM_ERROR, "iterations value must not be negative, assuming 0\n")); - iterations_ = 0; - } - break; - } - // Use the ``inline'' keyword for generated sub-routines. - case 'g': - { - ACE_SET_BITS (option_word_, INLINE); - break; - } - // Make the keyword table a global variable. - case 'G': - { - ACE_SET_BITS (option_word_, GLOBAL); - break; - } - // Displays a list of helpful Options to the user. - case 'h': - { - ACE_OS::fprintf (stderr, - "-a\tGenerate ANSI standard C output code, i.e., function prototypes.\n" - "-b\tGenerate code for Linear Search.\n" - "-B\tGenerate code for Binary Search.\n" - "-c\tGenerate comparison code using strncmp rather than strcmp.\n" - "-C\tMake the contents of generated lookup tables constant, i.e., readonly.\n" - "-d\tEnables the debugging option (produces verbose output to the standard error).\n" - "-D\tHandle keywords that hash to duplicate values. This is useful\n" - "\tfor certain highly redundant keyword sets.\n" - "-e\tAllow user to provide a string containing delimiters used to separate\n" - "\tkeywords from their attributes. Default is \",\\n\"\n" - "-E\tDefine constant values using an enum local to the lookup function\n" - "\trather than with defines\n" - "-f\tGenerate the gen-perf.hash function ``fast.'' This decreases GPERF's\n" - "\trunning time at the cost of minimizing generated table-size.\n" - "\tThe numeric argument represents the number of times to iterate when\n" - "\tresolving a collision. `0' means ``iterate by the number of keywords.''\n" - "-g\tMake generated routines use ``inline'' to remove function overhead.\n" - "-G\tGenerate the static table of keywords as a static global variable,\n" - "\trather than hiding it inside of the lookup function (which is the\n" - "\tdefault behavior).\n" - "-h\tPrints this mesage.\n" - "-H\tAllow user to specify name of generated hash function. Default\n" - "\tis `hash'.\n" - "-i\tProvide an initial value for the associate values array. Default is 0.\n" - "-I\tGenerate comparison code using case insensitive string comparison, e.g.,\n" - "\tstrncasecmp or strcasecmp.\n" - "\tSetting this value larger helps inflate the size of the final table.\n" - "-j\tAffects the ``jump value,'' i.e., how far to advance the associated\n" - "\tcharacter value upon collisions. Must be an odd number, default is %d.\n" - "-J\tSkips '#include <string.h>' part in the output.\n" - "-k\tAllows selection of the key positions used in the hash function.\n" - "\tThe allowable choices range between 1-%d, inclusive. The positions\n" - "\tare separated by commas, ranges may be used, and key positions may\n" - "\toccur in any order. Also, the meta-character '*' causes the generated\n" - "\thash function to consider ALL key positions, and $ indicates the\n" - "\t``final character'' of a key, e.g., $,1,2,4,6-10.\n" - "-K\tAllow use to select name of the keyword component in the keyword structure.\n" - "-l\tCompare key lengths before trying a string comparison. This helps\n" - "\tcut down on the number of string comparisons made during the lookup.\n" - "-L\tGenerates code in the language specified by the option's argument. Languages\n" - "\thandled are currently C++ and C. The default is C.\n" - "-m\tAvoids the warning about identical hash values. This is valid\n" - "\tonly if the -D option is enabled.\n" - "-M\tSkips class definition in the output. This is valid only in C++ mode.\n" - "-n\tDo not include the length of the keyword when computing the hash function\n" - "-N\tAllow user to specify name of generated lookup function. Default\n" - "\tname is `in_word_set.'\n" - "-o\tReorders input keys by frequency of occurrence of the key sets.\n" - "\tThis should decrease the search time dramatically.\n" - "-O\tOptimize the generated lookup function by assuming that all input keywords \n" - "\tare members of the keyset from the keyfile.\n" - "-p\tChanges the return value of the generated function ``in_word_set''\n" - "\tfrom its default boolean value (i.e., 0 or 1), to type ``pointer\n" - "\tto wordlist array'' This is most useful when the -t option, allowing\n" - "\tuser-defined structs, is used.\n" - "-r\tUtilizes randomness to initialize the associated values table.\n" - "-s\tAffects the size of the generated hash table. The numeric argument\n" - "\tfor this option indicates ``how many times larger or smaller'' the associated\n" - "\tvalue range should be, in relationship to the number of keys, e.g. a value of 3\n" - "\tmeans ``allow the maximum associated value to be about 3 times larger than the\n" - "\tnumber of input keys.'' Conversely, a value of -3 means ``make the maximum\n" - "\tassociated value about 3 times smaller than the number of input keys.\n" - "\tA larger table should decrease the time required for an unsuccessful search,\n" - "\tat the expense of extra table space. Default value is 1.\n" - "-S\tCauses the generated C code to use a switch statement scheme, rather\n" - "\tthan an array lookup table. This can lead to a reduction in both\n" - "\ttime and space requirements for some keyfiles. The argument to\n" - "\tthis option determines how many switch statements are generated.\n" - "\tA value of 1 generates 1 switch containing all the elements, a value of 2\n" - "\tgenerates 2 tables with 1/2 the elements in each table, etc. This\n" - "\tis useful since many C compilers cannot correctly generate code for\n" - "\tlarge switch statements.\n" - "-t\tAllows the user to include a structured type declaration for \n" - "\tgenerated code. Any text before %%%% is consider part of the type\n" - "\tdeclaration. Key words and additional fields may follow this, one\n" - "\tgroup of fields per line.\n" - "-T\tPrevents the transfer of the type declaration to the output file.\n" - "\tUse this option if the type is already defined elsewhere.\n" - "-v\tPrints out the current version number and exits with a value of 0\n" - "-V\tExits silently with a value of 0.\n" - "-Z\tAllow user to specify name of generated C++ class. Default\n" - "\tname is `Perfect_Hash.'\n", - DEFAULT_JUMP_VALUE, - MAX_KEY_POS - 1); - Options::usage (); - return -1; - } - // Sets the name for the hash function. - case 'H': - { - hash_name_ = getopt.optarg; - break; - } - // Sets the initial value for the associated values array. - case 'i': - { - initial_asso_value_ = atoi (getopt.optarg); - if (initial_asso_value_ < 0) - ACE_ERROR ((LM_ERROR, - "Initial value %d should be non-zero, ignoring and continuing.\n", - initial_asso_value_)); - if (option[RANDOM]) - ACE_ERROR ((LM_ERROR, - "warning, -r option superceeds -i, ignoring -i option and continuing\n")); - break; - } - case 'I': - { - ACE_SET_BITS (option_word_, STRCASECMP); - break; - } - // Sets the jump value, must be odd for later algorithms. - case 'j': - { - jump_ = atoi (getopt.optarg); - if (jump < 0) - ACE_ERROR_RETURN ((LM_ERROR, - "Jump value %d must be a positive number.\n%r", - jump_, - &Options::usage), - -1); - else if (jump_ && ACE_EVEN (jump_)) - ACE_ERROR ((LM_ERROR, - "Jump value %d should be odd, adding 1 and continuing...\n", - jump_++)); - break; - } - // Skip including the header file string.h. - case 'J': - { - ACE_SET_BITS (option_word_, SKIPSTRINGH); - break; - } - // Sets key positions used for hash function. - case 'k': - { - const int BAD_VALUE = -1; - int value; - Iterator expand (getopt.optarg, - 1, - MAX_KEY_POS - 1, - WORD_END, - BAD_VALUE, - EOS); - - // Use all the characters for hashing!!!! - if (*getopt.optarg == '*') - option_word_ = (option_word_ & ~DEFAULTCHARS) | ALLCHARS; - else - { - char *l_key_pos; - - for (l_key_pos = key_positions_; - (value = expand ()) != EOS; - l_key_pos++) - if (value == BAD_VALUE) - ACE_ERROR_RETURN ((LM_ERROR, - "Illegal key value or range, use 1,2,3-%d,'$' or '*'.\n%r", - MAX_KEY_POS - 1, - usage), - -1); - else - *l_key_pos = value;; - - *l_key_pos = EOS; - - total_keysig_size_ = (l_key_pos - key_positions_); - if (total_keysig_size_ == 0) - ACE_ERROR_RETURN ((LM_ERROR, - "No keys selected.\n%r", - &Options::usage), - -1); - else if (key_sort (key_positions_, total_keysig_size_) == 0) - ACE_ERROR_RETURN ((LM_ERROR, - "Duplicate keys selected\n%r", - &Options::usage), - -1); - if (total_keysig_size_ != 2 - || (key_positions_[0] != 1 - || key_positions_[1] != WORD_END)) - ACE_CLR_BITS (option_word_, DEFAULTCHARS); - } - break; - } - // Make this the keyname for the keyword component field. - case 'K': - { - key_name_ = getopt.optarg; - break; - } - // Create length table to avoid extra string compares. - case 'l': - { - ACE_SET_BITS (option_word_, LENTABLE); - break; - } - // Deal with different generated languages. - case 'L': - { - option_word_ &= ~C; - if (!ACE_OS::strcmp (getopt.optarg, "C++")) - ACE_SET_BITS (option_word_, (CPLUSPLUS | ANSI)); - else if (!ACE_OS::strcmp (getopt.optarg, "C")) - ACE_SET_BITS (option_word_, C); - else - { - ACE_ERROR ((LM_ERROR, - "unsupported language option %s, defaulting to C\n", - getopt.optarg)); - ACE_SET_BITS (option_word_, C); - } - break; - } - // Don't print the warnings. - case 'm': - { - ACE_SET_BITS (option_word_, MUTE); - break; - } - // Skip the class definition while in C++ mode. - case 'M': - { - ACE_SET_BITS (option_word_, SKIPCLASS); - break; - } - // Don't include the length when computing hash function. - case 'n': - { - ACE_SET_BITS (option_word_, NOLENGTH); - break; - } - // Make generated lookup function name be optarg - case 'N': - { - function_name_ = getopt.optarg; - break; - } - // Order input by frequency of key set occurrence. - case 'o': - { - ACE_SET_BITS (option_word_, ORDER); - break; - } - case 'O': - { - ACE_SET_BITS (option_word_, OPTIMIZE); - break; - } - // Generated lookup function now a pointer instead of int. - case 'p': - { - ACE_SET_BITS (option_word_, POINTER); - break; - } - // Utilize randomness to initialize the associated values - // table. - case 'r': - { - ACE_SET_BITS (option_word_, RANDOM); - if (initial_asso_value_ != 0) - ACE_ERROR ((LM_ERROR, - "warning, -r option superceeds -i, disabling -i option and continuing\n")); - break; - } - // Range of associated values, determines size of final table. - case 's': - { - size_ = atoi (getopt.optarg); - if (abs (size_) > 50) - ACE_ERROR ((LM_ERROR, - "%d is excessive, did you really mean this?! (type %n -h for help)\n", - size_)); - break; - } - // Generate switch statement output, rather than lookup table. - case 'S': - { - ACE_SET_BITS (option_word_, SWITCH); - total_switches_ = atoi (getopt.optarg); - if (total_switches_ <= 0) - ACE_ERROR_RETURN ((LM_ERROR, - "number of switches %s must be a positive number\n%r", - getopt.optarg, - &Options::usage), - -1); - break; - } - // Enable the TYPE mode, allowing arbitrary user structures. - case 't': - { - ACE_SET_BITS (option_word_, TYPE); - break; - } - // Don't print structure definition. - case 'T': - { - ACE_SET_BITS (option_word_, NOTYPE); - break; - } - // Print out the version and quit. - case 'v': - ACE_ERROR ((LM_ERROR, - "%n: version %s\n%r\n%a", - version_string, - &Options::usage, - 0)); - /* NOTREACHED */ - break; - // Exit with value of 0 (this is useful to check if gperf exists) - case 'V': - ACE_OS::exit (0); - /* NOTREACHED */ - break; - // Set the class name. - case 'Z': - { - class_name_ = getopt.optarg; - break; - } - default: - ACE_ERROR_RETURN ((LM_ERROR, - "%r", - &Options::usage), - -1); - } - - } - - if (argv[getopt.optind] && - freopen (argv[getopt.optind], - "r", - stdin) == 0) - ACE_ERROR_RETURN ((LM_ERROR, - "Cannot open keyword file %p\n%r", - argv[getopt.optind], - &Options::usage), - -1); - if (++getopt.optind < argc) - ACE_ERROR_RETURN ((LM_ERROR, - "Extra trailing arguments to %n.\n%r", - usage), - -1); - return 0; -} - -// True if option enable, else false. - -int -Options::operator[] (Option_Type option) -{ - return ACE_BIT_ENABLED (option_word_, option); -} - -// Enables option OPT. - -void -Options::operator = (enum Option_Type opt) -{ - ACE_SET_BITS (option_word_, opt); -} - -// Disables option OPT. - -void -Options::operator != (enum Option_Type opt) -{ - ACE_CLR_BITS (option_word_, opt); -} - -// Initializes the key Iterator. - -void -Options::reset (void) -{ - key_pos_ = 0; -} - -// Returns current key_position and advanced index. - -int -Options::get (void) -{ - return key_positions_[key_pos_++]; -} - -// Sets the size of the table size. - -void -Options::asso_max (int r) -{ - size_ = r; -} - -// Returns the size of the table size. - -int -Options::asso_max (void) -{ - return size_; -} - -// Returns total distinct key positions. - -u_int -Options::max_keysig_size (void) -{ - return total_keysig_size_; -} - -// Sets total distinct key positions. - -void -Options::keysig_size (u_int a_size) -{ - total_keysig_size_ = a_size; -} - -// Returns the jump value. - -int -Options::jump (void) -{ - return jump_; -} - -// Returns the generated function name. - -const char * -Options::function_name (void) -{ - return function_name_; -} - -// Returns the keyword key name. - -const char * -Options::key_name (void) -{ - return key_name_; -} - -// Returns the hash function name. - -const char * -Options::hash_name (void) -{ - return hash_name_; -} - -// Returns the generated class name. - -const char * -Options::class_name (void) -{ - return class_name_; -} - -// Returns the initial associated character value. - -int -Options::initial_value (void) -{ - return initial_asso_value_; -} - -// Returns the iterations value. - -int -Options::iterations (void) -{ - return iterations_; -} - -// Returns the string used to delimit keywords from other attributes. - -const char * -Options::delimiter (void) -{ - return delimiters_; -} - -// Gets the total number of switch statements to generate. - -int -Options::total_switches (void) -{ - return total_switches_; -} - -#endif /* ACE_HAS_GPERF */ diff --git a/apps/gperf/src/Options.h b/apps/gperf/src/Options.h deleted file mode 100644 index 4b102892a32..00000000000 --- a/apps/gperf/src/Options.h +++ /dev/null @@ -1,180 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -/* Copyright (C) 1989 Free Software Foundation, Inc. - written by Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 1, or (at your option) any -later version. - -GNU GPERF is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, -USA. */ - -#ifndef OPTIONS_H -#define OPTIONS_H - -#include "ace/Log_Msg.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#if defined (ACE_HAS_GPERF) - -// 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. - ANSI = 04, // Generate ANSI prototypes. - ALLCHARS = 010, // Use all characters in hash function. - INLINE = 020, // Generate code for inline functions. - TYPE = 040, // Handle user-defined type structured keyword input. - RANDOM = 0100, // Randomly initialize the associated values table. - DEFAULTCHARS = 0200, // Make default char positions be 1,$ (end of keyword). - SWITCH = 0400, // Generate switch output to save space. - POINTER = 01000, // Have in_word_set function return pointer, not boolean. - NOLENGTH = 02000, // Don't include keyword length in hash computations. - LENTABLE = 04000, // Generate a length table for string comparison. - DUP = 010000, // Handle duplicate hash values for keywords. - FAST = 020000, // Generate the hash function ``fast.'' - NOTYPE = 040000, // Don't include user-defined type definition in output -- it's already defined elsewhere. - COMP = 0100000, // Generate strncmp rather than strcmp. - GLOBAL = 0200000, // Make the keyword table a global variable. - CONSTANT = 0400000, // Make the generated tables readonly (const). - CPLUSPLUS = 01000000, // Generate C++ code. - C = 02000000, // Generate C code. - ENUM = 04000000, // Use enum for constants. - STRCASECMP = 010000000, // Use the case insensitive comparison. - OPTIMIZE = 020000000, // Assume all input keywords are in the keyset. - ADA = 040000000, // Generate Ada code. - MUTE = 0100000000, // Dont print the warnings. - SKIPCLASS = 0200000000, // Skip the class definition part in the output while in C++ mode. - SKIPSTRINGH = 0400000000, // Skip including the header file string.h. - BINARYSEARCH = 01000000000, // Generates Binary Search code. - LINEARSEARCH = 02000000000 // Generates Linear Search code. -}; - -// 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. -}; - -// @@ The Options class should be changed to use the Singleton pattern. -class Options -{ - // = TITLE - // This class provides a uniform interface to the various options - // available to a user of the gperf hash function generator. - // - // = DESCRIPTION - // In addition to the run-time options, found in the <Option_Type> - // 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. -public: - Options (void); - ~Options (void); - int operator[] (Option_Type option); - int parse_args (int argc, char *argv[]); - void operator= (enum Option_Type); - void operator!= (enum Option_Type); - static void print_options (void); - static void asso_max (int r); - static int asso_max (void); - static void reset (void); - static int get (void); - static int iterations (void); - static u_int max_keysig_size (void); - static void keysig_size (u_int); - static int jump (void); - static int initial_value (void); - static int total_switches (void); - static const char *function_name (void); - static const char *key_name (void); - static const char *class_name (void); - static const char *hash_name (void); - static const char *delimiter (void); - -private: - static int option_word_; - // Holds the user-specified Options. - - static int total_switches_; - // Number of switch statements to generate. - - static u_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 iterations_; - // Amount to iterate when a collision occurs. - - static int argc_; - // Records count of command-line arguments. - - static char **argv_; - // 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 *class_name_; - // Name used for generated C++ class. - - static const char *hash_name_; - // Name used for generated hash function. - - 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 usage (void); - // Prints proper program usage. -}; - -// Global option coordinator for the entire program. -extern Options option; - -#endif /* ACE_HAS_GPERF */ -#endif /* OPTIONS_H */ diff --git a/apps/gperf/src/Vectors.cpp b/apps/gperf/src/Vectors.cpp deleted file mode 100644 index a83eb74b5ef..00000000000 --- a/apps/gperf/src/Vectors.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// $Id$ - -/* Copyright (C) 1989 Free Software Foundation, Inc. - written by Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 1, or (at your option) any -later version. - -GNU GPERF is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, -USA. */ - -#include "Vectors.h" - -ACE_RCSID(src, Vectors, "$Id$") - -#if defined (ACE_HAS_GPERF) - -// Counts occurrences of each key set character. -int Vectors::occurrences[Vectors::ALPHA_SIZE]; - -// Value associated with each character. -int Vectors::asso_values[Vectors::ALPHA_SIZE]; - -#endif /* ACE_HAS_GPERF */ diff --git a/apps/gperf/src/Vectors.h b/apps/gperf/src/Vectors.h deleted file mode 100644 index f66a2d5e5a7..00000000000 --- a/apps/gperf/src/Vectors.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -/* Copyright (C) 1989 Free Software Foundation, Inc. - written by Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 1, or (at your option) any -later version. - -GNU GPERF is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, -USA. */ - -#ifndef VECTORS_H -#define VECTORS_H - -#include "ace/OS.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#if defined (ACE_HAS_GPERF) - -class Vectors -{ - // = TITLE - // Static class data members that are shared between several - // classes via inheritance. -public: - enum - { - ALPHA_SIZE = 128 - }; - - static int occurrences[ALPHA_SIZE]; - // Counts occurrences of each key set character. - - static int asso_values[ALPHA_SIZE]; - // Value associated with each character. -}; - -#endif /* ACE_HAS_GPERF */ -#endif /* VECTORS_H */ diff --git a/apps/gperf/src/Version.cpp b/apps/gperf/src/Version.cpp deleted file mode 100644 index deb5d5b9e5b..00000000000 --- a/apps/gperf/src/Version.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// $Id$ -// Current program version number. - -/* Copyright (C) 1989 Free Software Foundation, Inc. - written by Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 1, or (at your option) any -later version. - -GNU GPERF is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, -USA. */ - -#include "ace/ACE.h" - -ACE_RCSID(src, Version, "$Id$") - -char *version_string = "2.7 (GNU C++ version)"; diff --git a/apps/gperf/src/gperf.cpp b/apps/gperf/src/gperf.cpp deleted file mode 100644 index d4befbf8330..00000000000 --- a/apps/gperf/src/gperf.cpp +++ /dev/null @@ -1,82 +0,0 @@ -// $Id$ - -// Driver program for the gperf hash function generator. - -/* Copyright (C) 1989 Free Software Foundation, Inc. written by - Douglas C. Schmidt (schmidt@ics.uci.edu) - -This file is part of GNU GPERF. - -GNU GPERF is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 1, or (at your option) any -later version. - -GNU GPERF is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU GPERF; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, -USA. */ - -// Simple driver program for the gperf hash function generator. All -// the hard work is done in class Gen_Perf and its class methods. - -#include "Gen_Perf.h" - -ACE_RCSID(src, gperf, "$Id$") - -#if defined (ACE_HAS_GPERF) - -#include "Options.h" - -int -main (int argc, char *argv[]) -{ - struct tm *tm; - time_t clock; - - // Sets the Options. - if (option.parse_args (argc, argv) == -1) - return 1; - - ACE_OS::time (&clock); - tm = ACE_OS::localtime (&clock); - - ACE_OS::printf ("/* starting time is %d:%02d:%02d */\n", - tm->tm_hour, - tm->tm_min, - tm->tm_sec); - - // Initializes the key word list. - Gen_Perf gperf; - - // Generates and prints the gperf hash table. Don't use exit here, - // it skips the destructors. - int status = gperf.run (); - - ACE_OS::time (&clock); - tm = ACE_OS::localtime (&clock); - - ACE_OS::printf ("/* ending time is %d:%02d:%02d */\n", - tm->tm_hour, - tm->tm_min, - tm->tm_sec); - return status; -} -#else /* ! ACE_HAS_GPERF */ -int -main (int argc, char *argv[]) -{ - ACE_UNUSED_ARG (argc); - ACE_UNUSED_ARG (argv); - - ACE_ERROR_RETURN ((LM_ERROR, - "gperf is not operational because " - "ACE_HAS_GPERF was not enabled for the build\n"), - 1); -} -#endif /* ! ACE_HAS_GPERF */ diff --git a/apps/gperf/src/gperf.dsp b/apps/gperf/src/gperf.dsp deleted file mode 100644 index 1290436a2e2..00000000000 --- a/apps/gperf/src/gperf.dsp +++ /dev/null @@ -1,98 +0,0 @@ -# Microsoft Developer Studio Project File - Name="gperf" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=gperf - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "gperf.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "gperf.mak" CFG="gperf - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "gperf - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "gperf - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "gperf - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ""
-# PROP Intermediate_Dir ".\Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 gperf.lib ace.lib /nologo /subsystem:console /machine:I386 /out:"..\..\..\bin\Release\gperf.exe" /libpath:"..\..\..\ace" /libpath:".\lib"
-# SUBTRACT LINK32 /nodefaultlib
-
-!ELSEIF "$(CFG)" == "gperf - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ""
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 gperfd.lib aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\..\..\bin\gperf.exe" /pdbtype:sept /libpath:"..\..\..\ace" /libpath:".\lib\\"
-# SUBTRACT LINK32 /nodefaultlib
-
-!ENDIF
-
-# Begin Target
-
-# Name "gperf - Win32 Release"
-# Name "gperf - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter ".cpp"
-# Begin Source File
-
-SOURCE=.\gperf.cpp
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/apps/gperf/src/gperf.dsw b/apps/gperf/src/gperf.dsw deleted file mode 100644 index 6342ab5a626..00000000000 --- a/apps/gperf/src/gperf.dsw +++ /dev/null @@ -1,44 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "gperf"=.\gperf.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name gperf_lib
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "gperf_lib"=.\gperf_lib.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/apps/gperf/src/gperf_lib.dsp b/apps/gperf/src/gperf_lib.dsp deleted file mode 100644 index 264920a24fa..00000000000 --- a/apps/gperf/src/gperf_lib.dsp +++ /dev/null @@ -1,162 +0,0 @@ -# Microsoft Developer Studio Project File - Name="gperf_lib" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=gperf_lib - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "gperf_lib.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "gperf_lib.mak" CFG="gperf_lib - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "gperf_lib - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "gperf_lib - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "gperf_lib - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "gperf_li"
-# PROP BASE Intermediate_Dir "gperf_li"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\lib"
-# PROP Intermediate_Dir ".\lib\Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409
-# ADD RSC /l 0x409
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:".\lib\gperf.lib"
-
-!ELSEIF "$(CFG)" == "gperf_lib - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "gperf_l0"
-# PROP BASE Intermediate_Dir "gperf_l0"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\lib"
-# PROP Intermediate_Dir ".\lib\Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409
-# ADD RSC /l 0x409
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:".\lib\gperfd.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "gperf_lib - Win32 Release"
-# Name "gperf_lib - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter ".cpp"
-# Begin Source File
-
-SOURCE=.\Bool_Array.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Gen_Perf.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Hash_Table.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Iterator.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Key_List.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\List_Node.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Options.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Vectors.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Version.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter ".h"
-# Begin Source File
-
-SOURCE=.\Bool_Array.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Gen_Perf.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Hash_Table.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Iterator.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Key_List.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\List_Node.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Options.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Vectors.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/apps/gperf/tests/Makefile b/apps/gperf/tests/Makefile deleted file mode 100644 index 00714eebef2..00000000000 --- a/apps/gperf/tests/Makefile +++ /dev/null @@ -1,121 +0,0 @@ -# $Id$ -# Copyright (C) 1989, 1992, 1993 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 macros and targets -#---------------------------------------------------------------------------- - -SRC= test.cpp - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.lib.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -srcdir = . -GPERF = ../src/gperf - -all: - @echo "performing some tests of the perfect hash generator" - $(COMPILE.cc) $(srcdir)/test.cpp - $(GPERF) -a -p -c -l -S1 -o $(srcdir)/c.gperf > cinset.cpp - $(CXX) $(CCFLAGS) -o cout cinset.cpp test.o $(LDFLAGS) $(VLDLIBS) - ./cout -v < $(srcdir)/c.gperf > c.out - -diff -b $(srcdir)/c.exp c.out - $(GPERF) -a -k1,4,'$$' $(srcdir)/ada.gperf > adainset.cpp - $(CXX) $(CCFLAGS) -o aout adainset.cpp test.o $(LDFLAGS) $(VLDLIBS) - ./aout -v < $(srcdir)/ada.gperf > ada-res.out - -diff -b $(srcdir)/ada-res.exp ada-res.out - $(GPERF) -a -D $(srcdir)/c++.gperf > c++inset.cpp - $(CXX) $(CCFLAGS) -o c++out c++inset.cpp test.o $(LDFLAGS) $(VLDLIBS) - ./c++out -v < $(srcdir)/c++.gperf > c++-res.out - -diff -b $(srcdir)/c++-res.exp c++-res.out - $(GPERF) -a -p -D -k1,'$$' -s 2 -o $(srcdir)/adadefs.gperf > preinset.cpp - $(CXX) $(CCFLAGS) -o preout preinset.cpp test.o $(LDFLAGS) $(VLDLIBS) - ./preout -v < $(srcdir)/adadefs.gperf > ada-pred.out - -diff -b $(srcdir)/ada-pred.exp ada-pred.out - $(GPERF) -a -k1,2,'$$' -o $(srcdir)/modula3.gperf > m3inset.cpp - $(CXX) $(CCFLAGS) -o m3out m3inset.cpp test.o $(LDFLAGS) $(VLDLIBS) - ./m3out -v < $(srcdir)/modula3.gperf > modula.out - -diff -b $(srcdir)/modula.exp modula.out - $(GPERF) -a -o -S2 -p < $(srcdir)/pascal.gperf > pinset.cpp - $(CXX) $(CCFLAGS) -o pout pinset.cpp test.o $(LDFLAGS) $(VLDLIBS) - ./pout -v < $(srcdir)/pascal.gperf > pascal.out - -diff -b $(srcdir)/pascal.exp pascal.out - $(GPERF) -m -M -c -C -D -S1 -E -T -a -o -p < $(srcdir)/idl.gperf > iinset.cpp - $(CXX) $(CCFLAGS) -o iout iinset.cpp test.o $(LDFLAGS) $(VLDLIBS) - ./iout -v < $(srcdir)/idl.gperf > idl.out - -diff -b $(srcdir)/idl.exp idl.out - $(GPERF) -m -M -c -C -D -E -T -a -o -p < $(srcdir)/idl.gperf > iinset.cpp - $(CXX) $(CCFLAGS) -o iout iinset.cpp test.o $(LDFLAGS) $(VLDLIBS) - ./iout -v < $(srcdir)/idl.gperf > idl.out - -diff -b $(srcdir)/idl.exp idl.out - $(GPERF) -a -o < $(srcdir)/corba.gperf > tinset.cpp - $(CXX) $(CCFLAGS) -o tout tinset.cpp test.o $(LDFLAGS) $(VLDLIBS) - ./tout -v < $(srcdir)/corba.gperf > corba.out - -diff -b $(srcdir)/corba.exp corba.out -# these next 5 are demos that show off the generated code - $(GPERF) -p -j1 -o -t -N is_reserved_word -k1,3,'$$' < $(srcdir)/c-parse.gperf | egrep -v 'ing time is ' > test-1.out - -diff -b $(srcdir)/test-1.exp test-1.out - $(GPERF) -n -k1-8 -l <$(srcdir)/modula2.gperf | egrep -v 'ing time is ' > test-2.out - -diff -b $(srcdir)/test-2.exp test-2.out - $(GPERF) -p -j 1 -o -a -C -g -t -k1,4,$$ < $(srcdir)/gplus.gperf | egrep -v 'ing time is ' > test-3.out - -diff -b $(srcdir)/test-3.exp test-3.out - $(GPERF) -D -p -t < $(srcdir)/c-parse.gperf | egrep -v 'ing time is ' > test-4.out - -diff -b $(srcdir)/test-4.exp test-4.out - $(GPERF) -g -o -j1 -t -p -N is_reserved_word < $(srcdir)/gpc.gperf | egrep -v 'ing time is ' > test-5.out - -diff -b $(srcdir)/test-5.exp test-5.out -# prints out the help message - -$(GPERF) -a -h > test-6.out 2>&1 || [ a = a ] - -diff -b $(srcdir)/test-6.exp test-6.out - ./aout -v < $(srcdir)/c.gperf > test-7.out - -diff -b $(srcdir)/test-7.exp test-7.out - -realclean: - $(RM) -rf *.out cinset.cpp c++inset.cpp iinset.cpp tinset.cpp \ - pinset.cpp m3inset.cpp adainset.cpp preinset.cpp - $(RM) -rf c.out aout preout m3out pout cout c++out iout tout - -# DO NOT DELETE THIS LINE -- g++dep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. - -.obj/test.o .obj/test.so .shobj/test.o .shobj/test.so: test.cpp $(ACE_ROOT)/ace/OS.h \ - $(ACE_ROOT)/ace/inc_user_config.h \ - $(ACE_ROOT)/ace/config.h \ - $(ACE_ROOT)/ace/config-sunos5.5.h \ - $(ACE_ROOT)/ace/config-g++-common.h \ - $(ACE_ROOT)/ace/streams.h \ - $(ACE_ROOT)/ace/Basic_Types.h \ - $(ACE_ROOT)/ace/Basic_Types.i \ - $(ACE_ROOT)/ace/OS.i \ - $(ACE_ROOT)/ace/Trace.h \ - $(ACE_ROOT)/ace/Log_Msg.h \ - $(ACE_ROOT)/ace/Log_Record.h \ - $(ACE_ROOT)/ace/ACE.h \ - $(ACE_ROOT)/ace/ACE.i \ - $(ACE_ROOT)/ace/Log_Priority.h \ - $(ACE_ROOT)/ace/SString.h \ - $(ACE_ROOT)/ace/SString.i \ - $(ACE_ROOT)/ace/Malloc_Base.h \ - $(ACE_ROOT)/ace/Log_Record.i - -# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/apps/gperf/tests/ada-pred.exp b/apps/gperf/tests/ada-pred.exp deleted file mode 100644 index 33caaa32ea1..00000000000 --- a/apps/gperf/tests/ada-pred.exp +++ /dev/null @@ -1,54 +0,0 @@ -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/apps/gperf/tests/ada-res.exp b/apps/gperf/tests/ada-res.exp deleted file mode 100644 index 8134fe861f5..00000000000 --- a/apps/gperf/tests/ada-res.exp +++ /dev/null @@ -1,63 +0,0 @@ -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/apps/gperf/tests/ada.gperf b/apps/gperf/tests/ada.gperf deleted file mode 100644 index 332bdc740ad..00000000000 --- a/apps/gperf/tests/ada.gperf +++ /dev/null @@ -1,63 +0,0 @@ -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/apps/gperf/tests/adadefs.gperf b/apps/gperf/tests/adadefs.gperf deleted file mode 100644 index 875be69abc9..00000000000 --- a/apps/gperf/tests/adadefs.gperf +++ /dev/null @@ -1,54 +0,0 @@ -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/apps/gperf/tests/c++-res.exp b/apps/gperf/tests/c++-res.exp deleted file mode 100644 index 124af99193f..00000000000 --- a/apps/gperf/tests/c++-res.exp +++ /dev/null @@ -1,73 +0,0 @@ -in word set and -in word set and_eq -in word set asm -in word set auto -in word set bitand -in word set bitor -in word set bool -in word set break -in word set case -in word set catch -in word set char -in word set class -in word set compl -in word set const -in word set const_cast -in word set continue -in word set default -in word set delete -in word set do -in word set double -in word set dynamic_cast -in word set else -in word set enum -in word set explicit -in word set extern -in word set false -in word set float -in word set for -in word set friend -in word set goto -in word set if -in word set inline -in word set int -in word set long -in word set mutable -in word set namespace -in word set new -in word set not -in word set not_eq -in word set operator -in word set or -in word set or_eq -in word set private -in word set protected -in word set public -in word set register -in word set reinterpret_cast -in word set return -in word set short -in word set signed -in word set sizeof -in word set static -in word set static_cast -in word set struct -in word set switch -in word set template -in word set this -in word set throw -in word set true -in word set try -in word set typedef -in word set typeid -in word set typename -in word set union -in word set unsigned -in word set using -in word set virtual -in word set void -in word set volatile -in word set wchar_t -in word set while -in word set xor -in word set xor_eq diff --git a/apps/gperf/tests/c++.gperf b/apps/gperf/tests/c++.gperf deleted file mode 100644 index e8c8dc3f251..00000000000 --- a/apps/gperf/tests/c++.gperf +++ /dev/null @@ -1,73 +0,0 @@ -and -and_eq -asm -auto -bitand -bitor -bool -break -case -catch -char -class -compl -const -const_cast -continue -default -delete -do -double -dynamic_cast -else -enum -explicit -extern -false -float -for -friend -goto -if -inline -int -long -mutable -namespace -new -not -not_eq -operator -or -or_eq -private -protected -public -register -reinterpret_cast -return -short -signed -sizeof -static -static_cast -struct -switch -template -this -throw -true -try -typedef -typeid -typename -union -unsigned -using -virtual -void -volatile -wchar_t -while -xor -xor_eq diff --git a/apps/gperf/tests/c-parse.gperf b/apps/gperf/tests/c-parse.gperf deleted file mode 100644 index d1b8ba6c0ea..00000000000 --- a/apps/gperf/tests/c-parse.gperf +++ /dev/null @@ -1,56 +0,0 @@ -%{ -/* Command-line: gperf -p -j1 -i 1 -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/apps/gperf/tests/c.exp b/apps/gperf/tests/c.exp deleted file mode 100644 index 10c8b7f6116..00000000000 --- a/apps/gperf/tests/c.exp +++ /dev/null @@ -1,32 +0,0 @@ -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/apps/gperf/tests/c.gperf b/apps/gperf/tests/c.gperf deleted file mode 100644 index 8672d6c25ed..00000000000 --- a/apps/gperf/tests/c.gperf +++ /dev/null @@ -1,32 +0,0 @@ -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/apps/gperf/tests/corba.exp b/apps/gperf/tests/corba.exp deleted file mode 100644 index 4dac28e4a79..00000000000 --- a/apps/gperf/tests/corba.exp +++ /dev/null @@ -1,36 +0,0 @@ -in word set any -in word set module -in word set raises -in word set readonly -in word set attribute -in word set exception -in word set context -in word set interface -in word set const -in word set typedef -in word set struct -in word set enum -in word set string -in word set wstring -in word set sequence -in word set union -in word set switch -in word set case -in word set default -in word set float -in word set double -in word set long -in word set short -in word set unsigned -in word set char -in word set wchar -in word set boolean -in word set octet -in word set void -in word set native -in word set TRUE -in word set FALSE -in word set inout -in word set in -in word set out -in word set oneway diff --git a/apps/gperf/tests/corba.gperf b/apps/gperf/tests/corba.gperf deleted file mode 100644 index d9e4377492d..00000000000 --- a/apps/gperf/tests/corba.gperf +++ /dev/null @@ -1,36 +0,0 @@ -any -module -raises -readonly -attribute -exception -context -interface -const -typedef -struct -enum -string -wstring -sequence -union -switch -case -default -float -double -long -short -unsigned -char -wchar -boolean -octet -void -native -TRUE -FALSE -inout -in -out -oneway diff --git a/apps/gperf/tests/gpc.gperf b/apps/gperf/tests/gpc.gperf deleted file mode 100644 index 8fb469e46bc..00000000000 --- a/apps/gperf/tests/gpc.gperf +++ /dev/null @@ -1,48 +0,0 @@ -%{ -/* 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/apps/gperf/tests/gplus.gperf b/apps/gperf/tests/gplus.gperf deleted file mode 100644 index 2a2e37f9b26..00000000000 --- a/apps/gperf/tests/gplus.gperf +++ /dev/null @@ -1,76 +0,0 @@ -%{ -/* Command-line: gperf -p -j1 -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/apps/gperf/tests/idl.exp b/apps/gperf/tests/idl.exp deleted file mode 100644 index ce29fd044c0..00000000000 --- a/apps/gperf/tests/idl.exp +++ /dev/null @@ -1,9 +0,0 @@ -in word set set -in word set _is_a -in word set destroy -in word set get -in word set _get_width -in word set _set_width -in word set _get_height -in word set _set_height -in word set _non_existent diff --git a/apps/gperf/tests/idl.gperf b/apps/gperf/tests/idl.gperf deleted file mode 100644 index cbce5603da8..00000000000 --- a/apps/gperf/tests/idl.gperf +++ /dev/null @@ -1,9 +0,0 @@ -set -_is_a -destroy -get -_get_width -_set_width -_get_height -_set_height -_non_existent diff --git a/apps/gperf/tests/irc.gperf b/apps/gperf/tests/irc.gperf deleted file mode 100644 index afe53c59e7d..00000000000 --- a/apps/gperf/tests/irc.gperf +++ /dev/null @@ -1,63 +0,0 @@ -%{ -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/apps/gperf/tests/makeinfo.gperf b/apps/gperf/tests/makeinfo.gperf deleted file mode 100644 index 1488b8e38fb..00000000000 --- a/apps/gperf/tests/makeinfo.gperf +++ /dev/null @@ -1,116 +0,0 @@ -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/apps/gperf/tests/modula.exp b/apps/gperf/tests/modula.exp deleted file mode 100644 index cef7d5acad8..00000000000 --- a/apps/gperf/tests/modula.exp +++ /dev/null @@ -1,106 +0,0 @@ -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/apps/gperf/tests/modula2.gperf b/apps/gperf/tests/modula2.gperf deleted file mode 100644 index 5ef9c753835..00000000000 --- a/apps/gperf/tests/modula2.gperf +++ /dev/null @@ -1,40 +0,0 @@ -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/apps/gperf/tests/modula3.gperf b/apps/gperf/tests/modula3.gperf deleted file mode 100644 index d0243460d9b..00000000000 --- a/apps/gperf/tests/modula3.gperf +++ /dev/null @@ -1,106 +0,0 @@ -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/apps/gperf/tests/pascal.exp b/apps/gperf/tests/pascal.exp deleted file mode 100644 index 765e44c6a0f..00000000000 --- a/apps/gperf/tests/pascal.exp +++ /dev/null @@ -1,36 +0,0 @@ -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/apps/gperf/tests/pascal.gperf b/apps/gperf/tests/pascal.gperf deleted file mode 100644 index fed3fbb30ea..00000000000 --- a/apps/gperf/tests/pascal.gperf +++ /dev/null @@ -1,36 +0,0 @@ -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/apps/gperf/tests/test-1.exp b/apps/gperf/tests/test-1.exp deleted file mode 100644 index ec19bd7dd3c..00000000000 --- a/apps/gperf/tests/test-1.exp +++ /dev/null @@ -1,135 +0,0 @@ -/* C code produced by gperf version 2.7 (GNU C++ version) */ -/* Command-line: ../src/gperf -p -j1 -o -t -N is_reserved_word -k1,3,$ */ -/* Command-line: gperf -p -j1 -i 1 -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */ -#include <string.h> -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 -#define HASH_VALUE_RANGE 75 -#define DUPLICATES 0 - -static unsigned int -hash (str, len) - char *str; - 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, - }; - unsigned int hval = len; - - switch (hval) - { - default: - case 3: - hval += asso_values[str[2]]; - case 2: - case 1: - hval += asso_values[str[0]]; - } - return hval + asso_values[str[len - 1]]; -} - -struct resword * -is_reserved_word (str, len) - char *str; - 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) - { - unsigned int key = hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) - { - char *s = wordlist[key].name; - - if (*str == *s && !strcmp (str + 1, s + 1)) - return &wordlist[key]; - } - } - return 0; -} diff --git a/apps/gperf/tests/test-2.exp b/apps/gperf/tests/test-2.exp deleted file mode 100644 index 6533162bce4..00000000000 --- a/apps/gperf/tests/test-2.exp +++ /dev/null @@ -1,184 +0,0 @@ -/* C code produced by gperf version 2.7 (GNU C++ version) */ -/* Command-line: ../src/gperf -n -k1-8 -l */ -#include <string.h> - -#define TOTAL_KEYWORDS 40 -#define MIN_WORD_LENGTH 2 -#define MAX_WORD_LENGTH 14 -#define MIN_HASH_VALUE 1 -#define MAX_HASH_VALUE 256 -#define HASH_VALUE_RANGE 256 -#define DUPLICATES 0 - -static unsigned int -hash (str, len) - char *str; - 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, - }; - unsigned int hval = 0; - - switch (len) - { - default: - case 8: - hval += asso_values[str[7]]; - case 7: - hval += asso_values[str[6]]; - case 6: - hval += asso_values[str[5]]; - case 5: - hval += asso_values[str[4]]; - case 4: - hval += asso_values[str[3]]; - case 3: - hval += asso_values[str[2]]; - case 2: - hval += asso_values[str[1]]; - case 1: - hval += asso_values[str[0]]; - } - return hval; -} - -char * -in_word_set (str, len) - char *str; - 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 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) - { - unsigned int key = hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) - { - char *s = wordlist[key]; - - if (len == lengthtable[key] - && *str == *s && !strcmp (str + 1, s + 1)) - return s; - } - } - return 0; -} diff --git a/apps/gperf/tests/test-3.exp b/apps/gperf/tests/test-3.exp deleted file mode 100644 index 85ce4665dc1..00000000000 --- a/apps/gperf/tests/test-3.exp +++ /dev/null @@ -1,166 +0,0 @@ -/* C code produced by gperf version 2.7 (GNU C++ version) */ -/* Command-line: ../src/gperf -p -j 1 -o -a -C -g -t -k1,4,$ */ -/* Command-line: gperf -p -j1 -o -t -N is_reserved_word -k1,4,$ gplus.gperf */ -#include <string.h> -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 -#define HASH_VALUE_RANGE 144 -#define DUPLICATES 0 - -inline -static unsigned int -hash (const char *str, 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, - }; - unsigned int hval = len; - - switch (hval) - { - default: - case 4: - hval += asso_values[str[3]]; - case 3: - case 2: - case 1: - hval += asso_values[str[0]]; - } - return hval + asso_values[str[len - 1]]; -} - -inline -const struct resword * -in_word_set (const char *str, 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) - { - unsigned int key = hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) - { - const char *s = wordlist[key].name; - - if (*str == *s && !strcmp (str + 1, s + 1)) - return &wordlist[key]; - } - } - return 0; -} diff --git a/apps/gperf/tests/test-4.exp b/apps/gperf/tests/test-4.exp deleted file mode 100644 index 70fec863b59..00000000000 --- a/apps/gperf/tests/test-4.exp +++ /dev/null @@ -1,140 +0,0 @@ -/* C code produced by gperf version 2.7 (GNU C++ version) */ -/* Command-line: ../src/gperf -D -p -t */ -/* Command-line: gperf -p -j1 -i 1 -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */ -#include <string.h> -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 -#define HASH_VALUE_RANGE 79 -#define DUPLICATES 3 - -static unsigned int -hash (str, len) - char *str; - 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, - }; - return len + asso_values[str[len - 1]] + asso_values[str[0]]; -} - -struct resword * -in_word_set (str, len) - char *str; - 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 signed char lookup[] = - { - -1, -1, -9, -3, 4, 5, 6, 7, -1, 8, -90, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, -1, 23, 24, 25, -1, 26, - -1, -1, 27, 28, -1, 29, 30, -1, 31, -1, 32, 33, -1, 34, - 35, 36, 37, 38, 39, 40, 41, -1, -1, 42, -1, 43, -1, -1, - 44, -1, -1, -1, -1, 45, -1, 46, 47, 48, 49, -1, 50, -1, - -1, -1, -1, 51, 52, -1, -1, -1, -1, -1, 53, -1, 54, - }; - - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - unsigned int key = hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) - { - int index = lookup[key]; - - if (index >= 0 && index < MAX_HASH_VALUE) - { - char *s = wordlist[index].name; - - if (*str == *s && !strcmp (str + 1, s + 1)) - return &wordlist[index]; - } - else if (index < 0 && index >= -MAX_HASH_VALUE) - return 0; - else - { - unsigned int offset = key + index + (index > 0 ? -MAX_HASH_VALUE : MAX_HASH_VALUE); - struct resword *base = &wordlist[-lookup[offset]]; - struct resword *ptr = base + -lookup[offset + 1]; - - while (--ptr >= base) - if (*str == *ptr->name && !strcmp (str + 1, ptr->name + 1)) - return ptr; - } - } - } - return 0; -} diff --git a/apps/gperf/tests/test-5.exp b/apps/gperf/tests/test-5.exp deleted file mode 100644 index c06ae1e988f..00000000000 --- a/apps/gperf/tests/test-5.exp +++ /dev/null @@ -1,109 +0,0 @@ -/* C code produced by gperf version 2.7 (GNU C++ version) */ -/* 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 - * - */ -#include <string.h> -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 -#define HASH_VALUE_RANGE 42 -#define DUPLICATES 0 - -inline -static unsigned int -hash (str, len) - char *str; - 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, - }; - return len + asso_values[str[len - 1]] + asso_values[str[0]]; -} - -inline -struct resword * -is_reserved_word (str, len) - char *str; - 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) - { - unsigned int key = hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) - { - char *s = wordlist[key].name; - - if (*str == *s && !strcmp (str + 1, s + 1)) - return &wordlist[key]; - } - } - return 0; -} diff --git a/apps/gperf/tests/test-6.exp b/apps/gperf/tests/test-6.exp deleted file mode 100644 index d571a77cf7c..00000000000 --- a/apps/gperf/tests/test-6.exp +++ /dev/null @@ -1,84 +0,0 @@ --a Generate ANSI standard C output code, i.e., function prototypes. --b Generate code for Linear Search. --B Generate code for Binary Search. --c Generate comparison code using strncmp rather than strcmp. --C Make the contents of generated lookup tables constant, i.e., readonly. --d Enables the debugging option (produces verbose output to the standard error). --D Handle keywords that hash to duplicate values. This is useful - for certain highly redundant keyword sets. --e Allow user to provide a string containing delimiters used to separate - keywords from their attributes. Default is ",\n" --E Define constant values using an enum local to the lookup function - rather than with defines --f 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.'' --g Make generated routines use ``inline'' to remove function overhead. --G 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). --h Prints this mesage. --H Allow user to specify name of generated hash function. Default - is `hash'. --i Provide an initial value for the associate values array. Default is 0. --I Generate comparison code using case insensitive string comparison, e.g., - strncasecmp or strcasecmp. - Setting this value larger helps inflate the size of the final table. --j Affects the ``jump value,'' i.e., how far to advance the associated - character value upon collisions. Must be an odd number, default is 5. --J Skips '#include <string.h>' part in the output. --k Allows selection of 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. --K Allow use to select name of the keyword component in the keyword structure. --l Compare key lengths before trying a string comparison. This helps - cut down on the number of string comparisons made during the lookup. --L Generates code in the language specified by the option's argument. Languages - handled are currently C++ and C. The default is C. --m Avoids the warning about identical hash values. This is valid - only if the -D option is enabled. --M Skips class definition in the output. This is valid only in C++ mode. --n Do not include the length of the keyword when computing the hash function --N Allow user to specify name of generated lookup function. Default - name is `in_word_set.' --o Reorders input keys by frequency of occurrence of the key sets. - This should decrease the search time dramatically. --O Optimize the generated lookup function by assuming that all input keywords - are members of the keyset from the keyfile. --p Changes the return value of the generated function ``in_word_set'' - from its default boolean value (i.e., 0 or 1), to type ``pointer - to wordlist array'' This is most useful when the -t option, allowing - user-defined structs, is used. --r Utilizes randomness to initialize the associated values table. --s Affects the size of the generated hash table. The numeric argument - for this option 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. --S 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 argument to - this option 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. This - is useful since many C compilers cannot correctly generate code for - large switch statements. --t Allows the user to include a structured type declaration for - generated code. Any text before %% is consider part of the type - declaration. Key words and additional fields may follow this, one - group of fields per line. --T Prevents the transfer of the type declaration to the output file. - Use this option if the type is already defined elsewhere. --v Prints out the current version number and exits with a value of 0 --V Exits silently with a value of 0. --Z Allow user to specify name of generated C++ class. Default - name is `Perfect_Hash.' -Usage: ../src/gperf [-abBcCdDef[num]gGhH<hashname>i<init>IjJk<keys>K<keyname>lL<language>mMnN<function name>oOprs<size>S<switches>tTvVZ<class name>]. -(type ../src/gperf -h for help) diff --git a/apps/gperf/tests/test-7.exp b/apps/gperf/tests/test-7.exp deleted file mode 100644 index c5c942c10d1..00000000000 --- a/apps/gperf/tests/test-7.exp +++ /dev/null @@ -1,32 +0,0 @@ -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/apps/gperf/tests/test.cpp b/apps/gperf/tests/test.cpp deleted file mode 100644 index c43287836ab..00000000000 --- a/apps/gperf/tests/test.cpp +++ /dev/null @@ -1,33 +0,0 @@ -// $Id: test.cpp 1.1 10/18/96 - -// Tests the generated perfect has function. - -// The -v option prints diagnostics as to whether a word is in the set -// or not. Without -v the program is useful for timing. - -#include "ace/OS.h" - -ACE_RCSID(tests, test, "$Id$") - -static const int MAX_LEN = 80; - -char *in_word_set (const char *str, unsigned int len); - -int -main (int argc, char *argv[]) -{ - int verbose = argc > 1 && ACE_OS::strcmp (argv[1], "-v") == 0 ? 1 : 0; - char buf[MAX_LEN]; - - while (ACE_OS::fgets (buf, sizeof buf, stdin) != 0) - { - int len = ACE_OS::strlen (buf) - 1; - buf[len] = '\0'; - if (in_word_set (buf, len) && verbose) - printf ("in word set %s\n", buf); - else if (verbose) - printf ("NOT in word set %s\n", buf); - } - - return 0; -} diff --git a/apps/gperf/texinfo.tex b/apps/gperf/texinfo.tex deleted file mode 100644 index 1701ae10e81..00000000000 --- a/apps/gperf/texinfo.tex +++ /dev/null @@ -1,4977 +0,0 @@ -% texinfo.tex -- TeX macros to handle Texinfo files. -% $Id$ -% -% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98 -% 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.cs.umb.edu/pub/tex/texinfo.tex -% /home/gd/gnu/doc/texinfo.tex on the GNU machines. -% -% Send bug reports to bug-texinfo@gnu.org. -% Please include a precise test case in each bug report, -% including a complete document with which we can reproduce the problem. -% -% Texinfo macros (with @macro) are *not* supported by texinfo.tex. You -% have to run makeinfo -E to expand macros first; the texi2dvi script -% does this. - - -% Make it possible to create a .fmt file just by loading this file: -% if the underlying format is not loaded, start by loading it now. -% Added by gildea November 1993. -\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi - -% This automatically updates the version number based on RCS. -\def\deftexinfoversion$#1: #2 ${\def\texinfoversion{#2}} -\deftexinfoversion$Revision$ -\message{Loading texinfo package [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]}\message{} - \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 - -% 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\ } -} - - -\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. -\ifx\putwordChapter\undefined{\gdef\putwordChapter{Chapter}}\fi% -\def\putwordInfo{Info}% -\ifx\putwordSee\undefined{\gdef\putwordSee{See}}\fi% -\ifx\putwordsee\undefined{\gdef\putwordsee{see}}\fi% -\ifx\putwordfile\undefined{\gdef\putwordfile{file}}\fi% -\ifx\putwordpage\undefined{\gdef\putwordpage{page}}\fi% -\ifx\putwordsection\undefined{\gdef\putwordsection{section}}\fi% -\ifx\putwordSection\undefined{\gdef\putwordSection{Section}}\fi% -\ifx\putwordTableofContents\undefined{\gdef\putwordTableofContents{Table of Contents}}\fi% -\ifx\putwordShortContents\undefined{\gdef\putwordShortContents{Short Contents}}\fi% -\ifx\putwordAppendix\undefined{\gdef\putwordAppendix{Appendix}}\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}% -\def\loggingall{\tracingcommands2 \tracingstats2 - \tracingpages1 \tracingoutput1 \tracinglostchars1 - \tracingmacros2 \tracingparagraphs1 \tracingrestores1 - \showboxbreadth\maxdimen\showboxdepth\maxdimen -}% - -% 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\cornerlong \newdimen\cornerthick -\newdimen\topandbottommargin -\newdimen\outerhsize \newdimen\outervsize -\cornerlong=1pc\cornerthick=.3pt % These set size of cropmarks -\outerhsize=7in -%\outervsize=9.5in -% Alternative @smallbook page size is 9.25in -\outervsize=9.25in -\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{% - \ifcropmarks \vbox to \outervsize\bgroup - \hsize = \outerhsize - \line{\ewtop\hfil\ewtop}% - \nointerlineskip - \line{% - \vbox{\moveleft\cornerthick\nstop}% - \hfill - \vbox{\moveright\cornerthick\nstop}% - }% - \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 - \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. Type 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{Type <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 \char '100}} - -% 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 \char '173}} -\def\myrbrace {{\tt \char '175}} -\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 -} - -% @: 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\penalty 10000 -%\prevdepth=-1000pt -%}} - -\def\needx#1{% - % Go into vertical mode, so we don't make a big box in the middle of a - % paragraph. - \par - % - % Don't add any leading before our big empty box, but allow a page - % break, since the best break might be right here. - \allowbreak - \nointerlineskip - \vtop to #1\mil{\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 -} - -% @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{\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{% - \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{\catcode 64=\other \catcode 123=\other \catcode 125=\other% -\parsearg \commentxxx} - -\def\commentxxx #1{\catcode 64=0 \catcode 123=1 \catcode 125=2 } - -\let\c=\comment - -% @paragraphindent is defined for the Info formatting commands only. -\let\paragraphindent=\comment - -% 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\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}} - -% Also ignore @macro ... @end macro. The user must run texi2dvi, -% which runs makeinfo to do macro expansion. Ignore @unmacro, too. -\def\macro{\doignore{macro}} -\let\unmacro = \comment - - -% @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'. - \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 - % - % 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.ai.mit.edu/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\indrm = \nullfont \let\indit = \nullfont \let\indsl = \nullfont - \let\indbf = \nullfont \let\indtt = \nullfont \let\indsc = \nullfont - \let\indsf = \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}}% -} - -% @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. -% -\def\value{\begingroup - \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. - \valuexxx} -\def\valuexxx#1{% - \expandafter\ifx\csname SET#1\endcsname\relax - {\{No value for ``#1''\}}% - \else - \csname SET#1\endcsname - \fi -\endgroup} - -% @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} - -% @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} - -\def\node{\ENVcheck\parsearg\nodezzz} -\def\nodezzz#1{\nodexxx [#1,]} -\def\nodexxx[#1,#2]{\gdef\lastnode{#1}} -\let\nwnode=\node -\let\lastnode=\relax - -\def\donoderef{\ifx\lastnode\relax\else -\expandafter\expandafter\expandafter\setref{\lastnode}\fi -\global\let\lastnode=\relax} - -\def\unnumbnoderef{\ifx\lastnode\relax\else -\expandafter\expandafter\expandafter\unnumbsetref{\lastnode}\fi -\global\let\lastnode=\relax} - -\def\appendixnoderef{\ifx\lastnode\relax\else -\expandafter\expandafter\expandafter\appendixsetref{\lastnode}\fi -\global\let\lastnode=\relax} - -% @refill is a no-op. -\let\refill=\relax - -% @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{% - \readauxfile - \opencontents - \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. -} - -% @bye. -\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} - -% \def\macro#1{\begingroup\ignoresections\catcode`\#=6\def\macrotemp{#1}\parsearg\macroxxx} -% \def\macroxxx#1#2 \end macro{% -% \expandafter\gdef\macrotemp#1{#2}% -% \endgroup} - -%\def\linemacro#1{\begingroup\ignoresections\catcode`\#=6\def\macrotemp{#1}\parsearg\linemacroxxx} -%\def\linemacroxxx#1#2 \end linemacro{% -%\let\parsearg=\relax -%\edef\macrotempx{\csname M\butfirst\expandafter\string\macrotemp\endcsname}% -%\expandafter\xdef\macrotemp{\parsearg\macrotempx}% -%\expandafter\gdef\macrotempx#1{#2}% -%\endgroup} - -%\def\butfirst#1{} - - -\message{fonts,} - -% Font-change commands. - -% Texinfo 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 and small examples (9pt). -% We actually use the slanted font rather than the italic, -% because texinfo normally uses the slanted fonts for that. -% Do not make many font distinctions in general in the index, since they -% aren't very useful. -\setfont\ninett\ttshape{9}{1000} -\setfont\indrm\rmshape{9}{1000} -\setfont\indit\slshape{9}{1000} -\let\indsl=\indit -\let\indtt=\ninett -\let\indttsl=\ninett -\let\indsf=\indrm -\let\indbf=\indrm -\setfont\indsc\scshape{10}{900} -\font\indi=cmmi9 -\font\indsy=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\indexfonts{% - \let\tenrm=\indrm \let\tenit=\indit \let\tensl=\indsl - \let\tenbf=\indbf \let\tentt=\indtt \let\smallcaps=\indsc - \let\tensf=\indsf \let\teni=\indi \let\tensy=\indsy \let\tenttsl=\indttsl - \resetmathfonts \setleading{12pt}} - -% 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\smartitalic#1{{\sl #1}\futurelet\next\smartitalicx} - -\let\i=\smartitalic -\let\var=\smartitalic -\let\dfn=\smartitalic -\let\emph=\smartitalic -\let\cite=\smartitalic - -\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\smallrm\rmshape{8}{1000} -\font\smallsy=cmsy9 -\def\key#1{{\smallrm\textfont2=\smallsy \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} - -\let\file=\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 -\catcode`\|=\active -\global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex} -% The following is used by \doprintindex to insure that long function names -% wrap around. It is necessary for - and _ to be active before the index is -% read from the file, as \entry parses the arguments long before \code is -% ever called. -- mycroft -% _ is always active; and it shouldn't be \let = to an _ that is a -% subscript character anyway. Then, @cindex @samp{_} (for example) -% fails. --karl -\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} - -% @url. Quotes do not seem necessary, so use \code. -\let\url=\code - -% @uref (abbreviation for `urlref') takes an optional second argument -% specifying the text to display. First (mandatory) arg is the url. -% Perhaps eventually put in a hypertex \special here. -% -\def\uref#1{\urefxxx #1,,\finish} -\def\urefxxx#1,#2,#3\finish{% - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0 > 0pt - \unhbox0\ (\code{#1})% - \else - \code{#1}% - \fi -} - -% rms does not like the angle brackets --karl, 17may97. -% So now @email is just like @uref. -%\def\email#1{\angleleft{\tt #1}\angleright} -\let\email=\uref - -% 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} - -\def\r#1{{\rm #1}} % roman font -% Use of \lowercase was suggested. -\def\sc#1{{\smallcaps#1}} % smallcaps font -\def\ii#1{{\it #1}} % italic font - -% @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 - -\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 -% I deinstalled the following change because \cmr12 is undefined. -% This change was not in the ChangeLog anyway. --rms. -% \let\subtitlerm=\cmr12 - \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 - \HEADINGSon -} - -\def\finishtitlepage{% - \vskip4pt \hrule height 2pt width \hsize - \vskip\titlepagebottomglue - \finishedtitlepagetrue -} - -%%% Set up page headings and footings. - -\let\thispage=\folio - -\newtoks \evenheadline % Token sequence for heading line of even pages -\newtoks \oddheadline % Token sequence for heading line of odd pages -\newtoks \evenfootline % Token sequence for footing line of even pages -\newtoks \oddfootline % Token sequence for footing line of 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 -% Produces Day Month Year style of output. -\def\today{\number\day\space -\ifcase\month\or -January\or February\or March\or April\or May\or June\or -July\or August\or September\or October\or November\or December\fi -\space\number\year} - -% Use this if you want the Month Day, Year style of output. -%\def\today{\ifcase\month\or -%January\or February\or March\or April\or May\or June\or -%July\or August\or September\or October\or November\or December\fi -%\space\number\day, \number\year} - -% @settitle line... specifies the title of the document, for headings -% It generates no output of its own - -\def\thistitle{No Title} -\def\settitle{\parsearg\settitlezzz} -\def\settitlezzz #1{\gdef\thistitle{#1}} - - -\message{tables,} - -% @tabs -- simple alignment - -% These don't work. For one thing, \+ is defined as outer. -% So these macros cannot even be defined. - -%\def\tabs{\parsearg\tabszzz} -%\def\tabszzz #1{\settabs\+#1\cr} -%\def\tabline{\parsearg\tablinezzz} -%\def\tablinezzz #1{\+#1\cr} -%\def\&{&} - -% 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. - % - % Be sure we are not still in the middle of a paragraph. - %{\parskip = 0in - %\par - %}% - % - % 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. Since that - % text will be indented by \tableindent, we make the item text be in - % a zero-width box. - \noindent - \rlap{\hskip -\tableindent\box0}\ignorespaces% - \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}{}{}{}{}} - -\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 itemsize - \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 - -% 2/1/96, to allow fractions to be given with more than one digit. -\def\pickupwholefraction#1 {\global\advance\colcount by1 % -\expandafter\xdef\csname col\the\colcount\endcsname{.#1\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 % In this case arg of setuptable - % is the decimal point before the - % number given in percent of hsize. - % We don't need this so we don't use it. - \else - \global\advance\colcount by1 - \setbox0=\hbox{#1 }% 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\else\let\go\setuptable\fi% -\fi\go} - -% multitable syntax -\def\tab{&\hskip1sp\relax} % 2/2/96 - % tiny skip here makes sure this column space is - % maintained, even if it is never used. - -% @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 -%% strut to put in table in case some entry doesn't have descenders, -%% to keep lines equally spaced -\let\multistrut = \strut -%% 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. -\else -\gdef\multistrut{\vrule height\multitablelinespace depth\dp0 -width0pt\relax} \fi -\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{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{ -\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file -\openout \csname#1indfile\endcsname \jobname.#1 % Open the file -\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex -\noexpand\doindex {#1}} -} - -% @defindex foo == \newindex{foo} - -\def\defindex{\parsearg\newindex} - -% Define @defcodeindex, like @defindex except put all entries in @code. - -\def\newcodeindex #1{ -\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file -\openout \csname#1indfile\endcsname \jobname.#1 % Open the file -\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex -\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. -\def\synindex #1 #2 {% -\expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\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\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{% -% 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. -%\let\{ = \lbracecmd -%\let\} = \rbracecmd -\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\char{\realbackslash char}% -\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\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\value##1{\realbackslash value {##1}}% -\unsepspaces -} - -% 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\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 %initialize! -% workhorse for all \fooindexes -% #1 is name of index, #2 is stuff to put there -\def\doind #1#2{% - % 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. - % - % First process the index-string with all font commands turned off - % to get the string to sort by. - {\indexnofonts \xdef\indexsorttmp{#2}}% - % - % Now produce the complete index entry, with both the sort key and the - % original text, including any font commands. - \toks0 = {#2}% - \edef\temp{% - \write\csname#1indfile\endcsname{% - \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}% - }% - \temp - }% - }% - \penalty\count255 - }% -} - -\def\dosubind #1#2#3{% -{\count10=\lastpenalty % -{\indexdummies % Must do this here, since \bf, etc expand at this stage -\escapechar=`\\% -{\let\folio=0% -\def\rawbackslashxx{\indexbackslash}% -% -% Now process the index-string once, with all font commands turned off, -% to get the string to sort the index by. -{\indexnofonts -\xdef\temp1{#2 #3}% -}% -% Now produce the complete index entry. We process the index-string again, -% this time with font commands expanded, to get what to print in the index. -\edef\temp{% -\write \csname#1indfile\endcsname{% -\realbackslash entry {\temp1}{\folio}{#2}{#3}}}% -\temp }% -}\penalty\count10}} - -% 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}% - % - \indexfonts \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. - (Index is nonexistent) - \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 - (Index is empty) - \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. - -% Same as \bigskipamount except no shrink. -% \balancecolumns gets confused if there is any shrink. -\newskip\initialskipamount \initialskipamount 12pt plus4pt - -\def\initial #1{% -{\let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt -\ifdim\lastskip<\initialskipamount -\removelastskip \penalty-200 \vskip \initialskipamount\fi -\line{\secbf#1\hfill}\kern 2pt\penalty10000}} - -% 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 - % - % 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. - \ #2% The page number ends the paragraph. - \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 = {\global\setbox\partialpage = \vbox{% - % - % 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 must prevent the second \partialpage from - % simply overwriting the first, causing us to lose the page. - % This will preserve it until a real output routine can ship it - % out. Generally, \partialpage will be empty when this runs and - % this will be a no-op. - \unvbox\partialpage - % - % Unvbox the main output page. - \unvbox255 - \kern-\topskip \kern\baselineskip - }}% - \eject - % - % 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.) - \vsize = 2\vsize -} -\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@=\pageheight \advance\dimen@ by-\ht\partialpage - % 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. - \unvbox\partialpage - \hsize = \doublecolumnhsize - \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}% -} -\def\enddoublecolumns{% - \output = {\balancecolumns}\eject % split what we have - \endgroup % started in \begindoublecolumns - % - % Back to normal single-column typesetting, but take account of the - % fact that we just accumulated some stuff on the output page. - \pagegoal = \vsize -} -\def\balancecolumns{% - % Called at the end of the double column material. - \setbox0 = \vbox{\unvbox255}% - \dimen@ = \ht0 - \advance\dimen@ by \topskip - \advance\dimen@ by-\baselineskip - \divide\dimen@ by 2 - \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@ by1pt - \repeat}% - \setbox0=\vbox to\dimen@{\unvbox1}% - \setbox2=\vbox to\dimen@{\unvbox3}% - \pagesofar -} -\catcode`\@ = \other - - -\message{sectioning,} -% Define 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} - -\newwrite\contentsfile -% This is called from \setfilename. -\def\opencontents{\openout\contentsfile = \jobname.toc } - -% Each @chapter defines this as the name of the chapter. -% page headings and footings can use it. @section does likewise - -\def\thischapter{} \def\thissection{} -\def\seccheck#1{\ifnum \pageno<0 - \errmessage{@#1 not allowed after generating table of contents}% -\fi} - -\def\chapternofonts{% - \let\rawbackslash=\relax - \let\frenchspacing=\relax - \def\result{\realbackslash result}% - \def\equiv{\realbackslash equiv}% - \def\expansion{\realbackslash expansion}% - \def\print{\realbackslash print}% - \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\tt{\realbackslash tt}% - \def\bf{\realbackslash bf}% - \def\w{\realbackslash w}% - \def\less{\realbackslash less}% - \def\gtr{\realbackslash gtr}% - \def\hat{\realbackslash hat}% - \def\char{\realbackslash char}% - \def\tclose##1{\realbackslash tclose{##1}}% - \def\code##1{\realbackslash code{##1}}% - \def\samp##1{\realbackslash samp{##1}}% - \def\r##1{\realbackslash r{##1}}% - \def\b##1{\realbackslash b{##1}}% - \def\key##1{\realbackslash key{##1}}% - \def\file##1{\realbackslash file{##1}}% - \def\kbd##1{\realbackslash kbd{##1}}% - % These are redefined because @smartitalic wouldn't work inside xdef. - \def\i##1{\realbackslash i{##1}}% - \def\cite##1{\realbackslash cite{##1}}% - \def\var##1{\realbackslash var{##1}}% - \def\emph##1{\realbackslash emph{##1}}% - \def\dfn##1{\realbackslash dfn{##1}}% -} - -\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 -} - - -\def\thischaptername{No Chapter Title} -\outer\def\chapter{\parsearg\chapteryyy} -\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz -\def\chapterzzz #1{\seccheck{chapter}% -\secno=0 \subsecno=0 \subsubsecno=0 -\global\advance \chapno by 1 \message{\putwordChapter \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}% -{\chapternofonts% -\toks0 = {#1}% -\edef\temp{{\realbackslash chapentry{\the\toks0}{\the\chapno}{\noexpand\folio}}}% -\escapechar=`\\% -\write \contentsfile \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{\seccheck{appendix}% -\secno=0 \subsecno=0 \subsubsecno=0 -\global\advance \appendixno by 1 \message{Appendix \appendixletter}% -\chapmacro {#1}{\putwordAppendix{} \appendixletter}% -\gdef\thissection{#1}% -\gdef\thischaptername{#1}% -\xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% -{\chapternofonts% -\toks0 = {#1}% -\edef\temp{{\realbackslash chapentry{\the\toks0}% - {\putwordAppendix{} \appendixletter}{\noexpand\folio}}}% -\escapechar=`\\% -\write \contentsfile \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}}} - -\outer\def\top{\parsearg\unnumberedyyy} -\outer\def\unnumbered{\parsearg\unnumberedyyy} -\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz -\def\unnumberedzzz #1{\seccheck{unnumbered}% -\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 the <toks register>. -\toks0 = {#1}\message{(\the\toks0)}% -% -\unnumbchapmacro {#1}% -\gdef\thischapter{#1}\gdef\thissection{#1}% -{\chapternofonts% -\toks0 = {#1}% -\edef\temp{{\realbackslash unnumbchapentry{\the\toks0}{\noexpand\folio}}}% -\escapechar=`\\% -\write \contentsfile \temp % -\unnumbnoderef % -\global\let\section = \unnumberedsec -\global\let\subsection = \unnumberedsubsec -\global\let\subsubsection = \unnumberedsubsubsec -}} - -\outer\def\numberedsec{\parsearg\secyyy} -\def\secyyy #1{\numhead1{#1}} % normally calls seczzz -\def\seczzz #1{\seccheck{section}% -\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % -\gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% -{\chapternofonts% -\toks0 = {#1}% -\edef\temp{{\realbackslash secentry % -{\the\toks0}{\the\chapno}{\the\secno}{\noexpand\folio}}}% -\escapechar=`\\% -\write \contentsfile \temp % -\donoderef % -\penalty 10000 % -}} - -\outer\def\appendixsection{\parsearg\appendixsecyyy} -\outer\def\appendixsec{\parsearg\appendixsecyyy} -\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz -\def\appendixsectionzzz #1{\seccheck{appendixsection}% -\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % -\gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% -{\chapternofonts% -\toks0 = {#1}% -\edef\temp{{\realbackslash secentry % -{\the\toks0}{\appendixletter}{\the\secno}{\noexpand\folio}}}% -\escapechar=`\\% -\write \contentsfile \temp % -\appendixnoderef % -\penalty 10000 % -}} - -\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} -\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz -\def\unnumberedseczzz #1{\seccheck{unnumberedsec}% -\plainsecheading {#1}\gdef\thissection{#1}% -{\chapternofonts% -\toks0 = {#1}% -\edef\temp{{\realbackslash unnumbsecentry{\the\toks0}{\noexpand\folio}}}% -\escapechar=`\\% -\write \contentsfile \temp % -\unnumbnoderef % -\penalty 10000 % -}} - -\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} -\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz -\def\numberedsubseczzz #1{\seccheck{subsection}% -\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % -\subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% -{\chapternofonts% -\toks0 = {#1}% -\edef\temp{{\realbackslash subsecentry % -{\the\toks0}{\the\chapno}{\the\secno}{\the\subsecno}{\noexpand\folio}}}% -\escapechar=`\\% -\write \contentsfile \temp % -\donoderef % -\penalty 10000 % -}} - -\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} -\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz -\def\appendixsubseczzz #1{\seccheck{appendixsubsec}% -\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % -\subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% -{\chapternofonts% -\toks0 = {#1}% -\edef\temp{{\realbackslash subsecentry % -{\the\toks0}{\appendixletter}{\the\secno}{\the\subsecno}{\noexpand\folio}}}% -\escapechar=`\\% -\write \contentsfile \temp % -\appendixnoderef % -\penalty 10000 % -}} - -\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} -\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz -\def\unnumberedsubseczzz #1{\seccheck{unnumberedsubsec}% -\plainsubsecheading {#1}\gdef\thissection{#1}% -{\chapternofonts% -\toks0 = {#1}% -\edef\temp{{\realbackslash unnumbsubsecentry{\the\toks0}{\noexpand\folio}}}% -\escapechar=`\\% -\write \contentsfile \temp % -\unnumbnoderef % -\penalty 10000 % -}} - -\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} -\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz -\def\numberedsubsubseczzz #1{\seccheck{subsubsection}% -\gdef\thissection{#1}\global\advance \subsubsecno by 1 % -\subsubsecheading {#1} - {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% -{\chapternofonts% -\toks0 = {#1}% -\edef\temp{{\realbackslash subsubsecentry{\the\toks0} - {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno} - {\noexpand\folio}}}% -\escapechar=`\\% -\write \contentsfile \temp % -\donoderef % -\penalty 10000 % -}} - -\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} -\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz -\def\appendixsubsubseczzz #1{\seccheck{appendixsubsubsec}% -\gdef\thissection{#1}\global\advance \subsubsecno by 1 % -\subsubsecheading {#1} - {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% -{\chapternofonts% -\toks0 = {#1}% -\edef\temp{{\realbackslash subsubsecentry{\the\toks0}% - {\appendixletter} - {\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}% -\escapechar=`\\% -\write \contentsfile \temp % -\appendixnoderef % -\penalty 10000 % -}} - -\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} -\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz -\def\unnumberedsubsubseczzz #1{\seccheck{unnumberedsubsubsec}% -\plainsubsubsecheading {#1}\gdef\thissection{#1}% -{\chapternofonts% -\toks0 = {#1}% -\edef\temp{{\realbackslash unnumbsubsubsecentry{\the\toks0}{\noexpand\folio}}}% -\escapechar=`\\% -\write \contentsfile \temp % -\unnumbnoderef % -\penalty 10000 % -}} - -% 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\penalty 10000 % -} - -\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\penalty 10000 % -} - -\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 printing,} -% Finish up the main text and prepare to read what we've written -% to \contentsfile. - -\newskip\contentsrightmargin \contentsrightmargin=1in -\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 \contentsfile - \ifnum \pageno>0 - \pageno = -1 % Request roman numbered pages. - \fi - % Don't need to put `Contents' or `Short Contents' in the headline. - % It is abundantly clear what they are. - \unnumbchapmacro{#1}\def\thischapter{}% - \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. -} - - -% Normal (long) toc. -\outer\def\contents{% - \startcontents{\putwordTableofContents}% - \input \jobname.toc - \endgroup - \vfill \eject -} - -% And just the chapters. -\outer\def\summarycontents{% - \startcontents{\putwordShortContents}% - % - \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{} - \input \jobname.toc - \endgroup - \vfill \eject -} -\let\shortcontents = \summarycontents - -% 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{#3}}% -} - -% 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. -\setbox0 = \hbox{\shortcontrm \putwordAppendix } -\newdimen\shortappendixwidth \shortappendixwidth = \wd0 - -\def\shortchaplabel#1{% - % 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{#2}}} - -% 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{#2}}% - \endgroup - \nobreak\vskip .25\baselineskip plus.1\baselineskip -} - -\def\dosecentry#1#2{\begingroup - \secentryfonts \leftskip=\tocindent - \tocentry{#1}{\dopageno{#2}}% -\endgroup} - -\def\dosubsecentry#1#2{\begingroup - \subsecentryfonts \leftskip=2\tocindent - \tocentry{#1}{\dopageno{#2}}% -\endgroup} - -\def\dosubsubsecentry#1#2{\begingroup - \subsubsecentryfonts \leftskip=3\tocindent - \tocentry{#1}{\dopageno{#2}}% -\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,} - -% 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\}=\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: draw rectangle w/rounded corners around argument -\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 18pt % allow for 3pt kerns on either -% side, and for 6pt waste from -% each corner char - \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 -} - -% To ending 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}% - -\def\lisp{\begingroup - \nonfillstart - \let\Elisp = \nonfillfinish - \tt - % Make @kbd do something special, if requested. - \let\kbdfont\kbdexamplefont - \rawbackslash % have \ input char produce \ char from current font - \gobble -} - -% Define the \E... control sequence only if we are inside the -% environment, so the error checking in \end will work. -% -% We must call \lisp last in the definition, since it reads the -% return following the @example (or whatever) command. -% -\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} -\def\smallexample{\begingroup \def\Esmallexample{\nonfillfinish\endgroup}\lisp} -\def\smalllisp{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}\lisp} - -% @smallexample and @smalllisp. This is not used unless the @smallbook -% command is given. Originally contributed by Pavel@xerox. -% -\def\smalllispx{\begingroup - \nonfillstart - \let\Esmalllisp = \nonfillfinish - \let\Esmallexample = \nonfillfinish - % - % Smaller fonts for small examples. - \indexfonts \tt - \rawbackslash % make \ output the \ character from the current font (tt) - \gobble -} - -% This is @display; same as @lisp except use roman font. -% -\def\display{\begingroup - \nonfillstart - \let\Edisplay = \nonfillfinish - \gobble -} - -% This is @format; same as @display except don't narrow margins. -% -\def\format{\begingroup - \let\nonarrowing = t - \nonfillstart - \let\Eformat = \nonfillfinish - \gobble -} - -% @flushleft (same as @format) and @flushright. -% -\def\flushleft{\begingroup - \let\nonarrowing = t - \nonfillstart - \let\Eflushleft = \nonfillfinish - \gobble -} -\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,} -% Define formatter for defuns -% First, 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 } -\def\ampnr{\&} -\def\lbrb{{\bf\char`\[}} -\def\rbrb{{\bf\char`\]}} - -% 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 -\dimen3=\rightskip -\advance\dimen3 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 \advance \hsize by -\dimen3 -\rlap{\rightline{{\rm #2}\hskip \deftypemargin}}}% -% 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 \advance \rightskip by \defbodyindent -\exdentamount=\defbodyindent -\begingroup % -\catcode 61=\active % 61 is `=' -\obeylines\activeparens\spacesplit#3} - -\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 \advance \rightskip by \defbodyindent -\exdentamount=\defbodyindent -\begingroup\obeylines\activeparens\spacesplit{#3{#4}}} - -\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 \advance \rightskip 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 \advance \rightskip 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 \advance \rightskip 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 \advance \rightskip 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. -\hyphenchar\tensl=0 -#1% -\hyphenchar\tensl=45 -\ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% -\interlinepenalty=10000 -\advance\rightskip by 0pt plus 1fil -\endgraf\penalty 10000\vskip -\parskip\penalty 10000% -} - -\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\penalty 10000\vskip -\parskip\penalty 10000% -} - -% 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}{Function}% -\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}{Function}% -\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}{Macro}% -\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}{Special Form}% -\defunargs {#2}\endgroup % -\catcode 61=\other % Turn off change made in \defparsebody -} - -% This definition is run if you use @defunx -% anywhere other than immediately after a @defun or @defunx. - -\def\deffnx #1 {\errmessage{@deffnx in invalid context}} -\def\defunx #1 {\errmessage{@defunx in invalid context}} -\def\defmacx #1 {\errmessage{@defmacx in invalid context}} -\def\defspecx #1 {\errmessage{@defspecx in invalid context}} -\def\deftypefnx #1 {\errmessage{@deftypefnx in invalid context}} -\def\deftypemethodx #1 {\errmessage{@deftypemethodx in invalid context}} -\def\deftypeunx #1 {\errmessage{@deftypeunx in invalid context}} - -% @defmethod, and so on - -% @defop {Funny Method} foo-class frobnicate argument - -\def\defop #1 {\def\defoptype{#1}% -\defopparsebody\Edefop\defopx\defopheader\defoptype} - -\def\defopheader #1#2#3{% -\dosubind {fn}{\code{#2}}{on #1}% Make entry in function index -\begingroup\defname {#2}{\defoptype{} on #1}% -\defunargs {#3}\endgroup % -} - -% @deftypemethod foo-class return-type foo-method args -% -\def\deftypemethod{% - \defmethparsebody\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{% - \deftypefnheaderx{Method on #1}{#2}#3 #4\relax -} - -% @defmethod == @defop Method - -\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} - -\def\defmethodheader #1#2#3{% -\dosubind {fn}{\code{#2}}{on #1}% entry in function index -\begingroup\defname {#2}{Method on #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}}{of #1}% Make entry in var index -\begingroup\defname {#2}{\defcvtype{} of #1}% -\defvarargs {#3}\endgroup % -} - -% @defivar == @defcv {Instance Variable} - -\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} - -\def\defivarheader #1#2#3{% -\dosubind {vr}{\code{#2}}{of #1}% Make entry in var index -\begingroup\defname {#2}{Instance Variable of #1}% -\defvarargs {#3}\endgroup % -} - -% These definitions are run if you use @defmethodx, etc., -% anywhere other than immediately after a @defmethod, etc. - -\def\defopx #1 {\errmessage{@defopx in invalid context}} -\def\defmethodx #1 {\errmessage{@defmethodx in invalid context}} -\def\defcvx #1 {\errmessage{@defcvx in invalid context}} -\def\defivarx #1 {\errmessage{@defivarx in invalid context}} - -% Now @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\penalty 10000\vskip -\parskip\penalty 10000} - -% @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}{Variable}% -\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}{User Option}% -\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}{Variable}% -\interlinepenalty=10000 -\endgraf\penalty 10000\vskip -\parskip\penalty 10000 -\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\penalty 10000\vskip -\parskip\penalty 10000 -\endgroup} - -% This definition is run if you use @defvarx -% anywhere other than immediately after a @defvar or @defvarx. - -\def\defvrx #1 {\errmessage{@defvrx in invalid context}} -\def\defvarx #1 {\errmessage{@defvarx in invalid context}} -\def\defoptx #1 {\errmessage{@defoptx in invalid context}} -\def\deftypevarx #1 {\errmessage{@deftypevarx in invalid context}} -\def\deftypevrx #1 {\errmessage{@deftypevrx in invalid context}} - -% 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} - -% This definition is run if you use @deftpx, etc -% anywhere other than immediately after a @deftp, etc. - -\def\deftpx #1 {\errmessage{@deftpx in invalid context}} - - -\message{cross reference,} -% Define cross-reference macros -\newwrite \auxfile - -\newif\ifhavexrefs % True if xref values are known. -\newif\ifwarnedxrefs % True if we warned once that they aren't known. - -% @inforef is simple. -\def\inforef #1{\inforefzzz #1,,,,**} -\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, - node \samp{\ignorespaces#1{}}} - -% \setref{foo} defines a cross-reference point named foo. - -\def\setref#1{% -\dosetq{#1-title}{Ytitle}% -\dosetq{#1-pg}{Ypagenumber}% -\dosetq{#1-snt}{Ysectionnumberandtype}} - -\def\unnumbsetref#1{% -\dosetq{#1-title}{Ytitle}% -\dosetq{#1-pg}{Ypagenumber}% -\dosetq{#1-snt}{Ynothing}} - -\def\appendixsetref#1{% -\dosetq{#1-title}{Ytitle}% -\dosetq{#1-pg}{Ypagenumber}% -\dosetq{#1-snt}{Yappendixletterandtype}} - -% \xref, \pxref, and \ref generate cross-references to specified points. -% 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 - \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. - \ifdim \wd1 > 0pt - \putwordsection{} ``\printednodename'' in \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. - {\turnoffactive \refx{#1-snt}{}}% - \space [\printednodename],\space - \turnoffactive \putwordpage\tie\refx{#1-pg}{}% - \fi -\endgroup} - -% \dosetq is the interface for calls from other macros - -% Use \turnoffactive so that punctuation chars such as underscore -% work in node names. -\def\dosetq #1#2{{\let\folio=0 \turnoffactive -\edef\next{\write\auxfile{\internalsetq {#1}{#2}}}% -\next}} - -% \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 - \ifhavexrefs - \message{\linenumber Undefined cross reference `#1'.}% - \else - \ifwarnedxrefs\else - \global\warnedxrefstrue - \message{Cross reference values unknown; you must run TeX again.}% - \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 - % `\+ does not work, so use 43. - \catcode43=\other - % 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 - % - % 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\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 - \def\epsfannounce{\toks0 = }% do not bother showing banner - \input epsf.tex -\fi -% -\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://ftp.tug.org/tex/epsf.tex.} -% -% Only complain once about lack of 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{% - % \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 - \epsfbox{#1.eps}% -} - -% End of control word definitions. - - -\message{and turning on texinfo input format.} - -\def\openindices{% - \newindex{cp}% - \newcodeindex{fn}% - \newcodeindex{vr}% - \newcodeindex{tp}% - \newcodeindex{ky}% - \newcodeindex{pg}% -} - -% Set some numeric style parameters, for 8.5 x 11 format. - -\hsize = 6in -\hoffset = .25in -\newdimen\defaultparindent \defaultparindent = 15pt -\parindent = \defaultparindent -\parskip 3pt plus 2pt minus 1pt -\setleading{13.2pt} -\advance\topskip by 1.2cm - -\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 - -% 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. This makes it come to about 9pt for the 8.5x11 format. -% -\ifx\emergencystretch\thisisundefined - % Allow us to assign to \emergencystretch anyway. - \def\emergencystretch{\dimen0}% -\else - \emergencystretch = \hsize - \divide\emergencystretch by 45 -\fi - -% Use @smallbook to reset parameters for 7x9.5 format (or else 7x9.25) -\def\smallbook{ - \global\chapheadingskip = 15pt plus 4pt minus 2pt - \global\secheadingskip = 12pt plus 3pt minus 2pt - \global\subsecheadingskip = 9pt plus 2pt minus 2pt - % - \global\lispnarrowing = 0.3in - \setleading{12pt} - \advance\topskip by -1cm - \global\parskip 2pt plus 1pt - \global\hsize = 5in - \global\vsize=7.5in - \global\tolerance=700 - \global\hfuzz=1pt - \global\contentsrightmargin=0pt - \global\deftypemargin=0pt - \global\defbodyindent=.5cm - % - \global\pagewidth=\hsize - \global\pageheight=\vsize - % - \global\let\smalllisp=\smalllispx - \global\let\smallexample=\smalllispx - \global\def\Esmallexample{\Esmalllisp} -} - -% Use @afourpaper to print on European A4 paper. -\def\afourpaper{ -\global\tolerance=700 -\global\hfuzz=1pt -\setleading{12pt} -\global\parskip 15pt plus 1pt - -\global\vsize= 53\baselineskip -\advance\vsize by \topskip -%\global\hsize= 5.85in % A4 wide 10pt -\global\hsize= 6.5in -\global\outerhsize=\hsize -\global\advance\outerhsize by 0.5in -\global\outervsize=\vsize -\global\advance\outervsize by 0.6in - -\global\pagewidth=\hsize -\global\pageheight=\vsize -} - -\bindingoffset=0pt -\normaloffset=\hoffset -\pagewidth=\hsize -\pageheight=\vsize - -% Allow control of the text dimensions. Parameters in order: textheight; -% textwidth; voffset; hoffset; binding offset; topskip. -% All require a dimension; -% header is additional; added length extends the bottom of the page. - -\def\changepagesizes#1#2#3#4#5#6{ - \global\vsize= #1 - \global\topskip= #6 - \advance\vsize by \topskip - \global\voffset= #3 - \global\hsize= #2 - \global\outerhsize=\hsize - \global\advance\outerhsize by 0.5in - \global\outervsize=\vsize - \global\advance\outervsize by 0.6in - \global\pagewidth=\hsize - \global\pageheight=\vsize - \global\normaloffset= #4 - \global\bindingoffset= #5} - -% A specific text layout, 24x15cm overall, intended for A4 paper. Top margin -% 29mm, hence bottom margin 28mm, nominal side margin 3cm. -\def\afourlatex - {\global\tolerance=700 - \global\hfuzz=1pt - \setleading{12pt} - \global\parskip 15pt plus 1pt - \advance\baselineskip by 1.6pt - \changepagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm} - } - -% Use @afourwide to print on European A4 paper in wide format. -\def\afourwide{\afourpaper -\changepagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}{7mm}} - -% 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 -\def\normaldoublequote{"} -\def\normaltilde{~} -\def\normalcaret{^} -\def\normalunderscore{_} -\def\normalverticalbar{|} -\def\normalless{<} -\def\normalgreater{>} -\def\normalplus{+} - -% 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\the\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 \char '042}} -\let"=\activedoublequote -\catcode`\~=\active -\def~{{\tt \char '176}} -\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 \char '174}} -\chardef \less=`\< -\catcode`\<=\active -\def<{{\tt \less}} -\chardef \gtr=`\> -\catcode`\>=\active -\def>{{\tt \gtr}} -\catcode`\+=\active -\def+{{\tt \char 43}} -%\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}} - -% Say @foo, not \foo, in error messages. -\escapechar=`\@ - -% \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} - -@def@normalturnoffactive{@let"=@normaldoublequote -@let\=@normalbackslash -@let~=@normaltilde -@let^=@normalcaret -@let_=@normalunderscore -@let|=@normalverticalbar -@let<=@normalless -@let>=@normalgreater -@let+=@normalplus} - -% 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} - -%% These look ok in all fonts, so just make them not special. The @rm below -%% makes sure that the current font starts out as the newly loaded cmr10 -@catcode`@$=@other @catcode`@%=@other @catcode`@&=@other @catcode`@#=@other - -@textfonts -@rm - -@c Local variables: -@c page-delimiter: "^\\\\message" -@c End: diff --git a/apps/gperf/version.texi b/apps/gperf/version.texi deleted file mode 100644 index ca2c8c88bd3..00000000000 --- a/apps/gperf/version.texi +++ /dev/null @@ -1,3 +0,0 @@ -@set UPDATED 24 November 1998 -@set EDITION 2.0 -@set VERSION 2.0 |