This should give a working ecore with ecore_config. No test apps yet, that is another story. Also need a tidyup...

SVN revision: 8007
This commit is contained in:
handyande 2003-12-05 16:57:32 +00:00 committed by handyande
parent cdf915f312
commit f6627ea478
15 changed files with 2142 additions and 5 deletions

View File

@ -1,5 +1,6 @@
#undef PACKAGE_LOCALE_DIR
#undef PACKAGE_DATA_DIR
#undef PACKAGE_LIB_DIR
#undef PACKAGE_SOURCE_DIR
#undef PACKAGE_BIN_DIR
#undef BUILD_ECORE_EVAS

View File

@ -75,6 +75,17 @@ else
AC_DEFINE_UNQUOTED(PACKAGE_DATA_DIR, "${datadir}/${PACKAGE}")
fi
dnl Set PACKAGE_LIB_DIR in config.h.
if test "x${libdir}" = 'xNONE'; then
if test "x${prefix}" = "xNONE"; then
AC_DEFINE_UNQUOTED(PACKAGE_LIB_DIR, "${ac_default_prefix}/lib")
else
AC_DEFINE_UNQUOTED(PACKAGE_LIB_DIR, "${prefix}/lib")
fi
else
AC_DEFINE_UNQUOTED(PACKAGE_LIB_DIR, "${libdir}")
fi
dnl Set PACKAGE_SOURCE_DIR in config.h.
packagesrcdir=`cd $srcdir && pwd`
AC_DEFINE_UNQUOTED(PACKAGE_SOURCE_DIR, "${packagesrcdir}")
@ -378,6 +389,7 @@ src/lib/ecore_con/Makefile
src/lib/ecore_ipc/Makefile
src/lib/ecore_txt/Makefile
src/lib/ecore_config/Makefile
src/lib/ecore_config/ipc/Makefile
debian/Makefile
], [
chmod +x ecore-config

View File

@ -46,7 +46,7 @@ while test $# -gt 0; do
;;
--libs)
libdirs=-L@libdir@
echo $libdirs -lecore @ecore_job_libs@ @ecore_x_libs@ @ecore_evas_libs@ @ecore_con_libs@ @ecore_ipc_libs@ @ecore_txt_libs@ @ecore_fb_libs@ -lm
echo $libdirs -lecore @ecore_job_libs@ @ecore_x_libs@ @ecore_evas_libs@ @ecore_con_libs@ @ecore_ipc_libs@ @ecore_txt_libs@ @ecore_fb_libs@ @ecore_config_libs@ -lm
;;
*)
echo "${usage}" 1>&2

View File

@ -7,4 +7,5 @@ ecore_fb \
ecore_con \
ecore_x \
ecore_ipc \
ecore_evas
ecore_evas \
ecore_config

View File

@ -0,0 +1,145 @@
#ifndef _ECORE_CONFIG_H
#define _ECORE_CONFIG_H
/**
* @file Ecore_Config.h
* @brief The file that any project using ecore_config will want to include.
*
* This file provies all headers and structs for use with Ecore_Config.
* Using individual header files should not be necessary.
*/
/**
* @mainpage Enlightened Configuration Library Documentation
*
* @image html ecore_config_mini.png
*
* @section intro Introduction
*
* The Enlightened Property Library (Ecore_Config) is an adbstraction from the
* complexities of writing your own configuration. It provides many features
* using the Enlightenment 17 development libraries.
*/
#include "config.h"
#define DIR_DELIMITER '/'
#define ECORE_CONFIG_FLOAT_PRECISION 1000
#ifndef TRUE
# define FALSE (0)
# define TRUE (!FALSE)
#endif
#include "debug.h"
#include "errors.h"
#include <Ecore_Ipc.h>
/* structures */
typedef enum Ecore_Config_Type {
PT_NIL=0,
PT_INT=1,
PT_FLT=2,
PT_STR=3,
PT_PTR=4,
PT_RGB=5
} Ecore_Config_Type;
typedef enum Ecore_Config_Flag {
PF_NONE=0,
PF_BOUNDS=1,
PF_MODIFIED=2
} Ecore_Config_Flag;
typedef int (*Ecore_Config_Listener)(const char *key,const Ecore_Config_Type type,const int tag,void *data,void *bundle);
typedef struct Ecore_Config_Listener_List {
Ecore_Config_Listener listener;
const char *name;
void *data;
int tag;
struct Ecore_Config_Listener_List *next; } Ecore_Config_Listener_List;
/**
* The actual property for storing a key-value pair.
*/
typedef struct Ecore_Config_Prop {
char *key;
char *description;
Ecore_Config_Type type;
char *ptr;
long val,lo,hi,step;
Ecore_Config_Flag flags;
Ecore_Config_Listener_List *listeners;
struct Ecore_Config_Prop *next; /**< pointer to the next property in the list */
} Ecore_Config_Prop;
/**
* A container for a list of properties. Provided so that an application can
* use different set of properties at any time. This is useful for multiple
* window support.
*/
typedef struct Ecore_Config_Bundle {
char *identifier; /**< identifier for this set of properties (window ID for example) */
char *owner; /**< this is used to store the application name related to the bundle */
long serial; /**< unique identifier to identify bundle */
Ecore_Config_Prop *data; /**< pointer to root of property list */
void *user_data; /**< app specific pointer to "other data" */
struct Ecore_Config_Bundle *next; /**< pointer to next bundle in this application */
} Ecore_Config_Bundle;
typedef struct Ecore_Config_Server {
void *server;
char *name;
Ecore_Config_Bundle *bundles; /* data anchor */
struct Ecore_Config_Server *next; } Ecore_Config_Server;
Ecore_Config_Prop *ecore_config_get(const Ecore_Config_Bundle *t,const char *key);
const char *ecore_config_get_type(const Ecore_Config_Prop *e);
void *ecore_config_get_data(const Ecore_Config_Bundle *t,const char *key);
char *ecore_config_get_string(const Ecore_Config_Bundle *t,const char *key);
long ecore_config_get_int(const Ecore_Config_Bundle *t,const char *key);
int ecore_config_get_rgb(const Ecore_Config_Bundle *t,const char *key,int *r, int *g, int *b);
float ecore_config_get_float(const Ecore_Config_Bundle *t,const char *key);
char *ecore_config_get_as_string(const Ecore_Config_Bundle *t,const char *key);
char *ecore_config_canonize_key(char *,int modify);
int ecore_config_set(Ecore_Config_Bundle *t,const char *key,char *val);
int ecore_config_set_string(Ecore_Config_Bundle *t,const char *key,char *val);
int ecore_config_set_int(Ecore_Config_Bundle *t,const char *key,int val);
int ecore_config_set_rgb(Ecore_Config_Bundle *t,const char *key,char *val);
int ecore_config_set_float(Ecore_Config_Bundle *t,const char *key,float val);
int ecore_config_set_as_string(Ecore_Config_Bundle *t,const char *key,char *val);
int ecore_config_default(Ecore_Config_Bundle *t,const char *key,char *val,float lo,float hi,float step);
int ecore_config_listen(Ecore_Config_Bundle *t,const char *name,const char *key,Ecore_Config_Listener listener,int tag,void *data);
int ecore_config_deaf(Ecore_Config_Bundle *t,const char *name,const char *key,Ecore_Config_Listener listener);
Ecore_Config_Prop *ecore_config_dst(Ecore_Config_Bundle *t,Ecore_Config_Prop *e);
Ecore_Config_Bundle *ecore_config_new_bundle(Ecore_Config_Server *srv, const char *id);
Ecore_Config_Bundle *ecore_config_bundle_get_1st(Ecore_Config_Server *srv);
Ecore_Config_Bundle *ecore_config_bundle_get_next(Ecore_Config_Bundle *ns);
Ecore_Config_Bundle *ecore_config_bundle_get_by_serial(Ecore_Config_Server *srv, long serial);
Ecore_Config_Bundle *ecore_config_bundle_get_by_label(Ecore_Config_Server *srv, const char *label);
long ecore_config_bundle_get_serial(Ecore_Config_Bundle *ns);
char *ecore_config_bundle_get_label(Ecore_Config_Bundle *ns);
Ecore_Config_Server *ecore_config_init(char *name);
Ecore_Config_Server *ecore_config_init_global(char *name);
int ecore_config_exit(void);
int ecore_config_load(Ecore_Config_Bundle *b);
int ecore_config_load_file(Ecore_Config_Bundle *b, char *file);
int ecore_config_save(Ecore_Config_Bundle *b);
int ecore_config_save_file(Ecore_Config_Bundle *b, char *file);
#endif

