/*-
******************************************************************************
******************************************************************************
**
**  MODULE
**
**      $RCSfile: bibtex-1.c,v $
**      $Revision: 3.71 $
**      $Date: 1996/08/18 20:47:30 $
**
**  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 first 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:
**
**          aux_err_stuff_after_right_brace
**          aux_err_white_space_in_argument
**          aux_input_command
**          bad_argument_token
**          bad_cross_reference_print
**          bib_cmd_confusion
**          bib_equals_sign_print
**          bib_err_print
**          bib_field_too_long_print
**          bib_id_print
**          bib_ln_num_print
**          bib_one_of_two_print
**          bib_unbalanced_braces_print
**          bib_warn_print
**          brace_lvl_one_letters_complaint
**          braces_unbalanced_complaint
**          bst_1print_string_size_exceeded
**          bst_2print_string_size_exceeded
**          bst_cant_mess_with_entries_prin
**          bst_entry_command
**          bst_err_print_and_look_for_blan
**          bst_execute_command
**          bst_ex_warn_print
**          bst_function_command
**          bst_id_print
**          bst_integers_command
**          build_in
**          case_conversion_confusion
**          check_brace_level
**          check_cite_overflow
**          check_command_execution
**          check_field_overflow
**          cite_key_disappeared_confusion
**          compress_bib_white
**          decr_brace_level
**          eat_bib_print
**          eat_bib_white_space
**          eat_bst_print
**          eat_bst_white_space
**          enough_text_chars
**
**  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-1.c,v $
**      Revision 3.71  1996/08/18  20:47:30  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.5  1995/09/24  20:44:37  kempson
**      Many changes for final beta test version.
**
**      Revision 3.4  1995/04/09  22:15:38  kempson
**      Placed under RCS control
**
******************************************************************************
******************************************************************************
*/
static char *rcsid = "$Id: bibtex-1.c,v 3.71 1996/08/18 20:47:30 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:	 61
 * ~~~~~~~~~~~~~~~~~~~
 * This procedure copies the default logical area name |area| into the
 * array |name_of_file| starting at position 1, after shifting up the rest
 * of the filename.  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          add_area (StrNumber_T area)
BEGIN
  PoolPointer_T       p_ptr;

  if ((name_length + LENGTH (area)) > FILE_NAME_SIZE)
  BEGIN
    PRINT ("File=");
    PRINT_POOL_STR (area);
    PRINT2 ("%s,", name_of_file);
    file_nm_size_overflow ();
  END
  name_ptr = name_length - 1;
  while (name_ptr >= 0)
  BEGIN
    name_of_file[name_ptr + LENGTH (area)] = name_of_file[name_ptr];
    DECR (name_ptr);
  END
  name_ptr = 0;
  p_ptr = str_start[area];
  while (p_ptr < str_start[area + 1])
  BEGIN
    name_of_file[name_ptr] = CHR (str_pool[p_ptr]);
    INCR (name_ptr);
    INCR (p_ptr);
  END
  name_length = name_length + LENGTH (area);
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION  61 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/



/***************************************************************************
 * WEB section number:	 320
 * ~~~~~~~~~~~~~~~~~~~
 * This procedure adds to the execution buffer the given string in
 * |str_pool| if it will fit.  It assumes the global variable
 * |ex_buf_length| gives the length of the current string in |ex_buf|, and
 * thus also gives the location of the next character.
 ***************************************************************************/
void          add_buf_pool (StrNumber_T p_str)
BEGIN
  p_ptr1 = str_start[p_str];
  p_ptr2 = str_start[p_str + 1];
  if ((ex_buf_length + (p_ptr2 - p_ptr1)) > BUF_SIZE)
  BEGIN
    buffer_overflow ();
  END
  ex_buf_ptr = ex_buf_length;
  while (p_ptr1 < p_ptr2)
  BEGIN
    APPEND_EX_BUF_CHAR(str_pool[p_ptr1]);
    INCR (p_ptr1);
  END
  ex_buf_length = ex_buf_ptr;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 320 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 265
 * ~~~~~~~~~~~~~~~~~~~
 * This procedure adds (or restores) to |cite_list| a cite key; it is
 * called only when |all_entries| is |true| or when adding
 * cross references, and it assumes that |cite_loc| and |lc_cite_loc| are
 * set.  It also INCRs its argument.
 ***************************************************************************/
void          add_database_cite (CiteNumber_T *new_cite)
BEGIN
  check_cite_overflow (*new_cite);
  check_field_overflow (num_fields * (*new_cite));
  cite_list[*new_cite] = hash_text[cite_loc];
  ilk_info[cite_loc] = *new_cite;
  ilk_info[lc_cite_loc] = cite_loc;
  INCR (*new_cite);
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 265 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	  60
 * ~~~~~~~~~~~~~~~~~~~
 * This procedure copies file extension |ext| into the array
 * |name_of_file| starting at position |name_length+1|.  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          add_extension (StrNumber_T ext)
BEGIN
  PoolPointer_T       p_ptr;

  if ((name_length + LENGTH (ext)) > FILE_NAME_SIZE)
  BEGIN
    PRINT2 ("File=%s, extension=", name_of_file);
    PRINT_POOL_STR (ext);
    PRINT_LN (",");
    file_nm_size_overflow ();
  END
  name_ptr = name_length;
  p_ptr = str_start[ext];
  while (p_ptr < str_start[ext + 1])
  BEGIN
    name_of_file[name_ptr] = CHR (str_pool[p_ptr]);
    INCR (name_ptr);
    INCR (p_ptr);
  END
  name_length = name_length + LENGTH (ext);
  name_ptr = name_length;
  while (name_ptr < FILE_NAME_SIZE)
  BEGIN
    name_of_file[name_ptr] = ' ';
    INCR (name_ptr);
  END
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION  60 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 322
 * ~~~~~~~~~~~~~~~~~~~
 * This procedure adds to the output buffer the given string in
 * |str_pool|.  It assumes the global variable |out_buf_length| gives the
 * length of the current string in |out_buf|, and thus also gives the
 * location for the next character.  If there are enough characters
 * present in the output buffer, it writes one or more lines out to the
 * .bbl file.  It may break a line at any |white_space| character it
 * likes, but if it does, it will add two |space|s to the next output
 * line.
 ***************************************************************************/
void          add_out_pool (StrNumber_T p_str)
BEGIN
  BufPointer_T      break_ptr;
  BufPointer_T      end_ptr;

  p_ptr1 = str_start[p_str];
  p_ptr2 = str_start[p_str + 1];
  if ((out_buf_length + (p_ptr2 - p_ptr1)) > BUF_SIZE)
  BEGIN
    BIBTEX_OVERFLOW ("output buffer size ", BUF_SIZE);
  END
  out_buf_ptr = out_buf_length;
  while (p_ptr1 < p_ptr2)
  BEGIN
    out_buf[out_buf_ptr] = str_pool[p_ptr1];
    INCR (p_ptr1);
    INCR (out_buf_ptr);
  END
  out_buf_length = out_buf_ptr;
  while (out_buf_length > MAX_PRINT_LINE)

/***************************************************************************
 * WEB section number:	 323
 * ~~~~~~~~~~~~~~~~~~~
 * Here we break the line by looking for a |white_space| character,
 * backwards from |out_buf[max_print_line]| until
 * |out_buf[min_print_line]|; we break at the |white_space| and indent
 * the next line two |space|s.  The next module handles things when
 * there's no |white_space| character to break at.
 ***************************************************************************/
  BEGIN
    end_ptr = out_buf_length;
    out_buf_ptr = MAX_PRINT_LINE;
    while ((lex_class[out_buf[out_buf_ptr]] != WHITE_SPACE)
        && (out_buf_ptr >= MIN_PRINT_LINE))
    BEGIN
      DECR (out_buf_ptr);
    END
    if (out_buf_ptr == (MIN_PRINT_LINE - 1))

/***************************************************************************
 * WEB section number:	 324
 * ~~~~~~~~~~~~~~~~~~~
 * If there's no |white_space| character to break the line at, we break
 * it at |out_buf[max_print_line-1]|, append a |comment| character, and
 * don't indent the next line.
 ***************************************************************************/
    BEGIN
      out_buf[end_ptr] = out_buf[MAX_PRINT_LINE - 1];
      out_buf[MAX_PRINT_LINE - 1] = COMMENT;
      out_buf_length = MAX_PRINT_LINE;
      break_ptr = out_buf_length - 1;
      output_bbl_line ();
      out_buf[MAX_PRINT_LINE - 1] = out_buf[end_ptr];
      out_buf_ptr = 0;
      tmp_ptr = break_ptr;
      while (tmp_ptr < end_ptr)
      BEGIN
        out_buf[out_buf_ptr] = out_buf[tmp_ptr];
        INCR (out_buf_ptr);
        INCR (tmp_ptr);
      END
      out_buf_length = end_ptr - break_ptr;
    END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 324 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

    else
    BEGIN
      out_buf_length = out_buf_ptr;
      break_ptr = out_buf_length + 1;
      output_bbl_line ();
      out_buf[0] = SPACE;
      out_buf[1] = SPACE;
      out_buf_ptr = 2;
      tmp_ptr = break_ptr;
      while (tmp_ptr < end_ptr)
      BEGIN
        out_buf[out_buf_ptr] = out_buf[tmp_ptr];
        INCR (out_buf_ptr);
        INCR (tmp_ptr);
      END
      out_buf_length = end_ptr - break_ptr + 2;
    END
  END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 323 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 322 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 318
 * ~~~~~~~~~~~~~~~~~~~
 * This procedure adds to |str_pool| the string from |ex_buf[0]| through
 * |ex_buf[ex_buf_length-1]| if it will fit.  It assumes the global
 * variable |ex_buf_length| gives the length of the current string in
 * |ex_buf|.  It then pushes this string onto the literal stack.
 ***************************************************************************/
void          add_pool_buf_and_push (void)
BEGIN
  STR_ROOM (ex_buf_length);
  ex_buf_ptr = 0;
  while (ex_buf_ptr < ex_buf_length)
  BEGIN
    APPEND_CHAR (ex_buf[ex_buf_ptr]);
    INCR (ex_buf_ptr);
  END
  push_lit_stk (make_string (), STK_STR);
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 318 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 169
 * ~~~~~~~~~~~~~~~~~~~
 * This macro complains if we've already encountered a function to be
 * inserted into the hash table.
 ***************************************************************************/
void          already_seen_function_print (HashLoc_T seen_fn_loc)
BEGIN
  PRINT_POOL_STR (hash_text[seen_fn_loc]);
  PRINT (" is already a type \"");
  print_fn_class (seen_fn_loc);
  PRINT_LN ("\" function name");
  BST_ERR_PRINT_AND_LOOK_FOR_BLAN;
Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 169 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 120
 * ~~~~~~~~~~~~~~~~~~~
 * A \bibdata command will have its arguments between braces and
 * separated by commas.  There must be exactly one such command in the
 * .aux file(s).  All upper-case letters are converted to lower case.
 ***************************************************************************/
