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