$(LINK)
hostside: hostside.o serialio.o client.o obc.o commands.o \
- nmra.o encode.o retransmit.o output.o -loop
+ nmra.o encode.o retransmit.o output.o auproto-pic.o \
+ -loop
$(LINK)
proto-expanded: ../cebpic/README.protocol
expand <$< $o
+commands.o auproto-pic.o: auproto-pic.h
+
auproto-%: parse-proto-spec proto-expanded skelproto-%
./$+ $o
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
+#include <errno.h>
#include "hostside.h"
#include "../layout/dlist.h"
return 1;
}
+int ps_neednumber(ParseState *ps, long *r, long mi, long mx, const char *wh) {
+ char *ep;
+ long v;
+
+ if (!ps_needword(ps)) return 0;
+ errno= 0; v= strtol(ps->thisword,&ep,0);
+ if (errno || ep != ps->thisword + ps->lthisword) {
+ badcmd(ps,"invalid number for %s",wh);
+ return 0;
+ }
+ if (v < mi || v > mx) {
+ badcmd(ps,"%s %ld out of range %ld..%ld",wh,v,mi,mx);
+ return 0;
+ }
+ *r= v;
+ return 1;
+}
+
+int ps_neednoargs(ParseState *ps) {
+ if (ps->remain) {
+ badcmd(ps,"too many arguments");
+ return 0;
+ }
+ return 1;
+}
+
int ps_needhextoend(ParseState *ps, Byte *d, int *remain_io) {
Byte *d_end;
char buf[3], *ep;
#include <string.h>
#include "hostside.h"
+#include "auproto-pic.h"
#define NMRA_MAX_NARGS 10
};
static void cmd_pic(ParseState *ps, const CmdInfo *ci) {
- if (!ps_needword(ps)) return;
+ const PicInsnInfo *pii;
+ PicInsn pi;
+ long arg;
+ pii= some_needword_lookup(ps,pic_command_infos);
+ if (pii->argbits) {
+ if (!ps_neednumber(ps, &arg, 0, (1L << pii->argbits) - 1,
+ "pic object number"))
+ return;
+ } else {
+ arg= 0;
+ }
+ if (!ps_neednoargs(ps))
+ return;
+ enco_pic_anyinsn(&pi, pii, arg);
+ serial_transmit(pi.d, pi.l);
}
const CmdInfo toplevel_cmds[]= {
void *mmalloc(size_t sz);
char *mstrdupl(const char *s, int l);
char *mstrdup(const char *s);
-
+
extern int serial_fd, serial_fudge_delay;
/*---------- nmra parsing, nmra.c et al ----------*/
int ps_needword(ParseState *ps);
int ps_needhextoend(ParseState *ps, Byte *dbuf, int *len_io);
void ps_callword(ParseState *ps, const CmdInfo *infs, const char *what);
+int ps_neednumber(ParseState *ps, long *r, long min, long max, const char *wh);
+int ps_neednoargs(ParseState *ps);
void vbadcmd(ParseState *ps, const char *fmt, va_list al)
__attribute__((format(printf,2,0)));
($spec,$templ)=@ARGV;
+$linexpect= -1;
+
+sub pln ($) {
+ if ($dolinno && $linexpect != $templlinno) {
+ print "# $templlinno \"$templ\"\n" or die $!;
+ }
+ print $_[0] or die $!;
+ $linexpect= $templlinno+1;
+}
+
sub expand_and_write () {
$templl= $templlin;
$templl =~ s/\@([a-z]+)\=(\w*)\@/
die $1 unless exists $v{$1};
$v{$1}
/ge;
- print $templl or die $!;
+ pln($templl);
}
sub process_line () {
open T, "$templ" or die "$templ $!";
for (;;) {
$templlin= <T>; last unless length $templlin;
+ $templlinno= $.;
+ if ($templlin =~ s/\@L\@//) {
+ $dolinno= 1;
+ }
if ($templlin !~ m/\@\w+\@/) {
- print $templlin or die $!;
+ pln($templlin);
} elsif ($templlin =~ s/\@1\@//) {
undef %v;
$v{skeleton}= 'autogenerated - do not edit';
+/* @skeleton@ @1@ @L@ */
/*
* arranges for the declarations of
* enco_pic_WHATEVER
* and the tables
*/
-#ifndef PROTOCOL_H
-#define PROTOCOL_H
+#include "hostside.h"
+#include "auproto-pic.h"
+
+extern void enco_pic_anyinsn(PicInsn *out, const PicInsnInfo *pii,
+ int objnum) {
+ unsigned long as= objnum;
+ int i;
+
+ out->l= 1 + pii->argbits/7;
+ for (i= out->l - 1;
+ i > 0;
+ i--, as >>= 7)
+ out->d[i]= (as & 0x07fUL) | 0x080UL;
+ out->d[out->l - 1] &= ~0x080UL;
+ out->d[0] |= pii->opcode;
+}
const PicInsnInfo pic_command_infos[]= {
{ "@cnameyn@", @opcodeyn@, @arglen@ }, @h2p@
- 0
+ { 0 }
};
const PicInsnInfo pic_reply_infos[]= {
{ "@cnameyn@", @opcodeyn@, @arglen@ }, @p2h@
- 0
+ { 0 }
};
-/* @skeleton@ @1@ */
+/* @skeleton@ @1@ @L@ */
/*
* arranges for the declarations of
* enco_pic_WHATEVER
#ifndef AUPROTO_PIC_H
#define AUPROTO_PIC_H
+typedef struct PicInsnInfo PicInsnInfo;
+
void enco_pic_@cname@(PicInsn *out); @h2p@ @arglentf=0@
void enco_pic_@cname@(PicInsn *out, int objum); @h2p@ @arglentf=1@
extern void enco_pic_polarity_setbit(PicInsn *out, int objnum);
extern void on_pic_debug(int ch);
-typedef struct PicInsnInfo PicInsnInfo;
+extern void enco_pic_anyinsn(PicInsn *out, const PicInsnInfo *pii, int objnum);
+
struct PicInsnInfo {
const char *name;
Byte opcode;