You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2009/09/08 10:08:34 UTC

svn commit: r812370 - /commons/sandbox/runtime/trunk/src/main/native/port/pmatch.c

Author: mturk
Date: Tue Sep  8 08:08:34 2009
New Revision: 812370

URL: http://svn.apache.org/viewvc?rev=812370&view=rev
Log:
Add pmatch - borrowed from NetBSD kernel

Added:
    commons/sandbox/runtime/trunk/src/main/native/port/pmatch.c   (with props)

Added: commons/sandbox/runtime/trunk/src/main/native/port/pmatch.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/port/pmatch.c?rev=812370&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/port/pmatch.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/port/pmatch.c Tue Sep  8 08:08:34 2009
@@ -0,0 +1,423 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "acr.h"
+#include "acr_private.h"
+#include "acr_arch.h"
+#include "acr_port.h"
+
+#if defined(ACR_WANT_PMATCH)
+/*
+ * pmatch():
+ *  Return 2 on exact match.
+ *  Return 1 on substring match.
+ *  Return 0 on no match.
+ *  Return -1 on error.
+ * *estr will point to the end of the longest exact or substring match.
+ */
+int pmatch(const char *string, const char *pattern, const char **estr)
+{
+    unsigned char stringc, patternc, rangec;
+    int match, negate_range;
+    const char *oestr, *pestr, *testr;
+
+    if (estr == NULL)
+        estr = &testr;
+
+    for (;; ++string) {
+        stringc = *string;
+        switch (patternc = *pattern++) {
+        case 0:
+            *estr = string;
+            return stringc == '\0' ? 2 : 1;
+        case '?':
+            if (stringc == '\0')
+                return 0;
+            *estr = string;
+            break;
+        case '*':
+            if (!*pattern) {
+                while (*string)
+                    string++;
+                *estr = string;
+                return 2;
+            }
+            oestr = *estr;
+            pestr = NULL;
+
+            do {
+                switch (pmatch(string, pattern, estr)) {
+                case -1:
+                    return -1;
+                case 0:
+                    break;
+                case 1:
+                    pestr = *estr;
+                    break;
+                case 2:
+                    return 2;
+                default:
+                    return -1;
+                }
+                *estr = string;
+            }
+            while (*string++);
+
+            if (pestr) {
+                *estr = pestr;
+                return 1;
+            } else {
+                *estr = oestr;
+                return 0;
+            }
+
+        case '[':
+            match = 0;
+            if ((negate_range = (*pattern == '^')) != 0)
+                pattern++;
+            while ((rangec = *pattern++) != '\0') {
+                if (rangec == ']')
+                    break;
+                if (match)
+                    continue;
+                if (rangec == '-' && *(pattern - 2) != '[' &&
+                    *pattern != ']') {
+                    match =
+                        stringc <= (unsigned char)*pattern &&
+                        (unsigned char)*(pattern - 2) <= stringc;
+                    pattern++;
+                } else
+                    match = (stringc == rangec);
+            }
+            if (rangec == 0)
+                return -1;
+            if (match == negate_range)
+                return 0;
+            *estr = string;
+            break;
+        default:
+            if (patternc != stringc)
+                return 0;
+            *estr = string;
+            break;
+        }
+    }
+}
+
+#endif /* ACR_WANT_PMATCH */
+
+/* Wide char version of pmatch
+ */
+int wmatch(const wchar_t *string, const wchar_t *pattern, const wchar_t **estr)
+{
+    wchar_t stringc, patternc, rangec;
+    int match, negate_range;
+    const wchar_t *oestr, *pestr, *testr;
+
+    if (estr == NULL)
+        estr = &testr;
+
+    for (;; ++string) {
+        stringc = *string;
+        switch (patternc = *pattern++) {
+        case 0:
+            *estr = string;
+            return stringc == L'\0' ? 2 : 1;
+        case L'?':
+            if (stringc == L'\0')
+                return 0;
+            *estr = string;
+            break;
+        case L'*':
+            if (!*pattern) {
+                while (*string)
+                    string++;
+                *estr = string;
+                return 2;
+            }
+            oestr = *estr;
+            pestr = NULL;
+
+            do {
+                switch (wmatch(string, pattern, estr)) {
+                case -1:
+                    return -1;
+                case 0:
+                    break;
+                case 1:
+                    pestr = *estr;
+                    break;
+                case 2:
+                    return 2;
+                default:
+                    return -1;
+                }
+                *estr = string;
+            }
+            while (*string++);
+
+            if (pestr) {
+                *estr = pestr;
+                return 1;
+            } else {
+                *estr = oestr;
+                return 0;
+            }
+
+        case L'[':
+            match = 0;
+            if ((negate_range = (*pattern == L'^')) != 0)
+                pattern++;
+            while ((rangec = *pattern++) != L'\0') {
+                if (rangec == L']')
+                    break;
+                if (match)
+                    continue;
+                if (rangec == L'-' && *(pattern - 2) != L'[' &&
+                    *pattern != L']') {
+                    match =
+                        stringc <= (wchar_t)*pattern &&
+                        (wchar_t)*(pattern - 2) <= stringc;
+                    pattern++;
+                } else
+                    match = (stringc == rangec);
+            }
+            if (rangec == 0)
+                return -1;
+            if (match == negate_range)
+                return 0;
+            *estr = string;
+            break;
+        default:
+            if (patternc != stringc)
+                return 0;
+            *estr = string;
+            break;
+        }
+    }
+}
+
+/* Case insensitive version of pmatch
+ */
+int pimatch(const char *string, const char *pattern, const char **estr)
+{
+    unsigned char stringc, patternc, rangec;
+    int match, negate_range;
+    const char *oestr, *pestr, *testr;
+
+    if (estr == NULL)
+        estr = &testr;
+
+    for (;; ++string) {
+        stringc = acr_tolower(*string);
+        switch (patternc = acr_tolower(*pattern++)) {
+        case 0:
+            *estr = string;
+            return stringc == '\0' ? 2 : 1;
+        case '?':
+            if (stringc == '\0')
+                return 0;
+            *estr = string;
+            break;
+        case '*':
+            if (!*pattern) {
+                while (*string)
+                    string++;
+                *estr = string;
+                return 2;
+            }
+            oestr = *estr;
+            pestr = NULL;
+
+            do {
+                switch (pimatch(string, pattern, estr)) {
+                case -1:
+                    return -1;
+                case 0:
+                    break;
+                case 1:
+                    pestr = *estr;
+                    break;
+                case 2:
+                    return 2;
+                default:
+                    return -1;
+                }
+                *estr = string;
+            }
+            while (*string++);
+
+            if (pestr) {
+                *estr = pestr;
+                return 1;
+            } else {
+                *estr = oestr;
+                return 0;
+            }
+
+        case '[':
+            match = 0;
+            if ((negate_range = (*pattern == '^')) != 0)
+                pattern++;
+            while ((rangec = *pattern++) != '\0') {
+                if (rangec == ']')
+                    break;
+                if (match)
+                    continue;
+                if (rangec == '-' && *(pattern - 2) != '[' &&
+                    *pattern != ']') {
+                    match =
+                        stringc <= (unsigned char)*pattern &&
+                        (unsigned char)*(pattern - 2) <= stringc;
+                    pattern++;
+                } else
+                    match = (stringc == rangec);
+            }
+            if (rangec == 0)
+                return -1;
+            if (match == negate_range)
+                return 0;
+            *estr = string;
+            break;
+        default:
+            if (patternc != stringc)
+                return 0;
+            *estr = string;
+            break;
+        }
+    }
+}
+
+/* Wide char version of pimatch
+ */
+int wimatch(const wchar_t *string, const wchar_t *pattern, const wchar_t **estr)
+{
+    wchar_t stringc, patternc, rangec;
+    int match, negate_range;
+    const wchar_t *oestr, *pestr, *testr;
+
+    if (estr == NULL)
+        estr = &testr;
+
+    for (;; ++string) {
+        stringc = towlower(*string);
+        switch (patternc = towlower(*pattern++)) {
+        case 0:
+            *estr = string;
+            return stringc == L'\0' ? 2 : 1;
+        case L'?':
+            if (stringc == L'\0')
+                return 0;
+            *estr = string;
+            break;
+        case L'*':
+            if (!*pattern) {
+                while (*string)
+                    string++;
+                *estr = string;
+                return 2;
+            }
+            oestr = *estr;
+            pestr = NULL;
+
+            do {
+                switch (wimatch(string, pattern, estr)) {
+                case -1:
+                    return -1;
+                case 0:
+                    break;
+                case 1:
+                    pestr = *estr;
+                    break;
+                case 2:
+                    return 2;
+                default:
+                    return -1;
+                }
+                *estr = string;
+            }
+            while (*string++);
+
+            if (pestr) {
+                *estr = pestr;
+                return 1;
+            } else {
+                *estr = oestr;
+                return 0;
+            }
+
+        case L'[':
+            match = 0;
+            if ((negate_range = (*pattern == L'^')) != 0)
+                pattern++;
+            while ((rangec = *pattern++) != L'\0') {
+                if (rangec == L']')
+                    break;
+                if (match)
+                    continue;
+                if (rangec == L'-' && *(pattern - 2) != L'[' &&
+                    *pattern != L']') {
+                    match =
+                        stringc <= (wchar_t)*pattern &&
+                        (wchar_t)*(pattern - 2) <= stringc;
+                    pattern++;
+                } else
+                    match = (stringc == rangec);
+            }
+            if (rangec == 0)
+                return -1;
+            if (match == negate_range)
+                return 0;
+            *estr = string;
+            break;
+        default:
+            if (patternc != stringc)
+                return 0;
+            *estr = string;
+            break;
+        }
+    }
+}
+

Propchange: commons/sandbox/runtime/trunk/src/main/native/port/pmatch.c
------------------------------------------------------------------------------
    svn:eol-style = native