?? NEWTITLE := 'NOS/VE Job Scheduling : administer_display' ??
MODULE jmm$administer_display;

{ PURPOSE:
{   This modules contains the generic routines used to display objects
{   and attributes of objects from the scheduling profile.  All knowledge of
{   how to display an object and its attributes is kept here.
{
{ DESIGN:
{   Each entry point into this routine obtains the display file name,
{   opens the display file, obtains the objects to be displayed and
{   calls (if necessary) procedures to display the attributes of the object.
{
{ NOTES:
{   Objects are Job classes, service classes, etc.  Attributes are the
{   attributes of the job class, service class, etc.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc cyd$run_time_error_condition
*copyc jmc$class_names
*copyc jmc$job_management_id
*copyc jme$object_display_errors
*copyc jmt$profile_changes
*copyc jmt$profile_object_list
*copyc jmt$profile_set
?? POP ??
*copyc clp$build_standard_title
*copyc clp$close_display
*copyc clp$convert_integer_to_string
*copyc clp$evaluate_parameters
*copyc clp$horizontal_tab_display
*copyc clp$new_display_line
*copyc clp$open_display_reference
*copyc clp$put_display
*copyc clp$put_partial_display
*copyc clp$reset_for_next_display_page
*copyc clp$trimmed_string_size
*copyc jmp$get_object
*copyc jmp$get_attributes_for_display
*copyc jmp$internal_error
*copyc jmp$set_object_default
*copyc osp$disestablish_cond_handler
*copyc osp$establish_condition_handler
*copyc osp$format_message
*copyc osp$set_status_abnormal
*copyc osp$set_status_condition
*copyc osp$set_status_from_condition
*copyc pmp$continue_to_cause

*copyc jmv$dispatching_priority_names
*copyc jmv$object_definition
*copyc jmv$the_profile
*copyc jmv$working_storage
*copyc osv$upper_to_lower
?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??

  VAR
    object_name: [READ] array [jmt$profile_object_kinds] of string (20) :=
          ['Job Categories', 'Priorities', 'Output Categories', 'Reserved',
          'Controls', 'Job Classes', 'Service Classes', 'Output Classes',
          'Applications'],

    group_names: [READ] array [jmt$profile_group] of string (10) :=
          ['DEFINITION', 'CONTROL', 'LIMIT', 'MEMBERSHIP', 'PRIORITY',
          'STATISTIC', '-'];

  TYPE
    group_sets = array [jmt$profile_group] of jmt$profile_set;

?? NEWTITLE := 'display variables', EJECT ??

  VAR
    default_output_file: ^fst$file_reference := ^standard_output,
    display_control: clt$display_control,
    output_file_name: ^fst$file_reference,
    ring_attributes: [STATIC] amt$ring_attributes :=
          [osc$user_ring, osc$user_ring, osc$user_ring],
    standard_output: string (7) := '$OUTPUT';

*copy clv$display_variables
*copyc clp$new_page_procedure
?? OLDTITLE ??
?? OLDTITLE ??
?? NEWTITLE := 'put_subtitle', EJECT ??

{ PURPOSE:
{   Dummy routine for the display procedures to call when they wish to
{   display a subtitle.

  PROCEDURE put_subtitle
    (VAR display_control: clt$display_control;
     VAR status: ost$status);

  PROCEND put_subtitle;
?? TITLE := 'display_object_attribute', EJECT ??

{ PURPOSE:
{   Displays the attributes from a single object to the display file.
{
{ DESIGN:
{   The value must be a type to be displayed.  Each sub value of this type
{   is an attribute of the object so this routine displays the name of the
{   attribute, a ':' or '=', and then the value.  Each attribute is displayed
{   on a seperate line.  It calls a nested routine to display the value of
{   the object attribute since it is best done in a recursive manner.
{
{ NOTES:
{   The display file must be previously opened and the information on the
{   file kept in the variable 'display_control'.

  PROCEDURE display_object_attribute
    (    object_attributes: jmt$object_attribute;
         attributes_to_display: jmt$profile_set;
         attribute_structure: jmt$profile_declaration;
         sorted_parameters: jmt$object_parameter_list;
         suppress_empty_attributes: boolean;
         building_command_file: boolean;
     VAR status: ost$status);

?? NEWTITLE := 'display_item', EJECT ??

{ PURPOSE:
{   Used by the enclosing procedure to display the attributes for an attribute
{   of an object.
{
{ DESIGN:
{   A value is displayed according to its contained type.  Structured types
{   like lists, types, and ranges are displayed by recursively calling this
{   routine to display the sub attributes.  Before an atomic value is written
{   to the display the routine ensures that it will fit on the line and starts
{   a new line if necessary.  A new line is started for a list or type if
{   the current position is too close to the end of the line in order to
{   keep most structures together in the display.  If a new line is started
{   and the building_command_file flag is true it writes an elipsis at the
{   end of the previous line (for command language compatible input).

    PROCEDURE display_item
      (    object_attributes: jmt$object_attribute;
       VAR status: ost$status);

      VAR
        dispatching_priority_name: ost$name,
        display_line: ost$string,
        i: integer;

      CASE object_attributes.kind OF

      = jmc$list, jmc$type, jmc$editable_list =
        IF UPPERBOUND (object_attributes.attribute_list^) = 1 THEN
          IF object_attributes.attribute_list^ [1].kind > jmc$range THEN
            display_item (object_attributes.attribute_list^ [1], status);
            RETURN;
          IFEND;
        IFEND;

        IF display_control.column_number > 40 THEN
          clp$put_partial_display (display_control, '..', clc$no_trim,
                amc$terminate, status);
          clp$horizontal_tab_display (display_control, 10, status);
        IFEND;

        display_line.value (1) := '(';
        display_line.size := 1;
        FOR i := 1 TO UPPERBOUND (object_attributes.attribute_list^) DO
          clp$put_partial_display (display_control, display_line.value (1, 1),
                clc$no_trim, amc$continue, status);
          display_item (object_attributes.attribute_list^ [i], status);
          display_line.value (1) := ' ';
        FOREND;
        display_line.value (1) := ')';

      = jmc$range =
        display_item (object_attributes.attribute_list^ [1], status);
        IF object_attributes.attribute_list^ [2].kind <> jmc$empty THEN
          clp$put_partial_display (display_control, '..', clc$no_trim,
                amc$continue, status);
          display_item (object_attributes.attribute_list^ [2], status);
        IFEND;
        RETURN;

      = jmc$object =
        display_line.size := clp$trimmed_string_size
              (object_attributes.object_p^.name);
        #TRANSLATE (osv$upper_to_lower, object_attributes.object_p^.name,
              display_line.value (1, display_line.size));

      = jmc$number =
        clp$convert_integer_to_string (object_attributes.number, 10, FALSE,
              display_line, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

      = jmc$boolean =
        display_line.size := 5;
        display_line.value (1, 5) := 'false';
        IF object_attributes.bool THEN
          display_line.size := 4;
          display_line.value (1, 4) := 'true';
        IFEND;

      = jmc$file =
        #TRANSLATE (osv$upper_to_lower, object_attributes.file^,
              display_line.value);
        display_line.size := clp$trimmed_string_size (display_line.value);

      = jmc$name =
        display_line.size := clp$trimmed_string_size (object_attributes.name^);
        #TRANSLATE (osv$upper_to_lower, object_attributes.name^,
              display_line.value (1, display_line.size));

      = jmc$dispatching_priority =
        dispatching_priority_name := 'UNKNOWN';
        IF ((LOWERBOUND (jmv$dispatching_priority_names) <=
              object_attributes.number) AND (object_attributes.
              number <= UPPERBOUND (jmv$dispatching_priority_names))) THEN
          dispatching_priority_name := jmv$dispatching_priority_names [
                object_attributes.number];
        IFEND;
        display_line.size := clp$trimmed_string_size
              (dispatching_priority_name);
        #TRANSLATE (osv$upper_to_lower, dispatching_priority_name,
              display_line.value);

      = jmc$unspecified =
        display_line.size := 11;
        display_line.value := 'unspecified';

      = jmc$default =
        display_line.size := 7;
        display_line.value := 'default';

      = jmc$all =
        display_line.size := 3;
        display_line.value := 'all';

      = jmc$none =
        display_line.size := 4;
        display_line.value := 'none';

      = jmc$system_default =
        display_line.size := 14;
        display_line.value := 'system_default';

      = jmc$unlimited =
        display_line.size := 9;
        display_line.value := 'unlimited';

      = jmc$empty =
        display_line.size := 7;
        display_line.value := 'default';
      CASEND;
      IF (display_control.column_number + display_line.size) >
            (display_control.page_width - 3) THEN
        clp$put_partial_display (display_control, '..', clc$no_trim,
              amc$terminate, status);
        clp$horizontal_tab_display (display_control, 10, status);
      IFEND;
      clp$put_partial_display (display_control, display_line.
            value (1, display_line.size), clc$no_trim, amc$continue, status);
    PROCEND display_item;
?? OLDTITLE ??
?? NEWTITLE := 'display_complex_item', EJECT ??

    PROCEDURE display_complex_item
      (    object_attributes: jmt$object_attribute;
           attribute_structure: jmt$profile_declaration;
           depth: integer;
       VAR status: ost$status);

      VAR
        display_line: string (40),
        j: integer,
        i: integer;

      CASE object_attributes.kind OF

      = jmc$list =
        IF attribute_structure.declarations^ [1]^.kind > jmc$range THEN
          clp$horizontal_tab_display (display_control, 43, status);
          clp$put_partial_display (display_control, ': ', clc$no_trim,
                amc$continue, status);
          display_item (object_attributes, status);
          RETURN;
        IFEND;

        FOR i := 1 TO UPPERBOUND (object_attributes.attribute_list^) DO
          clp$put_partial_display (display_control, ' ', clc$no_trim,
                amc$terminate, status);
          clp$horizontal_tab_display (display_control, 2 * depth, status);
          STRINGREP (display_line, j, '[', i, ']');
          clp$put_partial_display (display_control, display_line (1, j),
                clc$no_trim, amc$continue, status);
          display_complex_item (object_attributes.attribute_list^ [i],
                attribute_structure.declarations^ [1]^, depth + 1, status);
        FOREND;

      = jmc$editable_list =
        IF attribute_structure.declarations^ [1]^.kind > jmc$range THEN
          clp$horizontal_tab_display (display_control, 43, status);
          clp$put_partial_display (display_control, ': ', clc$no_trim,
                amc$continue, status);
          display_item (object_attributes, status);
          RETURN;
        IFEND;

        FOR i := 1 TO UPPERBOUND (object_attributes.attribute_list^) DO
          IF i > 1 THEN
            clp$put_partial_display (display_control, ' ', clc$no_trim,
                  amc$terminate, status);
            clp$horizontal_tab_display (display_control, 2 * depth + 2,
                  status);
            clp$put_partial_display (display_control, '-', clc$no_trim,
                  amc$continue, status);
          IFEND;
          display_complex_item (object_attributes.attribute_list^ [i],
                attribute_structure.declarations^ [1]^, depth, status);
        FOREND;

      = jmc$type =
        FOR i := 1 TO UPPERBOUND (object_attributes.attribute_list^) DO
          clp$put_partial_display (display_control, ' ', clc$no_trim,
                amc$terminate, status);
          clp$horizontal_tab_display (display_control, 2 * depth, status);
          display_line := attribute_structure.declarations^ [i]^.name;
          clp$put_partial_display (display_control, display_line, clc$trim,
                amc$continue, status);
          display_complex_item (object_attributes.attribute_list^ [i],
                attribute_structure.declarations^ [i]^, depth + 1, status);
        FOREND;

      ELSE
        clp$horizontal_tab_display (display_control, 43, status);
        clp$put_partial_display (display_control, ': ', clc$no_trim,
              amc$continue, status);
        display_item (object_attributes, status);
      CASEND;
    PROCEND display_complex_item;
?? OLDTITLE, EJECT ??

    VAR
      display_line: string (50),
      something_displayed: boolean,
      j: integer,
      i: integer;

    status.normal := TRUE;
    IF object_attributes.kind <> jmc$type THEN
      RETURN;
    IFEND;

    IF attributes_to_display = $jmt$profile_set [] THEN
      RETURN;
    IFEND;

    something_displayed := FALSE;

  /display_attributes/
    FOR j := 1 TO UPPERBOUND (sorted_parameters) DO
      IF sorted_parameters [j].abbreviation THEN
        CYCLE /display_attributes/;
      IFEND;
      i := sorted_parameters [j].attribute_index;

      IF NOT (i IN attributes_to_display) OR
            (attribute_structure.declarations^ [i]^.kind = jmc$empty) THEN
        CYCLE /display_attributes/;
      IFEND;

      IF (object_attributes.attribute_list^ [i].kind = jmc$empty) OR
            (object_attributes.attribute_list^ [i].kind = jmc$default) THEN
        IF (attribute_structure.declarations^ [i]^.group =
              jmc$statistic_group) OR suppress_empty_attributes THEN
          CYCLE /display_attributes/;
        IFEND;
      IFEND;
      something_displayed := TRUE;
      IF building_command_file THEN
        display_line := ' ';
        display_line (2, * ) := '..';
        clp$put_partial_display (display_control, display_line (1, 3),
              clc$no_trim, amc$continue, status);
      IFEND;
      display_line := ' ';
      display_line (4, * ) := attribute_structure.declarations^ [i]^.name;
      IF building_command_file THEN
        display_line (35, 1) := '=';
        clp$put_partial_display (display_control, display_line (1, 36),
              clc$no_trim, amc$start, status);
        display_item (object_attributes.attribute_list^ [i], status);
      ELSE
        clp$put_partial_display (display_control, display_line (1, 36),
              clc$trim, amc$start, status);
        display_complex_item (object_attributes.attribute_list^ [i],
              attribute_structure.declarations^ [i]^, 3, status);
      IFEND;
    FOREND /display_attributes/;
    IF something_displayed THEN
      clp$put_partial_display (display_control, ' ', clc$trim, amc$terminate,
            status);
    IFEND;

  PROCEND display_object_attribute;
?? TITLE := 'get_attributes', EJECT ??

{ PURPOSE:
{   Determine which attributes were specified on the DISPLAY_OPTIONS parameter
{   of the display command.
{
{ DESIGN:
{   For each name specified on the DISPLAY_OPTIONS parameter compare it
{   against the parameter names and abbreviations in the provided declaration.
{   The result is returned as a set.  The option 'ALL' is treated as a
{   special case.

  PROCEDURE get_attributes
    (    attribute_list: ^clt$data_value;
         sorted_parameters: jmt$object_parameter_list;
     VAR attributes_to_display: jmt$profile_set;
     VAR status: ost$status);

    VAR
      temp: integer,
      high_index: jmt$object_attribute_index,
      list_item: ^clt$data_value,
      low_index: jmt$object_attribute_index,
      middle_index: jmt$object_attribute_index,
      i: integer;

    attributes_to_display := $jmt$profile_set [];

{ Check if the keyword ALL was given (or no default and not specified).

    IF (attribute_list = NIL) OR (attribute_list^.kind = clc$keyword) THEN
      attributes_to_display := -$jmt$profile_set [];
      RETURN;
    IFEND;

    list_item := attribute_list;

  /found/
    WHILE list_item <> NIL DO
      high_index := UPPERBOUND (sorted_parameters);
      low_index := 1;
      REPEAT
        temp := high_index + low_index;
        middle_index := temp DIV 2;
        IF sorted_parameters [middle_index].name <
              list_item^.element_value^.name_value THEN
          low_index := middle_index + 1;
        ELSEIF sorted_parameters [middle_index].name >
              list_item^.element_value^.name_value THEN
          high_index := middle_index - 1;
        ELSE
          attributes_to_display := attributes_to_display +
                $jmt$profile_set [sorted_parameters [middle_index].
                attribute_index];
          list_item := list_item^.link;
          CYCLE /found/;
        IFEND;
      UNTIL low_index > high_index;
      osp$set_status_abnormal (jmc$job_management_id, jme$unknown_attribute,
            list_item^.element_value^.name_value, status);
      RETURN;
    WHILEND /found/;

  PROCEND get_attributes;
?? TITLE := 'get_group', EJECT ??

{ PURPOSE:
{   Determine which groups were specified on the GROUP_OPTION parameter of a
{   display command.
{
{ DESIGN:
{   Each name specified on the GROUP_OPTION parameter is searched for in the
{   list of group names.  Finding a name sets the appropriate bit in a set.
{   ALL causes all bits to be set.  Then the attributes are scanned and
{   a bit is set for the attribute in the set it belongs to.  The sets for
{   the selected groups are returned.

  PROCEDURE get_group
    (    group_list: ^clt$data_value;
         attribute_structure: jmt$profile_declaration;
     VAR groups_to_display: group_sets;
     VAR status: ost$status);

    VAR
      group: jmt$profile_group,
      i: integer,
      list_item: ^clt$data_value,
      selected_groups: jmt$group_set;

    selected_groups := $jmt$group_set [];

    FOR group := LOWERVALUE (group) TO UPPERVALUE (group) DO
      groups_to_display [group] := $jmt$profile_set [];
    FOREND;

    FOR i := 1 TO UPPERBOUND (attribute_structure.declarations^) DO
      group := attribute_structure.declarations^ [i]^.group;
      groups_to_display [group] := groups_to_display [group] +
            $jmt$profile_set [i];
    FOREND;

    IF group_list^.kind = clc$keyword {ALL} THEN
      RETURN;
    IFEND;

    list_item := group_list;

  /found/
    WHILE list_item <> NIL DO

      FOR group := LOWERVALUE (group) TO UPPERVALUE (group) DO
        IF (group_names [group] = list_item^.element_value^.name_value) THEN
          selected_groups := selected_groups + $jmt$group_set [group];
          list_item := list_item^.link;
          CYCLE /found/;
        IFEND;
      FOREND;
      osp$set_status_abnormal (jmc$job_management_id, jme$unknown_group_name,
            list_item^.element_value^.name_value, status);
      RETURN;
    WHILEND /found/;

    FOR group := LOWERVALUE (group) TO UPPERVALUE (group) DO
      IF NOT (group IN selected_groups) THEN
        groups_to_display [group] := $jmt$profile_set [];
      IFEND;
    FOREND;

  PROCEND get_group;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] jmp$_change_list_option', EJECT ??

{ PURPOSE:
{   This interface processes the CHANGE_LIST_OPTION command for the utility.
{   This command causes all the utility sub commands to redirect their output
{   to an alternate list file.
{
{ DESIGN:
{   If the OUTPUT parameter is specified then save that file as the new
{   default output file.

  PROCEDURE [XDCL] jmp$_change_list_option
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE (osm$adms_chalo) change_list_option (
{   output, o: file = $optional
{   status)

?? PUSH (LISTEXT := ON) ??

    VAR
      pdt: [STATIC, READ, cls$declaration_section] record
        header: clt$pdt_header,
        names: array [1 .. 3] of clt$pdt_parameter_name,
        parameters: array [1 .. 2] of clt$pdt_parameter,
        type1: record
          header: clt$type_specification_header,
        recend,
        type2: record
          header: clt$type_specification_header,
        recend,
      recend := [[1, [88, 9, 26, 10, 34, 51, 457], clc$command, 3, 2, 0, 0, 0,
            0, 2, 'OSM$ADMS_CHALO'], [['O                              ',
            clc$abbreviation_entry, 1], ['OUTPUT                         ',
            clc$nominal_entry, 1], ['STATUS                         ',
            clc$nominal_entry, 2]], [

{ PARAMETER 1

      [2, clc$normal_usage_entry, clc$non_secure_parameter,
            $clt$parameter_spec_methods [clc$specify_by_name,
            clc$specify_positionally], clc$pass_by_value,
            clc$immediate_evaluation, clc$standard_parameter_checking, 3,
            clc$optional_parameter, 0, 0],

{ PARAMETER 2

      [3, clc$normal_usage_entry, clc$non_secure_parameter,
            $clt$parameter_spec_methods [clc$specify_by_name],
            clc$pass_by_reference, clc$immediate_evaluation,
            clc$standard_parameter_checking, 3, clc$optional_parameter, 0, 0]],

{ PARAMETER 1

      [[1, 0, clc$file_type]],

{ PARAMETER 2

      [[1, 0, clc$status_type]]];

?? POP ??

    CONST
      p$output = 1,
      p$status = 2;

    VAR
      pvt: array [1 .. 2] of clt$parameter_value;

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF pvt [p$output].specified THEN
      IF default_output_file <> ^standard_output THEN
        FREE default_output_file;
      IFEND;
      ALLOCATE default_output_file: [STRLENGTH (pvt [p$output].value^.
            file_value^)];
      default_output_file^ := pvt [p$output].value^.file_value^;
    IFEND;

  PROCEND jmp$_change_list_option;
?? TITLE := '[XDCL, #GATE] jmp$display_objects', EJECT ??

{ PURPOSE:
{   This routine is called to display a list of objects.
{
{ DESIGN:
{   It obtains the set of attributes to display, opens the display file,
{   and then displays each selected object using the nested routine.
{
{ NOTES:
{   The attributes are selected by the SCL parameter DISPLAY_OPTIONS
{   which is interpreted by this command.  The file used for the display
{   is obtained from the 'OUTPUT' parameter.
{
{   Attributes are displayed in the order of the attributes as stored
{   in the object attributes and not the order that the user specified on the
{   DISPLAY_OPTIONS parameter.

  PROCEDURE [XDCL, #GATE] jmp$display_objects
    (    object_kind: jmt$profile_object_kinds;
         suppress_empty_attributes: boolean;
         object_names: clt$parameter_value;
         attribute_parameter: clt$parameter_value;
         group_parameter: clt$parameter_value;
         output_parameter: clt$parameter_value;
     VAR status: ost$status);

    VAR
      attributes_to_display: jmt$profile_set,
      first_display_line: boolean,
      groups_to_display: group_sets;

?? NEWTITLE := 'abort_handler', EJECT ??

{   PURPOSE:
{     This procedure traps conditions which should abort the display being
{     generated.  In the event the display processor unexpectedly exits, it
{     cleans up by closing the display file.
{     Conditions to abort for are: system, segment access, cybil run time,
{     and interactive terminate break.

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      IF (condition.selector = pmc$system_conditions) OR
            (condition.selector = mmc$segment_access_condition) OR
            ((condition.selector = pmc$user_defined_condition) AND
            (condition.user_condition_name = cye$run_time_condition)) OR
            ((condition.selector = ifc$interactive_condition) AND
            (condition.interactive_condition = ifc$terminate_break)) THEN
        osp$set_status_from_condition (jmc$job_management_id, condition,
              save_area, handler_status, status);
        EXIT jmp$display_objects;
      ELSEIF (condition.selector = pmc$block_exit_processing) THEN
        clp$close_display (display_control, ignore_status);
        RETURN;
      IFEND;

      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);

    PROCEND abort_handler;
?? OLDTITLE ??
?? NEWTITLE := 'display_object_by_attribute', EJECT ??

{ PURPOSE:
{   Displays the attributes for a specific object.
{
{ DESIGN:
{   This routine requests the object's displayable_attributes for this kind
{   of object and then displays this fully specified attribute structure
{   Any objects immediatly following the specified object in the list with
{   the same name are also displayed since they are part of this object's
{   definition on the profile.

    PROCEDURE display_object_by_attribute
      (VAR the_object: jmt$profile_object_reference;
       VAR status: ost$status);

      VAR
        display_line: string (256),
        displayable_attributes: jmt$object_attribute,
        i: integer,
        name: ost$name;

      RESET jmv$working_storage;
      name := the_object^.name;
      IF NOT first_display_line THEN
        clp$new_display_line (display_control, 1, status);
      IFEND;
      first_display_line := FALSE;
      display_line := ' ';
      #TRANSLATE (osv$upper_to_lower, the_object^.name, display_line (2, 31));
      REPEAT
        clp$put_display (display_control, display_line, clc$trim, status);
        IF suppress_empty_attributes THEN
          displayable_attributes := the_object^.attributes;
        ELSE
          jmp$get_attributes_for_display (jmv$the_profile, the_object^,
                displayable_attributes, status);
        IFEND;
        display_object_attribute (displayable_attributes,
              attributes_to_display, attribute_structure, sorted_parameters^,
              suppress_empty_attributes, FALSE, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        the_object := the_object^.next_object;
      UNTIL (the_object = NIL) OR (the_object^.name <> name);
    PROCEND display_object_by_attribute;
?? TITLE := 'display_object_by_group', EJECT ??

{ PURPOSE:
{   Displays the attributes for a specific object by groups.
{
{ DESIGN:
{   This routine merges the object's attributes with the default attributes for
{   this kind of object and calls a routine to display this fully specified
{   value structure.  Any objects immediatly following the specified object
{   in the list with the same name are also displayed since they are
{   part of this object's definition on the profile.

    PROCEDURE display_object_by_group
      (VAR the_object: jmt$profile_object_reference;
       VAR status: ost$status);

      VAR
        group_names: [STATIC, READ] array [jmt$profile_group] of string (16) :=
              ['Definition Group', 'Control Group', 'Limit Group',
              'Membership Group', 'Priority Group', 'Statistic Group', '-'];

      VAR
        attributes: jmt$object_attribute,
        display_group: jmt$profile_group,
        display_line: string (34),
        group_display_line: string (20),
        i: integer,
        name: ost$name;

      RESET jmv$working_storage;
      IF NOT first_display_line THEN
        clp$new_display_line (display_control, 1, status);
      IFEND;
      first_display_line := FALSE;
      name := the_object^.name;
      display_line := ' ';
      #TRANSLATE (osv$upper_to_lower, the_object^.name, display_line (2, 31));
      REPEAT
        clp$put_display (display_control, display_line, clc$trim, status);
        IF suppress_empty_attributes THEN
          attributes := the_object^.attributes;
        ELSE
          jmp$get_attributes_for_display (jmv$the_profile, the_object^,
                attributes, status);
        IFEND;
        group_display_line := ' ';
        FOR display_group := LOWERVALUE (display_group)
              TO UPPERVALUE (display_group) DO
          IF groups_to_display [display_group] <> $jmt$profile_set [] THEN
            group_display_line (3, * ) := group_names [display_group];
            clp$put_display (display_control, group_display_line, clc$trim,
                  status);
            display_object_attribute (attributes,
                  groups_to_display [display_group], attribute_structure,
                  sorted_parameters^, suppress_empty_attributes, FALSE,
                  status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
          IFEND;
        FOREND;
        the_object := the_object^.next_object;
      UNTIL (the_object = NIL) OR (the_object^.name <> name);
    PROCEND display_object_by_group;
?? OLDTITLE, EJECT ??

    VAR
      attribute_list: clt$parameter_value,
      attribute_structure: jmt$profile_declaration,
      do_not_care: jmt$profile_object_reference,
      group_list: clt$parameter_value,
      object_list: ^clt$data_value,
      output_file: clt$parameter_value,
      sorted_parameters: ^jmt$object_parameter_list,
      the_object: jmt$profile_object_reference;

    VAR
      display_routine: ^procedure (VAR the_object: jmt$profile_object_reference
                                       ;
                                   VAR status: ost$status);

    attribute_structure := jmv$object_definition [object_kind].declaration;
    sorted_parameters := jmv$object_definition [object_kind].sorted_parameters;

    IF NOT group_parameter.specified THEN
      get_attributes (attribute_parameter.value, sorted_parameters^,
            attributes_to_display, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      display_routine := ^display_object_by_attribute;
      clv$command_name := 'Display of ';
      clv$command_name (12, * ) := object_name [object_kind];
    ELSEIF NOT attribute_parameter.specified THEN
      get_group (group_parameter.value, attribute_structure, groups_to_display,
            status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      display_routine := ^display_object_by_group;
      clv$command_name := 'Display by group of ';
      clv$command_name (21, * ) := object_name [object_kind];
    ELSE
      osp$set_status_condition (jme$cant_specify_both_do_and_go, status);
      RETURN;
    IFEND;

    output_file_name := default_output_file;
    IF output_parameter.specified THEN
      output_file_name := output_parameter.value^.file_value;
    IFEND;

    clp$open_display_reference (output_file_name^, ^clp$new_page_procedure,
          fsc$list, ring_attributes, display_control, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    osp$establish_condition_handler (^abort_handler, TRUE);
    first_display_line := TRUE;
    clv$titles_built := FALSE;

    object_list := object_names.value;
    IF object_list^.kind = clc$name THEN
      jmp$get_object (object_list^.name_value, object_kind, the_object,
            do_not_care, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      display_routine^ (the_object, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

    ELSEIF object_list^.kind = clc$list THEN
      WHILE object_list <> NIL DO
        IF object_list^.element_value <> NIL THEN
          jmp$get_object (object_list^.element_value^.name_value, object_kind,
                the_object, do_not_care, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
          display_routine^ (the_object, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
          object_list := object_list^.link;
        IFEND;
      WHILEND;

    ELSEIF object_list^.kind = clc$keyword {ALL} THEN
      the_object := jmv$the_profile.objects [object_kind];
      WHILE the_object <> NIL DO
        display_routine^ (the_object, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      WHILEND;
    IFEND;
    jmp$set_object_default (object_kind, object_names.value);

    clp$close_display (display_control, status);
    osp$disestablish_cond_handler;

  PROCEND jmp$display_objects;
?? TITLE := '[XDCL] jmp$display_profile_changes', EJECT ??

{ PURPOSE:
{   Displays the changes in when a profile is activated.

  PROCEDURE [XDCL] jmp$display_profile_changes
    (    the_changes: jmt$profile_changes;
         output_file: clt$parameter_value;
     VAR status: ost$status);

    VAR
      first_display_line: boolean;

?? NEWTITLE := 'abort_handler', EJECT ??

{   PURPOSE:
{     This procedure traps conditions which should abort the display being
{     generated.  In the event the display processor unexpectedly exits, it
{     cleans up by closing the display file.
{     Conditions to abort for are: system, segment access, cybil run time,
{     and interactive terminate break.

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      IF (condition.selector = pmc$system_conditions) OR
            (condition.selector = mmc$segment_access_condition) OR
            ((condition.selector = pmc$user_defined_condition) AND
            (condition.user_condition_name = cye$run_time_condition)) OR
            ((condition.selector = ifc$interactive_condition) AND
            (condition.interactive_condition = ifc$terminate_break)) THEN
        osp$set_status_from_condition (jmc$job_management_id, condition,
              save_area, handler_status, status);
        EXIT jmp$display_profile_changes;
      ELSEIF (condition.selector = pmc$block_exit_processing) THEN
        clp$close_display (display_control, ignore_status);
        RETURN;
      IFEND;

      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);

    PROCEND abort_handler;
?? OLDTITLE ??
?? NEWTITLE := 'display_job_list', EJECT ??

{ PURPOSE:
{   Displays a list of jobs with the specified title if the list is not
{   empty.  If the list is empty then nothing is displayed.
{
{ DESIGN:
{   If status of the resubmit of a job was normal then just the name
{   is displayed.  If the status was abnormal then the message
{      'resubmit fail with status'
{   is displayed on the same line as the job name and the status
{   from the resubmit is displayed in the following lines.

    PROCEDURE display_job_list
      (    job_list: jmt$resubmitted_job_list;
           title: string ( * );
       VAR status: ost$status);

      VAR
        display_line: string (clc$wide_page_width),
        message_data: ^ost$status_message,
        message_line_size: ^ost$status_message_line_size,
        message_line_count: ^ost$status_message_line_count,
        message_line_text: ^ost$status_message_line,
        line_index: 1 .. osc$max_status_message_lines,
        i: integer;

      IF job_list = NIL THEN
        RETURN;
      IFEND;

      display_line := ' ';
      PUSH message_data;
      IF NOT first_display_line THEN
        clp$new_display_line (display_control, 1, status);
      IFEND;
      first_display_line := FALSE;

      clp$put_display (display_control, title, clc$trim, status);
      FOR i := 1 TO UPPERBOUND (job_list^) DO
        display_line (4, * ) := job_list^ [i].job_name;
        IF job_list^ [i].status.normal THEN
          clp$put_display (display_control, display_line, clc$trim, status);
        ELSE
          display_line (25, * ) := 'Resubmit failed with status';
          clp$put_display (display_control, display_line, clc$trim, status);
          display_line := ' ';
          osp$format_message (job_list^ [i].status, osc$full_message_level,
                display_control.page_width - 4, message_data^, status);
          RESET message_data;
          NEXT message_line_count IN message_data;
          IF message_line_count = NIL THEN
            jmp$internal_error (30);
          IFEND;
          FOR line_index := 1 TO message_line_count^ DO
            NEXT message_line_size IN message_data;
            IF message_line_size = NIL THEN
              jmp$internal_error (31);
            IFEND;
            NEXT message_line_text: [message_line_size^] IN message_data;
            IF message_line_text = NIL THEN
              jmp$internal_error (32);
            IFEND;
            display_line (4, * ) := message_line_text^;
            clp$put_display (display_control, display_line, clc$trim, status);
          FOREND;
        IFEND;
      FOREND;
    PROCEND display_job_list;
?? TITLE := 'display_name_list', EJECT ??

{ PURPOSE:
{   Displays a list of names with the specified title if the list is not
{   empty.  If the list is empty then nothing at all is displayed.
{
{ NOTE:
{   Duplicate names are suppressed.

    PROCEDURE display_name_list
      (    name_list: jmt$object_name_list;
           title: string ( * );
       VAR status: ost$status);

      VAR
        display_line: string (40),
        previous_name: ost$name,
        i: integer;

      IF name_list = NIL THEN
        RETURN;
      IFEND;

      previous_name := osc$null_name;

      display_line := ' ';
      IF NOT first_display_line THEN
        clp$new_display_line (display_control, 1, status);
      IFEND;
      first_display_line := FALSE;

      clp$put_display (display_control, title, clc$trim, status);
      FOR i := 1 TO UPPERBOUND (name_list^) DO
        IF name_list^ [i] <> previous_name THEN
          previous_name := name_list^ [i];
          #TRANSLATE (osv$upper_to_lower, name_list^ [i], display_line (4,
                31));
          clp$put_display (display_control, display_line, clc$trim, status);
        IFEND;
      FOREND;
    PROCEND display_name_list;
?? OLDTITLE, EJECT ??

    VAR
      title_line: string (80),
      i: integer,
      j: integer;

    VAR
      object_kind_list: [STATIC] array [1 .. 6] of
            jmt$profile_object_kinds := [jmc$profile_category,
            jmc$profile_controls, jmc$profile_job_class,
            jmc$profile_service_class, jmc$profile_output_class,
            jmc$profile_application];

    output_file_name := default_output_file;
    IF output_file.specified THEN
      output_file_name := output_file.value^.file_value;
    IFEND;

    first_display_line := TRUE;

    clp$open_display_reference (output_file_name^, ^clp$new_page_procedure,
          fsc$list, ring_attributes, display_control, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    osp$establish_condition_handler (^abort_handler, TRUE);
    clv$titles_built := FALSE;
    clv$command_name := 'Activate Profile';

    FOR i := 1 TO UPPERBOUND (object_kind_list) DO
      STRINGREP (title_line, j, ' New ', object_name [object_kind_list [i]]);
      display_name_list (the_changes.objects_changed [object_kind_list [i]].
            new_objects, title_line (1, j), status);
      STRINGREP (title_line, j, ' Changed ',
            object_name [object_kind_list [i]]);
      display_name_list (the_changes.objects_changed [object_kind_list [i]].
            changed_objects, title_line (1, j), status);
      STRINGREP (title_line, j, ' Deleted ',
            object_name [object_kind_list [i]]);
      display_name_list (the_changes.objects_changed [object_kind_list [i]].
            deleted_objects, title_line (1, j), status);
    FOREND;
    title_line := ' All jobs in the following Job Classes were resubmitted.';
    display_name_list (the_changes.move_classes, title_line, status);
    title_line := ' The following jobs were resubmitted.';
    display_job_list (the_changes.resubmitted_jobs, title_line, status);
    IF NOT first_display_line THEN
      clp$new_display_line (display_control, 1, status);
    IFEND;
    clp$put_display (display_control, ' Profile activation complete.',
          clc$trim, status);
    clp$close_display (display_control, status);
    osp$disestablish_cond_handler;

  PROCEND jmp$display_profile_changes;
?? TITLE := '[XDCL] jmp$_display_profile_summary', EJECT ??

{ PURPOSE:
{   Displays the names of all objects on the profile by object type.
{
{ DESIGN:
{   For each object type display the name of this type of object and
{   then the name of each object of that type.  The names are displayed
{   in the order they are on the profile.

  PROCEDURE [XDCL] jmp$_display_profile_summary
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE (osm$adms_disps) display_profile_summary (
{   display_options, do: any of
{     key all keyend
{     list of key
{       (job_category, jca)
{       (controls, c)
{       (job_class, jcl)
{       (service_class, sc)
{       (application, a)
{     keyend
{    anyend = all
{   output, o: (by_name) file = $optional
{   status)

?? PUSH (LISTEXT := ON) ??

    VAR
      pdt: [STATIC, READ, cls$declaration_section] record
        header: clt$pdt_header,
        names: array [1 .. 5] of clt$pdt_parameter_name,
        parameters: array [1 .. 3] of clt$pdt_parameter,
        type1: record
          header: clt$type_specification_header,
          qualifier: clt$union_type_qualifier,
          type_size_1: clt$type_specification_size,
          element_type_spec_1: record
            header: clt$type_specification_header,
            qualifier: clt$keyword_type_qualifier,
            keyword_specs: array [1 .. 1] of clt$keyword_specification,
          recend,
          type_size_2: clt$type_specification_size,
          element_type_spec_2: record
            header: clt$type_specification_header,
            qualifier: clt$list_type_qualifier,
            element_type_spec: record
              header: clt$type_specification_header,
              qualifier: clt$keyword_type_qualifier,
              keyword_specs: array [1 .. 10] of clt$keyword_specification,
            recend,
          recend,
          default_value: string (3),
        recend,
        type2: record
          header: clt$type_specification_header,
        recend,
        type3: record
          header: clt$type_specification_header,
        recend,
      recend := [[1, [88, 9, 26, 11, 17, 39, 296], clc$command, 5, 3, 0, 0, 0,
            0, 3, 'OSM$ADMS_DISPS'], [['DISPLAY_OPTIONS                ',
            clc$nominal_entry, 1], ['DO                             ',
            clc$abbreviation_entry, 1], ['O                              ',
            clc$abbreviation_entry, 2], ['OUTPUT                         ',
            clc$nominal_entry, 2], ['STATUS                         ',
            clc$nominal_entry, 3]], [

{ PARAMETER 1

      [1, clc$normal_usage_entry, clc$non_secure_parameter,
            $clt$parameter_spec_methods [clc$specify_by_name,
            clc$specify_positionally], clc$pass_by_value,
            clc$immediate_evaluation, clc$standard_parameter_checking, 457,
            clc$optional_default_parameter, 0, 3],

{ PARAMETER 2

      [4, clc$normal_usage_entry, clc$non_secure_parameter,
            $clt$parameter_spec_methods [clc$specify_by_name],
            clc$pass_by_value, clc$immediate_evaluation,
            clc$standard_parameter_checking, 3, clc$optional_parameter, 0, 0],

{ PARAMETER 3

      [5, clc$normal_usage_entry, clc$non_secure_parameter,
            $clt$parameter_spec_methods [clc$specify_by_name],
            clc$pass_by_reference, clc$immediate_evaluation,
            clc$standard_parameter_checking, 3, clc$optional_parameter, 0, 0]],

{ PARAMETER 1

      [[1, 0, clc$union_type], [[clc$keyword_type, clc$list_type], FALSE, 2],
            44, [[1, 0, clc$keyword_type], [1],
            [['ALL                            ', clc$nominal_entry,
            clc$normal_usage_entry, 1]]], 393,
            [[1, 0, clc$list_type], [377, 1, clc$max_list_size, FALSE],
            [[1, 0, clc$keyword_type], [10], [[
            'A                              ', clc$abbreviation_entry,
            clc$normal_usage_entry, 5], ['APPLICATION                    ',
            clc$nominal_entry, clc$normal_usage_entry, 5],
            ['C                              ', clc$abbreviation_entry,
            clc$normal_usage_entry, 2], ['CONTROLS                       ',
            clc$nominal_entry, clc$normal_usage_entry, 2],
            ['JCA                            ', clc$abbreviation_entry,
            clc$normal_usage_entry, 1], ['JCL                            ',
            clc$abbreviation_entry, clc$normal_usage_entry, 3],
            ['JOB_CATEGORY                   ', clc$nominal_entry,
            clc$normal_usage_entry, 1], ['JOB_CLASS                      ',
            clc$nominal_entry, clc$normal_usage_entry, 3],
            ['SC                             ', clc$abbreviation_entry,
            clc$normal_usage_entry, 4], ['SERVICE_CLASS                  ',
            clc$nominal_entry, clc$normal_usage_entry, 4]]]], 'all'],

{ PARAMETER 2

      [[1, 0, clc$file_type]],

{ PARAMETER 3

      [[1, 0, clc$status_type]]];

?? POP ??

    CONST
      p$display_options = 1,
      p$output = 2,
      p$status = 3;

    VAR
      pvt: array [1 .. 3] of clt$parameter_value;

?? NEWTITLE := 'abort_handler', EJECT ??

{   PURPOSE:
{     This procedure traps conditions which should abort the display being
{     generated.  In the event the display processor unexpectedly exits, it
{     cleans up by closing the display file.
{     Conditions to abort for are: system, segment access, cybil run time,
{     and interactive terminate break.

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      IF (condition.selector = pmc$system_conditions) OR
            (condition.selector = mmc$segment_access_condition) OR
            ((condition.selector = pmc$user_defined_condition) AND
            (condition.user_condition_name = cye$run_time_condition)) OR
            ((condition.selector = ifc$interactive_condition) AND
            (condition.interactive_condition = ifc$terminate_break)) THEN
        osp$set_status_from_condition (jmc$job_management_id, condition,
              save_area, handler_status, status);
        EXIT jmp$_display_profile_summary;
      ELSEIF (condition.selector = pmc$block_exit_processing) THEN
        clp$close_display (display_control, ignore_status);
        RETURN;
      IFEND;

      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);

    PROCEND abort_handler;
?? OLDTITLE, EJECT ??

    TYPE
      object_kind_set = set of jmt$profile_object_kinds;

    VAR
      an_object: jmt$profile_object_reference,
      display_line: string (80),
      display_options: ^clt$data_value,
      first_display_line: boolean,
      i: integer,
      j: integer,
      object_kind: jmt$profile_object_kinds,
      which_object_kinds: object_kind_set;

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    which_object_kinds := $object_kind_set [];

    display_options := pvt [p$display_options].value;
    IF display_options^.kind = clc$keyword {ALL} THEN
      which_object_kinds := -$object_kind_set [];
    ELSE
      WHILE display_options <> NIL DO
        IF display_options^.element_value <> NIL THEN
          FOR object_kind := LOWERVALUE (object_kind)
                TO UPPERVALUE (object_kind) DO
            IF jmv$object_definition [object_kind].declaration.name =
                  display_options^.element_value^.name_value THEN
              which_object_kinds := which_object_kinds +
                    $object_kind_set [object_kind];
            IFEND;
          FOREND;
        IFEND;
        display_options := display_options^.link;
      WHILEND;
    IFEND;

    output_file_name := default_output_file;
    IF pvt [p$output].specified THEN
      output_file_name := pvt [p$output].value^.file_value;
    IFEND;

    clp$open_display_reference (output_file_name^, ^clp$new_page_procedure,
          fsc$list, ring_attributes, display_control, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    osp$establish_condition_handler (^abort_handler, TRUE);
    first_display_line := TRUE;
    clv$titles_built := FALSE;
    clv$command_name := 'Display Profile Summary';

    display_line := ' ';
    FOR object_kind := LOWERVALUE (object_kind) TO UPPERVALUE (object_kind) DO
      IF (object_kind IN which_object_kinds) AND
            (jmv$the_profile.objects [object_kind] <> NIL) THEN
        IF NOT first_display_line THEN
          clp$new_display_line (display_control, 1, status);
        IFEND;
        first_display_line := FALSE;
        display_line := ' Summary of ';
        display_line (13, * ) := object_name [object_kind];
        clp$put_display (display_control, display_line, clc$trim, status);

        display_line := '     ';
        an_object := jmv$the_profile.objects [object_kind];
        REPEAT
          #TRANSLATE (osv$upper_to_lower, an_object^.name,
                display_line (5, 31));
          STRINGREP (display_line (36, 20), i, an_object^.references);
          clp$put_display (display_control, display_line (1, 36 + i - 1),
                clc$no_trim, status);
          an_object := an_object^.next_object;
        UNTIL an_object = NIL;
      IFEND;
    FOREND;

    clp$close_display (display_control, status);
    osp$disestablish_cond_handler;

  PROCEND jmp$_display_profile_summary;
?? TITLE := '[XDCL] jmp$_generate_profile_definitio', EJECT ??

{ PURPOSE:
{   This interface generates a file of ADMINISTER_SCHEDULING commands
{   that will build a profile with the same structure as the current
{   profile - it converts the profile to source.
{
{ DESIGN:
{   The routine writes the 'ADMS' command to enter the utility.  It then
{   writes commands to delete the categories.  Each object type is
{   processed with commands output to delete the deleteable standard
{   objects and then create the objects on the profile of that type.

  PROCEDURE [XDCL] jmp$_generate_profile_definitio
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE (osm$adms_genpd) generate_profile_definition (
{   generate_option, go: key
{       (full, f), (brief, b)
{     keyend = brief
{   output, o: file = $required
{   status)

?? PUSH (LISTEXT := ON) ??

    VAR
      pdt: [STATIC, READ, cls$declaration_section] record
        header: clt$pdt_header,
        names: array [1 .. 5] of clt$pdt_parameter_name,
        parameters: array [1 .. 3] of clt$pdt_parameter,
        type1: record
          header: clt$type_specification_header,
          qualifier: clt$keyword_type_qualifier,
          keyword_specs: array [1 .. 4] of clt$keyword_specification,
          default_value: string (5),
        recend,
        type2: record
          header: clt$type_specification_header,
        recend,
        type3: record
          header: clt$type_specification_header,
        recend,
      recend := [[1, [88, 9, 26, 10, 36, 19, 426], clc$command, 5, 3, 1, 0, 0,
            0, 3, 'OSM$ADMS_GENPD'], [['GENERATE_OPTION                ',
            clc$nominal_entry, 1], ['GO                             ',
            clc$abbreviation_entry, 1], ['O                              ',
            clc$abbreviation_entry, 2], ['OUTPUT                         ',
            clc$nominal_entry, 2], ['STATUS                         ',
            clc$nominal_entry, 3]], [

{ PARAMETER 1

      [1, clc$normal_usage_entry, clc$non_secure_parameter,
            $clt$parameter_spec_methods [clc$specify_by_name,
            clc$specify_positionally], clc$pass_by_value,
            clc$immediate_evaluation, clc$standard_parameter_checking, 155,
            clc$optional_default_parameter, 0, 5],

{ PARAMETER 2

      [4, clc$normal_usage_entry, clc$non_secure_parameter,
            $clt$parameter_spec_methods [clc$specify_by_name,
            clc$specify_positionally], clc$pass_by_value,
            clc$immediate_evaluation, clc$standard_parameter_checking, 3,
            clc$required_parameter, 0, 0],

{ PARAMETER 3

      [5, clc$normal_usage_entry, clc$non_secure_parameter,
            $clt$parameter_spec_methods [clc$specify_by_name],
            clc$pass_by_reference, clc$immediate_evaluation,
            clc$standard_parameter_checking, 3, clc$optional_parameter, 0, 0]],

{ PARAMETER 1

      [[1, 0, clc$keyword_type], [4], [['B                              ',
            clc$abbreviation_entry, clc$normal_usage_entry, 2],
            ['BRIEF                          ', clc$nominal_entry,
            clc$normal_usage_entry, 2], ['F                              ',
            clc$abbreviation_entry, clc$normal_usage_entry, 1],
            ['FULL                           ', clc$nominal_entry,
            clc$normal_usage_entry, 1]], 'brief'],

{ PARAMETER 2

      [[1, 0, clc$file_type]],

{ PARAMETER 3

      [[1, 0, clc$status_type]]];

?? POP ??

    CONST
      p$generate_option = 1,
      p$output = 2,
      p$status = 3;

    VAR
      pvt: array [1 .. 3] of clt$parameter_value;

?? NEWTITLE := 'abort_handler', EJECT ??

{   PURPOSE:
{     This procedure traps conditions which should abort the display being
{     generated.  In the event the display processor unexpectedly exits, it
{     cleans up by closing the display file.
{     Conditions to abort for are: system, segment access, cybil run time,
{     and interactive terminate break.

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      IF (condition.selector = pmc$system_conditions) OR
            (condition.selector = mmc$segment_access_condition) OR
            ((condition.selector = pmc$user_defined_condition) AND
            (condition.user_condition_name = cye$run_time_condition)) OR
            ((condition.selector = ifc$interactive_condition) AND
            (condition.interactive_condition = ifc$terminate_break)) THEN
        osp$set_status_from_condition (jmc$job_management_id, condition,
              save_area, handler_status, status);
        EXIT jmp$_generate_profile_definitio;
      ELSEIF (condition.selector = pmc$block_exit_processing) THEN
        clp$close_display (display_control, ignore_status);
        RETURN;
      IFEND;

      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);

    PROCEND abort_handler;
?? OLDTITLE, EJECT ??

?? FMT (FORMAT := OFF) ??

    VAR
      utility_name: [STATIC] array [jmt$profile_object_kinds] of string (24) :=
       ['                        ', {Job category }
        '                        ', {Job priority }
        '                        ', {Output Category}
        '                        ', {Reserved     }
        'administer_controls     ', {Controls     }
        'administer_job_class    ', {Job Class    }
        'administer_service_class', {Service Class}
        'administer_output_class ', {Output Class }
        'administer_Application  '],{Application  }

      create_name: [STATIC] array [jmt$profile_object_kinds] of string (24) :=
       ['create_job_category     ', {Job category }
        'create_job_priority     ', {Job Priority }
        'create_output_category  ', {Output Category}
        '                        ', {Reserved     }
        'create_controls         ', {Controls     }
        'create_class            ', {Job Class    }
        'create_class            ', {Service Class}
        'create_class            ', {Output Class }
        'create_application      '],{Application  }

      cleanup_commands: [STATIC] array [1 .. 5] of string (40) := [
         ' create_default_profile                ',
         ' administer_job_class                  ',
         '  change_attributes all ec=none rc=none',
         ' quit                                  ',
         ' delete_job_category all               '];

?? FMT (FORMAT := ON) ??

    VAR
      order_of_objects_on_display: [STATIC] array [1 .. 7] of
            jmt$profile_object_kinds := [jmc$profile_priority,
            jmc$profile_category, jmc$profile_controls,
            jmc$profile_output_class, jmc$profile_service_class,
            jmc$profile_job_class, jmc$profile_application];

    VAR
      open_position: [STATIC] clt$open_position := [FALSE];

    VAR
      an_object: jmt$profile_object_reference,
      attribute_structure: jmt$profile_declaration,
      attributes: jmt$object_attribute,
      batch_class: boolean,
      display_line: string (40),
      full_display: boolean,
      i: integer,
      interactive_class: boolean,
      j: integer,
      job_or_service_class: boolean,
      lower_case_name: string (40),
      object_kind: jmt$profile_object_kinds,
      sorted_parameters: ^jmt$object_parameter_list;

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$open_display_reference (pvt [p$output].value^.file_value^,
          ^clp$new_page_procedure, fsc$legible_data, ring_attributes,
          display_control, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    osp$establish_condition_handler (^abort_handler, TRUE);
    clv$titles_built := FALSE;
    clv$command_name := 'Generate Profile Definition';

    full_display := FALSE;
    IF pvt [p$generate_option].value^.name_value = 'FULL' THEN
      full_display := TRUE;
    IFEND;

    clp$put_display (display_control, 'administer_scheduling', clc$trim,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    display_line := ' ';
    lower_case_name := ' ';

    clp$new_display_line (display_control, 1, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    FOR i := 1 TO UPPERBOUND (cleanup_commands) DO
      clp$put_display (display_control, cleanup_commands [i], clc$trim,
            status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    FOREND;
    FOR j := LOWERBOUND (order_of_objects_on_display)
          TO UPPERBOUND (order_of_objects_on_display) DO
      object_kind := order_of_objects_on_display [j];
      IF jmv$the_profile.objects [object_kind] <> NIL THEN
        IF object_kind >= jmc$profile_controls THEN
          clp$new_display_line (display_control, 1, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
          display_line (2, * ) := utility_name [object_kind];
          clp$put_display (display_control, display_line, clc$trim, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
          clp$new_display_line (display_control, 1, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
          IF object_kind = jmc$profile_controls THEN
            clp$put_display (display_control,
                  '  delete_controls $name($mainframe(identifier))', clc$trim,
                  status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
          IFEND;
          display_line (2) := ' ';
          display_line (3, * ) := create_name [object_kind];
          job_or_service_class := (object_kind = jmc$profile_job_class) OR
                (object_kind = jmc$profile_service_class);
          interactive_class := NOT job_or_service_class;
          batch_class := NOT job_or_service_class;
          an_object := jmv$the_profile.objects [object_kind];
          REPEAT
            IF job_or_service_class AND (an_object^.name =
                  jmc$interactive_class_name) THEN
              interactive_class := TRUE;
            ELSEIF job_or_service_class AND (an_object^.name =
                  jmc$batch_class_name) THEN
              batch_class := TRUE;
            ELSEIF NOT an_object^.permanent THEN
              clp$put_partial_display (display_control, display_line, clc$trim,
                    amc$start, status);
              IF NOT status.normal THEN
                RETURN;
              IFEND;
              #TRANSLATE (osv$upper_to_lower, an_object^.name,
                    lower_case_name (2, 31));
              clp$put_partial_display (display_control, lower_case_name,
                    clc$trim, amc$terminate, status);
              IF NOT status.normal THEN
                RETURN;
              IFEND;
            IFEND;
            an_object := an_object^.next_object;
          UNTIL an_object = NIL;
          IF NOT interactive_class THEN
            clp$put_display (display_control, '  delete_class interactive',
                  clc$trim, status);
          IFEND;
          IF NOT batch_class THEN
            clp$put_display (display_control, '  delete_class batch', clc$trim,
                  status);
          IFEND;
          display_line (2, * ) := ' change_attribute';
        ELSE
          display_line (2, * ) := create_name [object_kind];
        IFEND;

        sorted_parameters := jmv$object_definition [object_kind].
              sorted_parameters;
        attribute_structure := jmv$object_definition [object_kind].declaration;
        an_object := jmv$the_profile.objects [object_kind];
        REPEAT
          clp$new_display_line (display_control, 1, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
          clp$put_partial_display (display_control, display_line, clc$trim,
                amc$start, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
          #TRANSLATE (osv$upper_to_lower, an_object^.name,
                lower_case_name (2, 31));
          clp$put_partial_display (display_control, lower_case_name, clc$trim,
                amc$continue, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
          attributes := an_object^.attributes;
          IF full_display THEN
            RESET jmv$working_storage;
            jmp$get_attributes_for_display (jmv$the_profile, an_object^,
                  attributes, status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
          IFEND;
          display_object_attribute (attributes, -$jmt$profile_set [],
                attribute_structure, sorted_parameters^, TRUE, TRUE, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
          an_object := an_object^.next_object;
        UNTIL an_object = NIL;
        IF object_kind >= jmc$profile_controls THEN
          clp$put_display (display_control, ' quit', clc$trim, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        IFEND;
      IFEND;
    FOREND;
    clp$new_display_line (display_control, 1, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    clp$put_display (display_control, 'quit yes', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$close_display (display_control, status);
    osp$disestablish_cond_handler;

  PROCEND jmp$_generate_profile_definitio;
MODEND jmm$administer_display;
