Mercurial > mplayer.hg
annotate parser-cfg.c @ 12925:2abd8e24eb69
10l to the author of this longstanding and obscure bug. Each language
should be removed only once from the list.
Thanks to Chris White for pointing out that there was a problem.
author | diego |
---|---|
date | Sat, 31 Jul 2004 22:17:23 +0000 |
parents | 522afd56703c |
children | e632b43f0598 |
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; | |
40 | |
41 #ifdef MP_DEBUG | |
42 assert(config != NULL); | |
43 // assert(conf_list != NULL); | |
44 #endif | |
45 mp_msg(MSGT_CFGPARSER,MSGL_INFO,"Reading config file %s", conffile); | |
46 | |
47 if (recursion_depth > MAX_RECURSION_DEPTH) { | |
48 mp_msg(MSGT_CFGPARSER,MSGL_ERR,": too deep 'include'. check your configfiles\n"); | |
49 ret = -1; | |
50 goto out; | |
51 } else | |
52 | |
53 config->mode = M_CONFIG_FILE; | |
54 | |
55 if ((line = (char *) malloc(MAX_LINE_LEN + 1)) == NULL) { | |
56 mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"\ncan't get memory for 'line': %s", strerror(errno)); | |
57 ret = -1; | |
58 goto out; | |
59 } | |
60 | |
61 if ((fp = fopen(conffile, "r")) == NULL) { | |
62 mp_msg(MSGT_CFGPARSER,MSGL_ERR,": %s\n", strerror(errno)); | |
63 free(line); | |
64 ret = 0; | |
65 goto out; | |
66 } | |
67 mp_msg(MSGT_CFGPARSER,MSGL_INFO,"\n"); | |
68 | |
69 while (fgets(line, MAX_LINE_LEN, fp)) { | |
70 if (errors >= 16) { | |
71 mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"too many errors\n"); | |
72 goto out; | |
73 } | |
74 | |
75 line_num++; | |
76 line_pos = 0; | |
77 | |
78 /* skip whitespaces */ | |
79 while (isspace(line[line_pos])) | |
80 ++line_pos; | |
81 | |
82 /* EOL / comment */ | |
83 if (line[line_pos] == '\0' || line[line_pos] == '#') | |
84 continue; | |
85 | |
86 /* read option. */ | |
87 for (opt_pos = 0; isprint(line[line_pos]) && | |
88 line[line_pos] != ' ' && | |
89 line[line_pos] != '#' && | |
90 line[line_pos] != '='; /* NOTHING */) { | |
91 opt[opt_pos++] = line[line_pos++]; | |
92 if (opt_pos >= MAX_OPT_LEN) { | |
93 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
94 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long option at line %d\n",line_num); |
8164 | 95 errors++; |
96 ret = -1; | |
97 goto nextline; | |
98 } | |
99 } | |
100 if (opt_pos == 0) { | |
101 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
102 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"parse error at line %d\n",line_num); |
8164 | 103 ret = -1; |
104 errors++; | |
105 continue; | |
106 } | |
107 opt[opt_pos] = '\0'; | |
108 | |
109 #ifdef MP_DEBUG | |
110 PRINT_LINENUM; | |
111 mp_msg(MSGT_CFGPARSER,MSGL_V,"option: %s\n", opt); | |
112 #endif | |
113 | |
114 /* skip whitespaces */ | |
115 while (isspace(line[line_pos])) | |
116 ++line_pos; | |
117 | |
118 /* check '=' */ | |
119 if (line[line_pos++] != '=') { | |
120 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
121 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s needs a parameter at line %d\n",opt,line_num); |
8164 | 122 ret = -1; |
123 errors++; | |
124 continue; | |
125 } | |
126 | |
127 /* whitespaces... */ | |
128 while (isspace(line[line_pos])) | |
129 ++line_pos; | |
130 | |
131 /* read the parameter */ | |
132 if (line[line_pos] == '"' || line[line_pos] == '\'') { | |
133 c = line[line_pos]; | |
134 ++line_pos; | |
135 for (param_pos = 0; line[line_pos] != c; /* NOTHING */) { | |
136 param[param_pos++] = line[line_pos++]; | |
137 if (param_pos >= MAX_PARAM_LEN) { | |
138 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
139 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s has a too long parameter at line %d\n",opt,line_num); |
8164 | 140 ret = -1; |
141 errors++; | |
142 goto nextline; | |
143 } | |
144 } | |
145 line_pos++; /* skip the closing " or ' */ | |
146 } else { | |
147 for (param_pos = 0; isprint(line[line_pos]) && !isspace(line[line_pos]) | |
148 && line[line_pos] != '#'; /* NOTHING */) { | |
149 param[param_pos++] = line[line_pos++]; | |
150 if (param_pos >= MAX_PARAM_LEN) { | |
151 PRINT_LINENUM; | |
152 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long parameter\n"); | |
153 ret = -1; | |
154 errors++; | |
155 goto nextline; | |
156 } | |
157 } | |
158 } | |
159 param[param_pos] = '\0'; | |
160 | |
161 /* did we read a parameter? */ | |
162 if (param_pos == 0) { | |
163 PRINT_LINENUM; | |
10245
a660de2556c2
1000l! crashing on broken config files finally fixed!
rfelker
parents:
9813
diff
changeset
|
164 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Option %s needs a parameter at line %d\n",opt,line_num); |
8164 | 165 ret = -1; |
166 errors++; | |
167 continue; | |
168 } | |
169 | |
170 #ifdef MP_DEBUG | |
171 PRINT_LINENUM; | |
172 mp_msg(MSGT_CFGPARSER,MSGL_V,"parameter: %s\n", param); | |
173 #endif | |
174 | |
175 /* now, check if we have some more chars on the line */ | |
176 /* whitespace... */ | |
177 while (isspace(line[line_pos])) | |
178 ++line_pos; | |
179 | |
180 /* EOL / comment */ | |
181 if (line[line_pos] != '\0' && line[line_pos] != '#') { | |
182 PRINT_LINENUM; | |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
183 mp_msg(MSGT_CFGPARSER,MSGL_WARN,"extra characters on line %d: %s\n",line_num, line+line_pos); |
8164 | 184 ret = -1; |
185 } | |
186 | |
187 tmp = m_config_set_option(config, opt, param); | |
188 if (tmp < 0) { | |
189 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
|
190 if(tmp == M_OPT_UNKNOWN) { |
9578
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
191 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
|
192 continue; |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
193 } |
0c5454233dcf
Better error messages (with line number now) and make unknow option
albeu
parents:
8164
diff
changeset
|
194 mp_msg(MSGT_CFGPARSER,MSGL_ERR,"Error parsing option %s=%s at line %d\n",opt,param,line_num); |
8164 | 195 ret = -1; |
196 errors++; | |
197 continue; | |
198 /* break */ | |
199 } | |
200 nextline: | |
201 ; | |
202 } | |
203 | |
204 free(line); | |
205 fclose(fp); | |
206 out: | |
207 config->mode = prev_mode; | |
208 --recursion_depth; | |
209 return ret; | |
210 } |