commit 337da032e5745233816d9b2a66a547daf89ebdfa
parent 461bd53dec506671cffcc04f849021434265ecd7
Author: Tomas Hlavaty <tom@logand.com>
Date: Sun, 16 Aug 2015 20:30:25 +0200
type aware iargv parsing
Diffstat:
M | gi-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,