From 8e6ed707e7d1faedfb4594e0ef43a489e509a34c Mon Sep 17 00:00:00 2001 From: bakpakin Date: Wed, 17 Jan 2018 11:36:10 -0500 Subject: [PATCH] Make buffers print their contents. --- client/main.c | 2 +- core/context.c | 4 ++-- core/parse.c | 16 +++++++++------ core/string.c | 45 +++++++++++++++++++++++++++++++----------- include/dst/dst.h | 4 ++-- include/dst/dsttypes.h | 2 ++ 6 files changed, 50 insertions(+), 23 deletions(-) diff --git a/client/main.c b/client/main.c index 181c93d1..186ab26f 100644 --- a/client/main.c +++ b/client/main.c @@ -73,7 +73,7 @@ static void runfile(const uint8_t *src, int32_t len) { const uint8_t *s = src; const uint8_t *end = src + len; while (s < end) { - res = dst_parse(s, end - s); + res = dst_parse(s, end - s, DST_PARSEFLAG_SOURCEMAP); switch (res.status) { case DST_PARSE_NODATA: return; diff --git a/core/context.c b/core/context.c index e25b67f2..a49f3dce 100644 --- a/core/context.c +++ b/core/context.c @@ -50,7 +50,7 @@ static void replonvalue(DstContext *c, Dst value) { (void) c; dst_puts(dst_formatc("%v\n", value)); if (dst_checktype(c->env, DST_TABLE)) - dst_module_def(dst_unwrap_table(c->env), "_", dst_wrap_nil()); + dst_module_def(dst_unwrap_table(c->env), "_", value); } /* Handle errors on repl */ @@ -138,7 +138,7 @@ int dst_context_run(DstContext *c) { while (!done) { DstCompileResult cres; DstCompileOptions opts; - DstParseResult res = dst_parse(c->buffer.data, c->buffer.count); + DstParseResult res = dst_parse(c->buffer.data, c->buffer.count, DST_PARSEFLAG_SOURCEMAP); switch (res.status) { case DST_PARSE_NODATA: flushcontext(c); diff --git a/core/parse.c b/core/parse.c index 740cd389..287058ca 100644 --- a/core/parse.c +++ b/core/parse.c @@ -161,6 +161,7 @@ typedef struct { const uint8_t *end; const char *errmsg; DstParseStatus status; + int flags; } ParseArgs; @@ -397,12 +398,14 @@ static const uint8_t *parse_recur( /* Quote the returned value qcount times */ while (qcount--) { - ret = dst_ast_wrap(ret, mapstart - args->srcstart, src - args->srcstart); + if (args->flags & DST_PARSEFLAG_SOURCEMAP) + ret = dst_ast_wrap(ret, mapstart - args->srcstart, src - args->srcstart); ret = quote(ret); } /* Ast wrap */ - ret = dst_ast_wrap(ret, mapstart - args->srcstart, src - args->srcstart); + if (args->flags & DST_PARSEFLAG_SOURCEMAP) + ret = dst_ast_wrap(ret, mapstart - args->srcstart, src - args->srcstart); /* Push the result to the stack */ dst_array_push(&args->stack, ret); @@ -463,7 +466,7 @@ static const uint8_t *parse_recur( } /* Parse an array of bytes. Return value in the fiber return value. */ -DstParseResult dst_parse(const uint8_t *src, int32_t len) { +DstParseResult dst_parse(const uint8_t *src, int32_t len, int flags) { DstParseResult res; ParseArgs args; const uint8_t *newsrc; @@ -473,6 +476,7 @@ DstParseResult dst_parse(const uint8_t *src, int32_t len) { args.srcstart = src; args.end = src + len; args.errmsg = NULL; + args.flags = flags; newsrc = parse_recur(&args, src, DST_RECURSION_GUARD); res.status = args.status; @@ -492,10 +496,10 @@ DstParseResult dst_parse(const uint8_t *src, int32_t len) { } /* Parse a c string */ -DstParseResult dst_parsec(const char *src) { +DstParseResult dst_parsec(const char *src, int flags) { int32_t len = 0; while (src[len]) ++len; - return dst_parse((const uint8_t *)src, len); + return dst_parse((const uint8_t *)src, len, flags); } /* C Function parser */ @@ -507,7 +511,7 @@ int dst_parse_cfun(DstArgs args) { DstTable *t; if (args.n < 1) return dst_throw(args, "expected at least on argument"); if (!dst_chararray_view(args.v[0], &src, &len)) return dst_throw(args, "expected string/buffer"); - res = dst_parse(src, len); + res = dst_parse(src, len, 0); t = dst_table(4); switch (res.status) { case DST_PARSE_OK: diff --git a/core/string.c b/core/string.c index 5dd31c4b..6d943a2a 100644 --- a/core/string.c +++ b/core/string.c @@ -204,11 +204,14 @@ static const uint8_t *string_description(const char *title, void *pointer) { #undef HEX #undef DST_BUFSIZE -/* TODO - add more characters to escapes */ -static int32_t dst_escape_string_length(const uint8_t *str) { +/* TODO - add more characters to escape. + * + * When more escapes are added, they must correspond + * to dst_escape_string_impl exactly or a buffer overrun could occur. */ +static int32_t dst_escape_string_length(const uint8_t *str, int32_t slen) { int32_t len = 2; int32_t i; - for (i = 0; i < dst_string_length(str); ++i) { + for (i = 0; i < slen; ++i) { switch (str[i]) { case '"': case '\n': @@ -224,10 +227,10 @@ static int32_t dst_escape_string_length(const uint8_t *str) { return len; } -static void dst_escape_string_impl(uint8_t *buf, const uint8_t *str) { +static void dst_escape_string_impl(uint8_t *buf, const uint8_t *str, int32_t len) { int32_t i, j; buf[0] = '"'; - for (i = 0, j = 1; i < dst_string_length(str); ++i) { + for (i = 0, j = 1; i < len; ++i) { uint8_t c = str[i]; switch (c) { case '"': @@ -255,19 +258,32 @@ static void dst_escape_string_impl(uint8_t *buf, const uint8_t *str) { } void dst_escape_string_b(DstBuffer *buffer, const uint8_t *str) { - int32_t len = dst_escape_string_length(str); - dst_buffer_extra(buffer, len); - dst_escape_string_impl(buffer->data + buffer->count, str); - buffer->count += len; + int32_t len = dst_string_length(str); + int32_t elen = dst_escape_string_length(str, len); + dst_buffer_extra(buffer, elen); + dst_escape_string_impl(buffer->data + buffer->count, str, len); + buffer->count += elen; } const uint8_t *dst_escape_string(const uint8_t *str) { - int32_t len = dst_escape_string_length(str); - uint8_t *buf = dst_string_begin(len); - dst_escape_string_impl(buf, str); + int32_t len = dst_string_length(str); + int32_t elen = dst_escape_string_length(str, len); + uint8_t *buf = dst_string_begin(elen); + dst_escape_string_impl(buf, str, len); return dst_string_end(buf); } +void dst_escape_buffer_b(DstBuffer *buffer, DstBuffer *bx) { + int32_t elen = dst_escape_string_length(bx->data, bx->count); + dst_buffer_push_u8(buffer, '@'); + dst_buffer_extra(buffer, elen); + dst_escape_string_impl( + buffer->data + buffer->count, + bx->data, + bx->count); + buffer->count += elen; +} + /* Returns a string pointer with the description of the string */ const uint8_t *dst_short_description(Dst x) { switch (dst_type(x)) { @@ -319,6 +335,9 @@ void dst_short_description_b(DstBuffer *buffer, Dst x) { case DST_STRING: dst_escape_string_b(buffer, dst_unwrap_string(x)); return; + case DST_BUFFER: + dst_escape_buffer_b(buffer, dst_unwrap_buffer(x)); + return; case DST_ABSTRACT: string_description_b(buffer, dst_abstract_type(dst_unwrap_abstract(x))->name, @@ -593,6 +612,8 @@ const uint8_t *dst_to_string(Dst x) { switch (dst_type(x)) { default: return dst_short_description(x); + case DST_BUFFER: + return dst_string(dst_unwrap_buffer(x)->data, dst_unwrap_buffer(x)->count); case DST_STRING: case DST_SYMBOL: return dst_unwrap_string(x); diff --git a/include/dst/dst.h b/include/dst/dst.h index b8c4a696..37dff91b 100644 --- a/include/dst/dst.h +++ b/include/dst/dst.h @@ -179,8 +179,8 @@ Dst dst_ast_unwrap1(Dst x); Dst dst_ast_unwrap(Dst x); /* Parsing */ -DstParseResult dst_parse(const uint8_t *src, int32_t len); -DstParseResult dst_parsec(const char *src); +DstParseResult dst_parse(const uint8_t *src, int32_t len, int flags); +DstParseResult dst_parsec(const char *src, int flags); int dst_parse_cfun(DstArgs args); /* Native */ diff --git a/include/dst/dsttypes.h b/include/dst/dsttypes.h index a760ec04..62fbeae1 100644 --- a/include/dst/dsttypes.h +++ b/include/dst/dsttypes.h @@ -470,6 +470,8 @@ struct DstAst { int flags; }; +#define DST_PARSEFLAG_SOURCEMAP 1 + /* Parse structs */ enum DstParseStatus { DST_PARSE_OK,