~kubuntu-members/kompare/4.11

« back to all changes in this revision

Viewing changes to libdiff2/parserbase.cpp

  • Committer: Otto Bruggeman
  • Date: 2003-08-22 20:54:19 UTC
  • Revision ID: git-v1:d09a8c32a5056998bdb6f604549a5f24c8f6fe75
Die make_it_cool, die kompare! :)

svn path=/trunk/kdesdk/kompare/; revision=244089

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
**                             parserbase.cpp
 
3
**                              -------------------
 
4
**      begin                   : Sun Aug  4 15:05:35 2002
 
5
**      copyright               : (C) 2002-2003 by Otto Bruggeman
 
6
**      email                   : otto.bruggeman@home.nl
 
7
**
 
8
***************************************************************************/
 
9
/***************************************************************************
 
10
**
 
11
**   This program is free software; you can redistribute it and/or modify
 
12
**   it under the terms of the GNU General Public License as published by
 
13
**   the Free Software Foundation; either version 2 of the License, or
 
14
**   ( at your option ) any later version.
 
15
**
 
16
***************************************************************************/
 
17
 
 
18
//#include <qstring.h>
 
19
 
 
20
#include <kdebug.h>
 
21
 
 
22
#include "diffmodel.h"
 
23
#include "diffhunk.h"
 
24
#include "difference.h"
 
25
 
 
26
#include "parserbase.h"
 
27
 
 
28
using namespace Diff2;
 
29
 
 
30
ParserBase::ParserBase( const QStringList& diff ) :
 
31
    m_diffLines( diff ),
 
32
    m_currentModel( 0 ),
 
33
    m_models( 0 ),
 
34
    m_diffIterator( m_diffLines.begin() ),
 
35
    m_modelIndex( 0 ),
 
36
    m_diffIndex( 0 )
 
37
{
 
38
//      kdDebug(8101) << diff << endl;
 
39
//      kdDebug(8101) << m_diffLines << endl;
 
40
        m_models = new QPtrList<DiffModel>;
 
41
 
 
42
        // used in contexthunkheader
 
43
        m_contextHunkHeader1.setPattern( "^\\*{15} ?(.*)$" ); // capture is for function name
 
44
        m_contextHunkHeader2.setPattern( "^\\*\\*\\* ([0-9]+),([0-9]+) \\*\\*\\*\\*$" );
 
45
        // used in contexthunkbody
 
46
        m_contextHunkHeader3.setPattern( "^--- ([0-9]+),([0-9]+) ----$" );
 
47
 
 
48
        m_contextHunkBodyRemoved.setPattern( "^- (.*)$" );
 
49
        m_contextHunkBodyAdded.setPattern  ( "^\\+ (.*)$" );
 
50
        m_contextHunkBodyChanged.setPattern( "^! (.*)$" );
 
51
        m_contextHunkBodyContext.setPattern( "^  (.*)$" );
 
52
        m_contextHunkBodyLine.setPattern   ( "^[-\\+! ] (.*)$" );
 
53
 
 
54
        // This regexp sucks... i'll see what happens
 
55
        m_normalDiffHeader.setPattern( "^diff (?:(?:-|--)[a-zA-Z0-9=\\\"]+ )*(?:|-- +)(.*) +(.*)$" );
 
56
 
 
57
        m_normalHunkHeaderAdded.setPattern  ( "^([0-9]+)a([0-9]+)(|,[0-9]+)(.*)$" );
 
58
        m_normalHunkHeaderRemoved.setPattern( "^([0-9]+)(|,[0-9]+)d([0-9]+)(.*)$" );
 
59
        m_normalHunkHeaderChanged.setPattern( "^([0-9]+)(|,[0-9]+)c([0-9]+)(|,[0-9]+)(.*)$" );
 
60
 
 
61
        m_normalHunkBodyRemoved.setPattern  ( "^< (.*)$" );
 
62
        m_normalHunkBodyAdded.setPattern    ( "^> (.*)$" );
 
63
        m_normalHunkBodyDivider.setPattern  ( "^---$" );
 
64
 
 
65
        m_unifiedDiffHeader1.setPattern    ( "^--- ([^\\t]+)\\t([^\\t]+)(?:\\t?)(.*)$" );
 
66
        m_unifiedDiffHeader2.setPattern    ( "^\\+\\+\\+ ([^\\t]+)\\t([^\\t]+)(?:\\t?)(.*)$" );
 
67
        m_unifiedHunkHeader.setPattern     ( "^@@ -([0-9]+)(|,([0-9]+)) \\+([0-9]+)(|,([0-9]+)) @@(?: ?)(.*)$" );
 
68
        m_unifiedHunkBodyAdded.setPattern  ( "^\\+(.*)$" );
 
69
        m_unifiedHunkBodyRemoved.setPattern( "^-(.*)$" );
 
70
        m_unifiedHunkBodyContext.setPattern( "^ (.*)$" );
 
71
        m_unifiedHunkBodyLine.setPattern   ( "^([-+ ])(.*)$" );
 
72
}
 
