diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
commit | 487ca4806cc046076293cf6cc5fbba0db282bac7 (patch) | |
tree | 847b412ab5158dd7bdd7ed7e5a4cc3fbca94be32 /Build/source/texk/bibtex8/bibtex-3.c | |
parent | a3d3111bfe26b8e5f5bc6049dfb2a4ca2edc7881 (diff) |
texk 1
git-svn-id: svn://tug.org/texlive/trunk@1485 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/bibtex8/bibtex-3.c')
-rw-r--r-- | Build/source/texk/bibtex8/bibtex-3.c | 3377 |
1 files changed, 3377 insertions, 0 deletions
diff --git a/Build/source/texk/bibtex8/bibtex-3.c b/Build/source/texk/bibtex8/bibtex-3.c new file mode 100644 index 00000000000..33c30e8143e --- /dev/null +++ b/Build/source/texk/bibtex8/bibtex-3.c @@ -0,0 +1,3377 @@ +/*- +****************************************************************************** +****************************************************************************** +** +** MODULE +** +** $RCSfile: bibtex-3.c,v $ +** $Revision: 3.71 $ +** $Date: 1996/08/18 20:37:06 $ +** +** DESCRIPTION +** +** A 32-bit implementation of BibTeX v0.99c for MS-DOS, OS/2 2.x, +** Unix and VMS. This C language implementation is based on the +** original WEB source but it has been enhanced to support 8-bit input +** characters and a very large processing capacity. +** +** For documentation describing how to use and build this program, +** see the 00README.TXT file that accompanies this distribution. +** +** MODULE CONTENTS +** +** This is the third of 4 source modules for BibTeX. The source has +** been split into 4 parts so that some of the more primitive editors +** can cope. This code mimics the BibTeX WEB source as closely as +** possible and there should be NO system dependent code in any of the +** bibtex-#.c modules. +** +** The functions defined in this module are: +** +** pre_def_certain_strings +** pre_define +** print_lit +** print_missing_entry +** print_overflow +** print_recursion_illegal +** print_skipping_whatever_remains +** print_stk_lit +** print_wrong_stk_lit +** push_lit_stk +** quick_sort +** sam_too_long_file_name_print +** sam_wrong_file_name_print +** scan1 +** scan1_white +** scan2 +** scan2_white +** scan3 +** scan_a_field_token_and_eat_whit +** scan_alpha +** scan_and_store_the_field_value +** scan_balanced_braces +** str_eq_buf +** str_eq_str +** str_lookup +** swap +** trace_and_stat_printing +** trace_pr_fn_class +** unknwn_function_class_confusion +** unknwn_literal_confusion +** upper_case +** von_name_ends_and_last_name_sta +** von_token_found +** x_add_period +** +** AUTHORS +** +** Original WEB translation to C, conversion to "big" (32-bit) capacity, +** addition of run-time selectable capacity and 8-bit support extensions +** by: +** +** Niel Kempson +** Snowy Owl Systems Limited, Cheltenham, England +** E-mail: kempson@snowyowl.co.uk +** +** 8-bit support extensions also by: +** +** Alejandro Aguilar-Sierra +** Centro de Ciencias de la Atm\'osfera, +** Universidad Nacional Aut\'onoma de M\'exico, M\'exico +** E-mail: asierra@servidor.unam.mx +** +** COPYRIGHT +** +** This implementation copyright (c) 1991-1995 by Niel Kempson +** and copyright (c) 1995 by Alejandro Aguilar-Sierra. +** +** 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. +** +** 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! +** +** ACKNOWLEDGEMENT +** +** The original BibTeX was written by Oren Patashnik using Donald +** Knuth's WEB system. This format produces a PASCAL program for +** execution and a TeX documented version of the source code. This +** program started as a (manual) translation of the WEB source into C. +** +** CHANGE LOG +** +** $Log: bibtex-3.c,v $ +** Revision 3.71 1996/08/18 20:37:06 kempson +** Official release 3.71 (see HISTORY file for details). +** +** Revision 3.70 1996/04/08 10:08:40 kempson +** Final documentation & cosmetic changes for official release 3.70. +** +** Revision 3.6 1995/10/21 22:19:33 kempson +** Removed previous WEB-imposed limit on the maximum value of Hash_Prime. +** +** Revision 3.5 1995/09/24 20:44:37 kempson +** Many changes for final beta test version. +** +** Revision 3.4 1995/04/09 22:15:40 kempson +** Placed under RCS control +** +****************************************************************************** +****************************************************************************** +*/ +static char *rcsid = "$Id: bibtex-3.c,v 3.71 1996/08/18 20:37:06 kempson Exp $"; + +#include "sysdep.h" +#include "bibtex.h" +#include "datatype.h" +#include "gblprocs.h" +#include "gblvars.h" +#include "utils.h" +#include "version.h" + + +/*************************************************************************** + * WEB section number: 336 + * ~~~~~~~~~~~~~~~~~~~ + * This is a procedure so that |initialize| is smaller. + ***************************************************************************/ +void pre_def_certain_strings (void) +BEGIN + +/*************************************************************************** + * WEB section number: 75 + * ~~~~~~~~~~~~~~~~~~~ + * It's time to insert some of the pre-defined strings into |str_pool| + * (and thus the hash table). These system-dependent strings should + * contain no upper-case letters, and they must all be exactly + * |longest_pds| characters long (even if fewer characters are actually + * stored). The |pre_define| routine appears shortly. + * + * Important notes: These pre-definitions must not have any glitches or + * the program may bomb because the |log_file| hasn't been opened yet, + * and |text_ilk|s should be pre-defined later, for + * .bst-function-execution purposes. + ***************************************************************************/ + pre_define (".aux ", 4, FILE_EXT_ILK); + s_aux_extension = hash_text[pre_def_loc]; + pre_define (".bbl ", 4, FILE_EXT_ILK); + s_bbl_extension = hash_text[pre_def_loc]; + pre_define (".blg ", 4, FILE_EXT_ILK); + s_log_extension = hash_text[pre_def_loc]; + pre_define (".bst ", 4, FILE_EXT_ILK); + s_bst_extension = hash_text[pre_def_loc]; + pre_define (".bib ", 4, FILE_EXT_ILK); + s_bib_extension = hash_text[pre_def_loc]; + pre_define (" ", 0, FILE_AREA_ILK); + s_bst_area = hash_text[pre_def_loc]; + pre_define (" ", 0, FILE_AREA_ILK); + s_bib_area = hash_text[pre_def_loc]; + +/*************************************************************************** + * WEB section number: 79 + * ~~~~~~~~~~~~~~~~~~~ + * Now we pre-define the command strings; they must all be exactly + * |longest_pds| characters long. + * + * Important note: These pre-definitions must not have any glitches or + * the program may bomb because the |log_file| hasn't been opened yet. + ***************************************************************************/ + pre_define ("\\citation ", 9, AUX_COMMAND_ILK); + ilk_info[pre_def_loc] = N_AUX_CITATION; + pre_define ("\\bibdata ", 8, AUX_COMMAND_ILK); + ilk_info[pre_def_loc] = N_AUX_BIBDATA; + pre_define ("\\bibstyle ", 9, AUX_COMMAND_ILK); + ilk_info[pre_def_loc] = N_AUX_BIBSTYLE; + pre_define ("\\@input ", 7, AUX_COMMAND_ILK); + ilk_info[pre_def_loc] = N_AUX_INPUT; + pre_define ("entry ", 5, BST_COMMAND_ILK); + ilk_info[pre_def_loc] = N_BST_ENTRY; + pre_define ("execute ", 7, BST_COMMAND_ILK); + ilk_info[pre_def_loc] = N_BST_EXECUTE; + pre_define ("function ", 8, BST_COMMAND_ILK); + ilk_info[pre_def_loc] = N_BST_FUNCTION; + pre_define ("integers ", 8, BST_COMMAND_ILK); + ilk_info[pre_def_loc] = N_BST_INTEGERS; + pre_define ("iterate ", 7, BST_COMMAND_ILK); + ilk_info[pre_def_loc] = N_BST_ITERATE; + pre_define ("macro ", 5, BST_COMMAND_ILK); + ilk_info[pre_def_loc] = N_BST_MACRO; + pre_define ("read ", 4, BST_COMMAND_ILK); + ilk_info[pre_def_loc] = N_BST_READ; + pre_define ("reverse ", 7, BST_COMMAND_ILK); + ilk_info[pre_def_loc] = N_BST_REVERSE; + pre_define ("sort ", 4, BST_COMMAND_ILK); + ilk_info[pre_def_loc] = N_BST_SORT; + pre_define ("strings ", 7, BST_COMMAND_ILK); + ilk_info[pre_def_loc] = N_BST_STRINGS; + pre_define ("comment ", 7, BIB_COMMAND_ILK); + ilk_info[pre_def_loc] = N_BIB_COMMENT; + pre_define ("preamble ", 8, BIB_COMMAND_ILK); + ilk_info[pre_def_loc] = N_BIB_PREAMBLE; + pre_define ("string ", 6, BIB_COMMAND_ILK); + ilk_info[pre_def_loc] = N_BIB_STRING; +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 79 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + +/*************************************************************************** + * WEB section number: 334 + * ~~~~~~~~~~~~~~~~~~~ + * It's time for us to insert more pre-defined strings into |str_pool| + * (and thus the hash table) and to insert the |built_in| functions into + * the hash table. The strings corresponding to these functions should + * contain no upper-case letters, and they must all be exactly + * |longest_pds| characters long. The |build_in| routine (to appear + * shortly) does the work. + * + * Important note: These pre-definitions must not have any glitches or the + * program may bomb because the |log_file| hasn't been opened yet. + ***************************************************************************/ + build_in ("= ", 1, &b_equals, N_EQUALS); + build_in ("> ", 1, &b_greater_than, N_GREATER_THAN); + build_in ("< ", 1, &b_less_than, N_LESS_THAN); + build_in ("+ ", 1, &b_plus, N_PLUS); + build_in ("- ", 1, &b_minus, N_MINUS); + build_in ("* ", 1, &b_concatenate, N_CONCATENATE); + build_in (":= ", 2, &b_gets, N_GETS); + build_in ("add.period$ ", 11, &b_add_period, N_ADD_PERIOD); + build_in ("call.type$ ", 10, &b_call_type, N_CALL_TYPE); + build_in ("change.case$", 12, &b_change_case, N_CHANGE_CASE); + build_in ("chr.to.int$ ", 11, &b_chr_to_int, N_CHR_TO_INT); + build_in ("cite$ ", 5, &b_cite, N_CITE); + build_in ("duplicate$ ", 10, &b_duplicate, N_DUPLICATE); + build_in ("empty$ ", 6, &b_empty, N_EMPTY); + build_in ("format.name$", 12, &b_format_name, N_FORMAT_NAME); + build_in ("if$ ", 3, &b_if, N_IF); + build_in ("int.to.chr$ ", 11, &b_int_to_chr, N_INT_TO_CHR); + build_in ("int.to.str$ ", 11, &b_int_to_str, N_INT_TO_STR); + build_in ("missing$ ", 8, &b_missing, N_MISSING); + build_in ("newline$ ", 8, &b_newline, N_NEWLINE); + build_in ("num.names$ ", 10, &b_num_names, N_NUM_NAMES); + build_in ("pop$ ", 4, &b_pop, N_POP); + build_in ("preamble$ ", 9, &b_preamble, N_PREAMBLE); + build_in ("purify$ ", 7, &b_purify, N_PURIFY); + build_in ("quote$ ", 6, &b_quote, N_QUOTE); + build_in ("skip$ ", 5, &b_skip, N_SKIP); + build_in ("stack$ ", 6, &b_stack, N_STACK); + build_in ("substring$ ", 10, &b_substring, N_SUBSTRING); + build_in ("swap$ ", 5, &b_swap, N_SWAP); + build_in ("text.length$", 12, &b_text_length, N_TEXT_LENGTH); + build_in ("text.prefix$", 12, &b_text_prefix, N_TEXT_PREFIX); + build_in ("top$ ", 4, &b_top_stack, N_TOP_STACK); + build_in ("type$ ", 5, &b_type, N_TYPE); + build_in ("warning$ ", 8, &b_warning, N_WARNING); + build_in ("width$ ", 6, &b_width, N_WIDTH); + build_in ("while$ ", 6, &b_while, N_WHILE); + build_in ("width$ ", 6, &b_width, N_WIDTH); + build_in ("write$ ", 6, &b_write, N_WRITE); +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 334 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + +/*************************************************************************** + * WEB section number: 339 + * ~~~~~~~~~~~~~~~~~~~ + * Here we pre-define a few strings used in executing the .bst file: + * the null string, which is sometimes pushed onto the stack; a string + * used for default entry types; and some control sequences used to spot + * foreign characters. We also initialize the |s_preamble| array to + * empty. These pre-defined strings must all be exactly |longest_pds| + * characters long. + * + * Important note: These pre-definitions must not have any glitches or + * the program may bomb because the |log_file| hasn't been opened yet, + * and |text_ilk|s should be pre-defined here, not earlier, for + * .bst-function-execution purposes. + ***************************************************************************/ + pre_define (" ", 0, TEXT_ILK); + s_null = hash_text[pre_def_loc]; + fn_type[pre_def_loc] = STR_LITERAL; + pre_define ("default.type", 12, TEXT_ILK); + s_default = hash_text[pre_def_loc]; + fn_type[pre_def_loc] = STR_LITERAL; + b_default = b_skip; + preamble_ptr = 0; + pre_define ("i ", 1, CONTROL_SEQ_ILK); + ilk_info[pre_def_loc] = N_I; + pre_define ("j ", 1, CONTROL_SEQ_ILK); + ilk_info[pre_def_loc] = N_J; + pre_define ("oe ", 2, CONTROL_SEQ_ILK); + ilk_info[pre_def_loc] = N_OE; + pre_define ("OE ", 2, CONTROL_SEQ_ILK); + ilk_info[pre_def_loc] = N_OE_UPPER; + pre_define ("ae ", 2, CONTROL_SEQ_ILK); + ilk_info[pre_def_loc] = N_AE; + pre_define ("AE ", 2, CONTROL_SEQ_ILK); + ilk_info[pre_def_loc] = N_AE_UPPER; + pre_define ("aa ", 2, CONTROL_SEQ_ILK); + ilk_info[pre_def_loc] = N_AA; + pre_define ("AA ", 2, CONTROL_SEQ_ILK); + ilk_info[pre_def_loc] = N_AA_UPPER; + pre_define ("o ", 1, CONTROL_SEQ_ILK); + ilk_info[pre_def_loc] = N_O; + pre_define ("O ", 1, CONTROL_SEQ_ILK); + ilk_info[pre_def_loc] = N_O_UPPER; + pre_define ("l ", 1, CONTROL_SEQ_ILK); + ilk_info[pre_def_loc] = N_L; + pre_define ("L ", 1, CONTROL_SEQ_ILK); + ilk_info[pre_def_loc] = N_L_UPPER; + pre_define ("ss ", 2, CONTROL_SEQ_ILK); + ilk_info[pre_def_loc] = N_SS; +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 339 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + +/*************************************************************************** + * WEB section number: 340 + * ~~~~~~~~~~~~~~~~~~~ + * Now we pre-define any built-in |field|s, |str_entry_var|s, and + * |int_global_var|s; these strings must all be exactly |longest_pds| + * characters long. Note that although these are built-in functions, we + * classify them (in the |fn_type| array) otherwise. + * + * Important note: These pre-definitions must not have any glitches or + * the program may bomb because the |log_file| hasn't been opened yet. + ***************************************************************************/ + pre_define ("crossref ", 8, BST_FN_ILK); + fn_type[pre_def_loc] = FIELD; + FN_INFO[pre_def_loc] = num_fields; + crossref_num = num_fields; + INCR (num_fields); + num_pre_defined_fields = num_fields; + pre_define ("sort.key$ ", 9, BST_FN_ILK); + fn_type[pre_def_loc] = STR_ENTRY_VAR; + FN_INFO[pre_def_loc] = num_ent_strs; + sort_key_num = num_ent_strs; + INCR (num_ent_strs); + pre_define ("entry.max$ ", 10, BST_FN_ILK); + fn_type[pre_def_loc] = INT_GLOBAL_VAR; + FN_INFO[pre_def_loc] = ENT_STR_SIZE; + pre_define ("global.max$ ", 11, BST_FN_ILK); + fn_type[pre_def_loc] = INT_GLOBAL_VAR; + FN_INFO[pre_def_loc] = GLOB_STR_SIZE; +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 340 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 336 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 77 + * ~~~~~~~~~~~~~~~~~~~ + * This procedure initializes a pre-defined string of length at most + * |longest_pds|. + ***************************************************************************/ +void pre_define (PdsType_T pds, PdsLen_T len, StrIlk_T ilk) +BEGIN + PdsLen_T i; + + for (i=1; i<=len; i++) + BEGIN + + /*---------------------------------------------------------------------- + * Unlike the WEB, the string in `pds' will occupy the positions + * pds[0] ... pds[len-1], rather than pds[1] ... pds[len]. + *----------------------------------------------------------------------*/ + buffer[i] = xord[pds[i-1]]; + END + pre_def_loc = str_lookup (buffer, 1, len, ilk, DO_INSERT); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 77 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 3 + * ~~~~~~~~~~~~~~~~~~~ + ***************************************************************************/ +void print_a_newline (void) +BEGIN + if (log_file != NULL) + FPUTC ('\n', log_file); + FPUTC ('\n', TERM_OUT); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 3 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 51 + * ~~~~~~~~~~~~~~~~~~~ + * And here are the associated procedures. Note the |term_out| file is + * system dependent. + ***************************************************************************/ +void print_a_pool_str (StrNumber_T s) +BEGIN + out_pool_str (TERM_OUT, s); + out_pool_str (log_file, s); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 51 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 82 + * ~~~~~~~~~~~~~~~~~~~ + * And here are the associated procedures. Note the |term_out| file is + * system dependent. + ***************************************************************************/ +void print_a_token (void) +BEGIN + out_token (TERM_OUT); + out_token (log_file); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 82 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 108 + * ~~~~~~~~~~~~~~~~~~~ + * Print the name of the current .aux file, followed by a |newline|. + ***************************************************************************/ +void print_aux_name (void) +BEGIN + PRINT_POOL_STR (CUR_AUX_STR); + PRINT_NEWLINE; +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 108 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 95 + * ~~~~~~~~~~~~~~~~~~~ + * The |print_bad_input_line| procedure prints the current input line, + * splitting it at the character being scanned: It prints |buffer[0]|, + * |buffer[1]|, \dots, |buffer[buf_ptr2-1]| on one line and + * |SCAN_CHAR|, \dots, |buffer[last-1]| on the next (and both + * lines start with a colon between two |space|s). Each |white_space| + * character is printed as a |space|. + ***************************************************************************/ +void print_bad_input_line (void) +BEGIN + BufPointer_T bf_ptr; + + PRINT (" : "); + bf_ptr = 0; + while (bf_ptr < buf_ptr2) + BEGIN + if (lex_class[buffer[bf_ptr]] == WHITE_SPACE) + BEGIN + PRINT2 ("%c", xchr[SPACE]); + END + else + BEGIN + PRINT2 ("%c", xchr[buffer[bf_ptr]]); + END + INCR (bf_ptr); + END + PRINT_NEWLINE; + PRINT (" : "); + bf_ptr = 0; + while (bf_ptr < buf_ptr2) + BEGIN + PRINT2 ("%c", xchr[SPACE]); + INCR (bf_ptr); + END + bf_ptr = buf_ptr2; + while (bf_ptr < last) + BEGIN + if (lex_class[buffer[bf_ptr]] == WHITE_SPACE) + BEGIN + PRINT2 ("%c", xchr[SPACE]); + END + else + BEGIN + PRINT2 ("%c", xchr[buffer[bf_ptr]]); + END + INCR (bf_ptr); + END + PRINT_NEWLINE; + bf_ptr = 0; + while ((bf_ptr < buf_ptr2) && (lex_class[buffer[bf_ptr]] == WHITE_SPACE)) + BEGIN + INCR (bf_ptr); + END + if (bf_ptr == buf_ptr2) + BEGIN + PRINT_LN ("(Error may have been on previous line)"); + END + mark_error (); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 95 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 121 + * ~~~~~~~~~~~~~~~~~~~ + * Here's a procedure we'll need shortly. It prints the name of the + * current .bib file, followed by a |newline|. + ***************************************************************************/ +void print_bib_name (void) +BEGIN + PRINT_POOL_STR (CUR_BIB_STR); + PRINT_POOL_STR (s_bib_extension); + PRINT_NEWLINE; +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 121 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 128 + * ~~~~~~~~~~~~~~~~~~~ + * Print the name of the .bst file, followed by a |newline|. + ***************************************************************************/ +void print_bst_name (void) +BEGIN + PRINT_POOL_STR (bst_str); + PRINT_POOL_STR (s_bst_extension); + PRINT_NEWLINE; +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 128 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 45 + * ~~~~~~~~~~~~~~~~~~~ + * When something happens that the program thinks is impossible, + * call the maintainer. + ***************************************************************************/ +void print_confusion (void) +BEGIN + PRINT_LN ("---this can't happen"); + PRINT_LN ("*Please notify the BibTeX maintainer*"); + mark_fatal (); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 45 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 158 + * ~~~~~~~~~~~~~~~~~~~ + * Occasionally we'll want to |print| the name of one of these function + * classes. + ***************************************************************************/ +void print_fn_class (HashLoc_T fn_loc) +BEGIN + switch (fn_type[fn_loc]) + BEGIN + case BUILT_IN: + PRINT ("built-in"); + break; + case WIZ_DEFINED: + PRINT ("wizard-defined"); + break; + case INT_LITERAL: + PRINT ("integer-literal"); + break; + case STR_LITERAL: + PRINT ("string-literal"); + break; + case FIELD: + PRINT ("field"); + break; + case INT_ENTRY_VAR: + PRINT ("integer-entry-variable"); + break; + case STR_ENTRY_VAR: + PRINT ("string-entry-variable"); + break; + case INT_GLOBAL_VAR: + PRINT ("integer-global-variable"); + break; + case STR_GLOBAL_VAR: + PRINT ("string-global-variable"); + break; + default: + unknwn_function_class_confusion (); + break; + END +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 158 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 313 + * ~~~~~~~~~~~~~~~~~~~ + * This is similar to |print_stk_lit|, but here we don't give the + * literal's type, and here we end with a new line. This procedure + * should never be called after popping an empty stack. + ***************************************************************************/ +void print_lit (Integer_T stk_lt, StkType_T stk_tp) +BEGIN + switch (stk_tp) + BEGIN + case STK_INT: + PRINT_LN2 ("%ld", (long) stk_lt); + break; + case STK_STR: + PRINT_POOL_STR (stk_lt); + PRINT_NEWLINE; + break; + case STK_FN: + PRINT_POOL_STR (hash_text[stk_lt]); + PRINT_NEWLINE; + break; + case STK_FIELD_MISSING: + PRINT_POOL_STR (stk_lt); + PRINT_NEWLINE; + break; + case STK_EMPTY: + illegl_literal_confusion (); + break; + default: + unknwn_literal_confusion (); + break; + END +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 313 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/************************************************************************** + * WEB section number: 284 + * ~~~~~~~~~~~~~~~~~~~ + * When a cite key on the original |cite_list| (or added to |cite_list| + * because of cross~referencing) didn't appear in the database, complain. + ***************************************************************************/ +void print_missing_entry (StrNumber_T s) +BEGIN + PRINT ("Warning--I didn't find a database entry for \""); + PRINT_POOL_STR (s); + PRINT_LN ("\""); + mark_warning (); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 284 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + +/*************************************************************************** + * WEB section number: 44 + * ~~~~~~~~~~~~~~~~~~~ + * When something in the program wants to be bigger or something out + * there wants to be smaller, it's time to call it a run. Here's the + * first of several macros that have associated procedures so that they + * produce less inline code. + ***************************************************************************/ +void print_overflow (void) +BEGIN + PRINT ("Sorry---you've exceeded BibTeX's "); + mark_fatal (); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 44 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + +/*************************************************************************** + * WEB section number: 184 + * ~~~~~~~~~~~~~~~~~~~ + * This macro is similar to the last one but is specifically for + * recursion in a |wiz_defined| function, which is illegal; it helps save + * space. + ***************************************************************************/ +void print_recursion_illegal (void) +BEGIN + +#ifdef TRACE + if (Flag_trace) + TRACE_PR_NEWLINE; +#endif /* TRACE */ + + PRINT_LN ("Curse you, wizard, before you recurse me:"); + PRINT ("function "); + PRINT_TOKEN; + PRINT_LN (" is illegal in its own definition"); + + /*------------------------------------------------------------------------ + * print_recursion_illegal(); + *----------------------------------------------------------------------*/ + skip_token_print (); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 184 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + +/*************************************************************************** + * WEB section number: 96 + * ~~~~~~~~~~~~~~~~~~~ + * This little procedure exists because it's used by at least two other + * procedures and thus saves some space. + ***************************************************************************/ +void print_skipping_whatever_remains (void) +BEGIN + PRINT ("I'm skipping whatever remains of this "); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 96 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + +/*************************************************************************** + * WEB section number: 311 + * ~~~~~~~~~~~~~~~~~~~ + * Occasionally we'll want to know what's on the literal stack. Here we + * print out a stack literal, giving its type. This procedure should + * never be called after popping an empty stack. + ***************************************************************************/ +void print_stk_lit (Integer_T stk_lt, StkType_T stk_tp) +BEGIN + switch (stk_tp) + BEGIN + case STK_INT: + PRINT2 ("%ld is an integer literal", (long) stk_lt); + break; + case STK_STR: + PRINT ("\""); + PRINT_POOL_STR (stk_lt); + PRINT ("\" is a string literal"); + break; + case STK_FN: + PRINT ("`"); + PRINT_POOL_STR (hash_text[stk_lt]); + PRINT ("' is a function literal"); + break; + case STK_FIELD_MISSING: + PRINT ("`"); + PRINT_POOL_STR (stk_lt); + PRINT ("' is a missing field"); + break; + case STK_EMPTY: + illegl_literal_confusion (); + break; + default: + unknwn_literal_confusion (); + break; + END +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 311 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + +/*************************************************************************** + * WEB section number: 312 + * ~~~~~~~~~~~~~~~~~~~ + * This procedure appropriately chastises the style designer; however, if + * the wrong literal came from popping an empty stack, the procedure + * |pop_lit_stack| will have already done the chastising (because this + * procedure is called only after popping the stack) so there's no need + * for more. + ***************************************************************************/ +void print_wrong_stk_lit (Integer_T stk_lt, StkType_T stk_tp1, + StkType_T stk_tp2) +BEGIN + if (stk_tp1 != STK_EMPTY) + BEGIN + print_stk_lit (stk_lt, stk_tp1); + switch (stk_tp2) + BEGIN + case STK_INT: + PRINT (", not an integer,"); + break; + case STK_STR: + PRINT (", not a string,"); + break; + case STK_FN: + PRINT (", not a function,"); + break; + case STK_FIELD_MISSING: + case STK_EMPTY: + illegl_literal_confusion (); + break; + default: + unknwn_literal_confusion (); + break; + END + bst_ex_warn_print (); + END +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 312 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + +/*************************************************************************** + * WEB section number: 307 + * ~~~~~~~~~~~~~~~~~~~ + * Ok, that's it for sorting; now we'll play with the literal stack. + * This procedure pushes a literal onto the stack, checking for stack + * overflow. + ***************************************************************************/ +void push_lit_stk (Integer_T push_lt, StkType_T push_type) +BEGIN + +#ifdef TRACE + LitStkLoc_T dum_ptr; +#endif /* TRACE */ + + lit_stack[lit_stk_ptr] = push_lt; + lit_stk_type[lit_stk_ptr] = push_type; + +#ifdef TRACE + if (Flag_trace) { + for (dum_ptr=0; dum_ptr <= lit_stk_ptr; dum_ptr++) + BEGIN + TRACE_PR (" "); + END + TRACE_PR ("Pushing "); + + switch (lit_stk_type[lit_stk_ptr]) + BEGIN + case STK_INT: + TRACE_PR_LN2 ("%ld", (long) lit_stack[lit_stk_ptr]); + break; + case STK_STR: + TRACE_PR ("\""); + TRACE_PR_POOL_STR (lit_stack[lit_stk_ptr]); + TRACE_PR_LN ("\""); + break; + case STK_FN: + TRACE_PR ("`"); + TRACE_PR_POOL_STR (hash_text[lit_stack[lit_stk_ptr]]); + TRACE_PR_LN ("'"); + break; + case STK_FIELD_MISSING: + TRACE_PR ("missing field `"); + out_pool_str (log_file, lit_stack[lit_stk_ptr]); + TRACE_PR_LN ("'"); + break; + case STK_EMPTY: + TRACE_PR_LN ("a bad literal--popped from an empty stack"); + break; + default: + unknwn_literal_confusion (); + break; + END + } /* end if (Flag_trace) */ +#endif /* TRACE */ + + if (lit_stk_ptr == LIT_STK_SIZE) + BEGIN + BIBTEX_OVERFLOW ("literal-stack size ", LIT_STK_SIZE); + END + INCR (lit_stk_ptr); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 307 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + +/*************************************************************************** + * WEB section number: 303 + * ~~~~~~~~~~~~~~~~~~~ + * These next two procedures (actually, one procedures and one function, + * but who's counting) are subroutines for |quick_sort|, which follows. + * The |swap| procedure exchanges the two elements its arguments point + * to. + ***************************************************************************/ +void quick_sort (CiteNumber_T left_end, CiteNumber_T right_end) +BEGIN + CiteNumber_T left, + right; + CiteNumber_T insert_ptr; + CiteNumber_T middle; + CiteNumber_T partition; + +#ifdef TRACE + if (Flag_trace) + TRACE_PR_LN3 ("Sorting %ld through %ld", (long) left_end, + (long) right_end); +#endif /* TRACE */ + + if ((right_end - left_end) < SHORT_LIST) + BEGIN + +/*************************************************************************** + * WEB section number: 304 + * ~~~~~~~~~~~~~~~~~~~ + * This code sorts the entries between |left_end| and |right_end| when + * the difference is less than |short_list|. Each iteration of the outer + * loop inserts the element indicated by |insert_ptr| into its proper + * place among the (sorted) elements from |left_end| through + * |insert_ptr-1|. + ***************************************************************************/ + for (insert_ptr=(left_end+1); insert_ptr<=right_end; insert_ptr++) + BEGIN + for (right=insert_ptr; right >= (left_end+1); right--) + BEGIN + if (less_than (SORTED_CITES[right-1], SORTED_CITES[right])) + BEGIN + goto Next_Insert_Label; + END + swap (right - 1, right); + END +Next_Insert_Label: DO_NOTHING; + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 304 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + END + else + BEGIN + +/*************************************************************************** + * WEB section number: 305 + * ~~~~~~~~~~~~~~~~~~~ + * Now we find the median of the three sort.key$s to which the three + * elements |sorted_cites[left_end+end_offset]|, + * |sorted_cites[right_end]-end_offset|, and + * |sorted_cites[(left_end+right_end) div 2]| point (a nonzero + * |end_offset| avoids using as the leftmost of the three elements the + * one that was swapped there when the old partition element was swapped + * into its final spot; this turns out to avoid $n^2$ behavior when the + * list is nearly sorted to start with). This code determines which of + * the six possible permutations we're dealing with and moves the median + * element to |left_end|. The comments next to the |swap| actions give + * the known orderings of the corresponding elements of |sorted_cites| + * before the action. + ***************************************************************************/ + left = left_end + END_OFFSET; + middle = (left_end + right_end) / 2; + right = right_end - END_OFFSET; + if (less_than (SORTED_CITES[left], SORTED_CITES[middle])) + BEGIN + if (less_than (SORTED_CITES[middle], SORTED_CITES[right])) + BEGIN + swap (left_end, middle); + END + else if (less_than (SORTED_CITES[left], SORTED_CITES[right])) + BEGIN + swap (left_end, right); + END + else + BEGIN + swap (left_end, left); + END + END + else if (less_than (SORTED_CITES[right], SORTED_CITES[middle])) + BEGIN + swap (left_end, middle); + END + else if (less_than (SORTED_CITES[right], SORTED_CITES[left])) + BEGIN + swap (left_end, right); + END + else + BEGIN + swap (left_end, left); + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 305 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + +/*************************************************************************** + * WEB section number: 306 + * ~~~~~~~~~~~~~~~~~~~ + * This module uses the median-of-three computed above to partition the + * elements into those less than and those greater than the median. + * Equal sort.key$s are sorted by order of occurrence (in + * |cite_list|). + ***************************************************************************/ + partition = SORTED_CITES[left_end]; + left = left_end + 1; + right = right_end; + do + BEGIN + while (less_than (SORTED_CITES[left], partition)) + BEGIN + INCR (left); + END + while (less_than (partition, SORTED_CITES[right])) + BEGIN + DECR (right); + END + if (left < right) + BEGIN + swap (left, right); + INCR (left); + DECR (right); + END + END while ( ! (left == (right + 1))); + swap (left_end, right); + quick_sort (left_end, right - 1); + quick_sort (left, right_end); + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 306 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 303 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 98 + * ~~~~~~~~~~~~~~~~~~~ + * I mean, this is truly disgraceful. A user has to type something in to + * the terminal just once during the entire run. And it's not some + * complicated string where you have to get every last punctuation mark + * just right, and it's not some fancy list where you get nervous because + * if you forget one item you have to type the whole thing again; it's + * just a simple, ordinary, file name. Now you'd think a five-year-old + * could do it; you'd think it's so simple a user should be able to do it + * in his sleep. But noooooooooo. He had to sit there droning on and on + * about who knows what until he exceeded the bounds of common sense, and + * he probably didn't even realize it. Just pitiful. What's this world + * coming to? We should probably just delete all his files and be done + * with him. Note: The |TERM_OUT| file is system dependent. + * + * NOTE: because C arrays start at index 0, not 1, the subscripts of array + * |name_of_file| are generally 1 less than those in the WEB source. + ***************************************************************************/ +void sam_too_long_file_name_print (void) +BEGIN + FPRINTF (TERM_OUT, "File name `"); + name_ptr = 0; + while (name_ptr < aux_name_length) + BEGIN + FPUTC (name_of_file[name_ptr], TERM_OUT); + INCR (name_ptr); + END + FPRINTF (TERM_OUT, "' is too long\n"); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 98 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + +/*************************************************************************** + * WEB section number: 99 + * ~~~~~~~~~~~~~~~~~~~ + * We've abused the user enough for one section; suffice it to + * say here that most of what we said last module still applies. + * Note: The |TERM_OUT| file is system dependent. + * + * NOTE: because C arrays start at index 0, not 1, the subscripts of array + * |name_of_file| are generally 1 less than those in the WEB source. + ***************************************************************************/ +void sam_wrong_file_name_print (void) +BEGIN + FPRINTF (TERM_OUT, "I couldn't open file name `"); + name_ptr = 0; + while (name_ptr < name_length) + BEGIN + FPUTC (name_of_file[name_ptr], TERM_OUT); + INCR (name_ptr); + END + FPRINTF (TERM_OUT, "'\n"); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 99 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + +/*************************************************************************** + * WEB section number: 83 + * ~~~~~~~~~~~~~~~~~~~ + * This function scans the |buffer| for the next token, starting at the + * global variable |buf_ptr2| and ending just before either the single + * specified stop-character or the end of the current line, whichever + * comes first, respectively returning |true| or |false|; afterward, + * |scan_char| is the first character following this token. + ***************************************************************************/ +Boolean_T scan1 (ASCIICode_T char1) +BEGIN + Boolean_T scan1; + + buf_ptr1 = buf_ptr2; + while ((SCAN_CHAR != char1) && (buf_ptr2 < last)) + BEGIN + INCR (buf_ptr2); + END + if (buf_ptr2 < last) + BEGIN + scan1 = TRUE; + END + else + BEGIN + scan1 = FALSE; + END + return (scan1); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 83 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + +/*************************************************************************** + * WEB section number: 84 + * ~~~~~~~~~~~~~~~~~~~ + * This function is the same but stops at |white_space| characters as well. + ***************************************************************************/ +Boolean_T scan1_white (ASCIICode_T char1) +BEGIN + Boolean_T scan1_white; + + buf_ptr1 = buf_ptr2; + while ((lex_class[SCAN_CHAR] != WHITE_SPACE) + && (SCAN_CHAR != char1) && (buf_ptr2 < last)) + BEGIN + INCR (buf_ptr2); + END + if (buf_ptr2 < last) + BEGIN + scan1_white = TRUE; + END + else + BEGIN + scan1_white = FALSE; + END + return (scan1_white); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 84 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 85 + * ~~~~~~~~~~~~~~~~~~~ + * This function is similar to |scan1|, but stops at either of two + * stop-characters as well as the end of the current line. + ***************************************************************************/ +Boolean_T scan2 (ASCIICode_T char1, ASCIICode_T char2) +BEGIN + Boolean_T scan2; + + buf_ptr1 = buf_ptr2; + while ((SCAN_CHAR != char1) && (SCAN_CHAR != char2) + && (buf_ptr2 < last)) + BEGIN + INCR (buf_ptr2); + END + if (buf_ptr2 < last) + BEGIN + scan2 = TRUE; + END + else + BEGIN + scan2 = FALSE; + END + return (scan2); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 85 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + +/*************************************************************************** + * WEB section number: 86 + * ~~~~~~~~~~~~~~~~~~~ + * This function is the same but stops at |white_space| characters as well. + ***************************************************************************/ +Boolean_T scan2_white (ASCIICode_T char1, ASCIICode_T char2) +BEGIN + Boolean_T scan2_white; + + buf_ptr1 = buf_ptr2; + while ((SCAN_CHAR != char1) && (SCAN_CHAR != char2) + && (lex_class[SCAN_CHAR] != WHITE_SPACE) && (buf_ptr2 < last)) + BEGIN + INCR (buf_ptr2); + END + if (buf_ptr2 < last) + BEGIN + scan2_white = TRUE; + END + else + BEGIN + scan2_white = FALSE; + END + return (scan2_white); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 86 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 87 + * ~~~~~~~~~~~~~~~~~~~ + * This function is similar to |scan2|, but stops at either of three + * stop-characters as well as the end of the current line. + ***************************************************************************/ +Boolean_T scan3 (ASCIICode_T char1, ASCIICode_T char2, + ASCIICode_T char3) +BEGIN + Boolean_T scan3; + + buf_ptr1 = buf_ptr2; + while ((SCAN_CHAR != char1) && (SCAN_CHAR != char2) + && (SCAN_CHAR != char3) && (buf_ptr2 < last)) + BEGIN + INCR (buf_ptr2); + END + if (buf_ptr2 < last) + BEGIN + scan3 = TRUE; + END + else + BEGIN + scan3 = FALSE; + END + return (scan3); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 87 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 250 + * ~~~~~~~~~~~~~~~~~~~ + * Each field token is either a nonnegative number, a macro name (like + * `jan'), or a brace-balanced string delimited by either |double_quote|s + * or braces. Thus there are four possibilities for the first character + * of the field token: If it's a |left_brace| or a |double_quote|, the + * token (with balanced braces, up to the matching |right_str_delim|) is + * a string; if it's |numeric|, the token is a number; if it's anything + * else, the token is a macro name (and should thus have been defined by + * either the .bst-file's macro command or the .bib-file's + * string command). This function returns |false| if there was a + * serious syntax error. + ***************************************************************************/ +Boolean_T scan_a_field_token_and_eat_whit (void) +BEGIN + Boolean_T scan_a_field_token_And_eat_whit; + + scan_a_field_token_And_eat_whit = FALSE; + switch (SCAN_CHAR) + BEGIN + case LEFT_BRACE: + right_str_delim = RIGHT_BRACE; + if ( ! scan_balanced_braces ()) + goto Exit_Label; + break; + case DOUBLE_QUOTE: + right_str_delim = DOUBLE_QUOTE; + if ( ! scan_balanced_braces ()) + goto Exit_Label; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + +/*************************************************************************** + * WEB section number: 258 + * ~~~~~~~~~~~~~~~~~~~ + * This module scans a nonnegative number and copies it to |field_vl_str| + * if it's to store the field. + ***************************************************************************/ + if ( ! scan_nonneg_integer ()) + BEGIN + CONFUSION ("A digit disappeared"); + END + if (store_field) + BEGIN + tmp_ptr = buf_ptr1; + while (tmp_ptr < buf_ptr2) + BEGIN + COPY_CHAR (buffer[tmp_ptr]); + INCR (tmp_ptr); + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 258 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + break; + default: + +/*************************************************************************** + * WEB section number: 259 + * ~~~~~~~~~~~~~~~~~~~ + * This module scans a macro name and copies its string to |field_vl_str| + * if it's to store the field, complaining if the macro is recursive or + * undefined. + ***************************************************************************/ + scan_identifier (COMMA, right_outer_delim, CONCAT_CHAR); + BIB_IDENTIFIER_SCAN_CHECK ("a field part"); + if (store_field) + BEGIN + lower_case (buffer, buf_ptr1, TOKEN_LEN); + macro_name_loc = str_lookup (buffer, buf_ptr1, TOKEN_LEN, MACRO_ILK, + DONT_INSERT); + store_token = TRUE; + if (at_bib_command) + BEGIN + if (command_num == N_BIB_STRING) + BEGIN + if (macro_name_loc == cur_macro_loc) + BEGIN + store_token = FALSE; + MACRO_NAME_WARNING ("used in its own definition"); + END + END + END + if ( ! hash_found) + BEGIN + store_token = FALSE; + MACRO_NAME_WARNING ("undefined"); + END + if (store_token) + BEGIN + +/*************************************************************************** + * WEB section number: 260 + * ~~~~~~~~~~~~~~~~~~~ + * The macro definition may have |white_space| that needs compressing, + * because it may have been defined in the .bst file. + ***************************************************************************/ + tmp_ptr = str_start[ilk_info[macro_name_loc]]; + tmp_end_ptr = str_start[ilk_info[macro_name_loc] + 1]; + if (FIELD_END == 0) + BEGIN + if ((lex_class[str_pool[tmp_ptr]] == WHITE_SPACE) + && (tmp_ptr < tmp_end_ptr)) + BEGIN + COPY_CHAR (SPACE); + INCR (tmp_ptr); + while ((lex_class[str_pool[tmp_ptr]] == WHITE_SPACE) + && (tmp_ptr < tmp_end_ptr)) + BEGIN + INCR (tmp_ptr); + END + END + END + while (tmp_ptr < tmp_end_ptr) + BEGIN + if (lex_class[str_pool[tmp_ptr]] != WHITE_SPACE) + BEGIN + COPY_CHAR (str_pool[tmp_ptr]); + END + else if (FIELD_VL_STR[FIELD_END - 1] != SPACE) + BEGIN + COPY_CHAR (SPACE); + END + INCR (tmp_ptr); + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 260 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 259 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + break; + END + EAT_BIB_WHITE_AND_EOF_CHECK; + scan_a_field_token_And_eat_whit = TRUE; +Exit_Label: DO_NOTHING; + return (scan_a_field_token_And_eat_whit); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 250 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + +/*************************************************************************** + * WEB section number: 88 + * ~~~~~~~~~~~~~~~~~~~ + * This function scans for letters, stopping at the first nonletter; it + * returns |true| if there is at least one letter. + ***************************************************************************/ +Boolean_T scan_alpha (void) +BEGIN + Boolean_T scan_alpha; + + buf_ptr1 = buf_ptr2; + while ((lex_class[SCAN_CHAR] == ALPHA) && (buf_ptr2 < last)) + BEGIN + INCR (buf_ptr2); + END + if (TOKEN_LEN == 0) + BEGIN + scan_alpha = FALSE; + END + else + BEGIN + scan_alpha = TRUE; + END + return (scan_alpha); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 88 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + +/*************************************************************************** + * WEB section number: 249 + * ~~~~~~~~~~~~~~~~~~~ + * This function scans the list of field tokens that define the field + * value string. If |store_field| is |true| it accumulates (indirectly) + * in |field_vl_str| the concatenation of all the field tokens, + * compressing nonnull |white_space| to a single |space| and, if the + * field value is for a field (rather than a string definition), removing + * any leading or trailing |white_space|; when it's finished it puts the + * string into the hash table. It returns |false| if there was a serious + * syntax error. + ***************************************************************************/ +Boolean_T scan_and_store_the_field_value (void) +BEGIN + Boolean_T scan_and_store_the_field_value; + + scan_and_store_the_field_value = FALSE; + FIELD_END = 0; + if ( ! scan_a_field_token_and_eat_whit ()) + BEGIN + goto Exit_Label; + END + while (SCAN_CHAR == CONCAT_CHAR) + BEGIN + INCR (buf_ptr2); + EAT_BIB_WHITE_AND_EOF_CHECK; + if ( ! scan_a_field_token_and_eat_whit ()) + BEGIN + goto Exit_Label; + END + END + if (store_field) + BEGIN + +/*************************************************************************** + * WEB section number: 261 + * ~~~~~~~~~~~~~~~~~~~ + * Now it's time to store the field value in the hash table, and store an + * appropriate pointer to it (depending on whether it's for a database + * entry or command). But first, if necessary, we remove a trailing + * |space| and a leading |space| if these exist. (Hey, if we had some + * ham we could make ham-and-eggs if we had some eggs.) + ***************************************************************************/ + if ( ! at_bib_command) + BEGIN + if (FIELD_END > 0) + BEGIN + if (FIELD_VL_STR[FIELD_END - 1] == SPACE) + BEGIN + DECR (FIELD_END); + END + END + END + if (( ! at_bib_command) && (FIELD_VL_STR[0] == SPACE) && (FIELD_END > 0)) + BEGIN + FIELD_START = 1; + END + else + BEGIN + FIELD_START = 0; + END + field_val_loc = str_lookup (FIELD_VL_STR, FIELD_START, + FIELD_END - FIELD_START, TEXT_ILK, + DO_INSERT); + fn_type[field_val_loc] = STR_LITERAL; + +#ifdef TRACE + if (Flag_trace) { + TRACE_PR ("\""); + TRACE_PR_POOL_STR (hash_text[field_val_loc]); + TRACE_PR_LN ("\" is a field value"); + } +#endif /* TRACE */ + + if (at_bib_command) + BEGIN + +/*************************************************************************** + * WEB section number: 262 + * ~~~~~~~~~~~~~~~~~~~ + * Here's where we store the goods when we're dealing with a command + * rather than an entry. + ***************************************************************************/ + switch (command_num) + BEGIN + case N_BIB_PREAMBLE: + s_preamble[preamble_ptr] = hash_text[field_val_loc]; + INCR (preamble_ptr); + break; + case N_BIB_STRING: + ilk_info[cur_macro_loc] = hash_text[field_val_loc]; + break; + default: + bib_cmd_confusion (); + break; + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 262 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + END + else + BEGIN + +/*************************************************************************** + * WEB section number: 263 + * ~~~~~~~~~~~~~~~~~~~ + * And here, an entry. + ***************************************************************************/ + field_ptr = (entry_cite_ptr * num_fields) + FN_INFO[field_name_loc]; + if (field_info[field_ptr] != MISSING) + BEGIN + PRINT ("Warning--I'm ignoring "); + PRINT_POOL_STR (cite_list[entry_cite_ptr]); + PRINT ("'s extra \""); + PRINT_POOL_STR (hash_text[field_name_loc]); + BIB_WARN_NEWLINE ("\" field"); + END + else + BEGIN + field_info[field_ptr] = hash_text[field_val_loc]; + if ((ilk_info[field_name_loc] == crossref_num) + && ( ! all_entries)) + BEGIN + +/*************************************************************************** + * WEB section number: 264 + * ~~~~~~~~~~~~~~~~~~~ + * If the cross-referenced entry isn't already on |cite_list| we add it + * (at least temporarily); if it is already on |cite_list| we update the + * cross-reference count, if necessary. Note that |all_entries| is + * |false| here. The alias kludge helps make the stack space not + * overflow on some machines. + ***************************************************************************/ + tmp_ptr = FIELD_START; + while (tmp_ptr < FIELD_END) + BEGIN + EXTRA_BUF[tmp_ptr] = FIELD_VL_STR[tmp_ptr]; + INCR (tmp_ptr); + END + lower_case (EXTRA_BUF, FIELD_START, FIELD_END - FIELD_START); + lc_cite_loc = str_lookup (EXTRA_BUF, FIELD_START, + FIELD_END - FIELD_START, LC_CITE_ILK, + DO_INSERT); + if (hash_found) + BEGIN + cite_loc = ilk_info[lc_cite_loc]; + if (ilk_info[cite_loc] >= old_num_cites) + BEGIN + INCR (cite_info[ilk_info[cite_loc]]); + END + END + else + BEGIN + cite_loc = str_lookup (FIELD_VL_STR, FIELD_START, + FIELD_END - FIELD_START, CITE_ILK, + DO_INSERT); + if (hash_found) + BEGIN + hash_cite_confusion (); + END + add_database_cite (&cite_ptr); + cite_info[ilk_info[cite_loc]] = 1; + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 264 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 263 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 261 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + END + scan_and_store_the_field_value = TRUE; +Exit_Label: DO_NOTHING; + return (scan_and_store_the_field_value); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 249 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + +/*************************************************************************** + * WEB section number: 253 + * ~~~~~~~~~~~~~~~~~~~ + * This .bib-specific function scans a string with balanced braces, + * stopping just past the matching |right_str_delim|. How much work it + * does depends on whether |store_field = true|. It returns |false| if + * there was a serious syntax error. + ***************************************************************************/ +Boolean_T scan_balanced_braces (void) +BEGIN + Boolean_T scan_balanced_braces; + + scan_balanced_braces = FALSE; + INCR (buf_ptr2); + CHECK_FOR_AND_COMPRESS_BIB_WHIT; + if (FIELD_END > 1) + BEGIN + if (FIELD_VL_STR[FIELD_END- 1] == SPACE) + BEGIN + if (ex_buf[FIELD_END- 2] == SPACE) + BEGIN + DECR (FIELD_END); + END + END + END + bib_brace_level = 0; + if (store_field) + BEGIN + +/*************************************************************************** + * WEB section number: 256 + * ~~~~~~~~~~~~~~~~~~~ + * This module scans over a brace-balanced string, compressing multiple + * |white_space| characters into a single |space|. It starts with + * |bib_brace_level = 0| and starts at a non|white_space| character. + ***************************************************************************/ + while (SCAN_CHAR != right_str_delim) + BEGIN + switch (SCAN_CHAR) + BEGIN + case LEFT_BRACE: + INCR (bib_brace_level); + COPY_CHAR (LEFT_BRACE); + INCR (buf_ptr2); + CHECK_FOR_AND_COMPRESS_BIB_WHIT; + +/*************************************************************************** + * WEB section number: 257 + * ~~~~~~~~~~~~~~~~~~~ + * This module is similar to the last but starts with |bib_brace_level > 0| + * (and, like the last, it starts at a non|white_space| character). + ***************************************************************************/ + LOOP + BEGIN + switch (SCAN_CHAR) + BEGIN + case RIGHT_BRACE: + DECR (bib_brace_level); + COPY_CHAR (RIGHT_BRACE); + INCR (buf_ptr2); + CHECK_FOR_AND_COMPRESS_BIB_WHIT; + if (bib_brace_level == 0) + BEGIN + goto Loop_Exit_Label; + END + break; + case LEFT_BRACE: + INCR (bib_brace_level); + COPY_CHAR (LEFT_BRACE); + INCR (buf_ptr2); + CHECK_FOR_AND_COMPRESS_BIB_WHIT; + break; + default: + COPY_CHAR (SCAN_CHAR); + INCR (buf_ptr2); + CHECK_FOR_AND_COMPRESS_BIB_WHIT; + break; + END + END + Loop_Exit_Label: DO_NOTHING +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 257 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + break; + case RIGHT_BRACE: + BIB_UNBALANCED_BRACES_ERR; + default: + COPY_CHAR (SCAN_CHAR); + INCR (buf_ptr2); + CHECK_FOR_AND_COMPRESS_BIB_WHIT; + break; + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 256 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + END + else + BEGIN + +/*************************************************************************** + * WEB section number: 254 + * ~~~~~~~~~~~~~~~~~~~ + * This module scans over a brace-balanced string without keeping track + * of anything but the brace level. It starts with |bib_brace_level = 0| + * and at a non|white_space| character. + ***************************************************************************/ + while (SCAN_CHAR != right_str_delim) + BEGIN + if (SCAN_CHAR == LEFT_BRACE) + BEGIN + INCR (bib_brace_level); + INCR (buf_ptr2); + EAT_BIB_WHITE_AND_EOF_CHECK; + while (bib_brace_level > 0) + BEGIN + +/*************************************************************************** + * WEB section number: 255 + * ~~~~~~~~~~~~~~~~~~~ + * This module does the same as above but, because |bib_brace_level > 0|, it + * doesn't have to look for a |right_str_delim|. + ***************************************************************************/ + if (SCAN_CHAR == RIGHT_BRACE) + BEGIN + DECR (bib_brace_level); + INCR (buf_ptr2); + EAT_BIB_WHITE_AND_EOF_CHECK; + END + else if (SCAN_CHAR == LEFT_BRACE) + BEGIN + INCR (bib_brace_level); + INCR (buf_ptr2); + EAT_BIB_WHITE_AND_EOF_CHECK; + END + else + BEGIN + INCR (buf_ptr2); + if ( ! scan2 (RIGHT_BRACE, LEFT_BRACE)) + BEGIN + EAT_BIB_WHITE_AND_EOF_CHECK; + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 255 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + END + END + else if (SCAN_CHAR == RIGHT_BRACE) + BEGIN + BIB_UNBALANCED_BRACES_ERR; + END + else + BEGIN + INCR (buf_ptr2); + if ( ! scan3 (right_str_delim, LEFT_BRACE, RIGHT_BRACE)) + BEGIN + EAT_BIB_WHITE_AND_EOF_CHECK; + END + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 254 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + END + INCR (buf_ptr2); + scan_balanced_braces = TRUE; +Exit_Label: DO_NOTHING; + return (scan_balanced_braces); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 253 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + +/*************************************************************************** + * WEB section number: 187 + * ~~~~~~~~~~~~~~~~~~~ + * This recursive function reads and stores the list of functions + * (separated by |white_space| characters or ends-of-line) that define + * this new function, and reads a |right_brace|. + ***************************************************************************/ +void scan_fn_def (HashLoc_T fn_hash_loc) +BEGIN + typedef Integer_T FnDefLoc_T; + HashPtr2_T singl_function[SINGLE_FN_SPACE + 1]; + FnDefLoc_T single_ptr; + FnDefLoc_T copy_ptr; + BufPointer_T end_of_num; + HashLoc_T impl_fn_loc; + + EAT_BST_WHITE_AND_EOF_CHECK ("function"); + single_ptr = 0; + while (SCAN_CHAR != RIGHT_BRACE) + BEGIN + +/*************************************************************************** + * WEB section number: 189 + * ~~~~~~~~~~~~~~~~~~~ + * There are five possibilities for the first character of the token + * representing the next function of the definition: If it's a + * |number_sign|, the token is an |int_literal|; if it's a + * |double_quote|, the token is a |str_literal|; if it's a + * |single_quote|, the token is a quoted function; if it's a + * |left_brace|, the token isn't really a token, but rather the start of + * another function definition (which will result in a recursive call to + * |scan_fn_def|); if it's anything else, the token is the name of an + * already-defined function. Note: To prevent the wizard from using + * recursion, we have to check that neither a quoted function nor an + * already-defined-function is actually the currently-being-defined + * function (which is stored at |wiz_loc|). + ***************************************************************************/ + switch (SCAN_CHAR) + BEGIN + case NUMBER_SIGN: + +/*************************************************************************** + * WEB section number: 190 + * ~~~~~~~~~~~~~~~~~~~ + * An |int_literal| is preceded by a |number_sign|, consists of an + * integer (i.e., an optional |minus_sign| followed by one or more + * |numeric| characters), and is followed either by a |white_space| + * character, an end-of-line, or a |right_brace|. The array |fn_info| + * contains the value of the integer for |int_literal|s. + ***************************************************************************/ + BEGIN + INCR (buf_ptr2); + if ( ! scan_integer ()) + BEGIN + SKIP_TOKEN ("Illegal integer in integer literal"); + END + +#ifdef TRACE + if (Flag_trace) { + TRACE_PR ("#"); + TRACE_PR_TOKEN; + TRACE_PR_LN2 (" is an integer literal with value %ld", + (long) token_value); + } +#endif /* TRACE */ + + literal_loc = str_lookup (buffer, buf_ptr1, TOKEN_LEN, INTEGER_ILK, + DO_INSERT); + if ( ! hash_found) + BEGIN + fn_type[literal_loc] = INT_LITERAL; + FN_INFO[literal_loc] = token_value; + END + if ((lex_class[SCAN_CHAR] != WHITE_SPACE) && (buf_ptr2 < last) + && (SCAN_CHAR != RIGHT_BRACE) && (SCAN_CHAR != COMMENT)) + BEGIN + SKIP_TOKEN_ILLEGAL_STUFF_AFTER; + END + INSERT_FN_LOC (literal_loc); + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 190 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + break; + case DOUBLE_QUOTE: + +/*************************************************************************** + * WEB section number: 191 + * ~~~~~~~~~~~~~~~~~~~ + * A |str_literal| is preceded by a |double_quote| and consists of all + * characters on this line up to the next |double_quote|. Also, there + * must be either a |white_space| character, an end-of-line, a + * |right_brace|, or a |comment| following (since functions in the + * definition must be separated by |white_space|). The array |fn_info| + * contains nothing for |str_literal|s. + ***************************************************************************/ + BEGIN + INCR (buf_ptr2); + if ( ! scan1 (DOUBLE_QUOTE)) + BEGIN + SKIP_TOKEN2 ("No `%c' to end string literal", xchr[DOUBLE_QUOTE]); + END + +#ifdef TRACE + if (Flag_trace) { + TRACE_PR ("\""); + TRACE_PR_TOKEN; + TRACE_PR ("\""); + TRACE_PR_LN (" is a string literal"); + } +#endif /* TRACE */ + + literal_loc = str_lookup (buffer, buf_ptr1, TOKEN_LEN, TEXT_ILK, + DO_INSERT); + fn_type[literal_loc] = STR_LITERAL; + INCR (buf_ptr2); + if ((lex_class[SCAN_CHAR] != WHITE_SPACE) && (buf_ptr2 < last) + && (SCAN_CHAR != RIGHT_BRACE) && (SCAN_CHAR != COMMENT)) + BEGIN + SKIP_TOKEN_ILLEGAL_STUFF_AFTER; + END + INSERT_FN_LOC (literal_loc); + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 191 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + break; + case SINGLE_QUOTE: + +/*************************************************************************** + * WEB section number: 192 + * ~~~~~~~~~~~~~~~~~~~ + * A quoted function is preceded by a |single_quote| and consists of all + * characters up to the next |white_space| character, end-of-line, + * |right_brace|, or |comment|. + ***************************************************************************/ + BEGIN + INCR (buf_ptr2); + if (scan2_white (RIGHT_BRACE, COMMENT)) + BEGIN + DO_NOTHING; + END + +#ifdef TRACE + if (Flag_trace) { + TRACE_PR ("'"); + TRACE_PR_TOKEN; + TRACE_PR (" is a quoted function "); + } +#endif /* TRACE */ + + lower_case (buffer, buf_ptr1, TOKEN_LEN); + fn_loc = str_lookup (buffer, buf_ptr1, TOKEN_LEN, BST_FN_ILK, + DONT_INSERT); + if ( ! hash_found) + BEGIN + SKIP_TOKEN_UNKNOWN_FUNCTION; + END + else + +/*************************************************************************** + * WEB section number: 193 + * ~~~~~~~~~~~~~~~~~~~ + * Here we check that this quoted function is a legal one---the function + * name must already exist, but it mustn't be the currently-being-defined + * function (which is stored at |wiz_loc|). + ***************************************************************************/ + BEGIN + if (fn_loc == wiz_loc) + BEGIN + SKIP_RECURSIVE_TOKEN; + END + else + BEGIN + +#ifdef TRACE + if (Flag_trace) { + TRACE_PR ("of type "); + trace_pr_fn_class (fn_loc); + TRACE_PR_NEWLINE; + } +#endif /* TRACE */ + + INSERT_FN_LOC (QUOTE_NEXT_FN); + INSERT_FN_LOC (fn_loc); + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 193 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 192 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + break; + case LEFT_BRACE: + +/*************************************************************************** + * WEB section number: 194 + * ~~~~~~~~~~~~~~~~~~~ + * This module marks the implicit function as being quoted, generates a + * name, and stores it in the hash table. This name is strictly internal + * to this program, starts with a |single_quote| (since that will make + * this function name unique), and ends with the variable |impl_fn_num| + * converted to ASCII. The alias kludge helps make the stack space not + * overflow on some machines. + ***************************************************************************/ + BEGIN + EX_BUF2[0] = SINGLE_QUOTE; + int_to_ASCII (impl_fn_num, EX_BUF2, 1, &end_of_num); + impl_fn_loc = str_lookup (EX_BUF2, 0, end_of_num, BST_FN_ILK, + DO_INSERT); + if (hash_found) + BEGIN + CONFUSION ("Already encountered implicit function"); + END + +#ifdef TRACE + if (Flag_trace) { + TRACE_PR_POOL_STR (hash_text[impl_fn_loc]); + TRACE_PR_LN (" is an implicit function"); + } +#endif /* TRACE */ + + INCR (impl_fn_num); + fn_type[impl_fn_loc] = WIZ_DEFINED; + INSERT_FN_LOC (QUOTE_NEXT_FN); + INSERT_FN_LOC (impl_fn_loc); + INCR (buf_ptr2); + scan_fn_def (impl_fn_loc); + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 194 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + break; + default: + +/*************************************************************************** + * WEB section number: 199 + * ~~~~~~~~~~~~~~~~~~~ + * An already-defined function consists of all characters up to the next + * |white_space| character, end-of-line, |right_brace|, or |comment|. + * This function name must already exist, but it mustn't be the + * currently-being-defined function (which is stored at |wiz_loc|). + ***************************************************************************/ + BEGIN + if (scan2_white (RIGHT_BRACE, COMMENT)) + BEGIN + DO_NOTHING; + END + +#ifdef TRACE + if (Flag_trace) { + TRACE_PR_TOKEN; + TRACE_PR (" is a function "); + } +#endif /* TRACE */ + + lower_case (buffer, buf_ptr1, TOKEN_LEN); + fn_loc = str_lookup (buffer, buf_ptr1, TOKEN_LEN, BST_FN_ILK, + DONT_INSERT); + if ( ! hash_found) + BEGIN + SKIP_TOKEN_UNKNOWN_FUNCTION; + END + else if (fn_loc == wiz_loc) + BEGIN + SKIP_RECURSIVE_TOKEN; + END + else + BEGIN + +#ifdef TRACE + if (Flag_trace) { + TRACE_PR ("of type "); + trace_pr_fn_class (fn_loc); + TRACE_PR_NEWLINE; + } +#endif /* TRACE */ + + INSERT_FN_LOC (fn_loc); + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 199 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + break; + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 189 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + +Next_Token_Label: + EAT_BST_WHITE_AND_EOF_CHECK ("function"); + END + +/*************************************************************************** + * WEB section number: 200 + * ~~~~~~~~~~~~~~~~~~~ + * Now we add the |end_of_def| special marker, make sure this function will + * fit into |wiz_functions|, and put it there. + ***************************************************************************/ + BEGIN + INSERT_FN_LOC (END_OF_DEF); + if ((single_ptr + wiz_def_ptr) > Wiz_Fn_Space) + BEGIN + PRINT2 ("%ld: ", (long) (single_ptr + wiz_def_ptr)); + BIBTEX_OVERFLOW ("wizard-defined function space ", Wiz_Fn_Space); + END + FN_INFO[fn_hash_loc] = wiz_def_ptr; + copy_ptr = 0; + while (copy_ptr < single_ptr) + BEGIN + wiz_functions[wiz_def_ptr] = singl_function[copy_ptr]; + INCR (copy_ptr); + INCR (wiz_def_ptr); + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 200 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + INCR (buf_ptr2); +Exit_Label: DO_NOTHING; +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 187 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 90 + * ~~~~~~~~~~~~~~~~~~~ + * This procedure scans for an identifier, stopping at the first + * |illegal_id_char|, or stopping at the first character if it's + * |numeric|. It sets the global variable |scan_result| to |id_null| if + * the identifier is null, else to |white_adjacent| if it ended at a + * |white_space| character or an end-of-line, else to + * |specified_char_adjacent| if it ended at one of |char1| or |char2| or + * |char3|, else to |other_char_adjacent| if it ended at a nonspecified, + * non|white_space| |illegal_id_char|. By convention, when some calling + * code really wants just one or two ``specified'' characters, it merely + * repeats one of the characters. + ***************************************************************************/ +void scan_identifier (ASCIICode_T char1, ASCIICode_T char2, + ASCIICode_T char3) +BEGIN + buf_ptr1 = buf_ptr2; + if (lex_class[SCAN_CHAR] != NUMERIC) + BEGIN + while ((id_class[SCAN_CHAR] == LEGAL_ID_CHAR) && (buf_ptr2 < last)) + BEGIN + INCR (buf_ptr2); + END + END + if (TOKEN_LEN == 0) + BEGIN + scan_result = ID_NULL; + END + else if ((lex_class[SCAN_CHAR] == WHITE_SPACE) || (buf_ptr2 == last)) + BEGIN + scan_result = SPECIFIED_CHAR_ADJACENT; + END + else if ((SCAN_CHAR == char1) || (SCAN_CHAR == char2) + || (SCAN_CHAR == char3)) + BEGIN + scan_result = SPECIFIED_CHAR_ADJACENT; + END + else + BEGIN + scan_result = OTHER_CHAR_ADJACENT; + END +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 90 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 93 + * ~~~~~~~~~~~~~~~~~~~ + * This procedure scans for an integer, stopping at the first nondigit; + * it sets the value of |token_value| accordingly. It returns |true| if + * the token was a legal integer (i.e., consisted of an optional + * |minus_sign| followed by one or more digits). + ***************************************************************************/ +Boolean_T scan_integer (void) +BEGIN + Integer8_T sign_length; + Boolean_T scan_integer; + + buf_ptr1 = buf_ptr2; + if (SCAN_CHAR == MINUS_SIGN) + BEGIN + sign_length = 1; + INCR (buf_ptr2); + END + else + BEGIN + sign_length = 0; + END + token_value = 0; + while ((lex_class[SCAN_CHAR] == NUMERIC) && (buf_ptr2 < last)) + BEGIN + token_value = (token_value * 10) + CHAR_VALUE; + INCR (buf_ptr2); + END + if (NEGATIVE) + BEGIN + token_value = -token_value; + END + if (TOKEN_LEN == sign_length) + BEGIN + scan_integer = FALSE; + END + else + BEGIN + scan_integer = TRUE; + END + return(scan_integer); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 93 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 92 + * ~~~~~~~~~~~~~~~~~~~ + * This function scans for a nonnegative integer, stopping at the first + * nondigit; it sets the value of |token_value| accordingly. It returns + * |true| if the token was a legal nonnegative integer (i.e., consisted + * of one or more digits). + ***************************************************************************/ +Boolean_T scan_nonneg_integer (void) +BEGIN + Boolean_T scan_nonneg_integer; + + buf_ptr1 = buf_ptr2; + token_value = 0; + while ((lex_class[SCAN_CHAR] == NUMERIC) && (buf_ptr2 < last)) + BEGIN + token_value = (token_value * 10) + CHAR_VALUE; + INCR (buf_ptr2); + END + if (TOKEN_LEN == 0) + BEGIN + scan_nonneg_integer = FALSE; + END + else + BEGIN + scan_nonneg_integer = TRUE; + END + return (scan_nonneg_integer); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 92 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 94 + * ~~~~~~~~~~~~~~~~~~~ + * This function scans over |white_space| characters, stopping either at + * the first nonwhite character or the end of the line, respectively + * returning |true| or |false|. + ***************************************************************************/ +Boolean_T scan_white_space (void) +BEGIN + Boolean_T scan_white_space; + + while ((lex_class[SCAN_CHAR] == WHITE_SPACE) && (buf_ptr2 < last)) + BEGIN + INCR (buf_ptr2); + END + if (buf_ptr2 < last) + BEGIN + scan_white_space = TRUE; + END + else + BEGIN + scan_white_space = FALSE; + END + return (scan_white_space); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 94 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 188 + * ~~~~~~~~~~~~~~~~~~~ + * This macro inserts a hash-table location (or one of the two + * special markers |quote_next_fn| and |end_of_def|) into the + * |singl_function| array, which will later be copied into the + * |wiz_functions| array. + ***************************************************************************/ +void singl_fn_overflow (void) +BEGIN + BIBTEX_OVERFLOW ("single function space ", SINGLE_FN_SPACE); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 188 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 186 + * ~~~~~~~~~~~~~~~~~~~ + * And another. + ***************************************************************************/ +void skip_illegal_stuff_after_token (void) +BEGIN + PRINT2 ("\"%c\" can't follow a literal", xchr[SCAN_CHAR]); + skip_token_print (); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 186 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + +/*************************************************************************** + * WEB section number: 404 + * ~~~~~~~~~~~~~~~~~~~ + * When we come here |sp_ptr| is just past the |left_brace|, and when we + * leave it's either at |sp_end| or just past the matching |right_brace|. + ***************************************************************************/ +void skip_stuff_at_sp_brace_level_gr (void) +BEGIN + while ((sp_brace_level > 1) && (sp_ptr < sp_end)) + BEGIN + if (str_pool[sp_ptr] == RIGHT_BRACE) + BEGIN + DECR (sp_brace_level); + END + else if (str_pool[sp_ptr] == LEFT_BRACE) + BEGIN + INCR (sp_brace_level); + END + INCR (sp_ptr); + END +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 404 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 183 + * ~~~~~~~~~~~~~~~~~~~ + * We're about to start scanning tokens in a function definition. When a + * function token is illegal, we skip until it ends; a |white_space| + * character, an end-of-line, a |right_brace|, or a |comment| marks the + * end of the current token. + ***************************************************************************/ +void skip_token_print (void) +BEGIN + PRINT ("-"); + bst_ln_num_print (); + mark_error (); + if (scan2_white (RIGHT_BRACE, COMMENT)) + BEGIN + DO_NOTHING; + END +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 183 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 185 + * ~~~~~~~~~~~~~~~~~~~ + * Here's another macro for saving some space when there's a problem with + * a token. + ***************************************************************************/ +void skp_token_unknown_function_prin (void) +BEGIN + PRINT_TOKEN; + PRINT (" is an unknown function"); + skip_token_print (); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 185 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 58 + * ~~~~~~~~~~~~~~~~~~~ + * This procedure copies file name |file_name| into the beginning of + * |name_of_file|, if it will fit. It also sets the global variable + * |name_length| to the appropriate value. + * + * NOTE: because C arrays start at index 0, not 1, the subscripts of array + * |name_of_file| are generally 1 less than those in the WEB source. + ***************************************************************************/ +void start_name (StrNumber_T file_name) +BEGIN + PoolPointer_T p_ptr; + + if (LENGTH (file_name) > FILE_NAME_SIZE) + BEGIN + PRINT ("File="); + PRINT_POOL_STR (file_name); + PRINT_LN (","); + file_nm_size_overflow (); + END + name_ptr = 0; + p_ptr = str_start[file_name]; + while (p_ptr < str_start[file_name + 1]) + BEGIN + name_of_file[name_ptr] = CHR (str_pool[p_ptr]); + INCR (name_ptr); + INCR (p_ptr); + END + name_length = LENGTH (file_name); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 58 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 56 + * ~~~~~~~~~~~~~~~~~~~ + * This subroutine compares string |s| with another string that appears + * in the buffer |buf| between positions |bf_ptr| and |bf_ptr+len-1|; the + * result is |true| if and only if the strings are equal. + ***************************************************************************/ +Boolean_T str_eq_buf (StrNumber_T s, BufType_T buf, + BufPointer_T bf_ptr, BufPointer_T len) +BEGIN + BufPointer_T i; + PoolPointer_T j; + Boolean_T str_eq_buf; + + if (LENGTH (s) != len) + BEGIN + str_eq_buf = FALSE; + goto Exit_Label; + END + i = bf_ptr; + j = str_start[s]; + while (j < str_start[s + 1]) + BEGIN + if (str_pool[j] != buf[i]) + BEGIN + str_eq_buf = FALSE; + goto Exit_Label; + END + INCR (i); + INCR (j); + END + str_eq_buf = TRUE; +Exit_Label: + return (str_eq_buf); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 56 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 57 + * ~~~~~~~~~~~~~~~~~~~ + * This subroutine compares two |str_pool| strings and returns true + * |true| if and only if the strings are equal. + ***************************************************************************/ +Boolean_T str_eq_str (StrNumber_T s1, StrNumber_T s2) +BEGIN + Boolean_T str_eq_str; + + if (LENGTH (s1) != LENGTH (s2)) + BEGIN + str_eq_str = FALSE; + goto Exit_Label; + END + p_ptr1 = str_start[s1]; + p_ptr2 = str_start[s2]; + while (p_ptr1 < str_start[s1 + 1]) + BEGIN + if (str_pool[p_ptr1] != str_pool[p_ptr2]) + BEGIN + str_eq_str = FALSE; + goto Exit_Label; + END + INCR (p_ptr1); + INCR (p_ptr2); + END + str_eq_str = TRUE; +Exit_Label: + return (str_eq_str); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 57 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 68 + * ~~~~~~~~~~~~~~~~~~~ + * Here is the subroutine that searches the hash table for a + * (string,~|str_ilk|) pair, where the string is of length |l>=0| and + * appears in |buffer[j..(j+l-1)]|. If it finds the pair, it returns the + * corresponding hash-table location and sets the global variable + * |hash_found| to |true|. Otherwise it sets |hash_found| to |false|, + * and if the parameter |insert_it| is |true|, it inserts the pair into + * the hash table, inserts the string into |str_pool| if not previously + * encountered, and returns its location. Note that two different pairs + * can have the same string but different |str_ilk|s, in which case the + * second pair encountered, if |insert_it| were |true|, would be inserted + * into the hash table though its string wouldn't be inserted into + * |str_pool| because it would already be there. + ***************************************************************************/ +HashLoc_T str_lookup (BufType_T buf, BufPointer_T j, BufPointer_T l, + StrIlk_T ilk, Boolean_T insert_it) +BEGIN + HashLoc_T str_lookup; + long h; + HashLoc_T p; + BufPointer_T k; + Boolean_T old_string; + StrNumber_T str_num; + +/*************************************************************************** + * WEB section number: 69 + * ~~~~~~~~~~~~~~~~~~~ + * The value of |Hash_Prime| should be roughly 85\% of |Hash_Size|, and + * it should be a prime number + * (it should also be less than $2^14 + 2^6 = 16320$ because of + * WEB's simple-macro bound). The theory of hashing tells us to expect + * fewer than two table probes, on the average, when the search is + * successful. + * + * NOTE: the limit imposed on the value of Hash_Prime no longer applies + * because we are using C #defines. + ***************************************************************************/ + BEGIN + h = 0; + k = j; + while (k < (j + l)) + BEGIN + h = h + h + buf[k]; + while (h >= Hash_Prime) + h = h - Hash_Prime; + INCR (k); + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 69 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + p = h + HASH_BASE; + hash_found = FALSE; + old_string = FALSE; + LOOP + BEGIN + +/*************************************************************************** + * WEB section number: 70 + * ~~~~~~~~~~~~~~~~~~~ + * Here we handle the case in which we've already encountered this + * string; note that even if we have, we'll still have to insert the pair + * into the hash table if |str_ilk| doesn't match. + ***************************************************************************/ + BEGIN + if (hash_text[p] > 0) + BEGIN + if (str_eq_buf (hash_text[p], buf, j, l)) + BEGIN + if (hash_ilk[p] == ilk) + BEGIN + hash_found = TRUE; + goto Str_Found_Label; + END + else + BEGIN + old_string = TRUE; + str_num = hash_text[p]; + END + END + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 70 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + if (hash_next[p] == EMPTY) + BEGIN + if ( ! insert_it) + BEGIN + goto Str_Not_Found_Label; + END + +/*************************************************************************** + * WEB section number: 71 + * ~~~~~~~~~~~~~~~~~~~ + * This code inserts the pair in the appropriate unused location. + ***************************************************************************/ + BEGIN + if (hash_text[p] > 0) + BEGIN + REPEAT + BEGIN + if (HASH_IS_FULL) + BEGIN + BIBTEX_OVERFLOW ("hash size ", Hash_Size); + END + DECR (hash_used); + END UNTIL (hash_text[hash_used] == 0); + hash_next[p] = hash_used; + p = hash_used; + END + if (old_string) + BEGIN + hash_text[p] = str_num; + END + else + BEGIN + STR_ROOM (l); + k = j; + while (k < (j + l)) + BEGIN + APPEND_CHAR (buf[k]); + INCR (k); + END + hash_text[p] = make_string (); + END + hash_ilk[p] = ilk; + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 71 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + goto Str_Found_Label; + END + p = hash_next[p]; + END +Str_Not_Found_Label: DO_NOTHING; +Str_Found_Label: str_lookup = p; + return (str_lookup); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 68 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + +/*************************************************************************** + * WEB section number: 300 + * ~~~~~~~~~~~~~~~~~~~ + * The |swap| procedure exchanges the two elements its arguments point + * to. + ***************************************************************************/ +void swap (CiteNumber_T swap1, CiteNumber_T swap2) +BEGIN + CiteNumber_T innocent_bystander; + + innocent_bystander = SORTED_CITES[swap2]; + SORTED_CITES[swap2] = SORTED_CITES[swap1]; + SORTED_CITES[swap1] = innocent_bystander; +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 300 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + +/*************************************************************************** + * WEB section number: 456 + * ~~~~~~~~~~~~~~~~~~~ + * Here we print |trace| and/or |stat| information, if desired. + ***************************************************************************/ +void trace_and_stat_printing (void) +BEGIN + +#ifdef TRACE + + if (Flag_trace) { + +/*************************************************************************** + * WEB section number: 457 + * ~~~~~~~~~~~~~~~~~~~ + * This prints information obtained from the .aux file about the + * other files. + ***************************************************************************/ + BEGIN + if (num_bib_files == 1) + BEGIN + TRACE_PR_LN ("The 1 database file is"); + END + else + BEGIN + TRACE_PR_LN2 ("The %ld database files are", (long) num_bib_files); + END + if (num_bib_files == 0) + BEGIN + TRACE_PR_LN (" undefined"); + END + else + BEGIN + bib_ptr = 0; + while (bib_ptr < num_bib_files) + BEGIN + TRACE_PR (" "); + TRACE_PR_POOL_STR (CUR_BIB_STR); + TRACE_PR_POOL_STR (s_bib_extension); + TRACE_PR_NEWLINE; + INCR (bib_ptr); + END + END + TRACE_PR ("The style file is "); + if (bst_str == 0) + BEGIN + TRACE_PR_LN ("undefined"); + END + else + BEGIN + TRACE_PR_POOL_STR (bst_str); + TRACE_PR_POOL_STR (s_bst_extension); + TRACE_PR_NEWLINE; + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 457 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + +/*************************************************************************** + * WEB section number: 458 + * ~~~~~~~~~~~~~~~~~~~ + * In entry-sorted order, this prints an entry's |cite_list| string and, + * indirectly, its entry type and entry variables. + ***************************************************************************/ + BEGIN + if (all_entries) + BEGIN + TRACE_PR2 ("all_marker=%ld, ", (long) all_marker); + END + if (read_performed) + BEGIN + TRACE_PR_LN2 ("old_num_cites=%ld", (long) old_num_cites); + END + else + BEGIN + TRACE_PR_NEWLINE; + END + TRACE_PR2 ("The %ld", (long) num_cites); + if (num_cites == 1) + BEGIN + TRACE_PR_LN (" entry:"); + END + else + BEGIN + TRACE_PR_LN (" entries:"); + END + if (num_cites == 0) + BEGIN + TRACE_PR_LN (" undefined"); + END + else + BEGIN + sort_cite_ptr = 0; + while (sort_cite_ptr < num_cites) + BEGIN + if ( ! read_completed) + BEGIN + cite_ptr = sort_cite_ptr; + END + else + BEGIN + cite_ptr = SORTED_CITES[sort_cite_ptr]; + END + TRACE_PR_POOL_STR (CUR_CITE_STR); + if (read_performed) + +/*************************************************************************** + * WEB section number: 458 + * ~~~~~~~~~~~~~~~~~~~ + * This prints information gathered while reading the .bst and + * .bib files. + ***************************************************************************/ + BEGIN + TRACE_PR (", entry-type "); + if (type_list[cite_ptr] == UNDEFINED) + BEGIN + TRACE_PR ("unknown"); + END + else if (type_list[cite_ptr] == EMPTY) + BEGIN + TRACE_PR ("--- no type found"); + END + else + BEGIN + TRACE_PR_POOL_STR (hash_text[type_list[cite_ptr]]); + END + TRACE_PR_LN (", has entry strings"); + +/*************************************************************************** + * WEB section number: 460 + * ~~~~~~~~~~~~~~~~~~~ + * This prints, for the current entry, the strings declared by the + * entry command. + ***************************************************************************/ + BEGIN + if (num_ent_strs == 0) + BEGIN + TRACE_PR_LN (" undefined"); + END + else if ( ! read_completed) + BEGIN + TRACE_PR_LN (" uninitialized"); + END + else + BEGIN + str_ent_ptr = cite_ptr * num_ent_strs; + while (str_ent_ptr < ((cite_ptr + 1) * num_ent_strs)) + BEGIN + ent_chr_ptr = 0; + TRACE_PR (" \""); + + while (ENTRY_STRS(str_ent_ptr, ent_chr_ptr) != END_OF_STRING) + BEGIN + TRACE_PR2 ("%c", + xchr[ENTRY_STRS(str_ent_ptr, ent_chr_ptr)]); + INCR (ent_chr_ptr); + END + TRACE_PR_LN ("\""); + INCR (str_ent_ptr); + END + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 460 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + TRACE_PR (" has entry integers"); + +/*************************************************************************** + * WEB section number: 461 + * ~~~~~~~~~~~~~~~~~~~ + * This prints, for the current entry, the integers declared by the + * entry command. + ***************************************************************************/ + BEGIN + if (num_ent_ints == 0) + BEGIN + TRACE_PR (" undefined"); + END + else if ( ! read_completed) + BEGIN + TRACE_PR (" uninitialized"); + END + else + BEGIN + int_ent_ptr = cite_ptr * num_ent_ints; + while (int_ent_ptr < ((cite_ptr + 1) * num_ent_ints)) + BEGIN + TRACE_PR2 (" %ld", (long) entry_ints[int_ent_ptr]); + INCR (int_ent_ptr); + END + END + TRACE_PR_NEWLINE; + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 461 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + TRACE_PR_LN (" and has fields"); + +/*************************************************************************** + * WEB section number: 462 + * ~~~~~~~~~~~~~~~~~~~ + * This prints the fields stored for the current entry. + ***************************************************************************/ + BEGIN + if ( ! read_performed) + BEGIN + TRACE_PR_LN (" uninitialized"); + END + else + BEGIN + field_ptr = cite_ptr * num_fields; + field_end_ptr = field_ptr + num_fields; + no_fields = TRUE; + while (field_ptr < field_end_ptr) + BEGIN + if (field_info[field_ptr] != MISSING) + BEGIN + TRACE_PR (" \""); + TRACE_PR_POOL_STR (field_info[field_ptr]); + TRACE_PR_LN ("\""); + no_fields = FALSE; + END + INCR (field_ptr); + END + if (no_fields) + BEGIN + TRACE_PR_LN (" missing"); + END + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 462 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 459 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + else + BEGIN + TRACE_PR_NEWLINE; + END + INCR (sort_cite_ptr); + END + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 458 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + +/*************************************************************************** + * WEB section number: 463 + * ~~~~~~~~~~~~~~~~~~~ + * This gives all the |wiz_defined| functions that appeared in the + * .bst file. + ***************************************************************************/ + BEGIN + TRACE_PR_LN ("The wiz-defined functions are"); + if (wiz_def_ptr == 0) + BEGIN + TRACE_PR_LN (" nonexistent"); + END + else + BEGIN + wiz_fn_ptr = 0; + + while (wiz_fn_ptr < wiz_def_ptr) + BEGIN + if (wiz_functions[wiz_fn_ptr] == END_OF_DEF) + BEGIN + TRACE_PR_LN2 ("%ld--end-of-def--", (long) wiz_fn_ptr); + END + else if (wiz_functions[wiz_fn_ptr] == QUOTE_NEXT_FN) + BEGIN + TRACE_PR2 ("%ld quote_next_function ", (long) wiz_fn_ptr); + END + else + BEGIN + TRACE_PR2 ("%ld `", (long) wiz_fn_ptr); + TRACE_PR_POOL_STR (hash_text[wiz_functions[wiz_fn_ptr]]); + TRACE_PR_LN ("'"); + END + INCR (wiz_fn_ptr); + END + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 463 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + +/*************************************************************************** + * WEB section number: 464 + * ~~~~~~~~~~~~~~~~~~~ + * This includes all the `static' strings (that is, those that are also + * in the hash table), but none of the dynamic strings (that is, those + * put on the stack while executing .bst commands). + ***************************************************************************/ + BEGIN + TRACE_PR_LN ("The string pool is"); + str_num = 1; + + while (str_num < str_ptr) + BEGIN + TRACE_PR3 ("%4ld%6ld \"", (long) str_num, (long) str_start[str_num]); + TRACE_PR_POOL_STR (str_num); + TRACE_PR_LN ("\""); + INCR (str_num); + END + END + } /* end if (Flag_trace) */ + +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 464 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + +#endif /* TRACE */ + + +#ifdef STAT + +/*************************************************************************** + * WEB section number: 465 + * ~~~~~~~~~~~~~~~~~~~ + * These statistics can help determine how large some of the constants + * should be and can tell how useful certain |built_in| functions are. + * They are written to the same files as tracing information. + ***************************************************************************/ + if (Flag_stats) { + BEGIN + STAT_PR2 ("You've used %ld", (long) num_cites); + if (num_cites == 1) + BEGIN + STAT_PR_LN (" entry,"); + END + else + BEGIN + STAT_PR_LN (" entries,"); + END + STAT_PR_LN2 (" %ld wiz_defined-function locations,", + (long) wiz_def_ptr); + STAT_PR_LN3 (" %ld strings with %ld characters,", + (long) str_ptr, (long) str_start[str_ptr]); + blt_in_ptr = 0; + total_ex_count = 0; + while (blt_in_ptr < NUM_BLT_IN_FNS) + BEGIN + total_ex_count = total_ex_count + execution_count[blt_in_ptr]; + INCR (blt_in_ptr); + END + STAT_PR_LN2 ("and the built_in function-call counts, %ld in all, are:", + (long) total_ex_count); + blt_in_ptr = 0; + while (blt_in_ptr < NUM_BLT_IN_FNS) + BEGIN + STAT_PR_POOL_STR (hash_text[blt_in_loc[blt_in_ptr]]); + STAT_PR_LN2 (" -- %ld", (long) execution_count[blt_in_ptr]); + INCR (blt_in_ptr); + END + END + } /* end if (Flag_stats) */ + +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 465 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + +#endif /* STAT */ +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 456 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 159 + * ~~~~~~~~~~~~~~~~~~~ + * This version is for printing when in |trace| mode. + ***************************************************************************/ +#ifdef TRACE +void trace_pr_fn_class (HashLoc_T fn_loc) +BEGIN + + if (!Flag_trace) + return; + + switch (fn_type[fn_loc]) + BEGIN + case BUILT_IN: + TRACE_PR ("built-in"); + break; + case WIZ_DEFINED: + TRACE_PR ("wizard-defined"); + break; + case INT_LITERAL: + TRACE_PR ("integer-literal"); + break; + case STR_LITERAL: + TRACE_PR ("string-literal"); + break; + case FIELD: + TRACE_PR ("field"); + break; + case INT_ENTRY_VAR: + TRACE_PR ("integer-entry-variable"); + break; + case STR_ENTRY_VAR: + TRACE_PR ("string-entry-variable"); + break; + case INT_GLOBAL_VAR: + TRACE_PR ("integer-global-variable"); + break; + case STR_GLOBAL_VAR: + TRACE_PR ("string-global-variable"); + break; + default: + unknwn_function_class_confusion (); + break; + END +END +#endif /* TRACE */ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 159 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + + +/*************************************************************************** + * WEB section number: 157 + * ~~~~~~~~~~~~~~~~~~~ + * Here's another bug report. + ***************************************************************************/ +void unknwn_function_class_confusion (void) +BEGIN + CONFUSION ("Unknown function class"); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 157 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 310 + * ~~~~~~~~~~~~~~~~~~~ + * More bug complaints, this time about bad literals. + ***************************************************************************/ +void unknwn_literal_confusion (void) +BEGIN + CONFUSION ("Unknown literal type"); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 310 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 63 + * ~~~~~~~~~~~~~~~~~~~ + * This system-independent procedure is the same as the previous except + * that it converts lower- to upper-case letters. + ***************************************************************************/ +void upper_case (BufType_T buf, BufPointer_T bf_ptr, + BufPointer_T len) +BEGIN + BufPointer_T i; + + if (len > 0) + BEGIN + for (i = bf_ptr; i <= (bf_ptr+len-1); i++) + BEGIN + +#ifdef SUPPORT_8BIT + if (IsLower (buf[i])) + BEGIN + buf[i] = ToUpper(buf[i]); + END +#else /* NOT SUPPORT_8BIT */ + if ((buf[i] >= 'a') && (buf[i] <= 'z')) + BEGIN + buf[i] = buf[i] - CASE_DIFFERENCE; + END +#endif /* SUPPORT_8BIT */ + + END + END +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 63 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 401 + * ~~~~~~~~~~~~~~~~~~~ + * The last name starts just past the last token, before the first + * |comma| (if there is no |comma|, there is deemed to be one at the end + * of the string), for which there exists a first brace-level-0 letter + * (or brace-level-1 special character), and it's in lower case, unless + * this last token is also the last token before the |comma|, in which + * case the last name starts with this token (unless this last token is + * connected by a |sep_char| other than a |tie| to the previous token, in + * which case the last name starts with as many tokens earlier as are + * connected by non|tie|s to this last one (except on Tuesdays + * $\ldots\,$), although this module never sees such a case). Note that + * if there are any tokens in either the von or last names, then the last + * name has at least one, even if it starts with a lower-case letter. + ***************************************************************************/ +void von_name_ends_and_last_name_sta (void) +BEGIN + von_end = last_end - 1; + while (von_end > von_start) + BEGIN + name_bf_ptr = name_tok[von_end - 1]; + name_bf_xptr = name_tok[von_end]; + if (von_token_found ()) + BEGIN + goto Exit_Label; + END + DECR (von_end); + END +Exit_Label: DO_NOTHING; +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 401 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 397 + * ~~~~~~~~~~~~~~~~~~~ + * It's a von token if there exists a first brace-level-0 letter (or + * brace-level-1 special character), and it's in lower case; in this case + * we return |true|. The token is in |name_buf|, starting at + * |name_bf_ptr| and ending just before |name_bf_xptr|. + ***************************************************************************/ +Boolean_T von_token_found (void) +BEGIN + Boolean_T von_token_found; + + nm_brace_level = 0; + von_token_found = FALSE; + while (name_bf_ptr < name_bf_xptr) + BEGIN + +#ifdef SUPPORT_8BIT + if IsUpper(NAME_BUF[name_bf_ptr]) + BEGIN + goto Exit_Label; + END + else if IsLower(NAME_BUF[name_bf_ptr]) + BEGIN + RETURN_VON_FOUND; + END +#else /* NOT SUPPORT_8BIT */ + if ((NAME_BUF[name_bf_ptr] >= 'A') && (NAME_BUF[name_bf_ptr] <= 'Z')) + BEGIN + goto Exit_Label; + END + else if ((NAME_BUF[name_bf_ptr] >= 'a') && (NAME_BUF[name_bf_ptr] <= 'z')) + BEGIN + RETURN_VON_FOUND; + END +#endif /* SUPPORT_8BIT */ + + else if (NAME_BUF[name_bf_ptr] == LEFT_BRACE) + BEGIN + INCR (nm_brace_level); + INCR (name_bf_ptr); + if (((name_bf_ptr + 2) < name_bf_xptr) + && (NAME_BUF[name_bf_ptr] == BACKSLASH)) + +/*************************************************************************** + * WEB section number: 398 + * ~~~~~~~~~~~~~~~~~~~ + * When we come here |name_bf_ptr| is just past the |left_brace|, + * but we always leave by |return|ing. + ***************************************************************************/ + BEGIN + INCR (name_bf_ptr); + name_bf_yptr = name_bf_ptr; + while ((name_bf_ptr < name_bf_xptr) + && (lex_class[NAME_BUF[name_bf_ptr]] == ALPHA)) + BEGIN + INCR (name_bf_ptr); + END + control_seq_loc = str_lookup (NAME_BUF, name_bf_yptr, + name_bf_ptr - name_bf_yptr, + CONTROL_SEQ_ILK, DONT_INSERT); + if (hash_found) + +/*************************************************************************** + * WEB section number: 399 + * ~~~~~~~~~~~~~~~~~~~ + * The accented or foreign character is either `\i' or `\j' or + * one of the eleven alphabetic foreign characters in Table~3.2 of the + * \LaTeX\ manual. + ***************************************************************************/ + BEGIN + switch (ilk_info[control_seq_loc]) + BEGIN + case N_OE_UPPER: + case N_AE_UPPER: + case N_AA_UPPER: + case N_O_UPPER: + case N_L_UPPER: + goto Exit_Label; + case N_I: + case N_J: + case N_OE: + case N_AE: + case N_AA: + case N_O: + case N_L: + case N_SS: + RETURN_VON_FOUND; + default: + CONFUSION ("Control-sequence hash error"); + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 399 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + while ((name_bf_ptr < name_bf_xptr) && (nm_brace_level > 0)) + BEGIN + +#ifdef SUPPORT_8BIT + if IsUpper(NAME_BUF[name_bf_ptr]) + BEGIN + goto Exit_Label; + END + else if IsLower(NAME_BUF[name_bf_ptr]) + BEGIN + RETURN_VON_FOUND; + END +#else /* NOT SUPPORT_8BIT */ + if ((NAME_BUF[name_bf_ptr] >= 'A') && (NAME_BUF[name_bf_ptr] <= 'Z')) + BEGIN + goto Exit_Label; + END + else if ((NAME_BUF[name_bf_ptr] >= 'a') + && (NAME_BUF[name_bf_ptr] <= 'z')) + BEGIN + RETURN_VON_FOUND; + END +#endif /* SUPPORT_8BIT */ + + else if (NAME_BUF[name_bf_ptr] == RIGHT_BRACE) + BEGIN + DECR (nm_brace_level); + END + else if (NAME_BUF[name_bf_ptr] == LEFT_BRACE) + BEGIN + INCR (nm_brace_level); + END + INCR (name_bf_ptr); + END + goto Exit_Label; + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 398 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + else + +/*************************************************************************** + * WEB section number: 400 + * ~~~~~~~~~~~~~~~~~~~ + * When we come here |name_bf_ptr| is just past the |left_brace|; when we + * leave it's either at |name_bf_xptr| or just past the matching + * |right_brace|. + ***************************************************************************/ + BEGIN + while ((nm_brace_level > 0) && (name_bf_ptr < name_bf_xptr)) + BEGIN + if (NAME_BUF[name_bf_ptr] == RIGHT_BRACE) + BEGIN + DECR (nm_brace_level); + END + else if (NAME_BUF[name_bf_ptr] == LEFT_BRACE) + BEGIN + INCR (nm_brace_level); + END + INCR (name_bf_ptr); + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 400 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + END + else + BEGIN + INCR (name_bf_ptr); + END + END +Exit_Label: DO_NOTHING; + return (von_token_found); +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 397 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + + + +/*************************************************************************** + * WEB section number: 360 + * ~~~~~~~~~~~~~~~~~~~ + * The |built_in| function add.period$ pops the top (string) + * literal, adds a |period| to a nonnull string if its last + * non|right_brace| character isn't a |period|, |question_mark|, or + * |exclamation_mark|, and pushes this resulting string back onto the + * stack. If the literal isn't a string, it complains and pushes the + * null string. + ***************************************************************************/ +void x_add_period (void) +BEGIN + pop_lit_stk (&pop_lit1, &pop_typ1); + if (pop_typ1 != STK_STR) + BEGIN + print_wrong_stk_lit (pop_lit1, pop_typ1, STK_STR); + push_lit_stk (s_null, STK_STR); + END + else if (LENGTH (pop_lit1) == 0) + BEGIN + push_lit_stk (s_null, STK_STR); + END + else + +/*************************************************************************** + * WEB section number: 361 + * ~~~~~~~~~~~~~~~~~~~ + * Here we scan backwards from the end of the string, skipping + * non|right_brace| characters, to see if we have to add the |period|. + ***************************************************************************/ + BEGIN + sp_ptr = str_start[pop_lit1 + 1]; + sp_end = str_start[pop_lit1]; + while (sp_ptr > sp_end) + BEGIN + DECR (sp_ptr); + if (str_pool[sp_ptr] != RIGHT_BRACE) + BEGIN + goto Loop_Exit_Label; + END + END +Loop_Exit_Label: + switch (str_pool[sp_ptr]) + BEGIN + case PERIOD: + case QUESTION_MARK: + case EXCLAMATION_MARK: + REPUSH_STRING; + break; + default: + +/*************************************************************************** + * WEB section number: 362 + * ~~~~~~~~~~~~~~~~~~~ + * Ok guys, we really have to do it. + ***************************************************************************/ + BEGIN + if (pop_lit1 < cmd_str_ptr) + BEGIN + STR_ROOM (LENGTH (pop_lit1) + 1); + sp_ptr = str_start[pop_lit1]; + sp_end = str_start[pop_lit1 + 1]; + while (sp_ptr < sp_end) + BEGIN + APPEND_CHAR (str_pool[sp_ptr]); + INCR (sp_ptr); + END + END + else + BEGIN + pool_ptr = str_start[pop_lit1 + 1]; + STR_ROOM (1); + END + APPEND_CHAR (PERIOD); + push_lit_stk (make_string (), STK_STR); + break; + END + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 362 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 361 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + +END +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 360 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ |