chiark / gitweb /
hostside: more length for bavarian
[trains.git] / hostside / adhoc-test.c
1 /*
2  * simple test harness for now
3  * asserts on usage errors
4  * see README.adhoc-test for usage info
5  */
6
7 #include <stdio.h>
8 #include <string.h>
9 #include <assert.h>
10 #include <stdlib.h>
11 #include <limits.h>
12 #include <unistd.h>
13 #include <errno.h>
14
15 #include "common.h"
16
17 const char *progname= "adhoc-test";
18 static FILE *dump_stream= 0;
19
20 static int repeat_delay= -1, iterations= -1;
21 static const char *serial_port= "/dev/railway";
22
23 static Nmra buf;
24
25 void die_hook(void) { }
26 void die_vprintf_hook(const char *fmt, va_list al) { }
27
28 static void pahex(const char **argv) {
29   const char *data_string;
30   char hbuf[3], *ep;
31   int i, l;
32   Byte *c;
33
34   c= buf.d;
35
36   while ((data_string= *argv++)) {
37     l= strlen(data_string);
38     if (l&1) badusage("hex argument odd length");
39     l >>= 1;
40   
41     for (i=0; i<l; i++) {
42       if (c >= buf.d + sizeof(buf.d)) badusage("too much hex");
43
44       hbuf[0]= data_string[i*2];
45       hbuf[1]= data_string[i*2+1];
46       hbuf[2]= 0;
47       *c++= strtoul(hbuf,&ep,16); 
48       if (ep!=&hbuf[2]) badusage("bad hex in hex argument");
49     }
50   }
51   buf.l= c - buf.d;
52 }
53
54 struct NmraParseEncodeCaller {
55   const char *const *argv;
56 };
57
58 unsigned long nmra_argnumber(NmraParseEncodeCaller *pec, int argi) {
59   const char *arg;
60   char *ep;
61   unsigned long l;
62
63   arg= pec->argv[argi];
64   errno=0; l= strtoul(arg,&ep,0);
65   if (errno || *ep || ep==arg) badusage("bad numeric arg value");
66   return l;
67 }
68
69 void nmra_problem(NmraParseEncodeCaller *pec, const char *problem) {
70   badusage(problem);
71 }
72
73 static void dump(const char *what, const Byte *data, int length) {
74   if (!dump_stream) return;
75   fprintf(dump_stream,"%-25s %3d  ",what,length);
76   while (length>0) {
77     fprintf(dump_stream," %02x", *data);
78     data++;
79     length--;
80   }
81   fprintf(dump_stream,"\n");
82 }
83
84 static void xmit_command(void) {
85   dump("xmit_command", buf.d, buf.l);
86   serial_transmit_now(buf.d, buf.l);
87 }
88
89 static void xmit_nmra_raw(void) {
90   PicInsn pi;
91   
92   dump("xmit_nmra_raw", buf.d, buf.l);
93   nmra_encodeforpic(&buf, &pi);
94   serial_transmit_now(pi.d, pi.l);
95 }
96
97 static void xmit_nmra_bytes(void) {
98   int l;
99   l= buf.l;
100   nmra_addchecksum(&buf);
101   xmit_nmra_raw();
102   buf.l= l;
103 }
104
105 int main(int argc, const char **argv) {
106   void (*xmitter)(void);
107   const char *arg;
108
109   if (!*argv++) badusage("need argv[0]");
110   
111   while ((arg=*argv++) && *arg=='-') {
112     arg++;
113     switch (*arg++) {
114     case 's': serial_port=             arg;  break;
115     case 'i': iterations=         atoi(arg); break;
116     case 'f': serial_fudge_delay= atoi(arg); break;
117     case 'w': repeat_delay=       atoi(arg); break;
118     case 'd': dump_stream= stdout; goto noarg;
119     default: badusage("uknown option");
120     noarg: if (*arg) badusage("option with value where forbidden");
121     }
122   }
123
124   if (!arg) badusage("need arg");
125
126   #define BARE(f)                               \
127   if (!strcmp(arg,#f)) {                        \
128     pahex(argv);                                \
129     xmitter= xmit_##f;                          \
130   } else
131   BARE(command)
132   BARE(nmra_raw)
133   BARE(nmra_bytes)
134   #undef BARE
135   {
136     NmraParseEncodeCaller pec;
137     pec.argv= argv;
138     for (argc=0; argv[argc]; argc++);
139     nmra_parse_encode(&buf, arg, strlen(arg), argc, &pec);
140     xmitter= xmit_nmra_bytes;
141   }
142
143   serial_open(serial_port);
144
145   for (;;) {
146     xmitter();
147     
148     if (repeat_delay < 0) break;
149     if (iterations >= 0 && !iterations--) break;
150     if (repeat_delay > 0) usleep(repeat_delay);
151   }
152
153   return 0;
154 }