Merge branch 'master' of /srv/git/r/doldaconnect
[doldaconnect.git] / include / utils.h
index 4eada80..1e52949 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Dolda Connect - Modular multiuser Direct Connect-style client
- *  Copyright (C) 2004 Fredrik Tolf (fredrik@dolda2000.com)
+ *  Copyright (C) 2004 Fredrik Tolf <fredrik@dolda2000.com>
  *  
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -21,8 +21,6 @@
 
 #include <stdarg.h>
 #include <stdlib.h>
-#include <malloc.h>
-#include <assert.h>
 #ifdef DAEMON
 #include "log.h"
 #endif
@@ -33,13 +31,24 @@ struct wcspair {
     wchar_t *val;
 };
 
+struct strpair {
+    struct strpair *next;
+    char *key;
+    char *val;
+};
+
+struct btree {
+    struct btree *l, *r;
+    int h;
+    void *d;
+};
 
 /* "Safe" functions */
 #ifdef DAEMON
-#define LOGOOM(size) flog(LOG_CRIT, "%s (%s:%i): out of memory (alloc %i)", __FUNCTION__, __FILE__, __LINE__, (size))
-#define smalloc(size) ({void *__result__; ((__result__ = malloc(size)) == NULL)?({LOGOOM(size); abort(); (void *)0;}):__result__;})
-#define srealloc(ptr, size) ({void *__result__; ((__result__ = realloc((ptr), (size))) == NULL)?({LOGOOM(size); abort(); (void *)0;}):__result__;})
-#define swcsdup(wcs) ((wchar_t *)wcscpy(smalloc(sizeof(wchar_t) * (wcslen(wcs) + 1)), (wcs)))
+#define LOGOOM(size) flog(LOG_CRIT, "%s (%s:%i): out of memory (alloc %zi)", __FUNCTION__, __FILE__, __LINE__, (size))
+#define smalloc(size) ({void *__result__; ((__result__ = malloc(size)) == NULL)?({LOGOOM((ssize_t)(size)); abort(); (void *)0;}):__result__;})
+#define srealloc(ptr, size) ({void *__result__; ((__result__ = realloc((ptr), (size))) == NULL)?({LOGOOM((ssize_t)(size)); abort(); (void *)0;}):__result__;})
+#define swcsdup(wcs) ({wchar_t *__eval__; __eval__ = (wcs); (wchar_t *)wcscpy(smalloc(sizeof(wchar_t) * (wcslen(__eval__) + 1)), __eval__);})
 #define sstrdup(str) ((char *)strcpy(smalloc(strlen(str) + 1), (str)))
 #else
 #define LOGOOM(size)
@@ -55,7 +64,6 @@ struct cbchain_ ## name { \
     int (*func)(args, void *data); \
     void (*destroy)(void *data); \
     void *data; \
-    int running, free; \
 } * name
 
 #define GCBCHAIN(name, args...) \
@@ -68,15 +76,9 @@ extern struct cbchain_ ## name { \
     void *data; \
 } * name
 
-extern int vswprintf (wchar_t *__restrict __s, size_t __n,
-                     __const wchar_t *__restrict __format,
-                     __gnuc_va_list __arg);
-extern int swprintf (wchar_t *__restrict __s, size_t __n,
-                    __const wchar_t *__restrict __format, ...);
-
 char *vsprintf2(char *format, va_list al);
 char *sprintf2(char *format, ...)
-#if defined(__GNUC__) && 0
+#if defined(__GNUC__)
     __attribute__ ((format (printf, 1, 2)))
 #endif
 ;
@@ -91,7 +93,7 @@ wchar_t *wcstolower(wchar_t *wcs);
 wchar_t ucptowc(int ucp);
 void _sizebuf(void **buf, size_t *bufsize, size_t reqsize, size_t elsize, int algo);
 double ntime(void);
-int wcsexists(wchar_t *h, wchar_t *n);
+wchar_t *wcslower(wchar_t *wcs);
 #ifndef HAVE_WCSCASECMP
 int wcscasecmp(const wchar_t *s1, const wchar_t *s2);
 #endif
@@ -103,26 +105,41 @@ char *base32encode(char *data, size_t datalen);
 char *base32decode(char *data, size_t *datalen);
 void _freeparr(void **arr);
 int _parrlen(void **arr);
-char *findfile(char *gname, char *uname, char *homedir, int filldef);
+char *findfile(char *name, char *homedir, int filldef);
+struct strpair *newstrpair(char *key, char *val, struct strpair **list);
+void freestrpair(struct strpair *pair, struct strpair **list);
+char *spfind(struct strpair *list, char *key);
 struct wcspair *newwcspair(wchar_t *key, wchar_t *val, struct wcspair **list);
 void freewcspair(struct wcspair *pair, struct wcspair **list);
 wchar_t *wpfind(struct wcspair *list, wchar_t *key);
