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: 24-Mar-2003 12:07:42 Branch: HEAD Handle: 2003032411074200 Modified files: openpkg-re speclint.pl Log: work off internals and add first cut for real header checking Summary: Revision Changes Path 1.2 +75 -46 openpkg-re/speclint.pl ____________________________________________________________________________ patch -p0 <<'@@ .' Index: openpkg-re/speclint.pl ============================================================================ $ cvs diff -u -r1.1 -r1.2 speclint.pl --- openpkg-re/speclint.pl 5 Mar 2003 16:21:17 -0000 1.1 +++ openpkg-re/speclint.pl 24 Mar 2003 11:07:42 -0000 1.2 @@ -121,7 +121,6 @@ || "unable to open file \"$filename\" for reading"; my $spec; { local $/ = undef; $spec = <$io>; } $io->close; - foreach my $check (@checks) { eval "\&check_$check(\$filename, \$spec);"; } @@ -143,13 +142,16 @@ sub lint_message { my ($type, $file, $done, $this, $msg) = @_; - my $start = &lines($done) + 1; - my $end = $start + &lines($this); - my $pos = $start; - if ($end > $start) { - $pos .= "-". $end; + if (defined($done) and defined($this)) { + my $start = &lines($done) + 1; + my $end = $start + &lines($this); + my $pos = $start; + $pos .= "-". $end if ($end > $start); + printf("%s:%s: %s:%s: %s\n", $progname, $type, $file, $pos, $msg); + } + else { + printf("%s:%s: %s: %s\n", $progname, $type, $file, $msg); } - printf("%s: %s:%s: %s\n", $type, $file, $pos, $msg); } sub lint_warning { @@ -172,30 +174,24 @@ my ($file, $spec) = @_; # check for CR-LF combination - my $done = ''; - my $todo = $spec; + my $done = ''; my $this = ''; my $todo = $spec; while ($todo =~ m/\r\n/s) { - $done .= $`; - &lint_warning($file, $done, $&, "carriage-return (CR, 0x0d) line-feed (NL, 0x0a) combination (expected just line-feed)"); - $todo = $'; + $done .= $`; $this = $&; $todo = $'; + &lint_warning($file, $done, $this, "carriage-return (CR, 0x0d) line-feed (NL, 0x0a) combination (expected just line-feed)"); } # check for multiple blank lines - $done = ''; - $todo = $spec; + $done = ''; $this = ''; $todo = $spec; while ($todo =~ m/(\r?\n[ \t]*){3,}/s) { - $done .= $`; - &lint_warning($file, $done, $&, "multiple subsequent blank lines (expected single blank line)"); - $todo = $'; + $done .= $`; $this = $&; $todo = $'; + &lint_warning($file, $done, $this, "multiple subsequent blank lines (expected single blank line)"); } # check for trailing whitespaces - $done = ''; - $todo = $spec; + $done = ''; $this = ''; $todo = $spec; while ($todo =~ m/[ \t]+\r?\n/s) { - $done .= $`; - &lint_warning($file, $done, $&, "trailing whitespace (expected none)"); - $todo = $'; + $done .= $`; $this = $&; $todo = $'; + &lint_warning($file, $done, $this, "trailing whitespace (expected none)"); } } @@ -209,12 +205,9 @@ my ($file, $spec) = @_; # check for comment indentation - my $done = ''; - my $todo = $spec; + my $done = ''; my $this = ''; my $todo = $spec; while ($todo =~ m/^([ \t]*)(#+)([ \t]*)(.*?)$/m) { - $done .= $`; - my $this = $&; - $todo = $'; + $done .= $`; $this = $&; $todo = $'; my ($lead, $sharp, $pad, $text) = ($1, $2, $3, $4); if (length($lead) % 2 != 0) { &lint_warning($file, $done, $this, "incorrect comment indentation (expected a multiple of 2 spaces)"); @@ -283,31 +276,67 @@ my ($file, $spec) = @_; my @headers = (qw( - Name Summary URL Vendor Packager Distribution Group License Version Release - Source\d+ Patch\d+ - Prefix BuildRoot - BuildPreReq PreReq - AutoReq AutoReqProv - Provides Conflicts + m:Name:^[a-z][a-z0-9-]*$ + m:Summary:^[A-Z].+ + m:URL:^((https?|ftp)://.+|-)$ + m:Vendor:.+ + m:Packager:^The\sOpenPKG\sProject$ + m:Distribution:^OpenPKG\s\[(CORE|BASE|PLUS|EVAL|JUNK)\]$ + m:Group:^[A-Z][a-zA-Z0-9]+$ + m:License:.+ + m:Version:^[^-]+$ + m:Release:^(([1-9]\.)?20[0-9][0-9](0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[01])|[1-9]\.[0-9]\.\d+)$ + m:Source\d+:^((https?|ftp)://.+|[^/]+)$ + o:Patch\d+:^((https?|ftp)://.+|[^/]+)$ + m:Prefix:^%{l_prefix}$ + m:BuildRoot:^%{l_buildroot}$ + m:BuildPreReq:^(OpenPKG,\sopenpkg\s>=\s\S+)?((,\s)?([a-z][a-z0-9-]*(\:\:with_[a-z][a-z0-9_]+)?|[A-Z][A-Z0-9-]*)(\s(>=?|==?|<=?|!=)\s\S+)?)+$ + m:PreReq:^(OpenPKG,\sopenpkg\s>=\s\S+)?((,\s)?([a-z][a-z0-9-]*(\:\:with_[a-z][a-z0-9_]+)?|[A-Z][A-Z0-9-]*)(\s(>=?|==?|<=?|!=)\s\S+)?)+$ + m:AutoReq:^no$ + m:AutoReqProv:^no$ + o:Provides:^((,\s)?([a-z][a-z0-9-]*(\:\:with_[a-z][a-z0-9_]+)?|[A-Z][A-Z0-9-]*)(\s==?\s\S+)?)+$ + o:Conflicts:^((,\s)?([a-z][a-z0-9-]*(\:\:with_[a-z][a-z0-9_]+)?|[A-Z][A-Z0-9-]*)(\s(>=?|==?|<=?|!=)\s\S+)?)+$ )); - # check for comment indentation - my $done = ''; - my $todo = $spec; + my @seen = (); + my $done = ''; my $this = ''; my $todo = $spec; while ($todo =~ m/^(\S+):([ \t]*)(.*?)$/m) { - $done .= $`; - my $this = $&; - $todo = $'; + $done .= $`; $this = $&; $todo = $'; my ($header, $pad, $value) = ($1, $2, $3); - my $ok = 0; - foreach my $h (@headers) { - if ($header =~ m|^$h$|s) { - $ok = 1; - last; + + # check for layouting + if (length($value) == 0) { + &lint_error($file, $done, $this, "empty RPM header value"); + } + if (length($header.":".$pad) != 14) { + &lint_warning($file, $done, $this, "invalid RPM header name/value padding (expected value at column 15)"); + } + + # check for valid header name and value + if (not grep { $header =~ m|^$_$|s } map { m/^[^:]:([^:]+):/, $1 } @headers) { + &lint_error($file, $done, $this, "invalid RPM header name \"$header\""); + } + else { + my $hn = quotemeta((grep { $header =~ m|^$_$|s } map { m/^[^:]+:([^:]+):/, $1 } @headers)[0]); + my $re = (map { m/^[^:]+:${hn}:(.+)$/s } @headers)[0]; + my $re_match = $re; + $re_match =~ s|^\(|(?:|sg; + $re_match =~ s|([^\\])\(|\1(?:|sg; + if ($value !~ m|${re_match}|s) { + &lint_error($file, $done, $this, "RPM header \"$header\": " . + "invalid value \"$value\" (expected to match \"$re\""); } } - if (not $ok) { - &lint_error($file, $done, $this, "invalid header \"$header\""); + push(@seen, $header); + } + + # check for existence of mandatory headers + foreach my $header (@headers) { + my ($type, $name, $regex) = split(/:/, $header, 3); + if ($type eq 'm') { + if (not grep(/^$name$/, @seen)) { + &lint_error($file, undef, undef, "mandatory RPM header \"$name\" not found"); + } } } } @@ . ______________________________________________________________________ The OpenPKG Project www.openpkg.org CVS Repository Commit List [EMAIL PROTECTED]