add environment funcs (environ.hh) and update test runner code (less verbose/cleaner)

master
Daniel Kolesa 2016-03-13 01:28:39 +00:00
parent 3c708e780d
commit 40746de1c3
2 changed files with 107 additions and 57 deletions

62
ostd/environ.hh 100644
View File

@ -0,0 +1,62 @@
/* Environment handling.
*
* This file is part of OctaSTD. See COPYING.md for futher information.
*/
#ifndef OSTD_ENVIRON_HH
#define OSTD_ENVIRON_HH
#include <stdlib.h>
#include <string.h>
#include "ostd/maybe.hh"
#include "ostd/string.hh"
namespace ostd {
namespace environ {
inline Maybe<ConstCharRange> get(ConstCharRange name) {
char buf[256];
const char *ret = nullptr;
if (name.size() < sizeof(buf)) {
memcpy(buf, name.data(), name.size());
buf[name.size()] = '\0';
ret = getenv(buf);
} else {
ret = getenv(String(name).data());
}
if (!ret) return ostd::nothing;
return ostd::move(ConstCharRange(ret));
}
inline bool set(ConstCharRange name, ConstCharRange value,
bool update = true) {
char sbuf[2048];
char *buf = sbuf;
bool alloc = (name.size() + value.size() + 2) > sizeof(sbuf);
if (alloc)
buf = new char[name.size() + value.size() + 2];
memcpy(buf, name.data(), name.size());
buf[name.size()] = '\0';
memcpy(&buf[name.size() + 1], value.data(), value.size());
buf[name.size() + value.size() + 1] = '\0';
bool ret = !setenv(buf, &buf[name.size() + 1], update);
if (alloc)
delete[] buf;
return ret;
}
inline bool unset(ConstCharRange name) {
char buf[256];
if (name.size() < sizeof(buf)) {
memcpy(buf, name.data(), name.size());
buf[name.size()] = '\0';
return !unsetenv(buf);
}
return !unsetenv(String(name).data());
}
} /* namespace environ */
} /* namespace ostd */
#endif

View File

@ -1,102 +1,90 @@
#include <stdio.h>
#include <stdlib.h>
#include <ostd/platform.hh>
#include <ostd/io.hh>
#include <ostd/string.hh>
#include <ostd/map.hh>
#include <ostd/filesystem.hh>
#include <ostd/environ.hh>
using namespace ostd;
ConstCharRange get_env(ConstCharRange var, ConstCharRange def = nullptr) {
const char *ret = getenv(String(var).data());
if (!ret || !ret[0])
return def;
return ret;
}
#ifndef OSTD_PLATFORM_WIN32
constexpr auto ColorRed = "\033[91m";
constexpr auto ColorGreen = "\033[92m";
constexpr auto ColorBlue = "\033[94m";
constexpr auto ColorBold = "\033[1m";
constexpr auto ColorEnd = "\033[0m";
#else
constexpr auto ColorRed = "";
constexpr auto ColorGreen = "";
constexpr auto ColorBlue = "";
constexpr auto ColorBold = "";
constexpr auto ColorEnd = "";
#endif
int main() {
ConstCharRange compiler = get_env("CXX", "c++");
ConstCharRange cxxflags = "-std=c++14 -Wall -Wextra -Wshadow "
"-Wno-missing-braces " /* clang false positive */
"-I.";
ConstCharRange testdir = get_env("TESTDIR", "tests");
ConstCharRange srcext = ".cc";
/* configurable section */
Map<ConstCharRange, ConstCharRange> colors = {
#ifndef OSTD_PLATFORM_WIN32
{ "red", "\033[91m" },
{ "green", "\033[92m" },
{ "blue", "\033[94m" },
{ "bold", "\033[1m" },
{ "end", "\033[0m" }
#else
{ "red", "" },
{ "green", "" },
{ "blue", "" },
{ "bold", "" },
{ "end", "" }
#endif
};
auto compiler = environ::get("CXX").value_or("c++");
auto cxxflags = "-std=c++14 -Wall -Wextra -Wshadow "
"-Wno-missing-braces " /* clang false positive */
"-I.";
auto testdir = environ::get("TESTDIR").value_or("tests");
auto srcext = ".cc";
auto userflags = environ::get("CXXFLAGS").value_or("");
/* do not change past this point */
ConstCharRange userflags = get_env("CXXFLAGS", "");
int nsuccess = 0, nfailed = 0;
ConstCharRange modname = nullptr;
auto print_result = [&colors, &nsuccess, &nfailed]
(ConstCharRange modname, ConstCharRange fmsg = nullptr) {
auto print_result = [&](ConstCharRange fmsg = nullptr) {
write(modname, "...\t");
if (!fmsg.empty()) {
writeln(colors["red"], colors["bold"], "(", fmsg, ")", colors["end"]);
writeln(ColorRed, ColorBold, "(", fmsg, ")", ColorEnd);
++nfailed;
} else {
writeln(colors["green"], colors["bold"], "(success)", colors["end"]);
writeln(ColorGreen, ColorBold, "(success)", ColorEnd);
++nsuccess;
}
};
DirectoryStream ds(testdir);
for (auto v: ds.iter()) {
if (v.type() != FileType::regular)
continue;
if (v.extension() != srcext)
if ((v.type() != FileType::regular) || (v.extension() != srcext))
continue;
modname = v.stem();
String exepath = testdir;
exepath += PathSeparator;
exepath += v.stem();
exepath += modname;
String cxxcmd = compiler;
cxxcmd += " ";
cxxcmd += testdir;
cxxcmd += PathSeparator;
cxxcmd += v.filename();
cxxcmd += " -o ";
cxxcmd += exepath;
cxxcmd += " ";
cxxcmd += cxxflags;
auto cxxcmd = appender<String>();
format(cxxcmd, "%s %s%s%s -o %s %s", compiler, testdir, PathSeparator,
v.filename(), exepath, cxxflags);
if (!userflags.empty()) {
cxxcmd += " ";
cxxcmd += userflags;
cxxcmd.get() += " ";
cxxcmd.get() += userflags;
}
int ret = system(cxxcmd.data());
int ret = system(cxxcmd.get().data());
if (ret) {
print_result(v.stem(), "compile errror");
print_result("compile errror");
continue;
}
ret = system(exepath.data());
if (ret) {
print_result(v.stem(), "runtime error");
print_result("runtime error");
continue;
}
remove(exepath.data());
print_result(v.stem());
print_result();
}
writeln("\n", colors["blue"], colors["bold"], "testing done:", colors["end"]);
writeln(colors["green"], "SUCCESS: ", nsuccess, colors["end"]);
writeln(colors["red"], "FAILURE: ", nfailed, colors["end"]);
writeln("\n", ColorBlue, ColorBold, "testing done:", ColorEnd);
writeln(ColorGreen, "SUCCESS: ", nsuccess, ColorEnd);
writeln(ColorRed, "FAILURE: ", nfailed, ColorEnd);
}