Add a file tree section to the package set structure.
authorKristian H?gsberg <krh@redhat.com>
Sun Oct 21 21:57:22 2007 -0400 (2007-10-21)
changeset 48458b03594baf
parent 47 b3c8d19f743e
child 49 c66fd9a1eabe
Add a file tree section to the package set structure.
import.c
main.c
razor.c
razor.h
     1.1 --- a/import.c	Sun Oct 21 21:42:31 2007 -0400
     1.2 +++ b/import.c	Sun Oct 21 21:57:22 2007 -0400
     1.3 @@ -163,7 +163,7 @@
     1.4  struct yum_context {
     1.5  	struct razor_importer *importer;
     1.6  	struct import_property_context *current_property_context;
     1.7 -	char *name;
     1.8 +	char name[256], buffer[512], *p;
     1.9  	int state;
    1.10  };
    1.11  
    1.12 @@ -176,6 +176,7 @@
    1.13  
    1.14  	if (strcmp(name, "name") == 0) {
    1.15  		ctx->state = YUM_STATE_PACKAGE_NAME;
    1.16 +		ctx->p = ctx->name;
    1.17  	} else if (strcmp(name, "version") == 0) {
    1.18  		version = NULL;
    1.19  		for (i = 0; atts[i]; i += 2) {
    1.20 @@ -214,6 +215,7 @@
    1.21  		}
    1.22  	} else if (strcmp(name, "file") == 0) {
    1.23  		ctx->state = YUM_STATE_FILE;
    1.24 +		ctx->p = ctx->buffer;
    1.25  	}
    1.26  }
    1.27  
    1.28 @@ -223,23 +225,24 @@
    1.29  	struct yum_context *ctx = data;
    1.30  
    1.31  	ctx->state = YUM_STATE_BEGIN;
    1.32 -	if (strcmp(name, "package") == 0) {
    1.33 -		free(ctx->name);
    1.34 +	if (strcmp(name, "package") == 0)
    1.35  		razor_importer_finish_package(ctx->importer);
    1.36 -	}
    1.37 +	else if (strcmp(name, "file") == 0)
    1.38 +		razor_importer_add_file(ctx->importer, ctx->buffer);
    1.39  }
    1.40  
    1.41  static void
    1.42  yum_character_data (void *data, const XML_Char *s, int len)
    1.43  {
    1.44  	struct yum_context *ctx = data;
    1.45 -	char filename[PATH_MAX];
    1.46  
    1.47 -	if (ctx->state == YUM_STATE_PACKAGE_NAME)
    1.48 -		ctx->name = strndup(s, len);
    1.49 -	else if (ctx->state == YUM_STATE_FILE) {
    1.50 -		snprintf(filename, sizeof filename, "%.*s", len, s);
    1.51 -		razor_importer_add_file(ctx->importer, filename);
    1.52 +	switch (ctx->state) {
    1.53 +	case YUM_STATE_PACKAGE_NAME:
    1.54 +	case YUM_STATE_FILE:
    1.55 +		memcpy(ctx->p, s, len);
    1.56 +		ctx->p += len;
    1.57 +		*ctx->p = '\0';
    1.58 +		break;
    1.59  	}
    1.60  }
    1.61  
     2.1 --- a/main.c	Sun Oct 21 21:42:31 2007 -0400
     2.2 +++ b/main.c	Sun Oct 21 21:57:22 2007 -0400
     2.3 @@ -47,6 +47,20 @@
     2.4  }
     2.5  
     2.6  static int
     2.7 +command_list_files(int argc, const char *argv[])
     2.8 +{
     2.9 +	struct razor_set *set;
    2.10 +
    2.11 +	set = razor_set_open(repo_filename);
    2.12 +	if (set == NULL)
    2.13 +		return 1;
    2.14 +	razor_set_list_files(set);
    2.15 +	razor_set_destroy(set);
    2.16 +
    2.17 +	return 0;
    2.18 +}
    2.19 +
    2.20 +static int
    2.21  command_what_requires(int argc, const char *argv[])
    2.22  {
    2.23  	struct razor_set *set;
    2.24 @@ -168,6 +182,7 @@
    2.25  	{ "list", "list all packages", command_list },
    2.26  	{ "list-requires", "list all requires or requires for the given package", command_list_requires },
    2.27  	{ "list-provides", "list all provides or provides for the give package", command_list_provides },
    2.28 +	{ "list-files", "list files for package set", command_list_files },
    2.29  	{ "what-requires", "list the packages that have the given requires", command_what_requires },
    2.30  	{ "what-provides", "list the packages that have the given provides", command_what_provides },
    2.31  	{ "import-yum", "import yum filelist.xml on stdin", command_import_yum },
     3.1 --- a/razor.c	Sun Oct 21 21:42:31 2007 -0400
     3.2 +++ b/razor.c	Sun Oct 21 21:57:22 2007 -0400
     3.3 @@ -41,6 +41,7 @@
     3.4  #define RAZOR_PACKAGE_POOL 4
     3.5  #define RAZOR_REQUIRES_POOL 5
     3.6  #define RAZOR_PROVIDES_POOL 6
     3.7 +#define RAZOR_FILE_TREE 7
     3.8  
     3.9  struct razor_package {
    3.10  	unsigned long name;
    3.11 @@ -55,6 +56,12 @@
    3.12  	unsigned long packages;
    3.13  };
    3.14  
    3.15 +struct razor_entry {
    3.16 +	unsigned long name;
    3.17 +	unsigned long count;
    3.18 +	unsigned long start;
    3.19 +};
    3.20 +
    3.21  struct razor_set {
    3.22  	struct array string_pool;
    3.23   	struct array packages;
    3.24 @@ -63,6 +70,7 @@
    3.25   	struct array provides;
    3.26   	struct array requires_pool;
    3.27   	struct array provides_pool;
    3.28 + 	struct array file_tree;
    3.29  	struct razor_set_header *header;
    3.30  };
    3.31  
    3.32 @@ -77,6 +85,7 @@
    3.33  	struct import_property_context requires;
    3.34  	struct import_property_context provides;
    3.35  	struct razor_package *package;
    3.36 +	struct array files;
    3.37  };
    3.38  
    3.39  static void
    3.40 @@ -154,6 +163,7 @@
    3.41  	{ RAZOR_PACKAGE_POOL,	offsetof(struct razor_set, package_pool) },
    3.42  	{ RAZOR_REQUIRES_POOL,	offsetof(struct razor_set, requires_pool) },
    3.43  	{ RAZOR_PROVIDES_POOL,	offsetof(struct razor_set, provides_pool) },
    3.44 +	{ RAZOR_FILE_TREE,	offsetof(struct razor_set, file_tree) },
    3.45  };
    3.46  
    3.47  struct razor_set *
    3.48 @@ -453,6 +463,10 @@
    3.49  void
    3.50  razor_importer_add_file(struct razor_importer *importer, const char *name)
    3.51  {
    3.52 +	char **p;
    3.53 +
    3.54 +	p = array_add(&importer->files, sizeof *p);
    3.55 +	*p = strdup(name);
    3.56  }
    3.57  
    3.58  struct razor_importer *
    3.59 @@ -682,6 +696,147 @@
    3.60  			*p = map[*p];
    3.61  }
    3.62  
    3.63 +static int
    3.64 +compare_filenames(const void *p1, const void *p2, void *data)
    3.65 +{
    3.66 +	char *f1 = *(char **) p1;
    3.67 +	char *f2 = *(char **) p2;
    3.68 +
    3.69 +	return strcmp(f1, f2);
    3.70 +}
    3.71 +
    3.72 +struct directory {
    3.73 +	unsigned long name, count;
    3.74 +	struct array files;
    3.75 +	struct directory *last;
    3.76 +};
    3.77 +
    3.78 +static void
    3.79 +count_entries(struct directory *d)
    3.80 +{
    3.81 +	struct directory *p, *end;
    3.82 +
    3.83 +	p = d->files.data;
    3.84 +	end = d->files.data + d->files.size;
    3.85 +	d->count = 0;
    3.86 +	while (p < end) {
    3.87 +		count_entries(p);
    3.88 +		d->count += p->count + 1;
    3.89 +		p++;
    3.90 +	}		
    3.91 +}
    3.92 +
    3.93 +static void
    3.94 +serialize_files(struct directory *d, struct array *array)
    3.95 +{
    3.96 +	struct directory *p, *end;
    3.97 +	struct razor_entry *e;
    3.98 +	unsigned long s;
    3.99 +
   3.100 +	p = d->files.data;
   3.101 +	end = d->files.data + d->files.size;
   3.102 +	s = array->size / sizeof *e + d->files.size / sizeof *p;
   3.103 +	while (p < end) {
   3.104 +		e = array_add(array, sizeof *e);
   3.105 +		e->name = p->name;
   3.106 +		e->count = p->files.size / sizeof *p;
   3.107 +		e->start = s;
   3.108 +		s += p->count;
   3.109 +		p++;
   3.110 +	}		
   3.111 +
   3.112 +	p = d->files.data;
   3.113 +	end = d->files.data + d->files.size;
   3.114 +	while (p < end) {
   3.115 +		serialize_files(p, array);
   3.116 +		p++;
   3.117 +	}
   3.118 +}
   3.119 +
   3.120 +static void
   3.121 +build_file_tree(struct razor_importer *importer)
   3.122 +{
   3.123 +	int count, i, length;
   3.124 +	char **filenames, *f, *end;
   3.125 +	unsigned long name;
   3.126 +	char dirname[256];
   3.127 +	struct directory *d, root;
   3.128 +	struct razor_entry *e;
   3.129 +
   3.130 +	count = importer->files.size / sizeof (char *);
   3.131 +	qsort_with_data(importer->files.data,
   3.132 +			count,
   3.133 +			sizeof (char *),
   3.134 +			compare_filenames,
   3.135 +			NULL);
   3.136 +
   3.137 +	root.name = razor_importer_tokenize(importer, "");
   3.138 +	array_init(&root.files);
   3.139 +	root.last = NULL;
   3.140 +
   3.141 +	filenames = importer->files.data;
   3.142 +	for (i = 0; i < count; i++) {
   3.143 +		f = filenames[i];
   3.144 +		if (*f != '/')
   3.145 +			continue;
   3.146 +
   3.147 +		d = &root;
   3.148 +		while (*f) {
   3.149 +			end = strchr(f + 1, '/');
   3.150 +			if (end == NULL)
   3.151 +				end = f + strlen(f);
   3.152 +			length = end - (f + 1);
   3.153 +			memcpy(dirname, f + 1, length);
   3.154 +			dirname[length] ='\0';
   3.155 +			name = razor_importer_tokenize(importer, dirname);
   3.156 +			if (d->last == NULL || d->last->name != name) {
   3.157 +				d->last = array_add(&d->files, sizeof *d);
   3.158 +				d->last->name = name;
   3.159 +				d->last->last = NULL;
   3.160 +				array_init(&d->last->files);
   3.161 +			}
   3.162 +			d = d->last;				
   3.163 +			f = end;
   3.164 +		}
   3.165 +
   3.166 +		free(filenames[i]);
   3.167 +	}
   3.168 +
   3.169 +	count_entries(&root);
   3.170 +	array_init(&importer->set->file_tree);
   3.171 +
   3.172 +	e = array_add(&importer->set->file_tree, sizeof *e);
   3.173 +	e->name = root.name;
   3.174 +	e->count = root.files.size / sizeof *d;
   3.175 +	e->start = 1;
   3.176 +
   3.177 +	serialize_files(&root, &importer->set->file_tree);
   3.178 +
   3.179 +	array_release(&importer->files);
   3.180 +}
   3.181 +
   3.182 +static void
   3.183 +list_dir(struct razor_set *set, struct razor_entry *e, int indent)
   3.184 +{
   3.185 +	struct razor_entry *c;
   3.186 +	char *pool = set->string_pool.data;
   3.187 +	int i;
   3.188 +
   3.189 +	for (i = 0; i < indent; i++)
   3.190 +		putchar(' ');
   3.191 +	printf("%s\n", pool + e->name);
   3.192 +	for (i = 0; i < e->count; i++) {
   3.193 +		c = (struct razor_entry *) set->file_tree.data + e->start + i;
   3.194 +		list_dir(set, c, indent + 2);
   3.195 +	}
   3.196 +}
   3.197 +
   3.198 +void
   3.199 +razor_set_list_files(struct razor_set *set)
   3.200 +{
   3.201 +	list_dir(set, set->file_tree.data, 2);
   3.202 +}
   3.203 +
   3.204  struct razor_set *
   3.205  razor_importer_finish(struct razor_importer *importer)
   3.206  {
   3.207 @@ -712,6 +867,8 @@
   3.208  	free(map);
   3.209  	free(rmap);
   3.210  
   3.211 +	build_file_tree(importer);
   3.212 +
   3.213  	set = importer->set;
   3.214  	array_release(&importer->buckets);
   3.215  	free(importer);
     4.1 --- a/razor.h	Sun Oct 21 21:42:31 2007 -0400
     4.2 +++ b/razor.h	Sun Oct 21 21:57:22 2007 -0400
     4.3 @@ -18,6 +18,7 @@
     4.4  void razor_set_list_provides_packages(struct razor_set *set,
     4.5  				      const char *name,
     4.6  				      const char *version);
     4.7 +void razor_set_list_files(struct razor_set *set);
     4.8  
     4.9  void razor_set_list_unsatisfied(struct razor_set *set);
    4.10  struct razor_set *razor_set_update(struct razor_set *set,