Merge remote branch 'hwhw/master'

* hwhw/master:
  fix a Lua 5.0 syntax that was deprecated in 5.1
  separate DC out of pdf.c and djvu.c (cleanup)
  removed obsolete page rotation handling, closes #70
  allow easier customization of toolchain for libdjvu
  fix: remove page number checking in displaying TOC
  fix: handle LPGBCK and LPGFWD in selectmenu
pull/2/merge
traycold 12 years ago
commit 3d2a748aee

@ -13,6 +13,7 @@ LFSDIR=luafilesystem
CC:=arm-unknown-linux-gnueabi-gcc
CXX:=arm-unknown-linux-gnueabi-g++
HOST:=arm-unknown-linux-gnueabi
ifdef SBOX_UNAME_MACHINE
CC:=gcc
CXX:=g++
@ -133,7 +134,7 @@ $(DJVULIBS):
ifdef EMULATE_READER
cd $(DJVUDIR)/build && ../configure --disable-desktopfiles --disable-shared --enable-static
else
cd $(DJVUDIR)/build && ../configure --disable-desktopfiles --disable-shared --enable-static --host=arm-kindle-linux-gnueabi
cd $(DJVUDIR)/build && ../configure --disable-desktopfiles --disable-shared --enable-static --host=$(HOST)
endif
make -C $(DJVUDIR)/build

