diff options
-rw-r--r-- | cups/ipp-file.c | 97 | ||||
-rw-r--r-- | cups/ipp-private.h | 9 | ||||
-rw-r--r-- | cups/ipp-vars.c | 9 | ||||
-rw-r--r-- | cups/testipp.c | 4 | ||||
-rw-r--r-- | test/ipptool.c | 4 |
5 files changed, 78 insertions, 45 deletions
diff --git a/cups/ipp-file.c b/cups/ipp-file.c index 4c1008282..70697082e 100644 --- a/cups/ipp-file.c +++ b/cups/ipp-file.c @@ -21,9 +21,9 @@ * Local functions... */ -static ipp_t *parse_collection(_ipp_file_t *f, _ipp_vars_t *v, _ipp_ferror_cb_t errorcb, void *user_data); -static int parse_value(_ipp_file_t *f, _ipp_vars_t *v, _ipp_ferror_cb_t errorcb, void *user_data, ipp_t *ipp, ipp_attribute_t **attr, int element); -static void report_error(_ipp_file_t *f, _ipp_ferror_cb_t errorcb, void *user_data, const char *message, ...) __attribute((__format__ (__printf__, 4, 5))); +static ipp_t *parse_collection(_ipp_file_t *f, _ipp_vars_t *v, void *user_data); +static int parse_value(_ipp_file_t *f, _ipp_vars_t *v, void *user_data, ipp_t *ipp, ipp_attribute_t **attr, int element); +static void report_error(_ipp_file_t *f, _ipp_vars_t *v, void *user_data, const char *message, ...) __attribute((__format__ (__printf__, 4, 5))); /* @@ -34,16 +34,16 @@ ipp_t * /* O - IPP attributes or @code NULL@ on failure */ _ippFileParse( _ipp_vars_t *v, /* I - Variables */ const char *filename, /* I - Name of file to parse */ - _ipp_ftoken_cb_t tokencb, /* I - Callback for unknown tokens */ - _ipp_ferror_cb_t errorcb, /* I - Callback for errors */ void *user_data) /* I - User data pointer */ { _ipp_file_t f; /* IPP data file information */ + ipp_t *attrs = NULL; /* Active IPP message */ ipp_attribute_t *attr = NULL; /* Current attribute */ char token[1024]; /* Token string */ + ipp_t *ignored = NULL; /* Ignored attributes */ - DEBUG_printf(("_ippFileParse(v=%p, filename=\"%s\", tokencb=%p, errorcb=%p, user_data=%p)", (void *)v, filename, (void *)tokencb, (void *)errorcb, user_data)); + DEBUG_printf(("_ippFileParse(v=%p, filename=\"%s\", user_data=%p)", (void *)v, filename, user_data)); /* * Initialize file info... @@ -63,7 +63,7 @@ _ippFileParse( * Do the callback with a NULL token to setup any initial state... */ - (*tokencb)(&f, v, user_data, NULL); + (*v->tokencb)(&f, v, user_data, NULL); /* * Read data file, using the callback function as needed... @@ -86,7 +86,7 @@ _ippFileParse( } else { - report_error(&f, errorcb, user_data, "Missing %s name and/or value on line %d of \"%s\".", token, f.linenum, f.filename); + report_error(&f, v, user_data, "Missing %s name and/or value on line %d of \"%s\".", token, f.linenum, f.filename); break; } } @@ -104,28 +104,48 @@ _ippFileParse( if (!_ippFileReadToken(&f, syntax, sizeof(syntax))) { - report_error(&f, errorcb, user_data, "Missing ATTR syntax on line %d of \"%s\".", f.linenum, f.filename); + report_error(&f, v, user_data, "Missing ATTR syntax on line %d of \"%s\".", f.linenum, f.filename); break; } else if ((value_tag = ippTagValue(syntax)) < IPP_TAG_UNSUPPORTED_VALUE) { - report_error(&f, errorcb, user_data, "Bad ATTR syntax \"%s\" on line %d of \"%s\".", syntax, f.linenum, f.filename); + report_error(&f, v, user_data, "Bad ATTR syntax \"%s\" on line %d of \"%s\".", syntax, f.linenum, f.filename); break; } if (!_ippFileReadToken(&f, name, sizeof(name)) || !name[0]) { - report_error(&f, errorcb, user_data, "Missing ATTR name on line %d of \"%s\".", f.linenum, f.filename); + report_error(&f, v, user_data, "Missing ATTR name on line %d of \"%s\".", f.linenum, f.filename); break; } + if (!v->attrcb || (*v->attrcb)(&f, user_data, name)) + { + /* + * Add this attribute... + */ + + attrs = f.attrs; + } + else + { + /* + * Ignore this attribute... + */ + + if (!ignored) + ignored = ippNew(); + + attrs = ignored; + } + if (value_tag < IPP_TAG_INTEGER) { /* * Add out-of-band attribute - no value string needed... */ - ippAddOutOfBand(f.attrs, f.group_tag, value_tag, name); + ippAddOutOfBand(attrs, f.group_tag, value_tag, name); } else { @@ -133,9 +153,9 @@ _ippFileParse( * Add attribute with one or more values... */ - attr = ippAddString(f.attrs, f.group_tag, value_tag, name, NULL, NULL); + attr = ippAddString(attrs, f.group_tag, value_tag, name, NULL, NULL); - if (!parse_value(&f, v, errorcb, user_data, f.attrs, &attr, 0)) + if (!parse_value(&f, v, user_data, attrs, &attr, 0)) break; } @@ -146,7 +166,7 @@ _ippFileParse( * Additional value... */ - if (!parse_value(&f, v, errorcb, user_data, f.attrs, &attr, ippGetCount(attr))) + if (!parse_value(&f, v, user_data, attrs, &attr, ippGetCount(attr))) break; } else @@ -155,18 +175,21 @@ _ippFileParse( * Something else... */ - attr = NULL; + attr = NULL; + attrs = NULL; - if (!(*tokencb)(&f, v, user_data, token)) + if (!(*v->tokencb)(&f, v, user_data, token)) break; } } /* - * Close the file and free attributes, then return... + * Close the file and free ignored attributes, then return any attributes we + * kept... */ cupsFileClose(f.fp); + ippDelete(ignored); return (f.attrs); } @@ -364,7 +387,6 @@ static ipp_t * /* O - Collection value or @code NULL@ on error */ parse_collection( _ipp_file_t *f, /* I - IPP data file */ _ipp_vars_t *v, /* I - IPP variables */ - _ipp_ferror_cb_t errorcb, /* I - Error callback */ void *user_data) /* I - User data pointer */ { ipp_t *col = ippNew(); /* Collection value */ @@ -400,14 +422,14 @@ parse_collection( if (!_ippFileReadToken(f, syntax, sizeof(syntax))) { - report_error(f, errorcb, user_data, "Missing ATTR syntax on line %d of \"%s\".", f->linenum, f->filename); + report_error(f, v, user_data, "Missing ATTR syntax on line %d of \"%s\".", f->linenum, f->filename); ippDelete(col); col = NULL; break; } else if ((value_tag = ippTagValue(syntax)) < IPP_TAG_UNSUPPORTED_VALUE) { - report_error(f, errorcb, user_data, "Bad ATTR syntax \"%s\" on line %d of \"%s\".", syntax, f->linenum, f->filename); + report_error(f, v, user_data, "Bad ATTR syntax \"%s\" on line %d of \"%s\".", syntax, f->linenum, f->filename); ippDelete(col); col = NULL; break; @@ -415,7 +437,7 @@ parse_collection( if (!_ippFileReadToken(f, name, sizeof(name)) || !name[0]) { - report_error(f, errorcb, user_data, "Missing ATTR name on line %d of \"%s\".", f->linenum, f->filename); + report_error(f, v, user_data, "Missing ATTR name on line %d of \"%s\".", f->linenum, f->filename); ippDelete(col); col = NULL; break; @@ -437,7 +459,7 @@ parse_collection( attr = ippAddString(col, IPP_TAG_ZERO, value_tag, name, NULL, NULL); - if (!parse_value(f, v, errorcb, user_data, col, &attr, 0)) + if (!parse_value(f, v, user_data, col, &attr, 0)) { ippDelete(col); col = NULL; @@ -452,7 +474,7 @@ parse_collection( * Additional value... */ - if (!parse_value(f, v, errorcb, user_data, col, &attr, ippGetCount(attr))) + if (!parse_value(f, v, user_data, col, &attr, ippGetCount(attr))) { ippDelete(col); col = NULL; @@ -465,7 +487,7 @@ parse_collection( * Something else... */ - report_error(f, errorcb, user_data, "Unknown directive \"%s\" on line %d of \"%s\".", token, f->linenum, f->filename); + report_error(f, v, user_data, "Unknown directive \"%s\" on line %d of \"%s\".", token, f->linenum, f->filename); ippDelete(col); col = NULL; attr = NULL; @@ -485,7 +507,6 @@ parse_collection( static int /* O - 1 on success or 0 on error */ parse_value(_ipp_file_t *f, /* I - IPP data file */ _ipp_vars_t *v, /* I - IPP variables */ - _ipp_ferror_cb_t errorcb, /* I - Error callback */ void *user_data,/* I - User data pointer */ ipp_t *ipp, /* I - IPP message */ ipp_attribute_t **attr, /* IO - IPP attribute */ @@ -497,7 +518,7 @@ parse_value(_ipp_file_t *f, /* I - IPP data file */ if (!_ippFileReadToken(f, temp, sizeof(temp))) { - report_error(f, errorcb, user_data, "Missing value on line %d of \"%s\".", f->linenum, f->filename); + report_error(f, v, user_data, "Missing value on line %d of \"%s\".", f->linenum, f->filename); return (0); } @@ -529,7 +550,7 @@ parse_value(_ipp_file_t *f, /* I - IPP data file */ if (ptr <= value || xres <= 0 || yres <= 0 || !ptr || (_cups_strcasecmp(ptr, "dpi") && _cups_strcasecmp(ptr, "dpc") && _cups_strcasecmp(ptr, "dpcm") && _cups_strcasecmp(ptr, "other"))) { - report_error(f, errorcb, user_data, "Bad resolution value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename); + report_error(f, v, user_data, "Bad resolution value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename); return (0); } @@ -549,7 +570,7 @@ parse_value(_ipp_file_t *f, /* I - IPP data file */ if (sscanf(value, "%d-%d", &lower, &upper) != 2) { - report_error(f, errorcb, user_data, "Bad rangeOfInteger value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename); + report_error(f, v, user_data, "Bad rangeOfInteger value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename); return (0); } @@ -581,11 +602,11 @@ parse_value(_ipp_file_t *f, /* I - IPP data file */ if (strcmp(value, "{")) { - report_error(f, errorcb, user_data, "Bad ATTR collection value on line %d of \"%s\".", f->linenum, f->filename); + report_error(f, v, user_data, "Bad ATTR collection value on line %d of \"%s\".", f->linenum, f->filename); return (0); } - if ((col = parse_collection(f, v, errorcb, user_data)) == NULL) + if ((col = parse_collection(f, v, user_data)) == NULL) return (0); status = ippSetCollection(ipp, attr, element, col); @@ -596,7 +617,7 @@ parse_value(_ipp_file_t *f, /* I - IPP data file */ break; default : - report_error(f, errorcb, user_data, "Unsupported ATTR value on line %d of \"%s\".", f->linenum, f->filename); + report_error(f, v, user_data, "Unsupported ATTR value on line %d of \"%s\".", f->linenum, f->filename); return (0); } @@ -610,10 +631,10 @@ parse_value(_ipp_file_t *f, /* I - IPP data file */ static void report_error( - _ipp_file_t *f, /* I - IPP data file */ - _ipp_ferror_cb_t errorcb, /* I - Error callback function, if any */ - void *user_data, /* I - User data pointer */ - const char *message, /* I - Printf-style message */ + _ipp_file_t *f, /* I - IPP data file */ + _ipp_vars_t *v, /* I - Error callback function, if any */ + void *user_data, /* I - User data pointer */ + const char *message, /* I - Printf-style message */ ...) /* I - Additional arguments as needed */ { char buffer[8192]; /* Formatted string */ @@ -624,8 +645,8 @@ report_error( vsnprintf(buffer, sizeof(buffer), message, ap); va_end(ap); - if (errorcb) - (*errorcb)(f, user_data, buffer); + if (v->errorcb) + (*v->errorcb)(f, user_data, buffer); else fprintf(stderr, "%s\n", buffer); } diff --git a/cups/ipp-private.h b/cups/ipp-private.h index 428abcc1c..6a4708ed1 100644 --- a/cups/ipp-private.h +++ b/cups/ipp-private.h @@ -53,6 +53,8 @@ typedef struct /**** Attribute mapping data ****/ typedef struct _ipp_file_s _ipp_file_t;/**** File Parser ****/ typedef struct _ipp_vars_s _ipp_vars_t;/**** Variables ****/ +typedef int (*_ipp_fattr_cb_t)(_ipp_file_t *f, void *user_data, const char *attr); + /**** File Attribute (Filter) Callback ****/ typedef int (*_ipp_ferror_cb_t)(_ipp_file_t *f, void *user_data, const char *error); /**** File Parser Error Callback ****/ typedef int (*_ipp_ftoken_cb_t)(_ipp_file_t *f, _ipp_vars_t *v, void *user_data, const char *token); @@ -71,6 +73,9 @@ struct _ipp_vars_s /**** Variables ****/ int num_vars; /* Number of variables */ cups_option_t *vars; /* Array of variables */ int password_tries; /* Number of retries for password */ + _ipp_fattr_cb_t attrcb; /* Attribute (filter) callback */ + _ipp_ferror_cb_t errorcb; /* Error callback */ + _ipp_ftoken_cb_t tokencb; /* Token callback */ }; struct _ipp_file_s /**** File Parser */ @@ -94,14 +99,14 @@ extern const char *_ippCheckOptions(void); extern _ipp_option_t *_ippFindOption(const char *name); /* ipp-file.c */ -extern ipp_t *_ippFileParse(_ipp_vars_t *v, const char *filename, _ipp_ftoken_cb_t tokencb, _ipp_ferror_cb_t errorcb, void *user_data); +extern ipp_t *_ippFileParse(_ipp_vars_t *v, const char *filename, void *user_data); extern int _ippFileReadToken(_ipp_file_t *f, char *token, size_t tokensize); /* ipp-vars.c */ extern void _ippVarsDeinit(_ipp_vars_t *v); extern void _ippVarsExpand(_ipp_vars_t *v, char *dst, const char *src, size_t dstsize) __attribute__((nonnull(1,2,3))); extern const char *_ippVarsGet(_ipp_vars_t *v, const char *name); -extern void _ippVarsInit(_ipp_vars_t *v); +extern void _ippVarsInit(_ipp_vars_t *v, _ipp_fattr_cb_t attrcb, _ipp_ferror_cb_t errorcb, _ipp_ftoken_cb_t tokencb); extern const char *_ippVarsPasswordCB(const char *prompt, http_t *http, const char *method, const char *resource, void *user_data); extern int _ippVarsSet(_ipp_vars_t *v, const char *name, const char *value); diff --git a/cups/ipp-vars.c b/cups/ipp-vars.c index 28c023f3d..8d2ed7aa9 100644 --- a/cups/ipp-vars.c +++ b/cups/ipp-vars.c @@ -157,9 +157,16 @@ _ippVarsGet(_ipp_vars_t *v, /* I - IPP variables */ */ void -_ippVarsInit(_ipp_vars_t *v) /* I - IPP variables */ +_ippVarsInit(_ipp_vars_t *v, /* I - IPP variables */ + _ipp_fattr_cb_t attrcb, /* I - Attribute (filter) callback */ + _ipp_ferror_cb_t errorcb, /* I - Error callback */ + _ipp_ftoken_cb_t tokencb) /* I - Token callback */ { memset(v, 0, sizeof(_ipp_vars_t)); + + v->attrcb = attrcb; + v->errorcb = errorcb; + v->tokencb = tokencb; } diff --git a/cups/testipp.c b/cups/testipp.c index 1d198649d..0a9024f1f 100644 --- a/cups/testipp.c +++ b/cups/testipp.c @@ -715,8 +715,8 @@ main(int argc, /* I - Number of command-line arguments */ _ipp_vars_t v; /* IPP variables */ - _ippVarsInit(&v); - request = _ippFileParse(&v, argv[i], token_cb, NULL, NULL); + _ippVarsInit(&v, NULL, NULL, token_cb); + request = _ippFileParse(&v, argv[i], NULL); _ippVarsDeinit(&v); } else diff --git a/test/ipptool.c b/test/ipptool.c index d6b7904cc..3680d58d7 100644 --- a/test/ipptool.c +++ b/test/ipptool.c @@ -239,7 +239,7 @@ main(int argc, /* I - Number of command-line args */ init_data(&data); - _ippVarsInit(&vars); + _ippVarsInit(&vars, NULL, (_ipp_ferror_cb_t)error_cb, (_ipp_ftoken_cb_t)token_cb); /* * We need at least: @@ -1819,7 +1819,7 @@ do_tests(const char *testfile, /* I - Test file to use */ * Run tests... */ - _ippFileParse(vars, testfile, (_ipp_ftoken_cb_t)token_cb, (_ipp_ferror_cb_t)error_cb, (void *)data); + _ippFileParse(vars, testfile, (void *)data); /* * Close connection and return... |