diff options
Diffstat (limited to 'indexing/makeindex/src/mkind.c')
-rw-r--r-- | indexing/makeindex/src/mkind.c | 720 |
1 files changed, 720 insertions, 0 deletions
diff --git a/indexing/makeindex/src/mkind.c b/indexing/makeindex/src/mkind.c new file mode 100644 index 0000000000..4df0015d1e --- /dev/null +++ b/indexing/makeindex/src/mkind.c @@ -0,0 +1,720 @@ +/* + * + * This file is part of + * MakeIndex - A formatter and format independent index processor + * + * Copyright (C) 1989 by Chen & Harrison International Systems, Inc. + * Copyright (C) 1988 by Olivetti Research Center + * Copyright (C) 1987 by Regents of the University of California + * + * Author: + * Pehong Chen + * Chen & Harrison International Systems, Inc. + * Palo Alto, California + * USA + * (phc@renoir.berkeley.edu or chen@orc.olivetti.com) + * + * Contributors: + * Please refer to the CONTRIB file that comes with this release + * for a list of people who have contributed to this and/or previous + * release(s) of MakeIndex. + * + * All rights reserved by the copyright holders. See the copyright + * notice distributed with this software for a complete description of + * the conditions under which it is made available. + * + */ + +#define MKIND_C 1 +#include "mkind.h" +#undef MKIND_C + +int letter_ordering = FALSE; +int compress_blanks = FALSE; +int merge_page = TRUE; +int init_page = FALSE; +int even_odd = -1; +int verbose = TRUE; +int german_sort = FALSE; +int fn_no = -1; /* total number of files */ +int idx_dot = TRUE; /* flag which shows dot in ilg being + * active */ +int idx_tt = 0; /* total entry count (all files) */ +int idx_et = 0; /* erroneous entry count (all files) */ +int idx_gt = 0; /* good entry count (all files) */ + +FIELD_PTR *idx_key; +FILE *log_fp; +FILE *sty_fp; +FILE *idx_fp; +FILE *ind_fp; +FILE *ilg_fp; + +#if OS_BS2000 +FILE *widx_fp; +char widx_fn[STRING_MAX + 5]; +#endif /* OS_BS2000 */ + +char *pgm_fn; +char sty_fn[LINE_MAX]; +char *idx_fn; +char ind[STRING_MAX]; +char *ind_fn; +char ilg[STRING_MAX]; +char *ilg_fn; +char pageno[NUMBER_MAX]; + +static char log_fn[STRING_MAX]; +static char base[STRING_MAX]; +static int need_version = TRUE; + +static void check_all ARGS((char *fn,int ind_given,int ilg_given, + int log_given)); +static void check_idx ARGS((char *fn,int open_fn)); +static void find_pageno ARGS((void)); +static void open_sty ARGS((char *fn)); +static void prepare_idx ARGS((void)); +static void process_idx ARGS((char * *fn,int use_stdin,int sty_given, + int ind_given,int ilg_given,int log_given)); + +#if OS_PCDOS +#if IBM_PC_TURBO +unsigned _stklen = 0xf000; /* Turbo C ignores size set in + .exe file by LINK or EXEMOD, + sigh... */ +#endif /* IBM_PC_TURBO */ +#endif /* OS_PCDOS */ + +#if OS_ATARI +long _stksize = 20000L; /* make the stack larger than 2KB */ +/* size must be given */ +#endif /* OS_ATARI */ + +#ifdef DEBUG +long totmem = 0L; /* for debugging memory usage */ +#endif /* DEBUG */ + +int +#if STDC +main(int argc, char *argv[]) +#else +main(argc, argv) +int argc; +char *argv[]; +#endif +{ + char *fns[ARRAY_MAX]; + char *ap; + int use_stdin = FALSE; + int sty_given = FALSE; + int ind_given = FALSE; + int ilg_given = FALSE; + int log_given = FALSE; + + /* determine program name */ +#if (OS_ATARI | OS_VAXVMS | OS_BS2000 | OS_MVSXA | OS_VMCMS) + pgm_fn = "MakeIndex"; /* Use symbolic name on some systems */ +#else + pgm_fn = strrchr(*argv, DIR_DELIM); + if (pgm_fn == NULL) + pgm_fn = *argv; + else + pgm_fn++; + +#if OS_PCDOS + { + register char *ext = pgm_fn + strlen(pgm_fn)-4; + if ( *ext == '.' ) + *ext = NUL; /* cut off ".EXE" */ + } + (void)strlwr(pgm_fn); /* lower program name */ +#endif /* OS_PCDOS */ + +#endif /* OS_VAXVMS | OS_BS2000 | OS_MVSXA */ + + /* process command line options */ + while (--argc > 0) { + if (**++argv == SW_PREFIX) { + if (*(*argv + 1) == NUL) + break; + for (ap = ++*argv; *ap != NUL; ap++) +#if (OS_BS2000 | OS_MVSXA | OS_VAXVMS) + switch (tolower(*ap)) { +#else + switch (*ap) { +#endif /* (OS_BS2000 | OS_MVSXA | OS_VAXVMS) */ + + /* use standard input */ + case 'i': + use_stdin = TRUE; + break; + + /* enable letter ordering */ + case 'l': + letter_ordering = TRUE; + break; + + /* disable range merge */ + case 'r': + merge_page = FALSE; + break; + + /* supress progress message -- quiet mode */ + case 'q': + verbose = FALSE; + break; + + /* compress blanks */ + case 'c': + compress_blanks = TRUE; + break; + + /* style file */ + case 's': + argc--; + if (argc <= 0) + FATAL("Expected -s <stylefile>\n",""); + open_sty(*++argv); + sty_given = TRUE; + break; + + /* output index file name */ + case 'o': + argc--; + if (argc <= 0) + FATAL("Expected -o <ind>\n",""); + ind_fn = *++argv; + ind_given = TRUE; + break; + + /* transcript file name */ + case 't': + argc--; + if (argc <= 0) + FATAL("Expected -t <logfile>\n",""); + ilg_fn = *++argv; + ilg_given = TRUE; + break; + + /* initial page */ + case 'p': + argc--; + if (argc <= 0) + FATAL("Expected -p <num>\n",""); + strcpy(pageno, *++argv); + init_page = TRUE; + if (STREQ(pageno, EVEN)) { + log_given = TRUE; + even_odd = 2; + } else if (STREQ(pageno, ODD)) { + log_given = TRUE; + even_odd = 1; + } else if (STREQ(pageno, ANY)) { + log_given = TRUE; + even_odd = 0; + } + break; + + /* enable german sort */ + case 'g': + german_sort = TRUE; + break; + + /* bad option */ + default: + FATAL("Unknown option -%c.\n", *ap); + break; + } + } else { + if (fn_no < ARRAY_MAX) { + check_idx(*argv, FALSE); + fns[++fn_no] = *argv; + } else { + FATAL("Too many input files (max %d).\n", ARRAY_MAX); + } + } + } + +/* changes for 2.12 (May 20, 1993) by Julian Reschke (jr@ms.maus.de): + if only one input file and no explicit style file was given */ +#if OS_BS2000 +/* not supported */ +#else + if (fn_no == 0 && !sty_given) + { + char tmp[STRING_MAX + 5]; + + /* base set by last call to check_idx */ + sprintf (tmp, "%s%s", base, INDEX_STY); + if (0 == access(tmp, R_OK)) { + open_sty (tmp); + sty_given = TRUE; + } + } +#endif + + process_idx(fns, use_stdin, sty_given, ind_given, ilg_given, log_given); + idx_gt = idx_tt - idx_et; + ALL_DONE; + if (idx_gt > 0) { + prepare_idx(); + sort_idx(); + gen_ind(); + MESSAGE("Output written in %s.\n", ind_fn); + } else + MESSAGE("Nothing written in %s.\n", ind_fn); + + MESSAGE("Transcript written in %s.\n", ilg_fn); + CLOSE(ind_fp); + CLOSE(ilg_fp); + EXIT(0); + + return (0); /* never executed--avoids complaints */ + /* about no return value */ +} + + +static void +prepare_idx(VOID_ARG) +{ + NODE_PTR ptr = head; + int i = 0; + +#ifdef DEBUG + totmem += idx_gt * sizeof(FIELD_PTR); + (void)fprintf(stderr,"prepare_idx(): calloc(%d,%d)\ttotmem = %ld\n", + idx_gt,sizeof(FIELD_PTR),totmem); +#endif /* DEBUG */ + + if (head == (NODE_PTR)NULL) + FATAL("No valid index entries collected.\n", ""); + + if ((idx_key = (FIELD_PTR *) calloc(idx_gt, sizeof(FIELD_PTR))) == NULL) { + FATAL("Not enough core...abort.\n", ""); + } + for (i = 0; i < idx_gt; i++) { + idx_key[i] = &(ptr->data); + ptr = ptr->next; + } +} + + +static void +#if STDC +process_idx(char *fn[], int use_stdin, int sty_given, int ind_given, + int ilg_given, int log_given) +#else +process_idx(fn, use_stdin, sty_given, ind_given, ilg_given, log_given) +char *fn[]; +int use_stdin; +int sty_given; +int ind_given; +int ilg_given; +int log_given; +#endif +{ + int i; + + if (fn_no == -1) + /* use stdin if no input files specified */ + use_stdin = TRUE; + else { + check_all(fn[0], ind_given, ilg_given, log_given); + PUT_VERSION; + if (sty_given) + scan_sty(); + if (german_sort && (idx_quote == '"')) +FATAL("Option -g invalid, quote character must be different from '%c'.\n", +'"'); + scan_idx(); + ind_given = TRUE; + ilg_given = TRUE; + for (i = 1; i <= fn_no; i++) { + check_idx(fn[i], TRUE); + scan_idx(); + } + } + + if (use_stdin) { + idx_fn = "stdin"; + idx_fp = stdin; + + if (ind_given) { + if (!ind_fp && ((ind_fp = OPEN_OUT(ind_fn)) == NULL)) + FATAL("Can't create output index file %s.\n", ind_fn); + } else { + ind_fn = "stdout"; + ind_fp = stdout; + } + + if (ilg_given) { + if (!ilg_fp && ((ilg_fp = OPEN_OUT(ilg_fn)) == NULL)) + FATAL("Can't create transcript file %s.\n", ilg_fn); + } else { + ilg_fn = "stderr"; + ilg_fp = stderr; + } + + if ((fn_no == -1) && (sty_given)) + scan_sty(); + if (german_sort && (idx_quote == '"')) +FATAL("Option -g ignored, quote character must be different from '%c'.\n", +'"'); + + if (need_version) { + PUT_VERSION; + } + scan_idx(); + fn_no++; + } +} + + +static void +#if STDC +check_idx(char *fn, int open_fn) +#else +check_idx(fn, open_fn) +char *fn; +int open_fn; +#endif +{ + char *ptr = fn; + char *ext; + int with_ext = FALSE; + int i = 0; + +#if OS_BS2000 + char message[256]; /* error message */ + char arg[8]; /* argument for sprintf() */ + + ext = strrchr(fn, EXT_DELIM); + if ((ext != NULL) && + (((*fn == CATID) && (*(fn + 3) != DIR_DELIM)) || + (((*fn == DIR_DELIM) || (*fn == CATID)) && + (strchr(fn, EXT_DELIM) < ext)))) { +#else + ext = strrchr(fn, EXT_DELIM); + if ((ext != NULL) && (ext != fn) && (*(ext + 1) != DIR_DELIM)) { +#endif /* OS_BS2000 */ + with_ext = TRUE; + while ((ptr != ext) && (i < STRING_MAX)) + base[i++] = *ptr++; + } else + while ((*ptr != NUL) && (i < STRING_MAX)) + base[i++] = *ptr++; + + if (i < STRING_MAX) + base[i] = NUL; + else + FATAL2("Index file name %s too long (max %d).\n", + base, STRING_MAX); + + idx_fn = fn; + +#if OS_BS2000 /* Search both on HOME-PVS and + * WORK-PVS */ + sprintf(widx_fn, "%s%s", WORK, idx_fn); + if (((((idx_fp = OPEN_IN(idx_fn)) == NULL) && open_fn) || + !(open_fn || idx_fp)) && + ((((widx_fp = OPEN_IN(widx_fn)) == NULL) && open_fn) || + !(open_fn || widx_fp))) + if (with_ext) { + sprintf(message, "Input index file %s%%s not found.\n", + (strchr(idx_fn, ':') || (strlen(WORK) == 0)) ? + NIL : "<" WORK ">"); + FATAL(message, idx_fn); + } else { + +#ifdef DEBUG + totmem += STRING_MAX; + (void)fprintf(stderr,"check_idx()-1: malloc(%d)\ttotmem = %ld\n", + STRING_MAX,totmem); +#endif /* DEBUG */ + + if ((idx_fn = (char *) malloc(STRING_MAX)) == NULL) + FATAL("Not enough core...abort.\n", ""); + sprintf(idx_fn, "%s%s", base, INDEX_IDX); + sprintf(widx_fn, "%s%s%s", WORK, base, INDEX_IDX); + if (((((idx_fp = OPEN_IN(idx_fn)) == NULL) && open_fn) || + !(open_fn || idx_fp)) && + ((((widx_fp = OPEN_IN(widx_fn)) == NULL) && open_fn) || + !(open_fn || widx_fp))) { + sprintf(arg, "%s", + (strchr(idx_fn, ':') || (strlen(WORK) == 0)) ? + NIL : "<" WORK ">"); + sprintf(message, + "Couldn't find neither input file %s%%s nor %s%%s.\n", + arg, arg); + FATAL2(message, base, idx_fn); + } + } + if (!open_fn) { /* Close files if open */ + if (idx_fp) + FCLOSE(idx_fp); + if (widx_fp) + FCLOSE(widx_fp); + } + if (open_fn && (!idx_fp) && widx_fp) { /* File was found on PVS W */ + idx_fp = widx_fp; + idx_fn = widx_fn; + } +#else /* NOT OS_BS2000 */ + if ( ( open_fn && + ((idx_fp = OPEN_IN(idx_fn)) == NULL) + ) || + ((!open_fn) && (access(idx_fn, R_OK) != 0))) + if (with_ext) { + FATAL("Input index file %s not found.\n", idx_fn); + } else { + +#ifdef DEBUG + totmem += STRING_MAX; + (void)fprintf(stderr,"check_idx()-2: malloc(%d)\ttotmem = %ld\n", + STRING_MAX,totmem); +#endif /* DEBUG */ + + if ((idx_fn = (char *) malloc(STRING_MAX)) == NULL) + FATAL("Not enough core...abort.\n", ""); + sprintf(idx_fn, "%s%s", base, INDEX_IDX); + if ((open_fn && + ((idx_fp = OPEN_IN(idx_fn)) == NULL) + ) || + ((!open_fn) && (access(idx_fn, R_OK) != 0))) { + FATAL2("Couldn't find input index file %s nor %s.\n", base, + idx_fn); + } + } +#endif /* OS_BS2000 */ +} + + +static void +#if STDC +check_all(char *fn, int ind_given, int ilg_given, int log_given) +#else +check_all(fn, ind_given, ilg_given, log_given) +char *fn; +int ind_given; +int ilg_given; +int log_given; +#endif +{ + check_idx(fn, TRUE); + + /* index output file */ + if (!ind_given) { + sprintf(ind, "%s%s", base, INDEX_IND); + ind_fn = ind; +#if OS_BS2000 /* Look on HOME-, then WORK-PVS */ + if ((ind_fp = OPEN_IN(ind_fn)) == NULL) { + sprintf(ind, "%s%s%s", strchr(base, ':') ? + NIL : WORK, base, INDEX_IND); + ind_fn = ind; + } else + fclose(ind_fp); +#endif /* OS_BS2000 */ + } + if ((ind_fp = OPEN_OUT(ind_fn)) == NULL) + FATAL("Can't create output index file %s.\n", ind_fn); + + /* index transcript file */ + if (!ilg_given) { + sprintf(ilg, "%s%s", base, INDEX_ILG); + ilg_fn = ilg; +#if OS_BS2000 /* Look on HOME-, then WORK-PVS */ + if ((ilg_fp = OPEN_IN(ilg_fn)) == NULL) { + sprintf(ilg, "%s%s%s", strchr(base, ':') ? + NIL : WORK, base, INDEX_ILG); + ilg_fn = ilg; + } else + fclose(ilg_fp); +#endif /* OS_BS2000 */ + } + if ((ilg_fp = OPEN_OUT(ilg_fn)) == NULL) + FATAL("Can't create transcript file %s.\n", ilg_fn); + +#if OS_BS2000 /* Search both on HOME-PVS ans + * WORK-PVS */ + if (log_given) { + sprintf(log_fn, "%s%s%s", strchr(base, ':') ? NIL : WORK, + base, INDEX_LOG); + if ((log_fp = OPEN_IN(log_fn)) == NULL) { + if (strchr(base, ':')) + sprintf(log_fn, "%s%s", strrchr(base, ':') + 1, INDEX_LOG); + else + sprintf(log_fn, "%s%s", base, INDEX_LOG); + if ((log_fp = OPEN_IN(log_fn)) == NULL) + FATAL2("Source log file %s%s not found.\n", WORK, log_fn); + } else { + find_pageno(); + CLOSE(log_fp); + } + } +#else + if (log_given) { + sprintf(log_fn, "%s%s", base, INDEX_LOG); +#if OS_PCDOS /* open in binary mode (CR-LF) */ + if ((log_fp = OPEN_IN_B(log_fn)) == NULL) { +#else + if ((log_fp = OPEN_IN(log_fn)) == NULL) { +#endif /* OS_PCDOS */ + FATAL("Source log file %s not found.\n", log_fn); + } else { + find_pageno(); + CLOSE(log_fp); + } + } +#endif /* OS_BS2000 */ +} + + +static void +find_pageno(VOID_ARG) +{ + int i = 0; + int p, c; + +#if (OS_VAXVMS | OS_BS2000 | OS_MVSXA) + /* + * Scan forward through the file for VMS, because fseek doesn't work on + * variable record files + */ + c = GET_CHAR(log_fp); + while (c != EOF) { + p = c; + c = GET_CHAR(log_fp); + if (p == LSQ && isdigit(c)) { + i = 0; + do { + pageno[i++] = c; + c = GET_CHAR(log_fp); + } while (isdigit(c)); + pageno[i] = NUL; + } + } + if (i == 0) { + fprintf(ilg_fp, "Couldn't find any page number in %s...ignored\n", + log_fn); + init_page = FALSE; + } +#else /* NOT (OS_VAXVMS | ...) */ + fseek(log_fp, -1L, 2); + p = GET_CHAR(log_fp); + fseek(log_fp, -2L, 1); + do { + c = p; + p = GET_CHAR(log_fp); + } while (!(((p == LSQ) && isdigit(c)) || (fseek(log_fp, -2L, 1) != 0))); + if (p == LSQ) { + while ((c = GET_CHAR(log_fp)) == SPC); + do { + pageno[i++] = (char) c; + c = GET_CHAR(log_fp); + } while (isdigit(c)); + pageno[i] = NUL; + } else { + fprintf(ilg_fp, "Couldn't find any page number in %s...ignored\n", + log_fn); + init_page = FALSE; + } +#endif /* (OS_VAXVMS | ...) */ +} + +static void +#if STDC +open_sty(char *fn) +#else +open_sty(fn) +char *fn; +#endif +{ + char *path; + char *ptr; + int i; + int len; + + if ((path = getenv(STYLE_PATH)) == NULL) { + /* style input path not defined */ + strcpy(sty_fn, fn); + sty_fp = OPEN_IN(sty_fn); + } else { +#if OS_VAXVMS + if ((strlen(STYLE_PATH) + strlen(fn) + 1) > ARRAY_MAX) { + FATAL2("Path %s too long (max %d).\n", STYLE_PATH, ARRAY_MAX); + } else { + sprintf(sty_fn, "%s:%s", STYLE_PATH, fn); + sty_fp = OPEN_IN(sty_fn); + } +#else /* NOT OS_VAXVMS */ + len = ARRAY_MAX - strlen(fn) - 1; + while (*path != NUL) { +#if OS_XENIX + i = 0; + while ((*path != ENV_SEPAR) && (*path != NUL) && (i < len)) + sty_fn[i++] = *path++; +#else /* NOT OS_XENIX */ + ptr = strchr(path, ENV_SEPAR); + i = 0; + if (ptr == (char*)NULL) + { + int j = strlen(path); + + while (i < j) + sty_fn[i++] = *path++; + } + else + { + while ((path != ptr) && (i < len)) + sty_fn[i++] = *path++; + } +#endif /* OS_XENIX */ + if (i == len) { + FATAL2("Path %s too long (max %d).\n", sty_fn, ARRAY_MAX); + } else { +#ifdef OS_VAXVMS + if (sty_fn[i-1] != ']') + sty_fn[i++] = DIR_DELIM; +#else + sty_fn[i++] = DIR_DELIM; +#endif + sty_fn[i] = NUL; + strcat(sty_fn, fn); +#if OS_XENIX + if (((sty_fp = OPEN_IN(sty_fn)) == NULL) && (*path != NUL)) +#else /* NOT OS_XENIX */ + if ((sty_fp = OPEN_IN(sty_fn)) == NULL) +#endif /* OS_XENIX */ + path++; + else + break; + } + } +#endif /* OS_VAXVMS */ + } + + if (sty_fp == NULL) + FATAL("Index style file %s not found.\n", fn); +} + + +int +#if STDC +strtoint(char *str) +#else +strtoint(str) +char *str; +#endif +{ + int val = 0; + + while (*str != NUL) { +#if (OS_BS2000 | OS_MVSXA) + val = 10 * val + *str - '0'; +#else + val = 10 * val + *str - 48; +#endif /* (OS_BS2000 | OS_MVSXA) */ + str++; + } + return (val); +} |