From: ian Date: Sun, 8 Aug 2004 20:22:03 +0000 (+0000) Subject: seems to work X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=30abaefd58d1c558439969a24860938a0d44e434;p=trains.git seems to work --- diff --git a/parport/.cvsignore b/parport/.cvsignore new file mode 100644 index 0000000..af0105d --- /dev/null +++ b/parport/.cvsignore @@ -0,0 +1 @@ +parport-ctl diff --git a/parport/Makefile b/parport/Makefile new file mode 100644 index 0000000..4be6f6a --- /dev/null +++ b/parport/Makefile @@ -0,0 +1,5 @@ +CFLAGS= -Wall -Wwrite-strings -Wpointer-arith \ + -Wnested-externs -Wmissing-prototypes -Wstrict-prototypes \ + -O2 + +targets: parport-ctl diff --git a/parport/parport-ctl.c b/parport/parport-ctl.c new file mode 100644 index 0000000..e368336 --- /dev/null +++ b/parport/parport-ctl.c @@ -0,0 +1,216 @@ +/**/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static const struct numvalinfo { + const char *name; + int num; +} ioctlinfos[] = { +#define A(x) { #x , PP##x }, + A(CLAIM) + A(EXCL) + A(RELEASE) + A(YIELD) + A(NEGOT) + A(SETMODE) + A(GETMODE) + A(GETTIME) + A(GETMODES) + A(SETFLAGS) + A(WCONTROL) + A(RCONTROL) + A(FCONTROL) + A(RSTATUS) + A(DATADIR) + A(WDATA) + A(RDATA) + A(CLRIRQ) + A(WCTLONIRQ) +#undef A + { 0 } +}; + +#define FIND(v, a, d) do{ \ + for ((v)= a; (v)->name && strcasecmp(arg,(v)->name); (v)++); \ + if (!(v)->name) badusage("unknown " d); \ + }while(0) + +static const struct numvalinfo modeinfos[] = { +#define A(x) { #x , IEEE1284_MODE_##x }, + A(COMPAT) + A(NIBBLE) + A(BYTE) + A(EPP) + A(ECP) +#undef A + { 0 } +}; + +static union parm { + int i; + struct timeval tv; + unsigned char uc; + struct ppdev_frob_struct fs; +} parm; + +static const struct typeinfo { + const char *name; + void (*parse)(const char *const **argv); + void (*print)(void); +} typeinfos[]; + +static const void badusage(const char *what) { + const struct typeinfo *ti; + const struct numvalinfo *ioi; + const char *p; + + fprintf(stderr,"bad usage: %s\n" + "usage: parport-ctl <&parport ioctl" + " [input-type [input-args ...] [output-type]]\n" + "ioctls:", what); + for (ioi= ioctlinfos; ioi->name; ioi++) { + fputc(' ',stderr); + for (p= ioi->name; *p; p++) + fputc(tolower((unsigned char)*p),stderr); + } + fprintf(stderr,"\ntypes:"); + for (ti= typeinfos; ti->name; ti++) + fprintf(stderr," %s",ti->name); + fputc('\n',stderr); + exit(126); +} + +static const char *pa_1arg(const char *const **argv) { + const char *arg= *(*argv)++; + if (!arg) badusage("input type needs a value"); + return arg; +} + +static long pa_int(const char *const **argv) { + const char *arg= pa_1arg(argv); + char *ep; + long l; + + l= strtol(arg,&ep,0); + if (ep==arg || *ep) badusage("syntactically incorrect numeric input value"); + return l; +} +static unsigned char pa_uc(const char *const **argv) { + long l= pa_int(argv); + if (l<-128 || l>255) badusage("input unsigned char out of range"); + return (unsigned long)l; +} + +static void parse_none(const char *const **argv) { } +static void parse_int(const char *const **argv) { + long l= pa_int(argv); + if (lINT_MAX) badusage("input int out of range"); + parm.i= l; +} +static void parse_uc(const char *const **argv) { + parm.uc= pa_uc(argv); +} +static void parse_ppdfs(const char *const **argv) { + parm.fs.mask= pa_uc(argv); + parm.fs.val= pa_uc(argv); +} +static void parse_get(const char *const **argv) { } +static void parse_mode(const char *const **argv) { + const char *arg= pa_1arg(argv); + const struct numvalinfo *mi; + FIND(mi, modeinfos, "mode name"); + parm.i= mi->num; +} + +static void print_none(void) { } +static void print_int(void) { printf("%d\n",parm.i); } +static void print_uc(void) { printf("0x%02x\n",parm.uc); } +static void print_hex(void) { + const unsigned char *p; + for (p= (void*)&parm; + p < (const unsigned char*)(&parm + 1); + p++) + printf("0x%02x",*p); + putchar('\n'); +} +static void print_mode(void) { + const struct numvalinfo *mi; + for (mi= modeinfos; mi->name && mi->num != parm.i; mi++); + if (mi->name) printf("%s\n",mi->name); + else printf("unknown mode 0x%x\n",parm.i); +} +static void print_dump(void) { + const struct typeinfo *ti; + for (ti= typeinfos; ti->name; ti++) { + if (!ti->print || ti->print==print_dump || ti->print==print_none) continue; + printf("%s\t", ti->name); + ti->print(); + } +} + +static const struct typeinfo typeinfos[] = { +#define T(x) { #x, parse_##x, print_##x }, +#define TI(x) { #x, parse_##x, 0 }, +#define TO(x) { #x, 0, print_##x }, + T(none) + T(int) + T(uc) + T(mode) + TI(ppdfs) + TI(get) + TO(hex) + TO(dump) + { 0 } +}; + +#define FINDT(v, d, n) do { \ + FIND((v), typeinfos, "type for " d); \ + if (!(v)->n) badusage("unsupported type for " d); \ + }while(0) + +int main(int argc, const char *const *argv) { + const struct numvalinfo *ioi; + const struct typeinfo *iti, *oti; + const char *arg; + int r; + + if (!*argv++) badusage("need argv[0]"); + if (!(arg= *argv++)) badusage("need ioctl name"); + if (arg[0] == '-') badusage("no options supported"); + FIND(ioi, ioctlinfos, "ioctl name"); + + memset(&parm,0,sizeof(parm)); + if ((arg= *argv)) { + argv++; + FINDT(iti, "input to ioctl", parse); + iti->parse(&argv); + } + if ((arg= *argv)) { + argv++; + FINDT(oti, "type for output from ioctl", print); + } else { + oti= 0; + } + if (*argv) badusage("too many args"); + + r= ioctl(0, ioi->num, &parm); + if (r<0) { perror("parport-ctl: ioctl failed"); exit(-1); } + if (r>0) { fprintf(stderr,"parport-ctl: ioctl gave %d!\n",r); } + + if (oti) { + oti->print(); + if (ferror(stdout)) { perror("parport-ctl: write stdout"); exit(-1); } + } + + return r>125 ? 125 : r; +}