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