2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include "parser-cfg.h"
35 /// Maximal include depth.
36 #define MAX_RECURSION_DEPTH 8
38 /// Current include depth.
39 static int recursion_depth
= 0;
41 /// Setup the \ref Config from a config file.
42 /** \param config The config object.
43 * \param conffile Path to the config file.
44 * \return 1 on sucess, -1 on error.
46 int m_config_parse_config_file(m_config_t
*config
, const char *conffile
)
48 #define PRINT_LINENUM mp_msg(MSGT_CFGPARSER, MSGL_V, "%s(%d): ", conffile, line_num)
49 #define MAX_LINE_LEN 10000
50 #define MAX_OPT_LEN 1000
51 #define MAX_PARAM_LEN 1500
54 char opt
[MAX_OPT_LEN
+ 1];
55 char param
[MAX_PARAM_LEN
+ 1];
56 char c
; /* for the "" and '' check */
59 int line_pos
; /* line pos */
60 int opt_pos
; /* opt pos */
61 int param_pos
; /* param pos */
64 int prev_mode
= config
->mode
;
65 m_profile_t
*profile
= NULL
;
67 mp_msg(MSGT_CFGPARSER
, MSGL_V
, "Reading config file %s", conffile
);
69 if (recursion_depth
> MAX_RECURSION_DEPTH
) {
70 mp_msg(MSGT_CFGPARSER
, MSGL_ERR
,
71 ": too deep 'include'. check your configfiles\n");
76 config
->mode
= M_CONFIG_FILE
;
78 if ((line
= malloc(MAX_LINE_LEN
+ 1)) == NULL
) {
79 mp_msg(MSGT_CFGPARSER
, MSGL_FATAL
,
80 "\ncan't get memory for 'line': %s", strerror(errno
));
85 mp_msg(MSGT_CFGPARSER
, MSGL_V
, "\n");
87 if ((fp
= fopen(conffile
, "r")) == NULL
) {
88 mp_msg(MSGT_CFGPARSER
, MSGL_V
, ": %s\n", strerror(errno
));
94 while (fgets(line
, MAX_LINE_LEN
, fp
)) {
96 mp_msg(MSGT_CFGPARSER
, MSGL_FATAL
, "too many errors\n");
103 /* skip whitespaces */
104 while (isspace(line
[line_pos
]))
108 if (line
[line_pos
] == '\0' || line
[line_pos
] == '#')
112 for (opt_pos
= 0; isprint(line
[line_pos
]) &&
113 line
[line_pos
] != ' ' &&
114 line
[line_pos
] != '#' &&
115 line
[line_pos
] != '='; /* NOTHING */) {
116 opt
[opt_pos
++] = line
[line_pos
++];
117 if (opt_pos
>= MAX_OPT_LEN
) {
119 mp_msg(MSGT_CFGPARSER
, MSGL_ERR
,
120 "too long option at line %d\n", line_num
);
128 mp_msg(MSGT_CFGPARSER
, MSGL_ERR
, "parse error at line %d\n",
136 /* Profile declaration */
137 if (opt_pos
> 2 && opt
[0] == '[' && opt
[opt_pos
- 1] == ']') {
138 opt
[opt_pos
- 1] = '\0';
139 if (strcmp(opt
+ 1, "default"))
140 profile
= m_config_add_profile(config
, opt
+ 1);
146 /* skip whitespaces */
147 while (isspace(line
[line_pos
]))
151 if (line
[line_pos
++] != '=') {
153 mp_msg(MSGT_CFGPARSER
, MSGL_ERR
,
154 "Option %s needs a parameter at line %d\n", opt
, line_num
);
161 while (isspace(line
[line_pos
]))
164 /* read the parameter */
165 if (line
[line_pos
] == '"' || line
[line_pos
] == '\'') {
168 for (param_pos
= 0; line
[line_pos
] != c
; /* NOTHING */) {
169 param
[param_pos
++] = line
[line_pos
++];
170 if (param_pos
>= MAX_PARAM_LEN
) {
172 mp_msg(MSGT_CFGPARSER
, MSGL_ERR
,
173 "Option %s has a too long parameter at line %d\n",
180 line_pos
++; /* skip the closing " or ' */
182 for (param_pos
= 0; isprint(line
[line_pos
])
183 && !isspace(line
[line_pos
])
184 && line
[line_pos
] != '#'; /* NOTHING */) {
185 param
[param_pos
++] = line
[line_pos
++];
186 if (param_pos
>= MAX_PARAM_LEN
) {
188 mp_msg(MSGT_CFGPARSER
, MSGL_ERR
, "too long parameter\n");
195 param
[param_pos
] = '\0';
197 /* did we read a parameter? */
198 if (param_pos
== 0) {
200 mp_msg(MSGT_CFGPARSER
, MSGL_ERR
,
201 "Option %s needs a parameter at line %d\n", opt
, line_num
);
207 /* now, check if we have some more chars on the line */
209 while (isspace(line
[line_pos
]))
213 if (line
[line_pos
] != '\0' && line
[line_pos
] != '#') {
215 mp_msg(MSGT_CFGPARSER
, MSGL_WARN
,
216 "extra characters on line %d: %s\n",
217 line_num
, line
+ line_pos
);
222 if (!strcmp(opt
, "profile-desc"))
223 m_profile_set_desc(profile
, param
), tmp
= 1;
225 tmp
= m_config_set_profile_option(config
, profile
,
228 tmp
= m_config_set_option0(config
, opt
, param
, false);
231 if (tmp
== M_OPT_UNKNOWN
) {
232 mp_msg(MSGT_CFGPARSER
, MSGL_WARN
,
233 "Warning unknown option %s at line %d\n",
237 mp_msg(MSGT_CFGPARSER
, MSGL_ERR
,
238 "Error parsing option %s=%s at line %d\n",
239 opt
, param
, line_num
);
252 config
->mode
= prev_mode
;