1 # Copyright (C) 1998 Richard Braakman
3 # This program is free software. It is distributed under the terms of
4 # the GNU General Public License as published by the Free Software
5 # Foundation; either version 2 of the License, or (at your option) any
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, you can find it on the World Wide
15 # Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
16 # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
25 bad_field = 'Bad field value'
27 defaults = {'depends': [], 'recommends': [], 'suggests': [], 'pre-depends': [],
28 'conflicts': [], 'replaces': [], 'provides': [],
29 'essential': 0, 'distribution': 'main', 'architecture': 'all',
30 'description': '', 'synopsis': ''}
32 relationships = ['depends', 'recommends', 'suggests', 'pre-depends',
33 'conflicts', 'replaces']
35 # The Package class models a read-only dictionary that is initialized
36 # by feeding it a paragraph of control information.
37 # Some translation is done on the field names:
39 # 'source' -> 'sourcepackage' and 'sourceversion'
40 # 'description' -> 'synopsis' and 'description'
41 # 'section' -> 'distribution' and 'section'
47 return len(self.fields)
49 # Look up a field in this package.
50 def __getitem__(self, key):
51 if self.fields.has_key(key):
52 return self.fields[key]
53 # If it is not defined, return the default value for that field.
54 if defaults.has_key(key):
57 if key == 'sourcepackage':
59 if key == 'sourceversion':
60 return self['version']
61 # If there is no default, try again with a lowercase version
63 lcase = string.lower(key)
68 # Define some standard dictionary methods
69 def keys(self): return self.fields.keys()
70 def items(self): return self.fields.items()
71 def values(self): return self.fields.values()
72 def has_key(self, key): return self.fields.has_key(key)
74 def parsefield(self, field, fieldval):
75 # Perform translations on field and fieldval
76 if field == 'package':
78 elif field == 'version':
79 fieldval = version.make(fieldval)
80 elif field == 'architecture':
81 fieldval = string.split(fieldval)
82 if len(fieldval) == 1:
83 fieldval = fieldval[0]
84 elif field == 'source':
85 field = 'sourcepackage'
86 splitsource = string.split(fieldval)
87 if (len(splitsource) > 1):
88 if splitsource[1][0] != '(' \
89 or splitsource[1][-1] != ')':
90 raise ValueError, fieldval
91 fieldval = splitsource[0]
92 self.fields['sourceversion'] = version.make(splitsource[1][1:-1])
93 elif field in relationships:
94 fieldval = map(relation.parse, string.split(fieldval, ','))
95 elif field == 'provides':
96 # I will assume that the alternates construct is
97 # not allowed in the Provides: header.
98 fieldval = string.split(fieldval, ', ')
99 elif field == 'description':
100 i = string.find(fieldval, '\n')
102 self.fields['description'] = fieldval[i+1:]
103 fieldval = string.strip(fieldval[:i])
104 elif field == 'essential':
105 if fieldval == 'yes':
107 elif fieldval != 'no':
108 raise ValueError, fieldval
111 elif field == 'section':
112 i = string.find(fieldval, '/')
114 self.fields['distribution'] = fieldval[:i]
115 fieldval = fieldval[i+1:]
116 elif field == 'installed-size':
117 fieldval = string.atoi(fieldval)
118 elif field == 'size':
119 fieldval = string.atoi(fieldval)
121 self.fields[field] = fieldval
123 # This function accepts a list of "field: value" strings,
124 # with continuation lines already folded into the values.
125 # "filter" is an array of header fields (lowercase) to parse.
126 # If it is None, parse all fields.
127 def parseparagraph(self, lines, filter=None):
129 idx = string.find(line, ':')
131 raise bad_field, line
132 field = string.lower(line[:idx])
133 if not filter or field in filter:
135 self.parsefield(field, string.strip(line[idx+1:]))
137 raise bad_field, line
139 def parsepackages(infile, filter=None):
143 line = infile.readline()
146 elif line[0] == ' ' or line[0] == '\t':
147 paragraph[-1] = paragraph[-1] + line
148 elif line[0] == '\n':
150 pk.parseparagraph(paragraph, filter)
151 packages[pk['name']] = pk
154 paragraph.append(line)