summaryrefslogtreecommitdiff
path: root/biblio/bibtex/bibtex-x/bibtex.c
blob: 8df3f88c9df95c70c97f4a7e389fc4f8973acd16 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
/*-
******************************************************************************
******************************************************************************
**
**  MODULE
**
**      file: bibtex.c
**
**  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 system-dependent C code for BibTeX.
**      There should NOT be any such code code in any of the bibtex-#.c
**      modules.  Functions defined in this module are:
**
**          a_close
**          a_open_in
**          a_open_out
**          eoln
**          main
**
**  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.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.5  1995/09/24  20:44:37  kempson
**      Many changes for final beta test version.
**
**      Revision 3.4  1995/04/09  22:15:42  kempson
**      Placed under RCS control
**
******************************************************************************
******************************************************************************
*/

#define __BIBTEX_C__

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#ifdef KPATHSEA
#include <kpathsea/config.h>
#include <kpathsea/progname.h>
#include <kpathsea/variable.h>
#endif

#include "sysdep.h"
#include "bibtex.h"
#include "datatype.h"
#include "gblprocs.h"
#include "gblvars.h"
#include "utils.h"
#include "version.h"


/***************************************************************************
 * WEB section number:	 39
 * ~~~~~~~~~~~~~~~~~~~
 * Close the text file.
 ***************************************************************************/
void          a_close (const AlphaFile_T file_pointer)
BEGIN

  close_file (file_pointer);

END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION  39 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/


/***************************************************************************
 * WEB section number:	 38
 * ~~~~~~~~~~~~~~~~~~~
 * Open a text (ASCII) file in the current working directory for input.
 ***************************************************************************/
Boolean_T         a_open_in (AlphaFile_T *file_pointer, 
                             Integer_T search_path)
BEGIN
  *file_pointer = open_ip_file (search_path);

  if (*file_pointer != NULL)
    return TRUE;
  else
    return FALSE;
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION  39 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/



/***************************************************************************
 * WEB section number:	 38
 * ~~~~~~~~~~~~~~~~~~~
 * Open a text (ASCII) file for output in the current directory.
 ***************************************************************************/
Boolean_T         a_open_out (AlphaFile_T *file_pointer)
BEGIN

  *file_pointer = open_op_file ();

  if (*file_pointer != (AlphaFile_T) NULL)
    return TRUE;
  else
    return FALSE;

END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION  39 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/



/***************************************************************************
 * WEB section number:	  47
 * ~~~~~~~~~~~~~~~~~~~
 * Standard \PASCAL\ says that a file should have |eoln| immediately
 * before |eof|, but \BibTeX\ needs only a weaker restriction: If |eof|
 * occurs in the middle of a line, the system function |eoln| should
 * return a |true| result (even though |f^| will be undefined).
 ***************************************************************************/
Boolean_T         eoln (const AlphaFile_T file_pointer)
BEGIN
  int             c;

  if (feof (file_pointer))
  BEGIN
    return (TRUE);
  END
  c = getc (file_pointer);
  if (c != EOF)
  BEGIN
    (void) ungetc (c, file_pointer);
  END
  if (c == '\n' || c == '\r' || c == EOF)
  BEGIN
    return (TRUE);
  END
  else
  BEGIN
    return (FALSE);
  END
END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION  47 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/




/***************************************************************************
 * WEB section number:	 10
 * ~~~~~~~~~~~~~~~~~~~
 * This program first reads the .aux file that \LaTeX\ produces,
 *
 *   1. determining which .bib file(s) and .bst file to read and
 *   2. constructing a list of cite keys in order of occurrence.
 *
 * The .aux file may have other .aux files nested
 * within.  Second, it reads and executes the .bst file,
 *
 *   1. determining how and in which order to process the
 * 	database entries in the .bib file(s) corresponding to those cite
 * 	keys in the list (or in some cases, to all the entries in the .bib
 * 	file(s)),
 *   2. determining what text to be output for each
 * 	entry and determining any additional text to be output, and
 *   3.	outputting this text to the .bbl file.
 *
 * In addition, the program sends error messages and other remarks to the
 * |log_file| and terminal.
 ***************************************************************************/
int                     main (int argc, char **argv)
BEGIN
    extern Integer8_T       history;
    int			    exit_status;
#ifdef KPATHSEA
    char *mpl;
