Bump buildroot to version 2018.02.8

This commit is contained in:
2018-12-05 23:24:57 +01:00
parent 32918ded24
commit 5598b1b762
238 changed files with 6567 additions and 2450 deletions

View File

@@ -0,0 +1,16 @@
# See utils/checkpackagelib/readme.txt before editing this file.
class _CheckFunction(object):
def __init__(self, filename, url_to_manual):
self.filename = filename
self.url_to_manual = url_to_manual
def before(self):
pass
def check_line(self, lineno, text):
pass
def after(self):
pass

View File

@@ -0,0 +1,54 @@
# See utils/checkpackagelib/readme.txt before editing this file.
from base import _CheckFunction
class ConsecutiveEmptyLines(_CheckFunction):
def before(self):
self.lastline = "non empty"
def check_line(self, lineno, text):
if text.strip() == "" == self.lastline.strip():
return ["{}:{}: consecutive empty lines"
.format(self.filename, lineno)]
self.lastline = text
class EmptyLastLine(_CheckFunction):
def before(self):
self.lastlineno = 0
self.lastline = "non empty"
def check_line(self, lineno, text):
self.lastlineno = lineno
self.lastline = text
def after(self):
if self.lastline.strip() == "":
return ["{}:{}: empty line at end of file"
.format(self.filename, self.lastlineno)]
class NewlineAtEof(_CheckFunction):
def before(self):
self.lastlineno = 0
self.lastline = "\n"
def check_line(self, lineno, text):
self.lastlineno = lineno
self.lastline = text
def after(self):
if self.lastline == self.lastline.rstrip("\r\n"):
return ["{}:{}: missing newline at end of file"
.format(self.filename, self.lastlineno),
self.lastline]
class TrailingSpace(_CheckFunction):
def check_line(self, lineno, text):
line = text.rstrip("\r\n")
if line != line.rstrip():
return ["{}:{}: line contains trailing whitespace"
.format(self.filename, lineno),
text]

View File

@@ -0,0 +1,137 @@
# See utils/checkpackagelib/readme.txt before editing this file.
# Kconfig generates errors if someone introduces a typo like "boool" instead of
# "bool", so below check functions don't need to check for things already
# checked by running "make menuconfig".
import re
from base import _CheckFunction
from lib import ConsecutiveEmptyLines # noqa: F401
from lib import EmptyLastLine # noqa: F401
from lib import NewlineAtEof # noqa: F401
from lib import TrailingSpace # noqa: F401
def _empty_or_comment(text):
line = text.strip()
# ignore empty lines and comment lines indented or not
return line == "" or line.startswith("#")
def _part_of_help_text(text):
return text.startswith("\t ")
# used in more than one check
entries_that_should_not_be_indented = [
"choice", "comment", "config", "endchoice", "endif", "endmenu", "if",
"menu", "menuconfig", "source"]
class AttributesOrder(_CheckFunction):
attributes_order_convention = {
"bool": 1, "prompt": 1, "string": 1, "default": 2, "depends": 3,
"select": 4, "help": 5}
def before(self):
self.state = 0
def check_line(self, lineno, text):
if _empty_or_comment(text) or _part_of_help_text(text):
return
attribute = text.split()[0]
if attribute in entries_that_should_not_be_indented:
self.state = 0
return
if attribute not in self.attributes_order_convention.keys():
return
new_state = self.attributes_order_convention[attribute]
wrong_order = self.state > new_state
# save to process next line
self.state = new_state
if wrong_order:
return ["{}:{}: attributes order: type, default, depends on,"
" select, help ({}#_config_files)"
.format(self.filename, lineno, self.url_to_manual),
text]
class HelpText(_CheckFunction):
HELP_TEXT_FORMAT = re.compile("^\t .{,62}$")
URL_ONLY = re.compile("^(http|https|git)://\S*$")
def before(self):
self.help_text = False
def check_line(self, lineno, text):
if _empty_or_comment(text):
return
entry = text.split()[0]
if entry in entries_that_should_not_be_indented:
self.help_text = False
return
if text.strip() == "help":
self.help_text = True
return
if not self.help_text:
return
if self.HELP_TEXT_FORMAT.match(text.rstrip()):
return
if self.URL_ONLY.match(text.strip()):
return
return ["{}:{}: help text: <tab><2 spaces><62 chars>"
" ({}#writing-rules-config-in)"
.format(self.filename, lineno, self.url_to_manual),
text,
"\t " + "123456789 " * 6 + "12"]
class Indent(_CheckFunction):
ENDS_WITH_BACKSLASH = re.compile(r"^[^#].*\\$")
entries_that_should_be_indented = [
"bool", "default", "depends", "help", "prompt", "select", "string"]
def before(self):
self.backslash = False
def check_line(self, lineno, text):
if _empty_or_comment(text) or _part_of_help_text(text):
self.backslash = False
return
entry = text.split()[0]
last_line_ends_in_backslash = self.backslash
# calculate for next line
if self.ENDS_WITH_BACKSLASH.search(text):
self.backslash = True
else:
self.backslash = False
if last_line_ends_in_backslash:
if text.startswith("\t"):
return
return ["{}:{}: continuation line should be indented using tabs"
.format(self.filename, lineno),
text]
if entry in self.entries_that_should_be_indented:
if not text.startswith("\t{}".format(entry)):
return ["{}:{}: should be indented with one tab"
" ({}#_config_files)"
.format(self.filename, lineno, self.url_to_manual),
text]
elif entry in entries_that_should_not_be_indented:
if not text.startswith(entry):
return ["{}:{}: should not be indented"
.format(self.filename, lineno),
text]

