OpenPKG CVS Repository
  http://cvs.openpkg.org/
  ____________________________________________________________________________

  Server: cvs.openpkg.org                  Name:   Ralf S. Engelschall
  Root:   /e/openpkg/cvs                   Email:  [EMAIL PROTECTED]
  Module: openpkg-re                       Date:   21-Jul-2003 16:46:24
  Branch: HEAD                             Handle: 2003072115462400

  Modified files:
    openpkg-re              speclint.pl

  Log:
    and hammer it down forever: add a bunch a checks for the source
    definition and referencing

  Summary:
    Revision    Changes     Path
    1.41        +218 -0     openpkg-re/speclint.pl
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: openpkg-re/speclint.pl
  ============================================================================
  $ cvs diff -u -r1.40 -r1.41 speclint.pl
  --- openpkg-re/speclint.pl    21 Jul 2003 12:18:10 -0000      1.40
  +++ openpkg-re/speclint.pl    21 Jul 2003 14:46:24 -0000      1.41
  @@ -105,6 +105,7 @@
       preproc
       script
       global
  +    sources
   ));
   my @checks = ();
   if ($check eq 'all') {
  @@ -887,6 +888,223 @@
           $done .= $`; $this = $&; $todo = $';
           &lint_warning($file, $done, $this, "found constant \"root\" in %attr 
(expected variable %{l_susr})");
           $done .= $this;
  +    }
  +}
  +
  +##  _________________________________________________________________
  +##
  +##  CHECK "sources": source file consistency
  +##  _________________________________________________________________
  +##
  +
  +sub check_sources {
  +    my ($file, $spec) = @_;
  +
  +    ## 
  +    ##  PREPARATION
  +    ##
  +
  +    my $D = {};
  +    my $S = {};
  +    my $i = 99;
  +
  +    #   determine defines values
  +    my $done = ''; my $this = ''; my $todo = $spec;
  +    while ($todo =~ m/^\%(define|option)\s+(\S+)\s+(.+)\s*$/m) {
  +        $done .= $`; $this = $&; $todo = $';
  +        my ($var, $val) = ($2, $3);
  +        $val =~ s|(\%\{([a-zA-Z_][a-zA-Z0-9_]*)\})|defined($D->{$2}) ? $D->{$2} : 
$1|sge;
  +        $D->{$var} = $val;
  +        $done .= $this;
  +    }
  +    $done = ''; $this = ''; $todo = $spec;
  +    while ($todo =~ m/^([a-zA-Z][a-zA-Z0-9_]+):\s+(.*)$/m) {
  +        $done .= $`; $this = $&; $todo = $';
  +        my ($var, $val) = (lc($1), $2);
  +        $val =~ s|(\%\{([a-zA-Z_][a-zA-Z0-9_]*)\})|defined($D->{$2}) ? $D->{$2} : 
$1|sge;
  +        $D->{$var} = $val;
  +        $done .= $this;
  +    }
  +
  +    #   expand define values (allow one level of nesting)
  +    $spec =~ s|(\%\{([a-zA-Z_][a-zA-Z0-9_]*)\})|defined($D->{$2}) ? $D->{$2} : 
$1|sge;
  +    $spec =~ s|(\%\{([a-zA-Z_][a-zA-Z0-9_]*)\})|defined($D->{$2}) ? $D->{$2} : 
$1|sge;
  +
  +    #   parse Source# and Patch# headers
  +    $done = ''; $this = ''; $todo = $spec;
  +    while ($todo =~ m/^(Source|Patch)(\d+):[ \t]*(.*?)$/m) {
  +        $done .= $`; $this = $&; $todo = $';
  +        my ($type, $num, $file) = (lc($1), $2, $3);
  +        my $url = "";
  +        if ($file =~ m|^(.+/)([^/]+)$|s) {
  +            ($url, $file) = ($1, $2);
  +        }
  +        if (not defined($S->{"$type$num"})) {
  +            $S->{"$type$num"} = {
  +                -type   => $type,
  +                -num    => $num,
  +                -url    => $url,
  +                -file   => $file,
  +                -refhdr => 1,
  +                -refcmd => 0,
  +                -refmac => 0,
  +                -refvar => 0,
  +            };
  +        }
  +        else {
  +            $S->{"$type$num"}->{-refhdr}++;
  +        }
  +        $done .= $this;
  +    }
  +
  +    #   parse %setup and %patch commands
  +    $done = ''; $this = ''; $todo = $spec;
  +    while ($todo =~ m/^\s*\%(setup|patch)(\d+)?(\s+.*)?$/m) {
  +        $done .= $`; $this = $&; $todo = $';
  +        my ($type, $num, $opts) = ($1, $2, $3);
  +        $type = 'source' if ($type eq 'setup');
  +        my $num_force = '';
  +        if ($opts =~ m/\s-(?:a|b)\s*(\d+)/s) {
  +            $num_force = $1;
  +        }
  +        if ($num ne '' and $num_force ne '' and $num ne $num_force) {
  +            &lint_warning($file, $done, $this, "macro and enforced $type number 
conflict: $num <-> $num_force" .
  +                        " (expected either just enforced number or make them 
match)");
  +        }
  +        $num = $num_force if ($num_force ne '');
  +        $num = 0 if ($num eq '');
  +        next if ($opts =~ m|\s-T|s and $num == 0);
  +        if (not defined($S->{"$type$num"})) {
  +            $S->{"$type$num"} = {
  +                -type   => $type,
  +                -num    => $num,
  +                -url    => "",
  +                -file   => "",
  +                -refhdr => 0,
  +                -refcmd => 1,
  +                -refmac => 0,
  +                -refvar => 0,
  +            };
  +        }
  +        else {
  +            $S->{"$type$num"}->{-refcmd}++;
  +        }
  +        $done .= $this;
  +    }
  +
  +    #   parse %{SOURCE#} and %{PATCH#} macros
  +    $done = ''; $this = ''; $todo = $spec;
  +    while ($todo =~ m/\%\{(SOURCE|PATCH)(\d+)\}/m) {
  +        $done .= $`; $this = $&; $todo = $';
  +        my ($type, $num) = (lc($1), $2);
  +        if (not defined($S->{"$type$num"})) {
  +            $S->{"$type$num"} = {
  +                -type   => $type,
  +                -num    => $num,
  +                -url    => "",
  +                -file   => "",
  +                -refhdr => 0,
  +                -refcmd => 0,
  +                -refmac => 1,
  +                -refvar => 0,
  +            };
  +        }
  +        else {
  +            $S->{"$type$num"}->{-refmac}++;
  +        }
  +        $done .= $this;
  +    }
  +
  +    #   parse %{SOURCE ...} and %{PATCH ...} macros
  +    $done = ''; $this = ''; $todo = $spec;
  +    while ($todo =~ m/\%\{(SOURCE|PATCH)\s+([^\s}]+)\}/m) {
  +        $done .= $`; $this = $&; $todo = $';
  +        my ($type, $file) = (lc($1), $2);
  +        my $key = "";
  +        foreach my $src (keys(%{$S})) {
  +            if ($S->{$src}->{-type} eq $type and $S->{$src}->{-file} eq $file) {
  +                $key = $src;
  +            }
  +        }
  +        if ($key eq '') {
  +            $S->{"$type$i"} = {
  +                -type   => $type,
  +                -num    => $i,
  +                -url    => "",
  +                -file   => $file,
  +                -refhdr => 0,
  +                -refcmd => 0,
  +                -refmac => 1,
  +                -refvar => 0,
  +            };
  +            $i++;
  +        }
  +        else {
  +            $S->{$key}->{-refmac}++;
  +        }
  +        $done .= $this;
  +    }
  +
  +    #   parse $RPM_SOURCE_DIR based references
  +    $done = ''; $this = ''; $todo = $spec;
  +    while ($todo =~ m/\$RPM_SOURCE_DIR\/([^\s;"']+)/m) {
  +        $done .= $`; $this = $&; $todo = $';
  +        my ($file) = ($1);
  +        my $key = "";
  +        foreach my $src (keys(%{$S})) {
  +            if ($S->{$src}->{-file} eq $file) {
  +                $key = $src;
  +            }
  +        }
  +        if ($key eq '') {
  +            $S->{"source$i"} = {
  +                -type   => "source",
  +                -num    => $i,
  +                -url    => "",
  +                -file   => $file,
  +                -refhdr => 0,
  +                -refcmd => 0,
  +                -refmac => 0,
  +                -refvar => 1,
  +            };
  +            $i++;
  +        }
  +        else {
  +            $S->{$key}->{-refmac}++;
  +        }
  +        $done .= $this;
  +    }
  +
  +    ##
  +    ##  CHECKING
  +    ##
  +
  +    #   check refernce counts
  +    foreach my $src (%{$S}) {
  +        my $s = $S->{$src};
  +        my $str_hdr = ($s->{-type} eq 'source' ? 'Source' : 'Patch' ) . $s->{-num};
  +        my $str_cmd = ($s->{-type} eq 'source' ? '%setup' : '%patch') . $s->{-num};
  +        my $str_mac = ($s->{-type} eq 'source' ? '%{SOURCE ...}' : '%{PATCH ...}');
  +        my $str_var = "\$RPM_SOURCE_DIR";
  +        if ($file !~ m/\b(openpkg-.*|openpkg|vim|ncurses|openssh)\.spec$/) {
  +            if ($s->{-refhdr} > 0) {
  +                if ($s->{-refcmd} == 0 and $s->{-refmac} == 0 and $s->{-refmac} == 
0) {
  +                    &lint_error($file, undef, undef, "source \"$str_hdr\" defined 
(file $s->{-file}), but never used" .
  +                                " (expected at least one reference via 
\"$str_cmd\", \"$str_mac\" or \"$str_var\")");
  +                }
  +                elsif ($s->{-refcmd} > 1) {
  +                    &lint_error($file, undef, undef, "source \"$str_hdr\" defined 
(file $s->{-file}), but used multiple times" .
  +                                " (expected just one reference via \"$str_cmd\")");
  +                }
  +            }
  +            else {
  +                if ($s->{-refcmd}+$s->{-refmac}+$s->{-refmac} > 0) {
  +                    &lint_error($file, undef, undef, "source \"$str_hdr\" not 
defined, but used ".
  +                                ($s->{-file} ? "(file ".$s->{-file}.")" : "").
  +                                " (expected at least one definition via 
\"$str_hdr\")");
  +                }
  +            }
  +        }
       }
   }
   
  @@ .
______________________________________________________________________
The OpenPKG Project                                    www.openpkg.org
CVS Repository Commit List                     [EMAIL PROTECTED]

Reply via email to