compat_env.lua

Mon, 06 Jul 2020 10:56:23 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Mon, 06 Jul 2020 10:56:23 -0500
changeset 21
3c71c525cec2
parent 5
7667b101cb1e
permissions
-rw-r--r--

Use markdown-it as default markdown parser.

5
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1 --[[
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
2 compat_env - see README for details.
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
3 (c) 2012 David Manura. Licensed under Lua 5.1/5.2 terms (MIT license).
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
4 --]]
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
5
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
6 local M = {_TYPE='module', _NAME='compat_env', _VERSION='0.2.2.20120406'}
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
7
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
8 local function check_chunk_type(s, mode)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
9 local nmode = mode or 'bt'
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
10 local is_binary = s and #s > 0 and s:byte(1) == 27
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
11 if is_binary and not nmode:match'b' then
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
12 return nil, ("attempt to load a binary chunk (mode is '%s')"):format(mode)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
13 elseif not is_binary and not nmode:match't' then
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
14 return nil, ("attempt to load a text chunk (mode is '%s')"):format(mode)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
15 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
16 return true
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
17 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
18
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
19 local IS_52_LOAD = pcall(load, '')
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
20 if IS_52_LOAD then
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
21 M.load = _G.load
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
22 M.loadfile = _G.loadfile
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
23 else
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
24 -- 5.2 style `load` implemented in 5.1
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
25 function M.load(ld, source, mode, env)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
26 local f
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
27 if type(ld) == 'string' then
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
28 local s = ld
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
29 local ok, err = check_chunk_type(s, mode)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
30 if not ok then return ok, err end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
31 local err; f, err = loadstring(s, source)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
32 if not f then return f, err end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
33 elseif type(ld) == 'function' then
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
34 local ld2 = ld
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
35 if (mode or 'bt') ~= 'bt' then
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
36 local first = ld()
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
37 local ok, err = check_chunk_type(first, mode)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
38 if not ok then return ok, err end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
39 ld2 = function()
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
40 if first then
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
41 local chunk=first; first=nil; return chunk
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
42 else return ld() end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
43 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
44 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
45 local err; f, err = load(ld2, source); if not f then return f, err end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
46 else
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
47 error(("bad argument #1 to 'load' (function expected, got %s)")
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
48 :format(type(ld)), 2)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
49 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
50 if env then setfenv(f, env) end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
51 return f
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
52 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
53
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
54 -- 5.2 style `loadfile` implemented in 5.1
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
55 function M.loadfile(filename, mode, env)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
56 if (mode or 'bt') ~= 'bt' then
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
57 local ioerr
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
58 local fh, err = io.open(filename, 'rb'); if not fh then return fh,err end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
59 local function ld()
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
60 local chunk; chunk,ioerr = fh:read(4096); return chunk
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
61 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
62 local f, err = M.load(ld, filename and '@'..filename, mode, env)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
63 fh:close()
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
64 if not f then return f, err end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
65 if ioerr then return nil, ioerr end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
66 return f
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
67 else
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
68 local f, err = loadfile(filename); if not f then return f, err end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
69 if env then setfenv(f, env) end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
70 return f
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
71 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
72 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
73 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
74
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
75 if _G.setfenv then -- Lua 5.1
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
76 M.setfenv = _G.setfenv
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
77 M.getfenv = _G.getfenv
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
78 else -- >= Lua 5.2
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
79 -- helper function for `getfenv`/`setfenv`
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
80 local function envlookup(f)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
81 local name, val
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
82 local up = 0
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
83 local unknown
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
84 repeat
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
85 up=up+1; name, val = debug.getupvalue(f, up)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
86 if name == '' then unknown = true end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
87 until name == '_ENV' or name == nil
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
88 if name ~= '_ENV' then
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
89 up = nil
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
90 if unknown then
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
91 error("upvalues not readable in Lua 5.2 when debug info missing", 3)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
92 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
93 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
94 return (name == '_ENV') and up, val, unknown
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
95 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
96
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
97 -- helper function for `getfenv`/`setfenv`
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
98 local function envhelper(f, name)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
99 if type(f) == 'number' then
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
100 if f < 0 then
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
101 error(("bad argument #1 to '%s' (level must be non-negative)")
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
102 :format(name), 3)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
103 elseif f < 1 then
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
104 error("thread environments unsupported in Lua 5.2", 3) --[*]
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
105 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
106 f = debug.getinfo(f+2, 'f').func
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
107 elseif type(f) ~= 'function' then
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
108 error(("bad argument #1 to '%s' (number expected, got %s)")
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
109 :format(type(name, f)), 2)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
110 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
111 return f
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
112 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
113 -- [*] might simulate with table keyed by coroutine.running()
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
114
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
115 -- 5.1 style `setfenv` implemented in 5.2
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
116 function M.setfenv(f, t)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
117 local f = envhelper(f, 'setfenv')
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
118 local up, val, unknown = envlookup(f)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
119 if up then
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
120 debug.upvaluejoin(f, up, function() return up end, 1) --unique upval[*]
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
121 debug.setupvalue(f, up, t)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
122 else
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
123 local what = debug.getinfo(f, 'S').what
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
124 if what ~= 'Lua' and what ~= 'main' then -- not Lua func
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
125 error("'setfenv' cannot change environment of given object", 2)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
126 end -- else ignore no _ENV upvalue (warning: incompatible with 5.1)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
127 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
128 return f -- invariant: original f ~= 0
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
129 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
130 -- [*] http://lua-users.org/lists/lua-l/2010-06/msg00313.html
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
131
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
132 -- 5.1 style `getfenv` implemented in 5.2
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
133 function M.getfenv(f)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
134 if f == 0 or f == nil then return _G end -- simulated behavior
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
135 local f = envhelper(f, 'setfenv')
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
136 local up, val = envlookup(f)
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
137 if not up then return _G end -- simulated behavior [**]
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
138 return val
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
139 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
140 -- [**] possible reasons: no _ENV upvalue, C function
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
141 end
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
142
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
143
7667b101cb1e Lua 5.2 compatibility hack
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
144 return M

mercurial