 06316234ac
			
		
	
	06316234ac
	
	
	
		
			
			trp_gen is not a statement or function call, so it should not be followed with a semicolon. Noticed by gcc -pedantic. vcs-svn/repo_tree.c:41:81: warning: ISO C does not allow extra ';' outside of a function [-pedantic] Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
		
			
				
	
	
		
			103 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			103 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Licensed under a two-clause BSD-style license.
 | |
|  * See LICENSE for details.
 | |
|  */
 | |
| 
 | |
| #include "git-compat-util.h"
 | |
| #include "trp.h"
 | |
| #include "obj_pool.h"
 | |
| #include "string_pool.h"
 | |
| 
 | |
| static struct trp_root tree = { ~0 };
 | |
| 
 | |
| struct node {
 | |
| 	uint32_t offset;
 | |
| 	struct trp_node children;
 | |
| };
 | |
| 
 | |
| /* Two memory pools: one for struct node, and another for strings */
 | |
| obj_pool_gen(node, struct node, 4096)
 | |
| obj_pool_gen(string, char, 4096)
 | |
| 
 | |
| static char *node_value(struct node *node)
 | |
| {
 | |
| 	return node ? string_pointer(node->offset) : NULL;
 | |
| }
 | |
| 
 | |
| static int node_cmp(struct node *a, struct node *b)
 | |
| {
 | |
| 	return strcmp(node_value(a), node_value(b));
 | |
| }
 | |
| 
 | |
| /* Build a Treap from the node structure (a trp_node w/ offset) */
 | |
| trp_gen(static, tree_, struct node, children, node, node_cmp)
 | |
| 
 | |
| const char *pool_fetch(uint32_t entry)
 | |
| {
 | |
| 	return node_value(node_pointer(entry));
 | |
| }
 | |
| 
 | |
| uint32_t pool_intern(const char *key)
 | |
| {
 | |
| 	/* Canonicalize key */
 | |
| 	struct node *match = NULL, *node;
 | |
| 	uint32_t key_len;
 | |
| 	if (key == NULL)
 | |
| 		return ~0;
 | |
| 	key_len = strlen(key) + 1;
 | |
| 	node = node_pointer(node_alloc(1));
 | |
| 	node->offset = string_alloc(key_len);
 | |
| 	strcpy(node_value(node), key);
 | |
| 	match = tree_search(&tree, node);
 | |
| 	if (!match) {
 | |
| 		tree_insert(&tree, node);
 | |
| 	} else {
 | |
| 		node_free(1);
 | |
| 		string_free(key_len);
 | |
| 		node = match;
 | |
| 	}
 | |
| 	return node_offset(node);
 | |
| }
 | |
| 
 | |
| uint32_t pool_tok_r(char *str, const char *delim, char **saveptr)
 | |
| {
 | |
| 	char *token = strtok_r(str, delim, saveptr);
 | |
| 	return token ? pool_intern(token) : ~0;
 | |
| }
 | |
| 
 | |
| void pool_print_seq(uint32_t len, uint32_t *seq, char delim, FILE *stream)
 | |
| {
 | |
| 	uint32_t i;
 | |
| 	for (i = 0; i < len && ~seq[i]; i++) {
 | |
| 		fputs(pool_fetch(seq[i]), stream);
 | |
| 		if (i < len - 1 && ~seq[i + 1])
 | |
| 			fputc(delim, stream);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| uint32_t pool_tok_seq(uint32_t sz, uint32_t *seq, const char *delim, char *str)
 | |
| {
 | |
| 	char *context = NULL;
 | |
| 	uint32_t token = ~0;
 | |
| 	uint32_t length;
 | |
| 
 | |
| 	if (sz == 0)
 | |
| 		return ~0;
 | |
| 	if (str)
 | |
| 		token = pool_tok_r(str, delim, &context);
 | |
| 	for (length = 0; length < sz; length++) {
 | |
| 		seq[length] = token;
 | |
| 		if (token == ~0)
 | |
| 			return length;
 | |
| 		token = pool_tok_r(NULL, delim, &context);
 | |
| 	}
 | |
| 	seq[sz - 1] = ~0;
 | |
| 	return sz;
 | |
| }
 | |
| 
 | |
| void pool_reset(void)
 | |
| {
 | |
| 	node_reset();
 | |
| 	string_reset();
 | |
| }
 |