void          aux_bib_data_command (void)
BEGIN
  if (bib_seen)
  BEGIN
    AUX_ERR_ILLEGAL_ANOTHER (N_AUX_BIBDATA);
  END
  bib_seen = TRUE;
  while (SCAN_CHAR != RIGHT_BRACE)
  BEGIN
    INCR (buf_ptr2);
    if ( ! scan2_white (RIGHT_BRACE, COMMA))
    BEGIN
      AUX_ERR_NO_RIGHT_BRACE;
    END
    if (lex_class[SCAN_CHAR] == WHITE_SPACE)
    BEGIN
      AUX_ERR_WHITE_SPACE_IN_ARGUMENT;
    END
    if ((last > (buf_ptr2 + 1)) && (SCAN_CHAR == RIGHT_BRACE))
    BEGIN
      AUX_ERR_STUFF_AFTER_RIGHT_BRACE;
    END

/***************************************************************************
 * WEB section number:	123
 * ~~~~~~~~~~~~~~~~~~~
 * Now we add the just-found argument to |bib_list| if it hasn't already
 * been encountered as a \bibdata argument and if, after appending
 * the |s_bib_extension| string, the resulting file name can be opened.
 ***************************************************************************/
    BEGIN
      if (bib_ptr == MAX_BIB_FILES)
      BEGIN
        BIBTEX_OVERFLOW ("number of database files ", MAX_BIB_FILES);
      END
      CUR_BIB_STR = hash_text[str_lookup (buffer, buf_ptr1, TOKEN_LEN,
  					  BIB_FILE_ILK, DO_INSERT)];
      if (hash_found)
      BEGIN
        OPEN_BIBDATA_AUX_ERR ("This database file appears more than once: ");
      END
      start_name (CUR_BIB_STR);
      add_extension (s_bib_extension);
      if ( ! a_open_in (&CUR_BIB_FILE, BIB_FILE_SEARCH_PATH))
      BEGIN
        add_area (s_bib_area);
	if ( ! a_open_in (&CUR_BIB_FILE, BIB_FILE_SEARCH_PATH))
        BEGIN
          OPEN_BIBDATA_AUX_ERR ("I couldn't open database file ");
          perror ("\nReason");
        END
      END

#ifdef TRACE
      if (Flag_trace) {
        TRACE_PR_POOL_STR (CUR_BIB_STR);
        TRACE_PR_POOL_STR (s_bib_extension);
        TRACE_PR_LN (" is a bibdata file");
      }
#endif                      			/* TRACE */

      INCR (bib_ptr);
    END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 123 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

  END
Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 120 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 126
 * ~~~~~~~~~~~~~~~~~~~
 * A \bibstyle command will have exactly one argument, and it will be
 * between braces.  There must be exactly one such command in the .aux
 * file(s).  All upper-case letters are converted to lower case.
 ***************************************************************************/
void          aux_bib_style_command (void)
BEGIN
  if (bst_seen)
  BEGIN
    AUX_ERR_ILLEGAL_ANOTHER (N_AUX_BIBSTYLE);
  END
  bst_seen = TRUE;
  INCR (buf_ptr2);
  if ( ! scan1_white (RIGHT_BRACE))
  BEGIN
    AUX_ERR_NO_RIGHT_BRACE;
  END
  if (lex_class[SCAN_CHAR] == WHITE_SPACE)
  BEGIN
    AUX_ERR_WHITE_SPACE_IN_ARGUMENT;
  END
  if (last > (buf_ptr2 + 1))
  BEGIN
    AUX_ERR_STUFF_AFTER_RIGHT_BRACE;
  END

/***************************************************************************
 * WEB section number:	127
 * ~~~~~~~~~~~~~~~~~~~
 * Now we open the file whose name is the just-found argument appended
 * with the |s_bst_extension| string, if possible.
 ***************************************************************************/
  BEGIN
    bst_str = hash_text[str_lookup (buffer, buf_ptr1, TOKEN_LEN,
				    BST_FILE_ILK, DO_INSERT)];
    if (hash_found)
    BEGIN

#ifdef TRACE
      if (Flag_trace)
        print_bst_name ();
#endif                      			/* TRACE */

      CONFUSION ("Already encountered style file");
    END
    start_name (bst_str);
    add_extension (s_bst_extension);
    if ( ! a_open_in (&bst_file, BST_FILE_SEARCH_PATH))
    BEGIN
      add_area (s_bst_area);
      if ( ! a_open_in (&bst_file, BST_FILE_SEARCH_PATH))
      BEGIN
	PRINT ("I couldn't open style file ");
	print_bst_name ();
        perror ("\nReason");
	bst_str = 0;
	AUX_ERR_RETURN;
      END
    END
    PRINT ("The style file: ");
    print_bst_name ();
  END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 127 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 126 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/





/***************************************************************************
 * WEB section number:	 132
 * ~~~~~~~~~~~~~~~~~~~
 * A \citation command will have its arguments between braces and
 * separated by commas.  Upper/lower cases are considered to be different
 * for \citation arguments, which is the same as the rest of \LaTeX\
 * but different from the rest of \BibTeX.  A cite key needn't exactly
 * case-match its corresponding database key to work, although two cite
 * keys that are case-mismatched will produce an error message.  (A BEGIN\sl
 * case mismatch\/END is a mismatch, but only because of a case difference.)
 *
 * A \citation command having * as an argument indicates that the
 * entire database will be included (almost as if a \nocite command
 * that listed every cite key in the database, in order, had been given at
 * the corresponding spot in the .tex file).
 ***************************************************************************/
void          aux_citation_command (void)
BEGIN
  citation_seen = TRUE;
  while (SCAN_CHAR != RIGHT_BRACE)
  BEGIN
    INCR (buf_ptr2);
    if ( ! scan2_white (RIGHT_BRACE, COMMA))
    BEGIN
      AUX_ERR_NO_RIGHT_BRACE;
    END
    if (lex_class[SCAN_CHAR] == WHITE_SPACE)
    BEGIN
      AUX_ERR_WHITE_SPACE_IN_ARGUMENT;
    END
    if ((last > (buf_ptr2 + 1)) && (SCAN_CHAR == RIGHT_BRACE))
    BEGIN
      AUX_ERR_STUFF_AFTER_RIGHT_BRACE;
    END

/***************************************************************************
 * WEB section number:	133
 * ~~~~~~~~~~~~~~~~~~~
 * We must check if (the lower-case version of) this cite key has been
 * previously encountered, and proceed accordingly.  The alias kludge
 * helps make the stack space not overflow on some machines.
 ***************************************************************************/
    BEGIN

#ifdef TRACE
      if (Flag_trace) {
        TRACE_PR_TOKEN;
        TRACE_PR (" cite key encountered");
      }
#endif                      			/* TRACE */

/***************************************************************************
 * WEB section number:	134
 * ~~~~~~~~~~~~~~~~~~~
 * Here we check for a \citation command having * as an
 * argument, indicating that the entire database will be included.
 ***************************************************************************/
      BEGIN
	if (TOKEN_LEN == 1)
	BEGIN
	  if (buffer[buf_ptr1] == STAR)
	  BEGIN

#ifdef TRACE
            if (Flag_trace)
              TRACE_PR_LN ("---entire database to be included");
#endif                      			/* TRACE */

	    if (all_entries)
	    BEGIN
	      PRINT_LN ("Multiple inclusions of entire database");
	      AUX_ERR_RETURN;
	    END
	    else
	    BEGIN
	      all_entries = TRUE;
	      all_marker = cite_ptr;
	      goto Next_Cite_Label;
	    END
	  END
	END
     END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 134 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

      tmp_ptr = buf_ptr1;
      while (tmp_ptr < buf_ptr2)
      BEGIN
	ex_buf[tmp_ptr] = buffer[tmp_ptr];
	INCR (tmp_ptr);
      END
      lower_case (ex_buf, buf_ptr1, TOKEN_LEN);
      lc_cite_loc = str_lookup (ex_buf, buf_ptr1, TOKEN_LEN, LC_CITE_ILK,
			      DO_INSERT);
      if (hash_found)

/***************************************************************************
 * WEB section number:	135
 * ~~~~~~~~~~~~~~~~~~~
 * We've previously encountered the lower-case version, so we check that
 * the actual version exactly matches the actual version of the
 * previously-encountered cite key(s).
 ***************************************************************************/
     BEGIN

#ifdef	TRACE
        if (Flag_trace)
	  TRACE_PR_LN (" previously");
#endif                      			/* TRACE */

	dummy_loc = str_lookup (buffer, buf_ptr1, TOKEN_LEN, CITE_ILK,
				DONT_INSERT);
	if ( ! hash_found)
	BEGIN
	  PRINT ("Case mismatch error between cite keys ");
	  PRINT_TOKEN;
	  PRINT (" and ");
	  PRINT_POOL_STR (cite_list[ilk_info[ilk_info[lc_cite_loc]]]);
	  PRINT_NEWLINE;
	  AUX_ERR_RETURN;
	END
      END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 135 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

      else

/***************************************************************************
 * WEB section number:	136
 * ~~~~~~~~~~~~~~~~~~~
 * Now we add the just-found argument to |cite_list| if there isn't
 * anything funny happening.
 ***************************************************************************/
      BEGIN

#ifdef TRACE
        if (Flag_trace)
	  TRACE_PR_NEWLINE;
#endif                      			/* TRACE */

	cite_loc = str_lookup (buffer, buf_ptr1, TOKEN_LEN, CITE_ILK,
			       DO_INSERT);
	if (hash_found)
	BEGIN
	  hash_cite_confusion ();
	END
	check_cite_overflow (cite_ptr);
	CUR_CITE_STR = hash_text[cite_loc];
	ilk_info[cite_loc] = cite_ptr;
	ilk_info[lc_cite_loc] = cite_loc;
	INCR (cite_ptr);
      END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 136 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
    END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 133 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/


Next_Cite_Label: DO_NOTHING
  END
Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 132 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 144
 * ~~~~~~~~~~~~~~~~~~~
 * We must complain if anything's amiss.
 ***************************************************************************/
void          aux_end1_err_print (void)
BEGIN
  PRINT ("I found no ");
END


void          aux_end2_err_print (void)
BEGIN
  PRINT ("---while reading file ");
  print_aux_name ();
  mark_error ();
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 144 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 112
 * ~~~~~~~~~~~~~~~~~~~
 * Here are a bunch of macros whose print statements are used at least
 * twice.  Thus we save space by making the statements procedures.  This
 * macro complains when there's a repeated command that's to be used just
 * once.
 ***************************************************************************/
