Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ bugprone-suspicious-missing-comma,
bugprone-suspicious-semicolon,
bugprone-suspicious-string-compare,
bugprone-suspicious-memory-comparison,
//bugprone-suspicious-realloc-usage,
bugprone-suspicious-realloc-usage,
bugprone-swapped-arguments,
bugprone-terminating-continue,
bugprone-throw-keyword-missing,
Expand Down
32 changes: 25 additions & 7 deletions src/array.c
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
#include <stdio.h>

#include "include/array.h"
#include "include/macros.h"
#include "include/memory.h"

size_t array_sizeof(void) {
return sizeof(array_T);
}

array_T* array_init(size_t capacity) {
array_T* array = (array_T*) malloc(sizeof(array_T));
array_T* array = safe_malloc(array_sizeof());

array->size = 0;
array->capacity = capacity;
array->items = (void**) malloc(sizeof(void*) * capacity);
array->items = nullable_safe_malloc(sizeof(void*) * capacity);

if (!array->items) {
free(array);
return NULL;
}

return array;
}

void array_append(array_T* array, void* item) {
if (array->size >= array->capacity) {
array->capacity *= 2;
array->items = (void**) realloc(array->items, sizeof(void*) * array->capacity);
size_t new_capacity = (array->capacity > 0) ? array->capacity * 2 : 1;
void* new_items = safe_realloc(array->items, sizeof(void*) * new_capacity);

if (unlikely(new_items == NULL)) return;

array->items = (void**) new_items;
array->capacity = new_capacity;
}

array->items[array->size] = item;
Expand Down Expand Up @@ -60,7 +74,11 @@ size_t array_capacity(array_T* array) {
return array->capacity;
}

void array_free(array_T* array) {
free(array->items);
free(array);
void array_free(array_T** array) {
if (!array || !(*array)) return;

free((*array)->items);
free(*array);

*array = NULL;
}
96 changes: 62 additions & 34 deletions src/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,28 @@
#include <string.h>

#include "include/buffer.h"
#include "include/macros.h"
#include "include/memory.h"

bool buffer_init(buffer_T* buffer) {
buffer->capacity = 1024;
buffer->length = 0;
buffer->value = malloc(buffer->capacity * sizeof(char));
buffer->value = nullable_safe_malloc(buffer->capacity * sizeof(char));

if (buffer->value) {
buffer->value[0] = '\0';
if (!buffer->value) {
fprintf(stderr, "Error: Failed to initialize buffer with capacity of %zu.\n", buffer->capacity);
return false;
}

return buffer != NULL;
buffer->value[0] = '\0';

return true;
}

buffer_T buffer_new(void) {
buffer_T buffer;
buffer_init(&buffer);
return buffer;
}

char* buffer_value(buffer_T* buffer) {
Expand All @@ -31,63 +42,80 @@ size_t buffer_sizeof(void) {
return sizeof(buffer_T);
}

bool buffer_increase_capacity(buffer_T* buffer, size_t required_length) {
size_t required_capacity = buffer->length + required_length;

if (buffer->capacity >= required_capacity) return true;

size_t new_capacity = required_capacity * 2;
char* new_value = safe_realloc(buffer->value, new_capacity);

if (unlikely(new_value == NULL)) return false;

buffer->value = new_value;
buffer->capacity = new_capacity;

return true;
}

void buffer_append(buffer_T* buffer, const char* text) {
if (!text || text[0] == '\0') return;

size_t text_length = strlen(text);

if (buffer->length + text_length >= buffer->capacity) {
size_t new_capacity = (buffer->length + text_length) * 2;
char* new_buffer = realloc(buffer->value, new_capacity);

if (new_buffer) {
buffer->value = new_buffer;
buffer->capacity = new_capacity;
} else {
printf("Couldn't allocate memory for new_buffer in buffer_append");
return;
}
}
if (!buffer_increase_capacity(buffer, text_length)) return;

strcat(buffer->value + buffer->length, text);
memcpy(buffer->value + buffer->length, text, text_length);
buffer->length += text_length;
buffer->value[buffer->length] = '\0';
}

void buffer_append_char(buffer_T* buffer, char character) {
if (!buffer_increase_capacity(buffer, 1)) return;

buffer->value[buffer->length] = character;
buffer->length++;
buffer->value[buffer->length] = '\0';
}

void buffer_prepend(buffer_T* buffer, const char* text) {
if (text == NULL || text[0] == '\0') return;
if (!text || text[0] == '\0') return;

size_t text_length = strlen(text);
size_t new_length = buffer->length + text_length;

if (new_length >= buffer->capacity) {
size_t new_capacity = new_length * 2;
buffer->value = realloc(buffer->value, new_capacity);
buffer->capacity = new_capacity;
}
if (!buffer_increase_capacity(buffer, text_length)) return;

memmove(buffer->value + text_length, buffer->value, buffer->length + 1);
memcpy(buffer->value, text, text_length);

buffer->length = new_length;
buffer->value[buffer->length] = '\0';
buffer->length += text_length;
}

void buffer_concat(buffer_T* destination, buffer_T* source) {
if (source->length == 0) return;
if (!buffer_increase_capacity(destination, source->length)) return;

size_t new_length = destination->length + source->length;
memcpy(destination->value + destination->length, source->value, source->length);
destination->length += source->length;
destination->value[destination->length] = '\0';
}

if (new_length >= destination->capacity) {
size_t new_capacity = new_length * 2;
destination->value = realloc(destination->value, new_capacity);
destination->capacity = new_capacity;
}
bool buffer_reserve(buffer_T* buffer, size_t min_capacity) {
size_t required_length = min_capacity - buffer->length;

strcat(destination->value + destination->length, source->value);
return buffer_increase_capacity(buffer, required_length);
}

destination->length = new_length;
void buffer_clear(buffer_T* buffer) {
buffer->length = 0;
buffer->value[0] = '\0';
}

void buffer_free(buffer_T* buffer) {
if (!buffer) return;

free(buffer->value);

buffer->value = NULL;
buffer->length = buffer->capacity = 0;
}
13 changes: 13 additions & 0 deletions src/erbx.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,24 @@ void erbx_lex_to_buffer(char* source, buffer_T* output) {
buffer_append(output, "\n");
}

erbx_free_tokens(&tokens);

// parser_T* parser = parser_init(lexer);
// AST_T* root = parser_parse(parser);
// printf("%zu\n", root->children->size);
}

void erbx_free_tokens(array_T** tokens) {
if (!tokens || !(*tokens)) return;

for (size_t i = 0; i < array_size(*tokens); i++) {
token_T* token = array_get(*tokens, i);
if (token) token_free(token);
}

array_free(tokens);
}

const char* erbx_version(void) {
return ERBX_VERSION;
}
2 changes: 1 addition & 1 deletion src/include/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void* array_get(array_T* array, size_t index);

void array_append(array_T* array, void* item);
void array_set(array_T* array, size_t index, void* item);
void array_free(array_T* array);
void array_free(array_T** array);
void array_remove(array_T* array, size_t index);

size_t array_capacity(array_T* array);
Expand Down
9 changes: 8 additions & 1 deletion src/include/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,23 @@ typedef struct BUFFER_STRUCT {
} buffer_T;

bool buffer_init(buffer_T* buffer);
buffer_T buffer_new(void);

bool buffer_increase_capacity(buffer_T* buffer, size_t required_length);
bool buffer_reserve(buffer_T* buffer, size_t min_capacity);

void buffer_append(buffer_T* buffer, const char* text);
void buffer_append_char(buffer_T* buffer, char character);
void buffer_prepend(buffer_T* buffer, const char* text);
void buffer_concat(buffer_T* destination, buffer_T* source);
void buffer_free(buffer_T* buffer);

char* buffer_value(buffer_T* buffer);

size_t buffer_length(buffer_T* buffer);
size_t buffer_capacity(buffer_T* buffer);
size_t buffer_sizeof(void);

void buffer_clear(buffer_T* buffer);
void buffer_free(buffer_T* buffer);

#endif
1 change: 1 addition & 0 deletions src/include/erbx.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ void erbx_lex_to_buffer(char* source, buffer_T* output);
array_T* erbx_lex(char* source);
array_T* erbx_lex_file(const char* path);
const char* erbx_version(void);
void erbx_free_tokens(array_T** tokens);

#endif
2 changes: 2 additions & 0 deletions src/include/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@

#define MIN(a, b) (a) < (b) ? (a) : (b)

#define unlikely(x) __builtin_expect(!!(x), 0)

#endif
12 changes: 12 additions & 0 deletions src/include/memory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef ERBX_MEMORY_H
#define ERBX_MEMORY_H

#include <stddef.h>

void* safe_malloc(size_t size);
void* safe_realloc(void* pointer, size_t new_size);

void* nullable_safe_malloc(size_t size);
void* nullable_safe_realloc(void* pointer, size_t new_size);

#endif
2 changes: 2 additions & 0 deletions src/include/token.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ int token_type(token_T* token);

size_t token_sizeof(void);

void token_free(token_T* token);

#endif
2 changes: 2 additions & 0 deletions src/include/util.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef ERBX_UTIL_H
#define ERBX_UTIL_H

#include <stdlib.h>

int is_whitespace(int character);
int is_newline(int character);

Expand Down
29 changes: 13 additions & 16 deletions src/io.c
Original file line number Diff line number Diff line change
@@ -1,33 +1,30 @@
#include "include/io.h"
#include "include/buffer.h"

#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

char* erbx_read_file(const char* filename) {
char* line = NULL;
size_t len = 0;
ssize_t read;
#define FILE_READ_CHUNK 4096

char* erbx_read_file(const char* filename) {
FILE* fp = fopen(filename, "rb");

if (fp == NULL) {
printf("Could not read file '%s'\n", filename);
fprintf(stderr, "Could not read file '%s'\n", filename);
exit(1);
}

char* buffer = (char*) calloc(1, sizeof(char));
buffer[0] = '\0';
buffer_T buffer = buffer_new();

char chunk[FILE_READ_CHUNK];
size_t bytes_read;

while ((read = getline(&line, &len, fp)) != -1) {
buffer = (char*) realloc(buffer, (strlen(buffer) + strlen(line) + 1) * sizeof(char));
strcat(buffer, line);
while ((bytes_read = fread(chunk, 1, FILE_READ_CHUNK, fp)) > 0) {
buffer_append(&buffer, chunk);
}

fclose(fp);

if (line) {
free(line);
}

return buffer;
return buffer_value(&buffer);
}
Loading