_end function now runs on state END_STATE.
[qshowdiff.git] / src / parser / parser.cpp
blob6a25a5a71b8149df8c19e37f5771e1562b4cfe0d
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 break;
74 _end();
77 void Parser::_start()
79 if (_current_token == Tokens::FILE_TOK){
80 _changeState(FILE_STATE);
81 }else{
82 _readNextLine();
86 void Parser::_file()
88 _finishHunk();
90 if (_current_token == Tokens::FILE_TOK){
91 _createNewFile();
92 _readNextLine();
93 }else if (_current_token == Tokens::HUNK_TOK){
94 _changeState(HUNK_STATE);
95 }else{
96 _readNextLine();
100 void Parser::_hunk()
102 switch (_current_token){
103 case Tokens::HUNK_TOK:
104 _createNewHunk();
105 _readNextLine();
106 break;
107 case Tokens::ADDED_TOK:
108 _changeState(ADDED_STATE);
109 break;
110 case Tokens::DELETED_TOK:
111 _changeState(DELETED_STATE);
112 break;
113 case Tokens::CONTEXT_TOK:
114 _changeState(CONTEXT_STATE);
115 break;
116 default:
117 _readNextLine();
121 void Parser::_context()
123 if (_current_token == Tokens::CONTEXT_TOK){
124 _addCurrentLineToContext();
125 _readNextLine();
126 }else{
127 _finishContext();
129 switch (_current_token){
130 case Tokens::FILE_TOK:
131 _finishFile();
132 _changeState(FILE_STATE);
133 break;
134 case Tokens::HUNK_TOK:
135 _finishHunk();
136 _changeState(HUNK_STATE);
137 break;
138 case Tokens::ADDED_TOK:
139 _changeState(ADDED_STATE);
140 break;
141 case Tokens::DELETED_TOK:
142 _changeState(DELETED_STATE);
143 break;
144 default:
145 _changeState(END_STATE);
150 void Parser::_added()
152 if (_current_token == Tokens::ADDED_TOK){
153 _addCurrentLineToAdded();
154 _readNextLine();
155 }else if (_current_token == Tokens::DELETED_TOK){
156 _changeState(CHANGED_STATE);
157 }else{
158 _finishAdded();
160 switch (_current_token){
161 case Tokens::FILE_TOK:
162 _finishFile();
163 _changeState(FILE_STATE);
164 break;
165 case Tokens::HUNK_TOK:
166 _finishHunk();
167 _changeState(HUNK_STATE);
168 break;
169 case Tokens::CONTEXT_TOK:
170 _changeState(CONTEXT_STATE);
171 break;
172 default:
173 _changeState(END_STATE);
178 void Parser::_deleted()
180 if (_current_token == Tokens::DELETED_TOK){
181 _addCurrentLineToDeleted();
182 _readNextLine();
183 }else if (_current_token == Tokens::ADDED_TOK){
184 _changeState(CHANGED_STATE);
185 }else{
186 _finishDeleted();
188 switch (_current_token){
189 case Tokens::FILE_TOK:
190 _finishFile();
191 _changeState(FILE_STATE);
192 break;
193 case Tokens::HUNK_TOK:
194 _finishHunk();
195 _changeState(HUNK_STATE);
196 break;
197 case Tokens::CONTEXT_TOK:
198 _changeState(CONTEXT_STATE);
199 break;
200 default:
201 _changeState(END_STATE);
206 void Parser::_changed()
208 if (_current_token == Tokens::DELETED_TOK){
209 _addCurrentLineToDeleted();
210 _readNextLine();
211 }else if (_current_token == Tokens::ADDED_TOK){
212 _addCurrentLineToAdded();
213 _readNextLine();
214 }else{
215 _finishChanged();
217 switch (_current_token){
218 case Tokens::FILE_TOK:
219 _finishFile();
220 _changeState(FILE_STATE);
221 break;
222 case Tokens::HUNK_TOK:
223 _finishHunk();
224 _changeState(HUNK_STATE);
225 break;
226 case Tokens::CONTEXT_TOK:
227 _changeState(CONTEXT_STATE);
228 break;
229 default:
230 _changeState(END_STATE);
235 void Parser::_end()
237 _finishContext();
238 _finishChanged();
239 _finishAdded();
240 _finishDeleted();
241 _finishHunk();
242 _finishFile();
244 _changeState(END_STATE);
248 // private:
249 void Parser::_readNextLine()
251 _current_line = _in->readLine();
252 if (_current_line.isNull()){
253 _changeState(END_STATE);
254 return;
257 _current_token = _tokens->match(_current_line);
258 DBG("Read line \"" << _current_line.toStdString() << "\"");
261 void Parser::_changeState(Parser::states new_state)
263 _current_state = new_state;
264 #ifndef NDEBUG
265 string state;
266 switch (_current_state){
267 case START_STATE:
268 state = "START_STATE";
269 break;
270 case FILE_STATE:
271 state = "FILE_STATE";
272 break;
273 case HUNK_STATE:
274 state = "HUNK_STATE";
275 break;
276 case CONTEXT_STATE:
277 state = "CONTEXT_STATE";
278 break;
279 case ADDED_STATE:
280 state = "ADDED_STATE";
281 break;
282 case DELETED_STATE:
283 state = "DELETED_STATE";
284 break;
285 case CHANGED_STATE:
286 state = "CHANGED_STATE";
287 break;
288 case END_STATE:
289 state = "END_STATE";
290 break;
292 DBG("State changed to " << state);
293 #endif
297 QString Parser::_capCurrentLine(int cap)
299 switch (_current_token){
300 case Tokens::FILE_TOK:
301 return _tokens->file_tok.cap(cap);
302 case Tokens::HUNK_TOK:
303 return _tokens->hunk_tok.cap(cap);
304 case Tokens::CONTEXT_TOK:
305 return _tokens->context_tok.cap(cap);
306 case Tokens::ADDED_TOK:
307 return _tokens->added_tok.cap(cap);
308 case Tokens::DELETED_TOK:
309 return _tokens->deleted_tok.cap(cap);
310 case Tokens::NONE_TOK:
311 return "";
313 return "";
316 void Parser::_createNewFile()
318 if (_cur_file != NULL){
319 DBG("Can't create new file - _cur_file = " << (long)_cur_file);
320 return;
323 Diff::instance()->addFile(_cur_file = new File(_capCurrentLine(1)));
325 void Parser::_finishFile()
327 _cur_file = NULL;
330 void Parser::_createNewHunk()
332 if (_cur_file == NULL || _cur_hunk != NULL){
333 DBG("Can't create new hunk - _cur_hunk = " << (long)_cur_hunk
334 << ", _cur_file = " << (long)_cur_file);
335 return;
338 int from1, from2;
339 from1 = _capCurrentLine(1).toInt();
340 from2 = _capCurrentLine(2).toInt();
342 _cur_file->addHunk(_cur_hunk = new Hunk(from1, from2));
344 void Parser::_finishHunk()
346 _cur_hunk = NULL;
349 void Parser::_addCurrentLineToContext()
351 if (_cur_context == NULL)
352 _cur_context = new Text();
353 _cur_context->addLine(new QString(_current_line.remove(0,1)));
355 void Parser::_finishContext()
357 if (_cur_context == NULL || _cur_hunk == NULL)
358 return;
359 _cur_hunk->addSnippet(new Context(_cur_context));
360 _cur_context = NULL;
363 void Parser::_addCurrentLineToAdded()
365 if (_cur_added == NULL)
366 _cur_added = new Text();
367 _cur_added->addLine(new QString(_current_line.remove(0,1)));
369 void Parser::_finishAdded()
371 if (_cur_added == NULL || _cur_hunk == NULL){
372 return;
374 _cur_hunk->addSnippet(new Added(_cur_added));
375 _cur_added = NULL;
378 void Parser::_addCurrentLineToDeleted()
380 if (_cur_deleted == NULL)
381 _cur_deleted = new Text();
382 _cur_deleted->addLine(new QString(_current_line.remove(0,1)));
384 void Parser::_finishDeleted()
386 if (_cur_deleted == NULL || _cur_hunk == NULL){
387 return;
389 _cur_hunk->addSnippet(new Deleted(_cur_deleted));
390 _cur_deleted = NULL;
393 void Parser::_finishChanged()
395 if (_cur_deleted == NULL || _cur_added == NULL || _cur_hunk == NULL){
396 return;
398 _cur_hunk->addSnippet(new Changed(_cur_deleted, _cur_added));
399 _cur_deleted = NULL;
400 _cur_added = NULL;
402 /* PARSER END */
406 Tokens *factory(string type)
408 Tokens *ret;
410 ret = new TokensGit();
411 DBG("factory(" << type << ") - ret: " << (long)ret);
412 return ret;