Mercurial > mplayer.hg
annotate parser-cfg.c @ 30017:7119354805e7
Use on-stack subtitle struct for temporary storage for passing subtitles on
for rendering by libass.
This avoids mangling the static subtitle struct that is supposed to contain
the subtitles that will actually be displayed and it also minimally reduces
memory usage by freeing the subtitle lines again as early as possible.
author | reimar |
---|---|
date | Fri, 18 Dec 2009 19:29:33 +0000 |
parents | 61b1e80faf63 |
children | c1a3f1bbba26 |
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 */ | |
29559
8fd1ec0984b9
Make m_config_parse_config_file file name argument const
reimar
parents:
29263
diff
changeset
|
38 int m_config_parse_config_file(m_config_t* config, const char *conffile) |
8164 | 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 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
256 // Hack to shutup the parser error messages. |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
257 msg_lvl = mp_msg_levels[MSGT_CFGPARSER]; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
258 mp_msg_levels[MSGT_CFGPARSER] = -11; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
259 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
260 config->mode = M_COMMAND_LINE_PRE_PARSE; |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
261 |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26263
diff
changeset
|
262 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
|
263 const m_option_t* opt; |
26408
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 ///@} |