Category : Files from Magazines
Archive   : DDJ-CSPC.ZIP
Filename : WINTER.LST

 
Output of file : WINTER.LST contained in archive : DDJ-CSPC.ZIP
_AN AID TO DOCUMENTING C REVISITED_
by Ron Winter

[LISTING ONE]

/*********************************************************************
cpheader.h
*********************************************************************/

#include
#include
#include
#include
#include

#define Max_unget_buffer 20000
#define Max_general_buffers 3000
#define MAX_functions 5000
/* #define Max_functions 4000 */
#define Max_defined_functions 1400
#define Max_files 1400
#define Max_Recursion 50

#define false 0
#define true 1
#define completed 2

#define Escape 0x1b
#define Control_z 0x1a

/*********************************************************************/
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;
/********************************/

char *recursion_array[ Max_Recursion ];
int recursion_depth = 0;

char nesting_display_buffer[ Max_general_buffers ];

char target[ 40 ] = "main";
FILE *output = NULL;

char push_buffer[ Max_unget_buffer ] = { 0, 0, 0, 0 };
char *push_buffer_ptr;

char file_comment_buffer[ Max_general_buffers ];
int first_comment;

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

static void near bump_line_count( void );
static void near do_top_of_page( void );
static void near deallocate_arrays( void );
static void near allocate_arrays( void );
static void near initialize_globals( void );
static void near build_records_from_list( FILE * );
static void near sort_the_data_base_array( void );
static void near count_all_defined_references( void );
static void near show_function_relationships( void );
static void near show_line_and_byte_counts( void );
static void near show_sorted_function_list( void );
static void near show_page_references( void );
static void near show_unused_if_any( );
static void near show_library_functions( void );
static void near show_files_leading_comments( );
int main( int, char ** );

***************************************************************************/

#define MAIN 1
#include "cpheader.h"
#include "time.h"

extern int near binary_search_sorted_data_base( char * );
extern void near build_box_parts( int );
extern int near build_the_data_base( char *, char * );
extern void near check_for_new_page( void );
extern int near doprint( int );
extern void near nasty( int );
extern void near process_arguments( int, int, char **, int );
extern void near scan_for_static_or_global( int *, int, char *, char * );
extern void near tab_to_left_margin( FILE * );

static void near allocate_arrays( void );
static void near build_records_from_list( FILE * );
static void near bump_line_count( void );
static void near count_all_defined_references( void );
static void near deallocate_arrays( void );
static void near do_top_of_page( void );
static void near initialize_globals( void );
static void near show_files_leading_comments( void );
static void near show_function_relationships( void );
static void near show_library_functions( void );
static void near show_line_and_byte_counts( void );
static void near show_page_references( void );
static void near show_sorted_function_list( void );
static void near show_unused_if_any( void );
static void near sort_the_data_base_array( void );
int main( int, char ** );

/***************************************************************************/

static void near bump_line_count( )
{
top_of_form_done = false;
++line;
check_for_new_page();
tab_to_left_margin( output );
}
/***************************************************************************/
static void near do_top_of_page( )
{
if( !top_of_form_done )
{
top_of_form_done = true;
line = 9999;
check_for_new_page();
tab_to_left_margin( output );
}
}
/***************************************************************************/
static void near deallocate_arrays( )
{
if( function_list )
free( function_list );

if( file_record_array )
free( file_record_array );
if( data_base_array )
free( data_base_array );
if( sorted_called_list_ptrs )
free( sorted_called_list_ptrs );
if( array_of_ptrs_to_records )
free( array_of_ptrs_to_records );
}
/***************************************************************************/