#endif

    /*-
    **------------------------------------------------------------------------
    ** Set |log_file| initially to point to NULL.  All writes to the log
    ** check to see that |log_file| isn't NULL before writing.
    **-----------------------------------------------------------------
    */
    log_file = NULL;

    /*-----------------------------------------------------------------
     * Set up a global label PROGRAM_EXIT which can be used if an
     * error requiring an emergency stop is encountered.
     *-----------------------------------------------------------------*/
    if (setjmp (Exit_Program_Flag) == 1)
    BEGIN
      debug_msg (DBG_MISC, "arrived at setjmp (Exit_Program_Flag)");
      goto Exit_Program_Label;
    END

    /*-----------------------------------------------------------------
     * Set up a global label CLOSE_UP_SHOP which may be used when a
     * fatal error is detected. Used by BIBTEX_OVERFLOW & CONFUSION.
     *-----------------------------------------------------------------*/
    if (setjmp (Close_Up_Shop_Flag) == 1)
    BEGIN
      debug_msg (DBG_MISC, "arrived at setjmp (Close_Up_Shop_Flag)");
      goto Close_Up_Shop_Label;
    END

    number_of_command_line_args = argc;
    command_line_arg_strings = (char **) argv;

    history = SPOTLESS;
    parse_cmd_line (argc, argv);

#ifdef KPATHSEA
    kpse_set_program_name(argv[0], PROGNAME);
    mpl = kpse_var_value("max_print_line");
    if (mpl)
    BEGIN
        max_print_line = atoi(mpl);
        free(mpl);
    END
    else
        max_print_line = 79;  /* default */
#endif

    set_array_sizes ();
    report_search_paths ();

    initialize ();

    if (log_file != NULL) {
        FPRINTF (log_file, "%s-x%s (%s)\n", BANNER, EXT_VERSION, TL_VERSION);
        FPRINTF (log_file, "Implementation:  %s\n", IMPLEMENTATION);
        FPRINTF (log_file, "Release version: %s\n", VERSION);
#ifdef UTF_8
        {
            UVersionInfo icuVersion;
            char icu_version[U_MAX_VERSION_STRING_LENGTH] = "";
            UErrorCode err1 = U_ZERO_ERROR;
            u_getVersion(icuVersion);
            u_versionToString(icuVersion, icu_version);
            FPRINTF (log_file, "Compiled with:   ICU version %s\n", icu_version);

            if (Flag_location)
                u_coll = ucol_open(Str_location, &err1);
            else
                u_coll = ucol_open(NULL, &err1);
            if (!U_SUCCESS(err1)) {
                FPRINTF (log_file, "Error in opening ICU collator.\n");
                exit(FATAL_EXIT_STATUS);
            }
        }
#endif
        FPRINTF (log_file, "\n");
    }

#ifdef SUPPORT_8BIT
    /*
    ** Read the CS file and setup the 8-bit character set handling.
    ** Similar initialisation is done in the original initialise(), but
    ** we do it in a separate function to simplify the code.
    */
    c8initialise ();
#endif                          /* SUPPORT_8BIT */

    if (Flag_stats)
        report_bibtex_capacity ();



/***************************************************************************
 * WEB section number:	 110
 * ~~~~~~~~~~~~~~~~~~~
 * We keep reading and processing input lines until none left.  This is part
 * of the main program; hence, because of the |aux_done| label, there's no
 * BEGIN - END pair surrounding the entire module.
 ***************************************************************************/
    PRINT ("The top-level auxiliary file: ");
    print_aux_name ();

    /*-----------------------------------------------------------------
     * Set up a global label AUX_DONE which can be used if an error is
     * encountered while the .AUX file is being processed.
     *-----------------------------------------------------------------*/
    if (setjmp (Aux_Done_Flag) == 1)
    BEGIN
      debug_msg (DBG_MISC, "arrived at setjmp (Aux_Done_Flag)");
      goto Aux_Done_Label;
    END
    LOOP
    BEGIN
        INCR (CUR_AUX_LINE);
        if ( ! input_ln (CUR_AUX_FILE))
        BEGIN
            pop_the_aux_stack ();
        END
        else
        BEGIN
            get_aux_command_and_process ();
        END
    END

Aux_Done_Label:

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

    last_check_for_aux_errors ();
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 110 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