@ -366,12 +366,12 @@ static int paintRect(lua_State *L) {
return 0;
}
static const struct luaL_reg blitbuffer_func[] = {
static const struct luaL_Reg blitbuffer_func[] = {
{"new", newBlitBuffer},
{NULL, NULL}
};
static const struct luaL_reg blitbuffer_meth[] = {
static const struct luaL_Reg blitbuffer_meth[] = {
{"getWidth", getWidth},
{"getHeight", getHeight},
{"blitFrom", blitToBuffer},

106
djvu.c

@ -20,6 +20,7 @@
#include "string.h"
#include "blitbuffer.h"
#include "drawcontext.h"
#include "djvu.h"
#define MIN(a, b) ((a) < (b) ? (a) : (b))
@ -40,14 +41,6 @@ typedef struct DjvuPage {
DjvuDocument *doc;
} DjvuPage;
typedef struct DrawContext {
int rotate;
double zoom;
double gamma;
int offset_x;
int offset_y;
} DrawContext;
static int handle(lua_State *L, ddjvu_context_t *ctx, int wait)
{
@ -177,77 +170,6 @@ static int getTableOfContent(lua_State *L) {
return 1;
}
static int newDrawContext(lua_State *L) {
int rotate = luaL_optint(L, 1, 0);
double zoom = luaL_optnumber(L, 2, (double) 1.0);
int offset_x = luaL_optint(L, 3, 0);
int offset_y = luaL_optint(L, 4, 0);
double gamma = luaL_optnumber(L, 5, (double) -1.0);
DrawContext *dc = (DrawContext*) lua_newuserdata(L, sizeof(DrawContext));
dc->rotate = rotate;
dc->zoom = zoom;
dc->offset_x = offset_x;
dc->offset_y = offset_y;
dc->gamma = gamma;
luaL_getmetatable(L, "drawcontext");
lua_setmetatable(L, -2);
return 1;
}
static int dcSetOffset(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
dc->offset_x = luaL_checkint(L, 2);
dc->offset_y = luaL_checkint(L, 3);
return 0;
}
static int dcGetOffset(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
lua_pushinteger(L, dc->offset_x);
lua_pushinteger(L, dc->offset_y);
return 2;
}
static int dcSetRotate(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
dc->rotate = luaL_checkint(L, 2);
return 0;
}
static int dcSetZoom(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
dc->zoom = luaL_checknumber(L, 2);
return 0;
}
static int dcGetRotate(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
lua_pushinteger(L, dc->rotate);
return 1;
}
static int dcGetZoom(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
lua_pushnumber(L, dc->zoom);
return 1;
}
static int dcSetGamma(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
dc->gamma = luaL_checknumber(L, 2);
return 0;
}
static int dcGetGamma(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
lua_pushnumber(L, dc->gamma);
return 1;
}
static int openPage(lua_State *L) {
ddjvu_status_t r;
DjvuDocument *doc = (DjvuDocument*) luaL_checkudata(L, 1, "djvudocument");
@ -405,13 +327,12 @@ static int drawPage(lua_State *L) {
return 0;
}
static const struct luaL_reg djvu_func[] = {
static const struct luaL_Reg djvu_func[] = {
{"openDocument", openDocument},
{"newDC", newDrawContext},
{NULL, NULL}
};
static const struct luaL_reg djvudocument_meth[] = {
static const struct luaL_Reg djvudocument_meth[] = {
{"openPage", openPage},
{"getPages", getNumberOfPages},
{"getTOC", getTableOfContent},
@ -420,7 +341,7 @@ static const struct luaL_reg djvudocument_meth[] = {
{NULL, NULL}
};
static const struct luaL_reg djvupage_meth[] = {
static const struct luaL_Reg djvupage_meth[] = {
{"getSize", getPageSize},
{"getUsedBBox", getUsedBBox},
{"close", closePage},
@ -429,18 +350,6 @@ static const struct luaL_reg djvupage_meth[] = {
{NULL, NULL}
};
static const struct luaL_reg drawcontext_meth[] = {
{"setRotate", dcSetRotate},
{"getRotate", dcGetRotate},
{"setZoom", dcSetZoom},
{"getZoom", dcGetZoom},
{"setOffset", dcSetOffset},
{"getOffset", dcGetOffset},
{"setGamma", dcSetGamma},
{"getGamma", dcGetGamma},
{NULL, NULL}
};
int luaopen_djvu(lua_State *L) {
luaL_newmetatable(L, "djvudocument");
lua_pushstring(L, "__index");
@ -456,13 +365,6 @@ int luaopen_djvu(lua_State *L) {
luaL_register(L, NULL, djvupage_meth);
lua_pop(L, 1);
luaL_newmetatable(L, "drawcontext");
lua_pushstring(L, "__index");
lua_pushvalue(L, -2);
lua_settable(L, -3);
luaL_register(L, NULL, drawcontext_meth);
lua_pop(L, 1);
luaL_register(L, "djvu", djvu_func);
return 1;
}

@ -1,15 +1,6 @@
require "unireader"
DJVUReader = UniReader:new{
newDC = function()
print("djvu.newDC")
return djvu.newDC()
end,
}
function DJVUReader:init()
self.nulldc = self.newDC()
end
DJVUReader = UniReader:new{}
-- open a DJVU file and its settings store
-- DJVU does not support password yet

@ -0,0 +1,117 @@
/*
KindlePDFViewer: a DC abstraction
Copyright (C) 2012 Hans-Werner Hilse <hilse@web.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "drawcontext.h"
static int newDrawContext(lua_State *L) {
int rotate = luaL_optint(L, 1, 0);
double zoom = luaL_optnumber(L, 2, (double) 1.0);
int offset_x = luaL_optint(L, 3, 0);
int offset_y = luaL_optint(L, 4, 0);
double gamma = luaL_optnumber(L, 5, (double) -1.0);
DrawContext *dc = (DrawContext*) lua_newuserdata(L, sizeof(DrawContext));
dc->rotate = rotate;
dc->zoom = zoom;
dc->offset_x = offset_x;
dc->offset_y = offset_y;
dc->gamma = gamma;
luaL_getmetatable(L, "drawcontext");
lua_setmetatable(L, -2);
return 1;
}
static int dcSetOffset(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
dc->offset_x = luaL_checkint(L, 2);
dc->offset_y = luaL_checkint(L, 3);
return 0;
}
static int dcGetOffset(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
lua_pushinteger(L, dc->offset_x);
lua_pushinteger(L, dc->offset_y);
return 2;
}
static int dcSetRotate(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
dc->rotate = luaL_checkint(L, 2);
return 0;
}
static int dcSetZoom(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
dc->zoom = luaL_checknumber(L, 2);
return 0;
}
static int dcGetRotate(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
lua_pushinteger(L, dc->rotate);
return 1;
}
static int dcGetZoom(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
lua_pushnumber(L, dc->zoom);
return 1;
}
static int dcSetGamma(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
dc->gamma = luaL_checknumber(L, 2);
return 0;
}
static int dcGetGamma(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
lua_pushnumber(L, dc->gamma);
return 1;
}
static const struct luaL_Reg drawcontext_meth[] = {
{"setRotate", dcSetRotate},
{"getRotate", dcGetRotate},
{"setZoom", dcSetZoom},
{"getZoom", dcGetZoom},
{"setOffset", dcSetOffset},
{"getOffset", dcGetOffset},
{"setGamma", dcSetGamma},
{"getGamma", dcGetGamma},
{NULL, NULL}
};
static const struct luaL_Reg drawcontext_func[] = {
{"new", newDrawContext},
{NULL, NULL}
};
int luaopen_drawcontext(lua_State *L) {
luaL_newmetatable(L, "drawcontext");
lua_pushstring(L, "__index");
lua_pushvalue(L, -2);
lua_settable(L, -3);
luaL_register(L, NULL, drawcontext_meth);
lua_pop(L, 1);
luaL_register(L, "DrawContext", drawcontext_func);
return 1;
}

@ -0,0 +1,35 @@
/*
KindlePDFViewer: a DC abstraction
Copyright (C) 2012 Hans-Werner Hilse <hilse@web.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _DRAWCONTEXT_H
#define _DRAWCONTEXT_H
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
typedef struct DrawContext {
int rotate;
double zoom;
double gamma;
int offset_x;
int offset_y;
} DrawContext;
int luaopen_drawcontext(lua_State *L);
#endif

@ -203,12 +203,12 @@ static int einkSetOrientation(lua_State *L) {
}
static const struct luaL_reg einkfb_func[] = {
static const struct luaL_Reg einkfb_func[] = {
{"open", openFrameBuffer},
{NULL, NULL}
};
static const struct luaL_reg einkfb_meth[] = {
static const struct luaL_Reg einkfb_meth[] = {
{"close", closeFrameBuffer},
{"__gc", closeFrameBuffer},
{"refresh", einkUpdate},

@ -181,7 +181,7 @@ static int doneFace(lua_State *L) {
return 0;
}
static const struct luaL_reg ft_face_meth[] = {
static const struct luaL_Reg ft_face_meth[] = {
{"renderGlyph", renderGlyph},
{"hasKerning", hasKerning},
{"getKerning", getKerning},
@ -190,7 +190,7 @@ static const struct luaL_reg ft_face_meth[] = {
{NULL, NULL}
};
static const struct luaL_reg ft_func[] = {
static const struct luaL_Reg ft_func[] = {
{"newFace", newFace},
{"newBuiltinFace", newBuiltinFace},
{NULL, NULL}

@ -144,7 +144,7 @@ static int waitForInput(lua_State *L) {
#endif
}
static const struct luaL_reg input_func[] = {
static const struct luaL_Reg input_func[] = {
{"open", openInputDevice},
{"closeAll", closeInputDevices},
{"waitForEvent", waitForInput},

@ -24,6 +24,7 @@
#include <lauxlib.h>
#include "blitbuffer.h"
#include "drawcontext.h"
#include "pdf.h"
#include "einkfb.h"
#include "input.h"
@ -48,6 +49,7 @@ int main(int argc, char **argv) {
luaL_openlibs(L);
luaopen_blitbuffer(L);
luaopen_drawcontext(L);
luaopen_einkfb(L);
luaopen_pdf(L);
luaopen_djvu(L);

119
pdf.c

@ -19,6 +19,7 @@
#include <pdf/mupdf.h>
#include "blitbuffer.h"
#include "drawcontext.h"
#include "pdf.h"
typedef struct PdfDocument {
@ -36,14 +37,6 @@ typedef struct PdfPage {
PdfDocument *doc;
} PdfPage;
typedef struct DrawContext {
int rotate;
double zoom;
double gamma;
int offset_x;
int offset_y;
} DrawContext;
static int openDocument(lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *password = luaL_checkstring(L, 2);
@ -101,16 +94,17 @@ static int walkTableOfContent(lua_State *L, fz_outline* ol, int *count, int dept
lua_pushstring(L, "page");
lua_pushnumber(L, ol->dest.ld.gotor.page + 1);
lua_settable(L, -3);
lua_pushstring(L, "depth");
lua_pushnumber(L, depth);
lua_settable(L, -3);
lua_pushstring(L, "title");
lua_pushstring(L, "title");
lua_pushstring(L, ol->title);
lua_settable(L, -3);
lua_settable(L, -3);
lua_settable(L, -3);
(*count)++;
if (ol->down) {
walkTableOfContent(L, ol->down, count, depth);
@ -139,76 +133,6 @@ static int getTableOfContent(lua_State *L) {
return 1;
}
static int newDrawContext(lua_State *L) {
int rotate = luaL_optint(L, 1, 0);
double zoom = luaL_optnumber(L, 2, (double) 1.0);
int offset_x = luaL_optint(L, 3, 0);
int offset_y = luaL_optint(L, 4, 0);
double gamma = luaL_optnumber(L, 5, (double) -1.0);
DrawContext *dc = (DrawContext*) lua_newuserdata(L, sizeof(DrawContext));
dc->rotate = rotate;
dc->zoom = zoom;
dc->offset_x = offset_x;
dc->offset_y = offset_y;
dc->gamma = gamma;
luaL_getmetatable(L, "drawcontext");
lua_setmetatable(L, -2);
return 1;
}
static int dcSetOffset(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
dc->offset_x = luaL_checkint(L, 2);
dc->offset_y = luaL_checkint(L, 3);
return 0;
}
static int dcGetOffset(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
lua_pushinteger(L, dc->offset_x);
lua_pushinteger(L, dc->offset_y);
return 2;
}
static int dcSetRotate(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
dc->rotate = luaL_checkint(L, 2);
return 0;
}
static int dcSetZoom(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
dc->zoom = luaL_checknumber(L, 2);
return 0;
}
static int dcGetRotate(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
lua_pushinteger(L, dc->rotate);
return 1;
}
static int dcGetZoom(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
lua_pushnumber(L, dc->zoom);
return 1;
}
static int dcSetGamma(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
dc->gamma = luaL_checknumber(L, 2);
return 0;
}
static int dcGetGamma(lua_State *L) {
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext");
lua_pushnumber(L, dc->gamma);
return 1;
}
static int openPage(lua_State *L) {
fz_device *dev;
@ -239,15 +163,15 @@ static int openPage(lua_State *L) {
static int getPageSize(lua_State *L) {
fz_matrix ctm;
fz_rect bounds;
fz_rect bbox;
PdfPage *page = (PdfPage*) luaL_checkudata(L, 1, "pdfpage");
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 2, "drawcontext");
ctm = fz_translate(0, -page->page->mediabox.y1);
ctm = fz_concat(ctm, fz_scale(dc->zoom, -dc->zoom));
ctm = fz_concat(ctm, fz_rotate(page->page->rotate));
bounds = fz_bound_page(page->doc->xref, page->page);
ctm = fz_scale(dc->zoom, dc->zoom) ;
ctm = fz_concat(ctm, fz_rotate(dc->rotate));
bbox = fz_transform_rect(ctm, page->page->mediabox);
bbox = fz_transform_rect(ctm, bounds);
lua_pushnumber(L, bbox.x1-bbox.x0);
lua_pushnumber(L, bbox.y1-bbox.y0);
@ -263,7 +187,6 @@ static int getUsedBBox(lua_State *L) {
/* returned BBox is in centi-point (n * 0.01 pt) */
ctm = fz_scale(100, 100);
ctm = fz_concat(ctm, fz_rotate(page->page->rotate));
fz_try(page->doc->context) {
dev = fz_new_bbox_device(page->doc->context, &result);
@ -311,7 +234,6 @@ static int drawPage(lua_State *L) {
fz_clear_pixmap_with_value(page->doc->context, pix, 0xff);
ctm = fz_scale(dc->zoom, dc->zoom);
ctm = fz_concat(ctm, fz_rotate(page->page->rotate));
ctm = fz_concat(ctm, fz_rotate(dc->rotate));
ctm = fz_concat(ctm, fz_translate(dc->offset_x, dc->offset_y));
dev = fz_new_draw_device(page->doc->context, pix);
@ -352,13 +274,12 @@ static int drawPage(lua_State *L) {
return 0;
}
static const struct luaL_reg pdf_func[] = {
static const struct luaL_Reg pdf_func[] = {
{"openDocument", openDocument},
{"newDC", newDrawContext},
{NULL, NULL}
};
static const struct luaL_reg pdfdocument_meth[] = {
static const struct luaL_Reg pdfdocument_meth[] = {
{"openPage", openPage},
{"getPages", getNumberOfPages},
{"getTOC", getTableOfContent},
@ -367,7 +288,7 @@ static const struct luaL_reg pdfdocument_meth[] = {
{NULL, NULL}
};
static const struct luaL_reg pdfpage_meth[] = {
static const struct luaL_Reg pdfpage_meth[] = {
{"getSize", getPageSize},
{"getUsedBBox", getUsedBBox},
{"close", closePage},
@ -376,18 +297,6 @@ static const struct luaL_reg pdfpage_meth[] = {
{NULL, NULL}
};
static const struct luaL_reg drawcontext_meth[] = {
{"setRotate", dcSetRotate},
{"getRotate", dcGetRotate},
{"setZoom", dcSetZoom},
{"getZoom", dcGetZoom},
{"setOffset", dcSetOffset},
{"getOffset", dcGetOffset},
{"setGamma", dcSetGamma},
{"getGamma", dcGetGamma},
{NULL, NULL}
};
int luaopen_pdf(lua_State *L) {
luaL_newmetatable(L, "pdfdocument");
lua_pushstring(L, "__index");
@ -401,12 +310,6 @@ int luaopen_pdf(lua_State *L) {
lua_settable(L, -3);
luaL_register(L, NULL, pdfpage_meth);
lua_pop(L, 1);
luaL_newmetatable(L, "drawcontext");
lua_pushstring(L, "__index");
lua_pushvalue(L, -2);
lua_settable(L, -3);
luaL_register(L, NULL, drawcontext_meth);
lua_pop(L, 1);
luaL_register(L, "pdf", pdf_func);
return 1;
}

@ -1,15 +1,6 @@
require "unireader"
PDFReader = UniReader:new{
newDC = function()
print("pdf.newDC")
return pdf.newDC()
end,
}
function PDFReader:init()
self.nulldc = self.newDC();
end
PDFReader = UniReader:new{}
-- open a PDF file and its settings store
function PDFReader:open(filename, password)

@ -195,7 +195,7 @@ function SelectMenu:choose(ypos, height)
prevItem()
elseif ev.code == KEY_FW_DOWN then
nextItem()
elseif ev.code == KEY_PGFWD then
elseif ev.code == KEY_PGFWD or ev.code == KEY_LPGFWD then
if self.page < (self.items / perpage) then
if self.current + self.page*perpage > self.items then
self.current = self.items - self.page*perpage
@ -206,7 +206,7 @@ function SelectMenu:choose(ypos, height)
self.current = self.items - (self.page-1)*perpage
markerdirty = true
end
elseif ev.code == KEY_PGBCK then
elseif ev.code == KEY_PGBCK or ev.code == KEY_LPGBCK then
if self.page > 1 then
self.page = self.page - 1
pagedirty = true

@ -59,10 +59,8 @@ UniReader = {
-- list of available commands:
commands = nil,
-- you have to initialize newDC, nulldc in specific reader
newDC = function() return nil end,
-- we will use this one often, so keep it "static":
nulldc = nil,
nulldc = DrawContext.new(),
-- tile cache configuration:
cache_max_memsize = 1024*1024*5, -- 5MB tile cache
@ -91,13 +89,11 @@ end
For a new specific reader,
you must always overwrite following two methods:
* self:init()
* self:open()
overwrite other methods if needed.
--]]
function UniReader:init()
print("empty initialization method!")
end
-- open a file and its settings store
@ -292,7 +288,7 @@ end
-- set viewer state according to zoom state
function UniReader:setzoom(page)
local dc = self.newDC()
local dc = DrawContext.new()
local pwidth, pheight = page:getSize(self.nulldc)
print("# page::getSize "..pwidth.."*"..pheight);
local x0, y0, x1, y1 = page:getUsedBBox()
@ -684,15 +680,11 @@ function UniReader:showTOC()
end
local menu_items = {}
local filtered_toc = {}
local curr_page = -1
-- build menu items
for _k,_v in ipairs(self.toc) do
if(_v.page >= curr_page) then
table.insert(menu_items,
(" "):rep(_v.depth-1)..self:cleanUpTOCTitle(_v.title))
table.insert(filtered_toc,_v.page)
curr_page = _v.page
end
table.insert(menu_items,
(" "):rep(_v.depth-1)..self:cleanUpTOCTitle(_v.title))
table.insert(filtered_toc,_v.page)
end
toc_menu = SelectMenu:new{
menu_title = "Table of Contents",

@ -46,7 +46,7 @@ static int utf8charcode(lua_State *L) {
return 1;
}
static const struct luaL_reg util_func[] = {
static const struct luaL_Reg util_func[] = {
{"gettime", gettime},
{"utf8charcode", utf8charcode},
{NULL, NULL}

Loading…
Cancel
Save