~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to weavefile.py

  • Committer: Martin Pool
  • Date: 2005-05-16 02:19:13 UTC
  • Revision ID: mbp@sourcefrog.net-20050516021913-3a933f871079e3fe
- patch from ddaa to create api/ directory 
  before building API docs

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#! /usr/bin/python
2
 
 
3
 
# Copyright (C) 2005 Canonical Ltd
4
 
 
5
 
# This program is free software; you can redistribute it and/or modify
6
 
# it under the terms of the GNU General Public License as published by
7
 
# the Free Software Foundation; either version 2 of the License, or
8
 
# (at your option) any later version.
9
 
 
10
 
# This program is distributed in the hope that it will be useful,
11
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
# GNU General Public License for more details.
14
 
 
15
 
# You should have received a copy of the GNU General Public License
16
 
# along with this program; if not, write to the Free Software
17
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 
 
19
 
# Author: Martin Pool <mbp@canonical.com>
20
 
 
21
 
 
22
 
 
23
 
 
24
 
"""Store and retrieve weaves in files.
25
 
 
26
 
There is one format marker followed by a blank line, followed by a
27
 
series of version headers, followed by the weave itself.
28
 
 
29
 
Each version marker has 'v' and the version, then 'i' and the included
30
 
previous versions.  The inclusions do not need to list versions
31
 
included by a parent.
32
 
 
33
 
The weave is bracketed by 'w' and 'W' lines, and includes the '{}[]'
34
 
processing instructions.  Lines of text are prefixed by '.' if the
35
 
line contains a newline, or ',' if not.
36
 
"""
37
 
 
38
 
# TODO: When extracting a single version it'd be enough to just pass
39
 
# an iterator returning the weave lines...
40
 
 
41
 
FORMAT_1 = '# bzr weave file v1\n'
42
 
 
43
 
 
44
 
 
45
 
def write_weave(weave, f, format=None):
46
 
    if format == None or format == 1:
47
 
        return write_weave_v1(weave, f)
48
 
    else:
49
 
        raise ValueError("unknown weave format %r" % format)
50
 
 
51
 
 
52
 
def write_weave_v1(weave, f):
53
 
    """Write weave to file f."""
54
 
    print >>f, FORMAT_1,
55
 
 
56
 
    for version, included in enumerate(weave._v):
57
 
        print >>f, 'v', version
58
 
        if included:
59
 
            # find a minimal expression of it; bias towards using
60
 
            # later revisions
61
 
            li = list(included)
62
 
            li.sort()
63
 
            li.reverse()
64
 
 
65
 
            mininc = []
66
 
            gotit = set()
67
 
 
68
 
            for pv in li:
69
 
                if pv not in gotit:
70
 
                    mininc.append(pv)
71
 
                    gotit.update(weave._v[pv])
72
 
 
73
 
            assert mininc[0] >= 0
74
 
            assert mininc[-1] < version
75
 
            print >>f, 'i',
76
 
            for i in mininc:
77
 
                print >>f, i,
78
 
            print >>f
79
 
        else:
80
 
            print >>f, 'i'
81
 
        print >>f
82
 
 
83
 
    print >>f, 'w'
84
 
 
85
 
    for l in weave._l:
86
 
        if isinstance(l, tuple):
87
 
            assert l[0] in '{}[]'
88
 
            print >>f, '%s %d' % l
89
 
        else: # text line
90
 
            if not l:
91
 
                print >>f, ', '
92
 
            elif l[-1] == '\n':
93
 
                assert l.find('\n', 0, -1) == -1
94
 
                print >>f, '.', l,
95
 
            else:
96
 
                assert l.find('\n') == -1
97
 
                print >>f, ',', l
98
 
 
99
 
    print >>f, 'W'
100
 
 
101
 
 
102
 
 
103
 
def read_weave(f):
104
 
    return read_weave_v1(f)
105
 
 
106
 
 
107
 
def read_weave_v1(f):
108
 
    from weave import Weave, WeaveFormatError
109
 
    w = Weave()
110
 
 
111
 
    wfe = WeaveFormatError
112
 
    l = f.readline()
113
 
    if l != FORMAT_1:
114
 
        raise WeaveFormatError('invalid weave file header: %r' % l)
115
 
 
116
 
    v_cnt = 0
117
 
    while True:
118
 
        l = f.readline()
119
 
        if l.startswith('v '):
120
 
            ver = int(l[2:])
121
 
            if ver != v_cnt:
122
 
                raise WeaveFormatError('version %d!=%d out of order'
123
 
                                       % (ver, v_cnt))
124
 
            v_cnt += 1
125
 
            
126
 
            l = f.readline()[:-1]
127
 
            if l[0] != 'i':
128
 
                raise WeaveFormatError('unexpected line %r' % l)
129
 
            if len(l) > 2:
130
 
                included = map(int, l[2:].split(' '))
131
 
                full = set()
132
 
                for pv in included:
133
 
                    full.add(pv)
134
 
                    full.update(w._v[pv])
135
 
                w._addversion(full)
136
 
            else:
137
 
                w._addversion(None)
138
 
            assert f.readline() == '\n'
139
 
        elif l == 'w\n':
140
 
            break
141
 
        else:
142
 
            raise WeaveFormatError('unexpected line %r' % l)
143
 
 
144
 
    while True:
145
 
        l = f.readline()
146
 
        if l == 'W\n':
147
 
            break
148
 
        elif l.startswith('. '):
149
 
            w._l.append(l[2:])           # include newline
150
 
        elif l.startswith(', '):
151
 
            w._l.append(l[2:-1])        # exclude newline
152
 
        else:
153
 
            assert l[0] in '{}[]', l
154
 
            assert l[1] == ' ', l
155
 
            w._l.append((l[0], int(l[2:])))
156
 
 
157
 
    return w
158