Compare commits
6 Commits
a7eeedf7fb
...
0eb828251c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0eb828251c | ||
|
|
3b66a08d63 | ||
|
|
c0c5e3d77a | ||
|
|
5408fd8101 | ||
|
|
35a33c7d24 | ||
|
|
80813462be |
@@ -70,7 +70,7 @@ Also ensure stream_eoc is false.
|
|||||||
- Seeking forward/backward on a bad stream (should stop at 0)
|
- Seeking forward/backward on a bad stream (should stop at 0)
|
||||||
- Seeking forward/backward too far (should clamp)
|
- Seeking forward/backward too far (should clamp)
|
||||||
- Seeking forward/backward zero sum via relative index (stream_seek)
|
- Seeking forward/backward zero sum via relative index (stream_seek)
|
||||||
**** TODO Test substring
|
**** DONE Test substring
|
||||||
[[file:test/test_stream.c::void stream_test_substr(void)]]
|
[[file:test/test_stream.c::void stream_test_substr(void)]]
|
||||||
- Substr on bad stream (NULL sv)
|
- Substr on bad stream (NULL sv)
|
||||||
- Substr on bad position/size (NULL sv)
|
- Substr on bad position/size (NULL sv)
|
||||||
@@ -196,6 +196,12 @@ functions to construct and deconstruct strings as lisps.
|
|||||||
Should we capitalise symbols? This way, we limit the symbol table's
|
Should we capitalise symbols? This way, we limit the symbol table's
|
||||||
possible options a bit (potentially we could design a better hashing
|
possible options a bit (potentially we could design a better hashing
|
||||||
algorithm?) and it would be kinda like an actual Lisp.
|
algorithm?) and it would be kinda like an actual Lisp.
|
||||||
|
*** TODO sv_t
|
||||||
|
[[file:include/alisp/sv.h::/// String Views]]
|
||||||
|
**** TODO sv_substr
|
||||||
|
Takes an index and a size, returns a string view to that substring.
|
||||||
|
**** TODO sv_chop_left and sv_chop_right
|
||||||
|
Super obvious.
|
||||||
** Completed
|
** Completed
|
||||||
*** DONE Test value constructors and destructors :test:
|
*** DONE Test value constructors and destructors :test:
|
||||||
Test if ~make_int~ works with ~as_int,~ ~intern~ with ~as_sym~.
|
Test if ~make_int~ works with ~as_int,~ ~intern~ with ~as_sym~.
|
||||||
|
|||||||
@@ -69,9 +69,9 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
LOG("[INFO]: Initialised stream for `%s`\n", stream.name);
|
LOG("[INFO]: Initialised stream for `%s`\n", stream.name);
|
||||||
end:
|
end:
|
||||||
|
stream_stop(&stream);
|
||||||
if (pipe)
|
if (pipe)
|
||||||
fclose(pipe);
|
fclose(pipe);
|
||||||
stream_stop(&stream);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
10
src/stream.c
10
src/stream.c
@@ -5,6 +5,7 @@
|
|||||||
* Commentary:
|
* Commentary:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -95,8 +96,11 @@ void stream_stop(stream_t *stream)
|
|||||||
case STREAM_TYPE_STRING:
|
case STREAM_TYPE_STRING:
|
||||||
free(stream->string.data);
|
free(stream->string.data);
|
||||||
break;
|
break;
|
||||||
case STREAM_TYPE_PIPE:
|
|
||||||
case STREAM_TYPE_FILE:
|
case STREAM_TYPE_FILE:
|
||||||
|
// ensure we reset the FILE pointer to the start
|
||||||
|
fseek(stream->pipe.file, 0, SEEK_SET);
|
||||||
|
// fallthrough
|
||||||
|
case STREAM_TYPE_PIPE:
|
||||||
// Must cleanup vector
|
// Must cleanup vector
|
||||||
vec_free(&stream->pipe.cache);
|
vec_free(&stream->pipe.cache);
|
||||||
break;
|
break;
|
||||||
@@ -313,11 +317,11 @@ sv_t stream_substr(stream_t *stream, u64 size)
|
|||||||
|
|
||||||
// See if I can go forward enough to make this substring
|
// See if I can go forward enough to make this substring
|
||||||
u64 current_position = stream->position;
|
u64 current_position = stream->position;
|
||||||
bool successful = stream_seek_forward(stream, size);
|
u64 successful = stream_seek_forward(stream, size);
|
||||||
// Reset the position in either situation
|
// Reset the position in either situation
|
||||||
stream->position = current_position;
|
stream->position = current_position;
|
||||||
|
|
||||||
if (!successful)
|
if (successful != size)
|
||||||
return SV(NULL, 0);
|
return SV(NULL, 0);
|
||||||
|
|
||||||
char *ptr = NULL;
|
char *ptr = NULL;
|
||||||
|
|||||||
@@ -277,7 +277,109 @@ void stream_test_seek(void)
|
|||||||
void stream_test_substr(void)
|
void stream_test_substr(void)
|
||||||
{
|
{
|
||||||
TEST_START();
|
TEST_START();
|
||||||
TODO("Not implemented");
|
u64 size = rand() % (ARRSIZE(words_text) - 1);
|
||||||
|
u64 position = ARRSIZE(words_text) - size - 1;
|
||||||
|
|
||||||
|
// Taking substrings of invalid streams
|
||||||
|
{
|
||||||
|
stream_t stream = {0};
|
||||||
|
stream_init_file(&stream, NULL, invalid_fp);
|
||||||
|
|
||||||
|
// Relative
|
||||||
|
{
|
||||||
|
sv_t result = stream_substr(&stream, size);
|
||||||
|
TEST(result.data == NULL && result.size == 0,
|
||||||
|
"Relative substring with size %lu on invalid stream should be NULL",
|
||||||
|
size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Absolute
|
||||||
|
{
|
||||||
|
sv_t result = stream_substr_abs(&stream, position, size);
|
||||||
|
TEST(result.data == NULL && result.size == 0,
|
||||||
|
"Absolute substring @%lu with size %lu on invalid stream should be "
|
||||||
|
"NULL",
|
||||||
|
position, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
stream_stop(&stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Taking substrings of valid streams
|
||||||
|
{
|
||||||
|
stream_t stream = {0};
|
||||||
|
stream_init_file(&stream, valid_filename, valid_fp);
|
||||||
|
|
||||||
|
// Absolute
|
||||||
|
{
|
||||||
|
sv_t result = stream_substr_abs(&stream, position, size);
|
||||||
|
TEST(result.data && result.size,
|
||||||
|
"Absolute substring @%lu with size %lu on valid stream should be "
|
||||||
|
"nonzero",
|
||||||
|
position, size);
|
||||||
|
|
||||||
|
TEST(result.size == size, "Substring has right size (%lu)", result.size);
|
||||||
|
|
||||||
|
sv_t expected = SV((char *)words_text + position, size);
|
||||||
|
TEST(strncmp(result.data, expected.data, result.size) == 0,
|
||||||
|
"Expect the substring to be the same as the data we put in");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Relative
|
||||||
|
{
|
||||||
|
sv_t result = stream_substr(&stream, size);
|
||||||
|
TEST(result.data && result.size,
|
||||||
|
"Relative substring with size %lu should be nonzero", size);
|
||||||
|
|
||||||
|
TEST(result.size == size, "Substring has right size (%lu)", result.size);
|
||||||
|
|
||||||
|
sv_t expected = SV((char *)words_text, size);
|
||||||
|
TEST(strncmp(result.data, expected.data, result.size) == 0,
|
||||||
|
"Expect the substring to be the same as the data we put in");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Relative substring after seeking
|
||||||
|
{
|
||||||
|
// Shift forward to a random position
|
||||||
|
assert(stream_seek_forward(&stream, position)); // not a test
|
||||||
|
sv_t result = stream_substr(&stream, size);
|
||||||
|
TEST(result.data && result.size,
|
||||||
|
"Relative substring with size %lu after seeking %lu bytes should be "
|
||||||
|
"nonzero",
|
||||||
|
size, position);
|
||||||
|
|
||||||
|
TEST(result.size == size, "Substring has right size (%lu)", result.size);
|
||||||
|
|
||||||
|
sv_t expected = SV((char *)words_text + position, size);
|
||||||
|
TEST(strncmp(result.data, expected.data, result.size) == 0,
|
||||||
|
"Expect the substring to be the same as the data we put in");
|
||||||
|
|
||||||
|
// Shift back to the original position.
|
||||||
|
assert(stream_seek_backward(&stream, position)); // not a test
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bad substrings
|
||||||
|
{
|
||||||
|
{
|
||||||
|
sv_t result = stream_substr_abs(&stream, stream_size(&stream), 100);
|
||||||
|
TEST(!result.data && !result.size,
|
||||||
|
"Absolute substring at %lu of 100 bytes is invalid",
|
||||||
|
stream_size(&stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(stream_seek_forward(&stream, stream_size(&stream))); // not a test
|
||||||
|
{
|
||||||
|
sv_t result = stream_substr(&stream, 100);
|
||||||
|
TEST(!result.data && !result.size,
|
||||||
|
"Relative substring with size 100 after seeking %lu bytes is "
|
||||||
|
"invalid",
|
||||||
|
stream.position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stream_stop(&stream);
|
||||||
|
}
|
||||||
|
TEST_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
void stream_test_till(void)
|
void stream_test_till(void)
|
||||||
@@ -305,6 +407,7 @@ MAKE_TEST_SUITE(STREAM_SUITE, "Stream Tests",
|
|||||||
MAKE_TEST_FN(stream_test_file),
|
MAKE_TEST_FN(stream_test_file),
|
||||||
MAKE_TEST_FN(stream_test_peek_next),
|
MAKE_TEST_FN(stream_test_peek_next),
|
||||||
MAKE_TEST_FN(stream_test_seek),
|
MAKE_TEST_FN(stream_test_seek),
|
||||||
|
MAKE_TEST_FN(stream_test_substr),
|
||||||
MAKE_TEST_FN(stream_test_epilogue), );
|
MAKE_TEST_FN(stream_test_epilogue), );
|
||||||
|
|
||||||
/* Copyright (C) 2026 Aryadev Chavali
|
/* Copyright (C) 2026 Aryadev Chavali
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ void vec_test_concat(void)
|
|||||||
TEST_END();
|
TEST_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
void vec_test_substr(void)
|
void vec_test_gen_substr(void)
|
||||||
{
|
{
|
||||||
TEST_START();
|
TEST_START();
|
||||||
sys_t system = {0};
|
sys_t system = {0};
|
||||||
@@ -73,7 +73,8 @@ void vec_test_substr(void)
|
|||||||
|
|
||||||
MAKE_TEST_SUITE(VEC_SUITE, "Vector Tests",
|
MAKE_TEST_SUITE(VEC_SUITE, "Vector Tests",
|
||||||
|
|
||||||
MAKE_TEST_FN(vec_test_concat), MAKE_TEST_FN(vec_test_substr), );
|
MAKE_TEST_FN(vec_test_concat),
|
||||||
|
MAKE_TEST_FN(vec_test_gen_substr), );
|
||||||
|
|
||||||
/* Copyright (C) 2026 Aryadev Chavali
|
/* Copyright (C) 2026 Aryadev Chavali
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user