# DO NOT DELETE
-dest.o: cups.h ipp.h http.h md5.h ppd.h language.h string.h ../config.h
+attr.o: ppd.h debug.h string.h ../config.h
+dest.o: cups.h ipp.h http.h string.h ../config.h md5.h ppd.h language.h
emit.o: ppd.h string.h ../config.h
-encode.o: cups.h ipp.h http.h md5.h ppd.h string.h ../config.h debug.h
+encode.o: cups.h ipp.h http.h string.h ../config.h md5.h ppd.h debug.h
http.o: string.h ../config.h http.h md5.h http-private.h debug.h
http-addr.o: string.h ../config.h http.h md5.h
http-support.o: string.h ../config.h http.h md5.h ipp.h
language.o: string.h ../config.h language.h cups_C.h
mark.o: ppd.h string.h ../config.h debug.h
md5.o: md5.h string.h ../config.h
-md5passwd.o: http.h md5.h string.h ../config.h
-options.o: cups.h ipp.h http.h md5.h ppd.h string.h ../config.h debug.h
+md5passwd.o: http.h string.h ../config.h md5.h
+options.o: cups.h ipp.h http.h string.h ../config.h md5.h ppd.h debug.h
page.o: ppd.h string.h ../config.h
ppd.o: ppd.h string.h ../config.h language.h debug.h
snprintf.o: string.h ../config.h
string.o: string.h ../config.h
-tempfile.o: cups.h ipp.h http.h md5.h ppd.h string.h ../config.h debug.h
-usersys.o: cups.h ipp.h http.h md5.h ppd.h string.h ../config.h
-util.o: cups.h ipp.h http.h md5.h ppd.h language.h string.h ../config.h
+tempfile.o: cups.h ipp.h http.h string.h ../config.h md5.h ppd.h debug.h
+usersys.o: cups.h ipp.h http.h string.h ../config.h md5.h ppd.h
+util.o: cups.h ipp.h http.h string.h ../config.h md5.h ppd.h language.h
util.o: debug.h
-testhttp.o: http.h md5.h
+testhttp.o: http.h string.h ../config.h md5.h
testlang.o: language.h
#
-# "$Id: Makefile,v 1.80 2003/01/28 15:33:18 mike Exp $"
+# "$Id: Makefile,v 1.81 2003/01/29 17:03:37 mike Exp $"
#
# Support library Makefile for the Common UNIX Printing System (CUPS).
#
# Object files...
#
-LIBOBJS = dest.o emit.o encode.o http.o http-addr.o http-support.o \
- ipp.o ipp-support.o language.o mark.o md5.o md5passwd.o \
- options.o page.o ppd.o snprintf.o string.o tempfile.o \
- usersys.o util.o
+LIBOBJS = attr.o dest.o emit.o encode.o http.o http-addr.o \
+ http-support.o ipp.o ipp-support.o language.o mark.o \
+ md5.o md5passwd.o options.o page.o ppd.o snprintf.o \
+ string.o tempfile.o usersys.o util.o
OBJS = $(LIBOBJS) testhttp.o testlang.o
#
-# End of "$Id: Makefile,v 1.80 2003/01/28 15:33:18 mike Exp $".
+# End of "$Id: Makefile,v 1.81 2003/01/29 17:03:37 mike Exp $".
#
--- /dev/null
+/*
+ * "$Id: attr.c,v 1.2 2003/01/29 17:03:37 mike Exp $"
+ *
+ * PPD model-specific attribute routines for the Common UNIX Printing System
+ * (CUPS).
+ *
+ * Copyright 1997-2003 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products 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 missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9600
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "ppd.h"
+#include "debug.h"
+#include "string.h"
+#include <stdlib.h>
+
+
+/*
+ * Private function...
+ */
+
+extern int _ppd_attr_compare(ppd_attr_t **a, ppd_attr_t **b);
+
+
+/*
+ * 'ppdFindAttr()' - Find the first matching attribute...
+ */
+
+const char * /* O - Value or 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 */
+{
+ ppd_attr_t key, /* Search key */
+ *keyptr, /* Pointer to key */
+ **match; /* Matching attribute */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (ppd == NULL || name == NULL || ppd->num_attrs == 0)
+ return (NULL);
+
+ /*
+ * Do a binary search for a matching attribute...
+ */
+
+ memset(&key, 0, sizeof(key));
+ strncpy(key.name, name, sizeof(key.name) - 1);
+ if (spec)
+ strncpy(key.spec, spec, sizeof(key.spec) - 1);
+
+ keyptr = &key;
+
+ match = bsearch(&keyptr, ppd->attrs, ppd->num_attrs, sizeof(ppd_attr_t *),
+ (int (*)(const void *, const void *))_ppd_attr_compare);
+
+ if (match == NULL)
+ {
+ /*
+ * No match!
+ */
+
+ ppd->cur_attr = -1;
+ return (NULL);
+ }
+
+ if (match > ppd->attrs && spec == NULL)
+ {
+ /*
+ * Find the first attribute with the same name...
+ */
+
+ while (match > ppd->attrs)
+ {
+ if (strcmp(match[-1]->name, name) != 0)
+ break;
+
+ match --;
+ }
+ }
+
+ /*
+ * Save the current attribute and return its value...
+ */
+
+ ppd->cur_attr = match - ppd->attrs;
+
+ if ((*match)->value)
+ return ((*match)->value);
+ else
+ return ("");
+}
+
+
+/*
+ * 'ppdFindNextAttr()' - Find the next matching attribute...
+ */
+
+const char * /* O - Value 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 */
+{
+ ppd_attr_t **match; /* Matching attribute */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (ppd == NULL || name == NULL || ppd->num_attrs == 0 || ppd->cur_attr < 0)
+ return (NULL);
+
+ /*
+ * See if there are more attributes to return...
+ */
+
+ ppd->cur_attr ++;
+
+ if (ppd->cur_attr >= ppd->num_attrs)
+ {
+ /*
+ * Nope...
+ */
+
+ ppd->cur_attr = -1;
+ return (NULL);
+ }
+
+ /*
+ * Check the next attribute to see if it is a match...
+ */
+
+ match = ppd->attrs + ppd->cur_attr;
+
+ if (strcmp((*match)->name, name) != 0 ||
+ (spec != NULL && strcmp((*match)->spec, spec) != 0))
+ {
+ /*
+ * Nope...
+ */
+
+ ppd->cur_attr = -1;
+ return (NULL);
+ }
+
+ /*
+ * Return the next attribute's value...
+ */
+
+ if ((*match)->value)
+ return ((*match)->value);
+ else
+ return ("");
+}
+
+
+/*
+ * End of "$Id: attr.c,v 1.2 2003/01/29 17:03:37 mike Exp $".
+ */
/*
- * "$Id: ppd.c,v 1.81 2003/01/28 20:21:53 mike Exp $"
+ * "$Id: ppd.c,v 1.82 2003/01/29 17:03:37 mike Exp $"
*
* PPD file routines for the Common UNIX Printing System (CUPS).
*
*
* _ppd_attr_compare() - Compare two attributes.
* ppdClose() - Free all memory used by the PPD file.
+ * ppdErrorString() - Returns the text assocated with a status.
+ * ppdLastError() - Return the status from the last ppdOpen*().
* ppdOpen() - Read a PPD file into memory.
* ppdOpenFd() - Read a PPD file into memory.
* ppdOpenFile() - Read a PPD file into memory.
#define PPD_STRING 8 /* Line contained a string or code */
+/*
+ * Local globals...
+ */
+
+static ppd_status_t ppd_status = PPD_OK;
+ /* Status of last ppdOpen*() */
+static int ppd_line = 1; /* Current line number */
+
+
/*
* Local functions...
*/
}
+/*
+ * 'ppdErrorString()' - Returns the text assocated with a status.
+ */
+
+const char * /* O - Status string */
+ppdErrorString(ppd_status_t status) /* I - PPD status */
+{
+ static const char * const messages[] =/* Status messages */
+ {
+ "OK",
+ "Unable to open PPD file",
+ "NULL PPD file pointer",
+ "Missing PPD-Adobe-4.x header",
+ "Memory allocation error",
+ "Missing value string",
+ "Internal error",
+ "OpenGroup without a CloseGroup first",
+ "Bad OrderDependency",
+ "Bad UIConstraints",
+ };
+
+
+ if (status < PPD_OK || status > PPD_BAD_UI_CONSTRAINTS)
+ return ("Unknown");
+ else
+ return (messages[status]);
+}
+
+
+/*
+ * 'ppdLastError()' - Return the status from the last ppdOpen*().
+ */
+
+ppd_status_t /* O - Status code */
+ppdLastError(int *line) /* O - Line number */
+{
+ if (line)
+ *line = ppd_line;
+
+ return (ppd_status);
+}
+
+
/*
* 'ppdOpen()' - Read a PPD file into memory.
*/
cups_lang_t *language; /* Default language */
+ /*
+ * Default to "OK" status...
+ */
+
+ ppd_status = PPD_OK;
+ ppd_line = 1;
+
/*
* Range check input...
*/
if (fp == NULL)
+ {
+ ppd_status = PPD_NULL_FILE;
return (NULL);
+ }
/*
* Grab the first line and make sure it reads '*PPD-Adobe: "major.minor"'...
* Either this is not a PPD file, or it is not a 4.x PPD file.
*/
+ ppd_status = PPD_MISSING_PPDADOBE4;
+
ppd_free(string);
return (NULL);
*/
if ((ppd = calloc(sizeof(ppd_file_t), 1)) == NULL)
+ {
+ ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
+ }
ppd->language_level = 1;
ppd->color_device = 0;
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_MISSING_VALUE;
+
return (NULL);
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
}
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
}
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_INTERNAL_ERROR;
+
return (NULL);
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_INTERNAL_ERROR;
+
return (NULL);
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_NESTED_OPEN_GROUP;
+
return (NULL);
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_BAD_ORDER_DEPENDENCY;
+
return (NULL);
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
}
case 1 : /* Error */
ppdClose(ppd);
ppd_free(string);
- break;
+ ppd_status = PPD_BAD_UI_CONSTRAINTS;
+ return (NULL);
case 2 : /* Two options... */
/*
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
}
setlocale(LC_ALL, oldlocale);
#endif /* LC_NUMERIC */
+ ppd_status = PPD_ALLOC_ERROR;
+
return (NULL);
}
qsort(ppd->attrs, ppd->num_attrs, sizeof(ppd_attr_t *),
(int (*)(const void *, const void *))_ppd_attr_compare);
+ /*
+ * Return the PPD file structure...
+ */
+
return (ppd);
}
ppd_file_t *ppd; /* PPD file record */
+ /*
+ * Set the line number to 1...
+ */
+
+ ppd_line = 1;
+
/*
* Range check input...
*/
if (fd < 0)
+ {
+ ppd_status = PPD_NULL_FILE;
+
return (NULL);
+ }
/*
* Try to open the file and parse it...
ppd = ppdOpen(fp);
- ppd_free(fp);
+ fclose(fp);
}
else
- ppd = NULL;
+ {
+ ppd_status = PPD_FILE_OPEN_ERROR;
+ ppd = NULL;
+ }
return (ppd);
}
ppd_file_t *ppd; /* PPD file record */
+ /*
+ * Set the line number to 1...
+ */
+
+ ppd_line = 1;
+
/*
* Range check input...
*/
if (filename == NULL)
+ {
+ ppd_status = PPD_NULL_FILE;
+
return (NULL);
+ }
/*
* Try to open the file and parse it...
fclose(fp);
}
else
- ppd = NULL;
+ {
+ ppd_status = PPD_FILE_OPEN_ERROR;
+ ppd = NULL;
+ }
return (ppd);
}
* Line feed or carriage return...
*/
+ ppd_line ++;
+
if (lineptr == line) /* Skip blank lines */
continue;
/*
- * End of "$Id: ppd.c,v 1.81 2003/01/28 20:21:53 mike Exp $".
+ * End of "$Id: ppd.c,v 1.82 2003/01/29 17:03:37 mike Exp $".
*/
/*
- * "$Id: ppd.h,v 1.28 2003/01/28 15:29:14 mike Exp $"
+ * "$Id: ppd.h,v 1.29 2003/01/29 17:03:37 mike Exp $"
*
* PostScript Printer Description definitions for the Common UNIX Printing
* System (CUPS).
PPD_CS_N /* DeviceN colorspace */
} ppd_cs_t;
+typedef enum /**** Status Codes ****/
+{
+ PPD_OK = 0, /* OK */
+ PPD_FILE_OPEN_ERROR, /* Unable to open PPD file */
+ PPD_NULL_FILE, /* NULL PPD file pointer */
+ PPD_MISSING_PPDADOBE4, /* Missing PPD-Adobe-4.x header */
+ PPD_ALLOC_ERROR, /* Memory allocation error */
+ PPD_MISSING_VALUE, /* Missing value string */
+ PPD_INTERNAL_ERROR, /* Internal error */
+ PPD_NESTED_OPEN_GROUP, /* OpenGroup without a CloseGroup first */
+ PPD_BAD_ORDER_DEPENDENCY, /* Bad OrderDependency */
+ PPD_BAD_UI_CONSTRAINTS /* Bad UIConstraints */
+} ppd_status_t;
+
typedef struct /**** PPD Attribute Structure ****/
{
char name[PPD_MAX_NAME],
extern float ppdPageWidth(ppd_file_t *ppd, const char *name);
/**** New in CUPS 1.1.19 ****/
+extern const char *ppdErrorString(ppd_status_t status);
extern const char *ppdFindAttr(ppd_file_t *ppd, const char *name,
const char *spec);
extern const char *ppdFindNextAttr(ppd_file_t *ppd, const char *name,
const char *spec);
+extern ppd_status_t ppdLastError(int *line);
/*
* C++ magic...
#endif /* !_CUPS_PPD_H_ */
/*
- * End of "$Id: ppd.h,v 1.28 2003/01/28 15:29:14 mike Exp $".
+ * End of "$Id: ppd.h,v 1.29 2003/01/29 17:03:37 mike Exp $".
*/
/*
- * "$Id: cupstestppd.c,v 1.4 2003/01/29 01:40:16 mike Exp $"
+ * "$Id: cupstestppd.c,v 1.5 2003/01/29 17:03:38 mike Exp $"
*
* PPD test program for the Common UNIX Printing System (CUPS).
*
char *argv[]) /* I - Command-line arguments */
{
int i, j, k, m; /* Looping vars */
+ int files; /* Number of files */
int verbose; /* Want verbose output? */
int status; /* Exit status */
int errors; /* Number of conformance errors */
+ ppd_status_t error; /* Status of ppdOpen*() */
+ int line; /* Line number for error */
ppd_file_t *ppd; /* PPD file record */
ppd_size_t *size; /* Size record */
ppd_group_t *group; /* UI group */
verbose = 0;
ppd = NULL;
+ files = 0;
status = ERROR_NONE;
for (i = 1; i < argc; i ++)
* Open the PPD file...
*/
+ files ++;
+
if (argv[i][0] == '-')
{
/*
if (ppd == NULL)
{
- if (errno)
+ error = ppdLastError(&line);
+
+ if (error <= PPD_NULL_FILE)
{
status = ERROR_FILE_OPEN;
status = ERROR_PPD_FORMAT;
if (verbose >= 0)
- puts(" Unable to open PPD file using CUPS functions!\n");
+ printf(" Unable to open PPD file - %s on line %d.\n",
+ ppdErrorString(error), line);
}
continue;
ppdClose(ppd);
}
- if (!ppd && verbose >= 0)
+ if (!files && verbose >= 0)
{
puts("Usage: cupstestppd [-q] [-v] filename1.ppd [... filenameN.ppd]");
puts(" program | cupstestppd [-q] [-v] -");
/*
- * End of "$Id: cupstestppd.c,v 1.4 2003/01/29 01:40:16 mike Exp $".
+ * End of "$Id: cupstestppd.c,v 1.5 2003/01/29 17:03:38 mike Exp $".
*/