Browse code

- return values unified - print token info only when EXTRA_DEBUG is defined - cfg_get_token calls accept flags from the parent function - cfg_eat_eol implemented - parser functions are supposed to handle EOL themselves - various flags implemented to tell parser functions how to return strings (pkgmem, shmmem, malloc, static buf) - *_opt functions parse the whole option body, every of them has an alternative without _opt suffix which parses one token. - cfg_parse_section accepts memory allocation flags just like cfg_parse_str

Jan Janak authored on 11/06/2008 11:08:30
Showing 2 changed files
... ...
@@ -214,7 +214,7 @@ enum st {
214 214
     token->end.col = st->col;   \
215 215
     token->type = (c);          \
216 216
     print_token(token);         \
217
-    return 1;
217
+    return 0;
218 218
 
219 219
 
220 220
 /*
... ...
@@ -252,6 +252,7 @@ static void print_token(cfg_token_t* token)
252 252
 	int i, j;
253 253
 	char* buf;
254 254
 
255
+#ifdef EXTRA_DEBUG
255 256
 	if ((buf = pkg_malloc(token->val.len * 2)) == NULL) {
256 257
 		DBG("token(%d, '%.*s', <%d,%d>-<%d,%d>)\n", 
257 258
 			token->type, STR_FMT(&token->val),
... ...
@@ -274,8 +275,10 @@ static void print_token(cfg_token_t* token)
274 274
 			token->end.line, token->end.col);
275 275
 		pkg_free(buf);
276 276
 	}
277
+#endif /* EXTRA_DEBUG */
277 278
 }
278 279
 
280
+
279 281
 int cfg_get_token(cfg_token_t* token, cfg_parser_t* st, unsigned int flags)
280 282
 {
281 283
 	static int look_ahead = EOF;
... ...
@@ -481,7 +484,7 @@ int cfg_get_token(cfg_token_t* token, cfg_parser_t* st, unsigned int flags)
481 481
 	case ST_S: 
482 482
 	case ST_C:
483 483
 	case ST_CE:
484
-		return 0;
484
+		return 1;
485 485
 
486 486
 	case ST_A:
487 487
 		RETURN(CFG_TOKEN_ALPHA);
... ...
@@ -508,37 +511,18 @@ int cfg_parse_section(void* param, cfg_parser_t* st, unsigned int flags)
508 508
 {
509 509
 	cfg_token_t t;
510 510
 	int ret;
511
-	str* name;
512
-
513
-	name = (str*)param;
514
-	if (name == NULL) {
515
-		BUG("cfg_parser: Invalid parameter value to cfg_parse_section\n");
516
-		return -1;
517
-	}
518
-
519
-	ret = cfg_get_token(&t, st, 0);
520
-	if (ret < 0) return -1;
521
-	if (ret == 0) {
522
-		ERR("%s:%d:%d: Section name missing.\n", st->file, st->line, st->col);
523
-		return -1;
524
-	}
525 511
 
526
-	if (t.type != CFG_TOKEN_ALPHA) {
527
-		ERR("%s:%d:%d: Invalid table name %d:'%.*s'\n", 
528
-		    st->file, t.start.line, t.start.col,
529
-		    t.type, STR_FMT(&t.val));
530
-		return -1;
512
+	ret = cfg_parse_str(param, st, flags);
513
+	if (ret < 0) return ret;
514
+	if (ret > 0) {
515
+		ERR("%s:%d:%d: Section name missing.\n",
516
+			st->file, st->line, st->col);
517
+		return ret;
531 518
 	}
532
-	
533
-	if ((name->s = as_asciiz(&t.val)) == NULL) {
534
-		ERR("%s:%d:%d: Out of memory\n", st->file, t.start.line, t.start.col);
535
-		return -1;
536
-	}
537
-	name->len = t.val.len;
538 519
 
539
-	ret = cfg_get_token(&t, st, 0);
520
+	ret = cfg_get_token(&t, st, flags);
540 521
 	if (ret < 0) goto error;
541
-	if (ret == 0) {
522
+	if (ret > 0) {
542 523
 		ERR("%s:%d:%d: Closing ']' missing\n", st->file, st->line, st->col);
543 524
 		goto error;
544 525
 	}
... ...
@@ -547,10 +531,23 @@ int cfg_parse_section(void* param, cfg_parser_t* st, unsigned int flags)
547 547
 		    st->file, t.start.line, t.start.col);
548 548
 		goto error;
549 549
 	}
550
+
551
+	if (cfg_eat_eol(st, flags)) goto error;
550 552
 	return 0;
551 553
 
552 554
  error:
553
-	if (name->s) pkg_free(name->s);
555
+	if (param && ((str*)param)->s) {
556
+		if (flags & CFG_STR_PKGMEM) {
557
+			pkg_free(((str*)param)->s);
558
+			((str*)param)->s = NULL;
559
+		} else if (flags & CFG_STR_SHMMEM) {
560
+			shm_free(((str*)param)->s);
561
+			((str*)param)->s = NULL;
562
+		} else if (flags & CFG_STR_MALLOC) {
563
+			free(((str*)param)->s);
564
+			((str*)param)->s = NULL;
565
+		}		
566
+	}
554 567
 	return -1;
555 568
 }
556 569
 
... ...
@@ -679,7 +676,8 @@ int cfg_parse(cfg_parser_t* st)
679 679
 
680 680
 	while(1) {
681 681
 		ret = cfg_get_token(&t, st, 0);
682
-		if (ret <= 0) return ret;
682
+		if (ret < 0) return ret;
683
+		if (ret > 0) break;
683 684
 
684 685
 		switch(t.type) {
685 686
 		case CFG_TOKEN_ALPHA:
... ...
@@ -711,15 +709,6 @@ int cfg_parse(cfg_parser_t* st)
711 711
 			    st->file, t.start.line, t.start.col);
712 712
 			return -1;
713 713
 		}
714
-
715
-		     /* Skip EOL */
716
-		ret = cfg_get_token(&t, st, 0);
717
-		if (ret <= 0) return ret;
718
-		if (t.type != '\n') {
719
-			ERR("%s:%d:%d: End of line expected\n", 
720
-			    st->file, t.start.line, t.start.col);
721
-			return -1;
722
-		}
723 714
 	}
