common: implement s_get_row and s_get_name in ivy_file

This commit is contained in:
2025-05-08 20:28:24 +01:00
parent 9f963c5757
commit bb55bee7f8
4 changed files with 77 additions and 6 deletions

View File

@@ -1,8 +1,44 @@
#include <blue/object/array.h>
#include <blue/object/string.h>
#include <errno.h>
#include <ivy/file.h> #include <ivy/file.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static enum ivy_status file_readline( static enum ivy_status get_name(
struct ivy_line_source *src, char *buf, size_t count, size_t *nr_read)
{
struct ivy_file *f = (struct ivy_file *)src;
*nr_read = snprintf(buf, count, "%s", f->f_path);
return IVY_OK;
}
static enum ivy_status get_row(
struct ivy_line_source *src, size_t row, char *buf, size_t count,
size_t *nr_read)
{
struct ivy_file *f = (struct ivy_file *)src;
size_t nr_rows = b_array_size(f->f_lines);
if (row > nr_rows) {
return IVY_ERR_EOF;
}
b_string *line = B_STRING(b_array_at(f->f_lines, row - 1));
const char *line_str = b_string_ptr(line);
size_t line_len = b_string_get_size(line, B_STRLEN_NORMAL);
size_t copy_len = b_min(ulong, count, line_len);
memcpy(buf, line_str, copy_len);
buf[copy_len] = 0;
buf[strcspn(buf, "\n")] = 0;
*nr_read = copy_len;
return IVY_OK;
}
static enum ivy_status readline(
struct ivy_line_source *src, char *buf, size_t count, size_t *nr_read, struct ivy_line_source *src, char *buf, size_t count, size_t *nr_read,
const char *prompt) const char *prompt)
{ {
@@ -16,27 +52,45 @@ static enum ivy_status file_readline(
return feof(f->f_fp) ? IVY_ERR_EOF : IVY_ERR_IO_FAILURE; return feof(f->f_fp) ? IVY_ERR_EOF : IVY_ERR_IO_FAILURE;
} }
b_string *line_str = b_string_create_from_cstr(buf);
b_array_append(f->f_lines, B_OBJECT(line_str));
b_string_release(line_str);
*nr_read = strlen(buf); *nr_read = strlen(buf);
return IVY_OK; return IVY_OK;
} }
struct ivy_file *ivy_file_from_fp(FILE *fp) enum ivy_status ivy_file_open(const char *path, struct ivy_file **out)
{ {
FILE *fp = fopen(path, "r");
if (!fp) {
return ivy_status_from_errno(errno);
}
struct ivy_file *file = malloc(sizeof *file); struct ivy_file *file = malloc(sizeof *file);
if (!file) { if (!file) {
return NULL; fclose(fp);
return IVY_ERR_NO_MEMORY;
} }
memset(file, 0x0, sizeof *file); memset(file, 0x0, sizeof *file);
file->f_base.s_get_name = get_name;
file->f_base.s_get_row = get_row;
file->f_base.s_readline = readline;
file->f_fp = fp; file->f_fp = fp;
file->f_base.s_readline = file_readline; file->f_path = b_strdup(path);
file->f_lines = b_array_create();
return file; *out = file;
return IVY_OK;
} }
void ivy_file_close(struct ivy_file *file) void ivy_file_close(struct ivy_file *file)
{ {
b_array_release(file->f_lines);
free(file->f_path);
fclose(file->f_fp); fclose(file->f_fp);
free(file); free(file);
} }

View File

@@ -5,12 +5,16 @@
#include <ivy/misc.h> #include <ivy/misc.h>
#include <stdio.h> #include <stdio.h>
struct b_array;
struct ivy_file { struct ivy_file {
struct ivy_line_source f_base; struct ivy_line_source f_base;
struct b_array *f_lines;
char *f_path;
FILE *f_fp; FILE *f_fp;
}; };
IVY_API struct ivy_file *ivy_file_from_fp(FILE *fp); IVY_API enum ivy_status ivy_file_open(const char *path, struct ivy_file **out);
IVY_API void ivy_file_close(struct ivy_file *file); IVY_API void ivy_file_close(struct ivy_file *file);
#endif #endif

View File

@@ -21,5 +21,6 @@ enum ivy_status {
IVY_API const char *ivy_status_to_string(enum ivy_status status); IVY_API const char *ivy_status_to_string(enum ivy_status status);
IVY_API enum ivy_status ivy_status_from_b_status(enum b_status status); IVY_API enum ivy_status ivy_status_from_b_status(enum b_status status);
IVY_API enum ivy_status ivy_status_from_errno(int err);
#endif #endif

View File

@@ -1,4 +1,5 @@
#include <blue/core/status.h> #include <blue/core/status.h>
#include <errno.h>
#include <ivy/status.h> #include <ivy/status.h>
#define ENUM_STR(x) \ #define ENUM_STR(x) \
@@ -34,3 +35,14 @@ enum ivy_status ivy_status_from_b_status(enum b_status status)
return IVY_ERR_INTERNAL_FAILURE; return IVY_ERR_INTERNAL_FAILURE;
} }
} }
enum ivy_status ivy_status_from_errno(int err)
{
switch (err) {
ENUM_CONVERT(0, IVY_OK);
ENUM_CONVERT(ENOENT, IVY_ERR_NO_ENTRY);
ENUM_CONVERT(ENOMEM, IVY_ERR_NO_MEMORY);
default:
return IVY_ERR_INTERNAL_FAILURE;
}
}