Files
scst/scripts/specialize-patch
Vladislav Bolkhovitin 83af00fd15 Patch from Bart Van Assche <bart.vanassche@gmail.com>:
The current version of generate-kernel-patch does not remove preprocessor
statements that should have been removed because intended for another kernel
version (surrounded by #if LINUX_VERSION_CODE ... KERNEL_VERSION(...) / #endif).
The patch below fixes this.

I have verified the patch below by comparing the patch generated by the
old and the new versions of the generate-kernel-patch script:
$ diff p1 p2
7190d7189
< +#if defined(EXTRACHECKS)
7196c7195,7196
< +#endif
---
> > +
> > +
13056d13055
< +#ifdef STRICT_SERIALIZING
13058d13056
< +#elif !defined(SCSI_EXEC_REQ_FIFO_DEFINED)
13060d13057
< +#else
13062c13059,13062
< +#endif
---
> > +
> > +
> > +
> > +

Signed-off-by: Bart Van Assche <bart.vanassche@gmail.com>



git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@392 d57e44dd-8a1f-0410-8b47-8ef2f437770f
2008-05-23 15:19:52 +00:00

213 lines
4.8 KiB
Awk
Executable File

#!/usr/bin/awk -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 <bart.vanassche@gmail.com>
#
# 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)
do
{
last_stmnt = stmnt
pattern = "! ([0-9]+)"
while (match(stmnt, pattern, op) != 0)
{
sub(pattern, op[1] == 0, stmnt)
}
pattern="KERNEL_VERSION\\(([0-9]+) *, *([0-9]+) *, *([0-9]+) *\\)"
while (match(stmnt, pattern, op) != 0)
{
sub(pattern, op[1] * 65536 + op[2] * 256 + op[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)
}
pattern="\\(([0-9]+)\\)"
while (match(stmnt, pattern, op) != 0)
{
sub(pattern, op[1], stmnt)
}
} while (stmnt != last_stmnt)
return stmnt
}
# Evaluate ! stmnt
function invert(stmnt) {
sub("^+#if ", "+#if ! ", stmnt)
return evaluate(stmnt)
}
# Handle #if or #elif
function handle_if()
{
# Only act on preprocessor conditional expressions with regard to the Linux
# kernel version, and do not interpret other expressions.
if ($0 ~ "LINUX_VERSION_CODE")
{
$0 = evaluated
}
else
{
evaluated = "+#if undecided"
}
#printf "%s -> %s\n", $0, evaluated
if (evaluated ~ "^+#if")
{
if_stmnt[if_nesting_level] = evaluated
}
else
{
sub("^+#elif ", "+#if ! " + decision[if_nesting_level] + " && ", evaluated)
evaluated = evaluate(evaluated)
}
decision[if_nesting_level] = evaluated
matching_if = if_stmnt[if_nesting_level]
}
# Decide whether or 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")
{
if_nesting_level++
handle_if()
}
else if (evaluated ~ "^+#elif")
{
handle_if()
}
else if (evaluated ~ "^+#else")
{
matching_if = if_stmnt[if_nesting_level]
decision[if_nesting_level] = invert(decision[if_nesting_level])
}
else if (evaluated ~ "^+#endif")
{
matching_if = if_stmnt[if_nesting_level]
if_nesting_level--
}
else
{
condition = 0
}
if (condition)
{
output = 1
for (i = if_nesting_level; i >= 0; i--)
{
output = output && decision[i] != "+#if 0"
}
}
if (output && (! condition || condition && matching_if !~ "^+#if [01]"))
{
print $0
}
else
{
print "+"
}
}
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 "+"
}