Re: [LOW] STR #3949: Allow partial matches for WITH-VALUE "/regex/"?

Michael Sweet <[email protected]>
Newsgroups gmane.comp.printing.cups.bugs
Message-ID <[email protected]>
DO NOT REPLY TO THIS MESSAGE.  INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.

[STR Closed w/Resolution]

Fixed in Subversion repository.

Link: http://www.cups.org/str.php?L3949
Version: 1.6-current
Fix Version: 1.6-current (r10314)

_______________________________________________
cups-bugs mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/cups-bugs
str3949.patch (text/plain, 25.3 KB)
Index: doc/help/man-ipptoolfile.html
===================================================================
--- doc/help/man-ipptoolfile.html	(revision 10312)
+++ doc/help/man-ipptoolfile.html	(working copy)
@@ -338,14 +338,55 @@
 </dd>
 <dt>WITH-VALUE "literal string"
 </dt>
-<dd>Requires at least one value of the EXPECT attribute to match the literal string.
-Comparisons are case-sensitive.
+<dd></dd>
+<dt>WITH-ALL-VALUES "literal string"
+</dt>
+<dd>Requires that one/all values of the EXPECT attribute to match the literal string. Comparisons are case-sensitive.
 </dd>
+<dt>WITH-VALUE "&lt;number"
+</dt>
+<dd></dd>
+<dt>WITH-VALUE "=number"
+</dt>
+<dd></dd>
+<dt>WITH-VALUE ">number"
+</dt>
+<dd></dd>
+<dt>WITH-VALUE "number[,number,...]"
+</dt>
+<dd></dd>
+<dt>WITH-ALL-VALUES "&lt;number"
+</dt>
+<dd></dd>
+<dt>WITH-ALL-VALUES "=number"
+</dt>
+<dd></dd>
+<dt>WITH-ALL-VALUES ">number"
+</dt>
+<dd></dd>
+<dt>WITH-ALL-VALUES "number[,number,...]"
+</dt>
+<dd>Requires that one/all values of the EXPECT attribute to match the number(s) or numeric comparisons. When comparing rangeOfInteger values, the "&lt;" and ">" operators only check the upper bound of the range.
+</dd>
+<dt>WITH-VALUE "false"
+</dt>
+<dd></dd>
+<dt>WITH-VALUE "true"
+</dt>
+<dd></dd>
+<dt>WITH-ALL-VALUES "false"
+</dt>
+<dd></dd>
+<dt>WITH-ALL-VALUES "true"
+</dt>
+<dd>Requires that one/all values of the EXPECT attribute to match the boolean value given.
+</dd>
 <dt>WITH-VALUE "/regular expression/"
 </dt>
-<dd>Requires that all values of the EXPECT attribute match the regular expression,
-which must conform to the POSIX regular expression syntax.
-Comparisons are case-sensitive.
+<dd></dd>
+<dt>WITH-ALL-VALUES "/regular expression/"
+</dt>
+<dd>Requires that one/all values of the EXPECT attribute match the regular expression, which must conform to the POSIX regular expression syntax. Comparisons are case-sensitive.
 
 </dd>
 </dl>
@@ -413,6 +454,7 @@
     Get-Subscriptions
     Hold-Job
     Hold-New-Jobs
+    Identify-Printer
     Pause-Printer
     Pause-Printer-After-Current-Job
     Print-Job
@@ -437,6 +479,7 @@
     Shutdown-Printer
     Startup-Printer
     Suspend-Current-Job
+    Validate-Document
     Validate-Job
 </pre>
 
@@ -454,6 +497,10 @@
     client-error-document-access-error
     client-error-document-format-error
     client-error-document-format-not-supported
+    client-error-document-password-error
+    client-error-document-permission-error
+    client-error-document-security-error
+    client-error-document-unprintable-error
     client-error-forbidden
     client-error-gone
     client-error-ignored-all-notifications
@@ -601,7 +648,7 @@
 <a href='http://localhost:631/help'>http://localhost:631/help</a>
 
 <h2 class="title"><a name="COPYRIGHT">Copyright</a></h2>
