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 if ((fp
= fopen(conffile
, "r")) == NULL
) {
79 mp_msg(MSGT_CFGPARSER
,MSGL_V
,": %s\n", strerror(errno
));
84 mp_msg(MSGT_CFGPARSER
,MSGL_INFO
,"\n");
86 while (fgets(line
, MAX_LINE_LEN
, fp
)) {
88 mp_msg(MSGT_CFGPARSER
,MSGL_FATAL
,"too many errors\n");
95 /* skip whitespaces */
96 while (isspace(line
[line_pos
]))
100 if (line
[line_pos
] == '\0' || line
[line_pos
] == '#')
104 for (opt_pos
= 0; isprint(line
[line_pos
]) &&
105 line
[line_pos
] != ' ' &&
106 line
[line_pos
] != '#' &&
107 line
[line_pos
] != '='; /* NOTHING */) {
108 opt
[opt_pos
++] = line
[line_pos
++];
109 if (opt_pos
>= MAX_OPT_LEN
) {
111 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"too long option at line %d\n",line_num
);
119 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"parse error at line %d\n",line_num
);
126 /* Profile declaration */
127 if(opt_pos
> 2 && opt
[0] == '[' && opt
[opt_pos
-1] == ']') {
128 opt
[opt_pos
-1] = '\0';
129 if(strcmp(opt
+1,"default"))
130 profile
= m_config_add_profile(config
,opt
+1);
138 mp_msg(MSGT_CFGPARSER
,MSGL_V
,"option: %s\n", opt
);
141 /* skip whitespaces */
142 while (isspace(line
[line_pos
]))
146 if (line
[line_pos
++] != '=') {
148 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"Option %s needs a parameter at line %d\n",opt
,line_num
);
155 while (isspace(line
[line_pos
]))
158 /* read the parameter */
159 if (line
[line_pos
] == '"' || line
[line_pos
] == '\'') {
162 for (param_pos
= 0; line
[line_pos
] != c
; /* NOTHING */) {
163 param
[param_pos
++] = line
[line_pos
++];
164 if (param_pos
>= MAX_PARAM_LEN
) {
166 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"Option %s has a too long parameter at line %d\n",opt
,line_num
);
172 line_pos
++; /* skip the closing " or ' */
174 for (param_pos
= 0; isprint(line
[line_pos
]) && !isspace(line
[line_pos
])
175 && line
[line_pos
] != '#'; /* NOTHING */) {
176 param
[param_pos
++] = line
[line_pos
++];
177 if (param_pos
>= MAX_PARAM_LEN
) {
179 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"too long parameter\n");
186 param
[param_pos
] = '\0';
188 /* did we read a parameter? */
189 if (param_pos
== 0) {
191 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"Option %s needs a parameter at line %d\n",opt
,line_num
);
199 mp_msg(MSGT_CFGPARSER
,MSGL_V
,"parameter: %s\n", param
);
202 /* now, check if we have some more chars on the line */
204 while (isspace(line
[line_pos
]))
208 if (line
[line_pos
] != '\0' && line
[line_pos
] != '#') {
210 mp_msg(MSGT_CFGPARSER
,MSGL_WARN
,"extra characters on line %d: %s\n",line_num
, line
+line_pos
);
215 if(!strcmp(opt
,"profile-desc"))
216 m_profile_set_desc(profile
,param
), tmp
= 1;
218 tmp
= m_config_set_profile_option(config
,profile
,
221 tmp
= m_config_set_option(config
, opt
, param
);
224 if(tmp
== M_OPT_UNKNOWN
) {
225 mp_msg(MSGT_CFGPARSER
,MSGL_WARN
,"Warning unknown option %s at line %d\n", opt
,line_num
);
228 mp_msg(MSGT_CFGPARSER
,MSGL_ERR
,"Error parsing option %s=%s at line %d\n",opt
,param
,line_num
);
241 config
->mode
= prev_mode
;