diff options
Diffstat (limited to 'Src/ns-eel2/wdlcstring.h')
-rw-r--r-- | Src/ns-eel2/wdlcstring.h | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/Src/ns-eel2/wdlcstring.h b/Src/ns-eel2/wdlcstring.h new file mode 100644 index 00000000..71a248e6 --- /dev/null +++ b/Src/ns-eel2/wdlcstring.h @@ -0,0 +1,316 @@ +/* + WDL - wdlcstring.h + Copyright (C) 2005 and later, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* +C string manipulation utilities -- [v]snprintf for Win32, also snprintf_append, lstrcatn, etc + */ +#ifndef _WDL_CSTRING_H_ +#define _WDL_CSTRING_H_ + +#include <stdarg.h> +#include <stdio.h> +#include <ctype.h> + +#include "wdltypes.h" + +#ifdef _WDL_CSTRING_IMPL_ONLY_ + #ifdef _WDL_CSTRING_IF_ONLY_ + #undef _WDL_CSTRING_IF_ONLY_ + #endif + #define _WDL_CSTRING_PREFIX +#else + #define _WDL_CSTRING_PREFIX static WDL_STATICFUNC_UNUSED +#endif + + + +#if defined(_WIN32) && defined(_MSC_VER) + // provide snprintf()/vsnprintf() for win32 -- note that these have no way of knowing + // what the amount written was, code should(must) be written to not depend on this. + #ifdef snprintf + #undef snprintf + #endif + #define snprintf WDL_snprintf + + #ifdef vsnprintf + #undef vsnprintf + #endif + #define vsnprintf WDL_vsnprintf + +#endif // win32 snprintf/vsnprintf + +// use wdlcstring.h's lstrcpyn_safe rather than the real lstrcpyn. +#ifdef _WIN32 + #ifdef lstrcpyn + #undef lstrcpyn + #endif + #define lstrcpyn lstrcpyn_safe +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WDL_CSTRING_IF_ONLY_ + + void lstrcpyn_safe(char *o, const char *in, INT_PTR count); + void lstrcatn(char *o, const char *in, INT_PTR count); + void WDL_VARARG_WARN(printf,3,4) snprintf_append(char *o, INT_PTR count, const char *format, ...); + void vsnprintf_append(char *o, INT_PTR count, const char *format, va_list va); + + const char *WDL_get_filepart(const char *str); // returns whole string if no dir chars + const char *WDL_get_fileext(const char *str); // returns ".ext" or end of string "" if no extension + char *WDL_remove_fileext(char *str); // returns pointer to "ext" if ".ext" was removed (zero-d dot), or NULL + char WDL_remove_filepart(char *str); // returns dir character that was zeroed, or 0 if new string is empty + int WDL_remove_trailing_dirchars(char *str); // returns trailing dirchar count removed, will not convert "/" into "" + size_t WDL_remove_trailing_crlf(char *str); // returns new length + + + #if defined(_WIN32) && defined(_MSC_VER) + void WDL_vsnprintf(char *o, size_t count, const char *format, va_list args); + void WDL_VARARG_WARN(printf,3,4) WDL_snprintf(char *o, size_t count, const char *format, ...); + #endif + + int WDL_strcmp_logical(const char *s1, const char *s2, int case_sensitive); +#else + + + #if defined(_WIN32) && defined(_MSC_VER) + + _WDL_CSTRING_PREFIX void WDL_vsnprintf(char *o, size_t count, const char *format, va_list args) + { + if (count>0) + { + int rv; + o[0]=0; + rv=_vsnprintf(o,count,format,args); // returns -1 if over, and does not null terminate, ugh + if (rv < 0 || rv>=(int)count-1) o[count-1]=0; + } + } + _WDL_CSTRING_PREFIX void WDL_VARARG_WARN(printf,3,4) WDL_snprintf(char *o, size_t count, const char *format, ...) + { + if (count>0) + { + int rv; + va_list va; + va_start(va,format); + o[0]=0; + rv=_vsnprintf(o,count,format,va); // returns -1 if over, and does not null terminate, ugh + va_end(va); + + if (rv < 0 || rv>=(int)count-1) o[count-1]=0; + } + } + #endif + + _WDL_CSTRING_PREFIX void lstrcpyn_safe(char *o, const char *in, INT_PTR count) + { + if (count>0) + { + while (--count>0 && *in) *o++ = *in++; + *o=0; + } + } + + _WDL_CSTRING_PREFIX void lstrcatn(char *o, const char *in, INT_PTR count) + { + if (count>0) + { + while (*o) { if (--count < 1) return; o++; } + while (--count>0 && *in) *o++ = *in++; + *o=0; + } + } + + _WDL_CSTRING_PREFIX const char *WDL_get_filepart(const char *str) // returns whole string if no dir chars + { + const char *p = str; + while (*p) p++; + while (p >= str && !WDL_IS_DIRCHAR(*p)) --p; + return p + 1; + } + _WDL_CSTRING_PREFIX const char *WDL_get_fileext(const char *str) // returns ".ext" or end of string "" if no extension + { + const char *p=str, *ep; + while (*p) p++; + ep = p; + while (p >= str && !WDL_IS_DIRCHAR(*p)) + { + if (*p == '.') return p; + --p; + } + return ep; + } + + _WDL_CSTRING_PREFIX char *WDL_remove_fileext(char *str) // returns pointer to "ext" if ".ext" was removed (zero-d dot), or NULL + { + char *p=str; + while (*p) p++; + while (p >= str && !WDL_IS_DIRCHAR(*p)) + { + if (*p == '.') + { + *p = 0; + return p+1; + } + --p; + } + return NULL; + } + + _WDL_CSTRING_PREFIX char WDL_remove_filepart(char *str) // returns dir character that was zeroed, or 0 if new string is empty + { + char *p=str; + while (*p) p++; + while (p >= str) + { + char c = *p; + if (WDL_IS_DIRCHAR(c)) + { + *p = 0; + return c; + } + --p; + } + str[0] = 0; + return 0; + } + + _WDL_CSTRING_PREFIX int WDL_remove_trailing_dirchars(char *str) // returns trailing dirchar count removed + { + int cnt = 0; + char *p=str; + while (*p) p++; + while (p > str+1 && WDL_IS_DIRCHAR(p[-1])) + { + cnt++; + p--; + } + *p = 0; + return cnt; + } + + _WDL_CSTRING_PREFIX size_t WDL_remove_trailing_crlf(char *str) // returns new length + { + char *p=str; + while (*p) p++; + while (p > str && (p[-1] == '\r' || p[-1] == '\n')) p--; + *p = 0; + return p-str; + } + + _WDL_CSTRING_PREFIX void WDL_VARARG_WARN(printf,3,4) snprintf_append(char *o, INT_PTR count, const char *format, ...) + { + if (count>0) + { + va_list va; + while (*o) { if (--count < 1) return; o++; } + va_start(va,format); + vsnprintf(o,count,format,va); + va_end(va); + } + } + + _WDL_CSTRING_PREFIX void vsnprintf_append(char *o, INT_PTR count, const char *format, va_list va) + { + if (count>0) + { + while (*o) { if (--count < 1) return; o++; } + vsnprintf(o,count,format,va); + } + } + + _WDL_CSTRING_PREFIX int WDL_strcmp_logical(const char *s1, const char *s2, int case_sensitive) + { + // also exists as WDL_LogicalSortStringKeyedArray::_cmpstr() + + char lastNonZeroChar=0; + // last matching character, updated if not 0. this allows us to track whether + // we are inside of a number with the same leading digits + + for (;;) + { + char c1=*s1++, c2=*s2++; + if (!c1) return c1-c2; + + if (c1!=c2) + { + if (c1 >= '0' && c1 <= '9' && c2 >= '0' && c2 <= '9') + { + int lzdiff=0, cnt=0; + if (lastNonZeroChar < '1' || lastNonZeroChar > '9') + { + while (c1 == '0') { c1=*s1++; lzdiff--; } + while (c2 == '0') { c2=*s2++; lzdiff++; } // lzdiff = lz2-lz1, more leading 0s = earlier in list + } + + for (;;) + { + if (c1 >= '0' && c1 <= '9') + { + if (c2 < '0' || c2 > '9') return 1; + + c1=s1[cnt]; + c2=s2[cnt++]; + } + else + { + if (c2 >= '0' && c2 <= '9') return -1; + break; + } + } + + s1--; + s2--; + + while (cnt--) + { + const int d = *s1++ - *s2++; + if (d) return d; + } + + if (lzdiff) return lzdiff; + } + else + { + if (!case_sensitive) + { + if (c1>='a' && c1<='z') c1+='A'-'a'; + if (c2>='a' && c2<='z') c2+='A'-'a'; + } + if (c1 != c2) return c1-c2; + } + } + else if (c1 != '0') lastNonZeroChar=c1; + } + } + +#endif + + +#ifdef __cplusplus +}; +#endif + +#undef _WDL_CSTRING_PREFIX + +#endif |