Move os layer to be part of the core

This commit is contained in:
2025-02-24 00:30:25 +00:00
parent 4520f2269d
commit 1479c13417
28 changed files with 20 additions and 38 deletions

133
src/core/os/cpath/cpath.c Normal file
View File

@@ -0,0 +1,133 @@
#include "cpath.h"
#include "aliases.h"
#include "mem_allocator.h"
#include "mem_arena_allocator.h"
#include "misc_utils.h"
#include "str8.h"
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts) {
if (!dst || !parts) {
return CPATH_JOIN_INVALID_ARGS;
}
if (parts->node_count == 0) {
return CPATH_JOIN_EMPTY_PARTS;
}
Str8 separator = wapp_str8_buf(4);
wapp_str8_push_back(&separator, PATH_SEP);
u64 required_capacity = parts->node_count * separator.size + parts->total_size;
if (dst->capacity < required_capacity) {
return CPATH_JOIN_INSUFFICIENT_DST_CAPACITY;
}
// Handle first node
const Str8Node *first_node = wapp_str8_list_get(parts, 0);
wapp_str8_copy_str8_capped(dst, first_node->string);
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
const Str8Node *node = first_node;
u64 node_index = 1;
bool running = true;
while (running && node->next) {
node = node->next;
if (node->string->size == 0) {
continue;
}
if (dst->size > 0) {
char dst_last = wapp_str8_get(dst, dst->size - 1);
char node_start = wapp_str8_get(node->string, 0);
bool add_path_sep = dst_last != PATH_SEP && node_start != PATH_SEP;
if (add_path_sep) {
wapp_str8_concat_capped(dst, &separator);
}
}
wapp_str8_concat_capped(dst, node->string);
++node_index;
running = node_index < parts->node_count;
}
return CPATH_JOIN_SUCCESS;
}
Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
Str8 *output = NULL;
if (!allocator || !path) {
goto RETURN_DIRUP;
}
bool absolute = wapp_str8_get(path, 0) == PATH_SEP;
Str8 separator = wapp_str8_buf(4);
wapp_str8_push_back(&separator, PATH_SEP);
if (path->size == 0) {
output = wapp_str8_alloc_buf(allocator, 16);
if (!output) {
goto RETURN_DIRUP;
}
wapp_str8_push_back(output, absolute ? PATH_SEP : '.');
goto RETURN_DIRUP;
}
if (levels < 1) {
output = wapp_str8_alloc_str8(allocator, path);
goto RETURN_DIRUP;
}
Allocator tmp_arena = wapp_mem_arena_allocator_init(MB(8));
if (wapp_mem_allocator_invalid(&tmp_arena)) {
goto RETURN_DIRUP;
}
Str8List *parts = wapp_str8_split(&tmp_arena, path, &separator);
if (!parts) {
goto RETURN_DIRUP;
}
if (levels >= parts->node_count) {
output = wapp_str8_alloc_buf(allocator, 16);
if (!output) {
goto LIST_CLEANUP_DIRUP;
}
wapp_str8_push_back(output, absolute ? PATH_SEP : '.');
} else {
for (u64 i = 0; i < levels; ++i) {
wapp_str8_list_pop_back(parts);
}
u64 alignment = sizeof(void *) * 2;
u64 alloc_size = parts->total_size + parts->node_count * separator.size;
u64 modulo = alloc_size & (alignment - 1);
alloc_size += alignment - modulo;
output = wapp_str8_alloc_buf(allocator, alloc_size);
if (output) {
if (absolute) {
wapp_str8_push_back(output, PATH_SEP);
}
Str8 *joined = wapp_str8_join(&tmp_arena, parts, &separator);
if (joined) {
wapp_str8_concat_capped(output, joined);
}
}
}
LIST_CLEANUP_DIRUP:
wapp_mem_arena_allocator_destroy(&tmp_arena);
RETURN_DIRUP:
return output;
}

38
src/core/os/cpath/cpath.h Normal file
View File

