• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# Copyright 2014 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import re
7
8def quote(input_str, specials, escape='\\'):
9  """Returns a quoted version of |str|, where every character in the
10  iterable |specials| (usually a set or a string) and the escape
11  character |escape| is replaced by the original character preceded by
12  the escape character."""
13
14  assert len(escape) == 1
15
16  # Since escape is used in replacement pattern context, so we need to
17  # ensure that it stays a simple literal and cannot affect the \1
18  # that will follow it.
19  if escape == '\\':
20    escape = '\\\\'
21  if len(specials) > 0:
22    return re.sub(r'(' + r'|'.join(specials)+r'|'+escape + r')',
23                  escape + r'\1', input_str)
24  return re.sub(r'(' + escape + r')', escape + r'\1', input_str)
25
26
27def unquote(input_str, specials, escape='\\'):
28  """Splits the input string |input_str| where special characters in
29  the input |specials| are, if not quoted by |escape|, used as
30  delimiters to split the string.  The returned value is a list of
31  strings of alternating non-specials and specials used to break the
32  string. The list will always begin with a possibly empty string of
33  non-specials, but may end with either specials or non-specials."""
34
35  assert len(escape) == 1
36
37  out = []
38  cur_out = []
39  cur_special = False
40  lit_next = False
41  for c in input_str:
42    if cur_special:
43      lit_next = (c == escape)
44      if c not in specials or lit_next:
45        cur_special = False
46        out.append(''.join(cur_out))
47        if not lit_next:
48          cur_out = [c]
49        else:
50          cur_out = []
51      else:
52        cur_out.append(c)
53    else:
54      if lit_next:
55        cur_out.append(c)
56        lit_next = False
57      else:
58        lit_next = c == escape
59        if c not in specials:
60          if not lit_next:
61            cur_out.append(c)
62        else:
63          out.append(''.join(cur_out))
64          cur_out = [c]
65          cur_special = True
66  out.append(''.join(cur_out))
67  return out
68