ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/truck/Common/regex.cpp
Revision: 3
Committed: 2007-04-26T01:51:35-07:00 (18 years, 2 months ago) by douglas
File size: 4051 byte(s)
Log Message:
Stuffs!

File Contents

# User Rev Content
1 douglas 3 // Charlemagne Package Manager
2     //
3     // Douglas Thrift
4     //
5     // $Id$
6    
7     /* Menes - C++ High-Level Utility Library
8     * Copyright (C) 2003-2005 Jay Freeman (saurik)
9     */
10    
11     /*
12     * Redistribution and use in source and binary
13     * forms, with or without modification, are permitted
14     * provided that the following conditions are met:
15     *
16     * 1. Redistributions of source code must retain the
17     * above copyright notice, this list of conditions
18     * and the following disclaimer.
19     * 2. Redistributions in binary form must reproduce the
20     * above copyright notice, this list of conditions
21     * and the following disclaimer in the documentation
22     * and/or other materials provided with the
23     * distribution.
24     * 3. The name of the author may not be used to endorse
25     * or promote products derived from this software
26     * without specific prior written permission.
27     *
28     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
29     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
30     * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31     * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32     * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
33     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
34     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
35     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
36     * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
37     * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
38     * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39     * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
40     * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41     * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42     */
43    
44     #include <cassert>
45     #include <sstream>
46    
47     #include "regex.hpp"
48    
49     #undef _assert
50     #define _assert(b) assert(b)
51    
52     namespace Pcre
53     {
54    
55     Error::Error(int code)
56     {
57     std::ostringstream message;
58    
59     message << "Pcre[#" << code << "] ";
60    
61     switch (code)
62     {
63     case PCRE_ERROR_NOMATCH:
64     message << "PCRE_ERROR_NOMATCH";
65    
66     break;
67    
68     case PCRE_ERROR_NULL:
69     message << "PCRE_ERROR_NULL";
70    
71     break;
72    
73     case PCRE_ERROR_BADOPTION:
74     message << "PCRE_ERROR_BADOPTION";
75    
76     break;
77    
78     case PCRE_ERROR_BADMAGIC:
79     message << "PCRE_ERROR_BADMAGIC";
80    
81     break;
82    
83     case PCRE_ERROR_UNKNOWN_NODE:
84     message << "PCRE_ERROR_UNKNOWN_NODE";
85    
86     break;
87    
88     case PCRE_ERROR_NOMEMORY:
89     message << "PCRE_ERROR_NOMEMORY";
90    
91     break;
92    
93     case PCRE_ERROR_NOSUBSTRING:
94     message << "PCRE_ERROR_NOSUBSTRING";
95    
96     break;
97    
98     case PCRE_ERROR_MATCHLIMIT:
99     message << "PCRE_ERROR_MATCHLIMIT";
100    
101     break;
102    
103     case PCRE_ERROR_CALLOUT:
104     message << "PCRE_ERROR_CALLOUT";
105    
106     break;
107     case PCRE_ERROR_BADUTF8:
108     message << "PCRE_ERROR_BADUTF8";
109    
110     break;
111    
112     case PCRE_ERROR_BADUTF8_OFFSET:
113     message << "PCRE_ERROR_BADUTF8_OFFSET";
114    
115     break;
116    
117     default:
118     message << "Unknown Error";
119     }
120    
121     this->message = message.str();
122     }
123    
124     RegEx::Match::Match(const std::string &data, std::vector<int> &substrings) : data(data)
125     {
126     std::swap(this->substrings, substrings);
127     }
128    
129     RegEx::Match::Match() {}
130    
131     RegEx::Match::operator bool() const
132     {
133     return !substrings.empty();
134     }
135    
136     std::string RegEx::Match::operator [](size_t substring) const
137     {
138     size_t index(substring * 2);
139    
140     if (index >= substrings.size())
141     return std::string();
142    
143     return std::string(data.begin() + substrings[index], data.begin() + substrings[index + 1]);
144     }
145    
146     RegEx::RegEx(const std::string &pattern) : code(NULL), study(NULL), capture(-1)
147     {
148     const char *error;
149     int offset;
150    
151     code = ::pcre_compile(pattern.c_str(), PCRE_DOTALL | PCRE_DOLLAR_ENDONLY, &error, &offset, NULL);
152    
153     int err(::pcre_fullinfo(code, study, PCRE_INFO_CAPTURECOUNT, &capture));
154    
155     if (err != 0)
156     {
157     _assert(err < 0);
158    
159     throw Error(err);
160     }
161    
162     _assert(capture >= 0);
163     }
164    
165     RegEx::~RegEx()
166     {
167     ::pcre_free(code);
168     }
169    
170     RegEx::Match RegEx::operator ()(const std::string &data) const
171     {
172     std::vector<int> substrings((capture + 1) * 3);
173     int err(::pcre_exec(code, study, data.c_str(), data.size(), 0, 0, &substrings.front(), substrings.size()));
174    
175     _assert(err != 0);
176    
177     if (err == PCRE_ERROR_NOMATCH)
178     err = 0;
179    
180     if (err < 0)
181     throw Error(err);
182    
183     substrings.resize(err * 2);
184    
185     return Match(data, substrings);
186     }
187    
188     }