05/17/86 find_char_ This subroutine uses the EIS test character and translate (TCT) instruction to perform the function of the PL/I search and verify builtin functions in a highly efficient manner. Search and verify operations can be performed from either the left or right end of the string. The search function looks for the first occurrence of any of a set of characters (the search characters) within an input character string. The verify function checks that all characters within an input string are also characters in a verify string. It searches in the input string for the first occurrence of a character not in the verify string. Notes: The TCT instruction uses a test-and-translate table to control the searching. Entrypoints are provided to build a table that can be used for several search or verify operations, or to build tables as part of each search or verify operation. The PL/I compiler generates efficient, in-line TCT or TCTR instructions when the second argument of the search or verify builtin function is a constant (so that the test-and-translate table can be constructed at compile time). However, when the second argument is a variable, PL/I uses a less efficient operator call to perform the search or verify operation. This operator tests each character of the first string to see if it appears in the second string. The rationale for PL/I operator is that, for short first arguments, it is more expensive to construct a test-and-translate table at run-time than to do the indexing. Programs which must search lengthy strings with a variable second argument can use find_char_ to avoid using the PL/I operator, thereby regaining the efficiency of the TCT instruction. The test-and-translate table is an aligned, fixed length character string, 512 characters long to cover all possible Multics 9-bit byte values. It consists of "\000" characters and characters which are not "\000". Searching (or verifying) using a test-and-translate table progresses as follows: 1) Examine the first (or next) character of the input string. If i is the index of the character being examined, then: input_char = substr(string, i, 1) 2) For each input_char, examine its corresponding table_char value: table_char = substr(table,rank(input_char)+1,1) 3) If table_char = "\000", then the test fails and the search continues with step 1. 4) If table_char ^= "\000", then the test succeeds and the search stops. The current value of i is returned as the index value. For the find_char_$translate_first_in_table and $translate_last_in_table entrypoints, table_char is also returned. 5) If the input string is exhausted before the test succeeds, then a value of 0 is returned as the index argument. For the find_char_$translate_first_in_table and $translate_last_in_table entrypoints, "\000" is returned as the table_char. Entry points in find_char_: (List is generated by the help command) :Entry: first_in_list: 05/16/86 find_char_$first_in_list Function: This entry performs the PL/I search function, returning the character index of the first (leftmost) occurrence of one of the search_chars in the input string. It constructs the test-and-translate table used by the TCT instruction from search_chars string provided by the caller. Syntax: declare find_char_$first_in_list entry (char(*), char(*)) returns (fixed bin(21)) reducible; index = find_char_$first_in_list (string, search_chars); Arguments: string is the character string to be searched. (In) search_chars are characters to be found in the string. (In) index is the result of the search. It is the PL/I string index (character position) of the first occurrence of one of the search_chars in the input string. 0 is returned if none of the search_chars appear in the input string. (Out) :Entry: last_in_list: 05/16/86 find_char_$last_in_list Function: This entry returns the character index (character position relative to the beginning of the string) of the last (rightmost) occurrence of one of the search_chars in the input string. It performs the PL/I function: index = length(string) - search (reverse(string), chars) + 1 [when char searched for is found in string] index = 0 [when char searched for is not found.] It constructs the test-and-translate table used by the TCT instruction from search_chars string provided by the caller. Syntax: declare find_char_$last_in_list entry (char(*), char(*)) returns (fixed bin(21)) reducible; index = find_char_$last_in_list (string, search_chars); Arguments: string is the character string to be searched. (In) search_chars are characters to be found in the string. (In) index is the result of the search. It is the PL/I string index (character position) of the last (rightmost) occurrence of one of the search_chars in the input string. 0 is returned if none of the search_chars appear in the input string. (Out) :Entry: first_not_in_list: 05/16/86 find_char_$first_not_in_list Function: This entry performs the PL/I verify function, returning the character index of the first (leftmost) occurrence in the input string of a character which is not one of the verify_chars. It constructs the test-and-translate table from the verify_chars provided by the caller. Syntax: declare find_char_$first_not_in_list entry (char(*), char(*)) returns (fixed bin(21)) reducible; index = find_char_$first_not_in_list (string, verify_chars); Arguments: string is the character string to be searched. (In) verify_chars are characters which are skipped over when searching the string. (In) index is the result of the verify. It is the PL/I string index (character position) of the first (leftmost) occurrence of a character in the input string which is not one of the verify_chars. 0 is returned if the entire input string contains only the characters in verify_chars. (Out) :Entry: last_not_in_list: 05/16/86 find_char_$last_not_in_list Function: This entry returns the index (character position relative to the beginning of the string) of the last (rightmost) occurrence of a character in the input string which is not one of the verify_chars. It performs the PL/I function: index = length(string) - verify (reverse(string), chars) + 1; [when character not in chars is found in string] index = 0; [when character not in chars is not found in string.] It constructs the test-and-translate table from the verify_chars provided by the caller. Syntax: declare find_char_$last_not_in_list entry (char(*), char(*)) returns (fixed bin(21)) reducible; index = find_char_$last_not_in_list (string, verify_chars); Arguments: string is the character string to be searched. (In) verify_chars are characters to be skipped over when searching the string. (In) index is the result of the verify. It is the PL/I string index (character position) of the last (rightmost) occurrence of a character in the input string which is not one of the verify_chars. 0 is returned if the entire input string contains only the characters in verify_chars. (Out) :Entry: first_in_table: 05/16/86 find_char_$first_in_table Function: This entry point searches an input string from the left, using a user-defined test-and-translate table. Either a search or a verify operation can be performed, depending upon the contents of the table. find_char_$make_table_from_chars_in_list can be used to construct a search_table from a set of search_chars; find_char_$make_table_from_chars_not_in_list can be used to construct a verify_table from a set of verify_chars; or the user can create a table containing his own values. As described in the Notes, searching continues until an input string character corresponds to a nonzero element of the table. The character index of the input string character is returned. Syntax: declare find_char_$first_in_table entry (char(*), char(512) aligned) returns (fixed bin(21)) reducible; index = find_char_$first_in_table (string, table); Arguments: string is the character string to be searched. (In) table is the test-and-translate table. (In) index is the result of the search. It is a PL/I string index (character position) of the first (leftmost) input character corresponding to a nonzero table element. 0 is returned if no input characters correspond to a nonzero table element. (Out) :Entry: last_in_table: 05/16/86 find_char_$last_in_table Function: This entry point searches an input string from the right, using a user-defined test-and-translate table. Either a search or a verify operation can be performed, depending upon the contents of the table. find_char_$make_table_from_chars_in_list can be used to construct a search_table from a set of search_chars; find_char_$make_table_from_chars_not_in_list can be used to construct a verify_table from a set of verify_chars; or the user can create a table containing his own values. As described in the Notes, searching continues until an input string character corresponds to a nonzero element of the table. The character index of the input string character is returned. Syntax: declare find_char_$last_in_table entry (char(*), char(512) aligned) returns (fixed bin(21)) reducible; index = find_char_$last_in_table (string, table); Arguments: string is the character string to be searched. (In) table is the test-and-translate table. (In) index is the result of the search. It is a PL/I string index (character position) of the last (rightmost) input character corresponding to a nonzero table element. 0 is returned if no input characters correspond to a nonzero table element. (Out) :Entry: translate_first_in_table: 05/16/86 find_char_$translate_first_in_table Function: This entry point searches an input string from the left, using a user-defined test-and-translate table. Either a search or a verify operation can be performed, depending upon the contents of the table. As described in the Notes, searching continues until an input string character corresponds to a nonzero element of the table. The character index of the input string character is returned, along with the nonzero table element. Syntax: declare find_char_$translate_first_in_table entry (char(*), char(512) aligned, fixed bin(21)) returns (char(1)); table_element = find_char_$translate_first_in_table (string, table, index); Arguments: string is the character string to be searched. (In) table is the test-and-translate table. (In) index is the result of the search. It is a PL/I string index (character position) of the first (leftmost) input character corresponding to a nonzero table element. 0 is returned if no input characters correspond to a nonzero table element. (Out) table_element is the character from the test-and-translate table which corresponds to the input string character selected by index. "\000" is returned when index=0. (Out) :Entry: translate_last_in_table: 05/16/86 find_char_$translate_last_in_table Function: This entry point searches an input string from the right, using a user-defined test-and-translate table. Either a search or a verify operation can be performed, depending upon the contents of the table. As described in the Notes, searching continues until an input string character corresponds to a nonzero element of the table. The character index of the input string character is returned, along with the nonzero table element. Syntax: declare find_char_$translate_last_in_table entry (char(*), char(512) aligned, fixed bin(21)) returns (char(1)); table_element = find_char_$translate_last_in_table (string, table, index); Arguments: string is the character string to be searched. (In) table is the test-and-translate table. (In) index is the result of the search. It is a PL/I string index (character position) of the last (rightmost) input character corresponding to a nonzero table element. 0 is returned if no input characters correspond to a nonzero table element. (Out) table_element is the character from the test-and-translate table which corresponds to the input string character selected by index. "\000" is returned when index=0. (Out) :Entry: make_table_of_chars_in_list: 05/16/86 find_char_$make_table_of_chars_in_list Function: This entry constructs a test-and-translate table for use with the find_char_$first_in_table and find_char_$last_in_table entrypoints. Table entries corresponding to characters of search_chars are marked with \777 in the search table. Other table entries are filled with \000. Syntax: declare find_char_$make_table_of_chars_in_list entry (char(*), char(512) aligned); call find_char_$make_table_of_chars_in_list (search_chars, search_table); Arguments: search_chars is a string of characters whose corresponding entries are to be marked in the resulting translate table. (In) search_table is the test-and-translate table. (Out) :Entry: make_table_of_chars_not_in_list: 05/16/86 find_char_$make_table_of_chars_not_in_list Function: This entry constructs a test-and-translate table for use with the find_char_$first_in_table and find_char_$last_in_table entrypoints. Table entries corresponding to characters of verify_chars remain unmarked (\000 elements) in the table. Other table elements are filled with \777. Syntax: declare find_char_$make_table_of_chars_not_in_list entry (char(*), char(512) aligned); call find_char_$make_table_of_chars_not_in_list (verify_chars, verify_table); Arguments: verify_chars is a string of characters whose corresponding entries are to remain unmarked in the resulting translate table. (In) verify_table is the test-and-translate table. (Out) :Entry: not_ascii_table: 05/16/86 find_char_$not_ascii_table Function: This entrypoint is an external variable containing a predefined test-and-translate table which can be used to detect any non-ASCII characters in a character string. Non-ASCII characters are those in which one or both of the 2 leftmost bits of the 9-bit character byte are "1"b (i.e., character > "\177"). The first 128 values in the table are "\000". The next 384 table characters are set to their character offset within the table. This means that: substr(table,n+1,1) = "\000", for n: 000 <= n <= 127 substr(table,n+1,1) = "\n", for n: 128 <= n <= 511 Syntax: declare find_char_$not_ascii_table char(512) aligned external static; ----------------------------------------------------------- Historical Background This edition of the Multics software materials and documentation is provided and donated to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. as a contribution to computer science knowledge. This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL and BULL HN Information Systems Inc. to the development of this operating system. Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture for managing computer hardware properly and for executing programs. Many subsequent operating systems incorporated Multics principles. Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . ----------------------------------------------------------- Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without fee is hereby granted,provided that the below copyright notice and historical background appear in all copies and that both the copyright notice and historical background and this permission notice appear in supporting documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining to distribution of the programs without specific prior written permission. Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. Copyright 2006 by BULL HN Information Systems Inc. Copyright 2006 by Bull SAS All Rights Reserved