724 715
 	return 0;
725 716
 }
... ...
@@ -728,7 +717,7 @@ int cfg_parse(cfg_parser_t* st)
728 728
 cfg_option_t* cfg_lookup_token(cfg_option_t* table, str* token)
729 729
 {
730 730
 	int len, i;
731
-	int (*cmp)(const char* s12, const char* s2, size_t n) = NULL;
731
+	int (*cmp)(const char* s1, const char* s2, size_t n) = NULL;
732 732
 
733 733
 
734 734
 	if (table == NULL) return NULL;
... ...
@@ -755,17 +744,17 @@ cfg_option_t* cfg_lookup_token(cfg_option_t* table, str* token)
755 755
 }
756 756
 
757 757
 
758
-int cfg_eat_equal(cfg_parser_t* st)
758
+int cfg_eat_equal(cfg_parser_t* st, unsigned int flags)
759 759
 {
760 760
 	cfg_token_t t;
761 761
 	int ret;
762 762
 
763
-	ret = cfg_get_token(&t, st, 0);
764
-	if (ret < 0) return -1;
765
-	if (ret == 0) {
766
-		ERR("%s:%d:%d: Option value missing\n", 
763
+	ret = cfg_get_token(&t, st, flags);
764
+	if (ret < 0) return ret;
765
+	if (ret > 0) {
766
+		ERR("%s:%d:%d: Delimiter '=' missing\n", 
767 767
 		    st->file, st->line, st->col);
768
-		return -1;
768
+		return ret;
769 769
 	}
770 770
 
771 771
 	if (t.type != '=') {
... ...
@@ -777,7 +766,25 @@ int cfg_eat_equal(cfg_parser_t* st)
777 777
 }
778 778
 
779 779
 
780
-int cfg_parse_enum_val(void* param, cfg_parser_t* st, unsigned int flags)
780
+int cfg_eat_eol(cfg_parser_t* st, unsigned int flags)
781
+{
782
+	cfg_token_t t;
783
+	int ret;
784
+
785
+	/* Skip EOL */
786
+	ret = cfg_get_token(&t, st, 0);
787
+	if (ret < 0) return ret;
788
+	if (ret > 0) return 0;
789
+	if (t.type != '\n') {
790
+		ERR("%s:%d:%d: End of line expected\n", 
791
+			st->file, t.start.line, t.start.col);
792
+		return -1;
793
+	}
794
+	return 0;
795
+}
796
+
797
+
798
+int cfg_parse_enum(void* param, cfg_parser_t* st, unsigned int flags)
781 799
 {
782 800
 	int ret;
783 801
     cfg_token_t t;
... ...
@@ -785,25 +792,18 @@ int cfg_parse_enum_val(void* param, cfg_parser_t* st, unsigned int flags)
785 785
 	
786 786
 	values = (cfg_option_t*)param;
787 787
 
788
-	if (cfg_eat_equal(st)) return -1;
788
+	ret = cfg_get_token(&t, st, flags);
789
+	if (ret != 0) return ret;
789 790
 
790
-	ret = cfg_get_token(&t, st, CFG_EXTENDED_ALPHA);
791
-	if (ret < 0) return -1;
792
-	if (ret == 0) {
793
-		ERR("%s:%d:%d: Option value missing\n",
794
-		    st->file, st->line, st->col);
795
-		return -1;
796
-	}
797
-	
798 791
 	if (t.type != CFG_TOKEN_ALPHA && t.type != CFG_TOKEN_STRING) {
799
-		ERR("%s:%d:%d: Invalid option value '%.*s'\n",
792
+		ERR("%s:%d:%d: Invalid enum value '%.*s'\n",
800 793
 		    st->file, t.start.line, t.start.col, STR_FMT(&t.val));
801 794
 		return -1;
802 795
 	}
803 796
 
804 797
 	if (values) {
805 798
 		if ((val = cfg_lookup_token(values, &t.val)) == NULL) {
806
-			ERR("%s:%d:%d Unsupported option value '%.*s'\n", 
799
+			ERR("%s:%d:%d Unsupported enum value '%.*s'\n", 
807 800
 				st->file, t.start.line, t.start.col, STR_FMT(&t.val));
808 801
 			return -1;
809 802
 		}
... ...
@@ -814,25 +814,36 @@ int cfg_parse_enum_val(void* param, cfg_parser_t* st, unsigned int flags)
814 814
 }
815 815
 
816 816
 
817
-int cfg_parse_str_val(void* param, cfg_parser_t* st, unsigned int flags)
817
+int cfg_parse_enum_opt(void* param, cfg_parser_t* st, unsigned int flags)
818
+{
819
+	int ret;
820
+
821
+	if (cfg_eat_equal(st, flags)) return -1;
822
+
823
+	ret = cfg_parse_enum(param, st, CFG_EXTENDED_ALPHA | flags);
824
+	if (ret > 0) {
825
+		ERR("%s:%d:%d: Option value missing\n",
826
+		    st->file, st->line, st->col);
827
+		return ret;
828
+	} else if (ret < 0) return ret;
829
+
830
+	if (cfg_eat_eol(st, flags)) return -1;
831
+	return 0;
832
+}
833
+
834
+
835
+int cfg_parse_str(void* param, cfg_parser_t* st, unsigned int flags)
818 836
 {
819 837
 	str* val;
820 838
 	int ret;
821 839
 	char* buf;
822 840
     cfg_token_t t;
823 841
 	
824
-	if (cfg_eat_equal(st)) return -1;
825
-
826
-	ret = cfg_get_token(&t, st, CFG_EXTENDED_ALPHA);
827
-	if (ret < 0) return -1;
828
-	if (ret == 0) {
829
-		ERR("%s:%d:%d: Option value missing\n",
830
-		    st->file, t.start.line, t.start.col);
831
-		return -1;
832
-	}
842
+	ret = cfg_get_token(&t, st, flags);
843
+	if (ret != 0) return ret;
833 844
 	
834 845
 	if (t.type != CFG_TOKEN_ALPHA && t.type != CFG_TOKEN_STRING) {
835
-		ERR("%s:%d:%d: Invalid option value '%.*s'\n",
846
+		ERR("%s:%d:%d: Invalid string value '%.*s', a string expected.\n",
836 847
 		    st->file, t.start.line, t.start.col, STR_FMT(&t.val));
837 848
 		return -1;
838 849
 	}
... ...
@@ -881,8 +892,24 @@ int cfg_parse_str_val(void* param, cfg_parser_t* st, unsigned int flags)
881 881
 }
882 882
 
883 883
 
884
+int cfg_parse_str_opt(void* param, cfg_parser_t* st, unsigned int flags)
885
+{
886
+	int ret;
887
+
888
+	if (cfg_eat_equal(st, flags)) return -1;
889
+
890
+	ret = cfg_parse_str(param, st, flags | CFG_EXTENDED_ALPHA);
891
+	if (ret > 0) {
892
+		ERR("%s:%d:%d: Option value missing\n",
893
+		    st->file, st->line, st->col);
894
+	} else if (ret < 0) return ret;
895
+
896
+	if (cfg_eat_eol(st, flags)) return -1;
897
+	return 0;
898
+}
884 899
 
885
-int cfg_parse_int_val(void* param, cfg_parser_t* st, unsigned int flags)
900
+
901
+int cfg_parse_int(void* param, cfg_parser_t* st, unsigned int flags)
886 902
 {
887 903
 	int* val;
888 904
 	int ret, tmp;
... ...
@@ -890,18 +917,11 @@ int cfg_parse_int_val(void* param, cfg_parser_t* st, unsigned int flags)
890 890
 
891 891
 	val = (int*)param;
892 892
 
893
-	if (cfg_eat_equal(st)) return -1;
894
-	
895
-	ret = cfg_get_token(&t, st, CFG_EXTENDED_ALPHA);
896
-	if (ret < 0) return -1;
897
-	if (ret == 0) {
898
-		ERR("%s:%d:%d: Option value missing\n", 
899
-		    st->file, t.start.line, t.start.col);
900
-		return -1;
901
-	}
893
+	ret = cfg_get_token(&t, st, flags);
894
+	if (ret != 0) return ret;
902 895
 
903 896
 	if (t.type != CFG_TOKEN_ALPHA && t.type != CFG_TOKEN_STRING) {
904
-		ERR("%s:%d:%d: Invalid option value '%.*s', integer expected\n", 
897
+		ERR("%s:%d:%d: Invalid integer value '%.*s'\n", 
905 898
 		    st->file, t.start.line, t.start.col, STR_FMT(&t.val));
906 899
 		return -1;
907 900
 	}
... ...
@@ -917,7 +937,24 @@ int cfg_parse_int_val(void* param, cfg_parser_t* st, unsigned int flags)
917 917
 }
918 918
 
919 919
 
920
-int cfg_parse_bool_val(void* param, cfg_parser_t* st, unsigned int flags)
920
+int cfg_parse_int_opt(void* param, cfg_parser_t* st, unsigned int flags)
921
+{
922
+	int ret;
923
+
924
+	if (cfg_eat_equal(st, flags)) return -1;
925
+
926
+	ret = cfg_parse_int(param, st, flags);
927
+	if (ret > 0) {
928
+		ERR("%s:%d:%d: Option value missing\n", 
929
+		    st->file, st->line, st->col);
930
+	} else if (ret < 0) return ret;
931
+
932
+	if (cfg_eat_eol(st, flags)) return -1;
933
+	return 0;
934
+}
935
+
936
+
937
+int cfg_parse_bool(void* param, cfg_parser_t* st, unsigned int flags)
921 938
 {
922 939
 	int ret, *val;
923 940
 	cfg_token_t t;
... ...
@@ -925,27 +962,8 @@ int cfg_parse_bool_val(void* param, cfg_parser_t* st, unsigned int flags)
925 925
 	
926 926
 	val = (int*)param;
927 927
 
928
-	ret = cfg_get_token(&t, st, 0);
929
-	if (ret < 0) return -1;
930
-	if (ret == 0) {
931
-		ERR("%s:%d:%d: Option value missing\n", 
932
-		    st->file, t.start.line, t.start.col);
933
-		return -1;
934
-	}
935
-	
936
-	if (t.type != '=') {
937
-		ERR("%s:%d:%d: Syntax error, '=' expected\n", 
938
-		    st->file, t.start.line, t.start.col);
939
-		return -1;
940
-	}
941
-
942
-	ret = cfg_get_token(&t, st, CFG_EXTENDED_ALPHA);
943
-	if (ret < 0) return -1;
944
-	if (ret == 0) {
945
-		ERR("%s:%d:%d: Option value missing\n", 
946
-		    st->file, t.start.line, t.start.col);
947
-		return -1;
948
-	}
928
+	ret = cfg_get_token(&t, st, flags);
929
+	if (ret != 0) return ret;
949 930
 
950 931
 	if (t.type != CFG_TOKEN_ALPHA && t.type != CFG_TOKEN_STRING) {
951 932
 		ERR("%s:%d:%d: Invalid option value '%.*s', boolean expected\n", 
... ...
@@ -962,3 +980,19 @@ int cfg_parse_bool_val(void* param, cfg_parser_t* st, unsigned int flags)
962 962
 	if (val) *val = map->val;
963 963
 	return 0;
964 964
 }
965
+
966
+
967
+int cfg_parse_bool_opt(void* param, cfg_parser_t* st, unsigned int flags)
968
+{
969
+	int ret;
970
+	if (cfg_eat_equal(st, flags)) return -1;
971
+
972
+    ret = cfg_parse_bool(param, st, CFG_EXTENDED_ALPHA | flags);
973
+	if (ret > 0) {
974
+		ERR("%s:%d:%d: Option value missing\n", 
975
+		    st->file, st->line, st->col);
976
+	} else if (ret < 0) return ret;
977
+
978
+	if (cfg_eat_eol(st, flags)) return -1;
979
+	return 0;
980
+}
... ...
@@ -156,7 +156,9 @@ int cfg_get_token(struct cfg_token* token, struct cfg_parser* st, unsigned int f
156 156
 
157 157
 /* Commonly needed parser functions */
158 158
 
159
-int cfg_eat_equal(struct cfg_parser* st);
159
+int cfg_eat_equal(struct cfg_parser* st, unsigned int flags);
160
+
161
+int cfg_eat_eol(struct cfg_parser* st, unsigned int flags);
160 162
 
161 163
 /* Parse section identifier of form [section]. The function expects parameter
162 164
  * param to be of type (str*). The result string is allocated using pkg_malloc
... ...
@@ -165,14 +167,22 @@ int cfg_eat_equal(struct cfg_parser* st);
165 165
 int cfg_parse_section(void* param, struct cfg_parser* st, unsigned int flags);
166 166
 
167 167
 /* Parse string parameter value, either quoted or unquoted */
168
-int cfg_parse_str_val(void* param, struct cfg_parser* st, unsigned int flags);
168
+int cfg_parse_str_opt(void* param, struct cfg_parser* st, unsigned int flags);
169
+
170
+int cfg_parse_str(void* param, struct cfg_parser* st, unsigned int flags);
171
+
172
+int cfg_parse_enum_opt(void* param, struct cfg_parser* st, unsigned int flags);
169 173
 
170
-int cfg_parse_enum_val(void* param, struct cfg_parser* st, unsigned int flags);
174
+int cfg_parse_enum(void* param, struct cfg_parser* st, unsigned int flags);
171 175
 
172 176
 /* Parser integer parameter value */
173
-int cfg_parse_int_val(void* param, struct cfg_parser* st, unsigned int flags);
177
+int cfg_parse_int_opt(void* param, struct cfg_parser* st, unsigned int flags);
178
+
179
+int cfg_parse_int(void* param, struct cfg_parser* st, unsigned int flags);
174 180
 
175 181
 /* Parse boolean parameter value */
176
-int cfg_parse_bool_val(void* param, struct cfg_parser* st, unsigned int flags);
182
+int cfg_parse_bool_opt(void* param, struct cfg_parser* st, unsigned int flags);
183
+
184
+int cfg_parse_bool(void* param, struct cfg_parser* st, unsigned int flags);
177 185
 
178 186
 #endif /* _CFG_PARSER_H */