razor.c
changeset 7 235f7daf817c
parent 6 4eeed5fbe6b7
child 8 7820b7d94662
     1.1 --- a/razor.c	Tue Sep 04 23:52:59 2007 -0400
     1.2 +++ b/razor.c	Wed Sep 05 00:32:09 2007 -0400
     1.3 @@ -95,16 +95,23 @@
     1.4  #define RAZOR_BUCKETS 1
     1.5  #define RAZOR_STRINGS 2
     1.6  #define RAZOR_PACKAGES 3
     1.7 +#define RAZOR_PROVIDES 4
     1.8  
     1.9  struct razor_package {
    1.10  	unsigned long name;
    1.11  	unsigned long version;
    1.12  };
    1.13  
    1.14 +struct razor_provides {
    1.15 +	unsigned long name;
    1.16 +	unsigned long version;
    1.17 +};
    1.18 +
    1.19  struct razor_set {
    1.20  	struct array buckets;
    1.21  	struct array string_pool;
    1.22 -	struct array packages;
    1.23 + 	struct array packages;
    1.24 + 	struct array provides;
    1.25  	struct razor_set_header *header;
    1.26  };
    1.27  
    1.28 @@ -159,6 +166,11 @@
    1.29  			set->packages.size = size;
    1.30  			set->packages.size = size;
    1.31  			break;
    1.32 +		case RAZOR_PROVIDES:
    1.33 +			set->provides.data = (void *) set->header + offset;
    1.34 +			set->provides.size = size;
    1.35 +			set->provides.size = size;
    1.36 +			break;
    1.37  		}
    1.38  	}
    1.39  	close(fd);
    1.40 @@ -191,11 +203,12 @@
    1.41  {
    1.42  	char data[4096];
    1.43  	struct razor_set_header *header = (struct razor_set_header *) data;
    1.44 -	int fd, pool_size, packages_size;
    1.45 +	int fd, pool_size, packages_size, provides_size;
    1.46  
    1.47  	/* Align these to pages sizes */
    1.48  	pool_size = (set->string_pool.size + 4095) & ~4095;
    1.49  	packages_size = (set->packages.size + 4095) & ~4095;
    1.50 +	provides_size = (set->provides.size + 4095) & ~4095;
    1.51  
    1.52  	memset(data, 0, sizeof data);
    1.53  	header->magic = RAZOR_MAGIC;
    1.54 @@ -212,10 +225,14 @@
    1.55  	header->sections[2].offset =
    1.56  		header->sections[1].offset + pool_size;
    1.57  
    1.58 -	header->sections[3].type = 0;
    1.59 +	header->sections[3].type = RAZOR_PROVIDES;
    1.60  	header->sections[3].offset =
    1.61  		header->sections[2].offset + packages_size;
    1.62  
    1.63 +	header->sections[4].type = 0;
    1.64 +	header->sections[4].offset =
    1.65 +		header->sections[3].offset + provides_size;
    1.66 +
    1.67  	fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
    1.68  	if (fd < 0)
    1.69  		return -1;
    1.70 @@ -224,6 +241,7 @@
    1.71  	write_to_fd(fd, set->buckets.data, set->buckets.alloc);
    1.72  	write_to_fd(fd, set->string_pool.data, pool_size);
    1.73  	write_to_fd(fd, set->packages.data, packages_size);
    1.74 +	write_to_fd(fd, set->provides.data, provides_size);
    1.75  
    1.76  	return 0;
    1.77  }
    1.78 @@ -337,6 +355,20 @@
    1.79  	return p - (struct razor_package *) set->packages.data;
    1.80  }
    1.81  
    1.82 +static unsigned long
    1.83 +razor_set_add_provides(struct razor_set *set,
    1.84 +		       unsigned long name, unsigned long version)
    1.85 +{
    1.86 +	struct razor_provides *p;
    1.87 +
    1.88 +	p = array_add(&set->provides, sizeof *p);
    1.89 +
    1.90 +	p->name = name;
    1.91 +	p->version = version;
    1.92 +
    1.93 +	return p - (struct razor_provides *) set->packages.data;
    1.94 +}
    1.95 +
    1.96  unsigned long
    1.97  razor_set_tokenize(struct razor_set *set, const char *string)
    1.98  {
    1.99 @@ -360,6 +392,15 @@
   1.100  	return strcmp(&pool[pkg1->name], &pool[pkg2->name]);
   1.101  }
   1.102  
   1.103 +static int
   1.104 +compare_provides(const void *p1, const void *p2)
   1.105 +{
   1.106 +	const struct razor_provides *prv1 = p1, *prv2 = p2;
   1.107 +	char *pool = qsort_set->string_pool.data;
   1.108 +
   1.109 +	return strcmp(&pool[prv1->name], &pool[prv2->name]);
   1.110 +}
   1.111 +
   1.112  static void
   1.113  razor_set_sort(struct razor_set *set)
   1.114  {
   1.115 @@ -367,6 +408,9 @@
   1.116  	qsort(set->packages.data,
   1.117  	      set->packages.size / sizeof(struct razor_package),
   1.118  	      sizeof(struct razor_package), compare_packages);
   1.119 +	qsort(set->provides.data,
   1.120 +	      set->provides.size / sizeof(struct razor_provides),
   1.121 +	      sizeof(struct razor_provides), compare_provides);
   1.122  }
   1.123  
   1.124  struct parsing_context {
   1.125 @@ -377,7 +421,7 @@
   1.126  static void
   1.127  parse_package(struct parsing_context *ctx, const char **atts)
   1.128  {
   1.129 -	unsigned long name, version;
   1.130 +	unsigned long name = 0, version = 0;
   1.131  	int i;
   1.132  
   1.133  	for (i = 0; atts[i]; i += 2) {
   1.134 @@ -399,6 +443,26 @@
   1.135  }
   1.136  
   1.137  static void
   1.138 +parse_provides(struct parsing_context *ctx, const char **atts)
   1.139 +{
   1.140 +	unsigned long name = 0, version = 0;
   1.141 +	int i;
   1.142 +
   1.143 +	for (i = 0; atts[i]; i += 2) {
   1.144 +		if (strcmp(atts[i], "name") == 0)
   1.145 +			name = razor_set_tokenize(ctx->set, atts[i + 1]);
   1.146 +	}
   1.147 +	
   1.148 +	if (name == 0) {
   1.149 +		fprintf(stderr, "invalid provides tag, "
   1.150 +			"missing name attribute\n");
   1.151 +		return;
   1.152 +	}
   1.153 +
   1.154 +	ctx->pkg_id = razor_set_add_provides(ctx->set, name, version);
   1.155 +}
   1.156 +
   1.157 +static void
   1.158  start_element(void *data, const char *name, const char **atts)
   1.159  {
   1.160  	struct parsing_context *ctx = data;
   1.161 @@ -406,6 +470,8 @@
   1.162  
   1.163  	if (strcmp(name, "package") == 0)
   1.164  		parse_package(ctx, atts);
   1.165 +	else if (strcmp(name, "provides") == 0)
   1.166 +		parse_provides(ctx, atts);
   1.167  
   1.168  	for (i = 0; atts[i]; i += 2)
   1.169  		razor_set_tokenize(ctx->set, atts[i + 1]);
   1.170 @@ -500,6 +566,18 @@
   1.171  }
   1.172  
   1.173  void
   1.174 +razor_set_list_provides(struct razor_set *set)
   1.175 +{
   1.176 +	struct razor_provides *p, *end;
   1.177 +	char *pool;
   1.178 +
   1.179 +	pool = set->string_pool.data;
   1.180 +	end = set->provides.data + set->provides.size;
   1.181 +	for (p = set->provides.data; p < end && p->name; p++)
   1.182 +		printf("%s %s\n", &pool[p->name], &pool[p->version]);
   1.183 +}
   1.184 +
   1.185 +void
   1.186  razor_set_info(struct razor_set *set)
   1.187  {
   1.188  	unsigned int offset, size;
   1.189 @@ -519,6 +597,9 @@
   1.190  		case RAZOR_PACKAGES:
   1.191  			printf("package section:\t%dkb\n", size / 1024);
   1.192  			break;
   1.193 +		case RAZOR_PROVIDES:
   1.194 +			printf("provides section:\t%dkb\n", size / 1024);
   1.195 +			break;
   1.196  		}
   1.197  	}
   1.198  }
   1.199 @@ -526,7 +607,8 @@
   1.200  static int
   1.201  usage(void)
   1.202  {
   1.203 -	printf("usage: razor [ import FILES | lookup <key> | list | info ]\n");
   1.204 +	printf("usage: razor [ import FILES | lookup <key> | "
   1.205 +	       "list | list-provides | info ]\n");
   1.206  	exit(1);
   1.207  }
   1.208  
   1.209 @@ -563,10 +645,15 @@
   1.210  		 * should probably just have a size field in the
   1.211  		 * header section. */
   1.212  		razor_set_add_package(set, 0, 0);
   1.213 +		razor_set_add_provides(set, 0, 0);
   1.214  
   1.215  		printf("bucket allocation: %d\n", set->buckets.alloc);
   1.216  		printf("pool size: %d\n", set->string_pool.size);
   1.217  		printf("pool allocation: %d\n", set->string_pool.alloc);
   1.218 +		printf("packages: %d\n",
   1.219 +		       set->packages.size / sizeof(struct razor_package));
   1.220 +		printf("provides: %d\n",
   1.221 +		       set->provides.size / sizeof(struct razor_provides));
   1.222  
   1.223  		razor_set_write(set, repo_filename);
   1.224  
   1.225 @@ -580,6 +667,10 @@
   1.226  		set = razor_set_open(repo_filename);
   1.227  		razor_set_list(set);
   1.228  		razor_set_destroy(set);
   1.229 +	} else if (strcmp(argv[1], "list-provides") == 0) {
   1.230 +		set = razor_set_open(repo_filename);
   1.231 +		razor_set_list_provides(set);
   1.232 +		razor_set_destroy(set);
   1.233  	} else if (strcmp(argv[1], "info") == 0) {
   1.234  		set = razor_set_open(repo_filename);
   1.235  		razor_set_info(set);