clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name testaldor.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/kfp/aldor/aldor/aldor/subcmd/testaldor -fcoverage-compilation-dir=/home/kfp/aldor/aldor/aldor/subcmd/testaldor -resource-dir /usr/local/lib/clang/18 -D PACKAGE_NAME="aldor" -D PACKAGE_TARNAME="aldor" -D PACKAGE_VERSION="1.4.0" -D PACKAGE_STRING="aldor 1.4.0" -D PACKAGE_BUGREPORT="aldor@xinutec.org" -D PACKAGE_URL="" -D PACKAGE="aldor" -D VERSION="1.4.0" -D YYTEXT_POINTER=1 -D HAVE_STDIO_H=1 -D HAVE_STDLIB_H=1 -D HAVE_STRING_H=1 -D HAVE_INTTYPES_H=1 -D HAVE_STDINT_H=1 -D HAVE_STRINGS_H=1 -D HAVE_SYS_STAT_H=1 -D HAVE_SYS_TYPES_H=1 -D HAVE_UNISTD_H=1 -D STDC_HEADERS=1 -D HAVE_LIBREADLINE=1 -D HAVE_READLINE_READLINE_H=1 -D HAVE_READLINE_HISTORY=1 -D HAVE_READLINE_HISTORY_H=1 -D USE_GLOOP_SHELL=1 -D GENERATOR_COROUTINES=0 -D HAVE_DLFCN_H=1 -D LT_OBJDIR=".libs/" -I . -I ./../../src -internal-isystem /usr/local/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-empty-body -Wno-enum-compare -Wno-missing-field-initializers -Wno-unused -Wno-unused-parameter -Wno-error=format -Wno-error=type-limits -Wno-error=strict-aliasing -Wno-sign-compare -Wno-error=shift-negative-value -Wno-error=clobbered -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2026-01-15-223856-845667-1 -x c testaldor.c
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | #include "platform.h" |
| 10 | #include "cconfig.h" |
| 11 | |
| 12 | #include "signal.h0" |
| 13 | #include "stdarg.h0" |
| 14 | #include "stddef.h0" |
| 15 | #include "stdio.h0" |
| 16 | #include "string.h0" |
| 17 | #include "stdlib.h0" |
| 18 | |
| 19 | #include "testaldor.h" |
| 20 | #include "tx_opsys.c" |
| 21 | |
| 22 | |
| 23 | |
| 24 | |
| 25 | |
| 26 | |
| 27 | |
| 28 | #define BUFLEN 1024 |
| 29 | |
| 30 | String OldCurDir; |
| 31 | String TmpDir; |
| 32 | String OutDir; |
| 33 | |
| 34 | String Aldor; |
| 35 | String OAldor; |
| 36 | String CC; |
| 37 | |
| 38 | String Kind; |
| 39 | Int KindAct; |
| 40 | String Action; |
| 41 | |
| 42 | Int failc = 0; |
| 43 | String failv[BUFLEN]; |
| 44 | |
| 45 | int debug; |
| 46 | |
| 47 | |
| 48 | |
| 49 | |
| 50 | |
| 51 | |
| 52 | void testAldorHelp _OF((void)); |
| 53 | void testAldorClean _OF((String fn)); |
| 54 | void testAldorScript _OF((String fn)); |
| 55 | void testAldorDispatch _OF((String args, String fn)); |
| 56 | void testAldorCompile _OF((String args, String fn)); |
| 57 | void testAldorRun _OF((String args, String fn)); |
| 58 | void testAldorInterpret _OF((String args, String fn)); |
| 59 | void testAldorErrors _OF((String args, String fn)); |
| 60 | void testAldorPhase _OF((String args, String fn)); |
| 61 | void testAldorGenerate _OF((String args, String fn)); |
| 62 | |
| 63 | String testAldorOutDirForTest _OF((String fname)); |
| 64 | |
| 65 | |
| 66 | |
| 67 | |
| 68 | |
| 69 | |
| 70 | void testAldorInit _OF((void)); |
| 71 | void testAldorCleanup _OF((void)); |
| 72 | void testAldorFini _OF((int)); |
| 73 | Length testAldorArgs _OF((Length, String *)); |
| 74 | void testAldorGlean _OF((Length, String *)); |
| 75 | Int testAldorFilter _OF((String)); |
| 76 | |
| 77 | |
| 78 | |
| 79 | |
| 80 | |
| 81 | |
| 82 | |
| 83 | String |
| 84 | strAlloc(cc) |
| 85 | Length cc; |
| 86 | { |
| 87 | String s = (String) malloc(cc + 1); |
| |
| 88 | |
| 89 | s[0] = '\0'; |
| 90 | s[cc] = '\0'; |
| 91 | |
| 92 | return s; |
| 93 | } |
| 94 | |
| 95 | Length |
| 96 | strLength(s) |
| 97 | String s; |
| 98 | { |
| 99 | return strlen(s); |
| 100 | } |
| 101 | |
| 102 | String |
| 103 | strCopy(s) |
| 104 | String s; |
| 105 | { |
| 106 | Length cc = strLength(s); |
| 107 | String t = strAlloc(cc); |
| 108 | |
| 109 | strcpy(t, s); |
| 110 | return t; |
| 111 | } |
| 112 | |
| 113 | String |
| 114 | strConcat(s, t) |
| 115 | String s; |
| 116 | String t; |
| 117 | { |
| 118 | Length cc = strLength(s) + strLength(t); |
| 119 | String r = strAlloc(cc); |
| 120 | |
| 121 | strcpy(r, s); |
| 122 | strcat(r, t); |
| 123 | return r; |
| 124 | } |
| 125 | |
| 126 | #if defined(CC_no_prototype) |
| 127 | String |
| 128 | strPrintf(fmt, va_alist) |
| 129 | String fmt; |
| 130 | int va_alist; |
| 131 | #else |
| 132 | String |
| 133 | strPrintf(String fmt, ...) |
| 134 | #endif |
| 135 | { |
| 136 | Length cc = BUFLEN; |
| 137 | String s; |
| 138 | va_list argp; |
| 139 | |
| 140 | s = strAlloc(cc); |
| 141 | va_start(argp, fmt); |
| 142 | vsprintf(s, fmt, argp); |
| 143 | va_end(argp); |
| 144 | |
| 145 | return s; |
| 146 | } |
| 147 | |
| 148 | Int |
| 149 | strEqual(s, t) |
| 150 | String s; |
| 151 | String t; |
| 152 | { |
| 153 | return strcmp(s, t) == 0; |
| 154 | } |
| 155 | |
| 156 | Int |
| 157 | strIsPrefix(pre, s) |
| 158 | String pre; |
| 159 | String s; |
| 160 | { |
| 161 | Int c0, cc; |
| 162 | |
| 163 | c0 = strLength(pre); |
| 164 | cc = strLength(s); |
| 165 | if (cc < c0) return 0; |
| 166 | return strncmp(pre, s, c0) == 0; |
| 167 | } |
| 168 | |
| 169 | Int |
| 170 | strIsSuffix(suf, s) |
| 171 | String suf; |
| 172 | String s; |
| 173 | { |
| 174 | Int c0, cc; |
| 175 | |
| 176 | c0 = strLength(suf); |
| 177 | cc = strLength(s); |
| 178 | if (cc < c0) return 0; |
| 179 | return strncmp(suf, s + cc - c0, c0) == 0; |
| 180 | } |
| 181 | |
| 182 | |
| 183 | |
| 184 | |
| 185 | |
| 186 | |
| 187 | |
| 188 | String HelpMsg[] = { |
| 189 | "testAldor [option...] [dir|file..]", |
| 190 | "", |
| 191 | " The possible options are:", |
| 192 | " -help Display this information", |
| 193 | " -show Run the tests and display the output", |
| 194 | " -install Run the tests and install the output as correct", |
| 195 | " -oldaldor xx Run the tests, using xx to display old .ao files", |
| 196 | " -aldor xx Run the tests, using xx as aldor executable", |
| 197 | " -cc xx Run the tests, using xx as unicl executable", |
| 198 | " -only kk Run only tests of kind kk, where kk may be", |
| 199 | " one of test{script,comp,run,errs,phase,gen,int}.", |
| 200 | " -but kk Run all the tests, except those of kind kk.", |
| 201 | "", |
| 202 | " If files are given as args, they are the tests to be used.", |
| 203 | " If a directory is given as an arg, then all the test files", |
| 204 | " in it are used. (.as .sh files)", |
| 205 | " Otherwise, all the test files in the current directory", |
| 206 | " are used. (.as .sh files)", |
| 207 | "", |
| 208 | " .as files contain one or more lines like:", |
| 209 | " --> testcomp (compile and compare byte-code output)", |
| 210 | " --> testrun (compile, run and compare output)", |
| 211 | " --> testint (interpret and compare output)", |
| 212 | " --> testerrs (-D TestErrorsToo and compare msgs)", |
| 213 | " --> testphase phname (trace phase and compare output)", |
| 214 | " --> testgen ftype (for generated files of a given type)", |
| 215 | "", |
| 216 | " .sh files do not contain any special lines." |
| 217 | }; |
| 218 | |
| 219 | |
| 220 | |
| 221 | |
| 222 | void |
| 223 | testAldorHelp() |
| 224 | { |
| 225 | Length i, msgc = sizeof(HelpMsg)/sizeof(HelpMsg[0]); |
| 226 | |
| 227 | for (i = 0; i < msgc; i += 1) { |
| 228 | fputs(HelpMsg[i], stdout); |
| 229 | fnewline(stdout); |
| 230 | } |
| 231 | } |
| 232 | |
| 233 | |
| 234 | |
| 235 | |
| 236 | |
| 237 | String Ext[] = { "ax", "ai", "ao", "fm", "asy", "l", "c", "o" }; |
| 238 | |
| 239 | void |
| 240 | testAldorClean(fn) |
| 241 | String fn; |
| 242 | { |
| 243 | String bn = osFileBase(fn); |
| 244 | String on; |
| 245 | Length i, extc = sizeof(Ext)/sizeof(Ext[0]); |
| 246 | |
| 247 | osSetCurDir(TmpDir); |
| 248 | |
| 249 | for (i = 0; i < extc; i += 1) { |
| 250 | on = strPrintf("%s.%s", bn, Ext[i]); |
| 251 | osFileRemove(on); |
| 252 | } |
| 253 | osFileRemove(bn); |
| 254 | |
| 255 | osSetCurDir(OldCurDir); |
| 256 | } |
| 257 | |
| 258 | |
| 259 | |
| 260 | |
| 261 | void |
| 262 | testAldorScript(fn) |
| 263 | String fn; |
| 264 | { |
| 265 | String bn = osFileBase(fn); |
| 266 | String fname = strConcat(bn, ".sh"); |
| 267 | String Rname = strConcat(bn, ".shR"); |
| 268 | String TRname = osFileCombine(TmpDir, Rname); |
| 269 | String ORname = osFileCombine(OutDir, Rname); |
| 270 | |
| 271 | fprintf(stdout, ">> %s: (script) ", fname); |
| 272 | fflush(stdout); |
| 273 | |
| 274 | osPutEnv(strPrintf("TMPDIR=%s", TmpDir)); |
| 275 | if (osRunScript(fname, TRname) != 0) { |
| 276 | fprintf(stdout, "ERROR\n"); |
| 277 | failv[failc++] = fname; |
| 278 | } |
| 279 | else if (strEqual(Action, "show")) { |
| 280 | fnewline(stdout); |
| 281 | osFileCat(TRname); |
| 282 | } |
| 283 | else if (strEqual(Action, "install")) { |
| 284 | fprintf(stdout, "\n>> Installing result file %s\n", ORname); |
| 285 | osFileCopy(TRname, ORname); |
| 286 | } |
| 287 | else if (osFileEqual(ORname, TRname)) { |
| 288 | fprintf(stdout, "OK\n"); |
| 289 | } |
| 290 | else { |
| 291 | fprintf(stdout, "DIFFERENT\n"); |
| 292 | osShowDiff(ORname, TRname); |
| 293 | failv[failc++] = fname; |
| 294 | } |
| 295 | |
| 296 | osFileRemove(TRname); |
| 297 | osSetCurDir(OldCurDir); |
| 298 | } |
| 299 | |
| 300 | |
| 301 | |
| 302 | |
| 303 | typedef void (*TaxFun) _OF((String, String)); |
| 304 | |
| 305 | struct tax_info { |
| 306 | String tag; |
| 307 | TaxFun fn; |
| 308 | }; |
| 309 | |
| 310 | struct tax_info taxInfoTable[] = { |
| 311 | { "testcomp", testAldorCompile }, |
| 312 | { "testrun", testAldorRun }, |
| 313 | { "testint", testAldorInterpret }, |
| 314 | { "testerrs", testAldorErrors }, |
| 315 | { "testphase", testAldorPhase }, |
| 316 | { "testgen", testAldorGenerate } |
| 317 | }; |
| 318 | |
| 319 | #define TaxInfoTag(i) (taxInfoTable[i].tag) |
| 320 | #define TaxInfoFun(i) (taxInfoTable[i].fn) |
| 321 | |
| 322 | void |
| 323 | testAldorDispatch(args, fn) |
| 324 | String args; |
| 325 | String fn; |
| 326 | { |
| 327 | Length i, taxc = sizeof(taxInfoTable) / sizeof(taxInfoTable[0]); |
| 328 | |
| 329 | for (i = 0; i < taxc; i += 1) |
| 330 | if (strIsPrefix(TaxInfoTag(i), args)) { |
| 331 | args += strlen(TaxInfoTag(i)); |
| 332 | TaxInfoFun(i)(args, fn); |
| 333 | testAldorClean(fn); |
| 334 | return; |
| 335 | } |
| 336 | } |
| 337 | |
| 338 | |
| 339 | |
| 340 | |
| 341 | void |
| 342 | testAldorCompile(args, fn) |
| 343 | String args; |
| 344 | String fn; |
| 345 | { |
| 346 | String bn = osFileBase(fn); |
| 347 | String fname = strConcat(bn, ".as"); |
| 348 | String Bname = strConcat(bn, ".ao"); |
| 349 | String Sname = strConcat(bn, ".fm"); |
| 350 | String TBname = osFileCombine(TmpDir, Bname); |
| 351 | String TSname = osFileCombine(TmpDir, Sname); |
| 352 | String OBname = osFileCombine(OutDir, Bname); |
| 353 | String TNSname = osFileCombine(TmpDir, strPrintf("new-%s", Sname)); |
| 354 | String TSSname = osFileCombine(TmpDir, strPrintf("std-%s", Sname)); |
| 355 | String cmd; |
| 356 | |
| 357 | fprintf(stdout, ">> %s: (compilation) ", fname); |
| 358 | fflush(stdout); |
| 359 | |
| 360 | cmd = strPrintf("%s -R %s %s %s", |
| 361 | Aldor, TmpDir, args, fname); |
| 362 | if (osRunOutput(cmd, NULL) != 0) { |
| 363 | fprintf(stdout, "ERROR\n"); |
| 364 | failv[failc++] = fname; |
| 365 | } |
| 366 | else if (strEqual(Action, "show")) { |
| 367 | fnewline(stdout); |
| 368 | cmd = strPrintf("%s -R %s -F fm %s", Aldor, TmpDir, TBname); |
| 369 | osRunOutput(cmd, NULL); |
| 370 | osFileCat(TSname); |
| 371 | osFileRemove(TSname); |
| 372 | } |
| 373 | else if (strEqual(Action, "install")) { |
| 374 | fprintf(stdout, "\n>> Installing result file %s\n", OBname); |
| 375 | osFileCopy(TBname, OBname); |
| 376 | } |
| 377 | else if (osFileEqual(OBname, TBname)) { |
| 378 | fprintf(stdout, "OK\n"); |
| 379 | } |
| 380 | else { |
| 381 | fprintf(stdout, "(not identical) "); |
| 382 | fflush(stdout); |
| 383 | |
| 384 | cmd = strPrintf("%s -R %s -F fm %s", |
| 385 | Aldor, TmpDir, TBname); |
| 386 | osRunOutput(cmd, NULL); |
| 387 | osFileCopy(TSname, TNSname); |
| 388 | osFileRemove(TSname); |
| 389 | |
| 390 | cmd = strPrintf("%s -R %s -F fm %s", |
| 391 | OAldor, TmpDir, OBname); |
| 392 | osRunOutput(cmd, NULL); |
| 393 | osFileCopy(TSname, TSSname); |
| 394 | osFileRemove(TSname); |
| 395 | |
| 396 | if (osFileEqual(TSSname, TNSname)) { |
| 397 | fprintf(stdout, "OK\n"); |
| 398 | } |
| 399 | else { |
| 400 | fprintf(stdout, "DIFFERENT\n"); |
| 401 | osShowDiff(TSSname, TNSname); |
| 402 | failv[failc++] = fname; |
| 403 | } |
| 404 | osFileRemove(TNSname); |
| 405 | osFileRemove(TSSname); |
| 406 | } |
| 407 | |
| 408 | osFileRemove(TBname); |
| 409 | osSetCurDir(OldCurDir); |
| 410 | } |
| 411 | |
| 412 | |
| 413 | |
| 414 | |
| 415 | void |
| 416 | testAldorRun(args, fn) |
| 417 | String args; |
| 418 | String fn; |
| 419 | { |
| 420 | String bn = osFileBase(fn); |
| 421 | String fname = strConcat(bn, ".as"); |
| 422 | String Tname = strConcat(bn, ".out"); |
| 423 | String OTname = osFileCombine(OutDir, Tname); |
| 424 | String Pfname = osFileCombine(OldCurDir, fname); |
| 425 | String POname = osFileCombine(OldCurDir, OTname); |
| 426 | String cmd; |
| 427 | |
| 428 | fprintf(stdout, ">> %s: (execution) ", fname); |
| 429 | fflush(stdout); |
| 430 | |
| 431 | osSetCurDir(TmpDir); |
| 432 | |
| 433 | |
| 434 | cmd = strPrintf("%s -M base=%s%s -Ccc=\"%s\" -grun %s %s", |
| 435 | Aldor, OldCurDir, OS_PATH_SEP, CC, args, Pfname); |
| 436 | |
| 437 | if (osRunOutput(cmd, Tname) != 0) { |
| 438 | fprintf(stdout, "ERROR\n"); |
| 439 | failv[failc++] = fname; |
| 440 | osFileCat(Tname); |
| 441 | } |
| 442 | else if (strEqual(Action, "show")) { |
| 443 | fnewline(stdout); |
| 444 | osFileCat(Tname); |
| 445 | } |
| 446 | else if (strEqual(Action, "install")) { |
| 447 | fprintf(stdout, "\n>> Installing result file %s\n", OTname); |
| 448 | osFileCopy(Tname, POname); |
| 449 | } |
| 450 | else if (osFileEqual(POname, Tname)) { |
| 451 | fprintf(stdout, "OK\n"); |
| 452 | } |
| 453 | else { |
| 454 | fprintf(stdout, "DIFFERENT\n"); |
| 455 | fflush(stdout); |
| 456 | osShowDiff(POname, Tname); |
| 457 | failv[failc++] = fname; |
| 458 | } |
| 459 | |
| 460 | osFileRemove(Tname); |
| 461 | osSetCurDir(OldCurDir); |
| 462 | } |
| 463 | |
| 464 | |
| 465 | |
| 466 | |
| 467 | void |
| 468 | testAldorInterpret(args, fn) |
| 469 | String args; |
| 470 | String fn; |
| 471 | { |
| 472 | String bn = osFileBase(fn); |
| |
| 9 | | Returned allocated memory | |
|
| 473 | String fname = strConcat(bn, ".as"); |
| 474 | String Tname = strConcat(bn, ".out"); |
| 10 | | Potential leak of memory pointed to by 'bn' |
|
| 475 | String OTname = osFileCombine(OutDir, Tname); |
| 476 | String Pfname = osFileCombine(OldCurDir, fname); |
| 477 | String POname = osFileCombine(OldCurDir, OTname); |
| 478 | String cmd; |
| 479 | |
| 480 | fprintf(stdout, ">> %s: (interpreting) ", fname); |
| 481 | fflush(stdout); |
| 482 | |
| 483 | osSetCurDir(TmpDir); |
| 484 | |
| 485 | |
| 486 | cmd = strPrintf("%s -M base=%s%s -ginterp %s %s", |
| 487 | Aldor, OldCurDir, OS_PATH_SEP, args, Pfname); |
| 488 | |
| 489 | if (osRunOutput(cmd, Tname) != 0) { |
| 490 | fprintf(stdout, "ERROR\n"); |
| 491 | failv[failc++] = fname; |
| 492 | osFileCat(Tname); |
| 493 | } |
| 494 | else if (strEqual(Action, "show")) { |
| 495 | fnewline(stdout); |
| 496 | osFileCat(Tname); |
| 497 | } |
| 498 | else if (strEqual(Action, "install")) { |
| 499 | fprintf(stdout, "\n>> Installing result file %s\n", OTname); |
| 500 | osFileCopy(Tname, POname); |
| 501 | } |
| 502 | else if (osFileEqual(POname, Tname)) { |
| 503 | fprintf(stdout, "OK\n"); |
| 504 | } |
| 505 | else { |
| 506 | fprintf(stdout, "DIFFERENT\n"); |
| 507 | osShowDiff(POname, Tname); |
| 508 | failv[failc++] = fname; |
| 509 | } |
| 510 | |
| 511 | osFileRemove(Tname); |
| 512 | osSetCurDir(OldCurDir); |
| 513 | } |
| 514 | |
| 515 | |
| 516 | |
| 517 | |
| 518 | void |
| 519 | testAldorErrors(args, fn) |
| 520 | String args; |
| 521 | String fn; |
| 522 | { |
| 523 | String bn = osFileBase(fn); |
| 524 | String fname = strConcat(bn, ".as"); |
| 525 | String Ename = strConcat(bn, ".E"); |
| 526 | String Bname = strConcat(bn, ".ao"); |
| 527 | String TEname = osFileCombine(TmpDir, Ename); |
| 528 | String OEname = osFileCombine(OutDir, Ename); |
| 529 | String TBname = osFileCombine(TmpDir, Bname); |
| 530 | String cmd; |
| 531 | |
| 532 | fprintf(stdout, ">> %s: (error report) ", fname); |
| 533 | fflush(stdout); |
| 534 | |
| 535 | cmd = strPrintf("%s -M2 -D TestErrorsToo -R %s %s %s", |
| 536 | Aldor, TmpDir, args, fn); |
| 537 | osRunOutput(cmd, TEname); |
| 538 | |
| 539 | if (strEqual(Action, "show")) { |
| 540 | fnewline(stdout); |
| 541 | osFileCat(TEname); |
| 542 | } |
| 543 | else if (strEqual(Action, "install")) { |
| 544 | fprintf(stdout, "\n>> Installing result file %s\n", OEname); |
| 545 | osFileCopy(TEname, OEname); |
| 546 | } |
| 547 | else if (osFileEqual(OEname, TEname)) { |
| 548 | fprintf(stdout, "OK\n"); |
| 549 | } |
| 550 | else { |
| 551 | fprintf(stdout, "DIFFERENT\n"); |
| 552 | osShowDiff(OEname, TEname); |
| 553 | failv[failc++] = fname; |
| 554 | } |
| 555 | |
| 556 | osFileRemove(TEname); |
| 557 | osFileRemove(TBname); |
| 558 | osSetCurDir(OldCurDir); |
| 559 | } |
| 560 | |
| 561 | |
| 562 | |
| 563 | |
| 564 | void |
| 565 | testAldorPhase(args, fn) |
| 566 | String args; |
| 567 | String fn; |
| 568 | { |
| 569 | String bn = osFileBase(fn); |
| 570 | String fname = strConcat(bn, ".as"); |
| 571 | String Rname = strConcat(bn, ".R"); |
| 572 | String Bname = strConcat(bn, ".ao"); |
| 573 | String TRname = osFileCombine(TmpDir, Rname); |
| 574 | String ORname = osFileCombine(OutDir, Rname); |
| 575 | String TBname = osFileCombine(TmpDir, Bname); |
| 576 | String cmd; |
| 577 | |
| 578 | while (args[0] == ' ') args++; |
| 579 | |
| 580 | fprintf(stdout, ">> %s: (phase %s) ", fname, args); |
| 581 | fflush(stdout); |
| 582 | |
| 583 | cmd = strPrintf("%s -WTrt+%s -R %s %s", |
| 584 | Aldor, args, TmpDir, fname); |
| 585 | osRunOutput(cmd, TRname); |
| 586 | |
| 587 | if (strEqual(Action, "show")) { |
| 588 | fnewline(stdout); |
| 589 | osFileCat(TRname); |
| 590 | } |
| 591 | else if (strEqual(Action, "install")) { |
| 592 | fprintf(stdout, "\n>> Installing result file %s\n", ORname); |
| 593 | osFileCopy(TRname, ORname); |
| 594 | } |
| 595 | else if (osFileEqual(ORname, TRname)) { |
| 596 | fprintf(stdout, "OK\n"); |
| 597 | } |
| 598 | else { |
| 599 | fprintf(stdout, "DIFFERENT\n"); |
| 600 | osShowDiff(ORname, TRname); |
| 601 | failv[failc++] = fname; |
| 602 | } |
| 603 | |
| 604 | osFileRemove(TRname); |
| 605 | osFileRemove(TBname); |
| 606 | osSetCurDir(OldCurDir); |
| 607 | } |
| 608 | |
| 609 | |
| 610 | |
| 611 | |
| 612 | |
| 613 | void |
| 614 | testAldorGenerate(args, fn) |
| 615 | String args; |
| 616 | String fn; |
| 617 | { |
| 618 | String bn = osFileBase(fn); |
| 619 | String fname = strConcat(bn, ".as"); |
| 620 | String Bname = strConcat(bn, ".ao"); |
| 621 | String TBname = osFileCombine(TmpDir, Bname); |
| 622 | String Gname, TGname, OGname; |
| 623 | String fext, cmd; |
| 624 | |
| 625 | while (args[0] == ' ') args++; |
| 626 | |
| 627 | switch (args[0]) { |
| 628 | case 'i': fext = "ai"; break; |
| 629 | case 'a': fext = "ax"; break; |
| 630 | case 'o': fext = "ao"; break; |
| 631 | case 'y': fext = "asy"; break; |
| 632 | case 'f': fext = "fm"; break; |
| 633 | case 'c': fext = "c"; break; |
| 634 | case 'l': fext = "lsp"; break; |
| 635 | default: fext = "unk"; break; |
| 636 | } |
| 637 | args++; |
| 638 | while (args[0] == ' ') args++; |
| 639 | |
| 640 | fprintf(stdout, ">> %s: (generation .%s) ", fname, fext); |
| 641 | fflush(stdout); |
| 642 | |
| 643 | Gname = strPrintf("%s.%s", bn, fext); |
| 644 | TGname = osFileCombine(TmpDir, Gname); |
| 645 | OGname = osFileCombine(OutDir, Gname); |
| 646 | |
| 647 | cmd = strPrintf("%s -F %s -R %s %s %s", |
| 648 | Aldor, fext, TmpDir, args, fn); |
| 649 | |
| 650 | if (osRunOutput(cmd, NULL) != 0) { |
| 651 | fprintf(stdout, "ERROR\n"); |
| 652 | failv[failc++] = fname; |
| 653 | } |
| 654 | else if (strEqual(Action, "show")) { |
| 655 | fnewline(stdout); |
| 656 | osFileCat(TGname); |
| 657 | } |
| 658 | else if (strEqual(Action, "install")) { |
| 659 | fprintf(stdout, "\n>> Installing result file %s\n", OGname); |
| 660 | osFileCopy(TGname, OGname); |
| 661 | } |
| 662 | else if (osFileEqual(OGname, TGname)) { |
| 663 | fprintf(stdout, "OK\n"); |
| 664 | } |
| 665 | else { |
| 666 | fprintf(stdout, "DIFFERENT\n"); |
| 667 | osShowDiff(OGname, TGname); |
| 668 | failv[failc++] = fname; |
| 669 | } |
| 670 | |
| 671 | osFileRemove(TGname); |
| 672 | osFileRemove(TBname); |
| 673 | osSetCurDir(OldCurDir); |
| 674 | } |
| 675 | |
| 676 | |
| 677 | |
| 678 | |
| 679 | |
| 680 | |
| 681 | |
| 682 | void |
| 683 | testAldorInit() |
| 684 | { |
| 685 | Length cc = BUFLEN, rc; |
| 686 | String buf = strAlloc(cc); |
| 687 | |
| 688 | rc = osGetCurDir(buf, cc); |
| 689 | if (rc != 0) exitFailure(); |
| 690 | |
| 691 | OldCurDir = strCopy(buf); |
| 692 | TmpDir = osTempDirName(); |
| 693 | OutDir = osFileCombine("..", "testout"); |
| 694 | |
| 695 | Aldor = "aldor "; |
| 696 | OAldor = "aldor "; |
| 697 | CC = "unicl"; |
| 698 | |
| 699 | Kind = "all"; |
| 700 | KindAct = 1; |
| 701 | Action = "compare"; |
| 702 | |
| 703 | if (signal(SIGINT, testAldorFini) == SIG_ERR) exitFailure(); |
| 704 | if (signal(SIGABRT, testAldorFini) == SIG_ERR) exitFailure(); |
| 705 | if (signal(SIGTERM, testAldorFini) == SIG_ERR) exitFailure(); |
| 706 | #if SIGQUIT != SIGFAKE |
| 707 | if (signal(SIGQUIT, testAldorFini) == SIG_ERR) exitFailure(); |
| 708 | #endif |
| 709 | |
| 710 | osMakeDir(TmpDir); |
| 711 | } |
| 712 | |
| 713 | void |
| 714 | testAldorCleanup() |
| 715 | { |
| 716 | osRemoveDir(TmpDir); |
| 717 | } |
| 718 | |
| 719 | void |
| 720 | testAldorFini(sig) |
| 721 | int sig; |
| 722 | { |
| 723 | fprintf(stdout, "testAldor: Removing temporary directory %s\n", TmpDir); |
| 724 | osSetCurDir(OldCurDir); |
| 725 | testAldorCleanup(); |
| 726 | exitFailure(); |
| 727 | } |
| 728 | |
| 729 | Length |
| 730 | testAldorArgs(argc, argv) |
| 731 | Length argc; |
| 732 | String *argv; |
| 733 | { |
| 734 | Length i; |
| 735 | |
| 736 | for (i = 1; i < argc; i += 1) { |
| 737 | if (strEqual(argv[i], "-help")) { |
| 738 | testAldorHelp(); |
| 739 | exitSuccess(); |
| 740 | } |
| 741 | else if (strEqual(argv[i], "-compare")) |
| 742 | Action = "compare"; |
| 743 | else if (strEqual(argv[i], "-debug")) |
| 744 | debug = 1; |
| 745 | else if (strEqual(argv[i], "-install")) |
| 746 | Action = "install"; |
| 747 | else if (strEqual(argv[i], "-show")) |
| 748 | Action = "show"; |
| 749 | else if (strEqual(argv[i], "-oldaldor")) |
| 750 | OAldor = strCopy(argv[++i]); |
| 751 | else if (strEqual(argv[i], "-aldor")) |
| 752 | Aldor = strCopy(argv[++i]); |
| 753 | else if (strEqual(argv[i], "-cc")) |
| 754 | CC = strCopy(argv[++i]); |
| 755 | else if (strEqual(argv[i], "-only")) { |
| 756 | Kind = strCopy(argv[++i]); |
| 757 | KindAct = 1; |
| 758 | } |
| 759 | else if (strEqual(argv[i], "-but")) { |
| 760 | Kind = strCopy(argv[++i]); |
| 761 | KindAct = 0; |
| 762 | } |
| 763 | else |
| 764 | break; |
| 765 | } |
| 766 | |
| 767 | return i; |
| 768 | } |
| 769 | |
| 770 | void |
| 771 | testAldorGlean(argc, argv) |
| 772 | Length argc; |
| 773 | String *argv; |
| 774 | { |
| 775 | Length i, cc = BUFLEN; |
| 776 | String buf = strAlloc(cc); |
| 777 | |
| 778 | for (i = 0; i < argc; i += 1) { |
| 779 | if (!osFileIsThere(argv[i])) continue; |
| 780 | OutDir = testAldorOutDirForTest(argv[i]); |
| 781 | fprintf(stderr, "Outdir: %s\n", OutDir); |
| 782 | if (strIsSuffix(".as", argv[i])) { |
| 783 | FILE * argi; |
| 784 | String key = "\n--> "; |
| 785 | Int state = 1, j = 0; |
| 786 | Int c, k; |
| 787 | |
| 788 | argi = fopen(argv[i], "r"); |
| 789 | if (argi == NULL) exitFailure(); |
| 790 | |
| 791 | while ((c = fgetc(argi)) != EOF) { |
| 792 | if ((k = key[state]) != '\0') { |
| 793 | if (c == k) |
| 794 | state += 1; |
| 795 | else if (c == key[0]) |
| 796 | state = 1; |
| 797 | else |
| 798 | state = 0; |
| 799 | } |
| 800 | else if (c == '\n') { |
| 801 | buf[j] = '\0'; |
| 802 | if (testAldorFilter(buf)) { |
| 803 | testAldorDispatch(buf, argv[i]); |
| 804 | } |
| 805 | state = 1; |
| 806 | j = 0; |
| 807 | } |
| 808 | else |
| 809 | buf[j++] = c; |
| 810 | } |
| 811 | fclose(argi); |
| 812 | } |
| 813 | else if (strIsSuffix(".sh", argv[i])) { |
| 814 | if (testAldorFilter("testscript")) |
| 815 | testAldorScript(argv[i]); |
| 816 | } |
| 817 | free(OutDir); |
| 818 | OutDir = NULL; |
| 819 | } |
| 820 | } |
| 821 | |
| 822 | String |
| 823 | testAldorOutDirForTest(fname) |
| 824 | String fname; |
| 825 | { |
| 826 | String dir = osFileDirName(fname); |
| 827 | String base = osFileBase(fname); |
| 828 | if (dir == NULL) { |
| 829 | return osFileCombine("..", "testout"); |
| 830 | } |
| 831 | else { |
| 832 | String backOne = osFileCombine(dir, ".."); |
| 833 | String outDir = osFileCombine(backOne, "testout"); |
| 834 | free(backOne); |
| 835 | return outDir; |
| 836 | } |
| 837 | } |
| 838 | |
| 839 | |
| 840 | Int |
| 841 | testAldorFilter(buf) |
| 842 | String buf; |
| 843 | { |
| 844 | if (strEqual(Kind, "all")) |
| 845 | return 1; |
| 846 | else |
| 847 | return KindAct == (strncmp(buf, Kind, strlen(Kind)) == 0); |
| 848 | } |
| 849 | |
| 850 | int |
| 851 | main(argc, argv) |
| 852 | int argc; |
| 853 | String *argv; |
| 854 | { |
| 855 | Length i; |
| 856 | |
| 857 | testAldorInit(); |
| 858 | |
| 859 | i = testAldorArgs(argc, argv); |
| 860 | argc -= i; |
| 861 | argv += i; |
| 862 | testAldorGlean(argc, argv); |
| 863 | |
| 864 | if (failc == 0) { |
| 865 | fprintf(stdout, ">> No tests failed\n"); |
| 866 | testAldorCleanup(); |
| 867 | exitSuccess(); |
| 868 | } |
| 869 | else { |
| 870 | fprintf(stdout, ">> Failed tests:"); |
| 871 | for (i = 0; i < failc; i += 1) |
| 872 | fprintf(stdout, " %s", failv[i]); |
| 873 | fnewline(stdout); |
| 874 | testAldorCleanup(); |
| 875 | exitFailure(); |
| 876 | } |
| 877 | } |