-
-#define sizebuf(b, bs, rs, es, a) _sizebuf((void **)(b), (bs), (rs), (es), (a))
-#define sizebuf2(b, rs, a) _sizebuf((void **)(&(b)), &(b ## size), (rs), sizeof(*(b)), (a))
+int bbtreedel(struct btree **tree, void *item, int (*cmp)(void *, void *));
+int bbtreeput(struct btree **tree, void *item, int (*cmp)(void *, void *));
+void *btreeget(struct btree *tree, void *key, int (*cmp)(void *, void *));
+void *btreeiter(struct btree *tree);
+void btreefree(struct btree *tree);
+
+#define sizebuf(b, bs, rs, es, a) _sizebuf((void **)(void *)(b), (bs), (rs), (es), (a))
+#define sizebuf2(b, rs, a) _sizebuf((void **)(void *)(&(b)), &(b ## size), (rs), sizeof(*(b)), (a))
 #define addtobuf(b, c) \
 do { \
-    _sizebuf((void **)(&(b)), &(b ## size), (b ## data) + 1, sizeof(*(b)), 1); \
+    _sizebuf((void **)(void *)(&(b)), &(b ## size), (b ## data) + 1, sizeof(*(b)), 1); \
     (b)[(b ## data)++] = (c); \
 } while(0)
 #define bufcat(d, s, n) \
 do { \
     size_t __bufcat_size__; \
     __bufcat_size__ = (n); \
-    _sizebuf((void **)(&(d)), &(d ## size), (d ## data) + __bufcat_size__, sizeof(*(d)), 1); \
+    _sizebuf((void **)(void *)(&(d)), &(d ## size), (d ## data) + __bufcat_size__, sizeof(*(d)), 1); \
     memcpy((d) + (d ## data), (s), sizeof(*(d)) * __bufcat_size__); \
     (d ## data) += __bufcat_size__; \
 } while (0)
+#define bprintf(b, fmt...) \
+    do { \
+       char *__bprintf_dest__; \
+       __bprintf_dest__ = sprintf2(fmt); \
+       bufcat(b, __bprintf_dest__, strlen(__bprintf_dest__)); \
+       free(__bprintf_dest__); \
+    } while(0)
 
 #define freeparr(parr) _freeparr((void **)(parr))
 #define parrlen(parr) _parrlen((void **)(parr))
@@ -131,7 +148,6 @@ do { \
 do { \
     struct cbchain_ ## name *__new_cb__; \
     __new_cb__ = smalloc(sizeof(*__new_cb__)); \
-    __new_cb__->running = __new_cb__->free = 0; \
     __new_cb__->func = funca; \
     __new_cb__->destroy = destroya; \
     __new_cb__->data = dataa; \
@@ -143,12 +159,11 @@ do { \
     (obj)->name = __new_cb__; \
 } while(0)
 
-#define CBUNREG(obj, name, funca, dataa) \
-({ \
+#define CBUNREG(obj, name, dataa) \
+do { \
     struct cbchain_ ## name *__cur__; \
-    int __found__ = 0; \
     for(__cur__ = (obj)->name; __cur__ != NULL; __cur__ = __cur__->next) { \
-        if(((void *)(__cur__->func) == (void *)(funca)) && (__cur__->data == (void *)(dataa))) { \
+        if(__cur__->data == (dataa)) { \
             if(__cur__->destroy != NULL) \
                 __cur__->destroy(__cur__->data); \
             if(__cur__->prev != NULL) \
@@ -158,11 +173,10 @@ do { \
             if(__cur__ == (obj)->name) \
                 (obj)->name = __cur__->next; \
             free(__cur__); \
-            __found__ = 1; \
             break; \
         } \
     } \
-__found__;})
+} while(0)
 
 #define GCBREG(name, funca, dataa) \
 do { \
@@ -185,30 +199,18 @@ do { \
     struct cbchain_ ## name *__cur__; \
     while((__cur__ = (obj)->name) != NULL) { \
         (obj)->name = __cur__->next; \
-        if(__cur__->running) { \
-            __cur__->free = 1; \
-        } else { \
-            if(__cur__->destroy != NULL) \
-                __cur__->destroy(__cur__->data); \
-            free(__cur__); \
-       } \
+        if(__cur__->destroy != NULL) \
+            __cur__->destroy(__cur__->data); \
+        free(__cur__); \
     } \
 } while(0)
 
 #define CBCHAINDOCB(obj, name, args...) \
 do { \
     struct cbchain_ ## name *__cur__, *__next__; \
-    int __res__; \
     for(__cur__ = (obj)->name; __cur__ != NULL; __cur__ = __next__) { \
         __next__ = __cur__->next; \
-        __cur__->running = 1; \
-        __res__ = __cur__->func(args, __cur__->data); \
-        __cur__->running = 0; \
-        if(__cur__->free) { \
-            free(__cur__); \
-            break; \
-        } \
-        if(__res__) { \
+        if(__cur__->func(args, __cur__->data)) { \
             if(__cur__->next != NULL) \
                 __cur__->next->prev = __cur__->prev; \
             if(__cur__->prev != NULL) \