File indexing completed on 2024-12-08 05:05:48
0001 #!/bin/awk 0002 # 0003 # Copyright (c) 2014, Michal Policht. This file is dually licensed under terms of 0004 # either WTFPL or BEER-WARE LICENSE. You may obtain the copy of WTFPL or BEER-WARE 0005 # LICENSE in nearest drug store. 0006 # 0007 # THIS SOFTWARE IS ADDICTED TO DRUGS AND ALCOHOL AND IS A SUSPECT OF DRIVING UNDER THE 0008 # INFLUENCE OF ALCOHOL. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 0009 # CONTRIBUTORS "AS IS NOT" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 0010 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS AND APPLICATION AND 0011 # ACCOMODATION FOR A PARTICULAR PURPOSE AND MANY OTHERS NOT MENTIONED, NOR EVEN 0012 # INVENTED WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 0013 # OR CONTRIBUTORS BE LIABLE FOR ANY TEMPORAL, PERMANENT, UNFORTUNATE, UNLUCKY, 0014 # LUCKY, DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, ACCIDENTAL, MENTAL, 0015 # OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 0016 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION; 0017 # OR BEING KILLED BY A LIGHTNING; OR FLOOD; OR FIRE; OR ANTEATER (INCLUDING BUT NOT 0018 # LIMITED TO, GIANT ANTEATER, ANTEATER WHO LIES ON A SOFA; ANTEATER WHO LISTENS HEAVY 0019 # METAL MUSIC; ANTEATER WHO ATE HUMAN BEFORE) OR ANOTHER BEING.) HOWEVER CAUSED AND ON 0020 # ANY, ANY THEORY OF LIABILITY, CONSPIRACY THEORY, ANY THEORY OF RELATIVITY, WHETHER IN 0021 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 0022 # WAY OUT OF THE USE OF THIS SOFTWARE, ARISING IN ANY WAY OUT OF THE SUN, EVEN IF PROMISSED 0023 # WISHED OR ASSURED SUCH DAMAGE. THIS SOFTWARE CAN REALLY DO TERRIBLE THINGS. 0024 # 0025 # Script updates C/C++ include guards with macros based on header path (including directory structure). 0026 # It seeks for "#ifndef, #define" pair and substitutes first encountered pair with generated values. 0027 # Script does not distinguish include guards from other macros, so each HEADER FILE MUST CONTAIN 0028 # INCLUDE GUARD AS ITS FIRST "#ifndef, #define" MACRO PAIR. Script only updates include guards; 0029 # if file does not contain something that looks like include guard to the script it will not add one. 0030 # Script will also eat everything after last "#endif", presumably include guard comment. It's a stupid 0031 # beast, so always backup your data before use. 0032 # 0033 # usage: awk [-v prefix="PREFIX"] -f awkgward.awk header 0034 # example: awk -v prefix="PROJECT_" -f awkgward.awk file.hpp 0035 # 0036 # parameters: 0037 # header - header file. 0038 # 0039 # required tools: awk. 0040 0041 function create_guard_macro(prefix, filename) 0042 { 0043 escaped_underscores = toupper(filename); 0044 # Just in case, escape single underscores. 0045 gsub(/_/, "_u_", escaped_underscores); 0046 # \/ = slash (/), \. = dot (.), \\ = backslash (\) - replace them with underscore. 0047 gsub(/[\/\.\\]/, "_", escaped_underscores); 0048 return prefix escaped_underscores; 0049 } 0050 0051 function create_guard(prefix, filename) 0052 { 0053 guard_macro = create_guard_macro(prefix, filename); 0054 guard = "#ifndef " guard_macro ORS "#define " guard_macro; 0055 return guard; 0056 } 0057 0058 function print_or_buf(line) 0059 { 0060 if (global_buf_mode) 0061 global_buf = global_buf line ORS; 0062 else 0063 print line; 0064 } 0065 0066 BEGIN { 0067 S_START = 0; 0068 S_FIRST_IFNDEF = 1; 0069 S_END = 2; 0070 0071 if (!prefix) 0072 prefix = ""; 0073 0074 global_buf = ""; 0075 global_buf_mode = 0; 0076 endif_line = ""; 0077 0078 ifndef_buf = ""; 0079 # simple automata: 0080 # S_START /^#ifndef\s.*/ -> S_FIRST_IFNDEF /^#define\s.*/ -> S_END // -> S_START 0081 # S_FIRST_IFNDEF /^#define\s.*/ -> S_END 0082 # S_END // -> S_END 0083 state = S_START; 0084 } 0085 0086 /^#ifndef[\t ].*/ { 0087 if (state == S_START) { 0088 ifndef_buf = $0; 0089 state = S_FIRST_IFNDEF; 0090 next; 0091 } 0092 } 0093 0094 /^#define[\t ].*/ { 0095 if (state == S_FIRST_IFNDEF) { 0096 #eat old guard and replace it with new one 0097 print_or_buf(create_guard(prefix, FILENAME)); 0098 state = S_END; 0099 next; 0100 } 0101 if (state == S_START) 0102 state = S_END; 0103 } 0104 0105 /^#endif[\t ].*/ { 0106 #flush old buffer and whatever was in endif line 0107 if (global_buf_mode) { 0108 print endif_line; 0109 printf global_buf; 0110 global_buf = ""; 0111 } 0112 endif_line = $0; 0113 global_buf_mode = 1; 0114 next; 0115 } 0116 0117 0118 { 0119 if (state == S_END || state == S_START) 0120 print_or_buf($0); 0121 if (state == S_FIRST_IFNDEF) { 0122 print_or_buf(ifndef_buf); 0123 print_or_buf($0); 0124 state = S_END; 0125 } 0126 } 0127 0128 END { 0129 if (global_buf_mode) { 0130 #it's last endif so do not print full endif_line 0131 print "#endif"; 0132 printf global_buf; #flush whatever was after last endif 0133 } 0134 } 0135