Mercurial > mplayer.hg
annotate parser-cfg.c @ 29405:5edbab3df93b
stream/realrtsp/real.c: Fix integer overflow
Pointed-out-by: tixxDZ <tixxdz at gmail dot com> - DZCORE Labs, Algeria
author | uau |
---|---|
date | Mon, 27 Jul 2009 16:53:48 +0000 |
parents | 0f1b5b68af32 |
children | 8fd1ec0984b9 |
rev | line source |
---|---|
18265 | 1 |
2 /// \defgroup ConfigParsers Config parsers | |
3 /// | |
4 /// The \ref ConfigParsers make use of the \ref Config to setup the config variables, | |
5 /// the command line parsers also build the playlist. | |
6 ///@{ | |
7 | |
8 /// \file | |
9 | |
8164 | 10 #include "config.h" |
11 | |
12 #include <stdio.h> | |
13 #include <stdlib.h> | |
14 #include <string.h> | |
15 #include <errno.h> | |
16 #include <ctype.h> | |
17 | |
18 #ifdef MP_DEBUG | |
19 #include <assert.h> | |
20 #endif | |
21 | |
26263 | 22 #include "parser-cfg.h" |
8164 | 23 #include "mp_msg.h" |
24 #include "m_option.h" | |
25 #include "m_config.h" | |
26 | |
18265 | 27 /// Maximal include depth. |
8164 | 28 #define MAX_RECURSION_DEPTH 8 |
29 | |
18265 | 30 /// Current include depth. |
8164 | 31 static int recursion_depth = 0; |
32 | |
18265 | 33 /// Setup the \ref Config from a config file. |
34 /** \param config The config object. | |
35 * \param conffile Path to the config file. | |
36 * \return 1 on sucess, -1 on error. | |
37 */ | |
8164 | 38 int m_config_parse_config_file(m_config_t* config, char *conffile) |
39 { | |
40 #define PRINT_LINENUM mp_msg(MSGT_CFGPARSER,MSGL_V,"%s(%d): ", conffile, line_num) | |
9813 | 41 #define MAX_LINE_LEN 10000 |
42 #define MAX_OPT_LEN 1000 | |
21799
a6911070ac6e
increased a bit max param length as it can be too short to declare tv channels when you have a long list of
ben
parents:
19462
diff
changeset
|
43 #define MAX_PARAM_LEN 1500 |
8164 | 44 FILE *fp; |
45 char *line; | |
46 char opt[MAX_OPT_LEN + 1]; | |
47 char param[MAX_PARAM_LEN + 1]; | |
48 char c; /* for the "" and '' check */ | |
49 int tmp; | |
50 int line_num = 0; | |
51 int line_pos; /* line pos */ | |
52 int opt_pos; /* opt pos */ | |
53 int param_pos; /* param pos */ | |
54 int ret = 1; | |
55 int errors = 0; | |
56 int prev_mode = config->mode; | |
17471 | 57 m_profile_t* profile = NULL; |
8164 | 58 |
59 #ifdef MP_DEBUG | |
60 assert(config != NULL); | |
61 // assert(conf_list != NULL); | |
62 #endif | |
13946 | 63 mp_msg(MSGT_CFGPARSER,MSGL_V,"Reading config file %s", conffile); |
8164 | 64 |
65 if (recursion_depth > MAX_RECURSION_DEPTH) { | |
66 mp_msg(MSGT_CFGPARSER,MSGL_ERR,": too deep 'include'. check your configfiles\n"); | |
67 ret = -1; | |
68 goto out; | |
69 } else | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26408
diff
changeset
|
70 |
8164 | 71 config->mode = M_CONFIG_FILE; |
72 | |
23806 | 73 if ((line = malloc(MAX_LINE_LEN + 1)) == NULL) { |
8164 | 74 mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"\ncan't get memory for 'line': %s", strerror(errno)); |
75 ret = -1; | |
76 goto out; | |
19462
08fc089138f4
Fix stray newline that should only be printed in verbose mode.
diego
parents:
18265
diff
changeset
|
77 } else |
08fc089138f4
Fix stray newline that should only be printed in verbose mode.
diego
parents:
18265
diff
changeset
|
78 |
08fc089138f4
Fix stray newline that should only be printed in verbose mode.
diego
parents:
18265
diff
changeset
|
79 mp_msg(MSGT_CFGPARSER,MSGL_V,"\n"); |
8164 | 80 |
81 if ((fp = fopen(conffile, "r")) == NULL) { | |
13946 | 82 mp_msg(MSGT_CFGPARSER,MSGL_V,": %s\n", strerror(errno)); |
8164 | 83 free(line); |
84 ret = 0; | |
85 goto out; | |
86 } | |
87 | |
88 while (fgets(line, MAX_LINE_LEN, fp)) { | |
89 if (errors >= 16) { | |
90 mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"too many errors\n"); | |
91 goto out; | |
92 } | |
93 | |
94 line_num++; | |
95 line_pos = 0; | |
96 | |
97 /* skip whitespaces */ | |
98 while (isspace(line[line_pos])) | |
99 ++line_pos; | |
100 | |
101 /* EOL / comment */ | |
102 if (line[line_pos] == '\0' || line[line_pos] == '#') | |
103 continue; | |
104 | |
105 /* read option. */ | |
106 for (opt_pos = 0; isprint(line[line_pos]) && | |
107 line[line_pos] != ' ' && | |
108 line[line_pos] != '#' && | |
109 line[line_pos] != '='; /* NOTHING */) { | |
110 opt[opt_pos++] = line[line_pos++]; | |
111 if (opt_pos >= MAX_OPT_LEN) { | |
112 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
113 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long option at line %d\n",line_num); |
8164 | 114 errors++; |
115 ret = -1; | |
116 goto nextline; | |
117 } | |
118 } | |
119 if (opt_pos == 0) { | |
120 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
121 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"parse error at line %d\n",line_num); |
8164 | 122 ret = -1; |
123 errors++; | |
124 continue; | |
125 } | |
126 opt[opt_pos] = '\0'; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26408
diff
changeset
|
127 |
17471 | 128 /* Profile declaration */ |
129 if(opt_pos > 2 && opt[0] == '[' && opt[opt_pos-1] == ']') { | |
130 opt[opt_pos-1] = '\0'; | |
131 if(strcmp(opt+1,"default")) | |
132 profile = m_config_add_profile(config,opt+1); | |
133 else | |
134 profile = NULL; | |
135 continue; | |
136 } | |
8164 | 137 |
138 #ifdef MP_DEBUG | |
139 PRINT_LINENUM; | |
140 mp_msg(MSGT_CFGPARSER,MSGL_V,"option: %s\n", opt); | |
141 #endif | |
142 | |
143 /* skip whitespaces */ | |
144 while (isspace(line[line_pos])) | |
145 ++line_pos; | |
146 | |
147 /* check '=' */ | |
148 if (line[line_pos++] != '=') { | |
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 needs a parameter at line %d\n",opt,line_num); |
8164 | 151 ret = -1; |
152 errors++; | |
153 continue; | |
154 } | |
155 | |
156 /* whitespaces... */ | |
157 while (isspace(line[line_pos])) | |
158 ++line_pos; | |
159 | |
160 /* read the parameter */ | |
161 if (line[line_pos] == '"' || line[line_pos] == '\'') { | |
162 c = line[line_pos]; | |
163 ++line_pos; | |
164 for (param_pos = 0; line[line_pos] != c; /* NOTHING */) { | |
165 param[param_pos++] = line[line_pos++]; | |
166 if (param_pos >= MAX_PARAM_LEN) { | |
167 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
168 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s has a too long parameter at line %d\n",opt,line_num); |
8164 | 169 ret = -1; |
170 errors++; | |
171 goto nextline; | |
172 } | |
173 } | |
174 line_pos++; /* skip the closing " or ' */ | |
175 } else { | |
176 for (param_pos = 0; isprint(line[line_pos]) && !isspace(line[line_pos]) | |
177 && line[line_pos] != '#'; /* NOTHING */) { | |
178 param[param_pos++] = line[line_pos++]; | |
179 if (param_pos >= MAX_PARAM_LEN) { | |
180 PRINT_LINENUM; | |
181 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long parameter\n"); | |
182 ret = -1; | |
183 errors++; | |
184 goto nextline; | |
185 } | |
186 } | |
187 } | |
188 param[param_pos] = '\0'; | |
189 | |
190 /* did we read a parameter? */ | |
191 if (param_pos == 0) { | |
192 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
193 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s needs a parameter at line %d\n",opt,line_num); |
8164 | 194 ret = -1; |
195 errors++; | |
196 continue; | |
197 } | |
198 | |
199 #ifdef MP_DEBUG | |
200 PRINT_LINENUM; | |
201 mp_msg(MSGT_CFGPARSER,MSGL_V,"parameter: %s\n", param); | |
202 #endif | |
203 | |
204 /* now, check if we have some more chars on the line */ | |
205 /* whitespace... */ | |
206 while (isspace(line[line_pos])) | |
207 ++line_pos; | |
208 | |
209 /* EOL / comment */ | |
210 if (line[line_pos] != '\0' && line[line_pos] != '#') { | |
211 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
212 mp_msg(MSGT_CFGPARSER,MSGL_WARN,"extra characters on line %d: %s\n",line_num, line+line_pos); |
8164 | 213 ret = -1; |
214 } | |
215 | |
17471 | 216 if(profile) { |
217 if(!strcmp(opt,"profile-desc")) | |
218 m_profile_set_desc(profile,param), tmp = 1; | |
219 else | |
220 tmp = m_config_set_profile_option(config,profile, | |
221 opt,param); | |
222 } else | |
223 tmp = m_config_set_option(config, opt, param); | |
8164 | 224 if (tmp < 0) { |
225 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
|
226 if(tmp == M_OPT_UNKNOWN) { |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
227 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
|
228 continue; |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
229 } |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
230 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Error parsing option %s=%s at line %d\n",opt,param,line_num); |
8164 | 231 ret = -1; |
232 errors++; | |
233 continue; | |
234 /* break */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26408
diff
changeset
|
235 } |
8164 | 236 nextline: |
237 ; | |
238 } | |
239 | |
240 free(line); | |
241 fclose(fp); | |
242 out: | |
243 config->mode = prev_mode; | |
244 --recursion_depth; | |
245 return ret; | |
246 } | |
18265 | 247 |
26408
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
248 extern int mp_msg_levels[]; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
249 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
250 /// Parse the command line option that must be handled at startup. |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
251 int m_config_preparse_command_line(m_config_t *config, int argc, char **argv) |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
252 { |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
253 int msg_lvl, i, r, ret = 0; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
254 char* arg; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
255 m_option_t* opt; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
256 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
257 // Hack to shutup the parser error messages. |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
258 msg_lvl = mp_msg_levels[MSGT_CFGPARSER]; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
259 mp_msg_levels[MSGT_CFGPARSER] = -11; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
260 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
261 config->mode = M_COMMAND_LINE_PRE_PARSE; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
262 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
263 for(i = 1 ; i < argc ; i++) { |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
264 arg = argv[i]; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
265 // Ignore non option |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
266 if(arg[0] != '-' || arg[1] == 0) continue; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
267 arg++; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
268 // No more options after -- |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
269 if(arg[0] == '-' && arg[1] == 0) break; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
270 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
271 opt = m_config_get_option(config,arg); |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
272 // Ignore invalid option |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
273 if(!opt) continue; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
274 // Set, non-pre-parse options will be ignored |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
275 r = m_config_set_option(config,arg, |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
276 i+1 < argc ? argv[i+1] : NULL); |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
277 if(r < 0) ret = r; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
278 else i += r; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
279 } |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
280 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
281 mp_msg_levels[MSGT_CFGPARSER] = msg_lvl; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
282 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
283 return ret; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
284 } |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
285 |
18265 | 286 ///@} |