typedef signed int i32;
typedef signed long i64;
typedef signed long long i128;
+typedef unsigned long isize;
//-------------------------------------------------------------------------------------
// Better strings
//-------------------------------------------------------------------------------------
typedef enum bh_file_error {
- BH_FILE_ERROR_NONE
+ BH_FILE_ERROR_NONE,
+ BH_FILE_ERROR_INVALID
} bh_file_error;
typedef enum bh_file_mode {
} bh_file_mode;
typedef enum bh_file_whence {
- bh_file_whence_begin = 0,
- bh_file_whence_current = 1,
- bh_file_whence_end = 2,
+ BH_FILE_WHENCE_BEGIN = SEEK_SET,
+ BH_FILE_WHENCE_CURRENT = SEEK_CUR,
+ BH_FILE_WHENCE_END = SEEK_END,
} bh_file_whence;
typedef int bh_file_descriptor;
BH_FILE_STANDARD_ERROR
} bh_file_standard;
+typedef struct bh_file_contents {
+ // This will hold the allocator as well
+ isize length;
+ void* data;
+} bh_file_contents;
+
bh_file_error bh_file_get_standard(bh_file* file, bh_file_standard stand);
bh_file_error bh_file_create(bh_file* file, char const* filename);
bh_file_error bh_file_open(bh_file* file, char const* filename);
-bh_file_error bh_file_open_mode(bh_file* file, bh_file_mode mode, char const* filename);
-bh_file_error bh_file_new(bh_file* file, bh_file_descriptor fd, char const* filename);
+bh_file_error bh_file_open_mode(bh_file* file, bh_file_mode mode, const char* filename);
+bh_file_error bh_file_new(bh_file* file, bh_file_descriptor fd, const char* filename);
+i32 bh_file_read_at(bh_file* file, i64 offset, void* buffer, isize buff_size, isize* bytes_read);
+i32 bh_file_write_at(bh_file* file, i64 offset, void const* buffer, isize buff_size, isize* bytes_wrote);
+static i32 bh__file_seek_wrapper(i32 fd, i64 offset, bh_file_whence whence, i64* new_offset);
+i32 bh_file_seek(bh_file* file, i64 offset);
+i64 bh_file_seek_to_end(bh_file* file);
+i64 bh_file_skip(bh_file* file, i64 bytes);
+i64 bh_file_tell(bh_file* file);
+bh_file_error bh_file_close(bh_file* file);
+i32 bh_file_read(bh_file* file, void* buffer, isize buff_size);
+i32 bh_file_write(bh_file* file, void* buffer, isize buff_size);
+i64 bh_file_size(bh_file* file);
+
+#define bh_file_read_contents(x) _Generic((x), \
+ bh_file*: bh_file_read_contents_bh_file, \
+ const char*: bh_file_read_contents_direct, \
+ char*: bh_file_read_contents_direct)(x)
+
+bh_file_contents bh_file_read_contents_bh_file(bh_file* file);
+bh_file_contents bh_file_read_contents_direct(const char* filename);
+i32 bh_file_contents_delete(bh_file_contents* contents);
+
+
+
+
+
+
+
+
+
+
+
//-------------------------------------------------------------------------------------
// IMPLEMENTATIONS
//-------------------------------------------------------------------------------------
+//-------------------------------------------------------------------------------------
+// STRING IMPLEMENTATION
+//-------------------------------------------------------------------------------------
bh_string bh_string_new_cap(unsigned long cap) {
bh_string str;
str.data = (u8*) malloc(sizeof(u8) * cap);
write(STDOUT_FILENO, str->data, str->length);
}
+
+
+//-------------------------------------------------------------------------------------
+// FILE IMPLEMENTATION
+//-------------------------------------------------------------------------------------
+bh_file_error bh_file_get_standard(bh_file* file, bh_file_standard stand) {
+ i32 sd_fd = -1;
+ const char* filename = NULL;
+
+ switch (stand) {
+ case BH_FILE_STANDARD_INPUT:
+ sd_fd = STDIN_FILENO;
+ filename = "stdin"; // These are constants in the data section so everything should be okay
+ break;
+ case BH_FILE_STANDARD_OUTPUT:
+ sd_fd = STDOUT_FILENO;
+ filename = "stdout";
+ break;
+ case BH_FILE_STANDARD_ERROR:
+ sd_fd = STDERR_FILENO;
+ filename = "stderr";
+ break;
+ }
+
+ file->fd = sd_fd;
+ file->filename = filename;
+
+ return BH_FILE_ERROR_NONE;
+}
+
+bh_file_error bh_file_create(bh_file* file, const char* filename) {
+ // Need to do this to avoid compiler complaining about types
+ bh_file_mode write_rw = (bh_file_mode) (BH_FILE_MODE_WRITE | BH_FILE_MODE_RW);
+ return bh_file_open_mode(file, write_rw, filename);
+}
+
+bh_file_error bh_file_open(bh_file* file, const char* filename) {
+ return bh_file_open_mode(file, BH_FILE_MODE_READ, filename);
+}
+
+bh_file_error bh_file_open_mode(bh_file* file, bh_file_mode mode, const char* filename) {
+
+ i32 os_mode = 0;
+
+ switch (mode & BH_FILE_MODE_MODES) {
+ case BH_FILE_MODE_READ: os_mode = O_RDONLY; break;
+ case BH_FILE_MODE_WRITE: os_mode = O_WRONLY | O_CREAT | O_TRUNC; break;
+ case BH_FILE_MODE_APPEND: os_mode = O_RDONLY | O_APPEND | O_CREAT; break;
+ case BH_FILE_MODE_READ | BH_FILE_MODE_RW: os_mode = O_RDWR; break;
+ case BH_FILE_MODE_WRITE | BH_FILE_MODE_RW: os_mode = O_RDWR | O_CREAT | O_TRUNC; break;
+ case BH_FILE_MODE_APPEND | BH_FILE_MODE_RW: os_mode = O_RDWR | O_APPEND | O_CREAT; break;
+ //default: // TODO Handle errors
+ }
+
+ file->fd = open(filename, os_mode,
+ S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH | S_IRGRP | S_IWGRP //+rw-rw-rw-
+ );
+ if (file->fd < 0) {
+ return BH_FILE_ERROR_INVALID;
+ }
+
+ // TODO: Set this using some allocator
+ file->filename = filename;
+
+ return BH_FILE_ERROR_NONE;
+}
+
+bh_file_error bh_file_new(bh_file* file, bh_file_descriptor fd, const char* filename) {
+ file->filename = filename; // This may be unsafe
+ file->fd = fd;
+ return BH_FILE_ERROR_NONE;
+}
+
+i32 bh_file_read_at(bh_file* file, i64 offset, void* buffer, isize buff_size, isize* bytes_read) {
+ isize res = pread(file->fd, buffer, buff_size, offset);
+ if (res < 0) return 0;
+ if (bytes_read) *bytes_read = res;
+ return 1;
+}
+
+i32 bh_file_write_at(bh_file* file, i64 offset, void const* buffer, isize buff_size, isize* bytes_wrote) {
+ isize res;
+ i64 current_offset = 0;
+ bh__file_seek_wrapper(file->fd, offset, BH_FILE_WHENCE_CURRENT, ¤t_offset);
+ if (current_offset == offset) {
+ // Standard in and out do like pwrite()
+ res = write(file->fd, buffer, buff_size);
+ } else {
+ res = pwrite(file->fd, buffer, buff_size, offset);
+ }
+ if (res < 0) return 0;
+ if (bytes_wrote) *bytes_wrote = res;
+
+ return 1;
+}
+
+static i32 bh__file_seek_wrapper(i32 fd, i64 offset, bh_file_whence whence, i64* new_offset) {
+ i64 res = lseek(fd, offset, whence);
+ if (res < 0) return 0;
+ if (new_offset) *new_offset = res;
+ return 1;
+}
+
+// Returns new offset
+i64 bh_file_seek_to(bh_file* file, i64 offset) {
+ i64 new_offset = -1;
+ bh__file_seek_wrapper(file->fd, offset, BH_FILE_WHENCE_BEGIN, &new_offset);
+ return new_offset;
+}
+
+i64 bh_file_seek_to_end(bh_file* file) {
+ i64 new_offset = -1;
+ bh__file_seek_wrapper(file->fd, 0, BH_FILE_WHENCE_END, &new_offset);
+ return new_offset;
+}
+
+i64 bh_file_skip(bh_file* file, i64 bytes) {
+ i64 new_offset = 0;
+ bh__file_seek_wrapper(file->fd, bytes, BH_FILE_WHENCE_CURRENT, &new_offset);
+ return new_offset;
+}
+
+i64 bh_file_tell(bh_file* file) {
+ i64 new_offset = 0;
+ bh__file_seek_wrapper(file->fd, 0, BH_FILE_WHENCE_CURRENT, &new_offset);
+ return new_offset;
+}
+
+bh_file_error bh_file_close(bh_file* file) {
+ bh_file_error err = BH_FILE_ERROR_NONE;
+ i32 res = close(file->fd);
+ if (res < 0)
+ err = BH_FILE_ERROR_INVALID;
+
+ return err;
+}
+
+i32 bh_file_read(bh_file* file, void* buffer, isize buff_size) {
+ return bh_file_read_at(file, bh_file_tell(file), buffer, buff_size, NULL);
+}
+
+i32 bh_file_write(bh_file* file, void* buffer, isize buff_size) {
+ return bh_file_write_at(file, bh_file_tell(file), buffer, buff_size, NULL);
+}
+
+i64 bh_file_size(bh_file* file) {
+ i64 size = 0;
+ i64 prev = bh_file_tell(file);
+ bh_file_seek_to_end(file);
+ size = bh_file_tell(file);
+ bh_file_seek_to(file, prev);
+ return size;
+}
+
+bh_file_contents bh_file_read_contents_bh_file(bh_file* file) {
+ bh_file_contents fc = { .length = 0, .data = NULL };
+
+ isize size = bh_file_size(file);
+ if (size <= 0) return fc;
+
+ fc.data = malloc(size + 1);
+ fc.length = size;
+ bh_file_read_at(file, 0, fc.data, fc.length, NULL);
+ ((u8*) fc.data)[fc.length] = '\0';
+
+ return fc;
+}
+
+bh_file_contents bh_file_read_contents_direct(const char* filename) {
+ bh_file file;
+ bh_file_open(&file, filename);
+ bh_file_contents fc = bh_file_read_contents(&file);
+ bh_file_close(&file);
+ return fc;
+}
+
+i32 bh_file_contents_delete(bh_file_contents* contents) {
+ free(contents->data);
+ contents->length = 0;
+ return 1;
+}
#include <stdio.h> // TODO: Replace with custom lib
#include <stdlib.h> // TODO: Replace with custom lib
#include "bh.h"
-//
-// int main(int argc, char *argv[]) {
-// if (argc < 2) {
-// fprintf(stderr, "Expected file to compile\n");
-// return -1;
-// }
-//
-// File file;
-//
-// if (file_open(&file, argv[1], O_RDONLY)) {
-// fprintf(stderr, "Failed to open file: %s\n", argv[1]);
-// return -1;
-// }
-//
-// file_close(&file);
-//
-// return 0;
-// }
-//
int main(int argc, char *argv[]) {
- bh_string test_str = bh_string_new(256);
- bh_string world_str = bh_string_new("World FOO Bar test\n");
-
- bh_string_append(&test_str, "Hello Frank!\n");
- bh_string_replace_at(&test_str, &world_str, 6);
- bh_string_replace_at(&test_str, "Hola ", 0);
- bh_string_insert_at(&test_str, "World", 3);
- bh_string_print(&test_str);
-
- bh_string trim_str = bh_string_new("abcdeTesting words herezzzz\n \t");
- bh_string_print(&trim_str);
- bh_string_trim_begin(&trim_str, "abcde");
- bh_string_print(&trim_str);
- bh_string_trim_end_space(&trim_str);
- bh_string_print(&trim_str);
-
- bh_string_delete(&test_str);
- bh_string_delete(&world_str);
- bh_string_delete(&trim_str);
+ bh_file demofile;
+ bh_file_error err = bh_file_open(&demofile, argv[1]);
+ if (err != BH_FILE_ERROR_NONE) {
+ fprintf(stderr, "Failed to open file %s\n", argv[1]);
+ return EXIT_FAILURE;
+ }
+
+ bh_file_contents fc = bh_file_read_contents(&demofile);
+ printf("%ld: %s\n", fc.length, fc.data);
+
+ bh_file_contents_delete(&fc);
+ bh_file_close(&demofile);
+
+ // bh_string test_str = bh_string_new(256);
+ // bh_string world_str = bh_string_new("World FOO Bar test\n");
+
+ // bh_string_append(&test_str, "Hello Frank!\n");
+ // bh_string_replace_at(&test_str, &world_str, 6);
+ // bh_string_replace_at(&test_str, "Hola ", 0);
+ // bh_string_insert_at(&test_str, "World", 3);
+ // bh_string_print(&test_str);
+
+ // bh_string trim_str = bh_string_new("abcdeTesting words herezzzz\n \t");
+ // bh_string_print(&trim_str);
+ // bh_string_trim_begin(&trim_str, "abcde");
+ // bh_string_print(&trim_str);
+ // bh_string_trim_end_space(&trim_str);
+ // bh_string_print(&trim_str);
+
+ // bh_string_delete(&test_str);
+ // bh_string_delete(&world_str);
+ // bh_string_delete(&trim_str);
// bh_string file_contents = bh_file_read_contents("path");
return 0;
}
-
-// int main(int argc, char const *argv[]) {
-// FILE* file = fopen(argv[1], "r");
-// long start = ftell(file);
-// fseek(file, 0, SEEK_END);
-// long end = ftell(file);
-// fseek(file, 0, SEEK_SET);
-//
-//
-// char* data = (char *) malloc(sizeof(u8) * (end - start + 1));
-// read(file->, data, end - start);
-// fclose(file);
-// printf("%ld - %ld = %ld\n", end, start, end - start);
-// printf("%s", data);
-// }