diff options
author | William Wilgus <wilgus.william@gmail.com> | 2021-05-03 23:06:40 -0400 |
---|---|---|
committer | William Wilgus <wilgus.william@gmail.com> | 2021-05-03 23:13:25 -0400 |
commit | 9b2f23319c5ac84927774fca02b99bbb98057ebd (patch) | |
tree | 26392ade25f9a251f67bf9a2093a71d0e59e65f9 | |
parent | 489a5f3ff72802fac20ca7459620101cd263bd1a (diff) | |
download | rockbox-9b2f23319c5ac84927774fca02b99bbb98057ebd.tar.gz rockbox-9b2f23319c5ac84927774fca02b99bbb98057ebd.zip |
lua fix yellow and add temploader
temp loader allows some lua requires to be loaded and
later garbage collected unfortunately the module needs to be formatted
in such a way to pass back a call table in order to keep the functions
within from being garbage collected too early
BE AWARE this bypasses the module loader which would allow code reuse
so if you aren't careful this memory saving tool could spell disaster
for free RAM if you load the same code multiple times
Change-Id: I0b6f81e481b8c779edbd620c8403794f8353926f
-rw-r--r-- | apps/plugins/lua/include_lua/create_kbd_layout.lua | 119 | ||||
-rw-r--r-- | apps/plugins/lua/include_lua/temploader.lua | 30 | ||||
-rw-r--r-- | apps/plugins/lua/lua.make | 3 | ||||
-rw-r--r-- | apps/plugins/lua/rocklib.c | 8 |
4 files changed, 102 insertions, 58 deletions
diff --git a/apps/plugins/lua/include_lua/create_kbd_layout.lua b/apps/plugins/lua/include_lua/create_kbd_layout.lua index bb3ab297ca..3d8f343cc9 100644 --- a/apps/plugins/lua/include_lua/create_kbd_layout.lua +++ b/apps/plugins/lua/include_lua/create_kbd_layout.lua | |||
@@ -1,74 +1,82 @@ | |||
1 | --create keyboard layout | 1 | --create keyboard layout |
2 | --BILGUS 4/2021 | 2 | --BILGUS 4/2021 |
3 | local function encode_short(n) | 3 | -- kbdlayout = require("create_kbd_layout") |
4 | return string.char(bit.band(0x00FF, n), bit.rshift(bit.band(0xFF00, n), 8)) | 4 | -- local layout = kbdlayout.create_keyboard_layout("abcd") |
5 | end | 5 | local _kbdlayout = {} do |
6 | 6 | ||
7 | function utf8decode(str) | 7 | local function encode_short(n) |
8 | local INVALID = 0xfffd | 8 | return string.char(bit.band(0x00FF, n), bit.rshift(bit.band(0xFF00, n), 8)) |
9 | local t = {} | 9 | end |
10 | local function check_char(c) | ||
11 | local tail = false | ||
12 | local code | ||
13 | c = string.byte(c) | ||
14 | if (c <= 0x7f) or (c >= 0xc2) then | ||
15 | -- Start of new character | ||
16 | if (c < 0x80) then -- U-00000000 - U-0000007F, 1 string.byte | ||
17 | code = c; | ||
18 | elseif (c < 0xe0) then -- U-00000080 - U-000007FF, 2 string.bytes | ||
19 | tail = 1; | ||
20 | code = bit.band(c, 0x1f) | ||
21 | elseif (c < 0xf0) then -- U-00000800 - U-0000FFFF, 3 string.bytes | ||
22 | tail = 2; | ||
23 | code = bit.band(c, 0x0f) | ||
24 | elseif (c < 0xf5) then -- U-00010000 - U-001FFFFF, 4 string.bytes | ||
25 | tail = 3; | ||
26 | code = bit.band(c, 0x07) | ||
27 | else | ||
28 | -- Invalid size | ||
29 | code = 0xfffd; | ||
30 | end | ||
31 | 10 | ||
32 | while tail and c ~= 0 do | 11 | local function utf8decode(str) |
33 | tail = tail - 1 | 12 | local INVALID = 0xfffd |
34 | if bit.band(c, 0xc0) == 0x80 then | 13 | local t = {} |
35 | -- Valid continuation character | 14 | local function check_char(c) |
36 | code = bit.bor(bit.lshift(code, 6),bit.band(c, 0x3f)) | 15 | local tail = false |
16 | local code | ||
17 | c = string.byte(c) | ||
18 | if (c <= 0x7f) or (c >= 0xc2) then | ||
19 | -- Start of new character | ||
20 | if (c < 0x80) then -- U-00000000 - U-0000007F, 1 string.byte | ||
21 | code = c; | ||
22 | elseif (c < 0xe0) then -- U-00000080 - U-000007FF, 2 string.bytes | ||
23 | tail = 1; | ||
24 | code = bit.band(c, 0x1f) | ||
25 | elseif (c < 0xf0) then -- U-00000800 - U-0000FFFF, 3 string.bytes | ||
26 | tail = 2; | ||
27 | code = bit.band(c, 0x0f) | ||
28 | elseif (c < 0xf5) then -- U-00010000 - U-001FFFFF, 4 string.bytes | ||
29 | tail = 3; | ||
30 | code = bit.band(c, 0x07) | ||
37 | else | 31 | else |
38 | -- Invalid continuation char | 32 | -- Invalid size |
39 | code = INVALID; | 33 | code = 0xfffd; |
40 | break; | 34 | end |
35 | |||
36 | while tail and c ~= 0 do | ||
37 | tail = tail - 1 | ||
38 | if bit.band(c, 0xc0) == 0x80 then | ||
39 | -- Valid continuation character | ||
40 | code = bit.bor(bit.lshift(code, 6),bit.band(c, 0x3f)) | ||
41 | else | ||
42 | -- Invalid continuation char | ||
43 | code = INVALID; | ||
44 | break; | ||
45 | end | ||
41 | end | 46 | end |
47 | else | ||
48 | -- Invalid UTF-8 char | ||
49 | code = INVALID; | ||
42 | end | 50 | end |
43 | else | 51 | -- currently we don't support chars above U-FFFF |
44 | -- Invalid UTF-8 char | 52 | t[#t + 1 ] = encode_short((code < 0x10000) and code or 0xfffd) |
45 | code = INVALID; | ||
46 | end | 53 | end |
47 | -- currently we don't support chars above U-FFFF | 54 | str:gsub(".", check_char) -- run check function for every char |
48 | t[#t + 1 ] = encode_short((code < 0x10000) and code or 0xfffd) | 55 | return table.concat(t) |
49 | end | 56 | end |
50 | str:gsub(".", check_char) -- run check function for every char | ||
51 | return table.concat(t) | ||
52 | end | ||
53 | 57 | ||
54 | function create_keyboard_layout(s_layout) | 58 | local function create_keyboard_layout(s_layout) |
55 | local insert = table.insert | 59 | local insert = table.insert |
56 | lines = {} | 60 | lines = {} |
57 | 61 | ||
58 | local t={} | 62 | local t={} |
59 | for str in string.gmatch(s_layout, "([^\n]+)") do | 63 | for str in string.gmatch(s_layout, "([^\n]+)") do |
60 | local len = string.len(str) | 64 | local len = string.len(str) |
61 | lines[#lines + 1] = | 65 | lines[#lines + 1] = |
62 | table.concat({encode_short(len), utf8decode(str)}) | 66 | table.concat({encode_short(len), utf8decode(str)}) |
63 | end | 67 | end |
64 | lines[#lines + 1] = encode_short(0xFEFF) | 68 | lines[#lines + 1] = encode_short(0xFEFF) |
65 | 69 | ||
66 | return table.concat(lines) | 70 | return table.concat(lines) |
71 | end | ||
72 | _kbdlayout.create_keyboard_layout = create_keyboard_layout | ||
73 | _kbdlayout.utf8decode = utf8decode | ||
67 | end | 74 | end |
68 | 75 | ||
76 | |||
69 | --[[ | 77 | --[[ |
70 | local name = "Test_KBD_LAYOUT_" .. tostring(1) | 78 | local name = "Test_KBD_LAYOUT_" .. tostring(1) |
71 | local test = create_keyboard_layout("ABCDEFGHIJKLM\nNOPQRSTUVWXYZ\n0123456789") | 79 | local test = _kbdlayout.create_keyboard_layout("ABCDEFGHIJKLM\nNOPQRSTUVWXYZ\n0123456789") |
72 | local file = io.open('/' .. name, "w+") -- overwrite, rb ignores the 'b' flag | 80 | local file = io.open('/' .. name, "w+") -- overwrite, rb ignores the 'b' flag |
73 | file:write(test)-- write the layout to the file now | 81 | file:write(test)-- write the layout to the file now |
74 | file:close() | 82 | file:close() |
@@ -79,3 +87,4 @@ if not file then | |||
79 | end | 87 | end |
80 | rb.kbd_input(name, test) | 88 | rb.kbd_input(name, test) |
81 | ]] | 89 | ]] |
90 | return _kbdlayout | ||
diff --git a/apps/plugins/lua/include_lua/temploader.lua b/apps/plugins/lua/include_lua/temploader.lua new file mode 100644 index 0000000000..69eae468a8 --- /dev/null +++ b/apps/plugins/lua/include_lua/temploader.lua | |||
@@ -0,0 +1,30 @@ | |||
1 | --[[ | ||
2 | temp loader allows some lua requires to be loaded and later garbage collected | ||
3 | unfortunately the module needs to be formatted in such a way to pass back a | ||
4 | call table in order to keep the functions within from being garbage collected | ||
5 | too early | ||
6 | |||
7 | BE AWARE this bypasses the module loader which would allow code reuse | ||
8 | so if you aren't careful this memory saving tool could spell disaster | ||
9 | for free RAM if you load the same code multiple times | ||
10 | --]] | ||
11 | |||
12 | |||
13 | local function tempload(modulename) | ||
14 | --http://lua-users.org/wiki/LuaModulesLoader | ||
15 | local errmsg = "" | ||
16 | -- Find source | ||
17 | local modulepath = string.gsub(modulename, "%.", "/") | ||
18 | for path in string.gmatch(package.path, "([^;]+)") do | ||
19 | local filename = string.gsub(path, "%?", modulepath) | ||
20 | local file = io.open(filename, "r") | ||
21 | if file then | ||
22 | -- Compile and return the module | ||
23 | return assert(loadstring(assert(file:read("*a")), filename))() | ||
24 | end | ||
25 | errmsg = errmsg.."\n\tno file '"..filename.."' (temp loader)" | ||
26 | end | ||
27 | return errmsg | ||
28 | end | ||
29 | |||
30 | return tempload | ||
diff --git a/apps/plugins/lua/lua.make b/apps/plugins/lua/lua.make index eada6b370f..60dfd24cdd 100644 --- a/apps/plugins/lua/lua.make +++ b/apps/plugins/lua/lua.make | |||
@@ -22,7 +22,8 @@ LUA_INCLUDELIST := $(addprefix $(LUA_BUILDDIR)/,audio.lua blit.lua color.lua \ | |||
22 | math_ex.lua print.lua timer.lua playlist.lua pcm.lua \ | 22 | math_ex.lua print.lua timer.lua playlist.lua pcm.lua \ |
23 | sound.lua rbcompat.lua rbsettings.lua poly_points.lua \ | 23 | sound.lua rbcompat.lua rbsettings.lua poly_points.lua \ |
24 | printtable.lua printmenus.lua printsubmenu.lua \ | 24 | printtable.lua printmenus.lua printsubmenu.lua \ |
25 | menubuttons.lua menucoresettings.lua create_kbd_layout.lua) | 25 | menubuttons.lua menucoresettings.lua create_kbd_layout.lua \ |
26 | temploader.lua) | ||
26 | 27 | ||
27 | ifndef APP_TYPE | 28 | ifndef APP_TYPE |
28 | ROCKS += $(LUA_BUILDDIR)/lua.rock | 29 | ROCKS += $(LUA_BUILDDIR)/lua.rock |
diff --git a/apps/plugins/lua/rocklib.c b/apps/plugins/lua/rocklib.c index 050fbc73b2..2672d446fc 100644 --- a/apps/plugins/lua/rocklib.c +++ b/apps/plugins/lua/rocklib.c | |||
@@ -153,7 +153,7 @@ RB_WRAP(kbd_input) | |||
153 | 153 | ||
154 | const char *input = lua_tostring(L, 1); | 154 | const char *input = lua_tostring(L, 1); |
155 | size_t layout_len; | 155 | size_t layout_len; |
156 | const char *layout = lua_tolstring(L, 2, &layout_len); | 156 | const unsigned char *layout = lua_tolstring(L, 2, &layout_len); |
157 | char *buffer = luaL_prepbuffer(&b); | 157 | char *buffer = luaL_prepbuffer(&b); |
158 | 158 | ||
159 | if(input != NULL) | 159 | if(input != NULL) |
@@ -161,8 +161,12 @@ RB_WRAP(kbd_input) | |||
161 | else | 161 | else |
162 | buffer[0] = '\0'; | 162 | buffer[0] = '\0'; |
163 | 163 | ||
164 | if(layout_len <= 1 || (unsigned short)layout[layout_len - 1] != 0xFFFE) | 164 | if(layout_len <= 2 || |
165 | layout[layout_len - 1] != 0xFE || | ||
166 | layout[layout_len - 2] != 0xFF) | ||
167 | { | ||
165 | layout = NULL; | 168 | layout = NULL; |
169 | } | ||
166 | 170 | ||
167 | if(!rb->kbd_input(buffer, LUAL_BUFFERSIZE, (unsigned short *)layout)) | 171 | if(!rb->kbd_input(buffer, LUAL_BUFFERSIZE, (unsigned short *)layout)) |
168 | { | 172 | { |