Track files per package and add command to list them.
authorKristian H?gsberg <krh@redhat.com>
Wed Oct 24 00:05:42 2007 -0400 (2007-10-24)
changeset 569c00581c71be
parent 55 b21a4953ff91
child 57 016c61ca11e2
Track files per package and add command to list them.
TODO
bash-completion.sh
main.c
razor.c
razor.h
     1.1 --- a/TODO	Wed Oct 24 00:02:44 2007 -0400
     1.2 +++ b/TODO	Wed Oct 24 00:05:42 2007 -0400
     1.3 @@ -47,3 +47,9 @@
     1.4  
     1.5  - split out hash table code from importer, make the merger use just
     1.6    the hash table.
     1.7 +
     1.8 +- try to clean up the
     1.9 +
    1.10 +	do { ... } while (((e++)->name & RAZOR_ENTRY_LAST) == 0);
    1.11 +
    1.12 +  idiom for iteration of directories.
     2.1 --- a/bash-completion.sh	Wed Oct 24 00:02:44 2007 -0400
     2.2 +++ b/bash-completion.sh	Wed Oct 24 00:05:42 2007 -0400
     2.3 @@ -1,6 +1,6 @@
     2.4  __razor_commands () {
     2.5      local IFS=$'\n'
     2.6 -    COMPREPLY=($(IFS=: compgen -S' ' -W "list-requires:list-provides:list-files:list-file-packages:what-requires:what-provides:import-yum:import-rpmdb:validate:update:diff" -- $1))
     2.7 +    COMPREPLY=($(IFS=: compgen -S' ' -W "list-requires:list-provides:list-files:list-file-packages:list-package-files:what-requires:what-provides:import-yum:import-rpmdb:validate:update:diff" -- $1))
     2.8  }
     2.9  
    2.10  __razor_packages () {
    2.11 @@ -28,7 +28,8 @@
    2.12  	__razor_commands $cur
    2.13      else
    2.14  	case "${COMP_WORDS[1]}" in
    2.15 -	    list-requires|list-provides) __razor_packages $cur ;;
    2.16 +	    list-requires|list-provides|list-package-files)
    2.17 +		__razor_packages $cur ;;
    2.18  	    list-files|list-file-packages) __razor_files $cur ;;
    2.19  	    what-requires) __razor_requires $cur ;;
    2.20  	    what-provides) __razor_provides $cur ;;
     3.1 --- a/main.c	Wed Oct 24 00:02:44 2007 -0400
     3.2 +++ b/main.c	Wed Oct 24 00:05:42 2007 -0400
     3.3 @@ -74,6 +74,19 @@
     3.4  	return 0;
     3.5  }
     3.6  
     3.7 +static int
     3.8 +command_list_package_files(int argc, const char *argv[])
     3.9 +{
    3.10 +	struct razor_set *set;
    3.11 +
    3.12 +	set = razor_set_open(repo_filename);
    3.13 +	if (set == NULL)
    3.14 +		return 1;
    3.15 +	razor_set_list_package_files(set, argv[0]);
    3.16 +	razor_set_destroy(set);
    3.17 +
    3.18 +	return 0;
    3.19 +}
    3.20  
    3.21  static int
    3.22  command_what_requires(int argc, const char *argv[])
    3.23 @@ -199,6 +212,7 @@
    3.24  	{ "list-provides", "list all provides or provides for the give package", command_list_provides },
    3.25  	{ "list-files", "list files for package set", command_list_files },
    3.26  	{ "list-file-packages", "list packages owning file", command_list_file_packages },
    3.27 +	{ "list-package-files", "list files in package", command_list_package_files },
    3.28  	{ "what-requires", "list the packages that have the given requires", command_what_requires },
    3.29  	{ "what-provides", "list the packages that have the given provides", command_what_provides },
    3.30  	{ "import-yum", "import yum filelist.xml on stdin", command_import_yum },
     4.1 --- a/razor.c	Wed Oct 24 00:02:44 2007 -0400
     4.2 +++ b/razor.c	Wed Oct 24 00:05:42 2007 -0400
     4.3 @@ -35,20 +35,22 @@
     4.4  #define RAZOR_MAGIC 0x7a7a7a7a
     4.5  #define RAZOR_VERSION 1
     4.6  
     4.7 -#define RAZOR_PACKAGES 0
     4.8 -#define RAZOR_REQUIRES 1
     4.9 -#define RAZOR_PROVIDES 2
    4.10 -#define RAZOR_STRING_POOL 3
    4.11 -#define RAZOR_PACKAGE_POOL 4
    4.12 -#define RAZOR_REQUIRES_POOL 5
    4.13 -#define RAZOR_PROVIDES_POOL 6
    4.14 -#define RAZOR_FILE_TREE 7
    4.15 +#define RAZOR_STRING_POOL 0
    4.16 +#define RAZOR_PACKAGES 1
    4.17 +#define RAZOR_REQUIRES 2
    4.18 +#define RAZOR_PROVIDES 3
    4.19 +#define RAZOR_FILES 4
    4.20 +#define RAZOR_PACKAGE_POOL 5
    4.21 +#define RAZOR_REQUIRES_POOL 6
    4.22 +#define RAZOR_PROVIDES_POOL 7
    4.23 +#define RAZOR_FILE_POOL 8
    4.24  
    4.25  struct razor_package {
    4.26  	unsigned long name;
    4.27  	unsigned long version;
    4.28  	unsigned long requires;
    4.29  	unsigned long provides;
    4.30 +	unsigned long files;
    4.31  };
    4.32  
    4.33  struct razor_property {
    4.34 @@ -59,7 +61,6 @@
    4.35  
    4.36  struct razor_entry {
    4.37  	unsigned long name;
    4.38 -	unsigned long count;
    4.39  	unsigned long start;
    4.40  	unsigned long packages;
    4.41  };
    4.42 @@ -67,12 +68,13 @@
    4.43  struct razor_set {
    4.44  	struct array string_pool;
    4.45   	struct array packages;
    4.46 -	struct array package_pool;
    4.47   	struct array requires;
    4.48   	struct array provides;
    4.49 + 	struct array files;
    4.50 +	struct array package_pool;
    4.51   	struct array requires_pool;
    4.52   	struct array provides_pool;
    4.53 - 	struct array file_tree;
    4.54 + 	struct array file_pool;
    4.55  	struct razor_set_header *header;
    4.56  };
    4.57  
    4.58 @@ -170,14 +172,15 @@
    4.59  }
    4.60  
    4.61  struct razor_set_section razor_sections[] = {
    4.62 +	{ RAZOR_STRING_POOL,	offsetof(struct razor_set, string_pool) },
    4.63  	{ RAZOR_PACKAGES,	offsetof(struct razor_set, packages) },
    4.64  	{ RAZOR_REQUIRES,	offsetof(struct razor_set, requires) },
    4.65  	{ RAZOR_PROVIDES,	offsetof(struct razor_set, provides) },
    4.66 -	{ RAZOR_STRING_POOL,	offsetof(struct razor_set, string_pool) },
    4.67 +	{ RAZOR_FILES,		offsetof(struct razor_set, files) },
    4.68  	{ RAZOR_PACKAGE_POOL,	offsetof(struct razor_set, package_pool) },
    4.69  	{ RAZOR_REQUIRES_POOL,	offsetof(struct razor_set, requires_pool) },
    4.70  	{ RAZOR_PROVIDES_POOL,	offsetof(struct razor_set, provides_pool) },
    4.71 -	{ RAZOR_FILE_TREE,	offsetof(struct razor_set, file_tree) },
    4.72 +	{ RAZOR_FILE_POOL,	offsetof(struct razor_set, file_pool) },
    4.73  };
    4.74  
    4.75  struct razor_set *
    4.76 @@ -737,12 +740,15 @@
    4.77  	}		
    4.78  }
    4.79  
    4.80 +#define RAZOR_ENTRY_LAST 0x80000000ul
    4.81 +#define RAZOR_ENTRY_MASK 0x00fffffful
    4.82 +
    4.83  static void
    4.84  serialize_files(struct razor_set *set,
    4.85  		struct import_directory *d, struct array *array)
    4.86  {
    4.87  	struct import_directory *p, *end;
    4.88 -	struct razor_entry *e;
    4.89 +	struct razor_entry *e = NULL;
    4.90  	unsigned long s;
    4.91  
    4.92  	p = d->files.data;
    4.93 @@ -751,14 +757,15 @@
    4.94  	while (p < end) {
    4.95  		e = array_add(array, sizeof *e);
    4.96  		e->name = p->name;
    4.97 -		e->count = p->files.size / sizeof *p;
    4.98 -		e->start = s;
    4.99 +		e->start = p->count > 0 ? s : 0;
   4.100  		s += p->count;
   4.101  		e->packages = add_to_property_pool(&set->package_pool,
   4.102  						   &p->packages);
   4.103  		array_release(&p->packages);
   4.104  		p++;
   4.105  	}		
   4.106 +	if (e != NULL)
   4.107 +		e->name |= RAZOR_ENTRY_LAST;
   4.108  
   4.109  	p = d->files.data;
   4.110  	end = d->files.data + d->files.size;
   4.111 @@ -823,108 +830,48 @@
   4.112  	}
   4.113  
   4.114  	count_entries(&root);
   4.115 -	array_init(&importer->set->file_tree);
   4.116 +	array_init(&importer->set->files);
   4.117  
   4.118 -	e = array_add(&importer->set->file_tree, sizeof *e);
   4.119 -	e->name = root.name;
   4.120 -	e->count = root.files.size / sizeof *d;
   4.121 +	e = array_add(&importer->set->files, sizeof *e);
   4.122 +	e->name = root.name | RAZOR_ENTRY_LAST;
   4.123  	e->start = 1;
   4.124 +	e->packages = 0;
   4.125  
   4.126 -	serialize_files(importer->set, &root, &importer->set->file_tree);
   4.127 +	serialize_files(importer->set, &root, &importer->set->files);
   4.128  
   4.129  	array_release(&importer->files);
   4.130  }
   4.131  
   4.132 -static const char *
   4.133 -find_dir(struct razor_set *set, struct razor_entry **dir, const char *pattern)
   4.134 +static void
   4.135 +build_package_file_lists(struct razor_set *set)
   4.136  {
   4.137 +	struct razor_package *p, *packages;
   4.138 +	struct array *pkgs;
   4.139  	struct razor_entry *e, *end;
   4.140 -	const char *n, *pool = set->string_pool.data;
   4.141 -	int len;
   4.142 +	unsigned long *r, *q;
   4.143 +	int i, count;
   4.144  
   4.145 -	e = (struct razor_entry *) set->file_tree.data + (*dir)->start;
   4.146 -	end = e + (*dir)->count;
   4.147 +	count = set->packages.size / sizeof *p;
   4.148 +	pkgs = zalloc(count * sizeof *pkgs);
   4.149  
   4.150 +	e = set->files.data;
   4.151 +	end = set->files.data + set->files.size;
   4.152  	while (e < end) {
   4.153 -		n = pool + e->name;
   4.154 -		len = strlen(n);
   4.155 -		if (len == 0) {
   4.156 -			/* FIXME: Shouldn't have 0-length entries... */
   4.157 -			e++;
   4.158 -			continue;
   4.159 -		}
   4.160 -			
   4.161 -		if (strncmp(pattern + 1, n, len) == 0 &&
   4.162 -		    pattern[len + 1] == '/') {
   4.163 -			*dir = e;
   4.164 -			return find_dir(set, dir, pattern + len + 1);
   4.165 +		r = (unsigned long *) set->package_pool.data + e->packages;
   4.166 +		while (~*r) {
   4.167 +			q = array_add(&pkgs[*r++], sizeof *q);
   4.168 +			*q = e - (struct razor_entry *) set->files.data;
   4.169  		}
   4.170  		e++;
   4.171  	}
   4.172  
   4.173 -	return pattern + 1;
   4.174 -}
   4.175 -
   4.176 -static void
   4.177 -list_dir(struct razor_set *set, struct razor_entry *dir,
   4.178 -	 const char *pattern, const char *base)
   4.179 -{
   4.180 -	struct razor_entry *e, *end;
   4.181 -	char *pool = set->string_pool.data;
   4.182 -
   4.183 -	e = (struct razor_entry *) set->file_tree.data + dir->start;
   4.184 -	end = e + dir->count;
   4.185 -
   4.186 -	for ( ; e < end; e++) {
   4.187 -		if (base && base[0] && fnmatch(base, &pool[e->name], 0) != 0)
   4.188 -			continue;
   4.189 -		if (base && pattern)
   4.190 -			printf("%.*s%s%s\n",
   4.191 -			       base - pattern, pattern, pool + e->name,
   4.192 -			       e->count > 0 ? "/" : "");
   4.193 -		else
   4.194 -			printf("%s%s\n", pool + e->name,
   4.195 -			       e->count > 0 ? "/" : "");
   4.196 -		
   4.197 +	packages = set->packages.data;
   4.198 +	for (i = 0; i < count; i++) {
   4.199 +		packages[i].files =
   4.200 +			add_to_property_pool(&set->file_pool, &pkgs[i]);
   4.201 +		array_release(&pkgs[i]);
   4.202  	}
   4.203 -}
   4.204 -
   4.205 -void
   4.206 -razor_set_list_files(struct razor_set *set, const char *pattern)
   4.207 -{
   4.208 -	struct razor_entry *e;
   4.209 -	const char *base;
   4.210 -
   4.211 -	if (pattern == NULL)
   4.212 -		pattern = "/";
   4.213 -
   4.214 -	e = set->file_tree.data;
   4.215 -	base = find_dir(set, &e, pattern);
   4.216 -	if (base == NULL)
   4.217 -		return;
   4.218 -	list_dir(set, e, pattern, base);
   4.219 -}
   4.220 -
   4.221 -void
   4.222 -razor_set_list_file_packages(struct razor_set *set, const char *filename)
   4.223 -{
   4.224 -	struct razor_entry *e;
   4.225 -	struct razor_package *packages, *p;
   4.226 -	const char *pool, *base;
   4.227 -	unsigned long *r;
   4.228 -
   4.229 -	e = set->file_tree.data;
   4.230 -	base = find_dir(set, &e, filename);
   4.231 -	if (base == NULL)
   4.232 -		return;
   4.233 -	
   4.234 -	r = (unsigned long *) set->package_pool.data + e->packages;
   4.235 -	packages = set->packages.data;
   4.236 -	pool = set->string_pool.data;
   4.237 -	while (~*r) {
   4.238 -		p = &packages[*r++];
   4.239 -		printf("%s %s\n", &pool[p->name], &pool[p->version]);
   4.240 -	}
   4.241 +	free(pkgs);
   4.242  }
   4.243  
   4.244  struct razor_set *
   4.245 @@ -958,6 +905,8 @@
   4.246  	remap_links(&importer->set->package_pool, rmap);
   4.247  	free(rmap);
   4.248  
   4.249 +	build_package_file_lists(importer->set);
   4.250 +
   4.251  	set = importer->set;
   4.252  	array_release(&importer->buckets);
   4.253  	free(importer);
   4.254 @@ -1141,6 +1090,167 @@
   4.255  	razor_set_list_property_packages(set, &set->provides, name, version);
   4.256  }
   4.257  
   4.258 +static struct razor_entry *
   4.259 +find_entry(struct razor_set *set, struct razor_entry *dir, const char *pattern)
   4.260 +{
   4.261 +	struct razor_entry *e;
   4.262 +	const char *n, *pool = set->string_pool.data;
   4.263 +	int len;
   4.264 +
   4.265 +	e = (struct razor_entry *) set->files.data + dir->start;
   4.266 +	do {
   4.267 +		n = pool + (e->name & RAZOR_ENTRY_MASK);
   4.268 +		len = strlen(n);
   4.269 +		if (len == 0)
   4.270 +			/* FIXME: Shouldn't have 0-length entries... */
   4.271 +			continue;
   4.272 +			
   4.273 +		if (strcmp(pattern + 1, n) == 0)
   4.274 +			return e;
   4.275 +		if (e->start != 0 && strncmp(pattern + 1, n, len) == 0 &&
   4.276 +		    pattern[len + 1] == '/') {
   4.277 +			return find_entry(set, e, pattern + len + 1);
   4.278 +		}
   4.279 +	} while (((e++)->name & RAZOR_ENTRY_LAST) == 0);
   4.280 +
   4.281 +	return NULL;
   4.282 +}
   4.283 +
   4.284 +static void
   4.285 +list_dir(struct razor_set *set, struct razor_entry *dir,
   4.286 +	 const char *prefix, const char *pattern)
   4.287 +{
   4.288 +	struct razor_entry *e;
   4.289 +	const char *n, *pool = set->string_pool.data;
   4.290 +
   4.291 +	e = (struct razor_entry *) set->files.data + dir->start;
   4.292 +	do {
   4.293 +		n = pool + (e->name & RAZOR_ENTRY_MASK);
   4.294 +		if (pattern && pattern[0] && fnmatch(pattern, n, 0) != 0)
   4.295 +			continue;
   4.296 +		printf("%s/%s%s\n", prefix, n, e->start > 0 ? "/" : "");
   4.297 +	} while (((e++)->name & RAZOR_ENTRY_LAST) == 0);
   4.298 +}
   4.299 +
   4.300 +void
   4.301 +razor_set_list_files(struct razor_set *set, const char *pattern)
   4.302 +{
   4.303 +	struct razor_entry *e;
   4.304 +	char buffer[512], *p, *base;
   4.305 +
   4.306 +	if (pattern == NULL)
   4.307 +		pattern = "/";
   4.308 +
   4.309 +	strcpy(buffer, pattern);
   4.310 +	e = find_entry(set, set->files.data, buffer);
   4.311 +	if (e && e->start > 0) {
   4.312 +		base = NULL;
   4.313 +	} else {
   4.314 +		p = strrchr(buffer, '/');
   4.315 +		if (p) {
   4.316 +			*p = '\0';
   4.317 +			base = p + 1;
   4.318 +		} else {
   4.319 +			base = NULL;
   4.320 +		}
   4.321 +	}
   4.322 +	e = find_entry(set, set->files.data, buffer);
   4.323 +	if (e->start != 0)
   4.324 +		list_dir(set, e, buffer, base);
   4.325 +}
   4.326 +
   4.327 +void
   4.328 +razor_set_list_file_packages(struct razor_set *set, const char *filename)
   4.329 +{
   4.330 +	struct razor_entry *e;
   4.331 +	struct razor_package *packages, *p;
   4.332 +	const char *pool;
   4.333 +	unsigned long *r;
   4.334 +
   4.335 +	e = find_entry(set, set->files.data, filename);
   4.336 +	if (e == NULL)
   4.337 +		return;
   4.338 +	
   4.339 +	r = (unsigned long *) set->package_pool.data + e->packages;
   4.340 +	packages = set->packages.data;
   4.341 +	pool = set->string_pool.data;
   4.342 +	while (~*r) {
   4.343 +		p = &packages[*r++];
   4.344 +		printf("%s %s\n", &pool[p->name], &pool[p->version]);
   4.345 +	}
   4.346 +}
   4.347 +
   4.348 +static unsigned long *
   4.349 +list_package_files(struct razor_set *set, unsigned long *r,
   4.350 +		   struct razor_entry *dir, unsigned long end,
   4.351 +		   char *prefix)
   4.352 +{
   4.353 +	struct razor_entry *e, *f, *entries;
   4.354 +	unsigned long next;
   4.355 +	char *pool;
   4.356 +	int len;
   4.357 +	
   4.358 +	entries = (struct razor_entry *) set->files.data;
   4.359 +	pool = set->string_pool.data;
   4.360 +
   4.361 +	e = entries + dir->start;
   4.362 +	do {
   4.363 +		if (entries + *r == e) {
   4.364 +			printf("%s/%s\n", prefix,
   4.365 +			       pool + (e->name & RAZOR_ENTRY_MASK));
   4.366 +			r++;
   4.367 +			if (*r >= end)
   4.368 +				break;
   4.369 +		}
   4.370 +	} while (((e++)->name & RAZOR_ENTRY_LAST) == 0);
   4.371 +
   4.372 +	e = entries + dir->start;
   4.373 +	do {
   4.374 +		if (e->start == 0)
   4.375 +			continue;
   4.376 +
   4.377 +		if (e->name & RAZOR_ENTRY_LAST)
   4.378 +			next = end;
   4.379 +		else {
   4.380 +			f = e + 1; 
   4.381 +			while (f->start == 0 && !(f->name & RAZOR_ENTRY_LAST))
   4.382 +				f++;
   4.383 +			if (f->start == 0)
   4.384 +				next = end;
   4.385 +			else
   4.386 +				next = f->start;
   4.387 +		}
   4.388 +
   4.389 +		if (e->start <= *r && *r < next) {
   4.390 +			len = strlen(prefix);
   4.391 +			prefix[len] = '/';
   4.392 +			strcpy(prefix + len + 1,
   4.393 +			       pool + (e->name & RAZOR_ENTRY_MASK));
   4.394 +			r = list_package_files(set, r, e, next, prefix);
   4.395 +			prefix[len] = '\0';
   4.396 +			if (*r >= end)
   4.397 +				break;
   4.398 +		}
   4.399 +	} while (((e++)->name & RAZOR_ENTRY_LAST) == 0);
   4.400 +
   4.401 +	return r;
   4.402 +}
   4.403 +
   4.404 +void
   4.405 +razor_set_list_package_files(struct razor_set *set, const char *name)
   4.406 +{
   4.407 +	struct razor_package *package;
   4.408 +	unsigned long *r, end;
   4.409 +	char buffer[512];
   4.410 +
   4.411 +	package = razor_set_get_package(set, name);
   4.412 +
   4.413 +	r = (unsigned long *) set->file_pool.data + package->files;
   4.414 +	end = set->files.size / sizeof (struct razor_entry);
   4.415 +	buffer[0] = '\0';
   4.416 +	list_package_files(set, r, set->files.data, end, buffer);
   4.417 +}
   4.418 +
   4.419  static void
   4.420  razor_set_validate(struct razor_set *set, struct array *unsatisfied)
   4.421  {
     5.1 --- a/razor.h	Wed Oct 24 00:02:44 2007 -0400
     5.2 +++ b/razor.h	Wed Oct 24 00:05:42 2007 -0400
     5.3 @@ -20,6 +20,7 @@
     5.4  				      const char *version);
     5.5  void razor_set_list_files(struct razor_set *set, const char *prefix);
     5.6  void razor_set_list_file_packages(struct razor_set *set, const char *filename);
     5.7 +void razor_set_list_package_files(struct razor_set *set, const char *name);
     5.8  
     5.9  void razor_set_list_unsatisfied(struct razor_set *set);
    5.10  struct razor_set *razor_set_update(struct razor_set *set,