!++C! Build a pattern for pattern searching. Pattern characters are:! ! % single-character wildcard?! * multi-character wildcard, do not cross record boundaries9! ** multi-character wildcard, cross record boundaries! \* literal star! \% literal percent! \\ literal back-slash! \< Beginning of line! \> End of line3! \W whitespace (including up to one line-break)!F! And now many others, listed in the table below (in the package init)! N! LSI_BUILD_PATTERN takes a search string in INPUT_STRING and returns eitherK! a search string or a pattern string in RESULT_STRING. If RESULT_STRINGL! is a search string, LSI_BUILD_PATTERN returns the keyword STRING. If itG! is a pattern string, LSI_BUILD_PATTERN returns the keyword PATTERN.!-;procedure lsi_build_pattern ! Build a pattern for wildcard7 (input_string, result_string)!, leading_whitespace)local pattern_string, the_string, i, j, the_char, start_char, end_char, the_code, push_back, the_function, the_pattern, sub_pattern, is_double, temp, status, code_quote, code_close;!leading_whitespace := FALSE;4IF GET_INFO (LSI_X_WILD_FUNCTIONS, 'type') <> STRINGTHEN lsi_wildcard_module_init; TRUE := 1; FALSE := 0ENDIF; code_quote := lsi_wild_code (1); code_close := lsi_wild_code (8);pattern_string := "";the_string := "";i := 1;the_function := "";the_pattern := "";sub_pattern := "";!+.! Process each character in the input string!-loop if push_back > 1 then the_code := push_back; push_back := 0; else< the_code := lsi_get_wild_token (the_char, input_string, i); endif; exitif the_code < 0; case the_code from 0 TO 29 [0]: ! Ordinary character if the_char = "'" then) pattern_string := pattern_string + "'"; endif;1 pattern_string := pattern_string + the_char;) the_string := the_string + the_char; [1]: ! Escape (and quote)= message (fao ("Unrecognized wild-card function: !AS!AS", code_quote, the_char)); return FALSE; [2]: ! Star - Wildcard !+6 ! General wildcard, not crossing record boundaries ! ! Eat following * and % !-= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern; sub_pattern := "";9 is_double := lsi_eat_wild_code (2, input_string, i); !+* ! Use REMAIN if at end of input_string !-! if i > length (input_string) then) the_pattern := the_pattern + "& remain" else. if lsi_eat_wild_code (5, input_string, i) or, lsi_eat_wild_code (6, input_string, i) then, the_pattern := the_pattern + "& remain" else !+6 ! Use the MATCH built-in. We will accumulate8 ! MATCH characters until another special marker ! is encountered. !- if is_double then the_function := "matchl"; else the_function := "match"; endif; endif; endif; [3]: ! Percent -- arb !+ ! Single-character wildcard. !& ! Start by counting consecutive %s !-= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern; j := 1; loop4 exitif not lsi_eat_wild_code (3, input_string, i); j := j + 1; endloop; !+ ! Put it in the pattern !-- sub_pattern := "& arb(" + str (j) + ")"; [4]: ! Space= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern; leading_whitespace := TRUE;% sub_pattern := "& lsi_x_ws_pat"; loop4 exitif not lsi_eat_wild_code (4, input_string, i); endloop; [5]: ! \< Beginning of line= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern;# sub_pattern := "& line_begin"; [6]: ! \> End of line= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern;! sub_pattern := "& line_end"; [7]: ! \[ Start of any= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern; sub_pattern := ""; the_function := "any";/ if lsi_eat_wild_code (29, input_string, i) then the_function := "notany"; endif; j := 0; loop# exitif i > length (input_string);0 exitif lsi_eat_wild_code (8, input_string, i);* the_char := substr (input_string, i, 1); i := i + 1; j := j + 1; if the_char = code_quote then. the_char := substr (input_string, i, 1); i := i + 1; endif;! if (the_char = "-") and (j > 1) then/ if lsi_eat_wild_code (8, input_string, i) then/ pattern_string := pattern_string + the_char; exitif 1; endif;- lsi_eat_wild_code (1, input_string, i);+ start_char := substr (pattern_string,# length (pattern_string), 1);2 pattern_string := substr (pattern_string, 1,( length (pattern_string) - 1);. end_char := substr (input_string, i, 1); i := i + 1; if end_char = code_quote then+ end_char := substr (input_string, i, 1); i := i + 1; endif;= start_char := index (lsi_x_all_characters, start_char);9 end_char := index (lsi_x_all_characters, end_char); if start_char < end_char then% pattern_string := pattern_string +$ substr (lsi_x_all_characters, start_char,% (end_char - start_char) + 1); else% pattern_string := pattern_string +$ substr (lsi_x_all_characters, end_char,% (start_char - end_char) + 1); endif; j := 0; else2 pattern_string := pattern_string + the_char; endif; endloop;= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, 8);+ if get_info (status, "type") = KEYWORD then return status; endif; [8]: ! \] close of any3 pattern_string := pattern_string + code_close;+ the_string := the_string + code_close;" [9]: ! \: Repeat (minimum of 1) if the_function = "" then if pattern_string <> "" then% temp := substr (pattern_string,$ length (pattern_string), 1);2 pattern_string := substr (pattern_string, 1,( length (pattern_string) - 1);> status := lsi_do_sub_pattern (sub_pattern, the_function,# pattern_string, the_code);, if get_info (status, "type") = KEYWORD then return status; endif;/ the_pattern := the_pattern + sub_pattern;. sub_pattern := "& span('" + temp + "')"; else, if substr (sub_pattern, 3, 4) = "any(" then. sub_pattern := substr (sub_pattern, 1, 2) + "span(" +" substr (sub_pattern, 7," length (sub_pattern)); else) if substr (sub_pattern, 3, 4) = "arb(" then push_back := 2; i := i - 1; else0 if substr (sub_pattern, 3, 7) = "notany(" then/ sub_pattern := substr (sub_pattern, 1, 2) + "scan(" +$ substr (sub_pattern, 10,# length (sub_pattern)); else. message ("Improper repeat pattern usage"); return FALSE; endif; endif; endif; endif; else if the_function = "match" then$ if length (pattern_string) > 1 then" temp := substr (pattern_string,! length (pattern_string), 1);/ pattern_string := substr (pattern_string, 1,% length (pattern_string) - 1);- status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);) if get_info (status, "type") = KEYWORD then return status; endif;, the_pattern := the_pattern + sub_pattern;+ sub_pattern := "& span('" + temp + "')"; else! if length (pattern_string) = 1 then& temp := substr (pattern_string,% length (pattern_string), 1);1 status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);- if get_info (status, "type") = KEYWORD then return status; endif;0 the_pattern := the_pattern + sub_pattern;6 sub_pattern := "& (span('" + temp + "') | '')"; else4 message ("Cannot repeat a wildcard pattern"); return FALSE; endif; endif; else3 message ("Cannot repeat a wildcard pattern"); return FALSE; endif; endif;# [10]: ! \. Repeat (minimum of 0) if the_function = "" then if pattern_string <> "" then% temp := substr (pattern_string,$ length (pattern_string), 1);2 pattern_string := substr (pattern_string, 1,( length (pattern_string) - 1);> status := lsi_do_sub_pattern (sub_pattern, the_function,# pattern_string, the_code);, if get_info (status, "type") = KEYWORD then return status; endif;/ the_pattern := the_pattern + sub_pattern;5 sub_pattern := "& (span('" + temp + "') | '')"; else, if substr (sub_pattern, 3, 4) = "any(" then. sub_pattern := substr (sub_pattern, 1, 2) + "(span(" +" substr (sub_pattern, 7,# length (sub_pattern)) + " | '')"; else) if substr (sub_pattern, 3, 4) = "arb(" then sub_pattern := ""; push_back := 2; i := i - 1; else0 if substr (sub_pattern, 3, 7) = "notany(" then/ sub_pattern := substr (sub_pattern, 1, 2) + "(scan(" +$ substr (sub_pattern, 10,$ length (sub_pattern)) + " | '')"; else1 message ("Cannot repeat a wildcard pattern"); return FALSE; endif; endif; endif; endif; else if the_function = "match" then$ if length (pattern_string) > 1 then" temp := substr (pattern_string,! length (pattern_string), 1);/ pattern_string := substr (pattern_string, 1,% length (pattern_string) - 1);- status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);) if get_info (status, "type") = KEYWORD then return status; endif;, the_pattern := the_pattern + sub_pattern;2 sub_pattern := "& (span('" + temp + "') | '')"; else! if length (pattern_string) = 1 then* the_function := "(" + the_function;1 status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);- if get_info (status, "type") = KEYWORD then return status; endif;0 sub_pattern := sub_pattern + "| remain)"; else4 message ("Cannot repeat a wildcard pattern"); return FALSE; endif; endif; else0 message ("Improper repeat pattern usage"); return FALSE; endif; endif; [11]: ! \d Decimal digit= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern;* sub_pattern := "& any('1234567890')"; [12]: ! \o Octal digit= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern;( sub_pattern := "& any('01234567')"; [13]: ! \x Hex digit= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern;6 sub_pattern := "& any('1234567890abcdefABCDEF')"; [14]: ! \a Alphabetic char= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern;* sub_pattern := "& any(lsi_x_wild_a)"; [15]: ! \n Alphanumeric= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern;* sub_pattern := "& any(lsi_x_wild_n)";! [16]: ! \s Symbol constituent= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern;* sub_pattern := "& any(lsi_x_wild_s)"; [17]: ! \l Lower case letter= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern;* sub_pattern := "& any(lsi_X_WILD_L)"; [18]: ! \u Upper case letter= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern;* sub_pattern := "& any(lsi_X_WILD_U)"; [19]: ! \p Punctuation mark= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern;* sub_pattern := "& any(lsi_x_wild_p)";# [20]: ! \f Formatting character= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern;* sub_pattern := "& any(lsi_x_wild_f)"; [21]: ! \^ control= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern;0 sub_pattern := "& any(lsi_x_wild_control)";! [22]: ! \+ Characters 128-255= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern;. sub_pattern := "& any(lsi_x_wild_bit_7)";/ [26]: ! \| Previous pattern or next pattern= status := lsi_do_sub_pattern (sub_pattern, the_function, pattern_string, the_code);+ if get_info (status, "type") = KEYWORD then return status; endif;. the_pattern := the_pattern + sub_pattern; sub_pattern := "|"  [29]: ! ~ Not used in \[] 3 pattern_string := pattern_string + code_close;r+ the_string := the_string + code_close; [outrange]:E message (fao("Unrecognized wild-card function: !AS", the_char));% return FALSE; [inrange]:aF message (fao("Unimplimented wild-card function: !AS", the_char)); return FALSE; endcase;endloop;!+-! Empty out pattern_string into the_patternl!-8status := lsi_do_sub_pattern (sub_pattern, the_function,$ pattern_string, the_code);&if get_info (status, "type") = KEYWORDthen return status;endif;)the_pattern := the_pattern + sub_pattern;Usub_pattern := "";Athe_pattern := substr (the_pattern, 3, length (the_pattern) - 2);E!+.! Return either a string or a pattern string!--!message (fao ("Pattern: !AS", the_pattern)); !abort;r(if the_pattern <> "'" + the_string + "'"then! result_string := the_pattern;, return PATTERN;aelse result_string := the_string; return STRING;endif; endprocedure ! lsi_build_pattern _0procedure lsi_wildcard_module_init ! Module Init local temp;wwhitespace := ' ' + ASCII (9);=lsi_x_ws_pat := span (whitespace) | ((span (whitespace) | "")_ & line_end& & (span (whitespace) | ""));Clsi_x_wild_functions := "\*%\\\\]\\\\\\\\\\\\\\\\\\\\~";tClsi_x_wild_sub_functions := "\\\w<>[\:.doxanslupf^+?\\|\\\";_&! ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^A! 1 "\" Introducer ---------------+||||||||||||||||||||||||||||sA! 2 "*" Wildcard ------------------+||||||||||||||||||||||||||| A! 3 "%" ARB (place holder)----------+||||||||||||||||||||||||||;A! 4 "\w" Whitespace ------------------+||||||||||||||||||||||||| A! 5 "\<" BOL --------------------------+||||||||||||||||||||||||eA! 6 "\>" EOL ---------------------------+|||||||||||||||||||||||pA! 7 "\[" ANY (set of characters)---------+||||||||||||||||||||||eA! 8 "]" Close ANY -----------------------+|||||||||||||||||||||(A! 9 "\:" REPEAT (at least 1) --------------+||||||||||||||||||||eA! 10 "\." REPEAT (zero or more) -------------+||||||||||||||||||| A! 11 "\d" Decimal digit ----------------------+|||||||||||||||||| A! 12 "\o" Octal digit -------------------------+||||||||||||||||| A! 13 "\h" Hex digit ----------------------------+||||||||||||||||_A! 14 "\a" Alphabetic ----------------------------+||||||||||||||| A! 15 "\n" Alphanumeric ---------------------------+||||||||||||||uA! 16 "\s" Symbol constituent ----------------------+|||||||||||||dA! 17 "\l" Lower case letter ------------------------+||||||||||||nA! 18 "\u" Upper case letter -------------------------+||||||||||| A! 19 "\p" Punctuation character-----------------------+||||||||||wA! 20 "\f" Formatting character-------------------------+|||||||||_A! 21 "\^" Control (C0 or C1) character------------------+|||||||| A! 22 "\+" Any character with bit 7 set-------------------+|||||||uA! 23 "\?" Any character or BOL, EOL (BOF, & EOF)----------+|||||| A! 24 "\(" Open Parenthesis for grouping -------------------+|||||A! 25 "\)" Close Parentesis for grouping --------------------+||||"A! 26 "\|" Previous pattern or next pattern ------------------+|||A! 27 "\b" Bottom of file -------------------------------------+||tA! 28 "\t" Top of file -----------------------------------------+|tA! 29 "~" Not (used in \[...]) ---------------------------------+,lsi_x_wild_a := "abcdefghijklmnopqrstuvwxyz"! + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"d!%IF not eve$x_option_2byteh!%THEN$ + "àáâãäåæçèéêëìíîïñòóôõö÷øùúûüý"% + "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÑÒÓÔÕÖ×ØÙÚÛÜÝß",!%ENDIFr ;,lsi_x_wild_l := "abcdefghijklmnopqrstuvwxyz"!%IF not eve$x_option_2byte-!%THEN% + "àáâãäåæçèéêëìíîïñòóôõö÷øùúûüýß"!%ENDIF  ;,lsi_x_wild_u := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"!%IF not eve$x_option_2byte !%THEN$ + "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÑÒÓÔÕÖ×ØÙÚÛÜÝ"!%ENDIFo ;,lsi_x_wild_s := "abcdefghijklmnopqrstuvwxyz"- + "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890$_";_,lsi_x_wild_n := "abcdefghijklmnopqrstuvwxyz"+ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";a4lsi_x_wild_p := " !""#$%&'()*+,-./0123456789:;<=>?@" + "[\]^_`{|}~" !%IF not eve$x_option_2byteg!%THEN + "¡¢£¥§¨©ª«°±²³µ¶·¹º»¼½¿"u!%ENDIF  ;4lsi_x_wild_f := ascii (8) + ascii (9) + ascii (10) +( ascii (11) + ascii (12) + ascii (13);lsi_x_all_characters := "";loop!%IF not eve$x_option_2byte !%THEN exitif temp > 255;!%ELSE!% exitif temp > 160;!%ENDIFe@ lsi_x_all_characters := lsi_x_all_characters + ascii (temp); temp := temp + 1;cendloop;<lsi_x_wild_control := substr (lsi_x_all_characters, 1, 32) +0 substr (lsi_x_all_characters, 129, 32);!%IF not eve$x_option_2bytee!%THEN<lsi_x_wild_bit_7 := substr (lsi_x_all_characters, 129, 128);!%ENDIF](endprocedure ! lsi_wildcard_module_init u=procedure lsi_wild_code (the_code) ! INT => wildcard function local temp;e3temp := substr (lsi_x_wild_functions, the_code, 1);tif the_code <> 1then1 if temp = substr (lsi_x_wild_functions, 1, 1)u then? temp := temp + substr (lsi_x_wild_sub_functions, the_code, 1); endif;endif;/if temp = substr (lsi_x_wild_functions, 1, 1) + ' substr (lsi_x_wild_functions, 1, 1) then temp := "";lendif;!MESSAGE (temp);return (temp);endprocedure ! lsi_wild_code;_ r;procedure lsi_get_wild_token ! Get the next wildcard token1 (the_char, input_string, i) local the_code,: lower_char;if i > length (input_string)then return - 1;helse, the_char := substr (input_string, i, 1); if the_char <> "'" then lower_char := the_char;! change_case (lower_char, LOWER);6 the_code := index (lsi_x_wild_functions, lower_char); if the_code = 1 ! Saw "\"_ then  i := i + 1;- the_char := substr (input_string, i, 1);  lower_char := the_char;% change_case (lower_char, LOWER);p> the_code := index (lsi_x_wild_sub_functions, lower_char);* if the_code = 0 ! Not \<, \> or \\ thene7 the_code := index (lsi_x_wild_functions, lower_char);% if the_code = 0 ! Not \*, \%, etc  then the_code := 1; else ! Saw \*, \%, etc  the_code := 0; endif; else, if the_code = 1 ! Saw \\ then the_code := 0; endif; endif;e endif; endif; i := i + 1;c return (the_code);endif;$endprocedure ! lsi_get_wild_token; 7procedure lsi_eat_wild_code ! Test for a specific codes (the_code, input_string, i) local the_length, the_string;'the_string := lsi_wild_code (the_code);0"the_length := length (the_string);4if substr (input_string, i, the_length) = the_stringthen i := i + the_length; return TRUE;else return FALSE;tendif; endprocedure; ?procedure lsi_do_sub_pattern ! Collect the current sub-patterns5 (sub_pattern, the_function, the_string, the_code) if the_function <> ""nthen if the_string <> ""e then= if the_function = "&matchl" !*** Proposed, but unimplimented then + sub_pattern := local_sub_patt + "& " +s( "(unanchor+'" + the_string + "')"; elser( sub_pattern := sub_pattern + "& " +. the_function + "('" + the_string + "')"; endif;, the_string := ""; else D message (FAO ("No text preceding: !AS", lsi_wild_code (the_code))); return FALSE; endif; the_function := "";gelse if the_string <> ""O then7 sub_pattern := sub_pattern + "& '" + the_string + "'";r the_string := ""; endif;endif; endprocedure;" p&procedure lsi_search (the_pattern_str)LOCAL save_range,  found_range, search_str,e pattern_str, result;ON_ERROR IF ERROR = TPU$_EXECUTEFAIL THEN % MESSAGE ('Bad pattern string'); ABORT ENDIF;( ENDON_ERROR;!++"?! Check the input argument to ensure that a string was passed.e!--/IF GET_INFO (the_pattern_str, 'type') <> STRINGTHEN !++' ! No string, so prompt for a value., !--/ search_str := READ_LINE ('_Enter pattern: ')aELSE !++" ! Use the passed string value. !-- search_str := the_pattern_strENDIF;!++g%! Was last key pressed the HELP key?!--e(IF (LAST_KEY = HELP) OR (LAST_KEY = PF2)THEN; lse$do_command("HELP/LIBR=UTL_:[TPU]HELPLIB WILDCARDS");r RETURN ENDIF;!++tH! Check for null search string and use last search pattern, if defined.!--sIF search_str = ''THEN> IF GET_INFO (lsi_last_search_pattern, 'type') = UNSPECIFIED THENu2 MESSAGE ('No last search pattern defined.'); ABORT  ENDIFELSE !++! ! Build a new search pattern.( !--8 result := lsi_build_pattern(search_str, pattern_str); IF result = FALSE THEN_ ABORT_ ENDIF; # lsi_last_search_pattern := ('');'- lsi_last_search_pattern_str := search_str;  IF result = STRINGt THENb, pattern_str := '"' + pattern_str + '"' ENDIF;)8! MESSAGE ('lsi_last_search_pattern:=' + pattern_str);6 EXECUTE ('lsi_last_search_pattern:=' + pattern_str)ENDIF;!++e.! Hold this place before starting the search.!-- save_range := MARK (NONE);IF CURRENT_DIRECTION = FORWARDTHEN MOVE_HORIZONTAL (1);aELSE MOVE_HORIZONTAL (-1);ENDIF;!++e5! Look for the next occurence of the search pattern.e!--wfound_range := 0;Bfound_range := SEARCH (lsi_last_search_pattern, CURRENT_DIRECTION, EXACT);IF found_range = 0THEN9 MESSAGE (lsi_last_search_pattern_str + ' not found.');! POSITION (save_range)ELSE POSITION (found_range);ENDIFENDPROCEDURE ! lsi_search