73
 
 
74
ParserBase::~ParserBase()
 
75
{
 
76
}
 
77
 
 
78
enum Kompare::Format ParserBase::determineFormat()
 
79
{
 
80
        // Write your own format detection routine damn it :)
 
81
        return Kompare::UnknownFormat;
 
82
}
 
83
 
 
84
QPtrList<DiffModel>* ParserBase::parse()
 
85
{
 
86
        switch( determineFormat() )
 
87
        {
 
88
                case Kompare::Context :
 
89
                        return parseContext();
 
90
                case Kompare::Ed :
 
91
                        return parseEd();
 
92
                case Kompare::Normal :
 
93
                        return parseNormal();
 
94
                case Kompare::RCS :
 
95
                        return parseRCS();
 
96
                case Kompare::Unified :
 
97
                        return parseUnified();
 
98
                default: // Unknown and SideBySide for now
 
99
                        return 0L;
 
100
        }
 
101
}
 
102
 
 
103
bool ParserBase::parseContextDiffHeader()
 
104
{
 
105
        kdDebug(8101) << "ParserBase::parseContextDiffHeader()" << endl;
 
106
        bool result = false;
 
107
 
 
108
        while ( m_diffIterator != m_diffLines.end() )
 
109
        {
 
110
                if ( !m_contextDiffHeader1.exactMatch( *(m_diffIterator)++ ) )
 
111
                {
 
112
                        continue;
 
113
                }
 
114
                kdDebug(8101) << "Matched length Header1 = " << m_contextDiffHeader1.matchedLength() << endl;
 
115
                kdDebug(8101) << "Matched string Header1 = " << m_contextDiffHeader1.cap( 0 ) << endl;
 
116
                if ( m_diffIterator != m_diffLines.end() && m_contextDiffHeader2.exactMatch( *m_diffIterator ) )
 
117
                {
 
118
                        kdDebug(8101) << "Matched length Header2 = " << m_contextDiffHeader2.matchedLength() << endl;
 
119
                        kdDebug(8101) << "Matched string Header2 = " << m_contextDiffHeader2.cap( 0 ) << endl;
 
120
 
 
121
                        m_currentModel = new DiffModel();
 
122
                        m_currentModel->setSourceFile          ( m_contextDiffHeader1.cap( 1 ) );
 
123
                        m_currentModel->setSourceTimestamp     ( m_contextDiffHeader1.cap( 2 ) );
 
124
                        m_currentModel->setSourceRevision      ( m_contextDiffHeader1.cap( 4 ) );
 
125
                        m_currentModel->setDestinationFile     ( m_contextDiffHeader2.cap( 1 ) );
 
126
                        m_currentModel->setDestinationTimestamp( m_contextDiffHeader2.cap( 2 ) );
 
127
                        m_currentModel->setDestinationRevision ( m_contextDiffHeader2.cap( 4 ) );
 
128
                        m_currentModel->setIndex( m_modelIndex++ );
 
129
 
 
130
                        ++m_diffIterator;
 
131
                        m_diffIndex = 0;
 
132
                        result = true;
 
133
 
 
134
                        break;
 
135
                }
 
136
                else
 
137
                {
 
138
                        // We're screwed, second line does not match or is not there...
 
139
                        break;
 
140
                }
 
141
                // Dont inc the Iterator because the second line might be the first line of
 
142
                // the context header and the first hit was a fluke (impossible imo)
 
143
                // maybe we should return false here because the diff is broken ?
 
144
        }
 
145
 
 
146
        return result;
 
147
}
 
