Mercurial > mplayer.hg
annotate parser-cfg.c @ 23572:a00685941686
demux_mkv very long seek fix
The seek code searching for the closest position in the index used
"int64_t min_diff=0xFFFFFFFL" as the initial "further from the goal
than any real alternative" value. The unit is milliseconds so seeks more
than about 75 hours past the end of the file would fail to recognize the
last index position as the best match. This was triggered in practice by
chapter seek code which apparently uses a seek of 1000000000 seconds
forward to mean "seek to the end". The practical effect was that trying
to seek to the next chapter in a file without chapters made MPlayer
block until it finished reading the file from the current position to
the end.
Fixed by increasing the initial value from FFFFFFF to FFFFFFFFFFFFFFF.
author | uau |
---|---|
date | Wed, 20 Jun 2007 18:19:03 +0000 |
parents | a6911070ac6e |
children | 0a38ad149c5c |
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 | |
22 #include "mp_msg.h" | |
23 #include "m_option.h" | |
24 #include "m_config.h" | |
25 | |
18265 | 26 /// Maximal include depth. |
8164 | 27 #define MAX_RECURSION_DEPTH 8 |
28 | |
18265 | 29 /// Current include depth. |
8164 | 30 static int recursion_depth = 0; |
31 | |
18265 | 32 /// Setup the \ref Config from a config file. |
33 /** \param config The config object. | |
34 * \param conffile Path to the config file. | |
35 * \return 1 on sucess, -1 on error. | |
36 */ | |
8164 | 37 int m_config_parse_config_file(m_config_t* config, char *conffile) |
38 { | |
39 #define PRINT_LINENUM mp_msg(MSGT_CFGPARSER,MSGL_V,"%s(%d): ", conffile, line_num) | |
9813 | 40 #define MAX_LINE_LEN 10000 |
41 #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
|
42 #define MAX_PARAM_LEN 1500 |
8164 | 43 FILE *fp; |
44 char *line; | |
45 char opt[MAX_OPT_LEN + 1]; | |
46 char param[MAX_PARAM_LEN + 1]; | |
47 char c; /* for the "" and '' check */ | |
48 int tmp; | |
49 int line_num = 0; | |
50 int line_pos; /* line pos */ | |
51 int opt_pos; /* opt pos */ | |
52 int param_pos; /* param pos */ | |
53 int ret = 1; | |
54 int errors = 0; | |
55 int prev_mode = config->mode; | |
17471 | 56 m_profile_t* profile = NULL; |
8164 | 57 |
58 #ifdef MP_DEBUG | |
59 assert(config != NULL); | |
60 // assert(conf_list != NULL); | |
61 #endif | |
13946 | 62 mp_msg(MSGT_CFGPARSER,MSGL_V,"Reading config file %s", conffile); |
8164 | 63 |
64 if (recursion_depth > MAX_RECURSION_DEPTH) { | |
65 mp_msg(MSGT_CFGPARSER,MSGL_ERR,": too deep 'include'. check your configfiles\n"); | |
66 ret = -1; | |
67 goto out; | |
68 } else | |
69 | |
70 config->mode = M_CONFIG_FILE; | |
71 | |
72 if ((line = (char *) malloc(MAX_LINE_LEN + 1)) == NULL) { | |
73 mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"\ncan't get memory for 'line': %s", strerror(errno)); | |
74 ret = -1; | |
75 goto out; | |
19462
08fc089138f4
Fix stray newline that should only be printed in verbose mode.
diego
parents:
18265
diff
changeset
|
76 } else |
08fc089138f4
Fix stray newline that should only be printed in verbose mode.
diego
parents:
18265
diff
changeset
|
77 |
08fc089138f4
Fix stray newline that should only be printed in verbose mode.
diego
parents:
18265
diff
changeset
|
78 mp_msg(MSGT_CFGPARSER,MSGL_V,"\n"); |
8164 | 79 |
80 if ((fp = fopen(conffile, "r")) == NULL) { | |
13946 | 81 mp_msg(MSGT_CFGPARSER,MSGL_V,": %s\n", strerror(errno)); |
8164 | 82 free(line); |
83 ret = 0; | |
84 goto out; | |
85 } | |
86 | |
87 while (fgets(line, MAX_LINE_LEN, fp)) { | |
88 if (errors >= 16) { | |
89 mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"too many errors\n"); | |
90 goto out; | |
91 } | |
92 | |
93 line_num++; | |
94 line_pos = 0; | |
95 | |
96 /* skip whitespaces */ | |
97 while (isspace(line[line_pos])) | |
98 ++line_pos; | |
99 | |
100 /* EOL / comment */ | |
101 if (line[line_pos] == '\0' || line[line_pos] == '#') | |
102 continue; | |
103 | |
104 /* read option. */ | |
105 for (opt_pos = 0; isprint(line[line_pos]) && | |
106 line[line_pos] != ' ' && | |
107 line[line_pos] != '#' && | |
108 line[line_pos] != '='; /* NOTHING */) { | |
109 opt[opt_pos++] = line[line_pos++]; | |
110 if (opt_pos >= MAX_OPT_LEN) { | |
111 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
112 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long option at line %d\n",line_num); |
8164 | 113 errors++; |
114 ret = -1; | |
115 goto nextline; | |
116 } | |
117 } | |
118 if (opt_pos == 0) { | |
119 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
120 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"parse error at line %d\n",line_num); |
8164 | 121 ret = -1; |
122 errors++; | |
123 continue; | |
124 } | |
125 opt[opt_pos] = '\0'; | |
17471 | 126 |
127 /* Profile declaration */ | |
128 if(opt_pos > 2 && opt[0] == '[' && opt[opt_pos-1] == ']') { | |
129 opt[opt_pos-1] = '\0'; | |
130 if(strcmp(opt+1,"default")) | |
131 profile = m_config_add_profile(config,opt+1); | |
132 else | |
133 profile = NULL; | |
134 continue; | |
135 } | |
8164 | 136 |
137 #ifdef MP_DEBUG | |
138 PRINT_LINENUM; | |
139 mp_msg(MSGT_CFGPARSER,MSGL_V,"option: %s\n", opt); | |
140 #endif | |
141 | |
142 /* skip whitespaces */ | |
143 while (isspace(line[line_pos])) | |
144 ++line_pos; | |
145 | |
146 /* check '=' */ | |
147 if (line[line_pos++] != '=') { | |
148 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
149 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s needs a parameter at line %d\n",opt,line_num); |
8164 | 150 ret = -1; |
151 errors++; | |
152 continue; | |
153 } | |
154 | |
155 /* whitespaces... */ | |
156 while (isspace(line[line_pos])) | |
157 ++line_pos; | |
158 | |
159 /* read the parameter */ | |
160 if (line[line_pos] == '"' || line[line_pos] == '\'') { | |
161 c = line[line_pos]; | |
162 ++line_pos; | |
163 for (param_pos = 0; line[line_pos] != c; /* NOTHING */) { | |
164 param[param_pos++] = line[line_pos++]; | |
165 if (param_pos >= MAX_PARAM_LEN) { | |
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 has a too long parameter at line %d\n",opt,line_num); |
8164 | 168 ret = -1; |
169 errors++; | |
170 goto nextline; | |
171 } | |
172 } | |
173 line_pos++; /* skip the closing " or ' */ | |
174 } else { | |
175 for (param_pos = 0; isprint(line[line_pos]) && !isspace(line[line_pos]) | |
176 && line[line_pos] != '#'; /* NOTHING */) { | |
177 param[param_pos++] = line[line_pos++]; | |
178 if (param_pos >= MAX_PARAM_LEN) { | |
179 PRINT_LINENUM; | |
180 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long parameter\n"); | |
181 ret = -1; | |
182 errors++; | |
183 goto nextline; | |
184 } | |
185 } | |
186 } | |
187 param[param_pos] = '\0'; | |
188 | |
189 /* did we read a parameter? */ | |
190 if (param_pos == 0) { | |
191 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
192 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s needs a parameter at line %d\n",opt,line_num); |
8164 | 193 ret = -1; |
194 errors++; | |
195 continue; | |
196 } | |
197 | |
198 #ifdef MP_DEBUG | |
199 PRINT_LINENUM; | |
200 mp_msg(MSGT_CFGPARSER,MSGL_V,"parameter: %s\n", param); | |
201 #endif | |
202 | |
203 /* now, check if we have some more chars on the line */ | |
204 /* whitespace... */ | |
205 while (isspace(line[line_pos])) | |
206 ++line_pos; | |
207 | |
208 /* EOL / comment */ | |
209 if (line[line_pos] != '\0' && line[line_pos] != '#') { | |
210 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
211 mp_msg(MSGT_CFGPARSER,MSGL_WARN,"extra characters on line %d: %s\n",line_num, line+line_pos); |
8164 | 212 ret = -1; |
213 } | |
214 | |
17471 | 215 if(profile) { |
216 if(!strcmp(opt,"profile-desc")) | |
217 m_profile_set_desc(profile,param), tmp = 1; | |
218 else | |
219 tmp = m_config_set_profile_option(config,profile, | |
220 opt,param); | |
221 } else | |
222 tmp = m_config_set_option(config, opt, param); | |
8164 | 223 if (tmp < 0) { |
224 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
|
225 if(tmp == M_OPT_UNKNOWN) { |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
226 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
|
227 continue; |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
228 } |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
229 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Error parsing option %s=%s at line %d\n",opt,param,line_num); |
8164 | 230 ret = -1; |
231 errors++; | |
232 continue; | |
233 /* break */ | |
234 } | |
235 nextline: | |
236 ; | |
237 } | |
238 | |
239 free(line); | |
240 fclose(fp); | |
241 out: | |
242 config->mode = prev_mode; | |
243 --recursion_depth; | |
244 return ret; | |
245 } | |
18265 | 246 |
247 ///@} |