static void near allocate_arrays( )
{
unsigned long length;

length = (unsigned long)Max_functions * sizeof( function_type );
if( length > 65535 )
{
(void)printf( "too many called functions ( go to huge model code )\n" );
exit( 1 );
}
else
if(
!( function_list =
(function_type *)malloc( (unsigned int)length )
)
)
{
(void)printf( "No room for function_list\n" );
exit( 1 );
}
else
{
if( !g_quiet_flag && g_tech_flag )
(void)printf( "function list = %lu bytes long\n", length );
}

length = (unsigned long)Max_files * sizeof( file_record_type );
if( length > 65535 )
{
(void)printf( "too many files ( go to huge model code )\n" );
exit( 1 );
}
else
if(
!( file_record_array =
(file_record_type *)malloc( (unsigned int)length )
)
)
{
(void)printf( "No room for file_record_array\n" );
exit( 1 );
}
else
{
if( !g_quiet_flag && g_tech_flag )
(void)printf( "file record 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 ( 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 );
}

length = (unsigned long)Max_functions * sizeof( function_type * );
if( length > 65535 )
{
(void)printf(
"too many called function ptrs ( go to huge model code )\n"
);
exit( 1 );
}
else
if(
!( sorted_called_list_ptrs =
(function_type **)malloc( (unsigned int)length )
)
)
{
(void)printf( "No room for ptr function_list\n" );
exit( 1 );
}
else
{
if( !g_quiet_flag && g_tech_flag )
(void)printf( "sorted called list ptrs = %lu bytes long\n", length );
}
}
/***************************************************************************/

static void near initialize_globals( )
{
int i;
char *cp;

function_list_ptr = function_list;
data_base_array_ptr = data_base_array;
file_record_array_ptr = file_record_array;

for( i = 0; i < Max_Recursion; ++i )
recursion_array[ i ] = NULL;
build_box_parts( ibm_flag );
effective_width = /******** set global output width ***********/
defined_page_width - defined_left_margin - defined_right_margin;
if( effective_width < 40 )
{
(void)printf( "\nThe page width is too narrow( needs > 40 )." );
exit( 1 );
}

cp = &title[ 0 ]; /* insert date and nice time into title */
(void)_strdate( cp );
title[ 8 ] = ' ';
cp = &title[ 10 ];
(void)_strtime( cp );

title[ 15 ] = ' '; /* knock off seconds */
title[ 16 ] = ' '; /* put am, pm here */
title[ 17 ] = 'm';
title[ 18 ] = ' ';

i = atoi( &title[ 10 ] ); /* f/ military to civilian time */
title[ 16 ] = ( i < 12 )? (char)'a': (char)'p';

if( i == 0 )
i = 12;
if( i >= 13 )
i -= 12;

(void)sprintf( &title[ 10 ], "%2d", i );
title[ 12 ] = ':';

if( title[ 10 ] == '0' )
title[ 10 ] = ' ';
}
/***********************************************************************/
static void near build_records_from_list( stream )
FILE *stream;
{
char input_list_filename[ 129 ], input_line[ 129 ], overlay_number[ 129 ];
int l;

while( !feof( stream ) )
{
input_list_filename[ 0 ] = '\0';
input_line[ 0 ] = '\0';
overlay_number[ 0 ] = '\0';
fgets( input_line, 128, stream ); /* ends at \n or eof */

if(
( l = strlen( input_line ) ) > 1 /* ie not nul string */
)
{
if( input_line[ l - 1 ] == '\n' )
input_line[ l - 1 ] = '\0';

l = sscanf( input_line, " %s %s ",
input_list_filename, overlay_number
);
if( !g_quiet_flag && g_tech_flag )
{
(void)printf( "pathname = %s ", input_list_filename );
if( l )
(void)printf( "overlay # = %s ", overlay_number );
}
(void)build_the_data_base( input_list_filename, overlay_number );
}
}
}
/***************************************************************************/

static void near sort_the_data_base_array( )
{
int i, still_sorting_flag;

for( i = 0, data_base_array_ptr = data_base_array;
i < count_of_valid_records;
++i
)
array_of_ptrs_to_records[ i ] = data_base_array_ptr++;

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;
}
}
}
}
/************************************************************************/

static void near count_all_defined_references()
{
register int count;
int found;
register function_type *f_list_ptr;

f_list_ptr = function_list; /* the full list */

for( count = 0; count < count_of_functions; ++count )
{
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 )
array_of_ptrs_to_records[ found ]->number_of_references +=
f_list_ptr->is_referenced;
++f_list_ptr; /* for all defined functions */
}
if( !g_quiet_flag && g_dec_def_flag )
(void)printf( "\n" );
}
/***************************************************************************/

