diff libnnchat.c @ 103:eaa524e153f9

Initial implementation of functions for implementing tab-completion for user names.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 15 Oct 2010 00:34:25 +0300
parents b096ae97fc7d
children c587a99e2096
line wrap: on
line diff
--- a/libnnchat.c	Mon Oct 11 15:48:05 2010 +0300
+++ b/libnnchat.c	Fri Oct 15 00:34:25 2010 +0300
@@ -550,9 +550,35 @@
 }
 
 
+char * nn_editbuf_get_string(nn_editbuf_t *buf, ssize_t start, ssize_t end)
+{
+    char *str;
+    ssize_t siz;
+    
+    if (buf == NULL)
+        return NULL;
+
+    if (start < 0 || end > buf->len || start >= buf->len)
+        return NULL;
+
+    if (end < 0) {
+        siz = buf->len - start + 1;
+    } else if (start <= end) {
+        siz = end - start + 1;
+    } else
+        return NULL;
+
+    str = th_malloc(siz + 1);
+    memcpy(str, buf->data + start, siz);
+    str[siz] = 0;
+    return str;
+}
+
+
 void nn_editbuf_setpos(nn_editbuf_t *buf, ssize_t pos)
 {
-    /* Check arguments */
+    assert(buf != NULL);
+
     if (pos < 0)
         buf->pos = 0;
     else if (pos >= buf->len)
@@ -564,6 +590,7 @@
 
 static uint8_t nn_hash_user(const char *name)
 {
+/*
     int n = 0;
     const uint8_t *c = (uint8_t *)name;
     uint8_t hash = 0xff;
@@ -574,6 +601,8 @@
     }
     
     return (hash & 0xff);
+*/
+    return tolower(name[0]);
 }
 
 
@@ -584,6 +613,26 @@
 }
 
 
+nn_user_t *nn_userhash_foreach(const nn_userhash_t *list, int (*func)(const nn_user_t *))
+{
+    int i;
+
+    if (list == NULL) return NULL;
+    
+    for (i = 0; i < NN_NUM_BUCKETS; i++)
+    if (list->buckets[i] != NULL) {
+        nn_user_t *curr = list->buckets[i];
+        while (curr != NULL) {
+            if (func(curr) != 0)
+                return curr;
+            curr = curr->next;
+        }
+    }
+    
+    return NULL;
+}
+
+
 nn_user_t *nn_user_find_enc(const nn_userhash_t *list, const char *encname)
 {
     uint8_t hash;
@@ -604,7 +653,50 @@
 }
 
 
-int nn_user_add_to_hash(nn_userhash_t **list, const char *encname)
+nn_user_t *nn_user_match(const nn_userhash_t *list, const char *str, const char *current)
+{
+    uint8_t hash;
+    
+    if (list == NULL) return NULL;
+
+    hash = nn_hash_user(str);
+    if (list->buckets[hash] != NULL) {
+        nn_user_t *curr = list->buckets[hash];
+        int len = strlen(str);
+
+        if (current != NULL) {
+            nn_user_t *found = NULL;
+            while (curr != NULL) {
+                if (strcasecmp(curr->name, current) == 0) {
+                    found = curr->next;
+                    break;
+                }
+                curr = curr->next;
+            }
+            if (found != NULL)
+                curr = found;
+            else
+                curr = list->buckets[hash];
+        }
+        
+        while (curr != NULL) {
+            if (strncasecmp(curr->name, str, len) == 0)
+                return curr;
+            curr = curr->next;
+        }
+    }
+    
+    return NULL;
+}
+
+
+nn_userhash_t *nn_userhash_new(void)
+{
+    return th_calloc(1, sizeof(nn_userhash_t));
+}
+
+
+int nn_userhash_insert(nn_userhash_t *list, const char *encname)
 {
     uint8_t hash;
     nn_user_t *user;
@@ -613,15 +705,8 @@
     if (list == NULL || encname == NULL)
         return -1;
     
-    /* Check if list data exists */
-    if (*list == NULL) {
-        *list = th_calloc(1, sizeof(nn_userhash_t));
-        if (*list == NULL)
-            return -2;
-    }
-    
     /* Check if username is already there */
-    if (nn_user_find_enc(*list, encname) != NULL)
+    if (nn_user_find_enc(list, encname) != NULL)
         return 1;
     
     /* No, we'll add it */
@@ -634,11 +719,47 @@
         return -4;
     
     hash = nn_hash_user(encname);
-    nn_user_insert(&((*list)->buckets[hash]), user);
+    nn_user_insert(&(list->buckets[hash]), user);
+
     return 0;
 }
 
 
+int nn_userhash_delete(nn_userhash_t *list, const char *encname)
+{
+    uint8_t hash;
+    
+    /* Check arguments */
+    if (list == NULL || encname == NULL)
+        return -1;
+    
+    /* Check if username is already there */
+    hash = nn_hash_user(encname);
+    if (list->buckets[hash] != NULL) {
+        nn_user_t *curr, *prev;
+        curr = list->buckets[hash];
+        prev = NULL;
+        while (curr != NULL) {
+            if (strcasecmp(curr->encname, encname) == 0) {
+                if (prev)
+                    prev->next = curr->next;
+                else
+                    list->buckets[hash] = curr->next;
+                
+                nn_user_free(curr);
+                
+                return 0;
+            } else {
+                prev = curr;
+                curr = curr->next;
+            }
+        }
+    }
+
+    return 1;
+}
+
+
 nn_user_t *nn_user_copy(const nn_user_t *src)
 {
     nn_user_t *user;
@@ -658,7 +779,7 @@
 }
 
 
-static void nn_user_free(nn_user_t *user)
+void nn_user_free(nn_user_t *user)
 {
    th_free(user->encname);
    th_free(user->name);
@@ -676,7 +797,7 @@
     }
 }
 
-void nn_user_free_hash(nn_userhash_t *hash)
+void nn_userhash_free(nn_userhash_t *hash)
 {
     int i;
     if (hash == NULL)