View File

@ -16,8 +16,8 @@ Ecore_Config.h
libecore_config_la_SOURCES = \
ecore_config.c \
util.c \
ipc_main.c \
util.c \
edb.c
libecore_config_la_LIBADD = \
@ -31,10 +31,10 @@ endif
EXTRA_DIST = \
Ecore_Config.h \
ecore_config.c \
util.c \
util.h \
ipc_main.c \
ipc.h \
util.c \
util.h \
edb.c \
debug.h \
errors.h \

View File

@ -0,0 +1,10 @@
#define DEBUG 999
#ifdef ECORE_CONFIG_DEBUG
# define D(fmt,args...) do { if(DEBUG>=0) fprintf(stderr,fmt,## args); } while(0);
#else
# define D(msg,args...)
#endif
#define E(lvl,fmt,args...) do { if(DEBUG>=(lvl)) fprintf(stderr,fmt,## args); } while(0)

View File

@ -0,0 +1,534 @@
#include "Ecore_Config.h"
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
Ecore_Config_Server *ipc_init(char *name);
int ipc_quit(void);
static char *ecore_config_type[]={ "undefined", "integer", "float", "string", "pointer", "colour" };
/* tolower, weed out _ - */
char *prop_canonize_key(char *pn,int modify) {
char *v,*r;
if(!modify)
r=pn;
else if(!(r=strdup(pn)))
return NULL;
v=r;
while(*v) {
if(strchr("-_/",*v))
memmove(v,&v[1],strlen(v));
else {
if(isupper(*v))
*v=tolower(*v);
v++; }}
return r; }
Ecore_Config_Prop *ecore_config_dst(Ecore_Config_Bundle *t,Ecore_Config_Prop *e) {
Ecore_Config_Prop *p=NULL,*c=e;
Ecore_Config_Listener_List *l;
if(!e||!e->key)
return NULL;
if(t) {
if(t->data==e)
t->data=e->next;
else {
do {
p=c;
c=c->next;
} while(c&&(c!=e));
if(c) /* remove from list if even in there */
p->next=c->next; }}
while(e->listeners) {
l=e->listeners;
e->listeners=e->listeners->next;
free(l); }
if(e->key)
free(e->key);
if(e->ptr&&(e->type==PT_STR))
free(e->ptr);
memset(e,0,sizeof(Ecore_Config_Prop));
free(e);
return NULL; }
Ecore_Config_Prop *ecore_config_get(const Ecore_Config_Bundle *t,const char *key) {
Ecore_Config_Prop *e;
if(!t||!key)
return NULL;
e=t->data;
while(e) {
if(!strcmp(key,e->key))
return e;
e=e->next; }
return NULL; }
const char *ecore_config_get_type(const Ecore_Config_Prop *e) {
if(e) {
return ecore_config_type[e->type]; }
return "not found"; }
void *ecore_config_get_data(const Ecore_Config_Bundle *t,const char *key) {
Ecore_Config_Prop *e=ecore_config_get(t,key);
return (e?(((e->type==PT_STR)||(e->type==PT_PTR))?((void *)&e->ptr)
:((void *)&e->val))
:NULL); }
char *ecore_config_get_string(const Ecore_Config_Bundle *t,const char *key) {
Ecore_Config_Prop *e=ecore_config_get(t,key);
return (e&&(e->type==PT_STR))?e->ptr:NULL; }
long ecore_config_get_int(const Ecore_Config_Bundle *t,const char *key) {
Ecore_Config_Prop *e=ecore_config_get(t,key);
return (e&&((e->type==PT_INT)||(e->type==PT_RGB)))?e->val:0L; }
float ecore_config_get_float(const Ecore_Config_Bundle *t,const char *key) {
Ecore_Config_Prop *e=ecore_config_get(t,key);
return (e&&(e->type==PT_FLT))?(e->val/ECORE_CONFIG_FLOAT_PRECISION):0.0; }
int ecore_config_get_rgb(const Ecore_Config_Bundle *t,const char *key,int *r, int *g, int *b) {
Ecore_Config_Prop *e=ecore_config_get(t,key);
if(e&&((e->type==PT_RGB))) {
*r=(e->val>>16)&0xff;
*g=(e->val>>8)&0xff;
*b=e->val&0xff;
return ECORE_CONFIG_ERR_SUCC; }
return ECORE_CONFIG_ERR_FAIL; }
char *ecore_config_get_rgbstr(const Ecore_Config_Bundle *t,const char *key) {
Ecore_Config_Prop *e=ecore_config_get(t,key);
char *r=NULL;
esprintf(&r,"#%06x",ecore_config_get_int(t,key));
return r; }
char *ecore_config_get_as_string(const Ecore_Config_Bundle *t,const char *key) {
Ecore_Config_Prop *e;
char *r=NULL;
if(!(e=ecore_config_get(t,key)))
E(0,"no such property, \"%s\"...\n",key);
else {
const char *type=ecore_config_get_type(e);
switch(e->type) {
case PT_NIL:
esprintf(&r,"%s:%s=<nil>",key,type); break;
case PT_INT:
esprintf(&r,"%s:%s=%ld",key,type,ecore_config_get_int(t,key)); break;
case PT_FLT:
esprintf(&r,"%s:%s=%lf",key,type,ecore_config_get_float(t,key)); break;
case PT_STR:
esprintf(&r,"%s:%s=\"%s\"",key,type,ecore_config_get_string(t,key)); break;
case PT_PTR:
esprintf(&r,"%s:%s=%p",key,type,e->ptr); break;
case PT_RGB:
esprintf(&r,"%s:%s=#%06x",key,type,ecore_config_get_int(t,key)); break;
default:
esprintf(&r,"%s:unknown_type",key); break; }}
return r; }
static int ecore_config_bound(Ecore_Config_Prop *e) {
int ret=ECORE_CONFIG_ERR_SUCC;
long v;
if(!e)
return ECORE_CONFIG_ERR_FAIL;
if(e->flags&PF_BOUNDS) {
if((e->val<e->lo)) {
E(0,"ecore_config_bounds(\"%s\",%ld): value out of range; adjusted to %ld...\n",e->key,e->val,e->lo);
e->val=e->lo; }
else if((e->val>e->hi)) {
E(0,"ecore_config_bounds(\"%s\",%ld): value out of range; adjusted to %ld...\n",e->key,e->val,e->hi);
e->val=e->hi; }
else
ret=ECORE_CONFIG_ERR_IGNORED; }
else
ret=ECORE_CONFIG_ERR_IGNORED;
if(e->step) {
v=((int)(e->val/e->step))*e->step;
if(v!=e->val) {
if(e->type==PT_FLT)
E(0,"ecore_config_bound(\"%s\"): float value %f not a multiple of %f, adjusted to %f...\n",
e->key,((double)e->val)/ECORE_CONFIG_FLOAT_PRECISION,((double)e->step)/ECORE_CONFIG_FLOAT_PRECISION,((double)v)/ECORE_CONFIG_FLOAT_PRECISION);
else
E(0,"ecore_config_bound(\"%s\"): integer value %ld not a multiple of %ld, adjusted to %ld...\n",
e->key,e->val,e->step,v);
ret=ECORE_CONFIG_ERR_SUCC;
e->val=v; }}
return ret; }
int ecore_config_guess_type(char *val) {
char *l=NULL;
long v;
float f;
if(!val)
return PT_NIL;
if (val[0]=='#')
return PT_RGB;
v=strtol(val,&l,10);
if(*l) {
float f;
if (sscanf(val,"%f%*s",&f)!=1)
return PT_STR;
return PT_FLT;
}
return PT_INT;
}
static int ecore_config_val_typed(Ecore_Config_Prop *e,void *val,int type) {
char *l=NULL;
long v=0;
e->type=PT_NIL;
if(!val)
e->ptr=NULL;
else {
if (type==PT_INT) {
e->val=(int)val;
e->type=PT_INT;
} else if (type==PT_STR) {
if(!(e->ptr=strdup(val)))
return ECORE_CONFIG_ERR_OOM;
e->type=PT_STR;
} else if (type==PT_RGB) {
if (((char *)val)[0]=='#') {
if((v=strtol(&((char *)val)[1],&l,16))<0) {
v=0;
E(0,"ecore_config_val: key \"%s\" -- hexadecimal value less than zero, bound to zero...\n",val);
l=(char *)val;
}
} else {
E(0,"ecore_config_val: key \"%s\" -- value \"%s\" not a valid hexadecimal RGB value?\n",e->key,val);
return ECORE_CONFIG_ERR_FAIL;
}
if(*l)
E(0,"ecore_config_val: key \"%s\" -- value \"%s\" not a valid hexadecimal RGB value?\n",e->key,val);
else {
e->val=v;
e->type=PT_RGB;
}
} else if (type==PT_FLT) {
v=strtol(val,&l,10);
if(*l) {
float f;
if(sscanf(val,"%f%*s",&f)!=1) {
if(!(e->ptr=strdup(val)))
return ECORE_CONFIG_ERR_OOM;
e->type=PT_STR; }
else {
e->val=(long)(f*ECORE_CONFIG_FLOAT_PRECISION);
e->type=PT_FLT; }
}
}
ecore_config_bound(e);
e->flags|=PF_MODIFIED;
return ECORE_CONFIG_ERR_SUCC;
}
}
static int ecore_config_val(Ecore_Config_Prop *e,char *val) {
int type = ecore_config_guess_type(val);
return ecore_config_val_typed(e,(void *)val,type); }
static int ecore_config_add_typed(Ecore_Config_Bundle *t, const char *key, void* val, int type) {
Ecore_Config_Prop *e;
if (!key)
return ECORE_CONFIG_ERR_NODATA;
if(!(e=malloc(sizeof(Ecore_Config_Prop))))
goto ret;
memset(e,0,sizeof(Ecore_Config_Prop));
if(!(e->key=strdup(key)))
goto ret_free_nte;
if(!val)
e->type=PT_NIL;
else if(ecore_config_val_typed(e,val,type)==ECORE_CONFIG_ERR_OOM)
goto ret_free_key;
e->next=t?t->data:NULL;
if(t) t->data=e;
return ECORE_CONFIG_ERR_SUCC;
ret_free_key:
free(e->key);
ret_free_nte:
free(e);
ret:
return ECORE_CONFIG_ERR_OOM; }
static int ecore_config_add(Ecore_Config_Bundle *t,const char *key,char *val) {
int type=ecore_config_guess_type(val);
return ecore_config_add_typed(t,key,val,type); }
int ecore_config_set_typed(Ecore_Config_Bundle *t,const char *key,void *val,int type) {
Ecore_Config_Prop *e;
Ecore_Config_Listener_List *l;
int ret;
if (!t||!key)
return ECORE_CONFIG_ERR_NODATA;
if (!(e=ecore_config_get(t,key)))
return ecore_config_add_typed(t,key,val,type);
if ((ret=ecore_config_val_typed(e,val,type))==ECORE_CONFIG_ERR_SUCC) {
for(l=e->listeners;l;l=l->next)
l->listener(e->key,e->type,l->tag,l->data,t);
}
else {
E(0,"ecore_config_set_typed(\"%s\"): ecore_config_val_typed() failed: %d\n",key,ret);
}
return ret;
}
int ecore_config_set(Ecore_Config_Bundle *t,const char *key,char *val) {
int type=ecore_config_guess_type(val);
return ecore_config_set_typed(t,key,val,type); }
int ecore_config_set_as_string(Ecore_Config_Bundle *t,const char *key,char *val) {
return ecore_config_set(t,key,val); }
int ecore_config_set_int(Ecore_Config_Bundle *t,const char *key, int val) {
return ecore_config_set_typed(t,key,(void *)val,PT_INT); }
int ecore_config_set_string(Ecore_Config_Bundle *t,const char *key, char* val) {
return ecore_config_set_typed(t,key,(void *)val,PT_STR); }
int ecore_config_set_float(Ecore_Config_Bundle *t,const char *key, float val) {
return ecore_config_set_typed(t,key,(void *)&val,PT_FLT); }
int ecore_config_set_rgb(Ecore_Config_Bundle *t,const char *key, char* val) {
return ecore_config_set_typed(t,key,(void *)val,PT_RGB); }
int ecore_config_default(Ecore_Config_Bundle *t,const char *key,char *val,float lo,float hi,float step) {
int ret=ECORE_CONFIG_ERR_SUCC;
Ecore_Config_Prop *e;
if(!(e=ecore_config_get(t,key))) { /* prop doesn't exist yet */
if((ret=ecore_config_add(t,key,val))!=ECORE_CONFIG_ERR_SUCC) /* try to add it */
return ret; /* ...failed */
if(!(e=ecore_config_get(t,key))) /* get handle */
return ECORE_CONFIG_ERR_FAIL;
e->flags=e->flags&~PF_MODIFIED; }
if(e->type==PT_INT) {
e->step=(int)step;
e->flags|=PF_BOUNDS;
e->lo=(int)lo;
e->hi=(int)hi; }
else if(e->type==PT_FLT) {
e->step=(int)(step*ECORE_CONFIG_FLOAT_PRECISION);
e->flags|=PF_BOUNDS;
e->lo=(int)(lo*ECORE_CONFIG_FLOAT_PRECISION);
e->hi=(int)(hi*ECORE_CONFIG_FLOAT_PRECISION); }
ecore_config_bound(e);
return ret; }
int ecore_config_listen(Ecore_Config_Bundle *t,const char *name,const char *key,
Ecore_Config_Listener listener,int tag,void *data) {
Ecore_Config_Prop *e;
Ecore_Config_Listener_List *l;
if(!t||!key)
return ECORE_CONFIG_ERR_NODATA;
if(!(e=ecore_config_get(t,key))) {
int ret=ecore_config_add(t,key,"");
if(ret!=ECORE_CONFIG_ERR_SUCC) {
E(0,"ecore_config_listen: ecore_config_add(\"%s\") failed: %d\n",key,ret);
return ret; }
if(!(e=ecore_config_get(t,key))) {
E(0,"ecore_config_listen: list of properties corrupted!?\n");
return ECORE_CONFIG_ERR_FAIL; }}
for(l=e->listeners;l;l=l->next)
if(!strcmp(l->name,name)||(l->listener==listener)) {
E(1,"ecore_config_listen: %s is already listening for changes of %s in %s...\n",
name,key,t->identifier?t->identifier:"");
return ECORE_CONFIG_ERR_IGNORED; }
if(!(l=malloc(sizeof(Ecore_Config_Listener_List))))
return ECORE_CONFIG_ERR_OOM;
E(1,"registering listener \"%s\" for \"%s\" (%d)...\n",name,key,e->type);
memset(l,0,sizeof(Ecore_Config_Listener_List));
l->listener =listener;
l->name =name;
l->data =data;
l->tag =tag;
l->next =e->listeners;
e->listeners=l;
if(e->type!=PT_NIL) /* call right on creation if prop exists and has val */
listener(key,e->type,tag,data,t);
return ECORE_CONFIG_ERR_SUCC; }
int ecore_config_deaf(Ecore_Config_Bundle *t,const char *name,const char *key,
Ecore_Config_Listener listener) {
Ecore_Config_Prop *e;
Ecore_Config_Listener_List *l,*p;
int ret=ECORE_CONFIG_ERR_NOTFOUND;
if(!t||!key)
return ECORE_CONFIG_ERR_NODATA;
if(!(e=ecore_config_get(t,key)))
return ECORE_CONFIG_ERR_NOTFOUND;
for(p=NULL,l=e->listeners;l;p=l,l=l->next) {
if(!strcmp(l->name,name)||(l->listener==listener)) {
ret=ECORE_CONFIG_ERR_SUCC;
if(!p)
e->listeners=e->listeners->next;
else
p->next=l->next;
memset(l,0,sizeof(Ecore_Config_Listener));
free(l); }}
return ret; }
Ecore_Config_Bundle *ecore_config_bundle_get_1st(Ecore_Config_Server *srv) { /* anchor: global, but read-only */
return srv->bundles; }
Ecore_Config_Bundle *ecore_config_bundle_get_next(Ecore_Config_Bundle *ns) {
return ns?ns->next:NULL; }
Ecore_Config_Bundle *ecore_config_bundle_get_by_serial(Ecore_Config_Server *srv, long serial) {
Ecore_Config_Bundle *eb=srv->bundles;
if(serial<0)
return NULL;
else if(serial==0) {
Ecore_Config_Bundle *r=eb;
return r; }
while(eb) {
if(eb->serial==serial)
return eb;
eb=eb->next; }
return NULL; }
Ecore_Config_Bundle *ecore_config_bundle_get_by_label(Ecore_Config_Server *srv, const char *label) {
Ecore_Config_Bundle *ns=srv->bundles;
while(ns) {
if(ns->identifier&&!strcmp(ns->identifier,label))
return ns;
ns=ns->next; }
return NULL; }
long ecore_config_bundle_get_serial(Ecore_Config_Bundle *ns) {
return ns?ns->serial:-1; }
char *ecore_config_bundle_get_label(Ecore_Config_Bundle *ns) {
return ns?ns->identifier:NULL; }
Ecore_Config_Bundle *ecore_config_new_bundle(Ecore_Config_Server *srv,const char *identifier) {
Ecore_Config_Bundle *t;
static long ss=0; /* bundle unique serial */
if((t=malloc(sizeof(Ecore_Config_Bundle)))) {
memset(t,0,sizeof(Ecore_Config_Bundle));
t->identifier=identifier;
t->serial=++ss;
t->next=srv->bundles;
srv->bundles=t;
}
return t; }
Ecore_Config_Server *do_init(char *name) {
return ipc_init(name);
}
Ecore_Config_Server *ecore_config_init(char *name) {
char *p;
char *buf;
if((p=getenv("HOME"))) { /* debug-only ### FIXME */
if (!(buf=malloc(PATH_MAX*sizeof(char))))
return NULL;
snprintf(buf,PATH_MAX,"%s/.ecore/%s/.global",p,name);
unlink(buf, S_IRWXU);
free(buf);
}
return do_init(name);
}
Ecore_Config_Server *ecore_config_init_global(char *name) {
char *p;
int global=0;
char *buf;
if((p=getenv("HOME"))) { /* debug-only ### FIXME */
if (!(buf=malloc(PATH_MAX*sizeof(char))))
return NULL;
snprintf(buf,PATH_MAX,"%s/.ecore/%s/.global",p,name);
if (global = creat(buf, S_IRWXU))
close(global);
free(buf);
}
return do_init(name);
}
int ecore_config_exit(void) {
return ipc_exit();
}

