?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE SCL Interpreter : Help Message Services' ??
MODULE clm$help_message_interfaces;

{
{ PURPOSE:
{   This module contains routines to search for help modules and information
{   within them.
{

?? NEWTITLE := 'Global Declarations', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc amt$local_file_name
*copyc cle$ecc_expression_result
*copyc cle$ecc_mt_generator
*copyc cst$menu_class
*copyc cst$menu_list
*copyc llt$object_library_header
*copyc osc$max_system_message_modules
*copyc osd$virtual_address
*copyc ose$message_gen_exceptions
*copyc ost$application_menu_name
*copyc ost$caller_identifier
*copyc ost$help_module
*copyc ost$message_template
*copyc ost$message_template_kind
*copyc ost$message_template_module
*copyc ost$mtm_condition_codes
*copyc ost$mtm_condition_names
*copyc ost$mtm_header
*copyc ost$name
*copyc ost$natural_language
*copyc ost$online_manual_name
*copyc ost$status
*copyc ost$status_condition_code
*copyc ost$status_condition_name
*copyc ost$status_severity
*copyc ost$string
*copyc osv$lower_to_upper
*copyc osv$system_message_modules
*copyc pmt$program_name
?? POP ??
*copyc clp$extract_msg_module_contents
*copyc clp$find_command_list
*copyc clp$search_for_help_module
*copyc clp$search_help_module
*copyc clp$search_module_for_code
*copyc clp$search_module_for_name
*copyc clp$trimmed_string_size
*copyc clp$validate_name
*copyc osp$convert_to_status_severity
*copyc osp$enforce_exception_policies
*copyc osp$file_access_condition
*copyc osp$find_natural_language
*copyc osp$format_help_message
*copyc osp$set_status_abnormal
*copyc osv$initial_exception_context
*copyc pmp$get_library_dictionaries
*copyc pmp$log
?? TITLE := 'osp$find_help_module', EJECT ??
*copy osh$find_help_module

  PROCEDURE [XDCL, #GATE] osp$find_help_module
    (    seed_name: pmt$program_name;
     VAR help_module: ^ost$help_module;
     VAR online_manual_name: ost$online_manual_name;
     VAR natural_language: ost$natural_language;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      command_list: ^clt$command_list,
      current_entry: ^clt$command_list_entry,
      entry_found: boolean,
      i: integer,
      ignore_cmnd_list_found_in_task: boolean,
      local_library_name: amt$local_file_name,
      local_status: ost$status,
      module_index: 1 .. osc$max_system_message_modules,
      module_name: string (2 * osc$max_name_size + 1),
      module_name_length: integer,
      preferred_language: ost$natural_language,
      search_name: ost$name,
      selected_language: ^ost$natural_language,
      system_help_library_searched: boolean;

?? TITLE := 'search_for_help_module', EJECT ??

    PROCEDURE [INLINE] search_for_help_module;

      VAR
        context: ^ost$ecp_exception_context;

      context := NIL;

      REPEAT
        clp$search_for_help_module (caller_id.ring, search_name, local_library_name, entry_found, help_module,
              natural_language, online_manual_name, local_status);
        IF osp$file_access_condition (local_status) THEN
          IF context = NIL THEN
            PUSH context;
            context^ := osv$initial_exception_context;
            context^.file.selector := osc$ecp_file_reference;
            context^.file.file_reference := ^local_library_name;
          IFEND;
          context^.condition_status := local_status;
          osp$enforce_exception_policies (context^);
          local_status := context^.condition_status;
        IFEND;
      UNTIL local_status.normal OR (NOT osp$file_access_condition (local_status)) OR (NOT context^.wait);

    PROCEND search_for_help_module;

    status.normal := TRUE;
    local_status.normal := TRUE;
    #CALLER_ID (caller_id);
    help_module := NIL;
    online_manual_name := osc$null_name;
    natural_language := osc$null_name;
    osp$find_natural_language (selected_language);
    preferred_language := selected_language^;
    entry_found := FALSE;

  /search/
    WHILE TRUE DO
      STRINGREP (module_name, module_name_length, seed_name (1, clp$trimmed_string_size (seed_name)), '$',
            preferred_language (1, clp$trimmed_string_size (preferred_language)));

      #TRANSLATE (osv$lower_to_upper, module_name (1, module_name_length), search_name);

      clp$find_command_list (command_list, ignore_cmnd_list_found_in_task);
      current_entry := command_list^.entries.first_entry;

      WHILE current_entry <> NIL DO
        CASE current_entry^.kind OF

        = clc$library_commands =
          IF current_entry^.library_contains.help_modules AND NOT current_entry^.unaccessible_entry THEN
            local_library_name := current_entry^.local_file_name;
            search_for_help_module;
            IF (NOT local_status.normal) OR entry_found THEN
              EXIT /search/;
            IFEND;
          IFEND;

        = clc$system_commands =
          IF (command_list^.system_command_library_lfn <> osc$null_name) AND
                command_list^.system_library_contains.help_modules THEN
            local_library_name := command_list^.system_command_library_lfn;
            search_for_help_module;
            IF (NOT local_status.normal) OR entry_found THEN
              EXIT /search/;
            IFEND;
          IFEND;

        = clc$sub_commands =
          IF current_entry^.utility_info^.auxiliary_libraries <> NIL THEN
            FOR i := 1 TO UPPERBOUND (current_entry^.utility_info^.auxiliary_libraries^) DO
              IF current_entry^.utility_info^.auxiliary_libraries^ [i].contains.help_modules THEN
                local_library_name := current_entry^.utility_info^.auxiliary_libraries^ [i].name;
                search_for_help_module;
                IF NOT local_status.normal THEN
                  local_status.normal := TRUE;
                ELSEIF entry_found THEN
                  EXIT /search/;
                IFEND;
              IFEND;
            FOREND;
          IFEND;

        ELSE
          ;
        CASEND;

        current_entry := current_entry^.next_entry;
      WHILEND;
      IF preferred_language = osc$default_natural_language THEN
        EXIT /search/;
      IFEND;
      preferred_language := osc$default_natural_language;
    WHILEND /search/;

    IF NOT local_status.normal THEN
      status := local_status;
    ELSEIF NOT entry_found THEN

{ Search table of system message modules defined in osm$message_module_pointers }

      #TRANSLATE (osv$lower_to_upper, seed_name, search_name);
      FOR module_index := 1 TO osc$max_system_message_modules DO
        IF search_name = osv$system_message_modules [module_index].module_name THEN
          help_module := osv$system_message_modules [module_index].module_pointer_p^;
          RETURN;
        IFEND;
      FOREND;
    IFEND;

  PROCEND osp$find_help_module;
?? TITLE := 'osp$find_brief_help_message', EJECT ??
*copy osh$find_brief_help_message

  PROCEDURE [XDCL, #GATE] osp$find_brief_help_message
    (    help_module: ^ost$help_module;
     VAR message_template: ^ost$message_template;
     VAR status: ost$status);

    VAR
      local_help_module: ^ost$help_module,
      ignore_condition_codes: ^ost$mtm_condition_codes,
      names: ^ost$mtm_condition_names,
      blank_name: clt$parameter_name,
      kind: ost$message_template_kind,
      header: ^ost$mtm_header;


    status.normal := TRUE;
    local_help_module := help_module;
    message_template := NIL;
    ignore_condition_codes := NIL;
    names := NIL;
    blank_name := osc$null_name;
    kind := osc$brief_help;

    IF help_module = NIL THEN
      RETURN;
    IFEND;

    clp$extract_msg_module_contents (local_help_module, header, ignore_condition_codes, names);
    IF header = NIL THEN
      osp$set_status_abnormal ('CL', cle$bad_help_module, '', status);
      RETURN;
    IFEND;

    clp$search_help_module (blank_name, kind, names, local_help_module, message_template);

  PROCEND osp$find_brief_help_message;
?? TITLE := 'osp$find_full_help_message', EJECT ??
*copy osh$find_full_help_message

  PROCEDURE [XDCL, #GATE] osp$find_full_help_message
    (    help_module: ^ost$help_module;
     VAR message_template: ^ost$message_template;
     VAR status: ost$status);

    VAR
      local_help_module: ^ost$help_module,
      ignore_condition_codes: ^ost$mtm_condition_codes,
      names: ^ost$mtm_condition_names,
      header: ^ost$mtm_header,
      blank_name: clt$parameter_name,
      kind: ost$message_template_kind;


    status.normal := TRUE;
    local_help_module := help_module;
    message_template := NIL;
    ignore_condition_codes := NIL;
    names := NIL;
    blank_name := osc$null_name;
    kind := osc$full_help;

    IF help_module = NIL THEN
      RETURN;
    IFEND;

    clp$extract_msg_module_contents (local_help_module, header, ignore_condition_codes, names);
    IF header = NIL THEN
      osp$set_status_abnormal ('CL', cle$bad_help_module, '', status);
      RETURN;
    IFEND;

    clp$search_help_module (blank_name, kind, names, local_help_module, message_template);

  PROCEND osp$find_full_help_message;
?? TITLE := 'osp$find_parameter_prompt', EJECT ??
*copy osh$find_parameter_prompt

  PROCEDURE [XDCL, #GATE] osp$find_parameter_prompt
    (    help_module: ^ost$help_module;
         parameter_name: clt$parameter_name;
     VAR prompt_template: ^ost$message_template;
     VAR status: ost$status);

    VAR
      local_help_module: ^ost$help_module,
      ignore_condition_codes: ^ost$mtm_condition_codes,
      names: ^ost$mtm_condition_names,
      header: ^ost$mtm_header,
      kind: ost$message_template_kind;


    status.normal := TRUE;
    local_help_module := help_module;
    prompt_template := NIL;
    ignore_condition_codes := NIL;
    names := NIL;
    kind := osc$parameter_prompt;

    IF help_module = NIL THEN
      RETURN;
    IFEND;

    clp$extract_msg_module_contents (local_help_module, header, ignore_condition_codes, names);
    IF header = NIL THEN
      osp$set_status_abnormal ('CL', cle$bad_help_module, '', status);
      RETURN;
    IFEND;

    clp$search_help_module (parameter_name, kind, names, local_help_module, prompt_template);

  PROCEND osp$find_parameter_prompt;
?? TITLE := 'osp$find_param_assist_prompt', EJECT ??
*copy osh$find_param_assist_prompt

  PROCEDURE [XDCL, #GATE] osp$find_param_assist_prompt
    (    help_module: ^ost$help_module;
         parameter_name: clt$parameter_name;
     VAR prompt_template: ^ost$message_template;
     VAR status: ost$status);

    VAR
      local_help_module: ^ost$help_module,
      ignore_condition_codes: ^ost$mtm_condition_codes,
      names: ^ost$mtm_condition_names,
      header: ^ost$mtm_header,
      kind: ost$message_template_kind;


    status.normal := TRUE;
    local_help_module := help_module;
    prompt_template := NIL;
    ignore_condition_codes := NIL;
    names := NIL;
    kind := osc$parameter_assistance_prompt;

    IF help_module = NIL THEN
      RETURN;
    IFEND;

    clp$extract_msg_module_contents (local_help_module, header, ignore_condition_codes, names);
    IF header = NIL THEN
      osp$set_status_abnormal ('CL', cle$bad_help_module, '', status);
      RETURN;
    IFEND;

    clp$search_help_module (parameter_name, kind, names, local_help_module, prompt_template);

  PROCEND osp$find_param_assist_prompt;
?? TITLE := 'osp$find_parameter_help_message', EJECT ??
*copy osh$find_parameter_help_message

  PROCEDURE [XDCL, #GATE] osp$find_parameter_help_message
    (    help_module: ^ost$help_module;
         parameter_name: clt$parameter_name;
     VAR message_template: ^ost$message_template;
     VAR status: ost$status);

    VAR
      local_help_module: ^ost$help_module,
      ignore_condition_codes: ^ost$mtm_condition_codes,
      names: ^ost$mtm_condition_names,
      header: ^ost$mtm_header,
      kind: ost$message_template_kind;


    status.normal := TRUE;
    local_help_module := help_module;
    message_template := NIL;
    ignore_condition_codes := NIL;
    names := NIL;
    kind := osc$parameter_help;

    IF help_module = NIL THEN
      RETURN;
    IFEND;

    clp$extract_msg_module_contents (local_help_module, header, ignore_condition_codes, names);
    IF header = NIL THEN
      osp$set_status_abnormal ('CL', cle$bad_help_module, '', status);
      RETURN;
    IFEND;

    clp$search_help_module (parameter_name, kind, names, local_help_module, message_template);

  PROCEND osp$find_parameter_help_message;
?? TITLE := 'osp$find_application_menu', EJECT ??
*copy osh$find_application_menu

  PROCEDURE [XDCL, #GATE] osp$find_application_menu
    (    help_module: ^ost$help_module;
         menu_name: ost$application_menu_name;
     VAR menu_classes: cst$menu_class;
     VAR menu_items: cst$menu_list;
     VAR status: ost$status);

    VAR
      local_help_module: ^ost$help_module,
      ignore_condition_codes: ^ost$mtm_condition_codes,
      names: ^ost$mtm_condition_names,
      entry_found: boolean,
      header: ^ost$mtm_header,
      index: ost$status_condition_code,
      lower: 0 .. osc$max_status_condition_code + 1,
      upper: -1 .. osc$max_status_condition_code + 1,
      upper_case_name: ost$name,
      kind: ost$message_template_kind,
      temp: integer,
      menu_header_ptr: ^ost$mtm_menu_header;


    status.normal := TRUE;
    local_help_module := help_module;
    menu_classes := NIL;
    menu_items := NIL;
    ignore_condition_codes := NIL;
    names := NIL;
    kind := osc$application_menu;
    entry_found := FALSE;

    IF local_help_module = NIL THEN
      RETURN;
    IFEND;

  /find_menu/
    BEGIN
      clp$extract_msg_module_contents (local_help_module, header, ignore_condition_codes, names);
      IF header = NIL THEN
        EXIT /find_menu/;
      IFEND;

      #TRANSLATE (osv$lower_to_upper, menu_name, upper_case_name);

      lower := 0;
      upper := UPPERBOUND (names^);

    /search_help_module/

      WHILE lower <= upper DO
        temp := lower + upper;
        index := temp DIV 2;
        IF names^ [index].name = upper_case_name THEN
          IF names^ [index].kind = kind THEN
            menu_header_ptr := #PTR (names^ [index].menu_header, local_help_module^);
            entry_found := TRUE;
            EXIT /search_help_module/;
          ELSEIF names^ [index].kind > kind THEN
            upper := index - 1;
          ELSE
            lower := index + 1;
          IFEND;
        ELSEIF names^ [index].name > upper_case_name THEN
          upper := index - 1;
        ELSE
          lower := index + 1;
        IFEND;
      WHILEND /search_help_module/;

      IF entry_found THEN
        RESET local_help_module TO menu_header_ptr;
        NEXT menu_header_ptr IN local_help_module;
        IF (menu_header_ptr = NIL) OR (menu_header_ptr^.number_of_classes < 0) OR
              (menu_header_ptr^.number_of_classes > csc$max_classes) OR
              (menu_header_ptr^.number_of_menu_items < 0) OR (menu_header_ptr^.number_of_menu_items >
              csc$max_menu_items) THEN
          EXIT /find_menu/;
        IFEND;
        NEXT menu_classes: [1 .. menu_header_ptr^.number_of_classes] IN local_help_module;
        IF menu_classes = NIL THEN
          EXIT /find_menu/;
        IFEND;
        NEXT menu_items: [1 .. menu_header_ptr^.number_of_menu_items] IN local_help_module;
        IF menu_classes = NIL THEN
          EXIT /find_menu/;
        IFEND;
      IFEND;
      RETURN;
    END /find_menu/;
    osp$set_status_abnormal ('CL', cle$bad_help_module, '', status);

  PROCEND osp$find_application_menu;
?? TITLE := 'osp$find_help_module_in_library', EJECT ??
*copy osh$find_help_module_in_library

  PROCEDURE [XDCL, #GATE] osp$find_help_module_in_library
    (    object_library: ^SEQ ( * );
         seed_name: pmt$program_name;
     VAR help_module: ^ost$help_module;
     VAR online_manual_name: ost$online_manual_name;
     VAR natural_language: ost$natural_language;
     VAR status: ost$status);

?? NEWTITLE := 'search_help_dictionary', EJECT ??

    PROCEDURE [INLINE] search_help_dictionary
      (    search_name: ost$name);

      VAR
        lower: 1 .. llc$max_help_modules_in_library + 1,
        upper: 0 .. llc$max_help_modules_in_library,
        member_header: ^llt$library_member_header,
        header: ^ost$mtm_header,
        temp: integer,
        index: llt$help_module_index,
        ignore_condition_codes: ^ost$mtm_condition_codes,
        ignore_condition_names: ^ost$mtm_condition_names;


      found := FALSE;

      IF help_module_dictionary = NIL THEN
        RETURN;
      IFEND;

      lower := 1;
      upper := UPPERBOUND (help_module_dictionary^);

      WHILE (lower <= upper) DO
        temp := lower + upper;
        index := temp DIV 2;
        IF help_module_dictionary^ [index].name = search_name THEN
          found := TRUE;
          member_header := #PTR (help_module_dictionary^ [index].help_header, object_library^);
          help_module := #PTR (member_header^.member, object_library^);
          RESET help_module;
          clp$extract_msg_module_contents (help_module, header, ignore_condition_codes,
                ignore_condition_names);
          natural_language := header^.language;
          online_manual_name := header^.online_manual_name;
          RETURN;
        ELSEIF help_module_dictionary^ [index].name > search_name THEN
          upper := index - 1;
        ELSE
          lower := index + 1;
        IFEND;
      WHILEND;

    PROCEND search_help_dictionary;
?? TITLE := 'search_message_dictionary', EJECT ??

    PROCEDURE [INLINE] search_message_dictionary
      (    search_name: ost$name);

      VAR
        lower: 1 .. llc$max_message_modules_in_lib + 1,
        upper: 0 .. llc$max_message_modules_in_lib,
        member_header: ^llt$library_member_header,
        header: ^ost$mtm_header,
        temp: integer,
        index: llt$message_module_index,
        ignore_condition_codes: ^ost$mtm_condition_codes,
        ignore_condition_names: ^ost$mtm_condition_names;


      found := FALSE;

      IF message_module_dictionary = NIL THEN
        RETURN;
      IFEND;

      lower := 1;
      upper := UPPERBOUND (message_module_dictionary^);

      WHILE (lower <= upper) DO
        temp := lower + upper;
        index := temp DIV 2;
        IF message_module_dictionary^ [index].name = search_name THEN
          found := TRUE;
          member_header := #PTR (message_module_dictionary^ [index].message_header, object_library^);
          help_module := #PTR (member_header^.member, object_library^);
          RESET help_module;
          clp$extract_msg_module_contents (help_module, header, ignore_condition_codes,
                ignore_condition_names);
          natural_language := header^.language;
          online_manual_name := header^.online_manual_name;
          RETURN;
        ELSEIF message_module_dictionary^ [index].name > search_name THEN
          upper := index - 1;
        ELSE
          lower := index + 1;
        IFEND;
      WHILEND;

    PROCEND search_message_dictionary;
?? TITLE := 'search_dictionaries', EJECT ??

    PROCEDURE [INLINE] search_dictionaries;

      VAR
        module_name: string (osc$max_string_size),
        module_name_length: integer,
        search_name: ost$name;


      STRINGREP (module_name, module_name_length, seed_name (1, clp$trimmed_string_size (seed_name)), '$',
            preferred_language (1, clp$trimmed_string_size (preferred_language)));

      #TRANSLATE (osv$lower_to_upper, module_name (1, module_name_length), search_name);

      search_help_dictionary (search_name);
      IF found THEN
        EXIT osp$find_help_module_in_library;
      IFEND;

      search_message_dictionary (search_name);
      IF found THEN
        EXIT osp$find_help_module_in_library;
      IFEND;

    PROCEND search_dictionaries;
?? OLDTITLE, EJECT ??

    VAR
      dictionaries: llt$library_dictionary_pointers,
      preferred_language: ost$natural_language,
      selected_language: ^ost$natural_language,
      found: boolean,
      message_module_dictionary: ^llt$message_module_dictionary,
      help_module_dictionary: ^llt$help_module_dictionary;


    status.normal := TRUE;
    help_module := NIL;
    found := FALSE;
    online_manual_name := osc$null_name;
    natural_language := osc$null_name;
    osp$find_natural_language (selected_language);
    preferred_language := selected_language^;

    pmp$get_library_dictionaries (object_library, dictionaries, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    help_module_dictionary := dictionaries.help_module_dictionary;
    message_module_dictionary := dictionaries.message_module_dictionary;

    search_dictionaries;
    IF preferred_language <> osc$default_natural_language THEN
      preferred_language := osc$default_natural_language;
      search_dictionaries;
    IFEND;

  PROCEND osp$find_help_module_in_library;
?? TITLE := 'osp$find_status_message_by_code', EJECT ??
*copy osh$find_status_message_by_code

  PROCEDURE [XDCL, #GATE] osp$find_status_message_by_code
    (    help_module: ^ost$help_module;
         condition_code: ost$status_condition_code;
     VAR condition_name: ost$status_condition_name;
     VAR condition_severity: ost$status_severity;
     VAR message_template: ^ost$message_template;
     VAR status: ost$status);

    VAR
      ignore_language: ost$natural_language,
      ignore_entry_found: boolean,
      message_module_severity: ost$message_module_severity,
      saved_default: boolean;


    status.normal := TRUE;
    saved_default := FALSE;
    condition_name := 'UNKNOWN_CONDITION';
    condition_severity := osc$error_status;
    message_template := NIL;

    IF help_module = NIL THEN
      RETURN;
    IFEND;

    clp$search_module_for_code (help_module, condition_code, ignore_language, condition_name,
          message_module_severity, message_template, ignore_entry_found, status);

    condition_severity := osp$convert_to_status_severity (message_module_severity);

  PROCEND osp$find_status_message_by_code;
?? TITLE := 'osp$find_status_message_by_name', EJECT ??
*copy osh$find_status_message_by_name

  PROCEDURE [XDCL, #GATE] osp$find_status_message_by_name
    (    help_module: ^ost$help_module;
         condition_name: ost$status_condition_name;
     VAR condition_code: ost$status_condition_code;
     VAR condition_severity: ost$status_severity;
     VAR message_template: ^ost$message_template;
     VAR status: ost$status);

    VAR
      ignore_language: ost$natural_language,
      ignore_entry_found: boolean,
      message_module_severity: ost$message_module_severity,
      saved_default: boolean;


    status.normal := TRUE;
    saved_default := FALSE;
    condition_code := 0;
    condition_severity := osc$error_status;
    message_template := NIL;

    IF help_module = NIL THEN
      RETURN;
    IFEND;

    clp$search_module_for_name (help_module, condition_name, ignore_language, condition_code,
          message_module_severity, message_template, ignore_entry_found, status);

    condition_severity := osp$convert_to_status_severity (message_module_severity);

  PROCEND osp$find_status_message_by_name;
?? TITLE := 'osp$get_full_help_message', EJECT ??
*copy osh$get_full_help_message

  PROCEDURE [XDCL, #GATE] osp$get_full_help_message
    (    seed_name: pmt$program_name;
         message_parameters: ^ost$message_parameters;
         max_message_line: ost$max_status_message_line;
     VAR message: ost$status_message;
     VAR status: ost$status);

    VAR
      help_module: ^ost$help_module,
      message_template: ^ost$message_template,
      natural_language: ost$natural_language,
      online_manual_name: ost$online_manual_name;

    osp$find_help_module (seed_name, help_module, online_manual_name, natural_language, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    osp$find_full_help_message (help_module, message_template, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    osp$format_help_message (message_template, message_parameters, max_message_line, message, status);

  PROCEND osp$get_full_help_message;
?? TITLE := 'osp$get_parameter_prompt', EJECT ??
*copy osh$get_parameter_prompt

  PROCEDURE [XDCL, #GATE] osp$get_parameter_prompt
    (    seed_name: pmt$program_name;
         parameter_name: clt$parameter_name;
         message_parameters: ^ost$message_parameters;
         max_message_line: ost$max_status_message_line;
     VAR message: ost$status_message;
     VAR status: ost$status);

    VAR
      help_module: ^ost$help_module,
      message_template: ^ost$message_template,
      natural_language: ost$natural_language,
      online_manual_name: ost$online_manual_name;

    osp$find_help_module (seed_name, help_module, online_manual_name, natural_language, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    osp$find_parameter_prompt (help_module, parameter_name, message_template, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    osp$format_help_message (message_template, message_parameters, max_message_line, message, status);

  PROCEND osp$get_parameter_prompt;
?? TITLE := 'osp$get_parameter_help_message', EJECT ??
*copy osh$get_parameter_help_message

  PROCEDURE [XDCL, #GATE] osp$get_parameter_help_message
    (    seed_name: pmt$program_name;
         parameter_name: clt$parameter_name;
         message_parameters: ^ost$message_parameters;
         max_message_line: ost$max_status_message_line;
     VAR message: ost$status_message;
     VAR status: ost$status);

    VAR
      help_module: ^ost$help_module,
      message_template: ^ost$message_template,
      natural_language: ost$natural_language,
      online_manual_name: ost$online_manual_name;

    osp$find_help_module (seed_name, help_module, online_manual_name, natural_language, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    osp$find_parameter_help_message (help_module, parameter_name, message_template, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    osp$format_help_message (message_template, message_parameters, max_message_line, message, status);

  PROCEND osp$get_parameter_help_message;
?? TITLE := 'clp$find_help_module', EJECT ??
*copy clh$find_help_module

  PROCEDURE [XDCL, #GATE] clp$find_help_module
    (    seed_name: pmt$program_name;
         natural_language: ost$natural_language;
     VAR help_module: ^ost$help_module;
     VAR online_manual_name: ost$online_manual_name;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      command_list: ^clt$command_list,
      current_entry: ^clt$command_list_entry,
      entry_found: boolean,
      i: integer,
      ignore_cmnd_list_found_in_task: boolean,
      ignore_natural_language: ost$natural_language,
      local_library_name: amt$local_file_name,
      module_name: string (2 * osc$max_name_size + 1),
      module_name_length: integer,
      preferred_language: ost$natural_language,
      search_name: ost$name,
      selected_language: ^ost$natural_language,
      valid_language: boolean;

?? TITLE := 'search_for_help_module', EJECT ??

    PROCEDURE [INLINE] search_for_help_module;

      VAR
        context: ^ost$ecp_exception_context;

      context := NIL;

      REPEAT
        clp$search_for_help_module (caller_id.ring, search_name, local_library_name, entry_found, help_module,
              ignore_natural_language, online_manual_name, status);
        IF osp$file_access_condition (status) THEN
          IF context = NIL THEN
            PUSH context;
            context^ := osv$initial_exception_context;
            context^.file.selector := osc$ecp_file_reference;
            context^.file.file_reference := ^local_library_name;
          IFEND;
          context^.condition_status := status;
          osp$enforce_exception_policies (context^);
          status := context^.condition_status;
        IFEND;
      UNTIL status.normal OR (NOT osp$file_access_condition (status)) OR (NOT context^.wait);

    PROCEND search_for_help_module;

    status.normal := TRUE;
    #CALLER_ID (caller_id);
    help_module := NIL;
    online_manual_name := osc$null_name;
    entry_found := FALSE;

    clp$validate_name (natural_language, preferred_language, valid_language);
    IF NOT valid_language THEN
      osp$set_status_abnormal ('CL', ose$bad_natural_language, natural_language, status);
      RETURN;
    IFEND;

  /search/
    BEGIN
      STRINGREP (module_name, module_name_length, seed_name (1, clp$trimmed_string_size (seed_name)), '$',
            preferred_language (1, clp$trimmed_string_size (preferred_language)));

      #TRANSLATE (osv$lower_to_upper, module_name (1, module_name_length), search_name);

      clp$find_command_list (command_list, ignore_cmnd_list_found_in_task);
      current_entry := command_list^.entries.first_entry;

      WHILE current_entry <> NIL DO
        CASE current_entry^.kind OF

        = clc$library_commands =
          IF current_entry^.library_contains.help_modules AND NOT current_entry^.unaccessible_entry THEN
            local_library_name := current_entry^.local_file_name;
            search_for_help_module;
            IF (NOT status.normal) OR entry_found THEN
              EXIT /search/;
            IFEND;
          IFEND;

        = clc$system_commands =
          IF (command_list^.system_command_library_lfn <> osc$null_name) AND
                command_list^.system_library_contains.help_modules THEN
            local_library_name := command_list^.system_command_library_lfn;
            search_for_help_module;
            IF (NOT status.normal) OR entry_found THEN
              EXIT /search/;
            IFEND;
          IFEND;

        = clc$sub_commands =
          IF current_entry^.utility_info^.auxiliary_libraries <> NIL THEN
            FOR i := 1 TO UPPERBOUND (current_entry^.utility_info^.auxiliary_libraries^) DO
              IF current_entry^.utility_info^.auxiliary_libraries^ [i].contains.help_modules THEN
                local_library_name := current_entry^.utility_info^.auxiliary_libraries^ [i].name;
                search_for_help_module;
                IF NOT status.normal THEN
                  status.normal := TRUE;
                ELSEIF entry_found THEN
                  EXIT /search/;
                IFEND;
              IFEND;
            FOREND;
          IFEND;

        ELSE
          ;
        CASEND;

        current_entry := current_entry^.next_entry;
      WHILEND;
    END /search/;

  PROCEND clp$find_help_module;

MODEND clm$help_message_interfaces;
