24 #define BIT_DIGITS(N) (((N)*146)/485 + 1) 26 static char *fmt_setup(
char*,
size_t,
int,
int,
int,
int);
27 static char *ruby_ultoa(
unsigned long val,
char *endp,
int base,
int octzero);
30 sign_bits(
int base,
const char *p)
36 if (*p ==
'X') c =
'F';
57 #define CHECK(l) do {\ 58 int cr = ENC_CODERANGE(result);\ 59 while ((l) >= bsiz - blen) {\ 61 if (bsiz<0) rb_raise(rb_eArgError, "too big specifier");\ 63 rb_str_resize(result, bsiz);\ 64 ENC_CODERANGE_SET(result, cr);\ 65 buf = RSTRING_PTR(result);\ 68 #define PUSH(s, l) do { \ 73 #define PUSH_(s, l) do { \ 74 memcpy(&buf[blen], (s), (l));\ 78 #define FILL(c, l) do { \ 84 #define FILL_(c, l) do { \ 85 memset(&buf[blen], (c), (l));\ 89 #define GETARG() (nextvalue != Qundef ? nextvalue : \ 92 #define GETNEXTARG() ( \ 93 check_next_arg(posarg, nextarg), \ 94 (posarg = nextarg++, GETNTHARG(posarg))) 96 #define GETPOSARG(n) ( \ 97 check_pos_arg(posarg, (n)), \ 98 (posarg = -1, GETNTHARG(n))) 100 #define GETNTHARG(nth) \ 101 (((nth) >= argc) ? (rb_raise(rb_eArgError, "too few arguments"), 0) : argv[(nth)]) 103 #define CHECKNAMEARG(name, len, enc) ( \ 104 check_name_arg(posarg, name, len, enc), \ 107 #define GETNUM(n, val) \ 108 (!(p = get_num(p, end, enc, &(n))) ? \ 109 rb_raise(rb_eArgError, #val " too big") : (void)0) 111 #define GETASTER(val) do { \ 116 tmp = GETPOSARG(n); \ 119 tmp = GETNEXTARG(); \ 122 (val) = NUM2INT(tmp); \ 126 get_num(
const char *p,
const char *end,
rb_encoding *enc,
int *valp)
133 if (INT_MAX - (*p -
'0') < next_n)
145 check_next_arg(
int posarg,
int nextarg)
156 check_pos_arg(
int posarg,
int n)
185 if (*hash !=
Qundef)
return *hash;
193 return (*hash = tmp);
466 enum {default_float_precision = 6};
475 int width, prec, flags =
FNONE;
485 #define CHECK_FOR_WIDTH(f) \ 486 if ((f) & FWIDTH) { \ 487 rb_raise(rb_eArgError, "width given twice"); \ 489 if ((f) & FPREC0) { \ 490 rb_raise(rb_eArgError, "width after precision"); \ 492 #define CHECK_FOR_FLAGS(f) \ 493 if ((f) & FWIDTH) { \ 494 rb_raise(rb_eArgError, "flag after width"); \ 496 if ((f) & FPREC0) { \ 497 rb_raise(rb_eArgError, "flag after precision"); \ 514 memset(buf, 0, bsiz);
517 for (; p < end; p++) {
522 for (t = p; t < end && *t !=
'%'; t++) ;
578 case '1':
case '2':
case '3':
case '4':
579 case '5':
case '6':
case '7':
case '8':
case '9':
583 if (nextvalue !=
Qundef) {
598 const char *start = p;
599 char term = (*p ==
'<') ?
'>' :
'}';
602 for (; p < end && *p !=
term; ) {
608 #if SIZEOF_INT < SIZEOF_SIZE_T 609 if ((
size_t)(p - start) >= INT_MAX) {
610 const int message_limit = 20;
613 "too long name (%"PRIuSIZE" bytes) - %.*s...%c",
614 (
size_t)(p - start - 2), len, start, term);
617 len = (int)(p - start + 1);
623 get_hash(&hash, argc, argv);
628 if (nextvalue ==
Qundef) {
635 if (
NIL_P(nextvalue)) {
639 if (term ==
'}')
goto format_s;
680 if (flags !=
FNONE) {
713 else if ((flags &
FMINUS)) {
717 if (width > 1)
FILL(
' ', width-1);
720 if (width > 1)
FILL(
' ', width-1);
757 if ((flags&
FPREC) && (prec < slen)) {
764 if ((flags&
FWIDTH) && (width > slen)) {
799 const char *prefix = 0;
800 int sign = 0, dots = 0;
803 int base, bignum = 0;
824 prefix =
"0x";
break;
826 prefix =
"0X";
break;
828 prefix =
"0b";
break;
830 prefix =
"0B";
break;
876 int numbits =
ffs(base)-1;
880 if (INT_MAX-1 < numdigits)
895 else if (flags &
FPLUS) {
899 else if (flags &
FSPACE) {
914 if (numdigits == 0 ||
915 ((abs_nlz_bits != (
size_t)(numbits-1) ||
937 else if (flags &
FPLUS) {
941 else if (flags &
FSPACE) {
945 s = ruby_ultoa((
unsigned long)v, nbuf +
sizeof(nbuf), 10, 0);
946 len = (int)(nbuf +
sizeof(nbuf) - s);
958 else if (flags &
FPLUS) {
962 else if (flags &
FSPACE) {
977 while ((c = (
int)(
unsigned char)*pp) != 0) {
982 if (prefix && !prefix[1]) {
986 else if (len == 1 && *s ==
'0') {
988 if (flags &
FPREC) prec--;
990 else if ((flags &
FPREC) && (prec > len)) {
994 else if (len == 1 && *s ==
'0') {
998 width -= (int)
strlen(prefix);
1006 if (!prefix && prec == 0 && len == 1 && *s ==
'0') len = 0;
1015 if (sc)
PUSH(&sc, 1);
1017 int plen = (int)
strlen(prefix);
1020 if (dots)
PUSH(
"..", 2);
1023 if (!sign && valsign < 0) {
1024 char c = sign_bits(base, p);
1025 FILL_(c, prec - len);
1027 else if ((flags & (FMINUS|
FPREC)) != FMINUS) {
1028 FILL_(
'0', prec - len);
1040 int sign = (flags&
FPLUS) ? 1 : 0, zero = 0;
1054 if (!(flags&
FPREC)) prec = default_float_precision;
1071 else if (prec >= 0) {
1076 if (prec >= len) len = prec + 1;
1078 if (prec > 0) ++
len;
1079 fill = width > len ? width -
len : 0;
1084 if (sign || (flags&FSPACE)) {
1085 buf[blen++] = sign > 0 ?
'+' : sign < 0 ?
'-' :
' ';
1093 PUSH_(t, len - prec);
1104 else if (prec > len) {
1105 FILL_(
'0', prec - len);
1108 else if (prec > 0) {
1109 PUSH_(t + len - prec, prec);
1111 if (fill && (flags&
FMINUS)) {
1142 need = (int)
strlen(expr);
1144 if (!
isnan(fval) && fval < 0.0)
1147 sign = (flags &
FPLUS) ?
'+' :
' ';
1150 if ((flags &
FWIDTH) && need < width)
1156 buf[blen - need--] = sign;
1157 memcpy(&buf[blen - need], expr, elen);
1161 buf[blen - elen - 1] = sign;
1162 memcpy(&buf[blen - elen], expr, elen);
1169 char *fmt = fmt_setup(fbuf,
sizeof(fbuf), *p, flags, width, prec);
1186 if (posarg >= 0 && nextarg < argc) {
1187 const char *mesg =
"too many arguments for format string";
1198 fmt_setup(
char *
buf,
size_t size,
int c,
int flags,
int width,
int prec)
1204 if (flags &
FPREC) {
1205 buf = ruby_ultoa(prec, buf, 10, 0);
1210 buf = ruby_ultoa(width, buf, 10, 0);
1213 if (flags &
FSPACE) *--buf =
' ';
1214 if (flags &
FZERO) *--buf =
'0';
1215 if (flags &
FMINUS) *--buf =
'-';
1216 if (flags &
FPLUS) *--buf =
'+';
1217 if (flags &
FSHARP) *--buf =
'#';
1223 #define FILE rb_printf_buffer 1224 #define __sbuf rb_printf_sbuf 1225 #define __sFILE rb_printf_sfile 1230 #if SIZEOF_LONG < SIZEOF_VOIDP 1231 # if SIZEOF_LONG_LONG == SIZEOF_VOIDP 1232 # define _HAVE_SANE_QUAD_ 1233 # define _HAVE_LLP64_ 1234 # define quad_t LONG_LONG 1235 # define u_quad_t unsigned LONG_LONG 1237 #elif SIZEOF_LONG != SIZEOF_LONG_LONG && SIZEOF_LONG_LONG == 8 1238 # define _HAVE_SANE_QUAD_ 1239 # define quad_t LONG_LONG 1240 # define u_quad_t unsigned LONG_LONG 1242 #define FLOATING_POINT 1 1243 #define BSD__dtoa ruby_dtoa 1244 #define BSD__hdtoa ruby_hdtoa 1245 #ifdef RUBY_PRI_VALUE_MARK 1246 # define PRI_EXTRA_MARK RUBY_PRI_VALUE_MARK 1248 #define lower_hexdigits (ruby_hexdigits+0) 1249 #define upper_hexdigits (ruby_hexdigits+16) 1250 #if defined RUBY_USE_SETJMPEX && RUBY_USE_SETJMPEX 1251 # undef MAYBE_UNUSED 1252 # define MAYBE_UNUSED(x) x = 0 1257 ruby_ultoa(
unsigned long val,
char *endp,
int base,
int flags)
1260 int octzero = flags &
FSHARP;
1261 return BSD__ultoa(val, endp, base, octzero, xdigs);
1264 static int ruby_do_vsnprintf(
char *str,
size_t n,
const char *fmt, va_list ap);
1269 if (str && (ssize_t)n < 1)
1271 return ruby_do_vsnprintf(str, n, fmt, ap);
1275 ruby_do_vsnprintf(
char *str,
size_t n,
const char *fmt, va_list ap)
1281 f._bf._base = f._p = (
unsigned char *)str;
1282 f._bf._size = f._w = str ? (n - 1) : 0;
1283 f.vwrite = BSD__sfvwrite;
1285 ret = (int)BSD_vfprintf(&f, fmt, ap);
1296 if (str && (ssize_t)n < 1)
1300 ret = ruby_do_vsnprintf(str, n, fmt, ap);
1311 ruby__sfvwrite(
register rb_printf_buffer *fp,
register struct __suio *uio)
1315 char *buf = (
char*)fp->_p;
1317 long blen = buf -
RSTRING_PTR(result), bsiz = fp->_w;
1319 if (
RBASIC(result)->klass) {
1324 #if SIZE_MAX > LONG_MAX 1332 for (iov = uio->
uio_iov; len > 0; ++iov) {
1337 fp->_p = (
unsigned char *)buf;
1343 ruby__sfvextra(rb_printf_buffer *fp,
size_t valsize,
void *valp,
long *sz,
int sign)
1349 if (valsize !=
sizeof(
VALUE))
return 0;
1350 value = *(
VALUE *)valp;
1351 if (
RBASIC(result)->klass) {
1356 # define LITERAL(str) (*sz = rb_strlen_lit(str), str) 1379 if (sign ==
' ') value =
QUOTE(value);
1390 *(
volatile VALUE *)valp = value;
1403 #define f buffer.base 1418 f._bf._base = (
unsigned char *)result;
1421 f.vwrite = ruby__sfvwrite;
1422 f.vextra = ruby__sfvextra;
1424 BSD_vfprintf(&
f, fmt, ap);
1438 va_start(ap, format);
1457 va_start(ap, format);
1468 #define f buffer.base 1476 f._bf._base = (
unsigned char *)str;
1478 klass =
RBASIC(str)->klass;
1480 f.vwrite = ruby__sfvwrite;
1481 f.vextra = ruby__sfvextra;
1483 BSD_vfprintf(&
f, fmt, ap);
1496 va_start(ap, format);
RUBY_EXTERN VALUE rb_cString
int ruby_snprintf(char *str, size_t n, char const *fmt,...)
VALUE rb_int_plus(VALUE x, VALUE y)
#define RBASIC_CLEAR_CLASS(obj)
int rb_enc_codelen(int c, rb_encoding *enc)
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
void rb_warn(const char *fmt,...)
rb_encoding * rb_enc_check(VALUE str1, VALUE str2)
RUBY_EXTERN VALUE rb_cFalseClass
void rb_enc_copy(VALUE obj1, VALUE obj2)
long rb_str_coderange_scan_restartable(const char *, const char *, rb_encoding *, int *)
size_t strlen(const char *)
VALUE rb_sym_intern(const char *ptr, long len, rb_encoding *enc)
void rb_str_tmp_frozen_release(VALUE str, VALUE tmp)
void rb_raise(VALUE exc, const char *fmt,...)
const char ruby_digitmap[]
#define ENC_CODERANGE_SET(obj, cr)
if(len<=MAX_WORD_LENGTH &&len >=MIN_WORD_LENGTH)
rb_encoding * rb_enc_compatible(VALUE str1, VALUE str2)
void rb_str_set_len(VALUE, long)
VALUE rb_int_mul(VALUE x, VALUE y)
unsigned int rb_enc_codepoint_len(const char *p, const char *e, int *len_p, rb_encoding *enc)
#define RSTRING_GETMEM(str, ptrvar, lenvar)
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
VALUE rb_Integer(VALUE)
Equivalent to Kernel#Integer in Ruby.
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc)
VALUE rb_enc_vsprintf(rb_encoding *enc, const char *fmt, va_list ap)
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
VALUE rb_str_conv_enc_opts(VALUE str, rb_encoding *from, rb_encoding *to, int ecflags, VALUE ecopts)
#define INTEGER_PACK_2COMP
#define ENC_CODERANGE_7BIT
VALUE rb_enc_sprintf(rb_encoding *enc, const char *format,...)
VALUE rb_str_format(int argc, const VALUE *argv, VALUE fmt)
char * rb_enc_nth(const char *, const char *, long, rb_encoding *)
int rb_enc_toupper(int c, rb_encoding *enc)
VALUE rb_hash_default_value(VALUE hash, VALUE key)
int rb_absint_singlebit_p(VALUE val)
#define RBASIC_SET_CLASS_RAW(obj, cls)
#define RB_TYPE_P(obj, type)
VALUE rb_int_idiv(VALUE x, VALUE y)
VALUE rb_dbl2big(double d)
VALUE rb_str_to_inum(VALUE str, int base, int badcheck)
#define ECONV_INVALID_REPLACE
VALUE rb_obj_as_string(VALUE)
#define rb_key_err_raise(mesg, recv, name)
RUBY_EXTERN VALUE rb_cTrueClass
VALUE rb_int2str(VALUE num, int base)
VALUE rb_vsprintf(const char *fmt, va_list ap)
#define BIGNUM_NEGATIVE_P(b)
#define ENC_CODERANGE_UNKNOWN
#define rb_enc_isprint(c, enc)
#define MEMCPY(p1, p2, type, n)
RUBY_EXTERN int isinf(double)
#define ENC_CODERANGE_BROKEN
VALUE rb_check_symbol_cstr(const char *ptr, long len, rb_encoding *enc)
#define rb_enc_mbminlen(enc)
#define CHECK_FOR_WIDTH(f)
VALUE rb_big2str(VALUE x, int base)
RUBY_EXTERN VALUE rb_int_positive_pow(long x, unsigned long y)
VALUE rb_str_resize(VALUE, long)
VALUE rb_sprintf(const char *format,...)
VALUE rb_f_sprintf(int argc, const VALUE *argv)
VALUE rb_check_hash_type(VALUE hash)
unsigned char buf[MIME_BUF_SIZE]
#define rb_enc_isdigit(c, enc)
RUBY_EXTERN VALUE rb_cInteger
VALUE rb_rational_den(VALUE rat)
#define INTEGER_PACK_BIG_ENDIAN
register unsigned int len
#define StringValueCStr(v)
#define rb_enc_right_char_head(s, p, e, enc)
#define ECONV_UNDEF_REPLACE
void rb_str_modify(VALUE)
rb_encoding * rb_enc_get(VALUE obj)
VALUE rb_big_uminus(VALUE x)
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
long rb_enc_strlen(const char *, const char *, rb_encoding *)
VALUE rb_rational_num(VALUE rat)
VALUE rb_Float(VALUE)
Equivalent to Kernel#Float in Ruby.
VALUE rb_str_vcatf(VALUE str, const char *fmt, va_list ap)
VALUE rb_str_catf(VALUE str, const char *format,...)
#define ENC_CODERANGE(obj)
VALUE rb_check_string_type(VALUE)
size_t rb_str_capacity(VALUE str)
void rb_enc_raise(rb_encoding *enc, VALUE exc, const char *fmt,...)
size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret)
#define CHECKNAMEARG(name, len, enc)
#define CHECK_FOR_FLAGS(f)
VALUE rb_str_tmp_frozen_acquire(VALUE str)
int ruby_vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
RUBY_EXTERN VALUE rb_cSymbol
#define rb_enc_mbcput(c, buf, enc)
VALUE rb_str_buf_new(long)
#define MUL_OVERFLOW_INT_P(a, b)
#define RB_INTEGER_TYPE_P(obj)
RUBY_EXTERN VALUE rb_cNilClass
VALUE rb_str_new(const char *, long)