@@ -0,0 +1,38 @@
#ifndef CPATH_H
#define CPATH_H
#include "aliases.h"
#include "mem_allocator.h"
#include "platform.h"
#include "str8.h"
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // __cplusplus
#ifdef WAPP_PLATFORM_POSIX
#define PATH_SEP '/'
#elif defined(WAPP_PLATFORM_WINDOWS)
#define PATH_SEP '\\'
#else
#error "Unrecognised platform"
#endif
#define wapp_cpath_dirname(ALLOCATOR, PATH) dirup(ALLOCATOR, PATH, 1)
#define wapp_cpath_dirup(ALLOCATOR, PATH, COUNT) dirup(ALLOCATOR, PATH, COUNT)
enum {
CPATH_JOIN_SUCCESS = 0,
CPATH_JOIN_INVALID_ARGS,
CPATH_JOIN_EMPTY_PARTS,
CPATH_JOIN_INSUFFICIENT_DST_CAPACITY,
};
u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts);
Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels);
#ifdef __cplusplus
END_C_LINKAGE
#endif // __cplusplus
#endif // !CPATH_H

29
src/core/os/mem/mem_os.c Normal file
View File

@@ -0,0 +1,29 @@
#include "mem_os.h"
#include "mem_os_ops.h"
#include "aliases.h"
#include "platform.h"
#include <assert.h>
#include <stdbool.h>
#include <string.h>
#if defined(WAPP_PLATFORM_WINDOWS)
#include "mem_os_win.h"
#elif defined(WAPP_PLATFORM_POSIX)
#include "mem_os_posix.h"
#else
#error "Unrecognised platform"
#endif
void *wapp_mem_util_alloc(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) {
void *output = mem_util_allocate(addr, size, access, flags, type);
if (type == WAPP_MEM_INIT_INITIALISED) {
memset(output, 0, size);
}
return output;
}
void wapp_mem_util_free(void *ptr, u64 size) {
mem_util_free(ptr, size);
}

32
src/core/os/mem/mem_os.h Normal file
View File

@@ -0,0 +1,32 @@
#ifndef MEM_OS_H
#define MEM_OS_H
#include "aliases.h"
#include "platform.h"
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // __cplusplus
#include "mem_os_ops.h"
#if defined(WAPP_PLATFORM_WINDOWS)
#include "mem_os_win.h"
#elif defined(WAPP_PLATFORM_POSIX)
#include "mem_os_posix.h"
#else
#error "Unrecognised platform"
#endif
void *wapp_mem_util_align_forward(void *ptr, u64 alignment);
void *wapp_mem_util_alloc(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type);
void wapp_mem_util_free(void *ptr, u64 size);
external void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type);
external void mem_util_free(void *ptr, u64 size);
#ifdef __cplusplus
END_C_LINKAGE
#endif // __cplusplus
#endif // !MEM_OS_H

View File

@@ -0,0 +1,26 @@
#ifndef MEM_OS_OPS_H
#define MEM_OS_OPS_H
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // __cplusplus
typedef enum mem_access {
WAPP_MEM_ACCESS_NONE,
WAPP_MEM_ACCESS_READ_ONLY,
WAPP_MEM_ACCESS_EXEC_ONLY,
WAPP_MEM_ACCESS_READ_WRITE,
WAPP_MEM_ACCESS_READ_EXEC,
WAPP_MEM_ACCESS_READ_WRITE_EXEC,
} MemAccess;
typedef enum mem_init_type {
WAPP_MEM_INIT_UNINITIALISED,
WAPP_MEM_INIT_INITIALISED,
} MemInitType;
#ifdef __cplusplus
END_C_LINKAGE
#endif // __cplusplus
#endif // !MEM_OS_OPS_H

View File

