Package pybaz :: Module _escaping
[frames] | no frames]

Source Code for Module pybaz._escaping

  1  # arch-tag: b1ae35f1-d91b-49f0-a1ff-e163ddd8cefd 
  2  # Copyright (C) 2004 David Allouche <david@allouche.net> 
  3  #               2005 Canonical Limited. 
  4  # 
  5  #    This program is free software; you can redistribute it and/or modify 
  6  #    it under the terms of the GNU General Public License as published by 
  7  #    the Free Software Foundation; either version 2 of the License, or 
  8  #    (at your option) any later version. 
  9  # 
 10  #    This program is distributed in the hope that it will be useful, 
 11  #    but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 13  #    GNU General Public License for more details. 
 14  # 
 15  #    You should have received a copy of the GNU General Public License 
 16  #    along with this program; if not, write to the Free Software 
 17  #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 18   
 19  """ 
 20  Internal module providing name escaping functionality. 
 21   
 22  This module implements some of public interface for the 
 23  pybaz_ package. But for convenience reasons the author prefers 
 24  to store this code in a file separate from ``__init__.py``. 
 25   
 26  .. _pybaz: pybaz-module.html 
 27   
 28  This module is strictly internal and should never be used. 
 29  """ 
 30   
 31  __all__ = ['name_escape', 'name_unescape'] 
 32   
 33  import errors 
 34   
 35  ### Escaping Tables ### 
 36   
 37  __space_escape_table = { '\t': 'tab', '\n': 'nl', '\v': 'U+B', 
 38                      '\f': 'np', '\r': 'cr', ' ': 'sp' } 
 39   
40 -def __make_name_escape_table():
41 table = {} 42 for N in range(256): 43 C = chr(N) 44 if C in __space_escape_table: val = '\\(%s)' % __space_escape_table[C] 45 elif N < 32 or N > 127: val = '\\(U+%X)' % N 46 elif C in '\\': val = '\\'+C 47 else: val = C 48 table[C] = val 49 return table
50 51 __name_escape_table = __make_name_escape_table() 52 53 __space_unescape_table = {} 54 for k, v in __space_escape_table.items(): __space_unescape_table[v] = k 55 56 57 ### Escaping Functions ### 58
59 -def name_escape(name):
60 """Escape a file name using the Arch syntax. 61 62 :arg name: unescaped file name. 63 :type name: str 64 :return: escaped file name. 65 :rtype: str 66 """ 67 return ''.join([__name_escape_table[C] for C in name])
68 69
70 -def name_unescape(name):
71 """Unescape a file name using the Arch syntax. 72 73 :arg name: escaped file name. 74 :type name: str 75 :return: unescaped file name. 76 :rtype: str 77 :raise errors.IllegalEscapeSequence: the syntax of ``name`` is incorrect. 78 """ 79 result = [] 80 after_backslash = 'after_backslash' 81 in_brackets = 'in_brackets' 82 state = None 83 escape = None # buffer for escape sequence 84 for C in name: 85 if state is None: 86 if C != '\\': 87 result.append(C) 88 continue 89 else: 90 state = after_backslash 91 continue 92 elif state is after_backslash: 93 if C == '(': 94 escape = [] 95 state = in_brackets 96 continue 97 elif C in '\\"': 98 state = None 99 result.append(C) 100 continue 101 else: 102 raise errors.IllegalEscapeSequence(name) 103 elif state is in_brackets: 104 if C != ')': 105 escape.append(C) 106 continue 107 else: 108 state = None 109 if len(escape) < 2: 110 raise errors.IllegalEscapeSequence(name) 111 escape_str = ''.join(escape) 112 escape = None 113 if escape_str[0:2] in ('U+', 'u+'): 114 try: 115 code = int(escape_str[2:], 16) 116 except ValueError: 117 raise errors.IllegalEscapeSequence(name) 118 if code > 255: 119 raise errors.IllegalEscapeSequence(name) 120 result.append(chr(code)) 121 continue 122 else: 123 escape_str = escape_str.lower() 124 try: 125 result.append(__space_unescape_table[escape_str]) 126 except KeyError: 127 raise errors.IllegalEscapeSequence(name) 128 continue 129 else: 130 raise AssertionError, "The programmer is on crack!" 131 if state is not None: 132 raise errors.IllegalEscapeSequence(name) 133 else: 134 return ''.join(result)
135