enum state {
STATE_START,
- STATE_METADATA,
- STATE_OTHERDATA,
- STATE_DISKUSAGEDATA,
- STATE_SUSEDATA,
-
STATE_SOLVABLE,
- STATE_PRODUCT,
- STATE_PATTERN,
- STATE_PATCH,
+
STATE_NAME,
STATE_ARCH,
STATE_VERSION,
STATE_DOWNLOADSIZE,
STATE_INSTALLTIME,
STATE_INSTALLONLY,
-
+
/* Novell/SUSE extended attributes */
STATE_EULA,
+ STATE_KEYWORD,
STATE_DISKUSAGE,
STATE_DIRS,
STATE_DIR,
STATE_UPDATEURL,
STATE_OPTIONALURL,
STATE_FLAG,
- STATE_FLAVOR,
- STATE_REFERENCES,
/* rpm-md dependencies inside the
format tag */
{ STATE_START, "pattern", STATE_SOLVABLE, 0 },
{ STATE_START, "patch", STATE_SOLVABLE, 0 },
{ STATE_START, "package", STATE_SOLVABLE, 0 },
-
+
{ STATE_SOLVABLE, "name", STATE_NAME, 1 },
{ STATE_SOLVABLE, "arch", STATE_ARCH, 1 },
{ STATE_SOLVABLE, "version", STATE_VERSION, 0 },
// package attributes rpm-md
{ STATE_SOLVABLE, "location", STATE_LOCATION, 0 },
{ STATE_SOLVABLE, "checksum", STATE_CHECKSUM, 1 },
-
+
/* resobject attributes */
{ STATE_SOLVABLE, "summary", STATE_SUMMARY, 1 },
{ STATE_SOLVABLE, "install-only", STATE_INSTALLONLY, 1 },
{ STATE_SOLVABLE, "time", STATE_TIME, 0 },
- /* extended Novell/SUSE attributes (suseinfo.xml) */
+ /* extended Novell/SUSE attributes (susedata.xml) */
{ STATE_SOLVABLE, "eula", STATE_EULA, 1 },
+ { STATE_SOLVABLE, "keyword", STATE_KEYWORD, 1 },
{ STATE_SOLVABLE, "diskusage", STATE_DISKUSAGE, 0 },
- { STATE_DISKUSAGE, "dirs", STATE_DIRS, 0 },
- { STATE_DIRS, "dir", STATE_DIR, 0 },
// pattern attribute
{ STATE_SOLVABLE, "script", STATE_SCRIPT, 1 },
{ STATE_SOLVABLE, "update-url", STATE_UPDATEURL, 1 },
{ STATE_SOLVABLE, "optional-url", STATE_OPTIONALURL, 1 },
{ STATE_SOLVABLE, "flag", STATE_FLAG, 1 },
- { STATE_SOLVABLE, "flavor", STATE_FLAVOR, 1 },
- { STATE_SOLVABLE, "references", STATE_REFERENCES, 1 },
{ STATE_SOLVABLE, "rpm:vendor", STATE_VENDOR, 1 },
{ STATE_SOLVABLE, "rpm:group", STATE_RPM_GROUP, 1 },
{ STATE_SOLVABLE, "rpm:license", STATE_RPM_LICENSE, 1 },
- /* rpm-md dependencies */
+ /* rpm-md dependencies */
{ STATE_SOLVABLE, "rpm:provides", STATE_PROVIDES, 0 },
{ STATE_SOLVABLE, "rpm:requires", STATE_REQUIRES, 0 },
{ STATE_SOLVABLE, "rpm:obsoletes", STATE_OBSOLETES, 0 },
{ STATE_SOLVABLE, "rpm:sourcerpm", STATE_SOURCERPM, 1 },
{ STATE_SOLVABLE, "rpm:header-range", STATE_HEADERRANGE, 0 },
{ STATE_SOLVABLE, "file", STATE_FILE, 1 },
-
+
+ /* extended Novell/SUSE diskusage attributes (susedata.xml) */
+ { STATE_DISKUSAGE, "dirs", STATE_DIRS, 0 },
+ { STATE_DIRS, "dir", STATE_DIR, 0 },
+
{ STATE_PROVIDES, "rpm:entry", STATE_PROVIDESENTRY, 0 },
{ STATE_REQUIRES, "rpm:entry", STATE_REQUIRESENTRY, 0 },
{ STATE_OBSOLETES, "rpm:entry", STATE_OBSOLETESENTRY, 0 },
{ STATE_SUGGESTS, "rpm:entry", STATE_SUGGESTSENTRY, 0 },
{ STATE_ENHANCES, "rpm:entry", STATE_ENHANCESENTRY, 0 },
{ STATE_FRESHENS, "rpm:entry", STATE_FRESHENSENTRY, 0 },
-
+
{ NUMSTATES}
};
/*
* makeevr_atts
* parse 'epoch', 'ver' and 'rel', return evr Id
- *
+ *
*/
static Id
* I: txt, name of attribute
* I: atts, list of key/value attributes
* O: pointer to value of matching key, or NULL
- *
+ *
*/
static inline const char *
/*
* adddep
* parse attributes to reldep Id
- *
+ *
*/
static unsigned int
pd->content = sat_realloc(pd->content, l + 256);
pd->acontent = l + 256;
}
- sprintf(pd->content, "%s:%s", k, n);
- name = str2id(pool, pd->content, 1);
+ sprintf(pd->content, "%s:%s", k, n);
+ name = str2id(pool, pd->content, 1);
}
else
name = str2id(pool, (char *)n, 1);
if (!str || !*str)
return;
for (aut = str; (aut = strchr(aut, '\n')) != 0; aut++)
- if (!strncmp(aut, "\nAuthors:\n--------\n", 19))
+ if (!strncmp(aut, "\nAuthors:\n--------\n", 19))
break;
if (aut)
{
/* oh my, found SUSE special author section */
- int l = aut - str;
- str[l] = 0;
+ int l = aut - str;
+ str[l] = 0;
while (l > 0 && str[l - 1] == '\n')
- str[--l] = 0;
+ str[--l] = 0;
if (l)
repodata_set_str(data, handle, SOLVABLE_DESCRIPTION, str);
p = aut + 19;
aut = str; /* copy over */
while (*p == ' ' || *p == '\n')
p++;
- while (*p)
+ while (*p)
{
if (*p == '\n')
{
*aut++ = *p++;
- while (*p == ' ')
+ while (*p == ' ')
p++;
continue;
}
}
while (aut != str && aut[-1] == '\n')
aut--;
- *aut = 0;
+ *aut = 0;
if (*str)
repodata_set_str(data, handle, SOLVABLE_AUTHORS, str);
}
/*
* set_sourcerpm
- *
+ *
*/
static void
/*
* startElement
* XML callback
- *
+ *
*/
static void XMLCALL
if (pd->state == STATE_START && !strcmp(name, "patterns"))
return;
- if (pd->state == STATE_START && !strcmp(name, "metadata"))
- return;
+ //if (pd->state == STATE_START && !strcmp(name, "metadata"))
+ // return;
if (pd->state == STATE_SOLVABLE && !strcmp(name, "format"))
return;
pd->depth++;
+ if (!pd->swtab[pd->state])
+ return;
for (sw = pd->swtab[pd->state]; sw->from == pd->state; sw++)
if (!strcmp(sw->ename, name))
break;
pd->kind = "product";
else if (name[2] == 't' && name[3] == 'c')
pd->kind = "patch";
-
+
/* to support extension metadata files like others.xml which
have the following structure:
one.
*/
const char *pkgid;
- if ( (pkgid = find_attr("pkgid", atts)) != NULL )
+ if ((pkgid = find_attr("pkgid", atts)) != NULL)
{
- int found = 0;
- /*const char *name = find_attr("name", atts);*/
// look at the checksum cache
- Id index = stringpool_str2id (&pd->cspool, pkgid, 1 /* create it */);
- if ( index < pd->ncscache )
- {
- Id solvid = pd->cscache[index-1];
- /* printf */
- if ( solvid > 0 )
- {
- Solvable *s = pool_id2solvable(pool, solvid);
- /* we found the already defined package */
- pd->solvable = s;
- found = 1;
- /*fprintf(stderr, "package found %s-%s.\n", name, find_attr("arch", atts));*/
- }
- }
- if ( ! found )
- {
+ Id index = stringpool_str2id(&pd->cspool, pkgid, 0);
+ if (!index || index >= pd->ncscache || !pd->cscache[index])
+ {
fprintf(stderr, "error, the repository specifies extra information about package with checksum '%s', which does not exist in the repository.\n", pkgid);
exit(1);
- }
+ }
+ pd->solvable = pool_id2solvable(pool, pd->cscache[index]);
}
else
{
/* this is a new package */
pd->solvable = pool_id2solvable(pool, repo_add_solvable(pd->common.repo));
pd->freshens = 0;
- repodata_extend(pd->data, pd->solvable - pool->solvables);
}
- pd->handle = repodata_get_handle(pd->data, (pd->solvable - pool->solvables) - pd->data->start);
+ pd->handle = pd->solvable - pool->solvables;
#if 0
fprintf(stderr, "package #%d\n", pd->solvable - pool->solvables);
#endif
case STATE_LOCATION:
str = find_attr("href", atts);
if (str)
- {
- const char *str2 = strrchr(str, '/');
- if (str2)
- {
- char *str3 = strdup(str);
- str3[str2 - str] = 0;
- repodata_set_poolstr(pd->data, handle, SOLVABLE_MEDIADIR, str3);
- free(str3);
- repodata_set_str(pd->data, handle, SOLVABLE_MEDIAFILE, str2 + 1);
- }
- else
- repodata_set_str(pd->data, handle, SOLVABLE_MEDIAFILE, str);
- }
+ repodata_set_location(pd->data, handle, 0, 0, str);
break;
case STATE_CHECKSUM:
pd->tmpattr = find_attr("type", atts);
/* Really, do nothing, wat for <dir> tag */
break;
}
- case STATE_DIR:
+ case STATE_DIR:
{
long filesz = 0, filenum = 0;
unsigned dirid;
dirid = repodata_str2dir(pd->data, str, 1);
}
else
- {
+ {
fprintf( stderr, "<dir .../> tag without 'name' attribute, atts = %p, *atts = %p\n", atts, *atts);
break;
}
/*
* endElement
* XML callback
- *
+ *
*/
static void XMLCALL
/* ignore patterns & metadata */
if (pd->state == STATE_START && !strcmp(name, "patterns"))
return;
- if (pd->state == STATE_START && !strcmp(name, "metadata"))
- return;
+ //if (pd->state == STATE_START && !strcmp(name, "metadata"))
+ // return;
if (pd->state == STATE_SOLVABLE && !strcmp(name, "format"))
return;
pd->statedepth--;
switch (pd->state)
{
- case STATE_PATTERN:
- case STATE_PRODUCT:
case STATE_SOLVABLE:
if (!s->arch)
s->arch = ARCH_NOARCH;
s->evr = ID_EMPTY; /* some patterns have this */
if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
- s->supplements = repo_fix_legacy(repo, s->provides, s->supplements, pd->freshens);
+ s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, pd->freshens);
+ s->conflicts = repo_fix_conflicts(repo, s->conflicts);
pd->freshens = 0;
pd->kind = 0;
break;
repodata_set_poolstr(pd->data, handle, SOLVABLE_LICENSE, pd->content);
break;
case STATE_CHECKSUM:
- {
+ {
int l;
- Id type;
+ Id type, index;
if (!strcasecmp (pd->tmpattr, "sha") || !strcasecmp (pd->tmpattr, "sha1"))
l = SIZEOF_SHA1 * 2, type = REPOKEY_TYPE_SHA1;
else if (!strcasecmp (pd->tmpattr, "md5"))
repodata_set_checksum(pd->data, handle, SOLVABLE_CHECKSUM, type, pd->content);
/* we save the checksum to solvable id relationship for extended
metadata */
- Id index = stringpool_str2id (&pd->cspool, pd->content, 1 /* create it */);
- if ( index >= pd->ncscache )
- {
- /** realloc for this index plus CSREALLOC_STEP*/
- pd->cscache = (Id *) sat_zextend(pd->cscache, pd->ncscache, index - pd->ncscache +1, sizeof(Id), 255);
- /** fill the realloced part with 0s */
-
- pd->ncscache = index +1;
-
- }
+ index = stringpool_str2id(&pd->cspool, pd->content, 1 /* create it */);
+ if (index >= pd->ncscache)
+ {
+ pd->cscache = sat_zextend(pd->cscache, pd->ncscache, index + 1 - pd->ncscache, sizeof(Id), 255);
+ pd->ncscache = index + 1;
+ }
/* add the checksum to the cache */
- pd->cscache[index-1] = s - pool->solvables;
-
+ pd->cscache[index] = s - pool->solvables;
+ break;
}
- break;
case STATE_FILE:
#if 0
id = str2id(pool, pd->content, 1);
break;
case STATE_RELNOTESURL:
if (pd->content[0])
- repodata_set_poolstr(pd->data, handle, PRODUCT_RELNOTESURL, pd->content);
+ {
+ repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content);
+ repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, str2id(pool, "releasenotes", 1));
+ }
break;
case STATE_UPDATEURL:
if (pd->content[0])
- repodata_set_poolstr(pd->data, handle, PRODUCT_EXTRAURLS, pd->content);
+ {
+ repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content);
+ repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, str2id(pool, "update", 1));
+ }
break;
case STATE_OPTIONALURL:
if (pd->content[0])
- repodata_set_poolstr(pd->data, handle, PRODUCT_OPTIONALURLS, pd->content);
+ {
+ repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content);
+ repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, str2id(pool, "optional", 1));
+ }
break;
case STATE_FLAG:
if (pd->content[0])
repodata_set_poolstr(pd->data, handle, PRODUCT_FLAGS, pd->content);
break;
- case STATE_FLAVOR:
- if (pd->content[0])
- repodata_set_str(pd->data, handle, PRODUCT_FLAVOR, pd->content);
- break;
- case STATE_REFERENCES:
- if (pd->content[0])
- repodata_set_str(pd->data, handle, PRODUCT_REFERENCES, pd->content);
- break;
case STATE_EULA:
if (pd->content[0])
repodata_set_str(pd->data, handle, langtag(pd, SOLVABLE_EULA, pd->language), pd->content);
break;
+ case STATE_KEYWORD:
+ if (pd->content[0])
+ repodata_add_poolstr_array(pd->data, pd->handle, SOLVABLE_KEYWORDS, pd->content);
+ break;
case STATE_DISKUSAGE:
if (pd->ndirs)
commit_diskusage (pd, pd->handle);
- break;
+ break;
default:
break;
}
/*
* characterData
* XML callback
- *
+ *
*/
static void XMLCALL
/*
* repo_add_rpmmd
* parse rpm-md metadata (primary, others)
- *
+ *
*/
void
char buf[BUFF_SIZE];
int i, l;
struct stateswitch *sw;
+ Repodata *data;
+ unsigned int now;
+
+ now = sat_timems(0);
+ if (!(flags & REPO_REUSE_REPODATA))
+ data = repo_add_repodata(repo, 0);
+ else
+ data = repo_last_repodata(repo);
memset(&pd, 0, sizeof(pd));
for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
pd.common.pool = pool;
pd.common.repo = repo;
- pd.data = repo_add_repodata(repo, 0);
+ pd.data = data;
pd.content = sat_malloc(256);
pd.acontent = 256;
the package checksums we know about, to get an Id
we can use in a cache */
stringpool_init_empty(&pd.cspool);
- pd.cscache = (Id *) calloc(MAX_CSCACHE, sizeof(Id));
- pd.ncscache = MAX_CSCACHE;
XML_Parser parser = XML_ParserCreate(NULL);
XML_SetUserData(parser, &pd);
break;
}
XML_ParserFree(parser);
-
- if (pd.data)
- repodata_internalize(pd.data);
sat_free(pd.content);
join_freemem();
+ stringpool_free(&pd.cspool);
+ sat_free(pd.cscache);
+ if (!(flags & REPO_NO_INTERNALIZE))
+ repodata_internalize(data);
+ POOL_DEBUG(SAT_DEBUG_STATS, "repo_add_rpmmd took %d ms\n", sat_timems(now));
+ POOL_DEBUG(SAT_DEBUG_STATS, "repo size: %d solvables\n", repo->nsolvables);
+ POOL_DEBUG(SAT_DEBUG_STATS, "repo memory used: %ld K incore, %ld K idarray\n", (unsigned long)data->incoredatalen/1024, (unsigned long)repo->idarraysize / (1024/sizeof(Id)));
}