@@ -0,0 +1,34 @@
#include "aliases.h"
#include "platform.h"
#ifdef WAPP_PLATFORM_POSIX
#include "mem_os_ops.h"
#include "mem_os_posix.h"
#include <sys/mman.h>
internal const i32 access_types[] = {
[WAPP_MEM_ACCESS_NONE] = PROT_NONE,
[WAPP_MEM_ACCESS_READ_ONLY] = PROT_READ,
[WAPP_MEM_ACCESS_EXEC_ONLY] = PROT_EXEC,
[WAPP_MEM_ACCESS_READ_WRITE] = PROT_READ | PROT_WRITE,
[WAPP_MEM_ACCESS_READ_EXEC] = PROT_READ | PROT_EXEC,
[WAPP_MEM_ACCESS_READ_WRITE_EXEC] = PROT_READ | PROT_WRITE | PROT_EXEC,
};
void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) {
(void)type;
i32 alloc_flags = flags | MAP_ANON | MAP_PRIVATE;
#if defined(WAPP_PLATFORM_LINUX) || defined(WAPP_PLATFORM_GNU) || defined(WAPP_PLATFORM_NET_BSD)
alloc_flags |= MAP_NORESERVE;
#endif
return mmap(addr, size, access_types[access], alloc_flags, -1, 0);
}
void mem_util_free(void *ptr, u64 size) {
munmap(ptr, size);
}
#endif // !WAPP_PLATFORM_POSIX

View File

@@ -0,0 +1,33 @@
#ifndef MEM_OS_POSIX_H
#define MEM_OS_POSIX_H
#include "platform.h"
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // !__cplusplus
#ifdef WAPP_PLATFORM_POSIX
#include <sys/mman.h>
typedef enum mem_alloc_flags {
#if defined(WAPP_PLATFORM_LINUX) || defined(WAPP_PLATFORM_GNU)
WAPP_MEM_ALLOC_RESERVE = 0,
WAPP_MEM_ALLOC_COMMIT = MAP_POPULATE,
#elif defined(WAPP_PLATFORM_FREE_BSD)
WAPP_MEM_ALLOC_RESERVE = 0,
WAPP_MEM_ALLOC_COMMIT = MAP_PREFAULT_READ,
#elif defined(WAPP_PLATFORM_BSD) || defined(WAPP_PLATFORM_UNIX) || defined(WAPP_PLATFORM_APPLE)
WAPP_MEM_ALLOC_RESERVE = 0,
WAPP_MEM_ALLOC_COMMIT = 0,
#endif
} MemAllocFlags;
#endif // !WAPP_PLATFORM_POSIX
#ifdef __cplusplus
END_C_LINKAGE
#endif // !__cplusplus
#endif // !MEM_OS_POSIX_H

View File

@@ -0,0 +1,35 @@
#include "aliases.h"
#include "platform.h"
#ifdef WAPP_PLATFORM_WINDOWS
#include "mem_os_ops.h"
#include "mem_os_win.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <memoryapi.h>
internal const i32 access_types[] = {
[WAPP_MEM_ACCESS_NONE] = PAGE_NOACCESS,
[WAPP_MEM_ACCESS_READ_ONLY] = PAGE_READONLY,
[WAPP_MEM_ACCESS_EXEC_ONLY] = PAGE_EXECUTE,
[WAPP_MEM_ACCESS_READ_WRITE] = PAGE_READWRITE,
[WAPP_MEM_ACCESS_READ_EXEC] = PAGE_EXECUTE_READ,
[WAPP_MEM_ACCESS_READ_WRITE_EXEC] = PAGE_EXECUTE_READWRITE,
};
void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) {
// Ensure memory is committed if it's meant to be initialised
if (type == WAPP_MEM_INIT_INITIALISED) {
flags |= WAPP_MEM_ALLOC_COMMIT;
}
return VirtualAlloc(addr, (SIZE_T)size, flags, access_types[access]);
}
void mem_util_free(void *ptr, u64 size) {
VirtualFree(ptr, size, MEM_RELEASE);
}
#endif // !WAPP_PLATFORM_WINDOWS

View File

@@ -0,0 +1,27 @@
#ifndef MEM_OS_WIN_H
#define MEM_OS_WIN_H
#include "platform.h"
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // !__cplusplus
#ifdef WAPP_PLATFORM_WINDOWS
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <memoryapi.h>
typedef enum mem_alloc_flags {
WAPP_MEM_ALLOC_RESERVE = MEM_RESERVE,
WAPP_MEM_ALLOC_COMMIT = MEM_COMMIT,
} MemAllocFlags;
#endif // !WAPP_PLATFORM_WINDOWS
#ifdef __cplusplus
END_C_LINKAGE
#endif // !__cplusplus
#endif // !MEM_OS_WIN_H

