mruby-sprintf: improve code readability with comments and organization

Add clear section headers and explanatory comments to the format
handlers in mrb_str_format to improve code maintainability and
readability.

Changes:
- Add format type headers (CHARACTER, STRING, INTEGER, FLOAT)
- Add subsection comments explaining key logic steps
- Improve code organization within each format handler
- Better indentation and logical grouping

This makes the 450-line function much easier to navigate and understand
while maintaining identical functionality (all 1723 tests pass).

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-08-15 10:30:19 +09:00
parent 0c99d9f20c
commit e149553db2
+93 -78
View File
@@ -510,52 +510,55 @@ retry:
break;
case FMT_CHAR: {
mrb_value val = GETARG();
mrb_value tmp;
char *c;
/* CHARACTER FORMATTING (%c) */
mrb_value val = GETARG();
mrb_value tmp;
char *c;
tmp = mrb_check_string_type(mrb, val);
if (!mrb_nil_p(tmp)) {
if (RSTRING_LEN(tmp) != 1) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "%c requires a character");
/* Convert argument to character string */
tmp = mrb_check_string_type(mrb, val);
if (!mrb_nil_p(tmp)) {
if (RSTRING_LEN(tmp) != 1) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "%c requires a character");
}
}
}
else if (mrb_integer_p(val)) {
mrb_int n = mrb_integer(val);
else if (mrb_integer_p(val)) {
mrb_int n = mrb_integer(val);
#ifndef MRB_UTF8_STRING
char buf[1];
buf[0] = (char)n&0xff;
tmp = mrb_str_new(mrb, buf, 1);
#else
if (n < 0x80) {
char buf[1];
buf[0] = (char)n;
buf[0] = (char)n&0xff;
tmp = mrb_str_new(mrb, buf, 1);
#else
if (n < 0x80) {
char buf[1];
buf[0] = (char)n;
tmp = mrb_str_new(mrb, buf, 1);
}
else {
tmp = mrb_funcall_argv(mrb, val, MRB_SYM(chr), 0, NULL);
mrb_check_type(mrb, tmp, MRB_TT_STRING);
}
#endif
}
else {
tmp = mrb_funcall_argv(mrb, val, MRB_SYM(chr), 0, NULL);
mrb_check_type(mrb, tmp, MRB_TT_STRING);
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid character");
}
/* Format and output the character with width/alignment */
c = RSTRING_PTR(tmp);
n = (int)RSTRING_LEN(tmp);
if (!(flags & FWIDTH)) {
PUSH(c, n);
}
else if ((flags & FMINUS)) {
PUSH(c, n);
if (width>0) FILL(' ', width-1);
}
else {
if (width>0) FILL(' ', width-1);
PUSH(c, n);
}
#endif
}
else {
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid character");
}
c = RSTRING_PTR(tmp);
n = (int)RSTRING_LEN(tmp);
if (!(flags & FWIDTH)) {
PUSH(c, n);
}
else if ((flags & FMINUS)) {
PUSH(c, n);
if (width>0) FILL(' ', width-1);
}
else {
if (width>0) FILL(' ', width-1);
PUSH(c, n);
}
mrb_gc_arena_restore(mrb, ai);
}
break;
@@ -563,65 +566,74 @@ retry:
case FMT_STRING:
format_s:
{
/* STRING FORMATTING (%s, %p) */
mrb_value arg = GETARG();
mrb_int len;
mrb_int slen;
mrb_int len;
mrb_int slen;
/* Convert to string (with inspect for %p) */
if (spec.subtype == 1) arg = mrb_inspect(mrb, arg); /* 'p' format */
str = mrb_obj_as_string(mrb, arg);
len = RSTRING_LEN(str);
if (RSTRING(result)->flags & MRB_STR_EMBED) {
mrb_int tmp_n = len;
RSTRING(result)->flags &= ~MRB_STR_EMBED_LEN_MASK;
RSTRING(result)->flags |= tmp_n << MRB_STR_EMBED_LEN_SHIFT;
}
else {
RSTRING(result)->as.heap.len = blen;
}
if (flags&(FPREC|FWIDTH)) {
slen = RSTRING_LEN(str);
if (slen < 0) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid mbstring sequence");
str = mrb_obj_as_string(mrb, arg);
len = RSTRING_LEN(str);
/* Update result string length for embedded strings */
if (RSTRING(result)->flags & MRB_STR_EMBED) {
mrb_int tmp_n = len;
RSTRING(result)->flags &= ~MRB_STR_EMBED_LEN_MASK;
RSTRING(result)->flags |= tmp_n << MRB_STR_EMBED_LEN_SHIFT;
}
if ((flags&FPREC) && (prec < slen)) {
char *p = RSTRING_PTR(str) + prec;
slen = prec;
len = (mrb_int)(p - RSTRING_PTR(str));
else {
RSTRING(result)->as.heap.len = blen;
}
/* need to adjust multi-byte string pos */
if ((flags&FWIDTH) && (width > slen)) {
width -= (int)slen;
if (!(flags&FMINUS)) {
FILL(' ', width);
/* Handle precision and width formatting */
if (flags&(FPREC|FWIDTH)) {
slen = RSTRING_LEN(str);
if (slen < 0) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid mbstring sequence");
}
PUSH(RSTRING_PTR(str), len);
if (flags&FMINUS) {
FILL(' ', width);
if ((flags&FPREC) && (prec < slen)) {
char *p = RSTRING_PTR(str) + prec;
slen = prec;
len = (mrb_int)(p - RSTRING_PTR(str));
}
/* Apply width formatting with padding */
if ((flags&FWIDTH) && (width > slen)) {
width -= (int)slen;
if (!(flags&FMINUS)) {
FILL(' ', width);
}
PUSH(RSTRING_PTR(str), len);
if (flags&FMINUS) {
FILL(' ', width);
}
break;
}
break;
}
}
PUSH(RSTRING_PTR(str), len);
mrb_gc_arena_restore(mrb, ai);
}
break;
case FMT_INTEGER: {
mrb_value val = GETARG();
char nbuf[69], *s;
const char *prefix = NULL;
int sign = 0, dots = 0;
char sc = 0;
char fc = 0;
mrb_int v = 0;
int base;
int len;
/* INTEGER FORMATTING (%d, %i, %o, %x, %X, %b, %B, %u) */
mrb_value val = GETARG();
char nbuf[69], *s;
const char *prefix = NULL;
int sign = 0, dots = 0;
char sc = 0;
char fc = 0;
mrb_int v = 0;
int base;
int len;
/* Determine base and signedness from lookup table */
base = spec.base;
if (spec.subtype == 1) { /* signed formats: d, i, u */
sign = 1;
}
/* Set prefix for alternative format (#) */
if (flags & FSHARP) {
switch (base) {
case 8: prefix = "0"; break;
@@ -631,8 +643,9 @@ retry:
}
}
/* Convert value to integer and format as string */
bin_retry:
switch (mrb_type(val)) {
switch (mrb_type(val)) {
#ifndef MRB_NO_FLOAT
case MRB_TT_FLOAT:
val = mrb_float_to_integer(mrb, val);
@@ -718,6 +731,7 @@ retry:
s++; len--;
}
}
/* Convert to uppercase for X, B formats */
if (spec.subtype == 1) { /* uppercase formats: X, B */
char *pp = s;
int c;
@@ -805,10 +819,11 @@ retry:
break;
case FMT_FLOAT: {
/* FLOAT FORMATTING (%f, %g, %G, %e, %E) */
#ifdef MRB_NO_FLOAT
mrb_raisef(mrb, E_ARGUMENT_ERROR, "%%%c not supported with MRB_NO_FLOAT defined", spec.subtype);
#else
mrb_value val = GETARG();
mrb_value val = GETARG();
double fval;
mrb_int need = 6;