#!/usr/bin/perl # ./merge_MonitorsDB.pl ../../monitor-edid/test/new_MonitorsDB ../lst/MonitorsDB > MonitorsDB.new # diff -u ../lst/MonitorsDB MonitorsDB.new @ARGV == 2 or die "usage: $0 [--verif | <entries to add>] <mdk MonitorsDB>\n"; my ($to_add, $MonitorsDB) = @ARGV; my $verif = $to_add eq '--verif'; use MDK::Common; my $monitors_db = readMonitorsDB($MonitorsDB); if ($verif) { verif($monitors_db); } else { my $to_add = readMonitorsDB($to_add); rationalize_EISA_ID($_) foreach @$to_add, @$monitors_db; my %EISA_ID_to_VendorName = EISA_ID_to_VendorName($monitors_db); foreach (@$to_add) { my $VendorName = $_->{EISA_ID} =~ /(...)/ && $EISA_ID_to_VendorName{$1} or next; $_->{ModelName} =~ s/^(\Q$_->{VendorName}\E|\Q$VendorName\E)\s//i; $_->{VendorName} = $VendorName; $_->{ModelName} = "$VendorName $_->{ModelName}"; $_->{text} = join_line($_); } #- first see if the EISA_ID is already there my %to_add = map { $_->{EISA_ID} => $_ } @$to_add; foreach (@$monitors_db) { $to_add{$_->{EISA_ID}} or next; $_->{text} =~ s!.*\n$!$to_add{$_->{EISA_ID}}{text}!; delete $to_add{$_->{EISA_ID}}; } my @to_add = sort { lc($a->{text}) cmp lc($b->{text}) } values %to_add; foreach (@$monitors_db) { while (@to_add && lc("$to_add[0]{VendorName}; $to_add[0]{ModelName}") lt lc("$_->{VendorName}; $_->{ModelName}")) { $_->{text} = (shift @to_add)->{text} . $_->{text}; } } print $_->{text} foreach (@$monitors_db, @to_add); } sub verif { my ($monitors_db) = @_; my %l; foreach my $e (@$monitors_db) { rationalize_EISA_ID($e, sub { my ($previous) = @{$l{$e->{EISA_ID}} || []} or return; my @vs = map { $e->{$_} eq $previous->{$_} ? () : "$e->{$_} vs $previous->{$_}"; } 'ModelName', 'HorizSync', 'VertRefresh'; warn "$e->{lineno}: duplicate $e->{EISA_ID}: " . (@vs ? join(", ", @vs) : $e->{ModelName}) . "\n"; }); push @{$l{$e->{EISA_ID}}}, $e; } } sub rationalize_EISA_ID { my ($e, $o_verif) = @_; if ($e->{EISA_ID} =~ /^([A-Z]{3})([0-9a-f]{4})$/i) { # perfect! $e->{EISA_ID} = uc($1) . lc($2); $o_verif and $o_verif->(); } elsif ($e->{EISA_ID} eq '0') { # ok } elsif ($e->{EISA_ID} =~ /^([a-z]{3})([0-9a-f]{0,3})$/i) { # we can correct this (?) warn sprintf("$e->{lineno}: $e->{EISA_ID} should be %s%04x\n", $1, hex($2)) if $verif; } else { warn "$e->{lineno}: bad EISA_ID $e->{EISA_ID}\n" if $o_verif; } } sub EISA_ID_to_VendorName { my ($monitors_db) = @_; my %l; foreach (@$monitors_db) { $_->{EISA_ID} =~ /(...)/ and $l{$1}{$_->{VendorName}}++; } map { my $v = $l{$_}; my @l = sort { $v->{$b} <=> $v->{$a} } keys %$v; $_ => $l[0]; } keys %l; } BEGIN { our @fields = qw(VendorName ModelName EISA_ID HorizSync VertRefresh dpms); } sub join_line { my ($e) = @_; join('; ', @$e{@fields}) . "\n"; } sub split_line { my ($s) = @_; my %l; @l{@fields} = split(/\s*;\s*/, $s); \%l; } sub readMonitorsDB { my ($f) = @_; my $s = ''; my @monitors_db; my $lineno = 0; foreach (cat_($f)) { $lineno++; $s .= $_; s/\s+$//; /^#/ and next; /^$/ and next; my $e = split_line($_); ($e->{text}, $s) = ($s, ''); $e->{lineno} = $lineno; push @monitors_db, $e; } \@monitors_db; }