View File

@@ -0,0 +1,99 @@
#include "commander.h"
#include "aliases.h"
#include "commander_output.h"
#include "mem_allocator.h"
#include "mem_arena_allocator.h"
#include "misc_utils.h"
#include "shell_utils.h"
#include "str8.h"
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CMD_BUF_LEN 8192
#define OUT_BUF_LEN 4096
internal inline CMDResult execute_command(Str8RO *cmd, CMDOutHandling out_handling, Str8 *out_buf);
internal inline CMDError get_command_output(FILE *fp, CMDOutHandling out_handling, Str8 *out_buf);
CMDResult wapp_shell_commander_execute(CMDOutHandling out_handling, Str8 *out_buf, const Str8List *cmd) {
if (!cmd) {
return CMD_NO_EXIT(SHELL_ERR_INVALID_ARGS);
}
Allocator arena = wapp_mem_arena_allocator_init(KB(500));
Str8 *cmd_str = wapp_str8_join(&arena, cmd, &wapp_str8_lit_ro(" "));
if (!cmd_str) {
wapp_mem_arena_allocator_destroy(&arena);
return CMD_NO_EXIT(SHELL_ERR_ALLOCATION_FAIL);
}
// Redirect output
cmd_str = wapp_str8_alloc_concat(&arena, cmd_str, &wapp_str8_lit_ro(" 2>&1"));
CMDResult output = execute_command(cmd_str, out_handling, out_buf);
wapp_mem_arena_allocator_destroy(&arena);
return output;
}
internal inline CMDResult execute_command(Str8RO *cmd, CMDOutHandling out_handling, Str8 *out_buf) {
char cmd_buf[CMD_BUF_LEN] = {0};
wapp_str8_copy_to_cstr(cmd_buf, cmd, CMD_BUF_LEN);
FILE *fp = wapp_shell_utils_popen(cmd_buf, "r");
if (!fp) {
return CMD_NO_EXIT(SHELL_ERR_PROC_START_FAIL);
}
CMDResult output;
CMDError err = get_command_output(fp, out_handling, out_buf);
if (err > SHELL_ERR_NO_ERROR) {
output = CMD_NO_EXIT(err);
goto EXECUTE_COMMAND_CLOSE;
}
i32 st = EXIT_SUCCESS;
err = get_output_status(fp, &st);
if (err > SHELL_ERR_NO_ERROR) {
output = CMD_NO_EXIT(err);
goto EXECUTE_COMMAND_CLOSE;
}
// Process is already closed in get_output_status
fp = NULL;
output = (CMDResult){
.exited = true,
.exit_code = st,
.error = SHELL_ERR_NO_ERROR,
};
EXECUTE_COMMAND_CLOSE:
if (fp) {
wapp_shell_utils_pclose(fp);
}
return output;
}
internal inline CMDError get_command_output(FILE *fp, CMDOutHandling out_handling, Str8 *out_buf) {
Str8 out = wapp_str8_buf(OUT_BUF_LEN);
out.size = fread((void *)out.buf, sizeof(u8), out.capacity, fp);
if (out_handling == SHELL_OUTPUT_CAPTURE && out_buf != NULL) {
if (out.size >= out_buf->capacity) {
return SHELL_ERR_OUT_BUF_FULL;
}
wapp_str8_concat_capped(out_buf, &out);
} else if (out_handling == SHELL_OUTPUT_PRINT) {
printf(WAPP_STR8_SPEC, wapp_str8_varg(out));
}
return SHELL_ERR_NO_ERROR;
}

View File

@@ -0,0 +1,25 @@
#ifndef COMMANDER_H
#define COMMANDER_H
#include "aliases.h"
#include "commander_output.h"
#include "str8.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // __cplusplus
#define CMD_NO_EXIT(ERR) ((CMDResult){.exited = false, .exit_code = EXIT_FAILURE, .error = ERR})
CMDResult wapp_shell_commander_execute(CMDOutHandling out_handling, Str8 *out_buf, const Str8List *cmd);
external CMDError get_output_status(FILE *fp, i32 *status_out);
#ifdef __cplusplus
END_C_LINKAGE
#endif // __cplusplus
#endif // !COMMANDER_H

