#include <string.h>
#include <stdarg.h>
-#include <oop.h>
-#include <oop-read.h>
-
#include "../layout/dlist.h"
#include "hostside.h"
+#include "auproto-pic.h"
-oop_source *events;
FILE *dump_stream= 0;
-
-typedef struct OutBuffer OutBuffer;
-struct OutBuffer {
- OutBuffer *back, *next;
- char *m;
- int l;
-};
-typedef struct OutBufferChain OutBufferChain;
-struct OutBufferChain {
- const char *what;
- int fd;
- int done_of_head;
- struct { OutBuffer *head, *tail; } obs;
-};
-static OutBufferChain stdin_ochain= { "stdin", 0 };
-static OutBufferChain serial_ochain= { "serial", -1 };
-
-static void *ochain_writeable(oop_source *evts, int fd,
- oop_event evt, void *ch_v) {
- OutBufferChain *ch= ch_v;
- OutBuffer *ob;
- int r;
-
- assert(fd == ch->fd);
- assert(evt == OOP_WRITE);
-
- for (;;) {
- ob= ch->obs.head;
- if (!ob) {
- events->cancel_fd(events, fd, OOP_WRITE);
- events->cancel_fd(events, fd, OOP_EXCEPTION);
- return OOP_CONTINUE;
- }
- if (ch->done_of_head == ob->l) {
- LIST_UNLINK(ch->obs, ob);
- free(ob);
- free(ob->m);
- ch->done_of_head= 0;
- continue;
- }
- r= write(ch->fd, ob->m + ch->done_of_head, ob->l - ch->done_of_head);
- if (r==-1) {
- if (errno==EINTR) continue;
- if (errno==EWOULDBLOCK) return OOP_CONTINUE;
- diee(ch->what);
- }
- assert(r>=0);
- ch->done_of_head += r;
- assert(ch->done_of_head <= ob->l);
- }
-}
-
-static void *ochain_exception(oop_source *evts, int fd,
- oop_event evt, void *ch_v) {
- OutBufferChain *ch= ch_v;
- die(ch->what);
-}
-
-static void ochain_addlink(OutBufferChain *ch, OutBuffer *ob) {
- if (!ch->obs.head) {
- events->on_fd(events, ch->fd, OOP_WRITE, ochain_writeable, ch);
- events->on_fd(events, ch->fd, OOP_EXCEPTION, ochain_exception, ch);
- }
- LIST_LINK_TAIL(ch->obs, ob);
-}
-
-static void ovprintf(const char *fmt, va_list al)
- __attribute__((format(printf,1,0)));
-static void ovprintf(const char *fmt, va_list al) {
- OutBuffer *ob;
-
- ob= malloc(sizeof(*ob)); if (!ob) diem();
- ob->l= vasprintf(&ob->m, fmt, al); if (ob->l <= 0) diem();
- ochain_addlink(&stdin_ochain, ob);
-}
-
-static void oprintf(const char *msg, ...) __attribute__((format(printf,1,2)));
-static void oprintf(const char *msg, ...) {
- va_list al;
- va_start(al,msg);
- ovprintf(msg,al);
- va_end(al);
-}
-
-static void badcmd(const char *how) {
- oprintf("error %s\n",how);
-}
-
-static void cmd_noop(ParseState *ps, const CmdInfo *ci) {
- oprintf("noop successful\n");
-}
-
-static const CmdInfo toplevel_cmds[]= {
-#if 0
- { "nmra-x", cmd_nmra_x },
- { "nmra-1", cmd_nmra_1 },
- { "xmit-x", cmd_xmit_x },
- { "xmit-1", cmd_xmit_1 },
- { "pic", cmd_pic },
- { "raw", cmd_raw },
-#endif
- { "noop", cmd_noop },
- { 0 }
-};
-
-static int ps_needword(ParseState *ps) {
- const char *space;
- if (!ps->remain) { badcmd("too few args"); return 0; }
- space= strchr(ps->remain, ' ');
- ps->thisword= ps->remain;
- if (space) {
- ps->lthisword= space - ps->thisword;
- ps->remain= space + 1;
- } else {
- ps->lthisword= strlen(ps->remain);
- ps->remain= 0;
- }
- return 1;
-}
-
-static const CmdInfo *ps_lookup(ParseState *ps, const CmdInfo *inf) {
- for (;
- inf->name;
- inf++)
- if (ps->lthisword == strlen(inf->name) &&
- !memcmp(ps->thisword, inf->name, ps->lthisword))
- return inf;
- return 0;
-}
-
-static const CmdInfo *ps_needword_lookup(ParseState *ps, const CmdInfo *infs) {
- if (!ps_needword(ps)) return 0;
- return ps_lookup(ps,infs);
-}
-
-static void *stdin_iferr(oop_source *evts, oop_read *stdin_read,
- oop_rd_event evt, const char *errmsg, int errnoval,
- const char *data, size_t recsz, void *u0)
- __attribute__((noreturn));
-static void *stdin_iferr(oop_source *evts, oop_read *stdin_read,
- oop_rd_event evt, const char *errmsg, int errnoval,
- const char *data, size_t recsz, void *u0) {
- fprintf(stderr,"stdin %s\n",
- oop_rd_errmsg(stdin_read, evt, errnoval, OOP_RD_STYLE_GETLINE));
- exit(4);
-}
-
-static void *stdin_ifok(oop_source *evts, oop_read *stdin_read,
- oop_rd_event evt, const char *errmsg, int errnoval,
- const char *data, size_t recsz, void *u0) {
- ParseState ps;
- const CmdInfo *ci;
-
- if (evt == OOP_RD_EOF)
- exit(0);
- if (evt != OOP_RD_OK)
- stdin_iferr(evts,stdin_read,evt,errmsg,errnoval,data,recsz,u0);
-
- ps.remain= data;
- ci= ps_needword_lookup(&ps, toplevel_cmds);
- if (!ci) { badcmd("unknown command"); return OOP_CONTINUE; }
- ci->fn(&ps,ci);
- return OOP_CONTINUE;
-}
-
-static void *serial_readable(oop_source *evts, int fd,
- oop_event evt, void *u0) {
- abort();
-}
-
-const char *device;
-
-int main(int argc, const char **argv) {
- oop_read *stdin_source;
- oop_source_sys *sys_events;
- int r;
-
- device= argv[1];
- if (!device) device= "/dev/ttyS0";
-
- serial_open(device);
- r= oop_fd_nonblock(serial_fd, 1); if (r) diee("nonblock(serial_fd,1)");
- serial_ochain.fd= serial_fd;
-
- sys_events= oop_sys_new(); if (!sys_events) diee("oop_sys_new");
- events= oop_sys_source(sys_events); assert(events);
-
- stdin_source= oop_rd_new_fd(events, 0, 0,0);
- if (!stdin_source) diee("oop_rd_new_fd(,0,,)");
- r= oop_rd_read(stdin_source, OOP_RD_STYLE_GETLINE, 1024,
- stdin_ifok, 0, stdin_iferr, 0);
- if (r) diee("oop_rd_read(stdin_source,...)");
-
- events->on_fd(events, serial_fd, OOP_READ, serial_readable, 0);
- oop_sys_run(sys_events);
- abort();
-}