MakingThings
  • Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

osc_patternmatch.c

00001 /*********************************************************************************
00002 
00003  Copyright 2006-2008 MakingThings
00004 
00005  Licensed under the Apache License, 
00006  Version 2.0 (the "License"); you may not use this file except in compliance 
00007  with the License. You may obtain a copy of the License at
00008 
00009  http://www.apache.org/licenses/LICENSE-2.0 
00010  
00011  Unless required by applicable law or agreed to in writing, software distributed
00012  under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
00013  CONDITIONS OF ANY KIND, either express or implied. See the License for
00014  the specific language governing permissions and limitations under the License.
00015 
00016 *********************************************************************************/
00017 
00018 /*
00019     osc_patternmatch.c
00020 
00021     Adapted from OSC-pattern-match.c, by Matt Wright 
00022     Adapted from oscpattern.c, by Matt Wright and Amar Chaudhury
00023  */
00024 
00025 #include "config.h"
00026 #ifdef OSC
00027 
00028 #include "types.h"
00029 #include "osc.h"
00030 
00031 static const char *theWholePattern; /* Just for warning messages */
00032 
00033 static bool MatchBrackets (const char *pattern, const char *test);
00034 static bool MatchList (const char *pattern, const char *test);
00035 
00036 bool Osc_PatternMatch(const char *  pattern, const char * test) 
00037 {
00038   theWholePattern = pattern;
00039   
00040   if (pattern == 0 || pattern[0] == 0) 
00041   {
00042     return test[0] == 0;
00043   } 
00044   
00045   if (test[0] == 0)
00046   {
00047     if (pattern[0] == '*')
00048       return Osc_PatternMatch(pattern+1,test);
00049     else
00050       return false;
00051   }
00052 
00053   switch (pattern[0]) 
00054   {
00055     case 0: 
00056       return test[0] == 0;
00057     case '?': 
00058       return Osc_PatternMatch(pattern + 1, test + 1);
00059     case '*': 
00060       if (Osc_PatternMatch(pattern+1, test)) 
00061         return true;
00062       else 
00063         return Osc_PatternMatch(pattern, test+1);
00064     case ']':
00065     case '}':
00066       // OSCWarning("Spurious %c in pattern \".../%s/...\"",pattern[0], theWholePattern);
00067       return false;
00068     case '[':
00069       return MatchBrackets (pattern,test);
00070     case '{':
00071       return MatchList (pattern,test);
00072     case '\\':  
00073       if (pattern[1] == 0) 
00074         return test[0] == 0;
00075       else 
00076       {
00077         if (pattern[1] == test[0]) 
00078           return Osc_PatternMatch(pattern+2,test+1);
00079         else 
00080           return false;
00081       }
00082     default:
00083       if (pattern[0] == test[0]) 
00084         return Osc_PatternMatch(pattern+1,test+1);
00085       else 
00086         return false;
00087   }
00088 }
00089 
00090 
00091 /* we know that pattern[0] == '[' and test[0] != 0 */
00092 
00093 static bool MatchBrackets (const char *pattern, const char *test) 
00094 {
00095   bool result;
00096   bool negated = false;
00097   const char *p = pattern;
00098 
00099   if (pattern[1] == 0) 
00100   {
00101     // OSCWarning("Unterminated [ in pattern \".../%s/...\"", theWholePattern);
00102     return false;
00103   }
00104 
00105   if (pattern[1] == '!') 
00106   {
00107     negated = true;
00108     p++;
00109   }
00110 
00111   while (*p != ']') 
00112   {
00113     if (*p == 0) 
00114     {
00115       //OSCWarning("Unterminated [ in pattern \".../%s/...\"", theWholePattern);
00116       return false;
00117     }
00118     if (p[1] == '-' && p[2] != 0) 
00119     {
00120       if (test[0] >= p[0] && test[0] <= p[2]) 
00121       {
00122         result = !negated;
00123         goto advance;
00124       }
00125     }
00126     if (p[0] == test[0]) 
00127     {
00128       result = !negated;
00129       goto advance;
00130     }
00131     p++;
00132   }
00133 
00134   result = negated;
00135 
00136 advance:
00137 
00138   if (!result)
00139     return false;
00140 
00141   while (*p != ']') 
00142   {
00143     if (*p == 0) 
00144     {
00145       //OSCWarning("Unterminated [ in pattern \".../%s/...\"", theWholePattern);
00146       return false;
00147     }
00148     p++;
00149   }
00150 
00151   return Osc_PatternMatch(p+1,test+1);
00152 }
00153 
00154 static bool MatchList (const char *pattern, const char *test) 
00155 {
00156 
00157  const char *restOfPattern, *tp = test;
00158 
00159  for(restOfPattern = pattern; *restOfPattern != '}'; restOfPattern++) 
00160  {
00161    if (*restOfPattern == 0) 
00162    {
00163      //OSCWarning("Unterminated { in pattern \".../%s/...\"", theWholePattern);
00164      return false;
00165    }
00166  }
00167 
00168  restOfPattern++; /* skip close curly brace */
00169 
00170  pattern++; /* skip open curly brace */
00171 
00172  while (1) 
00173  {  
00174    if (*pattern == ',') 
00175    {
00176      if (Osc_PatternMatch(restOfPattern, tp)) 
00177        return true;
00178      else 
00179      {
00180        tp = test;
00181        ++pattern;
00182      }
00183    } 
00184    else 
00185    {
00186      if (*pattern == '}')
00187        return Osc_PatternMatch(restOfPattern, tp);
00188      else 
00189      {
00190        if (*pattern == *tp) 
00191        {
00192          ++pattern;
00193          ++tp;
00194        } 
00195        else 
00196        {
00197          tp = test;
00198          while (*pattern != ',' && *pattern != '}') {
00199            pattern++;
00200        }
00201        if (*pattern == ',') 
00202          pattern++;
00203       }
00204      }
00205    }
00206  }
00207 }
00208 
00209 #endif // OSC
00210 
00211 
00212 

The Make Controller Kit is an open source project maintained by MakingThings.
MakingThings code is released under the Apache 2.0 license.
Bug tracker, development wiki and status can be found at http://dev.makingthings.com.
This document was last updated on 18 May 2009.