goer@ellis.uchicago.edu (Richard L. Goerwitz) (03/20/91)
Here's what I finally settled on. Thanks, everyone.
-Richard
############################################################################
#
# Name: longstr.icn
#
# Title: match longest string in a list or set of strings
#
# Author: Jerry Nowlin, Steve Wampler, and Richard Goerwitz
#
# Version: 1.1
#
############################################################################
#
# Anystr(l,s,i,j) works like any(), except that instead of taking a
# cset as its first argument, it takes instead a list or set of
# strings (l). Returns i + *x, where x is the longest string in l
# for which match(x,s,i,j) succeeds. Fails if no match occurs.
#
# Defaults:
# s &subject
# i &pos if s is defaulted, otherwise 1
# j 0
#
# Errors:
# The only manual error-checking that is done is to test l to
# be sure it is, in fact, a list or set. Errors such as non-
# string members in l, and non-integer i/j parameters, are
# caught by the normal Icon built-in string processing and sub-
# scripting mechanisms.
#
############################################################################
#
# Links: none
#
############################################################################
procedure longstr(l,s,i,j)
local m
#
# Is l a list or set?
#
type(l) == ("list"|"set") |
stop("longstr: list or set expected (arg 1)")
#
# Set up s and i variables just as in built-in string-handling
# functions.
#
if /s := &subject then {
if \i then {
if i < 1 then
i := *s + (i+1)
}
else i := &pos
}
else i := 1
#
# Set up j.
#
if \j then {
if j < 1 then
j := *s + (j+1)
}
else j := *s+1
#
# Find longest match()-ing string in l. Initialize m to -1 so
# as to detect cases where "" is the only match that succeeds.
#
m := -1 # Attempt to match() each member in l (=!l).
while m <:= *(s[i:j] ? =!l) # Produce the length of each match that suc-
# ceeds, and store its value in m iff it is
# greater than m's current value.
#
# Return i + the length of the longest match. Fail if there was
# no match (i.e. m still has its original value).
#
return i + (-1 ~= m)
end