#include <fcntl.h>
#include "solv_xfopen.h"
+#include "util.h"
static FILE *cookieopen(void *cookie, const char *mode,
return fdopen(fd, mode);
}
+struct bufcookie {
+ char **bufp;
+ size_t *buflp;
+ char *freemem;
+ size_t bufl_int;
+};
+
+static ssize_t cookie_bufread(void *cookie, char *buf, size_t nbytes)
+{
+ struct bufcookie *bc = cookie;
+ size_t n = *bc->buflp > nbytes ? nbytes : *bc->buflp;
+ if (n)
+ {
+ memcpy(buf, *bc->bufp, n);
+ *bc->bufp += n;
+ *bc->buflp -= n;
+ }
+ return n;
+}
+
+static ssize_t cookie_bufwrite(void *cookie, const char *buf, size_t nbytes)
+{
+ struct bufcookie *bc = cookie;
+ int n = nbytes > 0x40000000 ? 0x40000000 : nbytes;
+ if (n)
+ {
+ *bc->bufp = solv_extend(*bc->bufp, *bc->buflp, n + 1, 1, 4095);
+ memcpy(*bc->bufp, buf, n);
+ (*bc->bufp)[n] = 0; /* zero-terminate */
+ *bc->buflp += n;
+ }
+ return n;
+}
+
+static int cookie_bufclose(void *cookie)
+{
+ struct bufcookie *bc = cookie;
+ if (bc->freemem)
+ solv_free(bc->freemem);
+ solv_free(bc);
+ return 0;
+}
+
+FILE *
+solv_xfopen_buf(const char *fn, char **bufp, size_t *buflp, const char *mode)
+{
+ struct bufcookie *bc;
+ FILE *fp;
+ if (*mode != 'r' && *mode != 'w')
+ return 0;
+ bc = solv_calloc(1, sizeof(*bc));
+ bc->freemem = 0;
+ bc->bufp = bufp;
+ if (!buflp)
+ {
+ bc->bufl_int = *mode == 'w' ? 0 : strlen(*bufp);
+ buflp = &bc->bufl_int;
+ }
+ bc->buflp = buflp;
+ if (*mode == 'w')
+ {
+ *bc->bufp = solv_extend(0, 0, 1, 1, 4095); /* always zero-terminate */
+ (*bc->bufp)[0] = 0;
+ *bc->buflp = 0;
+ }
+ fp = cookieopen(bc, mode, cookie_bufread, cookie_bufwrite, cookie_bufclose);
+ if (!strcmp(mode, "rf")) /* auto-free */
+ bc->freemem = *bufp;
+ if (!fp)
+ {
+ *bc->bufp = solv_free(*bc->bufp);
+ *bc->buflp = 0;
+ cookie_bufclose(bc);
+ }
+ return fp;
+}
if (npieces < 3)
{
pool_debug(pool, SOLV_ERROR, "str2job: bad line '%s'\n", str);
+ solv_free(pieces);
return 0;
}
if (!job2str[i].str)
{
pool_debug(pool, SOLV_ERROR, "str2job: unknown job '%s'\n", str);
+ solv_free(pieces);
return 0;
}
job = job2str[i].job;
if (!jobflags2str[i].str)
{
pool_debug(pool, SOLV_ERROR, "str2job: unknown jobflags in '%s'\n", str);
+ solv_free(pieces);
return 0;
}
job |= jobflags2str[i].flag;
if (npieces != 3)
{
pool_debug(pool, SOLV_ERROR, "str2job: bad pkg selector in '%s'\n", str);
+ solv_free(pieces);
return 0;
}
job |= SOLVER_SOLVABLE;
if (!what)
{
pool_debug(pool, SOLV_ERROR, "str2job: unknown package '%s'\n", pieces[2]);
+ solv_free(pieces);
return 0;
}
}
{
pool_debug(pool, SOLV_ERROR, "str2job: unknown package '%s'\n", pieces[i]);
queue_free(&q);
+ solv_free(pieces);
return 0;
}
queue_push(&q, p);
if (npieces != 3)
{
pool_debug(pool, SOLV_ERROR, "str2job: bad line '%s'\n", str);
+ solv_free(pieces);
return 0;
}
repo = testcase_str2repo(pool, pieces[2]);
if (!repo)
{
pool_debug(pool, SOLV_ERROR, "str2job: unknown repo '%s'\n", pieces[2]);
+ solv_free(pieces);
return 0;
}
job |= SOLVER_SOLVABLE_REPO;
if (npieces != 3 && strcmp(pieces[2], "packages") != 0)
{
pool_debug(pool, SOLV_ERROR, "str2job: bad line '%s'\n", str);
+ solv_free(pieces);
return 0;
}
job |= SOLVER_SOLVABLE_ALL;
else
{
pool_debug(pool, SOLV_ERROR, "str2job: unknown selection in '%s'\n", str);
+ solv_free(pieces);
return 0;
}
*whatp = what;
+ solv_free(pieces);
return job;
}
return 1;
}
+static char *
+read_inline_file(FILE *fp, char **bufp, char **bufpp, int *buflp)
+{
+ char *result = solv_malloc(1024);
+ char *rp = result;
+ int resultl = 1024;
+
+ for (;;)
+ {
+ size_t rl;
+ if (rp - result + 256 >= resultl)
+ {
+ resultl = rp - result;
+ result = solv_realloc(result, resultl + 1024);
+ rp = result + resultl;
+ resultl += 1024;
+ }
+ if (!fgets(rp, resultl - (rp - result), fp))
+ *rp = 0;
+ rl = strlen(rp);
+ if (rl && (rp == result || rp[-1] == '\n'))
+ {
+ if (rl > 1 && rp[0] == '#' && rp[1] == '>')
+ {
+ memmove(rp, rp + 2, rl - 2);
+ rl -= 2;
+ }
+ else
+ {
+ while (rl + 16 > *buflp)
+ {
+ *bufp = solv_realloc(*bufp, *buflp + 512);
+ *buflp += 512;
+ }
+ memmove(*bufp, rp, rl);
+ if ((*bufp)[rl - 1] == '\n')
+ {
+ ungetc('\n', fp);
+ rl--;
+ }
+ (*bufp)[rl] = 0;
+ (*bufpp) = *bufp + rl;
+ rl = 0;
+ }
+ }
+ if (rl <= 0)
+ {
+ *rp = 0;
+ break;
+ }
+ rp += rl;
+ }
+ return result;
+}
+
+static char *
+read_file(FILE *fp)
+{
+ char *result = solv_malloc(1024);
+ char *rp = result;
+ int resultl = 1024;
+
+ for (;;)
+ {
+ size_t rl;
+ if (rp - result + 256 >= resultl)
+ {
+ resultl = rp - result;
+ result = solv_realloc(result, resultl + 1024);
+ rp = result + resultl;
+ resultl += 1024;
+ }
+ rl = fread(rp, 1, resultl - (rp - result), fp);
+ if (rl <= 0)
+ {
+ *rp = 0;
+ break;
+ }
+ rp += rl;
+ }
+ return result;
+}
+
Solver *
testcase_read(Pool *pool, FILE *fp, char *testcase, Queue *job, char **resultp, int *resultflagsp)
{
repo->subpriority = subprio;
if (strcmp(pieces[3], "empty") != 0)
{
- rdata = pool_tmpjoin(pool, testcasedir, pieces[4], 0);
- if ((rfp = solv_xfopen(rdata, "r")) == 0)
+ const char *repotype = pool_tmpjoin(pool, pieces[3], 0, 0); /* gets overwritten in <inline> case */
+ if (!strcmp(pieces[4], "<inline>"))
+ {
+ char *idata = read_inline_file(fp, &buf, &bufp, &bufl);
+ rdata = "<inline>";
+ rfp = solv_xfopen_buf(rdata, &idata, 0, "rf");
+ }
+ else
+ {
+ rdata = pool_tmpjoin(pool, testcasedir, pieces[4], 0);
+ rfp = solv_xfopen(rdata, "r");
+ }
+ if (!rfp)
{
pool_debug(pool, SOLV_ERROR, "testcase_read: could not open '%s'\n", rdata);
}
- else if (!strcmp(pieces[3], "susetags"))
+ else if (!strcmp(repotype, "susetags"))
{
testcase_add_susetags(repo, rfp, 0);
fclose(rfp);
}
- else if (!strcmp(pieces[3], "solv"))
+ else if (!strcmp(repotype, "solv"))
{
repo_add_solv(repo, rfp, 0);
fclose(rfp);
}
else if (!strcmp(pieces[0], "result") && npieces > 2)
{
- FILE *rfp;
const char *rdata;
+ char *result = 0;
int resultflags = 0;
char *s = pieces[1];
int i;
rdata = pool_tmpjoin(pool, testcasedir, pieces[2], 0);
if (!strcmp(pieces[2], "<inline>"))
- rfp = fp;
- else
- rfp = fopen(rdata, "r");
- if (!rfp)
- {
- pool_debug(pool, SOLV_ERROR, "testcase_read: could not open '%s'\n", rdata);
- }
+ result = read_inline_file(fp, &buf, &bufp, &bufl);
else
{
- /* slurp it in... */
- char *result = solv_malloc(1024);
- char *rp = result;
- int resultl = 1024;
- for (;;)
+ FILE *rfp = fopen(rdata, "r");
+ if (!rfp)
+ pool_debug(pool, SOLV_ERROR, "testcase_read: could not open '%s'\n", rdata);
+ else
{
- size_t rl;
- if (rp - result + 256 >= resultl)
- {
- resultl = rp - result;
- result = solv_realloc(result, resultl + 1024);
- rp = result + resultl;
- resultl += 1024;
- }
- if (fp == rfp)
- {
- if (!fgets(rp, resultl - (rp - result), fp))
- rl = 0;
- else
- {
- rl = strlen(rp);
- if (rl && (rp == result || rp[-1] == '\n'))
- {
- if (rl > 1 && rp[0] == '#' && rp[1] == '>')
- {
- memmove(rp, rp + 2, rl - 2);
- rl -= 2;
- }
- else
- {
- while (rl + 16 > bufl)
- {
- buf = solv_realloc(buf, bufl + 512);
- bufl += 512;
- }
- memmove(buf, rp, rl);
- if (buf[rl - 1] == '\n')
- {
- ungetc('\n', fp);
- rl--;
- }
- bufp = buf + rl;
- rl = 0;
- }
- }
- }
- }
- else
- rl = fread(rp, 1, resultl - (rp - result), rfp);
- if (rl <= 0)
- {
- *rp = 0;
- break;
- }
- rp += rl;
+ result = read_file(rfp);
+ fclose(rfp);
}
- if (rfp != fp)
- fclose(rfp);
- if (resultp)
- *resultp = result;
- else
- solv_free(result);
- if (resultflagsp)
- *resultflagsp = resultflags;
}
+ if (resultp)
+ *resultp = result;
+ else
+ solv_free(result);
+ if (resultflagsp)
+ *resultflagsp = resultflags;
}
else if (!strcmp(pieces[0], "nextjob") && npieces == 1)
{