2 # Copyright: 2009-2010, Nick Treleaven
3 # License: GNU GPL V2 or later, as published by the Free Software Foundation, USA.
6 # Re-align C source code for Geany.
7 # Doesn't handle indents/blank lines/anything complicated ;-)
16 my $opt_write = $args{'w'};
18 my $argc = $#ARGV + 1;
21 (($argc == 1) or ($argc >= 1 and $opt_write)) or die <<END;
23 $scriptname sourcefile [>outfile]
24 Print formatted output to STDOUT or outfile.
25 Warning: do not use the same file for outfile.
27 $scriptname -w sourcefile(s)
28 Writes to the file(s) in-place.
29 Warning: backup your file(s) first or use clean version control files.
38 open(INPUT
, $infile) or die "Couldn't open $infile for reading: $!\n";
41 my $line = $_; # read a line, including \n char
43 # strip trailing space & newline
46 # for now, don't process lines with comments, strings, preproc non-defines, overflowed lines or chars
47 # multi-line comment internal lines are skipped only if they start with '* '.
48 if (!($line =~ m
,/\*|\*/|//|"|\\$|',) and !($line =~ m/^\s*(\*\s|#[^d])/)) {
49 # make binary operators have *one* space each side
50 # operators must have longer variants first otherwise trailing operators can be broken e.g. "+ ="
51 # '*' ignored as could be pointer
52 my $ops = '<<=,<<,>>=,>>,<=,>=,<,>,||,|=,|,&&,&=,-=,+=,+,*=,/=,/,==,!=,%=,%,^=,^,=';
53 $ops =~ s/([|*+])/\\$1/g; # escape regex chars
55 $line =~ s/([\w)\]]) ?($ops) ?([\w(]|$)/$1 $2 $3/g;
57 # space binary operators that can conflict with unaries with cast and/or 'return -1/&foo'
58 # '-' could be unary "(gint
)-j
"
59 # '&' could be address-of "(type
*)&foo
"
60 $line =~ s/([\w\]])(-|&) ?([\w(]|$)/$1 $2 $3/g;
62 # space ternary conditional operator
63 $line =~ s/ ?\? ?(.+?) ?: ?/ ? $1 : /g;
65 # space comma operator (allowing for possible alignment space afterwards)
66 $line =~ s/ ?,(\S)/, $1/g;
68 # space after statements
69 my $statements = 'for|if|while|switch';
70 $line =~ s/\b($statements)\b\s*/$1 /g;
72 # no space on inside of brackets
74 $line =~ s/(\S)\s+\)/$1)/g;
76 # enforce 'fn(void);' in prototypes
77 $line =~ s/^(\w.+\w\()\);$/$1void);/;
79 # strip trailing space again (e.g. a trailing operator now has space afterwards)
86 my $text = join("\n", @lines);
87 undef @lines; # free memory
90 # 1+ newline -> 2 newlines after function
91 $text =~ s/^}\n\n+([^\n])/}\n\n\n$1/gm;
97 open(OUTPUT, ">$infile") or die "Couldn
't open $infile for writing: $!\n";
104 foreach my $infile (@ARGV)