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;
 }