-Copyright 2007-2011 by Apple Inc.
+Copyright 2007-2012 by Apple Inc.
 
 </body>
 </html>
Index: cups/ipp.h
===================================================================
--- cups/ipp.h	(revision 10312)
+++ cups/ipp.h	(working copy)
@@ -3,7 +3,7 @@
  *
  *   Internet Printing Protocol definitions for CUPS.
  *
- *   Copyright 2007-2011 by Apple Inc.
+ *   Copyright 2007-2012 by Apple Inc.
  *   Copyright 1997-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -188,6 +188,7 @@
   IPP_RESUBMIT_JOB,			/* Resubmit-Job */
   IPP_CLOSE_JOB,			/* Close-Job */
   IPP_IDENTIFY_PRINTER,			/* Identify-Printer (proposed IPP JPS3) */
+  IPP_VALIDATE_DOCUMENT,		/* Validate-Document (proposed IPP JPS3) */
   IPP_PRIVATE = 0x4000,			/* Reserved @private@ */
   CUPS_GET_DEFAULT,			/* Get the default printer */
   CUPS_GET_PRINTERS,			/* Get a list of printers and/or classes */
Index: cups/ipp-support.c
===================================================================
--- cups/ipp-support.c	(revision 10312)
+++ cups/ipp-support.c	(working copy)
@@ -78,7 +78,11 @@
 		  "client-error-ignored-all-subscriptions",
 		  "client-error-too-many-subscriptions",
 		  "(client-error-ignored-all-notifications)",
