Introduce strsplit()

This commit is contained in:
Kim Woelders 2022-06-20 15:12:42 +02:00
parent 7ec44e68cb
commit 416f847dc3
5 changed files with 162 additions and 1 deletions

View File

@ -42,6 +42,7 @@ rotate.c rotate.h \
scale.c scale.h \
script.c script.h \
span.c span.h \
strutils.c strutils.h \
types.h \
updates.c updates.h

59
src/lib/strutils.c Normal file
View File

@ -0,0 +1,59 @@
#include <stdlib.h>
#include <string.h>
#include "strutils.h"
/*
* Create NULL terminated argv-like list of tokens in
* str separated by delim
*/
char **
__imlib_StrSplit(const char *str, int delim)
{
const char *s, *p;
char **lst;
int n, len;
if (delim == '\0')
return NULL;
lst = NULL;
n = 0;
for (s = str; s; s = p)
{
p = strchr(s, delim);
if (p && delim != '\0')
{
len = p - s;
p++;
}
else
{
len = strlen(s);
}
if (len <= 0)
continue;
lst = realloc(lst, (n + 2) * sizeof(char *));
lst[n++] = strndup(s, len);
}
if (lst)
lst[n] = NULL;
return lst;
}
void
__imlib_StrSplitFree(char **lst)
{
char **l = lst;
if (!l)
return;
for (; *l; l++)
free(*l);
free(lst);
}

7
src/lib/strutils.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef STRUTILS_H
#define STRUTILS_H
char **__imlib_StrSplit(const char *str, int delim);
void __imlib_StrSplitFree(char **plist);
#endif /* STRUTILS_H */

View File

@ -8,7 +8,8 @@ CLEANFILES = file.c img_save-*.*
GTEST_LIBS = -lgtest -lstdc++
GTESTS = test_file
GTESTS = test_string
GTESTS += test_file
GTESTS += test_context
GTESTS += test_load
GTESTS += test_load_2
@ -38,6 +39,10 @@ endif
TEST_COMMON = test.cpp test.h
test_string_SOURCES = $(TEST_COMMON) test_string.cpp
nodist_test_string_SOURCES = strutils.c
test_string_LDADD = $(LIBS)
test_file_SOURCES = $(TEST_COMMON) test_file.cpp
nodist_test_file_SOURCES = file.c
test_file_LDADD = $(LIBS)

89
test/test_string.cpp Normal file
View File

@ -0,0 +1,89 @@
#include <gtest/gtest.h>
/**INDENT-OFF**/
extern "C" {
#include "strutils.h"
}
/**INDENT-ON**/
#define EXPECT_OK(x) EXPECT_FALSE(x)
#define EXPECT_ERR(x) EXPECT_TRUE(x)
TEST(STR, strsplit_1)
{
char **sl;
sl = __imlib_StrSplit(NULL, '\0');
ASSERT_FALSE(sl);
sl = __imlib_StrSplit(NULL, ':');
ASSERT_FALSE(sl);
sl = __imlib_StrSplit("abc", '\0');
ASSERT_FALSE(sl);
}
TEST(STR, strsplit_2)
{
char **sl;
sl = __imlib_StrSplit("", ':');
ASSERT_FALSE(sl);
__imlib_StrSplitFree(sl);
sl = __imlib_StrSplit(":", ':');
ASSERT_FALSE(sl);
__imlib_StrSplitFree(sl);
sl = __imlib_StrSplit("::", ':');
ASSERT_FALSE(sl);
__imlib_StrSplitFree(sl);
}
TEST(STR, strsplit_3)
{
char **sl;
sl = __imlib_StrSplit("abc", ':');
ASSERT_TRUE(sl);
EXPECT_STREQ(sl[0], "abc");
EXPECT_STREQ(sl[1], NULL);
__imlib_StrSplitFree(sl);
sl = __imlib_StrSplit("abc:", ':');
ASSERT_TRUE(sl);
EXPECT_STREQ(sl[0], "abc");
EXPECT_STREQ(sl[1], NULL);
__imlib_StrSplitFree(sl);
sl = __imlib_StrSplit(":abc", ':');
ASSERT_TRUE(sl);
EXPECT_STREQ(sl[0], "abc");
EXPECT_STREQ(sl[1], NULL);
__imlib_StrSplitFree(sl);
sl = __imlib_StrSplit(":abc:", ':');
ASSERT_TRUE(sl);
EXPECT_STREQ(sl[0], "abc");
EXPECT_STREQ(sl[1], NULL);
__imlib_StrSplitFree(sl);
}
TEST(STR, strsplit_4)
{
char **sl;
sl = __imlib_StrSplit("abc:def", ':');
ASSERT_TRUE(sl);
EXPECT_STREQ(sl[0], "abc");
EXPECT_STREQ(sl[1], "def");
EXPECT_STREQ(sl[2], NULL);
__imlib_StrSplitFree(sl);
sl = __imlib_StrSplit("::abc:::def::", ':');
ASSERT_TRUE(sl);
EXPECT_STREQ(sl[0], "abc");
EXPECT_STREQ(sl[1], "def");
EXPECT_STREQ(sl[2], NULL);
__imlib_StrSplitFree(sl);
}