View File

@@ -0,0 +1,43 @@
#ifndef COMMANDER_OUTPUT_H
#define COMMANDER_OUTPUT_H
#include "aliases.h"
#include "platform.h"
#include <stdbool.h>
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // __cplusplus
typedef enum {
SHELL_OUTPUT_DISCARD,
SHELL_OUTPUT_PRINT,
SHELL_OUTPUT_CAPTURE,
} CMDOutHandling;
typedef enum {
SHELL_ERR_NO_ERROR,
SHELL_ERR_INVALID_ARGS,
SHELL_ERR_ALLOCATION_FAIL,
SHELL_ERR_PROC_START_FAIL,
SHELL_ERR_OUT_BUF_FULL,
SHELL_ERR_PROC_EXIT_FAIL,
} CMDError;
typedef struct commander_result CMDResult;
struct commander_result {
i32 exit_code;
CMDError error;
bool exited;
#ifdef WAPP_PLATFORM_WINDOWS
#include "misc_utils.h"
wapp_misc_utils_padding_size(sizeof(bool) + sizeof(i32) + sizeof(CMDError));
#endif // !WAPP_PLATFORM_WINDOWS
};
#ifdef __cplusplus
END_C_LINKAGE
#endif // __cplusplus
#endif // !COMMANDER_OUTPUT_H

View File

@@ -0,0 +1,23 @@
#include "aliases.h"
#include "platform.h"
#ifdef WAPP_PLATFORM_POSIX
#include "commander_output.h"
#include "shell_utils.h"
#include <stdio.h>
#include <stdlib.h>
CMDError get_output_status(FILE *fp, i32 *status_out) {
*status_out = wapp_shell_utils_pclose(fp);
if (!WIFEXITED(*status_out)) {
return SHELL_ERR_PROC_EXIT_FAIL;
}
*status_out = WEXITSTATUS(*status_out);
return SHELL_ERR_NO_ERROR;
}
#endif // !WAPP_PLATFORM_POSIX

View File

@@ -0,0 +1,22 @@
#include "aliases.h"
#include "platform.h"
#ifdef WAPP_PLATFORM_WINDOWS
#include "commander_output.h"
#include "shell_utils.h"
#include <stdio.h>
CMDError get_output_status(FILE *fp, i32 *status_out) {
if (!feof(fp)) {
// Ensure process is closed on failure
wapp_shell_utils_pclose(fp);
return SHELL_ERR_PROC_EXIT_FAIL;
}
*status_out = wapp_shell_utils_pclose(fp);
return SHELL_ERR_NO_ERROR;
}
#endif // !WAPP_PLATFORM_WINDOWS

View File

