?? RIGHT := 110 ??
MODULE ocm$anaol_display_handlers;



{ PURPOSE:
{   This module contains the display handlers for ANALYZE_OBJECT_LIBRARY.


?? PUSH (LISTEXT := ON) ??
*copyc oct$anaol_types
?? POP ??
*copyc ocp$open_output_file
*copyc ocp$output
*copyc ocp$output_section_kind
*copyc ocp$output_access_attributes
*copyc ocp$close_output_file

*copyc ocp$analyze_load_module
*copyc ocp$internal_error
*copyc ocp$abort_if_abnormal_status
*copyc ocp$abort_if_segment_overflow

*copyc pmp$get_last_path_name
?? NEWTITLE := '  Global Declarations', EJECT ??

  VAR
    ocv$command_sequence: [XREF] ^SEQ ( * ),
    ocv$library_sequence: [XREF] ^SEQ ( * );




  CONST
    end_of_line = TRUE,
    continue = FALSE;


  VAR
    v$page_header: [STATIC] string (58) := 'Analysis of Object Library ',
    strng: string (131),
    lngth: integer;

?? OLDTITLE ??
?? NEWTITLE := '  DISPLAY_RECORD_ANALYSIS', EJECT ??

  PROCEDURE display_record_analysis
    (    record_analysis: ^oct$record_analysis);


    VAR
      order: [STATIC, READ] array [llt$object_record_kind] of llt$object_record_kind :=
            [llc$identification, llc$libraries, llc$section_definition, llc$allotted_section_definition,
            llc$unallocated_common_block, llc$obsolete_segment_definition, llc$obsolete_allotted_seg_def,
            llc$segment_definition, llc$allotted_segment_definition, llc$text, llc$replication,
            llc$bit_string_insertion, llc$ppu_absolute, llc$68000_absolute, llc$address_formulation,
            llc$external_linkage, llc$entry_definition, llc$deferred_entry_points, llc$deferred_common_blocks,
            llc$relocation, llc$binding_template, llc$obsolete_line_table, llc$cybil_symbol_table_fragment,
            llc$line_table_fragment, llc$symbol_table_fragment, llc$line_table, llc$symbol_table,
            llc$supplemental_debug_tables, llc$actual_parameters, llc$obsolete_formal_parameters,
            llc$formal_parameters, llc$ses_reserved_1, llc$ses_reserved_2, llc$ses_reserved_3,
            llc$transfer_symbol, llc$form_definition, llc$application_identifier],


      record_kind: [STATIC, READ] array [llt$object_record_kind] of string (38) := [
            {} '     Identification records:          ', {} '     Libraries:                       ',
            {} '     Section definitions:             ', {} '     Text records:                    ',
            {} '     Replication records:             ', {} '     Bit string insertion records:    ',
            {} '     Entry definitions:               ', {} '     Relocation records:              ',
            {} '     Address formulation records:     ', {} '     External linkage records:        ',
            {} '     Obsolete Formal parameters:      ', {} '     Actual parameters:               ',
            {} '     Binding templates:               ', {} '     PPU absolute records:            ',
            {} '     Obsolete line table records:     ', {} '     Cybil symbol table fragments:    ',
            {} '     Allotted section definitions:    ', {} '     Symbol table records:            ',
            {} '     Transfer symbols:                ', {} '     SES reserved 1:                  ',
            {} '     SES reserved 2:                  ', {} '     SES reserved 3:                  ',
            {} '     M68000 absolute records:         ', {} '     Line table records:              ',
            {} '     Line table fragments:            ', {} '     symbol table fragments:          ',
            {} '     Obsolete segment definitions:    ', {} '     Obsolete allotted segment defs:  ',
            {} '     Formal parameters:               ', {} '     Unallocated common blocks:       ',
            {} '     Form definitions:                ', {} '     Application_identifiers:         ',
            {} '     Segment definitions:             ', {} '     Allotted segment definitions:    ',
            {} '     Supplemental debug tables:       ', {} '     Deferred entry points:           ',
            {} '     Deferred common blocks:          '],

      k: llt$object_record_kind,
      kind: llt$object_record_kind;


    ocp$output ('0', '  Record Analysis', 17, end_of_line);
    ocp$output (' ', '  ~~~~~~~~~~~~~~~', 17, end_of_line);

    FOR k := LOWERVALUE (llt$object_record_kind) TO UPPERVALUE (llt$object_record_kind) DO
      kind := order [k];
      IF (record_analysis^.kind [kind].number <> 0) THEN
        STRINGREP (strng, lngth, record_analysis^.kind [kind].number: 8);

        IF (record_analysis^.kind [kind].number_of_items <> 0) THEN
          ocp$output (record_kind [kind], strng, lngth, continue);

          STRINGREP (strng, lngth, record_analysis^.kind [kind].number_of_items: 8);
          ocp$output ('   items:', strng, lngth, end_of_line);
        ELSE
          ocp$output (record_kind [kind], strng, lngth, end_of_line);
        IFEND;
      IFEND;
    FOREND;


    ocp$output ('                                      ', '--------', 8, end_of_line);
    STRINGREP (strng, lngth, record_analysis^.total: 8);
    ocp$output ('       Total records:                 ', strng, lngth, end_of_line);


  PROCEND display_record_analysis;
?? OLDTITLE ??
?? NEWTITLE := '  DISPLAY_SECTION', EJECT ??

  PROCEDURE display_section
    (    section_: oct$section);


    VAR
      ignore: boolean;


    IF section_.segment_definition THEN
      ocp$output ('     Segment: ', section_.definition^.name, 31, continue);
    ELSE
      ocp$output ('     Section: ', section_.definition^.name, 31, continue);
    IFEND;

    STRINGREP (strng, lngth, section_.definition^.length: 12, ' bytes');
    ocp$output (' ', strng, lngth, continue);

    IF section_.allotted THEN
      ocp$output ('  ', 'ALLOTTED   ', 11, continue);
    ELSEIF section_.unallocated_common_block THEN
      ocp$output ('  ', 'UNALLOCATED', 11, continue);
    ELSE
      ocp$output ('  ', '           ', 11, continue);
    IFEND;

    ocp$output_section_kind (^section_.definition^.kind, continue, ignore);

    ocp$output_access_attributes (section_.definition^.access_attributes, end_of_line);

    IF ((section_.bytes_initialized + section_.externals_in + section_.addresses_in +
          section_.addresses_to) <> 0) THEN
      ocp$output ('', '     ', 5, continue);
      IF (section_.bytes_initialized <> 0) THEN
        STRINGREP (strng, lngth, section_.bytes_initialized);
        ocp$output ('  Bytes initialized:', strng, lngth, continue);
      IFEND;
      IF (section_.externals_in <> 0) THEN
        STRINGREP (strng, lngth, section_.externals_in);
        ocp$output ('  Externals in:', strng, lngth, continue);
      IFEND;
      IF (section_.addresses_in <> 0) THEN
        STRINGREP (strng, lngth, section_.addresses_in);
        ocp$output ('  Addresses in:', strng, lngth, continue);
      IFEND;
      IF (section_.addresses_to <> 0) THEN
        STRINGREP (strng, lngth, section_.addresses_to);
        ocp$output ('  Addresses to:', strng, lngth, continue);
      IFEND;

      ocp$output ('', ' ', 1, end_of_line);
    IFEND;


  PROCEND display_section;
?? OLDTITLE ??
?? NEWTITLE := '  DISPLAY_SECTION_ANALYSIS', EJECT ??

  PROCEDURE display_section_analysis
    (    sections: ^oct$sections);


    VAR
      i: llt$section_ordinal;


    ocp$output ('0', '  Section Analysis', 18, end_of_line);
    ocp$output (' ', '  ~~~~~~~~~~~~~~~~', 18, end_of_line);

    FOR i := LOWERBOUND (sections^) TO UPPERBOUND (sections^) DO
      IF sections^ [i].definition <> NIL THEN
        display_section (sections^ [i]);
      IFEND;
    FOREND;


  PROCEND display_section_analysis;
?? OLDTITLE ??
?? NEWTITLE := '  DISPLAY_LIBRARY_ANALYSIS', EJECT ??

  PROCEDURE display_library_analysis
    (    object_library: ^oct$object_library;
         display_options: oct$anaol_display_options);


    VAR
      i: integer;


    IF (occ$display_number_of_modules IN display_options) THEN
      STRINGREP (strng, lngth, object_library^.number_of_modules);
      ocp$output ('0  Number of modules: ', strng, lngth, end_of_line);
    IFEND;

    IF (occ$display_record_analysis IN display_options) THEN
      FOR i := 1 TO object_library^.number_of_modules DO
        ocp$analyze_load_module (object_library, ^object_library^.module_list^ [i], display_options);
      FOREND;

      display_record_analysis (object_library^.record_analysis);
    IFEND;


  PROCEND display_library_analysis;
?? OLDTITLE ??
?? NEWTITLE := '  DISPLAY_MODULE_ANALYSIS', EJECT ??

  PROCEDURE display_module_analysis
    (    object_library: ^oct$object_library;
         display_options: oct$anaol_display_options);


    VAR
      next_module: ^oct$module_item;


    next_module := object_library^.module_list^ [occ$head_of_list].link;

    WHILE (next_module <> NIL) DO
      ocp$output ('1Module Analysis of ', next_module^.name, #SIZE (next_module^.name), end_of_line);

      ocp$analyze_load_module (object_library, next_module, display_options);

      IF (occ$display_record_analysis IN display_options) THEN
        display_record_analysis (next_module^.record_analysis);
      IFEND;
      IF (occ$display_section_analysis IN display_options) THEN
        display_section_analysis (next_module^.record_analysis^.sections);
      IFEND;

      next_module := next_module^.link;
    WHILEND;


  PROCEND display_module_analysis;
?? OLDTITLE ??
?? NEWTITLE := '  DISPLAY_SECTION_USAGE', EJECT ??

  PROCEDURE display_section_usage
    (    object_library: ^oct$object_library;
         section_kinds: oct$section_kinds;
         access_attributes: llt$section_access_attributes;
         section_name: pmt$program_name);


    VAR
      display_options: [STATIC, READ] oct$anaol_display_options := [occ$display_section_analysis],
      occ$all_access_attributes: [XREF] llt$section_access_attributes,
      title_printed: boolean,
      next_module: ^oct$module_item,
      sections: ^oct$sections,
      i: llt$section_ordinal;


    next_module := object_library^.module_list^ [occ$head_of_list].link;

    WHILE (next_module <> NIL) DO
      ocp$analyze_load_module (object_library, next_module, display_options);

      sections := next_module^.record_analysis^.sections;

      IF (sections <> NIL) THEN
        title_printed := FALSE;

        FOR i := LOWERBOUND (sections^) TO UPPERBOUND (sections^) DO

          IF (sections^ [i].definition <> NIL) AND (sections^ [i].definition^.kind IN section_kinds) AND {}
                ((access_attributes = occ$all_access_attributes) OR {}
                (access_attributes = sections^ [i].definition^.access_attributes)) AND {}
                ((section_name = occ$any_section_name) OR (section_name = sections^ [i].definition^.name))
                THEN

            IF NOT title_printed THEN
              ocp$output ('1Section Usage of ', next_module^.name, #SIZE (next_module^.name), end_of_line);
              title_printed := TRUE;
            IFEND;

            display_section (sections^ [i]);
          IFEND;
        FOREND;
      IFEND;

      next_module := next_module^.link;
    WHILEND;


  PROCEND display_section_usage;
?? OLDTITLE ??
?? NEWTITLE := '  OUT70', EJECT ??

  PROCEDURE [INLINE] out70
    (    strng: string (70));


    ocp$output ('     ', strng, 70, end_of_line);

  PROCEND out70;
?? OLDTITLE ??
?? NEWTITLE := '  SYMBOL_TABLE_DESC', EJECT ??

  PROCEDURE symbol_table_desc;

    out70 ('  Symbol table records can be extremely large and use up a            ');
    out70 ('considerable amount of disk space.  Modules with symbol tables        ');
    out70 ('also take slightly longer to load than modules without symbol         ');
    out70 ('tables.  However, removing symbol tables significantly reduces        ');
    out70 ('the ability to debug failures in a program.                           ');
    out70 ('                                                                      ');
    out70 ('  Symbol table records can be removed from a module by either         ');
    out70 ('recompiling the module specifying DEBUG_AIDS=NONE, or by using        ');
    out70 ('the CHANGE_MODULE_ATTRIBUTES subcommand of CREATE_OBJECT_LIBRARY      ');
    out70 ('specifying OMIT_DEBUG_TABLE=SYMBOL_TABLE.                             ');
    out70 ('                                                                      ');

  PROCEND symbol_table_desc;
?? OLDTITLE ??
?? NEWTITLE := '  LINE_TABLE_DESC', EJECT ??

  PROCEDURE line_table_desc;

    out70 ('  Line table records can be large and use up a considerable           ');
    out70 ('amount of disk space.  Modules with line tables also take             ');
    out70 ('slightly longer to load than modules without line tables.             ');
    out70 ('                                                                      ');
    out70 ('  Line table records can be removed from a module by either           ');
    out70 ('recompiling the module specifying DEBUG_AIDS=NONE, or by using        ');
    out70 ('the CHANGE_MODULE_ATTRIBUTES subcommand of CREATE_OBJECT_LIBRARY      ');
    out70 ('specifying OMIT_DEBUG_TABLE=LINE_TABLE.                               ');
    out70 ('                                                                      ');

  PROCEND line_table_desc;
?? OLDTITLE ??
?? NEWTITLE := '  SUPPLEMENTAL_DEBUG_TABLE_DESC', EJECT ??

  PROCEDURE supplemental_debug_table_desc;

    out70 ('  Supplemental debug table records can be large and use up a          ');
    out70 ('considerable amount of disk space.  Modules with supplemental         ');
    out70 ('debug tables also take slightly longer to load than modules           ');
    out70 ('without supplemental debug tables.                                    ');
    out70 ('                                                                      ');
    out70 ('  Supplemental debug table records can be removed from a module by    ');
    out70 ('either recompiling the module specifying DEBUG_AIDS=NONE, or by using ');
    out70 ('the CHANGE_MODULE_ATTRIBUTES subcommand of CREATE_OBJECT_LIBRARY      ');
    out70 ('specifying OMIT_DEBUG_TABLE=SUPPLEMENTAL_DEBUG_TABLE.                 ');
    out70 ('                                                                      ');

  PROCEND supplemental_debug_table_desc;
?? OLDTITLE ??
?? NEWTITLE := '  PARAMETER_CHECKING_DESC', EJECT ??

  PROCEDURE parameter_checking_desc;

    out70 ('  Parameter checking records can significantly increase the           ');
    out70 ('load time of a module.  Since the same information is checked         ');
    out70 ('every time a module is loaded, it is a good idea to turn off          ');
    out70 ('parameter checking before putting a large program into production.    ');
    out70 ('                                                                      ');
    out70 ('  Parameter checking records can be removed from a module by either   ');
    out70 ('recompiling the module specifying DEBUG_AIDS=NONE, or by using        ');
    out70 ('the CHANGE_MODULE_ATTRIBUTES subcommand of CREATE_OBJECT_LIBRARY      ');
    out70 ('specifying OMIT_DEBUG_TABLE=PARAMETER_CHECKING.                       ');
    out70 ('                                                                      ');

  PROCEND parameter_checking_desc;
?? OLDTITLE ??
?? NEWTITLE := '  RUNTIME_CHECKING_DESC', EJECT ??

  PROCEDURE runtime_checking_desc;

    out70 ('  Runtime range checking of variables, subscript expressions, and     ');
    out70 ('character substring expressions can significantly increase the        ');
    out70 ('execution time of a module.  The actual increase depends on the       ');
    out70 ('runtime checking options selected at compile time and the language    ');
    out70 ('the program is written in.                                            ');
    out70 ('                                                                      ');
    out70 ('  Runtime checking can be removed from a module by recompiling the    ');
    out70 ('module specifying RUNTIME_CHECKS=NONE.                                ');
    out70 ('                                                                      ');

  PROCEND runtime_checking_desc;
?? OLDTITLE ??
?? NEWTITLE := '  RUNTIME_LIBRARY_CALLS_DESC', EJECT ??

  PROCEDURE runtime_library_calls_desc;

    out70 ('  Modules which contain external references to runtime library        ');
    out70 ('routines take longer to load, and execute slower than a single        ');
    out70 ('module bound with the runtime library routines it calls.              ');
    out70 ('However, the bound module''s copy of the runtime library code          ');
    out70 ('is not sharable with other programs.                                  ');
    out70 ('                                                                      ');
    out70 ('  A bound module can be built using the CREATE_OBJECT_LIBRARY         ');
    out70 ('subcommands ADD_MODULE, DISPLAY_NEW_LIBRARY, SATISFY_EXTERNAL_        ');
    out70 ('REFERENCES, CREATE_MODULE, and GENERATE_LIBRARY.  The runtime         ');
    out70 ('libraries to specify on the SATISFY_EXTERNAL_REFERENCES command       ');
    out70 ('can be obtained by doing DISPLAY_NEW_LIBRARY DO=LIBRARY.              ');
    out70 ('                                                                      ');

  PROCEND runtime_library_calls_desc;
?? OLDTITLE ??
?? NEWTITLE := '  RUNTIME_LIBRARIES_DESC', EJECT ??

  PROCEDURE runtime_libraries_desc;

    out70 ('  Modules which contain text imbedded runtime library records         ');
    out70 ('take longer to load than modules without runtime library records.     ');
    out70 ('Any libraries which are not required during loading should be         ');
    out70 ('omitted.                                                              ');
    out70 ('                                                                      ');
    out70 ('  After all the runtime library calls from a module have been         ');
    out70 ('satisfied, runtime library records can be omitted using the           ');
    out70 ('CHANGE_MODULE_ATTRIBUTES subcommand of CREATE_OBJECT_LIBRARY          ');
    out70 ('specifying OMIT_LIBRARY=( list of libraries ).  The library names     ');
    out70 ('to omit can be obtained by doing DISPLAY_NEW_LIBRARY DO=LIBRARY.      ');
    out70 ('                                                                      ');

  PROCEND runtime_libraries_desc;
?? OLDTITLE ??
?? NEWTITLE := '  OPT_DEBUG_DESC', EJECT ??

  PROCEDURE opt_debug_desc;

    out70 ('  Object code which is generated at an optimization level of          ');
    out70 ('DEBUG executes slower than object code generated at optimization      ');
    out70 ('levels of LOW or HIGH.                                                ');
    out70 ('                                                                      ');
    out70 ('  Execution time can be reduced by recompiling the module             ');
    out70 ('specifying OPTIMIZATION=LOW or OPTIMIZATION=HIGH.                     ');
    out70 ('                                                                      ');

  PROCEND opt_debug_desc;
?? OLDTITLE ??
?? NEWTITLE := '  OPT_LOW_DESC', EJECT ??

  PROCEDURE opt_low_desc;

    out70 ('  Object code which is generated at an optimization level of          ');
    out70 ('LOW executes slower than object code generated at optimization        ');
    out70 ('level HIGH.                                                           ');
    out70 ('                                                                      ');
    out70 ('  Execution time can be reduced by recompiling the module             ');
    out70 ('specifying OPTIMIZATION=HIGH.                                         ');
    out70 ('                                                                      ');

  PROCEND opt_low_desc;
?? OLDTITLE ??
?? NEWTITLE := '  OBJECT_MODULES_DESC', EJECT ??

  PROCEDURE object_modules_desc;

    out70 ('  Modules which exist on object libraries will load faster and        ');
    out70 ('execute slightly faster than modules which exist on object            ');
    out70 ('files.  Also, the code and read only data in a module can be          ');
    out70 ('be shared when the module is on an object library.                    ');
    out70 ('                                                                      ');
    out70 ('  An object library can be created using the ADD_MODULE,              ');
    out70 ('CREATE_MODULE, or CREATE_LINKED_MODULE subcommands of the             ');
    out70 ('CREATE_OBJECT_LIBRARY utility.                                        ');
    out70 ('                                                                      ');

  PROCEND object_modules_desc;
?? OLDTITLE ??
?? NEWTITLE := '  LOAD_MODULES_DESC', EJECT ??

  PROCEDURE load_modules_desc;

    out70 ('  A program which is made up of a number of unbound load              ');
    out70 ('modules will take longer to load and will execute slower              ');
    out70 ('than a module which has been bound into a single bound                ');
    out70 ('module.                                                               ');
    out70 ('                                                                      ');
    out70 ('  A bound module can be created using the CREATE_MODULE               ');
    out70 ('subcommand of the CREATE_OBJECT_LIBRARY utility.                      ');
    out70 ('                                                                      ');

  PROCEND load_modules_desc;
?? OLDTITLE ??
?? NEWTITLE := '  BOUND_MODULES_DESC', EJECT ??

  PROCEDURE bound_modules_desc;

    out70 ('  A bound module that has been prelinked can take significantly       ');
    out70 ('less time to load than the original bound module.                     ');
    out70 ('                                                                      ');
    out70 ('  A prelinked module can be created using the CREATE_LINKED_MODULE    ');
    out70 ('subcommand of the CREATE_OBJECT_LIBRARY utility.                      ');
    out70 ('                                                                      ');

  PROCEND bound_modules_desc;
?? OLDTITLE ??
?? NEWTITLE := '  UNREFERENCED_SECTIONS_DESC', EJECT ??

  PROCEDURE unreferenced_sections_desc;

    out70 ('  Section definitions which are not initialized and are never         ');
    out70 ('referenced inside an object module, unnecessarily increase the        ');
    out70 ('load time of the module.                                              ');
    out70 ('                                                                      ');
    out70 ('  The source of the module can be changed to omit any references      ');
    out70 ('to the empty section, and then recompiled.  The unreferenced          ');
    out70 ('sections can be found by using the ANALYZE_OBJECT_LIBRARY             ');
    out70 ('subcommand DISPLAY_MODULE_ANALYSIS and specifying                     ');
    out70 ('DISPLAY_OPTION=SECTION_ANALYSIS.  Any sections that are not           ');
    out70 ('initialized, and contain no references to or in,  can be              ');
    out70 ('omitted.                                                              ');
    out70 ('                                                                      ');

  PROCEND unreferenced_sections_desc;
?? OLDTITLE ??
?? NEWTITLE := '  MULTIPLE_ENTRY_POINTS_DESC', EJECT ??

  PROCEDURE multiple_entry_points_desc;

    out70 ('  Unused entry points in an object module increase the load time      ');
    out70 ('of the module.                                                        ');
    out70 ('                                                                      ');
    out70 ('  Unused entry points can be omitted from a module by using the       ');
    out70 ('CREATE_OBJECT_LIBRARY subcommand CHANGE_MODULE_ATTRIBUTES and         ');
    out70 ('specifying OMIT=( list of entry points ).  A list of a module''s       ');
    out70 ('entry points can be obtained by entering DISPLAY_NEW_LIBRARY          ');
    out70 ('DO=ENTRY_POINT.                                                       ');

  PROCEND multiple_entry_points_desc;
?? OLDTITLE ??
?? NEWTITLE := '  DISPLAY_PROBLEM_MODULES', EJECT ??

  PROCEDURE display_problem_modules
    (    object_library: ^oct$object_library;
         problem: oct$anaol_performance_problem;
         display_options: oct$anaol_performance_options);


    VAR
      problem_list: [STATIC, READ] array [oct$anaol_performance_problem] of record
        strng: string (43),
        description: ^procedure,
      recend := [

      {} ['   Modules with SYMBOL_TABLES:             ', ^symbol_table_desc],
            {} ['   Modules with LINE_TABLES:               ', ^line_table_desc],
            {} ['   Modules with PARAMETER_CHECKING:        ', ^parameter_checking_desc],
            {} ['   Modules with RUNTIME_CHECKING:          ', ^runtime_checking_desc],
            {} ['   Modules with RUNTIME_LIBRARY_CALLS:     ', ^runtime_library_calls_desc],
            {} ['   Modules with RUNTIME_LIBRARIES:         ', ^runtime_libraries_desc],
            {} ['   Modules compiled at OPT_DEBUG:          ', ^opt_debug_desc],
            {} ['   Modules compiled at OPT_LOW:            ', ^opt_low_desc],
            {} ['   Modules that are OBJECT_MODULES:        ', ^object_modules_desc],
            {} ['   Modules that are LOAD_MODULES:          ', ^load_modules_desc],
            {} ['   Modules that are BOUND_MODULES:         ', ^bound_modules_desc],
            {} ['   Modules with UNREFERENCED_SECTIONS:     ', ^unreferenced_sections_desc],
            {} ['      with MULTIPLE_ENTRY_POINTS:          ', ^multiple_entry_points_desc],
            {} ['   Modules with SUPPLEMENTAL_DEBUG_TABLES: ', ^supplemental_debug_table_desc]];

?? EJECT ??

    VAR
      count: integer,
      next_module: ^oct$module_item;

    count := 0;
    next_module := object_library^.module_list^ [occ$head_of_list].link;

    WHILE (next_module <> NIL) DO
      IF (problem IN next_module^.record_analysis^.performance_problems) THEN
        count := count + 1;
      IFEND;

      next_module := next_module^.link;
    WHILEND;

    IF (count > 0) THEN
      IF (problem = occ$multiple_entry_points) THEN
        ocp$output ('   ', 'Bound or prelinked modules', 26, end_of_line);
      IFEND;

      STRINGREP (strng, lngth, count: 5);
      ocp$output (problem_list [problem].strng, strng, lngth, end_of_line);

      IF (occ$display_module_names IN display_options) THEN
        next_module := object_library^.module_list^ [occ$head_of_list].link;

        WHILE (next_module <> NIL) DO
          IF (problem IN next_module^.record_analysis^.performance_problems) THEN
            ocp$output ('     ', next_module^.name, #SIZE (next_module^.name), end_of_line);
          IFEND;
          next_module := next_module^.link;
        WHILEND;

        ocp$output (' ', ' ', 1, end_of_line);
      IFEND;

      IF (occ$display_description IN display_options) THEN
        problem_list [problem].description^;
      IFEND;
    IFEND;


  PROCEND display_problem_modules;
?? OLDTITLE ??
?? NEWTITLE := '  DISPLAY_PERFORMANCE_ANALYSIS', EJECT ??

  PROCEDURE display_performance_analysis
    (    object_library: ^oct$object_library;
         performance_problems: oct$anaol_performance_problems;
         display_options: oct$anaol_performance_options);

    VAR
      analysis_options: [STATIC, READ] oct$anaol_display_options := [occ$display_record_analysis],
      next_module: ^oct$module_item,
      problem: oct$anaol_performance_problem;


    next_module := object_library^.module_list^ [occ$head_of_list].link;

    WHILE (next_module <> NIL) DO
      ocp$analyze_load_module (object_library, next_module, analysis_options);

      next_module := next_module^.link;
    WHILEND;

    ocp$output (' ', ' ', 1, end_of_line);

    FOR problem := LOWERVALUE (oct$anaol_performance_problem) TO UPPERVALUE (oct$anaol_performance_problem) DO
      IF (problem IN performance_problems) THEN
        display_problem_modules (object_library, problem, display_options);
      IFEND;
    FOREND;

  PROCEND display_performance_analysis;
?? OLDTITLE ??
?? NEWTITLE := '  OCP$DISPLAY_LIBRARY_ANALYSIS', EJECT ??

  PROCEDURE [XDCL] ocp$display_library_analysis
    (    object_library: ^oct$object_library;
         display_options: oct$anaol_display_options;
         output: clt$file;
     VAR status: ost$status);


    VAR
      library_name: amt$local_file_name;


    pmp$get_last_path_name (object_library^.file.local_file_name, library_name, status);
    ocp$abort_if_abnormal_status (status);

    v$page_header (28, 31) := library_name;
    ocp$open_output_file (output.local_file_name, ^v$page_header, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    ocp$output ('1Library Analysis of ', library_name, #SIZE (library_name), end_of_line);

    display_library_analysis (object_library, display_options);

    ocp$output (' ', ' ', 1, end_of_line);

    ocp$close_output_file (status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;


  PROCEND ocp$display_library_analysis;
?? OLDTITLE ??
?? NEWTITLE := '  OCP$DISPLAY_MODULE_ANALYSIS', EJECT ??

  PROCEDURE [XDCL] ocp$display_module_analysis
    (    object_library: ^oct$object_library;
         display_options: oct$anaol_display_options;
         output: clt$file;
     VAR status: ost$status);


    pmp$get_last_path_name (object_library^.file.local_file_name, v$page_header (28, 31), status);
    ocp$abort_if_abnormal_status (status);

    ocp$open_output_file (output.local_file_name, ^v$page_header, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    display_module_analysis (object_library, display_options);

    ocp$output (' ', ' ', 1, end_of_line);

    ocp$close_output_file (status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;


  PROCEND ocp$display_module_analysis;
?? OLDTITLE ??
?? NEWTITLE := '  OCP$DISPLAY_SECTION_USAGE', EJECT ??

  PROCEDURE [XDCL] ocp$display_section_usage
    (    object_library: ^oct$object_library;
         section_kinds: oct$section_kinds;
         access_attributes: llt$section_access_attributes;
         section_name: pmt$program_name;
         output: clt$file;
     VAR status: ost$status);


    pmp$get_last_path_name (object_library^.file.local_file_name, v$page_header (28, 31), status);
    ocp$abort_if_abnormal_status (status);

    ocp$open_output_file (output.local_file_name, ^v$page_header, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    display_section_usage (object_library, section_kinds, access_attributes, section_name);

    ocp$output (' ', ' ', 1, end_of_line);

    ocp$close_output_file (status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;


  PROCEND ocp$display_section_usage;
?? OLDTITLE ??
?? NEWTITLE := '  OCP$DISPLAY_PERFORMANCE_ANAL', EJECT ??

  PROCEDURE [XDCL] ocp$display_performance_anal
    (    object_library: ^oct$object_library;
         performance_problems: oct$anaol_performance_problems;
         display_options: oct$anaol_performance_options;
         output: clt$file;
     VAR status: ost$status);


    VAR
      library_name: amt$local_file_name;


    pmp$get_last_path_name (object_library^.file.local_file_name, library_name, status);
    ocp$abort_if_abnormal_status (status);

    v$page_header (28, 31) := library_name;
    ocp$open_output_file (output.local_file_name, ^v$page_header, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    ocp$output ('1Performance Analysis of ', library_name, #SIZE (library_name), end_of_line);

    display_performance_analysis (object_library, performance_problems, display_options);

    ocp$output (' ', ' ', 1, end_of_line);

    ocp$close_output_file (status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;


  PROCEND ocp$display_performance_anal;
?? OLDTITLE ??
MODEND ocm$anaol_display_handlers;
