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 >
C/C++ Source or Header  |  1993-05-26  |  18KB  |  831 lines

  1. /*
  2.  *
  3.  *  This file is part of
  4.  *    MakeIndex - A formatter and format independent index processor
  5.  *
  6.  *  Copyright (C) 1989 by Chen & Harrison International Systems, Inc.
  7.  *  Copyright (C) 1988 by Olivetti Research Center
  8.  *  Copyright (C) 1987 by Regents of the University of California
  9.  *
  10.  *  Author:
  11.  *    Pehong Chen
  12.  *    Chen & Harrison International Systems, Inc.
  13.  *    Palo Alto, California
  14.  *    USA
  15.  *    (phc@renoir.berkeley.edu or chen@orc.olivetti.com)
  16.  *
  17.  *  Contributors:
  18.  *    Please refer to the CONTRIB file that comes with this release
  19.  *    for a list of people who have contributed to this and/or previous
  20.  *    release(s) of MakeIndex.
  21.  *
  22.  *  All rights reserved by the copyright holders.  See the copyright
  23.  *  notice distributed with this software for a complete description of
  24.  *  the conditions under which it is made available.
  25.  *
  26.  */
  27.  
  28. #include    "mkind.h"
  29. #include    "scanid.h"
  30.  
  31. #define CHECK_LENGTH()    if (i > len_field) goto OVERFLOW
  32.  
  33. int     idx_lc;                   /* line count */
  34. int     idx_tc;                   /* total entry count */
  35. int     idx_ec;                   /* erroneous entry count */
  36. int     idx_dc;                   /* number of dots printed so far */
  37.  
  38. static int first_entry = TRUE;
  39. static int comp_len;
  40. static char key[ARGUMENT_MAX];
  41. static char no[NUMBER_MAX];
  42. extern char *strchr ARGS((const char* s,int c));
  43.  
  44. NODE_PTR head;
  45. NODE_PTR tail;
  46.  
  47. static    void    flush_to_eol ARGS((void));
  48. static    int    make_key ARGS((void));
  49. static    void    make_string ARGS((char **ppstr,int n));
  50. static    int    scan_alpha_lower ARGS((char *no,short *npg,short *count));
  51. static    int    scan_alpha_upper ARGS((char *no,short *npg,short *count));
  52. static    int    scan_arabic ARGS((char *no,short *npg,short *count));
  53. static    int    scan_arg1 ARGS((void));
  54. static    int    scan_arg2 ARGS((void));
  55. static    int    scan_field ARGS((int *n,char field[],int len_field,
  56.                  int ck_level, int ck_encap,int ck_actual));
  57. static    int    scan_key ARGS((struct KFIELD *data));
  58. static    int    scan_no ARGS((char *no,short *npg,short *count,short *type));
  59. static    int    scan_roman_lower ARGS((char *no,short *npg,short *count));
  60. static    int    scan_roman_upper ARGS((char *no,short *npg,short *count));
  61. static    void    search_quote ARGS((char sort_key[],char actual_key[]));
  62.  
  63. #if     (OS_BS2000 | OS_MVSXA)
  64. char    UPCC[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  65. #endif
  66.  
  67. void
  68. scan_idx(VOID_ARG)
  69. {
  70.     char    keyword[ARRAY_MAX];
  71.     int     c;
  72.     int     i = 0;
  73.     int     not_eof = TRUE;
  74.     int     arg_count = -1;
  75.  
  76.     MESSAGE("Scanning input file %s...", idx_fn);
  77.     idx_lc = idx_tc = idx_ec = idx_dc = 0;
  78.     comp_len = strlen(page_comp);
  79.     while (not_eof) {
  80.     switch (c = GET_CHAR(idx_fp)) {
  81.     case EOF:
  82.         if (arg_count == 2) {
  83.         idx_lc++;
  84.         if (make_key())
  85.             IDX_DOT(DOT_MAX);
  86.         arg_count = -1;
  87.         } else
  88.         not_eof = FALSE;
  89.         break;
  90.  
  91.     case LFD:
  92.         idx_lc++;
  93.         if (arg_count == 2) {
  94.         if (make_key())
  95.             IDX_DOT(DOT_MAX);
  96.         arg_count = -1;
  97.         } else if (arg_count > -1) {
  98.         IDX_ERROR("Missing arguments -- need two (premature LFD).\n",
  99.               NULL);
  100.         arg_count = -1;
  101.         }
  102.     case TAB:
  103.     case SPC:
  104.         break;
  105.  
  106.     default:
  107.         switch (arg_count) {
  108.         case -1:
  109.         i = 0;
  110.         keyword[i++] = (char) c;
  111.         arg_count++;
  112.         idx_tc++;
  113.         break;
  114.         case 0:
  115.         if (c == idx_aopen) {
  116.             arg_count++;
  117.             keyword[i] = NUL;
  118.             if (STREQ(keyword, idx_keyword)) {
  119.             if (!scan_arg1()) {
  120.                 arg_count = -1;
  121.             }
  122.             } else {
  123.             IDX_SKIPLINE;
  124.             IDX_ERROR("Unknown index keyword %s.\n", keyword);
  125.             }
  126.         } else {
  127.             if (i < ARRAY_MAX)
  128.             keyword[i++] = (char) c;
  129.             else {
  130.             IDX_SKIPLINE;
  131.             IDX_ERROR2("Index keyword %s too long (max %d).\n",
  132.                    keyword, ARRAY_MAX);
  133.             }
  134.         }
  135.         break;
  136.         case 1:
  137.         if (c == idx_aopen) {
  138.             arg_count++;
  139.             if (!scan_arg2()) {
  140.             arg_count = -1;
  141.             }
  142.         } else {
  143.             IDX_SKIPLINE;
  144. IDX_ERROR(
  145. "No opening delimiter for second argument (illegal character `%c').\n", c);
  146.         }
  147.         break;
  148.         case 2:
  149.         IDX_SKIPLINE;
  150. IDX_ERROR(
  151. "No closing delimiter for second argument (illegal character `%c').\n", c);
  152.         break;
  153.         }
  154.         break;
  155.     }
  156.     }
  157.  
  158.     /* fixup the total counts */
  159.     idx_tt += idx_tc;
  160.     idx_et += idx_ec;
  161.  
  162.     DONE(idx_tc - idx_ec, "entries accepted", idx_ec, "rejected");
  163.     CLOSE(idx_fp);
  164. }
  165.  
  166. static void
  167. flush_to_eol(VOID_ARG)
  168. {    /* flush to end-of-line, or end-of-file, whichever is first */
  169.     int a;
  170.  
  171.     while ( ((a = GET_CHAR(idx_fp)) != LFD) && (a != EOF) )
  172.         /* NO-OP */;
  173. }
  174.  
  175. static int
  176. make_key(VOID_ARG)
  177. {
  178.     NODE_PTR ptr;
  179.     int     i;
  180.  
  181.     /* allocate and initialize a node */
  182.  
  183. #ifdef DEBUG
  184.     totmem += sizeof(NODE);
  185.     (void)fprintf(stderr,"make_key(): malloc(%d)\ttotmem = %ld\n",
  186.         sizeof(NODE),totmem);
  187. #endif /* DEBUG */
  188.  
  189.     if ((ptr = (NODE_PTR) malloc(sizeof(NODE))) == NULL)
  190.     FATAL("Not enough core...abort.\n", "");
  191.  
  192.     for (i = 0; i < FIELD_MAX; i++)
  193.     {
  194.     ptr->data.sf[i] = "";        /* initialize fields to pointers */;
  195.     ptr->data.af[i] = "";        /* to constant empty strings */
  196.     }
  197.     ptr->data.encap = "";
  198.     ptr->data.lpg[0] = NUL;
  199.     ptr->data.count = 0;
  200.     ptr->data.type = EMPTY;
  201.  
  202.     /* process index key */
  203.     if (!scan_key(&(ptr->data)))
  204.     return (FALSE);
  205.  
  206.     /* determine group type */
  207.     ptr->data.group = group_type(ptr->data.sf[0]);
  208.  
  209.     /* process page number */
  210.     strcpy(ptr->data.lpg, no);
  211.     if (!scan_no(no, ptr->data.npg, &(ptr->data.count), &(ptr->data.type)))
  212.     return (FALSE);
  213.  
  214.     if (first_entry) {
  215.     head = tail = ptr;
  216.     first_entry = FALSE;
  217.     } else {
  218.     tail->next = ptr;
  219.     tail = ptr;
  220.     }
  221.     ptr->data.lc = idx_lc;
  222.     ptr->data.fn = idx_fn;
  223.     tail->next = NULL;
  224.  
  225.     return (TRUE);
  226. }
  227.  
  228. static void
  229. #if STDC
  230. make_string(char **ppstr, int n)
  231. #else
  232. make_string(ppstr,n)            /* allocate n-byte string if *ppstr */
  233. char    **ppstr;            /* points to an empty string */
  234. int    n;
  235. #endif
  236. {
  237.     if ((*ppstr)[0] == NUL)        /* then we have an empty string */
  238.     {
  239.     (*ppstr) = (char*)malloc(n);
  240.     if ((*ppstr) == (char*)NULL)
  241.         FATAL("Not enough core...abort.\n", "");
  242.     (*ppstr)[0] = NUL;
  243.     }
  244. }
  245.  
  246. static int
  247. #if STDC
  248. scan_key(FIELD_PTR data)
  249. #else
  250. scan_key(data)
  251. FIELD_PTR data;
  252. #endif
  253. {
  254.     int     i = 0;               /* current level */
  255.     int     n = 0;               /* index to the key[] array */
  256.     int     second_round = FALSE;
  257.     int     last = FIELD_MAX - 1;
  258.  
  259.     while (TRUE) {
  260.     if (key[n] == NUL)
  261.         break;
  262.     if (key[n] == idx_encap)
  263.     {
  264.         n++;
  265.         make_string(&(data->encap),strlen(key) + 1);
  266.         if (scan_field(&n, data->encap, strlen(key), FALSE, FALSE, FALSE))
  267.         break;
  268.         else
  269.         return (FALSE);
  270.     }
  271.     if (key[n] == idx_actual) {
  272.         n++;
  273.         if (i == last)
  274.         {
  275.         make_string(&(data->af[i]),strlen(key) + 1);
  276.         if (!scan_field(&n, data->af[i], strlen(key),
  277.                 FALSE, TRUE, FALSE))
  278.             return (FALSE);
  279.         }
  280.         else
  281.         {
  282.         make_string(&(data->af[i]),strlen(key) + 1);
  283.         if (!scan_field(&n, data->af[i], strlen(key),
  284.                 TRUE, TRUE, FALSE))
  285.             return (FALSE);
  286.         }
  287.     } else {
  288.         /* Next nesting level */
  289.         if (second_round) {
  290.         i++;
  291.         n++;
  292.         }
  293.         if (i == last)
  294.         {
  295.         make_string(&(data->sf[i]),strlen(key) + 1);
  296.         if (!scan_field(&n, data->sf[i], strlen(key),
  297.                 FALSE, TRUE, TRUE))
  298.             return (FALSE);
  299.         }
  300.         else
  301.         {
  302.         make_string(&(data->sf[i]),strlen(key) + 1);
  303.         if (!scan_field(&n, data->sf[i], strlen(key),
  304.                 TRUE, TRUE, TRUE))
  305.             return (FALSE);
  306.         }
  307.         second_round = TRUE;
  308.         if (german_sort && strchr(data->sf[i], '"'))
  309.         {
  310.         make_string(&(data->af[i]),strlen(data->sf[i]) + 1);
  311.         search_quote(data->sf[i], data->af[i]);
  312.         }
  313.     }
  314.     }
  315.  
  316.     /* check for empty fields which shouldn't be empty */
  317.     if (*data->sf[0] == NUL) {
  318.     NULL_RTN;
  319.     }
  320.     for (i = 1; i < FIELD_MAX - 1; i++)
  321.     if ((*data->sf[i] == NUL) &&
  322.         ((*data->af[i] != NUL) || (*data->sf[i + 1] != NUL))) {
  323.         NULL_RTN;
  324.     }
  325.     /* i == FIELD_MAX-1 */
  326.     if ((*data->sf[i] == NUL) && (*data->af[i] != NUL)) {
  327.     NULL_RTN;
  328.     }
  329.     return (TRUE);
  330. }
  331.  
  332. static int
  333. #if STDC
  334. scan_field(int *n, char field[], int len_field, int ck_level, int ck_encap, 
  335.     int ck_actual)
  336. #else
  337. scan_field(n, field, len_field, ck_level, ck_encap, ck_actual)
  338. int    *n;
  339. char    field[];
  340. int    len_field;    /* length of field[], EXCLUDING space for final NUL */
  341. int     ck_level;
  342. int     ck_encap;
  343. int     ck_actual;
  344. #endif
  345. {
  346.     int     i = 0;
  347.