/*
- * "$Id: attr.c 6649 2007-07-11 21:46:42Z mike $"
+ * "$Id$"
*
- * PPD model-specific attribute routines for the Common UNIX Printing System
- * (CUPS).
+ * PPD model-specific attribute routines for CUPS.
*
- * Copyright 2007 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products.
+ * Copyright 2007-2015 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * ppdFindAttr() - Find the first matching attribute...
- * ppdFindNextAttr() - Find the next matching attribute...
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*/
/*
* Include necessary headers...
*/
-#include "ppd.h"
-#include "debug.h"
-#include "string.h"
-#include <stdlib.h>
+#include "cups-private.h"
+#include "ppd-private.h"
/*
- * 'ppdFindAttr()' - Find the first matching attribute...
+ * 'ppdFindAttr()' - Find the first matching attribute.
*
- * @since CUPS 1.1.19@
+ * @since CUPS 1.1.19/OS X 10.3@
*/
-ppd_attr_t * /* O - Attribute or NULL if not found */
+ppd_attr_t * /* O - Attribute or @code NULL@ if not found */
ppdFindAttr(ppd_file_t *ppd, /* I - PPD file data */
const char *name, /* I - Attribute name */
- const char *spec) /* I - Specifier string or NULL */
+ const char *spec) /* I - Specifier string or @code NULL@ */
{
ppd_attr_t key, /* Search key */
*attr; /* Current attribute */
- int diff; /* Current difference */
- DEBUG_printf(("ppdFindAttr(ppd=%p, name=\"%s\", spec=\"%s\")\n", ppd,
- name ? name : "(null)", spec ? spec : "(null)"));
+ DEBUG_printf(("2ppdFindAttr(ppd=%p, name=\"%s\", spec=\"%s\")", ppd, name,
+ spec));
/*
* Range check input...
memset(&key, 0, sizeof(key));
strlcpy(key.name, name, sizeof(key.name));
- if (spec)
- strlcpy(key.spec, spec, sizeof(key.spec));
/*
* Return the first matching attribute, if any...
*/
if ((attr = (ppd_attr_t *)cupsArrayFind(ppd->sorted_attrs, &key)) != NULL)
- return (attr);
- else if (spec)
+ {
+ if (spec)
+ {
+ /*
+ * Loop until we find the first matching attribute for "spec"...
+ */
+
+ while (attr && _cups_strcasecmp(spec, attr->spec))
+ {
+ if ((attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs)) != NULL &&
+ _cups_strcasecmp(attr->name, name))
+ attr = NULL;
+ }
+ }
+ }
+
+ return (attr);
+}
+
+
+/*
+ * 'ppdFindNextAttr()' - Find the next matching attribute.
+ *
+ * @since CUPS 1.1.19/OS X 10.3@
+ */
+
+ppd_attr_t * /* O - Attribute or @code NULL@ if not found */
+ppdFindNextAttr(ppd_file_t *ppd, /* I - PPD file data */
+ const char *name, /* I - Attribute name */
+ const char *spec) /* I - Specifier string or @code NULL@ */
+{
+ ppd_attr_t *attr; /* Current attribute */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!ppd || !name || ppd->num_attrs == 0)
return (NULL);
/*
- * No match found, loop through the sorted attributes to see if we can
- * find a "wildcard" match for the attribute...
+ * See if there are more attributes to return...
*/
- for (attr = (ppd_attr_t *)cupsArrayFirst(ppd->sorted_attrs);
- attr;
- attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs))
+ while ((attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs)) != NULL)
{
- if ((diff = strcasecmp(attr->name, name)) == 0)
- break;
+ /*
+ * Check the next attribute to see if it is a match...
+ */
- if (diff > 0)
+ if (_cups_strcasecmp(attr->name, name))
{
/*
- * All remaining attributes are > than the one we are trying to find...
+ * Nope, reset the current pointer to the end of the array...
*/
cupsArrayIndex(ppd->sorted_attrs, cupsArrayCount(ppd->sorted_attrs));
return (NULL);
}
+
+ if (!spec || !_cups_strcasecmp(attr->spec, spec))
+ break;
}
+ /*
+ * Return the next attribute's value...
+ */
+
return (attr);
}
/*
- * 'ppdFindNextAttr()' - Find the next matching attribute...
+ * '_ppdNormalizeMakeAndModel()' - Normalize a product/make-and-model string.
*
- * @since CUPS 1.1.19@
+ * This function tries to undo the mistakes made by many printer manufacturers
+ * to produce a clean make-and-model string we can use.
*/
-ppd_attr_t * /* O - Attribute or NULL if not found */
-ppdFindNextAttr(ppd_file_t *ppd, /* I - PPD file data */
- const char *name, /* I - Attribute name */
- const char *spec) /* I - Specifier string or NULL */
+char * /* O - Normalized make-and-model string or NULL on error */
+_ppdNormalizeMakeAndModel(
+ const char *make_and_model, /* I - Original make-and-model string */
+ char *buffer, /* I - String buffer */
+ size_t bufsize) /* I - Size of string buffer */
{
- ppd_attr_t *attr; /* Current attribute */
+ char *bufptr; /* Pointer into buffer */
+
+
+ if (!make_and_model || !buffer || bufsize < 1)
+ {
+ if (buffer)
+ *buffer = '\0';
+ return (NULL);
+ }
/*
- * Range check input...
+ * Skip leading whitespace...
*/
- if (!ppd || !name || ppd->num_attrs == 0 ||
- !cupsArrayCurrent(ppd->sorted_attrs))
- return (NULL);
+ while (_cups_isspace(*make_and_model))
+ make_and_model ++;
/*
- * See if there are more attributes to return...
+ * Remove parenthesis and add manufacturers as needed...
*/
- if ((attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs)) == NULL)
- return (NULL);
+ if (make_and_model[0] == '(')
+ {
+ strlcpy(buffer, make_and_model + 1, bufsize);
+
+ if ((bufptr = strrchr(buffer, ')')) != NULL)
+ *bufptr = '\0';
+ }
+ else if (!_cups_strncasecmp(make_and_model, "XPrint", 6))
+ {
+ /*
+ * Xerox XPrint...
+ */
+
+ snprintf(buffer, bufsize, "Xerox %s", make_and_model);
+ }
+ else if (!_cups_strncasecmp(make_and_model, "Eastman", 7))
+ {
+ /*
+ * Kodak...
+ */
+
+ snprintf(buffer, bufsize, "Kodak %s", make_and_model + 7);
+ }
+ else if (!_cups_strncasecmp(make_and_model, "laserwriter", 11))
+ {
+ /*
+ * Apple LaserWriter...
+ */
+
+ snprintf(buffer, bufsize, "Apple LaserWriter%s", make_and_model + 11);
+ }
+ else if (!_cups_strncasecmp(make_and_model, "colorpoint", 10))
+ {
+ /*
+ * Seiko...
+ */
+
+ snprintf(buffer, bufsize, "Seiko %s", make_and_model);
+ }
+ else if (!_cups_strncasecmp(make_and_model, "fiery", 5))
+ {
+ /*
+ * EFI...
+ */
+
+ snprintf(buffer, bufsize, "EFI %s", make_and_model);
+ }
+ else if (!_cups_strncasecmp(make_and_model, "ps ", 3) ||
+ !_cups_strncasecmp(make_and_model, "colorpass", 9))
+ {
+ /*
+ * Canon...
+ */
+
+ snprintf(buffer, bufsize, "Canon %s", make_and_model);
+ }
+ else if (!_cups_strncasecmp(make_and_model, "designjet", 9) ||
+ !_cups_strncasecmp(make_and_model, "deskjet", 7))
+ {
+ /*
+ * HP...
+ */
+
+ snprintf(buffer, bufsize, "HP %s", make_and_model);
+ }
+ else
+ strlcpy(buffer, make_and_model, bufsize);
/*
- * Check the next attribute to see if it is a match...
+ * Clean up the make...
*/
- if (strcasecmp(attr->name, name) || (spec && strcasecmp(attr->spec, spec)))
+ if (!_cups_strncasecmp(buffer, "agfa", 4))
{
/*
- * Nope, reset the current pointer to the end of the array...
+ * Replace with AGFA (all uppercase)...
*/
- cupsArrayIndex(ppd->sorted_attrs, cupsArrayCount(ppd->sorted_attrs));
+ buffer[0] = 'A';
+ buffer[1] = 'G';
+ buffer[2] = 'F';
+ buffer[3] = 'A';
+ }
+ else if (!_cups_strncasecmp(buffer, "Hewlett-Packard hp ", 19))
+ {
+ /*
+ * Just put "HP" on the front...
+ */
- return (NULL);
+ buffer[0] = 'H';
+ buffer[1] = 'P';
+ _cups_strcpy(buffer + 2, buffer + 18);
}
-
+ else if (!_cups_strncasecmp(buffer, "Hewlett-Packard ", 16))
+ {
+ /*
+ * Just put "HP" on the front...
+ */
+
+ buffer[0] = 'H';
+ buffer[1] = 'P';
+ _cups_strcpy(buffer + 2, buffer + 15);
+ }
+ else if (!_cups_strncasecmp(buffer, "Lexmark International", 21))
+ {
+ /*
+ * Strip "International"...
+ */
+
+ _cups_strcpy(buffer + 8, buffer + 21);
+ }
+ else if (!_cups_strncasecmp(buffer, "herk", 4))
+ {
+ /*
+ * Replace with LHAG...
+ */
+
+ buffer[0] = 'L';
+ buffer[1] = 'H';
+ buffer[2] = 'A';
+ buffer[3] = 'G';
+ }
+ else if (!_cups_strncasecmp(buffer, "linotype", 8))
+ {
+ /*
+ * Replace with LHAG...
+ */
+
+ buffer[0] = 'L';
+ buffer[1] = 'H';
+ buffer[2] = 'A';
+ buffer[3] = 'G';
+ _cups_strcpy(buffer + 4, buffer + 8);
+ }
+
/*
- * Return the next attribute's value...
+ * Remove trailing whitespace and return...
*/
- return (attr);
+ for (bufptr = buffer + strlen(buffer) - 1;
+ bufptr >= buffer && _cups_isspace(*bufptr);
+ bufptr --);
+
+ bufptr[1] = '\0';
+
+ return (buffer[0] ? buffer : NULL);
}
/*
- * End of "$Id: attr.c 6649 2007-07-11 21:46:42Z mike $".
+ * End of "$Id$".
*/