bshell: re-organise build into three separate components
bshell: the front-end binary bshell.runtime: contains the parser, compiler, and classes needed to run bshell scripts bshell.core: contains the builtin commandlets and aliases
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
#include <bshell/file.h>
|
||||
#include <bshell/line-source.h>
|
||||
#include <errno.h>
|
||||
#include <fx/collections/array.h>
|
||||
#include <fx/string.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static enum bshell_status get_name(
|
||||
struct bshell_line_source *src,
|
||||
char *buf,
|
||||
size_t count,
|
||||
size_t *nr_read)
|
||||
{
|
||||
struct bshell_file *f = (struct bshell_file *)src;
|
||||
*nr_read = snprintf(buf, count, "%s", f->f_path);
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
static enum bshell_status get_row(
|
||||
struct bshell_line_source *src,
|
||||
size_t row,
|
||||
char *buf,
|
||||
size_t count,
|
||||
size_t *nr_read)
|
||||
{
|
||||
struct bshell_file *f = (struct bshell_file *)src;
|
||||
size_t nr_rows = fx_array_get_size(f->f_lines);
|
||||
|
||||
if (row > nr_rows) {
|
||||
return BSHELL_ERR_EOF;
|
||||
}
|
||||
|
||||
fx_value *line_v = fx_array_get_ref(f->f_lines, row - 1);
|
||||
fx_string *line = NULL;
|
||||
fx_value_get_object(line_v, &line);
|
||||
|
||||
const char *line_str = fx_string_get_cstr(line);
|
||||
size_t line_len = fx_string_get_size(line, FX_STRLEN_NORMAL);
|
||||
size_t copy_len = fx_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 BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
static enum bshell_status readline(
|
||||
struct bshell_line_source *src,
|
||||
fx_stringstream *out)
|
||||
{
|
||||
struct bshell_file *f = (struct bshell_file *)src;
|
||||
fx_wchar c = FX_WCHAR_INVALID;
|
||||
size_t nr_read = 0;
|
||||
|
||||
while (1) {
|
||||
fx_status status = fx_stream_read_char(f->f_strp, &c);
|
||||
if (!FX_OK(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
fx_stream_write_char(out, c);
|
||||
nr_read++;
|
||||
|
||||
if (c == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nr_read == 0) {
|
||||
return BSHELL_ERR_EOF;
|
||||
}
|
||||
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
enum bshell_status bshell_file_open(const char *path, struct bshell_file **out)
|
||||
{
|
||||
FILE *fp = fopen(path, "r");
|
||||
if (!fp) {
|
||||
return bshell_status_from_errno(errno);
|
||||
}
|
||||
|
||||
fx_stream *strp = fx_stream_open_fp(fp);
|
||||
|
||||
struct bshell_file *file = malloc(sizeof *file);
|
||||
if (!file) {
|
||||
fclose(fp);
|
||||
return BSHELL_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
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_strp = strp;
|
||||
file->f_path = fx_strdup(path);
|
||||
file->f_lines = fx_array_create();
|
||||
|
||||
*out = file;
|
||||
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
void bshell_file_close(struct bshell_file *file)
|
||||
{
|
||||
fx_stream_unref(file->f_strp);
|
||||
fx_array_unref(file->f_lines);
|
||||
free(file->f_path);
|
||||
fclose(file->f_fp);
|
||||
free(file);
|
||||
}
|
||||
Reference in New Issue
Block a user