View File

@ -0,0 +1,111 @@
#include <Edb.h>
#include "Ecore_Config.h"
#include <stdlib.h>
#include <stdio.h>
int ecore_config_load(Ecore_Config_Bundle *b) {
char* file = malloc(1024); /* ### fixme */
sprintf(file,"%s/.e/%s/config.db",getenv("HOME"),b->owner);
return ecore_config_load_file(b,file);
free(file);
}
int ecore_config_save(Ecore_Config_Bundle *b) {
char* file = malloc(1024); /* ### fixme */
sprintf(file,"%s/.e/%s/config.db",getenv("HOME"),b->owner);
return ecore_config_save_file(b,file);
free(file);
}
int ecore_config_load_file(Ecore_Config_Bundle *b, char *file) {
E_DB_File *db = NULL;
char **keys;
int key_count;
int x;
char *type = NULL;
db = e_db_open_read(file);
if (!db) {
E(0, "Cannot open database from file %s!\n", file);
return 1;
}
keys = e_db_dump_key_list(file, &key_count);
for (x = 0; x < key_count; x++) {
type = e_db_type_get(db, keys[x]);
if (!type) type = "?";
char *data = NULL;
if (!strcmp(type, "int")) {
int tmp;
if (e_db_int_get(db, keys[x], &tmp)) {
ecore_config_set_int(b, keys[x], tmp);
} else {
E(0, "Could not read key %s!\n", keys[x]);
}
} else if (!strcmp(type, "float")) {
float tmp;
if (e_db_float_get(db, keys[x], &tmp)) {
ecore_config_set_float(b, keys[x], tmp);
} else {
E(0, "Could not read key %s!\n", keys[x]);
}
} else if (!strcmp(type, "str")) {
if (data = e_db_str_get(db, keys[x])) {
if (ecore_config_guess_type(data)==PT_RGB)
ecore_config_set_rgb(b,keys[x],data);
else
ecore_config_set_string(b,keys[x],data);
} else {
E(0, "Could not read key %s!\n", keys[x]);
}
} else {
E(1, "Unexpected type: %s\n", type);
continue;
}
if (type) free(type);
}
e_db_close(db);
return 0;
}
int ecore_config_save_file(Ecore_Config_Bundle *b, char *file) {
Ecore_Config_Prop *next=b->data;
E_DB_File *db = NULL;
int x;
/* ### we may need to create a directory or two here! */
db = e_db_open(file);
if (!db) {
E(0, "Cannot open database from file %s!\n", file);
return 1;
}
while (next) {
switch (next->type) {
case PT_INT:
e_db_int_set(db, next->key, ecore_config_get_int(b, next->key));
break;
case PT_FLT:
e_db_float_set(db, next->key, ecore_config_get_float(b, next->key));
break;
case PT_RGB:
e_db_str_set(db, next->key, ecore_config_get_rgbstr(b, next->key));
break;
case PT_STR:
e_db_str_set(db, next->key, ecore_config_get_string(b, next->key));
break;
}
next=next->next;
}
e_db_close(db);
return 1;
}

