diff options
Diffstat (limited to 'test/ipptool.c')
-rw-r--r-- | test/ipptool.c | 1562 |
1 files changed, 773 insertions, 789 deletions
diff --git a/test/ipptool.c b/test/ipptool.c index 23270ee5..dac5541c 100644 --- a/test/ipptool.c +++ b/test/ipptool.c @@ -1,9 +1,9 @@ /* - * "$Id: ipptool.c 10090 2011-10-25 22:39:56Z mike $" + * "$Id: ipptool.c 10461 2012-05-11 23:01:21Z mike $" * * ipptool command for CUPS. * - * Copyright 2007-2011 by Apple Inc. + * Copyright 2007-2012 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -17,6 +17,7 @@ * Contents: * * main() - Parse options and do tests. + * add_stringf() - Add a formatted string to an array. * compare_vars() - Compare two variables. * do_tests() - Do tests as specified in the test file. * expand_variables() - Expand variables in a string. @@ -33,7 +34,6 @@ * print_csv() - Print a line of CSV text. * print_fatal_error() - Print a fatal error message. * print_line() - Print a line of formatted or CSV text. - * print_test_error() - Print a test error message. * print_xml_header() - Print a standard XML plist header. * print_xml_string() - Print an XML string with escaping. * print_xml_trailer() - Print the XML trailer with success/fail value. @@ -81,6 +81,13 @@ typedef enum _cups_output_e /**** Output mode ****/ _CUPS_OUTPUT_CSV /* Comma-separated values output */ } _cups_output_t; +typedef enum _cups_with_e /**** WITH flags ****/ +{ + _CUPS_WITH_LITERAL = 0, /* Match string is a literal value */ + _CUPS_WITH_ALL = 1, /* Must match all values */ + _CUPS_WITH_REGEX = 2 /* Match string is a regular expression */ +} _cups_with_t; + typedef struct _cups_expect_s /**** Expected attribute info ****/ { int optional, /* Optional attribute? */ @@ -94,9 +101,10 @@ typedef struct _cups_expect_s /**** Expected attribute info ****/ *define_match, /* Variable to define on match */ *define_no_match, /* Variable to define on no-match */ *define_value; /* Variable to define with value */ - int repeat_match, /* Repeat test on match */ + int repeat_limit, /* Maximum number of times to repeat */ + repeat_match, /* Repeat test on match */ repeat_no_match, /* Repeat test on no match */ - with_regex, /* WITH-VALUE is a regular expression */ + with_flags, /* WITH flags */ count; /* Expected count if > 0 */ ipp_tag_t in_group; /* IN-GROUP value */ } _cups_expect_t; @@ -106,7 +114,8 @@ typedef struct _cups_status_s /**** Status info ****/ ipp_status_t status; /* Expected status code */ char *if_defined, /* Only if variable is defined */ *if_not_defined; /* Only if variable is not defined */ - int repeat_match, /* Repeat the test when it does not match */ + int repeat_limit, /* Maximum number of times to repeat */ + repeat_match, /* Repeat the test when it does not match */ repeat_no_match; /* Repeat the test when it matches */ } _cups_status_t; @@ -171,14 +180,12 @@ const char * const URIStatusStrings[] = /* URI status strings */ * Local functions... */ +static void add_stringf(cups_array_t *a, const char *s, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); static int compare_vars(_cups_var_t *a, _cups_var_t *b); static int do_tests(_cups_vars_t *vars, const char *testfile); static void expand_variables(_cups_vars_t *vars, char *dst, const char *src, - size_t dstsize) -#ifdef __GNUC__ -__attribute((nonnull(1,2,3))) -#endif /* __GNUC__ */ -; + size_t dstsize) __attribute__((nonnull(1,2,3))); static int expect_matches(_cups_expect_t *expect, ipp_tag_t value_tag); static ipp_t *get_collection(_cups_vars_t *vars, FILE *fp, int *linenum); static char *get_filename(const char *testfile, char *dst, const char *src, @@ -193,17 +200,9 @@ static void print_col(ipp_t *col); static void print_csv(ipp_attribute_t *attr, int num_displayed, char **displayed, size_t *widths); static void print_fatal_error(const char *s, ...) -#ifdef __GNUC__ -__attribute__ ((__format__ (__printf__, 1, 2))) -#endif /* __GNUC__ */ -; + __attribute__ ((__format__ (__printf__, 1, 2))); static void print_line(ipp_attribute_t *attr, int num_displayed, char **displayed, size_t *widths); -static void print_test_error(const char *s, ...) -#ifdef __GNUC__ -__attribute__ ((__format__ (__printf__, 1, 2))) -#endif /* __GNUC__ */ -; static void print_xml_header(void); static void print_xml_string(const char *element, const char *s); static void print_xml_trailer(int success, const char *message); @@ -213,10 +212,11 @@ static void set_variable(_cups_vars_t *vars, const char *name, static void sigterm_handler(int sig); #endif /* WIN32 */ static int timeout_cb(http_t *http, void *user_data); -static void usage(void); -static int validate_attr(ipp_attribute_t *attr, int print); -static int with_value(char *value, int regex, ipp_attribute_t *attr, - int report, char *matchbuf, size_t matchlen); +static void usage(void) __attribute__((noreturn)); +static int validate_attr(cups_array_t *errors, ipp_attribute_t *attr); +static int with_value(cups_array_t *errors, char *value, int flags, + ipp_attribute_t *attr, char *matchbuf, + size_t matchlen); /* @@ -419,7 +419,11 @@ main(int argc, /* I - Number of command-line args */ */ snprintf(filename, sizeof(filename), "%s.gz", argv[i]); - if (access(filename, 0) && filename[0] != '/') + if (access(filename, 0) && filename[0] != '/' +#ifdef WIN32 + && (!isalpha(filename[0] & 255) || filename[1] != ':') +#endif /* WIN32 */ + ) { snprintf(filename, sizeof(filename), "%s/ipptool/%s", cg->cups_datadir, argv[i]); @@ -454,6 +458,9 @@ main(int argc, /* I - Number of command-line args */ set_variable(&vars, "filetype", "text/html"); else if (!_cups_strcasecmp(ext, ".jpg")) set_variable(&vars, "filetype", "image/jpeg"); + else if (!_cups_strcasecmp(ext, ".pcl") || + !_cups_strcasecmp(ext, ".pcl.gz")) + set_variable(&vars, "filetype", "application/vnd.hp-PCL"); else if (!_cups_strcasecmp(ext, ".pdf")) set_variable(&vars, "filetype", "application/pdf"); else if (!_cups_strcasecmp(ext, ".png")) @@ -505,8 +512,8 @@ main(int argc, /* I - Number of command-line args */ if (Output == _CUPS_OUTPUT_PLIST && interval) { - _cupsLangPuts(stderr, _("ipptool: \"-i\" is incompatible with " - "\"-X\".")); + _cupsLangPuts(stderr, _("ipptool: \"-i\" and \"-n\" are " + "incompatible with -X\".")); usage(); } break; @@ -529,8 +536,8 @@ main(int argc, /* I - Number of command-line args */ if (Output == _CUPS_OUTPUT_PLIST && repeat) { - _cupsLangPuts(stderr, _("ipptool: \"-n\" is incompatible with " - "\"-X\".")); + _cupsLangPuts(stderr, _("ipptool: \"-i\" and \"-n\" are " + "incompatible with -X\".")); usage(); } break; @@ -618,7 +625,11 @@ main(int argc, /* I - Number of command-line args */ usage(); } - if (access(argv[i], 0) && argv[i][0] != '/') + if (access(argv[i], 0) && argv[i][0] != '/' +#ifdef WIN32 + && (!isalpha(argv[i][0] & 255) || argv[i][1] != ':') +#endif /* WIN32 */ + ) { snprintf(testname, sizeof(testname), "%s/ipptool/%s", cg->cups_datadir, argv[i]); @@ -681,6 +692,42 @@ main(int argc, /* I - Number of command-line args */ /* + * 'add_stringf()' - Add a formatted string to an array. + */ + +static void +add_stringf(cups_array_t *a, /* I - Array */ + const char *s, /* I - Printf-style format string */ + ...) /* I - Additional args as needed */ +{ + char buffer[10240]; /* Format buffer */ + va_list ap; /* Argument pointer */ + + + /* + * Don't bother is the array is NULL... + */ + + if (!a) + return; + + /* + * Format the message... + */ + + va_start(ap, s); + vsnprintf(buffer, sizeof(buffer), s, ap); + va_end(ap); + + /* + * Add it to the array... + */ + + cupsArrayAdd(a, buffer); +} + + +/* * 'compare_vars()' - Compare two variables. */ @@ -708,6 +755,9 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ show_header = 1, /* Show the test header? */ ignore_errors, /* Ignore test failures? */ skip_previous = 0, /* Skip on previous test failure? */ + repeat_count, /* Repeat count */ + repeat_interval, /* Repeat interval */ + repeat_prev, /* Previous repeat interval */ repeat_test; /* Repeat a test? */ http_t *http = NULL; /* HTTP connection to server */ FILE *fp = NULL; /* Test file */ @@ -744,7 +794,9 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ int num_displayed = 0; /* Number of displayed attributes */ char *displayed[200]; /* Displayed attributes */ size_t widths[200]; /* Width of columns */ - cups_array_t *a; /* Duplicate attribute array */ + cups_array_t *a, /* Duplicate attribute array */ + *errors = NULL; /* Errors array */ + const char *error; /* Current error */ /* @@ -789,6 +841,8 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ CUPS_SRAND(time(NULL)); + errors = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, + (cups_afree_func_t)free); pass = 1; linenum = 1; request_id = (CUPS_RAND() % 1000) * 137 + 1; @@ -1122,14 +1176,17 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ _cups_strcasecmp(token, "IF-NOT-DEFINED") && _cups_strcasecmp(token, "IN-GROUP") && _cups_strcasecmp(token, "OF-TYPE") && + _cups_strcasecmp(token, "REPEAT-LIMIT") && _cups_strcasecmp(token, "REPEAT-MATCH") && _cups_strcasecmp(token, "REPEAT-NO-MATCH") && _cups_strcasecmp(token, "SAME-COUNT-AS") && + _cups_strcasecmp(token, "WITH-ALL-VALUES") && _cups_strcasecmp(token, "WITH-VALUE")) last_expect = NULL; if (_cups_strcasecmp(token, "IF-DEFINED") && _cups_strcasecmp(token, "IF-NOT-DEFINED") && + _cups_strcasecmp(token, "REPEAT-LIMIT") && _cups_strcasecmp(token, "REPEAT-MATCH") && _cups_strcasecmp(token, "REPEAT-NO-MATCH")) last_status = NULL; @@ -1156,7 +1213,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ if ((tempcol = realloc(lastcol, sizeof(ipp_attribute_t) + (lastcol->num_values + 1) * - sizeof(ipp_value_t))) == NULL) + sizeof(_ipp_value_t))) == NULL) { print_fatal_error("Unable to allocate memory on line %d.", linenum); pass = 0; @@ -1509,21 +1566,22 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ } expand_variables(vars, token, temp, sizeof(token)); + attrptr = NULL; switch (value) { case IPP_TAG_BOOLEAN : if (!_cups_strcasecmp(token, "true")) - ippAddBoolean(request, group, attr, 1); + attrptr = ippAddBoolean(request, group, attr, 1); else - ippAddBoolean(request, group, attr, atoi(token)); + attrptr = ippAddBoolean(request, group, attr, atoi(token)); break; case IPP_TAG_INTEGER : case IPP_TAG_ENUM : if (!strchr(token, ',')) - ippAddInteger(request, group, value, attr, - strtol(token, &tokenptr, 0)); + attrptr = ippAddInteger(request, group, value, attr, + strtol(token, &tokenptr, 0)); else { int values[100], /* Values */ @@ -1542,7 +1600,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ num_values ++; } - ippAddIntegers(request, group, value, attr, num_values, values); + attrptr = ippAddIntegers(request, group, value, attr, num_values, values); } if (!tokenptr || *tokenptr) @@ -1568,7 +1626,9 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ } if (ptr <= token || xres <= 0 || yres <= 0 || !ptr || - (_cups_strcasecmp(ptr, "dpi") && _cups_strcasecmp(ptr, "dpc") && + (_cups_strcasecmp(ptr, "dpi") && + _cups_strcasecmp(ptr, "dpc") && + _cups_strcasecmp(ptr, "dpcm") && _cups_strcasecmp(ptr, "other"))) { print_fatal_error("Bad resolution value \"%s\" on line %d.", @@ -1578,14 +1638,15 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ } if (!_cups_strcasecmp(ptr, "dpi")) - ippAddResolution(request, group, attr, IPP_RES_PER_INCH, - xres, yres); - else if (!_cups_strcasecmp(ptr, "dpc")) - ippAddResolution(request, group, attr, IPP_RES_PER_CM, - xres, yres); + attrptr = ippAddResolution(request, group, attr, IPP_RES_PER_INCH, + xres, yres); + else if (!_cups_strcasecmp(ptr, "dpc") || + !_cups_strcasecmp(ptr, "dpcm")) + attrptr = ippAddResolution(request, group, attr, IPP_RES_PER_CM, + xres, yres); else - ippAddResolution(request, group, attr, (ipp_res_t)0, - xres, yres); + attrptr = ippAddResolution(request, group, attr, (ipp_res_t)0, + xres, yres); } break; @@ -1610,8 +1671,8 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ goto test_exit; } - ippAddRanges(request, group, attr, num_vals / 2, lowers, - uppers); + attrptr = ippAddRanges(request, group, attr, num_vals / 2, lowers, + uppers); } break; @@ -1623,7 +1684,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ if (col) { - lastcol = ippAddCollection(request, group, attr, col); + attrptr = lastcol = ippAddCollection(request, group, attr, col); ippDelete(col); } else @@ -1658,7 +1719,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ case IPP_TAG_LANGUAGE : case IPP_TAG_MIMETYPE : if (!strchr(token, ',')) - ippAddString(request, group, value, attr, NULL, token); + attrptr = ippAddString(request, group, value, attr, NULL, token); else { /* @@ -1680,11 +1741,19 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ num_values ++; } - ippAddStrings(request, group, value, attr, num_values, - NULL, (const char **)values); + attrptr = ippAddStrings(request, group, value, attr, num_values, + NULL, (const char **)values); } break; } + + if (!attrptr) + { + print_fatal_error("Unable to add attribute on line %d: %s", linenum, + cupsLastErrorString()); + pass = 0; + goto test_exit; + } } else if (!_cups_strcasecmp(token, "FILE")) { @@ -1737,6 +1806,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ last_status->if_defined = NULL; last_status->if_not_defined = NULL; + last_status->repeat_limit = 1000; last_status->repeat_match = 0; last_status->repeat_no_match = 0; } @@ -1764,6 +1834,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ num_expects ++; memset(last_expect, 0, sizeof(_cups_expect_t)); + last_expect->repeat_limit = 1000; if (token[0] == '!') { @@ -1909,6 +1980,33 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ goto test_exit; } } + else if (!_cups_strcasecmp(token, "REPEAT-LIMIT")) + { + if (!get_token(fp, token, sizeof(token), &linenum)) + { + print_fatal_error("Missing REPEAT-LIMIT value on line %d.", linenum); + pass = 0; + goto test_exit; + } + else if (atoi(token) <= 0) + { + print_fatal_error("Bad REPEAT-LIMIT value on line %d.", linenum); + pass = 0; + goto test_exit; + } + + if (last_status) + last_status->repeat_limit = atoi(token); + else if (last_expect) + last_expect->repeat_limit = atoi(token); + else + { + print_fatal_error("REPEAT-LIMIT without a preceding EXPECT or STATUS " + "on line %d.", linenum); + pass = 0; + goto test_exit; + } + } else if (!_cups_strcasecmp(token, "REPEAT-MATCH")) { if (last_status) @@ -1998,11 +2096,15 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ goto test_exit; } } - else if (!_cups_strcasecmp(token, "WITH-VALUE")) + else if (!_cups_strcasecmp(token, "WITH-ALL-VALUES") || + !_cups_strcasecmp(token, "WITH-VALUE")) { + if (!_cups_strcasecmp(token, "WITH-ALL-VALUES") && last_expect) + last_expect->with_flags = _CUPS_WITH_ALL; + if (!get_token(fp, temp, sizeof(temp), &linenum)) { - print_fatal_error("Missing WITH-VALUE value on line %d.", linenum); + print_fatal_error("Missing %s value on line %d.", token, linenum); pass = 0; goto test_exit; } @@ -2024,7 +2126,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ */ last_expect->with_value = calloc(1, tokenptr - token); - last_expect->with_regex = 1; + last_expect->with_flags |= _CUPS_WITH_REGEX; if (last_expect->with_value) memcpy(last_expect->with_value, token + 1, tokenptr - token - 1); @@ -2036,11 +2138,12 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ */ last_expect->with_value = strdup(token); + last_expect->with_flags |= _CUPS_WITH_LITERAL; } } else { - print_fatal_error("WITH-VALUE without a preceding EXPECT on line %d.", + print_fatal_error("%s without a preceding EXPECT on line %d.", token, linenum); pass = 0; goto test_exit; @@ -2146,8 +2249,14 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ goto skip_error; } + repeat_count = 0; + repeat_interval = 1; + repeat_prev = 1; + do { + repeat_count ++; + status = HTTP_OK; if (transfer == _CUPS_TRANSFER_CHUNKED || @@ -2228,7 +2337,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ status = httpGetStatus(http); } - if (!Cancel && status == HTTP_ERROR && + if (!Cancel && status == HTTP_ERROR && http->error != EINVAL && #ifdef WIN32 http->error != WSAETIMEDOUT) #else @@ -2240,35 +2349,65 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ } else if (status == HTTP_ERROR) { - if (!Cancel) - httpReconnect(http); - prev_pass = 0; + break; + } + else if (status != HTTP_OK) + { + httpFlush(http); + break; } } } + if (!Cancel && status == HTTP_ERROR && http->error != EINVAL && +#ifdef WIN32 + http->error != WSAETIMEDOUT) +#else + http->error != ETIMEDOUT) +#endif /* WIN32 */ + { + if (httpReconnect(http)) + prev_pass = 0; + } + else if (status == HTTP_ERROR) + { + if (!Cancel) + httpReconnect(http); + + prev_pass = 0; + } + else if (status != HTTP_OK) + { + httpFlush(http); + prev_pass = 0; + } + /* * Check results of request... */ - if (!response) - prev_pass = pass = 0; - else - { - if (http->version != HTTP_1_1) - prev_pass = pass = 0; + cupsArrayClear(errors); - if (response->state != IPP_DATA) - prev_pass = pass = 0; + if (http->version != HTTP_1_1) + add_stringf(errors, "Bad HTTP version (%d.%d)", http->version / 100, + http->version % 100); - if (response->request.status.request_id != request_id) - prev_pass = pass = 0; + if (!response) + { + /* + * No response, log error... + */ - if (version && - (response->request.status.version[0] != (version / 10) || - response->request.status.version[1] != (version % 10))) - prev_pass = pass = 0; + add_stringf(errors, "IPP request failed with status %s (%s)", + ippErrorString(cupsLastError()), + cupsLastErrorString()); + } + else + { + /* + * Collect common attribute values... + */ if ((attrptr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL) @@ -2288,42 +2427,130 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ set_variable(vars, "notify-subscription-id", temp); } - attrptr = response->attrs; - if (!attrptr || !attrptr->name || - attrptr->value_tag != IPP_TAG_CHARSET || - attrptr->group_tag != IPP_TAG_OPERATION || - attrptr->num_values != 1 || - strcmp(attrptr->name, "attributes-charset")) - prev_pass = pass = 0; + /* + * Check response, validating groups and attributes and logging errors + * as needed... + */ - if (attrptr) + if (response->state != IPP_DATA) + add_stringf(errors, + "Missing end-of-attributes-tag in response " + "(RFC 2910 section 3.5.1)"); + + if (version && + (response->request.status.version[0] != (version / 10) || + response->request.status.version[1] != (version % 10))) + add_stringf(errors, + "Bad version %d.%d in response - expected %d.%d " + "(RFC 2911 section 3.1.8).", + response->request.status.version[0], + response->request.status.version[1], + version / 10, version % 10); + + if (response->request.status.request_id != request_id) + add_stringf(errors, + "Bad request ID %d in response - expected %d " + "(RFC 2911 section 3.1.1)", + response->request.status.request_id, request_id); + + attrptr = response->attrs; + if (!attrptr) + add_stringf(errors, + "Missing first attribute \"attributes-charset " + "(charset)\" in group operation-attributes-tag " + "(RFC 2911 section 3.1.4)."); + else { - attrptr = attrptr->next; - if (!attrptr || !attrptr->name || - attrptr->value_tag != IPP_TAG_LANGUAGE || + if (!attrptr->name || + attrptr->value_tag != IPP_TAG_CHARSET || attrptr->group_tag != IPP_TAG_OPERATION || attrptr->num_values != 1 || - strcmp(attrptr->name, "attributes-natural-language")) - prev_pass = pass = 0; - } + strcmp(attrptr->name, "attributes-charset")) + add_stringf(errors, + "Bad first attribute \"%s (%s%s)\" in group %s, " + "expected \"attributes-charset (charset)\" in " + "group operation-attributes-tag (RFC 2911 section " + "3.1.4).", + attrptr->name ? attrptr->name : "(null)", + attrptr->num_values > 1 ? "1setOf " : "", + ippTagString(attrptr->value_tag), + ippTagString(attrptr->group_tag)); + + attrptr = attrptr->next; + if (!attrptr) + add_stringf(errors, + "Missing second attribute \"attributes-natural-" + "language (naturalLanguage)\" in group " + "operation-attributes-tag (RFC 2911 section " + "3.1.4)."); + else if (!attrptr->name || + attrptr->value_tag != IPP_TAG_LANGUAGE || + attrptr->group_tag != IPP_TAG_OPERATION || + attrptr->num_values != 1 || + strcmp(attrptr->name, "attributes-natural-language")) + add_stringf(errors, + "Bad first attribute \"%s (%s%s)\" in group %s, " + "expected \"attributes-natural-language " + "(naturalLanguage)\" in group " + "operation-attributes-tag (RFC 2911 section " + "3.1.4).", + attrptr->name ? attrptr->name : "(null)", + attrptr->num_values > 1 ? "1setOf " : "", + ippTagString(attrptr->value_tag), + ippTagString(attrptr->group_tag)); + } if ((attrptr = ippFindAttribute(response, "status-message", - IPP_TAG_ZERO)) != NULL && - (attrptr->value_tag != IPP_TAG_TEXT || - attrptr->group_tag != IPP_TAG_OPERATION || - attrptr->num_values != 1 || - (attrptr->value_tag == IPP_TAG_TEXT && - strlen(attrptr->values[0].string.text) > 255))) - prev_pass = pass = 0; + IPP_TAG_ZERO)) != NULL) + { + if (attrptr->value_tag != IPP_TAG_TEXT) + add_stringf(errors, + "status-message (text(255)) has wrong value tag " + "%s (RFC 2911 section 3.1.6.2).", + ippTagString(attrptr->value_tag)); + if (attrptr->group_tag != IPP_TAG_OPERATION) + add_stringf(errors, + "status-message (text(255)) has wrong group tag " + "%s (RFC 2911 section 3.1.6.2).", + ippTagString(attrptr->group_tag)); + if (attrptr->num_values != 1) + add_stringf(errors, + "status-message (text(255)) has %d values " + "(RFC 2911 section 3.1.6.2).", + attrptr->num_values); + if (attrptr->value_tag == IPP_TAG_TEXT && + strlen(attrptr->values[0].string.text) > 255) + add_stringf(errors, + "status-message (text(255)) has bad length %d" + " (RFC 2911 section 3.1.6.2).", + (int)strlen(attrptr->values[0].string.text)); + } if ((attrptr = ippFindAttribute(response, "detailed-status-message", - IPP_TAG_ZERO)) != NULL && - (attrptr->value_tag != IPP_TAG_TEXT || - attrptr->group_tag != IPP_TAG_OPERATION || - attrptr->num_values != 1 || - (attrptr->value_tag == IPP_TAG_TEXT && - strlen(attrptr->values[0].string.text) > 1023))) - prev_pass = pass = 0; + IPP_TAG_ZERO)) != NULL) + { + if (attrptr->value_tag != IPP_TAG_TEXT) + add_stringf(errors, + "detailed-status-message (text(MAX)) has wrong " + "value tag %s (RFC 2911 section 3.1.6.3).", + ippTagString(attrptr->value_tag)); + if (attrptr->group_tag != IPP_TAG_OPERATION) + add_stringf(errors, + "detailed-status-message (text(MAX)) has wrong " + "group tag %s (RFC 2911 section 3.1.6.3).", + ippTagString(attrptr->group_tag)); + if (attrptr->num_values != 1) + add_stringf(errors, + "detailed-status-message (text(MAX)) has %d values" + " (RFC 2911 section 3.1.6.3).", + attrptr->num_values); + if (attrptr->value_tag == IPP_TAG_TEXT && + strlen(attrptr->values[0].string.text) > 1023) + add_stringf(errors, + "detailed-status-message (text(MAX)) has bad " + "length %d (RFC 2911 section 3.1.6.3).", + (int)strlen(attrptr->values[0].string.text)); + } a = cupsArrayNew((cups_array_func_t)strcmp, NULL); @@ -2333,61 +2560,59 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ { if (attrptr->group_tag != group) { + int out_of_order = 0; /* Are attribute groups out-of-order? */ cupsArrayClear(a); + switch (attrptr->group_tag) { case IPP_TAG_ZERO : break; case IPP_TAG_OPERATION : - prev_pass = pass = 0; + out_of_order = 1; break; case IPP_TAG_UNSUPPORTED_GROUP : if (group != IPP_TAG_OPERATION) - prev_pass = pass = 0; + out_of_order = 1; break; case IPP_TAG_JOB : case IPP_TAG_PRINTER : if (group != IPP_TAG_OPERATION && group != IPP_TAG_UNSUPPORTED_GROUP) - prev_pass = pass = 0; + out_of_order = 1; break; case IPP_TAG_SUBSCRIPTION : if (group > attrptr->group_tag && group != IPP_TAG_DOCUMENT) - prev_pass = pass = 0; + out_of_order = 1; break; default : if (group > attrptr->group_tag) - prev_pass = pass = 0; + out_of_order = 1; break; } - if (!pass) - break; + if (out_of_order) + add_stringf(errors, "Attribute groups out of order (%s < %s)", + ippTagString(attrptr->group_tag), + ippTagString(group)); if (attrptr->group_tag != IPP_TAG_ZERO) group = attrptr->group_tag; } - if (!validate_attr(attrptr, 0)) - { - prev_pass = pass = 0; - break; - } + validate_attr(errors, attrptr); if (attrptr->name) { if (cupsArrayFind(a, attrptr->name)) - { - prev_pass = pass = 0; - break; - } + add_stringf(errors, "Duplicate \"%s\" attribute in %s group", + attrptr->name, ippTagString(group)); cupsArrayAdd(a, attrptr->name); } @@ -2395,6 +2620,11 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ cupsArrayDelete(a); + /* + * Now check the test-defined expected status-code and attribute + * values... + */ + for (i = 0; i < num_statuses; i ++) { if (statuses[i].if_defined && @@ -2407,17 +2637,39 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ if (response->request.status.status_code == statuses[i].status) { - if (statuses[i].repeat_match) + if (statuses[i].repeat_match && + repeat_count < statuses[i].repeat_limit) repeat_test = 1; break; } - else if (statuses[i].repeat_no_match) + else if (statuses[i].repeat_no_match && + repeat_count < statuses[i].repeat_limit) repeat_test = 1; } if (i == num_statuses && num_statuses > 0) - prev_pass = pass = 0; + { + for (i = 0; i < num_statuses; i ++) + { + if (statuses[i].if_defined && + !get_variable(vars, statuses[i].if_defined)) + continue; + + if (statuses[i].if_not_defined && + get_variable(vars, statuses[i].if_not_defined)) + continue; + + add_stringf(errors, "EXPECTED: STATUS %s (got %s)", + ippErrorString(statuses[i].status), + ippErrorString(cupsLastError())); + } + + if ((attrptr = ippFindAttribute(response, "status-message", + IPP_TAG_TEXT)) != NULL) + add_stringf(errors, "status-message=\"%s\"", + attrptr->values[0].string.text); + } for (i = num_expects, expect = expects; i > 0; i --, expect ++) { @@ -2439,27 +2691,62 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ if (expect->define_no_match) set_variable(vars, expect->define_no_match, "1"); else if (!expect->define_match && !expect->define_value) - prev_pass = pass = 0; + { + if (found && expect->not_expect) + add_stringf(errors, "NOT EXPECTED: %s", expect->name); + else if (!found && !(expect->not_expect || expect->optional)) + add_stringf(errors, "EXPECTED: %s", expect->name); + else if (found) + { + if (!expect_matches(expect, found->value_tag)) + add_stringf(errors, "EXPECTED: %s OF-TYPE %s (got %s)", + expect->name, expect->of_type, + ippTagString(found->value_tag)); + + if (expect->in_group && found->group_tag != expect->in_group) + add_stringf(errors, "EXPECTED: %s IN-GROUP %s (got %s).", + expect->name, ippTagString(expect->in_group), + ippTagString(found->group_tag)); + } + } - if (expect->repeat_no_match) + if (expect->repeat_no_match && + repeat_count < expect->repeat_limit) repeat_test = 1; continue; } if (found) - _ippAttrString(found, buffer, sizeof(buffer)); + ippAttributeString(found, buffer, sizeof(buffer)); if (found && - !with_value(expect->with_value, expect->with_regex, found, 0, + !with_value(NULL, expect->with_value, expect->with_flags, found, buffer, sizeof(buffer))) { if (expect->define_no_match) set_variable(vars, expect->define_no_match, "1"); else if (!expect->define_match && !expect->define_value) - prev_pass = pass = 0; + { + if (expect->with_flags & _CUPS_WITH_REGEX) + add_stringf(errors, "EXPECTED: %s %s /%s/", + expect->name, + (expect->with_flags & _CUPS_WITH_ALL) ? + "WITH-ALL-VALUES" : "WITH-VALUE", + expect->with_value); + else + add_stringf(errors, "EXPECTED: %s %s \"%s\"", + expect->name, + (expect->with_flags & _CUPS_WITH_ALL) ? + "WITH-ALL-VALUES" : "WITH-VALUE", + expect->with_value); + + with_value(errors, expect->with_value, expect->with_flags, found, + buffer, sizeof(buffer)); + } - if (expect->repeat_no_match) + if (expect->repeat_no_match && + repeat_count < expect->repeat_limit) repeat_test = 1; continue; @@ -2471,9 +2758,13 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ if (expect->define_no_match) set_variable(vars, expect->define_no_match, "1"); else if (!expect->define_match && !expect->define_value) - prev_pass = pass = 0; + { + add_stringf(errors, "EXPECTED: %s COUNT %d (got %d)", expect->name, + expect->count, found->num_values); + } - if (expect->repeat_no_match) + if (expect->repeat_no_match && + repeat_count < expect->repeat_limit) repeat_test = 1; continue; @@ -2489,9 +2780,21 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ if (expect->define_no_match) set_variable(vars, expect->define_no_match, "1"); else if (!expect->define_match && !expect->define_value) - prev_pass = pass = 0; + { + if (!attrptr) + add_stringf(errors, + "EXPECTED: %s (%d values) SAME-COUNT-AS %s " + "(not returned)", expect->name, + found->num_values, expect->same_count_as); + else if (attrptr->num_values != found->num_values) + add_stringf(errors, + "EXPECTED: %s (%d values) SAME-COUNT-AS %s " + "(%d values)", expect->name, found->num_values, + expect->same_count_as, attrptr->num_values); + } - if (expect->repeat_no_match) + if (expect->repeat_no_match && + repeat_count < expect->repeat_limit) repeat_test = 1; continue; @@ -2504,7 +2807,8 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ if (found && expect->define_value) set_variable(vars, expect->define_value, buffer); - if (found && expect->repeat_match) + if (found && expect->repeat_match && + repeat_count < expect->repeat_limit) repeat_test = 1; } } @@ -2515,7 +2819,22 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ */ if (repeat_test) - sleep(1); + { + if (Output == _CUPS_OUTPUT_TEST) + { + printf("%04d]\n", repeat_count); + fflush(stdout); + } + + sleep(repeat_interval); + repeat_interval = _cupsNextDelay(repeat_interval, &repeat_prev); + + if (Output == _CUPS_OUTPUT_TEST) + { + printf(" %-68.68s [", name); + fflush(stdout); + } + } } while (repeat_test); @@ -2523,6 +2842,9 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ request = NULL; + if (cupsArrayCount(errors) > 0) + prev_pass = pass = 0; + if (prev_pass) PassCount ++; else @@ -2582,7 +2904,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ attrptr = ippFindNextAttribute(response, displayed[i], IPP_TAG_ZERO)) { - width = _ippAttrString(attrptr, NULL, 0); + width = ippAttributeString(attrptr, NULL, 0); if (width > widths[i]) widths[i] = width; } @@ -2618,303 +2940,24 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ { puts("<key>Errors</key>"); puts("<array>"); - } - if (http->version != HTTP_1_1) - print_test_error("Bad HTTP version (%d.%d)", http->version / 100, - http->version % 100); + for (error = (char *)cupsArrayFirst(errors); + error; + error = (char *)cupsArrayNext(errors)) + print_xml_string("string", error); - if (!response) - print_test_error("IPP request failed with status %s (%s)", - ippErrorString(cupsLastError()), - cupsLastErrorString()); + puts("</array>"); + } else { - if (response->state != IPP_DATA) - print_test_error("Missing end-of-attributes-tag in response " - "(RFC 2910 section 3.5.1)"); - - if (version && - (response->request.status.version[0] != (version / 10) || - response->request.status.version[1] != (version % 10))) - print_test_error("Bad version %d.%d in response - expected %d.%d " - "(RFC 2911 section 3.1.8).", - response->request.status.version[0], - response->request.status.version[1], - version / 10, version % 10); - - if (response->request.status.request_id != request_id) - print_test_error("Bad request ID %d in response - expected %d " - "(RFC 2911 section 3.1.1)", - response->request.status.request_id, request_id); - - attrptr = response->attrs; - if (!attrptr) - print_test_error("Missing first attribute \"attributes-charset " - "(charset)\" in group operation-attributes-tag " - "(RFC 2911 section 3.1.4)."); - else - { - if (!attrptr->name || - attrptr->value_tag != IPP_TAG_CHARSET || - attrptr->group_tag != IPP_TAG_OPERATION || - attrptr->num_values != 1 || - strcmp(attrptr->name, "attributes-charset")) - print_test_error("Bad first attribute \"%s (%s%s)\" in group %s, " - "expected \"attributes-charset (charset)\" in " - "group operation-attributes-tag (RFC 2911 section " - "3.1.4).", - attrptr->name ? attrptr->name : "(null)", - attrptr->num_values > 1 ? "1setOf " : "", - ippTagString(attrptr->value_tag), - ippTagString(attrptr->group_tag)); - - attrptr = attrptr->next; - if (!attrptr) - print_test_error("Missing second attribute \"attributes-natural-" - "language (naturalLanguage)\" in group " - "operation-attributes-tag (RFC 2911 section " - "3.1.4)."); - else if (!attrptr->name || - attrptr->value_tag != IPP_TAG_LANGUAGE || - attrptr->group_tag != IPP_TAG_OPERATION || - attrptr->num_values != 1 || - strcmp(attrptr->name, "attributes-natural-language")) - print_test_error("Bad first attribute \"%s (%s%s)\" in group %s, " - "expected \"attributes-natural-language " - "(naturalLanguage)\" in group " - "operation-attributes-tag (RFC 2911 section " - "3.1.4).", - attrptr->name ? attrptr->name : "(null)", - attrptr->num_values > 1 ? "1setOf " : "", - ippTagString(attrptr->value_tag), - ippTagString(attrptr->group_tag)); - } - - if ((attrptr = ippFindAttribute(response, "status-message", - IPP_TAG_ZERO)) != NULL) - { - if (attrptr->value_tag != IPP_TAG_TEXT) - print_test_error("status-message (text(255)) has wrong value tag " - "%s (RFC 2911 section 3.1.6.2).", - ippTagString(attrptr->value_tag)); - if (attrptr->group_tag != IPP_TAG_OPERATION) - print_test_error("status-message (text(255)) has wrong group tag " - "%s (RFC 2911 section 3.1.6.2).", - ippTagString(attrptr->group_tag)); - if (attrptr->num_values != 1) - print_test_error("status-message (text(255)) has %d values " - "(RFC 2911 section 3.1.6.2).", - attrptr->num_values); - if (attrptr->value_tag == IPP_TAG_TEXT && - strlen(attrptr->values[0].string.text) > 255) - print_test_error("status-message (text(255)) has bad length %d" - " (RFC 2911 section 3.1.6.2).", - (int)strlen(attrptr->values[0].string.text)); - } - - if ((attrptr = ippFindAttribute(response, "detailed-status-message", - IPP_TAG_ZERO)) != NULL) - { - if (attrptr->value_tag != IPP_TAG_TEXT) - print_test_error("detailed-status-message (text(MAX)) has wrong " - "value tag %s (RFC 2911 section 3.1.6.3).", - ippTagString(attrptr->value_tag)); - if (attrptr->group_tag != IPP_TAG_OPERATION) - print_test_error("detailed-status-message (text(MAX)) has wrong " - "group tag %s (RFC 2911 section 3.1.6.3).", - ippTagString(attrptr->group_tag)); - if (attrptr->num_values != 1) - print_test_error("detailed-status-message (text(MAX)) has %d values" - " (RFC 2911 section 3.1.6.3).", - attrptr->num_values); - if (attrptr->value_tag == IPP_TAG_TEXT && - strlen(attrptr->values[0].string.text) > 1023) - print_test_error("detailed-status-message (text(MAX)) has bad " - "length %d (RFC 2911 section 3.1.6.3).", - (int)strlen(attrptr->values[0].string.text)); - } - - a = cupsArrayNew((cups_array_func_t)strcmp, NULL); - - for (attrptr = response->attrs, group = attrptr->group_tag; - attrptr; - attrptr = attrptr->next) - { - if (attrptr->group_tag != group) - { - cupsArrayClear(a); - - switch (attrptr->group_tag) - { - case IPP_TAG_ZERO : - break; - - case IPP_TAG_OPERATION : - prev_pass = pass = 0; - break; - - case IPP_TAG_UNSUPPORTED_GROUP : - if (group != IPP_TAG_OPERATION) - print_test_error("Attribute groups out of order (%s < %s)", - ippTagString(attrptr->group_tag), - ippTagString(group)); - break; - - case IPP_TAG_JOB : - case IPP_TAG_PRINTER : - if (group != IPP_TAG_OPERATION && - group != IPP_TAG_UNSUPPORTED_GROUP) - print_test_error("Attribute groups out of order (%s < %s)", - ippTagString(attrptr->group_tag), - ippTagString(group)); - break; - - case IPP_TAG_SUBSCRIPTION : - if (group > attrptr->group_tag && - group != IPP_TAG_DOCUMENT) - print_test_error("Attribute groups out of order (%s < %s)", - ippTagString(attrptr->group_tag), - ippTagString(group)); - break; - - default : - if (group > attrptr->group_tag) - print_test_error("Attribute groups out of order (%s < %s)", - ippTagString(attrptr->group_tag), - ippTagString(group)); - break; - } - - if (attrptr->group_tag != IPP_TAG_ZERO) - group = attrptr->group_tag; - } - - validate_attr(attrptr, 1); - - if (attrptr->name) - { - if (cupsArrayFind(a, attrptr->name)) - print_test_error("Duplicate \"%s\" attribute in %s group", - attrptr->name, ippTagString(group)); - - cupsArrayAdd(a, attrptr->name); - } - } - - cupsArrayDelete(a); - - for (i = 0; i < num_statuses; i ++) - { - if (statuses[i].if_defined && - !get_variable(vars, statuses[i].if_defined)) - continue; - - if (statuses[i].if_not_defined && - get_variable(vars, statuses[i].if_not_defined)) - continue; - - if (response->request.status.status_code == statuses[i].status) - break; - } - - if (i == num_statuses && num_statuses > 0) - { - for (i = 0; i < num_statuses; i ++) - { - if (statuses[i].if_defined && - !get_variable(vars, statuses[i].if_defined)) - continue; - - if (statuses[i].if_not_defined && - get_variable(vars, statuses[i].if_not_defined)) - continue; - - print_test_error("EXPECTED: STATUS %s (got %s)", - ippErrorString(statuses[i].status), - ippErrorString(cupsLastError())); - } - - if ((attrptr = ippFindAttribute(response, "status-message", - IPP_TAG_TEXT)) != NULL) - print_test_error("status-message=\"%s\"", - attrptr->values[0].string.text); - } - - for (i = num_expects, expect = expects; i > 0; i --, expect ++) - { - if (expect->define_match || expect->define_no_match || - expect->define_value) - continue; - - if (expect->if_defined && !get_variable(vars, expect->if_defined)) - continue; - - if (expect->if_not_defined && - get_variable(vars, expect->if_not_defined)) - continue; - - found = ippFindAttribute(response, expect->name, IPP_TAG_ZERO); - - if (found && expect->not_expect) - print_test_error("NOT EXPECTED: %s", expect->name); - else if (!found && !(expect->not_expect || expect->optional)) - print_test_error("EXPECTED: %s", expect->name); - else if (found) - { - if (!expect_matches(expect, found->value_tag)) - print_test_error("EXPECTED: %s OF-TYPE %s (got %s)", - expect->name, expect->of_type, - ippTagString(found->value_tag)); - - if (expect->in_group && found->group_tag != expect->in_group) - print_test_error("EXPECTED: %s IN-GROUP %s (got %s).", - expect->name, ippTagString(expect->in_group), - ippTagString(found->group_tag)); - - if (!with_value(expect->with_value, expect->with_regex, found, 0, - buffer, sizeof(buffer))) - { - if (expect->with_regex) - print_test_error("EXPECTED: %s WITH-VALUE /%s/", - expect->name, expect->with_value); - else - print_test_error("EXPECTED: %s WITH-VALUE \"%s\"", - expect->name, expect->with_value); - - with_value(expect->with_value, expect->with_regex, found, 1, - buffer, sizeof(buffer)); - } - - if (expect->count > 0 && found->num_values != expect->count) - { - print_test_error("EXPECTED: %s COUNT %d (got %d)", expect->name, - expect->count, found->num_values); - } - - if (expect->same_count_as) - { - attrptr = ippFindAttribute(response, expect->same_count_as, - IPP_TAG_ZERO); - - if (!attrptr) - print_test_error("EXPECTED: %s (%d values) SAME-COUNT-AS %s " - "(not returned)", expect->name, - found->num_values, expect->same_count_as); - else if (attrptr->num_values != found->num_values) - print_test_error("EXPECTED: %s (%d values) SAME-COUNT-AS %s " - "(%d values)", expect->name, found->num_values, - expect->same_count_as, attrptr->num_values); - } - } - } + for (error = (char *)cupsArrayFirst(errors); + error; + error = (char *)cupsArrayNext(errors)) + printf(" %s\n", error); } - - if (Output == _CUPS_OUTPUT_PLIST) - puts("</array>"); } - if (num_displayed > 0 && !Verbosity && + if (num_displayed > 0 && !Verbosity && response && (Output == _CUPS_OUTPUT_TEST || Output == _CUPS_OUTPUT_PLIST)) { for (attrptr = response->attrs; @@ -2986,6 +3029,8 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ test_exit: + cupsArrayDelete(errors); + if (fp) fclose(fp); @@ -3235,7 +3280,7 @@ get_collection(_cups_vars_t *vars, /* I - Variables */ if ((tempcol = realloc(lastcol, sizeof(ipp_attribute_t) + (lastcol->num_values + 1) * - sizeof(ipp_value_t))) == NULL) + sizeof(_ipp_value_t))) == NULL) { print_fatal_error("Unable to allocate memory on line %d.", *linenum); goto col_error; @@ -3317,7 +3362,9 @@ get_collection(_cups_vars_t *vars, /* I - Variables */ char units[6]; /* Units */ if (sscanf(token, "%dx%d%5s", &xres, &yres, units) != 3 || - (_cups_strcasecmp(units, "dpi") && _cups_strcasecmp(units, "dpc") && + (_cups_strcasecmp(units, "dpi") && + _cups_strcasecmp(units, "dpc") && + _cups_strcasecmp(units, "dpcm") && _cups_strcasecmp(units, "other"))) { print_fatal_error("Bad resolution value \"%s\" on line %d.", @@ -3328,7 +3375,8 @@ get_collection(_cups_vars_t *vars, /* I - Variables */ if (!_cups_strcasecmp(units, "dpi")) ippAddResolution(col, IPP_TAG_ZERO, attr, xres, yres, IPP_RES_PER_INCH); - else if (!_cups_strcasecmp(units, "dpc")) + else if (!_cups_strcasecmp(units, "dpc") || + !_cups_strcasecmp(units, "dpcm")) ippAddResolution(col, IPP_TAG_ZERO, attr, xres, yres, IPP_RES_PER_CM); else @@ -3455,7 +3503,11 @@ get_filename(const char *testfile, /* I - Current test file */ if (*dstptr == '>') *dstptr = '\0'; } - else if (*src == '/' || !strchr(testfile, '/')) + else if (*src == '/' || !strchr(testfile, '/') +#ifdef WIN32 + || (isalpha(*src & 255) && src[1] == ':') +#endif /* WIN32 */ + ) { /* * Use the path as-is... @@ -3719,12 +3771,12 @@ print_attr(ipp_attribute_t *attr, /* I - Attribute to print */ attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? - "dpi" : "dpc"); + "dpi" : "dpcm"); else printf("%dx%d%s ", attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? - "dpi" : "dpc"); + "dpi" : "dpcm"); break; case IPP_TAG_DATE : @@ -3756,14 +3808,14 @@ print_attr(ipp_attribute_t *attr, /* I - Attribute to print */ if (Output == _CUPS_OUTPUT_PLIST) { fputs("<dict><key>language</key><string>", stdout); - print_xml_string(NULL, attr->values[i].string.charset); + print_xml_string(NULL, attr->values[i].string.language); fputs("</string><key>string</key><string>", stdout); print_xml_string(NULL, attr->values[i].string.text); puts("</string></dict>"); } else - printf("\"%s\"(%s) ", attr->values[i].string.text, - attr->values[i].string.charset); + printf("\"%s\"[%s] ", attr->values[i].string.text, + attr->values[i].string.language); break; case IPP_TAG_BEGIN_COLLECTION : @@ -3817,7 +3869,7 @@ print_attr(ipp_attribute_t *attr, /* I - Attribute to print */ ippTagString(attr->value_tag)); } - _ippAttrString(attr, buffer, sizeof(buffer)); + ippAttributeString(attr, buffer, sizeof(buffer)); puts(buffer); } } @@ -3871,7 +3923,7 @@ print_col(ipp_t *col) /* I - Collection attribute to print */ printf("%dx%d%s ", attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? - "dpi" : "dpc"); + "dpi" : "dpcm"); break; case IPP_TAG_STRING : @@ -3889,8 +3941,8 @@ print_col(ipp_t *col) /* I - Collection attribute to print */ case IPP_TAG_TEXTLANG : case IPP_TAG_NAMELANG : for (i = 0; i < attr->num_values; i ++) - printf("\"%s\",%s ", attr->values[i].string.text, - attr->values[i].string.charset); + printf("\"%s\"[%s] ", attr->values[i].string.text, + attr->values[i].string.language); break; case IPP_TAG_BEGIN_COLLECTION : @@ -3960,7 +4012,7 @@ print_csv( break; else if (!strcmp(current->name, displayed[i])) { - _ippAttrString(current, buffer, maxlength); + ippAttributeString(current, buffer, maxlength); break; } } @@ -4081,7 +4133,7 @@ print_line( break; else if (!strcmp(current->name, displayed[i])) { - _ippAttrString(current, buffer, maxlength); + ippAttributeString(current, buffer, maxlength); break; } } @@ -4118,37 +4170,6 @@ print_line( /* - * 'print_test_error()' - Print a test error message. - */ - -static void -print_test_error(const char *s, /* I - Printf-style format string */ - ...) /* I - Additional arguments as needed */ -{ - char buffer[10240]; /* Format buffer */ - va_list ap; /* Pointer to arguments */ - - - /* - * Format the error message... - */ - - va_start(ap, s); - vsnprintf(buffer, sizeof(buffer), s, ap); - va_end(ap); - - /* - * Then output it... - */ - - if (Output == _CUPS_OUTPUT_PLIST) - print_xml_string("string", buffer); - else - printf(" %s\n", buffer); -} - - -/* * 'print_xml_header()' - Print a standard XML plist header. */ @@ -4384,14 +4405,14 @@ usage(void) _cupsLangPuts(stderr, _(" -6 Connect using IPv6.")); _cupsLangPuts(stderr, _(" -C Send requests using " "chunking (default).")); - _cupsLangPuts(stderr, _(" -E Test with TLS " - "encryption.")); + _cupsLangPuts(stdout, _(" -E Test with HTTP Upgrade to " + "TLS.")); _cupsLangPuts(stderr, _(" -I Ignore errors.")); _cupsLangPuts(stderr, _(" -L Send requests using " "content-length.")); _cupsLangPuts(stderr, _(" -S Test with SSL " "encryption.")); - _cupsLangPuts(stderr, _(" -T Set the receive/send " + _cupsLangPuts(stderr, _(" -T seconds Set the receive/send " "timeout in seconds.")); _cupsLangPuts(stderr, _(" -V version Set default IPP " "version.")); @@ -4405,11 +4426,9 @@ usage(void) "the given time interval.")); _cupsLangPuts(stderr, _(" -n count Repeat the last file the " "given number of times.")); - _cupsLangPuts(stderr, _(" -q Be quiet - no output " - "except errors.")); + _cupsLangPuts(stderr, _(" -q Run silently.")); _cupsLangPuts(stderr, _(" -t Produce a test report.")); - _cupsLangPuts(stderr, _(" -v Show all attributes sent " - "and received.")); + _cupsLangPuts(stderr, _(" -v Be verbose.")); exit(1); } @@ -4420,8 +4439,8 @@ usage(void) */ static int /* O - 1 if valid, 0 otherwise */ -validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ - int print) /* I - 1 = report issues to stdout */ +validate_attr(cups_array_t *errors, /* I - Errors array */ + ipp_attribute_t *attr) /* I - Attribute to validate */ { int i; /* Looping var */ char scheme[64], /* Scheme from URI */ @@ -4456,18 +4475,18 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ { valid = 0; - if (print) - print_test_error("\"%s\": Bad attribute name - invalid character (RFC " - "2911 section 4.1.3).", attr->name); + add_stringf(errors, + "\"%s\": Bad attribute name - invalid character " + "(RFC 2911 section 4.1.3).", attr->name); } if ((ptr - attr->name) > 255) { valid = 0; - if (print) - print_test_error("\"%s\": Bad attribute name - bad length (RFC 2911 " - "section 4.1.3).", attr->name); + add_stringf(errors, + "\"%s\": Bad attribute name - bad length " + "(RFC 2911 section 4.1.3).", attr->name); } switch (attr->value_tag) @@ -4483,11 +4502,10 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ { valid = 0; - if (print) - print_test_error("\"%s\": Bad boolen value %d (RFC 2911 section " - "4.1.10).", attr->name, attr->values[i].boolean); - else - break; + add_stringf(errors, + "\"%s\": Bad boolen value %d " + "(RFC 2911 section 4.1.10).", attr->name, + attr->values[i].boolean); } } break; @@ -4499,12 +4517,10 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ { valid = 0; - if (print) - print_test_error("\"%s\": Bad enum value %d - out of range " - "(RFC 2911 section 4.1.4).", attr->name, - attr->values[i].integer); - else - break; + add_stringf(errors, + "\"%s\": Bad enum value %d - out of range " + "(RFC 2911 section 4.1.4).", attr->name, + attr->values[i].integer); } } break; @@ -4516,12 +4532,10 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ { valid = 0; - if (print) - print_test_error("\"%s\": Bad octetString value - bad length %d " - "(RFC 2911 section 4.1.10).", attr->name, - attr->values[i].unknown.length); - else - break; + add_stringf(errors, + "\"%s\": Bad octetString value - bad length %d " + "(RFC 2911 section 4.1.10).", attr->name, + attr->values[i].unknown.length); } } break; @@ -4535,99 +4549,81 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ { valid = 0; - if (print) - print_test_error("\"%s\": Bad dateTime month %u (RFC 2911 " - "section 4.1.13).", attr->name, date[2]); - else - break; + add_stringf(errors, + "\"%s\": Bad dateTime month %u " + "(RFC 2911 section 4.1.13).", attr->name, date[2]); } if (date[3] < 1 || date[3] > 31) { valid = 0; - if (print) - print_test_error("\"%s\": Bad dateTime day %u (RFC 2911 " - "section 4.1.13).", attr->name, date[3]); - else - break; + add_stringf(errors, + "\"%s\": Bad dateTime day %u " + "(RFC 2911 section 4.1.13).", attr->name, date[3]); } if (date[4] > 23) { valid = 0; - if (print) - print_test_error("\"%s\": Bad dateTime hours %u (RFC 2911 " - "section 4.1.13).", attr->name, date[4]); - else - break; + add_stringf(errors, + "\"%s\": Bad dateTime hours %u " + "(RFC 2911 section 4.1.13).", attr->name, date[4]); } if (date[5] > 59) { valid = 0; - if (print) - print_test_error("\"%s\": Bad dateTime minutes %u (RFC 2911 " - "section 4.1.13).", attr->name, date[5]); - else - break; + add_stringf(errors, + "\"%s\": Bad dateTime minutes %u " + "(RFC 2911 section 4.1.13).", attr->name, date[5]); } if (date[6] > 60) { valid = 0; - if (print) - print_test_error("\"%s\": Bad dateTime seconds %u (RFC 2911 " - "section 4.1.13).", attr->name, date[6]); - else - break; + add_stringf(errors, + "\"%s\": Bad dateTime seconds %u " + "(RFC 2911 section 4.1.13).", attr->name, date[6]); } if (date[7] > 9) { valid = 0; - if (print) - print_test_error("\"%s\": Bad dateTime deciseconds %u (RFC 2911 " - "section 4.1.13).", attr->name, date[7]); - else - break; + add_stringf(errors, + "\"%s\": Bad dateTime deciseconds %u " + "(RFC 2911 section 4.1.13).", attr->name, date[7]); } if (date[8] != '-' && date[8] != '+') { valid = 0; - if (print) - print_test_error("\"%s\": Bad dateTime UTC sign '%c' (RFC 2911 " - "section 4.1.13).", attr->name, date[8]); - else - break; + add_stringf(errors, + "\"%s\": Bad dateTime UTC sign '%c' " + "(RFC 2911 section 4.1.13).", attr->name, date[8]); } if (date[9] > 11) { valid = 0; - if (print) - print_test_error("\"%s\": Bad dateTime UTC hours %u (RFC 2911 " - "section 4.1.13).", attr->name, date[9]); - else - break; + add_stringf(errors, + "\"%s\": Bad dateTime UTC hours %u " + "(RFC 2911 section 4.1.13).", attr->name, date[9]); } if (date[10] > 59) { valid = 0; - if (print) - print_test_error("\"%s\": Bad dateTime UTC minutes %u (RFC 2911 " - "section 4.1.13).", attr->name, date[10]); - else - break; + add_stringf(errors, + "\"%s\": Bad dateTime UTC minutes %u " + "(RFC 2911 section 4.1.13).", attr->name, date[10]); } } break; @@ -4639,36 +4635,32 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ { valid = 0; - if (print) - print_test_error("\"%s\": Bad resolution value %dx%d%s - cross " - "feed resolution must be positive (RFC 2911 " - "section 4.1.13).", attr->name, - attr->values[i].resolution.xres, - attr->values[i].resolution.yres, - attr->values[i].resolution.units == - IPP_RES_PER_INCH ? "dpi" : - attr->values[i].resolution.units == - IPP_RES_PER_CM ? "dpc" : "unknown"); - else - break; + add_stringf(errors, + "\"%s\": Bad resolution value %dx%d%s - cross " + "feed resolution must be positive " + "(RFC 2911 section 4.1.13).", attr->name, + attr->values[i].resolution.xres, + attr->values[i].resolution.yres, + attr->values[i].resolution.units == + IPP_RES_PER_INCH ? "dpi" : + attr->values[i].resolution.units == + IPP_RES_PER_CM ? "dpcm" : "unknown"); } if (attr->values[i].resolution.yres <= 0) { valid = 0; - if (print) - print_test_error("\"%s\": Bad resolution value %dx%d%s - feed " - "resolution must be positive (RFC 2911 section " - "4.1.13).", attr->name, - attr->values[i].resolution.xres, - attr->values[i].resolution.yres, - attr->values[i].resolution.units == - IPP_RES_PER_INCH ? "dpi" : - attr->values[i].resolution.units == - IPP_RES_PER_CM ? "dpc" : "unknown"); - else - break; + add_stringf(errors, + "\"%s\": Bad resolution value %dx%d%s - feed " + "resolution must be positive " + "(RFC 2911 section 4.1.13).", attr->name, + attr->values[i].resolution.xres, + attr->values[i].resolution.yres, + attr->values[i].resolution.units == + IPP_RES_PER_INCH ? "dpi" : + attr->values[i].resolution.units == + IPP_RES_PER_CM ? "dpcm" : "unknown"); } if (attr->values[i].resolution.units != IPP_RES_PER_INCH && @@ -4676,17 +4668,15 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ { valid = 0; - if (print) - print_test_error("\"%s\": Bad resolution value %dx%d%s - bad " - "units value (RFC 2911 section 4.1.13).", - attr->name, attr->values[i].resolution.xres, - attr->values[i].resolution.yres, - attr->values[i].resolution.units == - IPP_RES_PER_INCH ? "dpi" : - attr->values[i].resolution.units == - IPP_RES_PER_CM ? "dpc" : "unknown"); - else - break; + add_stringf(errors, + "\"%s\": Bad resolution value %dx%d%s - bad " + "units value (RFC 2911 section 4.1.13).", + attr->name, attr->values[i].resolution.xres, + attr->values[i].resolution.yres, + attr->values[i].resolution.units == + IPP_RES_PER_INCH ? "dpi" : + attr->values[i].resolution.units == + IPP_RES_PER_CM ? "dpcm" : "unknown"); } } break; @@ -4698,13 +4688,11 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ { valid = 0; - if (print) - print_test_error("\"%s\": Bad rangeOfInteger value %d-%d - lower " - "greater than upper (RFC 2911 section 4.1.13).", - attr->name, attr->values[i].range.lower, - attr->values[i].range.upper); - else - break; + add_stringf(errors, + "\"%s\": Bad rangeOfInteger value %d-%d - lower " + "greater than upper (RFC 2911 section 4.1.13).", + attr->name, attr->values[i].range.lower, + attr->values[i].range.upper); } } break; @@ -4716,20 +4704,20 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ colattr; colattr = colattr->next) { - if (!validate_attr(colattr, 0)) + if (!validate_attr(NULL, colattr)) { valid = 0; break; } } - if (colattr && print) + if (colattr && errors) { - print_test_error("\"%s\": Bad collection value.", attr->name); + add_stringf(errors, "\"%s\": Bad collection value.", attr->name); while (colattr) { - validate_attr(colattr, print); + validate_attr(errors, colattr); colattr = colattr->next; } } @@ -4777,25 +4765,21 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ { valid = 0; - if (print) - print_test_error("\"%s\": Bad text value \"%s\" - bad UTF-8 " - "sequence (RFC 2911 section 4.1.1).", attr->name, - attr->values[i].string.text); - else - break; + add_stringf(errors, + "\"%s\": Bad text value \"%s\" - bad UTF-8 " + "sequence (RFC 2911 section 4.1.1).", attr->name, + attr->values[i].string.text); } if ((ptr - attr->values[i].string.text) > 1023) { valid = 0; - if (print) - print_test_error("\"%s\": Bad text value \"%s\" - bad length %d " - "(RFC 2911 section 4.1.1).", attr->name, - attr->values[i].string.text, - (int)strlen(attr->values[i].string.text)); - else - break; + add_stringf(errors, + "\"%s\": Bad text value \"%s\" - bad length %d " + "(RFC 2911 section 4.1.1).", attr->name, + attr->values[i].string.text, + (int)strlen(attr->values[i].string.text)); } } break; @@ -4841,25 +4825,21 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ { valid = 0; - if (print) - print_test_error("\"%s\": Bad name value \"%s\" - bad UTF-8 " - "sequence (RFC 2911 section 4.1.2).", attr->name, - attr->values[i].string.text); - else - break; + add_stringf(errors, + "\"%s\": Bad name value \"%s\" - bad UTF-8 " + "sequence (RFC 2911 section 4.1.2).", attr->name, + attr->values[i].string.text); } if ((ptr - attr->values[i].string.text) > 1023) { valid = 0; - if (print) - print_test_error("\"%s\": Bad name value \"%s\" - bad length %d " - "(RFC 2911 section 4.1.2).", attr->name, - attr->values[i].string.text, - (int)strlen(attr->values[i].string.text)); - else - break; + add_stringf(errors, + "\"%s\": Bad name value \"%s\" - bad length %d " + "(RFC 2911 section 4.1.2).", attr->name, + attr->values[i].string.text, + (int)strlen(attr->values[i].string.text)); } } break; @@ -4876,25 +4856,21 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ { valid = 0; - if (print) - print_test_error("\"%s\": Bad keyword value \"%s\" - invalid " - "character (RFC 2911 section 4.1.3).", - attr->name, attr->values[i].string.text); - else - break; + add_stringf(errors, + "\"%s\": Bad keyword value \"%s\" - invalid " + "character (RFC 2911 section 4.1.3).", + attr->name, attr->values[i].string.text); } if ((ptr - attr->values[i].string.text) > 255) { valid = 0; - if (print) - print_test_error("\"%s\": Bad keyword value \"%s\" - bad " - "length %d (RFC 2911 section 4.1.3).", - attr->name, attr->values[i].string.text, - (int)strlen(attr->values[i].string.text)); - else - break; + add_stringf(errors, + "\"%s\": Bad keyword value \"%s\" - bad " + "length %d (RFC 2911 section 4.1.3).", + attr->name, attr->values[i].string.text, + (int)strlen(attr->values[i].string.text)); } } break; @@ -4913,27 +4889,23 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ { valid = 0; - if (print) - print_test_error("\"%s\": Bad URI value \"%s\" - %s " - "(RFC 2911 section 4.1.5).", attr->name, - attr->values[i].string.text, - URIStatusStrings[uri_status - - HTTP_URI_OVERFLOW]); - else - break; + add_stringf(errors, + "\"%s\": Bad URI value \"%s\" - %s " + "(RFC 2911 section 4.1.5).", attr->name, + attr->values[i].string.text, + URIStatusStrings[uri_status - + HTTP_URI_OVERFLOW]); } if (strlen(attr->values[i].string.text) > 1023) { valid = 0; - if (print) - print_test_error("\"%s\": Bad URI value \"%s\" - bad length %d " - "(RFC 2911 section 4.1.5).", attr->name, - attr->values[i].string.text, - (int)strlen(attr->values[i].string.text)); - else - break; + add_stringf(errors, + "\"%s\": Bad URI value \"%s\" - bad length %d " + "(RFC 2911 section 4.1.5).", attr->name, + attr->values[i].string.text, + (int)strlen(attr->values[i].string.text)); } } break; @@ -4954,25 +4926,21 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ { valid = 0; - if (print) - print_test_error("\"%s\": Bad uriScheme value \"%s\" - bad " - "characters (RFC 2911 section 4.1.6).", - attr->name, attr->values[i].string.text); - else - break; + add_stringf(errors, + "\"%s\": Bad uriScheme value \"%s\" - bad " + "characters (RFC 2911 section 4.1.6).", + attr->name, attr->values[i].string.text); } if ((ptr - attr->values[i].string.text) > 63) { valid = 0; - if (print) - print_test_error("\"%s\": Bad uriScheme value \"%s\" - bad " - "length %d (RFC 2911 section 4.1.6).", - attr->name, attr->values[i].string.text, - (int)strlen(attr->values[i].string.text)); - else - break; + add_stringf(errors, + "\"%s\": Bad uriScheme value \"%s\" - bad " + "length %d (RFC 2911 section 4.1.6).", + attr->name, attr->values[i].string.text, + (int)strlen(attr->values[i].string.text)); } } break; @@ -4989,25 +4957,21 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ { valid = 0; - if (print) - print_test_error("\"%s\": Bad charset value \"%s\" - bad " - "characters (RFC 2911 section 4.1.7).", - attr->name, attr->values[i].string.text); - else - break; + add_stringf(errors, + "\"%s\": Bad charset value \"%s\" - bad " + "characters (RFC 2911 section 4.1.7).", + attr->name, attr->values[i].string.text); } if ((ptr - attr->values[i].string.text) > 40) { valid = 0; - if (print) - print_test_error("\"%s\": Bad charset value \"%s\" - bad " - "length %d (RFC 2911 section 4.1.7).", - attr->name, attr->values[i].string.text, - (int)strlen(attr->values[i].string.text)); - else - break; + add_stringf(errors, + "\"%s\": Bad charset value \"%s\" - bad " + "length %d (RFC 2911 section 4.1.7).", + attr->name, attr->values[i].string.text, + (int)strlen(attr->values[i].string.text)); } } break; @@ -5040,6 +5004,7 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ regerror(i, &re, temp, sizeof(temp)); print_fatal_error("Unable to compile naturalLanguage regular " "expression: %s.", temp); + break; } for (i = 0; i < attr->num_values; i ++) @@ -5048,25 +5013,21 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ { valid = 0; - if (print) - print_test_error("\"%s\": Bad naturalLanguage value \"%s\" - bad " - "characters (RFC 2911 section 4.1.8).", - attr->name, attr->values[i].string.text); - else - break; + add_stringf(errors, + "\"%s\": Bad naturalLanguage value \"%s\" - bad " + "characters (RFC 2911 section 4.1.8).", + attr->name, attr->values[i].string.text); } if (strlen(attr->values[i].string.text) > 63) { valid = 0; - if (print) - print_test_error("\"%s\": Bad naturalLanguage value \"%s\" - bad " - "length %d (RFC 2911 section 4.1.8).", - attr->name, attr->values[i].string.text, - (int)strlen(attr->values[i].string.text)); - else - break; + add_stringf(errors, + "\"%s\": Bad naturalLanguage value \"%s\" - bad " + "length %d (RFC 2911 section 4.1.8).", + attr->name, attr->values[i].string.text, + (int)strlen(attr->values[i].string.text)); } } @@ -5096,6 +5057,7 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ regerror(i, &re, temp, sizeof(temp)); print_fatal_error("Unable to compile mimeMediaType regular " "expression: %s.", temp); + break; } for (i = 0; i < attr->num_values; i ++) @@ -5104,27 +5066,25 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ { valid = 0; - if (print) - print_test_error("\"%s\": Bad mimeMediaType value \"%s\" - bad " - "characters (RFC 2911 section 4.1.9).", - attr->name, attr->values[i].string.text); - else - break; + add_stringf(errors, + "\"%s\": Bad mimeMediaType value \"%s\" - bad " + "characters (RFC 2911 section 4.1.9).", + attr->name, attr->values[i].string.text); } if (strlen(attr->values[i].string.text) > 255) { valid = 0; - if (print) - print_test_error("\"%s\": Bad mimeMediaType value \"%s\" - bad " - "length %d (RFC 2911 section 4.1.9).", - attr->name, attr->values[i].string.text, - (int)strlen(attr->values[i].string.text)); - else - break; + add_stringf(errors, + "\"%s\": Bad mimeMediaType value \"%s\" - bad " + "length %d (RFC 2911 section 4.1.9).", + attr->name, attr->values[i].string.text, + (int)strlen(attr->values[i].string.text)); } } + + regfree(&re); break; default : @@ -5140,18 +5100,20 @@ validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */ */ static int /* O - 1 on match, 0 on non-match */ -with_value(char *value, /* I - Value string */ - int regex, /* I - Value is a regular expression */ +with_value(cups_array_t *errors, /* I - Errors array */ + char *value, /* I - Value string */ + int flags, /* I - Flags for match */ ipp_attribute_t *attr, /* I - Attribute to compare */ - int report, /* I - 1 = report failures */ char *matchbuf, /* I - Buffer to hold matching value */ size_t matchlen) /* I - Length of match buffer */ { - int i; /* Looping var */ + int i, /* Looping var */ + match; /* Match? */ char *valptr; /* Pointer into value */ *matchbuf = '\0'; + match = (flags & _CUPS_WITH_ALL) ? 1 : 0; /* * NULL matches everything. @@ -5172,8 +5134,8 @@ with_value(char *value, /* I - Value string */ { char op, /* Comparison operator */ *nextptr; /* Next pointer */ - int intvalue; /* Integer value */ - + int intvalue, /* Integer value */ + valmatch = 0; /* Does the current value match? */ valptr = value; @@ -5197,37 +5159,39 @@ with_value(char *value, /* I - Value string */ break; valptr = nextptr; - switch (op) + if ((op == '=' && attr->values[i].integer == intvalue) || + (op == '<' && attr->values[i].integer < intvalue) || + (op == '>' && attr->values[i].integer > intvalue)) { - case '=' : - if (attr->values[i].integer == intvalue) - { - snprintf(matchbuf, matchlen, "%d", attr->values[i].integer); - return (1); - } - break; - case '<' : - if (attr->values[i].integer < intvalue) - { - snprintf(matchbuf, matchlen, "%d", attr->values[i].integer); - return (1); - } - break; - case '>' : - if (attr->values[i].integer > intvalue) - { - snprintf(matchbuf, matchlen, "%d", attr->values[i].integer); - return (1); - } - break; + if (!matchbuf[0]) + snprintf(matchbuf, matchlen, "%d", + attr->values[i].integer); + + valmatch = 1; + break; } } + + if (flags & _CUPS_WITH_ALL) + { + if (!valmatch) + { + match = 0; + break; + } + } + else if (valmatch) + { + match = 1; + break; + } } - if (report) + if (!match && errors) { for (i = 0; i < attr->num_values; i ++) - print_test_error("GOT: %s=%d", attr->name, attr->values[i].integer); + add_stringf(errors, "GOT: %s=%d", attr->name, + attr->values[i].integer); } break; @@ -5236,8 +5200,8 @@ with_value(char *value, /* I - Value string */ { char op, /* Comparison operator */ *nextptr; /* Next pointer */ - int intvalue; /* Integer value */ - + int intvalue, /* Integer value */ + valmatch = 0; /* Does the current value match? */ valptr = value; @@ -5261,44 +5225,40 @@ with_value(char *value, /* I - Value string */ break; valptr = nextptr; - switch (op) + if ((op == '=' && (attr->values[i].range.lower == intvalue || + attr->values[i].range.upper == intvalue)) || + (op == '<' && attr->values[i].range.upper < intvalue) || + (op == '>' && attr->values[i].range.upper > intvalue)) { - case '=' : - if (attr->values[i].range.lower == intvalue || - attr->values[i].range.upper == intvalue) - { - snprintf(matchbuf, matchlen, "%d-%d", - attr->values[i].range.lower, - attr->values[i].range.upper); - return (1); - } - break; - case '<' : - if (attr->values[i].range.upper < intvalue) - { - snprintf(matchbuf, matchlen, "%d-%d", - attr->values[i].range.lower, - attr->values[i].range.upper); - return (1); - } - break; - case '>' : - if (attr->values[i].range.upper > intvalue) - { - snprintf(matchbuf, matchlen, "%d-%d", - attr->values[i].range.lower, - attr->values[i].range.upper); - return (1); - } - break; + if (!matchbuf[0]) + snprintf(matchbuf, matchlen, "%d-%d", + attr->values[0].range.lower, + attr->values[0].range.upper); + + valmatch = 1; + break; } } + + if (flags & _CUPS_WITH_ALL) + { + if (!valmatch) + { + match = 0; + break; + } + } + else if (valmatch) + { + match = 1; + break; + } } - if (report) + if (!match && errors) { for (i = 0; i < attr->num_values; i ++) - print_test_error("GOT: %s=%d-%d", attr->name, + add_stringf(errors, "GOT: %s=%d-%d", attr->name, attr->values[i].range.lower, attr->values[i].range.upper); } @@ -5309,15 +5269,26 @@ with_value(char *value, /* I - Value string */ { if (!strcmp(value, "true") == attr->values[i].boolean) { - strlcpy(matchbuf, value, matchlen); - return (1); + if (!matchbuf[0]) + strlcpy(matchbuf, value, matchlen); + + if (!(flags & _CUPS_WITH_ALL)) + { + match = 1; + break; + } + } + else if (flags & _CUPS_WITH_ALL) + { + match = 0; + break; } } - if (report) + if (!match && errors) { for (i = 0; i < attr->num_values; i ++) - print_test_error("GOT: %s=%s", attr->name, + add_stringf(errors, "GOT: %s=%s", attr->name, attr->values[i].boolean ? "true" : "false"); } break; @@ -5336,7 +5307,7 @@ with_value(char *value, /* I - Value string */ case IPP_TAG_TEXTLANG : case IPP_TAG_URI : case IPP_TAG_URISCHEME : - if (regex) + if (flags & _CUPS_WITH_REGEX) { /* * Value is an extended, case-sensitive POSIX regular expression... @@ -5361,56 +5332,69 @@ with_value(char *value, /* I - Value string */ for (i = 0; i < attr->num_values; i ++) { - if (regexec(&re, attr->values[i].string.text, 0, NULL, 0)) + if (!regexec(&re, attr->values[i].string.text, 0, NULL, 0)) { - if (report) - print_test_error("GOT: %s=\"%s\"", attr->name, - attr->values[i].string.text); - else + if (!matchbuf[0]) + strlcpy(matchbuf, attr->values[i].string.text, matchlen); + + if (!(flags & _CUPS_WITH_ALL)) + { + match = 1; break; + } + } + else if (flags & _CUPS_WITH_ALL) + { + match = 0; + break; } } regfree(&re); - - if (i == attr->num_values) - strlcpy(matchbuf, attr->values[0].string.text, matchlen); - - return (i == attr->num_values); } else { /* - * Value is a literal string, see if at least one value matches the - * literal string... + * Value is a literal string, see if the value(s) match... */ for (i = 0; i < attr->num_values; i ++) { if (!strcmp(value, attr->values[i].string.text)) { - strlcpy(matchbuf, attr->values[i].string.text, matchlen); - return (1); - } - } + if (!matchbuf[0]) + strlcpy(matchbuf, attr->values[i].string.text, matchlen); - if (report) - { - for (i = 0; i < attr->num_values; i ++) - print_test_error("GOT: %s=\"%s\"", attr->name, - attr->values[i].string.text); + if (!(flags & _CUPS_WITH_ALL)) + { + match = 1; + break; + } + } + else if (flags & _CUPS_WITH_ALL) + { + match = 0; + break; + } } } + + if (!match && errors) + { + for (i = 0; i < attr->num_values; i ++) + add_stringf(errors, "GOT: %s=\"%s\"", attr->name, + attr->values[i].string.text); + } break; default : break; } - return (0); + return (match); } /* - * End of "$Id: ipptool.c 10090 2011-10-25 22:39:56Z mike $". + * End of "$Id: ipptool.c 10461 2012-05-11 23:01:21Z mike $". */ |