Mercurial > mplayer.hg
annotate m_config.c @ 33306:37e215798390
Fix output of "No bind found for key" to actually make sense for
key combinations and match the binding you'd have to add to input.conf
also for these.
Previously the extra keys would end up appended at the end, resulting
in output like
> No bind found for key 'MOUSE_BTN0'.-MOUSE_BTN2
and even worse for some translations.
author | reimar |
---|---|
date | Sat, 07 May 2011 11:11:07 +0000 |
parents | b39155e98ac3 |
children | 30e60125c2f4 |
rev | line source |
---|---|
30429
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29263
diff
changeset
|
1 /* |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29263
diff
changeset
|
2 * This file is part of MPlayer. |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29263
diff
changeset
|
3 * |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29263
diff
changeset
|
4 * MPlayer is free software; you can redistribute it and/or modify |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29263
diff
changeset
|
5 * it under the terms of the GNU General Public License as published by |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29263
diff
changeset
|
6 * the Free Software Foundation; either version 2 of the License, or |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29263
diff
changeset
|
7 * (at your option) any later version. |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29263
diff
changeset
|
8 * |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29263
diff
changeset
|
9 * MPlayer is distributed in the hope that it will be useful, |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29263
diff
changeset
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29263
diff
changeset
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29263
diff
changeset
|
12 * GNU General Public License for more details. |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29263
diff
changeset
|
13 * |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29263
diff
changeset
|
14 * You should have received a copy of the GNU General Public License along |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29263
diff
changeset
|
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29263
diff
changeset
|
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
c1a3f1bbba26
Add license header to all top-level files missing them.
diego
parents:
29263
diff
changeset
|
17 */ |
18258 | 18 |
19 /// \file | |
20 /// \ingroup Config | |
21 | |
8164 | 22 #include "config.h" |
23 | |
24 #include <stdlib.h> | |
25 #include <stdio.h> | |
26 #include <errno.h> | |
27 #include <string.h> | |
28 #ifdef MP_DEBUG | |
29 #include <assert.h> | |
30 #endif | |
31 | |
32 #include "m_config.h" | |
33 #include "m_option.h" | |
34 #include "mp_msg.h" | |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
35 #include "help_mp.h" |
8164 | 36 |
17471 | 37 #define MAX_PROFILE_DEPTH 20 |
38 | |
32301
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
39 |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
40 static int parse_profile(const m_option_t *opt, const char *name, |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
41 const char *param, void *dst, int src) |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
42 { |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
43 m_config_t *config = opt->priv; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
44 char **list = NULL; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
45 int i, r; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
46 if (param && !strcmp(param, "help")) { |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
47 m_profile_t *p; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
48 if (!config->profiles) { |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
49 mp_msg(MSGT_CFGPARSER, MSGL_INFO, MSGTR_NoProfileDefined); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
50 return M_OPT_EXIT-1; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
51 } |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
52 mp_msg(MSGT_CFGPARSER, MSGL_INFO, MSGTR_AvailableProfiles); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
53 for (p = config->profiles; p; p = p->next) |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
54 mp_msg(MSGT_CFGPARSER, MSGL_INFO, "\t%s\t%s\n", p->name, |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
55 p->desc ? p->desc : ""); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
56 mp_msg(MSGT_CFGPARSER, MSGL_INFO, "\n"); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
57 return M_OPT_EXIT-1; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
58 } |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
59 |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
60 r = m_option_type_string_list.parse(opt, name, param, &list,src); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
61 if (r < 0) |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
62 return r; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
63 if (!list || !list[0]) |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
64 return M_OPT_INVALID; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
65 for (i = 0; list[i]; i++) |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
66 if (!m_config_get_profile(config,list[i])) { |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
67 mp_msg(MSGT_CFGPARSER, MSGL_WARN, MSGTR_UnknownProfile, list[i]); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
68 r = M_OPT_INVALID; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
69 } |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
70 if (dst) |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
71 m_option_copy(opt, dst, &list); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
72 else |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
73 m_option_free(opt, &list); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
74 return r; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
75 } |
17471 | 76 |
77 static void | |
32301
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
78 set_profile(const m_option_t *opt, void *dst, const void *src) |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
79 { |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
80 m_config_t *config = opt->priv; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
81 m_profile_t *p; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
82 char **list = NULL; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
83 int i; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
84 if (!src || !*(char***)src) |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
85 return; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
86 m_option_copy(opt,&list,src); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
87 for (i = 0; list[i]; i++) { |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
88 p = m_config_get_profile(config, list[i]); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
89 if (!p) |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
90 continue; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
91 m_config_set_profile(config, p); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
92 } |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
93 m_option_free(opt, &list); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
94 } |
17471 | 95 |
32301
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
96 static int show_profile(m_option_t *opt, char* name, char *param) |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
97 { |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
98 m_config_t *config = opt->priv; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
99 m_profile_t *p; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
100 int i, j; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
101 if (!param) |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
102 return M_OPT_MISSING_PARAM; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
103 if (!(p = m_config_get_profile(config, param))) { |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
104 mp_msg(MSGT_CFGPARSER, MSGL_ERR, MSGTR_UnknownProfile, param); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
105 return M_OPT_EXIT - 1; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
106 } |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
107 if (!config->profile_depth) |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
108 mp_msg(MSGT_CFGPARSER, MSGL_INFO, MSGTR_Profile, param, |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
109 p->desc ? p->desc : ""); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
110 config->profile_depth++; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
111 for (i = 0; i < p->num_opts; i++) { |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
112 char spc[config->profile_depth + 1]; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
113 for (j = 0; j < config->profile_depth; j++) |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
114 spc[j] = ' '; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
115 spc[config->profile_depth] = '\0'; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
116 |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
117 mp_msg(MSGT_CFGPARSER, MSGL_INFO, "%s%s=%s\n", spc, |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
118 p->opts[2 * i], p->opts[2 * i + 1]); |
17471 | 119 |
32301
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
120 if (config->profile_depth < MAX_PROFILE_DEPTH && |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
121 !strcmp(p->opts[2*i],"profile")) { |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
122 char *e, *list = p->opts[2 * i + 1]; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
123 while ((e = strchr(list, ','))) { |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
124 int l = e-list; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
125 char tmp[l+1]; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
126 if (!l) |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
127 continue; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
128 memcpy(tmp, list, l); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
129 tmp[l] = '\0'; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
130 show_profile(opt, name, tmp); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
131 list = e+1; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
132 } |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
133 if (list[0] != '\0') |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
134 show_profile(opt, name, list); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
135 } |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
136 } |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
137 config->profile_depth--; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
138 if (!config->profile_depth) |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
139 mp_msg(MSGT_CFGPARSER, MSGL_INFO, "\n"); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
140 return M_OPT_EXIT - 1; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
141 } |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
142 |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
143 static int list_options(m_option_t *opt, char* name, char *param) |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
144 { |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
145 m_config_t *config = opt->priv; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
146 m_config_print_option_list(config); |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
147 return M_OPT_EXIT; |
a65635702512
cosmetics: Move some functions around to avoid ugly forward declarations.
diego
parents:
32300
diff
changeset
|
148 } |
17472
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
149 |
8164 | 150 m_config_t* |
151 m_config_new(void) { | |
152 m_config_t* config; | |
25962 | 153 static int initialized = 0; |
17471 | 154 static m_option_type_t profile_opt_type; |
155 static m_option_t ref_opts[] = { | |
156 { "profile", NULL, &profile_opt_type, CONF_NOSAVE, 0, 0, NULL }, | |
157 { "show-profile", show_profile, CONF_TYPE_PRINT_FUNC, CONF_NOCFG, 0, 0, NULL }, | |
17472
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
158 { "list-options", list_options, CONF_TYPE_PRINT_FUNC, CONF_NOCFG, 0, 0, NULL }, |
17471 | 159 { NULL, NULL, NULL, 0, 0, 0, NULL } |
160 }; | |
161 int i; | |
8164 | 162 |
18879 | 163 config = calloc(1,sizeof(m_config_t)); |
8164 | 164 config->lvl = 1; // 0 Is the defaults |
25962 | 165 if(!initialized) { |
166 initialized = 1; | |
17471 | 167 profile_opt_type = m_option_type_string_list; |
168 profile_opt_type.parse = parse_profile; | |
169 profile_opt_type.set = set_profile; | |
170 } | |
171 config->self_opts = malloc(sizeof(ref_opts)); | |
172 memcpy(config->self_opts,ref_opts,sizeof(ref_opts)); | |
173 for(i = 0 ; config->self_opts[i].name ; i++) | |
174 config->self_opts[i].priv = config; | |
175 m_config_register_options(config,config->self_opts); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26408
diff
changeset
|
176 |
8164 | 177 return config; |
178 } | |
179 | |
180 void | |
181 m_config_free(m_config_t* config) { | |
182 m_config_option_t *i = config->opts, *ct; | |
183 m_config_save_slot_t *sl,*st; | |
17471 | 184 m_profile_t *p,*pn; |
185 int j; | |
8164 | 186 |
187 #ifdef MP_DEBUG | |
188 assert(config != NULL); | |
189 #endif | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26408
diff
changeset
|
190 |
8164 | 191 while(i) { |
13824 | 192 if (i->flags & M_CFG_OPT_ALIAS) |
193 sl = NULL; | |
194 else | |
195 sl = i->slots; | |
8164 | 196 while(sl) { |
197 m_option_free(i->opt,sl->data); | |
198 st = sl->prev; | |
199 free(sl); | |
200 sl = st; | |
201 } | |
202 if(i->name != i->opt->name) | |
203 free(i->name); | |
204 ct = i->next; | |
205 free(i); | |
13824 | 206 i = ct; |
8164 | 207 } |
17471 | 208 for(p = config->profiles ; p ; p = pn) { |
209 pn = p->next; | |
210 free(p->name); | |
32511
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32301
diff
changeset
|
211 free(p->desc); |
17471 | 212 for(j = 0 ; j < p->num_opts ; j++) { |
213 free(p->opts[2*j]); | |
32511
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32301
diff
changeset
|
214 free(p->opts[2*j + 1]); |
17471 | 215 } |
216 free(p->opts); | |
217 free(p); | |
218 } | |
219 free(config->self_opts); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26408
diff
changeset
|
220 free(config); |
8164 | 221 } |
222 | |
223 void | |
224 m_config_push(m_config_t* config) { | |
225 m_config_option_t *co; | |
226 m_config_save_slot_t *slot; | |
227 | |
228 #ifdef MP_DEBUG | |
229 assert(config != NULL); | |
230 assert(config->lvl > 0); | |
231 #endif | |
232 | |
233 config->lvl++; | |
234 | |
235 for(co = config->opts ; co ; co = co->next ) { | |
236 if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) | |
237 continue; | |
238 if(co->opt->flags & (M_OPT_GLOBAL|M_OPT_NOSAVE)) | |
239 continue; | |
21054
7d5035aafcc6
Fix obvious typo, although the exact effect is still unclear to me, see also bug #593.
reimar
parents:
18879
diff
changeset
|
240 if((co->opt->flags & M_OPT_OLD) && !(co->flags & M_CFG_OPT_SET)) |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
241 continue; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
242 if(co->flags & M_CFG_OPT_ALIAS) |
8164 | 243 continue; |
244 | |
245 // Update the current status | |
246 m_option_save(co->opt,co->slots->data,co->opt->p); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26408
diff
changeset
|
247 |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26408
diff
changeset
|
248 // Allocate a new slot |
18879 | 249 slot = calloc(1,sizeof(m_config_save_slot_t) + co->opt->type->size); |
8164 | 250 slot->lvl = config->lvl; |
251 slot->prev = co->slots; | |
252 co->slots = slot; | |
253 m_option_copy(co->opt,co->slots->data,co->slots->prev->data); | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
254 // Reset our set flag |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
255 co->flags &= ~M_CFG_OPT_SET; |
8164 | 256 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26408
diff
changeset
|
257 |
8164 | 258 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Config pushed level is now %d\n",config->lvl); |
259 } | |
260 | |
261 void | |
262 m_config_pop(m_config_t* config) { | |
263 m_config_option_t *co; | |
264 m_config_save_slot_t *slot; | |
265 | |
266 #ifdef MP_DEBUG | |
267 assert(config != NULL); | |
268 assert(config->lvl > 1); | |
269 #endif | |
270 | |
271 for(co = config->opts ; co ; co = co->next ) { | |
272 int pop = 0; | |
273 if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) | |
274 continue; | |
275 if(co->opt->flags & (M_OPT_GLOBAL|M_OPT_NOSAVE)) | |
276 continue; | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
277 if(co->flags & M_CFG_OPT_ALIAS) |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
278 continue; |
8164 | 279 if(co->slots->lvl > config->lvl) |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
280 mp_msg(MSGT_CFGPARSER, MSGL_WARN,MSGTR_SaveSlotTooOld,config->lvl,co->slots->lvl); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26408
diff
changeset
|
281 |
8164 | 282 while(co->slots->lvl >= config->lvl) { |
283 m_option_free(co->opt,co->slots->data); | |
284 slot = co->slots; | |
285 co->slots = slot->prev; | |
286 free(slot); | |
287 pop++; | |
288 } | |
289 if(pop) // We removed some ctx -> set the previous value | |
290 m_option_set(co->opt,co->opt->p,co->slots->data); | |
291 } | |
292 | |
293 config->lvl--; | |
294 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Config poped level=%d\n",config->lvl); | |
295 } | |
296 | |
297 static void | |
25225
51c23a18a17b
First try to mark some things in m_config correctly as const
reimar
parents:
23868
diff
changeset
|
298 m_config_add_option(m_config_t *config, const m_option_t *arg, const char* prefix) { |
8164 | 299 m_config_option_t *co; |
300 m_config_save_slot_t* sl; | |
301 | |
302 #ifdef MP_DEBUG | |
303 assert(config != NULL); | |
304 assert(config->lvl > 0); | |
305 assert(arg != NULL); | |
306 #endif | |
307 | |
308 // Allocate a new entry for this option | |
18879 | 309 co = calloc(1,sizeof(m_config_option_t) + arg->type->size); |
8164 | 310 co->opt = arg; |
311 | |
312 // Fill in the full name | |
313 if(prefix && strlen(prefix) > 0) { | |
314 int l = strlen(prefix) + 1 + strlen(arg->name) + 1; | |
23806 | 315 co->name = malloc(l); |
8164 | 316 sprintf(co->name,"%s:%s",prefix,arg->name); |
317 } else | |
318 co->name = arg->name; | |
319 | |
23868 | 320 // Option with children -> add them |
8164 | 321 if(arg->type->flags & M_OPT_TYPE_HAS_CHILD) { |
25225
51c23a18a17b
First try to mark some things in m_config correctly as const
reimar
parents:
23868
diff
changeset
|
322 const m_option_t *ol = arg->p; |
8164 | 323 int i; |
13824 | 324 co->slots = NULL; |
8164 | 325 for(i = 0 ; ol[i].name != NULL ; i++) |
326 m_config_add_option(config,&ol[i], co->name); | |
327 } else { | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
328 m_config_option_t *i; |
23868 | 329 // Check if there is already an option pointing to this address |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
330 if(arg->p) { |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
331 for(i = config->opts ; i ; i = i->next ) { |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
332 if(i->opt->p == arg->p) { // So we don't save the same vars more than 1 time |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
333 co->slots = i->slots; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
334 co->flags |= M_CFG_OPT_ALIAS; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
335 break; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
336 } |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
337 } |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
338 } |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
339 if(!(co->flags & M_CFG_OPT_ALIAS)) { |
8164 | 340 // Allocate a slot for the defaults |
18879 | 341 sl = calloc(1,sizeof(m_config_save_slot_t) + arg->type->size); |
8164 | 342 m_option_save(arg,sl->data,(void**)arg->p); |
23868 | 343 // Hack to avoid too much trouble with dynamically allocated data : |
8164 | 344 // We always use a dynamic version |
345 if((arg->type->flags & M_OPT_TYPE_DYNAMIC) && arg->p && (*(void**)arg->p)) { | |
346 *(void**)arg->p = NULL; | |
347 m_option_set(arg,arg->p,sl->data); | |
348 } | |
349 sl->lvl = 0; | |
13824 | 350 sl->prev = NULL; |
18879 | 351 co->slots = calloc(1,sizeof(m_config_save_slot_t) + arg->type->size); |
8164 | 352 co->slots->prev = sl; |
353 co->slots->lvl = config->lvl; | |
354 m_option_copy(co->opt,co->slots->data,sl->data); | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
355 } // !M_OPT_ALIAS |
8164 | 356 } |
357 co->next = config->opts; | |
358 config->opts = co; | |
359 } | |
360 | |
361 int | |
25225
51c23a18a17b
First try to mark some things in m_config correctly as const
reimar
parents:
23868
diff
changeset
|
362 m_config_register_options(m_config_t *config, const m_option_t *args) { |
8164 | 363 int i; |
364 | |
365 #ifdef MP_DEBUG | |
366 assert(config != NULL); | |
367 assert(config->lvl > 0); | |
368 assert(args != NULL); | |
369 #endif | |
370 | |
371 for(i = 0 ; args[i].name != NULL ; i++) | |
372 m_config_add_option(config,&args[i],NULL); | |
373 | |
374 return 1; | |
375 } | |
376 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26408
diff
changeset
|
377 static m_config_option_t* |
32300
1ca3d798b518
Mark some function parameters that are not modified as const.
diego
parents:
30728
diff
changeset
|
378 m_config_get_co(const m_config_t *config, char *arg) { |
8164 | 379 m_config_option_t *co; |
380 | |
381 for(co = config->opts ; co ; co = co->next ) { | |
382 int l = strlen(co->name) - 1; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26408
diff
changeset
|
383 if((co->opt->type->flags & M_OPT_TYPE_ALLOW_WILDCARD) && |
8164 | 384 (co->name[l] == '*')) { |
385 if(strncasecmp(co->name,arg,l) == 0) | |
386 return co; | |
387 } else if(strcasecmp(co->name,arg) == 0) | |
388 return co; | |
389 } | |
390 return NULL; | |
391 } | |
392 | |
393 static int | |
32300
1ca3d798b518
Mark some function parameters that are not modified as const.
diego
parents:
30728
diff
changeset
|
394 m_config_parse_option(const m_config_t *config, char *arg, char *param, int set) { |
8164 | 395 m_config_option_t *co; |
396 int r = 0; | |
397 | |
398 #ifdef MP_DEBUG | |
399 assert(config != NULL); | |
400 assert(config->lvl > 0); | |
401 assert(arg != NULL); | |
402 #endif | |
403 | |
404 co = m_config_get_co(config,arg); | |
8892 | 405 if(!co){ |
8894 | 406 // mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Unknown option: %s\n",arg); |
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
|
407 return M_OPT_UNKNOWN; |
8892 | 408 } |
8164 | 409 |
410 #ifdef MP_DEBUG | |
411 // This is the only mandatory function | |
412 assert(co->opt->type->parse); | |
413 #endif | |
414 | |
23868 | 415 // Check if this option isn't forbidden in the current mode |
8164 | 416 if((config->mode == M_CONFIG_FILE) && (co->opt->flags & M_OPT_NOCFG)) { |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
417 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_InvalidCfgfileOption,arg); |
8164 | 418 return M_OPT_INVALID; |
419 } | |
420 if((config->mode == M_COMMAND_LINE) && (co->opt->flags & M_OPT_NOCMD)) { | |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
421 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_InvalidCmdlineOption,arg); |
8164 | 422 return M_OPT_INVALID; |
423 } | |
26408
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26288
diff
changeset
|
424 // During command line preparse set only pre-parse options |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26288
diff
changeset
|
425 // Otherwise only set pre-parse option if they were not already set. |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26288
diff
changeset
|
426 if(((config->mode == M_COMMAND_LINE_PRE_PARSE) && |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26288
diff
changeset
|
427 !(co->opt->flags & M_OPT_PRE_PARSE)) || |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26288
diff
changeset
|
428 ((config->mode != M_COMMAND_LINE_PRE_PARSE) && |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26288
diff
changeset
|
429 (co->opt->flags & M_OPT_PRE_PARSE) && (co->flags & M_CFG_OPT_SET))) |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26288
diff
changeset
|
430 set = 0; |
8164 | 431 |
23868 | 432 // Option with children are a bit different to parse |
8164 | 433 if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) { |
434 char** lst = NULL; | |
435 int i,sr; | |
436 // Parse the child options | |
9593
e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
albeu
parents:
9222
diff
changeset
|
437 r = m_option_parse(co->opt,arg,param,&lst,M_COMMAND_LINE); |
8164 | 438 // Set them now |
8894 | 439 if(r >= 0) |
8164 | 440 for(i = 0 ; lst && lst[2*i] ; i++) { |
441 int l = strlen(co->name) + 1 + strlen(lst[2*i]) + 1; | |
442 if(r >= 0) { | |
443 // Build the full name | |
444 char n[l]; | |
445 sprintf(n,"%s:%s",co->name,lst[2*i]); | |
446 sr = m_config_parse_option(config,n,lst[2*i+1],set); | |
8894 | 447 if(sr < 0){ |
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
|
448 if(sr == M_OPT_UNKNOWN){ |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
449 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_InvalidSuboption,co->name,lst[2*i]); |
8894 | 450 r = M_OPT_INVALID; |
451 } else | |
9222 | 452 if(sr == M_OPT_MISSING_PARAM){ |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
453 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_MissingSuboptionParameter,lst[2*i],co->name); |
9222 | 454 r = M_OPT_INVALID; |
455 } else | |
8894 | 456 r = sr; |
457 } | |
8164 | 458 } |
459 free(lst[2*i]); | |
460 free(lst[2*i+1]); | |
461 } | |
32511
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32301
diff
changeset
|
462 free(lst); |
8164 | 463 } else |
464 r = m_option_parse(co->opt,arg,param,set ? co->slots->data : NULL,config->mode); | |
465 | |
466 // Parsing failed ? | |
467 if(r < 0) | |
468 return r; | |
469 // Set the option | |
470 if(set) { | |
471 m_option_set(co->opt,co->opt->p,co->slots->data); | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
472 co->flags |= M_CFG_OPT_SET; |
8164 | 473 } |
474 | |
475 return r; | |
476 } | |
477 | |
478 int | |
479 m_config_set_option(m_config_t *config, char* arg, char* param) { | |
480 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Setting %s=%s\n",arg,param); | |
481 return m_config_parse_option(config,arg,param,1); | |
482 } | |
483 | |
484 int | |
32300
1ca3d798b518
Mark some function parameters that are not modified as const.
diego
parents:
30728
diff
changeset
|
485 m_config_check_option(const m_config_t *config, char *arg, char *param) { |
9222 | 486 int r; |
8164 | 487 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Checking %s=%s\n",arg,param); |
9222 | 488 r=m_config_parse_option(config,arg,param,0); |
489 if(r==M_OPT_MISSING_PARAM){ | |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
490 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_MissingOptionParameter,arg); |
9222 | 491 return M_OPT_INVALID; |
492 } | |
493 return r; | |
8164 | 494 } |
495 | |
496 | |
25225
51c23a18a17b
First try to mark some things in m_config correctly as const
reimar
parents:
23868
diff
changeset
|
497 const m_option_t* |
32300
1ca3d798b518
Mark some function parameters that are not modified as const.
diego
parents:
30728
diff
changeset
|
498 m_config_get_option(const m_config_t *config, char *arg) { |
8164 | 499 m_config_option_t *co; |
500 | |
501 #ifdef MP_DEBUG | |
502 assert(config != NULL); | |
503 assert(config->lvl > 0); | |
504 assert(arg != NULL); | |
505 #endif | |
506 | |
507 co = m_config_get_co(config,arg); | |
508 if(co) | |
509 return co->opt; | |
510 else | |
511 return NULL; | |
512 } | |
513 | |
514 | |
515 void | |
32300
1ca3d798b518
Mark some function parameters that are not modified as const.
diego
parents:
30728
diff
changeset
|
516 m_config_print_option_list(const m_config_t *config) { |
8164 | 517 char min[50],max[50]; |
518 m_config_option_t* co; | |
519 int count = 0; | |
520 | |
521 if(!config->opts) return; | |
522 | |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
523 mp_msg(MSGT_CFGPARSER, MSGL_INFO, MSGTR_OptionListHeader); |
8164 | 524 for(co = config->opts ; co ; co = co->next) { |
25225
51c23a18a17b
First try to mark some things in m_config correctly as const
reimar
parents:
23868
diff
changeset
|
525 const m_option_t* opt = co->opt; |
8164 | 526 if(opt->type->flags & M_OPT_TYPE_HAS_CHILD) continue; |
527 if(opt->flags & M_OPT_MIN) | |
528 sprintf(min,"%-8.0f",opt->min); | |
529 else | |
530 strcpy(min,"No"); | |
531 if(opt->flags & M_OPT_MAX) | |
532 sprintf(max,"%-8.0f",opt->max); | |
533 else | |
534 strcpy(max,"No"); | |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
535 mp_msg(MSGT_CFGPARSER, MSGL_INFO, " %-20.20s %-15.15s %-10.10s %-10.10s %-3.3s %-3.3s %-3.3s\n", |
8164 | 536 co->name, |
537 co->opt->type->name, | |
538 min, | |
539 max, | |
540 opt->flags & CONF_GLOBAL ? "Yes" : "No", | |
541 opt->flags & CONF_NOCMD ? "No" : "Yes", | |
542 opt->flags & CONF_NOCFG ? "No" : "Yes"); | |
543 count++; | |
544 } | |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
545 mp_msg(MSGT_CFGPARSER, MSGL_INFO, MSGTR_TotalOptions,count); |
8164 | 546 } |
17471 | 547 |
548 m_profile_t* | |
32300
1ca3d798b518
Mark some function parameters that are not modified as const.
diego
parents:
30728
diff
changeset
|
549 m_config_get_profile(const m_config_t *config, char *name) { |
17471 | 550 m_profile_t* p; |
551 for(p = config->profiles ; p ; p = p->next) | |
552 if(!strcmp(p->name,name)) return p; | |
553 return NULL; | |
554 } | |
555 | |
556 m_profile_t* | |
557 m_config_add_profile(m_config_t* config, char* name) { | |
558 m_profile_t* p = m_config_get_profile(config,name); | |
559 if(p) return p; | |
560 p = calloc(1,sizeof(m_profile_t)); | |
561 p->name = strdup(name); | |
562 p->next = config->profiles; | |
563 config->profiles = p; | |
564 return p; | |
565 } | |
566 | |
567 void | |
568 m_profile_set_desc(m_profile_t* p, char* desc) { | |
32511
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32301
diff
changeset
|
569 free(p->desc); |
17471 | 570 p->desc = desc ? strdup(desc) : NULL; |
571 } | |
572 | |
573 int | |
574 m_config_set_profile_option(m_config_t* config, m_profile_t* p, | |
575 char* name, char* val) { | |
576 int i = m_config_check_option(config,name,val); | |
577 if(i < 0) return i; | |
578 if(p->opts) p->opts = realloc(p->opts,2*(p->num_opts+2)*sizeof(char*)); | |
579 else p->opts = malloc(2*(p->num_opts+2)*sizeof(char*)); | |
580 p->opts[p->num_opts*2] = strdup(name); | |
581 p->opts[p->num_opts*2+1] = val ? strdup(val) : NULL; | |
582 p->num_opts++; | |
583 p->opts[p->num_opts*2] = p->opts[p->num_opts*2+1] = NULL; | |
17856 | 584 return 1; |
17471 | 585 } |
586 | |
25634 | 587 void |
17471 | 588 m_config_set_profile(m_config_t* config, m_profile_t* p) { |
589 int i; | |
590 if(config->profile_depth > MAX_PROFILE_DEPTH) { | |
18335 | 591 mp_msg(MSGT_CFGPARSER, MSGL_WARN, MSGTR_ProfileInclusionTooDeep); |
17471 | 592 return; |
593 } | |
594 config->profile_depth++; | |
595 for(i = 0 ; i < p->num_opts ; i++) | |
596 m_config_set_option(config,p->opts[2*i],p->opts[2*i+1]); | |
597 config->profile_depth--; | |
598 } |