148
 
 
149
bool ParserBase::parseEdDiffHeader()
 
150
{
 
151
        return false;
 
152
}
 
153
 
 
154
bool ParserBase::parseNormalDiffHeader()
 
155
{
 
156
        kdDebug(8101) << "ParserBase::parseNormalDiffHeader()" << endl;
 
157
        bool result = false;
 
158
 
 
159
        while ( m_diffIterator != m_diffLines.end() )
 
160
        {
 
161
                if ( m_normalDiffHeader.exactMatch( *(m_diffIterator)++ ) )
 
162
                {
 
163
//                      kdDebug(8101) << "Matched length Header = " << m_normalDiffHeader.matchedLength() << endl;
 
164
//                      kdDebug(8101) << "Matched string Header = " << m_normalDiffHeader.cap( 0 ) << endl;
 
165
 
 
166
                        m_currentModel = new DiffModel();
 
167
                        m_currentModel->setSourceFile          ( m_normalDiffHeader.cap( 1 ) );
 
168
                        m_currentModel->setDestinationFile     ( m_normalDiffHeader.cap( 2 ) );
 
169
                        m_currentModel->setIndex( m_modelIndex++ );
 
170
 
 
171
                        m_diffIndex = 0;
 
172
                        result = true;
 
173
 
 
174
                        break;
 
175
                }
 
176
        }
 
177
 
 
178
        return result;
 
179
}
 
180
 
 
181
bool ParserBase::parseRCSDiffHeader()
 
182
{
 
183
        return false;
 
184
}
 
185
 
 
186
bool ParserBase::parseUnifiedDiffHeader()
 
187
{
 
188
        kdDebug(8101) << "ParserBase::parseUnifiedDiffHeader()" << endl;
 
189
        bool result = false;
 
190
 
 
191
        while ( m_diffIterator != m_diffLines.end() ) // dont assume we start with the diffheader1 line
 
192
        {
 
193
                if ( !m_unifiedDiffHeader1.exactMatch( *(m_diffIterator)++ ) )
 
194
                {
 
195
                        continue;
 
196
                }
 
197
                kdDebug(8101) << "Matched length Header1 = " << m_unifiedDiffHeader1.matchedLength() << endl;
 
198
                kdDebug(8101) << "Matched string Header1 = " << m_unifiedDiffHeader1.cap( 0 ) << endl;
 
199
                if ( m_diffIterator != m_diffLines.end() && m_unifiedDiffHeader2.exactMatch( *m_diffIterator ) )
 
200
                {
 
201
                        m_currentModel = new DiffModel();
 
202
                        m_currentModel->setSourceFile( m_unifiedDiffHeader1.cap( 1 ) );
 
203
                        m_currentModel->setSourceTimestamp( m_unifiedDiffHeader1.cap( 2 ) );
 
204
                        m_currentModel->setSourceRevision( m_unifiedDiffHeader1.cap( 4 ) );
 
205
                        m_currentModel->setDestinationFile( m_unifiedDiffHeader2.cap( 1 ) );
 
206
                        m_currentModel->setDestinationTimestamp( m_unifiedDiffHeader2.cap( 2 ) );
 
207
                        m_currentModel->setDestinationRevision( m_unifiedDiffHeader2.cap( 4 ) );
 
208
                        m_currentModel->setIndex( m_modelIndex++ );
 
209
 
 
210
                        ++m_diffIterator;
 
211
                        m_diffIndex = 0;
 
212
                        result = true;
 
213
 
 
214
                        break;
 
215
                }
 
216
                else
 
217
                {
 
218
                        // We're screwed, second line does not match or is not there...
 
219
                        break;
 
220
                }
 
221
        }
 
222
 
 
223
        return result;
 
224
}
 
225
 
 
226
bool ParserBase::parseContextHunkHeader()
 
