Look for calls and callbacks according to the mode
This commit is contained in:
parent
eb3fe28e7c
commit
c4e1784816
|
@ -90,6 +90,9 @@ struct _AppInterface
|
||||||
AppStatus * status;
|
AppStatus * status;
|
||||||
AppInterfaceCall * calls;
|
AppInterfaceCall * calls;
|
||||||
size_t calls_cnt;
|
size_t calls_cnt;
|
||||||
|
AppInterfaceCall * callbacks;
|
||||||
|
size_t callbacks_cnt;
|
||||||
|
/* XXX for hash_foreach() in _new_interface_do() */
|
||||||
int error;
|
int error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -226,51 +229,38 @@ static String * _new_interface(String const * app)
|
||||||
|
|
||||||
|
|
||||||
/* appinterface_new_interface */
|
/* appinterface_new_interface */
|
||||||
static int _new_interface_append(AppInterface * ai, VariableType type,
|
static AppInterfaceCall * _new_interface_append_call(AppInterface * ai,
|
||||||
char const * method);
|
VariableType type, char const * method);
|
||||||
static int _new_interface_append_arg(AppInterface * ai, char const * arg);
|
static AppInterfaceCall * _new_interface_append_callback(AppInterface * ai,
|
||||||
|
VariableType type, char const * method);
|
||||||
|
static int _new_interface_append_arg(AppInterfaceCall * call, char const * arg);
|
||||||
AppInterface * _new_interface_do(AppTransportMode mode, String const * app,
|
AppInterface * _new_interface_do(AppTransportMode mode, String const * app,
|
||||||
String const * pathname);
|
String const * pathname);
|
||||||
static int _new_interface_do_appstatus(AppInterface * appinterface);
|
static int _new_interface_do_appstatus(AppInterface * appinterface);
|
||||||
static int _new_interface_foreach(char const * key, Hash * value,
|
static int _new_interface_foreach_calls(char const * key, Hash * value,
|
||||||
AppInterface * appinterface);
|
AppInterface * appinterface);
|
||||||
|
static int _new_interface_foreach_callbacks(char const * key, Hash * value,
|
||||||
|
AppInterface * appinterface);
|
||||||
|
static AppInterface * _new_interface_mode_client(AppTransportMode mode,
|
||||||
|
String const * app, String const * pathname);
|
||||||
|
static AppInterface * _new_interface_mode_server(AppTransportMode mode,
|
||||||
|
String const * app, String const * pathname);
|
||||||
|
|
||||||
AppInterface * appinterface_new_interface(AppTransportMode mode,
|
AppInterface * appinterface_new_interface(AppTransportMode mode,
|
||||||
String const * app, String const * pathname)
|
String const * app, String const * pathname)
|
||||||
{
|
{
|
||||||
AppInterface * ai;
|
switch(mode)
|
||||||
Plugin * handle;
|
{
|
||||||
size_t i;
|
case ATM_CLIENT:
|
||||||
String * name;
|
return _new_interface_mode_client(mode, app, pathname);
|
||||||
|
case ATM_SERVER:
|
||||||
if((handle = plugin_new_self()) == NULL)
|
return _new_interface_mode_server(mode, app, pathname);
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
if((ai = _new_interface_do(mode, app, pathname)) == NULL)
|
|
||||||
return NULL;
|
|
||||||
for(i = 0; i < ai->calls_cnt; i++)
|
|
||||||
{
|
|
||||||
if((name = string_new_append(ai->name, "_", ai->calls[i].name,
|
|
||||||
NULL)) == NULL)
|
|
||||||
{
|
|
||||||
appinterface_delete(ai);
|
|
||||||
ai = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ai->calls[i].func = plugin_lookup(handle, name);
|
|
||||||
string_delete(name);
|
|
||||||
if(ai->calls[i].func == NULL)
|
|
||||||
{
|
|
||||||
appinterface_delete(ai);
|
|
||||||
ai = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
plugin_delete(handle);
|
|
||||||
return ai;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _new_interface_append(AppInterface * ai, VariableType type,
|
static AppInterfaceCall * _new_interface_append_call(AppInterface * ai,
|
||||||
char const * method)
|
VariableType type, char const * method)
|
||||||
{
|
{
|
||||||
AppInterfaceCall * p;
|
AppInterfaceCall * p;
|
||||||
|
|
||||||
|
@ -278,25 +268,47 @@ static int _new_interface_append(AppInterface * ai, VariableType type,
|
||||||
fprintf(stderr, "DEBUG: %s(%d, \"%s\")\n", __func__, type, method);
|
fprintf(stderr, "DEBUG: %s(%d, \"%s\")\n", __func__, type, method);
|
||||||
#endif
|
#endif
|
||||||
if((p = realloc(ai->calls, sizeof(*p) * (ai->calls_cnt + 1))) == NULL)
|
if((p = realloc(ai->calls, sizeof(*p) * (ai->calls_cnt + 1))) == NULL)
|
||||||
return -1;
|
return NULL;
|
||||||
ai->calls = p;
|
ai->calls = p;
|
||||||
p = &ai->calls[ai->calls_cnt];
|
p = &ai->calls[ai->calls_cnt];
|
||||||
if((p->name = string_new(method)) == NULL)
|
if((p->name = string_new(method)) == NULL)
|
||||||
return -1;
|
return NULL;
|
||||||
p->type.type = type & AICT_MASK;
|
p->type.type = type & AICT_MASK;
|
||||||
p->type.direction = type & AICD_MASK;
|
p->type.direction = type & AICD_MASK;
|
||||||
p->args = NULL;
|
p->args = NULL;
|
||||||
p->args_cnt = 0;
|
p->args_cnt = 0;
|
||||||
ai->calls_cnt++;
|
ai->calls_cnt++;
|
||||||
return 0;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _new_interface_append_arg(AppInterface * ai, char const * arg)
|
static AppInterfaceCall * _new_interface_append_callback(AppInterface * ai,
|
||||||
|
VariableType type, char const * method)
|
||||||
|
{
|
||||||
|
AppInterfaceCall * p;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s(%d, \"%s\")\n", __func__, type, method);
|
||||||
|
#endif
|
||||||
|
if((p = realloc(ai->callbacks, sizeof(*p) * (ai->callbacks_cnt + 1)))
|
||||||
|
== NULL)
|
||||||
|
return NULL;
|
||||||
|
ai->callbacks = p;
|
||||||
|
p = &ai->callbacks[ai->callbacks_cnt];
|
||||||
|
if((p->name = string_new(method)) == NULL)
|
||||||
|
return NULL;
|
||||||
|
p->type.type = type & AICT_MASK;
|
||||||
|
p->type.direction = type & AICD_MASK;
|
||||||
|
p->args = NULL;
|
||||||
|
p->args_cnt = 0;
|
||||||
|
ai->callbacks_cnt++;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _new_interface_append_arg(AppInterfaceCall * call, char const * arg)
|
||||||
{
|
{
|
||||||
char buf[16];
|
char buf[16];
|
||||||
char * p;
|
char * p;
|
||||||
int type;
|
int type;
|
||||||
AppInterfaceCall * q;
|
|
||||||
AppInterfaceCallArg * r;
|
AppInterfaceCallArg * r;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -307,11 +319,10 @@ static int _new_interface_append_arg(AppInterface * ai, char const * arg)
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
if((type = _string_enum(buf, _string_type)) < 0)
|
if((type = _string_enum(buf, _string_type)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
q = &ai->calls[ai->calls_cnt - 1];
|
if((r = realloc(call->args, sizeof(*r) * (call->args_cnt + 1))) == NULL)
|
||||||
if((r = realloc(q->args, sizeof(*r) * (q->args_cnt + 1))) == NULL)
|
|
||||||
return error_set_code(-errno, "%s", strerror(errno));
|
return error_set_code(-errno, "%s", strerror(errno));
|
||||||
q->args = r;
|
call->args = r;
|
||||||
r = &q->args[q->args_cnt++];
|
r = &call->args[call->args_cnt++];
|
||||||
r->type = type & AICT_MASK;
|
r->type = type & AICT_MASK;
|
||||||
r->direction = type & AICD_MASK;
|
r->direction = type & AICD_MASK;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -336,6 +347,8 @@ AppInterface * _new_interface_do(AppTransportMode mode, String const * app,
|
||||||
appinterface->status = NULL;
|
appinterface->status = NULL;
|
||||||
appinterface->calls = NULL;
|
appinterface->calls = NULL;
|
||||||
appinterface->calls_cnt = 0;
|
appinterface->calls_cnt = 0;
|
||||||
|
appinterface->callbacks = NULL;
|
||||||
|
appinterface->callbacks_cnt = 0;
|
||||||
appinterface->error = 0;
|
appinterface->error = 0;
|
||||||
if(appinterface->name == NULL
|
if(appinterface->name == NULL
|
||||||
|| appinterface->config == NULL
|
|| appinterface->config == NULL
|
||||||
|
@ -346,7 +359,11 @@ AppInterface * _new_interface_do(AppTransportMode mode, String const * app,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
appinterface->error = 0;
|
appinterface->error = 0;
|
||||||
hash_foreach(appinterface->config, (HashForeach)_new_interface_foreach,
|
hash_foreach(appinterface->config,
|
||||||
|
(HashForeach)_new_interface_foreach_calls,
|
||||||
|
appinterface);
|
||||||
|
hash_foreach(appinterface->config,
|
||||||
|
(HashForeach)_new_interface_foreach_callbacks,
|
||||||
appinterface);
|
appinterface);
|
||||||
if(appinterface->error != 0)
|
if(appinterface->error != 0)
|
||||||
{
|
{
|
||||||
|
@ -365,15 +382,15 @@ static int _new_interface_do_appstatus(AppInterface * appinterface)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _new_interface_foreach(char const * key, Hash * value,
|
static int _new_interface_foreach_callbacks(char const * key, Hash * value,
|
||||||
AppInterface * appinterface)
|
AppInterface * appinterface)
|
||||||
{
|
{
|
||||||
String const * prefix = (appinterface->mode == ATM_SERVER)
|
String const * prefix = APPINTERFACE_CALLBACK_PREFIX;
|
||||||
? APPINTERFACE_CALL_PREFIX : APPINTERFACE_CALLBACK_PREFIX;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
char buf[8];
|
char buf[8];
|
||||||
int type = VT_NULL;
|
int type = VT_NULL;
|
||||||
char const * p;
|
char const * p;
|
||||||
|
AppInterfaceCall * callback;
|
||||||
|
|
||||||
if(key == NULL || strncmp(prefix, key, string_length(prefix)) != 0)
|
if(key == NULL || strncmp(prefix, key, string_length(prefix)) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -381,13 +398,12 @@ static int _new_interface_foreach(char const * key, Hash * value,
|
||||||
if((p = hash_get(value, "ret")) != NULL
|
if((p = hash_get(value, "ret")) != NULL
|
||||||
&& (type = _string_enum(p, _string_type)) < 0)
|
&& (type = _string_enum(p, _string_type)) < 0)
|
||||||
{
|
{
|
||||||
appinterface->error = error_set_code(1, "%s: %s%s", p,
|
appinterface->error = error_set_code(1, "%s: %s", p,
|
||||||
"Invalid return type for ",
|
"Invalid return type for callback");
|
||||||
(appinterface->mode == ATM_SERVER)
|
|
||||||
? "call" : "callback");
|
|
||||||
return -appinterface->error;
|
return -appinterface->error;
|
||||||
}
|
}
|
||||||
if(_new_interface_append(appinterface, type, key) != 0)
|
if((callback = _new_interface_append_callback(appinterface, type, key))
|
||||||
|
== NULL)
|
||||||
{
|
{
|
||||||
appinterface->error = 1;
|
appinterface->error = 1;
|
||||||
return -appinterface->error;
|
return -appinterface->error;
|
||||||
|
@ -397,7 +413,7 @@ static int _new_interface_foreach(char const * key, Hash * value,
|
||||||
snprintf(buf, sizeof(buf), "arg%u", i + 1);
|
snprintf(buf, sizeof(buf), "arg%u", i + 1);
|
||||||
if((p = hash_get(value, buf)) == NULL)
|
if((p = hash_get(value, buf)) == NULL)
|
||||||
break;
|
break;
|
||||||
if(_new_interface_append_arg(appinterface, p) != 0)
|
if(_new_interface_append_arg(callback, p) != 0)
|
||||||
{
|
{
|
||||||
/* FIXME may crash here? */
|
/* FIXME may crash here? */
|
||||||
appinterface->error = 1;
|
appinterface->error = 1;
|
||||||
|
@ -407,6 +423,123 @@ static int _new_interface_foreach(char const * key, Hash * value,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _new_interface_foreach_calls(char const * key, Hash * value,
|
||||||
|
AppInterface * appinterface)
|
||||||
|
{
|
||||||
|
String const * prefix = APPINTERFACE_CALL_PREFIX;
|
||||||
|
unsigned int i;
|
||||||
|
char buf[8];
|
||||||
|
int type = VT_NULL;
|
||||||
|
char const * p;
|
||||||
|
AppInterfaceCall * call;
|
||||||
|
|
||||||
|
if(key == NULL || strncmp(prefix, key, string_length(prefix)) != 0)
|
||||||
|
return 0;
|
||||||
|
key += string_length(prefix);
|
||||||
|
if((p = hash_get(value, "ret")) != NULL
|
||||||
|
&& (type = _string_enum(p, _string_type)) < 0)
|
||||||
|
{
|
||||||
|
appinterface->error = error_set_code(1, "%s: %s", p,
|
||||||
|
"Invalid return type for call");
|
||||||
|
return -appinterface->error;
|
||||||
|
}
|
||||||
|
if((call = _new_interface_append_call(appinterface, type, key)) == NULL)
|
||||||
|
{
|
||||||
|
appinterface->error = 1;
|
||||||
|
return -appinterface->error;
|
||||||
|
}
|
||||||
|
for(i = 0; i < APPSERVER_MAX_ARGUMENTS; i++)
|
||||||
|
{
|
||||||
|
snprintf(buf, sizeof(buf), "arg%u", i + 1);
|
||||||
|
if((p = hash_get(value, buf)) == NULL)
|
||||||
|
break;
|
||||||
|
if(_new_interface_append_arg(call, p) != 0)
|
||||||
|
{
|
||||||
|
/* FIXME may crash here? */
|
||||||
|
appinterface->error = 1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppInterface * _new_interface_mode_client(AppTransportMode mode,
|
||||||
|
String const * app, String const * pathname)
|
||||||
|
{
|
||||||
|
AppInterface * ai;
|
||||||
|
Plugin * plugin;
|
||||||
|
size_t i;
|
||||||
|
String * name;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s(%u, \"%s\", \"%s\")\n", __func__, mode, app,
|
||||||
|
pathname);
|
||||||
|
#endif
|
||||||
|
if((plugin = plugin_new_self()) == NULL)
|
||||||
|
return NULL;
|
||||||
|
if((ai = _new_interface_do(mode, app, pathname)) == NULL)
|
||||||
|
{
|
||||||
|
plugin_delete(plugin);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for(i = 0; i < ai->callbacks_cnt; i++)
|
||||||
|
{
|
||||||
|
if((name = string_new_append(ai->name, "_",
|
||||||
|
ai->callbacks[i].name, NULL))
|
||||||
|
== NULL)
|
||||||
|
break;
|
||||||
|
ai->callbacks[i].func = plugin_lookup(plugin, name);
|
||||||
|
string_delete(name);
|
||||||
|
if(ai->callbacks[i].func == NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
plugin_delete(plugin);
|
||||||
|
if(i != ai->callbacks_cnt)
|
||||||
|
{
|
||||||
|
appinterface_delete(ai);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return ai;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppInterface * _new_interface_mode_server(AppTransportMode mode,
|
||||||
|
String const * app, String const * pathname)
|
||||||
|
{
|
||||||
|
AppInterface * ai;
|
||||||
|
Plugin * plugin;
|
||||||
|
size_t i;
|
||||||
|
String * name;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s(%u, \"%s\", \"%s\")\n", __func__, mode, app,
|
||||||
|
pathname);
|
||||||
|
#endif
|
||||||
|
if((plugin = plugin_new_self()) == NULL)
|
||||||
|
return NULL;
|
||||||
|
if((ai = _new_interface_do(mode, app, pathname)) == NULL)
|
||||||
|
{
|
||||||
|
plugin_delete(plugin);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for(i = 0; i < ai->calls_cnt; i++)
|
||||||
|
{
|
||||||
|
if((name = string_new_append(ai->name, "_", ai->calls[i].name,
|
||||||
|
NULL)) == NULL)
|
||||||
|
break;
|
||||||
|
ai->calls[i].func = plugin_lookup(plugin, name);
|
||||||
|
string_delete(name);
|
||||||
|
if(ai->calls[i].func == NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
plugin_delete(plugin);
|
||||||
|
if(i != ai->calls_cnt)
|
||||||
|
{
|
||||||
|
appinterface_delete(ai);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return ai;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* appinterface_delete */
|
/* appinterface_delete */
|
||||||
void appinterface_delete(AppInterface * appinterface)
|
void appinterface_delete(AppInterface * appinterface)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user