gi-server

Unnamed repository; edit this file 'description' to name the repository.
git clone https://logand.com/git/gi-server.git/
Log | Files | Refs

commit 337da032e5745233816d9b2a66a547daf89ebdfa
parent 461bd53dec506671cffcc04f849021434265ecd7
Author: Tomas Hlavaty <tom@logand.com>
Date:   Sun, 16 Aug 2015 20:30:25 +0200

type aware iargv parsing

Diffstat:
Mgi-server.c | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 58 insertions(+), 10 deletions(-)

diff --git a/gi-server.c b/gi-server.c @@ -17,7 +17,9 @@ static void skip(void) { enum { OUT_OF_MEMORY = 1, - UNEXPECTED_EOF = 2 + UNEXPECTED_EOF = 2, + UNHANDLED_TYPE = 3, + UNHANDLED_CASE = 4 }; static void put(char c) { @@ -55,15 +57,48 @@ static char *token(void) { static long integer(void) {return atol(token());} static void *pointer(void) {return (void *) integer();} -static void argument(GIArgument *z) { +static void to_argument(GIArgument *z, GIArgInfo *ai, GITypeInfo ti) { memset(z, 0, sizeof(GIArgument)); char *t = token(); - if(!t) {z->v_pointer = NULL;} - else if(!strcmp("false", t)) {z->v_boolean = FALSE;} - else if(!strcmp("true", t)) {z->v_boolean = TRUE;} - else if(!strcmp("gpointer", t)) {z->v_pointer = pointer();} - else if(!strcmp("gint", t)) {z->v_int = integer();} - else z->v_pointer = t; + GITypeTag tag = g_type_info_get_tag(&ti); + switch(tag) { + case GI_TYPE_TAG_VOID: break; + case GI_TYPE_TAG_BOOLEAN: z->v_boolean = !!strcmp("false", t); break; + case GI_TYPE_TAG_INT8: z->v_int8 = atol(t); break; + case GI_TYPE_TAG_UINT8: z->v_uint8 = atol(t); break; + case GI_TYPE_TAG_INT16: z->v_int16 = atol(t); break; + case GI_TYPE_TAG_UINT16: z->v_uint16 = atol(t); break; + case GI_TYPE_TAG_INT32: z->v_int32 = atol(t); break; + case GI_TYPE_TAG_UINT32: z->v_uint32 = atol(t); break; + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + case GI_TYPE_TAG_FLOAT: + case GI_TYPE_TAG_DOUBLE: + fprintf(stderr, "unhandled type: %s %s\n", g_type_tag_to_string(tag), t); + fflush(stderr); + exit(UNHANDLED_TYPE); + break; + case GI_TYPE_TAG_GTYPE: z->v_pointer = (void *) atol(t); break; + case GI_TYPE_TAG_UTF8: z->v_string = t; break; + case GI_TYPE_TAG_FILENAME: + fprintf(stderr, "unhandled type: %s %s\n", g_type_tag_to_string(tag), t); + fflush(stderr); + exit(UNHANDLED_TYPE); + break; + case GI_TYPE_TAG_ARRAY: z->v_pointer = NULL; break; // TODO + case GI_TYPE_TAG_INTERFACE: z->v_pointer = (void *) atol(t); break; + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: + case GI_TYPE_TAG_GHASH: + case GI_TYPE_TAG_ERROR: + case GI_TYPE_TAG_UNICHAR: + fprintf(stderr, "unhandled type: %s %s\n", g_type_tag_to_string(tag), t); + fflush(stderr); + exit(UNHANDLED_TYPE); + break; + default: + exit(UNHANDLED_CASE); + } } int main(void) { @@ -97,8 +132,21 @@ int main(void) { if((f & GI_FUNCTION_IS_METHOD) && !(f & GI_FUNCTION_IS_CONSTRUCTOR)) iargc++; GIArgument iargv[iargc], oargv[oargc]; - for(i = 0; i < iargc; i++) { - argument(&iargv[i]); + int j = 0; + if((f & GI_FUNCTION_IS_METHOD) && !(f & GI_FUNCTION_IS_CONSTRUCTOR)) { + iargv[j].v_pointer = (void *) atol(token()); + j++; + } + for(i = 0; i < argc; i++) { + GIArgInfo *ai = g_callable_info_get_arg(p, i); + GIDirection d = g_arg_info_get_direction(ai); + if(GI_DIRECTION_INOUT == d || GI_DIRECTION_IN == d) { + GITypeInfo ti; + g_arg_info_load_type(ai, &ti); + to_argument(&iargv[j], ai, ti); + j++; + } + g_base_info_unref(ai); } if(g_function_info_invoke(p, 0 < iargv ? iargv : NULL, iargc,