xref: /aosp_15_r20/external/libcups/systemv/cupstestppd.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * PPD test program for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * THIS PROGRAM IS DEPRECATED AND WILL BE REMOVED IN A FUTURE VERSION OF CUPS.
5*5e7646d2SAndroid Build Coastguard Worker  *
6*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 2007-2018 by Apple Inc.
7*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
8*5e7646d2SAndroid Build Coastguard Worker  *
9*5e7646d2SAndroid Build Coastguard Worker  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
10*5e7646d2SAndroid Build Coastguard Worker  * information.
11*5e7646d2SAndroid Build Coastguard Worker  *
12*5e7646d2SAndroid Build Coastguard Worker  * PostScript is a trademark of Adobe Systems, Inc.
13*5e7646d2SAndroid Build Coastguard Worker  */
14*5e7646d2SAndroid Build Coastguard Worker 
15*5e7646d2SAndroid Build Coastguard Worker /*
16*5e7646d2SAndroid Build Coastguard Worker  * Include necessary headers...
17*5e7646d2SAndroid Build Coastguard Worker  */
18*5e7646d2SAndroid Build Coastguard Worker 
19*5e7646d2SAndroid Build Coastguard Worker #include <cups/cups-private.h>
20*5e7646d2SAndroid Build Coastguard Worker #include <cups/dir.h>
21*5e7646d2SAndroid Build Coastguard Worker #include <cups/ppd-private.h>
22*5e7646d2SAndroid Build Coastguard Worker #include <cups/raster.h>
23*5e7646d2SAndroid Build Coastguard Worker #include <math.h>
24*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
25*5e7646d2SAndroid Build Coastguard Worker #  define X_OK 0
26*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
27*5e7646d2SAndroid Build Coastguard Worker 
28*5e7646d2SAndroid Build Coastguard Worker 
29*5e7646d2SAndroid Build Coastguard Worker /*
30*5e7646d2SAndroid Build Coastguard Worker  * Error warning overrides...
31*5e7646d2SAndroid Build Coastguard Worker  */
32*5e7646d2SAndroid Build Coastguard Worker 
33*5e7646d2SAndroid Build Coastguard Worker enum
34*5e7646d2SAndroid Build Coastguard Worker {
35*5e7646d2SAndroid Build Coastguard Worker   WARN_NONE = 0,
36*5e7646d2SAndroid Build Coastguard Worker   WARN_CONSTRAINTS = 1,
37*5e7646d2SAndroid Build Coastguard Worker   WARN_DEFAULTS = 2,
38*5e7646d2SAndroid Build Coastguard Worker   WARN_FILTERS = 4,
39*5e7646d2SAndroid Build Coastguard Worker   WARN_PROFILES = 8,
40*5e7646d2SAndroid Build Coastguard Worker   WARN_TRANSLATIONS = 16,
41*5e7646d2SAndroid Build Coastguard Worker   WARN_DUPLEX = 32,
42*5e7646d2SAndroid Build Coastguard Worker   WARN_SIZES = 64,
43*5e7646d2SAndroid Build Coastguard Worker   WARN_FILENAME = 128,
44*5e7646d2SAndroid Build Coastguard Worker   WARN_ALL = 255
45*5e7646d2SAndroid Build Coastguard Worker };
46*5e7646d2SAndroid Build Coastguard Worker 
47*5e7646d2SAndroid Build Coastguard Worker 
48*5e7646d2SAndroid Build Coastguard Worker /*
49*5e7646d2SAndroid Build Coastguard Worker  * Error codes...
50*5e7646d2SAndroid Build Coastguard Worker  */
51*5e7646d2SAndroid Build Coastguard Worker 
52*5e7646d2SAndroid Build Coastguard Worker enum
53*5e7646d2SAndroid Build Coastguard Worker {
54*5e7646d2SAndroid Build Coastguard Worker   ERROR_NONE = 0,
55*5e7646d2SAndroid Build Coastguard Worker   ERROR_USAGE,
56*5e7646d2SAndroid Build Coastguard Worker   ERROR_FILE_OPEN,
57*5e7646d2SAndroid Build Coastguard Worker   ERROR_PPD_FORMAT,
58*5e7646d2SAndroid Build Coastguard Worker   ERROR_CONFORMANCE
59*5e7646d2SAndroid Build Coastguard Worker };
60*5e7646d2SAndroid Build Coastguard Worker 
61*5e7646d2SAndroid Build Coastguard Worker 
62*5e7646d2SAndroid Build Coastguard Worker /*
63*5e7646d2SAndroid Build Coastguard Worker  * Line endings...
64*5e7646d2SAndroid Build Coastguard Worker  */
65*5e7646d2SAndroid Build Coastguard Worker 
66*5e7646d2SAndroid Build Coastguard Worker enum
67*5e7646d2SAndroid Build Coastguard Worker {
68*5e7646d2SAndroid Build Coastguard Worker   EOL_NONE = 0,
69*5e7646d2SAndroid Build Coastguard Worker   EOL_CR,
70*5e7646d2SAndroid Build Coastguard Worker   EOL_LF,
71*5e7646d2SAndroid Build Coastguard Worker   EOL_CRLF
72*5e7646d2SAndroid Build Coastguard Worker };
73*5e7646d2SAndroid Build Coastguard Worker 
74*5e7646d2SAndroid Build Coastguard Worker 
75*5e7646d2SAndroid Build Coastguard Worker /*
76*5e7646d2SAndroid Build Coastguard Worker  * File permissions...
77*5e7646d2SAndroid Build Coastguard Worker  */
78*5e7646d2SAndroid Build Coastguard Worker 
79*5e7646d2SAndroid Build Coastguard Worker #define MODE_WRITE	0022		/* Group/other write */
80*5e7646d2SAndroid Build Coastguard Worker #define MODE_MASK	0555		/* Owner/group/other read+exec/search */
81*5e7646d2SAndroid Build Coastguard Worker #define MODE_DATAFILE	0444		/* Owner/group/other read */
82*5e7646d2SAndroid Build Coastguard Worker #define MODE_DIRECTORY	0555		/* Owner/group/other read+search */
83*5e7646d2SAndroid Build Coastguard Worker #define MODE_PROGRAM	0555		/* Owner/group/other read+exec */
84*5e7646d2SAndroid Build Coastguard Worker 
85*5e7646d2SAndroid Build Coastguard Worker 
86*5e7646d2SAndroid Build Coastguard Worker /*
87*5e7646d2SAndroid Build Coastguard Worker  * Local functions...
88*5e7646d2SAndroid Build Coastguard Worker  */
89*5e7646d2SAndroid Build Coastguard Worker 
90*5e7646d2SAndroid Build Coastguard Worker static void	check_basics(const char *filename);
91*5e7646d2SAndroid Build Coastguard Worker static int	check_constraints(ppd_file_t *ppd, int errors, int verbose,
92*5e7646d2SAndroid Build Coastguard Worker 		                  int warn);
93*5e7646d2SAndroid Build Coastguard Worker static int	check_case(ppd_file_t *ppd, int errors, int verbose);
94*5e7646d2SAndroid Build Coastguard Worker static int	check_defaults(ppd_file_t *ppd, int errors, int verbose,
95*5e7646d2SAndroid Build Coastguard Worker 		               int warn);
96*5e7646d2SAndroid Build Coastguard Worker static int	check_duplex(ppd_file_t *ppd, int errors, int verbose,
97*5e7646d2SAndroid Build Coastguard Worker 		             int warn);
98*5e7646d2SAndroid Build Coastguard Worker static int	check_filters(ppd_file_t *ppd, const char *root, int errors,
99*5e7646d2SAndroid Build Coastguard Worker 		              int verbose, int warn);
100*5e7646d2SAndroid Build Coastguard Worker static int	check_profiles(ppd_file_t *ppd, const char *root, int errors,
101*5e7646d2SAndroid Build Coastguard Worker 		               int verbose, int warn);
102*5e7646d2SAndroid Build Coastguard Worker static int	check_sizes(ppd_file_t *ppd, int errors, int verbose, int warn);
103*5e7646d2SAndroid Build Coastguard Worker static int	check_translations(ppd_file_t *ppd, int errors, int verbose,
104*5e7646d2SAndroid Build Coastguard Worker 		                   int warn);
105*5e7646d2SAndroid Build Coastguard Worker static void	show_conflicts(ppd_file_t *ppd, const char *prefix);
106*5e7646d2SAndroid Build Coastguard Worker static int	test_raster(ppd_file_t *ppd, int verbose);
107*5e7646d2SAndroid Build Coastguard Worker static void	usage(void) _CUPS_NORETURN;
108*5e7646d2SAndroid Build Coastguard Worker static int	valid_path(const char *keyword, const char *path, int errors,
109*5e7646d2SAndroid Build Coastguard Worker 		           int verbose, int warn);
110*5e7646d2SAndroid Build Coastguard Worker static int	valid_utf8(const char *s);
111*5e7646d2SAndroid Build Coastguard Worker 
112*5e7646d2SAndroid Build Coastguard Worker 
113*5e7646d2SAndroid Build Coastguard Worker /*
114*5e7646d2SAndroid Build Coastguard Worker  * 'main()' - Main entry for test program.
115*5e7646d2SAndroid Build Coastguard Worker  */
116*5e7646d2SAndroid Build Coastguard Worker 
117*5e7646d2SAndroid Build Coastguard Worker int					/* O - Exit status */
main(int argc,char * argv[])118*5e7646d2SAndroid Build Coastguard Worker main(int  argc,				/* I - Number of command-line args */
119*5e7646d2SAndroid Build Coastguard Worker      char *argv[])			/* I - Command-line arguments */
120*5e7646d2SAndroid Build Coastguard Worker {
121*5e7646d2SAndroid Build Coastguard Worker   int		i, j, k, m, n;		/* Looping vars */
122*5e7646d2SAndroid Build Coastguard Worker   size_t	len;			/* Length of option name */
123*5e7646d2SAndroid Build Coastguard Worker   char		*opt;			/* Option character */
124*5e7646d2SAndroid Build Coastguard Worker   const char	*ptr;			/* Pointer into string */
125*5e7646d2SAndroid Build Coastguard Worker   cups_file_t	*fp;			/* PPD file */
126*5e7646d2SAndroid Build Coastguard Worker   int		files;			/* Number of files */
127*5e7646d2SAndroid Build Coastguard Worker   int		verbose;		/* Want verbose output? */
128*5e7646d2SAndroid Build Coastguard Worker   int		warn;			/* Which errors to just warn about */
129*5e7646d2SAndroid Build Coastguard Worker   int		ignore;			/* Which errors to ignore */
130*5e7646d2SAndroid Build Coastguard Worker   int		status;			/* Exit status */
131*5e7646d2SAndroid Build Coastguard Worker   int		errors;			/* Number of conformance errors */
132*5e7646d2SAndroid Build Coastguard Worker   int		ppdversion;		/* PPD spec version in PPD file */
133*5e7646d2SAndroid Build Coastguard Worker   ppd_status_t	error;			/* Status of ppdOpen*() */
134*5e7646d2SAndroid Build Coastguard Worker   int		line;			/* Line number for error */
135*5e7646d2SAndroid Build Coastguard Worker   char		*root;			/* Root directory */
136*5e7646d2SAndroid Build Coastguard Worker   int		xdpi,			/* X resolution */
137*5e7646d2SAndroid Build Coastguard Worker 		ydpi;			/* Y resolution */
138*5e7646d2SAndroid Build Coastguard Worker   ppd_file_t	*ppd;			/* PPD file record */
139*5e7646d2SAndroid Build Coastguard Worker   ppd_attr_t	*attr;			/* PPD attribute */
140*5e7646d2SAndroid Build Coastguard Worker   ppd_size_t	*size;			/* Size record */
141*5e7646d2SAndroid Build Coastguard Worker   ppd_group_t	*group;			/* UI group */
142*5e7646d2SAndroid Build Coastguard Worker   ppd_option_t	*option;		/* Standard UI option */
143*5e7646d2SAndroid Build Coastguard Worker   ppd_group_t	*group2;		/* UI group */
144*5e7646d2SAndroid Build Coastguard Worker   ppd_option_t	*option2;		/* Standard UI option */
145*5e7646d2SAndroid Build Coastguard Worker   ppd_choice_t	*choice;		/* Standard UI option choice */
146*5e7646d2SAndroid Build Coastguard Worker   struct lconv	*loc;			/* Locale data */
147*5e7646d2SAndroid Build Coastguard Worker   static char	*uis[] = { "BOOLEAN", "PICKONE", "PICKMANY" };
148*5e7646d2SAndroid Build Coastguard Worker   static char	*sections[] = { "ANY", "DOCUMENT", "EXIT",
149*5e7646d2SAndroid Build Coastguard Worker                                 "JCL", "PAGE", "PROLOG" };
150*5e7646d2SAndroid Build Coastguard Worker 
151*5e7646d2SAndroid Build Coastguard Worker 
152*5e7646d2SAndroid Build Coastguard Worker   _cupsSetLocale(argv);
153*5e7646d2SAndroid Build Coastguard Worker   loc = localeconv();
154*5e7646d2SAndroid Build Coastguard Worker 
155*5e7646d2SAndroid Build Coastguard Worker  /*
156*5e7646d2SAndroid Build Coastguard Worker   * Display PPD files for each file listed on the command-line...
157*5e7646d2SAndroid Build Coastguard Worker   */
158*5e7646d2SAndroid Build Coastguard Worker 
159*5e7646d2SAndroid Build Coastguard Worker   ppdSetConformance(PPD_CONFORM_STRICT);
160*5e7646d2SAndroid Build Coastguard Worker 
161*5e7646d2SAndroid Build Coastguard Worker   verbose = 0;
162*5e7646d2SAndroid Build Coastguard Worker   ppd     = NULL;
163*5e7646d2SAndroid Build Coastguard Worker   files   = 0;
164*5e7646d2SAndroid Build Coastguard Worker   status  = ERROR_NONE;
165*5e7646d2SAndroid Build Coastguard Worker   root    = "";
166*5e7646d2SAndroid Build Coastguard Worker   warn    = WARN_NONE;
167*5e7646d2SAndroid Build Coastguard Worker   ignore  = WARN_NONE;
168*5e7646d2SAndroid Build Coastguard Worker 
169*5e7646d2SAndroid Build Coastguard Worker   for (i = 1; i < argc; i ++)
170*5e7646d2SAndroid Build Coastguard Worker     if (!strcmp(argv[i], "--help"))
171*5e7646d2SAndroid Build Coastguard Worker       usage();
172*5e7646d2SAndroid Build Coastguard Worker     else if (argv[i][0] == '-' && argv[i][1])
173*5e7646d2SAndroid Build Coastguard Worker     {
174*5e7646d2SAndroid Build Coastguard Worker       for (opt = argv[i] + 1; *opt; opt ++)
175*5e7646d2SAndroid Build Coastguard Worker         switch (*opt)
176*5e7646d2SAndroid Build Coastguard Worker 	{
177*5e7646d2SAndroid Build Coastguard Worker 	  case 'I' :			/* Ignore errors */
178*5e7646d2SAndroid Build Coastguard Worker 	      i ++;
179*5e7646d2SAndroid Build Coastguard Worker 
180*5e7646d2SAndroid Build Coastguard Worker 	      if (i >= argc)
181*5e7646d2SAndroid Build Coastguard Worker 	        usage();
182*5e7646d2SAndroid Build Coastguard Worker 
183*5e7646d2SAndroid Build Coastguard Worker               if (!strcmp(argv[i], "none"))
184*5e7646d2SAndroid Build Coastguard Worker 	        ignore = WARN_NONE;
185*5e7646d2SAndroid Build Coastguard Worker 	      else if (!strcmp(argv[i], "filename"))
186*5e7646d2SAndroid Build Coastguard Worker 	        ignore |= WARN_FILENAME;
187*5e7646d2SAndroid Build Coastguard Worker 	      else if (!strcmp(argv[i], "filters"))
188*5e7646d2SAndroid Build Coastguard Worker 	        ignore |= WARN_FILTERS;
189*5e7646d2SAndroid Build Coastguard Worker 	      else if (!strcmp(argv[i], "profiles"))
190*5e7646d2SAndroid Build Coastguard Worker 	        ignore |= WARN_PROFILES;
191*5e7646d2SAndroid Build Coastguard Worker 	      else if (!strcmp(argv[i], "all"))
192*5e7646d2SAndroid Build Coastguard Worker 	        ignore = WARN_FILTERS | WARN_PROFILES;
193*5e7646d2SAndroid Build Coastguard Worker 	      else
194*5e7646d2SAndroid Build Coastguard Worker 	        usage();
195*5e7646d2SAndroid Build Coastguard Worker 	      break;
196*5e7646d2SAndroid Build Coastguard Worker 
197*5e7646d2SAndroid Build Coastguard Worker 	  case 'R' :			/* Alternate root directory */
198*5e7646d2SAndroid Build Coastguard Worker 	      i ++;
199*5e7646d2SAndroid Build Coastguard Worker 
200*5e7646d2SAndroid Build Coastguard Worker 	      if (i >= argc)
201*5e7646d2SAndroid Build Coastguard Worker 	        usage();
202*5e7646d2SAndroid Build Coastguard Worker 
203*5e7646d2SAndroid Build Coastguard Worker               root = argv[i];
204*5e7646d2SAndroid Build Coastguard Worker 	      break;
205*5e7646d2SAndroid Build Coastguard Worker 
206*5e7646d2SAndroid Build Coastguard Worker 	  case 'W' :			/* Turn errors into warnings */
207*5e7646d2SAndroid Build Coastguard Worker 	      i ++;
208*5e7646d2SAndroid Build Coastguard Worker 
209*5e7646d2SAndroid Build Coastguard Worker 	      if (i >= argc)
210*5e7646d2SAndroid Build Coastguard Worker 	        usage();
211*5e7646d2SAndroid Build Coastguard Worker 
212*5e7646d2SAndroid Build Coastguard Worker               if (!strcmp(argv[i], "none"))
213*5e7646d2SAndroid Build Coastguard Worker 	        warn = WARN_NONE;
214*5e7646d2SAndroid Build Coastguard Worker 	      else if (!strcmp(argv[i], "constraints"))
215*5e7646d2SAndroid Build Coastguard Worker 	        warn |= WARN_CONSTRAINTS;
216*5e7646d2SAndroid Build Coastguard Worker 	      else if (!strcmp(argv[i], "defaults"))
217*5e7646d2SAndroid Build Coastguard Worker 	        warn |= WARN_DEFAULTS;
218*5e7646d2SAndroid Build Coastguard Worker 	      else if (!strcmp(argv[i], "duplex"))
219*5e7646d2SAndroid Build Coastguard Worker 	        warn |= WARN_DUPLEX;
220*5e7646d2SAndroid Build Coastguard Worker 	      else if (!strcmp(argv[i], "filters"))
221*5e7646d2SAndroid Build Coastguard Worker 	        warn |= WARN_FILTERS;
222*5e7646d2SAndroid Build Coastguard Worker 	      else if (!strcmp(argv[i], "profiles"))
223*5e7646d2SAndroid Build Coastguard Worker 	        warn |= WARN_PROFILES;
224*5e7646d2SAndroid Build Coastguard Worker 	      else if (!strcmp(argv[i], "sizes"))
225*5e7646d2SAndroid Build Coastguard Worker 	        warn |= WARN_SIZES;
226*5e7646d2SAndroid Build Coastguard Worker 	      else if (!strcmp(argv[i], "translations"))
227*5e7646d2SAndroid Build Coastguard Worker 	        warn |= WARN_TRANSLATIONS;
228*5e7646d2SAndroid Build Coastguard Worker 	      else if (!strcmp(argv[i], "all"))
229*5e7646d2SAndroid Build Coastguard Worker 	        warn = WARN_ALL;
230*5e7646d2SAndroid Build Coastguard Worker 	      else
231*5e7646d2SAndroid Build Coastguard Worker 	        usage();
232*5e7646d2SAndroid Build Coastguard Worker 	      break;
233*5e7646d2SAndroid Build Coastguard Worker 
234*5e7646d2SAndroid Build Coastguard Worker 	  case 'q' :			/* Quiet mode */
235*5e7646d2SAndroid Build Coastguard Worker 	      if (verbose > 0)
236*5e7646d2SAndroid Build Coastguard Worker 	      {
237*5e7646d2SAndroid Build Coastguard Worker         	_cupsLangPuts(stderr,
238*5e7646d2SAndroid Build Coastguard Worker 		              _("cupstestppd: The -q option is incompatible "
239*5e7646d2SAndroid Build Coastguard Worker 			        "with the -v option."));
240*5e7646d2SAndroid Build Coastguard Worker 		return (1);
241*5e7646d2SAndroid Build Coastguard Worker 	      }
242*5e7646d2SAndroid Build Coastguard Worker 
243*5e7646d2SAndroid Build Coastguard Worker 	      verbose --;
244*5e7646d2SAndroid Build Coastguard Worker 	      break;
245*5e7646d2SAndroid Build Coastguard Worker 
246*5e7646d2SAndroid Build Coastguard Worker 	  case 'r' :			/* Relaxed mode */
247*5e7646d2SAndroid Build Coastguard Worker               ppdSetConformance(PPD_CONFORM_RELAXED);
248*5e7646d2SAndroid Build Coastguard Worker 	      break;
249*5e7646d2SAndroid Build Coastguard Worker 
250*5e7646d2SAndroid Build Coastguard Worker 	  case 'v' :			/* Verbose mode */
251*5e7646d2SAndroid Build Coastguard Worker 	      if (verbose < 0)
252*5e7646d2SAndroid Build Coastguard Worker 	      {
253*5e7646d2SAndroid Build Coastguard Worker         	_cupsLangPuts(stderr,
254*5e7646d2SAndroid Build Coastguard Worker 		              _("cupstestppd: The -v option is incompatible "
255*5e7646d2SAndroid Build Coastguard Worker 			        "with the -q option."));
256*5e7646d2SAndroid Build Coastguard Worker 		return (1);
257*5e7646d2SAndroid Build Coastguard Worker 	      }
258*5e7646d2SAndroid Build Coastguard Worker 
259*5e7646d2SAndroid Build Coastguard Worker 	      verbose ++;
260*5e7646d2SAndroid Build Coastguard Worker 	      break;
261*5e7646d2SAndroid Build Coastguard Worker 
262*5e7646d2SAndroid Build Coastguard Worker 	  default :
263*5e7646d2SAndroid Build Coastguard Worker 	      usage();
264*5e7646d2SAndroid Build Coastguard Worker 	}
265*5e7646d2SAndroid Build Coastguard Worker     }
266*5e7646d2SAndroid Build Coastguard Worker     else
267*5e7646d2SAndroid Build Coastguard Worker     {
268*5e7646d2SAndroid Build Coastguard Worker      /*
269*5e7646d2SAndroid Build Coastguard Worker       * Open the PPD file...
270*5e7646d2SAndroid Build Coastguard Worker       */
271*5e7646d2SAndroid Build Coastguard Worker 
272*5e7646d2SAndroid Build Coastguard Worker       if (files && verbose >= 0)
273*5e7646d2SAndroid Build Coastguard Worker         puts("");
274*5e7646d2SAndroid Build Coastguard Worker 
275*5e7646d2SAndroid Build Coastguard Worker       files ++;
276*5e7646d2SAndroid Build Coastguard Worker 
277*5e7646d2SAndroid Build Coastguard Worker       if (argv[i][0] == '-')
278*5e7646d2SAndroid Build Coastguard Worker       {
279*5e7646d2SAndroid Build Coastguard Worker        /*
280*5e7646d2SAndroid Build Coastguard Worker         * Read from stdin...
281*5e7646d2SAndroid Build Coastguard Worker 	*/
282*5e7646d2SAndroid Build Coastguard Worker 
283*5e7646d2SAndroid Build Coastguard Worker         ppd = _ppdOpen(cupsFileStdin(), _PPD_LOCALIZATION_ALL);
284*5e7646d2SAndroid Build Coastguard Worker 
285*5e7646d2SAndroid Build Coastguard Worker         if (verbose >= 0)
286*5e7646d2SAndroid Build Coastguard Worker           printf("%s:", (ppd && ppd->pcfilename) ? ppd->pcfilename : "(stdin)");
287*5e7646d2SAndroid Build Coastguard Worker       }
288*5e7646d2SAndroid Build Coastguard Worker       else
289*5e7646d2SAndroid Build Coastguard Worker       {
290*5e7646d2SAndroid Build Coastguard Worker        /*
291*5e7646d2SAndroid Build Coastguard Worker         * Read from a file...
292*5e7646d2SAndroid Build Coastguard Worker 	*/
293*5e7646d2SAndroid Build Coastguard Worker 
294*5e7646d2SAndroid Build Coastguard Worker         if (verbose >= 0)
295*5e7646d2SAndroid Build Coastguard Worker           printf("%s:", argv[i]);
296*5e7646d2SAndroid Build Coastguard Worker 
297*5e7646d2SAndroid Build Coastguard Worker         if ((fp = cupsFileOpen(argv[i], "r")) != NULL)
298*5e7646d2SAndroid Build Coastguard Worker         {
299*5e7646d2SAndroid Build Coastguard Worker           ppd = _ppdOpen(fp, _PPD_LOCALIZATION_ALL);
300*5e7646d2SAndroid Build Coastguard Worker           cupsFileClose(fp);
301*5e7646d2SAndroid Build Coastguard Worker         }
302*5e7646d2SAndroid Build Coastguard Worker         else
303*5e7646d2SAndroid Build Coastguard Worker         {
304*5e7646d2SAndroid Build Coastguard Worker 	  status = ERROR_FILE_OPEN;
305*5e7646d2SAndroid Build Coastguard Worker 
306*5e7646d2SAndroid Build Coastguard Worker 	  if (verbose >= 0)
307*5e7646d2SAndroid Build Coastguard Worker           {
308*5e7646d2SAndroid Build Coastguard Worker             _cupsLangPuts(stdout, _(" FAIL"));
309*5e7646d2SAndroid Build Coastguard Worker             _cupsLangPrintf(stdout,
310*5e7646d2SAndroid Build Coastguard Worker 	                    _("      **FAIL**  Unable to open PPD file - %s on "
311*5e7646d2SAndroid Build Coastguard Worker 	                      "line %d."), strerror(errno), 0);
312*5e7646d2SAndroid Build Coastguard Worker 	    continue;
313*5e7646d2SAndroid Build Coastguard Worker           }
314*5e7646d2SAndroid Build Coastguard Worker         }
315*5e7646d2SAndroid Build Coastguard Worker       }
316*5e7646d2SAndroid Build Coastguard Worker 
317*5e7646d2SAndroid Build Coastguard Worker       if (ppd == NULL)
318*5e7646d2SAndroid Build Coastguard Worker       {
319*5e7646d2SAndroid Build Coastguard Worker         error = ppdLastError(&line);
320*5e7646d2SAndroid Build Coastguard Worker 
321*5e7646d2SAndroid Build Coastguard Worker 	if (error <= PPD_ALLOC_ERROR)
322*5e7646d2SAndroid Build Coastguard Worker 	{
323*5e7646d2SAndroid Build Coastguard Worker 	  status = ERROR_FILE_OPEN;
324*5e7646d2SAndroid Build Coastguard Worker 
325*5e7646d2SAndroid Build Coastguard Worker 	  if (verbose >= 0)
326*5e7646d2SAndroid Build Coastguard Worker           {
327*5e7646d2SAndroid Build Coastguard Worker             _cupsLangPuts(stdout, _(" FAIL"));
328*5e7646d2SAndroid Build Coastguard Worker             _cupsLangPrintf(stdout,
329*5e7646d2SAndroid Build Coastguard Worker 	                    _("      **FAIL**  Unable to open PPD file - %s on "
330*5e7646d2SAndroid Build Coastguard Worker 	                      "line %d."), strerror(errno), 0);
331*5e7646d2SAndroid Build Coastguard Worker           }
332*5e7646d2SAndroid Build Coastguard Worker 	}
333*5e7646d2SAndroid Build Coastguard Worker 	else
334*5e7646d2SAndroid Build Coastguard Worker 	{
335*5e7646d2SAndroid Build Coastguard Worker 	  status = ERROR_PPD_FORMAT;
336*5e7646d2SAndroid Build Coastguard Worker 
337*5e7646d2SAndroid Build Coastguard Worker           if (verbose >= 0)
338*5e7646d2SAndroid Build Coastguard Worker           {
339*5e7646d2SAndroid Build Coastguard Worker             _cupsLangPuts(stdout, _(" FAIL"));
340*5e7646d2SAndroid Build Coastguard Worker             _cupsLangPrintf(stdout,
341*5e7646d2SAndroid Build Coastguard Worker 	                    _("      **FAIL**  Unable to open PPD file - "
342*5e7646d2SAndroid Build Coastguard Worker 			      "%s on line %d."),
343*5e7646d2SAndroid Build Coastguard Worker 			    ppdErrorString(error), line);
344*5e7646d2SAndroid Build Coastguard Worker 
345*5e7646d2SAndroid Build Coastguard Worker             switch (error)
346*5e7646d2SAndroid Build Coastguard Worker 	    {
347*5e7646d2SAndroid Build Coastguard Worker 	      case PPD_MISSING_PPDADOBE4 :
348*5e7646d2SAndroid Build Coastguard Worker 	          _cupsLangPuts(stdout,
349*5e7646d2SAndroid Build Coastguard Worker 		                _("                REF: Page 42, section "
350*5e7646d2SAndroid Build Coastguard Worker 				  "5.2."));
351*5e7646d2SAndroid Build Coastguard Worker 	          break;
352*5e7646d2SAndroid Build Coastguard Worker 	      case PPD_MISSING_VALUE :
353*5e7646d2SAndroid Build Coastguard Worker 	          _cupsLangPuts(stdout,
354*5e7646d2SAndroid Build Coastguard Worker 		                _("                REF: Page 20, section "
355*5e7646d2SAndroid Build Coastguard Worker 				  "3.4."));
356*5e7646d2SAndroid Build Coastguard Worker 	          break;
357*5e7646d2SAndroid Build Coastguard Worker 	      case PPD_BAD_OPEN_GROUP :
358*5e7646d2SAndroid Build Coastguard Worker 	      case PPD_NESTED_OPEN_GROUP :
359*5e7646d2SAndroid Build Coastguard Worker 	          _cupsLangPuts(stdout,
360*5e7646d2SAndroid Build Coastguard Worker 		                _("                REF: Pages 45-46, section "
361*5e7646d2SAndroid Build Coastguard Worker 				  "5.2."));
362*5e7646d2SAndroid Build Coastguard Worker 	          break;
363*5e7646d2SAndroid Build Coastguard Worker 	      case PPD_BAD_OPEN_UI :
364*5e7646d2SAndroid Build Coastguard Worker 	      case PPD_NESTED_OPEN_UI :
365*5e7646d2SAndroid Build Coastguard Worker 	          _cupsLangPuts(stdout,
366*5e7646d2SAndroid Build Coastguard Worker 		                _("                REF: Pages 42-45, section "
367*5e7646d2SAndroid Build Coastguard Worker 				  "5.2."));
368*5e7646d2SAndroid Build Coastguard Worker 	          break;
369*5e7646d2SAndroid Build Coastguard Worker 	      case PPD_BAD_ORDER_DEPENDENCY :
370*5e7646d2SAndroid Build Coastguard Worker 	          _cupsLangPuts(stdout,
371*5e7646d2SAndroid Build Coastguard Worker 		                _("                REF: Pages 48-49, section "
372*5e7646d2SAndroid Build Coastguard Worker 				  "5.2."));
373*5e7646d2SAndroid Build Coastguard Worker 	          break;
374*5e7646d2SAndroid Build Coastguard Worker 	      case PPD_BAD_UI_CONSTRAINTS :
375*5e7646d2SAndroid Build Coastguard Worker 	          _cupsLangPuts(stdout,
376*5e7646d2SAndroid Build Coastguard Worker 		                _("                REF: Pages 52-54, section "
377*5e7646d2SAndroid Build Coastguard Worker 				  "5.2."));
378*5e7646d2SAndroid Build Coastguard Worker 	          break;
379*5e7646d2SAndroid Build Coastguard Worker 	      case PPD_MISSING_ASTERISK :
380*5e7646d2SAndroid Build Coastguard Worker 	          _cupsLangPuts(stdout,
381*5e7646d2SAndroid Build Coastguard Worker 		                _("                REF: Page 15, section "
382*5e7646d2SAndroid Build Coastguard Worker 				  "3.2."));
383*5e7646d2SAndroid Build Coastguard Worker 	          break;
384*5e7646d2SAndroid Build Coastguard Worker 	      case PPD_LINE_TOO_LONG :
385*5e7646d2SAndroid Build Coastguard Worker 	          _cupsLangPuts(stdout,
386*5e7646d2SAndroid Build Coastguard Worker 		                _("                REF: Page 15, section "
387*5e7646d2SAndroid Build Coastguard Worker 				  "3.1."));
388*5e7646d2SAndroid Build Coastguard Worker 	          break;
389*5e7646d2SAndroid Build Coastguard Worker 	      case PPD_ILLEGAL_CHARACTER :
390*5e7646d2SAndroid Build Coastguard Worker 	          _cupsLangPuts(stdout,
391*5e7646d2SAndroid Build Coastguard Worker 		                _("                REF: Page 15, section "
392*5e7646d2SAndroid Build Coastguard Worker 				  "3.1."));
393*5e7646d2SAndroid Build Coastguard Worker 	          break;
394*5e7646d2SAndroid Build Coastguard Worker 	      case PPD_ILLEGAL_MAIN_KEYWORD :
395*5e7646d2SAndroid Build Coastguard Worker 	          _cupsLangPuts(stdout,
396*5e7646d2SAndroid Build Coastguard Worker 		                _("                REF: Pages 16-17, section "
397*5e7646d2SAndroid Build Coastguard Worker 				  "3.2."));
398*5e7646d2SAndroid Build Coastguard Worker 	          break;
399*5e7646d2SAndroid Build Coastguard Worker 	      case PPD_ILLEGAL_OPTION_KEYWORD :
400*5e7646d2SAndroid Build Coastguard Worker 	          _cupsLangPuts(stdout,
401*5e7646d2SAndroid Build Coastguard Worker 		                _("                REF: Page 19, section "
402*5e7646d2SAndroid Build Coastguard Worker 				  "3.3."));
403*5e7646d2SAndroid Build Coastguard Worker 	          break;
404*5e7646d2SAndroid Build Coastguard Worker 	      case PPD_ILLEGAL_TRANSLATION :
405*5e7646d2SAndroid Build Coastguard Worker 	          _cupsLangPuts(stdout,
406*5e7646d2SAndroid Build Coastguard Worker 		                _("                REF: Page 27, section "
407*5e7646d2SAndroid Build Coastguard Worker 				  "3.5."));
408*5e7646d2SAndroid Build Coastguard Worker 	          break;
409*5e7646d2SAndroid Build Coastguard Worker               default :
410*5e7646d2SAndroid Build Coastguard Worker 	          break;
411*5e7646d2SAndroid Build Coastguard Worker 	    }
412*5e7646d2SAndroid Build Coastguard Worker 
413*5e7646d2SAndroid Build Coastguard Worker 	    check_basics(argv[i]);
414*5e7646d2SAndroid Build Coastguard Worker 	  }
415*5e7646d2SAndroid Build Coastguard Worker         }
416*5e7646d2SAndroid Build Coastguard Worker 
417*5e7646d2SAndroid Build Coastguard Worker 	continue;
418*5e7646d2SAndroid Build Coastguard Worker       }
419*5e7646d2SAndroid Build Coastguard Worker 
420*5e7646d2SAndroid Build Coastguard Worker      /*
421*5e7646d2SAndroid Build Coastguard Worker       * Show the header and then perform basic conformance tests (limited
422*5e7646d2SAndroid Build Coastguard Worker       * only by what the CUPS PPD functions actually load...)
423*5e7646d2SAndroid Build Coastguard Worker       */
424*5e7646d2SAndroid Build Coastguard Worker 
425*5e7646d2SAndroid Build Coastguard Worker       errors     = 0;
426*5e7646d2SAndroid Build Coastguard Worker       ppdversion = 43;
427*5e7646d2SAndroid Build Coastguard Worker 
428*5e7646d2SAndroid Build Coastguard Worker       if (verbose > 0)
429*5e7646d2SAndroid Build Coastguard Worker         _cupsLangPuts(stdout,
430*5e7646d2SAndroid Build Coastguard Worker 	              _("\n    DETAILED CONFORMANCE TEST RESULTS"));
431*5e7646d2SAndroid Build Coastguard Worker 
432*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ppdFindAttr(ppd, "FormatVersion", NULL)) != NULL &&
433*5e7646d2SAndroid Build Coastguard Worker           attr->value)
434*5e7646d2SAndroid Build Coastguard Worker         ppdversion = (int)(10 * _cupsStrScand(attr->value, NULL, loc) + 0.5);
435*5e7646d2SAndroid Build Coastguard Worker 
436*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ppdFindAttr(ppd, "cupsFilter2", NULL)) != NULL)
437*5e7646d2SAndroid Build Coastguard Worker       {
438*5e7646d2SAndroid Build Coastguard Worker         do
439*5e7646d2SAndroid Build Coastguard Worker         {
440*5e7646d2SAndroid Build Coastguard Worker 	  if (strstr(attr->value, "application/vnd.cups-raster"))
441*5e7646d2SAndroid Build Coastguard Worker 	  {
442*5e7646d2SAndroid Build Coastguard Worker 	    if (!test_raster(ppd, verbose))
443*5e7646d2SAndroid Build Coastguard Worker 	      errors ++;
444*5e7646d2SAndroid Build Coastguard Worker 	    break;
445*5e7646d2SAndroid Build Coastguard Worker 	  }
446*5e7646d2SAndroid Build Coastguard Worker 	}
447*5e7646d2SAndroid Build Coastguard Worker 	while ((attr = ppdFindNextAttr(ppd, "cupsFilter2", NULL)) != NULL);
448*5e7646d2SAndroid Build Coastguard Worker       }
449*5e7646d2SAndroid Build Coastguard Worker       else
450*5e7646d2SAndroid Build Coastguard Worker       {
451*5e7646d2SAndroid Build Coastguard Worker 	for (j = 0; j < ppd->num_filters; j ++)
452*5e7646d2SAndroid Build Coastguard Worker 	  if (strstr(ppd->filters[j], "application/vnd.cups-raster"))
453*5e7646d2SAndroid Build Coastguard Worker 	  {
454*5e7646d2SAndroid Build Coastguard Worker 	    if (!test_raster(ppd, verbose))
455*5e7646d2SAndroid Build Coastguard Worker 	      errors ++;
456*5e7646d2SAndroid Build Coastguard Worker 	    break;
457*5e7646d2SAndroid Build Coastguard Worker 	  }
458*5e7646d2SAndroid Build Coastguard Worker       }
459*5e7646d2SAndroid Build Coastguard Worker 
460*5e7646d2SAndroid Build Coastguard Worker      /*
461*5e7646d2SAndroid Build Coastguard Worker       * Look for default keywords with no matching option...
462*5e7646d2SAndroid Build Coastguard Worker       */
463*5e7646d2SAndroid Build Coastguard Worker 
464*5e7646d2SAndroid Build Coastguard Worker       if (!(warn & WARN_DEFAULTS))
465*5e7646d2SAndroid Build Coastguard Worker         errors = check_defaults(ppd, errors, verbose, 0);
466*5e7646d2SAndroid Build Coastguard Worker 
467*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ppdFindAttr(ppd, "DefaultImageableArea", NULL)) == NULL)
468*5e7646d2SAndroid Build Coastguard Worker       {
469*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
470*5e7646d2SAndroid Build Coastguard Worker 	{
471*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
472*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
473*5e7646d2SAndroid Build Coastguard Worker 
474*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
475*5e7646d2SAndroid Build Coastguard Worker 			_("      **FAIL**  REQUIRED DefaultImageableArea\n"
476*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Page 102, section 5.15."));
477*5e7646d2SAndroid Build Coastguard Worker 	}
478*5e7646d2SAndroid Build Coastguard Worker 
479*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
480*5e7646d2SAndroid Build Coastguard Worker       }
481*5e7646d2SAndroid Build Coastguard Worker       else if (ppdPageSize(ppd, attr->value) == NULL &&
482*5e7646d2SAndroid Build Coastguard Worker 	       strcmp(attr->value, "Unknown"))
483*5e7646d2SAndroid Build Coastguard Worker       {
484*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
485*5e7646d2SAndroid Build Coastguard Worker 	{
486*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
487*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
488*5e7646d2SAndroid Build Coastguard Worker 
489*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
490*5e7646d2SAndroid Build Coastguard Worker 			  _("      **FAIL**  Bad DefaultImageableArea %s\n"
491*5e7646d2SAndroid Build Coastguard Worker 			    "                REF: Page 102, section 5.15."),
492*5e7646d2SAndroid Build Coastguard Worker 			  attr->value);
493*5e7646d2SAndroid Build Coastguard Worker 	}
494*5e7646d2SAndroid Build Coastguard Worker 
495*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
496*5e7646d2SAndroid Build Coastguard Worker       }
497*5e7646d2SAndroid Build Coastguard Worker       else
498*5e7646d2SAndroid Build Coastguard Worker       {
499*5e7646d2SAndroid Build Coastguard Worker 	if (verbose > 0)
500*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _("        PASS    DefaultImageableArea"));
501*5e7646d2SAndroid Build Coastguard Worker       }
502*5e7646d2SAndroid Build Coastguard Worker 
503*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ppdFindAttr(ppd, "DefaultPaperDimension", NULL)) == NULL)
504*5e7646d2SAndroid Build Coastguard Worker       {
505*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
506*5e7646d2SAndroid Build Coastguard Worker 	{
507*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
508*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
509*5e7646d2SAndroid Build Coastguard Worker 
510*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
511*5e7646d2SAndroid Build Coastguard Worker 			_("      **FAIL**  REQUIRED DefaultPaperDimension\n"
512*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Page 103, section 5.15."));
513*5e7646d2SAndroid Build Coastguard Worker 	}
514*5e7646d2SAndroid Build Coastguard Worker 
515*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
516*5e7646d2SAndroid Build Coastguard Worker       }
517*5e7646d2SAndroid Build Coastguard Worker       else if (ppdPageSize(ppd, attr->value) == NULL &&
518*5e7646d2SAndroid Build Coastguard Worker 	       strcmp(attr->value, "Unknown"))
519*5e7646d2SAndroid Build Coastguard Worker       {
520*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
521*5e7646d2SAndroid Build Coastguard Worker 	{
522*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
523*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
524*5e7646d2SAndroid Build Coastguard Worker 
525*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
526*5e7646d2SAndroid Build Coastguard Worker 			  _("      **FAIL**  Bad DefaultPaperDimension %s\n"
527*5e7646d2SAndroid Build Coastguard Worker 			    "                REF: Page 103, section 5.15."),
528*5e7646d2SAndroid Build Coastguard Worker 			  attr->value);
529*5e7646d2SAndroid Build Coastguard Worker 	}
530*5e7646d2SAndroid Build Coastguard Worker 
531*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
532*5e7646d2SAndroid Build Coastguard Worker       }
533*5e7646d2SAndroid Build Coastguard Worker       else if (verbose > 0)
534*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _("        PASS    DefaultPaperDimension"));
535*5e7646d2SAndroid Build Coastguard Worker 
536*5e7646d2SAndroid Build Coastguard Worker       for (j = 0, group = ppd->groups; j < ppd->num_groups; j ++, group ++)
537*5e7646d2SAndroid Build Coastguard Worker 	for (k = 0, option = group->options;
538*5e7646d2SAndroid Build Coastguard Worker 	     k < group->num_options;
539*5e7646d2SAndroid Build Coastguard Worker 	     k ++, option ++)
540*5e7646d2SAndroid Build Coastguard Worker 	{
541*5e7646d2SAndroid Build Coastguard Worker 	 /*
542*5e7646d2SAndroid Build Coastguard Worker 	  * Verify that we have a default choice...
543*5e7646d2SAndroid Build Coastguard Worker 	  */
544*5e7646d2SAndroid Build Coastguard Worker 
545*5e7646d2SAndroid Build Coastguard Worker 	  if (option->defchoice[0])
546*5e7646d2SAndroid Build Coastguard Worker 	  {
547*5e7646d2SAndroid Build Coastguard Worker 	    if (ppdFindChoice(option, option->defchoice) == NULL &&
548*5e7646d2SAndroid Build Coastguard Worker 		strcmp(option->defchoice, "Unknown"))
549*5e7646d2SAndroid Build Coastguard Worker 	    {
550*5e7646d2SAndroid Build Coastguard Worker 	      if (verbose >= 0)
551*5e7646d2SAndroid Build Coastguard Worker 	      {
552*5e7646d2SAndroid Build Coastguard Worker 		if (!errors && !verbose)
553*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPuts(stdout, _(" FAIL"));
554*5e7646d2SAndroid Build Coastguard Worker 
555*5e7646d2SAndroid Build Coastguard Worker 		_cupsLangPrintf(stdout,
556*5e7646d2SAndroid Build Coastguard Worker 				_("      **FAIL**  Bad Default%s %s\n"
557*5e7646d2SAndroid Build Coastguard Worker 				  "                REF: Page 40, section 4.5."),
558*5e7646d2SAndroid Build Coastguard Worker 				option->keyword, option->defchoice);
559*5e7646d2SAndroid Build Coastguard Worker 	      }
560*5e7646d2SAndroid Build Coastguard Worker 
561*5e7646d2SAndroid Build Coastguard Worker 	      errors ++;
562*5e7646d2SAndroid Build Coastguard Worker 	    }
563*5e7646d2SAndroid Build Coastguard Worker 	    else if (verbose > 0)
564*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPrintf(stdout,
565*5e7646d2SAndroid Build Coastguard Worker 			      _("        PASS    Default%s"),
566*5e7646d2SAndroid Build Coastguard Worker 			      option->keyword);
567*5e7646d2SAndroid Build Coastguard Worker 	  }
568*5e7646d2SAndroid Build Coastguard Worker 	  else
569*5e7646d2SAndroid Build Coastguard Worker 	  {
570*5e7646d2SAndroid Build Coastguard Worker 	    if (verbose >= 0)
571*5e7646d2SAndroid Build Coastguard Worker 	    {
572*5e7646d2SAndroid Build Coastguard Worker 	      if (!errors && !verbose)
573*5e7646d2SAndroid Build Coastguard Worker 		_cupsLangPuts(stdout, _(" FAIL"));
574*5e7646d2SAndroid Build Coastguard Worker 
575*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPrintf(stdout,
576*5e7646d2SAndroid Build Coastguard Worker 			      _("      **FAIL**  REQUIRED Default%s\n"
577*5e7646d2SAndroid Build Coastguard Worker 				"                REF: Page 40, section 4.5."),
578*5e7646d2SAndroid Build Coastguard Worker 			      option->keyword);
579*5e7646d2SAndroid Build Coastguard Worker 	    }
580*5e7646d2SAndroid Build Coastguard Worker 
581*5e7646d2SAndroid Build Coastguard Worker 	    errors ++;
582*5e7646d2SAndroid Build Coastguard Worker 	  }
583*5e7646d2SAndroid Build Coastguard Worker 	}
584*5e7646d2SAndroid Build Coastguard Worker 
585*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ppdFindAttr(ppd, "FileVersion", NULL)) != NULL)
586*5e7646d2SAndroid Build Coastguard Worker       {
587*5e7646d2SAndroid Build Coastguard Worker         for (ptr = attr->value; *ptr; ptr ++)
588*5e7646d2SAndroid Build Coastguard Worker 	  if (!isdigit(*ptr & 255) && *ptr != '.')
589*5e7646d2SAndroid Build Coastguard Worker 	    break;
590*5e7646d2SAndroid Build Coastguard Worker 
591*5e7646d2SAndroid Build Coastguard Worker 	if (*ptr)
592*5e7646d2SAndroid Build Coastguard Worker 	{
593*5e7646d2SAndroid Build Coastguard Worker 	  if (verbose >= 0)
594*5e7646d2SAndroid Build Coastguard Worker 	  {
595*5e7646d2SAndroid Build Coastguard Worker 	    if (!errors && !verbose)
596*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPuts(stdout, _(" FAIL"));
597*5e7646d2SAndroid Build Coastguard Worker 
598*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPrintf(stdout,
599*5e7646d2SAndroid Build Coastguard Worker 			    _("      **FAIL**  Bad FileVersion \"%s\"\n"
600*5e7646d2SAndroid Build Coastguard Worker 			      "                REF: Page 56, section 5.3."),
601*5e7646d2SAndroid Build Coastguard Worker 			    attr->value);
602*5e7646d2SAndroid Build Coastguard Worker 	  }
603*5e7646d2SAndroid Build Coastguard Worker 
604*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
605*5e7646d2SAndroid Build Coastguard Worker 	}
606*5e7646d2SAndroid Build Coastguard Worker 	else if (verbose > 0)
607*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _("        PASS    FileVersion"));
608*5e7646d2SAndroid Build Coastguard Worker       }
609*5e7646d2SAndroid Build Coastguard Worker       else
610*5e7646d2SAndroid Build Coastguard Worker       {
611*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
612*5e7646d2SAndroid Build Coastguard Worker 	{
613*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
614*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
615*5e7646d2SAndroid Build Coastguard Worker 
616*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
617*5e7646d2SAndroid Build Coastguard Worker 	                _("      **FAIL**  REQUIRED FileVersion\n"
618*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Page 56, section 5.3."));
619*5e7646d2SAndroid Build Coastguard Worker         }
620*5e7646d2SAndroid Build Coastguard Worker 
621*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
622*5e7646d2SAndroid Build Coastguard Worker       }
623*5e7646d2SAndroid Build Coastguard Worker 
624*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ppdFindAttr(ppd, "FormatVersion", NULL)) != NULL)
625*5e7646d2SAndroid Build Coastguard Worker       {
626*5e7646d2SAndroid Build Coastguard Worker         ptr = attr->value;
627*5e7646d2SAndroid Build Coastguard Worker 	if (*ptr == '4' && ptr[1] == '.')
628*5e7646d2SAndroid Build Coastguard Worker 	{
629*5e7646d2SAndroid Build Coastguard Worker 
630*5e7646d2SAndroid Build Coastguard Worker 	  for (ptr += 2; *ptr; ptr ++)
631*5e7646d2SAndroid Build Coastguard Worker 	    if (!isdigit(*ptr & 255))
632*5e7646d2SAndroid Build Coastguard Worker 	      break;
633*5e7646d2SAndroid Build Coastguard Worker         }
634*5e7646d2SAndroid Build Coastguard Worker 
635*5e7646d2SAndroid Build Coastguard Worker 	if (*ptr)
636*5e7646d2SAndroid Build Coastguard Worker 	{
637*5e7646d2SAndroid Build Coastguard Worker 	  if (verbose >= 0)
638*5e7646d2SAndroid Build Coastguard Worker 	  {
639*5e7646d2SAndroid Build Coastguard Worker 	    if (!errors && !verbose)
640*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPuts(stdout, _(" FAIL"));
641*5e7646d2SAndroid Build Coastguard Worker 
642*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPrintf(stdout,
643*5e7646d2SAndroid Build Coastguard Worker 			    _("      **FAIL**  Bad FormatVersion \"%s\"\n"
644*5e7646d2SAndroid Build Coastguard Worker 			      "                REF: Page 56, section 5.3."),
645*5e7646d2SAndroid Build Coastguard Worker 			    attr->value);
646*5e7646d2SAndroid Build Coastguard Worker 	  }
647*5e7646d2SAndroid Build Coastguard Worker 
648*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
649*5e7646d2SAndroid Build Coastguard Worker 	}
650*5e7646d2SAndroid Build Coastguard Worker 	else if (verbose > 0)
651*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _("        PASS    FormatVersion"));
652*5e7646d2SAndroid Build Coastguard Worker       }
653*5e7646d2SAndroid Build Coastguard Worker       else
654*5e7646d2SAndroid Build Coastguard Worker       {
655*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
656*5e7646d2SAndroid Build Coastguard Worker 	{
657*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
658*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
659*5e7646d2SAndroid Build Coastguard Worker 
660*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
661*5e7646d2SAndroid Build Coastguard Worker 	                _("      **FAIL**  REQUIRED FormatVersion\n"
662*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Page 56, section 5.3."));
663*5e7646d2SAndroid Build Coastguard Worker         }
664*5e7646d2SAndroid Build Coastguard Worker 
665*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
666*5e7646d2SAndroid Build Coastguard Worker       }
667*5e7646d2SAndroid Build Coastguard Worker 
668*5e7646d2SAndroid Build Coastguard Worker       if (ppd->lang_encoding != NULL)
669*5e7646d2SAndroid Build Coastguard Worker       {
670*5e7646d2SAndroid Build Coastguard Worker 	if (verbose > 0)
671*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _("        PASS    LanguageEncoding"));
672*5e7646d2SAndroid Build Coastguard Worker       }
673*5e7646d2SAndroid Build Coastguard Worker       else if (ppdversion > 40)
674*5e7646d2SAndroid Build Coastguard Worker       {
675*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
676*5e7646d2SAndroid Build Coastguard Worker 	{
677*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
678*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
679*5e7646d2SAndroid Build Coastguard Worker 
680*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
681*5e7646d2SAndroid Build Coastguard Worker 	                _("      **FAIL**  REQUIRED LanguageEncoding\n"
682*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Pages 56-57, section 5.3."));
683*5e7646d2SAndroid Build Coastguard Worker         }
684*5e7646d2SAndroid Build Coastguard Worker 
685*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
686*5e7646d2SAndroid Build Coastguard Worker       }
687*5e7646d2SAndroid Build Coastguard Worker 
688*5e7646d2SAndroid Build Coastguard Worker       if (ppd->lang_version != NULL)
689*5e7646d2SAndroid Build Coastguard Worker       {
690*5e7646d2SAndroid Build Coastguard Worker 	if (verbose > 0)
691*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _("        PASS    LanguageVersion"));
692*5e7646d2SAndroid Build Coastguard Worker       }
693*5e7646d2SAndroid Build Coastguard Worker       else
694*5e7646d2SAndroid Build Coastguard Worker       {
695*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
696*5e7646d2SAndroid Build Coastguard Worker 	{
697*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
698*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
699*5e7646d2SAndroid Build Coastguard Worker 
700*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
701*5e7646d2SAndroid Build Coastguard Worker 	                _("      **FAIL**  REQUIRED LanguageVersion\n"
702*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Pages 57-58, section 5.3."));
703*5e7646d2SAndroid Build Coastguard Worker         }
704*5e7646d2SAndroid Build Coastguard Worker 
705*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
706*5e7646d2SAndroid Build Coastguard Worker       }
707*5e7646d2SAndroid Build Coastguard Worker 
708*5e7646d2SAndroid Build Coastguard Worker       if (ppd->manufacturer != NULL)
709*5e7646d2SAndroid Build Coastguard Worker       {
710*5e7646d2SAndroid Build Coastguard Worker         if (!_cups_strncasecmp(ppd->manufacturer, "Hewlett-Packard", 15) ||
711*5e7646d2SAndroid Build Coastguard Worker 	    !_cups_strncasecmp(ppd->manufacturer, "Hewlett Packard", 15))
712*5e7646d2SAndroid Build Coastguard Worker 	{
713*5e7646d2SAndroid Build Coastguard Worker 	  if (verbose >= 0)
714*5e7646d2SAndroid Build Coastguard Worker 	  {
715*5e7646d2SAndroid Build Coastguard Worker 	    if (!errors && !verbose)
716*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPuts(stdout, _(" FAIL"));
717*5e7646d2SAndroid Build Coastguard Worker 
718*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPrintf(stdout,
719*5e7646d2SAndroid Build Coastguard Worker 			    _("      **FAIL**  Bad Manufacturer (should be "
720*5e7646d2SAndroid Build Coastguard Worker 			      "\"%s\")\n"
721*5e7646d2SAndroid Build Coastguard Worker 			      "                REF: Page 211, table D.1."),
722*5e7646d2SAndroid Build Coastguard Worker 			    "HP");
723*5e7646d2SAndroid Build Coastguard Worker           }
724*5e7646d2SAndroid Build Coastguard Worker 
725*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
726*5e7646d2SAndroid Build Coastguard Worker 	}
727*5e7646d2SAndroid Build Coastguard Worker         else if (!_cups_strncasecmp(ppd->manufacturer, "OkiData", 7) ||
728*5e7646d2SAndroid Build Coastguard Worker 	         !_cups_strncasecmp(ppd->manufacturer, "Oki Data", 8))
729*5e7646d2SAndroid Build Coastguard Worker 	{
730*5e7646d2SAndroid Build Coastguard Worker 	  if (verbose >= 0)
731*5e7646d2SAndroid Build Coastguard Worker 	  {
732*5e7646d2SAndroid Build Coastguard Worker 	    if (!errors && !verbose)
733*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPuts(stdout, _(" FAIL"));
734*5e7646d2SAndroid Build Coastguard Worker 
735*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPrintf(stdout,
736*5e7646d2SAndroid Build Coastguard Worker 	                    _("      **FAIL**  Bad Manufacturer (should be "
737*5e7646d2SAndroid Build Coastguard Worker 			      "\"%s\")\n"
738*5e7646d2SAndroid Build Coastguard Worker 			      "                REF: Page 211, table D.1."),
739*5e7646d2SAndroid Build Coastguard Worker 			    "Oki");
740*5e7646d2SAndroid Build Coastguard Worker           }
741*5e7646d2SAndroid Build Coastguard Worker 
742*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
743*5e7646d2SAndroid Build Coastguard Worker 	}
744*5e7646d2SAndroid Build Coastguard Worker 	else if (verbose > 0)
745*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _("        PASS    Manufacturer"));
746*5e7646d2SAndroid Build Coastguard Worker       }
747*5e7646d2SAndroid Build Coastguard Worker       else if (ppdversion >= 43)
748*5e7646d2SAndroid Build Coastguard Worker       {
749*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
750*5e7646d2SAndroid Build Coastguard Worker 	{
751*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
752*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
753*5e7646d2SAndroid Build Coastguard Worker 
754*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
755*5e7646d2SAndroid Build Coastguard Worker 	                _("      **FAIL**  REQUIRED Manufacturer\n"
756*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Pages 58-59, section 5.3."));
757*5e7646d2SAndroid Build Coastguard Worker         }
758*5e7646d2SAndroid Build Coastguard Worker 
759*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
760*5e7646d2SAndroid Build Coastguard Worker       }
761*5e7646d2SAndroid Build Coastguard Worker 
762*5e7646d2SAndroid Build Coastguard Worker       if (ppd->modelname != NULL)
763*5e7646d2SAndroid Build Coastguard Worker       {
764*5e7646d2SAndroid Build Coastguard Worker         for (ptr = ppd->modelname; *ptr; ptr ++)
765*5e7646d2SAndroid Build Coastguard Worker 	  if (!isalnum(*ptr & 255) && !strchr(" ./-+", *ptr))
766*5e7646d2SAndroid Build Coastguard Worker 	    break;
767*5e7646d2SAndroid Build Coastguard Worker 
768*5e7646d2SAndroid Build Coastguard Worker 	if (*ptr)
769*5e7646d2SAndroid Build Coastguard Worker 	{
770*5e7646d2SAndroid Build Coastguard Worker 	  if (verbose >= 0)
771*5e7646d2SAndroid Build Coastguard Worker 	  {
772*5e7646d2SAndroid Build Coastguard Worker 	    if (!errors && !verbose)
773*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPuts(stdout, _(" FAIL"));
774*5e7646d2SAndroid Build Coastguard Worker 
775*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPrintf(stdout,
776*5e7646d2SAndroid Build Coastguard Worker 	                    _("      **FAIL**  Bad ModelName - \"%c\" not "
777*5e7646d2SAndroid Build Coastguard Worker 			      "allowed in string.\n"
778*5e7646d2SAndroid Build Coastguard Worker 			      "                REF: Pages 59-60, section 5.3."),
779*5e7646d2SAndroid Build Coastguard Worker 	                    *ptr);
780*5e7646d2SAndroid Build Coastguard Worker           }
781*5e7646d2SAndroid Build Coastguard Worker 
782*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
783*5e7646d2SAndroid Build Coastguard Worker 	}
784*5e7646d2SAndroid Build Coastguard Worker 	else if (verbose > 0)
785*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _("        PASS    ModelName"));
786*5e7646d2SAndroid Build Coastguard Worker       }
787*5e7646d2SAndroid Build Coastguard Worker       else
788*5e7646d2SAndroid Build Coastguard Worker       {
789*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
790*5e7646d2SAndroid Build Coastguard Worker 	{
791*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
792*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
793*5e7646d2SAndroid Build Coastguard Worker 
794*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
795*5e7646d2SAndroid Build Coastguard Worker 	                _("      **FAIL**  REQUIRED ModelName\n"
796*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Pages 59-60, section 5.3."));
797*5e7646d2SAndroid Build Coastguard Worker         }
798*5e7646d2SAndroid Build Coastguard Worker 
799*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
800*5e7646d2SAndroid Build Coastguard Worker       }
801*5e7646d2SAndroid Build Coastguard Worker 
802*5e7646d2SAndroid Build Coastguard Worker       if (ppd->nickname != NULL)
803*5e7646d2SAndroid Build Coastguard Worker       {
804*5e7646d2SAndroid Build Coastguard Worker 	if (verbose > 0)
805*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _("        PASS    NickName"));
806*5e7646d2SAndroid Build Coastguard Worker       }
807*5e7646d2SAndroid Build Coastguard Worker       else
808*5e7646d2SAndroid Build Coastguard Worker       {
809*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
810*5e7646d2SAndroid Build Coastguard Worker 	{
811*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
812*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
813*5e7646d2SAndroid Build Coastguard Worker 
814*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
815*5e7646d2SAndroid Build Coastguard Worker 	                _("      **FAIL**  REQUIRED NickName\n"
816*5e7646d2SAndroid Build Coastguard Worker 	                  "                REF: Page 60, section 5.3."));
817*5e7646d2SAndroid Build Coastguard Worker         }
818*5e7646d2SAndroid Build Coastguard Worker 
819*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
820*5e7646d2SAndroid Build Coastguard Worker       }
821*5e7646d2SAndroid Build Coastguard Worker 
822*5e7646d2SAndroid Build Coastguard Worker       if (ppdFindOption(ppd, "PageSize") != NULL)
823*5e7646d2SAndroid Build Coastguard Worker       {
824*5e7646d2SAndroid Build Coastguard Worker 	if (verbose > 0)
825*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _("        PASS    PageSize"));
826*5e7646d2SAndroid Build Coastguard Worker       }
827*5e7646d2SAndroid Build Coastguard Worker       else
828*5e7646d2SAndroid Build Coastguard Worker       {
829*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
830*5e7646d2SAndroid Build Coastguard Worker 	{
831*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
832*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
833*5e7646d2SAndroid Build Coastguard Worker 
834*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
835*5e7646d2SAndroid Build Coastguard Worker 	                _("      **FAIL**  REQUIRED PageSize\n"
836*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Pages 99-100, section 5.14."));
837*5e7646d2SAndroid Build Coastguard Worker         }
838*5e7646d2SAndroid Build Coastguard Worker 
839*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
840*5e7646d2SAndroid Build Coastguard Worker       }
841*5e7646d2SAndroid Build Coastguard Worker 
842*5e7646d2SAndroid Build Coastguard Worker       if (ppdFindOption(ppd, "PageRegion") != NULL)
843*5e7646d2SAndroid Build Coastguard Worker       {
844*5e7646d2SAndroid Build Coastguard Worker 	if (verbose > 0)
845*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _("        PASS    PageRegion"));
846*5e7646d2SAndroid Build Coastguard Worker       }
847*5e7646d2SAndroid Build Coastguard Worker       else
848*5e7646d2SAndroid Build Coastguard Worker       {
849*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
850*5e7646d2SAndroid Build Coastguard Worker 	{
851*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
852*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
853*5e7646d2SAndroid Build Coastguard Worker 
854*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
855*5e7646d2SAndroid Build Coastguard Worker 	                _("      **FAIL**  REQUIRED PageRegion\n"
856*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Page 100, section 5.14."));
857*5e7646d2SAndroid Build Coastguard Worker         }
858*5e7646d2SAndroid Build Coastguard Worker 
859*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
860*5e7646d2SAndroid Build Coastguard Worker       }
861*5e7646d2SAndroid Build Coastguard Worker 
862*5e7646d2SAndroid Build Coastguard Worker       if (ppd->pcfilename != NULL)
863*5e7646d2SAndroid Build Coastguard Worker       {
864*5e7646d2SAndroid Build Coastguard Worker 	if (verbose > 0)
865*5e7646d2SAndroid Build Coastguard Worker           _cupsLangPuts(stdout, _("        PASS    PCFileName"));
866*5e7646d2SAndroid Build Coastguard Worker       }
867*5e7646d2SAndroid Build Coastguard Worker       else if (!(ignore & WARN_FILENAME))
868*5e7646d2SAndroid Build Coastguard Worker       {
869*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
870*5e7646d2SAndroid Build Coastguard Worker 	{
871*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
872*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
873*5e7646d2SAndroid Build Coastguard Worker 
874*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
875*5e7646d2SAndroid Build Coastguard Worker 	                _("      **FAIL**  REQUIRED PCFileName\n"
876*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Pages 61-62, section 5.3."));
877*5e7646d2SAndroid Build Coastguard Worker         }
878*5e7646d2SAndroid Build Coastguard Worker 
879*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
880*5e7646d2SAndroid Build Coastguard Worker       }
881*5e7646d2SAndroid Build Coastguard Worker 
882*5e7646d2SAndroid Build Coastguard Worker       if (ppd->product != NULL)
883*5e7646d2SAndroid Build Coastguard Worker       {
884*5e7646d2SAndroid Build Coastguard Worker         if (ppd->product[0] != '(' ||
885*5e7646d2SAndroid Build Coastguard Worker 	    ppd->product[strlen(ppd->product) - 1] != ')')
886*5e7646d2SAndroid Build Coastguard Worker 	{
887*5e7646d2SAndroid Build Coastguard Worker 	  if (verbose >= 0)
888*5e7646d2SAndroid Build Coastguard Worker 	  {
889*5e7646d2SAndroid Build Coastguard Worker 	    if (!errors && !verbose)
890*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPuts(stdout, _(" FAIL"));
891*5e7646d2SAndroid Build Coastguard Worker 
892*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout,
893*5e7646d2SAndroid Build Coastguard Worker 	                  _("      **FAIL**  Bad Product - not \"(string)\".\n"
894*5e7646d2SAndroid Build Coastguard Worker 			    "                REF: Page 62, section 5.3."));
895*5e7646d2SAndroid Build Coastguard Worker           }
896*5e7646d2SAndroid Build Coastguard Worker 
897*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
898*5e7646d2SAndroid Build Coastguard Worker 	}
899*5e7646d2SAndroid Build Coastguard Worker 	else if (verbose > 0)
900*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _("        PASS    Product"));
901*5e7646d2SAndroid Build Coastguard Worker       }
902*5e7646d2SAndroid Build Coastguard Worker       else
903*5e7646d2SAndroid Build Coastguard Worker       {
904*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
905*5e7646d2SAndroid Build Coastguard Worker 	{
906*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
907*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
908*5e7646d2SAndroid Build Coastguard Worker 
909*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
910*5e7646d2SAndroid Build Coastguard Worker 	                _("      **FAIL**  REQUIRED Product\n"
911*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Page 62, section 5.3."));
912*5e7646d2SAndroid Build Coastguard Worker         }
913*5e7646d2SAndroid Build Coastguard Worker 
914*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
915*5e7646d2SAndroid Build Coastguard Worker       }
916*5e7646d2SAndroid Build Coastguard Worker 
917*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ppdFindAttr(ppd, "PSVersion", NULL)) != NULL &&
918*5e7646d2SAndroid Build Coastguard Worker           attr->value != NULL)
919*5e7646d2SAndroid Build Coastguard Worker       {
920*5e7646d2SAndroid Build Coastguard Worker         char	junkstr[255];			/* Temp string */
921*5e7646d2SAndroid Build Coastguard Worker 	int	junkint;			/* Temp integer */
922*5e7646d2SAndroid Build Coastguard Worker 
923*5e7646d2SAndroid Build Coastguard Worker 
924*5e7646d2SAndroid Build Coastguard Worker         if (sscanf(attr->value, "(%254[^)\n])%d", junkstr, &junkint) != 2)
925*5e7646d2SAndroid Build Coastguard Worker 	{
926*5e7646d2SAndroid Build Coastguard Worker 	  if (verbose >= 0)
927*5e7646d2SAndroid Build Coastguard Worker 	  {
928*5e7646d2SAndroid Build Coastguard Worker 	    if (!errors && !verbose)
929*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPuts(stdout, _(" FAIL"));
930*5e7646d2SAndroid Build Coastguard Worker 
931*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout,
932*5e7646d2SAndroid Build Coastguard Worker 	                  _("      **FAIL**  Bad PSVersion - not \"(string) "
933*5e7646d2SAndroid Build Coastguard Worker 			    "int\".\n"
934*5e7646d2SAndroid Build Coastguard Worker 			    "                REF: Pages 62-64, section 5.3."));
935*5e7646d2SAndroid Build Coastguard Worker           }
936*5e7646d2SAndroid Build Coastguard Worker 
937*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
938*5e7646d2SAndroid Build Coastguard Worker 	}
939*5e7646d2SAndroid Build Coastguard Worker 	else if (verbose > 0)
940*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _("        PASS    PSVersion"));
941*5e7646d2SAndroid Build Coastguard Worker       }
942*5e7646d2SAndroid Build Coastguard Worker       else
943*5e7646d2SAndroid Build Coastguard Worker       {
944*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
945*5e7646d2SAndroid Build Coastguard Worker 	{
946*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
947*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
948*5e7646d2SAndroid Build Coastguard Worker 
949*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
950*5e7646d2SAndroid Build Coastguard Worker 	                _("      **FAIL**  REQUIRED PSVersion\n"
951*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Pages 62-64, section 5.3."));
952*5e7646d2SAndroid Build Coastguard Worker         }
953*5e7646d2SAndroid Build Coastguard Worker 
954*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
955*5e7646d2SAndroid Build Coastguard Worker       }
956*5e7646d2SAndroid Build Coastguard Worker 
957*5e7646d2SAndroid Build Coastguard Worker       if (ppd->shortnickname != NULL)
958*5e7646d2SAndroid Build Coastguard Worker       {
959*5e7646d2SAndroid Build Coastguard Worker         if (strlen(ppd->shortnickname) > 31)
960*5e7646d2SAndroid Build Coastguard Worker 	{
961*5e7646d2SAndroid Build Coastguard Worker 	  if (verbose >= 0)
962*5e7646d2SAndroid Build Coastguard Worker 	  {
963*5e7646d2SAndroid Build Coastguard Worker 	    if (!errors && !verbose)
964*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPuts(stdout, _(" FAIL"));
965*5e7646d2SAndroid Build Coastguard Worker 
966*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout,
967*5e7646d2SAndroid Build Coastguard Worker 	                  _("      **FAIL**  Bad ShortNickName - longer "
968*5e7646d2SAndroid Build Coastguard Worker 			    "than 31 chars.\n"
969*5e7646d2SAndroid Build Coastguard Worker 			    "                REF: Pages 64-65, section 5.3."));
970*5e7646d2SAndroid Build Coastguard Worker           }
971*5e7646d2SAndroid Build Coastguard Worker 
972*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
973*5e7646d2SAndroid Build Coastguard Worker 	}
974*5e7646d2SAndroid Build Coastguard Worker 	else if (verbose > 0)
975*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _("        PASS    ShortNickName"));
976*5e7646d2SAndroid Build Coastguard Worker       }
977*5e7646d2SAndroid Build Coastguard Worker       else if (ppdversion >= 43)
978*5e7646d2SAndroid Build Coastguard Worker       {
979*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
980*5e7646d2SAndroid Build Coastguard Worker 	{
981*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
982*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
983*5e7646d2SAndroid Build Coastguard Worker 
984*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
985*5e7646d2SAndroid Build Coastguard Worker 	                _("      **FAIL**  REQUIRED ShortNickName\n"
986*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Page 64-65, section 5.3."));
987*5e7646d2SAndroid Build Coastguard Worker         }
988*5e7646d2SAndroid Build Coastguard Worker 
989*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
990*5e7646d2SAndroid Build Coastguard Worker       }
991*5e7646d2SAndroid Build Coastguard Worker 
992*5e7646d2SAndroid Build Coastguard Worker       if (ppd->patches != NULL && strchr(ppd->patches, '\"') &&
993*5e7646d2SAndroid Build Coastguard Worker           strstr(ppd->patches, "*End"))
994*5e7646d2SAndroid Build Coastguard Worker       {
995*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
996*5e7646d2SAndroid Build Coastguard Worker 	{
997*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
998*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
999*5e7646d2SAndroid Build Coastguard Worker 
1000*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
1001*5e7646d2SAndroid Build Coastguard Worker 	                _("      **FAIL**  Bad JobPatchFile attribute in file\n"
1002*5e7646d2SAndroid Build Coastguard Worker 	                  "                REF: Page 24, section 3.4."));
1003*5e7646d2SAndroid Build Coastguard Worker         }
1004*5e7646d2SAndroid Build Coastguard Worker 
1005*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
1006*5e7646d2SAndroid Build Coastguard Worker       }
1007*5e7646d2SAndroid Build Coastguard Worker 
1008*5e7646d2SAndroid Build Coastguard Worker      /*
1009*5e7646d2SAndroid Build Coastguard Worker       * Check for page sizes without the corresponding ImageableArea or
1010*5e7646d2SAndroid Build Coastguard Worker       * PaperDimension values...
1011*5e7646d2SAndroid Build Coastguard Worker       */
1012*5e7646d2SAndroid Build Coastguard Worker 
1013*5e7646d2SAndroid Build Coastguard Worker       if (ppd->num_sizes == 0)
1014*5e7646d2SAndroid Build Coastguard Worker       {
1015*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
1016*5e7646d2SAndroid Build Coastguard Worker 	{
1017*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
1018*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
1019*5e7646d2SAndroid Build Coastguard Worker 
1020*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
1021*5e7646d2SAndroid Build Coastguard Worker 	                _("      **FAIL**  REQUIRED PageSize\n"
1022*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Page 41, section 5.\n"
1023*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Page 99, section 5.14."));
1024*5e7646d2SAndroid Build Coastguard Worker         }
1025*5e7646d2SAndroid Build Coastguard Worker 
1026*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
1027*5e7646d2SAndroid Build Coastguard Worker       }
1028*5e7646d2SAndroid Build Coastguard Worker       else
1029*5e7646d2SAndroid Build Coastguard Worker       {
1030*5e7646d2SAndroid Build Coastguard Worker 	for (j = 0, size = ppd->sizes; j < ppd->num_sizes; j ++, size ++)
1031*5e7646d2SAndroid Build Coastguard Worker 	{
1032*5e7646d2SAndroid Build Coastguard Worker 	 /*
1033*5e7646d2SAndroid Build Coastguard Worker 	  * Don't check custom size...
1034*5e7646d2SAndroid Build Coastguard Worker 	  */
1035*5e7646d2SAndroid Build Coastguard Worker 
1036*5e7646d2SAndroid Build Coastguard Worker 	  if (!strcmp(size->name, "Custom"))
1037*5e7646d2SAndroid Build Coastguard Worker 	    continue;
1038*5e7646d2SAndroid Build Coastguard Worker 
1039*5e7646d2SAndroid Build Coastguard Worker 	 /*
1040*5e7646d2SAndroid Build Coastguard Worker 	  * Check for ImageableArea...
1041*5e7646d2SAndroid Build Coastguard Worker 	  */
1042*5e7646d2SAndroid Build Coastguard Worker 
1043*5e7646d2SAndroid Build Coastguard Worker           if (size->left == 0.0 && size->bottom == 0.0 &&
1044*5e7646d2SAndroid Build Coastguard Worker 	      size->right == 0.0 && size->top == 0.0)
1045*5e7646d2SAndroid Build Coastguard Worker 	  {
1046*5e7646d2SAndroid Build Coastguard Worker 	    if (verbose >= 0)
1047*5e7646d2SAndroid Build Coastguard Worker 	    {
1048*5e7646d2SAndroid Build Coastguard Worker 	      if (!errors && !verbose)
1049*5e7646d2SAndroid Build Coastguard Worker 		_cupsLangPuts(stdout, _(" FAIL"));
1050*5e7646d2SAndroid Build Coastguard Worker 
1051*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPrintf(stdout,
1052*5e7646d2SAndroid Build Coastguard Worker 	                      _("      **FAIL**  REQUIRED ImageableArea for "
1053*5e7646d2SAndroid Build Coastguard Worker 			        "PageSize %s\n"
1054*5e7646d2SAndroid Build Coastguard Worker 				"                REF: Page 41, section 5.\n"
1055*5e7646d2SAndroid Build Coastguard Worker 				"                REF: Page 102, section 5.15."),
1056*5e7646d2SAndroid Build Coastguard Worker 	        	      size->name);
1057*5e7646d2SAndroid Build Coastguard Worker             }
1058*5e7646d2SAndroid Build Coastguard Worker 
1059*5e7646d2SAndroid Build Coastguard Worker 	    errors ++;
1060*5e7646d2SAndroid Build Coastguard Worker 	  }
1061*5e7646d2SAndroid Build Coastguard Worker 
1062*5e7646d2SAndroid Build Coastguard Worker 	 /*
1063*5e7646d2SAndroid Build Coastguard Worker 	  * Check for PaperDimension...
1064*5e7646d2SAndroid Build Coastguard Worker 	  */
1065*5e7646d2SAndroid Build Coastguard Worker 
1066*5e7646d2SAndroid Build Coastguard Worker           if (size->width <= 0.0 && size->length <= 0.0)
1067*5e7646d2SAndroid Build Coastguard Worker 	  {
1068*5e7646d2SAndroid Build Coastguard Worker 	    if (verbose >= 0)
1069*5e7646d2SAndroid Build Coastguard Worker 	    {
1070*5e7646d2SAndroid Build Coastguard Worker 	      if (!errors && !verbose)
1071*5e7646d2SAndroid Build Coastguard Worker 		_cupsLangPuts(stdout, _(" FAIL"));
1072*5e7646d2SAndroid Build Coastguard Worker 
1073*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPrintf(stdout,
1074*5e7646d2SAndroid Build Coastguard Worker 	                      _("      **FAIL**  REQUIRED PaperDimension "
1075*5e7646d2SAndroid Build Coastguard Worker 			        "for PageSize %s\n"
1076*5e7646d2SAndroid Build Coastguard Worker 				"                REF: Page 41, section 5.\n"
1077*5e7646d2SAndroid Build Coastguard Worker 				"                REF: Page 103, section 5.15."),
1078*5e7646d2SAndroid Build Coastguard Worker 	                      size->name);
1079*5e7646d2SAndroid Build Coastguard Worker             }
1080*5e7646d2SAndroid Build Coastguard Worker 
1081*5e7646d2SAndroid Build Coastguard Worker 	    errors ++;
1082*5e7646d2SAndroid Build Coastguard Worker 	  }
1083*5e7646d2SAndroid Build Coastguard Worker 	}
1084*5e7646d2SAndroid Build Coastguard Worker       }
1085*5e7646d2SAndroid Build Coastguard Worker 
1086*5e7646d2SAndroid Build Coastguard Worker      /*
1087*5e7646d2SAndroid Build Coastguard Worker       * Check for valid Resolution, JCLResolution, or SetResolution values...
1088*5e7646d2SAndroid Build Coastguard Worker       */
1089*5e7646d2SAndroid Build Coastguard Worker 
1090*5e7646d2SAndroid Build Coastguard Worker       if ((option = ppdFindOption(ppd, "Resolution")) == NULL)
1091*5e7646d2SAndroid Build Coastguard Worker 	if ((option = ppdFindOption(ppd, "JCLResolution")) == NULL)
1092*5e7646d2SAndroid Build Coastguard Worker           option = ppdFindOption(ppd, "SetResolution");
1093*5e7646d2SAndroid Build Coastguard Worker 
1094*5e7646d2SAndroid Build Coastguard Worker       if (option != NULL)
1095*5e7646d2SAndroid Build Coastguard Worker       {
1096*5e7646d2SAndroid Build Coastguard Worker         for (j = option->num_choices, choice = option->choices;
1097*5e7646d2SAndroid Build Coastguard Worker 	     j > 0;
1098*5e7646d2SAndroid Build Coastguard Worker 	     j --, choice ++)
1099*5e7646d2SAndroid Build Coastguard Worker         {
1100*5e7646d2SAndroid Build Coastguard Worker 	 /*
1101*5e7646d2SAndroid Build Coastguard Worker 	  * Verify that all resolution options are of the form NNNdpi
1102*5e7646d2SAndroid Build Coastguard Worker 	  * or NNNxNNNdpi...
1103*5e7646d2SAndroid Build Coastguard Worker 	  */
1104*5e7646d2SAndroid Build Coastguard Worker 
1105*5e7646d2SAndroid Build Coastguard Worker           xdpi = strtol(choice->choice, (char **)&ptr, 10);
1106*5e7646d2SAndroid Build Coastguard Worker 	  if (ptr > choice->choice && xdpi > 0)
1107*5e7646d2SAndroid Build Coastguard Worker 	  {
1108*5e7646d2SAndroid Build Coastguard Worker 	    if (*ptr == 'x')
1109*5e7646d2SAndroid Build Coastguard Worker 	      ydpi = strtol(ptr + 1, (char **)&ptr, 10);
1110*5e7646d2SAndroid Build Coastguard Worker 	    else
1111*5e7646d2SAndroid Build Coastguard Worker 	      ydpi = xdpi;
1112*5e7646d2SAndroid Build Coastguard Worker 	  }
1113*5e7646d2SAndroid Build Coastguard Worker 	  else
1114*5e7646d2SAndroid Build Coastguard Worker 	    ydpi = xdpi;
1115*5e7646d2SAndroid Build Coastguard Worker 
1116*5e7646d2SAndroid Build Coastguard Worker 	  if (xdpi <= 0 || xdpi > 99999 || ydpi <= 0 || ydpi > 99999 ||
1117*5e7646d2SAndroid Build Coastguard Worker 	      strcmp(ptr, "dpi"))
1118*5e7646d2SAndroid Build Coastguard Worker 	  {
1119*5e7646d2SAndroid Build Coastguard Worker 	    if (verbose >= 0)
1120*5e7646d2SAndroid Build Coastguard Worker 	    {
1121*5e7646d2SAndroid Build Coastguard Worker 	      if (!errors && !verbose)
1122*5e7646d2SAndroid Build Coastguard Worker 		_cupsLangPuts(stdout, _(" FAIL"));
1123*5e7646d2SAndroid Build Coastguard Worker 
1124*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPrintf(stdout,
1125*5e7646d2SAndroid Build Coastguard Worker 	                      _("      **FAIL**  Bad option %s choice %s\n"
1126*5e7646d2SAndroid Build Coastguard Worker 			        "                REF: Page 84, section 5.9"),
1127*5e7646d2SAndroid Build Coastguard Worker 	                      option->keyword, choice->choice);
1128*5e7646d2SAndroid Build Coastguard Worker             }
1129*5e7646d2SAndroid Build Coastguard Worker 
1130*5e7646d2SAndroid Build Coastguard Worker 	    errors ++;
1131*5e7646d2SAndroid Build Coastguard Worker 	  }
1132*5e7646d2SAndroid Build Coastguard Worker 	}
1133*5e7646d2SAndroid Build Coastguard Worker       }
1134*5e7646d2SAndroid Build Coastguard Worker 
1135*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ppdFindAttr(ppd, "1284DeviceID", NULL)) &&
1136*5e7646d2SAndroid Build Coastguard Worker           strcmp(attr->name, "1284DeviceID"))
1137*5e7646d2SAndroid Build Coastguard Worker       {
1138*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
1139*5e7646d2SAndroid Build Coastguard Worker 	{
1140*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
1141*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
1142*5e7646d2SAndroid Build Coastguard Worker 
1143*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
1144*5e7646d2SAndroid Build Coastguard Worker 	                  _("      **FAIL**  %s must be 1284DeviceID\n"
1145*5e7646d2SAndroid Build Coastguard Worker 			    "                REF: Page 72, section 5.5"),
1146*5e7646d2SAndroid Build Coastguard Worker 			  attr->name);
1147*5e7646d2SAndroid Build Coastguard Worker         }
1148*5e7646d2SAndroid Build Coastguard Worker 
1149*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
1150*5e7646d2SAndroid Build Coastguard Worker       }
1151*5e7646d2SAndroid Build Coastguard Worker 
1152*5e7646d2SAndroid Build Coastguard Worker       errors = check_case(ppd, errors, verbose);
1153*5e7646d2SAndroid Build Coastguard Worker 
1154*5e7646d2SAndroid Build Coastguard Worker       if (!(warn & WARN_CONSTRAINTS))
1155*5e7646d2SAndroid Build Coastguard Worker         errors = check_constraints(ppd, errors, verbose, 0);
1156*5e7646d2SAndroid Build Coastguard Worker 
1157*5e7646d2SAndroid Build Coastguard Worker       if (!(warn & WARN_FILTERS) && !(ignore & WARN_FILTERS))
1158*5e7646d2SAndroid Build Coastguard Worker         errors = check_filters(ppd, root, errors, verbose, 0);
1159*5e7646d2SAndroid Build Coastguard Worker 
1160*5e7646d2SAndroid Build Coastguard Worker       if (!(warn & WARN_PROFILES) && !(ignore & WARN_PROFILES))
1161*5e7646d2SAndroid Build Coastguard Worker         errors = check_profiles(ppd, root, errors, verbose, 0);
1162*5e7646d2SAndroid Build Coastguard Worker 
1163*5e7646d2SAndroid Build Coastguard Worker       if (!(warn & WARN_SIZES))
1164*5e7646d2SAndroid Build Coastguard Worker 	errors = check_sizes(ppd, errors, verbose, 0);
1165*5e7646d2SAndroid Build Coastguard Worker 
1166*5e7646d2SAndroid Build Coastguard Worker       if (!(warn & WARN_TRANSLATIONS))
1167*5e7646d2SAndroid Build Coastguard Worker         errors = check_translations(ppd, errors, verbose, 0);
1168*5e7646d2SAndroid Build Coastguard Worker 
1169*5e7646d2SAndroid Build Coastguard Worker       if (!(warn & WARN_DUPLEX))
1170*5e7646d2SAndroid Build Coastguard Worker         errors = check_duplex(ppd, errors, verbose, 0);
1171*5e7646d2SAndroid Build Coastguard Worker 
1172*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ppdFindAttr(ppd, "cupsLanguages", NULL)) != NULL &&
1173*5e7646d2SAndroid Build Coastguard Worker 	  attr->value)
1174*5e7646d2SAndroid Build Coastguard Worker       {
1175*5e7646d2SAndroid Build Coastguard Worker        /*
1176*5e7646d2SAndroid Build Coastguard Worker 	* This file contains localizations, check for conformance of the
1177*5e7646d2SAndroid Build Coastguard Worker 	* base translation...
1178*5e7646d2SAndroid Build Coastguard Worker 	*/
1179*5e7646d2SAndroid Build Coastguard Worker 
1180*5e7646d2SAndroid Build Coastguard Worker         if ((attr = ppdFindAttr(ppd, "LanguageEncoding", NULL)) != NULL)
1181*5e7646d2SAndroid Build Coastguard Worker 	{
1182*5e7646d2SAndroid Build Coastguard Worker 	  if (!attr->value || strcmp(attr->value, "ISOLatin1"))
1183*5e7646d2SAndroid Build Coastguard Worker 	  {
1184*5e7646d2SAndroid Build Coastguard Worker 	    if (!errors && !verbose)
1185*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPuts(stdout, _(" FAIL"));
1186*5e7646d2SAndroid Build Coastguard Worker 
1187*5e7646d2SAndroid Build Coastguard Worker             if (verbose >= 0)
1188*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPrintf(stdout,
1189*5e7646d2SAndroid Build Coastguard Worker 	                      _("      **FAIL**  Bad LanguageEncoding %s - "
1190*5e7646d2SAndroid Build Coastguard Worker 			        "must be ISOLatin1."),
1191*5e7646d2SAndroid Build Coastguard Worker 	                      attr->value ? attr->value : "(null)");
1192*5e7646d2SAndroid Build Coastguard Worker 
1193*5e7646d2SAndroid Build Coastguard Worker             errors ++;
1194*5e7646d2SAndroid Build Coastguard Worker 	  }
1195*5e7646d2SAndroid Build Coastguard Worker 
1196*5e7646d2SAndroid Build Coastguard Worker           if (!ppd->lang_version || strcmp(ppd->lang_version, "English"))
1197*5e7646d2SAndroid Build Coastguard Worker 	  {
1198*5e7646d2SAndroid Build Coastguard Worker 	    if (!errors && !verbose)
1199*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPuts(stdout, _(" FAIL"));
1200*5e7646d2SAndroid Build Coastguard Worker 
1201*5e7646d2SAndroid Build Coastguard Worker             if (verbose >= 0)
1202*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPrintf(stdout,
1203*5e7646d2SAndroid Build Coastguard Worker 	                      _("      **FAIL**  Bad LanguageVersion %s - "
1204*5e7646d2SAndroid Build Coastguard Worker 			        "must be English."),
1205*5e7646d2SAndroid Build Coastguard Worker 	                      ppd->lang_version ? ppd->lang_version : "(null)");
1206*5e7646d2SAndroid Build Coastguard Worker 
1207*5e7646d2SAndroid Build Coastguard Worker             errors ++;
1208*5e7646d2SAndroid Build Coastguard Worker 	  }
1209*5e7646d2SAndroid Build Coastguard Worker 
1210*5e7646d2SAndroid Build Coastguard Worker 	 /*
1211*5e7646d2SAndroid Build Coastguard Worker 	  * Loop through all options and choices...
1212*5e7646d2SAndroid Build Coastguard Worker 	  */
1213*5e7646d2SAndroid Build Coastguard Worker 
1214*5e7646d2SAndroid Build Coastguard Worker 	  for (option = ppdFirstOption(ppd);
1215*5e7646d2SAndroid Build Coastguard Worker 	       option;
1216*5e7646d2SAndroid Build Coastguard Worker 	       option = ppdNextOption(ppd))
1217*5e7646d2SAndroid Build Coastguard Worker 	  {
1218*5e7646d2SAndroid Build Coastguard Worker 	   /*
1219*5e7646d2SAndroid Build Coastguard Worker 	    * Check for special characters outside A0 to BF, F7, or F8
1220*5e7646d2SAndroid Build Coastguard Worker 	    * that are used for languages other than English.
1221*5e7646d2SAndroid Build Coastguard Worker 	    */
1222*5e7646d2SAndroid Build Coastguard Worker 
1223*5e7646d2SAndroid Build Coastguard Worker 	    for (ptr = option->text; *ptr; ptr ++)
1224*5e7646d2SAndroid Build Coastguard Worker 	      if ((*ptr & 0x80) && (*ptr & 0xe0) != 0xa0 &&
1225*5e7646d2SAndroid Build Coastguard Worker 		  (*ptr & 0xff) != 0xf7 && (*ptr & 0xff) != 0xf8)
1226*5e7646d2SAndroid Build Coastguard Worker 		break;
1227*5e7646d2SAndroid Build Coastguard Worker 
1228*5e7646d2SAndroid Build Coastguard Worker 	    if (*ptr)
1229*5e7646d2SAndroid Build Coastguard Worker 	    {
1230*5e7646d2SAndroid Build Coastguard Worker 	      if (!errors && !verbose)
1231*5e7646d2SAndroid Build Coastguard Worker 		_cupsLangPuts(stdout, _(" FAIL"));
1232*5e7646d2SAndroid Build Coastguard Worker 
1233*5e7646d2SAndroid Build Coastguard Worker 	      if (verbose >= 0)
1234*5e7646d2SAndroid Build Coastguard Worker 		_cupsLangPrintf(stdout,
1235*5e7646d2SAndroid Build Coastguard Worker 				_("      **FAIL**  Default translation "
1236*5e7646d2SAndroid Build Coastguard Worker 				  "string for option %s contains 8-bit "
1237*5e7646d2SAndroid Build Coastguard Worker 				  "characters."),
1238*5e7646d2SAndroid Build Coastguard Worker 				option->keyword);
1239*5e7646d2SAndroid Build Coastguard Worker 
1240*5e7646d2SAndroid Build Coastguard Worker 	      errors ++;
1241*5e7646d2SAndroid Build Coastguard Worker 	    }
1242*5e7646d2SAndroid Build Coastguard Worker 
1243*5e7646d2SAndroid Build Coastguard Worker 	    for (j = 0; j < option->num_choices; j ++)
1244*5e7646d2SAndroid Build Coastguard Worker 	    {
1245*5e7646d2SAndroid Build Coastguard Worker 	     /*
1246*5e7646d2SAndroid Build Coastguard Worker 	      * Check for special characters outside A0 to BF, F7, or F8
1247*5e7646d2SAndroid Build Coastguard Worker 	      * that are used for languages other than English.
1248*5e7646d2SAndroid Build Coastguard Worker 	      */
1249*5e7646d2SAndroid Build Coastguard Worker 
1250*5e7646d2SAndroid Build Coastguard Worker 	      for (ptr = option->choices[j].text; *ptr; ptr ++)
1251*5e7646d2SAndroid Build Coastguard Worker 		if ((*ptr & 0x80) && (*ptr & 0xe0) != 0xa0 &&
1252*5e7646d2SAndroid Build Coastguard Worker 		    (*ptr & 0xff) != 0xf7 && (*ptr & 0xff) != 0xf8)
1253*5e7646d2SAndroid Build Coastguard Worker 		  break;
1254*5e7646d2SAndroid Build Coastguard Worker 
1255*5e7646d2SAndroid Build Coastguard Worker 	      if (*ptr)
1256*5e7646d2SAndroid Build Coastguard Worker 	      {
1257*5e7646d2SAndroid Build Coastguard Worker 		if (!errors && !verbose)
1258*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPuts(stdout, _(" FAIL"));
1259*5e7646d2SAndroid Build Coastguard Worker 
1260*5e7646d2SAndroid Build Coastguard Worker 		if (verbose >= 0)
1261*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stdout,
1262*5e7646d2SAndroid Build Coastguard Worker 				  _("      **FAIL**  Default translation "
1263*5e7646d2SAndroid Build Coastguard Worker 				    "string for option %s choice %s contains "
1264*5e7646d2SAndroid Build Coastguard Worker 				    "8-bit characters."),
1265*5e7646d2SAndroid Build Coastguard Worker 				  option->keyword,
1266*5e7646d2SAndroid Build Coastguard Worker 				  option->choices[j].choice);
1267*5e7646d2SAndroid Build Coastguard Worker 
1268*5e7646d2SAndroid Build Coastguard Worker 		errors ++;
1269*5e7646d2SAndroid Build Coastguard Worker 	      }
1270*5e7646d2SAndroid Build Coastguard Worker 	    }
1271*5e7646d2SAndroid Build Coastguard Worker 	  }
1272*5e7646d2SAndroid Build Coastguard Worker 	}
1273*5e7646d2SAndroid Build Coastguard Worker       }
1274*5e7646d2SAndroid Build Coastguard Worker 
1275*5e7646d2SAndroid Build Coastguard Worker      /*
1276*5e7646d2SAndroid Build Coastguard Worker       * Final pass/fail notification...
1277*5e7646d2SAndroid Build Coastguard Worker       */
1278*5e7646d2SAndroid Build Coastguard Worker 
1279*5e7646d2SAndroid Build Coastguard Worker       if (errors)
1280*5e7646d2SAndroid Build Coastguard Worker 	status = ERROR_CONFORMANCE;
1281*5e7646d2SAndroid Build Coastguard Worker       else if (!verbose)
1282*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" PASS"));
1283*5e7646d2SAndroid Build Coastguard Worker 
1284*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
1285*5e7646d2SAndroid Build Coastguard Worker       {
1286*5e7646d2SAndroid Build Coastguard Worker         check_basics(argv[i]);
1287*5e7646d2SAndroid Build Coastguard Worker 
1288*5e7646d2SAndroid Build Coastguard Worker 	if (warn & WARN_DEFAULTS)
1289*5e7646d2SAndroid Build Coastguard Worker 	  errors = check_defaults(ppd, errors, verbose, 1);
1290*5e7646d2SAndroid Build Coastguard Worker 
1291*5e7646d2SAndroid Build Coastguard Worker 	if (warn & WARN_CONSTRAINTS)
1292*5e7646d2SAndroid Build Coastguard Worker 	  errors = check_constraints(ppd, errors, verbose, 1);
1293*5e7646d2SAndroid Build Coastguard Worker 
1294*5e7646d2SAndroid Build Coastguard Worker 	if ((warn & WARN_FILTERS) && !(ignore & WARN_FILTERS))
1295*5e7646d2SAndroid Build Coastguard Worker 	  errors = check_filters(ppd, root, errors, verbose, 1);
1296*5e7646d2SAndroid Build Coastguard Worker 
1297*5e7646d2SAndroid Build Coastguard Worker 	if ((warn & WARN_PROFILES) && !(ignore & WARN_PROFILES))
1298*5e7646d2SAndroid Build Coastguard Worker 	  errors = check_profiles(ppd, root, errors, verbose, 1);
1299*5e7646d2SAndroid Build Coastguard Worker 
1300*5e7646d2SAndroid Build Coastguard Worker         if (warn & WARN_SIZES)
1301*5e7646d2SAndroid Build Coastguard Worker 	  errors = check_sizes(ppd, errors, verbose, 1);
1302*5e7646d2SAndroid Build Coastguard Worker         else
1303*5e7646d2SAndroid Build Coastguard Worker 	  errors = check_sizes(ppd, errors, verbose, 2);
1304*5e7646d2SAndroid Build Coastguard Worker 
1305*5e7646d2SAndroid Build Coastguard Worker 	if (warn & WARN_TRANSLATIONS)
1306*5e7646d2SAndroid Build Coastguard Worker 	  errors = check_translations(ppd, errors, verbose, 1);
1307*5e7646d2SAndroid Build Coastguard Worker 
1308*5e7646d2SAndroid Build Coastguard Worker 	if (warn & WARN_DUPLEX)
1309*5e7646d2SAndroid Build Coastguard Worker 	  errors = check_duplex(ppd, errors, verbose, 1);
1310*5e7646d2SAndroid Build Coastguard Worker 
1311*5e7646d2SAndroid Build Coastguard Worker        /*
1312*5e7646d2SAndroid Build Coastguard Worker         * Look for legacy duplex keywords...
1313*5e7646d2SAndroid Build Coastguard Worker 	*/
1314*5e7646d2SAndroid Build Coastguard Worker 
1315*5e7646d2SAndroid Build Coastguard Worker 	if ((option = ppdFindOption(ppd, "JCLDuplex")) == NULL)
1316*5e7646d2SAndroid Build Coastguard Worker 	  if ((option = ppdFindOption(ppd, "EFDuplex")) == NULL)
1317*5e7646d2SAndroid Build Coastguard Worker 	    option = ppdFindOption(ppd, "KD03Duplex");
1318*5e7646d2SAndroid Build Coastguard Worker 
1319*5e7646d2SAndroid Build Coastguard Worker 	if (option)
1320*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
1321*5e7646d2SAndroid Build Coastguard Worker 			  _("        WARN    Duplex option keyword %s may not "
1322*5e7646d2SAndroid Build Coastguard Worker 			    "work as expected and should be named Duplex.\n"
1323*5e7646d2SAndroid Build Coastguard Worker 			    "                REF: Page 122, section 5.17"),
1324*5e7646d2SAndroid Build Coastguard Worker 			  option->keyword);
1325*5e7646d2SAndroid Build Coastguard Worker 
1326*5e7646d2SAndroid Build Coastguard Worker        /*
1327*5e7646d2SAndroid Build Coastguard Worker 	* Look for default keywords with no corresponding option...
1328*5e7646d2SAndroid Build Coastguard Worker 	*/
1329*5e7646d2SAndroid Build Coastguard Worker 
1330*5e7646d2SAndroid Build Coastguard Worker 	for (j = 0; j < ppd->num_attrs; j ++)
1331*5e7646d2SAndroid Build Coastguard Worker 	{
1332*5e7646d2SAndroid Build Coastguard Worker 	  attr = ppd->attrs[j];
1333*5e7646d2SAndroid Build Coastguard Worker 
1334*5e7646d2SAndroid Build Coastguard Worker           if (!strcmp(attr->name, "DefaultColorSpace") ||
1335*5e7646d2SAndroid Build Coastguard Worker 	      !strcmp(attr->name, "DefaultColorSep") ||
1336*5e7646d2SAndroid Build Coastguard Worker 	      !strcmp(attr->name, "DefaultFont") ||
1337*5e7646d2SAndroid Build Coastguard Worker 	      !strcmp(attr->name, "DefaultHalftoneType") ||
1338*5e7646d2SAndroid Build Coastguard Worker 	      !strcmp(attr->name, "DefaultImageableArea") ||
1339*5e7646d2SAndroid Build Coastguard Worker 	      !strcmp(attr->name, "DefaultLeadingEdge") ||
1340*5e7646d2SAndroid Build Coastguard Worker 	      !strcmp(attr->name, "DefaultOutputOrder") ||
1341*5e7646d2SAndroid Build Coastguard Worker 	      !strcmp(attr->name, "DefaultPaperDimension") ||
1342*5e7646d2SAndroid Build Coastguard Worker 	      !strcmp(attr->name, "DefaultResolution") ||
1343*5e7646d2SAndroid Build Coastguard Worker 	      !strcmp(attr->name, "DefaultScreenProc") ||
1344*5e7646d2SAndroid Build Coastguard Worker 	      !strcmp(attr->name, "DefaultTransfer"))
1345*5e7646d2SAndroid Build Coastguard Worker 	    continue;
1346*5e7646d2SAndroid Build Coastguard Worker 
1347*5e7646d2SAndroid Build Coastguard Worker 	  if (!strncmp(attr->name, "Default", 7) &&
1348*5e7646d2SAndroid Build Coastguard Worker 	      !ppdFindOption(ppd, attr->name + 7))
1349*5e7646d2SAndroid Build Coastguard Worker             _cupsLangPrintf(stdout,
1350*5e7646d2SAndroid Build Coastguard Worker 	                    _("        WARN    %s has no corresponding "
1351*5e7646d2SAndroid Build Coastguard Worker 			      "options."),
1352*5e7646d2SAndroid Build Coastguard Worker 	                    attr->name);
1353*5e7646d2SAndroid Build Coastguard Worker 	}
1354*5e7646d2SAndroid Build Coastguard Worker 
1355*5e7646d2SAndroid Build Coastguard Worker         if (ppdversion < 43)
1356*5e7646d2SAndroid Build Coastguard Worker 	{
1357*5e7646d2SAndroid Build Coastguard Worker           _cupsLangPrintf(stdout,
1358*5e7646d2SAndroid Build Coastguard Worker 	                  _("        WARN    Obsolete PPD version %.1f.\n"
1359*5e7646d2SAndroid Build Coastguard Worker 			    "                REF: Page 42, section 5.2."),
1360*5e7646d2SAndroid Build Coastguard Worker 	        	  0.1f * ppdversion);
1361*5e7646d2SAndroid Build Coastguard Worker 	}
1362*5e7646d2SAndroid Build Coastguard Worker 
1363*5e7646d2SAndroid Build Coastguard Worker         if (!ppd->lang_encoding && ppdversion < 41)
1364*5e7646d2SAndroid Build Coastguard Worker 	{
1365*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
1366*5e7646d2SAndroid Build Coastguard Worker 	                _("        WARN    LanguageEncoding required by PPD "
1367*5e7646d2SAndroid Build Coastguard Worker 			  "4.3 spec.\n"
1368*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Pages 56-57, section 5.3."));
1369*5e7646d2SAndroid Build Coastguard Worker 	}
1370*5e7646d2SAndroid Build Coastguard Worker 
1371*5e7646d2SAndroid Build Coastguard Worker         if (!ppd->manufacturer && ppdversion < 43)
1372*5e7646d2SAndroid Build Coastguard Worker 	{
1373*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
1374*5e7646d2SAndroid Build Coastguard Worker 	                _("        WARN    Manufacturer required by PPD "
1375*5e7646d2SAndroid Build Coastguard Worker 			  "4.3 spec.\n"
1376*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Pages 58-59, section 5.3."));
1377*5e7646d2SAndroid Build Coastguard Worker 	}
1378*5e7646d2SAndroid Build Coastguard Worker 
1379*5e7646d2SAndroid Build Coastguard Worker        /*
1380*5e7646d2SAndroid Build Coastguard Worker 	* Treat a PCFileName attribute longer than 12 characters as
1381*5e7646d2SAndroid Build Coastguard Worker 	* a warning and not a hard error...
1382*5e7646d2SAndroid Build Coastguard Worker 	*/
1383*5e7646d2SAndroid Build Coastguard Worker 
1384*5e7646d2SAndroid Build Coastguard Worker         if (!(ignore & WARN_FILENAME) && ppd->pcfilename)
1385*5e7646d2SAndroid Build Coastguard Worker         {
1386*5e7646d2SAndroid Build Coastguard Worker 	  if (strlen(ppd->pcfilename) > 12)
1387*5e7646d2SAndroid Build Coastguard Worker 	  {
1388*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout,
1389*5e7646d2SAndroid Build Coastguard Worker 			  _("        WARN    PCFileName longer than 8.3 in "
1390*5e7646d2SAndroid Build Coastguard Worker 			    "violation of PPD spec.\n"
1391*5e7646d2SAndroid Build Coastguard Worker 			    "                REF: Pages 61-62, section "
1392*5e7646d2SAndroid Build Coastguard Worker 			    "5.3."));
1393*5e7646d2SAndroid Build Coastguard Worker 	  }
1394*5e7646d2SAndroid Build Coastguard Worker 
1395*5e7646d2SAndroid Build Coastguard Worker 	  if (!_cups_strcasecmp(ppd->pcfilename, "unused.ppd"))
1396*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout,
1397*5e7646d2SAndroid Build Coastguard Worker 	                  _("        WARN    PCFileName should contain a "
1398*5e7646d2SAndroid Build Coastguard Worker 	                    "unique filename.\n"
1399*5e7646d2SAndroid Build Coastguard Worker 			    "                REF: Pages 61-62, section "
1400*5e7646d2SAndroid Build Coastguard Worker 			    "5.3."));
1401*5e7646d2SAndroid Build Coastguard Worker         }
1402*5e7646d2SAndroid Build Coastguard Worker 
1403*5e7646d2SAndroid Build Coastguard Worker         if (!ppd->shortnickname && ppdversion < 43)
1404*5e7646d2SAndroid Build Coastguard Worker 	{
1405*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout,
1406*5e7646d2SAndroid Build Coastguard Worker 	                _("        WARN    ShortNickName required by PPD "
1407*5e7646d2SAndroid Build Coastguard Worker 			  "4.3 spec.\n"
1408*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Pages 64-65, section 5.3."));
1409*5e7646d2SAndroid Build Coastguard Worker 	}
1410*5e7646d2SAndroid Build Coastguard Worker 
1411*5e7646d2SAndroid Build Coastguard Worker        /*
1412*5e7646d2SAndroid Build Coastguard Worker         * Check the Protocols line and flag PJL + BCP since TBCP is
1413*5e7646d2SAndroid Build Coastguard Worker 	* usually used with PJL...
1414*5e7646d2SAndroid Build Coastguard Worker 	*/
1415*5e7646d2SAndroid Build Coastguard Worker 
1416*5e7646d2SAndroid Build Coastguard Worker         if (ppd->protocols)
1417*5e7646d2SAndroid Build Coastguard Worker 	{
1418*5e7646d2SAndroid Build Coastguard Worker 	  if (strstr(ppd->protocols, "PJL") &&
1419*5e7646d2SAndroid Build Coastguard Worker 	      strstr(ppd->protocols, "BCP") &&
1420*5e7646d2SAndroid Build Coastguard Worker 	      !strstr(ppd->protocols, "TBCP"))
1421*5e7646d2SAndroid Build Coastguard Worker 	  {
1422*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout,
1423*5e7646d2SAndroid Build Coastguard Worker 	                  _("        WARN    Protocols contains both PJL "
1424*5e7646d2SAndroid Build Coastguard Worker 			    "and BCP; expected TBCP.\n"
1425*5e7646d2SAndroid Build Coastguard Worker 			    "                REF: Pages 78-79, section 5.7."));
1426*5e7646d2SAndroid Build Coastguard Worker 	  }
1427*5e7646d2SAndroid Build Coastguard Worker 
1428*5e7646d2SAndroid Build Coastguard Worker 	  if (strstr(ppd->protocols, "PJL") &&
1429*5e7646d2SAndroid Build Coastguard Worker 	      (!ppd->jcl_begin || !ppd->jcl_end || !ppd->jcl_ps))
1430*5e7646d2SAndroid Build Coastguard Worker 	  {
1431*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout,
1432*5e7646d2SAndroid Build Coastguard Worker 	                  _("        WARN    Protocols contains PJL but JCL "
1433*5e7646d2SAndroid Build Coastguard Worker 			    "attributes are not set.\n"
1434*5e7646d2SAndroid Build Coastguard Worker 			    "                REF: Pages 78-79, section 5.7."));
1435*5e7646d2SAndroid Build Coastguard Worker 	  }
1436*5e7646d2SAndroid Build Coastguard Worker 	}
1437*5e7646d2SAndroid Build Coastguard Worker 
1438*5e7646d2SAndroid Build Coastguard Worker        /*
1439*5e7646d2SAndroid Build Coastguard Worker         * Check for options with a common prefix, e.g. Duplex and Duplexer,
1440*5e7646d2SAndroid Build Coastguard Worker 	* which are errors according to the spec but won't cause problems
1441*5e7646d2SAndroid Build Coastguard Worker 	* with CUPS specifically...
1442*5e7646d2SAndroid Build Coastguard Worker 	*/
1443*5e7646d2SAndroid Build Coastguard Worker 
1444*5e7646d2SAndroid Build Coastguard Worker 	for (j = 0, group = ppd->groups; j < ppd->num_groups; j ++, group ++)
1445*5e7646d2SAndroid Build Coastguard Worker 	  for (k = 0, option = group->options;
1446*5e7646d2SAndroid Build Coastguard Worker 	       k < group->num_options;
1447*5e7646d2SAndroid Build Coastguard Worker 	       k ++, option ++)
1448*5e7646d2SAndroid Build Coastguard Worker 	  {
1449*5e7646d2SAndroid Build Coastguard Worker 	    len = strlen(option->keyword);
1450*5e7646d2SAndroid Build Coastguard Worker 
1451*5e7646d2SAndroid Build Coastguard Worker 	    for (m = 0, group2 = ppd->groups;
1452*5e7646d2SAndroid Build Coastguard Worker 		 m < ppd->num_groups;
1453*5e7646d2SAndroid Build Coastguard Worker 		 m ++, group2 ++)
1454*5e7646d2SAndroid Build Coastguard Worker 	      for (n = 0, option2 = group2->options;
1455*5e7646d2SAndroid Build Coastguard Worker 	           n < group2->num_options;
1456*5e7646d2SAndroid Build Coastguard Worker 		   n ++, option2 ++)
1457*5e7646d2SAndroid Build Coastguard Worker 		if (option != option2 &&
1458*5e7646d2SAndroid Build Coastguard Worker 	            len < strlen(option2->keyword) &&
1459*5e7646d2SAndroid Build Coastguard Worker 	            !strncmp(option->keyword, option2->keyword, len))
1460*5e7646d2SAndroid Build Coastguard Worker 		{
1461*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stdout,
1462*5e7646d2SAndroid Build Coastguard Worker 		                  _("        WARN    %s shares a common "
1463*5e7646d2SAndroid Build Coastguard Worker 				    "prefix with %s\n"
1464*5e7646d2SAndroid Build Coastguard Worker 				    "                REF: Page 15, section "
1465*5e7646d2SAndroid Build Coastguard Worker 				    "3.2."),
1466*5e7646d2SAndroid Build Coastguard Worker 		                  option->keyword, option2->keyword);
1467*5e7646d2SAndroid Build Coastguard Worker         	}
1468*5e7646d2SAndroid Build Coastguard Worker 	  }
1469*5e7646d2SAndroid Build Coastguard Worker       }
1470*5e7646d2SAndroid Build Coastguard Worker 
1471*5e7646d2SAndroid Build Coastguard Worker       if (verbose > 0)
1472*5e7646d2SAndroid Build Coastguard Worker       {
1473*5e7646d2SAndroid Build Coastguard Worker         if (errors)
1474*5e7646d2SAndroid Build Coastguard Worker           _cupsLangPrintf(stdout, _("    %d ERRORS FOUND"), errors);
1475*5e7646d2SAndroid Build Coastguard Worker 	else
1476*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _("    NO ERRORS FOUND"));
1477*5e7646d2SAndroid Build Coastguard Worker       }
1478*5e7646d2SAndroid Build Coastguard Worker 
1479*5e7646d2SAndroid Build Coastguard Worker      /*
1480*5e7646d2SAndroid Build Coastguard Worker       * Then list the options, if "-v" was provided...
1481*5e7646d2SAndroid Build Coastguard Worker       */
1482*5e7646d2SAndroid Build Coastguard Worker 
1483*5e7646d2SAndroid Build Coastguard Worker       if (verbose > 1)
1484*5e7646d2SAndroid Build Coastguard Worker       {
1485*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
1486*5e7646d2SAndroid Build Coastguard Worker                         "\n"
1487*5e7646d2SAndroid Build Coastguard Worker 		        "    language_level = %d\n"
1488*5e7646d2SAndroid Build Coastguard Worker 			"    color_device = %s\n"
1489*5e7646d2SAndroid Build Coastguard Worker 			"    variable_sizes = %s\n"
1490*5e7646d2SAndroid Build Coastguard Worker 			"    landscape = %d",
1491*5e7646d2SAndroid Build Coastguard Worker 			ppd->language_level,
1492*5e7646d2SAndroid Build Coastguard Worker 			ppd->color_device ? "TRUE" : "FALSE",
1493*5e7646d2SAndroid Build Coastguard Worker 			ppd->variable_sizes ? "TRUE" : "FALSE",
1494*5e7646d2SAndroid Build Coastguard Worker 			ppd->landscape);
1495*5e7646d2SAndroid Build Coastguard Worker 
1496*5e7646d2SAndroid Build Coastguard Worker 	switch (ppd->colorspace)
1497*5e7646d2SAndroid Build Coastguard Worker 	{
1498*5e7646d2SAndroid Build Coastguard Worker 	  case PPD_CS_CMYK :
1499*5e7646d2SAndroid Build Coastguard Worker               _cupsLangPuts(stdout, "    colorspace = PPD_CS_CMYK");
1500*5e7646d2SAndroid Build Coastguard Worker 	      break;
1501*5e7646d2SAndroid Build Coastguard Worker 	  case PPD_CS_CMY :
1502*5e7646d2SAndroid Build Coastguard Worker               _cupsLangPuts(stdout, "    colorspace = PPD_CS_CMY");
1503*5e7646d2SAndroid Build Coastguard Worker 	      break;
1504*5e7646d2SAndroid Build Coastguard Worker 	  case PPD_CS_GRAY :
1505*5e7646d2SAndroid Build Coastguard Worker               _cupsLangPuts(stdout, "    colorspace = PPD_CS_GRAY");
1506*5e7646d2SAndroid Build Coastguard Worker 	      break;
1507*5e7646d2SAndroid Build Coastguard Worker 	  case PPD_CS_RGB :
1508*5e7646d2SAndroid Build Coastguard Worker               _cupsLangPuts(stdout, "    colorspace = PPD_CS_RGB");
1509*5e7646d2SAndroid Build Coastguard Worker 	      break;
1510*5e7646d2SAndroid Build Coastguard Worker 	  default :
1511*5e7646d2SAndroid Build Coastguard Worker               _cupsLangPuts(stdout, "    colorspace = <unknown>");
1512*5e7646d2SAndroid Build Coastguard Worker 	      break;
1513*5e7646d2SAndroid Build Coastguard Worker 	}
1514*5e7646d2SAndroid Build Coastguard Worker 
1515*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, "    num_emulations = %d",
1516*5e7646d2SAndroid Build Coastguard Worker 			ppd->num_emulations);
1517*5e7646d2SAndroid Build Coastguard Worker 	for (j = 0; j < ppd->num_emulations; j ++)
1518*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout, "        emulations[%d] = %s",
1519*5e7646d2SAndroid Build Coastguard Worker 	                  j, ppd->emulations[j].name);
1520*5e7646d2SAndroid Build Coastguard Worker 
1521*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, "    lang_encoding = %s",
1522*5e7646d2SAndroid Build Coastguard Worker 	                ppd->lang_encoding);
1523*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, "    lang_version = %s",
1524*5e7646d2SAndroid Build Coastguard Worker 	                ppd->lang_version);
1525*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, "    modelname = %s", ppd->modelname);
1526*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, "    ttrasterizer = %s",
1527*5e7646d2SAndroid Build Coastguard Worker         		ppd->ttrasterizer == NULL ? "None" : ppd->ttrasterizer);
1528*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, "    manufacturer = %s",
1529*5e7646d2SAndroid Build Coastguard Worker 	                ppd->manufacturer);
1530*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, "    product = %s", ppd->product);
1531*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, "    nickname = %s", ppd->nickname);
1532*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, "    shortnickname = %s",
1533*5e7646d2SAndroid Build Coastguard Worker 	                ppd->shortnickname);
1534*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, "    patches = %d bytes",
1535*5e7646d2SAndroid Build Coastguard Worker         		ppd->patches == NULL ? 0 : (int)strlen(ppd->patches));
1536*5e7646d2SAndroid Build Coastguard Worker 
1537*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, "    num_groups = %d", ppd->num_groups);
1538*5e7646d2SAndroid Build Coastguard Worker 	for (j = 0, group = ppd->groups; j < ppd->num_groups; j ++, group ++)
1539*5e7646d2SAndroid Build Coastguard Worker 	{
1540*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout, "        group[%d] = %s",
1541*5e7646d2SAndroid Build Coastguard Worker 	                  j, group->text);
1542*5e7646d2SAndroid Build Coastguard Worker 
1543*5e7646d2SAndroid Build Coastguard Worker 	  for (k = 0, option = group->options; k < group->num_options; k ++, option ++)
1544*5e7646d2SAndroid Build Coastguard Worker 	  {
1545*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPrintf(stdout,
1546*5e7646d2SAndroid Build Coastguard Worker 	                    "            options[%d] = %s (%s) %s %s %.0f "
1547*5e7646d2SAndroid Build Coastguard Worker 			    "(%d choices)",
1548*5e7646d2SAndroid Build Coastguard Worker 	        	    k, option->keyword, option->text, uis[option->ui],
1549*5e7646d2SAndroid Build Coastguard Worker 			    sections[option->section], option->order,
1550*5e7646d2SAndroid Build Coastguard Worker 			    option->num_choices);
1551*5e7646d2SAndroid Build Coastguard Worker 
1552*5e7646d2SAndroid Build Coastguard Worker             if (!strcmp(option->keyword, "PageSize") ||
1553*5e7646d2SAndroid Build Coastguard Worker         	!strcmp(option->keyword, "PageRegion"))
1554*5e7646d2SAndroid Build Coastguard Worker             {
1555*5e7646d2SAndroid Build Coastguard Worker               for (m = option->num_choices, choice = option->choices;
1556*5e7646d2SAndroid Build Coastguard Worker 		   m > 0;
1557*5e7646d2SAndroid Build Coastguard Worker 		   m --, choice ++)
1558*5e7646d2SAndroid Build Coastguard Worker 	      {
1559*5e7646d2SAndroid Build Coastguard Worker 		size = ppdPageSize(ppd, choice->choice);
1560*5e7646d2SAndroid Build Coastguard Worker 
1561*5e7646d2SAndroid Build Coastguard Worker 		if (size == NULL)
1562*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stdout,
1563*5e7646d2SAndroid Build Coastguard Worker                                   "                %s (%s) = ERROR%s",
1564*5e7646d2SAndroid Build Coastguard Worker 				  choice->choice, choice->text,
1565*5e7646d2SAndroid Build Coastguard Worker 				  !strcmp(option->defchoice, choice->choice)
1566*5e7646d2SAndroid Build Coastguard Worker 				      ? " *" : "");
1567*5e7646d2SAndroid Build Coastguard Worker         	else
1568*5e7646d2SAndroid Build Coastguard Worker 		  _cupsLangPrintf(stdout,
1569*5e7646d2SAndroid Build Coastguard Worker                                   "                %s (%s) = %.2fx%.2fin "
1570*5e7646d2SAndroid Build Coastguard Worker 				  "(%.1f,%.1f,%.1f,%.1f)%s",
1571*5e7646d2SAndroid Build Coastguard Worker 		        	  choice->choice, choice->text,
1572*5e7646d2SAndroid Build Coastguard Worker 				  size->width / 72.0, size->length / 72.0,
1573*5e7646d2SAndroid Build Coastguard Worker 				  size->left / 72.0, size->bottom / 72.0,
1574*5e7646d2SAndroid Build Coastguard Worker 				  size->right / 72.0, size->top / 72.0,
1575*5e7646d2SAndroid Build Coastguard Worker 				  !strcmp(option->defchoice, choice->choice)
1576*5e7646d2SAndroid Build Coastguard Worker 				      ? " *" : "");
1577*5e7646d2SAndroid Build Coastguard Worker               }
1578*5e7646d2SAndroid Build Coastguard Worker 	    }
1579*5e7646d2SAndroid Build Coastguard Worker 	    else
1580*5e7646d2SAndroid Build Coastguard Worker 	    {
1581*5e7646d2SAndroid Build Coastguard Worker 	      for (m = option->num_choices, choice = option->choices;
1582*5e7646d2SAndroid Build Coastguard Worker 		   m > 0;
1583*5e7646d2SAndroid Build Coastguard Worker 		   m --, choice ++)
1584*5e7646d2SAndroid Build Coastguard Worker 	      {
1585*5e7646d2SAndroid Build Coastguard Worker 		_cupsLangPrintf(stdout, "                %s (%s)%s",
1586*5e7646d2SAndroid Build Coastguard Worker 		                choice->choice, choice->text,
1587*5e7646d2SAndroid Build Coastguard Worker 				!strcmp(option->defchoice, choice->choice)
1588*5e7646d2SAndroid Build Coastguard Worker 				    ? " *" : "");
1589*5e7646d2SAndroid Build Coastguard Worker 	      }
1590*5e7646d2SAndroid Build Coastguard Worker             }
1591*5e7646d2SAndroid Build Coastguard Worker 	  }
1592*5e7646d2SAndroid Build Coastguard Worker 	}
1593*5e7646d2SAndroid Build Coastguard Worker 
1594*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, "    num_consts = %d",
1595*5e7646d2SAndroid Build Coastguard Worker 	                ppd->num_consts);
1596*5e7646d2SAndroid Build Coastguard Worker 	for (j = 0; j < ppd->num_consts; j ++)
1597*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
1598*5e7646d2SAndroid Build Coastguard Worker                 	  "        consts[%d] = *%s %s *%s %s",
1599*5e7646d2SAndroid Build Coastguard Worker         		  j, ppd->consts[j].option1, ppd->consts[j].choice1,
1600*5e7646d2SAndroid Build Coastguard Worker 			  ppd->consts[j].option2, ppd->consts[j].choice2);
1601*5e7646d2SAndroid Build Coastguard Worker 
1602*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, "    num_profiles = %d",
1603*5e7646d2SAndroid Build Coastguard Worker 	                ppd->num_profiles);
1604*5e7646d2SAndroid Build Coastguard Worker 	for (j = 0; j < ppd->num_profiles; j ++)
1605*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
1606*5e7646d2SAndroid Build Coastguard Worker                 	  "        profiles[%d] = %s/%s %.3f %.3f "
1607*5e7646d2SAndroid Build Coastguard Worker 			  "[ %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f ]",
1608*5e7646d2SAndroid Build Coastguard Worker         		  j, ppd->profiles[j].resolution,
1609*5e7646d2SAndroid Build Coastguard Worker 			  ppd->profiles[j].media_type,
1610*5e7646d2SAndroid Build Coastguard Worker 			  ppd->profiles[j].gamma, ppd->profiles[j].density,
1611*5e7646d2SAndroid Build Coastguard Worker 			  ppd->profiles[j].matrix[0][0],
1612*5e7646d2SAndroid Build Coastguard Worker 			  ppd->profiles[j].matrix[0][1],
1613*5e7646d2SAndroid Build Coastguard Worker 			  ppd->profiles[j].matrix[0][2],
1614*5e7646d2SAndroid Build Coastguard Worker 			  ppd->profiles[j].matrix[1][0],
1615*5e7646d2SAndroid Build Coastguard Worker 			  ppd->profiles[j].matrix[1][1],
1616*5e7646d2SAndroid Build Coastguard Worker 			  ppd->profiles[j].matrix[1][2],
1617*5e7646d2SAndroid Build Coastguard Worker 			  ppd->profiles[j].matrix[2][0],
1618*5e7646d2SAndroid Build Coastguard Worker 			  ppd->profiles[j].matrix[2][1],
1619*5e7646d2SAndroid Build Coastguard Worker 			  ppd->profiles[j].matrix[2][2]);
1620*5e7646d2SAndroid Build Coastguard Worker 
1621*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, "    num_fonts = %d", ppd->num_fonts);
1622*5e7646d2SAndroid Build Coastguard Worker 	for (j = 0; j < ppd->num_fonts; j ++)
1623*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout, "        fonts[%d] = %s",
1624*5e7646d2SAndroid Build Coastguard Worker 	                  j, ppd->fonts[j]);
1625*5e7646d2SAndroid Build Coastguard Worker 
1626*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, "    num_attrs = %d", ppd->num_attrs);
1627*5e7646d2SAndroid Build Coastguard Worker 	for (j = 0; j < ppd->num_attrs; j ++)
1628*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
1629*5e7646d2SAndroid Build Coastguard Worker 	                  "        attrs[%d] = %s %s%s%s: \"%s\"", j,
1630*5e7646d2SAndroid Build Coastguard Worker 	        	  ppd->attrs[j]->name, ppd->attrs[j]->spec,
1631*5e7646d2SAndroid Build Coastguard Worker 			  ppd->attrs[j]->text[0] ? "/" : "",
1632*5e7646d2SAndroid Build Coastguard Worker 			  ppd->attrs[j]->text,
1633*5e7646d2SAndroid Build Coastguard Worker 			  ppd->attrs[j]->value ?
1634*5e7646d2SAndroid Build Coastguard Worker 			      ppd->attrs[j]->value : "(null)");
1635*5e7646d2SAndroid Build Coastguard Worker       }
1636*5e7646d2SAndroid Build Coastguard Worker 
1637*5e7646d2SAndroid Build Coastguard Worker       ppdClose(ppd);
1638*5e7646d2SAndroid Build Coastguard Worker     }
1639*5e7646d2SAndroid Build Coastguard Worker 
1640*5e7646d2SAndroid Build Coastguard Worker   if (!files)
1641*5e7646d2SAndroid Build Coastguard Worker     usage();
1642*5e7646d2SAndroid Build Coastguard Worker 
1643*5e7646d2SAndroid Build Coastguard Worker   return (status);
1644*5e7646d2SAndroid Build Coastguard Worker }
1645*5e7646d2SAndroid Build Coastguard Worker 
1646*5e7646d2SAndroid Build Coastguard Worker 
1647*5e7646d2SAndroid Build Coastguard Worker /*
1648*5e7646d2SAndroid Build Coastguard Worker  * 'check_basics()' - Check for CR LF, mixed line endings, and blank lines.
1649*5e7646d2SAndroid Build Coastguard Worker  */
1650*5e7646d2SAndroid Build Coastguard Worker 
1651*5e7646d2SAndroid Build Coastguard Worker static void
check_basics(const char * filename)1652*5e7646d2SAndroid Build Coastguard Worker check_basics(const char *filename)	/* I - PPD file to check */
1653*5e7646d2SAndroid Build Coastguard Worker {
1654*5e7646d2SAndroid Build Coastguard Worker   cups_file_t	*fp;			/* File pointer */
1655*5e7646d2SAndroid Build Coastguard Worker   int		ch;			/* Current character */
1656*5e7646d2SAndroid Build Coastguard Worker   int		col,			/* Current column */
1657*5e7646d2SAndroid Build Coastguard Worker 		whitespace;		/* Only seen whitespace? */
1658*5e7646d2SAndroid Build Coastguard Worker   int		eol;			/* Line endings */
1659*5e7646d2SAndroid Build Coastguard Worker   int		linenum;		/* Line number */
1660*5e7646d2SAndroid Build Coastguard Worker   int		mixed;			/* Mixed line endings? */
1661*5e7646d2SAndroid Build Coastguard Worker 
1662*5e7646d2SAndroid Build Coastguard Worker 
1663*5e7646d2SAndroid Build Coastguard Worker   if ((fp = cupsFileOpen(filename, "r")) == NULL)
1664*5e7646d2SAndroid Build Coastguard Worker     return;
1665*5e7646d2SAndroid Build Coastguard Worker 
1666*5e7646d2SAndroid Build Coastguard Worker   linenum    = 1;
1667*5e7646d2SAndroid Build Coastguard Worker   col        = 0;
1668*5e7646d2SAndroid Build Coastguard Worker   eol        = EOL_NONE;
1669*5e7646d2SAndroid Build Coastguard Worker   mixed      = 0;
1670*5e7646d2SAndroid Build Coastguard Worker   whitespace = 1;
1671*5e7646d2SAndroid Build Coastguard Worker 
1672*5e7646d2SAndroid Build Coastguard Worker   while ((ch = cupsFileGetChar(fp)) != EOF)
1673*5e7646d2SAndroid Build Coastguard Worker   {
1674*5e7646d2SAndroid Build Coastguard Worker     if (ch == '\r' || ch == '\n')
1675*5e7646d2SAndroid Build Coastguard Worker     {
1676*5e7646d2SAndroid Build Coastguard Worker       if (ch == '\n')
1677*5e7646d2SAndroid Build Coastguard Worker       {
1678*5e7646d2SAndroid Build Coastguard Worker 	if (eol == EOL_NONE)
1679*5e7646d2SAndroid Build Coastguard Worker 	  eol = EOL_LF;
1680*5e7646d2SAndroid Build Coastguard Worker 	else if (eol != EOL_LF)
1681*5e7646d2SAndroid Build Coastguard Worker 	  mixed = 1;
1682*5e7646d2SAndroid Build Coastguard Worker       }
1683*5e7646d2SAndroid Build Coastguard Worker       else if (ch == '\r')
1684*5e7646d2SAndroid Build Coastguard Worker       {
1685*5e7646d2SAndroid Build Coastguard Worker 	if (cupsFilePeekChar(fp) == '\n')
1686*5e7646d2SAndroid Build Coastguard Worker 	{
1687*5e7646d2SAndroid Build Coastguard Worker 	  cupsFileGetChar(fp);
1688*5e7646d2SAndroid Build Coastguard Worker 
1689*5e7646d2SAndroid Build Coastguard Worker           if (eol == EOL_NONE)
1690*5e7646d2SAndroid Build Coastguard Worker 	    eol = EOL_CRLF;
1691*5e7646d2SAndroid Build Coastguard Worker 	  else if (eol != EOL_CRLF)
1692*5e7646d2SAndroid Build Coastguard Worker 	    mixed = 1;
1693*5e7646d2SAndroid Build Coastguard Worker 	}
1694*5e7646d2SAndroid Build Coastguard Worker 	else if (eol == EOL_NONE)
1695*5e7646d2SAndroid Build Coastguard Worker 	  eol = EOL_CR;
1696*5e7646d2SAndroid Build Coastguard Worker         else if (eol != EOL_CR)
1697*5e7646d2SAndroid Build Coastguard Worker 	  mixed = 1;
1698*5e7646d2SAndroid Build Coastguard Worker       }
1699*5e7646d2SAndroid Build Coastguard Worker 
1700*5e7646d2SAndroid Build Coastguard Worker       if (col > 0 && whitespace)
1701*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
1702*5e7646d2SAndroid Build Coastguard Worker 		        _("        WARN    Line %d only contains whitespace."),
1703*5e7646d2SAndroid Build Coastguard Worker 			linenum);
1704*5e7646d2SAndroid Build Coastguard Worker 
1705*5e7646d2SAndroid Build Coastguard Worker       linenum ++;
1706*5e7646d2SAndroid Build Coastguard Worker       col        = 0;
1707*5e7646d2SAndroid Build Coastguard Worker       whitespace = 1;
1708*5e7646d2SAndroid Build Coastguard Worker     }
1709*5e7646d2SAndroid Build Coastguard Worker     else
1710*5e7646d2SAndroid Build Coastguard Worker     {
1711*5e7646d2SAndroid Build Coastguard Worker       if (ch != ' ' && ch != '\t')
1712*5e7646d2SAndroid Build Coastguard Worker         whitespace = 0;
1713*5e7646d2SAndroid Build Coastguard Worker 
1714*5e7646d2SAndroid Build Coastguard Worker       col ++;
1715*5e7646d2SAndroid Build Coastguard Worker     }
1716*5e7646d2SAndroid Build Coastguard Worker   }
1717*5e7646d2SAndroid Build Coastguard Worker 
1718*5e7646d2SAndroid Build Coastguard Worker   if (mixed)
1719*5e7646d2SAndroid Build Coastguard Worker     _cupsLangPuts(stdout,
1720*5e7646d2SAndroid Build Coastguard Worker 		  _("        WARN    File contains a mix of CR, LF, and "
1721*5e7646d2SAndroid Build Coastguard Worker 		    "CR LF line endings."));
1722*5e7646d2SAndroid Build Coastguard Worker 
1723*5e7646d2SAndroid Build Coastguard Worker   if (eol == EOL_CRLF)
1724*5e7646d2SAndroid Build Coastguard Worker     _cupsLangPuts(stdout,
1725*5e7646d2SAndroid Build Coastguard Worker 		  _("        WARN    Non-Windows PPD files should use lines "
1726*5e7646d2SAndroid Build Coastguard Worker 		    "ending with only LF, not CR LF."));
1727*5e7646d2SAndroid Build Coastguard Worker 
1728*5e7646d2SAndroid Build Coastguard Worker   cupsFileClose(fp);
1729*5e7646d2SAndroid Build Coastguard Worker }
1730*5e7646d2SAndroid Build Coastguard Worker 
1731*5e7646d2SAndroid Build Coastguard Worker 
1732*5e7646d2SAndroid Build Coastguard Worker /*
1733*5e7646d2SAndroid Build Coastguard Worker  * 'check_constraints()' - Check UIConstraints in the PPD file.
1734*5e7646d2SAndroid Build Coastguard Worker  */
1735*5e7646d2SAndroid Build Coastguard Worker 
1736*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Errors found */
check_constraints(ppd_file_t * ppd,int errors,int verbose,int warn)1737*5e7646d2SAndroid Build Coastguard Worker check_constraints(ppd_file_t *ppd,	/* I - PPD file */
1738*5e7646d2SAndroid Build Coastguard Worker                   int        errors,	/* I - Errors found */
1739*5e7646d2SAndroid Build Coastguard Worker                   int        verbose,	/* I - Verbosity level */
1740*5e7646d2SAndroid Build Coastguard Worker                   int        warn)	/* I - Warnings only? */
1741*5e7646d2SAndroid Build Coastguard Worker {
1742*5e7646d2SAndroid Build Coastguard Worker   int			i;		/* Looping var */
1743*5e7646d2SAndroid Build Coastguard Worker   const char		*prefix;	/* WARN/FAIL prefix */
1744*5e7646d2SAndroid Build Coastguard Worker   ppd_const_t		*c;		/* Current UIConstraints data */
1745*5e7646d2SAndroid Build Coastguard Worker   ppd_attr_t		*constattr;	/* Current cupsUIConstraints attribute */
1746*5e7646d2SAndroid Build Coastguard Worker   const char		*vptr;		/* Pointer into constraint value */
1747*5e7646d2SAndroid Build Coastguard Worker   char			option[PPD_MAX_NAME],
1748*5e7646d2SAndroid Build Coastguard Worker   					/* Option name/MainKeyword */
1749*5e7646d2SAndroid Build Coastguard Worker 			choice[PPD_MAX_NAME],
1750*5e7646d2SAndroid Build Coastguard Worker 					/* Choice/OptionKeyword */
1751*5e7646d2SAndroid Build Coastguard Worker 			*ptr;		/* Pointer into option or choice */
1752*5e7646d2SAndroid Build Coastguard Worker   int			num_options;	/* Number of options */
1753*5e7646d2SAndroid Build Coastguard Worker   cups_option_t		*options;	/* Options */
1754*5e7646d2SAndroid Build Coastguard Worker   ppd_option_t		*o;		/* PPD option */
1755*5e7646d2SAndroid Build Coastguard Worker 
1756*5e7646d2SAndroid Build Coastguard Worker 
1757*5e7646d2SAndroid Build Coastguard Worker   prefix = warn ? "  WARN  " : "**FAIL**";
1758*5e7646d2SAndroid Build Coastguard Worker 
1759*5e7646d2SAndroid Build Coastguard Worker 
1760*5e7646d2SAndroid Build Coastguard Worker  /*
1761*5e7646d2SAndroid Build Coastguard Worker   * See what kind of constraint data we have in the PPD...
1762*5e7646d2SAndroid Build Coastguard Worker   */
1763*5e7646d2SAndroid Build Coastguard Worker 
1764*5e7646d2SAndroid Build Coastguard Worker   if ((constattr = ppdFindAttr(ppd, "cupsUIConstraints", NULL)) != NULL)
1765*5e7646d2SAndroid Build Coastguard Worker   {
1766*5e7646d2SAndroid Build Coastguard Worker    /*
1767*5e7646d2SAndroid Build Coastguard Worker     * Check new-style cupsUIConstraints data...
1768*5e7646d2SAndroid Build Coastguard Worker     */
1769*5e7646d2SAndroid Build Coastguard Worker 
1770*5e7646d2SAndroid Build Coastguard Worker     for (; constattr;
1771*5e7646d2SAndroid Build Coastguard Worker          constattr = ppdFindNextAttr(ppd, "cupsUIConstraints", NULL))
1772*5e7646d2SAndroid Build Coastguard Worker     {
1773*5e7646d2SAndroid Build Coastguard Worker       if (!constattr->value)
1774*5e7646d2SAndroid Build Coastguard Worker       {
1775*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
1776*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
1777*5e7646d2SAndroid Build Coastguard Worker 
1778*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
1779*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Empty cupsUIConstraints %s"),
1780*5e7646d2SAndroid Build Coastguard Worker 			prefix, constattr->spec);
1781*5e7646d2SAndroid Build Coastguard Worker 
1782*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
1783*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
1784*5e7646d2SAndroid Build Coastguard Worker 
1785*5e7646d2SAndroid Build Coastguard Worker         continue;
1786*5e7646d2SAndroid Build Coastguard Worker       }
1787*5e7646d2SAndroid Build Coastguard Worker 
1788*5e7646d2SAndroid Build Coastguard Worker       for (i = 0, vptr = strchr(constattr->value, '*');
1789*5e7646d2SAndroid Build Coastguard Worker            vptr;
1790*5e7646d2SAndroid Build Coastguard Worker 	   i ++, vptr = strchr(vptr + 1, '*'));
1791*5e7646d2SAndroid Build Coastguard Worker 
1792*5e7646d2SAndroid Build Coastguard Worker       if (i == 0)
1793*5e7646d2SAndroid Build Coastguard Worker       {
1794*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
1795*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
1796*5e7646d2SAndroid Build Coastguard Worker 
1797*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
1798*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Bad cupsUIConstraints %s: \"%s\""),
1799*5e7646d2SAndroid Build Coastguard Worker 			prefix, constattr->spec, constattr->value);
1800*5e7646d2SAndroid Build Coastguard Worker 
1801*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
1802*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
1803*5e7646d2SAndroid Build Coastguard Worker 
1804*5e7646d2SAndroid Build Coastguard Worker         continue;
1805*5e7646d2SAndroid Build Coastguard Worker       }
1806*5e7646d2SAndroid Build Coastguard Worker 
1807*5e7646d2SAndroid Build Coastguard Worker       cupsArraySave(ppd->sorted_attrs);
1808*5e7646d2SAndroid Build Coastguard Worker 
1809*5e7646d2SAndroid Build Coastguard Worker       if (constattr->spec[0] &&
1810*5e7646d2SAndroid Build Coastguard Worker           !ppdFindAttr(ppd, "cupsUIResolver", constattr->spec))
1811*5e7646d2SAndroid Build Coastguard Worker       {
1812*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
1813*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
1814*5e7646d2SAndroid Build Coastguard Worker 
1815*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
1816*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Missing cupsUIResolver %s"),
1817*5e7646d2SAndroid Build Coastguard Worker 			prefix, constattr->spec);
1818*5e7646d2SAndroid Build Coastguard Worker 
1819*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
1820*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
1821*5e7646d2SAndroid Build Coastguard Worker       }
1822*5e7646d2SAndroid Build Coastguard Worker 
1823*5e7646d2SAndroid Build Coastguard Worker       cupsArrayRestore(ppd->sorted_attrs);
1824*5e7646d2SAndroid Build Coastguard Worker 
1825*5e7646d2SAndroid Build Coastguard Worker       num_options = 0;
1826*5e7646d2SAndroid Build Coastguard Worker       options     = NULL;
1827*5e7646d2SAndroid Build Coastguard Worker 
1828*5e7646d2SAndroid Build Coastguard Worker       for (vptr = strchr(constattr->value, '*');
1829*5e7646d2SAndroid Build Coastguard Worker            vptr;
1830*5e7646d2SAndroid Build Coastguard Worker 	   vptr = strchr(vptr, '*'))
1831*5e7646d2SAndroid Build Coastguard Worker       {
1832*5e7646d2SAndroid Build Coastguard Worker        /*
1833*5e7646d2SAndroid Build Coastguard Worker         * Extract "*Option Choice" or just "*Option"...
1834*5e7646d2SAndroid Build Coastguard Worker 	*/
1835*5e7646d2SAndroid Build Coastguard Worker 
1836*5e7646d2SAndroid Build Coastguard Worker         for (vptr ++, ptr = option; *vptr && !isspace(*vptr & 255); vptr ++)
1837*5e7646d2SAndroid Build Coastguard Worker 	  if (ptr < (option + sizeof(option) - 1))
1838*5e7646d2SAndroid Build Coastguard Worker 	    *ptr++ = *vptr;
1839*5e7646d2SAndroid Build Coastguard Worker 
1840*5e7646d2SAndroid Build Coastguard Worker         *ptr = '\0';
1841*5e7646d2SAndroid Build Coastguard Worker 
1842*5e7646d2SAndroid Build Coastguard Worker         while (isspace(*vptr & 255))
1843*5e7646d2SAndroid Build Coastguard Worker 	  vptr ++;
1844*5e7646d2SAndroid Build Coastguard Worker 
1845*5e7646d2SAndroid Build Coastguard Worker         if (*vptr == '*')
1846*5e7646d2SAndroid Build Coastguard Worker 	  choice[0] = '\0';
1847*5e7646d2SAndroid Build Coastguard Worker 	else
1848*5e7646d2SAndroid Build Coastguard Worker 	{
1849*5e7646d2SAndroid Build Coastguard Worker 	  for (ptr = choice; *vptr && !isspace(*vptr & 255); vptr ++)
1850*5e7646d2SAndroid Build Coastguard Worker 	    if (ptr < (choice + sizeof(choice) - 1))
1851*5e7646d2SAndroid Build Coastguard Worker 	      *ptr++ = *vptr;
1852*5e7646d2SAndroid Build Coastguard Worker 
1853*5e7646d2SAndroid Build Coastguard Worker 	  *ptr = '\0';
1854*5e7646d2SAndroid Build Coastguard Worker 	}
1855*5e7646d2SAndroid Build Coastguard Worker 
1856*5e7646d2SAndroid Build Coastguard Worker         if (!_cups_strncasecmp(option, "Custom", 6) && !_cups_strcasecmp(choice, "True"))
1857*5e7646d2SAndroid Build Coastguard Worker 	{
1858*5e7646d2SAndroid Build Coastguard Worker 	  _cups_strcpy(option, option + 6);
1859*5e7646d2SAndroid Build Coastguard Worker 	  strlcpy(choice, "Custom", sizeof(choice));
1860*5e7646d2SAndroid Build Coastguard Worker 	}
1861*5e7646d2SAndroid Build Coastguard Worker 
1862*5e7646d2SAndroid Build Coastguard Worker         if ((o = ppdFindOption(ppd, option)) == NULL)
1863*5e7646d2SAndroid Build Coastguard Worker 	{
1864*5e7646d2SAndroid Build Coastguard Worker 	  if (!warn && !errors && !verbose)
1865*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
1866*5e7646d2SAndroid Build Coastguard Worker 
1867*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
1868*5e7646d2SAndroid Build Coastguard Worker 			  _("      %s  Missing option %s in "
1869*5e7646d2SAndroid Build Coastguard Worker 			    "cupsUIConstraints %s: \"%s\""),
1870*5e7646d2SAndroid Build Coastguard Worker 			  prefix, option, constattr->spec, constattr->value);
1871*5e7646d2SAndroid Build Coastguard Worker 
1872*5e7646d2SAndroid Build Coastguard Worker 	  if (!warn)
1873*5e7646d2SAndroid Build Coastguard Worker 	    errors ++;
1874*5e7646d2SAndroid Build Coastguard Worker 
1875*5e7646d2SAndroid Build Coastguard Worker 	  continue;
1876*5e7646d2SAndroid Build Coastguard Worker 	}
1877*5e7646d2SAndroid Build Coastguard Worker 
1878*5e7646d2SAndroid Build Coastguard Worker         if (choice[0] && !ppdFindChoice(o, choice))
1879*5e7646d2SAndroid Build Coastguard Worker 	{
1880*5e7646d2SAndroid Build Coastguard Worker 	  if (!warn && !errors && !verbose)
1881*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
1882*5e7646d2SAndroid Build Coastguard Worker 
1883*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
1884*5e7646d2SAndroid Build Coastguard Worker 			  _("      %s  Missing choice *%s %s in "
1885*5e7646d2SAndroid Build Coastguard Worker 			    "cupsUIConstraints %s: \"%s\""),
1886*5e7646d2SAndroid Build Coastguard Worker 			  prefix, option, choice, constattr->spec,
1887*5e7646d2SAndroid Build Coastguard Worker 			  constattr->value);
1888*5e7646d2SAndroid Build Coastguard Worker 
1889*5e7646d2SAndroid Build Coastguard Worker 	  if (!warn)
1890*5e7646d2SAndroid Build Coastguard Worker 	    errors ++;
1891*5e7646d2SAndroid Build Coastguard Worker 
1892*5e7646d2SAndroid Build Coastguard Worker 	  continue;
1893*5e7646d2SAndroid Build Coastguard Worker 	}
1894*5e7646d2SAndroid Build Coastguard Worker 
1895*5e7646d2SAndroid Build Coastguard Worker         if (choice[0])
1896*5e7646d2SAndroid Build Coastguard Worker 	  num_options = cupsAddOption(option, choice, num_options, &options);
1897*5e7646d2SAndroid Build Coastguard Worker 	else
1898*5e7646d2SAndroid Build Coastguard Worker 	{
1899*5e7646d2SAndroid Build Coastguard Worker 	  for (i = 0; i < o->num_choices; i ++)
1900*5e7646d2SAndroid Build Coastguard Worker 	    if (_cups_strcasecmp(o->choices[i].choice, "None") &&
1901*5e7646d2SAndroid Build Coastguard Worker 	        _cups_strcasecmp(o->choices[i].choice, "Off") &&
1902*5e7646d2SAndroid Build Coastguard Worker 	        _cups_strcasecmp(o->choices[i].choice, "False"))
1903*5e7646d2SAndroid Build Coastguard Worker             {
1904*5e7646d2SAndroid Build Coastguard Worker 	      num_options = cupsAddOption(option, o->choices[i].choice,
1905*5e7646d2SAndroid Build Coastguard Worker 	                                  num_options, &options);
1906*5e7646d2SAndroid Build Coastguard Worker               break;
1907*5e7646d2SAndroid Build Coastguard Worker 	    }
1908*5e7646d2SAndroid Build Coastguard Worker 	}
1909*5e7646d2SAndroid Build Coastguard Worker       }
1910*5e7646d2SAndroid Build Coastguard Worker 
1911*5e7646d2SAndroid Build Coastguard Worker      /*
1912*5e7646d2SAndroid Build Coastguard Worker       * Resolvers must list at least two options...
1913*5e7646d2SAndroid Build Coastguard Worker       */
1914*5e7646d2SAndroid Build Coastguard Worker 
1915*5e7646d2SAndroid Build Coastguard Worker       if (num_options < 2)
1916*5e7646d2SAndroid Build Coastguard Worker       {
1917*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
1918*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
1919*5e7646d2SAndroid Build Coastguard Worker 
1920*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
1921*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  cupsUIResolver %s does not list at least "
1922*5e7646d2SAndroid Build Coastguard Worker 			  "two different options."),
1923*5e7646d2SAndroid Build Coastguard Worker 			prefix, constattr->spec);
1924*5e7646d2SAndroid Build Coastguard Worker 
1925*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
1926*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
1927*5e7646d2SAndroid Build Coastguard Worker       }
1928*5e7646d2SAndroid Build Coastguard Worker 
1929*5e7646d2SAndroid Build Coastguard Worker      /*
1930*5e7646d2SAndroid Build Coastguard Worker       * Test the resolver...
1931*5e7646d2SAndroid Build Coastguard Worker       */
1932*5e7646d2SAndroid Build Coastguard Worker 
1933*5e7646d2SAndroid Build Coastguard Worker       if (!cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options))
1934*5e7646d2SAndroid Build Coastguard Worker       {
1935*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
1936*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
1937*5e7646d2SAndroid Build Coastguard Worker 
1938*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
1939*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  cupsUIResolver %s causes a loop."),
1940*5e7646d2SAndroid Build Coastguard Worker 			prefix, constattr->spec);
1941*5e7646d2SAndroid Build Coastguard Worker 
1942*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
1943*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
1944*5e7646d2SAndroid Build Coastguard Worker       }
1945*5e7646d2SAndroid Build Coastguard Worker 
1946*5e7646d2SAndroid Build Coastguard Worker       cupsFreeOptions(num_options, options);
1947*5e7646d2SAndroid Build Coastguard Worker     }
1948*5e7646d2SAndroid Build Coastguard Worker   }
1949*5e7646d2SAndroid Build Coastguard Worker   else
1950*5e7646d2SAndroid Build Coastguard Worker   {
1951*5e7646d2SAndroid Build Coastguard Worker    /*
1952*5e7646d2SAndroid Build Coastguard Worker     * Check old-style [Non]UIConstraints data...
1953*5e7646d2SAndroid Build Coastguard Worker     */
1954*5e7646d2SAndroid Build Coastguard Worker 
1955*5e7646d2SAndroid Build Coastguard Worker     for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++)
1956*5e7646d2SAndroid Build Coastguard Worker     {
1957*5e7646d2SAndroid Build Coastguard Worker       if (!_cups_strncasecmp(c->option1, "Custom", 6) &&
1958*5e7646d2SAndroid Build Coastguard Worker           !_cups_strcasecmp(c->choice1, "True"))
1959*5e7646d2SAndroid Build Coastguard Worker       {
1960*5e7646d2SAndroid Build Coastguard Worker 	strlcpy(option, c->option1 + 6, sizeof(option));
1961*5e7646d2SAndroid Build Coastguard Worker 	strlcpy(choice, "Custom", sizeof(choice));
1962*5e7646d2SAndroid Build Coastguard Worker       }
1963*5e7646d2SAndroid Build Coastguard Worker       else
1964*5e7646d2SAndroid Build Coastguard Worker       {
1965*5e7646d2SAndroid Build Coastguard Worker 	strlcpy(option, c->option1, sizeof(option));
1966*5e7646d2SAndroid Build Coastguard Worker 	strlcpy(choice, c->choice1, sizeof(choice));
1967*5e7646d2SAndroid Build Coastguard Worker       }
1968*5e7646d2SAndroid Build Coastguard Worker 
1969*5e7646d2SAndroid Build Coastguard Worker       if ((o = ppdFindOption(ppd, option)) == NULL)
1970*5e7646d2SAndroid Build Coastguard Worker       {
1971*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
1972*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
1973*5e7646d2SAndroid Build Coastguard Worker 
1974*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
1975*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Missing option %s in "
1976*5e7646d2SAndroid Build Coastguard Worker 			  "UIConstraints \"*%s %s *%s %s\"."),
1977*5e7646d2SAndroid Build Coastguard Worker 			prefix, c->option1,
1978*5e7646d2SAndroid Build Coastguard Worker 			c->option1, c->choice1, c->option2, c->choice2);
1979*5e7646d2SAndroid Build Coastguard Worker 
1980*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
1981*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
1982*5e7646d2SAndroid Build Coastguard Worker       }
1983*5e7646d2SAndroid Build Coastguard Worker       else if (choice[0] && !ppdFindChoice(o, choice))
1984*5e7646d2SAndroid Build Coastguard Worker       {
1985*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
1986*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
1987*5e7646d2SAndroid Build Coastguard Worker 
1988*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
1989*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Missing choice *%s %s in "
1990*5e7646d2SAndroid Build Coastguard Worker 			  "UIConstraints \"*%s %s *%s %s\"."),
1991*5e7646d2SAndroid Build Coastguard Worker 			prefix, c->option1, c->choice1,
1992*5e7646d2SAndroid Build Coastguard Worker 			c->option1, c->choice1, c->option2, c->choice2);
1993*5e7646d2SAndroid Build Coastguard Worker 
1994*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
1995*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
1996*5e7646d2SAndroid Build Coastguard Worker       }
1997*5e7646d2SAndroid Build Coastguard Worker 
1998*5e7646d2SAndroid Build Coastguard Worker       if (!_cups_strncasecmp(c->option2, "Custom", 6) &&
1999*5e7646d2SAndroid Build Coastguard Worker           !_cups_strcasecmp(c->choice2, "True"))
2000*5e7646d2SAndroid Build Coastguard Worker       {
2001*5e7646d2SAndroid Build Coastguard Worker 	strlcpy(option, c->option2 + 6, sizeof(option));
2002*5e7646d2SAndroid Build Coastguard Worker 	strlcpy(choice, "Custom", sizeof(choice));
2003*5e7646d2SAndroid Build Coastguard Worker       }
2004*5e7646d2SAndroid Build Coastguard Worker       else
2005*5e7646d2SAndroid Build Coastguard Worker       {
2006*5e7646d2SAndroid Build Coastguard Worker 	strlcpy(option, c->option2, sizeof(option));
2007*5e7646d2SAndroid Build Coastguard Worker 	strlcpy(choice, c->choice2, sizeof(choice));
2008*5e7646d2SAndroid Build Coastguard Worker       }
2009*5e7646d2SAndroid Build Coastguard Worker 
2010*5e7646d2SAndroid Build Coastguard Worker       if ((o = ppdFindOption(ppd, option)) == NULL)
2011*5e7646d2SAndroid Build Coastguard Worker       {
2012*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
2013*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
2014*5e7646d2SAndroid Build Coastguard Worker 
2015*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2016*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Missing option %s in "
2017*5e7646d2SAndroid Build Coastguard Worker 			  "UIConstraints \"*%s %s *%s %s\"."),
2018*5e7646d2SAndroid Build Coastguard Worker 			prefix, c->option2,
2019*5e7646d2SAndroid Build Coastguard Worker 			c->option1, c->choice1, c->option2, c->choice2);
2020*5e7646d2SAndroid Build Coastguard Worker 
2021*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
2022*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
2023*5e7646d2SAndroid Build Coastguard Worker       }
2024*5e7646d2SAndroid Build Coastguard Worker       else if (choice[0] && !ppdFindChoice(o, choice))
2025*5e7646d2SAndroid Build Coastguard Worker       {
2026*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
2027*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
2028*5e7646d2SAndroid Build Coastguard Worker 
2029*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2030*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Missing choice *%s %s in "
2031*5e7646d2SAndroid Build Coastguard Worker 			  "UIConstraints \"*%s %s *%s %s\"."),
2032*5e7646d2SAndroid Build Coastguard Worker 			prefix, c->option2, c->choice2,
2033*5e7646d2SAndroid Build Coastguard Worker 			c->option1, c->choice1, c->option2, c->choice2);
2034*5e7646d2SAndroid Build Coastguard Worker 
2035*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
2036*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
2037*5e7646d2SAndroid Build Coastguard Worker       }
2038*5e7646d2SAndroid Build Coastguard Worker     }
2039*5e7646d2SAndroid Build Coastguard Worker   }
2040*5e7646d2SAndroid Build Coastguard Worker 
2041*5e7646d2SAndroid Build Coastguard Worker   return (errors);
2042*5e7646d2SAndroid Build Coastguard Worker }
2043*5e7646d2SAndroid Build Coastguard Worker 
2044*5e7646d2SAndroid Build Coastguard Worker 
2045*5e7646d2SAndroid Build Coastguard Worker /*
2046*5e7646d2SAndroid Build Coastguard Worker  * 'check_case()' - Check that there are no duplicate groups, options,
2047*5e7646d2SAndroid Build Coastguard Worker  *                  or choices that differ only by case.
2048*5e7646d2SAndroid Build Coastguard Worker  */
2049*5e7646d2SAndroid Build Coastguard Worker 
2050*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Errors found */
check_case(ppd_file_t * ppd,int errors,int verbose)2051*5e7646d2SAndroid Build Coastguard Worker check_case(ppd_file_t *ppd,		/* I - PPD file */
2052*5e7646d2SAndroid Build Coastguard Worker            int        errors,		/* I - Errors found */
2053*5e7646d2SAndroid Build Coastguard Worker 	   int        verbose)		/* I - Verbosity level */
2054*5e7646d2SAndroid Build Coastguard Worker {
2055*5e7646d2SAndroid Build Coastguard Worker   int		i, j;			/* Looping vars */
2056*5e7646d2SAndroid Build Coastguard Worker   ppd_group_t	*groupa,		/* First group */
2057*5e7646d2SAndroid Build Coastguard Worker 		*groupb;		/* Second group */
2058*5e7646d2SAndroid Build Coastguard Worker   ppd_option_t	*optiona,		/* First option */
2059*5e7646d2SAndroid Build Coastguard Worker 		*optionb;		/* Second option */
2060*5e7646d2SAndroid Build Coastguard Worker   ppd_choice_t	*choicea,		/* First choice */
2061*5e7646d2SAndroid Build Coastguard Worker 		*choiceb;		/* Second choice */
2062*5e7646d2SAndroid Build Coastguard Worker 
2063*5e7646d2SAndroid Build Coastguard Worker 
2064*5e7646d2SAndroid Build Coastguard Worker  /*
2065*5e7646d2SAndroid Build Coastguard Worker   * Check that the groups do not have any duplicate names...
2066*5e7646d2SAndroid Build Coastguard Worker   */
2067*5e7646d2SAndroid Build Coastguard Worker 
2068*5e7646d2SAndroid Build Coastguard Worker   for (i = ppd->num_groups, groupa = ppd->groups; i > 1; i --, groupa ++)
2069*5e7646d2SAndroid Build Coastguard Worker     for (j = i - 1, groupb = groupa + 1; j > 0; j --, groupb ++)
2070*5e7646d2SAndroid Build Coastguard Worker       if (!_cups_strcasecmp(groupa->name, groupb->name))
2071*5e7646d2SAndroid Build Coastguard Worker       {
2072*5e7646d2SAndroid Build Coastguard Worker 	if (!errors && !verbose)
2073*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
2074*5e7646d2SAndroid Build Coastguard Worker 
2075*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
2076*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
2077*5e7646d2SAndroid Build Coastguard Worker 			  _("      **FAIL**  Group names %s and %s differ only "
2078*5e7646d2SAndroid Build Coastguard Worker 			    "by case."),
2079*5e7646d2SAndroid Build Coastguard Worker 			  groupa->name, groupb->name);
2080*5e7646d2SAndroid Build Coastguard Worker 
2081*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
2082*5e7646d2SAndroid Build Coastguard Worker       }
2083*5e7646d2SAndroid Build Coastguard Worker 
2084*5e7646d2SAndroid Build Coastguard Worker  /*
2085*5e7646d2SAndroid Build Coastguard Worker   * Check that the options do not have any duplicate names...
2086*5e7646d2SAndroid Build Coastguard Worker   */
2087*5e7646d2SAndroid Build Coastguard Worker 
2088*5e7646d2SAndroid Build Coastguard Worker   for (optiona = ppdFirstOption(ppd); optiona; optiona = ppdNextOption(ppd))
2089*5e7646d2SAndroid Build Coastguard Worker   {
2090*5e7646d2SAndroid Build Coastguard Worker     cupsArraySave(ppd->options);
2091*5e7646d2SAndroid Build Coastguard Worker     for (optionb = ppdNextOption(ppd); optionb; optionb = ppdNextOption(ppd))
2092*5e7646d2SAndroid Build Coastguard Worker       if (!_cups_strcasecmp(optiona->keyword, optionb->keyword))
2093*5e7646d2SAndroid Build Coastguard Worker       {
2094*5e7646d2SAndroid Build Coastguard Worker 	if (!errors && !verbose)
2095*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
2096*5e7646d2SAndroid Build Coastguard Worker 
2097*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
2098*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
2099*5e7646d2SAndroid Build Coastguard Worker 			  _("      **FAIL**  Option names %s and %s differ only "
2100*5e7646d2SAndroid Build Coastguard Worker 			    "by case."),
2101*5e7646d2SAndroid Build Coastguard Worker 			  optiona->keyword, optionb->keyword);
2102*5e7646d2SAndroid Build Coastguard Worker 
2103*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
2104*5e7646d2SAndroid Build Coastguard Worker       }
2105*5e7646d2SAndroid Build Coastguard Worker     cupsArrayRestore(ppd->options);
2106*5e7646d2SAndroid Build Coastguard Worker 
2107*5e7646d2SAndroid Build Coastguard Worker    /*
2108*5e7646d2SAndroid Build Coastguard Worker     * Then the choices...
2109*5e7646d2SAndroid Build Coastguard Worker     */
2110*5e7646d2SAndroid Build Coastguard Worker 
2111*5e7646d2SAndroid Build Coastguard Worker     for (i = optiona->num_choices, choicea = optiona->choices;
2112*5e7646d2SAndroid Build Coastguard Worker          i > 1;
2113*5e7646d2SAndroid Build Coastguard Worker 	 i --, choicea ++)
2114*5e7646d2SAndroid Build Coastguard Worker       for (j = i - 1, choiceb = choicea + 1; j > 0; j --, choiceb ++)
2115*5e7646d2SAndroid Build Coastguard Worker         if (!strcmp(choicea->choice, choiceb->choice))
2116*5e7646d2SAndroid Build Coastguard Worker 	{
2117*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
2118*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
2119*5e7646d2SAndroid Build Coastguard Worker 
2120*5e7646d2SAndroid Build Coastguard Worker 	  if (verbose >= 0)
2121*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPrintf(stdout,
2122*5e7646d2SAndroid Build Coastguard Worker 			    _("      **FAIL**  Multiple occurrences of "
2123*5e7646d2SAndroid Build Coastguard Worker 			      "option %s choice name %s."),
2124*5e7646d2SAndroid Build Coastguard Worker 			    optiona->keyword, choicea->choice);
2125*5e7646d2SAndroid Build Coastguard Worker 
2126*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
2127*5e7646d2SAndroid Build Coastguard Worker 
2128*5e7646d2SAndroid Build Coastguard Worker 	  choicea ++;
2129*5e7646d2SAndroid Build Coastguard Worker 	  i --;
2130*5e7646d2SAndroid Build Coastguard Worker 	  break;
2131*5e7646d2SAndroid Build Coastguard Worker 	}
2132*5e7646d2SAndroid Build Coastguard Worker         else if (!_cups_strcasecmp(choicea->choice, choiceb->choice))
2133*5e7646d2SAndroid Build Coastguard Worker 	{
2134*5e7646d2SAndroid Build Coastguard Worker 	  if (!errors && !verbose)
2135*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
2136*5e7646d2SAndroid Build Coastguard Worker 
2137*5e7646d2SAndroid Build Coastguard Worker 	  if (verbose >= 0)
2138*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPrintf(stdout,
2139*5e7646d2SAndroid Build Coastguard Worker 			    _("      **FAIL**  Option %s choice names %s and "
2140*5e7646d2SAndroid Build Coastguard Worker 			      "%s differ only by case."),
2141*5e7646d2SAndroid Build Coastguard Worker 			    optiona->keyword, choicea->choice, choiceb->choice);
2142*5e7646d2SAndroid Build Coastguard Worker 
2143*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
2144*5e7646d2SAndroid Build Coastguard Worker 	}
2145*5e7646d2SAndroid Build Coastguard Worker   }
2146*5e7646d2SAndroid Build Coastguard Worker 
2147*5e7646d2SAndroid Build Coastguard Worker  /*
2148*5e7646d2SAndroid Build Coastguard Worker   * Return the number of errors found...
2149*5e7646d2SAndroid Build Coastguard Worker   */
2150*5e7646d2SAndroid Build Coastguard Worker 
2151*5e7646d2SAndroid Build Coastguard Worker   return (errors);
2152*5e7646d2SAndroid Build Coastguard Worker }
2153*5e7646d2SAndroid Build Coastguard Worker 
2154*5e7646d2SAndroid Build Coastguard Worker 
2155*5e7646d2SAndroid Build Coastguard Worker /*
2156*5e7646d2SAndroid Build Coastguard Worker  * 'check_defaults()' - Check default option keywords in the PPD file.
2157*5e7646d2SAndroid Build Coastguard Worker  */
2158*5e7646d2SAndroid Build Coastguard Worker 
2159*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Errors found */
check_defaults(ppd_file_t * ppd,int errors,int verbose,int warn)2160*5e7646d2SAndroid Build Coastguard Worker check_defaults(ppd_file_t *ppd,		/* I - PPD file */
2161*5e7646d2SAndroid Build Coastguard Worker 	       int        errors,	/* I - Errors found */
2162*5e7646d2SAndroid Build Coastguard Worker 	       int        verbose,	/* I - Verbosity level */
2163*5e7646d2SAndroid Build Coastguard Worker 	       int        warn)		/* I - Warnings only? */
2164*5e7646d2SAndroid Build Coastguard Worker {
2165*5e7646d2SAndroid Build Coastguard Worker   int		j, k;			/* Looping vars */
2166*5e7646d2SAndroid Build Coastguard Worker   ppd_attr_t	*attr;			/* PPD attribute */
2167*5e7646d2SAndroid Build Coastguard Worker   ppd_option_t	*option;		/* Standard UI option */
2168*5e7646d2SAndroid Build Coastguard Worker   const char	*prefix;		/* WARN/FAIL prefix */
2169*5e7646d2SAndroid Build Coastguard Worker 
2170*5e7646d2SAndroid Build Coastguard Worker 
2171*5e7646d2SAndroid Build Coastguard Worker   prefix = warn ? "  WARN  " : "**FAIL**";
2172*5e7646d2SAndroid Build Coastguard Worker 
2173*5e7646d2SAndroid Build Coastguard Worker   ppdMarkDefaults(ppd);
2174*5e7646d2SAndroid Build Coastguard Worker   if (ppdConflicts(ppd))
2175*5e7646d2SAndroid Build Coastguard Worker   {
2176*5e7646d2SAndroid Build Coastguard Worker     if (!warn && !errors && !verbose)
2177*5e7646d2SAndroid Build Coastguard Worker       _cupsLangPuts(stdout, _(" FAIL"));
2178*5e7646d2SAndroid Build Coastguard Worker 
2179*5e7646d2SAndroid Build Coastguard Worker     if (verbose >= 0)
2180*5e7646d2SAndroid Build Coastguard Worker       _cupsLangPrintf(stdout,
2181*5e7646d2SAndroid Build Coastguard Worker 		      _("      %s  Default choices conflicting."), prefix);
2182*5e7646d2SAndroid Build Coastguard Worker 
2183*5e7646d2SAndroid Build Coastguard Worker     show_conflicts(ppd, prefix);
2184*5e7646d2SAndroid Build Coastguard Worker 
2185*5e7646d2SAndroid Build Coastguard Worker     if (!warn)
2186*5e7646d2SAndroid Build Coastguard Worker       errors ++;
2187*5e7646d2SAndroid Build Coastguard Worker   }
2188*5e7646d2SAndroid Build Coastguard Worker 
2189*5e7646d2SAndroid Build Coastguard Worker   for (j = 0; j < ppd->num_attrs; j ++)
2190*5e7646d2SAndroid Build Coastguard Worker   {
2191*5e7646d2SAndroid Build Coastguard Worker     attr = ppd->attrs[j];
2192*5e7646d2SAndroid Build Coastguard Worker 
2193*5e7646d2SAndroid Build Coastguard Worker     if (!strcmp(attr->name, "DefaultColorSpace") ||
2194*5e7646d2SAndroid Build Coastguard Worker 	!strcmp(attr->name, "DefaultFont") ||
2195*5e7646d2SAndroid Build Coastguard Worker 	!strcmp(attr->name, "DefaultHalftoneType") ||
2196*5e7646d2SAndroid Build Coastguard Worker 	!strcmp(attr->name, "DefaultImageableArea") ||
2197*5e7646d2SAndroid Build Coastguard Worker 	!strcmp(attr->name, "DefaultLeadingEdge") ||
2198*5e7646d2SAndroid Build Coastguard Worker 	!strcmp(attr->name, "DefaultOutputOrder") ||
2199*5e7646d2SAndroid Build Coastguard Worker 	!strcmp(attr->name, "DefaultPaperDimension") ||
2200*5e7646d2SAndroid Build Coastguard Worker 	!strcmp(attr->name, "DefaultResolution") ||
2201*5e7646d2SAndroid Build Coastguard Worker 	!strcmp(attr->name, "DefaultTransfer"))
2202*5e7646d2SAndroid Build Coastguard Worker       continue;
2203*5e7646d2SAndroid Build Coastguard Worker 
2204*5e7646d2SAndroid Build Coastguard Worker     if (!strncmp(attr->name, "Default", 7))
2205*5e7646d2SAndroid Build Coastguard Worker     {
2206*5e7646d2SAndroid Build Coastguard Worker       if ((option = ppdFindOption(ppd, attr->name + 7)) != NULL &&
2207*5e7646d2SAndroid Build Coastguard Worker 	  strcmp(attr->value, "Unknown"))
2208*5e7646d2SAndroid Build Coastguard Worker       {
2209*5e7646d2SAndroid Build Coastguard Worker        /*
2210*5e7646d2SAndroid Build Coastguard Worker 	* Check that the default option value matches a choice...
2211*5e7646d2SAndroid Build Coastguard Worker 	*/
2212*5e7646d2SAndroid Build Coastguard Worker 
2213*5e7646d2SAndroid Build Coastguard Worker 	for (k = 0; k < option->num_choices; k ++)
2214*5e7646d2SAndroid Build Coastguard Worker 	  if (!strcmp(option->choices[k].choice, attr->value))
2215*5e7646d2SAndroid Build Coastguard Worker 	    break;
2216*5e7646d2SAndroid Build Coastguard Worker 
2217*5e7646d2SAndroid Build Coastguard Worker 	if (k >= option->num_choices)
2218*5e7646d2SAndroid Build Coastguard Worker 	{
2219*5e7646d2SAndroid Build Coastguard Worker 	  if (!warn && !errors && !verbose)
2220*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
2221*5e7646d2SAndroid Build Coastguard Worker 
2222*5e7646d2SAndroid Build Coastguard Worker 	  if (verbose >= 0)
2223*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPrintf(stdout,
2224*5e7646d2SAndroid Build Coastguard Worker 			    _("      %s  %s %s does not exist."),
2225*5e7646d2SAndroid Build Coastguard Worker 			    prefix, attr->name, attr->value);
2226*5e7646d2SAndroid Build Coastguard Worker 
2227*5e7646d2SAndroid Build Coastguard Worker           if (!warn)
2228*5e7646d2SAndroid Build Coastguard Worker 	    errors ++;
2229*5e7646d2SAndroid Build Coastguard Worker 	}
2230*5e7646d2SAndroid Build Coastguard Worker       }
2231*5e7646d2SAndroid Build Coastguard Worker     }
2232*5e7646d2SAndroid Build Coastguard Worker   }
2233*5e7646d2SAndroid Build Coastguard Worker 
2234*5e7646d2SAndroid Build Coastguard Worker   return (errors);
2235*5e7646d2SAndroid Build Coastguard Worker }
2236*5e7646d2SAndroid Build Coastguard Worker 
2237*5e7646d2SAndroid Build Coastguard Worker 
2238*5e7646d2SAndroid Build Coastguard Worker /*
2239*5e7646d2SAndroid Build Coastguard Worker  * 'check_duplex()' - Check duplex keywords in the PPD file.
2240*5e7646d2SAndroid Build Coastguard Worker  */
2241*5e7646d2SAndroid Build Coastguard Worker 
2242*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Errors found */
check_duplex(ppd_file_t * ppd,int errors,int verbose,int warn)2243*5e7646d2SAndroid Build Coastguard Worker check_duplex(ppd_file_t *ppd,		/* I - PPD file */
2244*5e7646d2SAndroid Build Coastguard Worker              int        errors,		/* I - Error found */
2245*5e7646d2SAndroid Build Coastguard Worker 	     int        verbose,	/* I - Verbosity level */
2246*5e7646d2SAndroid Build Coastguard Worker              int        warn)		/* I - Warnings only? */
2247*5e7646d2SAndroid Build Coastguard Worker {
2248*5e7646d2SAndroid Build Coastguard Worker   int		i;			/* Looping var */
2249*5e7646d2SAndroid Build Coastguard Worker   ppd_option_t	*option;		/* PPD option */
2250*5e7646d2SAndroid Build Coastguard Worker   ppd_choice_t	*choice;		/* Current choice */
2251*5e7646d2SAndroid Build Coastguard Worker   const char	*prefix;		/* Message prefix */
2252*5e7646d2SAndroid Build Coastguard Worker 
2253*5e7646d2SAndroid Build Coastguard Worker 
2254*5e7646d2SAndroid Build Coastguard Worker   prefix = warn ? "  WARN  " : "**FAIL**";
2255*5e7646d2SAndroid Build Coastguard Worker 
2256*5e7646d2SAndroid Build Coastguard Worker  /*
2257*5e7646d2SAndroid Build Coastguard Worker   * Check for a duplex option, and for standard values...
2258*5e7646d2SAndroid Build Coastguard Worker   */
2259*5e7646d2SAndroid Build Coastguard Worker 
2260*5e7646d2SAndroid Build Coastguard Worker   if ((option = ppdFindOption(ppd, "Duplex")) != NULL)
2261*5e7646d2SAndroid Build Coastguard Worker   {
2262*5e7646d2SAndroid Build Coastguard Worker     if (!ppdFindChoice(option, "None"))
2263*5e7646d2SAndroid Build Coastguard Worker     {
2264*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2265*5e7646d2SAndroid Build Coastguard Worker       {
2266*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
2267*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
2268*5e7646d2SAndroid Build Coastguard Worker 
2269*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2270*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  REQUIRED %s does not define "
2271*5e7646d2SAndroid Build Coastguard Worker 			  "choice None.\n"
2272*5e7646d2SAndroid Build Coastguard Worker 			  "                REF: Page 122, section 5.17"),
2273*5e7646d2SAndroid Build Coastguard Worker 			prefix, option->keyword);
2274*5e7646d2SAndroid Build Coastguard Worker       }
2275*5e7646d2SAndroid Build Coastguard Worker 
2276*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2277*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
2278*5e7646d2SAndroid Build Coastguard Worker     }
2279*5e7646d2SAndroid Build Coastguard Worker 
2280*5e7646d2SAndroid Build Coastguard Worker     for (i = option->num_choices, choice = option->choices;
2281*5e7646d2SAndroid Build Coastguard Worker 	 i > 0;
2282*5e7646d2SAndroid Build Coastguard Worker 	 i --, choice ++)
2283*5e7646d2SAndroid Build Coastguard Worker       if (strcmp(choice->choice, "None") &&
2284*5e7646d2SAndroid Build Coastguard Worker 	  strcmp(choice->choice, "DuplexNoTumble") &&
2285*5e7646d2SAndroid Build Coastguard Worker 	  strcmp(choice->choice, "DuplexTumble") &&
2286*5e7646d2SAndroid Build Coastguard Worker 	  strcmp(choice->choice, "SimplexTumble"))
2287*5e7646d2SAndroid Build Coastguard Worker       {
2288*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
2289*5e7646d2SAndroid Build Coastguard Worker 	{
2290*5e7646d2SAndroid Build Coastguard Worker 	  if (!warn && !errors && !verbose)
2291*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
2292*5e7646d2SAndroid Build Coastguard Worker 
2293*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
2294*5e7646d2SAndroid Build Coastguard Worker 			  _("      %s  Bad %s choice %s.\n"
2295*5e7646d2SAndroid Build Coastguard Worker 			    "                REF: Page 122, section 5.17"),
2296*5e7646d2SAndroid Build Coastguard Worker 			  prefix, option->keyword, choice->choice);
2297*5e7646d2SAndroid Build Coastguard Worker 	}
2298*5e7646d2SAndroid Build Coastguard Worker 
2299*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
2300*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
2301*5e7646d2SAndroid Build Coastguard Worker       }
2302*5e7646d2SAndroid Build Coastguard Worker   }
2303*5e7646d2SAndroid Build Coastguard Worker 
2304*5e7646d2SAndroid Build Coastguard Worker   return (errors);
2305*5e7646d2SAndroid Build Coastguard Worker }
2306*5e7646d2SAndroid Build Coastguard Worker 
2307*5e7646d2SAndroid Build Coastguard Worker 
2308*5e7646d2SAndroid Build Coastguard Worker /*
2309*5e7646d2SAndroid Build Coastguard Worker  * 'check_filters()' - Check filters in the PPD file.
2310*5e7646d2SAndroid Build Coastguard Worker  */
2311*5e7646d2SAndroid Build Coastguard Worker 
2312*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Errors found */
check_filters(ppd_file_t * ppd,const char * root,int errors,int verbose,int warn)2313*5e7646d2SAndroid Build Coastguard Worker check_filters(ppd_file_t *ppd,		/* I - PPD file */
2314*5e7646d2SAndroid Build Coastguard Worker               const char *root,		/* I - Root directory */
2315*5e7646d2SAndroid Build Coastguard Worker 	      int        errors,	/* I - Errors found */
2316*5e7646d2SAndroid Build Coastguard Worker 	      int        verbose,	/* I - Verbosity level */
2317*5e7646d2SAndroid Build Coastguard Worker 	      int        warn)		/* I - Warnings only? */
2318*5e7646d2SAndroid Build Coastguard Worker {
2319*5e7646d2SAndroid Build Coastguard Worker   ppd_attr_t	*attr;			/* PPD attribute */
2320*5e7646d2SAndroid Build Coastguard Worker   const char	*ptr;			/* Pointer into string */
2321*5e7646d2SAndroid Build Coastguard Worker   char		super[16],		/* Super-type for filter */
2322*5e7646d2SAndroid Build Coastguard Worker 		type[256],		/* Type for filter */
2323*5e7646d2SAndroid Build Coastguard Worker 		dstsuper[16],		/* Destination super-type for filter */
2324*5e7646d2SAndroid Build Coastguard Worker 		dsttype[256],		/* Destination type for filter */
2325*5e7646d2SAndroid Build Coastguard Worker 		program[1024],		/* Program/filter name */
2326*5e7646d2SAndroid Build Coastguard Worker 		pathprog[1024];		/* Complete path to program/filter */
2327*5e7646d2SAndroid Build Coastguard Worker   int		cost;			/* Cost of filter */
2328*5e7646d2SAndroid Build Coastguard Worker   const char	*prefix;		/* WARN/FAIL prefix */
2329*5e7646d2SAndroid Build Coastguard Worker   struct stat	fileinfo;		/* File information */
2330*5e7646d2SAndroid Build Coastguard Worker 
2331*5e7646d2SAndroid Build Coastguard Worker 
2332*5e7646d2SAndroid Build Coastguard Worker   prefix = warn ? "  WARN  " : "**FAIL**";
2333*5e7646d2SAndroid Build Coastguard Worker 
2334*5e7646d2SAndroid Build Coastguard Worker  /*
2335*5e7646d2SAndroid Build Coastguard Worker   * cupsFilter
2336*5e7646d2SAndroid Build Coastguard Worker   */
2337*5e7646d2SAndroid Build Coastguard Worker 
2338*5e7646d2SAndroid Build Coastguard Worker   for (attr = ppdFindAttr(ppd, "cupsFilter", NULL);
2339*5e7646d2SAndroid Build Coastguard Worker        attr;
2340*5e7646d2SAndroid Build Coastguard Worker        attr = ppdFindNextAttr(ppd, "cupsFilter", NULL))
2341*5e7646d2SAndroid Build Coastguard Worker   {
2342*5e7646d2SAndroid Build Coastguard Worker     if (strcmp(attr->name, "cupsFilter"))
2343*5e7646d2SAndroid Build Coastguard Worker     {
2344*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2345*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2346*5e7646d2SAndroid Build Coastguard Worker 
2347*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2348*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2349*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Bad spelling of %s - should be %s."),
2350*5e7646d2SAndroid Build Coastguard Worker 			prefix, attr->name, "cupsFilter");
2351*5e7646d2SAndroid Build Coastguard Worker 
2352*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2353*5e7646d2SAndroid Build Coastguard Worker         errors ++;
2354*5e7646d2SAndroid Build Coastguard Worker     }
2355*5e7646d2SAndroid Build Coastguard Worker 
2356*5e7646d2SAndroid Build Coastguard Worker     if (!attr->value ||
2357*5e7646d2SAndroid Build Coastguard Worker         sscanf(attr->value, "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super, type,
2358*5e7646d2SAndroid Build Coastguard Worker                &cost, program) != 4)
2359*5e7646d2SAndroid Build Coastguard Worker     {
2360*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2361*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2362*5e7646d2SAndroid Build Coastguard Worker 
2363*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2364*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2365*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Bad cupsFilter value \"%s\"."),
2366*5e7646d2SAndroid Build Coastguard Worker 			prefix, attr->value);
2367*5e7646d2SAndroid Build Coastguard Worker 
2368*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2369*5e7646d2SAndroid Build Coastguard Worker         errors ++;
2370*5e7646d2SAndroid Build Coastguard Worker 
2371*5e7646d2SAndroid Build Coastguard Worker       continue;
2372*5e7646d2SAndroid Build Coastguard Worker     }
2373*5e7646d2SAndroid Build Coastguard Worker 
2374*5e7646d2SAndroid Build Coastguard Worker     if (!strncmp(program, "maxsize(", 8))
2375*5e7646d2SAndroid Build Coastguard Worker     {
2376*5e7646d2SAndroid Build Coastguard Worker       char	*mptr;			/* Pointer into maxsize(nnnn) program */
2377*5e7646d2SAndroid Build Coastguard Worker 
2378*5e7646d2SAndroid Build Coastguard Worker       strtoll(program + 8, &mptr, 10);
2379*5e7646d2SAndroid Build Coastguard Worker 
2380*5e7646d2SAndroid Build Coastguard Worker       if (*mptr != ')')
2381*5e7646d2SAndroid Build Coastguard Worker       {
2382*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
2383*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
2384*5e7646d2SAndroid Build Coastguard Worker 
2385*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
2386*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
2387*5e7646d2SAndroid Build Coastguard Worker 			  _("      %s  Bad cupsFilter value \"%s\"."),
2388*5e7646d2SAndroid Build Coastguard Worker 			  prefix, attr->value);
2389*5e7646d2SAndroid Build Coastguard Worker 
2390*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
2391*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
2392*5e7646d2SAndroid Build Coastguard Worker 
2393*5e7646d2SAndroid Build Coastguard Worker 	continue;
2394*5e7646d2SAndroid Build Coastguard Worker       }
2395*5e7646d2SAndroid Build Coastguard Worker 
2396*5e7646d2SAndroid Build Coastguard Worker       mptr ++;
2397*5e7646d2SAndroid Build Coastguard Worker       while (_cups_isspace(*mptr))
2398*5e7646d2SAndroid Build Coastguard Worker 	mptr ++;
2399*5e7646d2SAndroid Build Coastguard Worker 
2400*5e7646d2SAndroid Build Coastguard Worker       _cups_strcpy(program, mptr);
2401*5e7646d2SAndroid Build Coastguard Worker     }
2402*5e7646d2SAndroid Build Coastguard Worker 
2403*5e7646d2SAndroid Build Coastguard Worker     if (strcmp(program, "-"))
2404*5e7646d2SAndroid Build Coastguard Worker     {
2405*5e7646d2SAndroid Build Coastguard Worker       if (program[0] == '/')
2406*5e7646d2SAndroid Build Coastguard Worker 	snprintf(pathprog, sizeof(pathprog), "%s%s", root, program);
2407*5e7646d2SAndroid Build Coastguard Worker       else
2408*5e7646d2SAndroid Build Coastguard Worker       {
2409*5e7646d2SAndroid Build Coastguard Worker 	if ((ptr = getenv("CUPS_SERVERBIN")) == NULL)
2410*5e7646d2SAndroid Build Coastguard Worker 	  ptr = CUPS_SERVERBIN;
2411*5e7646d2SAndroid Build Coastguard Worker 
2412*5e7646d2SAndroid Build Coastguard Worker 	if (*ptr == '/' || !*root)
2413*5e7646d2SAndroid Build Coastguard Worker 	  snprintf(pathprog, sizeof(pathprog), "%s%s/filter/%s", root, ptr,
2414*5e7646d2SAndroid Build Coastguard Worker 		   program);
2415*5e7646d2SAndroid Build Coastguard Worker 	else
2416*5e7646d2SAndroid Build Coastguard Worker 	  snprintf(pathprog, sizeof(pathprog), "%s/%s/filter/%s", root, ptr,
2417*5e7646d2SAndroid Build Coastguard Worker 		   program);
2418*5e7646d2SAndroid Build Coastguard Worker       }
2419*5e7646d2SAndroid Build Coastguard Worker 
2420*5e7646d2SAndroid Build Coastguard Worker       if (stat(pathprog, &fileinfo))
2421*5e7646d2SAndroid Build Coastguard Worker       {
2422*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
2423*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
2424*5e7646d2SAndroid Build Coastguard Worker 
2425*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
2426*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout, _("      %s  Missing %s file \"%s\"."),
2427*5e7646d2SAndroid Build Coastguard Worker 	                  prefix, "cupsFilter", pathprog);
2428*5e7646d2SAndroid Build Coastguard Worker 
2429*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
2430*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
2431*5e7646d2SAndroid Build Coastguard Worker       }
2432*5e7646d2SAndroid Build Coastguard Worker       else if (fileinfo.st_uid != 0 ||
2433*5e7646d2SAndroid Build Coastguard Worker                (fileinfo.st_mode & MODE_WRITE) ||
2434*5e7646d2SAndroid Build Coastguard Worker 	       (fileinfo.st_mode & MODE_MASK) != MODE_PROGRAM)
2435*5e7646d2SAndroid Build Coastguard Worker       {
2436*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
2437*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
2438*5e7646d2SAndroid Build Coastguard Worker 
2439*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
2440*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
2441*5e7646d2SAndroid Build Coastguard Worker 	                  _("      %s  Bad permissions on %s file \"%s\"."),
2442*5e7646d2SAndroid Build Coastguard Worker 			  prefix, "cupsFilter", pathprog);
2443*5e7646d2SAndroid Build Coastguard Worker 
2444*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
2445*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
2446*5e7646d2SAndroid Build Coastguard Worker       }
2447*5e7646d2SAndroid Build Coastguard Worker       else
2448*5e7646d2SAndroid Build Coastguard Worker         errors = valid_path("cupsFilter", pathprog, errors, verbose, warn);
2449*5e7646d2SAndroid Build Coastguard Worker     }
2450*5e7646d2SAndroid Build Coastguard Worker   }
2451*5e7646d2SAndroid Build Coastguard Worker 
2452*5e7646d2SAndroid Build Coastguard Worker  /*
2453*5e7646d2SAndroid Build Coastguard Worker   * cupsFilter2
2454*5e7646d2SAndroid Build Coastguard Worker   */
2455*5e7646d2SAndroid Build Coastguard Worker 
2456*5e7646d2SAndroid Build Coastguard Worker   for (attr = ppdFindAttr(ppd, "cupsFilter2", NULL);
2457*5e7646d2SAndroid Build Coastguard Worker        attr;
2458*5e7646d2SAndroid Build Coastguard Worker        attr = ppdFindNextAttr(ppd, "cupsFilter2", NULL))
2459*5e7646d2SAndroid Build Coastguard Worker   {
2460*5e7646d2SAndroid Build Coastguard Worker     if (strcmp(attr->name, "cupsFilter2"))
2461*5e7646d2SAndroid Build Coastguard Worker     {
2462*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2463*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2464*5e7646d2SAndroid Build Coastguard Worker 
2465*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2466*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2467*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Bad spelling of %s - should be %s."),
2468*5e7646d2SAndroid Build Coastguard Worker 			prefix, attr->name, "cupsFilter2");
2469*5e7646d2SAndroid Build Coastguard Worker 
2470*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2471*5e7646d2SAndroid Build Coastguard Worker         errors ++;
2472*5e7646d2SAndroid Build Coastguard Worker     }
2473*5e7646d2SAndroid Build Coastguard Worker 
2474*5e7646d2SAndroid Build Coastguard Worker     if (!attr->value ||
2475*5e7646d2SAndroid Build Coastguard Worker 	sscanf(attr->value, "%15[^/]/%255s%*[ \t]%15[^/]/%255s%d%*[ \t]%1023[^\n]",
2476*5e7646d2SAndroid Build Coastguard Worker 	       super, type, dstsuper, dsttype, &cost, program) != 6)
2477*5e7646d2SAndroid Build Coastguard Worker     {
2478*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2479*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2480*5e7646d2SAndroid Build Coastguard Worker 
2481*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2482*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2483*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Bad cupsFilter2 value \"%s\"."),
2484*5e7646d2SAndroid Build Coastguard Worker 			prefix, attr->value);
2485*5e7646d2SAndroid Build Coastguard Worker 
2486*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2487*5e7646d2SAndroid Build Coastguard Worker         errors ++;
2488*5e7646d2SAndroid Build Coastguard Worker 
2489*5e7646d2SAndroid Build Coastguard Worker       continue;
2490*5e7646d2SAndroid Build Coastguard Worker     }
2491*5e7646d2SAndroid Build Coastguard Worker 
2492*5e7646d2SAndroid Build Coastguard Worker     if (!strncmp(program, "maxsize(", 8))
2493*5e7646d2SAndroid Build Coastguard Worker     {
2494*5e7646d2SAndroid Build Coastguard Worker       char	*mptr;			/* Pointer into maxsize(nnnn) program */
2495*5e7646d2SAndroid Build Coastguard Worker 
2496*5e7646d2SAndroid Build Coastguard Worker       strtoll(program + 8, &mptr, 10);
2497*5e7646d2SAndroid Build Coastguard Worker 
2498*5e7646d2SAndroid Build Coastguard Worker       if (*mptr != ')')
2499*5e7646d2SAndroid Build Coastguard Worker       {
2500*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
2501*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
2502*5e7646d2SAndroid Build Coastguard Worker 
2503*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
2504*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
2505*5e7646d2SAndroid Build Coastguard Worker 			  _("      %s  Bad cupsFilter2 value \"%s\"."),
2506*5e7646d2SAndroid Build Coastguard Worker 			  prefix, attr->value);
2507*5e7646d2SAndroid Build Coastguard Worker 
2508*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
2509*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
2510*5e7646d2SAndroid Build Coastguard Worker 
2511*5e7646d2SAndroid Build Coastguard Worker 	continue;
2512*5e7646d2SAndroid Build Coastguard Worker       }
2513*5e7646d2SAndroid Build Coastguard Worker 
2514*5e7646d2SAndroid Build Coastguard Worker       mptr ++;
2515*5e7646d2SAndroid Build Coastguard Worker       while (_cups_isspace(*mptr))
2516*5e7646d2SAndroid Build Coastguard Worker 	mptr ++;
2517*5e7646d2SAndroid Build Coastguard Worker 
2518*5e7646d2SAndroid Build Coastguard Worker       _cups_strcpy(program, mptr);
2519*5e7646d2SAndroid Build Coastguard Worker     }
2520*5e7646d2SAndroid Build Coastguard Worker 
2521*5e7646d2SAndroid Build Coastguard Worker     if (strcmp(program, "-"))
2522*5e7646d2SAndroid Build Coastguard Worker     {
2523*5e7646d2SAndroid Build Coastguard Worker       if (strncmp(program, "maxsize(", 8) &&
2524*5e7646d2SAndroid Build Coastguard Worker           (ptr = strchr(program + 8, ')')) != NULL)
2525*5e7646d2SAndroid Build Coastguard Worker       {
2526*5e7646d2SAndroid Build Coastguard Worker 	ptr ++;
2527*5e7646d2SAndroid Build Coastguard Worker 	while (_cups_isspace(*ptr))
2528*5e7646d2SAndroid Build Coastguard Worker 	  ptr ++;
2529*5e7646d2SAndroid Build Coastguard Worker 
2530*5e7646d2SAndroid Build Coastguard Worker 	_cups_strcpy(program, ptr);
2531*5e7646d2SAndroid Build Coastguard Worker       }
2532*5e7646d2SAndroid Build Coastguard Worker 
2533*5e7646d2SAndroid Build Coastguard Worker       if (program[0] == '/')
2534*5e7646d2SAndroid Build Coastguard Worker 	snprintf(pathprog, sizeof(pathprog), "%s%s", root, program);
2535*5e7646d2SAndroid Build Coastguard Worker       else
2536*5e7646d2SAndroid Build Coastguard Worker       {
2537*5e7646d2SAndroid Build Coastguard Worker 	if ((ptr = getenv("CUPS_SERVERBIN")) == NULL)
2538*5e7646d2SAndroid Build Coastguard Worker 	  ptr = CUPS_SERVERBIN;
2539*5e7646d2SAndroid Build Coastguard Worker 
2540*5e7646d2SAndroid Build Coastguard Worker 	if (*ptr == '/' || !*root)
2541*5e7646d2SAndroid Build Coastguard Worker 	  snprintf(pathprog, sizeof(pathprog), "%s%s/filter/%s", root, ptr,
2542*5e7646d2SAndroid Build Coastguard Worker 		   program);
2543*5e7646d2SAndroid Build Coastguard Worker 	else
2544*5e7646d2SAndroid Build Coastguard Worker 	  snprintf(pathprog, sizeof(pathprog), "%s/%s/filter/%s", root, ptr,
2545*5e7646d2SAndroid Build Coastguard Worker 		   program);
2546*5e7646d2SAndroid Build Coastguard Worker       }
2547*5e7646d2SAndroid Build Coastguard Worker 
2548*5e7646d2SAndroid Build Coastguard Worker       if (stat(pathprog, &fileinfo))
2549*5e7646d2SAndroid Build Coastguard Worker       {
2550*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
2551*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
2552*5e7646d2SAndroid Build Coastguard Worker 
2553*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
2554*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout, _("      %s  Missing %s file \"%s\"."),
2555*5e7646d2SAndroid Build Coastguard Worker 	                  prefix, "cupsFilter2", pathprog);
2556*5e7646d2SAndroid Build Coastguard Worker 
2557*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
2558*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
2559*5e7646d2SAndroid Build Coastguard Worker       }
2560*5e7646d2SAndroid Build Coastguard Worker       else if (fileinfo.st_uid != 0 ||
2561*5e7646d2SAndroid Build Coastguard Worker                (fileinfo.st_mode & MODE_WRITE) ||
2562*5e7646d2SAndroid Build Coastguard Worker 	       (fileinfo.st_mode & MODE_MASK) != MODE_PROGRAM)
2563*5e7646d2SAndroid Build Coastguard Worker       {
2564*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
2565*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
2566*5e7646d2SAndroid Build Coastguard Worker 
2567*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
2568*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
2569*5e7646d2SAndroid Build Coastguard Worker 	                  _("      %s  Bad permissions on %s file \"%s\"."),
2570*5e7646d2SAndroid Build Coastguard Worker 			  prefix, "cupsFilter2", pathprog);
2571*5e7646d2SAndroid Build Coastguard Worker 
2572*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
2573*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
2574*5e7646d2SAndroid Build Coastguard Worker       }
2575*5e7646d2SAndroid Build Coastguard Worker       else
2576*5e7646d2SAndroid Build Coastguard Worker         errors = valid_path("cupsFilter2", pathprog, errors, verbose, warn);
2577*5e7646d2SAndroid Build Coastguard Worker     }
2578*5e7646d2SAndroid Build Coastguard Worker   }
2579*5e7646d2SAndroid Build Coastguard Worker 
2580*5e7646d2SAndroid Build Coastguard Worker  /*
2581*5e7646d2SAndroid Build Coastguard Worker   * cupsPreFilter
2582*5e7646d2SAndroid Build Coastguard Worker   */
2583*5e7646d2SAndroid Build Coastguard Worker 
2584*5e7646d2SAndroid Build Coastguard Worker   for (attr = ppdFindAttr(ppd, "cupsPreFilter", NULL);
2585*5e7646d2SAndroid Build Coastguard Worker        attr;
2586*5e7646d2SAndroid Build Coastguard Worker        attr = ppdFindNextAttr(ppd, "cupsPreFilter", NULL))
2587*5e7646d2SAndroid Build Coastguard Worker   {
2588*5e7646d2SAndroid Build Coastguard Worker     if (strcmp(attr->name, "cupsPreFilter"))
2589*5e7646d2SAndroid Build Coastguard Worker     {
2590*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2591*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2592*5e7646d2SAndroid Build Coastguard Worker 
2593*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2594*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2595*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Bad spelling of %s - should be %s."),
2596*5e7646d2SAndroid Build Coastguard Worker 			prefix, attr->name, "cupsPreFilter");
2597*5e7646d2SAndroid Build Coastguard Worker 
2598*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2599*5e7646d2SAndroid Build Coastguard Worker         errors ++;
2600*5e7646d2SAndroid Build Coastguard Worker     }
2601*5e7646d2SAndroid Build Coastguard Worker 
2602*5e7646d2SAndroid Build Coastguard Worker     if (!attr->value ||
2603*5e7646d2SAndroid Build Coastguard Worker 	sscanf(attr->value, "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super, type,
2604*5e7646d2SAndroid Build Coastguard Worker 	       &cost, program) != 4)
2605*5e7646d2SAndroid Build Coastguard Worker     {
2606*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2607*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2608*5e7646d2SAndroid Build Coastguard Worker 
2609*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2610*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2611*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Bad cupsPreFilter value \"%s\"."),
2612*5e7646d2SAndroid Build Coastguard Worker 			prefix, attr->value ? attr->value : "");
2613*5e7646d2SAndroid Build Coastguard Worker 
2614*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2615*5e7646d2SAndroid Build Coastguard Worker         errors ++;
2616*5e7646d2SAndroid Build Coastguard Worker     }
2617*5e7646d2SAndroid Build Coastguard Worker     else if (strcmp(program, "-"))
2618*5e7646d2SAndroid Build Coastguard Worker     {
2619*5e7646d2SAndroid Build Coastguard Worker       if (program[0] == '/')
2620*5e7646d2SAndroid Build Coastguard Worker 	snprintf(pathprog, sizeof(pathprog), "%s%s", root, program);
2621*5e7646d2SAndroid Build Coastguard Worker       else
2622*5e7646d2SAndroid Build Coastguard Worker       {
2623*5e7646d2SAndroid Build Coastguard Worker 	if ((ptr = getenv("CUPS_SERVERBIN")) == NULL)
2624*5e7646d2SAndroid Build Coastguard Worker 	  ptr = CUPS_SERVERBIN;
2625*5e7646d2SAndroid Build Coastguard Worker 
2626*5e7646d2SAndroid Build Coastguard Worker 	if (*ptr == '/' || !*root)
2627*5e7646d2SAndroid Build Coastguard Worker 	  snprintf(pathprog, sizeof(pathprog), "%s%s/filter/%s", root, ptr,
2628*5e7646d2SAndroid Build Coastguard Worker 		   program);
2629*5e7646d2SAndroid Build Coastguard Worker 	else
2630*5e7646d2SAndroid Build Coastguard Worker 	  snprintf(pathprog, sizeof(pathprog), "%s/%s/filter/%s", root, ptr,
2631*5e7646d2SAndroid Build Coastguard Worker 		   program);
2632*5e7646d2SAndroid Build Coastguard Worker       }
2633*5e7646d2SAndroid Build Coastguard Worker 
2634*5e7646d2SAndroid Build Coastguard Worker       if (stat(pathprog, &fileinfo))
2635*5e7646d2SAndroid Build Coastguard Worker       {
2636*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
2637*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
2638*5e7646d2SAndroid Build Coastguard Worker 
2639*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
2640*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout, _("      %s  Missing %s file \"%s\"."),
2641*5e7646d2SAndroid Build Coastguard Worker 	                  prefix, "cupsPreFilter", pathprog);
2642*5e7646d2SAndroid Build Coastguard Worker 
2643*5e7646d2SAndroid Build Coastguard Worker         if (!warn)
2644*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
2645*5e7646d2SAndroid Build Coastguard Worker       }
2646*5e7646d2SAndroid Build Coastguard Worker       else if (fileinfo.st_uid != 0 ||
2647*5e7646d2SAndroid Build Coastguard Worker                (fileinfo.st_mode & MODE_WRITE) ||
2648*5e7646d2SAndroid Build Coastguard Worker 	       (fileinfo.st_mode & MODE_MASK) != MODE_PROGRAM)
2649*5e7646d2SAndroid Build Coastguard Worker       {
2650*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
2651*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
2652*5e7646d2SAndroid Build Coastguard Worker 
2653*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
2654*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
2655*5e7646d2SAndroid Build Coastguard Worker 	                  _("      %s  Bad permissions on %s file \"%s\"."),
2656*5e7646d2SAndroid Build Coastguard Worker 			  prefix, "cupsPreFilter", pathprog);
2657*5e7646d2SAndroid Build Coastguard Worker 
2658*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
2659*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
2660*5e7646d2SAndroid Build Coastguard Worker       }
2661*5e7646d2SAndroid Build Coastguard Worker       else
2662*5e7646d2SAndroid Build Coastguard Worker         errors = valid_path("cupsPreFilter", pathprog, errors, verbose, warn);
2663*5e7646d2SAndroid Build Coastguard Worker     }
2664*5e7646d2SAndroid Build Coastguard Worker   }
2665*5e7646d2SAndroid Build Coastguard Worker 
2666*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
2667*5e7646d2SAndroid Build Coastguard Worker  /*
2668*5e7646d2SAndroid Build Coastguard Worker   * APDialogExtension
2669*5e7646d2SAndroid Build Coastguard Worker   */
2670*5e7646d2SAndroid Build Coastguard Worker 
2671*5e7646d2SAndroid Build Coastguard Worker   for (attr = ppdFindAttr(ppd, "APDialogExtension", NULL);
2672*5e7646d2SAndroid Build Coastguard Worker        attr != NULL;
2673*5e7646d2SAndroid Build Coastguard Worker        attr = ppdFindNextAttr(ppd, "APDialogExtension", NULL))
2674*5e7646d2SAndroid Build Coastguard Worker   {
2675*5e7646d2SAndroid Build Coastguard Worker     if (strcmp(attr->name, "APDialogExtension"))
2676*5e7646d2SAndroid Build Coastguard Worker     {
2677*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2678*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2679*5e7646d2SAndroid Build Coastguard Worker 
2680*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2681*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2682*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Bad spelling of %s - should be %s."),
2683*5e7646d2SAndroid Build Coastguard Worker 			prefix, attr->name, "APDialogExtension");
2684*5e7646d2SAndroid Build Coastguard Worker 
2685*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2686*5e7646d2SAndroid Build Coastguard Worker         errors ++;
2687*5e7646d2SAndroid Build Coastguard Worker     }
2688*5e7646d2SAndroid Build Coastguard Worker 
2689*5e7646d2SAndroid Build Coastguard Worker     snprintf(pathprog, sizeof(pathprog), "%s%s", root,
2690*5e7646d2SAndroid Build Coastguard Worker              attr->value ? attr->value : "(null)");
2691*5e7646d2SAndroid Build Coastguard Worker 
2692*5e7646d2SAndroid Build Coastguard Worker     if (!attr->value || stat(pathprog, &fileinfo))
2693*5e7646d2SAndroid Build Coastguard Worker     {
2694*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2695*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2696*5e7646d2SAndroid Build Coastguard Worker 
2697*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2698*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, _("      %s  Missing %s file \"%s\"."),
2699*5e7646d2SAndroid Build Coastguard Worker 			prefix, "APDialogExtension", pathprog);
2700*5e7646d2SAndroid Build Coastguard Worker 
2701*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2702*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
2703*5e7646d2SAndroid Build Coastguard Worker     }
2704*5e7646d2SAndroid Build Coastguard Worker     else if (fileinfo.st_uid != 0 ||
2705*5e7646d2SAndroid Build Coastguard Worker 	     (fileinfo.st_mode & MODE_WRITE) ||
2706*5e7646d2SAndroid Build Coastguard Worker 	     (fileinfo.st_mode & MODE_MASK) != MODE_DIRECTORY)
2707*5e7646d2SAndroid Build Coastguard Worker     {
2708*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2709*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2710*5e7646d2SAndroid Build Coastguard Worker 
2711*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2712*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2713*5e7646d2SAndroid Build Coastguard Worker 	                _("      %s  Bad permissions on %s file \"%s\"."),
2714*5e7646d2SAndroid Build Coastguard Worker 			prefix, "APDialogExtension", pathprog);
2715*5e7646d2SAndroid Build Coastguard Worker 
2716*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2717*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
2718*5e7646d2SAndroid Build Coastguard Worker     }
2719*5e7646d2SAndroid Build Coastguard Worker     else
2720*5e7646d2SAndroid Build Coastguard Worker       errors = valid_path("APDialogExtension", pathprog, errors, verbose,
2721*5e7646d2SAndroid Build Coastguard Worker                           warn);
2722*5e7646d2SAndroid Build Coastguard Worker   }
2723*5e7646d2SAndroid Build Coastguard Worker 
2724*5e7646d2SAndroid Build Coastguard Worker  /*
2725*5e7646d2SAndroid Build Coastguard Worker   * APPrinterIconPath
2726*5e7646d2SAndroid Build Coastguard Worker   */
2727*5e7646d2SAndroid Build Coastguard Worker 
2728*5e7646d2SAndroid Build Coastguard Worker   if ((attr = ppdFindAttr(ppd, "APPrinterIconPath", NULL)) != NULL)
2729*5e7646d2SAndroid Build Coastguard Worker   {
2730*5e7646d2SAndroid Build Coastguard Worker     if (strcmp(attr->name, "APPrinterIconPath"))
2731*5e7646d2SAndroid Build Coastguard Worker     {
2732*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2733*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2734*5e7646d2SAndroid Build Coastguard Worker 
2735*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2736*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2737*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Bad spelling of %s - should be %s."),
2738*5e7646d2SAndroid Build Coastguard Worker 			prefix, attr->name, "APPrinterIconPath");
2739*5e7646d2SAndroid Build Coastguard Worker 
2740*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2741*5e7646d2SAndroid Build Coastguard Worker         errors ++;
2742*5e7646d2SAndroid Build Coastguard Worker     }
2743*5e7646d2SAndroid Build Coastguard Worker 
2744*5e7646d2SAndroid Build Coastguard Worker     snprintf(pathprog, sizeof(pathprog), "%s%s", root,
2745*5e7646d2SAndroid Build Coastguard Worker              attr->value ? attr->value : "(null)");
2746*5e7646d2SAndroid Build Coastguard Worker 
2747*5e7646d2SAndroid Build Coastguard Worker     if (!attr->value || stat(pathprog, &fileinfo))
2748*5e7646d2SAndroid Build Coastguard Worker     {
2749*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2750*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2751*5e7646d2SAndroid Build Coastguard Worker 
2752*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2753*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, _("      %s  Missing %s file \"%s\"."),
2754*5e7646d2SAndroid Build Coastguard Worker 			prefix, "APPrinterIconPath", pathprog);
2755*5e7646d2SAndroid Build Coastguard Worker 
2756*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2757*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
2758*5e7646d2SAndroid Build Coastguard Worker     }
2759*5e7646d2SAndroid Build Coastguard Worker     else if (fileinfo.st_uid != 0 ||
2760*5e7646d2SAndroid Build Coastguard Worker 	     (fileinfo.st_mode & MODE_WRITE) ||
2761*5e7646d2SAndroid Build Coastguard Worker 	     (fileinfo.st_mode & MODE_MASK) != MODE_DATAFILE)
2762*5e7646d2SAndroid Build Coastguard Worker     {
2763*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2764*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2765*5e7646d2SAndroid Build Coastguard Worker 
2766*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2767*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2768*5e7646d2SAndroid Build Coastguard Worker 	                _("      %s  Bad permissions on %s file \"%s\"."),
2769*5e7646d2SAndroid Build Coastguard Worker 			prefix, "APPrinterIconPath", pathprog);
2770*5e7646d2SAndroid Build Coastguard Worker 
2771*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2772*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
2773*5e7646d2SAndroid Build Coastguard Worker     }
2774*5e7646d2SAndroid Build Coastguard Worker     else
2775*5e7646d2SAndroid Build Coastguard Worker       errors = valid_path("APPrinterIconPath", pathprog, errors, verbose,
2776*5e7646d2SAndroid Build Coastguard Worker                           warn);
2777*5e7646d2SAndroid Build Coastguard Worker   }
2778*5e7646d2SAndroid Build Coastguard Worker 
2779*5e7646d2SAndroid Build Coastguard Worker  /*
2780*5e7646d2SAndroid Build Coastguard Worker   * APPrinterLowInkTool
2781*5e7646d2SAndroid Build Coastguard Worker   */
2782*5e7646d2SAndroid Build Coastguard Worker 
2783*5e7646d2SAndroid Build Coastguard Worker   if ((attr = ppdFindAttr(ppd, "APPrinterLowInkTool", NULL)) != NULL)
2784*5e7646d2SAndroid Build Coastguard Worker   {
2785*5e7646d2SAndroid Build Coastguard Worker     if (strcmp(attr->name, "APPrinterLowInkTool"))
2786*5e7646d2SAndroid Build Coastguard Worker     {
2787*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2788*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2789*5e7646d2SAndroid Build Coastguard Worker 
2790*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2791*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2792*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Bad spelling of %s - should be %s."),
2793*5e7646d2SAndroid Build Coastguard Worker 			prefix, attr->name, "APPrinterLowInkTool");
2794*5e7646d2SAndroid Build Coastguard Worker 
2795*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2796*5e7646d2SAndroid Build Coastguard Worker         errors ++;
2797*5e7646d2SAndroid Build Coastguard Worker     }
2798*5e7646d2SAndroid Build Coastguard Worker 
2799*5e7646d2SAndroid Build Coastguard Worker     snprintf(pathprog, sizeof(pathprog), "%s%s", root,
2800*5e7646d2SAndroid Build Coastguard Worker              attr->value ? attr->value : "(null)");
2801*5e7646d2SAndroid Build Coastguard Worker 
2802*5e7646d2SAndroid Build Coastguard Worker     if (!attr->value || stat(pathprog, &fileinfo))
2803*5e7646d2SAndroid Build Coastguard Worker     {
2804*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2805*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2806*5e7646d2SAndroid Build Coastguard Worker 
2807*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2808*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, _("      %s  Missing %s file \"%s\"."),
2809*5e7646d2SAndroid Build Coastguard Worker 			prefix, "APPrinterLowInkTool", pathprog);
2810*5e7646d2SAndroid Build Coastguard Worker 
2811*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2812*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
2813*5e7646d2SAndroid Build Coastguard Worker     }
2814*5e7646d2SAndroid Build Coastguard Worker     else if (fileinfo.st_uid != 0 ||
2815*5e7646d2SAndroid Build Coastguard Worker 	     (fileinfo.st_mode & MODE_WRITE) ||
2816*5e7646d2SAndroid Build Coastguard Worker 	     (fileinfo.st_mode & MODE_MASK) != MODE_DIRECTORY)
2817*5e7646d2SAndroid Build Coastguard Worker     {
2818*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2819*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2820*5e7646d2SAndroid Build Coastguard Worker 
2821*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2822*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2823*5e7646d2SAndroid Build Coastguard Worker 	                _("      %s  Bad permissions on %s file \"%s\"."),
2824*5e7646d2SAndroid Build Coastguard Worker 			prefix, "APPrinterLowInkTool", pathprog);
2825*5e7646d2SAndroid Build Coastguard Worker 
2826*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2827*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
2828*5e7646d2SAndroid Build Coastguard Worker     }
2829*5e7646d2SAndroid Build Coastguard Worker     else
2830*5e7646d2SAndroid Build Coastguard Worker       errors = valid_path("APPrinterLowInkTool", pathprog, errors, verbose,
2831*5e7646d2SAndroid Build Coastguard Worker                           warn);
2832*5e7646d2SAndroid Build Coastguard Worker   }
2833*5e7646d2SAndroid Build Coastguard Worker 
2834*5e7646d2SAndroid Build Coastguard Worker  /*
2835*5e7646d2SAndroid Build Coastguard Worker   * APPrinterUtilityPath
2836*5e7646d2SAndroid Build Coastguard Worker   */
2837*5e7646d2SAndroid Build Coastguard Worker 
2838*5e7646d2SAndroid Build Coastguard Worker   if ((attr = ppdFindAttr(ppd, "APPrinterUtilityPath", NULL)) != NULL)
2839*5e7646d2SAndroid Build Coastguard Worker   {
2840*5e7646d2SAndroid Build Coastguard Worker     if (strcmp(attr->name, "APPrinterUtilityPath"))
2841*5e7646d2SAndroid Build Coastguard Worker     {
2842*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2843*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2844*5e7646d2SAndroid Build Coastguard Worker 
2845*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2846*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2847*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Bad spelling of %s - should be %s."),
2848*5e7646d2SAndroid Build Coastguard Worker 			prefix, attr->name, "APPrinterUtilityPath");
2849*5e7646d2SAndroid Build Coastguard Worker 
2850*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2851*5e7646d2SAndroid Build Coastguard Worker         errors ++;
2852*5e7646d2SAndroid Build Coastguard Worker     }
2853*5e7646d2SAndroid Build Coastguard Worker 
2854*5e7646d2SAndroid Build Coastguard Worker     snprintf(pathprog, sizeof(pathprog), "%s%s", root,
2855*5e7646d2SAndroid Build Coastguard Worker              attr->value ? attr->value : "(null)");
2856*5e7646d2SAndroid Build Coastguard Worker 
2857*5e7646d2SAndroid Build Coastguard Worker     if (!attr->value || stat(pathprog, &fileinfo))
2858*5e7646d2SAndroid Build Coastguard Worker     {
2859*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2860*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2861*5e7646d2SAndroid Build Coastguard Worker 
2862*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2863*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, _("      %s  Missing %s file \"%s\"."),
2864*5e7646d2SAndroid Build Coastguard Worker 			prefix, "APPrinterUtilityPath", pathprog);
2865*5e7646d2SAndroid Build Coastguard Worker 
2866*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2867*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
2868*5e7646d2SAndroid Build Coastguard Worker     }
2869*5e7646d2SAndroid Build Coastguard Worker     else if (fileinfo.st_uid != 0 ||
2870*5e7646d2SAndroid Build Coastguard Worker 	     (fileinfo.st_mode & MODE_WRITE) ||
2871*5e7646d2SAndroid Build Coastguard Worker 	     (fileinfo.st_mode & MODE_MASK) != MODE_DIRECTORY)
2872*5e7646d2SAndroid Build Coastguard Worker     {
2873*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2874*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2875*5e7646d2SAndroid Build Coastguard Worker 
2876*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2877*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2878*5e7646d2SAndroid Build Coastguard Worker 	                _("      %s  Bad permissions on %s file \"%s\"."),
2879*5e7646d2SAndroid Build Coastguard Worker 			prefix, "APPrinterUtilityPath", pathprog);
2880*5e7646d2SAndroid Build Coastguard Worker 
2881*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2882*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
2883*5e7646d2SAndroid Build Coastguard Worker     }
2884*5e7646d2SAndroid Build Coastguard Worker     else
2885*5e7646d2SAndroid Build Coastguard Worker       errors = valid_path("APPrinterUtilityPath", pathprog, errors, verbose,
2886*5e7646d2SAndroid Build Coastguard Worker                           warn);
2887*5e7646d2SAndroid Build Coastguard Worker   }
2888*5e7646d2SAndroid Build Coastguard Worker 
2889*5e7646d2SAndroid Build Coastguard Worker  /*
2890*5e7646d2SAndroid Build Coastguard Worker   * APScanAppBundleID and APScanAppPath
2891*5e7646d2SAndroid Build Coastguard Worker   */
2892*5e7646d2SAndroid Build Coastguard Worker 
2893*5e7646d2SAndroid Build Coastguard Worker   if ((attr = ppdFindAttr(ppd, "APScanAppPath", NULL)) != NULL)
2894*5e7646d2SAndroid Build Coastguard Worker   {
2895*5e7646d2SAndroid Build Coastguard Worker     if (strcmp(attr->name, "APScanAppPath"))
2896*5e7646d2SAndroid Build Coastguard Worker     {
2897*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2898*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2899*5e7646d2SAndroid Build Coastguard Worker 
2900*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2901*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2902*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Bad spelling of %s - should be %s."),
2903*5e7646d2SAndroid Build Coastguard Worker 			prefix, attr->name, "APScanAppPath");
2904*5e7646d2SAndroid Build Coastguard Worker 
2905*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2906*5e7646d2SAndroid Build Coastguard Worker         errors ++;
2907*5e7646d2SAndroid Build Coastguard Worker     }
2908*5e7646d2SAndroid Build Coastguard Worker 
2909*5e7646d2SAndroid Build Coastguard Worker     if (!attr->value || stat(attr->value, &fileinfo))
2910*5e7646d2SAndroid Build Coastguard Worker     {
2911*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2912*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2913*5e7646d2SAndroid Build Coastguard Worker 
2914*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2915*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, _("      %s  Missing %s file \"%s\"."),
2916*5e7646d2SAndroid Build Coastguard Worker 			prefix, "APScanAppPath",
2917*5e7646d2SAndroid Build Coastguard Worker 			attr->value ? attr->value : "<NULL>");
2918*5e7646d2SAndroid Build Coastguard Worker 
2919*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2920*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
2921*5e7646d2SAndroid Build Coastguard Worker     }
2922*5e7646d2SAndroid Build Coastguard Worker     else if (fileinfo.st_uid != 0 ||
2923*5e7646d2SAndroid Build Coastguard Worker 	     (fileinfo.st_mode & MODE_WRITE) ||
2924*5e7646d2SAndroid Build Coastguard Worker 	     (fileinfo.st_mode & MODE_MASK) != MODE_DIRECTORY)
2925*5e7646d2SAndroid Build Coastguard Worker     {
2926*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2927*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2928*5e7646d2SAndroid Build Coastguard Worker 
2929*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2930*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
2931*5e7646d2SAndroid Build Coastguard Worker 	                _("      %s  Bad permissions on %s file \"%s\"."),
2932*5e7646d2SAndroid Build Coastguard Worker 			prefix, "APScanAppPath", attr->value);
2933*5e7646d2SAndroid Build Coastguard Worker 
2934*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2935*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
2936*5e7646d2SAndroid Build Coastguard Worker     }
2937*5e7646d2SAndroid Build Coastguard Worker     else
2938*5e7646d2SAndroid Build Coastguard Worker       errors = valid_path("APScanAppPath", attr->value, errors, verbose,
2939*5e7646d2SAndroid Build Coastguard Worker                           warn);
2940*5e7646d2SAndroid Build Coastguard Worker 
2941*5e7646d2SAndroid Build Coastguard Worker     if (ppdFindAttr(ppd, "APScanAppBundleID", NULL))
2942*5e7646d2SAndroid Build Coastguard Worker     {
2943*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
2944*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
2945*5e7646d2SAndroid Build Coastguard Worker 
2946*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
2947*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, _("      %s  Cannot provide both "
2948*5e7646d2SAndroid Build Coastguard Worker 				  "APScanAppPath and APScanAppBundleID."),
2949*5e7646d2SAndroid Build Coastguard Worker 			prefix);
2950*5e7646d2SAndroid Build Coastguard Worker 
2951*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
2952*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
2953*5e7646d2SAndroid Build Coastguard Worker     }
2954*5e7646d2SAndroid Build Coastguard Worker   }
2955*5e7646d2SAndroid Build Coastguard Worker #endif	/* __APPLE__ */
2956*5e7646d2SAndroid Build Coastguard Worker 
2957*5e7646d2SAndroid Build Coastguard Worker   return (errors);
2958*5e7646d2SAndroid Build Coastguard Worker }
2959*5e7646d2SAndroid Build Coastguard Worker 
2960*5e7646d2SAndroid Build Coastguard Worker 
2961*5e7646d2SAndroid Build Coastguard Worker /*
2962*5e7646d2SAndroid Build Coastguard Worker  * 'check_profiles()' - Check ICC color profiles in the PPD file.
2963*5e7646d2SAndroid Build Coastguard Worker  */
2964*5e7646d2SAndroid Build Coastguard Worker 
2965*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Errors found */
check_profiles(ppd_file_t * ppd,const char * root,int errors,int verbose,int warn)2966*5e7646d2SAndroid Build Coastguard Worker check_profiles(ppd_file_t *ppd,		/* I - PPD file */
2967*5e7646d2SAndroid Build Coastguard Worker                const char *root,	/* I - Root directory */
2968*5e7646d2SAndroid Build Coastguard Worker 	       int        errors,	/* I - Errors found */
2969*5e7646d2SAndroid Build Coastguard Worker 	       int        verbose,	/* I - Verbosity level */
2970*5e7646d2SAndroid Build Coastguard Worker 	       int        warn)		/* I - Warnings only? */
2971*5e7646d2SAndroid Build Coastguard Worker {
2972*5e7646d2SAndroid Build Coastguard Worker   int		i;			/* Looping var */
2973*5e7646d2SAndroid Build Coastguard Worker   ppd_attr_t	*attr;			/* PPD attribute */
2974*5e7646d2SAndroid Build Coastguard Worker   const char	*ptr;			/* Pointer into string */
2975*5e7646d2SAndroid Build Coastguard Worker   const char	*prefix;		/* WARN/FAIL prefix */
2976*5e7646d2SAndroid Build Coastguard Worker   char		filename[1024];		/* Profile filename */
2977*5e7646d2SAndroid Build Coastguard Worker   struct stat	fileinfo;		/* File information */
2978*5e7646d2SAndroid Build Coastguard Worker   int		num_profiles = 0;	/* Number of profiles */
2979*5e7646d2SAndroid Build Coastguard Worker   unsigned	hash,			/* Current hash value */
2980*5e7646d2SAndroid Build Coastguard Worker 		hashes[1000];		/* Hash values of profile names */
2981*5e7646d2SAndroid Build Coastguard Worker   const char	*specs[1000];		/* Specifiers for profiles */
2982*5e7646d2SAndroid Build Coastguard Worker 
2983*5e7646d2SAndroid Build Coastguard Worker 
2984*5e7646d2SAndroid Build Coastguard Worker   prefix = warn ? "  WARN  " : "**FAIL**";
2985*5e7646d2SAndroid Build Coastguard Worker 
2986*5e7646d2SAndroid Build Coastguard Worker   for (attr = ppdFindAttr(ppd, "cupsICCProfile", NULL);
2987*5e7646d2SAndroid Build Coastguard Worker        attr;
2988*5e7646d2SAndroid Build Coastguard Worker        attr = ppdFindNextAttr(ppd, "cupsICCProfile", NULL))
2989*5e7646d2SAndroid Build Coastguard Worker   {
2990*5e7646d2SAndroid Build Coastguard Worker    /*
2991*5e7646d2SAndroid Build Coastguard Worker     * Check for valid selector...
2992*5e7646d2SAndroid Build Coastguard Worker     */
2993*5e7646d2SAndroid Build Coastguard Worker 
2994*5e7646d2SAndroid Build Coastguard Worker     for (i = 0, ptr = strchr(attr->spec, '.'); ptr; ptr = strchr(ptr + 1, '.'))
2995*5e7646d2SAndroid Build Coastguard Worker       i ++;
2996*5e7646d2SAndroid Build Coastguard Worker 
2997*5e7646d2SAndroid Build Coastguard Worker     if (!attr->value || i < 2)
2998*5e7646d2SAndroid Build Coastguard Worker     {
2999*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
3000*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
3001*5e7646d2SAndroid Build Coastguard Worker 
3002*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
3003*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
3004*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Bad cupsICCProfile %s."),
3005*5e7646d2SAndroid Build Coastguard Worker 			prefix, attr->spec);
3006*5e7646d2SAndroid Build Coastguard Worker 
3007*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
3008*5e7646d2SAndroid Build Coastguard Worker         errors ++;
3009*5e7646d2SAndroid Build Coastguard Worker 
3010*5e7646d2SAndroid Build Coastguard Worker       continue;
3011*5e7646d2SAndroid Build Coastguard Worker     }
3012*5e7646d2SAndroid Build Coastguard Worker 
3013*5e7646d2SAndroid Build Coastguard Worker    /*
3014*5e7646d2SAndroid Build Coastguard Worker     * Check for valid profile filename...
3015*5e7646d2SAndroid Build Coastguard Worker     */
3016*5e7646d2SAndroid Build Coastguard Worker 
3017*5e7646d2SAndroid Build Coastguard Worker     if (attr->value[0] == '/')
3018*5e7646d2SAndroid Build Coastguard Worker       snprintf(filename, sizeof(filename), "%s%s", root, attr->value);
3019*5e7646d2SAndroid Build Coastguard Worker     else
3020*5e7646d2SAndroid Build Coastguard Worker     {
3021*5e7646d2SAndroid Build Coastguard Worker       if ((ptr = getenv("CUPS_DATADIR")) == NULL)
3022*5e7646d2SAndroid Build Coastguard Worker 	ptr = CUPS_DATADIR;
3023*5e7646d2SAndroid Build Coastguard Worker 
3024*5e7646d2SAndroid Build Coastguard Worker       if (*ptr == '/' || !*root)
3025*5e7646d2SAndroid Build Coastguard Worker 	snprintf(filename, sizeof(filename), "%s%s/profiles/%s", root, ptr,
3026*5e7646d2SAndroid Build Coastguard Worker 		 attr->value);
3027*5e7646d2SAndroid Build Coastguard Worker       else
3028*5e7646d2SAndroid Build Coastguard Worker 	snprintf(filename, sizeof(filename), "%s/%s/profiles/%s", root, ptr,
3029*5e7646d2SAndroid Build Coastguard Worker 		 attr->value);
3030*5e7646d2SAndroid Build Coastguard Worker     }
3031*5e7646d2SAndroid Build Coastguard Worker 
3032*5e7646d2SAndroid Build Coastguard Worker     if (stat(filename, &fileinfo))
3033*5e7646d2SAndroid Build Coastguard Worker     {
3034*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
3035*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
3036*5e7646d2SAndroid Build Coastguard Worker 
3037*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
3038*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout, _("      %s  Missing %s file \"%s\"."),
3039*5e7646d2SAndroid Build Coastguard Worker 	                prefix, "cupsICCProfile", filename);
3040*5e7646d2SAndroid Build Coastguard Worker 
3041*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
3042*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
3043*5e7646d2SAndroid Build Coastguard Worker     }
3044*5e7646d2SAndroid Build Coastguard Worker     else if (fileinfo.st_uid != 0 ||
3045*5e7646d2SAndroid Build Coastguard Worker 	     (fileinfo.st_mode & MODE_WRITE) ||
3046*5e7646d2SAndroid Build Coastguard Worker 	     (fileinfo.st_mode & MODE_MASK) != MODE_DATAFILE)
3047*5e7646d2SAndroid Build Coastguard Worker     {
3048*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
3049*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
3050*5e7646d2SAndroid Build Coastguard Worker 
3051*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
3052*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
3053*5e7646d2SAndroid Build Coastguard Worker 	                _("      %s  Bad permissions on %s file \"%s\"."),
3054*5e7646d2SAndroid Build Coastguard Worker 			prefix, "cupsICCProfile", filename);
3055*5e7646d2SAndroid Build Coastguard Worker 
3056*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
3057*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
3058*5e7646d2SAndroid Build Coastguard Worker     }
3059*5e7646d2SAndroid Build Coastguard Worker     else
3060*5e7646d2SAndroid Build Coastguard Worker       errors = valid_path("cupsICCProfile", filename, errors, verbose, warn);
3061*5e7646d2SAndroid Build Coastguard Worker 
3062*5e7646d2SAndroid Build Coastguard Worker    /*
3063*5e7646d2SAndroid Build Coastguard Worker     * Check for hash collisions...
3064*5e7646d2SAndroid Build Coastguard Worker     */
3065*5e7646d2SAndroid Build Coastguard Worker 
3066*5e7646d2SAndroid Build Coastguard Worker     hash = _ppdHashName(attr->spec);
3067*5e7646d2SAndroid Build Coastguard Worker 
3068*5e7646d2SAndroid Build Coastguard Worker     if (num_profiles > 0)
3069*5e7646d2SAndroid Build Coastguard Worker     {
3070*5e7646d2SAndroid Build Coastguard Worker       for (i = 0; i < num_profiles; i ++)
3071*5e7646d2SAndroid Build Coastguard Worker 	if (hashes[i] == hash)
3072*5e7646d2SAndroid Build Coastguard Worker 	  break;
3073*5e7646d2SAndroid Build Coastguard Worker 
3074*5e7646d2SAndroid Build Coastguard Worker       if (i < num_profiles)
3075*5e7646d2SAndroid Build Coastguard Worker       {
3076*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
3077*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
3078*5e7646d2SAndroid Build Coastguard Worker 
3079*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
3080*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
3081*5e7646d2SAndroid Build Coastguard Worker 			  _("      %s  cupsICCProfile %s hash value "
3082*5e7646d2SAndroid Build Coastguard Worker 			    "collides with %s."), prefix, attr->spec,
3083*5e7646d2SAndroid Build Coastguard Worker 			  specs[i]);
3084*5e7646d2SAndroid Build Coastguard Worker 
3085*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
3086*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
3087*5e7646d2SAndroid Build Coastguard Worker       }
3088*5e7646d2SAndroid Build Coastguard Worker     }
3089*5e7646d2SAndroid Build Coastguard Worker 
3090*5e7646d2SAndroid Build Coastguard Worker    /*
3091*5e7646d2SAndroid Build Coastguard Worker     * Remember up to 1000 profiles...
3092*5e7646d2SAndroid Build Coastguard Worker     */
3093*5e7646d2SAndroid Build Coastguard Worker 
3094*5e7646d2SAndroid Build Coastguard Worker     if (num_profiles < 1000)
3095*5e7646d2SAndroid Build Coastguard Worker     {
3096*5e7646d2SAndroid Build Coastguard Worker       hashes[num_profiles] = hash;
3097*5e7646d2SAndroid Build Coastguard Worker       specs[num_profiles]  = attr->spec;
3098*5e7646d2SAndroid Build Coastguard Worker       num_profiles ++;
3099*5e7646d2SAndroid Build Coastguard Worker     }
3100*5e7646d2SAndroid Build Coastguard Worker   }
3101*5e7646d2SAndroid Build Coastguard Worker 
3102*5e7646d2SAndroid Build Coastguard Worker   return (errors);
3103*5e7646d2SAndroid Build Coastguard Worker }
3104*5e7646d2SAndroid Build Coastguard Worker 
3105*5e7646d2SAndroid Build Coastguard Worker 
3106*5e7646d2SAndroid Build Coastguard Worker /*
3107*5e7646d2SAndroid Build Coastguard Worker  * 'check_sizes()' - Check media sizes in the PPD file.
3108*5e7646d2SAndroid Build Coastguard Worker  */
3109*5e7646d2SAndroid Build Coastguard Worker 
3110*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Errors found */
check_sizes(ppd_file_t * ppd,int errors,int verbose,int warn)3111*5e7646d2SAndroid Build Coastguard Worker check_sizes(ppd_file_t *ppd,		/* I - PPD file */
3112*5e7646d2SAndroid Build Coastguard Worker 	    int        errors,		/* I - Errors found */
3113*5e7646d2SAndroid Build Coastguard Worker 	    int        verbose,		/* I - Verbosity level */
3114*5e7646d2SAndroid Build Coastguard Worker 	    int        warn)		/* I - Warnings only? */
3115*5e7646d2SAndroid Build Coastguard Worker {
3116*5e7646d2SAndroid Build Coastguard Worker   int		i;			/* Looping var */
3117*5e7646d2SAndroid Build Coastguard Worker   ppd_size_t	*size;			/* Current size */
3118*5e7646d2SAndroid Build Coastguard Worker   int		width,			/* Custom width */
3119*5e7646d2SAndroid Build Coastguard Worker 		length;			/* Custom length */
3120*5e7646d2SAndroid Build Coastguard Worker   const char	*prefix;		/* WARN/FAIL prefix */
3121*5e7646d2SAndroid Build Coastguard Worker   ppd_option_t	*page_size,		/* PageSize option */
3122*5e7646d2SAndroid Build Coastguard Worker 		*page_region;		/* PageRegion option */
3123*5e7646d2SAndroid Build Coastguard Worker   pwg_media_t	*pwg_media;		/* PWG media */
3124*5e7646d2SAndroid Build Coastguard Worker   char		buf[PPD_MAX_NAME];	/* PapeSize name that is supposed to be */
3125*5e7646d2SAndroid Build Coastguard Worker   const char	*ptr;			/* Pointer into string */
3126*5e7646d2SAndroid Build Coastguard Worker   int		width_2540ths,		/* PageSize width in 2540ths */
3127*5e7646d2SAndroid Build Coastguard Worker 		length_2540ths;		/* PageSize length in 2540ths */
3128*5e7646d2SAndroid Build Coastguard Worker   int		is_ok;			/* Flag for PageSize name verification */
3129*5e7646d2SAndroid Build Coastguard Worker   double	width_tmp,		/* Width after rounded up */
3130*5e7646d2SAndroid Build Coastguard Worker 		length_tmp,		/* Length after rounded up */
3131*5e7646d2SAndroid Build Coastguard Worker 		width_inch,		/* Width in inches */
3132*5e7646d2SAndroid Build Coastguard Worker 		length_inch,		/* Length in inches */
3133*5e7646d2SAndroid Build Coastguard Worker 		width_mm,		/* Width in millimeters */
3134*5e7646d2SAndroid Build Coastguard Worker 		length_mm;		/* Length in millimeters */
3135*5e7646d2SAndroid Build Coastguard Worker 
3136*5e7646d2SAndroid Build Coastguard Worker 
3137*5e7646d2SAndroid Build Coastguard Worker   prefix = warn ? "  WARN  " : "**FAIL**";
3138*5e7646d2SAndroid Build Coastguard Worker 
3139*5e7646d2SAndroid Build Coastguard Worker   if ((page_size = ppdFindOption(ppd, "PageSize")) == NULL && warn != 2)
3140*5e7646d2SAndroid Build Coastguard Worker   {
3141*5e7646d2SAndroid Build Coastguard Worker     if (!warn && !errors && !verbose)
3142*5e7646d2SAndroid Build Coastguard Worker       _cupsLangPuts(stdout, _(" FAIL"));
3143*5e7646d2SAndroid Build Coastguard Worker 
3144*5e7646d2SAndroid Build Coastguard Worker     if (verbose >= 0)
3145*5e7646d2SAndroid Build Coastguard Worker       _cupsLangPrintf(stdout,
3146*5e7646d2SAndroid Build Coastguard Worker 		      _("      %s  Missing REQUIRED PageSize option.\n"
3147*5e7646d2SAndroid Build Coastguard Worker 		        "                REF: Page 99, section 5.14."),
3148*5e7646d2SAndroid Build Coastguard Worker 		      prefix);
3149*5e7646d2SAndroid Build Coastguard Worker 
3150*5e7646d2SAndroid Build Coastguard Worker     if (!warn)
3151*5e7646d2SAndroid Build Coastguard Worker       errors ++;
3152*5e7646d2SAndroid Build Coastguard Worker   }
3153*5e7646d2SAndroid Build Coastguard Worker 
3154*5e7646d2SAndroid Build Coastguard Worker   if ((page_region = ppdFindOption(ppd, "PageRegion")) == NULL && warn != 2)
3155*5e7646d2SAndroid Build Coastguard Worker   {
3156*5e7646d2SAndroid Build Coastguard Worker     if (!warn && !errors && !verbose)
3157*5e7646d2SAndroid Build Coastguard Worker       _cupsLangPuts(stdout, _(" FAIL"));
3158*5e7646d2SAndroid Build Coastguard Worker 
3159*5e7646d2SAndroid Build Coastguard Worker     if (verbose >= 0)
3160*5e7646d2SAndroid Build Coastguard Worker       _cupsLangPrintf(stdout,
3161*5e7646d2SAndroid Build Coastguard Worker 		      _("      %s  Missing REQUIRED PageRegion option.\n"
3162*5e7646d2SAndroid Build Coastguard Worker 		        "                REF: Page 100, section 5.14."),
3163*5e7646d2SAndroid Build Coastguard Worker 		      prefix);
3164*5e7646d2SAndroid Build Coastguard Worker 
3165*5e7646d2SAndroid Build Coastguard Worker     if (!warn)
3166*5e7646d2SAndroid Build Coastguard Worker       errors ++;
3167*5e7646d2SAndroid Build Coastguard Worker   }
3168*5e7646d2SAndroid Build Coastguard Worker 
3169*5e7646d2SAndroid Build Coastguard Worker   for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++)
3170*5e7646d2SAndroid Build Coastguard Worker   {
3171*5e7646d2SAndroid Build Coastguard Worker    /*
3172*5e7646d2SAndroid Build Coastguard Worker     * Check that the size name is standard...
3173*5e7646d2SAndroid Build Coastguard Worker     */
3174*5e7646d2SAndroid Build Coastguard Worker 
3175*5e7646d2SAndroid Build Coastguard Worker     if (!strcmp(size->name, "Custom"))
3176*5e7646d2SAndroid Build Coastguard Worker     {
3177*5e7646d2SAndroid Build Coastguard Worker      /*
3178*5e7646d2SAndroid Build Coastguard Worker       * Skip custom page size...
3179*5e7646d2SAndroid Build Coastguard Worker       */
3180*5e7646d2SAndroid Build Coastguard Worker 
3181*5e7646d2SAndroid Build Coastguard Worker       continue;
3182*5e7646d2SAndroid Build Coastguard Worker     }
3183*5e7646d2SAndroid Build Coastguard Worker 
3184*5e7646d2SAndroid Build Coastguard Worker     if (warn != 2 && size->name[0] == 'w' &&
3185*5e7646d2SAndroid Build Coastguard Worker         sscanf(size->name, "w%dh%d", &width, &length) == 2)
3186*5e7646d2SAndroid Build Coastguard Worker     {
3187*5e7646d2SAndroid Build Coastguard Worker      /*
3188*5e7646d2SAndroid Build Coastguard Worker       * Validate device-specific size wNNNhNNN should have proper width and
3189*5e7646d2SAndroid Build Coastguard Worker       * length...
3190*5e7646d2SAndroid Build Coastguard Worker       */
3191*5e7646d2SAndroid Build Coastguard Worker 
3192*5e7646d2SAndroid Build Coastguard Worker       if (fabs(width - size->width) >= 1.0 ||
3193*5e7646d2SAndroid Build Coastguard Worker           fabs(length - size->length) >= 1.0)
3194*5e7646d2SAndroid Build Coastguard Worker       {
3195*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
3196*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
3197*5e7646d2SAndroid Build Coastguard Worker 
3198*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
3199*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
3200*5e7646d2SAndroid Build Coastguard Worker 			  _("      %s  Size \"%s\" has unexpected dimensions "
3201*5e7646d2SAndroid Build Coastguard Worker 			    "(%gx%g)."),
3202*5e7646d2SAndroid Build Coastguard Worker 			  prefix, size->name, size->width, size->length);
3203*5e7646d2SAndroid Build Coastguard Worker 
3204*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
3205*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
3206*5e7646d2SAndroid Build Coastguard Worker       }
3207*5e7646d2SAndroid Build Coastguard Worker     }
3208*5e7646d2SAndroid Build Coastguard Worker 
3209*5e7646d2SAndroid Build Coastguard Worker    /*
3210*5e7646d2SAndroid Build Coastguard Worker     * Verify that the size is defined for both PageSize and PageRegion...
3211*5e7646d2SAndroid Build Coastguard Worker     */
3212*5e7646d2SAndroid Build Coastguard Worker 
3213*5e7646d2SAndroid Build Coastguard Worker     if (warn != 2 && !ppdFindChoice(page_size, size->name))
3214*5e7646d2SAndroid Build Coastguard Worker     {
3215*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
3216*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
3217*5e7646d2SAndroid Build Coastguard Worker 
3218*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
3219*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
3220*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Size \"%s\" defined for %s but not for "
3221*5e7646d2SAndroid Build Coastguard Worker 			  "%s."),
3222*5e7646d2SAndroid Build Coastguard Worker 			prefix, size->name, "PageRegion", "PageSize");
3223*5e7646d2SAndroid Build Coastguard Worker 
3224*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
3225*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
3226*5e7646d2SAndroid Build Coastguard Worker     }
3227*5e7646d2SAndroid Build Coastguard Worker     else if (warn != 2 && !ppdFindChoice(page_region, size->name))
3228*5e7646d2SAndroid Build Coastguard Worker     {
3229*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
3230*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
3231*5e7646d2SAndroid Build Coastguard Worker 
3232*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
3233*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
3234*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  Size \"%s\" defined for %s but not for "
3235*5e7646d2SAndroid Build Coastguard Worker 			  "%s."),
3236*5e7646d2SAndroid Build Coastguard Worker 			prefix, size->name, "PageSize", "PageRegion");
3237*5e7646d2SAndroid Build Coastguard Worker 
3238*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
3239*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
3240*5e7646d2SAndroid Build Coastguard Worker     }
3241*5e7646d2SAndroid Build Coastguard Worker 
3242*5e7646d2SAndroid Build Coastguard Worker    /*
3243*5e7646d2SAndroid Build Coastguard Worker     * Verify that the size name is Adobe standard name if it's a standard size
3244*5e7646d2SAndroid Build Coastguard Worker     * and the dimentional name if it's not a standard size.  Suffix should be
3245*5e7646d2SAndroid Build Coastguard Worker     * .Fullbleed, etc., or numeric, e.g., Letter, Letter.Fullbleed,
3246*5e7646d2SAndroid Build Coastguard Worker     * Letter.Transverse, Letter1, Letter2, 4x8, 55x91mm, 55x91mm.Fullbleed, etc.
3247*5e7646d2SAndroid Build Coastguard Worker     */
3248*5e7646d2SAndroid Build Coastguard Worker 
3249*5e7646d2SAndroid Build Coastguard Worker     if (warn != 0)
3250*5e7646d2SAndroid Build Coastguard Worker     {
3251*5e7646d2SAndroid Build Coastguard Worker       is_ok          = 1;
3252*5e7646d2SAndroid Build Coastguard Worker       width_2540ths  = (size->length > size->width) ?
3253*5e7646d2SAndroid Build Coastguard Worker                            PWG_FROM_POINTS(size->width) :
3254*5e7646d2SAndroid Build Coastguard Worker 			   PWG_FROM_POINTS(size->length);
3255*5e7646d2SAndroid Build Coastguard Worker       length_2540ths = (size->length > size->width) ?
3256*5e7646d2SAndroid Build Coastguard Worker                            PWG_FROM_POINTS(size->length) :
3257*5e7646d2SAndroid Build Coastguard Worker 			   PWG_FROM_POINTS(size->width);
3258*5e7646d2SAndroid Build Coastguard Worker       pwg_media      = pwgMediaForSize(width_2540ths, length_2540ths);
3259*5e7646d2SAndroid Build Coastguard Worker 
3260*5e7646d2SAndroid Build Coastguard Worker       if (pwg_media &&
3261*5e7646d2SAndroid Build Coastguard Worker           (abs(pwg_media->width - width_2540ths) > 34 ||
3262*5e7646d2SAndroid Build Coastguard Worker            abs(pwg_media->length - length_2540ths) > 34))
3263*5e7646d2SAndroid Build Coastguard Worker         pwg_media = NULL;		/* Only flag matches within a point */
3264*5e7646d2SAndroid Build Coastguard Worker 
3265*5e7646d2SAndroid Build Coastguard Worker       if (pwg_media && pwg_media->ppd &&
3266*5e7646d2SAndroid Build Coastguard Worker           (pwg_media->ppd[0] < 'a' || pwg_media->ppd[0] > 'z'))
3267*5e7646d2SAndroid Build Coastguard Worker       {
3268*5e7646d2SAndroid Build Coastguard Worker         size_t ppdlen = strlen(pwg_media->ppd);
3269*5e7646d2SAndroid Build Coastguard Worker 					/* Length of standard PPD name */
3270*5e7646d2SAndroid Build Coastguard Worker 
3271*5e7646d2SAndroid Build Coastguard Worker         strlcpy(buf, pwg_media->ppd, sizeof(buf));
3272*5e7646d2SAndroid Build Coastguard Worker 
3273*5e7646d2SAndroid Build Coastguard Worker         if (strcmp(size->name, buf) && size->width > size->length)
3274*5e7646d2SAndroid Build Coastguard Worker         {
3275*5e7646d2SAndroid Build Coastguard Worker           if (!strcmp(pwg_media->ppd, "DoublePostcardRotated"))
3276*5e7646d2SAndroid Build Coastguard Worker             strlcpy(buf, "DoublePostcard", sizeof(buf));
3277*5e7646d2SAndroid Build Coastguard Worker           else if (strstr(size->name, ".Transverse"))
3278*5e7646d2SAndroid Build Coastguard Worker             snprintf(buf, sizeof(buf), "%s.Transverse", pwg_media->ppd);
3279*5e7646d2SAndroid Build Coastguard Worker           else
3280*5e7646d2SAndroid Build Coastguard Worker             snprintf(buf, sizeof(buf), "%sRotated", pwg_media->ppd);
3281*5e7646d2SAndroid Build Coastguard Worker 
3282*5e7646d2SAndroid Build Coastguard Worker 	  ppdlen = strlen(buf);
3283*5e7646d2SAndroid Build Coastguard Worker         }
3284*5e7646d2SAndroid Build Coastguard Worker 
3285*5e7646d2SAndroid Build Coastguard Worker         if (size->left == 0 && size->bottom == 0 &&
3286*5e7646d2SAndroid Build Coastguard Worker 	    size->right == size->width && size->top == size->length)
3287*5e7646d2SAndroid Build Coastguard Worker         {
3288*5e7646d2SAndroid Build Coastguard Worker           strlcat(buf, ".Fullbleed", sizeof(buf) - strlen(buf));
3289*5e7646d2SAndroid Build Coastguard Worker 	  if (_cups_strcasecmp(size->name, buf))
3290*5e7646d2SAndroid Build Coastguard Worker 	  {
3291*5e7646d2SAndroid Build Coastguard Worker 	   /*
3292*5e7646d2SAndroid Build Coastguard Worker 	    * Allow an additional qualifier such as ".WithTab"...
3293*5e7646d2SAndroid Build Coastguard Worker 	    */
3294*5e7646d2SAndroid Build Coastguard Worker 
3295*5e7646d2SAndroid Build Coastguard Worker 	    size_t buflen = strlen(buf);/* Length of full bleed name */
3296*5e7646d2SAndroid Build Coastguard Worker 
3297*5e7646d2SAndroid Build Coastguard Worker             if (_cups_strncasecmp(size->name, buf, buflen) ||
3298*5e7646d2SAndroid Build Coastguard Worker                 size->name[buflen] != '.')
3299*5e7646d2SAndroid Build Coastguard Worker 	      is_ok = 0;
3300*5e7646d2SAndroid Build Coastguard Worker 	  }
3301*5e7646d2SAndroid Build Coastguard Worker         }
3302*5e7646d2SAndroid Build Coastguard Worker 	else if (!strncmp(size->name, pwg_media->ppd, ppdlen))
3303*5e7646d2SAndroid Build Coastguard Worker 	{
3304*5e7646d2SAndroid Build Coastguard Worker 	 /*
3305*5e7646d2SAndroid Build Coastguard Worker 	  * Check for a proper qualifier (number, "Small", or .something)...
3306*5e7646d2SAndroid Build Coastguard Worker 	  */
3307*5e7646d2SAndroid Build Coastguard Worker 
3308*5e7646d2SAndroid Build Coastguard Worker 	  ptr = size->name + ppdlen;
3309*5e7646d2SAndroid Build Coastguard Worker 
3310*5e7646d2SAndroid Build Coastguard Worker 	  if (isdigit(*ptr & 255))
3311*5e7646d2SAndroid Build Coastguard Worker           {
3312*5e7646d2SAndroid Build Coastguard Worker             for (ptr ++; *ptr; ptr ++)
3313*5e7646d2SAndroid Build Coastguard Worker             {
3314*5e7646d2SAndroid Build Coastguard Worker               if (!isdigit(*ptr & 255))
3315*5e7646d2SAndroid Build Coastguard Worker 	      {
3316*5e7646d2SAndroid Build Coastguard Worker                 is_ok = 0;
3317*5e7646d2SAndroid Build Coastguard Worker 		break;
3318*5e7646d2SAndroid Build Coastguard Worker 	      }
3319*5e7646d2SAndroid Build Coastguard Worker             }
3320*5e7646d2SAndroid Build Coastguard Worker           }
3321*5e7646d2SAndroid Build Coastguard Worker           else if (*ptr != '.' && *ptr && strcmp(ptr, "Small"))
3322*5e7646d2SAndroid Build Coastguard Worker 	    is_ok = 0;
3323*5e7646d2SAndroid Build Coastguard Worker         }
3324*5e7646d2SAndroid Build Coastguard Worker 	else
3325*5e7646d2SAndroid Build Coastguard Worker 	{
3326*5e7646d2SAndroid Build Coastguard Worker 	 /*
3327*5e7646d2SAndroid Build Coastguard Worker 	  * Check for EnvSizeName as well...
3328*5e7646d2SAndroid Build Coastguard Worker 	  */
3329*5e7646d2SAndroid Build Coastguard Worker 
3330*5e7646d2SAndroid Build Coastguard Worker 	  if (strncmp(pwg_media->ppd, "Env", 3) &&
3331*5e7646d2SAndroid Build Coastguard Worker 	      !strncmp(size->name, "Env", 3))
3332*5e7646d2SAndroid Build Coastguard Worker             snprintf(buf, sizeof(buf), "Env%s", pwg_media->ppd);
3333*5e7646d2SAndroid Build Coastguard Worker 
3334*5e7646d2SAndroid Build Coastguard Worker 	  if (strcmp(size->name, buf))
3335*5e7646d2SAndroid Build Coastguard Worker 	    is_ok = 0;
3336*5e7646d2SAndroid Build Coastguard Worker 	}
3337*5e7646d2SAndroid Build Coastguard Worker 
3338*5e7646d2SAndroid Build Coastguard Worker         if (!is_ok)
3339*5e7646d2SAndroid Build Coastguard Worker           _cupsLangPrintf(stdout,
3340*5e7646d2SAndroid Build Coastguard Worker                           _("      %s  Size \"%s\" should be the Adobe "
3341*5e7646d2SAndroid Build Coastguard Worker 			    "standard name \"%s\"."),
3342*5e7646d2SAndroid Build Coastguard Worker                           prefix, size->name, buf);
3343*5e7646d2SAndroid Build Coastguard Worker       }
3344*5e7646d2SAndroid Build Coastguard Worker       else
3345*5e7646d2SAndroid Build Coastguard Worker       {
3346*5e7646d2SAndroid Build Coastguard Worker         width_tmp  = (fabs(size->width - ceil(size->width)) < 0.1) ?
3347*5e7646d2SAndroid Build Coastguard Worker 	                 ceil(size->width) : size->width;
3348*5e7646d2SAndroid Build Coastguard Worker         length_tmp = (fabs(size->length - ceil(size->length)) < 0.1) ?
3349*5e7646d2SAndroid Build Coastguard Worker 	                 ceil(size->length) : size->length;
3350*5e7646d2SAndroid Build Coastguard Worker 
3351*5e7646d2SAndroid Build Coastguard Worker         if (fmod(width_tmp, 9.0) == 0.0 && fmod(length_tmp, 9.0) == 0.0)
3352*5e7646d2SAndroid Build Coastguard Worker         {
3353*5e7646d2SAndroid Build Coastguard Worker           width_inch  = width_tmp / 72.0;
3354*5e7646d2SAndroid Build Coastguard Worker           length_inch = length_tmp / 72.0;
3355*5e7646d2SAndroid Build Coastguard Worker 
3356*5e7646d2SAndroid Build Coastguard Worker           snprintf(buf, sizeof(buf), "%gx%g", width_inch, length_inch);
3357*5e7646d2SAndroid Build Coastguard Worker         }
3358*5e7646d2SAndroid Build Coastguard Worker         else
3359*5e7646d2SAndroid Build Coastguard Worker         {
3360*5e7646d2SAndroid Build Coastguard Worker           width_mm  = size->width / 72.0 * 25.4;
3361*5e7646d2SAndroid Build Coastguard Worker           length_mm = size->length / 72.0 * 25.4;
3362*5e7646d2SAndroid Build Coastguard Worker 
3363*5e7646d2SAndroid Build Coastguard Worker           snprintf(buf, sizeof(buf), "%.0fx%.0fmm", width_mm, length_mm);
3364*5e7646d2SAndroid Build Coastguard Worker         }
3365*5e7646d2SAndroid Build Coastguard Worker 
3366*5e7646d2SAndroid Build Coastguard Worker         if (size->left == 0 && size->bottom == 0 &&
3367*5e7646d2SAndroid Build Coastguard Worker 	    size->right == size->width && size->top == size->length)
3368*5e7646d2SAndroid Build Coastguard Worker           strlcat(buf, ".Fullbleed", sizeof(buf));
3369*5e7646d2SAndroid Build Coastguard Worker         else if (size->width > size->length)
3370*5e7646d2SAndroid Build Coastguard Worker           strlcat(buf, ".Transverse", sizeof(buf));
3371*5e7646d2SAndroid Build Coastguard Worker 
3372*5e7646d2SAndroid Build Coastguard Worker         if (_cups_strcasecmp(size->name, buf))
3373*5e7646d2SAndroid Build Coastguard Worker         {
3374*5e7646d2SAndroid Build Coastguard Worker           size_t	buflen = strlen(buf);
3375*5e7646d2SAndroid Build Coastguard Worker           				/* Length of proposed name */
3376*5e7646d2SAndroid Build Coastguard Worker 
3377*5e7646d2SAndroid Build Coastguard Worker           if (_cups_strncasecmp(size->name, buf, buflen) ||
3378*5e7646d2SAndroid Build Coastguard Worker               (strcmp(size->name + buflen, "in") &&
3379*5e7646d2SAndroid Build Coastguard Worker                size->name[buflen] != '.'))
3380*5e7646d2SAndroid Build Coastguard Worker           {
3381*5e7646d2SAndroid Build Coastguard Worker 	    char	altbuf[PPD_MAX_NAME];
3382*5e7646d2SAndroid Build Coastguard Worker 					/* Alternate "wNNNhNNN" name */
3383*5e7646d2SAndroid Build Coastguard Worker 	    size_t	altlen;		/* Length of alternate name */
3384*5e7646d2SAndroid Build Coastguard Worker 
3385*5e7646d2SAndroid Build Coastguard Worker 	    snprintf(altbuf, sizeof(altbuf), "w%.0fh%.0f", size->width,
3386*5e7646d2SAndroid Build Coastguard Worker 	             size->length);
3387*5e7646d2SAndroid Build Coastguard Worker 	    altlen = strlen(altbuf);
3388*5e7646d2SAndroid Build Coastguard Worker 	    if (_cups_strncasecmp(size->name, altbuf, altlen) ||
3389*5e7646d2SAndroid Build Coastguard Worker 	        (size->name[altlen] && size->name[altlen] != '.'))
3390*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPrintf(stdout,
3391*5e7646d2SAndroid Build Coastguard Worker 			      _("      %s  Size \"%s\" should be \"%s\"."),
3392*5e7646d2SAndroid Build Coastguard Worker 			      prefix, size->name, buf);
3393*5e7646d2SAndroid Build Coastguard Worker 	  }
3394*5e7646d2SAndroid Build Coastguard Worker         }
3395*5e7646d2SAndroid Build Coastguard Worker       }
3396*5e7646d2SAndroid Build Coastguard Worker     }
3397*5e7646d2SAndroid Build Coastguard Worker   }
3398*5e7646d2SAndroid Build Coastguard Worker 
3399*5e7646d2SAndroid Build Coastguard Worker   return (errors);
3400*5e7646d2SAndroid Build Coastguard Worker }
3401*5e7646d2SAndroid Build Coastguard Worker 
3402*5e7646d2SAndroid Build Coastguard Worker 
3403*5e7646d2SAndroid Build Coastguard Worker /*
3404*5e7646d2SAndroid Build Coastguard Worker  * 'check_translations()' - Check translations in the PPD file.
3405*5e7646d2SAndroid Build Coastguard Worker  */
3406*5e7646d2SAndroid Build Coastguard Worker 
3407*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Errors found */
check_translations(ppd_file_t * ppd,int errors,int verbose,int warn)3408*5e7646d2SAndroid Build Coastguard Worker check_translations(ppd_file_t *ppd,	/* I - PPD file */
3409*5e7646d2SAndroid Build Coastguard Worker                    int        errors,	/* I - Errors found */
3410*5e7646d2SAndroid Build Coastguard Worker                    int        verbose,	/* I - Verbosity level */
3411*5e7646d2SAndroid Build Coastguard Worker                    int        warn)	/* I - Warnings only? */
3412*5e7646d2SAndroid Build Coastguard Worker {
3413*5e7646d2SAndroid Build Coastguard Worker   int		j;			/* Looping var */
3414*5e7646d2SAndroid Build Coastguard Worker   ppd_attr_t	*attr;			/* PPD attribute */
3415*5e7646d2SAndroid Build Coastguard Worker   cups_array_t	*languages;		/* Array of languages */
3416*5e7646d2SAndroid Build Coastguard Worker   int		langlen;		/* Length of language */
3417*5e7646d2SAndroid Build Coastguard Worker   char		*language,		/* Current language */
3418*5e7646d2SAndroid Build Coastguard Worker 		keyword[PPD_MAX_NAME],	/* Localization keyword (full) */
3419*5e7646d2SAndroid Build Coastguard Worker 		llkeyword[PPD_MAX_NAME],/* Localization keyword (base) */
3420*5e7646d2SAndroid Build Coastguard Worker 		ckeyword[PPD_MAX_NAME],	/* Custom option keyword (full) */
3421*5e7646d2SAndroid Build Coastguard Worker 		cllkeyword[PPD_MAX_NAME];
3422*5e7646d2SAndroid Build Coastguard Worker 					/* Custom option keyword (base) */
3423*5e7646d2SAndroid Build Coastguard Worker   ppd_option_t	*option;		/* Standard UI option */
3424*5e7646d2SAndroid Build Coastguard Worker   ppd_coption_t	*coption;		/* Custom option */
3425*5e7646d2SAndroid Build Coastguard Worker   ppd_cparam_t	*cparam;		/* Custom parameter */
3426*5e7646d2SAndroid Build Coastguard Worker   char		ll[3];			/* Base language */
3427*5e7646d2SAndroid Build Coastguard Worker   const char	*prefix;		/* WARN/FAIL prefix */
3428*5e7646d2SAndroid Build Coastguard Worker   const char	*text;			/* Pointer into UI text */
3429*5e7646d2SAndroid Build Coastguard Worker 
3430*5e7646d2SAndroid Build Coastguard Worker 
3431*5e7646d2SAndroid Build Coastguard Worker   prefix = warn ? "  WARN  " : "**FAIL**";
3432*5e7646d2SAndroid Build Coastguard Worker 
3433*5e7646d2SAndroid Build Coastguard Worker   if ((languages = _ppdGetLanguages(ppd)) != NULL)
3434*5e7646d2SAndroid Build Coastguard Worker   {
3435*5e7646d2SAndroid Build Coastguard Worker    /*
3436*5e7646d2SAndroid Build Coastguard Worker     * This file contains localizations, check them...
3437*5e7646d2SAndroid Build Coastguard Worker     */
3438*5e7646d2SAndroid Build Coastguard Worker 
3439*5e7646d2SAndroid Build Coastguard Worker     for (language = (char *)cupsArrayFirst(languages);
3440*5e7646d2SAndroid Build Coastguard Worker          language;
3441*5e7646d2SAndroid Build Coastguard Worker 	 language = (char *)cupsArrayNext(languages))
3442*5e7646d2SAndroid Build Coastguard Worker     {
3443*5e7646d2SAndroid Build Coastguard Worker       langlen = (int)strlen(language);
3444*5e7646d2SAndroid Build Coastguard Worker       if (langlen != 2 && langlen != 5)
3445*5e7646d2SAndroid Build Coastguard Worker       {
3446*5e7646d2SAndroid Build Coastguard Worker 	if (!warn && !errors && !verbose)
3447*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPuts(stdout, _(" FAIL"));
3448*5e7646d2SAndroid Build Coastguard Worker 
3449*5e7646d2SAndroid Build Coastguard Worker 	if (verbose >= 0)
3450*5e7646d2SAndroid Build Coastguard Worker 	  _cupsLangPrintf(stdout,
3451*5e7646d2SAndroid Build Coastguard Worker 			  _("      %s  Bad language \"%s\"."),
3452*5e7646d2SAndroid Build Coastguard Worker 			  prefix, language);
3453*5e7646d2SAndroid Build Coastguard Worker 
3454*5e7646d2SAndroid Build Coastguard Worker 	if (!warn)
3455*5e7646d2SAndroid Build Coastguard Worker 	  errors ++;
3456*5e7646d2SAndroid Build Coastguard Worker 
3457*5e7646d2SAndroid Build Coastguard Worker 	continue;
3458*5e7646d2SAndroid Build Coastguard Worker       }
3459*5e7646d2SAndroid Build Coastguard Worker 
3460*5e7646d2SAndroid Build Coastguard Worker       if (!strcmp(language, "en"))
3461*5e7646d2SAndroid Build Coastguard Worker         continue;
3462*5e7646d2SAndroid Build Coastguard Worker 
3463*5e7646d2SAndroid Build Coastguard Worker       strlcpy(ll, language, sizeof(ll));
3464*5e7646d2SAndroid Build Coastguard Worker 
3465*5e7646d2SAndroid Build Coastguard Worker      /*
3466*5e7646d2SAndroid Build Coastguard Worker       * Loop through all options and choices...
3467*5e7646d2SAndroid Build Coastguard Worker       */
3468*5e7646d2SAndroid Build Coastguard Worker 
3469*5e7646d2SAndroid Build Coastguard Worker       for (option = ppdFirstOption(ppd);
3470*5e7646d2SAndroid Build Coastguard Worker 	   option;
3471*5e7646d2SAndroid Build Coastguard Worker 	   option = ppdNextOption(ppd))
3472*5e7646d2SAndroid Build Coastguard Worker       {
3473*5e7646d2SAndroid Build Coastguard Worker         if (!strcmp(option->keyword, "PageRegion"))
3474*5e7646d2SAndroid Build Coastguard Worker 	  continue;
3475*5e7646d2SAndroid Build Coastguard Worker 
3476*5e7646d2SAndroid Build Coastguard Worker 	snprintf(keyword, sizeof(keyword), "%s.Translation", language);
3477*5e7646d2SAndroid Build Coastguard Worker 	snprintf(llkeyword, sizeof(llkeyword), "%s.Translation", ll);
3478*5e7646d2SAndroid Build Coastguard Worker 
3479*5e7646d2SAndroid Build Coastguard Worker 	if ((attr = ppdFindAttr(ppd, keyword, option->keyword)) == NULL &&
3480*5e7646d2SAndroid Build Coastguard Worker 	    (attr = ppdFindAttr(ppd, llkeyword, option->keyword)) == NULL)
3481*5e7646d2SAndroid Build Coastguard Worker 	{
3482*5e7646d2SAndroid Build Coastguard Worker 	  if (!warn && !errors && !verbose)
3483*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
3484*5e7646d2SAndroid Build Coastguard Worker 
3485*5e7646d2SAndroid Build Coastguard Worker 	  if (verbose >= 0)
3486*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPrintf(stdout,
3487*5e7646d2SAndroid Build Coastguard Worker 			    _("      %s  Missing \"%s\" translation "
3488*5e7646d2SAndroid Build Coastguard Worker 			      "string for option %s."),
3489*5e7646d2SAndroid Build Coastguard Worker 			    prefix, language, option->keyword);
3490*5e7646d2SAndroid Build Coastguard Worker 
3491*5e7646d2SAndroid Build Coastguard Worker           if (!warn)
3492*5e7646d2SAndroid Build Coastguard Worker 	    errors ++;
3493*5e7646d2SAndroid Build Coastguard Worker 	}
3494*5e7646d2SAndroid Build Coastguard Worker 	else if (!valid_utf8(attr->text))
3495*5e7646d2SAndroid Build Coastguard Worker 	{
3496*5e7646d2SAndroid Build Coastguard Worker 	  if (!warn && !errors && !verbose)
3497*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
3498*5e7646d2SAndroid Build Coastguard Worker 
3499*5e7646d2SAndroid Build Coastguard Worker 	  if (verbose >= 0)
3500*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPrintf(stdout,
3501*5e7646d2SAndroid Build Coastguard Worker 			    _("      %s  Bad UTF-8 \"%s\" translation "
3502*5e7646d2SAndroid Build Coastguard Worker 			      "string for option %s."),
3503*5e7646d2SAndroid Build Coastguard Worker 			    prefix, language, option->keyword);
3504*5e7646d2SAndroid Build Coastguard Worker 
3505*5e7646d2SAndroid Build Coastguard Worker 	  if (!warn)
3506*5e7646d2SAndroid Build Coastguard Worker 	    errors ++;
3507*5e7646d2SAndroid Build Coastguard Worker 	}
3508*5e7646d2SAndroid Build Coastguard Worker 
3509*5e7646d2SAndroid Build Coastguard Worker 	snprintf(keyword, sizeof(keyword), "%s.%s", language,
3510*5e7646d2SAndroid Build Coastguard Worker 		 option->keyword);
3511*5e7646d2SAndroid Build Coastguard Worker 	snprintf(llkeyword, sizeof(llkeyword), "%s.%s", ll,
3512*5e7646d2SAndroid Build Coastguard Worker 		 option->keyword);
3513*5e7646d2SAndroid Build Coastguard Worker 
3514*5e7646d2SAndroid Build Coastguard Worker 	for (j = 0; j < option->num_choices; j ++)
3515*5e7646d2SAndroid Build Coastguard Worker 	{
3516*5e7646d2SAndroid Build Coastguard Worker          /*
3517*5e7646d2SAndroid Build Coastguard Worker 	  * First see if this choice is a number; if so, don't require
3518*5e7646d2SAndroid Build Coastguard Worker 	  * translation...
3519*5e7646d2SAndroid Build Coastguard Worker 	  */
3520*5e7646d2SAndroid Build Coastguard Worker 
3521*5e7646d2SAndroid Build Coastguard Worker           for (text = option->choices[j].text; *text; text ++)
3522*5e7646d2SAndroid Build Coastguard Worker 	    if (!strchr("0123456789-+.", *text))
3523*5e7646d2SAndroid Build Coastguard Worker 	      break;
3524*5e7646d2SAndroid Build Coastguard Worker 
3525*5e7646d2SAndroid Build Coastguard Worker           if (!*text)
3526*5e7646d2SAndroid Build Coastguard Worker 	    continue;
3527*5e7646d2SAndroid Build Coastguard Worker 
3528*5e7646d2SAndroid Build Coastguard Worker 	 /*
3529*5e7646d2SAndroid Build Coastguard Worker 	  * Check custom choices differently...
3530*5e7646d2SAndroid Build Coastguard Worker 	  */
3531*5e7646d2SAndroid Build Coastguard Worker 
3532*5e7646d2SAndroid Build Coastguard Worker 	  if (!_cups_strcasecmp(option->choices[j].choice, "Custom") &&
3533*5e7646d2SAndroid Build Coastguard Worker 	      (coption = ppdFindCustomOption(ppd,
3534*5e7646d2SAndroid Build Coastguard Worker 					     option->keyword)) != NULL)
3535*5e7646d2SAndroid Build Coastguard Worker 	  {
3536*5e7646d2SAndroid Build Coastguard Worker 	    snprintf(ckeyword, sizeof(ckeyword), "%s.Custom%s",
3537*5e7646d2SAndroid Build Coastguard Worker 		     language, option->keyword);
3538*5e7646d2SAndroid Build Coastguard Worker 
3539*5e7646d2SAndroid Build Coastguard Worker 	    if ((attr = ppdFindAttr(ppd, ckeyword, "True")) != NULL &&
3540*5e7646d2SAndroid Build Coastguard Worker 		!valid_utf8(attr->text))
3541*5e7646d2SAndroid Build Coastguard Worker 	    {
3542*5e7646d2SAndroid Build Coastguard Worker 	      if (!warn && !errors && !verbose)
3543*5e7646d2SAndroid Build Coastguard Worker 		_cupsLangPuts(stdout, _(" FAIL"));
3544*5e7646d2SAndroid Build Coastguard Worker 
3545*5e7646d2SAndroid Build Coastguard Worker 	      if (verbose >= 0)
3546*5e7646d2SAndroid Build Coastguard Worker 		_cupsLangPrintf(stdout,
3547*5e7646d2SAndroid Build Coastguard Worker 				_("      %s  Bad UTF-8 \"%s\" "
3548*5e7646d2SAndroid Build Coastguard Worker 				  "translation string for option %s, "
3549*5e7646d2SAndroid Build Coastguard Worker 				  "choice %s."),
3550*5e7646d2SAndroid Build Coastguard Worker 				prefix, language,
3551*5e7646d2SAndroid Build Coastguard Worker 				ckeyword + 1 + strlen(language),
3552*5e7646d2SAndroid Build Coastguard Worker 				"True");
3553*5e7646d2SAndroid Build Coastguard Worker 
3554*5e7646d2SAndroid Build Coastguard Worker               if (!warn)
3555*5e7646d2SAndroid Build Coastguard Worker 		errors ++;
3556*5e7646d2SAndroid Build Coastguard Worker 	    }
3557*5e7646d2SAndroid Build Coastguard Worker 
3558*5e7646d2SAndroid Build Coastguard Worker 	    if (_cups_strcasecmp(option->keyword, "PageSize"))
3559*5e7646d2SAndroid Build Coastguard Worker 	    {
3560*5e7646d2SAndroid Build Coastguard Worker 	      for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params);
3561*5e7646d2SAndroid Build Coastguard Worker 		   cparam;
3562*5e7646d2SAndroid Build Coastguard Worker 		   cparam = (ppd_cparam_t *)cupsArrayNext(coption->params))
3563*5e7646d2SAndroid Build Coastguard Worker 	      {
3564*5e7646d2SAndroid Build Coastguard Worker 		snprintf(ckeyword, sizeof(ckeyword), "%s.ParamCustom%s",
3565*5e7646d2SAndroid Build Coastguard Worker 			 language, option->keyword);
3566*5e7646d2SAndroid Build Coastguard Worker 		snprintf(cllkeyword, sizeof(cllkeyword), "%s.ParamCustom%s",
3567*5e7646d2SAndroid Build Coastguard Worker 			 ll, option->keyword);
3568*5e7646d2SAndroid Build Coastguard Worker 
3569*5e7646d2SAndroid Build Coastguard Worker 		if ((attr = ppdFindAttr(ppd, ckeyword,
3570*5e7646d2SAndroid Build Coastguard Worker 					cparam->name)) == NULL &&
3571*5e7646d2SAndroid Build Coastguard Worker 		    (attr = ppdFindAttr(ppd, cllkeyword,
3572*5e7646d2SAndroid Build Coastguard Worker 					cparam->name)) == NULL)
3573*5e7646d2SAndroid Build Coastguard Worker 		{
3574*5e7646d2SAndroid Build Coastguard Worker 		  if (!warn && !errors && !verbose)
3575*5e7646d2SAndroid Build Coastguard Worker 		    _cupsLangPuts(stdout, _(" FAIL"));
3576*5e7646d2SAndroid Build Coastguard Worker 
3577*5e7646d2SAndroid Build Coastguard Worker 		  if (verbose >= 0)
3578*5e7646d2SAndroid Build Coastguard Worker 		    _cupsLangPrintf(stdout,
3579*5e7646d2SAndroid Build Coastguard Worker 				    _("      %s  Missing \"%s\" "
3580*5e7646d2SAndroid Build Coastguard Worker 				      "translation string for option %s, "
3581*5e7646d2SAndroid Build Coastguard Worker 				      "choice %s."),
3582*5e7646d2SAndroid Build Coastguard Worker 				    prefix, language,
3583*5e7646d2SAndroid Build Coastguard Worker 				    ckeyword + 1 + strlen(language),
3584*5e7646d2SAndroid Build Coastguard Worker 				    cparam->name);
3585*5e7646d2SAndroid Build Coastguard Worker 
3586*5e7646d2SAndroid Build Coastguard Worker                   if (!warn)
3587*5e7646d2SAndroid Build Coastguard Worker 		    errors ++;
3588*5e7646d2SAndroid Build Coastguard Worker 		}
3589*5e7646d2SAndroid Build Coastguard Worker 		else if (!valid_utf8(attr->text))
3590*5e7646d2SAndroid Build Coastguard Worker 		{
3591*5e7646d2SAndroid Build Coastguard Worker 		  if (!warn && !errors && !verbose)
3592*5e7646d2SAndroid Build Coastguard Worker 		    _cupsLangPuts(stdout, _(" FAIL"));
3593*5e7646d2SAndroid Build Coastguard Worker 
3594*5e7646d2SAndroid Build Coastguard Worker 		  if (verbose >= 0)
3595*5e7646d2SAndroid Build Coastguard Worker 		    _cupsLangPrintf(stdout,
3596*5e7646d2SAndroid Build Coastguard Worker 				    _("      %s  Bad UTF-8 \"%s\" "
3597*5e7646d2SAndroid Build Coastguard Worker 				      "translation string for option %s, "
3598*5e7646d2SAndroid Build Coastguard Worker 				      "choice %s."),
3599*5e7646d2SAndroid Build Coastguard Worker 				    prefix, language,
3600*5e7646d2SAndroid Build Coastguard Worker 				    ckeyword + 1 + strlen(language),
3601*5e7646d2SAndroid Build Coastguard Worker 				    cparam->name);
3602*5e7646d2SAndroid Build Coastguard Worker 
3603*5e7646d2SAndroid Build Coastguard Worker 		  if (!warn)
3604*5e7646d2SAndroid Build Coastguard Worker 		    errors ++;
3605*5e7646d2SAndroid Build Coastguard Worker 		}
3606*5e7646d2SAndroid Build Coastguard Worker 	      }
3607*5e7646d2SAndroid Build Coastguard Worker 	    }
3608*5e7646d2SAndroid Build Coastguard Worker 	  }
3609*5e7646d2SAndroid Build Coastguard Worker 	  else if ((attr = ppdFindAttr(ppd, keyword,
3610*5e7646d2SAndroid Build Coastguard Worker 				       option->choices[j].choice)) == NULL &&
3611*5e7646d2SAndroid Build Coastguard Worker 		   (attr = ppdFindAttr(ppd, llkeyword,
3612*5e7646d2SAndroid Build Coastguard Worker 				       option->choices[j].choice)) == NULL)
3613*5e7646d2SAndroid Build Coastguard Worker 	  {
3614*5e7646d2SAndroid Build Coastguard Worker 	    if (!warn && !errors && !verbose)
3615*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPuts(stdout, _(" FAIL"));
3616*5e7646d2SAndroid Build Coastguard Worker 
3617*5e7646d2SAndroid Build Coastguard Worker 	    if (verbose >= 0)
3618*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPrintf(stdout,
3619*5e7646d2SAndroid Build Coastguard Worker 			      _("      %s  Missing \"%s\" "
3620*5e7646d2SAndroid Build Coastguard Worker 				"translation string for option %s, "
3621*5e7646d2SAndroid Build Coastguard Worker 				"choice %s."),
3622*5e7646d2SAndroid Build Coastguard Worker 			      prefix, language, option->keyword,
3623*5e7646d2SAndroid Build Coastguard Worker 			      option->choices[j].choice);
3624*5e7646d2SAndroid Build Coastguard Worker 
3625*5e7646d2SAndroid Build Coastguard Worker 	    if (!warn)
3626*5e7646d2SAndroid Build Coastguard Worker 	      errors ++;
3627*5e7646d2SAndroid Build Coastguard Worker 	  }
3628*5e7646d2SAndroid Build Coastguard Worker 	  else if (!valid_utf8(attr->text))
3629*5e7646d2SAndroid Build Coastguard Worker 	  {
3630*5e7646d2SAndroid Build Coastguard Worker 	    if (!warn && !errors && !verbose)
3631*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPuts(stdout, _(" FAIL"));
3632*5e7646d2SAndroid Build Coastguard Worker 
3633*5e7646d2SAndroid Build Coastguard Worker 	    if (verbose >= 0)
3634*5e7646d2SAndroid Build Coastguard Worker 	      _cupsLangPrintf(stdout,
3635*5e7646d2SAndroid Build Coastguard Worker 			      _("      %s  Bad UTF-8 \"%s\" "
3636*5e7646d2SAndroid Build Coastguard Worker 				"translation string for option %s, "
3637*5e7646d2SAndroid Build Coastguard Worker 				"choice %s."),
3638*5e7646d2SAndroid Build Coastguard Worker 			      prefix, language, option->keyword,
3639*5e7646d2SAndroid Build Coastguard Worker 			      option->choices[j].choice);
3640*5e7646d2SAndroid Build Coastguard Worker 
3641*5e7646d2SAndroid Build Coastguard Worker 	    if (!warn)
3642*5e7646d2SAndroid Build Coastguard Worker 	      errors ++;
3643*5e7646d2SAndroid Build Coastguard Worker 	  }
3644*5e7646d2SAndroid Build Coastguard Worker 	}
3645*5e7646d2SAndroid Build Coastguard Worker       }
3646*5e7646d2SAndroid Build Coastguard Worker     }
3647*5e7646d2SAndroid Build Coastguard Worker 
3648*5e7646d2SAndroid Build Coastguard Worker    /*
3649*5e7646d2SAndroid Build Coastguard Worker     * Verify that we have the base language for each localized one...
3650*5e7646d2SAndroid Build Coastguard Worker     */
3651*5e7646d2SAndroid Build Coastguard Worker 
3652*5e7646d2SAndroid Build Coastguard Worker     for (language = (char *)cupsArrayFirst(languages);
3653*5e7646d2SAndroid Build Coastguard Worker 	 language;
3654*5e7646d2SAndroid Build Coastguard Worker 	 language = (char *)cupsArrayNext(languages))
3655*5e7646d2SAndroid Build Coastguard Worker       if (language[2])
3656*5e7646d2SAndroid Build Coastguard Worker       {
3657*5e7646d2SAndroid Build Coastguard Worker        /*
3658*5e7646d2SAndroid Build Coastguard Worker 	* Lookup the base language...
3659*5e7646d2SAndroid Build Coastguard Worker 	*/
3660*5e7646d2SAndroid Build Coastguard Worker 
3661*5e7646d2SAndroid Build Coastguard Worker 	cupsArraySave(languages);
3662*5e7646d2SAndroid Build Coastguard Worker 
3663*5e7646d2SAndroid Build Coastguard Worker 	strlcpy(ll, language, sizeof(ll));
3664*5e7646d2SAndroid Build Coastguard Worker 
3665*5e7646d2SAndroid Build Coastguard Worker 	if (!cupsArrayFind(languages, ll) &&
3666*5e7646d2SAndroid Build Coastguard Worker 	    strcmp(ll, "zh") && strcmp(ll, "en"))
3667*5e7646d2SAndroid Build Coastguard Worker 	{
3668*5e7646d2SAndroid Build Coastguard Worker 	  if (!warn && !errors && !verbose)
3669*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPuts(stdout, _(" FAIL"));
3670*5e7646d2SAndroid Build Coastguard Worker 
3671*5e7646d2SAndroid Build Coastguard Worker 	  if (verbose >= 0)
3672*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPrintf(stdout,
3673*5e7646d2SAndroid Build Coastguard Worker 			    _("      %s  No base translation \"%s\" "
3674*5e7646d2SAndroid Build Coastguard Worker 			      "is included in file."), prefix, ll);
3675*5e7646d2SAndroid Build Coastguard Worker 
3676*5e7646d2SAndroid Build Coastguard Worker 	  if (!warn)
3677*5e7646d2SAndroid Build Coastguard Worker 	    errors ++;
3678*5e7646d2SAndroid Build Coastguard Worker 	}
3679*5e7646d2SAndroid Build Coastguard Worker 
3680*5e7646d2SAndroid Build Coastguard Worker 	cupsArrayRestore(languages);
3681*5e7646d2SAndroid Build Coastguard Worker       }
3682*5e7646d2SAndroid Build Coastguard Worker 
3683*5e7646d2SAndroid Build Coastguard Worker    /*
3684*5e7646d2SAndroid Build Coastguard Worker     * Free memory used for the languages...
3685*5e7646d2SAndroid Build Coastguard Worker     */
3686*5e7646d2SAndroid Build Coastguard Worker 
3687*5e7646d2SAndroid Build Coastguard Worker     _ppdFreeLanguages(languages);
3688*5e7646d2SAndroid Build Coastguard Worker   }
3689*5e7646d2SAndroid Build Coastguard Worker 
3690*5e7646d2SAndroid Build Coastguard Worker   return (errors);
3691*5e7646d2SAndroid Build Coastguard Worker }
3692*5e7646d2SAndroid Build Coastguard Worker 
3693*5e7646d2SAndroid Build Coastguard Worker 
3694*5e7646d2SAndroid Build Coastguard Worker /*
3695*5e7646d2SAndroid Build Coastguard Worker  * 'show_conflicts()' - Show option conflicts in a PPD file.
3696*5e7646d2SAndroid Build Coastguard Worker  */
3697*5e7646d2SAndroid Build Coastguard Worker 
3698*5e7646d2SAndroid Build Coastguard Worker static void
show_conflicts(ppd_file_t * ppd,const char * prefix)3699*5e7646d2SAndroid Build Coastguard Worker show_conflicts(ppd_file_t *ppd,		/* I - PPD to check */
3700*5e7646d2SAndroid Build Coastguard Worker                const char *prefix)	/* I - Prefix string */
3701*5e7646d2SAndroid Build Coastguard Worker {
3702*5e7646d2SAndroid Build Coastguard Worker   int		i, j;			/* Looping variables */
3703*5e7646d2SAndroid Build Coastguard Worker   ppd_const_t	*c;			/* Current constraint */
3704*5e7646d2SAndroid Build Coastguard Worker   ppd_option_t	*o1, *o2;		/* Options */
3705*5e7646d2SAndroid Build Coastguard Worker   ppd_choice_t	*c1, *c2;		/* Choices */
3706*5e7646d2SAndroid Build Coastguard Worker 
3707*5e7646d2SAndroid Build Coastguard Worker 
3708*5e7646d2SAndroid Build Coastguard Worker  /*
3709*5e7646d2SAndroid Build Coastguard Worker   * Loop through all of the UI constraints and report any options
3710*5e7646d2SAndroid Build Coastguard Worker   * that conflict...
3711*5e7646d2SAndroid Build Coastguard Worker   */
3712*5e7646d2SAndroid Build Coastguard Worker 
3713*5e7646d2SAndroid Build Coastguard Worker   for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++)
3714*5e7646d2SAndroid Build Coastguard Worker   {
3715*5e7646d2SAndroid Build Coastguard Worker    /*
3716*5e7646d2SAndroid Build Coastguard Worker     * Grab pointers to the first option...
3717*5e7646d2SAndroid Build Coastguard Worker     */
3718*5e7646d2SAndroid Build Coastguard Worker 
3719*5e7646d2SAndroid Build Coastguard Worker     o1 = ppdFindOption(ppd, c->option1);
3720*5e7646d2SAndroid Build Coastguard Worker 
3721*5e7646d2SAndroid Build Coastguard Worker     if (o1 == NULL)
3722*5e7646d2SAndroid Build Coastguard Worker       continue;
3723*5e7646d2SAndroid Build Coastguard Worker     else if (c->choice1[0] != '\0')
3724*5e7646d2SAndroid Build Coastguard Worker     {
3725*5e7646d2SAndroid Build Coastguard Worker      /*
3726*5e7646d2SAndroid Build Coastguard Worker       * This constraint maps to a specific choice.
3727*5e7646d2SAndroid Build Coastguard Worker       */
3728*5e7646d2SAndroid Build Coastguard Worker 
3729*5e7646d2SAndroid Build Coastguard Worker       c1 = ppdFindChoice(o1, c->choice1);
3730*5e7646d2SAndroid Build Coastguard Worker     }
3731*5e7646d2SAndroid Build Coastguard Worker     else
3732*5e7646d2SAndroid Build Coastguard Worker     {
3733*5e7646d2SAndroid Build Coastguard Worker      /*
3734*5e7646d2SAndroid Build Coastguard Worker       * This constraint applies to any choice for this option.
3735*5e7646d2SAndroid Build Coastguard Worker       */
3736*5e7646d2SAndroid Build Coastguard Worker 
3737*5e7646d2SAndroid Build Coastguard Worker       for (j = o1->num_choices, c1 = o1->choices; j > 0; j --, c1 ++)
3738*5e7646d2SAndroid Build Coastguard Worker         if (c1->marked)
3739*5e7646d2SAndroid Build Coastguard Worker 	  break;
3740*5e7646d2SAndroid Build Coastguard Worker 
3741*5e7646d2SAndroid Build Coastguard Worker       if (j == 0 ||
3742*5e7646d2SAndroid Build Coastguard Worker           !_cups_strcasecmp(c1->choice, "None") ||
3743*5e7646d2SAndroid Build Coastguard Worker           !_cups_strcasecmp(c1->choice, "Off") ||
3744*5e7646d2SAndroid Build Coastguard Worker           !_cups_strcasecmp(c1->choice, "False"))
3745*5e7646d2SAndroid Build Coastguard Worker         c1 = NULL;
3746*5e7646d2SAndroid Build Coastguard Worker     }
3747*5e7646d2SAndroid Build Coastguard Worker 
3748*5e7646d2SAndroid Build Coastguard Worker    /*
3749*5e7646d2SAndroid Build Coastguard Worker     * Grab pointers to the second option...
3750*5e7646d2SAndroid Build Coastguard Worker     */
3751*5e7646d2SAndroid Build Coastguard Worker 
3752*5e7646d2SAndroid Build Coastguard Worker     o2 = ppdFindOption(ppd, c->option2);
3753*5e7646d2SAndroid Build Coastguard Worker 
3754*5e7646d2SAndroid Build Coastguard Worker     if (o2 == NULL)
3755*5e7646d2SAndroid Build Coastguard Worker       continue;
3756*5e7646d2SAndroid Build Coastguard Worker     else if (c->choice2[0] != '\0')
3757*5e7646d2SAndroid Build Coastguard Worker     {
3758*5e7646d2SAndroid Build Coastguard Worker      /*
3759*5e7646d2SAndroid Build Coastguard Worker       * This constraint maps to a specific choice.
3760*5e7646d2SAndroid Build Coastguard Worker       */
3761*5e7646d2SAndroid Build Coastguard Worker 
3762*5e7646d2SAndroid Build Coastguard Worker       c2 = ppdFindChoice(o2, c->choice2);
3763*5e7646d2SAndroid Build Coastguard Worker     }
3764*5e7646d2SAndroid Build Coastguard Worker     else
3765*5e7646d2SAndroid Build Coastguard Worker     {
3766*5e7646d2SAndroid Build Coastguard Worker      /*
3767*5e7646d2SAndroid Build Coastguard Worker       * This constraint applies to any choice for this option.
3768*5e7646d2SAndroid Build Coastguard Worker       */
3769*5e7646d2SAndroid Build Coastguard Worker 
3770*5e7646d2SAndroid Build Coastguard Worker       for (j = o2->num_choices, c2 = o2->choices; j > 0; j --, c2 ++)
3771*5e7646d2SAndroid Build Coastguard Worker         if (c2->marked)
3772*5e7646d2SAndroid Build Coastguard Worker 	  break;
3773*5e7646d2SAndroid Build Coastguard Worker 
3774*5e7646d2SAndroid Build Coastguard Worker       if (j == 0 ||
3775*5e7646d2SAndroid Build Coastguard Worker           !_cups_strcasecmp(c2->choice, "None") ||
3776*5e7646d2SAndroid Build Coastguard Worker           !_cups_strcasecmp(c2->choice, "Off") ||
3777*5e7646d2SAndroid Build Coastguard Worker           !_cups_strcasecmp(c2->choice, "False"))
3778*5e7646d2SAndroid Build Coastguard Worker         c2 = NULL;
3779*5e7646d2SAndroid Build Coastguard Worker     }
3780*5e7646d2SAndroid Build Coastguard Worker 
3781*5e7646d2SAndroid Build Coastguard Worker    /*
3782*5e7646d2SAndroid Build Coastguard Worker     * If both options are marked then there is a conflict...
3783*5e7646d2SAndroid Build Coastguard Worker     */
3784*5e7646d2SAndroid Build Coastguard Worker 
3785*5e7646d2SAndroid Build Coastguard Worker     if (c1 != NULL && c1->marked && c2 != NULL && c2->marked)
3786*5e7646d2SAndroid Build Coastguard Worker       _cupsLangPrintf(stdout,
3787*5e7646d2SAndroid Build Coastguard Worker                       _("      %s  \"%s %s\" conflicts with \"%s %s\"\n"
3788*5e7646d2SAndroid Build Coastguard Worker                         "                (constraint=\"%s %s %s %s\")."),
3789*5e7646d2SAndroid Build Coastguard Worker         	      prefix, o1->keyword, c1->choice, o2->keyword, c2->choice,
3790*5e7646d2SAndroid Build Coastguard Worker 		      c->option1, c->choice1, c->option2, c->choice2);
3791*5e7646d2SAndroid Build Coastguard Worker   }
3792*5e7646d2SAndroid Build Coastguard Worker }
3793*5e7646d2SAndroid Build Coastguard Worker 
3794*5e7646d2SAndroid Build Coastguard Worker 
3795*5e7646d2SAndroid Build Coastguard Worker /*
3796*5e7646d2SAndroid Build Coastguard Worker  * 'test_raster()' - Test PostScript commands for raster printers.
3797*5e7646d2SAndroid Build Coastguard Worker  */
3798*5e7646d2SAndroid Build Coastguard Worker 
3799*5e7646d2SAndroid Build Coastguard Worker static int				/* O - 1 on success, 0 on failure */
test_raster(ppd_file_t * ppd,int verbose)3800*5e7646d2SAndroid Build Coastguard Worker test_raster(ppd_file_t *ppd,		/* I - PPD file */
3801*5e7646d2SAndroid Build Coastguard Worker             int        verbose)		/* I - Verbosity */
3802*5e7646d2SAndroid Build Coastguard Worker {
3803*5e7646d2SAndroid Build Coastguard Worker   cups_page_header2_t	header;		/* Page header */
3804*5e7646d2SAndroid Build Coastguard Worker 
3805*5e7646d2SAndroid Build Coastguard Worker 
3806*5e7646d2SAndroid Build Coastguard Worker   ppdMarkDefaults(ppd);
3807*5e7646d2SAndroid Build Coastguard Worker   if (cupsRasterInterpretPPD(&header, ppd, 0, NULL, 0))
3808*5e7646d2SAndroid Build Coastguard Worker   {
3809*5e7646d2SAndroid Build Coastguard Worker     if (!verbose)
3810*5e7646d2SAndroid Build Coastguard Worker       _cupsLangPuts(stdout, _(" FAIL"));
3811*5e7646d2SAndroid Build Coastguard Worker 
3812*5e7646d2SAndroid Build Coastguard Worker     if (verbose >= 0)
3813*5e7646d2SAndroid Build Coastguard Worker       _cupsLangPrintf(stdout,
3814*5e7646d2SAndroid Build Coastguard Worker 		      _("      **FAIL**  Default option code cannot be "
3815*5e7646d2SAndroid Build Coastguard Worker 			"interpreted: %s"), cupsRasterErrorString());
3816*5e7646d2SAndroid Build Coastguard Worker 
3817*5e7646d2SAndroid Build Coastguard Worker     return (0);
3818*5e7646d2SAndroid Build Coastguard Worker   }
3819*5e7646d2SAndroid Build Coastguard Worker 
3820*5e7646d2SAndroid Build Coastguard Worker  /*
3821*5e7646d2SAndroid Build Coastguard Worker   * Try a test of custom page size code, if available...
3822*5e7646d2SAndroid Build Coastguard Worker   */
3823*5e7646d2SAndroid Build Coastguard Worker 
3824*5e7646d2SAndroid Build Coastguard Worker   if (!ppdPageSize(ppd, "Custom.612x792"))
3825*5e7646d2SAndroid Build Coastguard Worker     return (1);
3826*5e7646d2SAndroid Build Coastguard Worker 
3827*5e7646d2SAndroid Build Coastguard Worker   ppdMarkOption(ppd, "PageSize", "Custom.612x792");
3828*5e7646d2SAndroid Build Coastguard Worker 
3829*5e7646d2SAndroid Build Coastguard Worker   if (cupsRasterInterpretPPD(&header, ppd, 0, NULL, 0))
3830*5e7646d2SAndroid Build Coastguard Worker   {
3831*5e7646d2SAndroid Build Coastguard Worker     if (!verbose)
3832*5e7646d2SAndroid Build Coastguard Worker       _cupsLangPuts(stdout, _(" FAIL"));
3833*5e7646d2SAndroid Build Coastguard Worker 
3834*5e7646d2SAndroid Build Coastguard Worker     if (verbose >= 0)
3835*5e7646d2SAndroid Build Coastguard Worker       _cupsLangPrintf(stdout,
3836*5e7646d2SAndroid Build Coastguard Worker 		      _("      **FAIL**  Default option code cannot be "
3837*5e7646d2SAndroid Build Coastguard Worker 			"interpreted: %s"), cupsRasterErrorString());
3838*5e7646d2SAndroid Build Coastguard Worker 
3839*5e7646d2SAndroid Build Coastguard Worker     return (0);
3840*5e7646d2SAndroid Build Coastguard Worker   }
3841*5e7646d2SAndroid Build Coastguard Worker 
3842*5e7646d2SAndroid Build Coastguard Worker   return (1);
3843*5e7646d2SAndroid Build Coastguard Worker }
3844*5e7646d2SAndroid Build Coastguard Worker 
3845*5e7646d2SAndroid Build Coastguard Worker 
3846*5e7646d2SAndroid Build Coastguard Worker /*
3847*5e7646d2SAndroid Build Coastguard Worker  * 'usage()' - Show program usage.
3848*5e7646d2SAndroid Build Coastguard Worker  */
3849*5e7646d2SAndroid Build Coastguard Worker 
3850*5e7646d2SAndroid Build Coastguard Worker static void
usage(void)3851*5e7646d2SAndroid Build Coastguard Worker usage(void)
3852*5e7646d2SAndroid Build Coastguard Worker {
3853*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("Warning: This program will be removed in a future version of CUPS."));
3854*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n"
3855*5e7646d2SAndroid Build Coastguard Worker 		          "       program | cupstestppd [options] -"));
3856*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("Options:"));
3857*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-I {filename,filters,none,profiles}\n"
3858*5e7646d2SAndroid Build Coastguard Worker                           "                          Ignore specific warnings"));
3859*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-R root-directory       Set alternate root"));
3860*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-W {all,none,constraints,defaults,duplex,filters,profiles,sizes,translations}\n"
3861*5e7646d2SAndroid Build Coastguard Worker                           "                          Issue warnings instead of errors"));
3862*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-q                      Run silently"));
3863*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-r                      Use 'relaxed' open mode"));
3864*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-v                      Be verbose"));
3865*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("-vv                     Be very verbose"));
3866*5e7646d2SAndroid Build Coastguard Worker 
3867*5e7646d2SAndroid Build Coastguard Worker   exit(ERROR_USAGE);
3868*5e7646d2SAndroid Build Coastguard Worker }
3869*5e7646d2SAndroid Build Coastguard Worker 
3870*5e7646d2SAndroid Build Coastguard Worker 
3871*5e7646d2SAndroid Build Coastguard Worker /*
3872*5e7646d2SAndroid Build Coastguard Worker  * 'valid_path()' - Check whether a path has the correct capitalization.
3873*5e7646d2SAndroid Build Coastguard Worker  */
3874*5e7646d2SAndroid Build Coastguard Worker 
3875*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Errors found */
valid_path(const char * keyword,const char * path,int errors,int verbose,int warn)3876*5e7646d2SAndroid Build Coastguard Worker valid_path(const char *keyword,		/* I - Keyword using path */
3877*5e7646d2SAndroid Build Coastguard Worker            const char *path,		/* I - Path to check */
3878*5e7646d2SAndroid Build Coastguard Worker 	   int        errors,		/* I - Errors found */
3879*5e7646d2SAndroid Build Coastguard Worker 	   int        verbose,		/* I - Verbosity level */
3880*5e7646d2SAndroid Build Coastguard Worker 	   int        warn)		/* I - Warnings only? */
3881*5e7646d2SAndroid Build Coastguard Worker {
3882*5e7646d2SAndroid Build Coastguard Worker   cups_dir_t	*dir;			/* Current directory */
3883*5e7646d2SAndroid Build Coastguard Worker   cups_dentry_t	*dentry;		/* Current directory entry */
3884*5e7646d2SAndroid Build Coastguard Worker   char		temp[1024],		/* Temporary path */
3885*5e7646d2SAndroid Build Coastguard Worker 		*ptr;			/* Pointer into temporary path */
3886*5e7646d2SAndroid Build Coastguard Worker   const char	*prefix;		/* WARN/FAIL prefix */
3887*5e7646d2SAndroid Build Coastguard Worker 
3888*5e7646d2SAndroid Build Coastguard Worker 
3889*5e7646d2SAndroid Build Coastguard Worker   prefix = warn ? "  WARN  " : "**FAIL**";
3890*5e7646d2SAndroid Build Coastguard Worker 
3891*5e7646d2SAndroid Build Coastguard Worker  /*
3892*5e7646d2SAndroid Build Coastguard Worker   * Loop over the components of the path, checking that the entry exists with
3893*5e7646d2SAndroid Build Coastguard Worker   * the same capitalization...
3894*5e7646d2SAndroid Build Coastguard Worker   */
3895*5e7646d2SAndroid Build Coastguard Worker 
3896*5e7646d2SAndroid Build Coastguard Worker   strlcpy(temp, path, sizeof(temp));
3897*5e7646d2SAndroid Build Coastguard Worker 
3898*5e7646d2SAndroid Build Coastguard Worker   while ((ptr = strrchr(temp, '/')) != NULL)
3899*5e7646d2SAndroid Build Coastguard Worker   {
3900*5e7646d2SAndroid Build Coastguard Worker    /*
3901*5e7646d2SAndroid Build Coastguard Worker     * Chop off the trailing component so temp == dirname and ptr == basename.
3902*5e7646d2SAndroid Build Coastguard Worker     */
3903*5e7646d2SAndroid Build Coastguard Worker 
3904*5e7646d2SAndroid Build Coastguard Worker     *ptr++ = '\0';
3905*5e7646d2SAndroid Build Coastguard Worker 
3906*5e7646d2SAndroid Build Coastguard Worker    /*
3907*5e7646d2SAndroid Build Coastguard Worker     * Try opening the directory containing the base name...
3908*5e7646d2SAndroid Build Coastguard Worker     */
3909*5e7646d2SAndroid Build Coastguard Worker 
3910*5e7646d2SAndroid Build Coastguard Worker     if (temp[0])
3911*5e7646d2SAndroid Build Coastguard Worker       dir = cupsDirOpen(temp);
3912*5e7646d2SAndroid Build Coastguard Worker     else
3913*5e7646d2SAndroid Build Coastguard Worker       dir = cupsDirOpen("/");
3914*5e7646d2SAndroid Build Coastguard Worker 
3915*5e7646d2SAndroid Build Coastguard Worker     if (!dir)
3916*5e7646d2SAndroid Build Coastguard Worker       dentry = NULL;
3917*5e7646d2SAndroid Build Coastguard Worker     else
3918*5e7646d2SAndroid Build Coastguard Worker     {
3919*5e7646d2SAndroid Build Coastguard Worker       while ((dentry = cupsDirRead(dir)) != NULL)
3920*5e7646d2SAndroid Build Coastguard Worker       {
3921*5e7646d2SAndroid Build Coastguard Worker         if (!strcmp(dentry->filename, ptr))
3922*5e7646d2SAndroid Build Coastguard Worker 	  break;
3923*5e7646d2SAndroid Build Coastguard Worker       }
3924*5e7646d2SAndroid Build Coastguard Worker 
3925*5e7646d2SAndroid Build Coastguard Worker       cupsDirClose(dir);
3926*5e7646d2SAndroid Build Coastguard Worker     }
3927*5e7646d2SAndroid Build Coastguard Worker 
3928*5e7646d2SAndroid Build Coastguard Worker    /*
3929*5e7646d2SAndroid Build Coastguard Worker     * Display an error if the filename doesn't exist with the same
3930*5e7646d2SAndroid Build Coastguard Worker     * capitalization...
3931*5e7646d2SAndroid Build Coastguard Worker     */
3932*5e7646d2SAndroid Build Coastguard Worker 
3933*5e7646d2SAndroid Build Coastguard Worker     if (!dentry)
3934*5e7646d2SAndroid Build Coastguard Worker     {
3935*5e7646d2SAndroid Build Coastguard Worker       if (!warn && !errors && !verbose)
3936*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPuts(stdout, _(" FAIL"));
3937*5e7646d2SAndroid Build Coastguard Worker 
3938*5e7646d2SAndroid Build Coastguard Worker       if (verbose >= 0)
3939*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stdout,
3940*5e7646d2SAndroid Build Coastguard Worker 			_("      %s  %s file \"%s\" has the wrong "
3941*5e7646d2SAndroid Build Coastguard Worker 			  "capitalization."), prefix, keyword, path);
3942*5e7646d2SAndroid Build Coastguard Worker 
3943*5e7646d2SAndroid Build Coastguard Worker       if (!warn)
3944*5e7646d2SAndroid Build Coastguard Worker 	errors ++;
3945*5e7646d2SAndroid Build Coastguard Worker 
3946*5e7646d2SAndroid Build Coastguard Worker       break;
3947*5e7646d2SAndroid Build Coastguard Worker     }
3948*5e7646d2SAndroid Build Coastguard Worker   }
3949*5e7646d2SAndroid Build Coastguard Worker 
3950*5e7646d2SAndroid Build Coastguard Worker   return (errors);
3951*5e7646d2SAndroid Build Coastguard Worker }
3952*5e7646d2SAndroid Build Coastguard Worker 
3953*5e7646d2SAndroid Build Coastguard Worker 
3954*5e7646d2SAndroid Build Coastguard Worker /*
3955*5e7646d2SAndroid Build Coastguard Worker  * 'valid_utf8()' - Check whether a string contains valid UTF-8 text.
3956*5e7646d2SAndroid Build Coastguard Worker  */
3957*5e7646d2SAndroid Build Coastguard Worker 
3958*5e7646d2SAndroid Build Coastguard Worker static int				/* O - 1 if valid, 0 if not */
valid_utf8(const char * s)3959*5e7646d2SAndroid Build Coastguard Worker valid_utf8(const char *s)		/* I - String to check */
3960*5e7646d2SAndroid Build Coastguard Worker {
3961*5e7646d2SAndroid Build Coastguard Worker   while (*s)
3962*5e7646d2SAndroid Build Coastguard Worker   {
3963*5e7646d2SAndroid Build Coastguard Worker     if (*s & 0x80)
3964*5e7646d2SAndroid Build Coastguard Worker     {
3965*5e7646d2SAndroid Build Coastguard Worker      /*
3966*5e7646d2SAndroid Build Coastguard Worker       * Check for valid UTF-8 sequence...
3967*5e7646d2SAndroid Build Coastguard Worker       */
3968*5e7646d2SAndroid Build Coastguard Worker 
3969*5e7646d2SAndroid Build Coastguard Worker       if ((*s & 0xc0) == 0x80)
3970*5e7646d2SAndroid Build Coastguard Worker         return (0);			/* Illegal suffix byte */
3971*5e7646d2SAndroid Build Coastguard Worker       else if ((*s & 0xe0) == 0xc0)
3972*5e7646d2SAndroid Build Coastguard Worker       {
3973*5e7646d2SAndroid Build Coastguard Worker        /*
3974*5e7646d2SAndroid Build Coastguard Worker         * 2-byte sequence...
3975*5e7646d2SAndroid Build Coastguard Worker         */
3976*5e7646d2SAndroid Build Coastguard Worker 
3977*5e7646d2SAndroid Build Coastguard Worker         s ++;
3978*5e7646d2SAndroid Build Coastguard Worker 
3979*5e7646d2SAndroid Build Coastguard Worker         if ((*s & 0xc0) != 0x80)
3980*5e7646d2SAndroid Build Coastguard Worker           return (0);			/* Missing suffix byte */
3981*5e7646d2SAndroid Build Coastguard Worker       }
3982*5e7646d2SAndroid Build Coastguard Worker       else if ((*s & 0xf0) == 0xe0)
3983*5e7646d2SAndroid Build Coastguard Worker       {
3984*5e7646d2SAndroid Build Coastguard Worker        /*
3985*5e7646d2SAndroid Build Coastguard Worker         * 3-byte sequence...
3986*5e7646d2SAndroid Build Coastguard Worker         */
3987*5e7646d2SAndroid Build Coastguard Worker 
3988*5e7646d2SAndroid Build Coastguard Worker         s ++;
3989*5e7646d2SAndroid Build Coastguard Worker 
3990*5e7646d2SAndroid Build Coastguard Worker         if ((*s & 0xc0) != 0x80)
3991*5e7646d2SAndroid Build Coastguard Worker           return (0);			/* Missing suffix byte */
3992*5e7646d2SAndroid Build Coastguard Worker 
3993*5e7646d2SAndroid Build Coastguard Worker         s ++;
3994*5e7646d2SAndroid Build Coastguard Worker 
3995*5e7646d2SAndroid Build Coastguard Worker         if ((*s & 0xc0) != 0x80)
3996*5e7646d2SAndroid Build Coastguard Worker           return (0);			/* Missing suffix byte */
3997*5e7646d2SAndroid Build Coastguard Worker       }
3998*5e7646d2SAndroid Build Coastguard Worker       else if ((*s & 0xf8) == 0xf0)
3999*5e7646d2SAndroid Build Coastguard Worker       {
4000*5e7646d2SAndroid Build Coastguard Worker        /*
4001*5e7646d2SAndroid Build Coastguard Worker         * 4-byte sequence...
4002*5e7646d2SAndroid Build Coastguard Worker         */
4003*5e7646d2SAndroid Build Coastguard Worker 
4004*5e7646d2SAndroid Build Coastguard Worker         s ++;
4005*5e7646d2SAndroid Build Coastguard Worker 
4006*5e7646d2SAndroid Build Coastguard Worker         if ((*s & 0xc0) != 0x80)
4007*5e7646d2SAndroid Build Coastguard Worker           return (0);			/* Missing suffix byte */
4008*5e7646d2SAndroid Build Coastguard Worker 
4009*5e7646d2SAndroid Build Coastguard Worker         s ++;
4010*5e7646d2SAndroid Build Coastguard Worker 
4011*5e7646d2SAndroid Build Coastguard Worker         if ((*s & 0xc0) != 0x80)
4012*5e7646d2SAndroid Build Coastguard Worker           return (0);			/* Missing suffix byte */
4013*5e7646d2SAndroid Build Coastguard Worker 
4014*5e7646d2SAndroid Build Coastguard Worker         s ++;
4015*5e7646d2SAndroid Build Coastguard Worker 
4016*5e7646d2SAndroid Build Coastguard Worker         if ((*s & 0xc0) != 0x80)
4017*5e7646d2SAndroid Build Coastguard Worker           return (0);			/* Missing suffix byte */
4018*5e7646d2SAndroid Build Coastguard Worker       }
4019*5e7646d2SAndroid Build Coastguard Worker       else
4020*5e7646d2SAndroid Build Coastguard Worker         return (0);			/* Bad sequence */
4021*5e7646d2SAndroid Build Coastguard Worker     }
4022*5e7646d2SAndroid Build Coastguard Worker 
4023*5e7646d2SAndroid Build Coastguard Worker     s ++;
4024*5e7646d2SAndroid Build Coastguard Worker   }
4025*5e7646d2SAndroid Build Coastguard Worker 
4026*5e7646d2SAndroid Build Coastguard Worker   return (1);
4027*5e7646d2SAndroid Build Coastguard Worker }
4028