#include #include #include #include #include #include #include "Compiler.h" #include "Script.h" #include "Tokenizer.h" static int doneTests = 0; static int allTests = 0; static char path[PATH_MAX] = {'\0'}; static int pathIndex = 0; #define TEST_BUFFER_LENGTH (1024 * 2) static char testBuffer[TEST_BUFFER_LENGTH]; static int testBufferIndex = 0; static void tsAddBufferIndex(int length) { testBufferIndex += length; if(testBufferIndex > TEST_BUFFER_LENGTH) { testBufferIndex = TEST_BUFFER_LENGTH; } } static bool tsPrinter(Object* o) { if(testBufferIndex >= TEST_BUFFER_LENGTH) { return true; } if(o->type == OT_INT) { int leftBytes = TEST_BUFFER_LENGTH - testBufferIndex; tsAddBufferIndex(snprintf(testBuffer + testBufferIndex, leftBytes, "%d\n", o->data.intValue)); return false; } return true; } static void tsAppend(const char* s) { for(int i = 0; pathIndex < (PATH_MAX - 1) && s[i] != '\0'; i++) { path[pathIndex++] = s[i]; } path[pathIndex] = '\0'; } static int tsEnter(const char* s) { int marker = pathIndex; tsAppend("/"); tsAppend(s); return marker; } static void tsReset(int marker) { path[marker] = '\0'; pathIndex = marker; } static void tsCompareResults(FILE* file) { for(int i = 0; i < testBufferIndex; i++) { char a = fgetc(file); char b = testBuffer[i]; if(a != b) { printf("error in '%s': expected %c, got:\n%s", path, a, testBuffer + i); return; } } if(fgetc(file) != EOF) { printf("error in '%s': no full read\n", path); return; } doneTests++; } static void tsCheckScript(Script* sc) { testBufferIndex = 0; sRun(sc); tsAppend(".out"); FILE* file = fopen(path, "r"); if(file == NULL) { printf("cannot open result file '%s'\n", path); return; } tsCompareResults(file); fclose(file); } static void tsCheckFile() { allTests++; if(tTokenize(path)) { puts(tGetError()); return; } int codeLength; unsigned char* code = cCompile(&codeLength); if(code == NULL) { puts(cGetError()); return; } Script* sc = sInit(code, codeLength); tsCheckScript(sc); sDelete(sc); } static void tsScanDirectory() { DIR* dir = opendir(path); if(dir == NULL) { printf("cannot open '%s': %s\n", path, strerror(errno)); return; } while(true) { struct dirent* e = readdir(dir); if(e == NULL) { return; } else if(strcmp(e->d_name, ".") == 0 || strcmp(e->d_name, "..") == 0) { continue; } else if(e->d_type == DT_DIR) { int marker = tsEnter(e->d_name); tsScanDirectory(); tsReset(marker); } else if(e->d_type == DT_REG && strchr(e->d_name, '.') == NULL) { int marker = tsEnter(e->d_name); tsCheckFile(); tsReset(marker); } } if(closedir(dir)) { printf("cannot close '%s': %s\n", path, strerror(errno)); } } /*static String readLine(std::ifstream& f) { String s; while(true) { char c = f.get(); if(!f.good() || c == '\n') { break; } s += c; } return s; } static bool testTokenizer(const String& input, const String& output) { tests++; std::ifstream oStream; oStream.open(output); if(!oStream.good()) { std::cout << "cannot open file '" << output << "'\n"; return true; } TokenStream tokenStream; if(Tokenizer::tokenize(tokenStream, input)) { return true; } while(true) { String expected = readLine(oStream); if(expected.getLength() == 0) { break; } else if(!tokenStream.hasToken()) { std::cout << "error in '" << input << "\n'out of tokens\n"; return false; } String buffer = tokenStream.nextTokenString(); if(strchr(buffer, '\n') != nullptr) { expected += '\n'; expected += readLine(oStream); } if(strcmp(buffer, expected) != 0) { std::cout << "error in '" << input << "\n'" << buffer << "' should be '" << expected << "'\n"; return false; } } done++; return false; }*/ void tsStart(const char* path) { sSetPrinter(tsPrinter); doneTests = 0; allTests = 0; tsAppend(path); tsScanDirectory(); printf("%d / %d tests succeeded\n", doneTests, allTests); }