227
{
 
228
        kdDebug(8101) << "ParserBase::parseContextHunkHeader()" << endl;
 
229
 
 
230
        if ( m_diffIterator == m_diffLines.end() )
 
231
                return false;
 
232
 
 
233
        if ( !m_contextHunkHeader1.exactMatch( *(m_diffIterator) ) )
 
234
                return false; // big fat trouble, aborting...
 
235
 
 
236
        m_diffIterator++;
 
237
 
 
238
        if ( m_diffIterator == m_diffLines.end() )
 
239
                return false;
 
240
 
 
241
        if ( !m_contextHunkHeader2.exactMatch( *(m_diffIterator) ) )
 
242
                return false; // big fat trouble, aborting...
 
243
 
 
244
        m_diffIterator++;
 
245
 
 
246
        return true;
 
247
}
 
248
 
 
249
bool ParserBase::parseEdHunkHeader()
 
250
{
 
251
        return false;
 
252
}
 
253
 
 
254
bool ParserBase::parseNormalHunkHeader()
 
255
{
 
256
//      kdDebug(8101) << "ParserBase::parseNormalHunkHeader()" << endl;
 
257
        if ( m_diffIterator != m_diffLines.end() )
 
258
        {
 
259
//              kdDebug(8101) << "Header = " << *m_diffIterator << endl;
 
260
                if ( m_normalHunkHeaderAdded.exactMatch( *m_diffIterator ) )
 
261
                {
 
262
                        m_normalDiffType = Difference::Insert;
 
263
                }
 
264
                else if ( m_normalHunkHeaderRemoved.exactMatch( *m_diffIterator ) )
 
265
                {
 
266
                        m_normalDiffType = Difference::Delete;
 
267
                }
 
268
                else if ( m_normalHunkHeaderChanged.exactMatch( *m_diffIterator ) )
 
269
                {
 
270
                        m_normalDiffType = Difference::Change;
 
271
                }
 
272
                else
 
273
                        return false;
 
274
 
 
275
                m_diffIterator++;
 
276
                return true;
 
277
        }
 
278
 
 
279
        return false;
 
280
}
 
281
 
 
282
bool ParserBase::parseRCSHunkHeader()
 
283
{
 
284
        return false;
 
285
}
 
286
 
 
287
bool ParserBase::parseUnifiedHunkHeader()
 
288
{
 
289
        kdDebug(8101) << "ParserBase::parseUnifiedHunkHeader()" << endl;
 
290
 
 
291
        if ( m_unifiedHunkHeader.exactMatch( *m_diffIterator ) )
 
292
        {
 
293
                m_diffIterator++;
 
294
                return true;
 
295
        }
 
296
        else
 
297
        {
 
298
                kdDebug(8101) << "This is not a unified hunk header : " << (*m_diffIterator) << endl;
 
299
                return false;
 
300
        }
 
301
 
 
302
}
 
303
 
 
304
bool ParserBase::parseContextHunkBody()
 
