home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource3 / 169_01 / xc.c < prev    next >
Text File  |  1984-07-29  |  22KB  |  928 lines

  1. /**********************************************************
  2.  
  3.       XC  -  A 'C' Concordance Utility
  4.  
  5.       Version 1.0   January, 1982
  6.  
  7.       Copyright (c) 1982 by Philip N. Hisley
  8.  
  9.           Philip N. Hisley
  10.           548H Jamestown Court
  11.           Edgewood, Maryland 21040
  12.           (301) 679-4606
  13.  
  14.       Released for non-commercial distribution only
  15.  
  16.  
  17.  
  18.  
  19.       Converted to IBM/PC CI/C86 by David N. Smith, May/June 1983
  20.       with enhancements and Lattice compiler support in December 1983.
  21.  
  22.           David N. Smith
  23.           44 Ole Musket Lane
  24.           Danbury, CT 06810
  25.           (203) 748-5934
  26.  
  27.       Changes Copyright (c) 1983 by David N. Smith
  28.  
  29.       PC Enhancements include:
  30.  
  31.        1)  Nested #INCLUDE statements
  32.        2)  Single spaced cross-reference list
  33.        3)  Removal of tabbing on output device
  34.            (Since many printers don't support it)
  35.        4)  #INCLUDE statements with both "--" and <-->
  36.            syntax and with a full fileid in the quotes.
  37.        5)  Multiple input filenames on command line.
  38.  
  39.  
  40.  
  41.       Abstract:
  42.  
  43.       'XC' is a cross-reference utility for 'C' programs.
  44.       Its has the ability to handle nested include files
  45.       to a depth of 8 levels and properly processes nested
  46.       comments as supported by BDS C. Option flags support
  47.       the following features:
  48.  
  49.       - Routing of list output to disk
  50.       - Cross-referencing of reserved words
  51.       - Processing of nested include files
  52.       - Generation of listing only
  53.  
  54.       Usage: xc <filename> <flag(s)>
  55.  
  56.       Flags: -i        = Enable file inclusion
  57.          -l        = Generate listing only
  58.          -r        = Cross-ref reserved words
  59.          -o <filename> = Write output to named file
  60.  
  61.  
  62. ***********************************************************/
  63.  
  64. #include "e:stdio.h"
  65.  
  66. /* Compiler specific stuff */
  67. #define Lattice
  68.  
  69. #ifdef Lattice
  70. #include "e:ctype.h"
  71. #endif
  72. /* end compiler specific section */
  73.  
  74. #ifndef  TRUE
  75. #define  TRUE         1
  76. #define  FALSE         0
  77. #endif
  78.  
  79. #define  ERROR        -1
  80. #define  MAX_REF     5        /* maximum refs per ref-block */
  81. #define  MAX_LEN    20        /* maximum identifier length  */
  82. #define  MAX_WRD   749        /* maximum number of identifiers */
  83. #define  MAX_ALPHA  53        /* maximum alpha chain heads */
  84. #define  REFS_PER_LINE    10    /* maximum refs per line */
  85. #define  LINES_PER_PAGE 60
  86. #define  MAXCOL     78        /* default maximum column number for listing line */
  87. #define  MINCOL     30        /* minimum value for -w option */
  88. #define  FF 0x0C        /* formfeed */
  89.  
  90. struct    rf_blk {
  91.          int  ref_item[MAX_REF];
  92.          int  ref_cnt;
  93.            } onerf;
  94.  
  95. struct    id_blk {
  96.          char  id_name[MAX_LEN];
  97.          struct id_blk *alpha_lnk;
  98.          struct rf_blk *top_lnk;
  99.          struct rf_blk *lst_lnk;
  100.            } oneid;
  101.  
  102. struct id_blk *id_vector[MAX_WRD];
  103.  
  104. struct alpha_hdr { struct id_blk *alpha_top;
  105.            struct id_blk *alpha_lst;
  106.          };
  107.  
  108. struct alpha_hdr alpha_vector[MAX_ALPHA];
  109.  
  110. int    linum;        /* line number */
  111. int    edtnum;     /* edit line number */
  112. int    fil_cnt;    /* active file index */
  113. int    wrd_cnt;    /* token count */
  114. int    pagno;        /* page number */
  115. int    id_cnt;     /* number of unique identifiers */
  116. int    rhsh_cnt;    /* number of conflict hits */
  117. int    filevl;     /* file level  */
  118. int    paglin;     /* page line counter */
  119. int    dummy;        /* dummy integer */
  120. int    maxcol=MAXCOL;    /* maximum right column for listing line */
  121. int    prt_ref;
  122. char    act_fil[MAX_LEN];
  123. char    lst_fil[MAX_LEN];
  124. char    gbl_fil[MAX_LEN];
  125. FILE    *f_lst_fil;
  126. int    i_flg,
  127.     o_flg,
  128.     r_flg,
  129.     l_flg;
  130.  
  131. long atoi();
  132.  
  133.  
  134. /*************************************************************************/
  135.  
  136. main(p_argc, p_argv)
  137. int    p_argc;
  138. char    **p_argv;
  139.  
  140. {
  141.     char  *arg;
  142.     int argc;
  143.     char **argv;
  144.     char c;
  145.     int i;
  146.  
  147.     argc = p_argc;
  148.     argv = p_argv;
  149.     if (argc < 2) use_err();
  150.     i_flg=r_flg=o_flg=l_flg=FALSE;
  151.     while(--argc != 0)
  152.      { if(*(arg=*++argv) == '-')
  153.     {switch(*++arg)
  154.      {
  155.        case 'i':
  156.        case 'I': i_flg++;
  157.              break;
  158.        case 'r':
  159.        case 'R': r_flg++;
  160.              break;
  161.        case 'l':
  162.        case 'L':  l_flg++;
  163.               break;
  164.        case 'o':
  165.        case 'O': { o_flg++;
  166.                if(--argc == 0) use_err();
  167.                strcpy(lst_fil,*++argv);
  168.                if(lst_fil[0] == '-') use_err();
  169.             break;}
  170.        case 'w':
  171.        case 'W': { if(--argc == 0) use_err();
  172.                i = atoi(*++argv);
  173.                if( i<=MINCOL || i>=255 ) use_err();
  174.                maxcol = i;
  175.                break;
  176.                }
  177.        default: use_err();
  178.      }
  179.        }
  180.      }
  181.  
  182.      if(o_flg)
  183.        {if( (f_lst_fil=fopen(lst_fil,"w")) == NULL)
  184.     { printf("ERROR: Unable to create list file - %s\n",lst_fil);
  185.       exit(0);}
  186.        printf("XC ... 'C' Concordance Utility  v1.0\n\n");
  187.     }
  188.  
  189.     prt_ref = FALSE;
  190.     for(linum=0;linum < MAX_WRD;linum++) {
  191.        id_vector[linum] = NULL; }
  192.     for(linum=0;linum < MAX_ALPHA;linum++)
  193.      {
  194.        alpha_vector[linum].alpha_top =
  195.        alpha_vector[linum].alpha_lst = NULL;
  196.      }
  197.     fil_cnt = wrd_cnt = linum = 0;
  198.     filevl=paglin=pagno=edtnum=0;
  199.     id_cnt=rhsh_cnt=0;
  200.  
  201.     argc = p_argc;  argc--;
  202.     argv = p_argv;
  203.     while(argc--) {
  204.        strcpy(gbl_fil,*++argv);
  205.        if(*gbl_fil == '-')  break;
  206.        proc_file(gbl_fil,dummy);
  207.        }
  208.     if(!l_flg) {
  209.       gbl_fil[0] = '\0';
  210.       prnt_tbl();
  211.       printf("\nAllowable Symbols: %d\n",MAX_WRD);
  212.       printf("Unique    Symbols: %d\n",id_cnt);}
  213.     if(o_flg) {
  214.      nl();
  215.      /* if(fprintf(f_lst_fil,"%c",CPMEOF) == ERROR) lst_err(); */
  216.      fclose(f_lst_fil);
  217.     }
  218. }
  219.  
  220. /*************************************************************************/
  221.  
  222. lst_err()
  223.  
  224. { printf("\nERROR: Write error on list output file - %s\n",
  225.    lst_fil);
  226.   exit(0);
  227. }
  228.  
  229. /*************************************************************************/
  230.  
  231. use_err()
  232.  
  233.        { printf("\nERROR: Invalid parameter specification\n\n");
  234.        printf("Usage: xc <filename>... <flag(s)>\n\n");
  235.        printf("Flags: -i            = Enable file inclusion\n");
  236.        printf("       -l            = Generate listing only\n");
  237.        printf("       -r            = Cross-reference reserved words\n");
  238.        printf("       -o <outfile>  = Write output to named file\n");
  239.        printf("       -w width      = Width of output page; default=78\n");
  240.        printf("Flags must follow all input file names");
  241.        exit(0); }
  242.  
  243. /*************************************************************************/
  244.  
  245. proc_file(filnam,incnum)
  246. char    *filnam;
  247. int     incnum;    /* prev. included line number (return to caller) */
  248.  
  249. {
  250.   char    token[MAX_LEN]; /* token buffer */
  251.   int    eof_flg;    /* end-of-file indicator */
  252.   int    tok_len;    /* token length */
  253.   FILE    *infile;    /* input file */
  254.  
  255.  
  256.   strcpy(act_fil,filnam);
  257.   edtnum=0;
  258.  
  259.   if((infile=fopen(filnam,"r")) == NULL)
  260.       {printf("\nERROR: Unable to open input file: %s\n",filnam);
  261.     return;}  /* ignore error */
  262.   if(filevl++ == 0) prt_hdr();
  263.   eof_flg = FALSE;
  264.   do {
  265.        if(get_token(infile,token,&tok_len,&eof_flg,0))
  266.       if(chk_token(token))
  267.          {
  268.          if(strcmp(token,"#include") == 0)
  269.         {
  270.         get_include_fileid(token,infile);
  271.         if(!i_flg) continue;
  272.         else
  273.            {
  274.            nl();
  275.            edtnum=proc_file(token,edtnum);
  276.            strcpy(act_fil,filnam);
  277.            continue;
  278.            }
  279.         }
  280.         put_token(token,linum);
  281.         }
  282.      } while (!eof_flg);
  283.  
  284.      filevl -= 1;
  285.      fclose(infile);
  286.  
  287.      return( incnum );
  288. }
  289.  
  290. /*************************************************************************/
  291.  
  292. get_include_fileid(token,infile)
  293. char *token;
  294. FILE *infile;
  295. {
  296.  
  297.    char c, term;
  298.  
  299.    while ( (term=getc(infile)) == ' ' )  echo(term);
  300.    echo(term);
  301.    if ( term=='<' ) term='>';   /* terminator is > or " */
  302.    if ( (term!='>') && (term!='"') )
  303.       {
  304.       printf("Error scanning #INCLUDE fileid: %c\n", term);
  305.       exit(1);
  306.       }
  307.  
  308.    do {
  309.       if ( (c = getc(infile)) != ' ')
  310.      {
  311.      *token++ = c;
  312.      echo(c);
  313.      }
  314.       else
  315.      echo(c);
  316.       }
  317.       while ( c!=term );
  318.  
  319.    *--token = '\0';
  320.  
  321. }
  322.  
  323. /*************************************************************************/
  324.  
  325. echo(c)
  326. char c;
  327. {
  328.    static int col = 11;
  329.    int i;
  330.    echochar(c);
  331.    if( c == '\n' )
  332.       col = 1