rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

commit ed5668b03ee713717d24a0bcaf4493f2d19393da
parent 52c2b9d8035ffeebd47a8e28ede76b541dba9214
Author: vaplv <vaplv@free.fr>
Date:   Fri, 29 Nov 2019 10:59:49 +0100

Rename the txtrdr_create function in txtrdr_stream

Add the txtrdr_file function

Diffstat:
Msrc/test_text_reader.c | 59+++++++++++++++++++++++++++++++++++++----------------------
Msrc/text_reader.c | 33++++++++++++++++++++++++++++++++-
Msrc/text_reader.h | 11+++++++++--
3 files changed, 78 insertions(+), 25 deletions(-)

diff --git a/src/test_text_reader.c b/src/test_text_reader.c @@ -37,6 +37,29 @@ static const char* text[] = { }; static const size_t nlines = sizeof(text)/sizeof(const char*); +static void +check_text_reader(struct txtrdr* txtrdr) +{ + size_t iline = 0; + + CHK(txtrdr_read_line(txtrdr) == RES_OK); + while(txtrdr_get_line(txtrdr)) { + + /* Discard empty line */ + while(strcspn(text[iline], "#\n") == strspn(text[iline], " \t")) ++iline; + + CHK(!strncmp(txtrdr_get_line(txtrdr), text[iline], strcspn(text[iline], "#\n"))); + CHK(txtrdr_get_line_num(txtrdr) == iline); + CHK(txtrdr_read_line(txtrdr) == RES_OK); + ++iline; + } + CHK(txtrdr_get_line_num(txtrdr) == nlines-1); + CHK(txtrdr_read_line(txtrdr) == RES_OK); + CHK(txtrdr_get_line(txtrdr) == NULL); + CHK(txtrdr_get_line_num(txtrdr) == nlines-1); + CHK(txtrdr_read_line(txtrdr) == RES_OK); +} + int main(int argc, char** argv) { @@ -44,43 +67,35 @@ main(int argc, char** argv) struct txtrdr* txtrdr = NULL; size_t i; FILE* stream; + const char* filename = "test_text_reader.txt"; + const char* stream_name = "my_stream"; (void)argc, (void)argv; mem_init_proxy_allocator(&allocator, &mem_default_allocator); /* Write the text into a stream */ - CHK(stream = tmpfile()); + CHK(stream = fopen(filename, "w+")); FOR_EACH(i, 0, nlines) { const size_t len = strlen(text[i]); CHK(fwrite(text[i], 1, len, stream) == len); } - rewind(stream); - CHK(txtrdr_create(NULL, stream, NULL, '#', &txtrdr) == RES_OK); + rewind(stream); + CHK(txtrdr_stream(NULL, stream, NULL, '#', &txtrdr) == RES_OK); + check_text_reader(txtrdr); txtrdr_ref_get(txtrdr); txtrdr_ref_put(txtrdr); txtrdr_ref_put(txtrdr); - CHK(txtrdr_create(&allocator, stream, "my_stream", '#', &txtrdr) == RES_OK); - CHK(!strcmp(txtrdr_get_name(txtrdr), "my_stream")); - - i = 0; - CHK(txtrdr_read_line(txtrdr) == RES_OK); - while(txtrdr_get_line(txtrdr)) { - - while(strcspn(text[i], "#\n") == strspn(text[i], " \t")) ++i; - - CHK(!strncmp(txtrdr_get_line(txtrdr), text[i], strcspn(text[i], "#\n"))); - CHK(txtrdr_get_line_num(txtrdr) == i); - CHK(txtrdr_read_line(txtrdr) == RES_OK); - ++i; - } - CHK(txtrdr_get_line_num(txtrdr) == nlines-1); - CHK(txtrdr_read_line(txtrdr) == RES_OK); - CHK(txtrdr_get_line(txtrdr) == NULL); - CHK(txtrdr_get_line_num(txtrdr) == nlines-1); - CHK(txtrdr_read_line(txtrdr) == RES_OK); + rewind(stream); + CHK(txtrdr_stream(&allocator, stream, stream_name, '#', &txtrdr) == RES_OK); + CHK(!strcmp(txtrdr_get_name(txtrdr), stream_name)); + check_text_reader(txtrdr); + txtrdr_ref_put(txtrdr); + CHK(txtrdr_file(&allocator, filename, '#', &txtrdr) == RES_OK); + CHK(!strcmp(txtrdr_get_name(txtrdr), filename)); + check_text_reader(txtrdr); txtrdr_ref_put(txtrdr); fclose(stream); diff --git a/src/text_reader.c b/src/text_reader.c @@ -32,6 +32,10 @@ struct txtrdr { /* String of chars from which the remaining line chars are skipped */ char reject[3]; + /* Boolean defining if the stream is internally managed or not, i.e. if it + * has to be closed on text_reader release or not */ + int manage_stream; + struct mem_allocator* allocator; ref_T ref; }; @@ -47,6 +51,7 @@ release_txtrdr(ref_T* ref) txtrdr = CONTAINER_OF(ref, struct txtrdr, ref); str_release(&txtrdr->name); darray_char_release(&txtrdr->line); + if(txtrdr->stream && txtrdr->manage_stream) fclose(txtrdr->stream); MEM_RM(txtrdr->allocator, txtrdr); } @@ -54,7 +59,7 @@ release_txtrdr(ref_T* ref) * Text reader API ******************************************************************************/ res_T -txtrdr_create +txtrdr_stream (struct mem_allocator* mem_allocator, FILE* stream, const char* name, @@ -99,6 +104,32 @@ error: goto exit; } +res_T +txtrdr_file + (struct mem_allocator* mem_allocator, + const char* filename, + const char comment, + struct txtrdr** out_txtrdr) +{ + FILE* fp = NULL; + res_T res = RES_OK; + ASSERT(filename); + + fp = fopen(filename, "r"); + if(!fp) { res = RES_IO_ERR; goto error; } + + res = txtrdr_stream(mem_allocator, fp, filename, comment, out_txtrdr); + if(res != RES_OK) goto error; + + (*out_txtrdr)->manage_stream = 1; + +exit: + return res; +error: + if(fp) fclose(fp); + goto exit; +} + void txtrdr_ref_get(struct txtrdr* txtrdr) { diff --git a/src/text_reader.h b/src/text_reader.h @@ -24,11 +24,18 @@ struct mem_allocator; BEGIN_DECLS RSYS_API res_T -txtrdr_create +txtrdr_file + (struct mem_allocator* allocator, /* May be NULL <=> default allocator */ + const char* filename, + const char comment, /* Char preceeding a comment */ + struct txtrdr** txtrdr); + +RSYS_API res_T +txtrdr_stream (struct mem_allocator* allocator, /* May be NULL <=> default allocator */ FILE* stream, const char* name, /* Stream name. May be NULL */ - const char comment, /* Char defining preceeding a comment */ + const char comment, /* Char preceeding a comment */ struct txtrdr** txtrdr); RSYS_API void