1# A kind of clone of dc geared towards binary operations. 2# by Paolo Bonzini 3# 4# commands available: 5# conversion commands 6# b convert decimal to binary 7# d convert binary to decimal 8# 9# arithmetic commands 10# < shift left binary by decimal number of bits (11 3< gives 11000) 11# > shift right binary by decimal number of bits (1011 2> gives 10) 12# & binary AND (between two binary operands) 13# | binary OR (between two binary operands) 14# ^ binary XOR (between two binary operands) 15# ~ binary NOT (between one binary operand) 16# 17# stack manipulation commands 18# c clear stack 19# P pop stack top 20# D duplicate stack top 21# x exchange top two elements 22# r rotate stack counter-clockwise (second element becomes first) 23# R rotate stack clockwise (last element becomes first) 24# 25# other commands 26# l print stack (stack top is first) 27# p print stack top 28# q quit, print stack top if any (cq is quiet quit) 29# 30# The only shortcoming is that you'd better not attempt conversions of 31# values above 1000 or so. 32# 33# This version keeps the stack and the current command in hold space and 34# the commands in pattern space; it is just a bit slower than binary2.sed 35# but more size optimized for broken seds which have a 199-command limit 36# (though binary2.sed does not have this much). 37# 38# -------------------------------------------------------------------------- 39# This was actually used in a one-disk distribution of Linux to compute 40# netmasks as follows (1 parameter => compute netmask e.g. 24 becomes 41# 255.255.255.0; 2 parameters => given host address and netmask compute 42# network and broadcast addresses): 43# 44# if [ $# = 1 ]; then 45# OUTPUT='$1.$2.$3.$4' 46# set 255.255.255.255 $1 47# else 48# OUTPUT='$1.$2.$3.$4 $5.$6.$7.$8' 49# fi 50# 51# if [ `expr $2 : ".*\\."` -gt 0 ]; then 52# MASK="$2 br b8<r b16<r b24< R|R|R|" 53# else 54# MASK="$2b 31b ^d D 55# 11111111111111111111111111111111 x>1> x<1<" 56# fi 57# 58# set `echo "$1 br b8<r b16<r b24< R|R|R| D # Load address 59# $MASK D ~r # Load mask 60# 61# & DDD 24>dpP 16>11111111& dpP 8>11111111& dpP 11111111& dpP 62# | DDD 24>dpP 16>11111111& dpP 8>11111111& dpP 11111111& dpP 63# " | sed -f binary.sed` 64# 65# eval echo $OUTPUT 66# -------------------------------------------------------------------------- 67 68:cmd 69s/^[\n\t ]*// 70s/^#.*// 71/^$/ { 72 $b quit 73 N 74 t cmd 75} 76/^[0-9][0-9]*/ { 77 G 78 h 79 s/^[0-9][0-9]* *\([^\n]*\).*/\1/ 80 x 81 s/^\([0-9][0-9]*\)[^\n]*/\1/ 82 x 83 t cmd 84} 85 86/^[^DPxrRcplqbd&|^~<>]/bbad 87 88H 89x 90s/\(\n[^\n]\)[^\n]*$/\1/ 91 92/D$/ s/^[^\n]*\n/&&/ 93/P$/ s/^[^\n]*\n// 94/x$/ s/^\([^\n]*\n\)\([^\n]*\n\)/\2\1/ 95/r$/ s/^\([^\n]*\n\)\(.*\)\(..\)/\2\1\3/ 96/R$/ s/^\(.*\n\)\([^\n]*\n\)\(..\)/\2\1\3/ 97/c$/ s/.*// 98/p$/ P 99/l$/ { 100 s/...$// 101 p 102 t cmd 103} 104 105/q$/ { 106 :quit 107 /.../P 108 d 109} 110 111/b$/ { 112 # Decimal to binary via analog form 113 s/^\([^\n]*\)/-&;9876543210aaaaaaaaa/ 114 :d2bloop1 115 s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\{9\}\(a*\)\)/\1\1\1\1\1\1\1\1\1\1\4-\3/ 116 t d2bloop1 117 s/-;9876543210aaaaaaaaa/;a01!/ 118 :d2bloop2 119 s/\(a*\)\1\(a\{0,1\}\)\(;\2.\(.\)[^!]*!\)/\1\3\4/ 120 /^a/b d2bloop2 121 s/[^!]*!// 122} 123 124/d$/ { 125 # Binary to decimal via analog form 126 s/^\([^\n]*\)/-&;10a/ 127 :b2dloop1 128 s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\(a*\)\)/\1\1\4-\3/ 129 t b2dloop1 130 s/-;10a/;aaaaaaaaa0123456789!/ 131 :b2dloop2 132 s/\(a*\)\1\1\1\1\1\1\1\1\1\(a\{0,9\}\)\(;\2.\{9\}\(.\)[^!]*!\)/\1\3\4/ 133 /^a/b b2dloop2 134 s/[^!]*!// 135} 136 137/&$/ { 138 # Binary AND 139 s/\([^\n]*\)\n\([^\n]*\)/-\1-\2-111 01000/ 140 :andloop 141 s/\([^-]*\)-\([^-]*\)\([^-]\)-\([^-]*\)\([^-]\)-\([01 ]*\3\5\([01]\)\)/\7\1-\2-\4-\6/ 142 t andloop 143 s/^0*\([^-]*\)-[^\n]*/\1/ 144 s/^\n/0&/ 145} 146 147/\^$/ { 148 # Binary XOR 149 s/\([^\n]*\)\n\([^\n]*\)/-\1-\2-000 01101/ 150 b orloop 151} 152 153/|$/ { 154 # Binary OR 155 s/\([^\n]*\)\n\([^\n]*\)/-\1-\2-000 10111/ 156 :orloop 157 s/\([^-]*\)-\([^-]*\)\([^-]\)-\([^-]*\)\([^-]\)-\([01 ]*\3\5\([01]\)\)/\7\1-\2-\4-\6/ 158 t orloop 159 s/\([^-]*\)-\([^-]*\)-\([^-]*\)-[^\n]*/\2\3\1/ 160} 161 162/~$/ { 163 # Binary NOT 164 s/^\(.\)\([^\n]*\n\)/\1-010-\2/ 165 :notloop 166 s/\(.\)-0\{0,1\}\1\(.\)0\{0,1\}-\([01\n]\)/\2\3-010-/ 167 t notloop 168 169 # If result is 00001..., \3 does not match (it looks for -10) and we just 170 # remove the table and leading zeros. If result is 0000...0, \3 matches 171 # (it looks for -0), \4 is a zero and we leave a lone zero as top of the 172 # stack. 173 174 s/0*\(1\{0,1\}\)\([^-]*\)-\(\1\(0\)\)\{0,1\}[^-]*-/\4\1\2/ 175} 176 177/<$/ { 178 # Left shift, convert to analog and add a binary digit for each analog digit 179 s/^\([^\n]*\)/-&;9876543210aaaaaaaaa/ 180 :lshloop1 181 s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\{9\}\(a*\)\)/\1\1\1\1\1\1\1\1\1\1\4-\3/ 182 t lshloop1 183 s/^\(a*\)-;9876543210aaaaaaaaa\n\([^\n]*\)/\2\1/ 184 s/a/0/g 185} 186 187/>$/ { 188 # Right shift, convert to analog and remove a binary digit for each analog digit 189 s/^\([^\n]*\)/-&;9876543210aaaaaaaaa/ 190 :rshloop1 191 s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\{9\}\(a*\)\)/\1\1\1\1\1\1\1\1\1\1\4-\3/ 192 t rshloop1 193 s/^\(a*\)-;9876543210aaaaaaaaa\n\([^\n]*\)/\2\1/ 194 :rshloop2 195 s/.a// 196 s/^aa*/0/ 197 /a\n/b rshloop2 198} 199 200s/..$// 201x 202:bad 203s/^.// 204tcmd 205