1 #include "testing.h"
2 #include "../../runtime/terminator.h"
3 #include <algorithm>
4 #include <cstdarg>
5 #include <cstdio>
6 #include <cstring>
7 #include <string>
8 
9 static int failures{0};
10 
11 // Override the Fortran runtime's Crash() for testing purposes
CatchCrash(const char * sourceFile,int sourceLine,const char * message,va_list & ap)12 [[noreturn]] static void CatchCrash(
13     const char *sourceFile, int sourceLine, const char *message, va_list &ap) {
14   char buffer[1000];
15   std::vsnprintf(buffer, sizeof buffer, message, ap);
16   va_end(ap);
17   llvm::errs() << (sourceFile ? sourceFile : "unknown source file") << '('
18                << sourceLine << "): CRASH: " << buffer << '\n';
19   throw std::string{buffer};
20 }
21 
StartTests()22 void StartTests() {
23   Fortran::runtime::Terminator::RegisterCrashHandler(CatchCrash);
24 }
25 
Fail()26 llvm::raw_ostream &Fail() {
27   ++failures;
28   return llvm::errs();
29 }
30 
EndTests()31 int EndTests() {
32   if (failures == 0) {
33     llvm::outs() << "PASS\n";
34   } else {
35     llvm::outs() << "FAIL " << failures << " tests\n";
36   }
37   return failures != 0;
38 }
39 
SetCharacter(char * to,std::size_t n,const char * from)40 void SetCharacter(char *to, std::size_t n, const char *from) {
41   auto len{std::strlen(from)};
42   std::memcpy(to, from, std::min(len, n));
43   if (len < n) {
44     std::memset(to + len, ' ', n - len);
45   }
46 }
47