]> Pileus Git - ~andy/lamechat/commitdiff
Add completion utils.
authorAndy Spencer <andy753421@gmail.com>
Thu, 4 Apr 2019 19:09:09 +0000 (19:09 +0000)
committerAndy Spencer <andy753421@gmail.com>
Thu, 4 Apr 2019 19:40:05 +0000 (19:40 +0000)
.gitignore
conf.c
conf.h
makefile
test.c [new file with mode: 0644]
util.c
util.h

index 1bde854a48a11287f50a7c744c1f698434e6b6c5..a84c5a5934e8b46b2a9e293b05070c5aba727ce6 100644 (file)
@@ -13,4 +13,5 @@ lamechat
 gmon.out
 test.key
 test.crt
+test
 tags
diff --git a/conf.c b/conf.c
index 7d48ac0696780ca4fd454435cb5384a9bc4d4bbc..eb74f6d9238e817b466e8e8a0f1588b8758978ed 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -333,11 +333,11 @@ void conf_sync(void)
 }
 
 /* Getters */
-int get_enum(const char *value, const char **map, int n)
+int get_enum(const char *value, const char **map, int s, int n)
 {
        wasfound = 1;
        for (int i = 0; i < n; i++)
-               if (match(map[i], value))
+               if (match(map[i*s], value))
                        return i;
        conf_error(value);
        return 0;
@@ -346,7 +346,7 @@ int get_enum(const char *value, const char **map, int n)
 int get_bool(const char *value)
 {
        wasfound = 1;
-       return get_enum(value, booleans, N_ELEMENTS(booleans));
+       return get_map(value, booleans);
 }
 
 int get_number(const char *value)
@@ -430,7 +430,7 @@ static void  test_parser(const char *group, const char *name,
                if (match(key, "bin"))
                        test_bin = get_bool(value);
                else if (match(key, "clr"))
-                       test_clr = get_enum(value, colors, N_ELEMENTS(colors));
+                       test_clr = get_map(value, colors);
                else if (match(key, "num"))
                        test_num = get_number(value);
                else if (match(key, "str"))
diff --git a/conf.h b/conf.h
index e055129cdb37f30cb5fcca3838cbbf6c80ba40e2..20bc53386c07af1940025d92d014c12d893209f8 100644 (file)
--- a/conf.h
+++ b/conf.h
@@ -21,9 +21,11 @@ typedef void (*parser_t)(const char *group, const char *name,
 
 /* Getters */
 #define get_map(value, map) \
-       get_enum(value, map, N_ELEMENTS(map))
+       get_enum(value, map, 1, N_ELEMENTS(map))
+#define get_mapv(value, map) \
+       get_enum(value, *map, N_ELEMENTS(*map), N_ELEMENTS(map))
 
-int get_enum(const char *value, const char **map, int n);
+int get_enum(const char *value, const char **map, int s, int n);
 int get_bool(const char *value);
 int get_number(const char *value);
 char *get_string(const char *value);
index 417accb92be6c610301a0f6fb9aa9bcd281580e9..e542c39b3c2f0d2ab90d132b047bf1c4444cea95 100644 (file)
--- a/makefile
+++ b/makefile
@@ -18,7 +18,9 @@ LDFLAGS   ?= -lncursesw -lexpat
 
 # Sources
 PROG      ?= lamechat
-SOURCES   ?= main util args conf view chat net irc xmpp 
+PROG_SRC  ?= main util args conf view chat net irc xmpp
+TEST      ?= test
+TEST_SRC  ?= test util
 
 # OpenSSL
 ifeq ($(CRYPTO),OPENSSL)
@@ -60,7 +62,10 @@ memcheck: $(PROG)
                 ./$(PROG)
 
 # Rules
-$(PROG): $(SOURCES:%=%.o)
+$(PROG): $(PROG_SRC:%=%.o)
+       $(GCC) -o $@ $+ $(LDFLAGS)
+
+$(TEST): $(TEST_SRC:%=%.o)
        $(GCC) -o $@ $+ $(LDFLAGS)
 
 %.o: %.c $(wildcard *.h makefile config.mk)
diff --git a/test.c b/test.c
new file mode 100644 (file)
index 0000000..ac0b0f1
--- /dev/null
+++ b/test.c
@@ -0,0 +1,9 @@
+#include "util.h"
+
+void util_test(void);
+
+int main(int argc, char **argv)
+{
+       util_test();
+       return 0;
+}
diff --git a/util.c b/util.c
index 85a03db8581425faa9720a7551bdb0c99f322898..ac75cfcafd0d20e64676145c77fdd01dcbdc66a2 100644 (file)
--- a/util.c
+++ b/util.c
@@ -128,6 +128,17 @@ void strset(char **old, const char *str)
                *old = NULL;
 }
 
+int compare(const char *a, const char *b)
+{
+       if (a == b)
+               return  0;
+       if (!a)
+               return -1;
+       if (!b)
+               return  1;
+       return strcmp(a, b);
+}
+
 int match(const char *a, const char *b)
 {
        if (a == b)
@@ -137,23 +148,38 @@ int match(const char *a, const char *b)
        return !strcmp(a, b);
 }
 
+int starts(const char *prefix, const char *str)
+{
+       if (prefix == str)
+               return 1;
+       if (!prefix || !prefix[0])
+               return 1;
+       if (!str || !str[0])
+               return 0;
+       int len = strlen(prefix);
+       return !strncmp(prefix, str, len);
+}
+
 int prefix(const char *str, const char *prefix, const char **suffix)
 {
-       while (*str && *prefix) {
-               if (*str != *prefix)
-                       return 0;
-               str++;
+       char last = 0;
+       while (*str && *prefix && *str == *prefix) {
                prefix++;
+               last = *str++;
        }
-       if (*prefix)
-               return 0;
-       if (*str && *str != ' ')
-               return 0;
        while (*str && *str == ' ')
-               str++;
+               last = *str++;
+
+       int         val = 0;
+       const char *arg = NULL;
+       if (*prefix == '\0' && (*str == '\0' || last == ' ')) {
+               arg = *str ? str : NULL;
+               val = 1;
+       }
+
        if (suffix)
-               *suffix = *str ? str : NULL;
-       return 1;
+               *suffix = arg;
+       return val;
 }
 
 char *despace(char *str)
@@ -444,3 +470,30 @@ void error(char *fmt, ...)
                view_exit();
        exit(-1);
 }
+
+/* Test case */
+static void test_prefix(const char *str,  const char *pre,
+                        const int val0, const char *arg0)
+{
+       const char *arg1 = "junk";
+       int val1 = prefix(str, pre, &arg1);
+       printf("%s -- [%s]%*s [%s]%*s -> %d=%d %s=%s\n",
+               val0==val1 && match(arg0,arg1) ? "pass" : "fail",
+               str, (int)(8-strlen(str)), "",
+               pre, (int)(5-strlen(pre)), "",
+               val0, val1,
+               arg0, arg1);
+}
+
+void util_test(void)
+{
+       test_prefix("/foo",     "/foo",  1, NULL);
+       test_prefix("/foo ",    "/foo",  1, NULL);
+       test_prefix("/foobar",  "/foo",  0, NULL);
+       test_prefix("/foo bar", "/foo",  1, "bar");
+
+       test_prefix("/foo",     "/foo ", 0, NULL);
+       test_prefix("/foo ",    "/foo ", 1, NULL);
+       test_prefix("/foobar",  "/foo ", 0, NULL);
+       test_prefix("/foo bar", "/foo ", 1, "bar");
+}
diff --git a/util.h b/util.h
index f3840c5ee4adad40d5d6236064d566f8d9caef90..ad30177ffe1cb8182582a9a87fec12b8aebe5d4a 100644 (file)
--- a/util.h
+++ b/util.h
@@ -53,7 +53,9 @@ void util_init(void);
 void strsub(char *str, char find, char repl);
 char *strcopy(const char *str);
 void strset(char **old, const char *str);
+int compare(const char *a, const char *b);
 int match(const char *a, const char *b);
+int starts(const char *prefix, const char *str);
 int prefix(const char *str, const char *prefix, const char **suffix);
 char *despace(char *text);
 void escape(char *dst, const char *src, int len);