#!/usr/bin/perl use IO::Handle; @ARGV==2 or die; sub begin ($) { $dname= $_[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=$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; pln($templl); } sub b2xh ($$) { my ($bin,$orin) = @_; return sprintf "0x%02x", (oct("0b$bin") | $orin); } sub process_line () { chomp; $origprotoline= $_; if (m/^From host to PIC/) { $dirn= '>'; begin("host2pic"); } elsif (m/^From PIC to host/) { $dirn= '<'; begin("pic2host"); } elsif (m/^\S/) { $dirn= undef; } next unless defined $dirn; next unless m/^ ([<>]) / && $1 eq $dirn; die if m/\t/; die unless m/^ [<>] ([01A-Za-z. ]+?)(?: +|\s+\([+? A-Z0-9a-z]+\)\s+)([^() \t\n].*)$/; $msg= $1; $rhs= $2; next if $rhs =~ m/^\}/; next if $msg =~ m/\.\.\./; $rhs =~ m/^([A-Z]+)\s/ or die "$rhs?"; $cname= lc $1; $msg =~ s/ //g; if ($msg =~ m/^0[01]{7}$/) { $opcode= $&; $opcodemask= '11111111'; $arglen= 0; $ybit= 0; } else { $ybit= substr($msg,0,8); $ybit =~ y/Y01A-Z/10/; $ybit =~ m/1.*1/ and die "$msg/$ybit?"; $msg =~ s/Y/0/g; $msg =~ m/[A-Z]/ or die "$msg?"; $oplet= $&; $msg =~ s/$oplet/_/g; die "$msg?" if $msg =~ m/[A-Z]/; die "$msg?" unless $msg =~ m/^(1[01][01_]{6})0_{7}$/ or $msg =~ m/^(0[01][01_]{6})$/; $opcode= $1; die if $opcode =~ m/_[01]/; $opcodemask= $opcode; $opcodemask =~ y/01_/110/; $opcode =~ s/_/0/g; $arglen= $msg; $arglen =~ s/[01]//g; $arglen= length $arglen; $ybit= oct("0b$ybit"); } for $yval (($ybit && $doyn) ? (0,1) : '') { undef %v; $v{yn}= $yval; $v{dname}= $dname; $v{cname}= $cname; $v{noiselevel}= ($cname =~ m/nmradone/ ? 3 : $cname =~ m/p[io]ng/ ? 2 : $cname =~ m/detect/ ? 1 : 0); $v{cnameyn}= $cname.$yval; $v{cnameynu}= uc($cname.$yval); $v{opcode}= b2xh($opcode, 0); $v{opcodeyn}= b2xh($opcode, $ybit * $yval); $v{opcodemask}= b2xh($opcodemask, 0); $v{opcodemaskyn}= b2xh($opcodemask, $ybit); $v{arglen}= $arglen; $v{arglentf}= sprintf "%d", !!$arglen; expand_and_write(); } } open T, "$templ" or die "$templ $!"; for (;;) { $templlin= ; last unless length $templlin; $templlinno= $.; if ($templlin =~ s/\@L\@//) { $dolinno= 1; } if ($templlin !~ m/\@\w+\@/) { pln($templlin); } 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(); } S->error and die $!; close S or die $!; } } T->error and die $!; close T or die $!;