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 ea26b23de082..c9a16abacab4 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c | |||
| @@ -138,38 +138,36 @@ static void print_cmdline(void) | |||
| 138 | printf("cmd_%s := %s\n\n", target, cmdline); | 138 | printf("cmd_%s := %s\n\n", target, cmdline); |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | char * str_config = NULL; | 141 | struct item { |
| 142 | int size_config = 0; | 142 | struct item *next; |
| 143 | int len_config = 0; | 143 | unsigned int len; |
| 144 | unsigned int hash; | ||
| 145 | char name[0]; | ||
| 146 | }; | ||
| 144 | 147 | ||
| 145 | /* | 148 | #define HASHSZ 256 |
| 146 | * Grow the configuration string to a desired length. | 149 | static struct item *hashtab[HASHSZ]; |
| 147 | * Usually the first growth is plenty. | ||
| 148 | */ | ||
| 149 | static void grow_config(int len) | ||
| 150 | { | ||
| 151 | while (len_config + len > size_config) { | ||
| 152 | if (size_config == 0) | ||
| 153 | size_config = 2048; | ||
| 154 | str_config = realloc(str_config, size_config *= 2); | ||
| 155 | if (str_config == NULL) | ||
| 156 | { perror("fixdep:malloc"); exit(1); } | ||
| 157 | } | ||
| 158 | } | ||
| 159 | 150 | ||
| 151 | static unsigned int strhash(const char *str, unsigned int sz) | ||
| 152 | { | ||
| 153 | /* fnv32 hash */ | ||
| 154 | unsigned int i, hash = 2166136261U; | ||
| 160 | 155 | ||
| 156 | for (i = 0; i < sz; i++) | ||
| 157 | hash = (hash ^ str[i]) * 0x01000193; | ||
| 158 | return hash; | ||
| 159 | } | ||
| 161 | 160 | ||
| 162 | /* | 161 | /* |
| 163 | * Lookup a value in the configuration string. | 162 | * Lookup a value in the configuration string. |
| 164 | */ | 163 | */ |
| 165 | static int is_defined_config(const char * name, int len) | 164 | static int is_defined_config(const char *name, int len, unsigned int hash) |
| 166 | { | 165 | { |
| 167 | const char * pconfig; | 166 | struct item *aux; |
| 168 | const char * plast = str_config + len_config - len; | 167 | |
| 169 | for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) { | 168 | for (aux = hashtab[hash % HASHSZ]; aux; aux = aux->next) { |
| 170 | if (pconfig[ -1] == '\n' | 169 | if (aux->hash == hash && aux->len == len && |
| 171 | && pconfig[len] == '\n' | 170 | memcmp(aux->name, name, len) == 0) |
| 172 | && !memcmp(pconfig, name, len)) | ||
| 173 | return 1; | 171 | return 1; |
| 174 | } | 172 | } |
| 175 | return 0; | 173 | return 0; |
| @@ -178,13 +176,19 @@ static int is_defined_config(const char * name, int len) | |||
| 178 | /* | 176 | /* |
| 179 | * Add a new value to the configuration string. | 177 | * Add a new value to the configuration string. |
| 180 | */ | 178 | */ |
| 181 | static void define_config(const char * name, int len) | 179 | static void define_config(const char *name, int len, unsigned int hash) |
| 182 | { | 180 | { |
| 183 | grow_config(len + 1); | 181 | struct item *aux = malloc(sizeof(*aux) + len); |
| 184 | 182 | ||
| 185 | memcpy(str_config+len_config, name, len); | 183 | if (!aux) { |
| 186 | len_config += len; | 184 | perror("fixdep:malloc"); |
| 187 | str_config[len_config++] = '\n'; | 185 | exit(1); |
| 186 | } | ||
| 187 | memcpy(aux->name, name, len); | ||
| 188 | aux->len = len; | ||
| 189 | aux->hash = hash; | ||
| 190 | aux->next = hashtab[hash % HASHSZ]; | ||
| 191 | hashtab[hash % HASHSZ] = aux; | ||
| 188 | } | 192 | } |
| 189 | 193 | ||
| 190 | /* | 194 | /* |
| @@ -192,40 +196,49 @@ static void define_config(const char * name, int len) | |||
| 192 | */ | 196 | */ |
| 193 | static void clear_config(void) | 197 | static void clear_config(void) |
| 194 | { | 198 | { |
| 195 | len_config = 0; | 199 | struct item *aux, *next; |
| 196 | define_config("", 0); | 200 | unsigned int i; |
| 201 | |||
| 202 | for (i = 0; i < HASHSZ; i++) { | ||
| 203 | for (aux = hashtab[i]; aux; aux = next) { | ||
| 204 | next = aux->next; | ||
| 205 | free(aux); | ||
| 206 | } | ||
| 207 | hashtab[i] = NULL; | ||
| 208 | } | ||
| 197 | } | 209 | } |
| 198 | 210 | ||
| 199 | /* | 211 | /* |
| 200 | * Record the use of a CONFIG_* word. | 212 | * Record the use of a CONFIG_* word. |
| 201 | */ | 213 | */ |
| 202 | static void use_config(char *m, int slen) | 214 | static void use_config(const char *m, int slen) |
| 203 | { | 215 | { |
| 204 | char s[PATH_MAX]; | 216 | unsigned int hash = strhash(m, slen); |
| 205 | char *p; | 217 | int c, i; |
| 206 | 218 | ||
| 207 | if (is_defined_config(m, slen)) | 219 | if (is_defined_config(m, slen, hash)) |
| 208 | return; | 220 | return; |
| 209 | 221 | ||
| 210 | define_config(m, slen); | 222 | define_config(m, slen, hash); |
| 211 | 223 | ||
| 212 | memcpy(s, m, slen); s[slen] = 0; | 224 | printf(" $(wildcard include/config/"); |
| 213 | 225 | for (i = 0; i < slen; i++) { | |
| 214 | for (p = s; p < s + slen; p++) { | 226 | c = m[i]; |
| 215 | if (*p == '_') | 227 | if (c == '_') |
| 216 | *p = '/'; | 228 | c = '/'; |
| 217 | else | 229 | else |
| 218 | *p = tolower((int)*p); | 230 | c = tolower(c); |
| 231 | putchar(c); | ||
| 219 | } | 232 | } |
| 220 | printf(" $(wildcard include/config/%s.h) \\\n", s); | 233 | printf(".h) \\\n"); |
| 221 | } | 234 | } |
| 222 | 235 | ||
| 223 | static void parse_config_file(char *map, size_t len) | 236 | static void parse_config_file(const char *map, size_t len) |
| 224 | { | 237 | { |
| 225 | int *end = (int *) (map + len); | 238 | const int *end = (const int *) (map + len); |
| 226 | /* start at +1, so that p can never be < map */ | 239 | /* start at +1, so that p can never be < map */ |
| 227 | int *m = (int *) map + 1; | 240 | const int *m = (const int *) map + 1; |
| 228 | char *p, *q; | 241 | const char *p, *q; |
| 229 | 242 | ||
| 230 | for (; m < end; m++) { | 243 | for (; m < end; m++) { |
| 231 | if (*m == INT_CONF) { p = (char *) m ; goto conf; } | 244 | if (*m == INT_CONF) { p = (char *) m ; goto conf; } |
| @@ -265,7 +278,7 @@ static int strrcmp(char *s, char *sub) | |||
| 265 | return memcmp(s + slen - sublen, sub, sublen); | 278 | return memcmp(s + slen - sublen, sub, sublen); |
| 266 | } | 279 | } |
| 267 | 280 | ||
| 268 | static void do_config_file(char *filename) | 281 | static void do_config_file(const char *filename) |
| 269 | { | 282 | { |
| 270 | struct stat st; | 283 | struct stat st; |
| 271 | int fd; | 284 | int fd; |
| @@ -273,7 +286,7 @@ static void do_config_file(char *filename) | |||
| 273 | 286 | ||
| 274 | fd = open(filename, O_RDONLY); | 287 | fd = open(filename, O_RDONLY); |
| 275 | if (fd < 0) { | 288 | if (fd < 0) { |
| 276 | fprintf(stderr, "fixdep: "); | 289 | fprintf(stderr, "fixdep: error opening config file: "); |
| 277 | perror(filename); | 290 | perror(filename); |
| 278 | exit(2); | 291 | exit(2); |
| 279 | } | 292 | } |
| @@ -344,11 +357,15 @@ static void print_deps(void) | |||
| 344 | 357 | ||
| 345 | fd = open(depfile, O_RDONLY); | 358 | fd = open(depfile, O_RDONLY); |
| 346 | if (fd < 0) { | 359 | if (fd < 0) { |
| 347 | fprintf(stderr, "fixdep: "); | 360 | fprintf(stderr, "fixdep: error opening depfile: "); |
| 348 | perror(depfile); | 361 | perror(depfile); |
| 349 | exit(2); | 362 | exit(2); |
| 350 | } | 363 | } |
| 351 | fstat(fd, &st); | 364 | if (fstat(fd, &st) < 0) { |
| 365 | fprintf(stderr, "fixdep: error fstat'ing depfile: "); | ||
| 366 | perror(depfile); | ||
| 367 | exit(2); | ||
| 368 | } | ||
| 352 | if (st.st_size == 0) { | 369 | if (st.st_size == 0) { |
| 353 | fprintf(stderr,"fixdep: %s is empty\n",depfile); | 370 | fprintf(stderr,"fixdep: %s is empty\n",depfile); |
| 354 | close(fd); | 371 | close(fd); |
