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 69 s/^[\n\t ]*// 70 s/^#.*// 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 88 H 89 x 90 s/\(\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 200 s/..$// 201 x 202 :bad 203 s/^.// 204 tcmd 205