static void near show_function_relationships( )
{
int found;
int record_index;

found = binary_search_sorted_data_base( target );/* w/o knowing filename */
/* note if static, will find random one if more than */
/* one with same name */
if( found >= 0 )
{
recursion_depth = 0;
if( !g_quiet_flag )
{
(void)printf( "Checking for usage...\n" );
}
count_all_defined_references();
nesting_display_buffer[ 0 ] = '\0';
if( !g_quiet_flag )
{
(void)printf( "Starting the printout...\n" );
}
if( !target_flag ) /* main is only called once */
array_of_ptrs_to_records[ found ]->number_of_references = 1;
line = 0;
if( !stats_only )
{
(void)doprint( found ); /* of target function */
for( record_index = 0;
record_index < count_of_valid_records;
++record_index
)
{
(void)fprintf( output, "\n" );
++line;
if( array_of_ptrs_to_records[ record_index ]->number_of_references >
1
)
(void)doprint( record_index );
}
}
}
else /* cant find target */
{
(void)printf( "cant find %s, exitting\n", target );
exit( 1 );
}
}
/***************************************************************************/

static void near show_line_and_byte_counts( )
{
long int total_byte_count;
long int total_line_count;
int i;

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 )
);
}
/***************************************************************************/

static void near show_sorted_function_list( )
{
int i, record_index;
long reference_total = 0;

do_top_of_page();

(void)fprintf( output, "Function index:\n" );
bump_line_count();

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( i = 0; i < effective_width; ++i )
(void)fputc( '_', output );
(void)fprintf( output, "\n" );
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();
}
/***************************************************************************/

static void near show_page_references( )
{
int pmax; /* max x ref columns */
int i, pcnt;
linked_pages_list *p;

if( !stats_only && ( defined_page_length > 0 ) )
{
pmax = (int)( effective_width - 7 - 32 - 2 ) / 5;
do_top_of_page();
(void)fprintf( output, "Function cross reference:\n" );
bump_line_count();

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 > 0 )
{
(void)fprintf( output, "%-7s%-32s- ",
( data_base_array_ptr->static_definition )?
"static": "",
data_base_array_ptr->defined_function );
p = data_base_array_ptr->ptr_to_page_list;
if( p )
{
pcnt = 0;
while( p->next_page_ptr )
{
(void)fprintf( output, "%4d,", p->on_this_page );
p = p->next_page_ptr;
++pcnt;
if( pcnt >= pmax )
{
(void)fputc( '\n', output );
bump_line_count();
(void)fprintf( output, "%7s%32s ", " ", " " );
pcnt = 0;
}
}
(void)fprintf( output, "%4d\n", p->on_this_page );
}
else
(void)fprintf( output, "\n" );
bump_line_count();
}
}
}
}
/***************************************************************************/

static void near show_unused_if_any( )
{
int i, unused_count, unused_index, count, still_sorting_flag;
data_base_record_type **unused_list_ptr_ptr, *unused_list_ptr;

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();
}
}
/************************************************************************/

static void near show_library_functions( )
{
register int count;
int found, total, still_sorting_flag, x_count, final_count, final_call;
function_type **f_list_ptr_ptr, *f_list_ptr;

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 */
}

if( !g_quiet_flag && g_tech_flag )
(void)printf( "gathering identical library functions...\n" );
final_count = total; /* number of calls to be collected and sorted */
f_list_ptr_ptr = sorted_called_list_ptrs;
for( count = 0; count < ( total - 1 ); ++count )
{
for( x_count = count + 1; x_count < total; ++x_count )
{
if( ( f_list_ptr_ptr[ count ]->functions_name[ 0 ] != '\0' ) &&
!strcmp( f_list_ptr_ptr[ count ]->functions_name,
f_list_ptr_ptr[ x_count ]->functions_name )
)
{
f_list_ptr_ptr[ count ]->is_referenced +=
f_list_ptr_ptr[ x_count ]->is_referenced;
f_list_ptr_ptr[ x_count ]->functions_name[ 0 ] = '\0';
--final_count;
}
}
}

if( !g_quiet_flag && g_tech_flag )
{
(void)printf( "\nSorting the library function calls...\n" );
}

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" );

(void)fprintf( output, "%-32s %-28s\n",
"library function", "calls" );
bump_line_count();

for( count = 0; count < effective_width; ++count )
(void)fputc( '_', output );
(void)fprintf( output, "\n" );
bump_line_count();

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();
}
}
/************************************************************************/

