mruby/c VM Source Code release 4.0.0
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 ret = mrbc_printf_int( pf, va_arg(*ap, mrbc_int_t), 10);
66 break;
67
68 case 'b':
69 case 'B':
70 ret = mrbc_printf_bit( pf, va_arg(*ap, unsigned int), 1);
71 break;
72
73 case 'x':
74 case 'X':
75 ret = mrbc_printf_bit( pf, va_arg(*ap, unsigned int), 4);
76 break;
77
78#if MRBC_USE_FLOAT
79 case 'f':
80 case 'e':
81 case 'E':
82 case 'g':
83 case 'G':
84 ret = mrbc_printf_float( pf, va_arg(*ap, double) );
85 break;
86#endif
87 case 'p':
88 ret = mrbc_printf_pointer( pf, va_arg(*ap, void *) );
89 break;
90
91 default:
92 ret = 0;
93 break;
94 }
95
96 return ret;
97}
98
99/* sub function to print a hashkey
100 */
101static int mrbc_p_sub_hashkey(const mrbc_value *v)
102{
103 switch( mrbc_type(*v) ) {
104 case MRBC_TT_SYMBOL:{
105 const char *s = mrbc_symbol_cstr(v);
106 const char *fmt = strchr(s, ':') ? "\"%s\": " : "%s: ";
107 mrbc_printf(fmt, s);
108 break;
109 }
110 default: {
111 mrbc_p_sub(v);
112 mrbc_print(" => ");
113 break;
114 }
115 }
116 return 0;
117}
118
119
120/***** Global functions *****************************************************/
121
122//================================================================
127void mrbc_putchar(char c)
128{
129#if defined(MRBC_CONVERT_CRLF)
130 static const char CRLF[2] = "\r\n";
131 if( c == '\n' ) {
132 mrbc_hal_write(1, CRLF, 2);
133 } else {
134 mrbc_hal_write(1, &c, 1);
135 }
136
137#else
138 mrbc_hal_write(1, &c, 1);
139#endif
140}
141
142
143//================================================================
149{
150 // normal case
151 if( !mrbc_is_nested_symid(sym_id) ) {
152 mrbc_print( mrbc_symid_to_str(sym_id) );
153 return;
154 }
155
156 // nested case
157 mrbc_sym id1, id2;
158 mrbc_separate_nested_symid( sym_id, &id1, &id2 );
159
160 mrbc_print_symbol( id1 );
161 mrbc_print("::");
162 mrbc_print_symbol( id2 );
163}
164
165
166//================================================================
172void mrbc_nprint(const char *str, int size)
173{
174#if defined(MRBC_CONVERT_CRLF)
175 static const char CRLF[2] = "\r\n";
176 const char *p1 = str;
177 const char *p2 = str;
178
179 for( int i = 0; i < size; i++ ) {
180 if( *p1++ == '\n' ) {
181 mrbc_hal_write(1, p2, p1 - p2 - 1);
182 mrbc_hal_write(1, CRLF, 2);
183 p2 = p1;
184 }
185 }
186 if( p1 != p2 ) {
187 mrbc_hal_write(1, p2, p1 - p2);
188 }
189
190#else
191 mrbc_hal_write(1, str, size);
192#endif
193}
194
195
196//================================================================
201void mrbc_printf(const char *fstr, ...)
202{
203 va_list ap;
204 va_start(ap, fstr);
205
206 mrbc_vprintf( fstr, ap );
207
208 va_end(ap);
209}
210
211
212//================================================================
219void mrbc_asprintf(char **buf, int bufsiz, const char *fstr, ...)
220{
221 va_list ap;
222 va_start(ap, fstr);
223
224 mrbc_vasprintf( buf, bufsiz, fstr, ap );
225
226 va_end(ap);
227}
228
229
230//================================================================
237void mrbc_snprintf(char *buf, int bufsiz, const char *fstr, ...)
238{
239 va_list ap;
240 va_start(ap, fstr);
241
242 mrbc_printf_t pf;
243 mrbc_printf_init( &pf, buf, bufsiz, fstr );
244
245 while( 1 ) {
246 if( mrbc_printf_main( &pf ) <= 0 ) break;
247 // normal end (==0) or buffer full (<0).
248 if( mrbc_printf_sub_output_arg( &pf, &ap ) != 0 ) break;
249 }
250
251 mrbc_printf_end( &pf );
252 va_end(ap);
253}
254
255
256//================================================================
262void mrbc_vprintf(const char *fstr, va_list ap)
263{
264 va_list ap1;
265 va_copy( ap1, ap );
266
267 mrbc_printf_t pf;
268 char buf[MRBC_PRINTF_MAX_WIDTH];
269 mrbc_printf_init( &pf, buf, sizeof(buf), fstr );
270
271 while( 1 ) {
272 int ret = mrbc_printf_main( &pf );
273 if( mrbc_printf_len( &pf ) ) {
274 mrbc_nprint( buf, mrbc_printf_len( &pf ) );
275 mrbc_printf_clear( &pf );
276 }
277 if( ret == 0 ) break;
278 if( ret < 0 ) continue;
279
280 mrbc_printf_sub_output_arg( &pf, &ap1 );
281 mrbc_nprint( buf, mrbc_printf_len( &pf ) );
282 mrbc_printf_clear( &pf );
283 }
284
285 va_end(ap1);
286}
287
288
289//================================================================
297void mrbc_vasprintf(char **buf, int bufsiz, const char *fstr, va_list ap)
298{
299 va_list ap1, ap_bak;
300 va_copy( ap1, ap );
301
302 mrbc_printf_t pf;
303 mrbc_printf_init( &pf, *buf, bufsiz, fstr );
304
305 while( 1 ) {
306 va_copy(ap_bak, ap1);
307 mrbc_printf_t pf_bak = pf;
308
309 int ret = mrbc_printf_main( &pf );
310 if( ret == 0 ) break; // normal break loop.
311 if( ret < 0 ) goto INCREASE_BUFFER;
312
313 ret = mrbc_printf_sub_output_arg( &pf, &ap1 );
314 if( ret >= 0 ) goto NEXT_LOOP;
315
316 va_end(ap1);
317 va_copy(ap1, ap_bak);
318 pf = pf_bak;
319
320 INCREASE_BUFFER:
321 bufsiz += 64;
322 void *newbuf = mrbc_raw_realloc( pf.buf, bufsiz );
323
324 mrbc_printf_replace_buffer( &pf, newbuf, bufsiz );
325 *buf = newbuf;
326
327 NEXT_LOOP:
328 va_end(ap_bak);
329 }
330
331 mrbc_printf_end( &pf );
332 va_end(ap1);
333 va_end(ap_bak);
334}
335
336
337//================================================================
342void mrbc_p(const mrbc_value *v)
343{
344 mrbc_p_sub( v );
345 mrbc_putchar('\n');
346}
347
348
349//================================================================
355void mrbc_char_to_s( char *buf, const void *src )
356{
357 unsigned char ch = *((unsigned char *)src);
358
359 if( ch == 0x7f ) goto hex;
360 if( ch < ' ' ) {
361 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 ];
362 if( ch1 == 0 ) goto hex;
363 ch = ch1;
364 goto esc;
365 }
366 if( ch == '"' || ch == '\\' ) {
367 goto esc;
368 }
369
370 buf[0] = ch;
371 buf[1] = 0;
372 return;
373
374 hex:
375 buf[0] = '\\';
376 buf[1] = 'x';
377 buf[2] = "0123456789ABCDEF"[ch >> 4];
378 buf[3] = "0123456789ABCDEF"[ch & 0x0f];
379 buf[4] = 0;
380 return;
381
382 esc:
383 buf[0] = '\\';
384 buf[1] = ch;
385 buf[2] = 0;
386}
387
388
389//================================================================
395{
396 if( !v ) {
397 mrbc_print("(null)"); // wrong things are happen. but it give me a clue.
398 return 0;
399 }
400
401 switch( mrbc_type(*v) ) {
402 case MRBC_TT_NIL:
403 mrbc_print("nil");
404 break;
405
406 case MRBC_TT_SYMBOL:{
407 const char *s = mrbc_symbol_cstr( v );
408 const char *fmt = strchr(s, ':') ? "\":%s\"" : ":%s";
409 mrbc_printf(fmt, s);
410 } break;
411
412#if MRBC_USE_STRING
413 case MRBC_TT_STRING:{
414 const char *s = mrbc_string_cstr(v);
415 int size = mrbc_string_size(v);
416
417 mrbc_putchar('"');
418#if MRBC_USE_STRING_UTF8
419 for( int i = 0; i < size; ) {
420 unsigned char uch = (unsigned char)s[i];
421 if( uch < 0x80 ) {
422 char buf[10];
423 mrbc_char_to_s( buf, s + i );
424 mrbc_print( buf );
425 i++;
426 } else {
427 int raw_len = mrbc_string_utf8_size(s + i);
428 int valid = (raw_len >= 2 && i + raw_len <= size);
429 if( valid ) {
430 for( int j = 1; j < raw_len; j++ ) {
431 if( ((unsigned char)s[i + j] & 0xC0) != 0x80 ) { valid = 0; break; }
432 }
433 }
434 if( valid ) {
435 mrbc_nprint(s + i, raw_len);
436 i += raw_len;
437 } else {
438 char buf[5];
439 buf[0] = '\\'; buf[1] = 'x';
440 buf[2] = "0123456789ABCDEF"[uch >> 4];
441 buf[3] = "0123456789ABCDEF"[uch & 0x0f];
442 buf[4] = 0;
443 mrbc_print( buf );
444 i++;
445 }
446 }
447 }
448#else
449 for( int i = 0; i < size; i++ ) {
450 char buf[10];
451 mrbc_char_to_s( buf, s + i );
452 mrbc_print( buf );
453 }
454#endif
455 mrbc_putchar('"');
456 } break;
457#endif
458
459 case MRBC_TT_RANGE:{
460 const mrbc_value *v1 = mrbc_range_first_p(v);
461 const mrbc_value *v2 = mrbc_range_last_p(v);
462
463 if( mrbc_type(*v1) != MRBC_TT_NIL ||
464 mrbc_type(*v2) == MRBC_TT_NIL ) mrbc_p_sub(v1);
465
466 mrbc_print( mrbc_range_exclude_end(v) ? "..." : ".." );
467
468 if( mrbc_type(*v1) == MRBC_TT_NIL ||
469 mrbc_type(*v2) != MRBC_TT_NIL ) mrbc_p_sub(v2);
470 } break;
471
472 default:
474 break;
475 }
476
477#if 0
478 // display reference counter
480 mrbc_printf("#%d", v->obj->ref_count);
481 }
482#endif
483
484 return 0;
485}
486
487
488//================================================================
496{
497 if( mrbc_type(*v) == MRBC_TT_ARRAY ) {
498
499 for( int i = 0; i < mrbc_array_size(v); i++ ) {
500 if( i != 0 ) mrbc_putchar('\n');
501 mrbc_value v1 = mrbc_array_get(v, i);
502 mrbc_puts_sub(&v1);
503 }
504 return 0;
505 }
506
507 return mrbc_print_sub(v);
508}
509
510
511//================================================================
519{
520 int ret = 0;
521
522 switch( mrbc_type(*v) ) {
523 case MRBC_TT_EMPTY: mrbc_print("(empty)"); break;
524 case MRBC_TT_NIL: break;
525 case MRBC_TT_FALSE: mrbc_print("false"); break;
526 case MRBC_TT_TRUE: mrbc_print("true"); break;
527 case MRBC_TT_INTEGER: mrbc_printf("%D", v->i); break;
528#if MRBC_USE_FLOAT
529 case MRBC_TT_FLOAT: {
530 char buf[32];
531 mrbc_format_float(buf, sizeof(buf), v->d);
532 mrbc_printf("%s", buf);
533 } break;
534#endif
535 case MRBC_TT_SYMBOL: mrbc_print_symbol(v->sym_id); break;
536 case MRBC_TT_CLASS: // fall through.
537 case MRBC_TT_MODULE: mrbc_print_symbol(v->cls->sym_id); break;
538
539 case MRBC_TT_OBJECT:{
540 mrbc_printf("#<");
543
545 while( mrbc_kv_i_has_next( &ite ) ) {
546 mrbc_printf( mrbc_kv_i_is_first(&ite) ? " " : ", " );
547 const mrbc_kv *kv = mrbc_kv_i_next( &ite );
549 mrbc_p_sub(&kv->value);
550 }
551 mrbc_printf(">");
552 } break;
553
554 case MRBC_TT_PROC:
555 mrbc_printf("#<Proc:%08x>", MRBC_PTR_TO_UINT32(v->proc) );
556 //mrbc_printf("#<Proc:%08x, callinfo=%p>", MRBC_PTR_TO_UINT32(v->proc), MRBC_PTR_TO_UINT32(v->proc->callinfo) );
557 break;
558
559 case MRBC_TT_ARRAY:{
560 mrbc_putchar('[');
561 for( int i = 0; i < mrbc_array_size(v); i++ ) {
562 if( i != 0 ) mrbc_print(", ");
563 mrbc_value v1 = mrbc_array_get(v, i);
564 mrbc_p_sub(&v1);
565 }
566 mrbc_putchar(']');
567 } break;
568
569#if MRBC_USE_STRING
570 case MRBC_TT_STRING:
572 if( mrbc_string_size(v) != 0 &&
573 mrbc_string_cstr(v)[ mrbc_string_size(v) - 1 ] == '\n' ) ret = 1;
574 break;
575#endif
576
577 case MRBC_TT_RANGE:{
580
581 mrbc_print_sub(v1);
582 mrbc_print( mrbc_range_exclude_end(v) ? "..." : ".." );
583 mrbc_print_sub(v2);
584 } break;
585
586 case MRBC_TT_HASH:{
587 mrbc_putchar('{');
589 while( mrbc_hash_i_has_next(&ite) ) {
590 mrbc_value *vk = mrbc_hash_i_next(&ite);
592 mrbc_p_sub(vk+1);
593 if( mrbc_hash_i_has_next(&ite) ) mrbc_print(", ");
594 }
595 mrbc_putchar('}');
596 } break;
597
598 case MRBC_TT_HANDLE:
599 mrbc_printf("#<Handle:%08x>", MRBC_PTR_TO_UINT32(v->handle) );
600 break;
601
604 v->exception->message ?
605 (const char *)v->exception->message :
607 break;
608
609 default:
610 mrbc_printf("Not support MRBC_TT_XX(%d)", mrbc_type(*v));
611 break;
612 }
613
614 return ret;
615}
616
617
618//================================================================
625void mrbc_printf_replace_buffer(mrbc_printf_t *pf, char *buf, int size)
626{
627 int p_ofs = pf->p - pf->buf;
628 pf->buf = buf;
629 pf->buf_end = buf + size - 1;
630 pf->p = pf->buf + p_ofs;
631}
632
633
634//================================================================
644{
645 int ch = -1;
646 pf->fmt = (struct RPrintfFormat){0};
647
648 while( pf->p < pf->buf_end && (ch = *pf->fstr) != '\0' ) {
649 pf->fstr++;
650 if( ch == '%' ) {
651 if( *pf->fstr == '%' ) { // is "%%"
652 pf->fstr++;
653 } else {
654 goto PARSE_FLAG;
655 }
656 }
657 *pf->p++ = ch;
658 }
659 return -(ch != '\0');
660
661
662 PARSE_FLAG:
663 // parse format - '%' [flag] [width] [.precision] type
664 // e.g. "%05d"
665 while( (ch = *pf->fstr) ) {
666 switch( ch ) {
667 case '+': pf->fmt.flag_plus = 1; break;
668 case ' ': pf->fmt.flag_space = 1; break;
669 case '-': pf->fmt.flag_minus = 1; break;
670 case '0': pf->fmt.flag_zero = 1; break;
671 default : goto PARSE_WIDTH;
672 }
673 pf->fstr++;
674 }
675
676 PARSE_WIDTH:
677 while( (void)(ch = *pf->fstr - '0'), (0 <= ch && ch <= 9)) { // isdigit()
678 pf->fmt.width = pf->fmt.width * 10 + ch;
679 pf->fstr++;
680 }
681 if( *pf->fstr == '.' ) {
682 pf->fstr++;
683 while( (void)(ch = *pf->fstr - '0'), (0 <= ch && ch <= 9)) {
684 pf->fmt.precision = pf->fmt.precision * 10 + ch;
685 pf->fstr++;
686 }
687 }
688 if( *pf->fstr ) pf->fmt.type = *pf->fstr++;
689
690 return 1;
691}
692
693
694//================================================================
704{
705 if( pf->fmt.flag_minus ) {
706 if( pf->p == pf->buf_end ) return -1;
707 *pf->p++ = ch;
708 }
709
710 int width = pf->fmt.width;
711 while( --width > 0 ) {
712 if( pf->p == pf->buf_end ) return -1;
713 *pf->p++ = ' ';
714 }
715
716 if( !pf->fmt.flag_minus ) {
717 if( pf->p == pf->buf_end ) return -1;
718 *pf->p++ = ch;
719 }
720
721 return 0;
722}
723
724
725//================================================================
736int mrbc_printf_bstr( mrbc_printf_t *pf, const char *str, int len, int pad )
737{
738 int ret = 0;
739
740 if( str == NULL ) {
741 str = "(null)";
742 len = 6;
743 }
744 if( pf->fmt.precision && len > pf->fmt.precision ) len = pf->fmt.precision;
745
746 int tw = len;
747 if( pf->fmt.width > len ) tw = pf->fmt.width;
748
749 int remain = pf->buf_end - pf->p;
750 if( len > remain ) {
751 len = remain;
752 ret = -1;
753 }
754 if( tw > remain ) {
755 tw = remain;
756 ret = -1;
757 }
758
759 int n_pad = tw - len;
760
761 if( !pf->fmt.flag_minus ) {
762 while( n_pad-- > 0 ) {
763 *pf->p++ = pad;
764 }
765 }
766 while( len-- > 0 ) {
767 *pf->p++ = *str++;
768 }
769 while( n_pad-- > 0 ) {
770 *pf->p++ = pad;
771 }
772
773 return ret;
774}
775
776
777
778//================================================================
788int mrbc_printf_int( mrbc_printf_t *pf, mrbc_int_t value, unsigned int base )
789{
790 int sign = 0;
791 mrbc_uint_t v = value;
792 char *pf_p_ini_val = pf->p;
793
794 if( value < 0 ) {
795 sign = '-';
796 v = -value;
797 } else if( pf->fmt.flag_plus ) {
798 sign = '+';
799 } else if( pf->fmt.flag_space ) {
800 sign = ' ';
801 }
802
803 // disable zero padding if conflict parameters exists.
804 if( pf->fmt.flag_minus || pf->fmt.width == 0 || pf->fmt.precision != 0 ) {
805 pf->fmt.flag_zero = 0;
806 }
807
808 // create string to temporary buffer
809 char buf[sizeof(mrbc_int_t) * 8];
810 char *p = buf + sizeof(buf);
811
812 do {
813 unsigned int ch = v % base;
814 *--p = ch + ((ch < 10)? '0' : 'a' - 10);
815 v /= base;
816 } while( v != 0 );
817
818 int dig_width = buf + sizeof(buf) - p;
819
820 // write padding character, if adjust right.
821 if( !pf->fmt.flag_minus && pf->fmt.width ) {
822 int pad = pf->fmt.flag_zero ? '0' : ' ';
823 int pad_width = pf->fmt.width - !!sign;
824 pad_width -= (pf->fmt.precision > dig_width)? pf->fmt.precision: dig_width;
825
826 for( ; pad_width > 0; pad_width-- ) {
827 *pf->p++ = pad;
828 if( pf->p >= pf->buf_end ) return -1;
829 }
830 }
831
832 // sign
833 if( sign ) {
834 *pf->p++ = sign;
835 if( pf->p >= pf->buf_end ) return -1;
836 }
837
838 // precision
839 int pre_width = pf->fmt.precision - dig_width;
840 for( ; pre_width > 0; pre_width-- ) {
841 *pf->p++ = '0';
842 if( pf->p >= pf->buf_end ) return -1;
843 }
844
845 // digit
846 for( ; dig_width > 0; dig_width-- ) {
847 *pf->p++ = *p++;
848 if( pf->p >= pf->buf_end ) return -1;
849 }
850
851 // write space, if adjust left.
852 if( pf->fmt.flag_minus && pf->fmt.width ) {
853 int pad_width = pf->fmt.width - (pf->p - pf_p_ini_val);
854 for( ; pad_width > 0; pad_width-- ) {
855 *pf->p++ = ' ';
856 if( pf->p >= pf->buf_end ) return -1;
857 }
858 }
859
860 return 0;
861}
862
863
864
865//================================================================
875int mrbc_printf_bit( mrbc_printf_t *pf, mrbc_int_t value, int bit )
876{
877 if( pf->fmt.flag_plus || pf->fmt.flag_space ) {
878 return mrbc_printf_int( pf, value, 1 << bit );
879 }
880
881 if( pf->fmt.flag_minus || pf->fmt.width == 0 ) {
882 pf->fmt.flag_zero = 0; // disable zero padding if left align or width zero.
883 }
884 pf->fmt.precision = 0;
885
886 mrbc_int_t v = value;
887 int offset_a = (pf->fmt.type == 'X') ? 'A' - 10 : 'a' - 10;
888 int mask = (1 << bit) - 1; // 0x0f, 0x07, 0x01
889 int mchar = mask + ((mask < 10)? '0' : offset_a);
890
891 // create string to local buffer
892 char buf[sizeof(mrbc_int_t) * 8 + 5];
893 assert( sizeof(buf) > (sizeof(mrbc_int_t) * 8 + 4) );
894 char *p = buf + sizeof(buf) - 1;
895 *p = '\0';
896 int n;
897 do {
898 assert( p >= buf );
899 n = v & mask;
900 *--p = n + ((n < 10)? '0' : offset_a);
901 v >>= bit;
902 } while( v != 0 && v != -1 );
903
904 // add "..f" for negative value?
905 // (note) '0' flag such as "%08x" is incompatible with ruby.
906 if( value < 0 && !pf->fmt.flag_zero ) {
907 if( n != mask ) *--p = mchar;
908 *--p = '.';
909 *--p = '.';
910 assert( p >= buf );
911 }
912
913 // decide pad character and output sign character
914 int pad;
915 if( pf->fmt.flag_zero ) {
916 pad = (value < 0) ? mchar : '0';
917 } else {
918 pad = ' ';
919 }
920
921 return mrbc_printf_str( pf, p, pad );
922}
923
924
925
926#if MRBC_USE_FLOAT
927//================================================================
935int mrbc_printf_float( mrbc_printf_t *pf, double value )
936{
937 char fstr[16];
938 const char *p1 = pf->fstr;
939 char *p2 = fstr + sizeof(fstr) - 1;
940
941 *p2 = '\0';
942 while( (*--p2 = *--p1) != '%' )
943 ;
944
945 snprintf( pf->p, (pf->buf_end - pf->p + 1), p2, value );
946
947 while( *pf->p != '\0' )
948 pf->p++;
949
950 return -(pf->p == pf->buf_end);
951}
952#endif
953
954
955
956//================================================================
970{
971 uint32_t v = MRBC_PTR_TO_UINT32(ptr);
972 int n = sizeof(ptr) * 2;
973 if( n > 8 ) n = 8;
974
975 // check buffer size.
976 if( (pf->buf_end - pf->p) < n+1 ) return -1;
977
978 // write pointer value.
979 *pf->p++ = '$';
980 pf->p += n;
981 char *p = pf->p - 1;
982
983 for(; n > 0; n-- ) {
984 *p-- = (v & 0xf) < 10 ? (v & 0xf) + '0' : (v & 0xf) - 10 + 'a';
985 v >>= 4;
986 }
987
988 return 0;
989}
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:262
void mrbc_p(const mrbc_value *v)
Definition console.c:342
int mrbc_printf_float(mrbc_printf_t *pf, double value)
Definition console.c:935
int mrbc_print_sub(const mrbc_value *v)
Definition console.c:518
void mrbc_printf(const char *fstr,...)
Definition console.c:201
int mrbc_printf_int(mrbc_printf_t *pf, mrbc_int_t value, unsigned int base)
Definition console.c:788
int mrbc_printf_char(mrbc_printf_t *pf, int ch)
Definition console.c:703
void mrbc_vprintf(const char *fstr, va_list ap)
Definition console.c:262
void mrbc_nprint(const char *str, int size)
Definition console.c:172
int mrbc_printf_bstr(mrbc_printf_t *pf, const char *str, int len, int pad)
Definition console.c:736
int mrbc_puts_sub(const mrbc_value *v)
Definition console.c:495
void mrbc_asprintf(char **buf, int bufsiz, const char *fstr,...)
Definition console.c:219
int mrbc_p_sub(const mrbc_value *v)
Definition console.c:394
int mrbc_printf_pointer(mrbc_printf_t *pf, void *ptr)
Definition console.c:969
static int mrbc_p_sub_hashkey(const mrbc_value *v)
Definition console.c:101
void mrbc_vasprintf(char **buf, int bufsiz, const char *fstr, va_list ap)
Definition console.c:297
void mrbc_snprintf(char *buf, int bufsiz, const char *fstr,...)
Definition console.c:237
void mrbc_printf_replace_buffer(mrbc_printf_t *pf, char *buf, int size)
Definition console.c:625
void mrbc_putchar(char c)
Definition console.c:127
void mrbc_char_to_s(char *buf, const void *src)
Definition console.c:355
#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:875
void mrbc_print_symbol(mrbc_sym sym_id)
Definition console.c:148
int mrbc_printf_main(mrbc_printf_t *pf)
Definition console.c:643
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:137
static void mrbc_print(const char *str)
Definition console.h:108
static void mrbc_printf_end(mrbc_printf_t *pf)
Definition console.h:148
static int mrbc_printf_len(mrbc_printf_t *pf)
Definition console.h:160
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:176
static void mrbc_printf_init(mrbc_printf_t *pf, char *buf, int size, const char *fstr)
Definition console.h:122
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:183
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:309
const char * mrbc_symid_to_str(mrbc_sym sym_id)
Definition symbol.c:242
static const char * mrbc_symbol_cstr(const mrbc_value *v)
Definition symbol.h:58
static int mrbc_is_nested_symid(mrbc_sym sym_id)
Definition symbol.h:71
void mrbc_format_float(char *buf, int bufsiz, mrbc_float_t flo)
Definition value.c:263
int32_t mrbc_int_t
Definition value.h:47
#define MRBC_PTR_TO_UINT32(p)
Definition value.h:504
#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.