chiark / gitweb /
hostside: more length for bavarian
[trains.git] / hostside / common.h
1 /*
2  * declarations common to
3  *  - simple test program
4  *  - realtime daemon
5  *  - multiplexer daemon
6  */
7
8 #ifndef COMMON_H
9 #define COMMON_H
10
11 #include <stdio.h>
12 #include <errno.h>
13 #include <unistd.h>
14 #include <assert.h>
15 #include <stdint.h>
16 #include <stdarg.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <limits.h>
20 #include <stddef.h>
21 #include <ctype.h>
22 #include <math.h>
23
24 typedef struct ParseState ParseState;
25 typedef struct CmdInfo CmdInfo;
26 typedef struct Client Client;
27
28 extern const char *progname;
29
30 #define TRAINMX_PORT 2883
31
32 /*---------- types ----------*/
33
34 typedef unsigned char Byte;
35
36 #define COMMAND_ENCODED_MAX 16
37 #define NMRA_PACKET_MAX ((COMMAND_ENCODED_MAX*7 - 14) / 8)
38
39 typedef struct Nmra {
40   Byte d[NMRA_PACKET_MAX];
41   int l;
42 } Nmra;
43
44 typedef struct PicInsn {
45   Byte d[COMMAND_ENCODED_MAX];
46   int l;
47 } PicInsn;
48
49 /*---------- from parseutils.c ----------*/
50
51 struct ParseState {
52   const char *remain;
53   const char *thisword;
54   int lthisword;
55 };
56
57 int vbadcmd(ParseState *ps, const char *fmt, va_list al)
58   __attribute__((format(printf,2,0)));
59 int badcmd(ParseState *ps, const char *fmt, ...)
60   __attribute__((format(printf,2,3)));
61
62 int lstrstrcmp(const char *a, int la, const char *b);
63 int thiswordstrcmp(ParseState *ps, const char *b);
64
65 int ps_word(ParseState *ps); /* returns 0 or -1, does not log */
66 void ps_pushbackword(ParseState *ps);
67
68 /* All of these return 0 or the return value from vbadcmd: */
69 int ps_needword(ParseState *ps);
70 int ps_needhextoend(ParseState *ps, Byte *dbuf, int *len_io);
71 int ps_neednumber(ParseState *ps, long *r, long min,
72                         long max, const char *wh);
73 int ps_neednoargs(ParseState *ps);
74
75 #define MUSTECR(something) do{          \
76     int mustecr__ec= (something);       \
77     if (mustecr__ec) return mustecr__ec;        \
78   }while(0)
79   
80
81 /*---------- macro for table lookups, with help from parseutils.c ----------*/
82
83 #define some_lookup_counted(ps, infos, ninfos)                  \
84   ((const typeof(infos[0])*)                                    \
85    any_lookup((ps),(infos),(ninfos),sizeof((infos)[0])))
86
87 #define some_lookup(ps, infos)                  \
88   (some_lookup_counted((ps),(infos),INT_MAX))
89
90 #define some_needword_lookup_counted(ps, infos, ninfos, what)             \
91   ((const typeof(infos[0])*)                                              \
92    any_needword_lookup((ps),(infos),(ninfos),sizeof((infos)[0]),(what)))
93
94 #define some_needword_lookup(ps, infos, what)                   \
95   (some_needword_lookup_counted((ps),(infos),INT_MAX,(what)))
96
97 const void *any_lookup(ParseState *ps,
98                        const void *infos, int ninfsmax, size_t infosz);
99 const void *any_needword_lookup(ParseState *ps, const void *infos,
100                                 int ninfsmax, size_t sz, const char *what);
101
102 /*---------- from client.c ----------*/
103
104 struct CmdInfo {
105   const char *name;
106   int (*fn)(ParseState *ps, const CmdInfo *ci);
107     /* return values:
108      *   0: ok
109      *   return value from badcmd
110      *   some other error to report (if mainloop is expecting it)
111      */
112   int xarg;
113 };
114
115 void stdin_client(void);
116
117 extern const CmdInfo toplevel_cmds[]; /* defined in commands.c*/
118
119 /*---------- from utils.c ----------*/
120
121 void vdie(const char *fmt, int ev, va_list al)
122      __attribute__((noreturn,format(printf,1,0)));
123 void die(const char *fmt, ...) __attribute__((noreturn,format(printf,1,2)));
124 void diee(const char *fmt, ...) __attribute__((noreturn,format(printf,1,2)));
125 void diem(void) __attribute__((noreturn));
126
127 void die_hook(void);
128 void die_vprintf_hook(const char *fmt, va_list al)
129      __attribute__((format(printf,1,0)));
130
131 void *mmalloc(size_t sz);
132 void *mrealloc(void *old, size_t sz);
133 char *mstrdupl(const char *s, int l);
134 char *mstrdup(const char *s);
135 void real_mgettimeofday(struct timeval *tv);
136
137 void mrename(const char *old, const char *new);
138 void mwaitpid(pid_t child, const char *what);
139 void mflushstdout(void);
140
141 void badusage(const char *why) __attribute__((noreturn));
142 void dumphex(FILE *f, const void *pu, int l); /* caller must check ferror */
143
144 #define massert(x) ((x) ? (void)0 : diem())
145
146 /*---------- from serialio.c ----------*/
147
148 void serial_open(const char *device);
149 void serial_transmit_now(const Byte *command, int length);
150
151 extern int serial_fd, serial_fudge_delay;
152
153 /*---------- nmra parsing, nmra.c et al ----------*/
154
155 typedef struct NmraParseEncodeCaller NmraParseEncodeCaller;
156 void nmra_parse_encode(Nmra *out, const char *arg, int argl,
157                        int argc, NmraParseEncodeCaller *pec);
158   /* will call back to these, supplied by caller: */
159   unsigned long nmra_argnumber(NmraParseEncodeCaller *pec, int argi);
160   void nmra_problem(NmraParseEncodeCaller *pec, const char *problem);
161
162 void nmra_addchecksum(Nmra *packet);
163 void nmra_encodeforpic(const Nmra *packet, PicInsn *pi_out);
164
165
166 #define ARRAY_SIZE(a) (sizeof((a))/sizeof(*(a)))
167 #define ARRAY_END(a) ((a) + ARRAY_SIZE((a)))
168 #define CTYPE(isfoobar,ch) (isfoobar((unsigned char)(ch)))
169 #define COMMA ,
170
171 #define MAX(a_,b_) ({ typeof(a_) a=(a_); typeof(b_) b=(b_); a >= b ? a : b; })
172 #define MIN(a_,b_) ({ typeof(a_) a=(a_); typeof(b_) b=(b_); a <= b ? a : b; })
173 #define ENSURE(var,rel,value_) do{              \
174     typeof(value_) value= (value_);             \
175     if ((var) rel value) ; else (var)= value;   \
176   }while(0)
177
178 #define STR2(x) #x
179 #define STR(x) STR2(x)
180
181 #endif /*COMMON_H*/