Branch data Line data Source code
1 : : // $Id: RE.h 6781 2009-06-28 00:50:04Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #ifndef re_h
6 : : #define re_h
7 : :
8 : : #include "Obj.h"
9 : : #include "Dict.h"
10 : : #include "BroString.h"
11 : : #include "CCL.h"
12 : : #include "EquivClass.h"
13 : :
14 : : #include <ctype.h>
15 : : typedef int (*cce_func)(int);
16 : :
17 : : class CCL;
18 : : class NFA_Machine;
19 : : class DFA_Machine;
20 : : class Specific_RE_Matcher;
21 : : class RE_Matcher;
22 : :
23 [ - + ][ # # ]: 448 : declare(PDict,char);
24 [ - + ][ # # ]: 3256 : declare(PDict,CCL);
25 : 2630 : declare(PList,CCL);
26 : :
27 : : extern int case_insensitive;
28 : : extern CCL* curr_ccl;
29 : : extern NFA_Machine* nfa;
30 : : extern Specific_RE_Matcher* rem;
31 : : extern const char* RE_parse_input;
32 : :
33 : : extern int re_lex(void);
34 : : extern int clower(int);
35 : : extern void synerr(const char str[]);
36 : :
37 : : typedef int_list AcceptingSet;
38 : : typedef name_list string_list;
39 : :
40 : : typedef enum { MATCH_ANYWHERE, MATCH_EXACTLY, } match_type;
41 : :
42 : : // A "specific" RE matcher will match one type of pattern: either
43 : : // MATCH_ANYWHERE or MATCH_EXACTLY.
44 : :
45 : : class Specific_RE_Matcher {
46 : : public:
47 : : Specific_RE_Matcher(match_type mt, int multiline=0);
48 : : ~Specific_RE_Matcher();
49 : :
50 : : void AddPat(const char* pat);
51 : :
52 : 0 : void SetPat(const char* pat) { pattern_text = copy_string(pat); }
53 : :
54 : : int Compile(int lazy = 0);
55 : :
56 : : // The following is vestigial from flex's use of "{name}" definitions.
57 : : // It's here because at some point we may want to support such
58 : : // functionality.
59 : : const char* LookupDef(const char* def);
60 : :
61 : 764 : void InsertCCL(const char* txt, CCL* ccl) { ccl_dict.Insert(txt, ccl); }
62 : 1069 : int InsertCCL(CCL* ccl)
63 : : {
64 : 1069 : ccl_list.append(ccl);
65 : 1069 : return ccl_list.length() - 1;
66 : : }
67 : 2044 : CCL* LookupCCL(const char* txt) { return ccl_dict.Lookup(txt); }
68 : : CCL* LookupCCL(int index) { return ccl_list[index]; }
69 : : CCL* AnyCCL();
70 : :
71 : : void ConvertCCLs();
72 : :
73 : : int MatchAll(const char* s);
74 : : int MatchAll(const BroString* s);
75 : :
76 : : // Compiles a set of regular expressions simultaniously.
77 : : // 'idx' contains indizes associated with the expressions.
78 : : // On matching, the set of indizes is returned which correspond
79 : : // to the matching expressions. (idx must not contain zeros).
80 : : int CompileSet(const string_list& set, const int_list& idx);
81 : :
82 : : // Returns the position in s just beyond where the first match
83 : : // occurs, or 0 if there is no such position in s. Note that
84 : : // if the pattern matches empty strings, matching continues
85 : : // in an attempt to match at least one character.
86 : : int Match(const char* s);
87 : : int Match(const BroString* s);
88 : :
89 : : int LongestMatch(const char* s);
90 : : int LongestMatch(const BroString* s);
91 : : int LongestMatch(const u_char* bv, int n);
92 : :
93 : 20737 : EquivClass* EC() { return &equiv_class; }
94 : :
95 : 4 : const char* PatternText() const { return pattern_text; }
96 : :
97 : 0 : DFA_Machine* DFA() const { return dfa; }
98 : :
99 : : void Dump(FILE* f);
100 : :
101 : : unsigned int MemoryAllocation() const;
102 : :
103 : : protected:
104 : : void AddAnywherePat(const char* pat);
105 : : void AddExactPat(const char* pat);
106 : :
107 : : // Used by the above. orig_fmt is the format to use when building
108 : : // up a new pattern_text from the given pattern; app_fmt is for when
109 : : // appending to an existing pattern_text.
110 : : void AddPat(const char* pat, const char* orig_fmt, const char* app_fmt);
111 : :
112 : : int MatchAll(const u_char* bv, int n);
113 : : int Match(const u_char* bv, int n);
114 : :
115 : : match_type mt;
116 : : int multiline;
117 : : char* pattern_text;
118 : :
119 : : PDict(char) defs;
120 : : PDict(CCL) ccl_dict;
121 : : PList(CCL) ccl_list;
122 : : EquivClass equiv_class;
123 : : int* ecs;
124 : : DFA_Machine* dfa;
125 : : CCL* any_ccl;
126 : : AcceptingSet* accepted;
127 : : };
128 : :
129 : : #ifdef EXPIRE_DFA_STATES
130 : : class DFA_State_Handle;
131 : : #else
132 : : class DFA_State;
133 : : typedef DFA_State DFA_State_Handle;
134 : : #endif
135 : :
136 : : class RE_Match_State {
137 : : public:
138 : 0 : RE_Match_State(Specific_RE_Matcher* matcher)
139 : 0 : {
140 [ # # ]: 0 : dfa = matcher->DFA() ? matcher->DFA() : 0;
141 : 0 : ecs = matcher->EC()->EquivClasses();
142 : 0 : current_pos = -1;
143 : 0 : current_state = 0;
144 : 0 : }
145 : :
146 : : ~RE_Match_State();
147 : :
148 : 0 : const AcceptingSet* Accepted() const { return &accepted; }
149 : 0 : const int_list* MatchPositions() const { return &match_pos; }
150 : :
151 : : // Returns the number of bytes feeded into the matcher so far
152 : : int Length() { return current_pos; }
153 : :
154 : : // Returns true if this inputs leads to at least one new match.
155 : : // If clear is true, starts matching over.
156 : : bool Match(const u_char* bv, int n, bool bol, bool eol, bool clear);
157 : :
158 : 0 : void Clear()
159 : : {
160 : 0 : current_pos = -1;
161 : 0 : current_state = 0;
162 : 0 : accepted.clear();
163 : 0 : match_pos.clear();
164 : 0 : }
165 : :
166 : : protected:
167 : : DFA_Machine* dfa;
168 : : int* ecs;
169 : :
170 : : AcceptingSet accepted;
171 : : int_list match_pos;
172 : : DFA_State_Handle* current_state;
173 : : int current_pos;
174 : : };
175 : :
176 : : class RE_Matcher : SerialObj {
177 : : public:
178 : : RE_Matcher();
179 : : RE_Matcher(const char* pat);
180 : : virtual ~RE_Matcher();
181 : :
182 : : void AddDef(const char* defn_name, const char* defn_val);
183 : : void AddPat(const char* pat);
184 : :
185 : : int Compile(int lazy = 0);
186 : :
187 : : // Returns true if s exactly matches the pattern, false otherwise.
188 : 0 : int MatchExactly(const char* s)
189 : 0 : { return re_exact->MatchAll(s); }
190 : 8 : int MatchExactly(const BroString* s)
191 : 8 : { return re_exact->MatchAll(s); }
192 : :
193 : : // Returns the position in s just beyond where the first match
194 : : // occurs, or 0 if there is no such position in s. Note that
195 : : // if the pattern matches empty strings, matching continues
196 : : // in an attempt to match at least one character.
197 : 0 : int MatchAnywhere(const char* s)
198 : 0 : { return re_anywhere->Match(s); }
199 : 2204 : int MatchAnywhere(const BroString* s)
200 : 2204 : { return re_anywhere->Match(s); }
201 : :
202 : : // Note: it matches the *longest* prefix and returns the
203 : : // length of matched prefix. It returns -1 on mismatch.
204 : 3400 : int MatchPrefix(const char* s)
205 : 3400 : { return re_exact->LongestMatch(s); }
206 : : int MatchPrefix(const BroString* s)
207 : : { return re_exact->LongestMatch(s); }
208 : 1089 : int MatchPrefix(const u_char* s, int n)
209 : 1089 : { return re_exact->LongestMatch(s, n); }
210 : :
211 : 4 : const char* PatternText() const { return re_exact->PatternText(); }
212 : : const char* AnywherePatternText() const { return re_anywhere->PatternText(); }
213 : :
214 : : bool Serialize(SerialInfo* info) const;
215 : : static RE_Matcher* Unserialize(UnserialInfo* info);
216 : :
217 : 0 : unsigned int MemoryAllocation() const
218 : : {
219 : : return padded_sizeof(*this)
220 : : + (re_anywhere ? re_anywhere->MemoryAllocation() : 0)
221 [ # # ][ # # ]: 0 : + (re_exact ? re_exact->MemoryAllocation() : 0);
222 : : }
223 : :
224 : : protected:
225 : 0 : DECLARE_SERIAL(RE_Matcher);
226 : :
227 : : Specific_RE_Matcher* re_anywhere;
228 : : Specific_RE_Matcher* re_exact;
229 : : };
230 : :
231 : : declare(PList, RE_Matcher);
232 : : typedef PList(RE_Matcher) re_matcher_list;
233 : :
234 : : extern RE_Matcher* RE_Matcher_conjunction(const RE_Matcher* re1, const RE_Matcher* re2);
235 : : extern RE_Matcher* RE_Matcher_disjunction(const RE_Matcher* re1, const RE_Matcher* re2);
236 : :
237 : : #endif
|