Yaffs site version 1.1
[yaffs-website] / vendor / psy / psysh / test / tools / vis.py
1 """
2 vis.py
3 ======
4
5 Ctypes based module to access libbsd's strvis & strunvis functions.
6
7 The `vis` function is the equivalent of strvis.
8 The `unvis` function is the equivalent of strunvis.
9 All functions accept unicode string as input and return a unicode string.
10
11 Constants:
12 ----------
13
14 * to select alternate encoding format
15   `VIS_OCTAL`:      use octal \ddd format
16   `VIS_CSTYLE`:     use \[nrft0..] where appropiate
17
18 * to alter set of characters encoded
19   (default is to encode all non-graphic except space, tab, and newline).
20   `VIS_SP`:         also encode space
21   `VIS_TAB`:        also encode tab
22   `VIS_NL`:         also encode newline
23   `VIS_WHITE`:      same as (VIS_SP | VIS_TAB | VIS_NL)
24   `VIS_SAFE`:       only encode "unsafe" characters
25
26 * other
27   `VIS_NOSLASH`:    inhibit printing '\'
28   `VIS_HTTP1808`:   http-style escape % hex hex
29   `VIS_HTTPSTYLE`:  http-style escape % hex hex
30   `VIS_MIMESTYLE`:  mime-style escape = HEX HEX
31   `VIS_HTTP1866`:   http-style &#num; or &string;
32   `VIS_NOESCAPE`:   don't decode `\'
33   `VIS_GLOB`:       encode glob(3) magic characters
34
35 :Authors:
36     - ju1ius (http://github.com/ju1ius)
37 :Version: 1
38 :Date: 2014-01-05
39 """
40 from ctypes import CDLL, c_char_p, c_int
41 from ctypes.util import find_library
42
43
44 __all__ = [
45     'vis', 'unvis',
46     'VIS_OCTAL', 'VIS_CSTYLE',
47     'VIS_SP', 'VIS_TAB', 'VIS_NL', 'VIS_WHITE', 'VIS_SAFE',
48     'VIS_NOSLASH', 'VIS_HTTP1808', 'VIS_HTTPSTYLE', 'VIS_MIMESTYLE',
49     'VIS_HTTP1866', 'VIS_NOESCAPE', 'VIS_GLOB'
50 ]
51
52
53 #############################################################
54 # Constants from bsd/vis.h
55 #############################################################
56
57 #to select alternate encoding format
58 VIS_OCTAL = 0x0001
59 VIS_CSTYLE = 0x0002
60 # to alter set of characters encoded
61 # (default is to encode all non-graphic except space, tab, and newline).
62 VIS_SP = 0x0004
63 VIS_TAB = 0x0008
64 VIS_NL = 0x0010
65 VIS_WHITE = VIS_SP | VIS_TAB | VIS_NL
66 VIS_SAFE = 0x0020
67 # other
68 VIS_NOSLASH = 0x0040
69 VIS_HTTP1808 = 0x0080
70 VIS_HTTPSTYLE = 0x0080
71 VIS_MIMESTYLE = 0x0100
72 VIS_HTTP1866 = 0x0200
73 VIS_NOESCAPE = 0x0400
74 VIS_GLOB = 0x1000
75
76 #############################################################
77 # Import libbsd/vis functions
78 #############################################################
79
80 _libbsd = CDLL(find_library('bsd'))
81
82 _strvis = _libbsd.strvis
83 _strvis.argtypes = [c_char_p, c_char_p, c_int]
84 _strvis.restype = c_int
85
86 _strunvis = _libbsd.strunvis
87 _strvis.argtypes = [c_char_p, c_char_p]
88 _strvis.restype = c_int
89
90
91 def vis(src, flags=VIS_WHITE):
92     """
93     Encodes the string `src` into libbsd's vis encoding.
94     `flags` must be one of the VIS_* constants
95
96     C definition:
97     int strvis(char *dst, char *src, int flags);
98     """
99     src = bytes(src, 'utf-8')
100     dst_p = c_char_p(bytes(len(src) * 4))
101     src_p = c_char_p(src)
102     flags = c_int(flags)
103
104     bytes_written = _strvis(dst_p, src_p, flags)
105     if -1 == bytes_written:
106         raise RuntimeError('vis failed to encode string "{}"'.format(src))
107
108     return dst_p.value.decode('utf-8')
109
110
111 def unvis(src):
112     """
113     Decodes a string encoded by vis.
114
115     C definition:
116     int strunvis(char *dst, char *src);
117     """
118     src = bytes(src, 'utf-8')
119     dst_p = c_char_p(bytes(len(src)))
120     src_p = c_char_p(src)
121
122     bytes_written = _strunvis(dst_p, src_p)
123     if -1 == bytes_written:
124         raise RuntimeError('unvis failed to decode string "{}"'.format(src))
125
126     return dst_p.value.decode('utf-8')