Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

executable file 109 lines (82 sloc) 2.91 kb
#!/usr/bin/env perl
# Copyright: 2009-2011, Nick Treleaven
# License: GNU GPL V2 or later, as published by the Free Software Foundation, USA.
# Warranty: NONE
# Re-align C source code for Geany.
# Doesn't handle indents/blank lines/anything complicated ;-)
use strict;
use warnings;
use Getopt::Std;
my %args = ();
getopts('w', \%args);
my $opt_write = $args{'w'};
my $argc = $#ARGV + 1;
my $scriptname = $0;
(($argc == 1) or ($argc >= 1 and $opt_write)) or die <<END;
Usage:
$scriptname sourcefile [>outfile]
Print formatted output to STDOUT or outfile.
Warning: do not use the same file for outfile.
$scriptname -w sourcefile(s)
Writes to the file(s) in-place.
Warning: backup your file(s) first or use clean version control files.
END
sub parse($)
{
my ($infile) = @_;
my @lines;
open(INPUT, $infile) or die "Couldn't open $infile for reading: $!\n";
while (<INPUT>) {
my $line = $_; # read a line, including \n char
# strip trailing space & newline
$line =~ s/\s+$//g;
# for now, don't process lines with comments, strings, preproc non-defines, overflowed lines or chars
# multi-line comment internal lines are skipped only if they start with '* '.
if (!($line =~ m,/\*|\*/|//|"|\\$|',) and !($line =~ m/^\s*(\*\s|#[^d])/)) {
# make binary operators have *one* space each side
# operators must have longer variants first otherwise trailing operators can be broken e.g. "+ ="
# '*' ignored as could be pointer
my $ops = '<<=,<<,>>=,>>,<=,>=,<,>,||,|=,|,&&,&=,-=,+=,+,*=,/=,/,==,!=,%=,%,^=,^,=';
$ops =~ s/([|*+])/\\$1/g; # escape regex chars
$ops =~ s/,/|/g;
$line =~ s/([\w)\]]) ?($ops) ?([\w(]|$)/$1 $2 $3/g;
# space binary operators that can conflict with unaries with cast and/or 'return -1/&foo'
# '-' could be unary "(gint)-j"
# '&' could be address-of "(type*)&foo"
$line =~ s/([\w\]])(-|&) ?([\w(]|$)/$1 $2 $3/g;
# space ternary conditional operator
$line =~ s/ ?\? ?(.+?) ?: ?/ ? $1 : /g;
# space comma operator (allowing for possible alignment space afterwards)
$line =~ s/ ?,(\S)/, $1/g;
# space after statements
my $statements = 'for|if|while|switch';
$line =~ s/\b($statements)\b\s*/$1 /g;
# no space on inside of brackets
$line =~ s/\(\s+/(/g;
$line =~ s/(\S)\s+\)/$1)/g;
# enforce 'fn(void);' in prototypes
$line =~ s/^(\w.+\w\()\);$/$1void);/;
}
# strip trailing space again (e.g. a trailing operator now has space afterwards)
$line =~ s/\s+$//g;
push(@lines, $line);
}
close(INPUT);
my $text = join("\n", @lines);
undef @lines; # free memory
$text .= "\n";
# 1+ newline -> 2 newlines after function
$text =~ s/^}\n\n+([^\n])/}\n\n\n$1/gm;
if (!$opt_write) {
print $text;
}
else {
open(OUTPUT, ">$infile") or die "Couldn't open $infile for writing: $!\n";
print OUTPUT $text;
close(OUTPUT);
}
}
foreach my $infile (@ARGV)
{
parse($infile);
}
Jump to Line
Something went wrong with that request. Please try again.