void          aux_err_illegal_another_print (Integer_T cmd_num)
BEGIN
  PRINT ("Illegal, another \\bib");
  switch (cmd_num)
  BEGIN
    case N_AUX_BIBDATA:
      PRINT ("data");
      break;
    case N_AUX_BIBSTYLE:
      PRINT ("style");
      break;
    default:
      CONFUSION ("Illegal auxiliary-file command");
  END
  PRINT (" command");
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 112 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 113
 * ~~~~~~~~~~~~~~~~~~~
 * This one complains when a command is missing its |right_brace|.
 ***************************************************************************/
void          aux_err_no_right_brace_print (void)
BEGIN
  PRINT2 ("No \"%c\"", xchr[RIGHT_BRACE]);
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 113 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 111
 * ~~~~~~~~~~~~~~~~~~~
 * When we find a bug, we print a message and flush the rest of the line.
 * This macro must be called from within a procedure that has an |exit|
 * label.
 ***************************************************************************/
void          aux_err_print (void)
BEGIN
  PRINT2 ("---line %ld of file ", (long) CUR_AUX_LINE);
  print_aux_name ();
  print_bad_input_line ();
  print_skipping_whatever_remains ();
  PRINT_LN ("command");
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 111 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 114
 * ~~~~~~~~~~~~~~~~~~~
 * This one complains when a command has stuff after its |right_brace|.
 ***************************************************************************/
void          aux_err_stuff_after_right_brace (void)
BEGIN
  PRINT2 ("Stuff after \"%c\"", xchr[RIGHT_BRACE]);
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 114 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 115
 * ~~~~~~~~~~~~~~~~~~~
 * And this one complains when a command has |white_space| in its
 * argument.
 ***************************************************************************/
void          aux_err_white_space_in_argument (void)
BEGIN
  PRINT ("White space in argument");
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 115 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 139
 * ~~~~~~~~~~~~~~~~~~~
 * An \@input command will have exactly one argument, it will be
 * between braces, and it must have the |s_aux_extension|.  All upper-case
 * letters are converted to lower case.
 ***************************************************************************/
void          aux_input_command (void)
BEGIN
  Boolean_T         aux_extension_ok;

  INCR (buf_ptr2);
  if ( ! scan1_white (RIGHT_BRACE))
  BEGIN
    AUX_ERR_NO_RIGHT_BRACE;
  END
  if (lex_class[SCAN_CHAR] == WHITE_SPACE)
  BEGIN
    AUX_ERR_WHITE_SPACE_IN_ARGUMENT;
  END
  if (last > (buf_ptr2 + 1))
  BEGIN
    AUX_ERR_STUFF_AFTER_RIGHT_BRACE;
  END

/***************************************************************************
 * WEB section number:	140
 * ~~~~~~~~~~~~~~~~~~~
 * We must check that this potential .aux file won't overflow the
 * stack, that it has the correct extension, that we haven't encountered
 * it before (to prevent, among other things, an infinite loop).
 ***************************************************************************/
  BEGIN
    INCR (aux_ptr);
    if (aux_ptr == AUX_STACK_SIZE)
    BEGIN
      PRINT_TOKEN;
      PRINT (": ");
      BIBTEX_OVERFLOW ("auxiliary file depth ", AUX_STACK_SIZE);
    END
    aux_extension_ok = TRUE;
    if (TOKEN_LEN < LENGTH (s_aux_extension))
    BEGIN
      aux_extension_ok = FALSE;
    END
    else if ( ! str_eq_buf (s_aux_extension, buffer,
			    (buf_ptr2 - LENGTH (s_aux_extension)),
			    LENGTH (s_aux_extension)))
    BEGIN
      aux_extension_ok = FALSE;
    END
    if ( ! aux_extension_ok)
    BEGIN
      PRINT_TOKEN;
      PRINT (" has a wrong extension");
      DECR (aux_ptr);
      AUX_ERR_RETURN;
    END
    CUR_AUX_STR = hash_text[str_lookup (buffer, buf_ptr1, TOKEN_LEN,
					AUX_FILE_ILK, DO_INSERT)];
    if (hash_found)
    BEGIN
      PRINT ("Already encountered file ");
      print_aux_name ();
      DECR (aux_ptr);
      AUX_ERR_RETURN;
    END

/***************************************************************************
 * WEB section number:	141
 * ~~~~~~~~~~~~~~~~~~~
 * We check that this .aux file can actually be opened, and then open it.
 *
 * 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.
 ***************************************************************************/
    BEGIN
      start_name (CUR_AUX_STR);
      name_ptr = name_length;
      while (name_ptr < FILE_NAME_SIZE)
      BEGIN
	name_of_file[name_ptr] = ' ';
	INCR (name_ptr);
      END
      if ( ! a_open_in (&CUR_AUX_FILE, AUX_FILE_SEARCH_PATH))
      BEGIN
	PRINT ("I couldn't open auxiliary file ");
	print_aux_name ();
        perror ("\nReason");
	DECR (aux_ptr);
	AUX_ERR_RETURN;
      END
      PRINT2 ("A level-%ld auxilliary file: ", (long) aux_ptr);
      print_aux_name ();
      CUR_AUX_LINE = 0;
    END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 141 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 140 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 139 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 177
 * ~~~~~~~~~~~~~~~~~~~
 * A legal argument for an execute, iterate, or reverse
 * command must exist and be |built_in| or |wiz_defined|.  Here's where we
 * check, returning |true| if the argument is illegal.
 ***************************************************************************/
Boolean_T         bad_argument_token (void)
BEGIN
  Boolean_T       bad_argument_token;

  bad_argument_token= TRUE;
  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
    PRINT_TOKEN;
    BST_ERR (" is an unknown function");
  END
  else if ((fn_type[fn_loc] != BUILT_IN) && (fn_type[fn_loc] != WIZ_DEFINED))
  BEGIN
    PRINT_TOKEN;
    PRINT (" has bad function type ");
    print_fn_class (fn_loc);
    BST_ERR_PRINT_AND_LOOK_FOR_BLAN;
  END
  bad_argument_token= FALSE;

Exit_Label:
  return (bad_argument_token);
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 177 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 280
 * ~~~~~~~~~~~~~~~~~~~
 * This procedure exists to save space, since it's used twice---once for
 * each of the two succeeding modules.
 ***************************************************************************/
void          bad_cross_reference_print (StrNumber_T s)
BEGIN
  PRINT ("--entry \"");
  PRINT_POOL_STR (CUR_CITE_STR);
  PRINT_LN ("\"");
  PRINT ("refers to entry \"");
  PRINT_POOL_STR (s);
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 280 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 240
 * ~~~~~~~~~~~~~~~~~~~
 * Here's another bug.
 ***************************************************************************/
void          bib_cmd_confusion (void)
BEGIN
  CONFUSION ("Unknown database-file command");
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 240 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 231
 * ~~~~~~~~~~~~~~~~~~~
 * This one's for an expected |equals_sign|.
 ***************************************************************************/
void          bib_equals_sign_print (void)
BEGIN
  BIB_ERR2 ("I was expecting an \"%c\"", xchr[EQUALS_SIGN]);

Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 231 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 221
 * ~~~~~~~~~~~~~~~~~~~
 * When there's a serious error parsing a .bib file, we flush
 * everything up to the beginning of the next entry.
 ***************************************************************************/
void          bib_err_print (void)
BEGIN
  PRINT ("-");
  bib_ln_num_print ();
  print_bad_input_line ();
  print_skipping_whatever_remains ();
  if (at_bib_command)
  BEGIN
    PRINT_LN ("command");
  END
  else
  BEGIN
    PRINT_LN ("entry");
  END
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 221 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 233
 * ~~~~~~~~~~~~~~~~~~~
 * And this one about an overly exuberant field.
 ***************************************************************************/
void          bib_field_too_long_print (void)
BEGIN
  BIB_ERR2 ("Your field is more than %ld characters",  (long) BUF_SIZE);

Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 233 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 235
 * ~~~~~~~~~~~~~~~~~~~
 * This macro is used to scan all .bib identifiers.  The argument
 * tells what was happening at the time.  The associated procedure simply
 * prints an error message.
 ***************************************************************************/
void          bib_id_print (void)
BEGIN
  if (scan_result == ID_NULL)
  BEGIN
    PRINT ("You're missing ");
  END
  else if (scan_result == OTHER_CHAR_ADJACENT)
  BEGIN
    PRINT2 ("\"%c\" immediately follows ", xchr[SCAN_CHAR]);
  END
  else
  BEGIN
    id_scanning_confusion ();
  END
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 235 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 220
 * ~~~~~~~~~~~~~~~~~~~
 * This little procedure exists because it's used by at least two other
 * procedures and thus saves some space.
 ***************************************************************************/
void          bib_ln_num_print (void)
BEGIN
  PRINT2 ("--line %ld of file ", (long) bib_line_num);
  print_bib_name ();
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 220 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 230
 * ~~~~~~~~~~~~~~~~~~~
 * And here are a bunch of error-message macros, each called more than
 * once, that thus save space as implemented.  This one is for when one of
 * two possible characters is expected while scanning.
 ***************************************************************************/
void          bib_one_of_two_print (ASCIICode_T char1, ASCIICode_T char2)
BEGIN
  BIB_ERR3 ("I was expecting a `%c' or a `%c'", xchr[char1], xchr[char2]);
Exit_Label: DO_NOTHING
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 230 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 232
 * ~~~~~~~~~~~~~~~~~~~
 * This complains about unbalanced braces.
 ***************************************************************************/
void          bib_unbalanced_braces_print (void)
BEGIN
  BIB_ERR ("Unbalanced braces");
Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 232 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 222
 * ~~~~~~~~~~~~~~~~~~~
 * When there's a harmless error parsing a .bib file, we just give a
 * warning message.  This is always called after other stuff has been
 * printed out.
 ***************************************************************************/
void          bib_warn_print (void)
BEGIN
  bib_ln_num_print ();
  mark_warning ();
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 222 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 406
 * ~~~~~~~~~~~~~~~~~~~
 * At most one of the important letters, perhaps doubled, may appear at
 * |sp_brace_level = 1|.
 ***************************************************************************/
void          brace_lvl_one_letters_complaint (void)
BEGIN
  PRINT ("The format string \"");
  PRINT_POOL_STR (pop_lit1);
  BST_EX_WARN ("\" has an illegal brace-level-1 letter");
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 406 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 368
 * ~~~~~~~~~~~~~~~~~~~
 * This complaint often arises because the style designer has to type lots
 * of braces.
 ***************************************************************************/
void          braces_unbalanced_complaint (StrNumber_T pop_lit_var)
BEGIN
  PRINT ("Warning--\"");
  PRINT_POOL_STR (pop_lit_var);
  BST_MILD_EX_WARN ("\" isn't a brace-balanced string");
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 368 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 356
 * ~~~~~~~~~~~~~~~~~~~
 * It's time for a complaint if either of the two (entry or global) string
 * lengths is exceeded.
 ***************************************************************************/
