]>
Commit | Line | Data |
---|---|---|
fa73b229 | 1 | /* |
b19ccc9e | 2 | * "$Id: testppd.c 7897 2008-09-02 19:33:19Z mike $" |
fa73b229 | 3 | * |
71e16022 | 4 | * PPD test program for CUPS. |
fa73b229 | 5 | * |
f14324a7 | 6 | * Copyright 2007-2011 by Apple Inc. |
fa73b229 | 7 | * Copyright 1997-2006 by Easy Software Products. |
8 | * | |
9 | * These coded instructions, statements, and computer programs are the | |
bc44d920 | 10 | * property of Apple Inc. and are protected by Federal copyright |
11 | * law. Distribution and use rights are outlined in the file "LICENSE.txt" | |
12 | * which should have been included with this file. If this file is | |
13 | * file is missing or damaged, see the license at "http://www.cups.org/". | |
fa73b229 | 14 | * |
15 | * This file is subject to the Apple OS-Developed Software exception. | |
16 | * | |
17 | * Contents: | |
18 | * | |
19 | * main() - Main entry. | |
20 | */ | |
21 | ||
22 | /* | |
23 | * Include necessary headers... | |
24 | */ | |
25 | ||
71e16022 | 26 | #include "cups-private.h" |
c9fc04c6 | 27 | #include <sys/stat.h> |
fa73b229 | 28 | #ifdef WIN32 |
29 | # include <io.h> | |
30 | #else | |
31 | # include <unistd.h> | |
32 | # include <fcntl.h> | |
33 | #endif /* WIN32 */ | |
34 | ||
35 | ||
e1d6a774 | 36 | /* |
37 | * Test data... | |
38 | */ | |
39 | ||
40 | static const char *default_code = | |
66ab9486 MS |
41 | "[{\n" |
42 | "%%BeginFeature: *InstalledDuplexer False\n" | |
43 | "%%EndFeature\n" | |
44 | "} stopped cleartomark\n" | |
e1d6a774 | 45 | "[{\n" |
46 | "%%BeginFeature: *PageRegion Letter\n" | |
47 | "PageRegion=Letter\n" | |
48 | "%%EndFeature\n" | |
49 | "} stopped cleartomark\n" | |
50 | "[{\n" | |
51 | "%%BeginFeature: *InputSlot Tray\n" | |
52 | "InputSlot=Tray\n" | |
53 | "%%EndFeature\n" | |
8ca02f3c | 54 | "} stopped cleartomark\n" |
55 | "[{\n" | |
54afec33 MS |
56 | "%%BeginFeature: *MediaType Plain\n" |
57 | "MediaType=Plain\n" | |
58 | "%%EndFeature\n" | |
59 | "} stopped cleartomark\n" | |
60 | "[{\n" | |
8ca02f3c | 61 | "%%BeginFeature: *IntOption None\n" |
62 | "%%EndFeature\n" | |
63 | "} stopped cleartomark\n" | |
64 | "[{\n" | |
65 | "%%BeginFeature: *StringOption None\n" | |
66 | "%%EndFeature\n" | |
67 | "} stopped cleartomark\n"; | |
68 | ||
69 | static const char *custom_code = | |
66ab9486 MS |
70 | "[{\n" |
71 | "%%BeginFeature: *InstalledDuplexer False\n" | |
72 | "%%EndFeature\n" | |
73 | "} stopped cleartomark\n" | |
8ca02f3c | 74 | "[{\n" |
75 | "%%BeginFeature: *InputSlot Tray\n" | |
76 | "InputSlot=Tray\n" | |
77 | "%%EndFeature\n" | |
78 | "} stopped cleartomark\n" | |
79 | "[{\n" | |
54afec33 MS |
80 | "%%BeginFeature: *MediaType Plain\n" |
81 | "MediaType=Plain\n" | |
82 | "%%EndFeature\n" | |
83 | "} stopped cleartomark\n" | |
84 | "[{\n" | |
8ca02f3c | 85 | "%%BeginFeature: *IntOption None\n" |
86 | "%%EndFeature\n" | |
87 | "} stopped cleartomark\n" | |
88 | "[{\n" | |
ee571f26 MS |
89 | "%%BeginFeature: *CustomStringOption True\n" |
90 | "(value\\0502\\051)\n" | |
91 | "(value 1)\n" | |
92 | "StringOption=Custom\n" | |
8ca02f3c | 93 | "%%EndFeature\n" |
0a682745 MS |
94 | "} stopped cleartomark\n" |
95 | "[{\n" | |
96 | "%%BeginFeature: *CustomPageSize True\n" | |
97 | "400\n" | |
98 | "500\n" | |
99 | "0\n" | |
100 | "0\n" | |
101 | "0\n" | |
102 | "PageSize=Custom\n" | |
103 | "%%EndFeature\n" | |
e1d6a774 | 104 | "} stopped cleartomark\n"; |
105 | ||
f11a948a MS |
106 | static const char *default2_code = |
107 | "[{\n" | |
108 | "%%BeginFeature: *InstalledDuplexer False\n" | |
109 | "%%EndFeature\n" | |
110 | "} stopped cleartomark\n" | |
111 | "[{\n" | |
112 | "%%BeginFeature: *InputSlot Tray\n" | |
113 | "InputSlot=Tray\n" | |
114 | "%%EndFeature\n" | |
115 | "} stopped cleartomark\n" | |
116 | "[{\n" | |
117 | "%%BeginFeature: *Quality Normal\n" | |
118 | "Quality=Normal\n" | |
119 | "%%EndFeature\n" | |
120 | "} stopped cleartomark\n" | |
121 | "[{\n" | |
122 | "%%BeginFeature: *IntOption None\n" | |
123 | "%%EndFeature\n" | |
124 | "} stopped cleartomark\n" | |
125 | "[{\n" | |
126 | "%%BeginFeature: *StringOption None\n" | |
127 | "%%EndFeature\n" | |
128 | "} stopped cleartomark\n"; | |
129 | ||
e1d6a774 | 130 | |
fa73b229 | 131 | /* |
132 | * 'main()' - Main entry. | |
133 | */ | |
134 | ||
135 | int /* O - Exit status */ | |
136 | main(int argc, /* I - Number of command-line arguments */ | |
137 | char *argv[]) /* I - Command-line arguments */ | |
138 | { | |
66ab9486 | 139 | int i; /* Looping var */ |
fa73b229 | 140 | ppd_file_t *ppd; /* PPD file loaded from disk */ |
141 | int status; /* Status of tests (0 = success, 1 = fail) */ | |
e1d6a774 | 142 | int conflicts; /* Number of conflicts */ |
143 | char *s; /* String */ | |
bc44d920 | 144 | char buffer[8192]; /* String buffer */ |
d2354e63 MS |
145 | const char *text, /* Localized text */ |
146 | *val; /* Option value */ | |
66ab9486 MS |
147 | int num_options; /* Number of options */ |
148 | cups_option_t *options; /* Options */ | |
005dd1eb | 149 | ppd_size_t minsize, /* Minimum size */ |
c168a833 MS |
150 | maxsize, /* Maximum size */ |
151 | *size; /* Current size */ | |
6e8b116d | 152 | ppd_attr_t *attr; /* Current attribute */ |
fa73b229 | 153 | |
154 | ||
155 | status = 0; | |
156 | ||
a74454a7 | 157 | if (argc == 1) |
fa73b229 | 158 | { |
c9fc04c6 MS |
159 | /* |
160 | * Setup directories for locale stuff... | |
161 | */ | |
162 | ||
163 | if (access("locale", 0)) | |
164 | { | |
165 | mkdir("locale", 0777); | |
166 | mkdir("locale/fr", 0777); | |
167 | symlink("../../../locale/cups_fr.po", "locale/fr/cups_fr.po"); | |
168 | mkdir("locale/zh_TW", 0777); | |
169 | symlink("../../../locale/cups_zh_TW.po", "locale/zh_TW/cups_zh_TW.po"); | |
170 | } | |
171 | ||
172 | putenv("LOCALEDIR=locale"); | |
b0f6947b | 173 | putenv("SOFTWARE=CUPS"); |
c9fc04c6 MS |
174 | |
175 | /* | |
176 | * Do tests with test.ppd... | |
177 | */ | |
178 | ||
66ab9486 | 179 | fputs("ppdOpenFile(test.ppd): ", stdout); |
a74454a7 | 180 | |
181 | if ((ppd = ppdOpenFile("test.ppd")) != NULL) | |
182 | puts("PASS"); | |
183 | else | |
184 | { | |
185 | ppd_status_t err; /* Last error in file */ | |
186 | int line; /* Line number in file */ | |
187 | ||
188 | ||
189 | status ++; | |
190 | err = ppdLastError(&line); | |
191 | ||
192 | printf("FAIL (%s on line %d)\n", ppdErrorString(err), line); | |
193 | } | |
194 | ||
6e8b116d MS |
195 | fputs("ppdFindAttr(wildcard): ", stdout); |
196 | if ((attr = ppdFindAttr(ppd, "cupsTest", NULL)) == NULL) | |
197 | { | |
198 | status ++; | |
199 | puts("FAIL (not found)"); | |
200 | } | |
201 | else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Foo")) | |
202 | { | |
203 | status ++; | |
204 | printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec); | |
205 | } | |
206 | else | |
207 | puts("PASS"); | |
208 | ||
209 | fputs("ppdFindNextAttr(wildcard): ", stdout); | |
210 | if ((attr = ppdFindNextAttr(ppd, "cupsTest", NULL)) == NULL) | |
211 | { | |
212 | status ++; | |
213 | puts("FAIL (not found)"); | |
214 | } | |
215 | else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Bar")) | |
216 | { | |
217 | status ++; | |
218 | printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec); | |
219 | } | |
220 | else | |
221 | puts("PASS"); | |
222 | ||
223 | fputs("ppdFindAttr(Foo): ", stdout); | |
224 | if ((attr = ppdFindAttr(ppd, "cupsTest", "Foo")) == NULL) | |
225 | { | |
226 | status ++; | |
227 | puts("FAIL (not found)"); | |
228 | } | |
229 | else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Foo")) | |
230 | { | |
231 | status ++; | |
232 | printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec); | |
233 | } | |
234 | else | |
235 | puts("PASS"); | |
236 | ||
237 | fputs("ppdFindNextAttr(Foo): ", stdout); | |
238 | if ((attr = ppdFindNextAttr(ppd, "cupsTest", "Foo")) != NULL) | |
239 | { | |
240 | status ++; | |
241 | printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec); | |
242 | } | |
243 | else | |
244 | puts("PASS"); | |
245 | ||
a74454a7 | 246 | fputs("ppdMarkDefaults: ", stdout); |
247 | ppdMarkDefaults(ppd); | |
248 | ||
249 | if ((conflicts = ppdConflicts(ppd)) == 0) | |
250 | puts("PASS"); | |
251 | else | |
252 | { | |
253 | status ++; | |
254 | printf("FAIL (%d conflicts)\n", conflicts); | |
255 | } | |
256 | ||
8ca02f3c | 257 | fputs("ppdEmitString (defaults): ", stdout); |
a74454a7 | 258 | if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL && |
259 | !strcmp(s, default_code)) | |
260 | puts("PASS"); | |
261 | else | |
262 | { | |
bc44d920 | 263 | status ++; |
a74454a7 | 264 | printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0, |
265 | (int)strlen(default_code)); | |
266 | ||
267 | if (s) | |
268 | puts(s); | |
ed486911 | 269 | } |
270 | ||
8ca02f3c | 271 | if (s) |
272 | free(s); | |
273 | ||
ee571f26 | 274 | fputs("ppdEmitString (custom size and string): ", stdout); |
8ca02f3c | 275 | ppdMarkOption(ppd, "PageSize", "Custom.400x500"); |
ee571f26 | 276 | ppdMarkOption(ppd, "StringOption", "{String1=\"value 1\" String2=value(2)}"); |
8ca02f3c | 277 | |
278 | if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL && | |
279 | !strcmp(s, custom_code)) | |
280 | puts("PASS"); | |
281 | else | |
282 | { | |
bc44d920 | 283 | status ++; |
8ca02f3c | 284 | printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0, |
285 | (int)strlen(custom_code)); | |
286 | ||
287 | if (s) | |
288 | puts(s); | |
289 | } | |
290 | ||
a74454a7 | 291 | if (s) |
292 | free(s); | |
e1d6a774 | 293 | |
66ab9486 MS |
294 | /* |
295 | * Test constraints... | |
296 | */ | |
297 | ||
d2354e63 | 298 | fputs("cupsGetConflicts(InputSlot=Envelope): ", stdout); |
66ab9486 | 299 | ppdMarkOption(ppd, "PageSize", "Letter"); |
d2354e63 MS |
300 | |
301 | num_options = cupsGetConflicts(ppd, "InputSlot", "Envelope", &options); | |
302 | if (num_options != 2 || | |
303 | (val = cupsGetOption("PageRegion", num_options, options)) == NULL || | |
88f9aafc | 304 | _cups_strcasecmp(val, "Letter") || |
d2354e63 | 305 | (val = cupsGetOption("PageSize", num_options, options)) == NULL || |
88f9aafc | 306 | _cups_strcasecmp(val, "Letter")) |
d2354e63 MS |
307 | { |
308 | printf("FAIL (%d options:", num_options); | |
309 | for (i = 0; i < num_options; i ++) | |
310 | printf(" %s=%s", options[i].name, options[i].value); | |
311 | puts(")"); | |
312 | status ++; | |
313 | } | |
314 | else | |
315 | puts("PASS"); | |
316 | ||
317 | fputs("ppdConflicts(): ", stdout); | |
66ab9486 MS |
318 | ppdMarkOption(ppd, "InputSlot", "Envelope"); |
319 | ||
320 | if ((conflicts = ppdConflicts(ppd)) == 2) | |
321 | puts("PASS (2)"); | |
322 | else | |
323 | { | |
324 | printf("FAIL (%d)\n", conflicts); | |
325 | status ++; | |
326 | } | |
327 | ||
06d4e77b | 328 | fputs("cupsResolveConflicts(InputSlot=Envelope): ", stdout); |
66ab9486 MS |
329 | num_options = 0; |
330 | options = NULL; | |
c168a833 | 331 | if (!cupsResolveConflicts(ppd, "InputSlot", "Envelope", &num_options, |
06d4e77b MS |
332 | &options)) |
333 | { | |
c168a833 MS |
334 | puts("FAIL (Unable to resolve)"); |
335 | status ++; | |
336 | } | |
337 | else if (num_options != 2 || | |
338 | !cupsGetOption("PageSize", num_options, options)) | |
339 | { | |
340 | printf("FAIL (%d options:", num_options); | |
341 | for (i = 0; i < num_options; i ++) | |
342 | printf(" %s=%s", options[i].name, options[i].value); | |
343 | puts(")"); | |
06d4e77b MS |
344 | status ++; |
345 | } | |
346 | else | |
c168a833 MS |
347 | puts("PASS (Resolved by changing PageSize)"); |
348 | ||
06d4e77b MS |
349 | cupsFreeOptions(num_options, options); |
350 | ||
351 | fputs("cupsResolveConflicts(No option/choice): ", stdout); | |
352 | num_options = 0; | |
353 | options = NULL; | |
354 | if (cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options) && | |
88f9aafc MS |
355 | num_options == 1 && !_cups_strcasecmp(options[0].name, "InputSlot") && |
356 | !_cups_strcasecmp(options[0].value, "Tray")) | |
c168a833 | 357 | puts("PASS (Resolved by changing InputSlot)"); |
66ab9486 MS |
358 | else if (num_options > 0) |
359 | { | |
360 | printf("FAIL (%d options:", num_options); | |
361 | for (i = 0; i < num_options; i ++) | |
362 | printf(" %s=%s", options[i].name, options[i].value); | |
363 | puts(")"); | |
364 | status ++; | |
365 | } | |
366 | else | |
367 | { | |
06d4e77b | 368 | puts("FAIL (Unable to resolve)"); |
66ab9486 MS |
369 | status ++; |
370 | } | |
371 | cupsFreeOptions(num_options, options); | |
372 | ||
373 | fputs("ppdInstallableConflict(): ", stdout); | |
374 | if (ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble") && | |
375 | !ppdInstallableConflict(ppd, "Duplex", "None")) | |
376 | puts("PASS"); | |
377 | else if (!ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble")) | |
378 | { | |
379 | puts("FAIL (Duplex=DuplexNoTumble did not conflict)"); | |
380 | status ++; | |
381 | } | |
382 | else | |
383 | { | |
384 | puts("FAIL (Duplex=None conflicted)"); | |
385 | status ++; | |
386 | } | |
387 | ||
005dd1eb MS |
388 | /* |
389 | * ppdPageSizeLimits | |
390 | */ | |
391 | ||
392 | fputs("ppdPageSizeLimits: ", stdout); | |
393 | if (ppdPageSizeLimits(ppd, &minsize, &maxsize)) | |
394 | { | |
395 | if (minsize.width != 36 || minsize.length != 36 || | |
396 | maxsize.width != 1080 || maxsize.length != 86400) | |
397 | { | |
398 | printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, " | |
399 | "expected min=36x36, max=1080x86400)\n", minsize.width, | |
400 | minsize.length, maxsize.width, maxsize.length); | |
401 | status ++; | |
402 | } | |
403 | else | |
404 | puts("PASS"); | |
405 | } | |
406 | else | |
407 | { | |
408 | puts("FAIL (returned 0)"); | |
409 | status ++; | |
410 | } | |
411 | ||
c168a833 MS |
412 | /* |
413 | * cupsMarkOptions with PWG and IPP size names. | |
414 | */ | |
415 | ||
416 | fputs("cupsMarkOptions(media=iso-a4): ", stdout); | |
417 | num_options = cupsAddOption("media", "iso-a4", 0, &options); | |
418 | cupsMarkOptions(ppd, num_options, options); | |
419 | cupsFreeOptions(num_options, options); | |
420 | ||
421 | size = ppdPageSize(ppd, NULL); | |
422 | if (!size || strcmp(size->name, "A4")) | |
423 | { | |
424 | printf("FAIL (%s)\n", size ? size->name : "unknown"); | |
425 | status ++; | |
426 | } | |
427 | else | |
428 | puts("PASS"); | |
429 | ||
430 | fputs("cupsMarkOptions(media=na_letter_8.5x11in): ", stdout); | |
431 | num_options = cupsAddOption("media", "na_letter_8.5x11in", 0, &options); | |
432 | cupsMarkOptions(ppd, num_options, options); | |
433 | cupsFreeOptions(num_options, options); | |
434 | ||
435 | size = ppdPageSize(ppd, NULL); | |
436 | if (!size || strcmp(size->name, "Letter")) | |
437 | { | |
438 | printf("FAIL (%s)\n", size ? size->name : "unknown"); | |
439 | status ++; | |
440 | } | |
441 | else | |
442 | puts("PASS"); | |
443 | ||
f14324a7 MS |
444 | fputs("cupsMarkOptions(media=oe_letter-fullbleed_8.5x11in): ", stdout); |
445 | num_options = cupsAddOption("media", "oe_letter-fullbleed_8.5x11in", 0, | |
446 | &options); | |
447 | cupsMarkOptions(ppd, num_options, options); | |
448 | cupsFreeOptions(num_options, options); | |
449 | ||
450 | size = ppdPageSize(ppd, NULL); | |
451 | if (!size || strcmp(size->name, "Letter.Fullbleed")) | |
452 | { | |
453 | printf("FAIL (%s)\n", size ? size->name : "unknown"); | |
454 | status ++; | |
455 | } | |
456 | else | |
457 | puts("PASS"); | |
458 | ||
cc754834 MS |
459 | fputs("cupsMarkOptions(media=A4): ", stdout); |
460 | num_options = cupsAddOption("media", "A4", 0, &options); | |
461 | cupsMarkOptions(ppd, num_options, options); | |
462 | cupsFreeOptions(num_options, options); | |
463 | ||
464 | size = ppdPageSize(ppd, NULL); | |
465 | if (!size || strcmp(size->name, "A4")) | |
466 | { | |
467 | printf("FAIL (%s)\n", size ? size->name : "unknown"); | |
468 | status ++; | |
469 | } | |
470 | else | |
471 | puts("PASS"); | |
472 | ||
bc44d920 | 473 | /* |
474 | * Test localization... | |
475 | */ | |
476 | ||
477 | fputs("ppdLocalizeIPPReason(text): ", stdout); | |
478 | if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) && | |
479 | !strcmp(buffer, "Foo Reason")) | |
480 | puts("PASS"); | |
481 | else | |
482 | { | |
483 | status ++; | |
484 | printf("FAIL (\"%s\" instead of \"Foo Reason\")\n", buffer); | |
485 | } | |
486 | ||
487 | fputs("ppdLocalizeIPPReason(http): ", stdout); | |
488 | if (ppdLocalizeIPPReason(ppd, "foo", "http", buffer, sizeof(buffer)) && | |
489 | !strcmp(buffer, "http://foo/bar.html")) | |
490 | puts("PASS"); | |
491 | else | |
492 | { | |
493 | status ++; | |
494 | printf("FAIL (\"%s\" instead of \"http://foo/bar.html\")\n", buffer); | |
495 | } | |
496 | ||
497 | fputs("ppdLocalizeIPPReason(help): ", stdout); | |
498 | if (ppdLocalizeIPPReason(ppd, "foo", "help", buffer, sizeof(buffer)) && | |
499 | !strcmp(buffer, "help:anchor='foo'%20bookID=Vendor%20Help")) | |
500 | puts("PASS"); | |
501 | else | |
502 | { | |
503 | status ++; | |
504 | printf("FAIL (\"%s\" instead of \"help:anchor='foo'%%20bookID=Vendor%%20Help\")\n", buffer); | |
505 | } | |
506 | ||
507 | fputs("ppdLocalizeIPPReason(file): ", stdout); | |
508 | if (ppdLocalizeIPPReason(ppd, "foo", "file", buffer, sizeof(buffer)) && | |
509 | !strcmp(buffer, "/help/foo/bar.html")) | |
510 | puts("PASS"); | |
511 | else | |
512 | { | |
513 | status ++; | |
514 | printf("FAIL (\"%s\" instead of \"/help/foo/bar.html\")\n", buffer); | |
515 | } | |
516 | ||
517 | putenv("LANG=fr"); | |
c5571a1d MS |
518 | putenv("LC_ALL=fr"); |
519 | putenv("LC_CTYPE=fr"); | |
520 | putenv("LC_MESSAGES=fr"); | |
bc44d920 | 521 | |
522 | fputs("ppdLocalizeIPPReason(fr text): ", stdout); | |
523 | if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) && | |
524 | !strcmp(buffer, "La Long Foo Reason")) | |
525 | puts("PASS"); | |
526 | else | |
527 | { | |
528 | status ++; | |
529 | printf("FAIL (\"%s\" instead of \"La Long Foo Reason\")\n", buffer); | |
530 | } | |
531 | ||
db1f069b | 532 | putenv("LANG=zh_TW"); |
c5571a1d MS |
533 | putenv("LC_ALL=zh_TW"); |
534 | putenv("LC_CTYPE=zh_TW"); | |
535 | putenv("LC_MESSAGES=zh_TW"); | |
db1f069b MS |
536 | |
537 | fputs("ppdLocalizeIPPReason(zh_TW text): ", stdout); | |
538 | if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) && | |
539 | !strcmp(buffer, "Number 1 Foo Reason")) | |
540 | puts("PASS"); | |
541 | else | |
542 | { | |
543 | status ++; | |
544 | printf("FAIL (\"%s\" instead of \"Number 1 Foo Reason\")\n", buffer); | |
545 | } | |
5a738aea MS |
546 | |
547 | /* | |
548 | * cupsMarkerName localization... | |
549 | */ | |
550 | ||
551 | putenv("LANG=en"); | |
c5571a1d MS |
552 | putenv("LC_ALL=en"); |
553 | putenv("LC_CTYPE=en"); | |
554 | putenv("LC_MESSAGES=en"); | |
5a738aea MS |
555 | |
556 | fputs("ppdLocalizeMarkerName(bogus): ", stdout); | |
557 | ||
558 | if ((text = ppdLocalizeMarkerName(ppd, "bogus")) != NULL) | |
559 | { | |
560 | status ++; | |
561 | printf("FAIL (\"%s\" instead of NULL)\n", text); | |
562 | } | |
563 | else | |
564 | puts("PASS"); | |
565 | ||
566 | fputs("ppdLocalizeMarkerName(cyan): ", stdout); | |
567 | ||
568 | if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL && | |
569 | !strcmp(text, "Cyan Toner")) | |
570 | puts("PASS"); | |
571 | else | |
572 | { | |
573 | status ++; | |
574 | printf("FAIL (\"%s\" instead of \"Cyan Toner\")\n", | |
575 | text ? text : "(null)"); | |
576 | } | |
577 | ||
578 | putenv("LANG=fr"); | |
c5571a1d MS |
579 | putenv("LC_ALL=fr"); |
580 | putenv("LC_CTYPE=fr"); | |
581 | putenv("LC_MESSAGES=fr"); | |
5a738aea MS |
582 | |
583 | fputs("ppdLocalizeMarkerName(fr cyan): ", stdout); | |
584 | if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL && | |
585 | !strcmp(text, "La Toner Cyan")) | |
586 | puts("PASS"); | |
587 | else | |
588 | { | |
589 | status ++; | |
590 | printf("FAIL (\"%s\" instead of \"La Toner Cyan\")\n", | |
591 | text ? text : "(null)"); | |
592 | } | |
593 | ||
594 | putenv("LANG=zh_TW"); | |
c5571a1d MS |
595 | putenv("LC_ALL=zh_TW"); |
596 | putenv("LC_CTYPE=zh_TW"); | |
597 | putenv("LC_MESSAGES=zh_TW"); | |
5a738aea MS |
598 | |
599 | fputs("ppdLocalizeMarkerName(zh_TW cyan): ", stdout); | |
600 | if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL && | |
601 | !strcmp(text, "Number 1 Cyan Toner")) | |
602 | puts("PASS"); | |
603 | else | |
604 | { | |
605 | status ++; | |
606 | printf("FAIL (\"%s\" instead of \"Number 1 Cyan Toner\")\n", | |
607 | text ? text : "(null)"); | |
608 | } | |
66ab9486 MS |
609 | |
610 | ppdClose(ppd); | |
611 | ||
612 | /* | |
613 | * Test new constraints... | |
614 | */ | |
615 | ||
616 | fputs("ppdOpenFile(test2.ppd): ", stdout); | |
617 | ||
618 | if ((ppd = ppdOpenFile("test2.ppd")) != NULL) | |
619 | puts("PASS"); | |
620 | else | |
621 | { | |
622 | ppd_status_t err; /* Last error in file */ | |
623 | int line; /* Line number in file */ | |
624 | ||
625 | ||
626 | status ++; | |
627 | err = ppdLastError(&line); | |
628 | ||
629 | printf("FAIL (%s on line %d)\n", ppdErrorString(err), line); | |
630 | } | |
631 | ||
632 | fputs("ppdMarkDefaults: ", stdout); | |
633 | ppdMarkDefaults(ppd); | |
634 | ||
635 | if ((conflicts = ppdConflicts(ppd)) == 0) | |
636 | puts("PASS"); | |
637 | else | |
638 | { | |
639 | status ++; | |
640 | printf("FAIL (%d conflicts)\n", conflicts); | |
641 | } | |
642 | ||
f11a948a MS |
643 | fputs("ppdEmitString (defaults): ", stdout); |
644 | if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL && | |
645 | !strcmp(s, default2_code)) | |
646 | puts("PASS"); | |
647 | else | |
648 | { | |
649 | status ++; | |
650 | printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0, | |
651 | (int)strlen(default2_code)); | |
652 | ||
653 | if (s) | |
654 | puts(s); | |
655 | } | |
656 | ||
657 | if (s) | |
658 | free(s); | |
659 | ||
66ab9486 MS |
660 | fputs("ppdConflicts(): ", stdout); |
661 | ppdMarkOption(ppd, "PageSize", "Env10"); | |
662 | ppdMarkOption(ppd, "InputSlot", "Envelope"); | |
663 | ppdMarkOption(ppd, "Quality", "Photo"); | |
664 | ||
1340db2d MS |
665 | if ((conflicts = ppdConflicts(ppd)) == 1) |
666 | puts("PASS (1)"); | |
66ab9486 MS |
667 | else |
668 | { | |
669 | printf("FAIL (%d)\n", conflicts); | |
670 | status ++; | |
671 | } | |
672 | ||
06d4e77b | 673 | fputs("cupsResolveConflicts(Quality=Photo): ", stdout); |
66ab9486 MS |
674 | num_options = 0; |
675 | options = NULL; | |
676 | if (cupsResolveConflicts(ppd, "Quality", "Photo", &num_options, | |
06d4e77b MS |
677 | &options)) |
678 | { | |
679 | printf("FAIL (%d options:", num_options); | |
680 | for (i = 0; i < num_options; i ++) | |
681 | printf(" %s=%s", options[i].name, options[i].value); | |
682 | puts(")"); | |
683 | status ++; | |
684 | } | |
685 | else | |
686 | puts("PASS (Unable to resolve)"); | |
687 | cupsFreeOptions(num_options, options); | |
688 | ||
689 | fputs("cupsResolveConflicts(No option/choice): ", stdout); | |
690 | num_options = 0; | |
691 | options = NULL; | |
692 | if (cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options) && | |
88f9aafc MS |
693 | num_options == 1 && !_cups_strcasecmp(options->name, "Quality") && |
694 | !_cups_strcasecmp(options->value, "Normal")) | |
66ab9486 MS |
695 | puts("PASS"); |
696 | else if (num_options > 0) | |
697 | { | |
698 | printf("FAIL (%d options:", num_options); | |
699 | for (i = 0; i < num_options; i ++) | |
700 | printf(" %s=%s", options[i].name, options[i].value); | |
701 | puts(")"); | |
702 | status ++; | |
703 | } | |
704 | else | |
705 | { | |
706 | puts("FAIL (Unable to resolve!)"); | |
707 | status ++; | |
708 | } | |
709 | cupsFreeOptions(num_options, options); | |
710 | ||
711 | fputs("cupsResolveConflicts(loop test): ", stdout); | |
712 | ppdMarkOption(ppd, "PageSize", "A4"); | |
1340db2d | 713 | ppdMarkOption(ppd, "InputSlot", "Tray"); |
66ab9486 MS |
714 | ppdMarkOption(ppd, "Quality", "Photo"); |
715 | num_options = 0; | |
716 | options = NULL; | |
06d4e77b | 717 | if (!cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options)) |
66ab9486 MS |
718 | puts("PASS"); |
719 | else if (num_options > 0) | |
720 | { | |
721 | printf("FAIL (%d options:", num_options); | |
722 | for (i = 0; i < num_options; i ++) | |
723 | printf(" %s=%s", options[i].name, options[i].value); | |
724 | puts(")"); | |
725 | } | |
726 | else | |
727 | puts("FAIL (No conflicts!)"); | |
6d2f911b | 728 | |
66ab9486 MS |
729 | fputs("ppdInstallableConflict(): ", stdout); |
730 | if (ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble") && | |
731 | !ppdInstallableConflict(ppd, "Duplex", "None")) | |
732 | puts("PASS"); | |
733 | else if (!ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble")) | |
734 | { | |
735 | puts("FAIL (Duplex=DuplexNoTumble did not conflict)"); | |
736 | status ++; | |
737 | } | |
738 | else | |
739 | { | |
740 | puts("FAIL (Duplex=None conflicted)"); | |
741 | status ++; | |
742 | } | |
005dd1eb MS |
743 | |
744 | /* | |
745 | * ppdPageSizeLimits | |
746 | */ | |
747 | ||
748 | ppdMarkDefaults(ppd); | |
749 | ||
750 | fputs("ppdPageSizeLimits(default): ", stdout); | |
751 | if (ppdPageSizeLimits(ppd, &minsize, &maxsize)) | |
752 | { | |
753 | if (minsize.width != 36 || minsize.length != 36 || | |
754 | maxsize.width != 1080 || maxsize.length != 86400) | |
755 | { | |
756 | printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, " | |
757 | "expected min=36x36, max=1080x86400)\n", minsize.width, | |
758 | minsize.length, maxsize.width, maxsize.length); | |
759 | status ++; | |
760 | } | |
761 | else | |
762 | puts("PASS"); | |
763 | } | |
764 | else | |
765 | { | |
766 | puts("FAIL (returned 0)"); | |
767 | status ++; | |
768 | } | |
769 | ||
770 | ppdMarkOption(ppd, "InputSlot", "Manual"); | |
771 | ||
772 | fputs("ppdPageSizeLimits(InputSlot=Manual): ", stdout); | |
773 | if (ppdPageSizeLimits(ppd, &minsize, &maxsize)) | |
774 | { | |
775 | if (minsize.width != 100 || minsize.length != 100 || | |
776 | maxsize.width != 1000 || maxsize.length != 1000) | |
777 | { | |
778 | printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, " | |
779 | "expected min=100x100, max=1000x1000)\n", minsize.width, | |
780 | minsize.length, maxsize.width, maxsize.length); | |
781 | status ++; | |
782 | } | |
783 | else | |
784 | puts("PASS"); | |
785 | } | |
786 | else | |
787 | { | |
788 | puts("FAIL (returned 0)"); | |
789 | status ++; | |
790 | } | |
791 | ||
792 | ppdMarkOption(ppd, "Quality", "Photo"); | |
793 | ||
794 | fputs("ppdPageSizeLimits(Quality=Photo): ", stdout); | |
795 | if (ppdPageSizeLimits(ppd, &minsize, &maxsize)) | |
796 | { | |
797 | if (minsize.width != 200 || minsize.length != 200 || | |
798 | maxsize.width != 1000 || maxsize.length != 1000) | |
799 | { | |
800 | printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, " | |
801 | "expected min=200x200, max=1000x1000)\n", minsize.width, | |
802 | minsize.length, maxsize.width, maxsize.length); | |
803 | status ++; | |
804 | } | |
805 | else | |
806 | puts("PASS"); | |
807 | } | |
808 | else | |
809 | { | |
810 | puts("FAIL (returned 0)"); | |
811 | status ++; | |
812 | } | |
813 | ||
814 | ppdMarkOption(ppd, "InputSlot", "Tray"); | |
815 | ||
816 | fputs("ppdPageSizeLimits(Quality=Photo): ", stdout); | |
817 | if (ppdPageSizeLimits(ppd, &minsize, &maxsize)) | |
818 | { | |
819 | if (minsize.width != 300 || minsize.length != 300 || | |
820 | maxsize.width != 1080 || maxsize.length != 86400) | |
821 | { | |
822 | printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, " | |
823 | "expected min=300x300, max=1080x86400)\n", minsize.width, | |
824 | minsize.length, maxsize.width, maxsize.length); | |
825 | status ++; | |
826 | } | |
827 | else | |
828 | puts("PASS"); | |
829 | } | |
830 | else | |
831 | { | |
832 | puts("FAIL (returned 0)"); | |
833 | status ++; | |
834 | } | |
e1d6a774 | 835 | } |
e1d6a774 | 836 | else |
837 | { | |
dd1abb6b | 838 | const char *filename; /* PPD filename */ |
d1c13e16 | 839 | struct stat fileinfo; /* File information */ |
dd1abb6b MS |
840 | |
841 | ||
842 | if (!strncmp(argv[1], "-d", 2)) | |
749b1e90 | 843 | { |
c8fef167 MS |
844 | const char *printer; /* Printer name */ |
845 | ||
846 | if (argv[1][2]) | |
847 | printer = argv[1] + 2; | |
848 | else if (argv[2]) | |
849 | printer = argv[2]; | |
850 | else | |
851 | { | |
852 | puts("Usage: ./testppd -d printer"); | |
853 | return (1); | |
854 | } | |
855 | ||
856 | filename = cupsGetPPD(printer); | |
857 | ||
749b1e90 MS |
858 | if (!filename) |
859 | { | |
c8fef167 | 860 | printf("%s: %s\n", printer, cupsLastErrorString()); |
749b1e90 MS |
861 | return (1); |
862 | } | |
863 | } | |
dd1abb6b MS |
864 | else |
865 | filename = argv[1]; | |
866 | ||
d1c13e16 MS |
867 | if (lstat(filename, &fileinfo)) |
868 | { | |
869 | printf("%s: %s\n", filename, strerror(errno)); | |
870 | return (1); | |
871 | } | |
872 | ||
873 | if (S_ISLNK(fileinfo.st_mode)) | |
874 | { | |
875 | char realfile[1024]; /* Real file path */ | |
876 | ssize_t realsize; /* Size of real file path */ | |
877 | ||
878 | ||
879 | if ((realsize = readlink(filename, realfile, sizeof(realfile) - 1)) < 0) | |
880 | strcpy(realfile, "Unknown"); | |
881 | else | |
882 | realfile[realsize] = '\0'; | |
883 | ||
884 | if (stat(realfile, &fileinfo)) | |
885 | printf("%s: symlink to \"%s\", %s\n", filename, realfile, | |
886 | strerror(errno)); | |
887 | else | |
888 | printf("%s: symlink to \"%s\", %ld bytes\n", filename, realfile, | |
889 | (long)fileinfo.st_size); | |
890 | } | |
891 | else | |
892 | printf("%s: regular file, %ld bytes\n", filename, (long)fileinfo.st_size); | |
893 | ||
dd1abb6b | 894 | if ((ppd = ppdOpenFile(filename)) == NULL) |
a74454a7 | 895 | { |
896 | ppd_status_t err; /* Last error in file */ | |
897 | int line; /* Line number in file */ | |
898 | ||
899 | ||
900 | status ++; | |
901 | err = ppdLastError(&line); | |
902 | ||
903 | printf("%s: %s on line %d\n", argv[1], ppdErrorString(err), line); | |
904 | } | |
905 | else | |
906 | { | |
66ab9486 | 907 | int j, k; /* Looping vars */ |
a74454a7 | 908 | ppd_group_t *group; /* Option group */ |
909 | ppd_option_t *option; /* Option */ | |
b86bc4cf | 910 | ppd_coption_t *coption; /* Custom option */ |
911 | ppd_cparam_t *cparam; /* Custom parameter */ | |
66ab9486 | 912 | ppd_const_t *c; /* UIConstraints */ |
c5571a1d MS |
913 | char lang[255], /* LANG environment variable */ |
914 | lc_all[255], /* LC_ALL environment variable */ | |
915 | lc_ctype[255], /* LC_CTYPE environment variable */ | |
916 | lc_messages[255];/* LC_MESSAGES environment variable */ | |
a74454a7 | 917 | |
918 | ||
d09495fa | 919 | if (argc > 2) |
920 | { | |
921 | snprintf(lang, sizeof(lang), "LANG=%s", argv[2]); | |
922 | putenv(lang); | |
c5571a1d MS |
923 | snprintf(lc_all, sizeof(lc_all), "LC_ALL=%s", argv[2]); |
924 | putenv(lc_all); | |
925 | snprintf(lc_ctype, sizeof(lc_ctype), "LC_CTYPE=%s", argv[2]); | |
926 | putenv(lc_ctype); | |
927 | snprintf(lc_messages, sizeof(lc_messages), "LC_MESSAGES=%s", argv[2]); | |
928 | putenv(lc_messages); | |
d09495fa | 929 | } |
930 | ||
a74454a7 | 931 | ppdLocalize(ppd); |
f0ab5bff | 932 | ppdMarkDefaults(ppd); |
a74454a7 | 933 | |
e4572d57 MS |
934 | if (argc > 3) |
935 | { | |
936 | text = ppdLocalizeIPPReason(ppd, argv[3], NULL, buffer, sizeof(buffer)); | |
937 | printf("ppdLocalizeIPPReason(%s)=%s\n", argv[3], | |
938 | text ? text : "(null)"); | |
939 | return (text == NULL); | |
940 | } | |
941 | ||
a74454a7 | 942 | for (i = ppd->num_groups, group = ppd->groups; |
943 | i > 0; | |
944 | i --, group ++) | |
945 | { | |
946 | printf("%s (%s):\n", group->name, group->text); | |
d09495fa | 947 | |
a74454a7 | 948 | for (j = group->num_options, option = group->options; |
949 | j > 0; | |
950 | j --, option ++) | |
951 | { | |
952 | printf(" %s (%s):\n", option->keyword, option->text); | |
953 | ||
954 | for (k = 0; k < option->num_choices; k ++) | |
f0ab5bff MS |
955 | printf(" - %s%s (%s)\n", |
956 | option->choices[k].marked ? "*" : "", | |
957 | option->choices[k].choice, option->choices[k].text); | |
b86bc4cf | 958 | |
959 | if ((coption = ppdFindCustomOption(ppd, option->keyword)) != NULL) | |
960 | { | |
961 | for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); | |
962 | cparam; | |
963 | cparam = (ppd_cparam_t *)cupsArrayNext(coption->params)) | |
964 | { | |
965 | switch (cparam->type) | |
966 | { | |
967 | case PPD_CUSTOM_CURVE : | |
968 | printf(" %s(%s): PPD_CUSTOM_CURVE (%g to %g)\n", | |
969 | cparam->name, cparam->text, | |
970 | cparam->minimum.custom_curve, | |
971 | cparam->maximum.custom_curve); | |
972 | break; | |
973 | ||
974 | case PPD_CUSTOM_INT : | |
975 | printf(" %s(%s): PPD_CUSTOM_INT (%d to %d)\n", | |
976 | cparam->name, cparam->text, | |
977 | cparam->minimum.custom_int, | |
978 | cparam->maximum.custom_int); | |
979 | break; | |
980 | ||
981 | case PPD_CUSTOM_INVCURVE : | |
982 | printf(" %s(%s): PPD_CUSTOM_INVCURVE (%g to %g)\n", | |
983 | cparam->name, cparam->text, | |
984 | cparam->minimum.custom_invcurve, | |
985 | cparam->maximum.custom_invcurve); | |
986 | break; | |
987 | ||
988 | case PPD_CUSTOM_PASSCODE : | |
989 | printf(" %s(%s): PPD_CUSTOM_PASSCODE (%d to %d)\n", | |
990 | cparam->name, cparam->text, | |
991 | cparam->minimum.custom_passcode, | |
992 | cparam->maximum.custom_passcode); | |
993 | break; | |
994 | ||
995 | case PPD_CUSTOM_PASSWORD : | |
996 | printf(" %s(%s): PPD_CUSTOM_PASSWORD (%d to %d)\n", | |
997 | cparam->name, cparam->text, | |
998 | cparam->minimum.custom_password, | |
999 | cparam->maximum.custom_password); | |
1000 | break; | |
1001 | ||
1002 | case PPD_CUSTOM_POINTS : | |
1003 | printf(" %s(%s): PPD_CUSTOM_POINTS (%g to %g)\n", | |
1004 | cparam->name, cparam->text, | |
1005 | cparam->minimum.custom_points, | |
1006 | cparam->maximum.custom_points); | |
1007 | break; | |
1008 | ||
1009 | case PPD_CUSTOM_REAL : | |
1010 | printf(" %s(%s): PPD_CUSTOM_REAL (%g to %g)\n", | |
1011 | cparam->name, cparam->text, | |
1012 | cparam->minimum.custom_real, | |
1013 | cparam->maximum.custom_real); | |
1014 | break; | |
1015 | ||
1016 | case PPD_CUSTOM_STRING : | |
1017 | printf(" %s(%s): PPD_CUSTOM_STRING (%d to %d)\n", | |
1018 | cparam->name, cparam->text, | |
1019 | cparam->minimum.custom_string, | |
1020 | cparam->maximum.custom_string); | |
1021 | break; | |
1022 | } | |
1023 | } | |
1024 | } | |
a74454a7 | 1025 | } |
1026 | } | |
d09495fa | 1027 | |
030ae6a1 MS |
1028 | puts("\nSizes:"); |
1029 | for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++) | |
1030 | printf(" %s = %gx%g, [%g %g %g %g]\n", size->name, size->width, | |
1031 | size->length, size->left, size->bottom, size->right, size->top); | |
1032 | ||
1340db2d | 1033 | puts("\nConstraints:"); |
66ab9486 MS |
1034 | |
1035 | for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++) | |
1036 | printf(" *UIConstraints: *%s %s *%s %s\n", c->option1, c->choice1, | |
1037 | c->option2, c->choice2); | |
1340db2d MS |
1038 | if (ppd->num_consts == 0) |
1039 | puts(" NO CONSTRAINTS"); | |
1040 | ||
1041 | puts("\nFilters:"); | |
1042 | ||
1043 | for (i = 0; i < ppd->num_filters; i ++) | |
1044 | printf(" %s\n", ppd->filters[i]); | |
1045 | ||
1046 | if (ppd->num_filters == 0) | |
1047 | puts(" NO FILTERS"); | |
66ab9486 | 1048 | |
1340db2d | 1049 | puts("\nAttributes:"); |
d09495fa | 1050 | |
1051 | for (attr = (ppd_attr_t *)cupsArrayFirst(ppd->sorted_attrs); | |
1052 | attr; | |
1053 | attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs)) | |
1054 | printf(" *%s %s/%s: \"%s\"\n", attr->name, attr->spec, | |
1055 | attr->text, attr->value ? attr->value : ""); | |
a74454a7 | 1056 | } |
dd1abb6b MS |
1057 | |
1058 | if (!strncmp(argv[1], "-d", 2)) | |
1059 | unlink(filename); | |
e1d6a774 | 1060 | } |
1061 | ||
2e4ff8af MS |
1062 | #ifdef __APPLE__ |
1063 | if (getenv("MallocStackLogging") && getenv("MallocStackLoggingNoCompact")) | |
1064 | { | |
1065 | char command[1024]; /* malloc_history command */ | |
1066 | ||
1067 | snprintf(command, sizeof(command), "malloc_history %d -all_by_size", | |
1068 | getpid()); | |
1069 | fflush(stdout); | |
1070 | system(command); | |
1071 | } | |
1072 | #endif /* __APPLE__ */ | |
1073 | ||
1074 | ppdClose(ppd); | |
1075 | ||
fa73b229 | 1076 | return (status); |
1077 | } | |
1078 | ||
1079 | ||
1080 | /* | |
b19ccc9e | 1081 | * End of "$Id: testppd.c 7897 2008-09-02 19:33:19Z mike $". |
fa73b229 | 1082 | */ |