739 lines
13 KiB
C
739 lines
13 KiB
C
/* azundris */
|
|
|
|
/*#include <glib.h>*/
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/time.h> /* gimetimeofday() */
|
|
#include <stdio.h> /* NULL */
|
|
#include <stdlib.h> /* malloc(), free() */
|
|
#include <string.h> /* str...() */
|
|
#include <ctype.h> /* isspace() */
|
|
|
|
#include <stdarg.h> /* varargs in dlmulti() */
|
|
#include <dlfcn.h> /* dlopen() and friends for dlmulti() */
|
|
|
|
/* #ifdef HAVE_GLIB2 */
|
|
/* # include <glib/gmain.h> */
|
|
/* #endif */
|
|
|
|
#include "Ecore_Config.h"
|
|
#include "util.h"
|
|
|
|
#include "ecore_config_private.h"
|
|
|
|
#define CHUNKLEN 4096
|
|
|
|
/*****************************************************************************/
|
|
/* MISC */
|
|
/********/
|
|
|
|
int
|
|
dlmulti(char *name, char *file, int flag, void **libr, const char *fmt, ...)
|
|
{
|
|
#define MAX_SYM_LEN 256
|
|
va_list ap;
|
|
void *lib;
|
|
int ret = ECORE_CONFIG_ERR_SUCC;
|
|
char buf[MAX_SYM_LEN] = "\0";
|
|
|
|
if (!libr)
|
|
return ECORE_CONFIG_ERR_FAIL;
|
|
|
|
if (!name)
|
|
name = file;
|
|
|
|
*libr = NULL;
|
|
|
|
if ((lib = dlopen(file, flag)))
|
|
{
|
|
void **funr, *fun;
|
|
char *b, *e;
|
|
size_t l;
|
|
int required = 1;
|
|
|
|
va_start(ap, fmt);
|
|
while (*fmt)
|
|
{
|
|
switch (*fmt)
|
|
{
|
|
case '?':
|
|
required = 0;
|
|
fmt++;
|
|
break;
|
|
|
|
case '!':
|
|
case '.':
|
|
required = 1;
|
|
fmt++;
|
|
break;
|
|
|
|
case '\t':
|
|
case '\n':
|
|
case '\r':
|
|
case ';':
|
|
case ',':
|
|
case ' ':
|
|
fmt++;
|
|
break;
|
|
|
|
default:
|
|
e = b = (char *)fmt;
|
|
while (*e && (strchr("?!.,; \t\n\r", *e) == NULL))
|
|
e++;
|
|
|
|
fmt = e;
|
|
if (e == b)
|
|
ret = ECORE_CONFIG_ERR_NODATA;
|
|
else if ((l = (e - b)) >= MAX_SYM_LEN)
|
|
ret = ECORE_CONFIG_ERR_OOM;
|
|
else
|
|
{
|
|
memcpy(buf, b, l);
|
|
buf[l] = '\0';
|
|
funr = va_arg(ap, void **);
|
|
|
|
if (!(fun = dlsym(lib, buf)))
|
|
{
|
|
if ((ret =
|
|
required ? ECORE_CONFIG_ERR_NOTFOUND :
|
|
ECORE_CONFIG_ERR_PARTIAL) ==
|
|
ECORE_CONFIG_ERR_NOTFOUND)
|
|
E(1,
|
|
"DLMulti: library/plugin/engine \"%s\" (\"%s\") did not contain required function \"%s\"...\n",
|
|
name, file, buf);
|
|
}
|
|
E(2, "DLMulti: %p => %p %c\"%s\"\n", fun, funr,
|
|
required ? '!' : '?', buf);
|
|
if (funr)
|
|
*funr = fun;
|
|
}
|
|
required = 1;
|
|
}
|
|
}
|
|
|
|
va_end(ap);
|
|
|
|
if ((ret == ECORE_CONFIG_ERR_SUCC) || (ret == ECORE_CONFIG_ERR_PARTIAL))
|
|
*libr = lib;
|
|
else
|
|
dlclose(lib);
|
|
}
|
|
else
|
|
ret = ECORE_CONFIG_ERR_NODATA;
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
unsigned long
|
|
now(long delay)
|
|
{
|
|
static struct timeval tv;
|
|
unsigned long r;
|
|
|
|
gettimeofday(&tv, NULL);
|
|
r = tv.tv_sec * 1000 + (((float)tv.tv_usec) / 1000.0) + delay;
|
|
return r;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
int
|
|
parse_line(char *in, char **o1, char **o2, char **o3, char **o4)
|
|
{
|
|
#define PLMAX 16
|
|
int c;
|
|
char *p = in;
|
|
char *r[PLMAX];
|
|
|
|
for (c = 0; c < PLMAX; c++)
|
|
r[c] = NULL;
|
|
|
|
c = 0;
|
|
if (!in || !*in)
|
|
goto pl_end;
|
|
|
|
do
|
|
{
|
|
while (isspace(*p))
|
|
*(p++) = '\0';
|
|
|
|
if (!*p || (strchr("#;", *p) && (!p[1] || isspace(p[1]))))
|
|
*p = '\0'; /* it ends HERE */
|
|
else
|
|
{
|
|
if (*p == '\"')
|
|
{
|
|
r[c++] = ++p;
|
|
while (*p && (*p != '\"'))
|
|
{
|
|
if ((*p == '\\') && p[1])
|
|
p += 2;
|
|
else
|
|
p++;
|
|
}
|
|
if (*p)
|
|
*(p++) = '\0';
|
|
}
|
|
else
|
|
{
|
|
r[c++] = p;
|
|
while (*p && !isspace(*p))
|
|
p++;
|
|
}
|
|
}
|
|
}
|
|
while (*p);
|
|
|
|
pl_end:
|
|
if (o1)
|
|
*o1 = r[0];
|
|
if (o2)
|
|
*o2 = r[1];
|
|
if (o3)
|
|
*o3 = r[2];
|
|
if (o4)
|
|
*o4 = r[3];
|
|
|
|
return c;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*char *unit_size(char *size) {
|
|
gchar *unit="byte";
|
|
long s;
|
|
|
|
if((s=atol(size))&&(s>=1024)) {
|
|
if((s>(1024*1024*1024))) {
|
|
unit="GB";
|
|
s=(long)(s/(1024*1024)); }
|
|
else if((s>(1024*1024))) {
|
|
unit="MB";
|
|
s=(long)(s/1024); }
|
|
else
|
|
unit="KB";
|
|
|
|
if((s/1024)>31)
|
|
sprintf(size,"%ld %s",(long)(s/1024),unit);
|
|
else
|
|
sprintf(size,"%.1f %s",((float)s)/1024,unit); }
|
|
else
|
|
sprintf(size,"%ld %s",s,unit);
|
|
|
|
return size; }
|
|
|
|
*/
|
|
|
|
/*****************************************************************************/
|
|
|
|
void
|
|
qsrt(void *a[], void *data, int lo, int hi,
|
|
int (*compare) (const void *, const void *, const void *))
|
|
{
|
|
int h, l;
|
|
void *p, *t;
|
|
|
|
if (lo < hi)
|
|
{
|
|
l = lo;
|
|
h = hi;
|
|
p = a[hi];
|
|
|
|
do
|
|
{
|
|
while ((l < h) && (compare(data, a[l], p) <= 0))
|
|
l = l + 1;
|
|
while ((h > l) && (compare(data, a[h], p) >= 0))
|
|
h = h - 1;
|
|
if (l < h)
|
|
{
|
|
t = a[l];
|
|
a[l] = a[h];
|
|
a[h] = t;
|
|
}
|
|
}
|
|
while (l < h);
|
|
|
|
t = a[l];
|
|
a[l] = a[hi];
|
|
a[hi] = t;
|
|
|
|
qsrt(a, data, lo, l - 1, compare);
|
|
qsrt(a, data, l + 1, hi, compare);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* TIMERS */
|
|
/**********/
|
|
|
|
unsigned long
|
|
timeout_add(uint f, int (*fun) (void *), void *data)
|
|
{
|
|
#ifdef HAVE_GLIB2
|
|
return g_timeout_add((guint) f, (GSourceFunc) fun, (gpointer) data);
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
timeout_remove(unsigned long handle)
|
|
{
|
|
#ifdef HAVE_GLIB2
|
|
return g_source_remove(handle) ? ECORE_CONFIG_ERR_SUCC :
|
|
ECORE_CONFIG_ERR_FAIL;
|
|
#endif
|
|
return ECORE_CONFIG_ERR_NOTSUPP;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* HASHES */
|
|
/**********/
|
|
|
|
int
|
|
eslist_free(eslist ** l)
|
|
{
|
|
eslist *e, *f;
|
|
|
|
if (!l)
|
|
return ECORE_CONFIG_ERR_NODATA;
|
|
for (e = *l; e; e = f)
|
|
{
|
|
f = e->next;
|
|
free(e);
|
|
}
|
|
*l = NULL;
|
|
return ECORE_CONFIG_ERR_SUCC;
|
|
}
|
|
|
|
int
|
|
eslist_next(eslist ** e)
|
|
{
|
|
if (!e || !*e)
|
|
return ECORE_CONFIG_ERR_NODATA;
|
|
*e = (*e)->next;
|
|
return ECORE_CONFIG_ERR_SUCC;
|
|
}
|
|
|
|
void *
|
|
eslist_payload(eslist ** e)
|
|
{
|
|
return (!e || !*e) ? NULL : (*e)->payload;
|
|
}
|
|
|
|
int
|
|
eslist_prepend(eslist ** e, void *p)
|
|
{
|
|
eslist *f;
|
|
|
|
if (!e)
|
|
return ECORE_CONFIG_ERR_NODATA;
|
|
|
|
if (!(f = malloc(sizeof(eslist))))
|
|
return ECORE_CONFIG_ERR_OOM;
|
|
|
|
f->payload = p;
|
|
f->next = *e;
|
|
|
|
*e = f;
|
|
|
|
return ECORE_CONFIG_ERR_SUCC;
|
|
}
|
|
|
|
int
|
|
eslist_append(eslist ** e, void *p)
|
|
{
|
|
eslist *f;
|
|
|
|
if (!e)
|
|
return ECORE_CONFIG_ERR_NODATA;
|
|
|
|
if (!(f = malloc(sizeof(eslist))))
|
|
return ECORE_CONFIG_ERR_OOM;
|
|
|
|
f->payload = p;
|
|
f->next = NULL;
|
|
|
|
if (!*e)
|
|
*e = f;
|
|
else
|
|
{
|
|
eslist *g = *e;
|
|
|
|
while (g->next)
|
|
g = g->next;
|
|
g->next = f;
|
|
}
|
|
|
|
return ECORE_CONFIG_ERR_SUCC;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* HASHES */
|
|
/**********/
|
|
|
|
void *
|
|
hash_table_new(void (*freekey), void (*freeval))
|
|
{
|
|
#ifdef HAVE_GLIB2
|
|
return g_hash_table_new_full(g_str_hash, g_str_equal, freekey, freeval);
|
|
#endif
|
|
return NULL;
|
|
}
|
|
|
|
void *
|
|
hash_table_fetch(void *hashtable, char *key)
|
|
{
|
|
#ifdef HAVE_GLIB2
|
|
return g_hash_table_lookup(hashtable, key);
|
|
#endif
|
|
return NULL;
|
|
}
|
|
|
|
int
|
|
hash_table_insert(void *hashtable, char *key, void *value)
|
|
{
|
|
#ifdef HAVE_GLIB2
|
|
g_hash_table_insert(hashtable, key, value);
|
|
return ECORE_CONFIG_ERR_SUCC;
|
|
#endif
|
|
return ECORE_CONFIG_ERR_NOTSUPP;
|
|
}
|
|
|
|
int
|
|
hash_table_replace(void *hashtable, char *key, void *value)
|
|
{
|
|
#ifdef HAVE_GLIB2
|
|
g_hash_table_replace(hashtable, key, value);
|
|
return ECORE_CONFIG_ERR_SUCC;
|
|
#endif
|
|
return ECORE_CONFIG_ERR_NOTSUPP;
|
|
}
|
|
|
|
int
|
|
hash_table_remove(void *hashtable, char *key)
|
|
{
|
|
#ifdef HAVE_GLIB2
|
|
g_hash_table_remove(hashtable, key);
|
|
return ECORE_CONFIG_ERR_SUCC;
|
|
#endif
|
|
return ECORE_CONFIG_ERR_NOTSUPP;
|
|
}
|
|
|
|
int
|
|
hash_table_dst(void *hashtable)
|
|
{
|
|
#ifdef HAVE_GLIB2
|
|
g_hash_table_destroy(hashtable);
|
|
return ECORE_CONFIG_ERR_SUCC;
|
|
#endif
|
|
return ECORE_CONFIG_ERR_NOTSUPP;
|
|
}
|
|
|
|
int
|
|
hash_table_walk(void *hashtable, hash_walker fun, void *data)
|
|
{
|
|
#ifdef HAVE_GLIB2
|
|
g_hash_table_foreach(hashtable, (GHFunc) fun, data);
|
|
return ECORE_CONFIG_ERR_SUCC;
|
|
#endif
|
|
return ECORE_CONFIG_ERR_NOTSUPP;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* STRINGS */
|
|
/***********/
|
|
|
|
estring *
|
|
estring_new(int size)
|
|
{
|
|
estring *e = malloc(sizeof(estring));
|
|
|
|
if (e)
|
|
{
|
|
memset(e, 0, sizeof(estring));
|
|
if ((size > 0) && (e->str = malloc(size)))
|
|
e->alloc = size;
|
|
}
|
|
return e;
|
|
}
|
|
|
|
estring *
|
|
estring_dst(estring * e)
|
|
{
|
|
if (e)
|
|
{
|
|
if (e->str)
|
|
free(e->str);
|
|
free(e);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
char *
|
|
estring_disown(estring * e)
|
|
{
|
|
if (e)
|
|
{
|
|
char *r = e->str;
|
|
|
|
free(e);
|
|
return r;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
char *
|
|
estring_free(estring * e, int release_payload)
|
|
{ /* glib compat */
|
|
if (release_payload)
|
|
{
|
|
estring_dst(e);
|
|
return NULL;
|
|
}
|
|
return estring_disown(e);
|
|
}
|
|
|
|
int
|
|
estring_truncate(estring * e, int size)
|
|
{
|
|
if (!e || (size < 0))
|
|
return ECORE_CONFIG_ERR_FAIL;
|
|
if (e->used <= size)
|
|
return e->used;
|
|
e->str[size] = '\0';
|
|
e->used = size;
|
|
return size;
|
|
}
|
|
|
|
int
|
|
estring_printf(estring * e, char *fmt, ...)
|
|
{
|
|
int need;
|
|
va_list ap;
|
|
char *p;
|
|
|
|
if (!e)
|
|
return ECORE_CONFIG_ERR_FAIL;
|
|
|
|
if (!(e->str))
|
|
{
|
|
if (!(e->str = (char *)malloc(e->alloc = 512)))
|
|
return ECORE_CONFIG_ERR_OOM;
|
|
}
|
|
|
|
retry:
|
|
va_start(ap, fmt);
|
|
need = vsnprintf(e->str, e->alloc, fmt, ap);
|
|
va_end(ap);
|
|
|
|
if ((need >= e->alloc) || (need < 0))
|
|
{
|
|
if (need < 0)
|
|
need = 2 * e->alloc;
|
|
else
|
|
need++;
|
|
if (!(p = (char *)realloc(e->str, need)))
|
|
{
|
|
free(e->str);
|
|
e->alloc = e->used = 0;
|
|
return ECORE_CONFIG_ERR_OOM;
|
|
}
|
|
e->alloc = need;
|
|
e->str = p;
|
|
goto retry;
|
|
}
|
|
|
|
return e->used = need;
|
|
}
|
|
|
|
int
|
|
estring_appendf(estring * e, char *fmt, ...)
|
|
{
|
|
int need;
|
|
va_list ap;
|
|
char *p;
|
|
|
|
if (!e)
|
|
return ECORE_CONFIG_ERR_FAIL;
|
|
|
|
if (!e->str)
|
|
{
|
|
e->used = e->alloc = 0;
|
|
if (!(e->str = (char *)malloc(e->alloc = 512)))
|
|
return ECORE_CONFIG_ERR_OOM;
|
|
}
|
|
|
|
retry:
|
|
va_start(ap, fmt);
|
|
need = vsnprintf(e->str + e->used, e->alloc - e->used, fmt, ap);
|
|
va_end(ap);
|
|
|
|
if ((need >= (e->alloc - e->used)) || (need < 0))
|
|
{
|
|
if (need < 0)
|
|
need = 2 * e->alloc;
|
|
else
|
|
need++;
|
|
need += e->used;
|
|
need += (CHUNKLEN - (need % CHUNKLEN));
|
|
|
|
if (!(p = (char *)realloc(e->str, need)))
|
|
{
|
|
free(e->str);
|
|
e->alloc = e->used = 0;
|
|
return ECORE_CONFIG_ERR_OOM;
|
|
}
|
|
e->alloc = need;
|
|
e->str = p;
|
|
goto retry;
|
|
}
|
|
|
|
return e->used += need;
|
|
}
|
|
|
|
int
|
|
esprintf(char **result, char *fmt, ...)
|
|
{
|
|
int need, have;
|
|
va_list ap;
|
|
char *n;
|
|
|
|
if (!result)
|
|
return ECORE_CONFIG_ERR_FAIL;
|
|
|
|
if (!(n = (char *)malloc(have = 512)))
|
|
return ECORE_CONFIG_ERR_OOM;
|
|
|
|
retry:
|
|
va_start(ap, fmt);
|
|
need = vsnprintf(n, have, fmt, ap);
|
|
va_end(ap);
|
|
|
|
if ((need >= have) || (need < 0))
|
|
{
|
|
char *p;
|
|
|
|
if (need < 0)
|
|
need = 2 * have;
|
|
else
|
|
need++;
|
|
if (!(p = (char *)realloc(n, need)))
|
|
{
|
|
free(n);
|
|
return ECORE_CONFIG_ERR_OOM;
|
|
}
|
|
have = need;
|
|
n = p;
|
|
goto retry;
|
|
}
|
|
|
|
if (*result)
|
|
free(*result);
|
|
*result = n;
|
|
|
|
return need;
|
|
}
|
|
|
|
#if 0
|
|
int
|
|
ejoin(char **result, char *delim, ...)
|
|
{
|
|
int dl, cl, ret = ECORE_CONFIG_ERR_SUCC;
|
|
va_list ap;
|
|
char *e, *n;
|
|
|
|
if (!result)
|
|
return ECORE_CONFIG_ERR_FAIL;
|
|
if (!delim)
|
|
delim = "";
|
|
dl = strlen(delim);
|
|
|
|
va_start(ap, delim);
|
|
cl = -dl;
|
|
while ((e = va_arg(ap, char *)))
|
|
cl += strlen(e) + dl;
|
|
|
|
va_end(ap);
|
|
|
|
if (cl <= 0)
|
|
{
|
|
if (!(n = strdup("")))
|
|
ret = ECORE_CONFIG_ERR_OOM;
|
|
}
|
|
else if (!(n = malloc(cl + 1)))
|
|
ret = ECORE_CONFIG_ERR_OOM;
|
|
else
|
|
{
|
|
char *p = n;
|
|
|
|
va_start(ap, delim);
|
|
while ((e = va_arg(ap, char *)))
|
|
{
|
|
if (dl && (p != n))
|
|
{
|
|
strcpy(p, delim);
|
|
p += dl;
|
|
}
|
|
strcpy(p, e);
|
|
p += strlen(p);
|
|
}
|
|
va_end(ap);
|
|
}
|
|
|
|
if (*result)
|
|
free(*result);
|
|
*result = n;
|
|
|
|
return ret;
|
|
}
|
|
|
|
int
|
|
ecat(char **result, ...)
|
|
{
|
|
int cl, ret = ECORE_CONFIG_ERR_SUCC;
|
|
va_list ap;
|
|
char *e, *n;
|
|
|
|
if (!result)
|
|
return ECORE_CONFIG_ERR_FAIL;
|
|
|
|
va_start(ap, result);
|
|
cl = 0;
|
|
while ((e = va_arg(ap, char *)))
|
|
cl += strlen(e);
|
|
|
|
va_end(ap);
|
|
|
|
if (cl <= 0)
|
|
{
|
|
if (!(n = strdup("")))
|
|
ret = ECORE_CONFIG_ERR_OOM;
|
|
}
|
|
else if (!(n = malloc(cl + 1)))
|
|
ret = ECORE_CONFIG_ERR_OOM;
|
|
else
|
|
{
|
|
char *p = n;
|
|
|
|
va_start(ap, result);
|
|
while ((e = va_arg(ap, char *)))
|
|
{
|
|
strcpy(p, e);
|
|
p += strlen(p);
|
|
}
|
|
va_end(ap);
|
|
}
|
|
|
|
if (*result)
|
|
free(*result);
|
|
*result = n;
|
|
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
/*****************************************************************************/
|