12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#!/usr/bin/env python 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)# Copyright 2014 The Chromium Authors. All rights reserved. 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# found in the LICENSE file. 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import re 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def quote(input_str, specials, escape='\\'): 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Returns a quoted version of |str|, where every character in the 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iterable |specials| (usually a set or a string) and the escape 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) character |escape| is replaced by the original character preceded by 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) the escape character.""" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert len(escape) == 1 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Since escape is used in replacement pattern context, so we need to 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # ensure that it stays a simple literal and cannot affect the \1 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # that will follow it. 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if escape == '\\': 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) escape = '\\\\' 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if len(specials) > 0: 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return re.sub(r'(' + r'|'.join(specials)+r'|'+escape + r')', 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) escape + r'\1', input_str) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return re.sub(r'(' + escape + r')', escape + r'\1', input_str) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def unquote(input_str, specials, escape='\\'): 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Splits the input string |input_str| where special characters in 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) the input |specials| are, if not quoted by |escape|, used as 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delimiters to split the string. The returned value is a list of 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) strings of alternating non-specials and specials used to break the 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) string. The list will always begin with a possibly empty string of 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non-specials, but may end with either specials or non-specials.""" 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert len(escape) == 1 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) out = [] 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cur_out = [] 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cur_special = False 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lit_next = False 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for c in input_str: 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if cur_special: 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lit_next = (c == escape) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if c not in specials or lit_next: 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cur_special = False 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) out.append(''.join(cur_out)) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if not lit_next: 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cur_out = [c] 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cur_out = [] 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cur_out.append(c) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if lit_next: 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cur_out.append(c) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lit_next = False 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lit_next = c == escape 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if c not in specials: 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if not lit_next: 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cur_out.append(c) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) out.append(''.join(cur_out)) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cur_out = [c] 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cur_special = True 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) out.append(''.join(cur_out)) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return out 68