View File

@@ -0,0 +1,55 @@
# See utils/checkpackagelib/readme.txt before editing this file.
# The validity of the hashes itself is checked when building, so below check
# functions don't need to check for things already checked by running
# "make package-dirclean package-source".
import re
from base import _CheckFunction
from lib import ConsecutiveEmptyLines # noqa: F401
from lib import EmptyLastLine # noqa: F401
from lib import NewlineAtEof # noqa: F401
from lib import TrailingSpace # noqa: F401
def _empty_line_or_comment(text):
return text.strip() == "" or text.startswith("#")
class HashNumberOfFields(_CheckFunction):
def check_line(self, lineno, text):
if _empty_line_or_comment(text):
return
fields = text.split()
if len(fields) != 3:
return ["{}:{}: expected three fields ({}#adding-packages-hash)"
.format(self.filename, lineno, self.url_to_manual),
text]
class HashType(_CheckFunction):
len_of_hash = {"md5": 32, "sha1": 40, "sha224": 56, "sha256": 64,
"sha384": 96, "sha512": 128}
def check_line(self, lineno, text):
if _empty_line_or_comment(text):
return
fields = text.split()
if len(fields) < 2:
return
htype, hexa = fields[:2]
if htype == "none":
return
if htype not in self.len_of_hash.keys():
return ["{}:{}: unexpected type of hash ({}#adding-packages-hash)"
.format(self.filename, lineno, self.url_to_manual),
text]
if not re.match("^[0-9A-Fa-f]{%s}$" % self.len_of_hash[htype], hexa):
return ["{}:{}: hash size does not match type "
"({}#adding-packages-hash)"
.format(self.filename, lineno, self.url_to_manual),
text,
"expected {} hex digits".format(self.len_of_hash[htype])]

View File

