# ppt5.awk version 1 by Ben Collver
#
# Format 5-bit values as 5 hole tape. (ISO 1154 paywalled)
#
# <
https://web.archive.org/web/20040408201444/
#
http://homepages.cwi.nl/~dik/english/codes/punched.html>
function bin2dec(str, dec, hex) {
hex = bin2hex(str)
dec = hex2dec(hex)
return dec
}
function bin2hex(str, chunk, n, i, hex, pad, rem) {
str = zpad4(str)
n = length(str)
for (i = 1; i <= n; i += 4) {
chunk = zpad4(substr(str, i, 4))
hex = hex b2h[chunk]
}
return hex
}
function dec2bin(dec, hex, bin) {
hex = sprintf("%x\n", dec)
bin = hex2bin(hex)
return bin
}
function hex2bin(hex, n, i, bin) {
n = length(hex)
for (i = 1; i <= n; i++) {
bin = bin h2b[substr(hex, i, 1)]
}
sub(/^0+/, "", bin)
if (length(bin) == 0) {
bin = "0"
}
return bin
}
function hex2dec(val, out, i, n) {
if (val ~ /^0x/) {
val = substr(val, 3)
}
n = length(val)
for (i = 1; i <= n; i++) {
out = (out * 16) + h2d[substr(val, i, 1)]
}
#return sprintf("%.0f", out)
return out
}
function init() {
split("0 1 2 3 4 5 6 7 8 9 A B C D E F", hex, " ")
split("0000 0001 0010 0011 0100 0101 0110 0111 " \
"1000 1001 1010 1011 1100 1101 1110 1111", bin, " ")
for (i = 0; i < 256; i++) {
c = sprintf("%c", i)
ord[c] = i
}
# bin/dec/hex conversion tables
for (i in hex) {
hu = hex[i]
hl = tolower(hu)
h2b[hl] = h2b[hu] = bin[i]
h2d[hl] = h2d[hu] = i - 1
b2h[bin[i]] = hu
}
}
function main() {
decode = 0
ignore = 0
if (ARGV[1] == "decode") {
delete ARGV[1]
decode = 1
}
}
function zpad4(str, pad, rem) {
rem = length(str) % 4
if (rem > 0) {
pad = substr("0000", 1, 4 - rem)
str = pad str
}
return str
}
BEGIN {
init()
main()
if (!decode) {
RS="\377"
print "________"
}
}
END {
if (!decode) {
print "--------"
}
}
/^________$/ && decode {
ignore = 1
}
/^--------$/ && decode {
ignore = 1
}
{
if (ignore) {
ignore = 0
next
}
if (decode) {
if (!/^|[ o][ o][ o]\.[ o][ o]|$/) {
printf "Error: Invalid ppt5 input: %s\n", $0
exit 1
}
s = substr($0, 2, 3) substr($0, 6, 2)
gsub(/ /, "0", s)
gsub(/o/, "1", s)
d = bin2dec(s)
printf "%c", d
} else {
len = length($0)
for (i = 1; i <= len; i++) {
c = substr($0, i, 1)
d = ord[c]
if (d > 32) {
printf "Error: Character won't fit in 5 bits: %c(%d)\n", c, d
exit 1
}
b = dec2bin(d)
s = sprintf("%5s", b)
gsub(/0/, " ", s)
gsub(/1/, "o", s)
printf "|%s.%s|\n", substr(s, 1, 3), substr(s, 4, 2)
}
}
}