home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / c_spec / poole_cp / cpfuncts.c < prev    next >
Text File  |  1989-11-21  |  18KB  |  623 lines

  1. /**********************************************************************
  2.                   cpfuncts.c
  3.        void near build_box_parts( int );
  4.        void near tab_to_left_margin( FILE * );
  5. static void near stop( void );
  6. static void near setpage( data_base_record_type * );
  7. static int  near recursion_check( char *, int );
  8.        void near check_for_new_page( void );
  9. static void near draw_output_block( char *, char *, char *,
  10.                     char *, int, int, int, int );
  11.        int near  doprint( int );
  12.        void near scan_for_static_or_global( int *, int, char *, char * );
  13.        int near  binary_search_sorted_data_base( char * );
  14. ***********************************************************************/
  15.  
  16. #define  MAIN  0
  17. #include "cpheader.h"
  18.  
  19. static char
  20.    *top_line_of_box, *bottom_line_of_box,
  21.    wall, ibm_line, bottom_attach,
  22.    upper_left_corner, lower_left_corner,
  23.    upper_right_corner, lower_right_corner,
  24.    left_attach, right_attach;
  25.  
  26. static char *recursion_filename, *test_filename;
  27. static int static_recursion;
  28.  
  29. #if VMS
  30.        int  binary_search_sorted_data_base( char * );
  31.        void build_box_parts( int );
  32.        void check_for_new_page( void );
  33.        int  doprint( int );
  34.        void scan_for_static_or_global( int *, int, char *, char * );
  35.        void tab_to_left_margin( FILE * );
  36.  
  37. static void draw_output_block( char *, char *, char *,
  38.                     char *, int, int, int, int );
  39. static int  recursion_check( char *, int );
  40. static void stop( void );
  41. static void setpage( data_base_record_type * );
  42. #endif
  43.  
  44. #if MSDOS
  45.        int near  binary_search_sorted_data_base( char * );
  46.        void near build_box_parts( int );
  47.        void near check_for_new_page( void );
  48.        int near  doprint( int );
  49.        void near scan_for_static_or_global( int *, int, char *, char * );
  50.        void near tab_to_left_margin( FILE * );
  51.  
  52. static void near draw_output_block( char *, char *, char *,
  53.                     char *, int, int, int, int );
  54. static int near  recursion_check( char *, int );
  55. static void near stop( void );
  56. static void near setpage( data_base_record_type * );
  57. #endif
  58.  
  59. /************************************************************************/
  60. #if MSDOS
  61. void near build_box_parts( is_ibm )
  62. #else
  63. void build_box_parts( is_ibm )
  64. #endif
  65. int is_ibm;
  66. {
  67. int i;
  68.  
  69. if( is_ibm )
  70.    {
  71.    wall =        '\xb3';
  72.    ibm_line =        '\xc4';
  73.    bottom_attach =    '\xc2';
  74.    upper_left_corner =    '\xda';
  75.    lower_left_corner =    '\xc0';
  76.    upper_right_corner = '\xbf';
  77.    lower_right_corner = '\xd9';
  78.    left_attach =    '\xb4';
  79.    right_attach =    '\xc3';
  80.    }
  81. else
  82.    {
  83.    wall =        '|';
  84.    ibm_line =        '-';
  85.    bottom_attach =    '+';
  86.    upper_left_corner =    '+';
  87.    lower_left_corner =    '+';
  88.    upper_right_corner = '+';
  89.    lower_right_corner = '+';
  90.    left_attach =    '+';
  91.    right_attach =    '+';
  92.    }
  93.  
  94. if( !( top_line_of_box =(char *)malloc( defined_box_width * sizeof(char) ))
  95.   )
  96. {
  97.    (void)fprintf( stderr, "Ran out of memory for top line of box.\n" );
  98.    exit( 1 );
  99. }
  100.  
  101. if( !( bottom_line_of_box =(char *)malloc( defined_box_width * sizeof(char) ))
  102.   )
  103. {
  104.    (void)fprintf( stderr, "Ran out of memory for bottom line of box.\n" );
  105.    exit( 1 );
  106. }
  107.  
  108. top_line_of_box[ 0 ] = upper_left_corner;   
  109. bottom_line_of_box[ 0 ] = lower_left_corner;
  110. for( i = 1; i <= (defined_box_width - 3); ++i )
  111.    {
  112.    top_line_of_box[ i ] = ibm_line;
  113.    bottom_line_of_box[ i ] = ibm_line;
  114.    }
  115. top_line_of_box[ i ] = upper_right_corner;
  116. bottom_line_of_box[ i ] = lower_right_corner;
  117. top_line_of_box[ ++i ] = '\0';
  118. bottom_line_of_box[ i ] = '\0';
  119. }
  120. /**********************************************************************/
  121. #if MSDOS
  122. void near tab_to_left_margin( output )
  123. #else
  124. void tab_to_left_margin( output )
  125. #endif
  126. FILE *output;
  127. {
  128. register int i;
  129.  
  130. for( i = 0; i < defined_left_margin; ++i )
  131.    (void)fputc( ' ', output );
  132. }
  133. /**********************************************************************/
  134. #if MSDOS
  135. static void near stop()
  136. #else
  137. static void stop()
  138. #endif
  139. {
  140. (void)printf( "hello" );
  141. }
  142. /**********************************************************************/
  143. #if MSDOS
  144. static void near setpage( data_base_ptr )
  145. #else
  146. static void setpage( data_base_ptr )
  147. #endif
  148. data_base_record_type *data_base_ptr;
  149. {
  150. linked_pages_list *page_list_ptr;
  151.  
  152. page_list_ptr = data_base_ptr->ptr_to_page_list;
  153. if( page_list_ptr == NULL )
  154.    {
  155.    if(
  156.       !( page_list_ptr =
  157.      (linked_pages_list *)malloc( sizeof( linked_pages_list ) )
  158.        )
  159.      )
  160.       {
  161.       (void)fprintf( stderr, "Ran out of memory for page # list.\n" );
  162.       exit( 1 );
  163.       }
  164.  
  165.    data_base_ptr->ptr_to_page_list = page_list_ptr;
  166.    }
  167. else
  168.    {
  169.    while( page_list_ptr->next_page_ptr )
  170.       page_list_ptr = page_list_ptr->next_page_ptr;
  171.  
  172.    if(
  173.       !( page_list_ptr->next_page_ptr =
  174.      (linked_pages_list *)malloc( sizeof( linked_pages_list ) )
  175.        )
  176.      )
  177.       {
  178.       (void)fprintf( stderr, "Ran out of memory for page # list.\n" );
  179.       exit( 1 );
  180.       }
  181.  
  182.    page_list_ptr = page_list_ptr->next_page_ptr;
  183.    }
  184. page_list_ptr->next_page_ptr = NULL;
  185. page_list_ptr->on_this_page = page - 1;
  186. }
  187. /*********************************************************************/
  188. #if MSDOS
  189. static int near recursion_check( string, static_call )
  190. #else
  191. static int recursion_check( string, static_call )
  192. #endif
  193. char *string;
  194. int static_call;
  195. {
  196. register char **recursion_array_ptr;
  197.  
  198. recursion_array_ptr = recursion_array;
  199. if( static_recursion )
  200.    {                 /* defined function is static */
  201.    while(
  202.      *recursion_array_ptr && /* not null */
  203.                  /* and different function names */
  204.      ( strcmp( *recursion_array_ptr, string ) ||
  205.                  /* or same function names and */
  206.                  /* in different files */
  207.        strcmp( test_filename, recursion_filename )
  208.      )
  209.     )
  210.    ++recursion_array_ptr;
  211.    }
  212. else
  213.    {                 /* defined function is not static */
  214.    while(
  215.      *recursion_array_ptr && /* not null & */
  216.                  /* and different function names */
  217.      ( strcmp( *recursion_array_ptr, string ) ||
  218.                  /* or same function names and */
  219.        static_call         /* called is static */
  220.      )
  221.     )
  222.       ++recursion_array_ptr;
  223.    }
  224. return ( *recursion_array_ptr )? true: false;
  225. }
  226. /**********************************************************************/
  227. #if MSDOS
  228. void near check_for_new_page()
  229. #else
  230. void check_for_new_page()
  231. #endif
  232. {
  233. int i;
  234.  
  235. if( defined_page_length == 0 && line == 9999 )
  236.    {
  237.    (void)fprintf( output, "\n\n\n\n" );
  238.    line = 0;
  239.    }
  240. else
  241.    {
  242.    if( defined_page_length != 0 )
  243.       {
  244.       if( line > ( defined_page_length - 5 ) )
  245.      {
  246.      (void)fprintf( output, "\f" );
  247.      line = 0;
  248.      }
  249.       if( line == 0 )
  250.      {
  251.      top_of_form_done = true;
  252.      tab_to_left_margin( output );
  253.      (void)fprintf( output, "%s", title );
  254.      for( i = strlen( title ); i < ( effective_width - 10 ); ++i )
  255.         (void)fputc( ' ', output );
  256.      (void)fprintf( output, "Page:%4d\n", page );
  257.      tab_to_left_margin( output );
  258.      for( i = 0; i < effective_width; ++i )
  259.         (void)fputc( '_', output );
  260.      (void)fprintf( output, "\n\n" );
  261.      line = 3;
  262.      ++page;
  263.      }
  264.       }
  265.    }
  266. }
  267. /**********************************************************************/
  268. #if MSDOS
  269. static void near draw_output_block( lead_in_string,
  270.                     name_of_function,
  271.                     name_of_file,
  272.                     description,
  273.                     either_count,
  274.                     tail_flag,
  275.                     kill_flag,
  276.                     ov_num
  277.                   )
  278. #else
  279. static void draw_output_block( lead_in_string,
  280.                    name_of_function,
  281.                    name_of_file,
  282.                    description,
  283.                    either_count,
  284.                    tail_flag,
  285.                    kill_flag,
  286.                    ov_num
  287.                  )
  288. #endif
  289. char *lead_in_string,
  290.    *name_of_function,
  291.    *description,
  292.    *name_of_file;
  293. int either_count, tail_flag, kill_flag, ov_num;
  294. {
  295. unsigned int string_length;
  296. int x;
  297. static char alternate_lead_in[ 140 ];
  298.  
  299. /******* 1st line *****************************************************/
  300. tab_to_left_margin( output );
  301. (void)fprintf( output, "%s %s\n", lead_in_string, top_line_of_box );
  302.  
  303. /******* 2nd line ******************************************************/
  304. tab_to_left_margin( output );
  305. string_length = strlen( lead_in_string );
  306. if( string_length )    /******* ie not main or defined function box ***/
  307.    {
  308.    (void)strncpy( alternate_lead_in, lead_in_string, --string_length );
  309.    alternate_lead_in[ string_length++ ] = '\0'; /*restore string_length*/
  310.    }
  311. if( string_length )   /******* ie not main or defined function box ***/
  312.    {
  313.    if( g_ov_flag && ov_num )
  314.       {
  315.       (void)fprintf( output, "%s%c%c%c%s %3d",
  316.              alternate_lead_in,
  317.       /***  if( kill_flag )   /****** last line to this box ******************/
  318.       /***  else          /****** line continues downwards ***************/
  319.              ( kill_flag )? lower_left_corner: right_attach,
  320.              ibm_line, left_attach, name_of_function, ov_num);
  321.       for(x=strlen(name_of_function);x < defined_box_width-7;x++)
  322.      putc(' ',output);
  323.       putc(wall,output);
  324.       putc('\n',output);
  325.       }
  326.    else
  327.       {
  328.       (void)fprintf( output, "%s%c%c%c%s    ",
  329.              alternate_lead_in,
  330.       /***  if( kill_flag )   /****** last line to this box ******************/
  331.       /***  else          /****** line continues downwards ***************/
  332.              ( kill_flag )? lower_left_corner: right_attach,
  333.              ibm_line, left_attach, name_of_function);
  334.       for(x=strlen(name_of_function);x < defined_box_width-7;x++)
  335.      putc(' ',output);
  336.       putc(wall,output);
  337.       putc('\n',output);
  338.       }
  339.    }
  340. else             /****** main or defined box starting ***********/
  341.    {
  342.    if( g_ov_flag && ov_num )
  343.       {
  344.       (void)fprintf( output,     "%c%c%s %3d",
  345.              ibm_line, left_attach, name_of_function, ov_num);
  346.       for(x=strlen(name_of_function);x < defined_box_width-7;x++)
  347.      putc(' ',output);
  348.       putc(wall,output);
  349.       putc('\n',output);
  350.       }
  351.    else
  352.       {
  353.       (void)fprintf( output,     "%c%c%s    ",
  354.              ibm_line, left_attach, name_of_function);
  355.       for(x=strlen(name_of_function);x < defined_box_width-7;x++)
  356.      putc(' ',output);
  357.       putc(wall,output);
  358.       putc('\n',output);
  359.       }
  360.    }
  361. /******* 3rd line *****************************************************/
  362. tab_to_left_margin( output );
  363. if( string_length-- )     /** kill outside vertical line on last box **/
  364.    lead_in_string[ string_length++ ] = ( kill_flag )? (char)' ': wall;
  365. (void)fprintf( output, "%s %c%s   %8s%3d",
  366.            lead_in_string, wall,  name_of_file, description, either_count);
  367.    for(x=strlen(name_of_file);x < defined_box_width-17;x++) putc(' ',output);
  368.    putc(wall,output);
  369.    putc('\n',output);
  370.  
  371. /******* 4th line *****************************************************/
  372. tab_to_left_margin( output );
  373. bottom_line_of_box[ 2 ] =  /**** if defined box has calls *******/
  374.    ( tail_flag && either_count )? bottom_attach: ibm_line;
  375. (void)fprintf( output, "%s %s\n", lead_in_string, bottom_line_of_box );
  376.  
  377. line += 4;
  378. top_of_form_done = false;
  379. }
  380. /**********************************************************************/
  381.  
  382. static char library_string[] = { "(library)" };
  383. static char usage_string[] =   { "Used=" };
  384. static char funct_string[] =   { "Functs=" };
  385.  
  386. #if MSDOS
  387. int near doprint( index )
  388. #else
  389. int doprint( index )
  390. #endif
  391. int index;
  392. {
  393. int
  394.    loop_counter,
  395.    max_count,
  396.    starting_index,
  397.    found,
  398.    return_value;
  399. void scan_for_static_or_global();
  400. data_base_record_type *record_ptr;
  401. function_type *f_list_ptr;
  402.  
  403. static int kill_flag = false;
  404.  
  405. starting_index = index;
  406. record_ptr = array_of_ptrs_to_records[ starting_index ];
  407.  
  408. recursion_array[ recursion_depth ] = record_ptr->defined_function;
  409. if( !recursion_depth )
  410.    {
  411.    recursion_filename = record_ptr->file_record_ptr->source_filename;
  412.             /* add function to list for recursion check */
  413.    static_recursion = record_ptr->static_definition;
  414.    }
  415. check_for_new_page();
  416. setpage( array_of_ptrs_to_records[ starting_index ] );
  417.  
  418. return_value = page - 1;           /* must be a relic! */
  419.                        /* start w/ target function */
  420. draw_output_block( nesting_display_buffer,
  421.            record_ptr->defined_function,
  422.            ( record_ptr->file_record_ptr )->source_filename,
  423.            funct_string,
  424.            record_ptr->number_of_function_calls,
  425.            true,
  426.            kill_flag,
  427.            record_ptr->overlay_number
  428.          );
  429.  
  430. ++recursion_depth;
  431.                /****   mystic width = 4 *****/
  432. (void)strcat( nesting_display_buffer, "   |" );
  433. nesting_display_buffer[ strlen( nesting_display_buffer ) - 1 ] = wall;
  434.  
  435. max_count = record_ptr->number_of_function_calls;
  436. for( loop_counter = 0, f_list_ptr = record_ptr->ptr_to_function_table;
  437.      loop_counter < max_count;
  438.      ++loop_counter, ++f_list_ptr
  439.    )
  440.    {
  441.    kill_flag = ( loop_counter == ( max_count - 1 ) )? true: false;
  442.    check_for_new_page();
  443.                /* is called function defined? */
  444.    found = binary_search_sorted_data_base( f_list_ptr->functions_name );
  445.    if( found >= 0 )
  446.       {
  447.       scan_for_static_or_global( &found,
  448.                  f_list_ptr->static_function,
  449.                  f_list_ptr->functions_name,
  450.                  f_list_ptr->its_filename
  451.                    );
  452.  
  453.       }
  454.    if( found >= 0 )       /* yes */
  455.       {
  456.       test_filename = f_list_ptr->its_filename;
  457.       if( recursion_check( f_list_ptr->functions_name,
  458.                f_list_ptr->static_function )
  459.     )
  460.      {
  461. /*       tab_to_left_margin( output );
  462. /*       (void)fprintf( output, "%s\n", nesting_display_buffer ); */
  463.      setpage( array_of_ptrs_to_records[ found ] );
  464. /*       ++line; */
  465.      top_of_form_done = false;
  466.      draw_output_block( nesting_display_buffer,
  467.              f_list_ptr->functions_name,
  468.              "(recursive)",
  469.              "",
  470.              0,
  471.              false,
  472.              kill_flag,
  473.              array_of_ptrs_to_records[ found ]->overlay_number
  474.               );
  475.      }
  476.       else      /* not recursive and found >= 0 */
  477.      {
  478.      if( array_of_ptrs_to_records[ found ]->number_of_references == 1 )
  479.         {                /* got a new function */
  480. /*          tab_to_left_margin( output );
  481. /*          (void)fprintf( output, "%s\n", nesting_display_buffer );
  482. /*          ++line;
  483. /*          top_of_form_done = false; */
  484.         doprint( found );        /* used only once */
  485.         }
  486.      else
  487.         {                /* a previously defined function */
  488. /*          tab_to_left_margin( output );
  489. /*          (void)fprintf( output, "%s\n", nesting_display_buffer ); */
  490.         setpage( array_of_ptrs_to_records[ found ] );
  491. /*          ++line;
  492. /*          top_of_form_done = false; */
  493.         draw_output_block( nesting_display_buffer,
  494.                    f_list_ptr->functions_name,
  495.                    "(defined)",
  496.                    usage_string,
  497.                    f_list_ptr->is_referenced,
  498.                    false,
  499.                    kill_flag,
  500.              array_of_ptrs_to_records[ found ]->overlay_number
  501.                  ); 
  502.         }
  503.      }
  504.       }
  505.    else       /* found = -1 ie not defined means */
  506.       {       /* a library function */
  507. /*    tab_to_left_margin( output );
  508. /*    (void)fprintf( output, "%s\n", nesting_display_buffer );
  509. /*    ++line;
  510. /*    top_of_form_done = false; */
  511.       draw_output_block( nesting_display_buffer,
  512.              f_list_ptr->functions_name,
  513.              library_string,
  514.              usage_string,
  515.              f_list_ptr->is_referenced,
  516.              false,
  517.              kill_flag,
  518.              0    /* .lib functions are in the kernel */
  519.                );
  520.       }
  521.    }           /* end of loop on all called functions */
  522.  
  523.                /* remove function f/ recursion list */
  524. recursion_array[ recursion_depth ] = NULL;
  525.                /****   mystic width = 4 *****/
  526. nesting_display_buffer[ strlen( nesting_display_buffer ) - 4 ] = '\0';
  527. --recursion_depth;
  528. return return_value;
  529. }
  530. /**********************************************************************/
  531.  
  532. #if MSDOS
  533. void near scan_for_static_or_global(
  534.              index_ptr, is_static, function_name, file_name
  535.                    )
  536. #else
  537. void scan_for_static_or_global(
  538.              index_ptr, is_static, function_name, file_name
  539.                   )
  540. #endif
  541. int *index_ptr, is_static;
  542. char *function_name, *file_name;
  543. {
  544. int index;
  545.  
  546. index = *index_ptr;
  547. if( index )
  548.    while( index-- )
  549.       if( strcmp( function_name,
  550.           array_of_ptrs_to_records[ index ]->defined_function )
  551.     )
  552.      {
  553.      ++index;    /* exit at last matching defined function */
  554.      break;
  555.      }
  556. do {
  557.    if(
  558.       ( !is_static && !array_of_ptrs_to_records[ index ]->static_definition
  559.       ) ||
  560.       ( is_static &&
  561.     array_of_ptrs_to_records[ index ]->static_definition &&
  562.     !strcmp( array_of_ptrs_to_records[ index ]->
  563.           file_record_ptr->source_filename,
  564.          file_name
  565.            )
  566.       )
  567.      )
  568.       break;
  569.    }
  570. while(
  571.       ( ++index < count_of_functions ) &&
  572.       !strcmp( function_name,
  573.            array_of_ptrs_to_records[ index ]->defined_function
  574.          )
  575.      );
  576. if(
  577.  ( index >= count_of_functions ) ||
  578.  strcmp( function_name, array_of_ptrs_to_records[ index ]->defined_function
  579.      )
  580.   )
  581.    index = -1;
  582. *index_ptr = index;
  583. }
  584. /**********************************************************************/
  585. #if MSDOS
  586. int near binary_search_sorted_data_base( key )
  587. #else
  588. int binary_search_sorted_data_base( key )
  589. #endif
  590. char *key;
  591. {
  592. int lo, hi, index;
  593. int doesnt_match;
  594.  
  595. lo = 0;
  596. hi = count_of_valid_records - 1;
  597. index = ( hi - lo ) / 2;
  598.  
  599. while( true )
  600.    {
  601.    doesnt_match =
  602.     strcmp( key, array_of_ptrs_to_records[ index ]->defined_function );
  603.    if( !doesnt_match )          /* a match found at index */
  604.       break;
  605.    if( lo >= hi )          /* no match found */
  606.       {
  607.       index = -1;
  608.       break;
  609.       }
  610.    if( doesnt_match < 0 )     /* key < choice so go downwards */
  611.       hi = index - 1;
  612.    else               /* key > choice so go upwards */
  613.       lo = index + 1;
  614.    index = ( hi + lo ) / 2;   /* new choice */
  615.    }
  616. return index;
  617. }
  618. /**********************************************************************/
  619.  ) / 2;   /* new choice */
  620.    }
  621. return index;
  622. }
  623. /********