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 cb16b23be62ad9224ef8513b3269627c8df06d8f
parent 5fd5bf02537a90bd6dc85c6284aa8eeba45a1c91
Author: Tomas Hlavaty <tom@logand.com>
Date:   Sun, 16 Aug 2015 17:55:24 +0200

simplify io

Diffstat:
Mgi-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; }