void          bst_1print_string_size_exceeded (void)
BEGIN
  PRINT ("Warning--you've exceeded ");
END

void          bst_2print_string_size_exceeded (void)
BEGIN
  PRINT ("-string-size,");
  bst_mild_ex_warn_print ();
  PRINT_LN ("*Please notify the bibstyle designer*");
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 356 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 295
 * ~~~~~~~~~~~~~~~~~~~
 * It's illegal to mess with the entry information at certain times;
 * here's a complaint for these times.
 ***************************************************************************/
void          bst_cant_mess_with_entries_prin (void)
BEGIN
  BST_EX_WARN ("You can't mess with entries here");
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 295 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 170
 * ~~~~~~~~~~~~~~~~~~~
 * An entry command has three arguments, each a (possibly empty) list
 * of function names between braces (the names are separated by one or
 * more |white_space| characters).  All function names in this and other
 * commands must be legal .bst identifiers.  Upper/lower cases are
 * considered to be the same for function names in these lists---all
 * upper-case letters are converted to lower case.  These arguments give
 * lists of |field|s, |int_entry_var|s, and |str_entry_var|s.
 ***************************************************************************/
void          bst_entry_command (void)
BEGIN
  if (entry_seen)
  BEGIN
    BST_ERR ("Illegal, another entry command");
  END
  entry_seen = TRUE;
  EAT_BST_WHITE_AND_EOF_CHECK ("entry");

/***************************************************************************
 * WEB section number:	171
 * ~~~~~~~~~~~~~~~~~~~
 * This module reads a |left_brace|, the list of |field|s, and a
 * |right_brace|.  The |field|s are those like `author' and `title.'
 ***************************************************************************/
  BEGIN
    BST_GET_AND_CHECK_LEFT_BRACE ("entry");
    EAT_BST_WHITE_AND_EOF_CHECK ("entry");
    while (SCAN_CHAR != RIGHT_BRACE)
    BEGIN
      BST_IDENTIFIER_SCAN ("entry");

/***************************************************************************
 * WEB section number:	172
 * ~~~~~~~~~~~~~~~~~~~
 * Here we insert the just found field name into the hash table, record
 * it as a |field|, and assign it a number to be used in indexing into
 * the |field_info| array.
 ***************************************************************************/
      BEGIN

#ifdef TRACE
        if (Flag_trace) {
	  TRACE_PR_TOKEN;
	  TRACE_PR_LN (" is a field");
        }
#endif                      			/* TRACE */

	lower_case (buffer, buf_ptr1, TOKEN_LEN);
	fn_loc = str_lookup (buffer, buf_ptr1, TOKEN_LEN,
			     BST_FN_ILK, DO_INSERT);
	CHECK_FOR_ALREADY_SEEN_FUNCTION (fn_loc);
	fn_type[fn_loc] = FIELD;
	ilk_info[fn_loc] = num_fields;
	INCR (num_fields);
      END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 172 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/


      EAT_BST_WHITE_AND_EOF_CHECK ("entry");
    END
    INCR (buf_ptr2);
  END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 171 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

  EAT_BST_WHITE_AND_EOF_CHECK ("entry");
  if (num_fields == num_pre_defined_fields)
  BEGIN
    BST_WARN ("Warning--I didn't find any fields");
  END

/***************************************************************************
 * WEB section number:	173
 * ~~~~~~~~~~~~~~~~~~~
 * This module reads a |left_brace|, the list of |int_entry_var|s,
 * and a |right_brace|.
 ***************************************************************************/
  BEGIN
    BST_GET_AND_CHECK_LEFT_BRACE ("entry");
    EAT_BST_WHITE_AND_EOF_CHECK ("entry");
    while (SCAN_CHAR != RIGHT_BRACE)
    BEGIN
      BST_IDENTIFIER_SCAN ("entry");

/***************************************************************************
 * WEB section number:	174
 * ~~~~~~~~~~~~~~~~~~~
 * Here we insert the just found |int_entry_var| name into the hash table
 * and record it as an |int_entry_var|.  An |int_entry_var| is one that
 * the style designer wants a separate copy of for each entry.
 ***************************************************************************/
      BEGIN

#ifdef TRACE
        if (Flag_trace) {
	  TRACE_PR_TOKEN;
	  TRACE_PR_LN (" is an integer entry-variable");
        }
#endif                      			/* TRACE */

	lower_case (buffer, buf_ptr1, TOKEN_LEN);
	fn_loc = str_lookup (buffer, buf_ptr1, TOKEN_LEN,
			     BST_FN_ILK, DO_INSERT);
	CHECK_FOR_ALREADY_SEEN_FUNCTION (fn_loc);
	fn_type[fn_loc] = INT_ENTRY_VAR;
	FN_INFO[fn_loc] = num_ent_ints;
	INCR (num_ent_ints);
      END

/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 174 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

      EAT_BST_WHITE_AND_EOF_CHECK ("entry");
    END
    INCR (buf_ptr2);
  END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 173 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

  EAT_BST_WHITE_AND_EOF_CHECK ("entry");

/***************************************************************************
 * WEB section number:	175
 * ~~~~~~~~~~~~~~~~~~~
 * This module reads a |left_brace|, the list of |str_entry_var|s, and a
 * |right_brace|.  A |str_entry_var| is one that the style designer wants
 * a separate copy of for each entry.
 ***************************************************************************/
  BEGIN
    BST_GET_AND_CHECK_LEFT_BRACE ("entry");
    EAT_BST_WHITE_AND_EOF_CHECK ("entry");
    while (SCAN_CHAR != RIGHT_BRACE)
    BEGIN
      BST_IDENTIFIER_SCAN ("entry");

/***************************************************************************
 * WEB section number:	176
 * ~~~~~~~~~~~~~~~~~~~
 * Here we insert the just found |str_entry_var| name into the hash
 * table, record it as a |str_entry_var|, and set its pointer into
 * |entry_strs|.
 ***************************************************************************/
      BEGIN
#ifdef TRACE
        if (Flag_trace) {
	  TRACE_PR_TOKEN;
	  TRACE_PR_LN (" is a string entry-variable");
        }
#endif                      			/* TRACE */

	lower_case (buffer, buf_ptr1, TOKEN_LEN);
	fn_loc = str_lookup (buffer, buf_ptr1, TOKEN_LEN,
			     BST_FN_ILK, DO_INSERT);
	CHECK_FOR_ALREADY_SEEN_FUNCTION (fn_loc);
	fn_type[fn_loc] = STR_ENTRY_VAR;
	FN_INFO[fn_loc] = num_ent_strs;
	INCR (num_ent_strs);
      END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 176 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

      EAT_BST_WHITE_AND_EOF_CHECK ("entry");
    END
    INCR (buf_ptr2);
  END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 175 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 170 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 149
 * ~~~~~~~~~~~~~~~~~~~
 * When there's a serious error parsing the .bst file, we flush the
 * rest of the current command; a blank line is assumed to mark the end of
 * a command (but for the purposes of error recovery only).  Thus, error
 * recovery will be better if style designers leave blank lines between
 * .bst commands.  This macro must be called from within a procedure
 * that has an |exit| label.
 ***************************************************************************/
void          bst_err_print_and_look_for_blan (void)
BEGIN
  PRINT ("-");
  bst_ln_num_print ();
  print_bad_input_line ();
  while (last != 0)
    if ( ! input_ln (bst_file))
    BEGIN
      longjmp (Bst_Done_Flag, 1);
    END
    else
    BEGIN
      INCR (bst_line_num);
    END
  buf_ptr2 = last;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 149 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 178
 * ~~~~~~~~~~~~~~~~~~~
 * An execute command has one argument, a single |built_in| or
 * |wiz_defined| function name between braces.  Upper/lower cases are
 * considered to be the same---all upper-case letters are converted to
 * lower case.  Also, we must make sure we've already seen a read
 * command.
 *
 * This module reads a |left_brace|, a single function to be executed, and
 * a |right_brace|.
 ***************************************************************************/
void          bst_execute_command (void)
BEGIN
  if ( ! read_seen)
  BEGIN
    BST_ERR ("Illegal, execute command before read command");
  END
  EAT_BST_WHITE_AND_EOF_CHECK ("execute");
  BST_GET_AND_CHECK_LEFT_BRACE ("execute");
  EAT_BST_WHITE_AND_EOF_CHECK ("execute");
  BST_IDENTIFIER_SCAN ("execute");


/***************************************************************************
 * WEB section number:	179
 * ~~~~~~~~~~~~~~~~~~~
 * Before executing the function, we must make sure it's a legal one.  It
 * must exist and be |built_in| or |wiz_defined|.
 ***************************************************************************/
  BEGIN

#ifdef TRACE
    if (Flag_trace) {
      TRACE_PR_TOKEN;
      TRACE_PR_LN (" is a to be executed function");
    }
#endif	                     			/* TRACE */

    if (bad_argument_token ())
    BEGIN
      goto Exit_Label;
    END
  END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 179 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

  EAT_BST_WHITE_AND_EOF_CHECK ("execute");
  BST_GET_AND_CHECK_RIGHT_BRACE ("execute");

/***************************************************************************
 * WEB section number:	296
 * ~~~~~~~~~~~~~~~~~~~
 * This module executes a single specified function once.  It can't do
 * anything with the entries.
 ***************************************************************************/
  BEGIN
    init_command_execution ();
    mess_with_entries = FALSE;
    execute_fn (fn_loc);
    check_command_execution ();
  END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 296 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 178 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 293
 * ~~~~~~~~~~~~~~~~~~~
 * When there's an error while executing .bst functions, what we do
 * depends on whether the function is messing with the entries.
 * Furthermore this error is serious enough to classify as an
 * |error_message| instead of a |warning_message|.  These messages (that
 * is, from |bst_ex_warn|) are meant both for the user and for the style
 * designer while debugging.
 ***************************************************************************/
void          bst_ex_warn_print (void)
BEGIN
  if (mess_with_entries)
  BEGIN
    PRINT (" for entry ");
    PRINT_POOL_STR (CUR_CITE_STR);
  END
  PRINT_NEWLINE;
  PRINT ("while executing-");
  bst_ln_num_print ();
  mark_error ();
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 293 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 180
 * ~~~~~~~~~~~~~~~~~~~
 * A function command has two arguments; the first is a |wiz_defined|
 * function name between braces.  Upper/lower cases are considered to be
 * the same---all upper-case letters are converted to lower case.  The
 * second argument defines this function.  It consists of a sequence of
 * functions, between braces, separated by |white_space| characters.
 * Upper/lower cases are considered to be the same for function names but
 * not for |str_literal|s.
 ***************************************************************************/
