Patch from Bart Van Assche <bart.vanassche@gmail.com>:
authorvlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Thu, 22 May 2008 15:55:23 +0000 (15:55 +0000)
committervlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Thu, 22 May 2008 15:55:23 +0000 (15:55 +0000)
The patch below implements the following changes:
- Make sure the output of the make command does not appear in the generated
  kernel patch.
- Changed interpreter of scripts/specialize-patch from /usr/bin/gawk to
  /usr/bin/awk in order to make sure this awk script also runs on systems
  where awk is installed but not gawk.
- Added an extra evaluation rule such that expressions like (0) are rewritten
  as 0.
- Fixed a spelling error.
- Expressions that can only be partially evaluated are now partially evaluated.
  E.g. #if defined(EXTRACHECKS) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
  becomes #if defined(EXTRACHECKS) && 0 in the output.
- Code between #if 0 / #endif or #if 1 / #endif is included in the generated
  kernel patch, including the surrounding preprocessor directives.
- Preprocessor statements with spaces behind # are now recognized (e.g. "#   if").
- Expression evaluator now supports ! (logical not) and () (braces).
- #elif is now evaluated correctly.
- Nested #if / #elif / #else / #endif are now interpreted correctly.

Signed-off-by: Bart Van Assche <bart.vanassche@gmail.com>
git-svn-id: https://scst.svn.sourceforge.net/svnroot/scst/trunk@385 d57e44dd-8a1f-0410-8b47-8ef2f437770f

scripts/generate-kernel-patch
scripts/specialize-patch

index c0343f8..788815d 100755 (executable)
@@ -121,7 +121,7 @@ cat "${kpatch[@]}"
 # Directory include/scst/
 
 # Make sure the file iscsi-scst/iscsi_scst_itf_ver.h is up to date.
-make -C iscsi-scst include/iscsi_scst_itf_ver.h
+make -s -C iscsi-scst include/iscsi_scst_itf_ver.h
 
 for f in scst/include/*h
 do
index d9b3ee3..89ffb1d 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/gawk -f
+#!/usr/bin/awk -f
 
 ############################################################################
 #
@@ -42,45 +42,93 @@ function version_code(kver) {
 function evaluate(stmnt) {
   gsub(" *\\/\\*[^*]*\\*\\/ *", "", 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)
+  do
   {
-    sub(pattern, ver[1]*65536+ver[2]*256+ver[3], stmnt)
-  }
+    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
+}
+
 
-  pattern="([0-9]+) *(<|<=|>|>=|==) *([0-9]+)"
-  while (match(stmnt, pattern, op) != 0)
+# 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")
   {
-    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)
+    $0 = evaluated
   }
-
-  pattern="([0-9]+) *\\&\\& *([0-9]+)"
-  while (match(stmnt, pattern, op) != 0)
+  else
   {
-    sub(pattern, op[1] && op[3], stmnt)
+    evaluated = "+#if undecided"
   }
-
-  pattern="([0-9]+) *\\|\\| *([0-9]+)"
-  while (match(stmnt, pattern, op) != 0)
+  #printf "%s -> %s\n", $0, evaluated
+  if (evaluated ~ "^+#elif")
   {
-    sub(pattern, op[1] || op[3], stmnt)
+    sub("^+#elif ", "+#if ! " + decision[if_nesting_level] + " && ", evaluated)
+    evaluated = evaluate(evaluated)
   }
-
-  return stmnt
+  decision[if_nesting_level] = evaluated
 }
 
 
-# Decide whetheror not to print the preprocessor statement $0.
+# Decide whether or not to print the preprocessor statement $0.
 
 function process_preprocessor_statement() {
   last_if_nesting_level = if_nesting_level
@@ -88,37 +136,33 @@ function process_preprocessor_statement() {
   condition = 1
   if (evaluated ~ "^+#if")
   {
-    output_array[if_nesting_level] = output
     if_nesting_level++
-    decision[if_nesting_level] = evaluated
-    output = evaluated != "+#if 0"
+    handle_if()
   }
   else if (evaluated ~ "^+#elif")
   {
-    decision[if_nesting_level] = evaluated
-    output = evaluated != "+#elif 0"
-    sub("^+#elif ", "+#if ", decision[if_nesting_level])
+    handle_if()
   }
   else if (evaluated ~ "^+#else")
   {
-    output = decision[if_nesting_level] != "+#if 1"
+    decision[if_nesting_level] = invert(decision[if_nesting_level])
   }
   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 (condition)
+  {
+    output = 1
+    for (i = if_nesting_level; i >= 0; i--)
+    {
+      output = output && decision[i] != "+#if 0"
+    }
+  }
   if (evaluated ~ "^+#if [01]$"                             \
       || condition                                          \
          && evaluated !~ "^+#if"                            \