?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE SCL Interpreter : File Reference Manager' ??
MODULE clm$file_reference_manager;

{
{ PURPOSE:
{   This module contains the procedures that deal with file references, path names, and permanent file
{   management parameters.
{

?? NEWTITLE := 'Global Declarations', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc cld$path_description
*copyc cle$ecc_command_processing
*copyc cle$ecc_file_reference
*copyc cle$ecc_miscellaneous
*copyc cle$ecc_parsing
*copyc cle$no_cyc_expr_with_wild_card
*IF $true(osv$unix)
*copyc cle$not_supported
*IFEND
*copyc cle$up_cant_follow_wild_card
*copyc cle$wild_card_cant_be_first
*copyc cle$wild_card_not_allowed
*copyc clk$convert_string_to_file
*copyc clk$get_path_description
*copyc clk$get_working_catalog
*copyc clk$set_working_catalog
*copyc clt$file
*copyc clt$file_ref_parsing_options
*copyc clt$file_reference
*copyc clt$lexical_unit_kinds
*copyc clt$parsed_path
*copyc clt$source
*copyc fme$file_management_errors
*copyc fmt$path_handle
*copyc fsc$local
*copyc fse$path_exception_conditions
*copyc fst$cycle_reference
*copyc fst$evaluated_file_reference
*copyc fst$file_reference
*copyc fst$goi_object_information
*copyc fst$goi_object_list
*IF $true(osv$unix)
*copyc fst$open_position
*IFEND
*copyc fst$parsed_file_reference
*copyc fst$path
*IF $true(osv$unix)
*copyc fst$path_element_index
*copyc fst$path_element_size
*IFEND
*copyc fst$path_element_string
*IF $true(osv$unix)
*copyc fst$path_index
*IFEND
*copyc fst$path_size
*IF $true(osv$unix)
*copyc ose$unix_system_error
*copyc clp_getcwd
*copyc clp_getenv
*copyc clp$evaluate_parameters
*copyc clt$working_catalog
*copyc osp$set_status_from_errno
*IFEND
*copyc oss$job_paged_literal
*copyc oss$task_shared
*copyc ost$caller_identifier
*copyc ost$name_reference
*copyc ost$status
*copyc ost$status_message_level
?? POP ??
*IF NOT $true(osv$unix)
*copyc bap$get_path_elements
*copyc bap$get_path_string
*copyc bap$get_resolved_file_reference
*copyc bap$process_pt_request
*IFEND
*copyc clp$append_status_parse_state
*copyc clp$append_status_type_desc
*copyc clp$append_status_value_type
*copyc clp$check_name_for_path_handle
*copyc clp$construct_block_handle_name
*copyc clp$construct_path_handle_name
*copyc clp$convert_integer_to_string
*copyc clp$convert_string_to_integer
*copyc clp$convert_string_to_name
*copyc clp$evaluate_name
*copyc clp$evaluate_unsigned_decimal
*copyc clp$find_caller_input_block
*copyc clp$find_command_input_block
*copyc clp$find_current_block
*IF NOT $true(osv$unix)
*copyc clp$find_scl_options
*copyc clp$find_working_catalog
*copyc clp$get_fs_path_elements
*IFEND
*copyc clp$get_work_area
*copyc clp$identify_lexical_units
*copyc clp$initialize_parse_state
*IF $true(osv$unix)
*copyc clp$make_a_file_value
*IFEND
*copyc clp$make_application_value
*copyc clp$make_file_value
*copyc clp$make_unspecified_value
*copyc clp$remove_last_path_element
*IF NOT $true(osv$unix)
*copyc clp$rescan_wild_card_lex_unit
*IFEND
*copyc clp$scan_argument_list
*copyc clp$scan_any_lexical_unit
*copyc clp$scan_non_space_lexical_unit
*IF NOT $true(osv$unix)
*copyc clp$scan_wild_card_lexical_unit
*IFEND
*copyc clp$set_working_catalog_path
*copyc clp$trimmed_string_size
*copyc clp$validate_name
*copyc clp$wild_card_file_expansion
*copyc clv$negative_infinity
*copyc clv$positive_infinity
*copyc clv$standard_files
*copyc clv$unique_name
*copyc clv$user_identification
*copyc clv$value_descriptors
*copyc fsp$convert_fs_structure_to_pf
*copyc fsp$path_element
*copyc fsv$evaluated_file_reference
*copyc i#compare_collated
*copyc osp$append_status_file
*copyc osp$append_status_integer
*copyc osp$append_status_parameter
*IF NOT $true(osv$unix)
*copyc osp$enforce_exception_policies
*copyc osp$file_access_condition
*IFEND
*copyc osp$find_status_message_level
*IF NOT $true(osv$unix)
*copyc osp$generate_log_message
*IFEND
*copyc osp$set_status_abnormal
*copyc osp$set_status_condition
*copyc osv$lower_to_upper
*IF NOT $true(osv$unix)
*copyc osv$initial_exception_context
*copyc pfp$get_object_information
*copyc pmp$log
*IFEND

{
{ PURPOSE:
{   The following procedure exists solely to provide a "shelter" for the
{   declarations contained in certain decks that are *COPYC'd into this
{   deck.  For example, this module defines an XDCL'd variable that is
{   referenced by an INLINE procedure.  In order to make the deck containing
{   the INLINE procedure "self-contained" it *COPYCs the deck containing the
{   XREF declaration of the variable.  Since the INLINE procedure is needed
{   in this module, both the XDCL and XREF declaration will appear in this
{   module.  The following "dummy" procedure is used to hide the XREF
{   declaration of the variable form the rest of the module.
{

  PROCEDURE [INLINE] dummy;

*copyc clv$open_position_designator

  PROCEND dummy;
*IF NOT $true(osv$unix)
*copyc clp$convert_file_ref_to_string
?? TITLE := 'clp$check_valid_catalog', EJECT ??
*copyc clp$check_valid_catalog
*ELSE
?? TITLE := 'clv$open_position_designator', EJECT ??
*IFEND

  VAR
    clv$open_position_designator: [XDCL, #GATE, READ, oss$job_paged_literal] array [amt$open_position] of
          record
      size: 4 .. 5,
      value: string (5),
    recend := [[5, '$ASIS'], [4, '$BOI'], [4, '$BOP'], [4, '$EOI']];

?? TITLE := 'check_for_special_path_element', EJECT ??

  TYPE
*IF NOT $true(osv$unix)
    clt$special_path_elements = (clc$not_a_special_path_element, clc$current_family_path_element,
*ELSE
    clt$special_path_element_kind = (clc$not_a_special_path_element, clc$current_family_path_element,
*IFEND
          clc$local_catalog_path_element, clc$system_path_element, clc$current_user_path_element,
          clc$command_file_path_element, clc$cycle_path_element, clc$position_path_element,
          clc$job_file_path_element, clc$standard_file_path_element, clc$defer_eval_path_element,
          clc$source_path_element, clc$reversal_path_element, clc$workin_catalog_path_element,
*IF NOT $true(osv$unix)
          clc$unsupported_path_element, clc$var_or_fcn_cyc_path_element, clc$traversal_path_element);
*ELSE
          clc$unsupported_path_element, clc$var_or_fcn_cyc_path_element, clc$traversal_path_element,
          clc$no_cycle_path_element, clc$no_position_path_element);
*IFEND

  TYPE
    clt$special_path_element = record
*IF NOT $true(osv$unix)
      case kind: clt$special_path_elements of
*ELSE
      case kind: clt$special_path_element_kind of
*IFEND
      = clc$current_family_path_element .. clc$command_file_path_element,
*IF NOT $true(osv$unix)
            clc$defer_eval_path_element .. clc$traversal_path_element =
*ELSE
            clc$defer_eval_path_element .. clc$traversal_path_element, clc$no_cycle_path_element,
            clc$no_position_path_element =
*IFEND
        ,
      = clc$job_file_path_element, clc$standard_file_path_element =
        standard_file: clt$standard_files,
      = clc$cycle_path_element =
        cycle_reference: fst$cycle_reference,
      = clc$position_path_element =
        position: amt$open_position,
      casend,
    recend;

  CONST
*IF NOT $true(osv$unix)
    min_special_path_element_size = 3 {$UP} ,
    max_special_path_element_size = 18 {$COMMAND_OF_CALLER} ,
    number_of_special_path_elements = 37;
*ELSE
    min_special_path_element_size = 3 {$UP,$WC,$WD} ,
    max_special_path_element_size = 18 {$COMMAND_OF_CALLER,$WORKING_DIRECTORY} ,
    number_of_special_path_elements = 10;
*IFEND

  TYPE
*IF NOT $true(osv$unix)
    clt$new_path_name_elements = set of clt$special_path_elements;
*ELSE
    clt$special_path_element_kinds = set of clt$special_path_element_kind;
*IFEND

  VAR
    table: [STATIC, READ, oss$job_paged_literal] array [1 .. number_of_special_path_elements] of record
      name: string (max_special_path_element_size),
      element: clt$special_path_element,
    recend := [
*IF NOT $true(osv$unix)
          {} ['$ALL              ', [clc$traversal_path_element]],
          {} ['$ASIS             ', [clc$position_path_element, amc$open_no_positioning]],
          {} ['$BOI              ', [clc$position_path_element, amc$open_at_boi]],
          {} ['$BOP              ', [clc$position_path_element, amc$open_at_bop]],
*IFEND
          {} ['$COMMAND          ', [clc$command_file_path_element]],
          {} ['$COMMAND_OF_CALLER', [clc$command_file_path_element]],
*IF NOT $true(osv$unix)
          {} ['$DEFER            ', [clc$defer_eval_path_element]],
          {} ['$ECHO             ', [clc$standard_file_path_element, clc$sf_echo_file]],
          {} ['$EOI              ', [clc$position_path_element, amc$open_at_eoi]],
*IFEND
          {} ['$ERRORS           ', [clc$standard_file_path_element, clc$sf_error_file]],
*IF NOT $true(osv$unix)
          {} ['$FAMILY           ', [clc$current_family_path_element]],
          {} ['$HIGH             ', [clc$cycle_path_element, [fsc$high_cycle]]],
*IFEND
          {} ['$INPUT            ', [clc$standard_file_path_element, clc$sf_standard_input_file]],
*IF NOT $true(osv$unix)
          {} ['$JOB              ', [clc$local_catalog_path_element]],
          {} ['$JOB_LOG          ', [clc$job_file_path_element, clc$sf_job_log_file]],
          {} ['$JOB_MESSAGE      ', [clc$unsupported_path_element]],
          {} ['$LIST             ', [clc$standard_file_path_element, clc$sf_list_file]],
*IFEND
          {} ['$LOCAL            ', [clc$local_catalog_path_element]],
*IF NOT $true(osv$unix)
          {} ['$LOW              ', [clc$cycle_path_element, [fsc$low_cycle]]],
          {} ['$NEXT             ', [clc$cycle_path_element, [fsc$next_cycle]]],
*IFEND
          {} ['$NULL             ', [clc$job_file_path_element, clc$sf_null_file]],
          {} ['$OUTPUT           ', [clc$standard_file_path_element, clc$sf_standard_output_file]],
*IF NOT $true(osv$unix)
          {} ['$PROCEDURE        ', [clc$unsupported_path_element]],
          {} ['$RESPONSE         ', [clc$standard_file_path_element, clc$sf_response_file]],
          {} ['$SOURCE           ', [clc$source_path_element]],
          {} ['$SOURCE_OF_CALLER ', [clc$source_path_element]],
          {} ['$SYSTEM           ', [clc$system_path_element]],
          {} ['$TASK             ', [clc$unsupported_path_element]],
          {} ['$TERMINAL         ', [clc$job_file_path_element, clc$sf_terminal_file]],
          {} ['$UP               ', [clc$reversal_path_element]],
          {} ['$USER             ', [clc$current_user_path_element]],
          {} ['$UTILITY          ', [clc$unsupported_path_element]],
          {} ['$WC               ', [clc$workin_catalog_path_element]],
          {} ['$WORKING_CATALOG  ', [clc$workin_catalog_path_element]],
*IFEND
          {} ['COMMAND           ', [clc$job_file_path_element, clc$sf_command_file]],
          {} ['INPUT             ', [clc$job_file_path_element, clc$sf_job_input_file]],
          {} ['OUTPUT            ', [clc$job_file_path_element, clc$sf_job_output_file]]];

?? SKIP := 4 ??

  PROCEDURE [INLINE] check_for_special_path_element
    (    element_name: fst$path_element_name;
         element_size: fst$path_element_size;
     VAR element: clt$special_path_element);

    VAR
      current_index: 1 .. number_of_special_path_elements,
      high_index: 0 .. number_of_special_path_elements,
      temp: integer,
      low_index: 1 .. number_of_special_path_elements + 1;

    element.kind := clc$not_a_special_path_element;
    CASE element_name (1) OF
    = '$' =
      IF (min_special_path_element_size <= element_size) AND
            (element_size <= max_special_path_element_size) THEN
        low_index := 1;
        high_index := number_of_special_path_elements - 3;
        REPEAT
          temp := low_index + high_index;
          current_index := temp DIV 2;
          IF element_name = table [current_index].name THEN
            element := table [current_index].element;
          ELSEIF element_name < table [current_index].name THEN
            high_index := current_index - 1;
          ELSE
            low_index := current_index + 1;
          IFEND;
        UNTIL (low_index > high_index) OR (element.kind <> clc$not_a_special_path_element);
      IFEND;
    = 'C' =
      IF element_name = table [number_of_special_path_elements - 2].name THEN
        element := table [number_of_special_path_elements - 2].element;
      IFEND;
    = 'I' =
      IF element_name = table [number_of_special_path_elements - 1].name THEN
        element := table [number_of_special_path_elements - 1].element;
      IFEND;
    = 'O' =
      IF element_name = table [number_of_special_path_elements].name THEN
        element := table [number_of_special_path_elements].element;
      IFEND;
    ELSE
    CASEND;

  PROCEND check_for_special_path_element;
*IF NOT $true(osv$unix)
?? TITLE := 'check_for_valid_new_file_name', EJECT ??

  PROCEDURE [INLINE] check_for_valid_new_file_name
    (    file_name: amt$local_file_name;
     VAR name_is_valid_new_file_name: boolean);

    VAR
      element: clt$special_path_element,
      name_size: fst$path_element_size;

    name_size := clp$trimmed_string_size (file_name);
    check_for_special_path_element (file_name, name_size, element);
    name_is_valid_new_file_name := element.kind IN $clt$new_path_name_elements
          [clc$not_a_special_path_element, clc$job_file_path_element, clc$standard_file_path_element,
          clc$system_path_element];

  PROCEND check_for_valid_new_file_name;
?? TITLE := 'clp$validate_new_file_name', EJECT ??

  PROCEDURE [XDCL] clp$validate_new_file_name
    (    file_name: string ( * <= fsc$max_path_element_size);
     VAR validated_file_name: ost$name;
     VAR name_is_valid_new_file_name: boolean);

    VAR
      path_handle: clt$path_handle;

    clp$validate_name (file_name, validated_file_name, name_is_valid_new_file_name);
    IF name_is_valid_new_file_name THEN
      clp$check_name_for_path_handle (validated_file_name, path_handle);
      IF path_handle.kind = clc$not_a_path_handle THEN
        check_for_valid_new_file_name (validated_file_name, name_is_valid_new_file_name);
      ELSE
        name_is_valid_new_file_name := FALSE;
      IFEND;
    IFEND;

  PROCEND clp$validate_new_file_name;
?? TITLE := 'clp$validate_new_lfn', EJECT ??

  PROCEDURE [XDCL] clp$validate_new_lfn
    (    local_file_name: string ( * <= fsc$max_path_element_size);
     VAR validated_local_file_name: ost$name;
     VAR name_is_valid_new_lfn: boolean);

    clp$validate_name (local_file_name, validated_local_file_name, name_is_valid_new_lfn);
    IF name_is_valid_new_lfn THEN
      check_for_valid_new_file_name (validated_local_file_name, name_is_valid_new_lfn);
    IFEND;

  PROCEND clp$validate_new_lfn;
*IFEND
?? TITLE := 'clp$find_command_source', EJECT ??

  PROCEDURE [XDCL] clp$find_command_source
    (    file_name: amt$local_file_name;
     VAR block: ^clt$block);

    clp$find_current_block (block);
    IF file_name = '$SOURCE_OF_CALLER' THEN
*IF NOT $true(osv$unix)
      WHILE (block <> NIL) AND (block^.kind <> clc$command_proc_block) AND
            (block^.kind <> clc$function_proc_block) DO
*ELSE
      WHILE (block <> NIL) DO
*IFEND
        IF block^.kind = clc$task_block THEN
          IF NOT block^.synchronous_with_parent THEN
            IF block^.command_file = osc$null_name THEN
              block := NIL;
            IFEND;
            RETURN;
          IFEND;
        IFEND;
        block := block^.previous_block;
      WHILEND;
      IF block <> NIL THEN
        block := block^.previous_block;
      IFEND;
    IFEND;

  /search/
    WHILE block <> NIL DO
      CASE block^.kind OF
      = clc$command_block =
        CASE block^.command_kind OF
        = clc$command_is_include_file, clc$command_is_include_line =
          ;
        ELSE
          EXIT /search/;
        CASEND;
*IF NOT $true(osv$unix)
      = clc$command_proc_block, clc$function_proc_block =
        EXIT /search/;
      = clc$function_block =
        IF block^.source.kind <> clc$system_commands THEN
          EXIT /search/;
        IFEND;
*IFEND
      ELSE
        ;
      CASEND;
      block := block^.previous_block;
    WHILEND /search/;

  PROCEND clp$find_command_source;
*IF NOT $true(osv$unix)
?? TITLE := 'process_pt_request', EJECT ??

  PROCEDURE process_pt_request
    (    work_list: bat$process_pt_work_list;
         local_file_name: amt$local_file_name;
     VAR evaluated_file_reference: {i/o} fst$evaluated_file_reference;
     VAR process_pt_results: bat$process_pt_results;
     VAR status {input, output} : ost$status);

    VAR
      context: ^ost$ecp_exception_context;

    PUSH context;
    context^ := osv$initial_exception_context;
    context^.file.selector := osc$ecp_evaluated_file_ref;
    context^.file.evaluated_file_reference := evaluated_file_reference;
    REPEAT
      context^.condition_status := status;
      osp$enforce_exception_policies (context^);
      status := context^.condition_status;

      IF (NOT osp$file_access_condition (status)) OR (NOT context^.wait) THEN
        RETURN;
      ELSE
        bap$process_pt_request (work_list, local_file_name, evaluated_file_reference, process_pt_results,
              status);
      IFEND;
    UNTIL status.normal;

  PROCEND process_pt_request;
?? TITLE := 'set and log', EJECT ??

  PROCEDURE [INLINE] set_and_log
    (    procedure_name: ost$name_reference;
         text: string ( * ));

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

    osp$set_status_abnormal ('CL', fme$system_error, text, status);
    osp$append_status_parameter ($CHAR (32), procedure_name, status);
    osp$generate_log_message ($pmt$ascii_logset [pmc$job_log], status, ignore_status);

  PROCEND set_and_log;
?? TITLE := 'translate_error', EJECT ??

  PROCEDURE translate_error
    (    procedure_name: ost$name_reference;
     VAR status: {input, output} ost$status);

    VAR
      ignore_status: ost$status;

    osp$generate_log_message ($pmt$ascii_logset [pmc$job_log], status, ignore_status);
    set_and_log (procedure_name, 'bap$process_pt_request returned bad status in');
    osp$set_status_condition (cle$system_error, status);

  PROCEND translate_error;
?? TITLE := 'process_status', EJECT ??

  PROCEDURE process_status
    (    path_handle_info: fst$path_handle_info;
         path_resolution: fst$path_resolution;
         procedure_name: ost$name_reference;
     VAR status: {input, output} ost$status);

    IF status.normal THEN
      IF (NOT path_handle_info.path_handle_present) OR (path_handle_info.path_handle.segment_offset = 0) THEN
        set_and_log (procedure_name, 'bap$process_pt_request returned invalid path handle in');
        osp$set_status_condition (cle$system_error, status);
        RETURN;
      IFEND;
    ELSEIF status.condition = fme$system_error THEN
      translate_error (procedure_name, status);
      RETURN;
    ELSEIF (NOT path_handle_info.path_handle_present) OR (path_handle_info.path_handle.segment_offset = 0)
          THEN
      RETURN;
    ELSEIF path_resolution = fsc$path_resolution_error THEN
      status.normal := TRUE;
    ELSE
      RETURN;
    IFEND;

  PROCEND process_status;
*IFEND
?? TITLE := 'clp$evaluate_file_reference', EJECT ??
*copyc clh$evaluate_file_reference

  PROCEDURE [XDCL, #GATE] clp$evaluate_file_reference
    (    file: fst$file_reference;
         file_reference_parsing_options: clt$file_ref_parsing_options;
         resolve_cycle_number: boolean;
     VAR evaluated_file_reference: fst$evaluated_file_reference;
     VAR status: ost$status);

*IF NOT $true(osv$unix)
    VAR
      ignore_pt_results: bat$process_pt_results,
      work_list: bat$process_pt_work_list;
*IFEND


    status.normal := TRUE;

    clp$setup_and_parse_file_ref (file, file_reference_parsing_options, clv$user_identification,
          evaluated_file_reference, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

*IF NOT $true(osv$unix)
    IF resolve_cycle_number AND (evaluated_file_reference.cycle_reference.specification <>
          fsc$cycle_omitted) AND (evaluated_file_reference.cycle_reference.specification <> fsc$cycle_number)
          THEN
      work_list := $bat$process_pt_work_list [bac$record_path, bac$resolve_path, bac$resolve_to_catalog];
      bap$process_pt_request (work_list, osc$null_name, evaluated_file_reference, ignore_pt_results, status);
      IF NOT status.normal THEN
        IF osp$file_access_condition (status) THEN
          process_pt_request (work_list, osc$null_name, evaluated_file_reference, ignore_pt_results, status);
        IFEND;
        IF evaluated_file_reference.path_resolution <> fsc$path_resolution_error THEN
          translate_error ('clp$evaluate_file_reference', status);
        IFEND;
      IFEND;
    IFEND;
*IFEND

  PROCEND clp$evaluate_file_reference;
?? TITLE := 'clp$complete_file_ref_eval', EJECT ??
*copyc clh$complete_file_ref_eval

  PROCEDURE [XDCL] clp$complete_file_ref_eval
*IF NOT $true(osv$unix)
    (    multiple_reference_allowed: boolean;
*ELSE
    (    unix_path: boolean;
         multiple_reference_allowed: boolean;
*IFEND
         defer_expansion: boolean;
         encode_file_values: boolean;
     VAR initial_path {input, output} : ^fst$file_reference;
     VAR parse {input, output} : clt$parse_state;
     VAR work_area {input, output} : ^clt$work_area;
     VAR result: ^clt$data_value;
     VAR result_sub_list_tail: ^clt$data_value;
     VAR status: ost$status);

    VAR
      evaluated_file_reference: fst$evaluated_file_reference,
*IF $true(osv$unix)
      first_delimiter: clt$lexical_unit_kind,
*IFEND
      ignore_command_name: clt$name,
      ignore_form: clt$command_reference_form,
*IF NOT $true(osv$unix)
      ignore_pt_results: bat$process_pt_results,
*IFEND
      local_parse: clt$parse_state,
      node: ^clt$data_value,
      parameter_name: clt$parameter_name,
      parsing_options: clt$file_ref_parsing_options,
      path_handle_name: fst$path_handle_name,
      path_handle_name_size: ost$name_size,
      path_name: fst$path,
      path_name_size: fst$path_size,
      path_parsed: boolean,
*IF NOT $true(osv$unix)
      work_list: bat$process_pt_work_list;
*ELSE
      result_kind: clt$data_kind;
*IFEND


    status.normal := TRUE;
    result_sub_list_tail := NIL;
    result := NIL;

    IF multiple_reference_allowed THEN
      parsing_options := $clt$file_ref_parsing_options [clc$multiple_reference_allowed,
            clc$command_file_ref_allowed];
    ELSE
      parsing_options := $clt$file_ref_parsing_options [clc$command_file_ref_allowed];
    IFEND;

*IF $true(osv$unix)
    IF unix_path THEN
      parsing_options := parsing_options + $clt$file_ref_parsing_options [clc$unix_path_syntax];
      first_delimiter := clc$lex_divide;
    ELSE
      first_delimiter := clc$lex_colon;
    IFEND;

*IFEND
  /parse_file_reference/
    BEGIN
      IF NOT encode_file_values THEN
        parsing_options := parsing_options + $clt$file_ref_parsing_options [clc$file_ref_evaluation_stage];
*IF NOT $true(osv$unix)
        IF (parse.unit.kind = clc$lex_colon) AND clp$file_ref_is_pre_evaluated
              ($clt$file_ref_parsing_options [], parse) THEN
          local_parse := parse;
          clp$parse_file_reference (local_parse, path_parsed, evaluated_file_reference, status);
          IF (NOT status.normal) OR path_parsed THEN
            parameter_name := osc$null_name;
            parse := local_parse;
            EXIT /parse_file_reference/;
          IFEND;
        IFEND;
*IFEND
      IFEND;
      clp$complete_file_ref_parse (initial_path, parse, work_area, parsing_options, clv$user_identification,
            evaluated_file_reference, ignore_command_name, ignore_form, parameter_name, status);
    END /parse_file_reference/;

    IF NOT status.normal THEN
      RETURN;
    ELSEIF parameter_name <> osc$null_name THEN
      clp$make_unspecified_value (work_area, result);
      IF result = NIL THEN
        osp$set_status_condition (cle$work_area_overflow, status);
      IFEND;
      RETURN;
    IFEND;

*IF NOT $true(osv$unix)
    IF (NOT evaluated_file_reference.multiple_reference_specified) OR defer_expansion THEN
      IF encode_file_values THEN

        IF evaluated_file_reference.path_resolution = fsc$command_file_path THEN
          clp$construct_block_handle_name (evaluated_file_reference.block_handle, path_handle_name);
        ELSE
          IF NOT evaluated_file_reference.path_handle_info.path_handle_present THEN
            work_list := $bat$process_pt_work_list [bac$externalize_path_handle, bac$record_path];
            IF (evaluated_file_reference.cycle_reference.specification <> fsc$cycle_omitted) AND
                  (evaluated_file_reference.cycle_reference.specification <> fsc$cycle_number) THEN
              work_list := work_list + $bat$process_pt_work_list [bac$resolve_path, bac$resolve_to_catalog];
            IFEND;
            bap$process_pt_request (work_list, osc$null_name, evaluated_file_reference, ignore_pt_results,
                  status);
            IF (NOT status.normal) AND osp$file_access_condition (status) THEN
              process_pt_request (work_list, osc$null_name, evaluated_file_reference, ignore_pt_results,
                    status);
            IFEND;
          IFEND;
          clp$construct_path_handle_name (evaluated_file_reference.path_handle_info.path_handle,
                path_handle_name);
          process_status (evaluated_file_reference.path_handle_info, evaluated_file_reference.path_resolution,
                'clp$complete_file_ref_eval', status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        IFEND;

        clp$make_file_value (path_handle_name, work_area, result);

      ELSE
        clp$convert_file_ref_to_string (evaluated_file_reference, TRUE, path_name, path_name_size,
              status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        IF evaluated_file_reference.multiple_reference_specified AND defer_expansion THEN
          clp$make_application_value (path_name (1, path_name_size), work_area, result);
        ELSE
          clp$make_file_value (path_name (1, path_name_size), work_area, result);
        IFEND;
      IFEND;

      IF result = NIL THEN
        osp$set_status_condition (cle$work_area_overflow, status);
      IFEND;
      RETURN;
    IFEND;

    clp$wild_card_file_expansion (evaluated_file_reference, clc$wcfe_only_files, work_area, result,
          result_sub_list_tail, status);
    IF (NOT status.normal) OR (NOT encode_file_values) THEN
      RETURN;
    IFEND;

    node := result;
    WHILE node <> NIL DO
      clp$convert_str_to_path_handle (node^.element_value^.file_value^, FALSE, FALSE, TRUE, path_handle_name,
            evaluated_file_reference, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      path_handle_name_size := clp$trimmed_string_size (path_handle_name);
      IF STRLENGTH (node^.element_value^.file_value^) >= path_handle_name_size THEN
        node^.element_value^.file_value := ^node^.element_value^.file_value^ (1, path_handle_name_size);
      ELSE
        NEXT node^.element_value^.file_value: [path_handle_name_size] IN work_area;
        IF node^.element_value^.file_value = NIL THEN
          osp$set_status_condition (cle$work_area_overflow, status);
          RETURN;
        IFEND;
      IFEND;
      node^.element_value^.file_value^ (1, path_handle_name_size) :=
            path_handle_name (1, path_handle_name_size);

      node := node^.link;
    WHILEND;
*ELSE
    IF evaluated_file_reference.standard_file OR evaluated_file_reference.command_file_path.found THEN
      result_kind := clc$nos_ve_file;
      clp$convert_file_ref_to_string (evaluated_file_reference, TRUE, path_name, path_name_size, status);
    ELSE
      result_kind := clc$unix_file;
      clp$conv_unix_file_ref_to_str (evaluated_file_reference, path_name, path_name_size, status);
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    clp$make_a_file_value (result_kind, path_name (1, path_name_size), work_area, result);
    IF result = NIL THEN
      osp$set_status_condition (cle$work_area_overflow, status);
    IFEND;
*IFEND

  PROCEND clp$complete_file_ref_eval;
?? TITLE := 'clp$parse_file_reference', EJECT ??
*IF NOT $true(osv$unix)
*copyc clh$parse_file_reference

  PROCEDURE [XDCL] clp$parse_file_reference
    (VAR parse {input, output} : clt$parse_state;
*ELSE

{
{   This request is used to parse a "pre-evaluated" file reference.
{
{       CLP$PARSE_FILE_REFERENCE (UNIX_PATH, PARSE, PATH_PARSED,
{         EVALUATED_FILE_REFERENCE, STATUS)
{
{ UNIX_PATH: (input)  This option specifies whether the file reference's syntax
{       is that of a UNIX path (TRUE) or a NOS/VE path (FALSE).
{
{ PARSE: (input, output)  This parameter specifies the file expression to be
{       evaluated.
{
{ PATH_PARSED: (output)  This parameter designates whether the file reference
{       had the correct syntax and was consequently successfully parsed.
{
{ EVALUATED_FILE_REFERENCE: (output)  This parameter specifies the information
{       resulting from the evaluation of the file reference.
{
{ STATUS: (output) This parameter specifies the request status.
{

  PROCEDURE clp$parse_file_reference
    (    unix_path: boolean;
     VAR parse {input, output} : clt$parse_state;
*IFEND
     VAR path_parsed {output} : boolean;
     VAR evaluated_file_reference {output} : fst$evaluated_file_reference;
     VAR status: ost$status);

*IF $true(osv$unix)
    VAR
      cycle_element_found: boolean,
      element_index: clt$string_index,
      element_name: fst$path_element_name,
      element_size: fst$path_element_size,
      number: integer;

*IFEND
?? NEWTITLE := 'append_element', EJECT ??

    PROCEDURE [INLINE] append_element
      (    size: fst$path_element_size;
           name: fst$path_element_string);


      evaluated_file_reference.path_structure (evaluated_file_reference.path_structure_size + 1) :=
            $CHAR (size);
      evaluated_file_reference.path_structure (evaluated_file_reference.path_structure_size + 2, size) :=
            name;
      evaluated_file_reference.path_structure_size := evaluated_file_reference.path_structure_size + 1 + size;
      evaluated_file_reference.number_of_path_elements := evaluated_file_reference.number_of_path_elements +
            1;

    PROCEND append_element;
?? OLDTITLE, EJECT ??

*IF NOT $true(osv$unix)
    VAR
      cycle_element_found: boolean,
      element_name: fst$path_element_name,
      element_size: fst$path_element_size,
      number: integer;


*IFEND
    status.normal := TRUE;
    path_parsed := FALSE;
    evaluated_file_reference := fsv$evaluated_file_reference;
    cycle_element_found := FALSE;

*IF NOT $true(osv$unix)
    WHILE (parse.unit.kind IN $clt$lexical_unit_kinds [clc$lex_colon, clc$lex_dot]) DO
      IF (evaluated_file_reference.number_of_path_elements > 0) AND (parse.unit.kind = clc$lex_colon) THEN
        osp$set_status_condition (cle$unexpected_colon_in_path, status);
        RETURN;
      IFEND;

      clp$scan_any_lexical_unit (parse);

*ELSE
    WHILE TRUE DO
*IFEND
      CASE parse.unit.kind OF
*IF $true(osv$unix)
      = clc$lex_colon =
        IF unix_path OR (evaluated_file_reference.number_of_path_elements > 0) THEN
          osp$set_status_condition (cle$unexpected_colon_in_path, status);
          RETURN;
        IFEND;
      = clc$lex_divide =
        IF NOT unix_path THEN
          RETURN;
        IFEND;
      = clc$lex_dot =
        ;
      ELSE
        path_parsed := TRUE;
        RETURN;
      CASEND;

      clp$scan_any_lexical_unit (parse);
      CASE parse.unit.kind OF

      = clc$lex_name, clc$lex_dot =
*ELSE
      = clc$lex_name =
*IFEND
        IF cycle_element_found THEN
          RETURN;
        IFEND;
*IF $true(osv$unix)
        IF unix_path THEN
          element_size := parse.unit.size;
          element_index := parse.unit_index;
          WHILE parse.units_array^ [parse.units_array_index + 1].kind IN
                $clt$lexical_unit_kinds [clc$lex_dot, clc$lex_name] DO
            clp$scan_any_lexical_unit (parse);
            element_size := element_size + parse.unit.size;
          WHILEND;
          element_name := parse.text^ (element_index, element_size);
        ELSE
*IFEND
        #TRANSLATE (osv$lower_to_upper, parse.text^ (parse.unit_index, parse.unit.size), element_name);
*IF $true(osv$unix)
          element_size := parse.unit.size;
        IFEND;
*IFEND
        IF element_name (1) = '$' THEN
          RETURN;
        IFEND;
*IF NOT $true(osv$unix)
        IF (evaluated_file_reference.path_structure_size + 1 + parse.unit.size)
             > fsc$max_path_size THEN
          osp$set_status_abnormal ('CL', cle$file_reference_too_long, '',
                status);
          RETURN;
        IFEND;
        element_size := parse.unit.size;
*IFEND
        append_element (element_size, element_name);

      = clc$lex_unsigned_decimal =
*IF NOT $true(osv$unix)
        IF evaluated_file_reference.number_of_path_elements <= 1 THEN
*ELSE
        IF unix_path THEN
          RETURN;
        ELSEIF evaluated_file_reference.number_of_path_elements <= 1 THEN
*IFEND
          osp$set_status_condition (cle$cycle_must_follow_file_name, status);
          RETURN;
        IFEND;

        clp$evaluate_unsigned_decimal (parse.text^ (parse.unit_index, parse.unit.size), number, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
*IF NOT $true(osv$unix)
        IF (number < pfc$minimum_cycle_number) OR (number > pfc$maximum_cycle_number) THEN
          osp$set_status_condition (pfe$bad_cycle_number, status);
          osp$append_status_integer (osc$status_parameter_delimiter, number, 10, FALSE, status);
          RETURN;
        IFEND;

        evaluated_file_reference.cycle_reference.specification := fsc$cycle_number;
        evaluated_file_reference.cycle_reference.cycle_number := number;
        cycle_element_found := TRUE;
*IFEND

*IF $true(osv$unix)
      = clc$lex_end_of_line =
        IF unix_path THEN
          path_parsed := TRUE;
        IFEND;
        RETURN;
*IFEND

      ELSE
        RETURN;
      CASEND;

      clp$scan_any_lexical_unit (parse);
      IF parse.unit.kind IN $clt$lexical_unit_kinds [clc$lex_concatenate,
            clc$lex_query, clc$lex_multiply, clc$lex_exponentiate, clc$lex_subtract] THEN
        RETURN;
      IFEND;
    WHILEND;

*IF NOT $true(osv$unix)
    path_parsed := TRUE;

*IFEND
  PROCEND clp$parse_file_reference;
?? TITLE := 'clp$complete_file_ref_parse', EJECT ??
*copyc clh$complete_file_ref_parse

  PROCEDURE [XDCL] clp$complete_file_ref_parse
    (VAR initial_path {input, output} : ^fst$file_reference;
     VAR parse {input, output} : clt$parse_state;
     VAR work_area {input, output} : ^clt$work_area;
         file_reference_parsing_options: clt$file_ref_parsing_options;
         user_identification: clt$user_identification;
     VAR evaluated_file_reference: fst$evaluated_file_reference;
     VAR command_or_program_name: clt$name;
     VAR form: clt$command_reference_form;
     VAR parameter_name: clt$parameter_name;
     VAR status: ost$status);

    TYPE
      chars = set of char;

    TYPE
      t$cycle_specifications = set of fst$cycle_specification;

    VAR
      unique_name_mask: [STATIC, READ, oss$job_paged_literal] string (256) := $CHAR (00) CAT $CHAR (01) CAT
            $CHAR (02) CAT $CHAR (03) CAT $CHAR (04) CAT $CHAR (05) CAT $CHAR (06) CAT $CHAR (07) CAT
            $CHAR (08) CAT $CHAR (09) CAT $CHAR (10) CAT $CHAR (11) CAT $CHAR (12) CAT $CHAR (13) CAT
            $CHAR (14) CAT $CHAR (15) CAT $CHAR (16) CAT $CHAR (17) CAT $CHAR (18) CAT $CHAR (19) CAT
            $CHAR (20) CAT $CHAR (21) CAT $CHAR (22) CAT $CHAR (23) CAT $CHAR (24) CAT $CHAR (25) CAT
            $CHAR (26) CAT $CHAR (27) CAT $CHAR (28) CAT $CHAR (29) CAT $CHAR (30) CAT $CHAR (31) CAT
            ' !"#$%&''()*+,-./9999999999:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_@ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~'
            CAT $CHAR (127) CAT $CHAR (128) CAT $CHAR (129) CAT $CHAR (130) CAT $CHAR (131) CAT
            $CHAR (132) CAT $CHAR (133) CAT $CHAR (134) CAT $CHAR (135) CAT $CHAR (136) CAT $CHAR (137) CAT
            $CHAR (138) CAT $CHAR (139) CAT $CHAR (140) CAT $CHAR (141) CAT $CHAR (142) CAT $CHAR (143) CAT
            $CHAR (144) CAT $CHAR (145) CAT $CHAR (146) CAT $CHAR (147) CAT $CHAR (148) CAT $CHAR (149) CAT
            $CHAR (150) CAT $CHAR (151) CAT $CHAR (152) CAT $CHAR (153) CAT $CHAR (154) CAT $CHAR (155) CAT
            $CHAR (156) CAT $CHAR (157) CAT $CHAR (158) CAT $CHAR (159) CAT $CHAR (160) CAT $CHAR (161) CAT
            $CHAR (162) CAT $CHAR (163) CAT $CHAR (164) CAT $CHAR (165) CAT $CHAR (166) CAT $CHAR (167) CAT
            $CHAR (168) CAT $CHAR (169) CAT $CHAR (170) CAT $CHAR (171) CAT $CHAR (172) CAT $CHAR (173) CAT
            $CHAR (174) CAT $CHAR (175) CAT $CHAR (176) CAT $CHAR (177) CAT $CHAR (178) CAT $CHAR (179) CAT
            $CHAR (180) CAT $CHAR (181) CAT $CHAR (182) CAT $CHAR (183) CAT $CHAR (184) CAT $CHAR (185) CAT
            $CHAR (186) CAT $CHAR (187) CAT $CHAR (188) CAT $CHAR (189) CAT $CHAR (190) CAT $CHAR (191) CAT
            $CHAR (192) CAT $CHAR (193) CAT $CHAR (194) CAT $CHAR (195) CAT $CHAR (196) CAT $CHAR (197) CAT
            $CHAR (198) CAT $CHAR (199) CAT $CHAR (200) CAT $CHAR (201) CAT $CHAR (202) CAT $CHAR (203) CAT
            $CHAR (204) CAT $CHAR (205) CAT $CHAR (206) CAT $CHAR (207) CAT $CHAR (208) CAT $CHAR (209) CAT
            $CHAR (210) CAT $CHAR (211) CAT $CHAR (212) CAT $CHAR (213) CAT $CHAR (214) CAT $CHAR (215) CAT
            $CHAR (216) CAT $CHAR (217) CAT $CHAR (218) CAT $CHAR (219) CAT $CHAR (220) CAT $CHAR (221) CAT
            $CHAR (222) CAT $CHAR (223) CAT $CHAR (224) CAT $CHAR (225) CAT $CHAR (226) CAT $CHAR (227) CAT
            $CHAR (228) CAT $CHAR (229) CAT $CHAR (230) CAT $CHAR (231) CAT $CHAR (232) CAT $CHAR (233) CAT
            $CHAR (234) CAT $CHAR (235) CAT $CHAR (236) CAT $CHAR (237) CAT $CHAR (238) CAT $CHAR (239) CAT
            $CHAR (240) CAT $CHAR (241) CAT $CHAR (242) CAT $CHAR (243) CAT $CHAR (244) CAT $CHAR (245) CAT
            $CHAR (246) CAT $CHAR (247) CAT $CHAR (248) CAT $CHAR (249) CAT $CHAR (250) CAT $CHAR (251) CAT
            $CHAR (252) CAT $CHAR (253) CAT $CHAR (254) CAT $CHAR (255),
      no_extra: [STATIC, READ, oss$job_paged_literal] array [boolean] of
            ost$status_condition := [cle$cycle_must_follow_file_name, cle$position_must_be_last];

    VAR
      append: boolean,
      block: ^clt$block,
      block_handle: clt$block_handle,
*IF NOT $true(osv$unix)
      block_handle_name: fst$path_handle_name,
*ELSE
      block_handle_name: fst$path,
      error_line: string (osc$max_string_size),
      error_line_size: integer,
*IFEND
      ignore_block_in_current_task: boolean,
      command_file_reference: boolean,
      command_or_program_name_found: boolean,
      current_parse: clt$parse_state,
      cycle_element_found: boolean,
      cycle_offset: integer,
      cycle_offset_found: boolean,
      element: clt$special_path_element,
      element_name: fst$path_element_name,
      element_size: fst$path_element_size,
*IF $true(osv$unix)
      element_text: ^fst$path_element_string,
*IFEND
      encountered_$defer: boolean,
      found: boolean,
      generic_element_present: boolean,
*IF NOT $true(osv$unix)
      ignore_pt_results: bat$process_pt_results,
      ignore_scan_index: integer,
*IFEND
      initial_path_passed_in: boolean,
      need_to_scan: boolean,
      number: integer,
      path_handle: clt$path_handle,
*IF $true(osv$unix)
      path_syntax, unix_path_syntax, ve_path_syntax: record
        delimiter: clt$lexical_unit_kind,
        delimiter_or_concatenate: clt$lexical_unit_kinds,
        first_path_units: clt$lexical_unit_kinds,
        first_element_units: clt$lexical_unit_kinds,
        element_units: clt$lexical_unit_kinds,
      recend,
*IFEND
      position_element_found: boolean,
      previous_element_is_generic: boolean,
      previous_unit_is_concatenate: boolean,
*IF $true(osv$unix)
      saved_parse: clt$parse_state,
*IFEND
      saved_parse_ptr: ^clt$parse_state,
      saved_work_area: ^clt$work_area,
*IF NOT $true(osv$unix)
      scan_found_char: boolean,
      scl_options: ^clt$scl_options,
*IFEND
      standard_file: clt$standard_files,
*IF NOT $true(osv$unix)
      string_found: boolean,
*IFEND
      string_index: clt$string_index,
*IF NOT $true(osv$unix)
      string_size: 0 .. clc$max_string_size,
      string_value: ^clt$string_value,
*IFEND
      units: ^clt$lexical_units,
      wild_card_chars: chars,
*IF NOT $true(osv$unix)
      working_catalog: ^^clt$working_catalog,
      work_list: bat$process_pt_work_list;
*ELSE
      working_catalog: clt$working_catalog;
*IFEND

?? NEWTITLE := 'append_element', EJECT ??

    PROCEDURE [INLINE] append_element
      (    size: fst$path_element_size;
           name: fst$path_element_string);


      evaluated_file_reference.path_structure (evaluated_file_reference.path_structure_size + 1) :=
            $CHAR (size);
      evaluated_file_reference.path_structure (evaluated_file_reference.path_structure_size + 2, size) :=
            name;
      evaluated_file_reference.path_structure_size := evaluated_file_reference.path_structure_size + 1 + size;
      evaluated_file_reference.number_of_path_elements := evaluated_file_reference.number_of_path_elements +
            1;

    PROCEND append_element;
?? TITLE := 'append_wild_card', EJECT ??

    PROCEDURE [INLINE] append_wild_card
      (    wild_card_element: fst$path_element_string);

      VAR
        size: fst$path_size;


      size := STRLENGTH (wild_card_element);
      evaluated_file_reference.path_structure (evaluated_file_reference.path_structure_size + 1) :=
            $CHAR (size);
*IF NOT $true(osv$unix)
      #TRANSLATE (osv$lower_to_upper, wild_card_element, evaluated_file_reference.
            path_structure (evaluated_file_reference.path_structure_size + 2, size));
*ELSE
      IF path_syntax = unix_path_syntax THEN
        evaluated_file_reference.path_structure (evaluated_file_reference.path_structure_size + 2,
              size) := wild_card_element;
      ELSE
        #TRANSLATE (osv$lower_to_upper, wild_card_element, evaluated_file_reference.
              path_structure (evaluated_file_reference.path_structure_size + 2, size));
      IFEND;
*IFEND
      evaluated_file_reference.path_structure_size := evaluated_file_reference.path_structure_size + 1 + size;
      evaluated_file_reference.number_of_path_elements := evaluated_file_reference.number_of_path_elements +
            1;
*IF NOT $true(osv$unix)
      evaluated_file_reference.multiple_reference_specified := TRUE;
*IFEND

    PROCEND append_wild_card;
?? TITLE := 'append_working_catalog', EJECT ??

    PROCEDURE append_working_catalog
      (    element_size: fst$path_size);


      IF clc$prevent_job_context_element IN file_reference_parsing_options THEN
        IF (user_identification.family.size = 0) OR (user_identification.user.size = 0) THEN
          osp$set_status_condition (cle$undefined_user_ident, status);
        ELSE
          append_element (user_identification.family.size, user_identification.family.value);
          append_element (user_identification.user.size, user_identification.user.value);
        IFEND;
        RETURN;
      IFEND;
      find_working_catalog (element_size);

    PROCEND append_working_catalog;
*IF NOT $true(osv$unix)
?? TITLE := 'check_for_cycle_offset', EJECT ??

    PROCEDURE check_for_cycle_offset;

      IF (current_parse.unit.kind = clc$lex_add) OR (current_parse.unit.kind = clc$lex_subtract) THEN
        clp$scan_any_lexical_unit (current_parse);
        IF current_parse.unit.kind <> clc$lex_unsigned_decimal THEN
          osp$set_status_abnormal ('CL', cle$wrong_kind_of_operand, 'INTEGER', status);
          clp$append_status_parse_state (osc$status_parameter_delimiter, current_parse, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, current_parse.
                text^ (current_parse.previous_non_space_unit_index,
                current_parse.previous_non_space_unit.size), status);
          RETURN;
        IFEND;

        clp$evaluate_unsigned_decimal (current_parse.text^ (current_parse.unit_index,
              current_parse.unit.size), cycle_offset, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        IF current_parse.previous_non_space_unit.kind = clc$lex_subtract THEN
          cycle_offset := -cycle_offset;
        IFEND;

{       cycle_offset_found := TRUE;

        clp$scan_any_lexical_unit (current_parse);
      IFEND;

    PROCEND check_for_cycle_offset;
*IFEND
?? TITLE := 'complete_evaluation', EJECT ??

    PROCEDURE complete_evaluation;

      IF current_parse.unit_is_space THEN
        clp$scan_non_space_lexical_unit (current_parse);
      IFEND;

{ This assignment is needed to restore the parse (input,output) to its correct position.

      parse := current_parse;

      IF path_handle.kind = clc$command_file_handle THEN

{ We got here because one of the following was specified:
{   command_file_handle_name by itself (block=NIL)
{   $COMMAND or $COMMAND_OF_CALLER (block<>NIL)
{   :$COMMAND or :$COMMAND_OF_CALLER (block<>NIL)

        get_path_handle_from_cmnd_file;
        IF NOT status.normal THEN
          RETURN;
        IFEND;
*IF $true(osv$unix)
        get_file_ref_from_path_handle;
*IFEND
      IFEND;

*IF NOT $true(osv$unix)
      IF path_handle.kind = clc$regular_path_handle THEN
        get_file_ref_from_path_handle;
      IFEND;
*IFEND

      IF (($clt$file_ref_parsing_options [clc$evaluating_command_ref,
            clc$evaluating_entry_point_ref] * file_reference_parsing_options) <>
            $clt$file_ref_parsing_options []) AND (NOT command_or_program_name_found) THEN
        determine_cmnd_prog_name_form;
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      IFEND;

      IF path_handle.kind = clc$regular_path_handle THEN
        RETURN;
*IF NOT $true(osv$unix)
      ELSEIF path_handle.kind = clc$not_a_path_handle THEN
        evaluated_file_reference.path_handle_info.path_handle_present := FALSE;
*IFEND
      IFEND;

      IF (standard_file = clc$sf_not_a_standard_file) THEN
*IF NOT $true(osv$unix)
        IF ((evaluated_file_reference.cycle_reference.specification = fsc$high_cycle) OR
              (evaluated_file_reference.cycle_reference.specification = fsc$low_cycle) OR
              (evaluated_file_reference.cycle_reference.specification = fsc$next_cycle))
{     } AND (cycle_offset_found OR (clc$evaluating_command_ref IN file_reference_parsing_options)) THEN

          determine_cycle_number;
        IFEND;
*IFEND
      ELSE
        get_path_handle_for_stand_file;
      IFEND;

*IF $true(osv$unix)
      IF (NOT evaluated_file_reference.command_file_path.found) AND
         (NOT evaluated_file_reference.standard_file) AND
         (fsp$path_element (^evaluated_file_reference, 1) ^ = fsc$local) THEN
        osp$set_status_abnormal ('CL', cle$not_supported, '$LOCAL is', status);
      IFEND;

*IFEND
    PROCEND complete_evaluation;
*IF $true(osv$unix)
?? TITLE := 'contains_wild_card_char', EJECT ??

    FUNCTION [INLINE] contains_wild_card_char
      (    text: clt$string_value): boolean;

      VAR
        ignore_scan_index: integer,
        scan_found_char: boolean;


      scan_found_char := FALSE;
{     IF (clc$multiple_reference_allowed IN file_reference_parsing_options) AND
{           (scl_options^.wild_card_pattern_type = clc$wc_extended_pattern) THEN
{       #SCAN (wild_card_chars, text, ignore_scan_index, scan_found_char);
{     IFEND;
      contains_wild_card_char := scan_found_char;

    FUNCEND contains_wild_card_char;
*IFEND
?? TITLE := 'determine_cmnd_prog_name_form', EJECT ??

    PROCEDURE determine_cmnd_prog_name_form;

      IF command_file_reference THEN
        osp$set_status_condition (cle$inappropriate_cmnd_file_ref, status);
        RETURN;
      IFEND;

      IF evaluated_file_reference.number_of_path_elements = 1 THEN
        osp$set_status_condition (cle$expecting_path_element, status);
        clp$append_status_parse_state (osc$status_parameter_delimiter, parse, status);
        RETURN;
      IFEND;
      command_or_program_name.value := fsp$path_element (^evaluated_file_reference,
            evaluated_file_reference.number_of_path_elements) ^;
      command_or_program_name.size := clp$trimmed_string_size (command_or_program_name.value);
      IF cycle_element_found OR (standard_file <> clc$sf_not_a_standard_file) THEN
        IF clc$evaluating_entry_point_ref IN file_reference_parsing_options THEN
          osp$set_status_condition (cle$cycle_must_follow_file_name, status);
          RETURN;
        IFEND;
        form := clc$file_cycle_command_ref;
      ELSE
        form := clc$module_or_file_command_ref;
      IFEND;

    PROCEND determine_cmnd_prog_name_form;
*IF NOT $true(osv$unix)
?? TITLE := 'determine_cycle_number', EJECT ??

    PROCEDURE determine_cycle_number;

      VAR
        ignore_parameter_name: clt$parameter_name,
        ignore_pt_results: bat$process_pt_results,
        initial_path: ^fst$file_reference,
        local_parse: clt$parse_state,
        number: integer,
        path_name: fst$path,
        path_name_size: fst$path_size,
        units: ^clt$lexical_units,
        work_list: bat$process_pt_work_list;


      IF generic_element_present THEN
        clp$convert_file_ref_to_string (evaluated_file_reference, TRUE, path_name, path_name_size, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        initial_path := NIL;
        clp$identify_lexical_units (^path_name, work_area, units, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        clp$initialize_parse_state (^path_name, units, local_parse);
        clp$scan_non_space_lexical_unit (local_parse);

{ We don't need to check for a clc$lex_name, clc$lex_colon, or clc$lex_dot
{ because the file reference has already been evaluated. Thus, the first
{ lexical unit is a clc$lex_colon.

        clp$complete_file_ref_parse (initial_path, local_parse, work_area, file_reference_parsing_options,
              user_identification, evaluated_file_reference, command_or_program_name, form,
              ignore_parameter_name, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      IFEND;

{ We must consult BAM to get the cycle number.

      work_list := $bat$process_pt_work_list [bac$resolve_path, bac$resolve_to_catalog];


      work_list := work_list + $bat$process_pt_work_list [bac$externalize_path_handle, bac$record_path];
      bap$process_pt_request (work_list, osc$null_name, evaluated_file_reference, ignore_pt_results, status);
      IF (NOT status.normal) AND osp$file_access_condition (status) THEN
        process_pt_request (work_list, osc$null_name, evaluated_file_reference, ignore_pt_results, status);
      IFEND;

{ If the file does not exist, return bad status.  BAP$PROCESS_PT_REQUEST may return other bad statuses --
{ we might have to special case them.

      IF status.normal THEN
        number := evaluated_file_reference.cycle_reference.cycle_number + cycle_offset;
        IF (number < pfc$minimum_cycle_number) OR (number > pfc$maximum_cycle_number) THEN
          osp$set_status_condition (pfe$bad_cycle_number, status);
          osp$append_status_integer (osc$status_parameter_delimiter, number, 10, FALSE, status);
        ELSE
          evaluated_file_reference.cycle_reference.cycle_number := number;
        IFEND;
      IFEND;

    PROCEND determine_cycle_number;
*IFEND
?? TITLE := 'evaluate_$command', EJECT ??

    PROCEDURE evaluate_$command;

      VAR
        cmnd_file_qualifier: fst$path_element_name,
        local_element: clt$special_path_element,
        local_element_name: fst$path_element_name,
        local_element_size: fst$path_element_size,
        local_parse: clt$parse_state;


{ If INITIAL_PATH<>NIL and INITIAL_PATH_PASSED_IN=TRUE then $COMMAND had already been evaluated via
{ CLP$$COMMAND and passed along in INITIAL_PATH.
{ If the PARSE contains more of the file reference, an error occurs.

      IF (initial_path <> NIL) AND initial_path_passed_in AND
*IF NOT $true(osv$unix)
            ((parse.unit.kind = clc$lex_dot) OR (parse.unit.kind = clc$lex_concatenate)) THEN
*ELSE
            (parse.unit.kind IN path_syntax.delimiter_or_concatenate) THEN
*IFEND
        osp$set_status_condition (cle$expecting_end_of_file_ref, status);
        clp$append_status_parse_state (osc$status_parameter_delimiter, parse, status);

{ This check is made in order to allow an open position specified on a $COMMAND reference.
{ Specifying an open position in this case has no bearing, so it is ignored.  We allow
{ the reference for compatability.

*IF NOT $true(osv$unix)
        IF parse.unit.kind = clc$lex_dot THEN
*ELSE
        IF parse.unit.kind = path_syntax.delimiter THEN
*IFEND
          local_parse := parse;
          clp$scan_any_lexical_unit (local_parse);
          IF local_parse.unit.kind = clc$lex_name THEN
            #TRANSLATE (osv$lower_to_upper, local_parse.text^ (local_parse.unit_index, local_parse.unit.size),
                  local_element_name);
            local_element_size := clp$trimmed_string_size (local_element_name);
            check_for_special_path_element (local_element_name, local_element_size, local_element);
*IF NOT $true(osv$unix)
            IF local_element.kind = clc$position_path_element THEN
*ELSE
            IF local_element.kind IN $clt$special_path_element_kinds
                  [clc$position_path_element, clc$no_position_path_element] THEN
*IFEND
              clp$scan_any_lexical_unit (local_parse);
*IF NOT $true(osv$unix)
              IF (local_parse.unit.kind <> clc$lex_dot) AND (local_parse.unit.kind <> clc$lex_concatenate)
                    THEN
*ELSE
              IF NOT (local_parse.unit.kind IN path_syntax.delimiter_or_concatenate) THEN
*IFEND
                status.normal := TRUE;
                parse := local_parse;
              IFEND;
            IFEND;
          IFEND;
        IFEND;
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      IFEND;

      clp$scan_any_lexical_unit (current_parse);
*IF NOT $true(osv$unix)
      IF current_parse.unit.kind = clc$lex_dot THEN
*ELSE
      IF current_parse.unit.kind = path_syntax.delimiter THEN
*IFEND
        IF element_name = '$COMMAND_OF_CALLER' THEN
          osp$set_status_condition (cle$expecting_end_of_file_ref, status);
          clp$append_status_parse_state (osc$status_parameter_delimiter, current_parse, status);
          RETURN;
        IFEND;
        clp$scan_any_lexical_unit (current_parse);
        IF current_parse.unit.kind = clc$lex_name THEN
          clp$scan_any_lexical_unit (current_parse);
*IF NOT $true(osv$unix)
          IF (current_parse.unit.kind = clc$lex_dot) OR (current_parse.unit.kind = clc$lex_concatenate) THEN
*ELSE
          IF current_parse.unit.kind IN path_syntax.delimiter_or_concatenate THEN
*IFEND
            osp$set_status_condition (cle$expecting_end_of_file_ref, status);
            clp$append_status_parse_state (osc$status_parameter_delimiter, current_parse, status);
            RETURN;
          IFEND;
          #TRANSLATE (osv$lower_to_upper, current_parse.text^
                (current_parse.previous_non_space_unit_index, current_parse.previous_non_space_unit.size),
                cmnd_file_qualifier);
          clp$check_name_for_path_handle (cmnd_file_qualifier, path_handle);
          IF path_handle.kind <> clc$command_file_handle THEN
            osp$set_status_abnormal ('CL', cle$improper_cmd_file_qualifier, cmnd_file_qualifier, status);
            RETURN;
          IFEND;
          IF NOT (clc$file_ref_evaluation_stage IN file_reference_parsing_options) THEN
            clp$find_command_input_block (path_handle.block_handle, block, ignore_block_in_current_task);
            IF block = NIL THEN
              osp$set_status_abnormal ('CL', cle$invalid_cmnd_file_qualifier, cmnd_file_qualifier, status);
              RETURN;
            IFEND;
          ELSE
            path_handle.kind := clc$not_a_path_handle;
            append_element (element_size, element_name);
            append_element (current_parse.previous_non_space_unit.size, cmnd_file_qualifier);
          IFEND;
        ELSE
          osp$set_status_condition (cle$expecting_end_of_file_ref, status);
          clp$append_status_parse_state (osc$status_parameter_delimiter, current_parse, status);
          RETURN;
        IFEND;
*IF NOT $true(osv$unix)
      ELSEIF (current_parse.unit.kind = clc$lex_dot) OR (current_parse.unit.kind = clc$lex_concatenate) THEN
*ELSE
      ELSEIF current_parse.unit.kind IN path_syntax.delimiter_or_concatenate THEN
*IFEND
        osp$set_status_condition (cle$expecting_end_of_file_ref, status);
        clp$append_status_parse_state (osc$status_parameter_delimiter, current_parse, status);
        RETURN;
      ELSE
        IF NOT (clc$file_ref_evaluation_stage IN file_reference_parsing_options) THEN
*IF NOT $true(osv$unix)
          clp$find_caller_input_block (element_name, block, ignore_block_in_current_task);
*ELSE
          clp$find_caller_input_block (element_name (1, osc$max_name_size), block,
                ignore_block_in_current_task);
*IFEND
          IF block <> NIL THEN
            path_handle.kind := clc$command_file_handle;
            path_handle.block_handle.segment_offset := #OFFSET (block);
            path_handle.block_handle.assignment_counter := block^.assignment_counter;
          ELSE
            append_element (6, '$LOCAL');
            append_element (5, '$NULL');
          IFEND;
        ELSE
          append_element (element_size, element_name);
        IFEND;
      IFEND;

      append := FALSE;
      need_to_scan := FALSE;

    PROCEND evaluate_$command;
*IF NOT $true(osv$unix)
?? TITLE := 'evaluate_$defer', EJECT ??

    PROCEDURE evaluate_$defer;

      clp$scan_any_lexical_unit (current_parse);
      IF current_parse.unit.kind = clc$lex_dot THEN
        clp$scan_any_lexical_unit (current_parse);
        IF current_parse.unit.kind = clc$lex_name THEN
          #TRANSLATE (osv$lower_to_upper, current_parse.text^
                (current_parse.unit_index, current_parse.unit.size), element_name);
          element_size := current_parse.unit.size;
          IF NOT encountered_$defer THEN
            encountered_$defer := TRUE;
          ELSE
            osp$set_status_condition (cle$recursive_$defer, status);
            RETURN;
          IFEND;
          clp$scan_any_lexical_unit (current_parse);
          need_to_scan := FALSE;
          IF NOT (clc$file_ref_evaluation_stage IN file_reference_parsing_options) THEN

{ Update PARSE to same position as CURRENT_PARSE.

            parse := current_parse;
            evaluate_file_var_or_fcn;
            IF NOT status.normal THEN
              RETURN;
            IFEND;
            IF found THEN
              need_to_scan := FALSE;
              append := FALSE;
            ELSE
              osp$set_status_abnormal ('CL', cle$var_or_fcn_follows_$defer, element_name (1, element_size),
                    status);
            IFEND;
          ELSE
            append_element (6, '$DEFER');
            check_for_special_path_element (element_name, element_size, element);
            IF element.kind IN $clt$new_path_name_elements [clc$current_family_path_element,
                  clc$current_user_path_element, clc$reversal_path_element, clc$source_path_element,
                  clc$workin_catalog_path_element] THEN
              previous_element_is_generic := TRUE;
            IFEND;
          IFEND;
          RETURN;
        IFEND;
      IFEND;
      osp$set_status_abnormal ('CL', cle$var_or_fcn_follows_$defer, current_parse.
            text^ (current_parse.unit_index, current_parse.unit.size), status);

    PROCEND evaluate_$defer;
?? TITLE := 'evaluate_file_var_or_fcn', EJECT ??

    PROCEDURE evaluate_file_var_or_fcn;

      VAR
        access_variable_requests: clt$access_variable_requests,
        file_value: ^fst$file_reference,
        saved_parse: clt$parse_state,
        units: ^clt$lexical_units,
        value: ^clt$data_value;


      saved_parse := current_parse;
      access_variable_requests := $clt$access_variable_requests [clc$possible_file_reference];
      clp$evaluate_name (element_name, access_variable_requests, current_parse, work_area, value, found,
            status);

      IF status.normal THEN
        IF found THEN
          IF value <> NIL THEN
            IF value^.kind = clc$file THEN
              IF value^.file_value^ (1) = ':' THEN
                file_value := ^value^.file_value^ (1, clp$trimmed_string_size (value^.file_value^));
                initial_path := file_value;
                initial_path_passed_in := FALSE;
                NEXT saved_parse_ptr IN work_area;
                IF saved_parse_ptr = NIL THEN
                  osp$set_status_condition (cle$work_area_overflow, status);
                  RETURN;
                IFEND;
                saved_parse_ptr^ := current_parse;
                clp$identify_lexical_units (file_value, work_area, units, status);
                IF status.normal THEN
                  clp$initialize_parse_state (file_value, units, current_parse);
                  clp$scan_non_space_lexical_unit (current_parse);
                  previous_element_is_generic := TRUE;
                IFEND;
              ELSE

{ The file variable or function value was incorrectly initialized (probably thru the program interface).

                osp$set_status_condition (cle$missing_colon_in_var_or_fcn, status);
              IFEND;
            ELSEIF value^.kind = clc$unspecified THEN

{ The current_parse should be pointing to the lexical unit after the variable

              IF (current_parse.unit.kind = clc$lex_concatenate) OR
                    (current_parse.unit.kind = clc$lex_dot) THEN
                osp$set_status_abnormal ('CL', cle$unexpected_oper_for_unspec, element_name, status);
                clp$append_status_parse_state (osc$status_parameter_delimiter, current_parse, status);
              IFEND;
              parameter_name := element_name;
              parse := current_parse;
              EXIT clp$complete_file_ref_parse;
            ELSE
              found := FALSE;
              current_parse := saved_parse;
              IF current_parse.unit.kind = clc$lex_left_parenthesis THEN
                osp$set_status_abnormal ('CL', cle$expecting_file_var_or_fcn, element_name (1, element_size),
                      status);
              IFEND;
            IFEND;
          ELSE
            found := FALSE;
            current_parse := saved_parse;
          IFEND;
        IFEND;
      IFEND;

    PROCEND evaluate_file_var_or_fcn;
*IFEND
?? TITLE := 'evaluate_first_element', EJECT ??

    PROCEDURE evaluate_first_element;

      VAR
*IF $true(osv$unix)
        element_contains_wild_card_char: boolean,
        home_element: ost_c_name,
        home_length: ost_c_integer,
        home_string: ost_c_name,
        home_value: ost_c_fixed_string,
        i: 1 .. 256,
        j: 0 .. 31,
*IFEND
        local_element: clt$special_path_element,
        local_element_name: fst$path_element_name,
        local_element_size: fst$path_element_size,
        local_parse: clt$parse_state;


      CASE element.kind OF

      = clc$command_file_path_element =

        IF clc$prevent_job_context_element IN file_reference_parsing_options THEN
          osp$set_status_abnormal ('CL', cle$no_job_context_elements, element_name (1, element_size), status);
          RETURN;
        IFEND;

*IF NOT $true(osv$unix)
        IF (current_parse.unit.kind = clc$lex_dot) OR (current_parse.unit.kind = clc$lex_concatenate) THEN
*ELSE
        IF current_parse.unit.kind IN path_syntax.delimiter_or_concatenate THEN
*IFEND
          osp$set_status_condition (cle$expecting_end_of_file_ref, status);
          clp$append_status_parse_state (osc$status_parameter_delimiter, current_parse, status);

{ This check is made in order to allow an open position specified on a $COMMAND reference.
{ Specifying an open position in this case has no bearing, so it is ignored.  We allow
{ the reference for compatability.

*IF NOT $true(osv$unix)
          IF current_parse.unit.kind = clc$lex_dot THEN
*ELSE
          IF current_parse.unit.kind = path_syntax.delimiter THEN
*IFEND
            local_parse := current_parse;
            clp$scan_any_lexical_unit (local_parse);
            IF local_parse.unit.kind = clc$lex_name THEN
              #TRANSLATE (osv$lower_to_upper, local_parse.text^
                    (local_parse.unit_index, local_parse.unit.size), local_element_name);
              local_element_size := clp$trimmed_string_size (local_element_name);
              check_for_special_path_element (local_element_name, local_element_size, local_element);
*IF NOT $true(osv$unix)
              IF local_element.kind = clc$position_path_element THEN
*ELSE
              IF local_element.kind IN $clt$special_path_element_kinds
                    [clc$position_path_element, clc$no_position_path_element] THEN
*IFEND
                clp$scan_any_lexical_unit (local_parse);
*IF NOT $true(osv$unix)
                IF (local_parse.unit.kind <> clc$lex_dot) AND (local_parse.unit.kind <> clc$lex_concatenate)
                      THEN
*ELSE
                IF NOT (local_parse.unit.kind IN path_syntax.delimiter_or_concatenate) THEN
*IFEND
                  status.normal := TRUE;
                  current_parse := local_parse;
                IFEND;
              IFEND;
            IFEND;
          IFEND;
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        IFEND;

*IF NOT $true(osv$unix)
        clp$find_caller_input_block (element_name, block, ignore_block_in_current_task);
*ELSE
        clp$find_caller_input_block (element_name (1, osc$max_name_size), block,
              ignore_block_in_current_task);
*IFEND
        IF block <> NIL THEN
          path_handle.kind := clc$command_file_handle;
          path_handle.block_handle.segment_offset := #OFFSET (block);
          path_handle.block_handle.assignment_counter := block^.assignment_counter;
        ELSE
          append_element (6, '$LOCAL');
          append_element (5, '$NULL');
          standard_file := clc$sf_null_file;
        IFEND;

        complete_evaluation;
        work_area := saved_work_area;
        EXIT clp$complete_file_ref_parse;

*IF NOT $true(osv$unix)
      = clc$current_family_path_element =

        IF (user_identification.family.size = 0) THEN
          osp$set_status_condition (cle$undefined_user_ident, status);
          RETURN;
        IFEND;

        append_element (user_identification.family.size, user_identification.family.value);

      = clc$current_user_path_element =

        IF (user_identification.family.size = 0) OR (user_identification.user.size = 0) THEN
          osp$set_status_condition (cle$undefined_user_ident, status);
          RETURN;
        IFEND;

        append_element (user_identification.family.size, user_identification.family.value);
        append_element (user_identification.user.size, user_identification.user.value);

      = clc$cycle_path_element =

        osp$set_status_condition (cle$cycle_must_follow_file_name, status);
        RETURN;

      = clc$defer_eval_path_element =

        osp$set_status_condition (cle$defer_must_follow_colon, status);
        RETURN;
*IFEND

      = clc$job_file_path_element, clc$standard_file_path_element =

        IF clc$prevent_job_context_element IN file_reference_parsing_options THEN
          osp$set_status_abnormal ('CL', cle$no_job_context_elements, element_name (1, element_size), status);
          RETURN;
        IFEND;

        IF element_name (1) <> '$' THEN
*IF NOT $true(osv$unix)
          evaluate_file_var_or_fcn;
          IF NOT status.normal THEN
            IF status.condition = cle$variable_never_given_value THEN
              status.normal := TRUE;
            ELSE
              RETURN;
            IFEND;
          IFEND;
          IF found THEN
            RETURN;
          IFEND;
*IFEND
        IFEND;

        append_element (6, '$LOCAL');
        append_element (element_size, element_name);
        standard_file := element.standard_file;

      = clc$local_catalog_path_element =

        IF clc$prevent_job_context_element IN file_reference_parsing_options THEN
          osp$set_status_abnormal ('CL', cle$no_job_context_elements, element_name (1, element_size), status);
          RETURN;
        IFEND;

        append_element (6, '$LOCAL');

      = clc$not_a_special_path_element =

*IF NOT $true(osv$unix)
        scan_found_char := FALSE;
        IF (clc$multiple_reference_allowed IN file_reference_parsing_options) AND
              (scl_options^.wild_card_pattern_type = clc$wc_extended_pattern) THEN
          #SCAN (wild_card_chars, element_name, ignore_scan_index, scan_found_char);
        IFEND;

        IF clc$prevent_job_context_element IN file_reference_parsing_options THEN
          IF (user_identification.family.size = 0) OR (user_identification.user.size = 0) THEN
            osp$set_status_condition (cle$undefined_user_ident, status);
            RETURN;
          IFEND;
          append_element (user_identification.family.size, user_identification.family.value);
          append_element (user_identification.user.size, user_identification.user.value);
          append_element (element_size, element_name);

{ The only time clc$evaluating_entry_point_ref is in the parsing_options and initial_path
{ is NIL is when we want to bypass evaluating file variables and functions - a file variable
{ or function may be present in file reference, but it is not a valid entry_point_reference.
{ So we want to evaluate the file reference relative to the working catalog.

        ELSEIF (clc$evaluating_entry_point_ref IN file_reference_parsing_options) AND
              (initial_path = NIL) THEN
          append_working_catalog (element_size);
          append_element (element_size, element_name);
        ELSEIF (element_name (1) = '$') AND (i#compare_collated
              (element_name, clv$unique_name, unique_name_mask) = 0) THEN
          append_element (6, '$LOCAL');
          append_element (element_size, element_name);
        ELSE
          clp$check_name_for_path_handle (element_name, path_handle);
          IF path_handle.kind <> clc$not_a_path_handle THEN
            append_element (6, '$LOCAL');
            append_element (element_size, element_name);
          ELSE

{  If the variable or function is not a file, then FOUND is set to false.
{  If it is, the CURRENT_PARSE will represent the value of the variable.

            IF NOT scan_found_char THEN
              evaluate_file_var_or_fcn;
              IF NOT status.normal THEN
                RETURN;
              IFEND;
            IFEND;

            IF NOT found THEN
              IF clc$use_$local_as_working_cat IN file_reference_parsing_options THEN
                append_element (6, '$LOCAL');
                append_element (element_size, element_name);
              ELSE
                find_working_catalog (element_size);
                IF NOT status.normal THEN
                  RETURN;
                IFEND;
                append_element (element_size, element_name);
              IFEND;
            IFEND;
          IFEND;
        IFEND;

        IF scan_found_char THEN
          evaluated_file_reference.multiple_reference_specified := TRUE;
        IFEND;

      = clc$position_path_element =
*ELSE
        IF (element_size = 5) AND ((element_name (1, element_size) = '$HOME') OR
              (element_name (1, element_size) = '$home')) THEN
          home_string := 'HOME' CAT $CHAR(0);
          clp_getenv (home_string, home_value, home_length);
          j := 0;
          IF home_length > 1 THEN  { ELSE $HOME must = /}
            FOR i := 2 TO home_length DO  { assumes the first character is "/" }
              IF home_value (i) <> '/' THEN
                j := j + 1;
                home_element (j) := home_value (i);
              ELSE
                append_element (j, home_element);
                j := 0;
              IFEND;
            FOREND;
            append_element (j, home_element);
          IFEND;
          RETURN;
        IFEND;
        find_working_catalog (element_size);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        append_element (element_size, element_name);
*IFEND

*IF NOT $true(osv$unix)

        osp$set_status_condition (cle$position_must_be_last, status);
        RETURN;

      = clc$reversal_path_element =

        IF clc$prevent_job_context_element IN file_reference_parsing_options THEN
          IF (user_identification.family.size = 0) OR (user_identification.user.size = 0) THEN
            osp$set_status_condition (cle$undefined_user_ident, status);
            RETURN;
          IFEND;
          append_element (user_identification.family.size, user_identification.family.value);
          append_element (user_identification.user.size, user_identification.user.value);
        ELSE
          clp$find_working_catalog (working_catalog);

          evaluated_file_reference.path_structure := working_catalog^^.evaluated_file_reference.
                path_structure;
          evaluated_file_reference.path_structure_size := working_catalog^^.evaluated_file_reference.
                path_structure_size;
          evaluated_file_reference.number_of_path_elements :=
                working_catalog^^.evaluated_file_reference.number_of_path_elements;
        IFEND;

        clp$remove_last_path_element (evaluated_file_reference, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        path_handle.kind := clc$not_a_path_handle;

      = clc$source_path_element =

        IF clc$prevent_job_context_element IN file_reference_parsing_options THEN
          osp$set_status_abnormal ('CL', cle$no_job_context_elements, element_name (1, element_size), status);
          RETURN;
        IFEND;

        find_command_source;
        IF NOT status.normal THEN
          RETURN;
        IFEND;

      = clc$system_path_element =

        append_element (7, '$SYSTEM');
        append_element (7, '$SYSTEM');

      = clc$traversal_path_element =

        IF clc$multiple_reference_allowed IN file_reference_parsing_options THEN
          append_working_catalog (4);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
          append_wild_card ('$ALL');
        ELSE
          osp$set_status_condition (cle$wild_card_not_allowed, status);
        IFEND;
*IFEND

      = clc$unsupported_path_element =

        osp$set_status_abnormal ('CL', cle$not_yet_implemented, element_name, status);
        osp$append_status_parameter (' ', 'in file references', status);
        RETURN;

*IF NOT $true(osv$unix)
      = clc$workin_catalog_path_element =

        IF clc$prevent_job_context_element IN file_reference_parsing_options THEN
          osp$set_status_abnormal ('CL', cle$no_job_context_elements, element_name (1, element_size), status);
          RETURN;
        IFEND;

        clp$find_working_catalog (working_catalog);

        evaluated_file_reference.path_structure := working_catalog^^.evaluated_file_reference.path_structure;
        evaluated_file_reference.path_structure_size := working_catalog^^.evaluated_file_reference.
              path_structure_size;
        evaluated_file_reference.number_of_path_elements :=
              working_catalog^^.evaluated_file_reference.number_of_path_elements;
*IFEND

      CASEND;

    PROCEND evaluate_first_element;
*IF NOT $true(osv$unix)
?? TITLE := 'evaluate_name_or_num_var_or_fcn', EJECT ??

    PROCEDURE evaluate_name_or_num_var_or_fcn;

      VAR
        access_variable_requests: clt$access_variable_requests,
        value: ^clt$data_value;


      clp$scan_any_lexical_unit (current_parse);
      need_to_scan := FALSE;

      access_variable_requests := $clt$access_variable_requests [];
      clp$evaluate_name (element_name, access_variable_requests, current_parse, work_area, value, found,
            status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

    /evaluate/
      BEGIN
        IF found THEN
          IF value = NIL THEN
            osp$set_status_abnormal ('CL', cle$variable_never_given_value, element_name (1, element_size),
                  status);
            RETURN;
          IFEND;
          CASE value^.kind OF
          = clc$name =
            element_name := value^.name_value;
            EXIT /evaluate/;
          = clc$data_name =
            element_name := value^.data_name_value;
            EXIT /evaluate/;
          = clc$keyword =
            element_name := value^.keyword_value;
            EXIT /evaluate/;
          = clc$integer =
            element.kind := clc$var_or_fcn_cyc_path_element;
            number := value^.integer_value.value;
            RETURN;
          = clc$program_name =
            IF (clc$evaluating_entry_point_ref IN file_reference_parsing_options) THEN
              element_name := value^.program_name_value;
              EXIT /evaluate/;
            IFEND;
          = clc$unspecified =
            osp$set_status_abnormal ('CL', cle$unexpected_oper_for_unspec, element_name, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, '//', status);
            parameter_name := element_name;
            EXIT clp$complete_file_ref_parse;
          ELSE
            ;
          CASEND;
        IFEND;

        osp$set_status_abnormal ('CL', cle$var_or_fcn_follows_concat, element_name (1, element_size), status);
        RETURN;
      END /evaluate/;

      element_size := clp$trimmed_string_size (element_name);
      check_for_special_path_element (element_name, element_size, element);

    PROCEND evaluate_name_or_num_var_or_fcn;
?? TITLE := 'find_command_source', EJECT ??

    PROCEDURE find_command_source;

      VAR
        block: ^clt$block;


      clp$find_command_source (element_name, block);
      IF block <> NIL THEN
        CASE block^.source.kind OF
        = clc$system_commands =
          osp$set_status_condition (cle$unexpected_sys_cmnd_source, status);
          RETURN;
        = clc$sub_commands =
          osp$set_status_abnormal ('CL', cle$unexpected_util_cmnd_source, block^.source.utility_name, status);
          RETURN;
        = clc$catalog_commands, clc$library_commands =
          clp$check_name_for_path_handle (block^.source.local_file_name, path_handle);
        CASEND;
        bap$get_path_elements (path_handle.regular_handle, evaluated_file_reference, status);
        IF status.normal THEN
          cycle_element_found := evaluated_file_reference.cycle_reference.specification <> fsc$cycle_omitted;
        IFEND;
      ELSE
        osp$set_status_condition (cle$unable_to_find_cmnd_source, status);
      IFEND;

    PROCEND find_command_source;
*IFEND
?? TITLE := 'find_working_catalog', EJECT ??

*IF NOT $true(osv$unix)
    PROCEDURE [INLINE] find_working_catalog (element_size: fst$path_size);
*ELSE
    PROCEDURE [INLINE] find_working_catalog
      (    element_size: fst$path_size);

*IFEND

*IF NOT $true(osv$unix)
      clp$find_working_catalog (working_catalog);
      IF working_catalog^ = NIL THEN
        append_element (6, '$LOCAL');
      ELSEIF (working_catalog^^.evaluated_file_reference.number_of_path_elements >= fsc$max_path_elements) OR
            ((working_catalog^^.evaluated_file_reference.path_structure_size + 1 + element_size) >
*ELSE
      clp$find_working_catalog (working_catalog, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      IF (working_catalog.evaluated_file_reference.number_of_path_elements >= fsc$max_path_elements) OR
            ((working_catalog.evaluated_file_reference.path_structure_size + 1 + element_size) >
*IFEND
            fsc$max_path_size) THEN
        osp$set_status_condition (cle$file_reference_too_long, status);
      ELSE
*IF NOT $true(osv$unix)
        evaluated_file_reference := working_catalog^^.evaluated_file_reference;
        evaluated_file_reference.path_resolution := fsc$unresolved_path;
        evaluated_file_reference.path_handle_info.path_handle_present := FALSE;
*ELSE
        evaluated_file_reference := working_catalog.evaluated_file_reference;
*IFEND
      IFEND;

    PROCEND find_working_catalog;
?? TITLE := 'get_file_ref_from_path_handle', EJECT ??

    PROCEDURE get_file_ref_from_path_handle;

*IF NOT $true(osv$unix)
      IF evaluated_file_reference.path_handle_info.path_handle.open_position.specified THEN
        path_handle.regular_handle.open_position := evaluated_file_reference.path_handle_info.path_handle.
              open_position;
      IFEND;
*IFEND
      IF command_file_reference THEN
*IF NOT $true(osv$unix)
        evaluated_file_reference.path_resolution := fsc$command_file_path;
        evaluated_file_reference.block_handle := block_handle;
*ELSE
        evaluated_file_reference.command_file_path.found := TRUE;
        evaluated_file_reference.command_file_path.block_handle := block_handle;
*IFEND
        IF clc$file_ref_evaluation_stage IN file_reference_parsing_options THEN
*IF NOT $true(osv$unix)
          clp$construct_block_handle_name (evaluated_file_reference.block_handle, block_handle_name);
*ELSE
          clp$construct_block_handle_name (evaluated_file_reference.command_file_path.block_handle,
                block_handle_name);
*IFEND
          append_element (8, '$COMMAND');
          append_element (clp$trimmed_string_size (block_handle_name), block_handle_name);
          RETURN;
        IFEND;
      IFEND;
*IF NOT $true(osv$unix)
      bap$get_path_elements (path_handle.regular_handle, evaluated_file_reference, status);
      IF NOT status.normal THEN

{
{ Bap$get_path_elements initializes evaluated_file_reference even if a bad status was returned.
{ Therefore you lose everything up to this point in evaluated_file_reference when the status is bad.
{

        status.normal := TRUE;
      ELSE
        cycle_element_found := evaluated_file_reference.cycle_reference.specification <> fsc$cycle_omitted;
      IFEND;
      IF command_file_reference THEN
        evaluated_file_reference.path_resolution := fsc$command_file_path;
        evaluated_file_reference.block_handle := block_handle;
      IFEND;
*IFEND

    PROCEND get_file_ref_from_path_handle;
?? TITLE := 'get_path_handle_for_stand_file', EJECT ??

    PROCEDURE get_path_handle_for_stand_file;


*IF NOT $true(osv$unix)
    /get_path_handle/
      BEGIN

        CASE evaluated_file_reference.cycle_reference.specification OF
        = fsc$high_cycle, fsc$low_cycle =
          IF cycle_offset <> 0 THEN
            EXIT /get_path_handle/;
          IFEND;
          evaluated_file_reference.cycle_reference.specification := fsc$cycle_number;
          evaluated_file_reference.cycle_reference.cycle_number := 1;
        = fsc$next_cycle =
          IF cycle_offset <> -1 THEN
            EXIT /get_path_handle/;
          IFEND;
          evaluated_file_reference.cycle_reference.specification := fsc$cycle_number;
          evaluated_file_reference.cycle_reference.cycle_number := 1;
        = fsc$cycle_number =
          IF evaluated_file_reference.cycle_reference.cycle_number <> 1 THEN
            EXIT /get_path_handle/;
          IFEND;
        ELSE {fsc$cycle_omitted}
          evaluated_file_reference.cycle_reference.specification := fsc$cycle_number;
          evaluated_file_reference.cycle_reference.cycle_number := 1;
        CASEND;

        IF clv$standard_files [standard_file].path_handle_name = osc$null_name THEN
          work_list := $bat$process_pt_work_list [bac$externalize_path_handle, bac$record_path];

          bap$process_pt_request (work_list, osc$null_name, evaluated_file_reference, ignore_pt_results,
                status);
          IF (NOT status.normal) AND osp$file_access_condition (status) THEN
            process_pt_request (work_list, osc$null_name, evaluated_file_reference, ignore_pt_results,
                  status);
          IFEND;
          process_status (evaluated_file_reference.path_handle_info, evaluated_file_reference.path_resolution,
                'clp$complete_file_ref_parse', status);
        ELSE
          evaluated_file_reference.path_handle_info.path_handle_present := TRUE;
          evaluated_file_reference.path_handle_info.path_handle :=
                clv$standard_files [standard_file].path_handle;
        IFEND;
        RETURN;
      END /get_path_handle/;

      osp$set_status_abnormal ('CL', cle$only_cycle_one_allowed,
            clv$standard_files [standard_file].path_handle_name, status);
*ELSE
      evaluated_file_reference.standard_file := TRUE;
      evaluated_file_reference.unix_standard_file := clv$standard_files [standard_file];
*IFEND

    PROCEND get_path_handle_for_stand_file;
?? TITLE := 'get_path_handle_from_cmnd_file', EJECT ??

    PROCEDURE get_path_handle_from_cmnd_file;


      IF NOT (clc$command_file_ref_allowed IN file_reference_parsing_options) THEN
        osp$set_status_condition (cle$inappropriate_cmnd_file_ref, status);
        RETURN;
      IFEND;
      IF block = NIL THEN
        clp$find_command_input_block (path_handle.block_handle, block, ignore_block_in_current_task);
      IFEND;
      IF block = NIL THEN
        path_handle.kind := clc$not_a_path_handle;
      ELSEIF (block^.kind = clc$task_block) OR (block^.input.kind <> clc$file_input) THEN
*IF NOT $true(osv$unix)
        evaluated_file_reference.path_resolution := fsc$command_file_path;
        evaluated_file_reference.block_handle := path_handle.block_handle;
*ELSE
        evaluated_file_reference.command_file_path.found := TRUE;
        evaluated_file_reference.command_file_path.block_handle := path_handle.block_handle;
*IFEND
        path_handle.kind := clc$not_a_path_handle;
        evaluated_file_reference.path_structure := '';
        evaluated_file_reference.path_structure_size := 0;
        evaluated_file_reference.number_of_path_elements := 0;
        IF clc$file_ref_evaluation_stage IN file_reference_parsing_options THEN
*IF NOT $true(osv$unix)
          clp$construct_block_handle_name (evaluated_file_reference.block_handle, block_handle_name);
*ELSE
          clp$construct_block_handle_name (evaluated_file_reference.command_file_path.block_handle,
                block_handle_name);
*IFEND
          append_element (8, '$COMMAND');
          append_element (clp$trimmed_string_size (block_handle_name), block_handle_name);
          RETURN;
        IFEND;
        append_element (6, '$LOCAL');
        append_element (5, '$NULL');
        standard_file := clc$sf_null_file;
      ELSE
        command_file_reference := TRUE;
        block_handle := path_handle.block_handle;
        clp$check_name_for_path_handle (block^.input.local_file_name, path_handle);
      IFEND;

    PROCEND get_path_handle_from_cmnd_file;
*IF NOT $true(osv$unix)
?? TITLE := 'process_program_name', EJECT ??

    PROCEDURE [INLINE] process_program_name;

      string_found := TRUE;
      NEXT string_value: [current_parse.unit.size - 2] IN work_area;
      IF string_value = NIL THEN
        osp$set_status_condition (cle$work_area_overflow, status);
        RETURN;
      IFEND;
      string_value^ (1, current_parse.unit.size - 2) := current_parse.
            text^ (current_parse.unit_index + 1, current_parse.unit.size - 2);

      WHILE TRUE DO
        clp$scan_any_lexical_unit (current_parse);
        CASE current_parse.unit.kind OF
        = clc$lex_string =
          RESET work_area TO string_value;
          NEXT string_value: [STRLENGTH (string_value^) + current_parse.unit.size - 1] IN work_area;
          IF string_value = NIL THEN
            osp$set_status_condition (cle$work_area_overflow, status);
            RETURN;
          IFEND;
          string_value^ (STRLENGTH (string_value^) - current_parse.unit.size + 2,
                current_parse.unit.size - 1) := current_parse.text^
                (current_parse.unit_index, current_parse.unit.size - 1);
        = clc$lex_unterminated_string =
          osp$set_status_abnormal ('CL', cle$missing_string_delimiter, current_parse.
                text^ (current_parse.unit_index, current_parse.unit.size), status);
          RETURN;
        ELSE
          string_size := STRLENGTH (string_value^);
          IF string_size > osc$max_name_size THEN
            osp$set_status_abnormal ('CL', cle$program_name_too_long, string_value^ (1, string_size), status);
            RETURN;
          ELSEIF string_size < 1 THEN
            osp$set_status_condition (cle$null_program_name, status);
            RETURN;
          ELSEIF string_value^ = osc$null_name THEN
            osp$set_status_condition (cle$null_program_name, status);
            RETURN;
          IFEND;
          command_or_program_name.value := string_value^ (1, string_size);
          command_or_program_name.size := string_size;
          command_or_program_name_found := TRUE;
          IF NOT cycle_element_found THEN
            IF (evaluated_file_reference.number_of_path_elements >= fsc$max_path_elements) OR
                  ((evaluated_file_reference.path_structure_size + 1 + string_size) > fsc$max_path_size) THEN
              osp$set_status_condition (cle$file_reference_too_long, status);
              RETURN;
            IFEND;
            append_element (string_size, string_value^);
          IFEND;
          RETURN;
        CASEND;
      WHILEND;

    PROCEND process_program_name;
*ELSE
?? TITLE := 'rescan_path_element_lex_unit', EJECT ??

{
{ PURPOSE:
{   This procedure updates its PARSE parameter to designate the lexical
{   unit(s), beginning with the current unit, that represent an element of a
{   file path.
{

    PROCEDURE [INLINE] rescan_path_element_lex_unit
      (VAR parse {input, output} : clt$parse_state);


      IF parse.unit.kind IN path_syntax.first_element_units THEN
        scan_path_element_lex_units (parse);
      IFEND;

    PROCEND rescan_path_element_lex_unit;
?? TITLE := 'scan_next_path_element_lex_unit', EJECT ??

{
{ PURPOSE:
{   This procedure updates its PARSE parameter to designate the next lexical
{   unit(s) that represent an element of a file path.
{

    PROCEDURE [INLINE] scan_next_path_element_lex_unit
      (VAR parse {input, output} : clt$parse_state);


      IF parse.unit_index < parse.index_limit THEN
        IF NOT parse.unit_is_space THEN
          parse.previous_non_space_unit := parse.unit;
          parse.previous_non_space_unit_index := parse.unit_index;
        IFEND;

        parse.previous_unit_is_space := parse.unit_is_space;
        parse.unit_index := parse.index;
        parse.units_array_index := parse.units_array_index + 1;
        parse.unit := parse.units_array^ [parse.units_array_index];
        parse.index := parse.index + parse.unit.size;

        IF parse.unit.kind IN path_syntax.first_element_units THEN
          parse.unit_is_space := FALSE;
          scan_path_element_lex_units (parse);
        ELSE
          parse.unit_is_space := parse.unit.kind IN $clt$lexical_unit_kinds
                [clc$lex_space, clc$lex_comment, clc$lex_unterminated_comment];
        IFEND;
      IFEND;

    PROCEND scan_next_path_element_lex_unit;
?? TITLE := 'scan_path_element_lex_units', EJECT ??

{
{ PURPOSE:
{
{   This procedure is called by RESCAN_PATH_ELEMENT_LEX_UNIT and
{   SCAN_PATH_ELEMENT_LEX_UNIT to perform the bulk of their processing.  It is
{   called when the current lexical unit is one that can start a path element.
{   It updates its PARSE parameter to designate the lexical unit(s) that
{   represent an element of a file path.
{
{   The path element may include "wild card" characters.  The unit kind
{   CLC$LEX_WILD_CARD_NAME can be thought of as a "compound" unit comprised of
{   one or more of the "simple" units:  CLC$LEX_NAME, CLC$LEX_LONG_NAME,
{   CLC$LEX_ALPHA_NUMBER, CLC$LEX_UNSIGNED_DECIMAL, CLC$LEX_QUERY,
{   CLC$LEX_MULTIPLY, CLC$LEX_EXPONENTIATE, CLC$LEX_SUBTRACT and, in the case
{   of a UNIX style path, CLC$LEX_DOT.
{
{   If the resulting unit kind when parsing a UNIX style path is
{   CLC$LEX_ALHA_NUMBER, the first lexical unit of the element is either a
{   CLC$LEX_ALHA_NUMBER or the path element contains a CLC$LEX_DOT.
{

    PROCEDURE [INLINE] scan_path_element_lex_units
      (VAR parse {input, output} : clt$parse_state);

      VAR
        result_unit_kind: clt$lexical_unit_kind;


      result_unit_kind := parse.unit.kind;

    /scan_units/
      WHILE TRUE DO
        IF result_unit_kind <> clc$lex_wild_card_name THEN
          IF parse.unit.kind IN $clt$lexical_unit_kinds [clc$lex_query, clc$lex_multiply,
                clc$lex_exponentiate] THEN
            result_unit_kind := clc$lex_wild_card_name;
          ELSEIF parse.unit.kind IN $clt$lexical_unit_kinds [clc$lex_dot] THEN
            result_unit_kind := clc$lex_alpha_number;
          IFEND;
        IFEND;

        IF parse.index >= parse.index_limit THEN
          EXIT /scan_units/;
        ELSEIF parse.units_array^ [parse.units_array_index + 1].kind IN path_syntax.element_units THEN
          ;
        ELSEIF parse.units_array^ [parse.units_array_index + 1].kind = clc$lex_subtract THEN

{ Should only get here for a NOS/VE style path since CLC$LEX_SUBTRACT is in
{ PATH_SYNTAX.ELEMENT_UNITS for a UNIX style path.

{ A "-" (clc$lex_subtract) can only be part of a NOS/VE path element if it is
{ used in a "character class" sequence (e.g., [a-b]).  This can only occur if
{ it is followed by other unit(s) that could be part of a path elemnet, unless
{ it is just followed by a clc$lex_unsigned_decimal (which cannot contain a "]").

          CASE parse.units_array^ [parse.units_array_index + 2].kind OF
          = clc$lex_name, clc$lex_long_name, clc$lex_alpha_number, clc$lex_query, clc$lex_multiply,
                clc$lex_exponentiate =
            result_unit_kind := clc$lex_wild_card_name;
          = clc$lex_unsigned_decimal =
            IF NOT (parse.units_array^ [parse.units_array_index + 3].kind IN
                  $clt$lexical_unit_kinds [clc$lex_name, clc$lex_long_name, clc$lex_alpha_number,
                  clc$lex_query, clc$lex_multiply, clc$lex_exponentiate]) THEN
              EXIT /scan_units/;
            IFEND;
            result_unit_kind := clc$lex_wild_card_name;
          ELSE
            EXIT /scan_units/;
          CASEND;
        ELSE
          EXIT /scan_units/;
        IFEND;

        parse.units_array_index := parse.units_array_index + 1;
        parse.unit.kind := parse.units_array^ [parse.units_array_index].kind;
        parse.index := parse.index + parse.units_array^ [parse.units_array_index].size;
      WHILEND /scan_units/;

      parse.unit.kind := result_unit_kind;
      parse.unit.size := parse.index - parse.unit_index;

    PROCEND scan_path_element_lex_units;
?? TITLE := 'setup_path_syntax_descriptor', EJECT ??

{
{ PURPOSE:
{   This procedure initializes the information in the variable PATH_SYNTAX that
{   describes the syntactic differences between a NOS/VE style file path and a
{   UNIX style file path.  This information is then used to make decisions in a
{   more efficient manner than possible by repeatedly asking, "Are we parsing a
{   NOS/VE or UNIX path?"
{

    PROCEDURE [INLINE] setup_path_syntax_descriptor;


    unix_path_syntax.delimiter := clc$lex_divide;
    unix_path_syntax.delimiter_or_concatenate := $clt$lexical_unit_kinds [clc$lex_divide,
          clc$lex_concatenate];
    unix_path_syntax.first_path_units := $clt$lexical_unit_kinds
          [clc$lex_divide, clc$lex_name, clc$lex_long_name, clc$lex_unsigned_decimal,
          clc$lex_alpha_number, clc$lex_dot, clc$lex_query, clc$lex_multiply, clc$lex_exponentiate];
    unix_path_syntax.first_element_units := $clt$lexical_unit_kinds
          [clc$lex_name, clc$lex_long_name, clc$lex_unsigned_decimal, clc$lex_alpha_number, clc$lex_dot,
          clc$lex_query, clc$lex_multiply, clc$lex_exponentiate];
    unix_path_syntax.element_units := $clt$lexical_unit_kinds
          [clc$lex_name, clc$lex_long_name, clc$lex_unsigned_decimal, clc$lex_alpha_number, clc$lex_dot,
          clc$lex_query, clc$lex_multiply, clc$lex_exponentiate,
          clc$lex_add, clc$lex_subtract];

    ve_path_syntax.delimiter := clc$lex_dot;
    ve_path_syntax.delimiter_or_concatenate := $clt$lexical_unit_kinds [clc$lex_dot, clc$lex_concatenate];
    ve_path_syntax.first_path_units := $clt$lexical_unit_kinds
          [clc$lex_colon, clc$lex_dot, clc$lex_name, clc$lex_long_name, clc$lex_query, clc$lex_multiply,
          clc$lex_exponentiate];
    ve_path_syntax.first_element_units := $clt$lexical_unit_kinds
          [clc$lex_name, clc$lex_long_name, clc$lex_query, clc$lex_multiply, clc$lex_exponentiate];
    ve_path_syntax.element_units := $clt$lexical_unit_kinds
          [clc$lex_name, clc$lex_long_name, clc$lex_unsigned_decimal, clc$lex_alpha_number, clc$lex_query,
          clc$lex_multiply, clc$lex_exponentiate];

    PROCEND setup_path_syntax_descriptor;
*IFEND
?? TITLE := 'update_current_parse', EJECT ??

    PROCEDURE [INLINE] update_current_parse;

{ Keep track if there is a generic path element in the file reference (and evaluation was deferrred).

      IF NOT generic_element_present THEN
        generic_element_present := previous_element_is_generic;
      IFEND;

{ We do not "need_to_scan" if we have just checked for a cycle offset or
{ evaluated :$DEFER.file_var_or_fcn.
{ Set the boolean back to TRUE after the test.

      IF need_to_scan THEN
        clp$scan_any_lexical_unit (current_parse);
      IFEND;
      need_to_scan := TRUE;
      IF current_parse.unit.kind = clc$lex_end_of_line THEN

{ If "initial_path" is not NIL, then we just got done parsing it.
{ Reset the current_parse to the original parse state and set "initial_path" to
{   NIL to prevent an additional iteration.

        IF initial_path <> NIL THEN
          IF initial_path_passed_in THEN
            current_parse := parse;
          ELSEIF saved_parse_ptr <> NIL THEN
            current_parse := saved_parse_ptr^;
          IFEND;
          initial_path := NIL;
        IFEND;
      IFEND;

    PROCEND update_current_parse;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;

    IF (clc$evaluating_command_ref IN file_reference_parsing_options) AND
          (clc$evaluating_entry_point_ref IN file_reference_parsing_options) THEN
      osp$set_status_condition (cle$conflicting_parse_options, status);
      RETURN;
    IFEND;

    path_handle.kind := clc$not_a_path_handle;
    evaluated_file_reference := fsv$evaluated_file_reference;
    standard_file := clc$sf_not_a_standard_file;
    command_file_reference := FALSE;
    block := NIL;
*IF NOT $true(osv$unix)
    previous_element_is_generic := FALSE;
    generic_element_present := FALSE;
    cycle_element_found := FALSE;
    position_element_found := FALSE;
*IFEND
    command_or_program_name_found := FALSE;
    number := 0;
    append := TRUE;
    need_to_scan := TRUE;
    initial_path_passed_in := initial_path <> NIL;
    saved_parse_ptr := NIL;
    saved_work_area := work_area;
    parameter_name := osc$null_name;
    cycle_offset := 0;
*IF NOT $true(osv$unix)
    string_found := FALSE;
    encountered_$defer := FALSE;
*IFEND
    wild_card_chars := $chars ['[', '{'];

*IF NOT $true(osv$unix)
    clp$find_scl_options (scl_options);

*IF NOT $true(osv$unix)
    clp$rescan_wild_card_lex_unit (parse);
*IFEND
*ELSE
    setup_path_syntax_descriptor;
    CASE parse.unit.kind OF
    = clc$lex_colon =
      path_syntax := ve_path_syntax;
      rescan_path_element_lex_unit (parse);
    = clc$lex_ellipsis =
      path_syntax := unix_path_syntax;
      clp$find_working_catalog (working_catalog, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      evaluated_file_reference.path_structure := working_catalog.evaluated_file_reference.
            path_structure;
      evaluated_file_reference.path_structure_size := working_catalog.evaluated_file_reference.
            path_structure_size;
      evaluated_file_reference.number_of_path_elements :=
            working_catalog.evaluated_file_reference.number_of_path_elements;

      clp$remove_last_path_element (evaluated_file_reference, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      clp$scan_any_lexical_unit (parse);
    = clc$lex_divide, clc$lex_dot =
      path_syntax := unix_path_syntax;
      rescan_path_element_lex_unit (parse);
    = clc$lex_alpha_number, clc$lex_unsigned_decimal =
      path_syntax := unix_path_syntax;
      rescan_path_element_lex_unit (parse);
    ELSE
{     path_syntax := unix_path_syntax;
{     rescan_path_element_lex_unit (parse);
      ;
    CASEND;
*IFEND

  /parse_file_reference/
    BEGIN
*IF NOT $true(osv$unix)
      IF (initial_path = NIL) AND NOT (parse.unit.kind IN $clt$lexical_unit_kinds
            [clc$lex_colon, clc$lex_dot, clc$lex_name, clc$lex_wild_card_name,
            clc$lex_long_name]) THEN
        osp$set_status_condition (cle$expecting_file_reference, status);
        clp$append_status_parse_state (osc$status_parameter_delimiter, parse, status);
        EXIT /parse_file_reference/;
      IFEND;

{ If the initial_path is not NIL, then it represents an evaluated file variable or function.
{ The initial_path is an absolute path, i.e. it will begin with a colon.

      IF initial_path <> NIL THEN
        initial_path := ^initial_path^ (1, clp$trimmed_string_size (initial_path^));
        clp$identify_lexical_units (initial_path, work_area, units, status);
        IF NOT status.normal THEN
          EXIT /parse_file_reference/;
        IFEND;
        clp$initialize_parse_state (initial_path, units, current_parse);
        clp$scan_non_space_lexical_unit (current_parse);
      ELSE
*IFEND
        current_parse := parse;
*IF NOT $true(osv$unix)
      IFEND;

*ELSE

      element_text := ^current_parse.text^ (current_parse.unit_index, current_parse.unit.size);
*IFEND
      element.kind := clc$not_a_special_path_element;
      CASE current_parse.unit.kind OF
*IF NOT $true(osv$unix)
      = clc$lex_colon =
        ;
      = clc$lex_dot =
        IF (user_identification.family.size = 0) THEN
          osp$set_status_condition (cle$undefined_user_ident, status);
          EXIT /parse_file_reference/;
        IFEND;

        append_element (user_identification.family.size, user_identification.family.value);
*ELSE

      = clc$lex_colon, clc$lex_divide =
{ Checked at top of /parse_path/ loop.

      = clc$lex_dot =

        path_syntax := unix_path_syntax;
        rescan_path_element_lex_unit (current_parse);
*IFEND

      = clc$lex_name =
*IF NOT $true(osv$unix)
        #TRANSLATE (osv$lower_to_upper, current_parse.text^
              (current_parse.unit_index, current_parse.unit.size), element_name);
*ELSE
        #TRANSLATE (osv$lower_to_upper, element_text^, element_name);
*IFEND
        element_size := current_parse.unit.size;
        found := FALSE;
*IF NOT $true(osv$unix)
        clp$scan_any_lexical_unit (current_parse);
*ELSE
        saved_parse := current_parse;
        clp$scan_any_lexical_unit (saved_parse);
*IFEND
*IF NOT $true(osv$unix)

{ If we find a left parenthesis, then evaluate as a function

        IF (current_parse.unit.kind = clc$lex_left_parenthesis) AND
              NOT (clc$prevent_job_context_element IN file_reference_parsing_options) THEN
          evaluate_file_var_or_fcn;
          IF NOT status.normal THEN
            EXIT /parse_file_reference/;
          IFEND;
        IFEND;
        IF NOT found THEN
*IFEND
          check_for_special_path_element (element_name, element_size, element);
*IF $true(osv$unix)
          IF element.kind = clc$not_a_special_path_element THEN
            path_syntax := unix_path_syntax;
            rescan_path_element_lex_unit (current_parse);
            element_text := ^current_parse.text^ (current_parse.unit_index, current_parse.unit.size);
            element_name := element_text^;
            element_size := current_parse.unit.size;
            clp$scan_any_lexical_unit (current_parse);
          ELSE
            path_syntax := ve_path_syntax;
            rescan_path_element_lex_unit (current_parse);
            element_text := ^current_parse.text^ (current_parse.unit_index, current_parse.unit.size);
            #TRANSLATE (osv$lower_to_upper, element_text^, element_name);
            element_size := current_parse.unit.size;
            current_parse := saved_parse;
          IFEND;
{         clp$scan_any_lexical_unit (current_parse);
*IFEND
          evaluate_first_element;
          IF NOT status.normal THEN
            EXIT /parse_file_reference/;
          IFEND;
*IF NOT $true(osv$unix)
        IFEND;
*IFEND

      = clc$lex_wild_card_name =
*IF NOT $true(osv$unix)
        IF NOT (clc$multiple_reference_allowed IN file_reference_parsing_options) THEN
*IFEND
          osp$set_status_condition (cle$wild_card_not_allowed, status);
          EXIT /parse_file_reference/;
*IF NOT $true(osv$unix)
        IFEND;
        append_working_catalog (current_parse.unit.size);
        IF NOT status.normal THEN
          EXIT /parse_file_reference/;
        IFEND;
        append_wild_card (current_parse.text^ (current_parse.unit_index, current_parse.unit.size));
        clp$scan_any_lexical_unit (current_parse);
*IFEND

      = clc$lex_long_name =
*IF NOT $true(osv$unix)
        #SCAN (wild_card_chars, current_parse.text^ (current_parse.unit_index, current_parse.unit.size),
              ignore_scan_index, scan_found_char);
        IF (clc$multiple_reference_allowed IN file_reference_parsing_options) AND
              (scl_options^.wild_card_pattern_type = clc$wc_extended_pattern) AND scan_found_char THEN
*ELSE
        path_syntax := unix_path_syntax;
        rescan_path_element_lex_unit (current_parse);
*IFEND
          append_working_catalog (current_parse.unit.size);
          IF NOT status.normal THEN
            EXIT /parse_file_reference/;
          IFEND;
*IF NOT $true(osv$unix)
          append_wild_card (current_parse.text^ (current_parse.unit_index, current_parse.unit.size));
*ELSE
        append_wild_card (element_text^);
*IFEND
          clp$scan_any_lexical_unit (current_parse);
*IF NOT $true(osv$unix)
        ELSE
          osp$set_status_abnormal ('CL', cle$name_too_long, current_parse.
                text^ (current_parse.unit_index, current_parse.unit.size), status);
          EXIT /parse_file_reference/;
        IFEND;
*ELSE

      = clc$lex_unterminated_string =
        osp$set_status_abnormal ('CL', cle$missing_string_delimiter, element_text^, status);
        EXIT /parse_file_reference/;

      = clc$lex_alpha_number, clc$lex_unsigned_decimal =
        append_working_catalog (current_parse.unit.size);
        IF NOT status.normal THEN
          EXIT /parse_file_reference/;
        IFEND;
        append_element (current_parse.unit.size, element_text^);
        clp$scan_any_lexical_unit (current_parse);

*IFEND
      ELSE
        osp$set_status_condition (cle$expecting_file_reference, status);
        clp$append_status_parse_state (osc$status_parameter_delimiter, current_parse, status);
        EXIT /parse_file_reference/;
      CASEND;


    /parse_path/
*IF NOT $true(osv$unix)
      WHILE (current_parse.unit.kind IN $clt$lexical_unit_kinds
            [clc$lex_colon, clc$lex_dot, clc$lex_concatenate]) AND (NOT string_found) DO
        IF (evaluated_file_reference.number_of_path_elements > 0) AND
              (current_parse.unit.kind = clc$lex_colon) THEN
          osp$set_status_condition (cle$unexpected_colon_in_path, status);
          EXIT /parse_file_reference/;
        IFEND;

        IF (current_parse.unit.kind = clc$lex_concatenate) THEN
          IF (evaluated_file_reference.number_of_path_elements = 0) THEN
            osp$set_status_condition (cle$concatenate_cant_be_first, status);
            EXIT /parse_file_reference/;
          ELSEIF clc$prevent_job_context_element IN file_reference_parsing_options THEN
            osp$set_status_abnormal ('CL', cle$no_concat_in_job_indep_path, element_name (1, element_size),
                  status);
            EXIT /parse_file_reference/;
          IFEND;
        IFEND;
*ELSE
      WHILE TRUE DO
        CASE current_parse.unit.kind OF

        = clc$lex_dot =
          ;

        = clc$lex_divide =
          IF path_syntax = ve_path_syntax THEN
            osp$set_status_condition (cle$expecting_file_reference, status);
            clp$append_status_parse_state (osc$status_parameter_delimiter, current_parse, status);
            EXIT /parse_file_reference/;
          IFEND;

        = clc$lex_colon =
          IF (path_syntax = unix_path_syntax) OR
                (evaluated_file_reference.number_of_path_elements > 0) THEN
            osp$set_status_condition (cle$unexpected_colon_in_path, status);
            EXIT /parse_file_reference/;
          IFEND;

        = clc$lex_concatenate =
          osp$set_status_abnormal ('CL', cle$no_concat_in_job_indep_path, element_name (1, element_size),
                  status);
          EXIT /parse_file_reference/;

        = clc$lex_ellipsis =
          IF (path_syntax = unix_path_syntax) AND (current_parse.unit.size = 2) THEN
            osp$set_status_condition (cle$expecting_path_element, status);
            clp$append_status_parse_state (osc$status_parameter_delimiter, current_parse, status);
            EXIT /parse_file_reference/;
          IFEND;
          EXIT /parse_path/;

        ELSE
          EXIT /parse_path/;
        CASEND;

*IFEND

*IF NOT $true(osv$unix)
        previous_unit_is_concatenate := FALSE;
        clp$scan_wild_card_lexical_unit (current_parse);

        CASE current_parse.unit.kind OF
*ELSE
        scan_next_path_element_lex_unit (current_parse);
        element_text := ^current_parse.text^ (current_parse.unit_index, current_parse.unit.size);
        CASE current_parse.unit.kind OF

*IFEND
        = clc$lex_name =
*IF NOT $true(osv$unix)
          #TRANSLATE (osv$lower_to_upper, current_parse.text^
                (current_parse.unit_index, current_parse.unit.size), element_name);
*ELSE
          IF path_syntax = ve_path_syntax THEN
            #TRANSLATE (osv$lower_to_upper, element_text^, element_name);
          ELSE
            element_name := element_text^;
          IFEND;
*IFEND
          append := TRUE;
          found := FALSE;

          element_size := current_parse.unit.size;
          check_for_special_path_element (element_name, element_size, element);
*IF NOT $true(osv$unix)
          IF (current_parse.previous_non_space_unit.kind = clc$lex_concatenate) THEN
*ELSE
          IF current_parse.previous_non_space_unit.kind = clc$lex_concatenate THEN
*IFEND

{ If a concatenation operator is found and INITIAL_PATH is not NIL, then the value of the file variable
{ or function was incorrectly initialized (probably thru the program interface).

*IF NOT $true(osv$unix)
            IF initial_path <> NIL THEN
              osp$set_status_condition (cle$no_concat_in_var_or_fcn, status);
              RETURN;
            IFEND;
            IF (element.kind = clc$cycle_path_element) OR (element.kind = clc$position_path_element) THEN
              clp$scan_any_lexical_unit (current_parse);
              need_to_scan := FALSE;
            ELSE
              evaluate_name_or_num_var_or_fcn;
              IF NOT status.normal THEN
                EXIT /parse_file_reference/;
              IFEND;
            IFEND;
            previous_unit_is_concatenate := TRUE;
          ELSEIF (element.kind = clc$cycle_path_element) OR (element.kind = clc$position_path_element) THEN
            clp$scan_any_lexical_unit (current_parse);
            need_to_scan := FALSE;
*ELSE
              osp$set_status_condition (cle$no_concat_in_var_or_fcn, status);
              EXIT /parse_file_reference/;
*IFEND
          IFEND;

          CASE element.kind OF

          = clc$command_file_path_element =

            IF evaluated_file_reference.number_of_path_elements <> 0 THEN
              osp$set_status_abnormal ('CL', cle$special_element_not_first, element_name, status);
              EXIT /parse_file_reference/;
            IFEND;

*IF NOT $true(osv$unix)
            IF clc$prevent_job_context_element IN file_reference_parsing_options THEN
              osp$set_status_abnormal ('CL', cle$no_job_context_elements, element_name (1, element_size),
                    status);
              EXIT /parse_file_reference/;
            IFEND;
*IFEND

            evaluate_$command;
            IF NOT status.normal THEN
              EXIT /parse_file_reference/;
            IFEND;

*IF NOT $true(osv$unix)
          = clc$current_family_path_element =

            IF evaluated_file_reference.number_of_path_elements <> 0 THEN
              osp$set_status_abnormal ('CL', cle$special_element_not_first, element_name, status);
              EXIT /parse_file_reference/;
            IFEND;

            IF NOT (clc$file_ref_evaluation_stage IN file_reference_parsing_options) THEN
              IF (user_identification.family.size = 0) THEN
                osp$set_status_condition (cle$undefined_user_ident, status);
                EXIT /parse_file_reference/;
              IFEND;
              element_name := user_identification.family.value;
              element_size := user_identification.family.size;
            IFEND;
            path_handle.kind := clc$not_a_path_handle;
            previous_element_is_generic := clc$file_ref_evaluation_stage IN file_reference_parsing_options;

          = clc$current_user_path_element =

            IF (NOT (clc$file_ref_evaluation_stage IN file_reference_parsing_options)) AND
                  ((evaluated_file_reference.number_of_path_elements > 1) OR
                  ((evaluated_file_reference.number_of_path_elements = 1) AND
                  (fsp$path_element (^evaluated_file_reference, 1) ^ = fsc$local))) THEN
              osp$set_status_abnormal ('CL', cle$special_element_not_first, element_name, status);
              EXIT /parse_file_reference/;
            IFEND;

            IF cycle_element_found OR position_element_found THEN
              osp$set_status_condition (no_extra [position_element_found], status);
              EXIT /parse_file_reference/;
            IFEND;

            IF NOT (clc$file_ref_evaluation_stage IN file_reference_parsing_options) THEN
              IF evaluated_file_reference.number_of_path_elements = 0 THEN
                IF (user_identification.family.size = 0) THEN
                  osp$set_status_condition (cle$undefined_user_ident, status);
                  EXIT /parse_file_reference/;
                IFEND;
                append_element (user_identification.family.size, user_identification.family.value);
              IFEND;
              IF (user_identification.user.size = 0) THEN
                osp$set_status_condition (cle$undefined_user_ident, status);
                EXIT /parse_file_reference/;
              IFEND;
              element_name := user_identification.user.value;
              element_size := user_identification.user.size;
            IFEND;
            path_handle.kind := clc$not_a_path_handle;
            previous_element_is_generic := clc$file_ref_evaluation_stage IN file_reference_parsing_options;

          = clc$cycle_path_element, clc$var_or_fcn_cyc_path_element =

            IF command_or_program_name_found OR (evaluated_file_reference.number_of_path_elements <= 1) THEN
              osp$set_status_condition (cle$cycle_must_follow_file_name, status);
              EXIT /parse_file_reference/;
            IFEND;

            cycle_offset_found := FALSE;
            cycle_offset := 0;

            IF previous_unit_is_concatenate THEN
              IF evaluated_file_reference.multiple_reference_specified THEN
                osp$set_status_condition (cle$no_cyc_expr_with_wild_card, status);
                EXIT /parse_file_reference/;
              IFEND;

              check_for_cycle_offset;
              IF NOT status.normal THEN
                EXIT /parse_file_reference/;
              IFEND;
              cycle_offset_found := TRUE;
            IFEND;

            IF element.kind = clc$cycle_path_element THEN
              evaluated_file_reference.cycle_reference := element.cycle_reference;
            ELSE

{ "element.kind" gets set to clc$var_or_fcn_cyc_path_element if a name was evaluated to be an integer
{ variable or function. "number" will be set to the value of that variable or function.

              IF ((number + cycle_offset) < pfc$minimum_cycle_number) OR
                    ((number + cycle_offset) > pfc$maximum_cycle_number) THEN
                osp$set_status_condition (pfe$bad_cycle_number, status);
                osp$append_status_integer (osc$status_parameter_delimiter, (number + cycle_offset), 10, FALSE,
                      status);
                EXIT /parse_file_reference/;
              IFEND;
              evaluated_file_reference.cycle_reference.specification := fsc$cycle_number;
              evaluated_file_reference.cycle_reference.cycle_number := number + cycle_offset;
            IFEND;

            cycle_element_found := TRUE;
            path_handle.kind := clc$not_a_path_handle;

          = clc$defer_eval_path_element =

            IF evaluated_file_reference.number_of_path_elements <> 0 THEN
              osp$set_status_abnormal ('CL', cle$special_element_not_first, element_name, status);
              EXIT /parse_file_reference/;
            IFEND;

            IF clc$prevent_job_context_element IN file_reference_parsing_options THEN
              osp$set_status_abnormal ('CL', cle$no_job_context_elements, element_name (1, element_size),
                    status);
              EXIT /parse_file_reference/;
            IFEND;

            evaluate_$defer;
            IF NOT status.normal THEN
              EXIT /parse_file_reference/;
            IFEND;
*IFEND

          = clc$job_file_path_element, clc$standard_file_path_element =

*IF NOT $true(osv$unix)
            IF clc$prevent_job_context_element IN file_reference_parsing_options THEN
              osp$set_status_abnormal ('CL', cle$no_job_context_elements, element_name (1, element_size),
                    status);
              EXIT /parse_file_reference/;
            IFEND;
*IFEND

            IF standard_file <> clc$sf_not_a_standard_file THEN
              standard_file := clc$sf_not_a_standard_file;
*IF NOT $true(osv$unix)
            ELSEIF evaluated_file_reference.path_structure (1,
                  evaluated_file_reference.path_structure_size) = ($CHAR (6) CAT '$LOCAL') THEN
*ELSE
            ELSEIF evaluated_file_reference.path_structure (1, evaluated_file_reference.path_structure_size) =
                  ($CHAR (6) CAT '$LOCAL') THEN
*IFEND
              standard_file := element.standard_file;
            IFEND;

*IF NOT $true(osv$unix)
            IF standard_file = clc$sf_not_a_standard_file THEN
              IF cycle_element_found OR position_element_found THEN
                IF (($clt$file_ref_parsing_options [clc$evaluating_command_ref,
                      clc$evaluating_entry_point_ref] * file_reference_parsing_options) =
                      $clt$file_ref_parsing_options []) OR command_or_program_name_found THEN
                  osp$set_status_condition (no_extra [position_element_found], status);
                  EXIT /parse_file_reference/;
                IFEND;
                command_or_program_name.value := element_name;
                command_or_program_name.size := element_size;
                command_or_program_name_found := TRUE;
                IF clc$evaluating_command_ref IN file_reference_parsing_options THEN
                  form := clc$module_or_file_command_ref;
                IFEND;
              IFEND;
            IFEND;
*IFEND

            path_handle.kind := clc$not_a_path_handle;
            previous_element_is_generic := FALSE;

          = clc$local_catalog_path_element =

            IF evaluated_file_reference.number_of_path_elements <> 0 THEN
              osp$set_status_abnormal ('CL', cle$special_element_not_first, element_name, status);
              EXIT /parse_file_reference/;
            IFEND;

*IF NOT $true(osv$unix)
            IF clc$prevent_job_context_element IN file_reference_parsing_options THEN
              osp$set_status_abnormal ('CL', cle$no_job_context_elements, element_name (1, element_size),
                    status);
              EXIT /parse_file_reference/;
            IFEND;
*IFEND

            element_name := '$LOCAL';
            element_size := 6;
            path_handle.kind := clc$not_a_path_handle;
            previous_element_is_generic := FALSE;

          = clc$not_a_special_path_element =

*IF NOT $true(osv$unix)
            IF cycle_element_found OR position_element_found THEN
              IF (($clt$file_ref_parsing_options [clc$evaluating_command_ref,
                    clc$evaluating_entry_point_ref] * file_reference_parsing_options) =
                    $clt$file_ref_parsing_options []) OR command_or_program_name_found THEN
                osp$set_status_condition (no_extra [position_element_found], status);
                EXIT /parse_file_reference/;
              IFEND;

              command_or_program_name.value := element_name;
              command_or_program_name.size := element_size;
              command_or_program_name_found := TRUE;
              IF clc$evaluating_command_ref IN file_reference_parsing_options THEN
                form := clc$module_or_file_command_ref;
              IFEND;
            IFEND;

            IF NOT evaluated_file_reference.multiple_reference_specified AND
                  (clc$multiple_reference_allowed IN file_reference_parsing_options) AND
                  (scl_options^.wild_card_pattern_type = clc$wc_extended_pattern) THEN
              #SCAN (wild_card_chars, element_name, ignore_scan_index, scan_found_char);
              IF scan_found_char THEN
                IF evaluated_file_reference.number_of_path_elements = 0 THEN
                  osp$set_status_condition (cle$wild_card_cant_be_first, status);
                  EXIT /parse_file_reference/;
                IFEND;
                evaluated_file_reference.multiple_reference_specified := TRUE;
              IFEND;
*ELSE
            IF path_syntax = unix_path_syntax THEN

{ No folding letters to upper case for a UNIX style path.

              element_name := element_text^;
            IFEND;

            IF contains_wild_card_char (element_name) THEN
              IF evaluated_file_reference.number_of_path_elements = 0 THEN
                osp$set_status_condition (cle$wild_card_cant_be_first, status);
                EXIT /parse_file_reference/;
              IFEND;
*IFEND
            IFEND;

            path_handle.kind := clc$not_a_path_handle;
*IF NOT $true(osv$unix)
            previous_element_is_generic := FALSE;
*IFEND
            standard_file := clc$sf_not_a_standard_file;

*IF NOT $true(osv$unix)
          = clc$position_path_element =

            IF evaluated_file_reference.number_of_path_elements = 0 THEN
              osp$set_status_condition (cle$position_must_be_last, status);
              EXIT /parse_file_reference/;
            IFEND;

            IF (($clt$file_ref_parsing_options [clc$evaluating_command_ref,
                  clc$evaluating_entry_point_ref] * file_reference_parsing_options) <>
                  $clt$file_ref_parsing_options []) THEN
              osp$set_status_condition (cle$no_pos_on_cmnd_entry_pt_ref, status);
              EXIT /parse_file_reference/;
            IFEND;

            position_element_found := TRUE;
            evaluated_file_reference.path_handle_info.path_handle.open_position.specified := TRUE;
            evaluated_file_reference.path_handle_info.path_handle.open_position.value := element.position;

          = clc$reversal_path_element =

            IF evaluated_file_reference.multiple_reference_specified THEN
              osp$set_status_condition (cle$up_cant_follow_wild_card, status);
              EXIT /parse_file_reference/;
            IFEND;

            IF evaluated_file_reference.number_of_path_elements = 0 THEN
              IF NOT (clc$file_ref_evaluation_stage IN file_reference_parsing_options) THEN
                IF clc$prevent_job_context_element IN file_reference_parsing_options THEN
                  IF (user_identification.family.size = 0) OR (user_identification.user.size = 0) THEN
                    osp$set_status_condition (cle$undefined_user_ident, status);
                    EXIT /parse_file_reference/;
                  IFEND;
                  append_element (user_identification.family.size, user_identification.family.value);
                  append_element (user_identification.user.size, user_identification.user.value);
                ELSE
                  clp$find_working_catalog (working_catalog);
                  evaluated_file_reference.path_structure := working_catalog^^.evaluated_file_reference.
                        path_structure;
                  evaluated_file_reference.path_structure_size :=
                        working_catalog^^.evaluated_file_reference.path_structure_size;
                  evaluated_file_reference.number_of_path_elements :=
                        working_catalog^^.evaluated_file_reference.number_of_path_elements;
                IFEND;
                clp$remove_last_path_element (evaluated_file_reference, status);
                IF NOT status.normal THEN
                  EXIT /parse_file_reference/;
                IFEND;
                append := FALSE;
              ELSE
                append_element (16, '$WORKING_CATALOG');
                previous_element_is_generic := TRUE;
              IFEND;
            ELSEIF (NOT (clc$file_ref_evaluation_stage IN file_reference_parsing_options)) OR
                  (NOT previous_element_is_generic) THEN
              clp$remove_last_path_element (evaluated_file_reference, status);
              IF NOT status.normal THEN
                EXIT /parse_file_reference/;
              IFEND;
              evaluated_file_reference.path_handle_info.path_handle_present := FALSE;
              evaluated_file_reference.path_handle_info.path_handle.open_position.specified := FALSE;
              evaluated_file_reference.cycle_reference.specification := fsc$cycle_omitted;
              cycle_element_found := FALSE;
              append := FALSE;
            IFEND;

          = clc$source_path_element =

            IF evaluated_file_reference.number_of_path_elements <> 0 THEN
              osp$set_status_abnormal ('CL', cle$special_element_not_first, element_name, status);
              EXIT /parse_file_reference/;
            IFEND;

            IF clc$prevent_job_context_element IN file_reference_parsing_options THEN
              osp$set_status_abnormal ('CL', cle$no_job_context_elements, element_name (1, element_size),
                    status);
              EXIT /parse_file_reference/;
            IFEND;

            IF NOT (clc$file_ref_evaluation_stage IN file_reference_parsing_options) THEN
              find_command_source;
              IF NOT status.normal THEN
                EXIT /parse_file_reference/;
              IFEND;
              append := FALSE;
            IFEND;
            previous_element_is_generic := clc$file_ref_evaluation_stage IN file_reference_parsing_options;

          = clc$system_path_element =

            IF cycle_element_found OR position_element_found THEN
              osp$set_status_condition (no_extra [position_element_found], status);
              EXIT /parse_file_reference/;
            IFEND;

            path_handle.kind := clc$not_a_path_handle;
            previous_element_is_generic := FALSE;
*IFEND

          = clc$unsupported_path_element =

            osp$set_status_abnormal ('CL', cle$special_element_not_first, element_name, status);
            EXIT /parse_file_reference/;

*IF NOT $true(osv$unix)
          = clc$traversal_path_element =

            IF clc$multiple_reference_allowed IN file_reference_parsing_options THEN
              evaluated_file_reference.multiple_reference_specified := TRUE;
            ELSE
              osp$set_status_condition (cle$wild_card_not_allowed, status);
              EXIT /parse_file_reference/;
            IFEND;

          = clc$workin_catalog_path_element =

            IF evaluated_file_reference.number_of_path_elements <> 0 THEN
              osp$set_status_abnormal ('CL', cle$special_element_not_first, element_name, status);
              EXIT /parse_file_reference/;
            IFEND;

            IF clc$prevent_job_context_element IN file_reference_parsing_options THEN
              osp$set_status_abnormal ('CL', cle$no_job_context_elements, element_name (1, element_size),
                    status);
              EXIT /parse_file_reference/;
            IFEND;

            IF NOT (clc$file_ref_evaluation_stage IN file_reference_parsing_options) THEN
              clp$find_working_catalog (working_catalog);
              evaluated_file_reference.path_structure := working_catalog^^.evaluated_file_reference.
                    path_structure;
              evaluated_file_reference.path_structure_size := working_catalog^^.evaluated_file_reference.
                    path_structure_size;
              evaluated_file_reference.number_of_path_elements :=
                    working_catalog^^.evaluated_file_reference.number_of_path_elements;
              append := FALSE;
            ELSE
              element_name := '$WORKING_CATALOG';
              element_size := 16;
            IFEND;
            path_handle.kind := clc$not_a_path_handle;
            previous_element_is_generic := TRUE;
*IFEND

          CASEND;

*IF NOT $true(osv$unix)
          IF (NOT (path_handle.kind = clc$command_file_handle)) AND (NOT position_element_found) THEN
            path_handle.kind := clc$not_a_path_handle;
            IF (NOT command_or_program_name_found) AND (NOT cycle_element_found) THEN
              IF append THEN
                IF (evaluated_file_reference.number_of_path_elements >= fsc$max_path_elements) OR
                      ((evaluated_file_reference.path_structure_size + 1 + element_size) >
                      fsc$max_path_size) THEN
                  osp$set_status_condition (cle$file_reference_too_long, status);
                  EXIT /parse_file_reference/;
                IFEND;
*ELSE
          IF NOT (path_handle.kind = clc$command_file_handle) THEN
            path_handle.kind := clc$not_a_path_handle;
*IFEND
                append_element (element_size, element_name);
*IF NOT $true(osv$unix)
              IFEND;
            IFEND;
*IFEND
          IFEND;

*IF $true(osv$unix)
        = clc$lex_alpha_number =
          IF path_syntax = ve_path_syntax THEN
            osp$set_status_condition (cle$expecting_path_element, status);
            clp$append_status_parse_state (osc$status_parameter_delimiter, current_parse, status);
            EXIT /parse_file_reference/;
          IFEND;
          append_element (current_parse.unit.size, element_text^);

        = clc$lex_ellipsis =
          IF path_syntax = ve_path_syntax THEN
            osp$set_status_condition (cle$expecting_path_element, status);
            clp$append_status_parse_state (osc$status_parameter_delimiter, current_parse, status);
            EXIT /parse_file_reference/;
          IFEND;

          clp$remove_last_path_element (evaluated_file_reference, status);
          IF NOT status.normal THEN
            EXIT /parse_file_reference/;
          IFEND;
*IFEND

        = clc$lex_unsigned_decimal =
*IF NOT $true(osv$unix)

          IF current_parse.previous_non_space_unit.kind = clc$lex_concatenate THEN
            osp$set_status_condition (cle$var_or_fcn_follows_concat, status);
            clp$append_status_parse_state (osc$status_parameter_delimiter, current_parse, status);
            EXIT /parse_file_reference/;
          IFEND;

          IF command_or_program_name_found OR (evaluated_file_reference.number_of_path_elements <= 1) THEN
            osp$set_status_condition (cle$cycle_must_follow_file_name, status);
            EXIT /parse_file_reference/;
          IFEND;

          clp$evaluate_unsigned_decimal (current_parse.text^
                (current_parse.unit_index, current_parse.unit.size), number, status);
          IF NOT status.normal THEN
            EXIT /parse_file_reference/;
          IFEND;
          IF (number < pfc$minimum_cycle_number) OR (number > pfc$maximum_cycle_number) THEN
            osp$set_status_condition (pfe$bad_cycle_number, status);
            osp$append_status_integer (osc$status_parameter_delimiter, number, 10, FALSE, status);
            EXIT /parse_file_reference/;
          IFEND;
          IF path_handle.kind = clc$command_file_handle THEN
            osp$set_status_condition (cle$inappropriate_cmnd_file_ref, status);
            EXIT /parse_file_reference/;
          IFEND;

          element.kind := clc$cycle_path_element;
          evaluated_file_reference.cycle_reference.specification := fsc$cycle_number;
          evaluated_file_reference.cycle_reference.cycle_number := number;
          cycle_element_found := TRUE;
          path_handle.kind := clc$not_a_path_handle;

        = clc$lex_string =

          IF current_parse.previous_non_space_unit.kind = clc$lex_concatenate THEN
            osp$set_status_condition (cle$var_or_fcn_follows_concat, status);
            clp$append_status_parse_state (osc$status_parameter_delimiter, current_parse, status);
            EXIT /parse_file_reference/;
          IFEND;

          IF cycle_element_found AND command_or_program_name_found THEN
            osp$set_status_condition (cle$cycle_must_follow_file_name, status);
            EXIT /parse_file_reference/;
          IFEND;

          IF (clc$evaluating_entry_point_ref IN file_reference_parsing_options) AND NOT string_found THEN
            process_program_name;
*ELSE
          IF path_syntax = unix_path_syntax THEN
            append_element (current_parse.unit.size, element_text^);
          ELSE
            IF evaluated_file_reference.number_of_path_elements <= 1 THEN
              osp$set_status_condition (cle$cycle_must_follow_file_name, status);
              EXIT /parse_file_reference/;
            IFEND;
            clp$evaluate_unsigned_decimal (element_text^, number, status);
*IFEND
            IF NOT status.normal THEN
              EXIT /parse_file_reference/;
            IFEND;
*IF NOT $true(osv$unix)
          ELSE
            osp$set_status_condition (cle$expecting_path_element, status);
            clp$append_status_parse_state (osc$status_parameter_delimiter, current_parse, status);
            EXIT /parse_file_reference/;
          IFEND;
*ELSE
            element.kind := clc$cycle_path_element;
            path_handle.kind := clc$not_a_path_handle;
          IFEND;


        = clc$lex_unterminated_string =
          osp$set_status_abnormal ('CL', cle$missing_string_delimiter, element_text^, status);
          EXIT /parse_file_reference/;
*IFEND

        = clc$lex_wild_card_name =
*IF NOT $true(osv$unix)

          IF clc$multiple_reference_allowed IN file_reference_parsing_options THEN
            IF current_parse.previous_non_space_unit.kind = clc$lex_concatenate THEN
              osp$set_status_condition (cle$var_or_fcn_follows_concat, status);
              clp$append_status_parse_state (osc$status_parameter_delimiter, current_parse, status);
              EXIT /parse_file_reference/;
            IFEND;

            append_wild_card (current_parse.text^ (current_parse.unit_index, current_parse.unit.size));
          ELSE
*IFEND
            osp$set_status_condition (cle$wild_card_not_allowed, status);
            EXIT /parse_file_reference/;
*IF NOT $true(osv$unix)
          IFEND;
*IFEND

        = clc$lex_long_name =
*IF NOT $true(osv$unix)
          #SCAN (wild_card_chars, current_parse.text^ (current_parse.unit_index, current_parse.unit.size),
                ignore_scan_index, scan_found_char);
          IF (clc$multiple_reference_allowed IN file_reference_parsing_options) AND
                (scl_options^.wild_card_pattern_type = clc$wc_extended_pattern) AND scan_found_char THEN
            append_wild_card (current_parse.text^ (current_parse.unit_index, current_parse.unit.size));
          ELSE
            osp$set_status_abnormal ('CL', cle$name_too_long, current_parse.
                  text^ (current_parse.unit_index, current_parse.unit.size), status);
            EXIT /parse_file_reference/;
          IFEND;

        ELSE

*ELSE
          IF path_syntax <> unix_path_syntax THEN
            osp$set_status_abnormal ('CL', cle$name_too_long, element_text^, status);
            EXIT /parse_file_reference/;
          IFEND;
          append_wild_card (element_text^);

        ELSE
{ Check if a '/' was specified - root directory }
          IF (current_parse.previous_non_space_unit.kind = clc$lex_divide) AND
                (evaluated_file_reference.number_of_path_elements = 0) THEN
            append_wild_card ('/');
            EXIT /parse_path/;
          IFEND;
*IFEND
          osp$set_status_condition (cle$expecting_path_element, status);
          clp$append_status_parse_state (osc$status_parameter_delimiter, current_parse, status);
          EXIT /parse_file_reference/;
        CASEND;

        update_current_parse;

      WHILEND /parse_path/;

      complete_evaluation;

    END /parse_file_reference/;

    work_area := saved_work_area;

  PROCEND clp$complete_file_ref_parse;
*IF $true(osv$unix)
?? TITLE := 'clp$convert_file_ref_to_string', EJECT ??
*copyc clh$convert_file_ref_to_string

  PROCEDURE [XDCL, #GATE] clp$convert_file_ref_to_string
    (    evaluated_file_reference: fst$evaluated_file_reference;
         include_open_position: boolean;
     VAR str: fst$path;
     VAR size: fst$path_size;
     VAR status: ost$status);

    TYPE
      chars = set of char;

    VAR
      cycle_string: ^ost$string,
      element: clt$special_path_element,
      element_index: fst$path_element_index,
      element_name: fst$path_element_name,
      element_size: fst$path_element_size,
      i: fst$path_index,
      ignore_scan_index: integer,
      j: fst$path_index,
      non_standard_1st_element_chars: chars,
      non_standard_element_chars: chars,
      open_pos_size: 4 .. 5,
      previous_element_is_generic: boolean,
      quote_element: boolean;


    status.normal := TRUE;

    non_standard_1st_element_chars := -$chars ['#', '$', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
          'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\', ']',
          '^', '_', '`', '{', '|', '}', '~'];
    non_standard_element_chars := -$chars ['#', '$', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '@',
          'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
          'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\', ']', '^', '_', '`', '{', '|', '}', '~'];

    str := '';
    i := 1;
    j := 1;
    size := evaluated_file_reference.path_structure_size;
    element_index := 1;
    previous_element_is_generic := FALSE;
    REPEAT
      element_size := $INTEGER (evaluated_file_reference.path_structure (i));
      i := i + 1;
      str (j) := '.';
      j := j + 1;
      quote_element := evaluated_file_reference.path_structure (i) IN non_standard_1st_element_chars;
      IF quote_element THEN
        previous_element_is_generic := FALSE;
      ELSE
        #SCAN (non_standard_element_chars, evaluated_file_reference.path_structure (i, element_size),
              ignore_scan_index, quote_element);
        IF quote_element OR (evaluated_file_reference.path_structure (i) <> '$') THEN
          previous_element_is_generic := FALSE;
        ELSE
          element_name := evaluated_file_reference.path_structure (i, element_size);
          check_for_special_path_element (element_name, element_size, element);
          CASE element.kind OF
          = clc$current_family_path_element, clc$defer_eval_path_element, clc$source_path_element,
                clc$workin_catalog_path_element, clc$unsupported_path_element =
            previous_element_is_generic := element_index = 1;
            quote_element := NOT previous_element_is_generic;
          = clc$current_user_path_element =
            previous_element_is_generic := element_index <= 2;
            quote_element := NOT previous_element_is_generic;
          = clc$local_catalog_path_element, clc$command_file_path_element =
            previous_element_is_generic := FALSE;
            quote_element := element_index > 1;
          = clc$cycle_path_element, clc$position_path_element, clc$var_or_fcn_cyc_path_element,
                  clc$no_cycle_path_element, clc$no_position_path_element =
            previous_element_is_generic := FALSE;
            quote_element := TRUE;
          = clc$reversal_path_element =
            quote_element := NOT previous_element_is_generic;
          { previous_element_is_generic := previous_element_is_generic;
          = clc$traversal_path_element =
            previous_element_is_generic := FALSE;
          ELSE
          { clc$not_a_special_path_element
          { clc$system_path_element
          { clc$job_file_path_element
          { clc$standard_file_path_element
            previous_element_is_generic := FALSE;
          CASEND;
        IFEND;
      IFEND;
      IF NOT quote_element THEN
        str (j, element_size) := evaluated_file_reference.path_structure (i, element_size);
        j := j + element_size;
        i := i + element_size;
      ELSE
        IF (size + 2) > fsc$max_path_size THEN
          osp$set_status_condition (cle$file_reference_too_long, status);
          RETURN;
        IFEND;
        size := size + 2;
        str (j) := '''';
        j := j + 1;
        REPEAT
          IF evaluated_file_reference.path_structure (i) = '''' THEN
            IF (size + 1) > fsc$max_path_size THEN
              osp$set_status_condition (cle$file_reference_too_long, status);
              RETURN;
            IFEND;
            size := size + 1;
            str (j) := '''';
            j := j + 1;
          IFEND;
          str (j) := evaluated_file_reference.path_structure (i);
          i := i + 1;
          j := j + 1;
          element_size := element_size - 1;
        UNTIL element_size <= 0;
        str (j) := '''';
        j := j + 1;
      IFEND;
      element_index := element_index + 1;
    UNTIL i > evaluated_file_reference.path_structure_size;
    str (1) := ':';

  PROCEND clp$convert_file_ref_to_string;
?? TITLE := 'clp$conv_unix_file_ref_to_str', EJECT ??
*copyc clh$conv_unix_file_ref_to_str

  PROCEDURE [XDCL, #GATE] clp$conv_unix_file_ref_to_str
    (    evaluated_file_reference: fst$evaluated_file_reference;
     VAR str: fst$path;
     VAR size: fst$path_size;
     VAR status: ost$status);

    TYPE
      chars = set of char;

    VAR
      element_size: fst$path_element_size,
      i: fst$path_index,
      ignore_scan_index: integer,
      j: fst$path_index,
      non_standard_1st_element_chars: chars,
      non_standard_element_chars: chars,
      open_pos_size: 4 .. 5,
      quote_element: boolean;


    status.normal := TRUE;

    non_standard_1st_element_chars := -$chars ['#', '$', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
          'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\', ']',
          '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
          'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~'];
    non_standard_element_chars := -$chars ['#', '$', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '@',
          'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
          'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
          'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|',
          '}', '~'];

    str := '';
    i := 1;
    j := 1;
    size := evaluated_file_reference.path_structure_size;
    REPEAT
      element_size := $INTEGER (evaluated_file_reference.path_structure (i));
      i := i + 1;
      str (j) := '/';
      j := j + 1;
      quote_element := evaluated_file_reference.path_structure (i) IN non_standard_1st_element_chars;
      IF quote_element AND (evaluated_file_reference.path_structure (i, element_size) = '/') THEN
        IF size > 1 THEN
          element_size := $INTEGER (evaluated_file_reference.path_structure (i+1));
          i := i + 2;
        ELSE
{ The path consists solely of a '/' - root directory.
          RETURN;
        IFEND;
      IFEND;
      IF NOT quote_element THEN
        #SCAN (non_standard_element_chars, evaluated_file_reference.path_structure (i, element_size),
              ignore_scan_index, quote_element);
      IFEND;
      IF NOT quote_element THEN
        str (j, element_size) := evaluated_file_reference.path_structure (i, element_size);
        j := j + element_size;
        i := i + element_size;
      ELSE
        IF (size + 2) > fsc$max_path_size THEN
          osp$set_status_condition (cle$file_reference_too_long, status);
          RETURN;
        IFEND;
        REPEAT
          IF evaluated_file_reference.path_structure (i) = '''' THEN
            IF (size + 1) > fsc$max_path_size THEN
              osp$set_status_condition (cle$file_reference_too_long, status);
              RETURN;
            IFEND;
            size := size + 1;
            str (j) := '''';
            j := j + 1;
          IFEND;
          str (j) := evaluated_file_reference.path_structure (i);
          i := i + 1;
          j := j + 1;
          element_size := element_size - 1;
        UNTIL element_size <= 0;
      IFEND;
    UNTIL i > evaluated_file_reference.path_structure_size;

  PROCEND clp$conv_unix_file_ref_to_str;
*ELSE
?? TITLE := 'clp$convert_cyc_ref_to_cyc_sel', EJECT ??
*copyc clh$convert_cyc_ref_to_cyc_sel

*copyc clp$convert_cyc_ref_to_cyc_sel
*IFEND

?? TITLE := 'clp$convert_str_to_path_handle', EJECT ??

  PROCEDURE [XDCL, #GATE] clp$convert_str_to_path_handle
    (    str: string ( * );
         delete_allowed: boolean;
         resolve_path: boolean;
         include_open_pos_in_handle: boolean;
*IF NOT $true(osv$unix)
     VAR path_handle_name: fst$path_handle_name;
*ELSE
     VAR path_handle_name: fst$path;
*IFEND
     VAR evaluated_file_reference: fst$evaluated_file_reference;
     VAR status: ost$status);

    VAR
*IF NOT $true(osv$unix)
      path_handle: fmt$path_handle,
      pt_results: bat$process_pt_results,
      work_list: bat$process_pt_work_list;
*ELSE
      path_handle_size: fst$path_size,
      path_handle: fmt$path_handle;
*IFEND


    status.normal := TRUE;

    clp$setup_and_parse_file_ref (str, $clt$file_ref_parsing_options [clc$command_file_ref_allowed],
          clv$user_identification, evaluated_file_reference, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

*IF NOT $true(osv$unix)
    IF evaluated_file_reference.path_resolution = fsc$command_file_path THEN
      clp$construct_block_handle_name (evaluated_file_reference.block_handle, path_handle_name);
*ELSE
    IF evaluated_file_reference.command_file_path.found THEN
      clp$construct_block_handle_name (evaluated_file_reference.command_file_path.block_handle,
            path_handle_name);
*IFEND
      RETURN;
    IFEND;

*IF NOT $true(osv$unix)
    work_list := $bat$process_pt_work_list [bac$record_path];
    IF NOT delete_allowed THEN
      work_list := work_list + $bat$process_pt_work_list [bac$externalize_path_handle];
    IFEND;
    IF NOT evaluated_file_reference.path_handle_info.path_handle_present THEN
      IF (resolve_path OR ((evaluated_file_reference.cycle_reference.specification <> fsc$cycle_omitted) AND
            (evaluated_file_reference.cycle_reference.specification <> fsc$cycle_number))) THEN
        work_list := work_list + $bat$process_pt_work_list [bac$resolve_path, bac$resolve_to_catalog];
      IFEND;
      bap$process_pt_request (work_list, osc$null_name, evaluated_file_reference, pt_results, status);
      IF (NOT status.normal) AND osp$file_access_condition (status) THEN
        process_pt_request (work_list, osc$null_name, evaluated_file_reference, pt_results, status);
      IFEND;
    ELSEIF resolve_path AND (evaluated_file_reference.cycle_reference.specification <> fsc$cycle_number) THEN
      work_list := work_list + $bat$process_pt_work_list [bac$resolve_path, bac$resolve_to_catalog];
      bap$process_pt_request (work_list, osc$null_name, evaluated_file_reference, pt_results, status);
      IF (NOT status.normal) AND osp$file_access_condition (status) THEN
        process_pt_request (work_list, osc$null_name, evaluated_file_reference, pt_results, status);
      IFEND;
    IFEND;

    path_handle := evaluated_file_reference.path_handle_info.path_handle;
    IF NOT include_open_pos_in_handle THEN
      path_handle.open_position.specified := FALSE;
    IFEND;

    clp$construct_path_handle_name (path_handle, path_handle_name);

    process_status (evaluated_file_reference.path_handle_info, fsc$unresolved_path,
          'clp$convert_str_to_path_handle', status);
*ELSE
    IF evaluated_file_reference.standard_file THEN
      path_handle_name := evaluated_file_reference.unix_standard_file.unix_file_name;
    ELSE
      clp$conv_unix_file_ref_to_str (evaluated_file_reference, path_handle_name,
            path_handle_size, status);
    IFEND;
*IFEND

  PROCEND clp$convert_str_to_path_handle;
?? TITLE := 'clp$convert_string_to_file', EJECT ??
*copyc clh$convert_string_to_file

  PROCEDURE [XDCL, #GATE] clp$convert_string_to_file
    (    str: string ( * );
*IF NOT $true(osv$unix)
     VAR file: clt$file;
*ELSE
     VAR file: fst$path;
*IFEND
     VAR status: ost$status);

    VAR
      ignore_evaluated_file_reference: fst$evaluated_file_reference;

    status.normal := TRUE;

*IF NOT $true(osv$unix)
    clp$convert_str_to_path_handle (str, FALSE, FALSE, TRUE, file.local_file_name,
*ELSE
    clp$convert_str_to_path_handle (str, FALSE, FALSE, TRUE, file,
*IFEND
          ignore_evaluated_file_reference, status);

  PROCEND clp$convert_string_to_file;
*IF NOT $true(osv$unix)
?? TITLE := 'clp$convert_string_to_file_path', EJECT ??
*copyc clh$convert_string_to_file_path

  PROCEDURE [XDCL, #GATE] clp$convert_string_to_file_path
    (    str: string ( * );
         use_$local_as_working_catalog: boolean;
         return_path_handle_name: boolean;
     VAR path_handle_name: fst$path_handle_name;
     VAR resolved_path: fst$resolved_file_reference;
     VAR status: ost$status);

    VAR
      context: ^ost$ecp_exception_context,
      evaluated_file_reference: fst$evaluated_file_reference,
      file_reference_parsing_options: clt$file_ref_parsing_options,
      ignore_pt_results: bat$process_pt_results;


    status.normal := TRUE;

    file_reference_parsing_options := $clt$file_ref_parsing_options [clc$command_file_ref_allowed];
    IF use_$local_as_working_catalog THEN
      file_reference_parsing_options := file_reference_parsing_options +
            $clt$file_ref_parsing_options [clc$use_$local_as_working_cat];
    IFEND;

    clp$evaluate_file_reference (str, file_reference_parsing_options, FALSE, evaluated_file_reference,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    bap$get_resolved_file_reference (evaluated_file_reference, resolved_path, status);
    IF NOT status.normal THEN
      IF osp$file_access_condition (status) THEN
        PUSH context;
        context^ := osv$initial_exception_context;
        context^.file.selector := osc$ecp_evaluated_file_ref;
        context^.file.evaluated_file_reference := evaluated_file_reference;
        REPEAT
          context^.condition_status := status;
          osp$enforce_exception_policies (context^);
          status := context^.condition_status;
          bap$get_resolved_file_reference (evaluated_file_reference, resolved_path, status);
        UNTIL status.normal OR (NOT osp$file_access_condition (status)) OR (NOT context^.wait);
      IFEND;
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF return_path_handle_name THEN
      bap$process_pt_request ($bat$process_pt_work_list [bac$record_path, bac$externalize_path_handle],
            osc$null_name, evaluated_file_reference, ignore_pt_results, status);
      IF (NOT status.normal) AND osp$file_access_condition (status) THEN
        process_pt_request ($bat$process_pt_work_list [bac$record_path, bac$externalize_path_handle],
              osc$null_name, evaluated_file_reference, ignore_pt_results, status);
      IFEND;
      process_status (evaluated_file_reference.path_handle_info, fsc$unresolved_path,
            'clp$convert_string_to_file_path', status);
      IF status.normal THEN
        clp$construct_path_handle_name (evaluated_file_reference.path_handle_info.path_handle,
              path_handle_name);
      IFEND;
    ELSE
      path_handle_name := osc$null_name;
    IFEND;

  PROCEND clp$convert_string_to_file_path;
*IFEND
?? TITLE := 'clp$convert_string_to_file_ref', EJECT ??
*copyc clh$convert_string_to_file_ref

  PROCEDURE [XDCL, #GATE] clp$convert_string_to_file_ref
    (    str: string ( * );
     VAR parsed_file_reference: fst$parsed_file_reference;
     VAR status: ost$status);

    VAR
      evaluated_file_reference: fst$evaluated_file_reference;

    status.normal := TRUE;

    clp$setup_and_parse_file_ref (str, $clt$file_ref_parsing_options
          [clc$command_file_ref_allowed, clc$file_ref_evaluation_stage], clv$user_identification,
          evaluated_file_reference, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    convert_eval_to_parsed_file_ref (evaluated_file_reference, TRUE, parsed_file_reference, status);

  PROCEND clp$convert_string_to_file_ref;
?? TITLE := 'clp$file_ref_is_pre_evaluated', EJECT ??
*copyc clh$file_ref_is_pre_evaluated

*copyc clp$file_ref_is_pre_evaluated

*IF NOT $true(osv$unix)
?? TITLE := 'clp$get_file_cycles', EJECT ??

  PROCEDURE [XDCL] clp$get_file_cycles
    (    file: fst$file_reference;
     VAR work_area {input, output} : ^clt$work_area;
     VAR cycle_array: ^array [1 .. * ] of fst$cycle_number;
     VAR status: ost$status);

    VAR
      object_info: ^fst$goi_object_information,
      information_request: fst$goi_information_request,
      saved_work_area: ^clt$work_area,
      cycle_object_list: ^fst$goi_object_list,
      i: fst$cycle_number,
      number_of_cycles: integer,
      catalog_depth: fst$catalog_depth;


    status.normal := TRUE;
    cycle_array := NIL;
    catalog_depth.depth_specification := fsc$entire_subtree;
    information_request.catalog_depth := catalog_depth;
    information_request.object_information_requests := $fst$goi_object_info_requests
          [fsc$goi_cycle_object_list];

    saved_work_area := work_area;

    pfp$get_object_information (file, information_request, NIL, work_area, status);

    IF NOT status.normal THEN
      IF status.condition = pfe$unknown_item THEN
        status.normal := TRUE;
      IFEND;
      RETURN;
    IFEND;

    NEXT object_info IN saved_work_area;
    IF (object_info = NIL) THEN
      RETURN;
    ELSEIF (object_info^.object = NIL) OR (object_info^.object^.object_type = fsc$goi_catalog_object)  THEN
      osp$set_status_condition (pfe$name_not_permanent_file, status);
      osp$append_status_file (osc$status_parameter_delimiter, file, status);
      RETURN;
    IFEND;

    IF object_info^.object^.object_type = fsc$goi_file_object THEN
      cycle_object_list := object_info^.object^.cycle_object_list;
      IF cycle_object_list = NIL THEN
        RETURN;
      IFEND;
      number_of_cycles := UPPERBOUND (cycle_object_list^);
      NEXT cycle_array: [1 .. number_of_cycles] IN work_area;
      FOR i := 1 TO number_of_cycles DO
        cycle_array^ [i] := cycle_object_list^ [i].cycle_number;
      FOREND;
    IFEND;

  PROCEND clp$get_file_cycles;
?? TITLE := 'clp$get_path_description', EJECT ??
*copyc clh$get_path_description

  PROCEDURE [XDCL, #GATE] clp$get_path_description
    (    file: clt$file;
     VAR file_reference: clt$file_reference;
     VAR path_container: clt$path_container;
     VAR path: ^pft$path;
     VAR cycle_selector: clt$cycle_selector;
     VAR open_position: clt$open_position;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      evaluated_file_reference: fst$evaluated_file_reference,
      fs_file_reference: fst$path,
      fs_path: ^fst$path,
      ignore_path_size: fst$path_size,
      path_container_ptr: ^clt$path_container,
      local_file_name: clt$name;

    status.normal := TRUE;
    #CALLER_ID (caller_id);

    file_reference.path_name := ' ';
    #TRANSLATE (osv$lower_to_upper, file.local_file_name, local_file_name.value);
    local_file_name.size := clp$trimmed_string_size (local_file_name.value);
    clp$evaluate_file_reference (local_file_name.value, $clt$file_ref_parsing_options
          [clc$command_file_ref_allowed], TRUE, evaluated_file_reference, status);
    IF status.normal THEN
      PUSH fs_path;
      clp$convert_file_ref_to_string (evaluated_file_reference, FALSE, fs_path^, ignore_path_size, status);
      IF status.normal THEN
        open_position := evaluated_file_reference.path_handle_info.path_handle.open_position;
        path_container_ptr := ^path_container;
        RESET path_container_ptr;
        NEXT path: [1 .. evaluated_file_reference.number_of_path_elements] IN path_container_ptr;
        IF path = NIL THEN
          osp$set_status_condition (cle$file_reference_too_long, status);
        ELSE
          fsp$convert_fs_structure_to_pf (evaluated_file_reference, path);
          clp$convert_cyc_ref_to_cyc_sel (evaluated_file_reference.cycle_reference, cycle_selector);

          format_path_name (local_file_name, fs_path, evaluated_file_reference.path_structure_size,
                open_position, osc$full_message_level, fs_file_reference);
          file_reference.path_name := fs_file_reference;
          file_reference.path_name_size := clp$trimmed_string_size (file_reference.path_name);
          file_reference.validation_ring.known := TRUE;
          file_reference.validation_ring.number := caller_id.ring;
        IFEND;
      IFEND;
    IFEND;

  PROCEND clp$get_path_description;
*IFEND
?? TITLE := 'clp$get_path_name', EJECT ??
*copyc clh$get_path_name

  PROCEDURE [XDCL, #GATE] clp$get_path_name ALIAS 'clpgpn'
    (    local_file_name: fst$file_reference;
         format: ost$format_message_level;
     VAR file_reference: fst$path);

    VAR
      actual_format: ost$status_message_level,
      current_format: ^ost$status_message_level,
      evaluated_file_reference: fst$evaluated_file_reference,
      ignore_path_size: fst$path_size,
      open_position: clt$open_position,
      cl_path_handle: clt$path_handle,
      pf_path: ^pft$path,
      path: ^fst$path,
      path_name_size: 0 .. fsc$max_path_size,
      status: ost$status,
      file_reference_name: string (fsc$max_path_size),
      file_name: clt$name;


    open_position.specified := FALSE;
    file_reference := ' ';

*IF NOT $true(osv$unix)
    CASE format OF
    = osc$current_message_level =
      osp$find_status_message_level (current_format);
      actual_format := current_format^;
    ELSE
      actual_format := format;
    CASEND;
*ELSE
    actual_format := osc$full_message_level;
*IFEND


*IF NOT $true(osv$unix)
    #TRANSLATE (osv$lower_to_upper, local_file_name, file_reference_name);
*ELSE
    file_reference_name := local_file_name;
*IFEND

  /get_path/
    BEGIN
      clp$evaluate_file_reference (file_reference_name, $clt$file_ref_parsing_options
            [clc$command_file_ref_allowed], TRUE, evaluated_file_reference, status);
      IF status.normal THEN
        IF evaluated_file_reference.number_of_path_elements = 0 THEN
          file_reference := file_reference_name;
          RETURN;
        IFEND;

        PUSH path;
        PUSH pf_path: [1 .. evaluated_file_reference.number_of_path_elements];
        fsp$convert_fs_structure_to_pf (evaluated_file_reference, pf_path);
        clp$check_name_for_path_handle (pf_path^ [UPPERBOUND (pf_path^)], cl_path_handle);
        IF cl_path_handle.kind = clc$command_file_handle THEN
          path^ := '$COMMAND';
          path_name_size := 8;
          open_position.specified := FALSE;
          file_name.size := 1;
          file_name.value := ' ';
          EXIT /get_path/;
        ELSE
*IF NOT $true(osv$unix)
          clp$convert_file_ref_to_string (evaluated_file_reference, FALSE, path^, ignore_path_size, status);
*ELSE
          IF evaluated_file_reference.standard_file THEN
            file_reference := evaluated_file_reference.unix_standard_file.unix_file_name;
            RETURN;
          ELSE
            clp$conv_unix_file_ref_to_str (evaluated_file_reference, path^, ignore_path_size, status);
          IFEND;
*IFEND
          IF status.normal THEN
*IF NOT $true(osv$unix)
            open_position := evaluated_file_reference.path_handle_info.path_handle.open_position;
*IFEND
            path_name_size := evaluated_file_reference.path_structure_size;
            file_name.size := 1;
            file_name.value := ' ';
            EXIT /get_path/;
          IFEND;
        IFEND;
      IFEND;
      path_name_size := 0;
      file_name.size := 1;
      file_name.value := '?';
      path := NIL;
    END /get_path/;

    format_path_name (file_name, path, path_name_size, open_position, actual_format, file_reference);

  PROCEND clp$get_path_name;
*IF NOT $true(osv$unix)
?? TITLE := 'clp$get_source', EJECT ??
*copyc clh$get_source

  PROCEDURE [XDCL, #GATE] clp$get_source
    (VAR source: clt$source;
     VAR status: ost$status);

    VAR
      block: ^clt$block,
      ignore_path_size: fst$path_size,
      path_handle: clt$path_handle;


    status.normal := TRUE;

    clp$find_current_block (block);
    WHILE (block <> NIL) AND (NOT (block^.kind IN $clt$block_kinds
          [clc$command_block, clc$command_proc_block, clc$function_block, clc$function_proc_block])) DO
      block := block^.previous_block;
    WHILEND;
    IF block = NIL THEN
      osp$set_status_condition (cle$unable_to_find_cmnd_source, status);
      RETURN;
    IFEND;

    CASE block^.source.kind OF
    = clc$system_commands =
      source.kind := clc$system_source;
    = clc$sub_commands =
      source.kind := clc$utility_source;
      source.utility_name := block^.source.utility_name;
    = clc$catalog_commands, clc$library_commands =
      IF block^.source.kind = clc$catalog_commands THEN
        source.kind := clc$catalog_source;
      ELSE
        source.kind := clc$library_source;
      IFEND;

      clp$check_name_for_path_handle (block^.source.local_file_name, path_handle);
      bap$get_path_string (path_handle.regular_handle, source.path_name, ignore_path_size, status);
    CASEND;

  PROCEND clp$get_source;
?? TITLE := 'clp$get_working_catalog', EJECT ??
*copyc clh$get_working_catalog

  PROCEDURE [XDCL, #GATE] clp$get_working_catalog
    (VAR catalog_reference: clt$file_reference;
     VAR path_container: clt$path_container;
     VAR path: ^pft$path;
     VAR status: ost$status);

    VAR
      fs_path: fst$path,
      fs_path_size: fst$path_size,
      path_container_ptr: ^clt$path_container,
      working_catalog: ^^clt$working_catalog;

    status.normal := TRUE;

    clp$find_working_catalog (working_catalog);

    clp$convert_file_ref_to_string (working_catalog^^.evaluated_file_reference, FALSE, fs_path, fs_path_size,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    catalog_reference.path_name := fs_path;
    catalog_reference.path_name_size := clp$trimmed_string_size (catalog_reference.path_name);
    catalog_reference.validation_ring.known := FALSE;

    path_container_ptr := ^path_container;
    RESET path_container_ptr;
    NEXT path: [1 .. working_catalog^^.evaluated_file_reference.number_of_path_elements] IN
          path_container_ptr;
    fsp$convert_fs_structure_to_pf (working_catalog^^.evaluated_file_reference, path);

  PROCEND clp$get_working_catalog;
?? TITLE := 'clp$parse_job_independent_path', EJECT ??
*copyc clh$parse_job_independent_path

  PROCEDURE [XDCL, #GATE] clp$parse_job_independent_path
    (    path: fst$file_reference;
         user_identification: ost$user_identification;
         include_open_position: boolean;
     VAR parsed_path: fst$parsed_file_reference;
     VAR status: ost$status);

    VAR
      clt_user_identification: clt$user_identification,
      evaluated_file_reference: fst$evaluated_file_reference;

    status.normal := TRUE;

    clt_user_identification.user.value := user_identification.user;
    clt_user_identification.user.size := clp$trimmed_string_size (user_identification.user);
    clt_user_identification.family.value := user_identification.family;
    clt_user_identification.family.size := clp$trimmed_string_size (user_identification.family);

    clp$setup_and_parse_file_ref (path, $clt$file_ref_parsing_options [clc$prevent_job_context_element],
          clt_user_identification, evaluated_file_reference, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    convert_eval_to_parsed_file_ref (evaluated_file_reference, include_open_position, parsed_path, status);

  PROCEND clp$parse_job_independent_path;
?? TITLE := 'clp$set_working_catalog', EJECT ??
*copyc clh$set_working_catalog

  PROCEDURE [XDCL, #GATE] clp$set_working_catalog
    (    catalog: fst$file_reference;
     VAR status: ost$status);

    VAR
      file: clt$file,
      local_status: ost$status,
      evaluated_file_reference: fst$evaluated_file_reference,
      pf_path_elements: ^pft$path;

    status.normal := TRUE;
    local_status.normal := TRUE;

  /set_working_catalog/
    BEGIN
      clp$convert_string_to_file (catalog, file, local_status);
      IF NOT local_status.normal THEN
        EXIT /set_working_catalog/;
      IFEND;
      clp$get_fs_path_elements (file.local_file_name, evaluated_file_reference, local_status);
      IF NOT local_status.normal THEN
        EXIT /set_working_catalog/;
      IFEND;

      IF fsp$path_element (^evaluated_file_reference, 1) ^ = fsc$local THEN
        IF evaluated_file_reference.number_of_path_elements > 1 THEN
          osp$set_status_condition (fse$local_subcatalog_illegal, local_status);
          EXIT /set_working_catalog/;
        IFEND;
      ELSE
        PUSH pf_path_elements: [1 .. evaluated_file_reference.number_of_path_elements];
        fsp$convert_fs_structure_to_pf (evaluated_file_reference, pf_path_elements);
        clp$check_valid_catalog (pf_path_elements^, local_status);
        IF NOT local_status.normal THEN
          EXIT /set_working_catalog/;
        IFEND;
      IFEND;

      evaluated_file_reference.path_resolution := fsc$catalog_path;

      IF evaluated_file_reference.cycle_reference.specification <> fsc$cycle_omitted THEN
        osp$set_status_abnormal ('CL', fse$catalogs_do_not_have_cycles, file.local_file_name, local_status);
        EXIT /set_working_catalog/;
      IFEND;

      IF evaluated_file_reference.path_handle_info.path_handle.open_position.specified THEN
        osp$set_status_condition (cle$file_position_not_allowed, local_status);
        EXIT /set_working_catalog/;
      IFEND;

      clp$set_working_catalog_path (file.local_file_name, evaluated_file_reference);

    END /set_working_catalog/;
    IF NOT local_status.normal THEN
      status := local_status;
    IFEND;

  PROCEND clp$set_working_catalog;
*ELSE

  PROCEDURE [INLINE] clp$getcwd (working_storage_area: ^cell;
    VAR directory_length: ost_c_integer;
    VAR syserrlist_message: string(256);
    VAR stat: ost_c_integer);

    clp_getcwd (working_storage_area, directory_length,
          syserrlist_message, stat);

  PROCEND clp$getcwd;

  PROCEDURE  clp$find_working_catalog
    (VAR working_catalog: clt$working_catalog;
     VAR status: ost$status);

    VAR
      directory_length: ost_c_integer,
      ignore_command_name: clt$name,
      ignore_form: clt$command_reference_form,
      ignore_parameter_name: clt$parameter_name,
      initial_path: ^fst$file_reference,
      parse: clt$parse_state,
      path: ^string(*),
      units: ^clt$lexical_units,
      stat: ost_c_integer,
      syserrlist_message: string(256),
      work_area: ^^clt$work_area;

    status.normal := TRUE;
    stat := 0;
    syserrlist_message := ' ';

    PUSH path: [fsc$max_path_size];
    clp$getcwd (path, directory_length, syserrlist_message, stat);
    IF stat <> 0 THEN
      osp$set_status_from_errno ('WRITE', stat, syserrlist_message, status);
      RETURN;
    IFEND;
    working_catalog.path := path^ (1, directory_length);

    clp$get_work_area (osc$user_ring, work_area, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    clp$identify_lexical_units (^working_catalog.path (1, directory_length), work_area^, units, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    clp$initialize_parse_state (^working_catalog.path (1, directory_length), units, parse);
    clp$scan_non_space_lexical_unit (parse);
    initial_path := NIL;
    clp$complete_file_ref_parse (initial_path, parse, work_area^, $clt$file_ref_parsing_options
            [clc$unix_path_syntax], clv$user_identification, working_catalog.evaluated_file_reference,
            ignore_command_name, ignore_form, ignore_parameter_name, status);

  PROCEND clp$find_working_catalog;
*IFEND
?? TITLE := 'clp$setup_and_parse_file_ref', EJECT ??
*copyc clh$setup_and_parse_file_ref

  PROCEDURE [XDCL, INLINE] clp$setup_and_parse_file_ref
    (    file: fst$file_reference;
         file_reference_parsing_options: clt$file_ref_parsing_options;
         user_identification: clt$user_identification;
     VAR evaluated_file_reference: fst$evaluated_file_reference;
     VAR status: ost$status);

    VAR
      ignore_command_name: clt$name,
      ignore_form: clt$command_reference_form,
      ignore_status: ost$status,
      initial_path: ^fst$file_reference,
      parameter_name: clt$parameter_name,
      parse: clt$parse_state,
      path_parsed: boolean,
*IF $true(osv$unix)
      possibly_pre_evaluated: boolean,
*IFEND
      saved_parse: clt$parse_state,
      units: ^clt$lexical_units,
*IF $true(osv$unix)
      unix_path: boolean,
*IFEND
      work_area: ^^clt$work_area;

    status.normal := TRUE;

*IF NOT $true(osv$unix)
    clp$get_work_area (#RING (^parse), work_area, status);
*ELSE
    clp$get_work_area (osc$user_ring, work_area, status);
*IFEND
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    clp$identify_lexical_units (^file, work_area^, units, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  /parse_path/
    BEGIN
      clp$initialize_parse_state (^file, units, parse);
      clp$scan_non_space_lexical_unit (parse);
*IF NOT $true(osv$unix)
      CASE parse.unit.kind OF
      = clc$lex_colon =
*IFEND

{ Check if the file reference is a candidate for clp$parse_file_reference.

*IF NOT $true(osv$unix)
        IF clp$file_ref_is_pre_evaluated (file_reference_parsing_options, parse) THEN
          saved_parse := parse;
          clp$parse_file_reference (saved_parse, path_parsed, evaluated_file_reference, status);
          IF (NOT status.normal) OR path_parsed THEN
            parameter_name := osc$null_name;
            parse := saved_parse;
            EXIT /parse_path/;
          IFEND;
        IFEND;
      ELSE
        ;
      CASEND;
*ELSE
      unix_path := clc$unix_path_syntax IN file_reference_parsing_options;
      possibly_pre_evaluated := FALSE;
      IF possibly_pre_evaluated AND clp$file_ref_is_pre_evaluated (file_reference_parsing_options, parse) THEN
        saved_parse := parse;
        clp$parse_file_reference (unix_path, saved_parse, path_parsed, evaluated_file_reference, status);
        IF (NOT status.normal) OR path_parsed THEN
          parameter_name := osc$null_name;
          parse := saved_parse;
          EXIT /parse_path/;
        IFEND;
      IFEND;
*IFEND

      initial_path := NIL;
      clp$complete_file_ref_parse (initial_path, parse, work_area^, file_reference_parsing_options,
            user_identification, evaluated_file_reference, ignore_command_name, ignore_form, parameter_name,
            status);
    END /parse_path/;
    RESET work_area^ TO units;

    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF parameter_name <> osc$null_name THEN
      osp$set_status_abnormal ('CL', cle$parameter_never_given_value, parameter_name, status);
      RETURN;
    IFEND;

    IF parse.unit_is_space THEN
      clp$scan_non_space_lexical_unit (parse);
    IFEND;
    IF parse.unit.kind <> clc$lex_end_of_line THEN
      osp$set_status_condition (cle$expecting_end_of_file_ref, status);
      clp$append_status_parse_state (osc$status_parameter_delimiter, parse, status);
    IFEND;

  PROCEND clp$setup_and_parse_file_ref;
?? TITLE := 'convert_eval_to_parsed_file_ref', EJECT ??

  PROCEDURE [INLINE] convert_eval_to_parsed_file_ref
    (    evaluated_file_reference: fst$evaluated_file_reference;
         include_open_position: boolean;
     VAR parsed_file_reference: fst$parsed_file_reference;
     VAR status: ost$status);

    VAR
      cycle_ref_size: fst$path_index,
      cycle_ref_value: string (5),
      cycle_string: ost$string,
      element_index: fst$path_index,
      i: fst$path_index,
      local_status: ost$status,
      open_pos_size: 4 .. 5,
      size: fst$path_size;

    status.normal := TRUE;

    size := evaluated_file_reference.path_structure_size;
    parsed_file_reference.path := evaluated_file_reference.path_structure (1, size);
*IF NOT $true(osv$unix)
    parsed_file_reference.path (1) := ':';
*ELSE
    parsed_file_reference.path (1) := '/';
*IFEND
    i := $INTEGER (evaluated_file_reference.path_structure (1)) + 2;
    element_index := 1;
    WHILE i < size DO
*IF NOT $true(osv$unix)
      parsed_file_reference.path (i) := '.';
*ELSE
      parsed_file_reference.path (i) := '/';
*IFEND
      element_index := i;
      i := i + $INTEGER (evaluated_file_reference.path_structure (i)) + 1;
    WHILEND;
    parsed_file_reference.first_name.index := 2;
    parsed_file_reference.first_name.size := $INTEGER (evaluated_file_reference.path_structure (1));
    parsed_file_reference.last_name.index := element_index + 1;
    parsed_file_reference.last_name.size := $INTEGER (evaluated_file_reference.
          path_structure (element_index));
    parsed_file_reference.file_path_size := size;
    parsed_file_reference.catalog_path_size := element_index - 1;

*IF NOT $true(osv$unix)
    IF evaluated_file_reference.cycle_reference.specification <> fsc$cycle_omitted THEN
      CASE evaluated_file_reference.cycle_reference.specification OF
      = fsc$cycle_number =
        clp$convert_integer_to_string (evaluated_file_reference.cycle_reference.cycle_number, 10, FALSE,
              cycle_string, local_status);
        cycle_ref_size := cycle_string.size;
        cycle_ref_value := cycle_string.value (1, cycle_string.size);
      = fsc$high_cycle =
        cycle_ref_size := 5;
        cycle_ref_value := '$HIGH';
      = fsc$low_cycle =
        cycle_ref_size := 4;
        cycle_ref_value := '$LOW';
      = fsc$next_cycle =
        cycle_ref_size := 5;
        cycle_ref_value := '$NEXT';
      ELSE
        cycle_ref_size := fsc$max_path_size;
      CASEND;

      IF (i + cycle_ref_size) <= fsc$max_path_size THEN
        parsed_file_reference.path (i) := '.';
        parsed_file_reference.path (i + 1, cycle_ref_size) := cycle_ref_value;
        size := i + cycle_ref_size;
      ELSE
        osp$set_status_condition (cle$file_reference_too_long, status);
        RETURN;
      IFEND;
      parsed_file_reference.cycle_reference.index := i + 1;
      parsed_file_reference.cycle_reference.size := cycle_ref_size;
    ELSE
*IFEND
      parsed_file_reference.cycle_reference.index := 1;
      parsed_file_reference.cycle_reference.size := 0;
*IF NOT $true(osv$unix)
    IFEND;
*IFEND
    parsed_file_reference.cycle_path_size := size;

    parsed_file_reference.open_position.index := 1;
    parsed_file_reference.open_position.size := 0;

*IF NOT $true(osv$unix)
    IF evaluated_file_reference.path_handle_info.path_handle.open_position.specified AND
          include_open_position THEN
      open_pos_size := clv$open_position_designator [evaluated_file_reference.path_handle_info.path_handle.
            open_position.value].size;
      IF size + open_pos_size + 1 <= fsc$max_path_size THEN
        parsed_file_reference.path (size + 1) := '.';
        parsed_file_reference.path (size + 2, open_pos_size) :=
              clv$open_position_designator [evaluated_file_reference.path_handle_info.path_handle.
              open_position.value].value (1, open_pos_size);
        parsed_file_reference.open_position.index := size + 2;
        parsed_file_reference.open_position.size := open_pos_size;
        size := size + open_pos_size + 1;
      IFEND;
    IFEND;
*IFEND

    parsed_file_reference.complete_path_size := size;
    parsed_file_reference.number_of_path_elements := evaluated_file_reference.number_of_path_elements;

  PROCEND convert_eval_to_parsed_file_ref;
?? TITLE := 'format_path_name', EJECT ??

  PROCEDURE format_path_name
    (    local_file_name: clt$name;
         path: ^fst$path;
         path_name_size: 0 .. fsc$max_path_size;
         open_position: clt$open_position;
         format: ost$status_message_level;
     VAR file_reference: fst$path);

    VAR
      file_reference_size: 1 .. fsc$max_path_size,
      ignore_status: ost$status,
      index: 1 .. fsc$max_path_size,
      integer_string: ost$string,
*IF NOT $true(osv$unix)
      size: 1 .. fsc$max_path_size,
      working_catalog: ^^clt$working_catalog,
      working_catalog_path: fst$path,
      working_catalog_path_size: fst$path_size;
*ELSE
      size: 1 .. fsc$max_path_size;
*IFEND


*IF NOT $true(osv$unix)
    clp$find_working_catalog (working_catalog);

    IF format = osc$brief_message_level THEN
      clp$convert_file_ref_to_string (working_catalog^^.evaluated_file_reference, FALSE, working_catalog_path,
            working_catalog_path_size, ignore_status);
    IFEND;
*IFEND

    IF path = NIL THEN
*IF NOT $true(osv$unix)
      IF (format = osc$brief_message_level) AND (working_catalog_path = '$LOCAL') THEN
        file_reference := local_file_name.value (1, local_file_name.size);
      ELSE
*IFEND
        file_reference (1, 8) := ':$LOCAL.';
        file_reference (9, local_file_name.size) := local_file_name.value;
*IF NOT $true(osv$unix)
      IFEND;
*IFEND
      RETURN;
    IFEND;

    size := clp$trimmed_string_size (path^);
*IF NOT $true(osv$unix)
    IF format = osc$full_message_level THEN
*IFEND
      index := 1;
*IF NOT $true(osv$unix)
    ELSE
      index := working_catalog_path_size;
      IF (size > index) AND (path^ (1, index) = working_catalog_path) AND (path^ (index + 1) = '.') AND
            (path_name_size > working_catalog_path_size) THEN
        index := index + 2;
        size := size - index + 1;
      ELSE
        index := 1;
      IFEND;
    IFEND;
*IFEND

    file_reference_size := size;
    file_reference := path^ (index, file_reference_size);

*IF NOT $true(osv$unix)
    IF format = osc$full_message_level THEN
      IF open_position.specified THEN
        size := clv$open_position_designator [open_position.value].size;
        IF (file_reference_size + 1 + size) <= fsc$max_path_size THEN
          file_reference (file_reference_size + 1) := '.';
          file_reference (file_reference_size + 2, size) := clv$open_position_designator
                [open_position.value].value (1, size);
        IFEND;
      IFEND;
    IFEND;
*IFEND

  PROCEND format_path_name;

MODEND clm$file_reference_manager;
