1
4
5
11
12
13
14# include "luametatex.h"
15
16
17
18inline static int strlib_aux_tounicode(const char *s, size_t l, size_t *p)
19{
20 unsigned char i = s[*p];
21 *p += 1;
22 if (i < 0x80) {
23 return i;
24 } else if (i >= 0xF0) {
25 if ((*p + 2) < l) {
26 unsigned char j = s[*p];
27 unsigned char k = s[*p + 1];
28 unsigned char l = s[*p + 2];
29 if (j >= 0x80 && k >= 0x80 && l >= 0x80) {
30 *p += 3;
31 return (((((i - 0xF0) * 0x40) + (j - 0x80)) * 0x40) + (k - 0x80)) * 0x40 + (l - 0x80);
32 }
33 }
34 } else if (i >= 0xE0) {
35 if ((*p + 1) < l) {
36 unsigned char j = s[*p];
37 unsigned char k = s[*p + 1];
38 if (j >= 0x80 && k >= 0x80) {
39 *p += 2;
40 return (((i - 0xE0) * 0x40) + (j - 0x80)) * 0x40 + (k - 0x80);
41 }
42 }
43 } else if (i >= 0xC0) {
44 if (*p < l) {
45 unsigned char j = s[*p];
46 if (j >= 0x80) {
47 *p += 1;
48 return ((i - 0xC0) * 0x40) + (j - 0x80);
49 }
50 }
51 }
52 return 0xFFFD;
53}
54
55inline static int strlib_aux_tounichar(const char *s, size_t l, size_t p)
56{
57 unsigned char i = s[p++];
58 if (i < 0x80) {
59 return 1;
60 } else if (i >= 0xF0) {
61 if ((p + 2) < l) {
62 unsigned char j = s[p];
63 unsigned char k = s[p + 1];
64 unsigned char l = s[p + 2];
65 if (j >= 0x80 && k >= 0x80 && l >= 0x80) {
66 return 4;
67 }
68 }
69 } else if (i >= 0xE0) {
70 if ((p + 1) < l) {
71 unsigned char j = s[p];
72 unsigned char k = s[p + 1];
73 if (j >= 0x80 && k >= 0x80) {
74 return 3;
75 }
76 }
77 } else if (i >= 0xC0) {
78 if (p < l) {
79 unsigned char j = s[p];
80 if (j >= 0x80) {
81 return 2;
82 }
83 }
84 }
85 return 0;
86}
87
88inline static size_t strlib_aux_toline(const char *s, size_t l, size_t p, size_t *b)
89{
90 size_t i = p;
91 while (i < l) {
92 if (s[i] == 13) {
93 if ((i + 1) < l) {
94 if (s[i + 1] == 10) {
95 *b = 2;
96 } else {
97 *b = 1;
98 }
99 }
100 return i - p;
101 } else if (s[i] == 10) {
102 *b = 1;
103 return i - p;
104 } else {
105
106 i += 1;
107 }
108 }
109 return i - p ;
110}
111
112
113
114static int strlib_aux_bytepairs(lua_State *L)
115{
116 size_t ls = 0;
117 const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
118 size_t ind = lmt_tointeger(L, lua_upvalueindex(2));
119 if (ind < ls) {
120 unsigned char i;
121
122 if (ind + 1 < ls) {
123 lua_pushinteger(L, ind + 2);
124 } else {
125 lua_pushinteger(L, ind + 1);
126 }
127 lua_replace(L, lua_upvalueindex(2));
128 i = (unsigned char)*(s + ind);
129
130 lua_pushinteger(L, i);
131 if (ind + 1 < ls) {
132
133 i = (unsigned char)*(s + ind + 1);
134 lua_pushinteger(L, i);
135 } else {
136
137 lua_pushnil(L);
138 }
139 return 2;
140 } else {
141 return 0;
142 }
143}
144
145static int strlib_bytepairs(lua_State *L)
146{
147 luaL_checkstring(L, 1);
148 lua_settop(L, 1);
149 lua_pushinteger(L, 0);
150 lua_pushcclosure(L, strlib_aux_bytepairs, 2);
151 return 1;
152}
153
154static int strlib_aux_bytes(lua_State *L)
155{
156 size_t ls = 0;
157 const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
158 size_t ind = lmt_tointeger(L, lua_upvalueindex(2));
159 if (ind < ls) {
160
161 lua_pushinteger(L, ind + 1);
162 lua_replace(L, lua_upvalueindex(2));
163
164 lua_pushinteger(L, (unsigned char)*(s + ind));
165 return 1;
166 } else {
167 return 0;
168 }
169}
170
171static int strlib_bytes(lua_State *L)
172{
173 luaL_checkstring(L, 1);
174 lua_settop(L, 1);
175 lua_pushinteger(L, 0);
176 lua_pushcclosure(L, strlib_aux_bytes, 2);
177 return 1;
178}
179
180static int strlib_aux_utf_failed(lua_State *L, int new_ind)
181{
182 lua_pushinteger(L, new_ind);
183 lua_replace(L, lua_upvalueindex(2));
184 lua_pushliteral(L, utf_fffd_string);
185 return 1;
186}
187
188
189
190static int strlib_aux_utfcharacters(lua_State *L)
191{
192 static const unsigned char mask[4] = { 0x80, 0xE0, 0xF0, 0xF8 };
193 static const unsigned char mequ[4] = { 0x00, 0xC0, 0xE0, 0xF0 };
194 size_t ls = 0;
195 const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
196 size_t ind = lmt_tointeger(L, lua_upvalueindex(2));
197 size_t l = ls;
198 if (ind >= l) {
199 return 0;
200 } else {
201 unsigned char c = (unsigned char) s[ind];
202 for (size_t j = 0; j < 4; j++) {
203 if ((c & mask[j]) == mequ[j]) {
204 if (ind + 1 + j > l) {
205
206 return strlib_aux_utf_failed(L, (int) l);
207 }
208 for (size_t k = 1; k <= j; k++) {
209 c = (unsigned char) s[ind + k];
210 if ((c & 0xC0) != 0x80) {
211
212 return strlib_aux_utf_failed(L, (int) (ind + k));
213 }
214 }
215
216 lua_pushinteger(L, ind + j + 1);
217 lua_replace(L, lua_upvalueindex(2));
218 lua_pushlstring(L, ind + s, j + 1);
219 return 1;
220 }
221 }
222 return strlib_aux_utf_failed(L, (int) (ind + 1));
223 }
224}
225
226static int strlib_utfcharacters(lua_State *L)
227{
228 luaL_checkstring(L, 1);
229 lua_settop(L, 1);
230 lua_pushinteger(L, 0);
231 lua_pushcclosure(L, strlib_aux_utfcharacters, 2);
232 return 1;
233}
234
235static int strlib_aux_utfvalues(lua_State *L)
236{
237 size_t l = 0;
238 const char *s = lua_tolstring(L, lua_upvalueindex(1), &l);
239 size_t ind = lmt_tointeger(L, lua_upvalueindex(2));
240 if (ind < l) {
241 int v = strlib_aux_tounicode(s, l, &ind);
242 lua_pushinteger(L, ind);
243 lua_replace(L, lua_upvalueindex(2));
244 lua_pushinteger(L, v);
245 return 1;
246 } else {
247 return 0;
248 }
249}
250
251static int strlib_utfvalues(lua_State *L)
252{
253 luaL_checkstring(L, 1);
254 lua_settop(L, 1);
255 lua_pushinteger(L, 0);
256 lua_pushcclosure(L, strlib_aux_utfvalues, 2);
257 return 1;
258}
259
260static int strlib_aux_characterpairs(lua_State *L)
261{
262 size_t ls = 0;
263 const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
264 size_t ind = lmt_tointeger(L, lua_upvalueindex(2));
265 if (ind < ls) {
266 char b[1];
267 lua_pushinteger(L, ind + 2);
268 lua_replace(L, lua_upvalueindex(2));
269 b[0] = s[ind];
270 lua_pushlstring(L, b, 1);
271 if ((ind + 1) < ls) {
272 b[0] = s[ind + 1];
273 lua_pushlstring(L, b, 1);
274 } else {
275 lua_pushliteral(L, "");
276 }
277 return 2;
278 } else {
279 return 0;
280 }
281}
282
283static int strlib_characterpairs(lua_State *L)
284{
285 luaL_checkstring(L, 1);
286 lua_settop(L, 1);
287 lua_pushinteger(L, 0);
288 lua_pushcclosure(L, strlib_aux_characterpairs, 2);
289 return 1;
290}
291
292static int strlib_aux_characters(lua_State *L)
293{
294 size_t ls = 0;
295 const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
296 size_t ind = lmt_tointeger(L, lua_upvalueindex(2));
297 if (ind < ls) {
298 char b[1];
299 lua_pushinteger(L, ind + 1);
300 lua_replace(L, lua_upvalueindex(2));
301 b[0] = *(s + ind);
302 lua_pushlstring(L, b, 1);
303 return 1;
304 } else {
305 return 0;
306 }
307}
308
309static int strlib_characters(lua_State *L)
310{
311 luaL_checkstring(L, 1);
312 lua_settop(L, 1);
313 lua_pushinteger(L, 0);
314 lua_pushcclosure(L, strlib_aux_characters, 2);
315 return 1;
316}
317
318static int strlib_bytetable(lua_State *L)
319{
320 size_t l;
321 const char *s = luaL_checklstring(L, 1, &l);
322 lua_createtable(L, (int) l, 0);
323 for (size_t i = 0; i < l; i++) {
324 lua_pushinteger(L, (unsigned char)*(s + i));
325 lua_rawseti(L, -2, i + 1);
326 }
327 return 1;
328}
329
330static int strlib_utfvaluetable(lua_State *L)
331{
332 size_t n = 1;
333 size_t l = 0;
334 size_t p = 0;
335 const char *s = luaL_checklstring(L, 1, &l);
336 lua_createtable(L, (int) l, 0);
337 while (p < l) {
338 lua_pushinteger(L, strlib_aux_tounicode(s, l, &p));
339 lua_rawseti(L, -2, n++);
340 }
341 return 1;
342}
343
344static int strlib_utfcharactertable(lua_State *L)
345{
346 size_t n = 1;
347 size_t l = 0;
348 size_t p = 0;
349 const char *s = luaL_checklstring(L, 1, &l);
350 lua_createtable(L, (int) l, 0);
351 while (p < l) {
352 int b = strlib_aux_tounichar(s, l, p);
353 if (b) {
354 lua_pushlstring(L, s + p, b);
355 p += b;
356 } else {
357 lua_pushliteral(L, utf_fffd_string);
358 p += 1;
359 }
360 lua_rawseti(L, -2, n++);
361 }
362 return 1;
363}
364
365static int strlib_linetable(lua_State *L)
366{
367 size_t n = 1;
368 size_t l = 0;
369 size_t p = 0;
370 const char *s = luaL_checklstring(L, 1, &l);
371 lua_createtable(L, (int) l, 0);
372 while (p < l) {
373 size_t b = 0;
374 size_t m = strlib_aux_toline(s, l, p, &b);
375 if (m) {
376 lua_pushlstring(L, s + p, m);
377 } else {
378 lua_pushliteral(L, "");
379 }
380 p += m + b;
381 lua_rawseti(L, -2, n++);
382 }
383 return 1;
384}
385
386
392
393# define MAXUNICODE 0x10FFFF
394
395
402
403static int strlib_utfcharacter(lua_State *L)
404{
405 int n = lua_gettop(L);
406 if (n == 1) {
407 char u[6];
408 char *c = aux_uni2string(&u[0], (unsigned) lua_tointeger(L, 1));
409 *c = '\0';
410 lua_pushstring(L, u);
411 return 1;
412 } else {
413 luaL_Buffer b;
414 luaL_buffinitsize(L, &b, (size_t) n * 4);
415 for (int i = 1; i <= n; i++) {
416 unsigned u = (unsigned) lua_tointeger(L, i);
417 if (u <= MAXUNICODE) {
418 if (0x80 > u) {
419 luaL_addchar(&b, (unsigned char) u);
420 } else {
421 if (0x800 > u)
422 luaL_addchar(&b, (unsigned char) (0xC0 | (u >> 6)));
423 else {
424 if (0x10000 > u)
425 luaL_addchar(&b, (unsigned char) (0xE0 | (u >> 12)));
426 else {
427 luaL_addchar(&b, (unsigned char) (0xF0 | (u >> 18)));
428 luaL_addchar(&b, (unsigned char) (0x80 | (0x3F & (u >> 12))));
429 }
430 luaL_addchar(&b, 0x80 | (0x3F & (u >> 6)));
431 }
432 luaL_addchar(&b, 0x80 | (0x3F & u));
433 }
434 }
435 }
436 luaL_pushresult(&b);
437 return 1;
438 }
439}
440
441
448
449static int strlib_utfvalue(lua_State *L)
450{
451 size_t l = 0;
452 size_t p = 0;
453 int i = 0;
454 const char *s = luaL_checklstring(L, 1, &l);
455 while (p < l) {
456 lua_pushinteger(L, strlib_aux_tounicode(s, l, &p));
457 i++;
458 }
459 return i;
460}
461
462
463
464static int strlib_utflength(lua_State *L)
465{
466 size_t ls = 0;
467 size_t ind = 0;
468 size_t n = 0;
469 const char *s = lua_tolstring(L, 1, &ls);
470 while (ind < ls) {
471 unsigned char i = (unsigned char) *(s + ind);
472 if (i < 0x80) {
473 ind += 1;
474 } else if (i >= 0xF0) {
475 ind += 4;
476 } else if (i >= 0xE0) {
477 ind += 3;
478 } else if (i >= 0xC0) {
479 ind += 2;
480 } else {
481
482 ind += 1;
483 }
484 n++;
485 }
486 lua_pushinteger(L, n);
487 return 1;
488}
489
490
491
492static int strlib_format_f6(lua_State *L)
493{
494 double n = luaL_optnumber(L, 1, 0.0);
495 if (n == 0.0) {
496 lua_pushliteral(L, "0");
497 } else if (n == 1.0) {
498 lua_pushliteral(L, "1");
499 } else {
500 char s[128];
501 int i, l;
502
503 if (fmod(n, 1) == 0) {
504 i = snprintf(s, 128, "%i", (int) n);
505 } else {
506 if (lua_type(L, 2) == LUA_TSTRING) {
507 const char *f = lua_tostring(L, 2);
508 i = snprintf(s, 128, f, n);
509 } else {
510 i = snprintf(s, 128, "%0.6f", n) ;
511 }
512 l = i - 1;
513 while (l > 1) {
514 if (s[l - 1] == '.') {
515 break;
516 } else if (s[l] == '0') {
517 s[l] = '\0';
518 --i;
519 } else {
520 break;
521 }
522 l--;
523 }
524 }
525 lua_pushlstring(L, s, i);
526 }
527 return 1;
528}
529
530
536
537inline static unsigned char strlib_aux_hexdigit(unsigned char n) {
538 return (n < 10 ? '0' : 'A' - 10) + n;
539}
540
541# define invalid_unicode(u) ( \
542 (u >= 0x00E000 && u <= 0x00F8FF) || \
543 (u >= 0x0F0000 && u <= 0x0FFFFF) || \
544 (u >= 0x100000 && u <= 0x10FFFF) || \
545 \
546 (u >= 0x00D7FF && u <= 0x00DFFF) \
547)
548
549static int strlib_format_tounicode16(lua_State *L)
550{
551 lua_Integer u = lua_tointeger(L, 1);
552 if (invalid_unicode(u)) {
553 lua_pushliteral(L, "FFFD");
554 } else if (u < 0xD7FF || (u > 0xDFFF && u <= 0xFFFF)) {
555 char s[4] ;
556 s[3] = strlib_aux_hexdigit((unsigned char) ((u & 0x000F) >> 0));
557 s[2] = strlib_aux_hexdigit((unsigned char) ((u & 0x00F0) >> 4));
558 s[1] = strlib_aux_hexdigit((unsigned char) ((u & 0x0F00) >> 8));
559 s[0] = strlib_aux_hexdigit((unsigned char) ((u & 0xF000) >> 12));
560 lua_pushlstring(L, s, 4);
561 } else {
562 unsigned u1, u2;
563 char s[8] ;
564 u = u - 0x10000;
565 u1 = (unsigned) (u >> 10) + 0xD800;
566 u2 = (unsigned) (u % 0x400) + 0xDC00;
567 s[3] = strlib_aux_hexdigit((unsigned char) ((u1 & 0x000F) >> 0));
568 s[2] = strlib_aux_hexdigit((unsigned char) ((u1 & 0x00F0) >> 4));
569 s[1] = strlib_aux_hexdigit((unsigned char) ((u1 & 0x0F00) >> 8));
570 s[0] = strlib_aux_hexdigit((unsigned char) ((u1 & 0xF000) >> 12));
571 s[7] = strlib_aux_hexdigit((unsigned char) ((u2 & 0x000F) >> 0));
572 s[6] = strlib_aux_hexdigit((unsigned char) ((u2 & 0x00F0) >> 4));
573 s[5] = strlib_aux_hexdigit((unsigned char) ((u2 & 0x0F00) >> 8));
574 s[4] = strlib_aux_hexdigit((unsigned char) ((u2 & 0xF000) >> 12));
575 lua_pushlstring(L, s, 8);
576 }
577 return 1;
578}
579
580static int strlib_format_toutf8(lua_State *L)
581{
582 if (lua_type(L, 1) == LUA_TTABLE) {
583 lua_Integer n = lua_rawlen(L, 1);
584 if (n > 0) {
585 luaL_Buffer b;
586 luaL_buffinitsize(L, &b, (n + 1) * 4);
587 for (lua_Integer i = 0; i <= n; i++) {
588
589 if (lua_rawgeti(L, 1, i) == LUA_TNUMBER) {
590 unsigned u = (unsigned) lua_tointeger(L, -1);
591 if (0x80 > u) {
592 luaL_addchar(&b, (unsigned char) u);
593 } else if (invalid_unicode(u)) {
594 luaL_addchar(&b, 0xFF);
595 luaL_addchar(&b, 0xFD);
596 } else {
597 if (0x800 > u)
598 luaL_addchar(&b, (unsigned char) (0xC0 | (u >> 6)));
599 else {
600 if (0x10000 > u)
601 luaL_addchar(&b, (unsigned char) (0xE0 | (u >> 12)));
602 else {
603 luaL_addchar(&b, (unsigned char) (0xF0 | (u >>18)));
604 luaL_addchar(&b, (unsigned char) (0x80 | (0x3F & (u >> 12))));
605 }
606 luaL_addchar(&b, 0x80 | (0x3F & (u >> 6)));
607 }
608 luaL_addchar(&b, 0x80 | (0x3F & u));
609 }
610 }
611 lua_pop(L, 1);
612 }
613 luaL_pushresult(&b);
614 } else {
615 lua_pushliteral(L, "");
616 }
617 return 1;
618 }
619 return 0;
620}
621
622
659
660static int strlib_format_toutf32(lua_State *L)
661{
662 if (lua_type(L, 1) == LUA_TTABLE) {
663 lua_Integer n = lua_rawlen(L, 1);
664 if (n > 0) {
665 luaL_Buffer b;
666 luaL_buffinitsize(L, &b, (n + 2) * 4);
667 for (lua_Integer i = 0; i <= n; i++) {
668
669 if (lua_rawgeti(L, 1, i) == LUA_TNUMBER) {
670 unsigned u = (unsigned) lua_tointeger(L, -1);
671 if (invalid_unicode(u)) {
672 luaL_addchar(&b, 0x00);
673 luaL_addchar(&b, 0x00);
674 luaL_addchar(&b, 0xFF);
675 luaL_addchar(&b, 0xFD);
676 } else {
677 luaL_addchar(&b, (unsigned char) ((u & 0x000000FF) ));
678 luaL_addchar(&b, (unsigned char) ((u & 0x0000FF00) >> 8));
679 luaL_addchar(&b, (unsigned char) ((u & 0x00FF0000) >> 16));
680 luaL_addchar(&b, (unsigned char) ((u & 0xFF000000) >> 24));
681 }
682 }
683 lua_pop(L, 1);
684 }
685 for (int i = 0; i <= 3; i++) {
686 luaL_addchar(&b, 0);
687 }
688 luaL_pushresult(&b);
689 } else {
690 lua_pushliteral(L, "");
691 }
692 return 1;
693 }
694 return 0;
695}
696
697
698
699
700
701
702
703
704static int strlib_pack_rows_columns(lua_State* L)
705{
706 if (lua_type(L, 1) == LUA_TTABLE) {
707 lua_Integer rows = lua_rawlen(L, 1);
708 if (lua_rawgeti(L, 1, 1) == LUA_TTABLE) {
709 lua_Integer columns = lua_rawlen(L, -1);
710 switch (lua_rawgeti(L, -1, 1)) {
711 case LUA_TNUMBER:
712 {
713 lua_Integer size = rows * columns;
714 unsigned char *result = lmt_memory_malloc(size);
715 lua_pop(L, 2);
716 if (result) {
717 unsigned char *first = result;
718 for (lua_Integer r = 1; r <= rows; r++) {
719 if (lua_rawgeti(L, -1, r) == LUA_TTABLE) {
720 for (lua_Integer c = 1; c <= columns; c++) {
721 if (lua_rawgeti(L, -1, c) == LUA_TNUMBER) {
722 lua_Integer v = lua_tointeger(L, -1);
723 *result++ = v < 0 ? 0 : v > 255 ? 255 : (unsigned char) v;
724 } else {
725 *result++ = 0;
726 }
727 lua_pop(L, 1);
728 }
729 }
730 lua_pop(L, 1);
731 }
732 lua_pushlstring(L, (char *) first, result - first);
733 return 1;
734 }
735 }
736 case LUA_TTABLE:
737 {
738 lua_Integer mode = lua_rawlen(L, -1);
739 lua_Integer size = rows * columns * mode;
740 unsigned char *result = lmt_memory_malloc(size);
741 lua_pop(L, 2);
742 if (result) {
743 unsigned char *first = result;
744 for (lua_Integer r = 1; r <= rows; r++) {
745 if (lua_rawgeti(L, -1, r) == LUA_TTABLE) {
746 for (lua_Integer c = 1; c <= columns; c++) {
747 if (lua_rawgeti(L, -1, c) == LUA_TTABLE) {
748 for (int i = 1; i <= mode; i++) {
749 if (lua_rawgeti(L, -1, i) == LUA_TNUMBER) {
750 lua_Integer v = lua_tointeger(L, -1);
751 *result++ = v < 0 ? 0 : v > 255 ? 255 : (unsigned char) v;
752 } else {
753 *result++ = 0;
754 }
755 lua_pop(L, 1);
756 }
757 }
758 lua_pop(L, 1);
759 }
760 }
761 lua_pop(L, 1);
762 }
763 lua_pushlstring(L, (char *) first, result - first);
764 return 1;
765 }
766 }
767 }
768 }
769 }
770 lua_pushnil(L);
771 return 1;
772}
773
774
778
779static int strlib_hextocharacters(lua_State *L)
780{
781 size_t ls = 0;
782 const char *s = lua_tolstring(L, 1, &ls);
783 if (ls > 0) {
784 luaL_Buffer b;
785 luaL_buffinitsize(L, &b, ls/2);
786 while (1) {
787 unsigned char first = *s++;
788 switch (first) {
789 case ' ': case '\n': case '\r': case '\t':
790 continue;
791 case '\0':
792 goto DONE;
793 default:
794 {
795 unsigned char second = *s++;
796 switch (second) {
797 case ' ': case '\n': case '\r': case '\t':
798 continue;
799 case '\0':
800 goto BAD;
801 default:
802 {
803 unsigned char chr;
804 if (first >= '0' && first <= '9') {
805 chr = 16 * (first - '0');
806 } else if (first>= 'A' && first <= 'F') {
807 chr = 16 * (first - 'A' + 10);
808 } else if (first >= 'a' && first <= 'f') {
809 chr = 16 * (first - 'a' + 10);
810 } else {
811 goto BAD;
812 }
813 if (second >= '0' && second <= '9') {
814 chr += second - '0';
815 } else if (second >= 'A' && second <= 'F') {
816 chr += second - 'A' + 10;
817 } else if (first >= 'a' && second <= 'f') {
818 chr += second - 'a' + 10;
819 } else {
820 goto BAD;
821 }
822 luaL_addchar(&b, chr);
823 break;
824 }
825 }
826 break;
827 }
828 }
829 }
830 DONE:
831 luaL_pushresult(&b);
832 return 1;
833 BAD:
834 lua_pushboolean(L, 0);
835 return 1;
836 } else {
837 lua_pushliteral(L, "");
838 return 1;
839 }
840}
841
842static int strlib_octtointeger(lua_State *L)
843{
844 const char *s = lua_tostring(L, 1);
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859 lua_pushinteger(L, strtoul(s, NULL, 8));
860 return 1;
861}
862
863static int strlib_dectointeger(lua_State *L)
864{
865 const char *s = lua_tostring(L, 1);
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881 lua_pushinteger(L, strtoul(s, NULL, 10));
882 return 1;
883}
884
885static int strlib_hextointeger(lua_State *L)
886{
887 const char *s = lua_tostring(L, 1);
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906 lua_pushinteger(L, strtoul(s, NULL, 16));
907 return 1;
908}
909
910static int strlib_chrtointeger(lua_State *L)
911{
912 lua_Integer n = 0;
913 size_t l = 0;
914 const char *s = lua_tolstring(L, 1, &l);
915 if (l > 0) {
916 size_t p = 0;
917 while (p < l && n < 0xFFFFFFFF) {
918 n = n * 255 + (unsigned char) s[p];
919 p++;
920 }
921 lua_pushinteger(L, n);
922 }
923 return 1;
924}
925
926static const luaL_Reg strlib_function_list[] = {
927 { "characters", strlib_characters },
928 { "characterpairs", strlib_characterpairs },
929 { "bytes", strlib_bytes },
930 { "bytepairs", strlib_bytepairs },
931 { "bytetable", strlib_bytetable },
932 { "linetable", strlib_linetable },
933 { "utfvalues", strlib_utfvalues },
934 { "utfcharacters", strlib_utfcharacters },
935 { "utfcharacter", strlib_utfcharacter },
936 { "utfvalue", strlib_utfvalue },
937 { "utflength", strlib_utflength },
938 { "utfvaluetable", strlib_utfvaluetable },
939 { "utfcharactertable", strlib_utfcharactertable },
940 { "f6", strlib_format_f6 },
941 { "tounicode16", strlib_format_tounicode16 },
942 { "toutf8", strlib_format_toutf8 },
943
944 { "toutf32", strlib_format_toutf32 },
945 { "packrowscolumns", strlib_pack_rows_columns },
946 { "hextocharacters", strlib_hextocharacters },
947 { "octtointeger", strlib_octtointeger },
948 { "dectointeger", strlib_dectointeger },
949 { "hextointeger", strlib_hextointeger },
950 { "chrtointeger", strlib_chrtointeger },
951 { NULL, NULL },
952};
953
954int luaextend_string(lua_State * L)
955{
956 lua_getglobal(L, "string");
957 for (const luaL_Reg *lib = strlib_function_list; lib->name; lib++) {
958 lua_pushcfunction(L, lib->func);
959 lua_setfield(L, -2, lib->name);
960 }
961 lua_pop(L, 1);
962 return 1;
963}
964
965
973
974
1077 |