Mercurial > mplayer.hg
annotate parser-cfg.c @ 29130:33956c5f5005
Reemit the ID_AID_x_LANG for the track. This allows the identification of the
audio track by language code (en or es) rather than by ID (128 or 129).
patch by Kevin DeKorte, kdekorte gmail com
author | diego |
---|---|
date | Sat, 11 Apr 2009 13:51:02 +0000 |
parents | 7a36d5941fd8 |
children | 0f1b5b68af32 |
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 | |
70 | |
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'; | |
17471 | 127 |
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 */ | |
235 } | |
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 ///@} |