publish format function family
This commit is contained in:
parent
2ffd1a8e00
commit
3a8aa3e728
|
@ -166,6 +166,9 @@ char *pic_strdup(pic_state *, const char *);
|
|||
char *pic_strndup(pic_state *, const char *, size_t);
|
||||
struct pic_string *pic_str_new(pic_state *, const char *, size_t); /* the 2nd arg may be NULL for empty string */
|
||||
struct pic_string *pic_str_new_cstr(pic_state *, const char *);
|
||||
pic_value pic_format(pic_state *, const char *, ...);
|
||||
pic_value pic_vformat(pic_state *, const char *, va_list);
|
||||
pic_value pic_vfformat(pic_state *, XFILE *, const char *, va_list);
|
||||
|
||||
struct pic_vector *pic_vec_new(pic_state *, size_t);
|
||||
struct pic_vector *pic_vec_new_from_list(pic_state *, pic_value);
|
||||
|
|
82
src/error.c
82
src/error.c
|
@ -8,8 +8,6 @@
|
|||
|
||||
#include "picrin.h"
|
||||
#include "picrin/pair.h"
|
||||
#include "picrin/proc.h"
|
||||
#include "picrin/port.h"
|
||||
#include "picrin/error.h"
|
||||
|
||||
const char *
|
||||
|
@ -20,86 +18,6 @@ pic_errmsg(pic_state *pic)
|
|||
return pic->err->msg->str;
|
||||
}
|
||||
|
||||
static pic_value
|
||||
pic_vfformat(pic_state *pic, XFILE *file, const char *fmt, va_list ap)
|
||||
{
|
||||
char c;
|
||||
pic_value irrs = pic_nil_value();
|
||||
|
||||
while ((c = *fmt++)) {
|
||||
switch (c) {
|
||||
default:
|
||||
xfputc(c, file);
|
||||
break;
|
||||
case '%':
|
||||
c = *fmt++;
|
||||
if (! c)
|
||||
goto exit;
|
||||
switch (c) {
|
||||
default:
|
||||
xfputc(c, file);
|
||||
break;
|
||||
case '%':
|
||||
xfputc('%', file);
|
||||
break;
|
||||
case 'c':
|
||||
xfprintf(file, "%c", va_arg(ap, int));
|
||||
break;
|
||||
case 's':
|
||||
xfprintf(file, "%s", va_arg(ap, const char *));
|
||||
break;
|
||||
case 'd':
|
||||
xfprintf(file, "%d", va_arg(ap, int));
|
||||
break;
|
||||
case 'p':
|
||||
xfprintf(file, "%p", va_arg(ap, void *));
|
||||
break;
|
||||
case 'f':
|
||||
xfprintf(file, "%f", va_arg(ap, double));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '~':
|
||||
c = *fmt++;
|
||||
if (! c)
|
||||
goto exit;
|
||||
switch (c) {
|
||||
default:
|
||||
xfputc(c, file);
|
||||
break;
|
||||
case '~':
|
||||
xfputc('~', file);
|
||||
break;
|
||||
case '%':
|
||||
xfputc('\n', file);
|
||||
break;
|
||||
case 'S':
|
||||
irrs = pic_cons(pic, pic_fdebug(pic, va_arg(ap, pic_value), file), irrs);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
exit:
|
||||
|
||||
return pic_reverse(pic, irrs);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
pic_vformat(pic_state *pic, const char *fmt, va_list ap)
|
||||
{
|
||||
struct pic_port *port;
|
||||
pic_value irrs;
|
||||
|
||||
port = pic_open_output_string(pic);
|
||||
|
||||
irrs = pic_vfformat(pic, port->file, fmt, ap);
|
||||
irrs = pic_cons(pic, pic_obj_value(pic_get_output_string(pic, port)), irrs);
|
||||
|
||||
pic_close_port(pic, port);
|
||||
return irrs;
|
||||
}
|
||||
|
||||
NORETURN static void
|
||||
error(pic_state *pic, struct pic_string *msg, pic_value irrs)
|
||||
{
|
||||
|
|
95
src/string.c
95
src/string.c
|
@ -5,6 +5,8 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "picrin.h"
|
||||
#include "picrin/pair.h"
|
||||
#include "picrin/port.h"
|
||||
|
||||
struct pic_string *
|
||||
pic_str_new(pic_state *pic, const char *cstr, size_t len)
|
||||
|
@ -24,6 +26,99 @@ pic_str_new(pic_state *pic, const char *cstr, size_t len)
|
|||
return str;
|
||||
}
|
||||
|
||||
pic_value
|
||||
pic_vfformat(pic_state *pic, XFILE *file, const char *fmt, va_list ap)
|
||||
{
|
||||
char c;
|
||||
pic_value irrs = pic_nil_value();
|
||||
|
||||
while ((c = *fmt++)) {
|
||||
switch (c) {
|
||||
default:
|
||||
xfputc(c, file);
|
||||
break;
|
||||
case '%':
|
||||
c = *fmt++;
|
||||
if (! c)
|
||||
goto exit;
|
||||
switch (c) {
|
||||
default:
|
||||
xfputc(c, file);
|
||||
break;
|
||||
case '%':
|
||||
xfputc('%', file);
|
||||
break;
|
||||
case 'c':
|
||||
xfprintf(file, "%c", va_arg(ap, int));
|
||||
break;
|
||||
case 's':
|
||||
xfprintf(file, "%s", va_arg(ap, const char *));
|
||||
break;
|
||||
case 'd':
|
||||
xfprintf(file, "%d", va_arg(ap, int));
|
||||
break;
|
||||
case 'p':
|
||||
xfprintf(file, "%p", va_arg(ap, void *));
|
||||
break;
|
||||
case 'f':
|
||||
xfprintf(file, "%f", va_arg(ap, double));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '~':
|
||||
c = *fmt++;
|
||||
if (! c)
|
||||
goto exit;
|
||||
switch (c) {
|
||||
default:
|
||||
xfputc(c, file);
|
||||
break;
|
||||
case '~':
|
||||
xfputc('~', file);
|
||||
break;
|
||||
case '%':
|
||||
xfputc('\n', file);
|
||||
break;
|
||||
case 'S':
|
||||
irrs = pic_cons(pic, pic_fdebug(pic, va_arg(ap, pic_value), file), irrs);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
exit:
|
||||
|
||||
return pic_reverse(pic, irrs);
|
||||
}
|
||||
|
||||
pic_value
|
||||
pic_vformat(pic_state *pic, const char *fmt, va_list ap)
|
||||
{
|
||||
struct pic_port *port;
|
||||
pic_value irrs;
|
||||
|
||||
port = pic_open_output_string(pic);
|
||||
|
||||
irrs = pic_vfformat(pic, port->file, fmt, ap);
|
||||
irrs = pic_cons(pic, pic_obj_value(pic_get_output_string(pic, port)), irrs);
|
||||
|
||||
pic_close_port(pic, port);
|
||||
return irrs;
|
||||
}
|
||||
|
||||
pic_value
|
||||
pic_format(pic_state *pic, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
pic_value objs;
|
||||
|
||||
va_start(ap, fmt);
|
||||
objs = pic_vformat(pic, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return objs;
|
||||
}
|
||||
|
||||
struct pic_string *
|
||||
pic_str_new_cstr(pic_state *pic, const char *cstr)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue