diff options
Diffstat (limited to 'Build/source/texk/bibtexu/utils.c')
-rw-r--r-- | Build/source/texk/bibtexu/utils.c | 2728 |
1 files changed, 0 insertions, 2728 deletions
diff --git a/Build/source/texk/bibtexu/utils.c b/Build/source/texk/bibtexu/utils.c deleted file mode 100644 index 44b3c82da32..00000000000 --- a/Build/source/texk/bibtexu/utils.c +++ /dev/null @@ -1,2728 +0,0 @@ -/*- -****************************************************************************** -****************************************************************************** -** -** MODULE -** -** $RCSfile: utils.c,v $ -** $Revision: 3.71 $ -** $Date: 1996/08/18 20:37:06 $ -** -** DESCRIPTION -** -** A 32-bit implementation of BibTeX v0.99c for MS-DOS, OS/2 2.x, -** Unix and VMS. This C language implementation is based on the -** original WEB source but it has been enhanced to support 8-bit input -** characters and a very large processing capacity. -** -** For documentation describing how to use and build this program, -** see the 00README.TXT file that accompanies this distribution. -** -** MODULE CONTENTS -** -** This module contains the new utility functions that will be used in -** the program. The functions are declared in alphabetical order. -** Functions defined in this module are: -** -** close_file -** debug_msg -** find_file -** open_ip_file -** open_op_file -** mymalloc -** myrealloc -** parse_cmd_line -** report_bibtex_capacity -** report_search_paths -** set_array_sizes -** usage -** -** 8-bit support functions: -** -** c8read_csf -** c8initialise -** c8read_lowercase -** c8read_lowupcase -** c8read_uppercase -** c8read_order -** c8report_8bit_handling -** -** 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: utils.c,v $ -** Revision 3.71 1996/08/18 20:37:06 kempson -** Official release 3.71 (see HISTORY file for details). -** -** Revision 3.70 1996/04/08 10:08:40 kempson -** Final documentation & cosmetic changes for official release 3.70. -** -** Revision 3.6 1995/10/21 22:20:42 kempson -** Fixed numerous bugs, improved error reporting and added the --wolfgang -** option. -** -** 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:43 kempson -** Placed under RCS control -** -****************************************************************************** -****************************************************************************** -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdarg.h> -#ifdef WIN32 -#include <getopt.h> -#else -#include <unistd.h> -#endif - -#ifdef KPATHSEA -#include <kpathsea/config.h> -#include <kpathsea/c-fopen.h> -#include <kpathsea/tex-file.h> -#include <kpathsea/paths.h> -#include <kpathsea/variable.h> -#include <kpathsea/lib.h> -#ifndef WIN32 -#include <kpathsea/getopt.h> -#endif -#endif - -#include "sysdep.h" -#include "bibtex.h" -#include "datatype.h" -#include "gblprocs.h" -#include "gblvars.h" -#include "utils.h" -#include "version.h" - - -/* -** Useful macros to keep the code nicely formatted. -*/ -#define FSE(_a) fprintf (stderr, _a); -#define FSO(_a) fprintf (TERM_OUT, _a); -#define LOG_CAPACITY(_a) \ - FPRINTF (log_file, " %-15s = %7ld\n", #_a, (long) _a) -#define ISEMPTYSTR(_a) ((_a == NULL) || (*_a == '\0')) -#define NULLCHECK(_a) (ISEMPTYSTR(_a) ? "<undefined>" : _a) - - -/*- -** Options supported by the program and parsed by getopt(). Each option -** can be specified by a "traditional" single character argument -** preceeded by a dash (e.g. "-7") or a more descriptive parameter -** preceeded by two dashes (e.g. "--ascii"). Each option is also defined -** as either not taking a value, optinally taking a value or requiring a -** value. -*/ -#define VALUE_NONE 0 -#define VALUE_REQD 1 -#define VALUE_OPT 2 - -static struct option long_options[] = { -#ifndef UTF_8 - {"8bit", VALUE_NONE, 0, '8'}, - {"csfile", VALUE_REQD, 0, 'c'}, -#endif - {"debug", VALUE_REQD, 0, 'd'}, - {"help", VALUE_NONE, 0, '?'}, - {"statistics", VALUE_NONE, 0, 's'}, - {"trace", VALUE_NONE, 0, 't'}, -#ifndef UTF_8 - {"traditional", VALUE_NONE, 0, '7'}, -#endif - {"version", VALUE_NONE, 0, 'v'}, - -#ifdef UTF_8 - {"language", VALUE_REQD, 0, 'l'}, - {"location", VALUE_REQD, 0, 'o'}, -#endif - - {"big", VALUE_NONE, 0, 'B'}, - {"huge", VALUE_NONE, 0, 'H'}, - {"wolfgang", VALUE_NONE, 0, 'W'}, - {"min_crossrefs", VALUE_REQD, 0, 'M'}, - - {"mcites", VALUE_REQD, 0, '\x0A'}, /* obsolete */ - {"mentints", VALUE_REQD, 0, '\x0B'}, /* obsolete */ - {"mentstrs", VALUE_REQD, 0, '\x0C'}, /* obsolete */ - {"mfields", VALUE_REQD, 0, '\x0D'}, /* obsolete */ - {"mpool", VALUE_REQD, 0, '\x0E'}, /* obsolete */ - {"mstrings", VALUE_REQD, 0, '\x0F'}, - {"mwizfuns", VALUE_REQD, 0, '\x10'}, /* obsolete */ - {0, 0, 0, 0} -}; - -static const char *getopt_str = -#ifndef UTF_8 - "78c:" -#endif - "d:?stv" -#ifdef UTF_8 - "l:o:" -#endif - "BHM:W"; - - - -/* -** Forward declaration of private functions and variables used in this -** module for 8-bit support. -*/ -#ifdef SUPPORT_8BIT -static int c8read_csf (void); -static void c8read_lowupcase (void); -static void c8read_lowercase (void); -static void c8read_order (void); -static void c8read_uppercase (void); -static void c8report_8bit_handling (void); - -static FILE *c8_cs_file; -static int c8_line; -static int sort_weight; -#endif /* SUPPORT_8BIT */ - - - -/*- -**============================================================================ -** allocate_arrays() -** -** Allocate memory dynamically for the large arrays whose size is fixed, -** regardless of the amount memory of memory available. If these arrays are -** declared statically, the linker will complain about an overflowing text -** segment. -** -** Allocate memory dynamically for the large arrays whose size is set -** dynamically, depending on the amount memory of memory available. -** -** AlphaFile_T bib_file[Max_Bib_Files + 1]; -** StrNumber_T bib_list[Max_Bib_Files + 1]; -** ASCIICode_T buffer[Buf_Size + 1]; -** StrNumber_T cite_info[Max_Cites + 1]; -** StrNumber_T cite_list[Max_Cites + 1]; -** Boolean_T entry_exists[Max_Cites + 1]; -** Integer_T entry_ints[Max_Ent_Ints + 1]; -** ASCIICode_T entry_strs[Max_Ent_Strs + 1][Ent_Str_Size + 1]; -** ASCIICode_T ex_buf[Buf_Size + 1]; -** StrNumber_T field_info[Max_Fields + 1]; -** FnClass_T fn_type[Hash_Size + 1]; -** Integer_T glb_str_end[Max_Glob_Strs]; -** StrNumber_T glb_str_ptr[Max_Glob_Strs]; -** ASCIICode_T global_strs[Max_Glob_Strs][Glob_Str_Size + 1];; -** StrIlk_T hash_ilk[Hash_Size + 1]; -** HashPointer_T hash_next[Hash_Size + 1]; -** StrNumber_T hash_text[Hash_Size + 1]; -** Integer_T ilk_info[Hash_Size + 1]; -** Integer_T lit_stack[Lit_Stk_Size + 1]; -** StkType_T lit_stk_type[Lit_Stk_Size + 1]; -** ASCIICode_T name_sep_char[Buf_Size + 1]; -** BufPointer_T name_tok[Buf_Size + 1]; -** ASCIICode_T out_buf[Buf_Size + 1]; -** StrNumber_T s_preamble[Max_Bib_Files + 1]; -** ASCIICode_T str_pool[Pool_Size + 1]; -** PoolPointer_T str_start[Max_Strings + 1]; -** ASCIICode_T sv_buffer[Buf_Size + 1]; -** HashPtr2_T type_list[Max_Cites + 1]; -** HashPtr2_T wiz_functions[Wiz_Fn_Space + 1]; -**============================================================================ -*/ -static void allocate_arrays (void) -{ - unsigned long bytes_required; - - debug_msg (DBG_MEM, "Starting to allocate memory for arrays ... "); - - /* - ** AlphaFile_T bib_file[Max_Bib_Files + 1]; - */ - bytes_required = (Max_Bib_Files + 1) * (unsigned long) sizeof (AlphaFile_T); - bib_file = (AlphaFile_T *) mymalloc (bytes_required, "bib_file"); - - /* - ** StrNumber_T bib_list[Max_Bib_Files + 1]; - */ - bytes_required = (Max_Bib_Files + 1) * (unsigned long) sizeof (StrNumber_T); - bib_list = (StrNumber_T *) mymalloc (bytes_required, "bib_list"); - - /* - ** ASCIICode_T buffer[Buf_Size + 1]; - */ - bytes_required = (Buf_Size + 1) * (unsigned long) sizeof (ASCIICode_T); - buffer = (ASCIICode_T *) mymalloc (bytes_required, "buffer"); - - /* - ** StrNumber_T cite_info[Max_Cites + 1]; - */ - bytes_required = (Max_Cites + 1) * (unsigned long) sizeof (StrNumber_T); - cite_info = (StrNumber_T *) mymalloc (bytes_required, "cite_info"); - - /* - ** StrNumber_T cite_list[Max_Cites + 1]; - */ - bytes_required = (Max_Cites + 1) * (unsigned long) sizeof (StrNumber_T); - cite_list = (StrNumber_T *) mymalloc (bytes_required, "cite_list"); - - /* - ** Boolean_T entry_exists[Max_Cites + 1]; - */ - bytes_required = (Max_Cites + 1) * (unsigned long) sizeof (Boolean_T); - entry_exists = (Boolean_T *) mymalloc (bytes_required, "entry_exists"); - - /* - ** Boolean_T entry_ints[Max_Ent_Ints + 1]; - ** allocated when num_ent_ints and num_cites are known - */ - entry_ints = NULL; - - /* - ** ASCIICode_T entry_strs[Max_Ent_Strs + 1][Ent_Str_Size + 1]; - ** allocated when num_ent_strs and num_cites are known - */ - entry_strs = NULL; - - /* - ** ASCIICode_T ex_buf[Buf_Size + 1]; - */ - bytes_required = (Buf_Size + 1) * (unsigned long) sizeof (ASCIICode_T); - ex_buf = (ASCIICode_T *) mymalloc (bytes_required, "ex_buf"); - - /* - ** StrNumber_T field_info[Max_Fields + 1]; - */ - bytes_required = (Max_Fields + 1) * (unsigned long) sizeof (StrNumber_T); - field_info = (StrNumber_T *) mymalloc (bytes_required, "field_info"); - - /* - ** FnClass_T fn_type[Hash_Size + 1]; - */ - bytes_required = (Hash_Size + 1) * (unsigned long) sizeof (FnClass_T); - fn_type = (FnClass_T *) mymalloc (bytes_required, "fn_type"); - - /* - ** Integer_T glb_str_end[Max_Glob_Strs]; - */ - bytes_required = Max_Glob_Strs * (unsigned long) sizeof (Integer_T); - glb_str_end = (Integer_T *) mymalloc (bytes_required, "glb_str_end"); - - /* - ** StrNumber_T glb_str_ptr[Max_Glob_Strs]; - */ - bytes_required = Max_Glob_Strs * (unsigned long) sizeof (StrNumber_T); - glb_str_ptr = (StrNumber_T *) mymalloc (bytes_required, "glb_str_ptr"); - - /* - ** ASCIICode_T global_strs[Max_Glob_Strs][Glob_Str_Size + 1]; - */ - bytes_required = (unsigned long) (Max_Glob_Strs) - * (Glob_Str_Size + 1) - * (unsigned long) sizeof (ASCIICode_T); - global_strs = (ASCIICode_T *) mymalloc (bytes_required, "global_strs"); - - /* - ** StrIlk_T hash_ilk[Hash_Size + 1]; - */ - bytes_required = (Hash_Size + 1) * (unsigned long) sizeof (StrIlk_T); - hash_ilk = (StrIlk_T *) mymalloc (bytes_required, "hash_ilk"); - - /* - ** HashPointer_T hash_next[Hash_Size + 1]; - */ - bytes_required = (Hash_Size + 1) * (unsigned long) sizeof (HashPointer_T); - hash_next = (HashPointer_T *) mymalloc (bytes_required, "hash_next"); - - /* - ** StrNumber_T hash_text[Hash_Size + 1]; - */ - bytes_required = (Hash_Size + 1) * (unsigned long) sizeof (StrNumber_T); - hash_text = (StrNumber_T *) mymalloc (bytes_required, "hash_text"); - - /* - ** Integer_T ilk_info[Hash_Size + 1]; - */ - bytes_required = (Hash_Size + 1) * (unsigned long) sizeof (Integer_T); - ilk_info = (Integer_T *) mymalloc (bytes_required, "ilk_info"); - - /* - ** Integer_T lit_stack[Lit_Stk_Size + 1]; - */ - bytes_required = (Lit_Stk_Size + 1) * (unsigned long) sizeof (Integer_T); - lit_stack = (Integer_T *) mymalloc (bytes_required, "lit_stack"); - - /* - ** StkType_T lit_stk_type[Lit_Stk_Size + 1]; - */ - bytes_required = (Lit_Stk_Size + 1) * (unsigned long) sizeof (StkType_T); - lit_stk_type = (StkType_T *) mymalloc (bytes_required, "lit_stk_type"); - - /* - ** ASCIICode_T name_sep_char[Buf_Size + 1]; - */ - bytes_required = (Buf_Size + 1) * (unsigned long) sizeof (ASCIICode_T); - name_sep_char = (ASCIICode_T *) mymalloc (bytes_required, "name_sep_char"); - - /* - ** BufPointer_T name_tok[Buf_Size + 1]; - */ - bytes_required = (Buf_Size + 1) * (unsigned long) sizeof (BufPointer_T); - name_tok = (BufPointer_T *) mymalloc (bytes_required, "name_tok"); - - /* - ** ASCIICode_T out_buf[Buf_Size + 1]; - */ - bytes_required = (Buf_Size + 1) * (unsigned long) sizeof (ASCIICode_T); - out_buf = (ASCIICode_T *) mymalloc (bytes_required, "out_buf"); - - /* - ** StrNumber_T s_preamble[Max_Bib_Files + 1]; - */ - bytes_required = (Max_Bib_Files + 1) * (unsigned long) sizeof (StrNumber_T); - s_preamble = (StrNumber_T *) mymalloc (bytes_required, "s_preamble"); - - /* - ** ASCIICode_T str_pool[Pool_Size + 1]; - */ - bytes_required = (Pool_Size + 1) * (unsigned long) sizeof (ASCIICode_T); - str_pool = (ASCIICode_T *) mymalloc (bytes_required, "str_pool"); - - /* - ** PoolPointer_T str_start[Max_Strings + 1]; - */ - bytes_required = (Max_Strings + 1) * (unsigned long) sizeof (PoolPointer_T); - str_start = (PoolPointer_T *) mymalloc (bytes_required, "str_start"); - - /* - ** ASCIICode_T sv_buffer[Buf_Size + 1]; - */ - bytes_required = (Buf_Size + 1) * (unsigned long) sizeof (ASCIICode_T); - sv_buffer = (ASCIICode_T *) mymalloc (bytes_required, "sv_buffer"); - - /* - ** HashPtr2_T type_list[Max_Cites + 1]; - */ - bytes_required = (Max_Cites + 1) * (unsigned long) sizeof (HashPtr2_T); - type_list = (HashPtr2_T *) mymalloc (bytes_required, "type_list"); - - /* - ** HashPtr2_T wiz_functions[Wiz_Fn_Space + 1]; - */ - bytes_required = (Wiz_Fn_Space + 1) * (unsigned long) sizeof (HashPtr2_T); - wiz_functions = (HashPtr2_T *) mymalloc (bytes_required, "wiz_functions"); - -} /* allocate_arrays () */ - - - -/*- -**============================================================================ -** checkdbg() -** -** Examine a string representing different debug options, usually provided -** as a value to a command line option, and return the value as a long -** integer. Return 0 (no debugging) if a valid option was not parsed. -**============================================================================ -*/ -static int checkdbg (char *str) -{ - int dbgval = 0; - - if ((str == NULL) || (*str == '\0')) - return (0); - - if (strstr (str, "all") != NULL) - dbgval |= DBG_ALL; - if (strstr (str, "csf") != NULL) - dbgval |= DBG_CSF; - if (strstr (str, "io") != NULL) - dbgval |= DBG_IO; - if (strstr (str, "mem") != NULL) - dbgval |= DBG_MEM; - if (strstr (str, "misc") != NULL) - dbgval |= DBG_MISC; - if (strstr (str, "search") != NULL) - dbgval |= DBG_SRCH; - - return (dbgval); -} /* checkdbg() */ - - - -/*- -**============================================================================ -** checklong() -** -** Examine a string representing an integer, usually provided as a value to -** a command line option, and return the value as a long integer. -** Return -1 if a valid integer was not parsed. -**============================================================================ -*/ -static long checklong (char *str) -{ - long value; - char *endptr; - int len; - - len = strlen (str); - value = strtol (str, &endptr, 10); - - if (str == endptr) - return (-1); - if ((endptr - str) < len) - return (-1); - - return (value); -} /* checklong() */ - - - -/*- -**============================================================================ -** close_file() -** -** Close a file - as long as it's open. -**============================================================================ -*/ -void close_file (const AlphaFile_T file_pointer) -{ - if (file_pointer != NULL) - fclose (file_pointer); -} /* close_file() */ - - - -/*- -**============================================================================ -** debug_msg() -** -** Write a debugging message to the stderr stream, but only if the -** appropriate debugging option has been selected. -**============================================================================ -*/ -void debug_msg (const int status, const char *printf_fmt, ...) -{ - va_list printf_args; - const char *prefix; - - switch (status) { - case DBG_CSF: - if ((Flag_debug & DBG_CSF) == 0) return; - prefix = "D-CSF"; - break; - case DBG_IO: - if ((Flag_debug & DBG_IO) == 0) return; - prefix = "D-I/O"; - break; - case DBG_MEM: - if ((Flag_debug & DBG_MEM) == 0) return; - prefix = "D-MEM"; - break; - case DBG_MISC: - if ((Flag_debug & DBG_MISC) == 0) return; - prefix = "D-MSC"; - break; - case DBG_SRCH: - if ((Flag_debug & DBG_SRCH) == 0) return; - prefix = "D-SCH"; - break; - default: - return; - } - - if (printf_fmt != NULL) { - fprintf (stderr, "%s: ", prefix); - va_start (printf_args, printf_fmt); - vfprintf (stderr, printf_fmt, printf_args); - va_end (printf_args); - fprintf (stderr, "\n"); - fflush (stderr); - } -} /* debug_msg () */ - - -#ifndef KPATHSEA -/*- -**============================================================================ -** find_file() -** -** Search along a path for a file. The search path is specified by the -** value of an environment variable which can contain multiple directories, -** separated by an appropriate delimiter. The best known example is the -** PATH environment variable found on DOS, OS/2 and Unix. -** -** If the environment variable is not specified, or it has not been set, -** a 'fallback' path will be used. The current working directory will be -** searched first, then directories along the search path define dby the -** environment variable or fallback path. -** -** If the file is found along the search path, a value of 0 is returned and -** the full file specification is stored in parameter full_file_spec. If -** the file was not found, -1 is returned. -**============================================================================ -*/ -int find_file (const char *envvar_name, const char *fallback_path, - const char *filename, char *full_file_spec) -{ - char c; - int len = 0; - char *search_path; - - debug_msg (DBG_SRCH, "find_file: searching for file name `%s'", - filename); - debug_msg (DBG_SRCH, - "find_file: environment variable for search path = `%s'", - (envvar_name == NULL) ? "NULL" : envvar_name); - debug_msg (DBG_SRCH, "find_file: fallback path = `%s'", - (fallback_path == NULL) ? "NULL" : fallback_path); - - if ((envvar_name == NULL) || (*envvar_name == '\0')) { - search_path = NULL; - debug_msg (DBG_SRCH, - "find_file: no environment variable specified"); - } else { - search_path = getenv (envvar_name); - debug_msg (DBG_SRCH, "find_file: %s = `%s'", envvar_name, - (search_path == NULL) ? "NULL" : search_path); - } - - /* - ** If we have a NULL search path because an environment variable name was - ** not specified or specified but not defined, we use the fallback - ** search path. - */ - if (search_path == NULL) { - debug_msg (DBG_SRCH, "find_file: using fallback search path `%s'", - (fallback_path == NULL) ? "NULL" : fallback_path); - search_path = (char *) fallback_path; - } - - - /* - ** Work along the search path looking for the wanted file. Stop when - ** the first match is found. - */ - while (1) { - full_file_spec[len] = '\0'; - - /* - ** If the path is not empty, and it doesn't end in '/' or '\', - ** append a trailing '/'. - */ - if (len != 0) { - c = full_file_spec[len - 1]; - if ((c != '/') && (c != '\\')) - strcat (full_file_spec, "/"); - } - - /* - ** Append the filename to the path and then test whether the - ** file exists. If not, return -1 and an empty string. - */ - strcat (full_file_spec, filename); - debug_msg (DBG_SRCH, "find_file: trying `%s'", full_file_spec); - - if (access (full_file_spec, 0) == 0) - break; - - if ((search_path == NULL) || (*search_path == '\0')) { - full_file_spec[0] = '\0'; - return (-1); - } - - len = 0; - - for (;;) { - if ((*search_path != PATH_DELIM) && (*search_path != '\0')) { - if (*search_path == '\\') - full_file_spec[len] = '/'; - else - full_file_spec[len] = *search_path; - - ++len; - ++search_path; - } else - break; - } /* end for (;;) */ - - if (*search_path != '\0') - ++search_path; - } /* end while (1) */ - - debug_msg (DBG_SRCH, "find_file: returning `%s'", full_file_spec); - return (0); -} /* find_file() */ -#endif /* ! KPATHSEA */ - - -/*- -**============================================================================ -** mymalloc() -** -** Allocate memory for a specified array and check whether the allocation -** was successful. If not, issue an error message and cause the program -** to stop with a fatal exit status. -** Allocate at least 1 byte, otherwise malloc may return NULL. -**============================================================================ -*/ -void *mymalloc (const unsigned long bytes_required, const char *array_name) -{ - void *ptr; - - ptr = malloc (bytes_required ? bytes_required : 1); - - if (ptr == NULL) { - printf ("\nFatal error: couldn't allocate %lu bytes for array `%s'", - bytes_required, array_name); - mark_fatal (); - debug_msg (DBG_MISC, "calling longjmp (Exit_Program_Flag) ... "); - longjmp (Exit_Program_Flag, 1); - } else { - debug_msg (DBG_MEM, "allocated %7lu bytes for array `%s'", - bytes_required, array_name); - } - - return (ptr); -} /* mymalloc () */ - - - -/*- -**============================================================================ -** myrealloc() -** -** Reallocate memory for a specified array and check whether the allocation -** was successful. If not, issue an error message and cause the program -** to stop with a fatal exit status. -** Allocate at least 1 byte, otherwise realloc may return NULL. -**============================================================================ -*/ -void *myrealloc (void *old_ptr, const unsigned long bytes_required, const char *array_name) -{ - void *ptr; - - if (old_ptr == NULL) - return mymalloc (bytes_required, array_name); - - ptr = realloc (old_ptr, bytes_required ? bytes_required : 1); - - if (ptr == NULL) { - printf ("\nFatal error: couldn't reallocate %lu bytes for array `%s'", - bytes_required, array_name); - mark_fatal (); - debug_msg (DBG_MISC, "calling longjmp (Exit_Program_Flag) ... "); - longjmp (Exit_Program_Flag, 1); - } else { - debug_msg (DBG_MEM, "reallocated %7lu bytes for array `%s'", - bytes_required, array_name); - } - - return (ptr); -} /* myrealloc () */ - - - -/*- -**============================================================================ -** open_ip_file() -** -** Open a file for input after locating it using one of the five predefined -** search strategies defined by the parameter "search_path". This parameter -** can take 5 values: -** -** AUX_FILE - used for locating .aux files. Search for the file along the -** path defined by the environment variable AUX_INPUT_ENVVAR or -** if it is not defined, use the fallback path defined by -** AUX_INPUT_PATH. -** -** BIB_FILE - used for locating .bib files. Search for the file along the -** path defined by the environment variable BIB_INPUT_ENVVAR or -** if it is not defined, use the fallback path defined by -** BIB_INPUT_PATH. -** -** BST_FILE - used for locating .bst files. Search for the file along the -** path defined by the environment variable BST_INPUT_ENVVAR or -** if it is not defined, use the fallback path defined by -** BST_INPUT_PATH. -** -** CSF_FILE - used for locating .csf files. Search for the file along the -** path defined by the environment variable CSF_INPUT_ENVVAR or -** if it is not defined, use the fallback path defined by -** CSF_INPUT_PATH. -** -** NO_SEARCH_PATH - only look for the file in the current directory. -** -** Searching for the file is delegated to the function find_file(), and -** only if it was successful, does this function attempt to open the file. -**============================================================================ -*/ -FILE *open_ip_file (Integer_T search_path) -{ - const char *filename = (const char *) name_of_file; -#ifdef KPATHSEA - string full_filespec; -#else - char full_filespec[FILE_NAME_SIZE + 1]; -#endif - FILE *fptr; - int status; - - switch (search_path) { - case AUX_FILE_SEARCH_PATH: -#ifdef KPATHSEA - status = ((full_filespec = kpse_find_file(filename, kpse_tex_format, false)) == NULL); -#else - status = find_file (AUX_INPUT_ENVVAR, AUX_INPUT_PATH, - filename, full_filespec); -#endif - break; - case BIB_FILE_SEARCH_PATH: -#ifdef KPATHSEA - status = ((full_filespec = kpse_find_file(filename, kpse_bib_format, false)) == NULL); -#else - status = find_file (BIB_INPUT_ENVVAR, BIB_INPUT_PATH, - filename, full_filespec); -#endif - break; - case BST_FILE_SEARCH_PATH: -#ifdef KPATHSEA - status = ((full_filespec = kpse_find_file(filename, kpse_bst_format, false)) == NULL); -#else - status = find_file (BST_INPUT_ENVVAR, BST_INPUT_PATH, - filename, full_filespec); -#endif - break; - case CSF_FILE_SEARCH_PATH: -#ifdef KPATHSEA - status = ((full_filespec = kpse_find_file(filename, kpse_bst_format, false)) == NULL); -#else - status = find_file (CSF_INPUT_ENVVAR, CSF_INPUT_PATH, - filename, full_filespec); -#endif - break; - case NO_SEARCH_PATH: - default: -#ifdef KPATHSEA - status = ((full_filespec = kpse_find_file(filename, kpse_program_text_format, false)) == NULL); -#else - status = find_file (NULL, NULL, filename, full_filespec); -#endif - break; - } /* end switch (search_path) */ - - /* - ** find_file() will return zero if the file was found somewhere - ** along the search path. If it does, try to open the file. - */ - if (status == 0) { - debug_msg (DBG_IO, "open_ip_file: trying to open `%s' ... ", - full_filespec); -#ifdef KPATHSEA - if (!kpse_in_name_ok(full_filespec)) - goto not_ok; - fptr = fopen (full_filespec, FOPEN_R_MODE); - free (full_filespec); -#else -# if defined(MSDOS) || defined(OS2) - fptr = fopen (full_filespec, "rt"); -# endif - -# if defined(UNIX) || defined(VMS) - fptr = fopen (full_filespec, "r"); -#endif -#endif /* ! KPATHSEA */ - } - - /* - ** Otherwise, return a NULL pointer. - */ - else { -not_ok: - debug_msg (DBG_IO, "open_ip_file: unable to open `%s' ... ", - full_filespec); - fptr = NULL; - } - return (fptr); -} /* open_ip_file() */ - - - -/*- -**============================================================================ -** open_op_file() -** -** Open a file for output in the current working directory. If the operating -** system makes a distinction between text and non-text files, make sure -** that the file is opened in "text" mode. -**============================================================================ -*/ -FILE *open_op_file (void) -{ - const char *tmp_file_name = (const char *) name_of_file; - FILE *fptr; - - debug_msg (DBG_IO, "open_op_file: trying to open `%s' ... ", - tmp_file_name); - - /* - ** Make sure that we open the output file as a "text" file. This - ** varies according to the operating system. - */ -#if defined(KPATHSEA) - if (kpse_out_name_ok(tmp_file_name)) - fptr = fopen(tmp_file_name, FOPEN_W_MODE); - else - fptr = NULL; -#else -# if defined(MSDOS) || defined(OS2) - fptr = fopen (tmp_file_name, "wt"); -# endif - -# ifdef UNIX - fptr = fopen (tmp_file_name, "w"); -# endif - -# ifdef VMS - fptr = fopen (tmp_file_name, "w", "rfm=var", "rat=cr"); -# endif -#endif /* ! KPATHSEA */ - - if (fptr == NULL) { - printf ("open_op_file: error opening `%s'\n", tmp_file_name); - } - return (fptr); -} /* open_op_file() */ - - - -/*- -**============================================================================ -** parse_cmd_line() -** -** Parse the command line used to launch BibTeX and set options accordingly. -** Most of the work is done by the GNU getopt() function to support these -** long and short options: -** -** -? --help display this help text -** -7 --traditional operate in the traditional 7-bit mode -** -8 --8bit force 8-bit mode, even if no CS file -** -c --csfile FILE read FILE as the BibTeX character set -** and sort definition file -** -d --debug TYPE report debugging information. TYPE is one or -** more of all, csf, io, mem, misc, search. -** -s --statistics report internal statistics -** -t --trace report execution tracing -** -v --version report BibTeX version\n -** -B --big set large BibTeX capacity -** -H --huge set huge BibTeX capacity -** -W --wolfgang set really huge BibTeX capacity for Wolfgang -** -M --min_crossrefs ## set ## as the minimum number of cross refs -** required for automatic inclusion of the cross -** referenced entry in the citation list -** (default = 2) -** --mcites ## ignored -** --mentints ## ignored -** --mentstrs ## ignored -** --mfields ## ignored -** --mpool ## ignored -** --mstrings ## allow ## unique strings -** --mwizfuns ## ignored -**============================================================================ -*/ -void parse_cmd_line (int argc, char **argv) -{ - int c; - int no_files; - - Flag_7bit = FALSE; - Flag_8bit = FALSE; - Flag_big = FALSE; - Flag_debug = FALSE; - Flag_huge = FALSE; - Flag_wolfgang = FALSE; - Flag_stats = FALSE; - Flag_trace = FALSE; - Str_auxfile = NULL; - Str_csfile = NULL; -#ifdef UTF_8 - Flag_language = FALSE; - Str_language = NULL; - Flag_location = FALSE; - Str_location = NULL; -#endif - - while (1) { - int option_index = 0; - - c = getopt_long (argc, argv, getopt_str, long_options, &option_index); - - if (c == EOF) - break; - - switch (c) { - case '?': /**************** -?, --help ***************/ - usage (NULL); - break; - -#ifndef UTF_8 - case '7': /**************** -7, --traditional ********/ - Flag_7bit = TRUE; - break; - - case '8': /**************** -8, --8bit ***************/ - Flag_8bit = TRUE; - break; -#endif - - case 'B': /**************** -B, --big ****************/ - Flag_big = TRUE; - break; - -#ifndef UTF_8 - case 'c': /**************** -c, --csfile *************/ - Str_csfile = strdup (optarg); - break; -#endif - - case 'd': /**************** -d, --debug **************/ - if ((optarg == NULL) || (*optarg == '\0')) - Flag_debug = DBG_ALL; - else - Flag_debug = checkdbg (optarg); - break; - - case 'H': /**************** -H, --huge ***************/ - Flag_huge = TRUE; - break; - -#ifdef UTF_8 - case 'l': /**************** -l, --language ***********/ - Flag_language =TRUE; - Str_language = optarg; - break; -#endif - - case 'M': /**************** -M, --min_crossrefs ******/ - M_min_crossrefs = checklong (optarg); - if (M_min_crossrefs < 0) { - mark_fatal (); - usage ("invalid minimum cross references `%s'\n", optarg); - } - break; - -#ifdef UTF_8 - case 'o': /**************** -o, --location ***********/ - Flag_location =TRUE; - Str_location = optarg; - break; -#endif - - case 's': /**************** -s, --statistics *********/ - Flag_stats = TRUE; - break; - - case 't': /**************** -t, --trace **************/ - Flag_trace = TRUE; - break; - - case 'v': /**************** -v, --version ************/ - FPRINTF (TERM_OUT, "%s\n", BANNER); - FPRINTF (TERM_OUT, "Implementation: %s\n", IMPLEMENTATION); - FPRINTF (TERM_OUT, "Release version: %s\n", VERSION); - debug_msg (DBG_MISC, - "calling longjmp (Exit_Program_Flag) ... "); - longjmp (Exit_Program_Flag, 1); - break; - - case 'W': /**************** -W, --wolfgang ***********/ - Flag_wolfgang = TRUE; - break; - - case '\x0A': /**************** --mcites *****************/ - case '\x0B': /**************** --mentints ***************/ - case '\x0C': /**************** --mentstrs ***************/ - case '\x0D': /**************** --mfields ****************/ - case '\x0E': /**************** --mpool *****************/ - case '\x10': /**************** --mwizfuns ***************/ - (void) checklong (optarg); /******** ignored ********/ - break; - - case '\x0F': /**************** --mstrings ***************/ - M_strings = checklong (optarg); - if (M_strings < 0) { - mark_fatal (); - usage ("invalid max number of strings `%s'\n", optarg); - } - break; - - default: /**************** Unknown argument ********/ - mark_fatal (); - usage ("unknown option"); - } /* end switch (c) */ - } /* end while (1) */ - - - /* - ** Check that a single .aux file was specified. - */ - no_files = argc - optind; - - if (no_files == 1) - Str_auxfile = argv[optind]; - else if (no_files < 1) { - mark_fatal (); - usage ("no aux file specified"); - } else { - mark_fatal (); - usage ("only one aux file may be specified"); - } - - /* - ** Check for contradictory options - */ - if (Flag_7bit && Flag_8bit) { - mark_fatal (); - usage ("can't specify --traditional and --8bit"); - } - - if ((Flag_big && Flag_huge) || (Flag_big && Flag_wolfgang) - || (Flag_huge && Flag_wolfgang)) { - mark_fatal (); - usage ("can only specify one of --big, --huge and --wolfgang"); - } - - if ((Str_csfile != NULL) && (Flag_7bit)) { - mark_fatal (); - usage ("can't specify --csfile and --traditional"); - } - - if ((Str_csfile != NULL) && (Flag_8bit)) { - mark_fatal (); - usage ("can't specify --csfile and --8bit"); - } - - /* - ** Check for options which have not been #defined into the code - */ -#ifndef DEBUG - if (Flag_debug) - FSO ("BibTeX: debugging support was not compiled into this version\n"); -#endif /* DEBUG */ - -#ifndef STAT - if (Flag_stats) - FSO ("BibTeX: statistics support was not compiled into this version\n"); -#endif /* STAT */ - -#ifndef TRACE - if (Flag_trace) - FSO ("BibTeX: tracing support was not compiled into this version\n"); -#endif /* TRACE */ - - -} /* parse_cmd_line() */ - - - -/*- -**============================================================================ -** report_bibtex_capacity() -** -** If the log file has been opened, indicate BibTeX's capacity by reporting -** the size/values of some key values and arrays. Anything in mixed case -** has been set at run-time. -**============================================================================ -*/ -void report_bibtex_capacity (void) -{ - if (log_file != NULL) { - FPRINTF (log_file, "BibTeX's capacity set as follows:\n\n"); - LOG_CAPACITY (AUX_STACK_SIZE); - LOG_CAPACITY (Buf_Size); - LOG_CAPACITY (Ent_Str_Size); - LOG_CAPACITY (Glob_Str_Size); - LOG_CAPACITY (Hash_Prime); - LOG_CAPACITY (Hash_Size); - LOG_CAPACITY (Lit_Stk_Size); - LOG_CAPACITY (Max_Bib_Files); - LOG_CAPACITY (Max_Cites); - LOG_CAPACITY (Max_Fields); - LOG_CAPACITY (Max_Glob_Strs); - LOG_CAPACITY (MAX_PRINT_LINE); - LOG_CAPACITY (Max_Strings); - LOG_CAPACITY (Min_Crossrefs); - LOG_CAPACITY (MIN_PRINT_LINE); - LOG_CAPACITY (Pool_Size); - LOG_CAPACITY (SINGLE_FN_SPACE); - LOG_CAPACITY (Wiz_Fn_Space); - FPRINTF (log_file, "\n"); - } -} /* report_bibtex_capacity() */ - - - -/*- -**============================================================================ -** report_search_paths() -** -** Report the environment variables and fallback search paths used by -** BibTeX for locating input files. -**============================================================================ -*/ -void report_search_paths (void) -{ -#ifndef KPATHSEA - /* - ** Define a couple of useful macros to simplify reporting of the desired - ** information. - */ -#define REPORT_SEARCH_PATH(_a,_b,_c) \ - debug_msg (DBG_SRCH, "Search strategy for %s files:", _a); \ - debug_msg (DBG_SRCH, " search path environment variable: %s", NULLCHECK (_b)); \ - if (! ISEMPTYSTR (_b)) { \ - char *ptr; \ - ptr = getenv (_b); \ - debug_msg (DBG_SRCH, " %s value: %s", _b, NULLCHECK (ptr)); \ - } \ - debug_msg (DBG_SRCH, " fallback search path: %s", NULLCHECK (_c)); - - -#define REPORT_SEARCH_FILE(_a,_b,_c) \ - debug_msg (DBG_SRCH, "Default %s file:", _a); \ - debug_msg (DBG_SRCH, " file name environment variable: %s", NULLCHECK (_b)); \ - if (! ISEMPTYSTR (_b)) { \ - char *ptr; \ - ptr = getenv (_b); \ - debug_msg (DBG_SRCH, " %s value: %s", _b, NULLCHECK (ptr)); \ - } \ - debug_msg (DBG_SRCH, " fallback file name: %s", NULLCHECK (_c)); - - /* - ** Now report the information. - */ - REPORT_SEARCH_PATH (".aux", AUX_INPUT_ENVVAR, AUX_INPUT_PATH); - REPORT_SEARCH_PATH (".bib", BIB_INPUT_ENVVAR, BIB_INPUT_PATH); - REPORT_SEARCH_PATH (".bst", BST_INPUT_ENVVAR, BST_INPUT_PATH); - REPORT_SEARCH_PATH (".csf", CSF_INPUT_ENVVAR, CSF_INPUT_PATH); - - REPORT_SEARCH_FILE (".csf", CSF_FILE_ENVVAR, CSF_FILE_NAME); -#endif /* ! KPATHSEA */ -} /* report_search_paths() */ - - -/*- -**============================================================================ -** setup_bound_variable() -** -** Obtain parameters from environment or configuration file, -** or use the default value. -**============================================================================ -*/ -static void setup_bound_variable (Integer_T *var, const char *name, - unsigned long def_value) -{ -#ifdef KPATHSEA - char *expansion = kpse_var_value (name); - const char *me = kpse_invocation_name; - const char *src = " or texmf.cnf"; -#else - char *expansion = getenv (name); - const char *me = PROGNAME; - const char *src = ""; -#endif - - *var = def_value; - if (expansion) { - int conf_val = atoi (expansion); - if (conf_val < def_value) - fprintf (stderr, - "%s: Bad value (%ld) in environment%s for %s, keeping %ld.\n", - me, (long) conf_val, src, name, def_value); - else - *var = conf_val; -#ifdef KPATHSEA - free (expansion); -#endif - } -} /* setup_bound_variable() */ - -/*- -**============================================================================ -** setup_params() -** -** Determine |ent_str_size|, |glob_str_size|, and |max_strings| from the -** environment, configuration file, or default value. Set -** |hash_size:=max_strings|, but not less than |HASH_SIZE|. -**============================================================================ -*/ -static void setup_params (void) -{ - setup_bound_variable (&Ent_Str_Size, "ent_str_size", ENT_STR_SIZE); - setup_bound_variable (&Glob_Str_Size, "glob_str_size", GLOB_STR_SIZE); - setup_bound_variable (&Max_Strings, "max_strings", MAX_STRINGS); - - /* Obsolete: Max_Strings specified via command line. */ - if (Flag_big) - Max_Strings = 10000; - if (Flag_huge) - Max_Strings = 19000; - if (Flag_wolfgang) - Max_Strings = 30000; - if (M_strings > 0) - Max_Strings = M_strings; - - if (Max_Strings < MAX_STRINGS) - Max_Strings = MAX_STRINGS; - Hash_Size = Max_Strings; - if (Hash_Size < HASH_SIZE) - Hash_Size = HASH_SIZE; -} /* setup_params() */ - - -/*- -**============================================================================ -** compute_hash_prime() -** -** We use the algorithm from Knuth's \.{primes.web} to compute -** |hash_prime| as the smallest prime number not less than 85\% -** of |hash_size| (and |>=128|). -** -** This algorithm uses two arrays |primes| and |mult|. We use the -** already allocated |hash_next| and |hash_text| for that purpose. -**============================================================================ -*/ -#define primes hash_next -#define mult hash_text -static void compute_hash_prime (void) -{ - Integer32_T Hash_Want = (Hash_Size / 20) * 17; /* 85\% of |hash_size| */ - Integer32_T k = 1; /*number of prime numbers $p_i$ in |primes| */ - Integer32_T j = 1; /* a prime number candidate */ - Integer32_T o = 2; /* number of odd multiples of primes in |mult| */ - Integer32_T square = 9; /* $p_o^2$ */ - Integer32_T n; /* loop index */ - Boolean_T j_prime; /* is |j| a prime? */ - - debug_msg (DBG_MEM, "Computing Hash_Prime ... "); - - primes[k] = Hash_Prime = 2; - while (Hash_Prime < Hash_Want) { - do { - j += 2; - if (j == square) { - mult[o++] = j; - j += 2; - square = primes[o] * primes[o]; - } - n = 2; - j_prime = TRUE; - while ((n < o) && j_prime) { - while (mult[n] < j) - mult[n] += 2 * primes[n]; - if (mult[n++] == j) - j_prime = FALSE; - } - } while (!j_prime); - primes[++k] = Hash_Prime = j; - } -} /* compute_hash_prime() */ - - -/*- -**============================================================================ -** set_array_sizes() -** -** Allocate memory dynamically for the large arrays whose size is set -** dynamically, depending on the amount memory of memory available. -** -** On virtual memory operating systems, there is not normally a problem -** allocating memory; the array sizes can be predetermined and memory -** allocated at run-time. -** -** Parameter Cmd Standard --big --huge --wolfgang -** ------------------------------------------------------------------ -** Buf_Size *** initialy 20000, increased as required *** -** Hash_Prime *** computed from Hash_Size *** -** Hash_Size *** determined from Max_Strings *** -** Max_Bib_Files *** initialy 20, increased as required *** -** Max_Cites *** initialy 750, increased as required *** -** Max_Ent_Ints *** as required *** -** Max_Ent_Strs *** as required *** -** Max_Fields *** initialy 5000, increased as required *** -** Max_Strings Y 4,000 10,000 19,000 30,000 -** Pool_Size *** initialy 65,000, increased as required *** -** Wiz_Fn_Space *** initialy 3000, increased as required *** -** ------------------------------------------------------------------ -** -**============================================================================ -*/ -void set_array_sizes (void) -{ - debug_msg (DBG_MEM, "Setting BibTeX's capacity ... "); - - Max_Strings = 4000; - Min_Crossrefs = 2; - - setup_params (); - Buf_Size = BUF_SIZE; - - Lit_Stk_Size = LIT_STK_SIZE; - - Max_Bib_Files = MAX_BIB_FILES; - - Max_Cites = MAX_CITES; - - Max_Fields = MAX_FIELDS; - - if (M_min_crossrefs > 0) - Min_Crossrefs = M_min_crossrefs; - - Pool_Size = POOL_SIZE; - - Wiz_Fn_Space = WIZ_FN_SPACE; - - - allocate_arrays (); - compute_hash_prime (); - - - debug_msg (DBG_MEM, "Hash_Prime = %d, Hash_Size = %d", - Hash_Prime, Hash_Size); - debug_msg (DBG_MEM, "Buf_Size = %d, Max_Bib_Files = %d", - Buf_Size, Max_Bib_Files); - debug_msg (DBG_MEM, "Max_Cites = %d, Max_Fields = %d", - Max_Cites, Max_Fields); - debug_msg (DBG_MEM, "Max_Strings = %d, Pool_Size = %d", - Max_Strings, Pool_Size); - debug_msg (DBG_MEM, "Min_Crossrefs = %d, Wiz_Fn_Space = %d", - Min_Crossrefs, Wiz_Fn_Space); - - - /*- - ** Check that the key values are sensible. These checks are stolen - ** from initialize(), but the error messages are more informative. - */ - debug_msg(DBG_MISC, "Sanity checking capacity values ... "); - - if (Hash_Prime < 128) - usage ("Hash_Prime (%d) must be >= 128", Hash_Prime); - - if (Hash_Prime > Hash_Size) - usage ("Hash_Prime (%d) must be <= Hash_Size (%d)", - Hash_Prime, Hash_Size); - - /* - ** The original WEB version of BibTeX imposed a maximum value of - ** 16321 on Hash_Prime. A WEB constant was defined: - ** - ** MAX_HASH_VALUE = (Hash_Prime + Hash_Prime - 2 + 127) - ** - ** but, because WEB constants are limited to 32767, Hash_Prime was - ** consequently limited to a maximum of (32767 + 2 - 127) / 2 = 16321. - ** - ** We're using C #defines, so that limit doesn't apply. The - ** following original sanity check is therefore commented out. - ** - ** if (Hash_Prime >= (16384 - 64)) - ** usage ("Hash_Prime (%d) must be < %d", Hash_Prime, (16384-64)); - */ - - if (Max_Strings > Hash_Size) - usage ("Max_Strings (%d) must be <= Hash_Size (%d)", - Max_Strings, Hash_Size); - - if (Max_Cites > Max_Strings) - usage ("Max_Cites (%d) must be <= Max_Strings (%d)", - Max_Cites, Max_Strings); - -} /* set_array_sizes() */ - - - -/*- -**============================================================================ -** usage() -** -** Display a helpful message reporting the command line options -** supported by this version of BibTeX. If a message string is -** provided, this is displayed first. -**============================================================================ -*/ -void usage (const char *printf_fmt, ...) -{ - va_list printf_args; - - if (printf_fmt != NULL) { -#ifdef UTF_8 - fprintf (stderr, "BibTeXu: "); -#else - fprintf (stderr, "BibTeX8: "); -#endif - va_start (printf_args, printf_fmt); - vfprintf (stderr, printf_fmt, printf_args); - va_end (printf_args); - fprintf (stderr, "\n"); - } - - FSO ("\nUsage: " PROGNAME " [options] aux-file\n\n"); - FSO (" Valid options are:\n\n"); - FSO (" -? --help display this help text\n"); - -#ifndef UTF_8 - FSO (" -7 --traditional operate in the original 7-bit mode\n"); - FSO (" -8 --8bit force 8-bit mode, no CS file used\n"); - FSO (" -c --csfile FILE read FILE as the BibTeX character set\n"); - FSO (" and sort definition file\n"); -#endif - -#ifdef DEBUG - FSO (" -d --debug TYPE report debugging information. TYPE is one\n"); - FSO (" or more of all, csf, io, mem, misc, search.\n"); -#endif /* DEBUG */ - -#ifdef STAT - FSO (" -s --statistics report internal statistics\n"); -#endif /* STAT */ - -#ifdef TRACE - FSO (" -t --trace report execution tracing\n"); -#endif /* TRACE */ - - FSO (" -v --version report BibTeX version\n\n"); - -#ifdef UTF_8 - FSO (" -l --language LANG use language LANG, ex: -l fr\n"); - FSO (" -o --location LOC use location LOC, ex: -o fr\n\n"); -#endif - - FSO (" -B --big same as --mstrings 10000\n"); - FSO (" -H --huge same as --mstrings 19000\n"); - FSO (" -W --wolfgang same as --mstrings 30000\n"); - FSO (" -M --min_crossrefs ## set min_crossrefs to ##\n"); - FSO (" --mstrings ## allow ## unique strings\n"); - - debug_msg (DBG_MISC, "calling longjmp (Exit_Program_Flag) ... "); - longjmp (Exit_Program_Flag, 1); -} /* usage() */ - - - -/*- -****************************************************************************** -****************************************************************************** -** -** Functions specifically for 8-bit support. -** -** c8read_csf -** c8initialise -** c8read_lowercase -** c8read_lowupcase -** c8read_uppercase -** c8read_order -** c8report_8bit_handling -** -****************************************************************************** -****************************************************************************** -*/ -#ifdef SUPPORT_8BIT - -/* -** Useful definitions. -*/ -#define c8is_alpha(c) (isalpha(c) || c > 127) -#define c8is_alphanumeric(c) (isalnum(c) || c > 127) -#define SORT_LAST 4095 - - - -/*- -**============================================================================ -** c8initialise () -** -** Initialise BibTeX's handling of 8-bit character sets. The steps are: -** -** o initialise default behaviour for sorting and upper/lowercase -** o if appropriate, read and parse the CS file -** o use CS data to set behaviour for sorting and upper/lowercase -** o update xchr/xord arrays for 8-bit characters. These arrays -** are initialised for ASCII character sets in the original -** initialize() function. Further initialisation for 8-bit -** characters is performed here to minimise "contamination" of -** the original BibTeX code. -** -** We have to deal with three modes of operation: -** -** --traditional - the original BibTeX behaviour -** --8bit - every character with a code > 127 is treated as -** a letter -** default - a CS file is read and parsed to define sorting order -** and how 8-bit characters should be handled -**============================================================================ -*/ -void c8initialise (void) -{ - int ascii_case_diff = 'a' - 'A'; - int c; - int status; - - /* - ** Traditional mode (--traditional, -7) results in identical behaviour - ** to the original BibTeX. - ** - ** o sort order by character code value ('A'=65 ... 'z'=122) - ** o upper/lowercase relationships for A..Za..z established - ** o no CS file read - ** o only characters < 128 allowed - ** o no need to update xchr/xord arrays - */ - if (Flag_7bit) { - - for (c = 0; c <= 255; c++) { - c8order[c] = c; - c8lowcase[c] = (UChar_T) c; - c8upcase[c] = (UChar_T) c; - } - - for (c = 'A'; c <= 'Z'; c++) { - c8lowcase[c] = (UChar_T) (c + ascii_case_diff); - c8upcase[c + ascii_case_diff] = (UChar_T) c; - } - - for (c = 128; c <= 255; c++) - lex_class[c] = ILLEGAL; - } - - /* - ** Raw 8-bit (--8bit, -8). - ** - ** o sort order by character code value ('A'=65 ... 'z'=122) - ** o upper/lowercase relationships for A..Za..z established - ** o no CS file read - ** o need to update xchr/xord arrays - ** o characters > 127 allowed and all treated as type ALPHA - */ - else if (Flag_8bit) { - - for (c = 0; c <= 255; c++) { - c8order[c] = c; - c8lowcase[c] = (UChar_T) c; - c8upcase[c] = (UChar_T) c; - } - - for (c = 'A'; c <= 'Z'; c++) { - c8lowcase[c] = (UChar_T) (c + ascii_case_diff); - c8upcase[c + ascii_case_diff] = (UChar_T) c; - } - - for (c = 128; c <= 255; c++) - xchr[c] = (char) c; - - for (c = 128; c <= 255; c++) - xord[xchr[c]] = (ASCIICode_T) c; - - for (c = 128; c <= 255; c++) - lex_class[c] = ALPHA; - } - - /* - ** Default initialisation using CS file. - ** - ** o no sort order defined - all set to weight SORT_LAST - ** o upper/lowercase relationships for A..Za..z established - ** o only characters < 128 allowed initially - ** o a CS file is read and parsed by BibTeX to modify these defaults - ** o need to update xchr/xord/lex_class arrays after reading CS file - */ - else { - - for (c = 0; c <= 255; c++) { - c8order[c] = SORT_LAST; - c8lowcase[c] = (UChar_T) c; - c8upcase[c] = (UChar_T) c; - } - - c8order[32] = 0; - - for (c = 'A'; c <= 'Z'; c++) { - c8lowcase[c] = (UChar_T) (c + ascii_case_diff); - c8upcase[c + ascii_case_diff] = (UChar_T) c; - } - - for (c = 128; c <= 255; c++) - xchr[c] = (char) c; - - for (c = 128; c <= 255; c++) - xord[xchr[c]] = (ASCIICode_T) c; - - for (c = 128; c <= 255; c++) - lex_class[c] = ILLEGAL; - - /* - ** Read the CS file. If it was read and parsed OK, update the - ** definition of 8-bit characters. If an 8-bit character is defined - ** in any section of the CS file, it is treated as type ALPHA. - */ - if ((status = c8read_csf ()) == TRUE) { - - for (c = 128; c <= 255; c++) - if ((c8order[c] != SORT_LAST) - || (c8lowcase[c] != c) - || (c8upcase[c] != c)) - lex_class[c] = ALPHA; - } - } /* end if (Flag_7bit) */ - - /* - ** If the CSF debugging option has been selected, report results. - */ - if ((Flag_debug & DBG_CSF)) - c8report_8bit_handling (); - -} /* c8initialise () */ - - - -/*- -**============================================================================ -** c8read_csf() -** -** Read the Case and Sorting definitions (CS) File. Steps taken are: -** -** o determine which CS file should be opened -** o open the CS file -** o look for valid CS file sections (\lowupcase, \lowercase, -** \uppercase, \order) and delegate parsing of each section to the -** appropriate function -** o close the CS file -** -** Returns TRUE if a CS file was successfully read and parsed, FALSE -** otherwise. -**============================================================================ -*/ -int c8read_csf (void) -{ - int c, i; - int in_comment; -#define SX_BUF_SIZE 15 - /* a section name: "order", "uppercase", "lowercase", or "lowupcase". */ - char sx[SX_BUF_SIZE + 1]; -#ifndef KPATHSEA - char *value; -#endif - - /* - ** Construct the name of the CS file to be used: - ** - ** 1. If the --csfile option was specified, use its value. - ** or - ** 2. If CSF_FILE_ENVVAR is defined to a non-empty value, it - ** contains the name of an environment variable. The value of - ** this environment variable will be used as the default CS file. - */ - if (Str_csfile == NULL) { -#ifdef KPATHSEA -#ifndef CSF_FILE_ENVVAR -#define CSF_FILE_ENVVAR "BIBTEX_CSFILE" -#endif - /* Default value from environment or texmf.cnf */ - Str_csfile = kpse_var_value (CSF_FILE_ENVVAR); - if (Str_csfile == NULL) /* Use fallback value */ - Str_csfile = xstrdup ("88591lat.csf"); -#else - if (strlen (CSF_FILE_ENVVAR) != 0) { - debug_msg (DBG_CSF, "c8read_csf: --csfile not set, checking '%s'", - CSF_FILE_ENVVAR); - value = getenv (CSF_FILE_ENVVAR); - - if (value == NULL) - debug_msg (DBG_CSF, "c8read_csf: %s = `NULL'", CSF_FILE_ENVVAR); - else - debug_msg (DBG_CSF, "c8read_csf: %s = `%s'", - CSF_FILE_ENVVAR, value); - /* - ** If the environment variable has a non-empty value, use it - ** as the file specifaction for the default CS file. - */ - if ((value != NULL) && (*value != '\0')) - Str_csfile = strdup (value); - else { - PRINT_LN ("Warning: cannot open CS file: --csfile not specfied"); - PRINT_LN2 ("and environment variable %s has no value.", - CSF_FILE_ENVVAR); - return FALSE; - } - } else { - PRINT_LN ("Warning: cannot open CS file: --csfile not specified"); - PRINT_LN ("and default environment variable not specified."); - return FALSE; - } /* if (strlen (CSF_FILE_ENVVAR) != 0) */ -#endif /* KPATHSEA */ - } /* if (Str_csfile == NULL) */ - /* - ** Make sure that we have ended up with a CS file name. If not, - ** return FALSE; - */ - if ((Str_csfile == NULL) || (*Str_csfile == '\0')) { - PRINT_LN ("Warning: cannot open CS file: empty --csfile value specified."); - return FALSE; - } - - /* - ** If the CS file name doesn't contain a '.', append ".csf". - */ - free (name_of_file); - name_of_file = (unsigned char *) mymalloc (strlen (Str_csfile) + 5, "name_of_file"); - strcpy ((char *)name_of_file, Str_csfile); - - if (strchr ((char *)name_of_file, '.') == NULL) - strcat ((char *)name_of_file, ".csf"); - name_length = strlen ((char *)name_of_file); - - debug_msg (DBG_CSF, "c8read_csf: trying to open CS file `%s' ...", - name_of_file); - - /* - ** Attempt to open the CS file, using the CS file search path if - ** necessary. If the open fails, return FALSE. - */ - if (! a_open_in (&c8_cs_file, CSF_FILE_SEARCH_PATH)) { - PRINT_LN2 ("Error: cannot open CS file: %s", name_of_file); - return FALSE; - } - PRINT_LN2 ("The 8-bit codepage and sorting file: %s", name_of_file); - - /* - ** The main loop for reading the CS file. - */ - c8_line = 1; - while (! feof (c8_cs_file)) { - - /* - ** Read the CS file until a '\\' character is found, denoting the - ** start of a major section. Comments begin with a '%' and - ** anything else on the same line is ignored. - */ - in_comment = FALSE; - do { - c = getc (c8_cs_file); - - if (c == '\n') { - ++c8_line; - in_comment = FALSE; - } - if (c == '%') - in_comment = TRUE; - if ((c == '\\') && (in_comment == FALSE)) - break; - } while (!feof (c8_cs_file)); - - /* - ** If we break out of the do loop on EOF, there were no more - ** sections in the CS file. Exit the main reading loop. - */ - if (feof (c8_cs_file)) - break; - - /* - ** After '\', a section name must be found. This name is a word - ** composed only of lower case ASCII letters. - */ - i = 0; - - do { - c = getc (c8_cs_file); - if ((c >= 'a') && (c <= 'z')) - sx[i++] = c; - else - break; - } while (!feof (c8_cs_file) && (i < SX_BUF_SIZE)); - sx[i] = '\0'; - - /* - ** A '{' should follow the section name, but it could be preceeded - ** by whitespace, comments or newlines. - */ - if (c != '{') - do { - if (c == '\n') { - ++c8_line; - in_comment = FALSE; - } - if (c == '%') - in_comment = TRUE; - if ((c == '{') && (in_comment == FALSE)) - break; - c = getc (c8_cs_file); - } while (!feof (c8_cs_file)); - - - /* - ** The major sections supported in the CS file are: \order{}, - ** \uppercase{}, \lowercase{} and \lowupcase{}. Anything else will - ** be ignored. Known sections are processed until they terminate - ** and then the loop starts again. - */ - if (strcmp (sx, "order") == 0) - c8read_order (); - else if (strcmp (sx, "uppercase") == 0) - c8read_uppercase (); - else if (strcmp (sx, "lowercase") == 0) - c8read_lowercase (); - else if (strcmp (sx, "lowupcase") == 0) - c8read_lowupcase (); - else { - PRINT_LN2 ("Unknown section on line in CS file %s", Str_csfile); - PRINT_LN3 ("%04d: \\%s", c8_line, buffer); - } - } /* while (! feof (c8_cs_file)) */ - - /* - ** Finished reading, close the CS file then return TRUE. - */ - close_file (c8_cs_file); - free (Str_csfile); - return TRUE; -} /* c8read_csf () */ - - - -/*- -**============================================================================ -** c8read_lowercase() -** -** Read and parse the \lowercase section of the CS file. This section is -** used to define the upper -> lower case relationship of pairs of specified -** characters. It should normally only be used if the relationship -** isn't symmetrical - use \lowupcase if it is. -** -** The syntax of the \lowercase section is: -** -** \lowercase{ -** <UC-val-1> <LC-val-1> % Comment begins with a percent sign -** <UC-val-2> <LC-val-2> <UC-val-3> <LC-val-3> -** ... -** <UC-val-N> <LC-val-N> -** } -** -** Notes: -** -** o characters can be entered normally, or in TeX notation for -** character codes, i.e. ^^XX, where XX is the hexadecimal value. -** -** o reading of the \lowercase section ends when the first '}' character -** is reached, so '}' can't be included in a case relationship pair. -** You can't use ^^7d either. -** -** o '%' is used to introduce a trailing comment, so '%' can't be included -** in the \lowercase section. You can't use ^^25 either. -** -** o you cannot redefine the lower case equivalent of an ASCII character -** (code < 128). In other words, all "left hand" characters in the -** relationship pairs must have codes > 127. -**============================================================================ -*/ -static void c8read_lowercase (void) -{ - int c; - int uppercase_val; - - debug_msg (DBG_CSF, "reading the \\lowercase section ... "); - uppercase_val = -1; - - /* - ** Keep reading characters until the end of the section is encountered - ** at a '}' or EOF is reached. - */ - c = getc (c8_cs_file); - - while ((c != '}') && !feof (c8_cs_file)) { - - /* - ** Characters may be specified using the TeX syntax for the - ** 8-bit code, i.e. ^^XX, where XX is the hexadecimal value. - ** We should really check the result of this fscanf(). Read the - ** character code and then start the while loop again. - */ - if (c == '^') - fscanf (c8_cs_file, "^%x", &c); - - /* - ** If we have reached the end of a line, simply increment the - ** line count. - */ - if (c == '\n') { - c8_line++; - } - - /* - ** If we encounter a '%', it signifies the start of a comment. - ** Ignore characters until the end of line is reached. - */ - else if (c == '%') { - do { - c = getc(c8_cs_file); - } while ((c != '\n') && (! feof( c8_cs_file))); - continue; - } - - /* - ** The normal case is for alpha characters to be included in the - ** case relationship. Alpha characters are assumed to be ASCII - ** alpha (A..Za..z) plus any character with a code > 127. - */ - else if (c8is_alpha (c)) { - - /* - ** The case relationship consists of a pair of alpha characters - ** separated by whitespace. In the \lowercase section, the pair - ** is in the order <uppercase-char> <lowercase-char>. We - ** must remember which character we are looking for - this is - ** achieved by setting uppercase_val to -1 when we are - ** looking for the first character of a pair. - ** - ** If uppercase_val is < 0, we treat the current character as - ** the upper case member of the pair and set uppercase_val - ** accordingly. - */ - if (uppercase_val < 0) - uppercase_val = c; - else { - - /* - ** We are not allowed to redefine the lower case - ** equivalent of an ASCII character. - */ - if (uppercase_val < 127) { - PRINT_LN2 ("Error: attempt to redefine lower case of " - "an ASCII character [0x%02x]", uppercase_val); - PRINT_LN3 ("Context: line %04d: of CS file %s", - c8_line, Str_csfile); - } - - /* - ** All OK, so set the appropriate element of the c8lowcase - ** array and reset the value of uppercase_val to signify - ** that we are looking for the next pair. - */ - else { - c8lowcase[uppercase_val] = c; - uppercase_val = -1; - } - } - } /* end if */ - - /* - ** Get the next character from the file and start the loop again. - */ - c = getc (c8_cs_file); - } /* end while */ - - /* - ** The only normal reason for breaking out of the while loop is that - ** we encountered '}' at the end of the \lowercase section. Two - ** conditions should be true: - ** - ** (uppercase_val = -1) - there is an unmatched character - ** (c == '}') - the terminating '}' has been read - */ - if (uppercase_val != -1){ - PRINT_LN ("Error: unmatched character pair in \\lowercase section"); - PRINT_LN3 ("Context: line %04d: of CS file %s", c8_line, Str_csfile); - } - - if (c != '}') { - PRINT_LN ("Error: unexpected end of file in \\lowercase section"); - PRINT_LN3 ("Context: line %04d: of CS file %s", c8_line, Str_csfile); - } - - debug_msg (DBG_CSF, "finished reading the \\lowercase section."); -} /* c8read_lowercase () */ - - - -/*- -**============================================================================ -** c8read_lowupcase() -** -** Read and parse the \lowupcase section of the CS file. This section is -** used to define the lower -> upper and upper -> lower case relationship -** of pairs of specified characters. It is only used if the relationship -** is symmetrical - use \lowercase or \uppercase if it isn't. -** -** The syntax of the \lowupcase section is: -** -** \uppercase{ -** <LC-val-1> <UC-val-1> % Comment begins with a percent sign -** <LC-val-2> <UC-val-2> <LC-val-3> <UC-val-3> -** ... -** <LC-val-N> <UC-val-N> -** } -** -** Notes: -** -** o characters can be entered normally, or in TeX notation for -** character codes, i.e. ^^XX, where XX is the hexadecimal value. -** -** o reading of the \lowupcase section ends when the first '}' character -** is reached, so '}' can't be included in a case relationship pair. -** You can't use ^^7d either. -** -** o '%' is used to introduce a trailing comment, so '%' can't be included -** in the \lowupcase section. You can't use ^^25 either. -** -** o you cannot redefine the lower or upper case equivalent of an ASCII -** character (code < 128). In other words, all characters in the -** relationship pairs must have codes > 127. -**============================================================================ -*/ -static void c8read_lowupcase (void) -{ - int c; - int lowercase_val; - - debug_msg (DBG_CSF, "reading the \\lowupcase section ... "); - lowercase_val = -1; - - /* - ** Keep reading characters until the end of the section is encountered - ** at a '}' or EOF is reached. - */ - c = getc (c8_cs_file); - - while ((c != '}') && !feof (c8_cs_file)) { - - /* - ** Characters may be specified using the TeX syntax for the - ** 8-bit code, i.e. ^^XX, where XX is the hexadecimal value. - ** We should really check the result of this fscanf(). - */ - if (c == '^') - fscanf (c8_cs_file, "^%x", &c); - - /* - ** If we have reached the end of a line, simply increment the - ** line count. - */ - if (c == '\n') { - c8_line++; - } - - /* - ** If we encounter a '%', it signifies the start of a comment, - ** unless it was translated from a ^^xx sequence. - ** Ignore characters until the end of line is reached. - */ - else if (c == '%') { - do { - c = getc(c8_cs_file); - } while ((c != '\n') && (! feof( c8_cs_file))); - continue; - } - - /* - ** The normal case is for alpha characters to be included in the - ** case relationship. Alpha characters are assumed to be ASCII - ** alpha (A..Za..z) plus any character with a code > 127. - */ - else if (c8is_alpha (c)) { - - /* - ** The case relationship consists of a pair of alpha characters - ** separated by whitespace. In the \lowupcase section, the pair - ** is in the order <lowercase-char> <uppercase-char>. We - ** must remember which character we are looking for - this is - ** achieved by setting lowercase_val to -1 when we are - ** looking for the first character of a pair. - ** - ** If lowercase_val is < 0, we treat the current character as - ** the lower case member of the pair and set lowercase_val - ** accordingly. - */ - if (lowercase_val < 0) - lowercase_val = c; - else { - - /* - ** We are not allowed to redefine the lower or upper case - ** equivalent of an ASCII character. - */ - if (lowercase_val < 127) { - PRINT_LN2 ("Error: attempt to redefine upper case of " - "an ASCII character [0x%02x]", lowercase_val); - PRINT_LN3 ("Context: line %04d: of CS file %s", - c8_line, Str_csfile); - } - else if (c < 127) { - PRINT_LN2 ("Error: attempt to redefine lower case of " - "an ASCII character [0x%02x]", c); - PRINT_LN3 ("Context: line %04d: of CS file %s", - c8_line, Str_csfile); - } - - /* - ** All OK, so set the appropriate element of the c8lowcase - ** and c8upcase arrays, then reset the value of lowercase_val - ** to signify that we are looking for the next pair. - */ - else { - c8lowcase[c] = lowercase_val; - c8upcase[lowercase_val] = c; - lowercase_val = -1; - } - } - } /* end if */ - - /* - ** Get the next character from the file and start the loop again. - */ - c = getc (c8_cs_file); - } /* end while */ - - /* - ** The only normal reason for breaking out of the while loop is that - ** we encountered '}' at the end of the \lowupcase section. Two - ** conditions should be true: - ** - ** (lowercase_val = -1) - there is an unmatched character - ** (c == '}') - the terminating '}' has been read - */ - if (lowercase_val != -1){ - PRINT_LN ("Error: unmatched character pair in \\lowupcase section"); - PRINT_LN3 ("Context: line %04d: of CS file %s", c8_line, Str_csfile); - } - - if (c != '}') { - PRINT_LN ("Error: unexpected end of file in \\lowupcase section"); - PRINT_LN3 ("Context: line %04d: of CS file %s", c8_line, Str_csfile); - } - - debug_msg (DBG_CSF, "finished reading the \\lowupcase section."); -} /* c8read_lowupcase () */ - - - -/*- -**============================================================================ -** c8read_order() -** -** Read and parse the \order section of the CS file. This section is -** used to define the sorting order of characters in the 8-bit character -** set. -** -** The syntax of the \order section is: -** -** \order{ -** <char-1> % Comment begins with a percent sign -** <char-2> <char-3> -** <char-4> - <char-5> -** <char-4> _ <char-5> -** ... -** <char-n> -** } -** -** Notes: -** -** o characters can be entered normally, or in TeX notation for -** character codes, i.e. ^^XX, where XX is the hexadecimal value. -** -** o reading of the \order section ends when the first '}' character -** is reached, so '}' can't be included in the \order section. You -** can't use ^^7d either. -** -** o '%' is used to introduce a trailing comment, so '%' can't be included -** in the \order section. You can't use ^^25 either. -** -** o All characters on the same line are given the same sorting weight. -** -** o The construct <char-1> <underscore> <char-2> is used to denote that -** all characters in the range <char-1> to <char-2> should be given the -** same sorting weight. For example, "A _ Z a _ z" would cause all -** ASCII alphabetical characters to have the same sorting weight and -** would be equivalent to placing all 26 characters on the same line. -** -** o The construct <char-1> <hyphen> <char-2> is used to denote that all -** characters in the range <char-1> to <char-2> should be given an -** ascending set of sorting weights, starting with <char-1> and -** ending with <char-2>. For example, "A - Z" would cause all -** upper case ASCII alphabetical characters to be sorted in -** ascending order and would be equivalent to placing 'A' on the -** first line, 'B' on the second, through to 'Z' on the 26th line. -** -** o the characters at the beginning of the order section are given a -** lower sorting weight than characters occuring later. When -** sorting alphabetically, characters with the lowest weight come -** first. -** -** o all characters not in the \order section (including ASCII characters) -** are given the same very high sorting weight to ensure that they -** come last when sorting alphabetically. -**============================================================================ -*/ -static void c8read_order (void) -{ - int c, i; - int c_previous = 0; - int c_previous_previous = 0; - int seen_chars; - - debug_msg (DBG_CSF, "reading the \\order section ... "); - sort_weight = 1; - seen_chars = FALSE; - - /* - ** Keep reading characters until the end of the section is - ** encountered at a '}' or EOF is reached. - */ - c = getc (c8_cs_file); - - while ((c != '}') && (! feof (c8_cs_file))) { - - /* - ** If we have reached the end of a line, the next line denotes - ** characters with an increased sorting weight. Any other - ** characters with a value less than ' ' are ignored. - */ - if (c == '\n') { - if (seen_chars) - sort_weight++; - c8_line++; - seen_chars = FALSE; - } - else if (c < ' ') { - debug_msg (DBG_CSF, "ignoring char 0x%02X on line %d of CS file", - c, c8_line); - } - else if (c > ' ') { - - /* - ** Characters may be specified using the TeX syntax for the - ** 8-bit code, i.e. ^^XX, where XX is the hexadecimal value. - ** We should really check the result of this fscanf(). Read the - ** character code and then start the while loop again. - */ - if (c == '^') - fscanf (c8_cs_file, "^%x", &c); - - /* - ** If we encounter a '%', it signifies the start of a comment. - ** Ignore characters until the end of line is reached. - */ - if (c == '%') { - do { - c = getc(c8_cs_file); - } while ((c != '\n') && (! feof( c8_cs_file))); - continue; - } - - /* - ** The normal case is for alpha characters to be included - ** in the sorting sequence. Alpha characters are ASCII alpha - ** plus any character with a code > 127. - */ - else if (c8is_alphanumeric (c) || c == ' ') { - - /* - ** If the previous char was '-', we expect this char to - ** terminate a "X-Y" sequence. The character before - ** the '-' must also be an alpha type. The characters in - ** the sequence are assigned an increasing sort weight. - */ - if (c_previous == '-') { - if (c8is_alphanumeric (c_previous_previous)) { - for (i = c_previous_previous; i < c; i++) - c8order[i] = sort_weight++; - seen_chars = TRUE; - } else { - PRINT_LN ("Error: non-alphanumeric character " - "starts X-Y sequence"); - PRINT_LN3 ("Context: line %04d: of CS file %s", - c8_line, Str_csfile); - } - - /* - ** If the previous char was '_', we expect this char to - ** terminate a "X_Y" sequence. The character before - ** the '_' must also be an alpha type. The characters in - ** the sequence are assigned the same sort weight. - */ - } else if (c_previous == '_') { - if (c8is_alphanumeric (c_previous_previous)) { - for (i = c_previous_previous; i < c; i++) - c8order[i] = sort_weight; - seen_chars = TRUE; - } else { - PRINT_LN ("Error: non-alphanumeric character " - "starts X_Y sequence"); - PRINT_LN3 ("Context: line %04d: of CS file %s", - c8_line, Str_csfile); - } - } - c8order[c] = sort_weight; - seen_chars = TRUE; - } - - /* - ** The only other non-alpha characters allowed are '-' & '_'. - */ - else if ((c != '-') && (c != '_')) { - PRINT_LN ("Error: only '-' or '_' may follow an " - "alpha character"); - PRINT_LN3 ("Context: line %04d: of CS file %s", - c8_line, Str_csfile); - } - - /* - ** Keep an up-to-date note of the two previous values of c. - */ - c_previous_previous = c_previous; - c_previous = c; - } /* end if */ - - /* - ** Get the next character and start the loop again. - */ - c = getc (c8_cs_file); - } /* end while */ - - /* - ** If c isn't '}', we ran into EOF. - */ - if (c != '}') { - PRINT_LN ("Error: unexpected end of file in \\order section"); - PRINT_LN3 ("Context: line %04d: of CS file %s", c8_line, Str_csfile); - } - debug_msg (DBG_CSF, "finished reading the \\order section."); -} /* c8read_order () */ - - - -/*- -**============================================================================ -** c8read_uppercase() -** -** Read and parse the \uppercase section of the CS file. This section is -** used to define the lower -> upper case relationship of pairs of specified -** characters. It should normally only be used if the relationship -** isn't symmetrical - use \lowupcase if it is. -** -** The syntax of the \uppercase section is: -** -** \uppercase{ -** <LC-val-1> <UC-val-1> % Comment begins with a percent sign -** <LC-val-2> <UC-val-2> <LC-val-3> <UC-val-3> -** ... -** <LC-val-N> <UC-val-N> -** } -** -** Notes: -** -** o characters can be entered normally, or in TeX notation for -** character codes, i.e. ^^XX, where XX is the hexadecimal value. -** -** o reading of the \uppercase section ends when the first '}' character -** is reached, so '}' can't be included in a case relationship pair. -** You can't use ^^7d either. -** -** o '%' is used to introduce a trailing comment, so '%' can't be included -** in the \uppercase section. You can't use ^^25 either. -** -** o you cannot redefine the upper case equivalent of an ASCII character -** (code < 128). In other words, all "left hand" characters in the -** relationship pairs must have codes > 127. -**============================================================================ -*/ -static void c8read_uppercase (void) -{ - int c; - int lowercase_val; - - debug_msg (DBG_CSF, "reading the \\uppercase section ... "); - lowercase_val = -1; - - /* - ** Keep reading characters until the end of the section is encountered - ** at a '}' or EOF is reached. - */ - c = getc (c8_cs_file); - - while ((c != '}') && (! feof (c8_cs_file))) { - - /* - ** Characters may be specified using the TeX syntax for the - ** 8-bit code, i.e. ^^XX, where XX is the hexadecimal value. - ** We should really check the result of this fscanf(). - */ - if (c == '^') - fscanf (c8_cs_file, "^%x", &c); - - /* - ** If we have reached the end of a line, simply increment the - ** line count. - */ - if (c == '\n') { - c8_line++; - } - - /* - ** If we encounter a '%', it signifies the start of a comment. - ** Ignore characters until the end of line is reached. - */ - else if (c == '%') { - do { - c = getc(c8_cs_file); - } while ((c != '\n') && (! feof( c8_cs_file))); - continue; - } - - /* - ** The normal case is for alpha characters to be included in the - ** case relationship. Alpha characters are assumed to be ASCII - ** alpha (A..Za..z) plus any character with a code > 127. - */ - else if (c8is_alpha (c)) { - - /* - ** The case relationship consists of a pair of alpha characters - ** separated by whitespace. In the \uppercase section, the pair - ** is in the order <lowercase-char> <uppercase-char>. We - ** must remember which character we are looking for - this is - ** achieved by setting lowercase_val to -1 when we are - ** looking for the first character of a pair. - ** - ** If lowercase_val is < 0, we treat the current character as - ** the lower case member of the pair and set lowercase_val - ** accordingly. - */ - if (lowercase_val < 0) - lowercase_val = c; - else { - - /* - ** We are not allowed to redefine the upper case - ** equivalent of an ASCII character. - */ - if (lowercase_val < 127) { - PRINT_LN2 ("Error: attempt to redefine upper case of " - "an ASCII character [0x%02x]", lowercase_val); - PRINT_LN3 ("Context: line %04d: of CS file %s", - c8_line, Str_csfile); - } - - /* - ** All OK, so set the appropriate element of the c8lowcase - ** array and reset the value of lowercase_val to signify - ** that we are looking for the next pair. - */ - else { - c8upcase[lowercase_val] = c; - lowercase_val = -1; - } - } - } /* end if */ - - /* - ** Get the next character from the file and start the loop again. - */ - c = getc (c8_cs_file); - } /* end while */ - - /* - ** The only normal reason for breaking out of the while loop is that - ** we encountered '}' at the end of the \uppercase section. Two - ** conditions should be true: - ** - ** (lowercase_val = -1) - there is an unmatched character - ** (c == '}') - the terminating '}' has been read - */ - if (lowercase_val != -1){ - PRINT_LN ("Error: unmatched character pair in \\uppercase section"); - PRINT_LN3 ("Context: line %04d: of CS file %s", c8_line, Str_csfile); - } - - if (c != '}') { - PRINT_LN ("Error: unexpected end of file in \\uppercase section"); - PRINT_LN3 ("Context: line %04d: of CS file %s", c8_line, Str_csfile); - } - - debug_msg (DBG_CSF, "finished reading the \\uppercase section."); -} /* c8read_uppercase () */ - - - -/* -**============================================================================ -** c8report_8bit_handling() -** -** Report the internal status of BibTeX's 8-bit character set handling. The -** information reported is: -** -** o 8-bit characters defined as type ALPHA -** o character codes with upper case equivalents -** o character codes with lower case equivalents -** o the character codes in sorting weight order -**============================================================================ -*/ -void c8report_8bit_handling (void) -{ - int c; - int column; - int weight; - - /* - ** Exit immediately if the CSF debugging option hasn't been selected. - */ - if ((Flag_debug & DBG_CSF) == 0) - return; - - /* - ** Report the 8-bit characters defined as type ALPHA, 16 to a row. - */ - fprintf (stderr, "\nD-CSF: 8-bit ALPHA characters\n"); - fprintf (stderr, "D-CSF: ----------------------\n"); - - for (c = 128; c <= 255; c += 16) { - fprintf (stderr, "D-CSF: %02x: ", c); - - for (column = 0; column < 16; column++) { - if (lex_class[c + column] == ALPHA) - fprintf (stderr, "%c ", c + column); - else - fputs (". ", stderr); - } - fputc ('\n', stderr); - } - - /* - ** Report the lower / upper case relationships, three pairs to a row. - */ - fprintf (stderr, "\nD-CSF: Characters with upper case equivalents\n"); - fprintf (stderr, "D-CSF: --------------------------------------"); - column = 0; - - for (c = 1; c <= 255; c++) - if (c8upcase[c] != c) { - if ((column % 3) == 0) - fprintf (stderr, "\nD-CSF: %c [%02x] <<< %c [%02x]", - c, (int) c, c8upcase[c], (int) c8upcase[c]); - else - fprintf (stderr, " %c [%02x] <<< %c [%02x]", - c, (int) c, c8upcase[c], (int) c8upcase[c]); - ++column; - } - - /* - ** Report the upper / lower case relationships, three pairs to a row. - */ - fprintf (stderr, "\n\nD-CSF: Characters with lower case equivalents\n"); - fprintf (stderr, "D-CSF: --------------------------------------"); - column = 0; - - for (c = 1; c <= 255; c++) - if (c8lowcase[c] != c) { - if ((column % 3) == 0) - fprintf (stderr, "\nD-CSF: %c [%02x] >>> %c [%02x]", - c, (int) c, c8lowcase[c], (int) c8lowcase[c]); - else - fprintf (stderr, " %c [%02x] >>> %c [%02x]", - c, (int) c, c8lowcase[c], (int) c8lowcase[c]); - ++column; - } - - /* - ** Report character codes in sorting weight order. If BibTeX is - ** operating in --traditional or --8bit mode, sorting order is simply - ** character code order. In that case, just give an abbreviated - ** summary. - */ - fprintf (stderr, "\n\nD-CSF: Characters in sorting order\n"); - fprintf (stderr, "D-CSF: ---------------------------\n"); - - if (Flag_7bit || Flag_8bit) { - fprintf (stderr, "D-CSF: 00: [00]\n"); - fprintf (stderr, "D-CSF: 01: [01]\n"); - fprintf (stderr, "D-CSF: .. ....\n"); - fprintf (stderr, "D-CSF: 41: A [41]\n"); - fprintf (stderr, "D-CSF: .. ....\n"); - fprintf (stderr, "D-CSF: 5a: Z [5a]\n"); - fprintf (stderr, "D-CSF: .. ....\n"); - fprintf (stderr, "D-CSF: 61: a [61]\n"); - fprintf (stderr, "D-CSF: .. ....\n"); - fprintf (stderr, "D-CSF: 7a: z [7a]\n"); - fprintf (stderr, "D-CSF: .. ....\n"); - fprintf (stderr, "D-CSF: fe: [fe]\n"); - fprintf (stderr, "D-CSF: ff: [ff]\n\n"); - } - - /* - ** When a CS file has been used, sort_weight will be set to the value of - ** the highest sorting weight. Report every character with a given - ** sorting weight, for 0 <= weight < sort_weight. - */ - else { - for (weight = 0; weight < sort_weight; weight++) { - fprintf (stderr, "D-CSF: %02x: ", weight); - - for (c = 0; c <= 255; c++) { - if (c8order[c] == weight) - fprintf (stderr, "%c [%02x] ", c, c); - } - fputc ('\n', stderr); - } - fprintf (stderr, "D-CSF: (All other characters are sorted " - "equally after any of the above.)\n\n"); - } -} /* c8report_8bit_handling() */ - - -#endif /* SUPPORT_8BIT */ |