mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-14 09:11:27 +00:00
The script scripts/specialize-patch'>scripts/specialize-patch is an awk script. Currently it specifies /usr/bin/awk as its interpreter although it doesn't use the standard AWK syntax but the extended GNU AWK syntax. The patch below changes the interpreter name such that the script also works on systems where /usr/bin/awk is not GNU AWK (e.g. Ubuntu 8.04). Note: GNU AWK is not installed by default on all Linux systems. E.g. on Debian systems it's in the gawk package. Signed-off-by: Bart Van Assche <bart.vanassche@gmail.com> git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@413 d57e44dd-8a1f-0410-8b47-8ef2f437770f
213 lines
4.8 KiB
Awk
Executable File
213 lines
4.8 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)
|
|
|
|
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 "+"
|
|
}
|
|
|