mercurial/utils/stringutil.py
changeset 47189 b0e92313107e
parent 46819 d4ba4d51f85f
child 48479 dcdecec401ca
equal deleted inserted replaced
47188:353718f741a8 47189:b0e92313107e
   866     If s is not a valid boolean, returns None.
   866     If s is not a valid boolean, returns None.
   867     """
   867     """
   868     return _booleans.get(s.lower(), None)
   868     return _booleans.get(s.lower(), None)
   869 
   869 
   870 
   870 
       
   871 def parselist(value):
       
   872     """parse a configuration value as a list of comma/space separated strings
       
   873 
       
   874     >>> parselist(b'this,is "a small" ,test')
       
   875     ['this', 'is', 'a small', 'test']
       
   876     """
       
   877 
       
   878     def _parse_plain(parts, s, offset):
       
   879         whitespace = False
       
   880         while offset < len(s) and (
       
   881             s[offset : offset + 1].isspace() or s[offset : offset + 1] == b','
       
   882         ):
       
   883             whitespace = True
       
   884             offset += 1
       
   885         if offset >= len(s):
       
   886             return None, parts, offset
       
   887         if whitespace:
       
   888             parts.append(b'')
       
   889         if s[offset : offset + 1] == b'"' and not parts[-1]:
       
   890             return _parse_quote, parts, offset + 1
       
   891         elif s[offset : offset + 1] == b'"' and parts[-1][-1:] == b'\\':
       
   892             parts[-1] = parts[-1][:-1] + s[offset : offset + 1]
       
   893             return _parse_plain, parts, offset + 1
       
   894         parts[-1] += s[offset : offset + 1]
       
   895         return _parse_plain, parts, offset + 1
       
   896 
       
   897     def _parse_quote(parts, s, offset):
       
   898         if offset < len(s) and s[offset : offset + 1] == b'"':  # ""
       
   899             parts.append(b'')
       
   900             offset += 1
       
   901             while offset < len(s) and (
       
   902                 s[offset : offset + 1].isspace()
       
   903                 or s[offset : offset + 1] == b','
       
   904             ):
       
   905                 offset += 1
       
   906             return _parse_plain, parts, offset
       
   907 
       
   908         while offset < len(s) and s[offset : offset + 1] != b'"':
       
   909             if (
       
   910                 s[offset : offset + 1] == b'\\'
       
   911                 and offset + 1 < len(s)
       
   912                 and s[offset + 1 : offset + 2] == b'"'
       
   913             ):
       
   914                 offset += 1
       
   915                 parts[-1] += b'"'
       
   916             else:
       
   917                 parts[-1] += s[offset : offset + 1]
       
   918             offset += 1
       
   919 
       
   920         if offset >= len(s):
       
   921             real_parts = _configlist(parts[-1])
       
   922             if not real_parts:
       
   923                 parts[-1] = b'"'
       
   924             else:
       
   925                 real_parts[0] = b'"' + real_parts[0]
       
   926                 parts = parts[:-1]
       
   927                 parts.extend(real_parts)
       
   928             return None, parts, offset
       
   929 
       
   930         offset += 1
       
   931         while offset < len(s) and s[offset : offset + 1] in [b' ', b',']:
       
   932             offset += 1
       
   933 
       
   934         if offset < len(s):
       
   935             if offset + 1 == len(s) and s[offset : offset + 1] == b'"':
       
   936                 parts[-1] += b'"'
       
   937                 offset += 1
       
   938             else:
       
   939                 parts.append(b'')
       
   940         else:
       
   941             return None, parts, offset
       
   942 
       
   943         return _parse_plain, parts, offset
       
   944 
       
   945     def _configlist(s):
       
   946         s = s.rstrip(b' ,')
       
   947         if not s:
       
   948             return []
       
   949         parser, parts, offset = _parse_plain, [b''], 0
       
   950         while parser:
       
   951             parser, parts, offset = parser(parts, s, offset)
       
   952         return parts
       
   953 
       
   954     if value is not None and isinstance(value, bytes):
       
   955         result = _configlist(value.lstrip(b' ,\n'))
       
   956     else:
       
   957         result = value
       
   958     return result or []
       
   959 
       
   960 
   871 def evalpythonliteral(s):
   961 def evalpythonliteral(s):
   872     """Evaluate a string containing a Python literal expression"""
   962     """Evaluate a string containing a Python literal expression"""
   873     # We could backport our tokenizer hack to rewrite '' to u'' if we want
   963     # We could backport our tokenizer hack to rewrite '' to u'' if we want
   874     if pycompat.ispy3:
   964     if pycompat.ispy3:
   875         return ast.literal_eval(s.decode('latin1'))
   965         return ast.literal_eval(s.decode('latin1'))