24 #define BIT_DIGITS(N) (((N)*146)/485 + 1)
25 #define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT)
26 #define EXTENDSIGN(n, l) (((~0 << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0 << (n)))
28 static void fmt_setup(
char*,
size_t,
int,
int,
int,
int);
62 if (*p ==
'X') c =
'F';
83 #define CHECK(l) do {\
84 int cr = ENC_CODERANGE(result);\
85 while (blen + (l) >= bsiz) {\
88 rb_str_resize(result, bsiz);\
89 ENC_CODERANGE_SET(result, cr);\
90 buf = RSTRING_PTR(result);\
93 #define PUSH(s, l) do { \
95 memcpy(&buf[blen], (s), (l));\
99 #define FILL(c, l) do { \
101 memset(&buf[blen], (c), (l));\
105 #define GETARG() (nextvalue != Qundef ? nextvalue : \
107 (rb_raise(rb_eArgError, "unnumbered(%d) mixed with numbered", nextarg), 0) : \
109 (rb_raise(rb_eArgError, "unnumbered(%d) mixed with named", nextarg), 0) : \
110 (posarg = nextarg++, GETNTHARG(posarg)))
112 #define GETPOSARG(n) (posarg > 0 ? \
113 (rb_raise(rb_eArgError, "numbered(%d) after unnumbered(%d)", (n), posarg), 0) : \
115 (rb_raise(rb_eArgError, "numbered(%d) after named", (n)), 0) : \
116 (((n) < 1) ? (rb_raise(rb_eArgError, "invalid index - %d$", (n)), 0) : \
117 (posarg = -1, GETNTHARG(n))))
119 #define GETNTHARG(nth) \
120 (((nth) >= argc) ? (rb_raise(rb_eArgError, "too few arguments"), 0) : argv[(nth)])
122 #define GETNAMEARG(id, name, len) ( \
124 (rb_raise(rb_eArgError, "named%.*s after unnumbered(%d)", (len), (name), posarg), 0) : \
126 (rb_raise(rb_eArgError, "named%.*s after numbered", (len), (name)), 0) : \
127 (posarg = -2, rb_hash_lookup2(get_hash(&hash, argc, argv), (id), Qundef)))
129 #define GETNUM(n, val) \
130 for (; p < end && rb_enc_isdigit(*p, enc); p++) { \
131 int next_n = 10 * (n) + (*p - '0'); \
132 if (next_n / 10 != (n)) {\
133 rb_raise(rb_eArgError, #val " too big"); \
138 rb_raise(rb_eArgError, "malformed format string - %%*[0-9]"); \
141 #define GETASTER(val) do { \
146 tmp = GETPOSARG(n); \
152 (val) = NUM2INT(tmp); \
168 return (*hash = tmp);
449 int width, prec, flags =
FNONE;
458 #define CHECK_FOR_WIDTH(f) \
459 if ((f) & FWIDTH) { \
460 rb_raise(rb_eArgError, "width given twice"); \
462 if ((f) & FPREC0) { \
463 rb_raise(rb_eArgError, "width after precision"); \
465 #define CHECK_FOR_FLAGS(f) \
466 if ((f) & FWIDTH) { \
467 rb_raise(rb_eArgError, "flag after width"); \
469 if ((f) & FPREC0) { \
470 rb_raise(rb_eArgError, "flag after precision"); \
486 memset(buf, 0, bsiz);
489 for (; p < end; p++) {
494 for (t = p; t < end && *t !=
'%'; t++) ;
547 case '1':
case '2':
case '3':
case '4':
548 case '5':
case '6':
case '7':
case '8':
case '9':
552 if (nextvalue !=
Qundef) {
567 const char *start =
p;
568 char term = (*p ==
'<') ?
'>' :
'}';
570 for (; p < end && *p != term; ) {
580 id =
rb_intern3(start + 1, p - start - 1, enc);
582 if (nextvalue ==
Qundef) {
585 if (term ==
'}')
goto format_s;
625 if (flags !=
FNONE) {
658 else if ((flags &
FMINUS)) {
698 if ((flags&
FPREC) && (prec < slen)) {
705 if ((flags&
FWIDTH) && (width > slen)) {
743 char fbuf[32], nbuf[64], *s;
744 const char *prefix = 0;
745 int sign = 0, dots = 0;
748 int base, bignum = 0;
769 prefix =
"0x";
break;
771 prefix =
"0X";
break;
773 prefix =
"0b";
break;
775 prefix =
"0B";
break;
827 if (c ==
'i') c =
'd';
833 else if (flags &
FPLUS) {
837 else if (flags &
FSPACE) {
841 snprintf(fbuf,
sizeof(fbuf),
"%%l%c", c);
842 snprintf(nbuf,
sizeof(nbuf), fbuf, v);
850 snprintf(fbuf,
sizeof(fbuf),
"%%l%c", *p ==
'X' ?
'x' : *p);
851 snprintf(++s,
sizeof(nbuf) - 1, fbuf, v);
878 else if (flags &
FPLUS) {
882 else if (flags &
FSPACE) {
897 rb_warning(
"negative number for %%u specifier");
902 if (s[0] !=
'f') *--s =
'f';
break;
904 if (s[0] !=
'7') *--s =
'7';
break;
906 if (s[0] !=
'1') *--s =
'1';
break;
921 while ((c = (
int)(
unsigned char)*pp) != 0) {
926 if (prefix && !prefix[1]) {
930 else if (len == 1 && *s ==
'0') {
932 if (flags &
FPREC) prec--;
934 else if ((flags &
FPREC) && (prec > len)) {
938 else if (len == 1 && *s ==
'0') {
942 width -= (int)
strlen(prefix);
950 if (!prefix && prec == 0 && len == 1 && *s ==
'0') len = 0;
957 while (width-- > 0) {
961 if (sc)
PUSH(&sc, 1);
963 int plen = (int)
strlen(prefix);
967 if (dots)
PUSH(
"..", 2);
968 if (!bignum && v < 0) {
970 while (len < prec--) {
974 else if ((flags & (FMINUS|
FPREC)) != FMINUS) {
981 while (len < prec--) {
988 while (width-- > 0) {
1017 need = (int)
strlen(expr);
1018 if ((!
isnan(fval) && fval < 0.0) || (flags &
FPLUS))
1020 if ((flags &
FWIDTH) && need < width)
1024 snprintf(&buf[blen], need + 1,
"%*s", need,
"");
1026 if (!
isnan(fval) && fval < 0.0)
1028 else if (flags &
FPLUS)
1032 memcpy(&buf[blen], expr,
strlen(expr));
1035 if (!
isnan(fval) && fval < 0.0)
1036 buf[blen + need -
strlen(expr) - 1] =
'-';
1037 else if (flags &
FPLUS)
1038 buf[blen + need -
strlen(expr) - 1] =
'+';
1039 else if ((flags &
FSPACE) && need > width)
1041 memcpy(&buf[blen + need -
strlen(expr)], expr,
1044 blen +=
strlen(&buf[blen]);
1048 fmt_setup(fbuf,
sizeof(fbuf), *p, flags, width, prec);
1050 if (*p !=
'e' && *p !=
'E') {
1056 need += (flags&
FPREC) ? prec : 6;
1057 if ((flags&
FWIDTH) && need < width)
1062 snprintf(&buf[blen], need, fbuf, fval);
1063 blen +=
strlen(&buf[blen]);
1074 if (posarg >= 0 && nextarg < argc) {
1075 const char *mesg =
"too many arguments for format string";
1088 char *end = buf +
size;
1090 if (flags &
FSHARP) *buf++ =
'#';
1091 if (flags &
FPLUS) *buf++ =
'+';
1092 if (flags &
FMINUS) *buf++ =
'-';
1093 if (flags &
FZERO) *buf++ =
'0';
1094 if (flags &
FSPACE) *buf++ =
' ';
1097 snprintf(buf, end - buf,
"%d", width);
1101 if (flags &
FPREC) {
1102 snprintf(buf, end - buf,
".%d", prec);
1111 #define FILE rb_printf_buffer
1112 #define __sbuf rb_printf_sbuf
1113 #define __sFILE rb_printf_sfile
1118 #if SIZEOF_LONG < SIZEOF_VOIDP
1119 # if SIZEOF_LONG_LONG == SIZEOF_VOIDP
1120 # define _HAVE_SANE_QUAD_
1121 # define _HAVE_LLP64_
1122 # define quad_t LONG_LONG
1123 # define u_quad_t unsigned LONG_LONG
1125 #elif SIZEOF_LONG != SIZEOF_LONG_LONG && SIZEOF_LONG_LONG == 8
1126 # define _HAVE_SANE_QUAD_
1127 # define quad_t LONG_LONG
1128 # define u_quad_t unsigned LONG_LONG
1130 #define FLOATING_POINT 1
1131 #define BSD__dtoa ruby_dtoa
1132 #define BSD__hdtoa ruby_hdtoa
1140 char *
buf = (
char*)fp->_p;
1144 if (
RBASIC(result)->klass) {
1152 for (iov = uio->
uio_iov; len > 0; ++iov) {
1157 fp->_p = (
unsigned char *)
buf;
1172 f._bf._base = (
unsigned char *)result;
1174 RBASIC(result)->klass = 0;
1189 va_start(ap, format);
1208 va_start(ap, format);
1226 f._bf._base = (
unsigned char *)str;
1228 klass =
RBASIC(str)->klass;
1232 RBASIC(str)->klass = klass;
1243 va_start(ap, format);
RUBY_EXTERN VALUE rb_cString
#define RSTRING_LEN(string)
VALUE rb_big_clone(VALUE x)
int rb_enc_codelen(int c, rb_encoding *enc)
static VALUE get_hash(volatile VALUE *hash, int argc, const VALUE *argv)
static char * remove_sign_bits(char *str, int base)
rb_encoding * rb_enc_check(VALUE str1, VALUE str2)
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 *)
static int ruby__sfvwrite(register rb_printf_buffer *fp, register struct __suio *uio)
#define RFLOAT_VALUE(val)
#define ENC_CODERANGE_SET(obj, cr)
#define RSTRING_PTR(string)
unsigned int rb_enc_codepoint_len(const char *p, const char *e, int *len_p, rb_encoding *enc)
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
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)
#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)
static char sign_bits(int base, const char *p)
VALUE rb_dbl2big(double d)
VALUE rb_str_to_inum(VALUE str, int base, int badcheck)
VALUE rb_obj_as_string(VALUE)
VALUE rb_vsprintf(const char *fmt, va_list ap)
#define ENC_CODERANGE_UNKNOWN
#define GETNAMEARG(id, name, len)
#define rb_enc_isprint(c, enc)
#define MEMCPY(p1, p2, type, n)
RUBY_EXTERN int isinf(double)
#define ENC_CODERANGE_BROKEN
#define CHECK_FOR_WIDTH(f)
VALUE rb_big2str(VALUE x, int base)
VALUE rb_str_resize(VALUE, long)
size_t rb_str_capacity(VALUE)
VALUE rb_sprintf(const char *format,...)
VALUE rb_f_sprintf(int argc, const VALUE *argv)
#define RB_GC_GUARD(object)
unsigned char buf[MIME_BUF_SIZE]
static void fmt_setup(char *, size_t, int, int, int, int)
register unsigned int len
void rb_str_modify(VALUE)
rb_encoding * rb_enc_get(VALUE obj)
long rb_enc_strlen(const char *, const char *, rb_encoding *)
VALUE rb_check_convert_type(VALUE, int, const char *, const char *)
static ssize_t BSD_vfprintf(FILE *fp, const char *fmt0, va_list ap)
VALUE rb_str_vcatf(VALUE str, const char *fmt, va_list ap)
VALUE rb_str_catf(VALUE str, const char *format,...)
VALUE rb_check_string_type(VALUE)
#define rb_str_set_len(str, length)
VALUE rb_big2str0(VALUE x, int base, int trim)
VALUE rb_int2big(SIGNED_VALUE n)
static unsigned int hash(const char *str, unsigned int len)
#define CHECK_FOR_FLAGS(f)
const char * rb_id2name(ID id)
static char fbuf[MAXPATHLEN]
void rb_warning(const char *fmt,...)
void rb_big_2comp(VALUE x)
ID rb_intern3(const char *name, long len, rb_encoding *enc)
expr expr keyword_or expr
#define rb_enc_mbcput(c, buf, enc)
VALUE rb_str_buf_new(long)
void rb_warn(const char *fmt,...)