~crm/cstring

d2a6d689d0f34b7ccc60a1ac7515212a345a2a4a — Christos Margiolis 3 years ago 805f9ac
updated manpage, added sort functions, pending erase bug fixes
3 files changed, 124 insertions(+), 20 deletions(-)

M cstring.3
M cstring.c
M cstring.h
M cstring.3 => cstring.3 +52 -8
@@ 1,7 1,44 @@
.TH cstring 3
.SH NAME
cstring \- A simple and lightweight string library for C inspired by C++'s
.B cstring
\- A simple and lightweight string library for C inspired by C++'s
STL string class
.SH SYNOPSIS
#include <cstring.h>
.SH DESCRIPTION
.P
The
.B cstring
library offers a lightweight and fast way to manage
strings with a wide range of useful functions.
.P
A program using
.B cstring
has to be linked using the
.B \-lcstring
option.
.P
In case you want to run the program in debug mode, compile
it with the
.B -DCSTRING_DEBUG
option.
.SH STRUCTURES AND ENUMS
.TP
.BR cstring
typedef struct cstring {
    char   *str;      /* contents of string */
    size_t  len;      /* string length */
    size_t  capacity; /* string capacity */
.br
};
.TP
.BR cstring_flags
enum cstring_flags {
    CSTRING_ASCENDING,  /* sort in ascending order */
    CSTRING_DESCENDING, /* sort in descending order */
    CSTRING_CALLBACK    /* use your own sort function */
.br
};
.SH FUNCTIONS
.TP
.BR cstring\ cstring_create(const\ char\ *s)


@@ 54,6 91,20 @@ Extract a substring from current string.
.BR void\ cstring_swap(cstring\ *lhs,\ cstring\ *rhs)
Swap contents of two strings.
.TP
.BR void\ cstring_sort(cstring\ **cs,\ size_t\ len,\ enum\ cstring_flags\ flags,\ int\ (*callback)(const\ void\ *lhs,\ const\ void\ *rhs))
Sort an array of cstrings. If you want to use the builtin comparison pass
.I NULL
in the last argument. In case you want to use your own callback use the
.I CSTRING_CALLBACK
flag and pass your own callback function in the last argument.
.TP
.BR void\ cstring_sort_chars(cstring\ *cs,\ enum\ cstring_flags\ flags,\ int\ (*callback)(const\ void\ *lhs,\ const\ void\ *rhs))
Sort a cstring's contents. If you want to use the builtin comparison pass
.I NULL
in the last argument. In case you want to use your own callback use the
.I CSTRING_CALLBACK
flag and pass your own callback function in the last argument.
.TP
.BR void\ cstring_shrink_to_fit(cstring\ *cs)
Reduce string's capacity to its size.
.TP


@@ 151,13 202,6 @@ Print contents of a normal string.
.BR CSTRING_NPOS
This constant signifies that a pattern hasn't been found inside
the string. It's value is -1.
.SH OPTIONS
.TP
.BR CSTRING_DEBUG
Runs in debug mode if it is defined. In order to define it compile
the library with the
.I -DCSTRING_DEBUG
option.
.SH USAGE
You must
.B always

M cstring.c => cstring.c +61 -10
@@ 2,6 2,12 @@

#define CSTRING_EXCEEDS_CAPACITY(len, cap)  ((len) >= (cap))

#define CSTRING_FIND_OCCURENCE(cs, s, func) do {                          \
    char *_found;                                                         \
    if ((_found = func(cs->str, (s))) != NULL)                            \
        return (_found - cs->str);                                        \
} while (0)

#ifdef CSTRING_DBG
#define CSTRING_FREE(cs) do {                                             \
    CSTRING_DBG_LOG("Before CSTRING_FREE: %s\n", cs->str);                \


@@ 13,9 19,9 @@
#define CSTRING_EXPECTED_ERASE_STR(cs, pos, len) do {                     \
    CSTRING_DBG_LOG("%s", "CSTRING_EXPECTED_ERASE_STR: ");                \
    size_t _i;                                                            \
    for (_i = 0; _i < pos; _i++)                                          \
    for (_i = 0; _i < (pos); _i++)                                        \
        printf("%c", cs->str[_i]);                                        \
    for (_i = pos + len; _i < cs->len; _i++)                              \
    for (_i = (pos) + (len); _i < cs->len; _i++)                          \
        printf("%c", cs->str[_i]);                                        \
    printf("\n");                                                         \
} while (0)


@@ 29,12 35,6 @@
} while (0)
#endif /* CSTRING_DBG */

