home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / c_spec / poole_cp / cp.c next >
Text File  |  1989-11-21  |  29KB  |  1,062 lines

  1. /*********************************************************************
  2.                      cp.c
  3.   
  4. static void near bump_line_count( void );
  5. static void near do_top_of_page( void );
  6. static void near deallocate_arrays( void );
  7. static void near allocate_arrays( void );
  8. static void near initialize_globals( void );
  9. static void near build_records_from_list( FILE * );
  10. static void near sort_the_data_base_array( void );
  11. static void near count_all_defined_references( void );
  12. static void near show_function_relationships( void );
  13. static void near show_line_and_byte_counts( void );
  14. static void near show_sorted_function_list( void );
  15. static void near show_page_references( void );
  16. static void near show_unused_if_any( );
  17. static void near show_library_functions( void );
  18. static void near show_files_leading_comments( );
  19.        int     main( int, char ** );
  20.  
  21.  ***************************************************************************/
  22.  
  23. #define  MAIN  1
  24. #include "cpheader.h"
  25. #if MSDOS
  26. #include "time.h"
  27. #else
  28. #include <time.h>
  29. #endif
  30.  
  31. #if VMS
  32. extern int  binary_search_sorted_data_base( char * );
  33. extern void build_box_parts( int );
  34. extern int  build_the_data_base( char *, char * );
  35. extern void check_for_new_page( void );
  36. extern int  doprint( int );
  37. extern void nasty( int );
  38. extern void process_arguments( int, int, char **, int );
  39. extern void scan_for_static_or_global( int *, int, char *, char * );
  40. extern void tab_to_left_margin( FILE * );
  41.  
  42. static void allocate_arrays( void );
  43. static void build_records_from_list( FILE * );
  44. static void bump_line_count( void );
  45. static void count_all_defined_references( void );
  46. static void deallocate_arrays( void );
  47. static void do_top_of_page( void );
  48. static void initialize_globals( void );
  49. static void show_files_leading_comments( void );
  50. static void show_function_relationships( void );
  51. static void show_library_functions( void );
  52. static void show_line_and_byte_counts( void );
  53. static void show_page_references( void );
  54. static void show_sorted_function_list( void );
  55. static void show_unused_if_any( void );
  56. static void sort_the_data_base_array( void );
  57. static char* strdup( char * );
  58. static void timedate( char * );
  59.        int     main( int, char ** );
  60. #endif
  61.  
  62. #if MSDOS
  63. extern int  near binary_search_sorted_data_base( char * );
  64. extern void near build_box_parts( int );
  65. extern int  near build_the_data_base( char *, char * );
  66. extern void near check_for_new_page( void );
  67. extern int  near doprint( int );
  68. extern void near nasty( int );
  69. extern void near process_arguments( int, int, char **, int );
  70. extern void near scan_for_static_or_global( int *, int, char *, char * );
  71. extern void near tab_to_left_margin( FILE * );
  72.  
  73. static void near allocate_arrays( void );
  74. static void near build_records_from_list( FILE * );
  75. static void near bump_line_count( void );
  76. static void near count_all_defined_references( void );
  77. static void near deallocate_arrays( void );
  78. static void near do_top_of_page( void );
  79. static void near initialize_globals( void );
  80. static void near show_files_leading_comments( void );
  81. static void near show_function_relationships( void );
  82. static void near show_library_functions( void );
  83. static void near show_line_and_byte_counts( void );
  84. static void near show_page_references( void );
  85. static void near show_sorted_function_list( void );
  86. static void near show_unused_if_any( void );
  87. static void near sort_the_data_base_array( void );
  88. static char* near strdup( char * );
  89. static void near timedate( char * );
  90.        int     main( int, char ** );
  91. #endif
  92.  
  93. /***************************************************************************/
  94.  
  95. #if MSDOS
  96. static void near bump_line_count( )
  97. #else
  98. static void bump_line_count( )
  99. #endif
  100. {
  101. top_of_form_done = false;
  102. ++line;
  103. check_for_new_page();
  104. tab_to_left_margin( output );
  105. }
  106. /***************************************************************************/
  107. #if MSDOS
  108. static void near do_top_of_page( )
  109. #else
  110. static void do_top_of_page( )
  111. #endif
  112. {
  113. if( !top_of_form_done )
  114.    {
  115.    top_of_form_done = true;
  116.    line = 9999;
  117.    check_for_new_page();
  118.    tab_to_left_margin( output );
  119.    }
  120. }
  121. /***************************************************************************/
  122. #if MSDOS
  123. static void near deallocate_arrays( )
  124. #else
  125. static void deallocate_arrays( )
  126. #endif
  127. {
  128. if( function_list )
  129.    free( function_list );
  130. if( file_record_array )
  131.    free( file_record_array );
  132. if( data_base_array )
  133.    free( data_base_array );
  134. if( sorted_called_list_ptrs )
  135.    free( sorted_called_list_ptrs );
  136. if( array_of_ptrs_to_records )
  137.    free( array_of_ptrs_to_records );
  138. }
  139. /***************************************************************************/
  140.  
  141. #if MSDOS
  142. static void near allocate_arrays( )
  143. #else
  144. static void allocate_arrays( )
  145. #endif
  146. {
  147. unsigned long length;
  148.  
  149. length = (unsigned long)Max_functions * sizeof( function_type );
  150. if( (length > 65535) && MSDOS )
  151.    {
  152.    (void)printf( "too many called functions ( go to huge model code )\n" );
  153.    exit( 1 );
  154.    }
  155. else
  156.    if(
  157.       !( function_list =
  158.      (function_type *)malloc( (unsigned int)length )
  159.        )
  160.      )
  161.       {
  162.       (void)printf( "No room for function_list\n" );
  163.       exit( 1 );
  164.       }
  165.    else
  166.       {
  167.       if( !g_quiet_flag && g_tech_flag )
  168.      (void)printf( "function list = %lu bytes long\n", length );
  169.       }
  170.  
  171. length = (unsigned long)Max_files * sizeof( file_record_type );
  172. if( (length > 65535) && MSDOS )
  173.    {
  174.    (void)printf( "too many files ( go to huge model code )\n" );
  175.    exit( 1 );
  176.    }
  177. else
  178.    if(
  179.       !( file_record_array =
  180.      (file_record_type *)malloc( (unsigned int)length )
  181.        )
  182.      )
  183.       {
  184.       (void)printf( "No room for file_record_array\n" );
  185.       exit( 1 );
  186.       }
  187.    else
  188.       {
  189.       if( !g_quiet_flag && g_tech_flag )
  190.      (void)printf( "file record array = %lu bytes long\n", length );
  191.       }
  192.  
  193. length =
  194.    (unsigned long)Max_defined_functions * sizeof( data_base_record_type );
  195. if( (length > 65535) && MSDOS )
  196.    {
  197.    (void)printf( "too many defined functions ( go to huge model code )\n" );
  198.    exit( 1 );
  199.    }
  200. else
  201.    if(
  202.       !( data_base_array =
  203.      (data_base_record_type *)malloc( (unsigned int)length )
  204.        )
  205.      )
  206.       {
  207.       (void)printf( "No room for data_base_array\n" );
  208.       exit( 1 );
  209.       }
  210.    else
  211.       {
  212.       if( !g_quiet_flag && g_tech_flag )
  213.      (void)printf( "data base array = %lu bytes long\n", length );
  214.       }
  215.  
  216. length =
  217.    (unsigned long)Max_defined_functions * sizeof( data_base_record_type * );
  218. if( (length > 65535) && MSDOS )
  219.    {
  220.    (void)printf(
  221.         "too many defined functions pointers( go to huge model code )\n"
  222.            );
  223.    exit( 1 );
  224.    }
  225. else
  226.    if(
  227.       !( array_of_ptrs_to_records =
  228.      (data_base_record_type **)malloc( (unsigned int)length )
  229.        )
  230.      )
  231.       {
  232.       (void)printf( "No room for *array_of_ptrs_to_records\n" );
  233.       exit( 1 );
  234.       }
  235.    else
  236.       {
  237.       if( !g_quiet_flag && g_tech_flag )
  238.      (void)printf( "array of ptrs to data base = %lu bytes long\n",
  239.             length );
  240.       }
  241.  
  242. length = (unsigned long)Max_functions * sizeof( function_type * );
  243. if( (length > 65535) && MSDOS )
  244.    {
  245.    (void)printf(
  246.       "too many called function ptrs ( go to huge model code )\n"
  247.            );
  248.    exit( 1 );
  249.    }
  250. else
  251.    if(
  252.       !( sorted_called_list_ptrs =
  253.         (function_type **)malloc( (unsigned int)length )
  254.        )
  255.      )
  256.       {
  257.       (void)printf( "No room for ptr function_list\n" );
  258.       exit( 1 );
  259.       }
  260.    else
  261.       {
  262.       if( !g_quiet_flag && g_tech_flag )
  263.      (void)printf( "sorted called list ptrs = %lu bytes long\n", length );
  264.       }
  265. }
  266. /***************************************************************************/
  267.  
  268. #if !MSDOS
  269. static void timedate(ret_time)
  270. char *ret_time;
  271. {
  272.   struct tm *time_structure;
  273.   int time_val, i;
  274.   static char *hour[2] = {"am","pm"};
  275.   char temp[19];
  276.  
  277.   time(&time_val);   
  278.   time_structure = localtime(&time_val); 
  279.  
  280.   i = 0;              
  281.   if((time_structure->tm_hour >= 12)&&(time_structure->tm_hour<24)) i=1;
  282.  
  283.   if(time_structure->tm_hour > 12)
  284.       time_structure->tm_hour = (time_structure->tm_hour)-12;
  285.   sprintf(temp,"%d/%d/%d  %d:%02d %s",
  286.                  time_structure->tm_mon,
  287.                  time_structure->tm_mday,    
  288.                  time_structure->tm_year,
  289.                  time_structure->tm_hour,
  290.                  time_structure->tm_min,
  291.                  hour[i]);
  292.   i=0;
  293.   while(temp[i]!='\0')
  294.   {
  295.      ret_time[i] = temp[i];
  296.      i++;
  297.   }
  298. }
  299. #endif
  300.  
  301. #if MSDOS
  302. static void near timedate(ret_time)
  303. char *ret_time;
  304. {
  305.   char *cp;
  306.   int i;
  307.  
  308.   cp = &ret_time[ 0 ];      /* insert date and nice time into ret_time */
  309.   (void)_strdate( cp );
  310.   ret_time[ 8 ] = ' ';
  311.   cp = &ret_time[ 10 ];
  312.   (void)_strtime( cp );
  313.  
  314.   ret_time[ 15 ] = ' ';   /* knock off seconds */
  315.   ret_time[ 16 ] = ' ';   /* put am, pm here */
  316.   ret_time[ 17 ] = 'm';
  317.   ret_time[ 18 ] = ' ';
  318.  
  319.   i = atoi( &ret_time[ 10 ] );    /* f/ military to civilian time */
  320.   ret_time[ 16 ] = ( i < 12 )? (char)'a': (char)'p';
  321.  
  322.   if( i == 0 )
  323.      i = 12;
  324.   if( i >= 13 )
  325.      i -= 12;
  326.  
  327.   (void)sprintf( &ret_time[ 10 ], "%2d", i );
  328.   ret_time[ 12 ] = ':';
  329.  
  330.   if( ret_time[ 10 ] == '0' )
  331.      ret_time[ 10 ] = ' ';
  332. }
  333. #endif
  334. /***************************************************************************/
  335.  
  336. #if MSDOS
  337. static void near initialize_globals( )
  338. #else
  339. static void initialize_globals( )
  340. #endif
  341. {
  342. int i;
  343. char *cp;
  344.  
  345. function_list_ptr = function_list;
  346. data_base_array_ptr = data_base_array;
  347. file_record_array_ptr = file_record_array;
  348.  
  349. for( i = 0; i < Max_Recursion; ++i )
  350.    recursion_array[ i ] = NULL;
  351. build_box_parts( ibm_flag );
  352. effective_width =          /******** set global output width ***********/
  353.    defined_page_width - defined_left_margin - defined_right_margin;
  354. if( effective_width < 40 )
  355.    {
  356.    (void)printf( "\nThe page width is too narrow( needs > 40 )." );
  357.    exit( 1 );
  358.    }
  359.    timedate(title);
  360. }
  361. /***********************************************************************/
  362. #if MSDOS
  363. static void near build_records_from_list( stream )
  364. #else
  365. static void build_records_from_list( stream )
  366. #endif
  367. FILE  *stream;
  368. {
  369. char input_list_filename[ LEN_INFILE ], input_line[ LEN_INFILE ];
  370. char overlay_number[ LEN_INFILE ];
  371. int l;
  372.  
  373. while( !feof( stream ) )
  374.    {
  375.    input_list_filename[ 0 ] = '\0';
  376.    input_line[ 0 ] = '\0';
  377.    overlay_number[ 0 ] = '\0';
  378.    fgets( input_line, LEN_INFILE-1, stream );    /* ends at \n or eof */
  379.  
  380.    if(
  381.       ( l = strlen( input_line ) ) > 1      /* ie not nul string */
  382.      )
  383.       {
  384.       if( input_line[ l - 1 ] == '\n' )
  385.      input_line[ l - 1 ] = '\0';
  386.  
  387.       l = sscanf( input_line, " %s %s ",
  388.           input_list_filename, overlay_number
  389.         );
  390.       if( !g_quiet_flag && g_tech_flag )
  391.      {
  392.      (void)printf( "pathname = %s ", input_list_filename );
  393.      if( l )
  394.         (void)printf( "overlay # = %s ", overlay_number );
  395.      }
  396.       (void)build_the_data_base( input_list_filename, overlay_number );
  397.       }
  398.    }
  399. }
  400. /***************************************************************************/
  401.  
  402. #if MSDOS
  403. static void near sort_the_data_base_array( )
  404. #else
  405. static void sort_the_data_base_array( )
  406. #endif
  407. {
  408. int i, still_sorting_flag;
  409.  
  410. for( i = 0, data_base_array_ptr = data_base_array;
  411.      i < count_of_valid_records;
  412.      ++i
  413.    )
  414.    array_of_ptrs_to_records[ i ] = data_base_array_ptr++;
  415.  
  416. if( !g_quiet_flag )
  417.    {
  418.    (void)printf( "\n\nSorting the function list...\n" );
  419.    (void)printf( " of %d functions\n", count_of_valid_records );
  420.    }
  421. still_sorting_flag = true;
  422. while( still_sorting_flag )
  423.    {
  424.    still_sorting_flag = false;
  425.    if( !g_quiet_flag )
  426.       {
  427.       (void)printf( "." );
  428.       }
  429.    for( i = 0; i < count_of_valid_records - 1; ++i )
  430.       {
  431.       if( strcmp( array_of_ptrs_to_records[ i ]->defined_function,
  432.           array_of_ptrs_to_records[ i + 1 ]->defined_function ) > 0 )
  433.      {
  434.      still_sorting_flag = true;
  435.      data_base_array_ptr = array_of_ptrs_to_records[ i ];
  436.      array_of_ptrs_to_records[ i ] = array_of_ptrs_to_records[ i + 1 ];
  437.      array_of_ptrs_to_records[ i + 1 ] = data_base_array_ptr;
  438.      }
  439.       }
  440.    }
  441. }
  442. /************************************************************************/
  443.  
  444. #if MSDOS
  445. static void near count_all_defined_references()
  446. #else
  447. static void count_all_defined_references()
  448. #endif
  449. {
  450. register int count;
  451. int found;
  452. register function_type *f_list_ptr;
  453.  
  454. f_list_ptr = function_list;        /* the full list */
  455.  
  456. for( count = 0; count < count_of_functions; ++count )
  457.    {
  458.    found = binary_search_sorted_data_base( f_list_ptr->functions_name );
  459.    if( found >= 0 )
  460.       scan_for_static_or_global( &found,
  461.                  f_list_ptr->static_function,
  462.                  f_list_ptr->functions_name,
  463.                  f_list_ptr->its_filename
  464.                    );
  465.    if( found >= 0 )
  466.       array_of_ptrs_to_records[ found ]->number_of_references +=
  467.      f_list_ptr->is_referenced;
  468.    ++f_list_ptr;    /* for all defined functions */
  469.    }
  470. if( !g_quiet_flag && g_dec_def_flag )
  471.    (void)printf( "\n" );
  472. }
  473. /***************************************************************************/
  474.  
  475. #if MSDOS
  476. static void near show_function_relationships( )
  477. #else
  478. static void show_function_relationships( )
  479. #endif
  480. {
  481. int found;
  482. int record_index;
  483.  
  484. found = binary_search_sorted_data_base( target );/* w/o knowing filename */
  485.           /* note if static, will find random one if more than */
  486.           /* one with same name */
  487. if( found >= 0 )
  488.    {
  489.    recursion_depth = 0;
  490.    if( !g_quiet_flag )
  491.       {
  492.       (void)printf( "Checking for usage...\n" );
  493.       }
  494.    count_all_defined_references();
  495.    nesting_display_buffer[ 0 ] = '\0';
  496.    if( !g_quiet_flag )
  497.       {
  498.       (void)printf( "Starting the printout...\n" );
  499.       }
  500.    if( !target_flag )            /* main is only called once */
  501.       array_of_ptrs_to_records[ found ]->number_of_references = 1;
  502.    line = 0;
  503.    if( !stats_only )
  504.       {
  505.       (void)doprint( found );        /* of target function */
  506.       for( record_index = 0;
  507.        record_index < count_of_valid_records;
  508.        ++record_index
  509.      )
  510.      {
  511.      (void)fprintf( output, "\n" );
  512.      ++line;
  513.      if( array_of_ptrs_to_records[ record_index ]->number_of_references >
  514.          1
  515.        )
  516.         (void)doprint( record_index );
  517.      }
  518.       }
  519.    }
  520. else        /* cant find target */
  521.    {
  522.    (void)printf( "cant find %s, exitting\n", target );
  523.    exit( 1 );
  524.    }
  525. }
  526. /***************************************************************************/
  527.  
  528. #if MSDOS
  529. static void near show_line_and_byte_counts( )
  530. #else
  531. static void show_line_and_byte_counts( )
  532. #endif
  533. {
  534. long int total_byte_count;
  535. long int total_line_count;
  536. int i;
  537.  
  538. file_record_array_ptr = file_record_array;
  539.  
  540. do_top_of_page();
  541. (void)fprintf( output, "File statistics:\n" );
  542. bump_line_count();
  543. total_byte_count = 0l;
  544. total_line_count = 0l;
  545. for( i = 0; i < count_of_source_files; ++i )
  546.    {
  547.    (void)fprintf( output,
  548.           "%-40s - %8u lines, %12ld bytes\n",
  549.           file_record_array_ptr->source_filename,
  550.           file_record_array_ptr->line_count,
  551.           file_record_array_ptr->size
  552.         );
  553.    bump_line_count();
  554.  
  555.    total_byte_count += file_record_array_ptr->size;
  556.    total_line_count += file_record_array_ptr->line_count;
  557.    ++file_record_array_ptr;
  558.    }
  559. (void)fputc( '\n', output );
  560. bump_line_count();
  561. (void)fprintf( output, "Totals:\n" );
  562. bump_line_count();
  563. /********            "%-40s - %8u lines, %12ld bytes\n", *******/
  564. (void)fprintf( output, "%4d files%-30s - %8ld lines, %12ld bytes\n",
  565.            count_of_source_files, " ", total_line_count, total_byte_count
  566.          );
  567. bump_line_count();
  568. (void)fputc( '\n', output );
  569. bump_line_count();
  570. (void)fprintf( output,
  571.            " %d defined functions found.\n", count_of_valid_records
  572.          );
  573. bump_line_count();
  574. (void)fprintf( output, "Averages:\n" );
  575. bump_line_count();
  576. (void)fprintf( output,
  577.            "%6d lines/file, %6d functions/file, %6d lines/function\n",
  578.            (int)( total_line_count / count_of_source_files ),
  579.            (int)( count_of_valid_records / count_of_source_files ),
  580.            (int)( total_line_count / count_of_valid_records )
  581.          );
  582. }
  583. /***************************************************************************/
  584.  
  585. #if MSDOS
  586. static void near show_sorted_function_list( )
  587. #else
  588. static void show_sorted_function_list( )
  589. #endif
  590. {
  591. int i, record_index;
  592. long reference_total = 0;
  593.  
  594. do_top_of_page();
  595.  
  596. (void)fprintf( output, "Function index:\n" );
  597. bump_line_count();
  598.  
  599. if( g_ov_flag )
  600.    (void)fprintf( output, "%-39s %-28s %s %s\n",
  601.           "function", "in file", "ov#", "refs" );
  602. else
  603.    (void)fprintf( output, "%-39s %-28s    %s\n",
  604.           "function", "in file", "refs" );
  605.  
  606. bump_line_count();
  607.  
  608. for( i = 0; i < effective_width; ++i )
  609.    (void)fputc( '_', output );
  610. (void)fprintf( output, "\n" );
  611. bump_line_count();
  612.  
  613. for( record_index = 0;
  614.      record_index < count_of_valid_records;
  615.      ++record_index
  616.    )
  617.    {
  618.    data_base_array_ptr = array_of_ptrs_to_records[ record_index ];
  619.    if( data_base_array_ptr->number_of_references > 0 )
  620.       {   
  621.       if( g_ov_flag && data_base_array_ptr->overlay_number )
  622.      (void)fprintf( output, "%-7s%-32s %-28s %3d %d\n",
  623.             ( data_base_array_ptr->static_definition )?
  624.             "static": "",
  625.             data_base_array_ptr->defined_function,
  626.           ( data_base_array_ptr->file_record_ptr )->source_filename,
  627.             data_base_array_ptr->overlay_number,
  628.             data_base_array_ptr->number_of_references
  629.               );
  630.       else
  631.      (void)fprintf( output, "%-7s%-32s %-28s     %d\n",
  632.             ( data_base_array_ptr->static_definition )?
  633.             "static": "",
  634.             data_base_array_ptr->defined_function,
  635.           ( data_base_array_ptr->file_record_ptr )->source_filename,
  636.             data_base_array_ptr->number_of_references
  637.               );
  638.       reference_total += (long)data_base_array_ptr->number_of_references;
  639.       bump_line_count();
  640.       }
  641.    }
  642. (void)fprintf( output, "%-7s%-32s %-28s     %s\n",
  643.            " ", " ", " ", "____"
  644.          );
  645. bump_line_count();
  646. (void)fprintf( output, "%-7s%-32s %-28s     %ld\n",
  647.            " ", " ", "total ", reference_total
  648.          );
  649. bump_line_count();
  650. }
  651. /***************************************************************************/
  652.  
  653. #if MSDOS
  654. static void near show_page_references( )
  655. #else
  656. static void show_page_references( )
  657. #endif
  658. {
  659. int pmax;       /* max x ref columns */
  660. int i, pcnt;
  661. linked_pages_list *p;
  662.  
  663. if( !stats_only && ( defined_page_length > 0 ) )
  664.    {
  665.    pmax = (int)( effective_width - 7 - 32 - 2 ) / 5;
  666.    do_top_of_page();
  667.    (void)fprintf( output, "Function cross reference:\n" );
  668.    bump_line_count();
  669.  
  670.    for( i = 0; i < count_of_valid_records; ++i )
  671.       {
  672.       data_base_array_ptr = array_of_ptrs_to_records[ i ];
  673.       if( data_base_array_ptr->number_of_references > 0 )
  674.      {
  675.      (void)fprintf( output, "%-7s%-32s- ",
  676.             ( data_base_array_ptr->static_definition )?
  677.             "static": "",
  678.             data_base_array_ptr->defined_function );
  679.      p = data_base_array_ptr->ptr_to_page_list;
  680.      if( p )
  681.         {
  682.         pcnt = 0;
  683.         while( p->next_page_ptr )
  684.            {
  685.            (void)fprintf( output, "%4d,", p->on_this_page );
  686.            p = p->next_page_ptr;
  687.            ++pcnt;
  688.            if( pcnt >= pmax )
  689.           {
  690.           (void)fputc( '\n', output );
  691.           bump_line_count();
  692.           (void)fprintf( output, "%7s%32s  ", " ", " " );
  693.           pcnt = 0;
  694.           }
  695.            }
  696.         (void)fprintf( output, "%4d\n", p->on_this_page );
  697.         }
  698.      else
  699.         (void)fprintf( output, "\n" );
  700.      bump_line_count();
  701.      }
  702.       }
  703.    }
  704. }
  705. /***************************************************************************/
  706.  
  707. #if MSDOS
  708. static void near show_unused_if_any( )
  709. #else
  710. static void show_unused_if_any( )
  711. #endif
  712. {
  713. int i, unused_count, unused_index, count, still_sorting_flag;
  714. data_base_record_type **unused_list_ptr_ptr, *unused_list_ptr;
  715.  
  716. do_top_of_page();
  717. (void)fprintf( output, "Un-used function list:\n" );
  718. bump_line_count();
  719.  
  720. unused_count = 0;
  721. for( i = 0; i < count_of_valid_records; ++i )
  722.    {
  723.    data_base_array_ptr = array_of_ptrs_to_records[ i ];
  724.    if( !data_base_array_ptr->number_of_references )
  725.       {
  726.       ++unused_count;
  727.       if( !g_un_flag )
  728.      {
  729.      (void)fprintf( output,
  730.             "%-7s%-32s- %-33s\n",
  731.             ( data_base_array_ptr->static_definition )?
  732.             "static": "",
  733.             data_base_array_ptr->defined_function,
  734.              ( data_base_array_ptr->file_record_ptr )->source_filename
  735.               );
  736.      bump_line_count();
  737.      }
  738.       }
  739.    }
  740. if( g_un_flag )           /* show sorted */
  741.    {
  742.    if( unused_count )
  743.       {
  744.       if(
  745.      !( array_of_unused_ptrs_to_records =
  746.         (data_base_record_type **)malloc( (unsigned int)unused_count )
  747.       )
  748.     )
  749.      (void)printf( "No room for *array_of_unused_ptrs_to_records\n" );
  750.       else
  751.      {
  752.      unused_index = 0;
  753.      for( i = 0; i < count_of_valid_records; ++i )
  754.         {
  755.         data_base_array_ptr = array_of_ptrs_to_records[ i ];
  756.         if( !data_base_array_ptr->number_of_references )
  757.            {            /* first just collect them */
  758.            array_of_unused_ptrs_to_records[ unused_index++ ] =
  759.           data_base_array_ptr;
  760.            }
  761.         }              /* so now there are unused_index of them */
  762.      unused_list_ptr_ptr = array_of_unused_ptrs_to_records;
  763.      still_sorting_flag = true;
  764.      if( unused_count > 1 )
  765.         {
  766.         while( still_sorting_flag )
  767.            {
  768.            still_sorting_flag = false;
  769.            if( !g_quiet_flag && g_tech_flag )
  770.           (void)printf( ".%d   \r", count );
  771.            for( count = 0; count < unused_count - 1; ++count )
  772.           {
  773.           if( strcmp( unused_list_ptr_ptr[ count ]->
  774.                   file_record_ptr->source_filename,
  775.                   unused_list_ptr_ptr[ count + 1 ]->
  776.                   file_record_ptr->source_filename
  777.                 ) > 0
  778.             )
  779.              {
  780.              still_sorting_flag = true;
  781.              unused_list_ptr = unused_list_ptr_ptr[ count ];
  782.              unused_list_ptr_ptr[ count ] =
  783.             unused_list_ptr_ptr[ count + 1 ];
  784.              unused_list_ptr_ptr[ count + 1 ] = unused_list_ptr;
  785.              }
  786.           }
  787.            }
  788.         }
  789.      for( i = 0; i < unused_count; ++i )
  790.         {
  791.         (void)fprintf( output,
  792.                "%-7s%-32s- %-33s\n",
  793.                ( unused_list_ptr_ptr[ i ]->static_definition )?
  794.                "static": "",
  795.                unused_list_ptr_ptr[ i ]->defined_function,
  796.            ( unused_list_ptr_ptr[ i ]->file_record_ptr )->source_filename
  797.              );
  798.         bump_line_count();
  799.         }
  800.      }
  801.       }
  802.    }
  803. if( !unused_count )
  804.    {
  805.    tab_to_left_margin( output );
  806.    (void)fprintf( output, "No un-used functions in the list.\n" );
  807.    bump_line_count();
  808.    }
  809. else
  810.    {
  811.    (void)fprintf( output, "%-7s%-39s- %d\n", "", "totals", unused_count );
  812.    bump_line_count();
  813.    }
  814. }
  815. /************************************************************************/
  816.  
  817. #if MSDOS
  818. static void near show_library_functions( )
  819. #else
  820. static void show_library_functions( )
  821. #endif
  822. {
  823. register int count;
  824. int found, total, still_sorting_flag, x_count, final_count, final_call;
  825. function_type **f_list_ptr_ptr, *f_list_ptr;
  826.  
  827. if( g_lib_flag )
  828.    {
  829.    if( !g_quiet_flag && g_tech_flag )
  830.       (void)printf( "collecting library functions...\n" );
  831.    do_top_of_page();
  832.    (void)fprintf( output, "Library functions:\n" );
  833.    bump_line_count();
  834.  
  835.    total = 0;
  836.    f_list_ptr = function_list;
  837.    for( count = 0; count < count_of_functions; ++count )
  838.       {
  839.       if( !f_list_ptr->static_function )
  840.      {
  841.      if(
  842.         ( found =
  843.           binary_search_sorted_data_base( f_list_ptr->functions_name )
  844.         ) < 0
  845.        )
  846.         sorted_called_list_ptrs[ total++ ] = f_list_ptr;
  847.      }
  848.       ++f_list_ptr;       /* for all called functions */
  849.       }
  850.  
  851.    if( !g_quiet_flag && g_tech_flag )
  852.       (void)printf( "gathering identical library functions...\n" );
  853.    final_count = total;    /* number of calls to be collected and sorted */
  854.    f_list_ptr_ptr = sorted_called_list_ptrs;
  855.    for( count = 0; count < ( total - 1 ); ++count )
  856.       {
  857.       for( x_count = count + 1; x_count < total; ++x_count )
  858.      {
  859.      if( ( f_list_ptr_ptr[ count ]->functions_name[ 0 ] != '\0' ) &&
  860.          !strcmp( f_list_ptr_ptr[ count ]->functions_name,
  861.               f_list_ptr_ptr[ x_count ]->functions_name )
  862.        )
  863.         {
  864.         f_list_ptr_ptr[ count ]->is_referenced +=
  865.            f_list_ptr_ptr[ x_count ]->is_referenced;
  866.         f_list_ptr_ptr[ x_count ]->functions_name[ 0 ] = '\0';
  867.         --final_count;
  868.         }
  869.      }
  870.       }
  871.  
  872.    if( !g_quiet_flag && g_tech_flag )
  873.       {
  874.       (void)printf( "\nSorting the library function calls...\n" );
  875.       }
  876.  
  877.    f_list_ptr_ptr = sorted_called_list_ptrs;
  878.    still_sorting_flag = true;
  879.    while( still_sorting_flag )
  880.       {
  881.       still_sorting_flag = false;
  882.       if( !g_quiet_flag && g_tech_flag )
  883.      (void)printf( ".%d   \r", count );
  884.       for( count = 0; count < total - 1; ++count )
  885.      {
  886.      if( strcmp( f_list_ptr_ptr[ count ]->functions_name,
  887.              f_list_ptr_ptr[ count + 1 ]->functions_name ) > 0 )
  888.         {
  889.         still_sorting_flag = true;
  890.         f_list_ptr = f_list_ptr_ptr[ count ];
  891.         f_list_ptr_ptr[ count ] = f_list_ptr_ptr[ count + 1 ];
  892.         f_list_ptr_ptr[ count + 1 ] = f_list_ptr;
  893.         }
  894.      }
  895.       }
  896.    if( !g_quiet_flag && g_tech_flag )
  897.       (void)printf( "\n" );
  898.  
  899.    (void)fprintf( output, "%-32s %-28s\n",
  900.           "library function", "calls" );
  901.    bump_line_count();
  902.  
  903.    for( count = 0; count < effective_width; ++count )
  904.       (void)fputc( '_', output );
  905.    (void)fprintf( output, "\n" );
  906.    bump_line_count();
  907.  
  908.    final_call = 0;
  909.    f_list_ptr_ptr = sorted_called_list_ptrs;
  910.    for( count = 0; count < total; ++count )
  911.       {
  912.       if( ( *f_list_ptr_ptr )->functions_name[ 0 ] != '\0' )
  913.      {
  914.      (void)fprintf( output, "%-32s %d\n",
  915.             ( *f_list_ptr_ptr )->functions_name,
  916.             ( *f_list_ptr_ptr )->is_referenced
  917.               );
  918.      final_call += ( *f_list_ptr_ptr )->is_referenced;
  919.      bump_line_count();
  920.      }
  921.       ++f_list_ptr_ptr;
  922.       }
  923.    (void)fprintf( output, "Totals:\n" );
  924.    bump_line_count();
  925.    (void)fprintf( output, "%6d %-25s %d calls.\n",
  926.           final_count, "library functions,", final_call
  927.         );
  928.    bump_line_count();
  929.    }
  930. }
  931. /************************************************************************/
  932.  
  933. #if MSDOS
  934. static void near show_files_leading_comments( )
  935. #else
  936. static void show_files_leading_comments( )
  937. #endif
  938. {
  939. int i;
  940. char *cp;
  941.  
  942. if( g_comment_flag )
  943.    {
  944.    do_top_of_page();
  945.    (void)fprintf( output, "File comments:\n" );
  946.    bump_line_count();
  947.    file_record_array_ptr = file_record_array;
  948.    for( i = 0; i < count_of_source_files; ++i )
  949.       {
  950.       (void)fprintf( output, "%40s\n",
  951.              file_record_array_ptr->source_filename
  952.            );
  953.       bump_line_count();
  954.       cp = file_record_array_ptr->source_file_comment;
  955.       while( *cp )
  956.      {
  957.      (void)fprintf( output, "%c", *cp );
  958.      if( *++cp == '\n' )
  959.         {
  960.         bump_line_count();
  961.         }
  962.      }
  963.       ++file_record_array_ptr;     
  964.       do_top_of_page();      /* one page per comment at least */
  965.       }
  966.    }
  967. }
  968. /**********************************************************************/
  969.  
  970. #if !MSDOS
  971. char *strdup(orig)
  972. char *orig;
  973. {
  974.    char *ptr;
  975.  
  976.    ptr = (char *) malloc( (strlen(orig) * sizeof(char)) + 1);
  977.  
  978.    if(ptr != NULL)
  979.    {
  980.       strcpy(ptr,orig);
  981.    }
  982.  
  983.    return(ptr);
  984. }
  985. #endif
  986. /**********************************************************************/
  987.  
  988. int main( argc, argv )
  989. char **argv;
  990. int argc;
  991. {
  992. int   index, in_error = false, out_error = false;
  993. FILE  *stream;
  994.  
  995. nasty( argc );
  996.  
  997. (void)printf( "\ncp - ver. 1.3,  (C)1987, 1988  Stewart A. Nutter\n" );
  998. (void)printf( "    extended and corrected by  Ron Winter\n" );
  999.  
  1000. index = 1;
  1001. if( !( stream = fopen( argv[ index ], "rt" ) ) )
  1002.    in_error = true;
  1003. else
  1004.    ++index;
  1005. if(
  1006.    ( argc > index ) &&
  1007.    (
  1008.     ( argv[ index ][ 0 ] != '/' ) && ( argv[ index ][ 0 ] != '-' )
  1009.    )
  1010.   )
  1011.    {
  1012.    if( strcmp(argv[2],"con") == 0)
  1013.       output = stderr;
  1014.    else
  1015.       output = fopen( argv[ 2 ], "w+" );     /******* wt+ <<<<<<<< ******/
  1016.    ++index;
  1017.    }
  1018. else
  1019.    output = fopen( "prn", "w+" );      /******** wt+ <<<<<< ********/
  1020.  
  1021. if( !output )
  1022.    out_error = true;
  1023.  
  1024. Max_functions = MAX_functions;
  1025. process_arguments( index, argc, argv, in_error || out_error );
  1026. if( in_error )
  1027.    {
  1028.    (void)printf( "\n can't open input list %s\n", argv[ 1 ] );
  1029.    exit( 1 );
  1030.    }
  1031. if( out_error )
  1032.    {
  1033.    (void)printf( "\n can't open output file.\n");
  1034.    exit( 1 );
  1035.    }
  1036. allocate_arrays( );
  1037. initialize_globals( );
  1038. (void)printf( "\n" );
  1039.  
  1040. build_records_from_list( stream );
  1041. sort_the_data_base_array( );
  1042. if( !g_quiet_flag )
  1043.    {
  1044.    (void)printf( "\n" );
  1045.    }
  1046. top_of_form_done = false;
  1047. show_function_relationships( );
  1048. show_page_references( );
  1049. show_line_and_byte_counts( );
  1050. show_sorted_function_list( );
  1051. show_unused_if_any( );
  1052. show_library_functions( );
  1053. show_files_leading_comments( );
  1054. deallocate_arrays( );
  1055.  
  1056. /************* done *****************/
  1057. (void)fprintf( output, "%c", 0x0c );   /* ff */
  1058.  
  1059. return false;      /* ok */
  1060. }
  1061. /********************************************************************/
  1062. ", 0x0c );