Mercurial > mplayer.hg
annotate parser-cfg.c @ 18277:74944211418d
Synced with 1.15
author | jheryan |
---|---|
date | Tue, 25 Apr 2006 13:25:47 +0000 |
parents | 1a14fde7680d |
children | 08fc089138f4 |
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 | |
42 #define MAX_PARAM_LEN 1000 | |
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; | |
76 } | |
77 | |
78 if ((fp = fopen(conffile, "r")) == NULL) { | |
13946 | 79 mp_msg(MSGT_CFGPARSER,MSGL_V,": %s\n", strerror(errno)); |
8164 | 80 free(line); |
81 ret = 0; | |
82 goto out; | |
83 } | |
84 mp_msg(MSGT_CFGPARSER,MSGL_INFO,"\n"); | |
85 | |
86 while (fgets(line, MAX_LINE_LEN, fp)) { | |
87 if (errors >= 16) { | |
88 mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"too many errors\n"); | |
89 goto out; | |
90 } | |
91 | |
92 line_num++; | |
93 line_pos = 0; | |
94 | |
95 /* skip whitespaces */ | |
96 while (isspace(line[line_pos])) | |
97 ++line_pos; | |
98 | |
99 /* EOL / comment */ | |
100 if (line[line_pos] == '\0' || line[line_pos] == '#') | |
101 continue; | |
102 | |
103 /* read option. */ | |
104 for (opt_pos = 0; isprint(line[line_pos]) && | |
105 line[line_pos] != ' ' && | |
106 line[line_pos] != '#' && | |
107 line[line_pos] != '='; /* NOTHING */) { | |
108 opt[opt_pos++] = line[line_pos++]; | |
109 if (opt_pos >= MAX_OPT_LEN) { | |
110 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
111 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long option at line %d\n",line_num); |
8164 | 112 errors++; |
113 ret = -1; | |
114 goto nextline; | |
115 } | |
116 } | |
117 if (opt_pos == 0) { | |
118 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
119 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"parse error at line %d\n",line_num); |
8164 | 120 ret = -1; |
121 errors++; | |
122 continue; | |
123 } | |
124 opt[opt_pos] = '\0'; | |
17471 | 125 |
126 /* Profile declaration */ | |
127 if(opt_pos > 2 && opt[0] == '[' && opt[opt_pos-1] == ']') { | |
128 opt[opt_pos-1] = '\0'; | |
129 if(strcmp(opt+1,"default")) | |
130 profile = m_config_add_profile(config,opt+1); | |
131 else | |
132 profile = NULL; | |
133 continue; | |
134 } | |
8164 | 135 |
136 #ifdef MP_DEBUG | |
137 PRINT_LINENUM; | |
138 mp_msg(MSGT_CFGPARSER,MSGL_V,"option: %s\n", opt); | |
139 #endif | |
140 | |
141 /* skip whitespaces */ | |
142 while (isspace(line[line_pos])) | |
143 ++line_pos; | |
144 | |
145 /* check '=' */ | |
146 if (line[line_pos++] != '=') { | |
147 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
148 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s needs a parameter at line %d\n",opt,line_num); |
8164 | 149 ret = -1; |
150 errors++; | |
151 continue; | |
152 } | |
153 | |
154 /* whitespaces... */ | |
155 while (isspace(line[line_pos])) | |
156 ++line_pos; | |
157 | |
158 /* read the parameter */ | |
159 if (line[line_pos] == '"' || line[line_pos] == '\'') { | |
160 c = line[line_pos]; | |
161 ++line_pos; | |
162 for (param_pos = 0; line[line_pos] != c; /* NOTHING */) { | |
163 param[param_pos++] = line[line_pos++]; | |
164 if (param_pos >= MAX_PARAM_LEN) { | |
165 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
166 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s has a too long parameter at line %d\n",opt,line_num); |
8164 | 167 ret = -1; |
168 errors++; | |
169 goto nextline; | |
170 } | |
171 } | |
172 line_pos++; /* skip the closing " or ' */ | |
173 } else { | |
174 for (param_pos = 0; isprint(line[line_pos]) && !isspace(line[line_pos]) | |
175 && line[line_pos] != '#'; /* NOTHING */) { | |
176 param[param_pos++] = line[line_pos++]; | |
177 if (param_pos >= MAX_PARAM_LEN) { | |
178 PRINT_LINENUM; | |
179 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long parameter\n"); | |
180 ret = -1; | |
181 errors++; | |
182 goto nextline; | |
183 } | |
184 } | |
185 } | |
186 param[param_pos] = '\0'; | |
187 | |
188 /* did we read a parameter? */ | |
189 if (param_pos == 0) { | |
190 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
191 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s needs a parameter at line %d\n",opt,line_num); |
8164 | 192 ret = -1; |
193 errors++; | |
194 continue; | |
195 } | |
196 | |
197 #ifdef MP_DEBUG | |
198 PRINT_LINENUM; | |
199 mp_msg(MSGT_CFGPARSER,MSGL_V,"parameter: %s\n", param); | |
200 #endif | |
201 | |
202 /* now, check if we have some more chars on the line */ | |
203 /* whitespace... */ | |
204 while (isspace(line[line_pos])) | |
205 ++line_pos; | |
206 | |
207 /* EOL / comment */ | |
208 if (line[line_pos] != '\0' && line[line_pos] != '#') { | |
209 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
210 mp_msg(MSGT_CFGPARSER,MSGL_WARN,"extra characters on line %d: %s\n",line_num, line+line_pos); |
8164 | 211 ret = -1; |
212 } | |
213 | |
17471 | 214 if(profile) { |
215 if(!strcmp(opt,"profile-desc")) | |
216 m_profile_set_desc(profile,param), tmp = 1; | |
217 else | |
218 tmp = m_config_set_profile_option(config,profile, | |
219 opt,param); | |
220 } else | |
221 tmp = m_config_set_option(config, opt, param); | |
8164 | 222 if (tmp < 0) { |
223 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
|
224 if(tmp == M_OPT_UNKNOWN) { |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
225 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
|
226 continue; |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
227 } |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
228 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Error parsing option %s=%s at line %d\n",opt,param,line_num); |
8164 | 229 ret = -1; |
230 errors++; | |
231 continue; | |
232 /* break */ | |
233 } | |
234 nextline: | |
235 ; | |
236 } | |
237 | |
238 free(line); | |
239 fclose(fp); | |
240 out: | |
241 config->mode = prev_mode; | |
242 --recursion_depth; | |
243 return ret; | |
244 } | |
18265 | 245 |
246 ///@} |