beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / lua / lstatslib.c
blob7c6e1bda2b8eddd6005bfe7b87a2fe3a5b5cf0ac
1 /* lstatslib.c
3 Copyright 2006-2011 Taco Hoekwater <taco@luatex.org>
5 This file is part of LuaTeX.
7 LuaTeX is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2 of the License, or (at your
10 option) any later version.
12 LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License along
18 with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
21 #include "ptexlib.h"
22 #include "lua/luatex-api.h"
24 typedef struct statistic {
25 const char *name;
26 char type;
27 void *value;
28 } statistic;
30 typedef const char *(*charfunc) (void);
31 typedef lua_Number(*numfunc) (void);
32 typedef int (*intfunc) (void);
34 static const char *getbanner(void)
36 return (const char *) luatex_banner;
39 static const char *getlogname(void)
41 return (const char *) texmf_log_name;
44 static const char *get_output_file_name(void)
46 if (static_pdf != NULL)
47 return (const char *) static_pdf->file_name;
48 return NULL;
52 static const char *getfilename(void)
54 int t = 0;
55 int level = in_open;
56 while ((level > 0)) {
57 t = input_stack[level--].name_field;
58 if (t >= STRING_OFFSET) {
59 return (const char *) str_string(t);
62 return "";
66 static const char *getfilename(void)
68 const char * s;
69 int level, t;
70 level = in_open;
71 while ((level > 0)) {
72 s = full_source_filename_stack[level--];
73 if (s != NULL) {
74 return s;
77 /* old method */
78 level = in_open;
79 while ((level > 0)) {
80 t = input_stack[level--].name_field;
81 if (t >= STRING_OFFSET) {
82 return (const char *) str_string(t);
85 return "";
89 static const char *getlasterror(void)
91 return last_error;
94 static const char *getlastluaerror(void)
96 return last_lua_error;
99 static const char *getlastwarningtag(void)
101 return last_warning_tag;
104 static const char *getlastwarningstr(void)
106 return last_warning_str;
109 static const char *getlasterrorcontext(void)
111 return last_error_context;
114 static const char *luatexrevision(void)
116 return (const char *) (strrchr(luatex_version_string, '.') + 1);
119 static lua_Number get_luatexhashchars(void)
121 return (lua_Number) LUAI_HASHLIMIT;
124 static const char *get_luatexhashtype(void)
126 #ifdef LuajitTeX
127 return (const char *)jithash_hashname;
128 #else
129 return "lua";
130 #endif
134 static lua_Number get_pdf_gone(void)
136 if (static_pdf != NULL)
137 return (lua_Number) static_pdf->gone;
138 return (lua_Number) 0;
141 static lua_Number get_pdf_ptr(void)
143 if (static_pdf != NULL)
144 return (lua_Number) (static_pdf->buf->p - static_pdf->buf->data);
145 return (lua_Number) 0;
148 static lua_Number get_pdf_os_cntr(void)
150 if (static_pdf != NULL)
151 return (lua_Number) static_pdf->os->ostm_ctr;
152 return (lua_Number) 0;
155 static lua_Number get_pdf_os_objidx(void)
157 if (static_pdf != NULL)
158 return (lua_Number) static_pdf->os->idx;
159 return (lua_Number) 0;
162 static lua_Number get_pdf_mem_size(void)
164 if (static_pdf != NULL)
165 return (lua_Number) static_pdf->mem_size;
166 return (lua_Number) 0;
169 static lua_Number get_pdf_mem_ptr(void)
171 if (static_pdf != NULL)
172 return (lua_Number) static_pdf->mem_ptr;
173 return (lua_Number) 0;
176 static lua_Number get_obj_ptr(void)
178 if (static_pdf != NULL)
179 return (lua_Number) static_pdf->obj_ptr;
180 return (lua_Number) 0;
183 static lua_Number get_obj_tab_size(void)
185 if (static_pdf != NULL)
186 return (lua_Number) static_pdf->obj_tab_size;
187 return (lua_Number) 0;
190 static lua_Number get_dest_names_size(void)
192 if (static_pdf != NULL)
193 return (lua_Number) static_pdf->dest_names_size;
194 return (lua_Number) 0;
197 static lua_Number get_dest_names_ptr(void)
199 if (static_pdf != NULL)
200 return (lua_Number) static_pdf->dest_names_ptr;
201 return (lua_Number) 0;
204 static int get_hash_size(void)
206 return hash_size; /* is a #define */
209 static lua_Number shell_escape_state(void)
211 if (shellenabledp <= 0) {
212 return (lua_Number) 0;
213 } else if (restrictedshell == 0) {
214 return (lua_Number) 1;
215 } else {
216 return (lua_Number) 2;
220 static int luastate_max = 1; /* fixed value */
222 /* temp, for backward compat */
223 static int init_pool_ptr = 0;
225 static struct statistic stats[] = {
227 /* most likely accessed */
229 {"output_active", 'b', &output_active},
230 {"best_page_break", 'n', &best_page_break},
232 {"filename", 'S', (void *) &getfilename},
233 {"inputid", 'g', &(iname)},
234 {"linenumber", 'g', &line},
236 {"lasterrorstring", 'S', (void *) &getlasterror},
237 {"lastluaerrorstring", 'S', (void *) &getlastluaerror},
238 {"lastwarningtag", 'S', (void *) &getlastwarningtag},
239 {"lastwarningstring", 'S', (void *) &getlastwarningstr},
240 {"lasterrorcontext", 'S', (void *) &getlasterrorcontext},
242 /* seldom or never accessed */
244 {"pdf_gone", 'N', &get_pdf_gone},
245 {"pdf_ptr", 'N', &get_pdf_ptr},
246 {"dvi_gone", 'g', &dvi_offset},
247 {"dvi_ptr", 'g', &dvi_ptr},
248 {"total_pages", 'g', &total_pages},
249 {"output_file_name", 'S', (void *) &get_output_file_name},
250 {"log_name", 'S', (void *) &getlogname},
251 {"banner", 'S', (void *) &getbanner},
252 {"luatex_version", 'G', &get_luatexversion},
253 {"luatex_revision", 'S', (void *) &luatexrevision},
254 {"luatex_hashtype", 'S', (void *) &get_luatexhashtype},
255 {"luatex_hashchars", 'N', &get_luatexhashchars},
257 {"ini_version", 'b', &ini_version},
259 {"shell_escape", 'N', &shell_escape_state}, /* be easy on old time usage */
261 * mem stat
263 {"var_used", 'g', &var_used},
264 {"dyn_used", 'g', &dyn_used},
266 * traditional tex stats
268 {"str_ptr", 'g', &str_ptr},
269 {"init_str_ptr", 'g', &init_str_ptr},
270 {"max_strings", 'g', &max_strings},
271 {"pool_ptr", 'g', &pool_size},
272 {"init_pool_ptr", 'g', &init_pool_ptr},
273 {"pool_size", 'g', &pool_size},
274 {"var_mem_max", 'g', &var_mem_max},
275 {"node_mem_usage", 'S', &sprint_node_mem_usage},
276 {"fix_mem_max", 'g', &fix_mem_max},
277 {"fix_mem_min", 'g', &fix_mem_min},
278 {"fix_mem_end", 'g', &fix_mem_end},
279 {"cs_count", 'g', &cs_count},
280 {"hash_size", 'G', &get_hash_size},
281 {"hash_extra", 'g', &hash_extra},
282 {"font_ptr", 'G', &max_font_id},
283 {"max_in_stack", 'g', &max_in_stack},
284 {"max_nest_stack", 'g', &max_nest_stack},
285 {"max_param_stack", 'g', &max_param_stack},
286 {"max_buf_stack", 'g', &max_buf_stack},
287 {"max_save_stack", 'g', &max_save_stack},
288 {"stack_size", 'g', &stack_size},
289 {"nest_size", 'g', &nest_size},
290 {"param_size", 'g', &param_size},
291 {"buf_size", 'g', &buf_size},
292 {"save_size", 'g', &save_size},
293 {"input_ptr", 'g', &input_ptr},
294 {"obj_ptr", 'N', &get_obj_ptr},
295 {"obj_tab_size", 'N', &get_obj_tab_size},
296 {"pdf_os_cntr", 'N', &get_pdf_os_cntr},
297 {"pdf_os_objidx", 'N', &get_pdf_os_objidx},
298 {"pdf_dest_names_ptr", 'N', &get_dest_names_ptr},
299 {"dest_names_size", 'N', &get_dest_names_size},
300 {"pdf_mem_ptr", 'N', &get_pdf_mem_ptr},
301 {"pdf_mem_size", 'N', &get_pdf_mem_size},
302 {"largest_used_mark", 'g', &biggest_used_mark},
303 {"luabytecodes", 'g', &luabytecode_max},
304 {"luabytecode_bytes", 'g', &luabytecode_bytes},
305 {"luastates", 'g', &luastate_max},
306 {"luastate_bytes", 'g', &luastate_bytes},
307 {"callbacks", 'g', &callback_count},
308 {"indirect_callbacks", 'g', &saved_callback_count},
310 {NULL, 0, 0}
313 static int stats_name_to_id(const char *name)
315 int i;
316 for (i = 0; stats[i].name != NULL; i++) {
317 if (strcmp(stats[i].name, name) == 0)
318 return i;
320 return -1;
323 static int do_getstat(lua_State * L, int i)
325 int t;
326 const char *st;
327 charfunc f;
328 intfunc g;
329 numfunc n;
330 int str;
331 t = stats[i].type;
332 switch (t) {
333 case 'S':
334 f = stats[i].value;
335 st = f();
336 lua_pushstring(L, st);
337 break;
338 case 's':
339 str = *(int *) (stats[i].value);
340 if (str) {
341 char *ss = makecstring(str);
342 lua_pushstring(L, ss);
343 free(ss);
344 } else {
345 lua_pushnil(L);
347 break;
348 case 'N':
349 n = stats[i].value;
350 lua_pushinteger(L, n());
351 break;
352 case 'G':
353 g = stats[i].value;
354 lua_pushinteger(L, g());
355 break;
356 case 'g':
357 lua_pushinteger(L, *(int *) (stats[i].value));
358 break;
359 case 'B':
360 g = stats[i].value;
361 lua_pushboolean(L, g());
362 break;
363 case 'n':
364 if (*(halfword *) (stats[i].value) != 0)
365 lua_nodelib_push_fast(L, *(halfword *) (stats[i].value));
366 else
367 lua_pushnil(L);
368 break;
369 case 'b':
370 lua_pushboolean(L, *(int *) (stats[i].value));
371 break;
372 default:
373 lua_pushnil(L);
375 return 1;
378 static int getstats(lua_State * L)
380 const char *st;
381 int i;
382 if (lua_type(L,-1) == LUA_TSTRING) {
383 st = lua_tostring(L, -1);
384 i = stats_name_to_id(st);
385 if (i >= 0) {
386 return do_getstat(L, i);
389 return 0;
392 static int setstats(lua_State * L)
394 (void) L;
395 return 0;
398 static int statslist(lua_State * L)
400 int i;
401 luaL_checkstack(L, 1, "out of stack space");
402 lua_newtable(L);
403 for (i = 0; stats[i].name != NULL; i++) {
404 luaL_checkstack(L, 2, "out of stack space");
405 lua_pushstring(L, stats[i].name);
406 do_getstat(L, i);
407 lua_rawset(L, -3);
409 return 1;
412 static int resetmessages(lua_State * L)
414 xfree(last_warning_str);
415 xfree(last_warning_tag);
416 xfree(last_error);
417 xfree(last_lua_error);
418 last_warning_str = NULL;
419 last_warning_tag = NULL;
420 last_error = NULL;
421 last_lua_error = NULL;
422 return 0;
425 static const struct luaL_Reg statslib[] = {
426 {"list", statslist},
427 {"resetmessages", resetmessages},
428 {NULL, NULL} /* sentinel */
431 int luaopen_stats(lua_State * L)
433 luaL_register(L, "status", statslib);
434 luaL_newmetatable(L, "tex.stats");
435 lua_pushstring(L, "__index");
436 lua_pushcfunction(L, getstats);
437 lua_settable(L, -3);
438 lua_pushstring(L, "__newindex");
439 lua_pushcfunction(L, setstats);
440 lua_settable(L, -3);
441 lua_setmetatable(L, -2); /* meta to itself */
442 return 1;