From 6e0f0aef26e4c9a1f4db5d3a80c85c90f1b3a0e1 Mon Sep 17 00:00:00 2001 From: Tigran Aivazian Date: Mon, 24 Sep 2012 19:48:12 +0100 Subject: [PATCH 1/4] Fix a crash in getDiskSizeInfo() and use util.df function 1. When executed in the emulator the viewer will crash if you press Right on any zip file in the filechooser. This is because the assertion on "df /mnt/us | tail -1" will fail as "/mnt/us" is normally non-existent. 2. The proper (faster, reliable, portable) way of obtaining the number of total and free bytes on a filesystem is by using the statvfs(2) system call via util.df Lua interface, see util.c. 3. Removed the "used" field in the function's return as unused and unneeded. --- fileinfo.lua | 11 ++--------- util.c | 3 ++- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/fileinfo.lua b/fileinfo.lua index 10027b3c1..7894a0d62 100644 --- a/fileinfo.lua +++ b/fileinfo.lua @@ -46,15 +46,8 @@ function getUnpackedZipSize(zipfile) end function getDiskSizeInfo() - local s = {} - local tmp = assert(io.popen('df /mnt/us/ | tail -1', "r")) - local output = assert(tmp:read("*line")) - for w in string.gmatch(output, "%d+") do - s[#s+1] = tonumber(w)*1024 -- to return in bytes - end - tmp:close() - if #s < 3 then return nil end - return { total = s[1], used = s[2], free = s[3] } + local t, f = util.df(".") + return { total = t, free = f } end function FileInfo:formatDiskSizeInfo() diff --git a/util.c b/util.c index 6a61d3e22..6a2c80697 100644 --- a/util.c +++ b/util.c @@ -46,8 +46,9 @@ static int util_df(lua_State *L) { char *path = luaL_checkstring(L, 1); struct statvfs vfs; statvfs(path, &vfs); + lua_pushnumber(L, (double)vfs.f_blocks * (double)vfs.f_bsize); lua_pushnumber(L, (double)vfs.f_bfree * (double)vfs.f_bsize); - return 1; + return 2; } /* Turn UTF-8 char code to Unicode */ From 43cbcbf319f28b7afb0c01caaa2d03853c098a93 Mon Sep 17 00:00:00 2001 From: Tigran Aivazian Date: Mon, 24 Sep 2012 20:07:23 +0100 Subject: [PATCH 2/4] Rewrite CREReader:ZipContentExt() function. Technically, the only serious problem in this function was the code: local tmp = assert(io.popen('unzip -l \"'..fname..'\"', "r")) while tmp do s = tmp:read("*line") if i > 3 then tmp:close(); break; end i = i + 1 end It is meaningless to evaluate the truth of the return value of assert() and the above code gives the impression that it relies on the (undocumented and unreliable) fact that after tmp:close() tmp will be nil, even though in actual fact it does because it breaks out of the loop. However, having looked at the function I saw that the whole thing can be rewritten in a much simpler way: local tmp = assert(io.popen('unzip -l \"'..fname..'\" | head -4 | tail -1', "r")) s = tmp:read("*line") tmp:close() --- crereader.lua | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/crereader.lua b/crereader.lua index eb9a245cf..4a55200c4 100644 --- a/crereader.lua +++ b/crereader.lua @@ -35,19 +35,16 @@ function CREReader:init() self.default_font = default_font end end + -- inspect the zipfile content function CREReader:ZipContentExt(fname) local i, s = 1 - local tmp = assert(io.popen('unzip -l \"'..fname..'\"', "r")) - while tmp do - s = tmp:read("*line") - if i > 3 then tmp:close(); break; end - i = i + 1 - end + local tmp = assert(io.popen('unzip -l \"'..fname..'\" | head -4 | tail -1', "r")) + s = tmp:read("*line") + tmp:close() return s and string.lower(string.match(s, ".+%.([^.]+)")) end - -- open a CREngine supported file and its settings store function CREReader:open(filename) local ok From 47b056861b95ffc81614cf78f4b98c8cfb83a18b Mon Sep 17 00:00:00 2001 From: Tigran Aivazian Date: Mon, 24 Sep 2012 20:38:18 +0100 Subject: [PATCH 3/4] Slightly shorter and more Lua-idiomatic way of reading lines. --- fileinfo.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fileinfo.lua b/fileinfo.lua index 7894a0d62..d030c1cf9 100644 --- a/fileinfo.lua +++ b/fileinfo.lua @@ -62,9 +62,7 @@ function FileInfo:getFolderContent() InfoMessage:show("Scanning folder...", 1) local tmp = assert(io.popen('du -a \"'..self.pathfile..'\"', "r")) local dirs, files, books, size, name, output, ftype, j = -1, 0, 0, 0 - while true do - output = tmp:read("*line") - if not output then break end + for output in tmp:lines() do j = output:find("/") name = output:sub(j, -1) size = tonumber(output:sub(1, j-1)) -- in kB From 1e2429b3be2fc0dd06f333a7b1406b34cf159301 Mon Sep 17 00:00:00 2001 From: Tigran Aivazian Date: Mon, 24 Sep 2012 21:33:47 +0100 Subject: [PATCH 4/4] Fix for the issue #311. Children nodes that have no [apparent] parent should be adopted by the "_HEAD" i.e. the root of the whole tree. --- unireader.lua | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/unireader.lua b/unireader.lua index 5e4263714..1f1aa7363 100644 --- a/unireader.lua +++ b/unireader.lua @@ -1642,14 +1642,22 @@ function UniReader:fillToc() end elseif (v.depth == prev_depth) then --> k and prev are siblings parent[k] = parent[prev] - table.insert(self.toc_children[parent[k]], k) + if not self.toc_children[parent[k]] then + table.insert(self.toc_children[0],k) + else + table.insert(self.toc_children[parent[k]], k) + end else --> k and prev must have a common (possibly virtual) ancestor local par = parent[prev] while (self.toc[par].depth > v.depth) do par = parent[par] end parent[k] = parent[par] - table.insert(self.toc_children[parent[k]], k) + if not self.toc_children[parent[k]] then + table.insert(self.toc_children[0],k) + else + table.insert(self.toc_children[parent[k]], k) + end end prev = k prev_depth = self.toc[prev].depth