Files
scst/scripts/specialize-patch
Vladislav Bolkhovitin 1504425c40 All empty lines due
to code commented out because inside #if LINUX_VERSION_CODE ... /
#endif is now really removed.

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



git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@481 d57e44dd-8a1f-0410-8b47-8ef2f437770f
2008-07-28 18:19:34 +00:00

234 lines
5.4 KiB
Awk
Executable File

#!/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 <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)
gsub("defined\\(INSIDE_KERNEL_TREE\\)", "1", 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 ~ "INSIDE_KERNEL_TREE")
{
$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]"))
{
line[lines++]=$0
}
else
{
lines_deleted++
}
}
function dump_lines() {
if (h[0] != "")
printf "@@ -%d,%d +%d,%d @@%s\n",h[1],h[2],h[3],h[4]-lines_deleted,h[5]
for (i = 0; i < lines; i++)
print line[i]
lines = 0
lines_deleted = 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.
lines = 0
lines_deleted = 0
output = 1
if_nesting_level = -1
}
{
if (match($0, "^@@ -([0-9]*),([0-9]*) \\+([0-9]*),([0-9]*) @@(.*)$"))
{
/* print h[1], h[2], h[3], h[4], h[5] */
dump_lines()
match($0, "^@@ -([0-9]*),([0-9]*) \\+([0-9]*),([0-9]*) @@(.*)$", h)
}
else if (match($0, "^+ *#"))
process_preprocessor_statement()
else if (output)
line[lines++]=$0
else
lines_deleted++
}
END {
dump_lines()
}