1#!@PERL@ 2 3use Getopt::Long; 4Getopt::Long::Configure("bundling", "no_ignore_case", "pass_through"); 5 6use strict; 7 8my $valgrind = 0; 9my $callgrind = 0; 10my $gdb_attach = 0; 11my $calc_md5_file = undef; 12my $calc_md5_dir = undef; 13my $dontrun = 0; 14my $retval = 0; 15my $testpattern_command; 16my @printer_list = (); 17my @special_options = (); 18my @standard_options = qw(InkType InkSet,RawChannels DitherAlgorithm Duplex MediaType InputSlot ColorCorrection ImageType FullBleed Quality UseGloss Weave PrintingDirection Density CyanDensity); 19my $global_status = 1; 20my $run_installed = 0; 21my $use_min_res = 0; 22my $help = 0; 23my $output = undef; 24my $hsize = 0.1; 25my $vsize = 0.1; 26my $left = 0.15; 27my $top = 0.15; 28my $geometry = ""; 29 30my @extras = (); 31my @job_extras = (); 32my @messages = (); 33my @global_messages = (); 34my @families = (); 35my %stpdata = (); 36my %models_found = (); 37my %models; 38my %families; 39my $skip_duplicate_printers = 0; 40my $std_pages = 1; 41my $duplex_pages = 4; 42my $skip_resolutions = 0; 43my $quiet = 0; 44my $single = 0; 45my $rerun = 0; 46 47my @default_options = (); 48my %base_settings = ("DitherAlgorithm" => "Fast"); 49 50my %param_types; 51my %param_classes; 52my %param_levels; 53my %stp_float_values; 54my %stp_int_values; 55my %rerun_cases; 56 57GetOptions("v+" => \$valgrind, 58 "c" => \$callgrind, 59 "g" => \$gdb_attach, 60 "G=s" => \$geometry, 61 "n" => \$dontrun, 62 "p:i" => \$std_pages, 63 "P:i" => \$duplex_pages, 64 "s!" => \$skip_duplicate_printers, 65 "S!" => \$single, 66 "i!" => \$run_installed, 67 "r!" => \$skip_resolutions, 68 "R+" => \$use_min_res, 69 "q!" => \$quiet, 70 "o=s" => \@special_options, 71 "f=s" => \@families, 72 "O=s" => \$output, 73 "d=s" => \@default_options, 74 "m:s" => \$calc_md5_dir, 75 "M:s" => \$calc_md5_file, 76 "X" => \$rerun, 77 "h" => \$help); 78 79sub print_help_and_exit() { 80 my $options = join("\n ", sort @standard_options); 81 print STDERR <<EOF; 82Usage: run-testpattern-2 [opts] [model ...] 83 84 Options: 85 -c Use callgrind (incompatible with -v) 86 -f family Test printers only in the specified family. Multiple 87 families may be tested. By default, all printer families 88 are tested. 89 -g Attach testpattern job to gdb 90 -G geometry Specify geometry (=(HxV)(+L+T)) 91 -i Use the installed Gutenprint libraries rather than 92 source tree 93 -m md5_dir Generate MD5 checksums and place them in the specified 94 directory, one file per run. Directory will be created 95 if necessary. 96 -M md5_file Generate MD5 checksums and place them in the specified 97 file, one line per run. 98 -n Do not actually run testpattern 99 -O out_dir Generate actual output and place it in the specified 100 directory, one file per run. Directory will be created 101 if necessary. 102 -o option Test this option. Multiple -o options may be specified. 103 option1,option2 indicates to test each value of option1 104 in combination with each value of option2. For floating 105 point and integer options, a selection of values is 106 tested. 107 Default: 108 $options 109 -d option=value Test this option with only the specified (default) value, 110 if available 111 -p page count Specify number of pages to print per printer. Default $std_pages. 112 -P page count Specify number of pages to print per printer when testing 113 duplex mode. Default $duplex_pages. 114 -q Do not print progress messages 115 -r Do not test each resolution (test only the default) 116 -R Use the minimum resolution (rather than the default) 117 to test other options. 118 -RR Use only the minimum resolution, and do not test other 119 resolutions. 120 -s Skip duplicate printers (with the same model number 121 in printers.xml) 122 -S Run a separate testpattern command for each printer 123 -X Repeat specified cases listed on standard input 124 -v[v[v[v]]] Use valgrind. Number of -v options controls usage: 125 -v Basic valgrind checking, no leak checking 126 -vv Additional leak checking 127 -vvv Show reachable data also 128 -vvvv Minimal checks only 129EOF 130exit 1; 131} 132 133if ($help) { 134 print_help_and_exit(); 135} 136 137my $pages = $std_pages; 138 139if (! @special_options) { 140 @special_options = @standard_options; 141} 142 143my $bad_opt = 0; 144 145foreach my $opt (@default_options) { 146 if (! ($opt =~ /=/)) { 147 print STDERR "Malformed default option `$opt'\n"; 148 $bad_opt = 1; 149 } 150 my ($option, $value) = split(/=/, $opt); 151 if (! $value) { 152 delete $base_settings{$option}; 153 } else { 154 $base_settings{$option} = $value; 155 } 156} 157 158if ($bad_opt) { 159 print_help_and_exit(); 160} 161 162my $pwd = `pwd`; 163chomp $pwd; 164 165my $srcdir = $ENV{"srcdir"}; 166my $sdir; 167 168$geometry =~ s/^=*//; 169if ($geometry =~ /^(([01]?(\.[0-9]*)?)x([01]?(\.[0-9]*)?))?(\+([01]?(\.[0-9]*)?)\+([01]?(\.[0-9]*)?))?$/) { 170 my ($H) = $2; 171 my ($V) = $4; 172 my ($L) = $7; 173 my ($T) = $9; 174 if ($H) { 175 $hsize = $H; 176 if ($hsize > 1) { 177 $hsize = 1; 178 } 179 } 180 if ($V) { 181 $vsize = $V; 182 if ($vsize > 1) { 183 $vsize = 1; 184 } 185 } 186 if ($L) { 187 $left = $L; 188 } 189 if ($T) { 190 $top = $T; 191 } 192 if ($left + $hsize > 1) { 193 $left = 1 - $hsize; 194 } 195 if ($top + $vsize > 1) { 196 $top = 1 - $vsize; 197 } 198} 199 200if ("$srcdir" eq "" || "$srcdir" eq ".") { 201 $sdir = $pwd; 202} elsif ($srcdir =~ /^\//) { 203 $sdir = "$srcdir"; 204} else { 205 $sdir = "$pwd/$srcdir"; 206} 207 208if (! $run_installed && ! defined $ENV{"STP_DATA_PATH"}) { 209 $ENV{"STP_DATA_PATH"} = "${sdir}/../xml"; 210} 211 212if (! defined $ENV{"STP_MODULE_PATH"}) { 213 $ENV{"STP_MODULE_PATH"} = "${sdir}/../main:${sdir}/../main/.libs"; 214} 215 216sub set_opt($$$) { 217 my ($opt, $val, $printer) = @_; 218 my ($type) = $param_types{$printer}{$opt}; 219 if ($type == 1) { 220 push @extras, "parameter_int \"$opt\" $val;\n"; 221 } elsif ($type == 2) { 222 my ($xval) = $val; 223 if ($val =~ /true/i) { 224 $xval = 1; 225 } elsif ($val =~ /false/i) { 226 $xval = 0; 227 } 228 push @extras, "parameter_bool \"$opt\" $xval;\n"; 229 } elsif ($type == 3) { 230 push @extras, "parameter_float \"$opt\" $val;\n"; 231 } elsif ($type == 4) { 232 push @extras, "parameter_curve \"$opt\" \"$val\";\n"; 233 } else { 234 if ($opt eq "PageSize" && $val =~ /^([^.]+)\.([0-9]+)x([0-9]+)$/) { 235 push @extras, "parameter \"PageSize\" \"$1\";\n"; 236 push @extras, "page_size $2 $3;\n"; 237 } else { 238 push @extras, "parameter \"$opt\" \"$val\";\n"; 239 } 240 } 241} 242 243sub set_message($) { 244 my ($message) = @_; 245 push @messages, "message \"$message\";\n" if (! $quiet); 246} 247 248sub set_global_message($) { 249 my ($message) = @_; 250 push @global_messages, "message \"$message\";\n" if (! $quiet); 251} 252 253sub print_one_testpattern($;$) { 254 my ($printer, $raw) = @_; 255 my $stuff = join "", @global_messages; 256 $stuff .= join "", @job_extras; 257 foreach my $page (0..$pages - 1) { 258 $stuff .= "printer \"$printer\";\n"; 259 $stuff .= "parameter \"PageSize\" \"Auto\";\n"; 260 $stuff .= join "", @extras, @messages; 261 if (! $quiet && $pages > 1) { 262 $stuff .= "message \"(page $page)\";\n"; 263 } 264 $stuff .= "parameter_int \"PageNumber\" $page;\n"; 265 if ($page == 0) { 266 $stuff .= "start_job;\n"; 267 } 268 if ($page == $pages - 1) { 269 $stuff .= "end_job;\n"; 270 } 271 $stuff .= sprintf("hsize %f;\n", $hsize); 272 $stuff .= sprintf("vsize %f;\n", $vsize); 273 $stuff .= sprintf("left %f;\n", $left); 274 $stuff .= sprintf("top %f;\n", $top); 275 $stuff .= "blackline 0;\n"; 276 $stuff .= "steps 16;\n"; 277 if ($raw > 0) { 278 $stuff .= "mode extended $raw 16;\n"; 279 $stuff .= "xpattern "; 280 for (my $i = 0; $i < $raw; $i++) { 281 $stuff .= "0.0 0.0 1.0 "; 282 } 283 $stuff .= ";\n"; 284 for (my $i = 0; $i < $raw; $i++) { 285 $stuff .= "xpattern "; 286 for (my $j = 0; $j < $raw; $j++) { 287 if ($i == $j) { 288 $stuff .= "0.0 1.0 1.0 "; 289 } else { 290 $stuff .= "0.0 0.0 1.0 "; 291 } 292 } 293 $stuff .= ";\n"; 294 } 295 $stuff .= "xpattern "; 296 for (my $i = 0; $i < $raw; $i++) { 297 $stuff .= "0.0 0.0 1.0 "; 298 } 299 $stuff .= ";\n"; 300 $stuff .= "end;\n"; 301 } else { 302 $stuff .= << 'EOF'; 303mode rgb 8; 304pattern 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 ; 305pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0; 306pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 0.0 0.0 1.0; 307pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0; 308pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 0.0 1.0 1.0 0.0 1.0 1.0; 309pattern 0.0 0.0 1.0 1.0 1.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0; 310pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.0 1.0 0.0 -2.0 1.0 0.0 -2.0 1.0 0.0 -2.0 1.0; 311pattern 1.0 1.0 1.0 1.0 1.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0; 312pattern 1.0 1.0 -2.0 -2.0 -2.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0; 313pattern 0.1 0.3 1.0 1.0 1.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0; 314pattern 0.3 0.7 -2.0 -2.0 -2.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0; 315pattern 0.1 0.999 1.0 1.0 1.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0; 316pattern 0.3 0.999 1.0 1.0 1.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0; 317pattern 0.5 0.999 1.0 1.0 1.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0; 318pattern 0.1 0.3 -2.0 -2.0 -2.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0; 319pattern 0.3 0.7 1.0 1.0 1.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0; 320pattern 0.1 0.999 -2.0 -2.0 -2.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0; 321pattern 0.3 0.999 -2.0 -2.0 -2.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0; 322pattern 0.5 0.999 -2.0 -2.0 -2.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0; 323pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 0.0 1.0 1.0; 324pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.25 1.0 0.0 0.0 1.0 0.0 0.75 1.0 0.0 0.75 1.0; 325pattern 0.0 0.0 1.0 1.0 1.0 0.0 0.25 1.0 0.0 0.0 1.0 0.0 0.75 1.0 0.0 0.75 1.0; 326pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.5 1.0 0.0 0.0 1.0 0.0 0.5 1.0 0.0 0.5 1.0; 327pattern 0.0 0.0 1.0 1.0 1.0 0.0 0.5 1.0 0.0 0.0 1.0 0.0 0.5 1.0 0.0 0.5 1.0; 328pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.75 1.0 0.0 0.0 1.0 0.0 0.25 1.0 0.0 0.25 1.0; 329pattern 0.0 0.0 1.0 1.0 1.0 0.0 0.75 1.0 0.0 0.0 1.0 0.0 0.25 1.0 0.0 0.25 1.0; 330pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.9 1.0 0.0 0.0 1.0 0.0 0.1 1.0 0.0 0.1 1.0; 331pattern 0.0 0.0 1.0 1.0 1.0 0.0 0.9 1.0 0.0 0.0 1.0 0.0 0.1 1.0 0.0 0.1 1.0; 332pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0; 333pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.25 1.0 0.0 0.75 1.0 0.0 0.0 1.0 0.0 0.75 1.0; 334pattern 0.0 0.0 1.0 1.0 1.0 0.0 0.25 1.0 0.0 0.75 1.0 0.0 0.0 1.0 0.0 0.75 1.0; 335pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.5 1.0 0.0 0.5 1.0 0.0 0.0 1.0 0.0 0.5 1.0; 336pattern 0.0 0.0 1.0 1.0 1.0 0.0 0.5 1.0 0.0 0.5 1.0 0.0 0.0 1.0 0.0 0.5 1.0; 337pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.75 1.0 0.0 0.25 1.0 0.0 0.0 1.0 0.0 0.25 1.0; 338pattern 0.0 0.0 1.0 1.0 1.0 0.0 0.75 1.0 0.0 0.25 1.0 0.0 0.0 1.0 0.0 0.25 1.0; 339pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.9 1.0 0.0 0.1 1.0 0.0 0.0 1.0 0.0 0.1 1.0; 340pattern 0.0 0.0 1.0 1.0 1.0 0.0 0.9 1.0 0.0 0.1 1.0 0.0 0.0 1.0 0.0 0.1 1.0; 341pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 0.0 1.0 1.0 0.0 0.0 1.0; 342pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.25 1.0 0.0 0.75 1.0 0.0 0.75 1.0 0.0 0.0 1.0; 343pattern 0.0 0.0 1.0 1.0 1.0 0.0 0.25 1.0 0.0 0.75 1.0 0.0 0.75 1.0 0.0 0.0 1.0; 344pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.5 1.0 0.0 0.5 1.0 0.0 0.5 1.0 0.0 0.0 1.0; 345pattern 0.0 0.0 1.0 1.0 1.0 0.0 0.5 1.0 0.0 0.5 1.0 0.0 0.5 1.0 0.0 0.0 1.0; 346pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.75 1.0 0.0 0.25 1.0 0.0 0.25 1.0 0.0 0.0 1.0; 347pattern 0.0 0.0 1.0 1.0 1.0 0.0 0.75 1.0 0.0 0.25 1.0 0.0 0.25 1.0 0.0 0.0 1.0; 348pattern 1.0 1.0 1.0 1.0 1.0 0.0 0.9 1.0 0.0 0.1 1.0 0.0 0.1 1.0 0.0 0.0 1.0; 349pattern 0.0 0.0 1.0 1.0 1.0 0.0 0.9 1.0 0.0 0.1 1.0 0.0 0.1 1.0 0.0 0.0 1.0; 350end; 351EOF 352 } 353 } 354 return $stuff; 355} 356 357my $extra_arg = ""; 358if ($#ARGV >= 0) { 359 @printer_list = @ARGV; 360 $extra_arg = join " ", @printer_list; 361} else { 362 open PIPE, "./printers|" or die "Cannot run printers: $!\n"; 363 while(<PIPE>) { 364 next if m!^#!; 365 chomp; 366 push @printer_list, $_; 367 } 368 close PIPE; 369} 370 371open PIPE, "./printer_options $extra_arg|" or die "Cannot run printer_options: $!\n"; 372while(<PIPE>) { 373 next if m!^#!; 374 eval $_; 375} 376close PIPE or die "Cannot run printer_options: $!\n"; 377 378sub do_print { 379 my ($output, $fh) = @_; 380 if ($dontrun) { 381 print $output; 382 } else { 383 print $fh $output; 384 } 385} 386 387sub do_output($) { 388 my ($outkey) = @_; 389 if (defined $output || defined $calc_md5_dir || 390 defined $calc_md5_file) { 391 my $md5_cmd; 392 my $outbase = "${outkey}.prn"; 393 my $outfile = "$output/$outbase"; 394 if (defined $calc_md5_file) { 395 $md5_cmd = "md5sum -b | sed 's/-/$outbase/' >> '$calc_md5_file'"; 396 } elsif (defined $calc_md5_dir) { 397 my $md5_dir = $calc_md5_dir; 398 if (defined $calc_md5_dir && $calc_md5_dir eq "") { 399 $md5_dir = $output; 400 } 401 my $md5file = "$md5_dir/${outkey}.md5"; 402 if (! $md5_dir) { 403 $md5file = "${outkey}.md5"; 404 } 405 $md5_cmd = "md5sum -b | sed 's/-/$outbase/' > '$md5file'"; 406 } 407 if ($output && $md5_cmd ne "") { 408 push @job_extras, "output \"|tee '$outfile' | $md5_cmd\";\n"; 409 } elsif ($output) { 410 push @job_extras, "output \"$outfile\";\n"; 411 } else { 412 push @job_extras, "output \"|$md5_cmd\";\n"; 413 } 414 } 415} 416 417sub build_list($$) { 418 my ($keys, $printer) = @_; 419 my (@keys) = split (/,/, $keys); 420 my ($key) = $keys[0]; 421 my ($rest); 422 my (@stuff); 423 if ($#keys > 0) { 424 $rest = join ",", @keys[1..$#keys]; 425 @stuff = build_list($rest, $printer); 426 } 427 my (@tmp); 428 if ($param_types{$printer}{$key} == 3) { 429 my ($minv) = $stp_float_values{$printer}{'MINVAL'}{$key}; 430 my ($defv) = $stp_float_values{$printer}{'DEFVAL'}{$key}; 431 my ($maxv) = $stp_float_values{$printer}{'MAXVAL'}{$key}; 432 push @tmp, $minv; 433 push @tmp, ($minv + $defv) / 2.0; 434 push @tmp, $defv; 435 push @tmp, ($defv + $maxv) / 2.0; 436 push @tmp, $maxv; 437 } elsif ($param_types{$printer}{$key} == 1) { 438 my ($minv) = $stp_int_values{$printer}{'MINVAL'}{$key}; 439 my ($maxv) = $stp_int_values{$printer}{'MAXVAL'}{$key}; 440 push @tmp, ($minv..$maxv); 441 } elsif ($param_types{$printer}{$key} == 2) { 442 push @tmp, 0; 443 push @tmp, 1; 444 } elsif (defined($param_types{$printer}{$key})) { 445 @tmp = keys %{$stpdata{$printer}{$key}}; 446 } 447 if (! @tmp) { 448 return @stuff; 449 } elsif (! @stuff) { 450 return @tmp; 451 } else { 452 my (@answer); 453 foreach my $i (@tmp) { 454 foreach my $j (@stuff) { 455 push @answer, "$i,$j"; 456 } 457 } 458 return @answer; 459 } 460 return @tmp; 461} 462 463sub build_key($$) { 464 my ($keys, $printer) = @_; 465 my (@keys) = split (/,/, $keys); 466 my (@answer) = grep { defined $param_types{$printer}{$_} } @keys; 467 return join ",", @answer; 468} 469 470sub do_printer($$) { 471 my ($printer, $fh) = @_; 472 my $tmp; 473 my $min_res_name; 474 my $min_res_value = 0; 475 my $first_time = 1; 476 my $key; 477 my %opt_vals = {}; 478 $tmp = $stpdata{$printer}{'Resolution'}; 479 my (@resolutions) = grep {$_ ne 'None' } keys %$tmp; 480 $tmp = $stpdata{$printer}{'PrintingMode'}; 481 my (@printing_modes) = grep {$_ ne 'None' } keys %$tmp; 482 if ($base_settings{'PrintingMode'}) { 483 if ($base_settings{'PrintingMode'} eq 'Color' && 484 grep { $_ eq 'Color' } @printing_modes) { 485 @printing_modes = 'Color'; 486 } elsif ($base_settings{'PrintingMode'} eq 'BW' && 487 grep { $_ eq 'BW' } @printing_modes) { 488 @printing_modes = 'BW'; 489 } else { 490 return; 491 } 492 } 493 494 foreach $key (@special_options) { 495 my $nkey = build_key($key, $printer); 496 if ($nkey ne "") { 497 my (@vals) = build_list($nkey, $printer); 498 $opt_vals{$nkey} = \@vals; 499 } 500 } 501 foreach $tmp (sort @resolutions) { 502 my $res_value = ($stpdata{$printer}{'x_resolution'}{$tmp} * 503 $stpdata{$printer}{'y_resolution'}{$tmp}); 504 if ($min_res_value == 0 || $res_value < $min_res_value) { 505 $min_res_value = $res_value; 506 $min_res_name = $tmp; 507 } 508 } 509 if ($use_min_res > 1) { 510 @resolutions = ($min_res_name); 511 } 512 # We want to do all resolutions and all ink types in both color modes. 513 # We don't need to do both resolutions and ink types. 514 my $pmode; 515 foreach $pmode (@printing_modes) { 516 my ($resolution); 517 $pages = $std_pages; 518 if (! $skip_resolutions) { 519 foreach $resolution (@resolutions) { 520 @extras = (); 521 @job_extras = (); 522 @messages = (); 523 @global_messages = (); 524 if ($first_time) { 525 set_global_message("$printer\n"); 526 } 527 set_opt("PrintingMode", $pmode, $printer); 528 set_opt("Resolution", $resolution, $printer); 529 map { set_opt($_, $base_settings{$_}, $printer)} keys %base_settings; 530 my ($case) = "${printer}_PrintingMode_${pmode}_Resolution_${resolution}"; 531 if (! $rerun || $rerun_cases{$case}) { 532 $first_time = 0; 533 do_output($case); 534 set_message(" ${pmode}+${resolution}"); 535 my $output = print_one_testpattern($printer); 536 do_print( $output, $fh ); 537 } 538 } 539 } 540 foreach $key (keys %opt_vals) { 541 next if ($key eq "RawChannels" && $pmode ne "Color"); 542 my (@subkeys) = split (/,/, $key); 543 $tmp = $opt_vals{$key}; 544 if (defined $tmp && $tmp >= 1) { 545 my (@opts) = @$tmp; 546 my $opt; 547 my $rawval; 548 my $set_resolution = 0; 549 foreach $opt (@opts) { 550 my (@subopts) = split (/,/, $opt); 551 @extras = (); 552 @job_extras = (); 553 @messages = (); 554 @global_messages = (); 555 set_opt("PrintingMode", $pmode, $printer); 556 if ($use_min_res) { 557 set_opt("Resolution", $min_res_name, $printer); 558 } 559 my (@mvals); 560 my (@ovals); 561 map { 562 my $k = $subkeys[$_]; 563 my $v = $subopts[$_]; 564 if ($k eq "RawChannels") { 565 next if ($v ne "None" && $pmode ne "Color"); 566 $rawval = $v; 567 } else { 568 set_opt($k, $v, $printer); 569 } 570 push @mvals, "${k}_${v}"; 571 push @ovals, "${k}=${v}"; 572 } (0..$#subkeys); 573 if ($first_time) { 574 set_global_message("$printer\n"); 575 $first_time = 0; 576 } 577 # FIXME! need to handle Duplex as a subkey 578 map { 579 $pages = $std_pages; 580 if ($key ne $_) { 581 set_opt($_, $base_settings{$_}, $printer); 582 push @mvals, "${_}_$base_settings{$_}"; 583 push @ovals, "${_}=$base_settings{$_}"; 584 if ($_ eq "Resolution") { 585 $set_resolution = 1; 586 } 587 if ($_ eq "Duplex") { 588 set_opt("JobMode", "Job", $printer); 589 $pages = $duplex_pages; 590 } 591 } 592 } keys %base_settings; 593 my ($mstring) = join "_", @mvals; 594 my ($ostring) = join "+", @ovals; 595 my $case; 596 if ($use_min_res && ! $set_resolution) { 597 $case = "${printer}_PrintingMode_${pmode}_Resolution_${min_res_name}_${mstring}"; 598 } else { 599 $case = "${printer}_PrintingMode_${pmode}_${mstring}"; 600 } 601 if (! $rerun || $rerun_cases{$case}) { 602 do_output($case); 603 if ($use_min_res && ! $set_resolution) { 604 set_message(" ${ostring}+${pmode}+${min_res_name}"); 605 } else { 606 set_message(" ${ostring}+${pmode}"); 607 } 608 my $output = print_one_testpattern($printer, $rawval); 609 do_print( $output, $fh ); 610 } 611 } 612 } 613 } 614 } 615} 616 617if ($rerun) { 618 while (<>) { 619 chomp; 620 s/^[^a-zA-Z]*//; 621 s/\.prn//; 622 $rerun_cases{$_} = 1; 623 } 624} 625 626my (@nprinter_list); 627foreach my $printer (@printer_list) { 628 my $model_id = $models{$printer}; 629 my $family_id = $families{$printer}; 630 if (($skip_duplicate_printers && $models_found{$family_id}{$model_id}) || 631 (@families && ! grep { $family_id eq $_ } @families)) { 632 } else { 633 $models_found{$family_id}{$model_id} = 1; 634 push @nprinter_list, $printer; 635 } 636} 637@printer_list = @nprinter_list; 638 639if ($dontrun) { 640 map { do_printer($_, \*STDOUT) } @printer_list; 641 exit 0; 642} else { 643 my $valgrind_command; 644 my $valopts; 645 if ($callgrind) { 646 $valopts = '--tool=callgrind --dump-instr=yes --trace-jump=yes'; 647 $valgrind = 4; 648 } elsif ($valgrind) { 649 $valopts = '--tool=memcheck'; 650 } 651 if ($gdb_attach) { 652 $valopts .= ' --db-attach=yes'; 653 } 654 if ($valgrind == 1) { 655 $valgrind_command = "valgrind $valopts -q --num-callers=50 --error-limit=no --leak-check=yes"; 656 } elsif ($valgrind == 2) { 657 $valgrind_command = "valgrind $valopts --num-callers=50 --error-limit=no --leak-resolution=high --leak-check=yes"; 658 } elsif ($valgrind == 3) { 659 $valgrind_command = "valgrind $valopts --error-limit=no --num-callers=50 --show-reachable=yes --leak-resolution=high --leak-check=yes"; 660 } elsif ($valgrind == 4) { 661 $valgrind_command = "valgrind $valopts"; 662 } 663 664 if (defined $output && $output ne "" && ! -d $output) { 665 mkdir $output || die "Can't create directory $output: $!\n"; 666 } 667 668 if (defined $calc_md5_dir && $calc_md5_dir ne "" && ! -d $calc_md5_dir) { 669 mkdir $calc_md5_dir || die "Can't create directory $calc_md5_dir: $!\n"; 670 } 671 672 if (defined $calc_md5_file) { 673 unlink $calc_md5_file; 674 system "touch $calc_md5_file"; 675 } 676 677 my $status = 1; 678 my ($suppress); 679 if (! defined $output && ! defined $calc_md5_dir && 680 ! defined $calc_md5_file) { 681 $suppress = '-n'; 682 } 683 my ($qopt) = $quiet ? "-q" : ""; 684 $testpattern_command = "$valgrind_command ./testpattern -y $suppress $qopt"; 685 if ($single) { 686 foreach my $printer (@printer_list) { 687 open TESTPATTERN, "|$testpattern_command" or 688 die "Can't run $testpattern_command: $!\n"; 689 do_printer($printer, \*TESTPATTERN); 690 $status |= close TESTPATTERN; 691 $status |= ($? & 255); 692 last if ($? & 255); 693 } 694 } else { 695 open TESTPATTERN, "|$testpattern_command" or 696 die "Can't run $testpattern_command: $!\n"; 697 map { do_printer($_, \*TESTPATTERN) } @printer_list; 698 $status = close TESTPATTERN; 699 } 700 if ($status) { 701 exit 0; 702 } else { 703 exit 1; 704 } 705} 706