implement mrb_format and mrb_vformat

This commit is contained in:
Yukihiro Matz Matsumoto
2013-03-27 23:03:48 +09:00
parent 8f8c22ac67
commit 8ce842a5d9
2 changed files with 50 additions and 0 deletions
+1
View File
@@ -54,6 +54,7 @@ mrb_value mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr);
mrb_value mrb_ary_entry(mrb_value ary, mrb_int offset);
mrb_value mrb_ary_shift(mrb_state *mrb, mrb_value self);
mrb_value mrb_ary_clear(mrb_state *mrb, mrb_value self);
mrb_value mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep);
#if defined(__cplusplus)
} /* extern "C" { */
+49
View File
@@ -13,6 +13,7 @@
#include "error.h"
#include "mruby/variable.h"
#include "mruby/string.h"
#include "mruby/array.h"
#include "mruby/class.h"
#include "mruby/proc.h"
#include "mruby/irep.h"
@@ -228,6 +229,54 @@ mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg)
mrb_exc_raise(mrb, mrb_exc_new3(mrb, c, mesg));
}
mrb_value
mrb_vformat(mrb_state *mrb, const char *format, va_list ap)
{
const char *p = format;
const char *b = p;
ptrdiff_t size;
mrb_value ary = mrb_ary_new_capa(mrb, 4);
while (*p) {
const char c = *p++;
if (c == '%') {
if (*p == 'S') {
size = p - b - 1;
mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size));
mrb_ary_push(mrb, ary, va_arg(ap, mrb_value));
b = p + 1;
}
}
else if (c == '\\') {
if (!*p) break;
p++;
}
p++;
}
if (b == format) {
return mrb_str_new_cstr(mrb, format);
}
else {
size = p - b;
mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size));
return mrb_ary_join(mrb, ary, mrb_str_new(mrb,NULL,0));
}
}
mrb_value
mrb_format(mrb_state *mrb, const char *format, ...)
{
va_list ap;
mrb_value str;
va_start(ap, format);
str = mrb_vformat(mrb, format, ap);
va_end(ap);
return str;
}
void
mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...)
{