1
4
5
16
17# include "luametatex.h"
18
19FILE *lmt_valid_file(lua_State *L) {
20 luaL_Stream *p = (luaL_Stream *) lua_touserdata(L, 1);
21 if (p && lua_getmetatable(L, 1)) {
22
23 lua_get_metatablelua(file_handle_instance);
24 if (! lua_rawequal(L, -1, -2)) {
25 p = NULL;
26 }
27 lua_pop(L, 2);
28 return (p && (p)->closef) ? p->f : NULL;
29 }
30 return NULL;
31}
32
33typedef void (*texio_printer) (const char *);
34
35
36static int texiolib_getselectorvalues(lua_State *L)
37{
38 lua_createtable(L, 3, 0);
39 lua_push_key_at_index(L, logfile, terminal_selector_code );
40 lua_push_key_at_index(L, terminal, logfile_selector_code );
41 lua_push_key_at_index(L, terminal_and_logfile, terminal_and_logfile_selector_code);
42 return 1;
43}
44
45static inline int texiolib_aux_get_selector_value(lua_State *L, int i, int *l, int dflt)
46{
47 switch (lua_type(L, i)) {
48 case LUA_TSTRING:
49 {
50 const char *s = lua_tostring(L, i);
51 if (lua_key_eq(s, logfile)) {
52 *l = logfile_selector_code;
53 } else if (lua_key_eq(s, terminal)) {
54 *l = terminal_selector_code;
55 } else if (lua_key_eq(s, terminal_and_logfile)) {
56 *l = terminal_and_logfile_selector_code;
57 } else {
58 *l = dflt;
59 }
60 return 1;
61 }
62 case LUA_TNUMBER:
63 {
64 int n = lmt_tointeger(L, i);
65 *l = n >= terminal_selector_code && n <= terminal_and_logfile_selector_code ? n : dflt;
66 return 1;
67 }
68 default:
69 return luaL_error(L, "(first) argument is not 'terminal_and_logfile', 'terminal' or 'logfile'");
70 }
71}
72
73static void texiolib_aux_print(lua_State *L, int n, texio_printer printfunction, const char *dflt)
74{
75 int i = 1;
76 int saved_selector = lmt_print_state.selector;
77 if (n > 1 && texiolib_aux_get_selector_value(L, i, &lmt_print_state.selector, terminal_selector_code)) {
78 i++;
79 }
80 switch (lmt_print_state.selector) {
81 case terminal_and_logfile_selector_code:
82 case logfile_selector_code:
83 case terminal_selector_code:
84 if (i <= n) {
85 do {
86 switch (lua_type(L, i)) {
87 case LUA_TNIL:
88 break;
89 case LUA_TBOOLEAN:
90 case LUA_TNUMBER:
91 case LUA_TSTRING:
92 printfunction(lua_tostring(L, i));
93 break;
94 default:
95 luaL_error(L, "argument is not a string, number or boolean");
96 }
97 i++;
98 } while (i <= n);
99 } else if (dflt) {
100 printfunction(dflt);
101 }
102 break;
103 }
104 lmt_print_state.selector = saved_selector;
105}
106
107static void texiolib_aux_print_selector(lua_State *L, int n, texio_printer printfunction, const char *dflt)
108{
109 int saved_selector = lmt_print_state.selector;
110 texiolib_aux_get_selector_value(L, 1, &lmt_print_state.selector, no_print_selector_code);
111 switch (lmt_print_state.selector) {
112 case terminal_and_logfile_selector_code:
113 case logfile_selector_code:
114 case terminal_selector_code:
115 {
116 if (n > 1) {
117 for (int i = 2; i <= n; i++) {
118 switch (lua_type(L, i)) {
119 case LUA_TNIL:
120 break;
121 case LUA_TBOOLEAN:
122 case LUA_TNUMBER:
123 case LUA_TSTRING:
124 printfunction(lua_tostring(L, i));
125 break;
126 default:
127 luaL_error(L, "argument is not a string, number or boolean");
128 }
129 };
130 } else if (dflt) {
131 printfunction(dflt);
132 }
133 break;
134 }
135 }
136 lmt_print_state.selector = saved_selector;
137}
138
139static void texiolib_aux_print_stdout(lua_State *L, const char *extra)
140{
141 int i = 1;
142 int l = terminal_and_logfile_selector_code;
143 int n = lua_gettop(L);
144 if (n > 1 && texiolib_aux_get_selector_value(L, i, &l, terminal_selector_code)) {
145 i++;
146 }
147 for (; i <= n; i++) {
148 if (lua_isstring(L, i)) {
149 const char *s = lua_tostring(L, i);
150 if (l == terminal_and_logfile_selector_code || l == terminal_selector_code) {
151 fputs(extra, stdout);
152 fputs(s, stdout);
153 }
154 if (l == terminal_and_logfile_selector_code || l == logfile_selector_code) {
155 if (lmt_print_state.loggable_info) {
156 char *v = (char*) lmt_memory_malloc(strlen(lmt_print_state.loggable_info) + strlen(extra) + strlen(s) + 1);
157 if (v) {
158 sprintf(v, "%s%s%s", lmt_print_state.loggable_info, extra, s);
159 }
160 lmt_memory_free(lmt_print_state.loggable_info);
161 lmt_print_state.loggable_info = v;
162 } else {
163 lmt_print_state.loggable_info = lmt_memory_strdup(s);
164 }
165 }
166 }
167 }
168}
169
170static void texiolib_aux_print_nlp_str(const char *s)
171{
172 tex_print_nlp();
173 tex_print_str(s);
174}
175
176static int texiolib_write(lua_State *L)
177{
178 if (lmt_main_state.ready_already == output_disabled_state || ! lmt_fileio_state.job_name) {
179 texiolib_aux_print_stdout(L, "");
180 } else {
181 int n = lua_gettop(L);
182 if (n > 0) {
183 texiolib_aux_print(L, n, tex_print_str, NULL);
184 } else {
185
186 }
187 }
188 return 0;
189}
190
191static int texiolib_write_nl(lua_State *L)
192{
193 if (lmt_main_state.ready_already == output_disabled_state || ! lmt_fileio_state.job_name) {
194 texiolib_aux_print_stdout(L, "\n");
195 } else {
196 int n = lua_gettop(L);
197 if (n > 0) {
198 texiolib_aux_print(L, n, texiolib_aux_print_nlp_str, "\n");
199 } else {
200
201 }
202 }
203 return 0;
204}
205
206static int texiolib_write_selector(lua_State *L)
207{
208 if (lmt_main_state.ready_already == output_disabled_state || ! lmt_fileio_state.job_name) {
209 texiolib_aux_print_stdout(L, "");
210 } else {
211 int n = lua_gettop(L);
212 if (n > 1) {
213 texiolib_aux_print_selector(L, n, tex_print_str, NULL);
214 } else {
215
216 }
217 }
218 return 0;
219}
220
221
222static int texiolib_write_selector_nl(lua_State *L)
223{
224 if (lmt_main_state.ready_already == output_disabled_state || ! lmt_fileio_state.job_name) {
225 texiolib_aux_print_stdout(L, "\n");
226 } else {
227 int n = lua_gettop(L);
228 if (n > 1) {
229 texiolib_aux_print_selector(L, n, texiolib_aux_print_nlp_str, "");
230 } else {
231
232 }
233 }
234 return 0;
235}
236
237static int texiolib_write_selector_lf(lua_State *L)
238{
239 if (lmt_main_state.ready_already == output_disabled_state || ! lmt_fileio_state.job_name) {
240 texiolib_aux_print_stdout(L, "\n");
241 } else {
242 int n = lua_gettop(L);
243 if (n >= 1) {
244 texiolib_aux_print_selector(L, n, texiolib_aux_print_nlp_str, "");
245 } else {
246
247 }
248 }
249 return 0;
250}
251
252
253
254static int texiolib_closeinput(lua_State *L)
255{
256 (void) (L);
257 if (lmt_input_state.cur_input.index > 0) {
258 tex_end_token_list();
259 tex_end_file_reading();
260 }
261 return 0 ;
262}
263
264static int texiolib_getinputindex(lua_State *L)
265{
266 lua_pushinteger(L, lmt_input_state.cur_input.index);
267 return 1;
268}
269
270static int texiolib_getsourcefilename(lua_State *L)
271{
272 lua_pushstring(L, lmt_input_state.in_stack[lmt_input_state.in_stack_data.ptr].full_source_filename);
273 return 1;
274}
275
276
282
283static int texiolib_setlogfile(lua_State *L)
284{
285 FILE *f = lmt_valid_file(L);
286 if (f) {
287
288 if (! lmt_print_state.logfile) {
289 lmt_print_state.saved_logfile = lmt_print_state.logfile;
290 lmt_print_state.saved_logfile_offset = lmt_print_state.logfile_offset;
291
292 }
293 lmt_print_state.logfile = f;
294 lmt_print_state.logfile_offset = 0;
295 } else if (lmt_print_state.logfile) {
296 lmt_print_state.logfile = lmt_print_state.saved_logfile;
297 lmt_print_state.logfile_offset = lmt_print_state.saved_logfile_offset;
298 }
299 return 0;
300}
301
302static int texiolib_forceendoffile(lua_State *L)
303{
304 (void) L;
305 lmt_token_state.force_eof = 1;
306 return 0;
307}
308
309static const struct luaL_Reg texiolib_function_list[] = {
310 { "write", texiolib_write },
311 { "writenl", texiolib_write_nl },
312 { "write_nl", texiolib_write_nl },
313 { "writeselector", texiolib_write_selector },
314 { "writeselectornl", texiolib_write_selector_nl },
315 { "writeselectorlf", texiolib_write_selector_lf },
316 { "closeinput", texiolib_closeinput },
317 { "setlogfile", texiolib_setlogfile },
318 { "getinputindex", texiolib_getinputindex },
319 { "getsourcefilename", texiolib_getsourcefilename },
320 { "forceendoffile", texiolib_forceendoffile },
321 { "getselectorvalues", texiolib_getselectorvalues },
322 { NULL, NULL },
323};
324
325static const struct luaL_Reg texiolib_function_list_only[] = {
326 { "write", texiolib_write },
327 { "writenl", texiolib_write_nl },
328 { "write_nl", texiolib_write_nl },
329 { "writeselector", texiolib_write_selector },
330 { "writeselectornl", texiolib_write_selector_nl },
331 { "writeselectorlf", texiolib_write_selector_lf },
332 { NULL, NULL },
333};
334
335int luaopen_texio(lua_State *L)
336{
337 lua_newtable(L);
338 luaL_setfuncs(L, lmt_engine_state.lua_only ? texiolib_function_list_only : texiolib_function_list, 0);
339 return 1;
340}
341 |