diff options
| author | Lars Hjemli <hjemli@gmail.com> | 2011-02-19 14:00:56 +0100 | 
|---|---|---|
| committer | Lars Hjemli <hjemli@gmail.com> | 2011-02-19 14:00:59 +0100 | 
| commit | e66a16cebcdac53b63e77876acef1ca9e4877038 (patch) | |
| tree | 839123e66853c4a80c305a3a1c13295fe5e6acc9 | |
| parent | 286c4c0a1d7085afdc8d9ddba86da4ed9f2f7400 (diff) | |
| parent | c2680325f68192368d32f26458fea9cfb50df6e5 (diff) | |
Merge branch 'lh/improve-range-search'
* lh/improve-range-search:
  html.c: use '+' to escape spaces in urls
  ui-log.c: improve handling of range-search argument
  Add vector utility functions
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | html.c | 4 | ||||
| -rw-r--r-- | ui-log.c | 71 | ||||
| -rw-r--r-- | vector.c | 38 | ||||
| -rw-r--r-- | vector.h | 17 | 
5 files changed, 118 insertions, 13 deletions
| @@ -115,6 +115,7 @@ OBJECTS += ui-stats.o  OBJECTS += ui-summary.o  OBJECTS += ui-tag.o  OBJECTS += ui-tree.o +OBJECTS += vector.o  ifdef NEEDS_LIBICONV  	EXTLIBS += -liconv @@ -18,7 +18,7 @@ static const char* url_escape_table[256] = {  	"%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07", "%08", "%09",  	"%0a", "%0b", "%0c", "%0d", "%0e", "%0f", "%10", "%11", "%12", "%13",  	"%14", "%15", "%16", "%17", "%18", "%19", "%1a", "%1b", "%1c", "%1d", -	"%1e", "%1f", "%20", 0, "%22", "%23", 0, "%25", "%26", "%27", 0, 0, 0, +	"%1e", "%1f", "+", 0, "%22", "%23", 0, "%25", "%26", "%27", 0, 0, 0,  	"%2b", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "%3c", "%3d",  	"%3e", "%3f", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  	0, 0, 0, 0, 0, 0, 0, 0, 0, "%5c", 0, "%5e", 0, "%60", 0, 0, 0, 0, 0, @@ -181,7 +181,7 @@ void html_url_arg(const char *txt)  		const char *e = url_escape_table[c];  		if (e) {  			html_raw(txt, t - txt); -			html_raw(e, 3); +			html_raw(e, strlen(e));  			txt = t+1;  		}  		t++; @@ -9,6 +9,7 @@  #include "cgit.h"  #include "html.h"  #include "ui-shared.h" +#include "vector.h"  int files, add_lines, rem_lines; @@ -148,38 +149,86 @@ static const char *disambiguate_ref(const char *ref)  	return ref;  } +static char *next_token(char **src) +{ +	char *result; + +	if (!src || !*src) +		return NULL; +	while (isspace(**src)) +		(*src)++; +	if (!**src) +		return NULL; +	result = *src; +	while (**src) { +		if (isspace(**src)) { +			**src = '\0'; +			(*src)++; +			break; +		} +		(*src)++; +	} +	return result; +} +  void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern,  		    char *path, int pager)  {  	struct rev_info rev;  	struct commit *commit; -	const char *argv[] = {NULL, NULL, NULL, NULL, NULL}; -	int argc = 2; +	struct vector vec = VECTOR_INIT(char *);  	int i, columns = 3; +	char *arg; + +	/* First argv is NULL */ +	vector_push(&vec, NULL, 0);  	if (!tip)  		tip = ctx.qry.head; - -	argv[1] = disambiguate_ref(tip); +	tip = disambiguate_ref(tip); +	vector_push(&vec, &tip, 0);  	if (grep && pattern && *pattern) { +		pattern = xstrdup(pattern);  		if (!strcmp(grep, "grep") || !strcmp(grep, "author") || -		    !strcmp(grep, "committer")) -			argv[argc++] = fmt("--%s=%s", grep, pattern); -		if (!strcmp(grep, "range")) -			argv[1] = pattern; +		    !strcmp(grep, "committer")) { +			arg = fmt("--%s=%s", grep, pattern); +			vector_push(&vec, &arg, 0); +		} +		if (!strcmp(grep, "range")) { +			/* Split the pattern at whitespace and add each token +			 * as a revision expression. Do not accept other +			 * rev-list options. Also, replace the previously +			 * pushed tip (it's no longer relevant). +			 */ +			vec.count--; +			while ((arg = next_token(&pattern))) { +				if (*arg == '-') { +					fprintf(stderr, "Bad range expr: %s\n", +						arg); +					break; +				} +				vector_push(&vec, &arg, 0); +			} +		}  	}  	if (path) { -		argv[argc++] = "--"; -		argv[argc++] = path; +		arg = "--"; +		vector_push(&vec, &arg, 0); +		vector_push(&vec, &path, 0);  	} + +	/* Make sure the vector is NULL-terminated */ +	vector_push(&vec, NULL, 0); +	vec.count--; +  	init_revisions(&rev, NULL);  	rev.abbrev = DEFAULT_ABBREV;  	rev.commit_format = CMIT_FMT_DEFAULT;  	rev.verbose_header = 1;  	rev.show_root_diff = 0; -	setup_revisions(argc, argv, &rev, NULL); +	setup_revisions(vec.count, vec.data, &rev, NULL);  	load_ref_decorations(DECORATE_FULL_REFS);  	rev.show_decorations = 1;  	rev.grep_filter.regflags |= REG_ICASE; diff --git a/vector.c b/vector.c new file mode 100644 index 0000000..0863908 --- /dev/null +++ b/vector.c @@ -0,0 +1,38 @@ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include "vector.h" + +static int grow(struct vector *vec, int gently) +{ +	size_t new_alloc; +	void *new_data; + +	new_alloc = vec->alloc * 3 / 2; +	if (!new_alloc) +		new_alloc = 8; +	new_data = realloc(vec->data, new_alloc * vec->size); +	if (!new_data) { +		if (gently) +			return ENOMEM; +		perror("vector.c:grow()"); +		exit(1); +	} +	vec->data = new_data; +	vec->alloc = new_alloc; +	return 0; +} + +int vector_push(struct vector *vec, const void *data, int gently) +{ +	int rc; + +	if (vec->count == vec->alloc && (rc = grow(vec, gently))) +		return rc; +	if (data) +		memmove(vec->data + vec->count * vec->size, data, vec->size); +	else +		memset(vec->data + vec->count * vec->size, 0, vec->size); +	vec->count++; +	return 0; +} diff --git a/vector.h b/vector.h new file mode 100644 index 0000000..c64eb1f --- /dev/null +++ b/vector.h @@ -0,0 +1,17 @@ +#ifndef CGIT_VECTOR_H +#define CGIT_VECTOR_H + +#include <stdlib.h> + +struct vector { +	size_t size; +	size_t count; +	size_t alloc; +	void *data; +}; + +#define VECTOR_INIT(type) {sizeof(type), 0, 0, NULL} + +int vector_push(struct vector *vec, const void *data, int gently); + +#endif /* CGIT_VECTOR_H */ | 
