File: foomatic-ppd-to-xml.in

package info (click to toggle)
foomatic-db-engine 4.0.13-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 1,972 kB
  • sloc: perl: 12,170; ansic: 6,958; python: 1,139; makefile: 248; sh: 215; xml: 83
file content (320 lines) | stat: -rwxr-xr-x 11,900 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
#!@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:Dc:Cf: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 $addonlyrequesteddrivers = $opt_D;
my $comment = $opt_c;
my $nodefaultcomment = $opt_C;
my $destdir = $opt_f;
my $nomod = $opt_n;
my $nocheck = $opt_x;

my @ppddrivers = ();
my @driverslist = ($drivers ? split(',', $drivers) : ());
my $commentadded = 0;

foreach $ppdfile (@ARGV) {

    my $ppddriver;
    if ($ppdfile =~ /^([^\:]+)\:(.*)$/) {
	$ppddriver = $1;
	$ppdfile = $2;
    } else {
	$ppddriver = $driverslist[0];
    }
    $ppdlink = $opt_l;
    if ($ppdlink && !$ppddriver) {
	$ppdlink = 0;
	warn("WARNING: \"-l\" set without assigning a driver to the PPD file \"$ppdfile\" and without supplying a driver via \"-d\". No links for this PPD file will get created!\n");
    } elsif ($ppdlink && Foomatic::DB::member($ppddriver, @ppddrivers)) {
	$ppdlink = 0;
	warn("WARNING: \"-l\" set and PPD file \"$ppdfile\" assigned to the driver \"$ppddriver\", to which another PPD file was assigned already. No links for this PPD file will get created!\n");
    }
    if ($ppddriver && !Foomatic::DB::member($ppddriver, @ppddrivers)) {
	push(@ppddrivers, $ppddriver);
    }
    if ($ppddriver && !Foomatic::DB::member($ppddriver, @driverslist)) {
	push(@driverslist, $ppddriver);
    }
    print "PPD file $ppdfile";
    if ($ppddriver) {
	print " for driver $ppddriver\n";
    } else {
	print "\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 = {
	(@driverslist ? ('drivers' => [@driverslist]) : ()),
	($rdriver ? ('recommendeddriver' => $rdriver) : ()),
	($pdls ? ('pdls' => [split(',', $pdls)]) : ()),
	($ppddriver ? ('ppddriver' => $ppddriver) : ()),
	($ppdlink ? ('ppdlink' => 1) : ()),
	($basedir ? ('basedir' => $basedir) : ()),
	($comment && !$commentadded ? ('comment' => $comment) : ()),
	($nodefaultcomment && !$commentadded ? ('nodefaultcomment' => 1) : ()),
	($addonlyrequesteddrivers ? ('addonlyrequesteddrivers' => 1) : ()),
    };
    $commentadded = 1;

    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;

    $db->{'dat'} = $dat;
    $db->{'dat'}{'comment'} =
	"      This database entry was automatically generated\n" .
	"      from the PPD file for this printer.<p>\n\n" .
	$db->{'dat'}{'comment'} if !$parameters->{'nodefaultcomment'};
    $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";
	my $f = ($destdir ? $destdir . "/" : ()) . 
	    $db->{'dat'}{'id'} . ".xml";
	open FILE, "> " . $f or
	    die "Cannot write file $db->{'dat'}{'id'}.xml!\n";
	print FILE $result;
	close FILE;
    }
    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`));
    }
    delete($db->{'dat'});
    foreach my $entry (@existing) {
	my $d = $db->get_printer($entry);
	my $result;
	next if $d->{'noxmlentry'};
	next if $nomod and $entry !~ /\.xml$/i;
	$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      <p>\n\n" . $dat->{'comment'};
	my $xml1 = $db->perltoxml('p');
	my $xml2 = $db->get_printer_xml($entry);
	$xml2 =~ s/(<\/functionality>)/$1\n  <driver><\/driver>/s if 
	    $xml2 !~ /<driver>/;
	$xml2 = transferregexp($xml1, $xml2,
			       '<driver>\S*<\/driver>');
	$xml2 =~ s/(<\/driver>)/$1\n  <drivers>\n  <\/drivers>/s if 
	    $xml2 !~ /<drivers>/;
	$xml2 = transferregexp($xml1, $xml2,
			       '<drivers>.*<\/drivers>');
	$xml2 =~ s/(<\/(mechanism|url)>)/$1\n  <lang>\n  <\/lang>/s if 
	    $xml2 !~ /<lang>/;
	$xml2 = transferregexp($xml1, $xml2,
			       '<lang>.*<\/lang>');
	$xml2 =~ s/(<\/lang>)/$1\n  <autodetect>\n  <\/autodetect>/s if 
	    $xml2 !~ /<autodetect>/;
	$xml2 =~ s/(<autodetect>)/$1\n    <general>\n    <\/general>/s if 
	    $xml2 !~ /<autodetect>[\s\n\r]*<general>/s;
	$xml2 = transferregexp($xml1, $xml2,
			       '<autodetect>[\s\n\r]*<general>.*<\/general>');
	$xml2 = transferregexp($xml1, $xml2,
			       '<\/drivers>[\s\n\r]*<comments>.*<\/comments>[\s\n\r]*<\/printer>');
	$result = $xml2;
	if ($entry !~ /\.xml$/i) {
	    print "  Modifying printer entry $db->{'dat'}{'id'}.xml ...\n";
	} else {
	    print "  Adding PPD file to $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'});
    }
    undef($db);
    undef($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 <<HELP;

$progname <options> [<driver>:]<ppdfile> [[<driver>:]<ppdfile> ...]
$progname -h

 <driver>       : Driver to which the PPD file should get assigned. This
                  is optional. If not supplied, the first driver in the driver 
		  list supplied via the "-d" option is used. Note that the PPD
		  files have to be supplied to different drivers, so with more
                  than one PPD drivers need to be specified here.
 <ppdfile>      : PPD file for which a printer XML file should be created
 -d <drivers>   : Comma-separated list of drivers with which the printer
                  works. First driver is the one for which the PPD file is.
                  If not otherwise stated by the "-r" option, this is also
                  the recommended driver. Drivers already specified together
		  with PPDs do no need to get specified with this option again.
		  The option is not needed if for all PPDs drivers are
		  specified.
 -r <driver>    : Recommended driver. Supply this option to specify another
                  driver than the driver from the PPD/the first one from the
                  "-d" argument as the recommended driver (or the one to which
		  the first PPD file is assigned if the "-d" option is not
		  used)..
 -p <pdls>      : Comma-separated list of known Page Description Languages
                  (PDLs) which the printer supports. This will add all 
                  suitable drivers to the XML entry. Currently supported are:
                  Postscript, PCLXL, PCL6, PCL5e, PCL5c, PCL5, and PCL4.
 -l             : Add a link to the PPD file to the driver entry in the
                  XML file.
 -b <directory> : Base directory for a relative link to the PPD. If the
                  base directory is given, the link set via the -l option 
                  is relative to this directory (and not relative to the
                  current directory). With a base directory given the 
                  <ppdfile> can also be given relative to this directory.
 -D             : Add only the driver requested by "-d" and "-r" to the
                  driver list in the XML file, do not add drivers based on
                  PDLs, not even on the PDLs supplied by the "-p" option.
 -c <comment>   : Add the given comment to the comment field of the XML
                  file. Comments are in HTML.
 -C             : Suppress any default comments (max paper width, pages
                  per minute, automatically generated XML, ...). Does not
                  suppress the comment supplied with "-c".
 -f <directory> : Directory where the resulting XML file to write to. The
                  name of the file will be the printer ID with the ".xml"
                  extension.
 -n             : Do not write modified versions of existing XML files,
                  only create XML files for printers for which there is no
                  XML file yet.
 -x             : Create XML files independent of whether there are already
                  XML files for the printers covered by the PPD or not. This
		  makes the process vastly faster if you have PPD files for
		  printers which are for sure not yet in the Foomatic
		  database.
 -h             : show help information


HELP
    exit 1;

}