LMMS
Loading...
Searching...
No Matches
wdlcstring.h
Go to the documentation of this file.
1/*
2 WDL - wdlcstring.h
3 Copyright (C) 2005 and later, Cockos Incorporated
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20
21*/
22
23/*
24C string manipulation utilities -- [v]snprintf for Win32, also snprintf_append, lstrcatn, etc
25 */
26#ifndef _WDL_CSTRING_H_
27#define _WDL_CSTRING_H_
28
29#include <stdarg.h>
30#include <stdio.h>
31#include <ctype.h>
32
33#include "wdltypes.h"
34
35#ifdef _WDL_CSTRING_IMPL_ONLY_
36 #ifdef _WDL_CSTRING_IF_ONLY_
37 #undef _WDL_CSTRING_IF_ONLY_
38 #endif
39 #define _WDL_CSTRING_PREFIX
40#else
41 #define _WDL_CSTRING_PREFIX static WDL_STATICFUNC_UNUSED
42#endif
43
44
45
46#if defined(_WIN32) && defined(_MSC_VER)
47 // provide snprintf()/vsnprintf() for win32 -- note that these have no way of knowing
48 // what the amount written was, code should(must) be written to not depend on this.
49 #ifdef snprintf
50 #undef snprintf
51 #endif
52 #define snprintf WDL_snprintf
53
54 #ifdef vsnprintf
55 #undef vsnprintf
56 #endif
57 #define vsnprintf WDL_vsnprintf
58
59#endif // win32 snprintf/vsnprintf
60
61// use wdlcstring.h's lstrcpyn_safe rather than the real lstrcpyn.
62#ifdef _WIN32
63 #ifdef lstrcpyn
64 #undef lstrcpyn
65 #endif
66 #define lstrcpyn lstrcpyn_safe
67#endif
68
69#ifdef __cplusplus
70extern "C" {
71#endif
72
73#ifdef _WDL_CSTRING_IF_ONLY_
74
75 void lstrcpyn_safe(char *o, const char *in, INT_PTR count);
76 void lstrcatn(char *o, const char *in, INT_PTR count);
77 void WDL_VARARG_WARN(printf,3,4) snprintf_append(char *o, INT_PTR count, const char *format, ...);
78 void vsnprintf_append(char *o, INT_PTR count, const char *format, va_list va);
79
80 const char *WDL_get_filepart(const char *str); // returns whole string if no dir chars
81 const char *WDL_get_fileext(const char *str); // returns ".ext" or end of string "" if no extension
82 char *WDL_remove_fileext(char *str); // returns pointer to "ext" if ".ext" was removed (zero-d dot), or NULL
83 char WDL_remove_filepart(char *str); // returns dir character that was zeroed, or 0 if new string is empty
84 int WDL_remove_trailing_dirchars(char *str); // returns trailing dirchar count removed, will not convert "/" into ""
85 size_t WDL_remove_trailing_crlf(char *str); // returns new length
86 size_t WDL_remove_trailing_whitespace(char *str); // returns new length, removes crlf space tab
87 const char *WDL_sanitize_ini_key_start(const char *p); // used for sanitizing the start of the "key" parameter to Write/GetPrivateProfile*. note does not fully santiize
88
89 char *WDL_remove_trailing_decimal_zeros(char *str, unsigned int keep); // returns pointer to decimal point or end of string. removes final zeros after final decimal point only, keep=0 makes min length X, keep=1 X., keep=2 X.0, keep=3 X.00 etc, and also treats commas as decimal points
90
91 #if defined(_WIN32) && defined(_MSC_VER)
92 void WDL_vsnprintf(char *o, size_t count, const char *format, va_list args);
93 void WDL_VARARG_WARN(printf,3,4) WDL_snprintf(char *o, size_t count, const char *format, ...);
94 #endif
95
96 int WDL_strcmp_logical(const char *s1, const char *s2, int case_sensitive);
97 const char *WDL_stristr(const char* a, const char* b);
98#else
99
100
101 #if defined(_WIN32) && defined(_MSC_VER)
102
103 _WDL_CSTRING_PREFIX void WDL_vsnprintf(char *o, size_t count, const char *format, va_list args)
104 {
105 if (count>0)
106 {
107 int rv;
108 o[0]=0;
109 rv=_vsnprintf(o,count,format,args); // returns -1 if over, and does not null terminate, ugh
110 if (rv < 0 || rv>=(int)count-1) o[count-1]=0;
111 }
112 }
113 _WDL_CSTRING_PREFIX void WDL_VARARG_WARN(printf,3,4) WDL_snprintf(char *o, size_t count, const char *format, ...)
114 {
115 if (count>0)
116 {
117 int rv;
118 va_list va;
119 va_start(va,format);
120 o[0]=0;
121 rv=_vsnprintf(o,count,format,va); // returns -1 if over, and does not null terminate, ugh
122 va_end(va);
123
124 if (rv < 0 || rv>=(int)count-1) o[count-1]=0;
125 }
126 }
127 #endif
128
130 {
131 if (count>0)
132 {
133 while (--count>0 && *in) *o++ = *in++;
134 *o=0;
135 }
136 }
137
138 _WDL_CSTRING_PREFIX void lstrcatn(char *o, const char *in, INT_PTR count)
139 {
140 if (count>0)
141 {
142 while (*o) { if (--count < 1) return; o++; }
143 while (--count>0 && *in) *o++ = *in++;
144 *o=0;
145 }
146 }
147
148 _WDL_CSTRING_PREFIX const char *WDL_get_filepart(const char *str) // returns whole string if no dir chars
149 {
150 const char *p = str;
151 while (*p) p++;
152 while (p >= str && !WDL_IS_DIRCHAR(*p)) --p;
153 return p + 1;
154 }
155 _WDL_CSTRING_PREFIX const char *WDL_get_fileext(const char *str) // returns ".ext" or end of string "" if no extension
156 {
157 const char *p=str, *ep;
158 while (*p) p++;
159 ep = p;
160 while (p >= str && !WDL_IS_DIRCHAR(*p))
161 {
162 if (*p == '.') return p;
163 --p;
164 }
165 return ep;
166 }
167
168 _WDL_CSTRING_PREFIX char *WDL_remove_fileext(char *str) // returns pointer to "ext" if ".ext" was removed (zero-d dot), or NULL
169 {
170 char *p=str;
171 while (*p) p++;
172 while (p >= str && !WDL_IS_DIRCHAR(*p))
173 {
174 if (*p == '.')
175 {
176 *p = 0;
177 return p+1;
178 }
179 --p;
180 }
181 return NULL;
182 }
183
184 _WDL_CSTRING_PREFIX char WDL_remove_filepart(char *str) // returns dir character that was zeroed, or 0 if new string is empty
185 {
186 char *p=str;
187 while (*p) p++;
188 while (p >= str)
189 {
190 char c = *p;
191 if (WDL_IS_DIRCHAR(c))
192 {
193 *p = 0;
194 return c;
195 }
196 --p;
197 }
198 str[0] = 0;
199 return 0;
200 }
201
202 _WDL_CSTRING_PREFIX int WDL_remove_trailing_dirchars(char *str) // returns trailing dirchar count removed
203 {
204 int cnt = 0;
205 char *p=str;
206 while (*p) p++;
207 while (p > str+1 && WDL_IS_DIRCHAR(p[-1]))
208 {
209 cnt++;
210 p--;
211 }
212 *p = 0;
213 return cnt;
214 }
215
216 _WDL_CSTRING_PREFIX size_t WDL_remove_trailing_crlf(char *str) // returns new length
217 {
218 char *p=str;
219 while (*p) p++;
220 while (p > str && (p[-1] == '\r' || p[-1] == '\n')) p--;
221 *p = 0;
222 return p-str;
223 }
224
225 _WDL_CSTRING_PREFIX size_t WDL_remove_trailing_whitespace(char *str) // returns new length
226 {
227 char *p=str;
228 while (*p) p++;
229 while (p > str && (p[-1] == '\r' || p[-1] == '\n' || p[-1] == ' '|| p[-1] == '\t')) p--;
230 *p = 0;
231 return p-str;
232 }
233
234 _WDL_CSTRING_PREFIX char *WDL_remove_trailing_decimal_zeros(char *str, unsigned int keep)
235 // returns pointer to decimal point or end of string. removes final zeros after final decimal point only, keep=0 makes min length X, keep=1 X., keep=2 X.0, keep=3 X.00 etc
236 // treats commas as decimal points
237 {
238 char *end = str, *decimal, *last_z=NULL;
239 while (*end) end++;
240 decimal = end;
241 while (--decimal >= str && *decimal >= '0' && *decimal <= '9') if (!last_z && *decimal != '0') last_z = decimal+1;
242 if (decimal < str || (*decimal != '.' && *decimal != ',')) return end;
243 if (!last_z || last_z < decimal+keep) last_z = decimal+keep;
244 if (last_z < end)
245 {
246 *last_z=0;
247 if (!str[0] || ((str[0] == '.' || str[0] == ',') && !str[1]))
248 {
249 str[0]='0';
250 str[1]=0;
251 return str+1;
252 }
253 }
254 return decimal;
255 }
256
257 _WDL_CSTRING_PREFIX const char *WDL_sanitize_ini_key_start(const char *p) // used for sanitizing the beginning of "key" parameter to Write/GetPrivateProfile*. does not fully sanitize
258 {
259 while (*p == ' ' || *p == '\t' || *p == '[') p++;
260 return p;
261 }
262
263 _WDL_CSTRING_PREFIX void WDL_VARARG_WARN(printf,3,4) snprintf_append(char *o, INT_PTR count, const char *format, ...)
264 {
265 if (count>0)
266 {
267 va_list va;
268 while (*o) { if (--count < 1) return; o++; }
269 va_start(va,format);
270 vsnprintf(o,count,format,va);
271 va_end(va);
272 }
273 }
274
275 _WDL_CSTRING_PREFIX void vsnprintf_append(char *o, INT_PTR count, const char *format, va_list va)
276 {
277 if (count>0)
278 {
279 while (*o) { if (--count < 1) return; o++; }
280 vsnprintf(o,count,format,va);
281 }
282 }
283
284 _WDL_CSTRING_PREFIX int WDL_strcmp_logical(const char *s1, const char *s2, int case_sensitive)
285 {
286 // also exists as WDL_LogicalSortStringKeyedArray::_cmpstr()
287
288 for (;;)
289 {
290 if (*s1 >= '0' && *s1 <= '9' && *s2 >= '0' && *s2 <= '9')
291 {
292 int lzdiff=0, len1=0, len2=0;
293
294 while (*s1 == '0') { s1++; lzdiff--; }
295 while (*s2 == '0') { s2++; lzdiff++; }
296
297 while (s1[len1] >= '0' && s1[len1] <= '9') len1++;
298 while (s2[len2] >= '0' && s2[len2] <= '9') len2++;
299
300 if (len1 != len2) return len1-len2;
301
302 while (len1--)
303 {
304 const int d = *s1++ - *s2++;
305 if (d) return d;
306 }
307
308 if (lzdiff) return lzdiff;
309 }
310 else
311 {
312 char c1 = *s1++, c2 = *s2++;
313 if (c1 != c2)
314 {
315 if (case_sensitive) return c1-c2;
316
317 if (c1>='a' && c1<='z') c1+='A'-'a';
318 if (c2>='a' && c2<='z') c2+='A'-'a';
319 if (c1 != c2) return c1-c2;
320 }
321 else if (!c1) return 0;
322 }
323 }
324 }
325 _WDL_CSTRING_PREFIX const char *WDL_stristr(const char* a, const char* b)
326 {
327 const size_t blen = strlen(b);
328 while (*a)
329 {
330 if (!strnicmp(a, b, blen)) return a;
331 a++;
332 }
333 return NULL;
334 }
335
336
337#endif
338
339
340#ifdef __cplusplus
341};
342#endif
343
344#undef _WDL_CSTRING_PREFIX
345
346#endif
#define NULL
Definition CarlaBridgeFormat.cpp:30
uint8_t a
Definition Spc_Cpu.h:141
#define decimal(p)
unsigned d
Definition inflate.c:940
static void c2(register WDL_FFT_COMPLEX *a)
Definition fft.c:270
float in
Definition lilv_test.c:1460
intptr_t INT_PTR
Definition swell-types.h:42
#define strnicmp(x, y, z)
Definition swell-types.h:71
uch * p
Definition crypt.c:594
return c
Definition crypt.c:175
b
Definition crypt.c:628
#define _WDL_CSTRING_PREFIX
Definition wdlcstring.h:41
_WDL_CSTRING_PREFIX void INT_PTR count
Definition wdlcstring.h:263
_WDL_CSTRING_PREFIX const char * WDL_get_filepart(const char *str)
Definition wdlcstring.h:148
_WDL_CSTRING_PREFIX char * WDL_remove_fileext(char *str)
Definition wdlcstring.h:168
_WDL_CSTRING_PREFIX const char * WDL_get_fileext(const char *str)
Definition wdlcstring.h:155
_WDL_CSTRING_PREFIX char * WDL_remove_trailing_decimal_zeros(char *str, unsigned int keep)
Definition wdlcstring.h:234
_WDL_CSTRING_PREFIX void lstrcpyn_safe(char *o, const char *in, INT_PTR count)
Definition wdlcstring.h:129
_WDL_CSTRING_PREFIX size_t WDL_remove_trailing_crlf(char *str)
Definition wdlcstring.h:216
_WDL_CSTRING_PREFIX void INT_PTR const char * format
Definition wdlcstring.h:263
_WDL_CSTRING_PREFIX void lstrcatn(char *o, const char *in, INT_PTR count)
Definition wdlcstring.h:138
_WDL_CSTRING_PREFIX const char * WDL_sanitize_ini_key_start(const char *p)
Definition wdlcstring.h:257
_WDL_CSTRING_PREFIX size_t WDL_remove_trailing_whitespace(char *str)
Definition wdlcstring.h:225
_WDL_CSTRING_PREFIX int WDL_remove_trailing_dirchars(char *str)
Definition wdlcstring.h:202
_WDL_CSTRING_PREFIX char WDL_remove_filepart(char *str)
Definition wdlcstring.h:184
#define WDL_VARARG_WARN(x, n, s)
Definition wdltypes.h:86
#define WDL_IS_DIRCHAR(x)
Definition wdltypes.h:129
#define const
Definition zconf.h:137