@@ -0,0 +1,246 @@
# See utils/checkpackagelib/readme.txt before editing this file.
# There are already dependency checks during the build, so below check
# functions don't need to check for things already checked by exploring the
# menu options using "make menuconfig" and by running "make" with appropriate
# packages enabled.
import re
from base import _CheckFunction
from lib import ConsecutiveEmptyLines # noqa: F401
from lib import EmptyLastLine # noqa: F401
from lib import NewlineAtEof # noqa: F401
from lib import TrailingSpace # noqa: F401
class Indent(_CheckFunction):
COMMENT = re.compile("^\s*#")
CONDITIONAL = re.compile("^\s*(ifeq|ifneq|endif)\s")
ENDS_WITH_BACKSLASH = re.compile(r"^[^#].*\\$")
END_DEFINE = re.compile("^\s*endef\s")
MAKEFILE_TARGET = re.compile("^[^# \t]+:\s")
START_DEFINE = re.compile("^\s*define\s")
def before(self):
self.define = False
self.backslash = False
self.makefile_target = False
def check_line(self, lineno, text):
if self.START_DEFINE.search(text):
self.define = True
return
if self.END_DEFINE.search(text):
self.define = False
return
expect_tabs = False
if self.define or self.backslash or self.makefile_target:
expect_tabs = True
if self.CONDITIONAL.search(text):
expect_tabs = False
# calculate for next line
if self.ENDS_WITH_BACKSLASH.search(text):
self.backslash = True
else:
self.backslash = False
if self.MAKEFILE_TARGET.search(text):
self.makefile_target = True
return
if text.strip() == "":
self.makefile_target = False
return
# comment can be indented or not inside define ... endef, so ignore it
if self.define and self.COMMENT.search(text):
return
if expect_tabs:
if not text.startswith("\t"):
return ["{}:{}: expected indent with tabs"
.format(self.filename, lineno),
text]
else:
if text.startswith("\t"):
return ["{}:{}: unexpected indent with tabs"
.format(self.filename, lineno),
text]
class PackageHeader(_CheckFunction):
def before(self):
self.skip = False
def check_line(self, lineno, text):
if self.skip or lineno > 6:
return
if lineno in [1, 5]:
if lineno == 1 and text.startswith("include "):
self.skip = True
return
if text.rstrip() != "#" * 80:
return ["{}:{}: should be 80 hashes ({}#writing-rules-mk)"
.format(self.filename, lineno, self.url_to_manual),
text,
"#" * 80]
elif lineno in [2, 4]:
if text.rstrip() != "#":
return ["{}:{}: should be 1 hash ({}#writing-rules-mk)"
.format(self.filename, lineno, self.url_to_manual),
text]
elif lineno == 6:
if text.rstrip() != "":
return ["{}:{}: should be a blank line ({}#writing-rules-mk)"
.format(self.filename, lineno, self.url_to_manual),
text]
class RemoveDefaultPackageSourceVariable(_CheckFunction):
packages_that_may_contain_default_source = ["binutils", "gcc", "gdb"]
PACKAGE_NAME = re.compile("/([^/]+)\.mk")
def before(self):
package = self.PACKAGE_NAME.search(self.filename).group(1)
package_upper = package.replace("-", "_").upper()
self.package = package
self.FIND_SOURCE = re.compile(
"^{}_SOURCE\s*=\s*{}-\$\({}_VERSION\)\.tar\.gz"
.format(package_upper, package, package_upper))
def check_line(self, lineno, text):
if self.FIND_SOURCE.search(text):
if self.package in self.packages_that_may_contain_default_source:
return
return ["{}:{}: remove default value of _SOURCE variable "
"({}#generic-package-reference)"
.format(self.filename, lineno, self.url_to_manual),
text]
class SpaceBeforeBackslash(_CheckFunction):
TAB_OR_MULTIPLE_SPACES_BEFORE_BACKSLASH = re.compile(r"^.*( |\t)\\$")
def check_line(self, lineno, text):
if self.TAB_OR_MULTIPLE_SPACES_BEFORE_BACKSLASH.match(text.rstrip()):
return ["{}:{}: use only one space before backslash"
.format(self.filename, lineno),
text]
class TrailingBackslash(_CheckFunction):
ENDS_WITH_BACKSLASH = re.compile(r"^[^#].*\\$")
def before(self):
self.backslash = False
def check_line(self, lineno, text):
last_line_ends_in_backslash = self.backslash
# calculate for next line
if self.ENDS_WITH_BACKSLASH.search(text):
self.backslash = True
self.lastline = text
return
self.backslash = False
if last_line_ends_in_backslash and text.strip() == "":
return ["{}:{}: remove trailing backslash"
.format(self.filename, lineno - 1),
self.lastline]
class TypoInPackageVariable(_CheckFunction):
ALLOWED = re.compile("|".join([
"ACLOCAL_DIR",
"ACLOCAL_HOST_DIR",
"BR_CCACHE_INITIAL_SETUP",
"BR_NO_CHECK_HASH_FOR",
"LINUX_POST_PATCH_HOOKS",
"LINUX_TOOLS",
"LUA_RUN",
"MKFS_JFFS2",
"MKIMAGE_ARCH",
"PKG_CONFIG_HOST_BINARY",
"TARGET_FINALIZE_HOOKS",
"XTENSA_CORE_NAME"]))
PACKAGE_NAME = re.compile("/([^/]+)\.mk")
VARIABLE = re.compile("^([A-Z0-9_]+_[A-Z0-9_]+)\s*(\+|)=")
def before(self):
package = self.PACKAGE_NAME.search(self.filename).group(1)
package = package.replace("-", "_").upper()
# linux tools do not use LINUX_TOOL_ prefix for variables
package = package.replace("LINUX_TOOL_", "")
self.package = package
self.REGEX = re.compile("^(HOST_)?({}_[A-Z0-9_]+)".format(package))
self.FIND_VIRTUAL = re.compile(
"^{}_PROVIDES\s*(\+|)=\s*(.*)".format(package))
self.virtual = []
def check_line(self, lineno, text):
m = self.VARIABLE.search(text)
if m is None:
return
variable = m.group(1)
# allow to set variables for virtual package this package provides
v = self.FIND_VIRTUAL.search(text)
if v:
self.virtual += v.group(2).upper().split()
return
for virtual in self.virtual:
if variable.startswith("{}_".format(virtual)):
return
if self.ALLOWED.match(variable):
return
if self.REGEX.search(text) is None:
return ["{}:{}: possible typo: {} -> *{}*"
.format(self.filename, lineno, variable, self.package),
text]
class UselessFlag(_CheckFunction):
DEFAULT_AUTOTOOLS_FLAG = re.compile("^.*{}".format("|".join([
"_AUTORECONF\s*=\s*NO",
"_LIBTOOL_PATCH\s*=\s*YES"])))
DEFAULT_GENERIC_FLAG = re.compile("^.*{}".format("|".join([
"_INSTALL_IMAGES\s*=\s*NO",
"_INSTALL_REDISTRIBUTE\s*=\s*YES",
"_INSTALL_STAGING\s*=\s*NO",
"_INSTALL_TARGET\s*=\s*YES"])))
END_CONDITIONAL = re.compile("^\s*(endif)")
START_CONDITIONAL = re.compile("^\s*(ifeq|ifneq)")
def before(self):
self.conditional = 0
def check_line(self, lineno, text):
if self.START_CONDITIONAL.search(text):
self.conditional += 1
return
if self.END_CONDITIONAL.search(text):
self.conditional -= 1
return
# allow non-default conditionally overridden by default
if self.conditional > 0:
return
if self.DEFAULT_GENERIC_FLAG.search(text):
return ["{}:{}: useless default value ({}#"
"_infrastructure_for_packages_with_specific_build_systems)"
.format(self.filename, lineno, self.url_to_manual),
text]
if self.DEFAULT_AUTOTOOLS_FLAG.search(text) and not text.lstrip().startswith("HOST_"):
return ["{}:{}: useless default value "
"({}#_infrastructure_for_autotools_based_packages)"
.format(self.filename, lineno, self.url_to_manual),
text]

