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