Last active
February 10, 2024 17:26
-
-
Save Hachem-H/597bb42cf8f8ef44f50beb2ebb9c14ec to your computer and use it in GitHub Desktop.
Hachem's C Extensions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* hext.h - Hachem's C Extensions. | |
* | |
* A set of utility functions, definitions and macros | |
* which make programming in C, a little less annoying. | |
* | |
* | |
* Author: Hachem H. | |
* Version: 0.1.1 | |
* | |
* | |
* ## Documentation | |
* ### Type definitions | |
* | |
* ```c | |
* typedef uint64_t u64; | |
* typedef uint32_t u32; | |
* typedef uint16_t u16; | |
* typedef uint8_t u8; | |
* | |
* typedef int64_t i64; | |
* typedef int32_t i32; | |
* typedef int16_t i16; | |
* typedef int8_t i8; | |
* | |
* typedef float f32; | |
* typedef double f64; | |
* | |
* typedef size_t usize; | |
* typedef ptrdiff_t isize; | |
* | |
* typedef uint8_t byte; | |
* typedef unsigned char uchar; | |
* ``` | |
* | |
* ### Memory utility functions | |
* Traditionally in C memory is allocated through the `malloc` function, which has to | |
* take in a size and returns a pointer which has to be casted into the proper buffer | |
* type. `hext` offers a macro which takes in the type and the number of elements instead. | |
* | |
* ```c | |
* #include <hext.h> | |
* | |
* int main(void) | |
* { | |
* u32* buffer = alloc(u32, 100); | |
* for (u32 i = 0; i < 100; i++) | |
* buffer[i] = i; | |
* free(buffer); | |
* } | |
* ``` | |
* | |
* ### Error and optional types | |
* The first type is the `Possible` type, which is defined by a `Possible(errorType, okayType)`. | |
* Its a result type which can give either an error of a given type or a default type in | |
* case of success. The following example shows an over engineered examples of a division function: | |
* | |
* ```c | |
* #include "hext.h" | |
* | |
* typedef enum DivideError_t | |
* { | |
* DivisionByZero, | |
* IllegalNumber, | |
* } DivideError; | |
* | |
* typedef Possible(DivideError, i32) DivisionResult; | |
* DivisionResult Divide(i32 a, i32 b) | |
* { | |
* if (b == 0) | |
* return Error(DivisionResult, DivisionByZero); | |
* i32 result = a/b; | |
* if (result == 69) | |
* return Error(DivisionResult, IllegalNumber); | |
* return Some(DivisionResult, result); | |
* } | |
* | |
* int main(void) | |
* { | |
* DivisionResult number = Divide(1, 0); | |
* if (!number.ok) | |
* { | |
* switch (number.error) | |
* { | |
* case IllegalNumber: | |
* puts("Illegal number obtained."); | |
* break; | |
* case DivisionByZero: | |
* puts("Division by zero error."); | |
* break; | |
* default: break; | |
* } | |
* } else | |
* printf("Result: %d\n", number.some); | |
* } | |
* ``` | |
* | |
* We first define a division result which can either be an error or an actual number. | |
* In case of errors, we simply return an `Error` containing the function return type | |
* and the actual error value (which should be in so called error type), or in case of | |
* success, we return `Some` value in the same manner. Later we can check if the function | |
* ran properly by checking the `ok` flag. | |
* | |
* ### Miscellaneous | |
* Testing if two strings are equal is somewhat long winded in C, so we have a macro | |
* `streql(string1, string2)` which just returns a boolean. `hext` also have 2 new | |
* keywords for context static. `global` and `internal`. | |
* | |
* ## Logging | |
* It's pretty common in C to write a logging system with colors as an alternative | |
* to the now ubiquitous `printf`, `hext` provides simple logging functions: | |
* - `HEXT_INFO` | |
* - `HEXT_DEBUG` | |
* - `HEXT_WARN` | |
* - `HEXT_INFO` | |
* which take formatting arguments similar to those in the standard library. | |
* `hext` also provides certain constants which allow color printing and style formatting | |
* for the tty. For example: | |
* | |
* ```c | |
* printf("%sThis is bold\n%sThis is bold and red\n%s%sThis is just red.", | |
* HEXT_CONSOLE_MODE_BOLD, HEXT_CONSOLE_COLOR_RED, | |
* HEXT_CONSOLE_MODE_RESET, HEXT_CONSOLE_COLOR_RED); | |
* ``` | |
* | |
* All of the available options in the header file are: | |
* - `HEXT_CONSOLE_MODE_RESET` | |
* - `HEXT_CONSOLE_MODE_BOLD` | |
* - `HEXT_CONSOLE_MODE_UNDERLINE` | |
* - `HEXT_CONSOLE_MODE_ITALIC` | |
* | |
* - `HEXT_CONSOLE_COLORS_RED` | |
* - `HEXT_CONSOLE_COLORS_GREEN` | |
* - `HEXT_CONSOLE_COLORS_YELLOW` | |
* - `HEXT_CONSOLE_COLORS_BLUE` | |
* - `HEXT_CONSOLE_COLORS_MAGENTA` | |
* - `HEXT_CONSOLE_COLORS_CYAN` | |
* | |
* | |
* MIT License | |
* | |
* Copyright (c) 2024 Hachem | |
* | |
* Permission is hereby granted, free of charge, to any person obtaining a copy | |
* of this software and associated documentation files (the "Software"), to deal | |
* in the Software without restriction, including without limitation the rights | |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
* copies of the Software, and to permit persons to whom the Software is | |
* furnished to do so, subject to the following conditions: | |
* | |
* The above copyright notice and this permission notice shall be included in all | |
* copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
* SOFTWARE. | |
* | |
*/ | |
#pragma once | |
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <stddef.h> | |
#include <stdbool.h> | |
#define internal static | |
#define global static | |
typedef uint64_t u64; | |
typedef uint32_t u32; | |
typedef uint16_t u16; | |
typedef uint8_t u8; | |
typedef int64_t i64; | |
typedef int32_t i32; | |
typedef int16_t i16; | |
typedef int8_t i8; | |
typedef float f32; | |
typedef double f64; | |
typedef size_t usize; | |
typedef ptrdiff_t isize; | |
typedef uint8_t byte; | |
typedef unsigned char uchar; | |
#define streql(str1, str2) (strcmp(str1, str2) == 0) | |
#define alloc(type, count) (type*) malloc(sizeof(type)*count); | |
#define Possible(errorType, okayType) \ | |
struct { bool ok; \ | |
union { errorType error; \ | |
okayType some; }; } | |
#define Error(T, errorExpression) \ | |
(T) { .ok = false, .error = errorExpression, } | |
#define Some(T, okayExpression) \ | |
(T) { .ok = true, .some = okayExpression, } | |
global const char* const HEXT_CONSOLE_MODE_RESET = "\033[0m"; | |
global const char* const HEXT_CONSOLE_MODE_BOLD = "\033[1m"; | |
global const char* const HEXT_CONSOLE_MODE_UNDERLINE = "\033[4m"; | |
global const char* const HEXT_CONSOLE_MODE_ITALIC = "\033[3m"; | |
global const char* const HEXT_CONSOLE_COLORS_RED = "\033[91m"; | |
global const char* const HEXT_CONSOLE_COLORS_GREEN = "\033[92m"; | |
global const char* const HEXT_CONSOLE_COLORS_YELLOW = "\033[93m"; | |
global const char* const HEXT_CONSOLE_COLORS_BLUE = "\033[94m"; | |
global const char* const HEXT_CONSOLE_COLORS_MAGENTA = "\033[95m"; | |
global const char* const HEXT_CONSOLE_COLORS_CYAN = "\033[96m"; | |
#define HEXT_INFO(...) { \ | |
printf("[%s%sINFO%s]: ", HEXT_CONSOLE_COLORS_CYAN, \ | |
HEXT_CONSOLE_MODE_BOLD, \ | |
HEXT_CONSOLE_MODE_RESET); \ | |
printf(__VA_ARGS__); putchar('\n'); } | |
#define HEXT_DEBUG(...) { \ | |
printf("[%s%sDEBUG%s]: ", HEXT_CONSOLE_COLORS_BLUE, \ | |
HEXT_CONSOLE_MODE_BOLD, \ | |
HEXT_CONSOLE_MODE_RESET); \ | |
printf(__VA_ARGS__); putchar('\n'); } | |
#define HEXT_WARN(...) { \ | |
printf("[%s%sWARN%s]: ", HEXT_CONSOLE_COLORS_YELLOW, \ | |
HEXT_CONSOLE_MODE_BOLD, \ | |
HEXT_CONSOLE_MODE_RESET); \ | |
printf(__VA_ARGS__); putchar('\n'); } | |
#define HEXT_ERROR(...) { \ | |
printf("[%s%sERROR%s]: ", HEXT_CONSOLE_COLORS_RED, \ | |
HEXT_CONSOLE_MODE_BOLD, \ | |
HEXT_CONSOLE_MODE_RESET); \ | |
printf(__VA_ARGS__); putchar('\n'); } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment