home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource5
/
364_01
/
func_ca.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-26
|
14KB
|
486 lines
/*
HEADER: ;
TITLE: C-ACROSS;
VERSION 1.02
DESCRIPTION: "Utility for multiple module programs. Produces
Six indexes of functions, prototypes, and globals that
enable user to 'see across' modules for use in checking
and comparison. One of these is type of hierarchical
functions list, a listing by module of functions
and calls made FROM them; another is alphabetical list
of functions and calls made TO them. Globals listed
in schematic descriptors which record all modifiers
and qualifiers and enable checking of declarators
across modules. Creates, on request, header file
consisting of prototypes constructed from function
definitions. Can list user types #defined and some
preprocessor #defines. Full documentation in README.CA";
KEYWORDS: Utility, Cross Reference, Deubgging;
SYSTEM: MS-DOS;
FILENAME: FUNC_CA.C;
WARNINGS: "1. Assumes function definitions conform with
ANSI standards and have prototype form. See
also "Caveats and Restrictions" in README.CA.
2. Assumes syntactically correct source files.
3. Written and tested using Microsoft QuickC.
4. Copyright retained. See Copyright
information in README.CA.";
SEE-ALSO: EXIT_CA.C, GLOB_CA.C, IFDEF_CA.C, INTF_CA.C,
LINKL_CA.C, PARSE_CA.C, TDEF_CA.C, TYPES_CA, UTIL_CA.C,
UTLG_CA.C, XRF_CA.C, README.CA,
CA.H, CA.PRJ, CA.RPT, CDECL_CA.H, KEYWORDS.H;
AUTHORS: Myron Turner;
COMPILERS: Microsoft C;
*/
/* ************************** C-ACROSS **************************
V. 1.02
Copyright (C) Myron Turner
333 Bartlet Ave.
Winnipeg, Manitoba
Canada R3L 0Z9
(204) 284-8387
******************************************************************** */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <graph.h>
#define TYPEDEF_DEFINE
#define TDEF_EXTERNAL
#define TDEF_NUM
#define INCLUDEFILES_DEFINE
#include "keywords.h"
#define TESTRUN
#include "ca.h"
#include "ca_decl.h"
#define FLAG_S static short
#define UINT unsigned
#define OPEN_CURLY '{'
extern FILE *scrn_out;
extern int declare_file ; /* create a C declarations file: /UHF switch */
extern int __mods[_MAX_MODS];
extern int reading_includeF;
extern UINT int inclfLine;
extern UINT int inclFini;
int skipifdefn(char *p, int skipdef_status);
FLAG_S functionstart(char **hold_p, char **hold_tptr);
int func_def(char *p, char *module, struct func **top,
char *big_buf, FILE *rptfp);
static struct func *syntax(char *p, char * big_buf, char *module,
struct func *top, FILE *rptfp);
FILE **FP_ADDRESS;
int function_no = 0;
int In_Parentheses = 0;
int In_MainLoop = 0;
struct func *function = NULL, *FirstFunction = NULL;
struct includeFILE inclF;
#define BIGBUFSIZE 350 + 261
#define mod_type_check_off() __mods[0] = 0
#define INPARENTHESES -1
/* Group of variables used by several functions in this module: the */
/* gloabls eliminate need to pass excessive number of function arguments */
/* for variables which are needed in and changed by several functions */
static char *routine;
FLAG_S infunction = 0;
FLAG_S open_parenthesis = 0; /* = possible function */
FLAG_S buffering = 0; /* = more than one input line in possible function */
FLAG_S inner_paren= 0; /* track of parentheses within main parenthetical */
static int brackets = 0;
static UINT endfunction = 0;
static struct func *previous = NULL;
static UINT bufring_line_held=0; /* holds 1st lineno of funct'n def when */
/* definition takes up more than one line */
FLAG_S inliteral = 0;
static UINT int line_count = 0, lineno;
static char *token_ptr;
static int t_pos = 0, m_pos = 0;
static char buffer[261];
static void ini_Globals(void);
#define DEBUG_LINE 13
char *debugptr;
/**********************FUNCTIONS******************************/
/* Main Loop for first pass */
struct func *main_loop(FILE *fp, FILE *rptfp, char *module)
{
static struct func *top = NULL;
char *p, big_buf[BIGBUFSIZE];
int __type, skip_ifdef = 0;
FILE * hold_fp = NULL;
ini_Globals();
FP_ADDRESS = &fp;
hold_fp = fp;
memset( big_buf, '\0', BIGBUFSIZE );
ini_if_def_stack();
_clearscreen(0);
relocate();
if (scrn_out != (FILE *)stdout) fprintf(scrn_out,
"\n**********\n\nFirst Pass: %s\n", module);
printf("First Pass: %s\n", module);
/* Main loop looks for the first indicator of a function definition, */
/* which is the type specifier. It also handles comments and strings, */
/* keeps count of curly braces, in order to determine end of */
/* function body. */
startmainloop:
while ( fgets (buffer, 160, fp) )
{
p = buffer;
debugptr = p;
if (!reading_includeF) line_count++;
else
inclfLine++;
if (line_count == DEBUG_LINE)
line_count = DEBUG_LINE;
if (inclfLine == DEBUG_LINE)
inclfLine = DEBUG_LINE;
skip_ifdef = skipifdefn(p, skip_ifdef);
if (skip_ifdef) goto startmainloop;
/* count curly brackets to determine ending line of function body */
/* infunction is set to 1 in func_def(), when a function definition */
/* is found. */
if (infunction && *p != '\n') {
brackets += countbrackets(buffer);
if (!brackets)
endfunction = line_count;
if (!brackets) infunction = 0;
}
/* handle comments and strings */
do {
if ( (inliteral = isliteral(p)) ) p++;
} while ( *p && inliteral );
if (!inliteral)
if(buffering && open_parenthesis) In_Parentheses = 1;
while (iswhite(*p)) p++;
/* move through modifiers; */
if (!buffering) { m_pos = _modifier (p, 0); p += m_pos; }
/* if next element in line is a data type check for function def */
if ( (t_pos = data_type_(p, &__type)) || open_parenthesis)
top = syntax(p, big_buf, module, top, rptfp);
}
/* check to see whether we are in an include file: if so, go back to */
/* start of the main_loop */
if (close_include(hold_fp, &fp, rptfp, module))
goto startmainloop;
print_userdefs(rptfp, module);
if (previous) previous->endfunc_line = endfunction;
free_if_def_stack();
return (top);
}
static void make_function_token(char *token_ptr, char *function_name)
{
char *p = token_ptr, *function_ptr = function_name;
while (*p == '\x20' || *p == '\x9' || *p == '*') p++;
while ( *p && *p != ' ' && *p != '(' )
*function_ptr++ = *p++;
*function_ptr = '\0';
}
static void print_userdefs(FILE *rptfp, char *module)
{
int i, j = 0;
char *tm[] = {"", "Modifier", "Type" };
fprintf(scrn_out, "\nUSER DEFINED TYPES AND MODIFIERS IN: %s ", module);
for (i = 0; i < __typedef_count; i++) {
j = (__typ_mod[i] & 0xf);
fprintf(scrn_out,"\n%d: %s [ %s ]", i, __type_def[i], tm[j]);
}
fprintf(scrn_out, "\n");
fprintf(scrn_out, "\n");
}
#define PTR_to_FN !In_MainLoop
struct func *fill_func_struct(char *token_ptr, int lineno, char *module)
{
static struct func *top = NULL;
function = (struct func *)
malloc ( sizeof (struct func) );
function->line_no = lineno;
/* list functions in order of appearance in files */
link_by_module(function);
function->first_call = NULL;
make_function_token(token_ptr, function->name);
strcpy (function->module, module);
if (PTR_to_FN) function->fnptr = 1;
else function->fnptr = 0;
top = store_linked_list(function, top);
function_no++;
if (!FirstFunction) FirstFunction = function;
return(top);
}
/* This function does syntactical analysis of the input line. */
/* If line includes possible function definition, it is sent to */
/* func_def() to determine whether it holds a function definition. */
static struc