mruby/c VM Source Code master (2026/08/06)
Loading...
Searching...
No Matches
console.c
Go to the documentation of this file.
1
14
15/***** Feature test switches ************************************************/
16/***** System headers *******************************************************/
17//@cond
18#include "vm_config.h"
19#include <stdint.h>
20#include <stdarg.h>
21#include <string.h>
22#include <assert.h>
23#if MRBC_USE_FLOAT
24#include <stdio.h>
25#endif
26//@endcond
27
28/***** Local headers ********************************************************/
29#include "mrubyc.h"
30
31/***** Constant values ******************************************************/
32#define MRBC_PRINTF_MAX_WIDTH 82
33
34
35/***** Macros ***************************************************************/
36/***** Typedefs *************************************************************/
37/***** Function prototypes **************************************************/
38/***** Local variables ******************************************************/
39/***** Global variables *****************************************************/
40/***** Signal catching functions ********************************************/
41/***** Local functions ******************************************************/
42//----------------------------------------------------------------
43/* sub function for mrbc_printf
44*/
45static int mrbc_printf_sub_output_arg( mrbc_printf_t *pf, va_list *ap )
46{
47 int ret;
48
49 switch(pf->fmt.type) {
50 case 'c':
51 ret = mrbc_printf_char( pf, va_arg(*ap, int) );
52 break;
53
54 case 's':
55 ret = mrbc_printf_str( pf, va_arg(*ap, char *), ' ');
56 break;
57
58 case 'd':
59 case 'i':
60 case 'u':
61 ret = mrbc_printf_int( pf, va_arg(*ap, int), 10);
62 break;
63
64 case 'D': // for mrbc_int_t (see mrbc_print_sub)
65#if defined(MRBC_INT16)
66 ret = mrbc_printf_int( pf, (mrbc_int_t)va_arg(*ap, int), 10);
67#else
68 ret = mrbc_printf_int( pf, va_arg(*ap, mrbc_int_t), 10);
69#endif
70 break;
71
72 case 'b':
73 case 'B':
74 ret = mrbc_printf_bit( pf, va_arg(*ap, unsigned int), 1);
75 break;
76
77 case 'x':
78 case 'X':
79 ret = mrbc_printf_bit( pf, va_arg(*ap, unsigned int), 4);
80 break;
81
82#if MRBC_USE_FLOAT
83 case 'f':
84 case 'e':
85 case 'E':
86 case 'g':
87 case 'G':
88 ret = mrbc_printf_float( pf, va_arg(*ap, double) );
89 break;
90#endif
91 case 'p':
92 ret = mrbc_printf_pointer( pf, va_arg(*ap, void *) );
93 break;
94
95 default:
96 ret = 0;
97 break;
98 }
99
100 return ret;
101}
102
103/* sub function to print a hashkey
104 */
105static int mrbc_p_sub_hashkey(const mrbc_value *v)
106{
107 switch( mrbc_type(*v) ) {
108 case MRBC_TT_SYMBOL:{
109 const char *s = mrbc_symbol_cstr(v);
110 const char *fmt = strchr(s, ':') ? "\"%s\": " : "%s: ";
111 mrbc_printf(fmt, s);
112 break;
113 }
114 default: {
115 mrbc_p_sub(v);
116 mrbc_print(" => ");
117 break;
118 }
119 }
120 return 0;
121}
122
123
124/***** Global functions *****************************************************/
125
126//================================================================
131void mrbc_putchar(char c)
132{
133#if defined(MRBC_CONVERT_CRLF)
134 static const char CRLF[2] = "\r\n";
135 if( c == '\n' ) {
136 mrbc_hal_write(1, CRLF, 2);
137 } else {
138 mrbc_hal_write(1, &c, 1);
139 }
140
141#else
142 mrbc_hal_write(1, &c, 1);
143#endif
144}
145
146
147//================================================================
153{
154 // normal case
155 if( !mrbc_is_nested_symid(sym_id) ) {
156 mrbc_printf("%s", mrbc_symid_to_str(sym_id) );
157 return;
158 }
159
160 // nested case
161 mrbc_sym id1, id2;
162 mrbc_separate_nested_symid( sym_id, &id1, &id2 );
163
164 mrbc_print_symbol( id1 );
165 mrbc_print("::");
166 mrbc_print_symbol( id2 );
167}
168
169
170//================================================================
176void mrbc_nprint(const char *str, int size)
177{
178#if defined(MRBC_CONVERT_CRLF)
179 static const char CRLF[2] = "\r\n";
180 const char *p1 = str;
181 const char *p2 = str;
182
183 for( int i = 0; i < size; i++ ) {
184 if( *p1++ == '\n' ) {
185 mrbc_hal_write(1, p2, p1 - p2 - 1);
186 mrbc_hal_write(1, CRLF, 2);
187 p2 = p1;
188 }
189 }
190 if( p1 != p2 ) {
191 mrbc_hal_write(1, p2, p1 - p2);
192 }
193
194#else
195 mrbc_hal_write(1, str, size);
196#endif
197}
198
199
200//================================================================
205void mrbc_printf(const char *fstr, ...)
206{
207 va_list ap;
208 va_start(ap, fstr);
209
210 mrbc_vprintf( fstr, ap );
211
212 va_end(ap);
213}
214
215
216//================================================================
223void mrbc_asprintf(char **buf, int bufsiz, const char *fstr, ...)
224{
225 va_list ap;
226 va_start(ap, fstr);
227
228 mrbc_vasprintf( buf, bufsiz, fstr, ap );
229
230 va_end(ap);
231}
232
233
234//================================================================
241void mrbc_snprintf(char *buf, int bufsiz, const char *fstr, ...)
242{
243 va_list ap;
244 va_start(ap, fstr);
245
246 mrbc_printf_t pf;
247 mrbc_printf_init( &pf, buf, bufsiz, fstr );
248
249 while( 1 ) {
250 if( mrbc_printf_main( &pf ) <= 0 ) break;
251 // normal end (==0) or buffer full (<0).
252 if( mrbc_printf_sub_output_arg( &pf, &ap ) != 0 ) break;
253 }
254
255 mrbc_printf_end( &pf );
256 va_end(ap);
257}
258
259
260//================================================================
266void mrbc_vprintf(const char *fstr, va_list ap)
267{
268 va_list ap1;
269 va_copy( ap1, ap );
270
271 mrbc_printf_t pf;
272 char buf[MRBC_PRINTF_MAX_WIDTH];
273 mrbc_printf_init( &pf, buf, sizeof(buf), fstr );
274
275 while( 1 ) {
276 int ret = mrbc_printf_main( &pf );
277 if( mrbc_printf_len( &pf ) ) {
278 mrbc_nprint( buf, mrbc_printf_len( &pf ) );
279 mrbc_printf_clear( &pf );
280 }
281 if( ret == 0 ) break;
282 if( ret < 0 ) continue;
283
284 mrbc_printf_sub_output_arg( &pf, &ap1 );
285 mrbc_nprint( buf, mrbc_printf_len( &pf ) );
286 mrbc_printf_clear( &pf );
287 }
288
289 va_end(ap1);
290}
291
292
293//================================================================
301void mrbc_vasprintf(char **buf, int bufsiz, const char *fstr, va_list ap)
302{
303 va_list ap1, ap_bak;
304 va_copy( ap1, ap );
305
306 mrbc_printf_t pf;
307 mrbc_printf_init( &pf, *buf, bufsiz, fstr );
308
309 while( 1 ) {
310 va_copy(ap_bak, ap1);
311 mrbc_printf_t pf_bak = pf;
312
313 int ret = mrbc_printf_main( &pf );
314 if( ret == 0 ) break; // normal break loop.
315 if( ret < 0 ) goto INCREASE_BUFFER;
316
317 ret = mrbc_printf_sub_output_arg( &pf, &ap1 );
318 if( ret >= 0 ) goto NEXT_LOOP;
319
320 va_end(ap1);
321 va_copy(ap1, ap_bak);
322 pf = pf_bak;
323
324 INCREASE_BUFFER:
325 bufsiz += 64;
326 void *newbuf = mrbc_raw_realloc( pf.buf, bufsiz );
327
328 mrbc_printf_replace_buffer( &pf, newbuf, bufsiz );
329 *buf = newbuf;
330
331 NEXT_LOOP:
332 va_end(ap_bak);
333 }
334
335 mrbc_printf_end( &pf );
336 va_end(ap1);
337 va_end(ap_bak);
338}
339
340
341//================================================================
346void mrbc_p(const mrbc_value *v)
347{
348 mrbc_p_sub( v );
349 mrbc_putchar('\n');
350}
351
352
353//================================================================
359void mrbc_char_to_s( char *buf, const void *src )
360{
361 unsigned char ch = *((unsigned char *)src);
362
363 if( ch == 0x7f ) goto hex;
364 if( ch < ' ' ) {
365 char ch1 = "\0\0\0\0\0\0\0abtnvfr\0\0\0\0\0\0\0\0\0\0\0\0\0e\0\0\0"[ ch ];
366 if( ch1 == 0 ) goto hex;
367 ch = ch1;
368 goto esc;
369 }
370 if( ch == '"' || ch == '\\' ) {
371 goto esc;
372 }
373
374 buf[0] = ch;
375 buf[1] = 0;
376 return;
377
378 hex:
379 buf[0] = '\\';
380 buf[1] = 'x';
381 buf[2] = "0123456789ABCDEF"[ch >> 4];
382 buf[3] = "0123456789ABCDEF"[ch & 0x0f];
383 buf[4] = 0;
384 return;
385
386 esc:
387 buf[0] = '\\';
388 buf[1] = ch;
389 buf[2] = 0;
390}
391
392
393//================================================================
399{
400 if( !v ) {
401 mrbc_print("(null)"); // wrong things are happen. but it give me a clue.
402 return 0;
403 }
404
405 switch( mrbc_type(*v) ) {
406 case MRBC_TT_NIL:
407 mrbc_print("nil");
408 break;
409
410 case MRBC_TT_SYMBOL:{
411 const char *s = mrbc_symbol_cstr( v );
412 const char *fmt = strchr(s, ':') ? "\":%s\"" : ":%s";
413 mrbc_printf(fmt, s);
414 } break;
415
416#if MRBC_USE_STRING
417 case MRBC_TT_STRING:{
418 const char *s = mrbc_string_cstr(v);
419 int size = mrbc_string_size(v);
420
421 mrbc_putchar('"');
422#if MRBC_USE_STRING_UTF8
423 for( int i = 0; i < size; ) {
424 unsigned char uch = (unsigned char)s[i];
425 if( uch < 0x80 ) {
426 char buf[10];
427 mrbc_char_to_s( buf, s + i );
428 mrbc_print( buf );
429 i++;
430 } else {
431 int raw_len = mrbc_string_utf8_size(s + i);
432 int valid = (raw_len >= 2 && i + raw_len <= size);
433 if( valid ) {
434 for( int j = 1; j < raw_len; j++ ) {
435 if( ((unsigned char)s[i + j] & 0xC0) != 0x80 ) { valid = 0; break; }
436 }
437 }
438 if( valid ) {
439 mrbc_nprint(s + i, raw_len);
440 i += raw_len;
441 } else {
442 char buf[5];
443 buf[0] = '\\'; buf[1] = 'x';
444 buf[2] = "0123456789ABCDEF"[uch >> 4];
445 buf[3] = "0123456789ABCDEF"[uch & 0x0f];
446 buf[4] = 0;
447 mrbc_print( buf );
448 i++;
449 }
450 }
451 }
452#else
453 for( int i = 0; i < size; i++ ) {
454 char buf[10];
455 mrbc_char_to_s( buf, s + i );
456 mrbc_print( buf );
457 }
458#endif
459 mrbc_putchar('"');
460 } break;
461#endif
462
463 case MRBC_TT_RANGE:{
464 const mrbc_value *v1 = mrbc_range_first_p(v);
465 const mrbc_value *v2 = mrbc_range_last_p(v);
466
467 if( mrbc_type(*v1) != MRBC_TT_NIL ||
468 mrbc_type(*v2) == MRBC_TT_NIL ) mrbc_p_sub(v1);
469
470 mrbc_print( mrbc_range_exclude_end(v) ? "..." : ".." );
471
472 if( mrbc_type(*v1) == MRBC_TT_NIL ||
473 mrbc_type(*v2) != MRBC_TT_NIL ) mrbc_p_sub(v2);
474 } break;
475
476 default:
478 break;
479 }
480
481#if 0
482 // display reference counter
484 mrbc_printf("#%d", v->obj->ref_count);
485 }
486#endif
487
488 return 0;
489}
490
491
492//================================================================
500{
501 if( mrbc_type(*v) == MRBC_TT_ARRAY ) {
502
503 for( int i = 0; i < mrbc_array_size(v); i++ ) {
504 if( i != 0 ) mrbc_putchar('\n');
505 mrbc_value v1 = mrbc_array_get(v, i);
506 mrbc_puts_sub(&v1);
507 }
508 return 0;
509 }
510
511 return mrbc_print_sub(v);
512}
513
514
515//================================================================
523{
524 int ret = 0;
525
526 switch( mrbc_type(*v) ) {
527 case MRBC_TT_EMPTY: mrbc_print("(empty)"); break;
528 case MRBC_TT_NIL: break;
529 case MRBC_TT_FALSE: mrbc_print("false"); break;
530 case MRBC_TT_TRUE: mrbc_print("true"); break;
531 case MRBC_TT_INTEGER: mrbc_printf("%D", v->i); break;
532#if MRBC_USE_FLOAT
533 case MRBC_TT_FLOAT: {
534 char buf[32];
535 mrbc_format_float(buf, sizeof(buf), v->d);
536 mrbc_printf("%s", buf);
537 } break;
538#endif
539 case MRBC_TT_SYMBOL: mrbc_print_symbol(v->sym_id); break;
540 case MRBC_TT_CLASS: // fall through.
541 case MRBC_TT_MODULE: mrbc_print_symbol(v->cls->sym_id); break;
542
543 case MRBC_TT_OBJECT:{
544 mrbc_printf("#<");
547
549 while( mrbc_kv_i_has_next( &ite ) ) {
550 mrbc_printf( mrbc_kv_i_is_first(&ite) ? " " : ", " );
551 const mrbc_kv *kv = mrbc_kv_i_next( &ite );
553 mrbc_p_sub(&kv->value);
554 }
555 mrbc_printf(">");
556 } break;
557
558 case MRBC_TT_PROC:
559 mrbc_printf("#<Proc:%08x>", MRBC_PTR_TO_UINT32(v->proc) );
560 //mrbc_printf("#<Proc:%08x, callinfo=%p>", MRBC_PTR_TO_UINT32(v->proc), MRBC_PTR_TO_UINT32(v->proc->callinfo) );
561 break;
562
563 case MRBC_TT_ARRAY:{
564 mrbc_putchar('[');
565 for( int i = 0; i < mrbc_array_size(v); i++ ) {
566 if( i != 0 ) mrbc_print(", ");
567 mrbc_value v1 = mrbc_array_get(v, i);
568 mrbc_p_sub(&v1);
569 }
570 mrbc_putchar(']');
571 } break;
572
573#if MRBC_USE_STRING
574 case MRBC_TT_STRING:
576 if( mrbc_string_size(v) != 0 &&
577 mrbc_string_cstr(v)[ mrbc_string_size(v) - 1 ] == '\n' ) ret = 1;
578 break;
579#endif
580
581 case MRBC_TT_RANGE:{
584
585 mrbc_print_sub(v1);
586 mrbc_print( mrbc_range_exclude_end(v) ? "..." : ".." );
587 mrbc_print_sub(v2);
588 } break;
589
590 case MRBC_TT_HASH:{
591 mrbc_putchar('{');
593 while( mrbc_hash_i_has_next(&ite) ) {
594 mrbc_value *vk = mrbc_hash_i_next(&ite);
596 mrbc_p_sub(vk+1);
597 if( mrbc_hash_i_has_next(&ite) ) mrbc_print(", ");
598 }
599 mrbc_putchar('}');
600 } break;
601
602 case MRBC_TT_HANDLE:
603 mrbc_printf("#<Handle:%08x>", MRBC_PTR_TO_UINT32(v->handle) );
604 break;
605
608 v->exception->message ?
609 (const char *)v->exception->message :
611 break;
612
613 default:
614 mrbc_printf("Not support MRBC_TT_XX(%d)", mrbc_type(*v));
615 break;
616 }
617
618 return ret;
619}
620
621
622//================================================================
629void mrbc_printf_replace_buffer(mrbc_printf_t *pf, char *buf, int size)
630{
631 int p_ofs = pf->p - pf->buf;
632 pf->buf = buf;
633 pf->buf_end = buf + size - 1;
634 pf->p = pf->buf + p_ofs;
635}
636
637
638//================================================================
648{
649 int ch = -1;
650 pf->fmt = (struct RPrintfFormat){0};
651
652 while( pf->p < pf->buf_end && (ch = *pf->fstr) != '\0' ) {
653 pf->fstr++;
654 if( ch == '%' ) {
655 if( *pf->fstr == '%' ) { // is "%%"
656 pf->fstr++;
657 } else {
658 goto PARSE_FLAG;
659 }
660 }
661 *pf->p++ = ch;
662 }
663 return -(ch != '\0');
664
665
666 PARSE_FLAG:
667 // parse format - '%' [flag] [width] [.precision] type
668 // e.g. "%05d"
669 while( (ch = *pf->fstr) ) {
670 switch( ch ) {
671 case '+': pf->fmt.flag_plus = 1; break;
672 case ' ': pf->fmt.flag_space = 1; break;
673 case '-': pf->fmt.flag_minus = 1; break;
674 case '0': pf->fmt.flag_zero = 1; break;
675 default : goto PARSE_WIDTH;
676 }
677 pf->fstr++;
678 }
679
680 PARSE_WIDTH:
681 while( (void)(ch = *pf->fstr - '0'), (0 <= ch && ch <= 9)) { // isdigit()
682 pf->fmt.width = pf->fmt.width * 10 + ch;
683 pf->fstr++;
684 }
685 if( *pf->fstr == '.' ) {
686 pf->fstr++;
687 while( (void)(ch = *pf->fstr - '0'), (0 <= ch && ch <= 9)) {
688 pf->fmt.precision = pf->fmt.precision * 10 + ch;
689 pf->fstr++;
690 }
691 }
692 if( *pf->fstr ) pf->fmt.type = *pf->fstr++;
693
694 return 1;
695}
696
697
698//================================================================
708{
709 if( pf->fmt.flag_minus ) {
710 if( pf->p == pf->buf_end ) return -1;
711 *pf->p++ = ch;
712 }
713
714 int width = pf->fmt.width;
715 while( --width > 0 ) {
716 if( pf->p == pf->buf_end ) return -1;
717 *pf->p++ = ' ';
718 }
719
720 if( !pf->fmt.flag_minus ) {
721 if( pf->p == pf->buf_end ) return -1;
722 *pf->p++ = ch;
723 }
724
725 return 0;
726}
727
728
729//================================================================
740int mrbc_printf_bstr( mrbc_printf_t *pf, const char *str, int len, int pad )
741{
742 int ret = 0;
743
744 if( str == NULL ) {
745 str = "(null)";
746 len = 6;
747 }
748 if( pf->fmt.precision && len > pf->fmt.precision ) len = pf->fmt.precision;
749
750 int tw = len;
751 if( pf->fmt.width > len ) tw = pf->fmt.width;
752
753 int remain = pf->buf_end - pf->p;
754 if( len > remain ) {
755 len = remain;
756 ret = -1;
757 }
758 if( tw > remain ) {
759 tw = remain;
760 ret = -1;
761 }
762
763 int n_pad = tw - len;
764
765 if( !pf->fmt.flag_minus ) {
766 while( n_pad-- > 0 ) {
767 *pf->p++ = pad;
768 }
769 }
770 while( len-- > 0 ) {
771 *pf->p++ = *str++;
772 }
773 while( n_pad-- > 0 ) {
774 *pf->p++ = pad;
775 }
776
777 return ret;
778}
779
780
781
782//================================================================
792int mrbc_printf_int( mrbc_printf_t *pf, mrbc_int_t value, unsigned int base )
793{
794 int sign = 0;
795 mrbc_uint_t v = value;
796 char *pf_p_ini_val = pf->p;
797
798 if( value < 0 ) {
799 sign = '-';
800 v = -value;
801 } else if( pf->fmt.flag_plus ) {
802 sign = '+';
803 } else if( pf->fmt.flag_space ) {
804 sign = ' ';
805 }
806
807 // disable zero padding if conflict parameters exists.
808 if( pf->fmt.flag_minus || pf->fmt.width == 0 || pf->fmt.precision != 0 ) {
809 pf->fmt.flag_zero = 0;
810 }
811
812 // create string to temporary buffer
813 char buf[sizeof(mrbc_int_t) * 8];
814 char *p = buf + sizeof(buf);
815
816 do {
817 unsigned int ch = v % base;
818 *--p = ch + ((ch < 10)? '0' : 'a' - 10);
819 v /= base;
820 } while( v != 0 );
821
822 int dig_width = buf + sizeof(buf) - p;
823
824 // write padding character, if adjust right.
825 if( !pf->fmt.flag_minus && pf->fmt.width ) {
826 int pad = pf->fmt.flag_zero ? '0' : ' ';
827 int pad_width = pf->fmt.width - !!sign;
828 pad_width -= (pf->fmt.precision > dig_width)? pf->fmt.precision: dig_width;
829
830 for( ; pad_width > 0; pad_width-- ) {
831 *pf->p++ = pad;
832 if( pf->p >= pf->buf_end ) return -1;
833 }
834 }
835
836 // sign
837 if( sign ) {
838 *pf->p++ = sign;
839 if( pf->p >= pf->buf_end ) return -1;
840 }
841
842 // precision
843 int pre_width = pf->fmt.precision - dig_width;
844 for( ; pre_width > 0; pre_width-- ) {
845 *pf->p++ = '0';
846 if( pf->p >= pf->buf_end ) return -1;
847 }
848
849 // digit
850 for( ; dig_width > 0; dig_width-- ) {
851 *pf->p++ = *p++;
852 if( pf->p >= pf->buf_end ) return -1;
853 }
854
855 // write space, if adjust left.
856 if( pf->fmt.flag_minus && pf->fmt.width ) {
857 int pad_width = pf->fmt.width - (pf->p - pf_p_ini_val);
858 for( ; pad_width > 0; pad_width-- ) {
859 *pf->p++ = ' ';
860 if( pf->p >= pf->buf_end ) return -1;
861 }
862 }
863
864 return 0;
865}
866
867
868
869//================================================================
879int mrbc_printf_bit( mrbc_printf_t *pf, mrbc_int_t value, int bit )
880{
881 if( pf->fmt.flag_plus || pf->fmt.flag_space ) {
882 return mrbc_printf_int( pf, value, 1 << bit );
883 }
884
885 if( pf->fmt.flag_minus || pf->fmt.width == 0 ) {
886 pf->fmt.flag_zero = 0; // disable zero padding if left align or width zero.
887 }
888 pf->fmt.precision = 0;
889
890 mrbc_int_t v = value;
891 int offset_a = (pf->fmt.type == 'X') ? 'A' - 10 : 'a' - 10;
892 int mask = (1 << bit) - 1; // 0x0f, 0x07, 0x01
893 int mchar = mask + ((mask < 10)? '0' : offset_a);
894
895 // create string to local buffer
896 char buf[sizeof(mrbc_int_t) * 8 + 5];
897 assert( sizeof(buf) > (sizeof(mrbc_int_t) * 8 + 4) );
898 char *p = buf + sizeof(buf) - 1;
899 *p = '\0';
900 int n;
901 do {
902 assert( p >= buf );
903 n = v & mask;
904 *--p = n + ((n < 10)? '0' : offset_a);
905 v >>= bit;
906 } while( v != 0 && v != -1 );
907
908 // add "..f" for negative value?
909 // (note) '0' flag such as "%08x" is incompatible with ruby.
910 if( value < 0 && !pf->fmt.flag_zero ) {
911 if( n != mask ) *--p = mchar;
912 *--p = '.';
913 *--p = '.';
914 assert( p >= buf );
915 }
916
917 // decide pad character and output sign character
918 int pad;
919 if( pf->fmt.flag_zero ) {
920 pad = (value < 0) ? mchar : '0';
921 } else {
922 pad = ' ';
923 }
924
925 return mrbc_printf_str( pf, p, pad );
926}
927
928
929
930#if MRBC_USE_FLOAT
931//================================================================
939int mrbc_printf_float( mrbc_printf_t *pf, double value )
940{
941 char fstr[16];
942 const char *p1 = pf->fstr;
943 char *p2 = fstr + sizeof(fstr) - 1;
944
945 *p2 = '\0';
946 while( (*--p2 = *--p1) != '%' )
947 ;
948
949 snprintf( pf->p, (pf->buf_end - pf->p + 1), p2, value );
950
951 while( *pf->p != '\0' )
952 pf->p++;
953
954 return -(pf->p == pf->buf_end);
955}
956#endif
957
958
959
960//================================================================
974{
975 uint32_t v = MRBC_PTR_TO_UINT32(ptr);
976 int n = sizeof(ptr) * 2;
977 if( n > 8 ) n = 8;
978
979 // check buffer size.
980 if( (pf->buf_end - pf->p) < n+1 ) return -1;
981
982 // write pointer value.
983 *pf->p++ = '$';
984 pf->p += n;
985 char *p = pf->p - 1;
986
987 for(; n > 0; n-- ) {
988 *p-- = (v & 0xf) < 10 ? (v & 0xf) + '0' : (v & 0xf) - 10 + 'a';
989 v >>= 4;
990 }
991
992 return 0;
993}
void * mrbc_raw_realloc(void *ptr, unsigned int size)
Definition alloc.c:806
#define mrbc_type(o)
Definition boxing_no.h:57
struct RObject mrbc_value
Value object. Default version.
mrbc_value mrbc_array_get(const mrbc_value *ary, int idx)
Definition c_array.c:207
static int mrbc_array_size(const mrbc_value *ary)
Definition c_array.h:84
static mrbc_value * mrbc_hash_i_next(mrbc_hash_iterator *ite)
Definition c_hash.h:143
static int mrbc_hash_i_has_next(mrbc_hash_iterator *ite)
Definition c_hash.h:135
struct RHashIterator mrbc_hash_iterator
Define Hash iterator.
static mrbc_hash_iterator mrbc_hash_iterator_new(const mrbc_value *v)
Definition c_hash.h:122
static mrbc_value * mrbc_range_last_p(const mrbc_value *v)
Definition c_range.h:90
static int mrbc_range_exclude_end(const mrbc_value *v)
Definition c_range.h:98
static mrbc_value * mrbc_range_first_p(const mrbc_value *v)
Definition c_range.h:74
static char * mrbc_string_cstr(const mrbc_value *v)
Definition c_string.h:122
static int mrbc_string_size(const mrbc_value *str)
Definition c_string.h:114
static mrbc_class * find_class_by_object(const mrbc_value *obj)
Definition class.h:265
void mrbc_p(const mrbc_value *v)
Definition console.c:346
int mrbc_printf_float(mrbc_printf_t *pf, double value)
Definition console.c:939
int mrbc_print_sub(const mrbc_value *v)
Definition console.c:522
void mrbc_printf(const char *fstr,...)
Definition console.c:205
int mrbc_printf_int(mrbc_printf_t *pf, mrbc_int_t value, unsigned int base)
Definition console.c:792
int mrbc_printf_char(mrbc_printf_t *pf, int ch)
Definition console.c:707
void mrbc_vprintf(const char *fstr, va_list ap)
Definition console.c:266
void mrbc_nprint(const char *str, int size)
Definition console.c:176
int mrbc_printf_bstr(mrbc_printf_t *pf, const char *str, int len, int pad)
Definition console.c:740
int mrbc_puts_sub(const mrbc_value *v)
Definition console.c:499
void mrbc_asprintf(char **buf, int bufsiz, const char *fstr,...)
Definition console.c:223
int mrbc_p_sub(const mrbc_value *v)
Definition console.c:398
int mrbc_printf_pointer(mrbc_printf_t *pf, void *ptr)
Definition console.c:973
static int mrbc_p_sub_hashkey(const mrbc_value *v)
Definition console.c:105
void mrbc_vasprintf(char **buf, int bufsiz, const char *fstr, va_list ap)
Definition console.c:301
void mrbc_snprintf(char *buf, int bufsiz, const char *fstr,...)
Definition console.c:241
void mrbc_printf_replace_buffer(mrbc_printf_t *pf, char *buf, int size)
Definition console.c:629
void mrbc_putchar(char c)
Definition console.c:131
void mrbc_char_to_s(char *buf, const void *src)
Definition console.c:359
#define MRBC_PRINTF_MAX_WIDTH
Definition console.c:32
int mrbc_printf_bit(mrbc_printf_t *pf, mrbc_int_t value, int bit)
Definition console.c:879
void mrbc_print_symbol(mrbc_sym sym_id)
Definition console.c:152
int mrbc_printf_main(mrbc_printf_t *pf)
Definition console.c:647
static int mrbc_printf_sub_output_arg(mrbc_printf_t *pf, va_list *ap)
Definition console.c:45
static void mrbc_printf_clear(mrbc_printf_t *pf)
Definition console.h:139
static void mrbc_print(const char *str)
Definition console.h:110
static void mrbc_printf_end(mrbc_printf_t *pf)
Definition console.h:150
static int mrbc_printf_len(mrbc_printf_t *pf)
Definition console.h:162
struct RPrintf mrbc_printf_t
printf tiny (mruby/c) version data container.
static int mrbc_printf_str(mrbc_printf_t *pf, const char *str, int pad)
Definition console.h:178
static void mrbc_printf_init(mrbc_printf_t *pf, char *buf, int size, const char *fstr)
Definition console.h:124
static mrbc_kv * mrbc_kv_i_next(mrbc_kv_iterator *ite)
Definition keyvalue.h:159
static int mrbc_kv_i_has_next(const mrbc_kv_iterator *ite)
Definition keyvalue.h:143
struct RKeyValue mrbc_kv
Key-Value data.
static int mrbc_kv_i_is_first(const mrbc_kv_iterator *ite)
Definition keyvalue.h:135
struct RKeyValueIterator mrbc_kv_iterator
Key-Value iterator.
static mrbc_kv_iterator mrbc_kv_iterator_new(const mrbc_kv_handle *h)
Definition keyvalue.h:122
Include at once the necessary header files.
mrbc_sym sym_id
class name's symbol ID
Definition class.h:97
struct RClass * cls
exception class.
Definition error.h:51
const uint8_t * message
to heap or ROM.
Definition error.h:54
struct RKeyValueHandle ivar
instance variable.
Definition class.h:184
mrbc_sym sym_id
symbol ID as key.
Definition keyvalue.h:43
mrbc_value value
stored value.
Definition keyvalue.h:44
struct RProc * proc
Definition boxing_no.h:30
struct RException * exception
Definition boxing_no.h:35
struct RInstance * instance
Definition boxing_no.h:29
mrbc_sym sym_id
Definition boxing_no.h:26
void * handle
Definition boxing_no.h:36
mrbc_float_t d
Definition boxing_no.h:24
struct RBasic * obj
Definition boxing_no.h:27
struct RClass * cls
Definition boxing_no.h:28
mrbc_int_t i
Definition boxing_no.h:22
printf tiny (mruby/c) version format container.
Definition console.h:50
int16_t width
display width. (e.g. %10d as 10)
Definition console.h:56
int16_t precision
precision (e.g. %5.2f as 2)
Definition console.h:57
unsigned int flag_space
Definition console.h:54
unsigned int flag_zero
Definition console.h:55
unsigned int flag_plus
Definition console.h:52
unsigned int flag_minus
Definition console.h:53
char type
format char. (e.g. 'd','f','x'...)
Definition console.h:51
struct RPrintfFormat fmt
Definition console.h:70
char * p
output buffer write point.
Definition console.h:68
const char * buf_end
output buffer end point.
Definition console.h:67
const char * fstr
format string. (e.g. "%d %03x")
Definition console.h:69
char * buf
output buffer.
Definition console.h:66
void mrbc_separate_nested_symid(mrbc_sym sym_id, mrbc_sym *id1, mrbc_sym *id2)
Definition symbol.c:312
const char * mrbc_symid_to_str(mrbc_sym sym_id)
Definition symbol.c:239
static const char * mrbc_symbol_cstr(const mrbc_value *v)
Definition symbol.h:61
static int mrbc_is_nested_symid(mrbc_sym sym_id)
Definition symbol.h:74
void mrbc_format_float(char *buf, int bufsiz, mrbc_float_t flo)
Definition value.c:264
int32_t mrbc_int_t
Definition value.h:47
#define MRBC_PTR_TO_UINT32(p)
Definition value.h:513
#define MRBC_TT_INC_DEC_THRESHOLD
Definition value.h:103
int16_t mrbc_sym
mruby/c symbol ID
Definition value.h:62
@ MRBC_TT_FALSE
FalseClass.
Definition value.h:82
@ MRBC_TT_HANDLE
Definition value.h:77
@ MRBC_TT_SYMBOL
Symbol.
Definition value.h:89
@ MRBC_TT_STRING
String.
Definition value.h:98
@ MRBC_TT_FLOAT
Float.
Definition value.h:88
@ MRBC_TT_INTEGER
Integer.
Definition value.h:86
@ MRBC_TT_EXCEPTION
Exception.
Definition value.h:101
@ MRBC_TT_EMPTY
Definition value.h:80
@ MRBC_TT_PROC
Proc.
Definition value.h:96
@ MRBC_TT_RANGE
Range.
Definition value.h:99
@ MRBC_TT_OBJECT
General instance.
Definition value.h:95
@ MRBC_TT_ARRAY
Array.
Definition value.h:97
@ MRBC_TT_MODULE
Module.
Definition value.h:91
@ MRBC_TT_TRUE
TrueClass.
Definition value.h:85
@ MRBC_TT_NIL
NilClass.
Definition value.h:81
@ MRBC_TT_HASH
Hash.
Definition value.h:100
@ MRBC_TT_CLASS
Class.
Definition value.h:90
uint32_t mrbc_uint_t
Definition value.h:48
Global configuration of mruby/c VM's.