Beruflich Dokumente
Kultur Dokumente
by Ron Winter
[LISTING ONE]
/*********************************************************************
cpheader.h
*********************************************************************/
#include <malloc.h>
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define false 0
#define true 1
#define completed 2
/*********************************************************************/
typedef struct the_Pages
{
int on_this_page;
struct the_Pages *next_page_ptr;
}linked_pages_list;
/**********************************************************************/
typedef struct
{
char *functions_name;
char *its_filename;
int is_referenced;
int static_function;
}function_type;
/**********************************************************************/
typedef struct
{
char *source_filename;
char *source_file_comment;
unsigned int line_count;
long size;
}file_record_type;
/**********************************************************************/
typedef struct /* this is the main data base record */
{
file_record_type *file_record_ptr;
char *defined_function;
function_type *ptr_to_function_table;
int number_of_function_calls;
linked_pages_list *ptr_to_page_list;
int number_of_references;
int static_definition;
int overlay_number;
}data_base_record_type;
/**********************************************************************/
#if MAIN != 0
/***********************************************************************/
function_type /* 6 */
**sorted_called_list_ptrs,
*function_list,
*function_list_ptr;
int
Max_functions,
count_of_functions = 0;
/********************************/
file_record_type /* 14 */
*file_record_array,
*file_record_array_ptr;
int
count_of_source_files = 0;
/********************************/
data_base_record_type /* 20 */
*data_base_array,
*data_base_array_ptr,
**array_of_unused_ptrs_to_records,
**array_of_ptrs_to_records;
int
count_of_valid_records = 0;
/********************************/
int effective_width;
int
page = 1,
line = 0,
defined_page_width = 80,
defined_page_length = 60,
defined_left_margin = 1,
defined_right_margin = 1,
stats_only = false,
g_lib_flag = false,
g_comment_flag = false,
g_dec_def_flag = false,
g_help_flag = false,
ibm_flag = true,
g_quiet_flag = false,
g_tech_flag = false,
g_ov_flag = false,
g_un_flag = false,
target_flag = false;
int top_of_form_done;
char title[] =
/* mm/dd/yy0 hh:mm:ss0 */
{ " C PRINTER - (c) 1987, 1988 rev. 1.3" };
/********************************************************************/
#else
/*********************************************************************/
extern function_type
**sorted_called_list_ptrs,
*function_list,
*function_list_ptr;
extern file_record_type
*file_record_array,
*file_record_array_ptr;
extern data_base_record_type
*data_base_array,
*data_base_array_ptr,
**array_of_unused_ptrs_to_records,
**array_of_ptrs_to_records;
extern char *recursion_array[ ];
extern int
count_of_valid_records,
Max_functions,
count_of_functions,
count_of_source_files;
extern int page, line, recursion_depth;
extern int first_comment;
extern char nesting_display_buffer[ ];
extern char top_bottom_line_of_box[ ];
extern FILE *output;
extern char push_buffer[ ];
extern char *push_buffer_ptr;
extern char file_comment_buffer[ ];
extern int defined_page_width;
extern int defined_page_length;
extern int defined_left_margin;
extern int defined_right_margin;
extern int effective_width;
extern char target[ ];
extern int
stats_only,
g_lib_flag,
g_comment_flag,
g_dec_def_flag,
g_help_flag,
ibm_flag,
g_quiet_flag,
g_tech_flag,
g_ov_flag,
g_un_flag,
target_flag;
extern int top_of_form_done;
extern char title[];
/*********************************************************************/
#endif
/**********************************************************************/
[LISTING TWO]
/*********************************************************************
cp.c
***************************************************************************/
#define MAIN 1
#include "cpheader.h"
#include "time.h"
/***************************************************************************/
length =
(unsigned long)Max_defined_functions * sizeof( data_base_record_type );
if( length > 65535 )
{
(void)printf( "too many defined functions ( go to huge model code )\n" );
exit( 1 );
}
else
if(
!( data_base_array =
(data_base_record_type *)malloc( (unsigned int)length )
)
)
{
(void)printf( "No room for data_base_array\n" );
exit( 1 );
}
else
{
if( !g_quiet_flag && g_tech_flag )
(void)printf( "data base array = %lu bytes long\n", length );
}
length =
(unsigned long)Max_defined_functions * sizeof( data_base_record_type * );
if( length > 65535 )
{
(void)printf(
"too many defined functions pointers( go to huge model code )\n"
);
exit( 1 );
}
else
if(
!( array_of_ptrs_to_records =
(data_base_record_type **)malloc( (unsigned int)length )
)
)
{
(void)printf( "No room for *array_of_ptrs_to_records\n" );
exit( 1 );
}
else
{
if( !g_quiet_flag && g_tech_flag )
(void)printf( "array of ptrs to data base = %lu bytes long\n",
length );
}
if( i == 0 )
i = 12;
if( i >= 13 )
i -= 12;
if(
( l = strlen( input_line ) ) > 1 /* ie not nul string */
)
{
if( input_line[ l - 1 ] == '\n' )
input_line[ l - 1 ] = '\0';
if( !g_quiet_flag )
{
(void)printf( "\n\nSorting the function list...\n" );
(void)printf( " of %d functions\n", count_of_valid_records );
}
still_sorting_flag = true;
while( still_sorting_flag )
{
still_sorting_flag = false;
if( !g_quiet_flag )
{
(void)printf( "." );
}
for( i = 0; i < count_of_valid_records - 1; ++i )
{
if( strcmp( array_of_ptrs_to_records[ i ]->defined_function,
array_of_ptrs_to_records[ i + 1 ]->defined_function ) > 0 )
{
still_sorting_flag = true;
data_base_array_ptr = array_of_ptrs_to_records[ i ];
array_of_ptrs_to_records[ i ] = array_of_ptrs_to_records[ i + 1 ];
array_of_ptrs_to_records[ i + 1 ] = data_base_array_ptr;
}
}
}
}
/************************************************************************/
file_record_array_ptr = file_record_array;
do_top_of_page();
(void)fprintf( output, "File statistics:\n" );
bump_line_count();
total_byte_count = 0l;
total_line_count = 0l;
for( i = 0; i < count_of_source_files; ++i )
{
(void)fprintf( output,
"%-40s - %8u lines, %12ld bytes\n",
file_record_array_ptr->source_filename,
file_record_array_ptr->line_count,
file_record_array_ptr->size
);
bump_line_count();
total_byte_count += file_record_array_ptr->size;
total_line_count += file_record_array_ptr->line_count;
++file_record_array_ptr;
}
(void)fputc( '\n', output );
bump_line_count();
(void)fprintf( output, "Totals:\n" );
bump_line_count();
/******** "%-40s - %8u lines, %12ld bytes\n", *******/
(void)fprintf( output, "%4d files%-30s - %8ld lines, %12ld bytes\n",
count_of_source_files, " ", total_line_count, total_byte_count
);
bump_line_count();
(void)fputc( '\n', output );
bump_line_count();
(void)fprintf( output,
" %d defined functions found.\n", count_of_valid_records
);
bump_line_count();
(void)fprintf( output, "Averages:\n" );
bump_line_count();
(void)fprintf( output,
"%6d lines/file, %6d functions/file, %6d lines/function\n",
(int)( total_line_count / count_of_source_files ),
(int)( count_of_valid_records / count_of_source_files ),
(int)( total_line_count / count_of_valid_records )
);
}
/***************************************************************************/
do_top_of_page();
if( g_ov_flag )
(void)fprintf( output, "%-39s %-28s %s %s\n",
"function", "in file", "ov#", "refs" );
else
(void)fprintf( output, "%-39s %-28s %s\n",
"function", "in file", "refs" );
bump_line_count();
for( record_index = 0;
record_index < count_of_valid_records;
++record_index
)
{
data_base_array_ptr = array_of_ptrs_to_records[ record_index ];
if( data_base_array_ptr->number_of_references > 0 )
{
if( g_ov_flag && data_base_array_ptr->overlay_number )
(void)fprintf( output, "%-7s%-32s %-28s %3d %d\n",
( data_base_array_ptr->static_definition )?
"static": "",
data_base_array_ptr->defined_function,
( data_base_array_ptr->file_record_ptr )->source_filename,
data_base_array_ptr->overlay_number,
data_base_array_ptr->number_of_references
);
else
(void)fprintf( output, "%-7s%-32s %-28s %d\n",
( data_base_array_ptr->static_definition )?
"static": "",
data_base_array_ptr->defined_function,
( data_base_array_ptr->file_record_ptr )->source_filename,
data_base_array_ptr->number_of_references
);
reference_total += (long)data_base_array_ptr->number_of_references;
bump_line_count();
}
}
(void)fprintf( output, "%-7s%-32s %-28s %s\n",
" ", " ", " ", "____"
);
bump_line_count();
(void)fprintf( output, "%-7s%-32s %-28s %ld\n",
" ", " ", "total ", reference_total
);
bump_line_count();
}
/***************************************************************************/
do_top_of_page();
(void)fprintf( output, "Un-used function list:\n" );
bump_line_count();
unused_count = 0;
for( i = 0; i < count_of_valid_records; ++i )
{
data_base_array_ptr = array_of_ptrs_to_records[ i ];
if( !data_base_array_ptr->number_of_references )
{
++unused_count;
if( !g_un_flag )
{
(void)fprintf( output,
"%-7s%-32s- %-33s\n",
( data_base_array_ptr->static_definition )?
"static": "",
data_base_array_ptr->defined_function,
( data_base_array_ptr->file_record_ptr )->source_filename
);
bump_line_count();
}
}
}
if( g_un_flag ) /* show sorted */
{
if( unused_count )
{
if(
!( array_of_unused_ptrs_to_records =
(data_base_record_type **)malloc( (unsigned int)unused_count )
)
)
(void)printf( "No room for *array_of_unused_ptrs_to_records\n" );
else
{
unused_index = 0;
for( i = 0; i < count_of_valid_records; ++i )
{
data_base_array_ptr = array_of_ptrs_to_records[ i ];
if( !data_base_array_ptr->number_of_references )
{ /* first just collect them */
array_of_unused_ptrs_to_records[ unused_index++ ] =
data_base_array_ptr;
}
} /* so now there are unused_index of them */
unused_list_ptr_ptr = array_of_unused_ptrs_to_records;
still_sorting_flag = true;
if( unused_count > 1 )
{
while( still_sorting_flag )
{
still_sorting_flag = false;
if( !g_quiet_flag && g_tech_flag )
(void)printf( ".%d \r", count );
for( count = 0; count < unused_count - 1; ++count )
{
if( strcmp( unused_list_ptr_ptr[ count ]->
file_record_ptr->source_filename,
unused_list_ptr_ptr[ count + 1 ]->
file_record_ptr->source_filename
) > 0
)
{
still_sorting_flag = true;
unused_list_ptr = unused_list_ptr_ptr[ count ];
unused_list_ptr_ptr[ count ] =
unused_list_ptr_ptr[ count + 1 ];
unused_list_ptr_ptr[ count + 1 ] = unused_list_ptr;
}
}
}
}
for( i = 0; i < unused_count; ++i )
{
(void)fprintf( output,
"%-7s%-32s- %-33s\n",
( unused_list_ptr_ptr[ i ]->static_definition )?
"static": "",
unused_list_ptr_ptr[ i ]->defined_function,
( unused_list_ptr_ptr[ i ]->file_record_ptr )->source_filename
);
bump_line_count();
}
}
}
}
if( !unused_count )
{
tab_to_left_margin( output );
(void)fprintf( output, "No un-used functions in the list.\n" );
bump_line_count();
}
else
{
(void)fprintf( output, "%-7s%-39s- %d\n", "", "totals", unused_count );
bump_line_count();
}
}
/************************************************************************/
if( g_lib_flag )
{
if( !g_quiet_flag && g_tech_flag )
(void)printf( "collecting library functions...\n" );
do_top_of_page();
(void)fprintf( output, "Library functions:\n" );
bump_line_count();
total = 0;
f_list_ptr = function_list;
for( count = 0; count < count_of_functions; ++count )
{
if( !f_list_ptr->static_function )
{
if(
( found =
binary_search_sorted_data_base( f_list_ptr->functions_name )
) < 0
)
sorted_called_list_ptrs[ total++ ] = f_list_ptr;
}
++f_list_ptr; /* for all called functions */
}
f_list_ptr_ptr = sorted_called_list_ptrs;
still_sorting_flag = true;
while( still_sorting_flag )
{
still_sorting_flag = false;
if( !g_quiet_flag && g_tech_flag )
(void)printf( ".%d \r", count );
for( count = 0; count < total - 1; ++count )
{
if( strcmp( f_list_ptr_ptr[ count ]->functions_name,
f_list_ptr_ptr[ count + 1 ]->functions_name ) > 0 )
{
still_sorting_flag = true;
f_list_ptr = f_list_ptr_ptr[ count ];
f_list_ptr_ptr[ count ] = f_list_ptr_ptr[ count + 1 ];
f_list_ptr_ptr[ count + 1 ] = f_list_ptr;
}
}
}
if( !g_quiet_flag && g_tech_flag )
(void)printf( "\n" );
final_call = 0;
f_list_ptr_ptr = sorted_called_list_ptrs;
for( count = 0; count < total; ++count )
{
if( ( *f_list_ptr_ptr )->functions_name[ 0 ] != '\0' )
{
(void)fprintf( output, "%-32s %d\n",
( *f_list_ptr_ptr )->functions_name,
( *f_list_ptr_ptr )->is_referenced
);
final_call += ( *f_list_ptr_ptr )->is_referenced;
bump_line_count();
}
++f_list_ptr_ptr;
}
(void)fprintf( output, "Totals:\n" );
bump_line_count();
(void)fprintf( output, "%6d %-25s %d calls.\n",
final_count, "library functions,", final_call
);
bump_line_count();
}
}
/************************************************************************/
nasty( argc );
index = 1;
if( !( stream = fopen( argv[ index ], "rt" ) ) )
in_error = true;
else
++index;
if(
( argc > index ) &&
(
( argv[ index ][ 0 ] != '/' ) && ( argv[ index ][ 0 ] != '-' )
)
)
{
output = fopen( argv[ 2 ], "w+" ); /******* wt+ <<<<<<<< ******/
++index;
}
else
output = fopen( "prn", "w+" ); /******** wt+ <<<<<< ********/
if( !output )
out_error = true;
Max_functions = MAX_functions;
process_arguments( index, argc, argv, in_error || out_error );
if( in_error )
{
(void)printf( "\n can't open input list %s\n", argv[ 1 ] );
exit( 1 );
}
if( out_error )
{
(void)printf( "\n can't open output file, error %s\n", strerror( errno ) );
exit( 1 );
}
allocate_arrays( );
initialize_globals( );
(void)printf( "\n" );
build_records_from_list( stream );
sort_the_data_base_array( );
if( !g_quiet_flag )
{
(void)printf( "\n" );
}
top_of_form_done = false;
show_function_relationships( );
show_page_references( );
show_line_and_byte_counts( );
show_sorted_function_list( );
show_unused_if_any( );
show_library_functions( );
show_files_leading_comments( );
deallocate_arrays( );
return false; /* ok */
}
/********************************************************************/
[LISTING THREE]
/***********************************************************************
cpinput.c
void near nasty( int );
void near process_arguments( int, int, char **, int );
************************************************************************/
#define MAIN 0
#include "cpheader.h"
(void)printf( "\n" );
exit( 0 );
}
}
/**********************************************************************/
void near process_arguments( index, argc, argv, an_error )
int index, argc, an_error;
char **argv;
{
char c;
int i, tmp;
if( g_tech_flag )
{
(void)printf( "\n" );
(void)printf( "Notes: 1. Max recursive function displacement of %d.\n",
Max_Recursion
);
(void)printf(
" 2. Max # of unique function calls per defined function\n\
for all defined functions is %d.\n",
Max_functions );
(void)printf( " 3. Max # of defined functions is %d.\n",
Max_defined_functions );
(void)printf( "\n" );
(void)printf( "sizeof()\'s:\n" );
(void)printf(
" function table = %u, contents = %u, data base = %u,\
database = %u, lib = %u\n",
sizeof( function_type ),
sizeof( file_record_type ),
sizeof( data_base_record_type ),
sizeof( array_of_ptrs_to_records ),
sizeof( sorted_called_list_ptrs )
);
(void)printf( "\n" );
(void)printf(
"The program will tend to show certain \'c\' functions as unused.\n" );
(void)printf(
"1. defined functions assigned to declared pointers to function names\n" );
(void)printf(
" and executed as pointers to those function names won't be seen.\n" );
(void)printf(
"2. #if(s) controlling the generation of code especially with\n" );
(void)printf(
" braces( { } ) in the conditional code section will especially\n" );
(void)printf(
" screw up if there is an #else code part. This program will work\n" );
(void)printf(
" on both code parts of the conditional and most probably get out\n" );
(void)printf(
" of sync with the braces. One might do a preprocessor pass compile\n" );
(void)printf(
" and heave it\'s output files as input files at this program.\n" );
(void)printf(
"3. #define(s) that expand to functions and call functions will also\n" );
(void)printf(
" be neglected. The preprocessor may be used as stated above.\n" );
/******
(void)printf(
"\n" );
******/
(void)printf( "\n" );
}
if( g_help_flag )
{
(void)printf( "\n" );
(void)printf(
"The listfile argument is an ascii text file containing the list of\n"
);
(void)printf(
"filenames to process, one filename per line (optional overlay number.)\n"
);
(void)printf(
"The output file may be a device or a filename. If there is no\n"
);
(void)printf(
"output filename, \'prn\' is assumed. Note that one may put \'con\'\n"
);
(void)printf(
"here and view the output of the program before printing or saving\n"
);
(void)printf(
"to a filename.\n"
);
(void)printf(
"Also note that the output filename and the input filenames in the\n"
);
(void)printf(
"listfile may be full pathnames with drives and or paths.\n"
);
(void)printf( "/ arguments accept the alternate - form.\n" );
(void)printf( "For example: cp x y -s, cp /h, cp x -x /d -t:junk\n" );
(void)printf( "arguments may be in upper or lower case.\n" );
(void)printf( "Note that the target function is case sensitive\n" );
(void)printf( "since it is a \'c\' function name.\n" );
(void)printf( "\n" );
}
if( an_error )
{
if( g_help_flag || g_tech_flag )
exit( 0 );
else
(void)printf( "Oops..." );
}
}
/***********************************************************************/
[LISTING FOUR]
/***************************************************************************
cpbuild.c
static void near mark_as_static( function_type *, char*, int );
static int near test_and_add( function_type *, char *, int );
static void near unget_chars( char );
static char near get_chars( FILE * );
static char near get_to_next_possible_token( FILE * );
static int near is_legal_identifier_character( char );
int near build_the_data_base( char * );
***************************************************************************/
#define MAIN 0
#include "cpheader.h"
/***************************************************************************/
static void near mark_as_static( ptr_to_function_list,
name_of_static_function, count
)
char *name_of_static_function;
function_type *ptr_to_function_list;
int count;
{
int i;
static int /* the only apparent reason these are static is for speed */
quotes_flag = false,
comment_flag = false,
escape_sequence_flag = false,
pound_sign_flag = false,
ascii_quote_flag = false;
static int
fp = 0; /*****<<<<< */
static char *cp;
done = false;
do {
c = get_chars( stream );
if( c != Control_z )
{
if( comment_flag )
{
/**************************
process /* comment sequence of characters
***************************/
if( first_comment == true )
{
if( fp < ( Max_general_buffers - 2 ) )
{
if(
( c != '\n' ) &&
( strlen( cp ) < effective_width )
)
{
file_comment_buffer[ fp++ ] = c;
file_comment_buffer[ fp ] = '\0';
}
else /* c == \n or length >= width */
{
file_comment_buffer[ fp++ ] = '\n';
file_comment_buffer[ fp ] = '\0';
cp = (char *)&file_comment_buffer[ fp ];
if( c != '\n' )
{
file_comment_buffer[ fp++ ] = c;
file_comment_buffer[ fp ] = '\0';
}
}
}
/* else /* 1st comment exceeds buffer */
} /* end of if first_comment == true */
if( c == '*' )
{
next_char_peek = get_chars( stream );
if( next_char_peek == '/' ) /* close comment */
{
comment_flag = false;
unget_chars( ' ' ); /* comments are white space in 'c' */
if( first_comment == true )
{
first_comment = completed;
fp = 0;
cp = (char *)&file_comment_buffer[ fp ];
}
}
else /* next_char_peek != '/' ie close comment */
unget_chars( (char)next_char_peek );
} /* end of if c == '*' */
}
else /* not /* */
{
/**************************
process \sequence character, hoping \" \' \\ etc inside " or '
***************************/
if( escape_sequence_flag )
escape_sequence_flag = false;
else /* not /*, not \ */
{
/**************************
process " string sequence of characters
***************************/
if( quotes_flag )
{
if( c == '\\' ) /* check for \'\n' */
{
next_char_peek = get_chars( stream );
if( next_char_peek != '\n' ) /* so not \'\n' */
{
escape_sequence_flag = true;
unget_chars( (char)next_char_peek );
}
/******* else /* \'\n' continuation */
}
else /* not \ */
if( c == '\"' )
quotes_flag = false;
}
else /* not ", not /*, not \ */
{
/**************************
process ' ascii character sequence
***************************/
if( ascii_quote_flag )
{
if( c == '\\' )
escape_sequence_flag = true;
else
if( c == '\'' )
ascii_quote_flag = false;
}
else /* not ', not ", not /*, not \ */
{
/**************************
process # sequence of characters, ie #if, #define, etc.
define causes code sequencing problems it would seem!
***************************/
if( pound_sign_flag )
{
if( c == '/' ) /* comments override #defines etc */
{
next_char_peek = get_chars( stream );
if( next_char_peek == '*' )
comment_flag = true;
else
unget_chars( (char)next_char_peek );
}
else
{
if( c == '\n' )
pound_sign_flag = false;
else /* c != \n */
{
if( c == '\\' ) /* check for \'\n' continuation */
{
next_char_peek = get_chars( stream );
if( next_char_peek != '\n' ) /* it aint \'\n' */
unget_chars( (char)next_char_peek );
/* else /* \'\n' means continue # */
}
}
}
}
else /* not ', not #, not ", not /*, not \ */
{
/**************************
process anything else
***************************/
done = false; /* assume a ' or " or # or /* */
switch( c )
{
case '\"':
quotes_flag = true;
break;
case '\'':
ascii_quote_flag = true;
break;
case '#':
pound_sign_flag = true;
break;
case '/':
next_char_peek = get_chars( stream );
if( next_char_peek == '*' )
{
comment_flag = true;
if( first_comment == false )
{ /* the 1st comment of the file */
first_comment = true;
fp = 0;
cp = (char *)&file_comment_buffer[ fp ];
}
}
else
{
unget_chars( (char)next_char_peek );
done = true;
}
break;
default: /* a worthy character to return */
done = true;
}
} /* end of else not ascii */
} /* end of else not # */
} /* end of else not " */
} /* end of else not /* */
} /* end of else not \ */
} /* end of if c != Control_z */
}
while( !done && ( c != Control_z ) );
if( c == Control_z )
{
ascii_quote_flag = false;
pound_sign_flag = false;
quotes_flag = false;
escape_sequence_flag = false;
comment_flag = false;
fp = 0;
}
return c;
}
/***************************************************************************/
static int near is_legal_identifier_character( c )
char c;
{
if(
( ( 'A' <= c ) && ( c <= 'Z' ) ) ||
( ( 'a' <= c ) && ( c <= 'z' ) ) ||
( ( '0' <= c ) && ( c <= '9' ) ) ||
( c == '_')
)
return true;
else
return false;
}
/***************************************************************************/
#define C_line_length 512
#define C_identifier_length 80
if( !g_quiet_flag )
{
(void)printf( "Processing file: %-12s\n", the_filename );
}
if( !( stream = fopen( the_filename, "r" ) ) ) /***** rt <<<<<<<<<< */
{
(void)printf( "Cant open %s\n", the_filename );
return -1;
}
starting_called_function_ptr = function_list_ptr;
starting_data_base_ptr = data_base_array_ptr; /* mark start of defined list */
look_ahead_buffer[ 0 ] = '\0';
first_comment = false;
file_comment_buffer[ 0 ] = '\0';
function_name_buffer_ptr = function_name_buffer;
function_name_buffer[ 0 ] = '\0';
static_flag = false;
found_a_possible_function = false;
open_parenthesis = false;
body_found = false;
brace_count = 0;
parenthesis_count = 0;
at_end_of_source_file = false;
while( !at_end_of_source_file )
{
c = get_to_next_possible_token( stream );
switch( c )
{
case '{':
++brace_count;
break;
case '}':
--brace_count;
break;
case Control_z:
at_end_of_source_file = true;
analyze_buffer_flag = true;
break;
case '(':
if( !open_parenthesis )
++open_parenthesis;
analyze_buffer_flag = true;
break;
case ' ': /* this is where we eat white space */
case '\v':
case '\b':
case '\f':
case '\t':
case '\r':
case '\n':
do {
c = get_to_next_possible_token( stream );
}
while(
( c == '\f' ) || ( c == ' ' ) || ( c == '\v' ) ||
( c == '\b' ) || ( c == '\t' ) || ( c == '\r' ) ||
( c == '\n' )
);
unget_chars( c ); /* put next non white character back */
if( c != '(' )
analyze_buffer_flag = true;
/*** else /* c == '(' and next pass will find it */
break;
default:
if( is_legal_identifier_character( c ) )
{ /* it's a good identifier character */
*function_name_buffer_ptr++ = c;
*function_name_buffer_ptr = '\0';
}
else /* it aint, so toss it */
{
if( static_flag && ( c == ';' ) )
static_flag = false;
/* if( c != '*' ) */
analyze_buffer_flag = true;
}
break;
} /* end of preliminary character parse */
/*****************
start checking characters accumulated in function_name_buffer[]
******************/
if( analyze_buffer_flag )
{
analyze_buffer_flag = false;
if(
function_name_buffer[ 0 ] && /* ie not null string */
( /* & not number */
( function_name_buffer[ 0 ] < '0' ) ||
( function_name_buffer[ 0 ] > '9' )
)
)
found_a_possible_function = true;
else /* it aint an identifier */
{ /* so erase buffer */
function_name_buffer_ptr = function_name_buffer;
function_name_buffer[ 0 ] = '\0';
if( static_flag && ( c == ';' ) )
static_flag = false;
open_parenthesis = false;
}
} /* end of analyze_buffer_flag */
/*****************
if function_name_buffer[] has legal function name, scan ahead
******************/
if( found_a_possible_function )
{
found_a_possible_function = false;
*function_name_buffer_ptr = '\0'; /* append nul char to end */
if( !static_flag ) /* don't retest if true */
if( !strcmp( function_name_buffer, "static" ) )
static_flag = true;
if( open_parenthesis )
{
open_parenthesis = false;
if( !brace_count )
{ /* ie outside any function body */
parenthesis_count = 1;
for( dummy_index = 0;
( dummy_index < C_line_length ) && parenthesis_count;
++dummy_index
)
{ /* scan ahead for function() */
c = get_to_next_possible_token( stream );
if( c == Control_z )
break; /* dummy_index not bumped */
look_ahead_buffer[ dummy_index ] = c;
look_ahead_buffer[ dummy_index + 1 ] = '\0';
switch( c )
{
case '(':
++parenthesis_count;
break;
case ')':
--parenthesis_count;
break;
} /* dummy_index is bumped */
} /* end of for loop scanning for (...) */
if( ( c == Control_z ) || ( !parenthesis_count ) )
--dummy_index;
function_definition_flag = false;
for( ++dummy_index;
( dummy_index < C_line_length ) && !function_definition_flag;
++dummy_index
)
{ /* what happens past (..) */
c = get_to_next_possible_token( stream );
if( c == Control_z )
break; /* w/ function_definition_flag == false */
look_ahead_buffer[ dummy_index ] = c;
look_ahead_buffer[ dummy_index + 1 ] = '\0';
switch( c )
{
case ' ': /* this is where we eat white space */
case '\v':
case '\b':
case '\f':
case '\t':
case '\n':
case '\r':
break;
case '{':
++body_found;
break;
case ';':
case ',':
case '(': /* at (*)() type declaration */
if( !body_found )
{
function_definition_flag = true; /* declaration */
if( !g_quiet_flag )
{
if( g_dec_def_flag )
{
if( static_flag )
(void)printf( " static" );
else
(void)printf( " " );
(void)printf( " declaration " );
(void)printf( "%s(%s\n",
function_name_buffer,
look_ahead_buffer );
}
}
}
break;
default: /* any other non white character means */
function_definition_flag = completed;
if( !g_quiet_flag )
{
if( g_dec_def_flag )
{
if( static_flag )
(void)printf( "static " );
else
(void)printf( " " );
(void)printf( "define " );
}
}
break;
} /* dummy_index is bumped */
} /* end of for loop parsing character after ) */
body_found = false;
if( function_definition_flag == false )
{
(void)printf( "\nSyntax error: " );
(void)printf( "Function description.\n" );
look_ahead_buffer[ dummy_index ] = '\0';
(void)printf( "\n%s\n", look_ahead_buffer );
exit( 1 );
}
while( dummy_index )
{ /* put all characters after ( back */
unget_chars( look_ahead_buffer[ dummy_index - 1 ] );
--dummy_index;
}
if( function_definition_flag == completed )
{
if( !g_quiet_flag )
{
if( g_dec_def_flag )
(void)printf( "%-40s\n", function_name_buffer );
}
/*******************
this element can distinguish static functions
in different files with the same name
*******************/
data_base_array_ptr->file_record_ptr = file_record_array_ptr;
data_base_array_ptr->number_of_function_calls = 0;
data_base_array_ptr->ptr_to_function_table = function_list_ptr;
data_base_array_ptr->static_definition = static_flag;
static_flag = false;
if(
!( data_base_array_ptr->defined_function =
strdup( function_name_buffer )
)
)
{
(void)printf( "\nRan out of memory( for strdup() )." );
exit( 1 );
}
data_base_array_ptr->number_of_references = 0;
data_base_array_ptr->ptr_to_page_list = NULL;
if(
!( file_record_array_ptr->source_file_comment =
strdup( file_comment_buffer )
)
)
file_record_array_ptr->source_file_comment = fake_comment;
[LISTING FIVE]
/***************************************************************************
cpfuncts.c
void near build_box_parts( int );
void near tab_to_left_margin( FILE * );
static void near stop( void );
static void near setpage( data_base_record_type * );
static int near recursion_check( char *, int );
void near check_for_new_page( void );
static void near draw_output_block( char *, char *, char *,
char *, int, int, int );
int near doprint( int );
void near scan_for_static_or_global( int *, int, char *, char * );
int near binary_search_sorted_data_base( char * );
***************************************************************************/
#define MAIN 0
#include "cpheader.h"
static char
top_line_of_box[ 37 ], bottom_line_of_box[ 37 ],
wall, ibm_line, bottom_attach,
upper_left_corner, lower_left_corner,
upper_right_corner, lower_right_corner,
left_attach, right_attach;
/***************************************************************************/
void near build_box_parts( is_ibm )
int is_ibm;
{
int i;
if( is_ibm )
{
wall = '\xb3';
ibm_line = '\xc4';
bottom_attach = '\xc2';
upper_left_corner = '\xda';
lower_left_corner = '\xc0';
upper_right_corner = '\xbf';
lower_right_corner = '\xd9';
left_attach = '\xb4';
right_attach = '\xc3';
}
else
{
wall = '|';
ibm_line = '-';
bottom_attach = '+';
upper_left_corner = '+';
lower_left_corner = '+';
upper_right_corner = '+';
lower_right_corner = '+';
left_attach = '+';
right_attach = '+';
}
top_line_of_box[ 0 ] = upper_left_corner;
bottom_line_of_box[ 0 ] = lower_left_corner;
for( i = 1; i <= 34; ++i )
{
top_line_of_box[ i ] = ibm_line;
bottom_line_of_box[ i ] = ibm_line;
}
top_line_of_box[ i ] = upper_right_corner;
bottom_line_of_box[ i ] = lower_right_corner;
top_line_of_box[ ++i ] = '\0';
bottom_line_of_box[ i ] = '\0';
}
/***************************************************************************/
void near tab_to_left_margin( output )
FILE *output;
{
register int i;
page_list_ptr = data_base_ptr->ptr_to_page_list;
if( page_list_ptr == NULL )
{
if(
!( page_list_ptr =
(linked_pages_list *)malloc( sizeof( linked_pages_list ) )
)
)
{
(void)fprintf( stderr, "Ran out of memory for page # list.\n" );
exit( 1 );
}
data_base_ptr->ptr_to_page_list = page_list_ptr;
}
else
{
while( page_list_ptr->next_page_ptr )
page_list_ptr = page_list_ptr->next_page_ptr;
if(
!( page_list_ptr->next_page_ptr =
(linked_pages_list *)malloc( sizeof( linked_pages_list ) )
)
)
{
(void)fprintf( stderr, "Ran out of memory for page # list.\n" );
exit( 1 );
}
page_list_ptr = page_list_ptr->next_page_ptr;
}
page_list_ptr->next_page_ptr = NULL;
page_list_ptr->on_this_page = page - 1;
}
/***************************************************************************/
static int near recursion_check( string, static_call )
char *string;
int static_call;
{
register char **recursion_array_ptr;
recursion_array_ptr = recursion_array;
if( static_recursion )
{ /* defined function is static */
while(
*recursion_array_ptr && /* not null */
/* and different function names */
( strcmp( *recursion_array_ptr, string ) ||
/* or same function names and */
/* in different files */
strcmp( test_filename, recursion_filename )
)
)
++recursion_array_ptr;
}
else
{ /* defined function is not static */
while(
*recursion_array_ptr && /* not null & */
/* and different function names */
( strcmp( *recursion_array_ptr, string ) ||
/* or same function names and */
static_call /* called is static */
)
)
++recursion_array_ptr;
}
return ( *recursion_array_ptr )? true: false;
}
/***************************************************************************/
void near check_for_new_page()
{
int i;
line += 4;
top_of_form_done = false;
}
/***************************************************************************/
static char library_string[] = { "(library)" };
static char usage_string[] = { "Used=" };
static char funct_string[] = { "Functs=" };
starting_index = index;
record_ptr = array_of_ptrs_to_records[ starting_index ];
++recursion_depth;
/**** mystic width = 4 *****/
(void)strcat( nesting_display_buffer, " |" );
nesting_display_buffer[ strlen( nesting_display_buffer ) - 1 ] = wall;
max_count = record_ptr->number_of_function_calls;
for( loop_counter = 0, f_list_ptr = record_ptr->ptr_to_function_table;
loop_counter < max_count;
++loop_counter, ++f_list_ptr
)
{
kill_flag = ( loop_counter == ( max_count - 1 ) )? true: false;
check_for_new_page();
/* is called function defined? */
found = binary_search_sorted_data_base( f_list_ptr->functions_name );
if( found >= 0 )
{
scan_for_static_or_global( &found,
f_list_ptr->static_function,
f_list_ptr->functions_name,
f_list_ptr->its_filename
);
}
if( found >= 0 ) /* yes */
{
test_filename = f_list_ptr->its_filename;
if( recursion_check( f_list_ptr->functions_name,
f_list_ptr->static_function )
)
{
/* tab_to_left_margin( output );
/* (void)fprintf( output, "%s\n", nesting_display_buffer ); */
setpage( array_of_ptrs_to_records[ found ] );
/* ++line; */
top_of_form_done = false;
draw_output_block( nesting_display_buffer,
f_list_ptr->functions_name,
"(recursive)",
"",
0,
false,
kill_flag
);
}
else /* not recursive and found >= 0 */
{
if( array_of_ptrs_to_records[ found ]->number_of_references == 1 )
{ /* got a new function */
/* tab_to_left_margin( output );
/* (void)fprintf( output, "%s\n", nesting_display_buffer );
/* ++line;
/* top_of_form_done = false; */
doprint( found ); /* used only once */
}
else
{ /* a previously defined function */
/* tab_to_left_margin( output );
/* (void)fprintf( output, "%s\n", nesting_display_buffer ); */
setpage( array_of_ptrs_to_records[ found ] );
/* ++line;
/* top_of_form_done = false; */
draw_output_block( nesting_display_buffer,
f_list_ptr->functions_name,
"(defined)",
usage_string,
f_list_ptr->is_referenced,
false,
kill_flag
);
}
}
}
else /* found = -1 ie not defined means */
{ /* a library function */
/* tab_to_left_margin( output );
/* (void)fprintf( output, "%s\n", nesting_display_buffer );
/* ++line;
/* top_of_form_done = false; */
draw_output_block( nesting_display_buffer,
f_list_ptr->functions_name,
library_string,
usage_string,
f_list_ptr->is_referenced,
false,
kill_flag
);
}
} /* end of loop on all called functions */
index = *index_ptr;
if( index )
while( index-- )
if( strcmp( function_name,
array_of_ptrs_to_records[ index ]->defined_function )
)
{
++index; /* exit at last matching defined function */
break;
}
do {
if(
( !is_static && !array_of_ptrs_to_records[ index ]->static_definition
) ||
( is_static &&
array_of_ptrs_to_records[ index ]->static_definition &&
!strcmp( array_of_ptrs_to_records[ index ]->
file_record_ptr->source_filename,
file_name
)
)
)
break;
}
while(
( ++index < count_of_functions ) &&
!strcmp( function_name,
array_of_ptrs_to_records[ index ]->defined_function
)
);
if(
( index >= count_of_functions ) ||
strcmp( function_name, array_of_ptrs_to_records[ index ]->defined_function
)
)
index = -1;
*index_ptr = index;
}
/***************************************************************************/
int near binary_search_sorted_data_base( key )
char *key;
{
int lo, hi, index;
int doesnt_match;
lo = 0;
hi = count_of_valid_records - 1;
index = ( hi - lo ) / 2;
while( true )
{
doesnt_match =
strcmp( key, array_of_ptrs_to_records[ index ]->defined_function );
if( !doesnt_match ) /* a match found at index */
break;
if( lo >= hi ) /* no match found */
{
index = -1;
break;
}
if( doesnt_match < 0 ) /* key < choice so go downwards */
hi = index - 1;
else /* key > choice so go upwards */
lo = index + 1;
index = ( hi + lo ) / 2; /* new choice */
}
return index;
}
/***************************************************************************/
[LISTING SIX]
[LISTING SEVEN]
cpheader.h
cp.c
cpbuild.c
cpfuncts.c
cpinput.c