-		  "(client-error-client-print-support-file-not-found)"
+		  "(client-error-client-print-support-file-not-found)",
+		  "client-error-document-password-error",
+		  "client-error-document-permission-error",
+		  "client-error-document-security-error",
+		  "client-error-document-unprintable-error"
 		},
 		* const ipp_status_500s[] =		/* Server errors */
 		{
@@ -158,7 +162,7 @@
 		  "Suspend-Current-Job",
 		  "Resume-Job",
 
-		  /* 0x0030 - 0x003b */
+		  /* 0x0030 - 0x003d */
 		  "Promote-Job",
 		  "Schedule-Job-After",
 		  "0x32",
@@ -171,7 +175,8 @@
 		  "Cancel-My-Jobs",
 		  "Resubmit-Job",
 		  "Close-Job",
-		  "Identify-Printer"
+		  "Identify-Printer",
+		  "Validate-Document"
 		},
 		* const ipp_cups_ops[] =
 		{
Index: man/ipptoolfile.man
===================================================================
--- man/ipptoolfile.man	(revision 10312)
+++ man/ipptoolfile.man	(working copy)
@@ -3,7 +3,7 @@
 .\"
 .\"   ipptoolfile man page for CUPS.
 .\"
-.\"   Copyright 2010-2011 by Apple Inc.
+.\"   Copyright 2010-2012 by Apple Inc.
 .\"
 .\"   These coded instructions, statements, and computer programs are the
 .\"   property of Apple Inc. and are protected by Federal copyright
@@ -11,7 +11,7 @@
 .\"   which should have been included with this file.  If this file is
 .\"   file is missing or damaged, see the license at "http://www.cups.org/".
 .\"
-.TH ipptoolfile 5 "CUPS" "28 September 2011" "Apple Inc."
+.TH ipptoolfile 5 "CUPS" "28 February 2012" "Apple Inc."
 .SH NAME
 ipptoolfile \- ipptool file format
 
@@ -277,13 +277,40 @@
 parallel attribute.
 .TP 5
 WITH-VALUE "literal string"
-Requires at least one value of the EXPECT attribute to match the literal string.
-Comparisons are case-sensitive.
 .TP 5
+WITH-ALL-VALUES "literal string"
+Requires that one/all values of the EXPECT attribute to match the literal string. Comparisons are case-sensitive.
+.TP 5
+WITH-VALUE "<number"
+.TP 5
+WITH-VALUE "=number"
+.TP 5
+WITH-VALUE ">number"
+.TP 5
+WITH-VALUE "number[,number,...]"
+.TP 5
+WITH-ALL-VALUES "<number"
+.TP 5
+WITH-ALL-VALUES "=number"
+.TP 5
+WITH-ALL-VALUES ">number"
+.TP 5
+WITH-ALL-VALUES "number[,number,...]"
+Requires that one/all values of the EXPECT attribute to match the number(s) or numeric comparisons. When comparing rangeOfInteger values, the "<" and ">" operators only check the upper bound of the range.
+.TP 5
+WITH-VALUE "false"
+.TP 5
+WITH-VALUE "true"
+.TP 5
+WITH-ALL-VALUES "false"
+.TP 5
+WITH-ALL-VALUES "true"
+Requires that one/all values of the EXPECT attribute to match the boolean value given.
+.TP 5
 WITH-VALUE "/regular expression/"
-Requires that all values of the EXPECT attribute match the regular expression,
-which must conform to the POSIX regular expression syntax.
-Comparisons are case-sensitive.
+.TP 5
+WITH-ALL-VALUES "/regular expression/"
+Requires that one/all values of the EXPECT attribute match the regular expression, which must conform to the POSIX regular expression syntax. Comparisons are case-sensitive.
 
 .SH STATUS PREDICATES
 The following predicates are understood following the STATUS test directive:
@@ -343,6 +370,7 @@
     Get-Subscriptions
     Hold-Job
     Hold-New-Jobs
+    Identify-Printer
     Pause-Printer
     Pause-Printer-After-Current-Job
     Print-Job
@@ -367,6 +395,7 @@
     Shutdown-Printer
     Startup-Printer
     Suspend-Current-Job
+    Validate-Document
     Validate-Job
 .fi
 
@@ -384,6 +413,10 @@
     client-error-document-access-error
     client-error-document-format-error
     client-error-document-format-not-supported
+    client-error-document-password-error
+    client-error-document-permission-error
+    client-error-document-security-error
+    client-error-document-unprintable-error
     client-error-forbidden
     client-error-gone
     client-error-ignored-all-notifications
@@ -517,7 +550,7 @@
 http://localhost:631/help
 
 .SH COPYRIGHT
-Copyright 2007-2011 by Apple Inc.
+Copyright 2007-2012 by Apple Inc.
 .\"
 .\" End of "$Id$".
 .\"
Index: test/ipp-2.0.test
===================================================================
--- test/ipp-2.0.test	(revision 10312)
+++ test/ipp-2.0.test	(working copy)
@@ -3,7 +3,7 @@
 #
 #   IPP/2.0 test suite.
 #
-#   Copyright 2007-2011 by Apple Inc.
+#   Copyright 2007-2012 by Apple Inc.
 #   Copyright 2001-2006 by Easy Software Products. All rights reserved.
 #
 #   These coded instructions, statements, and computer programs are the
@@ -24,7 +24,7 @@
 
 
 # Regular expression for PWG media size names (eek!)
-DEFINE MEDIA_REGEX "/^((custom|na|asme|roc|oe)_[a-z0-9][-a-z0-9]*_([1-9][0-9]*(\.[0-9]*[1-9])?|0\.[0-9]*[1-9])x([1-9][0-9]*(\.[0-9]*[1-9])?|0\.[0-9]*[1-9])in|(custom|iso|jis|jpn|prc|om)_[a-z0-9][-a-z0-9]*_([1-9][0-9]*(\.[0-9]*[1-9])?|0\.[0-9]*[1-9])x([1-9][0-9]*(\.[0-9]*[1-9])?|0\.[0-9]*[1-9])mm)$$/"
+DEFINE MEDIA_REGEX "/^(choice(_((custom|na|asme|roc|oe|roll)_[a-z0-9][-a-z0-9]*_([1-9][0-9]*(\.[0-9]*[1-9])?|0\.[0-9]*[1-9])x([1-9][0-9]*(\.[0-9]*[1-9])?|0\.[0-9]*[1-9])in|(custom|iso|jis|jpn|prc|om|roll)_[a-z0-9][-a-z0-9]*_([1-9][0-9]*(\.[0-9]*[1-9])?|0\.[0-9]*[1-9])x([1-9][0-9]*(\.[0-9]*[1-9])?|0\.[0-9]*[1-9])mm)){2,}|(custom|na|asme|roc|oe|roll)_[a-z0-9][-a-z0-9]*_([1-9][0-9]*(\.[0-9]*[1-9])?|0\.[0-9]*[1-9])x([1-9][0-9]*(\.[0-9]*[1-9])?|0\.[0-9]*[1-9])in|(custom|iso|jis|jpn|prc|om|roll)_[a-z0-9][-a-z0-9]*_([1-9][0-9]*(\.[0-9]*[1-9])?|0\.[0-9]*[1-9])x([1-9][0-9]*(\.[0-9]*[1-9])?|0\.[0-9]*[1-9])mm)$$/"
 
 
 # Test required printer description attribute support.
@@ -51,8 +51,8 @@
 	EXPECT finishings-default OF-TYPE enum IN-GROUP printer-attributes-tag
 	EXPECT finishings-supported OF-TYPE enum IN-GROUP printer-attributes-tag WITH-VALUE 3
 	EXPECT media-default OF-TYPE no-value|keyword|name IN-GROUP printer-attributes-tag COUNT 1 WITH-VALUE "$MEDIA_REGEX"
-	EXPECT ?media-ready OF-TYPE keyword|name IN-GROUP printer-attributes-tag WITH-VALUE "$MEDIA_REGEX"
-	EXPECT media-supported OF-TYPE keyword|name IN-GROUP printer-attributes-tag WITH-VALUE "$MEDIA_REGEX"
+	EXPECT ?media-ready OF-TYPE keyword|name IN-GROUP printer-attributes-tag WITH-ALL-VALUES "$MEDIA_REGEX"
+	EXPECT media-supported OF-TYPE keyword|name IN-GROUP printer-attributes-tag WITH-ALL-VALUES "$MEDIA_REGEX"
 	EXPECT orientation-requested-default OF-TYPE no-value|enum IN-GROUP printer-attributes-tag COUNT 1 WITH-VALUE 3,4,5,6
 	EXPECT orientation-requested-supported OF-TYPE enum IN-GROUP printer-attributes-tag WITH-VALUE 3,4,5,6
 	EXPECT output-bin-default OF-TYPE keyword|name IN-GROUP printer-attributes-tag COUNT 1
@@ -61,8 +61,8 @@
 	EXPECT print-quality-supported OF-TYPE enum IN-GROUP printer-attributes-tag WITH-VALUE 3,4,5
 	EXPECT printer-resolution-default OF-TYPE resolution IN-GROUP printer-attributes-tag COUNT 1
 	EXPECT printer-resolution-supported OF-TYPE resolution IN-GROUP printer-attributes-tag
-	EXPECT sides-default OF-TYPE keyword IN-GROUP printer-attributes-tag COUNT 1 WITH-VALUE "/^(one-sided|two-sided-long-edge|two-sided-short-edge)$$/"
-	EXPECT sides-supported OF-TYPE keyword IN-GROUP printer-attributes-tag WITH-VALUE "/^(one-sided|two-sided-long-edge|two-sided-short-edge)$$/"
+	EXPECT sides-default OF-TYPE keyword IN-GROUP printer-attributes-tag COUNT 1 WITH-ALL-VALUES "/^(one-sided|two-sided-long-edge|two-sided-short-edge)$$/"
+	EXPECT sides-supported OF-TYPE keyword IN-GROUP printer-attributes-tag WITH-ALL-VALUES "/^(one-sided|two-sided-long-edge|two-sided-short-edge)$$/"
 
 	# Optional media-col support
 	EXPECT ?media-col-default OF-TYPE collection IN-GROUP printer-attributes-tag COUNT 1
Index: test/ipp-1.1.test
===================================================================
--- test/ipp-1.1.test	(revision 10312)
+++ test/ipp-1.1.test	(working copy)
@@ -95,7 +95,7 @@
 	ATTR uri printer-uri $uri
 
 	STATUS successful-ok
-	EXPECT printer-uri-supported OF-TYPE uri WITH-VALUE "$IPP_URI_SCHEME"
+	EXPECT printer-uri-supported OF-TYPE uri WITH-ALL-VALUES "$IPP_URI_SCHEME"
 }
 
 
