chiark / gitweb /
speed <trainpname> <step> _[<direction>]
authorian <ian>
Sun, 14 Sep 2008 16:58:01 +0000 (16:58 +0000)
committerian <ian>
Sun, 14 Sep 2008 16:58:01 +0000 (16:58 +0000)
hostside/README.commands
hostside/commands.c
hostside/common.h
hostside/errorcodes.h.gen

index e4d79454372a2f3636a639536d3b8ff74343d26f..ef9bfaacef953816642a09200b3eb1d99ae79b40 100644 (file)
@@ -118,6 +118,10 @@ COMMANDS AND RESPONSES
  O< ?ack <command> SignallingPredictedProblem \
           <problematic-train> <problematic-segment>|- : <error message>...
 
+ O< ?ack <command> 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 <executing> and
     <ack> inclusive, is prefixed with `-' if they are not due to
@@ -182,7 +186,7 @@ MULTIPLEXER-IMPLEMENTED FUNCTIONALITY AFFECTING WHOLE SYSTEM
 
 CHIEF COMMANDS
 
- speed <trainpname> <step>
+ speed <trainpname> <step> [forwards|backwards]
  !speed <trainpname> <step>
 
  noop [<anything>...]
index 76be340d3598a76ab03b21fcfc435230c2997af1..5f0e32370b8ae22479699c0c092edcdca848d249 100644 (file)
@@ -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) );
index 0c9bb412849a07a43fc41938a8007d7506aa208b..d2dcf736ab9dbca6fa29daa780f694ed186b4b8e 100644 (file)
@@ -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);
index 2eaf6307bed6084aecad1e31a0c705c2dae76544..7ccd989489173284adad932b539301ebf0d3dbbe 100755 (executable)
@@ -11,6 +11,7 @@
        InvalidState
        SignallingPredictedProblem
        SignallingHorizonReached
+       CommandPreconditionsViolated
 
        LimitExceeded
        SystemFailed