/* 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;