void          bst_function_command (void)
BEGIN
  EAT_BST_WHITE_AND_EOF_CHECK ("function");

/***************************************************************************
 * WEB section number:	181
 * ~~~~~~~~~~~~~~~~~~~
 * This module reads a |left_brace|, a |wiz_defined| function name, and
 * a |right_brace|.
 ***************************************************************************/
  BEGIN
    BST_GET_AND_CHECK_LEFT_BRACE ("function");
    EAT_BST_WHITE_AND_EOF_CHECK ("function");
    BST_IDENTIFIER_SCAN ("function");

/***************************************************************************
 * WEB section number:	182
 * ~~~~~~~~~~~~~~~~~~~
 * The function name must exist and be a new one; we mark it as
 * |wiz_defined|.  Also, see if it's the default entry-type function.
 ***************************************************************************/
    BEGIN
#ifdef TRACE
      if (Flag_trace) {
        TRACE_PR_TOKEN;
        TRACE_PR_LN (" is a wizard-defined function");
      }
#endif                      			/* TRACE */

      lower_case (buffer, buf_ptr1, TOKEN_LEN);
      wiz_loc = str_lookup (buffer, buf_ptr1, TOKEN_LEN, BST_FN_ILK,
			    DO_INSERT);
      CHECK_FOR_ALREADY_SEEN_FUNCTION (wiz_loc);
      fn_type[wiz_loc] = WIZ_DEFINED;
      if (hash_text[wiz_loc] == s_default)
      BEGIN
	b_default = wiz_loc;
      END
    END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 182 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

    EAT_BST_WHITE_AND_EOF_CHECK ("function");
    BST_GET_AND_CHECK_RIGHT_BRACE ("function");
  END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 181 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

  EAT_BST_WHITE_AND_EOF_CHECK ("function");
  BST_GET_AND_CHECK_LEFT_BRACE ("function");
  scan_fn_def (wiz_loc);
Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 180 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 166
 * ~~~~~~~~~~~~~~~~~~~
 * This macro is used to scan all .bst identifiers.  The argument
 * supplies the .bst command name.  The associated procedure simply
 * prints an error message.
 ***************************************************************************/
void          bst_id_print (void)
BEGIN
  if (scan_result == ID_NULL)
  BEGIN
    PRINT2 ("\"%c\" begins identifier, command: ", xchr[SCAN_CHAR]);
  END
  else if (scan_result == OTHER_CHAR_ADJACENT)
  BEGIN
    PRINT2 ("\"%c\" immediately follows identifier, command: ",
	    xchr[SCAN_CHAR]);
  END
  else
  BEGIN
    id_scanning_confusion ();
  END
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 166 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 201
 * ~~~~~~~~~~~~~~~~~~~
 * An integers command has one argument, a list of function names
 * between braces (the names are separated by one or more |white_space|
 * characters).  Upper/lower cases are considered to be the same for
 * function names in these lists---all upper-case letters are converted to
 * lower case.  Each name in this list specifies an |int_global_var|.
 * There may be several integers commands in the .bst file.
 *
 * This module reads a |left_brace|, a list of |int_global_var|s, and a
 * |right_brace|.
 ***************************************************************************/
void          bst_integers_command (void)
BEGIN
  EAT_BST_WHITE_AND_EOF_CHECK ("integers");
  BST_GET_AND_CHECK_LEFT_BRACE ("integers");
  EAT_BST_WHITE_AND_EOF_CHECK ("integers");
  while (SCAN_CHAR != RIGHT_BRACE)
  BEGIN
    BST_IDENTIFIER_SCAN ("integers");

/***************************************************************************
 * WEB section number:	202
 * ~~~~~~~~~~~~~~~~~~~
 * Here we insert the just found |int_global_var| name into the hash
 * table and record it as an |int_global_var|.  Also, we initialize it by
 * setting |FN_INFO[fn_loc]| to 0.
 ***************************************************************************/
    BEGIN

#ifdef TRACE
      if (Flag_trace) {
        TRACE_PR_TOKEN;
        TRACE_PR_LN (" is an integer global-variable");
      }
#endif                      			/* TRACE */

      lower_case (buffer, buf_ptr1, TOKEN_LEN);
      fn_loc = str_lookup (buffer, buf_ptr1, TOKEN_LEN,
			   BST_FN_ILK, DO_INSERT);
      CHECK_FOR_ALREADY_SEEN_FUNCTION (fn_loc);
      fn_type[fn_loc] = INT_GLOBAL_VAR;
      FN_INFO[fn_loc] = 0;
    END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 202 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

    EAT_BST_WHITE_AND_EOF_CHECK ("integers");
  END
  INCR (buf_ptr2);
Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 201 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/


/***************************************************************************
 * WEB section number:	 203
 * ~~~~~~~~~~~~~~~~~~~
 * An iterate command has one argument, a single |built_in| or
 * |wiz_defined| function name between braces.  Upper/lower cases are
 * considered to be the same---all upper-case letters are converted to
 * lower case.  Also, we must make sure we've already seen a read
 * command.
 *
 * This module reads a |left_brace|, a single function to be iterated, and
 * a |right_brace|.
 ***************************************************************************/
void          bst_iterate_command (void)
BEGIN
  if ( ! read_seen)
  BEGIN
    BST_ERR ("Illegal, iterate command before read command");
  END
  EAT_BST_WHITE_AND_EOF_CHECK ("iterate");
  BST_GET_AND_CHECK_LEFT_BRACE ("iterate");
  EAT_BST_WHITE_AND_EOF_CHECK ("iterate");
  BST_IDENTIFIER_SCAN ("iterate");

/***************************************************************************
 * WEB section number:	204
 * ~~~~~~~~~~~~~~~~~~~
 * Before iterating the function, we must make sure it's a legal one.  It
 * must exist and be |built_in| or |wiz_defined|.
 ***************************************************************************/
  BEGIN

#ifdef TRACE
    if (Flag_trace) {
      TRACE_PR_TOKEN;
      TRACE_PR_LN (" is a to be iterated function");
    }
#endif                      			/* TRACE */

    if (bad_argument_token ())
    BEGIN
      goto Exit_Label;
    END
  END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 204 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

  EAT_BST_WHITE_AND_EOF_CHECK ("iterate");
  BST_GET_AND_CHECK_RIGHT_BRACE ("iterate");

/***************************************************************************
 * WEB section number:	297
 * ~~~~~~~~~~~~~~~~~~~
 * This module iterates a single specified function for all entries
 * specified by |cite_list|.
 ***************************************************************************/
  BEGIN
    init_command_execution ();
    mess_with_entries = TRUE;
    sort_cite_ptr = 0;
    while (sort_cite_ptr < num_cites)
    BEGIN
      cite_ptr = SORTED_CITES[sort_cite_ptr];

#ifdef TRACE
      if (Flag_trace) {
        TRACE_PR_POOL_STR (hash_text[fn_loc]);
        TRACE_PR (" to be iterated on ");
        TRACE_PR_POOL_STR (CUR_CITE_STR);
        TRACE_PR_NEWLINE;
      }
#endif                      			/* TRACE */

      execute_fn (fn_loc);
      check_command_execution ();
      INCR (sort_cite_ptr);
    END
  END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 297 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 203 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 167
 * ~~~~~~~~~~~~~~~~~~~
 * This macro just makes sure we're at a |left_brace|.
 ***************************************************************************/
void          bst_left_brace_print (void)
BEGIN
  PRINT2 ("\"%c\" is missing in command: ", xchr[LEFT_BRACE]);
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 167 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 148
 * ~~~~~~~~~~~~~~~~~~~
 * This little procedure exists because it's used by at least two other
 * procedures and thus saves some space.
 ***************************************************************************/
void          bst_ln_num_print (void)
BEGIN
  PRINT2 ("--line %ld of file ", (long) bst_line_num);
  print_bst_name ();
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 148 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 205
 * ~~~~~~~~~~~~~~~~~~~
 * A macro command, like a function command, has two arguments;
 * the first is a macro name between braces.  The name must be a legal
 * .bst identifier.  Upper/lower cases are considered to be the
 * same---all upper-case letters are converted to lower case.  The second
 * argument defines this macro.  It consists of a |double_quote|-delimited
 * string (which must be on a single line) between braces, with optional
 * |white_space| characters between the braces and the |double_quote|s.
 * This |double_quote|-delimited string is parsed exactly as a
 * |str_literal| is for the function command.
 ***************************************************************************/
void          bst_macro_command (void)
BEGIN
  if (read_seen)
  BEGIN
    BST_ERR ("Illegal, macro command after read command");
  END
  EAT_BST_WHITE_AND_EOF_CHECK ("macro");

/***************************************************************************
 * WEB section number:	206
 * ~~~~~~~~~~~~~~~~~~~
 * This module reads a |left_brace|, a macro name, and a |right_brace|.
 ***************************************************************************/
  BEGIN
    BST_GET_AND_CHECK_LEFT_BRACE ("macro");
    EAT_BST_WHITE_AND_EOF_CHECK ("macro");
    BST_IDENTIFIER_SCAN ("macro");

/***************************************************************************
 * WEB section number:	207
 * ~~~~~~~~~~~~~~~~~~~
 * The macro name must be a new one; we mark it as |macro_ilk|.
 ***************************************************************************/
    BEGIN

#ifdef TRACE
      if (Flag_trace) {
        TRACE_PR_TOKEN;
        TRACE_PR_LN (" is a macro");
      }
#endif                      			/* TRACE */

      lower_case (buffer, buf_ptr1, TOKEN_LEN);
      macro_name_loc = str_lookup (buffer, buf_ptr1, TOKEN_LEN, MACRO_ILK,
				   DO_INSERT);
      if (hash_found)
      BEGIN
	PRINT_TOKEN;
	BST_ERR (" is already defined as a macro");
      END
      ilk_info[macro_name_loc] = hash_text[macro_name_loc];
    END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 207 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

    EAT_BST_WHITE_AND_EOF_CHECK ("macro");
    BST_GET_AND_CHECK_RIGHT_BRACE ("macro");
  END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 206 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

  EAT_BST_WHITE_AND_EOF_CHECK ("macro");

/***************************************************************************
 * WEB section number:	208
 * ~~~~~~~~~~~~~~~~~~~
 * This module reads a |left_brace|, the |double_quote|-delimited string
 * that defines this macro, and a |right_brace|.
 ***************************************************************************/
  BEGIN
    BST_GET_AND_CHECK_LEFT_BRACE ("macro");
    EAT_BST_WHITE_AND_EOF_CHECK ("macro");
    if (SCAN_CHAR != DOUBLE_QUOTE)
    BEGIN
       BST_ERR2 ("A macro definition must be %c-delimited",
		 xchr[DOUBLE_QUOTE]);
    END

