/* * * This file is part of * MakeIndex - A formatter and format independent index processor * * Copyright (C) 1998-2011 by the TeX Live project. * 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 * * 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 "scanst.h" static int sty_lc = 0; /* line count */ static int sty_tc = 0; /* total count */ static int sty_ec = 0; /* error count */ char idx_keyword[ARRAY_MAX] = IDX_KEYWORD; char idx_aopen = IDX_AOPEN; char idx_aclose = IDX_ACLOSE; char idx_level = IDX_LEVEL; char idx_ropen = IDX_ROPEN; char idx_rclose = IDX_RCLOSE; char idx_quote = IDX_QUOTE; char idx_actual = IDX_ACTUAL; char idx_encap = IDX_ENCAP; char idx_escape = IDX_ESCAPE; char preamble[ARRAY_MAX] = PREAMBLE_DEF; char postamble[ARRAY_MAX] = POSTAMBLE_DEF; int prelen = PREAMBLE_LEN; int postlen = POSTAMBLE_LEN; char setpage_open[ARRAY_MAX] = SETPAGEOPEN_DEF; char setpage_close[ARRAY_MAX] = SETPAGECLOSE_DEF; int setpagelen = SETPAGE_LEN; char group_skip[ARRAY_MAX] = GROUPSKIP_DEF; int skiplen = GROUPSKIP_LEN; int headings_flag = HEADINGSFLAG_DEF; char heading_pre[ARRAY_MAX] = HEADINGPRE_DEF; char heading_suf[ARRAY_MAX] = HEADINGSUF_DEF; int headprelen = HEADINGPRE_LEN; int headsuflen = HEADINGSUF_LEN; char symhead_pos[ARRAY_MAX] = SYMHEADPOS_DEF; char symhead_neg[ARRAY_MAX] = SYMHEADNEG_DEF; char numhead_pos[ARRAY_MAX] = NUMHEADPOS_DEF; char numhead_neg[ARRAY_MAX] = NUMHEADNEG_DEF; char item_r[FIELD_MAX][ARRAY_MAX] = {ITEM0_DEF, ITEM1_DEF, ITEM2_DEF}; char item_u[FIELD_MAX][ARRAY_MAX] = {"", ITEM1_DEF, ITEM2_DEF}; char item_x[FIELD_MAX][ARRAY_MAX] = {"", ITEM1_DEF, ITEM2_DEF}; int ilen_r[FIELD_MAX] = {ITEM_LEN, ITEM_LEN, ITEM_LEN}; int ilen_u[FIELD_MAX] = {0, ITEM_LEN, ITEM_LEN}; int ilen_x[FIELD_MAX] = {0, ITEM_LEN, ITEM_LEN}; char delim_p[FIELD_MAX][ARRAY_MAX] = {DELIM_DEF, DELIM_DEF, DELIM_DEF}; char delim_n[ARRAY_MAX] = DELIM_DEF; /* page number separator */ char delim_r[ARRAY_MAX] = DELIMR_DEF;/* page range designator */ char delim_t[ARRAY_MAX] = DELIMT_DEF;/* page list terminating delimiter */ char suffix_2p[ARRAY_MAX] = ""; /* suffix for two page ranges */ char suffix_3p[ARRAY_MAX] = ""; /* suffix for three page ranges */ char suffix_mp[ARRAY_MAX] = ""; /* suffix for multiple page ranges */ char encap_p[ARRAY_MAX] = ENCAP0_DEF;/* encapsulator prefix */ char encap_i[ARRAY_MAX] = ENCAP1_DEF;/* encapsulator infix */ char encap_s[ARRAY_MAX] = ENCAP2_DEF;/* encapsulator postfix */ int linemax = LINE_MAX; int indent_length = INDENTLEN_DEF; char indent_space[ARRAY_MAX] = INDENTSPC_DEF; char page_comp[ARRAY_MAX] = COMPOSITOR_DEF; int page_offset[PAGETYPE_MAX] = { 0, ROMAN_LOWER_OFFSET, ROMAN_LOWER_OFFSET + ARABIC_OFFSET, ROMAN_LOWER_OFFSET + ARABIC_OFFSET + ALPHA_LOWER_OFFSET, ROMAN_LOWER_OFFSET + ARABIC_OFFSET + ALPHA_LOWER_OFFSET + ROMAN_UPPER_OFFSET }; char page_prec[ARRAY_MAX] = PRECEDENCE_DEF; static int put_dot; static int count_lfd (char *str); static int next_nonblank (void); static int process_precedence (void); static int scan_char (char *c); static int scan_spec (char *spec); static int scan_string (char *str); void scan_sty(void) { char spec[STRING_MAX]; int tmp; MESSAGE1("Scanning style file %s", sty_fn); while (scan_spec(spec)) { sty_tc++; put_dot = TRUE; /* output pre- and post-ambles */ if (STREQ(spec, PREAMBLE)) { (void) scan_string(preamble); prelen = count_lfd(preamble); } else if (STREQ(spec, POSTAMBLE)) { (void) scan_string(postamble); postlen = count_lfd(postamble); } else if (STREQ(spec, GROUP_SKIP)) { (void) scan_string(group_skip); skiplen = count_lfd(group_skip); } else if (STREQ(spec, HEADINGS_FLAG)) { SCAN_NO(&headings_flag); } else if (STREQ(spec, HEADING_PRE)) { (void) scan_string(heading_pre); headprelen = count_lfd(heading_pre); } else if (STREQ(spec, HEADING_SUF)) { (void) scan_string(heading_suf); headsuflen = count_lfd(heading_suf); } else if (STREQ(spec, SYMHEAD_POS)) { (void) scan_string(symhead_pos); } else if (STREQ(spec, SYMHEAD_NEG)) { (void) scan_string(symhead_neg); } else if (STREQ(spec, NUMHEAD_POS)) { (void) scan_string(numhead_pos); } else if (STREQ(spec, NUMHEAD_NEG)) { (void) scan_string(numhead_neg); } else if (STREQ(spec, SETPAGEOPEN)) { (void) scan_string(setpage_open); setpagelen = count_lfd(setpage_open); } else if (STREQ(spec, SETPAGECLOSE)) { (void) scan_string(setpage_close); setpagelen = count_lfd(setpage_close); /* output index item commands */ } else if (STREQ(spec, ITEM_0)) { (void) scan_string(item_r[0]); ilen_r[0] = count_lfd(item_r[0]); } else if (STREQ(spec, ITEM_1)) { (void) scan_string(item_r[1]); ilen_r[1] = count_lfd(item_r[1]); } else if (STREQ(spec, ITEM_2)) { (void) scan_string(item_r[2]); ilen_r[2] = count_lfd(item_r[2]); } else if (STREQ(spec, ITEM_01)) { (void) scan_string(item_u[1]); ilen_u[1] = count_lfd(item_u[1]); } else if (STREQ(spec, ITEM_12)) { (void) scan_string(item_u[2]); ilen_u[2] = count_lfd(item_u[2]); } else if (STREQ(spec, ITEM_x1)) { (void) scan_string(item_x[1]); ilen_x[1] = count_lfd(item_x[1]); } else if (STREQ(spec, ITEM_x2)) { (void) scan_string(item_x[2]); ilen_x[2] = count_lfd(item_x[2]); /* output encapsulators */ } else if (STREQ(spec, ENCAP_0)) (void) scan_string(encap_p); else if (STREQ(spec, ENCAP_1)) (void) scan_string(encap_i); else if (STREQ(spec, ENCAP_2)) (void) scan_string(encap_s); /* output delimiters */ else if (STREQ(spec, DELIM_0)) (void) scan_string(delim_p[0]); else if (STREQ(spec, DELIM_1)) (void) scan_string(delim_p[1]); else if (STREQ(spec, DELIM_2)) (void) scan_string(delim_p[2]); else if (STREQ(spec, DELIM_N)) (void) scan_string(delim_n); else if (STREQ(spec, DELIM_R)) (void) scan_string(delim_r); else if (STREQ(spec, DELIM_T)) (void) scan_string(delim_t); else if (STREQ(spec, SUFFIX_2P)) (void) scan_string(suffix_2p); else if (STREQ(spec, SUFFIX_3P)) (void) scan_string(suffix_3p); else if (STREQ(spec, SUFFIX_MP)) (void) scan_string(suffix_mp); /* output line width */ else if (STREQ(spec, LINEMAX)) { SCAN_NO(&tmp); if (tmp > 0) linemax = tmp; else STY_ERROR2("%s must be positive (got %d)", LINEMAX, tmp); /* output line indentation length */ } else if (STREQ(spec, INDENT_LENGTH)) { SCAN_NO(&tmp); if (tmp >= 0) indent_length = tmp; else STY_ERROR2("%s must be nonnegative (got %d)", INDENT_LENGTH, tmp); /* output line indentation */ } else if (STREQ(spec, INDENT_SPACE)) { (void) scan_string(indent_space); /* composite page delimiter */ } else if (STREQ(spec, COMPOSITOR)) { (void) scan_string(page_comp); /* page precedence */ } else if (STREQ(spec, PRECEDENCE)) { (void) scan_string(page_prec); /* index input format */ } else if (STREQ(spec, KEYWORD)) (void) scan_string(idx_keyword); else if (STREQ(spec, AOPEN)) (void) scan_char(&idx_aopen); else if (STREQ(spec, ACLOSE)) (void) scan_char(&idx_aclose); else if (STREQ(spec, LEVEL)) (void) scan_char(&idx_level); else if (STREQ(spec, ROPEN)) (void) scan_char(&idx_ropen); else if (STREQ(spec, RCLOSE)) (void) scan_char(&idx_rclose); else if (STREQ(spec, QUOTE)) (void) scan_char(&idx_quote); else if (STREQ(spec, ACTUAL)) (void) scan_char(&idx_actual); else if (STREQ(spec, ENCAP)) (void) scan_char(&idx_encap); else if (STREQ(spec, ESCAPE)) (void) scan_char(&idx_escape); else { (void) next_nonblank(); STY_SKIPLINE; STY_ERROR1("Unknown specifier %s.\n", spec); put_dot = FALSE; } if (put_dot) { STY_DOT; } } /* page precedence */ (void) process_precedence(); /* check if quote and escape are distinct */ if (idx_quote == idx_escape) { STY_ERROR1( "Quote and escape symbols must be distinct (both `%c' now).\n", idx_quote); idx_quote = IDX_QUOTE; idx_escape = IDX_ESCAPE; } DONE(sty_tc - sty_ec, "attributes redefined", sty_ec, "ignored"); CLOSE(sty_fp); } static int scan_spec(char spec[]) { int i = 0; int c; while (TRUE) if ((c = next_nonblank()) == -1) return (FALSE); else if (c == COMMENT) { STY_SKIPLINE; } else break; spec[0] = TOLOWER(c); while ((i++ < STRING_MAX) && ((c = GET_CHAR(sty_fp)) != SPC) && (c != TAB) && (c != LFD) && (c != EOF)) spec[i] = TOLOWER(c); if (i < STRING_MAX) { spec[i] = NUL; if (c == EOF) { STY_ERROR1( "No attribute for specifier %s (premature EOF)\n", spec); return (-1); } if (c == LFD) sty_lc++; return (TRUE); } else { STY_ERROR2("Specifier %s too long (max %d).\n", spec, STRING_MAX); return (FALSE); } } static int next_nonblank(void) { int c; while (TRUE) { switch (c = GET_CHAR(sty_fp)) { case EOF: return (-1); case LFD: sty_lc++; case SPC: case TAB: break; default: return (c); } } } static int scan_string(char str[]) { char clone[ARRAY_MAX]; int i = 0; int c; switch (c = next_nonblank()) { case STR_DELIM: while (TRUE) switch (c = GET_CHAR(sty_fp)) { case EOF: STY_ERROR1("No closing delimiter in %s.\n", clone); return (FALSE); case STR_DELIM: clone[i] = NUL; strcpy(str, clone); return (TRUE); case BSH: switch (c = GET_CHAR(sty_fp)) { case 't': clone[i++] = TAB; break; case 'n': clone[i++] = LFD; break; default: clone[i++] = (char) c; break; } break; default: if (c == LFD) sty_lc++; if (i < ARRAY_MAX) clone[i++] = (char) c; else { STY_SKIPLINE; STY_ERROR2( "Attribute string %s too long (max %d).\n", clone, ARRAY_MAX); return (FALSE); } break; } break; case COMMENT: STY_SKIPLINE; break; default: STY_SKIPLINE; STY_ERROR("No opening delimiter.\n"); return (FALSE); } return (TRUE); /* function value no longer used */ } static int scan_char(char *c) { int clone; switch (clone = next_nonblank()) { case CHR_DELIM: switch (clone = GET_CHAR(sty_fp)) { case CHR_DELIM: STY_SKIPLINE; STY_ERROR("Premature closing delimiter.\n"); return (FALSE); case LFD: sty_lc++; case EOF: STY_ERROR("No character (premature EOF).\n"); return (FALSE); case BSH: clone = GET_CHAR(sty_fp); default: if (GET_CHAR(sty_fp) == CHR_DELIM) { *c = (char) clone; return (TRUE); } else { STY_ERROR("No closing delimiter or too many letters.\n"); return (FALSE); } } /* break; */ /* NOT REACHED */ case COMMENT: STY_SKIPLINE; break; default: STY_SKIPLINE; STY_ERROR("No opening delimiter.\n"); return (FALSE); } return (TRUE); /* function value no longer used */ } static int count_lfd(char *str) { int i = 0; int n = 0; while (str[i] != NUL) { if (str[i] == LFD) n++; i++; } return (n); } static int process_precedence(void) { int order[PAGETYPE_MAX]; int type[PAGETYPE_MAX]; int i = 0; int last; int roml = FALSE; int romu = FALSE; int arab = FALSE; int alpl = FALSE; int alpu = FALSE; /* check for llegal specifiers first */ while ((i < PAGETYPE_MAX) && (page_prec[i] != NUL)) { switch (page_prec[i]) { case ROMAN_LOWER: if (roml) { MULTIPLE(ROMAN_LOWER); } else roml = TRUE; break; case ROMAN_UPPER: if (romu) { MULTIPLE(ROMAN_UPPER); } else romu = TRUE; break; case ARABIC: if (arab) { MULTIPLE(ARABIC); } else arab = TRUE; break; case ALPHA_LOWER: if (alpl) { MULTIPLE(ALPHA_UPPER); } else alpl = TRUE; break; case ALPHA_UPPER: if (alpu) { MULTIPLE(ALPHA_UPPER); } else alpu = TRUE; break; default: STY_SKIPLINE; STY_ERROR1("Unknow type `%c' in page precedence specification.\n", page_prec[i]); return (FALSE); } i++; } if (page_prec[i] != NUL) { STY_SKIPLINE; STY_ERROR("Page precedence specification string too long.\n"); return (FALSE); } last = i; switch (page_prec[0]) { case ROMAN_LOWER: order[0] = ROMAN_LOWER_OFFSET; type[0] = ROML; break; case ROMAN_UPPER: order[0] = ROMAN_UPPER_OFFSET; type[0] = ROMU; break; case ARABIC: order[0] = ARABIC_OFFSET; type[0] = ARAB; break; case ALPHA_LOWER: order[0] = ALPHA_LOWER_OFFSET; type[0] = ALPL; break; case ALPHA_UPPER: order[0] = ALPHA_LOWER_OFFSET; type[0] = ALPU; break; } i = 1; while (i < last) { switch (page_prec[i]) { case ROMAN_LOWER: order[i] = order[i - 1] + ROMAN_LOWER_OFFSET; type[i] = ROML; break; case ROMAN_UPPER: order[i] = order[i - 1] + ROMAN_UPPER_OFFSET; type[i] = ROMU; break; case ARABIC: order[i] = order[i - 1] + ARABIC_OFFSET; type[i] = ARAB; break; case ALPHA_LOWER: order[i] = order[i - 1] + ALPHA_LOWER_OFFSET; type[i] = ALPL; break; case ALPHA_UPPER: order[i] = order[i - 1] + ALPHA_LOWER_OFFSET; type[i] = ALPU; break; } i++; } for (i = 0; i < PAGETYPE_MAX; i++) { page_offset[i] = -1; } page_offset[type[0]] = 0; for (i = 1; i < last; i++) { page_offset[type[i]] = order[i - 1]; } for (i = 0; i < PAGETYPE_MAX; i++) { if (page_offset[i] == -1) { switch (type[last - 1]) { case ROML: order[last] = order[last - 1] + ROMAN_LOWER_OFFSET; break; case ROMU: order[last] = order[last - 1] + ROMAN_UPPER_OFFSET; break; case ARAB: order[last] = order[last - 1] + ARABIC_OFFSET; break; case ALPL: order[last] = order[last - 1] + ALPHA_LOWER_OFFSET; break; case ALPU: order[last] = order[last - 1] + ALPHA_UPPER_OFFSET; break; } type[last] = i; page_offset[i] = order[last]; last++; } } return (TRUE); /* function value no longer used */ }