#!/usr/bin/perl # -*- perl -*- # Foomatic printer XML file generator to get XML files corresponding # to manufacturer-supplied PostScript PPDs (or also PPDs from driver # packages). use Foomatic::Defaults; use Foomatic::DB; use Getopt::Std; use Data::Dumper; #use strict; my $debug = 0; # Program name $0 =~ m!/([^/]+)\s*$!; my $progname = ($1 || $0); help() if !@ARGV; #my ($opt_h, $opt_d, $opt_p, $opt_A, $opt_P, $opt_w); getopts("d:r:p:lb:f:nxh"); help() if $opt_h; my $drivers = $opt_d; my $rdriver = $opt_r; my $pdls = $opt_p; my $ppdlink = $opt_l; my $basedir = $opt_b; my $destdir = $opt_f; my $nomod = $opt_n; my $nocheck = $opt_x; $ppdfile = $ARGV[0]; if ($ppdlink && !$drivers) { $ppdlink = 0; warn("WARNING: \"-l\" set without supplying a driver via \"-d\". No PPD file links will get created!\n"); } my $ppddlpath; if ($basedir) { $basedir =~ s:/+$::; if (! -d $basedir) { die ("PPD base directory $basedir does not exist!\n"); } if (! -r $ppdfile) { $ppddlpath = $ppdfile; $ppdfile = $basedir . "/" . $ppdfile; if (! -r $ppdfile) { die ("Given PPD file not found, neither as $ppddlpath nor as $ppdfile!\n"); } } else { $ppddlpath = $1 if $ppdfile =~ m:$basedir/(.*)$:; } } else { if (! -r $ppdfile) { die ("Given PPD file $ppdfile not found!\n"); } $ppddlpath = $ppdfile; } my $parameters = { ($drivers ? ('drivers' => [split(',', $drivers)]) : ()), ($rdriver ? ('recommendeddriver' => $rdriver) : ()), ($pdls ? ('pdls' => [split(',', $pdls)]) : ()), ($ppdlink ? ('ppdlink' => 1) : ()), ($basedir ? ('basedir' => $basedir) : ()), }; my $db = Foomatic::DB->new(); my $dat = ppdtoperl($ppdfile, $parameters); if ($ppddlpath eq "") { $mk = $dat->{'id'}; $mk =~ s/^([^\-]+)\-.*$/$1/; $ppd = $ppdfile; $ppd =~ s:^.*/([^/]+):$1:; $pdddlpath = "PPD/$mk/$ppd"; } $ppddlpath =~ s/\.gz$//i; my @existing = (); if (!$nocheck) { @existing = $db->find_printer("$dat->{'make'}|$dat->{'model'}", 4, 1); foreach my $product (@{$dat->{ppdproduct}}) { my @pids = $db->find_printer("$dat->{'make'}|$product", 4, 1); push(@existing, grep { !Foomatic::DB::member($_, @existing); } @pids); } push(@existing, grep { !Foomatic::DB::member($_, @existing); } map { m:^(.*)\.xml$:; $1; } map { m:([^/]+)$:; $1; } split(/\n/s, `find $libdir/db/source/printer -name "*.xml" -print0 | xargs -0 grep -l $ppddlpath`)); } my $entryfound = 0; foreach my $entry (@existing) { my $d = $db->get_printer($entry); my $result; next if $d->{'noxmlentry'}; $entryfound = 1; last if $nomod; $db->{'dat'} = $d; if (!defined($parameters->{'drivers'})) { $parameters->{'drivers'} = [$dat->{'driver'}]; } if (!defined($parameters->{'pdls'})) { $parameters->{'pdls'} = [split(',', $dat->{'general_cmd'})]; } else { push(@{$parameters->{'pdls'}}, split(',', $dat->{'general_cmd'})); } Foomatic::DB::apply_driver_and_pdl_info($db->{'dat'}, $parameters); $db->{'dat'}{'general_ieee'} = $dat->{'general_ieee'} if defined($dat->{'general_ieee'}) && !defined($db->{'dat'}{'general_ieee'}); $db->{'dat'}{'general_mfg'} = $dat->{'general_mfg'} if defined($dat->{'general_mfg'}) && !defined($db->{'dat'}{'general_mfg'}); $db->{'dat'}{'general_mdl'} = $dat->{'general_mdl'} if defined($dat->{'general_mdl'}) && !defined($db->{'dat'}{'general_mdl'}); $db->{'dat'}{'general_des'} = $dat->{'general_des'} if defined($dat->{'general_des'}) && !defined($db->{'dat'}{'general_des'}); $db->{'dat'}{'general_cmd'} = $dat->{'general_cmd'} if defined($dat->{'general_cmd'}) && !defined($db->{'dat'}{'general_cmd'}); $db->{'dat'}{'comment'} .= "\n
\n\n" . $dat->{'comment'};
my $xml1 = $db->perltoxml('p');
my $xml2 = $db->get_printer_xml($entry);
$xml2 =~ s/(<\/functionality>)/$1\n \n\n" .
$db->{'dat'}{'comment'};
$db->{'dat'}{'functionality'} = "A";
foreach my $product (@{$db->{'dat'}{ppdproduct}}) {
$db->{'dat'}{'model'} =
Foomatic::DB::clean_manufacturer_name(Foomatic::DB::clean_model_name($product))
if scalar(@{$db->{'dat'}{ppdproduct}}) > 1;
$db->{'dat'}{'model'} =~ s/^$db->{'dat'}{'make'}\s*//i;
$db->{'dat'}{'id'} =
Foomatic::DB::generatepid($db->{'dat'}{'make'},
$db->{'dat'}{'model'});
if (scalar(@{$db->{'dat'}{ppdproduct}}) > 1) {
$db->{'dat'}{'general_mfg'} = $db->{'dat'}{'ppdmanufacturer'} if
$db->{'dat'}{'ppdmanufacturer'} &&
!$db->{'dat'}{'general_mfg'};
$db->{'dat'}{'general_mdl'} = $product;
$db->{'dat'}{'general_ieee'} = "MFG:" .
$db->{'dat'}{'general_mfg'} .
";MDL:" . $db->{'dat'}{'general_mdl'} . ";" .
($db->{'dat'}{'general_cmd'} ?
"CMD:" . $db->{'dat'}{'general_cmd'} . ";" : "");
}
$result = $db->perltoxml('p');
print "Creating new printer entry $db->{'dat'}{'id'}.xml ...\n";
open FILE, "> " . ($destdir ? $destdir . "/" : ()) .
$db->{'dat'}{'id'} . ".xml" or
die "Cannot write file $db->{'dat'}{'id'}.xml!\n";
print FILE $result;
close FILE;
}
delete($db->{'dat'});
}
exit 0;
sub transferregexp {
my ($src, $dest, $regexp) = @_;
# This function copies the text fraction matching $regexp out of
# the first string, cuts the piece of the second matching $regexp
# out of the second string and replaces it by the piece copied
# from the first string. This is mainly for transfering XML
# sections from one XML file to another (strings can be
# multi-line) without needing to rewrite the unaffected parts of
# the XML file.
$src =~ m/($regexp)/s;
my $totransfer = $1;
$dest =~ s/$regexp/$totransfer/s if $totransfer;
return $dest;
}
sub help {
print <