summaryrefslogtreecommitdiffstats
path: root/perl-install/pkgs.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/pkgs.pm')
-rw-r--r--perl-install/pkgs.pm143
1 files changed, 143 insertions, 0 deletions
diff --git a/perl-install/pkgs.pm b/perl-install/pkgs.pm
new file mode 100644
index 000000000..9b9654db9
--- /dev/null
+++ b/perl-install/pkgs.pm
@@ -0,0 +1,143 @@
+package pkgs; # $Id: pkgs.pm 61999 2006-09-18 16:41:40Z tv $
+
+use strict;
+
+use common;
+use run_program;
+use detect_devices;
+use log;
+
+
+sub read_rpmsrate_raw {
+ my ($file) = @_;
+ my $line_nb = 0;
+ my $fatal_error;
+ my (%flags, %rates, @need_to_copy);
+ my (@l);
+ local $_;
+ foreach (cat_($file)) {
+ $line_nb++;
+ /\t/ and die "tabulations not allowed at line $line_nb\n";
+ s/#.*//; # comments
+
+ my ($indent, $data) = /(\s*)(.*)/;
+ next if !$data; # skip empty lines
+
+ @l = grep { $_->[0] < length $indent } @l;
+
+ my @m = @l ? @{$l[-1][1]} : ();
+ my ($t, $flag, @l2);
+ while ($data =~
+ /^((
+ [1-5]
+ |
+ (?: (?: !\s*)? [0-9A-Z_]+(?:".*?")?)
+ (?: \s*\|\|\s* (?: !\s*)? [0-9A-Z_]+(?:".*?")?)*
+ )
+ (?:\s+|$)
+ )(.*)/x) { #@")) {
+ ($t, $flag, $data) = ($1,$2,$3);
+ while ($flag =~ s,^\s*(("[^"]*"|[^"\s]*)*)\s+,$1,) {}
+ push @m, $flag;
+ push @l2, [ length $indent, [ @m ] ];
+ $indent .= $t;
+ }
+ if ($data) {
+ # has packages on same line
+ my ($rates, $flags) = partition { /^\d$/ } @m;
+ my ($rate) = @$rates or die sprintf qq(missing rate for "%s" at line %d (flags are %s)\n), $data, $line_nb, join('&&', @m);
+ foreach my $name (split ' ', $data) {
+ if (uc($name) eq $name) {
+ log::l("$name is parsed as a package name, not as a flag");
+ }
+ if (member('INSTALL', @$flags)) {
+ push @need_to_copy, $name if !member('NOCOPY', @$flags);
+ next; #- do not need to put INSTALL flag for a package.
+ }
+ if (member('PRINTER', @$flags)) {
+ push @need_to_copy, $name;
+ }
+ my @new_flags = @$flags;
+ if (my $previous = $flags{$name}) {
+ my @common = intersection($flags, $previous);
+ my @diff1 = difference2($flags, \@common);
+ my @diff2 = difference2($previous, \@common);
+ if (!@diff1 || !@diff2) {
+ @new_flags = @common;
+ } elsif (@diff1 == 1 && @diff2 == 1) {
+ @new_flags = (@common, join('||', $diff1[0], $diff2[0]));
+ } else {
+ log::l("can not handle complicate flags for packages appearing twice ($name)");
+ $fatal_error++;
+ }
+ log::l("package $name appearing twice with different rates ($rate != " . $rates{$name} . ")") if $rate != $rates{$name};
+ }
+ $rates{$name} = $rate;
+ $flags{$name} = \@new_flags;
+ }
+ push @l, @l2;
+ } else {
+ push @l, [ $l2[0][0], $l2[-1][1] ];
+ }
+ }
+ $fatal_error and die "$fatal_error fatal errors in rpmsrate";
+ \%rates, \%flags, \@need_to_copy;
+}
+
+sub read_rpmsrate {
+ my ($packages, $rpmsrate_flags_chosen, $file, $match_all_hardware) = @_;
+
+ my ($rates, $flags, $need_to_copy) = read_rpmsrate_raw($file);
+
+ my ($TYPEs, @probeall);
+ if (!$match_all_hardware) {
+ $TYPEs = detect_devices::matching_types();
+ @probeall = detect_devices::probeall();
+ }
+
+ foreach (keys %$flags) {
+ my @flags = @{$flags->{$_}};
+ my $p;
+ if ($::isInstall) {
+ $p = install::pkgs::packageByName($packages, $_) or next;
+ if (my @l = map { if_(/locales-(.*)/, qq(LOCALES"$1")) } $p->requires_nosense) {
+ if (@l > 1) {
+ log::l("ERROR: package $_ is requiring many locales") if $_ ne 'lsb';
+ } else {
+ push @flags, @l;
+ }
+ }
+ }
+
+ @flags = map {
+ my ($user_flags, $known_flags) = partition { /^!?CAT_/ } split('\|\|', $_);
+ my $ok = find {
+ my $inv = s/^!//;
+ return 0 if $::isStandalone && $inv;
+ if (my ($p) = /^HW"(.*)"/) {
+ $match_all_hardware ? 1 : ($inv xor find { $_->{description} =~ /$p/i } @probeall);
+ } elsif (($p) = /^DRIVER"(.*)"/) {
+ $match_all_hardware ? 1 : ($inv xor find { $_->{driver} =~ /$p/i } @probeall);
+ } elsif (($p) = /^TYPE"(.*)"/) {
+ $match_all_hardware ? 1 : ($inv xor $TYPEs->{$p});
+ } elsif (($p) = /^HW_CAT"(.*)"/) {
+ $match_all_hardware ? 1 : ($inv xor detect_devices::probe_category($p));
+ } else {
+ $inv xor $rpmsrate_flags_chosen->{$_};
+ }
+ } @$known_flags;
+ $ok ? 'TRUE' : @$user_flags ? join('||', @$user_flags) : 'FALSE';
+ } @flags;
+
+ if ($::isInstall) {
+ $p->set_rate($rates->{$_});
+ $p->set_rflags(member('FALSE', @flags) ? 'FALSE' : @flags);
+ } elsif ($::isStandalone) {
+ $flags->{$_} = \@flags;
+ }
+ }
+ push @{$packages->{needToCopy} ||= []}, @$need_to_copy if ref($packages);
+ return ($rates, $flags) if $::isStandalone;
+}
+
+1;