View File

@@ -0,0 +1,61 @@
# See utils/checkpackagelib/readme.txt before editing this file.
# The format of the patch files is tested during the build, so below check
# functions don't need to check for things already checked by running
# "make package-dirclean package-patch".
import re
from base import _CheckFunction
from lib import NewlineAtEof # noqa: F401
class ApplyOrder(_CheckFunction):
APPLY_ORDER = re.compile("/\d{1,4}-[^/]*$")
def before(self):
if not self.APPLY_ORDER.search(self.filename):
return ["{}:0: use name <number>-<description>.patch "
"({}#_providing_patches)"
.format(self.filename, self.url_to_manual)]
class NumberedSubject(_CheckFunction):
NUMBERED_PATCH = re.compile("Subject:\s*\[PATCH\s*\d+/\d+\]")
def before(self):
self.git_patch = False
self.lineno = 0
self.text = None
def check_line(self, lineno, text):
if text.startswith("diff --git"):
self.git_patch = True
return
if self.NUMBERED_PATCH.search(text):
self.lineno = lineno
self.text = text
def after(self):
if self.git_patch and self.text:
return ["{}:{}: generate your patches with 'git format-patch -N'"
.format(self.filename, self.lineno),
self.text]
class Sob(_CheckFunction):
SOB_ENTRY = re.compile("^Signed-off-by: .*$")
def before(self):
self.found = False
def check_line(self, lineno, text):
if self.found:
return
if self.SOB_ENTRY.search(text):
self.found = True
def after(self):
if not self.found:
return ["{}:0: missing Signed-off-by in the header "
"({}#_format_and_licensing_of_the_package_patches)"
.format(self.filename, self.url_to_manual)]

