source: branches/profile/SOURCE_TOOLS/tabBrake.pl

Last change on this file was 10993, checked in by westram, 10 years ago
  • added detection for gcc vs clang
    • separated allowed version for both compilers
    • renamed a bunch of gcc-specific make variables
    • dumps compiler version output (-dumpversion and —version) to compile log in case of failure
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 9.6 KB
Line 
1#!/usr/bin/perl
2#
3# checks files for TABs and raises error if TABs found
4# (TABs are evil, cause they have no default width)
5#
6# As well checks for older ARB compile logs and removes them
7
8
9use strict;
10use warnings;
11
12my $forceAll  = 0; # 1 -> force scan of all files if no stamp, 0 -> assume all ok, scan only new files
13my $defsStart = 15; # lineno of start of definition
14
15my $checkForOldLogs = 1; # whether to check for old logfile and delete them
16
17my %scan_extension = map { $_ => 1; } (
18                                       'c', 'h',
19                                       'cxx', 'hxx',
20                                       'cpp', 'hpp',
21                                       'f', 'inc',
22                                       'm4', 'status', 'in',
23                                       'txt', 'doc', 'README', 'readme',
24                                       'sh',
25                                       'pl', 'pm', 'PL', 'cgi',
26                                       'java',
27                                       'head', 'header', 'default', 'footer',
28                                       'makefile',
29                                       'template',
30                                       'dat',
31                                       'dtd', 'xsl',
32                                       'eft', 'ift', 'ift2', 'amc',
33                                       'sellst',
34                                       'mask',
35                                       'aisc', 'pa',
36                                       'source', 'menu',
37                                       'mat', 'conf',
38                                      );
39
40my %auto_determine = map { $_ => 1; } (
41                                       'x', 'jar',
42                                      );
43
44my %ignore_extension = map { $_ => 1; } (
45                                         'a', 'o', 'so',
46                                         'class',
47                                         'html', 'bitmap', 'ps', 'icon', 'hlp', 'help', 
48                                         'gif', 'png', 'fig', 'vfont', 'SAVE',
49                                         'tgz', 'gz',
50                                         'lst', 'depends',
51                                         'md5', 'bs', 'xs',
52                                         'exists', 'ignore', '3pm',
53                                         'arb', 'seq', 'genmenu',
54                                         'init', 'cvsignore', 'log', 'am', 'org',
55                                         'last_gcc', 'last_compiler', 'csv',
56                                         'b', 'n', 'helpfiles', 
57                                         'ms', 'gon', 'pep', 'bla', 'tct', 'comm',
58                                         'before', 'v1', 'data', 'pdb', 'embl', 'xpm', 'big',
59                                         '2_manual_postscript', '2_manual_text',
60                                         'stamp',
61                                        );
62
63my %ignored_subdirs = map { $_ => 1; } (
64                                        'GDE',
65                                        'READSEQ',
66                                        'HEADERLIBS',
67                                        'patches',
68                                        'UNIT_TESTER/flags',
69                                        'UNIT_TESTER/logs',
70                                        'UNIT_TESTER/run',
71                                        'UNIT_TESTER/sockets',
72                                        'UNIT_TESTER/tests',
73                                        'UNIT_TESTER/valgrind',
74                                        'bin',
75                                       );
76
77my %ignored_relpath = map { $_ => 1; } (
78                                        'NAMES_COM/names_client.h',
79                                        'NAMES_COM/names_server.h',
80                                        'PROBE_COM/PT_com.h',
81                                        'PROBE_COM/PT_server.h',
82                                       );
83
84my $tab_count        = 0;
85my $files_newer_than = 0;
86
87sub getModtime($) {
88  my ($file) = @_;
89  my @st = stat($file);
90  if (not @st) { die "can't stat '$file' ($!)"; }
91  return $st[9];
92}
93
94
95sub scan_for_tabs($) {
96  my ($file) = @_;
97  my $has_tabs = `grep -m 1 -n -H '\t' $file`;
98
99  # print "$file:0: has_tabs='$has_tabs'\n";
100
101  if ($has_tabs ne '') {
102    my $pos = "$file:0:";
103    if ($has_tabs =~ /^[^:]+:[0-9]+:/) {
104      $pos = $&;
105    }
106    print "$pos contains tabs. Tabs are not allowed.\n";
107    $tab_count++;
108    if ($tab_count>10) { die "Further scan skipped.\n"; }
109  }
110}
111
112sub recurse_dirs($$);
113sub recurse_dirs($$) {
114  my ($dir,$basedir) = @_;
115
116  my @subdirs = ();
117  my $subdir  = '';
118  if ($dir ne $basedir) {
119    $subdir = substr($dir,length($basedir)+1);
120    if (defined $ignored_subdirs{$subdir}) {
121      # print "Ignoring '$subdir' (dir='$dir')\n";
122      return;
123    }
124  }
125
126  opendir(DIR, $dir) || die "can't read directory '$dir' (Reason: $!)";
127  foreach (readdir(DIR)) {
128    if ($_ ne '.' and $_ ne '..') {
129      my $full = $dir.'/'.$_;
130      my $rel  = $subdir.'/'.$_;
131      if (-l $full) {
132        # print "$full:0: link -- skipped\n";
133      }
134      elsif (-d $full) {
135        if ($_ ne 'CVS' and
136            $_ ne '.svn' and
137            $_ ne 'ARB_SOURCE_DOC' and
138            $_ ne 'old_help' and
139            $_ ne 'PERL2ARB' and
140            $_ ne 'GENC' and $_ ne 'GENH'
141           ) {
142          push @subdirs, $full;
143        }
144      }
145      elsif (-f $full) {
146        my $scan      = -1;
147        my $determine = 0;
148        my $modtime   = getModtime($full);
149
150        if ($modtime<$files_newer_than) {
151          # file was created before last run of tabBrake.pl
152          $scan = 0;
153
154          # check if it's a log from an aborted compile
155          if (/^[^.]+\.([0-9]+)\.log$/o) {
156            if ($checkForOldLogs and $modtime<($files_newer_than-3*60)) {
157              print "Old log file: $full -- removing\n";
158              unlink($full) || print "$full:0: can't unlink (Reason: $!)\n";
159            }
160          }
161        }
162        elsif (defined $ignored_relpath{$rel}) {
163          # print "$full:0: excluded by relpath '$rel'\n";
164          $scan = 0;
165        }
166        else {
167          if (/\.([^.]+)$/) {   # file with extension
168            my $ext = $1;
169            if (exists $ignore_extension{$ext}) {
170              # print "$full:0: excluded by extension '$ext'\n";
171              $scan = 0;
172            }
173            elsif (exists $scan_extension{$ext}) {
174              # print "$full:0: scan!\n";
175              $scan = 1;
176            }
177            elsif (exists $auto_determine{$ext}) {
178              # print "$full:0: scan!\n";
179              $determine = 1;
180            }
181            else {
182              if ($ext =~ /^[0-9]+$/ 
183                 ) {
184                $scan = 0;
185              }
186              elsif ($full =~ /util\/config\./ or
187                     $full =~ /lib\/config\./
188                    ) {
189                $scan = 1;
190              }
191              else {
192                                # print "$full:0: a '$ext' file\n";
193              }
194            }
195          }
196          else {
197            if (/Makefile/ or
198                /ChangeLog/
199               ) {
200              $scan = 0;
201            }
202            else {
203              $determine = 1;
204            }
205          }
206
207          if ($determine==1) {
208            $scan==-1 || die "logic error";
209            my $file_says = `file $full`;
210            if ($file_says =~ /^[^:]+:[ ]*(.*)$/) {
211              $file_says = $1;
212            }
213            else {
214              die "Can't parse output from 'file'-command";
215            }
216
217            if ($file_says =~ /executable/ or
218                $file_says eq 'empty' or
219                $file_says eq 'data' or
220                $file_says eq 'IFF data' or
221                $file_says =~ /archive.*data/
222               ) {
223              $scan = 0;
224            }
225            elsif ($file_says =~ /shell.*script/ or
226                   $file_says =~ /ASCII.*text/ or 
227                   $file_says =~ /ISO.*text/ or
228                   $file_says =~ /perl.*script/ 
229                  ) {
230              $scan = 1;
231            }
232            else {
233              print "$full:0: file_says='$file_says'\n";
234            }
235          }
236        }
237        if ($scan==-1) {
238          if (/^#.*#$/) {
239            print "$full:1: a lost file?\n";
240          }
241          else {
242            # die "Don't know what to do with '$full'";
243          }
244        }
245        elsif ($scan==1) {
246          scan_for_tabs($full);
247          # print "$full:0: scanning..\n";
248        }
249      }
250    }
251  }
252  closedir(DIR);
253
254  foreach (@subdirs) {
255    recurse_dirs($_,$basedir);
256  }
257}
258
259# --------------------------------------------------------------------------------
260
261print "--- TAB brake ---\n";
262
263my $ARBHOME = $ENV{'ARBHOME'};
264
265if (not defined $ARBHOME) {
266  die "'ARBHOME' not defined";
267}
268
269my $time_stamp = $ARBHOME.'/SOURCE_TOOLS/stamp.tabBrake';
270my $exitcode   = 0;
271if (-f $time_stamp) {
272  $files_newer_than = getModtime($time_stamp);
273  print "Checking files newer than ".localtime($files_newer_than)."\n";
274}
275else {
276  if ($forceAll==1) {
277    print "Initial call - checking all files\n";
278    $files_newer_than = 0;
279  }
280  else {
281    print "Initial call - assuming everything is TAB-free\n";
282    $files_newer_than = time;
283    $checkForOldLogs  = 0; # do not check for old logs (sometimes fails on fresh checkouts, e.g. in jenkins build server)
284  }
285}
286
287if ($exitcode==0) {
288  `touch $time_stamp`;          # mark time of last try
289  # i.e. user inserts TAB to file -> fail once
290}
291recurse_dirs($ARBHOME,$ARBHOME);
292if ($tab_count>0) {
293  $exitcode = 1;
294  print $ARBHOME.'/SOURCE_TOOLS/tabBrake.pl:'.$defsStart.': Warning: what may contain TABs is defined here'."\n";
295}
296
297exit($exitcode);
Note: See TracBrowser for help on using the repository browser.