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:
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