forked from OctaForge/libostd
add environment funcs (environ.hh) and update test runner code (less verbose/cleaner)
This commit is contained in:
parent
3c708e780d
commit
40746de1c3
62
ostd/environ.hh
Normal file
62
ostd/environ.hh
Normal 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
|
102
test_runner.cc
102
test_runner.cc
|
@ -1,102 +1,90 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <ostd/platform.hh>
|
#include <ostd/platform.hh>
|
||||||
#include <ostd/io.hh>
|
#include <ostd/io.hh>
|
||||||
#include <ostd/string.hh>
|
#include <ostd/string.hh>
|
||||||
#include <ostd/map.hh>
|
#include <ostd/map.hh>
|
||||||
#include <ostd/filesystem.hh>
|
#include <ostd/filesystem.hh>
|
||||||
|
#include <ostd/environ.hh>
|
||||||
|
|
||||||
using namespace ostd;
|
using namespace ostd;
|
||||||
|
|
||||||
ConstCharRange get_env(ConstCharRange var, ConstCharRange def = nullptr) {
|
#ifndef OSTD_PLATFORM_WIN32
|
||||||
const char *ret = getenv(String(var).data());
|
constexpr auto ColorRed = "\033[91m";
|
||||||
if (!ret || !ret[0])
|
constexpr auto ColorGreen = "\033[92m";
|
||||||
return def;
|
constexpr auto ColorBlue = "\033[94m";
|
||||||
return ret;
|
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() {
|
int main() {
|
||||||
ConstCharRange compiler = get_env("CXX", "c++");
|
/* configurable section */
|
||||||
ConstCharRange cxxflags = "-std=c++14 -Wall -Wextra -Wshadow "
|
|
||||||
"-Wno-missing-braces " /* clang false positive */
|
|
||||||
"-I.";
|
|
||||||
ConstCharRange testdir = get_env("TESTDIR", "tests");
|
|
||||||
ConstCharRange srcext = ".cc";
|
|
||||||
|
|
||||||
Map<ConstCharRange, ConstCharRange> colors = {
|
auto compiler = environ::get("CXX").value_or("c++");
|
||||||
#ifndef OSTD_PLATFORM_WIN32
|
auto cxxflags = "-std=c++14 -Wall -Wextra -Wshadow "
|
||||||
{ "red", "\033[91m" },
|
"-Wno-missing-braces " /* clang false positive */
|
||||||
{ "green", "\033[92m" },
|
"-I.";
|
||||||
{ "blue", "\033[94m" },
|
auto testdir = environ::get("TESTDIR").value_or("tests");
|
||||||
{ "bold", "\033[1m" },
|
auto srcext = ".cc";
|
||||||
{ "end", "\033[0m" }
|
|
||||||
#else
|
auto userflags = environ::get("CXXFLAGS").value_or("");
|
||||||
{ "red", "" },
|
|
||||||
{ "green", "" },
|
/* do not change past this point */
|
||||||
{ "blue", "" },
|
|
||||||
{ "bold", "" },
|
|
||||||
{ "end", "" }
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
ConstCharRange userflags = get_env("CXXFLAGS", "");
|
|
||||||
int nsuccess = 0, nfailed = 0;
|
int nsuccess = 0, nfailed = 0;
|
||||||
|
ConstCharRange modname = nullptr;
|
||||||
|
|
||||||
auto print_result = [&colors, &nsuccess, &nfailed]
|
auto print_result = [&](ConstCharRange fmsg = nullptr) {
|
||||||
(ConstCharRange modname, ConstCharRange fmsg = nullptr) {
|
|
||||||
write(modname, "...\t");
|
write(modname, "...\t");
|
||||||
if (!fmsg.empty()) {
|
if (!fmsg.empty()) {
|
||||||
writeln(colors["red"], colors["bold"], "(", fmsg, ")", colors["end"]);
|
writeln(ColorRed, ColorBold, "(", fmsg, ")", ColorEnd);
|
||||||
++nfailed;
|
++nfailed;
|
||||||
} else {
|
} else {
|
||||||
writeln(colors["green"], colors["bold"], "(success)", colors["end"]);
|
writeln(ColorGreen, ColorBold, "(success)", ColorEnd);
|
||||||
++nsuccess;
|
++nsuccess;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DirectoryStream ds(testdir);
|
DirectoryStream ds(testdir);
|
||||||
for (auto v: ds.iter()) {
|
for (auto v: ds.iter()) {
|
||||||
if (v.type() != FileType::regular)
|
if ((v.type() != FileType::regular) || (v.extension() != srcext))
|
||||||
continue;
|
|
||||||
if (v.extension() != srcext)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
modname = v.stem();
|
||||||
|
|
||||||
String exepath = testdir;
|
String exepath = testdir;
|
||||||
exepath += PathSeparator;
|
exepath += PathSeparator;
|
||||||
exepath += v.stem();
|
exepath += modname;
|
||||||
|
|
||||||
String cxxcmd = compiler;
|
auto cxxcmd = appender<String>();
|
||||||
cxxcmd += " ";
|
format(cxxcmd, "%s %s%s%s -o %s %s", compiler, testdir, PathSeparator,
|
||||||
cxxcmd += testdir;
|
v.filename(), exepath, cxxflags);
|
||||||
cxxcmd += PathSeparator;
|
|
||||||
cxxcmd += v.filename();
|
|
||||||
cxxcmd += " -o ";
|
|
||||||
cxxcmd += exepath;
|
|
||||||
cxxcmd += " ";
|
|
||||||
cxxcmd += cxxflags;
|
|
||||||
if (!userflags.empty()) {
|
if (!userflags.empty()) {
|
||||||
cxxcmd += " ";
|
cxxcmd.get() += " ";
|
||||||
cxxcmd += userflags;
|
cxxcmd.get() += userflags;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = system(cxxcmd.data());
|
int ret = system(cxxcmd.get().data());
|
||||||
if (ret) {
|
if (ret) {
|
||||||
print_result(v.stem(), "compile errror");
|
print_result("compile errror");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = system(exepath.data());
|
ret = system(exepath.data());
|
||||||
if (ret) {
|
if (ret) {
|
||||||
print_result(v.stem(), "runtime error");
|
print_result("runtime error");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(exepath.data());
|
remove(exepath.data());
|
||||||
print_result(v.stem());
|
print_result();
|
||||||
}
|
}
|
||||||
|
|
||||||
writeln("\n", colors["blue"], colors["bold"], "testing done:", colors["end"]);
|
writeln("\n", ColorBlue, ColorBold, "testing done:", ColorEnd);
|
||||||
writeln(colors["green"], "SUCCESS: ", nsuccess, colors["end"]);
|
writeln(ColorGreen, "SUCCESS: ", nsuccess, ColorEnd);
|
||||||
writeln(colors["red"], "FAILURE: ", nfailed, colors["end"]);
|
writeln(ColorRed, "FAILURE: ", nfailed, ColorEnd);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue