~crm/cstring

276def19cd965d9881e633906d2eec73dcb41d3e — Christos Margiolis 3 years ago bfce9e8
removed enum and organized flags as defines; fixed sort_chars cmp functions
5 files changed, 64 insertions(+), 100 deletions(-)

M Makefile
M config.mk -rw-r--r-- => -rwxr-xr-x
M cstring.3
M cstring.c
M cstring.h
M Makefile => Makefile +1 -1
@@ 26,7 26,7 @@ ${LIB}: ${OBJ}
	${AR} ${ARFLAGS} lib${LIB}.a ${OBJ}

.${EXT}.o:
	${CC} ${CFLAGS} -c $<
	${CC} -c ${CFLAGS} $<

dist: clean
	${MKDIR} ${DIST}

M config.mk => config.mk +0 -5
@@ 4,9 4,6 @@ VERSION = 0.1

# paths
PREFIX = /usr/local
#MAN_DIR = ${PREFIX}/man/man1
BIN_DIR = ${PREFIX}/bin
# uncomment if you're making a library
MAN_DIR = ${PREFIX}/man/man3
INC_DIR = ${PREFIX}/include
LIB_DIR = ${PREFIX}/lib


@@ 21,7 18,6 @@ CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L \
CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations \
	 -O3 ${INCS} ${CPPFLAGS}
LDFLAGS = ${LIBS}
# uncomment if you're making a library
ARFLAGS = rs

# utils


@@ 36,5 32,4 @@ GZIP = gzip

# compiler
CC = gcc
# uncomment if you're making a library
AR = ar

M cstring.3 => cstring.3 +19 -26
@@ 23,26 23,24 @@ In case you want to run the program in debug mode, compile
it with the
.Ar \-DCSTRING_DBG
option.
.Sh STRUCTURES AND ENUMS
.Sh STRUCTURES
.Bl -tag -width Ds
.It cstring
struct cstring {
        size_t  len;      /* string length */
        size_t  capacity; /* string capacity */
        char   *str;      /* contents of string */
typedef struct _cstring {
        size_t  len;            /* string length */
        size_t  capacity;       /* string capacity */
        char   *str;            /* contents of string */

CSTRING_SORT_ASCENDING  0x01    /* sort in ascending order */
.br
CSTRING_SORT_DESCENDING 0x02    /* sort in descending order */
.br
};
.It cstring_sort_flags
enum cstring_sort_flags {
        CSTRING_SORT_ASCENDING  = 1 << 0, /* sort in ascending order */
        CSTRING_SORT_DESCENDING = 1 << 1, /* sort in descending order */
        CSTRING_SORT_CALLBACK   = 1 << 2, /* use your own sort function */
        CSTRING_SORT_REST       = 1 << 3  /* sort the rest of the array */
CSTRING_SORT_CALLBACK   0x04    /* sort using a callback function */
.br
};
CSTRING_SORT_REST       0x10    /* sort the rest of the array */
.br
} cstring;
.Sh TYPEDEFS
.Bl -tag -width Ds
.It typedef\ struct\ cstring\ cstring;
Short typedef for the cstring structure.
.It typedef\ int\ (*cstring_sort_callback)(const void *, const void *);
Used in sort functions.


@@ 102,7 100,7 @@ Extract a substring from current string.
.It void Fn cstring_swap "cstring *lhs" "cstring *rhs"
Swap contents of two strings.

.It void Fn cstring_sort "cstring *cs" "size_t len" "enum cstring_sort_flags flags" "cstring_sort_callback callback"
.It void Fn cstring_sort "cstring *cs" "size_t len" "int flags" "cstring_sort_callback callback"
Sort an array of cstrings. If you want to use the builtin comparison pass
.Ar NULL
in the last argument. In case you want to use your own callback use the


@@ 110,12 108,12 @@ in the last argument. In case you want to use your own callback use the
flag and pass your own callback function in the last argument.
You can also combine flags using the bitwise OR operator.

