/* Copyright (c) 1995 by R. A. Vowels, from "Introduction to PL/I, Algorithms, and */ /* Structured Programming". Permission is given to reproduce and to use these procedures */ /* as part of a program, and to include them as part of a larger work to be sold for profit. */ /* However, the user is not permitted to sell the procedures separately. Provided always */ /* that these procedures and this copyright notice are reproduced in full. */ /* Revised 2 February 2000. */ DECLARE INDEX3 GENERIC (INDEX_sub_bit WHEN ( BIT, BIT, *), INDEX_sub_graphic WHEN ( GRAPHIC, GRAPHIC, *), INDEX_sub_graphic_1 WHEN ( GRAPHIC, *, *), INDEX_sub_graphic_2 WHEN (*, GRAPHIC, *), INDEX_sub_char_varying WHEN (VARYING, *, *), INDEX_sub_char WHEN (*,*,*) ); /* This function searches the first string STRING, to ascertain whether the second string */ /* SUB exists within it. If it does, the function returns the position of the left-most */ /* character that matches. The search commences from character position Position in STRING. */ INDEX_sub_char: PROCEDURE (STRING, SUB, POSITION) OPTIONS (REORDER) RETURNS (FIXED BINARY (31) ); /* INCOMING: STRING = the string to be searched; */ /* SUB = contains the string to look for; */ /* POSITION = where to start the search (measured from the left-hand end of */ /* STRING). */ DECLARE (STRING, SUB) CHARACTER (*); DECLARE POSITION FIXED BINARY (31); DECLARE (LENGTH, SUBSTR, INDEX) BUILTIN; DECLARE K FIXED BINARY (31); IF (Position > LENGTH(String)+1) | (Position <= 0) THEN DO; SIGNAL STRINGRANGE; RETURN (0); END; IF LENGTH (STRING) = 0 THEN /* There's nothing to search. */ RETURN (0); IF LENGTH (SUB) = 0 THEN /* Nothing with which to search. */ RETURN (0); K = INDEX (SUBSTR (STRING, POSITION), SUB); /* Start the search from position POSITION. */ IF K = 0 THEN RETURN (0); RETURN (POSITION + K - 1); END INDEX_sub_char; /* This function searches the first string STRING, to ascertain whether the second string */ /* SUB exists within it. If it does, the function returns the position of the left-most */ /* character that matches. The search commences from character position Position in STRING. */ INDEX_sub_char_varying: PROCEDURE (STRING, SUB, POSITION) OPTIONS (REORDER) RETURNS (FIXED BINARY (31) ); /* INCOMING: STRING = the string to be searched; */ /* SUB = contains the string to look for; */ /* POSITION = where to start the search (measured from the left-hand end of */ /* STRING). */ DECLARE STRING CHARACTER (*) VARYING, SUB CHARACTER (*); DECLARE POSITION FIXED BINARY (31); DECLARE (LENGTH, SUBSTR, INDEX) BUILTIN; DECLARE K FIXED BINARY (31); IF (Position > LENGTH(String)+1) | (Position <= 0) THEN DO; SIGNAL STRINGRANGE; RETURN (0); END; IF LENGTH (STRING) = 0 THEN /* There's nothing to search. */ RETURN (0); IF LENGTH (SUB) = 0 THEN /* Nothing with which to search. */ RETURN (0); K = INDEX (SUBSTR (STRING, POSITION), SUB); /* Start the search from position POSITION. */ IF K = 0 THEN RETURN (0); RETURN (POSITION + K - 1); END INDEX_sub_char_varying; /* This function searches the first string STRING, to ascertain whether the second string */ /* SUB exists within it. If it does, the function returns the position of the left-most */ /* character that matches. The search commences from graphic character position Position in */ /* STRING. */ INDEX_sub_graphic_1: PROCEDURE (STRING, SUB, POSITION) OPTIONS (REORDER) RETURNS (FIXED BINARY (31) ); /* INCOMING: STRING = the string to be searched; */ /* SUB = contains the string to look for; */ /* POSITION = where to start the search (measured from the left-hand end of */ /* STRING). */ DECLARE STRING GRAPHIC (*); DECLARE SUB CHARACTER (*); DECLARE POSITION FIXED BINARY (31); DECLARE (LENGTH, SUBSTR, INDEX) BUILTIN; DECLARE K FIXED BINARY (31); IF (Position > LENGTH(String)+1) | (Position <= 0) THEN DO; SIGNAL STRINGRANGE; RETURN (0); END; IF LENGTH (STRING) = 0 THEN /* There's nothing to search. */ RETURN (0); IF LENGTH (SUB) = 0 THEN /* Nothing with which to search. */ RETURN (0); K = INDEX (SUBSTR (STRING, POSITION), GRAPHIC(SUB)); /* Start the search from position POSITION. */ IF K = 0 THEN RETURN (0); RETURN (POSITION + K - 1); END INDEX_sub_graphic_1; /* This function searches the first string STRING, to ascertain whether the second string */ /* SUB exists within it. If it does, the function returns the position of the left-most */ /* character that matches. The search commences from graphic character position Position in */ /* STRING. */ INDEX_sub_graphic_2: PROCEDURE (STRING, SUB, POSITION) OPTIONS (REORDER) RETURNS (FIXED BINARY (31) ); /* INCOMING: STRING = the string to be searched; */ /* SUB = contains the string to look for; */ /* POSITION = where to start the search (measured from the left-hand end of */ /* STRING). */ DECLARE STRING CHARACTER (*); DECLARE SUB GRAPHIC (*); DECLARE POSITION FIXED BINARY (31); DECLARE (LENGTH, SUBSTR, INDEX) BUILTIN; DECLARE K FIXED BINARY (31); IF (Position > LENGTH(String)+1) | (Position <= 0) THEN DO; SIGNAL STRINGRANGE; RETURN (0); END; IF LENGTH (STRING) = 0 THEN /* There's nothing to search. */ RETURN (0); IF LENGTH (SUB) = 0 THEN /* Nothing with which to search. */ RETURN (0); K = INDEX (GRAPHIC(SUBSTR (STRING, POSITION)), SUB); /* Start the search from position POSITION. */ IF K = 0 THEN RETURN (0); RETURN (POSITION + K - 1); END INDEX_sub_graphic_2; /* This function searches the first string STRING, to ascertain whether the second string */ /* SUB exists within it. If it does, the function returns the position of the left-most */ /* character that matches. The search commences from graphic character position Position in */ /* STRING. */ INDEX_sub_graphic: PROCEDURE (STRING, SUB, POSITION) OPTIONS (REORDER) RETURNS (FIXED BINARY (31) ); /* INCOMING: STRING = the string to be searched; */ /* SUB = contains the string to look for; */ /* POSITION = where to start the search (measured from the left-hand end of */ /* STRING). */ DECLARE (STRING, SUB) GRAPHIC (*); DECLARE POSITION FIXED BINARY (31); DECLARE (LENGTH, SUBSTR, INDEX) BUILTIN; DECLARE K FIXED BINARY (31); IF (Position > LENGTH(String)+1) | (Position <= 0) THEN DO; SIGNAL STRINGRANGE; RETURN (0); END; IF LENGTH (STRING) = 0 THEN /* There's nothing to search. */ RETURN (0); IF LENGTH (SUB) = 0 THEN /* Nothing with which to search. */ RETURN (0); K = INDEX (SUBSTR (STRING, POSITION), SUB); /* Start the search from position POSITION. */ IF K = 0 THEN RETURN (0); RETURN (POSITION + K - 1); END INDEX_sub_graphic; /* This function searches the first bit string STRING, to ascertain whether the second bit */ /* string SUB exists within it. If it does, the function returns the position of the */ /* left-most bit that matches. The search commences from bit position Position in STRING. */ INDEX_sub_bit: PROCEDURE (STRING, SUB, POSITION) OPTIONS (REORDER) RETURNS (FIXED BINARY (31) ); /* INCOMING: STRING = the string to be searched; */ /* SUB = contains the string to look for; */ /* POSITION = where to start the search (measured from the left-hand end of */ /* STRING). */ DECLARE (STRING, SUB) BIT (*); DECLARE POSITION FIXED BINARY (31); DECLARE (LENGTH, SUBSTR, INDEX) BUILTIN; DECLARE K FIXED BINARY (31); IF (Position > LENGTH(String)+1) | (Position <= 0) THEN DO; SIGNAL STRINGRANGE; RETURN (0); END; IF LENGTH (STRING) = 0 THEN /* There's nothing to search. */ RETURN (0); IF LENGTH (SUB) = 0 THEN /* Nothing with which to search. */ RETURN (0); K = INDEX (SUBSTR (STRING, POSITION), SUB); /* Start the search from position POSITION. */ IF K = 0 THEN RETURN (0); RETURN (POSITION + K - 1); END INDEX_sub_bit;