99 restricted = 'record qfold qimport qnew qpush qrefresh qrecord' |
99 restricted = 'record qfold qimport qnew qpush qrefresh qrecord' |
100 |
100 |
101 def utcdate(date): |
101 def utcdate(date): |
102 '''Returns hgdate in cvs-like UTC format.''' |
102 '''Returns hgdate in cvs-like UTC format.''' |
103 return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0])) |
103 return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0])) |
104 |
|
105 def textsafe(s): |
|
106 '''Safe version of util.binary with reversed logic. |
|
107 Note: argument may not be None, which is allowed for util.binary.''' |
|
108 return '\0' not in s |
|
109 |
104 |
110 # make keyword tools accessible |
105 # make keyword tools accessible |
111 kwtools = {'templater': None, 'hgcmd': '', 'inc': [], 'exc': ['.hg*']} |
106 kwtools = {'templater': None, 'hgcmd': '', 'inc': [], 'exc': ['.hg*']} |
112 |
107 |
113 |
108 |
163 return '$%s: %s $' % (kw, ekw) |
158 return '$%s: %s $' % (kw, ekw) |
164 return subfunc(kwsub, data) |
159 return subfunc(kwsub, data) |
165 |
160 |
166 def expand(self, path, node, data): |
161 def expand(self, path, node, data): |
167 '''Returns data with keywords expanded.''' |
162 '''Returns data with keywords expanded.''' |
168 if not self.restrict and self.matcher(path) and textsafe(data): |
163 if not self.restrict and self.matcher(path) and not util.binary(data): |
169 changenode = self.getnode(path, node) |
164 changenode = self.getnode(path, node) |
170 return self.substitute(data, path, changenode, self.re_kw.sub) |
165 return self.substitute(data, path, changenode, self.re_kw.sub) |
171 return data |
166 return data |
172 |
167 |
173 def iskwfile(self, path, islink): |
168 def iskwfile(self, path, islink): |
191 candidates.sort() |
186 candidates.sort() |
192 action = expand and 'expanding' or 'shrinking' |
187 action = expand and 'expanding' or 'shrinking' |
193 for f in candidates: |
188 for f in candidates: |
194 fp = self.repo.file(f) |
189 fp = self.repo.file(f) |
195 data = fp.read(mf[f]) |
190 data = fp.read(mf[f]) |
196 if not textsafe(data): |
191 if util.binary(data): |
197 continue |
192 continue |
198 if expand: |
193 if expand: |
199 changenode = node or self.getnode(f, mf[f]) |
194 changenode = node or self.getnode(f, mf[f]) |
200 data, found = self.substitute(data, f, changenode, |
195 data, found = self.substitute(data, f, changenode, |
201 self.re_kw.subn) |
196 self.re_kw.subn) |
211 '''Unconditionally removes all keyword substitutions from text.''' |
206 '''Unconditionally removes all keyword substitutions from text.''' |
212 return self.re_kw.sub(r'$\1$', text) |
207 return self.re_kw.sub(r'$\1$', text) |
213 |
208 |
214 def shrink(self, fname, text): |
209 def shrink(self, fname, text): |
215 '''Returns text with all keyword substitutions removed.''' |
210 '''Returns text with all keyword substitutions removed.''' |
216 if self.matcher(fname) and textsafe(text): |
211 if self.matcher(fname) and not util.binary(text): |
217 return self.shrinktext(text) |
212 return self.shrinktext(text) |
218 return text |
213 return text |
219 |
214 |
220 def shrinklines(self, fname, lines): |
215 def shrinklines(self, fname, lines): |
221 '''Returns lines with keyword substitutions removed.''' |
216 '''Returns lines with keyword substitutions removed.''' |
222 if self.matcher(fname): |
217 if self.matcher(fname): |
223 text = ''.join(lines) |
218 text = ''.join(lines) |
224 if textsafe(text): |
219 if not util.binary(text): |
225 return self.shrinktext(text).splitlines(True) |
220 return self.shrinktext(text).splitlines(True) |
226 return lines |
221 return lines |
227 |
222 |
228 def wread(self, fname, data): |
223 def wread(self, fname, data): |
229 '''If in restricted mode returns data read from wdir with |
224 '''If in restricted mode returns data read from wdir with |