diff options
Diffstat (limited to 'scripts')
93 files changed, 2816 insertions, 1500 deletions
| diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 50cee534fd64..c8156d61678c 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -8,8 +8,6 @@ squote  := '  empty   :=  space   := $(empty) $(empty)  space_escape := _-_SPACE_-_ -right_paren := ) -left_paren := (  pound := \#  ### @@ -57,7 +55,6 @@ kecho := $($(quiet)kecho)  #   to specify a valid file as first prerequisite (often the kbuild file)  define filechk  	$(Q)set -e;				\ -	$(kecho) '  CHK     $@';		\  	mkdir -p $(dir $@);			\  	$(filechk_$(1)) < $< > [email protected];		\  	if [ -r $@ ] && cmp -s $@ [email protected]; then	\ @@ -83,71 +80,6 @@ cc-cross-prefix =  \  			echo $(c);                                    \  		fi))) -# Tools for caching Makefile variables that are "expensive" to compute. -# -# Here we want to help deal with variables that take a long time to compute -# by making it easy to store these variables in a cache. -# -# The canonical example here is testing for compiler flags.  On a simple system -# each call to the compiler takes 10 ms, but on a system with a compiler that's -# called through various wrappers it can take upwards of 100 ms.  If we have -# 100 calls to the compiler this can take 1 second (on a simple system) or 10 -# seconds (on a complicated system). -# -# The "cache" will be in Makefile syntax and can be directly included. -# Any time we try to reference a variable that's not in the cache we'll -# calculate it and store it in the cache for next time. - -# Include values from last time -make-cache := $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/,$(if $(obj),$(obj)/)).cache.mk -$(make-cache): ; --include $(make-cache) - -cached-data := $(filter __cached_%, $(.VARIABLES)) - -# If cache exceeds 1000 lines, shrink it down to 500. -ifneq ($(word 1000,$(cached-data)),) -$(shell tail -n 500 $(make-cache) > $(make-cache).tmp; \ -	mv $(make-cache).tmp $(make-cache)) -endif - -create-cache-dir := $(if $(KBUILD_SRC),$(if $(cache-data),,1)) - -# Usage: $(call __sanitize-opt,Hello=Hola$(comma)Goodbye Adios) -# -# Convert all '$', ')', '(', '\', '=', ' ', ',', ':' to '_' -__sanitize-opt = $(subst $$,_,$(subst $(right_paren),_,$(subst $(left_paren),_,$(subst \,_,$(subst =,_,$(subst $(space),_,$(subst $(comma),_,$(subst :,_,$(1))))))))) - -# Usage:   $(call shell-cached,shell_command) -# Example: $(call shell-cached,md5sum /usr/bin/gcc) -# -# If we've already seen a call to this exact shell command (even in a -# previous invocation of make!) we'll return the value.  If not, we'll -# compute it and store the result for future runs. -# -# This is a bit of voodoo, but basic explanation is that if the variable -# was undefined then we'll evaluate the shell command and store the result -# into the variable.  We'll then store that value in the cache and finally -# output the value. -# -# NOTE: The $$(2) here isn't actually a parameter to __run-and-store.  We -# happen to know that the caller will have their shell command in $(2) so the -# result of "call"ing this will produce a reference to that $(2).  The reason -# for this strangeness is to avoid an extra level of eval (and escaping) of -# $(2). -define __run-and-store -ifeq ($(origin $(1)),undefined) -  $$(eval $(1) := $$(shell $$(2))) -ifeq ($(create-cache-dir),1) -  $$(shell mkdir -p $(dir $(make-cache))) -  $$(eval create-cache-dir :=) -endif -  $$(shell echo '$(1) := $$($(1))' >> $(make-cache)) -endif -endef -__shell-cached = $(eval $(call __run-and-store,$(1)))$($(1)) -shell-cached = $(call __shell-cached,__cached_$(call __sanitize-opt,$(1)),$(1)) -  # output directory for tests below  TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/) @@ -155,36 +87,30 @@ TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/)  # Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise)  # Exit code chooses option. "$$TMP" serves as a temporary file and is  # automatically cleaned up. -__try-run = set -e;			\ +try-run = $(shell set -e;		\  	TMP="$(TMPOUT).$$$$.tmp";	\  	TMPO="$(TMPOUT).$$$$.o";	\  	if ($(1)) >/dev/null 2>&1;	\  	then echo "$(2)";		\  	else echo "$(3)";		\  	fi;				\ -	rm -f "$$TMP" "$$TMPO" - -try-run = $(shell $(__try-run)) - -# try-run-cached -# This works like try-run, but the result is cached. -try-run-cached = $(call shell-cached,$(__try-run)) +	rm -f "$$TMP" "$$TMPO")  # as-option  # Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,) -as-option = $(call try-run-cached,\ +as-option = $(call try-run,\  	$(CC) $(KBUILD_CFLAGS) $(1) -c -x assembler /dev/null -o "$$TMP",$(1),$(2))  # as-instr  # Usage: cflags-y += $(call as-instr,instr,option1,option2) -as-instr = $(call try-run-cached,\ +as-instr = $(call try-run,\  	printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3))  # __cc-option  # Usage: MY_CFLAGS += $(call __cc-option,$(CC),$(MY_CFLAGS),-march=winchip-c6,-march=i586) -__cc-option = $(call try-run-cached,\ +__cc-option = $(call try-run,\  	$(1) -Werror $(2) $(3) -c -x c /dev/null -o "$$TMP",$(3),$(4))  # Do not attempt to build with gcc plugins during cc-option tests. @@ -204,23 +130,23 @@ hostcc-option = $(call __cc-option, $(HOSTCC),\  # cc-option-yn  # Usage: flag := $(call cc-option-yn,-march=winchip-c6) -cc-option-yn = $(call try-run-cached,\ +cc-option-yn = $(call try-run,\  	$(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n)  # cc-disable-warning  # Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable) -cc-disable-warning = $(call try-run-cached,\ +cc-disable-warning = $(call try-run,\  	$(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))  # cc-name  # Expands to either gcc or clang -cc-name = $(call shell-cached,$(CC) -v 2>&1 | grep -q "clang version" && echo clang || echo gcc) +cc-name = $(shell $(CC) -v 2>&1 | grep -q "clang version" && echo clang || echo gcc)  # cc-version -cc-version = $(call shell-cached,$(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC)) +cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC))  # cc-fullversion -cc-fullversion = $(call shell-cached,$(CONFIG_SHELL) \ +cc-fullversion = $(shell $(CONFIG_SHELL) \  	$(srctree)/scripts/gcc-version.sh -p $(CC))  # cc-ifversion @@ -233,21 +159,21 @@ cc-if-fullversion = $(shell [ $(cc-fullversion) $(1) $(2) ] && echo $(3) || echo  # cc-ldoption  # Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both) -cc-ldoption = $(call try-run-cached,\ +cc-ldoption = $(call try-run,\  	$(CC) $(1) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2))  # ld-option  # Usage: LDFLAGS += $(call ld-option, -X) -ld-option = $(call try-run-cached, $(LD) $(LDFLAGS) $(1) -v,$(1),$(2)) +ld-option = $(call try-run, $(LD) $(LDFLAGS) $(1) -v,$(1),$(2))  # ar-option  # Usage: KBUILD_ARFLAGS := $(call ar-option,D)  # Important: no spaces around options -ar-option = $(call try-run-cached, $(AR) rc$(1) "$$TMP",$(1),$(2)) +ar-option = $(call try-run, $(AR) rc$(1) "$$TMP",$(1),$(2))  # ld-version  # Note this is mainly for HJ Lu's 3 number binutil versions -ld-version = $(call shell-cached,$(LD) --version | $(srctree)/scripts/ld-version.sh) +ld-version = $(shell $(LD) --version | $(srctree)/scripts/ld-version.sh)  # ld-ifversion  # Usage:  $(call ld-ifversion, -ge, 22252, y) diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include new file mode 100644 index 000000000000..dad5583451af --- /dev/null +++ b/scripts/Kconfig.include @@ -0,0 +1,30 @@ +# Kconfig helper macros + +# Convenient variables +comma       := , +quote       := " +squote      := ' +empty       := +space       := $(empty) $(empty) +dollar      := $ +right_paren := ) +left_paren  := ( + +# $(if-success,<command>,<then>,<else>) +# Return <then> if <command> exits with 0, <else> otherwise. +if-success = $(shell,{ $(1); } >/dev/null 2>&1 && echo "$(2)" || echo "$(3)") + +# $(success,<command>) +# Return y if <command> exits with 0, n otherwise +success = $(if-success,$(1),y,n) + +# $(cc-option,<flag>) +# Return y if the compiler supports <flag>, n otherwise +cc-option = $(success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null) + +# $(ld-option,<flag>) +# Return y if the linker supports <flag>, n otherwise +ld-option = $(success,$(LD) -v $(1)) + +# gcc version including patch level +gcc-version := $(shell,$(srctree)/scripts/gcc-version.sh -p $(CC) | sed 's/^0*//') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 8bdb1dc4072c..e7889f486ca1 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -147,7 +147,6 @@ $(obj)/%.i: $(src)/%.c FORCE  cmd_gensymtypes_c =                                                         \      $(CPP) -D__GENKSYMS__ $(c_flags) $< |                                   \      $(GENKSYMS) $(if $(1), -T $(2))                                         \ -     $(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX))             \       $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS))                             \       $(if $(KBUILD_PRESERVE),-p)                                            \       -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null)) @@ -207,6 +206,11 @@ cmd_modversions_c =								\  endif  ifdef CONFIG_FTRACE_MCOUNT_RECORD +# gcc 5 supports generating the mcount tables directly +ifneq ($(call cc-option,-mrecord-mcount,y),y) +KBUILD_CFLAGS += -mrecord-mcount +else +# else do it all manually  ifdef BUILD_C_RECORDMCOUNT  ifeq ("$(origin RECORDMCOUNT_WARN)", "command line")    RECORDMCOUNT_FLAGS = -w @@ -235,6 +239,7 @@ cmd_record_mcount =						\  	     "$(CC_FLAGS_FTRACE)" ]; then			\  		$(sub_cmd_record_mcount)			\  	fi; +endif # -record-mcount  endif # CONFIG_FTRACE_MCOUNT_RECORD  ifdef CONFIG_STACK_VALIDATION @@ -355,7 +360,6 @@ cmd_gensymtypes_S =                                                         \       sed 's/.*___EXPORT_SYMBOL[[:space:]]*\([a-zA-Z0-9_]*\)[[:space:]]*,.*/EXPORT_SYMBOL(\1);/' ) | \      $(CPP) -D__GENKSYMS__ $(c_flags) -xc - |                                \      $(GENKSYMS) $(if $(1), -T $(2))                                         \ -     $(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX))             \       $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS))                             \       $(if $(KBUILD_PRESERVE),-p)                                            \       -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null)) @@ -487,15 +491,10 @@ targets += $(lib-target)  dummy-object = $(obj)/.lib_exports.o  ksyms-lds = $(dot-target).lds -ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX -ref_prefix = EXTERN(_ -else -ref_prefix = EXTERN( -endif  quiet_cmd_export_list = EXPORTS $@  cmd_export_list = $(OBJDUMP) -h $< | \ -	sed -ne '/___ksymtab/s/.*+\([^ ]*\).*/$(ref_prefix)\1)/p' >$(ksyms-lds);\ +	sed -ne '/___ksymtab/s/.*+\([^ ]*\).*/EXTERN(\1)/p' >$(ksyms-lds);\  	rm -f $(dummy-object);\  	echo | $(CC) $(a_flags) -c -o $(dummy-object) -x assembler -;\  	$(LD) $(ld_flags) -r -o $@ -T $(ksyms-lds) $(dummy-object);\ diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index b2a95af7df18..c961b9a65d11 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -1,84 +1,37 @@  # SPDX-License-Identifier: GPL-2.0 -ifdef CONFIG_GCC_PLUGINS -  __PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC)) -  PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)") - -  SANCOV_PLUGIN := -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so - -  gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY)	+= cyc_complexity_plugin.so +gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY)	+= cyc_complexity_plugin.so -  gcc-plugin-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY)	+= latent_entropy_plugin.so -  gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY)	+= -DLATENT_ENTROPY_PLUGIN -  ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY +gcc-plugin-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY)	+= latent_entropy_plugin.so +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY)	+= -DLATENT_ENTROPY_PLUGIN +ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY      DISABLE_LATENT_ENTROPY_PLUGIN			+= -fplugin-arg-latent_entropy_plugin-disable -  endif - -  ifdef CONFIG_GCC_PLUGIN_SANCOV -    ifeq ($(CFLAGS_KCOV),) -      # It is needed because of the gcc-plugin.sh and gcc version checks. -      gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV)           += sancov_plugin.so - -      ifneq ($(PLUGINCC),) -        CFLAGS_KCOV := $(SANCOV_PLUGIN) -      else -        $(warning warning: cannot use CONFIG_KCOV: -fsanitize-coverage=trace-pc is not supported by compiler) -      endif -    endif -  endif - -  gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK)	+= structleak_plugin.so -  gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE)	+= -fplugin-arg-structleak_plugin-verbose -  gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL)	+= -fplugin-arg-structleak_plugin-byref-all -  gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK)	+= -DSTRUCTLEAK_PLUGIN +endif -  gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT)	+= randomize_layout_plugin.so -  gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT)	+= -DRANDSTRUCT_PLUGIN -  gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE)	+= -fplugin-arg-randomize_layout_plugin-performance-mode +gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV)		+= sancov_plugin.so +gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK)	+= structleak_plugin.so +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE)	+= -fplugin-arg-structleak_plugin-verbose +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL)	+= -fplugin-arg-structleak_plugin-byref-all +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK)	+= -DSTRUCTLEAK_PLUGIN -  GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) +gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT)	+= randomize_layout_plugin.so +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT)	+= -DRANDSTRUCT_PLUGIN +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE)	+= -fplugin-arg-randomize_layout_plugin-performance-mode -  export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN GCC_PLUGIN_SUBDIR -  export SANCOV_PLUGIN DISABLE_LATENT_ENTROPY_PLUGIN +GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) -  ifneq ($(PLUGINCC),) -    # SANCOV_PLUGIN can be only in CFLAGS_KCOV because avoid duplication. -    GCC_PLUGINS_CFLAGS := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGINS_CFLAGS)) -  endif +export GCC_PLUGINS_CFLAGS GCC_PLUGIN GCC_PLUGIN_SUBDIR +export DISABLE_LATENT_ENTROPY_PLUGIN -  KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) -  GCC_PLUGIN := $(gcc-plugin-y) -  GCC_PLUGIN_SUBDIR := $(gcc-plugin-subdir-y) -endif +# sancov_plugin.so can be only in CFLAGS_KCOV because avoid duplication. +GCC_PLUGINS_CFLAGS := $(filter-out %/sancov_plugin.so, $(GCC_PLUGINS_CFLAGS)) -# If plugins aren't supported, abort the build before hard-to-read compiler -# errors start getting spewed by the main build. -PHONY += gcc-plugins-check -gcc-plugins-check: FORCE -ifdef CONFIG_GCC_PLUGINS -  ifeq ($(PLUGINCC),) -    ifneq ($(GCC_PLUGINS_CFLAGS),) -      # Various gccs between 4.5 and 5.1 have bugs on powerpc due to missing -      # header files. gcc <= 4.6 doesn't work at all, gccs from 4.8 to 5.1 have -      # issues with 64-bit targets. -      ifeq ($(ARCH),powerpc) -        ifeq ($(call cc-ifversion, -le, 0501, y), y) -	  @echo "Cannot use CONFIG_GCC_PLUGINS: plugin support on gcc <= 5.1 is buggy on powerpc, please upgrade to gcc 5.2 or newer" >&2 && exit 1 -        endif -      endif -      ifeq ($(call cc-ifversion, -ge, 0405, y), y) -	$(Q)$(srctree)/scripts/gcc-plugin.sh --show-error "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)" || true -	@echo "Cannot use CONFIG_GCC_PLUGINS: your gcc installation does not support plugins, perhaps the necessary headers are missing?" >&2 && exit 1 -      else -	@echo "Cannot use CONFIG_GCC_PLUGINS: your gcc version does not support plugins, you should upgrade it to at least gcc 4.5" >&2 && exit 1 -      endif -    endif -  endif -endif -	@: +KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) +GCC_PLUGIN := $(gcc-plugin-y) +GCC_PLUGIN_SUBDIR := $(gcc-plugin-subdir-y)  # Actually do the build, if requested.  PHONY += gcc-plugins -gcc-plugins: scripts_basic gcc-plugins-check +gcc-plugins: scripts_basic  ifdef CONFIG_GCC_PLUGINS  	$(Q)$(MAKE) $(build)=scripts/gcc-plugins  endif diff --git a/scripts/Makefile.kcov b/scripts/Makefile.kcov index 5cc72037e423..3d61c4bfcbee 100644 --- a/scripts/Makefile.kcov +++ b/scripts/Makefile.kcov @@ -1,7 +1,9 @@  ifdef CONFIG_KCOV -CFLAGS_KCOV	:= $(call cc-option,-fsanitize-coverage=trace-pc,) -ifeq ($(CONFIG_KCOV_ENABLE_COMPARISONS),y) -CFLAGS_KCOV += $(call cc-option,-fsanitize-coverage=trace-cmp,) -endif + +kcov-flags-$(CONFIG_CC_HAS_SANCOV_TRACE_PC)	+= -fsanitize-coverage=trace-pc +kcov-flags-$(CONFIG_KCOV_ENABLE_COMPARISONS)	+= -fsanitize-coverage=trace-cmp +kcov-flags-$(CONFIG_GCC_PLUGIN_SANCOV)		+= -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so + +export CFLAGS_KCOV := $(kcov-flags-y)  endif diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 07d07409f16f..1bb594fcfe12 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -196,7 +196,7 @@ $(obj)/%.tab.c: $(src)/%.y FORCE  	$(call if_changed,bison)  quiet_cmd_bison_h = YACC    $@ -      cmd_bison_h = bison -o/dev/null --defines=$@ -t -l $< +      cmd_bison_h = $(YACC) -o/dev/null --defines=$@ -t -l $<  $(obj)/%.tab.h: $(src)/%.y FORCE  	$(call if_changed,bison_h) @@ -251,6 +251,9 @@ DTC_FLAGS += -Wno-unit_address_vs_reg \  	-Wno-unit_address_format \  	-Wno-avoid_unnecessary_addr_size \  	-Wno-alias_paths \ +	-Wno-graph_child_address \ +	-Wno-graph_port \ +	-Wno-unique_unit_address \  	-Wno-pci_device_reg  endif diff --git a/scripts/adjust_autoksyms.sh b/scripts/adjust_autoksyms.sh index 016b3c48a4ec..6e6d63957da3 100755 --- a/scripts/adjust_autoksyms.sh +++ b/scripts/adjust_autoksyms.sh @@ -61,9 +61,6 @@ for mod in "$MODVERDIR"/*.mod; do  	sed -n -e '3{s/ /\n/g;/^$/!p;}' "$mod"  done | sort -u |  while read sym; do -	if [ -n "$CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX" ]; then -		sym="${sym#_}" -	fi  	echo "#define __KSYM_${sym} 1"  done >> "$new_ksyms_file" diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index f387538c58bc..850966f3d602 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -115,7 +115,7 @@ static void usage(void)   */  static void print_dep(const char *m, int slen, const char *dir)  { -	int c, i; +	int c, prev_c = '/', i;  	printf("    $(wildcard %s/", dir);  	for (i = 0; i < slen; i++) { @@ -124,7 +124,9 @@ static void print_dep(const char *m, int slen, const char *dir)  			c = '/';  		else  			c = tolower(c); -		putchar(c); +		if (c != '/' || prev_c != '/') +			putchar(c); +		prev_c = c;  	}  	printf(".h) \\\n");  } diff --git a/scripts/bpf_helpers_doc.py b/scripts/bpf_helpers_doc.py new file mode 100755 index 000000000000..5010a4d5bfba --- /dev/null +++ b/scripts/bpf_helpers_doc.py @@ -0,0 +1,421 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2018 Netronome Systems, Inc. + +# In case user attempts to run with Python 2. +from __future__ import print_function + +import argparse +import re +import sys, os + +class NoHelperFound(BaseException): +    pass + +class ParsingError(BaseException): +    def __init__(self, line='<line not provided>', reader=None): +        if reader: +            BaseException.__init__(self, +                                   'Error at file offset %d, parsing line: %s' % +                                   (reader.tell(), line)) +        else: +            BaseException.__init__(self, 'Error parsing line: %s' % line) + +class Helper(object): +    """ +    An object representing the description of an eBPF helper function. +    @proto: function prototype of the helper function +    @desc: textual description of the helper function +    @ret: description of the return value of the helper function +    """ +    def __init__(self, proto='', desc='', ret=''): +        self.proto = proto +        self.desc = desc +        self.ret = ret + +    def proto_break_down(self): +        """ +        Break down helper function protocol into smaller chunks: return type, +        name, distincts arguments. +        """ +        arg_re = re.compile('((const )?(struct )?(\w+|...))( (\**)(\w+))?$') +        res = {} +        proto_re = re.compile('(.+) (\**)(\w+)\(((([^,]+)(, )?){1,5})\)$') + +        capture = proto_re.match(self.proto) +        res['ret_type'] = capture.group(1) +        res['ret_star'] = capture.group(2) +        res['name']     = capture.group(3) +        res['args'] = [] + +        args    = capture.group(4).split(', ') +        for a in args: +            capture = arg_re.match(a) +            res['args'].append({ +                'type' : capture.group(1), +                'star' : capture.group(6), +                'name' : capture.group(7) +            }) + +        return res + +class HeaderParser(object): +    """ +    An object used to parse a file in order to extract the documentation of a +    list of eBPF helper functions. All the helpers that can be retrieved are +    stored as Helper object, in the self.helpers() array. +    @filename: name of file to parse, usually include/uapi/linux/bpf.h in the +               kernel tree +    """ +    def __init__(self, filename): +        self.reader = open(filename, 'r') +        self.line = '' +        self.helpers = [] + +    def parse_helper(self): +        proto    = self.parse_proto() +        desc     = self.parse_desc() +        ret      = self.parse_ret() +        return Helper(proto=proto, desc=desc, ret=ret) + +    def parse_proto(self): +        # Argument can be of shape: +        #   - "void" +        #   - "type  name" +        #   - "type *name" +        #   - Same as above, with "const" and/or "struct" in front of type +        #   - "..." (undefined number of arguments, for bpf_trace_printk()) +        # There is at least one term ("void"), and at most five arguments. +        p = re.compile(' \* ?((.+) \**\w+\((((const )?(struct )?(\w+|\.\.\.)( \**\w+)?)(, )?){1,5}\))$') +        capture = p.match(self.line) +        if not capture: +            raise NoHelperFound +        self.line = self.reader.readline() +        return capture.group(1) + +    def parse_desc(self): +        p = re.compile(' \* ?(?:\t| {5,8})Description$') +        capture = p.match(self.line) +        if not capture: +            # Helper can have empty description and we might be parsing another +            # attribute: return but do not consume. +            return '' +        # Description can be several lines, some of them possibly empty, and it +        # stops when another subsection title is met. +        desc = '' +        while True: +            self.line = self.reader.readline() +            if self.line == ' *\n': +                desc += '\n' +            else: +                p = re.compile(' \* ?(?:\t| {5,8})(?:\t| {8})(.*)') +                capture = p.match(self.line) +                if capture: +                    desc += capture.group(1) + '\n' +                else: +                    break +        return desc + +    def parse_ret(self): +        p = re.compile(' \* ?(?:\t| {5,8})Return$') +        capture = p.match(self.line) +        if not capture: +            # Helper can have empty retval and we might be parsing another +            # attribute: return but do not consume. +            return '' +        # Return value description can be several lines, some of them possibly +        # empty, and it stops when another subsection title is met. +        ret = '' +        while True: +            self.line = self.reader.readline() +            if self.line == ' *\n': +                ret += '\n' +            else: +                p = re.compile(' \* ?(?:\t| {5,8})(?:\t| {8})(.*)') +                capture = p.match(self.line) +                if capture: +                    ret += capture.group(1) + '\n' +                else: +                    break +        return ret + +    def run(self): +        # Advance to start of helper function descriptions. +        offset = self.reader.read().find('* Start of BPF helper function descriptions:') +        if offset == -1: +            raise Exception('Could not find start of eBPF helper descriptions list') +        self.reader.seek(offset) +        self.reader.readline() +        self.reader.readline() +        self.line = self.reader.readline() + +        while True: +            try: +                helper = self.parse_helper() +                self.helpers.append(helper) +            except NoHelperFound: +                break + +        self.reader.close() +        print('Parsed description of %d helper function(s)' % len(self.helpers), +              file=sys.stderr) + +############################################################################### + +class Printer(object): +    """ +    A generic class for printers. Printers should be created with an array of +    Helper objects, and implement a way to print them in the desired fashion. +    @helpers: array of Helper objects to print to standard output +    """ +    def __init__(self, helpers): +        self.helpers = helpers + +    def print_header(self): +        pass + +    def print_footer(self): +        pass + +    def print_one(self, helper): +        pass + +    def print_all(self): +        self.print_header() +        for helper in self.helpers: +            self.print_one(helper) +        self.print_footer() + +class PrinterRST(Printer): +    """ +    A printer for dumping collected information about helpers as a ReStructured +    Text page compatible with the rst2man program, which can be used to +    generate a manual page for the helpers. +    @helpers: array of Helper objects to print to standard output +    """ +    def print_header(self): +        header = '''\ +.. Copyright (C) All BPF authors and contributors from 2014 to present. +.. See git log include/uapi/linux/bpf.h in kernel tree for details. +..  +.. %%%LICENSE_START(VERBATIM) +.. Permission is granted to make and distribute verbatim copies of this +.. manual provided the copyright notice and this permission notice are +.. preserved on all copies. +..  +.. Permission is granted to copy and distribute modified versions of this +.. manual under the conditions for verbatim copying, provided that the +.. entire resulting derived work is distributed under the terms of a +.. permission notice identical to this one. +..  +.. Since the Linux kernel and libraries are constantly changing, this +.. manual page may be incorrect or out-of-date.  The author(s) assume no +.. responsibility for errors or omissions, or for damages resulting from +.. the use of the information contained herein.  The author(s) may not +.. have taken the same level of care in the production of this manual, +.. which is licensed free of charge, as they might when working +.. professionally. +..  +.. Formatted or processed versions of this manual, if unaccompanied by +.. the source, must acknowledge the copyright and authors of this work. +.. %%%LICENSE_END +..  +.. Please do not edit this file. It was generated from the documentation +.. located in file include/uapi/linux/bpf.h of the Linux kernel sources +.. (helpers description), and from scripts/bpf_helpers_doc.py in the same +.. repository (header and footer). + +=========== +BPF-HELPERS +=========== +------------------------------------------------------------------------------- +list of eBPF helper functions +------------------------------------------------------------------------------- + +:Manual section: 7 + +DESCRIPTION +=========== + +The extended Berkeley Packet Filter (eBPF) subsystem consists in programs +written in a pseudo-assembly language, then attached to one of the several +kernel hooks and run in reaction of specific events. This framework differs +from the older, "classic" BPF (or "cBPF") in several aspects, one of them being +the ability to call special functions (or "helpers") from within a program. +These functions are restricted to a white-list of helpers defined in the +kernel. + +These helpers are used by eBPF programs to interact with the system, or with +the context in which they work. For instance, they can be used to print +debugging messages, to get the time since the system was booted, to interact +with eBPF maps, or to manipulate network packets. Since there are several eBPF +program types, and that they do not run in the same context, each program type +can only call a subset of those helpers. + +Due to eBPF conventions, a helper can not have more than five arguments. + +Internally, eBPF programs call directly into the compiled helper functions +without requiring any foreign-function interface. As a result, calling helpers +introduces no overhead, thus offering excellent performance. + +This document is an attempt to list and document the helpers available to eBPF +developers. They are sorted by chronological order (the oldest helpers in the +kernel at the top). + +HELPERS +======= +''' +        print(header) + +    def print_footer(self): +        footer = ''' +EXAMPLES +======== + +Example usage for most of the eBPF helpers listed in this manual page are +available within the Linux kernel sources, at the following locations: + +* *samples/bpf/* +* *tools/testing/selftests/bpf/* + +LICENSE +======= + +eBPF programs can have an associated license, passed along with the bytecode +instructions to the kernel when the programs are loaded. The format for that +string is identical to the one in use for kernel modules (Dual licenses, such +as "Dual BSD/GPL", may be used). Some helper functions are only accessible to +programs that are compatible with the GNU Privacy License (GPL). + +In order to use such helpers, the eBPF program must be loaded with the correct +license string passed (via **attr**) to the **bpf**\ () system call, and this +generally translates into the C source code of the program containing a line +similar to the following: + +:: + +	char ____license[] __attribute__((section("license"), used)) = "GPL"; + +IMPLEMENTATION +============== + +This manual page is an effort to document the existing eBPF helper functions. +But as of this writing, the BPF sub-system is under heavy development. New eBPF +program or map types are added, along with new helper functions. Some helpers +are occasionally made available for additional program types. So in spite of +the efforts of the community, this page might not be up-to-date. If you want to +check by yourself what helper functions exist in your kernel, or what types of +programs they can support, here are some files among the kernel tree that you +may be interested in: + +* *include/uapi/linux/bpf.h* is the main BPF header. It contains the full list +  of all helper functions, as well as many other BPF definitions including most +  of the flags, structs or constants used by the helpers. +* *net/core/filter.c* contains the definition of most network-related helper +  functions, and the list of program types from which they can be used. +* *kernel/trace/bpf_trace.c* is the equivalent for most tracing program-related +  helpers. +* *kernel/bpf/verifier.c* contains the functions used to check that valid types +  of eBPF maps are used with a given helper function. +* *kernel/bpf/* directory contains other files in which additional helpers are +  defined (for cgroups, sockmaps, etc.). + +Compatibility between helper functions and program types can generally be found +in the files where helper functions are defined. Look for the **struct +bpf_func_proto** objects and for functions returning them: these functions +contain a list of helpers that a given program type can call. Note that the +**default:** label of the **switch ... case** used to filter helpers can call +other functions, themselves allowing access to additional helpers. The +requirement for GPL license is also in those **struct bpf_func_proto**. + +Compatibility between helper functions and map types can be found in the +**check_map_func_compatibility**\ () function in file *kernel/bpf/verifier.c*. + +Helper functions that invalidate the checks on **data** and **data_end** +pointers for network processing are listed in function +**bpf_helper_changes_pkt_data**\ () in file *net/core/filter.c*. + +SEE ALSO +======== + +**bpf**\ (2), +**cgroups**\ (7), +**ip**\ (8), +**perf_event_open**\ (2), +**sendmsg**\ (2), +**socket**\ (7), +**tc-bpf**\ (8)''' +        print(footer) + +    def print_proto(self, helper): +        """ +        Format function protocol with bold and italics markers. This makes RST +        file less readable, but gives nice results in the manual page. +        """ +        proto = helper.proto_break_down() + +        print('**%s %s%s(' % (proto['ret_type'], +                              proto['ret_star'].replace('*', '\\*'), +                              proto['name']), +              end='') + +        comma = '' +        for a in proto['args']: +            one_arg = '{}{}'.format(comma, a['type']) +            if a['name']: +                if a['star']: +                    one_arg += ' {}**\ '.format(a['star'].replace('*', '\\*')) +                else: +                    one_arg += '** ' +                one_arg += '*{}*\\ **'.format(a['name']) +            comma = ', ' +            print(one_arg, end='') + +        print(')**') + +    def print_one(self, helper): +        self.print_proto(helper) + +        if (helper.desc): +            print('\tDescription') +            # Do not strip all newline characters: formatted code at the end of +            # a section must be followed by a blank line. +            for line in re.sub('\n$', '', helper.desc, count=1).split('\n'): +                print('{}{}'.format('\t\t' if line else '', line)) + +        if (helper.ret): +            print('\tReturn') +            for line in helper.ret.rstrip().split('\n'): +                print('{}{}'.format('\t\t' if line else '', line)) + +        print('') + +############################################################################### + +# If script is launched from scripts/ from kernel tree and can access +# ../include/uapi/linux/bpf.h, use it as a default name for the file to parse, +# otherwise the --filename argument will be required from the command line. +script = os.path.abspath(sys.argv[0]) +linuxRoot = os.path.dirname(os.path.dirname(script)) +bpfh = os.path.join(linuxRoot, 'include/uapi/linux/bpf.h') + +argParser = argparse.ArgumentParser(description=""" +Parse eBPF header file and generate documentation for eBPF helper functions. +The RST-formatted output produced can be turned into a manual page with the +rst2man utility. +""") +if (os.path.isfile(bpfh)): +    argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h', +                           default=bpfh) +else: +    argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h') +args = argParser.parse_args() + +# Parse file. +headerParser = HeaderParser(args.filename) +headerParser.run() + +# Print formatted output to standard output. +printer = PrinterRST(headerParser.helpers) +printer.print_all() diff --git a/scripts/cc-can-link.sh b/scripts/cc-can-link.sh new file mode 100755 index 000000000000..208eb2825dab --- /dev/null +++ b/scripts/cc-can-link.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +cat << "END" | $@ -x c - -o /dev/null >/dev/null 2>&1 && echo "y" +#include <stdio.h> +int main(void) +{ +	printf(""); +	return 0; +} +END diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index e16d6713f236..a9c05506e325 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1,9 +1,11 @@  #!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 +#  # (c) 2001, Dave Jones. (the file handling bit)  # (c) 2005, Joel Schopp <[email protected]> (the ugly bit)  # (c) 2007,2008, Andy Whitcroft <[email protected]> (new conditions, test suite)  # (c) 2008-2010 Andy Whitcroft <[email protected]> -# Licensed under the terms of the GNU GPL License version 2 +# (c) 2010-2018 Joe Perches <[email protected]>  use strict;  use warnings; @@ -2375,6 +2377,14 @@ sub process {  		my $rawline = $rawlines[$linenr - 1]; +# check if it's a mode change, rename or start of a patch +		if (!$in_commit_log && +		    ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ || +		    ($line =~ /^rename (?:from|to) \S+\s*$/ || +		     $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) { +			$is_patch = 1; +		} +  #extract the line range in the file after the patch is applied  		if (!$in_commit_log &&  		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { @@ -2596,12 +2606,6 @@ sub process {  			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);  		} -# Check for old stable address -		if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) { -			ERROR("STABLE_ADDRESS", -			      "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr); -		} -  # Check for unwanted Gerrit info  		if ($in_commit_log && $line =~ /^\s*change-id:/i) {  			ERROR("GERRIT_CHANGE_ID", @@ -5041,7 +5045,7 @@ sub process {  				$tmp_stmt =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;  				$tmp_stmt =~ s/\#+\s*$arg\b//g;  				$tmp_stmt =~ s/\b$arg\s*\#\#//g; -				my $use_cnt = $tmp_stmt =~ s/\b$arg\b//g; +				my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;  				if ($use_cnt > 1) {  					CHK("MACRO_ARG_REUSE",  					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); @@ -5121,16 +5125,6 @@ sub process {  			}  		} -# make sure symbols are always wrapped with VMLINUX_SYMBOL() ... -# all assignments may have only one of the following with an assignment: -#	. -#	ALIGN(...) -#	VMLINUX_SYMBOL(...) -		if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { -			WARN("MISSING_VMLINUX_SYMBOL", -			     "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); -		} -  # check for redundant bracing round if etc  		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {  			my ($level, $endln, @chunks) = diff --git a/scripts/clang-version.sh b/scripts/clang-version.sh index 9780efa56980..dbf0a31eb111 100755 --- a/scripts/clang-version.sh +++ b/scripts/clang-version.sh @@ -10,24 +10,14 @@  # clang-5.0.1 etc.  # -if [ "$1" = "-p" ] ; then -	with_patchlevel=1; -	shift; -fi -  compiler="$*" -if [ ${#compiler} -eq 0 ]; then -	echo "Error: No compiler specified." -	printf "Usage:\n\t$0 <clang-command>\n" +if !( $compiler --version | grep -q clang) ; then +	echo 0  	exit 1  fi  MAJOR=$(echo __clang_major__ | $compiler -E -x c - | tail -n 1)  MINOR=$(echo __clang_minor__ | $compiler -E -x c - | tail -n 1) -if [ "x$with_patchlevel" != "x" ] ; then -	PATCHLEVEL=$(echo __clang_patchlevel__ | $compiler -E -x c - | tail -n 1) -	printf "%02d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL -else -	printf "%02d%02d\\n" $MAJOR $MINOR -fi +PATCHLEVEL=$(echo __clang_patchlevel__ | $compiler -E -x c - | tail -n 1) +printf "%d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL diff --git a/scripts/coccinelle/locks/mini_lock.cocci b/scripts/coccinelle/locks/mini_lock.cocci index 47f649b0ea87..19c6ee5b986b 100644 --- a/scripts/coccinelle/locks/mini_lock.cocci +++ b/scripts/coccinelle/locks/mini_lock.cocci @@ -67,12 +67,14 @@ identifier lock,unlock;  @@  *lock(E1@p,...); -<+... when != E1 +... when != E1 +    when any  if (...) {    ... when != E1  *  return@r ...;  } -...+> +... when != E1 +    when any  *unlock@up(E1,...);  @script:python depends on org@ diff --git a/scripts/coccinelle/null/deref_null.cocci b/scripts/coccinelle/null/deref_null.cocci index b16ccb7663a7..cbc6184e69ef 100644 --- a/scripts/coccinelle/null/deref_null.cocci +++ b/scripts/coccinelle/null/deref_null.cocci @@ -14,18 +14,10 @@ virtual context  virtual org  virtual report -@ifm@ -expression *E; -statement S1,S2; -position p1; -@@ - -if@p1 ((E == NULL && ...) || ...) S1 else S2 -  // The following two rules are separate, because both can match a single  // expression in different ways  @pr1 expression@ -expression *ifm.E; +expression E;  identifier f;  position p1;  @@ @@ -33,7 +25,7 @@ position p1;   (E != NULL && ...) ? <+...E->f@p1...+> : ...  @pr2 expression@ -expression *ifm.E; +expression E;  identifier f;  position p2;  @@ @@ -46,6 +38,14 @@ position p2;   sizeof(<+...E->f@p2...+>)  ) +@ifm@ +expression *E; +statement S1,S2; +position p1; +@@ + +if@p1 ((E == NULL && ...) || ...) S1 else S2 +  // For org and report modes  @r depends on !context && (org || report) exists@ @@ -212,16 +212,8 @@ else S3  // The following three rules are duplicates of ifm, pr1 and pr2 respectively.  // It is need because the previous rule as already made a "change". -@ifm1 depends on context && !org && !report@ -expression *E; -statement S1,S2; -position p1; -@@ - -if@p1 ((E == NULL && ...) || ...) S1 else S2 -  @pr11 depends on context && !org && !report expression@ -expression *ifm1.E; +expression E;  identifier f;  position p1;  @@ @@ -229,7 +221,7 @@ position p1;   (E != NULL && ...) ? <+...E->f@p1...+> : ...  @pr12 depends on context && !org && !report expression@ -expression *ifm1.E; +expression E;  identifier f;  position p2;  @@ @@ -242,6 +234,14 @@ position p2;   sizeof(<+...E->f@p2...+>)  ) +@ifm1 depends on context && !org && !report@ +expression *E; +statement S1,S2; +position p1; +@@ + +if@p1 ((E == NULL && ...) || ...) S1 else S2 +  @depends on context && !org && !report exists@  expression subE <= ifm1.E;  expression *ifm1.E; diff --git a/scripts/depmod.sh b/scripts/depmod.sh index 9831cca31240..1a6f85e0e6e1 100755 --- a/scripts/depmod.sh +++ b/scripts/depmod.sh @@ -3,36 +3,17 @@  #  # A depmod wrapper used by the toplevel Makefile -if test $# -ne 3; then -	echo "Usage: $0 /sbin/depmod <kernelrelease> <symbolprefix>" >&2 +if test $# -ne 2; then +	echo "Usage: $0 /sbin/depmod <kernelrelease>" >&2  	exit 1  fi  DEPMOD=$1  KERNELRELEASE=$2 -SYMBOL_PREFIX=$3  if ! test -r System.map -a -x "$DEPMOD"; then  	exit 0  fi -# older versions of depmod don't support -P <symbol-prefix> -# support was added in module-init-tools 3.13 -if test -n "$SYMBOL_PREFIX"; then -	release=$("$DEPMOD" --version) -	package=$(echo "$release" | cut -d' ' -f 1) -	if test "$package" = "module-init-tools"; then -		version=$(echo "$release" | cut -d' ' -f 2) -		later=$(printf '%s\n' "$version" "3.13" | sort -V | tail -n 1) -		if test "$later" != "$version"; then -			# module-init-tools < 3.13, drop the symbol prefix -			SYMBOL_PREFIX="" -		fi -	fi -	if test -n "$SYMBOL_PREFIX"; then -		SYMBOL_PREFIX="-P $SYMBOL_PREFIX" -	fi -fi -  # older versions of depmod require the version string to start with three  # numbers, so we cheat with a symlink here  depmod_hack_needed=true @@ -55,7 +36,7 @@ set -- -ae -F System.map  if test -n "$INSTALL_MOD_PATH"; then  	set -- "$@" -b "$INSTALL_MOD_PATH"  fi -"$DEPMOD" "$@" "$KERNELRELEASE" $SYMBOL_PREFIX +"$DEPMOD" "$@" "$KERNELRELEASE"  ret=$?  if $depmod_hack_needed; then diff --git a/scripts/documentation-file-ref-check b/scripts/documentation-file-ref-check index bc1659900e89..078999a3fdff 100755 --- a/scripts/documentation-file-ref-check +++ b/scripts/documentation-file-ref-check @@ -1,15 +1,158 @@ -#!/bin/sh +#!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 +#  # Treewide grep for references to files under Documentation, and report  # non-existing files in stderr. -for f in $(git ls-files); do -	for ref in $(grep -ho "Documentation/[A-Za-z0-9_.,~/*+-]*" "$f"); do -		# presume trailing . and , are not part of the name -		ref=${ref%%[.,]} - -		# use ls to handle wildcards -		if ! ls $ref >/dev/null 2>&1; then -			echo "$f: $ref" >&2 -		fi -	done -done +use warnings; +use strict; +use Getopt::Long qw(:config no_auto_abbrev); + +my $scriptname = $0; +$scriptname =~ s,.*/([^/]+/),$1,; + +# Parse arguments +my $help = 0; +my $fix = 0; + +GetOptions( +	'fix' => \$fix, +	'h|help|usage' => \$help, +); + +if ($help != 0) { +    print "$scriptname [--help] [--fix]\n"; +    exit -1; +} + +# Step 1: find broken references +print "Finding broken references. This may take a while...  " if ($fix); + +my %broken_ref; + +open IN, "git grep 'Documentation/'|" +     or die "Failed to run git grep"; +while (<IN>) { +	next if (!m/^([^:]+):(.*)/); + +	my $f = $1; +	my $ln = $2; + +	# Makefiles and scripts contain nasty expressions to parse docs +	next if ($f =~ m/Makefile/ || $f =~ m/\.sh$/); + +	# Skip this script +	next if ($f eq $scriptname); + +	if ($ln =~ m,\b(\S*)(Documentation/[A-Za-z0-9\_\.\,\~/\*\[\]\?+-]*)(.*),) { +		my $prefix = $1; +		my $ref = $2; +		my $base = $2; +		my $extra = $3; + +		# some file references are like: +		# /usr/src/linux/Documentation/DMA-{API,mapping}.txt +		# For now, ignore them +		next if ($extra =~ m/^{/); + +		# Remove footnotes at the end like: +		# Documentation/devicetree/dt-object-internal.txt[1] +		$ref =~ s/(txt|rst)\[\d+]$/$1/; + +		# Remove ending ']' without any '[' +		$ref =~ s/\].*// if (!($ref =~ m/\[/)); + +		# Remove puntuation marks at the end +		$ref =~ s/[\,\.]+$//; + +		my $fulref = "$prefix$ref"; + +		$fulref =~ s/^(\<file|ref)://; +		$fulref =~ s/^[\'\`]+//; +		$fulref =~ s,^\$\(.*\)/,,; +		$base =~ s,.*/,,; + +		# Remove URL false-positives +		next if ($fulref =~ m/^http/); + +		# Check if exists, evaluating wildcards +		next if (grep -e, glob("$ref $fulref")); + +		# Accept relative Documentation patches for tools/ +		if ($f =~ m/tools/) { +			my $path = $f; +			$path =~ s,(.*)/.*,$1,; +			next if (grep -e, glob("$path/$ref $path/$fulref")); +		} + +		if ($fix) { +			if (!($ref =~ m/(scripts|Kconfig|Kbuild)/)) { +				$broken_ref{$ref}++; +			} +		} else { +			print STDERR "$f: $fulref\n"; +		} +	} +} + +exit 0 if (!$fix); + +# Step 2: Seek for file name alternatives +print "Auto-fixing broken references. Please double-check the results\n"; + +foreach my $ref (keys %broken_ref) { +	my $new =$ref; + +	# get just the basename +	$new =~ s,.*/,,; + +	my $f=""; + +	# usual reason for breakage: DT file moved around +	if ($ref =~ /devicetree/) { +		my $search = $new; +		$search =~ s,^.*/,,; +		$f = qx(find Documentation/devicetree/ -iname "*$search*") if ($search); +		if (!$f) { +			# Manufacturer name may have changed +			$search =~ s/^.*,//; +			$f = qx(find Documentation/devicetree/ -iname "*$search*") if ($search); +		} +	} + +	# usual reason for breakage: file renamed to .rst +	if (!$f) { +		$new =~ s/\.txt$/.rst/; +		$f=qx(find . -iname $new) if ($new); +	} + +	# usual reason for breakage: use dash or underline +	if (!$f) { +		$new =~ s/[-_]/[-_]/g; +		$f=qx(find . -iname $new) if ($new); +	} + +	# Wild guess: seek for the same name on another place +	if (!$f) { +		$f = qx(find . -iname $new) if ($new); +	} + +	my @find = split /\s+/, $f; + +	if (!$f) { +		print STDERR "ERROR: Didn't find a replacement for $ref\n"; +	} elsif (scalar(@find) > 1) { +		print STDERR "WARNING: Won't auto-replace, as found multiple files close to $ref:\n"; +		foreach my $j (@find) { +			$j =~ s,^./,,; +			print STDERR "    $j\n"; +		} +	} else { +		$f = $find[0]; +		$f =~ s,^./,,; +		print "INFO: Replacing $ref to $f\n"; +		foreach my $j (qx(git grep -l $ref)) { +			qx(sed "s\@$ref\@$f\@g" -i $j); +		} +	} +} diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c index c07ba4da9e36..a2cc1036c915 100644 --- a/scripts/dtc/checks.c +++ b/scripts/dtc/checks.c @@ -255,7 +255,7 @@ static void check_duplicate_node_names(struct check *c, struct dt_info *dti,  		     child2;  		     child2 = child2->next_sibling)  			if (streq(child->name, child2->name)) -				FAIL(c, dti, node, "Duplicate node name"); +				FAIL(c, dti, child2, "Duplicate node name");  }  ERROR(duplicate_node_names, check_duplicate_node_names, NULL); @@ -317,6 +317,11 @@ static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti,  	const char *unitname = get_unitname(node);  	struct property *prop = get_property(node, "reg"); +	if (get_subnode(node, "__overlay__")) { +		/* HACK: Overlay fragments are a special case */ +		return; +	} +  	if (!prop) {  		prop = get_property(node, "ranges");  		if (prop && !prop->val.len) @@ -579,6 +584,8 @@ static void fixup_phandle_references(struct check *c, struct dt_info *dti,  			phandle = get_node_phandle(dt, refnode);  			*((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); + +			reference_node(refnode);  		}  	}  } @@ -609,11 +616,21 @@ static void fixup_path_references(struct check *c, struct dt_info *dti,  			path = refnode->fullpath;  			prop->val = data_insert_at_marker(prop->val, m, path,  							  strlen(path) + 1); + +			reference_node(refnode);  		}  	}  }  ERROR(path_references, fixup_path_references, NULL, &duplicate_node_names); +static void fixup_omit_unused_nodes(struct check *c, struct dt_info *dti, +				    struct node *node) +{ +	if (node->omit_if_unused && !node->is_referenced) +		delete_node(node); +} +ERROR(omit_unused_nodes, fixup_omit_unused_nodes, NULL, &phandle_references, &path_references); +  /*   * Semantic checks   */ @@ -787,10 +804,9 @@ static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *  		FAIL(c, dti, node, "incorrect #size-cells for PCI bridge");  	prop = get_property(node, "bus-range"); -	if (!prop) { -		FAIL(c, dti, node, "missing bus-range for PCI bridge"); +	if (!prop)  		return; -	} +  	if (prop->val.len != (sizeof(cell_t) * 2)) {  		FAIL_PROP(c, dti, node, prop, "value must be 2 cells");  		return; @@ -1018,6 +1034,36 @@ static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *d  }  WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size); +static void check_unique_unit_address(struct check *c, struct dt_info *dti, +					      struct node *node) +{ +	struct node *childa; + +	if (node->addr_cells < 0 || node->size_cells < 0) +		return; + +	if (!node->children) +		return; + +	for_each_child(node, childa) { +		struct node *childb; +		const char *addr_a = get_unitname(childa); + +		if (!strlen(addr_a)) +			continue; + +		for_each_child(node, childb) { +			const char *addr_b = get_unitname(childb); +			if (childa == childb) +				break; + +			if (streq(addr_a, addr_b)) +				FAIL(c, dti, childb, "duplicate unit-address (also used in node %s)", childa->fullpath); +		} +	} +} +WARNING(unique_unit_address, check_unique_unit_address, NULL, &avoid_default_addr_size); +  static void check_obsolete_chosen_interrupt_controller(struct check *c,  						       struct dt_info *dti,  						       struct node *node) @@ -1358,6 +1404,152 @@ static void check_interrupts_property(struct check *c,  }  WARNING(interrupts_property, check_interrupts_property, &phandle_references); +static const struct bus_type graph_port_bus = { +	.name = "graph-port", +}; + +static const struct bus_type graph_ports_bus = { +	.name = "graph-ports", +}; + +static void check_graph_nodes(struct check *c, struct dt_info *dti, +			      struct node *node) +{ +	struct node *child; + +	for_each_child(node, child) { +		if (!(strprefixeq(child->name, child->basenamelen, "endpoint") || +		      get_property(child, "remote-endpoint"))) +			continue; + +		node->bus = &graph_port_bus; + +		/* The parent of 'port' nodes can be either 'ports' or a device */ +		if (!node->parent->bus && +		    (streq(node->parent->name, "ports") || get_property(node, "reg"))) +			node->parent->bus = &graph_ports_bus; + +		break; +	} + +} +WARNING(graph_nodes, check_graph_nodes, NULL); + +static void check_graph_child_address(struct check *c, struct dt_info *dti, +				      struct node *node) +{ +	int cnt = 0; +	struct node *child; + +	if (node->bus != &graph_ports_bus && node->bus != &graph_port_bus) +		return; + +	for_each_child(node, child) { +		struct property *prop = get_property(child, "reg"); + +		/* No error if we have any non-zero unit address */ +		if (prop && propval_cell(prop) != 0) +			return; + +		cnt++; +	} + +	if (cnt == 1 && node->addr_cells != -1) +		FAIL(c, dti, node, "graph node has single child node '%s', #address-cells/#size-cells are not necessary", +		     node->children->name); +} +WARNING(graph_child_address, check_graph_child_address, NULL, &graph_nodes); + +static void check_graph_reg(struct check *c, struct dt_info *dti, +			    struct node *node) +{ +	char unit_addr[9]; +	const char *unitname = get_unitname(node); +	struct property *prop; + +	prop = get_property(node, "reg"); +	if (!prop || !unitname) +		return; + +	if (!(prop->val.val && prop->val.len == sizeof(cell_t))) { +		FAIL(c, dti, node, "graph node malformed 'reg' property"); +		return; +	} + +	snprintf(unit_addr, sizeof(unit_addr), "%x", propval_cell(prop)); +	if (!streq(unitname, unit_addr)) +		FAIL(c, dti, node, "graph node unit address error, expected \"%s\"", +		     unit_addr); + +	if (node->parent->addr_cells != 1) +		FAIL_PROP(c, dti, node, get_property(node, "#address-cells"), +			  "graph node '#address-cells' is %d, must be 1", +			  node->parent->addr_cells); +	if (node->parent->size_cells != 0) +		FAIL_PROP(c, dti, node, get_property(node, "#size-cells"), +			  "graph node '#size-cells' is %d, must be 0", +			  node->parent->size_cells); +} + +static void check_graph_port(struct check *c, struct dt_info *dti, +			     struct node *node) +{ +	if (node->bus != &graph_port_bus) +		return; + +	if (!strprefixeq(node->name, node->basenamelen, "port")) +		FAIL(c, dti, node, "graph port node name should be 'port'"); + +	check_graph_reg(c, dti, node); +} +WARNING(graph_port, check_graph_port, NULL, &graph_nodes); + +static struct node *get_remote_endpoint(struct check *c, struct dt_info *dti, +					struct node *endpoint) +{ +	int phandle; +	struct node *node; +	struct property *prop; + +	prop = get_property(endpoint, "remote-endpoint"); +	if (!prop) +		return NULL; + +	phandle = propval_cell(prop); +	/* Give up if this is an overlay with external references */ +	if (phandle == 0 || phandle == -1) +		return NULL; + +	node = get_node_by_phandle(dti->dt, phandle); +	if (!node) +		FAIL_PROP(c, dti, endpoint, prop, "graph phandle is not valid"); + +	return node; +} + +static void check_graph_endpoint(struct check *c, struct dt_info *dti, +				 struct node *node) +{ +	struct node *remote_node; + +	if (!node->parent || node->parent->bus != &graph_port_bus) +		return; + +	if (!strprefixeq(node->name, node->basenamelen, "endpoint")) +		FAIL(c, dti, node, "graph endpont node name should be 'endpoint'"); + +	check_graph_reg(c, dti, node); + +	remote_node = get_remote_endpoint(c, dti, node); +	if (!remote_node) +		return; + +	if (get_remote_endpoint(c, dti, remote_node) != node) +		FAIL(c, dti, node, "graph connection to node '%s' is not bidirectional", +		     remote_node->fullpath); +} +WARNING(graph_endpoint, check_graph_endpoint, NULL, &graph_nodes); +  static struct check *check_table[] = {  	&duplicate_node_names, &duplicate_property_names,  	&node_name_chars, &node_name_format, &property_name_chars, @@ -1367,6 +1559,7 @@ static struct check *check_table[] = {  	&explicit_phandles,  	&phandle_references, &path_references, +	&omit_unused_nodes,  	&address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,  	&device_type_is_string, &model_is_string, &status_is_string, @@ -1391,6 +1584,7 @@ static struct check *check_table[] = {  	&avoid_default_addr_size,  	&avoid_unnecessary_addr_size, +	&unique_unit_address,  	&obsolete_chosen_interrupt_controller,  	&chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path, @@ -1417,6 +1611,8 @@ static struct check *check_table[] = {  	&alias_paths, +	&graph_nodes, &graph_child_address, &graph_port, &graph_endpoint, +  	&always_fail,  }; diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l index fd825ebba69c..615b7ec6588f 100644 --- a/scripts/dtc/dtc-lexer.l +++ b/scripts/dtc/dtc-lexer.l @@ -153,6 +153,13 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);  			return DT_DEL_NODE;  		} +<*>"/omit-if-no-ref/"	{ +			DPRINT("Keyword: /omit-if-no-ref/\n"); +			DPRINT("<PROPNODENAME>\n"); +			BEGIN(PROPNODENAME); +			return DT_OMIT_NO_REF; +		} +  <*>{LABEL}:	{  			DPRINT("Label: %s\n", yytext);  			yylval.labelref = xstrdup(yytext); diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y index 44af170abfea..011a5b25539a 100644 --- a/scripts/dtc/dtc-parser.y +++ b/scripts/dtc/dtc-parser.y @@ -63,6 +63,7 @@ extern bool treesource_error;  %token DT_BITS  %token DT_DEL_PROP  %token DT_DEL_NODE +%token DT_OMIT_NO_REF  %token <propnodename> DT_PROPNODENAME  %token <integer> DT_LITERAL  %token <integer> DT_CHAR_LITERAL @@ -190,18 +191,18 @@ devicetree:  		}  	| devicetree DT_REF nodedef  		{ -			struct node *target = get_node_by_ref($1, $2); - -			if (target) { -				merge_nodes(target, $3); +			/* +			 * We rely on the rule being always: +			 *   versioninfo plugindecl memreserves devicetree +			 * so $-1 is what we want (plugindecl) +			 */ +			if ($<flags>-1 & DTSF_PLUGIN) { +				add_orphan_node($1, $3, $2);  			} else { -				/* -				 * We rely on the rule being always: -				 *   versioninfo plugindecl memreserves devicetree -				 * so $-1 is what we want (plugindecl) -				 */ -				if ($<flags>-1 & DTSF_PLUGIN) -					add_orphan_node($1, $3, $2); +				struct node *target = get_node_by_ref($1, $2); + +				if (target) +					merge_nodes(target, $3);  				else  					ERROR(&@2, "Label or path %s not found", $2);  			} @@ -219,6 +220,18 @@ devicetree:  			$$ = $1;  		} +	| devicetree DT_OMIT_NO_REF DT_REF ';' +		{ +			struct node *target = get_node_by_ref($1, $3); + +			if (target) +				omit_node_if_unused(target); +			else +				ERROR(&@3, "Label or path %s not found", $3); + + +			$$ = $1; +		}  	;  nodedef: @@ -523,6 +536,10 @@ subnode:  		{  			$$ = name_node(build_node_delete(), $2);  		} +	| DT_OMIT_NO_REF subnode +		{ +			$$ = omit_node_if_unused($2); +		}  	| DT_LABEL subnode  		{  			add_label(&$2->labels, $1); diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h index 3b18a42b866e..6d667701ab6a 100644 --- a/scripts/dtc/dtc.h +++ b/scripts/dtc/dtc.h @@ -168,6 +168,8 @@ struct node {  	struct label *labels;  	const struct bus_type *bus; + +	bool omit_if_unused, is_referenced;  };  #define for_each_label_withdel(l0, l) \ @@ -202,6 +204,8 @@ struct property *reverse_properties(struct property *first);  struct node *build_node(struct property *proplist, struct node *children);  struct node *build_node_delete(void);  struct node *name_node(struct node *node, char *name); +struct node *omit_node_if_unused(struct node *node); +struct node *reference_node(struct node *node);  struct node *chain_node(struct node *first, struct node *list);  struct node *merge_nodes(struct node *old_node, struct node *new_node);  struct node *add_orphan_node(struct node *old_node, struct node *new_node, char *ref); diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c index 57b7db2ed153..6e4c367f54b3 100644 --- a/scripts/dtc/livetree.c +++ b/scripts/dtc/livetree.c @@ -134,6 +134,20 @@ struct node *name_node(struct node *node, char *name)  	return node;  } +struct node *omit_node_if_unused(struct node *node) +{ +	node->omit_if_unused = 1; + +	return node; +} + +struct node *reference_node(struct node *node) +{ +	node->is_referenced = 1; + +	return node; +} +  struct node *merge_nodes(struct node *old_node, struct node *new_node)  {  	struct property *new_prop, *old_prop; @@ -224,10 +238,16 @@ struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref)  	struct data d = empty_data;  	char *name; -	d = data_add_marker(d, REF_PHANDLE, ref); -	d = data_append_integer(d, 0xffffffff, 32); +	if (ref[0] == '/') { +		d = data_append_data(d, ref, strlen(ref) + 1); -	p = build_property("target", d); +		p = build_property("target-path", d); +	} else { +		d = data_add_marker(d, REF_PHANDLE, ref); +		d = data_append_integer(d, 0xffffffff, 32); + +		p = build_property("target", d); +	}  	xasprintf(&name, "fragment@%u",  			next_orphan_fragment++); diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h index ad87849e333b..b00f14ff7a17 100644 --- a/scripts/dtc/version_gen.h +++ b/scripts/dtc/version_gen.h @@ -1 +1 @@ -#define DTC_VERSION "DTC 1.4.6-gaadd0b65" +#define DTC_VERSION "DTC 1.4.6-g84e414b0" diff --git a/scripts/extract_xc3028.pl b/scripts/extract_xc3028.pl index 61d9b256c658..a1c51b7e4baf 100755 --- a/scripts/extract_xc3028.pl +++ b/scripts/extract_xc3028.pl @@ -1,6 +1,6 @@  #!/usr/bin/env perl -# Copyright (c) Mauro Carvalho Chehab <[email protected]> +# Copyright (c) Mauro Carvalho Chehab <[email protected]>  # Released under GPLv2  #  # In order to use, you need to: diff --git a/scripts/faddr2line b/scripts/faddr2line index 9e5735a4d3a5..a0149db00be7 100755 --- a/scripts/faddr2line +++ b/scripts/faddr2line @@ -56,7 +56,7 @@ command -v ${SIZE} >/dev/null 2>&1 || die "size isn't installed"  command -v ${NM} >/dev/null 2>&1 || die "nm isn't installed"  usage() { -	echo "usage: faddr2line <object file> <func+offset> <func+offset>..." >&2 +	echo "usage: faddr2line [--list] <object file> <func+offset> <func+offset>..." >&2  	exit 1  } @@ -166,12 +166,25 @@ __faddr2line() {  		local file_lines=$(${ADDR2LINE} -fpie $objfile $addr | sed "s; $dir_prefix\(\./\)*; ;")  		[[ -z $file_lines ]] && return +		if [[ $LIST = 0 ]]; then +			echo "$file_lines" | while read -r line +			do +				echo $line +			done +			DONE=1; +			return +		fi +  		# show each line with context  		echo "$file_lines" | while read -r line  		do +			echo  			echo $line -			eval $(echo $line | awk -F "[ :]" '{printf("n1=%d;n2=%d;f=%s",$NF-5, $NF+5, $(NF-1))}') -			awk 'NR>=strtonum("'$n1'") && NR<=strtonum("'$n2'") {printf("%d\t%s\n", NR, $0)}' $f +			n=$(echo $line | sed 's/.*:\([0-9]\+\).*/\1/g') +			n1=$[$n-5] +			n2=$[$n+5] +			f=$(echo $line | sed 's/.*at \(.\+\):.*/\1/g') +			awk 'NR>=strtonum("'$n1'") && NR<=strtonum("'$n2'") { if (NR=='$n') printf(">%d<", NR); else printf(" %d ", NR); printf("\t%s\n", $0)}' $f  		done  		DONE=1 @@ -182,6 +195,10 @@ __faddr2line() {  [[ $# -lt 2 ]] && usage  objfile=$1 + +LIST=0 +[[ "$objfile" == "--list" ]] && LIST=1 && shift && objfile=$1 +  [[ ! -f $objfile ]] && die "can't find objfile $objfile"  shift diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile index e2ff425f4c7e..326254653bd0 100644 --- a/scripts/gcc-plugins/Makefile +++ b/scripts/gcc-plugins/Makefile @@ -1,4 +1,5 @@  # SPDX-License-Identifier: GPL-2.0 +PLUGINCC := $(CONFIG_PLUGIN_HOSTCC:"%"=%)  GCC_PLUGINS_DIR := $(shell $(CC) -print-file-name=plugin)  ifeq ($(PLUGINCC),$(HOSTCC)) @@ -13,10 +14,6 @@ else    export HOST_EXTRACXXFLAGS  endif -ifneq ($(CFLAGS_KCOV), $(SANCOV_PLUGIN)) -  GCC_PLUGIN := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGIN)) -endif -  export HOSTLIBS  $(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h diff --git a/scripts/gcc-x86_32-has-stack-protector.sh b/scripts/gcc-x86_32-has-stack-protector.sh index 6b2aeefb9cd3..f5c119495254 100755 --- a/scripts/gcc-x86_32-has-stack-protector.sh +++ b/scripts/gcc-x86_32-has-stack-protector.sh @@ -1,9 +1,4 @@  #!/bin/sh  # SPDX-License-Identifier: GPL-2.0 -echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs" -if [ "$?" -eq "0" ] ; then -	echo y -else -	echo n -fi +echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m32 -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs" diff --git a/scripts/gcc-x86_64-has-stack-protector.sh b/scripts/gcc-x86_64-has-stack-protector.sh index 4a48bdcd4d6b..75e4e22b986a 100755 --- a/scripts/gcc-x86_64-has-stack-protector.sh +++ b/scripts/gcc-x86_64-has-stack-protector.sh @@ -1,9 +1,4 @@  #!/bin/sh  # SPDX-License-Identifier: GPL-2.0 -echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -mcmodel=kernel -fno-PIE -fstack-protector - -o - 2> /dev/null | grep -q "%gs" -if [ "$?" -eq "0" ] ; then -	echo y -else -	echo n -fi +echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m64 -O0 -mcmodel=kernel -fno-PIE -fstack-protector - -o - 2> /dev/null | grep -q "%gs" diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile index ef0287e42957..03b7ce97de14 100644 --- a/scripts/genksyms/Makefile +++ b/scripts/genksyms/Makefile @@ -14,14 +14,14 @@ genksyms-objs	:= genksyms.o parse.tab.o lex.lex.o  # so that 'bison: not found' will be displayed if it is missing.  ifeq ($(findstring 1,$(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),) -quiet_cmd_bison_no_warn = $(quet_cmd_bison) +quiet_cmd_bison_no_warn = $(quiet_cmd_bison)        cmd_bison_no_warn = $(YACC) --version >/dev/null; \  			  $(cmd_bison) 2>/dev/null  $(obj)/parse.tab.c: $(src)/parse.y FORCE  	$(call if_changed,bison_no_warn) -quiet_cmd_bison_h_no_warn = $(quet_cmd_bison_h) +quiet_cmd_bison_h_no_warn = $(quiet_cmd_bison_h)        cmd_bison_h_no_warn = $(YACC) --version >/dev/null; \  			    $(cmd_bison_h) 2>/dev/null diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c index c9235d8340f1..e007840f45b9 100644 --- a/scripts/genksyms/genksyms.c +++ b/scripts/genksyms/genksyms.c @@ -45,7 +45,6 @@ int in_source_file;  static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types,  	   flag_preserve, flag_warnings, flag_rel_crcs; -static const char *mod_prefix = "";  static int errors;  static int nsyms; @@ -693,10 +692,10 @@ void export_symbol(const char *name)  			fputs(">\n", debugfile);  		/* Used as a linker script. */ -		printf(!flag_rel_crcs ? "%s__crc_%s = 0x%08lx;\n" : +		printf(!flag_rel_crcs ? "__crc_%s = 0x%08lx;\n" :  		       "SECTIONS { .rodata : ALIGN(4) { " -		       "%s__crc_%s = .; LONG(0x%08lx); } }\n", -		       mod_prefix, name, crc); +		       "__crc_%s = .; LONG(0x%08lx); } }\n", +		       name, crc);  	}  } @@ -769,7 +768,6 @@ int main(int argc, char **argv)  #ifdef __GNU_LIBRARY__  	struct option long_opts[] = { -		{"symbol-prefix", 1, 0, 's'},  		{"debug", 0, 0, 'd'},  		{"warnings", 0, 0, 'w'},  		{"quiet", 0, 0, 'q'}, @@ -789,9 +787,6 @@ int main(int argc, char **argv)  	while ((o = getopt(argc, argv, "s:dwqVDr:T:phR")) != EOF)  #endif				/* __GNU_LIBRARY__ */  		switch (o) { -		case 's': -			mod_prefix = optarg; -			break;  		case 'd':  			flag_debug++;  			break; diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 99c96e86eccb..c87fa734e3e1 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -1,4 +1,6 @@  #!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 +#  # (c) 2007, Joe Perches <[email protected]>  #           created from checkpatch.pl  # @@ -7,8 +9,6 @@  #  # usage: perl scripts/get_maintainer.pl [OPTIONS] <patch>  #        perl scripts/get_maintainer.pl [OPTIONS] -f <file> -# -# Licensed under the terms of the GNU GPL License version 2  use warnings;  use strict; @@ -542,7 +542,18 @@ foreach my $file (@ARGV) {  	while (<$patch>) {  	    my $patch_line = $_; -	    if (m/^\+\+\+\s+(\S+)/ or m/^---\s+(\S+)/) { +	    if (m/^ mode change [0-7]+ => [0-7]+ (\S+)\s*$/) { +		my $filename = $1; +		push(@files, $filename); +	    } elsif (m/^rename (?:from|to) (\S+)\s*$/) { +		my $filename = $1; +		push(@files, $filename); +	    } elsif (m/^diff --git a\/(\S+) b\/(\S+)\s*$/) { +		my $filename1 = $1; +		my $filename2 = $2; +		push(@files, $filename1); +		push(@files, $filename2); +	    } elsif (m/^\+\+\+\s+(\S+)/ or m/^---\s+(\S+)/) {  		my $filename = $1;  		$filename =~ s@^[^/]*/@@;  		$filename =~ s@\n@@; diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 5abfbf1b8fe2..a9186a98a37d 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -62,7 +62,6 @@ static struct sym_entry *table;  static unsigned int table_size, table_cnt;  static int all_symbols = 0;  static int absolute_percpu = 0; -static char symbol_prefix_char = '\0';  static int base_relative = 0;  int token_profit[0x10000]; @@ -75,7 +74,6 @@ unsigned char best_table_len[256];  static void usage(void)  {  	fprintf(stderr, "Usage: kallsyms [--all-symbols] " -			"[--symbol-prefix=<prefix char>] "  			"[--base-relative] < in.map > out.S\n");  	exit(1);  } @@ -113,28 +111,22 @@ static int check_symbol_range(const char *sym, unsigned long long addr,  static int read_symbol(FILE *in, struct sym_entry *s)  { -	char str[500]; -	char *sym, stype; +	char sym[500], stype;  	int rc; -	rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str); +	rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, sym);  	if (rc != 3) { -		if (rc != EOF && fgets(str, 500, in) == NULL) +		if (rc != EOF && fgets(sym, 500, in) == NULL)  			fprintf(stderr, "Read error or end of file.\n");  		return -1;  	} -	if (strlen(str) > KSYM_NAME_LEN) { +	if (strlen(sym) > KSYM_NAME_LEN) {  		fprintf(stderr, "Symbol %s too long for kallsyms (%zu vs %d).\n"  				"Please increase KSYM_NAME_LEN both in kernel and kallsyms.c\n", -			str, strlen(str), KSYM_NAME_LEN); +			sym, strlen(sym), KSYM_NAME_LEN);  		return -1;  	} -	sym = str; -	/* skip prefix char */ -	if (symbol_prefix_char && str[0] == symbol_prefix_char) -		sym++; -  	/* Ignore most absolute/undefined (?) symbols. */  	if (strcmp(sym, "_text") == 0)  		_text = s->addr; @@ -155,7 +147,7 @@ static int read_symbol(FILE *in, struct sym_entry *s)  		 is_arm_mapping_symbol(sym))  		return -1;  	/* exclude also MIPS ELF local symbols ($L123 instead of .L123) */ -	else if (str[0] == '$') +	else if (sym[0] == '$')  		return -1;  	/* exclude debugging symbols */  	else if (stype == 'N' || stype == 'n') @@ -163,14 +155,14 @@ static int read_symbol(FILE *in, struct sym_entry *s)  	/* include the type field in the symbol name, so that it gets  	 * compressed together */ -	s->len = strlen(str) + 1; +	s->len = strlen(sym) + 1;  	s->sym = malloc(s->len + 1);  	if (!s->sym) {  		fprintf(stderr, "kallsyms failure: "  			"unable to allocate required amount of memory\n");  		exit(EXIT_FAILURE);  	} -	strcpy((char *)s->sym + 1, str); +	strcpy((char *)s->sym + 1, sym);  	s->sym[0] = stype;  	s->percpu_absolute = 0; @@ -233,11 +225,6 @@ static int symbol_valid(struct sym_entry *s)  	int i;  	char *sym_name = (char *)s->sym + 1; -	/* skip prefix char */ -	if (symbol_prefix_char && *sym_name == symbol_prefix_char) -		sym_name++; - -  	/* if --all-symbols is not specified, then symbols outside the text  	 * and inittext sections are discarded */  	if (!all_symbols) { @@ -302,15 +289,9 @@ static void read_map(FILE *in)  static void output_label(char *label)  { -	if (symbol_prefix_char) -		printf(".globl %c%s\n", symbol_prefix_char, label); -	else -		printf(".globl %s\n", label); +	printf(".globl %s\n", label);  	printf("\tALGN\n"); -	if (symbol_prefix_char) -		printf("%c%s:\n", symbol_prefix_char, label); -	else -		printf("%s:\n", label); +	printf("%s:\n", label);  }  /* uncompress a compressed symbol. When this function is called, the best table @@ -424,7 +405,7 @@ static void write_src(void)  	}  	output_label("kallsyms_num_syms"); -	printf("\tPTR\t%d\n", table_cnt); +	printf("\tPTR\t%u\n", table_cnt);  	printf("\n");  	/* table of offset markers, that give the offset in the compressed stream @@ -768,13 +749,7 @@ int main(int argc, char **argv)  				all_symbols = 1;  			else if (strcmp(argv[i], "--absolute-percpu") == 0)  				absolute_percpu = 1; -			else if (strncmp(argv[i], "--symbol-prefix=", 16) == 0) { -				char *p = &argv[i][16]; -				/* skip quote */ -				if ((*p == '"' && *(p+2) == '"') || (*p == '\'' && *(p+2) == '\'')) -					p++; -				symbol_prefix_char = *p; -			} else if (strcmp(argv[i], "--base-relative") == 0) +			else if (strcmp(argv[i], "--base-relative") == 0)  				base_relative = 1;  			else  				usage(); diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore index 2da579edcbaf..0aabc1d6a182 100644 --- a/scripts/kconfig/.gitignore +++ b/scripts/kconfig/.gitignore @@ -2,9 +2,6 @@  # Generated files  #  *.moc -gconf.glade.h -*.pot -*.mo  #  # configuration programs @@ -14,4 +11,3 @@ mconf  nconf  qconf  gconf -kxgettext diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 5def8779d7d8..a3ac2c91331c 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -3,7 +3,7 @@  # Kernel configuration targets  # These targets are used from top-level makefile -PHONY += xconfig gconfig menuconfig config syncconfig update-po-config \ +PHONY += xconfig gconfig menuconfig config syncconfig \  	localmodconfig localyesconfig  ifdef KBUILD_KCONFIG @@ -55,29 +55,6 @@ localyesconfig localmodconfig: $(obj)/conf  	fi  	$(Q)rm -f .tmp.config -# Create new linux.pot file -# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files -update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h -	$(Q)$(kecho) "  GEN     config.pot" -	$(Q)xgettext --default-domain=linux                         \ -	    --add-comments --keyword=_ --keyword=N_                 \ -	    --from-code=UTF-8                                       \ -	    --files-from=$(srctree)/scripts/kconfig/POTFILES.in     \ -	    --directory=$(srctree) --directory=$(objtree)           \ -	    --output $(obj)/config.pot -	$(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot -	$(Q)(for i in `ls $(srctree)/arch/*/Kconfig      \ -	    $(srctree)/arch/*/um/Kconfig`;               \ -	    do                                           \ -		$(kecho) "  GEN     $$i";                    \ -		$(obj)/kxgettext $$i                     \ -		     >> $(obj)/config.pot;               \ -	    done ) -	$(Q)$(kecho) "  GEN     linux.pot" -	$(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \ -	    --output $(obj)/linux.pot -	$(Q)rm -f $(obj)/config.pot -  # These targets map 1:1 to the commandline options of 'conf'  simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \  	alldefconfig randconfig listnewconfig olddefconfig @@ -151,8 +128,7 @@ clean-dirs += tests/.cache  # Help text used by make help  help:  	@echo  '  config	  - Update current config utilising a line-oriented program' -	@echo  '  nconfig         - Update current config utilising a ncurses menu based' -	@echo  '                    program' +	@echo  '  nconfig         - Update current config utilising a ncurses menu based program'  	@echo  '  menuconfig	  - Update current config utilising a menu based program'  	@echo  '  xconfig	  - Update current config utilising a Qt based front-end'  	@echo  '  gconfig	  - Update current config utilising a GTK+ based front-end' @@ -172,141 +148,77 @@ help:  	@echo  '  kvmconfig	  - Enable additional options for kvm guest kernel support'  	@echo  '  xenconfig       - Enable additional options for xen dom0 and guest kernel support'  	@echo  '  tinyconfig	  - Configure the tiniest possible kernel' - -# lxdialog stuff -check-lxdialog  := $(srctree)/$(src)/lxdialog/check-lxdialog.sh - -# Use recursively expanded variables so we do not call gcc unless -# we really need to do so. (Do not call gcc as part of make mrproper) -HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \ -                    -DLOCALE +	@echo  '  testconfig	  - Run Kconfig unit tests (requires python3 and pytest)'  # ===========================================================================  # Shared Makefile for the various kconfig executables:  # conf:	  Used for defconfig, oldconfig and related targets -# nconf:  Used for the nconfig target. -#         Utilizes ncurses -# mconf:  Used for the menuconfig target -#         Utilizes the lxdialog package -# qconf:  Used for the xconfig target -#         Based on Qt which needs to be installed to compile it -# gconf:  Used for the gconfig target -#         Based on GTK+ which needs to be installed to compile it  # object files used by all kconfig flavours -lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o -lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o -  conf-objs	:= conf.o  zconf.tab.o -mconf-objs     := mconf.o zconf.tab.o $(lxdialog) -nconf-objs     := nconf.o zconf.tab.o nconf.gui.o -kxgettext-objs	:= kxgettext.o zconf.tab.o -qconf-cxxobjs	:= qconf.o -qconf-objs	:= zconf.tab.o -gconf-objs	:= gconf.o zconf.tab.o -hostprogs-y := conf nconf mconf kxgettext qconf gconf +hostprogs-y := conf  targets		+= zconf.lex.c -clean-files	:= qconf.moc .tmp_qtcheck .tmp_gtkcheck -clean-files	+= gconf.glade.h -clean-files     += config.pot linux.pot - -# Check that we have the required ncurses stuff installed for lxdialog (menuconfig) -PHONY += $(obj)/dochecklxdialog -$(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/dochecklxdialog -$(obj)/dochecklxdialog: -	$(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTLOADLIBES_mconf) - -always := dochecklxdialog - -# Add environment specific flags -HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCC) $(HOSTCFLAGS)) -HOST_EXTRACXXFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCXX) $(HOSTCXXFLAGS))  # generated files seem to need this to find local include files  HOSTCFLAGS_zconf.lex.o	:= -I$(src)  HOSTCFLAGS_zconf.tab.o	:= -I$(src) -HOSTLOADLIBES_qconf	= $(KC_QT_LIBS) -HOSTCXXFLAGS_qconf.o	= $(KC_QT_CFLAGS) - -HOSTLOADLIBES_gconf	= `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` -HOSTCFLAGS_gconf.o	= `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ -                          -Wno-missing-prototypes - -HOSTLOADLIBES_mconf   = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) - -HOSTLOADLIBES_nconf	= $(shell \ -				pkg-config --libs menuw panelw ncursesw 2>/dev/null \ -				|| pkg-config --libs menu panel ncurses 2>/dev/null \ -				|| echo "-lmenu -lpanel -lncurses"  ) -$(obj)/qconf.o: $(obj)/.tmp_qtcheck - -ifeq ($(MAKECMDGOALS),xconfig) -$(obj)/.tmp_qtcheck: $(src)/Makefile --include $(obj)/.tmp_qtcheck - -# Qt needs some extra effort... -$(obj)/.tmp_qtcheck: -	@set -e; $(kecho) "  CHECK   qt"; \ -	if pkg-config --exists Qt5Core; then \ -	    cflags="-std=c++11 -fPIC `pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets`"; \ -	    libs=`pkg-config --libs Qt5Core Qt5Gui Qt5Widgets`; \ -	    moc=`pkg-config --variable=host_bins Qt5Core`/moc; \ -	elif pkg-config --exists QtCore; then \ -	    cflags=`pkg-config --cflags QtCore QtGui`; \ -	    libs=`pkg-config --libs QtCore QtGui`; \ -	    moc=`pkg-config --variable=moc_location QtCore`; \ -	else \ -	    echo >&2 "*"; \ -	    echo >&2 "* Could not find Qt via pkg-config."; \ -	    echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH"; \ -	    echo >&2 "*"; \ -	    exit 1; \ -	fi; \ -	echo "KC_QT_CFLAGS=$$cflags" > $@; \ -	echo "KC_QT_LIBS=$$libs" >> $@; \ -	echo "KC_QT_MOC=$$moc" >> $@ -endif +# nconf: Used for the nconfig target based on ncurses +hostprogs-y	+= nconf +nconf-objs	:= nconf.o zconf.tab.o nconf.gui.o -$(obj)/gconf.o: $(obj)/.tmp_gtkcheck - -ifeq ($(MAKECMDGOALS),gconfig) --include $(obj)/.tmp_gtkcheck - -# GTK+ needs some extra effort, too... -$(obj)/.tmp_gtkcheck: -	@if `pkg-config --exists gtk+-2.0 gmodule-2.0 libglade-2.0`; then		\ -		if `pkg-config --atleast-version=2.0.0 gtk+-2.0`; then			\ -			touch $@;								\ -		else									\ -			echo >&2 "*"; 							\ -			echo >&2 "* GTK+ is present but version >= 2.0.0 is required.";	\ -			echo >&2 "*";							\ -			false;								\ -		fi									\ -	else										\ -		echo >&2 "*"; 								\ -		echo >&2 "* Unable to find the GTK+ installation. Please make sure that"; 	\ -		echo >&2 "* the GTK+ 2.0 development package is correctly installed..."; 	\ -		echo >&2 "* You need gtk+-2.0, glib-2.0 and libglade-2.0."; 		\ -		echo >&2 "*"; 								\ -		false;									\ -	fi -endif +HOSTLOADLIBES_nconf	= $(shell . $(obj)/.nconf-cfg && echo $$libs) +HOSTCFLAGS_nconf.o	= $(shell . $(obj)/.nconf-cfg && echo $$cflags) +HOSTCFLAGS_nconf.gui.o	= $(shell . $(obj)/.nconf-cfg && echo $$cflags) -$(obj)/zconf.tab.o: $(obj)/zconf.lex.c +$(obj)/nconf.o: $(obj)/.nconf-cfg + +# mconf: Used for the menuconfig target based on lxdialog +hostprogs-y	+= mconf +lxdialog	:= checklist.o inputbox.o menubox.o textbox.o util.o yesno.o +mconf-objs	:= mconf.o zconf.tab.o $(addprefix lxdialog/, $(lxdialog)) -$(obj)/qconf.o: $(obj)/qconf.moc +HOSTLOADLIBES_mconf = $(shell . $(obj)/.mconf-cfg && echo $$libs) +$(foreach f, mconf.o $(lxdialog), \ +  $(eval HOSTCFLAGS_$f = $$(shell . $(obj)/.mconf-cfg && echo $$$$cflags))) + +$(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/.mconf-cfg + +# qconf: Used for the xconfig target based on Qt +hostprogs-y	+= qconf +qconf-cxxobjs	:= qconf.o +qconf-objs	:= zconf.tab.o + +HOSTLOADLIBES_qconf	= $(shell . $(obj)/.qconf-cfg && echo $$libs) +HOSTCXXFLAGS_qconf.o	= $(shell . $(obj)/.qconf-cfg && echo $$cflags) + +$(obj)/qconf.o: $(obj)/.qconf-cfg $(obj)/qconf.moc  quiet_cmd_moc = MOC     $@ -      cmd_moc = $(KC_QT_MOC) -i $< -o $@ +      cmd_moc = $(shell . $(obj)/.qconf-cfg && echo $$moc) -i $< -o $@ -$(obj)/%.moc: $(src)/%.h $(obj)/.tmp_qtcheck +$(obj)/%.moc: $(src)/%.h $(obj)/.qconf-cfg  	$(call cmd,moc) -# Extract gconf menu items for i18n support -$(obj)/gconf.glade.h: $(obj)/gconf.glade -	$(Q)intltool-extract --type=gettext/glade --srcdir=$(srctree) \ -	$(obj)/gconf.glade +# gconf: Used for the gconfig target based on GTK+ +hostprogs-y	+= gconf +gconf-objs	:= gconf.o zconf.tab.o + +HOSTLOADLIBES_gconf = $(shell . $(obj)/.gconf-cfg && echo $$libs) +HOSTCFLAGS_gconf.o  = $(shell . $(obj)/.gconf-cfg && echo $$cflags) + +$(obj)/gconf.o: $(obj)/.gconf-cfg + +$(obj)/zconf.tab.o: $(obj)/zconf.lex.c + +# check if necessary packages are available, and configure build flags +define filechk_conf_cfg +	$(CONFIG_SHELL) $< +endef + +$(obj)/.%conf-cfg: $(src)/%conf-cfg.sh FORCE +	$(call filechk,conf_cfg) + +clean-files += .*conf-cfg diff --git a/scripts/kconfig/POTFILES.in b/scripts/kconfig/POTFILES.in deleted file mode 100644 index 967457396990..000000000000 --- a/scripts/kconfig/POTFILES.in +++ /dev/null @@ -1,12 +0,0 @@ -scripts/kconfig/lxdialog/checklist.c -scripts/kconfig/lxdialog/inputbox.c -scripts/kconfig/lxdialog/menubox.c -scripts/kconfig/lxdialog/textbox.c -scripts/kconfig/lxdialog/util.c -scripts/kconfig/lxdialog/yesno.c -scripts/kconfig/mconf.c -scripts/kconfig/conf.c -scripts/kconfig/confdata.c -scripts/kconfig/gconf.c -scripts/kconfig/gconf.glade.h -scripts/kconfig/qconf.cc diff --git a/scripts/kconfig/check.sh b/scripts/kconfig/check.sh deleted file mode 100755 index 97f0fee7d173..000000000000 --- a/scripts/kconfig/check.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 -# Needed for systems without gettext -$* -x c -o /dev/null - > /dev/null 2>&1 << EOF -#include <libintl.h> -int main() -{ -	gettext(""); -	return 0; -} -EOF -if [ ! "$?" -eq "0"  ]; then -	echo -DKBUILD_NO_NLS; -fi diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 283eeedaa4fa..671ff5364497 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -3,7 +3,6 @@   * Released under the terms of the GNU GPL v2.0.   */ -#include <locale.h>  #include <ctype.h>  #include <limits.h>  #include <stdio.h> @@ -86,7 +85,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)  	enum symbol_type type = sym_get_type(sym);  	if (!sym_has_value(sym)) -		printf(_("(NEW) ")); +		printf("(NEW) ");  	line[0] = '\n';  	line[1] = 0; @@ -133,7 +132,7 @@ static int conf_string(struct menu *menu)  	const char *def;  	while (1) { -		printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); +		printf("%*s%s ", indent - 1, "", menu->prompt->text);  		printf("(%s) ", sym->name);  		def = sym_get_string_value(sym);  		if (sym_get_string_value(sym)) @@ -166,7 +165,7 @@ static int conf_sym(struct menu *menu)  	tristate oldval, newval;  	while (1) { -		printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); +		printf("%*s%s ", indent - 1, "", menu->prompt->text);  		if (sym->name)  			printf("(%s) ", sym->name);  		putchar('['); @@ -251,7 +250,7 @@ static int conf_choice(struct menu *menu)  		case no:  			return 1;  		case mod: -			printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); +			printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));  			return 0;  		case yes:  			break; @@ -261,7 +260,7 @@ static int conf_choice(struct menu *menu)  	while (1) {  		int cnt, def; -		printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); +		printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));  		def_sym = sym_get_choice_value(sym);  		cnt = def = 0;  		line[0] = 0; @@ -269,7 +268,7 @@ static int conf_choice(struct menu *menu)  			if (!menu_is_visible(child))  				continue;  			if (!child->sym) { -				printf("%*c %s\n", indent, '*', _(menu_get_prompt(child))); +				printf("%*c %s\n", indent, '*', menu_get_prompt(child));  				continue;  			}  			cnt++; @@ -278,14 +277,14 @@ static int conf_choice(struct menu *menu)  				printf("%*c", indent, '>');  			} else  				printf("%*c", indent, ' '); -			printf(" %d. %s", cnt, _(menu_get_prompt(child))); +			printf(" %d. %s", cnt, menu_get_prompt(child));  			if (child->sym->name)  				printf(" (%s)", child->sym->name);  			if (!sym_has_value(child->sym)) -				printf(_(" (NEW)")); +				printf(" (NEW)");  			printf("\n");  		} -		printf(_("%*schoice"), indent - 1, ""); +		printf("%*schoice", indent - 1, "");  		if (cnt == 1) {  			printf("[1]: 1\n");  			goto conf_childs; @@ -372,7 +371,7 @@ static void conf(struct menu *menu)  			if (prompt)  				printf("%*c\n%*c %s\n%*c\n",  					indent, '*', -					indent, '*', _(prompt), +					indent, '*', prompt,  					indent, '*');  		default:  			; @@ -437,7 +436,7 @@ static void check_conf(struct menu *menu)  				}  			} else {  				if (!conf_cnt++) -					printf(_("*\n* Restart config...\n*\n")); +					printf("*\n* Restart config...\n*\n");  				rootEntry = menu_get_parent_menu(menu);  				conf(rootEntry);  			} @@ -498,10 +497,6 @@ int main(int ac, char **av)  	const char *name, *defconfig_file = NULL /* gcc uninit */;  	struct stat tmpstat; -	setlocale(LC_ALL, ""); -	bindtextdomain(PACKAGE, LOCALEDIR); -	textdomain(PACKAGE); -  	tty_stdio = isatty(0) && isatty(1);  	while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) { @@ -559,7 +554,7 @@ int main(int ac, char **av)  		}  	}  	if (ac == optind) { -		fprintf(stderr, _("%s: Kconfig file missing\n"), av[0]); +		fprintf(stderr, "%s: Kconfig file missing\n", av[0]);  		conf_usage(progname);  		exit(1);  	} @@ -569,12 +564,12 @@ int main(int ac, char **av)  	if (sync_kconfig) {  		name = conf_get_configname();  		if (stat(name, &tmpstat)) { -			fprintf(stderr, _("***\n" +			fprintf(stderr, "***\n"  				"*** Configuration file \"%s\" not found!\n"  				"***\n"  				"*** Please run some configurator (e.g. \"make oldconfig\" or\n"  				"*** \"make menuconfig\" or \"make xconfig\").\n" -				"***\n"), name); +				"***\n", name);  			exit(1);  		}  	} @@ -585,9 +580,9 @@ int main(int ac, char **av)  			defconfig_file = conf_get_default_confname();  		if (conf_read(defconfig_file)) {  			fprintf(stderr, -				_("***\n" +				"***\n"  				  "*** Can't find default configuration \"%s\"!\n" -				  "***\n"), +				  "***\n",  				defconfig_file);  			exit(1);  		} @@ -611,7 +606,7 @@ int main(int ac, char **av)  		if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {  			if (conf_read_simple(name, S_DEF_USER)) {  				fprintf(stderr, -					_("*** Can't read seed configuration \"%s\"!\n"), +					"*** Can't read seed configuration \"%s\"!\n",  					name);  				exit(1);  			} @@ -628,7 +623,7 @@ int main(int ac, char **av)  		if (conf_read_simple(name, S_DEF_USER) &&  		    conf_read_simple("all.config", S_DEF_USER)) {  			fprintf(stderr, -				_("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"), +				"*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n",  				name);  			exit(1);  		} @@ -642,7 +637,7 @@ int main(int ac, char **av)  			name = getenv("KCONFIG_NOSILENTUPDATE");  			if (name && *name) {  				fprintf(stderr, -					_("\n*** The configuration requires explicit update.\n\n")); +					"\n*** The configuration requires explicit update.\n\n");  				return 1;  			}  		} @@ -694,22 +689,22 @@ int main(int ac, char **av)  		 * All other commands are only used to generate a config.  		 */  		if (conf_get_changed() && conf_write(NULL)) { -			fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n")); +			fprintf(stderr, "\n*** Error during writing of the configuration.\n\n");  			exit(1);  		}  		if (conf_write_autoconf()) { -			fprintf(stderr, _("\n*** Error during update of the configuration.\n\n")); +			fprintf(stderr, "\n*** Error during update of the configuration.\n\n");  			return 1;  		}  	} else if (input_mode == savedefconfig) {  		if (conf_write_defconfig(defconfig_file)) { -			fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"), +			fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n",  				defconfig_file);  			return 1;  		}  	} else if (input_mode != listnewconfig) {  		if (conf_write(NULL)) { -			fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n")); +			fprintf(stderr, "\n*** Error during writing of the configuration.\n\n");  			exit(1);  		}  	} diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index df26c7b0fe13..39e20974f4a3 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -30,7 +30,7 @@ static void conf_message(const char *fmt, ...)  static const char *conf_filename;  static int conf_lineno, conf_warnings; -const char conf_defname[] = "arch/$ARCH/defconfig"; +const char conf_defname[] = "arch/$(ARCH)/defconfig";  static void conf_warning(const char *fmt, ...)  { @@ -81,39 +81,13 @@ const char *conf_get_autoconfig_name(void)  	return name ? name : "include/config/auto.conf";  } -static char *conf_expand_value(const char *in) -{ -	struct symbol *sym; -	const char *src; -	static char res_value[SYMBOL_MAXLENGTH]; -	char *dst, name[SYMBOL_MAXLENGTH]; - -	res_value[0] = 0; -	dst = name; -	while ((src = strchr(in, '$'))) { -		strncat(res_value, in, src - in); -		src++; -		dst = name; -		while (isalnum(*src) || *src == '_') -			*dst++ = *src++; -		*dst = 0; -		sym = sym_lookup(name, 0); -		sym_calc_value(sym); -		strcat(res_value, sym_get_string_value(sym)); -		in = src; -	} -	strcat(res_value, in); - -	return res_value; -} -  char *conf_get_default_confname(void)  {  	struct stat buf;  	static char fullname[PATH_MAX+1];  	char *env, *name; -	name = conf_expand_value(conf_defname); +	name = expand_string(conf_defname);  	env = getenv(SRCTREE);  	if (env) {  		sprintf(fullname, "%s/%s", env, name); @@ -274,10 +248,11 @@ int conf_read_simple(const char *name, int def)  			if (expr_calc_value(prop->visible.expr) == no ||  			    prop->expr->type != E_SYMBOL)  				continue; -			name = conf_expand_value(prop->expr->left.sym->name); +			sym_calc_value(prop->expr->left.sym); +			name = sym_get_string_value(prop->expr->left.sym);  			in = zconf_fopen(name);  			if (in) { -				conf_message(_("using defaults found in %s"), +				conf_message("using defaults found in %s",  					 name);  				goto load;  			} @@ -745,7 +720,7 @@ int conf_write(const char *name)  	struct menu *menu;  	const char *basename;  	const char *str; -	char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1]; +	char dirname[PATH_MAX+1], tmpname[PATH_MAX+22], newname[PATH_MAX+8];  	char *env;  	dirname[0] = 0; @@ -831,7 +806,7 @@ next:  			return 1;  	} -	conf_message(_("configuration written to %s"), newname); +	conf_message("configuration written to %s", newname);  	sym_set_change_count(0); diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 94a383b21df6..f63b41b0dd49 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -171,6 +171,9 @@ struct symbol {   * config BAZ   *         int "BAZ Value"   *         range 1..255 + * + * Please, also check zconf.y:print_symbol() when modifying the + * list of property types!   */  enum prop_type {  	P_UNKNOWN, diff --git a/scripts/kconfig/gconf-cfg.sh b/scripts/kconfig/gconf-cfg.sh new file mode 100755 index 000000000000..533b3d8f8f08 --- /dev/null +++ b/scripts/kconfig/gconf-cfg.sh @@ -0,0 +1,23 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +PKG="gtk+-2.0 gmodule-2.0 libglade-2.0" + +if ! pkg-config --exists $PKG; then +	echo >&2 "*" +	echo >&2 "* Unable to find the GTK+ installation. Please make sure that" +	echo >&2 "* the GTK+ 2.0 development package is correctly installed." +	echo >&2 "* You need $PKG" +	echo >&2 "*" +	exit 1 +fi + +if ! pkg-config --atleast-version=2.0.0 gtk+-2.0; then +	echo >&2 "*" +	echo >&2 "* GTK+ is present but version >= 2.0.0 is required." +	echo >&2 "*" +	exit 1 +fi + +echo cflags=\"$(pkg-config --cflags $PKG)\" +echo libs=\"$(pkg-config --libs $PKG)\" diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index cfddddb9c9d7..610c4ab54d76 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -137,7 +137,7 @@ void init_main_window(const gchar * glade_file)  	xml = glade_xml_new(glade_file, "window1", NULL);  	if (!xml) -		g_error(_("GUI loading failed !\n")); +		g_error("GUI loading failed !\n");  	glade_xml_signal_autoconnect(xml);  	main_wnd = glade_xml_get_widget(xml, "window1"); @@ -233,7 +233,7 @@ void init_left_tree(void)  	column = gtk_tree_view_column_new();  	gtk_tree_view_append_column(view, column); -	gtk_tree_view_column_set_title(column, _("Options")); +	gtk_tree_view_column_set_title(column, "Options");  	renderer = gtk_cell_renderer_toggle_new();  	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), @@ -276,7 +276,7 @@ void init_right_tree(void)  	column = gtk_tree_view_column_new();  	gtk_tree_view_append_column(view, column); -	gtk_tree_view_column_set_title(column, _("Options")); +	gtk_tree_view_column_set_title(column, "Options");  	renderer = gtk_cell_renderer_pixbuf_new();  	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), @@ -305,7 +305,7 @@ void init_right_tree(void)  	renderer = gtk_cell_renderer_text_new();  	gtk_tree_view_insert_column_with_attributes(view, -1, -						    _("Name"), renderer, +						    "Name", renderer,  						    "text", COL_NAME,  						    "foreground-gdk",  						    COL_COLOR, NULL); @@ -329,7 +329,7 @@ void init_right_tree(void)  						    COL_COLOR, NULL);  	renderer = gtk_cell_renderer_text_new();  	gtk_tree_view_insert_column_with_attributes(view, -1, -						    _("Value"), renderer, +						    "Value", renderer,  						    "text", COL_VALUE,  						    "editable",  						    COL_EDIT, @@ -368,7 +368,7 @@ static void text_insert_help(struct menu *menu)  {  	GtkTextBuffer *buffer;  	GtkTextIter start, end; -	const char *prompt = _(menu_get_prompt(menu)); +	const char *prompt = menu_get_prompt(menu);  	struct gstr help = str_new();  	menu_get_ext_help(menu, &help); @@ -422,7 +422,7 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,  	if (!conf_get_changed())  		return FALSE; -	dialog = gtk_dialog_new_with_buttons(_("Warning !"), +	dialog = gtk_dialog_new_with_buttons("Warning !",  					     GTK_WINDOW(main_wnd),  					     (GtkDialogFlags)  					     (GTK_DIALOG_MODAL | @@ -436,7 +436,7 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,  	gtk_dialog_set_default_response(GTK_DIALOG(dialog),  					GTK_RESPONSE_CANCEL); -	label = gtk_label_new(_("\nSave configuration ?\n")); +	label = gtk_label_new("\nSave configuration ?\n");  	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);  	gtk_widget_show(label); @@ -496,7 +496,7 @@ load_filename(GtkFileSelection * file_selector, gpointer user_data)  					     (user_data));  	if (conf_read(fn)) -		text_insert_msg(_("Error"), _("Unable to load configuration !")); +		text_insert_msg("Error", "Unable to load configuration !");  	else  		display_tree(&rootmenu);  } @@ -505,7 +505,7 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)  {  	GtkWidget *fs; -	fs = gtk_file_selection_new(_("Load file...")); +	fs = gtk_file_selection_new("Load file...");  	g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),  			 "clicked",  			 G_CALLBACK(load_filename), (gpointer) fs); @@ -524,7 +524,7 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)  void on_save_activate(GtkMenuItem * menuitem, gpointer user_data)  {  	if (conf_write(NULL)) -		text_insert_msg(_("Error"), _("Unable to save configuration !")); +		text_insert_msg("Error", "Unable to save configuration !");  } @@ -537,7 +537,7 @@ store_filename(GtkFileSelection * file_selector, gpointer user_data)  					     (user_data));  	if (conf_write(fn)) -		text_insert_msg(_("Error"), _("Unable to save configuration !")); +		text_insert_msg("Error", "Unable to save configuration !");  	gtk_widget_destroy(GTK_WIDGET(user_data));  } @@ -546,7 +546,7 @@ void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data)  {  	GtkWidget *fs; -	fs = gtk_file_selection_new(_("Save file as...")); +	fs = gtk_file_selection_new("Save file as...");  	g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),  			 "clicked",  			 G_CALLBACK(store_filename), (gpointer) fs); @@ -639,7 +639,7 @@ on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data)  void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)  {  	GtkWidget *dialog; -	const gchar *intro_text = _( +	const gchar *intro_text =   	    "Welcome to gkc, the GTK+ graphical configuration tool\n"  	    "For each option, a blank box indicates the feature is disabled, a\n"  	    "check indicates it is enabled, and a dot indicates that it is to\n" @@ -654,7 +654,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)  	    "option.\n"  	    "\n"  	    "Toggling Show Debug Info under the Options menu will show \n" -	    "the dependencies, which you can then match by examining other options."); +	    "the dependencies, which you can then match by examining other options.";  	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),  					GTK_DIALOG_DESTROY_WITH_PARENT, @@ -671,8 +671,8 @@ void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data)  {  	GtkWidget *dialog;  	const gchar *about_text = -	    _("gkc is copyright (c) 2002 Romain Lievin <[email protected]>.\n" -	      "Based on the source code from Roman Zippel.\n"); +	    "gkc is copyright (c) 2002 Romain Lievin <[email protected]>.\n" +	      "Based on the source code from Roman Zippel.\n";  	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),  					GTK_DIALOG_DESTROY_WITH_PARENT, @@ -689,9 +689,9 @@ void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data)  {  	GtkWidget *dialog;  	const gchar *license_text = -	    _("gkc is released under the terms of the GNU GPL v2.\n" +	    "gkc is released under the terms of the GNU GPL v2.\n"  	      "For more information, please see the source code or\n" -	      "visit http://www.fsf.org/licenses/licenses.html\n"); +	      "visit http://www.fsf.org/licenses/licenses.html\n";  	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),  					GTK_DIALOG_DESTROY_WITH_PARENT, @@ -1049,7 +1049,7 @@ static gchar **fill_row(struct menu *menu)  	bzero(row, sizeof(row));  	row[COL_OPTION] = -	    g_strdup_printf("%s %s", _(menu_get_prompt(menu)), +	    g_strdup_printf("%s %s", menu_get_prompt(menu),  			    sym && !sym_has_value(sym) ? "(NEW)" : "");  	if (opt_mode == OPT_ALL && !menu_is_visible(menu)) @@ -1102,7 +1102,7 @@ static gchar **fill_row(struct menu *menu)  		if (def_menu)  			row[COL_VALUE] = -			    g_strdup(_(menu_get_prompt(def_menu))); +			    g_strdup(menu_get_prompt(def_menu));  	}  	if (sym->flags & SYMBOL_CHOICEVAL)  		row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); @@ -1447,10 +1447,6 @@ int main(int ac, char *av[])  	char *env;  	gchar *glade_file; -	bindtextdomain(PACKAGE, LOCALEDIR); -	bind_textdomain_codeset(PACKAGE, "UTF-8"); -	textdomain(PACKAGE); -  	/* GTK stuffs */  	gtk_set_locale();  	gtk_init(&ac, &av); diff --git a/scripts/kconfig/kconf_id.c b/scripts/kconfig/kconf_id.c index 3ea9c5f9f730..b3e0ea0ac732 100644 --- a/scripts/kconfig/kconf_id.c +++ b/scripts/kconfig/kconf_id.c @@ -32,7 +32,6 @@ static struct kconf_id kconf_id_array[] = {  	{ "on",			T_ON,			TF_PARAM },  	{ "modules",		T_OPT_MODULES,		TF_OPTION },  	{ "defconfig_list",	T_OPT_DEFCONFIG_LIST,	TF_OPTION }, -	{ "env",		T_OPT_ENV,		TF_OPTION },  	{ "allnoconfig_y",	T_OPT_ALLNOCONFIG_Y,	TF_OPTION },  }; diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c deleted file mode 100644 index 240880a89111..000000000000 --- a/scripts/kconfig/kxgettext.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Arnaldo Carvalho de Melo <[email protected]>, 2005 - * - * Released under the terms of the GNU GPL v2.0 - */ - -#include <stdlib.h> -#include <string.h> - -#include "lkc.h" - -static char *escape(const char* text, char *bf, int len) -{ -	char *bfp = bf; -	int multiline = strchr(text, '\n') != NULL; -	int eol = 0; -	int textlen = strlen(text); - -	if ((textlen > 0) && (text[textlen-1] == '\n')) -		eol = 1; - -	*bfp++ = '"'; -	--len; - -	if (multiline) { -		*bfp++ = '"'; -		*bfp++ = '\n'; -		*bfp++ = '"'; -		len -= 3; -	} - -	while (*text != '\0' && len > 1) { -		if (*text == '"') -			*bfp++ = '\\'; -		else if (*text == '\n') { -			*bfp++ = '\\'; -			*bfp++ = 'n'; -			*bfp++ = '"'; -			*bfp++ = '\n'; -			*bfp++ = '"'; -			len -= 5; -			++text; -			goto next; -		} -		else if (*text == '\\') { -			*bfp++ = '\\'; -			len--; -		} -		*bfp++ = *text++; -next: -		--len; -	} - -	if (multiline && eol) -		bfp -= 3; - -	*bfp++ = '"'; -	*bfp = '\0'; - -	return bf; -} - -struct file_line { -	struct file_line *next; -	const char *file; -	int lineno; -}; - -static struct file_line *file_line__new(const char *file, int lineno) -{ -	struct file_line *self = malloc(sizeof(*self)); - -	if (self == NULL) -		goto out; - -	self->file   = file; -	self->lineno = lineno; -	self->next   = NULL; -out: -	return self; -} - -struct message { -	const char	 *msg; -	const char	 *option; -	struct message	 *next; -	struct file_line *files; -}; - -static struct message *message__list; - -static struct message *message__new(const char *msg, char *option, -				    const char *file, int lineno) -{ -	struct message *self = malloc(sizeof(*self)); - -	if (self == NULL) -		goto out; - -	self->files = file_line__new(file, lineno); -	if (self->files == NULL) -		goto out_fail; - -	self->msg = xstrdup(msg); -	if (self->msg == NULL) -		goto out_fail_msg; - -	self->option = option; -	self->next = NULL; -out: -	return self; -out_fail_msg: -	free(self->files); -out_fail: -	free(self); -	self = NULL; -	goto out; -} - -static struct message *mesage__find(const char *msg) -{ -	struct message *m = message__list; - -	while (m != NULL) { -		if (strcmp(m->msg, msg) == 0) -			break; -		m = m->next; -	} - -	return m; -} - -static int message__add_file_line(struct message *self, const char *file, -				  int lineno) -{ -	int rc = -1; -	struct file_line *fl = file_line__new(file, lineno); - -	if (fl == NULL) -		goto out; - -	fl->next    = self->files; -	self->files = fl; -	rc = 0; -out: -	return rc; -} - -static int message__add(const char *msg, char *option, const char *file, -			int lineno) -{ -	int rc = 0; -	char bf[16384]; -	char *escaped = escape(msg, bf, sizeof(bf)); -	struct message *m = mesage__find(escaped); - -	if (m != NULL) -		rc = message__add_file_line(m, file, lineno); -	else { -		m = message__new(escaped, option, file, lineno); - -		if (m != NULL) { -			m->next	      = message__list; -			message__list = m; -		} else -			rc = -1; -	} -	return rc; -} - -static void menu_build_message_list(struct menu *menu) -{ -	struct menu *child; - -	message__add(menu_get_prompt(menu), NULL, -		     menu->file == NULL ? "Root Menu" : menu->file->name, -		     menu->lineno); - -	if (menu->sym != NULL && menu_has_help(menu)) -		message__add(menu_get_help(menu), menu->sym->name, -			     menu->file == NULL ? "Root Menu" : menu->file->name, -			     menu->lineno); - -	for (child = menu->list; child != NULL; child = child->next) -		if (child->prompt != NULL) -			menu_build_message_list(child); -} - -static void message__print_file_lineno(struct message *self) -{ -	struct file_line *fl = self->files; - -	putchar('\n'); -	if (self->option != NULL) -		printf("# %s:00000\n", self->option); - -	printf("#: %s:%d", fl->file, fl->lineno); -	fl = fl->next; - -	while (fl != NULL) { -		printf(", %s:%d", fl->file, fl->lineno); -		fl = fl->next; -	} - -	putchar('\n'); -} - -static void message__print_gettext_msgid_msgstr(struct message *self) -{ -	message__print_file_lineno(self); - -	printf("msgid %s\n" -	       "msgstr \"\"\n", self->msg); -} - -static void menu__xgettext(void) -{ -	struct message *m = message__list; - -	while (m != NULL) { -		/* skip empty lines ("") */ -		if (strlen(m->msg) > sizeof("\"\"")) -			message__print_gettext_msgid_msgstr(m); -		m = m->next; -	} -} - -int main(int ac, char **av) -{ -	conf_parse(av[1]); - -	menu_build_message_list(menu_get_root_menu(NULL)); -	menu__xgettext(); -	return 0; -} diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index f4394af6e4b8..ed3ff88e60ba 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -8,15 +8,6 @@  #include "expr.h" -#ifndef KBUILD_NO_NLS -# include <libintl.h> -#else -static inline const char *gettext(const char *txt) { return txt; } -static inline void textdomain(const char *domainname) {} -static inline void bindtextdomain(const char *name, const char *dir) {} -static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c; } -#endif -  #ifdef __cplusplus  extern "C" {  #endif @@ -29,11 +20,6 @@ extern "C" {  #define PACKAGE "linux"  #endif -#define LOCALEDIR "/usr/share/locale" - -#define _(text) gettext(text) -#define N_(text) (text) -  #ifndef CONFIG_  #define CONFIG_ "CONFIG_"  #endif @@ -58,7 +44,6 @@ enum conf_def_mode {  #define T_OPT_MODULES		1  #define T_OPT_DEFCONFIG_LIST	2 -#define T_OPT_ENV		3  #define T_OPT_ALLNOCONFIG_Y	4  struct kconf_id { @@ -117,6 +102,7 @@ void *xmalloc(size_t size);  void *xcalloc(size_t nmemb, size_t size);  void *xrealloc(void *p, size_t size);  char *xstrdup(const char *s); +char *xstrndup(const char *s, size_t n);  struct gstr {  	size_t len; @@ -134,9 +120,6 @@ void str_printf(struct gstr *gs, const char *fmt, ...);  const char *str_get(struct gstr *gs);  /* symbol.c */ -extern struct expr *sym_env_list; - -void sym_init(void);  void sym_clear_all_valid(void);  struct symbol *sym_choice_default(struct symbol *sym);  const char *sym_get_string_default(struct symbol *sym); diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 9dc8abfb1dc3..a8b7a330587e 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -31,7 +31,6 @@ extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];  struct symbol * sym_lookup(const char *name, int flags);  struct symbol * sym_find(const char *name); -char *sym_expand_string_value(const char *in);  const char * sym_escape_string_value(const char *in);  struct symbol ** sym_re_search(const char *pattern);  const char * sym_type_name(enum symbol_type type); @@ -49,5 +48,19 @@ const char * sym_get_string_value(struct symbol *sym);  const char * prop_get_type_name(enum prop_type type); +/* preprocess.c */ +enum variable_flavor { +	VAR_SIMPLE, +	VAR_RECURSIVE, +	VAR_APPEND, +}; +void env_write_dep(FILE *f, const char *auto_conf_name); +void variable_add(const char *name, const char *value, +		  enum variable_flavor flavor); +void variable_all_del(void); +char *expand_string(const char *in); +char *expand_dollar(const char **str); +char *expand_one_token(const char **str); +  /* expr.c */  void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken); diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh deleted file mode 100755 index 6c0bcd9c472d..000000000000 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ /dev/null @@ -1,93 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 -# Check ncurses compatibility - -# What library to link -ldflags() -{ -	pkg-config --libs ncursesw 2>/dev/null && exit -	pkg-config --libs ncurses 2>/dev/null && exit -	for ext in so a dll.a dylib ; do -		for lib in ncursesw ncurses curses ; do -			$cc -print-file-name=lib${lib}.${ext} | grep -q / -			if [ $? -eq 0 ]; then -				echo "-l${lib}" -				exit -			fi -		done -	done -	exit 1 -} - -# Where is ncurses.h? -ccflags() -{ -	if pkg-config --cflags ncursesw 2>/dev/null; then -		echo '-DCURSES_LOC="<ncurses.h>" -DNCURSES_WIDECHAR=1' -	elif pkg-config --cflags ncurses 2>/dev/null; then -		echo '-DCURSES_LOC="<ncurses.h>"' -	elif [ -f /usr/include/ncursesw/curses.h ]; then -		echo '-I/usr/include/ncursesw -DCURSES_LOC="<curses.h>"' -		echo ' -DNCURSES_WIDECHAR=1' -	elif [ -f /usr/include/ncurses/ncurses.h ]; then -		echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"' -	elif [ -f /usr/include/ncurses/curses.h ]; then -		echo '-I/usr/include/ncurses -DCURSES_LOC="<curses.h>"' -	elif [ -f /usr/include/ncurses.h ]; then -		echo '-DCURSES_LOC="<ncurses.h>"' -	else -		echo '-DCURSES_LOC="<curses.h>"' -	fi -} - -# Temp file, try to clean up after us -tmp=.lxdialog.tmp -trap "rm -f $tmp" 0 1 2 3 15 - -# Check if we can link to ncurses -check() { -        $cc -x c - -o $tmp 2>/dev/null <<'EOF' -#include CURSES_LOC -main() {} -EOF -	if [ $? != 0 ]; then -	    echo " *** Unable to find the ncurses libraries or the"       1>&2 -	    echo " *** required header files."                            1>&2 -	    echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2 -	    echo " *** "                                                  1>&2 -	    echo " *** Install ncurses (ncurses-devel or libncurses-dev " 1>&2 -	    echo " *** depending on your distribution) and try again."    1>&2 -	    echo " *** "                                                  1>&2 -	    exit 1 -	fi -} - -usage() { -	printf "Usage: $0 [-check compiler options|-ccflags|-ldflags compiler options]\n" -} - -if [ $# -eq 0 ]; then -	usage -	exit 1 -fi - -cc="" -case "$1" in -	"-check") -		shift -		cc="$@" -		check -		;; -	"-ccflags") -		ccflags -		;; -	"-ldflags") -		shift -		cc="$@" -		ldflags -		;; -	"*") -		usage -		exit 1 -		;; -esac diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c index 8d016faa28d7..2e96323ad11b 100644 --- a/scripts/kconfig/lxdialog/checklist.c +++ b/scripts/kconfig/lxdialog/checklist.c @@ -103,8 +103,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)  	int x = width / 2 - 11;  	int y = height - 2; -	print_button(dialog, gettext("Select"), y, x, selected == 0); -	print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); +	print_button(dialog, "Select", y, x, selected == 0); +	print_button(dialog, " Help ", y, x + 14, selected == 1);  	wmove(dialog, y, x + 1 + 14 * selected);  	wrefresh(dialog); diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h index fcffd5b41fb0..0b00be5abaa6 100644 --- a/scripts/kconfig/lxdialog/dialog.h +++ b/scripts/kconfig/lxdialog/dialog.h @@ -26,16 +26,10 @@  #include <string.h>  #include <stdbool.h> -#ifndef KBUILD_NO_NLS -# include <libintl.h> -#else -# define gettext(Msgid) ((const char *) (Msgid)) -#endif -  #ifdef __sun__  #define CURS_MACROS  #endif -#include CURSES_LOC +#include <ncurses.h>  /*   * Colors in ncurses 1.9.9e do not work properly since foreground and diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c index d58de1dc5360..fe82ff6d744e 100644 --- a/scripts/kconfig/lxdialog/inputbox.c +++ b/scripts/kconfig/lxdialog/inputbox.c @@ -31,8 +31,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)  	int x = width / 2 - 11;  	int y = height - 2; -	print_button(dialog, gettext("  Ok  "), y, x, selected == 0); -	print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); +	print_button(dialog, "  Ok  ", y, x, selected == 0); +	print_button(dialog, " Help ", y, x + 14, selected == 1);  	wmove(dialog, y, x + 1 + 14 * selected);  	wrefresh(dialog); diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c index 11ae9ad7ac7b..d70cab36137e 100644 --- a/scripts/kconfig/lxdialog/menubox.c +++ b/scripts/kconfig/lxdialog/menubox.c @@ -157,11 +157,11 @@ static void print_buttons(WINDOW * win, int height, int width, int selected)  	int x = width / 2 - 28;  	int y = height - 2; -	print_button(win, gettext("Select"), y, x, selected == 0); -	print_button(win, gettext(" Exit "), y, x + 12, selected == 1); -	print_button(win, gettext(" Help "), y, x + 24, selected == 2); -	print_button(win, gettext(" Save "), y, x + 36, selected == 3); -	print_button(win, gettext(" Load "), y, x + 48, selected == 4); +	print_button(win, "Select", y, x, selected == 0); +	print_button(win, " Exit ", y, x + 12, selected == 1); +	print_button(win, " Help ", y, x + 24, selected == 2); +	print_button(win, " Save ", y, x + 36, selected == 3); +	print_button(win, " Load ", y, x + 48, selected == 4);  	wmove(win, y, x + 1 + 12 * selected);  	wrefresh(win); diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c index 1773319b95e7..88d2818ed956 100644 --- a/scripts/kconfig/lxdialog/textbox.c +++ b/scripts/kconfig/lxdialog/textbox.c @@ -129,7 +129,7 @@ do_resize:  	print_title(dialog, title, width); -	print_button(dialog, gettext(" Exit "), height - 2, width / 2 - 4, TRUE); +	print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE);  	wnoutrefresh(dialog);  	getyx(dialog, cur_y, cur_x);	/* Save cursor position */ diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c index 676fb2f824a3..cd1223c903d1 100644 --- a/scripts/kconfig/lxdialog/yesno.c +++ b/scripts/kconfig/lxdialog/yesno.c @@ -29,8 +29,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)  	int x = width / 2 - 10;  	int y = height - 2; -	print_button(dialog, gettext(" Yes "), y, x, selected == 0); -	print_button(dialog, gettext("  No  "), y, x + 13, selected == 1); +	print_button(dialog, " Yes ", y, x, selected == 0); +	print_button(dialog, "  No  ", y, x + 13, selected == 1);  	wmove(dialog, y, x + 1 + 13 * selected);  	wrefresh(dialog); diff --git a/scripts/kconfig/mconf-cfg.sh b/scripts/kconfig/mconf-cfg.sh new file mode 100755 index 000000000000..e6f9facd0077 --- /dev/null +++ b/scripts/kconfig/mconf-cfg.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +PKG="ncursesw" +PKG2="ncurses" + +if pkg-config --exists $PKG; then +	echo cflags=\"$(pkg-config --cflags $PKG)\" +	echo libs=\"$(pkg-config --libs $PKG)\" +	exit 0 +fi + +if pkg-config --exists $PKG2; then +	echo cflags=\"$(pkg-config --cflags $PKG2)\" +	echo libs=\"$(pkg-config --libs $PKG2)\" +	exit 0 +fi + +# Unfortunately, some distributions (e.g. openSUSE) cannot find ncurses +# by pkg-config. +if [ -f /usr/include/ncursesw/ncurses.h ]; then +	echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncursesw\" +	echo libs=\"-lncursesw\" +	exit 0 +fi + +if [ -f /usr/include/ncurses/ncurses.h ]; then +	echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncurses\" +	echo libs=\"-lncurses\" +	exit 0 +fi + +if [ -f /usr/include/ncurses.h ]; then +	echo cflags=\"-D_GNU_SOURCE\" +	echo libs=\"-lncurses\" +	exit 0 +fi + +echo >&2 "*" +echo >&2 "* Unable to find the ncurses package." +echo >&2 "* Install ncurses (ncurses-devel or libncurses-dev" +echo >&2 "* depending on your distribution)." +echo >&2 "*" +exit 1 diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index c829be8bb19f..5294ed159b98 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -17,12 +17,11 @@  #include <string.h>  #include <signal.h>  #include <unistd.h> -#include <locale.h>  #include "lkc.h"  #include "lxdialog/dialog.h" -static const char mconf_readme[] = N_( +static const char mconf_readme[] =  "Overview\n"  "--------\n"  "This interface lets you select features and parameters for the build.\n" @@ -171,37 +170,37 @@ static const char mconf_readme[] = N_(  " blackbg    => selects a color scheme with black background\n"  " classic    => theme with blue background. The classic look\n"  " bluetitle  => an LCD friendly version of classic. (default)\n" -"\n"), -menu_instructions[] = N_( +"\n", +menu_instructions[] =  	"Arrow keys navigate the menu.  "  	"<Enter> selects submenus ---> (or empty submenus ----).  "  	"Highlighted letters are hotkeys.  "  	"Pressing <Y> includes, <N> excludes, <M> modularizes features.  "  	"Press <Esc><Esc> to exit, <?> for Help, </> for Search.  " -	"Legend: [*] built-in  [ ] excluded  <M> module  < > module capable"), -radiolist_instructions[] = N_( +	"Legend: [*] built-in  [ ] excluded  <M> module  < > module capable", +radiolist_instructions[] =  	"Use the arrow keys to navigate this window or "  	"press the hotkey of the item you wish to select "  	"followed by the <SPACE BAR>. " -	"Press <?> for additional information about this option."), -inputbox_instructions_int[] = N_( +	"Press <?> for additional information about this option.", +inputbox_instructions_int[] =  	"Please enter a decimal value. "  	"Fractions will not be accepted.  " -	"Use the <TAB> key to move from the input field to the buttons below it."), -inputbox_instructions_hex[] = N_( +	"Use the <TAB> key to move from the input field to the buttons below it.", +inputbox_instructions_hex[] =  	"Please enter a hexadecimal value. " -	"Use the <TAB> key to move from the input field to the buttons below it."), -inputbox_instructions_string[] = N_( +	"Use the <TAB> key to move from the input field to the buttons below it.", +inputbox_instructions_string[] =  	"Please enter a string value. " -	"Use the <TAB> key to move from the input field to the buttons below it."), -setmod_text[] = N_( +	"Use the <TAB> key to move from the input field to the buttons below it.", +setmod_text[] =  	"This feature depends on another which has been configured as a module.\n" -	"As a result, this feature will be built as a module."), -load_config_text[] = N_( +	"As a result, this feature will be built as a module.", +load_config_text[] =  	"Enter the name of the configuration file you wish to load.  "  	"Accept the name shown to restore the configuration you " -	"last retrieved.  Leave blank to abort."), -load_config_help[] = N_( +	"last retrieved.  Leave blank to abort.", +load_config_help[] =  	"\n"  	"For various reasons, one may wish to keep several different\n"  	"configurations available on a single machine.\n" @@ -211,11 +210,11 @@ load_config_help[] = N_(  	"configuration.\n"  	"\n"  	"If you are uncertain, then you have probably never used alternate\n" -	"configuration files. You should therefore leave this blank to abort.\n"), -save_config_text[] = N_( +	"configuration files. You should therefore leave this blank to abort.\n", +save_config_text[] =  	"Enter a filename to which this configuration should be saved " -	"as an alternate.  Leave blank to abort."), -save_config_help[] = N_( +	"as an alternate.  Leave blank to abort.", +save_config_help[] =  	"\n"  	"For various reasons, one may wish to keep different configurations\n"  	"available on a single machine.\n" @@ -225,8 +224,8 @@ save_config_help[] = N_(  	"configuration options you have selected at that time.\n"  	"\n"  	"If you are uncertain what all this means then you should probably\n" -	"leave this blank.\n"), -search_help[] = N_( +	"leave this blank.\n", +search_help[] =  	"\n"  	"Search for symbols and display their relations.\n"  	"Regular expressions are allowed.\n" @@ -271,7 +270,7 @@ search_help[] = N_(  	"Examples: USB	=> find all symbols containing USB\n"  	"          ^USB => find all symbols starting with USB\n"  	"          USB$ => find all symbols ending with USB\n" -	"\n"); +	"\n";  static int indent;  static struct menu *current_menu; @@ -400,19 +399,19 @@ static void search_conf(void)  	struct subtitle_part stpart;  	title = str_new(); -	str_printf( &title, _("Enter (sub)string or regexp to search for " -			      "(with or without \"%s\")"), CONFIG_); +	str_printf( &title, "Enter (sub)string or regexp to search for " +			      "(with or without \"%s\")", CONFIG_);  again:  	dialog_clear(); -	dres = dialog_inputbox(_("Search Configuration Parameter"), +	dres = dialog_inputbox("Search Configuration Parameter",  			      str_get(&title),  			      10, 75, "");  	switch (dres) {  	case 0:  		break;  	case 1: -		show_helptext(_("Search Configuration"), search_help); +		show_helptext("Search Configuration", search_help);  		goto again;  	default:  		str_free(&title); @@ -443,7 +442,7 @@ again:  		res = get_relations_str(sym_arr, &head);  		set_subtitle(); -		dres = show_textbox_ext(_("Search Results"), (char *) +		dres = show_textbox_ext("Search Results", (char *)  					str_get(&res), 0, 0, keys, &vscroll,  					&hscroll, &update_text, (void *)  					&data); @@ -491,7 +490,7 @@ static void build_conf(struct menu *menu)  			switch (prop->type) {  			case P_MENU:  				child_count++; -				prompt = _(prompt); +				prompt = prompt;  				if (single_menu_mode) {  					item_make("%s%*c%s",  						  menu->data ? "-->" : "++>", @@ -508,7 +507,7 @@ static void build_conf(struct menu *menu)  			case P_COMMENT:  				if (prompt) {  					child_count++; -					item_make("   %*c*** %s ***", indent + 1, ' ', _(prompt)); +					item_make("   %*c*** %s ***", indent + 1, ' ', prompt);  					item_set_tag(':');  					item_set_data(menu);  				} @@ -516,7 +515,7 @@ static void build_conf(struct menu *menu)  			default:  				if (prompt) {  					child_count++; -					item_make("---%*c%s", indent + 1, ' ', _(prompt)); +					item_make("---%*c%s", indent + 1, ' ', prompt);  					item_set_tag(':');  					item_set_data(menu);  				} @@ -560,10 +559,10 @@ static void build_conf(struct menu *menu)  			item_set_data(menu);  		} -		item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu))); +		item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu));  		if (val == yes) {  			if (def_menu) { -				item_add_str(" (%s)", _(menu_get_prompt(def_menu))); +				item_add_str(" (%s)", menu_get_prompt(def_menu));  				item_add_str("  --->");  				if (def_menu->list) {  					indent += 2; @@ -575,7 +574,7 @@ static void build_conf(struct menu *menu)  		}  	} else {  		if (menu == current_menu) { -			item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu))); +			item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));  			item_set_tag(':');  			item_set_data(menu);  			goto conf_childs; @@ -618,17 +617,17 @@ static void build_conf(struct menu *menu)  				tmp = indent - tmp + 4;  				if (tmp < 0)  					tmp = 0; -				item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)), +				item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu),  					     (sym_has_value(sym) || !sym_is_changable(sym)) ? -					     "" : _(" (NEW)")); +					     "" : " (NEW)");  				item_set_tag('s');  				item_set_data(menu);  				goto conf_childs;  			}  		} -		item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)), +		item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),  			  (sym_has_value(sym) || !sym_is_changable(sym)) ? -			  "" : _(" (NEW)")); +			  "" : " (NEW)");  		if (menu->prompt->type == P_MENU) {  			item_add_str("  %s", menu_is_empty(menu) ? "----" : "--->");  			return; @@ -665,8 +664,8 @@ static void conf(struct menu *menu, struct menu *active_menu)  			break;  		set_subtitle();  		dialog_clear(); -		res = dialog_menu(prompt ? _(prompt) : _("Main Menu"), -				  _(menu_instructions), +		res = dialog_menu(prompt ? prompt : "Main Menu", +				  menu_instructions,  				  active_menu, &s_scroll);  		if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)  			break; @@ -708,7 +707,7 @@ static void conf(struct menu *menu, struct menu *active_menu)  				show_help(submenu);  			else {  				reset_subtitle(); -				show_helptext(_("README"), _(mconf_readme)); +				show_helptext("README", mconf_readme);  			}  			break;  		case 3: @@ -793,13 +792,13 @@ static void show_help(struct menu *menu)  	help.max_width = getmaxx(stdscr) - 10;  	menu_get_ext_help(menu, &help); -	show_helptext(_(menu_get_prompt(menu)), str_get(&help)); +	show_helptext(menu_get_prompt(menu), str_get(&help));  	str_free(&help);  }  static void conf_choice(struct menu *menu)  { -	const char *prompt = _(menu_get_prompt(menu)); +	const char *prompt = menu_get_prompt(menu);  	struct menu *child;  	struct symbol *active; @@ -814,9 +813,9 @@ static void conf_choice(struct menu *menu)  			if (!menu_is_visible(child))  				continue;  			if (child->sym) -				item_make("%s", _(menu_get_prompt(child))); +				item_make("%s", menu_get_prompt(child));  			else { -				item_make("*** %s ***", _(menu_get_prompt(child))); +				item_make("*** %s ***", menu_get_prompt(child));  				item_set_tag(':');  			}  			item_set_data(child); @@ -826,8 +825,8 @@ static void conf_choice(struct menu *menu)  				item_set_tag('X');  		}  		dialog_clear(); -		res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"), -					_(radiolist_instructions), +		res = dialog_checklist(prompt ? prompt : "Main Menu", +					radiolist_instructions,  					MENUBOX_HEIGTH_MIN,  					MENUBOX_WIDTH_MIN,  					CHECKLIST_HEIGTH_MIN); @@ -868,26 +867,26 @@ static void conf_string(struct menu *menu)  		switch (sym_get_type(menu->sym)) {  		case S_INT: -			heading = _(inputbox_instructions_int); +			heading = inputbox_instructions_int;  			break;  		case S_HEX: -			heading = _(inputbox_instructions_hex); +			heading = inputbox_instructions_hex;  			break;  		case S_STRING: -			heading = _(inputbox_instructions_string); +			heading = inputbox_instructions_string;  			break;  		default: -			heading = _("Internal mconf error!"); +			heading = "Internal mconf error!";  		}  		dialog_clear(); -		res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"), +		res = dialog_inputbox(prompt ? prompt : "Main Menu",  				      heading, 10, 75,  				      sym_get_string_value(menu->sym));  		switch (res) {  		case 0:  			if (sym_set_string_value(menu->sym, dialog_input_result))  				return; -			show_textbox(NULL, _("You have made an invalid entry."), 5, 43); +			show_textbox(NULL, "You have made an invalid entry.", 5, 43);  			break;  		case 1:  			show_help(menu); @@ -915,10 +914,10 @@ static void conf_load(void)  				sym_set_change_count(1);  				return;  			} -			show_textbox(NULL, _("File does not exist!"), 5, 38); +			show_textbox(NULL, "File does not exist!", 5, 38);  			break;  		case 1: -			show_helptext(_("Load Alternate Configuration"), load_config_help); +			show_helptext("Load Alternate Configuration", load_config_help);  			break;  		case KEY_ESC:  			return; @@ -941,10 +940,10 @@ static void conf_save(void)  				set_config_filename(dialog_input_result);  				return;  			} -			show_textbox(NULL, _("Can't create file!  Probably a nonexistent directory."), 5, 60); +			show_textbox(NULL, "Can't create file!  Probably a nonexistent directory.", 5, 60);  			break;  		case 1: -			show_helptext(_("Save Alternate Configuration"), save_config_help); +			show_helptext("Save Alternate Configuration", save_config_help);  			break;  		case KEY_ESC:  			return; @@ -961,8 +960,8 @@ static int handle_exit(void)  	dialog_clear();  	if (conf_get_changed())  		res = dialog_yesno(NULL, -				   _("Do you wish to save your new configuration?\n" -				     "(Press <ESC><ESC> to continue kernel configuration.)"), +				   "Do you wish to save your new configuration?\n" +				     "(Press <ESC><ESC> to continue kernel configuration.)",  				   6, 60);  	else  		res = -1; @@ -972,26 +971,26 @@ static int handle_exit(void)  	switch (res) {  	case 0:  		if (conf_write(filename)) { -			fprintf(stderr, _("\n\n" +			fprintf(stderr, "\n\n"  					  "Error while writing of the configuration.\n"  					  "Your configuration changes were NOT saved." -					  "\n\n")); +					  "\n\n");  			return 1;  		}  		/* fall through */  	case -1:  		if (!silent) -			printf(_("\n\n" +			printf("\n\n"  				 "*** End of the configuration.\n"  				 "*** Execute 'make' to start the build or try 'make help'." -				 "\n\n")); +				 "\n\n");  		res = 0;  		break;  	default:  		if (!silent) -			fprintf(stderr, _("\n\n" +			fprintf(stderr, "\n\n"  					  "Your configuration changes were NOT saved." -					  "\n\n")); +					  "\n\n");  		if (res != KEY_ESC)  			res = 0;  	} @@ -1009,10 +1008,6 @@ int main(int ac, char **av)  	char *mode;  	int res; -	setlocale(LC_ALL, ""); -	bindtextdomain(PACKAGE, LOCALEDIR); -	textdomain(PACKAGE); -  	signal(SIGINT, sig_handler);  	if (ac > 1 && strcmp(av[1], "-s") == 0) { @@ -1031,8 +1026,8 @@ int main(int ac, char **av)  	}  	if (init_dialog(NULL)) { -		fprintf(stderr, N_("Your display is too small to run Menuconfig!\n")); -		fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n")); +		fprintf(stderr, "Your display is too small to run Menuconfig!\n"); +		fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");  		return 1;  	} diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 5c5c1374b151..379a119dcd1e 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -214,9 +214,6 @@ void menu_add_option(int token, char *arg)  			zconf_error("trying to redefine defconfig symbol");  		sym_defconfig_list->flags |= SYMBOL_AUTO;  		break; -	case T_OPT_ENV: -		prop_add_env(arg); -		break;  	case T_OPT_ALLNOCONFIG_Y:  		current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y;  		break; @@ -711,7 +708,7 @@ static void get_prompt_str(struct gstr *r, struct property *prop,  	struct menu *submenu[8], *menu, *location = NULL;  	struct jump_key *jump = NULL; -	str_printf(r, _("Prompt: %s\n"), _(prop->text)); +	str_printf(r, "Prompt: %s\n", prop->text);  	menu = prop->menu->parent;  	for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) {  		bool accessible = menu_is_visible(menu); @@ -744,16 +741,16 @@ static void get_prompt_str(struct gstr *r, struct property *prop,  	}  	if (i > 0) { -		str_printf(r, _("  Location:\n")); +		str_printf(r, "  Location:\n");  		for (j = 4; --i >= 0; j += 2) {  			menu = submenu[i];  			if (jump && menu == location)  				jump->offset = strlen(r->s);  			str_printf(r, "%*c-> %s", j, ' ', -				   _(menu_get_prompt(menu))); +				   menu_get_prompt(menu));  			if (menu->sym) {  				str_printf(r, " (%s [=%s])", menu->sym->name ? -					menu->sym->name : _("<choice>"), +					menu->sym->name : "<choice>",  					sym_get_string_value(menu->sym));  			}  			str_append(r, "\n"); @@ -817,23 +814,23 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym,  	prop = get_symbol_prop(sym);  	if (prop) { -		str_printf(r, _("  Defined at %s:%d\n"), prop->menu->file->name, +		str_printf(r, "  Defined at %s:%d\n", prop->menu->file->name,  			prop->menu->lineno);  		if (!expr_is_yes(prop->visible.expr)) { -			str_append(r, _("  Depends on: ")); +			str_append(r, "  Depends on: ");  			expr_gstr_print(prop->visible.expr, r);  			str_append(r, "\n");  		}  	} -	get_symbol_props_str(r, sym, P_SELECT, _("  Selects: ")); +	get_symbol_props_str(r, sym, P_SELECT, "  Selects: ");  	if (sym->rev_dep.expr) {  		expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, "  Selected by [y]:\n");  		expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, "  Selected by [m]:\n");  		expr_gstr_print_revdep(sym->rev_dep.expr, r, no, "  Selected by [n]:\n");  	} -	get_symbol_props_str(r, sym, P_IMPLY, _("  Implies: ")); +	get_symbol_props_str(r, sym, P_IMPLY, "  Implies: ");  	if (sym->implied.expr) {  		expr_gstr_print_revdep(sym->implied.expr, r, yes, "  Implied by [y]:\n");  		expr_gstr_print_revdep(sym->implied.expr, r, mod, "  Implied by [m]:\n"); @@ -852,7 +849,7 @@ struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head)  	for (i = 0; sym_arr && (sym = sym_arr[i]); i++)  		get_symbol_str(&res, sym, head);  	if (!i) -		str_append(&res, _("No matches found.\n")); +		str_append(&res, "No matches found.\n");  	return res;  } @@ -867,7 +864,7 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help)  			str_printf(help, "%s%s:\n\n", CONFIG_, sym->name);  		help_text = menu_get_help(menu);  	} -	str_printf(help, "%s\n", _(help_text)); +	str_printf(help, "%s\n", help_text);  	if (sym)  		get_symbol_str(help, sym, NULL);  } diff --git a/scripts/kconfig/nconf-cfg.sh b/scripts/kconfig/nconf-cfg.sh new file mode 100644 index 000000000000..42f5ac73548e --- /dev/null +++ b/scripts/kconfig/nconf-cfg.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +PKG="ncursesw menuw panelw" +PKG2="ncurses menu panel" + +if pkg-config --exists $PKG; then +	echo cflags=\"$(pkg-config --cflags $PKG)\" +	echo libs=\"$(pkg-config --libs $PKG)\" +	exit 0 +fi + +if pkg-config --exists $PKG2; then +	echo cflags=\"$(pkg-config --cflags $PKG2)\" +	echo libs=\"$(pkg-config --libs $PKG2)\" +	exit 0 +fi + +# Unfortunately, some distributions (e.g. openSUSE) cannot find ncurses +# by pkg-config. +if [ -f /usr/include/ncursesw/ncurses.h ]; then +	echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncursesw\" +	echo libs=\"-lncursesw -lmenuw -lpanelw\" +	exit 0 +fi + +if [ -f /usr/include/ncurses/ncurses.h ]; then +	echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncurses\" +	echo libs=\"-lncurses -lmenu -lpanel\" +	exit 0 +fi + +if [ -f /usr/include/ncurses.h ]; then +	echo cflags=\"-D_GNU_SOURCE\" +	echo libs=\"-lncurses -lmenu -lpanel\" +	exit 0 +fi + +echo >&2 "*" +echo >&2 "* Unable to find the ncurses package." +echo >&2 "* Install ncurses (ncurses-devel or libncurses-dev" +echo >&2 "* depending on your distribution)." +echo >&2 "*" +exit 1 diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 003114779815..97b78445584b 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -15,7 +15,7 @@  #include "nconf.h"  #include <ctype.h> -static const char nconf_global_help[] = N_( +static const char nconf_global_help[] =  "Help windows\n"  "------------\n"  "o  Global help:  Unless in a data entry window, pressing <F1> will give \n" @@ -130,8 +130,8 @@ static const char nconf_global_help[] = N_(  "\n"  "Note that this mode can eventually be a little more CPU expensive than\n"  "the default mode, especially with a larger number of unfolded submenus.\n" -"\n"), -menu_no_f_instructions[] = N_( +"\n", +menu_no_f_instructions[] =  "Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n"  "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"  "\n" @@ -147,8 +147,8 @@ menu_no_f_instructions[] = N_(  "You do not have function keys support.\n"  "Press <1> instead of <F1>, <2> instead of <F2>, etc.\n"  "For verbose global help use key <1>.\n" -"For help related to the current menu entry press <?> or <h>.\n"), -menu_instructions[] = N_( +"For help related to the current menu entry press <?> or <h>.\n", +menu_instructions[] =  "Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n"  "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"  "\n" @@ -163,30 +163,30 @@ menu_instructions[] = N_(  "\n"  "Pressing <1> may be used instead of <F1>, <2> instead of <F2>, etc.\n"  "For verbose global help press <F1>.\n" -"For help related to the current menu entry press <?> or <h>.\n"), -radiolist_instructions[] = N_( +"For help related to the current menu entry press <?> or <h>.\n", +radiolist_instructions[] =  "Press <Up>, <Down>, <Home> or <End> to navigate a radiolist, select\n"  "with <Space>.\n"  "For help related to the current entry press <?> or <h>.\n" -"For global help press <F1>.\n"), -inputbox_instructions_int[] = N_( +"For global help press <F1>.\n", +inputbox_instructions_int[] =  "Please enter a decimal value.\n"  "Fractions will not be accepted.\n" -"Press <Enter> to apply, <Esc> to cancel."), -inputbox_instructions_hex[] = N_( +"Press <Enter> to apply, <Esc> to cancel.", +inputbox_instructions_hex[] =  "Please enter a hexadecimal value.\n" -"Press <Enter> to apply, <Esc> to cancel."), -inputbox_instructions_string[] = N_( +"Press <Enter> to apply, <Esc> to cancel.", +inputbox_instructions_string[] =  "Please enter a string value.\n" -"Press <Enter> to apply, <Esc> to cancel."), -setmod_text[] = N_( +"Press <Enter> to apply, <Esc> to cancel.", +setmod_text[] =  "This feature depends on another feature which has been configured as a\n" -"module.  As a result, the current feature will be built as a module too."), -load_config_text[] = N_( +"module.  As a result, the current feature will be built as a module too.", +load_config_text[] =  "Enter the name of the configuration file you wish to load.\n"  "Accept the name shown to restore the configuration you last\n" -"retrieved.  Leave empty to abort."), -load_config_help[] = N_( +"retrieved.  Leave empty to abort.", +load_config_help[] =  "For various reasons, one may wish to keep several different\n"  "configurations available on a single machine.\n"  "\n" @@ -194,11 +194,11 @@ load_config_help[] = N_(  "default one, entering its name here will allow you to load and modify\n"  "that configuration.\n"  "\n" -"Leave empty to abort.\n"), -save_config_text[] = N_( +"Leave empty to abort.\n", +save_config_text[] =  "Enter a filename to which this configuration should be saved\n" -"as an alternate.  Leave empty to abort."), -save_config_help[] = N_( +"as an alternate.  Leave empty to abort.", +save_config_help[] =  "For various reasons, one may wish to keep several different\n"  "configurations available on a single machine.\n"  "\n" @@ -206,8 +206,8 @@ save_config_help[] = N_(  "and use the current configuration as an alternate to whatever\n"  "configuration options you have selected at that time.\n"  "\n" -"Leave empty to abort.\n"), -search_help[] = N_( +"Leave empty to abort.\n", +search_help[] =  "Search for symbols (configuration variable names CONFIG_*) and display\n"  "their relations.  Regular expressions are supported.\n"  "Example:  Search for \"^FOO\".\n" @@ -244,7 +244,7 @@ search_help[] = N_(  "USB  => find all symbols containing USB\n"  "^USB => find all symbols starting with USB\n"  "USB$ => find all symbols ending with USB\n" -"\n"); +"\n";  struct mitem {  	char str[256]; @@ -388,7 +388,7 @@ static void print_function_line(void)  static void handle_f1(int *key, struct menu *current_item)  {  	show_scroll_win(main_window, -			_("Global help"), _(nconf_global_help)); +			"Global help", nconf_global_help);  	return;  } @@ -403,8 +403,8 @@ static void handle_f2(int *key, struct menu *current_item)  static void handle_f3(int *key, struct menu *current_item)  {  	show_scroll_win(main_window, -			_("Short help"), -			_(current_instructions)); +			"Short help", +			current_instructions);  	return;  } @@ -412,7 +412,7 @@ static void handle_f3(int *key, struct menu *current_item)  static void handle_f4(int *key, struct menu *current_item)  {  	int res = btn_dialog(main_window, -			_("Show all symbols?"), +			"Show all symbols?",  			2,  			"   <Show All>   ",  			"<Don't show all>"); @@ -653,8 +653,8 @@ static int do_exit(void)  		return 0;  	}  	res = btn_dialog(main_window, -			_("Do you wish to save your new configuration?\n" -				"<ESC> to cancel and resume nconfig."), +			"Do you wish to save your new configuration?\n" +				"<ESC> to cancel and resume nconfig.",  			2,  			"   <save>   ",  			"<don't save>"); @@ -670,15 +670,15 @@ static int do_exit(void)  		if (res)  			btn_dialog(  				main_window, -				_("Error during writing of configuration.\n" -				  "Your configuration changes were NOT saved."), +				"Error during writing of configuration.\n" +				  "Your configuration changes were NOT saved.",  				  1,  				  "<OK>");  		break;  	default:  		btn_dialog(  			main_window, -			_("Your configuration changes were NOT saved."), +			"Your configuration changes were NOT saved.",  			1,  			"<OK>");  		break; @@ -697,12 +697,12 @@ static void search_conf(void)  	int dres;  	title = str_new(); -	str_printf( &title, _("Enter (sub)string or regexp to search for " -			      "(with or without \"%s\")"), CONFIG_); +	str_printf( &title, "Enter (sub)string or regexp to search for " +			      "(with or without \"%s\")", CONFIG_);  again:  	dres = dialog_inputbox(main_window, -			_("Search Configuration Parameter"), +			"Search Configuration Parameter",  			str_get(&title),  			"", &dialog_input_result, &dialog_input_result_len);  	switch (dres) { @@ -710,7 +710,7 @@ again:  		break;  	case 1:  		show_scroll_win(main_window, -				_("Search Configuration"), search_help); +				"Search Configuration", search_help);  		goto again;  	default:  		str_free(&title); @@ -726,7 +726,7 @@ again:  	res = get_relations_str(sym_arr, NULL);  	free(sym_arr);  	show_scroll_win(main_window, -			_("Search Results"), str_get(&res)); +			"Search Results", str_get(&res));  	str_free(&res);  	str_free(&title);  } @@ -754,7 +754,7 @@ static void build_conf(struct menu *menu)  			switch (ptype) {  			case P_MENU:  				child_count++; -				prompt = _(prompt); +				prompt = prompt;  				if (single_menu_mode) {  					item_make(menu, 'm',  						"%s%*c%s", @@ -775,7 +775,7 @@ static void build_conf(struct menu *menu)  					item_make(menu, ':',  						"   %*c*** %s ***",  						indent + 1, ' ', -						_(prompt)); +						prompt);  				}  				break;  			default: @@ -783,7 +783,7 @@ static void build_conf(struct menu *menu)  					child_count++;  					item_make(menu, ':', "---%*c%s",  						indent + 1, ' ', -						_(prompt)); +						prompt);  				}  			}  		} else @@ -829,11 +829,11 @@ static void build_conf(struct menu *menu)  		}  		item_add_str("%*c%s", indent + 1, -				' ', _(menu_get_prompt(menu))); +				' ', menu_get_prompt(menu));  		if (val == yes) {  			if (def_menu) {  				item_add_str(" (%s)", -					_(menu_get_prompt(def_menu))); +					menu_get_prompt(def_menu));  				item_add_str("  --->");  				if (def_menu->list) {  					indent += 2; @@ -847,7 +847,7 @@ static void build_conf(struct menu *menu)  		if (menu == current_menu) {  			item_make(menu, ':',  				"---%*c%s", indent + 1, -				' ', _(menu_get_prompt(menu))); +				' ', menu_get_prompt(menu));  			goto conf_childs;  		}  		child_count++; @@ -894,17 +894,17 @@ static void build_conf(struct menu *menu)  				if (tmp < 0)  					tmp = 0;  				item_add_str("%*c%s%s", tmp, ' ', -						_(menu_get_prompt(menu)), +						menu_get_prompt(menu),  						(sym_has_value(sym) ||  						 !sym_is_changable(sym)) ? "" : -						_(" (NEW)")); +						" (NEW)");  				goto conf_childs;  			}  		}  		item_add_str("%*c%s%s", indent + 1, ' ', -				_(menu_get_prompt(menu)), +				menu_get_prompt(menu),  				(sym_has_value(sym) || !sym_is_changable(sym)) ? -				"" : _(" (NEW)")); +				"" : " (NEW)");  		if (menu->prompt && menu->prompt->type == P_MENU) {  			item_add_str("  %s", menu_is_empty(menu) ? "----" : "--->");  			return; @@ -1086,8 +1086,8 @@ static void conf(struct menu *menu)  		if (!child_count)  			break; -		show_menu(prompt ? _(prompt) : _("Main Menu"), -				_(menu_instructions), +		show_menu(prompt ? prompt : "Main Menu", +				menu_instructions,  				current_index, &last_top_row);  		keypad((menu_win(curses_menu)), TRUE);  		while (!global_exit) { @@ -1227,13 +1227,13 @@ static void show_help(struct menu *menu)  	help = str_new();  	menu_get_ext_help(menu, &help); -	show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help)); +	show_scroll_win(main_window, menu_get_prompt(menu), str_get(&help));  	str_free(&help);  }  static void conf_choice(struct menu *menu)  { -	const char *prompt = _(menu_get_prompt(menu)); +	const char *prompt = menu_get_prompt(menu);  	struct menu *child = NULL;  	struct symbol *active;  	int selected_index = 0; @@ -1256,13 +1256,13 @@ static void conf_choice(struct menu *menu)  			if (child->sym == sym_get_choice_value(menu->sym))  				item_make(child, ':', "<X> %s", -						_(menu_get_prompt(child))); +						menu_get_prompt(child));  			else if (child->sym)  				item_make(child, ':', "    %s", -						_(menu_get_prompt(child))); +						menu_get_prompt(child));  			else  				item_make(child, ':', "*** %s ***", -						_(menu_get_prompt(child))); +						menu_get_prompt(child));  			if (child->sym == active){  				last_top_row = top_row(curses_menu); @@ -1270,8 +1270,8 @@ static void conf_choice(struct menu *menu)  			}  			i++;  		} -		show_menu(prompt ? _(prompt) : _("Choice Menu"), -				_(radiolist_instructions), +		show_menu(prompt ? prompt : "Choice Menu", +				radiolist_instructions,  				selected_index,  				&last_top_row);  		while (!global_exit) { @@ -1358,19 +1358,19 @@ static void conf_string(struct menu *menu)  		switch (sym_get_type(menu->sym)) {  		case S_INT: -			heading = _(inputbox_instructions_int); +			heading = inputbox_instructions_int;  			break;  		case S_HEX: -			heading = _(inputbox_instructions_hex); +			heading = inputbox_instructions_hex;  			break;  		case S_STRING: -			heading = _(inputbox_instructions_string); +			heading = inputbox_instructions_string;  			break;  		default: -			heading = _("Internal nconf error!"); +			heading = "Internal nconf error!";  		}  		res = dialog_inputbox(main_window, -				prompt ? _(prompt) : _("Main Menu"), +				prompt ? prompt : "Main Menu",  				heading,  				sym_get_string_value(menu->sym),  				&dialog_input_result, @@ -1381,7 +1381,7 @@ static void conf_string(struct menu *menu)  						dialog_input_result))  				return;  			btn_dialog(main_window, -				_("You have made an invalid entry."), 0); +				"You have made an invalid entry.", 0);  			break;  		case 1:  			show_help(menu); @@ -1410,11 +1410,11 @@ static void conf_load(void)  				sym_set_change_count(1);  				return;  			} -			btn_dialog(main_window, _("File does not exist!"), 0); +			btn_dialog(main_window, "File does not exist!", 0);  			break;  		case 1:  			show_scroll_win(main_window, -					_("Load Alternate Configuration"), +					"Load Alternate Configuration",  					load_config_help);  			break;  		case KEY_EXIT: @@ -1441,13 +1441,13 @@ static void conf_save(void)  				set_config_filename(dialog_input_result);  				return;  			} -			btn_dialog(main_window, _("Can't create file! " -				"Probably a nonexistent directory."), +			btn_dialog(main_window, "Can't create file! " +				"Probably a nonexistent directory.",  				1, "<OK>");  			break;  		case 1:  			show_scroll_win(main_window, -				_("Save Alternate Configuration"), +				"Save Alternate Configuration",  				save_config_help);  			break;  		case KEY_EXIT: @@ -1480,10 +1480,6 @@ int main(int ac, char **av)  	int lines, columns;  	char *mode; -	setlocale(LC_ALL, ""); -	bindtextdomain(PACKAGE, LOCALEDIR); -	textdomain(PACKAGE); -  	if (ac > 1 && strcmp(av[1], "-s") == 0) {  		/* Silence conf_read() until the real callback is set up */  		conf_set_message_callback(NULL); @@ -1541,8 +1537,8 @@ int main(int ac, char **av)  	/* check for KEY_FUNC(1) */  	if (has_key(KEY_F(1)) == FALSE) {  		show_scroll_win(main_window, -				_("Instructions"), -				_(menu_no_f_instructions)); +				"Instructions", +				menu_no_f_instructions);  	}  	conf_set_message_callback(conf_message_callback); diff --git a/scripts/kconfig/nconf.h b/scripts/kconfig/nconf.h index 9f6f21d3b0d4..2b9e19f603c4 100644 --- a/scripts/kconfig/nconf.h +++ b/scripts/kconfig/nconf.h @@ -14,7 +14,6 @@  #include <stdlib.h>  #include <string.h>  #include <unistd.h> -#include <locale.h>  #include <ncurses.h>  #include <menu.h>  #include <panel.h> diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c new file mode 100644 index 000000000000..5ca2df790d3c --- /dev/null +++ b/scripts/kconfig/preprocess.c @@ -0,0 +1,572 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (C) 2018 Masahiro Yamada <[email protected]> + +#include <stdarg.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "list.h" + +#define ARRAY_SIZE(arr)		(sizeof(arr) / sizeof((arr)[0])) + +static char *expand_string_with_args(const char *in, int argc, char *argv[]); + +static void __attribute__((noreturn)) pperror(const char *format, ...) +{ +	va_list ap; + +	fprintf(stderr, "%s:%d: ", current_file->name, yylineno); +	va_start(ap, format); +	vfprintf(stderr, format, ap); +	va_end(ap); +	fprintf(stderr, "\n"); + +	exit(1); +} + +/* + * Environment variables + */ +static LIST_HEAD(env_list); + +struct env { +	char *name; +	char *value; +	struct list_head node; +}; + +static void env_add(const char *name, const char *value) +{ +	struct env *e; + +	e = xmalloc(sizeof(*e)); +	e->name = xstrdup(name); +	e->value = xstrdup(value); + +	list_add_tail(&e->node, &env_list); +} + +static void env_del(struct env *e) +{ +	list_del(&e->node); +	free(e->name); +	free(e->value); +	free(e); +} + +/* The returned pointer must be freed when done */ +static char *env_expand(const char *name) +{ +	struct env *e; +	const char *value; + +	if (!*name) +		return NULL; + +	list_for_each_entry(e, &env_list, node) { +		if (!strcmp(name, e->name)) +			return xstrdup(e->value); +	} + +	value = getenv(name); +	if (!value) +		return NULL; + +	/* +	 * We need to remember all referenced environment variables. +	 * They will be written out to include/config/auto.conf.cmd +	 */ +	env_add(name, value); + +	return xstrdup(value); +} + +void env_write_dep(FILE *f, const char *autoconfig_name) +{ +	struct env *e, *tmp; + +	list_for_each_entry_safe(e, tmp, &env_list, node) { +		fprintf(f, "ifneq \"$(%s)\" \"%s\"\n", e->name, e->value); +		fprintf(f, "%s: FORCE\n", autoconfig_name); +		fprintf(f, "endif\n"); +		env_del(e); +	} +} + +/* + * Built-in functions + */ +struct function { +	const char *name; +	unsigned int min_args; +	unsigned int max_args; +	char *(*func)(int argc, char *argv[]); +}; + +static char *do_error_if(int argc, char *argv[]) +{ +	if (!strcmp(argv[0], "y")) +		pperror("%s", argv[1]); + +	return NULL; +} + +static char *do_filename(int argc, char *argv[]) +{ +	return xstrdup(current_file->name); +} + +static char *do_info(int argc, char *argv[]) +{ +	printf("%s\n", argv[0]); + +	return xstrdup(""); +} + +static char *do_lineno(int argc, char *argv[]) +{ +	char buf[16]; + +	sprintf(buf, "%d", yylineno); + +	return xstrdup(buf); +} + +static char *do_shell(int argc, char *argv[]) +{ +	FILE *p; +	char buf[256]; +	char *cmd; +	size_t nread; +	int i; + +	cmd = argv[0]; + +	p = popen(cmd, "r"); +	if (!p) { +		perror(cmd); +		exit(1); +	} + +	nread = fread(buf, 1, sizeof(buf), p); +	if (nread == sizeof(buf)) +		nread--; + +	/* remove trailing new lines */ +	while (nread > 0 && buf[nread - 1] == '\n') +		nread--; + +	buf[nread] = 0; + +	/* replace a new line with a space */ +	for (i = 0; i < nread; i++) { +		if (buf[i] == '\n') +			buf[i] = ' '; +	} + +	if (pclose(p) == -1) { +		perror(cmd); +		exit(1); +	} + +	return xstrdup(buf); +} + +static char *do_warning_if(int argc, char *argv[]) +{ +	if (!strcmp(argv[0], "y")) +		fprintf(stderr, "%s:%d: %s\n", +			current_file->name, yylineno, argv[1]); + +	return xstrdup(""); +} + +static const struct function function_table[] = { +	/* Name		MIN	MAX	Function */ +	{ "error-if",	2,	2,	do_error_if }, +	{ "filename",	0,	0,	do_filename }, +	{ "info",	1,	1,	do_info }, +	{ "lineno",	0,	0,	do_lineno }, +	{ "shell",	1,	1,	do_shell }, +	{ "warning-if",	2,	2,	do_warning_if }, +}; + +#define FUNCTION_MAX_ARGS		16 + +static char *function_expand(const char *name, int argc, char *argv[]) +{ +	const struct function *f; +	int i; + +	for (i = 0; i < ARRAY_SIZE(function_table); i++) { +		f = &function_table[i]; +		if (strcmp(f->name, name)) +			continue; + +		if (argc < f->min_args) +			pperror("too few function arguments passed to '%s'", +				name); + +		if (argc > f->max_args) +			pperror("too many function arguments passed to '%s'", +				name); + +		return f->func(argc, argv); +	} + +	return NULL; +} + +/* + * Variables (and user-defined functions) + */ +static LIST_HEAD(variable_list); + +struct variable { +	char *name; +	char *value; +	enum variable_flavor flavor; +	int exp_count; +	struct list_head node; +}; + +static struct variable *variable_lookup(const char *name) +{ +	struct variable *v; + +	list_for_each_entry(v, &variable_list, node) { +		if (!strcmp(name, v->name)) +			return v; +	} + +	return NULL; +} + +static char *variable_expand(const char *name, int argc, char *argv[]) +{ +	struct variable *v; +	char *res; + +	v = variable_lookup(name); +	if (!v) +		return NULL; + +	if (argc == 0 && v->exp_count) +		pperror("Recursive variable '%s' references itself (eventually)", +			name); + +	if (v->exp_count > 1000) +		pperror("Too deep recursive expansion"); + +	v->exp_count++; + +	if (v->flavor == VAR_RECURSIVE) +		res = expand_string_with_args(v->value, argc, argv); +	else +		res = xstrdup(v->value); + +	v->exp_count--; + +	return res; +} + +void variable_add(const char *name, const char *value, +		  enum variable_flavor flavor) +{ +	struct variable *v; +	char *new_value; +	bool append = false; + +	v = variable_lookup(name); +	if (v) { +		/* For defined variables, += inherits the existing flavor */ +		if (flavor == VAR_APPEND) { +			flavor = v->flavor; +			append = true; +		} else { +			free(v->value); +		} +	} else { +		/* For undefined variables, += assumes the recursive flavor */ +		if (flavor == VAR_APPEND) +			flavor = VAR_RECURSIVE; + +		v = xmalloc(sizeof(*v)); +		v->name = xstrdup(name); +		v->exp_count = 0; +		list_add_tail(&v->node, &variable_list); +	} + +	v->flavor = flavor; + +	if (flavor == VAR_SIMPLE) +		new_value = expand_string(value); +	else +		new_value = xstrdup(value); + +	if (append) { +		v->value = xrealloc(v->value, +				    strlen(v->value) + strlen(new_value) + 2); +		strcat(v->value, " "); +		strcat(v->value, new_value); +		free(new_value); +	} else { +		v->value = new_value; +	} +} + +static void variable_del(struct variable *v) +{ +	list_del(&v->node); +	free(v->name); +	free(v->value); +	free(v); +} + +void variable_all_del(void) +{ +	struct variable *v, *tmp; + +	list_for_each_entry_safe(v, tmp, &variable_list, node) +		variable_del(v); +} + +/* + * Evaluate a clause with arguments.  argc/argv are arguments from the upper + * function call. + * + * Returned string must be freed when done + */ +static char *eval_clause(const char *str, size_t len, int argc, char *argv[]) +{ +	char *tmp, *name, *res, *endptr, *prev, *p; +	int new_argc = 0; +	char *new_argv[FUNCTION_MAX_ARGS]; +	int nest = 0; +	int i; +	unsigned long n; + +	tmp = xstrndup(str, len); + +	/* +	 * If variable name is '1', '2', etc.  It is generally an argument +	 * from a user-function call (i.e. local-scope variable).  If not +	 * available, then look-up global-scope variables. +	 */ +	n = strtoul(tmp, &endptr, 10); +	if (!*endptr && n > 0 && n <= argc) { +		res = xstrdup(argv[n - 1]); +		goto free_tmp; +	} + +	prev = p = tmp; + +	/* +	 * Split into tokens +	 * The function name and arguments are separated by a comma. +	 * For example, if the function call is like this: +	 *   $(foo,$(x),$(y)) +	 * +	 * The input string for this helper should be: +	 *   foo,$(x),$(y) +	 * +	 * and split into: +	 *   new_argv[0] = 'foo' +	 *   new_argv[1] = '$(x)' +	 *   new_argv[2] = '$(y)' +	 */ +	while (*p) { +		if (nest == 0 && *p == ',') { +			*p = 0; +			if (new_argc >= FUNCTION_MAX_ARGS) +				pperror("too many function arguments"); +			new_argv[new_argc++] = prev; +			prev = p + 1; +		} else if (*p == '(') { +			nest++; +		} else if (*p == ')') { +			nest--; +		} + +		p++; +	} +	new_argv[new_argc++] = prev; + +	/* +	 * Shift arguments +	 * new_argv[0] represents a function name or a variable name.  Put it +	 * into 'name', then shift the rest of the arguments.  This simplifies +	 * 'const' handling. +	 */ +	name = expand_string_with_args(new_argv[0], argc, argv); +	new_argc--; +	for (i = 0; i < new_argc; i++) +		new_argv[i] = expand_string_with_args(new_argv[i + 1], +						      argc, argv); + +	/* Search for variables */ +	res = variable_expand(name, new_argc, new_argv); +	if (res) +		goto free; + +	/* Look for built-in functions */ +	res = function_expand(name, new_argc, new_argv); +	if (res) +		goto free; + +	/* Last, try environment variable */ +	if (new_argc == 0) { +		res = env_expand(name); +		if (res) +			goto free; +	} + +	res = xstrdup(""); +free: +	for (i = 0; i < new_argc; i++) +		free(new_argv[i]); +	free(name); +free_tmp: +	free(tmp); + +	return res; +} + +/* + * Expand a string that follows '$' + * + * For example, if the input string is + *     ($(FOO)$($(BAR)))$(BAZ) + * this helper evaluates + *     $($(FOO)$($(BAR))) + * and returns a new string containing the expansion (note that the string is + * recursively expanded), also advancing 'str' to point to the next character + * after the corresponding closing parenthesis, in this case, *str will be + *     $(BAR) + */ +static char *expand_dollar_with_args(const char **str, int argc, char *argv[]) +{ +	const char *p = *str; +	const char *q; +	int nest = 0; + +	/* +	 * In Kconfig, variable/function references always start with "$(". +	 * Neither single-letter variables as in $A nor curly braces as in ${CC} +	 * are supported.  '$' not followed by '(' loses its special meaning. +	 */ +	if (*p != '(') { +		*str = p; +		return xstrdup("$"); +	} + +	p++; +	q = p; +	while (*q) { +		if (*q == '(') { +			nest++; +		} else if (*q == ')') { +			if (nest-- == 0) +				break; +		} +		q++; +	} + +	if (!*q) +		pperror("unterminated reference to '%s': missing ')'", p); + +	/* Advance 'str' to after the expanded initial portion of the string */ +	*str = q + 1; + +	return eval_clause(p, q - p, argc, argv); +} + +char *expand_dollar(const char **str) +{ +	return expand_dollar_with_args(str, 0, NULL); +} + +static char *__expand_string(const char **str, bool (*is_end)(char c), +			     int argc, char *argv[]) +{ +	const char *in, *p; +	char *expansion, *out; +	size_t in_len, out_len; + +	out = xmalloc(1); +	*out = 0; +	out_len = 1; + +	p = in = *str; + +	while (1) { +		if (*p == '$') { +			in_len = p - in; +			p++; +			expansion = expand_dollar_with_args(&p, argc, argv); +			out_len += in_len + strlen(expansion); +			out = xrealloc(out, out_len); +			strncat(out, in, in_len); +			strcat(out, expansion); +			free(expansion); +			in = p; +			continue; +		} + +		if (is_end(*p)) +			break; + +		p++; +	} + +	in_len = p - in; +	out_len += in_len; +	out = xrealloc(out, out_len); +	strncat(out, in, in_len); + +	/* Advance 'str' to the end character */ +	*str = p; + +	return out; +} + +static bool is_end_of_str(char c) +{ +	return !c; +} + +/* + * Expand variables and functions in the given string.  Undefined variables + * expand to an empty string. + * The returned string must be freed when done. + */ +static char *expand_string_with_args(const char *in, int argc, char *argv[]) +{ +	return __expand_string(&in, is_end_of_str, argc, argv); +} + +char *expand_string(const char *in) +{ +	return expand_string_with_args(in, 0, NULL); +} + +static bool is_end_of_token(char c) +{ +	/* Why are '.' and '/' valid characters for symbols? */ +	return !(isalnum(c) || c == '_' || c == '-' || c == '.' || c == '/'); +} + +/* + * Expand variables in a token.  The parsing stops when a token separater + * (in most cases, it is a whitespace) is encountered.  'str' is updated to + * point to the next character. + * + * The returned string must be freed when done. + */ +char *expand_one_token(const char **str) +{ +	return __expand_string(str, is_end_of_token, 0, NULL); +} diff --git a/scripts/kconfig/qconf-cfg.sh b/scripts/kconfig/qconf-cfg.sh new file mode 100755 index 000000000000..0862e1562536 --- /dev/null +++ b/scripts/kconfig/qconf-cfg.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +PKG="Qt5Core Qt5Gui Qt5Widgets" +PKG2="QtCore QtGui" + +if pkg-config --exists $PKG; then +	echo cflags=\"-std=c++11 -fPIC $(pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets)\" +	echo libs=\"$(pkg-config --libs $PKG)\" +	echo moc=\"$(pkg-config --variable=host_bins Qt5Core)/moc\" +	exit 0 +fi + +if pkg-config --exists $PKG2; then +	echo cflags=\"$(pkg-config --cflags $PKG2)\" +	echo libs=\"$(pkg-config --libs $PKG2)\" +	echo moc=\"$(pkg-config --variable=moc_location QtCore)\" +	exit 0 +fi + +echo >&2 "*" +echo >&2 "* Could not find Qt via pkg-config." +echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH" +echo >&2 "*" +exit 1 diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index ae6c72546411..ad9c22dd04f5 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -34,10 +34,6 @@  #include "qconf.moc"  #include "images.c" -#ifdef _ -# undef _ -# define _ qgettext -#endif  static QApplication *configApp;  static ConfigSettings *configSettings; @@ -46,12 +42,7 @@ QAction *ConfigMainWindow::saveAction;  static inline QString qgettext(const char* str)  { -	return QString::fromLocal8Bit(gettext(str)); -} - -static inline QString qgettext(const QString& str) -{ -	return QString::fromLocal8Bit(gettext(str.toLatin1())); +	return QString::fromLocal8Bit(str);  }  ConfigSettings::ConfigSettings() @@ -127,7 +118,7 @@ void ConfigItem::updateMenu(void)  	sym = menu->sym;  	prop = menu->prompt; -	prompt = _(menu_get_prompt(menu)); +	prompt = qgettext(menu_get_prompt(menu));  	if (prop) switch (prop->type) {  	case P_MENU: @@ -216,7 +207,7 @@ void ConfigItem::updateMenu(void)  		break;  	}  	if (!sym_has_value(sym) && visible) -		prompt += _(" (NEW)"); +		prompt += " (NEW)";  set_prompt:  	setText(promptColIdx, prompt);  } @@ -327,7 +318,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name)  	setVerticalScrollMode(ScrollPerPixel);  	setHorizontalScrollMode(ScrollPerPixel); -	setHeaderLabels(QStringList() << _("Option") << _("Name") << "N" << "M" << "Y" << _("Value")); +	setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value");  	connect(this, SIGNAL(itemSelectionChanged(void)),  		SLOT(updateSelection(void))); @@ -883,7 +874,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)  			QAction *action;  			headerPopup = new QMenu(this); -			action = new QAction(_("Show Name"), this); +			action = new QAction("Show Name", this);  			  action->setCheckable(true);  			  connect(action, SIGNAL(toggled(bool)),  				  parent(), SLOT(setShowName(bool))); @@ -891,7 +882,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)  				  action, SLOT(setOn(bool)));  			  action->setChecked(showName);  			  headerPopup->addAction(action); -			action = new QAction(_("Show Range"), this); +			action = new QAction("Show Range", this);  			  action->setCheckable(true);  			  connect(action, SIGNAL(toggled(bool)),  				  parent(), SLOT(setShowRange(bool))); @@ -899,7 +890,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)  				  action, SLOT(setOn(bool)));  			  action->setChecked(showRange);  			  headerPopup->addAction(action); -			action = new QAction(_("Show Data"), this); +			action = new QAction("Show Data", this);  			  action->setCheckable(true);  			  connect(action, SIGNAL(toggled(bool)),  				  parent(), SLOT(setShowData(bool))); @@ -1086,7 +1077,7 @@ void ConfigInfoView::menuInfo(void)  	if (sym) {  		if (_menu->prompt) {  			head += "<big><b>"; -			head += print_filter(_(_menu->prompt->text)); +			head += print_filter(_menu->prompt->text);  			head += "</b></big>";  			if (sym->name) {  				head += " ("; @@ -1117,7 +1108,7 @@ void ConfigInfoView::menuInfo(void)  		str_free(&help_gstr);  	} else if (_menu->prompt) {  		head += "<big><b>"; -		head += print_filter(_(_menu->prompt->text)); +		head += print_filter(_menu->prompt->text);  		head += "</b></big><br><br>";  		if (showDebug()) {  			if (_menu->prompt->visible.expr) { @@ -1152,7 +1143,7 @@ QString ConfigInfoView::debug_info(struct symbol *sym)  		case P_PROMPT:  		case P_MENU:  			debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu); -			debug += print_filter(_(prop->text)); +			debug += print_filter(prop->text);  			debug += "</a><br>";  			break;  		case P_DEFAULT: @@ -1234,7 +1225,7 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char  QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)  {  	QMenu* popup = Parent::createStandardContextMenu(pos); -	QAction* action = new QAction(_("Show Debug Info"), popup); +	QAction* action = new QAction("Show Debug Info", popup);  	  action->setCheckable(true);  	  connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));  	  connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool))); @@ -1261,11 +1252,11 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam  	QHBoxLayout* layout2 = new QHBoxLayout(0);  	layout2->setContentsMargins(0, 0, 0, 0);  	layout2->setSpacing(6); -	layout2->addWidget(new QLabel(_("Find:"), this)); +	layout2->addWidget(new QLabel("Find:", this));  	editField = new QLineEdit(this);  	connect(editField, SIGNAL(returnPressed()), SLOT(search()));  	layout2->addWidget(editField); -	searchButton = new QPushButton(_("Search"), this); +	searchButton = new QPushButton("Search", this);  	searchButton->setAutoDefault(false);  	connect(searchButton, SIGNAL(clicked()), SLOT(search()));  	layout2->addWidget(searchButton); @@ -1387,44 +1378,44 @@ ConfigMainWindow::ConfigMainWindow(void)  	toolBar = new QToolBar("Tools", this);  	addToolBar(toolBar); -	backAction = new QAction(QPixmap(xpm_back), _("Back"), this); +	backAction = new QAction(QPixmap(xpm_back), "Back", this);  	  connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));  	  backAction->setEnabled(false); -	QAction *quitAction = new QAction(_("&Quit"), this); +	QAction *quitAction = new QAction("&Quit", this);  	quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);  	  connect(quitAction, SIGNAL(triggered(bool)), SLOT(close())); -	QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this); +	QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);  	loadAction->setShortcut(Qt::CTRL + Qt::Key_L);  	  connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig())); -	saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this); +	saveAction = new QAction(QPixmap(xpm_save), "&Save", this);  	saveAction->setShortcut(Qt::CTRL + Qt::Key_S);  	  connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));  	conf_set_changed_callback(conf_changed);  	// Set saveAction's initial state  	conf_changed(); -	QAction *saveAsAction = new QAction(_("Save &As..."), this); +	QAction *saveAsAction = new QAction("Save &As...", this);  	  connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs())); -	QAction *searchAction = new QAction(_("&Find"), this); +	QAction *searchAction = new QAction("&Find", this);  	searchAction->setShortcut(Qt::CTRL + Qt::Key_F);  	  connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig())); -	singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this); +	singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);  	singleViewAction->setCheckable(true);  	  connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView())); -	splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this); +	splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);  	splitViewAction->setCheckable(true);  	  connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView())); -	fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this); +	fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);  	fullViewAction->setCheckable(true);  	  connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView())); -	QAction *showNameAction = new QAction(_("Show Name"), this); +	QAction *showNameAction = new QAction("Show Name", this);  	  showNameAction->setCheckable(true);  	  connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));  	  showNameAction->setChecked(configView->showName()); -	QAction *showRangeAction = new QAction(_("Show Range"), this); +	QAction *showRangeAction = new QAction("Show Range", this);  	  showRangeAction->setCheckable(true);  	  connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool))); -	QAction *showDataAction = new QAction(_("Show Data"), this); +	QAction *showDataAction = new QAction("Show Data", this);  	  showDataAction->setCheckable(true);  	  connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool))); @@ -1435,21 +1426,21 @@ ConfigMainWindow::ConfigMainWindow(void)  	connect(optGroup, SIGNAL(triggered(QAction *)), menuView,  		SLOT(setOptionMode(QAction *))); -	configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup); -	configView->showAllAction = new QAction(_("Show All Options"), optGroup); -	configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup); +	configView->showNormalAction = new QAction("Show Normal Options", optGroup); +	configView->showAllAction = new QAction("Show All Options", optGroup); +	configView->showPromptAction = new QAction("Show Prompt Options", optGroup);  	configView->showNormalAction->setCheckable(true);  	configView->showAllAction->setCheckable(true);  	configView->showPromptAction->setCheckable(true); -	QAction *showDebugAction = new QAction( _("Show Debug Info"), this); +	QAction *showDebugAction = new QAction("Show Debug Info", this);  	  showDebugAction->setCheckable(true);  	  connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));  	  showDebugAction->setChecked(helpText->showDebug()); -	QAction *showIntroAction = new QAction( _("Introduction"), this); +	QAction *showIntroAction = new QAction("Introduction", this);  	  connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro())); -	QAction *showAboutAction = new QAction( _("About"), this); +	QAction *showAboutAction = new QAction("About", this);  	  connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));  	// init tool bar @@ -1463,7 +1454,7 @@ ConfigMainWindow::ConfigMainWindow(void)  	toolBar->addAction(fullViewAction);  	// create config menu -	QMenu* config = menu->addMenu(_("&File")); +	QMenu* config = menu->addMenu("&File");  	config->addAction(loadAction);  	config->addAction(saveAction);  	config->addAction(saveAsAction); @@ -1471,11 +1462,11 @@ ConfigMainWindow::ConfigMainWindow(void)  	config->addAction(quitAction);  	// create edit menu -	QMenu* editMenu = menu->addMenu(_("&Edit")); +	QMenu* editMenu = menu->addMenu("&Edit");  	editMenu->addAction(searchAction);  	// create options menu -	QMenu* optionMenu = menu->addMenu(_("&Option")); +	QMenu* optionMenu = menu->addMenu("&Option");  	optionMenu->addAction(showNameAction);  	optionMenu->addAction(showRangeAction);  	optionMenu->addAction(showDataAction); @@ -1486,7 +1477,7 @@ ConfigMainWindow::ConfigMainWindow(void)  	// create help menu  	menu->addSeparator(); -	QMenu* helpMenu = menu->addMenu(_("&Help")); +	QMenu* helpMenu = menu->addMenu("&Help");  	helpMenu->addAction(showIntroAction);  	helpMenu->addAction(showAboutAction); @@ -1534,14 +1525,14 @@ void ConfigMainWindow::loadConfig(void)  	if (s.isNull())  		return;  	if (conf_read(QFile::encodeName(s))) -		QMessageBox::information(this, "qconf", _("Unable to load configuration!")); +		QMessageBox::information(this, "qconf", "Unable to load configuration!");  	ConfigView::updateListAll();  }  bool ConfigMainWindow::saveConfig(void)  {  	if (conf_write(NULL)) { -		QMessageBox::information(this, "qconf", _("Unable to save configuration!")); +		QMessageBox::information(this, "qconf", "Unable to save configuration!");  		return false;  	}  	return true; @@ -1723,11 +1714,11 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)  		e->accept();  		return;  	} -	QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning, +	QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,  			QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape); -	mb.setButtonText(QMessageBox::Yes, _("&Save Changes")); -	mb.setButtonText(QMessageBox::No, _("&Discard Changes")); -	mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit")); +	mb.setButtonText(QMessageBox::Yes, "&Save Changes"); +	mb.setButtonText(QMessageBox::No, "&Discard Changes"); +	mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");  	switch (mb.exec()) {  	case QMessageBox::Yes:  		if (saveConfig()) @@ -1746,7 +1737,7 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)  void ConfigMainWindow::showIntro(void)  { -	static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n" +	static const QString str = "Welcome to the qconf graphical configuration tool.\n\n"  		"For each option, a blank box indicates the feature is disabled, a check\n"  		"indicates it is enabled, and a dot indicates that it is to be compiled\n"  		"as a module.  Clicking on the box will cycle through the three states.\n\n" @@ -1756,16 +1747,16 @@ void ConfigMainWindow::showIntro(void)  		"options must be enabled to support the option you are interested in, you can\n"  		"still view the help of a grayed-out option.\n\n"  		"Toggling Show Debug Info under the Options menu will show the dependencies,\n" -		"which you can then match by examining other options.\n\n"); +		"which you can then match by examining other options.\n\n";  	QMessageBox::information(this, "qconf", str);  }  void ConfigMainWindow::showAbout(void)  { -	static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <[email protected]>.\n" +	static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <[email protected]>.\n"  		"Copyright (C) 2015 Boris Barbulovski <[email protected]>.\n\n" -		"Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n"); +		"Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";  	QMessageBox::information(this, "qconf", str);  } @@ -1826,7 +1817,7 @@ static const char *progname;  static void usage(void)  { -	printf(_("%s [-s] <config>\n").toLatin1().constData(), progname); +	printf("%s [-s] <config>\n", progname);  	exit(0);  } @@ -1835,9 +1826,6 @@ int main(int ac, char** av)  	ConfigMainWindow* v;  	const char *name; -	bindtextdomain(PACKAGE, LOCALEDIR); -	textdomain(PACKAGE); -  	progname = av[0];  	configApp = new QApplication(ac, av);  	if (ac > 1 && av[1][0] == '-') { diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index a2e83ab17de3..4686531e2f8c 100755 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -165,10 +165,10 @@ sub read_kconfig {      my $last_source = "";      # Check for any environment variables used -    while ($source =~ /\$(\w+)/ && $last_source ne $source) { +    while ($source =~ /\$\((\w+)\)/ && $last_source ne $source) {  	my $env = $1;  	$last_source = $source; -	$source =~ s/\$$env/$ENV{$env}/; +	$source =~ s/\$\($env\)/$ENV{$env}/;      }      open(my $kinfile, '<', $source) || die "Can't open $kconfig"; diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index f0b2e3b3102d..7c9a88e91cfa 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -33,33 +33,6 @@ struct symbol *sym_defconfig_list;  struct symbol *modules_sym;  tristate modules_val; -struct expr *sym_env_list; - -static void sym_add_default(struct symbol *sym, const char *def) -{ -	struct property *prop = prop_alloc(P_DEFAULT, sym); - -	prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST)); -} - -void sym_init(void) -{ -	struct symbol *sym; -	struct utsname uts; -	static bool inited = false; - -	if (inited) -		return; -	inited = true; - -	uname(&uts); - -	sym = sym_lookup("UNAME_RELEASE", 0); -	sym->type = S_STRING; -	sym->flags |= SYMBOL_AUTO; -	sym_add_default(sym, uts.release); -} -  enum symbol_type sym_get_type(struct symbol *sym)  {  	enum symbol_type type = sym->type; @@ -906,59 +879,6 @@ struct symbol *sym_find(const char *name)  	return symbol;  } -/* - * Expand symbol's names embedded in the string given in argument. Symbols' - * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to - * the empty string. - */ -char *sym_expand_string_value(const char *in) -{ -	const char *src; -	char *res; -	size_t reslen; - -	/* -	 * Note: 'in' might come from a token that's about to be -	 * freed, so make sure to always allocate a new string -	 */ -	reslen = strlen(in) + 1; -	res = xmalloc(reslen); -	res[0] = '\0'; - -	while ((src = strchr(in, '$'))) { -		char *p, name[SYMBOL_MAXLENGTH]; -		const char *symval = ""; -		struct symbol *sym; -		size_t newlen; - -		strncat(res, in, src - in); -		src++; - -		p = name; -		while (isalnum(*src) || *src == '_') -			*p++ = *src++; -		*p = '\0'; - -		sym = sym_find(name); -		if (sym != NULL) { -			sym_calc_value(sym); -			symval = sym_get_string_value(sym); -		} - -		newlen = strlen(res) + strlen(symval) + strlen(src) + 1; -		if (newlen > reslen) { -			reslen = newlen; -			res = xrealloc(res, reslen); -		} - -		strcat(res, symval); -		in = src; -	} -	strcat(res, in); - -	return res; -} -  const char *sym_escape_string_value(const char *in)  {  	const char *p; @@ -1401,32 +1321,3 @@ const char *prop_get_type_name(enum prop_type type)  	}  	return "unknown";  } - -static void prop_add_env(const char *env) -{ -	struct symbol *sym, *sym2; -	struct property *prop; -	char *p; - -	sym = current_entry->sym; -	sym->flags |= SYMBOL_AUTO; -	for_all_properties(sym, prop, P_ENV) { -		sym2 = prop_get_symbol(prop); -		if (strcmp(sym2->name, env)) -			menu_warn(current_entry, "redefining environment symbol from %s", -				  sym2->name); -		return; -	} - -	prop = prop_alloc(P_ENV, sym); -	prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST)); - -	sym_env_list = expr_alloc_one(E_LIST, sym_env_list); -	sym_env_list->right.sym = sym; - -	p = getenv(env); -	if (p) -		sym_add_default(sym, p); -	else -		menu_warn(current_entry, "environment variable %s undefined", env); -} diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config b/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config index 0d15e41da475..473228810c35 100644 --- a/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config +++ b/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config @@ -1,5 +1,5 @@  #  # Automatically generated file; DO NOT EDIT. -# Linux Kernel Configuration +# Main menu  #  # CONFIG_A is not set diff --git a/scripts/kconfig/tests/preprocess/builtin_func/Kconfig b/scripts/kconfig/tests/preprocess/builtin_func/Kconfig new file mode 100644 index 000000000000..baa328827911 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/builtin_func/Kconfig @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0 + +# 'info' prints the argument to stdout. +$(info,hello world 0) + +# 'warning-if', if the first argument is y, sends the second argument to stderr, +# and the message is prefixed with the current file name and line number. +$(warning-if,y,hello world 1) + +# 'error-if' is similar, but it terminates the parsing immediately. +# The following is just no-op since the first argument is not y. +$(error-if,n,this should not be printed) + +# Shorthand +warning = $(warning-if,y,$(1)) + +# 'shell' executes a command, and returns its stdout. +$(warning,$(shell,echo hello world 3)) + +# Every newline in the output is replaced with a space, +# but any trailing newlines are deleted. +$(warning,$(shell,printf 'hello\nworld\n\n4\n\n\n')) + +# 'filename' is expanded to the currently parsed file name, +# 'lineno' to the line number. +$(warning,filename=$(filename)) +$(warning,lineno=$(lineno)) diff --git a/scripts/kconfig/tests/preprocess/builtin_func/__init__.py b/scripts/kconfig/tests/preprocess/builtin_func/__init__.py new file mode 100644 index 000000000000..2e53ba08fca1 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/builtin_func/__init__.py @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Built-in function tests. +""" + +def test(conf): +    assert conf.oldaskconfig() == 0 +    assert conf.stdout_contains('expected_stdout') +    assert conf.stderr_matches('expected_stderr') diff --git a/scripts/kconfig/tests/preprocess/builtin_func/expected_stderr b/scripts/kconfig/tests/preprocess/builtin_func/expected_stderr new file mode 100644 index 000000000000..33ea9ca38400 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/builtin_func/expected_stderr @@ -0,0 +1,5 @@ +Kconfig:8: hello world 1 +Kconfig:18: hello world 3 +Kconfig:22: hello world  4 +Kconfig:26: filename=Kconfig +Kconfig:27: lineno=27 diff --git a/scripts/kconfig/tests/preprocess/builtin_func/expected_stdout b/scripts/kconfig/tests/preprocess/builtin_func/expected_stdout new file mode 100644 index 000000000000..82de3a7e97de --- /dev/null +++ b/scripts/kconfig/tests/preprocess/builtin_func/expected_stdout @@ -0,0 +1 @@ +hello world 0 diff --git a/scripts/kconfig/tests/preprocess/circular_expansion/Kconfig b/scripts/kconfig/tests/preprocess/circular_expansion/Kconfig new file mode 100644 index 000000000000..6838997c23ba --- /dev/null +++ b/scripts/kconfig/tests/preprocess/circular_expansion/Kconfig @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + +X = $(Y) +Y = $(X) +$(info $(X)) diff --git a/scripts/kconfig/tests/preprocess/circular_expansion/__init__.py b/scripts/kconfig/tests/preprocess/circular_expansion/__init__.py new file mode 100644 index 000000000000..419bda3e075c --- /dev/null +++ b/scripts/kconfig/tests/preprocess/circular_expansion/__init__.py @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Detect circular variable expansion. + +If a recursively expanded variable references itself (eventually), +it should fail with an error message. +""" + +def test(conf): +    assert conf.oldaskconfig() != 0 +    assert conf.stderr_matches('expected_stderr') diff --git a/scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr b/scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr new file mode 100644 index 000000000000..cde68fa989d0 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr @@ -0,0 +1 @@ +Kconfig:5: Recursive variable 'X' references itself (eventually) diff --git a/scripts/kconfig/tests/preprocess/escape/Kconfig b/scripts/kconfig/tests/preprocess/escape/Kconfig new file mode 100644 index 000000000000..4e3f44445544 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/escape/Kconfig @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Shorthand +warning = $(warning-if,y,$(1)) + +# You can not pass commas directly to a function since they are treated as +# delimiters. You can use the following trick to do so. +comma   := , +$(warning,hello$(comma) world) + +# Like Make, single quotes, double quotes, spaces are treated verbatim. +# The following prints the text as-is. +$(warning,  ' " '"   ' ''' "'") + +# Unlike Make, '$' has special meaning only when it is followed by '('. +# No need to escape '$' itself. +$(warning,$) +$(warning,$$) +$ := 1 +$(warning,$($)) + +# You need a trick to escape '$' followed by '(' +# The following should print "$(X)". It should not be expanded further. +dollar := $ +$(warning,$(dollar)(X)) + +# You need a trick to treat unbalanced parentheses. +# The following should print "(". +left_paren := ( +$(warning,$(left_paren)) + +# A simple expanded should not be expanded multiple times. +# The following should print "$(X)". It should not be expanded further. +Y := $(dollar)(X) +$(warning,$(Y)) + +# The following should print "$(X)" as well. +Y = $(dollar)(X) +$(warning,$(Y)) + +# The following should print "$(". +# It should not be emit "unterminated reference" error. +unterminated := $(dollar)( +$(warning,$(unterminated)) diff --git a/scripts/kconfig/tests/preprocess/escape/__init__.py b/scripts/kconfig/tests/preprocess/escape/__init__.py new file mode 100644 index 000000000000..7ee8e747f546 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/escape/__init__.py @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Escape sequence tests. +""" + +def test(conf): +    assert conf.oldaskconfig() == 0 +    assert conf.stderr_matches('expected_stderr') diff --git a/scripts/kconfig/tests/preprocess/escape/expected_stderr b/scripts/kconfig/tests/preprocess/escape/expected_stderr new file mode 100644 index 000000000000..1c00957ddaa9 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/escape/expected_stderr @@ -0,0 +1,10 @@ +Kconfig:9: hello, world +Kconfig:13:   ' " '"   ' ''' "'" +Kconfig:17: $ +Kconfig:18: $$ +Kconfig:20: 1 +Kconfig:25: $(X) +Kconfig:30: ( +Kconfig:35: $(X) +Kconfig:39: $(X) +Kconfig:44: $( diff --git a/scripts/kconfig/tests/preprocess/variable/Kconfig b/scripts/kconfig/tests/preprocess/variable/Kconfig new file mode 100644 index 000000000000..9ce2f95cbd24 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/variable/Kconfig @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Shorthand +warning = $(warning-if,y,$(1)) + +# Simply expanded variable. +X := 1 +SIMPLE := $(X) +X := 2 +$(warning,SIMPLE = $(SIMPLE)) + +# Recursively expanded variable. +X := 1 +RECURSIVE = $(X) +X := 2 +$(warning,RECURSIVE = $(RECURSIVE)) + +# Append something to a simply expanded variable. +Y := 3 +SIMPLE += $(Y) +Y := 4 +$(warning,SIMPLE = $(SIMPLE)) + +# Append something to a recursively expanded variable. +Y := 3 +RECURSIVE += $(Y) +Y := 4 +$(warning,RECURSIVE = $(RECURSIVE)) + +# Use += operator to an undefined variable. +# This works as a recursively expanded variable. +Y := 3 +UNDEFINED_VARIABLE += $(Y) +Y := 4 +$(warning,UNDEFINED_VARIABLE = $(UNDEFINED_VARIABLE)) + +# You can use variable references for the lefthand side of assignment statement. +X := A +Y := B +$(X)$(Y) := 5 +$(warning,AB = $(AB)) + +# User-defined function. +greeting = $(1), my name is $(2). +$(warning,$(greeting,Hello,John)) + +# The number of arguments is not checked for user-defined functions. +# If some arguments are optional, it is useful to pass fewer parameters. +# $(2) will be blank in this case. +$(warning,$(greeting,Hello)) + +# Unreferenced parameters are just ignored. +$(warning,$(greeting,Hello,John,ignored,ignored)) diff --git a/scripts/kconfig/tests/preprocess/variable/__init__.py b/scripts/kconfig/tests/preprocess/variable/__init__.py new file mode 100644 index 000000000000..e88b1708d6d4 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/variable/__init__.py @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Variable and user-defined function tests. +""" + +def test(conf): +    assert conf.oldaskconfig() == 0 +    assert conf.stderr_matches('expected_stderr') diff --git a/scripts/kconfig/tests/preprocess/variable/expected_stderr b/scripts/kconfig/tests/preprocess/variable/expected_stderr new file mode 100644 index 000000000000..a4841c3fdff5 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/variable/expected_stderr @@ -0,0 +1,9 @@ +Kconfig:10: SIMPLE = 1 +Kconfig:16: RECURSIVE = 2 +Kconfig:22: SIMPLE = 1 3 +Kconfig:28: RECURSIVE = 2 4 +Kconfig:35: UNDEFINED_VARIABLE = 4 +Kconfig:41: AB = 5 +Kconfig:45: Hello, my name is John. +Kconfig:50: Hello, my name is . +Kconfig:53: Hello, my name is John. diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c index c6f6e21b809f..a365594770d9 100644 --- a/scripts/kconfig/util.c +++ b/scripts/kconfig/util.c @@ -14,18 +14,16 @@  struct file *file_lookup(const char *name)  {  	struct file *file; -	char *file_name = sym_expand_string_value(name);  	for (file = file_list; file; file = file->next) {  		if (!strcmp(name, file->name)) { -			free(file_name);  			return file;  		}  	}  	file = xmalloc(sizeof(*file));  	memset(file, 0, sizeof(*file)); -	file->name = file_name; +	file->name = xstrdup(name);  	file->next = file_list;  	file_list = file;  	return file; @@ -34,8 +32,6 @@ struct file *file_lookup(const char *name)  /* write a dependency file as used by kbuild to track dependencies */  int file_write_dep(const char *name)  { -	struct symbol *sym, *env_sym; -	struct expr *e;  	struct file *file;  	FILE *out; @@ -54,21 +50,7 @@ int file_write_dep(const char *name)  	fprintf(out, "\n%s: \\\n"  		     "\t$(deps_config)\n\n", conf_get_autoconfig_name()); -	expr_list_for_each_sym(sym_env_list, e, sym) { -		struct property *prop; -		const char *value; - -		prop = sym_get_env_prop(sym); -		env_sym = prop_get_symbol(prop); -		if (!env_sym) -			continue; -		value = getenv(env_sym->name); -		if (!value) -			value = ""; -		fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value); -		fprintf(out, "%s: FORCE\n", conf_get_autoconfig_name()); -		fprintf(out, "endif\n"); -	} +	env_write_dep(out, conf_get_autoconfig_name());  	fprintf(out, "\n$(deps_config): ;\n");  	fclose(out); @@ -165,3 +147,14 @@ char *xstrdup(const char *s)  	fprintf(stderr, "Out of memory.\n");  	exit(1);  } + +char *xstrndup(const char *s, size_t n) +{ +	char *p; + +	p = strndup(s, n); +	if (p) +		return p; +	fprintf(stderr, "Out of memory.\n"); +	exit(1); +} diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l index 045093d827e1..25bd2b89fe3f 100644 --- a/scripts/kconfig/zconf.l +++ b/scripts/kconfig/zconf.l @@ -1,13 +1,13 @@  %option nostdinit noyywrap never-interactive full ecs  %option 8bit nodefault yylineno -%option noinput -%x COMMAND HELP STRING PARAM +%x COMMAND HELP STRING PARAM ASSIGN_VAL  %{  /*   * Copyright (C) 2002 Roman Zippel <[email protected]>   * Released under the terms of the GNU GPL v2.0.   */ +#include <assert.h>  #include <limits.h>  #include <stdio.h>  #include <stdlib.h> @@ -35,6 +35,8 @@ struct buffer *current_buf;  static int last_ts, first_ts; +static char *expand_token(const char *in, size_t n); +static void append_expanded_string(const char *in);  static void zconf_endhelp(void);  static void zconf_endfile(void); @@ -101,17 +103,28 @@ n	[A-Za-z0-9_-]  <COMMAND>{  	{n}+	{  		const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); -		BEGIN(PARAM);  		current_pos.file = current_file;  		current_pos.lineno = yylineno;  		if (id && id->flags & TF_COMMAND) { +			BEGIN(PARAM);  			yylval.id = id;  			return id->token;  		}  		alloc_string(yytext, yyleng);  		yylval.string = text; -		return T_WORD; +		return T_VARIABLE;  	} +	({n}|$)+	{ +		/* this token includes at least one '$' */ +		yylval.string = expand_token(yytext, yyleng); +		if (strlen(yylval.string)) +			return T_VARIABLE; +		free(yylval.string); +	} +	"="	{ BEGIN(ASSIGN_VAL); yylval.flavor = VAR_RECURSIVE; return T_ASSIGN; } +	":="	{ BEGIN(ASSIGN_VAL); yylval.flavor = VAR_SIMPLE; return T_ASSIGN; } +	"+="	{ BEGIN(ASSIGN_VAL); yylval.flavor = VAR_APPEND; return T_ASSIGN; } +	[[:blank:]]+  	.	warn_ignored_character(*yytext);  	\n	{  		BEGIN(INITIAL); @@ -119,6 +132,16 @@ n	[A-Za-z0-9_-]  	}  } +<ASSIGN_VAL>{ +	[^[:blank:]\n]+.*	{ +		alloc_string(yytext, yyleng); +		yylval.string = text; +		return T_ASSIGN_VAL; +	} +	\n	{ BEGIN(INITIAL); return T_EOL; } +	. +} +  <PARAM>{  	"&&"	return T_AND;  	"||"	return T_OR; @@ -147,6 +170,13 @@ n	[A-Za-z0-9_-]  		yylval.string = text;  		return T_WORD;  	} +	({n}|[/.$])+	{ +		/* this token includes at least one '$' */ +		yylval.string = expand_token(yytext, yyleng); +		if (strlen(yylval.string)) +			return T_WORD; +		free(yylval.string); +	}  	#.*	/* comment */  	\\\n	;  	[[:blank:]]+ @@ -157,12 +187,13 @@ n	[A-Za-z0-9_-]  }  <STRING>{ -	[^'"\\\n]+/\n	{ +	"$".*	append_expanded_string(yytext); +	[^$'"\\\n]+/\n	{  		append_string(yytext, yyleng);  		yylval.string = text;  		return T_WORD_QUOTE;  	} -	[^'"\\\n]+	{ +	[^$'"\\\n]+	{  		append_string(yytext, yyleng);  	}  	\\.?/\n	{ @@ -249,6 +280,58 @@ n	[A-Za-z0-9_-]  }  %% +static char *expand_token(const char *in, size_t n) +{ +	char *out; +	int c; +	char c2; +	const char *rest, *end; + +	new_string(); +	append_string(in, n); + +	/* get the whole line because we do not know the end of token. */ +	while ((c = input()) != EOF) { +		if (c == '\n') { +			unput(c); +			break; +		} +		c2 = c; +		append_string(&c2, 1); +	} + +	rest = text; +	out = expand_one_token(&rest); + +	/* push back unused characters to the input stream */ +	end = rest + strlen(rest); +	while (end > rest) +		unput(*--end); + +	free(text); + +	return out; +} + +static void append_expanded_string(const char *str) +{ +	const char *end; +	char *res; + +	str++; + +	res = expand_dollar(&str); + +	/* push back unused characters to the input stream */ +	end = str + strlen(str); +	while (end > str) +		unput(*--end); + +	append_string(res, strlen(res)); + +	free(res); +} +  void zconf_starthelp(void)  {  	new_string(); diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y index ad6305b0f40c..4b68272ebdb9 100644 --- a/scripts/kconfig/zconf.y +++ b/scripts/kconfig/zconf.y @@ -31,7 +31,7 @@ struct symbol *symbol_hash[SYMBOL_HASHSIZE];  static struct menu *current_menu, *current_entry;  %} -%expect 32 +%expect 31  %union  { @@ -41,6 +41,7 @@ static struct menu *current_menu, *current_entry;  	struct expr *expr;  	struct menu *menu;  	const struct kconf_id *id; +	enum variable_flavor flavor;  }  %token <id>T_MAINMENU @@ -77,6 +78,9 @@ static struct menu *current_menu, *current_entry;  %token T_CLOSE_PAREN  %token T_OPEN_PAREN  %token T_EOL +%token <string> T_VARIABLE +%token <flavor> T_ASSIGN +%token <string> T_ASSIGN_VAL  %left T_OR  %left T_AND @@ -92,7 +96,7 @@ static struct menu *current_menu, *current_entry;  %type <id> end  %type <id> option_name  %type <menu> if_entry menu_entry choice_entry -%type <string> symbol_option_arg word_opt +%type <string> symbol_option_arg word_opt assign_val  %destructor {  	fprintf(stderr, "%s:%d: missing end statement for this entry\n", @@ -109,7 +113,7 @@ static struct menu *current_menu, *current_entry;  %%  input: nl start | start; -start: mainmenu_stmt stmt_list | no_mainmenu_stmt stmt_list; +start: mainmenu_stmt stmt_list | stmt_list;  /* mainmenu entry */ @@ -118,19 +122,6 @@ mainmenu_stmt: T_MAINMENU prompt nl  	menu_add_prompt(P_MENU, $2, NULL);  }; -/* Default main menu, if there's no mainmenu entry */ - -no_mainmenu_stmt: /* empty */ -{ -	/* -	 * Hack: Keep the main menu title on the heap so we can safely free it -	 * later regardless of whether it comes from the 'prompt' in -	 * mainmenu_stmt or here -	 */ -	menu_add_prompt(P_MENU, xstrdup("Linux Kernel Configuration"), NULL); -}; - -  stmt_list:  	  /* empty */  	| stmt_list common_stmt @@ -156,6 +147,7 @@ common_stmt:  	| config_stmt  	| menuconfig_stmt  	| source_stmt +	| assignment_stmt  ;  option_error: @@ -345,7 +337,7 @@ choice_block:  /* if entry */ -if_entry: T_IF expr nl +if_entry: T_IF expr T_EOL  {  	printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());  	menu_add_entry(NULL); @@ -524,31 +516,42 @@ symbol:	  nonconst_symbol  word_opt: /* empty */			{ $$ = NULL; }  	| T_WORD +/* assignment statement */ + +assignment_stmt:  T_VARIABLE T_ASSIGN assign_val T_EOL	{ variable_add($1, $3, $2); free($1); free($3); } + +assign_val: +	/* empty */		{ $$ = xstrdup(""); }; +	| T_ASSIGN_VAL +; +  %%  void conf_parse(const char *name)  { -	const char *tmp;  	struct symbol *sym;  	int i;  	zconf_initscan(name); -	sym_init();  	_menu_init();  	if (getenv("ZCONF_DEBUG"))  		yydebug = 1;  	yyparse(); + +	/* Variables are expanded in the parse phase. We can free them here. */ +	variable_all_del(); +  	if (yynerrs)  		exit(1);  	if (!modules_sym)  		modules_sym = sym_find( "n" ); -	tmp = rootmenu.prompt->text; -	rootmenu.prompt->text = _(rootmenu.prompt->text); -	rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text); -	free((char*)tmp); +	if (!menu_has_prompt(&rootmenu)) { +		current_entry = &rootmenu; +		menu_add_prompt(P_MENU, "Main menu", NULL); +	}  	menu_finalize(&rootmenu);  	for_all_symbols(i, sym) { @@ -714,6 +717,10 @@ static void print_symbol(FILE *out, struct menu *menu)  			print_quoted_string(out, prop->text);  			fputc('\n', out);  			break; +		case P_SYMBOL: +			fputs( "  symbol ", out); +			fprintf(out, "%s\n", prop->sym->name); +			break;  		default:  			fprintf(out, "  unknown prop %d!\n", prop->type);  			break; @@ -780,3 +787,4 @@ void zconfdump(FILE *out)  #include "expr.c"  #include "symbol.c"  #include "menu.c" +#include "preprocess.c" diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 9045823c7be7..4bf811c09f59 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -121,10 +121,6 @@ kallsyms()  	info KSYM ${2}  	local kallsymopt; -	if [ -n "${CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX}" ]; then -		kallsymopt="${kallsymopt} --symbol-prefix=_" -	fi -  	if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then  		kallsymopt="${kallsymopt} --all-symbols"  	fi diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index 9fad6afe4c41..6667f7b491d6 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c @@ -139,6 +139,9 @@ int main(void)  	DEVID(hv_vmbus_device_id);  	DEVID_FIELD(hv_vmbus_device_id, guid); +	DEVID(rpmsg_device_id); +	DEVID_FIELD(rpmsg_device_id, name); +  	DEVID(i2c_device_id);  	DEVID_FIELD(i2c_device_id, name); diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index b9beeaa4695b..52fd54a8fe39 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -944,6 +944,17 @@ static int do_vmbus_entry(const char *filename, void *symval,  }  ADD_TO_DEVTABLE("vmbus", hv_vmbus_device_id, do_vmbus_entry); +/* Looks like: rpmsg:S */ +static int do_rpmsg_entry(const char *filename, void *symval, +			  char *alias) +{ +	DEF_FIELD_ADDR(symval, rpmsg_device_id, name); +	sprintf(alias, RPMSG_DEVICE_MODALIAS_FMT, *name); + +	return 1; +} +ADD_TO_DEVTABLE("rpmsg", rpmsg_device_id, do_rpmsg_entry); +  /* Looks like: i2c:S */  static int do_i2c_entry(const char *filename, void *symval,  			char *alias) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 4ff08a0ef5d3..1663fb19343a 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -19,9 +19,7 @@  #include <stdbool.h>  #include <errno.h>  #include "modpost.h" -#include "../../include/generated/autoconf.h"  #include "../../include/linux/license.h" -#include "../../include/linux/export.h"  /* Are we using CONFIG_MODVERSIONS? */  static int modversions = 0; @@ -123,7 +121,7 @@ void *do_nofail(void *ptr, const char *expr)  /* A list of all modules we processed */  static struct module *modules; -static struct module *find_module(char *modname) +static struct module *find_module(const char *modname)  {  	struct module *mod; @@ -591,35 +589,32 @@ static void parse_elf_finish(struct elf_info *info)  static int ignore_undef_symbol(struct elf_info *info, const char *symname)  {  	/* ignore __this_module, it will be resolved shortly */ -	if (strcmp(symname, VMLINUX_SYMBOL_STR(__this_module)) == 0) +	if (strcmp(symname, "__this_module") == 0)  		return 1;  	/* ignore global offset table */  	if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)  		return 1;  	if (info->hdr->e_machine == EM_PPC)  		/* Special register function linked on all modules during final link of .ko */ -		if (strncmp(symname, "_restgpr_", sizeof("_restgpr_") - 1) == 0 || -		    strncmp(symname, "_savegpr_", sizeof("_savegpr_") - 1) == 0 || -		    strncmp(symname, "_rest32gpr_", sizeof("_rest32gpr_") - 1) == 0 || -		    strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0 || -		    strncmp(symname, "_restvr_", sizeof("_restvr_") - 1) == 0 || -		    strncmp(symname, "_savevr_", sizeof("_savevr_") - 1) == 0) +		if (strstarts(symname, "_restgpr_") || +		    strstarts(symname, "_savegpr_") || +		    strstarts(symname, "_rest32gpr_") || +		    strstarts(symname, "_save32gpr_") || +		    strstarts(symname, "_restvr_") || +		    strstarts(symname, "_savevr_"))  			return 1;  	if (info->hdr->e_machine == EM_PPC64)  		/* Special register function linked on all modules during final link of .ko */ -		if (strncmp(symname, "_restgpr0_", sizeof("_restgpr0_") - 1) == 0 || -		    strncmp(symname, "_savegpr0_", sizeof("_savegpr0_") - 1) == 0 || -		    strncmp(symname, "_restvr_", sizeof("_restvr_") - 1) == 0 || -		    strncmp(symname, "_savevr_", sizeof("_savevr_") - 1) == 0 || +		if (strstarts(symname, "_restgpr0_") || +		    strstarts(symname, "_savegpr0_") || +		    strstarts(symname, "_restvr_") || +		    strstarts(symname, "_savevr_") ||  		    strcmp(symname, ".TOC.") == 0)  			return 1;  	/* Do not ignore this symbol */  	return 0;  } -#define CRC_PFX     VMLINUX_SYMBOL_STR(__crc_) -#define KSYMTAB_PFX VMLINUX_SYMBOL_STR(__ksymtab_) -  static void handle_modversions(struct module *mod, struct elf_info *info,  			       Elf_Sym *sym, const char *symname)  { @@ -628,13 +623,13 @@ static void handle_modversions(struct module *mod, struct elf_info *info,  	bool is_crc = false;  	if ((!is_vmlinux(mod->name) || mod->is_dot_o) && -	    strncmp(symname, "__ksymtab", 9) == 0) +	    strstarts(symname, "__ksymtab"))  		export = export_from_secname(info, get_secindex(info, sym));  	else  		export = export_from_sec(info, get_secindex(info, sym));  	/* CRC'd symbol */ -	if (strncmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { +	if (strstarts(symname, "__crc_")) {  		is_crc = true;  		crc = (unsigned int) sym->st_value;  		if (sym->st_shndx != SHN_UNDEF && sym->st_shndx != SHN_ABS) { @@ -647,13 +642,13 @@ static void handle_modversions(struct module *mod, struct elf_info *info,  				info->sechdrs[sym->st_shndx].sh_addr : 0);  			crc = *crcp;  		} -		sym_update_crc(symname + strlen(CRC_PFX), mod, crc, +		sym_update_crc(symname + strlen("__crc_"), mod, crc,  				export);  	}  	switch (sym->st_shndx) {  	case SHN_COMMON: -		if (!strncmp(symname, "__gnu_lto_", sizeof("__gnu_lto_")-1)) { +		if (strstarts(symname, "__gnu_lto_")) {  			/* Should warn here, but modpost runs before the linker */  		} else  			warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name); @@ -685,15 +680,10 @@ static void handle_modversions(struct module *mod, struct elf_info *info,  		}  #endif -#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX -		if (symname[0] != '_') -			break; -		else -			symname++; -#endif  		if (is_crc) {  			const char *e = is_vmlinux(mod->name) ?"":".ko"; -			warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n", symname + strlen(CRC_PFX), mod->name, e); +			warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n", +			     symname + strlen("__crc_"), mod->name, e);  		}  		mod->unres = alloc_symbol(symname,  					  ELF_ST_BIND(sym->st_info) == STB_WEAK, @@ -701,13 +691,13 @@ static void handle_modversions(struct module *mod, struct elf_info *info,  		break;  	default:  		/* All exported symbols */ -		if (strncmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { -			sym_add_exported(symname + strlen(KSYMTAB_PFX), mod, +		if (strstarts(symname, "__ksymtab_")) { +			sym_add_exported(symname + strlen("__ksymtab_"), mod,  					export);  		} -		if (strcmp(symname, VMLINUX_SYMBOL_STR(init_module)) == 0) +		if (strcmp(symname, "init_module") == 0)  			mod->has_init = 1; -		if (strcmp(symname, VMLINUX_SYMBOL_STR(cleanup_module)) == 0) +		if (strcmp(symname, "cleanup_module") == 0)  			mod->has_cleanup = 1;  		break;  	} @@ -734,16 +724,17 @@ static char *next_string(char *string, unsigned long *secsize)  	return string;  } -static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len, -			      const char *tag, char *info) +static char *get_next_modinfo(struct elf_info *info, const char *tag, +			      char *prev)  {  	char *p;  	unsigned int taglen = strlen(tag); -	unsigned long size = modinfo_len; +	char *modinfo = info->modinfo; +	unsigned long size = info->modinfo_len; -	if (info) { -		size -= info - (char *)modinfo; -		modinfo = next_string(info, &size); +	if (prev) { +		size -= prev - modinfo; +		modinfo = next_string(prev, &size);  	}  	for (p = modinfo; p; p = next_string(p, &size)) { @@ -753,11 +744,10 @@ static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len,  	return NULL;  } -static char *get_modinfo(void *modinfo, unsigned long modinfo_len, -			 const char *tag) +static char *get_modinfo(struct elf_info *info, const char *tag)  { -	return get_next_modinfo(modinfo, modinfo_len, tag, NULL); +	return get_next_modinfo(info, tag, NULL);  }  /** @@ -1181,13 +1171,13 @@ static int secref_whitelist(const struct sectioncheck *mismatch,  	/* Check for pattern 1 */  	if (match(tosec, init_data_sections) &&  	    match(fromsec, data_sections) && -	    (strncmp(fromsym, "__param", strlen("__param")) == 0)) +	    strstarts(fromsym, "__param"))  		return 0;  	/* Check for pattern 1a */  	if (strcmp(tosec, ".init.text") == 0 &&  	    match(fromsec, data_sections) && -	    (strncmp(fromsym, "__param_ops_", strlen("__param_ops_")) == 0)) +	    strstarts(fromsym, "__param_ops_"))  		return 0;  	/* Check for pattern 2 */ @@ -1542,8 +1532,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf,  	from = find_elf_symbol2(elf, r->r_offset, fromsec);  	fromsym = sym_name(elf, from); -	if (!strncmp(fromsym, "reference___initcall", -		     sizeof("reference___initcall")-1)) +	if (strstarts(fromsym, "reference___initcall"))  		return;  	tosec = sec_name(elf, get_secindex(elf, sym)); @@ -1940,7 +1929,7 @@ static char *remove_dot(char *s)  	return s;  } -static void read_symbols(char *modname) +static void read_symbols(const char *modname)  {  	const char *symname;  	char *version; @@ -1961,7 +1950,7 @@ static void read_symbols(char *modname)  		mod->skip = 1;  	} -	license = get_modinfo(info.modinfo, info.modinfo_len, "license"); +	license = get_modinfo(&info, "license");  	if (!license && !is_vmlinux(modname))  		warn("modpost: missing MODULE_LICENSE() in %s\n"  		     "see include/linux/module.h for " @@ -1973,8 +1962,7 @@ static void read_symbols(char *modname)  			mod->gpl_compatible = 0;  			break;  		} -		license = get_next_modinfo(info.modinfo, info.modinfo_len, -					   "license", license); +		license = get_next_modinfo(&info, "license", license);  	}  	for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { @@ -1983,11 +1971,10 @@ static void read_symbols(char *modname)  		handle_modversions(mod, &info, sym, symname);  		handle_moddevtable(mod, &info, sym, symname);  	} -	if (!is_vmlinux(modname) || -	     (is_vmlinux(modname) && vmlinux_section_warnings)) +	if (!is_vmlinux(modname) || vmlinux_section_warnings)  		check_sec_ref(mod, modname, &info); -	version = get_modinfo(info.modinfo, info.modinfo_len, "version"); +	version = get_modinfo(&info, "version");  	if (version)  		maybe_frob_rcs_version(modname, version, info.modinfo,  				       version - (char *)info.hdr); @@ -2174,9 +2161,7 @@ static void add_retpoline(struct buffer *b)  static void add_staging_flag(struct buffer *b, const char *name)  { -	static const char *staging_dir = "drivers/staging"; - -	if (strncmp(staging_dir, name, strlen(staging_dir)) == 0) +	if (strstarts(name, "drivers/staging"))  		buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");  } @@ -2230,7 +2215,7 @@ static int add_versions(struct buffer *b, struct module *mod)  			err = 1;  			break;  		} -		buf_printf(b, "\t{ %#8x, __VMLINUX_SYMBOL_STR(%s) },\n", +		buf_printf(b, "\t{ %#8x, \"%s\" },\n",  			   s->crc, s->name);  	} diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index 944418da9fe3..0f6dcb4011a8 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c @@ -330,14 +330,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md)  		goto out;  	} -	/* There will be a line like so: -		deps_drivers/net/dummy.o := \ -		  drivers/net/dummy.c \ -		    $(wildcard include/config/net/fastroute.h) \ -		  include/linux/module.h \ - -	   Sum all files in the same dir or subdirs. -	*/ +	/* Sum all files in the same dir or subdirs. */  	while ((line = get_next_line(&pos, file, flen)) != NULL) {  		char* p = line; diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index 6adb3a16ba3b..985d72d1ab34 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -71,22 +71,21 @@ if [ "$ARCH" = "um" ] ; then  	packagename=user-mode-linux-$version  fi -# Try to determine maintainer and email values -if [ -n "$DEBEMAIL" ]; then -       email=$DEBEMAIL -elif [ -n "$EMAIL" ]; then -       email=$EMAIL -else -       email=$(id -nu)@$(hostname -f 2>/dev/null || hostname) -fi -if [ -n "$DEBFULLNAME" ]; then -       name=$DEBFULLNAME -elif [ -n "$NAME" ]; then -       name=$NAME +email=${DEBEMAIL-$EMAIL} + +# use email string directly if it contains <email> +if echo $email | grep -q '<.*>'; then +	maintainer=$email  else -       name="Anonymous" +	# or construct the maintainer string +	user=${KBUILD_BUILD_USER-$(id -nu)} +	name=${DEBFULLNAME-$user} +	if [ -z "$email" ]; then +		buildhost=${KBUILD_BUILD_HOST-$(hostname -f 2>/dev/null || hostname)} +		email="$user@$buildhost" +	fi +	maintainer="$name <$email>"  fi -maintainer="$name <$email>"  # Try to determine distribution  if [ -n "$KDEB_CHANGELOG_DIST" ]; then diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index 8c9691c3329e..895c40e8679f 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -500,7 +500,7 @@ do_file(char const *const fname)  	gpfx = 0;  	switch (w2(ehdr->e_machine)) {  	default: -		fprintf(stderr, "unrecognized e_machine %d %s\n", +		fprintf(stderr, "unrecognized e_machine %u %s\n",  			w2(ehdr->e_machine), fname);  		fail_file();  		break; diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index b9897e2be404..2e7793735e14 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h @@ -441,7 +441,7 @@ static unsigned find_secsym_ndx(unsigned const txtndx,  			return symp - sym0;  		}  	} -	fprintf(stderr, "Cannot find symbol for section %d: %s.\n", +	fprintf(stderr, "Cannot find symbol for section %u: %s.\n",  		txtndx, txtname);  	fail_file();  } diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 191eb949d52c..fe06e77c15eb 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -266,13 +266,29 @@ if ($arch eq "x86_64") {      $objcopy .= " -O elf32-sh-linux";  } elsif ($arch eq "powerpc") { +    my $ldemulation; +      $local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)";      # See comment in the sparc64 section for why we use '\w'.      $function_regex = "^([0-9a-fA-F]+)\\s+<(\\.?\\w*?)>:";      $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s\\.?_mcount\$"; +    if ($endian eq "big") { +	    $cc .= " -mbig-endian "; +	    $ld .= " -EB "; +	    $ldemulation = "ppc" +    } else { +	    $cc .= " -mlittle-endian "; +	    $ld .= " -EL "; +	    $ldemulation = "lppc" +    }      if ($bits == 64) { -	$type = ".quad"; +        $type = ".quad"; +        $cc .= " -m64 "; +        $ld .= " -m elf64".$ldemulation." "; +    } else { +        $cc .= " -m32 "; +        $ld .= " -m elf32".$ldemulation." ";      }  } elsif ($arch eq "arm") { diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c index ffe8179f5d41..073fe7537f6c 100644 --- a/scripts/selinux/mdp/mdp.c +++ b/scripts/selinux/mdp/mdp.c @@ -124,7 +124,6 @@ int main(int argc, char *argv[])  	fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n");  	fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t;\n");  	fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t;\n"); -	fprintf(fout, "fs_use_xattr lustre user_u:base_r:base_t;\n");  	fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t;\n");  	fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n"); diff --git a/scripts/spdxcheck.py b/scripts/spdxcheck.py new file mode 100755 index 000000000000..7deaef297f52 --- /dev/null +++ b/scripts/spdxcheck.py @@ -0,0 +1,284 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: GPL-2.0 +# Copyright Thomas Gleixner <[email protected]> + +from argparse import ArgumentParser +from ply import lex, yacc +import traceback +import sys +import git +import re +import os + +class ParserException(Exception): +    def __init__(self, tok, txt): +        self.tok = tok +        self.txt = txt + +class SPDXException(Exception): +    def __init__(self, el, txt): +        self.el = el +        self.txt = txt + +class SPDXdata(object): +    def __init__(self): +        self.license_files = 0 +        self.exception_files = 0 +        self.licenses = [ ] +        self.exceptions = { } + +# Read the spdx data from the LICENSES directory +def read_spdxdata(repo): + +    # The subdirectories of LICENSES in the kernel source +    license_dirs = [ "preferred", "other", "exceptions" ] +    lictree = repo.heads.master.commit.tree['LICENSES'] + +    spdx = SPDXdata() + +    for d in license_dirs: +        for el in lictree[d].traverse(): +            if not os.path.isfile(el.path): +                continue + +            exception = None +            for l in open(el.path).readlines(): +                if l.startswith('Valid-License-Identifier:'): +                    lid = l.split(':')[1].strip().upper() +                    if lid in spdx.licenses: +                        raise SPDXException(el, 'Duplicate License Identifier: %s' %lid) +                    else: +                        spdx.licenses.append(lid) + +                elif l.startswith('SPDX-Exception-Identifier:'): +                    exception = l.split(':')[1].strip().upper() +                    spdx.exceptions[exception] = [] + +                elif l.startswith('SPDX-Licenses:'): +                    for lic in l.split(':')[1].upper().strip().replace(' ', '').replace('\t', '').split(','): +                        if not lic in spdx.licenses: +                            raise SPDXException(None, 'Exception %s missing license %s' %(ex, lic)) +                        spdx.exceptions[exception].append(lic) + +                elif l.startswith("License-Text:"): +                    if exception: +                        if not len(spdx.exceptions[exception]): +                            raise SPDXException(el, 'Exception %s is missing SPDX-Licenses' %excid) +                        spdx.exception_files += 1 +                    else: +                        spdx.license_files += 1 +                    break +    return spdx + +class id_parser(object): + +    reserved = [ 'AND', 'OR', 'WITH' ] +    tokens = [ 'LPAR', 'RPAR', 'ID', 'EXC' ] + reserved + +    precedence = ( ('nonassoc', 'AND', 'OR'), ) + +    t_ignore = ' \t' + +    def __init__(self, spdx): +        self.spdx = spdx +        self.lasttok = None +        self.lastid = None +        self.lexer = lex.lex(module = self, reflags = re.UNICODE) +        # Initialize the parser. No debug file and no parser rules stored on disk +        # The rules are small enough to be generated on the fly +        self.parser = yacc.yacc(module = self, write_tables = False, debug = False) +        self.lines_checked = 0 +        self.checked = 0 +        self.spdx_valid = 0 +        self.spdx_errors = 0 +        self.curline = 0 +        self.deepest = 0 + +    # Validate License and Exception IDs +    def validate(self, tok): +        id = tok.value.upper() +        if tok.type == 'ID': +            if not id in self.spdx.licenses: +                raise ParserException(tok, 'Invalid License ID') +            self.lastid = id +        elif tok.type == 'EXC': +            if not self.spdx.exceptions.has_key(id): +                raise ParserException(tok, 'Invalid Exception ID') +            if self.lastid not in self.spdx.exceptions[id]: +                raise ParserException(tok, 'Exception not valid for license %s' %self.lastid) +            self.lastid = None +        elif tok.type != 'WITH': +            self.lastid = None + +    # Lexer functions +    def t_RPAR(self, tok): +        r'\)' +        self.lasttok = tok.type +        return tok + +    def t_LPAR(self, tok): +        r'\(' +        self.lasttok = tok.type +        return tok + +    def t_ID(self, tok): +        r'[A-Za-z.0-9\-+]+' + +        if self.lasttok == 'EXC': +            print(tok) +            raise ParserException(tok, 'Missing parentheses') + +        tok.value = tok.value.strip() +        val = tok.value.upper() + +        if val in self.reserved: +            tok.type = val +        elif self.lasttok == 'WITH': +            tok.type = 'EXC' + +        self.lasttok = tok.type +        self.validate(tok) +        return tok + +    def t_error(self, tok): +        raise ParserException(tok, 'Invalid token') + +    def p_expr(self, p): +        '''expr : ID +                | ID WITH EXC +                | expr AND expr +                | expr OR expr +                | LPAR expr RPAR''' +        pass + +    def p_error(self, p): +        if not p: +            raise ParserException(None, 'Unfinished license expression') +        else: +            raise ParserException(p, 'Syntax error') + +    def parse(self, expr): +        self.lasttok = None +        self.lastid = None +        self.parser.parse(expr, lexer = self.lexer) + +    def parse_lines(self, fd, maxlines, fname): +        self.checked += 1 +        self.curline = 0 +        try: +            for line in fd: +                self.curline += 1 +                if self.curline > maxlines: +                    break +                self.lines_checked += 1 +                if line.find("SPDX-License-Identifier:") < 0: +                    continue +                expr = line.split(':')[1].replace('*/', '').strip() +                self.parse(expr) +                self.spdx_valid += 1 +                # +                # Should we check for more SPDX ids in the same file and +                # complain if there are any? +                # +                break + +        except ParserException as pe: +            if pe.tok: +                col = line.find(expr) + pe.tok.lexpos +                tok = pe.tok.value +                sys.stdout.write('%s: %d:%d %s: %s\n' %(fname, self.curline, col, pe.txt, tok)) +            else: +                sys.stdout.write('%s: %d:0 %s\n' %(fname, self.curline, col, pe.txt)) +            self.spdx_errors += 1 + +def scan_git_tree(tree): +    for el in tree.traverse(): +        # Exclude stuff which would make pointless noise +        # FIXME: Put this somewhere more sensible +        if el.path.startswith("LICENSES"): +            continue +        if el.path.find("license-rules.rst") >= 0: +            continue +        if el.path == 'scripts/checkpatch.pl': +            continue +        if not os.path.isfile(el.path): +            continue +        parser.parse_lines(open(el.path), args.maxlines, el.path) + +def scan_git_subtree(tree, path): +    for p in path.strip('/').split('/'): +        tree = tree[p] +    scan_git_tree(tree) + +if __name__ == '__main__': + +    ap = ArgumentParser(description='SPDX expression checker') +    ap.add_argument('path', nargs='*', help='Check path or file. If not given full git tree scan. For stdin use "-"') +    ap.add_argument('-m', '--maxlines', type=int, default=15, +                    help='Maximum number of lines to scan in a file. Default 15') +    ap.add_argument('-v', '--verbose', action='store_true', help='Verbose statistics output') +    args = ap.parse_args() + +    # Sanity check path arguments +    if '-' in args.path and len(args.path) > 1: +        sys.stderr.write('stdin input "-" must be the only path argument\n') +        sys.exit(1) + +    try: +        # Use git to get the valid license expressions +        repo = git.Repo(os.getcwd()) +        assert not repo.bare + +        # Initialize SPDX data +        spdx = read_spdxdata(repo) + +        # Initilize the parser +        parser = id_parser(spdx) + +    except SPDXException as se: +        if se.el: +            sys.stderr.write('%s: %s\n' %(se.el.path, se.txt)) +        else: +            sys.stderr.write('%s\n' %se.txt) +        sys.exit(1) + +    except Exception as ex: +        sys.stderr.write('FAIL: %s\n' %ex) +        sys.stderr.write('%s\n' %traceback.format_exc()) +        sys.exit(1) + +    try: +        if len(args.path) and args.path[0] == '-': +            parser.parse_lines(sys.stdin, args.maxlines, '-') +        else: +            if args.path: +                for p in args.path: +                    if os.path.isfile(p): +                        parser.parse_lines(open(p), args.maxlines, p) +                    elif os.path.isdir(p): +                        scan_git_subtree(repo.head.reference.commit.tree, p) +                    else: +                        sys.stderr.write('path %s does not exist\n' %p) +                        sys.exit(1) +            else: +                # Full git tree scan +                scan_git_tree(repo.head.commit.tree) + +            if args.verbose: +                sys.stderr.write('\n') +                sys.stderr.write('License files:     %12d\n' %spdx.license_files) +                sys.stderr.write('Exception files:   %12d\n' %spdx.exception_files) +                sys.stderr.write('License IDs        %12d\n' %len(spdx.licenses)) +                sys.stderr.write('Exception IDs      %12d\n' %len(spdx.exceptions)) +                sys.stderr.write('\n') +                sys.stderr.write('Files checked:     %12d\n' %parser.checked) +                sys.stderr.write('Lines checked:     %12d\n' %parser.lines_checked) +                sys.stderr.write('Files with SPDX:   %12d\n' %parser.spdx_valid) +                sys.stderr.write('Files with errors: %12d\n' %parser.spdx_errors) + +            sys.exit(0) + +    except Exception as ex: +        sys.stderr.write('FAIL: %s\n' %ex) +        sys.stderr.write('%s\n' %traceback.format_exc()) +        sys.exit(1) diff --git a/scripts/split-man.pl b/scripts/split-man.pl index bfe16cbe42df..c3db607ee9ec 100755 --- a/scripts/split-man.pl +++ b/scripts/split-man.pl @@ -1,7 +1,7 @@  #!/usr/bin/perl  # SPDX-License-Identifier: GPL-2.0  # -# Author: Mauro Carvalho Chehab <[email protected]> +# Author: Mauro Carvalho Chehab <[email protected]>  #  # Produce manpages from kernel-doc.  # See Documentation/doc-guide/kernel-doc.rst for instructions diff --git a/scripts/tags.sh b/scripts/tags.sh index 78e546ff689c..66f08bb1cce9 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -28,20 +28,11 @@ fi  # ignore userspace tools  ignore="$ignore ( -path ${tree}tools ) -prune -o" -# Find all available archs -find_all_archs() -{ -	ALLSOURCE_ARCHS="" -	for arch in `ls ${tree}arch`; do -		ALLSOURCE_ARCHS="${ALLSOURCE_ARCHS} "${arch##\/} -	done -} -  # Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH  if [ "${ALLSOURCE_ARCHS}" = "" ]; then  	ALLSOURCE_ARCHS=${SRCARCH}  elif [ "${ALLSOURCE_ARCHS}" = "all" ]; then -	find_all_archs +	ALLSOURCE_ARCHS=$(find ${tree}arch/ -mindepth 1 -maxdepth 1 -type d -printf '%f ')  fi  # find sources in arch/$ARCH @@ -188,9 +179,9 @@ regex_c=(  	'/\<CLEARPAGEFLAG_NOOP(\([[:alnum:]_]*\).*/ClearPage\1/'  	'/\<__CLEARPAGEFLAG_NOOP(\([[:alnum:]_]*\).*/__ClearPage\1/'  	'/\<TESTCLEARFLAG_FALSE(\([[:alnum:]_]*\).*/TestClearPage\1/' -	'/^PAGE_MAPCOUNT_OPS(\([[:alnum:]_]*\).*/Page\1/' -	'/^PAGE_MAPCOUNT_OPS(\([[:alnum:]_]*\).*/__SetPage\1/' -	'/^PAGE_MAPCOUNT_OPS(\([[:alnum:]_]*\).*/__ClearPage\1/' +	'/^PAGE_TYPE_OPS(\([[:alnum:]_]*\).*/Page\1/' +	'/^PAGE_TYPE_OPS(\([[:alnum:]_]*\).*/__SetPage\1/' +	'/^PAGE_TYPE_OPS(\([[:alnum:]_]*\).*/__ClearPage\1/'  	'/^TASK_PFA_TEST([^,]*, *\([[:alnum:]_]*\))/task_\1/'  	'/^TASK_PFA_SET([^,]*, *\([[:alnum:]_]*\))/task_set_\1/'  	'/^TASK_PFA_CLEAR([^,]*, *\([[:alnum:]_]*\))/task_clear_\1/' diff --git a/scripts/ver_linux b/scripts/ver_linux index 545ec7388eb7..7227994ccf63 100755 --- a/scripts/ver_linux +++ b/scripts/ver_linux @@ -13,36 +13,34 @@ BEGIN {  	system("uname -a")  	printf("\n") -	printversion("GNU C", version("gcc -dumpversion 2>&1")) -	printversion("GNU Make", version("make --version 2>&1")) -	printversion("Binutils", version("ld -v 2>&1")) -	printversion("Util-linux", version("mount --version 2>&1")) -	printversion("Mount", version("mount --version 2>&1")) -	printversion("Module-init-tools", version("depmod -V  2>&1")) -	printversion("E2fsprogs", version("tune2fs 2>&1")) -	printversion("Jfsutils", version("fsck.jfs -V 2>&1")) -	printversion("Reiserfsprogs", version("reiserfsck -V 2>&1")) -	printversion("Reiser4fsprogs", version("fsck.reiser4 -V 2>&1")) -	printversion("Xfsprogs", version("xfs_db -V 2>&1")) -	printversion("Pcmciautils", version("pccardctl -V 2>&1")) -	printversion("Pcmcia-cs", version("cardmgr -V 2>&1")) -	printversion("Quota-tools", version("quota -V 2>&1")) -	printversion("PPP", version("pppd --version 2>&1")) -	printversion("Isdn4k-utils", version("isdnctrl 2>&1")) -	printversion("Nfs-utils", version("showmount --version 2>&1")) +	printversion("GNU C", version("gcc -dumpversion")) +	printversion("GNU Make", version("make --version")) +	printversion("Binutils", version("ld -v")) +	printversion("Util-linux", version("mount --version")) +	printversion("Mount", version("mount --version")) +	printversion("Module-init-tools", version("depmod -V")) +	printversion("E2fsprogs", version("tune2fs")) +	printversion("Jfsutils", version("fsck.jfs -V")) +	printversion("Reiserfsprogs", version("reiserfsck -V")) +	printversion("Reiser4fsprogs", version("fsck.reiser4 -V")) +	printversion("Xfsprogs", version("xfs_db -V")) +	printversion("Pcmciautils", version("pccardctl -V")) +	printversion("Pcmcia-cs", version("cardmgr -V")) +	printversion("Quota-tools", version("quota -V")) +	printversion("PPP", version("pppd --version")) +	printversion("Isdn4k-utils", version("isdnctrl")) +	printversion("Nfs-utils", version("showmount --version")) -	if (system("test -r /proc/self/maps") == 0) { -		while (getline <"/proc/self/maps" > 0) { -			n = split($0, procmaps, "/") -			if (/libc.*so$/ && match(procmaps[n], /[0-9]+([.]?[0-9]+)+/)) { -				ver = substr(procmaps[n], RSTART, RLENGTH) -				printversion("Linux C Library", ver) -				break -			} +	while (getline <"/proc/self/maps" > 0) { +		n = split($0, procmaps, "/") +		if (/libc.*so$/ && match(procmaps[n], /[0-9]+([.]?[0-9]+)+/)) { +			ver = substr(procmaps[n], RSTART, RLENGTH) +			printversion("Linux C Library", ver) +			break  		}  	} -	printversion("Dynamic linker (ldd)", version("ldd --version 2>&1")) +	printversion("Dynamic linker (ldd)", version("ldd --version"))  	while ("ldconfig -p 2>/dev/null" | getline > 0) {  		if (/(libg|stdc)[+]+\.so/) { @@ -50,28 +48,25 @@ BEGIN {  			break  		}  	} -	if (system("test -r " libcpp) == 0) -		printversion("Linux C++ Library", version("readlink " libcpp)) - -	printversion("Procps", version("ps --version 2>&1")) -	printversion("Net-tools", version("ifconfig --version 2>&1")) -	printversion("Kbd", version("loadkeys -V 2>&1")) -	printversion("Console-tools", version("loadkeys -V 2>&1")) -	printversion("Oprofile", version("oprofiled --version 2>&1")) -	printversion("Sh-utils", version("expr --v 2>&1")) -	printversion("Udev", version("udevadm --version 2>&1")) -	printversion("Wireless-tools", version("iwconfig --version 2>&1")) +	printversion("Linux C++ Library", version("readlink " libcpp)) +	printversion("Procps", version("ps --version")) +	printversion("Net-tools", version("ifconfig --version")) +	printversion("Kbd", version("loadkeys -V")) +	printversion("Console-tools", version("loadkeys -V")) +	printversion("Oprofile", version("oprofiled --version")) +	printversion("Sh-utils", version("expr --v")) +	printversion("Udev", version("udevadm --version")) +	printversion("Wireless-tools", version("iwconfig --version")) -	if (system("test -r /proc/modules") == 0) { -		while ("sort /proc/modules" | getline > 0) { -			mods = mods sep $1 -			sep = " " -		} -		printversion("Modules Loaded", mods) +	while ("sort /proc/modules" | getline > 0) { +		mods = mods sep $1 +		sep = " "  	} +	printversion("Modules Loaded", mods)  }  function version(cmd,    ver) { +	cmd = cmd " 2>&1"  	while (cmd | getline > 0) {  		if (!/ver_linux/ && match($0, /[0-9]+([.]?[0-9]+)+/)) {  			ver = substr($0, RSTART, RLENGTH) |