25#define BIT_DIGITS(N) (((N)*146)/485 + 1)
27static char *fmt_setup(
char*,
size_t,
int,
int,
int,
int);
28static char *ruby_ultoa(
unsigned long val,
char *endp,
int base,
int octzero);
31sign_bits(
int base,
const char *p)
37 if (*p ==
'X') c =
'F';
59 int cr = ENC_CODERANGE(result);\
60 while ((l) >= bsiz - blen) {\
62 if (bsiz<0) rb_raise(rb_eArgError, "too big specifier");\
64 rb_str_resize(result, bsiz);\
65 ENC_CODERANGE_SET(result, cr);\
66 buf = RSTRING_PTR(result);\
69#define PUSH(s, l) do { \
74#define PUSH_(s, l) do { \
75 memcpy(&buf[blen], (s), (l));\
79#define FILL(c, l) do { \
85#define FILL_(c, l) do { \
86 memset(&buf[blen], (c), (l));\
90#define GETARG() (nextvalue != Qundef ? nextvalue : \
93#define GETNEXTARG() ( \
94 check_next_arg(posarg, nextarg), \
95 (posarg = nextarg++, GETNTHARG(posarg)))
97#define GETPOSARG(n) ( \
98 check_pos_arg(posarg, (n)), \
99 (posarg = -1, GETNTHARG(n)))
101#define GETNTHARG(nth) \
102 (((nth) >= argc) ? (rb_raise(rb_eArgError, "too few arguments"), 0) : argv[(nth)])
104#define CHECKNAMEARG(name, len, enc) ( \
105 check_name_arg(posarg, name, len, enc), \
108#define GETNUM(n, val) \
109 (!(p = get_num(p, end, enc, &(n))) ? \
110 rb_raise(rb_eArgError, #val " too big") : (void)0)
112#define GETASTER(val) do { \
117 tmp = GETPOSARG(n); \
120 tmp = GETNEXTARG(); \
123 (val) = NUM2INT(tmp); \
134 if (
INT_MAX - (*p -
'0') < next_n)
146check_next_arg(
int posarg,
int nextarg)
157check_pos_arg(
int posarg,
int n)
186 if (*hash !=
Qundef)
return *hash;
194 return (*hash = tmp);
206 enum {default_float_precision = 6};
215 int width, prec, flags =
FNONE;
224#define CHECK_FOR_WIDTH(f) \
225 if ((f) & FWIDTH) { \
226 rb_raise(rb_eArgError, "width given twice"); \
228 if ((f) & FPREC0) { \
229 rb_raise(rb_eArgError, "width after precision"); \
231#define CHECK_FOR_FLAGS(f) \
232 if ((f) & FWIDTH) { \
233 rb_raise(rb_eArgError, "flag after width"); \
235 if ((f) & FPREC0) { \
236 rb_raise(rb_eArgError, "flag after precision"); \
255 for (; p < end; p++) {
260 for (t = p; t < end && *t !=
'%'; t++) ;
316 case '1':
case '2':
case '3':
case '4':
317 case '5':
case '6':
case '7':
case '8':
case '9':
321 if (nextvalue !=
Qundef) {
336 const char *start = p;
337 char term = (*p ==
'<') ?
'>' :
'}';
340 for (; p < end && *p !=
term; ) {
346#if SIZEOF_INT < SIZEOF_SIZE_T
347 if ((
size_t)(p - start) >=
INT_MAX) {
348 const int message_limit = 20;
351 "too long name (%"PRIuSIZE" bytes) - %.*s...%c",
352 (
size_t)(p - start - 2),
len, start,
term);
355 len = (
int)(p - start + 1);
366 if (nextvalue ==
Qundef) {
373 if (
NIL_P(nextvalue)) {
377 if (
term ==
'}')
goto format_s;
419 if (flags !=
FNONE) {
452 else if ((flags &
FMINUS)) {
456 if (width > 1)
FILL(
' ', width-1);
459 if (width > 1)
FILL(
' ', width-1);
495 if ((flags&
FPREC) && (prec < slen)) {
502 if ((flags&
FWIDTH) && (width > slen)) {
537 const char *prefix = 0;
538 int sign = 0, dots = 0;
541 int base, bignum = 0;
562 prefix =
"0x";
break;
564 prefix =
"0X";
break;
566 prefix =
"0b";
break;
568 prefix =
"0B";
break;
614 int numbits =
ffs(base)-1;
633 else if (flags &
FPLUS) {
637 else if (flags &
FSPACE) {
652 if (numdigits == 0 ||
653 ((abs_nlz_bits != (
size_t)(numbits-1) ||
675 else if (flags &
FPLUS) {
679 else if (flags &
FSPACE) {
683 s = ruby_ultoa((
unsigned long)
v, nbuf +
sizeof(nbuf), 10, 0);
684 len = (
int)(nbuf +
sizeof(nbuf) - s);
696 else if (flags &
FPLUS) {
700 else if (flags &
FSPACE) {
715 while ((c = (
int)(
unsigned char)*pp) != 0) {
720 if (prefix && !prefix[1]) {
724 else if (
len == 1 && *s ==
'0') {
726 if (flags &
FPREC) prec--;
728 else if ((flags &
FPREC) && (prec >
len)) {
732 else if (
len == 1 && *s ==
'0') {
744 if (!prefix && prec == 0 &&
len == 1 && *s ==
'0')
len = 0;
753 if (sc)
PUSH(&sc, 1);
758 if (dots)
PUSH(
"..", 2);
761 if (!sign && valsign < 0) {
762 char c = sign_bits(base, p);
778 int sign = (flags&
FPLUS) ? 1 : 0, zero = 0;
792 if (!(flags&
FPREC)) prec = default_float_precision;
809 else if (prec >= 0) {
814 if (prec >=
len)
len = prec + 1;
817 fill = width >
len ? width -
len : 0;
822 if (sign || (flags&
FSPACE)) {
823 buf[blen++] = sign > 0 ?
'+' : sign < 0 ?
'-' :
' ';
842 else if (prec >
len) {
849 if (fill && (flags&
FMINUS)) {
882 if (!
isnan(fval) && fval < 0.0)
885 sign = (flags &
FPLUS) ?
'+' :
' ';
888 if ((flags &
FWIDTH) && need < width)
894 buf[blen - need--] = sign;
899 buf[blen - elen - 1] = sign;
907 char *
fmt = fmt_setup(fbuf,
sizeof(fbuf), *p, flags, width, prec);
924 if (posarg >= 0 && nextarg <
argc) {
925 const char *mesg =
"too many arguments for format string";
935fmt_setup(
char *
buf,
size_t size,
int c,
int flags,
int width,
int prec)
942 buf = ruby_ultoa(prec,
buf, 10, 0);
947 buf = ruby_ultoa(width,
buf, 10, 0);
960#define FILE rb_printf_buffer
961#define __sbuf rb_printf_sbuf
962#define __sFILE rb_printf_sfile
967#if SIZEOF_LONG < SIZEOF_VOIDP
968# if SIZEOF_LONG_LONG == SIZEOF_VOIDP
969# define _HAVE_SANE_QUAD_
971# define quad_t LONG_LONG
972# define u_quad_t unsigned LONG_LONG
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
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
985#define lower_hexdigits (ruby_hexdigits+0)
986#define upper_hexdigits (ruby_hexdigits+16)
987#if defined RUBY_USE_SETJMPEX && RUBY_USE_SETJMPEX
989# define MAYBE_UNUSED(x) x = 0
994ruby_ultoa(
unsigned long val,
char *endp,
int base,
int flags)
997 int octzero = flags &
FSHARP;
998 return BSD__ultoa(val, endp, base, octzero, xdigs);
1001static int ruby_do_vsnprintf(
char *
str,
size_t n,
const char *
fmt,
va_list ap);
1008 return ruby_do_vsnprintf(
str,
n,
fmt, ap);
1012ruby_do_vsnprintf(
char *
str,
size_t n,
const char *
fmt,
va_list ap)
1018 f._bf._base =
f._p = (
unsigned char *)
str;
1019 f._bf._size =
f._w =
str ? (
n - 1) : 0;
1020 f.vwrite = BSD__sfvwrite;
1022 ret = BSD_vfprintf(&
f,
fmt, ap);
1024#if SIZEOF_SIZE_T > SIZEOF_INT
1040 ret = ruby_do_vsnprintf(
str,
n,
fmt, ap);
1051ruby__sfvwrite(
register rb_printf_buffer *fp,
register struct __suio *uio)
1055 char *
buf = (
char*)fp->_p;
1064#if SIZE_MAX > LONG_MAX
1077 fp->_p = (
unsigned char *)
buf;
1083ruby__sfvextra(rb_printf_buffer *fp,
size_t valsize,
void *valp,
long *sz,
int sign)
1089 if (valsize !=
sizeof(
VALUE))
return 0;
1090 value = *(
VALUE *)valp;
1091 if (
RBASIC(result)->klass) {
1096# define LITERAL(str) (*sz = rb_strlen_lit(str), str)
1125 if (sign ==
' ') value =
QUOTE(value);
1136 *(
volatile VALUE *)valp = value;
1148#define f buffer.base
1163 f._bf._base = (
unsigned char *)result;
1166 f.vwrite = ruby__sfvwrite;
1167 f.vextra = ruby__sfvextra;
1169 BSD_vfprintf(&
f,
fmt, ap);
1213#define f buffer.base
1221 f._bf._base = (
unsigned char *)
str;
1225 f.vwrite = ruby__sfvwrite;
1226 f.vextra = ruby__sfvextra;
1228 BSD_vfprintf(&
f,
fmt, ap);
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
unsigned int rb_enc_codepoint_len(const char *p, const char *e, int *len_p, rb_encoding *enc)
rb_encoding * rb_enc_get(VALUE obj)
void rb_enc_copy(VALUE obj1, VALUE obj2)
rb_encoding * rb_enc_check(VALUE str1, VALUE str2)
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc)
rb_encoding * rb_enc_compatible(VALUE str1, VALUE str2)
int rb_enc_toupper(int c, rb_encoding *enc)
int rb_enc_codelen(int c, rb_encoding *enc)
#define ENC_CODERANGE_7BIT
#define rb_enc_mbcput(c, buf, enc)
#define ECONV_UNDEF_REPLACE
#define ENC_CODERANGE(obj)
#define ENC_CODERANGE_UNKNOWN
VALUE rb_str_conv_enc_opts(VALUE str, rb_encoding *from, rb_encoding *to, int ecflags, VALUE ecopts)
#define ECONV_INVALID_REPLACE
#define rb_enc_isdigit(c, enc)
#define rb_enc_isprint(c, enc)
#define rb_enc_mbminlen(enc)
VALUE rb_check_symbol_cstr(const char *ptr, long len, rb_encoding *enc)
long rb_enc_strlen(const char *, const char *, rb_encoding *)
#define ENC_CODERANGE_BROKEN
long rb_str_coderange_scan_restartable(const char *, const char *, rb_encoding *, int *)
#define rb_enc_right_char_head(s, p, e, enc)
#define ENC_CODERANGE_SET(obj, cr)
char * rb_enc_nth(const char *, const char *, long, rb_encoding *)
char str[HTML_ESCAPE_MAX_LEN+1]
VALUE rb_cTrueClass
TrueClass class.
VALUE rb_cNilClass
NilClass class.
int ruby_vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
VALUE rb_cFalseClass
FalseClass class.
void rb_raise(VALUE exc, const char *fmt,...)
void rb_warn(const char *fmt,...)
void rb_enc_raise(rb_encoding *enc, VALUE exc, const char *fmt,...)
VALUE rb_Float(VALUE)
Equivalent to Kernel#Float in Ruby.
VALUE rb_Integer(VALUE)
Equivalent to Kernel#Integer in Ruby.
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
VALUE rb_str_catf(VALUE str, const char *format,...)
VALUE rb_sprintf(const char *format,...)
VALUE rb_str_format(int argc, const VALUE *argv, VALUE fmt)
VALUE rb_enc_vsprintf(rb_encoding *enc, const char *fmt, va_list ap)
VALUE rb_f_sprintf(int argc, const VALUE *argv)
VALUE rb_enc_sprintf(rb_encoding *enc, const char *format,...)
#define CHECK_FOR_FLAGS(f)
VALUE rb_str_vcatf(VALUE str, const char *fmt, va_list ap)
VALUE rb_vsprintf(const char *fmt, va_list ap)
#define CHECK_FOR_WIDTH(f)
#define CHECKNAMEARG(name, len, enc)
int ruby_snprintf(char *str, size_t n, char const *fmt,...)
size_t rb_str_capacity(VALUE str)
VALUE rb_sym_intern(const char *ptr, long len, rb_encoding *enc)