#define FEATURESADDR_TRANSMITS 4
/* 0..2 are func0to4 func5to8 func9to12 and speed cmd
- * pi.l is 0 if not transmitting */
+ * pi.l is 0 if not applicable */
typedef struct FeaturesAddr {
struct FeaturesAddr *next;
- int addr, cbitmap;
+ int addr;
+ unsigned current, permitted; /* nmra features */
RetransmitRelaxedNode rn[FEATURESADDR_TRANSMITS];
} FeaturesAddr;
-typedef struct {
- FeaturesAddr *a;
- int bitval; /* may have no or several bits set */
- int speedstep; /* -ve means backwards; 0 means not to use motor for feat */
-} FeaturesFeature;
-
-typedef struct FeaturesTarget {
- struct FeaturesTarget *next;
- char *pname;
- char *featchs; /* null-terminated */
- FeaturesFeature **feats; /* same order as featchs */
-} FeaturesTarget;
-
extern int n_trains;
extern Train *trains;
extern Segment *segments;
-extern FeaturesTarget *feattargs;
extern FeaturesAddr *feataddrs;
/*---------- global variables, in realtime.c ----------*/
is { STRT IS; }
at { STRT AT; }
has { STRT HAS; }
-inverted { STRT INVERTED; }
+minus { STRT MINUS; }
step { STRT STEP; }
stops { STRT STOPS; }
home { STRT HOME; }
double dbl;
}
-%token <name> TRAIN FEATURE SEG IS AT HAS INVERTED STEP STOPS HOME END
+%token <name> TRAIN FEATURE SEG IS AT HAS MINUS STEP STOPS HOME END
%token <name> IDENT FEATLETTER
%token <name> NL
%token <num> NUM
{ if ($2) record_seg_at($2,$4);
}
| FEATURE feature IS feataddr NUM
- { if ($2) record_feature_nmrafeat($2,$4,$5);
+ { if ($4) record_feature_nmrafeat($4,$5);
}
| FEATURE feature IS feataddr STEP NUM
- { if ($2) record_feature_motor($2,$4,$6);
+ { if ($4) record_feature_motor($4,$6);
}
backwards: /* empty */ { $$= 0; }
| '-' { $$= 1; }
inverted: /* empty */ { $$= 0; }
- | INVERTED { $$= 1; }
+ | MINUS { $$= 1; }
segments: { cur_train= (void*)-1; }
| backwards seg { record_train_home(cur_train,$1,$2); } segments
ident: TRAIN | SEG
- | IS | AT | HAS | INVERTED | STEP | STOPS | HOME
+ | IS | AT | HAS | MINUS | STEP | STOPS | HOME
| END
| IDENT | FEATLETTER
seg: ident { $$= record_pname2seg($1); }
train: ident { $$= record_pname2train($1); }
-feature: ident FEATLETTER { $$= record_pname2feature($1,$2); }
+feature: ident ident { record_feature_public($1,$2); }
+ | ident MINUS { record_feature_private(); }
feataddr: NUM { $$= record_feataddr($1); }
end: END NL
* train <trainpn> stops <step> at <distance> after <milliseconds>
* seg <segpn> has [-]<ownerpn> [inverted]
* seg <segpn> at <movposcomb>
- * feature <trainorfeatpn> <letter> is <addr> <nmranum>
- * feature <trainorfeatpn> <letter> is <addr> step [-]<nmranum>
+ * feature <trainpn> <featpn>|- is <addr> <nmranum>
+ * feature <trainpn> <featpn>|- is <addr> step [-]<nmranum>
*
* speed is floating point in m/s
*/
#include "record-i.h"
#include "record-l.h"
-FeaturesTarget *feattargs;
FeaturesAddr *feataddrs;
+static char *feat_train, *feat_feat;
+
/*---------- input and error handling ----------*/
static const char *filename;
return node;
}
-FeaturesFeature *record_pname2feature(const char *name, const char *letter) {
- FeaturesTarget **search, *node;
- FeaturesFeature *feat;
- char *p;
- int l;
-
- if (!trains) return 0; /* 2nd pass only */
- assert(letter[0] && !letter[1]);
-
- SLIST_FIND_OR_INSERT
- (feattargs,search,node, !strcmp(name,node->pname), ({
- node->pname= mstrdup(name);
- node->featchs= 0;
- node->feats= 0;
- }));
-
- l= node->featchs ? strlen(node->featchs) : 0;
- if (l) {
- p= strchr(node->featchs, letter[0]);
- if (p) return node->feats[p - node->featchs];
- }
-
- node->featchs= mrealloc(node->featchs,l+2);
- node->featchs[l]= letter[0];
- node->featchs[l+1]= 0;
-
- node->feats= mrealloc(node->feats, (l+1)*sizeof(*node->feats));
- node->feats[l]= feat= mmalloc(sizeof(*feat));
+static void record_feature_freeold(void) {
+ free(feat_train);
+ free(feat_feat);
+}
- feat->a= 0;
- feat->bitval= 0;
- feat->speedstep= 0;
+void record_feature_public(const char *name, const char *feat) {
+ record_feature_freeold();
+ feat_train= mstrdup(name);
+ feat_feat= mstrdup(feat);
+}
- return feat;
+void record_feature_private(void) {
+ record_feature_freeold();
+ feat_train= feat_feat= 0;
}
/*---------- zone allocator for strings ----------*/