]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | /* |
5eb9da71 | 2 | * "$Id: attr.c 7584 2008-05-16 22:55:53Z mike $" |
ef416fc2 | 3 | * |
f8b3a85b | 4 | * PPD model-specific attribute routines for CUPS. |
ef416fc2 | 5 | * |
f8b3a85b | 6 | * Copyright 2007-2010 by Apple Inc. |
bd7854cb | 7 | * Copyright 1997-2006 by Easy Software Products. |
ef416fc2 | 8 | * |
9 | * These coded instructions, statements, and computer programs are the | |
bc44d920 | 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/". | |
ef416fc2 | 14 | * |
15 | * Contents: | |
16 | * | |
f8b3a85b MS |
17 | * ppdFindAttr() - Find the first matching attribute. |
18 | * ppdFindNextAttr() - Find the next matching attribute. | |
19 | * _ppdNormalizeMakeAndModel() - Normalize a product/make-and-model string. | |
ef416fc2 | 20 | */ |
21 | ||
22 | /* | |
23 | * Include necessary headers... | |
24 | */ | |
25 | ||
5eb9da71 | 26 | #include "ppd-private.h" |
ef416fc2 | 27 | #include "debug.h" |
28 | #include "string.h" | |
29 | #include <stdlib.h> | |
30 | ||
31 | ||
ef416fc2 | 32 | /* |
5a738aea | 33 | * 'ppdFindAttr()' - Find the first matching attribute. |
ef416fc2 | 34 | * |
426c6a59 | 35 | * @since CUPS 1.1.19/Mac OS X 10.3@ |
ef416fc2 | 36 | */ |
37 | ||
5a738aea | 38 | ppd_attr_t * /* O - Attribute or @code NULL@ if not found */ |
d09495fa | 39 | ppdFindAttr(ppd_file_t *ppd, /* I - PPD file data */ |
40 | const char *name, /* I - Attribute name */ | |
5a738aea | 41 | const char *spec) /* I - Specifier string or @code NULL@ */ |
ef416fc2 | 42 | { |
d09495fa | 43 | ppd_attr_t key, /* Search key */ |
44 | *attr; /* Current attribute */ | |
d09495fa | 45 | |
ef416fc2 | 46 | |
e07d4801 MS |
47 | DEBUG_printf(("2ppdFindAttr(ppd=%p, name=\"%s\", spec=\"%s\")", ppd, name, |
48 | spec)); | |
ef416fc2 | 49 | |
50 | /* | |
51 | * Range check input... | |
52 | */ | |
53 | ||
bd7854cb | 54 | if (!ppd || !name || ppd->num_attrs == 0) |
ef416fc2 | 55 | return (NULL); |
56 | ||
57 | /* | |
bd7854cb | 58 | * Search for a matching attribute... |
ef416fc2 | 59 | */ |
60 | ||
61 | memset(&key, 0, sizeof(key)); | |
bd7854cb | 62 | strlcpy(key.name, name, sizeof(key.name)); |
ef416fc2 | 63 | |
64 | /* | |
bd7854cb | 65 | * Return the first matching attribute, if any... |
ef416fc2 | 66 | */ |
67 | ||
d09495fa | 68 | if ((attr = (ppd_attr_t *)cupsArrayFind(ppd->sorted_attrs, &key)) != NULL) |
d09495fa | 69 | { |
6e8b116d | 70 | if (spec) |
d09495fa | 71 | { |
72 | /* | |
6e8b116d | 73 | * Loop until we find the first matching attribute for "spec"... |
d09495fa | 74 | */ |
75 | ||
6e8b116d MS |
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 | } | |
d09495fa | 82 | } |
83 | } | |
84 | ||
85 | return (attr); | |
ef416fc2 | 86 | } |
87 | ||
88 | ||
89 | /* | |
5a738aea | 90 | * 'ppdFindNextAttr()' - Find the next matching attribute. |
ef416fc2 | 91 | * |
426c6a59 | 92 | * @since CUPS 1.1.19/Mac OS X 10.3@ |
ef416fc2 | 93 | */ |
94 | ||
5a738aea | 95 | ppd_attr_t * /* O - Attribute or @code NULL@ if not found */ |
ef416fc2 | 96 | ppdFindNextAttr(ppd_file_t *ppd, /* I - PPD file data */ |
97 | const char *name, /* I - Attribute name */ | |
5a738aea | 98 | const char *spec) /* I - Specifier string or @code NULL@ */ |
ef416fc2 | 99 | { |
bd7854cb | 100 | ppd_attr_t *attr; /* Current attribute */ |
ef416fc2 | 101 | |
102 | ||
103 | /* | |
104 | * Range check input... | |
105 | */ | |
106 | ||
6e8b116d | 107 | if (!ppd || !name || ppd->num_attrs == 0) |
ef416fc2 | 108 | return (NULL); |
109 | ||
110 | /* | |
111 | * See if there are more attributes to return... | |
112 | */ | |
113 | ||
6e8b116d | 114 | while ((attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs)) != NULL) |
ef416fc2 | 115 | { |
116 | /* | |
6e8b116d | 117 | * Check the next attribute to see if it is a match... |
ef416fc2 | 118 | */ |
119 | ||
6e8b116d MS |
120 | if (strcasecmp(attr->name, name)) |
121 | { | |
122 | /* | |
123 | * Nope, reset the current pointer to the end of the array... | |
124 | */ | |
bd7854cb | 125 | |
6e8b116d MS |
126 | cupsArrayIndex(ppd->sorted_attrs, cupsArrayCount(ppd->sorted_attrs)); |
127 | ||
128 | return (NULL); | |
129 | } | |
130 | ||
131 | if (!spec || !strcasecmp(attr->spec, spec)) | |
132 | break; | |
ef416fc2 | 133 | } |
6e8b116d | 134 | |
ef416fc2 | 135 | /* |
136 | * Return the next attribute's value... | |
137 | */ | |
138 | ||
bd7854cb | 139 | return (attr); |
ef416fc2 | 140 | } |
141 | ||
142 | ||
5eb9da71 MS |
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 $". | |
ef416fc2 | 337 | */ |