]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/attr.c
More debug printf overhaul to cover all of libcups.
[thirdparty/cups.git] / cups / attr.c
CommitLineData
da5bb70a 1/*
c9d3f842 2 * "$Id$"
da5bb70a 3 *
4 * PPD model-specific attribute routines for the Common UNIX Printing System
5 * (CUPS).
6 *
571af0ea 7 * Copyright 2007-2009 by Apple Inc.
91ac93ad 8 * Copyright 1997-2006 by Easy Software Products.
da5bb70a 9 *
10 * These coded instructions, statements, and computer programs are the
4e8d321f 11 * property of Apple Inc. and are protected by Federal copyright
12 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
13 * which should have been included with this file. If this file is
14 * file is missing or damaged, see the license at "http://www.cups.org/".
da5bb70a 15 *
16 * Contents:
17 *
8f6753d3 18 * ppdFindAttr() - Find the first matching attribute.
19 * ppdFindNextAttr() - Find the next matching attribute.
da5bb70a 20 */
21
22/*
23 * Include necessary headers...
24 */
25
48845cc1 26#include "ppd-private.h"
da5bb70a 27#include "debug.h"
28#include "string.h"
29#include <stdlib.h>
30
31
da5bb70a 32/*
8f6753d3 33 * 'ppdFindAttr()' - Find the first matching attribute.
0341722a 34 *
373b3e5f 35 * @since CUPS 1.1.19/Mac OS X 10.3@
da5bb70a 36 */
37
8f6753d3 38ppd_attr_t * /* O - Attribute or @code NULL@ if not found */
51c4a398 39ppdFindAttr(ppd_file_t *ppd, /* I - PPD file data */
40 const char *name, /* I - Attribute name */
8f6753d3 41 const char *spec) /* I - Specifier string or @code NULL@ */
da5bb70a 42{
51c4a398 43 ppd_attr_t key, /* Search key */
44 *attr; /* Current attribute */
da5bb70a 45
46
571af0ea 47 DEBUG_printf(("2ppdFindAttr(ppd=%p, name=\"%s\", spec=\"%s\")", ppd, name,
48 spec));
51c4a398 49
da5bb70a 50 /*
51 * Range check input...
52 */
53
91ac93ad 54 if (!ppd || !name || ppd->num_attrs == 0)
da5bb70a 55 return (NULL);
56
57 /*
91ac93ad 58 * Search for a matching attribute...
da5bb70a 59 */
60
61 memset(&key, 0, sizeof(key));
91ac93ad 62 strlcpy(key.name, name, sizeof(key.name));
da5bb70a 63
64 /*
91ac93ad 65 * Return the first matching attribute, if any...
da5bb70a 66 */
67
51c4a398 68 if ((attr = (ppd_attr_t *)cupsArrayFind(ppd->sorted_attrs, &key)) != NULL)
51c4a398 69 {
85abd435 70 if (spec)
51c4a398 71 {
72 /*
85abd435 73 * Loop until we find the first matching attribute for "spec"...
51c4a398 74 */
75
85abd435 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 }
51c4a398 82 }
83 }
84
85 return (attr);
da5bb70a 86}
87
88
89/*
8f6753d3 90 * 'ppdFindNextAttr()' - Find the next matching attribute.
0341722a 91 *
373b3e5f 92 * @since CUPS 1.1.19/Mac OS X 10.3@
da5bb70a 93 */
94
8f6753d3 95ppd_attr_t * /* O - Attribute or @code NULL@ if not found */
da5bb70a 96ppdFindNextAttr(ppd_file_t *ppd, /* I - PPD file data */
97 const char *name, /* I - Attribute name */
8f6753d3 98 const char *spec) /* I - Specifier string or @code NULL@ */
da5bb70a 99{
91ac93ad 100 ppd_attr_t *attr; /* Current attribute */
da5bb70a 101
102
103 /*
104 * Range check input...
105 */
106
85abd435 107 if (!ppd || !name || ppd->num_attrs == 0)
da5bb70a 108 return (NULL);
109
110 /*
111 * See if there are more attributes to return...
112 */
113
85abd435 114 while ((attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs)) != NULL)
da5bb70a 115 {
116 /*
85abd435 117 * Check the next attribute to see if it is a match...
da5bb70a 118 */
119
85abd435 120 if (strcasecmp(attr->name, name))
121 {
122 /*
123 * Nope, reset the current pointer to the end of the array...
124 */
91ac93ad 125
85abd435 126 cupsArrayIndex(ppd->sorted_attrs, cupsArrayCount(ppd->sorted_attrs));
127
128 return (NULL);
129 }
130
131 if (!spec || !strcasecmp(attr->spec, spec))
132 break;
da5bb70a 133 }
85abd435 134
da5bb70a 135 /*
136 * Return the next attribute's value...
137 */
138
91ac93ad 139 return (attr);
da5bb70a 140}
141
142
48845cc1 143/*
144 * '_ppdGet1284Values()' - Get 1284 device ID keys and values.
145 *
146 * The returned dictionary is a CUPS option array that can be queried with
147 * cupsGetOption and freed with cupsFreeOptions.
148 */
149
150int /* O - Number of key/value pairs */
151_ppdGet1284Values(
152 const char *device_id, /* I - IEEE-1284 device ID string */
153 cups_option_t **values) /* O - Array of key/value pairs */
154{
155 int num_values; /* Number of values */
156 char key[256], /* Key string */
157 value[256], /* Value string */
158 *ptr; /* Pointer into key/value */
159
160
161 /*
162 * Range check input...
163 */
164
165 if (values)
166 *values = NULL;
167
168 if (!device_id || !values)
169 return (0);
170
171 /*
172 * Parse the 1284 device ID value into keys and values. The format is
173 * repeating sequences of:
174 *
175 * [whitespace]key:value[whitespace];
176 */
177
178 num_values = 0;
179 while (*device_id)
180 {
181 while (isspace(*device_id & 255))
182 device_id ++;
183
184 if (!*device_id)
185 break;
186
187 for (ptr = key; *device_id && *device_id != ':'; device_id ++)
188 if (ptr < (key + sizeof(key) - 1))
189 *ptr++ = *device_id;
190
191 if (!*device_id)
192 break;
193
194 while (ptr > key && isspace(ptr[-1] & 255))
195 ptr --;
196
197 *ptr = '\0';
198 device_id ++;
199
200 while (isspace(*device_id & 255))
201 device_id ++;
202
203 if (!*device_id)
204 break;
205
206 for (ptr = value; *device_id && *device_id != ';'; device_id ++)
207 if (ptr < (value + sizeof(value) - 1))
208 *ptr++ = *device_id;
209
210 if (!*device_id)
211 break;
212
213 while (ptr > value && isspace(ptr[-1] & 255))
214 ptr --;
215
216 *ptr = '\0';
217 device_id ++;
218
219 num_values = cupsAddOption(key, value, num_values, values);
220 }
221
222 return (num_values);
223}
224
225
226/*
227 * '_ppdNormalizeMakeAndModel()' - Normalize a product/make-and-model string.
228 *
229 * This function tries to undo the mistakes made by many printer manufacturers
230 * to produce a clean make-and-model string we can use.
231 */
232
233char * /* O - Normalized make-and-model string or NULL on error */
234_ppdNormalizeMakeAndModel(
235 const char *make_and_model, /* I - Original make-and-model string */
236 char *buffer, /* I - String buffer */
237 size_t bufsize) /* I - Size of string buffer */
238{
239 char *bufptr; /* Pointer into buffer */
240
241
242 if (!make_and_model || !buffer || bufsize < 1)
243 {
244 if (buffer)
245 *buffer = '\0';
246
247 return (NULL);
248 }
249
250 /*
251 * Skip leading whitespace...
252 */
253
254 while (isspace(*make_and_model & 255))
255 make_and_model ++;
256
257 /*
258 * Remove parenthesis and add manufacturers as needed...
259 */
260
261 if (make_and_model[0] == '(')
262 {
263 strlcpy(buffer, make_and_model + 1, bufsize);
264
265 if ((bufptr = strrchr(buffer, ')')) != NULL)
266 *bufptr = '\0';
267 }
268 else if (!strncasecmp(make_and_model, "XPrint", 6))
269 {
270 /*
271 * Xerox XPrint...
272 */
273
274 snprintf(buffer, bufsize, "Xerox %s", make_and_model);
275 }
276 else if (!strncasecmp(make_and_model, "Eastman", 7))
277 {
278 /*
279 * Kodak...
280 */
281
282 snprintf(buffer, bufsize, "Kodak %s", make_and_model + 7);
283 }
284 else if (!strncasecmp(make_and_model, "laserwriter", 11))
285 {
286 /*
287 * Apple LaserWriter...
288 */
289
290 snprintf(buffer, bufsize, "Apple LaserWriter%s", make_and_model + 11);
291 }
292 else if (!strncasecmp(make_and_model, "colorpoint", 10))
293 {
294 /*
295 * Seiko...
296 */
297
298 snprintf(buffer, bufsize, "Seiko %s", make_and_model);
299 }
300 else if (!strncasecmp(make_and_model, "fiery", 5))
301 {
302 /*
303 * EFI...
304 */
305
306 snprintf(buffer, bufsize, "EFI %s", make_and_model);
307 }
308 else if (!strncasecmp(make_and_model, "ps ", 3) ||
309 !strncasecmp(make_and_model, "colorpass", 9))
310 {
311 /*
312 * Canon...
313 */
314
315 snprintf(buffer, bufsize, "Canon %s", make_and_model);
316 }
317 else if (!strncasecmp(make_and_model, "primera", 7))
318 {
319 /*
320 * Fargo...
321 */
322
323 snprintf(buffer, bufsize, "Fargo %s", make_and_model);
324 }
325 else if (!strncasecmp(make_and_model, "designjet", 9) ||
326 !strncasecmp(make_and_model, "deskjet", 7))
327 {
328 /*
329 * HP...
330 */
331
332 snprintf(buffer, bufsize, "HP %s", make_and_model);
333 }
334 else
335 strlcpy(buffer, make_and_model, bufsize);
336
337 /*
338 * Clean up the make...
339 */
340
341 if (!strncasecmp(buffer, "agfa", 4))
342 {
343 /*
344 * Replace with AGFA (all uppercase)...
345 */
346
347 buffer[0] = 'A';
348 buffer[1] = 'G';
349 buffer[2] = 'F';
350 buffer[3] = 'A';
351 }
352 else if (!strncasecmp(buffer, "Hewlett-Packard hp ", 19))
353 {
354 /*
355 * Just put "HP" on the front...
356 */
357
358 buffer[0] = 'H';
359 buffer[1] = 'P';
360 _cups_strcpy(buffer + 2, buffer + 18);
361 }
362 else if (!strncasecmp(buffer, "Hewlett-Packard ", 16))
363 {
364 /*
365 * Just put "HP" on the front...
366 */
367
368 buffer[0] = 'H';
369 buffer[1] = 'P';
370 _cups_strcpy(buffer + 2, buffer + 15);
371 }
372 else if (!strncasecmp(buffer, "Lexmark International", 21))
373 {
374 /*
375 * Strip "International"...
376 */
377
378 _cups_strcpy(buffer + 8, buffer + 21);
379 }
380 else if (!strncasecmp(buffer, "herk", 4))
381 {
382 /*
383 * Replace with LHAG...
384 */
385
386 buffer[0] = 'L';
387 buffer[1] = 'H';
388 buffer[2] = 'A';
389 buffer[3] = 'G';
390 }
391 else if (!strncasecmp(buffer, "linotype", 8))
392 {
393 /*
394 * Replace with LHAG...
395 */
396
397 buffer[0] = 'L';
398 buffer[1] = 'H';
399 buffer[2] = 'A';
400 buffer[3] = 'G';
401 _cups_strcpy(buffer + 4, buffer + 8);
402 }
403
404 /*
405 * Remove trailing whitespace and return...
406 */
407
408 for (bufptr = buffer + strlen(buffer) - 1;
409 bufptr >= buffer && isspace(*bufptr & 255);
410 bufptr --);
411
412 bufptr[1] = '\0';
413
414 return (buffer[0] ? buffer : NULL);
415}
416
417
da5bb70a 418/*
c9d3f842 419 * End of "$Id$".
da5bb70a 420 */