diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/Makefile.build | 14 | ||||
-rw-r--r-- | scripts/Makefile.extrawarn | 3 | ||||
-rw-r--r-- | scripts/Makefile.lib | 4 | ||||
-rw-r--r-- | scripts/basic/fixdep.c | 236 | ||||
-rwxr-xr-x | scripts/checkpatch.pl | 28 | ||||
-rwxr-xr-x | scripts/coccicheck | 2 | ||||
-rw-r--r-- | scripts/coccinelle/api/alloc/alloc_cast.cocci | 92 | ||||
-rw-r--r-- | scripts/coccinelle/api/alloc/kzalloc-simple.cocci | 86 | ||||
-rw-r--r-- | scripts/coccinelle/api/alloc/zalloc-simple.cocci | 448 | ||||
-rw-r--r-- | scripts/coccinelle/api/memdup.cocci | 1 | ||||
-rw-r--r-- | scripts/coccinelle/free/ifnullfree.cocci | 2 | ||||
-rw-r--r-- | scripts/coccinelle/misc/array_size.cocci | 4 | ||||
-rwxr-xr-x | scripts/decodecode | 20 | ||||
-rwxr-xr-x | scripts/faddr2line | 8 | ||||
-rw-r--r-- | scripts/gdb/linux/tasks.py | 2 | ||||
-rw-r--r-- | scripts/genksyms/.gitignore | 1 | ||||
-rw-r--r-- | scripts/kconfig/expr.c | 5 | ||||
-rwxr-xr-x | scripts/kernel-doc | 1508 | ||||
-rw-r--r-- | scripts/mod/devicetable-offsets.c | 4 | ||||
-rw-r--r-- | scripts/mod/file2alias.c | 15 | ||||
-rw-r--r-- | scripts/mod/modpost.c | 9 | ||||
-rw-r--r-- | scripts/package/Makefile | 26 | ||||
-rw-r--r-- | scripts/package/snapcraft.template | 14 | ||||
-rwxr-xr-x | scripts/tags.sh | 2 |
24 files changed, 943 insertions, 1591 deletions
diff --git a/scripts/Makefile.build b/scripts/Makefile.build index cb8997ed0149..47cddf32aeba 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -265,12 +265,18 @@ else objtool_args += $(call cc-ifversion, -lt, 0405, --no-unreachable) endif +ifdef CONFIG_MODVERSIONS +objtool_o = $(@D)/.tmp_$(@F) +else +objtool_o = $(@) +endif + # 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory # 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file # 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file cmd_objtool = $(if $(patsubst y%,, \ $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n), \ - $(__objtool_obj) $(objtool_args) "$(@)";) + $(__objtool_obj) $(objtool_args) "$(objtool_o)";) objtool_obj = $(if $(patsubst y%,, \ $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n), \ $(__objtool_obj)) @@ -286,16 +292,16 @@ objtool_dep = $(objtool_obj) \ define rule_cc_o_c $(call echo-cmd,checksrc) $(cmd_checksrc) \ $(call cmd_and_fixdep,cc_o_c) \ - $(cmd_modversions_c) \ $(cmd_checkdoc) \ $(call echo-cmd,objtool) $(cmd_objtool) \ + $(cmd_modversions_c) \ $(call echo-cmd,record_mcount) $(cmd_record_mcount) endef define rule_as_o_S $(call cmd_and_fixdep,as_o_S) \ - $(cmd_modversions_S) \ - $(call echo-cmd,objtool) $(cmd_objtool) + $(call echo-cmd,objtool) $(cmd_objtool) \ + $(cmd_modversions_S) endef # List module undefined symbols (or empty line if not enabled) diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index c6ebf4239e64..8d5357053f86 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -11,6 +11,8 @@ # are not supported by all versions of the compiler # ========================================================================== +KBUILD_CFLAGS += $(call cc-disable-warning, packed-not-aligned) + ifeq ("$(origin W)", "command line") export KBUILD_ENABLE_EXTRA_GCC_CHECKS := $(W) endif @@ -26,6 +28,7 @@ warning-1 += -Wold-style-definition warning-1 += $(call cc-option, -Wmissing-include-dirs) warning-1 += $(call cc-option, -Wunused-but-set-variable) warning-1 += $(call cc-option, -Wunused-const-variable) +warning-1 += $(call cc-option, -Wpacked-not-aligned) warning-1 += $(call cc-disable-warning, missing-field-initializers) warning-1 += $(call cc-disable-warning, sign-compare) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 5ff2761e973d..5fdc1a19b02c 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -274,7 +274,7 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \ DTC ?= $(objtree)/scripts/dtc/dtc # Disable noisy checks by default -ifeq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),) +ifeq ($(findstring 1,$(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),) DTC_FLAGS += -Wno-unit_address_vs_reg \ -Wno-simple_bus_reg \ -Wno-unit_address_format \ @@ -283,7 +283,7 @@ DTC_FLAGS += -Wno-unit_address_vs_reg \ -Wno-pci_device_reg endif -ifeq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),2) +ifneq ($(findstring 2,$(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),) DTC_FLAGS += -Wnode_name_chars_strict \ -Wproperty_name_chars_strict endif diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index bbf62cb1f819..fa3d39b6f23b 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -104,20 +104,12 @@ #include <sys/types.h> #include <sys/stat.h> -#include <sys/mman.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <stdlib.h> #include <stdio.h> -#include <limits.h> #include <ctype.h> -#include <arpa/inet.h> - -int insert_extra_deps; -char *target; -char *depfile; -char *cmdline; static void usage(void) { @@ -127,14 +119,6 @@ static void usage(void) } /* - * Print out the commandline prefixed with cmd_<target filename> := - */ -static void print_cmdline(void) -{ - printf("cmd_%s := %s\n\n", target, cmdline); -} - -/* * Print out a dependency path from a symbol name */ static void print_config(const char *m, int slen) @@ -155,16 +139,16 @@ static void print_config(const char *m, int slen) static void do_extra_deps(void) { - if (insert_extra_deps) { - char buf[80]; - while(fgets(buf, sizeof(buf), stdin)) { - int len = strlen(buf); - if (len < 2 || buf[len-1] != '\n') { - fprintf(stderr, "fixdep: bad data on stdin\n"); - exit(1); - } - print_config(buf, len-1); + char buf[80]; + + while (fgets(buf, sizeof(buf), stdin)) { + int len = strlen(buf); + + if (len < 2 || buf[len - 1] != '\n') { + fprintf(stderr, "fixdep: bad data on stdin\n"); + exit(1); } + print_config(buf, len - 1); } } @@ -235,6 +219,17 @@ static void use_config(const char *m, int slen) print_config(m, slen); } +/* test if s ends in sub */ +static int str_ends_with(const char *s, int slen, const char *sub) +{ + int sublen = strlen(sub); + + if (sublen > slen) + return 0; + + return !memcmp(s + slen - sublen, sub, sublen); +} + static void parse_config_file(const char *p) { const char *q, *r; @@ -244,7 +239,7 @@ static void parse_config_file(const char *p) q = p; while (*q && (isalnum(*q) || *q == '_')) q++; - if (memcmp(q - 7, "_MODULE", 7) == 0) + if (str_ends_with(p, q - p, "_MODULE")) r = q - 7; else r = q; @@ -254,56 +249,46 @@ static void parse_config_file(const char *p) } } -/* test if s ends in sub */ -static int strrcmp(const char *s, const char *sub) -{ - int slen = strlen(s); - int sublen = strlen(sub); - - if (sublen > slen) - return 1; - - return memcmp(s + slen - sublen, sub, sublen); -} - -static void do_config_file(const char *filename) +static void *read_file(const char *filename) { struct stat st; int fd; - char *map; + char *buf; fd = open(filename, O_RDONLY); if (fd < 0) { - fprintf(stderr, "fixdep: error opening config file: "); + fprintf(stderr, "fixdep: error opening file: "); perror(filename); exit(2); } if (fstat(fd, &st) < 0) { - fprintf(stderr, "fixdep: error fstat'ing config file: "); + fprintf(stderr, "fixdep: error fstat'ing file: "); perror(filename); exit(2); } - if (st.st_size == 0) { - close(fd); - return; - } - map = malloc(st.st_size + 1); - if (!map) { + buf = malloc(st.st_size + 1); + if (!buf) { perror("fixdep: malloc"); - close(fd); - return; + exit(2); } - if (read(fd, map, st.st_size) != st.st_size) { + if (read(fd, buf, st.st_size) != st.st_size) { perror("fixdep: read"); - close(fd); - return; + exit(2); } - map[st.st_size] = '\0'; + buf[st.st_size] = '\0'; close(fd); - parse_config_file(map); + return buf; +} - free(map); +/* Ignore certain dependencies */ +static int is_ignored_file(const char *s, int len) +{ + return str_ends_with(s, len, "include/generated/autoconf.h") || + str_ends_with(s, len, "include/generated/autoksyms.h") || + str_ends_with(s, len, "arch/um/include/uml-config.h") || + str_ends_with(s, len, "include/linux/kconfig.h") || + str_ends_with(s, len, ".ver"); } /* @@ -311,71 +296,70 @@ static void do_config_file(const char *filename) * assignments are parsed not only by make, but also by the rather simple * parser in scripts/mod/sumversion.c. */ -static void parse_dep_file(void *map, size_t len) +static void parse_dep_file(char *m, const char *target, int insert_extra_deps) { - char *m = map; - char *end = m + len; char *p; - char s[PATH_MAX]; - int is_target; + int is_last, is_target; int saw_any_target = 0; int is_first_dep = 0; + void *buf; - while (m < end) { + while (1) { /* Skip any "white space" */ - while (m < end && (*m == ' ' || *m == '\\' || *m == '\n')) + while (*m == ' ' || *m == '\\' || *m == '\n') m++; + + if (!*m) + break; + /* Find next "white space" */ p = m; - while (p < end && *p != ' ' && *p != '\\' && *p != '\n') + while (*p && *p != ' ' && *p != '\\' && *p != '\n') p++; + is_last = (*p == '\0'); /* Is the token we found a target name? */ is_target = (*(p-1) == ':'); /* Don't write any target names into the dependency file */ if (is_target) { /* The /next/ file is the first dependency */ is_first_dep = 1; - } else { - /* Save this token/filename */ - memcpy(s, m, p-m); - s[p - m] = 0; - - /* Ignore certain dependencies */ - if (strrcmp(s, "include/generated/autoconf.h") && - strrcmp(s, "include/generated/autoksyms.h") && - strrcmp(s, "arch/um/include/uml-config.h") && - strrcmp(s, "include/linux/kconfig.h") && - strrcmp(s, ".ver")) { + } else if (!is_ignored_file(m, p - m)) { + *p = '\0'; + + /* + * Do not list the source file as dependency, so that + * kbuild is not confused if a .c file is rewritten + * into .S or vice versa. Storing it in source_* is + * needed for modpost to compute srcversions. + */ + if (is_first_dep) { /* - * Do not list the source file as dependency, - * so that kbuild is not confused if a .c file - * is rewritten into .S or vice versa. Storing - * it in source_* is needed for modpost to - * compute srcversions. + * If processing the concatenation of multiple + * dependency files, only process the first + * target name, which will be the original + * source name, and ignore any other target + * names, which will be intermediate temporary + * files. */ - if (is_first_dep) { - /* - * If processing the concatenation of - * multiple dependency files, only - * process the first target name, which - * will be the original source name, - * and ignore any other target names, - * which will be intermediate temporary - * files. - */ - if (!saw_any_target) { - saw_any_target = 1; - printf("source_%s := %s\n\n", - target, s); - printf("deps_%s := \\\n", - target); - } - is_first_dep = 0; - } else - printf(" %s \\\n", s); - do_config_file(s); + if (!saw_any_target) { + saw_any_target = 1; + printf("source_%s := %s\n\n", + target, m); + printf("deps_%s := \\\n", target); + } + is_first_dep = 0; + } else { + printf(" %s \\\n", m); } + + buf = read_file(m); + parse_config_file(buf); + free(buf); } + + if (is_last) + break; + /* * Start searching for next token immediately after the first * "whitespace" character that follows this token. @@ -388,50 +372,19 @@ static void parse_dep_file(void *map, size_t len) exit(1); } - do_extra_deps(); + if (insert_extra_deps) + do_extra_deps(); printf("\n%s: $(deps_%s)\n\n", target, target); printf("$(deps_%s):\n", target); } -static void print_deps(void) -{ - struct stat st; - int fd; - void *map; - - fd = open(depfile, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "fixdep: error opening depfile: "); - perror(depfile); - exit(2); - } - 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); - return; - } - map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if ((long) map == -1) { - perror("fixdep: mmap"); - close(fd); - return; - } - - parse_dep_file(map, st.st_size); - - munmap(map, st.st_size); - - close(fd); -} - int main(int argc, char *argv[]) { + const char *depfile, *target, *cmdline; + int insert_extra_deps = 0; + void *buf; + if (argc == 5 && !strcmp(argv[1], "-e")) { insert_extra_deps = 1; argv++; @@ -442,8 +395,11 @@ int main(int argc, char *argv[]) target = argv[2]; cmdline = argv[3]; - print_cmdline(); - print_deps(); + printf("cmd_%s := %s\n\n", target, cmdline); + + buf = read_file(depfile); + parse_dep_file(buf, target, insert_extra_deps); + free(buf); return 0; } diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 040aa79e1d9d..ba03f17ff662 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -5586,6 +5586,12 @@ sub process { } } +# check for smp_read_barrier_depends and read_barrier_depends + if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) { + WARN("READ_BARRIER_DEPENDS", + "$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\n" . $herecurr); + } + # check of hardware specific defines if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { CHK("ARCH_DEFINES", @@ -6233,28 +6239,6 @@ sub process { } } -# whine about ACCESS_ONCE - if ($^V && $^V ge 5.10.0 && - $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) { - my $par = $1; - my $eq = $2; - my $fun = $3; - $par =~ s/^\(\s*(.*)\s*\)$/$1/; - if (defined($eq)) { - if (WARN("PREFER_WRITE_ONCE", - "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/; - } - } else { - if (WARN("PREFER_READ_ONCE", - "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/; - } - } - } - # check for mutex_trylock_recursive usage if ($line =~ /mutex_trylock_recursive/) { ERROR("LOCKING", diff --git a/scripts/coccicheck b/scripts/coccicheck index ecfac64b39fe..9fedca611b7f 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -177,7 +177,7 @@ coccinelle () { REQ_NUM=$(echo $REQ | ${DIR}/scripts/ld-version.sh) if [ "$REQ_NUM" != "0" ] ; then if [ "$SPATCH_VERSION_NUM" -lt "$REQ_NUM" ] ; then - echo "Skipping coccinele SmPL patch: $COCCI" + echo "Skipping coccinelle SmPL patch: $COCCI" echo "You have coccinelle: $SPATCH_VERSION" echo "This SmPL patch requires: $REQ" return diff --git a/scripts/coccinelle/api/alloc/alloc_cast.cocci b/scripts/coccinelle/api/alloc/alloc_cast.cocci index 6c308ee19b32..408ee3879f9b 100644 --- a/scripts/coccinelle/api/alloc/alloc_cast.cocci +++ b/scripts/coccinelle/api/alloc/alloc_cast.cocci @@ -5,10 +5,11 @@ //# kmalloc, kzalloc, kcalloc, kmem_cache_alloc, kmem_cache_zalloc, //# kmem_cache_alloc_node, kmalloc_node and kzalloc_node and removes //# the casting as it is not required. The result in the patch case may -//#need some reformatting. +//# need some reformatting. // // Confidence: High -// Copyright: 2014, Himangi Saraogi GPLv2. +// Copyright: (C) 2014 Himangi Saraogi GPLv2. +// Copyright: (C) 2017 Himanshu Jha GPLv2. // Comments: // Options: --no-includes --include-headers // @@ -18,55 +19,104 @@ virtual patch virtual org virtual report +@initialize:python@ +@@ +import re +pattern = '__' +m = re.compile(pattern) + +@r1 depends on context || patch@ +type T; +@@ + + (T *) + \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\| + kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\|vmalloc\|vzalloc\| + dma_alloc_coherent\|dma_zalloc_coherent\|devm_kmalloc\|devm_kzalloc\| + kvmalloc\|kvzalloc\|kvmalloc_node\|kvzalloc_node\|pci_alloc_consistent\| + pci_zalloc_consistent\|kmem_alloc\|kmem_zalloc\|kmem_zone_alloc\| + kmem_zone_zalloc\|vmalloc_node\|vzalloc_node\)(...) + //---------------------------------------------------------- // For context mode //---------------------------------------------------------- -@depends on context@ -type T; +@script:python depends on context@ +t << r1.T; +@@ + +if m.search(t) != None: + cocci.include_match(False) + +@depends on context && r1@ +type r1.T; @@ * (T *) \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\| - kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...) + kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\|vmalloc\|vzalloc\| + dma_alloc_coherent\|dma_zalloc_coherent\|devm_kmalloc\|devm_kzalloc\| + kvmalloc\|kvzalloc\|kvmalloc_node\|kvzalloc_node\|pci_alloc_consistent\| + pci_zalloc_consistent\|kmem_alloc\|kmem_zalloc\|kmem_zone_alloc\| + kmem_zone_zalloc\|vmalloc_node\|vzalloc_node\)(...) //---------------------------------------------------------- // For patch mode //---------------------------------------------------------- -@depends on patch@ -type T; +@script:python depends on patch@ +t << r1.T; +@@ + +if m.search(t) != None: + cocci.include_match(False) + +@depends on patch && r1@ +type r1.T; @@ - (T *) - (\(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\| - kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...)) + \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\| + kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\|vmalloc\|vzalloc\| + dma_alloc_coherent\|dma_zalloc_coherent\|devm_kmalloc\|devm_kzalloc\| + kvmalloc\|kvzalloc\|kvmalloc_node\|kvzalloc_node\|pci_alloc_consistent\| + pci_zalloc_consistent\|kmem_alloc\|kmem_zalloc\|kmem_zone_alloc\| + kmem_zone_zalloc\|vmalloc_node\|vzalloc_node\)(...) //---------------------------------------------------------- // For org and report mode //---------------------------------------------------------- -@r depends on org || report@ +@r2 depends on org || report@ type T; position p; @@ - (T@p *)\(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\| - kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...) + (T@p *) + \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\| + kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\|vmalloc\|vzalloc\| + dma_alloc_coherent\|dma_zalloc_coherent\|devm_kmalloc\|devm_kzalloc\| + kvmalloc\|kvzalloc\|kvmalloc_node\|kvzalloc_node\|pci_alloc_consistent\| + pci_zalloc_consistent\|kmem_alloc\|kmem_zalloc\|kmem_zone_alloc\| + kmem_zone_zalloc\|vmalloc_node\|vzalloc_node\)(...) @script:python depends on org@ -p << r.p; -t << r.T; +p << r2.p; +t << r2.T; @@ -coccilib.org.print_safe_todo(p[0], t) +if m.search(t) != None: + cocci.include_match(False) +else: + coccilib.org.print_safe_todo(p[0], t) @script:python depends on report@ -p << r.p; -t << r.T; +p << r2.p; +t << r2.T; @@ -msg="WARNING: casting value returned by memory allocation function to (%s *) is useless." % (t) -coccilib.report.print_report(p[0], msg) - - +if m.search(t) != None: + cocci.include_match(False) +else: + msg="WARNING: casting value returned by memory allocation function to (%s *) is useless." % (t) + coccilib.report.print_report(p[0], msg) diff --git a/scripts/coccinelle/api/alloc/kzalloc-simple.cocci b/scripts/coccinelle/api/alloc/kzalloc-simple.cocci deleted file mode 100644 index 52c55e4fa67d..000000000000 --- a/scripts/coccinelle/api/alloc/kzalloc-simple.cocci +++ /dev/null @@ -1,86 +0,0 @@ -/// -/// Use kzalloc rather than kmalloc followed by memset with 0 -/// -/// This considers some simple cases that are common and easy to validate -/// Note in particular that there are no ...s in the rule, so all of the -/// matched code has to be contiguous -/// -// Confidence: High -// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2. -// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6. GPLv2. -// URL: http://coccinelle.lip6.fr/rules/kzalloc.html -// Options: --no-includes --include-headers -// -// Keywords: kmalloc, kzalloc -// Version min: < 2.6.12 kmalloc -// Version min: 2.6.14 kzalloc -// - -virtual context -virtual patch -virtual org -virtual report - -//---------------------------------------------------------- -// For context mode -//---------------------------------------------------------- - -@depends on context@ -type T, T2; -expression x; -expression E1,E2; -statement S; -@@ - -* x = (T)kmalloc(E1,E2); - if ((x==NULL) || ...) S -* memset((T2)x,0,E1); - -//---------------------------------------------------------- -// For patch mode -//---------------------------------------------------------- - -@depends on patch@ -type T, T2; -expression x; -expression E1,E2; -statement S; -@@ - -- x = (T)kmalloc(E1,E2); -+ x = kzalloc(E1,E2); - if ((x==NULL) || ...) S -- memset((T2)x,0,E1); - -//---------------------------------------------------------- -// For org mode -//---------------------------------------------------------- - -@r depends on org || report@ -type T, T2; -expression x; -expression E1,E2; -statement S; -position p; -@@ - - x = (T)kmalloc@p(E1,E2); - if ((x==NULL) || ...) S - memset((T2)x,0,E1); - -@script:python depends on org@ -p << r.p; -x << r.x; -@@ - -msg="%s" % (x) -msg_safe=msg.replace("[","@(").replace("]",")") -coccilib.org.print_todo(p[0], msg_safe) - -@script:python depends on report@ -p << r.p; -x << r.x; -@@ - -msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x) -coccilib.report.print_report(p[0], msg) diff --git a/scripts/coccinelle/api/alloc/zalloc-simple.cocci b/scripts/coccinelle/api/alloc/zalloc-simple.cocci new file mode 100644 index 000000000000..92b20913055f --- /dev/null +++ b/scripts/coccinelle/api/alloc/zalloc-simple.cocci @@ -0,0 +1,448 @@ +/// +/// Use zeroing allocator rather than allocator followed by memset with 0 +/// +/// This considers some simple cases that are common and easy to validate +/// Note in particular that there are no ...s in the rule, so all of the +/// matched code has to be contiguous +/// +// Confidence: High +// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6. GPLv2. +// Copyright: (C) 2017 Himanshu Jha GPLv2. +// URL: http://coccinelle.lip6.fr/rules/kzalloc.html +// Options: --no-includes --include-headers +// +// Keywords: kmalloc, kzalloc +// Version min: < 2.6.12 kmalloc +// Version min: 2.6.14 kzalloc +// + +virtual context +virtual patch +virtual org +virtual report + +//---------------------------------------------------------- +// For context mode +//---------------------------------------------------------- + +@depends on context@ +type T, T2; +expression x; +expression E1; +statement S; +@@ + +* x = (T)\(kmalloc(E1, ...)\|vmalloc(E1)\|dma_alloc_coherent(...,E1,...)\| + kmalloc_node(E1, ...)\|kmem_cache_alloc(...)\|kmem_alloc(E1, ...)\| + devm_kmalloc(...,E1,...)\|kvmalloc(E1, ...)\|pci_alloc_consistent(...,E1,...)\| + kvmalloc_node(E1,...)\); + if ((x==NULL) || ...) S +* memset((T2)x,0,E1); + +//---------------------------------------------------------- +// For patch mode +//---------------------------------------------------------- + +@depends on patch@ +type T, T2; +expression x; +expression E1,E2,E3,E4; +statement S; +@@ + +( +- x = kmalloc(E1,E2); ++ x = kzalloc(E1,E2); +| +- x = (T *)kmalloc(E1,E2); ++ x = kzalloc(E1,E2); +| +- x = (T)kmalloc(E1,E2); ++ x = (T)kzalloc(E1,E2); +| +- x = vmalloc(E1); ++ x = vzalloc(E1); +| +- x = (T *)vmalloc(E1); ++ x = vzalloc(E1); +| +- x = (T)vmalloc(E1); ++ x = (T)vzalloc(E1); +| +- x = dma_alloc_coherent(E2,E1,E3,E4); ++ x = dma_zalloc_coherent(E2,E1,E3,E4); +| +- x = (T *)dma_alloc_coherent(E2,E1,E3,E4); ++ x = dma_zalloc_coherent(E2,E1,E3,E4); +| +- x = (T)dma_alloc_coherent(E2,E1,E3,E4); ++ x = (T)dma_zalloc_coherent(E2,E1,E3,E4); +| +- x = kmalloc_node(E1,E2,E3); ++ x = kzalloc_node(E1,E2,E3); +| +- x = (T *)kmalloc_node(E1,E2,E3); ++ x = kzalloc_node(E1,E2,E3); +| +- x = (T)kmalloc_node(E1,E2,E3); ++ x = (T)kzalloc_node(E1,E2,E3); +| +- x = kmem_cache_alloc(E3,E4); ++ x = kmem_cache_zalloc(E3,E4); +| +- x = (T *)kmem_cache_alloc(E3,E4); ++ x = kmem_cache_zalloc(E3,E4); +| +- x = (T)kmem_cache_alloc(E3,E4); ++ x = (T)kmem_cache_zalloc(E3,E4); +| +- x = kmem_alloc(E1,E2); ++ x = kmem_zalloc(E1,E2); +| +- x = (T *)kmem_alloc(E1,E2); ++ x = kmem_zalloc(E1,E2); +| +- x = (T)kmem_alloc(E1,E2); ++ x = (T)kmem_zalloc(E1,E2); +| +- x = devm_kmalloc(E2,E1,E3); ++ x = devm_kzalloc(E2,E1,E3); +| +- x = (T *)devm_kmalloc(E2,E1,E3); ++ x = devm_kzalloc(E2,E1,E3); +| +- x = (T)devm_kmalloc(E2,E1,E3); ++ x = (T)devm_kzalloc(E2,E1,E3); +| +- x = kvmalloc(E1,E2); ++ x = kvzalloc(E1,E2); +| +- x = (T *)kvmalloc(E1,E2); ++ x = kvzalloc(E1,E2); +| +- x = (T)kvmalloc(E1,E2); ++ x = (T)kvzalloc(E1,E2); +| +- x = pci_alloc_consistent(E2,E1,E3); ++ x = pci_zalloc_consistent(E2,E1,E3); +| +- x = (T *)pci_alloc_consistent(E2,E1,E3); ++ x = pci_zalloc_consistent(E2,E1,E3); +| +- x = (T)pci_alloc_consistent(E2,E1,E3); ++ x = (T)pci_zalloc_consistent(E2,E1,E3); +| +- x = kvmalloc_node(E1,E2,E3); ++ x = kvzalloc_node(E1,E2,E3); +| +- x = (T *)kvmalloc_node(E1,E2,E3); ++ x = kvzalloc_node(E1,E2,E3); +| +- x = (T)kvmalloc_node(E1,E2,E3); ++ x = (T)kvzalloc_node(E1,E2,E3); +) + if ((x==NULL) || ...) S +- memset((T2)x,0,E1); + +//---------------------------------------------------------- +// For org mode +//---------------------------------------------------------- + +@r depends on org || report@ +type T, T2; +expression x; +expression E1,E2; +statement S; +position p; +@@ + + x = (T)kmalloc@p(E1,E2); + if ((x==NULL) || ...) S + memset((T2)x,0,E1); + +@script:python depends on org@ +p << r.p; +x << r.x; +@@ + +msg="%s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << r.p; +x << r.x; +@@ + +msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x) +coccilib.report.print_report(p[0], msg) + +//----------------------------------------------------------------- +@r1 depends on org || report@ +type T, T2; +expression x; +expression E1; +statement S; +position p; +@@ + + x = (T)vmalloc@p(E1); + if ((x==NULL) || ...) S + memset((T2)x,0,E1); + +@script:python depends on org@ +p << r1.p; +x << r1.x; +@@ + +msg="%s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << r1.p; +x << r1.x; +@@ + +msg="WARNING: vzalloc should be used for %s, instead of vmalloc/memset" % (x) +coccilib.report.print_report(p[0], msg) + +//----------------------------------------------------------------- +@r2 depends on org || report@ +type T, T2; +expression x; +expression E1,E2,E3,E4; +statement S; +position p; +@@ + + x = (T)dma_alloc_coherent@p(E2,E1,E3,E4); + if ((x==NULL) || ...) S + memset((T2)x,0,E1); + +@script:python depends on org@ +p << r2.p; +x << r2.x; +@@ + +msg="%s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << r2.p; +x << r2.x; +@@ + +msg="WARNING: dma_zalloc_coherent should be used for %s, instead of dma_alloc_coherent/memset" % (x) +coccilib.report.print_report(p[0], msg) + +//----------------------------------------------------------------- +@r3 depends on org || report@ +type T, T2; +expression x; +expression E1,E2,E3; +statement S; +position p; +@@ + + x = (T)kmalloc_node@p(E1,E2,E3); + if ((x==NULL) || ...) S + memset((T2)x,0,E1); + +@script:python depends on org@ +p << r3.p; +x << r3.x; +@@ + +msg="%s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << r3.p; +x << r3.x; +@@ + +msg="WARNING: kzalloc_node should be used for %s, instead of kmalloc_node/memset" % (x) +coccilib.report.print_report(p[0], msg) + +//----------------------------------------------------------------- +@r4 depends on org || report@ +type T, T2; +expression x; +expression E1,E2,E3; +statement S; +position p; +@@ + + x = (T)kmem_cache_alloc@p(E2,E3); + if ((x==NULL) || ...) S + memset((T2)x,0,E1); + +@script:python depends on org@ +p << r4.p; +x << r4.x; +@@ + +msg="%s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << r4.p; +x << r4.x; +@@ + +msg="WARNING: kmem_cache_zalloc should be used for %s, instead of kmem_cache_alloc/memset" % (x) +coccilib.report.print_report(p[0], msg) + +//----------------------------------------------------------------- +@r5 depends on org || report@ +type T, T2; +expression x; +expression E1,E2; +statement S; +position p; +@@ + + x = (T)kmem_alloc@p(E1,E2); + if ((x==NULL) || ...) S + memset((T2)x,0,E1); + +@script:python depends on org@ +p << r5.p; +x << r5.x; +@@ + +msg="%s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << r5.p; +x << r5.x; +@@ + +msg="WARNING: kmem_zalloc should be used for %s, instead of kmem_alloc/memset" % (x) +coccilib.report.print_report(p[0], msg) + +//----------------------------------------------------------------- +@r6 depends on org || report@ +type T, T2; +expression x; +expression E1,E2,E3; +statement S; +position p; +@@ + + x = (T)devm_kmalloc@p(E2,E1,E3); + if ((x==NULL) || ...) S + memset((T2)x,0,E1); + +@script:python depends on org@ +p << r6.p; +x << r6.x; +@@ + +msg="%s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << r6.p; +x << r6.x; +@@ + +msg="WARNING: devm_kzalloc should be used for %s, instead of devm_kmalloc/memset" % (x) +coccilib.report.print_report(p[0], msg) + +//----------------------------------------------------------------- +@r7 depends on org || report@ +type T, T2; +expression x; +expression E1,E2; +statement S; +position p; +@@ + + x = (T)kvmalloc@p(E1,E2); + if ((x==NULL) || ...) S + memset((T2)x,0,E1); + +@script:python depends on org@ +p << r7.p; +x << r7.x; +@@ + +msg="%s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << r7.p; +x << r7.x; +@@ + +msg="WARNING: kvzalloc should be used for %s, instead of kvmalloc/memset" % (x) +coccilib.report.print_report(p[0], msg) + +//----------------------------------------------------------------- +@r8 depends on org || report@ +type T, T2; +expression x; +expression E1,E2,E3; +statement S; +position p; +@@ + + x = (T)pci_alloc_consistent@p(E2,E1,E3); + if ((x==NULL) || ...) S + memset((T2)x,0,E1); + +@script:python depends on org@ +p << r8.p; +x << r8.x; +@@ + +msg="%s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << r8.p; +x << r8.x; +@@ + +msg="WARNING: pci_zalloc_consistent should be used for %s, instead of pci_alloc_consistent/memset" % (x) +coccilib.report.print_report(p[0], msg) +//----------------------------------------------------------------- +@r9 depends on org || report@ +type T, T2; +expression x; +expression E1,E2,E3; +statement S; +position p; +@@ + + x = (T)kvmalloc_node@p(E1,E2,E3); + if ((x==NULL) || ...) S + memset((T2)x,0,E1); + +@script:python depends on org@ +p << r9.p; +x << r9.x; +@@ + +msg="%s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << r9.p; +x << r9.x; +@@ + +msg="WARNING: kvzalloc_node should be used for %s, instead of kvmalloc_node/memset" % (x) +coccilib.report.print_report(p[0], msg) diff --git a/scripts/coccinelle/api/memdup.cocci b/scripts/coccinelle/api/memdup.cocci index 3d1aa71b7579..1249b727644b 100644 --- a/scripts/coccinelle/api/memdup.cocci +++ b/scripts/coccinelle/api/memdup.cocci @@ -49,7 +49,6 @@ statement S; @@ * to = \(kmalloc@p\|kzalloc@p\)(size,flag); - to = kmemdup(from,size,flag); if (to==NULL || ...) S * memcpy(to, from, size); diff --git a/scripts/coccinelle/free/ifnullfree.cocci b/scripts/coccinelle/free/ifnullfree.cocci index 14a4cd98e83b..a70e123cb12b 100644 --- a/scripts/coccinelle/free/ifnullfree.cocci +++ b/scripts/coccinelle/free/ifnullfree.cocci @@ -55,5 +55,5 @@ cocci.print_main("NULL check before that freeing function is not needed", p) p << r.p; @@ -msg = "WARNING: NULL check before freeing functions like kfree, debugfs_remove, debugfs_remove_recursive or usb_free_urb is not needed. Maybe consider reorganizing relevant code to avoid passing NULL values." +msg = "WARNING: NULL check before some freeing functions is not needed." coccilib.report.print_report(p[0], msg) diff --git a/scripts/coccinelle/misc/array_size.cocci b/scripts/coccinelle/misc/array_size.cocci index 6ec05710b017..09520f0941f0 100644 --- a/scripts/coccinelle/misc/array_size.cocci +++ b/scripts/coccinelle/misc/array_size.cocci @@ -72,13 +72,13 @@ position p; (sizeof(E)@p /sizeof(T)) ) -@script:python depends on i&&org@ +@script:python depends on org@ p << r.p; @@ coccilib.org.print_todo(p[0], "WARNING should use ARRAY_SIZE") -@script:python depends on i&&report@ +@script:python depends on report@ p << r.p; @@ diff --git a/scripts/decodecode b/scripts/decodecode index 438120da1361..9cef558528aa 100755 --- a/scripts/decodecode +++ b/scripts/decodecode @@ -21,12 +21,24 @@ trap cleanup EXIT T=`mktemp` || die "cannot create temp file" code= +cont= while read i ; do case "$i" in *Code:*) code=$i + cont=yes + ;; +*) + [ -n "$cont" ] && { + xdump="$(echo $i | grep '^[[:xdigit:]<>[:space:]]\+$')" + if [ -n "$xdump" ]; then + code="$code $xdump" + else + cont= + fi + } ;; esac @@ -59,6 +71,14 @@ disas() { ${CROSS_COMPILE}strip $1.o fi + if [ "$ARCH" = "arm64" ]; then + if [ $width -eq 4 ]; then + type=inst + fi + + ${CROSS_COMPILE}strip $1.o + fi + ${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \ grep -v "/tmp\|Disassembly\|\.text\|^$" > $1.dis 2>&1 } diff --git a/scripts/faddr2line b/scripts/faddr2line index 39e07d8574dd..7721d5b2b0c0 100755 --- a/scripts/faddr2line +++ b/scripts/faddr2line @@ -44,10 +44,10 @@ set -o errexit set -o nounset -READELF="${CROSS_COMPILE}readelf" -ADDR2LINE="${CROSS_COMPILE}addr2line" -SIZE="${CROSS_COMPILE}size" -NM="${CROSS_COMPILE}nm" +READELF="${CROSS_COMPILE:-}readelf" +ADDR2LINE="${CROSS_COMPILE:-}addr2line" +SIZE="${CROSS_COMPILE:-}size" +NM="${CROSS_COMPILE:-}nm" command -v awk >/dev/null 2>&1 || die "awk isn't installed" command -v ${READELF} >/dev/null 2>&1 || die "readelf isn't installed" diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py index 1bf949c43b76..f6ab3ccf698f 100644 --- a/scripts/gdb/linux/tasks.py +++ b/scripts/gdb/linux/tasks.py @@ -96,6 +96,8 @@ def get_thread_info(task): thread_info_addr = task.address + ia64_task_size thread_info = thread_info_addr.cast(thread_info_ptr_type) else: + if task.type.fields()[0].type == thread_info_type.get_type(): + return task['thread_info'] thread_info = task['stack'].cast(thread_info_ptr_type) return thread_info.dereference() diff --git a/scripts/genksyms/.gitignore b/scripts/genksyms/.gitignore index 86dc07a01b43..e7836b47f060 100644 --- a/scripts/genksyms/.gitignore +++ b/scripts/genksyms/.gitignore @@ -1,4 +1,3 @@ -*.hash.c *.lex.c *.tab.c *.tab.h diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 04fa71e058b7..2ba332b3fed7 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -999,7 +999,10 @@ static enum string_value_kind expr_parse_string(const char *str, switch (type) { case S_BOOLEAN: case S_TRISTATE: - return k_string; + val->s = !strcmp(str, "n") ? 0 : + !strcmp(str, "m") ? 1 : + !strcmp(str, "y") ? 2 : -1; + return k_signed; case S_INT: val->s = strtoll(str, &tail, 10); kind = k_signed; diff --git a/scripts/kernel-doc b/scripts/kernel-doc index bd29a92b4b48..fee8952037b1 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -48,16 +48,11 @@ Read C language source or header FILEs, extract embedded documentation comments, and print formatted documentation to standard output. The documentation comments are identified by "/**" opening comment mark. See -Documentation/kernel-doc-nano-HOWTO.txt for the documentation comment syntax. +Documentation/doc-guide/kernel-doc.rst for the documentation comment syntax. Output format selection (mutually exclusive): - -docbook Output DocBook format. - -html Output HTML format. - -html5 Output HTML5 format. - -list Output symbol list format. This is for use by docproc. -man Output troff manual page format. This is the default. -rst Output reStructuredText format. - -text Output plain text format. -none Do not output documentation, only warnings. Output selection (mutually exclusive): @@ -216,7 +211,7 @@ my $anon_struct_union = 0; my $type_constant = '\b``([^\`]+)``\b'; my $type_constant2 = '\%([-_\w]+)'; my $type_func = '(\w+)\(\)'; -my $type_param = '\@(\w+(\.\.\.)?)'; +my $type_param = '\@(\w*(\.\w+)*(\.\.\.)?)'; my $type_fp_param = '\@(\w+)\(\)'; # Special RST handling for func ptr params my $type_env = '(\$\w+)'; my $type_enum = '\&(enum\s*([_\w]+))'; @@ -225,84 +220,11 @@ my $type_typedef = '\&(typedef\s*([_\w]+))'; my $type_union = '\&(union\s*([_\w]+))'; my $type_member = '\&([_\w]+)(\.|->)([_\w]+)'; my $type_fallback = '\&([_\w]+)'; -my $type_enum_xml = '\&(enum\s*([_\w]+))'; -my $type_struct_xml = '\&(struct\s*([_\w]+))'; -my $type_typedef_xml = '\&(typedef\s*([_\w]+))'; -my $type_union_xml = '\&(union\s*([_\w]+))'; -my $type_member_xml = '\&([_\w]+)(\.|-\>)([_\w]+)'; -my $type_fallback_xml = '\&([_\w]+)'; my $type_member_func = $type_member . '\(\)'; # Output conversion substitutions. # One for each output format -# these work fairly well -my @highlights_html = ( - [$type_constant, "<i>\$1</i>"], - [$type_constant2, "<i>\$1</i>"], - [$type_func, "<b>\$1</b>"], - [$type_enum_xml, "<i>\$1</i>"], - [$type_struct_xml, "<i>\$1</i>"], - [$type_typedef_xml, "<i>\$1</i>"], - [$type_union_xml, "<i>\$1</i>"], - [$type_env, "<b><i>\$1</i></b>"], - [$type_param, "<tt><b>\$1</b></tt>"], - [$type_member_xml, "<tt><i>\$1</i>\$2\$3</tt>"], - [$type_fallback_xml, "<i>\$1</i>"] - ); -my $local_lt = "\\\\\\\\lt:"; -my $local_gt = "\\\\\\\\gt:"; -my $blankline_html = $local_lt . "p" . $local_gt; # was "<p>" - -# html version 5 -my @highlights_html5 = ( - [$type_constant, "<span class=\"const\">\$1</span>"], - [$type_constant2, "<span class=\"const\">\$1</span>"], - [$type_func, "<span class=\"func\">\$1</span>"], - [$type_enum_xml, "<span class=\"enum\">\$1</span>"], - [$type_struct_xml, "<span class=\"struct\">\$1</span>"], - [$type_typedef_xml, "<span class=\"typedef\">\$1</span>"], - [$type_union_xml, "<span class=\"union\">\$1</span>"], - [$type_env, "<span class=\"env\">\$1</span>"], - [$type_param, "<span class=\"param\">\$1</span>]"], - [$type_member_xml, "<span class=\"literal\"><span class=\"struct\">\$1</span>\$2<span class=\"member\">\$3</span></span>"], - [$type_fallback_xml, "<span class=\"struct\">\$1</span>"] - ); -my $blankline_html5 = $local_lt . "br /" . $local_gt; - -# XML, docbook format -my @highlights_xml = ( - ["([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>"], - [$type_constant, "<constant>\$1</constant>"], - [$type_constant2, "<constant>\$1</constant>"], - [$type_enum_xml, "<type>\$1</type>"], - [$type_struct_xml, "<structname>\$1</structname>"], - [$type_typedef_xml, "<type>\$1</type>"], - [$type_union_xml, "<structname>\$1</structname>"], - [$type_param, "<parameter>\$1</parameter>"], - [$type_func, "<function>\$1</function>"], - [$type_env, "<envar>\$1</envar>"], - [$type_member_xml, "<literal><structname>\$1</structname>\$2<structfield>\$3</structfield></literal>"], - [$type_fallback_xml, "<structname>\$1</structname>"] - ); -my $blankline_xml = $local_lt . "/para" . $local_gt . $local_lt . "para" . $local_gt . "\n"; - -# gnome, docbook format -my @highlights_gnome = ( - [$type_constant, "<replaceable class=\"option\">\$1</replaceable>"], - [$type_constant2, "<replaceable class=\"option\">\$1</replaceable>"], - [$type_func, "<function>\$1</function>"], - [$type_enum, "<type>\$1</type>"], - [$type_struct, "<structname>\$1</structname>"], - [$type_typedef, "<type>\$1</type>"], - [$type_union, "<structname>\$1</structname>"], - [$type_env, "<envar>\$1</envar>"], - [$type_param, "<parameter>\$1</parameter>" ], - [$type_member, "<literal><structname>\$1</structname>\$2<structfield>\$3</structfield></literal>"], - [$type_fallback, "<structname>\$1</structname>"] - ); -my $blankline_gnome = "</para><para>\n"; - # these are pretty rough my @highlights_man = ( [$type_constant, "\$1"], @@ -318,21 +240,6 @@ my @highlights_man = ( ); my $blankline_man = ""; -# text-mode -my @highlights_text = ( - [$type_constant, "\$1"], - [$type_constant2, "\$1"], - [$type_func, "\$1"], - [$type_enum, "\$1"], - [$type_struct, "\$1"], - [$type_typedef, "\$1"], - [$type_union, "\$1"], - [$type_param, "\$1"], - [$type_member, "\$1\$2\$3"], - [$type_fallback, "\$1"] - ); -my $blankline_text = ""; - # rst-mode my @highlights_rst = ( [$type_constant, "``\$1``"], @@ -352,21 +259,6 @@ my @highlights_rst = ( ); my $blankline_rst = "\n"; -# list mode -my @highlights_list = ( - [$type_constant, "\$1"], - [$type_constant2, "\$1"], - [$type_func, "\$1"], - [$type_enum, "\$1"], - [$type_struct, "\$1"], - [$type_typedef, "\$1"], - [$type_union, "\$1"], - [$type_param, "\$1"], - [$type_member, "\$1"], - [$type_fallback, "\$1"] - ); -my $blankline_list = ""; - # read arguments if ($#ARGV == -1) { usage(); @@ -376,12 +268,12 @@ my $kernelversion; my $dohighlight = ""; my $verbose = 0; -my $output_mode = "man"; +my $output_mode = "rst"; my $output_preformatted = 0; my $no_doc_sections = 0; my $enable_lineno = 0; -my @highlights = @highlights_man; -my $blankline = $blankline_man; +my @highlights = @highlights_rst; +my $blankline = $blankline_rst; my $modulename = "Kernel API"; use constant { @@ -499,71 +391,51 @@ my $undescribed = "-- undescribed --"; reset_state(); -while ($ARGV[0] =~ m/^-(.*)/) { - my $cmd = shift @ARGV; - if ($cmd eq "-html") { - $output_mode = "html"; - @highlights = @highlights_html; - $blankline = $blankline_html; - } elsif ($cmd eq "-html5") { - $output_mode = "html5"; - @highlights = @highlights_html5; - $blankline = $blankline_html5; - } elsif ($cmd eq "-man") { +while ($ARGV[0] =~ m/^--?(.*)/) { + my $cmd = $1; + shift @ARGV; + if ($cmd eq "man") { $output_mode = "man"; @highlights = @highlights_man; $blankline = $blankline_man; - } elsif ($cmd eq "-text") { - $output_mode = "text"; - @highlights = @highlights_text; - $blankline = $blankline_text; - } elsif ($cmd eq "-rst") { + } elsif ($cmd eq "rst") { $output_mode = "rst"; @highlights = @highlights_rst; $blankline = $blankline_rst; - } elsif ($cmd eq "-docbook") { - $output_mode = "xml"; - @highlights = @highlights_xml; - $blankline = $blankline_xml; - } elsif ($cmd eq "-list") { - $output_mode = "list"; - @highlights = @highlights_list; - $blankline = $blankline_list; - } elsif ($cmd eq "-gnome") { - $output_mode = "gnome"; - @highlights = @highlights_gnome; - $blankline = $blankline_gnome; - } elsif ($cmd eq "-none") { + } elsif ($cmd eq "none") { $output_mode = "none"; - } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document + } elsif ($cmd eq "module") { # not needed for XML, inherits from calling document $modulename = shift @ARGV; - } elsif ($cmd eq "-function") { # to only output specific functions + } elsif ($cmd eq "function") { # to only output specific functions $output_selection = OUTPUT_INCLUDE; $function = shift @ARGV; $function_table{$function} = 1; - } elsif ($cmd eq "-nofunction") { # output all except specific functions + } elsif ($cmd eq "nofunction") { # output all except specific functions $output_selection = OUTPUT_EXCLUDE; $function = shift @ARGV; $function_table{$function} = 1; - } elsif ($cmd eq "-export") { # only exported symbols + } elsif ($cmd eq "export") { # only exported symbols $output_selection = OUTPUT_EXPORTED; %function_table = (); - } elsif ($cmd eq "-internal") { # only non-exported symbols + } elsif ($cmd eq "internal") { # only non-exported symbols $output_selection = OUTPUT_INTERNAL; %function_table = (); - } elsif ($cmd eq "-export-file") { + } elsif ($cmd eq "export-file") { my $file = shift @ARGV; push(@export_file_list, $file); - } elsif ($cmd eq "-v") { + } elsif ($cmd eq "v") { $verbose = 1; - } elsif (($cmd eq "-h") || ($cmd eq "--help")) { + } elsif (($cmd eq "h") || ($cmd eq "help")) { usage(); - } elsif ($cmd eq '-no-doc-sections') { + } elsif ($cmd eq 'no-doc-sections') { $no_doc_sections = 1; - } elsif ($cmd eq '-enable-lineno') { + } elsif ($cmd eq 'enable-lineno') { $enable_lineno = 1; - } elsif ($cmd eq '-show-not-found') { + } elsif ($cmd eq 'show-not-found') { $show_not_found = 1; + } else { + # Unknown argument + usage(); } } @@ -670,22 +542,11 @@ sub output_highlight { # confess "output_highlight got called with no args?\n"; # } - if ($output_mode eq "html" || $output_mode eq "html5" || - $output_mode eq "xml") { - $contents = local_unescape($contents); - # convert data read & converted thru xml_escape() into &xyz; format: - $contents =~ s/\\\\\\/\&/g; - } # print STDERR "contents b4:$contents\n"; eval $dohighlight; die $@ if $@; # print STDERR "contents af:$contents\n"; -# strip whitespaces when generating html5 - if ($output_mode eq "html5") { - $contents =~ s/^\s+//; - $contents =~ s/\s+$//; - } foreach $line (split "\n", $contents) { if (! $output_preformatted) { $line =~ s/^\s*//; @@ -706,817 +567,6 @@ sub output_highlight { } } -# output sections in html -sub output_section_html(%) { - my %args = %{$_[0]}; - my $section; - - foreach $section (@{$args{'sectionlist'}}) { - print "<h3>$section</h3>\n"; - print "<blockquote>\n"; - output_highlight($args{'sections'}{$section}); - print "</blockquote>\n"; - } -} - -# output enum in html -sub output_enum_html(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - print "<h2>enum " . $args{'enum'} . "</h2>\n"; - - print "<b>enum " . $args{'enum'} . "</b> {<br>\n"; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - print " <b>" . $parameter . "</b>"; - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ",\n"; - } - print "<br>"; - } - print "};<br>\n"; - - print "<h3>Constants</h3>\n"; - print "<dl>\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - print "<dt><b>" . $parameter . "</b>\n"; - print "<dd>"; - output_highlight($args{'parameterdescs'}{$parameter}); - } - print "</dl>\n"; - output_section_html(@_); - print "<hr>\n"; -} - -# output typedef in html -sub output_typedef_html(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - print "<h2>typedef " . $args{'typedef'} . "</h2>\n"; - - print "<b>typedef " . $args{'typedef'} . "</b>\n"; - output_section_html(@_); - print "<hr>\n"; -} - -# output struct in html -sub output_struct_html(%) { - my %args = %{$_[0]}; - my ($parameter); - - print "<h2>" . $args{'type'} . " " . $args{'struct'} . " - " . $args{'purpose'} . "</h2>\n"; - print "<b>" . $args{'type'} . " " . $args{'struct'} . "</b> {<br>\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - if ($parameter =~ /^#/) { - print "$parameter<br>\n"; - next; - } - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print " <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>\n"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print " <i>$1</i> <b>$parameter</b>$2;<br>\n"; - } else { - print " <i>$type</i> <b>$parameter</b>;<br>\n"; - } - } - print "};<br>\n"; - - print "<h3>Members</h3>\n"; - print "<dl>\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - ($parameter =~ /^#/) && next; - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - print "<dt><b>" . $parameter . "</b>\n"; - print "<dd>"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - } - print "</dl>\n"; - output_section_html(@_); - print "<hr>\n"; -} - -# output function in html -sub output_function_html(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - - print "<h2>" . $args{'function'} . " - " . $args{'purpose'} . "</h2>\n"; - print "<i>" . $args{'functiontype'} . "</i>\n"; - print "<b>" . $args{'function'} . "</b>\n"; - print "("; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print "<i>$1</i><b>$parameter</b>) <i>($2)</i>"; - } else { - print "<i>" . $type . "</i> <b>" . $parameter . "</b>"; - } - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ",\n"; - } - } - print ")\n"; - - print "<h3>Arguments</h3>\n"; - print "<dl>\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - print "<dt><b>" . $parameter . "</b>\n"; - print "<dd>"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - } - print "</dl>\n"; - output_section_html(@_); - print "<hr>\n"; -} - -# output DOC: block header in html -sub output_blockhead_html(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - - foreach $section (@{$args{'sectionlist'}}) { - print "<h3>$section</h3>\n"; - print "<ul>\n"; - output_highlight($args{'sections'}{$section}); - print "</ul>\n"; - } - print "<hr>\n"; -} - -# output sections in html5 -sub output_section_html5(%) { - my %args = %{$_[0]}; - my $section; - - foreach $section (@{$args{'sectionlist'}}) { - print "<section>\n"; - print "<h1>$section</h1>\n"; - print "<p>\n"; - output_highlight($args{'sections'}{$section}); - print "</p>\n"; - print "</section>\n"; - } -} - -# output enum in html5 -sub output_enum_html5(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - my $html5id; - - $html5id = $args{'enum'}; - $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; - print "<article class=\"enum\" id=\"enum:". $html5id . "\">"; - print "<h1>enum " . $args{'enum'} . "</h1>\n"; - print "<ol class=\"code\">\n"; - print "<li>"; - print "<span class=\"keyword\">enum</span> "; - print "<span class=\"identifier\">" . $args{'enum'} . "</span> {"; - print "</li>\n"; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - print "<li class=\"indent\">"; - print "<span class=\"param\">" . $parameter . "</span>"; - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ","; - } - print "</li>\n"; - } - print "<li>};</li>\n"; - print "</ol>\n"; - - print "<section>\n"; - print "<h1>Constants</h1>\n"; - print "<dl>\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - print "<dt>" . $parameter . "</dt>\n"; - print "<dd>"; - output_highlight($args{'parameterdescs'}{$parameter}); - print "</dd>\n"; - } - print "</dl>\n"; - print "</section>\n"; - output_section_html5(@_); - print "</article>\n"; -} - -# output typedef in html5 -sub output_typedef_html5(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - my $html5id; - - $html5id = $args{'typedef'}; - $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; - print "<article class=\"typedef\" id=\"typedef:" . $html5id . "\">\n"; - print "<h1>typedef " . $args{'typedef'} . "</h1>\n"; - - print "<ol class=\"code\">\n"; - print "<li>"; - print "<span class=\"keyword\">typedef</span> "; - print "<span class=\"identifier\">" . $args{'typedef'} . "</span>"; - print "</li>\n"; - print "</ol>\n"; - output_section_html5(@_); - print "</article>\n"; -} - -# output struct in html5 -sub output_struct_html5(%) { - my %args = %{$_[0]}; - my ($parameter); - my $html5id; - - $html5id = $args{'struct'}; - $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; - print "<article class=\"struct\" id=\"struct:" . $html5id . "\">\n"; - print "<hgroup>\n"; - print "<h1>" . $args{'type'} . " " . $args{'struct'} . "</h1>"; - print "<h2>". $args{'purpose'} . "</h2>\n"; - print "</hgroup>\n"; - print "<ol class=\"code\">\n"; - print "<li>"; - print "<span class=\"type\">" . $args{'type'} . "</span> "; - print "<span class=\"identifier\">" . $args{'struct'} . "</span> {"; - print "</li>\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - print "<li class=\"indent\">"; - if ($parameter =~ /^#/) { - print "<span class=\"param\">" . $parameter ."</span>\n"; - print "</li>\n"; - next; - } - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print "<span class=\"type\">$1</span> "; - print "<span class=\"param\">$parameter</span>"; - print "<span class=\"type\">)</span> "; - print "(<span class=\"args\">$2</span>);"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print "<span class=\"type\">$1</span> "; - print "<span class=\"param\">$parameter</span>"; - print "<span class=\"bits\">$2</span>;"; - } else { - print "<span class=\"type\">$type</span> "; - print "<span class=\"param\">$parameter</span>;"; - } - print "</li>\n"; - } - print "<li>};</li>\n"; - print "</ol>\n"; - - print "<section>\n"; - print "<h1>Members</h1>\n"; - print "<dl>\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - ($parameter =~ /^#/) && next; - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - print "<dt>" . $parameter . "</dt>\n"; - print "<dd>"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print "</dd>\n"; - } - print "</dl>\n"; - print "</section>\n"; - output_section_html5(@_); - print "</article>\n"; -} - -# output function in html5 -sub output_function_html5(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - my $html5id; - - $html5id = $args{'function'}; - $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; - print "<article class=\"function\" id=\"func:". $html5id . "\">\n"; - print "<hgroup>\n"; - print "<h1>" . $args{'function'} . "</h1>"; - print "<h2>" . $args{'purpose'} . "</h2>\n"; - print "</hgroup>\n"; - print "<ol class=\"code\">\n"; - print "<li>"; - print "<span class=\"type\">" . $args{'functiontype'} . "</span> "; - print "<span class=\"identifier\">" . $args{'function'} . "</span> ("; - print "</li>"; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - print "<li class=\"indent\">"; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print "<span class=\"type\">$1</span> "; - print "<span class=\"param\">$parameter</span>"; - print "<span class=\"type\">)</span> "; - print "(<span class=\"args\">$2</span>)"; - } else { - print "<span class=\"type\">$type</span> "; - print "<span class=\"param\">$parameter</span>"; - } - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ","; - } - print "</li>\n"; - } - print "<li>)</li>\n"; - print "</ol>\n"; - - print "<section>\n"; - print "<h1>Arguments</h1>\n"; - print "<p>\n"; - print "<dl>\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - print "<dt>" . $parameter . "</dt>\n"; - print "<dd>"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print "</dd>\n"; - } - print "</dl>\n"; - print "</section>\n"; - output_section_html5(@_); - print "</article>\n"; -} - -# output DOC: block header in html5 -sub output_blockhead_html5(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - my $html5id; - - foreach $section (@{$args{'sectionlist'}}) { - $html5id = $section; - $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; - print "<article class=\"doc\" id=\"doc:". $html5id . "\">\n"; - print "<h1>$section</h1>\n"; - print "<p>\n"; - output_highlight($args{'sections'}{$section}); - print "</p>\n"; - } - print "</article>\n"; -} - -sub output_section_xml(%) { - my %args = %{$_[0]}; - my $section; - # print out each section - $lineprefix=" "; - foreach $section (@{$args{'sectionlist'}}) { - print "<refsect1>\n"; - print "<title>$section</title>\n"; - if ($section =~ m/EXAMPLE/i) { - print "<informalexample><programlisting>\n"; - $output_preformatted = 1; - } else { - print "<para>\n"; - } - output_highlight($args{'sections'}{$section}); - $output_preformatted = 0; - if ($section =~ m/EXAMPLE/i) { - print "</programlisting></informalexample>\n"; - } else { - print "</para>\n"; - } - print "</refsect1>\n"; - } -} - -# output function in XML DocBook -sub output_function_xml(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - my $id; - - $id = "API-" . $args{'function'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - print "<refentry id=\"$id\">\n"; - print "<refentryinfo>\n"; - print " <title>LINUX</title>\n"; - print " <productname>Kernel Hackers Manual</productname>\n"; - print " <date>$man_date</date>\n"; - print "</refentryinfo>\n"; - print "<refmeta>\n"; - print " <refentrytitle><phrase>" . $args{'function'} . "</phrase></refentrytitle>\n"; - print " <manvolnum>9</manvolnum>\n"; - print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n"; - print "</refmeta>\n"; - print "<refnamediv>\n"; - print " <refname>" . $args{'function'} . "</refname>\n"; - print " <refpurpose>\n"; - print " "; - output_highlight ($args{'purpose'}); - print " </refpurpose>\n"; - print "</refnamediv>\n"; - - print "<refsynopsisdiv>\n"; - print " <title>Synopsis</title>\n"; - print " <funcsynopsis><funcprototype>\n"; - print " <funcdef>" . $args{'functiontype'} . " "; - print "<function>" . $args{'function'} . " </function></funcdef>\n"; - - $count = 0; - if ($#{$args{'parameterlist'}} >= 0) { - foreach $parameter (@{$args{'parameterlist'}}) { - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print " <paramdef>$1<parameter>$parameter</parameter>)\n"; - print " <funcparams>$2</funcparams></paramdef>\n"; - } else { - print " <paramdef>" . $type; - print " <parameter>$parameter</parameter></paramdef>\n"; - } - } - } else { - print " <void/>\n"; - } - print " </funcprototype></funcsynopsis>\n"; - print "</refsynopsisdiv>\n"; - - # print parameters - print "<refsect1>\n <title>Arguments</title>\n"; - if ($#{$args{'parameterlist'}} >= 0) { - print " <variablelist>\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - $type = $args{'parametertypes'}{$parameter}; - - print " <varlistentry>\n <term><parameter>$type $parameter</parameter></term>\n"; - print " <listitem>\n <para>\n"; - $lineprefix=" "; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print " </para>\n </listitem>\n </varlistentry>\n"; - } - print " </variablelist>\n"; - } else { - print " <para>\n None\n </para>\n"; - } - print "</refsect1>\n"; - - output_section_xml(@_); - print "</refentry>\n\n"; -} - -# output struct in XML DocBook -sub output_struct_xml(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $id; - - $id = "API-struct-" . $args{'struct'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - print "<refentry id=\"$id\">\n"; - print "<refentryinfo>\n"; - print " <title>LINUX</title>\n"; - print " <productname>Kernel Hackers Manual</productname>\n"; - print " <date>$man_date</date>\n"; - print "</refentryinfo>\n"; - print "<refmeta>\n"; - print " <refentrytitle><phrase>" . $args{'type'} . " " . $args{'struct'} . "</phrase></refentrytitle>\n"; - print " <manvolnum>9</manvolnum>\n"; - print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n"; - print "</refmeta>\n"; - print "<refnamediv>\n"; - print " <refname>" . $args{'type'} . " " . $args{'struct'} . "</refname>\n"; - print " <refpurpose>\n"; - print " "; - output_highlight ($args{'purpose'}); - print " </refpurpose>\n"; - print "</refnamediv>\n"; - - print "<refsynopsisdiv>\n"; - print " <title>Synopsis</title>\n"; - print " <programlisting>\n"; - print $args{'type'} . " " . $args{'struct'} . " {\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - if ($parameter =~ /^#/) { - my $prm = $parameter; - # convert data read & converted thru xml_escape() into &xyz; format: - # This allows us to have #define macros interspersed in a struct. - $prm =~ s/\\\\\\/\&/g; - print "$prm\n"; - next; - } - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - defined($args{'parameterdescs'}{$parameter_name}) || next; - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print " $1 $parameter) ($2);\n"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print " $1 $parameter$2;\n"; - } else { - print " " . $type . " " . $parameter . ";\n"; - } - } - print "};"; - print " </programlisting>\n"; - print "</refsynopsisdiv>\n"; - - print " <refsect1>\n"; - print " <title>Members</title>\n"; - - if ($#{$args{'parameterlist'}} >= 0) { - print " <variablelist>\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - ($parameter =~ /^#/) && next; - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - defined($args{'parameterdescs'}{$parameter_name}) || next; - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - print " <varlistentry>"; - print " <term><literal>$type $parameter</literal></term>\n"; - print " <listitem><para>\n"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print " </para></listitem>\n"; - print " </varlistentry>\n"; - } - print " </variablelist>\n"; - } else { - print " <para>\n None\n </para>\n"; - } - print " </refsect1>\n"; - - output_section_xml(@_); - - print "</refentry>\n\n"; -} - -# output enum in XML DocBook -sub output_enum_xml(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - my $id; - - $id = "API-enum-" . $args{'enum'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - print "<refentry id=\"$id\">\n"; - print "<refentryinfo>\n"; - print " <title>LINUX</title>\n"; - print " <productname>Kernel Hackers Manual</productname>\n"; - print " <date>$man_date</date>\n"; - print "</refentryinfo>\n"; - print "<refmeta>\n"; - print " <refentrytitle><phrase>enum " . $args{'enum'} . "</phrase></refentrytitle>\n"; - print " <manvolnum>9</manvolnum>\n"; - print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n"; - print "</refmeta>\n"; - print "<refnamediv>\n"; - print " <refname>enum " . $args{'enum'} . "</refname>\n"; - print " <refpurpose>\n"; - print " "; - output_highlight ($args{'purpose'}); - print " </refpurpose>\n"; - print "</refnamediv>\n"; - - print "<refsynopsisdiv>\n"; - print " <title>Synopsis</title>\n"; - print " <programlisting>\n"; - print "enum " . $args{'enum'} . " {\n"; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - print " $parameter"; - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ","; - } - print "\n"; - } - print "};"; - print " </programlisting>\n"; - print "</refsynopsisdiv>\n"; - - print "<refsect1>\n"; - print " <title>Constants</title>\n"; - print " <variablelist>\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - print " <varlistentry>"; - print " <term>$parameter</term>\n"; - print " <listitem><para>\n"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print " </para></listitem>\n"; - print " </varlistentry>\n"; - } - print " </variablelist>\n"; - print "</refsect1>\n"; - - output_section_xml(@_); - - print "</refentry>\n\n"; -} - -# output typedef in XML DocBook -sub output_typedef_xml(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $id; - - $id = "API-typedef-" . $args{'typedef'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - print "<refentry id=\"$id\">\n"; - print "<refentryinfo>\n"; - print " <title>LINUX</title>\n"; - print " <productname>Kernel Hackers Manual</productname>\n"; - print " <date>$man_date</date>\n"; - print "</refentryinfo>\n"; - print "<refmeta>\n"; - print " <refentrytitle><phrase>typedef " . $args{'typedef'} . "</phrase></refentrytitle>\n"; - print " <manvolnum>9</manvolnum>\n"; - print "</refmeta>\n"; - print "<refnamediv>\n"; - print " <refname>typedef " . $args{'typedef'} . "</refname>\n"; - print " <refpurpose>\n"; - print " "; - output_highlight ($args{'purpose'}); - print " </refpurpose>\n"; - print "</refnamediv>\n"; - - print "<refsynopsisdiv>\n"; - print " <title>Synopsis</title>\n"; - print " <synopsis>typedef " . $args{'typedef'} . ";</synopsis>\n"; - print "</refsynopsisdiv>\n"; - - output_section_xml(@_); - - print "</refentry>\n\n"; -} - -# output in XML DocBook -sub output_blockhead_xml(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - - my $id = $args{'module'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - # print out each section - $lineprefix=" "; - foreach $section (@{$args{'sectionlist'}}) { - if (!$args{'content-only'}) { - print "<refsect1>\n <title>$section</title>\n"; - } - if ($section =~ m/EXAMPLE/i) { - print "<example><para>\n"; - $output_preformatted = 1; - } else { - print "<para>\n"; - } - output_highlight($args{'sections'}{$section}); - $output_preformatted = 0; - if ($section =~ m/EXAMPLE/i) { - print "</para></example>\n"; - } else { - print "</para>"; - } - if (!$args{'content-only'}) { - print "\n</refsect1>\n"; - } - } - - print "\n\n"; -} - -# output in XML DocBook -sub output_function_gnome { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - my $id; - - $id = $args{'module'} . "-" . $args{'function'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - print "<sect2>\n"; - print " <title id=\"$id\">" . $args{'function'} . "</title>\n"; - - print " <funcsynopsis>\n"; - print " <funcdef>" . $args{'functiontype'} . " "; - print "<function>" . $args{'function'} . " "; - print "</function></funcdef>\n"; - - $count = 0; - if ($#{$args{'parameterlist'}} >= 0) { - foreach $parameter (@{$args{'parameterlist'}}) { - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print " <paramdef>$1 <parameter>$parameter</parameter>)\n"; - print " <funcparams>$2</funcparams></paramdef>\n"; - } else { - print " <paramdef>" . $type; - print " <parameter>$parameter</parameter></paramdef>\n"; - } - } - } else { - print " <void>\n"; - } - print " </funcsynopsis>\n"; - if ($#{$args{'parameterlist'}} >= 0) { - print " <informaltable pgwide=\"1\" frame=\"none\" role=\"params\">\n"; - print "<tgroup cols=\"2\">\n"; - print "<colspec colwidth=\"2*\">\n"; - print "<colspec colwidth=\"8*\">\n"; - print "<tbody>\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - print " <row><entry align=\"right\"><parameter>$parameter</parameter></entry>\n"; - print " <entry>\n"; - $lineprefix=" "; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print " </entry></row>\n"; - } - print " </tbody></tgroup></informaltable>\n"; - } else { - print " <para>\n None\n </para>\n"; - } - - # print out each section - $lineprefix=" "; - foreach $section (@{$args{'sectionlist'}}) { - print "<simplesect>\n <title>$section</title>\n"; - if ($section =~ m/EXAMPLE/i) { - print "<example><programlisting>\n"; - $output_preformatted = 1; - } else { - } - print "<para>\n"; - output_highlight($args{'sections'}{$section}); - $output_preformatted = 0; - print "</para>\n"; - if ($section =~ m/EXAMPLE/i) { - print "</programlisting></example>\n"; - } else { - } - print " </simplesect>\n"; - } - - print "</sect2>\n\n"; -} - ## # output function in man sub output_function_man(%) { @@ -1620,32 +670,12 @@ sub output_struct_man(%) { print ".SH NAME\n"; print $args{'type'} . " " . $args{'struct'} . " \\- " . $args{'purpose'} . "\n"; + my $declaration = $args{'definition'}; + $declaration =~ s/\t/ /g; + $declaration =~ s/\n/"\n.br\n.BI \"/g; print ".SH SYNOPSIS\n"; print $args{'type'} . " " . $args{'struct'} . " {\n.br\n"; - - foreach my $parameter (@{$args{'parameterlist'}}) { - if ($parameter =~ /^#/) { - print ".BI \"$parameter\"\n.br\n"; - next; - } - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print ".BI \" " . $1 . "\" " . $parameter . " \") (" . $2 . ")" . "\"\n;\n"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print ".BI \" " . $1 . "\ \" " . $parameter . $2 . " \"" . "\"\n;\n"; - } else { - $type =~ s/([^\*])$/$1 /; - print ".BI \" " . $type . "\" " . $parameter . " \"" . "\"\n;\n"; - } - print "\n.br\n"; - } - print "};\n.br\n"; + print ".BI \"$declaration\n};\n.br\n\n"; print ".SH Members\n"; foreach $parameter (@{$args{'parameterlist'}}) { @@ -1695,161 +725,6 @@ sub output_blockhead_man(%) { } ## -# output in text -sub output_function_text(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $start; - - print "Name:\n\n"; - print $args{'function'} . " - " . $args{'purpose'} . "\n"; - - print "\nSynopsis:\n\n"; - if ($args{'functiontype'} ne "") { - $start = $args{'functiontype'} . " " . $args{'function'} . " ("; - } else { - $start = $args{'function'} . " ("; - } - print $start; - - my $count = 0; - foreach my $parameter (@{$args{'parameterlist'}}) { - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print $1 . $parameter . ") (" . $2; - } else { - print $type . " " . $parameter; - } - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ",\n"; - print " " x length($start); - } else { - print ");\n\n"; - } - } - - print "Arguments:\n\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - print $parameter . "\n\t" . $args{'parameterdescs'}{$parameter_name} . "\n"; - } - output_section_text(@_); -} - -#output sections in text -sub output_section_text(%) { - my %args = %{$_[0]}; - my $section; - - print "\n"; - foreach $section (@{$args{'sectionlist'}}) { - print "$section:\n\n"; - output_highlight($args{'sections'}{$section}); - } - print "\n\n"; -} - -# output enum in text -sub output_enum_text(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - print "Enum:\n\n"; - - print "enum " . $args{'enum'} . " - " . $args{'purpose'} . "\n\n"; - print "enum " . $args{'enum'} . " {\n"; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - print "\t$parameter"; - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ","; - } - print "\n"; - } - print "};\n\n"; - - print "Constants:\n\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - print "$parameter\n\t"; - print $args{'parameterdescs'}{$parameter} . "\n"; - } - - output_section_text(@_); -} - -# output typedef in text -sub output_typedef_text(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - print "Typedef:\n\n"; - - print "typedef " . $args{'typedef'} . " - " . $args{'purpose'} . "\n"; - output_section_text(@_); -} - -# output struct as text -sub output_struct_text(%) { - my %args = %{$_[0]}; - my ($parameter); - - print $args{'type'} . " " . $args{'struct'} . " - " . $args{'purpose'} . "\n\n"; - print $args{'type'} . " " . $args{'struct'} . " {\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - if ($parameter =~ /^#/) { - print "$parameter\n"; - next; - } - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print "\t$1 $parameter) ($2);\n"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print "\t$1 $parameter$2;\n"; - } else { - print "\t" . $type . " " . $parameter . ";\n"; - } - } - print "};\n\n"; - - print "Members:\n\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - ($parameter =~ /^#/) && next; - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - print "$parameter\n\t"; - print $args{'parameterdescs'}{$parameter_name} . "\n"; - } - print "\n"; - output_section_text(@_); -} - -sub output_blockhead_text(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - - foreach $section (@{$args{'sectionlist'}}) { - print " $section:\n"; - print " -> "; - output_highlight($args{'sections'}{$section}); - } -} - -## # output in restructured text # @@ -2038,29 +913,9 @@ sub output_struct_rst(%) { print "**Definition**\n\n"; print "::\n\n"; - print " " . $args{'type'} . " " . $args{'struct'} . " {\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - if ($parameter =~ /^#/) { - print " " . "$parameter\n"; - next; - } - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print " $1 $parameter) ($2);\n"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print " $1 $parameter$2;\n"; - } else { - print " " . $type . " " . $parameter . ";\n"; - } - } - print " };\n\n"; + my $declaration = $args{'definition'}; + $declaration =~ s/\t/ /g; + print " " . $args{'type'} . " " . $args{'struct'} . " {\n$declaration };\n\n"; print "**Members**\n\n"; $lineprefix = " "; @@ -2083,44 +938,6 @@ sub output_struct_rst(%) { output_section_rst(@_); } - -## list mode output functions - -sub output_function_list(%) { - my %args = %{$_[0]}; - - print $args{'function'} . "\n"; -} - -# output enum in list -sub output_enum_list(%) { - my %args = %{$_[0]}; - print $args{'enum'} . "\n"; -} - -# output typedef in list -sub output_typedef_list(%) { - my %args = %{$_[0]}; - print $args{'typedef'} . "\n"; -} - -# output struct as list -sub output_struct_list(%) { - my %args = %{$_[0]}; - - print $args{'struct'} . "\n"; -} - -sub output_blockhead_list(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - - foreach $section (@{$args{'sectionlist'}}) { - print "DOC: $section\n"; - } -} - - ## none mode output functions sub output_function_none(%) { @@ -2186,39 +1003,128 @@ sub dump_union($$) { sub dump_struct($$) { my $x = shift; my $file = shift; - my $nested; if ($x =~ /(struct|union)\s+(\w+)\s*{(.*)}/) { my $decl_type = $1; $declaration_name = $2; my $members = $3; - # ignore embedded structs or unions - $members =~ s/({.*})//g; - $nested = $1; - # ignore members marked private: $members =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gosi; $members =~ s/\/\*\s*private:.*//gosi; # strip comments: $members =~ s/\/\*.*?\*\///gos; - $nested =~ s/\/\*.*?\*\///gos; # strip attributes $members =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//i; $members =~ s/__aligned\s*\([^;]*\)//gos; $members =~ s/\s*CRYPTO_MINALIGN_ATTR//gos; # replace DECLARE_BITMAP - $members =~ s/DECLARE_BITMAP\s*\(([^,)]+), ([^,)]+)\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos; + $members =~ s/DECLARE_BITMAP\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos; # replace DECLARE_HASHTABLE - $members =~ s/DECLARE_HASHTABLE\s*\(([^,)]+), ([^,)]+)\)/unsigned long $1\[1 << (($2) - 1)\]/gos; - - create_parameterlist($members, ';', $file); - check_sections($file, $declaration_name, $decl_type, $sectcheck, $struct_actual, $nested); - + $members =~ s/DECLARE_HASHTABLE\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[1 << (($2) - 1)\]/gos; + # replace DECLARE_KFIFO + $members =~ s/DECLARE_KFIFO\s*\(([^,)]+),\s*([^,)]+),\s*([^,)]+)\)/$2 \*$1/gos; + # replace DECLARE_KFIFO_PTR + $members =~ s/DECLARE_KFIFO_PTR\s*\(([^,)]+),\s*([^,)]+)\)/$2 \*$1/gos; + + my $declaration = $members; + + # Split nested struct/union elements as newer ones + while ($members =~ m/(struct|union)([^\{\};]+)\{([^\{\}]*)\}([^\{\}\;]*)\;/) { + my $newmember; + my $maintype = $1; + my $ids = $4; + my $content = $3; + foreach my $id(split /,/, $ids) { + $newmember .= "$maintype $id; "; + + $id =~ s/[:\[].*//; + $id =~ s/^\s*\**(\S+)\s*/$1/; + foreach my $arg (split /;/, $content) { + next if ($arg =~ m/^\s*$/); + if ($arg =~ m/^([^\(]+\(\*?\s*)([\w\.]*)(\s*\).*)/) { + # pointer-to-function + my $type = $1; + my $name = $2; + my $extra = $3; + next if (!$name); + if ($id =~ m/^\s*$/) { + # anonymous struct/union + $newmember .= "$type$name$extra; "; + } else { + $newmember .= "$type$id.$name$extra; "; + } + } else { + my $type; + my $names; + $arg =~ s/^\s+//; + $arg =~ s/\s+$//; + # Handle bitmaps + $arg =~ s/:\s*\d+\s*//g; + # Handle arrays + $arg =~ s/\[\S+\]//g; + # The type may have multiple words, + # and multiple IDs can be defined, like: + # const struct foo, *bar, foobar + # So, we remove spaces when parsing the + # names, in order to match just names + # and commas for the names + $arg =~ s/\s*,\s*/,/g; + if ($arg =~ m/(.*)\s+([\S+,]+)/) { + $type = $1; + $names = $2; + } else { + $newmember .= "$arg; "; + next; + } + foreach my $name (split /,/, $names) { + $name =~ s/^\s*\**(\S+)\s*/$1/; + next if (($name =~ m/^\s*$/)); + if ($id =~ m/^\s*$/) { + # anonymous struct/union + $newmember .= "$type $name; "; + } else { + $newmember .= "$type $id.$name; "; + } + } + } + } + } + $members =~ s/(struct|union)([^\{\};]+)\{([^\{\}]*)}([^\{\}\;]*)\;/$newmember/; + } + + # Ignore other nested elements, like enums + $members =~ s/({[^\{\}]*})//g; + + create_parameterlist($members, ';', $file, $declaration_name); + check_sections($file, $declaration_name, $decl_type, $sectcheck, $struct_actual); + + # Adjust declaration for better display + $declaration =~ s/([{;])/$1\n/g; + $declaration =~ s/}\s+;/};/g; + # Better handle inlined enums + do {} while ($declaration =~ s/(enum\s+{[^}]+),([^\n])/$1,\n$2/); + + my @def_args = split /\n/, $declaration; + my $level = 1; + $declaration = ""; + foreach my $clause (@def_args) { + $clause =~ s/^\s+//; + $clause =~ s/\s+$//; + $clause =~ s/\s+/ /; + next if (!$clause); + $level-- if ($clause =~ m/(})/ && $level > 1); + if (!($clause =~ m/^\s*#/)) { + $declaration .= "\t" x $level; + } + $declaration .= "\t" . $clause . "\n"; + $level++ if ($clause =~ m/({)/ && !($clause =~m/}/)); + } output_declaration($declaration_name, 'struct', {'struct' => $declaration_name, 'module' => $modulename, + 'definition' => $declaration, 'parameterlist' => \@parameterlist, 'parameterdescs' => \%parameterdescs, 'parametertypes' => \%parametertypes, @@ -2234,6 +1140,44 @@ sub dump_struct($$) { } } + +sub show_warnings($$) { + my $functype = shift; + my $name = shift; + + return 1 if ($output_selection == OUTPUT_ALL); + + if ($output_selection == OUTPUT_EXPORTED) { + if (defined($function_table{$name})) { + return 1; + } else { + return 0; + } + } + if ($output_selection == OUTPUT_INTERNAL) { + if (!($functype eq "function" && defined($function_table{$name}))) { + return 1; + } else { + return 0; + } + } + if ($output_selection == OUTPUT_INCLUDE) { + if (defined($function_table{$name})) { + return 1; + } else { + return 0; + } + } + if ($output_selection == OUTPUT_EXCLUDE) { + if (!defined($function_table{$name})) { + return 1; + } else { + return 0; + } + } + die("Please add the new output type at show_warnings()"); +} + sub dump_enum($$) { my $x = shift; my $file = shift; @@ -2254,16 +1198,18 @@ sub dump_enum($$) { push @parameterlist, $arg; if (!$parameterdescs{$arg}) { $parameterdescs{$arg} = $undescribed; - print STDERR "${file}:$.: warning: Enum value '$arg' ". - "not described in enum '$declaration_name'\n"; + if (show_warnings("enum", $declaration_name)) { + print STDERR "${file}:$.: warning: Enum value '$arg' not described in enum '$declaration_name'\n"; + } } $_members{$arg} = 1; } while (my ($k, $v) = each %parameterdescs) { if (!exists($_members{$k})) { - print STDERR "${file}:$.: warning: Excess enum value " . - "'$k' description in '$declaration_name'\n"; + if (show_warnings("enum", $declaration_name)) { + print STDERR "${file}:$.: warning: Excess enum value '$k' description in '$declaration_name'\n"; + } } } @@ -2299,7 +1245,7 @@ sub dump_typedef($$) { $declaration_name = $2; my $args = $3; - create_parameterlist($args, ',', $file); + create_parameterlist($args, ',', $file, $declaration_name); output_declaration($declaration_name, 'function', @@ -2348,10 +1294,11 @@ sub save_struct_actual($) { $struct_actual = $struct_actual . $actual . " "; } -sub create_parameterlist($$$) { +sub create_parameterlist($$$$) { my $args = shift; my $splitter = shift; my $file = shift; + my $declaration_name = shift; my $type; my $param; @@ -2376,12 +1323,12 @@ sub create_parameterlist($$$) { } elsif ($arg =~ m/\(.+\)\s*\(/) { # pointer-to-function $arg =~ tr/#/,/; - $arg =~ m/[^\(]+\(\*?\s*(\w*)\s*\)/; + $arg =~ m/[^\(]+\(\*?\s*([\w\.]*)\s*\)/; $param = $1; $type = $arg; $type =~ s/([^\(]+\(\*?)\s*$param/$1/; save_struct_actual($param); - push_parameter($param, $type, $file); + push_parameter($param, $type, $file, $declaration_name); } elsif ($arg) { $arg =~ s/\s*:\s*/:/g; $arg =~ s/\s*\[/\[/g; @@ -2406,27 +1353,28 @@ sub create_parameterlist($$$) { foreach $param (@args) { if ($param =~ m/^(\*+)\s*(.*)/) { save_struct_actual($2); - push_parameter($2, "$type $1", $file); + push_parameter($2, "$type $1", $file, $declaration_name); } elsif ($param =~ m/(.*?):(\d+)/) { if ($type ne "") { # skip unnamed bit-fields save_struct_actual($1); - push_parameter($1, "$type:$2", $file) + push_parameter($1, "$type:$2", $file, $declaration_name) } } else { save_struct_actual($param); - push_parameter($param, $type, $file); + push_parameter($param, $type, $file, $declaration_name); } } } } } -sub push_parameter($$$) { +sub push_parameter($$$$) { my $param = shift; my $type = shift; my $file = shift; + my $declaration_name = shift; if (($anon_struct_union == 1) && ($type eq "") && ($param eq "}")) { @@ -2463,21 +1411,15 @@ sub push_parameter($$$) { # warn if parameter has no description # (but ignore ones starting with # as these are not parameters # but inline preprocessor statements); - # also ignore unnamed structs/unions; - if (!$anon_struct_union) { + # Note: It will also ignore void params and unnamed structs/unions if (!defined $parameterdescs{$param} && $param !~ /^#/) { + $parameterdescs{$param} = $undescribed; - $parameterdescs{$param} = $undescribed; - - if (($type eq 'function') || ($type eq 'enum')) { - print STDERR "${file}:$.: warning: Function parameter ". - "or member '$param' not " . - "described in '$declaration_name'\n"; - } - print STDERR "${file}:$.: warning:" . - " No description found for parameter '$param'\n"; - ++$warnings; - } + if (show_warnings($type, $declaration_name)) { + print STDERR + "${file}:$.: warning: Function parameter or member '$param' not described in '$declaration_name'\n"; + ++$warnings; + } } $param = xml_escape($param); @@ -2496,8 +1438,8 @@ sub push_parameter($$$) { $parametertypes{$param} = $type; } -sub check_sections($$$$$$) { - my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck, $nested) = @_; +sub check_sections($$$$$) { + my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck) = @_; my @sects = split ' ', $sectcheck; my @prms = split ' ', $prmscheck; my $err; @@ -2531,14 +1473,6 @@ sub check_sections($$$$$$) { "'$sects[$sx]' " . "description in '$decl_name'\n"; ++$warnings; - } else { - if ($nested !~ m/\Q$sects[$sx]\E/) { - print STDERR "${file}:$.: warning: " . - "Excess $decl_type member " . - "'$sects[$sx]' " . - "description in '$decl_name'\n"; - ++$warnings; - } } } } @@ -2642,14 +1576,14 @@ sub dump_function($$) { $declaration_name = $2; my $args = $3; - create_parameterlist($args, ',', $file); + create_parameterlist($args, ',', $file, $declaration_name); } else { print STDERR "${file}:$.: warning: cannot understand function prototype: '$prototype'\n"; return; } my $prms = join " ", @parameterlist; - check_sections($file, $declaration_name, "function", $sectcheck, $prms, ""); + check_sections($file, $declaration_name, "function", $sectcheck, $prms); # This check emits a lot of warnings at the moment, because many # functions don't have a 'Return' doc section. So until the number @@ -2718,7 +1652,7 @@ sub tracepoint_munge($) { sub syscall_munge() { my $void = 0; - $prototype =~ s@[\r\n\t]+@ @gos; # strip newlines/CR's/tabs + $prototype =~ s@[\r\n]+@ @gos; # strip newlines/CR's ## if ($prototype =~ m/SYSCALL_DEFINE0\s*\(\s*(a-zA-Z0-9_)*\s*\)/) { if ($prototype =~ m/SYSCALL_DEFINE0/) { $void = 1; @@ -2823,7 +1757,7 @@ sub process_proto_type($$) { # just before actual output; (this is done by local_unescape()) sub xml_escape($) { my $text = shift; - if (($output_mode eq "text") || ($output_mode eq "man")) { + if ($output_mode eq "man") { return $text; } $text =~ s/\&/\\\\\\amp;/g; @@ -2835,7 +1769,7 @@ sub xml_escape($) { # xml_unescape: reverse the effects of xml_escape sub xml_unescape($) { my $text = shift; - if (($output_mode eq "text") || ($output_mode eq "man")) { + if ($output_mode eq "man") { return $text; } $text =~ s/\\\\\\amp;/\&/g; @@ -2848,7 +1782,7 @@ sub xml_unescape($) { # local escape strings look like: '\\\\menmonic:' (that's 4 backslashes) sub local_unescape($) { my $text = shift; - if (($output_mode eq "text") || ($output_mode eq "man")) { + if ($output_mode eq "man") { return $text; } $text =~ s/\\\\\\\\lt:/</g; @@ -2917,6 +1851,8 @@ sub process_file($) { while (s/\\\s*$//) { $_ .= <IN>; } + # Replace tabs by spaces + while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; if ($state == STATE_NORMAL) { if (/$doc_start/o) { $state = STATE_NAME; # next line is always the function name @@ -3016,8 +1952,7 @@ sub process_file($) { $in_purpose = 0; $contents = $newcontents; $new_start_line = $.; - while ((substr($contents, 0, 1) eq " ") || - substr($contents, 0, 1) eq "\t") { + while (substr($contents, 0, 1) eq " ") { $contents = substr($contents, 1); } if ($contents ne "") { @@ -3086,8 +2021,7 @@ sub process_file($) { $contents = $2; $new_start_line = $.; if ($contents ne "") { - while ((substr($contents, 0, 1) eq " ") || - substr($contents, 0, 1) eq "\t") { + while (substr($contents, 0, 1) eq " ") { $contents = substr($contents, 1); } $contents .= "\n"; @@ -3170,34 +2104,6 @@ sub process_file($) { if (($output_selection == OUTPUT_INCLUDE) && ($show_not_found == 1)) { print STDERR " Was looking for '$_'.\n" for keys %function_table; } - if ($output_mode eq "xml") { - # The template wants at least one RefEntry here; make one. - print "<refentry>\n"; - print " <refnamediv>\n"; - print " <refname>\n"; - print " ${orig_file}\n"; - print " </refname>\n"; - print " <refpurpose>\n"; - print " Document generation inconsistency\n"; - print " </refpurpose>\n"; - print " </refnamediv>\n"; - print " <refsect1>\n"; - print " <title>\n"; - print " Oops\n"; - print " </title>\n"; - print " <warning>\n"; - print " <para>\n"; - print " The template for this document tried to insert\n"; - print " the structured comment from the file\n"; - print " <filename>${orig_file}</filename> at this point,\n"; - print " but none was found.\n"; - print " This dummy section is inserted to allow\n"; - print " generation to continue.\n"; - print " </para>\n"; - print " </warning>\n"; - print " </refsect1>\n"; - print "</refentry>\n"; - } } } @@ -3248,4 +2154,4 @@ if ($verbose && $warnings) { print STDERR "$warnings warnings\n"; } -exit($errors); +exit($output_mode eq "none" ? 0 : $errors); diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index 9826b9a6543c..9fad6afe4c41 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c @@ -203,6 +203,10 @@ int main(void) DEVID_FIELD(hda_device_id, rev_id); DEVID_FIELD(hda_device_id, api_version); + DEVID(sdw_device_id); + DEVID_FIELD(sdw_device_id, mfg_id); + DEVID_FIELD(sdw_device_id, part_id); + DEVID(fsl_mc_device_id); DEVID_FIELD(fsl_mc_device_id, vendor); DEVID_FIELD(fsl_mc_device_id, obj_type); diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 6ef6e63f96fd..b9beeaa4695b 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1289,6 +1289,21 @@ static int do_hda_entry(const char *filename, void *symval, char *alias) } ADD_TO_DEVTABLE("hdaudio", hda_device_id, do_hda_entry); +/* Looks like: sdw:mNpN */ +static int do_sdw_entry(const char *filename, void *symval, char *alias) +{ + DEF_FIELD(symval, sdw_device_id, mfg_id); + DEF_FIELD(symval, sdw_device_id, part_id); + + strcpy(alias, "sdw:"); + ADD(alias, "m", mfg_id != 0, mfg_id); + ADD(alias, "p", part_id != 0, part_id); + + add_wildcard(alias); + return 1; +} +ADD_TO_DEVTABLE("sdw", sdw_device_id, do_sdw_entry); + /* Looks like: fsl-mc:vNdN */ static int do_fsl_mc_entry(const char *filename, void *symval, char *alias) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index f51cf977c65b..6510536c06df 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2165,6 +2165,14 @@ static void add_intree_flag(struct buffer *b, int is_intree) buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n"); } +/* Cannot check for assembler */ +static void add_retpoline(struct buffer *b) +{ + buf_printf(b, "\n#ifdef RETPOLINE\n"); + buf_printf(b, "MODULE_INFO(retpoline, \"Y\");\n"); + buf_printf(b, "#endif\n"); +} + static void add_staging_flag(struct buffer *b, const char *name) { static const char *staging_dir = "drivers/staging"; @@ -2506,6 +2514,7 @@ int main(int argc, char **argv) err |= check_modname_len(mod); add_header(&buf, mod); add_intree_flag(&buf, !external_module); + add_retpoline(&buf); add_staging_flag(&buf, mod->name); err |= add_versions(&buf, mod); add_depends(&buf, mod, modules); diff --git a/scripts/package/Makefile b/scripts/package/Makefile index c23534925b38..9fbcf5ed0ca7 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -32,10 +32,14 @@ MKSPEC := $(srctree)/scripts/package/mkspec quiet_cmd_src_tar = TAR $(2).tar.gz cmd_src_tar = \ +set -e; \ if test "$(objtree)" != "$(srctree)"; then \ - echo "Building source tarball is not possible outside the"; \ - echo "kernel source tree. Don't set KBUILD_OUTPUT, or use the"; \ - echo "binrpm-pkg or bindeb-pkg target instead."; \ + echo >&2; \ + echo >&2 " ERROR:"; \ + echo >&2 " Building source tarball is not possible outside the"; \ + echo >&2 " kernel source tree. Don't set KBUILD_OUTPUT, or use the"; \ + echo >&2 " binrpm-pkg or bindeb-pkg target instead."; \ + echo >&2; \ false; \ fi ; \ $(srctree)/scripts/setlocalversion --save-scmversion; \ @@ -94,6 +98,21 @@ bindeb-pkg: FORCE clean-dirs += $(objtree)/debian/ +# snap-pkg +# --------------------------------------------------------------------------- +snap-pkg: FORCE + rm -rf $(objtree)/snap + mkdir $(objtree)/snap + $(MAKE) clean + $(call cmd,src_tar,$(KERNELPATH)) + sed "s@KERNELRELEASE@$(KERNELRELEASE)@; \ + s@SRCTREE@$(shell realpath $(KERNELPATH).tar.gz)@" \ + $(srctree)/scripts/package/snapcraft.template > \ + $(objtree)/snap/snapcraft.yaml + cd $(objtree)/snap && \ + snapcraft --target-arch=$(UTS_MACHINE) + +clean-dirs += $(objtree)/snap/ # tarball targets # --------------------------------------------------------------------------- @@ -138,6 +157,7 @@ help: FORCE @echo ' binrpm-pkg - Build only the binary kernel RPM package' @echo ' deb-pkg - Build both source and binary deb kernel packages' @echo ' bindeb-pkg - Build only the binary kernel deb package' + @echo ' snap-pkg - Build only the binary kernel snap package (will connect to external hosts)' @echo ' tar-pkg - Build the kernel as an uncompressed tarball' @echo ' targz-pkg - Build the kernel as a gzip compressed tarball' @echo ' tarbz2-pkg - Build the kernel as a bzip2 compressed tarball' diff --git a/scripts/package/snapcraft.template b/scripts/package/snapcraft.template new file mode 100644 index 000000000000..626d278e4a5a --- /dev/null +++ b/scripts/package/snapcraft.template @@ -0,0 +1,14 @@ +name: kernel +version: KERNELRELEASE +summary: Linux kernel +description: The upstream Linux kernel +grade: stable +confinement: strict +type: kernel + +parts: + kernel: + plugin: kernel + source: SRCTREE + source-type: tar + kernel-with-firmware: false diff --git a/scripts/tags.sh b/scripts/tags.sh index d23dcbf17457..78e546ff689c 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -77,7 +77,7 @@ find_include_sources() find_other_sources() { find ${tree}* $ignore \ - \( -name include -o -name arch -o -name '.tmp_*' \) -prune -o \ + \( -path ${tree}include -o -path ${tree}arch -o -name '.tmp_*' \) -prune -o \ -name "$1" -not -type l -print; } |