147 lines
4.1 KiB
C
147 lines
4.1 KiB
C
/* 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 */
|