Regex.cc

Go to the documentation of this file.
00001 /*
00002  * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
00003  * downloading, copying, installing or using the software you agree to
00004  * this license. If you do not agree to this license, do not download,
00005  * install, copy or use the software.
00006  * 
00007  * Intel Open Source License 
00008  * 
00009  * Copyright (c) 2004 Intel Corporation. All rights reserved. 
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are
00013  * met:
00014  * 
00015  *   Redistributions of source code must retain the above copyright
00016  *   notice, this list of conditions and the following disclaimer.
00017  * 
00018  *   Redistributions in binary form must reproduce the above copyright
00019  *   notice, this list of conditions and the following disclaimer in the
00020  *   documentation and/or other materials provided with the distribution.
00021  * 
00022  *   Neither the name of the Intel Corporation nor the names of its
00023  *   contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *  
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
00030  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  */
00038 
00039 #include "../debug/DebugUtils.h"
00040 #include "Regex.h"
00041 
00042 namespace oasys {
00043 
00044 Regex::Regex(const char* regex, int cflags)
00045 {
00046     compilation_err_ = regcomp(&regex_, regex, cflags);
00047 }
00048 
00049 Regex::~Regex()
00050 {
00051     if (compilation_err_ == 0)
00052         regfree(&regex_);
00053 }
00054 
00055 int
00056 Regex::match(const char* str, int flags)
00057 {
00058     if (compilation_err_ != 0) {
00059         return compilation_err_;
00060     }
00061     
00062     return regexec(&regex_, str, MATCH_LIMIT, matches_, flags);
00063 }
00064 
00065 int 
00066 Regex::match(const char* regex, const char* str, int cflags, int rflags)
00067 {
00068     Regex r(regex, cflags);
00069     return r.match(str, rflags);
00070 }
00071 
00072 int
00073 Regex::num_matches()
00074 {
00075     for(size_t i = 0; i<MATCH_LIMIT; ++i) {
00076         if (matches_[i].rm_so == -1) {
00077             return i;
00078         }
00079     }
00080 
00081     return MATCH_LIMIT;
00082 }
00083 
00084 const regmatch_t&
00085 Regex::get_match(size_t i)
00086 {
00087     ASSERT(i <= MATCH_LIMIT);
00088     return matches_[i];
00089 }
00090 
00091 std::string
00092 Regex::regerror_str(int err)
00093 {
00094     char buf[1024];
00095     size_t len = regerror(err, &regex_, buf, sizeof(buf));
00096     return std::string(buf, len);
00097 }
00098 
00099 Regsub::Regsub(const char* regex, const char* sub_spec, int flags)
00100     : Regex(regex, flags), sub_spec_(sub_spec)
00101 {
00102 }
00103 
00104 Regsub::~Regsub()
00105 {
00106 }
00107 
00108 int
00109 Regsub::subst(const char* str, std::string* result, int flags)
00110 {
00111     int match_err = match(str, flags);
00112     if (match_err != 0) {
00113         return match_err;
00114     }
00115 
00116     size_t len = sub_spec_.length();
00117     size_t i = 0;
00118     int nmatches = num_matches();
00119 
00120     result->clear();
00121     
00122     while (i < len) {
00123         if (sub_spec_[i] == '\\') {
00124 
00125             // safe since there's a trailing null in sub_spec
00126             char c = sub_spec_[i + 1];
00127 
00128             // handle '\\'
00129             if (c == '\\') {
00130                 result->push_back('\\');
00131                 result->push_back('\\');
00132                 i += 2;
00133                 continue;
00134             }
00135 
00136             // handle \0, \1, etc
00137             int match_num = c - '0';
00138             if ((match_num >= 0) && (match_num < nmatches))
00139             {
00140                 regmatch_t* match = &matches_[match_num];
00141                 result->append(str + match->rm_so, match->rm_eo - match->rm_so);
00142                 i += 2;
00143                 continue;
00144             }
00145             else
00146             {
00147                 // out of range
00148                 result->clear();
00149                 return REG_ESUBREG;;
00150             }
00151             
00152         } else {
00153             // just copy the character
00154             result->push_back(sub_spec_[i]);
00155             ++i;
00156         }
00157     }
00158 
00159     return 0;
00160 }
00161 
00162 int
00163 Regsub::subst(const char* regex, const char* str,
00164               const char* sub_spec, std::string* result,
00165               int cflags, int rflags)
00166 {
00167     Regsub r(regex, sub_spec, cflags);
00168     return r.subst(str, result, rflags);
00169 }
00170 
00171 } // namespace oasys

Generated on Fri Dec 22 14:48:00 2006 for DTN Reference Implementation by  doxygen 1.5.1