/***************************************************************************
 * WEB section number:	209
 * ~~~~~~~~~~~~~~~~~~~
 * A macro definition-string is preceded by a |double_quote| and consists
 * of all characters on this line up to the next |double_quote|.  The
 * array |ilk_info| contains a pointer to this string for the macro name.
 ***************************************************************************/
    BEGIN
      INCR (buf_ptr2);
      if ( ! scan1 (DOUBLE_QUOTE))
      BEGIN
	BST_ERR2 ("There's no `%c' to end macro definition",
		   xchr[DOUBLE_QUOTE]);
      END

#ifdef TRACE
      if (Flag_trace) {
        TRACE_PR ("\"");
        TRACE_PR_TOKEN;
        TRACE_PR ("\"");
        TRACE_PR_LN (" is a macro string");
      }
#endif                      			/* TRACE */

      macro_def_loc = str_lookup (buffer, buf_ptr1, TOKEN_LEN, TEXT_ILK,
				  DO_INSERT);
      fn_type[macro_def_loc] = STR_LITERAL;
      ilk_info[macro_name_loc] = hash_text[macro_def_loc];
      INCR (buf_ptr2);
    END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 209 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

    EAT_BST_WHITE_AND_EOF_CHECK ("macro");
    BST_GET_AND_CHECK_RIGHT_BRACE ("macro");
  END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 208 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 205 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 294
 * ~~~~~~~~~~~~~~~~~~~
 * When an error is so harmless, we print a |warning_message| instead of
 * an |error_message|.
 ***************************************************************************/
void          bst_mild_ex_warn_print (void)
BEGIN
  if (mess_with_entries)
  BEGIN
    PRINT (" for entry ");
    PRINT_POOL_STR (CUR_CITE_STR);
  END
  PRINT_NEWLINE;
  BST_WARN ("while executing");
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 294 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 211
 * ~~~~~~~~~~~~~~~~~~~
 * The read command has no arguments so there's no more parsing to do.
 * We must make sure we haven't seen a read command before and we've
 * already seen an entry command.
 ***************************************************************************/
void          bst_read_command (void)
BEGIN
  if (read_seen)
  BEGIN
    BST_ERR ("Illegal, another read command");
  END
  read_seen = TRUE;
  if ( ! entry_seen)
  BEGIN
    BST_ERR ("Illegal, read command before entry command");
  END
  sv_ptr1 = buf_ptr2;
  sv_ptr2 = last;
  tmp_ptr = sv_ptr1;
  while (tmp_ptr < sv_ptr2)
  BEGIN
    sv_buffer[tmp_ptr] = buffer[tmp_ptr];
    INCR (tmp_ptr);
  END

/***************************************************************************
 * WEB section number:	223
 * ~~~~~~~~~~~~~~~~~~~
 * For all |num_bib_files| database files, we keep reading and processing
 * .bib entries until none left.
 ***************************************************************************/
  BEGIN

/***************************************************************************
 * WEB section number:	224
 * ~~~~~~~~~~~~~~~~~~~
 * We need to initialize the |field_info| array, and also various things
 * associated with the |cite_list| array (but not |cite_list| itself).
 ***************************************************************************/
    BEGIN

/***************************************************************************
 * WEB section number:	225
 * ~~~~~~~~~~~~~~~~~~~
 * This module initializes all fields of all entries to |missing|, the
 * value to which all fields are initialized.
 ***************************************************************************/
      BEGIN
	check_field_overflow (num_fields * num_cites);
	field_ptr = 0;
	while (field_ptr < Max_Fields)
	BEGIN
	  field_info[field_ptr] = MISSING;
	  INCR (field_ptr);
	END
      END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 225 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

/***************************************************************************
 * WEB section number:	227
 * ~~~~~~~~~~~~~~~~~~~
 * We must initialize the |type_list| array so that we can detect
 * duplicate (or missing) entries for cite keys on |cite_list|.  Also,
 * when we're to include the entire database, we use the array
 * |entry_exists| to detect those missing entries whose |cite_list| info
 * will (or to be more precise, might) be overwritten; and we use the
 * array |cite_info| to save the part of |cite_list| that will (might) be
 * overwritten.  We also use |cite_info| for counting cross~references
 * when it's appropriate---when an entry isn't otherwise to be included
 * on |cite_list| (that is, the entry isn't \cited or
 * \nocited).  Such an entry is included on the final |cite_list| if
 * it's cross~referenced at least |min_crossrefs| times.
 ***************************************************************************/
      BEGIN
	cite_ptr = 0;
	while (cite_ptr < Max_Cites)
	BEGIN
	  type_list[cite_ptr] = EMPTY;
	  cite_info[cite_ptr] = ANY_VALUE;
	  INCR (cite_ptr);
	END
	old_num_cites = num_cites;
	if (all_entries)
	BEGIN
	  cite_ptr = all_marker;
	  while (cite_ptr < old_num_cites)
	  BEGIN
	    cite_info[cite_ptr] = cite_list[cite_ptr];
	    entry_exists[cite_ptr] = FALSE;
	    INCR (cite_ptr);
	  END
	  cite_ptr = all_marker;
	END
	else
	BEGIN
	  cite_ptr = num_cites;
	  all_marker = ANY_VALUE;
	END
      END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 227 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
    END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 224 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

    read_performed = TRUE;
    bib_ptr = 0;
    while (bib_ptr < num_bib_files)
    BEGIN
      PRINT2 ("Database file #%ld: ", (long) bib_ptr + 1);
      print_bib_name ();
      bib_line_num = 0;
      buf_ptr2 = last;
      while ( ! feof (CUR_BIB_FILE))
      BEGIN
	get_bib_command_or_entry_and_pr ();
      END
      a_close (CUR_BIB_FILE);
      INCR (bib_ptr);
    END
    reading_completed = TRUE;

#ifdef TRACE
    if (Flag_trace)
      TRACE_PR_LN ("Finished reading the database file(s)");
#endif                      			/* TRACE */

/***************************************************************************
 * WEB section number:	276
 * ~~~~~~~~~~~~~~~~~~~
 * This gets things ready for further .bst processing.
 ***************************************************************************/
    BEGIN
      num_cites = cite_ptr;
      num_preamble_strings = preamble_ptr;

/***************************************************************************
 * WEB section number:	277
 * ~~~~~~~~~~~~~~~~~~~
 * Now we update any entry (here called a child entry) that
 * cross referenced another (here called a parent entry); this
 * cross referencing occurs when the child's crossref field (value)
 * consists of the parent's database key.  To do the update, we replace
 * the child's |missing| fields by the corresponding fields of the
 * parent.  Also, we make sure the crossref field contains the
 * case-correct version.  Finally, although it is technically illegal to
 * nest cross references, and although we give a warning (a few modules
 * hence) when someone tries, we do what we can to accommodate the
 * attempt.
 ***************************************************************************/
      BEGIN
	cite_ptr = 0;
	while (cite_ptr < num_cites)
	BEGIN
	  field_ptr = (cite_ptr * num_fields) + crossref_num;
	  if (field_info[field_ptr] != MISSING)
	  BEGIN
	    if (find_cite_locs_for_this_cite_ke (field_info[field_ptr]))
	    BEGIN
	      cite_loc = ilk_info[lc_cite_loc];
	      field_info[field_ptr] = hash_text[cite_loc];
	      cite_parent_ptr = ilk_info[cite_loc];
	      field_ptr = (cite_ptr * num_fields) + num_pre_defined_fields;
	      field_end_ptr = field_ptr - num_pre_defined_fields + num_fields;
	      field_parent_ptr = (cite_parent_ptr * num_fields)
				   + num_pre_defined_fields;
	      while (field_ptr < field_end_ptr)
	      BEGIN
		if (field_info[field_ptr] == MISSING)
		BEGIN
		  field_info[field_ptr] = field_info[field_parent_ptr];
		END
		INCR (field_ptr);
		INCR (field_parent_ptr);
	      END
	    END
	  END
	  INCR (cite_ptr);
	END
      END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 277 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

/***************************************************************************
 * WEB section number:	279
 * ~~~~~~~~~~~~~~~~~~~
 * Here we remove the crossref field value for each child whose
 * parent was cross referenced too few times.  We also issue any
 * necessary warnings arising from a bad cross reference.
 ***************************************************************************/
      BEGIN
	cite_ptr = 0;
	while (cite_ptr < num_cites)
	BEGIN
	  field_ptr = (cite_ptr * num_fields) + crossref_num;
	  if (field_info[field_ptr] != MISSING)
	  BEGIN
	    if ( ! find_cite_locs_for_this_cite_ke (field_info[field_ptr]))
	    BEGIN
	      if (cite_hash_found)
	      BEGIN
		hash_cite_confusion ();
	      END
	      non_existent_cross_reference_er ();
	      field_info[field_ptr] = MISSING;
	    END
	    else
	    BEGIN
	      if (cite_loc != ilk_info[lc_cite_loc])
	      BEGIN
		hash_cite_confusion ();
	      END
	      cite_parent_ptr = ilk_info[cite_loc];
	      if (type_list[cite_parent_ptr] == EMPTY)
	      BEGIN
		non_existent_cross_reference_er ();
		field_info[field_ptr] = MISSING;
	      END
	      else
	      BEGIN
		field_parent_ptr = (cite_parent_ptr * num_fields)
				    + crossref_num;
		if (field_info[field_parent_ptr] != MISSING)

/***************************************************************************
 * WEB section number:	282
 * ~~~~~~~~~~~~~~~~~~~
 * We also complain when an entry being cross referenced has a
 * non|missing| crossref field itself, but this one is just a
 * warning, not a full-blown error.
 ***************************************************************************/
		BEGIN
		  PRINT ("Warning--you've nested cross references");
		  bad_cross_reference_print (cite_list[cite_parent_ptr]);
		  PRINT_LN ("\", which also refers to something");
		  mark_warning ();
		END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 282 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

		if (( ! all_entries) && (cite_parent_ptr >= old_num_cites)
		      && (cite_info[cite_parent_ptr] < Min_Crossrefs))
		BEGIN
		  field_info[field_ptr] = MISSING;
		END
	      END
	    END
	  END
	  INCR (cite_ptr);
	END
      END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 279 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

/***************************************************************************
 * WEB section number:	283
 * ~~~~~~~~~~~~~~~~~~~
 * We remove (and give a warning for) each cite key on the original
 * |cite_list| without a corresponding database entry.  And we remove any
 * entry that was included on |cite_list| only because it was
 * cross~referenced, yet was cross~referenced fewer than |min_crossrefs|
 * times.  Throughout this module, |cite_ptr| points to the next cite key
 * to be checked and |cite_xptr| points to the next permanent spot on
 * |cite_list|.
 ***************************************************************************/
      BEGIN
	cite_ptr = 0;
	while (cite_ptr < num_cites)
	BEGIN
	  if (type_list[cite_ptr] == EMPTY)
	  BEGIN
	    print_missing_entry (CUR_CITE_STR);
	  END
	  else if ((all_entries) || (cite_ptr < old_num_cites)
		      || (cite_info[cite_ptr] >= Min_Crossrefs))
	  BEGIN
	    if (cite_ptr > cite_xptr)

