1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-28 19:19:53 +00:00

Add xprint, xprin, xprintf, and xprinf.

This commit is contained in:
Calvin Rose 2020-08-09 09:30:58 -05:00
parent c3af30d520
commit 7b42ed66f2

View File

@ -391,18 +391,16 @@ FILE *janet_dynfile(const char *name, FILE *def) {
return iofile->file; return iofile->file;
} }
static Janet cfun_io_print_impl(int32_t argc, Janet *argv, static Janet cfun_io_print_impl_x(int32_t argc, Janet *argv, int newline,
int newline, const char *name, FILE *dflt_file) { FILE *dflt_file, int32_t offset, Janet x) {
FILE *f; FILE *f;
Janet x = janet_dyn(name);
switch (janet_type(x)) { switch (janet_type(x)) {
default: default:
/* Other values simply do nothing */ janet_panicf("cannot print to %v", x);
return janet_wrap_nil();
case JANET_BUFFER: { case JANET_BUFFER: {
/* Special case buffer */ /* Special case buffer */
JanetBuffer *buf = janet_unwrap_buffer(x); JanetBuffer *buf = janet_unwrap_buffer(x);
for (int32_t i = 0; i < argc; ++i) { for (int32_t i = offset; i < argc; ++i) {
janet_to_string_b(buf, argv[i]); janet_to_string_b(buf, argv[i]);
} }
if (newline) if (newline)
@ -411,6 +409,7 @@ static Janet cfun_io_print_impl(int32_t argc, Janet *argv,
} }
case JANET_NIL: case JANET_NIL:
f = dflt_file; f = dflt_file;
if (f == NULL) janet_panic("cannot print to nil");
break; break;
case JANET_ABSTRACT: { case JANET_ABSTRACT: {
void *abstract = janet_unwrap_abstract(x); void *abstract = janet_unwrap_abstract(x);
@ -421,7 +420,7 @@ static Janet cfun_io_print_impl(int32_t argc, Janet *argv,
break; break;
} }
} }
for (int32_t i = 0; i < argc; ++i) { for (int32_t i = offset; i < argc; ++i) {
int32_t len; int32_t len;
const uint8_t *vstr; const uint8_t *vstr;
if (janet_checktype(argv[i], JANET_BUFFER)) { if (janet_checktype(argv[i], JANET_BUFFER)) {
@ -434,7 +433,11 @@ static Janet cfun_io_print_impl(int32_t argc, Janet *argv,
} }
if (len) { if (len) {
if (1 != fwrite(vstr, len, 1, f)) { if (1 != fwrite(vstr, len, 1, f)) {
janet_panicf("could not print %d bytes to (dyn :%s)", len, name); if (f == dflt_file) {
janet_panicf("cannot print %d bytes", len);
} else {
janet_panicf("cannot print %d bytes to %v", len, x);
}
} }
} }
} }
@ -443,6 +446,13 @@ static Janet cfun_io_print_impl(int32_t argc, Janet *argv,
return janet_wrap_nil(); return janet_wrap_nil();
} }
static Janet cfun_io_print_impl(int32_t argc, Janet *argv,
int newline, const char *name, FILE *dflt_file) {
Janet x = janet_dyn(name);
return cfun_io_print_impl_x(argc, argv, newline, dflt_file, 0, x);
}
static Janet cfun_io_print(int32_t argc, Janet *argv) { static Janet cfun_io_print(int32_t argc, Janet *argv) {
return cfun_io_print_impl(argc, argv, 1, "out", stdout); return cfun_io_print_impl(argc, argv, 1, "out", stdout);
} }
@ -459,25 +469,33 @@ static Janet cfun_io_eprin(int32_t argc, Janet *argv) {
return cfun_io_print_impl(argc, argv, 0, "err", stderr); return cfun_io_print_impl(argc, argv, 0, "err", stderr);
} }
static Janet cfun_io_printf_impl(int32_t argc, Janet *argv, int newline, static Janet cfun_io_xprint(int32_t argc, Janet *argv) {
const char *name, FILE *dflt_file) {
FILE *f;
janet_arity(argc, 1, -1); janet_arity(argc, 1, -1);
const char *fmt = janet_getcstring(argv, 0); return cfun_io_print_impl_x(argc, argv, 1, NULL, 1, argv[0]);
Janet x = janet_dyn(name); }
static Janet cfun_io_xprin(int32_t argc, Janet *argv) {
janet_arity(argc, 1, -1);
return cfun_io_print_impl_x(argc, argv, 0, NULL, 1, argv[0]);
}
static Janet cfun_io_printf_impl_x(int32_t argc, Janet *argv, int newline,
FILE *dflt_file, int32_t offset, Janet x) {
FILE *f;
const char *fmt = janet_getcstring(argv, offset);
switch (janet_type(x)) { switch (janet_type(x)) {
default: default:
/* Other values simply do nothing */ janet_panicf("cannot print to %v", x);
return janet_wrap_nil();
case JANET_BUFFER: { case JANET_BUFFER: {
/* Special case buffer */ /* Special case buffer */
JanetBuffer *buf = janet_unwrap_buffer(x); JanetBuffer *buf = janet_unwrap_buffer(x);
janet_buffer_format(buf, fmt, 0, argc, argv); janet_buffer_format(buf, fmt, offset, argc, argv);
if (newline) janet_buffer_push_u8(buf, '\n'); if (newline) janet_buffer_push_u8(buf, '\n');
return janet_wrap_nil(); return janet_wrap_nil();
} }
case JANET_NIL: case JANET_NIL:
f = dflt_file; f = dflt_file;
if (f == NULL) janet_panic("cannot print to nil");
break; break;
case JANET_ABSTRACT: { case JANET_ABSTRACT: {
void *abstract = janet_unwrap_abstract(x); void *abstract = janet_unwrap_abstract(x);
@ -489,11 +507,11 @@ static Janet cfun_io_printf_impl(int32_t argc, Janet *argv, int newline,
} }
} }
JanetBuffer *buf = janet_buffer(10); JanetBuffer *buf = janet_buffer(10);
janet_buffer_format(buf, fmt, 0, argc, argv); janet_buffer_format(buf, fmt, offset, argc, argv);
if (newline) janet_buffer_push_u8(buf, '\n'); if (newline) janet_buffer_push_u8(buf, '\n');
if (buf->count) { if (buf->count) {
if (1 != fwrite(buf->data, buf->count, 1, f)) { if (1 != fwrite(buf->data, buf->count, 1, f)) {
janet_panicf("could not print %d bytes to file", buf->count, name); janet_panicf("could not print %d bytes to file", buf->count);
} }
} }
/* Clear buffer to make things easier for GC */ /* Clear buffer to make things easier for GC */
@ -504,6 +522,14 @@ static Janet cfun_io_printf_impl(int32_t argc, Janet *argv, int newline,
return janet_wrap_nil(); return janet_wrap_nil();
} }
static Janet cfun_io_printf_impl(int32_t argc, Janet *argv, int newline,
const char *name, FILE *dflt_file) {
janet_arity(argc, 1, -1);
Janet x = janet_dyn(name);
return cfun_io_printf_impl_x(argc, argv, newline, dflt_file, 0, x);
}
static Janet cfun_io_printf(int32_t argc, Janet *argv) { static Janet cfun_io_printf(int32_t argc, Janet *argv) {
return cfun_io_printf_impl(argc, argv, 1, "out", stdout); return cfun_io_printf_impl(argc, argv, 1, "out", stdout);
} }
@ -520,6 +546,16 @@ static Janet cfun_io_eprinf(int32_t argc, Janet *argv) {
return cfun_io_printf_impl(argc, argv, 0, "err", stderr); return cfun_io_printf_impl(argc, argv, 0, "err", stderr);
} }
static Janet cfun_io_xprintf(int32_t argc, Janet *argv) {
janet_arity(argc, 2, -1);
return cfun_io_printf_impl_x(argc, argv, 1, NULL, 1, argv[0]);
}
static Janet cfun_io_xprinf(int32_t argc, Janet *argv) {
janet_arity(argc, 2, -1);
return cfun_io_printf_impl_x(argc, argv, 0, NULL, 1, argv[0]);
}
static void janet_flusher(const char *name, FILE *dflt_file) { static void janet_flusher(const char *name, FILE *dflt_file) {
Janet x = janet_dyn(name); Janet x = janet_dyn(name);
switch (janet_type(x)) { switch (janet_type(x)) {
@ -633,6 +669,29 @@ static const JanetReg io_cfuns[] = {
JDOC("(eprinf fmt & xs)\n\n" JDOC("(eprinf fmt & xs)\n\n"
"Like eprintf but with no trailing newline.") "Like eprintf but with no trailing newline.")
}, },
{
"xprint", cfun_io_xprint,
JDOC("(xprint to & xs)\n\n"
"Print to a file or other value explicitly (no dynamic bindings) with a trailing "
"newline character. The value to print "
"to is the first argument, and is otherwise the same as print. Returns nil.")
},
{
"xprin", cfun_io_xprin,
JDOC("(xprin to & xs)\n\n"
"Print to a file or other value explicitly (no dynamic bindings). The value to print "
"to is the first argument, and is otherwise the same as prin. Returns nil.")
},
{
"xprintf", cfun_io_xprintf,
JDOC("(xprint to fmt & xs)\n\n"
"Like printf but prints to an explicit file or value to. Returns nil.")
},
{
"xprinf", cfun_io_xprinf,
JDOC("(xprin to fmt & xs)\n\n"
"Like prinf but prints to an explicit file or value to. Returns nil.")
},
{ {
"flush", cfun_io_flush, "flush", cfun_io_flush,
JDOC("(flush)\n\n" JDOC("(flush)\n\n"