2014-03-06 12:37:22 +00:00
#!/usr/bin/perl
2014-02-13 06:30:03 +00:00
my $ input = $ ARGV [ 0 ] ;
my $ source = `clang-format $input` ;
2018-07-25 19:28:00 +00:00
2024-06-07 08:25:09 +00:00
# for_each (...) and friends...
2014-05-22 06:03:40 +00:00
$ source =~ s/(?:\G|^)(.*each.*\(.*) \* (\S.*\))$/$1 *$2/img ; # if a variable is declared in the argument, '*' is an indicator for a pointer, not arithmatic
$ source =~ s/(?:\G|^)(.*each.*\(.*) \& (\S.*\))$/$1 &$2/img ; # if a variable is declared in the argument, '&' is an indicator for a reference, not bit logic
$ source =~ s/(?:\G|^)(.*each[^\s(]*)\s*(\(.*)$/$1 $2/img ; # we want exactly one space between keyword and opening parenthesis '('
$ source =~ s/(?:\G|^)(.*each.*\(.*\).*)\n\s*{\s*$/$1 {/img ; # we want the opening curly brace on the same line, separated by a space
2014-03-03 21:25:55 +00:00
$ source =~ s/(?:\G|^)(\s+[^#\/*].*each.*\(.*\))\n(\s*)([^{}\s])/$1\n\t$2$3/img ;
2014-05-22 06:03:40 +00:00
# don't have '{' in the next line when declaring data types
2014-02-16 23:38:01 +00:00
$ source =~ s/^(\s*struct[^()\n]*)\n\s*{\s*$/$1 {/img ;
$ source =~ s/^(\s*static\s+struct[^()\n]*)\n\s*{\s*$/$1 {/img ;
$ source =~ s/^(\s*union[^()\n]*)\n\s*{\s*$/$1 {/img ;
$ source =~ s/^(\s*static\s+union[^()\n]*)\n\s*{\s*$/$1 {/img ;
2014-02-14 06:08:09 +00:00
$ source =~ s/^(\s*class.*)\n\s*{\s*$/$1 {/img ;
2018-07-25 19:28:00 +00:00
2014-05-22 06:03:40 +00:00
# a namespace shouldn't look like a function
2015-09-05 17:24:04 +00:00
$ source =~ s/(?:\G|^)(namespace.*)\n\{/$1 {/img ;
2018-07-25 19:28:00 +00:00
2014-03-05 20:19:45 +00:00
# colon goes at the end of a line
2014-02-14 06:08:09 +00:00
$ source =~ s/^(\S*::\S*.*)\n\s*: /$1 : /img ;
2018-07-25 19:28:00 +00:00
2014-05-22 06:03:40 +00:00
# odd indentations from clang-format:
2014-03-05 20:19:45 +00:00
# six spaces or four spaces after tabs (for continuation strings)
2014-02-13 06:30:03 +00:00
$ source =~ s/(?:\G|^)[ ]{6}/\t/mg ;
2014-02-14 06:08:09 +00:00
$ source =~ s/(?:\G|^)(\t*)[ ]{4}"/$1\t"/mg ;
2018-07-25 19:28:00 +00:00
2014-03-05 20:19:45 +00:00
# the next ones are rather awkward
# they capture multi line #define and #if definded statements
# that clang-format messes up (where does that 4 space indentation come
# from?
# I couldn't figure out how to make it apply to an arbitrary number of
# intermediate lines, so I hardcoded 0 through 5 lines between the #define
2014-05-22 06:03:40 +00:00
# or #if defined statements and the end of the multi line statement
2014-03-05 20:19:45 +00:00
$ source =~ s/^(#(?:if |)define.*)\n +([^*].*)$/$1\n\t$2/mg ;
$ source =~ s/^(#(?:if |)define.*)((?:\\\n.*){1})\n +([^*].*)$/$1$2\n\t$3/mg ;
$ source =~ s/^(#(?:if |)define.*)((?:\\\n.*){2})\n +([^*].*)$/$1$2\n\t$3/mg ;
$ source =~ s/^(#(?:if |)define.*)((?:\\\n.*){3})\n +([^*].*)$/$1$2\n\t$3/mg ;
$ source =~ s/^(#(?:if |)define.*)((?:\\\n.*){4})\n +([^*].*)$/$1$2\n\t$3/mg ;
$ source =~ s/^(#(?:if |)define.*)((?:\\\n.*){5})\n +([^*].*)$/$1$2\n\t$3/mg ;
2018-07-25 19:28:00 +00:00
2014-05-22 06:03:40 +00:00
# don't put line break before the last single term argument of a calculation
2014-03-03 21:25:55 +00:00
$ source =~ s/(?:\G|^)(.*[+-])\n\s*(\S*\;)$/$1 $2/mg ;
2015-10-18 00:05:36 +00:00
sub indent_ctor_init_lists {
my ( $ content ) = @ _ ;
2018-07-25 19:28:00 +00:00
# all caps/_ with just an argument list is a macro invocation and shouldn't be moved
2015-10-18 00:05:36 +00:00
my @ not_ctor_words = qw(
\ bdo \ b
\ belse \ b
\ bfor \ b
\ bif \ b
\ bsizeof \ b
\ bswitch \ b
\ bwhile \ b
\ btr \ b
\ bconnect \ b
2018-07-25 19:28:00 +00:00
^ [ A - Z_ ] + \ ( . * \ ) $
2015-10-18 00:05:36 +00:00
) ;
my $ regexStr = "(" . join ( "|" , @ not_ctor_words ) . ")" ;
my $ not_ctor_regex = qr{ $regexStr } ;
my $ result = "" ;
for ( split ( /\n/ , $ content ) ) {
if ( $ _ =~ $ not_ctor_regex ) {
# probably not a ctor line. leave it be.
$ result . = $ _ . "\n" ;
}
else {
$ _ =~ s/^\s*(\w*\(.*\),?)$/\t$1/mg ;
$ result . = $ _ . "\n" ;
}
}
return $ result ;
}
$ source = indent_ctor_init_lists ( $ source ) ;
2014-05-22 06:03:40 +00:00
$ quotedinput = $ input ;
$ quotedinput =~ s | /|\\/ | g ;
open ( DIFF , "| diff -u $input - | sed -e 's/--- $quotedinput/--- $quotedinput.old/' | sed -e 's/+++ -/+++ $quotedinput/'" ) ;
2014-02-13 06:30:03 +00:00
print DIFF $ source ;