############################################################################ # # File: scanset.icn # # Subject: Procedures setup for string scanning procedures # # Author: Robert J. Alexander # # Date: June 4, 1993 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # Procedure to set up for user-written string-scanning procedures that # are in the spirit of Icon's built-ins. # # The values passed are the s, i1, i2 parameters which are the last # three arguments to all Icon scanning functions (such as # upto(c,s,i1,i2)). scan_setup() supplies any appropriate defaults and # returns needed values. # # The value returned is a "scan_setup_result" record consisting of two # values: # # 1. The substring of s to be scanned (ss). # 2. The size of the substring of s that precedes the # substring to be scanned (offset). # # scan_setup() fails if i1 or i2 is out of range with respect to s. # # The user-written procedure can then match in the string ss to compute # the position within ss appropriate to the scan (p). The value # returned (or suspended) to the caller is p + offset (the position # within the original string, s). # # For example, the following function finds two words separated by # spaces: # # procedure two_words(s,i1,i2) # local x,p # x := scan_setup(s,i1,i2) | fail # fail if out of range # x.ss ? suspend { # tab(upto(&letters)) & # pos(1) | (move(-1) & tab(any(~&letters))) & # p := &pos & # remember starting position # tab(many(&letters)) & # tab(many(' ')) & # tab(many(&letters)) & # p + x.offset # return position in original s # } # end # record scan_setup_result( ss, # substring to be scanned offset) # length of substring preceding ss procedure scan_setup(s,i1,i2) if /s := &subject then /i1 := &pos else /i1 := 1 /i2 := 0 return scan_setup_result(s[i1:i2],match("",s,i1,i2) - 1) end