static void near show_files_leading_comments( )
{
int i;
char *cp;

if( g_comment_flag )
{
do_top_of_page();
(void)fprintf( output, "File comments:\n" );
bump_line_count();
file_record_array_ptr = file_record_array;
for( i = 0; i < count_of_source_files; ++i )
{
(void)fprintf( output, "%40s\n",
file_record_array_ptr->source_filename
);
bump_line_count();
cp = file_record_array_ptr->source_file_comment;
while( *cp )
{
(void)fprintf( output, "%c", *cp );
if( *++cp == '\n' )
{
bump_line_count();
}
}
++file_record_array_ptr;
do_top_of_page(); /* one page per comment at least */
}
}
}
/**********************************************************************/

int main( argc, argv )
char **argv;
int argc;
{
int index, in_error = false, out_error = false;
FILE *stream;

nasty( argc );

(void)printf( "\ncp - ver. 1.3, (C)1987, 1988 Stewart A. Nutter\n" );
(void)printf( " extended and corrected by Ron Winter\n" );

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( );

/************* done *****************/
(void)fprintf( output, "%c", 0x0c ); /* ff */

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 near nasty( int );
void near process_arguments( int, int, char **, int );
/************************************************************************/

void near nasty( argc )
int argc;
{
if( argc < 2 )
{
(void)printf( "\ncp listfile [ outfile ] [\n" );
(void)printf(
" /p:nn /w:nn /m:nn /r:nn /t:main /f:nnnn\n"
);
(void)printf(
" /l /n /s /q /d /c /h /x\n"
);
(void)printf( " ]\n\n" );
(void)printf(
" outfile = prn\n" );
(void)printf(
" p: page length = %3d [ 0, 50 -255 ]\n", defined_page_length
);
(void)printf(
" w: page width = %3d [ 80 - 255 ]\n", defined_page_width
);
(void)printf(
" m: left margin = %2d [ 0 - 30 ]\n", defined_left_margin
);
(void)printf(
" r: right margin = %2d [ 0 - 30 ]\n", defined_right_margin
);
(void)printf(
" t: target function = %s\n", target
);
(void)printf(
" f: # of function calls = %4d [ 2 - 5461 ]\n", MAX_functions
);
(void)printf(
" n: normal characters( ie not ibm character graphics )\n"
);
(void)printf(
" l output library functions\n"
);
(void)printf(
" c output file\'s 1st comment\n"
);
(void)printf(
" s output statistics only\n"
);
(void)printf(
" d show declarations and definitions\n"
);
(void)printf(
" o show overlay information\n"
);
(void)printf(
" u show unused sorted by filename\n"
);
(void)printf(
" q show no messages\n"
);
(void)printf(
" h show more help\n"
);
(void)printf(
" x show tech info\n"
);

(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;

for( i = index; i < argc; ++i )
{
if( ( argv[ i ][ 0 ] == '/' ) || ( argv[ i ][ 0 ] == '-' ) )
{
c = (char)tolower( (int)argv[ i ][ 1 ] );
switch( c )
{
case 'n':
ibm_flag = ( ibm_flag )? false: true;
break;
case 'l':
g_lib_flag = ( g_lib_flag )? false: true;
break;
case 'c':
g_comment_flag = ( g_comment_flag )? false: true;
break;
case 'd':
g_dec_def_flag = ( g_dec_def_flag )? false: true;
break;
case 's':
stats_only = ( stats_only )? false: true;
break;
case 'q':
g_quiet_flag = ( g_quiet_flag )? false: true;
break;
case 'o':
g_ov_flag = true;
break;
case 'u':
g_un_flag = true;
break;
case 'h':
g_help_flag = true;
break;
case 'x':
g_tech_flag = true;
break;
default:
if( ( strlen( argv[ i ] ) > 3 ) && ( argv[ i ][ 2 ] == ':' ) )
{
tmp = atoi( &argv[ i ][ 3 ] );
switch( c )
{
case 'p':
if( ( ( 50 < tmp ) && ( tmp < 256 ) ) || ( tmp == 0 ) )
defined_page_length = tmp;
break;
case 'm':
if( ( 0 <= tmp ) && ( tmp <= 30 ) )
defined_left_margin = tmp;
break;
case 'r':
if( ( 0 <= tmp ) && ( tmp <= 30 ) )
defined_right_margin = tmp;
break;
case 't':
(void)strcpy( target, &argv[ i ][ 3 ] );
target_flag = true;
break;
case 'w':
if( ( 79 < tmp ) && ( tmp < 256 ) )
defined_page_width = tmp;
break;
case 'f':
if( ( 1 < tmp ) && ( tmp < 5462 ) )
Max_functions = tmp;
break;
default:
(void)printf(
"\nUnknown argument character: %c, ignored!\n",
argv[ i ][ 1 ]
);
break;
} /* end of switch on character after / or - */
} /* end of if :something */
else
(void)printf( "\nMissing : for argument %s, ignored!\n",
argv[ i ] );
break;
} /* end of switch on character after / or - */
} /* end of if / or - */
else
(void)printf( "\nUnknown argument: %s, ignored!\n", argv[ i ] );
} /* end of for loop on arguments */

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"

int near build_the_data_base( char * );
static char near get_chars( FILE * );
static char near get_to_next_possible_token( FILE * );
static int near is_legal_identifier_character( char );
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 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;

for( i = 0; i < count; ++i )
{
if(
!strcmp( name_of_static_function, ptr_to_function_list->functions_name )
)
ptr_to_function_list->static_function = true;
++ptr_to_function_list;
}
}
/***************************************************************************/
#define KEYS 7

static int near test_and_add( ptr_to_function_list, string, count )
function_type *ptr_to_function_list;
char *string;
int count;
{
int i, is_a_new_function_name;
static char *keywords[ KEYS ] =
{ /* must catch do (void)printf, while(), else (void)... etc. ***/
"do", "while", "if", "else", "for", "switch", "return"
};

for( i = 0; ( i < KEYS ) && ( strcmp( string, keywords[ i ] ) != 0 ); ++i )
;
if( i < KEYS )
is_a_new_function_name = false; /* ie a reserved word match */
else /* is a function name */
{
for( i = 0; i < count; ++i )
{
if( !strcmp( string, ptr_to_function_list->functions_name ) )
{ /* function name matches */
if( !ptr_to_function_list->static_function )
break; /* and isn't static */
else
{
if( !strcmp( ptr_to_function_list->its_filename,
file_record_array_ptr->source_filename
)
)
break; /* only statics in same file match */
}
}
++ptr_to_function_list;
}
if( i == count )
{ /* new function name */
is_a_new_function_name = true; /* add function name to list */
if( ( function_list_ptr->functions_name = strdup( string ) ) == NULL )
{
(void)fprintf( stderr, "Ran out of memory.\n" );
exit( 1 );
}
function_list_ptr->static_function = false;
function_list_ptr->its_filename =
file_record_array_ptr->source_filename;
function_list_ptr->is_referenced = 1;

++function_list_ptr; /* point to next empty cell */
++count_of_functions; /* increase current size */
if( count_of_functions > Max_functions )
{
(void)fprintf( stderr, "Too many functions.\n" );
exit( 1 );
}
}
else /* string already in function list */
{
is_a_new_function_name = false;
ptr_to_function_list->is_referenced++;
}
}
return is_a_new_function_name;
}
/***************************************************************************/
static void near unget_chars( c )
char c;
{
if( ( push_buffer_ptr - push_buffer ) < Max_unget_buffer )
*push_buffer_ptr++ = c;
else
{
(void)fprintf( stderr, "\nProgram syntax error:" );
(void)fprintf( stderr, " Too many pushed characters.\n" );
exit( 1 );
}
}
/***************************************************************************/
static char near get_chars( stream )
FILE * stream;
{
register char c;

if( push_buffer_ptr != push_buffer )
c = *--push_buffer_ptr;
else
{
c = (char)fgetc( stream );
if( c == EOF )
c = Control_z;
if( c == 0x0a )
{
file_record_array_ptr->line_count++;
file_record_array_ptr->size++; /* count the unseen */
}
file_record_array_ptr->size++;
}
return c;
}
/***************************************************************************/
static char near get_to_next_possible_token( stream )
FILE *stream;
{
register char
c;
char
next_char_peek;
int
done;

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

int near build_the_data_base( the_filename )
char * the_filename;
{
static char fake_comment[ ] = "no room!";
int found_a_possible_function;
int brace_count, body_found;
int open_parenthesis, parenthesis_count;
int at_end_of_source_file;
int dummy_index, total_called_count;
int function_definition_flag, static_flag;
int analyze_buffer_flag = false;
char c;
char *function_name_buffer_ptr;
char function_name_buffer[ C_identifier_length ];
char look_ahead_buffer[ C_line_length + 1 ];
FILE *stream;
data_base_record_type *data_base_ptr, *starting_data_base_ptr;
function_type *starting_called_function_ptr;

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;
}

push_buffer_ptr = push_buffer; /* reset input character stack */
/* add file name to data base */
if( !( file_record_array_ptr->source_filename = strdup( the_filename ) ) )
{
(void)printf( "Ran out of memory.\n" );
exit( 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';

file_record_array_ptr->line_count = 0; /* clear it's variables */
file_record_array_ptr->size = 0l;

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;

data_base_ptr = data_base_array_ptr; /* save current pointer */
++data_base_array_ptr; /* next entry */
++count_of_valid_records;
if( count_of_valid_records > Max_defined_functions )
{
(void)printf( "\nToo many new functions\n" );
exit( 1 );
}
} /* end of function definition */
static_flag = false;
}
else /* brace_count is not zero */
{ /* so inside a function */
data_base_ptr->number_of_function_calls +=
test_and_add( data_base_ptr->ptr_to_function_table,
function_name_buffer,
data_base_ptr->number_of_function_calls
);
}
look_ahead_buffer[ 0 ] = '\0'; /* reset tail buffer */
static_flag = false;
} /* end of parenthesis */
function_name_buffer_ptr = function_name_buffer; /* reset buffer */
*function_name_buffer_ptr = '\0';
} /* end of found_a_possible_function */
} /* end of while !at_end_of_source_file */
(void)fclose( stream );
if( !g_quiet_flag )
{
(void)printf( "\n" );
}

if(
!( file_record_array_ptr->source_file_comment =
strdup( file_comment_buffer )
)
)
file_record_array_ptr->source_file_comment = fake_comment;

/***** mark called functions in list as static if in defined list *******/
total_called_count = 0;
data_base_ptr = starting_data_base_ptr;
while( data_base_ptr != data_base_array_ptr )
{
total_called_count += data_base_ptr->number_of_function_calls;
++data_base_ptr;
}
data_base_ptr = starting_data_base_ptr;
while( data_base_ptr < data_base_array_ptr )
{
if( data_base_ptr->static_definition )
mark_as_static( starting_called_function_ptr,
data_base_ptr->defined_function,
total_called_count
);
++data_base_ptr;
}
++file_record_array_ptr; /* next file name entry */
++count_of_source_files;
if( count_of_source_files >= Max_files )
{
(void)printf( "\nError: too many files to process.\n" );
exit( 1 );
}
return at_end_of_source_file;
}
/***************************************************************************/


