aboutsummaryrefslogtreecommitdiffstats
path: root/gendepslist2.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gendepslist2.cc')
-rw-r--r--gendepslist2.cc413
1 files changed, 0 insertions, 413 deletions
diff --git a/gendepslist2.cc b/gendepslist2.cc
deleted file mode 100644
index 3b71259..0000000
--- a/gendepslist2.cc
+++ /dev/null
@@ -1,413 +0,0 @@
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <rpm/rpmlib.h>
-#include <rpm/header.h>
-#include <string>
-#include <vector>
-#include <map>
-#include <set>
-#include <fstream>
-#include <algorithm>
-
-#define COMPATIBILITY
-
-
-/********************************************************************************/
-/* C++ template functions *******************************************************/
-/********************************************************************************/
-template<class V, class C> C sum(const V &v, const C &join = C()) {
- typename V::const_iterator p, q;
- C s = C();
- if (v.begin() != v.end()) {
- for (p = q = v.begin(), q++; q != v.end(); p = q, q++) s += *p + join;
- s += *p;
- }
- return s;
-}
-
-vector<string> split(char sep, const string &l) {
- vector<string> r;
- for (int pos = 0, pos2 = 0; pos2 >= 0;) {
- pos2 = l.find(sep, pos);
- r.push_back(l.substr(pos, pos2 - pos));
- pos = pos2 + 1;
- }
- return r;
-}
-
-template<class A, class B> void map_insert(map<A, set<B> > &m, const A &a, const B &b) {
- if (m.find(a) == m.end()) m[a] = *(new set<B>);
- m[a].insert(b);
-}
-
-template<class A> bool in(const A &a, const vector<A> &v) {
- vector<A>::const_iterator p;
- for (p = v.begin(); p != v.end(); p++) if (*p == a) return 1;
- return 0;
-}
-template<class A> bool in(const A &a, const set<A> &m) {
- return m.find(a) != m.end();
-}
-template<class A, class B> bool in(const A &a, const map<A,B> &m) {
- return m.find(a) != m.end();
-}
-
-template<class A, class B> map<A,B> &set2map(const set<A> &s) {
- map<A,B> map;
- set<A>::const_iterator p;
- for (p = s.begin(); p != s.end(); p++) map[*p] = *(new B);
- return map;
-}
-
-template<class A, class B> void add(set<A> &v1, const B &v2) {
- typename B::const_iterator p;
- for (p = v2.begin(); p != v2.end(); p++) v1.insert(*p);
-}
-template<class A, class B> void add(vector<A> &v1, const B &v2) {
- typename B::const_iterator p;
- for (p = v2.begin(); p != v2.end(); p++) v1.push_back(*p);
-}
-
-typedef vector<string>::iterator ITv;
-typedef set<string>::iterator ITs;
-typedef map<string, set<string> >::iterator ITms;
-
-bool start_with(const string &s, const char *prefix) {
- return strncmp(s.c_str(), prefix, strlen(prefix)) == 0;
-}
-
-
-
-/********************************************************************************/
-/* header extracting functions **************************************************/
-/********************************************************************************/
-string get_name(Header header, int_32 tag) {
- int_32 type, count;
- char *name;
-
- headerGetEntry(header, tag, &type, (void **) &name, &count);
- return string(name);
-}
-
-int get_int(Header header, int_32 tag) {
- int_32 type, count;
- int *i;
-
- headerGetEntry(header, tag, &type, (void **) &i, &count);
- return *i;
-}
-
-vector<string> get_info(Header header, int_32 tag) {
- int_32 type, count, i;
- vector<string> r;
- char **list;
-
- headerGetEntry(header, tag, &type, (void **) &list, &count);
- if (list) {
- r.reserve(count);
- for (i = 0; i < count; i++) r.push_back(list[i]);
- free(list);
- }
- return r;
-}
-
-vector<string> get_files(Header header) {
- int_32 type, count, i;
- char ** baseNames, ** dirNames;
- int_32 * dirIndexes;
-
-#ifdef COMPATIBILITY
- // deprecated one
- vector<string> r = get_info(header, RPMTAG_OLDFILENAMES);
-#else
- vector<string> r;
-#endif
-
- headerGetEntry(header, RPMTAG_BASENAMES, &type, (void **) &baseNames, &count);
- headerGetEntry(header, RPMTAG_DIRINDEXES, &type, (void **) &dirIndexes, NULL);
- headerGetEntry(header, RPMTAG_DIRNAMES, &type, (void **) &dirNames, NULL);
-
- if (baseNames && dirNames && dirIndexes) {
- r.reserve(count);
- for(i = 0; i < count; i++) {
- string s(dirNames[dirIndexes[i]]);
- s += baseNames[i];
- r.push_back(s);
- }
- free(baseNames);
- free(dirNames);
- }
- return r;
-}
-
-/********************************************************************************/
-/* gendepslist ******************************************************************/
-/********************************************************************************/
-int nb_hdlists;
-vector<string> packages;
-map<string, int> sizes;
-map<int, set<string> > hdlist2names;
-map<string, string> name2fullname;
-map<string, vector<string> > requires, frequires;
-map<string, vector<string> > provided_by, fprovided_by;
-
-void getRequires(FD_t fd, int current_hdlist) {
- set<string> all_requires, all_frequires;
- Header header;
-
- while ((header=headerRead(fd, HEADER_MAGIC_YES)))
- {
- string s_name = get_name(header, RPMTAG_NAME);
- string name = s_name + "-" + get_name(header, RPMTAG_VERSION) + "-" + get_name(header, RPMTAG_RELEASE);
- vector<string> l = get_info(header, RPMTAG_REQUIRENAME);
- if (in(s_name, name2fullname)) continue;
- packages.push_back(name);
- name2fullname[s_name] = name;
- hdlist2names[current_hdlist].insert(name);
- sizes[name] = get_int(header, RPMTAG_SIZE);
-
- for (ITv p = l.begin(); p != l.end(); p++) {
- if (!start_with(*p, "rpmlib(")) {
- ((*p)[0] == '/' ? frequires : requires)[name].push_back(*p);
- ((*p)[0] == '/' ? all_frequires : all_requires).insert(*p);
- }
- }
- headerFree(header);
- }
- for (ITs p = all_requires.begin(); p != all_requires.end(); p++) provided_by[*p] = *(new vector<string>);
- for (ITs p = all_frequires.begin(); p != all_frequires.end(); p++) fprovided_by[*p] = *(new vector<string>);
-}
-
-void getProvides(FD_t fd, int current_hdlist) {
- map<string,bool> used;
- Header header;
- while ((header=headerRead(fd, HEADER_MAGIC_YES)))
- {
- string s_name = get_name(header, RPMTAG_NAME);
- string name = s_name + "-" + get_name(header, RPMTAG_VERSION) + "-" + get_name(header, RPMTAG_RELEASE);
- if (in(s_name, used)) continue;
- used[s_name] = true;
-
- if (in(s_name, provided_by)) provided_by[s_name].push_back(name);
-
- vector<string> provides = get_info(header, RPMTAG_PROVIDES);
- for (ITv p = provides.begin(); p != provides.end(); p++)
- if (in(*p, provided_by)) provided_by[*p].push_back(name);
-
- vector<string> fprovides = get_files(header);
- for (ITv p = fprovides.begin(); p != fprovides.end(); p++)
- if (in(*p, fprovided_by)) fprovided_by[*p].push_back(name);
-
- headerFree(header);
- }
-}
-
-set<string> getDep_(const string &dep, vector<string> &l) {
- set<string> r;
- switch (l.size())
- {
- case 0:
- r.insert((string) "NOTFOUND_" + dep);
- break;
- case 1:
- r.insert(l[0]);
- break;
- default:
- r.insert(sum(l, (string)"|"));
- }
- return r;
-}
-
-set<string> getDep(const string &name) {
- set<string> r;
- r.insert(name);
- for (ITv p = requires[name].begin(); p != requires[name].end(); p++) add(r, getDep_(*p, provided_by[*p]));
- for (ITv p = frequires[name].begin(); p != frequires[name].end(); p++) add(r, getDep_(*p, fprovided_by[*p]));
- return r;
-}
-
-map<string, set<string> > closure(const map<string, set<string> > &names) {
- map<string, set<string> > r = names;
-
- map<string, set<string> > reverse;
- for (ITv i = packages.begin(); i != packages.end(); i++) reverse[*i] = *(new set<string>);
-
- for (ITms i = r.begin(); i != r.end(); i++)
- for (ITs j = i->second.begin(); j != i->second.end(); j++)
- reverse[*j].insert(i->first);
-
- for (ITms i = r.begin(); i != r.end(); i++) {
- set<string> rev = reverse[i->first];
- for (ITs j = rev.begin(); j != rev.end(); j++) {
-
- for (ITs k = i->second.begin(); k != i->second.end(); k++) {
- r[*j].insert(*k);
- reverse[*k].insert(*j);
- }
-
- }
- }
- return r;
-}
-
-
-//struct cmp : public binary_function<string,string,bool> {
-// bool operator()(const string &a, const string &b) {
-// int na = closed[a].size();
-// int nb = closed[b].size();
-// return na < nb;
-// }
-//};
-
-inline int verif(int npack, int ndep, const string &package, const string &dep) {
- if (ndep > npack && !(ndep == 0 && npack == -1)) cerr << package << " requires " << dep << " which is not in the same hdlist " << ndep << " > " << npack << "\n";
- return ndep;
-}
-
-void printDepslist(ofstream *out1, ofstream *out2) {
-
- map<string, set<string> > names;
- for (ITv p = packages.begin(); p != packages.end(); p++) {
- set<string> s = getDep(*p);
- s.erase(*p);
- names[*p] = s;
- if (out1) *out1 << *p << " " << sizes[*p] << " " << sum(s, (string) " ") << "\n";
- }
- if (out2 == 0) return;
-
- map<string, set<string> > closed = closure(names);
- for (ITms p = closed.begin(); p != closed.end(); p++) p->second.erase(p->first);
- names = closed;
-
- vector<string> packages;
- set<string> list = hdlist2names[0];
- int nb2hdlist[2 * names.size()]; // the 2x is a hacky hack. nb_names is not enough, need a little more
- int i = 0;
- string n;
-
- map<string,int> nb_deps_done;
- for (ITms p = names.begin(); p != names.end(); p++) nb_deps_done[p->first] = 0;
-
-
-
- for (int i = -1, nb = 0; i < nb_hdlists; i++, nb++) {
- set<string> list;
-
- if (i == -1) {
- list.insert(name2fullname["filesystem"]); nb_deps_done[name2fullname["filesystem"]] = 10;
- list.insert(name2fullname["setup"]); nb_deps_done[name2fullname["setup"]] = 10;
- add(list, names[name2fullname["basesystem"]]);
- list.insert(name2fullname["basesystem"]);
-
- for (ITs p = list.begin(); p != list.end(); p++) {
- if (p->find('|') != string::npos) {
- list.erase(*p);
- }
- }
- for (ITs p = list.begin(); p != list.end(); p++) {
- hdlist2names[0].erase(*p);
- }
- } else {
- list = hdlist2names[i];
- }
- while (list.begin() != list.end()) {
- int l_best = 9999;
-
- for (ITs p = list.begin(); p != list.end(); p++) {
- if (start_with(*p, "NOTFOUND_")) {
- list.erase(*p);
- continue;
- }
- int lo = names[*p].size() - nb_deps_done[*p];
- if (lo < l_best) {
- l_best = lo;
- n = *p;
- if (l_best == -1) break;
- }
- }
- names.erase(n);
- list.erase(n);
- nb2hdlist[nb++] = i;
- packages.push_back(n);
- for (ITms p = names.begin(); p != names.end(); p++) p->second.erase(n);
- }
- }
- cerr << "ordering done\n";
-
- i = 0;
- map<string,int> where;
- for (ITv p = packages.begin(); p != packages.end(); p++, i++) where[*p] = i;
-
- i = 0;
- for (ITv p = packages.begin(); p != packages.end(); p++, i++) {
- set<string> dep = closed[*p];
- *out2 << *p << " " << sizes[*p];
- for (ITs q = dep.begin(); q != dep.end(); q++) {
- if (q->find('|') != string::npos) {
- vector<string> l = split('|', *q);
-
- int skip = 0;
- for (ITv k = l.begin(); k != l.end(); k++) if (*p == *k) { skip = 1; break; }
- if (skip) continue;
-
- *out2 << " ";
- int previous = 0;
- for (ITv k = l.begin(); k != l.end(); k++) {
- if (previous) *out2 << "|";
- previous = 1;
-
- verif(nb2hdlist[i], nb2hdlist[where[*k]], *p, *k);
- *out2 << where[*k];
- }
- } else if (start_with(*q, "NOTFOUND_")) {
- *out2 << " " << *q;
- } else {
- verif(nb2hdlist[i], nb2hdlist[where[*q]], *p, *q);
- *out2 << " " << where[*q];
- }
- }
- *out2 << "\n";
- }
-}
-
-void hdlists(void (*f)(FD_t, int), const char *file, int current_hdlist) {
- bool isfile = strlen(file) > 4 && strncmp(file + strlen(file) - 4, ".rpm", 4) == 0;
- string cmd = isfile ? "rpm2header " : "packdrake -c ";
- FILE *pipe = popen((cmd + file + " 2>/dev/null").c_str(), "r");
-
- f(fdDup(fileno(pipe)), current_hdlist);
-
- if (pclose(pipe) != 0) {
- cerr << "bad hdlist " << file << "\n";
- exit(1);
- }
-}
-
-int main(int argc, char **argv)
-{
- ofstream *out1 = 0, *out2 = 0;
- if (argc > 2 && (string)argv[1] == "-o") {
- out1 = new ofstream(argv[2]);
- out2 = new ofstream(((string)argv[2] + ".ordered").c_str());
- argc -= 2; argv += 2;
- } else {
- out1 = new ofstream(STDOUT_FILENO);
- }
- if (argc < 2) {
- cerr << "usage: gendepslist2 [-o <depslist>] hdlists_cz2...\n";
- return 1;
- }
-
- nb_hdlists = argc - 1;
-
- for (int i = 1; i < argc; i++) if ((string)argv[i] == "--") break; else hdlists(getRequires, argv[i], i - 1);
- cerr << "getRequires done\n";
-
- for (int i = 1; i < argc; i++) if ((string)argv[i] == "--") continue; else hdlists(getProvides, argv[i], i - 1);
- cerr << "getProvides done\n";
-
- printDepslist(out1, out2);
- delete out1;
- delete out2;
-}