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);
}
static void cmd_pic(ParseState *ps, const CmdInfo *ci) {
if (!ps_needword(ps)) return;
+
}
const CmdInfo toplevel_cmds[]= {
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)
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*/
($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= $_;
$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();
}
}
$templlin= <T>; 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 (<S>) {
process_line();
+/* @skeleton@ @1@ */
/*
* arranges for the declarations of
* enco_pic_WHATEVER