[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;

static char *recursion_filename, *test_filename;
static int static_recursion;

int near binary_search_sorted_data_base( char * );
void near build_box_parts( int );
void near check_for_new_page( void );
int near doprint( int );
void near scan_for_static_or_global( int *, int, char *, char * );
void near tab_to_left_margin( FILE * );

static void near draw_output_block( char *, char *, char *,
char *, int, int, int );
static int near recursion_check( char *, int );
static void near stop( void );
static void near setpage( data_base_record_type * );

/***************************************************************************/
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;

for( i = 0; i < defined_left_margin; ++i )
(void)fputc( ' ', output );
}
/***************************************************************************/
static void near stop()
{
(void)printf( "hello" );
}
/***************************************************************************/
static void near setpage( data_base_ptr )
data_base_record_type *data_base_ptr;
{
linked_pages_list *page_list_ptr;

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;

if( defined_page_length == 0 && line == 9999 )
{
(void)fprintf( output, "\n\n\n\n" );
line = 0;
}
else
{
if( defined_page_length != 0 )
{
if( line > ( defined_page_length - 5 ) )
{
(void)fprintf( output, "\f" );
line = 0;
}
if( line == 0 )
{
top_of_form_done = true;
tab_to_left_margin( output );
(void)fprintf( output, "%s", title );
for( i = strlen( title ); i < ( effective_width - 10 ); ++i )
(void)fputc( ' ', output );
(void)fprintf( output, "Page:%4d\n", page );
tab_to_left_margin( output );
for( i = 0; i < effective_width; ++i )
(void)fputc( '_', output );
(void)fprintf( output, "\n\n" );
line = 3;
++page;
}
}
}
}
/***************************************************************************/
static void near draw_output_block( lead_in_string,
name_of_function,
description,
name_of_file,
either_count,
tail_flag,
kill_flag
)
char *lead_in_string,
*name_of_function,
*description,
*name_of_file;
int either_count, tail_flag, kill_flag;
{
unsigned int string_length;
static char alternate_lead_in[ 140 ];

/******* 1st line ***********************************************************/
tab_to_left_margin( output );
(void)fprintf( output, "%s %s\n", lead_in_string, top_line_of_box );

/******* 2nd line ***********************************************************/
tab_to_left_margin( output );
string_length = strlen( lead_in_string );
if( string_length ) /******* ie not main or defined function box ***/
{
(void)strncpy( alternate_lead_in, lead_in_string, --string_length );
alternate_lead_in[ string_length++ ] = '\0'; /* restore string_length */
}
if( string_length ) /******* ie not main or defined function box ***/
(void)fprintf( output, "%s%c%c%c%-33s %c\n",
alternate_lead_in,
/*** if( kill_flag ) /****** last line to this box ******************/
/*** else /****** line continues downwards ***************/
( kill_flag )? lower_left_corner: right_attach,
ibm_line, left_attach, name_of_function, wall );
else /****** main or defined box starting ***********/
(void)fprintf( output, "%c%c%-33s %c\n",
ibm_line, left_attach, name_of_function, wall );

/******* 3rd line ***********************************************************/
tab_to_left_margin( output );
if( string_length-- ) /***** kill outside vertical line on last box ****/
lead_in_string[ string_length++ ] = ( kill_flag )? (char)' ': wall;
(void)fprintf( output, "%s %c%-20s %8s%3d %c\n",
lead_in_string, wall, description,
name_of_file, either_count, wall );

/******* 4th line ***********************************************************/
tab_to_left_margin( output );
bottom_line_of_box[ 2 ] = /******** if defined box has calls ***********/
( tail_flag && either_count )? bottom_attach: ibm_line;
(void)fprintf( output, "%s %s\n", lead_in_string, bottom_line_of_box );

line += 4;
top_of_form_done = false;
}
/***************************************************************************/
static char library_string[] = { "(library)" };
static char usage_string[] = { "Used=" };
static char funct_string[] = { "Functs=" };

