From: ian Date: Fri, 3 Jun 2005 23:43:33 +0000 (+0000) Subject: new some_lookup X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=d4e9bb5768782b1f6246bbe6ef6a8268182355f7;p=trains.git new some_lookup --- diff --git a/hostside/client.c b/hostside/client.c index 22e1c0c..a3f409a 100644 --- a/hostside/client.c +++ b/hostside/client.c @@ -81,23 +81,25 @@ int thiswordstrcmp(ParseState *ps, const char *b) { return lstrstrcmp(ps->thisword, ps->lthisword, b); } -const CmdInfo *ps_lookup(ParseState *ps, const CmdInfo *inf) { +const void *any_lookup(ParseState *ps, const void *inf, size_t sz) { + const char *tname; + for (; - inf->name; - inf++) - if (!thiswordstrcmp(ps,inf->name)) + (tname= *(const char *const*)inf); + inf= (const char*)inf + sz) + if (!thiswordstrcmp(ps,tname)) return inf; return 0; } -const CmdInfo *ps_needword_lookup(ParseState *ps, const CmdInfo *infs) { +const void *any_needword_lookup(ParseState *ps, const void *infs, size_t sz) { if (!ps_needword(ps)) return 0; - return ps_lookup(ps,infs); + return any_lookup(ps,infs,sz); } void ps_callword(ParseState *ps, const CmdInfo *infs, const char *what) { const CmdInfo *ci; - ci= ps_needword_lookup(ps,infs); + ci= some_needword_lookup(ps,infs); if (!ci) { badcmd(ps,"unknown %s",what); return; } ci->fn(ps,ci); } diff --git a/hostside/commands.c b/hostside/commands.c index 3441f9b..904e53b 100644 --- a/hostside/commands.c +++ b/hostside/commands.c @@ -159,6 +159,7 @@ struct PicCmdInfo { static void cmd_pic(ParseState *ps, const CmdInfo *ci) { if (!ps_needword(ps)) return; + } const CmdInfo toplevel_cmds[]= { diff --git a/hostside/hostside.h b/hostside/hostside.h index 62dd211..dc6efa3 100644 --- a/hostside/hostside.h +++ b/hostside/hostside.h @@ -98,8 +98,6 @@ int thiswordstrcmp(ParseState *ps, const char *b); int ps_word(ParseState *ps); int ps_needword(ParseState *ps); int ps_needhextoend(ParseState *ps, Byte *dbuf, int *len_io); -const CmdInfo *ps_lookup(ParseState *ps, const CmdInfo *inf); -const CmdInfo *ps_needword_lookup(ParseState *ps, const CmdInfo *infs); void ps_callword(ParseState *ps, const CmdInfo *infs, const char *what); void vbadcmd(ParseState *ps, const char *fmt, va_list al) @@ -123,4 +121,17 @@ struct RetransmitNode { void retransmit_queue(RetransmitNode *rn); void retransmit_cancel(RetransmitNode *rn); +/*---------- macro for table lookups, with help from client.c ----------*/ + +#define some_lookup(ps, infos) \ + ((const typeof(infos[0])*) \ + any_lookup((ps),(infos),sizeof((infos)[0]))) + +#define some_needword_lookup(ps, infos) \ + ((const typeof(infos[0])*) \ + any_needword_lookup((ps),(infos),sizeof((infos)[0]))) + +const void *any_lookup(ParseState *ps, const void *infos, size_t infosz); +const void *any_needword_lookup(ParseState *ps, const void *infos, size_t); + #endif /*HOSTSIDE_H*/ diff --git a/hostside/parse-proto-spec b/hostside/parse-proto-spec index 8d34ce3..b484732 100755 --- a/hostside/parse-proto-spec +++ b/hostside/parse-proto-spec @@ -10,6 +10,21 @@ sub begin ($) { ($spec,$templ)=@ARGV; +sub expand_and_write () { + $templl= $templlin; + $templl =~ s/\@([a-z]+)\=(\w*)\@/ + die "$1=$2 in $templl ?" unless exists $v{$1}; + $v{$1} eq $2 ? '' : '@SKIP@' + /ge; + $templl =~ m/\@SKIP\@/ + and next; + $templl =~ s/\@([a-z]+)\@/ + die $1 unless exists $v{$1}; + $v{$1} + /ge; + print $templl or die $!; +} + sub process_line () { chomp; $origprotoline= $_; @@ -64,20 +79,7 @@ sub process_line () { $v{opcodeyn}= sprintf "0x%02x", (oct("0b$opcode") | $ybit * $yval); $v{arglen}= $arglen; $v{arglentf}= sprintf "%d", !!$arglen; - $templl= $templlin; - $templl =~ s/\@h2p\@/\@dname=host2pic\@/; - $templl =~ s/\@p2h\@/\@dname=pic2host\@/; - $templl =~ s/\@([a-z]+)\=(\w*)\@/ - die "$1=$2 in $templl ?" unless exists $v{$1}; - $v{$1} eq $2 ? '' : '@SKIP@' - /ge; - $templl =~ m/\@SKIP\@/ - and next; - $templl =~ s/\@([a-z]+)\@/ - die $1 unless exists $v{$1}; - $v{$1} - /ge; - print $templl or die $!; + expand_and_write(); } } @@ -86,8 +88,14 @@ for (;;) { $templlin= ; last unless length $templlin; if ($templlin !~ m/\@\w+\@/) { print $templlin or die $!; + } elsif ($templlin =~ s/\@1\@//) { + undef %v; + $v{skeleton}= 'autogenerated - do not edit'; + expand_and_write(); } else { $doyn= $templlin =~ m/\@[a-z]+yn\@/; + $templlin =~ s/\@h2p\@/\@dname=host2pic\@/; + $templlin =~ s/\@p2h\@/\@dname=pic2host\@/; open S, "$spec" or die "$spec $!"; while () { process_line(); diff --git a/hostside/skelproto-pic.h b/hostside/skelproto-pic.h index c6804e6..dc1ca89 100644 --- a/hostside/skelproto-pic.h +++ b/hostside/skelproto-pic.h @@ -1,3 +1,4 @@ +/* @skeleton@ @1@ */ /* * arranges for the declarations of * enco_pic_WHATEVER