From: ian Date: Sun, 14 Sep 2008 16:58:01 +0000 (+0000) Subject: speed _[] X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=511e21647957928cb48aea40418bc79e7dc6475c;p=trains.git speed _[] --- diff --git a/hostside/README.commands b/hostside/README.commands index e4d7945..ef9bfaa 100644 --- a/hostside/README.commands +++ b/hostside/README.commands @@ -118,6 +118,10 @@ COMMANDS AND RESPONSES O< ?ack SignallingPredictedProblem \ |- : ... + O< ?ack CommandPreconditionsViolated direction + response to speed command which specified a direction, if the train + is actually facing the other direction + when these come through the multiplexer, everything which is a result of _other_ clients' activities, between and inclusive, is prefixed with `-' if they are not due to @@ -182,7 +186,7 @@ MULTIPLEXER-IMPLEMENTED FUNCTIONALITY AFFECTING WHOLE SYSTEM CHIEF COMMANDS - speed + speed [forwards|backwards] !speed noop [...] diff --git a/hostside/commands.c b/hostside/commands.c index 76be340..5f0e323 100644 --- a/hostside/commands.c +++ b/hostside/commands.c @@ -47,6 +47,14 @@ struct NmraParseEncodeCaller { jmp_buf jb; }; +typedef struct { const char *word; int backwards; int change; } DirectionInfo; +static const DirectionInfo directioninfos[]= { + { "forwards", 0, 0 }, /* first two must be `forwards' and `backwards' */ + { "backwards", 1, 0 }, /* for the benefit of cmd_speed */ + { "change", -1, 1 }, + { 0 } +}; + unsigned long nmra_argnumber(NmraParseEncodeCaller *pec, int argi) { return pec->arg[argi]; } @@ -318,12 +326,21 @@ static int cmd_route(ParseState *ps, const CmdInfo *ci) { static int cmd_speed(ParseState *ps, const CmdInfo *ci) { long speed; Train *tra; + const DirectionInfo *di= 0; MUSTECR( ps_needtrain(ps,&tra) ); - MUSTECR( ps_neednumber(ps,&speed,0,126,"speed step") ); + if (ps->remain) { + di= some_needword_lookup_counted(ps,directioninfos,2,"direction"); + if (!di) return EC_BadCmd; + } MUSTECR( ps_neednoargs(ps) ); + if (di && di->backwards != tra->backwards) { + ouprintf("ack %s CommandPreconditionsViolated direction\n", ci->name); + return EC_BadCmd; + } + if (ci->xarg & CIXF_FORCE) { actual_speed(tra,speed); } else { @@ -350,15 +367,15 @@ static int cmd_invert(ParseState *ps, const CmdInfo *ci) { static int cmd_direction(ParseState *ps, const CmdInfo *ci) { Train *tra; int backwards; + const DirectionInfo *di; MUSTECR( ps_needtrain(ps,&tra) ); - MUSTECR( ps_needword(ps) ); - if (!thiswordstrcmp(ps,"forwards")) backwards= 0; - else if (!thiswordstrcmp(ps,"backwards")) backwards= 1; - else if (!thiswordstrcmp(ps,"change")) backwards= !tra->backwards; - else return badcmd(ps, "direction must be forwards|backwards|change"); + di= some_needword_lookup(ps,directioninfos,"direction"); + if (!di) return EC_BadCmd; + backwards= di->change ? !tra->backwards : di->backwards; + MUSTECR( ps_neednoargs(ps) ); MUSTECRPREDICT( safety_setdirection(tra,backwards,CMDPPC) ); diff --git a/hostside/common.h b/hostside/common.h index 0c9bb41..d2dcf73 100644 --- a/hostside/common.h +++ b/hostside/common.h @@ -80,19 +80,19 @@ int ps_neednoargs(ParseState *ps); /*---------- macro for table lookups, with help from parseutils.c ----------*/ +#define some_lookup_counted(ps, infos, ninfos) \ + ((const typeof(infos[0])*) \ + any_lookup((ps),(infos),(ninfos),sizeof((infos)[0]))) + #define some_lookup(ps, infos) \ - ((const typeof(infos[0])*) \ - any_lookup((ps),(infos),INT_MAX,sizeof((infos)[0]))) + (some_lookup_counted((ps),(infos),INT_MAX)) -#define some_needword_lookup_counted(ps, infos, ninfos, what) \ - ((const typeof(infos[0])*) \ - any_needword_lookup((ps), \ - (infos), (ninfos), sizeof((infos)[0]), \ - (what))) +#define some_needword_lookup_counted(ps, infos, ninfos, what) \ + ((const typeof(infos[0])*) \ + any_needword_lookup((ps),(infos),(ninfos),sizeof((infos)[0]),(what))) #define some_needword_lookup(ps, infos, what) \ - ((const typeof(infos[0])*) \ - any_needword_lookup((ps),(infos),INT_MAX,sizeof((infos)[0]),(what))) + (some_needword_lookup_counted((ps),(infos),INT_MAX,(what))) const void *any_lookup(ParseState *ps, const void *infos, int ninfsmax, size_t infosz); diff --git a/hostside/errorcodes.h.gen b/hostside/errorcodes.h.gen index 2eaf630..7ccd989 100755 --- a/hostside/errorcodes.h.gen +++ b/hostside/errorcodes.h.gen @@ -11,6 +11,7 @@ InvalidState SignallingPredictedProblem SignallingHorizonReached + CommandPreconditionsViolated LimitExceeded SystemFailed