1 #include <ctype.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include "conf.h"
6
7
8 typedef struct _SField
9 {
10 char *name;
11 int type;
12 union {
13 char *str_value;
14 int int_value;
15 double double_value;
16 HTable table_value;
17 } value;
18 struct _SField *next;
19 } SField;
20
21
22 typedef struct _STable
23 {
24 SField *fields;
25 char *stat_buf;
26 } STable;
27
28
29 typedef struct _STableIterator
30 {
31 HTable table;
32 SField *cur_field;
33 int before_start;
34 char *stat_buf;
35 } STableIterator;
36
37
38
table_create()39 HTable table_create()
40 {
41 HTable table;
42
43 table = (STable*)calloc(1, sizeof(STable));
44 return table;
45 }
46
47
free_field(SField * field)48 static void free_field(SField *field)
49 {
50 if (! field)
51 return;
52 if (field->name)
53 free(field->name);
54 switch (field->type)
55 {
56 case TYPE_STRING: free(field->value.str_value); break;
57 case TYPE_TABLE: table_free(field->value.table_value); break;
58 }
59 free(field);
60 }
61
62
find_field(HTable table,const char * name)63 static SField* find_field(HTable table, const char *name)
64 {
65 SField *f;
66
67 if ((! table) || (! name))
68 return NULL;
69
70 f = table->fields;
71 while (f)
72 {
73 if (f->name && (! strcmp(f->name, name)))
74 return f;
75 f = f->next;
76 }
77
78 return NULL;
79 }
80
81
table_remove_field(HTable table,char * field)82 int table_remove_field(HTable table, char *field)
83 {
84 SField *f, *pf;
85
86 if ((! table) || (! field))
87 return -1;
88
89 f = find_field(table, field);
90 if (f)
91 {
92 if (table->fields == f)
93 table->fields = f->next;
94 else
95 {
96 pf = table->fields;
97 while (pf && (pf->next != f))
98 pf = pf->next;
99 if (pf)
100 pf->next = f->next;
101 }
102 free_field(f);
103 }
104
105 return 0;
106 }
107
108
add_empty_field(HTable table,const char * field)109 static SField* add_empty_field(HTable table, const char *field)
110 {
111 SField *f, *nf;
112
113 if ((! table) || (! field))
114 return NULL;
115
116 f = find_field(table, field);
117 if (f)
118 table_remove_field(table, f->name);
119
120 nf = (SField*)calloc(1, sizeof(SField));
121 if (! nf) return NULL;
122 nf->name = strdup(field);
123
124 f = table->fields;
125 if (f)
126 {
127 while (f->next)
128 f = f->next;
129 f->next = nf;
130 }
131 else
132 table->fields = nf;
133
134 return nf;
135 }
136
137
table_set_str(HTable table,const char * field,const char * value)138 int table_set_str(HTable table, const char *field, const char *value)
139 {
140 SField *f;
141
142 if ((! table) || (! field) || (! value))
143 return -1;
144
145 f = add_empty_field(table, field);
146 if (! f) return -1;
147
148 f->type = TYPE_STRING;
149 f->value.str_value = strdup(value);
150 return 0;
151 }
152
153
table_set_int(HTable table,const char * field,int value)154 int table_set_int(HTable table, const char *field, int value)
155 {
156 SField *f;
157
158 if ((! table) || (! field))
159 return -1;
160
161 f = add_empty_field(table, field);
162 if (! f) return -1;
163
164 f->type = TYPE_INT;
165 f->value.int_value = value;
166 return 0;
167 }
168
169
table_set_double(HTable table,const char * field,double value)170 int table_set_double(HTable table, const char *field, double value)
171 {
172 SField *f;
173
174 if ((! table) || (! field))
175 return -1;
176
177 f = add_empty_field(table, field);
178 if (! f) return -1;
179
180 f->type = TYPE_FLOAT;
181 f->value.double_value = value;
182 return 0;
183 }
184
185
table_set_table(HTable table,const char * field,HTable value)186 int table_set_table(HTable table, const char *field, HTable value)
187 {
188 SField *f;
189
190 if ((! table) || (! field) || (! value))
191 return -1;
192
193 f = add_empty_field(table, field);
194 if (! f) return -1;
195
196 f->type = TYPE_TABLE;
197 f->value.table_value = value;
198 return 0;
199 }
200
201
202 static int skip_spaces(char *buf, long int *pos);
203
204
skip_multy_comment(char * buf,long int * pos)205 static int skip_multy_comment(char *buf, long int *pos)
206 {
207 while (buf[*pos])
208 {
209 if (buf[*pos] == '*')
210 {
211 (*pos)++;
212 if (buf[*pos] == '/')
213 {
214 (*pos)++;
215 return skip_spaces(buf, pos);
216 }
217 }
218 (*pos)++;
219 }
220
221 return -1;
222 }
223
224
skip_line_comment(char * buf,long int * pos)225 static int skip_line_comment(char *buf, long int *pos)
226 {
227 while (buf[*pos] && ((buf[*pos]) != '\n'))
228 (*pos)++;
229 return skip_spaces(buf, pos);
230 }
231
232
is_cspace(char * buf,long int * pos)233 static int is_cspace(char *buf, long int *pos)
234 {
235 if (isspace(buf[*pos]))
236 return 1;
237 if (buf[*pos] == '/')
238 {
239 if ((buf[(*pos) + 1] == '*') || (buf[(*pos) + 1] == '/'))
240 return 1;
241 }
242 return 0;
243 }
244
245
skip_spaces(char * buf,long int * pos)246 static int skip_spaces(char *buf, long int *pos)
247 {
248 while (buf[*pos] && isspace(buf[*pos]))
249 (*pos)++;
250
251 if (buf[*pos] == '/')
252 {
253 (*pos)++;
254 if (buf[*pos] == '*')
255 {
256 (*pos)++;
257 return skip_multy_comment(buf, pos);
258 }
259 else if (buf[*pos] == '/')
260 {
261 (*pos)++;
262 return skip_line_comment(buf, pos);
263 }
264 else
265 return -1;
266 }
267 return 0;
268 }
269
270
is_symbol(char sym)271 static int is_symbol(char sym)
272 {
273 static char syms[] = { '=', '{', '}', ';', '\'', '"', ',', '/', '\\' };
274 unsigned int i;
275
276 for (i = 0; i < sizeof(syms) / sizeof(char); i++)
277 {
278 if (sym == syms[i])
279 return 1;
280 }
281
282 return 0;
283 }
284
285
read_string(char * buf,long int * pos)286 static char* read_string(char* buf, long int *pos)
287 {
288 int allocated=50, len=1;
289 char *b;
290
291 b = (char*)malloc(allocated);
292 if (! b) return NULL;
293 b[0] = buf[*pos];
294 (*pos)++;
295 while (buf[*pos])
296 {
297 if (len + 3 > allocated)
298 {
299 char *s = (char*)realloc(b, allocated+=20);
300 if (! s)
301 {
302 free(b);
303 return NULL;
304 }
305 b = s;
306 }
307 if ((buf[*pos] == '\\') && (buf[*pos + 1] == b[0]))
308 {
309 b[len++] = '\\';
310 b[len] = b[0];
311 }
312 else
313 {
314 b[len++] = buf[*pos];
315 if (buf[*pos] == b[0])
316 {
317 b[len] = 0;
318 (*pos)++;
319 return b;
320 }
321 }
322 (*pos)++;
323 }
324 free(b);
325 return NULL;
326 }
327
328
read_word(char * buf,long int * pos)329 static char* read_word(char* buf, long int *pos)
330 {
331 int allocated=50, len=0;
332 char *b;
333
334 b = (char*)malloc(allocated);
335 if (! b) return NULL;
336 while (buf[*pos] && (! is_cspace(buf, pos)) && (! is_symbol(buf[*pos])))
337 {
338 if (len + 3 > allocated)
339 {
340 char *s = (char*)realloc(b, allocated+=20);
341 if (! s)
342 {
343 free(b);
344 return NULL;
345 }
346 b = s;
347 }
348 b[len++] = buf[*pos];
349 (*pos)++;
350 }
351 if (! len)
352 {
353 free(b);
354 return NULL;
355 }
356 b[len] = 0;
357 return b;
358 }
359
360
read_token(char * buf,long int * pos)361 static char* read_token(char *buf, long int *pos)
362 {
363 if (skip_spaces(buf, pos) || (! buf[*pos]))
364 return NULL;
365
366 if ((buf[*pos] == '\'') || (buf[*pos] == '"'))
367 return read_string(buf, pos);
368
369 if (is_symbol(buf[*pos]))
370 {
371 char *b = (char*)malloc(2);
372 if (! b) return NULL;
373 b[0] = buf[*pos];
374 b[1] = 0;
375 (*pos)++;
376 return b;
377 }
378
379 return read_word(buf, pos);
380 }
381
382
get_file_size(FILE * f)383 static long int get_file_size(FILE *f)
384 {
385 long int len;
386
387 if (fseek(f, 0L, SEEK_END))
388 return -1;
389
390 len = ftell(f);
391
392 if (fseek(f, 0L, SEEK_SET))
393 return -1;
394
395 return len;
396 }
397
398
read_file(const char * filename,long int * length)399 static char* read_file(const char *filename, long int *length)
400 {
401 FILE *f;
402 char *buf;
403 long int len;
404
405 f = fopen(filename, "rb");
406 if (! f) return NULL;
407
408 len = get_file_size(f);
409 if (len <= 0)
410 {
411 fclose(f);
412 return NULL;
413 }
414
415 buf = (char*)malloc(len + 1);
416 if (! buf)
417 {
418 fclose(f);
419 return NULL;
420 }
421
422 if (fread(buf, 1, len, f) != (unsigned)len)
423 {
424 free(buf);
425 fclose(f);
426 return NULL;
427 }
428
429 buf[len] = 0;
430
431 fclose(f);
432 *length = len + 1;
433 return buf;
434 }
435
436
get_next_index(HTable table)437 static int get_next_index(HTable table)
438 {
439 SField *f;
440 int v, max_v=-1;
441 char *endptr;
442
443 for (f = table->fields; f; f = f->next)
444 {
445 v = strtol(f->name, &endptr, 10);
446 if ((! f->name[0]) || (endptr[0]))
447 continue;
448 if (v > max_v)
449 max_v = v;
450 }
451
452 return max_v + 1;
453 }
454
455
is_ident(char * str)456 static int is_ident(char *str)
457 {
458 char *p;
459
460 if (! str)
461 return 0;
462 if (strlen(str) < 1)
463 return 0;
464 if (! isalpha(str[0]))
465 return 0;
466
467 for (p = str; *p; p++)
468 if (! (isalnum(*p) || (*p == '_') || (*p == '.')))
469 return 0;
470
471 return 1;
472 }
473
474
is_string_value(char * value)475 static int is_string_value(char *value)
476 {
477 int len;
478
479 if ((value[0] == '\'') || (value[0] == '"'))
480 {
481 if ((len = strlen(value)) >= 2)
482 {
483 if (value[len - 1] == value[0])
484 return 1;
485 }
486 }
487
488 return 0;
489 }
490
491
is_int_value(char * value)492 static int is_int_value(char *value)
493 {
494 char *p;
495
496 for (p = value; *p; p++)
497 {
498 if (! isdigit(*p))
499 {
500 if (p != value)
501 return 0;
502 else
503 if (! ((*p == '+') || (*p == '-')))
504 return 0;
505 }
506 }
507 return 1;
508 }
509
510
is_float_value(char * value)511 static int is_float_value(char *value)
512 {
513 char *p;
514 int pcount = 0;
515
516 for (p = value; *p; p++)
517 {
518 if (! isdigit(*p))
519 {
520 if (p != value)
521 {
522 if (*p != '.')
523 return 0;
524 else
525 {
526 pcount++;
527 if (pcount > 1)
528 return 0;
529 }
530 }
531 else
532 {
533 if (! ((*p == '+') || (*p == '-')))
534 return 0;
535 }
536 }
537 }
538 return 1;
539 }
540
541
get_value_type(char * value)542 static int get_value_type(char *value)
543 {
544 if ((! value) || (! value[0]))
545 return -1;
546
547 if (is_string_value(value))
548 return TYPE_STRING;
549 if (! strcmp(value, "{"))
550 return TYPE_TABLE;
551 if (is_int_value(value))
552 return TYPE_INT;
553 if (is_float_value(value))
554 return TYPE_FLOAT;
555
556 return -1;
557 }
558
559
unescape_string(char * str)560 static char* unescape_string(char *str)
561 {
562 char *buf, quote, *p;
563 int allocated=50, len=0;
564
565 buf = (char*)malloc(allocated);
566
567 quote = str[0];
568 p = str + 1;
569 while ((*p) && (*p != quote))
570 {
571 if (len + 10 > allocated)
572 {
573 char *s = (char*)realloc(buf, allocated+=20);
574 if (! s)
575 {
576 free(buf);
577 return NULL;
578 }
579 buf = s;
580 }
581 if (*p == '\\')
582 {
583 p++;
584 switch (*p)
585 {
586 case 'n': buf[len++] = '\n'; break;
587 case 't': buf[len++] = '\t'; break;
588 case 'r': buf[len++] = '\r'; break;
589 default: buf[len++] = *p;
590 }
591 }
592 else
593 buf[len++] = *p;
594 p++;
595 }
596 buf[len] = 0;
597
598 if ((*p == quote) && (*(p + 1)))
599 {
600 free(buf);
601 return NULL;
602 }
603 return buf;
604 }
605
606
607 static int parse_table(HTable table, char *buf, long int *pos, int top_level);
608
609
add_field(HTable table,char * name,char * value,char * buf,long int * pos)610 static int add_field(HTable table, char *name, char *value, char *buf, long int *pos)
611 {
612 int value_type;
613 char *s;
614 HTable tbl;
615
616 value_type = get_value_type(value);
617 switch (value_type)
618 {
619 case TYPE_INT:
620 table_set_int(table, name, atoi(value));
621 break;
622 case TYPE_STRING:
623 s = unescape_string(value);
624 if (! s)
625 return -1;
626 table_set_str(table, name, s);
627 free(s);
628 break;
629 case TYPE_FLOAT:
630 table_set_double(table, name, atof(value));
631 break;
632 case TYPE_TABLE:
633 tbl = table_create();
634 if (table_set_table(table, name, tbl))
635 {
636 table_free(tbl);
637 return -1;
638 }
639 if (parse_table(tbl, buf, pos, 0))
640 return -1;
641 break;
642 default:
643 return -1;
644 }
645 return 0;
646 }
647
648
add_field_to_array(HTable table,char * token,char * buf,long int * pos)649 static int add_field_to_array(HTable table, char *token, char *buf, long int *pos)
650 {
651 int idx = get_next_index(table);
652 char b[100];
653 sprintf(b, "%i", idx);
654 return add_field(table, b, token, buf, pos);
655 }
656
657
658
659 /*
660 * TODO: add field as in array highly unoptimized. it scans for max index
661 * number on every element addition, converting idexes from strings
662 * to numbers where it possible. optimizations method: process
663 * indexes in batch
664 */
665
parse_table(HTable table,char * buf,long int * pos,int top_level)666 static int parse_table(HTable table, char *buf, long int *pos, int top_level)
667 {
668 char *token=NULL;
669 char *name;
670 int res;
671
672 while (1)
673 {
674 if (! token)
675 token = read_token(buf, pos);
676 if (! token)
677 {
678 if (top_level)
679 return 0;
680 else
681 return -1;
682 }
683
684 if (! strcmp(token, "{"))
685 {
686 if (add_field_to_array(table, token, buf, pos))
687 {
688 free(token);
689 return -1;
690 }
691 free(token);
692 token = read_token(buf, pos);
693 if (! token)
694 {
695 if (top_level)
696 return 0;
697 else
698 return -1;
699 }
700 if ((! strcmp(token, ";")) || (! strcmp(token, ",")))
701 {
702 free(token);
703 token = NULL;
704 }
705 continue;
706 }
707 else if (! strcmp(token, "}"))
708 {
709 free(token);
710 if (top_level)
711 return -1;
712 else
713 return 0;
714 }
715
716 name = token;
717
718 token = read_token(buf, pos);
719
720 if (token && (! strcmp(token, "=")))
721 {
722 free(token);
723
724 if (! is_ident(name))
725 {
726 free(name);
727 return -1;
728 }
729
730 token = read_token(buf, pos);
731 if (! token)
732 {
733 free(name);
734 return -1;
735 }
736
737 res = add_field(table, name, token, buf, pos);
738 free(name);
739 free(token);
740 if (res)
741 {
742 return -1;
743 }
744
745 token = read_token(buf, pos);
746 if (! token)
747 {
748 if (top_level)
749 return 0;
750 else
751 return -1;
752 }
753 if ((! strcmp(token, ";")) || (! strcmp(token, ",")))
754 {
755 free(token);
756 token = NULL;
757 }
758 else
759 if (strcmp(token, "}"))
760 {
761 free(token);
762 return -1;
763 }
764 }
765 else
766 {
767 if ((! token) && (! top_level))
768 {
769 free(name);
770 return -1;
771 }
772 if (! (token && ((! strcmp(token, ";")) || (! strcmp(token, ","))
773 || (! strcmp(token, "}")))))
774 {
775 free(name);
776 if (token) free(token);
777 return -1;
778 }
779
780 res = add_field_to_array(table, name, buf, pos);
781 free(name);
782 if (res)
783 {
784 free(token);
785 return -1;
786 }
787
788 if ((! token) || (! strcmp(token, "}")))
789 {
790 if (token) free(token);
791 return 0;
792 }
793
794 if (token && ((! strcmp(token, ",")) || ((! strcmp(token, ";")))))
795 {
796 free(token);
797 token = NULL;
798 }
799 }
800 }
801
802 return 0;
803 }
804
805
table_read(const char * filename)806 HTable table_read(const char *filename)
807 {
808 long int len, pos;
809 char *buf;
810 HTable table;
811 int res;
812
813 buf = read_file(filename, &len);
814 if (! buf) return NULL;
815
816 pos = 0;
817 table = table_create();
818 res = parse_table(table, buf, &pos, 1);
819 if (res)
820 {
821 table_free(table);
822 table = NULL;
823 }
824
825 free(buf);
826 return table;
827 }
828
829
table_free(HTable table)830 void table_free(HTable table)
831 {
832 SField *f, *nf;
833
834 if (! table) return;
835
836 f = table->fields;
837 while (f)
838 {
839 nf = f->next;
840 free_field(f);
841 f = nf;
842 }
843 if (table->stat_buf)
844 free(table->stat_buf);
845 free(table);
846 }
847
848
table_get_iter(HTable table)849 HTableIterator table_get_iter(HTable table)
850 {
851 HTableIterator it;
852
853 it = (HTableIterator)calloc(sizeof(STableIterator), 1);
854 if (! it) return NULL;
855
856 it->table = table;
857 it->before_start = 1;
858
859 return it;
860 }
861
862
table_free_iter(HTableIterator iterator)863 void table_free_iter(HTableIterator iterator)
864 {
865 if (! iterator) return;
866 if (iterator->stat_buf) free(iterator->stat_buf);
867 free(iterator);
868 }
869
870
table_iter_next(HTableIterator iterator)871 int table_iter_next(HTableIterator iterator)
872 {
873 if (! iterator)
874 return 0;
875
876 if (iterator->before_start)
877 {
878 iterator->before_start = 0;
879 iterator->cur_field = iterator->table->fields;
880 }
881 else
882 {
883 if (iterator->cur_field)
884 iterator->cur_field = iterator->cur_field->next;
885 }
886
887 if (! iterator->cur_field)
888 return 0;
889
890 return 1;
891 }
892
893
table_iter_get_name(HTableIterator iterator)894 char* table_iter_get_name(HTableIterator iterator)
895 {
896 if ((! iterator) || (! iterator->cur_field))
897 return NULL;
898
899 return iterator->cur_field->name;
900 }
901
902
table_iter_get_type(HTableIterator iterator)903 int table_iter_get_type(HTableIterator iterator)
904 {
905 if ((! iterator) || (! iterator->cur_field))
906 return -1;
907
908 return iterator->cur_field->type;
909 }
910
911
encode_string(char * str)912 static char* encode_string(char *str)
913 {
914 char *buf, *s;
915 int allocated, len;
916
917 if (! str)
918 return strdup("''");
919
920 allocated = 20;
921 buf = (char*)malloc(allocated);
922 if (! buf) return NULL;
923 buf[0] = '\'';
924 len = 1;
925 for (s = str; *s; s++)
926 {
927 if (len + 2 < allocated - 2)
928 {
929 char *m = (char*)realloc(buf, allocated += 20);
930 if (! m)
931 {
932 free(buf);
933 return NULL;
934 }
935 buf = m;
936 }
937 switch (*s)
938 {
939 case '\n': buf[len++] = '\\'; buf[len++] = 'n'; break;
940 case '\r': buf[len++] = '\\'; buf[len++] = 'r'; break;
941 case '\'': buf[len++] = '\\'; buf[len++] = '\''; break;
942 case '\\': buf[len++] = '\\'; buf[len++] = '\\'; break;
943 default:
944 buf[len++] = *s;
945 }
946 }
947 buf[len++] = '\'';
948 buf[len] = 0;
949 return buf;
950 }
951
952
print_field(SField * field,int butify,int spaces)953 static char* print_field(SField *field, int butify, int spaces)
954 {
955 char buf[100];
956
957 if (! field) return NULL;
958
959 switch (field->type)
960 {
961 case TYPE_STRING:
962 return encode_string(field->value.str_value);
963 case TYPE_INT:
964 sprintf(buf, "%i", field->value.int_value);
965 return strdup(buf);
966 case TYPE_FLOAT:
967 sprintf(buf, "%g", field->value.double_value);
968 if (! strchr(buf, '.'))
969 strcat(buf, ".0");
970 return strdup(buf);
971 case TYPE_TABLE:
972 return table_to_str(field->value.table_value, 1, butify, spaces);
973 }
974
975 return NULL;
976 }
977
978
isSimpleArray(HTable table)979 static int isSimpleArray(HTable table)
980 {
981 SField *f;
982 char buf[50];
983 int i;
984
985 for (f = table->fields, i = 0; f; f = f->next, i++)
986 {
987 sprintf(buf, "%i", i);
988 if (! (f && f->name && (! strcmp(f->name, buf))))
989 return 0;
990 }
991 return 1;
992 }
993
994
995 #define APPEND_BUF(buf, s) { int l = strlen(s); \
996 if (len + l > allocated - 5) { \
997 char *nb; \
998 allocated += l + 50; \
999 nb = (char*)realloc(buf, allocated); \
1000 if (! nb) { \
1001 free(buf); \
1002 return NULL; \
1003 } \
1004 buf = nb; \
1005 } \
1006 strcat(buf, s); \
1007 len += l; \
1008 }
1009
1010 #define APPEND_SPACES(buf, n) \
1011 for (int i = 0; i < n; i++) { APPEND_BUF(buf, " "); }
1012
table_to_str(HTable table,int print_braces,int butify,int spaces)1013 char* table_to_str(HTable table, int print_braces, int butify, int spaces)
1014 {
1015 char *b, *fs;
1016 int len=0, allocated;
1017 SField *f;
1018
1019 if (! table) return NULL;
1020
1021 allocated = 100;
1022 b = (char*)malloc(allocated);
1023 if (! b) return NULL;
1024
1025 if (print_braces) {
1026 if (butify)
1027 strcpy(b, "{\n");
1028 else
1029 strcpy(b, "{ ");
1030 } else
1031 strcpy(b, "");
1032 len = strlen(b);
1033 int printNames = ! isSimpleArray(table);
1034 for (f = table->fields; f; f = f->next) {
1035 if (butify) {
1036 APPEND_SPACES(b, spaces);
1037 } else
1038 if (f != table->fields) {
1039 APPEND_BUF(b, " ");
1040 }
1041 if (printNames) {
1042 APPEND_BUF(b, f->name);
1043 APPEND_BUF(b, " = ");
1044 }
1045 fs = print_field(f, butify, spaces + 4);
1046 APPEND_BUF(b, fs);
1047 free(fs);
1048 if (butify) {
1049 APPEND_BUF(b, ";\n");
1050 } else {
1051 APPEND_BUF(b, ";");
1052 }
1053 }
1054 if (print_braces) {
1055 if (! butify) {
1056 APPEND_BUF(b, " }");
1057 } else {
1058 APPEND_SPACES(b, spaces);
1059 APPEND_BUF(b, "}");
1060 }
1061 }
1062 return b;
1063 }
1064
1065
get_field_str(SField * field,int * err)1066 static char* get_field_str(SField *field, int *err)
1067 {
1068 char buf[100];
1069
1070 if (err) *err = 0;
1071
1072 if (! field)
1073 {
1074 if (err) *err = 1;
1075 return NULL;
1076 }
1077
1078 switch (field->type)
1079 {
1080 case TYPE_STRING:
1081 return strdup(field->value.str_value);
1082 case TYPE_INT:
1083 sprintf(buf, "%i", field->value.int_value);
1084 return strdup(buf);
1085 case TYPE_FLOAT:
1086 sprintf(buf, "%f", field->value.double_value);
1087 return strdup(buf);
1088 case TYPE_TABLE:
1089 return table_to_str(field->value.table_value, 1, 0, 0);;
1090 }
1091
1092 if (err) *err = 1;
1093 return NULL;
1094 }
1095
1096
table_iter_get_str(HTableIterator iterator,int * err)1097 char* table_iter_get_str(HTableIterator iterator, int *err)
1098 {
1099 if ((! iterator) || (! iterator->cur_field))
1100 {
1101 if (err) *err = 1;
1102 return NULL;
1103 }
1104
1105 return get_field_str(iterator->cur_field, err);
1106 }
1107
1108
table_iter_get_strs(HTableIterator iterator,int * err)1109 char* table_iter_get_strs(HTableIterator iterator, int *err)
1110 {
1111 if ((! iterator) || (! iterator->cur_field))
1112 {
1113 if (err) *err = 1;
1114 return NULL;
1115 }
1116
1117 if (iterator->stat_buf)
1118 free(iterator->stat_buf);
1119 iterator->stat_buf = get_field_str(iterator->cur_field, err);
1120 return iterator->stat_buf;
1121 }
1122
1123
get_field_int(SField * field,int * err)1124 static int get_field_int(SField *field, int *err)
1125 {
1126 char *endptr;
1127 int n;
1128
1129 if (err) *err = 0;
1130
1131 if (! field)
1132 {
1133 if (err) *err = 1;
1134 return 0;
1135 }
1136
1137 switch (field->type)
1138 {
1139 case TYPE_STRING:
1140 n = strtol(field->value.str_value, &endptr, 10);
1141 if ((! field->value.str_value[0]) || (endptr[0]))
1142 {
1143 if (err) *err = 1;
1144 return 0;
1145 }
1146 return n;
1147 case TYPE_INT:
1148 return field->value.int_value;
1149 case TYPE_FLOAT:
1150 return (int)field->value.double_value;
1151 }
1152
1153 if (err) *err = 1;
1154 return 0;
1155 }
1156
1157
table_iter_get_int(HTableIterator iterator,int * err)1158 int table_iter_get_int(HTableIterator iterator, int *err)
1159 {
1160 if ((! iterator) || (! iterator->cur_field))
1161 {
1162 if (err) *err = 1;
1163 return 0;
1164 }
1165
1166 return get_field_int(iterator->cur_field, err);
1167 }
1168
1169
get_field_double(SField * field,int * err)1170 static double get_field_double(SField *field, int *err)
1171 {
1172 char *endptr;
1173 double n;
1174
1175 if (err) *err = 0;
1176
1177 if (! field)
1178 {
1179 if (err) *err = 1;
1180 return 0.0;
1181 }
1182
1183 switch (field->type)
1184 {
1185 case TYPE_STRING:
1186 n = strtod(field->value.str_value, &endptr);
1187 if ((! field->value.str_value[0]) || (endptr[0]))
1188 {
1189 if (err) *err = 1;
1190 return 0.0;
1191 }
1192 return n;
1193 case TYPE_INT:
1194 return field->value.int_value;
1195 case TYPE_FLOAT:
1196 return field->value.double_value;
1197 }
1198
1199 if (err) *err = 1;
1200 return 0.0;
1201 }
1202
1203
table_iter_get_double(HTableIterator iterator,int * err)1204 double table_iter_get_double(HTableIterator iterator, int *err)
1205 {
1206 if ((! iterator) || (! iterator->cur_field))
1207 {
1208 if (err) *err = 1;
1209 return 0.0;
1210 }
1211
1212 return get_field_double(iterator->cur_field, err);
1213 }
1214
1215
table_iter_get_table(HTableIterator iterator,int * err)1216 HTable table_iter_get_table(HTableIterator iterator, int *err)
1217 {
1218 if ((! iterator) || (! iterator->cur_field))
1219 {
1220 if (err) *err = 1;
1221 return NULL;
1222 }
1223
1224 if (iterator->cur_field->type != TYPE_TABLE)
1225 {
1226 if (err) *err = 1;
1227 return NULL;
1228 }
1229
1230 if (err) *err = 0;
1231 return iterator->cur_field->value.table_value;
1232 }
1233
1234
table_is_field_exists(HTable table,char * name)1235 int table_is_field_exists(HTable table, char *name)
1236 {
1237 SField *f;
1238
1239 f = find_field(table, name);
1240 if (f)
1241 return 1;
1242 else
1243 return 0;
1244 }
1245
1246
table_get_field_type(HTable table,char * field)1247 int table_get_field_type(HTable table, char *field)
1248 {
1249 SField *f;
1250
1251 f = find_field(table, field);
1252 if (! f)
1253 return -1;
1254
1255 return f->type;
1256 }
1257
1258
table_get_str(HTable table,char * field,char * dflt,int * err)1259 char* table_get_str(HTable table, char *field, char *dflt, int *err)
1260 {
1261 SField *f;
1262 char *s;
1263 int e;
1264
1265 f = find_field(table, field);
1266 if (! f)
1267 {
1268 if (err) *err = 1;
1269 if (dflt)
1270 return strdup(dflt);
1271 else
1272 return NULL;
1273 }
1274
1275 s = get_field_str(f, &e);
1276 if (err) *err = e;
1277 if (e)
1278 {
1279 if (dflt)
1280 return strdup(dflt);
1281 else
1282 return NULL;
1283 }
1284 else
1285 {
1286 if (s)
1287 return strdup(s);
1288 else
1289 return NULL;
1290 }
1291 }
1292
1293
table_get_strs(HTable table,char * field,char * dflt,int * err)1294 char* table_get_strs(HTable table, char *field, char *dflt, int *err)
1295 {
1296 SField *f;
1297 char *s;
1298 int e;
1299
1300 if (! table)
1301 {
1302 if (err) *err = 1;
1303 return dflt;
1304 }
1305
1306 if (table->stat_buf)
1307 {
1308 free(table->stat_buf);
1309 table->stat_buf = NULL;
1310 }
1311
1312 f = find_field(table, field);
1313 if (! f)
1314 {
1315 if (err) *err = 1;
1316 return dflt;
1317 }
1318
1319 s = get_field_str(f, &e);
1320 table->stat_buf = s;
1321 if (err) *err = e;
1322 if (e)
1323 s = dflt;
1324
1325 return s;
1326 }
1327
1328
table_get_int(HTable table,char * field,int dflt,int * err)1329 int table_get_int(HTable table, char *field, int dflt, int *err)
1330 {
1331 SField *f;
1332 int v, e;
1333
1334 f = find_field(table, field);
1335 if (! f)
1336 {
1337 if (err) *err = 1;
1338 return dflt;
1339 }
1340
1341 v = get_field_int(f, &e);
1342 if (err) *err = e;
1343 if (e)
1344 v = dflt;
1345
1346 return v;
1347 }
1348
1349
table_get_double(HTable table,char * field,double dflt,int * err)1350 double table_get_double(HTable table, char *field, double dflt, int *err)
1351 {
1352 SField *f;
1353 double v;
1354 int e;
1355
1356 f = find_field(table, field);
1357 if (! f)
1358 {
1359 if (err) *err = 1;
1360 return dflt;
1361 }
1362
1363 v = get_field_double(f, &e);
1364 if (err) *err = e;
1365 if (e)
1366 v = dflt;
1367
1368 return v;
1369 }
1370
1371
table_get_table(HTable table,char * field,HTable dflt,int * err)1372 HTable table_get_table(HTable table, char *field, HTable dflt, int *err)
1373 {
1374 SField *f;
1375 HTable v;
1376
1377 f = find_field(table, field);
1378 if ((! f) || (f->type != TYPE_TABLE))
1379 {
1380 if (err) *err = 1;
1381 return dflt;
1382 }
1383
1384 v = f->value.table_value;
1385 if (err) *err = 0;
1386
1387 return v;
1388 }
1389
1390
table_append_str(HTable table,const char * val)1391 int table_append_str(HTable table, const char *val)
1392 {
1393 int idx;
1394 char b[100];
1395
1396 if ((! table) || (! val))
1397 return -1;
1398
1399 idx = get_next_index(table);
1400 sprintf(b, "%i", idx);
1401 table_set_str(table, b, val);
1402 return 0;
1403 }
1404
1405
table_append_int(HTable table,int val)1406 int table_append_int(HTable table, int val)
1407 {
1408 int idx;
1409 char b[100];
1410
1411 if ((! table) || (! val))
1412 return -1;
1413
1414 idx = get_next_index(table);
1415 sprintf(b, "%i", idx);
1416 table_set_int(table, b, val);
1417 return 0;
1418 }
1419
1420
table_append_double(HTable table,double val)1421 int table_append_double(HTable table, double val)
1422 {
1423 int idx;
1424 char b[100];
1425
1426 if ((! table) || (! val))
1427 return -1;
1428
1429 idx = get_next_index(table);
1430 sprintf(b, "%i", idx);
1431 table_set_double(table, b, val);
1432 return 0;
1433 }
1434
1435
table_append_table(HTable table,HTable val)1436 int table_append_table(HTable table, HTable val)
1437 {
1438 int idx;
1439 char b[100];
1440
1441 if ((! table) || (! val))
1442 return -1;
1443
1444 idx = get_next_index(table);
1445 sprintf(b, "%i", idx);
1446 table_set_table(table, b, val);
1447 return 0;
1448 }
1449
1450