header only lib
This commit is contained in:
@@ -11,10 +11,10 @@ const char* CXX = "g++";
|
|||||||
#define DEBUG_FLAGS "-g"
|
#define DEBUG_FLAGS "-g"
|
||||||
|
|
||||||
// ...when not debugging
|
// ...when not debugging
|
||||||
#define RELEASE_FLAGS "-Ofast", "-flto", "-s"
|
#define RELEASE_FLAGS "-Ofast", "-s"
|
||||||
|
|
||||||
// ...for both C and C++
|
// ...for both C and C++
|
||||||
#define CPPFLAGS "-pipe", "-march=native", "-Wall", "-Wextra"
|
#define CPPFLAGS "--whole-program", "-march=native", "-Wall", "-Wextra", "-pipe"
|
||||||
|
|
||||||
// ...for C
|
// ...for C
|
||||||
#define CFLAGS CPPFLAGS
|
#define CFLAGS CPPFLAGS
|
||||||
@@ -22,4 +22,4 @@ const char* CXX = "g++";
|
|||||||
// ...for C++
|
// ...for C++
|
||||||
// cppipe command functions use C++17
|
// cppipe command functions use C++17
|
||||||
// Wparentheses is disabled on C++ because of the cppipe functions
|
// Wparentheses is disabled on C++ because of the cppipe functions
|
||||||
#define CXXFLAGS CPPFLAGS, "-std=c++17", "-Wno-parentheses", "-lcppipe"
|
#define CXXFLAGS CPPFLAGS, "-std=c++17", "-Wno-parentheses"
|
||||||
|
|||||||
+4
-11
@@ -5,24 +5,17 @@ cd src
|
|||||||
# Install location
|
# Install location
|
||||||
PREFIX=/usr/local
|
PREFIX=/usr/local
|
||||||
|
|
||||||
# Compile lib
|
|
||||||
options="-std=c++17 -Ofast -flto -march=native -DNDEBUG -Wall -Wextra -Wno-parentheses -Wno-unused-result -s -pipe"
|
|
||||||
# options="-std=c++17 -g"
|
|
||||||
g++ -c $options commands.cpp childProcess.cpp
|
|
||||||
|
|
||||||
# Create lib
|
|
||||||
ar rc libcppipe.a commands.o childProcess.o
|
|
||||||
mv libcppipe.a ${PREFIX}/lib
|
|
||||||
rm commands.o childProcess.o
|
|
||||||
|
|
||||||
# Compile cppipe
|
# Compile cppipe
|
||||||
g++ -o cppipe $options cppipe.cpp -lcppipe
|
options="-std=c++17 -Ofast --whole-program -march=native -DNDEBUG -Wall -Wextra -Wno-parentheses -Wno-unused-result -s -pipe"
|
||||||
|
# options="-std=c++17 -g"
|
||||||
|
g++ -o cppipe $options cppipe.cpp
|
||||||
chmod 755 cppipe
|
chmod 755 cppipe
|
||||||
mv cppipe ${PREFIX}/bin
|
mv cppipe ${PREFIX}/bin
|
||||||
|
|
||||||
# Install headers
|
# Install headers
|
||||||
mkdir -p ${PREFIX}/include/cppipe
|
mkdir -p ${PREFIX}/include/cppipe
|
||||||
cp basicTypes.h commands.hpp childProcess.hpp ${PREFIX}/include/cppipe
|
cp basicTypes.h commands.hpp commands.inl childProcess.hpp childProcess.inl ${PREFIX}/include/cppipe
|
||||||
|
|
||||||
# Clear old cache
|
# Clear old cache
|
||||||
rm -rf ~/.cache/cppipe ${XDG_CACHE_HOME}/cppipe
|
rm -rf ~/.cache/cppipe ${XDG_CACHE_HOME}/cppipe
|
||||||
|
|||||||
@@ -1,185 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <cstring>
|
|
||||||
#include "childProcess.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
RetProc::RetProc(Proc origin, int status)
|
|
||||||
: Proc(origin)
|
|
||||||
, normal_exit(WIFEXITED(status))
|
|
||||||
, returned(WEXITSTATUS(status))
|
|
||||||
{}
|
|
||||||
|
|
||||||
RetProc::operator bool()
|
|
||||||
{
|
|
||||||
return normal_exit && returned == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
RetProc wait(Proc p)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
waitpid(p.pid, &status, 0);
|
|
||||||
return RetProc(p, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create a process taking input from pipe childIn */
|
|
||||||
static Proc createProc(const char* const argv[], const fd_t childIn[2])
|
|
||||||
{
|
|
||||||
Proc childproc;
|
|
||||||
childproc.in = childIn[1];
|
|
||||||
childproc.out = STDOUT_FILENO;
|
|
||||||
|
|
||||||
childproc.pid = fork();
|
|
||||||
if(childproc.pid == 0) /* child */
|
|
||||||
{
|
|
||||||
close(childIn[1]);
|
|
||||||
dup2(childIn[0], STDIN_FILENO);
|
|
||||||
|
|
||||||
exec_or_die(argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return childproc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create a process and redirect it's output to a pipe */
|
|
||||||
static Proc createRedirProc(const char* const argv[])
|
|
||||||
{
|
|
||||||
fd_t childOut[2];
|
|
||||||
pipe(childOut);
|
|
||||||
|
|
||||||
Proc childproc;
|
|
||||||
childproc.in = STDIN_FILENO;
|
|
||||||
childproc.out = childOut[0];
|
|
||||||
|
|
||||||
childproc.pid = fork();
|
|
||||||
/* close(STDIN_FILENO); flush?*/
|
|
||||||
if(childproc.pid != 0) /* parent */
|
|
||||||
{
|
|
||||||
close(childOut[1]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dup2(childOut[1], STDOUT_FILENO);
|
|
||||||
|
|
||||||
exec_or_die(argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return childproc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create a process redirecting both in and out */
|
|
||||||
static Proc createRedirProc(const char* const argv[], const fd_t childIn[2])
|
|
||||||
{
|
|
||||||
fd_t childOut[2]; /* todo: add error #include "processTypes.hpp"*/
|
|
||||||
pipe(childOut);
|
|
||||||
|
|
||||||
Proc childproc;
|
|
||||||
childproc.in = childIn[1];
|
|
||||||
childproc.out = childOut[0];
|
|
||||||
|
|
||||||
childproc.pid = fork();
|
|
||||||
/* close(STDIN_FILENO); flush?*/
|
|
||||||
if(childproc.pid != 0) /* parent */
|
|
||||||
{
|
|
||||||
close(childOut[1]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
close(childIn[1]);
|
|
||||||
dup2(childIn[0], STDIN_FILENO);
|
|
||||||
|
|
||||||
dup2(childOut[1], STDOUT_FILENO);
|
|
||||||
|
|
||||||
exec_or_die(argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return childproc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Proc createRedirProcess(const char* const argv[], U32 flags) /* todo rename */
|
|
||||||
{
|
|
||||||
fd_t childIn[2];
|
|
||||||
Proc proc;
|
|
||||||
|
|
||||||
if(flags & INPUT)
|
|
||||||
{
|
|
||||||
pipe(childIn);
|
|
||||||
if(flags & OUTPUT)
|
|
||||||
proc = createRedirProc(argv, childIn);
|
|
||||||
else
|
|
||||||
proc = createProc(argv, childIn);
|
|
||||||
}
|
|
||||||
else if(flags & OUTPUT)
|
|
||||||
proc = createRedirProc(argv);
|
|
||||||
else
|
|
||||||
proc = createProcess(argv);
|
|
||||||
|
|
||||||
return proc;
|
|
||||||
}
|
|
||||||
|
|
||||||
Proc createCapProcess(const char* const argv[], fd_t in, fd_t err)
|
|
||||||
{
|
|
||||||
fd_t childOut[2];
|
|
||||||
pipe(childOut);
|
|
||||||
|
|
||||||
Proc proc;
|
|
||||||
proc.in = in;
|
|
||||||
proc.out = childOut[0];
|
|
||||||
proc.err = err;
|
|
||||||
|
|
||||||
proc.pid = fork();
|
|
||||||
if(proc.pid == 0) /* child */
|
|
||||||
{
|
|
||||||
if(in != STDIN_FILENO)
|
|
||||||
dup2(in, STDIN_FILENO);
|
|
||||||
|
|
||||||
dup2(childOut[1], STDOUT_FILENO);
|
|
||||||
|
|
||||||
if(err != STDERR_FILENO)
|
|
||||||
dup2(err, STDERR_FILENO);
|
|
||||||
|
|
||||||
exec_or_die(argv);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
close(childOut[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return proc;
|
|
||||||
}
|
|
||||||
|
|
||||||
Proc createProcess(const char* const argv[], fd_t in, fd_t out, fd_t err)
|
|
||||||
{
|
|
||||||
Proc proc;
|
|
||||||
proc.in = in;
|
|
||||||
proc.out = out;
|
|
||||||
proc.err = err;
|
|
||||||
|
|
||||||
proc.pid = fork();
|
|
||||||
if(proc.pid == 0) /* child */
|
|
||||||
{
|
|
||||||
if(in != STDIN_FILENO)
|
|
||||||
dup2(in, STDIN_FILENO);
|
|
||||||
|
|
||||||
if(out != STDOUT_FILENO)
|
|
||||||
dup2(out, STDOUT_FILENO);
|
|
||||||
|
|
||||||
if(err != STDERR_FILENO)
|
|
||||||
dup2(err, STDERR_FILENO);
|
|
||||||
|
|
||||||
exec_or_die(argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return proc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void exec_or_die(const char* const argv[])
|
|
||||||
{
|
|
||||||
execvp(argv[0], (char* const *)argv);
|
|
||||||
|
|
||||||
std::cerr << "Can't execute: " << argv[0] << ' ' << strerror(errno) << std::endl;
|
|
||||||
_exit(1); // _exit since we are a child
|
|
||||||
}
|
|
||||||
@@ -51,3 +51,5 @@ Proc createProcess(const char* const argv[], fd_t in=0, fd_t out=1, fd_t err=2);
|
|||||||
|
|
||||||
/* execvp the command or exit */
|
/* execvp the command or exit */
|
||||||
void exec_or_die(const char* const argv[]);
|
void exec_or_die(const char* const argv[]);
|
||||||
|
|
||||||
|
#include "childProcess.inl"
|
||||||
|
|||||||
@@ -0,0 +1,187 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <cstring>
|
||||||
|
#include "childProcess.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
inline RetProc::RetProc(Proc origin, int status)
|
||||||
|
: Proc(origin)
|
||||||
|
, normal_exit(WIFEXITED(status))
|
||||||
|
, returned(WEXITSTATUS(status))
|
||||||
|
{}
|
||||||
|
|
||||||
|
inline RetProc::operator bool()
|
||||||
|
{
|
||||||
|
return normal_exit && returned == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline RetProc wait(Proc p)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
waitpid(p.pid, &status, 0);
|
||||||
|
return RetProc(p, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace _cppipe
|
||||||
|
{
|
||||||
|
/* create a process taking input from pipe childIn */
|
||||||
|
inline Proc createProc(const char* const argv[], const fd_t childIn[2])
|
||||||
|
{
|
||||||
|
Proc childproc;
|
||||||
|
childproc.in = childIn[1];
|
||||||
|
childproc.out = STDOUT_FILENO;
|
||||||
|
|
||||||
|
childproc.pid = fork();
|
||||||
|
if(childproc.pid == 0) /* child */
|
||||||
|
{
|
||||||
|
close(childIn[1]);
|
||||||
|
dup2(childIn[0], STDIN_FILENO);
|
||||||
|
|
||||||
|
exec_or_die(argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return childproc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create a process and redirect it's output to a pipe */
|
||||||
|
inline Proc createRedirProc(const char* const argv[])
|
||||||
|
{
|
||||||
|
fd_t childOut[2];
|
||||||
|
pipe(childOut);
|
||||||
|
|
||||||
|
Proc childproc;
|
||||||
|
childproc.in = STDIN_FILENO;
|
||||||
|
childproc.out = childOut[0];
|
||||||
|
|
||||||
|
childproc.pid = fork();
|
||||||
|
/* close(STDIN_FILENO); flush?*/
|
||||||
|
if(childproc.pid != 0) /* parent */
|
||||||
|
{
|
||||||
|
close(childOut[1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dup2(childOut[1], STDOUT_FILENO);
|
||||||
|
|
||||||
|
exec_or_die(argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return childproc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create a process redirecting both in and out */
|
||||||
|
inline Proc createRedirProc(const char* const argv[], const fd_t childIn[2])
|
||||||
|
{
|
||||||
|
fd_t childOut[2]; /* todo: add error #include "processTypes.hpp"*/
|
||||||
|
pipe(childOut);
|
||||||
|
|
||||||
|
Proc childproc;
|
||||||
|
childproc.in = childIn[1];
|
||||||
|
childproc.out = childOut[0];
|
||||||
|
|
||||||
|
childproc.pid = fork();
|
||||||
|
/* close(STDIN_FILENO); flush?*/
|
||||||
|
if(childproc.pid != 0) /* parent */
|
||||||
|
{
|
||||||
|
close(childOut[1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
close(childIn[1]);
|
||||||
|
dup2(childIn[0], STDIN_FILENO);
|
||||||
|
|
||||||
|
dup2(childOut[1], STDOUT_FILENO);
|
||||||
|
|
||||||
|
exec_or_die(argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return childproc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Proc createRedirProcess(const char* const argv[], U32 flags) /* todo rename */
|
||||||
|
{
|
||||||
|
fd_t childIn[2];
|
||||||
|
Proc proc;
|
||||||
|
|
||||||
|
if(flags & INPUT)
|
||||||
|
{
|
||||||
|
pipe(childIn);
|
||||||
|
if(flags & OUTPUT)
|
||||||
|
proc = _cppipe::createRedirProc(argv, childIn);
|
||||||
|
else
|
||||||
|
proc = _cppipe::createProc(argv, childIn);
|
||||||
|
}
|
||||||
|
else if(flags & OUTPUT)
|
||||||
|
proc = _cppipe::createRedirProc(argv);
|
||||||
|
else
|
||||||
|
proc = createProcess(argv);
|
||||||
|
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Proc createCapProcess(const char* const argv[], fd_t in, fd_t err)
|
||||||
|
{
|
||||||
|
fd_t childOut[2];
|
||||||
|
pipe(childOut);
|
||||||
|
|
||||||
|
Proc proc;
|
||||||
|
proc.in = in;
|
||||||
|
proc.out = childOut[0];
|
||||||
|
proc.err = err;
|
||||||
|
|
||||||
|
proc.pid = fork();
|
||||||
|
if(proc.pid == 0) /* child */
|
||||||
|
{
|
||||||
|
if(in != STDIN_FILENO)
|
||||||
|
dup2(in, STDIN_FILENO);
|
||||||
|
|
||||||
|
dup2(childOut[1], STDOUT_FILENO);
|
||||||
|
|
||||||
|
if(err != STDERR_FILENO)
|
||||||
|
dup2(err, STDERR_FILENO);
|
||||||
|
|
||||||
|
exec_or_die(argv);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
close(childOut[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Proc createProcess(const char* const argv[], fd_t in, fd_t out, fd_t err)
|
||||||
|
{
|
||||||
|
Proc proc;
|
||||||
|
proc.in = in;
|
||||||
|
proc.out = out;
|
||||||
|
proc.err = err;
|
||||||
|
|
||||||
|
proc.pid = fork();
|
||||||
|
if(proc.pid == 0) /* child */
|
||||||
|
{
|
||||||
|
if(in != STDIN_FILENO)
|
||||||
|
dup2(in, STDIN_FILENO);
|
||||||
|
|
||||||
|
if(out != STDOUT_FILENO)
|
||||||
|
dup2(out, STDOUT_FILENO);
|
||||||
|
|
||||||
|
if(err != STDERR_FILENO)
|
||||||
|
dup2(err, STDERR_FILENO);
|
||||||
|
|
||||||
|
exec_or_die(argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void exec_or_die(const char* const argv[])
|
||||||
|
{
|
||||||
|
execvp(argv[0], (char* const *)argv);
|
||||||
|
|
||||||
|
std::cerr << "Can't execute: " << argv[0] << ' ' << strerror(errno) << std::endl;
|
||||||
|
_exit(1); // _exit since we are a child
|
||||||
|
}
|
||||||
@@ -160,3 +160,5 @@ PendingCmd operator&(const PendingCmd&, const Cmd&);
|
|||||||
auto var = $(ls);
|
auto var = $(ls);
|
||||||
*/
|
*/
|
||||||
std::string $(const PendingCmd&);
|
std::string $(const PendingCmd&);
|
||||||
|
|
||||||
|
#include "commands.inl"
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ enum constants: I32
|
|||||||
FILE_PERMISIONS = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
|
FILE_PERMISIONS = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
|
||||||
};
|
};
|
||||||
|
|
||||||
static fd_t open_or_die(const char* file, I32 flags)
|
namespace _cppipe
|
||||||
|
{
|
||||||
|
inline fd_t open_or_die(const char* file, I32 flags)
|
||||||
{
|
{
|
||||||
fd_t fd = open(file, flags, FILE_PERMISIONS);
|
fd_t fd = open(file, flags, FILE_PERMISIONS);
|
||||||
if(fd == -1)
|
if(fd == -1)
|
||||||
@@ -23,8 +25,9 @@ static fd_t open_or_die(const char* file, I32 flags)
|
|||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RetProc Cmd::operator()(fd_t in, fd_t out, fd_t err)
|
inline RetProc Cmd::operator()(fd_t in, fd_t out, fd_t err)
|
||||||
{
|
{
|
||||||
Proc p = createProcess(argv.data(), in, out, err);
|
Proc p = createProcess(argv.data(), in, out, err);
|
||||||
|
|
||||||
@@ -39,12 +42,12 @@ RetProc Cmd::operator()(fd_t in, fd_t out, fd_t err)
|
|||||||
return wait(p);
|
return wait(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
Proc Cmd::detach(fd_t in, fd_t out, fd_t err)
|
inline Proc Cmd::detach(fd_t in, fd_t out, fd_t err)
|
||||||
{
|
{
|
||||||
return createProcess(argv.data(), in, out, err);
|
return createProcess(argv.data(), in, out, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cmd::append_args(std::initializer_list<const char*> args)
|
inline void Cmd::append_args(std::initializer_list<const char*> args)
|
||||||
{
|
{
|
||||||
argv.reserve(argv.size() + args.size());
|
argv.reserve(argv.size() + args.size());
|
||||||
argv.back() = *args.begin();
|
argv.back() = *args.begin();
|
||||||
@@ -53,7 +56,7 @@ void Cmd::append_args(std::initializer_list<const char*> args)
|
|||||||
argv.push_back(nullptr);
|
argv.push_back(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Cmd Cmd::operator+(const char* arg)
|
inline Cmd Cmd::operator+(const char* arg)
|
||||||
{
|
{
|
||||||
Cmd result(*this);
|
Cmd result(*this);
|
||||||
result.argv.back() = arg;
|
result.argv.back() = arg;
|
||||||
@@ -61,7 +64,7 @@ Cmd Cmd::operator+(const char* arg)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cmd& Cmd::operator+=(const char* arg)
|
inline Cmd& Cmd::operator+=(const char* arg)
|
||||||
{
|
{
|
||||||
argv.back() = arg;
|
argv.back() = arg;
|
||||||
argv.push_back(nullptr);
|
argv.push_back(nullptr);
|
||||||
@@ -69,7 +72,7 @@ Cmd& Cmd::operator+=(const char* arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PendingCmd::PendingCmd(const Cmd& origin, fd_t in, fd_t out, fd_t err)
|
inline PendingCmd::PendingCmd(const Cmd& origin, fd_t in, fd_t out, fd_t err)
|
||||||
: cmd(origin)
|
: cmd(origin)
|
||||||
, in(in)
|
, in(in)
|
||||||
, out(out)
|
, out(out)
|
||||||
@@ -77,7 +80,7 @@ PendingCmd::PendingCmd(const Cmd& origin, fd_t in, fd_t out, fd_t err)
|
|||||||
, execed_(false)
|
, execed_(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
PendingCmd::~PendingCmd()
|
inline PendingCmd::~PendingCmd()
|
||||||
{
|
{
|
||||||
if(!execed_)
|
if(!execed_)
|
||||||
operator()();
|
operator()();
|
||||||
@@ -89,21 +92,21 @@ PendingCmd::~PendingCmd()
|
|||||||
/* close(err); */
|
/* close(err); */
|
||||||
}
|
}
|
||||||
|
|
||||||
RetProc PendingCmd::operator()()
|
inline RetProc PendingCmd::operator()()
|
||||||
{
|
{
|
||||||
assert(!execed_ && "Executed command twice");
|
assert(!execed_ && "Executed command twice");
|
||||||
execed_ = true;
|
execed_ = true;
|
||||||
return cmd(in, out, err);
|
return cmd(in, out, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
Proc PendingCmd::detach()
|
inline Proc PendingCmd::detach()
|
||||||
{
|
{
|
||||||
assert(!execed_ && "Executed command twice");
|
assert(!execed_ && "Executed command twice");
|
||||||
execed_ = true;
|
execed_ = true;
|
||||||
return cmd.detach(in, out, err);
|
return cmd.detach(in, out, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
Proc PendingCmd::detachRedirOut()
|
inline Proc PendingCmd::detachRedirOut()
|
||||||
{
|
{
|
||||||
assert(!execed_ && "Executed command twice"); assert(out==1 && "already redirected");
|
assert(!execed_ && "Executed command twice"); assert(out==1 && "already redirected");
|
||||||
assert(out==1 && "capturing redirected proccess");
|
assert(out==1 && "capturing redirected proccess");
|
||||||
@@ -112,12 +115,12 @@ Proc PendingCmd::detachRedirOut()
|
|||||||
return createCapProcess(cmd.argv.data(), in, err);
|
return createCapProcess(cmd.argv.data(), in, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PendingCmd::cancel()
|
inline void PendingCmd::cancel()
|
||||||
{
|
{
|
||||||
execed_ = true;
|
execed_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string $(const PendingCmd& cmd)
|
inline std::string $(const PendingCmd& cmd)
|
||||||
{
|
{
|
||||||
Proc p = const_cast<PendingCmd&>(cmd).detachRedirOut();
|
Proc p = const_cast<PendingCmd&>(cmd).detachRedirOut();
|
||||||
|
|
||||||
@@ -144,24 +147,24 @@ std::string $(const PendingCmd& cmd)
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
void exec(const Cmd& cmd)
|
inline void exec(const Cmd& cmd)
|
||||||
{
|
{
|
||||||
exec_or_die(cmd.argv.data());
|
exec_or_die(cmd.argv.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
PendingCmd operator,(const PendingCmd& cfirst, const Cmd& second)
|
inline PendingCmd operator,(const PendingCmd& cfirst, const Cmd& second)
|
||||||
{
|
{
|
||||||
auto& first = const_cast<PendingCmd&>(cfirst);
|
auto& first = const_cast<PendingCmd&>(cfirst);
|
||||||
first();
|
first();
|
||||||
return PendingCmd(second);
|
return PendingCmd(second);
|
||||||
}
|
}
|
||||||
|
|
||||||
PendingCmd operator,(RetProc, const Cmd& second)
|
inline PendingCmd operator,(RetProc, const Cmd& second)
|
||||||
{
|
{
|
||||||
return PendingCmd(second);
|
return PendingCmd(second);
|
||||||
}
|
}
|
||||||
|
|
||||||
PendingCmd operator|(const PendingCmd& cfirst, const Cmd& second)
|
inline PendingCmd operator|(const PendingCmd& cfirst, const Cmd& second)
|
||||||
{
|
{
|
||||||
auto& first = const_cast<PendingCmd&>(cfirst);
|
auto& first = const_cast<PendingCmd&>(cfirst);
|
||||||
fd_t firstOut = first.detachRedirOut().out;
|
fd_t firstOut = first.detachRedirOut().out;
|
||||||
@@ -169,7 +172,7 @@ PendingCmd operator|(const PendingCmd& cfirst, const Cmd& second)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RetProc operator&&(const PendingCmd& cfirst, const Cmd& csecond)
|
inline RetProc operator&&(const PendingCmd& cfirst, const Cmd& csecond)
|
||||||
{
|
{
|
||||||
auto& first = const_cast<PendingCmd&>(cfirst);
|
auto& first = const_cast<PendingCmd&>(cfirst);
|
||||||
auto& second = const_cast<Cmd&>(csecond);
|
auto& second = const_cast<Cmd&>(csecond);
|
||||||
@@ -181,7 +184,7 @@ RetProc operator&&(const PendingCmd& cfirst, const Cmd& csecond)
|
|||||||
return firstProc;
|
return firstProc;
|
||||||
}
|
}
|
||||||
|
|
||||||
RetProc operator&&(RetProc p, const Cmd& ccmd)
|
inline RetProc operator&&(RetProc p, const Cmd& ccmd)
|
||||||
{
|
{
|
||||||
auto& cmd = const_cast<Cmd&>(ccmd);
|
auto& cmd = const_cast<Cmd&>(ccmd);
|
||||||
if(p)
|
if(p)
|
||||||
@@ -190,7 +193,7 @@ RetProc operator&&(RetProc p, const Cmd& ccmd)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
RetProc operator||(const PendingCmd& cfirst, const Cmd& csecond)
|
inline RetProc operator||(const PendingCmd& cfirst, const Cmd& csecond)
|
||||||
{
|
{
|
||||||
auto& first = const_cast<PendingCmd&>(cfirst);
|
auto& first = const_cast<PendingCmd&>(cfirst);
|
||||||
auto& second = const_cast<Cmd&>(csecond);
|
auto& second = const_cast<Cmd&>(csecond);
|
||||||
@@ -202,7 +205,7 @@ RetProc operator||(const PendingCmd& cfirst, const Cmd& csecond)
|
|||||||
return firstProc;
|
return firstProc;
|
||||||
}
|
}
|
||||||
|
|
||||||
RetProc operator||(RetProc p, const Cmd& ccmd)
|
inline RetProc operator||(RetProc p, const Cmd& ccmd)
|
||||||
{
|
{
|
||||||
auto& cmd = const_cast<Cmd&>(ccmd);
|
auto& cmd = const_cast<Cmd&>(ccmd);
|
||||||
if(!p)
|
if(!p)
|
||||||
@@ -211,12 +214,12 @@ RetProc operator||(RetProc p, const Cmd& ccmd)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
PendingCmd& operator>(const PendingCmd& cmd, const char* file)
|
inline PendingCmd& operator>(const PendingCmd& cmd, const char* file)
|
||||||
{
|
{
|
||||||
fd_t fd = open_or_die(file, O_WRONLY | O_CREAT);
|
fd_t fd = _cppipe::open_or_die(file, O_WRONLY | O_CREAT);
|
||||||
return cmd > fd;
|
return cmd > fd;
|
||||||
}
|
}
|
||||||
PendingCmd& operator>(const PendingCmd& ccmd, fd_t fd)
|
inline PendingCmd& operator>(const PendingCmd& ccmd, fd_t fd)
|
||||||
{
|
{
|
||||||
auto& cmd = const_cast<PendingCmd&>(ccmd);
|
auto& cmd = const_cast<PendingCmd&>(ccmd);
|
||||||
assert(cmd.out == 1 || !"ERROR: Output is already redirected!");
|
assert(cmd.out == 1 || !"ERROR: Output is already redirected!");
|
||||||
@@ -225,22 +228,22 @@ PendingCmd& operator>(const PendingCmd& ccmd, fd_t fd)
|
|||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
PendingCmd& operator>>(const PendingCmd& cmd, const char* file)
|
inline PendingCmd& operator>>(const PendingCmd& cmd, const char* file)
|
||||||
{
|
{
|
||||||
fd_t fd = open_or_die(file, O_WRONLY | O_CREAT | O_APPEND);
|
fd_t fd = _cppipe::open_or_die(file, O_WRONLY | O_CREAT | O_APPEND);
|
||||||
return cmd > fd;
|
return cmd > fd;
|
||||||
}
|
}
|
||||||
PendingCmd& operator>>(const PendingCmd& cmd, fd_t fd)
|
inline PendingCmd& operator>>(const PendingCmd& cmd, fd_t fd)
|
||||||
{
|
{
|
||||||
return cmd > fd;
|
return cmd > fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
PendingCmd& operator>=(const PendingCmd& cmd, const char* file)
|
inline PendingCmd& operator>=(const PendingCmd& cmd, const char* file)
|
||||||
{
|
{
|
||||||
fd_t fd = open_or_die(file, O_WRONLY | O_CREAT);
|
fd_t fd = _cppipe::open_or_die(file, O_WRONLY | O_CREAT);
|
||||||
return cmd >= fd;
|
return cmd >= fd;
|
||||||
}
|
}
|
||||||
PendingCmd& operator>=(const PendingCmd& ccmd, fd_t fd)
|
inline PendingCmd& operator>=(const PendingCmd& ccmd, fd_t fd)
|
||||||
{
|
{
|
||||||
auto& cmd = const_cast<PendingCmd&>(ccmd);
|
auto& cmd = const_cast<PendingCmd&>(ccmd);
|
||||||
assert(cmd.err == 2 || !"ERROR: Error output is already redirected!");
|
assert(cmd.err == 2 || !"ERROR: Error output is already redirected!");
|
||||||
@@ -249,22 +252,22 @@ PendingCmd& operator>=(const PendingCmd& ccmd, fd_t fd)
|
|||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
PendingCmd& operator>>=(const PendingCmd& cmd, const char* file)
|
inline PendingCmd& operator>>=(const PendingCmd& cmd, const char* file)
|
||||||
{
|
{
|
||||||
fd_t fd = open_or_die(file, O_WRONLY | O_CREAT | O_APPEND);
|
fd_t fd = _cppipe::open_or_die(file, O_WRONLY | O_CREAT | O_APPEND);
|
||||||
return cmd >= fd;
|
return cmd >= fd;
|
||||||
}
|
}
|
||||||
PendingCmd& operator>>=(const PendingCmd& cmd, fd_t fd)
|
inline PendingCmd& operator>>=(const PendingCmd& cmd, fd_t fd)
|
||||||
{
|
{
|
||||||
return cmd >= fd;
|
return cmd >= fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
PendingCmd& operator<(const PendingCmd& cmd, const char* file)
|
inline PendingCmd& operator<(const PendingCmd& cmd, const char* file)
|
||||||
{
|
{
|
||||||
fd_t fd = open_or_die(file, O_RDONLY);
|
fd_t fd = _cppipe::open_or_die(file, O_RDONLY);
|
||||||
return cmd < fd;
|
return cmd < fd;
|
||||||
}
|
}
|
||||||
PendingCmd& operator<(const PendingCmd& ccmd, fd_t fd)
|
inline PendingCmd& operator<(const PendingCmd& ccmd, fd_t fd)
|
||||||
{
|
{
|
||||||
auto& cmd = const_cast<PendingCmd&>(ccmd);
|
auto& cmd = const_cast<PendingCmd&>(ccmd);
|
||||||
assert(cmd.in == 0 || !"ERROR: Input is already redirected!");
|
assert(cmd.in == 0 || !"ERROR: Input is already redirected!");
|
||||||
@@ -273,7 +276,7 @@ PendingCmd& operator<(const PendingCmd& ccmd, fd_t fd)
|
|||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
PendingCmd operator&(const PendingCmd& cfirst, const Cmd& second)
|
inline PendingCmd operator&(const PendingCmd& cfirst, const Cmd& second)
|
||||||
{
|
{
|
||||||
const_cast<PendingCmd&>(cfirst).detach();
|
const_cast<PendingCmd&>(cfirst).detach();
|
||||||
return PendingCmd(second);
|
return PendingCmd(second);
|
||||||
+21
-21
@@ -25,35 +25,35 @@ struct MappedFile // todo: move to utils
|
|||||||
};
|
};
|
||||||
|
|
||||||
// process the args until the src file arg is found, return its index
|
// process the args until the src file arg is found, return its index
|
||||||
static int parse_args_until_src(int argc, char* argv[]);
|
int parse_args_until_src(int argc, char* argv[]);
|
||||||
|
|
||||||
// find the cpp to run, if it doesn't exist, exit program
|
// find the cpp to run, if it doesn't exist, exit program
|
||||||
static fs::path find_path_to_cpp(string_view src_file);
|
fs::path find_path_to_cpp(string_view src_file);
|
||||||
|
|
||||||
// find the path of the cache for the given src_file path
|
// find the path of the cache for the given src_file path
|
||||||
static fs::path get_cache_dir_path(const fs::path& src_file);
|
fs::path get_cache_dir_path(const fs::path& src_file);
|
||||||
|
|
||||||
// map file in memory with write persmissions
|
// map file in memory with write persmissions
|
||||||
static MappedFile mapfile_for_writing(const fs::path& file);
|
MappedFile mapfile_for_writing(const fs::path& file);
|
||||||
|
|
||||||
// preprocess the src file and compare the result to the previous version, return weather it's changed
|
// preprocess the src file and compare the result to the previous version, return weather it's changed
|
||||||
// remove cached bin if true
|
// remove cached bin if true
|
||||||
static bool preprocess_and_compare();
|
bool preprocess_and_compare();
|
||||||
|
|
||||||
// only recompile if changes are present
|
// only recompile if changes are present
|
||||||
static void compile_src_file();
|
void compile_src_file();
|
||||||
|
|
||||||
static void print_usage();
|
void print_usage();
|
||||||
|
|
||||||
static bool is_src_file(string_view path);
|
bool is_src_file(string_view path);
|
||||||
|
|
||||||
static const char DEBUG_PREFIX[] = "__DBG";
|
const char DEBUG_PREFIX[] = "__DBG";
|
||||||
|
|
||||||
// Context
|
// Context
|
||||||
static bool debug = false;
|
bool debug = false;
|
||||||
static fs::path src_file;
|
fs::path src_file;
|
||||||
static fs::path cache_dir;
|
fs::path cache_dir;
|
||||||
static fs::path bin; // cache bins to avoid recompiles
|
fs::path bin; // cache bins to avoid recompiles
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
@@ -81,7 +81,7 @@ int main(int argc, char* argv[])
|
|||||||
exec(run);
|
exec(run);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_args_until_src(int argc, char* argv[])
|
int parse_args_until_src(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
if(argc < 2)
|
if(argc < 2)
|
||||||
{
|
{
|
||||||
@@ -123,7 +123,7 @@ static int parse_args_until_src(int argc, char* argv[])
|
|||||||
return src_arg;
|
return src_arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fs::path find_path_to_cpp(string_view src_file)
|
fs::path find_path_to_cpp(string_view src_file)
|
||||||
{
|
{
|
||||||
if(fs::exists(src_file)) // found relative to CWD
|
if(fs::exists(src_file)) // found relative to CWD
|
||||||
{
|
{
|
||||||
@@ -161,7 +161,7 @@ static fs::path find_path_to_cpp(string_view src_file)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fs::path get_cache_dir_path(const fs::path& src_file)
|
fs::path get_cache_dir_path(const fs::path& src_file)
|
||||||
{
|
{
|
||||||
fs::path cache_dir;
|
fs::path cache_dir;
|
||||||
if(char* xdg_cache = getenv("XDG_CACHE_HOME"))
|
if(char* xdg_cache = getenv("XDG_CACHE_HOME"))
|
||||||
@@ -180,7 +180,7 @@ static fs::path get_cache_dir_path(const fs::path& src_file)
|
|||||||
return cache_dir;
|
return cache_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MappedFile mapfile_for_writing(const fs::path& file)
|
MappedFile mapfile_for_writing(const fs::path& file)
|
||||||
{
|
{
|
||||||
fd_t fd = open(file.c_str(), O_RDWR);
|
fd_t fd = open(file.c_str(), O_RDWR);
|
||||||
|
|
||||||
@@ -192,7 +192,7 @@ static MappedFile mapfile_for_writing(const fs::path& file)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool preprocess_and_compare()
|
bool preprocess_and_compare()
|
||||||
{
|
{
|
||||||
Cmd preprocess(
|
Cmd preprocess(
|
||||||
CXX,
|
CXX,
|
||||||
@@ -242,7 +242,7 @@ static bool preprocess_and_compare()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compile_src_file()
|
void compile_src_file()
|
||||||
{
|
{
|
||||||
// Only compile if the source is newer then the bin
|
// Only compile if the source is newer then the bin
|
||||||
if(preprocess_and_compare() || !fs::exists(bin))
|
if(preprocess_and_compare() || !fs::exists(bin))
|
||||||
@@ -269,12 +269,12 @@ static void compile_src_file()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_usage()
|
void print_usage()
|
||||||
{
|
{
|
||||||
cout << "Usage: cppipe [-g] CPP_FILE [ARGUMENTS]...\n";
|
cout << "Usage: cppipe [-g] CPP_FILE [ARGUMENTS]...\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_src_file(const string_view p)
|
bool is_src_file(const string_view p)
|
||||||
{
|
{
|
||||||
size_t end = p.size() - 1;
|
size_t end = p.size() - 1;
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
int* x;
|
||||||
|
void* y;
|
||||||
|
x = y;
|
||||||
|
|
||||||
char s[16];
|
char s[16];
|
||||||
scanf("%s", s);
|
scanf("%s", s);
|
||||||
printf("%s\n", s);
|
printf("%s\n", s);
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
config
|
|
||||||
support C
|
support C
|
||||||
man
|
man
|
||||||
|
.cppipe file extension
|
||||||
|
tips
|
||||||
|
|
||||||
?
|
?
|
||||||
header only lib
|
precompiled header cppipe.h
|
||||||
-Wno-unused-result in install.sh
|
-Wno-unused-result in install.sh
|
||||||
file operations, lack of uniformity (C++ vs POSIX)
|
file operations, lack of uniformity (C++ vs POSIX)
|
||||||
split
|
split
|
||||||
@@ -14,3 +15,4 @@ shaded obj
|
|||||||
uninstall
|
uninstall
|
||||||
throw when a command couldnt be ran
|
throw when a command couldnt be ran
|
||||||
improve debug (the src file shown is the .ii)
|
improve debug (the src file shown is the .ii)
|
||||||
|
no optimizations option
|
||||||
|
|||||||
Reference in New Issue
Block a user