Gama C Library
Gama C API Documentation
utils.h
Go to the documentation of this file.
1/**
2 * @file utils.h
3 * @brief Provides general utility functions for file handling and string manipulation.
4 *
5 * This file contains miscellaneous helper functions that are not directly
6 * related to a specific Gama module but are useful across the engine.
7 */
8#pragma once
9
10#include "_malloc.h" // For custom malloc/free
11#include <ctype.h>
12#include <stdio.h>
13#include <string.h>
14
15/**
16 * @brief Extracts the base filename (filename with extension) from a full path.
17 *
18 * Example: `path = "/home/user/image.png"` -> `out_base = "image.png"`
19 *
20 * @param path The full path string.
21 * @param out_base Buffer to store the extracted filename.
22 * @param out_size The size of the `out_base` buffer.
23 */
24void gmu_get_filename_base(const char *path, char *out_base, size_t out_size) {
25 // Find last path separator (works for both / and \‍)
26 const char *filename = path;
27 const char *p = path;
28 while (*p) {
29 if (*p == '/' || *p == '\\') {
30 filename = p + 1;
31 }
32 p++;
33 }
34
35 // Find extension (not used for base, but can be for stem)
36 // const char *ext = strrchr(filename, '.');
37
38 size_t len = strlen(filename);
39
40 // Ensure we don't overflow out_base
41 if (len >= out_size)
42 len = out_size - 1;
43
44 strncpy(out_base, filename, len);
45 out_base[len] = '\0';
46}
47
48/**
49 * @brief Extracts the filename stem (filename without extension) from a full path.
50 *
51 * Example: `path = "/home/user/image.png"` -> `out_stem = "image"`
52 *
53 * @param path The full path string.
54 * @param out_stem Buffer to store the extracted filename stem.
55 * @param out_size The size of the `out_stem` buffer.
56 */
57void gmu_get_filename_stem(const char *path, char *out_stem, size_t out_size) {
58 // Find last path separator (works for both / and \‍)
59 const char *filename = path;
60 const char *p = path;
61 while (*p) {
62 if (*p == '/' || *p == '\\') {
63 filename = p + 1;
64 }
65 p++;
66 }
67
68 // Find extension
69 const char *ext = strrchr(filename, '.');
70
71 // Copy stem
72 size_t len;
73 if (ext) {
74 len = ext - filename;
75 } else {
76 len = strlen(filename);
77 }
78
79 // Ensure we don't overflow
80 if (len >= out_size) {
81 len = out_size - 1;
82 }
83
84 strncpy(out_stem, filename, len);
85 out_stem[len] = '\0';
86}
87
88/**
89 * @brief Reads the entire content of a file into a dynamically allocated buffer.
90 *
91 * The caller is responsible for freeing the `*content` buffer.
92 *
93 * @param path The path to the file to read.
94 * @param content A pointer to a `char*` that will be allocated and filled with the file's content.
95 * @param size A pointer to a `size_t` that will store the size of the read content. Can be NULL.
96 * @return 0 on success, -1 if the file cannot be opened, -5 on memory allocation failure.
97 */
98int gmu_read_file(const char *path, char **content, size_t *size) {
99 FILE *f = fopen(path, "r");
100 size_t _s;
101 if (size == NULL)
102 size = &_s;
103 if (!f)
104 return -1;
105 fseek(f, 0, SEEK_END);
106 *size = ftell(f);
107 fseek(f, 0, SEEK_SET);
108 char *buffer = malloc(1 + *size);
109 if (!buffer)
110 return -5;
111 fread(buffer, sizeof(char), *size, f);
112 buffer[*size] = '\0';
113 *content = buffer;
114 return 0;
115}
116
117/**
118 * @internal
119 * @brief Copies a string up to an End-Of-Line character or maximum length, trimming trailing whitespace.
120 * @param dest The destination buffer.
121 * @param src The source string.
122 * @param max_len The maximum length of the destination buffer, including null terminator.
123 */
124static inline void gm3u_str_copy_eol(char *dest, const char *src,
125 size_t max_len) {
126 while (*src && isspace((unsigned char)*src))
127 src++;
128 size_t i = 0;
129 while (src[i] != '\0' && src[i] != '\n' && src[i] != '\r' &&
130 i < max_len - 1) {
131 dest[i] = src[i];
132 i++;
133 }
134 dest[i] = '\0';
135 while (i > 0 && isspace((unsigned char)dest[i - 1])) {
136 dest[--i] = '\0';
137 }
138}
void * malloc(size_t size)
Custom implementation of malloc using a static memory pool.
Definition malloc.h:144
void gmu_get_filename_base(const char *path, char *out_base, size_t out_size)
Extracts the base filename (filename with extension) from a full path.
Definition utils.h:24
void gmu_get_filename_stem(const char *path, char *out_stem, size_t out_size)
Extracts the filename stem (filename without extension) from a full path.
Definition utils.h:57
int gmu_read_file(const char *path, char **content, size_t *size)
Reads the entire content of a file into a dynamically allocated buffer.
Definition utils.h:98