view th_string.h @ 682:527a4d29d384

Typofix :S
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 04 Mar 2020 20:17:39 +0200
parents 39c82d877251
children 5a7254b78614
line wrap: on
line source

/*
 * Miscellaneous string-handling related utility-functions
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (C) Copyright 2002-2020 Tecnic Software productions (TNSP)
 *
 * Please read file 'COPYING' for information on license and distribution.
 */
/// @file
/// @brief String utility functions
#ifndef TH_STRING_H
#define TH_STRING_H

#include "th_util.h"
#include <ctype.h>

#ifdef __cplusplus
extern "C" {
#endif


/** @def String utility wrapper macros
 */
#define th_isalnum(c)   isalnum((int)(unsigned char) (c))
#define th_isalpha(c)   isalpha((int)(unsigned char) (c))
#define th_isascii(c)   isascii((int)(unsigned char) (c))
#define th_isblank(c)   isblank((int)(unsigned char) (c))
#define th_iscntrl(c)   iscntrl((int)(unsigned char) (c))
#define th_isdigit(c)   isdigit((int)(unsigned char) (c))
#define th_isgraph(c)   isgraph((int)(unsigned char) (c))
#define th_islower(c)   islower((int)(unsigned char) (c))
#define th_isprint(c)   isprint((int)(unsigned char) (c))
#define th_ispunct(c)   ispunct((int)(unsigned char) (c))
#define th_isspace(c)   isspace((int)(unsigned char) (c))
#define th_isupper(c)   isupper((int)(unsigned char) (c))
#define th_isxdigit(c)  isxdigit((int)(unsigned char) (c))
#define th_iscrlf(c)    ((c) == '\r' || (c) == '\n')

#define th_tolower(c)   tolower((int)(unsigned char) (c))
#define th_toupper(c)   toupper((int)(unsigned char) (c))


/** @brief
 * String trimming option flags for th_strdup_trim()
 */
enum
{
    TH_TRIM_START    = 1,  ///< Trim whitespace from start of the string
    TH_TRIM_END      = 2,  ///< Trim whitespace from end of the string
    TH_TRIM_BOTH     = 3,  ///< Trim whitespace from start and end of the string
};


typedef struct
{
    size_t nelems;
    th_char_t **elems;
} th_strelems_t;


/** @brief
 * Internal *printf() implementation flags
 */
enum
{
    TH_PF_NONE       = 0x0000,
    TH_PF_ALT        = 0x0001,
    TH_PF_SIGN       = 0x0002,
    TH_PF_SPACE      = 0x0004,
    TH_PF_GROUP      = 0x0008,

    TH_PF_ZERO       = 0x0100,
    TH_PF_LEFT       = 0x0200,

    TH_PF_LONG       = 0x1000,
    TH_PF_LONGLONG   = 0x2000,
    TH_PF_POINTER    = 0x4000,
    TH_PF_UPCASE     = 0x8000,
};


/** @struct th_vprintf_ctx
 * Internal printf() implementation context structure, contains state information
 * used by the printf() code for "output" purposes.
 */
typedef struct
{
    th_char_t *buf;           ///< Resulting string buffer pointer (might not be used if printing to file or such)
    size_t size;         ///< Size of result string buffer
    size_t pos;          ///< Current position in the buffer
    int ipos;            ///< Signed position
    void *data;          ///< Pointer to other data (for example a FILE pointer)
} th_vprintf_ctx;


/** @brief
 * A putch() helper function typedef for internal printf() implementation
 * @param[in,out] ctx pointer to internal printf() state context structure.
 * @param[in] ch character to be outputted
 * @returns the character @p ch cast to int or @c EOF in case of error
 */
typedef int (*th_vprintf_putch)(th_vprintf_ctx *ctx, const th_char_t ch);


/** @brief
 * Internal *printf() implementation helper function typedef
 * for alternative formatting, such as octal and hexadecimal
 */
typedef th_char_t * (*th_vprintf_altfmt_func)(
    const th_char_t *buf, const size_t len, const int vret, int *prec, int *flags, int *outlen);

#define TH_VPRINTF_ALTFMT_FUNC(fname) th_char_t * fname ( \
    const th_char_t *buf, const size_t len, const int vret, int *prec, int *flags, int *outlen)


TH_VPRINTF_ALTFMT_FUNC(th_vprintf_altfmt_oct);
TH_VPRINTF_ALTFMT_FUNC(th_vprintf_altfmt_hex);


/* Normal NUL-terminated string functions
 */
#ifdef TH_CHAR_TYPE
/**
 * Implementation of strlen() that uses th_char_t type. Not optimized.
 * @param[in] src string to get length of
 * @returns length of the string in number of th_char_t units.
 */
size_t th_strlen(const th_char_t *str)
{
    size_t len = 0;
    assert(str != NULL);

    while (str[len]) len++;

    return len;
}
#else
#define     th_strlen(xd) strlen(xd)
#endif


