1 /*
2  * Copyright (c) 2002-2007  Daniel Elstner  <daniel.kitta@gmail.com>
3  *
4  * This file is part of regexxer.
5  *
6  * regexxer is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * regexxer is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with regexxer; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20 
21 #ifndef REGEXXER_FILESHARED_H_INCLUDED
22 #define REGEXXER_FILESHARED_H_INCLUDED
23 
24 #include "sharedptr.h"
25 
26 #include <gtkmm.h>
27 #include <functional>
28 #include <utility>
29 #include <vector>
30 
31 namespace Regexxer
32 {
33 
34 enum BoundState
35 {
36   BOUND_NONE  = 0,
37   BOUND_FIRST = 1 << 0,
38   BOUND_LAST  = 1 << 1
39 };
40 
41 inline BoundState operator|(BoundState a, BoundState b)
42   { return static_cast<BoundState>(static_cast<unsigned>(a) | static_cast<unsigned>(b)); }
43 
44 inline BoundState operator&(BoundState a, BoundState b)
45   { return static_cast<BoundState>(static_cast<unsigned>(a) & static_cast<unsigned>(b)); }
46 
47 inline BoundState operator^(BoundState a, BoundState b)
48   { return static_cast<BoundState>(static_cast<unsigned>(a) ^ static_cast<unsigned>(b)); }
49 
50 inline BoundState operator~(BoundState flags)
51   { return static_cast<BoundState>(~static_cast<unsigned>(flags)); }
52 
53 inline BoundState& operator|=(BoundState& a, BoundState b)
54   { return (a = static_cast<BoundState>(static_cast<unsigned>(a) | static_cast<unsigned>(b))); }
55 
56 inline BoundState& operator&=(BoundState& a, BoundState b)
57   { return (a = static_cast<BoundState>(static_cast<unsigned>(a) & static_cast<unsigned>(b))); }
58 
59 inline BoundState& operator^=(BoundState& a, BoundState b)
60   { return (a = static_cast<BoundState>(static_cast<unsigned>(a) ^ static_cast<unsigned>(b))); }
61 
62 /*
63  * This struct holds all the information that's necessary to locate a
64  * match's position in the buffer and to substitute captured substrings
65  * into a replacement string.  The latter is achieved by storing the whole
66  * subject string (i.e. the line in the buffer) together with a table of
67  * indices into it.  This arrangement should consume less memory than the
68  * alternative of storing a vector of captured substrings since we want
69  * to support $&, $`, $' too.
70  */
71 struct MatchData : public Util::SharedObject
72 {
73   int                                index;
74   int                                length;
75   Glib::ustring                      subject;
76   std::vector< std::pair<int, int> > captures;
77   Glib::RefPtr<Gtk::TextMark>        mark;
78 
79   MatchData(int match_index, const Glib::ustring& line,
80             Glib::MatchInfo& match_info);
81   ~MatchData();
82 
83   void install_mark(const Gtk::TextBuffer::iterator& pos);
84 
85   static bool                       is_match_mark(const Glib::RefPtr<Gtk::TextMark>& textmark);
86   static Util::SharedPtr<MatchData> get_from_mark(const Glib::RefPtr<Gtk::TextMark>& textmark);
87 
88 private:
89   MatchData(const MatchData&);
90   MatchData& operator=(const MatchData&);
91 };
92 
93 typedef Util::SharedPtr<MatchData> MatchDataPtr;
94 
95 /*
96  * Sort predicate for use with std::set<>.
97  */
98 struct MatchDataLess : public std::binary_function<MatchDataPtr, MatchDataPtr, bool>
99 {
operatorMatchDataLess100   bool operator()(const MatchDataPtr& a, const MatchDataPtr& b) const
101     { return (a->index < b->index); }
102 };
103 
104 } // namespace Regexxer
105 
106 #endif /* REGEXXER_FILESHARED_H_INCLUDED */
107