commit 2958db2ae9740d269c40353d945410bd94d9c3a0
Author: Tomas Hlavaty <tom@logand.com>
Date: Sat, 27 Jun 2015 01:20:41 +0200
initial commit
Diffstat:
4 files changed, 164 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1 @@
+*~
diff --git a/Makefile b/Makefile
@@ -0,0 +1,8 @@
+all: gi-server
+
+gi-server: gi-server.c
+ $(CC) -Wall -Os -o $@ $< `pkg-config --cflags --libs gobject-introspection-1.0`
+ strip $@
+
+clean:
+ rm -f gi-server
diff --git a/default.nix b/default.nix
@@ -0,0 +1,14 @@
+with import <nixpkgs> {}; {
+ giServerEnv = stdenv.mkDerivation {
+ name = "gi-server-env";
+ buildInputs = [
+ pkgs.pkgconfig
+ pkgs.gobjectIntrospection
+ ];
+ GI_TYPELIB_PATH =
+ "${gtk3}/lib/girepository-1.0"
+ + ":${pango}/lib/girepository-1.0"
+ + ":${gdk_pixbuf}/lib/girepository-1.0"
+ + ":${atk}/lib/girepository-1.0";
+ };
+}
diff --git a/gi-server.c b/gi-server.c
@@ -0,0 +1,141 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <girepository.h>
+
+#define BLEN 4096
+#define MAXARG 100
+
+enum Error {
+ LINE_TOO_LONG = 1,
+};
+
+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 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;
+ };
+ 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 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");
+}
+
+struct Command {
+ char* name;
+ void (*fn)(int argc, char* argv[]);
+};
+
+int main(void) {
+ r = g_irepository_get_default();
+ line:
+ for(;;) {
+ 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++;
+ }
+ }
+ a[m] = NULL;
+ if(m <= 0) {
+ printf("error missing command\n");
+ goto line;
+ }
+ 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 return LINE_TOO_LONG;
+ }
+ return 0;
+}