static void
finish_solvable(struct parsedata *pd, Solvable *s, Offset freshens)
{
  Pool *pool = pd->repo->pool;
  Id handle = s - pool->solvables;

  if (pd->nfilelist)
    {
      int l;
      Id did;
      for (l = 0; l < pd->nfilelist; l += strlen(pd->filelist + l) + 1)
        {
	  char *p = strrchr(pd->filelist + l, '/');
	  if (!p)
	    continue;
	  *p++ = 0;
	  did = repodata_str2dir(pd->data, pd->filelist + l, 1);
	  p[-1] = '/';
	  if (!did)
	    did = repodata_str2dir(pd->data, "/", 1);
	  repodata_add_dirstr(pd->data, handle, SOLVABLE_FILELIST, did, p);
	}
      pd->nfilelist = 0;
    }
  /* Add self provide, except for source packages.  This is harmless
     to do twice (in case we see the same package twice).  */
  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);
  repo_rewrite_suse_deps(s, freshens);
  if (pd->diskusageq.count)
    repodata_add_diskusage(pd->data, handle, &pd->diskusageq);
}
Esempio n. 2
0
static void XMLCALL
endElement(void *userData, const char *name)
{
  //fprintf(stderr,"-tag: %s\n", name);
  struct parsedata *pd = userData;
  Pool *pool = pd->common.pool;
  Solvable *s = pd->solvable;
  Repo *repo = pd->common.repo;
  Id handle = pd->handle;
  Id id;
  char *p;

  if (pd->depth != pd->statedepth)
    {
      pd->depth--;
      // printf("back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth);
      return;
    }

  /* ignore patterns & metadata */
  if (pd->state == STATE_START && !strcmp(name, "patterns"))
    return;
  if (pd->state == STATE_START && !strcmp(name, "products"))
    return;
  //if (pd->state == STATE_START && !strcmp(name, "metadata"))
  //  return;
  if (pd->state == STATE_SOLVABLE && !strcmp(name, "format"))
    return;

  pd->depth--;
  pd->statedepth--;
  switch (pd->state)
    {
    case STATE_SOLVABLE:
      if (pd->kind && !s->name) /* add namespace in case of NULL name */
        s->name = str2id(pool, join2(pd->kind, ":", ""), 1);
      if (!s->arch)
        s->arch = ARCH_NOARCH;
      if (!s->evr)
        s->evr = ID_EMPTY;	/* some patterns have this */
      if (s->name && 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_supplements(repo, s->provides, s->supplements, pd->freshens);
      s->conflicts = repo_fix_conflicts(repo, s->conflicts);
      pd->freshens = 0;
      pd->kind = 0;
      break;
    case STATE_NAME:
      if (pd->kind)
        s->name = str2id(pool, join2(pd->kind, ":", pd->content), 1);
      else
        s->name = str2id(pool, pd->content, 1);
      break;
    case STATE_ARCH:
      s->arch = str2id(pool, pd->content, 1);
      break;
    case STATE_VENDOR:
      s->vendor = str2id(pool, pd->content, 1);
      break;
    case STATE_RPM_GROUP:
      repodata_set_poolstr(pd->data, handle, SOLVABLE_GROUP, pd->content);
      break;
    case STATE_RPM_LICENSE:
      repodata_set_poolstr(pd->data, handle, SOLVABLE_LICENSE, pd->content);
      break;
    case STATE_CHECKSUM:
      {
        Id type, index;
	type = sat_chksum_str2type(pd->tmpattr);
	if (!type)
	  {
            fprintf(stderr, "Unknown checksum type: %d: %s\n", (unsigned int)XML_GetCurrentLineNumber(*pd->parser), pd->tmpattr);
            exit(1);
	  }
        if (strlen(pd->content) != 2 * sat_chksum_len(type))
          {
            fprintf(stderr, "Invalid checksum length: %d: for %s\n", (unsigned int)XML_GetCurrentLineNumber(*pd->parser), pd->tmpattr);
            exit(1);
          }
        repodata_set_checksum(pd->data, handle, SOLVABLE_CHECKSUM, type, pd->content);
        /* we save the checksum to solvable id relationship for extended
           metadata */
        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] = s - pool->solvables;
        break;
      }
    case STATE_FILE:
#if 0
      id = str2id(pool, pd->content, 1);
      s->provides = repo_addid_dep(repo, s->provides, id, SOLVABLE_FILEMARKER);
#endif
      if ((p = strrchr(pd->content, '/')) != 0)
	{
	  *p++ = 0;
	  if (pd->lastdir && !strcmp(pd->lastdirstr, pd->content))
	    {
	      id = pd->lastdir;
	    }
	  else
	    {
	      int l;
	      id = repodata_str2dir(pd->data, pd->content, 1);
	      l = strlen(pd->content) + 1;
	      if (l > pd->lastdirstrl)
		{
		  pd->lastdirstrl = l + 128;
		  pd->lastdirstr = sat_realloc(pd->lastdirstr, pd->lastdirstrl);
		}
	      strcpy(pd->lastdirstr, pd->content);
	      pd->lastdir = id;
	    }
	}
      else
	{
	  p = pd->content;
	  id = 0;
	}
      if (!id)
	id = repodata_str2dir(pd->data, "/", 1);
      repodata_add_dirstr(pd->data, handle, SOLVABLE_FILELIST, id, p);
      break;
    case STATE_SUMMARY:
      repodata_set_str(pd->data, handle, langtag(pd, SOLVABLE_SUMMARY, pd->tmplang), pd->content);
      break;
    case STATE_DESCRIPTION:
      set_description_author(pd->data, handle, pd->content, pd);
      break;
    case STATE_CATEGORY:
      repodata_set_str(pd->data, handle, langtag(pd, SOLVABLE_CATEGORY, pd->tmplang), pd->content);
      break;
    case STATE_DISTRIBUTION:
        repodata_set_poolstr(pd->data, handle, SOLVABLE_DISTRIBUTION, pd->content);
        break;
    case STATE_URL:
      if (pd->content[0])
	repodata_set_str(pd->data, handle, SOLVABLE_URL, pd->content);
      break;
    case STATE_PACKAGER:
      if (pd->content[0])
	repodata_set_poolstr(pd->data, handle, SOLVABLE_PACKAGER, pd->content);
      break;
    case STATE_SOURCERPM:
      set_sourcerpm(pd->data, s, handle, pd->content);
      break;
    case STATE_RELNOTESURL:
      if (pd->content[0])
        {
          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_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_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_EULA:
      if (pd->content[0])
	repodata_set_str(pd->data, handle, langtag(pd, SOLVABLE_EULA, pd->tmplang), 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;
    case STATE_ORDER:
      if (pd->content[0])
        repodata_set_str(pd->data, pd->handle, SOLVABLE_ORDER, pd->content);
    default:
      break;
    }
  pd->state = pd->sbtab[pd->state];
  pd->docontent = 0;
  // fprintf(stderr, "back from known %d %d %d\n", pd->state, pd->depth, pd->statedepth);
}