lib/conf.c: cleanup a bit

This commit is contained in:
Duncan Overbruck
2021-06-26 15:26:18 +02:00
parent 453595a822
commit 248ca4b152
2 changed files with 77 additions and 70 deletions

View File

@@ -50,37 +50,28 @@
* Functions for parsing xbps configuration files. * Functions for parsing xbps configuration files.
*/ */
static void static int
store_vars(struct xbps_handle *xhp, xbps_dictionary_t *d, store_virtualpkg(struct xbps_handle *xhp, const char *path, size_t line, char *val)
const char *key, const char *path, size_t line, char *buf)
{ {
char *lp, *rp, *tc; char *p;
size_t len;
if (*d == NULL)
*d = xbps_dictionary_create();
if (xhp->vpkgd_conf == NULL)
xhp->vpkgd_conf = xbps_dictionary_create();
/* /*
* Parse strings delimited by ':' i.e * Parse strings delimited by ':' i.e
* <left>:<right> * <left>:<right>
*/ */
lp = buf; p = strchr(val, ':');
rp = strchr(buf, ':'); if (p == NULL || p[1] == '\0') {
if (rp == NULL || *rp == '\0') {
xbps_dbg_printf(xhp, "%s: ignoring invalid " xbps_dbg_printf(xhp, "%s: ignoring invalid "
"%s option at line %zu\n", path, key, line); "virtualpkg option at line %zu\n", path, line);
return; return 0;
} }
tc = strchr(buf, ':'); *p++ = '\0';
len = strlen(buf) - strlen(tc);
lp[len] = '\0';
rp++; if (!xbps_dictionary_set_cstring(xhp->vpkgd, val, p))
xbps_dictionary_set_cstring(*d, lp, rp); return -errno;
xbps_dictionary_set_cstring(xhp->vpkgd_conf, lp, rp); if (!xbps_dictionary_set_cstring(xhp->vpkgd_conf, val, p))
xbps_dbg_printf(xhp, "%s: added %s %s for %s\n", path, key, lp, rp); return -errno;
xbps_dbg_printf(xhp, "%s: added virtualpkg %s for %s\n", path, val, p);
return 1;
} }
static void static void
@@ -184,60 +175,61 @@ static const struct key {
{ "cachedir", 8, KEY_CACHEDIR }, { "cachedir", 8, KEY_CACHEDIR },
{ "ignorepkg", 9, KEY_IGNOREPKG }, { "ignorepkg", 9, KEY_IGNOREPKG },
{ "include", 7, KEY_INCLUDE }, { "include", 7, KEY_INCLUDE },
{ "keepconf", 8, KEY_KEEPCONF },
{ "noextract", 9, KEY_NOEXTRACT }, { "noextract", 9, KEY_NOEXTRACT },
{ "preserve", 8, KEY_PRESERVE }, { "preserve", 8, KEY_PRESERVE },
{ "repository", 10, KEY_REPOSITORY }, { "repository", 10, KEY_REPOSITORY },
{ "rootdir", 7, KEY_ROOTDIR }, { "rootdir", 7, KEY_ROOTDIR },
{ "syslog", 6, KEY_SYSLOG }, { "syslog", 6, KEY_SYSLOG },
{ "virtualpkg", 10, KEY_VIRTUALPKG }, { "virtualpkg", 10, KEY_VIRTUALPKG },
{ "keepconf", 8, KEY_KEEPCONF },
}; };
static int static int
parse_option(char *buf, const char **keyp, char **valp) cmpkey(const void *a, const void *b)
{ {
size_t klen, end; const struct key *ka = a;
const char *key; const struct key *kb = b;
char *value; return strncmp(ka->str, kb->str, ka->len);
int k = 0;
for (unsigned int i = 0; i < __arraycount(keys); i++) {
key = keys[i].str;
klen = keys[i].len;
if (strncmp(buf, key, klen) == 0) {
k = keys[i].key;
break;
} }
}
/* non matching option */
if (k == 0)
return 0;
/* check if next char is the equal sign */ static int
if (buf[klen] != '=') parse_option(char *line, size_t linelen, char **valp, size_t *vallen)
return 0; {
size_t len;
char *p;
struct key needle, *result;
/* skip equal sign */ p = strpbrk(line, " \t=");
value = buf + klen + 1; if (p == NULL)
return KEY_ERROR;
needle.str = line;
needle.len = p-line;
/* eat blanks */ while (*p && isblank((unsigned char)*p))
while (isblank((unsigned char)*value)) p++;
value++; if (*p != '=')
return KEY_ERROR;
end = strlen(value); result = bsearch(&needle, keys, __arraycount(keys), sizeof(struct key), cmpkey);
/* eat trailing spaces, end - 1 here because \0 should be set -after- the first non-space if (result == NULL)
* if end points at the actual current character, we can never make it an empty string return KEY_ERROR;
* because than end needs to be set to -1, but end is a unsigned type thus would result in underflow */
while (end > 0 && isspace((unsigned char)value[end - 1]))
end--;
value[end] = '\0'; p++;
while (isblank((unsigned char)*p))
p++;
/* option processed successfully */ len = linelen-(p-line);
*keyp = key; /* eat trailing spaces, len - 1 here because \0 should be set -after- the first non-space
*valp = value; * if len points at the actual current character, we can never make it an empty string
* because than end needs to be set to -1, but len is a unsigned type thus would result in underflow */
while (len > 0 && isblank((unsigned char)p[len-1]))
len--;
return k; p[len] = '\0';
*valp = p;
*vallen = len;
return result->key;
} }
static int parse_file(struct xbps_handle *, const char *, bool); static int parse_file(struct xbps_handle *, const char *, bool);
@@ -283,7 +275,7 @@ parse_file(struct xbps_handle *xhp, const char *path, bool nested)
{ {
FILE *fp; FILE *fp;
size_t len, nlines = 0; size_t len, nlines = 0;
ssize_t nread; ssize_t rd;
char *line = NULL; char *line = NULL;
int rv = 0; int rv = 0;
int size, rs; int size, rs;
@@ -297,22 +289,25 @@ parse_file(struct xbps_handle *xhp, const char *path, bool nested)
xbps_dbg_printf(xhp, "Parsing configuration file: %s\n", path); xbps_dbg_printf(xhp, "Parsing configuration file: %s\n", path);
while (rv == 0 && (nread = getline(&line, &len, fp)) != -1) { while ((rd = getline(&line, &len, fp)) != -1) {
const char *key; char *val = NULL;
char *p, *val; size_t vallen;
if (line[rd-1] == '\n') {
line[rd-1] = '\0';
rd--;
}
nlines++; nlines++;
p = line;
/* eat blanks */ /* eat blanks */
while (isblank((unsigned char)*p)) while (isblank((unsigned char)*line))
p++; line++;
/* ignore comments or empty lines */ /* ignore comments or empty lines */
if (*p == '#' || *p == '\n') if (line[0] == '#' || line[0] == '\n')
continue; continue;
switch (parse_option(p, &key, &val)) { switch (parse_option(line, rd, &val, &vallen)) {
case KEY_ERROR: case KEY_ERROR:
xbps_dbg_printf(xhp, "%s: ignoring invalid option at " xbps_dbg_printf(xhp, "%s: ignoring invalid option at "
"line %zu\n", path, nlines); "line %zu\n", path, nlines);
@@ -359,7 +354,12 @@ parse_file(struct xbps_handle *xhp, const char *path, bool nested)
xbps_dbg_printf(xhp, "%s: added repository %s\n", path, val); xbps_dbg_printf(xhp, "%s: added repository %s\n", path, val);
break; break;
case KEY_VIRTUALPKG: case KEY_VIRTUALPKG:
store_vars(xhp, &xhp->vpkgd, key, path, nlines, val); rv = store_virtualpkg(xhp, path, nlines, val);
if (rv < 0) {
rv = -rv;
break;
}
rv = 0;
break; break;
case KEY_PRESERVE: case KEY_PRESERVE:
store_preserved_file(xhp, val); store_preserved_file(xhp, val);

View File

@@ -90,6 +90,13 @@ xbps_init(struct xbps_handle *xhp)
xbps_fetch_set_cache_connection(XBPS_FETCH_CACHECONN, XBPS_FETCH_CACHECONN_HOST); xbps_fetch_set_cache_connection(XBPS_FETCH_CACHECONN, XBPS_FETCH_CACHECONN_HOST);
xhp->vpkgd = xbps_dictionary_create();
if (xhp->vpkgd == NULL)
return errno ? errno : ENOMEM;
xhp->vpkgd_conf = xbps_dictionary_create();
if (xhp->vpkgd_conf == NULL)
return errno ? errno : ENOMEM;
/* process xbps.d directories */ /* process xbps.d directories */
if ((rv = xbps_conf_init(xhp)) != 0) if ((rv = xbps_conf_init(xhp)) != 0)
return rv; return rv;