305
{
 
306
        kdDebug(8101) << "ParserBase::parseContextHunkBody()" << endl;
 
307
 
 
308
        // Storing the src part of the hunk for later use
 
309
        QStringList oldLines;
 
310
        for( ; m_diffIterator != m_diffLines.end() && m_contextHunkBodyLine.exactMatch( *m_diffIterator ); ++m_diffIterator ) {
 
311
                oldLines.append( *m_diffIterator );
 
312
        }
 
313
 
 
314
        if( !m_contextHunkHeader3.exactMatch( *(m_diffIterator)++ ) )
 
315
                return false;
 
316
 
 
317
        // Storing the dest part of the hunk for later use
 
318
        QStringList newLines;
 
319
        for( ; m_diffIterator != m_diffLines.end() && m_contextHunkBodyLine.exactMatch( *m_diffIterator ); ++m_diffIterator ) {
 
320
                newLines.append( *m_diffIterator );
 
321
        }
 
322
 
 
323
        QString function = m_contextHunkHeader1.cap( 1 );
 
324
        kdDebug() << "Captured function: " << function << endl;
 
325
        int linenoA      = m_contextHunkHeader2.cap( 1 ).toInt();
 
326
        kdDebug() << "Source line number: " << linenoA << endl;
 
327
        int linenoB      = m_contextHunkHeader3.cap( 1 ).toInt();
 
328
        kdDebug() << "Dest   line number: " << linenoB << endl;
 
329
 
 
330
        DiffHunk* hunk = new DiffHunk( linenoA, linenoB, function );
 
331
 
 
332
        m_currentModel->addHunk( hunk );
 
333
 
 
334
        QStringList::Iterator oldIt = oldLines.begin();
 
335
        QStringList::Iterator newIt = newLines.begin();
 
336
 
 
337
        Difference* diff;
 
338
        while( oldIt != oldLines.end() || newIt != newLines.end() )
 
339
        {
 
340
                if( oldIt != oldLines.end() && m_contextHunkBodyRemoved.exactMatch( *oldIt ) )
 
341
                {
 
342
                        kdDebug(8101) << "Delete: " << endl;
 
343
                        diff = new Difference( linenoA, linenoB );
 
344
                        diff->setType( Difference::Delete );
 
345
                        diff->setIndex( m_diffIndex++ );
 
346
                        m_currentModel->addDiff( diff );
 
347
                        kdDebug(8101) << "Difference added" << endl;
 
348
                        hunk->add( diff );
 
349
                        for( ; oldIt != oldLines.end() && m_contextHunkBodyRemoved.exactMatch( *oldIt ); ++oldIt )
 
350
                        {
 
351
                                kdDebug(8101) << " " << m_contextHunkBodyRemoved.cap( 1 ) << endl;
 
352
                                diff->addSourceLine( m_contextHunkBodyRemoved.cap( 1 ) );
 
353
                                linenoA++;
 
354
                        }
 
355
                }
 
356
 
 
357
                else if( newIt != newLines.end() && m_contextHunkBodyAdded.exactMatch( *newIt ) )
 
358
                {
 
359
                        kdDebug(8101) << "Insert: " << endl;
 
360
                        diff = new Difference( linenoA, linenoB );
 
361
                        diff->setType( Difference::Insert );
 
362
                        diff->setIndex( m_diffIndex++ );
 
363
                        m_currentModel->addDiff( diff );
 
364
                        kdDebug(8101) << "Difference added" << endl;
 
365
                        hunk->add( diff );
 
366
                        for( ; newIt != newLines.end() && m_contextHunkBodyAdded.exactMatch( *newIt ); ++newIt )
 
367
                        {
 
368
                                kdDebug(8101) << " " << m_contextHunkBodyAdded.cap( 1 ) << endl;
 
369
                                diff->addDestinationLine( m_contextHunkBodyAdded.cap( 1 ) );
 
370
                                linenoB++;
 
371
                        }
 
372
                }
 
373
 
 
374
                else if(  ( oldIt != oldLines.end() && m_contextHunkBodyContext.exactMatch( *oldIt ) ) ||
 
375
                          ( newIt != newLines.end() && m_contextHunkBodyContext.exactMatch( *newIt ) ) )
 
376
                {
 
377
                        kdDebug(8101) << "Unchanged: " << endl;
 
378
                        diff = new Difference( linenoA, linenoB );
 
379
                        // Dont add this diff with addDiff to the model... no unchanged differences allowed in there...
 
380
                        diff->setType( Difference::Unchanged );
 
381
                        hunk->add( diff );
 
382
                        while( ( oldIt != oldLines.end() && m_contextHunkBodyContext.exactMatch( *oldIt ) ) &&
 
383
                               ( newIt != newLines.end() && m_contextHunkBodyContext.exactMatch( *newIt ) ) )
 
384
                        {
 
385
                                QString l;
 
386
                                if( oldIt != oldLines.end() )
 
387
                                {
 
388
                                        l = m_contextHunkBodyContext.cap( 1 );
 
389
                                        kdDebug(8101) << "old: " << l << endl;
 
390
                                        ++oldIt;
 
391
                                }
 
392
                                if( newIt != newLines.end() )
 
393
                                {
 
394
                                        l = m_contextHunkBodyContext.cap( 1 );
 
395
                                        kdDebug(8101) << "new: " << l << endl;
 
396
                                        ++newIt;
 
397
                                }
 
398
                                diff->addSourceLine( l );
 
399
                                diff->addDestinationLine( l );
 
400
                                linenoA++;
 
401
                                linenoB++;
 
402
                        }
 
403
                }
 
404
 
 
405
                else if( ( oldIt != oldLines.end() && m_contextHunkBodyChanged.exactMatch( *oldIt ) ) ||
 
406
                         ( newIt != newLines.end() && m_contextHunkBodyChanged.exactMatch( *newIt ) ) )
 
407
                {
 
408
                        kdDebug(8101) << "Changed: " << endl;
 
409
                        diff = new Difference( linenoA, linenoB );
 
410
                        diff->setType( Difference::Change );
 
411
                        diff->setIndex( m_diffIndex++ );
 
412
                        m_currentModel->addDiff( diff );
 
413
                        kdDebug(8101) << "Difference added" << endl;
 
414
                        hunk->add( diff );
 
415
                        while( oldIt != oldLines.end() && m_contextHunkBodyChanged.exactMatch( *oldIt ) )
 
416
                        {
 
417
                                kdDebug(8101) << " " << m_contextHunkBodyChanged.cap( 1 ) << endl;
 
418
                                diff->addSourceLine( m_contextHunkBodyChanged.cap( 1 ) );
 
419
                                linenoA++;
 
420
                                ++oldIt;
 
421
                        }
 
422
                        while( newIt != newLines.end() && m_contextHunkBodyChanged.exactMatch( *newIt ) )
 
423
                        {
 
424
                                kdDebug(8101) << " " << m_contextHunkBodyChanged.cap( 1 ) << endl;
 
425
                                diff->addDestinationLine( m_contextHunkBodyChanged.cap( 1 ) );
 
426
                                linenoB++;
 
427
                                ++newIt;
 
428
                        }
 
429
                }
 
430
                else
 
431
                        return false;
 
432
        }
 
433
 
 
434
        return true;
 
435
}
 
