From: Ian Jackson Date: Sun, 20 Feb 2011 14:03:49 +0000 (+0000) Subject: hostside: hidrawconv: factor out most of the reporter functions' bodies into macros X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=f7dce805;p=trains.git hostside: hidrawconv: factor out most of the reporter functions' bodies into macros --- diff --git a/hostside/hidrawconv.c b/hostside/hidrawconv.c index 3321ccf..9a298b5 100644 --- a/hostside/hidrawconv.c +++ b/hostside/hidrawconv.c @@ -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]; diff --git a/hostside/hidrawconv.h b/hostside/hidrawconv.h index 6ffd35e..3887537 100644 --- a/hostside/hidrawconv.h +++ b/hostside/hidrawconv.h @@ -23,26 +23,30 @@ typedef void ProcessReport(const uint8_t *msg, int msglen, const uint8_t *last); extern const char *const descriptor; extern ProcessReport *const report_processors[MAXREPORTS]; +void dispatch(LastReports *lasts, const char *message_prefix, + ProcessReport *const report_processors[MAXREPORTS], + const uint8_t *msg, int l); + +/*---------- specific reporters ----------*/ + typedef struct { const char *str; int pos; uint8_t mask; } KeyBit; +void reportbits(const uint8_t msg[], const uint8_t last[], + int len, const KeyBit bits[]); + + typedef struct { const char *str; int pos, rshift, sign; /* mask is applied before rshift */ uint8_t mask, zero; } ValLoc; -void reportbits(const uint8_t msg[], const uint8_t last[], - int len, const KeyBit bits[]); - void reportlocs(const uint8_t msg[], const uint8_t last[], int len, const ValLoc locs[]); -void dispatch(LastReports *lasts, const char *message_prefix, - ProcessReport *const report_processors[MAXREPORTS], - const uint8_t *msg, int l); #endif /*HIDRAWCONV_H*/