home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 364_02 / xrf_ca.c < prev   
C/C++ Source or Header  |  1992-05-26  |  7KB  |  252 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:       XRF_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.            UTIL_CA.C, UTLG_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 <stdio.h>
  54. #include <string.h>
  55. #include <stdlib.h>
  56. #define EXIT_CODES
  57. #include "ca.h"
  58. #include "ca_decl.h"
  59.  
  60.  
  61. /* externs and globals */
  62. extern int function_no;
  63. char **bsearch_start;
  64. struct func *top_mod = NULL;     /* initialized in link_by_module() */
  65. struct func *calling_function;   /* used in store_calls_from() in PARSE_CA */
  66.                  /* and as argument to parse() */
  67.  
  68.  
  69. /******************BEGIN ROUTINES***********/
  70.  
  71. void xrf(struct func *func_start, struct filespec *c_file_start, FILE *rptfp)
  72. {
  73.  struct func *func_top;
  74.  struct filespec * files_top;
  75.  FILE *fp;
  76.  unsigned line_count = 0, next_function ;
  77.  char buffer[81], filename[_MAX_FNAME];
  78.  short last_func_in_mod;
  79.  struct func *hold_func_start = func_start;
  80.  
  81.  if (!top_mod  || !c_file_start)  return(NULL);
  82.  func_top = top_mod;
  83.  files_top = c_file_start;
  84.  
  85.  bsearch_start = create_bsearch_array(func_start);
  86.  
  87.  print_headings(2, rptfp );
  88.  
  89.  fp = ini_cfile(c_file_start->path, rptfp,  func_top->line_no,  &line_count);
  90.  
  91.  
  92.  while(func_top && files_top) {
  93.  
  94.     last_func_in_mod = 0;
  95.  
  96.       fprintf(rptfp,"\n%6u: %-25s (%s)\n", func_top->line_no,
  97.                      func_top->name,
  98.                      func_top->module);
  99.        paginate(rptfp); paginate(rptfp);
  100.        calling_function = func_top;
  101.        func_top = func_top->next_function;
  102.  
  103.     /*since func_top is one function ahead, and calling_function         */
  104.     /* is current function:  when a new module comes up func_top->module */
  105.     /*  will point to it>  Also, there will not be a next function       */
  106.     /* in current module:  therefore, line number of 'next_function'     */
  107.     /* LAST_FUNCTION                                                     */
  108.  
  109.       if (files_top->path)
  110.     if (files_match(files_top->path, func_top->module)
  111.                      && !func_top->fnptr)
  112.          next_function =  func_top->line_no;
  113.          else {
  114.            next_function = LAST_FUNCTION;
  115.            last_func_in_mod = 1;
  116.            if (func_top)
  117.          if(func_top->fnptr) func_top =  skip_fnptrs(func_top);
  118.            }
  119.  
  120.       parse(fp, rptfp, calling_function->endfunc_line,
  121.                 next_function, &line_count);
  122.  
  123.      if (last_func_in_mod) {
  124.          fclose(fp);
  125.          if (files_top->next->path) {
  126.              files_top = files_top->next;
  127.              if (!files_top || !func_top)
  128.             nullptrxit("Gap in array", __FILE__, __LINE__);
  129.              line_count = 0;
  130.              fp = ini_cfile(files_top->path, rptfp,
  131.                         func_top->line_no,  &line_count);
  132.                     }
  133.                     else files_top = NULL;
  134.               }
  135.          }
  136.  
  137.  
  138.  
  139. }
  140.  
  141. /* creates list of functions in order of appearance in files:  */
  142. /* uses 'next_function'                                         */
  143. void link_by_module(struct func *function)
  144. {
  145.  static struct func *previous = NULL;
  146.  
  147.  if (!top_mod) {
  148.      top_mod = function;
  149.      previous = function;
  150.      return;    }
  151.  
  152.  function->next_function = NULL;
  153.  previous->next_function = function;
  154.  previous = function;
  155. }
  156.  
  157. static int files_match(char *path, char *module)
  158. {
  159.    char drive[_MAX_DRIVE], dir[_MAX_DIR];
  160.   char fname[_MAX_FNAME], ext[_MAX_EXT] ;
  161.  
  162.    _splitpath(path, drive, dir, fname, ext );
  163.    if ( strcmp(fname, module) ) return (0);
  164.  
  165.    return (1);
  166.  
  167.  
  168. }
  169.  
  170. /* Open source file and move to first function [*count < func_line]; */
  171. /* count is line count and func_line the line number of first function. */
  172. static FILE *ini_cfile(char *path, FILE *rptfp, unsigned func_line,
  173.                             unsigned *count)
  174. {
  175.  char buffer[261];
  176.  FILE *fp;
  177.  
  178.  printf ("Third Pass: %s\n", path);
  179.  fp = open_c_file(path, rptfp);
  180.  while (  (fgets (buffer, 160, fp)) && ++(*count) < func_line) ;
  181.  
  182.  return (fp);
  183. }
  184.  
  185.  
  186.  
  187. int binary_search(char **item, int count, char *key)
  188. {
  189.    int low, high, mid;
  190.    int result = 0;
  191.  
  192.   low = 0;
  193.   high = count - 1;
  194.   while (low <= high)
  195.    {
  196.     mid = (low + high) / 2;
  197.     result =  strcmp(key, *(item + mid));
  198.     if (result < 0) high = mid - 1;
  199.       else if ( result > 0) low = mid + 1;
  200.       else
  201.       return (mid);
  202.    }
  203.  
  204.    return (-1);
  205. }
  206.  
  207.  /*create array of ptrs to function names, aligned in alphabetical order,
  208.  from linked list in which alphabeticization is by links, not by alignment
  209.  in memory */
  210. static char **create_bsearch_array(struct func *top)
  211. {
  212.  
  213.    char **ptr =  NULL, **ptr_start = NULL;
  214.      if ( !( ptr = (char **) malloc ( sizeof(char **) * function_no ) ) )
  215.             exit_ca (NO_BSEARCH_ARRAY, "");
  216.      ptr_start = ptr;
  217.  
  218.     while(top)
  219.     {
  220.      *ptr++ = top->name;
  221.      top = top->next;
  222.     }
  223.  
  224.   return (ptr_start);
  225.  }
  226.  
  227.  
  228. struct func *skip_fnptrs(struct func *func_top)
  229. {
  230.  
  231.   while (func_top &&  func_top->fnptr)
  232.     func_top = func_top->next_function;
  233.  
  234.   return(func_top);
  235. }
  236.  
  237.  
  238. int infunclist(char *token_string)
  239. {
  240.  struct func *top = top_mod;
  241.  
  242.  if (!top) return (0);
  243.  
  244.  while (top)
  245.  {
  246.  if (!strcmp( top->name, token_string) ) return (1);
  247.  top = top->next_function;
  248.  }
  249.  
  250.  return (0);
  251. }
  252.