modded version CNMAT/OSC https://github.com/CNMAT/OSC
Fork of osc-cnmat by
OSCMatch.c
00001 #define OSC_MATCH_ENABLE_2STARS 1 00002 #define OSC_MATCH_ENABLE_NSTARS 1 00003 /* 00004 Written by John MacCallum, The Center for New Music and Audio Technologies, 00005 University of California, Berkeley. Copyright (c) 2009, The Regents of 00006 the University of California (Regents). 00007 Permission to use, copy, modify, distribute, and distribute modified versions 00008 of this software and its documentation without fee and without a signed 00009 licensing agreement, is hereby granted, provided that the above copyright 00010 notice, this paragraph and the following two paragraphs appear in all copies, 00011 modifications, and distributions. 00012 00013 IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 00014 SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING 00015 OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS 00016 BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00017 00018 REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 00019 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00020 PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED 00021 HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE 00022 MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 00023 */ 00024 #include <string.h> 00025 #include "OSCMatch.h" 00026 00027 static int osc_match_star(const char *pattern, const char *address); 00028 static int osc_match_star_r(const char *pattern, const char *address); 00029 static int osc_match_single_char(const char *pattern, const char *address); 00030 static int osc_match_bracket(const char *pattern, const char *address); 00031 static int osc_match_curly_brace(const char *pattern, const char *address); 00032 00033 int osc_match(const char *pattern, const char *address, int *pattern_offset, int *address_offset) 00034 { 00035 if(!strcmp(pattern, address)){ 00036 *pattern_offset = strlen(pattern); 00037 *address_offset = strlen(address); 00038 return OSC_MATCH_ADDRESS_COMPLETE | OSC_MATCH_PATTERN_COMPLETE; 00039 } 00040 00041 const char *pattern_start; 00042 const char *address_start; 00043 00044 pattern_start = pattern; 00045 address_start = address; 00046 00047 *pattern_offset = 0; 00048 *address_offset = 0; 00049 00050 while(*address != '\0' && *pattern != '\0'){ 00051 if(*pattern == '*'){ 00052 if(!osc_match_star(pattern, address)){ 00053 return 0; 00054 } 00055 while(*pattern != '/' && *pattern != '\0'){ 00056 pattern++; 00057 } 00058 while(*address != '/' && *address != '\0'){ 00059 address++; 00060 } 00061 }else if(*address == '*'){ 00062 while(*pattern != '/' && *pattern != '\0'){ 00063 pattern++; 00064 } 00065 while(*address != '/' && *address != '\0'){ 00066 address++; 00067 } 00068 }else{ 00069 int n = 0; 00070 if(!(n = osc_match_single_char(pattern, address))){ 00071 return 0; 00072 } 00073 if(*pattern == '['){ 00074 while(*pattern != ']'){ 00075 pattern++; 00076 } 00077 pattern++; 00078 address++; 00079 }else if(*pattern == '{'){ 00080 while(*pattern != '}'){ 00081 pattern++; 00082 } 00083 pattern++; 00084 address += n; 00085 }else{ 00086 pattern++; 00087 address++; 00088 } 00089 } 00090 } 00091 00092 *pattern_offset = pattern - pattern_start; 00093 *address_offset = address - address_start; 00094 00095 int r = 0; 00096 00097 if(*address == '\0') { 00098 r |= OSC_MATCH_ADDRESS_COMPLETE; 00099 } 00100 00101 if(*pattern == '\0') { 00102 r |= OSC_MATCH_PATTERN_COMPLETE; 00103 } 00104 00105 return r; 00106 } 00107 00108 static int osc_match_star(const char *pattern, const char *address) 00109 { 00110 const char *address_start = address; 00111 const char *pattern_start = pattern; 00112 int num_stars = 0; 00113 if(*address == '\0') { return 0; } 00114 while(*address != '/' && *address != '\0'){ 00115 address++; 00116 } 00117 while(*pattern != '/' && *pattern != '\0'){ 00118 if(*pattern == '*'){ 00119 num_stars++; 00120 } 00121 pattern++; 00122 } 00123 pattern--; 00124 address--; 00125 switch(num_stars){ 00126 case 1: 00127 { 00128 const char *pp = pattern, *aa = address; 00129 while(*pp != '*'){ 00130 if(!(osc_match_single_char(pp, aa))){ 00131 return 0; 00132 } 00133 if(*pp == ']' || *pp == '}'){ 00134 while(*pp != '[' && *pp != '{'){ 00135 pp--; 00136 } 00137 } 00138 pp--; 00139 aa--; 00140 } 00141 } 00142 break; 00143 case 2: 00144 #if (OSC_MATCH_ENABLE_2STARS == 1) 00145 { 00146 const char *pp = pattern, *aa = address; 00147 while(*pp != '*'){ 00148 if(!(osc_match_single_char(pp, aa))){ 00149 return 0; 00150 } 00151 if(*pp == ']' || *pp == '}'){ 00152 while(*pp != '[' && *pp != '{'){ 00153 pp--; 00154 } 00155 } 00156 pp--; 00157 aa--; 00158 } 00159 aa++; // we want to start one character forward to allow the star to match nothing 00160 const char *star2 = pp; 00161 const char *test = aa; 00162 int i = 0; 00163 while(test > address_start){ 00164 pp = star2 - 1; 00165 aa = test - 1; 00166 i++; 00167 while(*pp != '*'){ 00168 if(!osc_match_single_char(pp, aa)){ 00169 break; 00170 } 00171 if(*pp == ']' || *pp == '}'){ 00172 while(*pp != '[' && *pp != '{'){ 00173 pp--; 00174 } 00175 } 00176 pp--; 00177 aa--; 00178 } 00179 if(pp == pattern_start){ 00180 return 1; 00181 } 00182 test--; 00183 } 00184 return 0; 00185 } 00186 break; 00187 #else 00188 return 0; 00189 #endif 00190 default: 00191 #if (OSC_MATCH_ENABLE_NSTARS == 1) 00192 return osc_match_star_r(pattern_start, address_start); 00193 break; 00194 #else 00195 return 0; 00196 #endif 00197 } 00198 return 1; 00199 } 00200 00201 #if (OSC_MATCH_ENABLE_NSTARS == 1) 00202 static int osc_match_star_r(const char *pattern, const char *address) 00203 { 00204 if(*address == '/' || *address == '\0'){ 00205 if(*pattern == '/' || *pattern == '\0' || (*pattern == '*' && ((*(pattern + 1) == '/') || *(pattern + 1) == '\0'))){ 00206 return 1; 00207 }else{ 00208 return 0; 00209 } 00210 } 00211 if(*pattern == '*'){ 00212 if(osc_match_star_r(pattern + 1, address)){ 00213 return 1; 00214 }else{ 00215 return osc_match_star_r(pattern, address + 1); 00216 } 00217 }else{ 00218 if(!osc_match_single_char(pattern, address)){ 00219 return 0; 00220 } 00221 if(*pattern == '[' || *pattern == '{'){ 00222 while(*pattern != ']' && *pattern != '}'){ 00223 pattern++; 00224 } 00225 } 00226 return osc_match_star_r(pattern + 1, address + 1); 00227 } 00228 } 00229 #endif 00230 00231 static int osc_match_single_char(const char *pattern, const char *address) 00232 { 00233 switch(*pattern){ 00234 case '[': 00235 return osc_match_bracket(pattern, address); 00236 case ']': 00237 while(*pattern != '['){ 00238 pattern--; 00239 } 00240 return osc_match_bracket(pattern, address); 00241 case '{': 00242 return osc_match_curly_brace(pattern, address); 00243 case '}': 00244 while(*pattern != '{'){ 00245 pattern--; 00246 } 00247 return osc_match_curly_brace(pattern, address); 00248 case '?': 00249 return 1; 00250 default: 00251 if(*pattern == *address){ 00252 return 1; 00253 }else{ 00254 return 0; 00255 } 00256 } 00257 return 0; 00258 } 00259 00260 static int osc_match_bracket(const char *pattern, const char *address) 00261 { 00262 pattern++; 00263 int val = 1; 00264 if(*pattern == '!'){ 00265 pattern++; 00266 val = 0; 00267 } 00268 int matched = !val; 00269 while(*pattern != ']' && *pattern != '\0'){ 00270 // the character we're on now is the beginning of a range 00271 if(*(pattern + 1) == '-'){ 00272 if(*address >= *pattern && *address <= *(pattern + 2)){ 00273 matched = val; 00274 break; 00275 }else{ 00276 pattern += 3; 00277 } 00278 }else{ 00279 // just test the character 00280 if(*pattern == *address){ 00281 matched = val; 00282 break; 00283 } 00284 pattern++; 00285 } 00286 } 00287 return matched; 00288 } 00289 00290 static int osc_match_curly_brace(const char *pattern, const char *address) 00291 { 00292 pattern++; 00293 const char *ptr = pattern; 00294 while(*ptr != '}' && *ptr != '\0' && *ptr != '/'){ 00295 while(*ptr != '}' && *ptr != '\0' && *ptr != '/' && *ptr != ','){ 00296 ptr++; 00297 } 00298 int n = ptr - pattern; 00299 if(!strncmp(pattern, address, n)){ 00300 return n; 00301 }else{ 00302 ptr++; 00303 pattern = ptr; 00304 } 00305 } 00306 return 0; 00307 }
Generated on Fri Jul 22 2022 01:41:29 by 1.7.2