예제 #1
0
// reset all hash tables
// 
void
pool_freeidhashes(Pool *pool)
{
  stringpool_freehash(&pool->ss);
  pool->relhashtbl = sat_free(pool->relhashtbl);
  pool->relhashmask = 0;
}
예제 #2
0
파일: queue.c 프로젝트: openSUSE/sat-solver
void
queue_free(Queue *q)
{
  if (q->alloc)
    sat_free(q->alloc);
  q->alloc = q->elements = 0;
  q->count = q->left = 0;
}
예제 #3
0
int main(int argc, char *argv[]) {
	int c;
	sat_t *sat;
	uint32_t sa_repeat = 100;
	uint32_t sa_best = 0;
	uint32_t sa_sum = 0;
	bool run_bruteforce = 0;
	bool sa_run = true;

	srand(time(0));

	while ((c = getopt(argc, argv, "bc:l:r:sSP")) != -1) {
		switch (c) {
		case 'b':
			run_bruteforce = true;
			break;
		case 'c':
			switch (atoi(optarg)) {
			case 1:
				cost = &cost1;
				break;
			case 2:
				cost = &cost2;
				break;
			case 3:
				cost = &cost3;
				break;
			default:
				assert(0);
				break;
			}
			break;
		case 'l':
			g_limit = atoi(optarg);
			break;
		case 'r':
			sa_repeat = (uint32_t) atoi(optarg);
			break;
		case 's':
			g_just_solved = true;
			break;
		case 'S':
			sa_run = false;
			break;
		case 'P':
			g_print_progress = true;
			break;
		case '?':
			fprintf(stderr, "unknown opt\n");
			return (EXIT_FAILURE);
			break;
		default:
			abort();
			break;
		}
	}

	sat = sat_load();
	//sat_print(sat);

//	sat_simulated_evolution(sat, 100);

	if (run_bruteforce) {
		sat_bruteforce(sat);
	}

	if (sa_run) {
		assert(cost != NULL);
		double sa_time = omp_get_wtime();
		for (uint32_t i = 0; i < sa_repeat; i++) {
			uint32_t res = simulated_annealing(sat, 0.01, 10000);
//		fprintf(stderr, "[%u]", i);
//		fflush(stdout);
			sa_sum += res;
			if (sa_best < res) {
				sa_best = res;
			}
		}
		sa_time = (omp_get_wtime() - sa_time) / (double) sa_repeat;
//	fprintf(stderr, "\n");


		if (g_just_solved) {
			if (sa_best > 0) {
				fprintf(stderr, "1");
			} else {
				fprintf(stderr, "0");
			}
		} else {
			fprintf(stderr, "saavg= %u sabest= %u satime= %lf \n",
					(uint32_t) ((double) sa_sum / (double) sa_repeat), sa_best,
					sa_time);

		}
	}



	sat_free(sat);

	return (EXIT_SUCCESS);
}
예제 #4
0
/* http://people.sc.fsu.edu/~jburkardt/data/cnf/cnf.html */
static sat_t *sat_load() {
	sat_t *sat = NULL;

	sat = calloc(1, sizeof(sat_t));
	assert(sat != NULL);

	if (scanf("p cnf %" SCNu32 " %" SCNu32, &sat->vars_cnt, &sat->clauses_cnt)
			!= 2) {
		fprintf(stderr, "scanf p cnf %%d %%d has failed\n");
		goto error;
	}

	sat->clauses_cnt = min(sat->clauses_cnt, g_limit);

	sat->weights = malloc(sizeof(uint32_t) * sat->vars_cnt);

#ifdef SAT_READ_WEIGHTS
	char c;
	if (scanf("%c", &c) != 1) {
		fprintf(stderr, "reading w failed\n");
		goto error;
	}
	if ((c = getchar()) != 'w') {
		fprintf(stderr, "reading w failed its -%c-\n", c);
		goto error;
	}
#else
	srand(0);
#endif

	sat->weight_sum = 0;
	sat->weight_max = 0;
	for (uint32_t i = 0; i < sat->vars_cnt; i++) {
#ifdef SAT_READ_WEIGHTS
		int res;
		if ((res = scanf("%" SCNu32, &sat->weights[i])) != 1) {
			fprintf(stderr, "reading weight %d has failed, scanf=%d\n", i, res);
			goto error;
		}
#else
		sat->weights[i] = (rand() % 5) + 1;
#endif
		sat->weight_sum += sat->weights[i];
		sat->weight_max = max(sat->weight_max, sat->weights[i]);
	}

#ifndef SAT_READ_WEIGHTS
	srand(time(0));
#endif

	sat->clauses = malloc(sizeof(int8_t *) * sat->clauses_cnt);
	assert(sat->clauses);
	for (uint32_t i = 0; i < sat->clauses_cnt; i++) {
		sat->clauses[i] = malloc(sizeof(int8_t *) * (sat->clauses_cnt + 1));
		assert(sat->clauses[i]);

		for (uint32_t j = 0; j < 3; j++) {
			if (scanf("%" SCNd32, &sat->clauses[i][j]) != 1) {
				fprintf(stderr, "reading clause [%d][%d] has failed\n", i, j);
				goto error;
			}
		}

		if (scanf("%" SCNd32, &sat->clauses[i][sat->vars_cnt]) != 1) {
			fprintf(stderr, "reading terminating clause [%d][] has failed\n",
					i);
			goto error;
		}
		if (sat->clauses[i][sat->vars_cnt] != 0) {
			fprintf(stderr, "terminating clause [%d][] is not 0 but %d\n", i,
					sat->clauses[i][sat->vars_cnt]);
			goto error;
		}
	}

	return (sat);

	error: //
	sat_free(sat);
	return (NULL);
}
예제 #5
0
void
repo_add_rpmmd(Repo *repo, FILE *fp, const char *language, int flags)
{
  Pool *pool = repo->pool;
  struct parsedata pd;
  char buf[BUFF_SIZE];
  int i, l;
  struct stateswitch *sw;
  Repodata *data;
  unsigned int now;

  now = sat_timems(0);
  data = repo_add_repodata(repo, flags);

  memset(&pd, 0, sizeof(pd));
  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;
    }
  pd.common.pool = pool;
  pd.common.repo = repo;

  pd.data = data;

  pd.content = sat_malloc(256);
  pd.acontent = 256;
  pd.lcontent = 0;
  pd.common.tmp = 0;
  pd.common.tmpl = 0;
  pd.kind = 0;
  pd.language = language;

  /* initialize the string pool where we will store
     the package checksums we know about, to get an Id
     we can use in a cache */
  stringpool_init_empty(&pd.cspool);
  if ((flags & REPO_EXTEND_SOLVABLES) != 0)
    {
      /* setup join data */
      Dataiterator di;
      dataiterator_init(&di, pool, repo, 0, SOLVABLE_CHECKSUM, 0, 0);
      while (dataiterator_step(&di))
	{
	  const char *str;
	  int index;

	  if (!sat_chksum_len(di.key->type))
	    continue;
	  str = repodata_chk2str(di.data, di.key->type, (const unsigned char *)di.kv.str);
          index = stringpool_str2id(&pd.cspool, str, 1);
	  if (index >= pd.ncscache)
	    {
	      pd.cscache = sat_zextend(pd.cscache, pd.ncscache, index + 1 - pd.ncscache, sizeof(Id), 255);
	      pd.ncscache = index + 1;
	    }
          pd.cscache[index] = di.solvid;
	}
      dataiterator_free(&di);
    }

  XML_Parser parser = XML_ParserCreate(NULL);
  XML_SetUserData(parser, &pd);
  pd.parser = &parser;
  XML_SetElementHandler(parser, startElement, endElement);
  XML_SetCharacterDataHandler(parser, characterData);
  for (;;)
    {
      l = fread(buf, 1, sizeof(buf), fp);
      if (XML_Parse(parser, buf, l, l == 0) == XML_STATUS_ERROR)
	{
	  pool_debug(pool, SAT_FATAL, "repo_rpmmd: %s at line %u:%u\n", XML_ErrorString(XML_GetErrorCode(parser)), (unsigned int)XML_GetCurrentLineNumber(parser), (unsigned int)XML_GetCurrentColumnNumber(parser));
	  exit(1);
	}
      if (l == 0)
	break;
    }
  XML_ParserFree(parser);
  sat_free(pd.content);
  sat_free(pd.lastdirstr);
  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: %d K incore, %d K idarray\n", data->incoredatalen/1024, repo->idarraysize / (int)(1024/sizeof(Id)));
}
예제 #6
0
int
main(int argc, char **argv)
{
  int c, flags = 0;
  const char *attrname = 0;
  const char *basefile = 0;
  const char *dir = 0;
  const char *locale = 0;
  
  Pool *pool = pool_create();
  Repo *repo = repo_create(pool, "<stdin>");

  while ((c = getopt (argc, argv, "hkn:b:d:l:")) >= 0)
    {
      switch(c)
	{
        case 'h':
          usage(0);
          break;
        case 'k':
          flags |= RPMMD_KINDS_SEPARATELY;   /* do not use! */
          break;
        case 'n':
          attrname = optarg;
          break;
        case 'b':
          basefile = optarg;
          break;
        case 'd':
          dir = optarg;
          break;
	case 'l':
	  locale = optarg;
	  break;
        default:
          usage(1);
          break;
	}
    }
  if (dir)
    {
      FILE *fp;
      int l;
      char *fnp;
      l = strlen(dir) + 128;
      fnp = sat_malloc(l+1);
      snprintf(fnp, l, "%s/primary.xml.gz", dir);
      if (!(fp = myfopen(fnp)))
	{
	  perror(fnp);
	  exit(1);
	}
      repo_add_rpmmd(repo, fp, 0, flags);
      fclose(fp);
      snprintf(fnp, l, "%s/diskusagedata.xml.gz", dir);
      if ((fp = myfopen(fnp)))
	{
	  repo_add_rpmmd(repo, fp, 0, flags);
	  fclose(fp);
	}
      if (locale)
	{
	  if (snprintf(fnp, l, "%s/translation-%s.xml.gz", dir, locale) >= l)
	    {
	      fprintf(stderr, "-l parameter too long\n");
	      exit(1);
	    }
	  while (!(fp = myfopen(fnp)))
	    {
	      fprintf(stderr, "not opened %s\n", fnp);
	      if (strlen(locale) > 2)
		{
		  if (snprintf(fnp, l, "%s/translation-%.2s.xml.gz", dir, locale) >= l)
		    {
		      fprintf(stderr, "-l parameter too long\n");
		      exit(1);
		    }
		  if ((fp = myfopen(fnp)))
		    break;
		}
	      perror(fnp);
	      exit(1);
	    }
	  fprintf(stderr, "opened %s\n", fnp);
	  repo_add_rpmmd(repo, fp, 0, flags);
	  fclose(fp);
	}
      sat_free(fnp);
    }
  else
    repo_add_rpmmd(repo, stdin, 0, flags);
  tool_write(repo, basefile, attrname);
  pool_free(pool);
  exit(0);
}
예제 #7
0
Id
pool_rel2id(Pool *pool, Id name, Id evr, int flags, int create)
{
  Hashval h;
  unsigned int hh;
  Hashmask hashmask;
  int i;
  Id id;
  Hashtable hashtbl;
  Reldep *ran;

  hashmask = pool->relhashmask;
  hashtbl = pool->relhashtbl;
  ran = pool->rels;
  
  /* extend hashtable if needed */
  if (pool->nrels * 2 > hashmask)
    {
      sat_free(pool->relhashtbl);
      pool->relhashmask = hashmask = mkmask(pool->nrels + REL_BLOCK);
      pool->relhashtbl = hashtbl = sat_calloc(hashmask + 1, sizeof(Id));
      // rehash all rels into new hashtable
      for (i = 1; i < pool->nrels; i++)
	{
	  h = relhash(ran[i].name, ran[i].evr, ran[i].flags) & hashmask;
	  hh = HASHCHAIN_START;
	  while (hashtbl[h])
	    h = HASHCHAIN_NEXT(h, hh, hashmask);
	  hashtbl[h] = i;
	}
    }
  
  /* compute hash and check for match */
  h = relhash(name, evr, flags) & hashmask;
  hh = HASHCHAIN_START;
  while ((id = hashtbl[h]) != 0)
    {
      if (ran[id].name == name && ran[id].evr == evr && ran[id].flags == flags)
	break;
      h = HASHCHAIN_NEXT(h, hh, hashmask);
    }
  if (id)
    return MAKERELDEP(id);

  if (!create)
    return ID_NULL;

  id = pool->nrels++;
  /* extend rel space if needed */
  pool->rels = sat_extend(pool->rels, id, 1, sizeof(Reldep), REL_BLOCK);
  hashtbl[h] = id;
  ran = pool->rels + id;
  ran->name = name;
  ran->evr = evr;
  ran->flags = flags;

  /* extend whatprovides_rel if needed */
  if (pool->whatprovides_rel && (id & WHATPROVIDES_BLOCK) == 0)
    {
      pool->whatprovides_rel = sat_realloc2(pool->whatprovides_rel, id + (WHATPROVIDES_BLOCK + 1), sizeof(Offset));
      memset(pool->whatprovides_rel + id, 0, (WHATPROVIDES_BLOCK + 1) * sizeof(Offset));
    }
  return MAKERELDEP(id);
}
예제 #8
0
void
repo_add_content(Repo *repo, FILE *fp, int flags)
{
  Pool *pool = repo->pool;
  char *line, *linep;
  int aline;
  Solvable *s;
  struct parsedata pd;
  Repodata *data;
  Id handle = 0;
  int contentstyle = 0;
  char *descrdir = 0;
  char *datadir = 0;
  char *defvendor = 0;

  int i = 0;

  /* architectures
     we use the first architecture in BASEARCHS or noarch
     for the product. At the end we create (clone) the product
     for each one of the remaining architectures
     we allow max 4 archs
  */
  unsigned int numotherarchs = 0;
  Id *otherarchs = 0;

  memset(&pd, 0, sizeof(pd));
  line = sat_malloc(1024);
  aline = 1024;

  pd.repo = repo;
  linep = line;
  s = 0;

  data = repo_add_repodata(repo, flags);

  for (;;)
    {
      char *key, *value;

      /* read line into big-enough buffer */
      if (linep - line + 16 > aline)
	{
	  aline = linep - line;
	  line = sat_realloc(line, aline + 512);
	  linep = line + aline;
	  aline += 512;
	}
      if (!fgets(linep, aline - (linep - line), fp))
	break;
      linep += strlen(linep);
      if (linep == line || linep[-1] != '\n')
        continue;
      while ( --linep > line && ( linep[-1] == ' ' ||  linep[-1] == '\t' ) )
        ; /* skip trailing ws */
      *linep = 0;
      linep = line;

      /* expect "key value" lines */
      value = line;
      key = splitword(&value);

      if (key)
        {
#if 0
	  fprintf (stderr, "key %s, value %s\n", key, value);
#endif

#define istag(x) (!strcmp (key, x))
#define code10 (contentstyle == 10)
#define code11 (contentstyle == 11)


	  if (istag ("CONTENTSTYLE"))
	    {
	      if (contentstyle)
	        pool_debug(pool, SAT_ERROR, "repo_content: 'CONTENTSTYLE' must be first line of 'content'\n");
	      contentstyle = atoi(value);
	      continue;
	    }
	  if (!contentstyle)
	    contentstyle = 10;

	  /* repository tags */
          /* we also replicate some of them into the product solvables
           * to be backward compatible */

	  if (istag ("REPOID"))
	    {
	      repodata_add_poolstr_array(data, SOLVID_META, REPOSITORY_REPOID, value);
	      continue;
	    }

	  if (istag ("DESCRDIR"))
	    {
	      if (descrdir)
		free(descrdir);
	      else
	        repo_set_str(repo, SOLVID_META, SUSETAGS_DESCRDIR, value);
	      if (s)
	        repo_set_str(repo, s - pool->solvables, SUSETAGS_DESCRDIR, value);
	      descrdir = strdup(value);
	      continue;
	    }
	  if (istag ("DATADIR"))
	    {
	      if (datadir)
		free(datadir);
	      else
	        repo_set_str(repo, SOLVID_META, SUSETAGS_DATADIR, value);
	      if (s)
	        repo_set_str(repo, s - pool->solvables, SUSETAGS_DATADIR, value);
	      datadir = strdup(value);
	      continue;
	    }
	  if (istag ("VENDOR"))
	    {
	      if (defvendor)
		free(defvendor);
	      else
	        repo_set_poolstr(repo, SOLVID_META, SUSETAGS_DEFAULTVENDOR, value);
	      if (s)
		s->vendor = str2id(pool, value, 1);
	      defvendor = strdup(value);
	      continue;
	    }

	  if (istag ("META") || istag ("HASH") || istag ("KEY"))
	    {
	      char *checksumtype, *checksum;
	      Id fh, type;
	      int l;

	      if ((checksumtype = splitword(&value)) == 0)
		continue;
	      if ((checksum = splitword(&value)) == 0)
		continue;
	      if (!*value)
		continue;
	      if (!strcasecmp(checksumtype, "sha") || !strcasecmp(checksumtype, "sha1"))
	        l = SIZEOF_SHA1 * 2, type = REPOKEY_TYPE_SHA1;
	      else if (!strcasecmp(checksumtype, "sha256"))
	        l = SIZEOF_SHA256 * 2, type = REPOKEY_TYPE_SHA256;
	      else if (!strcasecmp(checksumtype, "md5"))
	        l = SIZEOF_MD5 * 2, type = REPOKEY_TYPE_MD5;
	      else
	        {
		  fprintf(stderr, "Unknown checksum type: %s: %s\n", value, checksumtype);
		  exit(1);
	        }
	      if (strlen(checksum) != l)
	        {
		  fprintf(stderr, "Invalid checksum length: %s: for %s\n", value, checksum);
		  exit(1);
	        }
	      fh = repodata_new_handle(data);
	      repodata_set_poolstr(data, fh, SUSETAGS_FILE_TYPE, key);
	      repodata_set_str(data, fh, SUSETAGS_FILE_NAME, value);
	      repodata_set_checksum(data, fh, SUSETAGS_FILE_CHECKSUM, type, checksum);
	      repodata_add_flexarray(data, SOLVID_META, SUSETAGS_FILE, fh);
	      continue;
	    }

	  /* product tags */

	  if ((code10 && istag ("PRODUCT"))
	      || (code11 && istag ("NAME")))
	    {
	      if (s && !s->name)
		{
		  /* this solvable was created without seeing a
		     PRODUCT entry, just set the name and continue */
		  s->name = str2id(pool, join(&pd, "product", ":", value), 1);
		  continue;
		}
	      if (s)
		{
		  /* finish old solvable */
		  if (!s->arch)
		    s->arch = ARCH_NOARCH;
		  if (!s->evr)
		    s->evr = ID_EMPTY;
		  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);
		  if (code10)
		    s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);
		}
	      /* create new solvable */
	      s = pool_id2solvable(pool, repo_add_solvable(repo));
	      repodata_extend(data, s - pool->solvables);
	      handle = s - pool->solvables;
	      s->name = str2id(pool, join(&pd, "product", ":", value), 1);
	      if (datadir)
	        repo_set_str(repo, s - pool->solvables, SUSETAGS_DATADIR, datadir);
	      if (descrdir)
	        repo_set_str(repo, s - pool->solvables, SUSETAGS_DESCRDIR, descrdir);
	      if (defvendor)
		s->vendor = str2id(pool, defvendor, 1);
	      continue;
	    }

	  /* Sometimes PRODUCT/NAME is not the first entry, but we need a solvable
	     from here on.  */
	  if (!s)
	    {
	      s = pool_id2solvable(pool, repo_add_solvable(repo));
	      repodata_extend(data, s - pool->solvables);
	      handle = s - pool->solvables;
	    }

	  if (istag ("VERSION"))
            pd.tmpvers = strdup(value);
          else if (istag ("RELEASE"))
            pd.tmprel = strdup(value);
	  else if (code11 && istag ("DISTRIBUTION"))
	    repo_set_str(repo, s - pool->solvables, SOLVABLE_DISTRIBUTION, value);
	  else if (istag ("UPDATEURLS"))
	    add_multiple_urls(data, handle, value, str2id(pool, "update", 1));
	  else if (istag ("EXTRAURLS"))
	    add_multiple_urls(data, handle, value, str2id(pool, "extra", 1));
	  else if (istag ("OPTIONALURLS"))
	    add_multiple_urls(data, handle, value, str2id(pool, "optional", 1));
	  else if (istag ("RELNOTESURL"))
	    add_multiple_urls(data, handle, value, str2id(pool, "releasenotes", 1));
	  else if (istag ("SHORTLABEL"))
	    repo_set_str(repo, s - pool->solvables, PRODUCT_SHORTLABEL, value);
	  else if (istag ("LABEL")) /* LABEL is the products SUMMARY. */
	    repo_set_str(repo, s - pool->solvables, SOLVABLE_SUMMARY, value);
	  else if (!strncmp (key, "LABEL.", 6))
	    repo_set_str(repo, s - pool->solvables, pool_id2langid(pool, SOLVABLE_SUMMARY, key + 6, 1), value);
	  else if (istag ("FLAGS"))
	    add_multiple_strings(data, handle, PRODUCT_FLAGS, value);
	  else if (istag ("VENDOR"))	/* actually already handled above */
	    s->vendor = str2id(pool, value, 1);
          else if (istag ("BASEARCHS"))
            {
              char *arch;

	      if ((arch = splitword(&value)) != 0)
		{
		  s->arch = str2id(pool, arch, 1);
		  while ((arch = splitword(&value)) != 0)
		    {
		       otherarchs = sat_extend(otherarchs, numotherarchs, 1, sizeof(Id), 7);
		       otherarchs[numotherarchs++] = str2id(pool, arch, 1);
		    }
		}
            }

	  /*
	   * Every tag below is Code10 only
	   *
	   */

	  if (code10 && istag ("DISTPRODUCT"))
	    /* DISTPRODUCT is for registration and Yast, not for the solver. */
	    repo_set_str(repo, s - pool->solvables, PRODUCT_DISTPRODUCT, value);
	  else if (code10 && istag ("DISTVERSION"))
	    /* DISTVERSION is for registration and Yast, not for the solver. */
	    repo_set_str(repo, s - pool->solvables, PRODUCT_DISTVERSION, value);
	  else if (code10 && istag ("ARCH"))
	    /* Theoretically we want to have the best arch of the given
	       modifiers which still is compatible with the system
	       arch.  We don't know the latter here, though.  */
	    s->arch = ARCH_NOARCH;
	  else if (code10 && istag ("PREREQUIRES"))
	    s->requires = adddep(pool, &pd, s->requires, value, SOLVABLE_PREREQMARKER);
	  else if (code10 && istag ("REQUIRES"))
	    s->requires = adddep(pool, &pd, s->requires, value, -SOLVABLE_PREREQMARKER);
	  else if (code10 && istag ("PROVIDES"))
	    s->provides = adddep(pool, &pd, s->provides, value, 0);
	  else if (code10 && istag ("CONFLICTS"))
	    s->conflicts = adddep(pool, &pd, s->conflicts, value, 0);
	  else if (code10 && istag ("OBSOLETES"))
	    s->obsoletes = adddep(pool, &pd, s->obsoletes, value, 0);
	  else if (code10 && istag ("RECOMMENDS"))
	    s->recommends = adddep(pool, &pd, s->recommends, value, 0);
	  else if (code10 && istag ("SUGGESTS"))
	    s->suggests = adddep(pool, &pd, s->suggests, value, 0);
	  else if (code10 && istag ("SUPPLEMENTS"))
	    s->supplements = adddep(pool, &pd, s->supplements, value, 0);
	  else if (code10 && istag ("ENHANCES"))
	    s->enhances = adddep(pool, &pd, s->enhances, value, 0);
	  /* FRESHENS doesn't seem to exist.  */
	  else if (code10 && istag ("TYPE"))
	    repo_set_str(repo, s - pool->solvables, PRODUCT_TYPE, value);

	  /* XXX do something about LINGUAS and ARCH?
          * <ma>: Don't think so. zypp does not use or propagate them.
          */
#undef istag
	}
      else
	pool_debug(pool, SAT_ERROR, "repo_content: malformed line: %s\n", line);
    }

  if (datadir)
    free(datadir);
  if (descrdir)
    free(descrdir);
  if (defvendor)
    free(defvendor);

  if (s)
    {
      if (!s->name)
	{
	  pool_debug(pool, SAT_FATAL, "repo_content: 'content' incomplete, no product solvable created!\n");
	  exit(1);
	}

      if (pd.tmprel)
	s->evr = makeevr(pool, join(&pd, pd.tmpvers, "-", pd.tmprel));
      else
	s->evr = makeevr(pool, pd.tmpvers);
      pd.tmpvers = sat_free((void *)pd.tmpvers);
      pd.tmprel = sat_free((void *)pd.tmprel);

      if (!s->arch)
	s->arch = ARCH_NOARCH;
      if (!s->evr)
	s->evr = ID_EMPTY;
      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);
      if (code10)
	s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);

      /* now for every other arch, clone the product except the architecture */
      for (i = 0; i < numotherarchs; ++i)
	{
	  Solvable *p = pool_id2solvable(pool, repo_add_solvable(repo));
	  repodata_extend(data, p - pool->solvables);
	  p->name = s->name;
	  p->evr = s->evr;
	  p->vendor = s->vendor;
	  p->arch = otherarchs[i];

	  /* self provides */
	  if (s->name && p->arch != ARCH_SRC && p->arch != ARCH_NOSRC)
	      p->provides = repo_addid_dep(repo, p->provides, rel2id(pool, p->name, p->evr, REL_EQ, 1), 0);

	  /* now merge the attributes */
	  repodata_merge_attrs(data, p - pool->solvables, s - pool->solvables);
	}
    }

  if (pd.tmp)
    sat_free(pd.tmp);
  sat_free(line);
  sat_free(otherarchs);
  join_freemem();
  if (!(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
}
예제 #9
0
void
repo_add_code11_products(Repo *repo, const char *dirpath, int flags)
{
  Repodata *data;
  struct parsedata pd;
  struct stateswitch *sw;
  DIR *dir;
  int i;

  data = repo_add_repodata(repo, flags);

  memset(&pd, 0, sizeof(pd));
  pd.repo = repo;
  pd.pool = repo->pool;
  pd.data = data;

  pd.content = sat_malloc(256);
  pd.acontent = 256;

  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;
    }

  dir = opendir(dirpath);
  if (dir)
    {
      struct dirent *entry;
      struct stat st;
      char *fullpath;

      /* check for <productsdir>/baseproduct on code11 and remember its target inode */
      if (stat(join2(dirpath, "/", "baseproduct"), &st) == 0) /* follow symlink */
	pd.baseproduct = st.st_ino;
      else
	pd.baseproduct = 0;

      while ((entry = readdir(dir)))
	{
	  int len = strlen(entry->d_name);
	  if (len <= 5 || strcmp(entry->d_name + len - 5, ".prod") != 0)
	    continue;
	  fullpath = join2(dirpath, "/", entry->d_name);
	  FILE *fp = fopen(fullpath, "r");
	  if (!fp)
	    {
	      perror(fullpath);
	      continue;
	    }
	  pd.filename = fullpath;
	  pd.basename = entry->d_name;
	  add_code11_product(&pd, fp);
	  fclose(fp);
	}
      closedir(dir);
    }
  sat_free((void *)pd.tmplang);
  sat_free(pd.content);
  join_freemem();

  if (!(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
}
예제 #10
0
static void XMLCALL
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);
#endif
  if (pd->depth != pd->statedepth)
    {
      pd->depth--;
#if 0
      fprintf(stderr, "back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth);
#endif
      return;
    }

  pd->depth--;
  pd->statedepth--;

  switch (pd->state)
    {
    case STATE_PRODUCT:
      /* product done, finish solvable */
      if (pd->ctime)
        repodata_set_num(pd->data, pd->handle, SOLVABLE_INSTALLTIME, pd->ctime);

      if (pd->basename)
        repodata_set_str(pd->data, pd->handle, PRODUCT_REFERENCEFILE, pd->basename);

      /* 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->evr)
	s->evr = ID_EMPTY;
      if (s->name && 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:
      s->vendor = str2id(pd->pool, pd->content, 1);
      break;
    case STATE_NAME:
      s->name = str2id(pd->pool, join2("product", ":", pd->content), 1);
      break;
    case STATE_VERSION:
      pd->tmpvers = strdup(pd->content);
      break;
    case STATE_RELEASE:
      pd->tmprel = strdup(pd->content);
      break;
    case STATE_ARCH:
      s->arch = str2id(pd->pool, pd->content, 1);
      break;
    case STATE_PRODUCTLINE:
      repodata_set_str(pd->data, pd->handle, PRODUCT_PRODUCTLINE, pd->content);
    break;
    case STATE_UPDATEREPOKEY:
      /** obsolete **/
      break;
    case STATE_SUMMARY:
      repodata_set_str(pd->data, pd->handle, langtag(pd, SOLVABLE_SUMMARY, pd->tmplang), pd->content);
      pd->tmplang = sat_free((void *)pd->tmplang);
      break;
    case STATE_SHORTSUMMARY:
      repodata_set_str(pd->data, pd->handle, PRODUCT_SHORTLABEL, pd->content);
      break;
    case STATE_DESCRIPTION:
      repodata_set_str(pd->data, pd->handle, langtag(pd, SOLVABLE_DESCRIPTION, pd->tmplang), pd->content );
      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);
      break;
    case STATE_REGRELEASE:
      repodata_set_str(pd->data, pd->handle, PRODUCT_REGISTER_RELEASE, pd->content);
      break;
    case STATE_CPEID:
      if (pd->content)
        repodata_set_str(pd->data, pd->handle, SOLVABLE_CPEID, pd->content);
    default:
      break;
    }

  pd->state = pd->sbtab[pd->state];
  pd->docontent = 0;

#if 0
      fprintf(stderr, "end: [%s] -> %d\n", name, pd->state);
#endif
}