diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | include/ui_utils.h | 151 | ||||
-rw-r--r-- | library/base_components.c | 21 | ||||
-rw-r--r-- | library/meson.build | 7 | ||||
-rw-r--r-- | library/renderer.c | 19 | ||||
-rw-r--r-- | library/tree.c | 16 | ||||
-rw-r--r-- | library/ui.c | 3 | ||||
-rw-r--r-- | meson.build | 23 | ||||
-rw-r--r-- | uicc/main.c | 9 | ||||
-rw-r--r-- | uicc/meson.build | 8 | ||||
-rw-r--r-- | uicc/reader.c | 37 | ||||
-rw-r--r-- | uicc/tokenizer.c | 15 |
12 files changed, 311 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bc95448 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.cache/ +build/ diff --git a/include/ui_utils.h b/include/ui_utils.h new file mode 100644 index 0000000..5510433 --- /dev/null +++ b/include/ui_utils.h @@ -0,0 +1,151 @@ +#ifndef UI_UTILS +#define UI_UTILS + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <errno.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <unistd.h> + +#ifdef _GNU_SOURCE +#include <stdalign.h> +#endif + +#define UI_INTERNAL static +#define UI_GLOBAL + +typedef signed char i8; +typedef unsigned char u8; +typedef signed short int i16; +typedef unsigned short int u16; +typedef signed int i32; +typedef unsigned int u32; +typedef signed long int i64; +typedef unsigned long int u64; + +UI_INTERNAL void __crash_error(const char *message, const char *file, + u32 line) { + fprintf(stderr, "(%s:%d): %s\n", file, line, message); + exit(1); +} + +#define crash_error(message) __crash_error(message, __FILE__, __LINE__) +#define crash_errno() __crash_error(strerror(errno), __FILE__, __LINE__) + +#define assert_mmap(expr) \ + if ((expr) == MAP_FAILED) \ + crash_errno() + +#define assert_errno(expr) \ + if (errno != 0) \ + crash_errno() + +#define assert_success(actual, expected) \ + if ((actual) != expected) \ + crash_error("assertion failed") + +#define assert_failure(actual, expected) \ + if ((actual) == expected) \ + crash_error("assertion failed") + +typedef struct { + uint64_t size; + const char *buf; +} String; + +String string_slice(const char *cStr) { + String str = {0}; + str.size = strlen(cStr); + str.buf = cStr; + + return str; +} + +typedef struct { + u64 size; + u64 capacity; + u8 *buffer; +} Arena; + +Arena *arena_init(void) { + Arena *arena = malloc(sizeof(Arena)); + size_t page_size = sysconf(_SC_PAGE_SIZE); + arena->capacity = page_size * 4; + + assert_mmap(arena->buffer = mmap(0, arena->capacity, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, 0, 0)); + + return arena; +} + +void *arena_alloc(Arena *arena, u64 size, u8 align) { + void *mem; + u8 offset; + + u64 available = arena->capacity - arena->size; + if (size > available) { + assert_mmap(arena->buffer = mremap(arena->buffer, arena->size, + arena->size + (available * 2), 0)); + } + + mem = &(arena->buffer[arena->size]); + offset = (u64)mem % align; + mem = (void *)((u64)mem + offset); + arena->size += size + offset; + return mem; +} + +void arena_zero(Arena *arena) { + arena->size = 0; + memset(arena->buffer, 0, arena->size); +} + +void arena_free(Arena *arena) { + if (munmap(arena->buffer, arena->capacity) == -1) { + crash_error("can't unmap arena"); + } + + arena->buffer = 0; + arena->size = 0; + arena->capacity = 0; +} + +typedef struct { + Arena *arena; + u64 initial; +} ArenaTemp; + +ArenaTemp *arena_temp(Arena *arena) { + ArenaTemp *temp = malloc(sizeof(ArenaTemp)); + temp->arena = arena; + temp->initial = arena->size; + + return temp; +} + +void arena_temp_free(ArenaTemp *temp) { + temp->arena->size = temp->initial; + free(temp); +} + +#if __STDC_VERSION__ >= 202311L +#define arena_type(arena, type) \ + (type *)(arena_alloc(arena, sizeof(type), alignof(type))) +#define arena_array(arena, type, size) \ + (type *)(arena_alloc(arena, sizeof(type) * size, alignof(type))) +#elif __STDC_VERSION__ >= 201112L +(type *)(arena_alloc(arena, sizeof(type), _Alignof(type))) +#define arena_array(arena, type, size) \ + (type *)(arena_alloc(arena, sizeof(type) * size, _Alignof(type))) +#else +#define arena_type(arena, type) \ + (type *)(arena_alloc(arena, sizeof(type), __alignof__(type))) +#define arena_array(arena, type, size) \ + (type *)(arena_alloc(arena, sizeof(type) * size, __alignof__(type))) +#endif + +#endif diff --git a/library/base_components.c b/library/base_components.c new file mode 100644 index 0000000..fb49d2b --- /dev/null +++ b/library/base_components.c @@ -0,0 +1,21 @@ +#include <utils.h> + +typedef struct { + String label; +} Button; + +typedef struct { + String value; +} Text; + +typedef struct { + String value; +} TextInput; + +typedef struct { + Node *children +} ListBox; + +typedef struct { + Node *children +} Stack; diff --git a/library/meson.build b/library/meson.build new file mode 100644 index 0000000..deae140 --- /dev/null +++ b/library/meson.build @@ -0,0 +1,7 @@ +uil_include = include_directories('include') + +sources = files( + 'layout.c', +) + +uil = library('ui', sources) diff --git a/library/renderer.c b/library/renderer.c new file mode 100644 index 0000000..55bedb7 --- /dev/null +++ b/library/renderer.c @@ -0,0 +1,19 @@ +#include <utils.h> + +// TODO(roberto): support more pixel formats, for now we're assuming BGRA +typedef struct { + u16 width; + u16 height; + u16 stride; + u16 bpp; + u8 *bytes; +} PixelBuffer; + +typedef enum { + SOFTWARE, +} RendererType; + +typedef struct { + RenderType type; + void *renderer; +} Renderer; diff --git a/library/tree.c b/library/tree.c new file mode 100644 index 0000000..0519767 --- /dev/null +++ b/library/tree.c @@ -0,0 +1,16 @@ +#include <utils.h> + +typedef struct { + Node *parent; + u64 nodeType; + void *value; +} Node; + +typedef struct { + void *page; +} TreeAllocator; + +typedef struct { + TreeAllocator allocactor; + Node *root; +} Tree; diff --git a/library/ui.c b/library/ui.c new file mode 100644 index 0000000..213fb57 --- /dev/null +++ b/library/ui.c @@ -0,0 +1,3 @@ +typedef struct { + Tree tree; +} UIContext; diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..69b23a7 --- /dev/null +++ b/meson.build @@ -0,0 +1,23 @@ +project( + 'ui', + 'c', + meson_version: '>= 1.3.0', + version: '0.1', + default_options: ['warning_level=3', 'c_std=c89'], +) + +compile_args = [] +if host_machine.system() == 'linux' + compile_args += ['-D_GNU_SOURCE'] +elif host_machine.system() == 'darwin' + compile_args += ['-D_DARWIN_C_SOURCE'] +elif host_machine.system() == 'windows' + compile_args += ['-D_WIN32_WINNT=0x0601'] +endif + +add_global_arguments(compile_args, language: ['c']) + +ui_include = include_directories('include') + +subdir('library') +subdir('uicc') diff --git a/uicc/main.c b/uicc/main.c new file mode 100644 index 0000000..6f0d276 --- /dev/null +++ b/uicc/main.c @@ -0,0 +1,9 @@ +#include "arena.c" +#include "reader.c" +#include "tokenizer.c" +#include "utils.c" + +int main(int argc, char **argv) { + printf("teste: %s\n", argv[0]); + return 0; +} diff --git a/uicc/meson.build b/uicc/meson.build new file mode 100644 index 0000000..9696dba --- /dev/null +++ b/uicc/meson.build @@ -0,0 +1,8 @@ +preprocessorSources = files('main.c', 'reader.c', 'tokenizer.c') + +executable( + 'uicc', + preprocessorSources, + include_directories: ui_include, + install: true, +) diff --git a/uicc/reader.c b/uicc/reader.c new file mode 100644 index 0000000..ea21b82 --- /dev/null +++ b/uicc/reader.c @@ -0,0 +1,37 @@ +#include <ui_utils.h> + +typedef struct { + int fd; + uint64_t buffer_size; + char *buffer; +} Reader; + +Reader *reader_open(Arena *arena, const char *path, uint64_t buffer_size) { + Reader *reader = {0}; + int fd; + + assert_failure(fd = open(path, O_RDONLY, O_NOFOLLOW), -1); + + reader = arena_type(arena, Reader); + reader->fd = fd; + reader->buffer_size = buffer_size; + reader->buffer = arena_array(arena, char, reader->buffer_size); + + return reader; +} + +void reader_advance(Reader *self, uint32_t *start, uint32_t *end) { + if (*end > self->buffer_size) { + if (*start == 0) { + /* TODO(roberto): maybe reallocate the buffer instead of crashing */ + crash_error("ERROR: token is too long\n"); + } + + assert_errno(lseek(self->fd, *start * -1, SEEK_CUR)); + assert_errno(read(self->fd, self->buffer, self->buffer_size)); + *end -= *start; + *start = 0; + } +} + +void reader_close(Reader *self) { close(self->fd); } diff --git a/uicc/tokenizer.c b/uicc/tokenizer.c new file mode 100644 index 0000000..90ac274 --- /dev/null +++ b/uicc/tokenizer.c @@ -0,0 +1,15 @@ +/** + * Definição de elemento + * Elemento { + * propriedade: valor + * } + * + * Definição do layout + * <ContainerList> + * <Button label="Olá"> + * </ContainerList> + */ + +#include "reader.c" + +void tokenizeElement(int fd) {} |