/***************************************************************************
 * WEB section number:	285
 * ~~~~~~~~~~~~~~~~~~~
 * We have to move to its final resting place all the entry information
 * associated with the exact location in |cite_list| of this cite key.
 ***************************************************************************/
	    BEGIN
	      cite_list[cite_xptr] = cite_list[cite_ptr];
	      type_list[cite_xptr] = type_list[cite_ptr];
	      if ( ! find_cite_locs_for_this_cite_ke (cite_list[cite_ptr]))
	      BEGIN
		cite_key_disappeared_confusion ();
	      END
	      if (( ! cite_hash_found) || (cite_loc != ilk_info[lc_cite_loc]))
	      BEGIN
		hash_cite_confusion ();
	      END
	      ilk_info[cite_loc] = cite_xptr;
	      field_ptr = cite_xptr * num_fields;
	      field_end_ptr = field_ptr + num_fields;
	      tmp_ptr = cite_ptr * num_fields;
	      while (field_ptr < field_end_ptr)
	      BEGIN
		field_info[field_ptr] = field_info[tmp_ptr];
		INCR (field_ptr);
		INCR (tmp_ptr);
	      END
	    END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 285 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

	    INCR (cite_xptr);
	  END
	  INCR (cite_ptr);
	END
	num_cites = cite_xptr;
	if (all_entries)

/***************************************************************************
 * WEB section number:	286
 * ~~~~~~~~~~~~~~~~~~~
 * We need this module only when we're including the whole database.
 * It's for missing entries whose cite key originally resided in
 * |cite_list| at a spot that another cite key (might have) claimed.
 ***************************************************************************/
	BEGIN
	  cite_ptr = all_marker;
	  while (cite_ptr < old_num_cites)
	  BEGIN
	    if ( ! entry_exists[cite_ptr])
	    BEGIN
	      print_missing_entry (cite_info[cite_ptr]);
	    END
	    INCR (cite_ptr);
	  END
	END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 286 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

      END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 283 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

/***************************************************************************
 * WEB section number:	287
 * ~~~~~~~~~~~~~~~~~~~
 * This module initializes all |int_entry_var|s of all entries to 0, the
 * value to which all integers are initialized.
 ***************************************************************************/
      BEGIN
	if ((num_ent_ints * num_cites) > Max_Ent_Ints)
	BEGIN
	  PRINT2 ("%ld: ", (long) (num_ent_ints * num_cites));
	  BIBTEX_OVERFLOW ("total number of integer entry-variables ", Max_Ent_Ints);
	END
	int_ent_ptr = 0;
	while (int_ent_ptr < (num_ent_ints * num_cites))
	BEGIN
	  entry_ints[int_ent_ptr] = 0;
	  INCR (int_ent_ptr);
	END
      END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 287 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

/***************************************************************************
 * WEB section number:	288
 * ~~~~~~~~~~~~~~~~~~~
 * This module initializes all |str_entry_var|s of all entries to the
 * null string, the value to which all strings are initialized.
 ***************************************************************************/
      BEGIN
	if ((num_ent_strs * num_cites) > Max_Ent_Strs)
	BEGIN
	  PRINT2 ("%ld: ", (long) (num_ent_strs * num_cites));
	  BIBTEX_OVERFLOW ("total number of string entry-variables ", Max_Ent_Strs);
	END
	str_ent_ptr = 0;
	while (str_ent_ptr < (num_ent_strs * num_cites))
	BEGIN
	  ENTRY_STRS(str_ent_ptr,0) = END_OF_STRING;
	  INCR (str_ent_ptr);
	END
      END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 288 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

/***************************************************************************
 * WEB section number:	289
 * ~~~~~~~~~~~~~~~~~~~
 * The array |sorted_cites| initially specifies that the entries are to
 * be processed in order of cite-key occurrence.  The sort command
 * may change this to whatever it likes (which, we hope, is whatever the
 * style-designer instructs it to like).  We make |sorted_cites| an alias
 * to save space; this works fine because we're done with |cite_info|.
 ***************************************************************************/
      BEGIN
	cite_ptr = 0;
	while (cite_ptr < num_cites)
	BEGIN
	  SORTED_CITES[cite_ptr] = cite_ptr;
	  INCR (cite_ptr);
	END
      END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 289 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

    END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 276 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

    read_completed = TRUE;
  END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 223 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

  buf_ptr2 = sv_ptr1;
  last = sv_ptr2;
  tmp_ptr = buf_ptr2;
  while (tmp_ptr < last)
  BEGIN
    buffer[tmp_ptr] = sv_buffer[tmp_ptr];
    INCR (tmp_ptr);
  END
Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 211 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 212
 * ~~~~~~~~~~~~~~~~~~~
 * A reverse command has one argument, a single |built_in| or
 * |wiz_defined| function name between braces.  Upper/lower cases are
 * considered to be the same---all upper-case letters are converted to
 * lower case.  Also, we must make sure we've already seen a read
 * command.
 *
 * This module reads a |left_brace|, a single function to be iterated in
 * reverse, and a |right_brace|.
 ***************************************************************************/
void          bst_reverse_command (void)
BEGIN
  if ( ! read_seen)
  BEGIN
    BST_ERR ("Illegal, reverse command before read command");
  END
  EAT_BST_WHITE_AND_EOF_CHECK ("reverse");
  BST_GET_AND_CHECK_LEFT_BRACE ("reverse");
  EAT_BST_WHITE_AND_EOF_CHECK ("reverse");
  BST_IDENTIFIER_SCAN ("reverse");

/***************************************************************************
 * WEB section number:	213
 * ~~~~~~~~~~~~~~~~~~~
 * Before iterating the function, we must make sure it's a legal one.  It
 * must exist and be |built_in| or |wiz_defined|.
 ***************************************************************************/
  BEGIN

#ifdef TRACE
    if (Flag_trace) {
      TRACE_PR_TOKEN;
      TRACE_PR_LN (" is a to be iterated in reverse function");
    }
#endif                      			/* TRACE */

    if (bad_argument_token ())
    BEGIN
      goto Exit_Label;
    END
  END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 213 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

  EAT_BST_WHITE_AND_EOF_CHECK ("reverse");
  BST_GET_AND_CHECK_RIGHT_BRACE ("reverse");

/***************************************************************************
 * WEB section number:	298
 * ~~~~~~~~~~~~~~~~~~~
 * This module iterates a single specified function for all entries
 * specified by |cite_list|, but does it in reverse order.
 ***************************************************************************/
  BEGIN
    init_command_execution ();
    mess_with_entries = TRUE;
    if (num_cites > 0)
    BEGIN
      sort_cite_ptr = num_cites;
      REPEAT
      BEGIN
	DECR (sort_cite_ptr);
	cite_ptr = SORTED_CITES[sort_cite_ptr];

#ifdef TRACE
        if (Flag_trace) {
  	  TRACE_PR_POOL_STR (hash_text[fn_loc]);
	  TRACE_PR (" to be iterated in reverse on ");
	  TRACE_PR_POOL_STR (CUR_CITE_STR);
	  TRACE_PR_NEWLINE;
        }
#endif                      			/* TRACE */

	execute_fn (fn_loc);
	check_command_execution ();
      END UNTIL (sort_cite_ptr == 0);
    END
  END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 298 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 212 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/



/***************************************************************************
 * WEB section number:	 168
 * ~~~~~~~~~~~~~~~~~~~
 * And this one, a |right_brace|.
 ***************************************************************************/
void          bst_right_brace_print (void)
BEGIN
  PRINT2 ("\"%c\" is missing in command: ", xchr[RIGHT_BRACE]);
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 168 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/



/***************************************************************************
 * WEB section number:	 214
 * ~~~~~~~~~~~~~~~~~~~
 * The sort command has no arguments so there's no more parsing to do,
 * but we must make sure we've already seen a read command.
 ***************************************************************************/
void          bst_sort_command (void)
BEGIN
  if ( ! read_seen)
  BEGIN
    BST_ERR ("Illegal, sort command before read command");
  END

/***************************************************************************
 * WEB section number:	299
 * ~~~~~~~~~~~~~~~~~~~
 * This module sorts the entries based on sort.key$; it is a stable
 * sort.
 ***************************************************************************/
  BEGIN

#ifdef TRACE
    if (Flag_trace)
      TRACE_PR_LN ("Sorting the entries");
#endif                      			/* TRACE */

    if (num_cites > 1)
    BEGIN
      quick_sort (0, num_cites - 1);
    END

#ifdef TRACE
    if (Flag_trace)
      TRACE_PR_LN ("Done sorting");
#endif                      			/* TRACE */

  END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 299 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 214 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/



/***************************************************************************
 * WEB section number:	 215
 * ~~~~~~~~~~~~~~~~~~~
 * A strings command has one argument, a list of function names
 * between braces (the names are separated by one or more |white_space|
 * characters).  Upper/lower cases are considered to be the same for
 * function names in these lists---all upper-case letters are converted to
 * lower case.  Each name in this list specifies a |str_global_var|.
 * There may be several strings commands in the .bst file.
 *
 * This module reads a |left_brace|, a list of |str_global_var|s, and a
 * |right_brace|.
 ***************************************************************************/
void          bst_strings_command (void)
BEGIN
  EAT_BST_WHITE_AND_EOF_CHECK ("strings");
  BST_GET_AND_CHECK_LEFT_BRACE ("strings");
  EAT_BST_WHITE_AND_EOF_CHECK ("strings");
  while (SCAN_CHAR != RIGHT_BRACE)
  BEGIN
    BST_IDENTIFIER_SCAN ("strings");

/***************************************************************************
 * WEB section number:	216
 * ~~~~~~~~~~~~~~~~~~~
 * Here we insert the just found |str_global_var| name into the hash
 * table, record it as a |str_global_var|, set its pointer into
 * |global_strs|, and initialize its value there to the null string.
 ***************************************************************************/
    BEGIN

#ifdef TRACE
      if (Flag_trace) {
        TRACE_PR_TOKEN;
        TRACE_PR_LN (" is a string global-variable");
      }
