/*
* repo_helix.c
- *
+ *
* Parse 'helix' XML representation
* and create 'repo'
- *
+ *
+ * A bit of history: "Helix Code" was the name of the company that
+ * wrote Red Carpet. The company was later renamed to Ximian.
+ * The Red Carpet solver was merged into the ZYPP project, the
+ * library used both by ZENworks and YaST for package management.
+ * Red Carpet came with solver testcases in its own repository
+ * format, the 'helix' format.
+ *
*/
#include <sys/types.h>
{ STATE_START, "channel", STATE_CHANNEL, 0 },
{ STATE_CHANNEL, "subchannel", STATE_SUBCHANNEL, 0 },
{ STATE_SUBCHANNEL, "package", STATE_PACKAGE, 0 },
+ { STATE_SUBCHANNEL, "srcpackage", STATE_PACKAGE, 0 },
{ STATE_SUBCHANNEL, "selection", STATE_PACKAGE, 0 },
{ STATE_SUBCHANNEL, "pattern", STATE_PACKAGE, 0 },
{ STATE_SUBCHANNEL, "atom", STATE_PACKAGE, 0 },
{ STATE_SUBCHANNEL, "patch", STATE_PACKAGE, 0 },
{ STATE_SUBCHANNEL, "product", STATE_PACKAGE, 0 },
+ { STATE_SUBCHANNEL, "application", STATE_PACKAGE, 0 },
{ STATE_PACKAGE, "name", STATE_NAME, 1 },
{ STATE_PACKAGE, "vendor", STATE_VENDOR, 1 },
{ STATE_PACKAGE, "buildtime", STATE_BUILDTIME, 1 },
*/
typedef struct _parsedata {
- // XML parser data
+ int ret;
+ /* XML parser data */
int depth;
- enum state state; // current state
+ enum state state; /* current state */
int statedepth;
- char *content; // buffer for content of node
- int lcontent; // actual length of current content
- int acontent; // actual buffer size
- int docontent; // handle content
-
- // repo data
- Pool *pool; // current pool
- Repo *repo; // current repo
- Repodata *data; // current repo data
- Solvable *solvable; // current solvable
- Offset freshens; // current freshens vector
-
- // package data
- int epoch; // epoch (as offset into evrspace)
- int version; // version (as offset into evrspace)
- int release; // release (as offset into evrspace)
- char *evrspace; // buffer for evr
- int aevrspace; // actual buffer space
- int levrspace; // actual evr length
+ char *content; /* buffer for content of node */
+ int lcontent; /* actual length of current content */
+ int acontent; /* actual buffer size */
+ int docontent; /* handle content */
+
+ /* repo data */
+ Pool *pool; /* current pool */
+ Repo *repo; /* current repo */
+ Repodata *data; /* current repo data */
+ Solvable *solvable; /* current solvable */
+ Offset freshens; /* current freshens vector */
+
+ /* package data */
+ int epoch; /* epoch (as offset into evrspace) */
+ int version; /* version (as offset into evrspace) */
+ int release; /* release (as offset into evrspace) */
+ char *evrspace; /* buffer for evr */
+ int aevrspace; /* actual buffer space */
+ int levrspace; /* actual evr length */
char *kind;
struct stateswitch *swtab[NUMSTATES];
/*------------------------------------------------------------------*/
/* E:V-R handling */
-// create Id from epoch:version-release
+/* create Id from epoch:version-release */
static Id
evr2id(Pool *pool, Parsedata *pd, const char *e, const char *v, const char *r)
char *c;
int l;
- // treat explitcit 0 as NULL
- if (e && !strcmp(e, "0"))
- e = NULL;
+ /* treat explitcit 0 as NULL */
+ if (e && (!*e || !strcmp(e, "0")))
+ e = 0;
if (v && !e)
{
const char *v2;
- // scan version for ":"
- for (v2 = v; *v2 >= '0' && *v2 <= '9'; v2++) // skip leading digits
+ /* scan version for ":" */
+ for (v2 = v; *v2 >= '0' && *v2 <= '9'; v2++) /* skip leading digits */
;
- // if version contains ":", set epoch to "0"
+ /* if version contains ":", set epoch to "0" */
if (v2 > v && *v2 == ':')
e = "0";
}
-
- // compute length of Id string
- l = 1; // for the \0
+
+ /* compute length of Id string */
+ l = 1; /* for the \0 */
if (e)
- l += strlen(e) + 1; // e:
+ l += strlen(e) + 1; /* e: */
if (v)
- l += strlen(v); // v
+ l += strlen(v); /* v */
if (r)
- l += strlen(r) + 1; // -r
+ l += strlen(r) + 1; /* -r */
- // extend content if not sufficient
+ /* extend content if not sufficient */
if (l > pd->acontent)
{
pd->content = (char *)realloc(pd->content, l + 256);
pd->acontent = l + 256;
}
- // copy e-v-r to content
+ /* copy e-v-r to content */
c = pd->content;
if (e)
{
c += strlen(c);
}
*c = 0;
- // if nothing inserted, return Id 0
+ /* if nothing inserted, return Id 0 */
if (!*pd->content)
return ID_NULL;
#if 0
fprintf(stderr, "evr: %s\n", pd->content);
#endif
- // intern and create
+ /* intern and create */
return pool_str2id(pool, pd->content, 1);
}
-// create e:v-r from attributes
-// atts is array of name,value pairs, NULL at end
-// even index into atts is name
-// odd index is value
-//
+/* create e:v-r from attributes
+ * atts is array of name,value pairs, NULL at end
+ * even index into atts is name
+ * odd index is value
+ */
static Id
evr_atts2id(Pool *pool, Parsedata *pd, const char **atts)
{
/*
* XML callback
* <name>
- *
+ *
*/
static void XMLCALL
#endif
return;
}
-
- // set new state
+
+ /* set new state */
pd->state = sw->to;
pd->docontent = sw->docontent;
pd->statedepth = pd->depth;
- // start with empty content
- // (will collect data until end element
+ /* start with empty content */
+ /* (will collect data until end element) */
pd->lcontent = 0;
*pd->content = 0;
pd->kind = "product";
else if (!strcmp(name, "patch"))
pd->kind = "patch";
+ else if (!strcmp(name, "application"))
+ pd->kind = "application";
else
pd->kind = NULL; /* default is package */
pd->levrspace = 1;
{
Pool *pool = pd->pool;
Id pid, *pidp;
-
+
if (s->provides)
{
pidp = pd->repo->idarraydata + s->provides;
{
Reldep *prd;
const char *depname;
-
+
if (!ISRELDEP(pid))
continue; /* wrong provides name */
prd = GETRELDEP(pool, pid);
if (!ISRELDEP(pid))
{
depname = pool_id2str(pool, pid);
- }
- else
+ }
+ else
{
Reldep *prd = GETRELDEP(pool, pid);
depname = pool_id2str(pool, prd->name);
/*
* XML callback
* </name>
- *
+ *
* create Solvable from collected data
*/
if (pd->depth != pd->statedepth)
{
pd->depth--;
- // printf("back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth);
+ /* printf("back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth); */
return;
}
{
case STATE_PACKAGE: /* package complete */
+ if (name[0] == 's' && name[1] == 'r' && name[2] == 'c' && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
+ s->arch = ARCH_SRC;
if (!s->arch) /* default to "noarch" */
s->arch = ARCH_NOARCH;
s->evr = evr2id(pool, pd,
pd->epoch ? pd->evrspace + pd->epoch : 0,
pd->version ? pd->evrspace + pd->version : 0,
- pd->release ? pd->evrspace + pd->release : 0);
+ pd->release ? pd->evrspace + pd->release : "");
/* ensure self-provides */
if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
s->provides = repo_addid_dep(pd->repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
/* see bugzilla bnc#190163 */
flavor = findKernelFlavor(pd, s);
- if (flavor)
+ if (flavor)
{
char *cflavor = solv_strdup(flavor); /* make pointer safe */
pd->version = 0;
pd->release = 0;
/* use highest evr */
- if (!s->evr || pool_evrcmp(pool, s->evr, evr, EVRCMP_MATCH_RELEASE) <= 0)
+ if (!s->evr || pool_evrcmp(pool, s->evr, evr, EVRCMP_COMPARE) <= 0)
s->evr = evr;
break;
case STATE_EPOCH:
}
pd->state = pd->sbtab[pd->state];
pd->docontent = 0;
- // printf("back from known %d %d %d\n", pd->state, pd->depth, pd->statedepth);
+ /* printf("back from known %d %d %d\n", pd->state, pd->depth, pd->statedepth); */
}
/*
* XML callback
* character data
- *
+ *
*/
static void XMLCALL
int l;
char *c;
- // check if current nodes content is interesting
+ /* check if current nodes content is interesting */
if (!pd->docontent)
return;
- // adapt content buffer
+ /* adapt content buffer */
l = pd->lcontent + len + 1;
if (l > pd->acontent)
{
pd->content = (char *)realloc(pd->content, l + 256);
pd->acontent = l + 256;
}
- // append new content to buffer
+ /* append new content to buffer */
c = pd->content + pd->lcontent;
pd->lcontent += len;
while (len-- > 0)
/*
* read 'helix' type xml from fp
* add packages to pool/repo
- *
+ *
*/
int
now = solv_timems(0);
data = repo_add_repodata(repo, flags);
-
+
/* prepare parsedata */
memset(&pd, 0, sizeof(pd));
for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
pd.levrspace = 1;
pd.data = data;
- // set up XML parser
+ /* set up XML parser */
parser = XML_ParserCreate(NULL);
XML_SetUserData(parser, &pd); /* make parserdata available to XML callbacks */
XML_SetElementHandler(parser, startElement, endElement);
XML_SetCharacterDataHandler(parser, characterData);
- // read/parse XML file
+ /* read/parse XML file */
for (;;)
{
l = fread(buf, 1, sizeof(buf), fp);
if (XML_Parse(parser, buf, l, l == 0) == XML_STATUS_ERROR)
{
- pool_debug(pool, SOLV_FATAL, "%s at line %u\n", XML_ErrorString(XML_GetErrorCode(parser)), (unsigned int)XML_GetCurrentLineNumber(parser));
- exit(1);
+ pd.ret = pool_error(pool, -1, "%s at line %u", XML_ErrorString(XML_GetErrorCode(parser)), (unsigned int)XML_GetCurrentLineNumber(parser));
+ break;
}
if (l == 0)
break;
repodata_internalize(data);
POOL_DEBUG(SOLV_DEBUG_STATS, "repo_add_helix took %d ms\n", solv_timems(now));
POOL_DEBUG(SOLV_DEBUG_STATS, "repo size: %d solvables\n", repo->nsolvables);
- POOL_DEBUG(SOLV_DEBUG_STATS, "repo memory used: %d K incore, %d K idarray\n", data->incoredatalen/1024, repo->idarraysize / (int)(1024/sizeof(Id)));
- return 0;
+ POOL_DEBUG(SOLV_DEBUG_STATS, "repo memory used: %d K incore, %d K idarray\n", repodata_memused(data)/1024, repo->idarraysize / (int)(1024/sizeof(Id)));
+ return pd.ret;
}