source: tags/arb-6.0/util/arb_srclst.pl

Last change on this file was 11947, checked in by westram, 10 years ago
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 21.4 KB
Line 
1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
6my $debug_matching = 0;
7my $ignore_unknown = 0;
8
9# ------------------------------------------------------------
10# override checks below and save strictly as checked-in in SVN
11
12my @strictly_as_in_svn_when_matchesDir = (
13                                           qr/\/GDE\/MAFFT\/mafft-[0-9\.]+-with[out]*-extensions/o,
14                                          );
15
16# ------------------------------------------------------------
17# skipped_directories and files inside are never examined:
18
19my @skipped_directories = (
20                           qr/\/.+\/bin$/o,
21                           qr/\/.+\/build$/o,
22                           qr/\/HELP_SOURCE\/Xml$/o,
23                           qr/\/GDE\/MUSCLE\/obj$/o,
24                           qr/\/GDE\/PHYML20130708\/phyml\/autom4te.cache$/o,
25                           qr/\/ignore\./o,
26                           qr/\/PERL2ARB\/blib$/o,
27                           qr/\/HEADERLIBS\/[^\/]+/o,
28                           qr/\/UNIT_TESTER\/logs$/o,
29                           qr/\/UNIT_TESTER\/tests$/o,
30                           qr/\/UNIT_TESTER\/run\/homefake\/.arb_prop\/(macros|cfgSave)$/o,
31                           qr/^\.\/ARB_SOURCE_DOC/o,
32                           qr/^\.\/dep_graphs/o,
33                           qr/^\.\/INCLUDE$/o,
34                           qr/^\.\/lib\/help$/o,
35                           qr/^\.\/lib\/help_html$/o,
36                           qr/^\.\/lib\/pts$/o,
37                           qr/^\.\/lib\/mafft$/o,
38                           qr/^\.\/patches.arb$/o,
39                           qr/^\.\/PERL5$/o,
40                           qr/_COM\/DUMP$/o,
41                           qr/_COM\/GEN[CH]$/o,
42                           qr/_COM\/O$/o,
43                           qr/_GEN$/o,
44                           qr/nbproject/o,
45                           # needed by ralf:
46                           qr/^\.\/test_arb_make_targets_logs/o,
47                           qr/\.dSYM$/o,
48                          );
49
50# first used/skipped match wins (exception see @3 below)
51
52my %used_files = map { $_ => 1; } (
53                                   '!BRANCH_STATE',
54                                   'AUTHORS',
55                                   'COPYING',
56                                   'demo.arb',
57                                   'Doxyfile',
58                                   'export2sub',
59                                   'Makefile',
60                                   'Makefile.org',
61                                   'Makefile.setup.include',
62                                   'Makefile.setup.template',
63                                   'Makefile.suite',
64                                   'Makefile.test',
65                                   'needs_libs',
66                                  );
67
68my %skipped_files = map { $_ => 1; } (
69                                      '.build.lst',
70                                      '.cvsignore',
71                                      '.depends',
72                                      'ChangeLog',
73                                      'config.makefile',
74                                      'helpfiles.lst',
75                                      'last.success',
76                                      'Makefile.setup.local',
77                                      'makeloc.here',
78                                      'makeloc.here',
79                                      'nt_date.h',
80                                      'postcompile.sav',
81                                      'TAGS',
82                                      '.DS_Store',
83                                      );
84
85my %used_extensions = map { $_ => 1; } (
86                                        'c', 'cpp', 'cxx', 'cc',
87                                        'h', 'hpp', 'hxx',
88
89                                        'aisc', 'pa',
90                                        'bitmap',
91                                        'dtd', 'xsl',
92                                        'f',
93                                        'footer',
94                                        'head', 'header',
95                                        'i',  # swig input
96                                        'inc',
97                                        'java', 'manifest',
98                                        'makefile',
99                                        'pl', 'pm', 'PL', 'cgi', 'xs',
100                                        'awk',
101                                        'py',
102                                        'script',
103                                        'sh',
104                                        'source', 'menu',
105                                        'template', 'default',
106                                        'txt', 'doc', 'ps', 'pdf',
107                                       );
108
109my %skipped_extensions = map { $_ => 1; } (
110                                           'a',
111                                           'bak',
112                                           'class',
113                                           'bundle', # Some file from XCode
114                                           'gcno',
115                                           'genmenu',
116                                           'jar',
117                                           'last_gcc',
118                                           'last_compiler',
119                                           'list',
120                                           'log',
121                                           'o',
122                                           'old',
123                                           'patch',
124                                           'rej',
125                                           'so',
126                                           'stamp',
127                                           'swp',
128                                           'yml', 'json', # perl2arb
129                                          );
130
131
132# used_when_matches, skipped_when_matches and used_when_matchesFull are only tested,
133# if above filters did not match:
134
135my @used_when_matches = (
136                         qr/^arb_.*\.txt$/o,
137                         qr/disclaimer/io,
138                         qr/license/io,
139                         qr/needs_libs\..*/io,
140                         qr/readme$/io,
141                         qr/typemap$/io,
142                         qr/unused.*source.*\.tgz$/io,
143                        );
144
145my @skipped_when_matches = (
146                            qr/.*~$/o, # backups
147                            qr/\#.*\#$/o,
148                            qr/\.\#.*$/o,
149                            qr/^arbsrc.*\.tgz$/o,
150                            qr/^arbsrc\.lst$/o,
151                            qr/^arbsrc\.lst\.tmp$/o,
152                            qr/^callgrind\./o,
153                           );
154
155my @used_when_matchesFull = (
156                             qr/\/AISC_COM\/AISC\/magic.lst$/o,
157                             qr/\/CLUSTALW\/.*$/o,
158                             qr/\/EISPACK\/rg\.html$/o,
159                             qr/\/GDE\/.*\.html$/o,
160                             qr/\/GDEHELP\/FASTA/o,
161                             qr/\/GDEHELP\/GDE.*/o,
162                             qr/\/GDEHELP\/HELP_PLAIN/o,
163                             qr/\/GDEHELP\/HELP_WRITTEN/o,
164                             qr/\/GDEHELP\/Makefile\.helpfiles/o,
165                             qr/\/HEADERLIBS\/.*COPYING$/o,
166                             qr/\/HEADERLIBS\/.*\.tgz$/o,
167                             qr/\/HELP_SOURCE\/.*\.gif$/o,
168                             qr/\/HELP_SOURCE\/oldhelp\/.*\.(ps|pdf)\.gz$/o,
169                             qr/\/HELP_SOURCE\/oldhelp\/.*\.hlp$/o,
170                             qr/\/HGL_SRC\/plot\.icon$/o,
171                             qr/\/PERL2ARB\/.*\.html$/o,
172                             qr/\/PERL2ARB\/Makefile.main$/o,
173                             qr/\/PHYLIP\/doc\//o,
174                             qr/\/PROBE_SERVER\/.*\.conf$/o,
175                             qr/\/READSEQ\/.*\.help$/o,
176                             qr/\/READSEQ\/Formats$/o,
177                             qr/\/SH\/[^\/\.]*$/o,
178                             qr/\/SOURCE_TOOLS\//o,
179                             qr/\/TREEPUZZLE\/.*\.gif$/o,
180                             qr/\/UNIT_TESTER\/run\/.*\.a00$/o,
181                             qr/\/UNIT_TESTER\/run\/.*\.arb$/o,
182                             qr/\/UNIT_TESTER\/run\/.*\.amc$/o,
183                             qr/\/UNIT_TESTER\/run\/.*\.expected$/o,
184                             qr/\/UNIT_TESTER\/run\/.*\.fig$/o,
185                             qr/\/UNIT_TESTER\/run\/.*\.in$/o,
186                             qr/\/UNIT_TESTER\/run\/.*\.inp$/o,
187                             qr/\/UNIT_TESTER\/run\/.*\.input$/o,
188                             qr/\/UNIT_TESTER\/run\/.*\.out$/o,
189                             qr/\/UNIT_TESTER\/run\/.*\.tree$/o,
190                             qr/\/UNIT_TESTER\/run\/help\//o,
191                             qr/\/UNIT_TESTER\/run\/impexp\/.*\.exported$/o,
192                             qr/\/UNIT_TESTER\/valgrind\/arb_valgrind_logged$/o,
193                             qr/^\.\/etc\//o,
194                             qr/^\.\/lib\/arb_default\/.*\.arb$/o,
195                             qr/^\.\/lib\/arb_tcp_org\.dat$/o,
196                             qr/^\.\/lib\/config\.[^\.]+$/io,
197                             qr/^\.\/lib\/export\/.*\.eft$/o,
198                             qr/^\.\/lib\/import\/.*\.ift2?$/o,
199                             qr/^\.\/lib\/inputMasks\/.*\.mask$/o,
200                             qr/^\.\/lib\/macros\/.*\.amc$/o,
201                             qr/^\.\/lib\/macros\/.checks\/.*\.expected$/o,
202                             qr/^\.\/lib\/nas\/names\.dat\.template$/o,
203                             qr/^\.\/lib\/pictures\/.*\.(fig|vfont)$/o,
204                             qr/^\.\/lib\/pixmaps\/.*\.xpm$/o,
205                             qr/^\.\/lib\/protein_2nd_structure\/.*\.dat$/o,
206                             qr/^\.\/lib\/rna3d\/.*\.(pdb|data)$/o,
207                             qr/^\.\/lib\/rna3d\/images\/.*\.png$/o,
208                             qr/^\.\/lib\/sellists\/.*\.sellst$/o,
209                             qr/^\.\/lib\/submit\//o,
210                             qr/^\.\/lib\/BUGS\//o,
211                             qr/^\.\/util\/arb_.*$/o,
212                             qr/^\.\/util\/config\..*$/o,
213                             qr/\/GDE\/.*\/Makefile\.[^\/]+$/io,
214                             qr/\/GDE\/PHYML[^\/]+\/phyml\//o,
215                            );
216
217# skipped_when_matchesFull and forced_when_matchesFull are always tested! (@3)
218
219my @skipped_when_matchesFull = (
220                                qr/\/genhelp\/.*\.hlp$/o,
221                                qr/\/lib\/addlibs\/(lib.*\.so\..*)$/o,
222                                qr/^\.\/arb.*\.tgz$/o,
223                                qr/^\.\/bin\//o,
224                                qr/^\.\/GDE\/CORE\/functions.h$/o,
225                                qr/^\.\/GDE\/PHYML[^\/]+\/phyml\/(configure|config.h.in)$/o,
226                                qr/^\.\/lib\/ARB\.pm$/o,
227                                qr/^\.\/lib\/arb_tcp\.dat$/o,
228                                qr/^\.\/lib\/gde\/.*\.menu$/o,
229                                qr/^\.\/lib\/nas\/names.*\.dat$/o,
230                                qr/^\.\/lib\/macros\/\.checks\/.*\.ids$/o,
231                                qr/^\.\/lib\/motifHack\/pixmaps\/.*$/o,
232                                qr/^\.\/PERL2ARB\/.*\.h$/o,
233                                qr/^\.\/PERL2ARB\/ARB\.bs$/o,
234                                qr/^\.\/PERL2ARB\/ARB\.c$/o,
235                                qr/^\.\/PERL2ARB\/ARB\.xs$/o,
236                                qr/^\.\/PERL2ARB\/Makefile$/o,
237                                qr/^\.\/PERL2ARB\/Makefile.PL$/o,
238                                qr/^\.\/PERL2ARB\/perlmain.c$/o,
239                                qr/^\.\/PERL2ARB\/pm_to_blib$/o,
240                                qr/^\.\/SOURCE_TOOLS\/valgrind2grep\.lst$/o,
241                                qr/^\.\/SOURCE_TOOLS\/stamp\./o,
242                                qr/^\.\/TEMPLATES\/arb_build\.h$/o,
243                                qr/^\.\/UNIT_TESTER\/run\/TEST_g?pt\.arb$/o,
244                                qr/^\.\/UNIT_TESTER\/run\/.*\.ARM$/o,
245                                qr/^\.\/UNIT_TESTER\/run\/.*\.ARF$/o,
246                                qr/^\.\/UNIT_TESTER\/Makefile\.setup\.local\.last$/o,
247                                qr/date\.xsl$/o,
248                               );
249
250my @forced_when_matchesFull = (
251                               qr/^\.\/bin\/Makefile/o,
252                               qr/\/PROBE_WEB\/SERVER\/.*\.jar$/o,
253                               qr/\/GDE\/PHYML[^\/]+\/phyml\/.*\.log$/o,
254                              );
255
256# files that are even packed when generated and not in VC
257my @pack_fullGenerated = (
258                          qr/\/TEMPLATES\/svn_revision\.h$/o,
259                         );
260
261# ------------------------------------------------------------
262# sanity checks
263
264foreach (keys %used_extensions) {
265  if (exists $skipped_extensions{$_}) { die "'$_' in \$used_extensions and \$skipped_extensions"; }
266}
267foreach (keys %used_files) {
268  if (exists $skipped_files{$_}) { die "'$_' in \$used_files and \$skipped_files"; }
269}
270
271# ------------------------------------------------------------
272
273sub useDir($) {
274  my ($dir) = @_;
275
276  if ($dir =~ /.svn$/o) { return 0; }
277  if ($dir =~ /CVS$/o) { return 0; }
278  foreach (@skipped_directories) {
279    if ($dir =~ $_) { return 0; }
280  }
281  return 1;
282}
283
284sub matchingExpr($\@) {
285  # return 0 if no regexp matched, return index+1 otherwise
286  my ($str,$regexp_arr_r) = @_;
287
288  my $regexps = scalar(@$regexp_arr_r);
289  for (my $r=0; $r<$regexps; $r++) {
290    my $reg = $$regexp_arr_r[$r];
291    if ($str =~ $reg) {
292      return $r+1;
293    }
294  }
295  return 0;
296}
297
298sub useIfMatching($\@\$) {
299  my ($str,$regexp_arr_r,$use_r) = @_;
300  my $matches = matchingExpr($str,@$regexp_arr_r);
301  if ($matches>0) {
302    if ($debug_matching!=0) { print "'$str' matches '".$$regexp_arr_r[$matches-1]."' => use!\n"; }
303    $$use_r = 1;
304  }
305}
306sub dontUseIfMatching($\@\$) {
307  my ($str,$regexp_arr_r,$use_r) = @_;
308  my $matches = matchingExpr($str,@$regexp_arr_r);
309  if ($matches>0) {
310    if ($debug_matching!=0) { print "'$str' matches '".$$regexp_arr_r[$matches-1]."' => don't use!\n"; }
311    $$use_r = 0;
312  }
313}
314
315sub useFile($$) {
316  my ($dir,$file) = @_;
317
318  my $use = undef;
319  if (exists $used_files{$file}) { $use = 1; }
320  elsif (exists $skipped_files{$file}) { $use = 0; }
321
322  my $hasExt = 0;
323  if (not defined $use) {
324    if ($file =~ /\.([^\.]+)$/o) {
325      my $ext = $1;
326      $hasExt = 1;
327      if (exists $used_extensions{$ext}) { $use = 1; }
328      elsif (exists $skipped_extensions{$ext}) { $use = 0; }
329    }
330  }
331
332  if (not defined $use) {
333    useIfMatching($file,@used_when_matches, $use);
334  }
335
336  if (not defined $use) {
337    dontUseIfMatching($file,@skipped_when_matches, $use);
338  }
339
340  my $full;
341  if (not defined $use) {
342    $full = $dir.'/'.$file;
343
344    useIfMatching($full,@used_when_matchesFull, $use);
345    if (not defined $use) {
346      if (-X $full and $hasExt==0) { $use = 0; } # exclude binaries by default (wrong for scripts)
347    }
348  }
349
350  if (not defined $use or $use==1) {
351    if (not defined $full) { $full = $dir.'/'.$file; }
352
353    dontUseIfMatching($full,@skipped_when_matchesFull, $use);
354  }
355  if (not defined $use or $use==0) {
356    if (not defined $full) { $full = $dir.'/'.$file; }
357    useIfMatching($full,@forced_when_matchesFull, $use);
358  }
359
360  if (not defined $use) {
361    if ($ignore_unknown==0) {
362      die "Don't know whether to use or skip '$file' (in $dir)";
363    }
364    $use = 1;
365  }
366
367  return $use;
368}
369
370# ------------------------------------------------------------
371
372my $VC_FILE    = 1;
373my $VC_DIR     = 2;
374my $VC_UNKNOWN = 3; # in SVN, but unknown whether dir or file
375
376my $svn_entries_read = 0;
377my %all_svn_entries = ();
378
379sub isSVNcheckout($) {
380  my ($dir) = @_;
381  if (-f $dir.'/.svn/entries') { return 1; }
382  if (-f $dir.'/.svn/wc.db') { return 1; }
383  return 0;
384}
385
386sub getSVNEntries($\%) {
387  my ($dir,$SVN_r) = @_;
388
389  if ($svn_entries_read==0) { # first call
390    if (isSVNcheckout($dir)==0) { return 0; }
391
392    my $cmd = "svn status -v $dir";
393    open(SVNSTATUS, "$cmd|") || die "failed to execute '$cmd' (Reason: $!)";
394
395    eval {
396      my $reg_status_line = qr/^(.*)\s+[0-9]+\s+[0-9]+\s+[^\s]+\s+([^\s]+)$/;
397
398      my $line;
399      while (defined($line=<SVNSTATUS>)) {
400        chomp($line);
401        if ($line =~ $reg_status_line) {
402          my ($flags,$name) = ($1,$2);
403          if (-f $name) {
404            $all_svn_entries{$name} = $VC_FILE;
405          }
406          elsif (-d $name) {
407            $all_svn_entries{$name} = $VC_DIR;
408          }
409          else {
410            $all_svn_entries{$name} = $VC_UNKNOWN;
411          }
412        }
413        else {
414          if ($line =~ /^?/) {
415            ; # silently ignore unknown files
416          }
417          else {
418            die "Cant parse line '$line'";
419          }
420        }
421      }
422    };
423    if ($@) {
424      die "Failed to read svn status: $@";
425    }
426
427    close(SVNSTATUS);
428    $svn_entries_read = 1;
429  }
430
431  if ($dir eq '.') {
432    foreach (keys %all_svn_entries) {
433      if (not /\//) { # root entry
434        $$SVN_r{$_} = $all_svn_entries{$_};
435      }
436    }
437  }
438  else {
439    if (not $dir =~ /^\.\//) { die "expected '$dir' to start with './'"; }
440    my $sdir = $';
441    my $reg_matchdir = qr/^$sdir\//;
442    foreach (keys %all_svn_entries) {
443      if ($_ =~ $reg_matchdir) {
444        my $rest = $';
445        if (not $rest =~ /\//) { # in $dir (not below)
446          $$SVN_r{$rest} = $all_svn_entries{$_};
447        }
448      }
449    }
450  }
451
452  return 1;
453}
454
455sub getCVSEntries($\%) {
456  my ($dir,$CVS_r) = @_;
457
458  my $cvsentries = $dir.'/CVS/Entries';
459  if (-f $cvsentries) {
460    open(CVS,'<'.$cvsentries) || die "can't read '$cvsentries' (Reason: $!)";
461    eval {
462      foreach (<CVS>) {
463        chomp;
464        if (/^D\/([^\/]+)\//o) { # directory
465          $$CVS_r{$1} = $VC_DIR;
466        }
467        elsif (/^\/([^\/]+)\//o) { # file
468          $$CVS_r{$1} = $VC_FILE;
469        }
470        elsif (/^D$/o) {
471          ;
472        }
473        else {
474          die "can't parse line '$_'";
475        }
476      }
477    };
478    if ($@) { die "$@ while reading $cvsentries"; }
479    close(CVS);
480    return 1;
481  }
482  return 0;
483}
484
485my $VC = '<no VC>';
486
487sub getVCEntries($\%) {
488  my ($dir,$VC_r) = @_;
489
490  my $res = 1;
491  if (getSVNEntries($dir,%$VC_r)==0) {
492    if (getCVSEntries($dir,%$VC_r)==0) {
493      $VC = '<no VC>';
494      $res = 0;
495    }
496    else {
497      $VC = 'CVS';
498    }
499  }
500  else {
501    $VC = 'SVN';
502  }
503
504  if (0) {
505    print "$VC entries for $dir:\n";
506    foreach (sort keys %$VC_r) {
507      print " ".$$VC_r{$_}.": $_\n";
508    }
509  }
510
511  return $res;
512}
513
514# ------------------------------------------------------------
515
516sub expectVCmember($$\%) {
517  my ($full,$item,$VC_r) = @_;
518  if ((not defined $$VC_r{$item}) and ($ignore_unknown==0)) {
519    if (not matchingExpr($full,@pack_fullGenerated)) {
520      die "'$full' ($_) included, but not in $VC (seems to be generated)";
521    }
522  }
523}
524
525my %unpackedCVSmember = map { $_ => 1; } (
526                                          '.cvsignore',
527                                          'ChangeLog',
528                                         );
529
530sub unexpectVCmember($$\%) {
531  my ($full,$item,$VC_r) = @_;
532  if (defined $$VC_r{$item}) {
533    if ((not exists $unpackedCVSmember{$item}) and ($ignore_unknown==0)) {
534      die "'$full' excluded, but in $VC";
535    }
536  }
537}
538
539sub is_version_controlled($\%) {
540  my ($item,$VC_r) = @_;
541  if (defined $$VC_r{$item}) {
542    return 1;
543  }
544  return 0;
545}
546
547sub saveAsInSVNforDir($) {
548  my ($dir) = @_;
549  foreach my $reg (@strictly_as_in_svn_when_matchesDir) {
550    if ($dir =~ $reg) {
551      return 1;
552    }
553  }
554  return 0;
555}
556
557sub dumpFiles($);
558sub dumpFiles($) {
559  my ($dir) = @_;
560
561  eval {
562    my @subdirs;
563    my @files;
564
565    my %CVS;
566    if (!getVCEntries($dir,%CVS)) {
567      die "arb_srclst.pl only works in a SVN checkout";
568    }
569
570    my $as_in_svn = saveAsInSVNforDir($dir);
571
572    opendir(DIR,$dir) || die "can't read directory '$dir' (Reason: $!)";
573    foreach (readdir(DIR)) {
574      if ($_ ne '.' and $_ ne '..') {
575        my $full = $dir.'/'.$_;
576
577        # print STDERR "full='$full' (as_in_svn=$as_in_svn)\n";
578
579        if (not -l $full) {
580          if (-d $full) {
581            if ($as_in_svn==1) {
582              if (is_version_controlled($_,%CVS)==1) {
583                push @subdirs, $full;
584              }
585            }
586            else {
587              if (useDir($full)==1) {
588                expectVCmember($full,$_,%CVS);
589                push @subdirs, $full;
590              }
591              else { unexpectVCmember($full,$_,%CVS); }
592            }
593          }
594          elsif (-f $full) {
595            if ($as_in_svn==1) {
596              if (is_version_controlled($_,%CVS)==1) {
597                push @files, $full;
598              }
599            }
600            else {
601              if (useFile($dir,$_)==1) {
602                expectVCmember($full,$_,%CVS);
603                push @files, $full;
604              }
605              else { unexpectVCmember($full,$_,%CVS); }
606            }
607          }
608          else { die "Unknown (neighter link nor file nor directory): '$full'"; }
609        }
610      }
611    }
612    closedir(DIR);
613
614    foreach (@files) { print $_."\n"; }
615    foreach (@subdirs) { dumpFiles($_); }
616  };
617  if ($@) {
618    my $err = $@;
619    if ($err =~ /at\s(.*\.pl)\sline\s([0-9]+)/) {
620      $err = "$1:$2: Error: $`";
621    }
622    $err =~ s/\n//g;
623    die "$err\n";
624  }
625}
626
627my $args = scalar(@ARGV);
628if ($args==0) {
629  dumpFiles('.');
630}
631else {
632  my $arg = $ARGV[0];
633  if ($arg eq 'ignore') {
634    $ignore_unknown = 1;
635    dumpFiles('.');
636  }
637  elsif ($arg eq 'matching') {
638    $debug_matching = 1;
639    dumpFiles('.');
640  }
641  else {
642    die "Usage: arb_srclst.pl [ignore|matching]\n";
643  }
644}
Note: See TracBrowser for help on using the repository browser.