View File

@ -0,0 +1,22 @@
#ifndef ECORE_CONFIG_ERRORS_H
#define ECORE_CONFIG_ERRORS_H
# define ECORE_CONFIG_ERR_NOTSUPP (-16)
# define ECORE_CONFIG_ERR_NOFILE (-15)
# define ECORE_CONFIG_ERR_META_DLFAIL (-14)
# define ECORE_CONFIG_ERR_META_FILE (-13)
# define ECORE_CONFIG_ERR_META_FORMAT (-12)
# define ECORE_CONFIG_ERR_MONMIS (-11)
# define ECORE_CONFIG_ERR_NOEXEC (-10)
# define ECORE_CONFIG_ERR_PARTIAL (-9)
# define ECORE_CONFIG_ERR_PATHEX (-8)
# define ECORE_CONFIG_ERR_TYPEMISMATCH (-7)
# define ECORE_CONFIG_ERR_MUTEX (-6)
# define ECORE_CONFIG_ERR_NOTFOUND (-5)
# define ECORE_CONFIG_ERR_OOM (-4)
# define ECORE_CONFIG_ERR_IGNORED (-3)
# define ECORE_CONFIG_ERR_NODATA (-2)
# define ECORE_CONFIG_ERR_FAIL (-1)
# define ECORE_CONFIG_ERR_SUCC (0)
#endif

