?? RIGHT := 110 ??
?? NEWTITLE := 'DEFINE_SUBPRODUCT Subutility: QUIT Subcommand.' ??
MODULE ram$quit_defs;

{ PURPOSE:
{   This module contains the procedure to end the define subproduct subutility
{   session.
{
{ DESIGN:
{   The compiled module resides in RAF$LIBRARY.
{
{ NOTES:
{

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc rae$package_software_cc
*copyc rat$path
?? POP ??
*copyc clp$end_scan_command_file
*copyc clp$evaluate_parameters
*copyc clp$trimmed_string_size
*copyc osp$append_status_file
*copyc osp$append_status_parameter
*copyc osp$set_status_abnormal
*copyc osp$generate_error_message
*copyc rap$write_subproduct_info_file
*copyc rav$defs_utility_name
*copyc rav$subproduct_info_pointers
*copyc rav$pacs_catalog_ref_p
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] rap$quit_defs', EJECT ??

{ PURPOSE:
{   This interface completes the define subproduct processing.
{
{ DESIGN:
{   When WRITE_FILE parameter is specified true, the subproduct is verified
{   to be defined and the subproduct information file is written.  The
{   DEFINE_SUBPRODUCT utility is then closed.
{
{   If WRITE_FILE is FALSE, the DEFINE_SUBPRODUCT utility is closed.  No
{   subproduct information file is written.
{
{ NOTES:
{   The format conversion of the PACS catalog path from an
{   fst$file_reference to rat$path eliminates the need for a scratch
{   sequence to store the FS format when traversing through the element
{   list.
{

  PROCEDURE [XDCL] rap$quit_defs
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE quid_pdt (
{   write_file, wf: boolean = true
{   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,
          default_value: string (4),
        recend,
        type2: record
          header: clt$type_specification_header,
        recend,
      recend := [[1, [88, 7, 25, 14, 39, 46, 169], clc$command, 3, 2, 0, 0, 0, 0, 2, 'QUID_PDT'],
            [['STATUS                         ', clc$nominal_entry, 2],
            ['WF                             ', clc$abbreviation_entry, 1],
            ['WRITE_FILE                     ', clc$nominal_entry, 1]], [
{ PARAMETER 1
      [3, 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_default_parameter, 0, 4],
{ PARAMETER 2
      [1, 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$boolean_type], 'true'],
{ PARAMETER 2
      [[1, 0, clc$status_type]]];

?? POP ??

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

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

    VAR
      defined: boolean,
      local_status: ost$status,
      pacs_catalog: rat$path;


    status.normal := TRUE;

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

    IF pvt [p$write_file].value^.boolean_value.value THEN
      pacs_catalog.path := rav$pacs_catalog_ref_p^;
      pacs_catalog.size := #SIZE (rav$pacs_catalog_ref_p^);

      verify_subproduct_defined (pacs_catalog, rav$subproduct_info_pointers, defined);

      IF defined THEN

        rap$write_subproduct_info_file (pacs_catalog, rav$subproduct_info_pointers, status);

      ELSE
        osp$set_status_abnormal ('RA', rae$subproduct_not_defined, '', status);
      IFEND;
    IFEND;

    clp$end_scan_command_file (rav$defs_utility_name, local_status);
    IF status.normal THEN
      status := local_status;
    IFEND;

  PROCEND rap$quit_defs;

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

{ PURPOSE:
{   This procedure validates that all the required fields in the element
{   list have been filled.
{
{ DESIGN:
{   If the element is a file, a procedure is called to check all the fields
{   that a file element contains.  If the element is a catalog and it
{   contains files, VERIFY_ELEMENTS_DEFINED is called recursively.
{
{ NOTES:
{   The #SPOIL's around the assignment of the CURRENT_ELEMENT_P prevents a
{   cybil bug from occuring when compiled with opt=high.  These statements
{   can be removed when PSR CILB431 is answered.
{

  PROCEDURE verify_elements_defined
    (    catalog_permit_exists: boolean;
         installation_path_indexer: rat$path_container_indexer;
         path_container_p: ^rat$path_container;
         element_path: rat$path;
         element_p: ^rat$element;
     VAR subproduct_info_seq_p {input} : ^rat$subproduct_info_sequence;
     VAR defined: boolean);


    VAR
      current_element_p: ^rat$element,
      current_element_path: rat$path,
      first_element_down_p: ^rat$element,
      next_catalog_permit_exists: boolean;

    current_element_p := element_p;

    WHILE current_element_p <> NIL DO

      STRINGREP (current_element_path.path, current_element_path.size, element_path.
            path (1, element_path.size), '.', current_element_p^.
            name (1, clp$trimmed_string_size (current_element_p^.name)));

      IF current_element_p^.element_type = rac$file THEN

        verify_file_defined (catalog_permit_exists, installation_path_indexer, path_container_p,
              current_element_path, current_element_p, defined);

      ELSEIF (current_element_p^.element_type = rac$catalog) AND (current_element_p^.element_count <> 0) THEN
        next_catalog_permit_exists := (current_element_p^.permit.defined OR catalog_permit_exists);
        first_element_down_p := #PTR (current_element_p^.first_element_down_p, subproduct_info_seq_p^);

        verify_elements_defined (next_catalog_permit_exists, installation_path_indexer, path_container_p,
              current_element_path, first_element_down_p, subproduct_info_seq_p, defined);
      IFEND;

      #SPOIL (current_element_p);
      current_element_p := #PTR (current_element_p^.next_element_across_p, subproduct_info_seq_p^);
      #SPOIL (current_element_p);

    WHILEND;

  PROCEND verify_elements_defined;

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

{ PURPOSE:
{   This procedure validates each required field in the element list for a
{   FILE.
{
{ DESIGN:
{   This procedure verifies that permits and ring attributes are correctly
{   defined for a FILE.
{
{ NOTES:
{   ** When library merge is implimented it will be validated as well.  The
{      parameters INSTALLATION PATH_INDEXER and PATH_CONTAINER_P are setup to
{      support library merge.  The actual code to validate the libary merge is
{      not, because the path container format is going to change.  See the
{      section below.
{

  PROCEDURE verify_file_defined
    (    catalog_permit_exists: boolean;
         installation_path_indexer: rat$path_container_indexer;
         path_container_p: ^rat$path_container;
         element_path: rat$path;
     VAR element_p: ^rat$element;
     VAR defined: boolean);


    VAR
      ignore_status: ost$status,
      length: integer,
      local_status: ost$status;


    { Verify file permits are defined.

    IF (NOT element_p^.permit.defined) AND (NOT catalog_permit_exists) THEN
      osp$set_status_abnormal ('RA', rae$attribute_required, 'Permit', local_status);
      osp$append_status_file (osc$status_parameter_delimiter, element_path.path (1, element_path.size),
            local_status);
      osp$generate_error_message (local_status, ignore_status);
      defined := FALSE;
    IFEND;

    { Verify ring attributes are defined.

    IF element_p^.ring_attributes.r1 = osc$invalid_ring THEN
      osp$set_status_abnormal ('RA', rae$attribute_required, 'Ring Attributes', local_status);
      osp$append_status_file (osc$status_parameter_delimiter, element_path.path (1, element_path.size),
            local_status);
      osp$generate_error_message (local_status, ignore_status);
      defined := FALSE;
    IFEND;

    { Verify library merge is correctly defined.

    {  ** To be implimented.  When library merge has been defined for this
    {  element it will be validated (ie.  the library merge path indexer
    {  for the file is not 0).  To validate, the family and user names for
    {  the library specified by the library merge path must equal
    {  :$SYSTEM.$SYSTEM or they must equal those defined for the
    {  installation path.  When this is not the case generate an error
    {  message using condition RAE$BAD_MASTER_CATALOG_FOR_LIB (in the same
    {  manner as for the other tests).

  PROCEND verify_file_defined;

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

{ PURPOSE:
{   This procedure validates that the subproduct attributes record and the
{   element list have been properly defined.
{
{ DESIGN:
{   If the subproducts licensed product field has a valid value then all of
{   the attributes have been defined.  Another procedure is called to
{   validate the element list.
{
{ NOTES:
{
{

  PROCEDURE verify_subproduct_defined
    (    pacs_catalog: rat$path;
     VAR subproduct_info_pointers {input} : rat$subproduct_info_pointers;
     VAR defined: boolean);


    VAR
      ignore_status: ost$status,
      local_status: ost$status;


    defined := TRUE;

    IF subproduct_info_pointers.attributes_p^.licensed_product = '' THEN
      osp$set_status_abnormal ('RA', rae$command_defsa_required, '', local_status);
      osp$generate_error_message (local_status, ignore_status);
      defined := FALSE;
      RETURN;
    IFEND;

    verify_elements_defined (subproduct_info_pointers.attributes_p^.catalog_permit.defined,
          subproduct_info_pointers.attributes_p^.installation_path, subproduct_info_pointers.path_container_p,
          pacs_catalog, subproduct_info_pointers.element_list_p,
          subproduct_info_pointers.subproduct_info_seq_p, defined);

  PROCEND verify_subproduct_defined;
MODEND ram$quit_defs;

