Ibiltari Nora / OSC
Committer:
ibiltari
Date:
Mon Dec 10 16:51:59 2018 +0100
Revision:
14:2148b54dfdbf
timing

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ibiltari 14:2148b54dfdbf 1 #define OSC_MATCH_ENABLE_2STARS 1
ibiltari 14:2148b54dfdbf 2 #define OSC_MATCH_ENABLE_NSTARS 1
ibiltari 14:2148b54dfdbf 3 /*
ibiltari 14:2148b54dfdbf 4 Written by John MacCallum, The Center for New Music and Audio Technologies,
ibiltari 14:2148b54dfdbf 5 University of California, Berkeley. Copyright (c) 2009, The Regents of
ibiltari 14:2148b54dfdbf 6 the University of California (Regents).
ibiltari 14:2148b54dfdbf 7 Permission to use, copy, modify, distribute, and distribute modified versions
ibiltari 14:2148b54dfdbf 8 of this software and its documentation without fee and without a signed
ibiltari 14:2148b54dfdbf 9 licensing agreement, is hereby granted, provided that the above copyright
ibiltari 14:2148b54dfdbf 10 notice, this paragraph and the following two paragraphs appear in all copies,
ibiltari 14:2148b54dfdbf 11 modifications, and distributions.
ibiltari 14:2148b54dfdbf 12
ibiltari 14:2148b54dfdbf 13 IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
ibiltari 14:2148b54dfdbf 14 SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
ibiltari 14:2148b54dfdbf 15 OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
ibiltari 14:2148b54dfdbf 16 BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ibiltari 14:2148b54dfdbf 17
ibiltari 14:2148b54dfdbf 18 REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
ibiltari 14:2148b54dfdbf 19 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
ibiltari 14:2148b54dfdbf 20 PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
ibiltari 14:2148b54dfdbf 21 HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
ibiltari 14:2148b54dfdbf 22 MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
ibiltari 14:2148b54dfdbf 23 */
ibiltari 14:2148b54dfdbf 24 #include <string.h>
ibiltari 14:2148b54dfdbf 25 #include "OSCMatch.h"
ibiltari 14:2148b54dfdbf 26
ibiltari 14:2148b54dfdbf 27 static int osc_match_star(const char *pattern, const char *address);
ibiltari 14:2148b54dfdbf 28 static int osc_match_star_r(const char *pattern, const char *address);
ibiltari 14:2148b54dfdbf 29 static int osc_match_single_char(const char *pattern, const char *address);
ibiltari 14:2148b54dfdbf 30 static int osc_match_bracket(const char *pattern, const char *address);
ibiltari 14:2148b54dfdbf 31 static int osc_match_curly_brace(const char *pattern, const char *address);
ibiltari 14:2148b54dfdbf 32
ibiltari 14:2148b54dfdbf 33 int osc_match(const char *pattern, const char *address, int *pattern_offset, int *address_offset)
ibiltari 14:2148b54dfdbf 34 {
ibiltari 14:2148b54dfdbf 35 if(!strcmp(pattern, address)){
ibiltari 14:2148b54dfdbf 36 *pattern_offset = strlen(pattern);
ibiltari 14:2148b54dfdbf 37 *address_offset = strlen(address);
ibiltari 14:2148b54dfdbf 38 return OSC_MATCH_ADDRESS_COMPLETE | OSC_MATCH_PATTERN_COMPLETE;
ibiltari 14:2148b54dfdbf 39 }
ibiltari 14:2148b54dfdbf 40
ibiltari 14:2148b54dfdbf 41 const char *pattern_start;
ibiltari 14:2148b54dfdbf 42 const char *address_start;
ibiltari 14:2148b54dfdbf 43
ibiltari 14:2148b54dfdbf 44 pattern_start = pattern;
ibiltari 14:2148b54dfdbf 45 address_start = address;
ibiltari 14:2148b54dfdbf 46
ibiltari 14:2148b54dfdbf 47 *pattern_offset = 0;
ibiltari 14:2148b54dfdbf 48 *address_offset = 0;
ibiltari 14:2148b54dfdbf 49
ibiltari 14:2148b54dfdbf 50 while(*address != '\0' && *pattern != '\0'){
ibiltari 14:2148b54dfdbf 51 if(*pattern == '*'){
ibiltari 14:2148b54dfdbf 52 if(!osc_match_star(pattern, address)){
ibiltari 14:2148b54dfdbf 53 return 0;
ibiltari 14:2148b54dfdbf 54 }
ibiltari 14:2148b54dfdbf 55 while(*pattern != '/' && *pattern != '\0'){
ibiltari 14:2148b54dfdbf 56 pattern++;
ibiltari 14:2148b54dfdbf 57 }
ibiltari 14:2148b54dfdbf 58 while(*address != '/' && *address != '\0'){
ibiltari 14:2148b54dfdbf 59 address++;
ibiltari 14:2148b54dfdbf 60 }
ibiltari 14:2148b54dfdbf 61 }else if(*address == '*'){
ibiltari 14:2148b54dfdbf 62 while(*pattern != '/' && *pattern != '\0'){
ibiltari 14:2148b54dfdbf 63 pattern++;
ibiltari 14:2148b54dfdbf 64 }
ibiltari 14:2148b54dfdbf 65 while(*address != '/' && *address != '\0'){
ibiltari 14:2148b54dfdbf 66 address++;
ibiltari 14:2148b54dfdbf 67 }
ibiltari 14:2148b54dfdbf 68 }else{
ibiltari 14:2148b54dfdbf 69 int n = 0;
ibiltari 14:2148b54dfdbf 70 if(!(n = osc_match_single_char(pattern, address))){
ibiltari 14:2148b54dfdbf 71 return 0;
ibiltari 14:2148b54dfdbf 72 }
ibiltari 14:2148b54dfdbf 73 if(*pattern == '['){
ibiltari 14:2148b54dfdbf 74 while(*pattern != ']'){
ibiltari 14:2148b54dfdbf 75 pattern++;
ibiltari 14:2148b54dfdbf 76 }
ibiltari 14:2148b54dfdbf 77 pattern++;
ibiltari 14:2148b54dfdbf 78 address++;
ibiltari 14:2148b54dfdbf 79 }else if(*pattern == '{'){
ibiltari 14:2148b54dfdbf 80 while(*pattern != '}'){
ibiltari 14:2148b54dfdbf 81 pattern++;
ibiltari 14:2148b54dfdbf 82 }
ibiltari 14:2148b54dfdbf 83 pattern++;
ibiltari 14:2148b54dfdbf 84 address += n;
ibiltari 14:2148b54dfdbf 85 }else{
ibiltari 14:2148b54dfdbf 86 pattern++;
ibiltari 14:2148b54dfdbf 87 address++;
ibiltari 14:2148b54dfdbf 88 }
ibiltari 14:2148b54dfdbf 89 }
ibiltari 14:2148b54dfdbf 90 }
ibiltari 14:2148b54dfdbf 91
ibiltari 14:2148b54dfdbf 92 *pattern_offset = pattern - pattern_start;
ibiltari 14:2148b54dfdbf 93 *address_offset = address - address_start;
ibiltari 14:2148b54dfdbf 94
ibiltari 14:2148b54dfdbf 95 int r = 0;
ibiltari 14:2148b54dfdbf 96
ibiltari 14:2148b54dfdbf 97 if(*address == '\0') {
ibiltari 14:2148b54dfdbf 98 r |= OSC_MATCH_ADDRESS_COMPLETE;
ibiltari 14:2148b54dfdbf 99 }
ibiltari 14:2148b54dfdbf 100
ibiltari 14:2148b54dfdbf 101 if(*pattern == '\0') {
ibiltari 14:2148b54dfdbf 102 r |= OSC_MATCH_PATTERN_COMPLETE;
ibiltari 14:2148b54dfdbf 103 }
ibiltari 14:2148b54dfdbf 104
ibiltari 14:2148b54dfdbf 105 return r;
ibiltari 14:2148b54dfdbf 106 }
ibiltari 14:2148b54dfdbf 107
ibiltari 14:2148b54dfdbf 108 static int osc_match_star(const char *pattern, const char *address)
ibiltari 14:2148b54dfdbf 109 {
ibiltari 14:2148b54dfdbf 110 const char *address_start = address;
ibiltari 14:2148b54dfdbf 111 const char *pattern_start = pattern;
ibiltari 14:2148b54dfdbf 112 int num_stars = 0;
ibiltari 14:2148b54dfdbf 113 if(*address == '\0') { return 0; }
ibiltari 14:2148b54dfdbf 114 while(*address != '/' && *address != '\0'){
ibiltari 14:2148b54dfdbf 115 address++;
ibiltari 14:2148b54dfdbf 116 }
ibiltari 14:2148b54dfdbf 117 while(*pattern != '/' && *pattern != '\0'){
ibiltari 14:2148b54dfdbf 118 if(*pattern == '*'){
ibiltari 14:2148b54dfdbf 119 num_stars++;
ibiltari 14:2148b54dfdbf 120 }
ibiltari 14:2148b54dfdbf 121 pattern++;
ibiltari 14:2148b54dfdbf 122 }
ibiltari 14:2148b54dfdbf 123 pattern--;
ibiltari 14:2148b54dfdbf 124 address--;
ibiltari 14:2148b54dfdbf 125 switch(num_stars){
ibiltari 14:2148b54dfdbf 126 case 1:
ibiltari 14:2148b54dfdbf 127 {
ibiltari 14:2148b54dfdbf 128 const char *pp = pattern, *aa = address;
ibiltari 14:2148b54dfdbf 129 while(*pp != '*'){
ibiltari 14:2148b54dfdbf 130 if(!(osc_match_single_char(pp, aa))){
ibiltari 14:2148b54dfdbf 131 return 0;
ibiltari 14:2148b54dfdbf 132 }
ibiltari 14:2148b54dfdbf 133 if(*pp == ']' || *pp == '}'){
ibiltari 14:2148b54dfdbf 134 while(*pp != '[' && *pp != '{'){
ibiltari 14:2148b54dfdbf 135 pp--;
ibiltari 14:2148b54dfdbf 136 }
ibiltari 14:2148b54dfdbf 137 }
ibiltari 14:2148b54dfdbf 138 pp--;
ibiltari 14:2148b54dfdbf 139 aa--;
ibiltari 14:2148b54dfdbf 140 }
ibiltari 14:2148b54dfdbf 141 }
ibiltari 14:2148b54dfdbf 142 break;
ibiltari 14:2148b54dfdbf 143 case 2:
ibiltari 14:2148b54dfdbf 144 #if (OSC_MATCH_ENABLE_2STARS == 1)
ibiltari 14:2148b54dfdbf 145 {
ibiltari 14:2148b54dfdbf 146 const char *pp = pattern, *aa = address;
ibiltari 14:2148b54dfdbf 147 while(*pp != '*'){
ibiltari 14:2148b54dfdbf 148 if(!(osc_match_single_char(pp, aa))){
ibiltari 14:2148b54dfdbf 149 return 0;
ibiltari 14:2148b54dfdbf 150 }
ibiltari 14:2148b54dfdbf 151 if(*pp == ']' || *pp == '}'){
ibiltari 14:2148b54dfdbf 152 while(*pp != '[' && *pp != '{'){
ibiltari 14:2148b54dfdbf 153 pp--;
ibiltari 14:2148b54dfdbf 154 }
ibiltari 14:2148b54dfdbf 155 }
ibiltari 14:2148b54dfdbf 156 pp--;
ibiltari 14:2148b54dfdbf 157 aa--;
ibiltari 14:2148b54dfdbf 158 }
ibiltari 14:2148b54dfdbf 159 aa++; // we want to start one character forward to allow the star to match nothing
ibiltari 14:2148b54dfdbf 160 const char *star2 = pp;
ibiltari 14:2148b54dfdbf 161 const char *test = aa;
ibiltari 14:2148b54dfdbf 162 int i = 0;
ibiltari 14:2148b54dfdbf 163 while(test > address_start){
ibiltari 14:2148b54dfdbf 164 pp = star2 - 1;
ibiltari 14:2148b54dfdbf 165 aa = test - 1;
ibiltari 14:2148b54dfdbf 166 i++;
ibiltari 14:2148b54dfdbf 167 while(*pp != '*'){
ibiltari 14:2148b54dfdbf 168 if(!osc_match_single_char(pp, aa)){
ibiltari 14:2148b54dfdbf 169 break;
ibiltari 14:2148b54dfdbf 170 }
ibiltari 14:2148b54dfdbf 171 if(*pp == ']' || *pp == '}'){
ibiltari 14:2148b54dfdbf 172 while(*pp != '[' && *pp != '{'){
ibiltari 14:2148b54dfdbf 173 pp--;
ibiltari 14:2148b54dfdbf 174 }
ibiltari 14:2148b54dfdbf 175 }
ibiltari 14:2148b54dfdbf 176 pp--;
ibiltari 14:2148b54dfdbf 177 aa--;
ibiltari 14:2148b54dfdbf 178 }
ibiltari 14:2148b54dfdbf 179 if(pp == pattern_start){
ibiltari 14:2148b54dfdbf 180 return 1;
ibiltari 14:2148b54dfdbf 181 }
ibiltari 14:2148b54dfdbf 182 test--;
ibiltari 14:2148b54dfdbf 183 }
ibiltari 14:2148b54dfdbf 184 return 0;
ibiltari 14:2148b54dfdbf 185 }
ibiltari 14:2148b54dfdbf 186 break;
ibiltari 14:2148b54dfdbf 187 #else
ibiltari 14:2148b54dfdbf 188 return 0;
ibiltari 14:2148b54dfdbf 189 #endif
ibiltari 14:2148b54dfdbf 190 default:
ibiltari 14:2148b54dfdbf 191 #if (OSC_MATCH_ENABLE_NSTARS == 1)
ibiltari 14:2148b54dfdbf 192 return osc_match_star_r(pattern_start, address_start);
ibiltari 14:2148b54dfdbf 193 break;
ibiltari 14:2148b54dfdbf 194 #else
ibiltari 14:2148b54dfdbf 195 return 0;
ibiltari 14:2148b54dfdbf 196 #endif
ibiltari 14:2148b54dfdbf 197 }
ibiltari 14:2148b54dfdbf 198 return 1;
ibiltari 14:2148b54dfdbf 199 }
ibiltari 14:2148b54dfdbf 200
ibiltari 14:2148b54dfdbf 201 #if (OSC_MATCH_ENABLE_NSTARS == 1)
ibiltari 14:2148b54dfdbf 202 static int osc_match_star_r(const char *pattern, const char *address)
ibiltari 14:2148b54dfdbf 203 {
ibiltari 14:2148b54dfdbf 204 if(*address == '/' || *address == '\0'){
ibiltari 14:2148b54dfdbf 205 if(*pattern == '/' || *pattern == '\0' || (*pattern == '*' && ((*(pattern + 1) == '/') || *(pattern + 1) == '\0'))){
ibiltari 14:2148b54dfdbf 206 return 1;
ibiltari 14:2148b54dfdbf 207 }else{
ibiltari 14:2148b54dfdbf 208 return 0;
ibiltari 14:2148b54dfdbf 209 }
ibiltari 14:2148b54dfdbf 210 }
ibiltari 14:2148b54dfdbf 211 if(*pattern == '*'){
ibiltari 14:2148b54dfdbf 212 if(osc_match_star_r(pattern + 1, address)){
ibiltari 14:2148b54dfdbf 213 return 1;
ibiltari 14:2148b54dfdbf 214 }else{
ibiltari 14:2148b54dfdbf 215 return osc_match_star_r(pattern, address + 1);
ibiltari 14:2148b54dfdbf 216 }
ibiltari 14:2148b54dfdbf 217 }else{
ibiltari 14:2148b54dfdbf 218 if(!osc_match_single_char(pattern, address)){
ibiltari 14:2148b54dfdbf 219 return 0;
ibiltari 14:2148b54dfdbf 220 }
ibiltari 14:2148b54dfdbf 221 if(*pattern == '[' || *pattern == '{'){
ibiltari 14:2148b54dfdbf 222 while(*pattern != ']' && *pattern != '}'){
ibiltari 14:2148b54dfdbf 223 pattern++;
ibiltari 14:2148b54dfdbf 224 }
ibiltari 14:2148b54dfdbf 225 }
ibiltari 14:2148b54dfdbf 226 return osc_match_star_r(pattern + 1, address + 1);
ibiltari 14:2148b54dfdbf 227 }
ibiltari 14:2148b54dfdbf 228 }
ibiltari 14:2148b54dfdbf 229 #endif
ibiltari 14:2148b54dfdbf 230
ibiltari 14:2148b54dfdbf 231 static int osc_match_single_char(const char *pattern, const char *address)
ibiltari 14:2148b54dfdbf 232 {
ibiltari 14:2148b54dfdbf 233 switch(*pattern){
ibiltari 14:2148b54dfdbf 234 case '[':
ibiltari 14:2148b54dfdbf 235 return osc_match_bracket(pattern, address);
ibiltari 14:2148b54dfdbf 236 case ']':
ibiltari 14:2148b54dfdbf 237 while(*pattern != '['){
ibiltari 14:2148b54dfdbf 238 pattern--;
ibiltari 14:2148b54dfdbf 239 }
ibiltari 14:2148b54dfdbf 240 return osc_match_bracket(pattern, address);
ibiltari 14:2148b54dfdbf 241 case '{':
ibiltari 14:2148b54dfdbf 242 return osc_match_curly_brace(pattern, address);
ibiltari 14:2148b54dfdbf 243 case '}':
ibiltari 14:2148b54dfdbf 244 while(*pattern != '{'){
ibiltari 14:2148b54dfdbf 245 pattern--;
ibiltari 14:2148b54dfdbf 246 }
ibiltari 14:2148b54dfdbf 247 return osc_match_curly_brace(pattern, address);
ibiltari 14:2148b54dfdbf 248 case '?':
ibiltari 14:2148b54dfdbf 249 return 1;
ibiltari 14:2148b54dfdbf 250 default:
ibiltari 14:2148b54dfdbf 251 if(*pattern == *address){
ibiltari 14:2148b54dfdbf 252 return 1;
ibiltari 14:2148b54dfdbf 253 }else{
ibiltari 14:2148b54dfdbf 254 return 0;
ibiltari 14:2148b54dfdbf 255 }
ibiltari 14:2148b54dfdbf 256 }
ibiltari 14:2148b54dfdbf 257 return 0;
ibiltari 14:2148b54dfdbf 258 }
ibiltari 14:2148b54dfdbf 259
ibiltari 14:2148b54dfdbf 260 static int osc_match_bracket(const char *pattern, const char *address)
ibiltari 14:2148b54dfdbf 261 {
ibiltari 14:2148b54dfdbf 262 pattern++;
ibiltari 14:2148b54dfdbf 263 int val = 1;
ibiltari 14:2148b54dfdbf 264 if(*pattern == '!'){
ibiltari 14:2148b54dfdbf 265 pattern++;
ibiltari 14:2148b54dfdbf 266 val = 0;
ibiltari 14:2148b54dfdbf 267 }
ibiltari 14:2148b54dfdbf 268 int matched = !val;
ibiltari 14:2148b54dfdbf 269 while(*pattern != ']' && *pattern != '\0'){
ibiltari 14:2148b54dfdbf 270 // the character we're on now is the beginning of a range
ibiltari 14:2148b54dfdbf 271 if(*(pattern + 1) == '-'){
ibiltari 14:2148b54dfdbf 272 if(*address >= *pattern && *address <= *(pattern + 2)){
ibiltari 14:2148b54dfdbf 273 matched = val;
ibiltari 14:2148b54dfdbf 274 break;
ibiltari 14:2148b54dfdbf 275 }else{
ibiltari 14:2148b54dfdbf 276 pattern += 3;
ibiltari 14:2148b54dfdbf 277 }
ibiltari 14:2148b54dfdbf 278 }else{
ibiltari 14:2148b54dfdbf 279 // just test the character
ibiltari 14:2148b54dfdbf 280 if(*pattern == *address){
ibiltari 14:2148b54dfdbf 281 matched = val;
ibiltari 14:2148b54dfdbf 282 break;
ibiltari 14:2148b54dfdbf 283 }
ibiltari 14:2148b54dfdbf 284 pattern++;
ibiltari 14:2148b54dfdbf 285 }
ibiltari 14:2148b54dfdbf 286 }
ibiltari 14:2148b54dfdbf 287 return matched;
ibiltari 14:2148b54dfdbf 288 }
ibiltari 14:2148b54dfdbf 289
ibiltari 14:2148b54dfdbf 290 static int osc_match_curly_brace(const char *pattern, const char *address)
ibiltari 14:2148b54dfdbf 291 {
ibiltari 14:2148b54dfdbf 292 pattern++;
ibiltari 14:2148b54dfdbf 293 const char *ptr = pattern;
ibiltari 14:2148b54dfdbf 294 while(*ptr != '}' && *ptr != '\0' && *ptr != '/'){
ibiltari 14:2148b54dfdbf 295 while(*ptr != '}' && *ptr != '\0' && *ptr != '/' && *ptr != ','){
ibiltari 14:2148b54dfdbf 296 ptr++;
ibiltari 14:2148b54dfdbf 297 }
ibiltari 14:2148b54dfdbf 298 int n = ptr - pattern;
ibiltari 14:2148b54dfdbf 299 if(!strncmp(pattern, address, n)){
ibiltari 14:2148b54dfdbf 300 return n;
ibiltari 14:2148b54dfdbf 301 }else{
ibiltari 14:2148b54dfdbf 302 ptr++;
ibiltari 14:2148b54dfdbf 303 pattern = ptr;
ibiltari 14:2148b54dfdbf 304 }
ibiltari 14:2148b54dfdbf 305 }
ibiltari 14:2148b54dfdbf 306 return 0;
ibiltari 14:2148b54dfdbf 307 }