1 #!/usr/bin/env awk 2 3 4 function shift( array, \ 5 junk, elm0, l ) 6 { 7 elm0 = array[0] 8 for ( l = 0; l < asorti( array, junk ) - 1; l++ ) 9 array[l] = array[l+1]; 10 delete array[l] 11 return elm0 12 } 13 14 15 function init_cpp_src_line() 16 { 17 logical_line = "" 18 delete break_pos 19 } 20 21 22 function shift_valid_bp( array, \ 23 junk, elm ) 24 { 25 elm = -1 26 27 if ( 0 < asorti( array, junk ) ) 28 do { 29 elm = shift( array ) 30 } while ( 0 > elm ); 31 32 return elm 33 } 34 35 36 function check_cpp_src_line_break_pos( \ 37 i, junk ) 38 { 39 printf( "break_pos:" ) 40 for ( i = 0; i < asorti( break_pos, junk ); i++ ) 41 printf( " %d", break_pos[i] ); 42 printf( "\n" ) 43 } 44 45 46 function check_cpp_src_line() 47 { 48 printf( "logical_line[%s]\n", logical_line ) 49 check_cpp_src_line_break_pos() 50 } 51 52 53 function append_line( phys_line, \ 54 filt_line, bp_len ) 55 { 56 filt_line = phys_line 57 sub( /\\$/, " ", filt_line ) 58 logical_line = logical_line filt_line 59 bp_len = asorti( break_pos, junk ) 60 break_pos[bp_len] = length( logical_line ) - 1 61 } 62 63 64 function print_line( \ 65 c0, c1, i, junk, part_str ) 66 { 67 c0 = 0 68 69 while( asorti( break_pos, junk ) > 1 ) 70 { 71 if ( ( c1 = shift_valid_bp( break_pos ) ) < 1 ) 72 { 73 part_str = substr( logical_line, c0 + 1 ) 74 printf( "%s\n", part_str ) 75 return 76 } 77 78 part_str = substr( logical_line, c0 + 1, c1 - c0 + 1 ) 79 gsub( / $/, "\\", part_str ) 80 printf( "%s\n", part_str ) 81 c0 = c1 + 1 82 } 83 84 part_str = substr( logical_line, c0 + 1 ) 85 printf( "%s\n", part_str ) 86 } 87 88 89 function shrink_spaces( pos, \ 90 tail, removed_length, k ) 91 { 92 tail = substr( logical_line, pos ) 93 sub( /^[ \t]+/, " ", tail ) 94 removed_length = length( logical_line ) - pos - length( tail ) + 1 95 logical_line = substr( logical_line, 0, pos - 1 ) tail 96 97 98 for ( k = 0; k < asorti( break_pos, junk ); k++ ) 99 if ( ( pos + removed_length ) <= break_pos[k] ) 100 break_pos[k] = break_pos[k] - removed_length; 101 else if ( pos <= break_pos[k] ) 102 break_pos[k] = -1; 103 104 return removed_length 105 } 106 107 108 function shrink_spaces_to_linebreak( pos, \ 109 junk, part_str, removed_length, i ) 110 { 111 for ( i = 0; i < asorti( break_pos, junk ) && break_pos[i] < pos ; i++ ) 112 ; 113 114 if ( break_pos[i] < 1 ) 115 return; 116 117 part_str = substr( logical_line, pos, break_pos[i] - pos + 1 ) 118 sub( /^[ \t]+/, " ", part_str ) 119 removed_length = ( break_pos[i] - pos + 1 ) - length( part_str ) 120 121 tail = substr( logical_line, pos + removed_length ) 122 logical_line = substr( logical_line, 0, pos - 1 ) tail 123 124 for ( ; i < asorti( break_pos, junk ); i++ ) 125 break_pos[i] -= removed_length; 126 127 return removed_length 128 } 129 130 131 function delete_linebreaks_in_2nd_token( \ 132 tail, paren_depth, junk, i, j, k, l ) 133 { 134 if ( logical_line ~ /^[ \t]*#[ \t]*define[ \t]+[0-9A-Za-z_]+\(/ ) 135 { 136 tail = logical_line 137 sub( /^[ \t]*#[ \t]*define[ \t]+[0-9A-Za-z_]+/, "", tail ) 138 139 paren_depth = 0 140 l = 0 141 i = length( logical_line ) - length( tail ) + 1 # seek to the 1st op paren 142 j = i 143 do { 144 if ( substr( logical_line, j, 2 ) ~ /[ \t][ \t]/ ) 145 l = shrink_spaces( j ); 146 else if ( substr( logical_line, j, 1 ) == "(" ) 147 paren_depth += 1; 148 else if ( substr( logical_line, j, 1 ) == ")" ) 149 paren_depth -= 1; 150 j += 1 151 } while ( j < length( logical_line ) && paren_depth != 0 ) 152 153 for ( k = 0; k < asorti( break_pos, junk ); k++ ) 154 if ( i <= break_pos[k] && break_pos[k] < j ) 155 break_pos[k] = -1; 156 157 if ( l > 0 ) 158 shrink_spaces_to_linebreak( j ); 159 } 160 } 161 162 163 BEGIN{ 164 init_cpp_src_line() 165 } 166 { 167 append_line( $0 ) 168 if ( $0 !~ /\\$/ ) 169 { 170 delete_linebreaks_in_2nd_token() 171 print_line() 172 init_cpp_src_line() 173 } 174 } 175 END{ 176 if ( 0 < length( logical_line ) ) 177 { 178 delete_linebreaks_in_2nd_token() 179 print_line() 180 } 181 } 182