modded version CNMAT/OSC https://github.com/CNMAT/OSC

Dependents:   CVtoOSCConverter

Fork of osc-cnmat by Asperius van Hansen

Revision:
1:18009e3041ea
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OSCMatch.c	Fri May 16 22:10:49 2014 +0000
@@ -0,0 +1,307 @@
+#define OSC_MATCH_ENABLE_2STARS 1
+#define OSC_MATCH_ENABLE_NSTARS 1
+/*
+ Written by John MacCallum, The Center for New Music and Audio Technologies,
+ University of California, Berkeley.  Copyright (c) 2009, The Regents of
+ the University of California (Regents).
+ Permission to use, copy, modify, distribute, and distribute modified versions
+ of this software and its documentation without fee and without a signed
+ licensing agreement, is hereby granted, provided that the above copyright
+ notice, this paragraph and the following two paragraphs appear in all copies,
+ modifications, and distributions.
+ 
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+#include <string.h>
+#include "OSCMatch.h"
+
+static int osc_match_star(const char *pattern, const char *address);
+static int osc_match_star_r(const char *pattern, const char *address);
+static int osc_match_single_char(const char *pattern, const char *address);
+static int osc_match_bracket(const char *pattern, const char *address);
+static int osc_match_curly_brace(const char *pattern, const char *address);
+
+int osc_match(const char *pattern, const char *address, int *pattern_offset, int *address_offset)
+{
+    if(!strcmp(pattern, address)){
+        *pattern_offset = strlen(pattern);
+        *address_offset = strlen(address);
+        return OSC_MATCH_ADDRESS_COMPLETE | OSC_MATCH_PATTERN_COMPLETE;
+    }
+    
+    const char *pattern_start;
+    const char *address_start;
+    
+    pattern_start = pattern;
+    address_start = address;
+    
+    *pattern_offset = 0;
+    *address_offset = 0;
+    
+    while(*address != '\0' && *pattern != '\0'){
+        if(*pattern == '*'){
+            if(!osc_match_star(pattern, address)){
+                return 0;
+            }
+            while(*pattern != '/' && *pattern != '\0'){
+                pattern++;
+            }
+            while(*address != '/' && *address != '\0'){
+                address++;
+            }
+        }else if(*address == '*'){
+            while(*pattern != '/' && *pattern != '\0'){
+                pattern++;
+            }
+            while(*address != '/' && *address != '\0'){
+                address++;
+            }
+        }else{
+            int n = 0;
+            if(!(n = osc_match_single_char(pattern, address))){
+                return 0;
+            }
+            if(*pattern == '['){
+                while(*pattern != ']'){
+                    pattern++;
+                }
+                pattern++;
+                address++;
+            }else if(*pattern == '{'){
+                while(*pattern != '}'){
+                    pattern++;
+                }
+                pattern++;
+                address += n;
+            }else{
+                pattern++;
+                address++;
+            }
+        }
+    }
+    
+    *pattern_offset = pattern - pattern_start;
+    *address_offset = address - address_start;
+    
+    int r = 0;
+    
+    if(*address == '\0') {
+        r |= OSC_MATCH_ADDRESS_COMPLETE;
+    }
+    
+    if(*pattern == '\0') {
+        r |= OSC_MATCH_PATTERN_COMPLETE;
+    }
+    
+    return r;
+}
+
+static int osc_match_star(const char *pattern, const char *address)
+{
+    const char *address_start = address;
+    const char *pattern_start = pattern;
+    int num_stars = 0;
+    if(*address == '\0') { return 0; }
+    while(*address != '/' && *address != '\0'){
+        address++;
+    }
+    while(*pattern != '/' && *pattern != '\0'){
+        if(*pattern == '*'){
+            num_stars++;
+        }
+        pattern++;
+    }
+    pattern--;
+    address--;
+    switch(num_stars){
+        case 1:
+        {
+            const char *pp = pattern, *aa = address;
+            while(*pp != '*'){
+                if(!(osc_match_single_char(pp, aa))){
+                    return 0;
+                }
+                if(*pp == ']' || *pp == '}'){
+                    while(*pp != '[' && *pp != '{'){
+                        pp--;
+                    }
+                }
+                pp--;
+                aa--;
+            }
+        }
+            break;
+        case 2:
+#if (OSC_MATCH_ENABLE_2STARS == 1)
+        {
+            const char *pp = pattern, *aa = address;
+            while(*pp != '*'){
+                if(!(osc_match_single_char(pp, aa))){
+                    return 0;
+                }
+                if(*pp == ']' || *pp == '}'){
+                    while(*pp != '[' && *pp != '{'){
+                        pp--;
+                    }
+                }
+                pp--;
+                aa--;
+            }
+            aa++; // we want to start one character forward to allow the star to match nothing
+            const char *star2 = pp;
+            const char *test = aa;
+            int i = 0;
+            while(test > address_start){
+                pp = star2 - 1;
+                aa = test - 1;
+                i++;
+                while(*pp != '*'){
+                    if(!osc_match_single_char(pp, aa)){
+                        break;
+                    }
+                    if(*pp == ']' || *pp == '}'){
+                        while(*pp != '[' && *pp != '{'){
+                            pp--;
+                        }
+                    }
+                    pp--;
+                    aa--;
+                }
+                if(pp == pattern_start){
+                    return 1;
+                }
+                test--;
+            }
+            return 0;
+        }
+            break;
+#else
+            return 0;
+#endif
+        default:
+#if (OSC_MATCH_ENABLE_NSTARS == 1)
+            return osc_match_star_r(pattern_start, address_start);
+            break;
+#else
+            return 0;
+#endif
+    }
+    return 1;
+}
+
+#if (OSC_MATCH_ENABLE_NSTARS == 1)
+static int osc_match_star_r(const char *pattern, const char *address)
+{
+    if(*address == '/' || *address == '\0'){
+        if(*pattern == '/' || *pattern == '\0' || (*pattern == '*' && ((*(pattern + 1) == '/') || *(pattern + 1) == '\0'))){
+            return 1;
+        }else{
+            return 0;
+        }
+    }
+    if(*pattern == '*'){
+        if(osc_match_star_r(pattern + 1, address)){
+            return 1;
+        }else{
+            return osc_match_star_r(pattern, address + 1);
+        }
+    }else{
+        if(!osc_match_single_char(pattern, address)){
+            return 0;
+        }
+        if(*pattern == '[' || *pattern == '{'){
+            while(*pattern != ']' && *pattern != '}'){
+                pattern++;
+            }
+        }
+        return osc_match_star_r(pattern + 1, address + 1);
+    }
+}
+#endif
+
+static int osc_match_single_char(const char *pattern, const char *address)
+{
+    switch(*pattern){
+        case '[':
+            return osc_match_bracket(pattern, address);
+        case ']':
+            while(*pattern != '['){
+                pattern--;
+            }
+            return osc_match_bracket(pattern, address);
+        case '{':
+            return osc_match_curly_brace(pattern, address);
+        case '}':
+            while(*pattern != '{'){
+                pattern--;
+            }
+            return osc_match_curly_brace(pattern, address);
+        case '?':
+            return 1;
+        default:
+            if(*pattern == *address){
+                return 1;
+            }else{
+                return 0;
+            }
+    }
+    return 0;
+}
+
+static int osc_match_bracket(const char *pattern, const char *address)
+{
+    pattern++;
+    int val = 1;
+    if(*pattern == '!'){
+        pattern++;
+        val = 0;
+    }
+    int matched = !val;
+    while(*pattern != ']' && *pattern != '\0'){
+        // the character we're on now is the beginning of a range
+        if(*(pattern + 1) == '-'){
+            if(*address >= *pattern && *address <= *(pattern + 2)){
+                matched = val;
+                break;
+            }else{
+                pattern += 3;
+            }
+        }else{
+            // just test the character
+            if(*pattern == *address){
+                matched = val;
+                break;
+            }
+            pattern++;
+        }
+    }
+    return matched;
+}
+
+static int osc_match_curly_brace(const char *pattern, const char *address)
+{
+    pattern++;
+    const char *ptr = pattern;
+    while(*ptr != '}' && *ptr != '\0' && *ptr != '/'){
+        while(*ptr != '}' && *ptr != '\0' && *ptr != '/' && *ptr != ','){
+            ptr++;
+        }
+        int n = ptr - pattern;
+        if(!strncmp(pattern, address, n)){
+            return n;
+        }else{
+            ptr++;
+            pattern = ptr;
+        }
+    }
+    return 0;
+}
\ No newline at end of file