/***************************************************************************
 * WEB section number:	 151
 * ~~~~~~~~~~~~~~~~~~~
 * Here's the outer loop for reading the .bst file - it keeps reading and
 * processing .bst commands until none left.  This is part of the main
 * program; hence, because of the |bst_done| label, there's no conventional
 * BEGIN - END pair surrounding the entire module.
 ***************************************************************************/
    if (bst_str == 0)
    BEGIN
        goto No_Bst_File_Label;
    END
    bst_line_num = 0;
    bbl_line_num = 1;
    buf_ptr2 = last;

    /*-----------------------------------------------------------------
     * Set up a global label BST_DONE which can be used if an error is
     * encountered while the .BST file is being processed.
     *-----------------------------------------------------------------*/
    if (setjmp (Bst_Done_Flag) == 1)
    BEGIN
      debug_msg (DBG_MISC, "arrived at setjmp (Bst_Done_Flag)");
      goto Bst_Done_Label;
    END
    LOOP
    BEGIN
      if (!eat_bst_white_space ())
      BEGIN
	goto Bst_Done_Label;
      END
      get_bst_command_and_process ();
    END
#ifdef UTF_8
    ucol_close(u_coll);
#endif
Bst_Done_Label:
    a_close (bst_file);
No_Bst_File_Label:
    a_close (bbl_file);
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 151 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

Close_Up_Shop_Label:

/***************************************************************************
 * WEB section number:	 455
 * ~~~~~~~~~~~~~~~~~~~
 * This section does any last-minute printing and ends the program.
 ***************************************************************************/
    BEGIN
      if ((read_performed) && ( ! reading_completed))
      BEGIN
	PRINT2 ("Aborted at line %ld of file ", (long) bib_line_num);
        print_bib_name ();
      END

      trace_and_stat_printing ();

      /*-
      ** Report on BibTeX memory usage to log file.
      */
      TRACE_PR_NEWLINE;
      TRACE_PR_LN  ("Here's how much of BibTeX's memory you used:");
      TRACE_PR_LN3 (" Cites:            %6ld out of %ld",
                    (long) num_cites, (long) Max_Cites);
      TRACE_PR_LN3 (" Fields:           %6ld out of %ld",
                    (long) field_ptr, (long) Max_Fields);
      TRACE_PR_LN3 (" Hash table:       %6ld out of %ld",
                    (long) hash_used, (long) Hash_Size);
      TRACE_PR_LN3 (" Strings:          %6ld out of %ld",
                    (long) str_ptr, (long) Max_Strings);
      TRACE_PR_LN3 (" Free string pool: %6ld out of %ld",
                    (long) pool_ptr, (long) Pool_Size);
      TRACE_PR_LN3 (" Wizard functions: %6ld out of %ld",
                    (long) wiz_def_ptr, (long) Wiz_Fn_Space);


/***************************************************************************
 * WEB section number:	 466
 * ~~~~~~~~~~~~~~~~~~~
 * Some implementations may wish to pass the |history| value to the
 * operating system so that it can be used to govern whether or not other
 * programs are started.  Here we simply report the history to the user.
 * The appropriate exit status will be passed to the operating system just
 * before exiting.
 ***************************************************************************/
      switch (history)
      BEGIN
        case SPOTLESS:
	  DO_NOTHING;
          break;
        case WARNING_MESSAGE:
          if (err_count == 1)
          BEGIN
	    PRINT_LN ("(There was 1 warning)");
          END
          else
          BEGIN
            PRINT_LN2 ("(There were %ld warnings)", (long) err_count);
          END
          break;
        case ERROR_MESSAGE:
          if (err_count == 1)
          BEGIN
            PRINT_LN ("(There was 1 error message)");
          END
          else
          BEGIN
            PRINT_LN2 ("(There were %ld error messages)", (long) err_count);
          END
          break;
        case FATAL_MESSAGE:
          PRINT_LN ("(That was a fatal error)");
          break;
        default:
          PRINT ("History is bunk");
          print_confusion ();
          break;
        END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 466 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

        a_close (log_file);
    END
/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION 455 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

Exit_Program_Label:

    switch (history)
    BEGIN
        case SPOTLESS:
	    exit_status = NORMAL_EXIT_STATUS;
	    break;
        case WARNING_MESSAGE:
	    exit_status = WARNING_EXIT_STATUS;
            break;
        case ERROR_MESSAGE:
	    exit_status = ERROR_EXIT_STATUS;
            break;
        case FATAL_MESSAGE:
        default:
	    exit_status = FATAL_EXIT_STATUS;
            break;
    END

    exit (exit_status);
    return (exit_status);
END

/*^^^^^^^^^^^^^^^^^^^^^^^^^^ END OF SECTION  10 ^^^^^^^^^^^^^^^^^^^^^^^^^^^*/