commit 22060bd2333f19c4dbd47606a9bedddcf4b2a9ab
parent e86d615950a8a019265783f3fc8091ba104f2ce4
Author: Christos Margiolis <christos@margiolis.net>
Date: Thu, 1 Oct 2020 22:53:08 +0300
added debug mode and macros, still pending push_back/resize fix
Diffstat:
5 files changed, 84 insertions(+), 15 deletions(-)
diff --git a/Makefile b/Makefile
@@ -12,7 +12,7 @@ AR = ar
ARFLAGS = rs
CC = gcc
CPPFLAGS += -Iinclude -pedantic
-CFLAGS += -Wall -std=c99 -O3
+CFLAGS += -Wall -std=c99 -O3 -DCSTRING_DBG
LDFLAGS += -Llib
#LDLIBS +=
@@ -39,7 +39,7 @@ install: all
${CP} ${MAN3} ${DESTDIR}${MAN_DIR}
chmod 644 ${DESTDIR}${MAN_DIR}/${MAN3}
-uninstall: all
+uninstall:
sudo ${RM} ${DESTDIR}${HDR_DIR}/${LIB}.h
sudo ${RM} ${DESTDIR}${LIB_DIR}/lib${LIB}.a
sudo ${RM} ${DESTDIR}${MAN_DIR}/${MAN3}
diff --git a/cstring.3 b/cstring.3
@@ -125,11 +125,40 @@ stream. Similar behavior to
Check if
.I pos
is out of bounds.
+.TP
+.BR CSTRING_MALLOC(ptr,\ size)
+Allocate memory with error cheking.
+.P
+The following macros can only be used in debug mode:
+.TP
+.BR CSTRING_DBG_LOG(fmt,\ ...)
+Prints a message in the format of "DEBUG: file:line:func(): msg".
+.TP
+.BR CSTRING_DBG_LOG_STR_INFO(cs)
+Uses
+.I CSTRING_DBG_LOG
+to print all the contents of a
+.I cstring
+struct. The argument has to be a pointer.
+.TP
+.BR CSTRING_DBG_LOG_STR_INFO_NPTR(cs)
+Uses
+.I CSTRING_DBG_LOG
+to print all the contents of a
+.I cstring
+struct. The argument has to be a non-pointer.
.SH CONSTANTS
.TP
.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
diff --git a/cstring.c b/cstring.c
@@ -23,6 +23,9 @@ cstring_create(const char *s)
cs.len = strlen(s);
cs.str = cstring_copy(s);
cstring_resize(&cs, cs.len << 1);
+#ifdef CSTRING_DBG
+ CSTRING_DBG_LOG_STR_INFO_NPTR(cs);
+#endif /* CSTRING_DBG */
return cs;
}
@@ -44,6 +47,9 @@ cstring_assign(cstring *cs, const char *s)
if (!cstring_empty(cs)) free(cs->str);
cs->str = cstring_copy(s);
cs->len = newlen;
+#ifdef CSTRING_DBG
+ CSTRING_DBG_LOG_STR_INFO(cs);
+#endif /* CSTRING_DBG */
}
void
@@ -52,16 +58,20 @@ cstring_insert(cstring *cs, const char *s, size_t i)
if (!CSTRING_OUT_OF_BOUNDS(cs, i) && s != NULL) {
size_t slen = strlen(s);
size_t newlen = cs->len + slen;
- char *tmp = (char *)malloc(newlen + 1);
- memcpy(tmp, cs->str, i);
- memcpy(tmp + i, s, slen);
- memcpy(tmp + slen + i, cs->str + i , newlen - slen - i);
+ char *tmp;
+ CSTRING_MALLOC(tmp, newlen + 1);
if (CSTRING_EXCEEDS_CAPACITY(newlen, cs->capacity))
cstring_resize(cs, newlen << 1);
+ memcpy(tmp, cs->str, i);
+ memcpy(tmp + i, s, slen);
+ memcpy(tmp + slen + i, cs->str + i, newlen - slen - i);
free(cs->str);
cs->len = newlen;
cs->str = tmp;
cs->str[cs->len] = '\0';
+#ifdef CSTRING_DBG
+ CSTRING_DBG_LOG_STR_INFO(cs);
+#endif /* CSTRING_DBG */
}
}
@@ -73,7 +83,8 @@ cstring_erase(cstring *cs, size_t pos, size_t len)
&& !CSTRING_OUT_OF_BOUNDS(cs, len))
{
size_t newlen = cs->len - len;
- char *tmp = (char *)malloc(newlen + 1);
+ char *tmp;
+ CSTRING_MALLOC(tmp, newlen + 1);
memcpy(tmp, cs->str, pos); // pos + 1??
memcpy(tmp + pos, cs->str + pos + len, newlen);
free(cs->str);
@@ -116,13 +127,17 @@ cstring_push_back(cstring *cs, char c)
cstring_resize(cs, cs->len << 1);
cs->str[cs->len] = c;
cs->str[++cs->len] = '\0';
+#ifdef CSTRING_DBG
+ CSTRING_DBG_LOG_STR_INFO(cs);
+#endif /* CSTRING_DBG */
}
void
cstring_pop_back(cstring *cs)
{
if (cs->len > 0) {
- char *tmp = (char *)malloc(cs->len);
+ char *tmp;
+ CSTRING_MALLOC(tmp, cs->len);
memcpy(tmp, cs->str, cs->len);
free(cs->str);
tmp[--cs->len] = '\0';
@@ -175,7 +190,7 @@ void
cstring_clear(cstring *cs)
{
if (!cstring_empty(cs)) free(cs->str);
- cs->str = (char *)malloc(1);
+ CSTRING_MALLOC(cs->str, 1);
cs->str[0] = '\0';
cs->len = 0;
cs->capacity = 0;
@@ -264,7 +279,8 @@ char *
cstring_copy(const char *s)
{
size_t len = strlen(s);
- char *tmp = (char *)malloc(len + 1);
+ char *tmp;
+ CSTRING_MALLOC(tmp, len + 1);
memcpy(tmp, s, len + 1);
tmp[len] = '\0';
return tmp;
@@ -273,8 +289,11 @@ cstring_copy(const char *s)
void
cstring_resize(cstring *cs, size_t newcapacity)
{
- cs->str = (char *)realloc(cs->str, newcapacity);
+ cs->str = (char *)realloc(cs->str, newcapacity + 1);
cs->capacity = newcapacity;
+#ifdef CSTRING_DBG
+ CSTRING_DBG_LOG_STR_INFO(cs);
+#endif /* CSTRING_DBG */
}
cstring *
diff --git a/cstring.h b/cstring.h
@@ -12,6 +12,26 @@ extern "C" {
#define CSTRING_NPOS -1
#define CSTRING_OUT_OF_BOUNDS(cs, pos) ((pos) > cs->len)
+#define CSTRING_MALLOC(ptr, size) do { \
+ ptr = (char *)malloc((size)); \
+ if (ptr == NULL) \
+ fputs("CSTRING_MALLOC(): cannot allocate memory\n", stderr); \
+} while (0)
+
+#ifdef CSTRING_DBG
+#define CSTRING_DBG_LOG(fmt, ...) \
+ fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt, \
+ __FILE__, __LINE__, __func__, __VA_ARGS__)
+
+#define CSTRING_DBG_LOG_STR_INFO(cs) \
+ CSTRING_DBG_LOG("STR: %s | LEN: %ld | CAP: %ld\n", \
+ cs->str, cs->len, cs->capacity)
+
+#define CSTRING_DBG_LOG_STR_INFO_NPTR(cs) \
+ CSTRING_DBG_LOG("STR: %s | LEN: %ld | CAP: %ld\n", \
+ cs.str, cs.len, cs.capacity)
+#endif /* CSTRING_DBG */
+
typedef struct cstring {
char *str;
size_t len;
diff --git a/tests/test.c b/tests/test.c
@@ -17,6 +17,10 @@ main(int argc, char **argv)
cstring_prepend(&s, "OK");
printf("cstring_prepend: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+ // BUG
+ /*for (int i = 0; i < 50; i++)*/
+ /*cstring_push_back(&s, 'c');*/
+
cstring_push_back(&s, 'c');
printf("cstring_push_back: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
@@ -50,11 +54,8 @@ main(int argc, char **argv)
cstring_trim(&s, " ");
printf("cstring_trim: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
- cstring_insert(&s, "New text", 2);
- printf("cstring_insert: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
-
cstring_delete(&s);
- if (cstring_empty(&s)) printf("cstring_delete: Deleted string.\n");
+ if (cstring_empty(&s)) puts("cstring_delete: Deleted string.");
return 0;
}