@@ -325,7 +325,7 @@
 	EXPECT printer-state OF-TYPE enum IN-GROUP printer-attributes-tag COUNT 1 WITH-VALUE 3,4,5
 	EXPECT printer-state-reasons OF-TYPE keyword IN-GROUP printer-attributes-tag
 	EXPECT printer-up-time OF-TYPE integer IN-GROUP printer-attributes-tag COUNT 1 WITH-VALUE >0
-	EXPECT printer-uri-supported OF-TYPE uri IN-GROUP printer-attributes-tag SAME-COUNT-AS uri-security-supported WITH-VALUE "$IPP_URI_SCHEME"
+	EXPECT printer-uri-supported OF-TYPE uri IN-GROUP printer-attributes-tag SAME-COUNT-AS uri-security-supported WITH-ALL-VALUES "$IPP_URI_SCHEME"
 	EXPECT queued-job-count OF-TYPE integer IN-GROUP printer-attributes-tag COUNT 1
 	EXPECT uri-authentication-supported OF-TYPE keyword IN-GROUP printer-attributes-tag
 	EXPECT uri-security-supported OF-TYPE keyword IN-GROUP printer-attributes-tag SAME-COUNT-AS uri-authentication-supported
@@ -348,7 +348,7 @@
 
 	STATUS successful-ok
 
