blob: b4d221d671278745392db63219271f68c9142789 [file]
//
// PPD test program for libppd.
//
// Copyright © 2007-2018 by Apple Inc.
// Copyright © 1997-2006 by Easy Software Products.
//
// Licensed under Apache License v2.0. See the file "LICENSE" for more
// information.
//
//
// Include necessary headers...
//
#include <ppd/ppd.h>
#include <ppd/array-private.h>
#include <ppd/raster-private.h>
#include <ppd/libcups2-private.h>
#include <sys/stat.h>
#ifdef _WIN32
# include <io.h>
#else
# include <unistd.h>
# include <fcntl.h>
#endif // _WIN32
#include <math.h>
//
// Local functions...
//
static int do_ppd_tests(const char *filename, int num_options,
cups_option_t *options);
static int do_ps_tests(void);
static void print_changes(cups_page_header_t *header, cups_page_header_t *expected);
//
// Test data...
//
static const char *dsc_code =
"[{\n"
"%%BeginFeature: *PageSize Tabloid\n"
"<</PageSize[792 1224]>>setpagedevice\n"
"%%EndFeature\n"
"} stopped cleartomark\n";
static const char *setpagedevice_code =
"<<"
"/MediaClass(Media Class)"
"/MediaColor((Media Color))"
"/MediaType(Media\\\\Type)"
"/OutputType<416263>"
"/AdvanceDistance 1000"
"/AdvanceMedia 1"
"/Collate false"
"/CutMedia 2"
"/Duplex true"
"/HWResolution[100 200]"
"/InsertSheet true"
"/Jog 3"
"/LeadingEdge 1"
"/ManualFeed true"
"/MediaPosition 8#777"
"/MediaWeight 16#fe01"
"/MirrorPrint true"
"/NegativePrint true"
"/NumCopies 1"
"/Orientation 1"
"/OutputFaceUp true"
"/PageSize[612 792.1]"
"/Separations true"
"/TraySwitch true"
"/Tumble true"
"/cupsMediaType 2"
"/cupsColorOrder 1"
"/cupsColorSpace 1"
"/cupsCompression 1"
"/cupsRowCount 1"
"/cupsRowFeed 1"
"/cupsRowStep 1"
"/cupsBorderlessScalingFactor 1.001"
"/cupsInteger0 1"
"/cupsInteger1 2"
"/cupsInteger2 3"
"/cupsInteger3 4"
"/cupsInteger4 5"
"/cupsInteger5 6"
"/cupsInteger6 7"
"/cupsInteger7 8"
"/cupsInteger8 9"
"/cupsInteger9 10"
"/cupsInteger10 11"
"/cupsInteger11 12"
"/cupsInteger12 13"
"/cupsInteger13 14"
"/cupsInteger14 15"
"/cupsInteger15 16"
"/cupsReal0 1.1"
"/cupsReal1 2.1"
"/cupsReal2 3.1"
"/cupsReal3 4.1"
"/cupsReal4 5.1"
"/cupsReal5 6.1"
"/cupsReal6 7.1"
"/cupsReal7 8.1"
"/cupsReal8 9.1"
"/cupsReal9 10.1"
"/cupsReal10 11.1"
"/cupsReal11 12.1"
"/cupsReal12 13.1"
"/cupsReal13 14.1"
"/cupsReal14 15.1"
"/cupsReal15 16.1"
"/cupsString0(1)"
"/cupsString1(2)"
"/cupsString2(3)"
"/cupsString3(4)"
"/cupsString4(5)"
"/cupsString5(6)"
"/cupsString6(7)"
"/cupsString7(8)"
"/cupsString8(9)"
"/cupsString9(10)"
"/cupsString10(11)"
"/cupsString11(12)"
"/cupsString12(13)"
"/cupsString13(14)"
"/cupsString14(15)"
"/cupsString15(16)"
"/cupsMarkerType(Marker Type)"
"/cupsRenderingIntent(Rendering Intent)"
"/cupsPageSizeName(Letter)"
"/cupsPreferredBitsPerColor 17"
">> setpagedevice";
static cups_page_header_t setpagedevice_header =
{
"Media Class", // MediaClass
"(Media Color)", // MediaColor
"Media\\Type", // MediaType
"Abc", // OutputType
1000, // AdvanceDistance
CUPS_ADVANCE_FILE, // AdvanceMedia
CUPS_FALSE, // Collate
CUPS_CUT_JOB, // CutMedia
CUPS_TRUE, // Duplex
{ 100, 200 }, // HWResolution
{ 0, 0, 0, 0 }, // ImagingBoundingBox
CUPS_TRUE, // InsertSheet
CUPS_JOG_SET, // Jog
CUPS_EDGE_RIGHT, // LeadingEdge
{ 0, 0 }, // Margins
CUPS_TRUE, // ManualFeed
0777, // MediaPosition
0xfe01, // MediaWeight
CUPS_TRUE, // MirrorPrint
CUPS_TRUE, // NegativePrint
1, // NumCopies
CUPS_ORIENT_90, // Orientation
CUPS_TRUE, // OutputFaceUp
{ 612, 792 }, // PageSize
CUPS_TRUE, // Separations
CUPS_TRUE, // TraySwitch
CUPS_TRUE, // Tumble
0, // cupsWidth
0, // cupsHeight
2, // cupsMediaType
0, // cupsBitsPerColor
0, // cupsBitsPerPixel
0, // cupsBytesPerLine
CUPS_ORDER_BANDED, // cupsColorOrder
CUPS_CSPACE_RGB, // cupsColorSpace
1, // cupsCompression
1, // cupsRowCount
1, // cupsRowFeed
1, // cupsRowStep
0, // cupsNumColors
1.001f, // cupsBorderlessScalingFactor
{ 612.0f, 792.1f }, // cupsPageSize
{ 0.0f, 0.0f, 0.0f, 0.0f }, // cupsImagingBBox
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
// cupsInteger[16]
{ 1.1f, 2.1f, 3.1f, 4.1f, 5.1f, 6.1f, 7.1f, 8.1f, 9.1f, 10.1f, 11.1f, 12.1f, 13.1f, 14.1f, 15.1f, 16.1f }, // cupsReal[16]
{ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",
"14", "15", "16" }, // cupsString[16]
"Marker Type", // cupsMarkerType
"Rendering Intent", // cupsRenderingIntent
"Letter" // cupsPageSizeName
};
static const char *default_code =
"[{\n"
"%%BeginFeature: *InstalledDuplexer False\n"
"%%EndFeature\n"
"} stopped cleartomark\n"
"[{\n"
"%%BeginFeature: *PageRegion Letter\n"
"PageRegion=Letter\n"
"%%EndFeature\n"
"} stopped cleartomark\n"
"[{\n"
"%%BeginFeature: *InputSlot Tray\n"
"InputSlot=Tray\n"
"%%EndFeature\n"
"} stopped cleartomark\n"
"[{\n"
"%%BeginFeature: *OutputBin Tray1\n"
"OutputBin=Tray1\n"
"%%EndFeature\n"
"} stopped cleartomark\n"
"[{\n"
"%%BeginFeature: *MediaType Plain\n"
"MediaType=Plain\n"
"%%EndFeature\n"
"} stopped cleartomark\n"
"[{\n"
"%%BeginFeature: *IntOption None\n"
"%%EndFeature\n"
"} stopped cleartomark\n"
"[{\n"
"%%BeginFeature: *StringOption None\n"
"%%EndFeature\n"
"} stopped cleartomark\n";
static const char *custom_code =
"[{\n"
"%%BeginFeature: *InstalledDuplexer False\n"
"%%EndFeature\n"
"} stopped cleartomark\n"
"[{\n"
"%%BeginFeature: *InputSlot Tray\n"
"InputSlot=Tray\n"
"%%EndFeature\n"
"} stopped cleartomark\n"
"[{\n"
"%%BeginFeature: *MediaType Plain\n"
"MediaType=Plain\n"
"%%EndFeature\n"
"} stopped cleartomark\n"
"[{\n"
"%%BeginFeature: *OutputBin Tray1\n"
"OutputBin=Tray1\n"
"%%EndFeature\n"
"} stopped cleartomark\n"
"[{\n"
"%%BeginFeature: *IntOption None\n"
"%%EndFeature\n"
"} stopped cleartomark\n"
"[{\n"
"%%BeginFeature: *CustomStringOption True\n"
"(value\\0502\\051)\n"
"(value 1)\n"
"StringOption=Custom\n"
"%%EndFeature\n"
"} stopped cleartomark\n"
"[{\n"
"%%BeginFeature: *CustomPageSize True\n"
"400\n"
"500\n"
"0\n"
"0\n"
"0\n"
"PageSize=Custom\n"
"%%EndFeature\n"
"} stopped cleartomark\n";
static const char *default2_code =
"[{\n"
"%%BeginFeature: *InstalledDuplexer False\n"
"%%EndFeature\n"
"} stopped cleartomark\n"
"[{\n"
"%%BeginFeature: *InputSlot Tray\n"
"InputSlot=Tray\n"
"%%EndFeature\n"
"} stopped cleartomark\n"
"[{\n"
"%%BeginFeature: *Quality Normal\n"
"Quality=Normal\n"
"%%EndFeature\n"
"} stopped cleartomark\n"
"[{\n"
"%%BeginFeature: *IntOption None\n"
"%%EndFeature\n"
"} stopped cleartomark\n"
"[{\n"
"%%BeginFeature: *StringOption None\n"
"%%EndFeature\n"
"} stopped cleartomark\n";
//
// '_ppdRasterColorSpaceString()' - Return the colorspace name for a
// cupsColorSpace value.
//
const char *
_ppdRasterColorSpaceString(
cups_cspace_t cspace) // I - cupsColorSpace value
{
static const char * const cups_color_spaces[] =
{ // Color spaces
"W",
"RGB",
"RGBA",
"K",
"CMY",
"YMC",
"CMYK",
"YMCK",
"KCMY",
"KCMYcm",
"GMCK",
"GMCS",
"WHITE",
"GOLD",
"SILVER",
"CIEXYZ",
"CIELab",
"RGBW",
"SW",
"SRGB",
"ADOBERGB",
"21",
"22",
"23",
"24",
"25",
"26",
"27",
"28",
"29",
"30",
"31",
"ICC1",
"ICC2",
"ICC3",
"ICC4",
"ICC5",
"ICC6",
"ICC7",
"ICC8",
"ICC9",
"ICCA",
"ICCB",
"ICCC",
"ICCD",
"ICCE",
"ICCF",
"47",
"DEVICE1",
"DEVICE2",
"DEVICE3",
"DEVICE4",
"DEVICE5",
"DEVICE6",
"DEVICE7",
"DEVICE8",
"DEVICE9",
"DEVICEA",
"DEVICEB",
"DEVICEC",
"DEVICED",
"DEVICEE",
"DEVICEF"
};
if (cspace < CUPS_CSPACE_W || cspace > CUPS_CSPACE_DEVICEF)
return ("Unknown");
else
return (cups_color_spaces[cspace]);
}
//
// '_log()' - Simple log function
//
void
_log(void *data,
cf_loglevel_t level,
const char *message,
...)
{
va_list arglist;
(void)data; // No extra data needed
switch(level)
{
default:
break;
case CF_LOGLEVEL_ERROR:
printf("ERROR: ");
break;
case CF_LOGLEVEL_FATAL:
printf("FATAL: ");
break;
}
va_start(arglist, message);
vprintf(message, arglist);
fflush(stdout);
va_end(arglist);
putchar('\n');
}
//
// 'main()' - Main entry.
//
int // O - Exit status
main(int argc, // I - Number of command-line arguments
char *argv[]) // I - Command-line arguments
{
int i; // Looping var
ppd_file_t *ppd = NULL; // PPD file loaded from disk
int status; // Status of tests (0 = success, 1 = fail)
int conflicts; // Number of conflicts
char *s; // String
char buffer[8192]; // String buffer
const char *text, // Localized text
*val; // Option value
int num_options; // Number of options
cups_option_t *options; // Options
ppd_size_t minsize, // Minimum size
maxsize, // Maximum size
*size; // Current size
ppd_attr_t *attr; // Current attribute
ppd_cache_t *pc; // PPD cache
status = 0;
if (argc == 1)
{
//
// Setup directories for locale stuff...
//
if (access("locale", 0))
{
mkdir("locale", 0777);
mkdir("locale/fr", 0777);
i = symlink("../../../locale/cups_fr.po", "locale/fr/cups_fr.po");
mkdir("locale/zh_TW", 0777);
i = symlink("../../../locale/cups_zh_TW.po", "locale/zh_TW/cups_zh_TW.po");
}
putenv("LOCALEDIR=locale");
putenv("SOFTWARE=CUPS");
//
// Do tests with test.ppd...
//
fputs("ppdOpenFile(\"ppd/test.ppd\"): ", stdout);
if ((ppd = ppdOpenFileWithLocalization("ppd/test.ppd", PPD_LOCALIZATION_ALL)) != NULL)
puts("PASS");
else
{
ppd_status_t err; // Last error in file
int line; // Line number in file
status ++;
err = ppdLastError(&line);
printf("FAIL (%s on line %d)\n", ppdErrorString(err), line);
}
fputs("ppdFindAttr(wildcard): ", stdout);
if ((attr = ppdFindAttr(ppd, "cupsTest", NULL)) == NULL)
{
status ++;
puts("FAIL (not found)");
}
else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Foo"))
{
status ++;
printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
}
else
puts("PASS");
fputs("ppdFindNextAttr(wildcard): ", stdout);
if ((attr = ppdFindNextAttr(ppd, "cupsTest", NULL)) == NULL)
{
status ++;
puts("FAIL (not found)");
}
else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Bar"))
{
status ++;
printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
}
else
puts("PASS");
fputs("ppdFindAttr(Foo): ", stdout);
if ((attr = ppdFindAttr(ppd, "cupsTest", "Foo")) == NULL)
{
status ++;
puts("FAIL (not found)");
}
else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Foo"))
{
status ++;
printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
}
else
puts("PASS");
fputs("ppdFindNextAttr(Foo): ", stdout);
if ((attr = ppdFindNextAttr(ppd, "cupsTest", "Foo")) != NULL)
{
status ++;
printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
}
else
puts("PASS");
fputs("ppdMarkDefaults: ", stdout);
ppdMarkDefaults(ppd);
if ((conflicts = ppdConflicts(ppd)) == 0)
puts("PASS");
else
{
status ++;
printf("FAIL (%d conflicts)\n", conflicts);
}
fputs("ppdEmitString (defaults): ", stdout);
if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
!strcmp(s, default_code))
puts("PASS");
else
{
status ++;
printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
(int)strlen(default_code));
if (s)
puts(s);
}
if (s)
free(s);
fputs("ppdEmitString (custom size and string): ", stdout);
ppdMarkOption(ppd, "PageSize", "Custom.400x500");
ppdMarkOption(ppd, "StringOption",
"{String1=\"value 1\" String2=value(2)}");
if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
!strcmp(s, custom_code))
puts("PASS");
else
{
status ++;
printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
(int)strlen(custom_code));
if (s)
puts(s);
}
if (s)
free(s);
//
// Test constraints...
//
fputs("ppdGetConflicts(InputSlot=Envelope): ", stdout);
ppdMarkOption(ppd, "PageSize", "Letter");
num_options = ppdGetConflicts(ppd, "InputSlot", "Envelope", &options);
if (num_options != 2 ||
(val = cupsGetOption("PageRegion", num_options, options)) == NULL ||
_ppd_strcasecmp(val, "Letter") ||
(val = cupsGetOption("PageSize", num_options, options)) == NULL ||
_ppd_strcasecmp(val, "Letter"))
{
printf("FAIL (%d options:", num_options);
for (i = 0; i < num_options; i ++)
printf(" %s=%s", options[i].name, options[i].value);
puts(")");
status ++;
}
else
puts("PASS");
fputs("ppdConflicts(): ", stdout);
ppdMarkOption(ppd, "InputSlot", "Envelope");
if ((conflicts = ppdConflicts(ppd)) == 2)
puts("PASS (2)");
else
{
printf("FAIL (%d)\n", conflicts);
status ++;
}
fputs("ppdResolveConflicts(InputSlot=Envelope): ", stdout);
num_options = 0;
options = NULL;
if (!ppdResolveConflicts(ppd, "InputSlot", "Envelope", &num_options,
&options))
{
puts("FAIL (Unable to resolve)");
status ++;
}
else if (num_options != 2 ||
!cupsGetOption("PageSize", num_options, options))
{
printf("FAIL (%d options:", num_options);
for (i = 0; i < num_options; i ++)
printf(" %s=%s", options[i].name, options[i].value);
puts(")");
status ++;
}
else
puts("PASS (Resolved by changing PageSize)");
cupsFreeOptions(num_options, options);
fputs("ppdResolveConflicts(No option/choice): ", stdout);
num_options = 0;
options = NULL;
if (ppdResolveConflicts(ppd, NULL, NULL, &num_options, &options) &&
num_options == 1 && !_ppd_strcasecmp(options[0].name, "InputSlot") &&
!_ppd_strcasecmp(options[0].value, "Tray"))
puts("PASS (Resolved by changing InputSlot)");
else if (num_options > 0)
{
printf("FAIL (%d options:", num_options);
for (i = 0; i < num_options; i ++)
printf(" %s=%s", options[i].name, options[i].value);
puts(")");
status ++;
}
else
{
puts("FAIL (Unable to resolve)");
status ++;
}
cupsFreeOptions(num_options, options);
fputs("ppdInstallableConflict(): ", stdout);
if (ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble") &&
!ppdInstallableConflict(ppd, "Duplex", "None"))
puts("PASS");
else if (!ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble"))
{
puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
status ++;
}
else
{
puts("FAIL (Duplex=None conflicted)");
status ++;
}
//
// ppdPageSizeLimits
//
fputs("ppdPageSizeLimits: ", stdout);
if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
{
if (fabs(minsize.width - 36.0) > 0.001 ||
fabs(minsize.length - 36.0) > 0.001 ||
fabs(maxsize.width - 1080.0) > 0.001 ||
fabs(maxsize.length - 86400.0) > 0.001)
{
printf("FAIL (got min=%.3fx%.3f, max=%.3fx%.3f, "
"expected min=36x36, max=1080x86400)\n", minsize.width,
minsize.length, maxsize.width, maxsize.length);
status ++;
}
else
puts("PASS");
}
else
{
puts("FAIL (returned 0)");
status ++;
}
//
// ppdMarkOptions with PWG and IPP size names.
//
fputs("ppdMarkOptions(media=iso-a4): ", stdout);
num_options = cupsAddOption("media", "iso-a4", 0, &options);
ppdMarkOptions(ppd, num_options, options);
cupsFreeOptions(num_options, options);
size = ppdPageSize(ppd, NULL);
if (!size || strcmp(size->name, "A4"))
{
printf("FAIL (%s)\n", size ? size->name : "unknown");
status ++;
}
else
puts("PASS");
fputs("ppdMarkOptions(media=na_letter_8.5x11in): ", stdout);
num_options = cupsAddOption("media", "na_letter_8.5x11in", 0, &options);
ppdMarkOptions(ppd, num_options, options);
cupsFreeOptions(num_options, options);
size = ppdPageSize(ppd, NULL);
if (!size || strcmp(size->name, "Letter"))
{
printf("FAIL (%s)\n", size ? size->name : "unknown");
status ++;
}
else
puts("PASS");
fputs("ppdMarkOptions(media=oe_letter-fullbleed_8.5x11in): ", stdout);
num_options = cupsAddOption("media", "oe_letter-fullbleed_8.5x11in", 0,
&options);
ppdMarkOptions(ppd, num_options, options);
cupsFreeOptions(num_options, options);
size = ppdPageSize(ppd, NULL);
if (!size || strcmp(size->name, "Letter.Fullbleed"))
{
printf("FAIL (%s)\n", size ? size->name : "unknown");
status ++;
}
else
puts("PASS");
fputs("ppdMarkOptions(media=A4): ", stdout);
num_options = cupsAddOption("media", "A4", 0, &options);
ppdMarkOptions(ppd, num_options, options);
cupsFreeOptions(num_options, options);
size = ppdPageSize(ppd, NULL);
if (!size || strcmp(size->name, "A4"))
{
printf("FAIL (%s)\n", size ? size->name : "unknown");
status ++;
}
else
puts("PASS");
//
// Custom sizes...
//
fputs("ppdMarkOptions(media=Custom.8x10in): ", stdout);
num_options = cupsAddOption("media", "Custom.8x10in", 0, &options);
ppdMarkOptions(ppd, num_options, options);
cupsFreeOptions(num_options, options);
size = ppdPageSize(ppd, NULL);
if (!size || strcmp(size->name, "Custom") ||
fabs(size->width - 576.0) > 0.001 ||
fabs(size->length - 720.0) > 0.001)
{
printf("FAIL (%s - %gx%g)\n", size ? size->name : "unknown",
size ? size->width : 0.0, size ? size->length : 0.0);
status ++;
}
else
puts("PASS");
//
// Test localization...
//
// Force US English base locale
putenv("LANG=en");
putenv("LC_ALL=en");
putenv("LC_CTYPE=en");
putenv("LC_MESSAGES=en");
fputs("ppdLocalizeIPPReason(text): ", stdout);
if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
!strcmp(buffer, "Foo Reason"))
puts("PASS");
else
{
status ++;
printf("FAIL (\"%s\" instead of \"Foo Reason\")\n", buffer);
}
fputs("ppdLocalizeIPPReason(http): ", stdout);
if (ppdLocalizeIPPReason(ppd, "foo", "http", buffer, sizeof(buffer)) &&
!strcmp(buffer, "http://foo/bar.html"))
puts("PASS");
else
{
status ++;
printf("FAIL (\"%s\" instead of \"http://foo/bar.html\")\n", buffer);
}
fputs("ppdLocalizeIPPReason(help): ", stdout);
if (ppdLocalizeIPPReason(ppd, "foo", "help", buffer, sizeof(buffer)) &&
!strcmp(buffer, "help:anchor='foo'%20bookID=Vendor%20Help"))
puts("PASS");
else
{
status ++;
printf("FAIL (\"%s\" instead of \"help:anchor='foo'%%20bookID=Vendor%%20Help\")\n", buffer);
}
fputs("ppdLocalizeIPPReason(file): ", stdout);
if (ppdLocalizeIPPReason(ppd, "foo", "file", buffer, sizeof(buffer)) &&
!strcmp(buffer, "/help/foo/bar.html"))
puts("PASS");
else
{
status ++;
printf("FAIL (\"%s\" instead of \"/help/foo/bar.html\")\n", buffer);
}
// Force French
putenv("LANG=fr");
putenv("LC_ALL=fr");
putenv("LC_CTYPE=fr");
putenv("LC_MESSAGES=fr");
fputs("ppdLocalizeIPPReason(fr text): ", stdout);
if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
!strcmp(buffer, "La Long Foo Reason"))
puts("PASS");
else
{
status ++;
printf("FAIL (\"%s\" instead of \"La Long Foo Reason\")\n", buffer);
}
// Force Simplified Chinese
putenv("LANG=zh_TW");
putenv("LC_ALL=zh_TW");
putenv("LC_CTYPE=zh_TW");
putenv("LC_MESSAGES=zh_TW");
fputs("ppdLocalizeIPPReason(zh_TW text): ", stdout);
if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
!strcmp(buffer, "Number 1 Foo Reason"))
puts("PASS");
else
{
status ++;
printf("FAIL (\"%s\" instead of \"Number 1 Foo Reason\")\n", buffer);
}
//
// cupsMarkerName localization...
//
// Force US English base locale
putenv("LANG=en");
putenv("LC_ALL=en");
putenv("LC_CTYPE=en");
putenv("LC_MESSAGES=en");
fputs("ppdLocalizeMarkerName(bogus): ", stdout);
if ((text = ppdLocalizeMarkerName(ppd, "bogus")) != NULL)
{
status ++;
printf("FAIL (\"%s\" instead of NULL)\n", text);
}
else
puts("PASS");
fputs("ppdLocalizeMarkerName(cyan): ", stdout);
if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
!strcmp(text, "Cyan Toner"))
puts("PASS");
else
{
status ++;
printf("FAIL (\"%s\" instead of \"Cyan Toner\")\n",
text ? text : "(null)");
}
// Force French locale
putenv("LANG=fr");
putenv("LC_ALL=fr");
putenv("LC_CTYPE=fr");
putenv("LC_MESSAGES=fr");
fputs("ppdLocalizeMarkerName(fr cyan): ", stdout);
if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
!strcmp(text, "La Toner Cyan"))
puts("PASS");
else
{
status ++;
printf("FAIL (\"%s\" instead of \"La Toner Cyan\")\n",
text ? text : "(null)");
}
// Force Simplified Chinese locale
putenv("LANG=zh_TW");
putenv("LC_ALL=zh_TW");
putenv("LC_CTYPE=zh_TW");
putenv("LC_MESSAGES=zh_TW");
fputs("ppdLocalizeMarkerName(zh_TW cyan): ", stdout);
if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
!strcmp(text, "Number 1 Cyan Toner"))
puts("PASS");
else
{
status ++;
printf("FAIL (\"%s\" instead of \"Number 1 Cyan Toner\")\n",
text ? text : "(null)");
}
ppdClose(ppd);
// Force US English base locale
putenv("LANG=en");
putenv("LC_ALL=en");
putenv("LC_CTYPE=en");
putenv("LC_MESSAGES=en");
//
// Test new constraints...
//
fputs("ppdOpenFile(\"ppd/test2.ppd\"): ", stdout);
if ((ppd = ppdOpenFile("ppd/test2.ppd")) != NULL)
puts("PASS");
else
{
ppd_status_t err; // Last error in file
int line; // Line number in file
status ++;
err = ppdLastError(&line);
printf("FAIL (%s on line %d)\n", ppdErrorString(err), line);
}
fputs("ppdMarkDefaults: ", stdout);
ppdMarkDefaults(ppd);
if ((conflicts = ppdConflicts(ppd)) == 0)
puts("PASS");
else
{
status ++;
printf("FAIL (%d conflicts)\n", conflicts);
}
fputs("ppdEmitString (defaults): ", stdout);
if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
!strcmp(s, default2_code))
puts("PASS");
else
{
status ++;
printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
(int)strlen(default2_code));
if (s)
puts(s);
}
if (s)
free(s);
fputs("ppdConflicts(): ", stdout);
ppdMarkOption(ppd, "PageSize", "Env10");
ppdMarkOption(ppd, "InputSlot", "Envelope");
ppdMarkOption(ppd, "Quality", "Photo");
if ((conflicts = ppdConflicts(ppd)) == 1)
puts("PASS (1)");
else
{
printf("FAIL (%d)\n", conflicts);
status ++;
}
fputs("ppdResolveConflicts(Quality=Photo): ", stdout);
num_options = 0;
options = NULL;
if (ppdResolveConflicts(ppd, "Quality", "Photo", &num_options,
&options))
{
printf("FAIL (%d options:", num_options);
for (i = 0; i < num_options; i ++)
printf(" %s=%s", options[i].name, options[i].value);
puts(")");
status ++;
}
else
puts("PASS (Unable to resolve)");
cupsFreeOptions(num_options, options);
fputs("ppdResolveConflicts(No option/choice): ", stdout);
num_options = 0;
options = NULL;
if (ppdResolveConflicts(ppd, NULL, NULL, &num_options, &options) &&
num_options == 1 && !_ppd_strcasecmp(options->name, "Quality") &&
!_ppd_strcasecmp(options->value, "Normal"))
puts("PASS");
else if (num_options > 0)
{
printf("FAIL (%d options:", num_options);
for (i = 0; i < num_options; i ++)
printf(" %s=%s", options[i].name, options[i].value);
puts(")");
status ++;
}
else
{
puts("FAIL (Unable to resolve!)");
status ++;
}
cupsFreeOptions(num_options, options);
fputs("ppdResolveConflicts(loop test): ", stdout);
ppdMarkOption(ppd, "PageSize", "A4");
ppdMarkOption(ppd, "InputSlot", "Tray");
ppdMarkOption(ppd, "Quality", "Photo");
num_options = 0;
options = NULL;
if (!ppdResolveConflicts(ppd, NULL, NULL, &num_options, &options))
puts("PASS");
else if (num_options > 0)
{
printf("FAIL (%d options:", num_options);
for (i = 0; i < num_options; i ++)
printf(" %s=%s", options[i].name, options[i].value);
puts(")");
}
else
puts("FAIL (No conflicts!)");
fputs("ppdInstallableConflict(): ", stdout);
if (ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble") &&
!ppdInstallableConflict(ppd, "Duplex", "None"))
puts("PASS");
else if (!ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble"))
{
puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
status ++;
}
else
{
puts("FAIL (Duplex=None conflicted)");
status ++;
}
//
// ppdPageSizeLimits
//
ppdMarkDefaults(ppd);
fputs("ppdPageSizeLimits(default): ", stdout);
if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
{
if (fabs(minsize.width - 36.0) > 0.001 ||
fabs(minsize.length - 36.0) > 0.001 ||
fabs(maxsize.width - 1080.0) > 0.001 ||
fabs(maxsize.length - 86400.0) > 0.001)
{
printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
"expected min=36x36, max=1080x86400)\n", minsize.width,
minsize.length, maxsize.width, maxsize.length);
status ++;
}
else
puts("PASS");
}
else
{
puts("FAIL (returned 0)");
status ++;
}
ppdMarkOption(ppd, "InputSlot", "Manual");
fputs("ppdPageSizeLimits(InputSlot=Manual): ", stdout);
if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
{
if (fabs(minsize.width - 100.0) > 0.001 ||
fabs(minsize.length - 100.0) > 0.001 ||
fabs(maxsize.width - 1000.0) > 0.001 ||
fabs(maxsize.length - 1000.0) > 0.001)
{
printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
"expected min=100x100, max=1000x1000)\n", minsize.width,
minsize.length, maxsize.width, maxsize.length);
status ++;
}
else
puts("PASS");
}
else
{
puts("FAIL (returned 0)");
status ++;
}
ppdMarkOption(ppd, "Quality", "Photo");
fputs("ppdPageSizeLimits(Quality=Photo): ", stdout);
if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
{
if (fabs(minsize.width - 200.0) > 0.001 ||
fabs(minsize.length - 200.0) > 0.001 ||
fabs(maxsize.width - 1000.0) > 0.001 ||
fabs(maxsize.length - 1000.0) > 0.001)
{
printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
"expected min=200x200, max=1000x1000)\n", minsize.width,
minsize.length, maxsize.width, maxsize.length);
status ++;
}
else
puts("PASS");
}
else
{
puts("FAIL (returned 0)");
status ++;
}
ppdMarkOption(ppd, "InputSlot", "Tray");
fputs("ppdPageSizeLimits(Quality=Photo): ", stdout);
if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
{
if (fabs(minsize.width - 300.0) > 0.001 ||
fabs(minsize.length - 300.0) > 0.001 ||
fabs(maxsize.width - 1080.0) > 0.001 ||
fabs(maxsize.length - 86400.0) > 0.001)
{
printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
"expected min=300x300, max=1080x86400)\n", minsize.width,
minsize.length, maxsize.width, maxsize.length);
status ++;
}
else
puts("PASS");
}
else
{
puts("FAIL (returned 0)");
status ++;
}
status += do_ps_tests();
}
else if (!strcmp(argv[1], "--raster"))
{
for (status = 0, num_options = 0, options = NULL, i = 1; i < argc; i ++)
{
if (argv[i][0] == '-')
{
if (argv[i][1] == 'o')
{
if (argv[i][2])
num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
else
{
i ++;
if (i < argc)
num_options = cupsParseOptions(argv[i], num_options, &options);
else
{
puts("Usage: testppd --raster [-o name=value ...] [filename.ppd ...]");
return (1);
}
}
}
else
{
puts("Usage: testppd --raster [-o name=value ...] [filename.ppd ...]");
return (1);
}
}
else
status += do_ppd_tests(argv[i], num_options, options);
}
cupsFreeOptions(num_options, options);
}
else if (!strcmp(argv[1], "dump") && argc == 3)
{
ppdCollectionDumpCache(argv[2], _log, NULL);
}
else if (strchr(argv[1], ',') ||
(s = strcasestr(argv[1], ".ppd")) == NULL ||
s[4] != '\0')
{
// First argument is not FILE.ppd but DIR or DIR,DIR,... ->
// PPD directory list -> See whether we have valid PPD collection
cups_array_t *dirlist = _ppdArrayNewStrings(argv[1], ',');
cups_array_t *ppd_collections = cupsArrayNew(NULL, NULL, NULL, 0, NULL, NULL);
ppd_collection_t *col;
cups_option_t *options = NULL;
int num_options = 0;
int i;
char *testname = NULL;
for (s = (char *)cupsArrayGetFirst(dirlist), i = 1;
s;
s = (char *)cupsArrayGetNext(dirlist), i ++)
{
col = (ppd_collection_t *)calloc(1, sizeof(ppd_collection_t));
col->path = s;
printf("Searching directory %d, %s ...\n", i, col->path);
col->name = (char *)calloc(20, sizeof(char));
snprintf(col->name, 19, "%d", i);
cupsArrayAdd(ppd_collections, col);
}
for (i = 2; i < argc; i ++)
if (strlen(argv[i]) > 0 && argv[i][0] != '=')
{
if ((s = strchr(argv[i], '=')) == NULL)
s = "";
else
{
*s = '\0';
s ++;
}
num_options = cupsAddOption(argv[i], s, num_options, &options);
}
cups_array_t *ppds =
ppdCollectionListPPDs(ppd_collections, 0, num_options, options,
_log, NULL);
if (ppds)
{
if (cupsGetOption("only-makes", num_options, options))
{
printf("Found %d manufacturers.\n\n", (int)cupsArrayGetCount(ppds));
for (s = (char *)cupsArrayGetFirst(ppds);
s;
s = (char *)cupsArrayGetNext(ppds))
puts(s);
}
else
{
ppd_info_t *ppd;
printf("Found %d PPD files.\n\n", (int)cupsArrayGetCount(ppds));
puts("mtime,size,model_number,type,filename,name,languages0,products0,"
"psversions0,make,make_and_model,device_id,scheme");
for (ppd = (ppd_info_t *)cupsArrayGetFirst(ppds);
ppd;
ppd = (ppd_info_t *)cupsArrayGetNext(ppds))
{
printf("%d,%ld,%d,%d,\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\","
"\"%s\",\"%s\"\n",
(int)ppd->record.mtime, (long)ppd->record.size,
ppd->record.model_number, ppd->record.type,
ppd->record.filename,
ppd->record.name, ppd->record.languages[0],
ppd->record.products[0],
ppd->record.psversions[0], ppd->record.make,
ppd->record.make_and_model, ppd->record.device_id,
ppd->record.scheme);
testname = ppd->record.name;
}
}
}
if (testname)
{
if ((ppd = ppdOpen2(ppdCollectionGetPPD(testname, ppd_collections,
_log, NULL))) == NULL)
{
ppd_status_t err; // Last error in file
int line; // Line number in file
status ++;
err = ppdLastError(&line);
printf("%s: %s on line %d\n", argv[1], ppdErrorString(err), line);
}
else
{
printf("PPD %s: %s\n", testname, ppd->nickname);
ppdClose(ppd);
}
}
else
printf("%s: No PPD files found.\n", argv[1]);
cupsArrayDelete(dirlist);
for (col = (ppd_collection_t *)cupsArrayGetFirst(ppd_collections);
col;
col = (ppd_collection_t *)cupsArrayGetNext(ppd_collections))
{
free(col->name);
free(col);
}
cupsArrayDelete(ppd_collections);
if (ppds)
{
for (s = (char *)cupsArrayGetFirst(ppds);
s;
s = (char *)cupsArrayGetNext(ppds))
free(s);
cupsArrayDelete(ppds);
}
if (num_options)
cupsFreeOptions(num_options, options);
return (0);
}
else
{
const char *name; // PPD name
char *filename; // Name of actual file containing PPD
struct stat fileinfo; // File information
name = argv[1];
filename = strdup(name);
if ((s = strchr(filename, ':')) != NULL)
*s = '\0';
if (lstat(filename, &fileinfo))
{
printf("%s: %s\n", filename, strerror(errno));
return (1);
}
if (S_ISLNK(fileinfo.st_mode))
{
char realfile[1024]; // Real file path
ssize_t realsize; // Size of real file path
if ((realsize = readlink(filename, realfile, sizeof(realfile) - 1)) < 0)
strlcpy(realfile, "Unknown", sizeof(realfile));
else
realfile[realsize] = '\0';
if (stat(realfile, &fileinfo))
printf("%s: symlink to \"%s\", %s\n", filename, realfile,
strerror(errno));
else
printf("%s: symlink to \"%s\", %ld bytes\n", filename, realfile,
(long)fileinfo.st_size);
}
else
printf("%s: regular file, %ld bytes\n", filename, (long)fileinfo.st_size);
if (s)
printf("\nPPD file %s from %s:\n\n", s + 1, filename);
else
printf("\nPPD file %s:\n\n", filename);
if ((ppd = ppdOpen2(ppdCollectionGetPPD(name, NULL, _log, NULL))) ==
NULL)
{
ppd_status_t err; // Last error in file
int line; // Line number in file
status ++;
err = ppdLastError(&line);
printf("%s: %s on line %d\n", argv[1], ppdErrorString(err), line);
}
else
{
int j, k; // Looping vars
ppd_group_t *group; // Option group
ppd_option_t *option; // Option
ppd_coption_t *coption; // Custom option
ppd_cparam_t *cparam; // Custom parameter
ppd_const_t *c; // UIConstraints
char lang[255], // LANG environment variable
lc_all[255], // LC_ALL environment variable
lc_ctype[255], // LC_CTYPE environment variable
lc_messages[255];// LC_MESSAGES environment variable
if (argc > 2)
{
snprintf(lang, sizeof(lang), "LANG=%s", argv[2]);
putenv(lang);
snprintf(lc_all, sizeof(lc_all), "LC_ALL=%s", argv[2]);
putenv(lc_all);
snprintf(lc_ctype, sizeof(lc_ctype), "LC_CTYPE=%s", argv[2]);
putenv(lc_ctype);
snprintf(lc_messages, sizeof(lc_messages), "LC_MESSAGES=%s", argv[2]);
putenv(lc_messages);
}
ppdLocalize(ppd);
ppdMarkDefaults(ppd);
if (argc > 3)
{
text = ppdLocalizeIPPReason(ppd, argv[3], NULL, buffer, sizeof(buffer));
printf("ppdLocalizeIPPReason(%s)=%s\n", argv[3],
text ? text : "(null)");
free(filename);
return (text == NULL);
}
for (i = ppd->num_groups, group = ppd->groups;
i > 0;
i --, group ++)
{
printf("%s (%s):\n", group->name, group->text);
for (j = group->num_options, option = group->options;
j > 0;
j --, option ++)
{
printf(" %s (%s):\n", option->keyword, option->text);
for (k = 0; k < option->num_choices; k ++)
printf(" - %s%s (%s)\n",
option->choices[k].marked ? "*" : "",
option->choices[k].choice, option->choices[k].text);
if ((coption = ppdFindCustomOption(ppd, option->keyword)) != NULL)
{
for (cparam = (ppd_cparam_t *)cupsArrayGetFirst(coption->params);
cparam;
cparam = (ppd_cparam_t *)cupsArrayGetNext(coption->params))
{
switch (cparam->type)
{
case PPD_CUSTOM_UNKNOWN :
printf(" %s(%s): PPD_CUSTOM_UNKNOWN (error)\n",
cparam->name, cparam->text);
break;
case PPD_CUSTOM_CURVE :
printf(" %s(%s): PPD_CUSTOM_CURVE (%g to %g)\n",
cparam->name, cparam->text,
cparam->minimum.custom_curve,
cparam->maximum.custom_curve);
break;
case PPD_CUSTOM_INT :
printf(" %s(%s): PPD_CUSTOM_INT (%d to %d)\n",
cparam->name, cparam->text,
cparam->minimum.custom_int,
cparam->maximum.custom_int);
break;
case PPD_CUSTOM_INVCURVE :
printf(" %s(%s): PPD_CUSTOM_INVCURVE (%g to %g)\n",
cparam->name, cparam->text,
cparam->minimum.custom_invcurve,
cparam->maximum.custom_invcurve);
break;
case PPD_CUSTOM_PASSCODE :
printf(" %s(%s): PPD_CUSTOM_PASSCODE (%d to %d)\n",
cparam->name, cparam->text,
cparam->minimum.custom_passcode,
cparam->maximum.custom_passcode);
break;
case PPD_CUSTOM_PASSWORD :
printf(" %s(%s): PPD_CUSTOM_PASSWORD (%d to %d)\n",
cparam->name, cparam->text,
cparam->minimum.custom_password,
cparam->maximum.custom_password);
break;
case PPD_CUSTOM_POINTS :
printf(" %s(%s): PPD_CUSTOM_POINTS (%g to %g)\n",
cparam->name, cparam->text,
cparam->minimum.custom_points,
cparam->maximum.custom_points);
break;
case PPD_CUSTOM_REAL :
printf(" %s(%s): PPD_CUSTOM_REAL (%g to %g)\n",
cparam->name, cparam->text,
cparam->minimum.custom_real,
cparam->maximum.custom_real);
break;
case PPD_CUSTOM_STRING :
printf(" %s(%s): PPD_CUSTOM_STRING (%d to %d)\n",
cparam->name, cparam->text,
cparam->minimum.custom_string,
cparam->maximum.custom_string);
break;
}
}
}
}
}
puts("\nSizes:");
for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++)
printf(" %s = %gx%g, [%g %g %g %g]\n", size->name, size->width,
size->length, size->left, size->bottom, size->right, size->top);
puts("\nConstraints:");
for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++)
printf(" *UIConstraints: *%s %s *%s %s\n", c->option1, c->choice1,
c->option2, c->choice2);
if (ppd->num_consts == 0)
puts(" NO CONSTRAINTS");
puts("\nFilters:");
for (i = 0; i < ppd->num_filters; i ++)
printf(" %s\n", ppd->filters[i]);
if (ppd->num_filters == 0)
puts(" NO FILTERS");
puts("\nAttributes:");
for (attr = (ppd_attr_t *)cupsArrayGetFirst(ppd->sorted_attrs);
attr;
attr = (ppd_attr_t *)cupsArrayGetNext(ppd->sorted_attrs))
printf(" *%s %s/%s: \"%s\"\n", attr->name, attr->spec,
attr->text, attr->value ? attr->value : "");
puts("\nPPD Cache:");
if ((pc = ppdCacheCreateWithPPD(ppd)) == NULL)
printf(" Unable to create: %s\n", cupsGetErrorString());
else
{
ppdCacheWriteFile(pc, "t.cache", NULL);
puts(" Wrote t.cache.");
}
}
if (!strncmp(argv[1], "-d", 2))
unlink(filename);
free(filename);
}
#ifdef __APPLE__
if (getenv("MallocStackLogging") && getenv("MallocStackLoggingNoCompact"))
{
char command[1024]; // malloc_history command
snprintf(command, sizeof(command), "malloc_history %d -all_by_size",
getpid());
fflush(stdout);
system(command);
}
#endif // __APPLE__
ppdClose(ppd);
return (status);
}
//
// 'do_ppd_tests()' - Test the default option commands in a PPD file.
//
static int // O - Number of errors
do_ppd_tests(const char *filename, // I - PPD file
int num_options, // I - Number of options
cups_option_t *options) // I - Options
{
ppd_file_t *ppd; // PPD file data
cups_page_header_t header; // Page header
printf("\"%s\": ", filename);
fflush(stdout);
if ((ppd = ppdOpenFile(filename)) == NULL)
{
ppd_status_t status; // Status from PPD loader
int line; // Line number containing error
status = ppdLastError(&line);
puts("FAIL (bad PPD file)");
printf(" %s on line %d\n", ppdErrorString(status), line);
return (1);
}
ppdMarkDefaults(ppd);
ppdMarkOptions(ppd, num_options, options);
if (ppdRasterInterpretPPD(&header, ppd, 0, NULL, NULL))
{
puts("FAIL (error from function)");
puts(_ppdRasterErrorString());
return (1);
}
else
{
puts("PASS");
return (0);
}
}
//
// 'do_ps_tests()' - Test standard PostScript commands.
//
static int
do_ps_tests(void)
{
cups_page_header_t header; // Page header
int preferred_bits; // Preferred bits
int errors = 0; // Number of errors
//
// Test PS exec code...
//
fputs("ppdRasterExecPS(\"setpagedevice\"): ", stdout);
fflush(stdout);
memset(&header, 0, sizeof(header));
header.Collate = CUPS_TRUE;
preferred_bits = 0;
if (ppdRasterExecPS(&header, &preferred_bits, setpagedevice_code))
{
puts("FAIL (error from function)");
puts(_ppdRasterErrorString());
errors ++;
}
else if (preferred_bits != 17 ||
memcmp(&header, &setpagedevice_header, sizeof(header)))
{
puts("FAIL (bad header)");
if (preferred_bits != 17)
printf(" cupsPreferredBitsPerColor %d, expected 17\n",
preferred_bits);
print_changes(&setpagedevice_header, &header);
errors ++;
}
else
puts("PASS");
fputs("ppdRasterExecPS(\"roll\"): ", stdout);
fflush(stdout);
if (ppdRasterExecPS(&header, &preferred_bits,
"792 612 0 0 0\n"
"pop pop pop\n"
"<</PageSize[5 -2 roll]/ImagingBBox null>>"
"setpagedevice\n"))
{
puts("FAIL (error from function)");
puts(_ppdRasterErrorString());
errors ++;
}
else if (header.PageSize[0] != 792 || header.PageSize[1] != 612)
{
printf("FAIL (PageSize [%d %d], expected [792 612])\n", header.PageSize[0],
header.PageSize[1]);
errors ++;
}
else
puts("PASS");
fputs("ppdRasterExecPS(\"dup index\"): ", stdout);
fflush(stdout);
if (ppdRasterExecPS(&header, &preferred_bits,
"true false dup\n"
"<</Collate 4 index"
"/Duplex 5 index"
"/Tumble 6 index>>setpagedevice\n"
"pop pop pop"))
{
puts("FAIL (error from function)");
puts(_ppdRasterErrorString());
errors ++;
}
else
{
if (!header.Collate)
{
printf("FAIL (Collate false, expected true)\n");
errors ++;
}
if (header.Duplex)
{
printf("FAIL (Duplex true, expected false)\n");
errors ++;
}
if (header.Tumble)
{
printf("FAIL (Tumble true, expected false)\n");
errors ++;
}
if(header.Collate && !header.Duplex && !header.Tumble)
puts("PASS");
}
fputs("ppdRasterExecPS(\"%%Begin/EndFeature code\"): ", stdout);
fflush(stdout);
if (ppdRasterExecPS(&header, &preferred_bits, dsc_code))
{
puts("FAIL (error from function)");
puts(_ppdRasterErrorString());
errors ++;
}
else if (header.PageSize[0] != 792 || header.PageSize[1] != 1224)
{
printf("FAIL (bad PageSize [%d %d], expected [792 1224])\n",
header.PageSize[0], header.PageSize[1]);
errors ++;
}
else
puts("PASS");
return (errors);
}
//
// 'print_changes()' - Print differences in the page header.
//
static void
print_changes(
cups_page_header_t *header, // I - Actual page header
cups_page_header_t *expected) // I - Expected page header
{
int i; // Looping var
if (strcmp(header->MediaClass, expected->MediaClass))
printf(" MediaClass (%s), expected (%s)\n", header->MediaClass,
expected->MediaClass);
if (strcmp(header->MediaColor, expected->MediaColor))
printf(" MediaColor (%s), expected (%s)\n", header->MediaColor,
expected->MediaColor);
if (strcmp(header->MediaType, expected->MediaType))
printf(" MediaType (%s), expected (%s)\n", header->MediaType,
expected->MediaType);
if (strcmp(header->OutputType, expected->OutputType))
printf(" OutputType (%s), expected (%s)\n", header->OutputType,
expected->OutputType);
if (header->AdvanceDistance != expected->AdvanceDistance)
printf(" AdvanceDistance %d, expected %d\n", header->AdvanceDistance,
expected->AdvanceDistance);
if (header->AdvanceMedia != expected->AdvanceMedia)
printf(" AdvanceMedia %d, expected %d\n", header->AdvanceMedia,
expected->AdvanceMedia);
if (header->Collate != expected->Collate)
printf(" Collate %d, expected %d\n", header->Collate,
expected->Collate);
if (header->CutMedia != expected->CutMedia)
printf(" CutMedia %d, expected %d\n", header->CutMedia,
expected->CutMedia);
if (header->Duplex != expected->Duplex)
printf(" Duplex %d, expected %d\n", header->Duplex,
expected->Duplex);
if (header->HWResolution[0] != expected->HWResolution[0] ||
header->HWResolution[1] != expected->HWResolution[1])
printf(" HWResolution [%d %d], expected [%d %d]\n",
header->HWResolution[0], header->HWResolution[1],
expected->HWResolution[0], expected->HWResolution[1]);
if (memcmp(header->ImagingBoundingBox, expected->ImagingBoundingBox,
sizeof(header->ImagingBoundingBox)))
printf(" ImagingBoundingBox [%d %d %d %d], expected [%d %d %d %d]\n",
header->ImagingBoundingBox[0],
header->ImagingBoundingBox[1],
header->ImagingBoundingBox[2],
header->ImagingBoundingBox[3],
expected->ImagingBoundingBox[0],
expected->ImagingBoundingBox[1],
expected->ImagingBoundingBox[2],
expected->ImagingBoundingBox[3]);
if (header->InsertSheet != expected->InsertSheet)
printf(" InsertSheet %d, expected %d\n", header->InsertSheet,
expected->InsertSheet);
if (header->Jog != expected->Jog)
printf(" Jog %d, expected %d\n", header->Jog,
expected->Jog);
if (header->LeadingEdge != expected->LeadingEdge)
printf(" LeadingEdge %d, expected %d\n", header->LeadingEdge,
expected->LeadingEdge);
if (header->Margins[0] != expected->Margins[0] ||
header->Margins[1] != expected->Margins[1])
printf(" Margins [%d %d], expected [%d %d]\n",
header->Margins[0], header->Margins[1],
expected->Margins[0], expected->Margins[1]);
if (header->ManualFeed != expected->ManualFeed)
printf(" ManualFeed %d, expected %d\n", header->ManualFeed,
expected->ManualFeed);
if (header->MediaPosition != expected->MediaPosition)
printf(" MediaPosition %d, expected %d\n", header->MediaPosition,
expected->MediaPosition);
if (header->MediaWeight != expected->MediaWeight)
printf(" MediaWeight %d, expected %d\n", header->MediaWeight,
expected->MediaWeight);
if (header->MirrorPrint != expected->MirrorPrint)
printf(" MirrorPrint %d, expected %d\n", header->MirrorPrint,
expected->MirrorPrint);
if (header->NegativePrint != expected->NegativePrint)
printf(" NegativePrint %d, expected %d\n", header->NegativePrint,
expected->NegativePrint);
if (header->NumCopies != expected->NumCopies)
printf(" NumCopies %d, expected %d\n", header->NumCopies,
expected->NumCopies);
if (header->Orientation != expected->Orientation)
printf(" Orientation %d, expected %d\n", header->Orientation,
expected->Orientation);
if (header->OutputFaceUp != expected->OutputFaceUp)
printf(" OutputFaceUp %d, expected %d\n", header->OutputFaceUp,
expected->OutputFaceUp);
if (header->PageSize[0] != expected->PageSize[0] ||
header->PageSize[1] != expected->PageSize[1])
printf(" PageSize [%d %d], expected [%d %d]\n",
header->PageSize[0], header->PageSize[1],
expected->PageSize[0], expected->PageSize[1]);
if (header->Separations != expected->Separations)
printf(" Separations %d, expected %d\n", header->Separations,
expected->Separations);
if (header->TraySwitch != expected->TraySwitch)
printf(" TraySwitch %d, expected %d\n", header->TraySwitch,
expected->TraySwitch);
if (header->Tumble != expected->Tumble)
printf(" Tumble %d, expected %d\n", header->Tumble,
expected->Tumble);
if (header->cupsWidth != expected->cupsWidth)
printf(" cupsWidth %d, expected %d\n", header->cupsWidth,
expected->cupsWidth);
if (header->cupsHeight != expected->cupsHeight)
printf(" cupsHeight %d, expected %d\n", header->cupsHeight,
expected->cupsHeight);
if (header->cupsMediaType != expected->cupsMediaType)
printf(" cupsMediaType %d, expected %d\n", header->cupsMediaType,
expected->cupsMediaType);
if (header->cupsBitsPerColor != expected->cupsBitsPerColor)
printf(" cupsBitsPerColor %d, expected %d\n", header->cupsBitsPerColor,
expected->cupsBitsPerColor);
if (header->cupsBitsPerPixel != expected->cupsBitsPerPixel)
printf(" cupsBitsPerPixel %d, expected %d\n", header->cupsBitsPerPixel,
expected->cupsBitsPerPixel);
if (header->cupsBytesPerLine != expected->cupsBytesPerLine)
printf(" cupsBytesPerLine %d, expected %d\n", header->cupsBytesPerLine,
expected->cupsBytesPerLine);
if (header->cupsColorOrder != expected->cupsColorOrder)
printf(" cupsColorOrder %d, expected %d\n", header->cupsColorOrder,
expected->cupsColorOrder);
if (header->cupsColorSpace != expected->cupsColorSpace)
printf(" cupsColorSpace %s, expected %s\n",
_ppdRasterColorSpaceString(header->cupsColorSpace),
_ppdRasterColorSpaceString(expected->cupsColorSpace));
if (header->cupsCompression != expected->cupsCompression)
printf(" cupsCompression %d, expected %d\n", header->cupsCompression,
expected->cupsCompression);
if (header->cupsRowCount != expected->cupsRowCount)
printf(" cupsRowCount %d, expected %d\n", header->cupsRowCount,
expected->cupsRowCount);
if (header->cupsRowFeed != expected->cupsRowFeed)
printf(" cupsRowFeed %d, expected %d\n", header->cupsRowFeed,
expected->cupsRowFeed);
if (header->cupsRowStep != expected->cupsRowStep)
printf(" cupsRowStep %d, expected %d\n", header->cupsRowStep,
expected->cupsRowStep);
if (header->cupsNumColors != expected->cupsNumColors)
printf(" cupsNumColors %d, expected %d\n", header->cupsNumColors,
expected->cupsNumColors);
if (fabs(header->cupsBorderlessScalingFactor -
expected->cupsBorderlessScalingFactor) > 0.001)
printf(" cupsBorderlessScalingFactor %g, expected %g\n",
header->cupsBorderlessScalingFactor,
expected->cupsBorderlessScalingFactor);
if (fabs(header->cupsPageSize[0] - expected->cupsPageSize[0]) > 0.001 ||
fabs(header->cupsPageSize[1] - expected->cupsPageSize[1]) > 0.001)
printf(" cupsPageSize [%g %g], expected [%g %g]\n",
header->cupsPageSize[0], header->cupsPageSize[1],
expected->cupsPageSize[0], expected->cupsPageSize[1]);
if (fabs(header->cupsImagingBBox[0] - expected->cupsImagingBBox[0]) > 0.001 ||
fabs(header->cupsImagingBBox[1] - expected->cupsImagingBBox[1]) > 0.001 ||
fabs(header->cupsImagingBBox[2] - expected->cupsImagingBBox[2]) > 0.001 ||
fabs(header->cupsImagingBBox[3] - expected->cupsImagingBBox[3]) > 0.001)
printf(" cupsImagingBBox [%g %g %g %g], expected [%g %g %g %g]\n",
header->cupsImagingBBox[0], header->cupsImagingBBox[1],
header->cupsImagingBBox[2], header->cupsImagingBBox[3],
expected->cupsImagingBBox[0], expected->cupsImagingBBox[1],
expected->cupsImagingBBox[2], expected->cupsImagingBBox[3]);
for (i = 0; i < 16; i ++)
if (header->cupsInteger[i] != expected->cupsInteger[i])
printf(" cupsInteger%d %d, expected %d\n", i, header->cupsInteger[i],
expected->cupsInteger[i]);
for (i = 0; i < 16; i ++)
if (fabs(header->cupsReal[i] - expected->cupsReal[i]) > 0.001)
printf(" cupsReal%d %g, expected %g\n", i, header->cupsReal[i],
expected->cupsReal[i]);
for (i = 0; i < 16; i ++)
if (strcmp(header->cupsString[i], expected->cupsString[i]))
printf(" cupsString%d (%s), expected (%s)\n", i,
header->cupsString[i], expected->cupsString[i]);
if (strcmp(header->cupsMarkerType, expected->cupsMarkerType))
printf(" cupsMarkerType (%s), expected (%s)\n", header->cupsMarkerType,
expected->cupsMarkerType);
if (strcmp(header->cupsRenderingIntent, expected->cupsRenderingIntent))
printf(" cupsRenderingIntent (%s), expected (%s)\n",
header->cupsRenderingIntent,
expected->cupsRenderingIntent);
if (strcmp(header->cupsPageSizeName, expected->cupsPageSizeName))
printf(" cupsPageSizeName (%s), expected (%s)\n",
header->cupsPageSizeName,
expected->cupsPageSizeName);
}