Ruby  2.7.1p83(2020-03-31revisiona0c7c23c9cec0d0ffcba012279cd652d28ad5bf3)
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
199 {
200  return rb_str_format(argc - 1, argv + 1, GETNTHARG(0));
201 }
202 
203 VALUE
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;
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);
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 {
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)) {
492  if (slen < 0) {
493  rb_raise(rb_eArgError, "invalid mbstring sequence");
494  }
495  if ((flags&FPREC) && (prec < slen)) {
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),
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:
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;
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,
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);
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;
1225  f.vwrite = ruby__sfvwrite;
1226  f.vextra = ruby__sfvextra;
1227  buffer.value = 0;
1228  BSD_vfprintf(&f, fmt, ap);
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
i
uint32_t i
Definition: rb_mjit_min_header-2.7.1.h:5464
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
long
#define long
Definition: rb_mjit_min_header-2.7.1.h:2880
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
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.1.h:13259
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
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:1986
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:263
n
const char size_t n
Definition: rb_mjit_min_header-2.7.1.h:5456
__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:1985
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
fmt
const VALUE int int int int int int VALUE char * fmt
Definition: rb_mjit_min_header-2.7.1.h:6462
TYPE
#define TYPE(x)
Definition: ruby.h:554
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
rb_rational_den
VALUE rb_rational_den(VALUE rat)
Definition: rational.c:1966
id.h
SIGNED_VALUE
#define SIGNED_VALUE
Definition: ruby.h:104
isinf
#define isinf(__x)
Definition: rb_mjit_min_header-2.7.1.h:3673
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
rb_enc_isdigit
#define rb_enc_isdigit(c, enc)
Definition: encoding.h:238
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.1.h:5601
rb_hash_lookup2
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
Definition: hash.c:2045
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_new
#define rb_str_new(str, len)
Definition: rb_mjit_min_header-2.7.1.h:6116
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
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
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
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
rb_cNilClass
RUBY_EXTERN VALUE rb_cNilClass
Definition: ruby.h:2036
va_start
#define va_start(v, l)
Definition: rb_mjit_min_header-2.7.1.h:3978
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
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
FPLUS
#define FPLUS
Definition: sprintf.c:51
va_list
__gnuc_va_list va_list
Definition: rb_mjit_min_header-2.7.1.h:836
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
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
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:1847
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4322
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
StringValue
use StringValue() instead")))
internal.h
__suio::uio_resid
size_t uio_resid
Definition: vsnprintf.c:233
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
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
ssize_t
_ssize_t ssize_t
Definition: rb_mjit_min_header-2.7.1.h:1329
__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
SIZEOF_LONG
#define SIZEOF_LONG
Definition: rb_mjit_min_header-2.7.1.h:85
memset
void * memset(void *, int, size_t)
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
int
__inline__ int
Definition: rb_mjit_min_header-2.7.1.h:2839
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
memcpy
void * memcpy(void *__restrict, const void *__restrict, size_t)
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
v
int VALUE v
Definition: rb_mjit_min_header-2.7.1.h:12337
RBASIC
#define RBASIC(obj)
Definition: ruby.h:1267
SIZEOF_INT
#define SIZEOF_INT
Definition: rb_mjit_min_header-2.7.1.h:83
rb_str_catf
VALUE rb_str_catf(VALUE str, const char *format,...)
Definition: sprintf.c:1237
QUOTE
#define QUOTE(str)
Definition: internal.h:2147
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
LONG2FIX
#define LONG2FIX(i)
Definition: ruby.h:265
RBASIC_SET_CLASS_RAW
#define RBASIC_SET_CLASS_RAW(obj, cls)
Definition: internal.h:1987
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
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:1580
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
INT_MAX
#define INT_MAX
Definition: rb_mjit_min_header-2.7.1.h:4052
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
va_end
#define va_end(v)
Definition: rb_mjit_min_header-2.7.1.h:3979
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