1
4
5
12
13# include "luametatex.h"
14
15# define STATS_METATABLE "tex.stats"
16
17typedef struct statistic_entry {
18 const char *name;
19 void *value;
20 int type;
21 int padding;
22} statistic_entry;
23
24typedef const char *(*constfunc) (void);
25typedef char *(*charfunc) (void);
26typedef lua_Number (*numfunc) (void);
27typedef int (*intfunc) (void);
28typedef int (*luafunc) (lua_State *L);
29
30static int statslib_callbackstate(lua_State *L)
31{
32 lmt_push_callback_usage(L);
33 return 1;
34}
35
36static int statslib_texstate(lua_State *L)
37{
38 lua_Integer approximate = 0
39 + (lua_Integer) lmt_string_pool_state .string_pool_data .allocated * (lua_Integer) lmt_string_pool_state .string_pool_data .itemsize
40 + (lua_Integer) lmt_string_pool_state .string_body_data .allocated * (lua_Integer) lmt_string_pool_state .string_body_data .itemsize
41 + (lua_Integer) lmt_node_memory_state .nodes_data .allocated * (lua_Integer) lmt_node_memory_state .nodes_data .itemsize
42 + (lua_Integer) lmt_node_memory_state .extra_data .allocated * (lua_Integer) lmt_node_memory_state .extra_data .itemsize
43 + (lua_Integer) lmt_token_memory_state.tokens_data .allocated * (lua_Integer) lmt_token_memory_state.tokens_data .itemsize
44 + (lua_Integer) lmt_fileio_state .io_buffer_data .allocated * (lua_Integer) lmt_fileio_state .io_buffer_data .itemsize
45 + (lua_Integer) lmt_input_state .input_stack_data .allocated * (lua_Integer) lmt_input_state .input_stack_data .itemsize
46 + (lua_Integer) lmt_input_state .in_stack_data .allocated * (lua_Integer) lmt_input_state .in_stack_data .itemsize
47 + (lua_Integer) lmt_nest_state .nest_data .allocated * (lua_Integer) lmt_nest_state .nest_data .itemsize
48 + (lua_Integer) lmt_input_state .parameter_stack_data.allocated * (lua_Integer) lmt_input_state .parameter_stack_data.itemsize
49 + (lua_Integer) lmt_save_state .save_stack_data .allocated * (lua_Integer) lmt_save_state .save_stack_data .itemsize
50 + (lua_Integer) lmt_hash_state .hash_data .allocated * (lua_Integer) lmt_hash_state .hash_data .itemsize
51 + (lua_Integer) lmt_fileio_state .io_buffer_data .allocated * (lua_Integer) lmt_fileio_state .io_buffer_data .itemsize
52 + (lua_Integer) lmt_font_state .font_data .allocated * (lua_Integer) lmt_font_state .font_data .itemsize
53 + (lua_Integer) lmt_language_state .language_data .allocated * (lua_Integer) lmt_language_state .language_data .itemsize
54 + (lua_Integer) lmt_mark_state .mark_data .allocated * (lua_Integer) lmt_mark_state .mark_data .itemsize
55 + (lua_Integer) lmt_insert_state .insert_data .allocated * (lua_Integer) lmt_insert_state .insert_data .itemsize
56 + (lua_Integer) lmt_sparse_state .sparse_data .allocated * (lua_Integer) lmt_sparse_state .sparse_data .itemsize
57 ;
58 lua_createtable(L, 0, 4);
59 lua_set_integer_by_key(L, "approximate", (int) approximate);
60 return 1;
61}
62
63static int statslib_luastate(lua_State *L)
64{
65 lua_createtable(L, 0, 6);
66 lua_set_integer_by_key(L, "functionsize", lmt_lua_state.function_table_size);
67 lua_set_integer_by_key(L, "propertiessize", lmt_node_memory_state.node_properties_table_size);
68 lua_set_integer_by_key(L, "bytecodes", lmt_lua_state.bytecode_max);
69 lua_set_integer_by_key(L, "bytecodebytes", lmt_lua_state.bytecode_bytes);
70 lua_set_integer_by_key(L, "statebytes", lmt_lua_state.used_bytes);
71 lua_set_integer_by_key(L, "statebytesmax", lmt_lua_state.used_bytes_max);
72 return 1;
73}
74
75static int statslib_errorstate(lua_State* L)
76{
77 lua_createtable(L, 0, 3);
78 lua_set_string_by_key(L, "error", lmt_error_state.last_error);
79 lua_set_string_by_key(L, "errorcontext", lmt_error_state.last_error_context);
80 lua_set_string_by_key(L, "luaerror", lmt_error_state.last_lua_error);
81 return 1;
82}
83
84static int statslib_warningstate(lua_State* L)
85{
86 lua_createtable(L, 0, 2);
87 lua_set_string_by_key(L, "warningtag", lmt_error_state.last_warning_tag);
88 lua_set_string_by_key(L, "warning", lmt_error_state.last_warning);
89 return 1;
90}
91
92static int statslib_aux_stats_name_to_id(const char *name, statistic_entry stats[])
93{
94 for (int i = 0; stats[i].name; i++) {
95 if (strcmp (stats[i].name, name) == 0) {
96 return i;
97 }
98 }
99 return -1;
100}
101
102static int statslib_aux_limits_state(lua_State* L, limits_data *data)
103{
104 lua_createtable(L, 0, 4);
105 lua_set_integer_by_key(L, "set", data->size);
106 lua_set_integer_by_key(L, "min", data->minimum);
107 lua_set_integer_by_key(L, "max", data->maximum);
108 lua_set_integer_by_key(L, "top", data->top);
109 return 1;
110}
111
112static int statslib_aux_memory_state(lua_State* L, memory_data *data)
113{
114 lua_createtable(L, 0, 9);
115 lua_set_integer_by_key(L, "set", data->size);
116 lua_set_integer_by_key(L, "min", data->minimum);
117 lua_set_integer_by_key(L, "max", data->maximum);
118 lua_set_integer_by_key(L, "mem", data->allocated);
119 lua_set_integer_by_key(L, "all", data->allocated > 0 ? (int) lmt_rounded(((double) data->allocated) * ((double) data->itemsize)) : data->allocated);
120 lua_set_integer_by_key(L, "top", data->top - data->offset);
121 lua_set_integer_by_key(L, "ptr", data->ptr - data->offset);
122 lua_set_integer_by_key(L, "ini", data->initial);
123 lua_set_integer_by_key(L, "stp", data->step);
124
125 return 1;
126}
127
128static int statslib_errorlinestate (lua_State* L) { return statslib_aux_limits_state(L, &lmt_error_state .line_limits); }
129static int statslib_halferrorlinestate(lua_State* L) { return statslib_aux_limits_state(L, &lmt_error_state .half_line_limits); }
130static int statslib_expandstate (lua_State* L) { return statslib_aux_limits_state(L, &lmt_expand_state .limits); }
131static int statslib_stringstate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_string_pool_state .string_pool_data); }
132static int statslib_poolstate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_string_pool_state .string_body_data); }
133static int statslib_lookupstate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_hash_state .eqtb_data); }
134static int statslib_hashstate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_hash_state .hash_data); }
135static int statslib_nodestate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_node_memory_state .nodes_data); }
136static int statslib_extrastate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_node_memory_state .extra_data); }
137static int statslib_tokenstate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_token_memory_state.tokens_data); }
138static int statslib_inputstate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_input_state .input_stack_data); }
139static int statslib_filestate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_input_state .in_stack_data); }
140static int statslib_parameterstate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_input_state .parameter_stack_data); }
141static int statslib_neststate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_nest_state .nest_data); }
142static int statslib_savestate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_save_state .save_stack_data); }
143static int statslib_bufferstate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_fileio_state .io_buffer_data); }
144static int statslib_fontstate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_font_state .font_data); }
145static int statslib_languagestate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_language_state .language_data); }
146static int statslib_markstate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_mark_state .mark_data); }
147static int statslib_insertstate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_insert_state .insert_data); }
148static int statslib_sparsestate (lua_State* L) { return statslib_aux_memory_state(L, &lmt_sparse_state .sparse_data); }
149
150static int statslib_readstate(lua_State *L)
151{
152 lua_createtable(L, 0, 4);
153 lua_set_string_by_key (L, "filename", tex_current_input_file_name());
154 lua_set_integer_by_key(L, "iocode", lmt_input_state.cur_input.name > io_file_input_code ? io_file_input_code : lmt_input_state.cur_input.name);
155 lua_set_integer_by_key(L, "linenumber", lmt_input_state.input_line);
156 lua_set_integer_by_key(L, "skiplinenumber", lmt_condition_state.skip_line);
157 return 1;
158}
159
160static int statslib_enginestate(lua_State *L)
161{
162 lua_createtable(L, 0, 15);
163 lua_set_string_by_key (L, "logfilename", lmt_fileio_state.log_name);
164 lua_set_string_by_key (L, "banner", lmt_engine_state.luatex_banner);
165 lua_set_number_by_key (L, "version", lmt_version_state.luatexversion);
166 lua_set_string_by_key (L, "luatex_engine", lmt_engine_state.engine_name);
167 lua_set_integer_by_key(L, "luatex_version", lmt_version_state.version);
168 lua_set_integer_by_key(L, "luatex_revision", lmt_version_state.revision);
169 lua_set_integer_by_key(L, "luatex_release", lmt_version_state.release);
170 lua_set_string_by_key(L, "luatex_verbose", lmt_version_state.verbose);
171 lua_set_integer_by_key(L, "development_id", lmt_version_state.developmentid);
172 lua_set_string_by_key (L, "copyright", lmt_version_state.copyright);
173 lua_set_integer_by_key(L, "format_id", lmt_version_state.formatid);
174 lua_set_integer_by_key(L, "tex_hash_size", hash_size);
175 lua_set_string_by_key (L, "used_compiler", lmt_version_state.compiler);
176
177 lua_set_integer_by_key(L, "run_state", lmt_main_state.run_state);
178 lua_set_boolean_by_key(L, "permit_loadlib", lmt_engine_state.permit_loadlib);
179 return 1;
180}
181
182static int statslib_aux_getstat_indeed(lua_State *L, statistic_entry stats[], int i)
183{
184 switch (stats[i].type) {
185 case 'S':
186
187 {
188 const char *st = (*(constfunc) stats[i].value)();
189 lua_pushstring(L, st);
190
191 break;
192 }
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209 case 'd':
210
211 lua_pushnumber(L, *(double *) (stats[i].value));
212 break;
213 case 'g':
214
215 lua_pushinteger(L, *(int *) (stats[i].value));
216 break;
217 case 'c':
218
219 lua_pushstring(L, *(const char **) (stats[i].value));
220 break;
221
222
223
224
225
226
227
228
229 case 'b':
230
231 lua_pushboolean(L, *(int *) (stats[i].value));
232 break;
233 case 'f':
234 (*(luafunc) stats[i].value)(L);
235 break;
236 default:
237
238 lua_pushnil(L);
239 break;
240 }
241 return 1;
242}
243
244static int statslib_aux_getstats_indeed(lua_State *L, statistic_entry stats[])
245{
246 if (lua_type(L, -1) == LUA_TSTRING) {
247 const char *st = lua_tostring(L, -1);
248 int i = statslib_aux_stats_name_to_id(st, stats);
249 if (i >= 0) {
250 return statslib_aux_getstat_indeed(L, stats, i);
251 }
252 }
253 return 0;
254}
255
256static int statslib_getconstants(lua_State *L)
257{
258 lua_createtable(L, 0, 100);
259
260 lua_set_integer_by_key(L, "no_catcode_table", no_catcode_table_preset);
261 lua_set_integer_by_key(L, "default_catcode_table", default_catcode_table_preset);
262
263 lua_set_cardinal_by_key(L,"max_cardinal", max_cardinal);
264 lua_set_cardinal_by_key(L,"min_cardinal", min_cardinal);
265 lua_set_integer_by_key(L, "max_integer", max_integer);
266 lua_set_integer_by_key(L, "min_integer", min_integer);
267 lua_set_integer_by_key(L, "max_dimen", max_dimension);
268 lua_set_integer_by_key(L, "min_dimen", min_dimension);
269 lua_set_integer_by_key(L, "max_dimension", max_dimension);
270 lua_set_integer_by_key(L, "min_dimension", min_dimension);
271 lua_set_integer_by_key(L, "min_data_value", min_data_value);
272 lua_set_integer_by_key(L, "max_data_value", max_data_value);
273 lua_set_integer_by_key(L, "max_half_value", max_half_value);
274
275 lua_set_integer_by_key(L, "max_limited_scale", max_limited_scale);
276 lua_set_integer_by_key(L, "max_math_style_scale", max_math_style_scale);
277
278 lua_set_integer_by_key(L, "one_bp", one_bp);
279
280 lua_set_integer_by_key(L, "infinity", max_infinity);
281 lua_set_integer_by_key(L, "min_infinity", min_infinity);
282 lua_set_integer_by_key(L, "awful_bad", awful_bad);
283 lua_set_integer_by_key(L, "infinite_bad", infinite_bad);
284 lua_set_integer_by_key(L, "infinite_penalty", infinite_penalty);
285 lua_set_integer_by_key(L, "eject_penalty", eject_penalty);
286 lua_set_integer_by_key(L, "deplorable", deplorable);
287 lua_set_integer_by_key(L, "large_width_excess", large_width_excess);
288 lua_set_integer_by_key(L, "small_stretchability", small_stretchability);
289 lua_set_integer_by_key(L, "decent_criterion", decent_criterion);
290 lua_set_integer_by_key(L, "loose_criterion", loose_criterion);
291
292 lua_set_integer_by_key(L, "default_rule", default_rule);
293 lua_set_integer_by_key(L, "ignore_depth", ignore_depth);
294
295 lua_set_integer_by_key(L, "min_quarterword", min_quarterword);
296 lua_set_integer_by_key(L, "max_quarterword", max_quarterword);
297
298 lua_set_integer_by_key(L, "min_halfword", min_halfword);
299 lua_set_integer_by_key(L, "max_halfword", max_halfword);
300
301 lua_set_integer_by_key(L, "null_flag", null_flag);
302 lua_set_integer_by_key(L, "zero_glue", zero_glue);
303 lua_set_integer_by_key(L, "unity", unity);
304 lua_set_integer_by_key(L, "two", two);
305 lua_set_integer_by_key(L, "null", null);
306 lua_set_integer_by_key(L, "null_font", null_font);
307
308 lua_set_integer_by_key(L, "unused_attribute_value", unused_attribute_value);
309 lua_set_integer_by_key(L, "unused_state_value", unused_state_value);
310 lua_set_integer_by_key(L, "unused_script_value", unused_script_value);
311
312 lua_set_integer_by_key(L, "preset_rule_thickness", preset_rule_thickness);
313 lua_set_integer_by_key(L, "running_rule", null_flag);
314
315 lua_set_integer_by_key(L, "min_space_factor", min_space_factor);
316 lua_set_integer_by_key(L, "max_space_factor", max_space_factor);
317 lua_set_integer_by_key(L, "min_scale_factor", min_scale_factor);
318 lua_set_integer_by_key(L, "max_scale_factor", max_scale_factor);
319 lua_set_integer_by_key(L, "default_space_factor", default_space_factor);
320 lua_set_integer_by_key(L, "default_tolerance", default_tolerance);
321 lua_set_integer_by_key(L, "default_hangafter", default_hangafter);
322 lua_set_integer_by_key(L, "default_deadcycles", default_deadcycles);
323 lua_set_integer_by_key(L, "default_pre_display_gap", default_pre_display_gap);
324 lua_set_integer_by_key(L, "default_eqno_gap_step", default_eqno_gap_step);
325
326 lua_set_integer_by_key(L, "default_output_box", default_output_box);
327
328 lua_set_integer_by_key(L, "max_n_of_fonts", max_n_of_fonts);
329 lua_set_integer_by_key(L, "max_n_of_bytecodes", max_n_of_bytecodes);
330 lua_set_integer_by_key(L, "max_n_of_math_families", max_n_of_math_families);
331 lua_set_integer_by_key(L, "max_n_of_languages", max_n_of_languages);
332 lua_set_integer_by_key(L, "max_n_of_catcode_tables", max_n_of_catcode_tables);
333
334 lua_set_integer_by_key(L, "max_n_of_marks", max_n_of_marks);
335
336 lua_set_integer_by_key(L, "max_character_code", max_character_code);
337 lua_set_integer_by_key(L, "max_mark_index", max_mark_index);
338
339 lua_set_integer_by_key(L, "max_toks_register_index", max_toks_register_index);
340 lua_set_integer_by_key(L, "max_box_register_index", max_box_register_index);
341 lua_set_integer_by_key(L, "max_int_register_index", max_integer_register_index);
342 lua_set_integer_by_key(L, "max_integer_register_index", max_integer_register_index);
343 lua_set_integer_by_key(L, "max_float_register_index", max_posit_register_index);
344 lua_set_integer_by_key(L, "max_dimension_register_index", max_dimension_register_index);
345 lua_set_integer_by_key(L, "max_dimen_register_index", max_dimension_register_index);
346 lua_set_integer_by_key(L, "max_attribute_register_index", max_attribute_register_index);
347 lua_set_integer_by_key(L, "max_glue_register_index", max_glue_register_index);
348 lua_set_integer_by_key(L, "max_muglue_register_index", max_muglue_register_index);
349
350 lua_set_integer_by_key(L, "max_bytecode_index", max_bytecode_index);
351 lua_set_integer_by_key(L, "max_math_family_index", max_math_family_index);
352 lua_set_integer_by_key(L, "max_math_class_code", max_math_class_code);
353 lua_set_integer_by_key(L, "max_function_reference", max_function_reference);
354 lua_set_integer_by_key(L, "max_category_code", max_category_code);
355
356 lua_set_integer_by_key(L, "max_newline_character", max_newline_character);
357 lua_set_integer_by_key(L, "max_endline_character", max_endline_character);
358
359 lua_set_integer_by_key(L, "max_size_of_word", max_size_of_word);
360
361 lua_set_integer_by_key(L, "tex_hash_size", hash_size);
362 lua_set_integer_by_key(L, "tex_hash_prime", hash_prime);
363 lua_set_integer_by_key(L, "tex_eqtb_size", eqtb_size);
364
365 lua_set_integer_by_key(L, "math_begin_class", math_begin_class);
366 lua_set_integer_by_key(L, "math_end_class", math_end_class);
367 lua_set_integer_by_key(L, "unused_math_family", unused_math_family);
368 lua_set_integer_by_key(L, "unused_math_style", unused_math_style);
369 lua_set_integer_by_key(L, "assumed_math_control", assumed_math_control);
370
371 lua_set_integer_by_key(L, "undefined_math_parameter", undefined_math_parameter);
372
373 lua_set_integer_by_key(L, "max_calculated_badness", max_calculated_badness);
374
375 lua_set_integer_by_key(L, "max_math_scaling_factor", max_math_scaling_factor);
376 lua_set_integer_by_key(L, "math_default_penalty", math_default_penalty);
377
378 lua_set_integer_by_key(L, "max_font_adjust_step", max_font_adjust_step);
379 lua_set_integer_by_key(L, "max_font_adjust_stretch_factor", max_font_adjust_stretch_factor);
380 lua_set_integer_by_key(L, "max_font_adjust_shrink_factor", max_font_adjust_shrink_factor);
381
382 return 1;
383}
384
385static struct statistic_entry statslib_entries[] = {
386
387
388
389 { .name = "enginestate", .value = &statslib_enginestate, .type = 'f' },
390 { .name = "errorlinestate", .value = &statslib_errorlinestate, .type = 'f' },
391 { .name = "halferrorlinestate", .value = &statslib_halferrorlinestate, .type = 'f' },
392 { .name = "expandstate", .value = &statslib_expandstate, .type = 'f' },
393 { .name = "stringstate", .value = &statslib_stringstate, .type = 'f' },
394 { .name = "poolstate", .value = &statslib_poolstate, .type = 'f' },
395 { .name = "hashstate", .value = &statslib_hashstate, .type = 'f' },
396 { .name = "lookupstate", .value = &statslib_lookupstate, .type = 'f' },
397 { .name = "nodestate", .value = &statslib_nodestate, .type = 'f' },
398 { .name = "extrastate", .value = &statslib_extrastate, .type = 'f' },
399 { .name = "tokenstate", .value = &statslib_tokenstate, .type = 'f' },
400 { .name = "inputstate", .value = &statslib_inputstate, .type = 'f' },
401 { .name = "filestate", .value = &statslib_filestate, .type = 'f' },
402 { .name = "parameterstate", .value = &statslib_parameterstate, .type = 'f' },
403 { .name = "neststate", .value = &statslib_neststate, .type = 'f' },
404 { .name = "savestate", .value = &statslib_savestate, .type = 'f' },
405 { .name = "bufferstate", .value = &statslib_bufferstate, .type = 'f' },
406 { .name = "texstate", .value = &statslib_texstate, .type = 'f' },
407 { .name = "luastate", .value = &statslib_luastate, .type = 'f' },
408 { .name = "callbackstate", .value = &statslib_callbackstate, .type = 'f' },
409 { .name = "errorstate", .value = &statslib_errorstate, .type = 'f' },
410 { .name = "warningstate", .value = &statslib_warningstate, .type = 'f' },
411 { .name = "readstate", .value = &statslib_readstate, .type = 'f' },
412 { .name = "fontstate", .value = &statslib_fontstate, .type = 'f' },
413 { .name = "languagestate", .value = &statslib_languagestate, .type = 'f' },
414 { .name = "markstate", .value = &statslib_markstate, .type = 'f' },
415 { .name = "insertstate", .value = &statslib_insertstate, .type = 'f' },
416 { .name = "sparsestate", .value = &statslib_sparsestate, .type = 'f' },
417
418
419
420 { .name = "lua_version_major", .value = (void *) &lmt_version_state.luaversionmajor, .type = 'g' },
421 { .name = "lua_version_minor", .value = (void *) &lmt_version_state.luaversionminor, .type = 'g' },
422 { .name = "lua_version_release", .value = (void *) &lmt_version_state.luaversionrelease, .type = 'g' },
423 { .name = "lua_version", .value = (void *) &lmt_version_state.luaversion, .type = 'd' },
424
425
426
427 { .name = "filename", .value = (void *) &tex_current_input_file_name, .type = 'S' },
428 { .name = "logfilename", .value = (void *) &lmt_fileio_state.log_name, .type = 'c' },
429 { .name = "banner", .value = (void *) &lmt_engine_state.luatex_banner, .type = 'c' },
430 { .name = "version", .value = (void *) &lmt_version_state.luatexversion, .type = 'd' },
431 { .name = "luatex_engine", .value = (void *) &lmt_engine_state.engine_name, .type = 'c' },
432 { .name = "luatex_version", .value = (void *) &lmt_version_state.version, .type = 'g' },
433 { .name = "luatex_revision", .value = (void *) &lmt_version_state.revision, .type = 'g' },
434 { .name = "luatex_release", .value = (void *) &lmt_version_state.release, .type = 'g' },
435 { .name = "luatex_verbose", .value = (void *) &lmt_version_state.verbose, .type = 'c' },
436 { .name = "copyright", .value = (void *) &lmt_version_state.copyright, .type = 'c' },
437 { .name = "development_id", .value = (void *) &lmt_version_state.developmentid, .type = 'g' },
438 { .name = "format_id", .value = (void *) &lmt_version_state.formatid, .type = 'g' },
439 { .name = "used_compiler", .value = (void *) &lmt_version_state.compiler, .type = 'c' },
440 { .name = "run_state", .value = (void *) &lmt_main_state.run_state, .type = 'g' },
441 { .name = "permit_loadlib", .value = (void *) &lmt_engine_state.permit_loadlib, .type = 'b' },
442
443 { .name = NULL, .value = NULL, .type = 0 },
444};
445
446static struct statistic_entry statslib_entries_only[] = {
447 { .name = "filename", .value = (void *) &tex_current_input_file_name, .type = 'S' },
448 { .name = "banner", .value = (void *) &lmt_engine_state.luatex_banner, .type = 'c' },
449 { .name = "version", .value = (void *) &lmt_version_state.luatexversion, .type = 'd' },
450 { .name = "luatex_engine", .value = (void *) &lmt_engine_state.engine_name, .type = 'c' },
451 { .name = "luatex_version", .value = (void *) &lmt_version_state.version, .type = 'g' },
452 { .name = "luatex_revision", .value = (void *) &lmt_version_state.revision, .type = 'g' },
453 { .name = "luatex_release", .value = (void *) &lmt_version_state.release, .type = 'g' },
454 { .name = "luatex_verbose", .value = (void *) &lmt_version_state.verbose, .type = 'c' },
455 { .name = "copyright", .value = (void *) &lmt_version_state.copyright, .type = 'c' },
456 { .name = "development_id", .value = (void *) &lmt_version_state.developmentid, .type = 'g' },
457 { .name = "format_id", .value = (void *) &lmt_version_state.formatid, .type = 'g' },
458 { .name = "used_compiler", .value = (void *) &lmt_version_state.compiler, .type = 'c' },
459
460 { .name = NULL, .value = NULL, .type = 0 },
461};
462
463static int statslib_aux_getstats(lua_State *L)
464{
465 return statslib_aux_getstats_indeed(L, statslib_entries);
466}
467
468static int statslib_aux_getstats_only(lua_State *L)
469{
470 return statslib_aux_getstats_indeed(L, statslib_entries_only);
471}
472
473static int statslib_aux_statslist(lua_State *L, statistic_entry stats[])
474{
475 lua_createtable(L, 0, 60);
476 for (int i = 0; stats[i].name; i++) {
477 lua_pushstring(L, stats[i].name);
478 statslib_aux_getstat_indeed(L, stats, i);
479 lua_rawset(L, -3);
480 }
481 return 1;
482}
483
484static int statslib_statslist(lua_State *L)
485{
486 return statslib_aux_statslist(L, statslib_entries);
487}
488
489static int statslib_statslist_only(lua_State *L)
490{
491 return statslib_aux_statslist(L, statslib_entries_only);
492}
493
494static int statslib_resetmessages(lua_State *L)
495{
496 (void) (L);
497 lmt_memory_free(lmt_error_state.last_warning);
498 lmt_memory_free(lmt_error_state.last_warning_tag);
499 lmt_memory_free(lmt_error_state.last_error);
500 lmt_memory_free(lmt_error_state.last_lua_error);
501 lmt_error_state.last_warning = NULL;
502 lmt_error_state.last_warning_tag = NULL;
503 lmt_error_state.last_error = NULL;
504 lmt_error_state.last_lua_error = NULL;
505 return 0;
506}
507
508static const struct luaL_Reg statslib_function_list[] = {
509 { "list", statslib_statslist },
510 { "getconstants", statslib_getconstants },
511 { "resetmessages", statslib_resetmessages },
512
513 { "gettexstate", statslib_texstate },
514 { "getluastate", statslib_luastate },
515 { "geterrorstate", statslib_errorstate },
516 { "getwarningstate", statslib_warningstate },
517 { "getreadstate", statslib_readstate },
518 { "getcallbackstate", statslib_callbackstate },
519
520 { "geterrorlinestate", statslib_errorlinestate },
521 { "gethalferrorlinestate", statslib_halferrorlinestate },
522 { "getexpandstate", statslib_expandstate },
523
524 { "getstringstate", statslib_stringstate },
525 { "getpoolstate", statslib_poolstate },
526 { "gethashstate", statslib_hashstate },
527 { "getlookupstate", statslib_lookupstate },
528 { "getnodestate", statslib_nodestate },
529 { "getextrastate", statslib_extrastate },
530 { "gettokenstate", statslib_tokenstate },
531 { "getinputstate", statslib_inputstate },
532 { "getfilestate", statslib_filestate },
533 { "getparameterstate", statslib_parameterstate },
534 { "getneststate", statslib_neststate },
535 { "getsavestate", statslib_savestate },
536 { "getbufferstate", statslib_bufferstate },
537 { "getfontstate", statslib_fontstate },
538 { "getlanguagestate", statslib_languagestate },
539 { "getmarkstate", statslib_markstate },
540 { "getinsertstate", statslib_insertstate },
541 { "getsparsestate", statslib_sparsestate },
542
543 { NULL, NULL },
544};
545
546static const struct luaL_Reg statslib_function_list_only[] = {
547 { "list", statslib_statslist_only },
548 { NULL, NULL },
549};
550
551int luaopen_status(lua_State *L)
552{
553 lua_newtable(L);
554 luaL_setfuncs(L, lmt_engine_state.lua_only ? statslib_function_list_only : statslib_function_list, 0);
555 luaL_newmetatable(L, STATS_METATABLE);
556 lua_pushstring(L, "__index");
557 lua_pushcfunction(L, lmt_engine_state.lua_only ? statslib_aux_getstats_only : statslib_aux_getstats);
558 lua_settable(L, -3);
559 lua_setmetatable(L, -2);
560 return 1;
561}
562 |