View File

@ -0,0 +1,32 @@
#include <Ecore_Ipc.h>
#include "Ecore_Config.h"
typedef enum {
IPC_NONE,
IPC_PROP_LIST,
IPC_PROP_DESC,
IPC_PROP_GET,
IPC_PROP_SET,
IPC_BUNDLE_LIST,
IPC_BUNDLE_NEW,
IPC_BUNDLE_LABEL_GET,
IPC_BUNDLE_LABEL_SET,
IPC_BUNDLE_LABEL_FIND,
IPC_LAST
} ex_ipc_call;
Ecore_Config_Server *srv2ecore_config_srv(void *srv);
char *ipc_prop_list(Ecore_Config_Server *srv, const long serial);
char *ipc_prop_desc(Ecore_Config_Server *srv, const long serial,const char *key);
char *ipc_prop_get(Ecore_Config_Server *srv, const long serial,const char *key);
int ipc_prop_set(Ecore_Config_Server *srv, const long serial,const char *key,const char *val);
char *ipc_bundle_list(Ecore_Config_Server *srv);
int ipc_bundle_new(Ecore_Config_Server *srv, const char *);
char *ipc_bundle_label_get(Ecore_Config_Server *srv, const long);
int ipc_bundle_label_set(Ecore_Config_Server *srv, const long,const char *);
long ipc_bundle_label_find(Ecore_Config_Server *srv, const char *);

