* See http://en.opensuse.org/Product_Management/Code11
*
*
- * Copyright (c) 2007, Novell Inc.
+ * Copyright (c) 2008, Novell Inc.
*
* This program is licensed under the BSD license, read LICENSE.BSD
* for further information
#include "repo_content.h"
-static ino_t baseproduct = 0;
-static ino_t currentproduct = 0;
-
-static int productscheme = -1;
-
//#define DUMPOUT 0
enum state {
STATE_UPDATEREPOKEY, // 9
STATE_URLS, // 10
STATE_URL, // 11
-#if 0 /* not needed */
- STATE_BUILDCONFIG, // 12
- STATE_INSTALLCONFIG, // 13
-#endif
- STATE_RUNTIMECONFIG, // 14
- STATE_LINGUAS, // 15
- STATE_LANG, // 16
- STATE_REGISTER, // 17
- STATE_TARGET, // 18
- STATE_FLAVOR, // 19
- STATE_REGRELEASE, // 20
+ STATE_RUNTIMECONFIG, // 12
+ STATE_LINGUAS, // 13
+ STATE_LANG, // 14
+ STATE_REGISTER, // 15
+ STATE_TARGET, // 16
+ STATE_FLAVOR, // 17
+ STATE_REGRELEASE, // 18
NUMSTATES // 0
};
{ STATE_PRODUCT, "register", STATE_REGISTER, 0 },
{ STATE_PRODUCT, "urls", STATE_URLS, 0 },
{ STATE_PRODUCT, "runtimeconfig", STATE_RUNTIMECONFIG, 0 },
-#if 0 /* not needed */
- { STATE_PRODUCT, "installconfig", STATE_INSTALLCONFIG, 0 },
- { STATE_PRODUCT, "buildconfig", STATE_BUILDCONFIG, 0 },
-#endif
{ STATE_PRODUCT, "linguas", STATE_LINGUAS, 0 },
{ STATE_PRODUCT, "updaterepokey", STATE_UPDATEREPOKEY, 1 },
{ STATE_URLS, "url", STATE_URL, 1 },
-/* { STATE_BUILDCONFIG,"linguas", STATE_LINGUAS, 0 }, */
{ STATE_LINGUAS, "lang", STATE_LANG, 0 },
{ STATE_REGISTER, "flavor", STATE_FLAVOR, 1 },
{ STATE_REGISTER, "target", STATE_TARGET, 1 },
const char *attribute; /* only print this attribute, if currentproduct == baseproduct */
const char *tmplang;
+
const char *tmpvers;
const char *tmprel;
const char *tmpurltype;
- Solvable *s;
+ unsigned int ctime;
+
+ Solvable *solvable;
Id handle;
+ ino_t baseproduct;
+ ino_t currentproduct;
+ int productscheme;
+
Id langcache[ID_NUM_INTERNAL];
};
{
struct parsedata *pd = userData;
Pool *pool = pd->pool;
+ Solvable *s = pd->solvable;
struct stateswitch *sw;
#if 0
}
pd->depth++;
- if ( !(sw = pd->swtab[pd->state]) ) /* no statetable -> no substates */
+ if (!(sw = pd->swtab[pd->state])) /* no statetable -> no substates */
{
#if 0
fprintf(stderr, "into unknown: [?]%s (from: ?, state %d)\n", name, pd->state);
/* parse 'schemeversion' and store in global variable */
{
const char * scheme = find_attr("schemeversion", atts, 0);
- productscheme = (scheme && *scheme) ? atoi(scheme) : -1;
+ pd->productscheme = (scheme && *scheme) ? atoi(scheme) : -1;
}
- if (!pd->s)
+ if (!s)
{
- pd->s = pool_id2solvable(pool, repo_add_solvable(pd->repo));
- repodata_extend(pd->data, pd->s - pool->solvables);
- pd->handle = repodata_get_handle(pd->data, pd->s - pool->solvables - pd->repo->start);
+ s = pd->solvable = pool_id2solvable(pool, repo_add_solvable(pd->repo));
+ repodata_extend(pd->data, s - pool->solvables);
+ pd->handle = repodata_get_handle(pd->data, (s - pool->solvables) - pd->repo->start);
}
- break;
+ break;
/* <summary lang="xy">... */
case STATE_SUMMARY:
default:
break;
}
- return;
}
endElement(void *userData, const char *name)
{
struct parsedata *pd = userData;
+ Solvable *s = pd->solvable;
#if 0
fprintf(stderr, "end: [%d]%s\n", pd->state, name);
switch (pd->state)
{
+ case STATE_PRODUCT:
+ /* product done, finish solvable */
+ if (pd->ctime)
+ repodata_set_num(pd->data, pd->handle, SOLVABLE_INSTALLTIME, pd->ctime);
+
+ /* this is where <productsdir>/baseproduct points to */
+ if (pd->currentproduct == pd->baseproduct)
+ repodata_set_str(pd->data, pd->handle, PRODUCT_TYPE, "base");
+
+ if (pd->tmprel)
+ {
+ if (pd->tmpvers)
+ s->evr = makeevr(pd->pool, join2(pd->tmpvers, "-", pd->tmprel));
+ else
+ {
+ fprintf(stderr, "Seen <release> but no <version>\n");
+ }
+ }
+ else if (pd->tmpvers)
+ s->evr = makeevr(pd->pool, pd->tmpvers); /* just version, no release */
+ pd->tmpvers = sat_free((void *)pd->tmpvers);
+ pd->tmprel = sat_free((void *)pd->tmprel);
+ if (!s->arch)
+ s->arch = ARCH_NOARCH;
+ if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
+ s->provides = repo_addid_dep(pd->repo, s->provides, rel2id(pd->pool, s->name, s->evr, REL_EQ, 1), 0);
+ pd->solvable = 0;
+ break;
case STATE_VENDOR:
- pd->s->vendor = str2id(pd->pool, pd->content, 1);
+ s->vendor = str2id(pd->pool, pd->content, 1);
break;
case STATE_NAME:
- pd->s->name = str2id(pd->pool, join2("product", ":", pd->content), 1);
+ s->name = str2id(pd->pool, join2("product", ":", pd->content), 1);
break;
case STATE_VERSION:
pd->tmpvers = strdup(pd->content);
pd->tmprel = strdup(pd->content);
break;
case STATE_ARCH:
- pd->s->arch = str2id(pd->pool, pd->content, 1);
+ s->arch = str2id(pd->pool, pd->content, 1);
break;
case STATE_UPDATEREPOKEY:
repodata_set_str(pd->data, pd->handle, langtag(pd, PRODUCT_UPDATEREPOKEY, pd->tmplang), pd->content);
break;
case STATE_SUMMARY:
repodata_set_str(pd->data, pd->handle, langtag(pd, SOLVABLE_SUMMARY, pd->tmplang), pd->content);
- if (pd->tmplang)
- {
- free( (char *)pd->tmplang );
- pd->tmplang = 0;
- }
+ pd->tmplang = sat_free((void *)pd->tmplang);
break;
case STATE_DESCRIPTION:
repodata_set_str(pd->data, pd->handle, langtag(pd, SOLVABLE_DESCRIPTION, pd->tmplang), pd->content );
- if (pd->tmplang)
- {
- free( (char *)pd->tmplang );
- pd->tmplang = 0;
- }
+ pd->tmplang = sat_free((void *)pd->tmplang);
break;
case STATE_URL:
if (pd->tmpurltype)
{
repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content);
-
repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, str2id(pd->pool, pd->tmpurltype, 1));
}
+ pd->tmpurltype = sat_free((void *)pd->tmpurltype);
break;
case STATE_TARGET:
- repodata_set_str(pd->data, pd->handle, PRODUCT_REGISTER_TARGET, pd->content );
- if (currentproduct == baseproduct
+ repodata_set_str(pd->data, pd->handle, PRODUCT_REGISTER_TARGET, pd->content);
+ if (pd->currentproduct == pd->baseproduct
&& pd->attribute
&& !strcmp(pd->attribute, "register.target"))
{
}
break;
case STATE_FLAVOR:
- repodata_set_str(pd->data, pd->handle, PRODUCT_FLAVOR, pd->content );
- if (currentproduct == baseproduct
+ repodata_set_str(pd->data, pd->handle, PRODUCT_FLAVOR, pd->content);
+ if (pd->currentproduct == pd->baseproduct
&& pd->attribute
&& !strcmp(pd->attribute, "register.flavor"))
{
}
break;
case STATE_REGRELEASE:
- repodata_set_str(pd->data, pd->handle, PRODUCT_REGISTER_RELEASE, pd->content );
- if (currentproduct == baseproduct
+ repodata_set_str(pd->data, pd->handle, PRODUCT_REGISTER_RELEASE, pd->content);
+ if (pd->currentproduct == pd->baseproduct
&& pd->attribute
&& !strcmp(pd->attribute, "register.release"))
{
#if 0
fprintf(stderr, "end: [%s] -> %d\n", name, pd->state);
#endif
- return;
}
static void
repo_add_product(struct parsedata *pd, Repodata *data, FILE *fp, int code11)
{
- Pool *pool = pd->pool;
char buf[BUFF_SIZE];
- int i, l;
- struct stateswitch *sw;
+ int l;
struct stat st;
- pd->s = NULL; /* enforce new solvable when coming here again */
-
if (!fstat(fileno(fp), &st))
- currentproduct = st.st_ino;
- else
{
- currentproduct = baseproduct+1; /* make it != baseproduct if stat fails */
- st.st_ctime = 0;
- perror("Can't stat()");
+ pd->currentproduct = st.st_ino;
+ pd->ctime = (unsigned int)st.st_ctime;
}
-
- for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
+ else
{
- if (!pd->swtab[sw->from])
- pd->swtab[sw->from] = sw;
- pd->sbtab[sw->to] = sw->from;
+ pd->currentproduct = pd->baseproduct + 1; /* make it != baseproduct if stat fails */
+ perror("fstat");
+ pd->ctime = 0;
}
+
XML_Parser parser = XML_ParserCreate(NULL);
XML_SetUserData(parser, pd);
XML_SetElementHandler(parser, startElement, endElement);
break;
}
XML_ParserFree(parser);
-
- if (pd->s)
- {
- Solvable *s = pd->s;
-
- if (st.st_ctime)
- repodata_set_num(pd->data, pd->handle, SOLVABLE_INSTALLTIME, st.st_ctime);
- /* this is where <productsdir>/baseproduct points to */
- if (currentproduct == baseproduct)
- repodata_set_str(pd->data, pd->handle, PRODUCT_TYPE, "base");
-
- if (pd->tmprel)
- {
- if (pd->tmpvers)
- {
- s->evr = makeevr(pool, join2(pd->tmpvers, "-", pd->tmprel));
- free((char *)pd->tmpvers);
- pd->tmpvers = 0;
- }
- else
- {
- fprintf(stderr, "Seen <release> but no <version>\n");
- }
- free((char *)pd->tmprel);
- pd->tmprel = 0;
- }
- else if (pd->tmpvers)
- {
- s->evr = makeevr(pool, pd->tmpvers); /* just version, no release */
- free((char *)pd->tmpvers);
- pd->tmpvers = 0;
- }
- if (!s->arch)
- s->arch = ARCH_NOARCH;
- if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
- {
- s->provides = repo_addid_dep(pd->repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
- }
- } /* if pd->s */
-
- return;
}
if (code11
&& stat(join2(path, "/", "baseproduct"), &st) == 0) /* follow symlink */
{
- baseproduct = st.st_ino;
+ pd->baseproduct = st.st_ino;
}
else
- baseproduct = 0;
+ pd->baseproduct = 0;
while ((entry = readdir(dir)))
{
}
if (len > slen
- && strcmp(entry->d_name+len-slen, suffix) == 0)
+ && strcmp(entry->d_name + len - slen, suffix) == 0)
{
char *fullpath = join2(path, "/", entry->d_name);
FILE *fp = fopen(fullpath, "r");
repo_add_products(Repo *repo, Repodata *repodata, const char *proddir, const char *root, const char *attribute)
{
const char *fullpath = proddir;
- int code11 = 1;
- DIR *dir = opendir(fullpath);
+ int code11;
+ DIR *dir;
+ int i;
struct parsedata pd;
+ struct stateswitch *sw;
memset(&pd, 0, sizeof(pd));
pd.repo = repo;
pd.attribute = attribute;
+ for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
+ {
+ if (!pd.swtab[sw->from])
+ pd.swtab[sw->from] = sw;
+ pd.sbtab[sw->to] = sw->from;
+ }
+
+ code11 = 1;
+ dir = opendir(fullpath);
if (!dir)
{
fullpath = root ? join2(root, "", "/etc") : "/etc";
parse_dir(dir, fullpath, &pd, repodata, code11);
}
+ sat_free((void *)pd.tmplang);
free(pd.content);
join_freemem();
closedir(dir);