Regex.cc

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2004-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 
00018 #include "../debug/DebugUtils.h"
00019 #include "Regex.h"
00020 
00021 namespace oasys {
00022 
00023 Regex::Regex(const char* regex, int cflags)
00024 {
00025     compilation_err_ = regcomp(&regex_, regex, cflags);
00026 }
00027 
00028 Regex::~Regex()
00029 {
00030     if (compilation_err_ == 0)
00031         regfree(&regex_);
00032 }
00033 
00034 int
00035 Regex::match(const char* str, int flags)
00036 {
00037     if (compilation_err_ != 0) {
00038         return compilation_err_;
00039     }
00040     
00041     return regexec(&regex_, str, MATCH_LIMIT, matches_, flags);
00042 }
00043 
00044 int 
00045 Regex::match(const char* regex, const char* str, int cflags, int rflags)
00046 {
00047     Regex r(regex, cflags);
00048     return r.match(str, rflags);
00049 }
00050 
00051 int
00052 Regex::num_matches()
00053 {
00054     for(size_t i = 0; i<MATCH_LIMIT; ++i) {
00055         if (matches_[i].rm_so == -1) {
00056             return i;
00057         }
00058     }
00059 
00060     return MATCH_LIMIT;
00061 }
00062 
00063 const regmatch_t&
00064 Regex::get_match(size_t i)
00065 {
00066     ASSERT(i <= MATCH_LIMIT);
00067     return matches_[i];
00068 }
00069 
00070 std::string
00071 Regex::regerror_str(int err)
00072 {
00073     char buf[1024];
00074     size_t len = regerror(err, &regex_, buf, sizeof(buf));
00075     return std::string(buf, len);
00076 }
00077 
00078 Regsub::Regsub(const char* regex, const char* sub_spec, int flags)
00079     : Regex(regex, flags), sub_spec_(sub_spec)
00080 {
00081 }
00082 
00083 Regsub::~Regsub()
00084 {
00085 }
00086 
00087 int
00088 Regsub::subst(const char* str, std::string* result, int flags)
00089 {
00090     int match_err = match(str, flags);
00091     if (match_err != 0) {
00092         return match_err;
00093     }
00094 
00095     size_t len = sub_spec_.length();
00096     size_t i = 0;
00097     int nmatches = num_matches();
00098 
00099     result->clear();
00100     
00101     while (i < len) {
00102         if (sub_spec_[i] == '\\') {
00103 
00104             // safe since there's a trailing null in sub_spec
00105             char c = sub_spec_[i + 1];
00106 
00107             // handle '\\'
00108             if (c == '\\') {
00109                 result->push_back('\\');
00110                 result->push_back('\\');
00111                 i += 2;
00112                 continue;
00113             }
00114 
00115             // handle \0, \1, etc
00116             int match_num = c - '0';
00117             if ((match_num >= 0) && (match_num < nmatches))
00118             {
00119                 regmatch_t* match = &matches_[match_num];
00120                 result->append(str + match->rm_so, match->rm_eo - match->rm_so);
00121                 i += 2;
00122                 continue;
00123             }
00124             else
00125             {
00126                 // out of range
00127                 result->clear();
00128                 return REG_ESUBREG;;
00129             }
00130             
00131         } else {
00132             // just copy the character
00133             result->push_back(sub_spec_[i]);
00134             ++i;
00135         }
00136     }
00137 
00138     return 0;
00139 }
00140 
00141 int
00142 Regsub::subst(const char* regex, const char* str,
00143               const char* sub_spec, std::string* result,
00144               int cflags, int rflags)
00145 {
00146     Regsub r(regex, sub_spec, cflags);
00147     return r.subst(str, result, rflags);
00148 }
00149 
00150 } // namespace oasys

Generated on Thu Jun 7 16:56:51 2007 for DTN Reference Implementation by  doxygen 1.5.1