X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=tools%2Fcommon_write.c;h=577b1aba564154b19506902ba92b6f45c6984d3d;hb=refs%2Fchanges%2F89%2F194389%2F1;hp=9673faae97c51886fbab3b760524a17c02da4c02;hpb=c49cb71a693d3201080c11a558ca74af3d345403;p=platform%2Fupstream%2Flibsolv.git diff --git a/tools/common_write.c b/tools/common_write.c index 9673faa..577b1ab 100644 --- a/tools/common_write.c +++ b/tools/common_write.c @@ -6,8 +6,6 @@ */ #include -#include -#include #include #include #include @@ -16,89 +14,329 @@ #include "repo.h" #include "repo_write.h" #include "common_write.h" +#include "solvversion.h" -static char *verticals[] = { - "authors", - "description", - "messagedel", - "messageins", - "eula", - "diskusage", - "filelist", +/* toolversion history + * 1.0: initial tool version + * 1.1: changed PRODUCT_ENDOFLIFE parsing +*/ + +static Id verticals[] = { + SOLVABLE_AUTHORS, + SOLVABLE_DESCRIPTION, + SOLVABLE_MESSAGEDEL, + SOLVABLE_MESSAGEINS, + SOLVABLE_EULA, + SOLVABLE_DISKUSAGE, + SOLVABLE_FILELIST, + SOLVABLE_CHANGELOG_AUTHOR, + SOLVABLE_CHANGELOG_TEXT, 0 }; -static unsigned char *filter; -static int nfilter; - -static void -create_filter(Pool *pool) -{ - char **s; - Id id; - for (s = verticals; *s; s++) - { - id = str2id(pool, *s, 1); - if (id >= nfilter) - { - filter = sat_realloc(filter, id + 16); - memset(filter + nfilter, 0, id + 16 - nfilter); - nfilter = id + 16; - } - filter[id] = 1; - } -} +static char *languagetags[] = { + "solvable:summary:", + "solvable:description:", + "solvable:messageins:", + "solvable:messagedel:", + "solvable:eula:", + 0 +}; static int test_separate = 0; +struct keyfilter_data { + char **languages; + int nlanguages; + int haveaddedfileprovides; + int haveexternal; +}; + static int keyfilter_solv(Repo *data, Repokey *key, void *kfdata) { + struct keyfilter_data *kd = kfdata; + int i; + const char *keyname; + if (test_separate && key->storage != KEY_STORAGE_SOLVABLE) return KEY_STORAGE_DROPPED; - if (key->name < nfilter && filter[key->name]) - return KEY_STORAGE_VERTICAL_OFFSET; + if (!kd->haveaddedfileprovides && key->name == REPOSITORY_ADDEDFILEPROVIDES) + return KEY_STORAGE_DROPPED; + if (!kd->haveexternal && key->name == REPOSITORY_EXTERNAL) + return KEY_STORAGE_DROPPED; + if (key->name == SUSETAGS_SHARE_NAME || key->name == SUSETAGS_SHARE_EVR || key->name == SUSETAGS_SHARE_ARCH) + return KEY_STORAGE_DROPPED; + for (i = 0; verticals[i]; i++) + if (key->name == verticals[i]) + return KEY_STORAGE_VERTICAL_OFFSET; + keyname = pool_id2str(data->pool, key->name); + for (i = 0; languagetags[i] != 0; i++) + if (!strncmp(keyname, languagetags[i], strlen(languagetags[i]))) + return KEY_STORAGE_VERTICAL_OFFSET; return KEY_STORAGE_INCORE; } static int keyfilter_attr(Repo *data, Repokey *key, void *kfdata) { + int i; + const char *keyname; if (key->storage == KEY_STORAGE_SOLVABLE) return KEY_STORAGE_DROPPED; - if (key->name < nfilter && filter[key->name]) - return KEY_STORAGE_VERTICAL_OFFSET; + /* those must only be in the main solv file */ + if (key->name == REPOSITORY_EXTERNAL || key->name == REPOSITORY_ADDEDFILEPROVIDES || key->name == REPOSITORY_TOOLVERSION) + return KEY_STORAGE_DROPPED; + for (i = 0; verticals[i]; i++) + if (key->name == verticals[i]) + return KEY_STORAGE_VERTICAL_OFFSET; + keyname = pool_id2str(data->pool, key->name); + for (i = 0; languagetags[i] != 0; i++) + if (!strncmp(keyname, languagetags[i], strlen(languagetags[i]))) + return KEY_STORAGE_VERTICAL_OFFSET; + return KEY_STORAGE_INCORE; +} + +static int +keyfilter_language(Repo *repo, Repokey *key, void *kfdata) +{ + Pool *pool = repo->pool; + const char *name, *p; + char *lang = kfdata; + int i; + + name = pool_id2str(repo->pool, key->name); + p = strrchr(name, ':'); + if (!p || strcmp(p + 1, lang) != 0) + return KEY_STORAGE_DROPPED; + for (i = 0; verticals[i]; i++) + { + const char *vname = pool_id2str(pool, verticals[i]); + if (!strncmp(name, vname, p - name) && vname[p - name] == 0) + return KEY_STORAGE_VERTICAL_OFFSET; + } + return KEY_STORAGE_INCORE; +} + +static int +keyfilter_DU(Repo *repo, Repokey *key, void *kfdata) +{ + int i; + if (key->name != SOLVABLE_DISKUSAGE) + return KEY_STORAGE_DROPPED; + for (i = 0; verticals[i]; i++) + if (key->name == verticals[i]) + return KEY_STORAGE_VERTICAL_OFFSET; + return KEY_STORAGE_INCORE; +} + +static int +keyfilter_FL(Repo *repo, Repokey *key, void *kfdata) +{ + int i; + if (key->name != SOLVABLE_FILELIST) + return KEY_STORAGE_DROPPED; + for (i = 0; verticals[i]; i++) + if (key->name == verticals[i]) + return KEY_STORAGE_VERTICAL_OFFSET; + return KEY_STORAGE_INCORE; +} + +static int +keyfilter_other(Repo *repo, Repokey *key, void *kfdata) +{ + const char *name, *p; + struct keyfilter_data *kd = kfdata; + int i; + + if (!kd->haveaddedfileprovides && key->name == REPOSITORY_ADDEDFILEPROVIDES) + return KEY_STORAGE_DROPPED; + if (!kd->haveexternal && key->name == REPOSITORY_EXTERNAL) + return KEY_STORAGE_DROPPED; + + if (key->name == SOLVABLE_FILELIST || key->name == SOLVABLE_DISKUSAGE) + return KEY_STORAGE_DROPPED; + + name = pool_id2str(repo->pool, key->name); + p = strrchr(name, ':'); + if (p) + { + for (i = 0; i < kd->nlanguages; i++) + if (!strcmp(p + 1, kd->languages[i])) + return KEY_STORAGE_DROPPED; + } + for (i = 0; verticals[i]; i++) + if (key->name == verticals[i]) + return KEY_STORAGE_VERTICAL_OFFSET; return KEY_STORAGE_INCORE; } /* * Write to stdout * If is given, write attributes to + * If is given, split attributes */ -int +#define REPODATAFILE_BLOCK 15 + +static void +write_info(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata, Repodata *info, const char *location) +{ + Id h; + Queue keyq; + + queue_init(&keyq); + if (repo_write_filtered(repo, fp, keyfilter, kfdata, &keyq) != 0) + { + fprintf(stderr, "repo_write failed\n"); + exit(1); + } + h = repodata_new_handle(info); + if (keyq.count) + repodata_set_idarray(info, h, REPOSITORY_KEYS, &keyq); + queue_free(&keyq); + repodata_set_str(info, h, REPOSITORY_LOCATION, location); + repodata_add_flexarray(info, SOLVID_META, REPOSITORY_EXTERNAL, h); +} + +void tool_write(Repo *repo, const char *basename, const char *attrname) { - Pool *pool = repo->pool; - Repodatafile fileinfoa[1]; - Repodatafile *fileinfo = 0; - int nsubfiles = 0; + Repodata *data; + Repodata *info = 0; + Repokey *key; + char **languages = 0; + int nlanguages = 0; + int i, j, k, l; + struct keyfilter_data kd; + Queue addedfileprovides; - create_filter(pool); - memset (fileinfoa, 0, sizeof fileinfoa); + memset(&kd, 0, sizeof(kd)); + info = repo_add_repodata(repo, 0); + repodata_set_str(info, SOLVID_META, REPOSITORY_TOOLVERSION, LIBSOLV_TOOLVERSION); + queue_init(&addedfileprovides); + pool_addfileprovides_queue(repo->pool, &addedfileprovides, 0); + if (addedfileprovides.count) + { + kd.haveaddedfileprovides = 1; + repodata_set_idarray(info, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, &addedfileprovides); + } + queue_free(&addedfileprovides); + + pool_freeidhashes(repo->pool); /* free some mem */ + + if (basename) + { + char fn[4096]; + FILE *fp; + int has_DU = 0; + int has_FL = 0; + + /* find languages and other info */ + FOR_REPODATAS(repo, i, data) + { + for (j = 1, key = data->keys + j; j < data->nkeys; j++, key++) + { + const char *keyname = pool_id2str(repo->pool, key->name); + if (key->name == SOLVABLE_DISKUSAGE) + has_DU = 1; + if (key->name == SOLVABLE_FILELIST) + has_FL = 1; + for (k = 0; languagetags[k] != 0; k++) + if (!strncmp(keyname, languagetags[k], strlen(languagetags[k]))) + break; + if (!languagetags[k]) + continue; + l = strlen(languagetags[k]); + if (strlen(keyname + l) > 5) + continue; + for (k = 0; k < nlanguages; k++) + if (!strcmp(languages[k], keyname + l)) + break; + if (k < nlanguages) + continue; + languages = solv_realloc2(languages, nlanguages + 1, sizeof(char *)); + languages[nlanguages++] = strdup(keyname + l); + } + } + /* write language subfiles */ + for (i = 0; i < nlanguages; i++) + { + sprintf(fn, "%s.%s.solv", basename, languages[i]); + if (!(fp = fopen(fn, "w"))) + { + perror(fn); + exit(1); + } + write_info(repo, fp, keyfilter_language, languages[i], info, fn); + fclose(fp); + kd.haveexternal = 1; + } + /* write DU subfile */ + if (has_DU) + { + sprintf(fn, "%s.DU.solv", basename); + if (!(fp = fopen(fn, "w"))) + { + perror(fn); + exit(1); + } + write_info(repo, fp, keyfilter_DU, 0, info, fn); + fclose(fp); + kd.haveexternal = 1; + } + /* write filelist */ + if (has_FL) + { + sprintf(fn, "%s.FL.solv", basename); + if (!(fp = fopen(fn, "w"))) + { + perror(fn); + exit(1); + } + write_info(repo, fp, keyfilter_FL, 0, info, fn); + fclose(fp); + kd.haveexternal = 1; + } + /* write everything else */ + sprintf(fn, "%s.solv", basename); + if (!(fp = fopen(fn, "w"))) + { + perror(fn); + exit(1); + } + kd.languages = languages; + kd.nlanguages = nlanguages; + repodata_internalize(info); + if (repo_write_filtered(repo, fp, keyfilter_other, &kd, 0) != 0) + { + fprintf(stderr, "repo_write failed\n"); + exit(1); + } + if (fclose(fp) != 0) + { + perror("fclose"); + exit(1); + } + for (i = 0; i < nlanguages; i++) + free(languages[i]); + solv_free(languages); + repodata_free(info); + } if (attrname) { + FILE *fp; test_separate = 1; - fileinfo = fileinfoa; - FILE *fp = fopen (attrname, "w"); - repo_write(repo, fp, keyfilter_attr, 0, fileinfo, 0); - fclose (fp); - fileinfo->location = strdup (attrname); - fileinfo++; - - nsubfiles = fileinfo - fileinfoa; - fileinfo = fileinfoa; + fp = fopen(attrname, "w"); + write_info(repo, fp, keyfilter_attr, 0, info, attrname); + fclose(fp); + kd.haveexternal = 1; + } + repodata_internalize(info); + if (repo_write_filtered(repo, stdout, keyfilter_solv, &kd, 0) != 0) + { + fprintf(stderr, "repo_write failed\n"); + exit(1); } - repo_write(repo, stdout, keyfilter_solv, 0, fileinfo, nsubfiles); - return 0; + repodata_free(info); }