Mercurial > mplayer.hg
annotate parser-cfg.c @ 18049:77a3b0d11ca5
Limit the number of entires to the amount that does fit into the chunk.
the function need rewrite as it assumes quite many things that are not guaranteed by the specifications.
author | iive |
---|---|
date | Thu, 06 Apr 2006 20:04:02 +0000 |
parents | 63909962d3fc |
children | 1a14fde7680d |
rev | line source |
---|---|
8164 | 1 #include "config.h" |
2 | |
3 #include <stdio.h> | |
4 #include <stdlib.h> | |
5 #include <string.h> | |
6 #include <errno.h> | |
7 #include <ctype.h> | |
8 | |
9 #ifdef MP_DEBUG | |
10 #include <assert.h> | |
11 #endif | |
12 | |
13 #include "mp_msg.h" | |
14 #include "m_option.h" | |
15 #include "m_config.h" | |
16 | |
17 #define MAX_RECURSION_DEPTH 8 | |
18 | |
19 static int recursion_depth = 0; | |
20 | |
21 int m_config_parse_config_file(m_config_t* config, char *conffile) | |
22 { | |
23 #define PRINT_LINENUM mp_msg(MSGT_CFGPARSER,MSGL_V,"%s(%d): ", conffile, line_num) | |
9813 | 24 #define MAX_LINE_LEN 10000 |
25 #define MAX_OPT_LEN 1000 | |
26 #define MAX_PARAM_LEN 1000 | |
8164 | 27 FILE *fp; |
28 char *line; | |
29 char opt[MAX_OPT_LEN + 1]; | |
30 char param[MAX_PARAM_LEN + 1]; | |
31 char c; /* for the "" and '' check */ | |
32 int tmp; | |
33 int line_num = 0; | |
34 int line_pos; /* line pos */ | |
35 int opt_pos; /* opt pos */ | |
36 int param_pos; /* param pos */ | |
37 int ret = 1; | |
38 int errors = 0; | |
39 int prev_mode = config->mode; | |
17471 | 40 m_profile_t* profile = NULL; |
8164 | 41 |
42 #ifdef MP_DEBUG | |
43 assert(config != NULL); | |
44 // assert(conf_list != NULL); | |
45 #endif | |
13946 | 46 mp_msg(MSGT_CFGPARSER,MSGL_V,"Reading config file %s", conffile); |
8164 | 47 |
48 if (recursion_depth > MAX_RECURSION_DEPTH) { | |
49 mp_msg(MSGT_CFGPARSER,MSGL_ERR,": too deep 'include'. check your configfiles\n"); | |
50 ret = -1; | |
51 goto out; | |
52 } else | |
53 | |
54 config->mode = M_CONFIG_FILE; | |
55 | |
56 if ((line = (char *) malloc(MAX_LINE_LEN + 1)) == NULL) { | |
57 mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"\ncan't get memory for 'line': %s", strerror(errno)); | |
58 ret = -1; | |
59 goto out; | |
60 } | |
61 | |
62 if ((fp = fopen(conffile, "r")) == NULL) { | |
13946 | 63 mp_msg(MSGT_CFGPARSER,MSGL_V,": %s\n", strerror(errno)); |
8164 | 64 free(line); |
65 ret = 0; | |
66 goto out; | |
67 } | |
68 mp_msg(MSGT_CFGPARSER,MSGL_INFO,"\n"); | |
69 | |
70 while (fgets(line, MAX_LINE_LEN, fp)) { | |
71 if (errors >= 16) { | |
72 mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"too many errors\n"); | |
73 goto out; | |
74 } | |
75 | |
76 line_num++; | |
77 line_pos = 0; | |
78 | |
79 /* skip whitespaces */ | |
80 while (isspace(line[line_pos])) | |
81 ++line_pos; | |
82 | |
83 /* EOL / comment */ | |
84 if (line[line_pos] == '\0' || line[line_pos] == '#') | |
85 continue; | |
86 | |
87 /* read option. */ | |
88 for (opt_pos = 0; isprint(line[line_pos]) && | |
89 line[line_pos] != ' ' && | |
90 line[line_pos] != '#' && | |
91 line[line_pos] != '='; /* NOTHING */) { | |
92 opt[opt_pos++] = line[line_pos++]; | |
93 if (opt_pos >= MAX_OPT_LEN) { | |
94 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
95 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long option at line %d\n",line_num); |
8164 | 96 errors++; |
97 ret = -1; | |
98 goto nextline; | |
99 } | |
100 } | |
101 if (opt_pos == 0) { | |
102 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
103 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"parse error at line %d\n",line_num); |
8164 | 104 ret = -1; |
105 errors++; | |
106 continue; | |
107 } | |
108 opt[opt_pos] = '\0'; | |
17471 | 109 |
110 /* Profile declaration */ | |
111 if(opt_pos > 2 && opt[0] == '[' && opt[opt_pos-1] == ']') { | |
112 opt[opt_pos-1] = '\0'; | |
113 if(strcmp(opt+1,"default")) | |
114 profile = m_config_add_profile(config,opt+1); | |
115 else | |
116 profile = NULL; | |
117 continue; | |
118 } | |
8164 | 119 |
120 #ifdef MP_DEBUG | |
121 PRINT_LINENUM; | |
122 mp_msg(MSGT_CFGPARSER,MSGL_V,"option: %s\n", opt); | |
123 #endif | |
124 | |
125 /* skip whitespaces */ | |
126 while (isspace(line[line_pos])) | |
127 ++line_pos; | |
128 | |
129 /* check '=' */ | |
130 if (line[line_pos++] != '=') { | |
131 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
132 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s needs a parameter at line %d\n",opt,line_num); |
8164 | 133 ret = -1; |
134 errors++; | |
135 continue; | |
136 } | |
137 | |
138 /* whitespaces... */ | |
139 while (isspace(line[line_pos])) | |
140 ++line_pos; | |
141 | |
142 /* read the parameter */ | |
143 if (line[line_pos] == '"' || line[line_pos] == '\'') { | |
144 c = line[line_pos]; | |
145 ++line_pos; | |
146 for (param_pos = 0; line[line_pos] != c; /* NOTHING */) { | |
147 param[param_pos++] = line[line_pos++]; | |
148 if (param_pos >= MAX_PARAM_LEN) { | |
149 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
150 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s has a too long parameter at line %d\n",opt,line_num); |
8164 | 151 ret = -1; |
152 errors++; | |
153 goto nextline; | |
154 } | |
155 } | |
156 line_pos++; /* skip the closing " or ' */ | |
157 } else { | |
158 for (param_pos = 0; isprint(line[line_pos]) && !isspace(line[line_pos]) | |
159 && line[line_pos] != '#'; /* NOTHING */) { | |
160 param[param_pos++] = line[line_pos++]; | |
161 if (param_pos >= MAX_PARAM_LEN) { | |
162 PRINT_LINENUM; | |
163 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long parameter\n"); | |
164 ret = -1; | |
165 errors++; | |
166 goto nextline; | |
167 } | |
168 } | |
169 } | |
170 param[param_pos] = '\0'; | |
171 | |
172 /* did we read a parameter? */ | |
173 if (param_pos == 0) { | |
174 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
175 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s needs a parameter at line %d\n",opt,line_num); |
8164 | 176 ret = -1; |
177 errors++; | |
178 continue; | |
179 } | |
180 | |
181 #ifdef MP_DEBUG | |
182 PRINT_LINENUM; | |
183 mp_msg(MSGT_CFGPARSER,MSGL_V,"parameter: %s\n", param); | |
184 #endif | |
185 | |
186 /* now, check if we have some more chars on the line */ | |
187 /* whitespace... */ | |
188 while (isspace(line[line_pos])) | |
189 ++line_pos; | |
190 | |
191 /* EOL / comment */ | |
192 if (line[line_pos] != '\0' && line[line_pos] != '#') { | |
193 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
194 mp_msg(MSGT_CFGPARSER,MSGL_WARN,"extra characters on line %d: %s\n",line_num, line+line_pos); |
8164 | 195 ret = -1; |
196 } | |
197 | |
17471 | 198 if(profile) { |
199 if(!strcmp(opt,"profile-desc")) | |
200 m_profile_set_desc(profile,param), tmp = 1; | |
201 else | |
202 tmp = m_config_set_profile_option(config,profile, | |
203 opt,param); | |
204 } else | |
205 tmp = m_config_set_option(config, opt, param); | |
8164 | 206 if (tmp < 0) { |
207 PRINT_LINENUM; | |
10595
522afd56703c
100l to albeu for his english grammar, and 10l to me becouse I noticed that lately (my backward compatibilty macro uses M_OPT_UNKNOWN)
alex
parents:
10594
diff
changeset
|
208 if(tmp == M_OPT_UNKNOWN) { |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
209 mp_msg(MSGT_CFGPARSER,MSGL_WARN,"Warning unknown option %s at line %d\n", opt,line_num); |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
210 continue; |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
211 } |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
212 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Error parsing option %s=%s at line %d\n",opt,param,line_num); |
8164 | 213 ret = -1; |
214 errors++; | |
215 continue; | |
216 /* break */ | |
217 } | |
218 nextline: | |
219 ; | |
220 } | |
221 | |
222 free(line); | |
223 fclose(fp); | |
224 out: | |
225 config->mode = prev_mode; | |
226 --recursion_depth; | |
227 return ret; | |
228 } |