Created parser and interfaces for creating specific parsers for specific
[qshowdiff.git] / src / parser / parser.cpp
blob915523bfe30cae94dbeeef9737db2508e8421a95
1 #include "parser.h"
2 #include "../diff/diff.h"
4 using namespace std;
6 Tokens::Tokens(const char *f_tok,
7 const char *h_tok,
8 const char *c_tok,
9 const char *a_tok,
10 const char *d_tok) :
11 file_tok(f_tok),
12 hunk_tok(h_tok),
13 context_tok(c_tok),
14 added_tok(a_tok),
15 deleted_tok(d_tok){}
17 Tokens::token Tokens::match(QString &line) const
19 if (file_tok.indexIn(line) != -1){
20 return FILE_TOK;
21 }else if (hunk_tok.indexIn(line) != -1){
22 return HUNK_TOK;
23 }else if (context_tok.indexIn(line) != -1){
24 return CONTEXT_TOK;
25 }else if (added_tok.indexIn(line) != -1){
26 return ADDED_TOK;
27 }else if (deleted_tok.indexIn(line) != -1){
28 return DELETED_TOK;
31 return NONE_TOK;
34 TokensGit::TokensGit() : Tokens::Tokens("^diff --git a/([^ ]+) b/.*$",
35 "^@@ -([0-9]+),.* \\+([0-9]+),.*$",
36 "^ .*$",
37 "^\\+.*$",
38 "^-.*$"){}
41 /* PARSER */
42 // public:
43 void Parser::parse()
45 _readNextLine();
47 while (_current_state != END_STATE){
48 switch (_current_state){
49 case START_STATE:
50 _start();
51 break;
52 case FILE_STATE:
53 _file();
54 break;
55 case HUNK_STATE:
56 _hunk();
57 break;
58 case CONTEXT_STATE:
59 _context();
60 break;
61 case ADDED_STATE:
62 _added();
63 break;
64 case DELETED_STATE:
65 _deleted();
66 break;
67 case CHANGED_STATE:
68 _changed();
69 break;
70 case END_STATE:
71 _end();
72 break;
77 void Parser::_start()
79 if (_current_token == Tokens::FILE_TOK){
80 _changeState(FILE_STATE);
81 }else{
82 _readNextLine();
86 void Parser::_file()
88 if (_current_token == Tokens::FILE_TOK){
89 _createNewFile();
90 _readNextLine();
91 }else if (_current_token == Tokens::HUNK_TOK){
92 _changeState(HUNK_STATE);
93 }else{
94 _readNextLine();
98 void Parser::_hunk()
100 switch (_current_token){
101 case Tokens::HUNK_TOK:
102 _createNewHunk();
103 _readNextLine();
104 break;
105 case Tokens::ADDED_TOK:
106 _changeState(ADDED_STATE);
107 break;
108 case Tokens::DELETED_TOK:
109 _changeState(DELETED_STATE);
110 break;
111 case Tokens::CONTEXT_TOK:
112 _changeState(CONTEXT_STATE);
113 break;
114 default:
115 _readNextLine();
119 void Parser::_context()
121 if (_current_token == Tokens::CONTEXT_TOK){
122 _addCurrentLineToContext();
123 _readNextLine();
124 }else{
125 _finishContext();
127 switch (_current_token){
128 case Tokens::FILE_TOK:
129 _finishFile();
130 _changeState(FILE_STATE);
131 break;
132 case Tokens::HUNK_TOK:
133 _finishHunk();
134 _changeState(HUNK_STATE);
135 break;
136 case Tokens::ADDED_TOK:
137 _changeState(ADDED_STATE);
138 break;
139 case Tokens::DELETED_TOK:
140 _changeState(DELETED_STATE);
141 break;
142 default:
143 _changeState(END_STATE);
148 void Parser::_added()
150 if (_current_token == Tokens::ADDED_TOK){
151 _addCurrentLineToAdded();
152 _readNextLine();
153 }else if (_current_token == Tokens::DELETED_TOK){
154 _changeState(CHANGED_STATE);
155 }else{
156 _finishAdded();
158 switch (_current_token){
159 case Tokens::FILE_TOK:
160 _finishFile();
161 _changeState(FILE_STATE);
162 break;
163 case Tokens::HUNK_TOK:
164 _finishHunk();
165 _changeState(HUNK_STATE);
166 break;
167 case Tokens::CONTEXT_TOK:
168 _changeState(CONTEXT_STATE);
169 break;
170 default:
171 _changeState(END_STATE);
176 void Parser::_deleted()
178 if (_current_token == Tokens::DELETED_TOK){
179 _addCurrentLineToDeleted();
180 _readNextLine();
181 }else if (_current_token == Tokens::ADDED_TOK){
182 _changeState(CHANGED_STATE);
183 }else{
184 _finishDeleted();
186 switch (_current_token){
187 case Tokens::FILE_TOK:
188 _finishFile();
189 _changeState(FILE_STATE);
190 break;
191 case Tokens::HUNK_TOK:
192 _finishHunk();
193 _changeState(HUNK_STATE);
194 break;
195 case Tokens::CONTEXT_TOK:
196 _changeState(CONTEXT_STATE);
197 break;
198 default:
199 _changeState(END_STATE);
204 void Parser::_changed()
206 if (_current_token == Tokens::DELETED_TOK){
207 _addCurrentLineToDeleted();
208 _readNextLine();
209 }else if (_current_token == Tokens::ADDED_TOK){
210 _addCurrentLineToAdded();
211 _readNextLine();
212 }else{
213 _finishChanged();
215 switch (_current_token){
216 case Tokens::FILE_TOK:
217 _finishFile();
218 _changeState(FILE_STATE);
219 break;
220 case Tokens::HUNK_TOK:
221 _finishHunk();
222 _changeState(HUNK_STATE);
223 break;
224 case Tokens::CONTEXT_TOK:
225 _changeState(CONTEXT_STATE);
226 break;
227 default:
228 _changeState(END_STATE);
233 void Parser::_end()
235 _finishContext();
236 _finishChanged();
237 _finishAdded();
238 _finishDeleted();
239 _finishHunk();
240 _finishFile();
242 _changeState(END_STATE);
246 // private:
247 void Parser::_readNextLine()
249 _current_line = _in->readLine();
250 _current_token = _tokens->match(_current_line);
251 DBG("Read line \"" << _current_line.toStdString() << "\"");
254 void Parser::_changeState(Parser::states new_state)
256 _current_state = new_state;
257 #ifndef NDEBUG
258 string state;
259 switch (_current_state){
260 case START_STATE:
261 state = "START_STATE";
262 break;
263 case FILE_STATE:
264 state = "FILE_STATE";
265 break;
266 case HUNK_STATE:
267 state = "HUNK_STATE";
268 break;
269 case CONTEXT_STATE:
270 state = "CONTEXT_STATE";
271 break;
272 case ADDED_STATE:
273 state = "ADDED_STATE";
274 break;
275 case DELETED_STATE:
276 state = "DELETED_STATE";
277 break;
278 case CHANGED_STATE:
279 state = "CHANGED_STATE";
280 break;
281 case END_STATE:
282 state = "END_STATE";
283 break;
285 DBG("State changed to " << state);
286 #endif
290 QString Parser::_capCurrentLine(int cap)
292 switch (_current_token){
293 case Tokens::FILE_TOK:
294 return _tokens->file_tok.cap(cap);
295 case Tokens::HUNK_TOK:
296 return _tokens->hunk_tok.cap(cap);
297 case Tokens::CONTEXT_TOK:
298 return _tokens->context_tok.cap(cap);
299 case Tokens::ADDED_TOK:
300 return _tokens->added_tok.cap(cap);
301 case Tokens::DELETED_TOK:
302 return _tokens->deleted_tok.cap(cap);
303 case Tokens::NONE_TOK:
304 return "";
306 return "";
309 void Parser::_createNewFile()
311 if (_cur_file != NULL)
312 return;
314 Diff::instance()->addFile(_cur_file = new File(_capCurrentLine(1)));
316 void Parser::_finishFile()
318 _cur_file = NULL;
321 void Parser::_createNewHunk()
323 if (_cur_file == NULL || _cur_hunk != NULL)
324 return;
326 int from1, from2;
327 from1 = _capCurrentLine(1).toInt();
328 from2 = _capCurrentLine(2).toInt();
330 _cur_file->addHunk(_cur_hunk = new Hunk(from1, from2));
332 void Parser::_finishHunk()
334 _cur_hunk = NULL;
337 void Parser::_addCurrentLineToContext()
339 if (_cur_context == NULL)
340 _cur_context = new Text();
341 _cur_context->addLine(new QString(_current_line.remove(0,1)));
343 void Parser::_finishContext()
345 if (_cur_context == NULL || _cur_hunk == NULL)
346 return;
347 _cur_hunk->addSnippet(new Context(_cur_context));
348 _cur_context = NULL;
351 void Parser::_addCurrentLineToAdded()
353 if (_cur_added == NULL)
354 _cur_added = new Text();
355 _cur_added->addLine(new QString(_current_line.remove(0,1)));
357 void Parser::_finishAdded()
359 if (_cur_added == NULL || _cur_hunk == NULL){
360 return;
362 _cur_hunk->addSnippet(new Added(_cur_added));
363 _cur_added = NULL;
366 void Parser::_addCurrentLineToDeleted()
368 if (_cur_deleted == NULL)
369 _cur_deleted = new Text();
370 _cur_deleted->addLine(new QString(_current_line.remove(0,1)));
372 void Parser::_finishDeleted()
374 if (_cur_deleted == NULL || _cur_hunk == NULL){
375 return;
377 _cur_hunk->addSnippet(new Deleted(_cur_deleted));
378 _cur_deleted = NULL;
381 void Parser::_finishChanged()
383 if (_cur_deleted == NULL || _cur_added == NULL || _cur_hunk == NULL){
384 return;
386 _cur_hunk->addSnippet(new Changed(_cur_deleted, _cur_added));
387 _cur_deleted = NULL;
388 _cur_added = NULL;
390 /* PARSER END */
394 Tokens *factory(string type)
396 Tokens *ret;
398 ret = new TokensGit();
399 DBG("factory(" << type << ") - ret: " << (long)ret);
400 return ret;