/* $Id: lstatslib.c 1013 2008-02-14 00:09:02Z oneiros $ */ #include "luatex-api.h" #include typedef struct statistic { const char *name; char type; void *value; } statistic ; extern char *ptexbanner; /* extern string getcurrentfilenamestring; */ typedef char * (*charfunc)(void); typedef integer (*intfunc)(void); char *getbanner (void) { return ptexbanner; } /* hack, I really should implement the makecstring */ char *getfilename (void) { integer t; t = get_current_name(); if (t>(1<<21)) return makecstring(t); else return xstrdup (""); } char *getlasterror (void) { return makecstring(last_error); } extern int luabytecode_max; extern int luabytecode_bytes; extern int luastate_max; extern int luastate_bytes; static struct statistic stats[] = { { "pdf_gone", 'g', &pdf_gone }, { "pdf_ptr", 'g', &pdf_ptr }, { "dvi_gone", 'g', &dvi_offset }, { "dvi_ptr", 'g', &dvi_ptr }, { "total_pages", 'g', &total_pages }, { "output_file_name", 's', &output_file_name }, { "log_name", 's', &texmf_log_name }, /* weird */ { "banner", 'S', &getbanner }, { "pdftex_banner", 's', &pdftex_banner }, /* * mem stat */ { "var_used", 'g', &var_used }, { "dyn_used", 'g', &dyn_used }, /* * traditional tex stats */ { "str_ptr", 'g', &str_ptr }, { "init_str_ptr", 'g', &init_str_ptr }, { "max_strings", 'g', &max_strings }, { "pool_ptr", 'g', &pool_ptr }, { "init_pool_ptr", 'g', &init_pool_ptr }, { "pool_size", 'g', &pool_size }, { "var_mem_max", 'g', &var_mem_max }, { "node_mem_usage", 'S', &sprint_node_mem_usage }, { "fix_mem_max", 'g', &fix_mem_max }, { "fix_mem_min", 'g', &fix_mem_min }, { "fix_mem_end", 'g', &fix_mem_end }, { "cs_count", 'g', &cs_count }, { "hash_size", 'G', &get_hash_size }, { "hash_extra", 'g', &hash_extra }, { "font_ptr", 'G', &max_font_id }, { "max_in_stack", 'g', &max_in_stack }, { "max_nest_stack", 'g', &max_nest_stack }, { "max_param_stack", 'g', &max_param_stack }, { "max_buf_stack", 'g', &max_buf_stack }, { "max_save_stack", 'g', &max_save_stack }, { "stack_size", 'g', &stack_size }, { "nest_size", 'g', &nest_size }, { "param_size", 'g', ¶m_size }, { "buf_size", 'g', &buf_size }, { "save_size", 'g', &save_size }, /* pdf stats */ { "obj_ptr", 'g', &obj_ptr }, { "obj_tab_size", 'g', &obj_tab_size }, { "pdf_os_cntr", 'g', &pdf_os_cntr }, { "pdf_os_objidx", 'g', &pdf_os_objidx }, { "pdf_dest_names_ptr", 'g', &pdf_dest_names_ptr }, { "dest_names_size", 'g', &dest_names_size }, { "pdf_mem_ptr", 'g', &pdf_mem_ptr }, { "pdf_mem_size", 'g', &pdf_mem_size }, { "largest_used_mark", 'g', &biggest_used_mark }, { "filename", 'S', &getfilename }, { "inputid", 'G', &get_current_name }, { "linenumber", 'g', &line }, { "lasterrorstring", 'S', &getlasterror }, { "luabytecodes", 'g', &luabytecode_max }, { "luabytecode_bytes", 'g', &luabytecode_bytes }, { "luastates", 'g', &luastate_max }, { "luastate_bytes", 'g', &luastate_bytes }, { "output_active", 'b', &output_active }, { NULL, 0 , 0 } }; static int stats_name_to_id (char *name) { int i; for (i=0; stats[i].name!=NULL; i++) { if (strcmp(stats[i].name, name) == 0) return i; } return 0; } static int do_getstat (lua_State *L,int i) { int t; char *st; charfunc f; intfunc g; int str; t = stats[i].type; switch(t) { case 'S': f = stats[i].value; st = f(); lua_pushstring(L,st); break; case 's': str = *(integer *)(stats[i].value); if (str) { lua_pushstring(L,makecstring(str)); } else { lua_pushnil(L); } break; case 'G': g = stats[i].value; lua_pushnumber(L,g()); break; case 'g': lua_pushnumber(L,*(integer *)(stats[i].value)); break; case 'B': g = stats[i].value; lua_pushboolean(L,g()); break; case 'b': lua_pushboolean(L,*(integer *)(stats[i].value)); break; default: lua_pushnil(L); } return 1; } static int getstats (lua_State *L) { char *st; int i; if (lua_isstring(L,-1)) { st = (char *)lua_tostring(L,-1); i = stats_name_to_id(st); if (i>0) { return do_getstat(L,i); } } return 0; } static int setstats (lua_State *L) { return 0; } static int statslist (lua_State *L) { int i; luaL_checkstack(L,1,"out of stack space"); lua_newtable(L); for (i=0; stats[i].name!=NULL; i++) { luaL_checkstack(L,2,"out of stack space"); lua_pushstring(L,stats[i].name); do_getstat(L,i); lua_rawset(L,-3); } return 1; } static const struct luaL_reg statslib [] = { {"list",statslist}, {NULL, NULL} /* sentinel */ }; int luaopen_stats (lua_State *L) { luaL_register(L, "status", statslib); luaL_newmetatable(L,"stats_meta"); lua_pushstring(L, "__index"); lua_pushcfunction(L, getstats); lua_settable(L, -3); lua_pushstring(L, "__newindex"); lua_pushcfunction(L, setstats); lua_settable(L, -3); lua_setmetatable(L,-2); /* meta to itself */ return 1; }