Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Google test gen #5

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Implement subprocess
tsarn committed Dec 2, 2020
commit be8a23b43766c5448d557ecc6a415cc3d6cb2854
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -4,10 +4,15 @@ project(fuzz VERSION 0.1)
list(APPEND CMAKE_MODULE_PATH
"${CMAKE_CURRENT_SOURCE_DIR}/llvm-project/llvm/cmake/modules"
"${CMAKE_CURRENT_SOURCE_DIR}/llvm-project/clang/cmake/modules")

if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
set(LLVM_TARGETS_TO_BUILD "X86")
endif()

include(AddLLVM)
include(AddClang)

add_library(fuzz src/test.cpp src/test.h src/test_main.h src/test_main.cpp src/test_rt.h)
add_library(fuzz src/test.cpp src/test.h src/test_main.h src/test_main.cpp src/printer.cpp src/subprocess.cpp src/subprocess.h)
add_library(fuzz::fuzz ALIAS fuzz)
target_include_directories(fuzz PUBLIC src/)

46 changes: 46 additions & 0 deletions src/printer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "test.h"

struct TypePrinter {
std::string s;

void visitPrimitiveType(PrimitiveType x) {
s = printPrimitiveType(x);
}

void visitPointerTo(const PointerTo& x) {
s = printType(*x.type) + "*";
}

void visitInRange(const InRange& x) {
s = printType(*x.type);
}
};

std::string printType(const Type &type) {
TypePrinter typePrinter;
type.accept(typePrinter);
return typePrinter.s;
}

struct ValuePrinter {
std::string value, s;

void visitPrimitiveType(PrimitiveType x) {
s = "static_cast<" + printPrimitiveType(x) + ">(" + value + ")";
}

void visitPointerTo(const PointerTo& x) {
s = "new " + printType(*x.type) + "{" + printValue(*x.type, value) + "}";
}

void visitInRange(const InRange& x) {
s = printValue(*x.type, value);
}
};

std::string printValue(const Type &type, const std::string &value) {
ValuePrinter valuePrinter;
valuePrinter.value = value;
type.accept(valuePrinter);
return valuePrinter.s;
}
91 changes: 91 additions & 0 deletions src/subprocess.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#include <string>
#include <utility>
#include <vector>
#include <array>
#include <system_error>
#include <unistd.h>
#include <sys/wait.h>

class Subprocess {
private:
std::vector<std::string> cmd;
std::string capturedStdout;
int exitCode;

public:
explicit Subprocess(std::vector<std::string> cmd);
explicit operator bool() const {
return exitCode == 0;
}

Subprocess &run(std::string input);
[[nodiscard]] std::string output() const;
};

Subprocess::Subprocess(std::vector<std::string> cmd) : cmd(std::move(cmd)), exitCode(0) {}

Subprocess &Subprocess::run(std::string input) {
exitCode = -1;
capturedStdout.clear();

int inputPipe[2];
int outputPipe[2];

if (pipe(inputPipe) != 0) {
throw std::system_error(errno, std::generic_category());
}

if (pipe(outputPipe) != 0) {
throw std::system_error(errno, std::generic_category());
}

pid_t pid = fork();

if (pid < 0) {
throw std::system_error(errno, std::generic_category());
}

if (pid == 0) {
// child
close(inputPipe[1]);
close(outputPipe[0]);
dup2(0, inputPipe[0]); // remap stdin
dup2(1, outputPipe[1]); // remap stdout

std::vector<char*> argv;
for (auto s : cmd) {
argv.push_back(s.data());
}

execvp(cmd[0].c_str(), argv.data());

}

// parent

close(outputPipe[1]);
write(inputPipe[0], input.data(), input.size());
close(inputPipe[0]);

int stat;
waitpid(pid, &stat, 0);

if (WIFEXITED(stat)) {
exitCode = WEXITSTATUS(stat);
} else if (WIFSIGNALED(stat)) {
exitCode = -WTERMSIG(stat);
}

std::array<char, 4096> buf;
int rd;

while ((rd = read(outputPipe[0], buf.data(), buf.size())) > 0) {
std::copy(buf.begin(), buf.begin() + rd, std::back_inserter(capturedStdout));
}

return *this;
}

std::string Subprocess::output() const {
return capturedStdout;
}
20 changes: 20 additions & 0 deletions src/subprocess.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

#include <vector>
#include <string>

class Subprocess {
private:
std::vector<std::string> cmd;
std::string capturedStdout;
int exitCode;

public:
explicit Subprocess(std::vector<std::string> cmd);
explicit operator bool() const {
return exitCode == 0;
}

Subprocess &run(std::string input);
[[nodiscard]] std::string output() const;
};
30 changes: 3 additions & 27 deletions src/test.cpp
Original file line number Diff line number Diff line change
@@ -3,31 +3,7 @@
#include <sstream>

std::string Value::print() const {
return type->printValue(std::to_string(value));
}

std::string Type::print() const {
if (auto primitiveType = std::get_if<PrimitiveType>(&type)) {
return printPrimitiveType(*primitiveType);
} else if (auto pointerTo = std::get_if<PointerTo>(&type)) {
return pointerTo->type->print() + "*";
} else if (auto inRange = std::get_if<InRange>(&type)) {
return inRange->type->print();
}

return "<unknown>";
}

std::string Type::printValue(const std::string& value) const {
if (auto primitiveType = std::get_if<PrimitiveType>(&type)) {
return "static_cast<" + print() + ">(" + value + ")";
} else if (auto pointerTo = std::get_if<PointerTo>(&type)) {
return "new " + pointerTo->type->print() + "{" + pointerTo->type->printValue(value) + "}";
} else if (auto inRange = std::get_if<InRange>(&type)) {
return inRange->type->printValue(value);
}

return "<unknown>";
return printValue(*type, std::to_string(value));
}

std::pair<PrimitiveInteger, PrimitiveInteger> Type::getRange() const {
@@ -132,7 +108,7 @@ Type::ptr pointerTo(Type::ptr type) {
}

std::string TestSignature::print() const {
std::string res = returnType->print() + " " + name;
std::string res = printType(*returnType) + " " + name;
res += "(";

bool first = true;
@@ -142,7 +118,7 @@ std::string TestSignature::print() const {
res += ", ";
}
first = false;
res += type->print();
res += printType(*type);
}

res += ");\n";
16 changes: 14 additions & 2 deletions src/test.h
Original file line number Diff line number Diff line change
@@ -38,11 +38,23 @@ struct Type {

using ptr = std::shared_ptr<Type>;

[[nodiscard]] std::string print() const;
[[nodiscard]] std::string printValue(const std::string &value) const;
[[nodiscard]] std::pair<PrimitiveInteger, PrimitiveInteger> getRange() const;

template<class Visitor>
void accept(Visitor &visitor) const {
if (auto primitiveType = std::get_if<PrimitiveType>(&type)) {
visitor.visitPrimitiveType(type);
} else if (auto pointerTo = std::get_if<PointerTo>(&type)) {
visitor.visitPointerTo(pointerTo);
} else if (auto inRange = std::get_if<InRange>(&type)) {
visitor.visitInRange(inRange);
}
}
};

std::string printType(const Type &type);
std::string printValue(const Type &type, const std::string &value);

[[nodiscard]] Type::ptr primitiveType(PrimitiveType type);
[[nodiscard]] Type::ptr primitiveType(PrimitiveType type, PrimitiveInteger min, PrimitiveInteger max);
[[nodiscard]] Type::ptr pointerTo(Type::ptr type);
36 changes: 0 additions & 36 deletions src/test_rt.h

This file was deleted.