diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-09-10 15:38:44 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-09-10 15:38:44 +0900 |
commit | 79b3a6b7ab494c5ff10e740fd147f21a04907907 (patch) | |
tree | 4d4a0edc3666922135d2d2a2e4a93dd2d695ce47 /ext | |
parent | 26781f8c44b4495fba2d0f4a39fe6379b08f32ce (diff) | |
download | libsolv-79b3a6b7ab494c5ff10e740fd147f21a04907907.tar.gz libsolv-79b3a6b7ab494c5ff10e740fd147f21a04907907.tar.bz2 libsolv-79b3a6b7ab494c5ff10e740fd147f21a04907907.zip |
Imported Upstream version 0.7.2upstream/0.7.2
Diffstat (limited to 'ext')
-rw-r--r-- | ext/repo_appdata.c | 22 | ||||
-rw-r--r-- | ext/repo_arch.c | 5 | ||||
-rw-r--r-- | ext/repo_comps.c | 13 | ||||
-rw-r--r-- | ext/repo_content.c | 3 | ||||
-rw-r--r-- | ext/repo_cudf.c | 15 | ||||
-rw-r--r-- | ext/repo_deb.c | 4 | ||||
-rw-r--r-- | ext/repo_deltainfoxml.c | 12 | ||||
-rw-r--r-- | ext/repo_helix.c | 14 | ||||
-rw-r--r-- | ext/repo_mdk.c | 15 | ||||
-rw-r--r-- | ext/repo_products.c | 21 | ||||
-rw-r--r-- | ext/repo_repomdxml.c | 13 | ||||
-rw-r--r-- | ext/repo_rpmdb.c | 7 | ||||
-rw-r--r-- | ext/repo_rpmmd.c | 12 | ||||
-rw-r--r-- | ext/repo_updateinfoxml.c | 12 | ||||
-rw-r--r-- | ext/repo_zyppdb.c | 20 | ||||
-rw-r--r-- | ext/solv_jsonparser.c | 294 | ||||
-rw-r--r-- | ext/solv_jsonparser.h | 49 | ||||
-rw-r--r-- | ext/solv_xmlparser.c | 41 | ||||
-rw-r--r-- | ext/solv_xmlparser.h | 12 | ||||
-rw-r--r-- | ext/testcase.c | 12 |
20 files changed, 441 insertions, 155 deletions
diff --git a/ext/repo_appdata.c b/ext/repo_appdata.c index 03098e2..3174968 100644 --- a/ext/repo_appdata.c +++ b/ext/repo_appdata.c @@ -420,19 +420,6 @@ endElement(struct solv_xmlparser *xmlp, int state, char *content) } } -static void -errorCallback(struct solv_xmlparser *xmlp, const char *errstr, unsigned int line, unsigned int column) -{ - struct parsedata *pd = xmlp->userdata; - pool_debug(pd->pool, SOLV_ERROR, "repo_appdata: %s at line %u:%u\n", errstr, line, column); - pd->ret = -1; - if (pd->solvable) - { - repo_free_solvable(pd->repo, pd->solvable - pd->pool->solvables, 1); - pd->solvable = 0; - } -} - static int repo_add_appdata_fn(Repo *repo, FILE *fp, int flags, const char *filename, Queue *owners) { @@ -448,8 +435,13 @@ repo_add_appdata_fn(Repo *repo, FILE *fp, int flags, const char *filename, Queue pd.filename = filename; pd.owners = owners; - solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement, errorCallback); - solv_xmlparser_parse(&pd.xmlp, fp); + solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement); + if (solv_xmlparser_parse(&pd.xmlp, fp) != SOLV_XMLPARSER_OK) + { + pool_debug(pd.pool, SOLV_ERROR, "repo_appdata: %s at line %u:%u\n", pd.xmlp.errstr, pd.xmlp.line, pd.xmlp.column); + pd.ret = -1; + pd.solvable = solvable_free(pd.solvable, 1); + } solv_xmlparser_free(&pd.xmlp); solv_free(pd.desktop_file); diff --git a/ext/repo_arch.c b/ext/repo_arch.c index a0c45ce..698d506 100644 --- a/ext/repo_arch.c +++ b/ext/repo_arch.c @@ -444,8 +444,7 @@ repo_add_arch_pkg(Repo *repo, const char *fn, int flags) if (s && !s->name) { pool_error(pool, -1, "%s: package has no name", fn); - repo_free_solvable(repo, s - pool->solvables, 1); - s = 0; + s = solvable_free(s, 1); } if (s) { @@ -728,7 +727,7 @@ finishsolvable(Repo *repo, Solvable *s) return; if (!s->name) { - repo_free_solvable(repo, s - pool->solvables, 1); + solvable_free(s, 1); return; } if (!s->arch) diff --git a/ext/repo_comps.c b/ext/repo_comps.c index 255ecb1..9400e1e 100644 --- a/ext/repo_comps.c +++ b/ext/repo_comps.c @@ -206,14 +206,6 @@ endElement(struct solv_xmlparser *xmlp, int state, char *content) } } -static void -errorCallback(struct solv_xmlparser *xmlp, const char *errstr, unsigned int line, unsigned int column) -{ - struct parsedata *pd = xmlp->userdata; - pool_debug(pd->pool, SOLV_ERROR, "repo_comps: %s at line %u:%u\n", errstr, line, column); -} - - int repo_add_comps(Repo *repo, FILE *fp, int flags) { @@ -226,8 +218,9 @@ repo_add_comps(Repo *repo, FILE *fp, int flags) pd.repo = repo; pd.pool = repo->pool; pd.data = data; - solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement, errorCallback); - solv_xmlparser_parse(&pd.xmlp, fp); + solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement); + if (solv_xmlparser_parse(&pd.xmlp, fp) != SOLV_XMLPARSER_OK) + pool_debug(pd.pool, SOLV_ERROR, "repo_comps: %s at line %u:%u\n", pd.xmlp.errstr, pd.xmlp.line, pd.xmlp.column); solv_xmlparser_free(&pd.xmlp); join_freemem(&pd.jd); diff --git a/ext/repo_content.c b/ext/repo_content.c index 68af2d5..f361900 100644 --- a/ext/repo_content.c +++ b/ext/repo_content.c @@ -517,8 +517,7 @@ repo_add_content(Repo *repo, FILE *fp, int flags) if (s && !s->name) { pool_debug(pool, SOLV_ERROR, "repo_content: 'content' incomplete, no product solvable created!\n"); - repo_free_solvable(repo, s - pool->solvables, 1); - s = 0; + s = solvable_free(s, 1); } if (s) { diff --git a/ext/repo_cudf.c b/ext/repo_cudf.c index 14ddcc9..64bb86f 100644 --- a/ext/repo_cudf.c +++ b/ext/repo_cudf.c @@ -224,10 +224,7 @@ repo_add_cudf(Repo *repo, Repo *installedrepo, FILE *fp, Queue *job, int flags) if (!*buf) { if (s && !repo && !isinstalled) - { - repo_free_solvable(repo, s - pool->solvables, 1); - s = 0; - } + s = solvable_free(s, 1); if (s) finishpackage(pool, s, keep, job); s = 0; @@ -323,10 +320,7 @@ repo_add_cudf(Repo *repo, Repo *installedrepo, FILE *fp, Queue *job, int flags) { isinstalled = 1; if (!installedrepo) - { - repo_free_solvable(repo, s - pool->solvables, 1); - s = 0; - } + s = solvable_free(s, 1); else if (s->repo != installedrepo) { copysolvabledata(pool, s, installedrepo); @@ -371,10 +365,7 @@ repo_add_cudf(Repo *repo, Repo *installedrepo, FILE *fp, Queue *job, int flags) } } if (s && !repo && !isinstalled) - { - repo_free_solvable(repo, s - pool->solvables, 1); - s = 0; - } + s = solvable_free(s, 1); if (s) finishpackage(pool, s, keep, job); solv_free(buf); diff --git a/ext/repo_deb.c b/ext/repo_deb.c index 6af7f10..5dd79f4 100644 --- a/ext/repo_deb.c +++ b/ext/repo_deb.c @@ -499,7 +499,7 @@ repo_add_debpackages(Repo *repo, FILE *fp, int flags) s = pool_id2solvable(pool, repo_add_solvable(repo)); control2solvable(s, data, buf); if (!s->name) - repo_free_solvable(repo, s - pool->solvables, 1); + s = solvable_free(s, 1); if (l > ll) memmove(buf, p + 1, l - ll); l -= ll; @@ -511,7 +511,7 @@ repo_add_debpackages(Repo *repo, FILE *fp, int flags) s = pool_id2solvable(pool, repo_add_solvable(repo)); control2solvable(s, data, buf); if (!s->name) - repo_free_solvable(repo, s - pool->solvables, 1); + s = solvable_free(s, 1); } solv_free(buf); if (!(flags & REPO_NO_INTERNALIZE)) diff --git a/ext/repo_deltainfoxml.c b/ext/repo_deltainfoxml.c index 4eb340f..ad315da 100644 --- a/ext/repo_deltainfoxml.c +++ b/ext/repo_deltainfoxml.c @@ -306,13 +306,6 @@ endElement(struct solv_xmlparser *xmlp, int state, char *content) } } -void -errorCallback(struct solv_xmlparser *xmlp, const char *errstr, unsigned int line, unsigned int column) -{ - struct parsedata *pd = xmlp->userdata; - pd->ret = pool_error(pd->pool, -1, "repo_deltainfoxml: %s at line %u:%u", errstr, line, column); -} - int repo_add_deltainfoxml(Repo *repo, FILE *fp, int flags) { @@ -327,8 +320,9 @@ repo_add_deltainfoxml(Repo *repo, FILE *fp, int flags) pd.pool = pool; pd.repo = repo; pd.data = data; - solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement, errorCallback); - solv_xmlparser_parse(&pd.xmlp, fp); + solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement); + if (solv_xmlparser_parse(&pd.xmlp, fp) != SOLV_XMLPARSER_OK) + pd.ret = pool_error(pd.pool, -1, "repo_deltainfoxml: %s at line %u:%u", pd.xmlp.errstr, pd.xmlp.line, pd.xmlp.column); solv_xmlparser_free(&pd.xmlp); /* now commit all handles */ diff --git a/ext/repo_helix.c b/ext/repo_helix.c index 3c2c6d1..37359bb 100644 --- a/ext/repo_helix.c +++ b/ext/repo_helix.c @@ -674,14 +674,6 @@ endElement(struct solv_xmlparser *xmlp, int state, char *content) } } -static void -errorCallback(struct solv_xmlparser *xmlp, const char *errstr, unsigned int line, unsigned int column) -{ - struct parsedata *pd = xmlp->userdata; - pd->ret = pool_error(pd->pool, -1, "%s at line %u", errstr, line); -} - - /*-------------------------------------------------------------------*/ /* @@ -706,14 +698,14 @@ repo_add_helix(Repo *repo, FILE *fp, int flags) pd.pool = pool; pd.repo = repo; pd.data = data; - solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement, errorCallback); pd.evrspace = (char *)solv_malloc(256); pd.aevrspace = 256; pd.levrspace = 1; - solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement, errorCallback); - solv_xmlparser_parse(&pd.xmlp, fp); + solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement); + if (solv_xmlparser_parse(&pd.xmlp, fp) != SOLV_XMLPARSER_OK) + pd.ret = pool_error(pd.pool, -1, "repo_helix: %s at line %u", pd.xmlp.errstr, pd.xmlp.line); solv_xmlparser_free(&pd.xmlp); solv_free(pd.evrspace); diff --git a/ext/repo_mdk.c b/ext/repo_mdk.c index 418bc61..4d3e102 100644 --- a/ext/repo_mdk.c +++ b/ext/repo_mdk.c @@ -230,7 +230,7 @@ repo_add_mdk(Repo *repo, FILE *fp, int flags) if (s) { pool_debug(pool, SOLV_ERROR, "unclosed package at EOF\n"); - repo_free_solvable(s->repo, s - pool->solvables, 1); + s = solvable_free(s, 1); } solv_free(buf); if (!(flags & REPO_NO_INTERNALIZE)) @@ -437,14 +437,6 @@ endElement(struct solv_xmlparser *xmlp, int state, char *content) } } -static void -errorCallback(struct solv_xmlparser *xmlp, const char *errstr, unsigned int line, unsigned int column) -{ - struct parsedata *pd = xmlp->userdata; - pool_debug(pd->pool, SOLV_ERROR, "%s at line %u:%u\n", errstr, line, column); -} - - int repo_add_mdk_info(Repo *repo, FILE *fp, int flags) { @@ -463,9 +455,10 @@ repo_add_mdk_info(Repo *repo, FILE *fp, int flags) pd.repo = repo; pd.pool = repo->pool; pd.data = data; - solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement, errorCallback); + solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement); pd.joinhash = joinhash_init(repo, &pd.joinhashmask); - solv_xmlparser_parse(&pd.xmlp, fp); + if (solv_xmlparser_parse(&pd.xmlp, fp) != SOLV_XMLPARSER_OK) + pool_debug(pd.pool, SOLV_ERROR, "%s at line %u:%u\n", pd.xmlp.errstr, pd.xmlp.line, pd.xmlp.column); solv_xmlparser_free(&pd.xmlp); solv_free(pd.joinhash); if (!(flags & REPO_NO_INTERNALIZE)) diff --git a/ext/repo_products.c b/ext/repo_products.c index 154a909..edf15bf 100644 --- a/ext/repo_products.c +++ b/ext/repo_products.c @@ -291,19 +291,6 @@ endElement(struct solv_xmlparser *xmlp, int state, char *content) } } -static void -errorCallback(struct solv_xmlparser *xmlp, const char *errstr, unsigned int line, unsigned int column) -{ - struct parsedata *pd = xmlp->userdata; - pool_debug(pd->pool, SOLV_ERROR, "%s: %s at line %u:%u\n", pd->filename, errstr, line, column); - if (pd->solvable) - { - repo_free_solvable(pd->repo, pd->solvable - pd->pool->solvables, 1); - pd->solvable = 0; - } -} - - int repo_add_code11_products(Repo *repo, const char *dirpath, int flags) { @@ -318,7 +305,7 @@ repo_add_code11_products(Repo *repo, const char *dirpath, int flags) pd.pool = repo->pool; pd.data = data; - solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement, errorCallback); + solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement); if (flags & REPO_USE_ROOTDIR) dirpath = pool_prepend_rootdir(repo->pool, dirpath); @@ -358,7 +345,11 @@ repo_add_code11_products(Repo *repo, const char *dirpath, int flags) pd.ctime = (unsigned int)st.st_ctime; pd.filename = fullpath; pd.basename = entry->d_name; - solv_xmlparser_parse(&pd.xmlp, fp); + if (solv_xmlparser_parse(&pd.xmlp, fp) != SOLV_XMLPARSER_OK) + { + pool_debug(pd.pool, SOLV_ERROR, "%s: %s at line %u:%u\n", pd.filename, pd.xmlp.errstr, pd.xmlp.line, pd.xmlp.column); + pd.solvable = solvable_free(pd.solvable, 1); + } fclose(fp); } closedir(dir); diff --git a/ext/repo_repomdxml.c b/ext/repo_repomdxml.c index 760d481..fd46272 100644 --- a/ext/repo_repomdxml.c +++ b/ext/repo_repomdxml.c @@ -329,13 +329,6 @@ endElement(struct solv_xmlparser *xmlp, int state, char *content) } } -static void -errorCallback(struct solv_xmlparser *xmlp, const char *errstr, unsigned int line, unsigned int column) -{ - struct parsedata *pd = xmlp->userdata; - pd->ret = pool_error(pd->pool, -1, "repo_repomdxml: %s at line %u:%u", errstr, line, column); -} - int repo_add_repomdxml(Repo *repo, FILE *fp, int flags) { @@ -350,9 +343,9 @@ repo_add_repomdxml(Repo *repo, FILE *fp, int flags) pd.pool = pool; pd.repo = repo; pd.data = data; - solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement, errorCallback); - - solv_xmlparser_parse(&pd.xmlp, fp); + solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement); + if (solv_xmlparser_parse(&pd.xmlp, fp) != SOLV_XMLPARSER_OK) + pd.ret = pool_error(pd.pool, -1, "repo_repomdxml: %s at line %u:%u", pd.xmlp.errstr, pd.xmlp.line, pd.xmlp.column); solv_xmlparser_free(&pd.xmlp); if (!(flags & REPO_NO_INTERNALIZE)) diff --git a/ext/repo_rpmdb.c b/ext/repo_rpmdb.c index a2d518f..9acb400 100644 --- a/ext/repo_rpmdb.c +++ b/ext/repo_rpmdb.c @@ -1661,9 +1661,8 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags) if (s) { /* oops, could not reuse. free it instead */ - repo_free_solvable(repo, s - pool->solvables, 1); + s = solvable_free(s, 1); solvend--; - s = 0; } /* now sort all solvables in the new solvstart..solvend block */ if (solvend - solvstart > 1) @@ -2044,7 +2043,7 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags) s = pool_id2solvable(pool, repo_add_solvable(repo)); if (!rpmhead2solv(pool, repo, data, s, state.rpmhead, flags & ~(RPM_ADD_WITH_HDRID | RPM_ADD_WITH_PKGID))) { - repo_free_solvable(repo, s - pool->solvables, 1); + s = solvable_free(s, 1); solv_chksum_free(chksumh, 0); headfree(state.rpmhead); return 0; @@ -2096,7 +2095,7 @@ repo_add_rpm_handle(Repo *repo, void *rpmhandle, int flags) s = pool_id2solvable(pool, repo_add_solvable(repo)); if (!rpmhead2solv(pool, repo, data, s, rpmhead, flags)) { - repo_free_solvable(repo, s - pool->solvables, 1); + s = solvable_free(s, 1); return 0; } if (!(flags & REPO_NO_INTERNALIZE)) diff --git a/ext/repo_rpmmd.c b/ext/repo_rpmmd.c index 9f49bd3..9bb50a0 100644 --- a/ext/repo_rpmmd.c +++ b/ext/repo_rpmmd.c @@ -1091,13 +1091,6 @@ endElement(struct solv_xmlparser *xmlp, int state, char *content) } } -static void -errorCallback(struct solv_xmlparser *xmlp, const char *errstr, unsigned int line, unsigned int column) -{ - struct parsedata *pd = xmlp->userdata; - pd->ret = pool_error(pd->pool, -1, "repo_rpmmd: %s at line %u:%u", errstr, line, column); -} - /*-----------------------------------------------*/ @@ -1135,8 +1128,9 @@ repo_add_rpmmd(Repo *repo, FILE *fp, const char *language, int flags) fill_cshash_from_repo(&pd); } - solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement, errorCallback); - solv_xmlparser_parse(&pd.xmlp, fp); + solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement); + if (solv_xmlparser_parse(&pd.xmlp, fp) != SOLV_XMLPARSER_OK) + pd.ret = pool_error(pool, -1, "repo_rpmmd: %s at line %u:%u", pd.xmlp.errstr, pd.xmlp.line, pd.xmlp.column); solv_xmlparser_free(&pd.xmlp); solv_free(pd.lastdirstr); diff --git a/ext/repo_updateinfoxml.c b/ext/repo_updateinfoxml.c index 7ba0062..ff84d32 100644 --- a/ext/repo_updateinfoxml.c +++ b/ext/repo_updateinfoxml.c @@ -427,13 +427,6 @@ endElement(struct solv_xmlparser *xmlp, int state, char *content) } } -static void -errorCallback(struct solv_xmlparser *xmlp, const char *errstr, unsigned int line, unsigned int column) -{ - struct parsedata *pd = xmlp->userdata; - pd->ret = pool_error(pd->pool, -1, "repo_updateinfoxml: %s at line %u:%u", errstr, line, column); -} - int repo_add_updateinfoxml(Repo *repo, FILE *fp, int flags) { @@ -447,8 +440,9 @@ repo_add_updateinfoxml(Repo *repo, FILE *fp, int flags) pd.pool = pool; pd.repo = repo; pd.data = data; - solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement, errorCallback); - solv_xmlparser_parse(&pd.xmlp, fp); + solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement); + if (solv_xmlparser_parse(&pd.xmlp, fp) != SOLV_XMLPARSER_OK) + pd.ret = pool_error(pool, -1, "repo_updateinfoxml: %s at line %u:%u", pd.xmlp.errstr, pd.xmlp.line, pd.xmlp.column); solv_xmlparser_free(&pd.xmlp); join_freemem(&pd.jd); diff --git a/ext/repo_zyppdb.c b/ext/repo_zyppdb.c index d73a900..f6e2bfa 100644 --- a/ext/repo_zyppdb.c +++ b/ext/repo_zyppdb.c @@ -138,18 +138,6 @@ endElement(struct solv_xmlparser *xmlp, int state, char *content) } } -static void -errorCallback(struct solv_xmlparser *xmlp, const char *errstr, unsigned int line, unsigned int column) -{ - struct parsedata *pd = xmlp->userdata; - pool_debug(pd->pool, SOLV_ERROR, "repo_zyppdb: %s: %s at line %u:%u\n", pd->filename, errstr, line, column); - if (pd->solvable) - { - repo_free_solvable(pd->repo, pd->solvable - pd->pool->solvables, 1); - pd->solvable = 0; - } -} - /* * read all installed products @@ -172,7 +160,7 @@ repo_add_zyppdb_products(Repo *repo, const char *dirpath, int flags) pd.repo = repo; pd.pool = repo->pool; pd.data = data; - solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement, errorCallback); + solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement); if (flags & REPO_USE_ROOTDIR) dirpath = pool_prepend_rootdir(repo->pool, dirpath); @@ -190,7 +178,11 @@ repo_add_zyppdb_products(Repo *repo, const char *dirpath, int flags) continue; } pd.filename = entry->d_name; - solv_xmlparser_parse(&pd.xmlp, fp); + if (solv_xmlparser_parse(&pd.xmlp, fp) != SOLV_XMLPARSER_OK) + { + pool_debug(pd.pool, SOLV_ERROR, "repo_zyppdb: %s: %s at line %u:%u\n", pd.filename, pd.xmlp.errstr, pd.xmlp.line, pd.xmlp.column); + pd.solvable = solvable_free(pd.solvable, 1); + } fclose(fp); } } diff --git a/ext/solv_jsonparser.c b/ext/solv_jsonparser.c new file mode 100644 index 0000000..053ee6f --- /dev/null +++ b/ext/solv_jsonparser.c @@ -0,0 +1,294 @@ +/* + * solv_jsonparser.c + * + * Simple JSON stream parser + * + * Copyright (c) 2018, SUSE LLC + * + * This program is licensed under the BSD license, read LICENSE.BSD + * for further information + */ + +#include <stdio.h> +#include <stdlib.h> + +#include "util.h" +#include "solv_jsonparser.h" + +struct solv_jsonparser * +jsonparser_init(struct solv_jsonparser *jp, FILE *fp) +{ + memset(jp, 0, sizeof(*jp)); + jp->fp = fp; + jp->state = JP_START; + jp->line = jp->nextline = 1; + jp->nextc = ' '; + queue_init(&jp->stateq); + return jp; +} + +struct solv_jsonparser * +jsonparser_free(struct solv_jsonparser *jp) +{ + queue_free(&jp->stateq); + return 0; +} + +static void +savec(struct solv_jsonparser *jp, char c) +{ + if (jp->nspace == jp->aspace) + { + jp->aspace += 256; + jp->space = solv_realloc(jp->space, jp->aspace); + } + jp->space[jp->nspace++] = c; +} + +static void +saveutf8(struct solv_jsonparser *jp, int c) +{ + int i; + if (c < 0x80) + { + savec(jp, c); + return; + } + i = c < 0x800 ? 1 : c < 0x10000 ? 2 : 3; + savec(jp, (0x1f80 >> i) | (c >> (6 * i))); + while (--i >= 0) + savec(jp, 0x80 | ((c >> (6 * i)) & 0x3f)); +} + +static inline int +nextc(struct solv_jsonparser *jp) +{ + int c = getc(jp->fp); + if (c == '\n') + jp->nextline++; + return c; +} + +static int +skipspace(struct solv_jsonparser *jp) +{ + int c = jp->nextc; + while (c == ' ' || c == '\t' || c == '\r' || c == '\n') + c = nextc(jp); + jp->line = jp->nextline; + return (jp->nextc = c); +} + +static int +parseliteral(struct solv_jsonparser *jp) +{ + size_t nspace = jp->nspace; + int c; + savec(jp, jp->nextc); + for (;;) + { + c = nextc(jp); + if (c < 'a' || c > 'z') + break; + savec(jp, c); + } + jp->nextc = c; + savec(jp, 0); + if (!strcmp(jp->space + nspace, "true")) + return JP_BOOL; + if (!strcmp(jp->space + nspace, "false")) + return JP_BOOL; + if (!strcmp(jp->space + nspace, "null")) + return JP_NULL; + return JP_ERROR; +} + +static int +parsenumber(struct solv_jsonparser *jp) +{ + int c; + savec(jp, jp->nextc); + for (;;) + { + c = nextc(jp); + if ((c < '0' || c > '9') && c != '+' && c != '-' && c != '.' && c != 'e' && c != 'E') + break; + savec(jp, c); + } + jp->nextc = c; + savec(jp, 0); + return JP_NUMBER; +} + +static int +parseutf8(struct solv_jsonparser *jp, int surrogate) +{ + int c, i, r = 0; + /* parse 4-digit hex */ + for (i = 0; i < 4; i++) + { + c = nextc(jp); + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'a' && c <= 'f') + c -= 'a' - 10; + else if (c >= 'A' && c <= 'F') + c -= 'A' - 10; + else + return -1; + r = (r << 4) | c; + } + if (!surrogate && r >= 0xd800 && r < 0xdc00) + { + /* utf16 surrogate pair encodes 0x10000 - 0x10ffff */ + int r2; + if (nextc(jp) != '\\' || nextc(jp) != 'u' || (r2 = parseutf8(jp, 1)) < 0xdc00 || r2 >= 0xe000) + return -1; + r = 0x10000 + ((r & 0x3ff) << 10 | (r2 & 0x3ff)); + } + return r; +} + +static int +parsestring(struct solv_jsonparser *jp) +{ + int c; + for (;;) + { + if ((c = nextc(jp)) < 32) + return JP_ERROR; + if (c == '"') + break; + if (c == '\\') + { + switch (c = nextc(jp)) + { + case '"': + case '\\': + case '/': + case '\n': + break; + case 'b': + c = '\b'; + break; + case 'f': + c = '\f'; + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'u': + if ((c = parseutf8(jp, 0)) < 0) + return JP_ERROR; + saveutf8(jp, c); + continue; + default: + return JP_ERROR; + } + } + savec(jp, c); + } + jp->nextc = ' '; + savec(jp, 0); + return JP_STRING; +} + +static int +parsevalue(struct solv_jsonparser *jp) +{ + int c = skipspace(jp); + if (c == '"') + return parsestring(jp); + if ((c >= '0' && c <= '9') || c == '+' || c == '-' || c == '.') + return parsenumber(jp); + if ((c >= 'a' && c <= 'z')) + return parseliteral(jp); + jp->nextc = ' '; + if (c == '[') + return JP_ARRAY; + if (c == '{') + return JP_OBJECT; + if (c == ']') + return JP_ARRAY_END; + if (c == '}') + return JP_OBJECT_END; + return JP_ERROR; +} + +int +jsonparser_parse(struct solv_jsonparser *jp) +{ + int type; + size_t nspace; + + jp->depth = jp->stateq.count; + jp->key = jp->value = 0; + jp->keylen = jp->valuelen = 0; + nspace = jp->nspace = 0; + + if (jp->state == JP_END) + return JP_END; + if (jp->state == JP_START) + jp->state = JP_END; + type = parsevalue(jp); + if (type <= 0) + return JP_ERROR; + if (type == JP_OBJECT_END || type == JP_ARRAY_END) + { + if (jp->state != type - 1) + return JP_ERROR; + jp->state = queue_pop(&jp->stateq); + } + else if (jp->state == JP_OBJECT) + { + nspace = jp->nspace; + if (type != JP_STRING) + return JP_ERROR; + if (skipspace(jp) != ':') + return JP_ERROR; + jp->nextc = ' '; + type = parsevalue(jp); + if (type == JP_OBJECT_END || type == JP_ARRAY_END) + return JP_ERROR; + jp->key = jp->space; + jp->keylen = nspace - 1; + } + if (type == JP_STRING || type == JP_NUMBER || type == JP_BOOL || type == JP_NULL) + { + jp->value = jp->space + nspace; + jp->valuelen = jp->nspace - nspace - 1; + } + if (type == JP_ARRAY || type == JP_OBJECT) + { + queue_push(&jp->stateq, jp->state); + jp->state = type; + } + else if (jp->state == JP_OBJECT || jp->state == JP_ARRAY) + { + int c = skipspace(jp); + if (c == ',') + jp->nextc = ' '; + else if (c != (jp->state == JP_OBJECT ? '}' : ']')) + return JP_ERROR; + } + return type; +} + +int +jsonparser_skip(struct solv_jsonparser *jp, int type) +{ + if (type == JP_ARRAY || type == JP_OBJECT) + { + int depth = jp->depth + 1, endtype = type + 1; + while (type > 0 && (type != endtype || jp->depth != depth)) + type = jsonparser_parse(jp); + } + return type; +} + diff --git a/ext/solv_jsonparser.h b/ext/solv_jsonparser.h new file mode 100644 index 0000000..d58d9e3 --- /dev/null +++ b/ext/solv_jsonparser.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018, SUSE LLC + * + * This program is licensed under the BSD license, read LICENSE.BSD + * for further information + */ + +#ifndef SOLV_JSONPARSER_H +#define SOLV_JSONPARSER_H + +#include "queue.h" + +struct solv_jsonparser { + FILE *fp; + int line; + int depth; + + char *key; + size_t keylen; + char *value; + size_t valuelen; + + int state; + Queue stateq; + int nextc; + int nextline; + char *space; + size_t nspace; + size_t aspace; +}; + +#define JP_ERROR -1 +#define JP_END 0 +#define JP_START 1 +#define JP_STRING 2 +#define JP_NUMBER 3 +#define JP_BOOL 4 +#define JP_NULL 5 +#define JP_OBJECT 6 +#define JP_OBJECT_END 7 +#define JP_ARRAY 8 +#define JP_ARRAY_END 9 + +struct solv_jsonparser *jsonparser_init(struct solv_jsonparser *jp, FILE *fp); +struct solv_jsonparser *jsonparser_free(struct solv_jsonparser *jp); +int jsonparser_parse(struct solv_jsonparser *jp); +int jsonparser_skip(struct solv_jsonparser *jp, int type); + +#endif /* SOLV_JSONPARSER_H */ diff --git a/ext/solv_xmlparser.c b/ext/solv_xmlparser.c index 170520f..6292663 100644 --- a/ext/solv_xmlparser.c +++ b/ext/solv_xmlparser.c @@ -132,8 +132,7 @@ solv_xmlparser_init(struct solv_xmlparser *xmlp, struct solv_xmlparser_element *elements, void *userdata, void (*startelement)(struct solv_xmlparser *, int state, const char *name, const char **atts), - void (*endelement)(struct solv_xmlparser *, int state, char *content), - void (*errorhandler)(struct solv_xmlparser *, const char *errstr, unsigned int line, unsigned int column)) + void (*endelement)(struct solv_xmlparser *, int state, char *content)) { int i, nstates, nelements; struct solv_xmlparser_element *el; @@ -169,7 +168,6 @@ solv_xmlparser_init(struct solv_xmlparser *xmlp, xmlp->userdata = userdata; xmlp->startelement = startelement; xmlp->endelement = endelement; - xmlp->errorhandler = errorhandler; } void @@ -178,6 +176,16 @@ solv_xmlparser_free(struct solv_xmlparser *xmlp) xmlp->elementhelper = solv_free(xmlp->elementhelper); queue_free(&xmlp->elementq); xmlp->content = solv_free(xmlp->content); + xmlp->errstr = solv_free(xmlp->errstr); +} + +static void +set_error(struct solv_xmlparser *xmlp, const char *errstr, unsigned int line, unsigned int column) +{ + solv_free(xmlp->errstr); + xmlp->errstr = solv_strdup(errstr); + xmlp->line = line; + xmlp->column = column; } #ifdef WITH_LIBXML2 @@ -197,7 +205,8 @@ free_parser(struct solv_xmlparser *xmlp) xmlp->parser = 0; } -static xmlParserCtxtPtr create_parser_ctx(struct solv_xmlparser *xmlp, char *buf, int l) +static xmlParserCtxtPtr +create_parser_ctx(struct solv_xmlparser *xmlp, char *buf, int l) { xmlSAXHandler sax; memset(&sax, 0, sizeof(sax)); @@ -216,7 +225,7 @@ parse_block(struct solv_xmlparser *xmlp, char *buf, int l) xmlp->parser = create_parser_ctx(xmlp, buf, l2); if (!xmlp->parser) { - xmlp->errorhandler(xmlp, "could not create parser", 0, 0); + set_error(xmlp, "could not create parser", 0, 0); return 0; } buf += l2; @@ -227,7 +236,7 @@ parse_block(struct solv_xmlparser *xmlp, char *buf, int l) if (xmlParseChunk(xmlp->parser, buf, l, l == 0 ? 1 : 0)) { xmlErrorPtr err = xmlCtxtGetLastError(xmlp->parser); - xmlp->errorhandler(xmlp, err->message, err->line, err->int2); + set_error(xmlp, err->message, err->line, err->int2); return 0; } return 1; @@ -265,9 +274,7 @@ parse_block(struct solv_xmlparser *xmlp, char *buf, int l) { if (XML_Parse(xmlp->parser, buf, l, l == 0) == XML_STATUS_ERROR) { - unsigned int line = XML_GetCurrentLineNumber(xmlp->parser); - unsigned int column = XML_GetCurrentColumnNumber(xmlp->parser); - xmlp->errorhandler(xmlp, XML_ErrorString(XML_GetErrorCode(xmlp->parser)), line, column); + set_error(xmlp, XML_ErrorString(XML_GetErrorCode(xmlp->parser)), XML_GetCurrentLineNumber(xmlp->parser), XML_GetCurrentColumnNumber(xmlp->parser)); return 0; } return 1; @@ -281,11 +288,11 @@ solv_xmlparser_lineno(struct solv_xmlparser *xmlp) #endif -void +int solv_xmlparser_parse(struct solv_xmlparser *xmlp, FILE *fp) { char buf[8192]; - int l; + int l, ret = SOLV_XMLPARSER_OK; xmlp->state = 0; xmlp->unknowncnt = 0; @@ -295,16 +302,22 @@ solv_xmlparser_parse(struct solv_xmlparser *xmlp, FILE *fp) if (!create_parser(xmlp)) { - xmlp->errorhandler(xmlp, "could not create xml parser", 0, 0); - return; + set_error(xmlp, "could not create parser", 0, 0); + return SOLV_XMLPARSER_ERROR; } for (;;) { l = fread(buf, 1, sizeof(buf), fp); - if (!parse_block(xmlp, buf, l) || !l) + if (!parse_block(xmlp, buf, l)) + { + ret = SOLV_XMLPARSER_ERROR; + break; + } + if (!l) break; } free_parser(xmlp); + return ret; } char * diff --git a/ext/solv_xmlparser.h b/ext/solv_xmlparser.h index 9fb342f..ced0571 100644 --- a/ext/solv_xmlparser.h +++ b/ext/solv_xmlparser.h @@ -8,6 +8,9 @@ struct solv_xmlparser_element { struct solv_xmlparser { void *userdata; + char *errstr; + unsigned int line; + unsigned int column; int state; int docontent; @@ -24,12 +27,14 @@ struct solv_xmlparser { void (*startelement)(struct solv_xmlparser *xmlp, int state, const char *name, const char **atts); void (*endelement)(struct solv_xmlparser *xmlp, int state, char *content); - void (*errorhandler)(struct solv_xmlparser *xmlp, const char *errstr, unsigned int line, unsigned int column); Id *elementhelper; void *parser; }; +#define SOLV_XMLPARSER_OK 0 +#define SOLV_XMLPARSER_ERROR -1 + static inline const char * solv_xmlparser_find_attr(const char *txt, const char **atts) { @@ -41,11 +46,10 @@ solv_xmlparser_find_attr(const char *txt, const char **atts) extern void solv_xmlparser_init(struct solv_xmlparser *xmlp, struct solv_xmlparser_element *elements, void *userdata, void (*startelement)(struct solv_xmlparser *xmlp, int state, const char *name, const char **atts), - void (*endelement)(struct solv_xmlparser *xmlp, int state, char *content), - void (*errorhandler)(struct solv_xmlparser *xmlp, const char *errstr, unsigned int line, unsigned int column)); + void (*endelement)(struct solv_xmlparser *xmlp, int state, char *content)); extern void solv_xmlparser_free(struct solv_xmlparser *xmlp); -extern void solv_xmlparser_parse(struct solv_xmlparser *xmlp, FILE *fp); +extern int solv_xmlparser_parse(struct solv_xmlparser *xmlp, FILE *fp); unsigned int solv_xmlparser_lineno(struct solv_xmlparser *xmlp); char *solv_xmlparser_contentspace(struct solv_xmlparser *xmlp, int l); diff --git a/ext/testcase.c b/ext/testcase.c index ffc8b8a..b815c56 100644 --- a/ext/testcase.c +++ b/ext/testcase.c @@ -15,6 +15,7 @@ #include "pool.h" #include "poolarch.h" #include "poolvendor.h" +#include "evr.h" #include "repo.h" #include "repo_solv.h" #include "solver.h" @@ -121,6 +122,7 @@ static struct solverflags2str { { SOLVER_FLAG_FOCUS_BEST, "focusbest", 0 }, { SOLVER_FLAG_STRONG_RECOMMENDS, "strongrecommends", 0 }, { SOLVER_FLAG_INSTALL_ALSO_UPDATES, "installalsoupdates", 0 }, + { SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED, "onlynamespacerecommended", 0 }, { 0, 0, 0 } }; @@ -1071,7 +1073,7 @@ testcase_str2job(Pool *pool, const char *str, Id *whatp) Queue q; job |= SOLVER_SOLVABLE_ONE_OF; queue_init(&q); - if (npieces > 3 && strcmp(pieces[2], "nothing") != 0) + if (npieces > 2 && strcmp(pieces[2], "nothing") != 0) { for (i = 2; i < npieces; i++) { @@ -2966,6 +2968,14 @@ testcase_read(Pool *pool, FILE *fp, const char *testcase, Queue *job, char **res } queue_push(&autoinstq, pool_str2id(pool, pieces[2], 1)); } + else if (!strcmp(pieces[0], "evrcmp") && npieces == 3) + { + Id evr1 = pool_str2id(pool, pieces[1], 1); + Id evr2 = pool_str2id(pool, pieces[2], 1); + int r = pool_evrcmp(pool, evr1, evr2, EVRCMP_COMPARE); + r = r < 0 ? REL_LT : r > 0 ? REL_GT : REL_EQ; + queue_push2(job, SOLVER_NOOP | SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, evr1, evr2, r, 1)); + } else { pool_error(pool, 0, "testcase_read: cannot parse command '%s'", pieces[0]); |