Mercurial > mplayer.hg
annotate parser-cfg.c @ 35165:b924f0df5a1d
Remove our internal mp3lib copy.
We have FFmpeg as integrated decoder, and the
external mpg123 library should include all important
improvements from our mp3lib and is actually properly
maintained.
author | reimar |
---|---|
date | Sun, 21 Oct 2012 12:10:38 +0000 |
parents | 5761a9a31bcb |
children | 2d529504ec2d |
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 |
8164 | 62 FILE *fp; |
63 char *line; | |
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)); |
8164 | 101 free(line); |
34172 | 102 ret = silent ? 0 : -1; |
8164 | 103 goto out; |
104 } | |
105 | |
106 while (fgets(line, MAX_LINE_LEN, fp)) { | |
107 if (errors >= 16) { | |
108 mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"too many errors\n"); | |
109 goto out; | |
110 } | |
111 | |
112 line_num++; | |
113 line_pos = 0; | |
114 | |
115 /* skip whitespaces */ | |
116 while (isspace(line[line_pos])) | |
117 ++line_pos; | |
118 | |
119 /* EOL / comment */ | |
120 if (line[line_pos] == '\0' || line[line_pos] == '#') | |
121 continue; | |
122 | |
123 /* read option. */ | |
124 for (opt_pos = 0; isprint(line[line_pos]) && | |
125 line[line_pos] != ' ' && | |
126 line[line_pos] != '#' && | |
127 line[line_pos] != '='; /* NOTHING */) { | |
128 opt[opt_pos++] = line[line_pos++]; | |
129 if (opt_pos >= MAX_OPT_LEN) { | |
130 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
131 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long option at line %d\n",line_num); |
8164 | 132 errors++; |
133 ret = -1; | |
134 goto nextline; | |
135 } | |
136 } | |
137 if (opt_pos == 0) { | |
138 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
139 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"parse error at line %d\n",line_num); |
8164 | 140 ret = -1; |
141 errors++; | |
142 continue; | |
143 } | |
144 opt[opt_pos] = '\0'; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26408
diff
changeset
|
145 |
17471 | 146 /* Profile declaration */ |
147 if(opt_pos > 2 && opt[0] == '[' && opt[opt_pos-1] == ']') { | |
148 opt[opt_pos-1] = '\0'; | |
149 if(strcmp(opt+1,"default")) | |
150 profile = m_config_add_profile(config,opt+1); | |
151 else | |
152 profile = NULL; | |
153 continue; | |
154 } | |
8164 | 155 |
156 #ifdef MP_DEBUG | |
157 PRINT_LINENUM; | |
158 mp_msg(MSGT_CFGPARSER,MSGL_V,"option: %s\n", opt); | |
159 #endif | |
160 | |
161 /* skip whitespaces */ | |
162 while (isspace(line[line_pos])) | |
163 ++line_pos; | |
164 | |
165 /* check '=' */ | |
166 if (line[line_pos++] != '=') { | |
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 needs a parameter at line %d\n",opt,line_num); |
8164 | 169 ret = -1; |
170 errors++; | |
171 continue; | |
172 } | |
173 | |
174 /* whitespaces... */ | |
175 while (isspace(line[line_pos])) | |
176 ++line_pos; | |
177 | |
178 /* read the parameter */ | |
179 if (line[line_pos] == '"' || line[line_pos] == '\'') { | |
180 c = line[line_pos]; | |
181 ++line_pos; | |
182 for (param_pos = 0; line[line_pos] != c; /* NOTHING */) { | |
183 param[param_pos++] = line[line_pos++]; | |
184 if (param_pos >= MAX_PARAM_LEN) { | |
185 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
186 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s has a too long parameter at line %d\n",opt,line_num); |
8164 | 187 ret = -1; |
188 errors++; | |
189 goto nextline; | |
190 } | |
191 } | |
192 line_pos++; /* skip the closing " or ' */ | |
193 } else { | |
194 for (param_pos = 0; isprint(line[line_pos]) && !isspace(line[line_pos]) | |
195 && line[line_pos] != '#'; /* NOTHING */) { | |
196 param[param_pos++] = line[line_pos++]; | |
197 if (param_pos >= MAX_PARAM_LEN) { | |
198 PRINT_LINENUM; | |
199 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long parameter\n"); | |
200 ret = -1; | |
201 errors++; | |
202 goto nextline; | |
203 } | |
204 } | |
205 } | |
206 param[param_pos] = '\0'; | |
207 | |
208 /* did we read a parameter? */ | |
209 if (param_pos == 0) { | |
210 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
211 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s needs a parameter at line %d\n",opt,line_num); |
8164 | 212 ret = -1; |
213 errors++; | |
214 continue; | |
215 } | |
216 | |
217 #ifdef MP_DEBUG | |
218 PRINT_LINENUM; | |
219 mp_msg(MSGT_CFGPARSER,MSGL_V,"parameter: %s\n", param); | |
220 #endif | |
221 | |
222 /* now, check if we have some more chars on the line */ | |
223 /* whitespace... */ | |
224 while (isspace(line[line_pos])) | |
225 ++line_pos; | |
226 | |
227 /* EOL / comment */ | |
228 if (line[line_pos] != '\0' && line[line_pos] != '#') { | |
229 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
230 mp_msg(MSGT_CFGPARSER,MSGL_WARN,"extra characters on line %d: %s\n",line_num, line+line_pos); |
8164 | 231 ret = -1; |
232 } | |
233 | |
17471 | 234 if(profile) { |
235 if(!strcmp(opt,"profile-desc")) | |
236 m_profile_set_desc(profile,param), tmp = 1; | |
237 else | |
238 tmp = m_config_set_profile_option(config,profile, | |
239 opt,param); | |
240 } else | |
241 tmp = m_config_set_option(config, opt, param); | |
8164 | 242 if (tmp < 0) { |
243 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
|
244 if(tmp == M_OPT_UNKNOWN) { |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
245 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
|
246 continue; |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
247 } |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
248 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Error parsing option %s=%s at line %d\n",opt,param,line_num); |
8164 | 249 ret = -1; |
250 errors++; | |
251 continue; | |
252 /* break */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26408
diff
changeset
|
253 } |
8164 | 254 nextline: |
255 ; | |
256 } | |
257 | |
258 free(line); | |
259 fclose(fp); | |
260 out: | |
261 config->mode = prev_mode; | |
262 --recursion_depth; | |
263 return ret; | |
264 } | |
18265 | 265 |
26408
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
266 /// 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
|
267 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
|
268 { |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
269 int msg_lvl, i, r, ret = 0; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
270 char* arg; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
271 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
272 // Hack to shutup the parser error messages. |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
273 msg_lvl = mp_msg_levels[MSGT_CFGPARSER]; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
274 mp_msg_levels[MSGT_CFGPARSER] = -11; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
275 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
276 config->mode = M_COMMAND_LINE_PRE_PARSE; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
277 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
278 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
|
279 const m_option_t* opt; |
26408
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
280 arg = argv[i]; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
281 // Ignore non option |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
282 if(arg[0] != '-' || arg[1] == 0) continue; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
283 arg++; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
284 // No more options after -- |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
285 if(arg[0] == '-' && arg[1] == 0) break; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
286 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
287 opt = m_config_get_option(config,arg); |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
288 // Ignore invalid option |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
289 if(!opt) continue; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
290 // 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
|
291 r = m_config_set_option(config,arg, |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
292 i+1 < argc ? argv[i+1] : NULL); |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
293 if(r < 0) ret = r; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
294 else i += r; |
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 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
297 mp_msg_levels[MSGT_CFGPARSER] = msg_lvl; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
298 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
299 return ret; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
300 } |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
301 |
18265 | 302 ///@} |