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