chiark / gitweb /
new gui-plan compiles again, still does not work in client mode
authorian <ian>
Tue, 27 May 2008 19:34:19 +0000 (19:34 +0000)
committerian <ian>
Tue, 27 May 2008 19:34:19 +0000 (19:34 +0000)
hostside/Makefile
hostside/common.h
hostside/gui-plan.c

index e31dca65fe21c2564db1f0a3596c9b80ab9e18b0..eff205b60b5df54ee7489365d606aa2d680a65f6 100644 (file)
@@ -47,7 +47,7 @@ realtime:     $(REALTIME_CORE_OBJS)                           \
 proto-expanded:        ../cebpic/README.protocol
                expand <$< $o
 
-gui-plan-bot: gui-plan-%: gui-plan.o utils.o parseutils.o \
+gui-plan-bot: gui-plan-%: gui-plan.o utils.o parseutils.o obc.o \
                 ../layout/ours.dgram-%.plandata.o \
                 __oop-read-copy.o -loop
                $(LINK) -L/usr/X11R6/lib -lXpm -lX11
index c6f95e1e26798761f736fb9041c4dca31c959bbe..5c4208c91753cc71f4f0c3b4b93f6cc6390a1dd2 100644 (file)
@@ -127,6 +127,7 @@ void real_mgettimeofday(struct timeval *tv);
 
 void mrename(const char *old, const char *new);
 void mwaitpid(pid_t child, const char *what);
+void mflushstdout(void);
 
 void badusage(const char *why) __attribute__((noreturn));
 
index 2725e2a3b94e061813fa78010f5f92fd38090600..468dcc7860b7b09186fbf5eaaa811ab77b6f34ca 100644 (file)
@@ -11,6 +11,7 @@
 #include <assert.h>
 #include <string.h>
 #include <errno.h>
+#include <stdarg.h>
 
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -21,7 +22,7 @@
 
 typedef int ErrorCode;
 
-#include "common.h"
+#include "daemons.h"
 #include "../layout/plan-data-format.h"
 
 #include <oop.h>
