1
# arch-tag: b1ae35f1-d91b-49f0-a1ff-e163ddd8cefd
2
# Copyright (C) 2004 David Allouche <david@allouche.net>
3
# 2005 Canonical Limited.
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.
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.
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
20
Internal module providing name escaping functionality.
22
This module implements some of public interface for the
23
arch_ package. But for convenience reasons the author prefers
24
to store this code in a file separate from ``__init__.py`` .
26
.. _arch: arch-module.html
28
This module is strictly internal and should never be used.
31
__all__ = ['name_escape', 'name_unescape']
34
### Escaping Tables ###
36
__space_escape_table = { '\t': 'tab', '\n': 'nl', '\v': 'U+B',
37
'\f': 'np', '\r': 'cr', ' ': 'sp' }
39
def __make_name_escape_table():
43
if C in __space_escape_table: val = '\\(%s)' % __space_escape_table[C]
44
elif N < 32 or N > 127: val = '\\(U+%X)' % N
45
elif C in '"\\': val = '\\'+C
50
__name_escape_table = __make_name_escape_table()
52
__space_unescape_table = {}
53
for k, v in __space_escape_table.items(): __space_unescape_table[v] = k
56
### Escaping Functions ###
58
def name_escape(name):
59
"""Escape a file name using the Arch syntax.
61
:arg name: unescaped file name.
63
:return: escaped file name.
66
return ''.join([__name_escape_table[C] for C in name])
69
def name_unescape(name):
70
"""Unescape a file name using the Arch syntax.
72
:arg name: escaped file name.
74
:return: unescaped file name.
76
:raise errors.IllegalEscapeSequence: the syntax of ``name`` is incorrect.
79
after_backslash = 'after_backslash'
80
in_brackets = 'in_brackets'
82
escape = None # buffer for escape sequence
89
state = after_backslash
91
elif state is after_backslash:
101
raise errors.IllegalEscapeSequence(name)
102
elif state is in_brackets:
109
raise errors.IllegalEscapeSequence(name)
110
escape_str = ''.join(escape)
112
if escape_str[0:2] in ('U+', 'u+'):
114
code = int(escape_str[2:], 16)
116
raise errors.IllegalEscapeSequence(name)
118
raise errors.IllegalEscapeSequence(name)
119
result.append(chr(code))
122
escape_str = escape_str.lower()
124
result.append(__space_unescape_table[escape_str])
126
raise errors.IllegalEscapeSequence(name)
129
raise AssertionError, "The programmer is on crack!"
130
if state is not None:
131
raise errors.IllegalEscapeSequence(name)
133
return ''.join(result)