#endif                      			/* TRACE */

      lower_case (buffer, buf_ptr1, TOKEN_LEN);
      fn_loc = str_lookup (buffer, buf_ptr1, TOKEN_LEN, BST_FN_ILK,
			   DO_INSERT);
      CHECK_FOR_ALREADY_SEEN_FUNCTION (fn_loc);
      fn_type[fn_loc] = STR_GLOBAL_VAR;
      FN_INFO[fn_loc] = num_glb_strs;
      if (num_glb_strs == MAX_GLOB_STRS)
      BEGIN
	BIBTEX_OVERFLOW ("number of string global-variables %ld", MAX_GLOB_STRS);
      END
      INCR (num_glb_strs);
    END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 216 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

      EAT_BST_WHITE_AND_EOF_CHECK ("strings");

  END
  INCR (buf_ptr2);
Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 215 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 150
 * ~~~~~~~~~~~~~~~~~~~
 * When there's a harmless error parsing the .bst file (harmless
 * syntactically, at least) we give just a |warning_message|.
 ***************************************************************************/
void          bst_warn_print (void)
BEGIN
  bst_ln_num_print ();
  mark_warning ();
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 150 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 46
 * ~~~~~~~~~~~~~~~~~~~
 * When a buffer overflows, it's time to complain (and then quit).
 ***************************************************************************/
void          buffer_overflow (void)
BEGIN
  BIBTEX_OVERFLOW ("buffer size ", BUF_SIZE);
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION  46 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 335
 * ~~~~~~~~~~~~~~~~~~~
 * This procedure inserts a |built_in| function into the hash table and
 * initializes the corresponding pre-defined string (of length at most
 * |longest_pds|).  The array |FN_INFO| contains a number from 0 through
 * the number of |built_in| functions minus 1 (i.e., |num_blt_in_fns - 1|
 * if we're keeping statistics); this number is used by a |case| statement
 * to execute this function and is used for keeping execution counts when
 * keeping statistics.
 ***************************************************************************/
void          build_in (PdsType_T pds, PdsLen_T len,
			HashLoc_T *fn_hash_loc, BltInRange_T blt_in_num)
BEGIN
  pre_define (pds, len, BST_FN_ILK);
  *fn_hash_loc = pre_def_loc;
  fn_type[*fn_hash_loc] = BUILT_IN;
  FN_INFO[*fn_hash_loc] = blt_in_num;

#ifdef STAT
  if (Flag_stats) {
    blt_in_loc[blt_in_num] = *fn_hash_loc;
    execution_count[blt_in_num] = 0;
  }
#endif                      			/* STAT */

END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 335 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 373
 * ~~~~~~~~~~~~~~~~~~~
 * Another bug complaint.
 ***************************************************************************/
void          case_conversion_confusion (void)
BEGIN
  CONFUSION ("Unknown type of case conversion");
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 373 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 369
 * ~~~~~~~~~~~~~~~~~~~
 * This one makes sure that |brace_level=0| (it's called at a point in a
 * string where braces must be balanced).
 ***************************************************************************/
void          check_brace_level (StrNumber_T pop_lit_var)
BEGIN
  if (brace_level > 0)
  BEGIN
    braces_unbalanced_complaint (pop_lit_var);
  END
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 369 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 138
 * ~~~~~~~~~~~~~~~~~~~
 * Complain if somebody's got a cite fetish.  This procedure is called
 * when were about to add another cite key to |cite_list|.  It assumes
 * that |cite_loc| gives the potential cite key's hash table location.
 ***************************************************************************/
void          check_cite_overflow (CiteNumber_T last_cite)
BEGIN
  if (last_cite == Max_Cites)
  BEGIN
    PRINT_POOL_STR (hash_text[cite_loc]);
    PRINT_LN (" is the key:");
    BIBTEX_OVERFLOW ("number of cite keys ", Max_Cites);
  END
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 138 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 317
 * ~~~~~~~~~~~~~~~~~~~
 * At the end of a .bst command-execution we check that the stack and
 * |str_pool| are still in good shape.
 ***************************************************************************/
void          check_command_execution (void)
BEGIN
  if (lit_stk_ptr != 0)
  BEGIN
    PRINT_LN2 ("ptr=%ld, stack=", (long) lit_stk_ptr);
    pop_whole_stack ();
    PRINT ("---the literal stack isn't empty");
    bst_ex_warn_print ();
  END
  if (cmd_str_ptr != str_ptr)
  BEGIN

#ifdef TRACE
    if (Flag_trace)
      TRACE_PR_LN3 ("Pointer is %ld but should be %ld", (long) str_ptr,
	  	    (long) cmd_str_ptr);
#endif                      			/* TRACE */

    CONFUSION ("Nonempty empty string stack");
  END
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 317 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 226
 * ~~~~~~~~~~~~~~~~~~~
 * Complain if somebody's got a field fetish.
 ***************************************************************************/
void          check_field_overflow (Integer_T total_fields)
BEGIN
  if (total_fields > Max_Fields)
  BEGIN
    PRINT_LN2 ("%ld fields:", (long) total_fields);
    BIBTEX_OVERFLOW ("total number of fields ", Max_Fields);
  END
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 226 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/



/***************************************************************************
 * WEB section number:	 271
 * ~~~~~~~~~~~~~~~~~~~
 * Here's another bug complaint.
 ***************************************************************************/
void          cite_key_disappeared_confusion (void)
BEGIN
  CONFUSION ("A cite key disappeared");
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 271 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 252
 * ~~~~~~~~~~~~~~~~~~~
 * The .bib-specific scanning function |compress_bib_white| skips over
 * |white_space| characters within a string until hitting a nonwhite
 * character; in fact, it does everything |eat_bib_white_space| does, but
 * it also adds a |space| to |field_vl_str|.  This function is never
 * called if there are no |white_space| characters (or ends-of-line) to be
 * scanned (though the associated macro might be).  The function returns
 * |false| if there is a serious syntax error.
 ***************************************************************************/
Boolean_T         compress_bib_white (void)
BEGIN
  Boolean_T       compress_bib_white;

  compress_bib_white = FALSE;
  COPY_CHAR (SPACE);
  while ( ! scan_white_space ())
  BEGIN
    if ( ! input_ln (CUR_BIB_FILE))
    BEGIN
      eat_bib_print ();
      goto Exit_Label;
    END
    INCR (bib_line_num);
    buf_ptr2 = 0;
  END
  compress_bib_white = TRUE;
Exit_Label: DO_NOTHING;
  return (compress_bib_white);
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 252 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 367
 * ~~~~~~~~~~~~~~~~~~~
 * This procedure complains if the just-encountered |right_brace| would
 * make |brace_level| negative.
 ***************************************************************************/
void          decr_brace_level (StrNumber_T pop_lit_var)
BEGIN
  if (brace_level == 0)
  BEGIN
    braces_unbalanced_complaint (pop_lit_var);
  END
  else
  BEGIN
    DECR (brace_level);
  END
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 367 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 229
 * ~~~~~~~~~~~~~~~~~~~
 * It's often illegal to end a .bib command in certain places, and
 * this is where we come to check.
 ***************************************************************************/
void          eat_bib_print (void)
BEGIN
  BIB_ERR (" Illegal end of database file");
Exit_Label: DO_NOTHING;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 229 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 228
 * ~~~~~~~~~~~~~~~~~~~
 * Before we actually start the code for reading a database file, we must
 * define this .bib-specific scanning function.  It skips over
 * |white_space| characters until hitting a nonwhite character or the end
 * of the file, respectively returning |true| or |false|.  It also updates
 * |bib_line_num|, the line counter.
 ***************************************************************************/
Boolean_T         eat_bib_white_space (void)
BEGIN
  Boolean_T       eat_bib_white_space;

  while ( ! scan_white_space ())
  BEGIN
    if ( ! input_ln (CUR_BIB_FILE))
    BEGIN
      eat_bib_white_space = FALSE;
      goto Exit_Label;
    END
    INCR (bib_line_num);
    buf_ptr2 = 0;
  END
  eat_bib_white_space = TRUE;
Exit_Label:
  return (eat_bib_white_space);
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 228 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 153
 * ~~~~~~~~~~~~~~~~~~~
 * It's often illegal to end a .bst command in certain places, and
 * this is where we come to check.
 ***************************************************************************/
void          eat_bst_print (void)
BEGIN
  PRINT ("Illegal end of style file in command: ");
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 153 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 152
 * ~~~~~~~~~~~~~~~~~~~
 * This .bst-specific scanning function skips over |white_space|
 * characters (and comments) until hitting a nonwhite character or the end
 * of the file, respectively returning |true| or |false|.  It also updates
 * |bst_line_num|, the line counter.
 ***************************************************************************/
Boolean_T         eat_bst_white_space (void)
BEGIN
  Boolean_T	  eat_bst_white_space;

  LOOP
  BEGIN
    if (scan_white_space ())
    BEGIN
      if (SCAN_CHAR != COMMENT)
      BEGIN
	eat_bst_white_space = TRUE;
	goto Exit_Label;
      END
    END
    if ( ! input_ln (bst_file))
    BEGIN
      eat_bst_white_space = FALSE;
      goto Exit_Label;
    END
    INCR (bst_line_num);
    buf_ptr2 = 0;
  END
Exit_Label:
  return (eat_bst_white_space);
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 152 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 418
 * ~~~~~~~~~~~~~~~~~~~
 * This function looks at the string in |ex_buf|, starting at
 * |ex_buf_xptr| and ending just before |ex_buf_ptr|, and it returns
 * |true| if there are |enough_chars|, where a special character (even if
 * it's missing its matching |right_brace|) counts as a single charcter.
 * This procedure is called only for strings that don't have too many
 * |right_brace|s.
 ***************************************************************************/
Boolean_T         enough_text_chars (BufPointer_T enough_chars)
BEGIN
  Boolean_T	  enough_text_chars;
  num_text_chars = 0;
  ex_buf_yptr = ex_buf_xptr;
  while ((ex_buf_yptr < ex_buf_ptr) && (num_text_chars < enough_chars))
  BEGIN
    INCR (ex_buf_yptr);
    if (ex_buf[ex_buf_yptr - 1] == LEFT_BRACE)
    BEGIN
      INCR (brace_level);
      if ((brace_level == 1) && (ex_buf_yptr < ex_buf_ptr))
      BEGIN
        if (ex_buf[ex_buf_yptr] == BACKSLASH)
        BEGIN
          INCR (ex_buf_yptr);
          while ((ex_buf_yptr < ex_buf_ptr) && (brace_level > 0))
          BEGIN
            if (ex_buf[ex_buf_yptr] == RIGHT_BRACE)
            BEGIN
              DECR (brace_level);
            END
            else if (ex_buf[ex_buf_yptr] == LEFT_BRACE)
            BEGIN
              INCR (brace_level);
            END
            INCR (ex_buf_yptr);
          END
        END
      END
    END
    else if (ex_buf[ex_buf_yptr - 1] == RIGHT_BRACE)
    BEGIN
      DECR (brace_level);
    END
    INCR (num_text_chars);
  END
  if (num_text_chars < enough_chars)
  BEGIN
    enough_text_chars = FALSE;
  END
  else
  BEGIN
    enough_text_chars = TRUE;
  END
  return (enough_text_chars);
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 418 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
