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