View File

@ -0,0 +1,257 @@
/* by Azundris, with thanks to Corey Donohoe <atmos@atmos.org> */
//#include "config.h"
#include "errors.h"
#include "debug.h"
#include "ipc.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include <Ecore.h>
#include <Ecore_Ipc.h>
#include "Ecore_Config.h"
/*****************************************************************************/
static int get_string(char **m,char **r) {
char *q;
int l=0;
if(!m||!*m)
return ECORE_CONFIG_ERR_NODATA;
if(!r)
return ECORE_CONFIG_ERR_FAIL;
q=*m;
if(*q!='s')
return ECORE_CONFIG_ERR_TYPEMISMATCH;
q++;
l=(*(q++))<<8;
l+=*(q++);
*r=q;
q+=l;
*m=q;
E(1,"IPC/eCore: got string-%d \"%s\"\n",l,*r);
return ECORE_CONFIG_ERR_SUCC; }
/*****************************************************************************/
static int send(Ecore_Ipc_Event_Client_Data *e,int code,char *reply) {
static int our_ref=0;
int len=reply?strlen(reply)+1:0;
our_ref++;
E(1,"IPC/eCore: replying [0,0] %d IRT %d => %d {\"%s\":%d}\n",our_ref,e->ref,code,reply?reply:"",len);
return ecore_ipc_client_send(e->client,0,0,our_ref,e->ref,code,reply,len); }
/*****************************************************************************/
static int handle_request(Ecore_Ipc_Server *server,Ecore_Ipc_Event_Client_Data *e) {
Ecore_Config_Server *srv;
long serial=e->minor;
int ret=ECORE_CONFIG_ERR_FAIL;
char *r=NULL,*k,*v,*m=(char *)e->data;
srv=srv2ecore_config_srv(server);
E(1,"IPC/eCore: client sent: [%d,%d] #%d (%d) @ %p\n",e->major,e->minor,e->ref,e->size,server);
switch(e->major) {
case IPC_PROP_LIST:
r=ipc_prop_list(srv, serial);
break;
case IPC_PROP_DESC:
if(get_string(&m,&k)==ECORE_CONFIG_ERR_SUCC)
r=ipc_prop_desc(srv, serial,k);
break;
case IPC_PROP_GET:
if(get_string(&m,&k)==ECORE_CONFIG_ERR_SUCC)
r=ipc_prop_get(srv, serial,k);
break;
case IPC_PROP_SET:
if(get_string(&m,&k)==ECORE_CONFIG_ERR_SUCC) {
if(get_string(&m,&v)==ECORE_CONFIG_ERR_SUCC)
return send(e,ipc_prop_set(srv, serial,k,v),NULL); }
break;
case IPC_BUNDLE_LIST:
r=ipc_bundle_list(srv);
break;
case IPC_BUNDLE_NEW:
if(get_string(&m,&k)==ECORE_CONFIG_ERR_SUCC)
return send(e,k?ipc_bundle_new(srv, k):ECORE_CONFIG_ERR_FAIL,NULL);
break;
case IPC_BUNDLE_LABEL_SET:
if(get_string(&m,&k)==ECORE_CONFIG_ERR_SUCC)
return send(e,k?ipc_bundle_label_set(srv, serial,k):ECORE_CONFIG_ERR_FAIL,NULL);
break;
case IPC_BUNDLE_LABEL_FIND:
if(get_string(&m,&k)==ECORE_CONFIG_ERR_SUCC)
return send(e,ipc_bundle_label_find(srv, k),NULL);
break;
case IPC_BUNDLE_LABEL_GET:
r=ipc_bundle_label_get(srv, serial);
break; }
ret=send(e,r?ECORE_CONFIG_ERR_SUCC:ECORE_CONFIG_ERR_FAIL,r);
if(r) {
free(r);
return ret; }
return ECORE_CONFIG_ERR_NOTFOUND; }
/*****************************************************************************/
static int ipc_client_add(void *data,int type,void *event) {
Ecore_Ipc_Server **server=(Ecore_Ipc_Server **)data;
Ecore_Ipc_Event_Client_Data *e=(Ecore_Ipc_Event_Client_Data *)event;
if (*server != ecore_ipc_client_server_get(e->client))
return 1;
E(1,"IPC/eCore: Client connected. @ %p\n",server);
return 1; }
static int ipc_client_del(void *data, int type, void *event) {
Ecore_Ipc_Server **server=(Ecore_Ipc_Server **)data;
Ecore_Ipc_Event_Client_Data *e=(Ecore_Ipc_Event_Client_Data *)event;
if (*server != ecore_ipc_client_server_get(e->client))
return 1;
E(1,"IPC/eCore: Client disconnected. @ %p\n",server);
return 1; }
static int ipc_client_sent(void *data,int type,void *event) {
Ecore_Ipc_Server **server=(Ecore_Ipc_Server **)data;
Ecore_Ipc_Event_Client_Data *e=(Ecore_Ipc_Event_Client_Data *)event;
if (*server != ecore_ipc_client_server_get(e->client))
return 1;
handle_request(*server,e);
return 1; }
/*****************************************************************************/
int ipc_init(char *pipe_name, void **data) {
Ecore_Ipc_Server **server=(Ecore_Ipc_Server **)data;
struct stat st;
char *p;
int port=0;
char *str;
if(!server)
return ECORE_CONFIG_ERR_FAIL;
// if(*server)
// return ECORE_CONFIG_ERR_IGNORED;
ecore_init();
if(ecore_ipc_init()<1)
return ECORE_CONFIG_ERR_FAIL;
if((p=getenv("HOME"))) { /* debug-only ### FIXME */
char buf[PATH_MAX];
str=malloc(1000*sizeof(char));
int stale=1;
while (stale) {
sprintf(str,"%s/.ecore/%s/%d",p,pipe_name,port);
snprintf(buf,PATH_MAX,str);
if(!stat(buf,&st)) {
E(0,"IPC/eCore: pipe \"%s\" already exists!?\n",buf);
// if(unlink(buf))
// E(0,"IPC/eCore: could not remove pipe \"%s\": %d\n",buf,errno); }}
port++;
} else {
stale = 0;
}
}
}
*server=ecore_ipc_server_add(ECORE_IPC_LOCAL_USER,pipe_name,port,NULL);
ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD, ipc_client_add, server);
ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, ipc_client_del, server);
ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA,ipc_client_sent,server);
sprintf(str,"IPC/eCore: Server is listening on %s.\n", pipe_name);
E(1,str);
return ECORE_CONFIG_ERR_SUCC; }
int ipc_exit(void **data) {
int ret=ECORE_CONFIG_ERR_SUCC;
Ecore_Ipc_Server **server=(Ecore_Ipc_Server **)data;
if(!server)
return ECORE_CONFIG_ERR_FAIL;
if(*server) {
ecore_ipc_server_del(*server);
*server=NULL; }
ecore_ipc_shutdown();
return ret; }
/*****************************************************************************/
int ipc_poll(void **data) {
Ecore_Ipc_Server **server=(Ecore_Ipc_Server **)data;
if(!server)
return ECORE_CONFIG_ERR_FAIL;
ecore_main_loop_iterate();
return ECORE_CONFIG_ERR_SUCC; }
/*****************************************************************************/