View File

@@ -0,0 +1,73 @@
How the scripts are structured:
- check-package is the main engine, called by the user.
For each input file, this script decides which parser should be used and it
collects all classes declared in the library file and instantiates them.
The main engine opens the input files and it serves each raw line (including
newline!) to the method check_line() of every check object.
Two special methods before() and after() are used to call the initialization
of variables (for the case it needs to keep data across calls) and the
equivalent finalization (e.g. for the case a warning must be issued if some
pattern is not in the input file).
- base.py contains the base class for all check functions.
- lib.py contains the classes for common check functions.
Each check function is explicitly included in a given type-parsing library.
Do not include every single check function in this file, a class that will
only parse hash files should be implemented in the hash-parsing library.
When a warning must be issued, the check function returns an array of strings.
Each string is a warning message and is displayed if the corresponding verbose
level is active. When the script is called without --verbose only the first
warning in the returned array is printed; when called with --verbose both
first and second warnings are printed; when called with -vv until the third
warning is printed; an so on.
Helper functions can be defined and will not be called by the main script.
- lib_type.py contains check functions specific to files of this type.
Some hints when changing this code:
- prefer O(n) algorithms, where n is the total number of lines in the files
processed.
- when there is no other reason for ordering, use alphabetical order (e.g. keep
the check functions in alphabetical order, keep the imports in alphabetical
order, and so on).
- keep in mind that for every class the method before() will be called before
any line is served to be checked by the method check_line(). A class that
checks the filename should only implement the method before(). A function that
needs to keep data across calls (e.g. keep the last line before the one being
processed) should initialize all variables using this method.
- keep in mind that for every class the method after() will be called after all
lines were served to be checked by the method check_line(). A class that
checks the absence of a pattern in the file will need to use this method.
- try to avoid false warnings. It's better to not issue a warning message to a
corner case than have too many false warnings. The second can make users stop
using the script.
- do not check spacing in the input line in every single function. Trailing
whitespace and wrong indentation should be checked by separate functions.
- avoid duplicate tests. Try to test only one thing in each function.
- in the warning message, include the url to a section from the manual, when
applicable. It potentially will make more people know the manual.
- use short sentences in the warning messages. A complete explanation can be
added to show when --verbose is used.
- when testing, verify the error message is displayed when the error pattern is
found, but also verify the error message is not displayed for few
well-formatted packages... there are many of these, just pick your favorite
as golden package that should not trigger any warning message.
- check the url displayed by the warning message works.
Usage examples:
- to get a list of check functions that would be called without actually
calling them you can use the --dry-run option:
$ utils/check-package --dry-run package/yourfavorite/*
- when you just added a new check function, e.g. Something, check how it behaves
for all current packages:
$ utils/check-package --include-only Something $(find package -type f)
- the effective processing time (when the .pyc were already generated and all
files to be processed are cached in the RAM) should stay in the order of few
seconds:
$ utils/check-package $(find package -type f) >/dev/null ; \
time utils/check-package $(find package -type f) >/dev/null
- vim users can navigate the warnings (most editors probably have similar
function) since warnings are generated in the form 'path/file:line: warning':
$ find package/ -name 'Config.*' > filelist && vim -c \
'set makeprg=utils/check-package\ $(cat\ filelist)' -c make -c copen