aboutsummaryrefslogtreecommitdiff
path: root/lobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'lobject.c')
-rw-r--r--lobject.c66
1 files changed, 37 insertions, 29 deletions
diff --git a/lobject.c b/lobject.c
index 58eecd4a..ce14059f 100644
--- a/lobject.c
+++ b/lobject.c
@@ -392,11 +392,20 @@ void luaO_tostring (lua_State *L, TValue *obj) {
392} 392}
393 393
394 394
395
396
397/*
398** {==================================================================
399** 'luaO_pushvfstring'
400** ===================================================================
401*/
402
395/* size for buffer space used by 'luaO_pushvfstring' */ 403/* size for buffer space used by 'luaO_pushvfstring' */
396#define BUFVFS 400 404#define BUFVFS 400
397 405
398/* buffer used by 'luaO_pushvfstring' */ 406/* buffer used by 'luaO_pushvfstring' */
399typedef struct BuffFS { 407typedef struct BuffFS {
408 lua_State *L;
400 int pushed; /* number of string pieces already on the stack */ 409 int pushed; /* number of string pieces already on the stack */
401 int blen; /* length of partial string in 'space' */ 410 int blen; /* length of partial string in 'space' */
402 char space[BUFVFS]; /* holds last part of the result */ 411 char space[BUFVFS]; /* holds last part of the result */
@@ -407,7 +416,8 @@ typedef struct BuffFS {
407** Push given string to the stack, as part of the buffer. If the stack 416** Push given string to the stack, as part of the buffer. If the stack
408** is almost full, join all partial strings in the stack into one. 417** is almost full, join all partial strings in the stack into one.
409*/ 418*/
410static void pushstr (lua_State *L, BuffFS *buff, const char *str, size_t l) { 419static void pushstr (BuffFS *buff, const char *str, size_t l) {
420 lua_State *L = buff->L;
411 setsvalue2s(L, L->top, luaS_newlstr(L, str, l)); 421 setsvalue2s(L, L->top, luaS_newlstr(L, str, l));
412 L->top++; 422 L->top++;
413 buff->pushed++; 423 buff->pushed++;
@@ -421,8 +431,8 @@ static void pushstr (lua_State *L, BuffFS *buff, const char *str, size_t l) {
421/* 431/*
422** empty the buffer space into the stack 432** empty the buffer space into the stack
423*/ 433*/
424static void clearbuff (lua_State *L, BuffFS *buff) { 434static void clearbuff (BuffFS *buff) {
425 pushstr(L, buff, buff->space, buff->blen); /* push buffer contents */ 435 pushstr(buff, buff->space, buff->blen); /* push buffer contents */
426 buff->blen = 0; /* space now is empty */ 436 buff->blen = 0; /* space now is empty */
427} 437}
428 438
@@ -431,10 +441,10 @@ static void clearbuff (lua_State *L, BuffFS *buff) {
431** Get a space of size 'sz' in the buffer. If buffer has not enough 441** Get a space of size 'sz' in the buffer. If buffer has not enough
432** space, empty it. 'sz' must fit in an empty space. 442** space, empty it. 'sz' must fit in an empty space.
433*/ 443*/
434static char *getbuff (lua_State *L, BuffFS *buff, size_t sz) { 444static char *getbuff (BuffFS *buff, size_t sz) {
435 lua_assert(buff->blen <= BUFVFS); lua_assert(sz <= BUFVFS); 445 lua_assert(buff->blen <= BUFVFS); lua_assert(sz <= BUFVFS);
436 if (sz > BUFVFS - cast_sizet(buff->blen)) /* string does not fit? */ 446 if (sz > BUFVFS - cast_sizet(buff->blen)) /* string does not fit? */
437 clearbuff(L, buff); 447 clearbuff(buff);
438 return buff->space + buff->blen; 448 return buff->space + buff->blen;
439} 449}
440 450
@@ -446,16 +456,15 @@ static char *getbuff (lua_State *L, BuffFS *buff, size_t sz) {
446** Add 'str' to the buffer. If string is larger than the buffer space, 456** Add 'str' to the buffer. If string is larger than the buffer space,
447** push the string directly to the stack. 457** push the string directly to the stack.
448*/ 458*/
449static void addstr2buff (lua_State *L, BuffFS *buff, const char *str, 459static void addstr2buff (BuffFS *buff, const char *str, size_t slen) {
450 size_t slen) {
451 if (slen <= BUFVFS) { /* does string fit into buffer? */ 460 if (slen <= BUFVFS) { /* does string fit into buffer? */
452 char *bf = getbuff(L, buff, slen); 461 char *bf = getbuff(buff, slen);
453 memcpy(bf, str, slen); /* add string to buffer */ 462 memcpy(bf, str, slen); /* add string to buffer */
454 addsize(buff, slen); 463 addsize(buff, slen);
455 } 464 }
456 else { /* string larger than buffer */ 465 else { /* string larger than buffer */
457 clearbuff(L, buff); /* string comes after buffer's content */ 466 clearbuff(buff); /* string comes after buffer's content */
458 pushstr(L, buff, str, slen); /* push string */ 467 pushstr(buff, str, slen); /* push string */
459 } 468 }
460} 469}
461 470
@@ -463,8 +472,8 @@ static void addstr2buff (lua_State *L, BuffFS *buff, const char *str,
463/* 472/*
464** Add a number to the buffer. 473** Add a number to the buffer.
465*/ 474*/
466static void addnum2buff (lua_State *L, BuffFS *buff, TValue *num) { 475static void addnum2buff (BuffFS *buff, TValue *num) {
467 char *numbuff = getbuff(L, buff, MAXNUMBER2STR); 476 char *numbuff = getbuff(buff, MAXNUMBER2STR);
468 size_t len = tostringbuff(num, numbuff); /* format number into 'numbuff' */ 477 size_t len = tostringbuff(num, numbuff); /* format number into 'numbuff' */
469 addsize(buff, len); 478 addsize(buff, len);
470} 479}
@@ -478,58 +487,55 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
478 BuffFS buff; /* holds last part of the result */ 487 BuffFS buff; /* holds last part of the result */
479 const char *e; /* points to next '%' */ 488 const char *e; /* points to next '%' */
480 buff.pushed = buff.blen = 0; 489 buff.pushed = buff.blen = 0;
490 buff.L = L;
481 while ((e = strchr(fmt, '%')) != NULL) { 491 while ((e = strchr(fmt, '%')) != NULL) {
482 addstr2buff(L, &buff, fmt, e - fmt); /* add 'fmt' up to '%' */ 492 addstr2buff(&buff, fmt, e - fmt); /* add 'fmt' up to '%' */
483 switch (*(e + 1)) { /* conversion specifier */ 493 switch (*(e + 1)) { /* conversion specifier */
484 case 's': { /* zero-terminated string */ 494 case 's': { /* zero-terminated string */
485 const char *s = va_arg(argp, char *); 495 const char *s = va_arg(argp, char *);
486 if (s == NULL) s = "(null)"; 496 if (s == NULL) s = "(null)";
487 addstr2buff(L, &buff, s, strlen(s)); 497 addstr2buff(&buff, s, strlen(s));
488 break; 498 break;
489 } 499 }
490 case 'c': { /* an 'int' as a character */ 500 case 'c': { /* an 'int' as a character */
491 /* if non-printable character, print its code */ 501 char c = cast_uchar(va_arg(argp, int));
492 char *bf = getbuff(L, &buff, 10); 502 addstr2buff(&buff, &c, sizeof(char));
493 int c = va_arg(argp, int);
494 int len = (lisprint(c)) ? l_sprintf(bf, 10, "%c", c)
495 : l_sprintf(bf, 10, "<\\%u>", c);
496 addsize(&buff, len);
497 break; 503 break;
498 } 504 }
499 case 'd': { /* an 'int' */ 505 case 'd': { /* an 'int' */
500 TValue num; 506 TValue num;
501 setivalue(&num, va_arg(argp, int)); 507 setivalue(&num, va_arg(argp, int));
502 addnum2buff(L, &buff, &num); 508 addnum2buff(&buff, &num);
503 break; 509 break;
504 } 510 }
505 case 'I': { /* a 'lua_Integer' */ 511 case 'I': { /* a 'lua_Integer' */
506 TValue num; 512 TValue num;
507 setivalue(&num, cast(lua_Integer, va_arg(argp, l_uacInt))); 513 setivalue(&num, cast(lua_Integer, va_arg(argp, l_uacInt)));
508 addnum2buff(L, &buff, &num); 514 addnum2buff(&buff, &num);
509 break; 515 break;
510 } 516 }
511 case 'f': { /* a 'lua_Number' */ 517 case 'f': { /* a 'lua_Number' */
512 TValue num; 518 TValue num;
513 setfltvalue(&num, cast_num(va_arg(argp, l_uacNumber))); 519 setfltvalue(&num, cast_num(va_arg(argp, l_uacNumber)));
514 addnum2buff(L, &buff, &num); 520 addnum2buff(&buff, &num);
515 break; 521 break;
516 } 522 }
517 case 'p': { /* a pointer */ 523 case 'p': { /* a pointer */
518 const int sz = 3 * sizeof(void*) + 8; /* enough space for '%p' */ 524 const int sz = 3 * sizeof(void*) + 8; /* enough space for '%p' */
519 char *bf = getbuff(L, &buff, sz); 525 char *bf = getbuff(&buff, sz);
520 void *p = va_arg(argp, void *); 526 void *p = va_arg(argp, void *);
521 int len = l_sprintf(bf, sz, "%p", p); 527 int len = lua_pointer2str(bf, sz, p);
522 addsize(&buff, len); 528 addsize(&buff, len);
523 break; 529 break;
524 } 530 }
525 case 'U': { /* a 'long' as a UTF-8 sequence */ 531 case 'U': { /* a 'long' as a UTF-8 sequence */
526 char bf[UTF8BUFFSZ]; 532 char bf[UTF8BUFFSZ];
527 int len = luaO_utf8esc(bf, va_arg(argp, long)); 533 int len = luaO_utf8esc(bf, va_arg(argp, long));
528 addstr2buff(L, &buff, bf + UTF8BUFFSZ - len, len); 534 addstr2buff(&buff, bf + UTF8BUFFSZ - len, len);
529 break; 535 break;
530 } 536 }
531 case '%': { 537 case '%': {
532 addstr2buff(L, &buff, "%", 1); 538 addstr2buff(&buff, "%", 1);
533 break; 539 break;
534 } 540 }
535 default: { 541 default: {
@@ -539,8 +545,8 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
539 } 545 }
540 fmt = e + 2; /* skip '%' and the specifier */ 546 fmt = e + 2; /* skip '%' and the specifier */
541 } 547 }
542 addstr2buff(L, &buff, fmt, strlen(fmt)); /* rest of 'fmt' */ 548 addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */
543 clearbuff(L, &buff); /* empty buffer into the stack */ 549 clearbuff(&buff); /* empty buffer into the stack */
544 if (buff.pushed > 1) 550 if (buff.pushed > 1)
545 luaV_concat(L, buff.pushed); /* join all partial results */ 551 luaV_concat(L, buff.pushed); /* join all partial results */
546 return svalue(s2v(L->top - 1)); 552 return svalue(s2v(L->top - 1));
@@ -556,6 +562,8 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
556 return msg; 562 return msg;
557} 563}
558 564
565/* }================================================================== */
566
559 567
560#define RETS "..." 568#define RETS "..."
561#define PRE "[string \"" 569#define PRE "[string \""