@@ -52,7 +53,13 @@ struct SegmovfeatState {
 oop_source *events;
 const char *progname= "gui-plan";
 
-static SegmovfeatState **state, *states_head;
+typedef struct {
+  SegmovfeatState *mfs;
+  unsigned inverted:1, updated:1;
+} SegState;
+
+static SegState *state;
+static SegmovfeatState *states_head;
 static Display *d;
 static oop_source_sys *sys_events;
 static Window w=None;
@@ -280,22 +287,22 @@ static void *input_iferr(oop_source *evts, oop_read *stdin_read,
                          const char *data, size_t recsz, void *is_v) {
   const InputStream *is= is_v;
   const char *emsg;
-  emsg= oop_rd_errmsg(stdin_read, evt, errnoval, OOP_RD_STYLE_GETLINE)
+  emsg= oop_rd_errmsg(stdin_read, evt, errnoval, OOP_RD_STYLE_GETLINE);
   die("%s: %s", is->name, emsg);
 }
 
 static void *input_ifok(oop_source *evts, oop_read *cl_read,
                        oop_rd_event evt, const char *errmsg, int errnoval,
-                       const char *data, size_t recsz, void *cl_v) {
+                       const char *data, size_t recsz, void *is_v) {
   const InputStream *is= is_v;
   ParseState ps;
 
   if (evt == OOP_RD_EOF) {
     is->on_eof();
-    abort;
+    abort();
   }
   if (evt != OOP_RD_OK) {
-    input_iferr(evts,cl_read,evt,errmsg,errnoval,data,recsz,cl_v);
+    input_iferr(evts,cl_read,evt,errmsg,errnoval,data,recsz,is_v);
     return OOP_CONTINUE;
   }
 
@@ -314,7 +321,7 @@ static void *input_ifok(oop_source *evts, oop_read *cl_read,
 
 static void stdin_eof(void) { exit(0); }
 
-static void stdin_input_line() {
+static void stdin_input_line(ParseState *ps) {
   const char *slash, *movfeatname;
   int invert, det, trainown, segment_ix, movfeat_ix, lmovfeatname;
   long posn;
@@ -336,16 +343,16 @@ static void stdin_input_line() {
          (badcmd(ps,"unknown command"),-1));
   }
   ps_needword(ps);
-  slash= memchr(ps.thisword, '/', ps.lthisword);
+  slash= memchr(ps->thisword, '/', ps->lthisword);
   if (slash) {
     movfeatname= slash + 1;
-    lmovfeatname= (ps.thisword + ps.lthisword) - movfeatname;
-    ps.lthisword= slash - ps.thisword;
+    lmovfeatname= (ps->thisword + ps->lthisword) - movfeatname;
+    ps->lthisword= slash - ps->thisword;
   } else {
     movfeatname= 0;
     lmovfeatname= 0;
   }
-  segment_ix= lstrpdbsearch(ps.thisword, ps.lthisword,
+  segment_ix= lstrpdbsearch(ps->thisword, ps->lthisword,
                            "segment", ui_plan_data.segments,
                            ui_plan_data.n_segments, sizeof(*segment_d));
   segment_d= &ui_plan_data.segments[segment_ix];
@@ -355,7 +362,7 @@ static void stdin_input_line() {
                            segment_d->n_movfeats, sizeof(*movfeat_d));
   movfeat_d= &segment_d->movfeats[movfeat_ix];
 
-  if (ps.remain) {
+  if (ps->remain) {
     if (invert<0) badcmd(0,"off may not take movfeatpos");
     ps_neednumber(ps, &posn, 0, movfeat_d->n_posns-1, "movfeatpos");
   } else {
@@ -368,7 +375,7 @@ static void stdin_input_line() {
 
   ps_neednoargs(ps);
 
-  fs= &state[segment_ix][movfeat_ix];
+  fs= &state[segment_ix].mfs[movfeat_ix];
   fs->invert= invert;
   fs->det= det;
   fs->trainown= trainown;
@@ -376,14 +383,29 @@ static void stdin_input_line() {
 
   redraw(fs);
   xlib_process();
-
-  return OOP_CONTINUE;
 }
 
 static const InputStream stdin_is= { "stdin", stdin_eof, stdin_input_line };
 
 /*---------- multiplexer client ----------*/
 
+static OutBufferChain sock= { (char*)"multiplexer socket", -1 };
+
+static void sockvprintf(const char *fmt, va_list al)
+  __attribute__((format(printf,1,0)));
+static void sockprintf(const char *fmt, ...)
+  __attribute__((format(printf,1,2)));
+
+static void sockvprintf(const char *fmt, va_list al) {
+  ovprintf(&sock,fmt,al);
+}
+static void sockprintf(const char *fmt, ...) {
+  va_list al;
+  va_start(al,fmt);
+  sockvprintf(fmt,al);
+  va_end(al);
+}
+
 static int sock_clientconnect(const char *node, const char *service) {
   struct addrinfo *aires, *try, hints;
   char niaddrbuf[256], niportbuf[64];
@@ -429,24 +451,95 @@ static int sock_clientconnect(const char *node, const char *service) {
 
 static void sock_eof(void) { die("EOF on multiplexer connection"); }
 
-static void 
-
-static const char[]= {
-  { "?detect",             si_detect     },
-  { "?picio_out_polarity", si_polarity   },
-  { "?movpos_*_feat",      si_movpos     },
-  { "?stastate",           si_stastate   },
-  { "?picio_out_on",       si_pic_on     },
-  { "?picio_out_off",      si_pic_off    },
-  { "=connected",          si_connected  },
-  { "=permission",         0             },
+static void *sock_exception(oop_source *evts, int fd,
+                           oop_event evt, void *cmdi_v) {
+  die("multiplexer socket has exceptional condition");
+}
+
+/*---------- multiplexer protocol ----------*/
+
+static void si_detect(ParseState *ps) {
+}
+
+static void si_polarity(ParseState *ps) {
+}
+
+static void si_movpos(ParseState *ps) {
+}
+
+static void si_on(ParseState *ps) {
+}
+
+static void si_off(ParseState *ps) {
+}
+
+typedef struct MuxEventInfo MuxEventInfo;
+typedef void MuxEventFn(ParseState *ps);
+
+struct MuxEventInfo {
+  const char *prefix; /* 0: sentinel */
+  const char *remainpat; /* 0: no pattern in select needed */
+  MuxEventFn *fn; /* 0: just ignore matching messages */
+};
+static const MuxEventInfo muxeventinfos[];
+
+static void si_connected(ParseState *ps) {
+  const MuxEventInfo *mxi;
+  const char *p;
+  int c;
+  
+  sockprintf("select-replay");
+  for (mxi=muxeventinfos; mxi->prefix; mxi++) {
+    sockprintf(" ");
+    for (p=mxi->prefix; (c=*p); p++) {
+      switch (c) {
+      case ' ': c= '_';
+      }
+      sockprintf("%c",c);
+    }
+    sockprintf("%s",mxi->remainpat);
+  }
+  sockprintf("\n");
+}
+
+static void si_problem(ParseState *ps) {
+  die("multiplexer reports problem: %.*s\n",
+      (int)badcmdreport_recsz, badcmdreport_data);
+}
+
+static const MuxEventInfo muxeventinfos[]= {
+  { "?detect ", "",             si_detect     },
+  { "?picio out polarity", "",  si_polarity   },
+  { "?movpos ", "*_feat",       si_movpos     },
+  { "?enco pic on", "",         si_on         },
+  { "?enco pic off", "",        si_off        },
+  
+  { "=connected", "",           si_connected  },
+  { "=permission", "",          0             },
+
+  { "+executing", 0,            0             },
+  { "+ack * ok", 0,             0             },
+  { "+ack", 0,                  si_problem    },
+  { "+nak", 0,                  si_problem    },
+  { "=failed", 0,               si_problem    },
+  { "=denied", 0,               si_problem    },
   { 0 }
-}  
+};
 
-static void sock_input_line(ParseStatee *ps) {
-  if (thiswordstrcmp(ps,"=connected")) {
-    write sock ("select ?detect ?stastate ?picio_out_on ?picio_out_off"
-               " ?picio_out_polarity
+static void sock_input_line(ParseState *ps) {
+  const MuxEventInfo *mxi;
+  int l;
+  for (mxi=muxeventinfos; mxi->prefix; mxi++) {
+    l= strlen(mxi->prefix);
+    if (!memcmp(mxi->prefix, ps->remain, l))
+      goto found;
+  }
+  return;
+found:
+  if (!mxi->fn) return;
+  ps->remain += l;
+  if (*ps->remain==' ') ps->remain++;
+  mxi->fn(ps);
 }
 
 static const InputStream sock_is= {
@@ -462,7 +555,7 @@ int main(int argc, const char *const *argv) {
   const char *arg;
   XpmAttributes mattribs;
   XWindowAttributes wattribs;
-  int segment_ix, movfeat_ix, posn, invert, det, oor, sock=-1;
+  int segment_ix, movfeat_ix, posn, invert, det, oor;
   XGCValues gcv;
   XColor colour;
   SegmovfeatState *fs;
@@ -486,8 +579,10 @@ int main(int argc, const char *const *argv) {
       } else {
        service= STR(TRAINMX_PORT);
       }
-      sock= clientconnect(node,service);
-      if (sock<0) die("unable to connect to multiplexer");
+      sock.fd= sock_clientconnect(node,service);
+      if (sock.fd<0) die("unable to connect to multiplexer");
+      obc_init(&sock);
+      events->on_fd(events, sock.fd, OOP_EXCEPTION, sock_exception, 0);
       if (comma) *comma= ',';
     } else if (arg[0]=='-') {
       die("invalid option(s)");
@@ -527,8 +622,8 @@ int main(int argc, const char *const *argv) {
   for (segment_ix= 0, segment_d= ui_plan_data.segments;
        segment_ix < ui_plan_data.n_segments;
        segment_ix++, segment_d++) {
-    state[segment_ix]= fs=
-      mmalloc(sizeof(**state) * segment_d->n_movfeats);
+    state[segment_ix].mfs= fs=
+      mmalloc(sizeof(*state[segment_ix].mfs) * segment_d->n_movfeats);
     for (movfeat_ix= 0, movfeat_d= segment_d->movfeats;
         movfeat_ix < segment_d->n_movfeats;
         movfeat_ix++, movfeat_d++, fs++) {
@@ -579,18 +674,20 @@ int main(int argc, const char *const *argv) {
   rd= oop_rd_new_fd(events, 0, 0,0);
   if (!rd) diee("oop_rd_new_fd");
 
-  if (sock==-1)
+  if (sock.fd==-1) {
+    events->on_fd(events, 0, OOP_EXCEPTION, some_exception, 0);
+
     oor= oop_rd_read(rd, OOP_RD_STYLE_GETLINE, 1024,
-                    stdin_ifok, (void*)&stdin_is,
-                    stdin_iferr, (void*)&stdin_is);
-  else
+                    input_ifok, (void*)&stdin_is,
+                    input_iferr, (void*)&stdin_is);
+  } else {
     oor= oop_rd_read(rd, OOP_RD_STYLE_GETLINE, 1024,
-                    sock_ifok, (void*)&sock_is,
-                    sock_iferr, (void*)&sock_is);
+                    input_ifok, (void*)&sock_is,
+                    input_iferr, (void*)&sock_is);
+  }
 
   if (oor) diee("oop_rd_read");
 
-  events->on_fd(events, 0,                   OOP_EXCEPTION, some_exception, 0);
   events->on_fd(events, ConnectionNumber(d), OOP_READ,      xlib_readable,  0);
   events->on_fd(events, ConnectionNumber(d), OOP_EXCEPTION, some_exception, 0);