@@ -0,0 +1,34 @@
#include "aliases.h"
#include "platform.h"
#include "str8.h"
#ifdef WAPP_PLATFORM_POSIX
#include "terminal_colours.h"
#include <stdio.h>
internal Str8RO colours[COUNT_TERM_COLOUR] = {
[WAPP_TERM_COLOUR_FG_BLACK] = wapp_str8_lit_ro_initialiser_list("\033[30m"),
[WAPP_TERM_COLOUR_FG_RED] = wapp_str8_lit_ro_initialiser_list("\033[31m"),
[WAPP_TERM_COLOUR_FG_GREEN] = wapp_str8_lit_ro_initialiser_list("\033[32m"),
[WAPP_TERM_COLOUR_FG_BLUE] = wapp_str8_lit_ro_initialiser_list("\033[34m"),
[WAPP_TERM_COLOUR_FG_CYAN] = wapp_str8_lit_ro_initialiser_list("\033[36m"),
[WAPP_TERM_COLOUR_FG_MAGENTA] = wapp_str8_lit_ro_initialiser_list("\033[35m"),
[WAPP_TERM_COLOUR_FG_YELLOW] = wapp_str8_lit_ro_initialiser_list("\033[33m"),
[WAPP_TERM_COLOUR_FG_WHITE] = wapp_str8_lit_ro_initialiser_list("\033[37m"),
[WAPP_TERM_COLOUR_FG_BR_BLACK] = wapp_str8_lit_ro_initialiser_list("\033[90m"),
[WAPP_TERM_COLOUR_FG_BR_RED] = wapp_str8_lit_ro_initialiser_list("\033[91m"),
[WAPP_TERM_COLOUR_FG_BR_GREEN] = wapp_str8_lit_ro_initialiser_list("\033[92m"),
[WAPP_TERM_COLOUR_FG_BR_BLUE] = wapp_str8_lit_ro_initialiser_list("\033[94m"),
[WAPP_TERM_COLOUR_FG_BR_CYAN] = wapp_str8_lit_ro_initialiser_list("\033[96m"),
[WAPP_TERM_COLOUR_FG_BR_MAGENTA] = wapp_str8_lit_ro_initialiser_list("\033[95m"),
[WAPP_TERM_COLOUR_FG_BR_YELLOW] = wapp_str8_lit_ro_initialiser_list("\033[93m"),
[WAPP_TERM_COLOUR_FG_BR_WHITE] = wapp_str8_lit_ro_initialiser_list("\033[97m"),
[WAPP_TERM_COLOUR_CLEAR] = wapp_str8_lit_ro_initialiser_list("\033[0m"),
};
void print_coloured_text(Str8RO *text, TerminalColour colour) {
printf(WAPP_STR8_SPEC WAPP_STR8_SPEC, wapp_str8_varg(colours[colour]), wapp_str8_varg((*text)));
}
#endif // !WAPP_PLATFORM_POSIX

View File

@@ -0,0 +1,15 @@
#include "termcolour.h"
#include "terminal_colours.h"
void wapp_shell_termcolour_print_text(Str8RO *text, TerminalColour colour) {
if (colour < WAPP_TERM_COLOUR_FG_BLACK || colour > WAPP_TERM_COLOUR_FG_BR_WHITE) {
return;
}
print_coloured_text(text, colour);
}
void wapp_shell_termcolour_clear_colour(void) {
Str8RO empty = wapp_str8_lit_ro("");
print_coloured_text(&empty, WAPP_TERM_COLOUR_CLEAR);
}

View File

@@ -0,0 +1,21 @@
#ifndef TERM_COLOUR_H
#define TERM_COLOUR_H
#include "aliases.h"
#include "terminal_colours.h"
#include "str8.h"
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // __cplusplus
void wapp_shell_termcolour_print_text(Str8RO *text, TerminalColour colour);
void wapp_shell_termcolour_clear_colour(void);
external void print_coloured_text(Str8RO *text, TerminalColour colour);
#ifdef __cplusplus
END_C_LINKAGE
#endif // __cplusplus
#endif // !TERM_COLOUR_H

View File

@@ -0,0 +1,34 @@
#ifndef TERMINAL_COLOURS_H
#define TERMINAL_COLOURS_H
#ifdef __cplusplus
BEGIN_C_LINKAGE
#endif // __cplusplus
typedef enum {
WAPP_TERM_COLOUR_FG_BLACK,
WAPP_TERM_COLOUR_FG_RED,
WAPP_TERM_COLOUR_FG_GREEN,
WAPP_TERM_COLOUR_FG_BLUE,
WAPP_TERM_COLOUR_FG_CYAN,
WAPP_TERM_COLOUR_FG_MAGENTA,
WAPP_TERM_COLOUR_FG_YELLOW,
WAPP_TERM_COLOUR_FG_WHITE,
WAPP_TERM_COLOUR_FG_BR_BLACK,
WAPP_TERM_COLOUR_FG_BR_RED,
WAPP_TERM_COLOUR_FG_BR_GREEN,
WAPP_TERM_COLOUR_FG_BR_BLUE,
WAPP_TERM_COLOUR_FG_BR_CYAN,
WAPP_TERM_COLOUR_FG_BR_MAGENTA,
WAPP_TERM_COLOUR_FG_BR_YELLOW,
WAPP_TERM_COLOUR_FG_BR_WHITE,
WAPP_TERM_COLOUR_CLEAR,
COUNT_TERM_COLOUR,
} TerminalColour;
#ifdef __cplusplus
END_C_LINKAGE
#endif // __cplusplus
#endif // !TERMINAL_COLOURS_H

