1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
# Definition of delimeters used in parsing words
define IS_DELIM (($1) <= ' ' || ($1) == ',')
define NOT_DELIM (($1) > ' ' && ($1) != ',')
.help
.nf_________________________________________________________________________
The procedures in this file perform simple processing on lists of
words. These procedures count the number of words in a list, fetch
the next word in a list, find the n-th word in a list, check for an
exact match between a word and a list of words. A word is any group
of contiguous characters which are neither whitespace or commas. The
definition of whitespace is anomalous, it includes any character whose
integer value is less than or equal to a blank. Note that words cannot
be delimeted by quotes and that escape processing is not done.
.endhelp____________________________________________________________________
#______________________________HISTORY______________________________________
#
# B.Simon 20-Apr-1990 Modified versions of CDBS routines adb_*tok.x
#
#___________________________________________________________________________
# WORD_COUNT -- Return the number of words in a list of words
int procedure word_count (list)
char list[ARB] # i: List of words
#--
char ch
int count, ic
begin
# The absolute value of count is the number of the current
# word of the list, count is negative if we are currently
# between words.
count = 0
# Loop over all characters in the list
for (ic = 1 ; list[ic] != EOS; ic = ic + 1) {
ch = list[ic]
if (count > 0) {
if (IS_DELIM(ch))
count = - count
} else if (NOT_DELIM(ch)) {
count = - count + 1
}
}
return (abs(count))
end
# WORD_FETCH -- Retrieve next word from string
int procedure word_fetch (str, ic, word, maxch)
char str[ARB] # i: String containing words
int ic # io: Index of starting character
char word[ARB] # o: Word string
int maxch # i: Declared length of output string
#--
char ch
int jc
begin
# Skip leading whitespace or commas. Don't go past string terminator.
for (ch = str[ic]; IS_DELIM(ch); ch = str[ic]) {
if (ch == EOS)
break
ic = ic + 1
}
# Copy characters to word. End when maxch is reached, or
# when commas, whitespace, or EOS is found
for (jc = 1; jc <= maxch; jc = jc + 1) {
if (IS_DELIM(ch))
break
word[jc] = ch
ic = ic + 1
ch = str[ic]
}
word[jc] = EOS
# If loop is terminated because of maxch, eat remaining characters
# in field
while (NOT_DELIM(ch)) {
ic = ic + 1
ch = str[ic]
}
# Return number of characters in word
return (jc - 1)
end
# WORD_FIND -- Find the i-th word in a list of words
int procedure word_find (index, list, word, maxch)
int index # i: Index to word within list
char list[ARB] # i: List of words
char word[ARB] # o: Word returned by this procedure
int maxch # i: Declared length of output string
#--
char ch
int count, ic, jc
begin
# The absolute value of count is the number of the current
# word of the list, count is negative if we are currently
# between words
count = 0
# Loop until i-th word is reached in list
for (ic = 1 ; count < index && list[ic] != EOS; ic = ic + 1) {
ch = list[ic]
if (count > 0) {
if (IS_DELIM(ch))
count = - count
} else if (NOT_DELIM(ch)) {
count = - count + 1
}
}
# If index is out of bounds, return zero
if (index < 0 || index > count)
return (0)
jc = 1
for (ic = ic - 1; NOT_DELIM(list[ic]); ic = ic + 1) {
if (jc > maxch)
break
word[jc] = list[ic]
jc = jc + 1
}
word[jc] = EOS
# Return number of characters in word
return (jc - 1)
end
# WORD_MATCH -- Return number of the word in the list which matches the word
int procedure word_match (word, list)
char word[ARB] # i: Word to be matched
char list[ARB] # i: List of words
#--
char ch
int match, inword, ic, jc
begin
# The absolute value of inword is the number of the current
# word of the list, inword is negative if we are currently
# between words in the list
jc = 1
match = 0
inword = 0
# Loop over all characters in the list
for (ic = 1 ; list[ic] != EOS; ic = ic + 1) {
ch = list[ic]
# First case: current character is within a word
if (inword > 0) {
# Check for conversion to second case
if (IS_DELIM(ch)) {
inword = - inword
# Simultaneous end of word in list and word
# means a match has been found
if (match != 0 && word[jc] == EOS)
break
else
match = 0
} else if (match != 0) {
# Check for match between list and word
if (ch == word[jc])
jc = jc + 1
else
match = 0
}
# Second case: current character is between words
# Check for conversion to first case
} else if (NOT_DELIM(ch)) {
jc = 1
ic = ic - 1
inword = - inword + 1
match = inword
}
}
# If list ended before word, there was no match
if (word[jc] != EOS)
match = 0
return (match)
end
|