.It void Fn cstring_sort_partial "cstring *cs" "size_t pos" "size_t len" "enum cstring_sort_flags flags" "cstring_sort_callback callback"
.It void Fn cstring_sort_partial "cstring *cs" "size_t pos" "size_t len" "int flags" "cstring_sort_callback callback"
Like
.Fn cstring_sort
but for specified part of an array.

.It void Fn cstring_sort_chars "cstring *cs" "enum cstring_sort_flags flags" "cstring_sort_callback callback"
.It void Fn cstring_sort_chars "cstring *cs" "int flags" "cstring_sort_callback callback"
Sort a cstring's contents. If you want to use the builtin comparison pass
.Ar NULL
in the last argument. In case you want to use your own callback use the


@@ 123,7 121,7 @@ in the last argument. In case you want to use your own callback use the
flag and pass your own callback function in the last argument.
You can also combine flags using the bitwise OR operator.

.It void Fn cstring_sort_chars_partial "cstring *cs" "size_t pos" "size_t len" "enum cstring_sort_flags flags" "cstring_sort_callback callback"
.It void Fn cstring_sort_chars_partial "cstring *cs" "size_t pos" "size_t len" "int flags" "cstring_sort_callback callback"
Like
.Fn cstring_sort_chars
but for specified part of string.


@@ 214,20 212,15 @@ Check if lhs <= rhs

.Sh MACROS
.Bl -tag -width Ds
.It Fn CSTRING_OUT_OF_BOUNDS "cs" "pos"
.It Fn CSTRING_OUT_OF_BOUNDS "len" "pos"
Check if
.Ar pos
is out of bounds.
is out of bounds (pos > len).

.It Fn CSTRING_ARR_LEN "arr"
Determine an array's length. The macro must be called in the same function
the array is declared.

.It Fn CSTRING_FLAG_CHECK "flag" "bit"
Check if a flag is on. This macro is used for checking
.Ar cstring_sort_flags
in the implementation, but it can be used everywhere.

.It Fn CSTRING_MALLOC "ptr" "size"
Allocate memory with error cheking.


M cstring.c => cstring.c +26 -35
@@ 1,5 1,4 @@
/* See LICENSE file for copyright and license details. */

#include "cstring.h"

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


@@ 54,13 53,13 @@ cstring_cmp_less(const void *lhs, const void *rhs)
static inline int
cstring_cmp_char_greater(const void *lhs, const void *rhs)
{
        return (*(char *)lhs > *(char *)rhs);
        return (*(char *)lhs - *(char *)rhs);
}

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

/* externs */


