Compare commits

...

6 Commits

Author SHA1 Message Date
Aryadev Chavali
0eb828251c alisp: add TODO for sv_t 2026-02-06 06:07:18 +00:00
Aryadev Chavali
3b66a08d63 test_stream: implement stream_test_substr 2026-02-06 06:06:22 +00:00
Aryadev Chavali
c0c5e3d77a test_vec: vec_test_substr -> vec_test_gen_substr 2026-02-06 06:05:57 +00:00
Aryadev Chavali
5408fd8101 main: put stream_stop before FILE pointer close
As stream_stop requires a valid FILE pointer (fseek), we need to do it
before we close the pipe.
2026-02-06 06:05:26 +00:00
Aryadev Chavali
35a33c7d24 stream: stream_substr's call to stream_seek_forward refactored
Following stream_seek_forward's own refactor, where we get offsets
back instead of just a boolean, we should verify that offset.
2026-02-06 06:04:41 +00:00
Aryadev Chavali
80813462be stream: ensure stream_stop resets the FILE pointer if STREAM_TYPE_FILE 2026-02-06 06:04:34 +00:00
5 changed files with 122 additions and 8 deletions

View File

@@ -70,7 +70,7 @@ Also ensure stream_eoc is false.
- Seeking forward/backward on a bad stream (should stop at 0)
- Seeking forward/backward too far (should clamp)
- 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)]]
- Substr on bad stream (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
possible options a bit (potentially we could design a better hashing
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
*** DONE Test value constructors and destructors :test:
Test if ~make_int~ works with ~as_int,~ ~intern~ with ~as_sym~.

View File

@@ -69,9 +69,9 @@ int main(int argc, char *argv[])
LOG("[INFO]: Initialised stream for `%s`\n", stream.name);
end:
stream_stop(&stream);
if (pipe)
fclose(pipe);
stream_stop(&stream);
return ret;
}

View File

@@ -5,6 +5,7 @@
* Commentary:
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -95,8 +96,11 @@ void stream_stop(stream_t *stream)
case STREAM_TYPE_STRING:
free(stream->string.data);
break;
case STREAM_TYPE_PIPE:
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
vec_free(&stream->pipe.cache);
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
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
stream->position = current_position;
if (!successful)
if (successful != size)
return SV(NULL, 0);
char *ptr = NULL;

View File

@@ -277,7 +277,109 @@ void stream_test_seek(void)
void stream_test_substr(void)
{
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)
@@ -305,6 +407,7 @@ MAKE_TEST_SUITE(STREAM_SUITE, "Stream Tests",
MAKE_TEST_FN(stream_test_file),
MAKE_TEST_FN(stream_test_peek_next),
MAKE_TEST_FN(stream_test_seek),
MAKE_TEST_FN(stream_test_substr),
MAKE_TEST_FN(stream_test_epilogue), );
/* Copyright (C) 2026 Aryadev Chavali

View File

@@ -37,7 +37,7 @@ void vec_test_concat(void)
TEST_END();
}
void vec_test_substr(void)
void vec_test_gen_substr(void)
{
TEST_START();
sys_t system = {0};
@@ -73,7 +73,8 @@ void vec_test_substr(void)
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