]>
wolfpit.net Git - tool/Arch-pacman/.git/blob - src/pacman/ini.c
4 * Copyright (c) 2013 Pacman Development Team <pacman-dev@archlinux.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include <string.h> /* strdup */
31 * @brief INI parser backend.
33 * @param file path to the config file
34 * @param cb callback for key/value pairs
35 * @param data caller defined data to be passed to the callback
36 * @param section_name the name of the current section
37 * @param line buffer to read into, must be at least PATH_MAX long
38 * @param depth recursion depth, should initially be 0
40 * @return 0 on success, 1 on parsing errors, the callback return value
43 static int _parse_ini(const char *file
, ini_parser_fn cb
, void *data
,
44 char **section_name
, char *line
, int depth
)
49 const int max_depth
= 10;
51 if(depth
>= max_depth
) {
52 pm_printf(ALPM_LOG_ERROR
,
53 _("config parsing exceeded max recursion depth of %d.\n"), max_depth
);
58 pm_printf(ALPM_LOG_DEBUG
, "config: attempting to read file %s\n", file
);
59 fp
= fopen(file
, "r");
61 pm_printf(ALPM_LOG_ERROR
, _("config file %s could not be read: %s\n"),
62 file
, strerror(errno
));
67 while(fgets(line
, PATH_MAX
, fp
)) {
68 char *key
, *value
, *ptr
;
73 /* ignore whole line and end of line comments */
74 if((ptr
= strchr(line
, '#'))) {
78 line_len
= strtrim(line
);
84 if(line
[0] == '[' && line
[line_len
- 1] == ']') {
86 /* only possibility here is a line == '[]' */
88 pm_printf(ALPM_LOG_ERROR
, _("config file %s, line %d: bad section name.\n"),
93 /* new config section, skip the '[' */
94 name
= strdup(line
+ 1);
95 name
[line_len
- 2] = '\0';
97 ret
= cb(file
, linenum
, name
, NULL
, NULL
, data
);
101 /* we're at a new section; perform any post-actions for the prior */
109 /* strsep modifies the 'line' string: 'key \0 value' */
117 pm_printf(ALPM_LOG_ERROR
, _("config file %s, line %d: syntax error in config file- missing key.\n"),
122 /* Include is allowed in both options and repo sections */
123 if(strcmp(key
, "Include") == 0) {
129 pm_printf(ALPM_LOG_ERROR
, _("config file %s, line %d: directive '%s' needs a value\n"),
134 /* Ignore include failures... assume non-critical */
135 globret
= glob(value
, GLOB_NOCHECK
, NULL
, &globbuf
);
138 pm_printf(ALPM_LOG_DEBUG
,
139 "config file %s, line %d: include globbing out of space\n",
143 pm_printf(ALPM_LOG_DEBUG
,
144 "config file %s, line %d: include globbing read error for %s\n",
145 file
, linenum
, value
);
148 pm_printf(ALPM_LOG_DEBUG
,
149 "config file %s, line %d: no include found for %s\n",
150 file
, linenum
, value
);
153 for(gindex
= 0; gindex
< globbuf
.gl_pathc
; gindex
++) {
154 pm_printf(ALPM_LOG_DEBUG
, "config file %s, line %d: including %s\n",
155 file
, linenum
, globbuf
.gl_pathv
[gindex
]);
156 _parse_ini(globbuf
.gl_pathv
[gindex
], cb
, data
,
157 section_name
, line
, depth
+ 1);
164 if((ret
= cb(file
, linenum
, *section_name
, key
, value
, data
)) != 0) {
170 ret
= cb(NULL
, 0, NULL
, NULL
, NULL
, data
);
179 *section_name
= NULL
;
181 pm_printf(ALPM_LOG_DEBUG
, "config: finished parsing %s\n", file
);
186 * @brief Parse a pacman-style INI config file.
188 * @param file path to the config file
189 * @param cb callback for key/value pairs
190 * @param data caller defined data to be passed to the callback
192 * @return 0 on success, 1 on parsing errors, the callback return value
195 * @note The callback will be called at the beginning of each section with an
196 * empty key and value, for each key/value pair, and when parsing is complete
197 * with all arguments except @a data empty.
199 * @note The @a key and @a value passed to @ cb will be overwritten between
200 * calls. The section name will remain valid until after @a cb is called to
201 * begin a new section.
203 * @note Parsing will immediately stop if the callback returns non-zero.
205 int parse_ini(const char *file
, ini_parser_fn cb
, void *data
)
207 char *section_name
= NULL
, line
[PATH_MAX
];
208 return _parse_ini(file
, cb
, data
, §ion_name
, line
, 0);
211 /* vim: set ts=2 sw=2 noet: */