#define CSTRING_FIND_OCCURENCE(cs, s, func) do {                          \
    char *_found;                                                         \
    if ((_found = func(cs->str, (s))) != NULL)                            \
        return (_found - cs->str);                                        \
} while (0)

static int
cstring_is_one_of(char c, const char *s)
{


@@ 44,6 44,30 @@ cstring_is_one_of(char c, const char *s)
    return 0;
}

static inline int
cstring_cmp_greater(const void *lhs, const void *rhs)
{
    return cstring_greater((cstring *)lhs, (cstring *)rhs);
}

static inline int
cstring_cmp_less(const void *lhs, const void *rhs)
{
    return cstring_less((cstring *)lhs, (cstring *)rhs);
}

static inline int
cstring_cmp_char_greater(const void *lhs, const void *rhs)
{
    return (*(char *)lhs > *(char *)rhs);
}

static inline int
cstring_cmp_char_less(const void *lhs, const void *rhs)
{
    return (*(char *)lhs < *(char *)rhs);
}

cstring
cstring_create(const char *s)
{


@@ 219,6 243,33 @@ cstring_swap(cstring *lhs, cstring *rhs)
}

void
cstring_sort(cstring **cs,
             size_t len,
             enum cstring_flags flags,
             int (*callback)(const void *lhs, const void *rhs))
{
    if (flags == CSTRING_ASCENDING)
        qsort(cs, len, sizeof(cstring *), cstring_cmp_greater);
    else if (flags == CSTRING_DESCENDING)
        qsort(cs, len, sizeof(cstring *), cstring_cmp_less);
    else if (flags == CSTRING_CALLBACK)
        qsort(cs, len, sizeof(cstring *), callback);
}

void
cstring_sort_chars(cstring *cs,
                   enum cstring_flags flags,
                   int (*callback)(const void *lhs, const void *rhs))
{
    if (flags == CSTRING_ASCENDING)
        qsort(cs->str, cs->len, sizeof(char), cstring_cmp_char_greater);
    else if (flags == CSTRING_DESCENDING)
        qsort(cs->str, cs->len, sizeof(char), cstring_cmp_char_less);
    else if (flags == CSTRING_CALLBACK)
        qsort(cs->str, cs->len, sizeof(char), callback);
}

void
cstring_clear(cstring *cs)
{
    CSTRING_FREE(cs);


@@ 228,8 279,8 @@ cstring_clear(cstring *cs)
    cs->capacity = 0;
}

#define CSTRING_CHECK(cs, s)      \
    if (cstring_empty(cs) || !*s) \
#define CSTRING_CHECK(cs, s)        \
    if (cstring_empty(cs) || !*(s)) \
        return CSTRING_NPOS

size_t

M cstring.h => cstring.h +11 -2
@@ 32,7 32,7 @@ extern "C" {
            cs.str, cs.len, cs.capacity)

#define CSTRING_DBG_LOG_STR_INFO(s, len)                             \
    CSTRING_DBG_LOG("S: %s | LEN: %ld\n", s, len)
    CSTRING_DBG_LOG("S: %s | LEN: %ld\n", (s), (len))
#endif /* CSTRING_DBG */

typedef struct cstring {


@@ 41,6 41,12 @@ typedef struct cstring {
    size_t  capacity;
} cstring;

enum cstring_flags {
    CSTRING_ASCENDING,
    CSTRING_DESCENDING,
    CSTRING_CALLBACK
};

extern cstring  cstring_create(const char *);
extern void     cstring_delete(cstring *);
extern void     cstring_assign(cstring *, const char *);


@@ 55,6 61,10 @@ extern void     cstring_replace_char(cstring *, size_t, char);
extern void     cstring_replace_str(cstring *, const char *, size_t, size_t);
extern cstring  cstring_substr(const cstring *, size_t, size_t);
extern void     cstring_swap(cstring *, cstring *);
extern void     cstring_sort(cstring **, size_t, enum cstring_flags,
                             int (*)(const void *, const void *));
extern void     cstring_sort_chars(cstring *cs, enum cstring_flags,
                                   int (*)(const void *, const void *));
extern void     cstring_clear(cstring *);
extern size_t   cstring_find(const cstring *, const char *);
extern size_t   cstring_rfind(const cstring *, const char *);


@@ 63,7 73,6 @@ extern size_t   cstring_find_first_not_of(const cstring *,const  char *);
extern size_t   cstring_find_last_of(const cstring *, const char *);
extern size_t   cstring_find_last_not_of(const cstring *, const char *);
extern char    *cstring_copy(const char *);
//extern void     cstring_move(cstring *cs, const char *);
extern void     cstring_resize(cstring *, size_t);
extern cstring *cstring_getline(FILE *, cstring *, char);