/**
- * Test the given node for an attribute whose value contains the
- * given substring
- *
- * This will return true (via the "match" pointer) if the libdom node
- * has an attribute with the given name and whose value contains the
- * given substring. The comparison is case-sensitive. This corresponds
- * to [attr*=value] in CSS.
- *
- * \param pw          Pointer to the current SVG parser state
- * \param node        Libdom SVG node to test
- * \param qname       Attribute name to check for
- * \param substring   Value substring to check for
- * \param match       Pointer to the test result
- *
- * \return Returns CSS_OK if successful and CSS_NOMEM if we cannot
- *         intern the attribute name (which usually indicates memory
- *         exhaustion)
+ * Implement node_has_attribute_substring() with optional case-
+ * insensitivity. This corresponds to [attr*=value i] in CSS and is
+ * not supported by libcss yet, but it allows us to factor out some
+ * common code.
  */
-css_error node_has_attribute_substring(void *pw, void *node,
+static css_error _node_has_attribute_substring(void *pw, void *node,
                const css_qname *qname, lwc_string *substring,
-               bool *match)
+               bool *match, bool insensitive)
 {
-       UNUSED(pw);
+       UNUSED(pw);
        dom_string *name;
-       dom_string *attr_val;
+       dom_string *attr_val = NULL;
        dom_exception err;
        size_t attr_len;  /* length of attr_val */
        size_t substrlen; /* length of "substring" */
        if (substrlen == 0) {
                /* In this case, the spec says that "if 'val' is the
                 * empty string, it will never represent anything." */
+               *match = false;
                return CSS_OK;
        }
 
         * and the first thing we want to do is check to see if the
         * whole thing matches the substring. */
        *match = dom_string_lwc_isequal(attr_val, substring);
+       if (insensitive) {
+               *match = dom_string_caseless_lwc_isequal(attr_val, substring);
+       }
+       else {
+               *match = dom_string_lwc_isequal(attr_val, substring);
+       }
 
        /* If not, check to see if an, uh, substring matches the
         * substring */
        return CSS_OK;
 }
 
+/**
+ * Test the given node for an attribute whose value contains the
+ * given substring
+ *
+ * This will return true (via the "match" pointer) if the libdom node
+ * has an attribute with the given name and whose value contains the
+ * given substring. The comparison is case-sensitive. This corresponds
+ * to [attr*=value] in CSS.
+ *
+ * \param pw          Pointer to the current SVG parser state
+ * \param node        Libdom SVG node to test
+ * \param qname       Attribute name to check for
+ * \param substring   Value substring to check for
+ * \param match       Pointer to the test result
+ *
+ * \return Returns CSS_OK if successful and CSS_NOMEM if we cannot
+ *         intern the attribute name (which usually indicates memory
+ *         exhaustion)
+ */
+css_error node_has_attribute_substring(void *pw, void *node,
+               const css_qname *qname, lwc_string *substring,
+               bool *match)
+{
+       return _node_has_attribute_substring(pw, node, qname, substring,
+                       match, false);
+}
+
 
 /**
  * Test whether or not the given node is the document's root element