Ruby 2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)

sprintf.c
Go to the documentation of this file.
1 /**********************************************************************
2
3 sprintf.c -
4
5 $Author$
6 created at: Fri Oct 15 10:39:26 JST 1993
7
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
9 Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
10 Copyright (C) 2000 Information-technology Promotion Agency, Japan
11
12 **********************************************************************/
13
14 #include "ruby/encoding.h"
15 #include "ruby/re.h"
16 #include "internal.h"
17 #include "id.h"
18 #include <math.h>
19 #include <stdarg.h>
20
21 #ifdef HAVE_IEEEFP_H
22 #include <ieeefp.h>
23 #endif
24
25 #define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log2(10) =~ 146/485 */
26
27 static char *fmt_setup(char*,size_t,int,int,int,int);
28 static char *ruby_ultoa(unsigned long val, char *endp, int base, int octzero);
29
30 static char
31 sign_bits(int base, const char *p)
32 {
33 char c = '.';
34
35 switch (base) {
36 case 16:
37 if (*p == 'X') c = 'F';
38 else c = 'f';
39 break;
40 case 8:
41 c = '7'; break;
42 case 2:
43 c = '1'; break;
44 }
45 return c;
46 }
47
48 #define FNONE 0
49 #define FSHARP 1
50 #define FMINUS 2
51 #define FPLUS 4
52 #define FZERO 8
53 #define FSPACE 16
54 #define FWIDTH 32
55 #define FPREC 64
56 #define FPREC0 128
57
58 #define CHECK(l) do {\
59 int cr = ENC_CODERANGE(result);\
60 while ((l) >= bsiz - blen) {\
61 bsiz*=2;\
62 if (bsiz<0) rb_raise(rb_eArgError, "too big specifier");\
63 }\
64 rb_str_resize(result, bsiz);\
65 ENC_CODERANGE_SET(result, cr);\
66 buf = RSTRING_PTR(result);\
67 } while (0)
68
69 #define PUSH(s, l) do { \
70 CHECK(l);\
71 PUSH_(s, l);\
72 } while (0)
73
74 #define PUSH_(s, l) do { \
75 memcpy(&buf[blen], (s), (l));\
76 blen += (l);\
77 } while (0)
78
79 #define FILL(c, l) do { \
80 if ((l) <= 0) break;\
81 CHECK(l);\
82 FILL_(c, l);\
83 } while (0)
84
85 #define FILL_(c, l) do { \
86 memset(&buf[blen], (c), (l));\
87 blen += (l);\
88 } while (0)
89
90 #define GETARG() (nextvalue != Qundef ? nextvalue : \
91 GETNEXTARG())
92
93 #define GETNEXTARG() ( \
94 check_next_arg(posarg, nextarg), \
95 (posarg = nextarg++, GETNTHARG(posarg)))
96
97 #define GETPOSARG(n) ( \
98 check_pos_arg(posarg, (n)), \
99 (posarg = -1, GETNTHARG(n)))
100
101 #define GETNTHARG(nth) \
102 (((nth) >= argc) ? (rb_raise(rb_eArgError, "too few arguments"), 0) : argv[(nth)])
103
104 #define CHECKNAMEARG(name, len, enc) ( \
105 check_name_arg(posarg, name, len, enc), \
106 posarg = -2)
107
108 #define GETNUM(n, val) \
109 (!(p = get_num(p, end, enc, &(n))) ? \
110 rb_raise(rb_eArgError, #val " too big") : (void)0)
111
112 #define GETASTER(val) do { \
113 t = p++; \
114 n = 0; \
115 GETNUM(n, val); \
116 if (*p == '$') { \
117 tmp = GETPOSARG(n); \
118 } \
119 else { \
120 tmp = GETNEXTARG(); \
121 p = t; \
122 } \
123 (val) = NUM2INT(tmp); \
124 } while (0)
125
126 static const char *
127 get_num(const char *p, const char *end, rb_encoding *enc, int *valp)
128 {
129 int next_n = *valp;
130 for (; p < end && rb_enc_isdigit(*p, enc); p++) {
131 if (MUL_OVERFLOW_INT_P(10, next_n))
132 return NULL;
133 next_n *= 10;
134 if (INT_MAX - (*p - '0') < next_n)
135 return NULL;
136 next_n += *p - '0';
137 }
138 if (p >= end) {
139 rb_raise(rb_eArgError, "malformed format string - %%*[0-9]");
140 }
141 *valp = next_n;
142 return p;
143 }
144
145 static void
146 check_next_arg(int posarg, int nextarg)
147 {
148 switch (posarg) {
149 case -1:
150 rb_raise(rb_eArgError, "unnumbered(%d) mixed with numbered", nextarg);
151 case -2:
152 rb_raise(rb_eArgError, "unnumbered(%d) mixed with named", nextarg);
153 }
154 }
155
156 static void
157 check_pos_arg(int posarg, int n)
158 {
159 if (posarg > 0) {
160 rb_raise(rb_eArgError, "numbered(%d) after unnumbered(%d)", n, posarg);
161 }
162 if (posarg == -2) {
163 rb_raise(rb_eArgError, "numbered(%d) after named", n);
164 }
165 if (n < 1) {
166 rb_raise(rb_eArgError, "invalid index - %d$", n);
167 }
168 }
169
170 static void
171 check_name_arg(int posarg, const char *name, int len, rb_encoding *enc)
172 {
173 if (posarg > 0) {
174 rb_enc_raise(enc, rb_eArgError, "named%.*s after unnumbered(%d)", len, name, posarg);
175 }
176 if (posarg == -1) {
177 rb_enc_raise(enc, rb_eArgError, "named%.*s after numbered", len, name);
178 }
179 }
180
181 static VALUE
182 get_hash(volatile VALUE *hash, int argc, const VALUE *argv)
183 {
184 VALUE tmp;
185
186 if (*hash != Qundef) return *hash;
187 if (argc != 2) {
188 rb_raise(rb_eArgError, "one hash required");
189 }
190 tmp = rb_check_hash_type(argv[1]);
191 if (NIL_P(tmp)) {
192 rb_raise(rb_eArgError, "one hash required");
193 }
194 return (*hash = tmp);
195 }
196
197 VALUE
198 rb_f_sprintf(int argc, const VALUE *argv)
199 {
200 return rb_str_format(argc - 1, argv + 1, GETNTHARG(0));
201 }
202
203 VALUE
204 rb_str_format(int argc, const VALUE *argv, VALUE fmt)
205 {
206 enum {default_float_precision = 6};
207 rb_encoding *enc;
208 const char *p, *end;
209 char *buf;
210 long blen, bsiz;
211 VALUE result;
212
213 long scanned = 0;
214 int coderange = ENC_CODERANGE_7BIT;
215 int width, prec, flags = FNONE;
216 int nextarg = 1;
217 int posarg = 0;
218 VALUE nextvalue;
219 VALUE tmp;
220 VALUE orig;
221 VALUE str;
222 volatile VALUE hash = Qundef;
223
224 #define CHECK_FOR_WIDTH(f) \
225 if ((f) & FWIDTH) { \
226 rb_raise(rb_eArgError, "width given twice"); \
227 } \
228 if ((f) & FPREC0) { \
229 rb_raise(rb_eArgError, "width after precision"); \
230 }
231 #define CHECK_FOR_FLAGS(f) \
232 if ((f) & FWIDTH) { \
233 rb_raise(rb_eArgError, "flag after width"); \
234 } \
235 if ((f) & FPREC0) { \
236 rb_raise(rb_eArgError, "flag after precision"); \
237 }
238
239 ++argc;
240 --argv;
241 StringValue(fmt);
242 enc = rb_enc_get(fmt);
243 orig = fmt;
244 fmt = rb_str_tmp_frozen_acquire(fmt);
245 p = RSTRING_PTR(fmt);
246 end = p + RSTRING_LEN(fmt);
247 blen = 0;
248 bsiz = 120;
249 result = rb_str_buf_new(bsiz);
250 rb_enc_copy(result, fmt);
251 buf = RSTRING_PTR(result);
252 memset(buf, 0, bsiz);
253 ENC_CODERANGE_SET(result, coderange);
254
255 for (; p < end; p++) {
256 const char *t;
257 int n;
258 VALUE sym = Qnil;
259
260 for (t = p; t < end && *t != '%'; t++) ;
261 if (t + 1 == end) {
262 rb_raise(rb_eArgError, "incomplete format specifier; use %%%% (double %%) instead");
263 }
264 PUSH(p, t - p);
265 if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) {
266 scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &coderange);
267 ENC_CODERANGE_SET(result, coderange);
268 }
269 if (t >= end) {
270 /* end of fmt string */
271 goto sprint_exit;
272 }
273 p = t + 1; /* skip `%' */
274
275 width = prec = -1;
276 nextvalue = Qundef;
277 retry:
278 switch (*p) {
279 default:
280 if (rb_enc_isprint(*p, enc))
281 rb_raise(rb_eArgError, "malformed format string - %%%c", *p);
282 else
283 rb_raise(rb_eArgError, "malformed format string");
284 break;
285
286 case ' ':
287 CHECK_FOR_FLAGS(flags);
288 flags |= FSPACE;
289 p++;
290 goto retry;
291
292 case '#':
293 CHECK_FOR_FLAGS(flags);
294 flags |= FSHARP;
295 p++;
296 goto retry;
297
298 case '+':
299 CHECK_FOR_FLAGS(flags);
300 flags |= FPLUS;
301 p++;
302 goto retry;
303
304 case '-':
305 CHECK_FOR_FLAGS(flags);
306 flags |= FMINUS;
307 p++;
308 goto retry;
309
310 case '0':
311 CHECK_FOR_FLAGS(flags);
312 flags |= FZERO;
313 p++;
314 goto retry;
315
316 case '1': case '2': case '3': case '4':
317 case '5': case '6': case '7': case '8': case '9':
318 n = 0;
319 GETNUM(n, width);
320 if (*p == '$') {
321 if (nextvalue != Qundef) {
322 rb_raise(rb_eArgError, "value given twice - %d$", n);
323 }
324 nextvalue = GETPOSARG(n);
325 p++;
326 goto retry;
327 }
328 CHECK_FOR_WIDTH(flags);
329 width = n;
330 flags |= FWIDTH;
331 goto retry;
332
333 case '<':
334 case '{':
335 {
336 const char *start = p;
337 char term = (*p == '<') ? '>' : '}';
338 int len;
339
340 for (; p < end && *p != term; ) {
341 p += rb_enc_mbclen(p, end, enc);
342 }
343 if (p >= end) {
344 rb_raise(rb_eArgError, "malformed name - unmatched parenthesis");
345 }
346 #if SIZEOF_INT < SIZEOF_SIZE_T
347 if ((size_t)(p - start) >= INT_MAX) {
348 const int message_limit = 20;
349 len = (int)(rb_enc_right_char_head(start, start + message_limit, p, enc) - start);
350 rb_enc_raise(enc, rb_eArgError,
351 "too long name (%"PRIuSIZE" bytes) - %.*s...%c",
352 (size_t)(p - start - 2), len, start, term);
353 }
354 #endif
355 len = (int)(p - start + 1); /* including parenthesis */
356 if (sym != Qnil) {
357 rb_enc_raise(enc, rb_eArgError, "named%.*s after <%"PRIsVALUE">",
358 len, start, rb_sym2str(sym));
359 }
360 CHECKNAMEARG(start, len, enc);
361 get_hash(&hash, argc, argv);
362 sym = rb_check_symbol_cstr(start + 1,
363 len - 2 /* without parenthesis */,
364 enc);
365 if (!NIL_P(sym)) nextvalue = rb_hash_lookup2(hash, sym, Qundef);
366 if (nextvalue == Qundef) {
367 if (NIL_P(sym)) {
368 sym = rb_sym_intern(start + 1,
369 len - 2 /* without parenthesis */,
370 enc);
371 }
372 nextvalue = rb_hash_default_value(hash, sym);
373 if (NIL_P(nextvalue)) {
374 rb_key_err_raise(rb_enc_sprintf(enc, "key%.*s not found", len, start), hash, sym);
375 }
376 }
377 if (term == '}') goto format_s;
378 p++;
379 goto retry;
380 }
381
382 case '*':
383 CHECK_FOR_WIDTH(flags);
384 flags |= FWIDTH;
385 GETASTER(width);
386 if (width < 0) {
387 flags |= FMINUS;
388 width = -width;
389 if (width < 0) rb_raise(rb_eArgError, "width too big");
390 }
391 p++;
392 goto retry;
393
394 case '.':
395 if (flags & FPREC0) {
396 rb_raise(rb_eArgError, "precision given twice");
397 }
398 flags |= FPREC|FPREC0;
399
400 prec = 0;
401 p++;
402 if (*p == '*') {
403 GETASTER(prec);
404 if (prec < 0) { /* ignore negative precision */
405 flags &= ~FPREC;
406 }
407 p++;
408 goto retry;
409 }
410
411 GETNUM(prec, precision);
412 goto retry;
413
414 case '\n':
415 case '\0':
416 p--;
417 /* fall through */
418 case '%':
419 if (flags != FNONE) {
420 rb_raise(rb_eArgError, "invalid format character - %%");
421 }
422 PUSH("%", 1);
423 break;
424
425 case 'c':
426 {
427 VALUE val = GETARG();
428 VALUE tmp;
429 unsigned int c;
430 int n;
431
432 tmp = rb_check_string_type(val);
433 if (!NIL_P(tmp)) {
434 if (rb_enc_strlen(RSTRING_PTR(tmp),RSTRING_END(tmp),enc) != 1) {
435 rb_raise(rb_eArgError, "%%c requires a character");
436 }
437 c = rb_enc_codepoint_len(RSTRING_PTR(tmp), RSTRING_END(tmp), &n, enc);
438 RB_GC_GUARD(tmp);
439 }
440 else {
441 c = NUM2INT(val);
442 n = rb_enc_codelen(c, enc);
443 }
444 if (n <= 0) {
445 rb_raise(rb_eArgError, "invalid character");
446 }
447 if (!(flags & FWIDTH)) {
448 CHECK(n);
449 rb_enc_mbcput(c, &buf[blen], enc);
450 blen += n;
451 }
452 else if ((flags & FMINUS)) {
453 CHECK(n);
454 rb_enc_mbcput(c, &buf[blen], enc);
455 blen += n;
456 if (width > 1) FILL(' ', width-1);
457 }
458 else {
459 if (width > 1) FILL(' ', width-1);
460 CHECK(n);
461 rb_enc_mbcput(c, &buf[blen], enc);
462 blen += n;
463 }
464 }
465 break;
466
467 case 's':
468 case 'p':
469 format_s:
470 {
471 VALUE arg = GETARG();
472 long len, slen;
473
474 if (*p == 'p') {
475 str = rb_inspect(arg);
476 }
477 else {
478 str = rb_obj_as_string(arg);
479 }
480 len = RSTRING_LEN(str);
481 rb_str_set_len(result, blen);
482 if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) {
483 int cr = coderange;
484 scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &cr);
485 ENC_CODERANGE_SET(result,
486 (cr == ENC_CODERANGE_UNKNOWN ?
487 ENC_CODERANGE_BROKEN : (coderange = cr)));
488 }
489 enc = rb_enc_check(result, str);
490 if (flags&(FPREC|FWIDTH)) {
491 slen = rb_enc_strlen(RSTRING_PTR(str),RSTRING_END(str),enc);
492 if (slen < 0) {
493 rb_raise(rb_eArgError, "invalid mbstring sequence");
494 }
495 if ((flags&FPREC) && (prec < slen)) {
496 char *p = rb_enc_nth(RSTRING_PTR(str), RSTRING_END(str),
497 prec, enc);
498 slen = prec;
499 len = p - RSTRING_PTR(str);
500 }
501 /* need to adjust multi-byte string pos */
502 if ((flags&FWIDTH) && (width > slen)) {
503 width -= (int)slen;
504 if (!(flags&FMINUS)) {
505 FILL(' ', width);
506 width = 0;
507 }
508 CHECK(len);
509 memcpy(&buf[blen], RSTRING_PTR(str), len);
510 RB_GC_GUARD(str);
511 blen += len;
512 if (flags&FMINUS) {
513 FILL(' ', width);
514 }
515 rb_enc_associate(result, enc);
516 break;
517 }
518 }
519 PUSH(RSTRING_PTR(str), len);
520 RB_GC_GUARD(str);
521 rb_enc_associate(result, enc);
522 }
523 break;
524
525 case 'd':
526 case 'i':
527 case 'o':
528 case 'x':
529 case 'X':
530 case 'b':
531 case 'B':
532 case 'u':
533 {
534 volatile VALUE val = GETARG();
535 int valsign;
536 char nbuf[BIT_DIGITS(SIZEOF_LONG*CHAR_BIT)+2], *s;
537 const char *prefix = 0;
538 int sign = 0, dots = 0;
539 char sc = 0;
540 long v = 0;
541 int base, bignum = 0;
542 int len;
543
544 switch (*p) {
545 case 'd':
546 case 'i':
547 case 'u':
548 sign = 1; break;
549 case 'o':
550 case 'x':
551 case 'X':
552 case 'b':
553 case 'B':
554 if (flags&(FPLUS|FSPACE)) sign = 1;
555 break;
556 }
557 if (flags & FSHARP) {
558 switch (*p) {
559 case 'o':
560 prefix = "0"; break;
561 case 'x':
562 prefix = "0x"; break;
563 case 'X':
564 prefix = "0X"; break;
565 case 'b':
566 prefix = "0b"; break;
567 case 'B':
568 prefix = "0B"; break;
569 }
570 }
571
572 bin_retry:
573 switch (TYPE(val)) {
574 case T_FLOAT:
575 if (FIXABLE(RFLOAT_VALUE(val))) {
576 val = LONG2FIX((long)RFLOAT_VALUE(val));
577 goto bin_retry;
578 }
579 val = rb_dbl2big(RFLOAT_VALUE(val));
580 if (FIXNUM_P(val)) goto bin_retry;
581 bignum = 1;
582 break;
583 case T_STRING:
584 val = rb_str_to_inum(val, 0, TRUE);
585 goto bin_retry;
586 case T_BIGNUM:
587 bignum = 1;
588 break;
589 case T_FIXNUM:
590 v = FIX2LONG(val);
591 break;
592 default:
593 val = rb_Integer(val);
594 goto bin_retry;
595 }
596
597 switch (*p) {
598 case 'o':
599 base = 8; break;
600 case 'x':
601 case 'X':
602 base = 16; break;
603 case 'b':
604 case 'B':
605 base = 2; break;
606 case 'u':
607 case 'd':
608 case 'i':
609 default:
610 base = 10; break;
611 }
612
613 if (base != 10) {
614 int numbits = ffs(base)-1;
615 size_t abs_nlz_bits;
616 size_t numdigits = rb_absint_numwords(val, numbits, &abs_nlz_bits);
617 long i;
618 if (INT_MAX-1 < numdigits) /* INT_MAX is used because rb_long2int is used later. */
619 rb_raise(rb_eArgError, "size too big");
620 if (sign) {
621 if (numdigits == 0)
622 numdigits = 1;
623 tmp = rb_str_new(NULL, numdigits);
624 valsign = rb_integer_pack(val, RSTRING_PTR(tmp), RSTRING_LEN(tmp),
625 1, CHAR_BIT-numbits, INTEGER_PACK_BIG_ENDIAN);
626 for (i = 0; i < RSTRING_LEN(tmp); i++)
627 RSTRING_PTR(tmp)[i] = ruby_digitmap[((unsigned char *)RSTRING_PTR(tmp))[i]];
628 s = RSTRING_PTR(tmp);
629 if (valsign < 0) {
630 sc = '-';
631 width--;
632 }
633 else if (flags & FPLUS) {
634 sc = '+';
635 width--;
636 }
637 else if (flags & FSPACE) {
638 sc = ' ';
639 width--;
640 }
641 }
642 else {
643 /* Following conditional "numdigits++" guarantees the
644 * most significant digit as
645 * - '1'(bin), '7'(oct) or 'f'(hex) for negative numbers
646 * - '0' for zero
647 * - not '0' for positive numbers.
648 *
649 * It also guarantees the most significant two
650 * digits will not be '11'(bin), '77'(oct), 'ff'(hex)
651 * or '00'. */
652 if (numdigits == 0 ||
653 ((abs_nlz_bits != (size_t)(numbits-1) ||
654 !rb_absint_singlebit_p(val)) &&
655 (!bignum ? v < 0 : BIGNUM_NEGATIVE_P(val))))
656 numdigits++;
657 tmp = rb_str_new(NULL, numdigits);
658 valsign = rb_integer_pack(val, RSTRING_PTR(tmp), RSTRING_LEN(tmp),
659 1, CHAR_BIT-numbits, INTEGER_PACK_2COMP | INTEGER_PACK_BIG_ENDIAN);
660 for (i = 0; i < RSTRING_LEN(tmp); i++)
661 RSTRING_PTR(tmp)[i] = ruby_digitmap[((unsigned char *)RSTRING_PTR(tmp))[i]];
662 s = RSTRING_PTR(tmp);
663 dots = valsign < 0;
664 }
665 len = rb_long2int(RSTRING_END(tmp) - s);
666 }
667 else if (!bignum) {
668 valsign = 1;
669 if (v < 0) {
670 v = -v;
671 sc = '-';
672 width--;
673 valsign = -1;
674 }
675 else if (flags & FPLUS) {
676 sc = '+';
677 width--;
678 }
679 else if (flags & FSPACE) {
680 sc = ' ';
681 width--;
682 }
683 s = ruby_ultoa((unsigned long)v, nbuf + sizeof(nbuf), 10, 0);
684 len = (int)(nbuf + sizeof(nbuf) - s);
685 }
686 else {
687 tmp = rb_big2str(val, 10);
688 s = RSTRING_PTR(tmp);
689 valsign = 1;
690 if (s[0] == '-') {
691 s++;
692 sc = '-';
693 width--;
694 valsign = -1;
695 }
696 else if (flags & FPLUS) {
697 sc = '+';
698 width--;
699 }
700 else if (flags & FSPACE) {
701 sc = ' ';
702 width--;
703 }
704 len = rb_long2int(RSTRING_END(tmp) - s);
705 }
706
707 if (dots) {
708 prec -= 2;
709 width -= 2;
710 }
711
712 if (*p == 'X') {
713 char *pp = s;
714 int c;
715 while ((c = (int)(unsigned char)*pp) != 0) {
716 *pp = rb_enc_toupper(c, enc);
717 pp++;
718 }
719 }
720 if (prefix && !prefix[1]) { /* octal */
721 if (dots) {
722 prefix = 0;
723 }
724 else if (len == 1 && *s == '0') {
725 len = 0;
726 if (flags & FPREC) prec--;
727 }
728 else if ((flags & FPREC) && (prec > len)) {
729 prefix = 0;
730 }
731 }
732 else if (len == 1 && *s == '0') {
733 prefix = 0;
734 }
735 if (prefix) {
736 width -= (int)strlen(prefix);
737 }
738 if ((flags & (FZERO|FMINUS|FPREC)) == FZERO) {
739 prec = width;
740 width = 0;
741 }
742 else {
743 if (prec < len) {
744 if (!prefix && prec == 0 && len == 1 && *s == '0') len = 0;
745 prec = len;
746 }
747 width -= prec;
748 }
749 if (!(flags&FMINUS)) {
750 FILL(' ', width);
751 width = 0;
752 }
753 if (sc) PUSH(&sc, 1);
754 if (prefix) {
755 int plen = (int)strlen(prefix);
756 PUSH(prefix, plen);
757 }
758 if (dots) PUSH("..", 2);
759 if (prec > len) {
760 CHECK(prec - len);
761 if (!sign && valsign < 0) {
762 char c = sign_bits(base, p);
763 FILL_(c, prec - len);
764 }
765 else if ((flags & (FMINUS|FPREC)) != FMINUS) {
766 FILL_('0', prec - len);
767 }
768 }
769 PUSH(s, len);
770 RB_GC_GUARD(tmp);
771 FILL(' ', width);
772 }
773 break;
774
775 case 'f':
776 {
777 VALUE val = GETARG(), num, den;
778 int sign = (flags&FPLUS) ? 1 : 0, zero = 0;
779 long len, fill;
780 if (RB_INTEGER_TYPE_P(val)) {
781 den = INT2FIX(1);
782 num = val;
783 }
784 else if (RB_TYPE_P(val, T_RATIONAL)) {
785 den = rb_rational_den(val);
786 num = rb_rational_num(val);
787 }
788 else {
789 nextvalue = val;
790 goto float_value;
791 }
792 if (!(flags&FPREC)) prec = default_float_precision;
793 if (FIXNUM_P(num)) {
794 if ((SIGNED_VALUE)num < 0) {
795 long n = -FIX2LONG(num);
796 num = LONG2FIX(n);
797 sign = -1;
798 }
799 }
800 else if (BIGNUM_NEGATIVE_P(num)) {
801 sign = -1;
802 num = rb_big_uminus(num);
803 }
804 if (den != INT2FIX(1)) {
805 num = rb_int_mul(num, rb_int_positive_pow(10, prec));
806 num = rb_int_plus(num, rb_int_idiv(den, INT2FIX(2)));
807 num = rb_int_idiv(num, den);
808 }
809 else if (prec >= 0) {
810 zero = prec;
811 }
812 val = rb_int2str(num, 10);
813 len = RSTRING_LEN(val) + zero;
814 if (prec >= len) len = prec + 1; /* integer part 0 */
815 if (sign || (flags&FSPACE)) ++len;
816 if (prec > 0) ++len; /* period */
817 fill = width > len ? width - len : 0;
818 CHECK(fill + len);
819 if (fill && !(flags&(FMINUS|FZERO))) {
820 FILL_(' ', fill);
821 }
822 if (sign || (flags&FSPACE)) {
823 buf[blen++] = sign > 0 ? '+' : sign < 0 ? '-' : ' ';
824 }
825 if (fill && (flags&(FMINUS|FZERO)) == FZERO) {
826 FILL_('0', fill);
827 }
828 len = RSTRING_LEN(val) + zero;
829 t = RSTRING_PTR(val);
830 if (len > prec) {
831 PUSH_(t, len - prec);
832 }
833 else {
834 buf[blen++] = '0';
835 }
836 if (prec > 0) {
837 buf[blen++] = '.';
838 }
839 if (zero) {
840 FILL_('0', zero);
841 }
842 else if (prec > len) {
843 FILL_('0', prec - len);
844 PUSH_(t, len);
845 }
846 else if (prec > 0) {
847 PUSH_(t + len - prec, prec);
848 }
849 if (fill && (flags&FMINUS)) {
850 FILL_(' ', fill);
851 }
852 RB_GC_GUARD(val);
853 break;
854 }
855 case 'g':
856 case 'G':
857 case 'e':
858 case 'E':
859 /* TODO: rational support */
860 case 'a':
861 case 'A':
862 float_value:
863 {
864 VALUE val = GETARG();
865 double fval;
866
867 fval = RFLOAT_VALUE(rb_Float(val));
868 if (isnan(fval) || isinf(fval)) {
869 const char *expr;
870 int need;
871 int elen;
872 char sign = '\0';
873
874 if (isnan(fval)) {
875 expr = "NaN";
876 }
877 else {
878 expr = "Inf";
879 }
880 need = (int)strlen(expr);
881 elen = need;
882 if (!isnan(fval) && fval < 0.0)
883 sign = '-';
884 else if (flags & (FPLUS|FSPACE))
885 sign = (flags & FPLUS) ? '+' : ' ';
886 if (sign)
887 ++need;
888 if ((flags & FWIDTH) && need < width)
889 need = width;
890
891 FILL(' ', need);
892 if (flags & FMINUS) {
893 if (sign)
894 buf[blen - need--] = sign;
895 memcpy(&buf[blen - need], expr, elen);
896 }
897 else {
898 if (sign)
899 buf[blen - elen - 1] = sign;
900 memcpy(&buf[blen - elen], expr, elen);
901 }
902 break;
903 }
904 else {
905 int cr = ENC_CODERANGE(result);
906 char fbuf[2*BIT_DIGITS(SIZEOF_INT*CHAR_BIT)+10];
907 char *fmt = fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec);
908 rb_str_set_len(result, blen);
909 rb_str_catf(result, fmt, fval);
910 ENC_CODERANGE_SET(result, cr);
911 bsiz = rb_str_capacity(result);
912 RSTRING_GETMEM(result, buf, blen);
913 }
914 }
915 break;
916 }
917 flags = FNONE;
918 }
919
920 sprint_exit:
921 rb_str_tmp_frozen_release(orig, fmt);
922 /* XXX - We cannot validate the number of arguments if (digit)$ style used.
923 */
924 if (posarg >= 0 && nextarg < argc) {
925 const char *mesg = "too many arguments for format string";
926 if (RTEST(ruby_debug)) rb_raise(rb_eArgError, "%s", mesg);
927 if (RTEST(ruby_verbose)) rb_warn("%s", mesg);
928 }
929 rb_str_resize(result, blen);
930
931 return result;
932 }
933
934 static char *
935 fmt_setup(char *buf, size_t size, int c, int flags, int width, int prec)
936 {
937 buf += size;
938 *--buf = '\0';
939 *--buf = c;
940
941 if (flags & FPREC) {
942 buf = ruby_ultoa(prec, buf, 10, 0);
943 *--buf = '.';
944 }
945
946 if (flags & FWIDTH) {
947 buf = ruby_ultoa(width, buf, 10, 0);
948 }
949
950 if (flags & FSPACE) *--buf = ' ';
951 if (flags & FZERO) *--buf = '0';
952 if (flags & FMINUS) *--buf = '-';
953 if (flags & FPLUS) *--buf = '+';
954 if (flags & FSHARP) *--buf = '#';
955 *--buf = '%';
956 return buf;
957 }
958
959 #undef FILE
960 #define FILE rb_printf_buffer
961 #define __sbuf rb_printf_sbuf
962 #define __sFILE rb_printf_sfile
963 #undef feof
964 #undef ferror
965 #undef clearerr
966 #undef fileno
967 #if SIZEOF_LONG < SIZEOF_VOIDP
968 # if SIZEOF_LONG_LONG == SIZEOF_VOIDP
969 # define _HAVE_SANE_QUAD_
970 # define _HAVE_LLP64_
971 # define quad_t LONG_LONG
972 # define u_quad_t unsigned LONG_LONG
973 # endif
974 #elif SIZEOF_LONG != SIZEOF_LONG_LONG && SIZEOF_LONG_LONG == 8
975 # define _HAVE_SANE_QUAD_
976 # define quad_t LONG_LONG
977 # define u_quad_t unsigned LONG_LONG
978 #endif
979 #define FLOATING_POINT 1
980 #define BSD__dtoa ruby_dtoa
981 #define BSD__hdtoa ruby_hdtoa
982 #ifdef RUBY_PRI_VALUE_MARK
983 # define PRI_EXTRA_MARK RUBY_PRI_VALUE_MARK
984 #endif
985 #define lower_hexdigits (ruby_hexdigits+0)
986 #define upper_hexdigits (ruby_hexdigits+16)
987 #if defined RUBY_USE_SETJMPEX && RUBY_USE_SETJMPEX
988 # undef MAYBE_UNUSED
989 # define MAYBE_UNUSED(x) x = 0
990 #endif
991 #include "vsnprintf.c"
992
993 static char *
994 ruby_ultoa(unsigned long val, char *endp, int base, int flags)
995 {
996 const char *xdigs = lower_hexdigits;
997 int octzero = flags & FSHARP;
998 return BSD__ultoa(val, endp, base, octzero, xdigs);
999 }
1000
1001 static int ruby_do_vsnprintf(char *str, size_t n, const char *fmt, va_list ap);
1002
1003 int
1004 ruby_vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
1005 {
1006 if (str && (ssize_t)n < 1)
1007 return (EOF);
1008 return ruby_do_vsnprintf(str, n, fmt, ap);
1009 }
1010
1011 static int
1012 ruby_do_vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
1013 {
1014 ssize_t ret;
1015 rb_printf_buffer f;
1016
1017 f._flags = __SWR | __SSTR;
1018 f._bf._base = f._p = (unsigned char *)str;
1019 f._bf._size = f._w = str ? (n - 1) : 0;
1020 f.vwrite = BSD__sfvwrite;
1021 f.vextra = 0;
1022 ret = BSD_vfprintf(&f, fmt, ap);
1023 if (str) *f._p = 0;
1024 #if SIZEOF_SIZE_T > SIZEOF_INT
1025 if (n > INT_MAX) return INT_MAX;
1026 #endif
1027 return (int)ret;
1028 }
1029
1030 int
1031 ruby_snprintf(char *str, size_t n, char const *fmt, ...)
1032 {
1033 int ret;
1034 va_list ap;
1035
1036 if (str && (ssize_t)n < 1)
1037 return (EOF);
1038
1039 va_start(ap, fmt);
1040 ret = ruby_do_vsnprintf(str, n, fmt, ap);
1041 va_end(ap);
1042 return ret;
1043 }
1044
1045 typedef struct {
1046 rb_printf_buffer base;
1047 volatile VALUE value;
1048 } rb_printf_buffer_extra;
1049
1050 static int
1051 ruby__sfvwrite(register rb_printf_buffer *fp, register struct __suio *uio)
1052 {
1053 struct __siov *iov;
1054 VALUE result = (VALUE)fp->_bf._base;
1055 char *buf = (char*)fp->_p;
1056 long len, n;
1057 long blen = buf - RSTRING_PTR(result), bsiz = fp->_w;
1058
1059 if (RBASIC(result)->klass) {
1060 rb_raise(rb_eRuntimeError, "rb_vsprintf reentered");
1061 }
1062 if (uio->uio_resid == 0)
1063 return 0;
1064 #if SIZE_MAX > LONG_MAX
1065 if (uio->uio_resid >= LONG_MAX)
1066 rb_raise(rb_eRuntimeError, "too big string");
1067 #endif
1068 len = (long)uio->uio_resid;
1069 CHECK(len);
1070 buf += blen;
1071 fp->_w = bsiz;
1072 for (iov = uio->uio_iov; len > 0; ++iov) {
1073 MEMCPY(buf, iov->iov_base, char, n = iov->iov_len);
1074 buf += n;
1075 len -= n;
1076 }
1077 fp->_p = (unsigned char *)buf;
1078 rb_str_set_len(result, buf - RSTRING_PTR(result));
1079 return 0;
1080 }
1081
1082 static const char *
1083 ruby__sfvextra(rb_printf_buffer *fp, size_t valsize, void *valp, long *sz, int sign)
1084 {
1085 VALUE value, result = (VALUE)fp->_bf._base;
1086 rb_encoding *enc;
1087 char *cp;
1088
1089 if (valsize != sizeof(VALUE)) return 0;
1090 value = *(VALUE *)valp;
1091 if (RBASIC(result)->klass) {
1092 rb_raise(rb_eRuntimeError, "rb_vsprintf reentered");
1093 }
1094 if (sign == '+') {
1095 if (RB_TYPE_P(value, T_CLASS)) {
1096 # define LITERAL(str) (*sz = rb_strlen_lit(str), str)
1097
1098 if (value == rb_cNilClass) {
1099 return LITERAL("nil");
1100 }
1101 else if (value == rb_cInteger) {
1102 return LITERAL("Integer");
1103 }
1104 else if (value == rb_cSymbol) {
1105 return LITERAL("Symbol");
1106 }
1107 else if (value == rb_cTrueClass) {
1108 return LITERAL("true");
1109 }
1110 else if (value == rb_cFalseClass) {
1111 return LITERAL("false");
1112 }
1113 # undef LITERAL
1114 }
1115 value = rb_inspect(value);
1116 }
1117 else if (SYMBOL_P(value)) {
1118 value = rb_sym2str(value);
1119 if (sign == ' ' && !rb_str_symname_p(value)) {
1120 value = rb_str_inspect(value);
1121 }
1122 }
1123 else {
1124 value = rb_obj_as_string(value);
1125 if (sign == ' ') value = QUOTE(value);
1126 }
1127 enc = rb_enc_compatible(result, value);
1128 if (enc) {
1129 rb_enc_associate(result, enc);
1130 }
1131 else {
1132 enc = rb_enc_get(result);
1133 value = rb_str_conv_enc_opts(value, rb_enc_get(value), enc,
1134 ECONV_UNDEF_REPLACE|ECONV_INVALID_REPLACE,
1135 Qnil);
1136 *(volatile VALUE *)valp = value;
1137 }
1138 StringValueCStr(value);
1139 RSTRING_GETMEM(value, cp, *sz);
1140 ((rb_printf_buffer_extra *)fp)->value = value;
1141 return cp;
1142 }
1143
1144 VALUE
1145 rb_enc_vsprintf(rb_encoding *enc, const char *fmt, va_list ap)
1146 {
1147 rb_printf_buffer_extra buffer;
1148 #define f buffer.base
1149 VALUE result;
1150
1151 f._flags = __SWR | __SSTR;
1152 f._bf._size = 0;
1153 f._w = 120;
1154 result = rb_str_buf_new(f._w);
1155 if (enc) {
1156 if (rb_enc_mbminlen(enc) > 1) {
1157 /* the implementation deeply depends on plain char */
1158 rb_raise(rb_eArgError, "cannot construct wchar_t based encoding string: %s",
1159 rb_enc_name(enc));
1160 }
1161 rb_enc_associate(result, enc);
1162 }
1163 f._bf._base = (unsigned char *)result;
1164 f._p = (unsigned char *)RSTRING_PTR(result);
1165 RBASIC_CLEAR_CLASS(result);
1166 f.vwrite = ruby__sfvwrite;
1167 f.vextra = ruby__sfvextra;
1168 buffer.value = 0;
1169 BSD_vfprintf(&f, fmt, ap);
1170 RBASIC_SET_CLASS_RAW(result, rb_cString);
1171 rb_str_resize(result, (char *)f._p - RSTRING_PTR(result));
1172 #undef f
1173
1174 return result;
1175 }
1176
1177 VALUE
1178 rb_enc_sprintf(rb_encoding *enc, const char *format, ...)
1179 {
1180 VALUE result;
1181 va_list ap;
1182
1183 va_start(ap, format);
1184 result = rb_enc_vsprintf(enc, format, ap);
1185 va_end(ap);
1186
1187 return result;
1188 }
1189
1190 VALUE
1191 rb_vsprintf(const char *fmt, va_list ap)
1192 {
1193 return rb_enc_vsprintf(NULL, fmt, ap);
1194 }
1195
1196 VALUE
1197 rb_sprintf(const char *format, ...)
1198 {
1199 VALUE result;
1200 va_list ap;
1201
1202 va_start(ap, format);
1203 result = rb_vsprintf(format, ap);
1204 va_end(ap);
1205
1206 return result;
1207 }
1208
1209 VALUE
1210 rb_str_vcatf(VALUE str, const char *fmt, va_list ap)
1211 {
1212 rb_printf_buffer_extra buffer;
1213 #define f buffer.base
1214 VALUE klass;
1215
1216 StringValue(str);
1217 rb_str_modify(str);
1218 f._flags = __SWR | __SSTR;
1219 f._bf._size = 0;
1220 f._w = rb_str_capacity(str);
1221 f._bf._base = (unsigned char *)str;
1222 f._p = (unsigned char *)RSTRING_END(str);
1223 klass = RBASIC(str)->klass;
1224 RBASIC_CLEAR_CLASS(str);
1225 f.vwrite = ruby__sfvwrite;
1226 f.vextra = ruby__sfvextra;
1227 buffer.value = 0;
1228 BSD_vfprintf(&f, fmt, ap);
1229 RBASIC_SET_CLASS_RAW(str, klass);
1230 rb_str_resize(str, (char *)f._p - RSTRING_PTR(str));
1231 #undef f
1232
1233 return str;
1234 }
1235
1236 VALUE
1237 rb_str_catf(VALUE str, const char *format, ...)
1238 {
1239 va_list ap;
1240
1241 va_start(ap, format);
1242 str = rb_str_vcatf(str, format, ap);
1243 va_end(ap);
1244
1245 return str;
1246 }
__SSTR
#define __SSTR
Definition: vsnprintf.c:196
rb_str_symname_p
int rb_str_symname_p(VALUE)
Definition: string.c:10695
TRUE
#define TRUE
Definition: nkf.h:175
GETNTHARG
#define GETNTHARG(nth)
Definition: sprintf.c:101
RSTRING_GETMEM
#define RSTRING_GETMEM(str, ptrvar, lenvar)
Definition: ruby.h:1018
T_FLOAT
#define T_FLOAT
Definition: ruby.h:527
ruby_snprintf
int ruby_snprintf(char *str, size_t n, char const *fmt,...)
Definition: sprintf.c:1031
rb_enc_name
#define rb_enc_name(enc)
Definition: encoding.h:177
LONG_MAX
#define LONG_MAX
Definition: ruby.h:220
rb_enc_mbclen
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc)
Definition: encoding.c:1020
rb_enc_mbcput
#define rb_enc_mbcput(c, buf, enc)
Definition: encoding.h:217
rb_sym_intern
VALUE rb_sym_intern(const char *ptr, long len, rb_encoding *enc)
Definition: symbol.c:1024
rb_warn
void rb_warn(const char *fmt,...)
Definition: error.c:313
rb_str_buf_new
VALUE rb_str_buf_new(long)
Definition: string.c:1315
memset
void * memset(void *, int, size_t)
rb_enc_strlen
long rb_enc_strlen(const char *, const char *, rb_encoding *)
Definition: string.c:1740
RBASIC_CLEAR_CLASS
#define RBASIC_CLEAR_CLASS(obj)
Definition: internal.h:1981
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:263
__suio
Definition: vsnprintf.c:230
rb_int2str
VALUE rb_int2str(VALUE num, int base)
Definition: numeric.c:3562
rb_hash_default_value
VALUE rb_hash_default_value(VALUE hash, VALUE key)
Definition: hash.c:1917
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:1009
re.h
rb_dbl2big
VALUE rb_dbl2big(double d)
Definition: bignum.c:5249
FSPACE
#define FSPACE
Definition: sprintf.c:53
GETARG
#define GETARG()
Definition: sprintf.c:90
FNONE
#define FNONE
Definition: sprintf.c:48
rb_int_positive_pow
RUBY_EXTERN VALUE rb_int_positive_pow(long x, unsigned long y)
Definition: numeric.c:4033
rb_enc_sprintf
VALUE rb_enc_sprintf(rb_encoding *enc, const char *format,...)
Definition: sprintf.c:1178
VALUE
unsigned long VALUE
Definition: ruby.h:102
rb_obj_as_string
VALUE rb_obj_as_string(VALUE)
Definition: string.c:1440
rb_eArgError
VALUE rb_eArgError
Definition: error.c:923
encoding.h
ruby_verbose
#define ruby_verbose
Definition: ruby.h:1925
rb_str_format
VALUE rb_str_format(int argc, const VALUE *argv, VALUE fmt)
Definition: sprintf.c:204
RB_TYPE_P
#define RB_TYPE_P(obj, type)
Definition: ruby.h:560
TYPE
#define TYPE(x)
Definition: ruby.h:554
SIZEOF_INT
#define SIZEOF_INT
Definition: rb_mjit_min_header-2.7.0.h:83
rb_enc_get
rb_encoding * rb_enc_get(VALUE obj)
Definition: encoding.c:872
rb_enc_check
rb_encoding * rb_enc_check(VALUE str1, VALUE str2)
Definition: encoding.c:891
ECONV_UNDEF_REPLACE
#define ECONV_UNDEF_REPLACE
Definition: encoding.h:396
rb_rational_num
VALUE rb_rational_num(VALUE rat)
Definition: rational.c:1960
int
__inline__ int
Definition: rb_mjit_min_header-2.7.0.h:2839
rb_rational_den
VALUE rb_rational_den(VALUE rat)
Definition: rational.c:1966
id.h
SIGNED_VALUE
#define SIGNED_VALUE
Definition: ruby.h:104
FILL
#define FILL(c, l)
Definition: sprintf.c:79
rb_inspect
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
Definition: object.c:551
vsnprintf.c
StringValue
use StringValue() instead")))
rb_enc_isdigit
#define rb_enc_isdigit(c, enc)
Definition: encoding.h:238
rb_hash_lookup2
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
Definition: hash.c:1977
rb_check_string_type
VALUE rb_check_string_type(VALUE)
Definition: string.c:2314
rb_Float
VALUE rb_Float(VALUE)
Equivalent to Kernel#Float in Ruby.
Definition: object.c:3493
Qundef
#define Qundef
Definition: ruby.h:470
MUL_OVERFLOW_INT_P
#define MUL_OVERFLOW_INT_P(a, b)
Definition: internal.h:283
T_RATIONAL
#define T_RATIONAL
Definition: ruby.h:541
CHAR_BIT
#define CHAR_BIT
Definition: ruby.h:227
rb_str_modify
void rb_str_modify(VALUE)
Definition: string.c:2114
rb_long2int
#define rb_long2int(n)
Definition: ruby.h:350
ENC_CODERANGE_SET
#define ENC_CODERANGE_SET(obj, cr)
Definition: encoding.h:110
rb_str_inspect
VALUE rb_str_inspect(VALUE)
Definition: string.c:5930
rb_Integer
VALUE rb_Integer(VALUE)
Equivalent to Kernel#Integer in Ruby.
Definition: object.c:3106
ssize_t
_ssize_t ssize_t
Definition: rb_mjit_min_header-2.7.0.h:1329
rb_enc_right_char_head
#define rb_enc_right_char_head(s, p, e, enc)
Definition: encoding.h:223
rb_cInteger
RUBY_EXTERN VALUE rb_cInteger
Definition: ruby.h:2031
NULL
#define NULL
Definition: _sdbm.c:101
PRIsVALUE
#define PRIsVALUE
Definition: ruby.h:166
rb_enc_vsprintf
VALUE rb_enc_vsprintf(rb_encoding *enc, const char *fmt, va_list ap)
Definition: sprintf.c:1145
FIX2LONG
#define FIX2LONG(x)
Definition: ruby.h:394
rb_int_idiv
VALUE rb_int_idiv(VALUE x, VALUE y)
Definition: numeric.c:3843
strlen
size_t strlen(const char *)
FMINUS
#define FMINUS
Definition: sprintf.c:50
INTEGER_PACK_BIG_ENDIAN
#define INTEGER_PACK_BIG_ENDIAN
Definition: intern.h:165
rb_check_symbol_cstr
VALUE rb_check_symbol_cstr(const char *ptr, long len, rb_encoding *enc)
Definition: symbol.c:999
FSHARP
#define FSHARP
Definition: sprintf.c:49
v
int VALUE v
Definition: rb_mjit_min_header-2.7.0.h:12332
rb_str_capacity
size_t rb_str_capacity(VALUE str)
Definition: string.c:712
rb_str_resize
VALUE rb_str_resize(VALUE, long)
Definition: string.c:2709
rb_big_uminus
VALUE rb_big_uminus(VALUE x)
Definition: bignum.c:5554
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2669
rb_str_conv_enc_opts
VALUE rb_str_conv_enc_opts(VALUE str, rb_encoding *from, rb_encoding *to, int ecflags, VALUE ecopts)
Definition: string.c:914
rb_str_tmp_frozen_acquire
VALUE rb_str_tmp_frozen_acquire(VALUE str)
Definition: string.c:1210
rb_str_to_inum
VALUE rb_str_to_inum(VALUE str, int base, int badcheck)
Definition: bignum.c:4268
if
if((ID)(DISPID) nameid !=nameid)
Definition: win32ole.c:357
SIZEOF_LONG
#define SIZEOF_LONG
Definition: rb_mjit_min_header-2.7.0.h:85
rb_integer_pack
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
Definition: bignum.c:3547
PRIuSIZE
#define PRIuSIZE
Definition: ruby.h:208
memcpy
void * memcpy(void *__restrict, const void *__restrict, size_t)
rb_cNilClass
RUBY_EXTERN VALUE rb_cNilClass
Definition: ruby.h:2036
rb_int_mul
VALUE rb_int_mul(VALUE x, VALUE y)
Definition: numeric.c:3699
__siov::iov_base
const void * iov_base
Definition: vsnprintf.c:227
rb_encoding
const typedef OnigEncodingType rb_encoding
Definition: encoding.h:115
LITERAL
#define LITERAL(str)
T_FIXNUM
#define T_FIXNUM
Definition: ruby.h:535
i
uint32_t i
Definition: rb_mjit_min_header-2.7.0.h:5464
rb_cSymbol
RUBY_EXTERN VALUE rb_cSymbol
Definition: ruby.h:2046
GETASTER
#define GETASTER(val)
Definition: sprintf.c:112
sym
#define sym(x)
Definition: date_core.c:3716
PUSH
#define PUSH(s, l)
Definition: sprintf.c:69
INT_MAX
#define INT_MAX
Definition: rb_mjit_min_header-2.7.0.h:4052
long
#define long
Definition: rb_mjit_min_header-2.7.0.h:2880
va_end
#define va_end(v)
Definition: rb_mjit_min_header-2.7.0.h:3979
FPLUS
#define FPLUS
Definition: sprintf.c:51
rb_enc_mbminlen
#define rb_enc_mbminlen(enc)
Definition: encoding.h:180
term
const char term
Definition: id.c:37
isnan
#define isnan(x)
Definition: win32.h:369
FPREC0
#define FPREC0
Definition: sprintf.c:56
rb_cFalseClass
RUBY_EXTERN VALUE rb_cFalseClass
Definition: ruby.h:2022
T_CLASS
#define T_CLASS
Definition: ruby.h:524
__SWR
#define __SWR
Definition: vsnprintf.c:189
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:920
rb_enc_copy
void rb_enc_copy(VALUE obj1, VALUE obj2)
Definition: encoding.c:990
size
int size
Definition: encoding.c:58
rb_enc_compatible
rb_encoding * rb_enc_compatible(VALUE str1, VALUE str2)
Definition: encoding.c:974
rb_str_set_len
void rb_str_set_len(VALUE, long)
Definition: string.c:2692
isinf
#define isinf(__x)
Definition: rb_mjit_min_header-2.7.0.h:3673
FIXNUM_P
#define FIXNUM_P(f)
Definition: ruby.h:396
CHECK
#define CHECK(l)
Definition: sprintf.c:58
StringValueCStr
#define StringValueCStr(v)
Definition: ruby.h:604
ENC_CODERANGE_BROKEN
#define ENC_CODERANGE_BROKEN
Definition: encoding.h:106
EOF
#define EOF
Definition: vsnprintf.c:203
fmt
const VALUE int int int int int int VALUE char * fmt
Definition: rb_mjit_min_header-2.7.0.h:6462
rb_f_sprintf
VALUE rb_f_sprintf(int argc, const VALUE *argv)
Definition: sprintf.c:198
rb_vsprintf
VALUE rb_vsprintf(const char *fmt, va_list ap)
Definition: sprintf.c:1191
FZERO
#define FZERO
Definition: sprintf.c:52
rb_printf_buffer_extra
Definition: sprintf.c:1045
rb_check_hash_type
VALUE rb_check_hash_type(VALUE hash)
Definition: hash.c:1825
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4322
n
const char size_t n
Definition: rb_mjit_min_header-2.7.0.h:5456
CHECK_FOR_WIDTH
#define CHECK_FOR_WIDTH(f)
T_BIGNUM
#define T_BIGNUM
Definition: ruby.h:533
rb_printf_buffer_extra::value
volatile VALUE value
Definition: sprintf.c:1047
internal.h
__suio::uio_resid
size_t uio_resid
Definition: vsnprintf.c:233
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.0.h:5601
argv
char ** argv
Definition: ruby.c:223
f
#define f
BIGNUM_NEGATIVE_P
#define BIGNUM_NEGATIVE_P(b)
Definition: internal.h:766
rb_absint_numwords
size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret)
Definition: bignum.c:3382
rb_sprintf
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1197
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.0.h:13254
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
__suio::uio_iov
struct __siov * uio_iov
Definition: vsnprintf.c:231
rb_str_vcatf
VALUE rb_str_vcatf(VALUE str, const char *fmt, va_list ap)
Definition: sprintf.c:1210
ENC_CODERANGE_7BIT
#define ENC_CODERANGE_7BIT
Definition: encoding.h:104
lower_hexdigits
#define lower_hexdigits
Definition: sprintf.c:985
MEMCPY
#define MEMCPY(p1, p2, type, n)
Definition: ruby.h:1753
rb_cString
RUBY_EXTERN VALUE rb_cString
Definition: ruby.h:2044
ffs
RUBY_EXTERN int ffs(int)
Definition: ffs.c:6
NIL_P
#define NIL_P(v)
Definition: ruby.h:482
rb_enc_raise
void rb_enc_raise(rb_encoding *enc, VALUE exc, const char *fmt,...)
Definition: error.c:2650
rb_str_tmp_frozen_release
void rb_str_tmp_frozen_release(VALUE str, VALUE tmp)
Definition: string.c:1217
argc
int argc
Definition: ruby.c:222
PUSH_
#define PUSH_(s, l)
Definition: sprintf.c:74
rb_big2str
VALUE rb_big2str(VALUE x, int base)
Definition: bignum.c:5091
ruby_digitmap
const char ruby_digitmap[]
Definition: bignum.c:38
rb_enc_nth
char * rb_enc_nth(const char *, const char *, long, rb_encoding *)
Definition: string.c:2388
ruby_debug
#define ruby_debug
Definition: ruby.h:1926
rb_enc_toupper
int rb_enc_toupper(int c, rb_encoding *enc)
Definition: encoding.c:1106
rb_cTrueClass
RUBY_EXTERN VALUE rb_cTrueClass
Definition: ruby.h:2049
RFLOAT_VALUE
#define RFLOAT_VALUE(v)
Definition: ruby.h:966
RBASIC
#define RBASIC(obj)
Definition: ruby.h:1267
rb_str_new
#define rb_str_new(str, len)
Definition: rb_mjit_min_header-2.7.0.h:6116
rb_str_catf
VALUE rb_str_catf(VALUE str, const char *format,...)
Definition: sprintf.c:1237
QUOTE
#define QUOTE(str)
Definition: internal.h:2142
len
uint8_t len
Definition: escape.c:17
SYMBOL_P
#define SYMBOL_P(x)
Definition: ruby.h:413
ENC_CODERANGE
#define ENC_CODERANGE(obj)
Definition: encoding.h:108
INTEGER_PACK_2COMP
#define INTEGER_PACK_2COMP
Definition: intern.h:156
rb_printf_buffer_extra::base
rb_printf_buffer base
Definition: sprintf.c:1046
va_start
#define va_start(v, l)
Definition: rb_mjit_min_header-2.7.0.h:3978
LONG2FIX
#define LONG2FIX(i)
Definition: ruby.h:265
RBASIC_SET_CLASS_RAW
#define RBASIC_SET_CLASS_RAW(obj, cls)
Definition: internal.h:1982
rb_enc_codelen
int rb_enc_codelen(int c, rb_encoding *enc)
Definition: encoding.c:1089
T_STRING
#define T_STRING
Definition: ruby.h:528
GETPOSARG
#define GETPOSARG(n)
Definition: sprintf.c:97
FILL_
#define FILL_(c, l)
Definition: sprintf.c:85
ruby_vsnprintf
int ruby_vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
Definition: sprintf.c:1004
rb_sym2str
VALUE rb_sym2str(VALUE)
Definition: symbol.c:784
CHECKNAMEARG
#define CHECKNAMEARG(name, len, enc)
Definition: sprintf.c:104
va_list
__gnuc_va_list va_list
Definition: rb_mjit_min_header-2.7.0.h:836
FIXABLE
#define FIXABLE(f)
Definition: ruby.h:399
RB_INTEGER_TYPE_P
#define RB_INTEGER_TYPE_P(obj)
Definition: ruby_missing.h:15
FWIDTH
#define FWIDTH
Definition: sprintf.c:54
ECONV_INVALID_REPLACE
#define ECONV_INVALID_REPLACE
Definition: encoding.h:394
__siov::iov_len
size_t iov_len
Definition: vsnprintf.c:228
NUM2INT
#define NUM2INT(x)
Definition: ruby.h:715
Qnil
#define Qnil
Definition: ruby.h:469
rb_key_err_raise
#define rb_key_err_raise(mesg, recv, name)
Definition: internal.h:1578
rb_enc_isprint
#define rb_enc_isprint(c, enc)
Definition: encoding.h:236
rb_int_plus
VALUE rb_int_plus(VALUE x, VALUE y)
Definition: numeric.c:3610
RB_GC_GUARD
#define RB_GC_GUARD(v)
Definition: ruby.h:585
GETNUM
#define GETNUM(n, val)
Definition: sprintf.c:108
rb_str_coderange_scan_restartable
long rb_str_coderange_scan_restartable(const char *, const char *, rb_encoding *, int *)
Definition: string.c:567
RSTRING_LEN
#define RSTRING_LEN(str)
Definition: ruby.h:1005
rb_enc_codepoint_len
unsigned int rb_enc_codepoint_len(const char *p, const char *e, int *len_p, rb_encoding *enc)
Definition: encoding.c:1068
FPREC
#define FPREC
Definition: sprintf.c:55
BIT_DIGITS
#define BIT_DIGITS(N)
Definition: sprintf.c:25
rb_enc_associate
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
Definition: encoding.c:866
ENC_CODERANGE_UNKNOWN
#define ENC_CODERANGE_UNKNOWN
Definition: encoding.h:103
RTEST
#define RTEST(v)
Definition: ruby.h:481
CHECK_FOR_FLAGS
#define CHECK_FOR_FLAGS(f)
rb_absint_singlebit_p
int rb_absint_singlebit_p(VALUE val)
Definition: bignum.c:3446
RSTRING_END
#define RSTRING_END(str)
Definition: ruby.h:1013
__siov
Definition: vsnprintf.c:226
name
const char * name
Definition: nkf.c:208
get_num
#define get_num(num)
Definition: ripper.c:589