/* * * Copyright (C) 1987 Pehong Chen (phc@renoir.berkeley.edu) * Computer Science Division * University of California, Berkeley * */ #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[LONG_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[LONG_MAX] = PREAMBLE_DEF; char postamble[LONG_MAX] = POSTAMBLE_DEF; int prelen = PREAMBLE_LEN; int postlen = POSTAMBLE_LEN; char setpage_open[LONG_MAX] = SETPAGEOPEN_DEF; char setpage_close[LONG_MAX] = SETPAGECLOSE_DEF; int setpagelen = SETPAGE_LEN; char group_skip[LONG_MAX] = GROUPSKIP_DEF; char lethead_pre[LONG_MAX] = LETHEADPRE_DEF; char lethead_suf[LONG_MAX] = LETHEADSUF_DEF; int lethead_flag = LETHEADFLAG_DEF; int skiplen = GROUPSKIP_LEN; int headprelen = LETHEADPRE_LEN; int headsuflen = LETHEADSUF_LEN; char item_r[FIELD_MAX][LONG_MAX] = {ITEM0_DEF, ITEM1_DEF, ITEM2_DEF}; char item_u[FIELD_MAX][LONG_MAX] = {"", ITEM1_DEF, ITEM2_DEF}; char item_x[FIELD_MAX][LONG_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][LONG_MAX] = {DELIM_DEF, DELIM_DEF, DELIM_DEF}; char delim_n[LONG_MAX] = DELIM_DEF; /* page number separator */ char delim_r[LONG_MAX] = DELIMR_DEF; /* page range designator */ char encap_p[LONG_MAX] = ENCAP0_DEF; /* encapsulator prefix */ char encap_i[LONG_MAX] = ENCAP1_DEF; /* encapsulator infix */ char encap_s[LONG_MAX] = ENCAP2_DEF; /* encapsulator postfix */ int linemax = LINE_MAX; int indent_length = INDENTLEN_DEF; char indent_space[LONG_MAX] = INDENTSPC_DEF; char page_comp[LONG_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 }; static char page_prec[LONG_MAX] = PRECEDENCE_DEF; static int put_dot; void scan_sty() { char spec[STRING_MAX]; int tmp; MESSAGE("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, LETHEAD_PRE)) { (void)scan_string(lethead_pre); headprelen = count_lfd(lethead_pre); } else if (STREQ(spec, LETHEAD_SUF)) { (void)scan_string(lethead_suf); headsuflen = count_lfd(lethead_suf); } else if (STREQ(spec, LETHEAD_FLAG)) { SCAN_NO(&lethead_flag); } 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); /* 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)", LINE_MAX, 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); (void)process_precedence(); /* 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_ERROR("Unknown specifier %s.\n", spec); put_dot = FALSE; } if (put_dot) { STY_DOT; } } /* check if quote and escape are distinct */ if (idx_quote == idx_escape) { STY_ERROR("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(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] = NULL; if (c == EOF) { STY_ERROR("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() { 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(str) char str[]; { char clone[LONG_MAX]; int i = 0; int c; switch (c = next_nonblank()) { case STR_DELIM: while (TRUE) switch (c = GET_CHAR(sty_fp)) { case EOF: STY_ERROR("No closing delimiter in %s.\n", clone); return (FALSE); case STR_DELIM: clone[i] = NULL; 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 < LONG_MAX) clone[i++] = (char)c; else { STY_SKIPLINE; STY_ERROR2("Attribute string %s too long (max %d).\n", clone, LONG_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(c) 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; } 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 count_lfd(str) char *str; { int i = 0; int n = 0; while (str[i] != NULL) { if (str[i] == LFD) n++; i++; } return (n); } static int process_precedence() { 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] != NULL)) { 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_ERROR("Unknow type `%c' in page precedence specification.\n", page_prec[i]); return (FALSE); } i++; } if (page_prec[i] != NULL) { 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 */ }