##// END OF EJS Templates
ignore: fix up comment parsing...
Matt Mackall -
r5640:04c76f29 default
parent child Browse files
Show More
@@ -1,87 +1,90 b''
1 # ignore.py - ignored file handling for mercurial
1 # ignore.py - ignored file handling for mercurial
2 #
2 #
3 # Copyright 2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 from i18n import _
8 from i18n import _
9 import util
9 import util, re
10
11 _commentre = None
10
12
11 def _parselines(fp):
13 def _parselines(fp):
12 for line in fp:
14 for line in fp:
13 if not line.endswith('\n'):
15 if "#" in line:
14 line += '\n'
16 global _commentre
15 escape = False
17 if not _commentre:
16 for i in xrange(len(line)):
18 _commentre = re.compile(r'((^|[^\\])(\\\\)*)#.*')
17 if escape: escape = False
19 # remove comments prefixed by an even number of escapes
18 elif line[i] == '\\': escape = True
20 line = _commentre.sub(r'\1', line)
19 elif line[i] == '#': break
21 # fixup properly escaped comments that survived the above
20 line = line[:i].rstrip()
22 line = line.replace("\\#", "#")
23 line = line.rstrip()
21 if line:
24 if line:
22 yield line
25 yield line
23
26
24 def ignore(root, files, warn):
27 def ignore(root, files, warn):
25 '''return the contents of .hgignore files as a list of patterns.
28 '''return the contents of .hgignore files as a list of patterns.
26
29
27 the files parsed for patterns include:
30 the files parsed for patterns include:
28 .hgignore in the repository root
31 .hgignore in the repository root
29 any additional files specified in the [ui] section of ~/.hgrc
32 any additional files specified in the [ui] section of ~/.hgrc
30
33
31 trailing white space is dropped.
34 trailing white space is dropped.
32 the escape character is backslash.
35 the escape character is backslash.
33 comments start with #.
36 comments start with #.
34 empty lines are skipped.
37 empty lines are skipped.
35
38
36 lines can be of the following formats:
39 lines can be of the following formats:
37
40
38 syntax: regexp # defaults following lines to non-rooted regexps
41 syntax: regexp # defaults following lines to non-rooted regexps
39 syntax: glob # defaults following lines to non-rooted globs
42 syntax: glob # defaults following lines to non-rooted globs
40 re:pattern # non-rooted regular expression
43 re:pattern # non-rooted regular expression
41 glob:pattern # non-rooted glob
44 glob:pattern # non-rooted glob
42 pattern # pattern of the current default type'''
45 pattern # pattern of the current default type'''
43
46
44 syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:'}
47 syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:'}
45 pats = {}
48 pats = {}
46 for f in files:
49 for f in files:
47 try:
50 try:
48 pats[f] = []
51 pats[f] = []
49 fp = open(f)
52 fp = open(f)
50 syntax = 'relre:'
53 syntax = 'relre:'
51 for line in _parselines(fp):
54 for line in _parselines(fp):
52 if line.startswith('syntax:'):
55 if line.startswith('syntax:'):
53 s = line[7:].strip()
56 s = line[7:].strip()
54 try:
57 try:
55 syntax = syntaxes[s]
58 syntax = syntaxes[s]
56 except KeyError:
59 except KeyError:
57 warn(_("%s: ignoring invalid syntax '%s'\n") % (f, s))
60 warn(_("%s: ignoring invalid syntax '%s'\n") % (f, s))
58 continue
61 continue
59 pat = syntax + line
62 pat = syntax + line
60 for s, rels in syntaxes.items():
63 for s, rels in syntaxes.items():
61 if line.startswith(rels):
64 if line.startswith(rels):
62 pat = line
65 pat = line
63 break
66 break
64 elif line.startswith(s+':'):
67 elif line.startswith(s+':'):
65 pat = rels + line[len(s)+1:]
68 pat = rels + line[len(s)+1:]
66 break
69 break
67 pats[f].append(pat)
70 pats[f].append(pat)
68 except IOError, inst:
71 except IOError, inst:
69 if f != files[0]:
72 if f != files[0]:
70 warn(_("skipping unreadable ignore file '%s': %s\n") %
73 warn(_("skipping unreadable ignore file '%s': %s\n") %
71 (f, inst.strerror))
74 (f, inst.strerror))
72
75
73 allpats = []
76 allpats = []
74 [allpats.extend(patlist) for patlist in pats.values()]
77 [allpats.extend(patlist) for patlist in pats.values()]
75 if not allpats:
78 if not allpats:
76 return util.never
79 return util.never
77
80
78 try:
81 try:
79 files, ignorefunc, anypats = (
82 files, ignorefunc, anypats = (
80 util.matcher(root, inc=allpats, src='.hgignore'))
83 util.matcher(root, inc=allpats, src='.hgignore'))
81 except util.Abort:
84 except util.Abort:
82 # Re-raise an exception where the src is the right file
85 # Re-raise an exception where the src is the right file
83 for f, patlist in pats.items():
86 for f, patlist in pats.items():
84 files, ignorefunc, anypats = (
87 files, ignorefunc, anypats = (
85 util.matcher(root, inc=patlist, src=f))
88 util.matcher(root, inc=patlist, src=f))
86
89
87 return ignorefunc
90 return ignorefunc
General Comments 0
You need to be logged in to leave comments. Login now