]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_codesigning/antlr2/src/TokenStreamRewriteEngine.cpp
Security-59754.41.1.tar.gz
[apple/security.git] / OSX / libsecurity_codesigning / antlr2 / src / TokenStreamRewriteEngine.cpp
1 #include <antlr/config.hpp>
2
3 #include <string>
4 #include <list>
5 #include <vector>
6 #include <map>
7 #include <utility>
8 //#include <iostream>
9 #include <iterator>
10 #include <sstream>
11 #include <cassert>
12
13 #include <antlr/TokenStream.hpp>
14 #include <antlr/TokenWithIndex.hpp>
15 #include <antlr/BitSet.hpp>
16 #include <antlr/TokenStreamRewriteEngine.hpp>
17
18 #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
19 namespace antlr {
20 #endif
21
22 #ifndef NO_STATIC_CONSTS
23 const size_t TokenStreamRewriteEngine::MIN_TOKEN_INDEX = 0;
24 const int TokenStreamRewriteEngine::PROGRAM_INIT_SIZE = 100;
25 #endif
26
27 const char* TokenStreamRewriteEngine::DEFAULT_PROGRAM_NAME = "default";
28
29 namespace {
30
31 struct compareOperationIndex {
32 typedef TokenStreamRewriteEngine::RewriteOperation RewriteOperation;
33 bool operator() ( const RewriteOperation* a, const RewriteOperation* b ) const
34 {
35 return a->getIndex() < b->getIndex();
36 }
37 };
38 struct dumpTokenWithIndex {
39 dumpTokenWithIndex( ANTLR_USE_NAMESPACE(std)ostream& o ) : out(o) {}
40 void operator() ( const RefTokenWithIndex& t ) {
41 out << "[txt='" << t->getText() << "' tp=" << t->getType() << " idx=" << t->getIndex() << "]\n";
42 }
43 ANTLR_USE_NAMESPACE(std)ostream& out;
44 };
45 }
46
47 TokenStreamRewriteEngine::TokenStreamRewriteEngine(TokenStream& upstream)
48 : stream(upstream)
49 , index(MIN_TOKEN_INDEX)
50 , tokens()
51 , programs()
52 , discardMask()
53 {
54 }
55
56 TokenStreamRewriteEngine::TokenStreamRewriteEngine(TokenStream& upstream, size_t initialSize )
57 : stream(upstream)
58 , index(MIN_TOKEN_INDEX)
59 , tokens(initialSize)
60 , programs()
61 , discardMask()
62 {
63 }
64
65 RefToken TokenStreamRewriteEngine::nextToken( void )
66 {
67 RefTokenWithIndex t;
68 // suck tokens until end of stream or we find a non-discarded token
69 do {
70 t = RefTokenWithIndex(stream.nextToken());
71 if ( t )
72 {
73 t->setIndex(index); // what is t's index in list?
74 if ( t->getType() != Token::EOF_TYPE ) {
75 tokens.push_back(t); // track all tokens except EOF
76 }
77 index++; // move to next position
78 }
79 } while ( t && discardMask.member(t->getType()) );
80 return RefToken(t);
81 }
82
83 void TokenStreamRewriteEngine::rollback( const std::string& programName,
84 size_t instructionIndex )
85 {
86 program_map::iterator rewrite = programs.find(programName);
87 if( rewrite != programs.end() )
88 {
89 operation_list& prog = rewrite->second;
90 operation_list::iterator
91 j = prog.begin(),
92 end = prog.end();
93
94 std::advance(j,instructionIndex);
95 if( j != end )
96 prog.erase(j, end);
97 }
98 }
99
100 void TokenStreamRewriteEngine::originalToStream( std::ostream& out,
101 size_t start,
102 size_t end ) const
103 {
104 token_list::const_iterator s = tokens.begin();
105 std::advance( s, start );
106 token_list::const_iterator e = s;
107 std::advance( e, end-start );
108 std::for_each( s, e, tokenToStream(out) );
109 }
110
111 void TokenStreamRewriteEngine::toStream( std::ostream& out,
112 const std::string& programName,
113 size_t firstToken,
114 size_t lastToken ) const
115 {
116 if( tokens.size() == 0 )
117 return;
118
119 program_map::const_iterator rewriter = programs.find(programName);
120
121 if ( rewriter == programs.end() )
122 return;
123
124 // get the prog and some iterators in it...
125 const operation_list& prog = rewriter->second;
126 operation_list::const_iterator
127 rewriteOpIndex = prog.begin(),
128 rewriteOpEnd = prog.end();
129
130 size_t tokenCursor = firstToken;
131 // make sure we don't run out of the tokens we have...
132 if( lastToken > (tokens.size() - 1) ) {
133 lastToken = tokens.size() - 1;
134 }
135
136 while ( tokenCursor <= lastToken )
137 {
138 // std::cout << "tokenCursor = " << tokenCursor << " first prog index = " << (*rewriteOpIndex)->getIndex() << std::endl;
139
140 if( rewriteOpIndex != rewriteOpEnd )
141 {
142 size_t up_to_here = std::min(lastToken,(*rewriteOpIndex)->getIndex());
143 while( tokenCursor < up_to_here )
144 out << tokens[tokenCursor++]->getText();
145 }
146 while ( rewriteOpIndex != rewriteOpEnd &&
147 tokenCursor == (*rewriteOpIndex)->getIndex() &&
148 tokenCursor <= lastToken )
149 {
150 tokenCursor = (*rewriteOpIndex)->execute(out);
151 ++rewriteOpIndex;
152 }
153 if( tokenCursor <= lastToken )
154 out << tokens[tokenCursor++]->getText();
155 }
156 // std::cout << "Handling tail operations # left = " << std::distance(rewriteOpIndex,rewriteOpEnd) << std::endl;
157 // now see if there are operations (append) beyond last token index
158 std::for_each( rewriteOpIndex, rewriteOpEnd, executeOperation(out) );
159 rewriteOpIndex = rewriteOpEnd;
160 }
161
162 void TokenStreamRewriteEngine::toDebugStream( std::ostream& out,
163 size_t start,
164 size_t end ) const
165 {
166 token_list::const_iterator s = tokens.begin();
167 std::advance( s, start );
168 token_list::const_iterator e = s;
169 std::advance( e, end-start );
170 std::for_each( s, e, dumpTokenWithIndex(out) );
171 }
172
173 void TokenStreamRewriteEngine::addToSortedRewriteList( const std::string& programName,
174 RewriteOperation* op )
175 {
176 program_map::iterator rewrites = programs.find(programName);
177 // check if we got the program already..
178 if ( rewrites == programs.end() )
179 {
180 // no prog make a new one...
181 operation_list ops;
182 ops.push_back(op);
183 programs.insert(std::make_pair(programName,ops));
184 return;
185 }
186 operation_list& prog = rewrites->second;
187
188 if( prog.empty() )
189 {
190 prog.push_back(op);
191 return;
192 }
193
194 operation_list::iterator i, end = prog.end();
195 i = end;
196 --i;
197 // if at or beyond last op's index, just append
198 if ( op->getIndex() >= (*i)->getIndex() ) {
199 prog.push_back(op); // append to list of operations
200 return;
201 }
202 i = prog.begin();
203
204 if( i != end )
205 {
206 operation_list::iterator pos = std::upper_bound( i, end, op, compareOperationIndex() );
207 prog.insert(pos,op);
208 }
209 else
210 prog.push_back(op);
211 }
212
213 #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
214 }
215 #endif