ovsdb: Fix support for systems where libpcre is not installed.
authorBen Pfaff <blp@nicira.com>
Mon, 8 Feb 2010 23:37:49 +0000 (15:37 -0800)
committerBen Pfaff <blp@nicira.com>
Mon, 8 Feb 2010 23:37:49 +0000 (15:37 -0800)
This is one of the loose ends that I intended to fix up and test before
pushing off my commits to add use of PCRE, but obviously I forgot.

INSTALL.Linux
lib/automake.mk
lib/ovsdb-types.c
lib/ovsdb-types.h
lib/pcre.h [deleted file]
m4/openvswitch.m4
tests/atlocal.in
tests/ovs-vsctl.at
tests/ovsdb-data.at
tests/ovsdb-types.at

index c0344f2..6529118 100644 (file)
@@ -27,6 +27,10 @@ you will need the following software:
       connections from an Open vSwitch to an OpenFlow controller.  To
       enable, configure with --enable-ssl=yes.
 
+    - libpcre, the Perl Compatible Regular Expression library, is
+      optional but recommended.  Without it, OVSDB will not be able to
+      validate regular-expression based contraints.
+
 To compile the kernel module, you must also install the following.  If
 you cannot build or install the kernel module, you may use the
 userspace-only implementation, at a cost in performance.  The
@@ -80,6 +84,9 @@ following software:
     - libssl compatible with the libssl used for build, if OpenSSL was
       used for the build.
 
+    - libpcre compatible with the libpcre used for build, if PCRE was
+      used for the build.
+
     - The Linux kernel version configured as part of the build.
 
     - For optional support of ingress policing, the "tc" program from
index e5a0648..51d3c11 100644 (file)
@@ -88,7 +88,6 @@ lib_libopenvswitch_a_SOURCES = \
        lib/packets.h \
        lib/pcap.c \
        lib/pcap.h \
-       lib/pcre.h \
        lib/poll-loop.c \
        lib/poll-loop.h \
        lib/port-array.c \
index 1b5c7ed..2cefd4d 100644 (file)
@@ -134,7 +134,9 @@ ovsdb_base_type_init(struct ovsdb_base_type *base, enum ovsdb_atomic_type type)
         break;
 
     case OVSDB_TYPE_STRING:
+#ifdef HAVE_PCRE
         base->u.string.re = NULL;
+#endif
         base->u.string.reMatch = NULL;
         base->u.string.reComment = NULL;
         base->u.string.minLen = 0;
