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.
19 /// \defgroup ConfigParsers Config parsers
21 /// The \ref ConfigParsers make use of the \ref Config to setup the config variables,
22 /// the command line parsers also build the playlist.
39 #include "parser-cfg.h"
44 /// Maximal include depth.
45 #define MAX_RECURSION_DEPTH 8
47 /// Current include depth.
48 static int recursion_depth
= 0;
50 /// Setup the \ref Config from a config file.
51 /** \param config The config object.
52 * \param conffile Path to the config file.
53 * \return 1 on sucess, -1 on error.
55 int m_config_parse_config_file(m_config_t
* config
, const char *conffile
)
57 #define PRINT_LINENUM mp_msg(MSGT_CFGPARSER,MSGL_V,"%s(%d): ", conffile, line_num)
58 #define MAX_LINE_LEN 10000
59 #define MAX_OPT_LEN 1000
60 #define MAX_PARAM_LEN 1500
63 char opt
[MAX_OPT_LEN
+ 1];
64 char param
[MAX_PARAM_LEN
+ 1];
65 char c
; /* for the "" and '' check */
68 int line_pos
; /* line pos */
69 int opt_pos
; /* opt pos */
70 int param_pos
; /* param pos */
73 int prev_mode
= config
->mode
;
74 m_profile_t
* profile
= NULL
;
77 assert(config
!= NULL
);
78 // assert(conf_list != NULL);
80 mp_msg(MSGT_CFGPARSER
,MSGL_V
,"Reading config file %s", conffile
);
82 if (recursion_depth
> MAX_RECURSION_DEPTH
) {
83 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,": too deep 'include'. check your configfiles\n");
88 config
->mode
= M_CONFIG_FILE
;
90 if ((line
= malloc(MAX_LINE_LEN
+ 1)) == NULL
) {
91 mp_msg(MSGT_CFGPARSER
,MSGL_FATAL
,"\ncan't get memory for 'line': %s", strerror(errno
));
96 mp_msg(MSGT_CFGPARSER
,MSGL_V
,"\n");
98 if ((fp
= fopen(conffile
, "r")) == NULL
) {
99 mp_msg(MSGT_CFGPARSER
,MSGL_V
,": %s\n", strerror(errno
));
105 while (fgets(line
, MAX_LINE_LEN
, fp
)) {
107 mp_msg(MSGT_CFGPARSER
,MSGL_FATAL
,"too many errors\n");
114 /* skip whitespaces */
115 while (isspace(line
[line_pos
]))
119 if (line
[line_pos
] == '\0' || line
[line_pos
] == '#')
123 for (opt_pos
= 0; isprint(line
[line_pos
]) &&
124 line
[line_pos
] != ' ' &&
125 line
[line_pos
] != '#' &&
126 line
[line_pos
] != '='; /* NOTHING */) {
127 opt
[opt_pos
++] = line
[line_pos
++];
128 if (opt_pos
>= MAX_OPT_LEN
) {
130 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"too long option at line %d\n",line_num
);
138 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"parse error at line %d\n",line_num
);
145 /* Profile declaration */
146 if(opt_pos
> 2 && opt
[0] == '[' && opt
[opt_pos
-1] == ']') {
147 opt
[opt_pos
-1] = '\0';
148 if(strcmp(opt
+1,"default"))
149 profile
= m_config_add_profile(config
,opt
+1);
157 mp_msg(MSGT_CFGPARSER
,MSGL_V
,"option: %s\n", opt
);
160 /* skip whitespaces */
161 while (isspace(line
[line_pos
]))
165 if (line
[line_pos
++] != '=') {
167 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"Option %s needs a parameter at line %d\n",opt
,line_num
);
174 while (isspace(line
[line_pos
]))
177 /* read the parameter */
178 if (line
[line_pos
] == '"' || line
[line_pos
] == '\'') {
181 for (param_pos
= 0; line
[line_pos
] != c
; /* NOTHING */) {
182 param
[param_pos
++] = line
[line_pos
++];
183 if (param_pos
>= MAX_PARAM_LEN
) {
185 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"Option %s has a too long parameter at line %d\n",opt
,line_num
);
191 line_pos
++; /* skip the closing " or ' */
193 for (param_pos
= 0; isprint(line
[line_pos
]) && !isspace(line
[line_pos
])
194 && line
[line_pos
] != '#'; /* NOTHING */) {
195 param
[param_pos
++] = line
[line_pos
++];
196 if (param_pos
>= MAX_PARAM_LEN
) {
198 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"too long parameter\n");
205 param
[param_pos
] = '\0';
207 /* did we read a parameter? */
208 if (param_pos
== 0) {
210 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"Option %s needs a parameter at line %d\n",opt
,line_num
);
218 mp_msg(MSGT_CFGPARSER
,MSGL_V
,"parameter: %s\n", param
);
221 /* now, check if we have some more chars on the line */
223 while (isspace(line
[line_pos
]))
227 if (line
[line_pos
] != '\0' && line
[line_pos
] != '#') {
229 mp_msg(MSGT_CFGPARSER
,MSGL_WARN
,"extra characters on line %d: %s\n",line_num
, line
+line_pos
);
234 if(!strcmp(opt
,"profile-desc"))
235 m_profile_set_desc(profile
,param
), tmp
= 1;
237 tmp
= m_config_set_profile_option(config
,profile
,
240 tmp
= m_config_set_option(config
, opt
, param
);
243 if(tmp
== M_OPT_UNKNOWN
) {
244 mp_msg(MSGT_CFGPARSER
,MSGL_WARN
,"Warning unknown option %s at line %d\n", opt
,line_num
);
247 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"Error parsing option %s=%s at line %d\n",opt
,param
,line_num
);
260 config
->mode
= prev_mode
;
265 extern int mp_msg_levels
[];
267 /// Parse the command line option that must be handled at startup.
268 int m_config_preparse_command_line(m_config_t
*config
, int argc
, char **argv
)
270 int msg_lvl
, i
, r
, ret
= 0;
273 // Hack to shutup the parser error messages.
274 msg_lvl
= mp_msg_levels
[MSGT_CFGPARSER
];
275 mp_msg_levels
[MSGT_CFGPARSER
] = -11;
277 config
->mode
= M_COMMAND_LINE_PRE_PARSE
;
279 for(i
= 1 ; i
< argc
; i
++) {
280 const m_option_t
* opt
;
283 if(arg
[0] != '-' || arg
[1] == 0) continue;
285 // No more options after --
286 if(arg
[0] == '-' && arg
[1] == 0) break;
288 opt
= m_config_get_option(config
,arg
);
289 // Ignore invalid option
291 // Set, non-pre-parse options will be ignored
292 r
= m_config_set_option(config
,arg
,
293 i
+1 < argc
? argv
[i
+1] : NULL
);
298 mp_msg_levels
[MSGT_CFGPARSER
] = msg_lvl
;