-	EXPECT printer-uri-supported OF-TYPE uri IN-GROUP printer-attributes-tag WITH-VALUE "$IPP_URI_SCHEME"
+	EXPECT printer-uri-supported OF-TYPE uri IN-GROUP printer-attributes-tag WITH-ALL-VALUES "$IPP_URI_SCHEME"
 	EXPECT !printer-name
 }
 
Index: test/ipptool.c
===================================================================
--- test/ipptool.c	(revision 10312)
+++ test/ipptool.c	(working copy)
@@ -81,6 +81,13 @@
   _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? */
@@ -96,7 +103,7 @@
 		*define_value;		/* Variable to define with value */
   int		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;
@@ -205,7 +212,7 @@
 static int	timeout_cb(http_t *http, void *user_data);
 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 regex,
+static int      with_value(cups_array_t *errors, char *value, int flags,
 		           ipp_attribute_t *attr, char *matchbuf,
 		           size_t matchlen);
 
@@ -1164,6 +1171,7 @@
           _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;
 
@@ -2049,11 +2057,12 @@
 	  goto test_exit;
 	}
       }
-      else if (!_cups_strcasecmp(token, "WITH-VALUE"))
+      else if (!_cups_strcasecmp(token, "WITH-ALL-VALUES") ||
+               !_cups_strcasecmp(token, "WITH-VALUE"))
       {
       	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;
 	}
@@ -2075,7 +2084,7 @@
 	    */
 
 	    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);
@@ -2087,11 +2096,15 @@
 	    */
 
 	    last_expect->with_value = strdup(token);
+	    last_expect->with_flags = _CUPS_WITH_LITERAL;
 	  }
+
+          if (!_cups_strcasecmp(token, "WITH-ALL-VALUES"))
+            last_expect->with_flags |= _CUPS_WITH_ALL;
 	}
 	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;
@@ -2660,21 +2673,27 @@
 	    ippAttributeString(found, buffer, sizeof(buffer));
 
 	  if (found &&
-	      !with_value(NULL, expect->with_value, expect->with_regex, found,
+	      !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)
 	    {
-	      if (expect->with_regex)
-		add_stringf(errors, "EXPECTED: %s WITH-VALUE /%s/",
-			    expect->name, expect->with_value);
+	      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 WITH-VALUE \"%s\"",
-			    expect->name, expect->with_value);
+		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_regex, found,
+	      with_value(errors, expect->with_value, expect->with_flags, found,
 	                 buffer, sizeof(buffer));
 	    }
 
