#include "runtime/helpers/read_test_entries.h" #include #include #include #include #ifdef USE_BOOST_REGEX #include "boost/regex.hpp" using boost::regex; using boost::regex_search; using boost::regex_replace; using boost::smatch; using boost::regex_constants::extended; #else #include using std::regex; using std::regex_search; using std::regex_replace; using std::smatch; using std::regex_constants::extended; #endif using std::string; using std::vector; using std::ifstream; using std::istreambuf_iterator; static string trim_output(const string &input) { string result(input); result = regex_replace(result, regex("[\n\t ]+", extended), string(" ")); result = regex_replace(result, regex("^ ", extended), string("")); result = regex_replace(result, regex(" $", extended), string("")); result = regex_replace(result, regex("\\) \\)", extended), string("))")); return result; } static vector get_test_entries_from_string(string content) { regex header_pattern("===+\n" "([^=]+)\n" "===+", extended); regex separator_pattern("---+", extended); vector descriptions; vector bodies; for (;;) { smatch matches; if (!regex_search(content, matches, header_pattern) || matches.empty()) break; string description = matches[1].str(); descriptions.push_back(description); if (!bodies.empty()) bodies.back().erase(matches.position()); content.erase(0, matches.position() + matches[0].length()); bodies.push_back(content); } vector result; for (size_t i = 0; i < descriptions.size(); i++) { string body = bodies[i]; smatch matches; if (regex_search(body, matches, separator_pattern)) { result.push_back({ descriptions[i], body.substr(0, matches.position()), trim_output(body.substr(matches.position() + matches[0].length())) }); } } return result; } static vector list_directory(string dir_name) { vector result; DIR *dir = opendir(dir_name.c_str()); if (!dir) { printf("\nTest error - no such directory '%s'", dir_name.c_str()); return result; } struct dirent *dir_entry; while ((dir_entry = readdir(dir))) { string name(dir_entry->d_name); if (name != "." && name != "..") result.push_back(dir_name + "/" + name); } closedir(dir); return result; } static string src_dir() { const char *dir = getenv("TREESITTER_DIR"); if (!dir) dir = getenv("PWD"); return dir; } vector test_entries_for_language(string language) { vector result; string language_dir = src_dir() + "/spec/runtime/languages/" + language; vector filenames = list_directory(language_dir); for (string &filename : filenames) { ifstream file(filename); std::string content((istreambuf_iterator(file)), istreambuf_iterator()); for (TestEntry &entry : get_test_entries_from_string(content)) result.push_back(entry); } return result; }