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 275
 			token->end.line, token->end.col);
275 276
 		pkg_free(buf);
276 277
 	}
278
+#endif /* EXTRA_DEBUG */
277 279
 }
278 280
 
281
+
279 282
 int cfg_get_token(cfg_token_t* token, cfg_parser_t* st, unsigned int flags)
280 283
 {
281 284
 	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 484
 	case ST_S: 
482 485
 	case ST_C:
483 486
 	case ST_CE:
484
-		return 0;
487
+		return 1;
485 488
 
486 489
 	case ST_A:
487 490
 		RETURN(CFG_TOKEN_ALPHA);
... ...
@@ -508,37 +511,18 @@ int cfg_parse_section(void* param, cfg_parser_t* st, unsigned int flags)
508 511
 {
509 512
 	cfg_token_t t;
510 513
 	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 514
 
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;
515
+	ret = cfg_parse_str(param, st, flags);
516
+	if (ret < 0) return ret;
517
+	if (ret > 0) {
518
+		ERR("%s:%d:%d: Section name missing.\n",
519
+			st->file, st->line, st->col);
520
+		return ret;
531 521
 	}
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 522
 
539
-	ret = cfg_get_token(&t, st, 0);
523
+	ret = cfg_get_token(&t, st, flags);
540 524
 	if (ret < 0) goto error;
541
-	if (ret == 0) {
525
+	if (ret > 0) {
542 526
 		ERR("%s:%d:%d: Closing ']' missing\n", st->file, st->line, st->col);
543 527
 		goto error;
544 528
 	}
... ...
@@ -547,10 +531,23 @@ int cfg_parse_section(void* param, cfg_parser_t* st, unsigned int flags)
547 531
 		    st->file, t.start.line, t.start.col);
548 532
 		goto error;
549 533
 	}
534
+
535
+	if (cfg_eat_eol(st, flags)) goto error;
550 536
 	return 0;
551 537
 
552 538
  error:
553
-	if (name->s) pkg_free(name->s);
539
+	if (param && ((str*)param)->s) {
540
+		if (flags & CFG_STR_PKGMEM) {
541
+			pkg_free(((str*)param)->s);
542
+			((str*)param)->s = NULL;
543
+		} else if (flags & CFG_STR_SHMMEM) {
544
+			shm_free(((str*)param)->s);
545
+			((str*)param)->s = NULL;
546
+		} else if (flags & CFG_STR_MALLOC) {
547
+			free(((str*)param)->s);
548
+			((str*)param)->s = NULL;
549
+		}		
550
+	}
554 551
 	return -1;
555 552
 }
556 553
 
... ...
@@ -679,7 +676,8 @@ int cfg_parse(cfg_parser_t* st)
679 676
 
680 677
 	while(1) {
681 678
 		ret = cfg_get_token(&t, st, 0);
682
-		if (ret <= 0) return ret;
679
+		if (ret < 0) return ret;
680
+		if (ret > 0) break;
683 681
 
684 682
 		switch(t.type) {
685 683
 		case CFG_TOKEN_ALPHA:
... ...
@@ -711,15 +709,6 @@ int cfg_parse(cfg_parser_t* st)
711 709
 			    st->file, t.start.line, t.start.col);
712 710
 			return -1;
713 711
 		}
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 712
 	}
724 713
 	return 0;
725 714
 }
... ...
@@ -728,7 +717,7 @@ int cfg_parse(cfg_parser_t* st)
728 717
 cfg_option_t* cfg_lookup_token(cfg_option_t* table, str* token)
729 718
 {
730 719
 	int len, i;
731
-	int (*cmp)(const char* s12, const char* s2, size_t n) = NULL;
720
+	int (*cmp)(const char* s1, const char* s2, size_t n) = NULL;
732 721
 
733 722
 
734 723
 	if (table == NULL) return NULL;
... ...
@@ -755,17 +744,17 @@ cfg_option_t* cfg_lookup_token(cfg_option_t* table, str* token)
755 744
 }
756 745
 
757 746
 