th_char_t   *th_strdup(const th_char_t *src);
th_char_t   *th_strndup(const th_char_t *src, const size_t n);
th_char_t   *th_strdup_trim(const th_char_t *src, const int flags);
th_char_t   *th_strndup_trim(const th_char_t *src, const size_t n, const int flags);

th_char_t   *th_strndup_no0(const th_char_t *src, const size_t len);
th_char_t   *th_strndup_no0_trim(const th_char_t *src, const size_t len, const int flags);

int         th_strcasecmp(const th_char_t *haystack, const th_char_t *needle);
int         th_strncasecmp(const th_char_t *haystack, const th_char_t *needle, size_t n);
th_char_t   *th_strrcasecmp(th_char_t *haystack, const th_char_t *needle);

int         th_vsnprintf(th_char_t *buf, size_t size, const th_char_t *fmt, va_list ap);
int         th_snprintf(th_char_t *buf, size_t size, const th_char_t *fmt, ...)
            TH_ATTR_PRINTF_FMT(3, 4);
int         th_vfprintf(FILE *fh, const th_char_t *fmt, va_list ap);
int         th_fprintf(FILE *fh, const th_char_t *fmt, ...)
            TH_ATTR_PRINTF_FMT(2, 3);


th_char_t   *th_strdup_vprintf(const th_char_t *fmt, va_list ap);
th_char_t   *th_strdup_printf(const th_char_t *fmt, ...)
            TH_ATTR_PRINTF_FMT(1, 2);

void        th_pstr_vprintf(th_char_t **buf, const th_char_t *fmt, va_list ap);
void        th_pstr_printf(th_char_t **buf, const th_char_t *fmt, ...)
            TH_ATTR_PRINTF_FMT(2, 3);

int         th_pstr_cpy(th_char_t **pdst, const th_char_t *src);
int         th_pstr_cat(th_char_t **pdst, const th_char_t *src);

int         th_split_string_elems(const th_char_t *str, th_strelems_t *ctx, const th_char_t *sep);
int         th_split_string(const th_char_t *str, th_char_t ***elems, size_t *nelems, const th_char_t *sep);
int         th_join_string_elems(th_char_t **str, const th_strelems_t *ctx, const th_char_t *sep);
int         th_join_string(th_char_t **str, th_char_t **elems, const size_t nelems, const th_char_t *sep);
void        th_strelems_free(th_strelems_t *ctx);


/* Internal printf() implementation. NOTICE! This API may be unstable.
 */
int         th_vprintf_do(th_vprintf_ctx *ctx, th_vprintf_putch vputch,
            const th_char_t *fmt, va_list ap);

int         th_vprintf_put_str(th_vprintf_ctx *ctx, th_vprintf_putch vputch,
            const th_char_t *str, int f_flags, const int f_width, const int f_prec);

int 	    th_vprintf_put_int(th_vprintf_ctx *ctx, th_vprintf_putch vputch,
            va_list ap, const int f_radix, int f_flags, int f_width, int f_prec,
            const BOOL f_unsig, th_vprintf_altfmt_func f_alt);

int	    th_vprintf_put_int_format(th_vprintf_ctx *ctx, th_vprintf_putch vputch,
            th_char_t *buf, int f_flags, int f_width, int f_prec, int f_len, int vret,
            BOOL f_neg, BOOL f_unsig, th_vprintf_altfmt_func f_alt);


#define TH_VPRINTF_INTFMT_NAME th_vprintf_buf_int
#define TH_VPRINTF_INTFMT_TYPE_S int
#define TH_VPRINTF_INTFMT_TYPE_U unsigned int
#define TH_VPRINTF_INTFMT_HEADER 1
#include "th_printf1.c"


#define TH_VPRINTF_INTFMT_NAME th_vprintf_buf_int64
#define TH_VPRINTF_INTFMT_TYPE_S int64_t
#define TH_VPRINTF_INTFMT_TYPE_U uint64_t
#define TH_VPRINTF_INTFMT_HEADER 1
#include "th_printf1.c"


#ifdef TH_PRINTF_DEBUG
extern BOOL th_printf_debug;
extern char *th_printf_debug_prefix;
#endif


/* Parsing, matching
 */
const th_char_t  *th_findnext(const th_char_t *str, size_t *pos);
const th_char_t  *th_findsep(const th_char_t *str, size_t *pos, const th_char_t sep);
const th_char_t  *th_findseporspace(const th_char_t *str, size_t *pos, const th_char_t sep);

BOOL        th_strmatch(const th_char_t *haystack, const th_char_t *pattern);
BOOL        th_strcasematch(const th_char_t *haystack, const th_char_t *pattern);

BOOL        th_get_hex_triplet(const th_char_t *str, unsigned int *value);
BOOL        th_get_boolean(const th_char_t *str, BOOL *value);
BOOL        th_get_int(const th_char_t *str, unsigned int *value, BOOL *neg);


#ifdef __cplusplus
}
#endif
#endif // TH_STRING_H