436
 
 
437
bool ParserBase::parseEdHunkBody()
 
438
{
 
439
        return false;
 
440
}
 
441
 
 
442
bool ParserBase::parseNormalHunkBody()
 
443
{
 
444
//      kdDebug(8101) << "ParserBase::parseNormalHunkBody" << endl;
 
445
 
 
446
        QString type = QString::null;
 
447
 
 
448
        int linenoA = 0, linenoB = 0;
 
449
 
 
450
        if ( m_normalDiffType == Difference::Insert )
 
451
        {
 
452
                linenoA = m_normalHunkHeaderAdded.cap( 1 ).toInt();
 
453
                linenoB = m_normalHunkHeaderAdded.cap( 2 ).toInt();
 
454
        }
 
455
        else if ( m_normalDiffType == Difference::Delete )
 
456
        {
 
457
                linenoA = m_normalHunkHeaderRemoved.cap( 1 ).toInt();
 
458
                linenoB = m_normalHunkHeaderRemoved.cap( 3 ).toInt();
 
459
        }
 
460
        else if ( m_normalDiffType == Difference::Change )
 
461
        {
 
462
                linenoA = m_normalHunkHeaderChanged.cap( 1 ).toInt();
 
463
                linenoB = m_normalHunkHeaderChanged.cap( 3 ).toInt();
 
464
        }
 
465
 
 
466
        DiffHunk* hunk = new DiffHunk( linenoA, linenoB );
 
467
        m_currentModel->addHunk( hunk );
 
468
        Difference* diff = new Difference( linenoA, linenoB );
 
469
        diff->setIndex( m_diffIndex++ );
 
470
        hunk->add( diff );
 
471
        m_currentModel->addDiff( diff );
 
472
 
 
473
        diff->setType( m_normalDiffType );
 
474
 
 
475
        if ( m_normalDiffType == Difference::Change || m_normalDiffType == Difference::Delete )
 
476
                for( ; m_diffIterator != m_diffLines.end() && m_normalHunkBodyRemoved.exactMatch( *m_diffIterator ); ++m_diffIterator )
 
477
                {
 
478
//                      kdDebug(8101) << "Line = " << *m_diffIterator << endl;
 
479
                        diff->addSourceLine( m_normalHunkBodyRemoved.cap( 1 ) );
 
480
                }
 
481
        if ( m_normalDiffType == Difference::Change )
 
482
                if( m_diffIterator != m_diffLines.end() && m_normalHunkBodyDivider.exactMatch( *m_diffIterator ) )
 
483
                {
 
484
//                      kdDebug(8101) << "Line = " << *m_diffIterator << endl;
 
485
                        ++m_diffIterator;
 
486
                }
 
487
                else
 
488
                        return false;
 
489
        if ( m_normalDiffType == Difference::Insert || m_normalDiffType == Difference::Change )
 
490
                for( ; m_diffIterator != m_diffLines.end() && m_normalHunkBodyAdded.exactMatch( *m_diffIterator ); ++m_diffIterator )
 
491
                {
 
492
//                      kdDebug(8101) << "Line = " << *m_diffIterator << endl;
 
493
                        diff->addDestinationLine( m_normalHunkBodyAdded.cap( 1 ) );
 
494
                }
 
495
 
 
496
        return true;
 
497
}
 
