Mercurial > mplayer.hg
annotate parser-cfg.c @ 36776:5ea757ca6270
Fix careless pointer parameter handling.
User proper GLib macros to avoid pointer cast warnings.
This renders the usage of intptr_t redundant (introduced in r36858).
author | ib |
---|---|
date | Mon, 17 Feb 2014 02:30:49 +0000 |
parents | 2d529504ec2d |
children |
rev | line source |
---|---|
30429
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29560
diff
changeset
|
1 /* |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29560
diff
changeset
|
2 * This file is part of MPlayer. |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29560
diff
changeset
|
3 * |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29560
diff
changeset
|
4 * MPlayer is free software; you can redistribute it and/or modify |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29560
diff
changeset
|
5 * it under the terms of the GNU General Public License as published by |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29560
diff
changeset
|
6 * the Free Software Foundation; either version 2 of the License, or |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29560
diff
changeset
|
7 * (at your option) any later version. |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29560
diff
changeset
|
8 * |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29560
diff
changeset
|
9 * MPlayer is distributed in the hope that it will be useful, |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29560
diff
changeset
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29560
diff
changeset
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29560
diff
changeset
|
12 * GNU General Public License for more details. |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29560
diff
changeset
|
13 * |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29560
diff
changeset
|
14 * You should have received a copy of the GNU General Public License along |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29560
diff
changeset
|
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29560
diff
changeset
|
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29560
diff
changeset
|
17 */ |
18265 | 18 |
19 /// \defgroup ConfigParsers Config parsers | |
20 /// | |
21 /// The \ref ConfigParsers make use of the \ref Config to setup the config variables, | |
22 /// the command line parsers also build the playlist. | |
23 ///@{ | |
24 | |
25 /// \file | |
26 | |
8164 | 27 #include "config.h" |
28 | |
29 #include <stdio.h> | |
30 #include <stdlib.h> | |
31 #include <string.h> | |
32 #include <errno.h> | |
33 #include <ctype.h> | |
34 | |
35 #ifdef MP_DEBUG | |
36 #include <assert.h> | |
37 #endif | |
38 | |
26263 | 39 #include "parser-cfg.h" |
8164 | 40 #include "mp_msg.h" |
41 #include "m_option.h" | |
42 #include "m_config.h" | |
43 | |
18265 | 44 /// Maximal include depth. |
8164 | 45 #define MAX_RECURSION_DEPTH 8 |
46 | |
18265 | 47 /// Current include depth. |
8164 | 48 static int recursion_depth = 0; |
49 | |
18265 | 50 /// Setup the \ref Config from a config file. |
51 /** \param config The config object. | |
52 * \param conffile Path to the config file. | |
34172 | 53 * \param silent print message when failing to open file only at verbose level |
18265 | 54 * \return 1 on sucess, -1 on error. |
55 */ | |
34172 | 56 int m_config_parse_config_file(m_config_t* config, const char *conffile, int silent) |
8164 | 57 { |
58 #define PRINT_LINENUM mp_msg(MSGT_CFGPARSER,MSGL_V,"%s(%d): ", conffile, line_num) | |
9813 | 59 #define MAX_LINE_LEN 10000 |
60 #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
|
61 #define MAX_PARAM_LEN 1500 |
35273
2d529504ec2d
Properly free resources even when encountering many
reimar
parents:
34172
diff
changeset
|
62 FILE *fp = NULL; |
2d529504ec2d
Properly free resources even when encountering many
reimar
parents:
34172
diff
changeset
|
63 char *line = NULL; |
8164 | 64 char opt[MAX_OPT_LEN + 1]; |
65 char param[MAX_PARAM_LEN + 1]; | |
66 char c; /* for the "" and '' check */ | |
67 int tmp; | |
68 int line_num = 0; | |
69 int line_pos; /* line pos */ | |
70 int opt_pos; /* opt pos */ | |
71 int param_pos; /* param pos */ | |
72 int ret = 1; | |
73 int errors = 0; | |
74 int prev_mode = config->mode; | |
17471 | 75 m_profile_t* profile = NULL; |
8164 | 76 |
77 #ifdef MP_DEBUG | |
78 assert(config != NULL); | |
79 // assert(conf_list != NULL); | |
80 #endif | |
13946 | 81 mp_msg(MSGT_CFGPARSER,MSGL_V,"Reading config file %s", conffile); |
8164 | 82 |
34168
55abe5125482
Make include recursion depth actually have some effect.
reimar
parents:
31484
diff
changeset
|
83 if (++recursion_depth > MAX_RECURSION_DEPTH) { |
8164 | 84 mp_msg(MSGT_CFGPARSER,MSGL_ERR,": too deep 'include'. check your configfiles\n"); |
85 ret = -1; | |
86 goto out; | |
87 } else | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26408
diff
changeset
|
88 |
8164 | 89 config->mode = M_CONFIG_FILE; |
90 | |
23806 | 91 if ((line = malloc(MAX_LINE_LEN + 1)) == NULL) { |
8164 | 92 mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"\ncan't get memory for 'line': %s", strerror(errno)); |
93 ret = -1; | |
94 goto out; | |
19462
08fc089138f4
Fix stray newline that should only be printed in verbose mode.
diego
parents:
18265
diff
changeset
|
95 } else |
08fc089138f4
Fix stray newline that should only be printed in verbose mode.
diego
parents:
18265
diff
changeset
|
96 |
08fc089138f4
Fix stray newline that should only be printed in verbose mode.
diego
parents:
18265
diff
changeset
|
97 mp_msg(MSGT_CFGPARSER,MSGL_V,"\n"); |
8164 | 98 |
99 if ((fp = fopen(conffile, "r")) == NULL) { | |
34172 | 100 mp_msg(MSGT_CFGPARSER,silent?MSGL_V:MSGL_ERR,"Failed to read %s: %s\n", conffile, strerror(errno)); |
101 ret = silent ? 0 : -1; | |
8164 | 102 goto out; |
103 } | |
104 | |
105 while (fgets(line, MAX_LINE_LEN, fp)) { | |
106 if (errors >= 16) { | |
107 mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"too many errors\n"); | |
108 goto out; | |
109 } | |
110 | |
111 line_num++; | |
112 line_pos = 0; | |
113 | |
114 /* skip whitespaces */ | |
115 while (isspace(line[line_pos])) | |
116 ++line_pos; | |
117 | |
118 /* EOL / comment */ | |
119 if (line[line_pos] == '\0' || line[line_pos] == '#') | |
120 continue; | |
121 | |
122 /* read option. */ | |
123 for (opt_pos = 0; isprint(line[line_pos]) && | |
124 line[line_pos] != ' ' && | |
125 line[line_pos] != '#' && | |
126 line[line_pos] != '='; /* NOTHING */) { | |
127 opt[opt_pos++] = line[line_pos++]; | |
128 if (opt_pos >= MAX_OPT_LEN) { | |
129 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
130 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long option at line %d\n",line_num); |
8164 | 131 errors++; |
132 ret = -1; | |
133 goto nextline; | |
134 } | |
135 } | |
136 if (opt_pos == 0) { | |
137 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
138 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"parse error at line %d\n",line_num); |
8164 | 139 ret = -1; |
140 errors++; | |
141 continue; | |
142 } | |
143 opt[opt_pos] = '\0'; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26408
diff
changeset
|
144 |
17471 | 145 /* Profile declaration */ |
146 if(opt_pos > 2 && opt[0] == '[' && opt[opt_pos-1] == ']') { | |
147 opt[opt_pos-1] = '\0'; | |
148 if(strcmp(opt+1,"default")) | |
149 profile = m_config_add_profile(config,opt+1); | |
150 else | |
151 profile = NULL; | |
152 continue; | |
153 } | |
8164 | 154 |
155 #ifdef MP_DEBUG | |
156 PRINT_LINENUM; | |
157 mp_msg(MSGT_CFGPARSER,MSGL_V,"option: %s\n", opt); | |
158 #endif | |
159 | |
160 /* skip whitespaces */ | |
161 while (isspace(line[line_pos])) | |
162 ++line_pos; | |
163 | |
164 /* check '=' */ | |
165 if (line[line_pos++] != '=') { | |
166 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
167 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s needs a parameter at line %d\n",opt,line_num); |
8164 | 168 ret = -1; |
169 errors++; | |
170 continue; | |
171 } | |
172 | |
173 /* whitespaces... */ | |
174 while (isspace(line[line_pos])) | |
175 ++line_pos; | |
176 | |
177 /* read the parameter */ | |
178 if (line[line_pos] == '"' || line[line_pos] == '\'') { | |
179 c = line[line_pos]; | |
180 ++line_pos; | |
181 for (param_pos = 0; line[line_pos] != c; /* NOTHING */) { | |
182 param[param_pos++] = line[line_pos++]; | |
183 if (param_pos >= MAX_PARAM_LEN) { | |
184 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
185 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s has a too long parameter at line %d\n",opt,line_num); |
8164 | 186 ret = -1; |
187 errors++; | |
188 goto nextline; | |
189 } | |
190 } | |
191 line_pos++; /* skip the closing " or ' */ | |
192 } else { | |
193 for (param_pos = 0; isprint(line[line_pos]) && !isspace(line[line_pos]) | |
194 && line[line_pos] != '#'; /* NOTHING */) { | |
195 param[param_pos++] = line[line_pos++]; | |
196 if (param_pos >= MAX_PARAM_LEN) { | |
197 PRINT_LINENUM; | |
198 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long parameter\n"); | |
199 ret = -1; | |
200 errors++; | |
201 goto nextline; | |
202 } | |
203 } | |
204 } | |
205 param[param_pos] = '\0'; | |
206 | |
207 /* did we read a parameter? */ | |
208 if (param_pos == 0) { | |
209 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
210 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s needs a parameter at line %d\n",opt,line_num); |
8164 | 211 ret = -1; |
212 errors++; | |
213 continue; | |
214 } | |
215 | |
216 #ifdef MP_DEBUG | |
217 PRINT_LINENUM; | |
218 mp_msg(MSGT_CFGPARSER,MSGL_V,"parameter: %s\n", param); | |
219 #endif | |
220 | |
221 /* now, check if we have some more chars on the line */ | |
222 /* whitespace... */ | |
223 while (isspace(line[line_pos])) | |
224 ++line_pos; | |
225 | |
226 /* EOL / comment */ | |
227 if (line[line_pos] != '\0' && line[line_pos] != '#') { | |
228 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
229 mp_msg(MSGT_CFGPARSER,MSGL_WARN,"extra characters on line %d: %s\n",line_num, line+line_pos); |
8164 | 230 ret = -1; |
231 } | |
232 | |
17471 | 233 if(profile) { |
234 if(!strcmp(opt,"profile-desc")) | |
235 m_profile_set_desc(profile,param), tmp = 1; | |
236 else | |
237 tmp = m_config_set_profile_option(config,profile, | |
238 opt,param); | |
239 } else | |
240 tmp = m_config_set_option(config, opt, param); | |
8164 | 241 if (tmp < 0) { |
242 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
|
243 if(tmp == M_OPT_UNKNOWN) { |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
244 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
|
245 continue; |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
246 } |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
247 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Error parsing option %s=%s at line %d\n",opt,param,line_num); |
8164 | 248 ret = -1; |
249 errors++; | |
250 continue; | |
251 /* break */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26408
diff
changeset
|
252 } |
8164 | 253 nextline: |
254 ; | |
255 } | |
256 | |
35273
2d529504ec2d
Properly free resources even when encountering many
reimar
parents:
34172
diff
changeset
|
257 out: |
8164 | 258 free(line); |
35273
2d529504ec2d
Properly free resources even when encountering many
reimar
parents:
34172
diff
changeset
|
259 if (fp) fclose(fp); |
8164 | 260 config->mode = prev_mode; |
261 --recursion_depth; | |
262 return ret; | |
263 } | |
18265 | 264 |
26408
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
265 /// 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
|
266 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
|
267 { |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
268 int msg_lvl, i, r, ret = 0; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
269 char* arg; |
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 // Hack to shutup the parser error messages. |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
272 msg_lvl = mp_msg_levels[MSGT_CFGPARSER]; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
273 mp_msg_levels[MSGT_CFGPARSER] = -11; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
274 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
275 config->mode = M_COMMAND_LINE_PRE_PARSE; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
276 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
277 for(i = 1 ; i < argc ; i++) { |
29560
61b1e80faf63
Move variable declaration into block where it is used and make it const.
reimar
parents:
29559
diff
changeset
|
278 const m_option_t* opt; |
26408
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
279 arg = argv[i]; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
280 // Ignore non option |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
281 if(arg[0] != '-' || arg[1] == 0) continue; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
282 arg++; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
283 // No more options after -- |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
284 if(arg[0] == '-' && arg[1] == 0) break; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
285 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
286 opt = m_config_get_option(config,arg); |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
287 // Ignore invalid option |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
288 if(!opt) continue; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
289 // 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
|
290 r = m_config_set_option(config,arg, |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
291 i+1 < argc ? argv[i+1] : NULL); |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
292 if(r < 0) ret = r; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
293 else i += r; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
294 } |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
295 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
296 mp_msg_levels[MSGT_CFGPARSER] = msg_lvl; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
297 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
298 return ret; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
299 } |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
300 |
18265 | 301 ///@} |