razor.c
changeset 55 b21a4953ff91
parent 52 8cb4c45dc86f
child 56 9c00581c71be
     1.1 --- a/razor.c	Mon Oct 22 22:53:55 2007 -0400
     1.2 +++ b/razor.c	Wed Oct 24 00:02:44 2007 -0400
     1.3 @@ -11,6 +11,7 @@
     1.4  #include <fcntl.h>
     1.5  #include <errno.h>
     1.6  #include <ctype.h>
     1.7 +#include <fnmatch.h>
     1.8  
     1.9  #include "razor.h"
    1.10  
    1.11 @@ -834,56 +835,74 @@
    1.12  	array_release(&importer->files);
    1.13  }
    1.14  
    1.15 -static struct razor_entry *
    1.16 -find_entry(struct razor_set *set, struct razor_entry *dir, const char *name)
    1.17 +static const char *
    1.18 +find_dir(struct razor_set *set, struct razor_entry **dir, const char *pattern)
    1.19 +{
    1.20 +	struct razor_entry *e, *end;
    1.21 +	const char *n, *pool = set->string_pool.data;
    1.22 +	int len;
    1.23 +
    1.24 +	e = (struct razor_entry *) set->file_tree.data + (*dir)->start;
    1.25 +	end = e + (*dir)->count;
    1.26 +
    1.27 +	while (e < end) {
    1.28 +		n = pool + e->name;
    1.29 +		len = strlen(n);
    1.30 +		if (len == 0) {
    1.31 +			/* FIXME: Shouldn't have 0-length entries... */
    1.32 +			e++;
    1.33 +			continue;
    1.34 +		}
    1.35 +			
    1.36 +		if (strncmp(pattern + 1, n, len) == 0 &&
    1.37 +		    pattern[len + 1] == '/') {
    1.38 +			*dir = e;
    1.39 +			return find_dir(set, dir, pattern + len + 1);
    1.40 +		}
    1.41 +		e++;
    1.42 +	}
    1.43 +
    1.44 +	return pattern + 1;
    1.45 +}
    1.46 +
    1.47 +static void
    1.48 +list_dir(struct razor_set *set, struct razor_entry *dir,
    1.49 +	 const char *pattern, const char *base)
    1.50  {
    1.51  	struct razor_entry *e, *end;
    1.52  	char *pool = set->string_pool.data;
    1.53 -	char *p, *n;
    1.54  
    1.55 -	if (name == NULL)
    1.56 -		return dir;
    1.57 -
    1.58 -	p = strchr(name + 1, '/');
    1.59  	e = (struct razor_entry *) set->file_tree.data + dir->start;
    1.60  	end = e + dir->count;
    1.61  
    1.62 -	while (e < end) {
    1.63 -		n = pool + e->name;
    1.64 -		if ((p != NULL && strncmp(n, name + 1, p - (name + 1)) == 0) ||
    1.65 -		    (p == NULL && strcmp(n, name + 1) == 0))
    1.66 -			return find_entry(set, e, p);
    1.67 -		e++;
    1.68 -	}
    1.69 -
    1.70 -	return NULL;
    1.71 -}
    1.72 -
    1.73 -static void
    1.74 -list_dir(struct razor_set *set, struct razor_entry *e, int indent)
    1.75 -{
    1.76 -	struct razor_entry *c;
    1.77 -	char *pool = set->string_pool.data;
    1.78 -	int i;
    1.79 -
    1.80 -	for (i = 0; i < indent; i++)
    1.81 -		putchar(' ');
    1.82 -	printf("%s\n", pool + e->name);
    1.83 -	for (i = 0; i < e->count; i++) {
    1.84 -		c = (struct razor_entry *) set->file_tree.data + e->start + i;
    1.85 -		list_dir(set, c, indent + 2);
    1.86 +	for ( ; e < end; e++) {
    1.87 +		if (base && base[0] && fnmatch(base, &pool[e->name], 0) != 0)
    1.88 +			continue;
    1.89 +		if (base && pattern)
    1.90 +			printf("%.*s%s%s\n",
    1.91 +			       base - pattern, pattern, pool + e->name,
    1.92 +			       e->count > 0 ? "/" : "");
    1.93 +		else
    1.94 +			printf("%s%s\n", pool + e->name,
    1.95 +			       e->count > 0 ? "/" : "");
    1.96 +		
    1.97  	}
    1.98  }
    1.99  
   1.100  void
   1.101 -razor_set_list_files(struct razor_set *set, const char *prefix)
   1.102 +razor_set_list_files(struct razor_set *set, const char *pattern)
   1.103  {
   1.104  	struct razor_entry *e;
   1.105 +	const char *base;
   1.106  
   1.107 -	e = find_entry(set, set->file_tree.data, prefix);
   1.108 -	if (e == NULL)
   1.109 +	if (pattern == NULL)
   1.110 +		pattern = "/";
   1.111 +
   1.112 +	e = set->file_tree.data;
   1.113 +	base = find_dir(set, &e, pattern);
   1.114 +	if (base == NULL)
   1.115  		return;
   1.116 -	list_dir(set, e, 2);
   1.117 +	list_dir(set, e, pattern, base);
   1.118  }
   1.119  
   1.120  void
   1.121 @@ -891,11 +910,12 @@
   1.122  {
   1.123  	struct razor_entry *e;
   1.124  	struct razor_package *packages, *p;
   1.125 -	const char *pool;
   1.126 +	const char *pool, *base;
   1.127  	unsigned long *r;
   1.128  
   1.129 -	e = find_entry(set, set->file_tree.data, filename);
   1.130 -	if (e == NULL)
   1.131 +	e = set->file_tree.data;
   1.132 +	base = find_dir(set, &e, filename);
   1.133 +	if (base == NULL)
   1.134  		return;
   1.135  	
   1.136  	r = (unsigned long *) set->package_pool.data + e->packages;
   1.137 @@ -946,15 +966,22 @@
   1.138  }
   1.139  
   1.140  void
   1.141 -razor_set_list(struct razor_set *set)
   1.142 +razor_set_list(struct razor_set *set, const char *pattern)
   1.143  {
   1.144  	struct razor_package *p, *end;
   1.145 +	int with_version = 0;
   1.146  	char *pool;
   1.147  
   1.148  	pool = set->string_pool.data;
   1.149  	end = set->packages.data + set->packages.size;
   1.150 -	for (p = set->packages.data; p < end; p++)
   1.151 -		printf("%s %s\n", &pool[p->name], &pool[p->version]);
   1.152 +	for (p = set->packages.data; p < end; p++) {
   1.153 +		if (pattern && fnmatch(pattern, &pool[p->name], 0) != 0)
   1.154 +		    continue;
   1.155 +		if (with_version)
   1.156 +			printf("%s %s\n", &pool[p->name], &pool[p->version]);
   1.157 +		else
   1.158 +			printf("%s\n", &pool[p->name]);
   1.159 +	}
   1.160  }
   1.161  
   1.162  struct razor_set *bsearch_set;