2 /// \defgroup ConfigParsers Config parsers
4 /// The \ref ConfigParsers make use of the \ref Config to setup the config variables,
5 /// the command line parsers also build the playlist.
26 /// Maximal include depth.
27 #define MAX_RECURSION_DEPTH 8
29 /// Current include depth.
30 static int recursion_depth
= 0;
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.
37 int m_config_parse_config_file(m_config_t
* config
, char *conffile
)
39 #define PRINT_LINENUM mp_msg(MSGT_CFGPARSER,MSGL_V,"%s(%d): ", conffile, line_num)
40 #define MAX_LINE_LEN 10000
41 #define MAX_OPT_LEN 1000
42 #define MAX_PARAM_LEN 1000
45 char opt
[MAX_OPT_LEN
+ 1];
46 char param
[MAX_PARAM_LEN
+ 1];
47 char c
; /* for the "" and '' check */
50 int line_pos
; /* line pos */
51 int opt_pos
; /* opt pos */
52 int param_pos
; /* param pos */
55 int prev_mode
= config
->mode
;
56 m_profile_t
* profile
= NULL
;
59 assert(config
!= NULL
);
60 // assert(conf_list != NULL);
62 mp_msg(MSGT_CFGPARSER
,MSGL_V
,"Reading config file %s", conffile
);
64 if (recursion_depth
> MAX_RECURSION_DEPTH
) {
65 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,": too deep 'include'. check your configfiles\n");
70 config
->mode
= M_CONFIG_FILE
;
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
));
78 mp_msg(MSGT_CFGPARSER
,MSGL_V
,"\n");
80 if ((fp
= fopen(conffile
, "r")) == NULL
) {
81 mp_msg(MSGT_CFGPARSER
,MSGL_V
,": %s\n", strerror(errno
));
87 while (fgets(line
, MAX_LINE_LEN
, fp
)) {
89 mp_msg(MSGT_CFGPARSER
,MSGL_FATAL
,"too many errors\n");
96 /* skip whitespaces */
97 while (isspace(line
[line_pos
]))
101 if (line
[line_pos
] == '\0' || line
[line_pos
] == '#')
105 for (opt_pos
= 0; isprint(line
[line_pos
]) &&
106 line
[line_pos
] != ' ' &&
107 line
[line_pos
] != '#' &&
108 line
[line_pos
] != '='; /* NOTHING */) {
109 opt
[opt_pos
++] = line
[line_pos
++];
110 if (opt_pos
>= MAX_OPT_LEN
) {
112 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"too long option at line %d\n",line_num
);
120 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"parse error at line %d\n",line_num
);
127 /* Profile declaration */
128 if(opt_pos
> 2 && opt
[0] == '[' && opt
[opt_pos
-1] == ']') {
129 opt
[opt_pos
-1] = '\0';
130 if(strcmp(opt
+1,"default"))
131 profile
= m_config_add_profile(config
,opt
+1);
139 mp_msg(MSGT_CFGPARSER
,MSGL_V
,"option: %s\n", opt
);
142 /* skip whitespaces */
143 while (isspace(line
[line_pos
]))
147 if (line
[line_pos
++] != '=') {
149 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"Option %s needs a parameter at line %d\n",opt
,line_num
);
156 while (isspace(line
[line_pos
]))
159 /* read the parameter */
160 if (line
[line_pos
] == '"' || line
[line_pos
] == '\'') {
163 for (param_pos
= 0; line
[line_pos
] != c
; /* NOTHING */) {
164 param
[param_pos
++] = line
[line_pos
++];
165 if (param_pos
>= MAX_PARAM_LEN
) {
167 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"Option %s has a too long parameter at line %d\n",opt
,line_num
);
173 line_pos
++; /* skip the closing " or ' */
175 for (param_pos
= 0; isprint(line
[line_pos
]) && !isspace(line
[line_pos
])
176 && line
[line_pos
] != '#'; /* NOTHING */) {
177 param
[param_pos
++] = line
[line_pos
++];
178 if (param_pos
>= MAX_PARAM_LEN
) {
180 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"too long parameter\n");
187 param
[param_pos
] = '\0';
189 /* did we read a parameter? */
190 if (param_pos
== 0) {
192 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"Option %s needs a parameter at line %d\n",opt
,line_num
);
200 mp_msg(MSGT_CFGPARSER
,MSGL_V
,"parameter: %s\n", param
);
203 /* now, check if we have some more chars on the line */
205 while (isspace(line
[line_pos
]))
209 if (line
[line_pos
] != '\0' && line
[line_pos
] != '#') {
211 mp_msg(MSGT_CFGPARSER
,MSGL_WARN
,"extra characters on line %d: %s\n",line_num
, line
+line_pos
);
216 if(!strcmp(opt
,"profile-desc"))
217 m_profile_set_desc(profile
,param
), tmp
= 1;
219 tmp
= m_config_set_profile_option(config
,profile
,
222 tmp
= m_config_set_option(config
, opt
, param
);
225 if(tmp
== M_OPT_UNKNOWN
) {
226 mp_msg(MSGT_CFGPARSER
,MSGL_WARN
,"Warning unknown option %s at line %d\n", opt
,line_num
);
229 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"Error parsing option %s=%s at line %d\n",opt
,param
,line_num
);
242 config
->mode
= prev_mode
;