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