@@ 107,7 106,7 @@ cstring_insert(cstring *cs, const char *s, size_t i)
        size_t slen, newlen;
        char *tmp;

        if (!CSTRING_OUT_OF_BOUNDS(cs, i) && s != NULL) {
        if (!CSTRING_OUT_OF_BOUNDS(cs->len, i) && s != NULL) {
                slen = strlen(s);
                newlen = cs->len + slen;
                CSTRING_MALLOC(tmp, newlen + 1);


@@ 150,8 149,8 @@ cstring_erase(cstring *cs, size_t pos, size_t len)
        char *tmp;

        if (!cstring_empty(cs)
        && (!CSTRING_OUT_OF_BOUNDS(cs, pos)
        ||  !CSTRING_OUT_OF_BOUNDS(cs, len))) {
        && (!CSTRING_OUT_OF_BOUNDS(cs->len, pos)
        ||  !CSTRING_OUT_OF_BOUNDS(cs->len, len))) {
#ifdef CSTRING_DBG
                CSTRING_DBG_LOG("STR: %s | INDEX: %ld | LEN: %ld\n",
                                cs->str, pos, len);


@@ 229,15 228,15 @@ cstring_pop_back(cstring *cs)
void
cstring_replace_char(cstring *cs, size_t i, char c)
{
        if (!CSTRING_OUT_OF_BOUNDS(cs, i))
        if (!CSTRING_OUT_OF_BOUNDS(cs->len, i))
                cs->str[i] = c;
}

void
cstring_replace_str(cstring *cs, const char *s, size_t pos, size_t olen)
{
        if (!CSTRING_OUT_OF_BOUNDS(cs, pos)
        &&  !CSTRING_OUT_OF_BOUNDS(cs, olen)) {
        if (!CSTRING_OUT_OF_BOUNDS(cs->len, pos)
        &&  !CSTRING_OUT_OF_BOUNDS(cs->len, olen)) {
                cstring_erase(cs, pos, olen);
                cstring_insert(cs, s, pos);
        }


@@ 246,8 245,8 @@ cstring_replace_str(cstring *cs, const char *s, size_t pos, size_t olen)
cstring
cstring_substr(const cstring *cs, size_t pos, size_t len)
{
        if (CSTRING_OUT_OF_BOUNDS(cs, pos)
        ||  CSTRING_OUT_OF_BOUNDS(cs, len))
        if (CSTRING_OUT_OF_BOUNDS(cs->len, pos)
        ||  CSTRING_OUT_OF_BOUNDS(cs->len, len))
                return cstring_create("");
        cstring substr = cstring_create(&cs->str[pos]);
        substr.len = len;


@@ 265,41 264,33 @@ cstring_swap(cstring *lhs, cstring *rhs)
}

void
cstring_sort_partial(cstring *cs,
                     size_t pos,
                     size_t len,
                     enum cstring_sort_flags flags,
                     cstring_sort_callback callback)
{
        /* maybe chanage out of bounds macro */
        if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_REST) ||  pos + len > len)
cstring_sort_partial(cstring *cs, size_t pos, size_t len, int flags,
                     cstring_sort_callback cb)
{
        if (flags & CSTRING_SORT_REST ||  CSTRING_OUT_OF_BOUNDS(len, pos + len))
                len -= pos;

        if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_ASCENDING))
        if (flags & CSTRING_SORT_ASCENDING)
                qsort(cs + pos, len, sizeof(cstring), cstring_cmp_greater);
        else if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_DESCENDING))
        else if (flags & CSTRING_SORT_DESCENDING)
                qsort(cs + pos, len, sizeof(cstring), cstring_cmp_less);
        else if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_CALLBACK))
                qsort(cs + pos, len, sizeof(cstring), callback);
        else if (flags & CSTRING_SORT_CALLBACK)
                qsort(cs + pos, len, sizeof(cstring), cb);
}

void
cstring_sort_chars_partial(cstring *cs,
                           size_t pos,
                           size_t len,
                           enum cstring_sort_flags flags,
                           cstring_sort_callback callback)
{
        if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_REST)
        ||  CSTRING_OUT_OF_BOUNDS(cs, pos + len))
cstring_sort_chars_partial(cstring *cs, size_t pos, size_t len, int flags,
                           cstring_sort_callback cb)
{
        if (flags & CSTRING_SORT_REST ||  CSTRING_OUT_OF_BOUNDS(cs->len, pos + len))
                len = cs->len - pos;

        if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_ASCENDING))
        if (flags & CSTRING_SORT_ASCENDING)
                qsort(cs->str + pos, len, sizeof(char), cstring_cmp_char_greater);
        else if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_DESCENDING))
        else if (flags & CSTRING_SORT_DESCENDING)
                qsort(cs->str + pos, len, sizeof(char), cstring_cmp_char_less);
        else if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_CALLBACK))
                qsort(cs->str + pos, len, sizeof(char), callback);
        else if (flags & CSTRING_SORT_CALLBACK)
                qsort(cs->str + pos, len, sizeof(char), cb);
}

void

M cstring.h => cstring.h +18 -33
@@ 1,5 1,4 @@
/* See LICENSE file for copyright and license details. */

#ifndef CSTRING_H
#define CSTRING_H