@@ -5018,16 +5037,18 @@
 static int				/* O - 1 on match, 0 on non-match */
 with_value(cups_array_t    *errors,	/* I - Errors array */
            char            *value,	/* I - Value string */
-           int             regex,	/* I - Value is a regular expression */
+           int             flags,	/* I - Flags for match */
            ipp_attribute_t *attr,	/* I - Attribute to compare */
 	   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.
@@ -5048,9 +5069,9 @@
         {
 	  char	op,			/* Comparison operator */
 	  	*nextptr;		/* Next pointer */
-	  int	intvalue;		/* Integer value */
+	  int	intvalue,		/* Integer value */
+	  	valmatch = 0;		/* Does the current value match? */
 
-
           valptr = value;
 
 	  while (isspace(*valptr & 255) || isdigit(*valptr & 255) ||
@@ -5073,34 +5094,35 @@
 	      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 (errors)
+        if (!match && errors)
 	{
 	  for (i = 0; i < attr->num_values; i ++)
 	    add_stringf(errors, "GOT: %s=%d", attr->name,
@@ -5113,9 +5135,9 @@
         {
 	  char	op,			/* Comparison operator */
 	  	*nextptr;		/* Next pointer */
-	  int	intvalue;		/* Integer value */
+	  int	intvalue,		/* Integer value */
+	  	valmatch = 0;		/* Does the current value match? */
 
-
           valptr = value;
 
 	  while (isspace(*valptr & 255) || isdigit(*valptr & 255) ||
@@ -5138,41 +5160,37 @@
 	      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 (errors)
+        if (!match && errors)
 	{
 	  for (i = 0; i < attr->num_values; i ++)
 	    add_stringf(errors, "GOT: %s=%d-%d", attr->name,
@@ -5186,12 +5204,23 @@
 	{
           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 (errors)
+	if (!match && errors)
 	{
 	  for (i = 0; i < attr->num_values; i ++)
 	    add_stringf(errors, "GOT: %s=%s", attr->name,
@@ -5213,7 +5242,7 @@
     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...
@@ -5238,53 +5267,66 @@
 
 	  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 (errors)
-	        add_stringf(errors, "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 (!(flags & _CUPS_WITH_ALL))
+	      {
+	        match = 1;
+	        break;
+	      }
 	    }
+	    else if (flags & _CUPS_WITH_ALL)
+	    {
+	      match = 0;
+	      break;
+	    }
 	  }
+	}
 
-	  if (errors)
-	  {
-	    for (i = 0; i < attr->num_values; i ++)
-	      add_stringf(errors, "GOT: %s=\"%s\"", attr->name,
-			       attr->values[i].string.text);
-	  }
-	}
+        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);
 }
 
 
Index: CHANGES-IPPTOOL.txt
===================================================================
--- CHANGES-IPPTOOL.txt	(revision 10312)
+++ CHANGES-IPPTOOL.txt	(working copy)
@@ -1,10 +1,21 @@
-CHANGES-IPPTOOL.txt - 2012-02-06
+CHANGES-IPPTOOL.txt - 2012-02-28
 --------------------------------
 
 This file provides a list of changes to the ipptool binary distribution posted
 on cups.org.
 
 
+2012-02-28
+
+	- Changed behavior of WITH-VALUES "/regex/" to not require all values to
+	  match.
+	- Added WITH-ALL-VALUES directive for EXPECT predicates that require all
+	  values to match.
+	- Updated test files to use WITH-ALL-VALUES where necessary.
+	- Updated test files to use new ABNF for media names from PWG Media
+	  Names 2.0.
+
+
 2012-02-06
 
 	- Fixed the packaging of ipptool on Windows (removed unnecessary DLLs)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.