1#!/bin/sh 2# Copyright 2018 by Denys Vlasenko 3# Licensed under GPLv2 or later, see file LICENSE in this source tree. 4 5. ./testing.sh 6 7# testing "test name" "command" "expected result" "file input" "stdin" 8 9testing "bc comment" \ 10 "bc" \ 11 "3\n" \ 12 "" "1 /* comment */ + 2" 13 14testing "bc /*/ is not a closed comment" \ 15 "bc" \ 16 "4\n" \ 17 "" "1 /*/ + 2 */ + 3" 18 19# this needs interactive testing 20testing "bc comment with \"" \ 21 "bc" \ 22 "3\n" \ 23 "" "1 /* \" */ + 2" 24 25# this needs interactive testing 26testing "bc \"string/*\" is not a comment" \ 27 "bc" \ 28 "string/*9\n" \ 29 "" "\"string/*\";9" 30 31testing "bc comment 3: unterminated #comment" \ 32 "bc" \ 33 "" \ 34 "" "#foo" # no trailing newline 35 36testing "bc backslash 1" \ 37 "bc" \ 38 "3\n" \ 39 "" "1 \\\\\n + 2" 40 41testing "bc string 1" \ 42 "bc" \ 43 "STR\n" \ 44 "" "\"STR\n\"" 45 46testing "bc read() 4<EOF>" \ 47 "bc input" \ 48 "4\n" \ 49 "read();halt" "4" 50 51testing "bc read()^2" \ 52 "bc input" \ 53 "16\n" \ 54 "read()^2;halt" "4\n" 55 56testing "bc read()*read()" \ 57 "bc input" \ 58 "20\n" \ 59 "read()*read();halt" "4\n5" 60 61testing "bc if 0 else" \ 62 "bc" \ 63 "2\n9\n" \ 64 "" "if (0) 1 else 2; 9" 65 66testing "bc if 1 else" \ 67 "bc" \ 68 "1\n9\n" \ 69 "" "if (1) 1 else 2; 9" 70 71testing "bc if 1 if 1 else else" \ 72 "bc" \ 73 "1\n9\n" \ 74 "" "if (1) if (1) 1 else 2 else 3; 9" 75 76testing "bc if 0 else if 1" \ 77 "bc" \ 78 "2\n9\n" \ 79 "" "if (0) 1 else if (1) 2; 9" 80 81testing "bc for (;;)" \ 82 "bc" \ 83 "2\n3\n2\n9\n" \ 84 "" "i=2; for (;;) { 2; if(--i==0) break; 3; }; 9" 85 86testing "bc for (;cond;)" \ 87 "bc" \ 88 "1\n2\n3\n9\n" \ 89 "" "i=0; for(;i<3;)++i; 9" 90 91testing "bc for (;cond;upd)" \ 92 "bc" \ 93 "1\n2\n3\n9\n" \ 94 "" "i=1; for(;i<4;i++)i; 9" 95 96testing "bc for (init;cond;upd)" \ 97 "bc" \ 98 "1\n2\n3\n9\n" \ 99 "" "for(i=1;i<4;i++)i; 9" 100 101testing "bc for (;;) {break}" \ 102 "bc" \ 103 "2\n9\n" \ 104 "" "for (;;) {2;break}; 9" 105 106testing "bc define {return}" \ 107 "bc" \ 108 "0\n9\n" \ 109 "" "define w() {return}\nw();9" 110 111testing "bc define auto" \ 112 "bc" \ 113 "8\n9\n" \ 114 "" "define w() { auto z; return 8; }; w(); 9" 115 116testing "bc define auto array same name" \ 117 "bc" \ 118 "8\n9\n" \ 119 "" "define w(x) { auto x[]; return x; }; w(8); 9" 120 121testing "bc define with body on next line" \ 122 "bc" \ 123 "8\n9\n" \ 124 "" "define w()\n{ auto z; return 8; }\nw()\n9" 125 126testing "bc void function" \ 127 "bc" \ 128 "void9\n" \ 129 "" "define void w() {print \"void\"}\nw()\n9" 130 131# Extra POSIX compat - GNU bc does not allow this 132testing "bc function named 'void'" \ 133 "bc" \ 134 "void0\n9\n" \ 135 "" "define void() {print \"void\"}\nvoid()\n9" 136 137# Extra POSIX compat - GNU bc does not allow this 138testing "bc variable named 'void'" \ 139 "bc" \ 140 "6\n9\n" \ 141 "" "void=6\nvoid\n9" 142 143testing "bc if(cond)<NL>" \ 144 "bc" \ 145 "9\n" \ 146 "" "if(0)\n3\n9" 147 148testing "bc if(cond) stmt else<NL>" \ 149 "bc" \ 150 "4\n9\n" \ 151 "" "if(0)3 else\n4\n9" 152 153testing "bc while(cond)<NL>" \ 154 "bc" \ 155 "8\n7\n6\n5\n4\n3\n2\n1\n9\n" \ 156 "" "i=9;while(--i)\ni\n9" 157 158testing "bc ifz does not match if keyword" \ 159 "bc" \ 160 "1\n2\n2\n3\n" \ 161 "" "ifz=1;ifz\n++ifz;ifz++\nifz" 162 163# had parse error on "f()-N" 164testing "bc -l 'e(0)-2'" \ 165 "bc -l" \ 166 "-1.00000000000000000000\n" \ 167 "" "e(0)-2" 168 169testing "bc (!a&&b)" \ 170 "bc" \ 171 "0\n" \ 172 "" "(!a&&b)" 173 174# check that dc code is not messing this up (no NUL printing!) 175testing "bc print \"\"" \ 176 "bc" \ 177 "" \ 178 "" "print \"\"" 179 180testing "bc print 1,2,3" \ 181 "bc" \ 182 "123" \ 183 "" "print 1,2,3" 184 185testing "bc { print 1 }" \ 186 "bc" \ 187 "1" \ 188 "" "{ print 1 }" 189 190testing "bc nested loops and breaks" \ 191 "bc" \ 192 "\ 19311 19421 19531 19622 19712 19899 199" \ 200 "" "\ 201if(1) { 202 11 203 while(1) { 204 21 205 while(1) { 206 31 207 break 208 32 209 } 210 22 211 break 212 23 213 } 214 12 215} else { 216 88 217} 21899 219" 220 221testing "bc continue in if" \ 222 "bc" \ 223 "\ 22411 22521 22611 22731 22899 229" \ 230 "" "\ 231i=2 232while(i--) { 233 11 234 if(i) { 235 21 236 continue 237 22 238 } else { 239 31 240 continue 241 32 242 } 243 12 244} 24599 246" 247 248testing "bc continue in for" \ 249 "bc" \ 250 "\ 2511 25277 2532 25499 255" \ 256 "" "\ 257for(i=1; i<3; i++) { 258 i 259 if(i==2) continue 260 77 261} 26299 263" 264 265testing "bc ibase" \ 266 "bc" \ 267 "99\n1295\n1224\n" \ 268 "" "a=ZZ;a;ibase=36;a=ZZ;a;ibase=Z;a=ZZ;a" 269 270testing "bc parsing of numbers" \ 271 "bc 2>&1 | bc 2>&1 | md5sum 2>&1" \ 272 "465d8c01308d0863b6f5669e8a1c69fb -\n" \ 273 "" ' 274for (b = 2; b <= 16; ++b) { 275 if (b == 10) continue 276 obase = 10 277 print "ibase = A; ibase = ", b, "\n" 278 obase = b 279 for (i = 0; i <= 65536; ++i) { 280 i 281 print "0.", i, "\n" 282 print "1.", i, "\n" 283 print i, ".", i, "\n" 284 } 285}' 286 287testing "bc printing of numbers" \ 288 "bc 2>&1 | bc 2>&1 | md5sum 2>&1" \ 289 "d884b35d251ca096410712743aeafb9e -\n" \ 290 "" ' 291for (b = 2; b <= 101; ++b) { 292 if (b == 10) continue 293 s = b * b 294 print "obase = ", b, "\n" 295 for (i = 0; i <= s; ++i) { 296 i 297 print "0.", i, "\n" 298 print "1.", i, "\n" 299 print i, ".", i, "\n" 300 } 301 2189432174861923048671023498128347619023487610234689172304.192748960128745108927461089237469018723460 302}' 303 304for f in bc*.bc; do 305 r="`basename "$f" .bc`_results.txt" 306 test -f "$r" || continue 307 # testing "test name" "command" "expected result" "file input" "stdin" 308 testing "bc -lq $f" \ 309 "{ { bc -lq $f 2>&1; echo E:\$? >&2; } | diff -u - $r; echo E:\$?; } 2>&1" \ 310 "E:0\nE:0\n" \ 311 "" "" 312done 313 314exit $FAILCOUNT 315