chiark / gitweb /
hostside: hidrawconv: factor out most of the reporter functions' bodies into macros
[trains.git] / hostside / hidrawconv.c
index 3321ccf701aa517a1a475b27db361d56fd971e62..9a298b5e866c46c2511f2d874e51bdd3b59567d7 100644 (file)
@@ -20,31 +20,64 @@ void die_hook(void) { }
 
 static LastReports lasts;
 
-void reportbits(const uint8_t msg[], const uint8_t last[],
-               int len, const KeyBit *bit) {
-  for (; bit->str; bit++) {
-    if (bit->pos >= len) continue;
-    uint8_t m= msg[bit->pos] & bit->mask;
-    uint8_t l= last[bit->pos] & bit->mask;
-    if (m==l) continue;
-    printf("%s %d\n", bit->str, !!m);
+
+/*---------- helpful macros for reporter functions ----------*/
+
+/*
+ * These expect/define:
+ *
+ *   const uint8_t msg[], last[];
+ *   int len;
+ *   const EntType *ent;
+ *   uint8_t mb, lb;  // bits from the message, masked but unshifted
+ *
+ *   typedef struct {
+ *     const char *str;
+ *     uint8_t mask;
+ *     int pos;
+ *   } EntType;
+ */
+
+#define FOR_REPORTENTRIES(ent)                 \
+  /* Like for(;;) */                           \
+  for (; (ent)->str; (ent)++)                  \
+    if ((ent)->pos >= len) continue;           \
+    else
+
+#define MSG_BITS(ent)  (msg[(ent)->pos] & (ent)->mask)
+#define LAST_BITS(ent) (msg[(ent)->pos] & (ent)->mask)
+  /* uint8_t MSG_BITS(EntType *ent);
+   * uint8_t LAST_BITS(EntType *ent);
+   */
+
+#define DEFINE_STANDARD_REPORTER(EntType, ent, BODY_BLOCK)             \
+  void report##ent##s(const uint8_t msg[], const uint8_t last[],       \
+                     int len, const EntType *ent) {                    \
+    FOR_REPORTENTRIES(ent) {                                           \
+      uint8_t mb= MSG_BITS(ent);                                       \
+      uint8_t lb= LAST_BITS(ent);                                      \
+      if (mb==lb) continue;                                            \
+      BODY_BLOCK                                                       \
+    }                                                                  \
   }
-}
 
-void reportlocs(const uint8_t msg[], const uint8_t last[],
-               int len, const ValLoc *loc) {
-  for (; loc->str; loc++) {
-    if (loc->pos >= len) continue;
-    uint8_t mb= msg[loc->pos] & loc->mask;
-    uint8_t lb= last[loc->pos] & loc->mask;
-    if (mb==lb) continue;
+
+/*---------- reporter functions ----------*/
+
+DEFINE_STANDARD_REPORTER(KeyBit, bit, {
+    printf("%s %d\n", bit->str, !!mb);
+  })
+
+DEFINE_STANDARD_REPORTER(ValLoc, loc, {
     mb >>= loc->rshift;
     mb -= loc->zero;
     double val= (int8_t)mb;
     val /= (val >= 0 ? 127 : 128);
     printf("%s %.5f\n", loc->str, loc->sign * val);
-  }
-}
+  })
+
+
+/*---------- core functions ----------*/
 
 void dispatch(LastReports *lasts, const char *message_prefix,
              ProcessReport *const report_processors[MAXREPORTS],
@@ -72,6 +105,8 @@ void dispatch(LastReports *lasts, const char *message_prefix,
   memcpy(last->msg, msg, l);
 }  
 
+/*---------- main program ----------*/
+
 static void events(int verbose) {
   uint8_t msg[MAXREPORTLEN+1];
   char phys[PATH_MAX], name[PATH_MAX];