1 | #include "madx.h" |
---|
2 | |
---|
3 | // private globals |
---|
4 | |
---|
5 | static char tmp_key[NAME_L]; |
---|
6 | |
---|
7 | // public interface |
---|
8 | |
---|
9 | void |
---|
10 | mystrcpy(struct char_array* target, char* source) |
---|
11 | { |
---|
12 | /* string copy to char_array with size adjustment */ |
---|
13 | int len = strlen(source); |
---|
14 | while (len > target->max) grow_char_array(target); |
---|
15 | strcpy(target->c, source); |
---|
16 | } |
---|
17 | |
---|
18 | void |
---|
19 | mycpy(char* out, const char* in) |
---|
20 | /* copies string, ends at any non-ascii character including 0 */ |
---|
21 | { |
---|
22 | int i; |
---|
23 | |
---|
24 | for (i=0; i<NAME_L-1 && in[i]>' ' && in[i]<='~'; i++) |
---|
25 | out[i] = in[i]; |
---|
26 | |
---|
27 | out[i] = '\0'; |
---|
28 | } |
---|
29 | |
---|
30 | char* |
---|
31 | mystrstr(char* string, char* s) |
---|
32 | /* returns strstr for s, but only outside strings included |
---|
33 | in single or double quotes */ |
---|
34 | { |
---|
35 | char quote = ' '; /* only for the compiler */ |
---|
36 | int toggle = 0, n = strlen(s); |
---|
37 | if (n == 0) return NULL; |
---|
38 | while (*string != '\0') |
---|
39 | { |
---|
40 | if (toggle) |
---|
41 | { |
---|
42 | if (*string == quote) toggle = 0; |
---|
43 | } |
---|
44 | else if(*string == '\'' || *string == '\"') |
---|
45 | { |
---|
46 | quote = *string; toggle = 1; |
---|
47 | } |
---|
48 | else if (strncmp(string, s, n) == 0) return string; |
---|
49 | string++; |
---|
50 | } |
---|
51 | return NULL; |
---|
52 | } |
---|
53 | |
---|
54 | void |
---|
55 | myrepl(char* in, char* out, char* string_in, char* string_out) |
---|
56 | /* replaces all occurrences of "in" in string_in by "out" |
---|
57 | in output string string_out */ |
---|
58 | { |
---|
59 | int n, add, l_in = strlen(in), l_out = strlen(out); |
---|
60 | char* cp; |
---|
61 | char tmp[8]; |
---|
62 | while ((cp = strstr(string_in, in)) != NULL) |
---|
63 | { |
---|
64 | while (string_in != cp) *string_out++ = *string_in++; |
---|
65 | string_in += l_in; |
---|
66 | if (*out == '$') |
---|
67 | { |
---|
68 | n = get_variable(&out[1]); |
---|
69 | sprintf(tmp,"%d", n); add = strlen(tmp); |
---|
70 | strncpy(string_out, tmp, add); |
---|
71 | string_out += add; |
---|
72 | } |
---|
73 | else |
---|
74 | { |
---|
75 | strncpy(string_out, out, l_out); |
---|
76 | string_out += l_out; |
---|
77 | } |
---|
78 | } |
---|
79 | strcpy(string_out, string_in); |
---|
80 | } |
---|
81 | |
---|
82 | char* |
---|
83 | mystrchr(char* string, char c) |
---|
84 | /* returns strchr for character c, but only outside strings included |
---|
85 | in single or double quotes */ |
---|
86 | { |
---|
87 | char quote = ' '; /* only for the compiler */ |
---|
88 | int toggle = 0; |
---|
89 | while (*string != '\0') |
---|
90 | { |
---|
91 | if (toggle) |
---|
92 | { |
---|
93 | if (*string == quote) toggle = 0; |
---|
94 | } |
---|
95 | else if(*string == '\'' || *string == '\"') |
---|
96 | { |
---|
97 | quote = *string; toggle = 1; |
---|
98 | } |
---|
99 | else if (*string == c) return string; |
---|
100 | string++; |
---|
101 | } |
---|
102 | return NULL; |
---|
103 | } |
---|
104 | |
---|
105 | int |
---|
106 | mysplit(char* buf, struct char_p_array* list) |
---|
107 | { |
---|
108 | /* splits into tokens */ |
---|
109 | int j; |
---|
110 | char* p; |
---|
111 | if ((p =strtok(buf, " \n")) == NULL) return 0; |
---|
112 | list->curr = 0; |
---|
113 | list->p[list->curr++] = p; |
---|
114 | while ((p = strtok(NULL, " \n")) != NULL) |
---|
115 | { |
---|
116 | if (list->curr == list->max) grow_char_p_array(list); |
---|
117 | list->p[list->curr++] = p; |
---|
118 | } |
---|
119 | /* remove '@' in strings */ |
---|
120 | for (j = 0; j < list->curr; j++) |
---|
121 | if(*list->p[j] == '\"' || *list->p[j] == '\'') /* quote */ |
---|
122 | replace(list->p[j], '@', ' '); |
---|
123 | |
---|
124 | return list->curr; |
---|
125 | } |
---|
126 | |
---|
127 | char* |
---|
128 | buffer(char* string) /* replaced by permbuff */ |
---|
129 | { |
---|
130 | return permbuff(string); |
---|
131 | } |
---|
132 | |
---|
133 | char* |
---|
134 | permbuff(char* string) /* string -> general buffer, returns address */ |
---|
135 | { |
---|
136 | int n, k = char_buff->ca[char_buff->curr-1]->curr; |
---|
137 | if (string == NULL) return NULL; |
---|
138 | n = strlen(string)+1; |
---|
139 | if (k + n >= char_buff->ca[char_buff->curr-1]->max) |
---|
140 | { |
---|
141 | if (char_buff->curr == char_buff->max) grow_char_array_list(char_buff); |
---|
142 | char_buff->ca[char_buff->curr++] = new_char_array(CHAR_BUFF_SIZE); |
---|
143 | k = 0; |
---|
144 | } |
---|
145 | strcpy(&char_buff->ca[char_buff->curr-1]->c[k], string); |
---|
146 | char_buff->ca[char_buff->curr-1]->curr += n; |
---|
147 | return &char_buff->ca[char_buff->curr-1]->c[k]; |
---|
148 | } |
---|
149 | |
---|
150 | char* |
---|
151 | tmpbuff(const char* string) |
---|
152 | /* buffers string in a temporary (i.e. allocated) buffer */ |
---|
153 | // aka strdup |
---|
154 | { |
---|
155 | char* p; |
---|
156 | p = mymalloc("tmpbuff",strlen(string)+1); |
---|
157 | strcpy(p, string); |
---|
158 | return p; |
---|
159 | } |
---|
160 | |
---|
161 | void |
---|
162 | conv_char(const char* string, struct int_array* tint) |
---|
163 | /*converts character string to integer array, using ascii code */ |
---|
164 | { |
---|
165 | int i, l = strlen(string); |
---|
166 | int n = (l < tint->max-1) ? l : tint->max-1; |
---|
167 | |
---|
168 | tint->i[0] = n; |
---|
169 | for (i = 0; i < n; i++) |
---|
170 | tint->i[i+1] = (unsigned char) string[i]; |
---|
171 | } |
---|
172 | |
---|
173 | void |
---|
174 | stolower_nq(char* s) |
---|
175 | /* converts string to lower in place outside quotes */ |
---|
176 | { |
---|
177 | char *c = s; |
---|
178 | int j, toggle = 0; |
---|
179 | char quote = ' '; /* just to suit the compiler */ |
---|
180 | for (j = 0; s[j]; j++) |
---|
181 | { |
---|
182 | if (toggle) |
---|
183 | { |
---|
184 | if (*c == quote) toggle = 0; |
---|
185 | } |
---|
186 | else if (*c == '\"' || *c == '\'') |
---|
187 | { |
---|
188 | toggle = 1; quote = *c; |
---|
189 | } |
---|
190 | else |
---|
191 | { |
---|
192 | *c = (char) tolower((int) *c); |
---|
193 | } |
---|
194 | c++; |
---|
195 | } |
---|
196 | } |
---|
197 | |
---|
198 | char* |
---|
199 | strip(char* name) |
---|
200 | /* strip ':' and following off */ |
---|
201 | { |
---|
202 | char* p; |
---|
203 | strcpy(tmp_key, name); |
---|
204 | if ((p = strchr(tmp_key, ':')) != NULL) *p = '\0'; |
---|
205 | return tmp_key; |
---|
206 | } |
---|
207 | |
---|
208 | int |
---|
209 | supp_lt(char* inbuf, int flag) |
---|
210 | /* suppress leading, trailing blanks and replace some special char.s*/ |
---|
211 | { |
---|
212 | int l = strlen(inbuf), i, j; |
---|
213 | replace(inbuf, '\x9', ' '); /* tab */ |
---|
214 | replace(inbuf, '\xd', ' '); /* Windows e-o-l */ |
---|
215 | if (flag == 0) replace(inbuf, '\n', ' '); /* e-o-l */ |
---|
216 | supp_tb(inbuf); /* suppress trailing blanks */ |
---|
217 | if ((l = strlen(inbuf)) > 0) |
---|
218 | { |
---|
219 | for (j = 0; j < l; j++) if (inbuf[j] != ' ') break; /* leading blanks */ |
---|
220 | if (j > 0) |
---|
221 | { |
---|
222 | for (i = 0; i < l - j; i++) inbuf[i] = inbuf[i+j]; |
---|
223 | inbuf[i] = '\0'; |
---|
224 | } |
---|
225 | } |
---|
226 | return strlen(inbuf); |
---|
227 | } |
---|
228 | |
---|
229 | void |
---|
230 | supp_mul_char(char c, char* string) |
---|
231 | /* reduces multiple occurrences of c in string to 1 occurrence */ |
---|
232 | { |
---|
233 | char* cp = string; |
---|
234 | int cnt = 0; |
---|
235 | while (*string != '\0') |
---|
236 | { |
---|
237 | if (*string != c) |
---|
238 | { |
---|
239 | *cp++ = *string; cnt = 0; |
---|
240 | } |
---|
241 | else if (cnt++ == 0) *cp++ = *string; |
---|
242 | string++; |
---|
243 | } |
---|
244 | *cp = '\0'; |
---|
245 | } |
---|
246 | |
---|
247 | char* |
---|
248 | supp_tb(char* string) /* suppress trailing blanks in string */ |
---|
249 | { |
---|
250 | int l = strlen(string), j; |
---|
251 | for (j = l-1; j >= 0; j--) |
---|
252 | { |
---|
253 | if (string[j] != ' ') break; |
---|
254 | string[j] = '\0'; |
---|
255 | } |
---|
256 | return string; |
---|
257 | } |
---|
258 | |
---|
259 | int |
---|
260 | zero_string(char* string) /* returns 1 if string defaults to '0', else 0 */ |
---|
261 | { |
---|
262 | int i, l = strlen(string); |
---|
263 | char c; |
---|
264 | for (i = 0; i < l; i++) |
---|
265 | if ((c = string[i]) != '0' && c != ' ' && c != '.') return 0; |
---|
266 | return 1; |
---|
267 | } |
---|
268 | |
---|
269 | #if 0 // veryyyy slloowww, replaced by string_icmp |
---|
270 | int |
---|
271 | compare_no_case(char* string_1, char* string_2) |
---|
272 | /* like strcmp, but ignoring case */ |
---|
273 | { |
---|
274 | int ret; |
---|
275 | char rout_name[] = "compare_no_case"; |
---|
276 | char* s1 = mymalloc(rout_name, strlen(string_1)+1); |
---|
277 | char* s2 = mymalloc(rout_name, strlen(string_2)+1); |
---|
278 | strcpy(s1, string_1); stolower(s1); |
---|
279 | strcpy(s2, string_2); stolower(s2); |
---|
280 | ret = strcmp(s1, s2); |
---|
281 | myfree(rout_name, s1); myfree(rout_name, s2); |
---|
282 | return ret; |
---|
283 | } |
---|
284 | #endif |
---|
285 | |
---|
286 | int |
---|
287 | is_token(char* pb, char* string, int slen) |
---|
288 | { |
---|
289 | char* pbl = pb; |
---|
290 | if ((pbl == string || *(--pbl) == ' ') |
---|
291 | && (*(pb+slen) == '\0' || *(pb+slen) == ' ')) return 1; |
---|
292 | else return 0; |
---|
293 | } |
---|
294 | |
---|
295 | char* |
---|
296 | join(char** it_list, int n) |
---|
297 | /* joins n character strings into one */ |
---|
298 | { |
---|
299 | int j; |
---|
300 | *c_join->c = '\0'; |
---|
301 | for (j = 0; j < n; j++) strcat(c_join->c, it_list[j]); |
---|
302 | return c_join->c; |
---|
303 | } |
---|
304 | |
---|
305 | char* |
---|
306 | join_b(char** it_list, int n) |
---|
307 | /* joins n character strings into one, blank separated */ |
---|
308 | { |
---|
309 | char* target; |
---|
310 | int j, k = 0; |
---|
311 | target = c_join->c; |
---|
312 | for (j = 0; j < n; j++) |
---|
313 | { |
---|
314 | strcpy(&target[k], it_list[j]); |
---|
315 | k += strlen(it_list[j]); |
---|
316 | target[k++] = ' '; |
---|
317 | } |
---|
318 | target[k] = '\0'; |
---|
319 | return target; |
---|
320 | } |
---|
321 | |
---|
322 | char |
---|
323 | next_non_blank(char* string) |
---|
324 | /* returns next non-blank in string outside quotes, else blank */ |
---|
325 | { |
---|
326 | int i, toggle = 0, l = strlen(string); |
---|
327 | char quote = ' '; |
---|
328 | for (i = 0; i < l; i++) |
---|
329 | { |
---|
330 | if (toggle) |
---|
331 | { |
---|
332 | if (string[i] == quote) toggle = 0; |
---|
333 | } |
---|
334 | else if (string[i] == '\'' || string[i] == '\"') |
---|
335 | { |
---|
336 | quote = string[i]; toggle = 1; |
---|
337 | } |
---|
338 | else if (string[i] != ' ') return string[i]; |
---|
339 | } |
---|
340 | return ' '; |
---|
341 | } |
---|
342 | |
---|
343 | int |
---|
344 | next_non_blank_pos(char* string) |
---|
345 | /* returns position of next non-blank in string outside quotes, else -1 */ |
---|
346 | { |
---|
347 | int i, toggle = 0, l = strlen(string); |
---|
348 | char quote = ' '; |
---|
349 | for (i = 0; i < l; i++) |
---|
350 | { |
---|
351 | if (toggle) |
---|
352 | { |
---|
353 | if (string[i] == quote) toggle = 0; |
---|
354 | } |
---|
355 | else if (string[i] == '\'' || string[i] == '\"') |
---|
356 | { |
---|
357 | quote = string[i]; toggle = 1; |
---|
358 | } |
---|
359 | else if (string[i] != ' ') return i; |
---|
360 | } |
---|
361 | return -1; |
---|
362 | } |
---|
363 | |
---|
364 | char* |
---|
365 | noquote(char* string) |
---|
366 | { |
---|
367 | char* c = string; |
---|
368 | char* d = c; |
---|
369 | char k; |
---|
370 | if (string != NULL) |
---|
371 | { |
---|
372 | k = *c; |
---|
373 | if (k == '\"' || k == '\'') |
---|
374 | { |
---|
375 | d++; |
---|
376 | while (*d != k) *c++ = *d++; |
---|
377 | *c = '\0'; |
---|
378 | } |
---|
379 | } |
---|
380 | return string; |
---|
381 | } |
---|
382 | |
---|
383 | int |
---|
384 | quote_level(char* string, char* send) |
---|
385 | { |
---|
386 | /* returns the level count of quotation marks " and ' inside string between */ |
---|
387 | /* start of string and send */ |
---|
388 | int level = 0; |
---|
389 | char* p; |
---|
390 | char c = ' '; |
---|
391 | for (p = string; p < send; p++) |
---|
392 | { |
---|
393 | if (level == 0) |
---|
394 | { |
---|
395 | if (*p == '\"' || *p == '\'') |
---|
396 | { |
---|
397 | c = *p; level++; |
---|
398 | } |
---|
399 | } |
---|
400 | else if(*p == c) level--; |
---|
401 | } |
---|
402 | return level; |
---|
403 | } |
---|
404 | |
---|
405 | #if 0 // not used... |
---|
406 | static int |
---|
407 | remove_colon(char** toks, int number, int start) |
---|
408 | /* removes colon behind declarative part for MAD-8 compatibility */ |
---|
409 | { |
---|
410 | int i, k = start; |
---|
411 | for (i = start; i < number; i++) |
---|
412 | if (*toks[i] != ':') toks[k++] = toks[i]; |
---|
413 | return k; |
---|
414 | } |
---|
415 | #endif |
---|
416 | |
---|
417 | int |
---|
418 | square_to_colon(char* string) |
---|
419 | /* sets occurrence count behind colon, possibly replacing [] */ |
---|
420 | { |
---|
421 | char* t; |
---|
422 | int k = strlen(string); |
---|
423 | if ((t = strchr(string, '[')) == NULL) |
---|
424 | { |
---|
425 | string[k++] = ':'; string[k++] = '1'; string[k] = '\0'; |
---|
426 | } |
---|
427 | else |
---|
428 | { |
---|
429 | *t = ':'; |
---|
430 | if ((t = strchr(string, ']')) == NULL) return 0; |
---|
431 | else *t = '\0'; |
---|
432 | } |
---|
433 | return strlen(string); |
---|
434 | } |
---|
435 | |
---|