~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/weave.py

  • Committer: Martin Pool
  • Date: 2005-07-11 03:16:29 UTC
  • Revision ID: mbp@sourcefrog.net-20050711031629-924ff7343d55103c
- faster weave extraction

Show diffs side-by-side

added added

removed removed

Lines of Context:
298
298
 
299
299
        The set typically but not necessarily corresponds to a version.
300
300
        """
301
 
        istack = []          # versions for which an insertion block is current
302
 
 
303
 
        dset = set()         # versions for which a deletion block is current
304
 
 
305
 
        isactive = None
 
301
 
 
302
        istack = []
 
303
        dset = set()
306
304
 
307
305
        lineno = 0         # line of weave, 0-based
308
 
 
309
 
        # TODO: Probably only need to put included revisions in the istack
310
 
 
311
 
        # TODO: Could split this into two functions, one that updates
312
 
        # the stack and the other that processes the results -- but
313
 
        # I'm not sure it's really needed.
314
 
 
315
 
        # TODO: In fact, I think we only need to store the *count* of
316
 
        # active insertions and deletions, and we can maintain that by
317
 
        # just by just counting as we go along.
 
306
        isactive = False
318
307
 
319
308
        WFE = WeaveFormatError
320
309
 
321
310
        for l in self._l:
322
311
            if isinstance(l, tuple):
323
 
                isactive = None         # recalculate
324
312
                c, v = l
325
 
                if c == '{':
326
 
                    if istack and (istack[-1] >= v):
327
 
                        raise WFE("improperly nested insertions %d>=%d on line %d" 
328
 
                                  % (istack[-1], v, lineno))
329
 
                    istack.append(v)
330
 
                elif c == '}':
331
 
                    try:
 
313
                if v in included:       # only active blocks are interesting
 
314
                    if c == '{':
 
315
                        assert v not in istack
 
316
                        istack.append(v)
 
317
                        isactive = not dset
 
318
                    elif c == '}':
332
319
                        oldv = istack.pop()
333
 
                    except IndexError:
334
 
                        raise WFE("unmatched close of insertion %d on line %d"
335
 
                                  % (v, lineno))
336
 
                    if oldv != v:
337
 
                        raise WFE("mismatched close of insertion %d!=%d on line %d"
338
 
                                  % (oldv, v, lineno))
339
 
                elif c == '[':
340
 
                    # block deleted in v
341
 
                    if v in dset:
342
 
                        raise WFE("repeated deletion marker for version %d on line %d"
343
 
                                  % (v, lineno))
344
 
                    if istack:
345
 
                        if istack[-1] == v:
346
 
                            raise WFE("version %d deletes own text on line %d"
347
 
                                      % (v, lineno))
348
 
                        # XXX
 
320
                        assert oldv == v
 
321
                        isactive = istack and not dset
 
322
                    elif c == '[':
 
323
                        assert v not in dset
349
324
                        dset.add(v)
350
 
                elif c == ']':
351
 
                    if v in dset:
 
325
                        isactive = False
 
326
                    else:
 
327
                        assert c == ']'
 
328
                        assert v in dset
352
329
                        dset.remove(v)
353
 
                    else:
354
 
                        raise WFE("unmatched close of deletion %d on line %d"
355
 
                                  % (v, lineno))
356
 
                else:
357
 
                    raise WFE("invalid processing instruction %r on line %d"
358
 
                              % (l, lineno))
 
330
                        isactive = istack and not dset
359
331
            else:
360
332
                assert isinstance(l, basestring)
361
 
                if not istack:
362
 
                    raise WFE("literal at top level on line %d"
363
 
                              % lineno)
364
 
                if isactive == None:
365
 
                    isactive = (istack[-1] in included) \
366
 
                               and not included.intersection(dset)
367
333
                if isactive:
368
 
                    origin = istack[-1]
369
334
                    yield origin, lineno, l
370
335
            lineno += 1
371
336
 
433
398
                                 "got %s, expected %s"
434
399
                                 % (version, hd, expected))
435
400
 
 
401
        # TODO: check insertions are properly nested, that there are
 
402
        # no lines outside of insertion blocks, that deletions are
 
403
        # properly paired, etc.
 
404
 
436
405
 
437
406
 
438
407
    def merge(self, merge_versions):