1/*
2 * PWG unit test program for CUPS.
3 *
4 * Copyright 2009-2016 by Apple Inc.
5 *
6 * These coded instructions, statements, and computer programs are the
7 * property of Apple Inc. and are protected by Federal copyright
8 * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
9 * which should have been included with this file.  If this file is
10 * missing or damaged, see the license at "http://www.cups.org/".
11 *
12 * This file is subject to the Apple OS-Developed Software exception.
13 */
14
15/*
16 * Include necessary headers...
17 */
18
19#include "ppd-private.h"
20#include "file-private.h"
21
22
23/*
24 * Local functions...
25 */
26
27static int	test_pagesize(_ppd_cache_t *pc, ppd_file_t *ppd,
28		              const char *ppdsize);
29static int	test_ppd_cache(_ppd_cache_t *pc, ppd_file_t *ppd);
30
31
32/*
33 * 'main()' - Main entry.
34 */
35
36int					/* O - Exit status */
37main(int  argc,				/* I - Number of command-line args */
38     char *argv[])			/* I - Command-line arguments */
39{
40  int			status;		/* Status of tests (0 = success, 1 = fail) */
41  const char		*ppdfile;	/* PPD filename */
42  ppd_file_t		*ppd;		/* PPD file */
43  _ppd_cache_t		*pc;		/* PPD cache and PWG mapping data */
44  const pwg_media_t	*pwgmedia;	/* PWG media size */
45  size_t		i,		/* Looping var */
46			num_media;	/* Number of media sizes */
47  const pwg_media_t	*mediatable;	/* Media size table */
48  int			dupmedia = 0;	/* Duplicate media sizes? */
49
50
51  status = 0;
52
53  if (argc < 2 || argc > 3)
54  {
55    puts("Usage: ./testpwg filename.ppd [jobfile]");
56    return (1);
57  }
58
59  ppdfile = argv[1];
60
61  printf("ppdOpenFile(%s): ", ppdfile);
62  if ((ppd = ppdOpenFile(ppdfile)) == NULL)
63  {
64    ppd_status_t err;			/* Last error in file */
65    int		line;			/* Line number in file */
66
67
68    err = ppdLastError(&line);
69
70    printf("FAIL (%s on line %d)\n", ppdErrorString(err), line);
71
72    return (1);
73  }
74  else
75    puts("PASS");
76
77  fputs("_ppdCacheCreateWithPPD(ppd): ", stdout);
78  if ((pc = _ppdCacheCreateWithPPD(ppd)) == NULL)
79  {
80    puts("FAIL");
81    status ++;
82  }
83  else
84  {
85    puts("PASS");
86    status += test_ppd_cache(pc, ppd);
87
88    if (argc == 3)
89    {
90     /*
91      * Test PageSize mapping code.
92      */
93
94      int		fd;		/* Job file descriptor */
95      const char	*pagesize;	/* PageSize value */
96      ipp_t		*job;		/* Job attributes */
97      ipp_attribute_t	*media;		/* Media attribute */
98
99      if ((fd = open(argv[2], O_RDONLY)) >= 0)
100      {
101	job = ippNew();
102	ippReadFile(fd, job);
103	close(fd);
104
105        if ((media = ippFindAttribute(job, "media", IPP_TAG_ZERO)) != NULL &&
106	    media->value_tag != IPP_TAG_NAME &&
107	    media->value_tag != IPP_TAG_KEYWORD)
108	  media = NULL;
109
110	if (media)
111	  printf("_ppdCacheGetPageSize(media=%s): ",
112	         media->values[0].string.text);
113	else
114	  fputs("_ppdCacheGetPageSize(media-col): ", stdout);
115
116        fflush(stdout);
117
118	if ((pagesize = _ppdCacheGetPageSize(pc, job, NULL, NULL)) == NULL)
119	{
120	  puts("FAIL (Not Found)");
121	  status = 1;
122	}
123	else if (media && _cups_strcasecmp(pagesize, media->values[0].string.text))
124	{
125	  printf("FAIL (Got \"%s\", Expected \"%s\")\n", pagesize,
126		 media->values[0].string.text);
127	  status = 1;
128	}
129	else
130	  printf("PASS (%s)\n", pagesize);
131
132	ippDelete(job);
133      }
134      else
135      {
136        perror(argv[2]);
137	status = 1;
138      }
139    }
140
141   /*
142    * _ppdCacheDestroy should never fail...
143    */
144
145    fputs("_ppdCacheDestroy(pc): ", stdout);
146    _ppdCacheDestroy(pc);
147    puts("PASS");
148  }
149
150  fputs("pwgMediaForPWG(\"iso_a4_210x297mm\"): ", stdout);
151  if ((pwgmedia = pwgMediaForPWG("iso_a4_210x297mm")) == NULL)
152  {
153    puts("FAIL (not found)");
154    status ++;
155  }
156  else if (strcmp(pwgmedia->pwg, "iso_a4_210x297mm"))
157  {
158    printf("FAIL (%s)\n", pwgmedia->pwg);
159    status ++;
160  }
161  else if (pwgmedia->width != 21000 || pwgmedia->length != 29700)
162  {
163    printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length);
164    status ++;
165  }
166  else
167    puts("PASS");
168
169  fputs("pwgMediaForPWG(\"roll_max_36.1025x3622.0472in\"): ", stdout);
170  if ((pwgmedia = pwgMediaForPWG("roll_max_36.1025x3622.0472in")) == NULL)
171  {
172    puts("FAIL (not found)");
173    status ++;
174  }
175  else if (pwgmedia->width != 91700 || pwgmedia->length != 9199999)
176  {
177    printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length);
178    status ++;
179  }
180  else
181    printf("PASS (%dx%d)\n", pwgmedia->width, pwgmedia->length);
182
183  fputs("pwgMediaForPWG(\"disc_test_10x100mm\"): ", stdout);
184  if ((pwgmedia = pwgMediaForPWG("disc_test_10x100mm")) == NULL)
185  {
186    puts("FAIL (not found)");
187    status ++;
188  }
189  else if (pwgmedia->width != 10000 || pwgmedia->length != 10000)
190  {
191    printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length);
192    status ++;
193  }
194  else
195    printf("PASS (%dx%d)\n", pwgmedia->width, pwgmedia->length);
196
197  fputs("pwgMediaForLegacy(\"na-letter\"): ", stdout);
198  if ((pwgmedia = pwgMediaForLegacy("na-letter")) == NULL)
199  {
200    puts("FAIL (not found)");
201    status ++;
202  }
203  else if (strcmp(pwgmedia->pwg, "na_letter_8.5x11in"))
204  {
205    printf("FAIL (%s)\n", pwgmedia->pwg);
206    status ++;
207  }
208  else if (pwgmedia->width != 21590 || pwgmedia->length != 27940)
209  {
210    printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length);
211    status ++;
212  }
213  else
214    puts("PASS");
215
216  fputs("pwgMediaForPPD(\"4x6\"): ", stdout);
217  if ((pwgmedia = pwgMediaForPPD("4x6")) == NULL)
218  {
219    puts("FAIL (not found)");
220    status ++;
221  }
222  else if (strcmp(pwgmedia->pwg, "na_index-4x6_4x6in"))
223  {
224    printf("FAIL (%s)\n", pwgmedia->pwg);
225    status ++;
226  }
227  else if (pwgmedia->width != 10160 || pwgmedia->length != 15240)
228  {
229    printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length);
230    status ++;
231  }
232  else
233    puts("PASS");
234
235  fputs("pwgMediaForPPD(\"10x15cm\"): ", stdout);
236  if ((pwgmedia = pwgMediaForPPD("10x15cm")) == NULL)
237  {
238    puts("FAIL (not found)");
239    status ++;
240  }
241  else if (strcmp(pwgmedia->pwg, "om_100x150mm_100x150mm"))
242  {
243    printf("FAIL (%s)\n", pwgmedia->pwg);
244    status ++;
245  }
246  else if (pwgmedia->width != 10000 || pwgmedia->length != 15000)
247  {
248    printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length);
249    status ++;
250  }
251  else
252    puts("PASS");
253
254  fputs("pwgMediaForPPD(\"Custom.10x15cm\"): ", stdout);
255  if ((pwgmedia = pwgMediaForPPD("Custom.10x15cm")) == NULL)
256  {
257    puts("FAIL (not found)");
258    status ++;
259  }
260  else if (strcmp(pwgmedia->pwg, "custom_10x15cm_100x150mm"))
261  {
262    printf("FAIL (%s)\n", pwgmedia->pwg);
263    status ++;
264  }
265  else if (pwgmedia->width != 10000 || pwgmedia->length != 15000)
266  {
267    printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length);
268    status ++;
269  }
270  else
271    puts("PASS");
272
273  fputs("pwgMediaForSize(29700, 42000): ", stdout);
274  if ((pwgmedia = pwgMediaForSize(29700, 42000)) == NULL)
275  {
276    puts("FAIL (not found)");
277    status ++;
278  }
279  else if (strcmp(pwgmedia->pwg, "iso_a3_297x420mm"))
280  {
281    printf("FAIL (%s)\n", pwgmedia->pwg);
282    status ++;
283  }
284  else
285    puts("PASS");
286
287  fputs("pwgMediaForSize(9842, 19050): ", stdout);
288  if ((pwgmedia = pwgMediaForSize(9842, 19050)) == NULL)
289  {
290    puts("FAIL (not found)");
291    status ++;
292  }
293  else if (strcmp(pwgmedia->pwg, "na_monarch_3.875x7.5in"))
294  {
295    printf("FAIL (%s)\n", pwgmedia->pwg);
296    status ++;
297  }
298  else
299    printf("PASS (%s)\n", pwgmedia->pwg);
300
301  fputs("pwgMediaForSize(9800, 19000): ", stdout);
302  if ((pwgmedia = pwgMediaForSize(9800, 19000)) == NULL)
303  {
304    puts("FAIL (not found)");
305    status ++;
306  }
307  else if (strcmp(pwgmedia->pwg, "jpn_you6_98x190mm"))
308  {
309    printf("FAIL (%s)\n", pwgmedia->pwg);
310    status ++;
311  }
312  else
313    printf("PASS (%s)\n", pwgmedia->pwg);
314
315  fputs("Duplicate size test: ", stdout);
316  for (mediatable = _pwgMediaTable(&num_media);
317       num_media > 1;
318       num_media --, mediatable ++)
319  {
320    for (i = num_media - 1, pwgmedia = mediatable + 1; i > 0; i --, pwgmedia ++)
321    {
322      if (pwgmedia->width == mediatable->width &&
323          pwgmedia->length == mediatable->length)
324      {
325        if (!dupmedia)
326        {
327          dupmedia = 1;
328          status ++;
329          puts("FAIL");
330        }
331
332        printf("    %s and %s have the same dimensions (%dx%d)\n",
333               pwgmedia->pwg, mediatable->pwg, pwgmedia->width,
334               pwgmedia->length);
335      }
336    }
337  }
338  if (!dupmedia)
339    puts("PASS");
340
341
342  return (status);
343}
344
345
346/*
347 * 'test_pagesize()' - Test the PWG mapping functions.
348 */
349
350static int				/* O - 1 on failure, 0 on success */
351test_pagesize(_ppd_cache_t *pc,		/* I - PWG mapping data */
352              ppd_file_t   *ppd,	/* I - PPD file */
353	      const char   *ppdsize)	/* I - PPD page size */
354{
355  int		status = 0;		/* Return status */
356  ipp_t		*job;			/* Job attributes */
357  const char	*pagesize;		/* PageSize value */
358
359
360  if (ppdPageSize(ppd, ppdsize))
361  {
362    printf("_ppdCacheGetPageSize(keyword=%s): ", ppdsize);
363    fflush(stdout);
364
365    if ((pagesize = _ppdCacheGetPageSize(pc, NULL, ppdsize, NULL)) == NULL)
366    {
367      puts("FAIL (Not Found)");
368      status = 1;
369    }
370    else if (_cups_strcasecmp(pagesize, ppdsize))
371    {
372      printf("FAIL (Got \"%s\", Expected \"%s\")\n", pagesize, ppdsize);
373      status = 1;
374    }
375    else
376      puts("PASS");
377
378    job = ippNew();
379    ippAddString(job, IPP_TAG_JOB, IPP_TAG_KEYWORD, "media", NULL, ppdsize);
380
381    printf("_ppdCacheGetPageSize(media=%s): ", ppdsize);
382    fflush(stdout);
383
384    if ((pagesize = _ppdCacheGetPageSize(pc, job, NULL, NULL)) == NULL)
385    {
386      puts("FAIL (Not Found)");
387      status = 1;
388    }
389    else if (_cups_strcasecmp(pagesize, ppdsize))
390    {
391      printf("FAIL (Got \"%s\", Expected \"%s\")\n", pagesize, ppdsize);
392      status = 1;
393    }
394    else
395      puts("PASS");
396
397    ippDelete(job);
398  }
399
400  return (status);
401}
402
403
404/*
405 * 'test_ppd_cache()' - Test the PPD cache functions.
406 */
407
408static int				/* O - 1 on failure, 0 on success */
409test_ppd_cache(_ppd_cache_t *pc,	/* I - PWG mapping data */
410               ppd_file_t   *ppd)	/* I - PPD file */
411{
412  int		i,			/* Looping var */
413		status = 0;		/* Return status */
414  _ppd_cache_t	*pc2;			/* Loaded data */
415  pwg_size_t	*size,			/* Size from original */
416		*size2;			/* Size from saved */
417  pwg_map_t	*map,			/* Map from original */
418		*map2;			/* Map from saved */
419
420
421 /*
422  * Verify that we can write and read back the same data...
423  */
424
425  fputs("_ppdCacheWriteFile(test.pwg): ", stdout);
426  if (!_ppdCacheWriteFile(pc, "test.pwg", NULL))
427  {
428    puts("FAIL");
429    status ++;
430  }
431  else
432    puts("PASS");
433
434  fputs("_ppdCacheCreateWithFile(test.pwg): ", stdout);
435  if ((pc2 = _ppdCacheCreateWithFile("test.pwg", NULL)) == NULL)
436  {
437    puts("FAIL");
438    status ++;
439  }
440  else
441  {
442    // TODO: FINISH ADDING ALL VALUES IN STRUCTURE
443    if (pc2->num_sizes != pc->num_sizes)
444    {
445      if (!status)
446        puts("FAIL");
447
448      printf("    SAVED num_sizes=%d, ORIG num_sizes=%d\n", pc2->num_sizes,
449             pc->num_sizes);
450
451      status ++;
452    }
453    else
454    {
455      for (i = pc->num_sizes, size = pc->sizes, size2 = pc2->sizes;
456           i > 0;
457	   i --, size ++, size2 ++)
458      {
459        if (strcmp(size2->map.pwg, size->map.pwg) ||
460	    strcmp(size2->map.ppd, size->map.ppd) ||
461	    size2->width != size->width ||
462	    size2->length != size->length ||
463	    size2->left != size->left ||
464	    size2->bottom != size->bottom ||
465	    size2->right != size->right ||
466	    size2->top != size->top)
467	{
468	  if (!status)
469	    puts("FAIL");
470
471	  if (strcmp(size->map.pwg, size2->map.pwg))
472	    printf("    SAVED size->map.pwg=\"%s\", ORIG "
473	           "size->map.pwg=\"%s\"\n", size2->map.pwg, size->map.pwg);
474
475	  if (strcmp(size2->map.ppd, size->map.ppd))
476	    printf("    SAVED size->map.ppd=\"%s\", ORIG "
477	           "size->map.ppd=\"%s\"\n", size2->map.ppd, size->map.ppd);
478
479	  if (size2->width != size->width)
480	    printf("    SAVED size->width=%d, ORIG size->width=%d\n",
481		   size2->width, size->width);
482
483	  if (size2->length != size->length)
484	    printf("    SAVED size->length=%d, ORIG size->length=%d\n",
485		   size2->length, size->length);
486
487	  if (size2->left != size->left)
488	    printf("    SAVED size->left=%d, ORIG size->left=%d\n",
489		   size2->left, size->left);
490
491	  if (size2->bottom != size->bottom)
492	    printf("    SAVED size->bottom=%d, ORIG size->bottom=%d\n",
493		   size2->bottom, size->bottom);
494
495	  if (size2->right != size->right)
496	    printf("    SAVED size->right=%d, ORIG size->right=%d\n",
497		   size2->right, size->right);
498
499	  if (size2->top != size->top)
500	    printf("    SAVED size->top=%d, ORIG size->top=%d\n",
501		   size2->top, size->top);
502
503	  status ++;
504	  break;
505	}
506      }
507
508      for (i = pc->num_sources, map = pc->sources, map2 = pc2->sources;
509           i > 0;
510	   i --, map ++, map2 ++)
511      {
512        if (strcmp(map2->pwg, map->pwg) ||
513	    strcmp(map2->ppd, map->ppd))
514	{
515	  if (!status)
516	    puts("FAIL");
517
518	  if (strcmp(map->pwg, map2->pwg))
519	    printf("    SAVED source->pwg=\"%s\", ORIG source->pwg=\"%s\"\n",
520	           map2->pwg, map->pwg);
521
522	  if (strcmp(map2->ppd, map->ppd))
523	    printf("    SAVED source->ppd=\"%s\", ORIG source->ppd=\"%s\"\n",
524	           map2->ppd, map->ppd);
525
526	  status ++;
527	  break;
528	}
529      }
530
531      for (i = pc->num_types, map = pc->types, map2 = pc2->types;
532           i > 0;
533	   i --, map ++, map2 ++)
534      {
535        if (strcmp(map2->pwg, map->pwg) ||
536	    strcmp(map2->ppd, map->ppd))
537	{
538	  if (!status)
539	    puts("FAIL");
540
541	  if (strcmp(map->pwg, map2->pwg))
542	    printf("    SAVED type->pwg=\"%s\", ORIG type->pwg=\"%s\"\n",
543	           map2->pwg, map->pwg);
544
545	  if (strcmp(map2->ppd, map->ppd))
546	    printf("    SAVED type->ppd=\"%s\", ORIG type->ppd=\"%s\"\n",
547	           map2->ppd, map->ppd);
548
549	  status ++;
550	  break;
551	}
552      }
553    }
554
555    if (!status)
556      puts("PASS");
557
558    _ppdCacheDestroy(pc2);
559  }
560
561 /*
562  * Test PageSize mapping code...
563  */
564
565  status += test_pagesize(pc, ppd, "Letter");
566  status += test_pagesize(pc, ppd, "na-letter");
567  status += test_pagesize(pc, ppd, "A4");
568  status += test_pagesize(pc, ppd, "iso-a4");
569
570  return (status);
571}
572