View File

@ -0,0 +1,309 @@
/* ############## bad */
#define HAVE_EVAS2
#include "Ecore_Config.h"
#include "util.h"
#include "ipc.h"
#include "errors.h"
#include "config.h"
#include <signal.h>
#include <dlfcn.h>
#include <stdio.h>
#include <glob.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h> /* malloc(), free() */
#ifndef TRUE
# define FALSE 0
# define TRUE (!FALSE)
#endif
typedef struct _ipc {
void *lib;
void *data;
int (*ipc_init)(char *pipe_name,void **data);
int (*ipc_exit)(void **data);
int (*ipc_poll)(void **data);
struct _ipc *next;
} ipc;
static ipc *ipc_modules=NULL;
static ulong ipc_timer=0L;
Ecore_Config_Server *srv2ecore_config_srv(void *srv) {
ipc *ipc_tmp;
Ecore_Config_Server *srv_tmp;
ipc_tmp = ipc_modules;
while (ipc_tmp) {
srv_tmp = ipc_tmp->data;
while (srv_tmp) {
if (srv_tmp->server == srv)
return srv_tmp;
srv_tmp=srv_tmp->next;
}
ipc_tmp = ipc_tmp->next;
}
return NULL;
}
/*****************************************************************************/
/* INTERFACE FOR IPC MODULES */
/*****************************/
char *ipc_prop_list(Ecore_Config_Server *srv, const long serial) {
Ecore_Config_Bundle *theme=ecore_config_bundle_get_by_serial(srv, serial);
Ecore_Config_Prop *e=theme?theme->data:NULL;
estring *s=estring_new(8192);
int f=0;
while(e) {
estring_appendf(s,"%s%s: %s",f?"\n":"",e->key,ecore_config_get_type(e));
if(e->flags&PF_BOUNDS)
estring_appendf(s,", range %d..%d",e->lo,e->hi);
f=1;
e=e->next; }
return estring_disown(s); }
char *ipc_prop_desc(Ecore_Config_Server *srv, const long serial,const char *key) {
#ifdef HAVE_EVAS2
Ecore_Config_Bundle *theme=ecore_config_bundle_get_by_serial(srv, serial);
Ecore_Config_Prop *e=ecore_config_get(theme,key);
if(e) {
estring *s=estring_new(512);
estring_appendf(s,"%s: %s",e->key,ecore_config_get_type(e));
if(e->flags&PF_BOUNDS)
estring_appendf(s,", range %d..%d",e->lo,e->hi);
return estring_disown(s); }
#endif
return strdup("<undefined>"); }
char *ipc_prop_get(Ecore_Config_Server *srv, const long serial,const char *key) {
#ifdef HAVE_EVAS2
char *ret=NULL;
Ecore_Config_Bundle *theme=ecore_config_bundle_get_by_serial(srv, serial);
if((ret=ecore_config_get_as_string(theme,key)))
return ret;
#endif
return strdup("<undefined>"); }
int ipc_prop_set(Ecore_Config_Server *srv, const long serial,const char *key,const char *val) {
#ifdef HAVE_EVAS2
int ret;
Ecore_Config_Bundle *theme=ecore_config_bundle_get_by_serial(srv, serial);
ret=ecore_config_set(theme,key,(char *)val);
E(1,"ipc.prop.set(%s->%s,\"%s\") => %d\n",theme->identifier,key,val,ret);
return ret;
#else
return ECORE_CONFIG_ERR_NOTSUPP;
#endif
}
/*****************************************************************************/
char *ipc_bundle_list(Ecore_Config_Server *srv) {
Ecore_Config_Bundle *ns=ecore_config_bundle_get_1st(srv);
estring *s=estring_new(8192);
int f=0;
if(!ns)
return strdup("<no_bundles_created>");
while(ns) {
estring_appendf(s,"%s%d: %s",f?"\n":"",ecore_config_bundle_get_serial(ns),ecore_config_bundle_get_label(ns));
f=1;
ns=ecore_config_bundle_get_next(ns); }
return estring_disown(s); }
int ipc_bundle_new(Ecore_Config_Server *srv, const char *label) {
//Ecore_Config_Bundle *ns=ecore_config_bundle_get_by_serial(srv, 0);
if (ecore_config_new_bundle(srv, label))
return ECORE_CONFIG_ERR_SUCC;
return ECORE_CONFIG_ERR_FAIL; }
char *ipc_bundle_label_get(Ecore_Config_Server *srv, const long serial) {
Ecore_Config_Bundle *ns=ecore_config_bundle_get_by_serial(srv, serial);
char *label=ecore_config_bundle_get_label(ns);
return strdup(label?label:"<no such bundle>"); }
int ipc_bundle_label_set(Ecore_Config_Server *srv, const long serial,const char *label) {
Ecore_Config_Bundle *ns=ecore_config_bundle_get_by_serial(srv, serial);
if (!(ns->identifier=malloc(sizeof(label))))
return ECORE_CONFIG_ERR_OOM;
memcpy(ns->identifier,label,sizeof(label));
return ECORE_CONFIG_ERR_SUCC; }
long ipc_bundle_label_find(Ecore_Config_Server *srv, const char *label) {
Ecore_Config_Bundle *ns=ecore_config_bundle_get_by_label(srv, label);
return ns?ecore_config_bundle_get_serial(ns):-1; }
static int ipc_poll(void *data) {
ipc *m=(ipc *)data;
Ecore_Config_Server *s;
while(m) {
s = m->data;
while (s) {
m->ipc_poll(&s->server);
s = s->next;
}
m=m->next; }
return TRUE; }
int ipc_exit(void) {
ipc *m;
Ecore_Config_Server *l;
if(ipc_timer)
timeout_remove(ipc_timer);
while(ipc_modules) {
m=ipc_modules;
ipc_modules=ipc_modules->next;
l=m->data;
while(l) {
m->ipc_exit(&l->server);
l=l->next;
}
free(m); }
return ECORE_CONFIG_ERR_IGNORED; }
Ecore_Config_Server *ipc_init(char *pipe_name) {
char buf[PATH_MAX];
glob_t globbuf;
int ret;
unsigned int c;
ipc *nm=NULL;
Ecore_Config_Server *list=NULL;
Ecore_Config_Server *ret_srv;
if (nm) {
list=(Ecore_Config_Server *)nm->data;
while (list) {
if (!strcmp(list->name, pipe_name))
return NULL;
list = list->next;
}
}
list=NULL;
if (ipc_modules) {
nm = ipc_modules;
while (nm) {
list=malloc(sizeof(Ecore_Config_Server));
memset(list, 0, sizeof(Ecore_Config_Server));
if((ret=nm->ipc_init(pipe_name,&list->server))!=ECORE_CONFIG_ERR_SUCC) {
E(2,"ipc_init: failed to register %s, code %d\n", pipe_name, ret);
break;
}
E(2,"ipc_init: registered \"%s\"...\n",pipe_name);
list->name=strdup(pipe_name);
list->next=nm->data;
nm->data=list;
if (ret_srv) ret_srv=list;
nm = nm->next;
}
return ret_srv;
}
if(((ret=snprintf(buf,PATH_MAX,PACKAGE_LIB_DIR "/ecore_config_ipc_*.so"))<0)||
(ret>=PATH_MAX))
return NULL;
glob(buf,0,NULL,&globbuf);
if(!globbuf.gl_pathc)
return NULL;
for(c=0;c<globbuf.gl_pathc;c++) {
if(!(nm=malloc(sizeof(ipc)))) {
ret=ECORE_CONFIG_ERR_OOM;
goto done; }
memset(nm,0,sizeof(ipc));
E(1,"ipc_init: checking \"%s\"...\n",globbuf.gl_pathv[c]);
ret=dlmulti("IPC-plugin",globbuf.gl_pathv[c],RTLD_NOW,&nm->lib,
"!ipc_init !ipc_exit !ipc_poll",
&nm->ipc_init,&nm->ipc_exit,&nm->ipc_poll);
if(ret==ECORE_CONFIG_ERR_NODATA)
E(0,"ipc_init: could not load \"%s\": %s...\n",globbuf.gl_pathv[c],dlerror());
else if(ret==ECORE_CONFIG_ERR_SUCC) {
list=malloc(sizeof(Ecore_Config_Server));
// memcpy(list, 0, sizeof(Ecore_Config_Server));
if((ret=nm->ipc_init(pipe_name,&list->server))!=ECORE_CONFIG_ERR_SUCC)
E(0,"ipc_init: could not initialize \"%s\": %d\n",globbuf.gl_pathv[c],ret);
else {
char *p=globbuf.gl_pathv[c];
if(DEBUG!=0) {
char *q=strrchr(p,DIR_DELIMITER);
if(q)
p=++q; }
E(0,"ipc_init: adding \"%s\"...\n",p);
E(2,"ipc_init: registered \"%s\"...\n",pipe_name);
list->name=strdup(pipe_name);
list->next=nm->data;
nm->data=list;
if (ret_srv) ret_srv=list;
nm->next=ipc_modules;
ipc_modules=nm; }}
if(ret!=ECORE_CONFIG_ERR_SUCC)
free(nm); }
done:
globfree(&globbuf);
if(ipc_modules) {
/* ### temporary evilness */
/* if((debug>0)||(getenv("USER")&&!strcmp(getenv("USER"),"aje"))) {
signal(SIGINT,SIG_DFL);
signal(SIGSEGV,SIG_DFL); } */
ipc_timer=timeout_add(100,ipc_poll,ipc_modules); }
return ret_srv; }
/*****************************************************************************/