@@ 13,9 12,8 @@ extern "C" {

#define CSTRING_NPOS -1
#define CSTRING_INIT_EMPTY ""
#define CSTRING_OUT_OF_BOUNDS(cs, val) ((val) > cs->len)
#define CSTRING_OUT_OF_BOUNDS(len, pos) ((pos) > (len))
#define CSTRING_ARR_LEN(arr)           ((size_t)sizeof((arr)) / sizeof((arr)[0]))
#define CSTRING_FLAG_CHECK(flag, bit)  (((flag) & (int)(bit)) == (int)(bit))

#define CSTRING_MALLOC(ptr, size) do {                                       \
        ptr = malloc((size));                                                \


@@ 40,20 38,17 @@ extern "C" {
        CSTRING_DBG_LOG("S: %s | LEN: %ld\n", (s), (len))
#endif /* CSTRING_DBG */

struct cstring {
        size_t    len;
        size_t    capacity;
        char     *str;
};
typedef struct _cstring {
        size_t    len;                  /* strlen of str */
        size_t    capacity;             /* total capacity of the array */
        char     *str;                  /* the string */

enum cstring_sort_flags {
        CSTRING_SORT_ASCENDING  = 1 << 0,
        CSTRING_SORT_DESCENDING = 1 << 1,
        CSTRING_SORT_CALLBACK   = 1 << 2,
        CSTRING_SORT_REST       = 1 << 3
};
#define CSTRING_SORT_ASCENDING  0x01    /* sort in ascending order */
#define CSTRING_SORT_DESCENDING 0x02    /* sort in descending order */
#define CSTRING_SORT_CALLBACK   0x04    /* sort using a callback function */
#define CSTRING_SORT_REST       0x10    /* sort the rest of the array */
} cstring;

typedef struct cstring cstring;
typedef int (*cstring_sort_callback)(const void *, const void *);

extern cstring    cstring_create(const char *);


@@ 70,11 65,9 @@ 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_partial(cstring *, size_t, size_t,
                                       enum cstring_sort_flags,
extern void       cstring_sort_partial(cstring *, size_t, size_t, int,
                                       cstring_sort_callback);
extern void       cstring_sort_chars_partial(cstring *cs, size_t, size_t,
                                             enum cstring_sort_flags,
extern void       cstring_sort_chars_partial(cstring *cs, size_t, size_t, int,
                                             cstring_sort_callback);
extern void       cstring_clear(cstring *);
extern size_t     cstring_find(const cstring *, const char *);


@@ 88,14 81,11 @@ extern char      *cstring_copy(const char *);
extern void       cstring_resize(cstring *, size_t);
extern cstring   *cstring_getline(FILE *, cstring *, char);


/* static inlines */
static inline void    cstring_prepend(cstring *, const char *);
static inline void    cstring_append(cstring *, const char *);
static inline void    cstring_sort(cstring *, size_t, enum cstring_sort_flags,
                                   cstring_sort_callback);
static inline void    cstring_sort_chars(cstring *, enum cstring_sort_flags,
                                         cstring_sort_callback);
static inline void    cstring_sort(cstring *, size_t, int, cstring_sort_callback);
static inline void    cstring_sort_chars(cstring *, int, cstring_sort_callback);
static inline void    cstring_shrink_to_fit(cstring *);
static inline int     cstring_empty(const cstring *);
static inline char    cstring_front(const cstring *);


@@ 123,20 113,15 @@ cstring_append(cstring *cs, const char *s)
}

static inline void
cstring_sort(cstring *cs,
             size_t len,
             enum cstring_sort_flags flags,
             cstring_sort_callback callback)
cstring_sort(cstring *cs, size_t len, int flags, cstring_sort_callback cb)
{
        cstring_sort_partial(cs, 0, len, flags, callback);
        cstring_sort_partial(cs, 0, len, flags, cb);
}

static inline void
cstring_sort_chars(cstring *cs,
                   enum cstring_sort_flags flags,
                   cstring_sort_callback callback)
cstring_sort_chars(cstring *cs, int flags, cstring_sort_callback cb)
{
        cstring_sort_chars_partial(cs, 0, cs->len, flags, callback);
        cstring_sort_chars_partial(cs, 0, cs->len, flags, cb);
}

static inline void