From: Michael D. Lowis Date: Wed, 9 Oct 2019 03:03:53 +0000 (-0400) Subject: fixed bug in context selection X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=f1e1a932e15a7bd033a7f333219e91a763aaeff6;p=projs%2Ftide.git fixed bug in context selection --- diff --git a/Rsconscript b/Rsconscript index 5896af3..4e8ba3f 100644 --- a/Rsconscript +++ b/Rsconscript @@ -11,12 +11,18 @@ build do env = Environment.new env["prefix"] = ENV["PREFIX"] || env["prefix"] env["CC"] = "./alcc" -# env["CFLAGS"] += ["-g", "-fsanitize=undefined,address"] -# env["LDFLAGS"] += ["-g", "-fsanitize=undefined,address"] env["CPPPATH"] += %w[. inc] env["LIBPATH"] += %w[.] env["CFLAGS"] << "-DNDEBUG" +# # Enable Sanitizers +# env["CFLAGS"] += ["-g", "-fsanitize=undefined,address"] +# env["LDFLAGS"] += ["-g", "-fsanitize=undefined,address"] + +# # Enable Coverage +# env["CFLAGS"] += ["-g", "-O0", "--coverage"] +# env["LDFLAGS"] += ["-g", "-O0", "--coverage"] + # Build library and binaries env.Library("libtide.a", glob("src/lib/**/*.c")) (glob("src/*.c") - ["src/term.c", "src/tsed.c"]).each do |src| diff --git a/TODO.md b/TODO.md index 1446e0f..8cf88a2 100644 --- a/TODO.md +++ b/TODO.md @@ -4,10 +4,11 @@ ## STAGING +* tide: column tracking should be hidden in buf.c * tide: buf_findstr has an infinite loop condition * tide: refactor byword, byline, etc api * tide: refactor undo/redo api in view.c -* all: eliminate multiple return statements +* all: eliminate multiple return statements and other lint ## BACKLOG diff --git a/alcc b/alcc index c226c0b..e3b0619 100755 --- a/alcc +++ b/alcc @@ -264,7 +264,7 @@ script=$(cat <= buf_end(buf) || end == 0) - { - break; - } - else - { - end += dir; + if (balance == 0 || end >= buf_end(buf) || end == 0) + { + break; + } + else + { + end += dir; + } } - } - /* update the passed in selection if we found a block */ - if (balance) - { - if (end > beg) + /* update the selection if we found a block */ + if (balance == 0) { - beg++; - } - else - { - end++; + if (end > beg) + { + beg++; + } + else + { + end++; + } + buf->selection.beg = beg; + buf->selection.end = end; } - buf->selection.beg = beg; - buf->selection.end = end; } } @@ -842,7 +845,7 @@ void buf_selctx(Buf* buf, bool (*isword)(Rune)) { ; /* condition performs selection */ } - else if (risword(curr)) + else if (isword(curr)) { buf_selword(buf, isword); } @@ -1105,12 +1108,8 @@ char* buf_fetch(Buf* buf, bool (*isword)(Rune), size_t off) { buf->selection = (Sel){ .beg = off, .end = off }; buf_selword(buf, isword); - str = buf_gets(buf); - } - else - { - str = buf_gets(buf); } + str = buf_gets(buf); buf->selection = prev; return str; } diff --git a/tests/lib/buf.c b/tests/lib/buf.c index c889173..b36836f 100644 --- a/tests/lib/buf.c +++ b/tests/lib/buf.c @@ -257,9 +257,23 @@ TEST_SUITE(BufferTests) CHECK(TestBuf.status != MODIFIED); } + /* Basic Operation + *************************************************************************/ + TEST(buffer should grow to fit data) + { + size_t datasz = 2*1024*1024; + char* data = malloc(datasz); + memset(data, '.', datasz); + data[datasz - 1] = '\0'; + buf_init(&TestBuf); + buf_puts(&TestBuf, data); + int result = buffer_equals(data); + free(data); + CHECK(result); + } + /* Movements *************************************************************************/ - // Start of Line TEST(buf_bol should return 0 if column 1 of first line) { set_buffer_text("ab\ncd"); @@ -345,4 +359,201 @@ TEST_SUITE(BufferTests) // printf("%lu\n", TestBuf.selection.end); // CHECK(8 == TestBuf.selection.end); // } + + /* Context-Sensitive Selection + *************************************************************************/ + TEST(buf_selctx should select from ( to )) + { + set_buffer_text("(...)"); + TestBuf.selection = (Sel){ .beg = 0, .end = 0 }; + buf_selctx(&TestBuf, risword); + CHECK(1 == buf_selbeg(&TestBuf)); + CHECK(4 == buf_selend(&TestBuf)); + TestBuf.selection = (Sel){ .beg = 4, .end = 4 }; + buf_selctx(&TestBuf, risword); + CHECK(1 == buf_selbeg(&TestBuf)); + CHECK(4 == buf_selend(&TestBuf)); + } + + TEST(buf_selctx should select from < to >) + { + set_buffer_text("<...>"); + TestBuf.selection = (Sel){ .beg = 0, .end = 0 }; + buf_selctx(&TestBuf, risword); + CHECK(1 == buf_selbeg(&TestBuf)); + CHECK(4 == buf_selend(&TestBuf)); + TestBuf.selection = (Sel){ .beg = 4, .end = 4 }; + buf_selctx(&TestBuf, risword); + CHECK(1 == buf_selbeg(&TestBuf)); + CHECK(4 == buf_selend(&TestBuf)); + } + + TEST(buf_selctx should select from [ to ]) + { + set_buffer_text("[...]"); + TestBuf.selection = (Sel){ .beg = 0, .end = 0 }; + buf_selctx(&TestBuf, risword); + CHECK(1 == buf_selbeg(&TestBuf)); + CHECK(4 == buf_selend(&TestBuf)); + TestBuf.selection = (Sel){ .beg = 4, .end = 4 }; + buf_selctx(&TestBuf, risword); + CHECK(1 == buf_selbeg(&TestBuf)); + CHECK(4 == buf_selend(&TestBuf)); + } + + TEST(buf_selctx should select from { to }) + { + set_buffer_text("{...}"); + TestBuf.selection = (Sel){ .beg = 0, .end = 0 }; + buf_selctx(&TestBuf, risword); + CHECK(1 == buf_selbeg(&TestBuf)); + CHECK(4 == buf_selend(&TestBuf)); + TestBuf.selection = (Sel){ .beg = 4, .end = 4 }; + buf_selctx(&TestBuf, risword); + CHECK(1 == buf_selbeg(&TestBuf)); + CHECK(4 == buf_selend(&TestBuf)); + } + + TEST(buf_selctx should do nothing for unbalanced block) + { + set_buffer_text("...}{..."); + TestBuf.selection = (Sel){ .beg = 3, .end = 3 }; + buf_selctx(&TestBuf, risword); + CHECK(3 == buf_selbeg(&TestBuf)); + CHECK(3 == buf_selend(&TestBuf)); + TestBuf.selection = (Sel){ .beg = 4, .end = 4 }; + buf_selctx(&TestBuf, risword); + CHECK(4 == buf_selbeg(&TestBuf)); + CHECK(4 == buf_selend(&TestBuf)); + } + + TEST(buf_selctx should select '"' quotes) + { + set_buffer_text(" \"...\" "); + TestBuf.selection = (Sel){ .beg = 1, .end = 1 }; // opening quote + buf_selctx(&TestBuf, risword); + CHECK(2 == buf_selbeg(&TestBuf)); + CHECK(5 == buf_selend(&TestBuf)); + TestBuf.selection = (Sel){ .beg = 2, .end = 2 }; // first char of quote + buf_selctx(&TestBuf, risword); + CHECK(2 == buf_selbeg(&TestBuf)); + CHECK(5 == buf_selend(&TestBuf)); + TestBuf.selection = (Sel){ .beg = 4, .end = 4 }; // last char of quote + buf_selctx(&TestBuf, risword); + CHECK(2 == buf_selbeg(&TestBuf)); + CHECK(5 == buf_selend(&TestBuf)); + } + + TEST(buf_selctx should select '`' quotes) + { + set_buffer_text(" `...` "); + TestBuf.selection = (Sel){ .beg = 1, .end = 1 }; // opening quote + buf_selctx(&TestBuf, risword); + CHECK(2 == buf_selbeg(&TestBuf)); + CHECK(5 == buf_selend(&TestBuf)); + TestBuf.selection = (Sel){ .beg = 2, .end = 2 }; // first char of quote + buf_selctx(&TestBuf, risword); + CHECK(2 == buf_selbeg(&TestBuf)); + CHECK(5 == buf_selend(&TestBuf)); + TestBuf.selection = (Sel){ .beg = 4, .end = 4 }; // last char of quote + buf_selctx(&TestBuf, risword); + CHECK(2 == buf_selbeg(&TestBuf)); + CHECK(5 == buf_selend(&TestBuf)); + } + + TEST(buf_selctx should select '\'' quotes) + { + set_buffer_text(" '...' "); + TestBuf.selection = (Sel){ .beg = 1, .end = 1 }; // opening quote + buf_selctx(&TestBuf, risword); + CHECK(2 == buf_selbeg(&TestBuf)); + CHECK(5 == buf_selend(&TestBuf)); + TestBuf.selection = (Sel){ .beg = 2, .end = 2 }; // first char of quote + buf_selctx(&TestBuf, risword); + CHECK(2 == buf_selbeg(&TestBuf)); + CHECK(5 == buf_selend(&TestBuf)); + TestBuf.selection = (Sel){ .beg = 4, .end = 4 }; // last char of quote + buf_selctx(&TestBuf, risword); + CHECK(2 == buf_selbeg(&TestBuf)); + CHECK(5 == buf_selend(&TestBuf)); + } + + TEST(buf_selctx should select word using risword) + { + set_buffer_text(" abc/def "); + TestBuf.selection = (Sel){ .beg = 1, .end = 1 }; + buf_selctx(&TestBuf, risword); + CHECK(1 == buf_selbeg(&TestBuf)); + CHECK(4 == buf_selend(&TestBuf)); + TestBuf.selection = (Sel){ .beg = 5, .end = 5 }; + buf_selctx(&TestBuf, risword); + CHECK(5 == buf_selbeg(&TestBuf)); + CHECK(8 == buf_selend(&TestBuf)); + } + + TEST(buf_selctx should select word using risbigword) + { + set_buffer_text(" abc/def "); + TestBuf.selection = (Sel){ .beg = 1, .end = 1 }; + buf_selctx(&TestBuf, risbigword); + CHECK(1 == buf_selbeg(&TestBuf)); + CHECK(8 == buf_selend(&TestBuf)); + TestBuf.selection = (Sel){ .beg = 5, .end = 5 }; + buf_selctx(&TestBuf, risbigword); + CHECK(1 == buf_selbeg(&TestBuf)); + CHECK(8 == buf_selend(&TestBuf)); + } + + TEST(buf_selctx should select big word on non word character) + { + set_buffer_text(" abc/def "); + TestBuf.selection = (Sel){ .beg = 4, .end = 4 }; + buf_selctx(&TestBuf, risword); + CHECK(1 == buf_selbeg(&TestBuf)); + CHECK(8 == buf_selend(&TestBuf)); + } + + TEST(buf_selctx should select line on bol) + { + set_buffer_text("\n...\n"); + TestBuf.selection = (Sel){ .beg = 2, .end = 2 }; + buf_selctx(&TestBuf, risword); + CHECK(2 == buf_selbeg(&TestBuf)); + CHECK(7 == buf_selend(&TestBuf)); + } + + TEST(buf_selctx should select line on eol) + { + set_buffer_text("\n...\n"); + TestBuf.selection = (Sel){ .beg = 4, .end = 4 }; + buf_selctx(&TestBuf, risword); + CHECK(2 == buf_selbeg(&TestBuf)); + CHECK(5 == buf_selend(&TestBuf)); + } + + /* String Retrieval + *************************************************************************/ + TEST(buf_getsat should get string defined by range) + { + set_buffer_text(" abc/def "); + char* str = buf_getsat(&TestBuf, 1, 8); + int result = !strcmp(str, "abc/def"); + free(str); + CHECK(result); + } + + TEST(buf_fetch should get string defined by function) + { + set_buffer_text(" abc/def "); + TestBuf.selection = (Sel){ .beg = 0, .end = 1 }; + char* str = buf_fetch(&TestBuf, risbigword, 4); + int result = !strcmp(str, "abc/def"); + free(str); + CHECK(result); + TestBuf.selection = (Sel){ .beg = 1, .end = 8 }; + str = buf_fetch(&TestBuf, risbigword, 4); + result = !strcmp(str, "abc/def"); + free(str); + CHECK(result); + } }