commit cb16b23be62ad9224ef8513b3269627c8df06d8f
parent 5fd5bf02537a90bd6dc85c6284aa8eeba45a1c91
Author: Tomas Hlavaty <tom@logand.com>
Date: Sun, 16 Aug 2015 17:55:24 +0200
simplify io
Diffstat:
M | gi-server.c | | | 219 | ++++++++++++++++++++++++++++++++++++++----------------------------------------- |
1 file changed, 104 insertions(+), 115 deletions(-)
diff --git a/gi-server.c b/gi-server.c
@@ -4,138 +4,127 @@
#include <string.h>
#include <girepository.h>
-#define BLEN 4096
-#define MAXARG 100
+#define HSIZE (1024 * 1024)
-enum Error {
- LINE_TOO_LONG = 1,
-};
+static char heap[HSIZE];
+static char *top;
-static GIRepository *r;
-
-static void require(int argc, char* argv[]) {
- char* namespace = NULL;
- char* version = NULL;
- switch(argc) {
- case 2:
- version = argv[1];
- case 1:
- namespace = argv[0];
- break;
- default:
- printf("error calling require\n");
- return;
- };
- GError *e = NULL;
- g_irepository_require(r, namespace, version, 0, &e);
- if(e) printf("error calling require %s\n", e->message);
- else printf("ok\n");
+static void skip(void) {
+ int c;
+ while(isspace(c = getc(stdin)));
+ ungetc(c, stdin);
}
-static void find(int argc, char* argv[]) {
- char* namespace = NULL;
- char* name = NULL;
- switch(argc) {
- case 2:
- name = argv[1];
- namespace = argv[0];
- break;
- default:
- printf("error calling find\n");
- return;
+static char *token(void) {
+ skip();
+ char *z = top;
+ int c = getc(stdin);
+ if('"' == c) {
+ while('"' != (c = getc(stdin)) && EOF != c) {
+ if(EOF == c)
+ exit(1);
+ if('\\' == c) {
+ c = getc(stdin);
+ if(EOF == c)
+ exit(1);
+ }
+ *top++ = c;
+ }
+ *top++ = 0;
+ return z;
+ } else {
+ *top++ = c;
+ while(!isspace(c = getc(stdin)) && EOF != c)
+ *top++ = c;
+ *top++ = 0;
+ return !strcmp("null", z) ? (char *) NULL : z;
};
- GIBaseInfo *p = g_irepository_find_by_name(r, namespace, name);
- if(p) printf("ok %ld\n", (long) p);
- else printf("error calling find %s.%s\n", namespace, name);
}
-static void invoke(int argc, char* argv[]) {
- GIFunctionInfo* p = NULL;
- if(0 < argc && (p = (void*) atol(argv[0])));
- else {
- printf("error calling invoke\n");
- return;
- }
- argc--;
- GIArgument a[MAXARG];
- int i;
- for(i = 0; i < argc; i++) {
- a[i].v_pointer = argv[i];
- }
- GIArgument z;
- GError *e = NULL;
- if(g_function_info_invoke(p,
- (const GIArgument *) &a,
- argc,
- NULL,
- 0,
- &z,
- &e))
- printf("ok\n");
- else printf("error calling invoke %s\n", e->message);
-}
+static long integer(void) {return atol(token());}
+static void *pointer(void) {return (void *) integer();}
-static void unref(int argc, char* argv[]) {
- void* p = NULL;
- if(1 == argc && (p = (void*) atol(argv[0]))) {
- g_base_info_unref(p);
- printf("ok\n");
- }
- else printf("error calling unref\n");
+static void argument(GIArgument *z) {
+ 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;
}
-struct Command {
- char* name;
- void (*fn)(int argc, char* argv[]);
-};
-
int main(void) {
- r = g_irepository_get_default();
- line:
+ GIRepository *r = g_irepository_get_default();
for(;;) {
+ top = heap;
fflush(stdout);
- char b[BLEN];
- fgets(b, BLEN, stdin);
- int n = strlen(b);
- if(n < BLEN) {
- char* a[MAXARG];
- int i = 0, m = 0;
- while(i < n) {
- while(i < n && isspace(b[i])) i++;
- if(i < n) {
- if(MAXARG <= m) {
- printf("error too many agruments\n");
- goto line;
- }
- a[m] = &b[i];
- while(i < n && !isspace(b[i])) i++;
- b[i] = 0;
- i++;
- /* printf("A %d '%s'\n", m, a[m]); */
- m++;
- }
+ char *cmd = token();
+ if(!strcmp("find", cmd)) {
+ char* namespace = token();
+ char* name = token();
+ GIBaseInfo *p = g_irepository_find_by_name(r, namespace, name);
+ if(p) printf("ok %ld\n", (unsigned long) p);
+ else printf("error in find: %s.%s\n", namespace, name);
+ }
+ else if(!strcmp("invoke", cmd)) {
+ GIArgument z;
+ GError *e = NULL;
+ GICallableInfo *p = pointer();
+ int iargc = integer(); //g_callable_info_get_n_args (p);
+ int oargc = integer();
+ GIArgument iargv[iargc], oargv[oargc];
+ int i;
+ for(i = 0; i < iargc; i++) {
+ argument(&iargv[i]);
}
- a[m] = NULL;
- if(m <= 0) {
- printf("error missing command\n");
- goto line;
+ if(g_function_info_invoke(p,
+ 0 < iargv ? iargv : NULL, iargc,
+ 0 < oargc ? oargv : NULL, oargc,
+ &z, &e)) {
+ printf("ok %ld\n", (unsigned long) z.v_pointer);
}
- static struct Command commands[] = {
- {"r", require},
- {"f", find},
- {"i", invoke},
- {"u", unref},
- {NULL, NULL}
- };
- struct Command* c;
- for(c = commands; c->name; c++) {
- if(!strcmp(c->name, a[0])) {
- c->fn(m - 1, &a[1]);
- break;
- }
+ else printf("error in invoke: %s\n", e->message);
+ }
+ else if(!strcmp("require", cmd)) {
+ GError *e = NULL;
+ char *namespace = token();
+ char *version = token();
+ g_irepository_require(r, namespace, version, 0, &e);
+ if(e) printf("error in require: %s\n", e->message);
+ else printf("ok\n");
+ }
+ else if(!strcmp("unref", cmd)) {
+ g_base_info_unref(pointer());
+ printf("ok\n");
+ }
+ else if(!strcmp("type", cmd)) {
+ GIInfoType z = g_base_info_get_type(pointer());
+ printf("ok %d\n", z);
+ }
+ else if(!strcmp("method", cmd)) {
+ GIObjectInfo* ptr = pointer();
+ char* name = token();
+ GIBaseInfo *p = NULL;
+ for(; ptr; ptr = g_object_info_get_parent(ptr)) {
+ p = g_object_info_find_method(ptr, name);
+ if(p) break;
}
+ if(p) printf("ok %ld\n", (unsigned long) p);
+ else printf("error in method: %s\n", name);
+ }
+ else if(!strcmp("flags", cmd)) {
+ GIFunctionInfoFlags z = g_function_info_get_flags(pointer());
+ printf("ok %d\n", z);
+ }
+ else if(!strcmp("vfunc", cmd)) {
+ GIObjectInfo* ptr = pointer();
+ char* name = token();
+ GIBaseInfo *p = g_object_info_find_vfunc(ptr, name);
+ if(p) printf("ok %ld\n", (unsigned long) p);
+ else printf("error in vfunc: %s\n", name);
}
- else return LINE_TOO_LONG;
}
return 0;
}