Back to index

tetex-bin  3.0
scanst.c
Go to the documentation of this file.
00001 /*
00002  *
00003  *  This file is part of
00004  *     MakeIndex - A formatter and format independent index processor
00005  *
00006  *  Copyright (C) 1989 by Chen & Harrison International Systems, Inc.
00007  *  Copyright (C) 1988 by Olivetti Research Center
00008  *  Copyright (C) 1987 by Regents of the University of California
00009  *
00010  *  Author:
00011  *     Pehong Chen
00012  *     Chen & Harrison International Systems, Inc.
00013  *     Palo Alto, California
00014  *     USA
00015  *     (phc@renoir.berkeley.edu or chen@orc.olivetti.com)
00016  *
00017  *  Contributors:
00018  *     Please refer to the CONTRIB file that comes with this release
00019  *     for a list of people who have contributed to this and/or previous
00020  *     release(s) of MakeIndex.
00021  *
00022  *  All rights reserved by the copyright holders.  See the copyright
00023  *  notice distributed with this software for a complete description of
00024  *  the conditions under which it is made available.
00025  *
00026  */
00027 
00028 #include    "mkind.h"
00029 #include    "scanst.h"
00030 
00031 static int sty_lc = 0;                 /* line count */
00032 static int sty_tc = 0;                 /* total count */
00033 static int sty_ec = 0;                 /* error count */
00034 
00035 char    idx_keyword[ARRAY_MAX] = IDX_KEYWORD;
00036 char    idx_aopen = IDX_AOPEN;
00037 char    idx_aclose = IDX_ACLOSE;
00038 char    idx_level = IDX_LEVEL;
00039 char    idx_ropen = IDX_ROPEN;
00040 char    idx_rclose = IDX_RCLOSE;
00041 char    idx_quote = IDX_QUOTE;
00042 char    idx_actual = IDX_ACTUAL;
00043 char    idx_encap = IDX_ENCAP;
00044 char    idx_escape = IDX_ESCAPE;
00045 
00046 char    preamble[ARRAY_MAX] = PREAMBLE_DEF;
00047 char    postamble[ARRAY_MAX] = POSTAMBLE_DEF;
00048 int     prelen = PREAMBLE_LEN;
00049 int     postlen = POSTAMBLE_LEN;
00050 
00051 char    setpage_open[ARRAY_MAX] = SETPAGEOPEN_DEF;
00052 char    setpage_close[ARRAY_MAX] = SETPAGECLOSE_DEF;
00053 int     setpagelen = SETPAGE_LEN;
00054 
00055 char    group_skip[ARRAY_MAX] = GROUPSKIP_DEF;
00056 int     skiplen = GROUPSKIP_LEN;
00057 
00058 int     headings_flag = HEADINGSFLAG_DEF;
00059 char    heading_pre[ARRAY_MAX] = HEADINGPRE_DEF;
00060 char    heading_suf[ARRAY_MAX] = HEADINGSUF_DEF;
00061 int     headprelen = HEADINGPRE_LEN;
00062 int     headsuflen = HEADINGSUF_LEN;
00063 
00064 char    symhead_pos[ARRAY_MAX] = SYMHEADPOS_DEF;
00065 char    symhead_neg[ARRAY_MAX] = SYMHEADNEG_DEF;
00066 
00067 char    numhead_pos[ARRAY_MAX] = NUMHEADPOS_DEF;
00068 char    numhead_neg[ARRAY_MAX] = NUMHEADNEG_DEF;
00069 
00070 char    item_r[FIELD_MAX][ARRAY_MAX] = {ITEM0_DEF, ITEM1_DEF, ITEM2_DEF};
00071 char    item_u[FIELD_MAX][ARRAY_MAX] = {"", ITEM1_DEF, ITEM2_DEF};
00072 char    item_x[FIELD_MAX][ARRAY_MAX] = {"", ITEM1_DEF, ITEM2_DEF};
00073 
00074 int     ilen_r[FIELD_MAX] = {ITEM_LEN, ITEM_LEN, ITEM_LEN};
00075 int     ilen_u[FIELD_MAX] = {0, ITEM_LEN, ITEM_LEN};
00076 int     ilen_x[FIELD_MAX] = {0, ITEM_LEN, ITEM_LEN};
00077 
00078 char    delim_p[FIELD_MAX][ARRAY_MAX] = {DELIM_DEF, DELIM_DEF, DELIM_DEF};
00079 char    delim_n[ARRAY_MAX] = DELIM_DEF; /* page number separator */
00080 char    delim_r[ARRAY_MAX] = DELIMR_DEF;/* page range designator */
00081 char    delim_t[ARRAY_MAX] = DELIMT_DEF;/* page list terminating delimiter */
00082 
00083 char    suffix_2p[ARRAY_MAX] = "";      /* suffix for two page ranges */
00084 char    suffix_3p[ARRAY_MAX] = "";      /* suffix for three page ranges */
00085 char    suffix_mp[ARRAY_MAX] = "";      /* suffix for multiple page ranges */
00086 
00087 char    encap_p[ARRAY_MAX] = ENCAP0_DEF;/* encapsulator prefix */
00088 char    encap_i[ARRAY_MAX] = ENCAP1_DEF;/* encapsulator infix */
00089 char    encap_s[ARRAY_MAX] = ENCAP2_DEF;/* encapsulator postfix */
00090 
00091 int     linemax = LINE_MAX;
00092 
00093 int     indent_length = INDENTLEN_DEF;
00094 char    indent_space[ARRAY_MAX] = INDENTSPC_DEF;
00095 
00096 char    page_comp[ARRAY_MAX] = COMPOSITOR_DEF;
00097 int     page_offset[PAGETYPE_MAX] = {
00098 0,
00099 ROMAN_LOWER_OFFSET,
00100 ROMAN_LOWER_OFFSET + ARABIC_OFFSET,
00101 ROMAN_LOWER_OFFSET + ARABIC_OFFSET + ALPHA_LOWER_OFFSET,
00102 ROMAN_LOWER_OFFSET + ARABIC_OFFSET + ALPHA_LOWER_OFFSET + ROMAN_UPPER_OFFSET
00103 };
00104 static char page_prec[ARRAY_MAX] = PRECEDENCE_DEF;
00105 
00106 static int put_dot;
00107 
00108 static int    count_lfd ARGS((char *str));
00109 static int    next_nonblank ARGS((void));
00110 static int    process_precedence ARGS((void));
00111 static int    scan_char ARGS((char *c));
00112 static int    scan_spec ARGS((char *spec));
00113 static int    scan_string ARGS((char *str));
00114 
00115 void
00116 scan_sty(VOID_ARG)
00117 {
00118     char    spec[STRING_MAX];
00119     int     tmp;
00120 
00121     MESSAGE("Scanning style file %s", sty_fn);
00122     while (scan_spec(spec)) {
00123        sty_tc++;
00124        put_dot = TRUE;
00125 
00126        /* output pre- and post-ambles */
00127        if (STREQ(spec, PREAMBLE)) {
00128            (void) scan_string(preamble);
00129            prelen = count_lfd(preamble);
00130        } else if (STREQ(spec, POSTAMBLE)) {
00131            (void) scan_string(postamble);
00132            postlen = count_lfd(postamble);
00133        } else if (STREQ(spec, GROUP_SKIP)) {
00134            (void) scan_string(group_skip);
00135            skiplen = count_lfd(group_skip);
00136        } else if (STREQ(spec, HEADINGS_FLAG)) {
00137            SCAN_NO(&headings_flag);
00138        } else if (STREQ(spec, HEADING_PRE)) {
00139            (void) scan_string(heading_pre);
00140            headprelen = count_lfd(heading_pre);
00141        } else if (STREQ(spec, HEADING_SUF)) {
00142            (void) scan_string(heading_suf);
00143            headsuflen = count_lfd(heading_suf);
00144        } else if (STREQ(spec, SYMHEAD_POS)) {
00145            (void) scan_string(symhead_pos);
00146        } else if (STREQ(spec, SYMHEAD_NEG)) {
00147            (void) scan_string(symhead_neg);
00148        } else if (STREQ(spec, NUMHEAD_POS)) {
00149            (void) scan_string(numhead_pos);
00150        } else if (STREQ(spec, NUMHEAD_NEG)) {
00151            (void) scan_string(numhead_neg);
00152        } else if (STREQ(spec, SETPAGEOPEN)) {
00153            (void) scan_string(setpage_open);
00154            setpagelen = count_lfd(setpage_open);
00155        } else if (STREQ(spec, SETPAGECLOSE)) {
00156            (void) scan_string(setpage_close);
00157            setpagelen = count_lfd(setpage_close);
00158            /* output index item commands */
00159        } else if (STREQ(spec, ITEM_0)) {
00160            (void) scan_string(item_r[0]);
00161            ilen_r[0] = count_lfd(item_r[0]);
00162        } else if (STREQ(spec, ITEM_1)) {
00163            (void) scan_string(item_r[1]);
00164            ilen_r[1] = count_lfd(item_r[1]);
00165        } else if (STREQ(spec, ITEM_2)) {
00166            (void) scan_string(item_r[2]);
00167            ilen_r[2] = count_lfd(item_r[2]);
00168        } else if (STREQ(spec, ITEM_01)) {
00169            (void) scan_string(item_u[1]);
00170            ilen_u[1] = count_lfd(item_u[1]);
00171        } else if (STREQ(spec, ITEM_12)) {
00172            (void) scan_string(item_u[2]);
00173            ilen_u[2] = count_lfd(item_u[2]);
00174        } else if (STREQ(spec, ITEM_x1)) {
00175            (void) scan_string(item_x[1]);
00176            ilen_x[1] = count_lfd(item_x[1]);
00177        } else if (STREQ(spec, ITEM_x2)) {
00178            (void) scan_string(item_x[2]);
00179            ilen_x[2] = count_lfd(item_x[2]);
00180            /* output encapsulators */
00181        } else if (STREQ(spec, ENCAP_0))
00182            (void) scan_string(encap_p);
00183        else if (STREQ(spec, ENCAP_1))
00184            (void) scan_string(encap_i);
00185        else if (STREQ(spec, ENCAP_2))
00186            (void) scan_string(encap_s);
00187        /* output delimiters */
00188        else if (STREQ(spec, DELIM_0))
00189            (void) scan_string(delim_p[0]);
00190        else if (STREQ(spec, DELIM_1))
00191            (void) scan_string(delim_p[1]);
00192        else if (STREQ(spec, DELIM_2))
00193            (void) scan_string(delim_p[2]);
00194        else if (STREQ(spec, DELIM_N))
00195            (void) scan_string(delim_n);
00196        else if (STREQ(spec, DELIM_R))
00197            (void) scan_string(delim_r);
00198        else if (STREQ(spec, DELIM_T))
00199            (void) scan_string(delim_t);
00200        else if (STREQ(spec, SUFFIX_2P))
00201            (void) scan_string(suffix_2p);
00202        else if (STREQ(spec, SUFFIX_3P))
00203            (void) scan_string(suffix_3p);
00204        else if (STREQ(spec, SUFFIX_MP))
00205            (void) scan_string(suffix_mp);
00206        /* output line width */
00207        else if (STREQ(spec, LINEMAX)) {
00208            SCAN_NO(&tmp);
00209            if (tmp > 0)
00210               linemax = tmp;
00211            else
00212               STY_ERROR2("%s must be positive (got %d)",
00213                         LINEMAX, tmp);
00214            /* output line indentation length */
00215        } else if (STREQ(spec, INDENT_LENGTH)) {
00216            SCAN_NO(&tmp);
00217            if (tmp >= 0)
00218               indent_length = tmp;
00219            else
00220               STY_ERROR2("%s must be nonnegative (got %d)",
00221                         INDENT_LENGTH, tmp);
00222            /* output line indentation */
00223        } else if (STREQ(spec, INDENT_SPACE)) {
00224            (void) scan_string(indent_space);
00225            /* composite page delimiter */
00226        } else if (STREQ(spec, COMPOSITOR)) {
00227            (void) scan_string(page_comp);
00228            /* page precedence */
00229        } else if (STREQ(spec, PRECEDENCE)) {
00230            (void) scan_string(page_prec);
00231            (void) process_precedence();
00232            /* index input format */
00233        } else if (STREQ(spec, KEYWORD))
00234            (void) scan_string(idx_keyword);
00235        else if (STREQ(spec, AOPEN))
00236            (void) scan_char(&idx_aopen);
00237        else if (STREQ(spec, ACLOSE))
00238            (void) scan_char(&idx_aclose);
00239        else if (STREQ(spec, LEVEL))
00240            (void) scan_char(&idx_level);
00241        else if (STREQ(spec, ROPEN))
00242            (void) scan_char(&idx_ropen);
00243        else if (STREQ(spec, RCLOSE))
00244            (void) scan_char(&idx_rclose);
00245        else if (STREQ(spec, QUOTE))
00246            (void) scan_char(&idx_quote);
00247        else if (STREQ(spec, ACTUAL))
00248            (void) scan_char(&idx_actual);
00249        else if (STREQ(spec, ENCAP))
00250            (void) scan_char(&idx_encap);
00251        else if (STREQ(spec, ESCAPE))
00252            (void) scan_char(&idx_escape);
00253        else {
00254            (void) next_nonblank();
00255            STY_SKIPLINE;
00256            STY_ERROR("Unknown specifier %s.\n", spec);
00257            put_dot = FALSE;
00258        }
00259        if (put_dot) {
00260            STY_DOT;
00261        }
00262     }
00263 
00264     /* check if quote and escape are distinct */
00265     if (idx_quote == idx_escape) {
00266        STY_ERROR(
00267               "Quote and escape symbols must be distinct (both `%c' now).\n",
00268               idx_quote);
00269        idx_quote = IDX_QUOTE;
00270        idx_escape = IDX_ESCAPE;
00271     }
00272     DONE(sty_tc - sty_ec, "attributes redefined", sty_ec, "ignored");
00273     CLOSE(sty_fp);
00274 }
00275 
00276 static int
00277 #if STDC
00278 scan_spec(char spec[])
00279 #else
00280 scan_spec(spec)
00281 char    spec[];
00282 #endif
00283 {
00284     int     i = 0;
00285     int     c;
00286 
00287     while (TRUE)
00288        if ((c = next_nonblank()) == -1)
00289            return (FALSE);
00290        else if (c == COMMENT) {
00291            STY_SKIPLINE;
00292        } else
00293            break;
00294 
00295     spec[0] = TOLOWER(c);
00296     while ((i++ < STRING_MAX) && ((c = GET_CHAR(sty_fp)) != SPC) &&
00297           (c != TAB) && (c != LFD) && (c != EOF))
00298        spec[i] = TOLOWER(c);
00299     if (i < STRING_MAX) {
00300        spec[i] = NUL;
00301        if (c == EOF) {
00302            STY_ERROR(
00303                     "No attribute for specifier %s (premature EOF)\n",
00304                     spec);
00305            return (-1);
00306        }
00307        if (c == LFD)
00308            sty_lc++;
00309        return (TRUE);
00310     } else {
00311        STY_ERROR2("Specifier %s too long (max %d).\n",
00312                  spec, STRING_MAX);
00313        return (FALSE);
00314     }
00315 }
00316 
00317 
00318 static int
00319 next_nonblank(VOID_ARG)
00320 {
00321     int     c;
00322 
00323     while (TRUE) {
00324        switch (c = GET_CHAR(sty_fp)) {
00325        case EOF:
00326            return (-1);
00327 
00328        case LFD:
00329            sty_lc++;
00330        case SPC:
00331        case TAB:
00332            break;
00333        default:
00334            return (c);
00335        }
00336     }
00337 }
00338 
00339 
00340 static int
00341 #if STDC
00342 scan_string(char str[])
00343 #else
00344 scan_string(str)
00345 char    str[];
00346 #endif
00347 {
00348     char    clone[ARRAY_MAX];
00349     int     i = 0;
00350     int     c;
00351 
00352     switch (c = next_nonblank()) {
00353     case STR_DELIM:
00354        while (TRUE)
00355            switch (c = GET_CHAR(sty_fp)) {
00356            case EOF:
00357               STY_ERROR("No closing delimiter in %s.\n",
00358                        clone);
00359               return (FALSE);
00360            case STR_DELIM:
00361               clone[i] = NUL;
00362               strcpy(str, clone);
00363               return (TRUE);
00364            case BSH:
00365               switch (c = GET_CHAR(sty_fp)) {
00366               case 't':
00367                   clone[i++] = TAB;
00368                   break;
00369               case 'n':
00370                   clone[i++] = LFD;
00371                   break;
00372 
00373               default:
00374                   clone[i++] = (char) c;
00375                   break;
00376               }
00377               break;
00378            default:
00379               if (c == LFD)
00380                   sty_lc++;
00381               if (i < ARRAY_MAX)
00382                   clone[i++] = (char) c;
00383               else {
00384                   STY_SKIPLINE;
00385                   STY_ERROR2(
00386                             "Attribute string %s too long (max %d).\n",
00387                             clone, ARRAY_MAX);
00388                   return (FALSE);
00389               }
00390               break;
00391            }
00392        break;
00393     case COMMENT:
00394        STY_SKIPLINE;
00395        break;
00396     default:
00397        STY_SKIPLINE;
00398        STY_ERROR("No opening delimiter.\n", "");
00399        return (FALSE);
00400     }
00401     return (TRUE);                     /* function value no longer used */
00402 }
00403 
00404 
00405 static int
00406 #if STDC
00407 scan_char(char *c)
00408 #else
00409 scan_char(c)
00410 char   *c;
00411 #endif
00412 {
00413     int     clone;
00414 
00415     switch (clone = next_nonblank()) {
00416     case CHR_DELIM:
00417        switch (clone = GET_CHAR(sty_fp)) {
00418        case CHR_DELIM:
00419            STY_SKIPLINE;
00420            STY_ERROR("Premature closing delimiter.\n", "");
00421            return (FALSE);
00422        case LFD:
00423            sty_lc++;
00424        case EOF:
00425            STY_ERROR("No character (premature EOF).\n", "");
00426            return (FALSE);
00427        case BSH:
00428            clone = GET_CHAR(sty_fp);
00429        default:
00430            if (GET_CHAR(sty_fp) == CHR_DELIM) {
00431               *c = (char) clone;
00432               return (TRUE);
00433            } else {
00434               STY_ERROR("No closing delimiter or too many letters.\n", "");
00435               return (FALSE);
00436            }
00437        }
00438        /* break; */                       /* NOT REACHED */
00439     case COMMENT:
00440        STY_SKIPLINE;
00441        break;
00442     default:
00443        STY_SKIPLINE;
00444        STY_ERROR("No opening delimiter.\n", "");
00445        return (FALSE);
00446     }
00447     return (TRUE);                     /* function value no longer used */
00448 }
00449 
00450 
00451 static int
00452 #if STDC
00453 count_lfd(char *str)
00454 #else
00455 count_lfd(str)
00456 char   *str;
00457 #endif
00458 {
00459     int     i = 0;
00460     int     n = 0;
00461 
00462     while (str[i] != NUL) {
00463        if (str[i] == LFD)
00464            n++;
00465        i++;
00466     }
00467     return (n);
00468 }
00469 
00470 
00471 static int
00472 process_precedence(VOID_ARG)
00473 {
00474     int     order[PAGETYPE_MAX];
00475     int     type[PAGETYPE_MAX];
00476     int     i = 0;
00477     int     last;
00478     int     roml = FALSE;
00479     int     romu = FALSE;
00480     int     arab = FALSE;
00481     int     alpl = FALSE;
00482     int     alpu = FALSE;
00483 
00484     /* check for llegal specifiers first */
00485     while ((i < PAGETYPE_MAX) && (page_prec[i] != NUL)) {
00486        switch (page_prec[i]) {
00487        case ROMAN_LOWER:
00488            if (roml) {
00489               MULTIPLE(ROMAN_LOWER);
00490            } else
00491               roml = TRUE;
00492            break;
00493        case ROMAN_UPPER:
00494            if (romu) {
00495               MULTIPLE(ROMAN_UPPER);
00496            } else
00497               romu = TRUE;
00498            break;
00499        case ARABIC:
00500            if (arab) {
00501               MULTIPLE(ARABIC);
00502            } else
00503               arab = TRUE;
00504            break;
00505        case ALPHA_LOWER:
00506            if (alpl) {
00507               MULTIPLE(ALPHA_UPPER);
00508            } else
00509               alpl = TRUE;
00510            break;
00511        case ALPHA_UPPER:
00512            if (alpu) {
00513               MULTIPLE(ALPHA_UPPER);
00514            } else
00515               alpu = TRUE;
00516            break;
00517        default:
00518            STY_SKIPLINE;
00519            STY_ERROR("Unknow type `%c' in page precedence specification.\n",
00520                     page_prec[i]);
00521            return (FALSE);
00522        }
00523        i++;
00524     }
00525     if (page_prec[i] != NUL) {
00526        STY_SKIPLINE;
00527        STY_ERROR("Page precedence specification string too long.\n", "");
00528        return (FALSE);
00529     }
00530     last = i;
00531     switch (page_prec[0]) {
00532     case ROMAN_LOWER:
00533        order[0] = ROMAN_LOWER_OFFSET;
00534        type[0] = ROML;
00535        break;
00536     case ROMAN_UPPER:
00537        order[0] = ROMAN_UPPER_OFFSET;
00538        type[0] = ROMU;
00539        break;
00540     case ARABIC:
00541        order[0] = ARABIC_OFFSET;
00542        type[0] = ARAB;
00543        break;
00544     case ALPHA_LOWER:
00545        order[0] = ALPHA_LOWER_OFFSET;
00546        type[0] = ALPL;
00547        break;
00548     case ALPHA_UPPER:
00549        order[0] = ALPHA_LOWER_OFFSET;
00550        type[0] = ALPU;
00551        break;
00552     }
00553 
00554     i = 1;
00555     while (i < last) {
00556        switch (page_prec[i]) {
00557        case ROMAN_LOWER:
00558            order[i] = order[i - 1] + ROMAN_LOWER_OFFSET;
00559            type[i] = ROML;
00560            break;
00561        case ROMAN_UPPER:
00562            order[i] = order[i - 1] + ROMAN_UPPER_OFFSET;
00563            type[i] = ROMU;
00564            break;
00565        case ARABIC:
00566            order[i] = order[i - 1] + ARABIC_OFFSET;
00567            type[i] = ARAB;
00568            break;
00569        case ALPHA_LOWER:
00570            order[i] = order[i - 1] + ALPHA_LOWER_OFFSET;
00571            type[i] = ALPL;
00572            break;
00573        case ALPHA_UPPER:
00574            order[i] = order[i - 1] + ALPHA_LOWER_OFFSET;
00575            type[i] = ALPU;
00576            break;
00577        }
00578        i++;
00579     }
00580 
00581     for (i = 0; i < PAGETYPE_MAX; i++) {
00582        page_offset[i] = -1;
00583     }
00584     page_offset[type[0]] = 0;
00585     for (i = 1; i < last; i++) {
00586        page_offset[type[i]] = order[i - 1];
00587     }
00588     for (i = 0; i < PAGETYPE_MAX; i++) {
00589        if (page_offset[i] == -1) {
00590            switch (type[last - 1]) {
00591            case ROML:
00592               order[last] = order[last - 1] + ROMAN_LOWER_OFFSET;
00593               break;
00594            case ROMU:
00595               order[last] = order[last - 1] + ROMAN_UPPER_OFFSET;
00596               break;
00597            case ARAB:
00598               order[last] = order[last - 1] + ARABIC_OFFSET;
00599               break;
00600            case ALPL:
00601               order[last] = order[last - 1] + ALPHA_LOWER_OFFSET;
00602               break;
00603            case ALPU:
00604               order[last] = order[last - 1] + ALPHA_UPPER_OFFSET;
00605               break;
00606            }
00607            type[last] = i;
00608            page_offset[i] = order[last];
00609            last++;
00610        }
00611     }
00612     return (TRUE);                     /* function value no longer used */
00613 }