aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/basic
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/basic')
-rw-r--r--scripts/basic/Makefile2
-rw-r--r--scripts/basic/docproc.c132
-rw-r--r--scripts/basic/fixdep.c119
-rw-r--r--scripts/basic/hash.c64
4 files changed, 200 insertions, 117 deletions
diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile
index 09559951df12..4c324a1f1e0e 100644
--- a/scripts/basic/Makefile
+++ b/scripts/basic/Makefile
@@ -9,7 +9,7 @@
9# fixdep: Used to generate dependency information during build process 9# fixdep: Used to generate dependency information during build process
10# docproc: Used in Documentation/DocBook 10# docproc: Used in Documentation/DocBook
11 11
12hostprogs-y := fixdep docproc hash 12hostprogs-y := fixdep docproc
13always := $(hostprogs-y) 13always := $(hostprogs-y)
14 14
15# fixdep is needed to compile other host programs 15# fixdep is needed to compile other host programs
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c
index 79ab973fb43a..98dec87974d0 100644
--- a/scripts/basic/docproc.c
+++ b/scripts/basic/docproc.c
@@ -34,12 +34,14 @@
34 * 34 *
35 */ 35 */
36 36
37#define _GNU_SOURCE
37#include <stdio.h> 38#include <stdio.h>
38#include <stdlib.h> 39#include <stdlib.h>
39#include <string.h> 40#include <string.h>
40#include <ctype.h> 41#include <ctype.h>
41#include <unistd.h> 42#include <unistd.h>
42#include <limits.h> 43#include <limits.h>
44#include <errno.h>
43#include <sys/types.h> 45#include <sys/types.h>
44#include <sys/wait.h> 46#include <sys/wait.h>
45 47
@@ -54,6 +56,7 @@ typedef void FILEONLY(char * file);
54FILEONLY *internalfunctions; 56FILEONLY *internalfunctions;
55FILEONLY *externalfunctions; 57FILEONLY *externalfunctions;
56FILEONLY *symbolsonly; 58FILEONLY *symbolsonly;
59FILEONLY *findall;
57 60
58typedef void FILELINE(char * file, char * line); 61typedef void FILELINE(char * file, char * line);
59FILELINE * singlefunctions; 62FILELINE * singlefunctions;
@@ -65,12 +68,30 @@ FILELINE * docsection;
65#define KERNELDOCPATH "scripts/" 68#define KERNELDOCPATH "scripts/"
66#define KERNELDOC "kernel-doc" 69#define KERNELDOC "kernel-doc"
67#define DOCBOOK "-docbook" 70#define DOCBOOK "-docbook"
71#define LIST "-list"
68#define FUNCTION "-function" 72#define FUNCTION "-function"
69#define NOFUNCTION "-nofunction" 73#define NOFUNCTION "-nofunction"
70#define NODOCSECTIONS "-no-doc-sections" 74#define NODOCSECTIONS "-no-doc-sections"
71 75
72static char *srctree, *kernsrctree; 76static char *srctree, *kernsrctree;
73 77
78static char **all_list = NULL;
79static int all_list_len = 0;
80
81static void consume_symbol(const char *sym)
82{
83 int i;
84
85 for (i = 0; i < all_list_len; i++) {
86 if (!all_list[i])
87 continue;
88 if (strcmp(sym, all_list[i]))
89 continue;
90 all_list[i] = NULL;
91 break;
92 }
93}
94
74static void usage (void) 95static void usage (void)
75{ 96{
76 fprintf(stderr, "Usage: docproc {doc|depend} file\n"); 97 fprintf(stderr, "Usage: docproc {doc|depend} file\n");
@@ -248,6 +269,7 @@ static void docfunctions(char * filename, char * type)
248 struct symfile * sym = &symfilelist[i]; 269 struct symfile * sym = &symfilelist[i];
249 for (j=0; j < sym->symbolcnt; j++) { 270 for (j=0; j < sym->symbolcnt; j++) {
250 vec[idx++] = type; 271 vec[idx++] = type;
272 consume_symbol(sym->symbollist[j].name);
251 vec[idx++] = sym->symbollist[j].name; 273 vec[idx++] = sym->symbollist[j].name;
252 } 274 }
253 } 275 }
@@ -287,6 +309,11 @@ static void singfunc(char * filename, char * line)
287 vec[idx++] = &line[i]; 309 vec[idx++] = &line[i];
288 } 310 }
289 } 311 }
312 for (i = 0; i < idx; i++) {
313 if (strcmp(vec[i], FUNCTION))
314 continue;
315 consume_symbol(vec[i + 1]);
316 }
290 vec[idx++] = filename; 317 vec[idx++] = filename;
291 vec[idx] = NULL; 318 vec[idx] = NULL;
292 exec_kernel_doc(vec); 319 exec_kernel_doc(vec);
@@ -306,6 +333,13 @@ static void docsect(char *filename, char *line)
306 if (*s == '\n') 333 if (*s == '\n')
307 *s = '\0'; 334 *s = '\0';
308 335
336 if (asprintf(&s, "DOC: %s", line) < 0) {
337 perror("asprintf");
338 exit(1);
339 }
340 consume_symbol(s);
341 free(s);
342
309 vec[0] = KERNELDOC; 343 vec[0] = KERNELDOC;
310 vec[1] = DOCBOOK; 344 vec[1] = DOCBOOK;
311 vec[2] = FUNCTION; 345 vec[2] = FUNCTION;
@@ -315,6 +349,84 @@ static void docsect(char *filename, char *line)
315 exec_kernel_doc(vec); 349 exec_kernel_doc(vec);
316} 350}
317 351
352static void find_all_symbols(char *filename)
353{
354 char *vec[4]; /* kerneldoc -list file NULL */
355 pid_t pid;
356 int ret, i, count, start;
357 char real_filename[PATH_MAX + 1];
358 int pipefd[2];
359 char *data, *str;
360 size_t data_len = 0;
361
362 vec[0] = KERNELDOC;
363 vec[1] = LIST;
364 vec[2] = filename;
365 vec[3] = NULL;
366
367 if (pipe(pipefd)) {
368 perror("pipe");
369 exit(1);
370 }
371
372 switch (pid=fork()) {
373 case -1:
374 perror("fork");
375 exit(1);
376 case 0:
377 close(pipefd[0]);
378 dup2(pipefd[1], 1);
379 memset(real_filename, 0, sizeof(real_filename));
380 strncat(real_filename, kernsrctree, PATH_MAX);
381 strncat(real_filename, "/" KERNELDOCPATH KERNELDOC,
382 PATH_MAX - strlen(real_filename));
383 execvp(real_filename, vec);
384 fprintf(stderr, "exec ");
385 perror(real_filename);
386 exit(1);
387 default:
388 close(pipefd[1]);
389 data = malloc(4096);
390 do {
391 while ((ret = read(pipefd[0],
392 data + data_len,
393 4096)) > 0) {
394 data_len += ret;
395 data = realloc(data, data_len + 4096);
396 }
397 } while (ret == -EAGAIN);
398 if (ret != 0) {
399 perror("read");
400 exit(1);
401 }
402 waitpid(pid, &ret ,0);
403 }
404 if (WIFEXITED(ret))
405 exitstatus |= WEXITSTATUS(ret);
406 else
407 exitstatus = 0xff;
408
409 count = 0;
410 /* poor man's strtok, but with counting */
411 for (i = 0; i < data_len; i++) {
412 if (data[i] == '\n') {
413 count++;
414 data[i] = '\0';
415 }
416 }
417 start = all_list_len;
418 all_list_len += count;
419 all_list = realloc(all_list, sizeof(char *) * all_list_len);
420 str = data;
421 for (i = 0; i < data_len && start != all_list_len; i++) {
422 if (data[i] == '\0') {
423 all_list[start] = str;
424 str = data + i + 1;
425 start++;
426 }
427 }
428}
429
318/* 430/*
319 * Parse file, calling action specific functions for: 431 * Parse file, calling action specific functions for:
320 * 1) Lines containing !E 432 * 1) Lines containing !E
@@ -322,7 +434,8 @@ static void docsect(char *filename, char *line)
322 * 3) Lines containing !D 434 * 3) Lines containing !D
323 * 4) Lines containing !F 435 * 4) Lines containing !F
324 * 5) Lines containing !P 436 * 5) Lines containing !P
325 * 6) Default lines - lines not matching the above 437 * 6) Lines containing !C
438 * 7) Default lines - lines not matching the above
326 */ 439 */
327static void parse_file(FILE *infile) 440static void parse_file(FILE *infile)
328{ 441{
@@ -365,6 +478,12 @@ static void parse_file(FILE *infile)
365 s++; 478 s++;
366 docsection(line + 2, s); 479 docsection(line + 2, s);
367 break; 480 break;
481 case 'C':
482 while (*s && !isspace(*s)) s++;
483 *s = '\0';
484 if (findall)
485 findall(line+2);
486 break;
368 default: 487 default:
369 defaultline(line); 488 defaultline(line);
370 } 489 }
@@ -380,6 +499,7 @@ static void parse_file(FILE *infile)
380int main(int argc, char *argv[]) 499int main(int argc, char *argv[])
381{ 500{
382 FILE * infile; 501 FILE * infile;
502 int i;
383 503
384 srctree = getenv("SRCTREE"); 504 srctree = getenv("SRCTREE");
385 if (!srctree) 505 if (!srctree)
@@ -415,6 +535,7 @@ int main(int argc, char *argv[])
415 symbolsonly = find_export_symbols; 535 symbolsonly = find_export_symbols;
416 singlefunctions = noaction2; 536 singlefunctions = noaction2;
417 docsection = noaction2; 537 docsection = noaction2;
538 findall = find_all_symbols;
418 parse_file(infile); 539 parse_file(infile);
419 540
420 /* Rewind to start from beginning of file again */ 541 /* Rewind to start from beginning of file again */
@@ -425,8 +546,16 @@ int main(int argc, char *argv[])
425 symbolsonly = printline; 546 symbolsonly = printline;
426 singlefunctions = singfunc; 547 singlefunctions = singfunc;
427 docsection = docsect; 548 docsection = docsect;
549 findall = NULL;
428 550
429 parse_file(infile); 551 parse_file(infile);
552
553 for (i = 0; i < all_list_len; i++) {
554 if (!all_list[i])
555 continue;
556 fprintf(stderr, "Warning: didn't use docs for %s\n",
557 all_list[i]);
558 }
430 } 559 }
431 else if (strcmp("depend", argv[1]) == 0) 560 else if (strcmp("depend", argv[1]) == 0)
432 { 561 {
@@ -439,6 +568,7 @@ int main(int argc, char *argv[])
439 symbolsonly = adddep; 568 symbolsonly = adddep;
440 singlefunctions = adddep2; 569 singlefunctions = adddep2;
441 docsection = adddep2; 570 docsection = adddep2;
571 findall = adddep;
442 parse_file(infile); 572 parse_file(infile);
443 printf("\n"); 573 printf("\n");
444 } 574 }
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
141char * str_config = NULL; 141struct item {
142int size_config = 0; 142 struct item *next;
143int 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. 149static struct item *hashtab[HASHSZ];
147 * Usually the first growth is plenty.
148 */
149static 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
151static 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 */
165static int is_defined_config(const char * name, int len) 164static 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 */
181static void define_config(const char * name, int len) 179static 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 */
193static void clear_config(void) 197static 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 */
202static void use_config(char *m, int slen) 214static 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
223static void parse_config_file(char *map, size_t len) 236static 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
268static void do_config_file(char *filename) 281static 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);
diff --git a/scripts/basic/hash.c b/scripts/basic/hash.c
deleted file mode 100644
index 2ef5d3f666b8..000000000000
--- a/scripts/basic/hash.c
+++ /dev/null
@@ -1,64 +0,0 @@
1/*
2 * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
3 *
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9
10#define DYNAMIC_DEBUG_HASH_BITS 6
11
12static const char *program;
13
14static void usage(void)
15{
16 printf("Usage: %s <djb2|r5> <modname>\n", program);
17 exit(1);
18}
19
20/* djb2 hashing algorithm by Dan Bernstein. From:
21 * http://www.cse.yorku.ca/~oz/hash.html
22 */
23
24static unsigned int djb2_hash(char *str)
25{
26 unsigned long hash = 5381;
27 int c;
28
29 c = *str;
30 while (c) {
31 hash = ((hash << 5) + hash) + c;
32 c = *++str;
33 }
34 return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
35}
36
37static unsigned int r5_hash(char *str)
38{
39 unsigned long hash = 0;
40 int c;
41
42 c = *str;
43 while (c) {
44 hash = (hash + (c << 4) + (c >> 4)) * 11;
45 c = *++str;
46 }
47 return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
48}
49
50int main(int argc, char *argv[])
51{
52 program = argv[0];
53
54 if (argc != 3)
55 usage();
56 if (!strcmp(argv[1], "djb2"))
57 printf("%d\n", djb2_hash(argv[2]));
58 else if (!strcmp(argv[1], "r5"))
59 printf("%d\n", r5_hash(argv[2]));
60 else
61 usage();
62 exit(0);
63}
64