int near doprint( index )
int index;
{
int
loop_counter,
max_count,
starting_index,
found,
return_value;
data_base_record_type *record_ptr;
function_type *f_list_ptr;

static int kill_flag = false;

starting_index = index;
record_ptr = array_of_ptrs_to_records[ starting_index ];

recursion_array[ recursion_depth ] = record_ptr->defined_function;
if( !recursion_depth )
{
recursion_filename = record_ptr->file_record_ptr->source_filename;
/* add function to list for recursion check */
static_recursion = record_ptr->static_definition;
}
check_for_new_page();
setpage( array_of_ptrs_to_records[ starting_index ] );

return_value = page - 1; /* must be a relic! */
/* start w/ target function */
draw_output_block( nesting_display_buffer,
record_ptr->defined_function,
( record_ptr->file_record_ptr )->source_filename,
funct_string,
record_ptr->number_of_function_calls,
true,
kill_flag
);

++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 */

/* remove function f/ recursion list */
recursion_array[ recursion_depth ] = NULL;
/**** mystic width = 4 *****/
nesting_display_buffer[ strlen( nesting_display_buffer ) - 4 ] = '\0';
--recursion_depth;
return return_value;
}
/***************************************************************************/
void near scan_for_static_or_global(
index_ptr, is_static, function_name, file_name
)
int *index_ptr, is_static;
char *function_name, *file_name;
{
int index;

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]

cp.obj : cp.c cpheader.h cp
cl -AL -c cp.c

cpinput.obj : cpinput.c cpheader.h cp
cl -AL -c cpinput.c

cpfuncts.obj : cpfuncts.c cpheader.h cp
cl -AL -c cpfuncts.c

cpbuild.obj: cpbuild.c cpheader.h cp
cl -AL cpbuild.c -c

cp.exe : cp.obj cpinput.obj cpfuncts.obj cpbuild.obj cp
link cp+ cpinput+ cpbuild+ cpfuncts/packcode/st:16000,,cp;



[LISTING SEVEN]

cpheader.h
cp.c
cpbuild.c
cpfuncts.c
cpinput.c




  3 Responses to “Category : Files from Magazines
Archive   : DDJ-CSPC.ZIP
Filename : WINTER.LST

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/