1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | #ifdef HAVE_CONFIG_H1 |
23 | # include <config.h> |
24 | #endif |
25 | |
26 | #if STDC_HEADERS1 |
27 | # include <stdlib.h> |
28 | #else |
29 | # if HAVE_STDLIB_H1 |
30 | # include <stdlib.h> |
31 | # endif |
32 | #endif |
33 | #if HAVE_STRING_H1 |
34 | # if !STDC_HEADERS1 && HAVE_MEMORY_H1 |
35 | # include <memory.h> |
36 | # endif |
37 | # include <string.h> |
38 | #endif |
39 | #if HAVE_STRINGS_H1 |
40 | # include <strings.h> |
41 | #endif |
42 | #if HAVE_MATH_H1 |
43 | # include <math.h> |
44 | #endif |
45 | #if HAVE_LIMITS_H1 |
46 | # include <limits.h> |
47 | #endif |
48 | #if HAVE_FLOAT_H1 |
49 | # include <float.h> |
50 | #endif |
51 | #if HAVE_CTYPE_H1 |
52 | # include <ctype.h> |
53 | #endif |
54 | #if HAVE_ERRNO_H1 |
55 | # include <errno(*__errno_location ()).h> |
56 | #endif |
57 | |
58 | #include <platon/str/strplus.h> |
59 | #include <platon/str/strdyn.h> |
60 | |
61 | #include "cfg+.h" |
62 | |
63 | |
64 | |
65 | static int search_cur_opt_idx(const CFG_CONTEXT con); |
66 | static int add_to_used_opt_idx(const CFG_CONTEXT con, int opt_idx); |
67 | static int store_multi_arg( |
68 | const int type, |
69 | const char **multi_arg, |
70 | void ***ar); |
71 | static int store_single_arg( |
72 | const int type, |
73 | const char *arg, |
74 | const void *where); |
75 | static int split_multi_arg( |
76 | char *arg, |
77 | char ***ar, |
78 | char **quote_prefix_ar, |
79 | char **quote_postfix_ar, |
80 | char **separator_ar); |
81 | static int unquote_single_arg( |
82 | char *arg, |
83 | char **quote_prefix_ar, |
84 | char **quote_postfix_ar); |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | void |
92 | __cfg_free_currents(con) |
93 | const CFG_CONTEXT con; |
94 | { |
95 | if (con->cur_opt != NULL((void*)0)) |
96 | free(con->cur_opt); |
97 | if (con->cur_arg != NULL((void*)0)) |
98 | free(con->cur_arg); |
99 | |
100 | con->cur_opt = con->cur_arg = NULL((void*)0); |
101 | con->cur_opt_type = CFG_NONE_OPTION; |
102 | } |
103 | |
104 | int |
105 | __cfg_process_currents(con, ret_val, arg_used) |
106 | const CFG_CONTEXT con; |
107 | int *ret_val; |
108 | int *arg_used; |
109 | { |
110 | register int ret = 0; |
111 | register int opt_idx; |
112 | register int opt_type, opt_data_type, opt_f_multi, opt_f_multi_sep; |
113 | register char **quote_prefix_ar, **quote_postfix_ar, **separator_ar; |
114 | |
115 | *ret_val = 0; |
116 | if (arg_used != NULL((void*)0)) |
117 | *arg_used = 0; |
118 | |
119 | opt_idx = search_cur_opt_idx(con); |
120 | |
121 | #if defined(DEBUG) && DEBUG |
122 | fprintf(stderrstderr, "%s|%ld|%s|%s|%s|%d|flags=%x[", |
123 | con->type == CFG_LINE ? "cmdline" : "cfgfile", |
124 | con->type == CFG_LINE ? con->cur_idx : 0, |
125 | con->type == CFG_LINE ? con->argv[con->cur_idx] : "N/A", |
126 | con->cur_opt == NULL((void*)0) ? "[NULL]" : con->cur_opt, |
127 | con->cur_arg == NULL((void*)0) ? "[NULL]" : con->cur_arg, |
128 | opt_idx, con->cur_opt_type); |
129 | |
130 | if (con->cur_opt_type & CFG_LONG_OPTION) |
131 | fputs("-LONG-", stderrstderr); |
132 | if (con->cur_opt_type & CFG_SHORT_OPTION) |
133 | fputs("-SHORT-", stderrstderr); |
134 | if (con->cur_opt_type & CFG_SHORT_OPTIONS) |
135 | fputs("-SHORTS-", stderrstderr); |
136 | if (con->cur_opt_type & CFG_LONG_SEPINIT) |
137 | fputs("-SEPINIT-", stderrstderr); |
138 | |
139 | fputs("]\n", stderrstderr); |
140 | #endif |
141 | |
142 | if (opt_idx < 0) |
143 | return CFG_ERROR_UNKNOWN; |
144 | |
145 | if (! (con->flags & CFG_IGNORE_MULTI) |
146 | && ! (con->options[opt_idx].type & CFG_MULTI)) { |
147 | ret = add_to_used_opt_idx(con, opt_idx); |
148 | |
149 | if (ret < 0) |
150 | return CFG_ERROR_NOMEM; |
151 | else if (ret > 0) |
152 | return CFG_ERROR_MULTI; |
153 | } |
154 | |
155 | |
156 | |
157 | opt_type = con->options[opt_idx].type; |
158 | opt_data_type = opt_type & CFG_DATA_TYPE_MASK; |
159 | opt_f_multi = opt_type & CFG_MULTI; |
160 | opt_f_multi_sep = opt_type & (CFG_MULTI_SEPARATED & ~CFG_MULTI); |
161 | |
162 | if (con->type == CFG_LINE) { |
163 | quote_prefix_ar = con->prop[CFG_LINE_QUOTE_PREFIX]; |
164 | quote_postfix_ar = con->prop[CFG_LINE_QUOTE_POSTFIX]; |
165 | separator_ar = (opt_type & CFG_LEFTOVER_ARGS) |
166 | ? con->prop[CFG_LINE_LEFTOVER_MULTI_VALS_SEPARATOR] |
167 | : con->prop[CFG_LINE_NORMAL_MULTI_VALS_SEPARATOR]; |
168 | } |
169 | else { |
170 | quote_prefix_ar = con->prop[CFG_FILE_QUOTE_PREFIX]; |
171 | quote_postfix_ar = con->prop[CFG_FILE_QUOTE_POSTFIX]; |
172 | separator_ar = (opt_type & CFG_LEFTOVER_ARGS) |
173 | ? con->prop[CFG_FILE_LEFTOVER_MULTI_VALS_SEPARATOR] |
174 | : con->prop[CFG_FILE_NORMAL_MULTI_VALS_SEPARATOR]; |
175 | } |
176 | |
177 | switch (opt_data_type) { |
178 | default: |
179 | return CFG_ERROR_INTERNAL; |
180 | break; |
181 | |
182 | |
183 | |
184 | case CFG_BOOLEAN: |
185 | if (con->cur_opt_type & CFG_LONG_SEPINIT |
186 | && con->cur_arg != NULL((void*)0)) |
187 | return CFG_ERROR_NOTALLOWEDARG; |
188 | |
189 | if (con->options[opt_idx].value != NULL((void*)0)) |
190 | (*((int *) con->options[opt_idx].value))++; |
191 | break; |
192 | |
193 | |
194 | |
195 | case CFG_INT: |
196 | case CFG_UINT: |
197 | case CFG_LONG: |
198 | case CFG_ULONG: |
199 | case CFG_FLOAT: |
200 | case CFG_DOUBLE: |
201 | |
202 | if (con->cur_arg == NULL((void*)0)) |
203 | return CFG_ERROR_NOARG; |
204 | |
205 | if (opt_f_multi) { |
206 | char **add; |
207 | char *static_add[2] = {NULL((void*)0), NULL((void*)0)}; |
208 | |
209 | if (opt_f_multi_sep) { |
210 | |
211 | ret = split_multi_arg(con->cur_arg, &add, |
212 | quote_prefix_ar, quote_postfix_ar, separator_ar); |
213 | |
214 | if (ret != CFG_OK) { |
215 | PLATON_FUNC(strdyn_safe_free)strdyn_safe_free(add); |
216 | return ret; |
217 | } |
218 | } |
219 | else { |
220 | add = static_add; |
221 | add[0] = con->cur_arg; |
222 | } |
223 | |
224 | ret = store_multi_arg(opt_data_type, |
225 | (const char **) add, |
226 | con->options[opt_idx].value); |
227 | |
228 | if (add != static_add) |
229 | PLATON_FUNC(strdyn_free)strdyn_free((char **) add); |
230 | } |
231 | else { |
232 | ret = unquote_single_arg(con->cur_arg, |
233 | quote_prefix_ar, quote_postfix_ar); |
234 | |
235 | if (ret != CFG_OK) |
236 | return ret; |
237 | |
238 | ret = store_single_arg(opt_data_type, con->cur_arg, |
239 | con->options[opt_idx].value); |
240 | } |
241 | |
242 | if (ret != CFG_OK) |
243 | return ret; |
244 | |
245 | if (arg_used != NULL((void*)0)) |
246 | *arg_used = 1; |
247 | break; |
248 | |
249 | |
250 | |
251 | case CFG_STRING: |
252 | |
253 | if (con->cur_arg == NULL((void*)0)) |
254 | return CFG_ERROR_NOARG; |
255 | |
256 | if (con->options[opt_idx].value != NULL((void*)0)) { |
257 | if (opt_f_multi) { |
258 | register char ***p; |
259 | p = (char ***) con->options[opt_idx].value; |
260 | |
261 | if (opt_f_multi_sep) { |
262 | char **ar; |
263 | ret = split_multi_arg(con->cur_arg, &ar, |
264 | quote_prefix_ar, quote_postfix_ar, |
265 | separator_ar); |
266 | |
267 | if (ret != CFG_OK) { |
268 | PLATON_FUNC(strdyn_safe_free)strdyn_safe_free(ar); |
269 | return ret; |
270 | } |
271 | |
272 | if ((*p = PLATON_FUNC(strdyn_add_ar)strdyn_add_ar(*p, ar)) == NULL((void*)0)) |
273 | return CFG_ERROR_NOMEM; |
274 | |
275 | PLATON_FUNC(strdyn_free)strdyn_free(ar); |
276 | } |
277 | else { |
278 | ret = unquote_single_arg(con->cur_arg, |
279 | quote_prefix_ar, quote_postfix_ar); |
280 | |
281 | if (ret != CFG_OK) |
282 | return ret; |
283 | |
284 | if ((*p = PLATON_FUNC(strdyn_add)strdyn_add(*p, con->cur_arg)) == NULL((void*)0)) |
285 | return CFG_ERROR_NOMEM; |
286 | } |
287 | } |
288 | else { |
289 | ret = unquote_single_arg(con->cur_arg, |
290 | quote_prefix_ar, quote_postfix_ar); |
291 | |
292 | if (ret != CFG_OK) |
293 | return ret; |
294 | |
295 | *((char **) con->options[opt_idx].value) = |
296 | strdup(con->cur_arg); |
297 | } |
298 | } |
299 | |
300 | if (arg_used != NULL((void*)0)) |
301 | *arg_used = 1; |
302 | break; |
303 | } |
304 | |
305 | *ret_val = con->options[opt_idx].val; |
306 | |
307 | return CFG_OK; |
308 | } |
309 | |
310 | int |
311 | __cfg_cmdline_set_currents(con) |
312 | const CFG_CONTEXT con; |
313 | { |
314 | register int i, size; |
315 | register char *s, *s_sep, *s_tmp; |
316 | register char *ptr; |
317 | |
318 | size = -1; |
319 | s = con->argv[con->cur_idx]; |
320 | |
321 | |
322 | |
323 | |
324 | for (i = 0; (ptr = con->prop[CFG_LINE_SHORT_OPTION_PREFIX][i]) != NULL((void*)0); i++) |
325 | if ((int) strlen(ptr) > size && strstr(s, ptr) == s) { |
326 | size = strlen(ptr); |
327 | con->cur_opt_type = CFG_SHORT_OPTION; |
328 | } |
329 | |
330 | for (i = 0; (ptr = con->prop[CFG_LINE_LONG_OPTION_PREFIX][i]) != NULL((void*)0); i++) |
331 | if ((int) strlen(ptr) > size && strstr(s, ptr) == s) { |
332 | size = strlen(ptr); |
333 | con->cur_opt_type = CFG_LONG_OPTION; |
334 | } |
335 | |
336 | s_sep = NULL((void*)0); |
337 | |
338 | switch (con->cur_opt_type) { |
339 | default: |
340 | case CFG_NONE_OPTION: |
341 | break; |
342 | |
343 | case CFG_SHORT_OPTION: |
344 | s += size; |
345 | s_sep = strlen(s) > 0 ? s + 1 : s; |
346 | |
347 | if (strlen(s_sep) > 0) { |
348 | con->cur_opt_type += CFG_SHORT_OPTIONS; |
349 | |
350 | if ((con->cur_arg = strdup(s_sep)) == NULL((void*)0)) |
351 | return CFG_ERROR_NOMEM; |
352 | } |
353 | else { |
354 | if (con->argv[con->cur_idx + 1] != NULL((void*)0)) { |
355 | con->cur_arg = strdup(con->argv[con->cur_idx + 1]); |
356 | if (con->cur_arg == NULL((void*)0)) |
357 | return CFG_ERROR_NOMEM; |
358 | } |
359 | else |
360 | con->cur_arg = NULL((void*)0); |
361 | } |
362 | break; |
363 | |
364 | case CFG_LONG_OPTION: |
365 | s += size; |
366 | size = 0; |
367 | |
368 | for (i = 0; (ptr = con->prop[CFG_LINE_OPTION_ARG_SEPARATOR][i]) |
369 | != NULL((void*)0); i++) |
370 | if ((s_tmp = strstr(s, ptr)) != NULL((void*)0)) |
371 | if (s_sep == NULL((void*)0) || s_tmp < s_sep |
372 | || (s_tmp == s_sep && strlen(ptr) > size)) { |
373 | s_sep = s_tmp; |
374 | size = strlen(ptr); |
375 | } |
376 | |
377 | if (s_sep == NULL((void*)0)) { |
378 | if (con->argv[con->cur_idx + 1] != NULL((void*)0)) { |
379 | con->cur_arg = strdup(con->argv[con->cur_idx + 1]); |
380 | if (con->cur_arg == NULL((void*)0)) |
381 | return CFG_ERROR_NOMEM; |
382 | } |
383 | else |
384 | con->cur_arg = NULL((void*)0); |
385 | } |
386 | else { |
387 | con->cur_opt_type += CFG_LONG_SEPINIT; |
388 | if ((con->cur_arg = strdup(s_sep + size)) == NULL((void*)0)) |
389 | return CFG_ERROR_NOMEM; |
390 | } |
391 | } |
392 | |
393 | if (s_sep == NULL((void*)0)) |
394 | s_sep = s + strlen(s); |
395 | |
396 | con->cur_opt = (char *) malloc((s_sep - s + 1) * sizeof(char)); |
397 | if (con->cur_opt == NULL((void*)0)) |
398 | return CFG_ERROR_NOMEM; |
399 | |
400 | strncpy(con->cur_opt, s, s_sep - s); |
401 | con->cur_opt[s_sep - s] = '\0'; |
402 | |
403 | if (con->cur_opt_type == CFG_NONE_OPTION) { |
404 | register char *tmp_str; |
405 | tmp_str = con->cur_opt; |
406 | con->cur_opt = con->cur_arg; |
407 | con->cur_arg = tmp_str; |
408 | } |
409 | |
410 | return CFG_OK; |
411 | } |
412 | |
413 | int |
414 | __cfg_cfgfile_set_currents(con, buf) |
415 | const CFG_CONTEXT con; |
416 | char *buf; |
417 | { |
418 | register char **pos; |
419 | register char *s_sep, *s_tmp; |
420 | register int size; |
421 | |
422 | s_sep = NULL((void*)0); |
423 | size = 0; |
424 | for (pos = con->prop[CFG_FILE_OPTION_ARG_SEPARATOR]; |
425 | pos != NULL((void*)0) && *pos != NULL((void*)0); pos++) { |
426 | |
427 | if ((s_tmp = strstr(buf, *pos)) != NULL((void*)0)) |
428 | if (s_sep == NULL((void*)0) || s_tmp < s_sep |
429 | || (s_tmp == s_sep && strlen(*pos) > size)) { |
430 | s_sep = s_tmp; |
431 | size = strlen(*pos); |
432 | } |
433 | } |
434 | |
435 | if (s_sep == NULL((void*)0)) { |
436 | con->cur_arg = NULL((void*)0); |
437 | |
438 | con->cur_opt = strdup(buf); |
439 | if (con->cur_opt == NULL((void*)0)) |
440 | return CFG_ERROR_NOMEM; |
441 | } |
442 | else { |
443 | con->cur_opt = (char *) malloc((s_sep - buf + 1) * sizeof(char)); |
444 | if (con->cur_opt == NULL((void*)0)) |
445 | return CFG_ERROR_NOMEM; |
446 | |
447 | strncpy(con->cur_opt, buf, s_sep - buf); |
448 | con->cur_opt[s_sep - buf] = '\0'; |
449 | |
450 | if ((con->cur_arg = strdup(s_sep + size)) == NULL((void*)0)) |
451 | return CFG_ERROR_NOMEM; |
452 | |
453 | PLATON_FUNC(str_right_trim)str_right_trim(con->cur_opt); |
454 | PLATON_FUNC(str_left_trim)str_left_trim(con->cur_arg); |
455 | } |
456 | |
457 | return CFG_OK; |
458 | } |
459 | |
460 | |
461 | |
462 | |
463 | |
464 | |
465 | |
466 | |
467 | |
468 | |
469 | |
470 | |
471 | static int |
472 | search_cur_opt_idx(con) |
473 | const CFG_CONTEXT con; |
474 | { |
475 | register int i; |
476 | |
477 | for (i = 0; con->options[i].cmdline_long_name != NULL((void*)0) |
| 1 | Loop condition is true. Entering loop body |
|
478 | || con->options[i].cmdline_short_name != '\0' |
479 | || con->options[i].cfgfile_name != NULL((void*)0) |
480 | || con->options[i].type != CFG_END |
481 | || con->options[i].value != NULL((void*)0) |
482 | || con->options[i].val != 0; |
483 | i++) |
484 | { |
485 | if (con->type == CFG_CMDLINE) { |
| |
486 | if ((con->cur_opt_type & CFG_LONG_OPTION && con->cur_opt != NULL((void*)0) |
| 3 | Assuming pointer value is null |
|
487 | && con->options[i].cmdline_long_name != NULL((void*)0) |
488 | && ! strcmp(con->cur_opt, |
489 | con->options[i].cmdline_long_name)) |
490 | || (con->cur_opt_type & CFG_SHORT_OPTION && |
491 | con->cur_opt[0] != '\0' && |
| 4 | Dereference of null pointer |
|
492 | con->cur_opt[0] == con->options[i].cmdline_short_name) |
493 | || (con->cur_opt_type == CFG_NONE_OPTION && |
494 | con->options[i].type & CFG_LEFTOVER_ARGS)) |
495 | |
496 | return i; |
497 | } |
498 | else { |
499 | int len; |
500 | |
501 | if (con->cur_opt != NULL((void*)0) |
502 | && con->options[i].cfgfile_name != NULL((void*)0) |
503 | && con->cur_opt == PLATON_FUNC(str_white_str)str_white_str(con->cur_opt, |
504 | (char *)(con->options[i].cfgfile_name), &len) |
505 | && len == strlen(con->cur_opt)) |
506 | |
507 | return i; |
508 | } |
509 | } |
510 | |
511 | return -1; |
512 | } |
513 | |
514 | |
515 | |
516 | |
517 | |
518 | |
519 | |
520 | #ifdef CFG_USED_OPT_IDX_STEP(10) |
521 | # undef CFG_USED_OPT_IDX_STEP(10) |
522 | #endif |
523 | |
524 | #if defined(DEBUG) && DEBUG |
525 | # define CFG_USED_OPT_IDX_STEP(10) (1) |
526 | #else |
527 | # define CFG_USED_OPT_IDX_STEP(10) (10) |
528 | #endif |
529 | |
530 | |
531 | |
532 | |
533 | |
534 | |
535 | |
536 | |
537 | |
538 | |
539 | |
540 | |
541 | |
542 | |
543 | |
544 | |
545 | static int |
546 | add_to_used_opt_idx(con, opt_idx) |
547 | const CFG_CONTEXT con; |
548 | int opt_idx; |
549 | { |
550 | int *p_i = NULL((void*)0); |
551 | |
552 | if (opt_idx < 0) |
553 | return 1; |
554 | |
555 | if (con->used_opt_idx != NULL((void*)0)) |
556 | for (p_i = con->used_opt_idx; *p_i >= 0; p_i++) |
557 | if (*p_i == opt_idx) |
558 | return 1; |
559 | |
560 | if (p_i == NULL((void*)0) || *p_i == -255) { |
561 | register int *p_j; |
562 | register int new_size; |
563 | |
564 | new_size = (p_i == NULL((void*)0) ? 0 : p_i - con->used_opt_idx) |
565 | + 1 + CFG_USED_OPT_IDX_STEP(10); |
566 | |
567 | con->used_opt_idx = (int *) realloc(con->used_opt_idx, |
568 | new_size * sizeof(int)); |
569 | |
570 | #if defined(DEBUG) && DEBUG |
571 | printf("add_to_used_opt_idx(con, %d): realloc(%d) = %p\n", |
572 | opt_idx, new_size, (void *) con->used_opt_idx); |
573 | #endif |
574 | |
575 | if (con->used_opt_idx == NULL((void*)0)) |
576 | return -1; |
577 | |
578 | if (p_i == NULL((void*)0)) |
579 | p_i = con->used_opt_idx; |
580 | else |
581 | for (p_i = con->used_opt_idx; *p_i >= 0; p_i++) ; |
582 | |
583 | for (p_j = p_i; p_j - p_i < CFG_USED_OPT_IDX_STEP(10); p_j++) |
584 | *p_j = -1; |
585 | |
586 | *p_j = -255; |
587 | } |
588 | |
589 | *p_i = opt_idx; |
590 | |
591 | return 0; |
592 | } |
593 | |
594 | |
595 | |
596 | |
597 | |
598 | |
599 | |
600 | |
601 | |
602 | static int |
603 | store_multi_arg(type, multi_arg, ar) |
604 | const int type; |
605 | const char **multi_arg; |
606 | void ***ar; |
607 | { |
608 | register int ptr_len, item_len; |
609 | register int size_plus, size; |
610 | register int k, ret; |
611 | |
612 | switch (type) { |
613 | default: |
614 | return CFG_ERROR_INTERNAL; |
615 | break; |
616 | |
617 | case CFG_INT: |
618 | ptr_len = sizeof(int *); |
619 | item_len = sizeof(int); |
620 | break; |
621 | |
622 | case CFG_UINT: |
623 | ptr_len = sizeof(unsigned int *); |
624 | item_len = sizeof(unsigned int); |
625 | break; |
626 | |
627 | case CFG_LONG: |
628 | ptr_len = sizeof(long *); |
629 | item_len = sizeof(long); |
630 | break; |
631 | |
632 | case CFG_ULONG: |
633 | ptr_len = sizeof(unsigned long *); |
634 | item_len = sizeof(unsigned long); |
635 | break; |
636 | |
637 | case CFG_FLOAT: |
638 | ptr_len = sizeof(float *); |
639 | item_len = sizeof(float); |
640 | break; |
641 | |
642 | case CFG_DOUBLE: |
643 | ptr_len = sizeof(double *); |
644 | item_len = sizeof(double); |
645 | break; |
646 | } |
647 | |
648 | for (size_plus = 0; multi_arg[size_plus] != NULL((void*)0); size_plus++) ; |
649 | for (size = 0; *ar != NULL((void*)0) && (*ar)[size] != NULL((void*)0); size++) ; |
650 | |
651 | *ar = realloc(*ar, (size + 1 + size_plus) * ptr_len); |
652 | |
653 | if (*ar == NULL((void*)0)) |
654 | return CFG_ERROR_NOMEM; |
655 | |
656 | |
657 | (*ar)[size + size_plus] = NULL((void*)0); |
658 | |
659 | for (k = 0; k < size_plus; k++) { |
660 | (*ar)[size + k] = malloc(item_len); |
661 | if ((*ar)[size + k] == NULL((void*)0)) |
662 | return CFG_ERROR_NOMEM; |
663 | |
664 | ret = store_single_arg(type, multi_arg[k], (*ar)[size + k]); |
665 | |
666 | if (ret != CFG_OK) { |
667 | |
668 | (*ar)[size + k] = NULL((void*)0); |
669 | return ret; |
670 | } |
671 | } |
672 | |
673 | return CFG_OK; |
674 | } |
675 | |
676 | |
677 | |
678 | |
679 | |
680 | |
681 | |
682 | |
683 | static int |
684 | store_single_arg(type, arg, where) |
685 | const int type; |
686 | const char *arg; |
687 | const void *where; |
688 | { |
689 | register long long_val = 0; |
690 | register unsigned long ulong_val = 0; |
691 | register double double_val = 0.0; |
692 | register int f_integer = 0; |
693 | char *end; |
694 | |
695 | if (where == NULL((void*)0)) |
696 | return CFG_OK; |
697 | |
698 | |
699 | switch (type) { |
700 | default: |
701 | return CFG_ERROR_INTERNAL; |
702 | break; |
703 | |
704 | case CFG_INT: |
705 | case CFG_UINT: |
706 | case CFG_LONG: |
707 | case CFG_ULONG: |
708 | f_integer = 1; |
709 | if (type == CFG_ULONG) { |
710 | ulong_val = strtoul(arg, &end, 0); |
711 | } else { |
712 | long_val = strtol(arg, &end, 0); |
713 | } |
714 | if (! (end == NULL((void*)0) || *end != '\0')) |
715 | |
716 | break; |
717 | |
718 | |
719 | |
720 | |
721 | case CFG_FLOAT: |
722 | case CFG_DOUBLE: |
723 | double_val = strtod(arg, &end); |
724 | if (*end) |
725 | return CFG_ERROR_BADNUMBER; |
726 | |
727 | if (double_val == +HUGE_VAL(__builtin_huge_val()) || double_val == -HUGE_VAL(__builtin_huge_val())) |
728 | |
729 | return f_integer ? CFG_ERROR_OVERFLOW : CFG_ERROR_OVERFLOW; |
730 | #if HAVE_ERRNO_H1 |
731 | if (double_val == 0.0 && errno(*__errno_location ()) == ERANGE34) |
732 | #else |
733 | if (double_val == 0.0 && end == arg) |
734 | #endif |
735 | |
736 | return f_integer ? CFG_ERROR_OVERFLOW : CFG_ERROR_OVERFLOW; |
737 | |
738 | |
739 | if (end == NULL((void*)0) || *end != '\0') |
740 | return CFG_ERROR_BADNUMBER; |
741 | |
742 | if (! f_integer) |
743 | break; |
744 | |
745 | if (type == CFG_ULONG) { |
746 | register double diff; |
747 | ulong_val = (unsigned long) double_val; |
748 | diff = double_val - (double) long_val; |
749 | if (diff >= 1.0 || diff <= -1.0) |
750 | return CFG_ERROR_OVERFLOW; |
751 | if (diff != 0.0) |
752 | return CFG_ERROR_BADNUMBER; |
753 | } else { |
754 | register double diff; |
755 | long_val = (long) double_val; |
756 | diff = double_val - (double) long_val; |
757 | if (diff >= 1.0 || diff <= -1.0) |
758 | return CFG_ERROR_OVERFLOW; |
759 | if (diff != 0.0) |
760 | return CFG_ERROR_BADNUMBER; |
761 | } |
762 | break; |
763 | } |
764 | |
765 | |
766 | switch (type) { |
767 | default: |
768 | return CFG_ERROR_INTERNAL; |
769 | break; |
770 | |
771 | case CFG_INT: |
772 | if (long_val >= INT_MAX2147483647 || long_val <= INT_MIN(-2147483647 -1)) |
773 | return CFG_ERROR_OVERFLOW; |
774 | |
775 | *((int *) where) = (int) long_val; |
776 | break; |
777 | |
778 | case CFG_UINT: |
779 | if (long_val > UINT_MAX(2147483647 *2U +1U) || long_val < 0) |
780 | return CFG_ERROR_OVERFLOW; |
781 | |
782 | *((unsigned int *) where) = (unsigned int) long_val; |
783 | break; |
784 | |
785 | case CFG_LONG: |
786 | if (long_val == LONG_MIN(-9223372036854775807L -1L) || long_val == LONG_MAX9223372036854775807L) |
787 | return CFG_ERROR_OVERFLOW; |
788 | |
789 | *((long *) where) = long_val; |
790 | break; |
791 | |
792 | case CFG_ULONG: |
793 | |
794 | for (end = (char *) arg; isspace(*end)((*__ctype_b_loc ())[(int) ((*end))] & (unsigned short int ) _ISspace); end++) ; |
795 | |
796 | |
797 | if (*end == '-' || ulong_val == ULONG_MAX(9223372036854775807L *2UL +1UL) ) |
798 | return CFG_ERROR_OVERFLOW; |
799 | |
800 | *((unsigned long *) where) = (unsigned long) ulong_val; |
801 | break; |
802 | |
803 | case CFG_FLOAT: |
804 | #ifdef ABS /* Borrowed from popt library. */ |
805 | # undef ABS |
806 | #endif |
807 | #define ABS(a)(((a) < 0) ? -(a) : (a)) (((a) < 0) ? -(a) : (a)) |
808 | |
809 | if (double_val != 0.0) |
810 | if (ABS(double_val)(((double_val) < 0) ? -(double_val) : (double_val)) > FLT_MAX3.40282347e+38F || ABS(double_val)(((double_val) < 0) ? -(double_val) : (double_val)) < FLT_MIN1.17549435e-38F) |
811 | return CFG_ERROR_OVERFLOW; |
812 | |
813 | *((float *) where) = (float) double_val; |
814 | break; |
815 | |
816 | case CFG_DOUBLE: |
817 | *((double *) where) = (double) double_val; |
818 | break; |
819 | } |
820 | |
821 | return CFG_OK; |
822 | } |
823 | |
824 | |
825 | |
826 | |
827 | |
828 | |
829 | |
830 | |
831 | static int |
832 | split_multi_arg(arg, ar, quote_prefix_ar, quote_postfix_ar, separator_ar) |
833 | char *arg; |
834 | char ***ar; |
835 | char **quote_prefix_ar; |
836 | char **quote_postfix_ar; |
837 | char **separator_ar; |
838 | { |
839 | register int i; |
840 | int quote_idx, sep_size, tmp_sep_size; |
841 | char *p_quote, *p_sep, *tmp_s; |
842 | char *arg_base = arg; |
843 | |
844 | if ((*ar = PLATON_FUNC(strdyn_create)strdyn_create()) == NULL((void*)0)) |
845 | return CFG_ERROR_NOMEM; |
846 | |
847 | do { |
848 | |
849 | |
850 | |
851 | p_quote = PLATON_FUNC(strdyn_str2)strdyn_str2(arg, quote_prefix_ar, "e_idx); |
852 | p_sep = NULL((void*)0); |
853 | sep_size = 0; |
854 | |
855 | |
856 | for (i = 0; separator_ar[i] != NULL((void*)0); i++) { |
857 | if ((tmp_s = PLATON_FUNC(str_white_str)str_white_str(arg, separator_ar[i], &tmp_sep_size)) |
858 | != NULL((void*)0) && (p_sep == NULL((void*)0) || tmp_s < p_sep)) { |
859 | p_sep = tmp_s; |
860 | sep_size = tmp_sep_size; |
861 | } |
862 | } |
863 | |
864 | |
865 | |
866 | if ((p_quote != NULL((void*)0) && p_sep == NULL((void*)0)) |
867 | || (p_quote != NULL((void*)0) && p_sep != NULL((void*)0) && p_quote < p_sep)) { |
868 | |
869 | register char *end_ptr, *prefix, *postfix; |
870 | register int prefix_len, postfix_len; |
871 | |
872 | if (quote_idx < 0 |
873 | || quote_idx > PLATON_FUNC(strdyn_get_size)strdyn_get_size(quote_prefix_ar) - 1 |
874 | || quote_idx > PLATON_FUNC(strdyn_get_size)strdyn_get_size(quote_postfix_ar) - 1 |
875 | || (prefix = quote_prefix_ar[quote_idx]) == NULL((void*)0) |
876 | || (postfix = quote_postfix_ar[quote_idx]) == NULL((void*)0)) |
877 | return CFG_ERROR_INTERNAL; |
878 | |
879 | prefix_len = strlen(prefix); |
880 | postfix_len = strlen(postfix); |
881 | |
882 | memmove(p_quote, p_quote + prefix_len, |
883 | strlen(p_quote + prefix_len) + 1); |
884 | |
885 | end_ptr = strstr(p_quote, postfix); |
886 | |
887 | if (end_ptr == NULL((void*)0)) |
888 | return CFG_ERROR_BADQUOTE; |
889 | |
890 | memmove(end_ptr, end_ptr + postfix_len, |
891 | strlen(end_ptr + postfix_len) + 1); |
892 | |
893 | arg = end_ptr; |
894 | } |
895 | |
896 | else if ((p_sep != NULL((void*)0) && p_quote == NULL((void*)0)) |
897 | || (p_sep != NULL((void*)0) && p_quote != NULL((void*)0) && p_sep <= p_quote)) { |
898 | |
899 | register char c; |
900 | |
901 | c = *p_sep; |
902 | *p_sep = '\0'; |
903 | *ar = PLATON_FUNC(strdyn_add_va)strdyn_add_va(*ar, arg_base, NULL((void*)0)); |
904 | *p_sep = c; |
905 | arg = arg_base = p_sep + sep_size; |
906 | |
907 | if (*ar == NULL((void*)0)) |
908 | return CFG_ERROR_NOMEM; |
909 | } |
910 | |
911 | } while (p_quote != NULL((void*)0) || p_sep != NULL((void*)0)); |
912 | |
913 | if ((*ar = PLATON_FUNC(strdyn_add_va)strdyn_add_va(*ar, arg_base, NULL((void*)0))) == NULL((void*)0)) |
914 | return CFG_ERROR_NOMEM; |
915 | |
916 | return CFG_OK; |
917 | } |
918 | |
919 | |
920 | |
921 | |
922 | |
923 | |
924 | |
925 | |
926 | static int |
927 | unquote_single_arg(arg, quote_prefix_ar, quote_postfix_ar) |
928 | char *arg; |
929 | char **quote_prefix_ar; |
930 | char **quote_postfix_ar; |
931 | { |
932 | register char *p_quote; |
933 | int quote_idx; |
934 | |
935 | do { |
936 | p_quote = PLATON_FUNC(strdyn_str2)strdyn_str2(arg, quote_prefix_ar, "e_idx); |
937 | |
938 | |
939 | if (p_quote != NULL((void*)0)) { |
940 | register char *end_ptr, *prefix, *postfix; |
941 | register int prefix_len, postfix_len; |
942 | |
943 | if (quote_idx < 0 |
944 | || quote_idx > PLATON_FUNC(strdyn_get_size)strdyn_get_size(quote_prefix_ar) - 1 |
945 | || quote_idx > PLATON_FUNC(strdyn_get_size)strdyn_get_size(quote_postfix_ar) - 1 |
946 | || (prefix = quote_prefix_ar[quote_idx]) == NULL((void*)0) |
947 | || (postfix = quote_postfix_ar[quote_idx]) == NULL((void*)0)) |
948 | return CFG_ERROR_INTERNAL; |
949 | |
950 | prefix_len = strlen(prefix); |
951 | postfix_len = strlen(postfix); |
952 | |
953 | memmove(p_quote, p_quote + prefix_len, |
954 | strlen(p_quote + prefix_len) + 1); |
955 | |
956 | end_ptr = strstr(p_quote, postfix); |
957 | |
958 | if (end_ptr == NULL((void*)0)) |
959 | return CFG_ERROR_BADQUOTE; |
960 | |
961 | memmove(end_ptr, end_ptr + postfix_len, |
962 | strlen(end_ptr + postfix_len) + 1); |
963 | |
964 | arg = end_ptr; |
965 | } |
966 | } while (p_quote != NULL((void*)0)); |
967 | |
968 | return CFG_OK; |
969 | } |
970 | |
971 | |
972 | |
973 | |
974 | |
975 | |