diff --git a/jh.h b/jh.h new file mode 100644 index 0000000..9e87a78 --- /dev/null +++ b/jh.h @@ -0,0 +1,146 @@ +/* jh.h - v0.01 - Jason Hilder + +Heavily inspired and designed from: +* https://github.com/nothings/stb/ +* https://github.com/gingerBill/gb/ + +This is a single header file with things I reach for often + +To use this library, do this in *one* C or C++ file: + #define JH_IMPLEMENTATION + #include "jh.h" + +*/ + +#ifndef JH_INCLUDE_JH_H +#define JH_INCLUDE_JH_H + +int jh_read_file_to_buffer(char* file_path, char** out_buffer, int add_terminator); +void jh_sort_int_array(int* array, size_t arrlen, const char* order); + +// -------------------------------------- +// -------------------------------------- +// implementation Below +// -------------------------------------- + +#ifdef JH_H_IMPLEMENTATION + +// -------------------------------------- +// Macros: +// -------------------------------------- + +#define max(a,b) \ +({ \ + __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a > _b ? _a : _b; \ +}) + +#define min(a,b) \ +({ \ + __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a < _b ? _a : _b; \ +}) + +// -------------------------------------- +// Comparison helpers: +// -------------------------------------- + +static inline int int_compare_asc(const void* a, const void* b) { + return (*(int*)a - *(int*)b); +} + +static inline int int_compare_desc(const void* a, const void* b) { + return (*(int*)b - *(int*)a); +} + +// -------------------------------------- +// FILE I/O helpers: +// -------------------------------------- + +// Takes file path and a buffer which will get reallocated to the full file size. +// Note: buffer still needs to be manually free'd +int hf_read_file_to_buffer(char* file_path, char** out_buffer, int add_terminator) +{ + FILE *file = fopen(file_path, "rb"); + if(file == NULL) + { + perror("Failed to open file."); + return -1; + } + + fseek(file, 0L, SEEK_END); + long file_size = ftell(file); + if (file_size == -1) + { + perror("Failed to determine file size"); + fclose(file); + return -1; + } + rewind(file); + + // Reallocate memory for the buffer, check if realloc is successful + // Realloc with extra space if terminator is needed + char *buffer = realloc(*out_buffer, file_size + (add_terminator ? 1 : 0)); + if (buffer == NULL) + { + perror("Memory allocation failed"); + fclose(file); + return -1; + } + + // Update the pointer to the newly allocated buffer + *out_buffer = buffer; + + size_t bytes_read = fread(*out_buffer, 1, file_size, file); + if (bytes_read != file_size) + { + perror("Error reading file"); + fclose(file); + return -1; + } + + // Add null terminator if needed + if (add_terminator == 1) + { + (*out_buffer)[file_size] = '\0'; + } + + fclose(file); + return 0; +} + +// -------------------------------------- +// array helpers: +// -------------------------------------- + +/* + Sorts an integer array in ascending or descending order. + + This function uses the `qsort` function to sort an array of integers either + in ascending or descending order, based on the provided `order` argument. + The comparison is done using the standard integer comparison logic. + + @param array Pointer to the integer array to be sorted. + @param arrlen The length of the array. + @param order A string that specifies the sorting order. It can be: + - "asc" for ascending order + - "desc" for descending order + If an invalid value is provided, the function will print an error message. + + @note If the `order` parameter is not one of "asc" or "desc", an error message will be printed. + @see qsort(3) for the underlying sorting algorithm used. +*/ +void jh_sort_int_array(int* array, size_t arrlen, const char* order) { + if (strcmp(order, "asc") == 0) { + qsort(array, arrlen, sizeof(int), int_compare_asc); + } else if (strcmp(order, "desc") == 0) { + qsort(array, arrlen, sizeof(int), int_compare_desc); + } else { + printf("Invalid order: %s. Use 'asc' or 'desc'.\n", order); + } +} + +#endif /* JH_H_IMPLEMENTATION */ +#endif /* JH_INCLUDE_JH_H */