source: tags/terminal-6.x/util/arb_srclst.pl

Last change on this file was 15215, 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.5 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\/desktop\/.*$/o,
198                             qr/^\.\/lib\/export\/.*\.eft$/o,
199                             qr/^\.\/lib\/import\/.*\.ift2?$/o,
200                             qr/^\.\/lib\/inputMasks\/.*\.mask$/o,
201                             qr/^\.\/lib\/macros\/.*\.amc$/o,
202                             qr/^\.\/lib\/macros\/.checks\/.*\.expected$/o,
203                             qr/^\.\/lib\/nas\/names\.dat\.template$/o,
204                             qr/^\.\/lib\/pictures\/.*\.(fig|vfont)$/o,
205                             qr/^\.\/lib\/pixmaps\/.*\.xpm$/o,
206                             qr/^\.\/lib\/protein_2nd_structure\/.*\.dat$/o,
207                             qr/^\.\/lib\/rna3d\/.*\.(pdb|data)$/o,
208                             qr/^\.\/lib\/rna3d\/images\/.*\.png$/o,
209                             qr/^\.\/lib\/sellists\/.*\.sellst$/o,
210                             qr/^\.\/lib\/submit\//o,
211                             qr/^\.\/lib\/BUGS\//o,
212                             qr/^\.\/util\/arb_.*$/o,
213                             qr/^\.\/util\/config\..*$/o,
214                             qr/\/GDE\/.*\/Makefile\.[^\/]+$/io,
215                             qr/\/GDE\/PHYML[^\/]+\/phyml\//o,
216                            );
217
218# skipped_when_matchesFull and forced_when_matchesFull are always tested! (@3)
219
220my @skipped_when_matchesFull = (
221                                qr/\/genhelp\/.*\.hlp$/o,
222                                qr/\/lib\/addlibs\/(lib.*\.so\..*)$/o,
223                                qr/^\.\/arb.*\.tgz$/o,
224                                qr/^\.\/bin\//o,
225                                qr/^\.\/GDE\/CORE\/functions.h$/o,
226                                qr/^\.\/GDE\/PHYML[^\/]+\/phyml\/(configure|config.h.in)$/o,
227                                qr/^\.\/lib\/ARB\.pm$/o,
228                                qr/^\.\/lib\/arb_tcp\.dat$/o,
229                                qr/^\.\/lib\/gde\/.*\.menu$/o,
230                                qr/^\.\/lib\/nas\/names.*\.dat$/o,
231                                qr/^\.\/lib\/macros\/\.checks\/.*\.ids$/o,
232                                qr/^\.\/lib\/motifHack\/pixmaps\/.*$/o,
233                                qr/^\.\/PERL2ARB\/.*\.h$/o,
234                                qr/^\.\/PERL2ARB\/ARB\.bs$/o,
235                                qr/^\.\/PERL2ARB\/ARB\.c$/o,
236                                qr/^\.\/PERL2ARB\/ARB\.xs$/o,
237                                qr/^\.\/PERL2ARB\/Makefile$/o,
238                                qr/^\.\/PERL2ARB\/Makefile.PL$/o,
239                                qr/^\.\/PERL2ARB\/perlmain.c$/o,
240                                qr/^\.\/PERL2ARB\/pm_to_blib$/o,
241                                qr/^\.\/SOURCE_TOOLS\/valgrind2grep\.lst$/o,
242                                qr/^\.\/SOURCE_TOOLS\/stamp\./o,
243                                qr/^\.\/TEMPLATES\/arb_build\.h$/o,
244                                qr/^\.\/UNIT_TESTER\/run\/TEST_g?pt\.arb$/o,
245                                qr/^\.\/UNIT_TESTER\/run\/.*\.ARM$/o,
246                                qr/^\.\/UNIT_TESTER\/run\/.*\.ARF$/o,
247                                qr/^\.\/UNIT_TESTER\/Makefile\.setup\.local\.last$/o,
248                                qr/date\.xsl$/o,
249                               );
250
251my @forced_when_matchesFull = (
252                               qr/^\.\/bin\/Makefile/o,
253                               qr/\/PROBE_WEB\/SERVER\/.*\.jar$/o,
254                               qr/\/GDE\/PHYML[^\/]+\/phyml\/.*\.log$/o,
255                               qr/\/HEADERLIBS\/.*\.patch$/o,
256                              );
257
258# files that are even packed when generated and not in VC
259my @pack_fullGenerated = (
260                          qr/\/TEMPLATES\/svn_revision\.h$/o,
261                         );
262
263# ------------------------------------------------------------
264# sanity checks
265
266foreach (keys %used_extensions) {
267  if (exists $skipped_extensions{$_}) { die "'$_' in \$used_extensions and \$skipped_extensions"; }
268}
269foreach (keys %used_files) {
270  if (exists $skipped_files{$_}) { die "'$_' in \$used_files and \$skipped_files"; }
271}
272
273# ------------------------------------------------------------
274
275sub useDir($) {
276  my ($dir) = @_;
277
278  if ($dir =~ /.svn$/o) { return 0; }
279  if ($dir =~ /CVS$/o) { return 0; }
280  foreach (@skipped_directories) {
281    if ($dir =~ $_) { return 0; }
282  }
283  return 1;
284}
285
286sub matchingExpr($\@) {
287  # return 0 if no regexp matched, return index+1 otherwise
288  my ($str,$regexp_arr_r) = @_;
289
290  my $regexps = scalar(@$regexp_arr_r);
291  for (my $r=0; $r<$regexps; $r++) {
292    my $reg = $$regexp_arr_r[$r];
293    if ($str =~ $reg) {
294      return $r+1;
295    }
296  }
297  return 0;
298}
299
300sub useIfMatching($\@\$) {
301  my ($str,$regexp_arr_r,$use_r) = @_;
302  my $matches = matchingExpr($str,@$regexp_arr_r);
303  if ($matches>0) {
304    if ($debug_matching!=0) { print "'$str' matches '".$$regexp_arr_r[$matches-1]."' => use!\n"; }
305    $$use_r = 1;
306  }
307}
308sub dontUseIfMatching($\@\$) {
309  my ($str,$regexp_arr_r,$use_r) = @_;
310  my $matches = matchingExpr($str,@$regexp_arr_r);
311  if ($matches>0) {
312    if ($debug_matching!=0) { print "'$str' matches '".$$regexp_arr_r[$matches-1]."' => don't use!\n"; }
313    $$use_r = 0;
314  }
315}
316
317sub useFile($$) {
318  my ($dir,$file) = @_;
319
320  my $use = undef;
321  if (exists $used_files{$file}) { $use = 1; }
322  elsif (exists $skipped_files{$file}) { $use = 0; }
323
324  my $hasExt = 0;
325  if (not defined $use) {
326    if ($file =~ /\.([^\.]+)$/o) {
327      my $ext = $1;
328      $hasExt = 1;
329      if (exists $used_extensions{$ext}) { $use = 1; }
330      elsif (exists $skipped_extensions{$ext}) { $use = 0; }
331    }
332  }
333
334  if (not defined $use) {
335    useIfMatching($file,@used_when_matches, $use);
336  }
337
338  if (not defined $use) {
339    dontUseIfMatching($file,@skipped_when_matches, $use);
340  }
341
342  my $full;
343  if (not defined $use) {
344    $full = $dir.'/'.$file;
345
346    useIfMatching($full,@used_when_matchesFull, $use);
347    if (not defined $use) {
348      if (-X $full and $hasExt==0) { $use = 0; } # exclude binaries by default (wrong for scripts)
349    }
350  }
351
352  if (not defined $use or $use==1) {
353    if (not defined $full) { $full = $dir.'/'.$file; }
354
355    dontUseIfMatching($full,@skipped_when_matchesFull, $use);
356  }
357  if (not defined $use or $use==0) {
358    if (not defined $full) { $full = $dir.'/'.$file; }
359    useIfMatching($full,@forced_when_matchesFull, $use);
360  }
361
362  if (not defined $use) {
363    if ($ignore_unknown==0) {
364      die "Don't know whether to use or skip '$file' (in $dir)";
365    }
366    $use = 1;
367  }
368
369  return $use;
370}
371
372# ------------------------------------------------------------
373
374my $VC_FILE    = 1;
375my $VC_DIR     = 2;
376my $VC_UNKNOWN = 3; # in SVN, but unknown whether dir or file
377
378my $svn_entries_read = 0;
379my %all_svn_entries = ();
380
381sub isSVNcheckout($) {
382  my ($dir) = @_;
383  if (-f $dir.'/.svn/entries') { return 1; }
384  if (-f $dir.'/.svn/wc.db') { return 1; }
385  return 0;
386}
387
388sub getSVNEntries($\%) {
389  my ($dir,$SVN_r) = @_;
390
391  if ($svn_entries_read==0) { # first call
392    if (isSVNcheckout($dir)==0) { return 0; }
393
394    my $cmd = "svn status -v $dir";
395    open(SVNSTATUS, "$cmd|") || die "failed to execute '$cmd' (Reason: $!)";
396
397    eval {
398      my $reg_status_line = qr/^(.*)\s+[0-9]+\s+[0-9]+\s+[^\s]+\s+([^\s]+)$/;
399
400      my $line;
401      while (defined($line=<SVNSTATUS>)) {
402        chomp($line);
403        if ($line =~ $reg_status_line) {
404          my ($flags,$name) = ($1,$2);
405          if (-f $name) {
406            $all_svn_entries{$name} = $VC_FILE;
407          }
408          elsif (-d $name) {
409            $all_svn_entries{$name} = $VC_DIR;
410          }
411          else {
412            $all_svn_entries{$name} = $VC_UNKNOWN;
413          }
414        }
415        else {
416          if ($line =~ /^?/) {
417            ; # silently ignore unknown files
418          }
419          else {
420            die "Cant parse line '$line'";
421          }
422        }
423      }
424    };
425    if ($@) {
426      die "Failed to read svn status: $@";
427    }
428
429    close(SVNSTATUS);
430    $svn_entries_read = 1;
431  }
432
433  if ($dir eq '.') {
434    foreach (keys %all_svn_entries) {
435      if (not /\//) { # root entry
436        $$SVN_r{$_} = $all_svn_entries{$_};
437      }
438    }
439  }
440  else {
441    if (not $dir =~ /^\.\//) { die "expected '$dir' to start with './'"; }
442    my $sdir = $';
443    my $reg_matchdir = qr/^$sdir\//;
444    foreach (keys %all_svn_entries) {
445      if ($_ =~ $reg_matchdir) {
446        my $rest = $';
447        if (not $rest =~ /\//) { # in $dir (not below)
448          $$SVN_r{$rest} = $all_svn_entries{$_};
449        }
450      }
451    }
452  }
453
454  return 1;
455}
456
457sub getCVSEntries($\%) {
458  my ($dir,$CVS_r) = @_;
459
460  my $cvsentries = $dir.'/CVS/Entries';
461  if (-f $cvsentries) {
462    open(CVS,'<'.$cvsentries) || die "can't read '$cvsentries' (Reason: $!)";
463    eval {
464      foreach (<CVS>) {
465        chomp;
466        if (/^D\/([^\/]+)\//o) { # directory
467          $$CVS_r{$1} = $VC_DIR;
468        }
469        elsif (/^\/([^\/]+)\//o) { # file
470          $$CVS_r{$1} = $VC_FILE;
471        }
472        elsif (/^D$/o) {
473          ;
474        }
475        else {
476          die "can't parse line '$_'";
477        }
478      }
479    };
480    if ($@) { die "$@ while reading $cvsentries"; }
481    close(CVS);
482    return 1;
483  }
484  return 0;
485}
486
487my $VC = '<no VC>';
488
489sub getVCEntries($\%) {
490  my ($dir,$VC_r) = @_;
491
492  my $res = 1;
493  if (getSVNEntries($dir,%$VC_r)==0) {
494    if (getCVSEntries($dir,%$VC_r)==0) {
495      $VC = '<no VC>';
496      $res = 0;
497    }
498    else {
499      $VC = 'CVS';
500    }
501  }
502  else {
503    $VC = 'SVN';
504  }
505
506  if (0) {
507    print "$VC entries for $dir:\n";
508    foreach (sort keys %$VC_r) {
509      print " ".$$VC_r{$_}.": $_\n";
510    }
511  }
512
513  return $res;
514}
515
516# ------------------------------------------------------------
517
518sub expectVCmember($$\%) {
519  my ($full,$item,$VC_r) = @_;
520  if ((not defined $$VC_r{$item}) and ($ignore_unknown==0)) {
521    if (not matchingExpr($full,@pack_fullGenerated)) {
522      die "'$full' ($_) included, but not in $VC (seems to be generated)";
523    }
524  }
525}
526
527my %unpackedCVSmember = map { $_ => 1; } (
528                                          '.cvsignore',
529                                          'ChangeLog',
530                                         );
531
532sub unexpectVCmember($$\%) {
533  my ($full,$item,$VC_r) = @_;
534  if (defined $$VC_r{$item}) {
535    if ((not exists $unpackedCVSmember{$item}) and ($ignore_unknown==0)) {
536      die "'$full' excluded, but in $VC";
537    }
538  }
539}
540
541sub is_version_controlled($\%) {
542  my ($item,$VC_r) = @_;
543  if (defined $$VC_r{$item}) {
544    return 1;
545  }
546  return 0;
547}
548
549sub saveAsInSVNforDir($) {
550  my ($dir) = @_;
551  foreach my $reg (@strictly_as_in_svn_when_matchesDir) {
552    if ($dir =~ $reg) {
553      return 1;
554    }
555  }
556  return 0;
557}
558
559sub dumpFiles($);
560sub dumpFiles($) {
561  my ($dir) = @_;
562
563  eval {
564    my @subdirs;
565    my @files;
566
567    my %CVS;
568    if (!getVCEntries($dir,%CVS)) {
569      die "arb_srclst.pl only works in a SVN checkout";
570    }
571
572    my $as_in_svn = saveAsInSVNforDir($dir);
573
574    opendir(DIR,$dir) || die "can't read directory '$dir' (Reason: $!)";
575    foreach (readdir(DIR)) {
576      if ($_ ne '.' and $_ ne '..') {
577        my $full = $dir.'/'.$_;
578
579        # print STDERR "full='$full' (as_in_svn=$as_in_svn)\n";
580
581        if (not -l $full) {
582          if (-d $full) {
583            if ($as_in_svn==1) {
584              if (is_version_controlled($_,%CVS)==1) {
585                push @subdirs, $full;
586              }
587            }
588            else {
589              if (useDir($full)==1) {
590                expectVCmember($full,$_,%CVS);
591                push @subdirs, $full;
592              }
593              else { unexpectVCmember($full,$_,%CVS); }
594            }
595          }
596          elsif (-f $full) {
597            if ($as_in_svn==1) {
598              if (is_version_controlled($_,%CVS)==1) {
599                push @files, $full;
600              }
601            }
602            else {
603              if (useFile($dir,$_)==1) {
604                expectVCmember($full,$_,%CVS);
605                push @files, $full;
606              }
607              else { unexpectVCmember($full,$_,%CVS); }
608            }
609          }
610          else { die "Unknown (neighter link nor file nor directory): '$full'"; }
611        }
612      }
613    }
614    closedir(DIR);
615
616    foreach (@files) { print $_."\n"; }
617    foreach (@subdirs) { dumpFiles($_); }
618  };
619  if ($@) {
620    my $err = $@;
621    if ($err =~ /at\s(.*\.pl)\sline\s([0-9]+)/) {
622      $err = "$1:$2: Error: $`";
623    }
624    $err =~ s/\n//g;
625    die "$err\n";
626  }
627}
628
629my $args = scalar(@ARGV);
630if ($args==0) {
631  dumpFiles('.');
632}
633else {
634  my $arg = $ARGV[0];
635  if ($arg eq 'ignore') {
636    $ignore_unknown = 1;
637    dumpFiles('.');
638  }
639  elsif ($arg eq 'matching') {
640    $debug_matching = 1;
641    dumpFiles('.');
642  }
643  else {
644    die "Usage: arb_srclst.pl [ignore|matching]\n";
645  }
646}
Note: See TracBrowser for help on using the repository browser.