home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 364_02 / util_ca.c < prev    next >
C/C++ Source or Header  |  1992-05-26  |  9KB  |  374 lines

  1. /*
  2. HEADER:         ;
  3. TITLE:          C-ACROSS;
  4. VERSION         1.02
  5.  
  6. DESCRIPTION:   "Utility for multiple module programs. Produces
  7.       Six indexes of functions, prototypes, and globals that
  8.       enable user to 'see across' modules for use in checking
  9.       and comparison.  One of these is type of hierarchical
  10.       functions list, a listing by module of functions
  11.       and calls made FROM them; another is alphabetical list
  12.       of functions and calls made TO them. Globals listed
  13.       in schematic descriptors which record all modifiers
  14.       and qualifiers and enable checking of declarators
  15.       across modules. Creates, on request, header file
  16.       consisting of prototypes constructed from function
  17.       definitions. Can list user types #defined and some
  18.       preprocessor #defines. Full documentation in README.CA";
  19.  
  20. KEYWORDS:       Utility, Cross Reference, Deubgging;
  21. SYSTEM:         MS-DOS;
  22. FILENAME:       UTIL_CA.C;
  23.  
  24. WARNINGS:      "1. Assumes function definitions conform with
  25.         ANSI standards and have prototype form. See
  26.         also "Caveats and Restrictions" in README.CA.
  27.         2. Assumes syntactically correct source files.
  28.         3. Written and tested using Microsoft QuickC.
  29.         4. Copyright retained.  See Copyright
  30.         information in README.CA.";
  31.  
  32. SEE-ALSO:      EXIT_CA.C, FUNC_CA.C, GLOB_CA.C, IFDEF_CA.C, INTF_CA.C,
  33.            LINKL_CA.C, PARSE_CA.C, TDEF_CA.C, TYPES_CA,
  34.            UTLG_CA.C, XRF_CA.C, README.CA,
  35.            CA.H, CA.PRJ, CA.RPT, CDECL_CA.H, KEYWORDS.H;
  36. AUTHORS:       Myron Turner;
  37. COMPILERS:     Microsoft C;
  38.  
  39. */
  40.  
  41. /***************************  C-ACROSS  ***************************
  42.                    V. 1.02
  43.                Copyright (C) Myron Turner
  44.  
  45.               333 Bartlet Ave.
  46.               Winnipeg, Manitoba
  47.               Canada R3L 0Z9
  48.               (204) 284-8387
  49.  
  50. *********************************************************************/
  51.  
  52.  
  53. #include <stdlib.h>
  54. #include <string.h>
  55. #include <stdio.h>
  56. #include <time.h>
  57. #include <ctype.h>
  58.  
  59.  
  60. #define INCLUDEFILES_DEFINE
  61. #include "ca.h"
  62. #include "ca_decl.h"
  63. #define EXTERNAL
  64. #include "keywords.h"
  65.  
  66. #define QUOT  '\x22'
  67. #define RET_FULLPATH 0x10
  68. #define RET_PATHVAR_ONLY  0x20
  69.  
  70. /* externs and globals */
  71. char SubstInclude[128];
  72. extern int __Inclf_Limit;
  73. extern int declare_file;
  74. extern FILE *scrn_out;
  75. extern int user_hfile_only;
  76. extern FILE **FP_ADDRESS;
  77. int reading_includeF = 0;
  78. unsigned int inclfLine = 0;
  79. unsigned int inclFini = 0;
  80. struct includeFILE inclF;
  81.  
  82. /******** UTILITIES FOR HANDLING FILES, INCLUDE FILES, PATH *****/
  83.  
  84. char * get_envpath(int service, char *env_var, char *fname)
  85. {
  86.     char *pathvar, pathbuf[128], filebuf[128];
  87.     int i, conver_fact = 32;
  88.     size_t strL;
  89.  
  90.     if (!(pathvar = getenv("INCLUDE" )) ) {
  91.       i = 0;
  92.       if (env_var[i] > 'Z' ) conver_fact = -conver_fact;
  93.       while(env_var[i]) {
  94.     env_var[i++] += (char)conver_fact;
  95.        }
  96.  
  97.        if ( !(pathvar = getenv(env_var)) ) {
  98.     if (service == RET_PATHVAR_ONLY) return (NULL);
  99.      printf("\nPath not found for %s.\nEnter path [%s]: ",
  100.                         fname, SubstInclude);
  101.      gets(filebuf);
  102.  
  103.      strL = strlen(filebuf);
  104.      if (strL) {
  105.      if (filebuf[strL] != '\\') {
  106.          filebuf[strL] = '\\';
  107.          filebuf[strL + 1] =  '\0';
  108.          }
  109.      if (!SubstInclude[0]) strcpy (SubstInclude, filebuf);
  110.      }
  111.      else {
  112.       if (SubstInclude[0]) strcpy(filebuf, SubstInclude);
  113.      }
  114.  
  115.      strcat(filebuf, fname);
  116.      strcpy(fname, filebuf);
  117.      return(fname);
  118.      }
  119.     }
  120.  
  121.     if (service == RET_FULLPATH) {
  122.        _searchenv( fname, env_var, filebuf );
  123.        return(strcpy(fname, filebuf));
  124.        }
  125.      else if (service == RET_PATHVAR_ONLY)
  126.        return(strcpy(fname, pathvar));
  127.  
  128. }
  129.  
  130.  
  131. /* Check whether include file is enclosed in brackets "<>" or in */
  132. /* quotation marks. Isolate the filename in passed string and open */
  133. /* file if it is less than or equal to the include file limit*/
  134.  
  135. FILE *setincludefile(char *includebuf)
  136. {
  137.   char *fname, *ptr, *endbuf = includebuf;
  138.   char  filespec[128];
  139.   size_t strL;
  140.   FILE *fp;
  141.   char delimiter = '>';
  142.  
  143.  
  144.   strL = strlen(includebuf);
  145.   endbuf += (strL -1);
  146.   if ( !(fname = strchr(includebuf, '<')) )
  147.       if ( (fname = strchr(includebuf, QUOT)) )
  148.           delimiter = QUOT;
  149.   if (!fname || (fname >= endbuf)) return(NULL);
  150.   if  (user_hfile_only) if (*fname == '<') return (NULL);
  151.   while( (*(++fname) == ' ' || *fname == (char) 0x9) && *fname);
  152.   ptr = strchr(fname, delimiter);
  153.   if (!ptr || (ptr >= endbuf)) return (NULL);
  154.   while(*(--ptr) == (char)0x9 || *ptr == (char)0x20);
  155.   *(++ptr) = '\0';
  156.  
  157.   strcpy(filespec, fname);
  158.   if  (inclF.level <= __Inclf_Limit)
  159.     strcpy(inclF.file[inclF.level], fname);
  160.     else return(NULL);
  161.  
  162.   if (delimiter == QUOT)
  163.     if ((fp = open_includef(filespec))) return(fp);
  164.  
  165.   get_envpath(RET_FULLPATH, "INCLUDE", filespec);
  166.   if (!(fp = open_includef(filespec)))
  167.      fprintf (scrn_out,
  168.         "Cannot open: %s. Possible INCLUDE variable error.\n", fname);
  169.  
  170.  
  171.   return(fp);
  172. }
  173.  
  174.  
  175. FILE *open_includef(char *filespec)
  176. {
  177.   FILE *fp;
  178.   extern FILE *rptfp;
  179.  
  180.   if (   (fp = fopen( filespec, "rt") ) == NULL )
  181.        {
  182.        return (NULL);
  183.        }
  184.  
  185.  
  186.    return(fp);
  187.  
  188.  
  189. }
  190.  
  191. /*  File pointer for scrnout.rpt when /red switch is set */
  192. FILE *get_redfp(void)
  193. {
  194.  
  195.     return(fopen("scrnout.rpt", "w"));
  196. }
  197.  
  198.  
  199. int is_include(char *token_ptr, FILE *holdfp)
  200. {
  201.   int str_pos;
  202.  
  203.     if (inclF.level == __Inclf_Limit) return(0);
  204.     holdfp = *FP_ADDRESS;
  205.     if ( (str_pos = test_token(token_ptr, TYPES[INCLUDE_])) )   {
  206.       if( (*FP_ADDRESS = setincludefile(token_ptr+str_pos)) ) {
  207.          reading_includeF = 1;
  208.          inclF.address[inclF.level] = *FP_ADDRESS;
  209.          fprintf(scrn_out, "\nOpened Include File: %s (%d)\n",
  210.             inclF.file[inclF.level],
  211.             fileno(inclF.address[inclF.level]) );
  212.          inclF.level++;
  213.          inclfLine = 0;
  214.          inclFini = 1;
  215.  
  216.          return (str_pos);
  217.          }
  218.          else *FP_ADDRESS = holdfp;
  219.        }
  220.  return(0);
  221. }
  222.  
  223. int close_include(FILE *hold_fp, FILE **fp, FILE *rptfp, char *module)
  224. {
  225.   inclFini = 0;
  226.   if (reading_includeF) {
  227.       if (inclF.level > 1 && inclF.level <= __Inclf_Limit) {
  228.     inclF.level--;
  229.     fprintf(scrn_out,"Closing Include: %s (%d). Returning to: %s (%d)\n",
  230.        inclF.file[inclF.level], fileno (inclF.address[inclF.level]),
  231.        inclF.file[inclF.level - 1], fileno (inclF.address[inclF.level - 1]) );
  232.     fclose( inclF.address[inclF.level] );
  233.     *fp = inclF.address[inclF.level - 1];
  234.     }
  235.     else {
  236.     fprintf(scrn_out,
  237.        "Closing Include: %s (%d). Returning to Module: %s (%d)\n",
  238.         inclF.file[0], fileno (inclF.address[0]),
  239.         module, fileno (hold_fp) );
  240.     inclF.level = 0;
  241.     fclose( inclF.address[0] );
  242.     reading_includeF = 0;
  243.     *fp = hold_fp;
  244.  
  245.     }
  246.      /* return 1 causes an exit from the main loop */
  247.       return (1);
  248.       }
  249.  
  250.  /*  cr/lf at end of module */
  251.     fprintf(rptfp, "\n");
  252.     paginate(rptfp);
  253.     paginate(rptfp);
  254.  
  255.    return(0);
  256. }
  257.  
  258.  
  259. /************** Utility functions for FUNC_CA ************/
  260.  
  261.  
  262. void date_time(FILE *rptfp )
  263. {
  264.  char tmpbuf[128];
  265.      if (declare_file) return;
  266.  
  267.     _strdate( tmpbuf );
  268.      fprintf(rptfp, "DOS date:\t\t\t\t%s\n", tmpbuf );
  269.      paginate(rptfp);
  270.      paginate(rptfp);
  271.     _strtime( tmpbuf );
  272.     fprintf( rptfp, "DOS time:\t\t\t\t%s\n\n", tmpbuf );
  273.     paginate(rptfp);
  274.     paginate(rptfp);
  275.     paginate(rptfp);
  276. }
  277.  
  278. void heading(FILE *rptfp, char *fname)
  279. {
  280.  int i;
  281.  
  282.  if (declare_file) return;
  283.  
  284.  fprintf(rptfp, "        \"C-ACROSS\" CROSS-REFERENCE LISTINGS FOR: %s\n\n",
  285.                                 fname);
  286.  for (i = 0; i < 79; i++) fprintf(rptfp, "%c", '\x5f');
  287.  fprintf(rptfp,"\n\n");
  288.  
  289.  paginate(rptfp);
  290.  paginate(rptfp);
  291.  paginate(rptfp);
  292.  paginate(rptfp);
  293.  
  294. }
  295.  
  296. int countbrackets(char *buffer)
  297. {
  298.   int brackets = 0;
  299.   int ischar = 0;
  300.   char *p = buffer;
  301.    while(*buffer) {
  302.      if(*buffer == '\'')  {
  303.      if (*++buffer == '{') brackets--;
  304.      if (*buffer == '}') brackets++;
  305.       }
  306.      if(*buffer == '{') brackets++;
  307.      if(*buffer == '}') brackets--;
  308.      buffer++;
  309.      }
  310.  
  311.  return (brackets);
  312. }
  313.  
  314.  
  315. char *headings[] =    {
  316.   "I.   FUNCTION DECLARATIONS AND GLOBAL VARIABLES",
  317.   "II.  ALPHABETICAL INDEX OF FUNCTIONS & THEIR MODULES",
  318.   "III. FUNCTIONS (LISTED BY MODULE) AND CALLS",
  319.   "IV.  LIST OF FUNCTIONS AND CALLING FUNCTIONS",
  320.   "V.   FUNCTION POINTERS AND CALLING FUNCTIONS",
  321.   "VI.  GLOBAL VARIABLES LISTED ALPHABETICALLY"
  322. };
  323. void print_headings(int head_no, FILE *rptfp )
  324. {
  325.   int line_count;
  326.  
  327.    if(head_no != 0) {
  328.    line_count = paginate(rptfp);
  329.    formfeed(line_count, rptfp);
  330.    }
  331.  
  332.    fprintf(rptfp,"\n%s\n\n", headings[head_no]);
  333.    paginate(rptfp); paginate(rptfp); paginate(rptfp); paginate(rptfp);
  334.  
  335. }
  336.  
  337. /************** Utility functions for Tokens ************/
  338.  
  339. char * isolate_token(char * p, char **end_token)
  340. {
  341.   char *token_ptr;
  342.  
  343.                /* eliminate initial white space */
  344.   while (*p == '\x20' || *p == '\x9') p++;
  345.   token_ptr  = p;
  346.   while ( *p != '\x20' && *p != '\x9' && *p != '(' && *p != '\0' ) p++;
  347.   *p = '\0';      /* isolate first element in line as possible token */
  348.   *end_token = p;
  349.    return (token_ptr);
  350. }
  351.  
  352.  
  353. int test_token( char *token, char *type)
  354. {
  355.   int count = 0, i;
  356.   char *tptr = token;
  357.  
  358.   if(*token == '\0' || *token == '\n') return(0);
  359.  
  360.      do
  361.        {
  362.     type++;
  363.     token++;
  364.     count++;
  365.     }
  366.      while ( (*token == *type) && *type );
  367.  
  368.      if (!(*token) && !(*type))
  369.      return (++count);
  370.  
  371.      return (0);
  372. }
  373.  
  374.