?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE SCL Interpreter : Wild Card File Reference Expansion' ??
MODULE clm$wild_card_file_expansion;

{
{ PURPOSE:
{   This module contains request that expands a file reference containing
{   "wild cards" into a "list of file".
{

?? NEWTITLE := 'Global Declarations', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc cle$no_match_for_wild_card_file
*copyc cle$wild_card_cant_be_first
*copyc cle$work_area_overflow
*copyc clt$data_value
*copyc clt$wc_file_expansion_option
*copyc clt$work_area
*copyc fsc$local
*copyc fst$evaluated_file_reference
*copyc pft$p_cycle_array
*copyc fst$path_element_name
*copyc oss$job_paged_literal
*copyc ost$status
?? POP ??
*copyc bap$process_pt_request
*copyc clp$build_pattern_for_wild_card
*copyc clp$convert_file_ref_to_string
*copyc clp$convert_integer_to_string
*copyc clp$evaluate_file_reference
*copyc clp$find_scl_options
*copyc clp$get_file_cycles
*copyc clp$get_list_of_$local_files
*copyc clp$make_file_value
*copyc clp$make_list_value
*copyc clp$make_value
*copyc clp$match_string_pattern
*copyc clp$trimmed_string_size
*copyc clv$open_position_designator
*copyc fsp$convert_fs_structure_to_pf
*copyc fsp$path_element
*copyc osp$generate_log_message
*copyc osp$set_status_abnormal
*copyc pfp$find_directory_array
*copyc pfp$find_next_info_record
*copyc pfp$get_multi_item_info

?? TITLE := 'clp$wild_card_file_expansion', EJECT ??
*copyc clh$wild_card_file_expansion

  PROCEDURE [XDCL, #GATE] clp$wild_card_file_expansion
    (    evaluated_file_reference: fst$evaluated_file_reference;
         expansion_option: clt$wc_file_expansion_option;
     VAR work_area {input, output} : ^clt$work_area;
     VAR result_list_head: ^clt$data_value;
     VAR result_list_tail: ^clt$data_value;
     VAR status: ost$status);

    CONST
      max_cycle_reference = 5,
      max_open_position = 5,
      max_cycle_ref_open_pos_suffix = 1 + max_cycle_reference + 1 + max_open_position;

    TYPE
      chars = set of char;

    VAR
      current_list_node: ^^clt$data_value,
      cycle_ref_open_pos_suffix: string (max_cycle_ref_open_pos_suffix),
      cycle_ref_open_pos_suffix_size: 0 .. max_cycle_ref_open_pos_suffix,
      first_path_element: ^fst$path_element_string,
      include_catalogs: boolean,
      include_files: boolean,
      local_status: ost$status,
      open_pos_suffix_index: 1 .. max_cycle_ref_open_pos_suffix + 1,
      open_pos_suffix_size: 0 .. 1 + max_open_position,
      original_path: ^fst$path,
      original_path_size: fst$path_size,
      path: ^fst$file_reference,
      scl_options: ^clt$scl_options,
      traversal_count: integer,
      wild_card_characters: chars;

?? NEWTITLE := 'add_path_and_open_pos_to_list', EJECT ??

    PROCEDURE add_path_and_open_pos_to_list
      (    path: fst$file_reference);


      IF (STRLENGTH (path) + open_pos_suffix_size) > fsc$max_path_size THEN
        osp$set_status_abnormal ('CL', cle$file_reference_too_long, '', status);
        EXIT clp$wild_card_file_expansion;
      IFEND;

      IF (traversal_count > 1) AND path_is_in_list (path) THEN
        RETURN;
      IFEND;

      clp$make_list_value (work_area, current_list_node^);
      IF current_list_node^ = NIL THEN
        work_area_overflow;
      IFEND;
      clp$make_value (clc$file, work_area, current_list_node^^.element_value);
      IF current_list_node^^.element_value = NIL THEN
        work_area_overflow;
      IFEND;
      NEXT current_list_node^^.element_value^.file_value: [STRLENGTH (path) + open_pos_suffix_size] IN
            work_area;
      IF current_list_node^^.element_value^.file_value = NIL THEN
        work_area_overflow;
      IFEND;

      current_list_node^^.element_value^.file_value^ := path;
      IF open_pos_suffix_size > 0 THEN
        current_list_node^^.element_value^.file_value^ (STRLENGTH (path) + 1,
              open_pos_suffix_size) := cycle_ref_open_pos_suffix
              (open_pos_suffix_index, open_pos_suffix_size);
      IFEND;

      result_list_tail := current_list_node^;
      current_list_node := ^result_list_tail^.link;

    PROCEND add_path_and_open_pos_to_list;
?? TITLE := 'add_path_and_suffix_to_list', EJECT ??

    PROCEDURE add_path_and_suffix_to_list
      (    path: fst$file_reference);


      IF (STRLENGTH (path) + cycle_ref_open_pos_suffix_size) > fsc$max_path_size THEN
        osp$set_status_abnormal ('CL', cle$file_reference_too_long, '', status);
        EXIT clp$wild_card_file_expansion;
      IFEND;

      IF (traversal_count > 1) AND path_is_in_list (path) THEN
        RETURN;
      IFEND;

      clp$make_list_value (work_area, current_list_node^);
      IF current_list_node^ = NIL THEN
        work_area_overflow;
      IFEND;
      clp$make_value (clc$file, work_area, current_list_node^^.element_value);
      IF current_list_node^^.element_value = NIL THEN
        work_area_overflow;
      IFEND;
      NEXT current_list_node^^.element_value^.file_value: [STRLENGTH (path) +
            cycle_ref_open_pos_suffix_size] IN work_area;
      IF current_list_node^^.element_value^.file_value = NIL THEN
        work_area_overflow;
      IFEND;

      current_list_node^^.element_value^.file_value^ := path;
      IF cycle_ref_open_pos_suffix_size > 0 THEN
        current_list_node^^.element_value^.file_value^ (STRLENGTH (path) + 1,
              cycle_ref_open_pos_suffix_size) := cycle_ref_open_pos_suffix;
      IFEND;

      result_list_tail := current_list_node^;
      current_list_node := ^result_list_tail^.link;

    PROCEND add_path_and_suffix_to_list;
?? TITLE := 'add_path_to_list', EJECT ??

    PROCEDURE add_path_to_list
      (    path: fst$file_reference);


      IF (traversal_count > 1) AND path_is_in_list (path) THEN
        RETURN;
      IFEND;

      clp$make_list_value (work_area, current_list_node^);
      IF current_list_node^ = NIL THEN
        work_area_overflow;
      IFEND;
      clp$make_file_value (path, work_area, current_list_node^^.element_value);
      IF current_list_node^^.element_value = NIL THEN
        work_area_overflow;
      IFEND;
      result_list_tail := current_list_node^;
      current_list_node := ^result_list_tail^.link;

    PROCEND add_path_to_list;
?? TITLE := 'contains_wild_card', EJECT ??

    FUNCTION [INLINE] contains_wild_card
      (    path_element: ^fst$path_element_string): boolean;

      VAR
        ignore_scan_index: integer,
        scan_found_char: boolean;


      #SCAN (wild_card_characters, path_element^, ignore_scan_index, scan_found_char);
      contains_wild_card := scan_found_char;

    FUNCEND contains_wild_card;
?? TITLE := 'cycle_number_exists', EJECT ??

    FUNCTION cycle_number_exists
      (    cycles: pft$p_cycle_array): boolean;

      VAR
        i: pft$array_index;


      FOR i := LOWERBOUND (cycles^) TO UPPERBOUND (cycles^) DO
        IF cycles^ [i].cycle_number = evaluated_file_reference.cycle_reference.cycle_number THEN
          cycle_number_exists := TRUE;
          RETURN;
        IFEND;
      FOREND;

      cycle_number_exists := FALSE;

    FUNCEND cycle_number_exists;
?? TITLE := 'path_is_in_list', EJECT ??

    FUNCTION [INLINE] path_is_in_list
      (    path: fst$file_reference): boolean;

      VAR
        local_node: ^clt$data_value;


      local_node := result_list_head;

      WHILE local_node <> NIL DO
        IF local_node^.element_value^.file_value^ = path THEN
          path_is_in_list := TRUE;
          RETURN;
        IFEND;
        local_node := local_node^.link;
      WHILEND;

      path_is_in_list := FALSE;

    FUNCEND path_is_in_list;
?? TITLE := 'prepare_cycle_open_pos_suffix', EJECT ??

    PROCEDURE prepare_cycle_open_pos_suffix;

      VAR
        cycle_string: ost$string;


      cycle_ref_open_pos_suffix_size := 0;
      open_pos_suffix_index := 1;
      open_pos_suffix_size := 0;

      IF evaluated_file_reference.cycle_reference.specification <> fsc$cycle_omitted THEN
        include_catalogs := FALSE;
        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_open_pos_suffix_size := 1 + cycle_string.size;
          cycle_ref_open_pos_suffix (1) := '.';
          cycle_ref_open_pos_suffix (2, * ) := cycle_string.value (1, cycle_string.size);
        = fsc$high_cycle =
          cycle_ref_open_pos_suffix_size := 6;
          cycle_ref_open_pos_suffix := '.$HIGH';
        = fsc$low_cycle =
          cycle_ref_open_pos_suffix_size := 5;
          cycle_ref_open_pos_suffix := '.$LOW';
        = fsc$next_cycle =
          cycle_ref_open_pos_suffix_size := 6;
          cycle_ref_open_pos_suffix := '.$NEXT';
        ELSE
          ;
        CASEND;
        open_pos_suffix_index := cycle_ref_open_pos_suffix_size + 1;
      IFEND;

      IF evaluated_file_reference.path_handle_info.path_handle.open_position.specified THEN
        include_catalogs := FALSE;
        open_pos_suffix_size := clv$open_position_designator
              [evaluated_file_reference.path_handle_info.path_handle.open_position.value].size;
        cycle_ref_open_pos_suffix (cycle_ref_open_pos_suffix_size + 1) := '.';
        cycle_ref_open_pos_suffix (cycle_ref_open_pos_suffix_size + 2,
              open_pos_suffix_size) := clv$open_position_designator
              [evaluated_file_reference.path_handle_info.path_handle.open_position.value].
              value (1, open_pos_suffix_size);
        open_pos_suffix_size := 1 + open_pos_suffix_size;
        cycle_ref_open_pos_suffix_size := cycle_ref_open_pos_suffix_size + open_pos_suffix_size;
      IFEND;

    PROCEND prepare_cycle_open_pos_suffix;
?? TITLE := 'process_element', EJECT ??

    PROCEDURE process_element
      (    starting_path: fst$file_reference;
           starting_element_number: fst$number_of_path_elements);

      VAR
        current_path_element: ^fst$path_element_string,
        cycles: pft$p_cycle_array,
        directory: pft$p_directory_array,
        element_number: fst$number_of_path_elements,
        i: pft$array_index,
        item_is_catalog: boolean,
        local_status: ost$status,
        match_info: clt$string_pattern_match_info,
        name_size: ost$name_size,
        path: fst$path,
        path_size: fst$path_size,
        string_pattern: ^clt$string_pattern;

?? NEWTITLE := 'get_catalog_directory', EJECT ??

      PROCEDURE get_catalog_directory
        (    catalog: fst$file_reference;
         VAR directory: pft$p_directory_array);

        VAR
          evaluated_file_reference: fst$evaluated_file_reference,
          first_path_element_is_$local: boolean,
          group: pft$group,
          info: pft$p_info,
          info_record: pft$p_info_record,
          pf_path: ^pft$path;

?? NEWTITLE := 'sort_directory', EJECT ??

        PROCEDURE sort_directory;

          VAR
            gap: integer,
            start: integer,
            current: integer,
            swap: pft$directory_array_entry;

{ Use shell sort technique.

          gap := UPPERBOUND (directory^);
          WHILE gap > 1 DO
            gap := 2 * (gap DIV 4) + 1;
            FOR start := 1 TO UPPERBOUND (directory^) - gap DO
              current := start;
              WHILE (current > 0) AND (directory^ [current].name > directory^ [current + gap].name) DO
                swap := directory^ [current];
                directory^ [current] := directory^ [current + gap];
                directory^ [current + gap] := swap;
                current := current - gap;
              WHILEND;
            FOREND;
          WHILEND;

        PROCEND sort_directory;
?? OLDTITLE, EJECT ??

        directory := NIL;

        clp$evaluate_file_reference (catalog, $clt$file_ref_parsing_options [], FALSE,
              evaluated_file_reference, local_status);
        IF NOT local_status.normal THEN
          RETURN;
        IFEND;

        first_path_element_is_$local := fsp$path_element (^evaluated_file_reference, 1) ^ = fsc$local;

        IF first_path_element_is_$local AND (evaluated_file_reference.number_of_path_elements > 1) THEN
          RETURN;
        IFEND;

        info := work_area;

        IF first_path_element_is_$local THEN
          clp$get_list_of_$local_files (work_area, local_status);

        ELSE
          PUSH pf_path: [1 .. evaluated_file_reference.number_of_path_elements];
          fsp$convert_fs_structure_to_pf (evaluated_file_reference, pf_path);

          group.group_type := pfc$member;
          group.member_description.family := osc$null_name;
          group.member_description.account := osc$null_name;
          group.member_description.project := osc$null_name;
          group.member_description.user := osc$null_name;

          pfp$get_multi_item_info (pf_path^, group, $pft$catalog_info_selections [pfc$catalog_directory],
                $pft$file_info_selections [pfc$file_directory], work_area, local_status);
        IFEND;

        IF NOT local_status.normal THEN
          RETURN;
        IFEND;

        pfp$find_next_info_record (info, info_record, local_status);
        IF NOT local_status.normal THEN
          RETURN;
        IFEND;
        pfp$find_directory_array (info_record, directory, local_status);
        IF NOT local_status.normal THEN
          RETURN;
        IFEND;

        IF directory <> NIL THEN
          sort_directory;
        IFEND;

      PROCEND get_catalog_directory;
?? TITLE := 'get_catalog_item_info', EJECT ??

      PROCEDURE get_catalog_item_info
        (    path: fst$file_reference;
         VAR item_is_catalog: boolean;
         VAR cycles: pft$p_cycle_array);

        VAR
          cycle_array: ^array [1 .. * ] of fst$cycle_number,
          evaluated_file_reference: fst$evaluated_file_reference,
          first_path_element_is_$local: boolean,
          group: pft$group,
          i: fst$cycle_number,
          info: pft$p_info;

?? NEWTITLE := 'sort_cycles', EJECT ??

        PROCEDURE sort_cycles;

          VAR
            gap: integer,
            start: integer,
            current: integer,
            swap: pft$cycle_array_entry;

{ Use shell sort technique.

          gap := UPPERBOUND (cycles^);
          WHILE gap > 1 DO
            gap := 2 * (gap DIV 4) + 1;
            FOR start := 1 TO UPPERBOUND (cycles^) - gap DO
              current := start;
              WHILE (current > 0) AND (cycles^ [current].cycle_number < cycles^ [current + gap].
                    cycle_number) DO
                swap := cycles^ [current];
                cycles^ [current] := cycles^ [current + gap];
                cycles^ [current + gap] := swap;
                current := current - gap;
              WHILEND;
            FOREND;
          WHILEND;

        PROCEND sort_cycles;
?? OLDTITLE, EJECT ??

        item_is_catalog := FALSE;
        cycles := NIL;

        clp$evaluate_file_reference (path, $clt$file_ref_parsing_options [], FALSE, evaluated_file_reference,
              local_status);
        IF NOT local_status.normal THEN
          RETURN;
        IFEND;

        first_path_element_is_$local := fsp$path_element (^evaluated_file_reference, 1) ^ = fsc$local;

        IF first_path_element_is_$local AND (evaluated_file_reference.number_of_path_elements = 1) THEN
          item_is_catalog := TRUE;
          RETURN;
        IFEND;

        clp$get_file_cycles (path, work_area, cycle_array, local_status);
        IF (NOT local_status.normal) THEN
          IF local_status.condition = pfe$name_not_permanent_file THEN
            item_is_catalog := TRUE;
          IFEND;
          RETURN;
        ELSEIF (cycle_array = NIL) THEN
          RETURN;
        IFEND;

        NEXT cycles: [1 .. UPPERBOUND (cycle_array^)] IN work_area;
        IF cycles = NIL THEN
          work_area_overflow;
        IFEND;
        FOR i := 1 TO UPPERBOUND (cycle_array^) DO
          cycles^ [i].cycle_number := cycle_array^ [i];
        FOREND;

        IF cycles <> NIL THEN
          sort_cycles;
        IFEND;

      PROCEND get_catalog_item_info;
?? TITLE := 'process_path_traversal', EJECT ??

      PROCEDURE process_path_traversal
        (    path: fst$file_reference;
             element_number: fst$number_of_path_elements);

        VAR
          directory: pft$p_directory_array,
          i: pft$array_index,
          sub_path: fst$path;


        process_element (path, element_number);

        get_catalog_directory (path, directory);
        IF directory <> NIL THEN
          sub_path := path;
          sub_path (STRLENGTH (path) + 1) := '.';

          FOR i := LOWERBOUND (directory^) TO UPPERBOUND (directory^) DO
            sub_path (STRLENGTH (path) + 2, * ) := directory^ [i].name;
            process_path_traversal (sub_path (1, STRLENGTH (path) +
                  1 + clp$trimmed_string_size (directory^ [i].name)), element_number);
          FOREND;
        IFEND;

      PROCEND process_path_traversal;
?? TITLE := 'process_subordinate_paths', EJECT ??

      PROCEDURE process_subordinate_paths
        (    path: fst$file_reference);

        VAR
          cycle_string: ost$string,
          cycles: pft$p_cycle_array,
          directory: pft$p_directory_array,
          i: pft$array_index,
          item_is_catalog: boolean,
          sub_path: fst$path;


        get_catalog_item_info (path, item_is_catalog, cycles);
        sub_path := path;
        sub_path (STRLENGTH (path) + 1) := '.';

        IF item_is_catalog THEN
          IF include_catalogs THEN
            add_path_to_list (path);
          IFEND;
          get_catalog_directory (path, directory);
          IF directory <> NIL THEN
            FOR i := LOWERBOUND (directory^) TO UPPERBOUND (directory^) DO
              sub_path (STRLENGTH (path) + 2, * ) := directory^ [i].name;
              process_subordinate_paths (sub_path (1, STRLENGTH (path) +
                    1 + clp$trimmed_string_size (directory^ [i].name)));
            FOREND;
          IFEND;

        ELSEIF (cycles <> NIL) AND include_files THEN
          CASE evaluated_file_reference.cycle_reference.specification OF
          = fsc$cycle_omitted =
            FOR i := LOWERBOUND (cycles^) TO UPPERBOUND (cycles^) DO
              clp$convert_integer_to_string (cycles^ [i].cycle_number, 10, FALSE, cycle_string,
                    {ignore} status);
              sub_path (STRLENGTH (path) + 2, * ) := cycle_string.value (1, cycle_string.size);
              add_path_and_open_pos_to_list (sub_path (1, STRLENGTH (path) + 1 + cycle_string.size));
            FOREND;
          = fsc$cycle_number =
            IF cycle_number_exists (cycles) THEN
              add_path_and_suffix_to_list (path);
            IFEND;
          ELSE
            add_path_and_suffix_to_list (path);
          CASEND;
        IFEND;

      PROCEND process_subordinate_paths;
?? OLDTITLE, EJECT ??

      path := starting_path;
      path_size := STRLENGTH (starting_path);
      element_number := starting_element_number;

      WHILE element_number <= evaluated_file_reference.number_of_path_elements DO
        current_path_element := fsp$path_element (^evaluated_file_reference, element_number);

        IF current_path_element^ = '$ALL' THEN
          IF element_number = evaluated_file_reference.number_of_path_elements THEN
            traversal_count := traversal_count + 1;
            process_subordinate_paths (path (1, path_size));
            traversal_count := traversal_count - 1;
            RETURN;
          IFEND;

{ If the next path element is also $ALL, ignore the current element.
{ This has the effect of treating adjacent $ALL's as if there's only one.

          IF fsp$path_element (^evaluated_file_reference, element_number + 1) ^ <> '$ALL' THEN
            traversal_count := traversal_count + 1;
            process_path_traversal (path (1, path_size), element_number + 1);
            traversal_count := traversal_count - 1;
            RETURN;
          IFEND;

        ELSEIF contains_wild_card (current_path_element) THEN
          get_catalog_directory (path (1, path_size), directory);
          IF directory = NIL THEN
            RETURN;
          IFEND;

          clp$build_pattern_for_wild_card (scl_options^.wild_card_pattern_type,
                $clt$string_pattern_build_opts [clc$sp_match_at_right, clc$sp_ignore_matched_substring],
                current_path_element^, work_area, string_pattern, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;

          FOR i := LOWERBOUND (directory^) TO UPPERBOUND (directory^) DO
            IF (directory^ [i].name_type = pfc$catalog_name) OR include_files THEN
              name_size := clp$trimmed_string_size (directory^ [i].name);
              clp$match_string_pattern (directory^ [i].name (1, name_size), string_pattern, clc$sp_anchored,
                    clc$sp_quick_scan, match_info, status);
              IF status.normal THEN
                IF match_info.result = clc$sp_success THEN
                  path (path_size + 1) := '.';
                  path (path_size + 2, name_size) := directory^ [i].name (1, name_size);
                  IF element_number < evaluated_file_reference.number_of_path_elements THEN
                    process_element (path (1, path_size + 1 + name_size), element_number + 1);
                  ELSEIF directory^ [i].name_type = pfc$file_name THEN
                    IF evaluated_file_reference.cycle_reference.specification <> fsc$cycle_number THEN
                      add_path_and_suffix_to_list (path (1, path_size + 1 + name_size));
                    ELSE
                      get_catalog_item_info (path (1, path_size + 1 + name_size), item_is_catalog, cycles);
                      IF (cycles <> NIL) AND cycle_number_exists (cycles) THEN
                        add_path_and_suffix_to_list (path (1, path_size + 1 + name_size));
                      IFEND;
                    IFEND;
                  ELSEIF include_catalogs THEN
                    add_path_to_list (path (1, path_size + 1 + name_size));
                  IFEND;
                IFEND;
              ELSE
                RETURN;
              IFEND;
            IFEND;
          FOREND;
          RETURN;

        ELSE
          path (path_size + 1) := '.';
          path (path_size + 2, STRLENGTH (current_path_element^)) := current_path_element^;
          path_size := path_size + 1 + STRLENGTH (current_path_element^);

          IF element_number = evaluated_file_reference.number_of_path_elements THEN
            get_catalog_item_info (path (1, path_size), item_is_catalog, cycles);
            IF item_is_catalog AND include_catalogs THEN
              add_path_to_list (path (1, path_size));
            ELSEIF (cycles <> NIL) AND include_files AND ((evaluated_file_reference.cycle_reference.
                  specification <> fsc$cycle_number) OR cycle_number_exists (cycles)) THEN
              add_path_and_suffix_to_list (path (1, path_size));
            IFEND;
            RETURN;
          IFEND;
        IFEND;

        element_number := element_number + 1;
      WHILEND;

    PROCEND process_element;
?? TITLE := 'work_area_overflow', EJECT ??

    PROCEDURE [INLINE] work_area_overflow;


      osp$set_status_abnormal ('CL', cle$work_area_overflow, 'clp$wild_card_file_expansion', status);
      EXIT clp$wild_card_file_expansion;

    PROCEND work_area_overflow;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;
    result_list_head := NIL;
    result_list_tail := NIL;
    traversal_count := 0;

    clp$find_scl_options (scl_options);

    IF scl_options^.wild_card_pattern_type = clc$wc_basic_pattern THEN
      wild_card_characters := $chars ['*', '?'];
    ELSE { clc$wc_extended_pattern }
      wild_card_characters := $chars ['*', '?', '[', '-', ']', '{', '}'];
    IFEND;

    first_path_element := fsp$path_element (^evaluated_file_reference, 1);
    IF (first_path_element^ = '$ALL') OR contains_wild_card (first_path_element) THEN
      osp$set_status_abnormal ('CL', cle$wild_card_cant_be_first, '', status);
      RETURN;
    IFEND;

    CASE expansion_option OF
    = clc$wcfe_only_files =
      include_files := TRUE;
      include_catalogs := FALSE;
    = clc$wcfe_only_catalogs =
      include_files := FALSE;
      include_catalogs := TRUE;
    ELSE {clc$wcfe_files_and_catalogs}
      include_files := TRUE;
      include_catalogs := TRUE;
    CASEND;

    current_list_node := ^result_list_head;

    prepare_cycle_open_pos_suffix;

    IF include_files OR include_catalogs THEN
      PUSH path: [1 + STRLENGTH (first_path_element^)];
      path^ (1) := ':';
      path^ (2, * ) := first_path_element^;
      IF (evaluated_file_reference.number_of_path_elements = 1) AND (first_path_element^ = '$LOCAL') AND
            include_catalogs THEN
        add_path_to_list (path^ (1, clp$trimmed_string_size (path^)));
        RETURN;
      IFEND;
      process_element (path^, 2);
    IFEND;

    IF result_list_head = NIL THEN
      PUSH original_path;
      clp$convert_file_ref_to_string (evaluated_file_reference, TRUE, original_path^, original_path_size,
            {ignore} status);
      IF original_path_size > osc$max_string_size THEN
        original_path_size := osc$max_string_size;
      IFEND;
      osp$set_status_abnormal ('CL', cle$no_match_for_wild_card_file, original_path^ (1, original_path_size),
            status);
    IFEND;

  PROCEND clp$wild_card_file_expansion;

MODEND clm$wild_card_file_expansion;
