From cbd863960542092afedcfccd46a986bb36bc9e42 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Wed, 13 Nov 2024 21:36:37 +0000 Subject: [PATCH] common: add generic input-line interface, and an implementation of it for text files --- common/file.c | 42 ++++++++++++++++++++++++++++++++ common/include/ivy/file.h | 15 ++++++++++++ common/include/ivy/line-source.h | 12 +++------ common/include/ivy/status.h | 15 ++++++++++++ common/line-source.c | 4 +-- common/status.c | 19 +++++++++++++++ 6 files changed, 96 insertions(+), 11 deletions(-) create mode 100644 common/file.c create mode 100644 common/include/ivy/file.h create mode 100644 common/include/ivy/status.h create mode 100644 common/status.c diff --git a/common/file.c b/common/file.c new file mode 100644 index 0000000..ec003f4 --- /dev/null +++ b/common/file.c @@ -0,0 +1,42 @@ +#include +#include +#include + +static enum ivy_status file_readline( + struct ivy_line_source *src, char *buf, size_t count, size_t *nr_read, + const char *prompt) +{ + if (!count) { + *nr_read = 0; + return IVY_OK; + } + + struct ivy_file *f = (struct ivy_file *)src; + if (!fgets(buf, count, f->f_fp)) { + return feof(f->f_fp) ? IVY_ERR_EOF : IVY_ERR_IO_FAILURE; + } + + *nr_read = strlen(buf); + return IVY_OK; +} + +struct ivy_file *ivy_file_from_fp(FILE *fp) +{ + struct ivy_file *file = malloc(sizeof *file); + if (!file) { + return NULL; + } + + memset(file, 0x0, sizeof *file); + + file->f_fp = fp; + file->f_base.s_readline = file_readline; + + return file; +} + +void ivy_file_close(struct ivy_file *file) +{ + fclose(file->f_fp); + free(file); +} diff --git a/common/include/ivy/file.h b/common/include/ivy/file.h new file mode 100644 index 0000000..35b3260 --- /dev/null +++ b/common/include/ivy/file.h @@ -0,0 +1,15 @@ +#ifndef IVY_COMMON_FILE_H_ +#define IVY_COMMON_FILE_H_ + +#include +#include + +struct ivy_file { + struct ivy_line_source f_base; + FILE *f_fp; +}; + +extern struct ivy_file *ivy_file_from_fp(FILE *fp); +extern void ivy_file_close(struct ivy_file *file); + +#endif diff --git a/common/include/ivy/line-source.h b/common/include/ivy/line-source.h index c0223d9..656a50d 100644 --- a/common/include/ivy/line-source.h +++ b/common/include/ivy/line-source.h @@ -1,21 +1,15 @@ #ifndef IVY_COMMON_LINE_SOURCE_H_ #define IVY_COMMON_LINE_SOURCE_H_ +#include #include -enum ivy_line_source_status { - IVY_LS_OK = 0, - IVY_LS_EOF, - IVY_LS_ERR_IOERR, - IVY_LS_ERR_NOSYS, -}; - struct ivy_line_source { - enum ivy_line_source_status (*s_readline)( + enum ivy_status (*s_readline)( struct ivy_line_source *, char *, size_t, size_t *, const char *); }; -extern enum ivy_line_source_status ivy_line_source_readline( +extern enum ivy_status ivy_line_source_readline( struct ivy_line_source *src, char *buf, size_t count, size_t *nr_read, const char *prompt); diff --git a/common/include/ivy/status.h b/common/include/ivy/status.h new file mode 100644 index 0000000..02046c4 --- /dev/null +++ b/common/include/ivy/status.h @@ -0,0 +1,15 @@ +#ifndef IVY_COMMON_STATUS_H_ +#define IVY_COMMON_STATUS_H_ + +enum ivy_status { + IVY_OK = 0, + IVY_ERR_EOF = -1, + IVY_ERR_IO_FAILURE = -2, + IVY_ERR_BAD_SYNTAX = -3, + IVY_ERR_NO_MEMORY = -4, + IVY_ERR_NOT_SUPPORTED = -5, +}; + +extern const char *ivy_status_to_string(enum ivy_status status); + +#endif diff --git a/common/line-source.c b/common/line-source.c index ff872ff..eb69ca3 100644 --- a/common/line-source.c +++ b/common/line-source.c @@ -1,6 +1,6 @@ #include -enum ivy_line_source_status ivy_line_source_readline( +enum ivy_status ivy_line_source_readline( struct ivy_line_source *src, char *buf, size_t count, size_t *nr_read, const char *prompt) { @@ -8,5 +8,5 @@ enum ivy_line_source_status ivy_line_source_readline( return src->s_readline(src, buf, count, nr_read, prompt); } - return IVY_LS_ERR_NOSYS; + return IVY_ERR_NOT_SUPPORTED; } diff --git a/common/status.c b/common/status.c new file mode 100644 index 0000000..64738d2 --- /dev/null +++ b/common/status.c @@ -0,0 +1,19 @@ +#include + +#define ENUM_STR(x) \ + case x: \ + return #x + +const char *ivy_status_to_string(enum ivy_status status) +{ + switch (status) { + ENUM_STR(IVY_OK); + ENUM_STR(IVY_ERR_EOF); + ENUM_STR(IVY_ERR_IO_FAILURE); + ENUM_STR(IVY_ERR_BAD_SYNTAX); + ENUM_STR(IVY_ERR_NO_MEMORY); + ENUM_STR(IVY_ERR_NOT_SUPPORTED); + default: + return ""; + } +}