#! /bin/bash # XXX this does not handle c++ namespacing. # XXX this becomes *incredibly* slow for some files - # have to replace the regexp voodoo with a proper parser, i guess. typefile=typedefs.out if ! test -f $typefile; then find . \( -name '*.c' -o -name '*.cpp' -o -name '*.h' \) -exec cpp -DHAVE_CONFIG_H -I. -I.. -I../.. {} \; 2>/dev/null | perl -w -e ' use strict; use re "eval"; my ($btypes, $bt, $ctypes, $np, $wrd); $bt=$btypes="void (?:(?:un)?signed\\s+)?(?:short\\s+|long\\s+(?:long\\s+)?\\s+)?int (?:(?:un)?signed\\s+)?(?:short|long(?:\\s+long)?) (?:un)?signed (?:(?:un)?signed\\s+)?char float (?:long\\s+(?:long\\s+)?)?double"; $ctypes="(?:struct|union)\\s+\\w+"; $bt =~ s/\n/|/g; $np=qr{\{(?:(?>[^{}]+)|(??{$np}))*\}}x; $wrd=qr{(?>\s*)(?>\**)(?>\s*)((?>\b\w+\b))(?{print $^N."\n"})(?>\s*)}x; read STDIN, $_, 1e9; s/^\s*typedef\s+(?:$bt\s|(?:struct|union)(?>\s+)(?>\b\w+\b\s+)?(??{$np})|$ctypes\s)$wrd(?:,$wrd)*;//xmg; s/^\s*class\s+(\w+)(?{print $^N."\n"})//xmg; print $btypes."\n".$ctypes."\n"; ' | sort -u | tr '\n' '|' | sed 's,|$,,' > $typefile fi pty=$(<$typefile) skw="if|switch|for|while|return" nskw="sizeof|offsetof|defined|as|ki18n|i18n|i18nc|i18np|i18npc|I18N_NOOP|I18N_NOOP2|QString::fromLatin1|QLatin1String|SIGNAL|SLOT" for i in "$@"; do echo "Indenting $i ..." ( # cat $i # expand -i < $i | unexpand -t 4 --first-only # expand -i < $i | unexpand -t 2 --first-only # expand -i -t 2 < $i | unexpand -t 8 --first-only # expand -i -t 8 < $i | unexpand -t 2 --first-only # expand -i -t 4 < $i | unexpand -t 2 --first-only expand -i -t 4 < $i | unexpand -t 4 --first-only ) | perl -w -e ' use strict; use re '"'eval'"'; # remove trailing whitespace, append exactly one space after semicolon sub stws($) { local $_ = shift; s/ *$//; s/(?[^()]+)|(??{$fp})|(??{$np}))*}xs; # parenthesized complex expression $np=qr{\($pc\)}xs; # basic expression: function( n times complex expression ) $fp=qr{(\b(?:new(?>\s+)|(?!'"$pty|$skw|$nskw|else"'))(?:\w|\.|::)+|\(\ *\*\ *(?:(?>[^()]*)|(??{$np}))*\))(?>\s*)\((?>\ *)($pc)\)}xs; sub ffn($) { local $_ = shift; # fix whitespace around function calls # XXX maybe correct parens in $1, too? s/$fp/$1."( ".stws(&ffn($2))." )"/eg; # fix whitespace around function-like (pseudo-)operators s/\b('"$nskw"')\s*\(\s*(?!{~)($pc)\)/$1."(".stws($2).")"/eg; # fix whitespace around c-style type casts s/(?) { if ($cpp) { $cpp = /\\$/; } elsif (/^#/) { if (/^#\ *if/) { push @ifst, ($il, @pcs); push @elst, $els; $els = 0; } elsif (/^# *elif/) { ($il, @pcs) = $ifst[$#ifst]; } elsif (/^# *else/) { ($il, @pcs) = pop @ifst; $els = 1; } elsif (/^# *endif/) { if (!$els) { ($il, @pcs) = pop @ifst; } $els = pop @elst; } $cpp = /\\$/; } else { $cmt = 1 if /^([ \t]*)\/\*/; if (!$cmt) { if (@pcs) { s/^[ \t]*/$il.(" " x ($pcs[$#pcs] - length($il)))/e; } else { /^([ \t]*)/; $il = $1; } /^(?>[ \t]*)(?:\((?>\ *)(?{push @pcs, pos;})|\)(?{pop @pcs;})|\/\*.*?\*\/|'"'"'(?:\\.|[^'"'"'])*'"'"'|"(?:\\.|[^"])*"|.)*$/x; } $cmt = 0 if /\*\/$/; } print $_; } ' > $i.tmp && mv $i.tmp $i done exit 0