2023-03-06 14:42:04 +01:00
|
|
|
// SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
// author: Max Kellermann <max.kellermann@gmail.com>
|
2015-03-05 07:47:42 +01:00
|
|
|
|
2015-09-01 21:12:16 +02:00
|
|
|
#ifndef STRING_API_HXX
|
|
|
|
#define STRING_API_HXX
|
2015-03-05 07:47:42 +01:00
|
|
|
|
2020-05-01 04:25:55 +02:00
|
|
|
#include <cstring>
|
2015-03-05 07:47:42 +01:00
|
|
|
|
2015-03-05 08:05:31 +01:00
|
|
|
#ifdef _UNICODE
|
|
|
|
#include "WStringAPI.hxx"
|
|
|
|
#endif
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 07:47:42 +01:00
|
|
|
static inline size_t
|
2017-05-08 14:44:49 +02:00
|
|
|
StringLength(const char *p) noexcept
|
2015-03-05 07:47:42 +01:00
|
|
|
{
|
|
|
|
return strlen(p);
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 07:47:42 +01:00
|
|
|
static inline const char *
|
2017-05-08 14:44:49 +02:00
|
|
|
StringFind(const char *haystack, const char *needle) noexcept
|
2015-03-05 07:47:42 +01:00
|
|
|
{
|
|
|
|
return strstr(haystack, needle);
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 07:47:42 +01:00
|
|
|
static inline char *
|
2017-05-08 14:44:49 +02:00
|
|
|
StringFind(char *haystack, char needle, size_t size) noexcept
|
2015-03-05 07:47:42 +01:00
|
|
|
{
|
2020-05-01 04:25:55 +02:00
|
|
|
return (char *)std::memchr(haystack, needle, size);
|
2015-03-05 07:47:42 +01:00
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 07:47:42 +01:00
|
|
|
static inline const char *
|
2017-05-08 14:44:49 +02:00
|
|
|
StringFind(const char *haystack, char needle, size_t size) noexcept
|
2015-03-05 07:47:42 +01:00
|
|
|
{
|
2020-05-01 04:25:55 +02:00
|
|
|
return (const char *)std::memchr(haystack, needle, size);
|
2015-03-05 07:47:42 +01:00
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 07:47:42 +01:00
|
|
|
static inline const char *
|
2017-05-08 14:44:49 +02:00
|
|
|
StringFind(const char *haystack, char needle) noexcept
|
2015-03-05 07:47:42 +01:00
|
|
|
{
|
2020-05-01 04:25:55 +02:00
|
|
|
return std::strchr(haystack, needle);
|
2015-03-05 07:47:42 +01:00
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 07:47:42 +01:00
|
|
|
static inline char *
|
2017-05-08 14:44:49 +02:00
|
|
|
StringFind(char *haystack, char needle) noexcept
|
2015-03-05 07:47:42 +01:00
|
|
|
{
|
2020-05-01 04:25:55 +02:00
|
|
|
return std::strchr(haystack, needle);
|
2015-03-05 07:47:42 +01:00
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 07:47:42 +01:00
|
|
|
static inline const char *
|
2017-05-08 14:44:49 +02:00
|
|
|
StringFindLast(const char *haystack, char needle) noexcept
|
2015-03-05 07:47:42 +01:00
|
|
|
{
|
2020-05-01 04:25:55 +02:00
|
|
|
return std::strrchr(haystack, needle);
|
2015-03-05 07:47:42 +01:00
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 07:47:42 +01:00
|
|
|
static inline char *
|
2017-05-08 14:44:49 +02:00
|
|
|
StringFindLast(char *haystack, char needle) noexcept
|
2015-03-05 07:47:42 +01:00
|
|
|
{
|
2020-05-01 04:25:55 +02:00
|
|
|
return std::strrchr(haystack, needle);
|
2015-03-05 07:47:42 +01:00
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2019-09-07 23:59:59 +02:00
|
|
|
static inline const char *
|
|
|
|
StringFindLast(const char *haystack, char needle, size_t size) noexcept
|
|
|
|
{
|
|
|
|
#if defined(__GLIBC__) || defined(__BIONIC__)
|
|
|
|
/* memrchr() is a GNU extension (and also available on
|
|
|
|
Android) */
|
|
|
|
return (const char *)memrchr(haystack, needle, size);
|
|
|
|
#else
|
|
|
|
/* emulate for everybody else */
|
|
|
|
const auto *p = haystack + size;
|
|
|
|
while (p > haystack) {
|
|
|
|
--p;
|
|
|
|
if (*p == needle)
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2018-07-18 15:59:41 +02:00
|
|
|
static inline const char *
|
|
|
|
StringFindAny(const char *haystack, const char *accept) noexcept
|
|
|
|
{
|
|
|
|
return strpbrk(haystack, accept);
|
|
|
|
}
|
|
|
|
|
2017-05-16 23:04:27 +02:00
|
|
|
static inline char *
|
|
|
|
StringToken(char *str, const char *delim) noexcept
|
|
|
|
{
|
|
|
|
return strtok(str, delim);
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::nonnull]]
|
2015-03-05 07:47:42 +01:00
|
|
|
static inline void
|
2017-05-08 14:44:49 +02:00
|
|
|
UnsafeCopyString(char *dest, const char *src) noexcept
|
2015-03-05 07:47:42 +01:00
|
|
|
{
|
|
|
|
strcpy(dest, src);
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::returns_nonnull]] [[gnu::nonnull]]
|
2015-09-01 21:16:08 +02:00
|
|
|
static inline char *
|
2017-05-08 14:44:49 +02:00
|
|
|
UnsafeCopyStringP(char *dest, const char *src) noexcept
|
2015-09-01 21:16:08 +02:00
|
|
|
{
|
2018-08-20 13:31:23 +02:00
|
|
|
#if defined(_WIN32)
|
2017-05-16 23:01:43 +02:00
|
|
|
/* emulate stpcpy() */
|
|
|
|
UnsafeCopyString(dest, src);
|
|
|
|
return dest + StringLength(dest);
|
2015-09-01 21:16:08 +02:00
|
|
|
#else
|
2017-05-16 23:01:43 +02:00
|
|
|
return stpcpy(dest, src);
|
2015-09-01 21:16:08 +02:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2018-07-18 17:18:34 +02:00
|
|
|
static inline int
|
|
|
|
StringCompare(const char *a, const char *b) noexcept
|
|
|
|
{
|
|
|
|
return strcmp(a, b);
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2019-04-16 14:01:59 +02:00
|
|
|
static inline int
|
|
|
|
StringCompare(const char *a, const char *b, size_t n) noexcept
|
|
|
|
{
|
|
|
|
return strncmp(a, b, n);
|
|
|
|
}
|
|
|
|
|
2015-03-05 07:47:42 +01:00
|
|
|
/**
|
|
|
|
* Checks whether #a and #b are equal.
|
|
|
|
*/
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 07:47:42 +01:00
|
|
|
static inline bool
|
2017-05-08 14:44:49 +02:00
|
|
|
StringIsEqual(const char *a, const char *b) noexcept
|
2015-03-05 07:47:42 +01:00
|
|
|
{
|
2018-08-20 15:31:09 +02:00
|
|
|
return StringCompare(a, b) == 0;
|
2015-03-05 07:47:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks whether #a and #b are equal.
|
|
|
|
*/
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2015-03-05 07:47:42 +01:00
|
|
|
static inline bool
|
2017-05-08 14:44:49 +02:00
|
|
|
StringIsEqual(const char *a, const char *b, size_t length) noexcept
|
2015-03-05 07:47:42 +01:00
|
|
|
{
|
|
|
|
return strncmp(a, b, length) == 0;
|
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2017-05-16 23:04:27 +02:00
|
|
|
static inline bool
|
|
|
|
StringIsEqualIgnoreCase(const char *a, const char *b) noexcept
|
|
|
|
{
|
2021-07-23 05:49:12 +02:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
return _stricmp(a, b) == 0;
|
|
|
|
#else
|
2017-05-16 23:04:27 +02:00
|
|
|
return strcasecmp(a, b) == 0;
|
2021-07-23 05:49:12 +02:00
|
|
|
#endif
|
2017-05-16 23:04:27 +02:00
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2017-05-16 23:04:27 +02:00
|
|
|
static inline bool
|
|
|
|
StringIsEqualIgnoreCase(const char *a, const char *b, size_t size) noexcept
|
|
|
|
{
|
2021-07-23 05:49:12 +02:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
return _strnicmp(a, b, size) == 0;
|
|
|
|
#else
|
2017-05-16 23:04:27 +02:00
|
|
|
return strncasecmp(a, b, size) == 0;
|
2021-07-23 05:49:12 +02:00
|
|
|
#endif
|
2017-05-16 23:04:27 +02:00
|
|
|
}
|
|
|
|
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::pure]] [[gnu::nonnull]]
|
2017-05-16 23:04:27 +02:00
|
|
|
static inline int
|
|
|
|
StringCollate(const char *a, const char *b) noexcept
|
|
|
|
{
|
|
|
|
return strcoll(a, b);
|
|
|
|
}
|
|
|
|
|
2015-03-05 07:47:42 +01:00
|
|
|
/**
|
|
|
|
* Copy the string to a new allocation. The return value must be
|
|
|
|
* freed with free().
|
|
|
|
*/
|
2021-07-22 13:16:02 +02:00
|
|
|
[[gnu::malloc]] [[gnu::returns_nonnull]] [[gnu::nonnull]]
|
2015-03-05 07:47:42 +01:00
|
|
|
static inline char *
|
2017-05-16 23:02:36 +02:00
|
|
|
DuplicateString(const char *p) noexcept
|
2015-03-05 07:47:42 +01:00
|
|
|
{
|
|
|
|
return strdup(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|