mirror of
https://codeberg.org/1414codeforge/ubgpsuite.git
synced 2025-06-05 21:29:11 +02:00
[*] Initial commit
This commit is contained in:
198
lonetix/include/df/strlib.h
Normal file
198
lonetix/include/df/strlib.h
Normal file
@ -0,0 +1,198 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
/**
|
||||
* \file strlib.h
|
||||
*
|
||||
* Additional ASCII string and char classification utility library.
|
||||
*
|
||||
* \copyright The DoubleFourteen Code Forge (c) All Rights Reserved
|
||||
* \author Lorenzo Cogotti
|
||||
*/
|
||||
|
||||
#ifndef DF_STRLIB_H_
|
||||
#define DF_STRLIB_H_
|
||||
|
||||
#include "xpt.h"
|
||||
|
||||
/// Test whether `c` is a digit `char`.
|
||||
FORCE_INLINE Boolean Df_isdigit(char c)
|
||||
{
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
/// Test whether `c` is an uppercase ASCII `char`.
|
||||
FORCE_INLINE Boolean Df_isupper(char c)
|
||||
{
|
||||
return c >= 'A' && c <= 'Z';
|
||||
}
|
||||
|
||||
/// Test whether `c` is a lowercase ASCII `char`.
|
||||
FORCE_INLINE Boolean Df_islower(char c)
|
||||
{
|
||||
return c >= 'a' && c <= 'z';
|
||||
}
|
||||
|
||||
/// Test whether `c` is an ASCII space `char`.
|
||||
FORCE_INLINE Boolean Df_isspace(char c)
|
||||
{
|
||||
return c == ' ' || (c >= '\t' && c <= '\n');
|
||||
}
|
||||
|
||||
/// Test whether `c` is an alphabetic ASCII `char`.
|
||||
FORCE_INLINE Boolean Df_isalpha(char c)
|
||||
{
|
||||
return Df_islower(c) || Df_isupper(c);
|
||||
}
|
||||
|
||||
/// Test whether `c` is an alphanumeric ASCII `char`.
|
||||
FORCE_INLINE Boolean Df_isalnum(char c)
|
||||
{
|
||||
return Df_isdigit(c) || Df_isalpha(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert `c` to uppercase ASCII `char`.
|
||||
*
|
||||
* \return Uppercase `c`, if `c` is lowecase, otherwise
|
||||
* returns `c` itself.
|
||||
*/
|
||||
FORCE_INLINE char Df_toupper(char c)
|
||||
{
|
||||
// Toggle off lowercase bit if c is lowercase
|
||||
return c & ~(Df_islower(c) << 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert `c` to lowercase ASCII `char`.
|
||||
*
|
||||
* \return Lowercase `c`, if `c` is uppercase, otherwise returns `c` itself.
|
||||
*/
|
||||
FORCE_INLINE char Df_tolower(char c)
|
||||
{
|
||||
// Only toggle lowercase bit if c is uppercase
|
||||
return c | (Df_isupper(c) << 5);
|
||||
}
|
||||
|
||||
/// Test whether `c` is an hexadecimal digit `char`.
|
||||
FORCE_INLINE Boolean Df_ishexdigit(char c)
|
||||
{
|
||||
char lc = Df_tolower(c);
|
||||
|
||||
return Df_isdigit(c) || (lc >= 'a' && lc <= 'f');
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Concatenate `dest` with `s`, writing at most `n` `char`s to `dest`
|
||||
* (including `\0`).
|
||||
*
|
||||
* \return `strlen(dest) + strlen(s)` before concatenation, that is:
|
||||
* the length of the concatenated string without truncation,
|
||||
* truncation occurred if return value `>= n`.
|
||||
*
|
||||
* \note Function always terminates `dest` with `\0`.
|
||||
*/
|
||||
size_t Df_strncatz(char *dest, const char *s, size_t n);
|
||||
/**
|
||||
* \brief Copy at most `n` `char`s from `s` to `dest` (including `\0`).
|
||||
*
|
||||
* \return The length of `s`, truncation occurred if return value `>= n`.
|
||||
*
|
||||
* \note Function always terminates `dest` with `\0`.
|
||||
*/
|
||||
size_t Df_strncpyz(char *dest, const char *s, size_t n);
|
||||
/// Compare ASCII strings `a` and `b` ignoring case.
|
||||
int Df_stricmp(const char *a, const char *b);
|
||||
/// Compare at most `n` chars from ASCII strings `a` and `b`, ignoring case.
|
||||
int Df_strnicmp(const char *a, const char *b, size_t n);
|
||||
|
||||
/// Convert ASCII string to lowercase, returns `s` itself.
|
||||
FORCE_INLINE char *Df_strlwr(char *s)
|
||||
{
|
||||
char *p = s;
|
||||
char c;
|
||||
|
||||
while ((c = *p) != '\0')
|
||||
*p++ = Df_tolower(c);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Convert ASCII string to uppercase, returns `s` itself.
|
||||
FORCE_INLINE char *Df_strupr(char *s)
|
||||
{
|
||||
char *p = s;
|
||||
char c;
|
||||
|
||||
while ((c = *p) != '\0')
|
||||
*p++ = Df_toupper(c);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Trim trailing whitespaces in-place, returns `s` itself.
|
||||
INLINE char *Df_strtrimr(char *s)
|
||||
{
|
||||
EXTERNC size_t strlen(const char *);
|
||||
|
||||
size_t n = strlen(s);
|
||||
while (n > 0 && Df_isspace(s[n-1])) n--;
|
||||
|
||||
s[n] = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Trim leading whitespaces in-place, returns `s` itself.
|
||||
INLINE char *Df_strtriml(char *s)
|
||||
{
|
||||
char *p1 = s, *p2 = s;
|
||||
|
||||
while (Df_isspace(*p1)) p1++;
|
||||
while ((*p2++ = *p1++) != '\0');
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Trim leading and trailing whitespaces in-place, returns `s` itself.
|
||||
INLINE char *Df_strtrim(char *s)
|
||||
{
|
||||
Df_strtrimr(s);
|
||||
return Df_strtriml(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Pad string to left with `c` up to `n` ASCII chars.
|
||||
*
|
||||
* \return Resulting string length.
|
||||
*/
|
||||
INLINE size_t Df_strpadl(char *s, char c, size_t n)
|
||||
{
|
||||
EXTERNC size_t strlen(const char *);
|
||||
EXTERNC void *memmove(void *, const void *, size_t);
|
||||
EXTERNC void *memset(void *, int, size_t);
|
||||
|
||||
size_t len = strlen(s);
|
||||
if (len < n) {
|
||||
memmove(s + n - len, s, len + 1);
|
||||
memset(s, c, n - len);
|
||||
len = n;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Pad string to right with `c` up to `n` ASCII chars.
|
||||
*
|
||||
* \return Resulting string length.
|
||||
*/
|
||||
INLINE size_t Df_strpadr(char *s, char c, size_t n)
|
||||
{
|
||||
EXTERNC size_t strlen(const char *);
|
||||
|
||||
size_t i = strlen(s);
|
||||
while (i < n) s[i++] = c;
|
||||
|
||||
s[i] = '\0';
|
||||
return i;
|
||||
}
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user