1: #!/usr/bin/env rexx
2: /**
3: * A stringTable subclass that will support indexes of one word
4: * strings in any case (lower- upper- or mixed-case) and treat
5: * them as being the same when processing.
6: * ----------------------------------------------------------------
7: * Originally by Ruurd J. Idenburg
8: *
9: * No copyright, no licence, no guarantees or warrantees, be it
10: * explicit, implicit or whatever. Usage is totally and completely
11: * at the users own risk, the author shall not be liable for any
12: * damages whatsoever, for any reason whatsoever.
13: *
14: * Please keep this comment block intact when modifying this code
15: * and add a note with date and a description.
16: * ----------------------------------------------------------------
17: * 2023/02/08 - Initial version requires ooRexx version 5.0.0 or
18: * later
19: * 2023/04/02 - Added catering for multi-word indexes by removing
20: * the spaces between words when processing them (rji)
21: * 2023/05/04 - Added a (perhaps) more common example (rji)
22: * 2023/05/05 - Removed unneccesary exit statements in method
23: * definitions (rji)
24: *
25: */----------------------------------------------------------------
26:
27: -- A simple sample
28: cst = .caselessStringTable~new
29: say "HELLO =>" cst~hello
30: cst["Blonde On Blonde"] = "An album by Bob Dylan"
31: cst~blonde = "My Hair"
32: --say cst~allIndexes
33: say "blond On Blonde => "cst["blonde On blonde"]
34: say "Blonde =>" cst["Blonde"]
35: say "Real indexes =>" cst~makeArray~toString(,", ")
36: say "Index BLONDE ONBLONDE =>" cst~hasIndex("BLONDE ONBLONDE")
37: say "Removing bLoNdE =>" cst~remove("bLoNdE")
38: say "-"~copies(40)
39: -- A more common (perhaps) sample
40: memberList = .routines~createMemberList~call
41: say "Actual indexes:" memberList[0]~allIndexes~sort~toString(,", ")
42: say "Used indexes..: ~first, ~last, ~middle"
43: say "-"~copies(40)
44: do m over memberList
45: if m~middle==.nil
46: then say m~last"," m~first"," "middle name to be done"
47: else say m~last"," m~first"," m~middle
48: end
49: say "-"~copies(40)
50:
51: /**
52: * Do not execute above code when invoked via a "::requires" directive
53: */
54: ::options noprolog
55:
56: /**
57: * All indexes are maintained in the .caselessStringTable superclass
58: * (i.e the .stringTable class). All methods with an index as argument
59: * are first checked for a caseless match before being forwarded to
60: * the superclass .stringTable methods.
61: */
62: ::class "caselessStringTable" public subclass "stringTable"
63:
64: /**
65: * Just let the superclass initiate the instance
66: */
67: ::method "init"
68: self~init:super
69: exit
70:
71: /**
72: * Will check if there is already an index exactly the same in mixed-
73: * or lower- or upper-case and return the matched index, otherwise
74: * will return the index given as the parameter.
75: */
76: ::method "caselessIndex" private
77: use strict arg key
78: /**
79: * Make sure the index will be one word only
80: */
81: key = key~space(0)
82: tmpString = self~makeArray~toString(," ")
83: wp = tmpString~caselessWordPos(key)
84: if wp=0
85: then tableIndex = key
86: else tableIndex = tmpString~word(wp)
87: return tableIndex
88:
89: /**
90: * This is the same as method "at", so let the"at' method handle it
91: */
92: ::method "[]"
93: forward to (self) message ("at")
94: exit
95:
96: /**
97: * This the same method as "put", so let the "put' method handle it
98: */
99: ::method "[]="
100: forward to (self) message ("put")
101: exit
102:
103: /**
104: * Same as the super class, but with the caseless match
105: * for it's indexes.
106: */
107: ::method "at"
108: use strict arg key
109: index = self~caselessIndex(key)
110: return self~at:super(index)
111:
112: /**
113: * Same as the super class, but with the caseless match
114: * for it's indexes.
115: */
116: ::method "hasIndex"
117: use strict arg key
118: index = self~caselessIndex(key)
119: return self~hasIndex:super(index)
120:
121: /**
122: * Same as the super class, but with the caseless for it's
123: * indexes.If a caseless match exists the item value will be
124: * updated. If no match is found the index will be as provided.
125: */
126: ::method "put"
127: use strict arg value, key
128: index = self~caselessIndex(key)
129: self~put:super(value, index)
130: exit
131:
132: /**
133: * Same as the super class, but with the caseless match
134: */
135: ::method "remove"
136: use strict arg key
137: index = self~caselessIndex(key)
138: return self~remove:super(index)
139:
140: /**
141: * The "unknown" method allows processing as for an ooRexx standard
142: * .stringTable, like myCaselessStringtable~firstName="Mike"
143: */
144: ::method "unknown"
145: use arg key, args
146: index = self~caselessIndex(key~strip('T','='))
147: if key~endsWith("=")
148: then self~put:super(args[1],index)
149: else return self~at:super(index)
150: exit
151:
152: /**
153: * Following are the methods to support the .stringTable "ENTRY" methods.
154: * I have not tested these.
155: */
156: ::method "setEntry"
157: use strict arg key, value=.nil
158: index = self~caselessIndex(key)
159: self~setEntry:super(index, value)
160: exit
161:
162: ::method "entry"
163: use strict arg key
164: index = self~caselessIndex(key)
165: return self~entry:super(index)
166:
167: ::method "hasEntry"
168: use strict arg key
169: index = self~caselessIndex(key)
170: return self~hasEntry:super(index)
171: exit
172:
173: ::method "removeEntry"
174: use strict arg key
175: index = self~caselessIndex(key)
176: return self~removeEntry:super(index)
177:
178: ::routine createMemberList
179: members = (("Zimmerman", "Robert", "Allen"),("Zappa","Frank",),("Cale","J.J.",),("Clapton","Eric","Patrick"))
180: memberList = .list~new
181: do m over members
182: member = .caselessStringTable~new
183: member["Last"] = m[1]
184: member~first = m[2]
185: member["middle"] = m[3]
186: memberList~append(member)
187: end
188: return memberList
189:
190: