diff options
| author | Lukas Fleischer <cgit@cryptocrack.de> | 2015-03-03 13:00:07 +0100 | 
|---|---|---|
| committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2015-03-03 16:47:30 +0100 | 
| commit | 936295c4e4de8da83701c67377a911a0aefbcbd6 (patch) | |
| tree | 8a7d0f56bc0faaca7f68eab0037bb2bb7dd4579c | |
| parent | git: update to v2.3.1 (diff) | |
| download | cgit-936295c4e4de8da83701c67377a911a0aefbcbd6.tar.gz cgit-936295c4e4de8da83701c67377a911a0aefbcbd6.tar.bz2 cgit-936295c4e4de8da83701c67377a911a0aefbcbd6.zip | |
Simplify commit and tag parsing
* Use skip_prefix to avoid magic numbers in the code.
* Use xcalloc() instead of xmalloc(), followed by manual initialization.
* Split out line splitting.
Signed-off-by: Lukas Fleischer <cgit@cryptocrack.de>
Diffstat (limited to '')
| -rw-r--r-- | parsing.c | 112 | 
1 files changed, 41 insertions, 71 deletions
| @@ -118,45 +118,50 @@ static const char *reencode(char **txt, const char *src_enc, const char *dst_enc  }  #endif +static const char *next_header_line(const char *p) +{ +	p = strchr(p, '\n'); +	if (!p) +		return NULL; +	return p + 1; +} + +static int end_of_header(const char *p) +{ +	return !p || (*p == '\n'); +} +  struct commitinfo *cgit_parse_commit(struct commit *commit)  { +	const int sha1hex_len = 40;  	struct commitinfo *ret;  	const char *p = get_cached_commit_buffer(commit, NULL);  	const char *t; -	ret = xmalloc(sizeof(*ret)); +	ret = xcalloc(1, sizeof(struct commitinfo));  	ret->commit = commit; -	ret->author = NULL; -	ret->author_email = NULL; -	ret->committer = NULL; -	ret->committer_email = NULL; -	ret->subject = NULL; -	ret->msg = NULL; -	ret->msg_encoding = NULL; -	if (p == NULL) +	if (!p)  		return ret; -	if (!starts_with(p, "tree ")) +	if (!skip_prefix(p, "tree ", &p))  		die("Bad commit: %s", sha1_to_hex(commit->object.sha1)); -	else -		p += 46; // "tree " + hex[40] + "\n" +	p += sha1hex_len + 1; -	while (starts_with(p, "parent ")) -		p += 48; // "parent " + hex[40] + "\n" +	while (skip_prefix(p, "parent ", &p)) +		p += sha1hex_len + 1; -	if (p && starts_with(p, "author ")) { -		p = parse_user(p + 7, &ret->author, &ret->author_email, +	if (p && skip_prefix(p, "author ", &p)) { +		p = parse_user(p, &ret->author, &ret->author_email,  			&ret->author_date);  	} -	if (p && starts_with(p, "committer ")) { -		p = parse_user(p + 10, &ret->committer, &ret->committer_email, +	if (p && skip_prefix(p, "committer ", &p)) { +		p = parse_user(p, &ret->committer, &ret->committer_email,  			&ret->committer_date);  	} -	if (p && starts_with(p, "encoding ")) { -		p += 9; +	if (p && skip_prefix(p, "encoding ", &p)) {  		t = strchr(p, '\n');  		if (t) {  			ret->msg_encoding = substr(p, t + 1); @@ -164,38 +169,21 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)  		}  	} -	/* if no special encoding is found, assume UTF-8 */  	if (!ret->msg_encoding)  		ret->msg_encoding = xstrdup("UTF-8"); -	// skip unknown header fields -	while (p && *p && (*p != '\n')) { -		p = strchr(p, '\n'); -		if (p) -			p++; -	} - -	// skip empty lines between headers and message +	while (!end_of_header(p)) +		p = next_header_line(p);  	while (p && *p == '\n')  		p++; -  	if (!p)  		return ret; -	t = strchr(p, '\n'); -	if (t) { -		ret->subject = substr(p, t); -		p = t + 1; - -		while (p && *p == '\n') { -			p = strchr(p, '\n'); -			if (p) -				p++; -		} -		if (p) -			ret->msg = xstrdup(p); -	} else -		ret->subject = xstrdup(p); +	t = strchrnul(p, '\n'); +	ret->subject = substr(p, t); +	while (*t == '\n') +		t++; +	ret->msg = xstrdup(t);  	reencode(&ret->author, ret->msg_encoding, PAGE_ENCODING);  	reencode(&ret->author_email, ret->msg_encoding, PAGE_ENCODING); @@ -207,49 +195,31 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)  	return ret;  } -  struct taginfo *cgit_parse_tag(struct tag *tag)  {  	void *data;  	enum object_type type;  	unsigned long size;  	const char *p; -	struct taginfo *ret; +	struct taginfo *ret = NULL;  	data = read_sha1_file(tag->object.sha1, &type, &size); -	if (!data || type != OBJ_TAG) { -		free(data); -		return 0; -	} - -	ret = xmalloc(sizeof(*ret)); -	ret->tagger = NULL; -	ret->tagger_email = NULL; -	ret->tagger_date = 0; -	ret->msg = NULL; +	if (!data || type != OBJ_TAG) +		goto cleanup; -	p = data; +	ret = xcalloc(1, sizeof(struct taginfo)); -	while (p && *p) { -		if (*p == '\n') -			break; - -		if (starts_with(p, "tagger ")) { -			p = parse_user(p + 7, &ret->tagger, &ret->tagger_email, +	for (p = data; !end_of_header(p); p = next_header_line(p)) { +		if (skip_prefix(p, "tagger ", &p)) { +			p = parse_user(p, &ret->tagger, &ret->tagger_email,  				&ret->tagger_date); -		} else { -			p = strchr(p, '\n'); -			if (p) -				p++;  		}  	} -	// skip empty lines between headers and message -	while (p && *p == '\n') -		p++; -  	if (p && *p)  		ret->msg = xstrdup(p); + +cleanup:  	free(data);  	return ret;  } | 