498
 
 
499
bool ParserBase::parseRCSHunkBody()
 
500
{
 
501
        return false;
 
502
}
 
503
 
 
504
bool ParserBase::parseUnifiedHunkBody()
 
505
{
 
506
        kdDebug(8101) << "ParserBase::parseUnifiedHunkBody" << endl;
 
507
 
 
508
        int linenoA = 0, linenoB = 0;
 
509
 
 
510
        // Fetching the stuff we need from the hunkheader regexp that was parsed in parseUnifiedHunkHeader();
 
511
        linenoA = m_unifiedHunkHeader.cap( 1 ).toInt();
 
512
        linenoB = m_unifiedHunkHeader.cap( 4 ).toInt();
 
513
        QString function = m_unifiedHunkHeader.cap( 7 );
 
514
        for ( int i = 0; i < 9; i++ )
 
515
        {
 
516
                kdDebug(8101) << "Capture " << i << ": " << m_unifiedHunkHeader.cap( i ) << endl;
 
517
        }
 
518
 
 
519
        DiffHunk* hunk = new DiffHunk( linenoA, linenoB, function );
 
520
        m_currentModel->addHunk( hunk );
 
521
 
 
522
        while( m_diffIterator != m_diffLines.end() && m_unifiedHunkBodyLine.exactMatch( *m_diffIterator ) )
 
523
        {
 
524
                Difference* diff = new Difference( linenoA, linenoB );
 
525
                diff->setIndex( m_diffIndex++ );
 
526
                hunk->add( diff );
 
527
 
 
528
                if( m_unifiedHunkBodyLine.cap( 1 ) == " " )
 
529
                {       // context
 
530
                        for( ; m_diffIterator != m_diffLines.end() && m_unifiedHunkBodyContext.exactMatch( *m_diffIterator ); ++m_diffIterator ) {
 
531
                                diff->addSourceLine( m_unifiedHunkBodyContext.cap( 1 ) );
 
532
                                diff->addDestinationLine( m_unifiedHunkBodyContext.cap( 1 ) );
 
533
                                linenoA++;
 
534
                                linenoB++;
 
535
                        }
 
536
                }
 
537
                else
 
538
                {       // This is a real difference, not context
 
539
                        for( ; m_diffIterator != m_diffLines.end() && m_unifiedHunkBodyRemoved.exactMatch( *m_diffIterator ); ++m_diffIterator ) {
 
540
                                diff->addSourceLine( m_unifiedHunkBodyRemoved.cap( 1 ) );
 
541
                                linenoA++;
 
542
                        }
 
543
                        if ( (*m_diffIterator).startsWith( "\\ " ) )
 
544
                                ++m_diffIterator;
 
545
                        for( ; m_diffIterator != m_diffLines.end() && m_unifiedHunkBodyAdded.exactMatch( *m_diffIterator ); ++m_diffIterator ) {
 
546
                                diff->addDestinationLine( m_unifiedHunkBodyAdded.cap( 1 ) );
 
547
                                linenoB++;
 
548
                        }
 
549
                        if ( (*m_diffIterator).startsWith( "\\ " ) )
 
550
                                ++m_diffIterator;
 
551
                        if ( diff->sourceLineCount() == 0 )
 
552
                        {
 
553
                                diff->setType( Difference::Insert );
 
554
                                kdDebug(8101) << "Insert difference" << endl;
 
555
                        }
 
556
                        else if ( diff->destinationLineCount() == 0 )
 
557
                        {
 
558
                                diff->setType( Difference::Delete );
 
559
                                kdDebug(8101) << "Delete difference" << endl;
 
560
                        }
 
561
                        else
 
562
                        {
 
563
                                diff->setType( Difference::Change );
 
564
                                kdDebug(8101) << "Change difference" << endl;
 
565
                        }
 
566
                        // Dont move this up, leave it somewhere in this else part. We dont want to
 
567
                        // add context differences to the differences list...
 
568
                        m_currentModel->addDiff( diff );
 
569
                }
 
570
        }
 
571
 
 
572
        return true;
 
573
}
 
