home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fonts 1
/
freshfonts1.bin
/
bbs
/
programs
/
amiga
/
makeindex.lha
/
makeindex-2.12
/
src
/
scanid.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-26
|
18KB
|
831 lines
/*
*
* 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.
*
*/
#include "mkind.h"
#include "scanid.h"
#define CHECK_LENGTH() if (i > len_field) goto OVERFLOW
int idx_lc; /* line count */
int idx_tc; /* total entry count */
int idx_ec; /* erroneous entry count */
int idx_dc; /* number of dots printed so far */
static int first_entry = TRUE;
static int comp_len;
static char key[ARGUMENT_MAX];
static char no[NUMBER_MAX];
extern char *strchr ARGS((const char* s,int c));
NODE_PTR head;
NODE_PTR tail;
static void flush_to_eol ARGS((void));
static int make_key ARGS((void));
static void make_string ARGS((char **ppstr,int n));
static int scan_alpha_lower ARGS((char *no,short *npg,short *count));
static int scan_alpha_upper ARGS((char *no,short *npg,short *count));
static int scan_arabic ARGS((char *no,short *npg,short *count));
static int scan_arg1 ARGS((void));
static int scan_arg2 ARGS((void));
static int scan_field ARGS((int *n,char field[],int len_field,
int ck_level, int ck_encap,int ck_actual));
static int scan_key ARGS((struct KFIELD *data));
static int scan_no ARGS((char *no,short *npg,short *count,short *type));
static int scan_roman_lower ARGS((char *no,short *npg,short *count));
static int scan_roman_upper ARGS((char *no,short *npg,short *count));
static void search_quote ARGS((char sort_key[],char actual_key[]));
#if (OS_BS2000 | OS_MVSXA)
char UPCC[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
#endif
void
scan_idx(VOID_ARG)
{
char keyword[ARRAY_MAX];
int c;
int i = 0;
int not_eof = TRUE;
int arg_count = -1;
MESSAGE("Scanning input file %s...", idx_fn);
idx_lc = idx_tc = idx_ec = idx_dc = 0;
comp_len = strlen(page_comp);
while (not_eof) {
switch (c = GET_CHAR(idx_fp)) {
case EOF:
if (arg_count == 2) {
idx_lc++;
if (make_key())
IDX_DOT(DOT_MAX);
arg_count = -1;
} else
not_eof = FALSE;
break;
case LFD:
idx_lc++;
if (arg_count == 2) {
if (make_key())
IDX_DOT(DOT_MAX);
arg_count = -1;
} else if (arg_count > -1) {
IDX_ERROR("Missing arguments -- need two (premature LFD).\n",
NULL);
arg_count = -1;
}
case TAB:
case SPC:
break;
default:
switch (arg_count) {
case -1:
i = 0;
keyword[i++] = (char) c;
arg_count++;
idx_tc++;
break;
case 0:
if (c == idx_aopen) {
arg_count++;
keyword[i] = NUL;
if (STREQ(keyword, idx_keyword)) {
if (!scan_arg1()) {
arg_count = -1;
}
} else {
IDX_SKIPLINE;
IDX_ERROR("Unknown index keyword %s.\n", keyword);
}
} else {
if (i < ARRAY_MAX)
keyword[i++] = (char) c;
else {
IDX_SKIPLINE;
IDX_ERROR2("Index keyword %s too long (max %d).\n",
keyword, ARRAY_MAX);
}
}
break;
case 1:
if (c == idx_aopen) {
arg_count++;
if (!scan_arg2()) {
arg_count = -1;
}
} else {
IDX_SKIPLINE;
IDX_ERROR(
"No opening delimiter for second argument (illegal character `%c').\n", c);
}
break;
case 2:
IDX_SKIPLINE;
IDX_ERROR(
"No closing delimiter for second argument (illegal character `%c').\n", c);
break;
}
break;
}
}
/* fixup the total counts */
idx_tt += idx_tc;
idx_et += idx_ec;
DONE(idx_tc - idx_ec, "entries accepted", idx_ec, "rejected");
CLOSE(idx_fp);
}
static void
flush_to_eol(VOID_ARG)
{ /* flush to end-of-line, or end-of-file, whichever is first */
int a;
while ( ((a = GET_CHAR(idx_fp)) != LFD) && (a != EOF) )
/* NO-OP */;
}
static int
make_key(VOID_ARG)
{
NODE_PTR ptr;
int i;
/* allocate and initialize a node */
#ifdef DEBUG
totmem += sizeof(NODE);
(void)fprintf(stderr,"make_key(): malloc(%d)\ttotmem = %ld\n",
sizeof(NODE),totmem);
#endif /* DEBUG */
if ((ptr = (NODE_PTR) malloc(sizeof(NODE))) == NULL)
FATAL("Not enough core...abort.\n", "");
for (i = 0; i < FIELD_MAX; i++)
{
ptr->data.sf[i] = ""; /* initialize fields to pointers */;
ptr->data.af[i] = ""; /* to constant empty strings */
}
ptr->data.encap = "";
ptr->data.lpg[0] = NUL;
ptr->data.count = 0;
ptr->data.type = EMPTY;
/* process index key */
if (!scan_key(&(ptr->data)))
return (FALSE);
/* determine group type */
ptr->data.group = group_type(ptr->data.sf[0]);
/* process page number */
strcpy(ptr->data.lpg, no);
if (!scan_no(no, ptr->data.npg, &(ptr->data.count), &(ptr->data.type)))
return (FALSE);
if (first_entry) {
head = tail = ptr;
first_entry = FALSE;
} else {
tail->next = ptr;
tail = ptr;
}
ptr->data.lc = idx_lc;
ptr->data.fn = idx_fn;
tail->next = NULL;
return (TRUE);
}
static void
#if STDC
make_string(char **ppstr, int n)
#else
make_string(ppstr,n) /* allocate n-byte string if *ppstr */
char **ppstr; /* points to an empty string */
int n;
#endif
{
if ((*ppstr)[0] == NUL) /* then we have an empty string */
{
(*ppstr) = (char*)malloc(n);
if ((*ppstr) == (char*)NULL)
FATAL("Not enough core...abort.\n", "");
(*ppstr)[0] = NUL;
}
}
static int
#if STDC
scan_key(FIELD_PTR data)
#else
scan_key(data)
FIELD_PTR data;
#endif
{
int i = 0; /* current level */
int n = 0; /* index to the key[] array */
int second_round = FALSE;
int last = FIELD_MAX - 1;
while (TRUE) {
if (key[n] == NUL)
break;
if (key[n] == idx_encap)
{
n++;
make_string(&(data->encap),strlen(key) + 1);
if (scan_field(&n, data->encap, strlen(key), FALSE, FALSE, FALSE))
break;
else
return (FALSE);
}
if (key[n] == idx_actual) {
n++;
if (i == last)
{
make_string(&(data->af[i]),strlen(key) + 1);
if (!scan_field(&n, data->af[i], strlen(key),
FALSE, TRUE, FALSE))
return (FALSE);
}
else
{
make_string(&(data->af[i]),strlen(key) + 1);
if (!scan_field(&n, data->af[i], strlen(key),
TRUE, TRUE, FALSE))
return (FALSE);
}
} else {
/* Next nesting level */
if (second_round) {
i++;
n++;
}
if (i == last)
{
make_string(&(data->sf[i]),strlen(key) + 1);
if (!scan_field(&n, data->sf[i], strlen(key),
FALSE, TRUE, TRUE))
return (FALSE);
}
else
{
make_string(&(data->sf[i]),strlen(key) + 1);
if (!scan_field(&n, data->sf[i], strlen(key),
TRUE, TRUE, TRUE))
return (FALSE);
}
second_round = TRUE;
if (german_sort && strchr(data->sf[i], '"'))
{
make_string(&(data->af[i]),strlen(data->sf[i]) + 1);
search_quote(data->sf[i], data->af[i]);
}
}
}
/* check for empty fields which shouldn't be empty */
if (*data->sf[0] == NUL) {
NULL_RTN;
}
for (i = 1; i < FIELD_MAX - 1; i++)
if ((*data->sf[i] == NUL) &&
((*data->af[i] != NUL) || (*data->sf[i + 1] != NUL))) {
NULL_RTN;
}
/* i == FIELD_MAX-1 */
if ((*data->sf[i] == NUL) && (*data->af[i] != NUL)) {
NULL_RTN;
}
return (TRUE);
}
static int
#if STDC
scan_field(int *n, char field[], int len_field, int ck_level, int ck_encap,
int ck_actual)
#else
scan_field(n, field, len_field, ck_level, ck_encap, ck_actual)
int *n;
char field[];
int len_field; /* length of field[], EXCLUDING space for final NUL */
int ck_level;
int ck_encap;
int ck_actual;
#endif
{
int i = 0;