Mercurial > mplayer.hg
annotate parser-cfg.c @ 35801:98693cc5df48
Exit GUI if we can't return to the skin we started with.
If there are errors in both the selected skin and the skin
we started with, there's nothing we can do but exit.
author | ib |
---|---|
date | Sat, 26 Jan 2013 00:34:43 +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 ///@} |