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