View File

@@ -0,0 +1,71 @@
#include "aliases.h"
#include "platform.h"
#include "str8.h"
#ifdef WAPP_PLATFORM_WINDOWS
#include "misc_utils.h"
#include "terminal_colours.h"
#include <stdio.h>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
typedef struct termcolour_data TermcolourData;
struct termcolour_data {
HANDLE handle;
WORD default_colour;
WORD current_colour;
wapp_misc_utils_padding_size(sizeof(HANDLE) + sizeof(WORD) + sizeof(WORD));
};
internal void init_data(TermcolourData *data);
internal WORD colours[COUNT_TERM_COLOUR] = {
[WAPP_TERM_COLOUR_FG_BLACK] = 0,
[WAPP_TERM_COLOUR_FG_RED] = FOREGROUND_RED,
[WAPP_TERM_COLOUR_FG_GREEN] = FOREGROUND_GREEN,
[WAPP_TERM_COLOUR_FG_BLUE] = FOREGROUND_BLUE,
[WAPP_TERM_COLOUR_FG_CYAN] = FOREGROUND_GREEN | FOREGROUND_BLUE,
[WAPP_TERM_COLOUR_FG_MAGENTA] = FOREGROUND_RED | FOREGROUND_BLUE,
[WAPP_TERM_COLOUR_FG_YELLOW] = FOREGROUND_RED | FOREGROUND_GREEN,
[WAPP_TERM_COLOUR_FG_WHITE] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
[WAPP_TERM_COLOUR_FG_BR_BLACK] = FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_RED] = FOREGROUND_RED | FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_GREEN] = FOREGROUND_GREEN | FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_BLUE] = FOREGROUND_BLUE | FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_CYAN] = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_MAGENTA] = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_YELLOW] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_WHITE] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
};
void print_coloured_text(Str8RO *text, TerminalColour colour) {
persistent TermcolourData data = {0};
if (data.handle == 0) {
init_data(&data);
}
if (colour == WAPP_TERM_COLOUR_CLEAR) {
data.current_colour = data.default_colour;
} else {
data.current_colour = colours[colour];
}
SetConsoleTextAttribute(data.handle, data.current_colour);
printf(WAPP_STR8_SPEC, wapp_str8_varg((*text)));
}
internal void init_data(TermcolourData *data) {
// create handle
data->handle = GetStdHandle(STD_OUTPUT_HANDLE);
// get console colour information
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(data->handle, &csbi);
data->default_colour = csbi.wAttributes;
data->current_colour = data->default_colour;
}
#endif // !WAPP_PLATFORM_WINDOWS

View File

@@ -0,0 +1,15 @@
#ifndef SHELL_UTILS_H
#define SHELL_UTILS_H
#include "platform.h"
#include <stdio.h>
#ifdef WAPP_PLATFORM_WINDOWS
#define wapp_shell_utils_popen _popen
#define wapp_shell_utils_pclose _pclose
#else
#define wapp_shell_utils_popen popen
#define wapp_shell_utils_pclose pclose
#endif /* ifdef WAPP_PLATFORM_WINDOWS */
#endif // !SHELL_UTILS_H

View File

@@ -7,5 +7,15 @@
#include "mem_arena_allocator.c"
#include "mem_allocator.c"
#include "str8.c"
#include "termcolour_win.c"
#include "termcolour_posix.c"
#include "termcolour.c"
#include "commander_win.c"
#include "commander.c"
#include "commander_posix.c"
#include "mem_os_win.c"
#include "mem_os.c"
#include "mem_os_posix.c"
#include "cpath.c"
#endif // !WAPP_CORE_C

View File

@@ -6,6 +6,16 @@
#include "mem_utils.h"
#include "mem_allocator.h"
#include "str8.h"
#include "termcolour.h"
#include "terminal_colours.h"
#include "shell_utils.h"
#include "commander_output.h"
#include "commander.h"
#include "mem_os_ops.h"
#include "mem_os_win.h"
#include "mem_os.h"
#include "mem_os_posix.h"
#include "cpath.h"
#include "wapp_common.h"
#endif // !WAPP_CORE_H