Mercurial > mplayer.hg
annotate parser-cfg.c @ 17499:a9512fbdd5d4
Unify the handling of escaped spaces.
author | diego |
---|---|
date | Sun, 29 Jan 2006 02:11:38 +0000 |
parents | 63909962d3fc |
children | 1a14fde7680d |
rev | line source |
---|---|
8164 | 1 #include "config.h" |
2 | |
3 #include <stdio.h> | |
4 #include <stdlib.h> | |
5 #include <string.h> | |
6 #include <errno.h> | |
7 #include <ctype.h> | |
8 | |
9 #ifdef MP_DEBUG | |
10 #include <assert.h> | |
11 #endif | |
12 | |
13 #include "mp_msg.h" | |
14 #include "m_option.h" | |
15 #include "m_config.h" | |
16 | |
17 #define MAX_RECURSION_DEPTH 8 | |
18 | |
19 static int recursion_depth = 0; | |
20 | |
21 int m_config_parse_config_file(m_config_t* config, char *conffile) | |
22 { | |
23 #define PRINT_LINENUM mp_msg(MSGT_CFGPARSER,MSGL_V,"%s(%d): ", conffile, line_num) | |
9813 | 24 #define MAX_LINE_LEN 10000 |
25 #define MAX_OPT_LEN 1000 | |
26 #define MAX_PARAM_LEN 1000 | |
8164 | 27 FILE *fp; |
28 char *line; | |
29 char opt[MAX_OPT_LEN + 1]; | |
30 char param[MAX_PARAM_LEN + 1]; | |
31 char c; /* for the "" and '' check */ | |
32 int tmp; | |
33 int line_num = 0; | |
34 int line_pos; /* line pos */ | |
35 int opt_pos; /* opt pos */ | |
36 int param_pos; /* param pos */ | |
37 int ret = 1; | |
38 int errors = 0; | |
39 int prev_mode = config->mode; | |
17471 | 40 m_profile_t* profile = NULL; |
8164 | 41 |
42 #ifdef MP_DEBUG | |
43 assert(config != NULL); | |
44 // assert(conf_list != NULL); | |
45 #endif | |
13946 | 46 mp_msg(MSGT_CFGPARSER,MSGL_V,"Reading config file %s", conffile); |
8164 | 47 |
48 if (recursion_depth > MAX_RECURSION_DEPTH) { | |
49 mp_msg(MSGT_CFGPARSER,MSGL_ERR,": too deep 'include'. check your configfiles\n"); | |
50 ret = -1; | |
51 goto out; | |
52 } else | |
53 | |
54 config->mode = M_CONFIG_FILE; | |
55 | |
56 if ((line = (char *) malloc(MAX_LINE_LEN + 1)) == NULL) { | |
57 mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"\ncan't get memory for 'line': %s", strerror(errno)); | |
58 ret = -1; | |
59 goto out; | |
60 } | |
61 | |
62 if ((fp = fopen(conffile, "r")) == NULL) { | |
13946 | 63 mp_msg(MSGT_CFGPARSER,MSGL_V,": %s\n", strerror(errno)); |
8164 | 64 free(line); |
65 ret = 0; | |
66 goto out; | |
67 } | |
68 mp_msg(MSGT_CFGPARSER,MSGL_INFO,"\n"); | |
69 | |
70 while (fgets(line, MAX_LINE_LEN, fp)) { | |
71 if (errors >= 16) { | |
72 mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"too many errors\n"); | |
73 goto out; | |
74 } | |
75 | |
76 line_num++; | |
77 line_pos = 0; | |
78 | |
79 /* skip whitespaces */ | |
80 while (isspace(line[line_pos])) | |
81 ++line_pos; | |
82 | |
83 /* EOL / comment */ | |
84 if (line[line_pos] == '\0' || line[line_pos] == '#') | |
85 continue; | |
86 | |
87 /* read option. */ | |
88 for (opt_pos = 0; isprint(line[line_pos]) && | |
89 line[line_pos] != ' ' && | |
90 line[line_pos] != '#' && | |
91 line[line_pos] != '='; /* NOTHING */) { | |
92 opt[opt_pos++] = line[line_pos++]; | |
93 if (opt_pos >= MAX_OPT_LEN) { | |
94 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
95 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long option at line %d\n",line_num); |
8164 | 96 errors++; |
97 ret = -1; | |
98 goto nextline; | |
99 } | |
100 } | |
101 if (opt_pos == 0) { | |
102 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
103 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"parse error at line %d\n",line_num); |
8164 | 104 ret = -1; |
105 errors++; | |
106 continue; | |
107 } | |
108 opt[opt_pos] = '\0'; | |
17471 | 109 |
110 /* Profile declaration */ | |
111 if(opt_pos > 2 && opt[0] == '[' && opt[opt_pos-1] == ']') { | |
112 opt[opt_pos-1] = '\0'; | |
113 if(strcmp(opt+1,"default")) | |
114 profile = m_config_add_profile(config,opt+1); | |
115 else | |
116 profile = NULL; | |
117 continue; | |
118 } | |
8164 | 119 |
120 #ifdef MP_DEBUG | |
121 PRINT_LINENUM; | |
122 mp_msg(MSGT_CFGPARSER,MSGL_V,"option: %s\n", opt); | |
123 #endif | |
124 | |
125 /* skip whitespaces */ | |
126 while (isspace(line[line_pos])) | |
127 ++line_pos; | |
128 | |
129 /* check '=' */ | |
130 if (line[line_pos++] != '=') { | |
131 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
132 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s needs a parameter at line %d\n",opt,line_num); |
8164 | 133 ret = -1; |
134 errors++; | |
135 continue; | |
136 } | |
137 | |
138 /* whitespaces... */ | |
139 while (isspace(line[line_pos])) | |
140 ++line_pos; | |
141 | |
142 /* read the parameter */ | |
143 if (line[line_pos] == '"' || line[line_pos] == '\'') { | |
144 c = line[line_pos]; | |
145 ++line_pos; | |
146 for (param_pos = 0; line[line_pos] != c; /* NOTHING */) { | |
147 param[param_pos++] = line[line_pos++]; | |
148 if (param_pos >= MAX_PARAM_LEN) { | |
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 has a too long parameter at line %d\n",opt,line_num); |
8164 | 151 ret = -1; |
152 errors++; | |
153 goto nextline; | |
154 } | |
155 } | |
156 line_pos++; /* skip the closing " or ' */ | |
157 } else { | |
158 for (param_pos = 0; isprint(line[line_pos]) && !isspace(line[line_pos]) | |
159 && line[line_pos] != '#'; /* NOTHING */) { | |
160 param[param_pos++] = line[line_pos++]; | |
161 if (param_pos >= MAX_PARAM_LEN) { | |
162 PRINT_LINENUM; | |
163 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long parameter\n"); | |
164 ret = -1; | |
165 errors++; | |
166 goto nextline; | |
167 } | |
168 } | |
169 } | |
170 param[param_pos] = '\0'; | |
171 | |
172 /* did we read a parameter? */ | |
173 if (param_pos == 0) { | |
174 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
175 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s needs a parameter at line %d\n",opt,line_num); |
8164 | 176 ret = -1; |
177 errors++; | |
178 continue; | |
179 } | |
180 | |
181 #ifdef MP_DEBUG | |
182 PRINT_LINENUM; | |
183 mp_msg(MSGT_CFGPARSER,MSGL_V,"parameter: %s\n", param); | |
184 #endif | |
185 | |
186 /* now, check if we have some more chars on the line */ | |
187 /* whitespace... */ | |
188 while (isspace(line[line_pos])) | |
189 ++line_pos; | |
190 | |
191 /* EOL / comment */ | |
192 if (line[line_pos] != '\0' && line[line_pos] != '#') { | |
193 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
194 mp_msg(MSGT_CFGPARSER,MSGL_WARN,"extra characters on line %d: %s\n",line_num, line+line_pos); |
8164 | 195 ret = -1; |
196 } | |
197 | |
17471 | 198 if(profile) { |
199 if(!strcmp(opt,"profile-desc")) | |
200 m_profile_set_desc(profile,param), tmp = 1; | |
201 else | |
202 tmp = m_config_set_profile_option(config,profile, | |
203 opt,param); | |
204 } else | |
205 tmp = m_config_set_option(config, opt, param); | |
8164 | 206 if (tmp < 0) { |
207 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
|
208 if(tmp == M_OPT_UNKNOWN) { |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
209 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
|
210 continue; |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
211 } |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
212 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Error parsing option %s=%s at line %d\n",opt,param,line_num); |
8164 | 213 ret = -1; |
214 errors++; | |
215 continue; | |
216 /* break */ | |
217 } | |
218 nextline: | |
219 ; | |
220 } | |
221 | |
222 free(line); | |
223 fclose(fp); | |
224 out: | |
225 config->mode = prev_mode; | |
226 --recursion_depth; | |
227 return ret; | |
228 } |