@@ -168,11 +170,21 @@ ovsdb_base_type_clone(struct ovsdb_base_type *dst,
         break;
 
     case OVSDB_TYPE_STRING:
+#if HAVE_PCRE
         if (dst->u.string.re) {
             pcre_refcount(dst->u.string.re, 1);
         }
+#else
+        if (dst->u.string.reMatch) {
+            dst->u.string.reMatch = xstrdup(dst->u.string.reMatch);
+        }
+        if (dst->u.string.reComment) {
+            dst->u.string.reComment = xstrdup(dst->u.string.reComment);
+        }
+#endif
         break;
 
+
     case OVSDB_TYPE_UUID:
         if (dst->u.uuid.refTableName) {
             dst->u.uuid.refTableName = xstrdup(dst->u.uuid.refTableName);
@@ -197,11 +209,16 @@ ovsdb_base_type_destroy(struct ovsdb_base_type *base)
             break;
 
         case OVSDB_TYPE_STRING:
+#ifdef HAVE_PCRE
             if (base->u.string.re && !pcre_refcount(base->u.string.re, -1)) {
                 pcre_free(base->u.string.re);
                 free(base->u.string.reMatch);
                 free(base->u.string.reComment);
             }
+#else
+            free(base->u.string.reMatch);
+            free(base->u.string.reComment);
+#endif
             break;
 
         case OVSDB_TYPE_UUID:
@@ -291,6 +308,7 @@ struct ovsdb_error *
 ovsdb_base_type_set_regex(struct ovsdb_base_type *base,
                           const char *reMatch, const char *reComment)
 {
+#ifdef HAVE_PCRE
     const char *errorString;
     const char *pattern;
     int errorOffset;
@@ -300,6 +318,10 @@ ovsdb_base_type_set_regex(struct ovsdb_base_type *base,
     if (pattern[0] == '\0' || strchr(pattern, '\0')[-1] != '$') {
         pattern = xasprintf("%s$", pattern);
     }
+
+#ifndef PCRE_JAVASCRIPT_COMPAT  /* Added in PCRE 7.7. */
+#define PCRE_JAVASCRIPT_COMPAT 0
+#endif
     base->u.string.re = pcre_compile(pattern, (PCRE_ANCHORED | PCRE_UTF8
                                                | PCRE_JAVASCRIPT_COMPAT),
                                      &errorString, &errorOffset, NULL);
@@ -311,9 +333,10 @@ ovsdb_base_type_set_regex(struct ovsdb_base_type *base,
                                   "\"%s\" is not a valid regular "
                                   "expression: %s", reMatch, errorString);
     }
+    pcre_refcount(base->u.string.re, 1);
+#endif
 
     /* Save regular expression. */
-    pcre_refcount(base->u.string.re, 1);
     base->u.string.reMatch = xstrdup(reMatch);
     base->u.string.reComment = reComment ? xstrdup(reComment) : NULL;
     return NULL;
index b11f827..0eca931 100644 (file)
 #define OVSDB_TYPES_H 1
 
 #include <float.h>
-#include <pcre.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include "compiler.h"
 #include "uuid.h"
 
+#ifdef HAVE_PCRE
+#include <pcre.h>
+#endif
+
 struct json;
 
 /* An atomic type: one that OVSDB regards as a single unit of data. */
@@ -61,7 +64,9 @@ struct ovsdb_base_type {
         /* No constraints for Boolean types. */
 
         struct ovsdb_string_constraints {
+#ifdef HAVE_PCRE
             pcre *re;           /* Compiled regular expression. */
+#endif
             char *reMatch;      /* reMatch or NULL. */
             char *reComment;    /* reComment or NULL. */
             unsigned int minLen; /* minLength or 0. */
@@ -81,9 +86,15 @@ struct ovsdb_base_type {
 #define OVSDB_BASE_REAL_INIT    { .type = OVSDB_TYPE_REAL,          \
                                   .u.real = { -DBL_MAX, DBL_MAX } }
 #define OVSDB_BASE_BOOLEAN_INIT { .type = OVSDB_TYPE_BOOLEAN }
+#ifdef HAVE_PCRE
 #define OVSDB_BASE_STRING_INIT  { .type = OVSDB_TYPE_STRING,        \
                                   .u.string = { NULL, NULL, NULL,   \
                                                 0, UINT_MAX } }
+#else
+#define OVSDB_BASE_STRING_INIT  { .type = OVSDB_TYPE_STRING,    \
+                                  .u.string = { NULL, NULL,     \
+                                                0, UINT_MAX } }
+#endif
 #define OVSDB_BASE_UUID_INIT    { .type = OVSDB_TYPE_UUID,      \
                                   .u.uuid = { NULL, NULL } }
 
diff --git a/lib/pcre.h b/lib/pcre.h
deleted file mode 100644 (file)
index 5ade833..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2010 Nicira Networks.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef PCRE_H
-#define PCRE_H 1
-
-#ifdef HAVE_PCRE
-#include_next <pcre.h>
-#else
-typedef void pcre;
-#endif
-
-#endif /* pcre.h */
index affeac3..861e4eb 100644 (file)
@@ -224,16 +224,22 @@ dnl which is libpcre 7.2 or later.
 AC_DEFUN([OVS_CHECK_PCRE],
   [dnl Make sure that pkg-config is installed.
    m4_pattern_forbid([PKG_CHECK_MODULES])
-   HAVE_PCRE=no
-   HAVE_PCRE_PARTIAL=no
-   PKG_CHECK_MODULES([PCRE], [libpcre >= 6.6], 
-     [HAVE_PCRE=yes
-      PKG_CHECK_EXISTS([libpcre >= 7.2], [HAVE_PCRE_PARTIAL=yes])])
+   PKG_CHECK_MODULES([PCRE],
+                     [libpcre >= 6.6], 
+                     [HAVE_PCRE=yes
+                      PKG_CHECK_EXISTS([libpcre >= 7.2], 
+                                       [HAVE_PCRE_PARTIAL=yes],
+                                       [HAVE_PCRE_PARTIAL=no])],
+                     [HAVE_PCRE=no
+                      HAVE_PCRE_PARTIAL=no])
    AM_CONDITIONAL([HAVE_PCRE], [test "$HAVE_PCRE" = yes])
    AM_CONDITIONAL([HAVE_PCRE_PARTIAL], [test "$HAVE_PCRE_PARTIAL" = yes])
    if test "$HAVE_PCRE" = yes; then
       AC_DEFINE([HAVE_PCRE], [1], [Define to 1 if libpcre is installed.])
-   fi])
+   fi
+   AC_SUBST([HAVE_PCRE])
+   AC_SUBST([HAVE_PCRE_PARTIAL])
+])
 
 dnl Checks for Python 2.x, x >= 4.
 AC_DEFUN([OVS_CHECK_PYTHON],
index 8ac4f67..1628ea5 100644 (file)
@@ -1,5 +1,6 @@
 # -*- shell-script -*-
 HAVE_OPENSSL='@HAVE_OPENSSL@'
+HAVE_PCRE='@HAVE_PCRE@'
 HAVE_PYTHON='@HAVE_PYTHON@'
 PERL='@PERL@'
 PYTHON='@PYTHON@'
index 103b17a..b140f02 100644 (file)
@@ -562,9 +562,14 @@ AT_CHECK([RUN_OVS_VSCTL([set b br0 flood_vlans=-1])],
 AT_CHECK([RUN_OVS_VSCTL([set b br0 flood_vlans=4096])], 
   [1], [], [ovs-vsctl: constraint violation: 4096 is not in the valid range 0 to 4095 (inclusive)
 ], [OVS_VSCTL_CLEANUP])
-AT_CHECK([RUN_OVS_VSCTL([set c br1 'connection-mode=xyz'])], 
-  [1], [], [ovs-vsctl: constraint violation: "xyz" is not a either "in-band" or "out-of-band"
+if test "$HAVE_PCRE" = yes; then
+    AT_CHECK([RUN_OVS_VSCTL([set c br1 'connection-mode=xyz'])], 
+      [1], [], [ovs-vsctl: constraint violation: "xyz" is not a either "in-band" or "out-of-band"
 ], [OVS_VSCTL_CLEANUP])
+else
+    AT_CHECK([RUN_OVS_VSCTL([set c br1 'connection-mode=xyz'])], 
+      [0], [], [], [OVS_VSCTL_CLEANUP])
+fi
 AT_CHECK([RUN_OVS_VSCTL([set c br1 connection-mode:x=y])], 
   [1], [], [ovs-vsctl: cannot specify key to set for non-map column connection_mode
 ], [OVS_VSCTL_CLEANUP])
index 03ec3b3..708ed90 100644 (file)
@@ -290,8 +290,17 @@ constraint violation: -11 is not in the valid range -10 to 10 (inclusive)
 constraint violation: 11 is not in the valid range -10 to 10 (inclusive)
 constraint violation: 123576 is not in the valid range -10 to 10 (inclusive)])
 
-OVSDB_CHECK_POSITIVE([strings matching /(a(b)?)c?/],
-  [[parse-atoms '{"type": "string", "reMatch": "(a(b)?)?c?"}' \
+AT_SETUP([strings matching /(a(b)?)c?/])
+AT_KEYWORDS([ovsdb positive])
+if test "$HAVE_PCRE" = yes; then
+   b_out='constraint violation: "b" does not match regular expression /(a(b)?)?c?/'
+   bc_out='constraint violation: "bc" does not match regular expression /(a(b)?)?c?/'
+else
+   b_out='"b"'
+   bc_out='"bc"'
+fi
+AT_CHECK_UNQUOTED(
+  [[test-ovsdb parse-atoms '{"type": "string", "reMatch": "(a(b)?)?c?"}' \
     '[""]' \
     '["a"]' \
     '["ab"]' \
@@ -300,14 +309,17 @@ OVSDB_CHECK_POSITIVE([strings matching /(a(b)?)c?/],
     '["b"]' \
     '["bc"]' \
     '["c"]']],
+  [0],
   [[""
 "a"
 "ab"
 "abc"
 "ac"
-constraint violation: "b" does not match regular expression /(a(b)?)?c?/
-constraint violation: "bc" does not match regular expression /(a(b)?)?c?/
-"c"]])
+$b_out
+$bc_out
+"c"
+]])
+AT_CLEANUP
 
 OVSDB_CHECK_POSITIVE([strings at least 2 characters long],
   [[parse-atoms '{"type": "string", "minLength": 2}' \
index 4647e69..d052776 100644 (file)
@@ -50,9 +50,24 @@ OVSDB_CHECK_POSITIVE([string reMatch],
 OVSDB_CHECK_POSITIVE([string reMatch + reComment], 
   [[parse-base-type '{"type": "string", "reMatch": "\\d{3}-\\d{3}-\\d{4}", "reComment": "US-style telephone number"}']],
   [{"reComment":"US-style telephone number","reMatch":"\\d{3}-\\d{3}-\\d{4}","type":"string"}])
-OVSDB_CHECK_NEGATIVE([reMatch must be a valid JavaScript regexp],
-  [[parse-base-type '{"type": "string", "reMatch": "ab@:>@cd"}']],
-  [[test-ovsdb: invalid regular expression: "ab@:>@cd" is not a valid regular expression: @:>@ is an invalid data character in JavaScript compatibility mode]])
+
+AT_SETUP([reMatch must be a valid regexp])
+AT_KEYWORDS([ovsdb negative])
+if test "$HAVE_PCRE" = yes; then
+   AT_CHECK(
+     [[test-ovsdb parse-base-type \
+                  '{"type": "string", "reMatch": "x{2,1}"}']],
+     [1], [],
+     [[test-ovsdb: invalid regular expression: "x{2,1}" is not a valid regular expression: numbers out of order in {} quantifier
+]])
+else
+   AT_CHECK(
+     [[test-ovsdb parse-base-type \
+                  '{"type": "string", "reMatch": "x{2,1}"}']],
+     [0], [[{"reMatch":"x{2,1}","type":"string"}
+]], [])
+fi
+AT_CLEANUP
 
 OVSDB_CHECK_POSITIVE([string minLength], 
   [[parse-base-type '{"type": "string", "minLength": 1}']],