574
 
 
575
QPtrList<DiffModel>* ParserBase::parseContext()
 
576
{
 
577
        while ( parseContextDiffHeader() )
 
578
        {
 
579
                while ( parseContextHunkHeader() )
 
580
                        parseContextHunkBody();
 
581
                if ( m_currentModel->differenceCount() > 0 )
 
582
                        m_models->append( m_currentModel );
 
583
        }
 
584
 
 
585
        if ( m_models->count() > 0 )
 
586
        {
 
587
                return m_models;
 
588
        }
 
589
        else
 
590
        {
 
591
                delete m_models;
 
592
                return 0L;
 
593
        }
 
594
}
 
595
 
 
596
QPtrList<DiffModel>* ParserBase::parseEd()
 
597
{
 
598
        while ( parseEdDiffHeader() )
 
599
        {
 
600
                while ( parseEdHunkHeader() )
 
601
                        parseEdHunkBody();
 
602
                m_models->append( m_currentModel );
 
603
        }
 
604
 
 
605
        if ( m_models->count() > 0 )
 
606
        {
 
607
                return m_models;
 
608
        }
 
609
        else
 
610
        {
 
611
                delete m_models;
 
612
                return 0L;
 
613
        }
 
614
}
 
615
 
 
616
QPtrList<DiffModel>* ParserBase::parseNormal()
 
617
{
 
618
        while ( parseNormalDiffHeader() )
 
619
        {
 
620
                while ( parseNormalHunkHeader() )
 
621
                        parseNormalHunkBody();
 
622
                m_models->append( m_currentModel );
 
623
        }
 
624
 
 
625
        if ( m_models->count() > 0 )
 
626
        {
 
627
                return m_models;
 
628
        }
 
629
        else
 
630
        {
 
631
                delete m_models;
 
632
                return 0L;
 
633
        }
 
634
}
 
635
 
 
636
QPtrList<DiffModel>* ParserBase::parseRCS()
 
637
{
 
638
        while ( parseRCSDiffHeader() )
 
639
        {
 
640
                while ( parseRCSHunkHeader() )
 
641
                        parseRCSHunkBody();
 
642
                m_models->append( m_currentModel );
 
643
        }
 
644
 
 
645
        if ( m_models->count() > 0 )
 
646
        {
 
647
                return m_models;
 
648
        }
 
649
        else
 
650
        {
 
651
                delete m_models;
 
652
                return 0L;
 
653
        }
 
654
}
 
655
 
 
656
QPtrList<DiffModel>* ParserBase::parseUnified()
 
657
{
 
658
        while ( parseUnifiedDiffHeader() )
 
659
        {
 
660
                while ( parseUnifiedHunkHeader() )
 
661
                        parseUnifiedHunkBody();
 
662
                m_models->append( m_currentModel );
 
663
        }
 
664
 
 
665
        if ( m_models->count() > 0 )
 
666
        {
 
667
                return m_models;
 
668
        }
 
669
        else
 
670
        {
 
671
                delete m_models;
 
672
                return 0L;
 
673
        }
 
674
}