View File

@ -0,0 +1,643 @@
/* azundris */
//#include "config.h"
//#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 "util.h"
//#include "evidence.h"
#include "errors.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; }
/*****************************************************************************/
ulong now(long delay) {
static struct timeval tv;
ulong 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 */
/**********/
ulong 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(ulong 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
/*****************************************************************************/

View File

@ -0,0 +1,60 @@
#define TIMER_STOP 0
#define TIMER_CONT 1
#include "debug.h"
typedef struct _estring {
char *str;
int alloc,used;
} estring;
typedef struct _eslist {
void *payload;
struct _eslist *next;
} eslist;
int parse_line(char *,char **,char **,char **,char **);
char *unit_size(char *size);
//ulong now(long delay);
void qsrt(void *a[],void *data,int lo,int hi,int (*compare)(const void *,const void *,const void *));
int dlmulti(char *name,char *file,int flag,void **libr,const char *fmt, ...);
typedef void (*hash_walker)(char *key,void *value,void *data);
void *hash_table_new( void (*freekey),void (*freeval));
void *hash_table_fetch( void *hashtable,char *key);
int hash_table_insert( void *hashtable,char *key,void *value);
int hash_table_replace(void *hashtable,char *key,void *value);
int hash_table_remove( void *hashtable,char *key);
int hash_table_dst( void *hashtable);
int hash_table_walk( void *hashtable,hash_walker fun,void *data);
int eslist_free(eslist **);
int eslist_next(eslist **);
#define ESLIST_NEXT(e) (e=e->next)
void *eslist_payload(eslist **);
#define ESLIST_PAYLOAD(e) ((e)->payload)
int eslist_prepend(eslist **,void *);
int eslist_append(eslist **,void *);
estring *estring_new(int size);
estring *estring_dst(estring *e);
char *estring_disown(estring *e);
char *estring_free(estring *e,int release_payload); /* glib compat */
int estring_printf(estring *e,char *fmt, ...);
int estring_appendf(estring *e,char *fmt, ...);
int estring_truncate(estring *e,int size);
#define ESTRING_GET_CSTRING(a) ((a)->str)
int esprintf(char **result,char *fmt, ...);
int ejoin(char **result,char *delim, ...);
int ecat(char **result, ...);
//ulong timeout_add(uint f,int(*fun)(void *),void *data);
//int timeout_remove(ulong handle);