diff options
Diffstat (limited to 'scripts/basic/fixdep.c')
| -rw-r--r-- | scripts/basic/fixdep.c | 119 | 
1 files changed, 68 insertions, 51 deletions
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index ea26b23de08..c9a16abacab 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -138,38 +138,36 @@ static void print_cmdline(void)  	printf("cmd_%s := %s\n\n", target, cmdline);  } -char * str_config  = NULL; -int    size_config = 0; -int    len_config  = 0; +struct item { +	struct item	*next; +	unsigned int	len; +	unsigned int	hash; +	char		name[0]; +}; -/* - * Grow the configuration string to a desired length. - * Usually the first growth is plenty. - */ -static void grow_config(int len) -{ -	while (len_config + len > size_config) { -		if (size_config == 0) -			size_config = 2048; -		str_config = realloc(str_config, size_config *= 2); -		if (str_config == NULL) -			{ perror("fixdep:malloc"); exit(1); } -	} -} +#define HASHSZ 256 +static struct item *hashtab[HASHSZ]; +static unsigned int strhash(const char *str, unsigned int sz) +{ +	/* fnv32 hash */ +	unsigned int i, hash = 2166136261U; +	for (i = 0; i < sz; i++) +		hash = (hash ^ str[i]) * 0x01000193; +	return hash; +}  /*   * Lookup a value in the configuration string.   */ -static int is_defined_config(const char * name, int len) +static int is_defined_config(const char *name, int len, unsigned int hash)  { -	const char * pconfig; -	const char * plast = str_config + len_config - len; -	for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) { -		if (pconfig[ -1] == '\n' -		&&  pconfig[len] == '\n' -		&&  !memcmp(pconfig, name, len)) +	struct item *aux; + +	for (aux = hashtab[hash % HASHSZ]; aux; aux = aux->next) { +		if (aux->hash == hash && aux->len == len && +		    memcmp(aux->name, name, len) == 0)  			return 1;  	}  	return 0; @@ -178,13 +176,19 @@ static int is_defined_config(const char * name, int len)  /*   * Add a new value to the configuration string.   */ -static void define_config(const char * name, int len) +static void define_config(const char *name, int len, unsigned int hash)  { -	grow_config(len + 1); +	struct item *aux = malloc(sizeof(*aux) + len); -	memcpy(str_config+len_config, name, len); -	len_config += len; -	str_config[len_config++] = '\n'; +	if (!aux) { +		perror("fixdep:malloc"); +		exit(1); +	} +	memcpy(aux->name, name, len); +	aux->len = len; +	aux->hash = hash; +	aux->next = hashtab[hash % HASHSZ]; +	hashtab[hash % HASHSZ] = aux;  }  /* @@ -192,40 +196,49 @@ static void define_config(const char * name, int len)   */  static void clear_config(void)  { -	len_config = 0; -	define_config("", 0); +	struct item *aux, *next; +	unsigned int i; + +	for (i = 0; i < HASHSZ; i++) { +		for (aux = hashtab[i]; aux; aux = next) { +			next = aux->next; +			free(aux); +		} +		hashtab[i] = NULL; +	}  }  /*   * Record the use of a CONFIG_* word.   */ -static void use_config(char *m, int slen) +static void use_config(const char *m, int slen)  { -	char s[PATH_MAX]; -	char *p; +	unsigned int hash = strhash(m, slen); +	int c, i; -	if (is_defined_config(m, slen)) +	if (is_defined_config(m, slen, hash))  	    return; -	define_config(m, slen); +	define_config(m, slen, hash); -	memcpy(s, m, slen); s[slen] = 0; - -	for (p = s; p < s + slen; p++) { -		if (*p == '_') -			*p = '/'; +	printf("    $(wildcard include/config/"); +	for (i = 0; i < slen; i++) { +		c = m[i]; +		if (c == '_') +			c = '/';  		else -			*p = tolower((int)*p); +			c = tolower(c); +		putchar(c);  	} -	printf("    $(wildcard include/config/%s.h) \\\n", s); +	printf(".h) \\\n");  } -static void parse_config_file(char *map, size_t len) +static void parse_config_file(const char *map, size_t len)  { -	int *end = (int *) (map + len); +	const int *end = (const int *) (map + len);  	/* start at +1, so that p can never be < map */ -	int *m   = (int *) map + 1; -	char *p, *q; +	const int *m   = (const int *) map + 1; +	const char *p, *q;  	for (; m < end; m++) {  		if (*m == INT_CONF) { p = (char *) m  ; goto conf; } @@ -265,7 +278,7 @@ static int strrcmp(char *s, char *sub)  	return memcmp(s + slen - sublen, sub, sublen);  } -static void do_config_file(char *filename) +static void do_config_file(const char *filename)  {  	struct stat st;  	int fd; @@ -273,7 +286,7 @@ static void do_config_file(char *filename)  	fd = open(filename, O_RDONLY);  	if (fd < 0) { -		fprintf(stderr, "fixdep: "); +		fprintf(stderr, "fixdep: error opening config file: ");  		perror(filename);  		exit(2);  	} @@ -344,11 +357,15 @@ static void print_deps(void)  	fd = open(depfile, O_RDONLY);  	if (fd < 0) { -		fprintf(stderr, "fixdep: "); +		fprintf(stderr, "fixdep: error opening depfile: ");  		perror(depfile);  		exit(2);  	} -	fstat(fd, &st); +	if (fstat(fd, &st) < 0) { +                fprintf(stderr, "fixdep: error fstat'ing depfile: "); +                perror(depfile); +                exit(2); +        }  	if (st.st_size == 0) {  		fprintf(stderr,"fixdep: %s is empty\n",depfile);  		close(fd);  |