From e6927238e13e248c6939b2be392a49b54de35b35 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Fri, 10 Feb 2017 09:10:06 -0500 Subject: [PATCH 1/5] Construct TSStringInput with explicit length. --- src/runtime/string_input.c | 12 +++++++++++- src/runtime/string_input.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/runtime/string_input.c b/src/runtime/string_input.c index 713a272d..8038fb34 100644 --- a/src/runtime/string_input.c +++ b/src/runtime/string_input.c @@ -27,13 +27,23 @@ int ts_string_input_seek(void *payload, uint32_t character, uint32_t byte) { } TSInput ts_string_input_make(const char *string) { + if (!input) + goto error; + + return ts_string_input_make_with_length(string, strlen(string)) + + error: + return (TSInput){ NULL, NULL, NULL, TSInputEncodingUTF8 }; +} + +TSInput ts_string_input_make_with_length(const char *string, uint32_t length) { TSStringInput *input = ts_malloc(sizeof(TSStringInput)); if (!input) goto error; input->string = string; input->position = 0; - input->length = strlen(string); + input->length = length; return (TSInput){ .payload = input, .read = ts_string_input_read, diff --git a/src/runtime/string_input.h b/src/runtime/string_input.h index fe5e4b1f..c96cd416 100644 --- a/src/runtime/string_input.h +++ b/src/runtime/string_input.h @@ -8,6 +8,7 @@ extern "C" { #include "tree_sitter/runtime.h" TSInput ts_string_input_make(const char *); +TSInput ts_string_input_make_with_length(const char *, uint32_t); #ifdef __cplusplus } From c230658bae80dcd6a56669218b9386f6ae13e372 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Fri, 10 Feb 2017 09:10:31 -0500 Subject: [PATCH 2/5] Add public API to set the input string with explicit length. --- include/tree_sitter/runtime.h | 1 + src/runtime/document.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/include/tree_sitter/runtime.h b/include/tree_sitter/runtime.h index 00d8e7c4..69334ad0 100644 --- a/include/tree_sitter/runtime.h +++ b/include/tree_sitter/runtime.h @@ -104,6 +104,7 @@ void ts_document_set_language(TSDocument *, const TSLanguage *); TSInput ts_document_input(TSDocument *); void ts_document_set_input(TSDocument *, TSInput); void ts_document_set_input_string(TSDocument *, const char *); +void ts_document_set_input_string_with_length(TSDocument *, const char *, uint32_t); TSLogger ts_document_logger(const TSDocument *); void ts_document_set_logger(TSDocument *, TSLogger); void ts_document_print_debugging_graphs(TSDocument *, bool); diff --git a/src/runtime/document.c b/src/runtime/document.c index 8c1eb779..ff09610d 100644 --- a/src/runtime/document.c +++ b/src/runtime/document.c @@ -77,6 +77,15 @@ void ts_document_set_input_string(TSDocument *self, const char *text) { } } +void ts_document_set_input_string_with_length(TSDocument *self, const char *text, uint32_t length) { + ts_document_invalidate(self); + TSInput input = ts_string_input_make_with_length(text, length); + ts_document_set_input(self, input); + if (input.payload) { + self->owns_input = true; + } +} + void ts_document_edit(TSDocument *self, TSInputEdit edit) { if (!self->tree) return; From eab518e5da1558d62088cf05a35b15bb70df2989 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Fri, 10 Feb 2017 09:20:58 -0500 Subject: [PATCH 3/5] Semicolon shame. --- src/runtime/string_input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/string_input.c b/src/runtime/string_input.c index 8038fb34..1a244432 100644 --- a/src/runtime/string_input.c +++ b/src/runtime/string_input.c @@ -30,7 +30,7 @@ TSInput ts_string_input_make(const char *string) { if (!input) goto error; - return ts_string_input_make_with_length(string, strlen(string)) + return ts_string_input_make_with_length(string, strlen(string)); error: return (TSInput){ NULL, NULL, NULL, TSInputEncodingUTF8 }; From 638aa87e42f22c3cf905d967493211a23bb109c4 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Fri, 10 Feb 2017 09:27:21 -0500 Subject: [PATCH 4/5] Pass through to ts_string_input_make_with_length. --- src/runtime/string_input.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/runtime/string_input.c b/src/runtime/string_input.c index 1a244432..3b951a10 100644 --- a/src/runtime/string_input.c +++ b/src/runtime/string_input.c @@ -27,13 +27,7 @@ int ts_string_input_seek(void *payload, uint32_t character, uint32_t byte) { } TSInput ts_string_input_make(const char *string) { - if (!input) - goto error; - return ts_string_input_make_with_length(string, strlen(string)); - - error: - return (TSInput){ NULL, NULL, NULL, TSInputEncodingUTF8 }; } TSInput ts_string_input_make_with_length(const char *string, uint32_t length) { From 93e94bf4b27dd20ec848642ea3488bf9e362539b Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Mon, 13 Feb 2017 08:48:51 -0800 Subject: [PATCH 5/5] Add a happy path test for ts_document_set_input_string_with_length --- spec/runtime/document_spec.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spec/runtime/document_spec.cc b/spec/runtime/document_spec.cc index 52e65ffb..f80419dc 100644 --- a/spec/runtime/document_spec.cc +++ b/spec/runtime/document_spec.cc @@ -116,6 +116,17 @@ describe("Document", [&]() { AssertThat(spy_input->strings_read, Equals(vector({" [null, 2" }))); }); + it("allows setting input string with length", [&]() { + const char content[] = { '1' }; + ts_document_set_input_string_with_length(document, content, 1); + ts_document_parse(document); + TSNode new_root = ts_document_root_node(document); + AssertThat(ts_node_end_char(new_root), Equals(1)); + assert_node_string_equals( + new_root, + "(number)"); + }); + it("reads from the new input correctly when the old input was blank", [&]() { ts_document_set_input_string(document, ""); ts_document_parse(document);