#!/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-2009 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, array) { if (!match(kver, "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$", array)) match(kver, "^([0-9]+)\\.([0-9]+)$", array) return 65536*array[1] + 256*array[2] + array[3] } # Evaluate a preprocessor statement via repeated substitutions. # Mathematicians call this algorithm 'term rewriting'. # Note: the order in which the substitutions appear below is important -- # it is the same order as the order of operators in C. function evaluate(stmnt, pattern, arg, op, result) { if (debug) printf "/* debug specialize-patch: (a) %s */\n", stmnt # Remove C-style comments. gsub("[[:blank:]]*\\/\\*[^*]*\\*\\/[[:blank:]]*", "", stmnt) # Remove the spaces before the #-sign. gsub("^+[[:blank:]]*#[[:blank:]]*", "+#", stmnt) if (match(stmnt, "^+#ifdef (.*)$", arg)) { stmnt = "+#if defined(" arg[1] ")" } if (match(stmnt, "^+#ifndef (.*)$", arg)) { stmnt = "+#if !defined(" arg[1] ")" } gsub("defined\\(REGISTER_MAD_AGENT_HAS_FLAGS_ARG\\)", "(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))", stmnt) gsub("SOCK_RECVMSG_HAS_FOUR_ARGS", "(LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0))", stmnt) gsub("defined\\(USE_PRE_440_WR_STRUCTURE\\)", "(LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0))", stmnt) gsub("defined\\(IB_CREATE_CQ_HAS_INIT_ATTR\\)", "(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))", stmnt) gsub("defined\\(CREATE_SEND_MAD_HAS_BASE_ARG\\)", "(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))", stmnt) gsub("defined\\(IB_CM_LISTEN_TAKES_FOURTH_ARG\\)", "(LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0))", stmnt) gsub("defined\\(IB_CLIENT_REMOVE_TAKES_TWO_ARGS\\)", "(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0))", stmnt) gsub("defined\\(IB_QUERY_GID_HAS_ATTR_ARG\\)", "(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))", stmnt) gsub("RDMA_CREATE_ID_TAKES_NET_ARG", "(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))", stmnt) gsub("HAVE_DEV_ATTR_MAX_SEND_SGE", "(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))", stmnt) gsub("HAVE_RDMA_DESTROY_AH", "(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))", stmnt) gsub("HAVE_RDMA_QUERY_GID", "(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))", stmnt) gsub("HAVE_STRUCT_SRP_LOGIN_REQ_RDMA", "(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0))", stmnt) gsub("defined\\(USE_PRE_440_WR_STRUCTURE\\)", "(LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0))", stmnt) gsub("defined\\(HAVE_IB_QUERY_DEVICE\\)", "(LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))", stmnt) gsub("defined\\(MAD_HANDLER_TAKES_SEND_BUF\\)", "(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0))", stmnt) gsub("defined\\(HAVE_IB_SET_CPI_RESP_TIME\\)", "(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))", stmnt) gsub("defined\\(IB_PD_HAS_LOCAL_DMA_LKEY\\)", "(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0))", stmnt) gsub("defined\\(HAVE_IB_DMA_MAP_OPS\\)", "(LINUX_VERSION_CODE >= KERNEL_VERSION(0, 0, 0))", stmnt) gsub("defined(ENABLE_NPIV)", 0, stmnt) gsub("defined(FC_VPORT_CREATE_DEFINED)", 0, stmnt) gsub("LINUX_VERSION_CODE", LINUX_VERSION_CODE, stmnt) pattern="KERNEL_VERSION\\([[:blank:]]*([0-9]+)[[:blank:]]*,[[:blank:]]*([0-9]+)[[:blank:]]*,[[:blank:]]*([0-9]+)[[:blank:]]*\\)" while (match(stmnt, pattern, op) != 0) { sub(pattern, op[1] * 65536 + op[2] * 256 + op[3], stmnt) } gsub("defined\\(INSIDE_KERNEL_TREE\\)", "1", stmnt) gsub("defined\\(BACKPORT_LINUX_WORKQUEUE_TO_2_6_19\\)", "0", stmnt) gsub("defined\\(CONFIG_SUSE_KERNEL\\)", "0", stmnt) gsub("defined\\(CONFIG_SCST_STRICT_SERIALIZING\\)", "0", stmnt) if (RHEL_MAJOR == "") { gsub("defined\\(RHEL_MAJOR\\)", "0", stmnt) gsub("RHEL_MAJOR", "", stmnt) } else { gsub("defined\\(RHEL_MAJOR\\)", "1", stmnt) gsub("RHEL_MAJOR", RHEL_MAJOR, stmnt) } if (RHEL_MINOR == "") { gsub("defined\\(RHEL_MINOR\\)", "0", stmnt) gsub("RHEL_MINOR", "0", stmnt) } else { gsub("defined\\(RHEL_MINOR\\)", "1", stmnt) gsub("RHEL_MINOR", RHEL_MINOR, stmnt) } gsub("defined\\(RHEL_RELEASE_VERSION\\)", "1", stmnt) if (RHEL_MAJOR == "" || RHEL_MINOR == "") { gsub("defined\\(RHEL_RELEASE_CODE\\)", "0", stmnt) gsub("RHEL_RELEASE_CODE", "", stmnt) gsub("RHEL_RELEASE_VERSION\\([^,)]*,[ ]*[^,)]*\\)", "0", stmnt) } else { gsub("defined\\(RHEL_RELEASE_CODE\\)", "1", stmnt) gsub("RHEL_RELEASE_CODE", RHEL_MAJOR * 256 + RHEL_MINOR, stmnt) stmnt = gensub("RHEL_RELEASE_VERSION\\(([^,)]*),[ ]*([^,)]*)\\)", "(\\1) * 256 + (\\2)", "g", stmnt) } if (SCSI_EXEC_REQ_FIFO_DEFINED != "") { gsub("defined[[:blank:]]+SCSI_EXEC_REQ_FIFO_DEFINED", SCSI_EXEC_REQ_FIFO_DEFINED, stmnt) gsub("defined[[:blank:]]*\\([[:blank:]]*SCSI_EXEC_REQ_FIFO_DEFINED[[:blank:]]*\\)", SCSI_EXEC_REQ_FIFO_DEFINED, stmnt) } if (SCST_IO_CONTEXT != "") { gsub("defined[[:blank:]]+SCST_IO_CONTEXT", SCST_IO_CONTEXT, stmnt) gsub("defined[[:blank:]]*\\([[:blank:]]*SCST_IO_CONTEXT[[:blank:]]*\\)", SCST_IO_CONTEXT, stmnt) } if (generating_upstream_patch_defined) { gsub("defined[[:blank:]]+GENERATING_UPSTREAM_PATCH", 1, stmnt) gsub("defined[[:blank:]]*\\([[:blank:]]*GENERATING_UPSTREAM_PATCH[[:blank:]]*\\)", 1, stmnt) } if (config_tcp_zero_copy_transfer_completion_notification_undefined) { gsub("defined[[:blank:]]+CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION", 0, stmnt) gsub("defined[[:blank:]]*\\([[:blank:]]*CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION[[:blank:]]*\\)", 0, stmnt) } gsub("defined[[:blank:]]+CONFIG_SCST_PROC", !config_scst_proc_undefined, stmnt) gsub("defined[[:blank:]]*\\([[:blank:]]*CONFIG_SCST_PROC[[:blank:]]*\\)", !config_scst_proc_undefined, stmnt) if (debug) printf "/* debug specialize-patch: (b) %s */\n", stmnt do { last_stmnt = stmnt pattern = "![[:blank:]]*(-*[0-9]+)" while (match(stmnt, pattern, op) != 0) { sub(pattern, op[1] == 0, stmnt) } pattern = "![[:blank:]]*\\([[:blank:]]*(-*[0-9]+)[[:blank:]]*\\)" while (match(stmnt, pattern, op) != 0) { sub(pattern, op[1] == 0, stmnt) } pattern="(-*[0-9]+)[[:blank:]]*(\\*|/)[[:blank:]]*(-*[0-9]+)" while (match(stmnt, pattern, op) != 0) { result="error" if (op[2] == "*") result = op[1] * op[3] else if (op[2] == "/" && op[3] != 0) result = op[1] / op[3] sub(pattern, result, stmnt) } pattern="(-*[0-9]+)[[:blank:]]*(\\+|-)[[:blank:]]*(-*[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] sub(pattern, result, stmnt) } pattern="(-*[0-9]+)[[:blank:]]*(<<|>>)[[:blank:]]*(-*[0-9]+)" while (match(stmnt, pattern, op) != 0) { result="error" if (op[2] == "<<") result = int(op[1] * (2**op[3])) else if (op[2] == ">>") result = int(op[1] / (2**op[3])) sub(pattern, result, stmnt) } pattern="(-*[0-9]+)[[:blank:]]*(<|<=|>|>=|==|!=)[[:blank:]]*(-*[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] else if (op[2] == "!=") result = op[1] != op[3] sub(pattern, result, stmnt) } pattern="(-*[0-9]+)[[:blank:]]*\\&\\&[[:blank:]]*\\([[:blank:]]*(-*[0-9]+)[[:blank:]]*\\)" while (match(stmnt, pattern, op) != 0) { sub(pattern, (op[1] != 0) && (op[2] != 0), stmnt) } pattern="(-*[0-9]+)[[:blank:]]*\\&\\&[[:blank:]]*(-*[0-9]+)" while (match(stmnt, pattern, op) != 0) { sub(pattern, (op[1] != 0) && (op[2] != 0), stmnt) } pattern="^+#(if|elif)[[:blank:]]*([01])[[:blank:]]*\\&\\&[[:blank:]]*(!*[[:blank:]]*defined[[:blank:]]*\\([[:blank:]]*[A-Za-z0-9_]*[[:blank:]]*\\))$" while (match(stmnt, pattern, op) != 0) { stmnt = "+#" op[1] " " (op[2] != 0 ? op[3] : op[2]) } pattern="^+#(if|elif)[[:blank:]]*(!*[[:blank:]]*defined[[:blank:]]*\\([[:blank:]]*[A-Za-z0-9_]*[[:blank:]]*\\))\\&\\&[[:blank:]]*([01])[[:blank:]]*$" while (match(stmnt, pattern, op) != 0) { stmnt = "+#" op[1] " " (op[3] != 0 ? op[2] : op[3]) } pattern="^+#(if|elif)[[:blank:]]*(!*[[:blank:]]*[A-Za-z0-9_]*)[[:blank:]]*\\&\\&[[:blank:]]*([01])[[:blank:]]*$" while (match(stmnt, pattern, op) != 0) { stmnt = "+#" op[1] " " (op[3] != 0 ? op[2] : op[3]) } pattern="(-*[0-9]+)[[:blank:]]*\\|\\|[[:blank:]]*(-*[0-9]+)" while (match(stmnt, pattern, op) != 0) { sub(pattern, (op[1] != 0) || (op[2] != 0), stmnt) } pattern="^+#(if|elif)[[:blank:]]*([01])[[:blank:]]*\\|\\|[[:blank:]]*(!*[[:blank:]]*defined[[:blank:]]*\\([[:blank:]]*[A-Za-z0-9_]*[[:blank:]]*\\))$" while (match(stmnt, pattern, op) != 0) { stmnt = "+#" op[1] " " (op[2] == 0 ? op[3] : op[2]) } pattern="\\(([01])[[:blank:]]*\\|\\|[[:blank:]]*(!*[[:blank:]]*defined[[:blank:]]*\\([[:blank:]]*[A-Za-z0-9_]*[[:blank:]]*\\))\\)" while (match(stmnt, pattern, op) != 0) { sub(pattern, op[1] == 0 ? op[2] : op[1], stmnt) } pattern="\\([[:blank:]]*(-*[0-9]+)[[:blank:]]*\\)" while (match(stmnt, pattern, op) != 0) { sub(pattern, op[1], stmnt) } if (debug) printf "/* debug specialize-patch: (c) %s -> %s */\n", last_stmnt, stmnt } while (stmnt != last_stmnt) return stmnt } # Evaluate !stmnt function invert(stmnt) { return evaluate(gensub("^+#if (.*)$", "+#if !(\\1)", "g", stmnt)) } # Handle #if or #elif function handle_if(evaluated) { # 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 ~ "CONFIG_SCST_PROC" \ || $0 ~ "CONFIG_SCST_STRICT_SERIALIZING" \ || $0 ~ "CREATE_SEND_MAD_HAS_BASE_ARG" \ || $0 ~ "ENABLE_NPIV" \ || $0 ~ "FC_VPORT_CREATE_DEFINED" \ || $0 ~ "HAVE_DEV_ATTR_MAX_SEND_SGE" \ || $0 ~ "HAVE_IB_DMA_MAP_OPS" \ || $0 ~ "HAVE_IB_QUERY_DEVICE" \ || $0 ~ "HAVE_IB_SET_CPI_RESP_TIME" \ || $0 ~ "HAVE_RDMA_DESTROY_AH" \ || $0 ~ "HAVE_RDMA_QUERY_GID" \ || $0 ~ "HAVE_STRUCT_SRP_LOGIN_REQ_RDMA" \ || $0 ~ "IB_CLIENT_REMOVE_TAKES_TWO_ARGS" \ || $0 ~ "IB_CM_LISTEN_TAKES_FOURTH_ARG" \ || $0 ~ "IB_CREATE_CQ_HAS_INIT_ATTR" \ || $0 ~ "IB_PD_HAS_LOCAL_DMA_LKEY" \ || $0 ~ "IB_PD_HAS_LOCAL_DMA_LKEY" \ || $0 ~ "IB_QUERY_GID_HAS_ATTR_ARG" \ || $0 ~ "INSIDE_KERNEL_TREE" \ || $0 ~ "MAD_HANDLER_TAKES_SEND_BUF" \ || $0 ~ "RDMA_CREATE_ID_TAKES_NET_ARG" \ || $0 ~ "REGISTER_MAD_AGENT_HAS_FLAGS_ARG" \ || $0 ~ "RHEL_MAJOR" \ || $0 ~ "RHEL_MINOR" \ || $0 ~ "RHEL_RELEASE_CODE" \ || $0 ~ "SOCK_RECVMSG_HAS_FOUR_ARGS" \ || $0 ~ "USE_PRE_440_WR_STRUCTURE" \ || generating_upstream_patch_defined \ && $0 ~ "GENERATING_UPSTREAM_PATCH" \ || $0 ~ "CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION" \ || ($0 ~ "CONFIG_SCST_PROC" && config_scst_proc_undefined) \ || ($0 ~ "SCSI_EXEC_REQ_FIFO_DEFINED" && SCSI_EXEC_REQ_FIFO_DEFINED!="") \ || ($0 ~ "SCST_IO_CONTEXT" && SCST_IO_CONTEXT != "")) { } else { evaluated = "+#if undecided" } if (debug) printf "/* debug specialize-patch: (d) %s -> %s */\n", $0, evaluated if (evaluated ~ "^+#if") { if_stmnt[if_nesting_level] = evaluated any_section_output[if_nesting_level] = 0 decision[if_nesting_level] = evaluated inv_decision[if_nesting_level] = evaluate(sprintf("+#if !%s", substr(evaluated, 6))) if (debug) printf "/* debug specialize-patch: (f) %s / %s */\n", \ decision[if_nesting_level], inv_decision[if_nesting_level] } else { sub("^+#elif ", sprintf("+#if %s \\&\\& ", substr(inv_decision[if_nesting_level], 6)), evaluated) if (debug) printf "/* debug specialize-patch: (e) %s */\n", evaluated evaluated = evaluate(evaluated) sub("^+#if", "+#elif", evaluated); decision[if_nesting_level] = evaluated inv_decision[if_nesting_level] \ = evaluate(sprintf("+#if %s && !%s", \ substr(inv_decision[if_nesting_level], 6), \ substr(evaluated, 8))) if (debug) printf "/* debug specialize-patch: (f) %s / %s */\n", \ decision[if_nesting_level], inv_decision[if_nesting_level] } return evaluated } # Decide whether or not to print the preprocessor statement $0. function process_preprocessor_statement(evaluated, condition) { evaluated = evaluate($0) condition = 1 ei = evaluated_if_stmnt[if_nesting_level]; if (evaluated ~ "^+#if") { if_nesting_level++ evaluated_if_stmnt[if_nesting_level] = evaluated evaluated = handle_if(evaluated) } else if (evaluated ~ "^+#elif") { if (if_discarded[if_nesting_level]) { sub("^+#elif", "+#if", input_line[0]) if (debug) printf "/* debug specialize-patch: (g0) -> %s */\n", evaluated } evaluated = handle_if(evaluated) } else if (evaluated ~ "^+#else") { decision[if_nesting_level] = inv_decision[if_nesting_level] } else if (evaluated ~ "^+#endif") { if_nesting_level-- } else { condition = 0 } if (condition) { output = 1 if (debug) printf "/* debug specialize-patch: (g1a) if_nesting_level = %d */\n", \ if_nesting_level for (i = if_nesting_level; i >= 0; i--) { if (debug) printf "/* debug specialize-patch: (g1b) %s: decision[%d] = %s */\n", \ evaluated, i, decision[i] output = output && decision[i] != "+#if 0" && decision[i] != "+#elif 0" } if (output) any_section_output[if_nesting_level] = 1 if (debug) printf "/* debug specialize-patch: (g2) %s: output = %d */\n", \ evaluated, output } if (evaluated ~ "^+#define SCSI_EXEC_REQ_FIFO_DEFINED$" \ && SCSI_EXEC_REQ_FIFO_DEFINED != "" \ || evaluated ~ "^+#define SCST_IO_CONTEXT$" \ && SCST_IO_CONTEXT != "" \ || (evaluated ~ "^+#define CONFIG_SCST_PROC$" \ && config_scst_proc_undefined)) { discard = 1 delete_next_blank_line = 1 } else if (output && (!condition || \ decision[if_nesting_level + (evaluated ~ "^+#endif$")] \ !~ "^+#(el|)if [01]")) { if (evaluated == "+#if undecided" \ || (evaluated !~ "^+#if" \ && evaluated !~ "^+#elif" \ && evaluated !~ "^+#endif")) { for (i = 0; i < input_line_count; i++) line[lines++] = input_line[i] } else { # If the statement being processed is an #else or #endif that is not a # header file include guard and if that statement has a trailing comment, # replace that comment by the partially evaluated matching #if expression. if (evaluated ~ "^+#else" || evaluated ~ "^+#endif") { if ($0 ~ "\\*/") { if ($0 ~ "_H_* \\*/$") { evaluated = $0 } else { if (ei ~ "^+#if ") ei = substr(ei, 6) else if (ei ~ "^+#ifdef") ei = substr(ei, 9) evaluated = sprintf("%s /* %s */", $0 ~ " " ? substr($0, 1, index($0, " ")) : $0, ei); if (match(evaluated, "([^/ ]*) */\\* defined\\(([^()]*)\\) \\*/", arg)) { evaluated = sprintf("%s /* %s */", arg[1], arg[2]) } } } else { evaluated = $0 } if (debug) printf "/* debug specialize-patch: (h) %s */\n", evaluated } line[lines++] = evaluated lines_less_added += input_line_count - 1 } } else { discard = 1 if (lines >= 1 && line[lines - 1] == "+") delete_next_blank_line = 1 } if (evaluated ~ "^+#if") if_discarded[if_nesting_level] = discard } function reset_hunk_state_variables() { lines = 0 lines_less_added = 0 lines_less_deleted = 0 output = 1 if_nesting_level = -1 delete_next_blank_line = 0 h[0] = "" } function dump_lines() { # Detect empty hunks first_modif = -1 for (i = 0; i < lines; i++) { if (line[i] ~ "^[+-]") { first_modif = i break } } # Dump line[] as a hunk, but only if the hunk is not empty. if (first_modif >= 0) { if (h[0] != "") printf "@@ -%d,%d +%d,%d @@%s\n",h[1],h[2]-lines_less_deleted,h[3],h[4]-lines_less_added,h[5] for (i = 0; i < lines; i++) print line[i] } } 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) { printf "Error: kernel version (%s) is out of range.\n", kernel_version exit 1 } if (blank_deleted_code != 0 && blank_deleted_code != 1) blank_deleted_code = 0 if (generating_upstream_patch_defined != 0 && generating_upstream_patch_defined != 1) generating_upstream_patch_defined = 0 if (config_tcp_zero_copy_transfer_completion_notification_undefined != 0 && config_tcp_zero_copy_transfer_completion_notification_undefined != 1) config_tcp_zero_copy_transfer_completion_notification_undefined = 0 if (config_scst_proc_undefined != 0 && config_scst_proc_undefined != 1) config_scst_proc_undefined = 0 # Variable initialization. is_c_source = 0 reset_hunk_state_variables() } { if (match($0, "^diff[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+([^ \t]+)$", filename) \ || match($0, "^\\+\\+\\+[ \t]+([^ \t]+)[ \t]+", filename)) { # Start of new file. dump_lines() reset_hunk_state_variables() is_c_source = match(filename[1], "\\.[ch]$") != 0 } if (!is_c_source) { print next } if (!config_scst_proc_undefined) { gsub("^+/\\* #define CONFIG_SCST_PROC \\*/$", "+#define CONFIG_SCST_PROC") } else { gsub("^+/\\* #define CONFIG_SCST_PROC \\*/$", "+") } input_line[0] = $0 input_line_count = 1 # Join continued lines before processing these. while (match($0, "\\\\$")) { previous_line = $0 sub("[ \t]*\\\\$", "", previous_line) getline input_line[input_line_count++] = $0 sub("^+[ \t]*", "", $0) $0 = previous_line " " $0 } discard = 0 # If the line currently being processed is a hunk header, print all lines # that were stored in the array line[] since the last hunk header was read. if (match($0, "^@@ -([0-9]*),([0-9]*) \\+([0-9]*),([0-9]*) @@(.*)$")) { /* print h[1], h[2], h[3], h[4], h[5] */ dump_lines() reset_hunk_state_variables() match($0, "^@@ -([0-9]*),([0-9]*) \\+([0-9]*),([0-9]*) @@(.*)$", h) } else if (delete_next_blank_line && $0 == "+") { discard = 1 delete_next_blank_line = 0 } else if (lines >= 2 && !match(line[lines-2], ":$") && line[lines-1] == "+\x9return;" && $0 == "+}") { # Delete "return;" statements at the end of a function that are not # preceded by a label. line[lines-1] = $0 lines_less_added++ } else { delete_next_blank_line = 0 if (match($0, "^+ *#")) { if (debug) printf "/* debug specialize-patch: line %d: %s*/\n", NR, $0 process_preprocessor_statement() } else if (output) { # Store the lines that were just read. for (i = 0; i < input_line_count; i++) line[lines++] = input_line[i] # Convert double blank lines into a single blank line. if (line[lines-1] == "+") delete_next_blank_line = 1 } else { discard = 1 if (lines >= 1 && line[lines-1] == "+") delete_next_blank_line = 1 } } if (discard) { for (i = 0; i < input_line_count; i++) { if (blank_deleted_code) { if (input_line[i] ~ "^+") line[lines++] = "+" else line[lines++] = input_line[i] } else { if (input_line[i] ~ "^+") lines_less_added++ else if (input_line[i] ~ "^-") lines_less_deleted++ } } } } END { # Dump processed contents of the last read hunk. dump_lines() } # Local variables: # indent-tabs-mode: nil # c-basic-offset: 2 # End: