- 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.