From e1cd55070dd9484cf5a2b486f4281cac8c784ecf Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Wed, 21 May 2008 15:48:02 +0000 Subject: [PATCH] Patch from Bart Van Assche : The patch below contains a script that removes C preprocessor tests on the LINUX_VERSION_CODE macro, depending on the kernel version that was passed as an argument to that script. Furthermore, the generate-kernel-patch script has been modified such that its output is filtered by the specialize-patch script. This eliminates another class of checkpatch errors. Note: due to the way the specialize-patch script is implemented, #if 0 and #if 1 statements are also processed. The patch below has been verified as follows: - Checked that checkpatch does no longer complain about LINUX_VERSION_CODE on the generated patch. - Checked that the generated kernel patch applies cleanly to the 2.6.25.4 kernel. - Checked that the patched kernel compiles and installs cleanly, and that after reboot it was possible to load the iscsi-scst and ib_srpt kernel modules. I will wait with sending more patches until this and the previous two patches have been reviewed and/or applied. Signed-off-by: Bart Van Assche git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@384 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scripts/generate-kernel-patch | 10 ++ scripts/specialize-patch | 168 ++++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100755 scripts/specialize-patch diff --git a/scripts/generate-kernel-patch b/scripts/generate-kernel-patch index 76a6a5c55..c0343f8d5 100755 --- a/scripts/generate-kernel-patch +++ b/scripts/generate-kernel-patch @@ -103,6 +103,16 @@ do done +# Redirect the output of all subsequent commands to the specialize-patch script + +trap "rm -f ${fifo}" EXIT +fifo=/tmp/generate-kernel-patch-fifo.$$ +rm -f "${fifo}" +mkfifo "${fifo}" +"$(dirname $0)/specialize-patch" -v kernel_version="${kernel_version}" \ + < "${fifo}" & +exec >"${fifo}" + # General kernel patches. cat "${kpatch[@]}" diff --git a/scripts/specialize-patch b/scripts/specialize-patch new file mode 100755 index 000000000..d9b3ee31d --- /dev/null +++ b/scripts/specialize-patch @@ -0,0 +1,168 @@ +#!/usr/bin/gawk -f + +############################################################################ +# +# Script that removes preprocessor checks on the kernel version. Somewhat +# related to the v4l-scripts-gentree.pl script. +# +# Copyright (C) 2008 Bart Van Assche +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, version 2 +# of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +############################################################################ + +# Usage: +# * Specify the kernel version code as follows: -v kernel_version=... +# * Provide the patch to be processed to stdin. +# +# The output of this script will be a patch that is specialized for the +# specified kernel version. + + +# Convert a kernel version in the x.y.z format into numeric form, just like +# the KERNEL_VERSION() macro. + +function version_code(kver) { + match(kver, "([0-9]+).([0-9]+).([0-9]+)", array) + return 65536*array[1] + 256*array[2] + array[3] +} + + +# Evaluate a preprocessor statement via repeated substitutions. +# Mathematicians call this 'term rewriting'. + +function evaluate(stmnt) { + gsub(" *\\/\\*[^*]*\\*\\/ *", "", stmnt) + + gsub("^+ *#", "+#", stmnt) + + gsub("LINUX_VERSION_CODE", LINUX_VERSION_CODE, stmnt) + + pattern="KERNEL_VERSION\\(([0-9]+) *, *([0-9]+) *, *([0-9]+) *\\)" + while (match(stmnt, pattern, ver) != 0) + { + sub(pattern, ver[1]*65536+ver[2]*256+ver[3], stmnt) + } + + pattern="([0-9]+) *(<|<=|>|>=|==) *([0-9]+)" + while (match(stmnt, pattern, op) != 0) + { + result="error" + if (op[2] == "<" ) result = op[1] < op[3] + else if (op[2] == "<=") result = op[1] <= op[3] + else if (op[2] == ">" ) result = op[1] > op[3] + else if (op[2] == ">=") result = op[1] >= op[3] + else if (op[2] == "==") result = op[1] == op[3] + sub(pattern, result, stmnt) + } + + pattern="([0-9]+) *\\&\\& *([0-9]+)" + while (match(stmnt, pattern, op) != 0) + { + sub(pattern, op[1] && op[3], stmnt) + } + + pattern="([0-9]+) *\\|\\| *([0-9]+)" + while (match(stmnt, pattern, op) != 0) + { + sub(pattern, op[1] || op[3], stmnt) + } + + return stmnt +} + + +# Decide whetheror not to print the preprocessor statement $0. + +function process_preprocessor_statement() { + last_if_nesting_level = if_nesting_level + evaluated = evaluate($0) + condition = 1 + if (evaluated ~ "^+#if") + { + output_array[if_nesting_level] = output + if_nesting_level++ + decision[if_nesting_level] = evaluated + output = evaluated != "+#if 0" + } + else if (evaluated ~ "^+#elif") + { + decision[if_nesting_level] = evaluated + output = evaluated != "+#elif 0" + sub("^+#elif ", "+#if ", decision[if_nesting_level]) + } + else if (evaluated ~ "^+#else") + { + output = decision[if_nesting_level] != "+#if 1" + } + else if (evaluated ~ "^+#endif") + { + if_nesting_level-- + if (if_nesting_level >= 0) + { + output = output_array[if_nesting_level] + } + else + { + output = 1 + } + } + else + { + condition = 0 + } + if (evaluated ~ "^+#if [01]$" \ + || condition \ + && evaluated !~ "^+#if" \ + && last_if_nesting_level >= 0 \ + && decision[last_if_nesting_level] ~ "+#if [01]$" \ + || ! condition \ + && last_if_nesting_level >= 0 \ + && decision[last_if_nesting_level] == "+#if 0") + { + print "+" + } + else + { + print $0 + } +} + + +BEGIN { + # Verify arguments. + if (kernel_version == "") + { + printf "Error: kernel_version was not specified.\n" + exit 1 + } + LINUX_VERSION_CODE = version_code(kernel_version) + if (LINUX_VERSION_CODE < 2*65536 || LINUX_VERSION_CODE > 3*65536) + { + printf "Error: kernel version (%s) is out of range.\n", kernel_version + exit 1 + } + + # Variable initialization. + output = 1 + if_nesting_level = -1 +} + + +{ + if (match($0, "^+ *#")) + process_preprocessor_statement() + else if (output) + print $0 + else + print "+" +} +