luatex 1.0.3 (the last round, we hope)
[luatex.git] / source / texk / web2c / luatexdir / lua / lstatslib.c
blob7473ca214a4da8c29904c468cdab7fb77379dee1
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 const char *getenginename(void)
121 return engine_name;
126 static lua_Number get_luatexhashchars(void)
128 return (lua_Number) LUAI_HASHLIMIT;
131 static const char *get_luatexhashtype(void)
133 #ifdef LuajitTeX
134 return (const char *)jithash_hashname;
135 #else
136 return "lua";
137 #endif
141 static lua_Number get_pdf_gone(void)
143 if (static_pdf != NULL)
144 return (lua_Number) static_pdf->gone;
145 return (lua_Number) 0;
148 static lua_Number get_pdf_ptr(void)
150 if (static_pdf != NULL)
151 return (lua_Number) (static_pdf->buf->p - static_pdf->buf->data);
152 return (lua_Number) 0;
155 static lua_Number get_pdf_os_cntr(void)
157 if (static_pdf != NULL)
158 return (lua_Number) static_pdf->os->ostm_ctr;
159 return (lua_Number) 0;
162 static lua_Number get_pdf_os_objidx(void)
164 if (static_pdf != NULL)
165 return (lua_Number) static_pdf->os->idx;
166 return (lua_Number) 0;
169 static lua_Number get_pdf_mem_size(void)
171 if (static_pdf != NULL)
172 return (lua_Number) static_pdf->mem_size;
173 return (lua_Number) 0;
176 static lua_Number get_pdf_mem_ptr(void)
178 if (static_pdf != NULL)
179 return (lua_Number) static_pdf->mem_ptr;
180 return (lua_Number) 0;
183 static lua_Number get_obj_ptr(void)
185 if (static_pdf != NULL)
186 return (lua_Number) static_pdf->obj_ptr;
187 return (lua_Number) 0;
190 static lua_Number get_obj_tab_size(void)
192 if (static_pdf != NULL)
193 return (lua_Number) static_pdf->obj_tab_size;
194 return (lua_Number) 0;
197 static lua_Number get_dest_names_size(void)
199 if (static_pdf != NULL)
200 return (lua_Number) static_pdf->dest_names_size;
201 return (lua_Number) 0;
204 static lua_Number get_dest_names_ptr(void)
206 if (static_pdf != NULL)
207 return (lua_Number) static_pdf->dest_names_ptr;
208 return (lua_Number) 0;
211 static int get_hash_size(void)
213 return hash_size; /* is a #define */
216 static lua_Number shell_escape_state(void)
218 if (shellenabledp <= 0) {
219 return (lua_Number) 0;
220 } else if (restrictedshell == 0) {
221 return (lua_Number) 1;
222 } else {
223 return (lua_Number) 2;
227 /* temp, for backward compat */
228 static int init_pool_ptr = 0;
230 static struct statistic stats[] = {
232 /* most likely accessed */
234 {"output_active", 'b', &output_active},
235 {"best_page_break", 'n', &best_page_break},
237 {"filename", 'S', (void *) &getfilename},
238 {"inputid", 'g', &(iname)},
239 {"linenumber", 'g', &line},
241 {"lasterrorstring", 'S', (void *) &getlasterror},
242 {"lastluaerrorstring", 'S', (void *) &getlastluaerror},
243 {"lastwarningtag", 'S', (void *) &getlastwarningtag},
244 {"lastwarningstring", 'S', (void *) &getlastwarningstr},
245 {"lasterrorcontext", 'S', (void *) &getlasterrorcontext},
247 /* seldom or never accessed */
249 {"pdf_gone", 'N', &get_pdf_gone},
250 {"pdf_ptr", 'N', &get_pdf_ptr},
251 {"dvi_gone", 'g', &dvi_offset},
252 {"dvi_ptr", 'g', &dvi_ptr},
253 {"total_pages", 'g', &total_pages},
254 {"output_file_name", 'S', (void *) &get_output_file_name},
255 {"log_name", 'S', (void *) &getlogname},
256 {"banner", 'S', (void *) &getbanner},
257 {"luatex_version", 'G', &get_luatexversion},
258 {"luatex_revision", 'S', (void *) &luatexrevision},
259 {"luatex_hashtype", 'S', (void *) &get_luatexhashtype},
260 {"luatex_hashchars", 'N', &get_luatexhashchars},
261 {"luatex_engine", 'S', (void *) &getenginename},
263 {"ini_version", 'b', &ini_version},
265 {"shell_escape", 'N', &shell_escape_state}, /* be easy on old time usage */
267 * mem stat
269 {"var_used", 'g', &var_used},
270 {"dyn_used", 'g', &dyn_used},
272 * traditional tex stats
274 {"str_ptr", 'g', &str_ptr},
275 {"init_str_ptr", 'g', &init_str_ptr},
276 {"max_strings", 'g', &max_strings},
277 {"pool_ptr", 'g', &pool_size},
278 {"init_pool_ptr", 'g', &init_pool_ptr},
279 {"pool_size", 'g', &pool_size},
280 {"var_mem_max", 'g', &var_mem_max},
281 {"node_mem_usage", 'S', &sprint_node_mem_usage},
282 {"fix_mem_max", 'g', &fix_mem_max},
283 {"fix_mem_min", 'g', &fix_mem_min},
284 {"fix_mem_end", 'g', &fix_mem_end},
285 {"cs_count", 'g', &cs_count},
286 {"hash_size", 'G', &get_hash_size},
287 {"hash_extra", 'g', &hash_extra},
288 {"font_ptr", 'G', &max_font_id},
289 {"max_in_stack", 'g', &max_in_stack},
290 {"max_nest_stack", 'g', &max_nest_stack},
291 {"max_param_stack", 'g', &max_param_stack},
292 {"max_buf_stack", 'g', &max_buf_stack},
293 {"max_save_stack", 'g', &max_save_stack},
294 {"stack_size", 'g', &stack_size},
295 {"nest_size", 'g', &nest_size},
296 {"param_size", 'g', &param_size},
297 {"buf_size", 'g', &buf_size},
298 {"save_size", 'g', &save_size},
299 {"input_ptr", 'g', &input_ptr},
300 {"obj_ptr", 'N', &get_obj_ptr},
301 {"obj_tab_size", 'N', &get_obj_tab_size},
302 {"pdf_os_cntr", 'N', &get_pdf_os_cntr},
303 {"pdf_os_objidx", 'N', &get_pdf_os_objidx},
304 {"pdf_dest_names_ptr", 'N', &get_dest_names_ptr},
305 {"dest_names_size", 'N', &get_dest_names_size},
306 {"pdf_mem_ptr", 'N', &get_pdf_mem_ptr},
307 {"pdf_mem_size", 'N', &get_pdf_mem_size},
308 {"largest_used_mark", 'g', &biggest_used_mark},
309 {"luabytecodes", 'g', &luabytecode_max},
310 {"luabytecode_bytes", 'g', &luabytecode_bytes},
311 {"luastate_bytes", 'g', &luastate_bytes},
312 {"callbacks", 'g', &callback_count},
313 {"indirect_callbacks", 'g', &saved_callback_count},
315 {NULL, 0, 0}
318 static int stats_name_to_id(const char *name)
320 int i;
321 for (i = 0; stats[i].name != NULL; i++) {
322 if (strcmp(stats[i].name, name) == 0)
323 return i;
325 return -1;
328 static int do_getstat(lua_State * L, int i)
330 int t;
331 const char *st;
332 charfunc f;
333 intfunc g;
334 numfunc n;
335 int str;
336 t = stats[i].type;
337 switch (t) {
338 case 'S':
339 f = stats[i].value;
340 st = f();
341 lua_pushstring(L, st);
342 break;
343 case 's':
344 str = *(int *) (stats[i].value);
345 if (str) {
346 char *ss = makecstring(str);
347 lua_pushstring(L, ss);
348 free(ss);
349 } else {
350 lua_pushnil(L);
352 break;
353 case 'N':
354 n = stats[i].value;
355 lua_pushinteger(L, n());
356 break;
357 case 'G':
358 g = stats[i].value;
359 lua_pushinteger(L, g());
360 break;
361 case 'g':
362 lua_pushinteger(L, *(int *) (stats[i].value));
363 break;
364 case 'B':
365 g = stats[i].value;
366 lua_pushboolean(L, g());
367 break;
368 case 'n':
369 if (*(halfword *) (stats[i].value) != 0)
370 lua_nodelib_push_fast(L, *(halfword *) (stats[i].value));
371 else
372 lua_pushnil(L);
373 break;
374 case 'b':
375 lua_pushboolean(L, *(int *) (stats[i].value));
376 break;
377 default:
378 lua_pushnil(L);
380 return 1;
383 static int getstats(lua_State * L)
385 const char *st;
386 int i;
387 if (lua_type(L,-1) == LUA_TSTRING) {
388 st = lua_tostring(L, -1);
389 i = stats_name_to_id(st);
390 if (i >= 0) {
391 return do_getstat(L, i);
394 return 0;
397 static int setstats(lua_State * L)
399 (void) L;
400 return 0;
403 static int statslist(lua_State * L)
405 int i;
406 luaL_checkstack(L, 1, "out of stack space");
407 lua_newtable(L);
408 for (i = 0; stats[i].name != NULL; i++) {
409 luaL_checkstack(L, 2, "out of stack space");
410 lua_pushstring(L, stats[i].name);
411 do_getstat(L, i);
412 lua_rawset(L, -3);
414 return 1;
417 static int resetmessages(lua_State * L)
419 xfree(last_warning_str);
420 xfree(last_warning_tag);
421 xfree(last_error);
422 xfree(last_lua_error);
423 last_warning_str = NULL;
424 last_warning_tag = NULL;
425 last_error = NULL;
426 last_lua_error = NULL;
427 return 0;
430 static const struct luaL_Reg statslib[] = {
431 {"list", statslist},
432 {"resetmessages", resetmessages},
433 {NULL, NULL} /* sentinel */
436 int luaopen_stats(lua_State * L)
438 luaL_register(L, "status", statslib);
439 luaL_newmetatable(L, "tex.stats");
440 lua_pushstring(L, "__index");
441 lua_pushcfunction(L, getstats);
442 lua_settable(L, -3);
443 lua_pushstring(L, "__newindex");
444 lua_pushcfunction(L, setstats);
445 lua_settable(L, -3);
446 lua_setmetatable(L, -2); /* meta to itself */
447 return 1;