758
-int cfg_eat_equal(cfg_parser_t* st)
747
+int cfg_eat_equal(cfg_parser_t* st, unsigned int flags)
759 748
 {
760 749
 	cfg_token_t t;
761 750
 	int ret;
762 751
 
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", 
752
+	ret = cfg_get_token(&t, st, flags);
753
+	if (ret < 0) return ret;
754
+	if (ret > 0) {
755
+		ERR("%s:%d:%d: Delimiter '=' missing\n", 
767 756
 		    st->file, st->line, st->col);
768
-		return -1;
757
+		return ret;
769 758
 	}
770 759
 
771 760
 	if (t.type != '=') {
... ...
@@ -777,7 +766,25 @@ int cfg_eat_equal(cfg_parser_t* st)
777 766
 }
778 767
 
779 768
 
780
-int cfg_parse_enum_val(void* param, cfg_parser_t* st, unsigned int flags)
769
+int cfg_eat_eol(cfg_parser_t* st, unsigned int flags)
770
+{
771
+	cfg_token_t t;
772
+	int ret;
773
+
774
+	/* Skip EOL */
775
+	ret = cfg_get_token(&t, st, 0);
776
+	if (ret < 0) return ret;
777
+	if (ret > 0) return 0;
778
+	if (t.type != '\n') {
779
+		ERR("%s:%d:%d: End of line expected\n", 
780
+			st->file, t.start.line, t.start.col);
781
+		return -1;
782
+	}
783
+	return 0;
784
+}
785
+
786
+
787
+int cfg_parse_enum(void* param, cfg_parser_t* st, unsigned int flags)
781 788
 {
782 789
 	int ret;
783 790
     cfg_token_t t;
... ...
@@ -785,25 +792,18 @@ int cfg_parse_enum_val(void* param, cfg_parser_t* st, unsigned int flags)
785 792
 	
786 793
 	values = (cfg_option_t*)param;
787 794
 
788
-	if (cfg_eat_equal(st)) return -1;
795
+	ret = cfg_get_token(&t, st, flags);
796
+	if (ret != 0) return ret;
789 797
 
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 798
 	if (t.type != CFG_TOKEN_ALPHA && t.type != CFG_TOKEN_STRING) {
799
-		ERR("%s:%d:%d: Invalid option value '%.*s'\n",
799
+		ERR("%s:%d:%d: Invalid enum value '%.*s'\n",
800 800
 		    st->file, t.start.line, t.start.col, STR_FMT(&t.val));
801 801
 		return -1;
802 802
 	}
803 803
 
804 804
 	if (values) {
805 805
 		if ((val = cfg_lookup_token(values, &t.val)) == NULL) {
806
-			ERR("%s:%d:%d Unsupported option value '%.*s'\n", 
806
+			ERR("%s:%d:%d Unsupported enum value '%.*s'\n", 
807 807
 				st->file, t.start.line, t.start.col, STR_FMT(&t.val));
808 808
 			return -1;
809 809
 		}
... ...
@@ -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 892
 }
882 893
 
883 894
 
895
+int cfg_parse_str_opt(void* param, cfg_parser_t* st, unsigned int flags)
896
+{
897
+	int ret;
898
+
899
+	if (cfg_eat_equal(st, flags)) return -1;
900
+
901
+	ret = cfg_parse_str(param, st, flags | CFG_EXTENDED_ALPHA);
902
+	if (ret > 0) {
903
+		ERR("%s:%d:%d: Option value missing\n",
904
+		    st->file, st->line, st->col);
905
+	} else if (ret < 0) return ret;
906
+
907
+	if (cfg_eat_eol(st, flags)) return -1;
908
+	return 0;
909
+}
884 910
 
885
-int cfg_parse_int_val(void* param, cfg_parser_t* st, unsigned int flags)
911
+
912
+int cfg_parse_int(void* param, cfg_parser_t* st, unsigned int flags)
886 913
 {
887 914
 	int* val;
888 915
 	int ret, tmp;
... ...
@@ -890,18 +917,11 @@ int cfg_parse_int_val(void* param, cfg_parser_t* st, unsigned int flags)
890 917
 
891 918
 	val = (int*)param;
892 919
 
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
-	}
920
+	ret = cfg_get_token(&t, st, flags);
921
+	if (ret != 0) return ret;
902 922
 
903 923
 	if (t.type != CFG_TOKEN_ALPHA && t.type != CFG_TOKEN_STRING) {
904
-		ERR("%s:%d:%d: Invalid option value '%.*s', integer expected\n", 
924
+		ERR("%s:%d:%d: Invalid integer value '%.*s'\n", 
905 925
 		    st->file, t.start.line, t.start.col, STR_FMT(&t.val));
906 926
 		return -1;
907 927
 	}
... ...
@@ -917,7 +937,24 @@ int cfg_parse_int_val(void* param, cfg_parser_t* st, unsigned int flags)
917 937
 }
918 938
 
919 939
 
920
-int cfg_parse_bool_val(void* param, cfg_parser_t* st, unsigned int flags)
940
+int cfg_parse_int_opt(void* param, cfg_parser_t* st, unsigned int flags)
941
+{
942
+	int ret;
943
+
944
+	if (cfg_eat_equal(st, flags)) return -1;
945
+
946
+	ret = cfg_parse_int(param, st, flags);
947
+	if (ret > 0) {
948
+		ERR("%s:%d:%d: Option value missing\n", 
949
+		    st->file, st->line, st->col);
950
+	} else if (ret < 0) return ret;
951
+
952
+	if (cfg_eat_eol(st, flags)) return -1;
953
+	return 0;
954
+}
955
+
956
+
957
+int cfg_parse_bool(void* param, cfg_parser_t* st, unsigned int flags)
921 958
 {
922 959
 	int ret, *val;
923 960
 	cfg_token_t t;
... ...
@@ -925,27 +962,8 @@ int cfg_parse_bool_val(void* param, cfg_parser_t* st, unsigned int flags)
925 962
 	
926 963
 	val = (int*)param;
927 964
 
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
-	}
965
+	ret = cfg_get_token(&t, st, flags);
966
+	if (ret != 0) return ret;
949 967
 
950 968
 	if (t.type != CFG_TOKEN_ALPHA && t.type != CFG_TOKEN_STRING) {
951 969
 		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 980
 	if (val) *val = map->val;
963 981
 	return 0;
964 982
 }
983
+
984
+
985
+int cfg_parse_bool_opt(void* param, cfg_parser_t* st, unsigned int flags)
986
+{
987
+	int ret;
988
+	if (cfg_eat_equal(st, flags)) return -1;
989
+
990
+    ret = cfg_parse_bool(param, st, CFG_EXTENDED_ALPHA | flags);
991
+	if (ret > 0) {
992
+		ERR("%s:%d:%d: Option value missing\n", 
993
+		    st->file, st->line, st->col);
994
+	} else if (ret < 0) return ret;
995
+
996
+	if (cfg_eat_eol(st, flags)) return -1;
997
+	return 0;
998
+}
... ...
@@ -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 167
 int cfg_parse_section(void* param, struct cfg_parser* st, unsigned int flags);
166 168
 
167 169
 /* Parse string parameter value, either quoted or unquoted */
168
-int cfg_parse_str_val(void* param, struct cfg_parser* st, unsigned int flags);
170
+int cfg_parse_str_opt(void* param, struct cfg_parser* st, unsigned int flags);
171
+
172
+int cfg_parse_str(void* param, struct cfg_parser* st, unsigned int flags);
173
+
174
+int cfg_parse_enum_opt(void* param, struct cfg_parser* st, unsigned int flags);
169 175
 
170
-int cfg_parse_enum_val(void* param, struct cfg_parser* st, unsigned int flags);
176
+int cfg_parse_enum(void* param, struct cfg_parser* st, unsigned int flags);
171 177
 
172 178
 /* Parser integer parameter value */
173
-int cfg_parse_int_val(void* param, struct cfg_parser* st, unsigned int flags);
179
+int cfg_parse_int_opt(void* param, struct cfg_parser* st, unsigned int flags);
180
+
181
+int cfg_parse_int(void* param, struct cfg_parser* st, unsigned int flags);
174 182
 
175 183
 /* Parse boolean parameter value */
176
-int cfg_parse_bool_val(void* param, struct cfg_parser* st, unsigned int flags);
184
+int cfg_parse_bool_opt(void* param, struct cfg_parser* st, unsigned int flags);
185
+
186
+int cfg_parse_bool(void* param, struct cfg_parser* st, unsigned int flags);
177 187
 
178 188
 #endif /* _CFG_PARSER_H */