mercurial/match.py
changeset 25213 08a8e9da0ae7
parent 25195 472a685a4961
child 25214 08703b10c3ae
equal deleted inserted replaced
25212:a39c35e8e559 25213:08a8e9da0ae7
    24 def _expandsets(kindpats, ctx, listsubrepos):
    24 def _expandsets(kindpats, ctx, listsubrepos):
    25     '''Returns the kindpats list with the 'set' patterns expanded.'''
    25     '''Returns the kindpats list with the 'set' patterns expanded.'''
    26     fset = set()
    26     fset = set()
    27     other = []
    27     other = []
    28 
    28 
    29     for kind, pat in kindpats:
    29     for kind, pat, source in kindpats:
    30         if kind == 'set':
    30         if kind == 'set':
    31             if not ctx:
    31             if not ctx:
    32                 raise util.Abort("fileset expression with no context")
    32                 raise util.Abort("fileset expression with no context")
    33             s = ctx.getfileset(pat)
    33             s = ctx.getfileset(pat)
    34             fset.update(s)
    34             fset.update(s)
    37                 for subpath in ctx.substate:
    37                 for subpath in ctx.substate:
    38                     s = ctx.sub(subpath).getfileset(pat)
    38                     s = ctx.sub(subpath).getfileset(pat)
    39                     fset.update(subpath + '/' + f for f in s)
    39                     fset.update(subpath + '/' + f for f in s)
    40 
    40 
    41             continue
    41             continue
    42         other.append((kind, pat))
    42         other.append((kind, pat, source))
    43     return fset, other
    43     return fset, other
    44 
    44 
    45 def _kindpatsalwaysmatch(kindpats):
    45 def _kindpatsalwaysmatch(kindpats):
    46     """"Checks whether the kindspats match everything, as e.g.
    46     """"Checks whether the kindspats match everything, as e.g.
    47     'relpath:.' does.
    47     'relpath:.' does.
    48     """
    48     """
    49     for kind, pat in kindpats:
    49     for kind, pat, source in kindpats:
    50         if pat != '' or kind not in ['relpath', 'glob']:
    50         if pat != '' or kind not in ['relpath', 'glob']:
    51             return False
    51             return False
    52     return True
    52     return True
    53 
    53 
    54 class match(object):
    54 class match(object):
   220                     else:
   220                     else:
   221                         files = files.splitlines()
   221                         files = files.splitlines()
   222                     files = [f for f in files if f]
   222                     files = [f for f in files if f]
   223                 except EnvironmentError:
   223                 except EnvironmentError:
   224                     raise util.Abort(_("unable to read file list (%s)") % pat)
   224                     raise util.Abort(_("unable to read file list (%s)") % pat)
   225                 kindpats += self._normalize(files, default, root, cwd, auditor)
   225                 for k, p, source in self._normalize(files, default, root, cwd,
       
   226                                                     auditor):
       
   227                     kindpats.append((k, p, pat))
   226                 continue
   228                 continue
   227             # else: re or relre - which cannot be normalized
   229             # else: re or relre - which cannot be normalized
   228             kindpats.append((kind, pat))
   230             kindpats.append((kind, pat, ''))
   229         return kindpats
   231         return kindpats
   230 
   232 
   231 def exact(root, cwd, files):
   233 def exact(root, cwd, files):
   232     return match(root, cwd, files, exact=True)
   234     return match(root, cwd, files, exact=True)
   233 
   235 
   313 
   315 
   314     def _normalize(self, patterns, default, root, cwd, auditor):
   316     def _normalize(self, patterns, default, root, cwd, auditor):
   315         self._kp = super(icasefsmatcher, self)._normalize(patterns, default,
   317         self._kp = super(icasefsmatcher, self)._normalize(patterns, default,
   316                                                           root, cwd, auditor)
   318                                                           root, cwd, auditor)
   317         kindpats = []
   319         kindpats = []
   318         for kind, pats in self._kp:
   320         for kind, pats, source in self._kp:
   319             if kind not in ('re', 'relre'):  # regex can't be normalized
   321             if kind not in ('re', 'relre'):  # regex can't be normalized
   320                 pats = self._dsnormalize(pats)
   322                 pats = self._dsnormalize(pats)
   321             kindpats.append((kind, pats))
   323             kindpats.append((kind, pats, source))
   322         return kindpats
   324         return kindpats
   323 
   325 
   324 def patkind(pattern, default=None):
   326 def patkind(pattern, default=None):
   325     '''If pattern is 'kind:pat' with a known kind, return kind.'''
   327     '''If pattern is 'kind:pat' with a known kind, return kind.'''
   326     return _patsplit(pattern, default)[0]
   328     return _patsplit(pattern, default)[0]
   447 def _buildregexmatch(kindpats, globsuffix):
   449 def _buildregexmatch(kindpats, globsuffix):
   448     """Build a match function from a list of kinds and kindpats,
   450     """Build a match function from a list of kinds and kindpats,
   449     return regexp string and a matcher function."""
   451     return regexp string and a matcher function."""
   450     try:
   452     try:
   451         regex = '(?:%s)' % '|'.join([_regex(k, p, globsuffix)
   453         regex = '(?:%s)' % '|'.join([_regex(k, p, globsuffix)
   452                                      for (k, p) in kindpats])
   454                                      for (k, p, s) in kindpats])
   453         if len(regex) > 20000:
   455         if len(regex) > 20000:
   454             raise OverflowError
   456             raise OverflowError
   455         return regex, _rematcher(regex)
   457         return regex, _rematcher(regex)
   456     except OverflowError:
   458     except OverflowError:
   457         # We're using a Python with a tiny regex engine and we
   459         # We're using a Python with a tiny regex engine and we
   462             raise
   464             raise
   463         regexa, a = _buildregexmatch(kindpats[:l//2], globsuffix)
   465         regexa, a = _buildregexmatch(kindpats[:l//2], globsuffix)
   464         regexb, b = _buildregexmatch(kindpats[l//2:], globsuffix)
   466         regexb, b = _buildregexmatch(kindpats[l//2:], globsuffix)
   465         return regex, lambda s: a(s) or b(s)
   467         return regex, lambda s: a(s) or b(s)
   466     except re.error:
   468     except re.error:
   467         for k, p in kindpats:
   469         for k, p, s in kindpats:
   468             try:
   470             try:
   469                 _rematcher('(?:%s)' % _regex(k, p, globsuffix))
   471                 _rematcher('(?:%s)' % _regex(k, p, globsuffix))
   470             except re.error:
   472             except re.error:
   471                 raise util.Abort(_("invalid pattern (%s): %s") % (k, p))
   473                 if s:
       
   474                     raise util.Abort(_("%s: invalid pattern (%s): %s") %
       
   475                                      (s, k, p))
       
   476                 else:
       
   477                     raise util.Abort(_("invalid pattern (%s): %s") % (k, p))
   472         raise util.Abort(_("invalid pattern"))
   478         raise util.Abort(_("invalid pattern"))
   473 
   479 
   474 def _roots(kindpats):
   480 def _roots(kindpats):
   475     '''return roots and exact explicitly listed files from patterns
   481     '''return roots and exact explicitly listed files from patterns
   476 
   482 
   477     >>> _roots([('glob', 'g/*'), ('glob', 'g'), ('glob', 'g*')])
   483     >>> _roots([('glob', 'g/*', ''), ('glob', 'g', ''), ('glob', 'g*', '')])
   478     ['g', 'g', '.']
   484     ['g', 'g', '.']
   479     >>> _roots([('relpath', 'r'), ('path', 'p/p'), ('path', '')])
   485     >>> _roots([('relpath', 'r', ''), ('path', 'p/p', ''), ('path', '', '')])
   480     ['r', 'p/p', '.']
   486     ['r', 'p/p', '.']
   481     >>> _roots([('relglob', 'rg*'), ('re', 're/'), ('relre', 'rr')])
   487     >>> _roots([('relglob', 'rg*', ''), ('re', 're/', ''), ('relre', 'rr', '')])
   482     ['.', '.', '.']
   488     ['.', '.', '.']
   483     '''
   489     '''
   484     r = []
   490     r = []
   485     for kind, pat in kindpats:
   491     for kind, pat, source in kindpats:
   486         if kind == 'glob': # find the non-glob prefix
   492         if kind == 'glob': # find the non-glob prefix
   487             root = []
   493             root = []
   488             for p in pat.split('/'):
   494             for p in pat.split('/'):
   489                 if '[' in p or '{' in p or '*' in p or '?' in p:
   495                 if '[' in p or '{' in p or '*' in p or '?' in p:
   490                     break
   496                     break
   495         else: # relglob, re, relre
   501         else: # relglob, re, relre
   496             r.append('.')
   502             r.append('.')
   497     return r
   503     return r
   498 
   504 
   499 def _anypats(kindpats):
   505 def _anypats(kindpats):
   500     for kind, pat in kindpats:
   506     for kind, pat, source in kindpats:
   501         if kind in ('glob', 're', 'relglob', 'relre', 'set'):
   507         if kind in ('glob', 're', 'relglob', 'relre', 'set'):
   502             return True
   508             return True
   503 
   509 
   504 _commentre = None
   510 _commentre = None
   505 
   511