solidc
Robust collection of general-purpose cross-platform C libraries and data structures designed for rapid and safe development in C
Loading...
Searching...
No Matches
str_utils.h
Go to the documentation of this file.
1
6#ifndef STR_UTILS_H
7#define STR_UTILS_H
8
9#include <ctype.h>
10#include <stddef.h>
11#include <string.h>
12
13#ifdef __cplusplus
14extern "C" {
15#endif
16
28static inline char* trim_string(char* str) {
29 if (!str) return NULL;
30
31 // Trim leading whitespace
32 while (isspace((unsigned char)*str)) {
33 str++;
34 }
35
36 // If string is empty or all spaces, return early
37 if (*str == '\0') {
38 return str;
39 }
40
41 // Single-pass forward scan for trailing trim
42 char* end = str;
43 char* cursor = str;
44 while (*cursor) {
45 if (!isspace((unsigned char)*cursor)) {
46 end = cursor;
47 }
48 cursor++;
49 }
50
51 // Terminate after the last non-space character
52 *(end + 1) = '\0';
53
54 return str;
55}
56
57/*
58 * Microsoft Visual C++ (MSVC) lacks standard POSIX string functions.
59 * MinGW (which also defines _WIN32) typically includes them in <strings.h>.
60 */
61#if defined(_MSC_VER)
62
63#include <stdbool.h>
64
69static inline int strcasecmp(const char* s1, const char* s2) {
70 // Handle NULL pointers safely (not standard POSIX, but requested behavior)
71 if (s1 == s2) return 0;
72 if (s1 == NULL) return -1;
73 if (s2 == NULL) return 1;
74
75 return _stricmp(s1, s2);
76}
77
82static inline int strncasecmp(const char* s1, const char* s2, size_t n) {
83 if (n == 0) return 0;
84
85 // Handle NULL pointers safely
86 if (s1 == s2) return 0;
87 if (s1 == NULL) return -1;
88 if (s2 == NULL) return 1;
89
90 return _strnicmp(s1, s2, n);
91}
92
98static inline char* strcasestr(const char* haystack, const char* needle) {
99 if (!needle || *needle == '\0') return (char*)haystack;
100 if (!haystack) return NULL;
101
102 const size_t needle_len = strlen(needle);
103
104 /* Optimization:
105 We iterate until the remaining haystack is shorter than the needle.
106 We do the tolower() conversion on the fly to avoid allocating memory. */
107 while (*haystack) {
108 if (strncasecmp(haystack, needle, needle_len) == 0) {
109 return (char*)haystack;
110 }
111 haystack++;
112 }
113
114 return NULL;
115}
116
117#else
118
119/*
120 * Non-MSVC platforms (Linux, macOS, MinGW, BSD)
121 * typically provide these in <strings.h>.
122 */
123#include <strings.h>
124
125/*
126 * Note: standard strcasestr is a GNU/BSD extension.
127 * If your specific compiler settings (e.g., -std=c99 --pedantic)
128 * hide it, you may need to explicitly define _GNU_SOURCE before includes
129 * or uncomment the fallback implementation below.
130 */
131
132#endif // _MSC_VER
133
134#ifdef __cplusplus
135}
136#endif
137
138#endif // STR_UTILS_H