Glob.cc

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2006 Intel Corporation
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
00015  */
00016 
00017 #include "Glob.h"
00018 
00019 namespace oasys {
00020 
00021 bool
00022 Glob::fixed_glob(const char* pat, const char* str)
00023 {
00024     const int STACK_SIZE = 32;
00025     State stk[STACK_SIZE];
00026     int         stk_size = 1;
00027 
00028     stk[0].pat_      = pat;
00029     stk[0].to_match_ = str;
00030 
00031     while (stk_size > 0) 
00032     {
00033         int old_stk_size = stk_size;
00034         
00035         // Match the next character or '*'
00036         for (int i = 0; i < old_stk_size; ++i) 
00037         {
00038             State* state = &stk[i];
00039             
00040             switch (* (state->pat_)) 
00041             {
00042             case '*':
00043                 if (*(state->pat_ + 1) == *state->to_match_)
00044                 {
00045                     // Can start another state to match the rest of
00046                     // the string after the '*'
00047                     if (stk_size == STACK_SIZE) 
00048                     {
00049                         // On stack overflow, just return not matched
00050                         return false;
00051                     }
00052                     
00053                     stk[stk_size].pat_      = state->pat_ + 1;
00054                     stk[stk_size].to_match_ = state->to_match_;
00055                     stk_size++;
00056                 }
00057 
00058                 state->to_match_++;
00059                 break;
00060                 
00061             default:
00062                 if (* (state->pat_) == *(state->to_match_)) 
00063                 {
00064                     state->pat_++;
00065                     state->to_match_++;
00066                 }
00067                 else
00068                 {
00069                     state->pat_      = "";
00070                     state->to_match_ = "NO_MATCH";
00071                 }
00072                 break;
00073             }
00074         }
00075 
00076         // Clean up the states
00077         old_stk_size = stk_size;
00078         for (int i = 0, j = 0; i < old_stk_size; i++) 
00079         {
00080             State* state = &stk[i];
00081             
00082             if ((*state->pat_ == '\0' && *state->to_match_ == '\0') ||
00083                 (*state->pat_ == '*' && *(state->pat_ + 1) == '\0' && 
00084                  *state->to_match_ == '\0'))
00085             {
00086                 return true;
00087             }
00088 
00089             if (*state->pat_ == '\0' || *state->to_match_ == '\0')
00090             {
00091                 stk_size--;
00092                 continue;
00093             }
00094 
00095             stk[j] = stk[i];
00096             j++;
00097         }
00098     }
00099 
00100     return false;
00101 }
00102 
00103 } // namespace oasys
00104 
00105 #if 0
00106 
00107 #include <cstdio>
00108 
00109 void 
00110 g(const char* pat, const char* str) 
00111 {
00112     printf("%s:%s - %s\n", 
00113            pat, str, oasys::Glob::fixed_glob(pat, str) ? "match" : "no match");
00114 }
00115 
00116 int 
00117 main()
00118 {
00119     g("hello", "hello");
00120     g("hello", "world");
00121     g("hel*", "world"); 
00122     g("hel*", "helicopter"); 
00123     g("hel*lo*world", "hello there world");
00124     g("hel*lo*world", "hello there world!");
00125     g("hel*", "hello, world!");
00126     g("hel*o", "hellow");
00127     g("*world", "hello cruel world");
00128 }
00129 
00130 #endif

Generated on Sat Sep 8 08:43:28 2007 for DTN Reference Implementation by  doxygen 1.5.3