1240116Smarcel// 2240116Smarcel// Automated Testing Framework (atf) 3240116Smarcel// 4240116Smarcel// Copyright (c) 2009 The NetBSD Foundation, Inc. 5240116Smarcel// All rights reserved. 6240116Smarcel// 7240116Smarcel// Redistribution and use in source and binary forms, with or without 8240116Smarcel// modification, are permitted provided that the following conditions 9240116Smarcel// are met: 10240116Smarcel// 1. Redistributions of source code must retain the above copyright 11240116Smarcel// notice, this list of conditions and the following disclaimer. 12240116Smarcel// 2. Redistributions in binary form must reproduce the above copyright 13240116Smarcel// notice, this list of conditions and the following disclaimer in the 14240116Smarcel// documentation and/or other materials provided with the distribution. 15240116Smarcel// 16240116Smarcel// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17240116Smarcel// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18240116Smarcel// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19240116Smarcel// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20240116Smarcel// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21240116Smarcel// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22240116Smarcel// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23240116Smarcel// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24240116Smarcel// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25240116Smarcel// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26240116Smarcel// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27240116Smarcel// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28240116Smarcel// 29240116Smarcel 30240116Smarcelextern "C" { 31240116Smarcel#include <regex.h> 32240116Smarcel} 33240116Smarcel 34240116Smarcel#include <fstream> 35240116Smarcel#include <iostream> 36240116Smarcel#include <string> 37240116Smarcel#include <vector> 38240116Smarcel 39240116Smarcel#include "../check.hpp" 40240116Smarcel#include "../config.hpp" 41240116Smarcel#include "../macros.hpp" 42240116Smarcel 43240116Smarcel#include "fs.hpp" 44240116Smarcel#include "process.hpp" 45240116Smarcel#include "test_helpers.hpp" 46240116Smarcel 47240116Smarcelvoid 48240116Smarcelbuild_check_cxx_o_aux(const atf::fs::path& sfile, const char* failmsg, 49240116Smarcel const bool expect_pass) 50240116Smarcel{ 51240116Smarcel std::vector< std::string > optargs; 52240116Smarcel optargs.push_back("-I" + atf::config::get("atf_includedir")); 53240116Smarcel optargs.push_back("-Wall"); 54240116Smarcel optargs.push_back("-Werror"); 55240116Smarcel 56240116Smarcel const bool result = atf::check::build_cxx_o( 57240116Smarcel sfile.str(), "test.o", atf::process::argv_array(optargs)); 58240116Smarcel if ((expect_pass && !result) || (!expect_pass && result)) 59240116Smarcel ATF_FAIL(failmsg); 60240116Smarcel} 61240116Smarcel 62240116Smarcelvoid 63240116Smarcelbuild_check_cxx_o(const atf::tests::tc& tc, const char* sfile, 64240116Smarcel const char* failmsg, const bool expect_pass) 65240116Smarcel{ 66240116Smarcel const atf::fs::path sfilepath = 67240116Smarcel atf::fs::path(tc.get_config_var("srcdir")) / sfile; 68240116Smarcel build_check_cxx_o_aux(sfilepath, failmsg, expect_pass); 69240116Smarcel} 70240116Smarcel 71240116Smarcelvoid 72240116Smarcelheader_check(const char *hdrname) 73240116Smarcel{ 74240116Smarcel std::ofstream srcfile("test.c"); 75240116Smarcel ATF_REQUIRE(srcfile); 76240116Smarcel srcfile << "#include <" << hdrname << ">\n"; 77240116Smarcel srcfile.close(); 78240116Smarcel 79240116Smarcel const std::string failmsg = std::string("Header check failed; ") + 80240116Smarcel hdrname + " is not self-contained"; 81240116Smarcel build_check_cxx_o_aux(atf::fs::path("test.c"), failmsg.c_str(), true); 82240116Smarcel} 83240116Smarcel 84240116Smarcelatf::fs::path 85251108Smarcelget_process_helpers_path(const atf::tests::tc& tc, bool is_detail) 86240116Smarcel{ 87251108Smarcel if (is_detail) 88251108Smarcel return atf::fs::path(tc.get_config_var("srcdir")) / 89251108Smarcel ".." / ".." / "atf-c" / "detail" / "process_helpers"; 90251108Smarcel else 91251108Smarcel return atf::fs::path(tc.get_config_var("srcdir")) / 92251108Smarcel ".." / "atf-c" / "detail" / "process_helpers"; 93240116Smarcel} 94240116Smarcel 95240116Smarcelbool 96240116Smarcelgrep_file(const char* name, const char* regex) 97240116Smarcel{ 98240116Smarcel std::ifstream is(name); 99240116Smarcel ATF_REQUIRE(is); 100240116Smarcel 101240116Smarcel bool found = false; 102240116Smarcel 103240116Smarcel std::string line; 104240116Smarcel std::getline(is, line); 105240116Smarcel while (!found && is.good()) { 106240116Smarcel if (grep_string(line, regex)) 107240116Smarcel found = true; 108240116Smarcel else 109240116Smarcel std::getline(is, line); 110240116Smarcel } 111240116Smarcel 112240116Smarcel return found; 113240116Smarcel} 114240116Smarcel 115240116Smarcelbool 116240116Smarcelgrep_string(const std::string& str, const char* regex) 117240116Smarcel{ 118240116Smarcel int res; 119240116Smarcel regex_t preg; 120240116Smarcel 121240116Smarcel std::cout << "Looking for '" << regex << "' in '" << str << "'\n"; 122240116Smarcel ATF_REQUIRE(::regcomp(&preg, regex, REG_EXTENDED) == 0); 123240116Smarcel 124240116Smarcel res = ::regexec(&preg, str.c_str(), 0, NULL, 0); 125240116Smarcel ATF_REQUIRE(res == 0 || res == REG_NOMATCH); 126240116Smarcel 127240116Smarcel ::regfree(&preg); 128240116Smarcel 129240116Smarcel return res == 0; 130240116Smarcel} 131240116Smarcel 132240116Smarcelvoid 133240116Smarceltest_helpers_detail::check_equal(const char* expected[], 134240116Smarcel const string_vector& actual) 135240116Smarcel{ 136240116Smarcel const char** expected_iter = expected; 137240116Smarcel string_vector::const_iterator actual_iter = actual.begin(); 138240116Smarcel 139240116Smarcel bool equals = true; 140240116Smarcel while (equals && *expected_iter != NULL && actual_iter != actual.end()) { 141240116Smarcel if (*expected_iter != *actual_iter) { 142240116Smarcel equals = false; 143240116Smarcel } else { 144240116Smarcel expected_iter++; 145240116Smarcel actual_iter++; 146240116Smarcel } 147240116Smarcel } 148240116Smarcel if (equals && ((*expected_iter == NULL && actual_iter != actual.end()) || 149240116Smarcel (*expected_iter != NULL && actual_iter == actual.end()))) 150240116Smarcel equals = false; 151240116Smarcel 152240116Smarcel if (!equals) { 153240116Smarcel std::cerr << "EXPECTED:\n"; 154240116Smarcel for (expected_iter = expected; *expected_iter != NULL; expected_iter++) 155240116Smarcel std::cerr << *expected_iter << "\n"; 156240116Smarcel 157240116Smarcel std::cerr << "ACTUAL:\n"; 158240116Smarcel for (actual_iter = actual.begin(); actual_iter != actual.end(); 159240116Smarcel actual_iter++) 160240116Smarcel std::cerr << *actual_iter << "\n"; 161240116Smarcel 162240116Smarcel ATF_FAIL("Expected results differ to actual values"); 163240116Smarcel } 164240116Smarcel} 165