summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2024-05-05 14:11:47 -0400
committerWilliam Wilgus <wilgus.william@gmail.com>2024-05-05 14:11:47 -0400
commitf55483a9668f2e27d155a94ff157d79145147a70 (patch)
treefe3fd7ed3fe8085419faa83913702c5b1f69f40e
parentc34076b2a591f8fc134b73d664fd8bd0b438d8ec (diff)
downloadrockbox-f55483a9668f2e27d155a94ff157d79145147a70.tar.gz
rockbox-f55483a9668f2e27d155a94ff157d79145147a70.zip
lua --remove files moved to include directory
Change-Id: Ic9256cb28126dba89b1458109c717f846f5b6d38
-rw-r--r--apps/plugins/lua_scripts.lua173
-rw-r--r--apps/plugins/lua_scripts/dbgettags.lua119
-rwxr-xr-xapps/plugins/lua_scripts/filebrowse.lua241
-rwxr-xr-xapps/plugins/lua_scripts/fileviewers.lua468
4 files changed, 0 insertions, 1001 deletions
diff --git a/apps/plugins/lua_scripts.lua b/apps/plugins/lua_scripts.lua
deleted file mode 100644
index 43593d96b0..0000000000
--- a/apps/plugins/lua_scripts.lua
+++ /dev/null
@@ -1,173 +0,0 @@
1--[[
2/***************************************************************************
3 * __________ __ ___.
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * \/ \/ \/ \/ \/
9 * $Id$
10 *
11 * Copyright (C) 2017 William Wilgus
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22]]
23
24local scrpath = rb.current_path() .. "/lua_scripts/"
25
26package.path = scrpath .. "/?.lua;" .. package.path --add lua_scripts directory to path
27require("printmenus")
28
29rb.actions = nil
30package.loaded["actions"] = nil
31
32local excludedsrc = ";filebrowse.lua;fileviewers.lua;printmenu.lua;dbgettags.lua;"
33--------------------------------------------------------------------------------
34local Icon_Plugin = 0x9
35
36
37local function get_files(path, norecurse, finddir, findfile, f_t, d_t)
38
39 local quit = false
40
41 local files = f_t or {}
42 local dirs = d_t or {}
43
44 local function f_filedir(name)
45 --default find function
46 -- example: return name:find(".mp3", 1, true) ~= nil
47 if name:len() <= 2 and (name == "." or name == "..") then
48 return false
49 end
50 if string.find(excludedsrc, ";" .. name .. ";") then
51 return false
52 end
53 if string.sub(name, -4) == ".lua" then
54 return true
55 end
56 return false
57 end
58 local function d_filedir(name)
59 --default discard function
60 return false
61 end
62
63 if finddir == nil then
64 finddir = f_filedir
65 elseif type(finddir) ~= "function" then
66 finddir = d_filedir
67 end
68
69 if findfile == nil then
70 findfile = f_filedir
71 elseif type(findfile) ~= "function" then
72 findfile = d_filedir
73 end
74
75 local function _get_files(path, cancelbtn)
76 local sep = ""
77 if string.sub(path, - 1) ~= "/" then sep = "/" end
78 for fname, isdir in luadir.dir(path) do
79
80 if isdir and finddir(fname) then
81 table.insert(dirs, path .. sep ..fname)
82 elseif not isdir and findfile(fname) then
83 table.insert(files, path .. sep ..fname)
84 end
85
86 if rb.get_plugin_action(0) == cancelbtn then
87 return true
88 end
89 end
90 end
91
92 local function cmp_alphanum (op1, op2)
93 local type1= type(op1)
94 local type2 = type(op2)
95
96 if type1 ~= type2 then
97 return type1 < type2
98 else
99 if type1 == "string" then
100 op1 = op1:upper()
101 op2 = op2:upper()
102 end
103 return op1 < op2
104 end
105 end
106
107 table.insert(dirs, path) -- root
108
109 for key,value in pairs(dirs) do
110 --luadir.dir may error out so we need to do the call protected
111 _, quit = pcall(_get_files, value, CANCEL_BUTTON)
112
113 if quit == true or norecurse then
114 break;
115 end
116 end
117
118 table.sort(files, cmp_alphanum)
119 table.sort(dirs, cmp_alphanum)
120
121 return dirs, files
122end -- get_files
123--------------------------------------------------------------------------------
124
125function icon_fn(item, icon)
126 if item ~= 0 then
127 icon = Icon_Plugin
128 else
129 icon = -1
130 end
131 return icon
132end
133
134-- uses print_table and get_files to display simple file browser
135function script_choose(dir, title)
136 local dstr
137 local hstr = title
138
139 local norecurse = true
140 local f_finddir = false -- function to match directories; nil all, false none
141 local f_findfile = nil -- function to match files; nil all, false none
142 local t_linedesc = {show_icons = true, icon_fn = icon_fn}
143 local p_settings = {wrap = true, hasheader = true, justify = "left", linedesc = t_linedesc}
144 local files = {}
145 local dirs = {}
146 local item = 1
147 rb.lcd_clear_display()
148
149 while item > 0 do
150 dirs, files = get_files(dir, norecurse, f_finddir, f_findfile, dirs, files)
151 for i=1, #dirs do dirs[i] = nil end -- empty table for reuse
152 table.insert(dirs, 1, hstr)
153 for i = 1, #files do
154 table.insert(dirs, "\t" .. string.gsub(files[i], ".*/",""))
155 end
156 --print_menu(menu_t, func_t, selected, settings, copy_screen)
157 _, item = print_menu(dirs, nil, 0, p_settings)
158
159 -- If item was selected follow directory or return filename
160 item = item or -1
161 if item > 0 then
162 dir = files[item - 1]
163 if not rb.dir_exists("/" .. dir) then
164 return dir
165 end
166 end
167
168 end
169end -- file_choose
170--------------------------------------------------------------------------------
171
172local script_path = script_choose(scrpath, "lua scripts")
173if script_path then rb.restart_lua(script_path) end
diff --git a/apps/plugins/lua_scripts/dbgettags.lua b/apps/plugins/lua_scripts/dbgettags.lua
deleted file mode 100644
index 8e9f26393d..0000000000
--- a/apps/plugins/lua_scripts/dbgettags.lua
+++ /dev/null
@@ -1,119 +0,0 @@
1-- dbgettags.lua Bilgus 2017
2--[[
3/***************************************************************************
4 * __________ __ ___.
5 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
6 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
7 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
8 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * \/ \/ \/ \/ \/
10 * $Id$
11 *
12 * Copyright (C) 2017 William Wilgus
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23]]
24
25require("actions")
26local CANCEL_BUTTON = rb.actions.PLA_CANCEL
27
28local sINVALIDDATABASE = "Invalid Database"
29local sERROROPENING = "Error opening"
30
31-- tag cache header
32sTCVERSION = string.char(0x10)
33sTCHEADER = string.reverse("TCH" .. sTCVERSION)
34DATASZ = 4 -- int32_t
35TCHSIZE = 3 * DATASZ -- 3 x int32_t
36
37-- Converts array of bytes to proper endian
38function bytesLE_n(str)
39 str = str or ""
40 local tbyte={str:byte(1, -1)}
41 local bpos = 1
42 local num = 0
43 for k = 1,#tbyte do -- (k = #t, 1, -1 for BE)
44 num = num + tbyte[k] * bpos
45 bpos = bpos * 256
46 end
47 return num
48end
49
50-- uses database files to retrieve database tags
51-- adds all unique tags into a lua table
52-- ftable is optional
53function get_tags(filename, hstr, ftable)
54
55 if not filename then return end
56 if not ftable then ftable = {} end
57 hstr = hstr or filename
58
59 local file = io.open('/' .. filename or "", "r") --read
60 if not file then rb.splash(100, sERROROPENING .. " " .. filename) return end
61
62 local fsz = file:seek("end")
63
64 local posln = 0
65 local tag_len = TCHSIZE
66 local idx
67
68 local function readchrs(count)
69 if posln >= fsz then return nil end
70 file:seek("set", posln)
71 posln = posln + count
72 return file:read(count)
73 end
74
75 -- check the header and get size + #entries
76 local tagcache_header = readchrs(DATASZ) or ""
77 local tagcache_sz = readchrs(DATASZ) or ""
78 local tagcache_entries = readchrs(DATASZ) or ""
79
80 if tagcache_header ~= sTCHEADER or
81 bytesLE_n(tagcache_sz) ~= (fsz - TCHSIZE) then
82 rb.splash(100, sINVALIDDATABASE .. " " .. filename)
83 return
84 end
85
86 -- local tag_entries = bytesLE_n(tagcache_entries)
87
88 for k, v in pairs(ftable) do ftable[k] = nil end -- clear table
89 ftable[1] = hstr
90
91 local tline = #ftable + 1
92 ftable[tline] = ""
93
94 local str = ""
95
96 while true do
97 tag_len = bytesLE_n(readchrs(DATASZ))
98 readchrs(DATASZ) -- idx = bytesLE_n(readchrs(DATASZ))
99 str = readchrs(tag_len) or ""
100 str = string.match(str, "(%Z+)%z") -- \0 terminated string
101
102 if str then
103 if ftable[tline - 1] ~= str then -- Remove dupes
104 ftable[tline] = str
105 tline = tline + 1
106 end
107 elseif posln >= fsz then
108 break
109 end
110
111 if rb.get_plugin_action(0) == CANCEL_BUTTON then
112 break
113 end
114 end
115
116 file:close()
117
118 return ftable
119end -- get_tags
diff --git a/apps/plugins/lua_scripts/filebrowse.lua b/apps/plugins/lua_scripts/filebrowse.lua
deleted file mode 100755
index 0640ec3764..0000000000
--- a/apps/plugins/lua_scripts/filebrowse.lua
+++ /dev/null
@@ -1,241 +0,0 @@
1--[[
2/***************************************************************************
3 * __________ __ ___.
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * \/ \/ \/ \/ \/
9 * $Id$
10 *
11 * Copyright (C) 2017 William Wilgus
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22]]
23if ... == nil then rb.splash(rb.HZ * 3, "use 'require'") end
24require("printtable")
25local _lcd = require("lcd")
26local _timer = require("timer")
27
28--------------------------------------------------------------------------------
29--[[ returns a sorted tables of directories and (another) of files
30-- path is the starting path; norecurse == true.. only that path will be searched
31-- findfile & finddir are definable search functions
32-- if not defined all files/dirs are returned if false is passed.. none
33-- or you can provide your own function see below..
34-- f_t and d_t allow you to pass your own tables for re-use but isn't necessary
35]]
36local function get_files(path, norecurse, finddir, findfile, sort_by, f_t, d_t)
37 local quit = false
38 local sort_by_function -- forward declaration
39 local filepath_function -- forward declaration
40 local files = f_t or {}
41 local dirs = d_t or {}
42
43 local function f_filedir(name)
44 --default find function
45 -- example: return name:find(".mp3", 1, true) ~= nil
46 if name:len() <= 2 and (name == "." or name == "..") then
47 return false
48 end
49 return true
50 end
51 local function d_filedir(name)
52 --default discard function
53 return false
54 end
55
56 if finddir == nil then
57 finddir = f_filedir
58 elseif type(finddir) ~= "function" then
59 finddir = d_filedir
60 end
61
62 if findfile == nil then
63 findfile = f_filedir
64 elseif type(findfile) ~= "function" then
65 findfile = d_filedir
66 end
67
68 local function _get_files(path, cancelbtn)
69 local sep = ""
70 local filepath
71 local finfo_t
72 if string.sub(path, - 1) ~= "/" then sep = "/" end
73 for fname, isdir, finfo_t in luadir.dir(path, true) do
74 if isdir and finddir(fname) then
75 table.insert(dirs, path .. sep ..fname)
76 elseif not isdir and findfile(fname) then
77 filepath = filepath_function(path, sep, fname, finfo_t.attribute, finfo_t.size, finfo_t.time)
78 table.insert(files, filepath)
79 end
80
81 if rb.get_plugin_action(0) == cancelbtn then
82 return true
83 end
84 end
85 end
86
87
88
89 local function cmp_alphanum (op1, op2)
90 local type1= type(op1)
91 local type2 = type(op2)
92
93 if type1 ~= type2 then
94 return type1 < type2
95 else
96 if type1 == "string" then
97 op1 = op1:upper()
98 op2 = op2:upper()
99 return sort_by_function(op1, op2)
100 end
101 return op1 < op2
102 end
103 end
104
105 _lcd:splashf(1, "Searching for Files")
106
107 if sort_by == "name" then
108 sort_by_function = function(s1, s2) return s1 < s2 end
109 filepath_function = function(path, sep, fname, fattrib, fsize, ftime)
110 return string.format("%s%s%s;", path, sep, fname)
111 end
112 elseif sort_by == "size" then
113 filepath_function = function(path, sep, fname, fattrib, fsize, ftime)
114 return string.format("%s%s%s; At:%d, Sz:%d, Tm:%d", path, sep, fname, fattrib, fsize, ftime)
115 end
116 sort_by_function = function(s1, s2)
117 local v1, v2
118 v1 = string.match(s1, "SZ:(%d+)")
119 v2 = string.match(s2, "SZ:(%d+)")
120 if v1 or v2 then
121 return tonumber(v1 or 0) < tonumber(v2 or 0)
122 end
123 return s1 < s2
124 end
125 elseif sort_by == "date" then
126 filepath_function = function(path, sep, fname, fattrib, fsize, ftime)
127 return string.format("%s%s%s; At:%d, Sz:%d, Tm:%d", path, sep, fname, fattrib, fsize, ftime)
128 end
129 sort_by_function = function(s1, s2)
130 local v1, v2
131 v1 = string.match(s1, "TM:(%d+)")
132 v2 = string.match(s2, "TM:(%d+)")
133 if v1 or v2 then
134 return tonumber(v1 or 0) < tonumber(v2 or 0)
135 end
136 return s1 < s2
137 end
138 end
139
140 table.insert(dirs, path) -- root
141
142 for key,value in pairs(dirs) do
143 --luadir.dir may error out so we need to do the call protected
144 -- _get_files(value, CANCEL_BUTTON)
145 _, quit = pcall(_get_files, value, CANCEL_BUTTON)
146
147 if quit == true or norecurse then
148 break;
149 end
150 end
151
152 table.sort(files, cmp_alphanum)
153 table.sort(dirs, cmp_alphanum)
154
155 return dirs, files
156end -- get_files
157--------------------------------------------------------------------------------
158
159-- uses print_table and get_files to display simple file browser
160-- sort_by "date" "name" "size"
161-- descending true/false
162function file_choose(dir, title, sort_by, descending)
163 local dstr, hstr = ""
164 if not title then
165 dstr = "%d items found in %0d.%02d seconds"
166 else
167 hstr = title
168 end
169
170 if not sort_by then sort_by = "name" end
171 sort_by = sort_by:lower()
172
173 -- returns whole seconds and remainder
174 local function tick2seconds(ticks)
175 local secs = (ticks / rb.HZ)
176 local csecs = (ticks - (secs * rb.HZ))
177 return secs, csecs
178 end
179
180 local norecurse = true
181 local f_finddir = nil -- function to match directories; nil all, false none
182 local f_findfile = nil -- function to match files; nil all, false none
183
184 local p_settings = {wrap = true, hasheader = true}
185
186 local timer
187 local files = {}
188 local dirs = {}
189 local item = 1
190 _lcd:clear()
191
192 while item > 0 do
193 if not title then
194 timer = _timer()
195 end
196
197 dirs, files = get_files(dir, norecurse, f_finddir, f_findfile, sort_by, dirs, files)
198
199 local parentdir = dirs[1]
200 for i = 1, #dirs do
201 dirs[i] = "\t" .. dirs[i]
202 end
203
204 if not descending then
205 for i = 1, #files do
206 -- only store file name .. strip attributes from end
207 table.insert(dirs, "\t" .. string.match(files[i], "[^;]+") or "?")
208 end
209 else
210 for i = #files, 1, -1 do
211 -- only store file name .. strip attributes from end
212 table.insert(dirs, "\t" .. string.match(files[i], "[^;]+") or "?")
213 end
214 end
215 for i=1, #files do files[i] = nil end -- empty table for reuse
216
217 if not title then
218 hstr = string.format(dstr, #dirs - 1, tick2seconds(timer:stop()))
219 end
220
221 table.insert(dirs, 1, hstr)
222
223 item = print_table(dirs, #dirs, p_settings)
224
225 -- If item was selected follow directory or return filename
226 if item > 0 then
227 dir = string.gsub(dirs[item], "%c+","")
228 if not rb.dir_exists("/" .. dir) then
229 return dir
230 end
231 end
232
233 if dir == parentdir then
234 dir = dir:sub(1, dir:match(".*()/") - 1)
235 if dir == "" then dir = "/" end
236 end
237 for i=1, #dirs do dirs[i] = nil end -- empty table for reuse
238
239 end
240end -- file_choose
241--------------------------------------------------------------------------------
diff --git a/apps/plugins/lua_scripts/fileviewers.lua b/apps/plugins/lua_scripts/fileviewers.lua
deleted file mode 100755
index c686f3eeda..0000000000
--- a/apps/plugins/lua_scripts/fileviewers.lua
+++ /dev/null
@@ -1,468 +0,0 @@
1--[[
2/***************************************************************************
3 * __________ __ ___.
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * \/ \/ \/ \/ \/
9 * $Id$
10 *
11 * Copyright (C) 2017 William Wilgus
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22]]
23if ... == nil then rb.splash(rb.HZ * 3, "use 'require'") end
24require("printtable")
25local _clr = require("color")
26local _lcd = require("lcd")
27local _print = require("print")
28local _timer = require("timer")
29
30require("actions")
31local CANCEL_BUTTON = rb.actions.PLA_CANCEL
32--------------------------------------------------------------------------------
33-- builds an index of byte position of every line at each bufsz increment
34-- in filename; bufsz == 1 would be every line; saves to filename.ext.idx_ext
35-- lnbyte should be nil for text files and number of bytes per line for binary
36local function build_file_index(filename, idx_ext, bufsz, lnbyte)
37
38 if not filename then return end
39 local file = io.open('/' .. filename, "r") --read
40 if not file then _lcd:splashf(100, "Can't open %s", filename) return end
41 local fsz = file:seek("end")
42 local fsz_kb = fsz / 1024
43 local count
44 local ltable = {0} --first index is the beginning of the file
45 local timer = _timer()
46 local fread
47 _lcd:splashf(100, "Indexing file %d Kb", (fsz / 1024))
48
49 if lnbyte then
50 fread = function(f) return f:read(lnbyte) end
51 else
52 lnbyte = -1
53 fread = function(f) return f:read("*l") end
54 end
55
56 file:seek("set", 0)
57 for i = 1, fsz do
58 if i % bufsz == 0 then
59 local loc = file:seek()
60 ltable[#ltable + 1] = loc
61 _lcd:splashf(1, "Parsing %d of %d Kb", loc / 1024, fsz_kb)
62 end
63 if rb.get_plugin_action(0) == CANCEL_BUTTON then
64 return
65 end
66 if not fread(file) then
67 count = i
68 break
69 end
70 end
71
72 local fileidx = io.open('/' .. filename .. idx_ext, "w+") -- write/erase
73 if fileidx then
74 fileidx:write(fsz .. "\n")
75 fileidx:write(count .. "\n")
76 fileidx:write(bufsz .. "\n")
77 fileidx:write(lnbyte .. "\n")
78 fileidx:write(table.concat(ltable, "\n"))
79 fileidx:close()
80 _lcd:splashf(100, "Finished in %d seconds", timer.stop() / rb.HZ)
81 collectgarbage("collect")
82 else
83 error("unable to save index file")
84 end
85end -- build_file_index
86--------------------------------------------------------------------------------
87
88--- returns size of original file, total lines buffersize, and table filled
89-- with line offsets in index file -> filename
90local function load_index_file(filename)
91 local filesz, count, bufsz, lnbyte
92 local ltable
93 local fileidx = io.open('/' .. filename, "r") --read
94 if fileidx then
95 local idx = -3
96 ltable = {}
97 fileidx:seek("set", 0)
98 for line in fileidx:lines() do
99 if idx == -3 then
100 filesz = tonumber(line)
101 elseif idx == -2 then
102 count = tonumber(line)
103 elseif idx == -1 then
104 bufsz = tonumber(line)
105 elseif idx == 0 then
106 lnbyte = tonumber(line)
107 else
108 ltable[idx] = tonumber(line)
109 end
110 idx = idx + 1
111 end
112 fileidx:close()
113 end
114 return lnbyte, filesz, count, bufsz, ltable
115end -- load_index_file
116--------------------------------------------------------------------------------
117
118-- creates a fixed index with fixed line lengths, perfect for viewing hex files
119-- not so great for reading text files but works as a fallback
120local function load_fixed_index(bytesperline, filesz, bufsz)
121 local lnbyte = bytesperline
122 local count = (filesz + lnbyte - 1) / lnbyte + 1
123 local idx_t = {} -- build index
124 for i = 0, filesz, bufsz do
125 idx_t[#idx_t + 1] = lnbyte * i
126 end
127 return lnbyte, filesz, count, bufsz, idx_t
128end -- load_fixed_index
129--------------------------------------------------------------------------------
130
131-- uses print_table to display a whole file
132function print_file(filename, maxlinelen, settings)
133
134 if not filename then return end
135 local file = io.open('/' .. filename or "", "r") --read
136 if not file then _lcd:splashf(100, "Can't open %s", filename) return end
137 maxlinelen = 33
138 local hstr = filename
139 local ftable = {}
140 table.insert(ftable, 1, hstr)
141
142 local tline = #ftable + 1
143 local remln = maxlinelen
144 local posln = 1
145
146 for line in file:lines() do
147 if line then
148 if maxlinelen then
149 if line == "" then
150 ftable[tline] = ftable[tline] or ""
151 tline = tline + 1
152 remln = maxlinelen
153 else
154 line = line:match("%w.+") or ""
155 end
156 local linelen = line:len()
157 while linelen > 0 do
158
159 local fsp = line:find("%s", posln + remln - 5) or 0x0
160 fsp = fsp - (posln + remln)
161 if fsp >= 0 then
162 local fspr = fsp
163 fsp = line:find("%s", posln + remln) or linelen
164 fsp = fsp - (posln + remln)
165 if math.abs(fspr) < fsp then fsp = fspr end
166 end
167 if fsp > 5 or fsp < -5 then fsp = 0 end
168
169 local str = line:sub(posln, posln + remln + fsp)
170 local slen = str:len()
171 ftable[tline] = ftable[tline] or ""
172 ftable[tline] = ftable[tline] .. str
173 linelen = linelen - slen
174 if linelen > 0 then
175 tline = tline + 1
176 posln = posln + slen
177 remln = maxlinelen
178 --loop continues
179 else
180 ftable[tline] = ftable[tline] .. " "
181 remln = maxlinelen - slen
182 posln = 1
183 --loop ends
184 end
185
186 end
187 else
188 ftable[#ftable + 1] = line
189 end
190
191
192 end
193 end
194
195 file:close()
196
197 _lcd:clear()
198 _print.clear()
199
200 if not settings then
201 settings = {}
202 settings.justify = "center"
203 settings.wrap = true
204 settings.msel = true
205 end
206 settings.hasheader = true
207 settings.co_routine = nil
208 settings.ovfl = "manual"
209
210 local sel =
211 print_table(ftable, #ftable, settings)
212
213 _lcd:splashf(rb.HZ * 2, "%d items {%s}", #sel, table.concat(sel, ", "))
214 ftable = nil
215end -- print_file
216--------------------------------------------------------------------------------
217
218-- uses print_table to display a portion of a file
219function print_file_increment(filename, settings)
220
221 if not filename then return end
222 local file = io.open('/' .. filename, "r") --read
223 if not file then _lcd:splashf(100, "Can't open %s", filename) return end
224 local fsz = file:seek("end")
225 local bsz = 1023
226 --if small file do it the easier way and load whole file to table
227 if fsz < 60 * 1024 then
228 file:close()
229 print_file(filename, settings)
230 return
231 end
232
233 local ext = ".idx"
234 local lnbyte, filesz, count, bufsz, idx_t = load_index_file(filename .. ext)
235
236 if not idx_t or fsz ~= filesz then -- build file index
237 build_file_index(filename, ext, bsz)
238 lnbyte, filesz, count, bufsz, idx_t = load_index_file(filename .. ext)
239 end
240
241 -- if invalid or user canceled creation fallback to a fixed index
242 if not idx_t or fsz ~= filesz or count <= 0 then
243 _lcd:splashf(rb.HZ * 5, "Unable to read file index %s", filename .. ext)
244 lnbyte, filesz, count, bufsz, idx_t = load_fixed_index(32, fsz, bsz)
245 end
246
247 if not idx_t or fsz ~= filesz or count <= 0 then
248 _lcd:splashf(rb.HZ * 5, "Unable to load file %s", filename)
249 return
250 end
251
252 local hstr = filename
253 local file_t = setmetatable({},{__mode = "kv"}) --weak keys and values
254 -- this allows them to be garbage collected as space is needed
255 -- rebuilds when needed
256 local ovf = 0
257 local lpos = 1
258 local timer = _timer()
259 file:seek("set", 0)
260
261 function print_co()
262 while true do
263 collectgarbage("step")
264 file_t[1] = hstr --position 1 is ALWAYS header/title
265
266 for i = 1, bufsz + ovf do
267 file_t[lpos + i] = file:read ("*l")
268 end
269 ovf = 0
270 lpos = lpos + bufsz
271
272 local bpos = coroutine.yield()
273
274 if bpos <= lpos then -- roll over or scroll up
275 bpos = (bpos - bufsz) + bpos % bufsz
276 timer:check(true)
277 end
278
279 lpos = bpos - bpos % bufsz
280
281 if lpos < 1 then
282 lpos = 1
283 elseif lpos > count - bufsz then -- partial fill
284 ovf = count - bufsz - lpos
285 end
286 --get position in file of the nearest indexed line
287 file:seek("set", idx_t[bpos / bufsz + 1])
288
289 -- on really large files if it has been more than 10 minutes
290 -- since the user scrolled up the screen wipe out the prior
291 -- items to free memory
292 if lpos % 5000 == 0 and timer:check() > rb.HZ * 600 then
293 for i = 1, lpos - 100 do
294 file_t[i] = nil
295 end
296 end
297
298 end
299 end
300
301 co = coroutine.create(print_co)
302 _lcd:clear()
303 _print.clear()
304
305 if not settings then
306 settings = {}
307 settings.justify = "center"
308 settings.wrap = true
309 end
310 settings.hasheader = true
311 settings.co_routine = co
312 settings.msel = false
313 settings.ovfl = "manual"
314
315 table.insert(file_t, 1, hstr) --position 1 is header/title
316 local sel =
317 print_table(file_t, count, settings)
318 file:close()
319 idx_t = nil
320 file_t = nil
321 return sel
322end --print_file_increment
323--------------------------------------------------------------------------------
324function print_file_hex(filename, bytesperline, settings)
325
326 if not filename then return end
327 local file = io.open('/' .. filename, "r") --read
328 if not file then _lcd:splashf(100, "Can't open %s", filename) return end
329 local hstr = filename
330 local bpl = bytesperline
331 local fsz = file:seek("end")
332--[[
333 local filesz = file:seek("end")
334 local bufsz = 1023
335 local lnbyte = bytesperline
336 local count = (filesz + lnbyte - 1) / lnbyte + 1
337
338 local idx_t = {} -- build index
339 for i = 0, filesz, bufsz do
340 idx_t[#idx_t + 1] = lnbyte * i
341 end]]
342
343 local lnbyte, filesz, count, bufsz, idx_t = load_fixed_index(bpl, fsz, 1023)
344
345 local file_t = setmetatable({},{__mode = "kv"}) --weak keys and values
346 -- this allows them to be garbage collected as space is needed
347 -- rebuilds when needed
348 local ovf = 0
349 local lpos = 1
350 local timer = _timer()
351 file:seek("set", 0)
352
353 function hex_co()
354 while true do
355 collectgarbage("step")
356 file_t[1] = hstr --position 1 is ALWAYS header/title
357
358 for i = 1, bufsz + ovf do
359 local pos = file:seek()
360 local s = file:read (lnbyte)
361 if not s then -- EOF
362 file_t[lpos + i] = ""
363 break;
364 end
365 local s_len = s:len()
366
367 if s_len > 0 then
368 local fmt = "0x%04X: " .. string.rep("%02X ", s_len)
369 local schrs = " " .. s:gsub("(%c)", " . ")
370 file_t[lpos + i] = string.format(fmt, pos, s:byte(1, s_len)) ..
371 schrs
372 else
373 file_t[lpos + i] = string.format("0x%04X: ", pos)
374 end
375 end
376 ovf = 0
377 lpos = lpos + bufsz
378
379 local bpos = coroutine.yield()
380
381 if bpos < lpos then -- roll over or scroll up
382 bpos = (bpos - bufsz) + bpos % bufsz
383 timer:check(true)
384 end
385
386 lpos = bpos - bpos % bufsz
387
388 if lpos < 1 then
389 lpos = 1
390 elseif lpos > count - bufsz then -- partial fill
391 ovf = count - bufsz - lpos
392 end
393 --get position in file of the nearest indexed line
394 file:seek("set", idx_t[bpos / bufsz + 1])
395
396 -- on really large files if it has been more than 10 minutes
397 -- since the user scrolled up the screen wipe out the prior
398 -- items to free memory
399 if lpos % 10000 == 0 and timer:check() > rb.HZ * 600 then
400 for i = 1, lpos - 100 do
401 file_t[i] = nil
402 end
403 end
404
405 end
406 end
407
408 co = coroutine.create(hex_co)
409
410 local function repl(char)
411 local ret = ""
412 if char:sub(1,2) == "0x" then
413 return string.format("%dd:", tonumber(char:sub(3, -2), 16))
414 else
415 return string.format("%03d ", tonumber(char, 16))
416 end
417 end
418
419
420 _lcd:clear()
421 _print.clear()
422
423 local sel, start, vcur = 1
424 table.insert(file_t, 1, hstr) --position 1 is header/title
425
426 if not settings then
427 settings = {}
428 settings.justify = "left"
429 settings.wrap = true
430 settings.msel = false
431 settings.hfgc = _clr.set( 0, 000, 000, 000)
432 settings.hbgc = _clr.set(-1, 255, 255, 255)
433 settings.ifgc = _clr.set(-1, 255, 255, 255)
434 settings.ibgc = _clr.set( 0, 000, 000, 000)
435 settings.iselc = _clr.set( 1, 000, 200, 100)
436 end
437
438 settings.hasheader = true
439 settings.co_routine = co
440 settings.start = start
441 settings.curpos = vcur
442 settings.ovfl = "manual"
443
444 while sel > 0 do
445 settings.start = start
446 settings.curpos = vcur
447
448 sel, start, vcur = print_table(file_t, count, settings)
449
450 if sel > 1 and file_t[sel] then -- flips between hex and decimal
451 local s = file_t[sel]
452 if s:sub(-1) == "\b" then
453 file_t[sel] = nil
454 ovf = -(bufsz - 1)
455 coroutine.resume(co, sel) --rebuild this item
456 else
457 s = s:gsub("(0x%x+:)", repl) .. "\b"
458 file_t[sel] = s:gsub("(%x%x%s)", repl) .. "\b"
459 end
460 end
461 end
462
463 file:close()
464 idx_t = nil
465 file_t = nil
466 return sel
467end -- print_file_hex
468--------------------------------------------------------------------------------