xref: /aosp_15_r20/external/libcups/cups/ppd-attr.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * PPD model-specific attribute routines for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright 2007-2015 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker  * Copyright 1997-2006 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker  *
7*5e7646d2SAndroid Build Coastguard Worker  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker  * information.
9*5e7646d2SAndroid Build Coastguard Worker  */
10*5e7646d2SAndroid Build Coastguard Worker 
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker  * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker  */
14*5e7646d2SAndroid Build Coastguard Worker 
15*5e7646d2SAndroid Build Coastguard Worker #include "cups-private.h"
16*5e7646d2SAndroid Build Coastguard Worker #include "ppd-private.h"
17*5e7646d2SAndroid Build Coastguard Worker #include "debug-internal.h"
18*5e7646d2SAndroid Build Coastguard Worker 
19*5e7646d2SAndroid Build Coastguard Worker 
20*5e7646d2SAndroid Build Coastguard Worker /*
21*5e7646d2SAndroid Build Coastguard Worker  * 'ppdFindAttr()' - Find the first matching attribute.
22*5e7646d2SAndroid Build Coastguard Worker  *
23*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.1.19/macOS 10.3@
24*5e7646d2SAndroid Build Coastguard Worker  */
25*5e7646d2SAndroid Build Coastguard Worker 
26*5e7646d2SAndroid Build Coastguard Worker ppd_attr_t *				/* O - Attribute or @code NULL@ if not found */
ppdFindAttr(ppd_file_t * ppd,const char * name,const char * spec)27*5e7646d2SAndroid Build Coastguard Worker ppdFindAttr(ppd_file_t *ppd,		/* I - PPD file data */
28*5e7646d2SAndroid Build Coastguard Worker             const char *name,		/* I - Attribute name */
29*5e7646d2SAndroid Build Coastguard Worker             const char *spec)		/* I - Specifier string or @code NULL@ */
30*5e7646d2SAndroid Build Coastguard Worker {
31*5e7646d2SAndroid Build Coastguard Worker   ppd_attr_t	key,			/* Search key */
32*5e7646d2SAndroid Build Coastguard Worker 		*attr;			/* Current attribute */
33*5e7646d2SAndroid Build Coastguard Worker 
34*5e7646d2SAndroid Build Coastguard Worker 
35*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("2ppdFindAttr(ppd=%p, name=\"%s\", spec=\"%s\")", ppd, name,
36*5e7646d2SAndroid Build Coastguard Worker                 spec));
37*5e7646d2SAndroid Build Coastguard Worker 
38*5e7646d2SAndroid Build Coastguard Worker  /*
39*5e7646d2SAndroid Build Coastguard Worker   * Range check input...
40*5e7646d2SAndroid Build Coastguard Worker   */
41*5e7646d2SAndroid Build Coastguard Worker 
42*5e7646d2SAndroid Build Coastguard Worker   if (!ppd || !name || ppd->num_attrs == 0)
43*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
44*5e7646d2SAndroid Build Coastguard Worker 
45*5e7646d2SAndroid Build Coastguard Worker  /*
46*5e7646d2SAndroid Build Coastguard Worker   * Search for a matching attribute...
47*5e7646d2SAndroid Build Coastguard Worker   */
48*5e7646d2SAndroid Build Coastguard Worker 
49*5e7646d2SAndroid Build Coastguard Worker   memset(&key, 0, sizeof(key));
50*5e7646d2SAndroid Build Coastguard Worker   strlcpy(key.name, name, sizeof(key.name));
51*5e7646d2SAndroid Build Coastguard Worker 
52*5e7646d2SAndroid Build Coastguard Worker  /*
53*5e7646d2SAndroid Build Coastguard Worker   * Return the first matching attribute, if any...
54*5e7646d2SAndroid Build Coastguard Worker   */
55*5e7646d2SAndroid Build Coastguard Worker 
56*5e7646d2SAndroid Build Coastguard Worker   if ((attr = (ppd_attr_t *)cupsArrayFind(ppd->sorted_attrs, &key)) != NULL)
57*5e7646d2SAndroid Build Coastguard Worker   {
58*5e7646d2SAndroid Build Coastguard Worker     if (spec)
59*5e7646d2SAndroid Build Coastguard Worker     {
60*5e7646d2SAndroid Build Coastguard Worker      /*
61*5e7646d2SAndroid Build Coastguard Worker       * Loop until we find the first matching attribute for "spec"...
62*5e7646d2SAndroid Build Coastguard Worker       */
63*5e7646d2SAndroid Build Coastguard Worker 
64*5e7646d2SAndroid Build Coastguard Worker       while (attr && _cups_strcasecmp(spec, attr->spec))
65*5e7646d2SAndroid Build Coastguard Worker       {
66*5e7646d2SAndroid Build Coastguard Worker         if ((attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs)) != NULL &&
67*5e7646d2SAndroid Build Coastguard Worker 	    _cups_strcasecmp(attr->name, name))
68*5e7646d2SAndroid Build Coastguard Worker 	  attr = NULL;
69*5e7646d2SAndroid Build Coastguard Worker       }
70*5e7646d2SAndroid Build Coastguard Worker     }
71*5e7646d2SAndroid Build Coastguard Worker   }
72*5e7646d2SAndroid Build Coastguard Worker 
73*5e7646d2SAndroid Build Coastguard Worker   return (attr);
74*5e7646d2SAndroid Build Coastguard Worker }
75*5e7646d2SAndroid Build Coastguard Worker 
76*5e7646d2SAndroid Build Coastguard Worker 
77*5e7646d2SAndroid Build Coastguard Worker /*
78*5e7646d2SAndroid Build Coastguard Worker  * 'ppdFindNextAttr()' - Find the next matching attribute.
79*5e7646d2SAndroid Build Coastguard Worker  *
80*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.1.19/macOS 10.3@
81*5e7646d2SAndroid Build Coastguard Worker  */
82*5e7646d2SAndroid Build Coastguard Worker 
83*5e7646d2SAndroid Build Coastguard Worker ppd_attr_t *				/* O - Attribute or @code NULL@ if not found */
ppdFindNextAttr(ppd_file_t * ppd,const char * name,const char * spec)84*5e7646d2SAndroid Build Coastguard Worker ppdFindNextAttr(ppd_file_t *ppd,	/* I - PPD file data */
85*5e7646d2SAndroid Build Coastguard Worker                 const char *name,	/* I - Attribute name */
86*5e7646d2SAndroid Build Coastguard Worker 		const char *spec)	/* I - Specifier string or @code NULL@ */
87*5e7646d2SAndroid Build Coastguard Worker {
88*5e7646d2SAndroid Build Coastguard Worker   ppd_attr_t	*attr;			/* Current attribute */
89*5e7646d2SAndroid Build Coastguard Worker 
90*5e7646d2SAndroid Build Coastguard Worker 
91*5e7646d2SAndroid Build Coastguard Worker  /*
92*5e7646d2SAndroid Build Coastguard Worker   * Range check input...
93*5e7646d2SAndroid Build Coastguard Worker   */
94*5e7646d2SAndroid Build Coastguard Worker 
95*5e7646d2SAndroid Build Coastguard Worker   if (!ppd || !name || ppd->num_attrs == 0)
96*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
97*5e7646d2SAndroid Build Coastguard Worker 
98*5e7646d2SAndroid Build Coastguard Worker  /*
99*5e7646d2SAndroid Build Coastguard Worker   * See if there are more attributes to return...
100*5e7646d2SAndroid Build Coastguard Worker   */
101*5e7646d2SAndroid Build Coastguard Worker 
102*5e7646d2SAndroid Build Coastguard Worker   while ((attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs)) != NULL)
103*5e7646d2SAndroid Build Coastguard Worker   {
104*5e7646d2SAndroid Build Coastguard Worker    /*
105*5e7646d2SAndroid Build Coastguard Worker     * Check the next attribute to see if it is a match...
106*5e7646d2SAndroid Build Coastguard Worker     */
107*5e7646d2SAndroid Build Coastguard Worker 
108*5e7646d2SAndroid Build Coastguard Worker     if (_cups_strcasecmp(attr->name, name))
109*5e7646d2SAndroid Build Coastguard Worker     {
110*5e7646d2SAndroid Build Coastguard Worker      /*
111*5e7646d2SAndroid Build Coastguard Worker       * Nope, reset the current pointer to the end of the array...
112*5e7646d2SAndroid Build Coastguard Worker       */
113*5e7646d2SAndroid Build Coastguard Worker 
114*5e7646d2SAndroid Build Coastguard Worker       cupsArrayIndex(ppd->sorted_attrs, cupsArrayCount(ppd->sorted_attrs));
115*5e7646d2SAndroid Build Coastguard Worker 
116*5e7646d2SAndroid Build Coastguard Worker       return (NULL);
117*5e7646d2SAndroid Build Coastguard Worker     }
118*5e7646d2SAndroid Build Coastguard Worker 
119*5e7646d2SAndroid Build Coastguard Worker     if (!spec || !_cups_strcasecmp(attr->spec, spec))
120*5e7646d2SAndroid Build Coastguard Worker       break;
121*5e7646d2SAndroid Build Coastguard Worker   }
122*5e7646d2SAndroid Build Coastguard Worker 
123*5e7646d2SAndroid Build Coastguard Worker  /*
124*5e7646d2SAndroid Build Coastguard Worker   * Return the next attribute's value...
125*5e7646d2SAndroid Build Coastguard Worker   */
126*5e7646d2SAndroid Build Coastguard Worker 
127*5e7646d2SAndroid Build Coastguard Worker   return (attr);
128*5e7646d2SAndroid Build Coastguard Worker }
129*5e7646d2SAndroid Build Coastguard Worker 
130*5e7646d2SAndroid Build Coastguard Worker 
131*5e7646d2SAndroid Build Coastguard Worker /*
132*5e7646d2SAndroid Build Coastguard Worker  * '_ppdNormalizeMakeAndModel()' - Normalize a product/make-and-model string.
133*5e7646d2SAndroid Build Coastguard Worker  *
134*5e7646d2SAndroid Build Coastguard Worker  * This function tries to undo the mistakes made by many printer manufacturers
135*5e7646d2SAndroid Build Coastguard Worker  * to produce a clean make-and-model string we can use.
136*5e7646d2SAndroid Build Coastguard Worker  */
137*5e7646d2SAndroid Build Coastguard Worker 
138*5e7646d2SAndroid Build Coastguard Worker char *					/* O - Normalized make-and-model string or NULL on error */
_ppdNormalizeMakeAndModel(const char * make_and_model,char * buffer,size_t bufsize)139*5e7646d2SAndroid Build Coastguard Worker _ppdNormalizeMakeAndModel(
140*5e7646d2SAndroid Build Coastguard Worker     const char *make_and_model,		/* I - Original make-and-model string */
141*5e7646d2SAndroid Build Coastguard Worker     char       *buffer,			/* I - String buffer */
142*5e7646d2SAndroid Build Coastguard Worker     size_t     bufsize)			/* I - Size of string buffer */
143*5e7646d2SAndroid Build Coastguard Worker {
144*5e7646d2SAndroid Build Coastguard Worker   char	*bufptr;			/* Pointer into buffer */
145*5e7646d2SAndroid Build Coastguard Worker 
146*5e7646d2SAndroid Build Coastguard Worker 
147*5e7646d2SAndroid Build Coastguard Worker   if (!make_and_model || !buffer || bufsize < 1)
148*5e7646d2SAndroid Build Coastguard Worker   {
149*5e7646d2SAndroid Build Coastguard Worker     if (buffer)
150*5e7646d2SAndroid Build Coastguard Worker       *buffer = '\0';
151*5e7646d2SAndroid Build Coastguard Worker 
152*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
153*5e7646d2SAndroid Build Coastguard Worker   }
154*5e7646d2SAndroid Build Coastguard Worker 
155*5e7646d2SAndroid Build Coastguard Worker  /*
156*5e7646d2SAndroid Build Coastguard Worker   * Skip leading whitespace...
157*5e7646d2SAndroid Build Coastguard Worker   */
158*5e7646d2SAndroid Build Coastguard Worker 
159*5e7646d2SAndroid Build Coastguard Worker   while (_cups_isspace(*make_and_model))
160*5e7646d2SAndroid Build Coastguard Worker     make_and_model ++;
161*5e7646d2SAndroid Build Coastguard Worker 
162*5e7646d2SAndroid Build Coastguard Worker  /*
163*5e7646d2SAndroid Build Coastguard Worker   * Remove parenthesis and add manufacturers as needed...
164*5e7646d2SAndroid Build Coastguard Worker   */
165*5e7646d2SAndroid Build Coastguard Worker 
166*5e7646d2SAndroid Build Coastguard Worker   if (make_and_model[0] == '(')
167*5e7646d2SAndroid Build Coastguard Worker   {
168*5e7646d2SAndroid Build Coastguard Worker     strlcpy(buffer, make_and_model + 1, bufsize);
169*5e7646d2SAndroid Build Coastguard Worker 
170*5e7646d2SAndroid Build Coastguard Worker     if ((bufptr = strrchr(buffer, ')')) != NULL)
171*5e7646d2SAndroid Build Coastguard Worker       *bufptr = '\0';
172*5e7646d2SAndroid Build Coastguard Worker   }
173*5e7646d2SAndroid Build Coastguard Worker   else if (!_cups_strncasecmp(make_and_model, "XPrint", 6))
174*5e7646d2SAndroid Build Coastguard Worker   {
175*5e7646d2SAndroid Build Coastguard Worker    /*
176*5e7646d2SAndroid Build Coastguard Worker     * Xerox XPrint...
177*5e7646d2SAndroid Build Coastguard Worker     */
178*5e7646d2SAndroid Build Coastguard Worker 
179*5e7646d2SAndroid Build Coastguard Worker     snprintf(buffer, bufsize, "Xerox %s", make_and_model);
180*5e7646d2SAndroid Build Coastguard Worker   }
181*5e7646d2SAndroid Build Coastguard Worker   else if (!_cups_strncasecmp(make_and_model, "Eastman", 7))
182*5e7646d2SAndroid Build Coastguard Worker   {
183*5e7646d2SAndroid Build Coastguard Worker    /*
184*5e7646d2SAndroid Build Coastguard Worker     * Kodak...
185*5e7646d2SAndroid Build Coastguard Worker     */
186*5e7646d2SAndroid Build Coastguard Worker 
187*5e7646d2SAndroid Build Coastguard Worker     snprintf(buffer, bufsize, "Kodak %s", make_and_model + 7);
188*5e7646d2SAndroid Build Coastguard Worker   }
189*5e7646d2SAndroid Build Coastguard Worker   else if (!_cups_strncasecmp(make_and_model, "laserwriter", 11))
190*5e7646d2SAndroid Build Coastguard Worker   {
191*5e7646d2SAndroid Build Coastguard Worker    /*
192*5e7646d2SAndroid Build Coastguard Worker     * Apple LaserWriter...
193*5e7646d2SAndroid Build Coastguard Worker     */
194*5e7646d2SAndroid Build Coastguard Worker 
195*5e7646d2SAndroid Build Coastguard Worker     snprintf(buffer, bufsize, "Apple LaserWriter%s", make_and_model + 11);
196*5e7646d2SAndroid Build Coastguard Worker   }
197*5e7646d2SAndroid Build Coastguard Worker   else if (!_cups_strncasecmp(make_and_model, "colorpoint", 10))
198*5e7646d2SAndroid Build Coastguard Worker   {
199*5e7646d2SAndroid Build Coastguard Worker    /*
200*5e7646d2SAndroid Build Coastguard Worker     * Seiko...
201*5e7646d2SAndroid Build Coastguard Worker     */
202*5e7646d2SAndroid Build Coastguard Worker 
203*5e7646d2SAndroid Build Coastguard Worker     snprintf(buffer, bufsize, "Seiko %s", make_and_model);
204*5e7646d2SAndroid Build Coastguard Worker   }
205*5e7646d2SAndroid Build Coastguard Worker   else if (!_cups_strncasecmp(make_and_model, "fiery", 5))
206*5e7646d2SAndroid Build Coastguard Worker   {
207*5e7646d2SAndroid Build Coastguard Worker    /*
208*5e7646d2SAndroid Build Coastguard Worker     * EFI...
209*5e7646d2SAndroid Build Coastguard Worker     */
210*5e7646d2SAndroid Build Coastguard Worker 
211*5e7646d2SAndroid Build Coastguard Worker     snprintf(buffer, bufsize, "EFI %s", make_and_model);
212*5e7646d2SAndroid Build Coastguard Worker   }
213*5e7646d2SAndroid Build Coastguard Worker   else if (!_cups_strncasecmp(make_and_model, "ps ", 3) ||
214*5e7646d2SAndroid Build Coastguard Worker 	   !_cups_strncasecmp(make_and_model, "colorpass", 9))
215*5e7646d2SAndroid Build Coastguard Worker   {
216*5e7646d2SAndroid Build Coastguard Worker    /*
217*5e7646d2SAndroid Build Coastguard Worker     * Canon...
218*5e7646d2SAndroid Build Coastguard Worker     */
219*5e7646d2SAndroid Build Coastguard Worker 
220*5e7646d2SAndroid Build Coastguard Worker     snprintf(buffer, bufsize, "Canon %s", make_and_model);
221*5e7646d2SAndroid Build Coastguard Worker   }
222*5e7646d2SAndroid Build Coastguard Worker   else if (!_cups_strncasecmp(make_and_model, "designjet", 9) ||
223*5e7646d2SAndroid Build Coastguard Worker            !_cups_strncasecmp(make_and_model, "deskjet", 7))
224*5e7646d2SAndroid Build Coastguard Worker   {
225*5e7646d2SAndroid Build Coastguard Worker    /*
226*5e7646d2SAndroid Build Coastguard Worker     * HP...
227*5e7646d2SAndroid Build Coastguard Worker     */
228*5e7646d2SAndroid Build Coastguard Worker 
229*5e7646d2SAndroid Build Coastguard Worker     snprintf(buffer, bufsize, "HP %s", make_and_model);
230*5e7646d2SAndroid Build Coastguard Worker   }
231*5e7646d2SAndroid Build Coastguard Worker   else
232*5e7646d2SAndroid Build Coastguard Worker     strlcpy(buffer, make_and_model, bufsize);
233*5e7646d2SAndroid Build Coastguard Worker 
234*5e7646d2SAndroid Build Coastguard Worker  /*
235*5e7646d2SAndroid Build Coastguard Worker   * Clean up the make...
236*5e7646d2SAndroid Build Coastguard Worker   */
237*5e7646d2SAndroid Build Coastguard Worker 
238*5e7646d2SAndroid Build Coastguard Worker   if (!_cups_strncasecmp(buffer, "agfa", 4))
239*5e7646d2SAndroid Build Coastguard Worker   {
240*5e7646d2SAndroid Build Coastguard Worker    /*
241*5e7646d2SAndroid Build Coastguard Worker     * Replace with AGFA (all uppercase)...
242*5e7646d2SAndroid Build Coastguard Worker     */
243*5e7646d2SAndroid Build Coastguard Worker 
244*5e7646d2SAndroid Build Coastguard Worker     buffer[0] = 'A';
245*5e7646d2SAndroid Build Coastguard Worker     buffer[1] = 'G';
246*5e7646d2SAndroid Build Coastguard Worker     buffer[2] = 'F';
247*5e7646d2SAndroid Build Coastguard Worker     buffer[3] = 'A';
248*5e7646d2SAndroid Build Coastguard Worker   }
249*5e7646d2SAndroid Build Coastguard Worker   else if (!_cups_strncasecmp(buffer, "Hewlett-Packard hp ", 19))
250*5e7646d2SAndroid Build Coastguard Worker   {
251*5e7646d2SAndroid Build Coastguard Worker    /*
252*5e7646d2SAndroid Build Coastguard Worker     * Just put "HP" on the front...
253*5e7646d2SAndroid Build Coastguard Worker     */
254*5e7646d2SAndroid Build Coastguard Worker 
255*5e7646d2SAndroid Build Coastguard Worker     buffer[0] = 'H';
256*5e7646d2SAndroid Build Coastguard Worker     buffer[1] = 'P';
257*5e7646d2SAndroid Build Coastguard Worker     _cups_strcpy(buffer + 2, buffer + 18);
258*5e7646d2SAndroid Build Coastguard Worker   }
259*5e7646d2SAndroid Build Coastguard Worker   else if (!_cups_strncasecmp(buffer, "Hewlett-Packard ", 16))
260*5e7646d2SAndroid Build Coastguard Worker   {
261*5e7646d2SAndroid Build Coastguard Worker    /*
262*5e7646d2SAndroid Build Coastguard Worker     * Just put "HP" on the front...
263*5e7646d2SAndroid Build Coastguard Worker     */
264*5e7646d2SAndroid Build Coastguard Worker 
265*5e7646d2SAndroid Build Coastguard Worker     buffer[0] = 'H';
266*5e7646d2SAndroid Build Coastguard Worker     buffer[1] = 'P';
267*5e7646d2SAndroid Build Coastguard Worker     _cups_strcpy(buffer + 2, buffer + 15);
268*5e7646d2SAndroid Build Coastguard Worker   }
269*5e7646d2SAndroid Build Coastguard Worker   else if (!_cups_strncasecmp(buffer, "Lexmark International", 21))
270*5e7646d2SAndroid Build Coastguard Worker   {
271*5e7646d2SAndroid Build Coastguard Worker    /*
272*5e7646d2SAndroid Build Coastguard Worker     * Strip "International"...
273*5e7646d2SAndroid Build Coastguard Worker     */
274*5e7646d2SAndroid Build Coastguard Worker 
275*5e7646d2SAndroid Build Coastguard Worker     _cups_strcpy(buffer + 8, buffer + 21);
276*5e7646d2SAndroid Build Coastguard Worker   }
277*5e7646d2SAndroid Build Coastguard Worker   else if (!_cups_strncasecmp(buffer, "herk", 4))
278*5e7646d2SAndroid Build Coastguard Worker   {
279*5e7646d2SAndroid Build Coastguard Worker    /*
280*5e7646d2SAndroid Build Coastguard Worker     * Replace with LHAG...
281*5e7646d2SAndroid Build Coastguard Worker     */
282*5e7646d2SAndroid Build Coastguard Worker 
283*5e7646d2SAndroid Build Coastguard Worker     buffer[0] = 'L';
284*5e7646d2SAndroid Build Coastguard Worker     buffer[1] = 'H';
285*5e7646d2SAndroid Build Coastguard Worker     buffer[2] = 'A';
286*5e7646d2SAndroid Build Coastguard Worker     buffer[3] = 'G';
287*5e7646d2SAndroid Build Coastguard Worker   }
288*5e7646d2SAndroid Build Coastguard Worker   else if (!_cups_strncasecmp(buffer, "linotype", 8))
289*5e7646d2SAndroid Build Coastguard Worker   {
290*5e7646d2SAndroid Build Coastguard Worker    /*
291*5e7646d2SAndroid Build Coastguard Worker     * Replace with LHAG...
292*5e7646d2SAndroid Build Coastguard Worker     */
293*5e7646d2SAndroid Build Coastguard Worker 
294*5e7646d2SAndroid Build Coastguard Worker     buffer[0] = 'L';
295*5e7646d2SAndroid Build Coastguard Worker     buffer[1] = 'H';
296*5e7646d2SAndroid Build Coastguard Worker     buffer[2] = 'A';
297*5e7646d2SAndroid Build Coastguard Worker     buffer[3] = 'G';
298*5e7646d2SAndroid Build Coastguard Worker     _cups_strcpy(buffer + 4, buffer + 8);
299*5e7646d2SAndroid Build Coastguard Worker   }
300*5e7646d2SAndroid Build Coastguard Worker 
301*5e7646d2SAndroid Build Coastguard Worker  /*
302*5e7646d2SAndroid Build Coastguard Worker   * Remove trailing whitespace and return...
303*5e7646d2SAndroid Build Coastguard Worker   */
304*5e7646d2SAndroid Build Coastguard Worker 
305*5e7646d2SAndroid Build Coastguard Worker   for (bufptr = buffer + strlen(buffer) - 1;
306*5e7646d2SAndroid Build Coastguard Worker        bufptr >= buffer && _cups_isspace(*bufptr);
307*5e7646d2SAndroid Build Coastguard Worker        bufptr --);
308*5e7646d2SAndroid Build Coastguard Worker 
309*5e7646d2SAndroid Build Coastguard Worker   bufptr[1] = '\0';
310*5e7646d2SAndroid Build Coastguard Worker 
311*5e7646d2SAndroid Build Coastguard Worker   return (buffer[0] ? buffer : NULL);
312*5e7646d2SAndroid Build Coastguard Worker }
313