From f7de8a46abb09a198cc95b3ff72226896bd29ea3 Mon Sep 17 00:00:00 2001 From: ian Date: Thu, 26 Jun 2008 15:52:14 +0000 Subject: [PATCH] features are named rather than lettered; define the features --- hostside/homes.record | 14 ++++++++ hostside/realtime.h | 11 +++--- hostside/record-l.l | 1 - hostside/record-y.y | 6 ++-- hostside/record.c | 82 +++++++++++++++++++++++++++---------------- 5 files changed, 74 insertions(+), 40 deletions(-) diff --git a/hostside/homes.record b/hostside/homes.record index 12420be..05275b9 100644 --- a/hostside/homes.record +++ b/hostside/homes.record @@ -1,3 +1,17 @@ train santafe home -X8 train shinkansen home -X7 -X9 -X11 -A5 -A6 + +feature shinkansen head is 1 5 +feature shinkansen head-red is 1 6 +feature shinkansen tail is 1 7 +feature shinkansen tail-red is 1 8 + +feature santafe head is 2 5 +feature santafe tail is 2 6 + +feature bavarian head is 4 5 +feature bavarian tail is 4 6 + +feature hoover motor is 5 step 60 + end diff --git a/hostside/realtime.h b/hostside/realtime.h index bd67a7a..419f143 100644 --- a/hostside/realtime.h +++ b/hostside/realtime.h @@ -80,24 +80,25 @@ typedef struct FeaturesAddr { } FeaturesAddr; typedef struct { + char *pname; /* first, for pname1st_compar */ 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 */ + char *pname; /* first, for pname1st_compar */ + int n_feats; + FeaturesFeature *feats; } FeaturesTarget; extern int n_trains; extern Train *trains; extern Segment *segments; +extern int n_feattargs; extern FeaturesTarget *feattargs; -extern FeaturesAddr *feataddrs; +extern FeaturesAddr *feataddrs_head; /*---------- global variables, in realtime.c ----------*/ diff --git a/hostside/record-l.l b/hostside/record-l.l index c514a09..053a0e8 100644 --- a/hostside/record-l.l +++ b/hostside/record-l.l @@ -31,7 +31,6 @@ end { STRT END; } /* new keywords must be added to %token and ident: in record-y.y */ [A-Za-z][A-Za-z0-9_]+ { STRT IDENT; } -[a-z] { STRT FEATLETTER; } [0-9]{0,8} { record_yylval.num= strtoul(yytext,0,10); return NUM; } [0-9]{9} { record_yyerror("number too long"); } diff --git a/hostside/record-y.y b/hostside/record-y.y index 8ddbe8b..5042851 100644 --- a/hostside/record-y.y +++ b/hostside/record-y.y @@ -18,7 +18,7 @@ static Train *cur_train; } %token TRAIN FEATURE SEG IS AT HAS INVERTED STEP STOPS HOME END -%token IDENT FEATLETTER +%token IDENT %token NL %token NUM %token DBL @@ -79,14 +79,14 @@ segments: { cur_train= (void*)-1; } ident: TRAIN | SEG | IS | AT | HAS | INVERTED | STEP | STOPS | HOME | END - | IDENT | FEATLETTER + | IDENT dbl: DBL | NUM { $$= $1 } seg: ident { $$= record_pname2seg($1); } train: ident { $$= record_pname2train($1); } -feature: ident FEATLETTER { $$= record_pname2feature($1,$2); } +feature: ident ident { $$= record_pname2feature($1,$2); } feataddr: NUM { $$= record_feataddr($1); } end: END NL diff --git a/hostside/record.c b/hostside/record.c index f22d5b0..dedd663 100644 --- a/hostside/record.c +++ b/hostside/record.c @@ -10,8 +10,8 @@ * train stops at after * seg has [-] [inverted] * seg at - * feature is - * feature is step [-] + * feature is + * feature is step [-] * * speed is floating point in m/s */ @@ -21,8 +21,9 @@ #include "record-i.h" #include "record-l.h" +int n_feattargs; FeaturesTarget *feattargs; -FeaturesAddr *feataddrs; +FeaturesAddr *feataddrs_head; /*---------- input and error handling ----------*/ @@ -75,13 +76,25 @@ Segment *record_pname2seg(const char *pname) { } \ }while(0) +#define ARY_FIND_OR_APPEND(things,n_things,i,entry,found,fillin) do{ \ + for ((i)=0, (entry)=(things); \ + (i)<(n_things) && !(found); \ + (i)++, (entry)++); \ + if ((i) >= (n_things)) { \ + (n_things)++; \ + (things)= mrealloc((things), sizeof(*things) * (n_things)); \ + entry= &(things)[(i)]; \ + fillin; \ + } \ + }while(0) + FeaturesAddr *record_feataddr(int num) { FeaturesAddr **search, *node; if (num<1 || num>0x3ff) record_yyerror("feature address out of range"); SLIST_FIND_OR_INSERT - (feataddrs,search,node, node->addr == num, ({ + (feataddrs_head,search,node, node->addr == num, ({ int i; node->next= 0; node->addr= num; @@ -92,38 +105,26 @@ FeaturesAddr *record_feataddr(int num) { return node; } -FeaturesFeature *record_pname2feature(const char *name, const char *letter) { - FeaturesTarget **search, *node; +FeaturesFeature *record_pname2feature(const char *targpn, const char *featpn) { + int i; + FeaturesTarget *targ; 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; + ARY_FIND_OR_APPEND + (feattargs,n_feattargs,i,targ, !strcmp(targ->pname, targpn), ({ + targ->pname= mstrdup(targpn); + targ->n_feats= 0; + targ->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)); - - feat->a= 0; - feat->bitval= 0; - feat->speedstep= 0; + ARY_FIND_OR_APPEND + (targ->feats,targ->n_feats,i,feat, !strcmp(feat->pname, featpn), ({ + feat->pname= mstrdup(featpn); + feat->a= 0; + feat->bitval= 0; + feat->speedstep= 0; + })); return feat; } @@ -260,6 +261,24 @@ void record_feature_motor(FeaturesFeature *feat, FeaturesAddr *addr, feat->speedstep= speed; } +static int pname1st_compar(const void *av, const void *bv) { + const char *const *a= av; + const char *const *b= bv; + return strcmp(*a,*b); +} + +static void features_postprocess(void) { + int i; + FeaturesTarget *targ; + + qsort(feattargs, n_feattargs, sizeof(*feattargs), pname1st_compar); + + for (i=0, targ=feattargs; + ifeats, targ->n_feats, sizeof(*targ->feats), pname1st_compar); +} + /*---------- speed curves ----------*/ static SpeedRange *rangebuf; @@ -470,6 +489,7 @@ void records_parse(const char **argv) { parse_pass(argv); /* trains!=0: populates data area */ record_tempzone_clear(); speeds_postprocess(); + features_postprocess(); record_tempzone_freeall(); record_yylex_destroy(); } -- 2.30.2