move pic_printf family to port.c
This commit is contained in:
parent
8592802afc
commit
01c817799b
2
Makefile
2
Makefile
|
@ -37,7 +37,6 @@ PICRIN_OBJS = \
|
||||||
CONTRIB_SRCS =
|
CONTRIB_SRCS =
|
||||||
CONTRIB_OBJS = $(CONTRIB_SRCS:.c=.o)
|
CONTRIB_OBJS = $(CONTRIB_SRCS:.c=.o)
|
||||||
CONTRIB_LIBS =
|
CONTRIB_LIBS =
|
||||||
CONTRIB_DEFS =
|
|
||||||
CONTRIB_INITS =
|
CONTRIB_INITS =
|
||||||
CONTRIB_TESTS =
|
CONTRIB_TESTS =
|
||||||
CONTRIB_DOCS = $(wildcard contrib/*/docs/*.rst)
|
CONTRIB_DOCS = $(wildcard contrib/*/docs/*.rst)
|
||||||
|
@ -63,7 +62,6 @@ tiny-picrin: $(LIBPICRIN_OBJS) src/tiny-main.o
|
||||||
|
|
||||||
include $(sort $(wildcard contrib/*/nitro.mk))
|
include $(sort $(wildcard contrib/*/nitro.mk))
|
||||||
|
|
||||||
picrin: CFLAGS += $(CONTRIB_DEFS)
|
|
||||||
picrin: $(PICRIN_OBJS) $(CONTRIB_OBJS) $(LIBPICRIN_OBJS)
|
picrin: $(PICRIN_OBJS) $(CONTRIB_OBJS) $(LIBPICRIN_OBJS)
|
||||||
$(CC) $(CFLAGS) -o $@ $(PICRIN_OBJS) $(CONTRIB_OBJS) $(LIBPICRIN_OBJS) $(LDFLAGS)
|
$(CC) $(CFLAGS) -o $@ $(PICRIN_OBJS) $(CONTRIB_OBJS) $(LIBPICRIN_OBJS) $(LDFLAGS)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
#include "picrin.h"
|
||||||
|
|
||||||
|
#include "emyg_dtoa.h"
|
||||||
|
#include "emyg_atod.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
int2str(long x, int base, char *buf)
|
||||||
|
{
|
||||||
|
static const char digits[36] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||||
|
int i, neg, len;
|
||||||
|
|
||||||
|
neg = 0;
|
||||||
|
if (x < 0) {
|
||||||
|
neg = 1;
|
||||||
|
x = -x;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
do {
|
||||||
|
buf[i++] = digits[x % base];
|
||||||
|
} while ((x /= base) != 0);
|
||||||
|
|
||||||
|
if (neg) {
|
||||||
|
buf[i++] = '-';
|
||||||
|
}
|
||||||
|
buf[i] = '\0';
|
||||||
|
len = i;
|
||||||
|
|
||||||
|
for (i = 0; i < len / 2; ++i) {
|
||||||
|
char tmp = buf[i];
|
||||||
|
buf[i] = buf[len - i - 1];
|
||||||
|
buf[len - i - 1] = tmp;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static pic_value
|
||||||
|
emyg_number_to_string(pic_state *pic)
|
||||||
|
{
|
||||||
|
double f;
|
||||||
|
bool e;
|
||||||
|
int radix = 10;
|
||||||
|
|
||||||
|
pic_get_args(pic, "F|i", &f, &e, &radix);
|
||||||
|
|
||||||
|
if (radix < 2 || radix > 36) {
|
||||||
|
pic_error(pic, "invalid radix (between 2 and 36, inclusive)", 1, pic_int_value(pic, radix));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e) {
|
||||||
|
char buf[sizeof(int) * CHAR_BIT + 3];
|
||||||
|
int len = int2str((int) f, radix, buf);
|
||||||
|
return pic_str_value(pic, buf, len);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
char buf[64];
|
||||||
|
emyg_dtoa(f, buf);
|
||||||
|
return pic_cstr_value(pic, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
strcaseeq(const char *s1, const char *s2)
|
||||||
|
{
|
||||||
|
char a, b;
|
||||||
|
|
||||||
|
while ((a = *s1++) * (b = *s2++)) {
|
||||||
|
if (tolower(a) != tolower(b))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return a == b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static pic_value
|
||||||
|
string_to_number(pic_state *pic, const char *str)
|
||||||
|
{
|
||||||
|
double flt;
|
||||||
|
const char *c = str;
|
||||||
|
bool isint = 1;
|
||||||
|
|
||||||
|
if (*c == '+' || *c == '-')
|
||||||
|
c++;
|
||||||
|
|
||||||
|
if (! isdigit(*c++)) {
|
||||||
|
return pic_false_value(pic);
|
||||||
|
}
|
||||||
|
while (isdigit(*c)) c++;
|
||||||
|
|
||||||
|
if (*c == '.') {
|
||||||
|
isint = false;
|
||||||
|
c++;
|
||||||
|
while (isdigit(*c)) c++;
|
||||||
|
}
|
||||||
|
if (*c == 'e' || *c == 'E') {
|
||||||
|
isint = false;
|
||||||
|
c++;
|
||||||
|
if (*c == '+' || *c == '-')
|
||||||
|
c++;
|
||||||
|
if (! isdigit(*c++)) {
|
||||||
|
return pic_false_value(pic);
|
||||||
|
}
|
||||||
|
while (isdigit(*c)) c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*c != '\0') {
|
||||||
|
return pic_false_value(pic);
|
||||||
|
}
|
||||||
|
|
||||||
|
flt = emyg_atod(str);
|
||||||
|
|
||||||
|
if (isint && INT_MIN <= flt && flt <= INT_MAX) {
|
||||||
|
return pic_int_value(pic, flt);
|
||||||
|
} else {
|
||||||
|
return pic_float_value(pic, flt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static pic_value
|
||||||
|
emyg_string_to_number(pic_state *pic)
|
||||||
|
{
|
||||||
|
const char *str;
|
||||||
|
int radix = 10;
|
||||||
|
long num;
|
||||||
|
char *eptr;
|
||||||
|
|
||||||
|
pic_get_args(pic, "z|i", &str, &radix);
|
||||||
|
|
||||||
|
if (strcaseeq(str, "+inf.0"))
|
||||||
|
return pic_float_value(pic, 1.0 / 0.0);
|
||||||
|
if (strcaseeq(str, "-inf.0"))
|
||||||
|
return pic_float_value(pic, -1.0 / 0.0);
|
||||||
|
if (strcaseeq(str, "+nan.0"))
|
||||||
|
return pic_float_value(pic, 0.0 / 0.0);
|
||||||
|
if (strcaseeq(str, "-nan.0"))
|
||||||
|
return pic_float_value(pic, -0.0 / 0.0);
|
||||||
|
|
||||||
|
num = strtol(str, &eptr, radix);
|
||||||
|
if (*eptr == '\0') {
|
||||||
|
return INT_MIN <= num && num <= INT_MAX ? pic_int_value(pic, num) : pic_float_value(pic, num);
|
||||||
|
}
|
||||||
|
|
||||||
|
return string_to_number(pic, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pic_nitro_init_roundtrip(pic_state *PIC_UNUSED(pic))
|
||||||
|
{
|
||||||
|
pic_set(pic, "number->string", pic_lambda(pic, emyg_number_to_string, 0));
|
||||||
|
pic_set(pic, "string->number", pic_lambda(pic, emyg_string_to_number, 0));
|
||||||
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
CONTRIB_DEFS += -DPIC_CSTRING_TO_DOUBLE=emyg_atod -DPIC_DOUBLE_TO_CSTRING=emyg_dtoa
|
CONTRIB_INITS += roundtrip
|
||||||
|
|
||||||
CONTRIB_SRCS += contrib/10.roundtrip/emyg_dtoa.c \
|
CONTRIB_SRCS += contrib/10.roundtrip/emyg_dtoa.c \
|
||||||
contrib/10.roundtrip/emyg_atod.c
|
contrib/10.roundtrip/emyg_atod.c \
|
||||||
|
contrib/10.roundtrip/emyg.c
|
||||||
|
|
||||||
CONTRIB_TESTS += test-roundtrip
|
CONTRIB_TESTS += test-roundtrip
|
||||||
|
|
||||||
|
|
131
lib/ext/write.c
131
lib/ext/write.c
|
@ -6,6 +6,8 @@
|
||||||
#include "picrin/extra.h"
|
#include "picrin/extra.h"
|
||||||
#include "../object.h"
|
#include "../object.h"
|
||||||
|
|
||||||
|
#if PIC_USE_WRITE
|
||||||
|
|
||||||
struct writer_control {
|
struct writer_control {
|
||||||
int mode;
|
int mode;
|
||||||
int op;
|
int op;
|
||||||
|
@ -21,135 +23,6 @@ struct writer_control {
|
||||||
#define OP_WRITE_SHARED 2
|
#define OP_WRITE_SHARED 2
|
||||||
#define OP_WRITE_SIMPLE 3
|
#define OP_WRITE_SIMPLE 3
|
||||||
|
|
||||||
#if PIC_USE_WRITE
|
|
||||||
static void write_value(pic_state *pic, pic_value obj, pic_value port, int mode, int op);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_int(pic_state *pic, pic_value port, long x, int base)
|
|
||||||
{
|
|
||||||
static const char digits[] = "0123456789abcdef";
|
|
||||||
char buf[20];
|
|
||||||
int i, neg;
|
|
||||||
|
|
||||||
neg = 0;
|
|
||||||
if (x < 0) {
|
|
||||||
neg = 1;
|
|
||||||
x = -x;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
do {
|
|
||||||
buf[i++] = digits[x % base];
|
|
||||||
} while ((x /= base) != 0);
|
|
||||||
|
|
||||||
if (neg) {
|
|
||||||
buf[i++] = '-';
|
|
||||||
}
|
|
||||||
|
|
||||||
while (i-- > 0) {
|
|
||||||
pic_fputc(pic, buf[i], port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
pic_vfprintf(pic_state *pic, pic_value port, const char *fmt, va_list ap)
|
|
||||||
{
|
|
||||||
const char *p;
|
|
||||||
char *sval;
|
|
||||||
int ival;
|
|
||||||
void *vp;
|
|
||||||
long start = pic_fseek(pic, port, 0, PIC_SEEK_CUR);
|
|
||||||
|
|
||||||
for (p = fmt; *p; p++) {
|
|
||||||
|
|
||||||
#if PIC_USE_WRITE
|
|
||||||
if (*p == '~') {
|
|
||||||
switch (*++p) {
|
|
||||||
default:
|
|
||||||
pic_fputc(pic, *(p-1), port);
|
|
||||||
break;
|
|
||||||
case '%':
|
|
||||||
pic_fputc(pic, '\n', port);
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
write_value(pic, va_arg(ap, pic_value), port, DISPLAY_MODE, OP_WRITE);
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
write_value(pic, va_arg(ap, pic_value), port, WRITE_MODE, OP_WRITE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (*p != '%') {
|
|
||||||
pic_fputc(pic, *p, port);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch (*++p) {
|
|
||||||
case 'd':
|
|
||||||
case 'i':
|
|
||||||
ival = va_arg(ap, int);
|
|
||||||
print_int(pic, port, ival, 10);
|
|
||||||
break;
|
|
||||||
case 'f': {
|
|
||||||
char buf[64];
|
|
||||||
PIC_DOUBLE_TO_CSTRING(va_arg(ap, double), buf);
|
|
||||||
pic_fputs(pic, buf, port);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'c':
|
|
||||||
ival = va_arg(ap, int);
|
|
||||||
pic_fputc(pic, ival, port);
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
sval = va_arg(ap, char*);
|
|
||||||
pic_fputs(pic, sval, port);
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
vp = va_arg(ap, void*);
|
|
||||||
pic_fputs(pic, "0x", port);
|
|
||||||
print_int(pic, port, (long)vp, 16);
|
|
||||||
break;
|
|
||||||
case '%':
|
|
||||||
pic_fputc(pic, *(p-1), port);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
pic_fputc(pic, '%', port);
|
|
||||||
pic_fputc(pic, *(p-1), port);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pic_fseek(pic, port, 0, PIC_SEEK_CUR) - start;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
pic_fprintf(pic_state *pic, pic_value port, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
n = pic_vfprintf(pic, port, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
pic_printf(pic_state *pic, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
n = pic_vfprintf(pic, pic_stdout(pic), fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if PIC_USE_WRITE
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
writer_control_init(pic_state *pic, struct writer_control *p, int mode, int op)
|
writer_control_init(pic_state *pic, struct writer_control *p, int mode, int op)
|
||||||
{
|
{
|
||||||
|
|
|
@ -409,6 +409,12 @@ atof(const char *nptr)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
PIC_STATIC_INLINE double
|
||||||
|
pic_atod(const char *str)
|
||||||
|
{
|
||||||
|
return atof(str);
|
||||||
|
}
|
||||||
|
|
||||||
#if PIC_USE_STDIO
|
#if PIC_USE_STDIO
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
|
|
||||||
|
@ -469,16 +475,6 @@ pic_dtoa(double dval, char *buf)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PIC_DOUBLE_TO_CSTRING
|
|
||||||
#define PIC_DOUBLE_TO_CSTRING pic_dtoa
|
|
||||||
#endif
|
|
||||||
void PIC_DOUBLE_TO_CSTRING(double, char *);
|
|
||||||
|
|
||||||
#ifndef PIC_CSTRING_TO_DOUBLE
|
|
||||||
#define PIC_CSTRING_TO_DOUBLE atof
|
|
||||||
#endif
|
|
||||||
double PIC_CSTRING_TO_DOUBLE(const char *);
|
|
||||||
|
|
||||||
/* optional features available? */
|
/* optional features available? */
|
||||||
|
|
||||||
#if (defined(__GNUC__) || defined(__clang__)) && ! defined(__STRICT_ANSI__)
|
#if (defined(__GNUC__) || defined(__clang__)) && ! defined(__STRICT_ANSI__)
|
||||||
|
|
85
lib/number.c
85
lib/number.c
|
@ -170,45 +170,34 @@ DEFINE_AOP(div, pic_div(pic, pic_int_value(pic, 1), argv[0]), do {
|
||||||
} while (0))
|
} while (0))
|
||||||
|
|
||||||
static int
|
static int
|
||||||
number_string_length(int val, int radix)
|
int2str(long x, int base, char *buf)
|
||||||
{
|
{
|
||||||
unsigned long v = val; /* in case val == INT_MIN */
|
static const char digits[36] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||||
int count = 0;
|
int i, neg, len;
|
||||||
if (val == 0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (val < 0) {
|
|
||||||
v = -val;
|
|
||||||
count = 1;
|
|
||||||
}
|
|
||||||
while (v > 0) {
|
|
||||||
++count;
|
|
||||||
v /= radix;
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
neg = 0;
|
||||||
number_string(int val, int radix, int length, char *buffer) {
|
if (x < 0) {
|
||||||
const char digits[37] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
neg = 1;
|
||||||
unsigned long v = val;
|
x = -x;
|
||||||
int i;
|
|
||||||
if (val == 0) {
|
|
||||||
buffer[0] = '0';
|
|
||||||
buffer[1] = '\0';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (val < 0) {
|
|
||||||
buffer[0] = '-';
|
|
||||||
v = -val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = length - 1; v > 0; --i) {
|
i = 0;
|
||||||
buffer[i] = digits[v % radix];
|
do {
|
||||||
v /= radix;
|
buf[i++] = digits[x % base];
|
||||||
|
} while ((x /= base) != 0);
|
||||||
|
|
||||||
|
if (neg) {
|
||||||
|
buf[i++] = '-';
|
||||||
}
|
}
|
||||||
buffer[length] = '\0';
|
buf[i] = '\0';
|
||||||
return;
|
len = i;
|
||||||
|
|
||||||
|
for (i = 0; i < len / 2; ++i) {
|
||||||
|
char tmp = buf[i];
|
||||||
|
buf[i] = buf[len - i - 1];
|
||||||
|
buf[len - i - 1] = tmp;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
|
@ -217,35 +206,23 @@ pic_number_number_to_string(pic_state *pic)
|
||||||
double f;
|
double f;
|
||||||
bool e;
|
bool e;
|
||||||
int radix = 10;
|
int radix = 10;
|
||||||
pic_value str;
|
|
||||||
|
|
||||||
pic_get_args(pic, "F|i", &f, &e, &radix);
|
pic_get_args(pic, "F|i", &f, &e, &radix);
|
||||||
|
|
||||||
if (radix < 2 || radix > 36) {
|
if (radix < 2 || radix > 36) {
|
||||||
pic_error(pic, "number->string: invalid radix (between 2 and 36, inclusive)", 1, pic_int_value(pic, radix));
|
pic_error(pic, "invalid radix (between 2 and 36, inclusive)", 1, pic_int_value(pic, radix));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
int ival = (int) f;
|
char buf[sizeof(int) * CHAR_BIT + 3];
|
||||||
int ilen = number_string_length(ival, radix);
|
int len = int2str((int) f, radix, buf);
|
||||||
char *buf = pic_alloca(pic, ilen + 1);
|
return pic_str_value(pic, buf, len);
|
||||||
|
|
||||||
number_string(ival, radix, ilen, buf);
|
|
||||||
|
|
||||||
str = pic_str_value(pic, buf, ilen);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pic_value port = pic_fmemopen(pic, NULL, 0, "w");
|
char buf[64];
|
||||||
const char *buf;
|
pic_dtoa(f, buf);
|
||||||
int len;
|
return pic_cstr_value(pic, buf);
|
||||||
|
|
||||||
pic_fprintf(pic, port, "%f", f);
|
|
||||||
pic_fgetbuf(pic, port, &buf, &len);
|
|
||||||
str = pic_str_value(pic, buf, len);
|
|
||||||
pic_fclose(pic, port);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -295,7 +272,7 @@ string_to_number(pic_state *pic, const char *str)
|
||||||
return pic_false_value(pic);
|
return pic_false_value(pic);
|
||||||
}
|
}
|
||||||
|
|
||||||
flt = PIC_CSTRING_TO_DOUBLE(str);
|
flt = pic_atod(str);
|
||||||
|
|
||||||
if (isint && INT_MIN <= flt && flt <= INT_MAX) {
|
if (isint && INT_MIN <= flt && flt <= INT_MAX) {
|
||||||
return pic_int_value(pic, flt);
|
return pic_int_value(pic, flt);
|
||||||
|
|
102
lib/port.c
102
lib/port.c
|
@ -307,6 +307,108 @@ pic_fseek(pic_state *pic, pic_value port, long offset, int whence)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pic_vfprintf(pic_state *pic, pic_value port, const char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
const char *p;
|
||||||
|
long start = pic_fseek(pic, port, 0, PIC_SEEK_CUR);
|
||||||
|
|
||||||
|
for (p = fmt; *p; p++) {
|
||||||
|
if (*p == '~') {
|
||||||
|
switch (*++p) {
|
||||||
|
default:
|
||||||
|
pic_fputc(pic, *(p-1), port);
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
pic_fputc(pic, '\n', port);
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
pic_void(pic, pic_funcall(pic, "display", 2, va_arg(ap, pic_value), port));
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
pic_void(pic, pic_funcall(pic, "write", 2, va_arg(ap, pic_value), port));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (*p == '%') {
|
||||||
|
switch (*++p) {
|
||||||
|
case 'd':
|
||||||
|
case 'i': {
|
||||||
|
int ival = va_arg(ap, int);
|
||||||
|
pic_value str = pic_funcall(pic, "number->string", 1, pic_int_value(pic, ival));
|
||||||
|
pic_fputs(pic, pic_str(pic, str, 0), port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'f': {
|
||||||
|
double f = va_arg(ap, double);
|
||||||
|
pic_value str = pic_funcall(pic, "number->string", 1, pic_float_value(pic, f));
|
||||||
|
pic_fputs(pic, pic_str(pic, str, 0), port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'c': {
|
||||||
|
int ival = va_arg(ap, int);
|
||||||
|
pic_fputc(pic, ival, port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 's': {
|
||||||
|
char *sval = va_arg(ap, char*);
|
||||||
|
pic_fputs(pic, sval, port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'p': {
|
||||||
|
static const char digits[] = "0123456789abcdef";
|
||||||
|
unsigned long vp = (unsigned long) va_arg(ap, void*);
|
||||||
|
char buf[sizeof vp * CHAR_BIT / 4 + 1];
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < sizeof buf; ++i) {
|
||||||
|
buf[sizeof buf - i - 1] = digits[vp % 16];
|
||||||
|
vp /= 16;
|
||||||
|
}
|
||||||
|
buf[i] = '\0';
|
||||||
|
pic_fputs(pic, "0x", port);
|
||||||
|
pic_fputs(pic, buf, port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '%':
|
||||||
|
pic_fputc(pic, *(p-1), port);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pic_fputc(pic, '%', port);
|
||||||
|
pic_fputc(pic, *(p-1), port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pic_fputc(pic, *p, port);
|
||||||
|
}
|
||||||
|
return pic_fseek(pic, port, 0, PIC_SEEK_CUR) - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pic_fprintf(pic_state *pic, pic_value port, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
n = pic_vfprintf(pic, port, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pic_printf(pic_state *pic, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
n = pic_vfprintf(pic, pic_stdout(pic), fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct { char *buf; long pos, end, capa; } xbuf_t;
|
typedef struct { char *buf; long pos, end, capa; } xbuf_t;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
Loading…
Reference in New Issue