@@ -16,16 +16,8 @@ int BXParser::get() { | |||
return c; | |||
} | |||
int BXParser::peek() { | |||
return buf_.peek(); | |||
} | |||
int BXParser::peek2() { | |||
return buf_.peek2(); | |||
} | |||
BXParser::Operator BXParser::readOperator() { | |||
int ch2 = peek2(); | |||
int ch2 = peek(2); | |||
if (peek() == ':' && ch2 == '=') { | |||
skip(); // ':' | |||
skip(); // '=' | |||
@@ -233,7 +225,7 @@ bool BXParser::parseString(const BXVariables &vars, std::string &content, int se | |||
break; | |||
default: | |||
if (ch == ':' && peek2() == '=') | |||
if (ch == ':' && peek(2) == '=') | |||
return success; | |||
content.push_back(get()); |
@@ -24,15 +24,14 @@ public: | |||
static const int FLAG_NONE = 0; | |||
static const int FLAG_ONE_LINE = 1 << 0; | |||
BXParser(std::istream &stream, int flags, int line = 1, int ch = 1): | |||
BXParser(bufio::IStream &stream, int flags, int line = 1, int ch = 1): | |||
flags_(flags), line_(line), ch_(ch), buf_(stream) {} | |||
void parse(BXVariables &vars); | |||
void parseList(const BXVariables &vars, std::vector<std::string> &values); | |||
int get(); | |||
int peek(); | |||
int peek2(); | |||
int peek(size_t count = 1) { return buf_.peek(count); } | |||
void skip(char expected); | |||
void skip() { get(); } | |||
@@ -69,7 +68,7 @@ private: | |||
class BXWriter { | |||
public: | |||
BXWriter(std::ostream &stream): buf_(stream) {} | |||
BXWriter(bufio::OStream &stream): buf_(stream) {} | |||
void write(const BXVariables &vars); | |||
@@ -36,7 +36,7 @@ bool CompileStep::checkHasChanged(const std::string &outDir) { | |||
BXVariables cachedVariables; | |||
try { | |||
std::ifstream f = sys::ifstream(confPath); | |||
bufio::IFStream f(confPath); | |||
BXParser parser(f, BXParser::FLAG_NONE); | |||
parser.parse(cachedVariables); | |||
} catch (BXParseError &err) { | |||
@@ -95,7 +95,7 @@ void CompileStep::doBuild(const std::string &outDir) { | |||
sys::mkdirp(dirPath); | |||
std::ofstream f = sys::ofstream(confPath(outDir)); | |||
bufio::OFStream f(confPath(outDir)); | |||
BXWriter writer(f); | |||
writer.write(newCachedVars); | |||
@@ -129,14 +129,14 @@ BXVariables &CompileStep::variables() { | |||
return variables_; | |||
} | |||
std::ifstream f = sys::ifstream(path_); | |||
bufio::IFStream f(path_); | |||
BXParser parser(f, BXParser::FLAG_ONE_LINE); | |||
while (f.good()) { | |||
while (parser.peek() != EOF) { | |||
if (startsWith(parser, "//#bx")) { | |||
parser.parse(variables_); | |||
} else { | |||
while (f.good() && parser.get() != '\n'); | |||
while (parser.peek() != EOF && parser.get() != '\n'); | |||
} | |||
} | |||
@@ -21,7 +21,7 @@ bool LinkStep::checkHasChanged(const std::string &outDir) { | |||
BXVariables cachedVariables; | |||
try { | |||
std::ifstream f = sys::ifstream(confPath); | |||
bufio::IFStream f(confPath); | |||
BXParser parser(f, BXParser::FLAG_NONE); | |||
parser.parse(cachedVariables); | |||
} catch (BXParseError &err) { | |||
@@ -51,7 +51,7 @@ void LinkStep::doBuild(const std::string &outDir) { | |||
{ "command", command}, | |||
}; | |||
std::ofstream f = sys::ofstream(confPath(outDir)); | |||
bufio::OFStream f(confPath(outDir)); | |||
BXWriter writer(f); | |||
writer.write(newCachedVars); | |||
@@ -1,22 +1,65 @@ | |||
#pragma once | |||
#include <iostream> | |||
#include <fstream> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
namespace bufio { | |||
class IStream { | |||
public: | |||
virtual size_t read(char *buf, size_t maxlen) = 0; | |||
}; | |||
class IFStream: public IStream { | |||
public: | |||
IFStream(const char *path); | |||
IFStream(const std::string &path): IFStream(path.c_str()) {} | |||
size_t read(char *buf, size_t maxlen) override; | |||
private: | |||
std::ifstream is_; | |||
}; | |||
class ISStream: public IStream { | |||
public: | |||
ISStream(const std::string &str): str_(str) {} | |||
size_t read(char *buf, size_t maxlen) override; | |||
private: | |||
size_t idx_ = 0; | |||
const std::string &str_; | |||
}; | |||
class OStream { | |||
public: | |||
virtual void write(const char *buf, size_t len) = 0; | |||
}; | |||
class OFStream: public OStream { | |||
public: | |||
OFStream(const char *path); | |||
OFStream(const std::string &path): OFStream(path.c_str()) {} | |||
void write(const char *buf, size_t len) override; | |||
private: | |||
std::ofstream os_; | |||
}; | |||
template<size_t bufsiz = 1024> | |||
class IBuf { | |||
public: | |||
IBuf(std::istream &is): is_(is) {} | |||
IBuf(IStream &is): is_(is) {} | |||
char get(); | |||
int peek(); | |||
int peek2(); | |||
int peek(size_t count = 1); | |||
private: | |||
std::istream &is_; | |||
IStream &is_; | |||
char buf_[bufsiz]; | |||
size_t idx_ = 0; | |||
size_t len_ = 0; | |||
@@ -25,7 +68,7 @@ private: | |||
template<size_t bufsiz = 1024> | |||
class OBuf { | |||
public: | |||
OBuf(std::ostream &os): os_(os) {} | |||
OBuf(OStream &os): os_(os) {} | |||
~OBuf(); | |||
void put(char ch); | |||
@@ -34,11 +77,56 @@ public: | |||
void put(const std::string &str) { put(str.c_str(), str.size()); } | |||
private: | |||
std::ostream &os_; | |||
OStream &os_; | |||
char buf_[bufsiz]; | |||
size_t idx_ = 0; | |||
}; | |||
/* | |||
* IFStream | |||
*/ | |||
inline IFStream::IFStream(const char *path) { | |||
is_.exceptions(std::ifstream::badbit); | |||
is_.open(path); | |||
if (!is_.good()) { | |||
throw std::system_error(errno, std::generic_category(), path); | |||
} | |||
} | |||
inline size_t IFStream::read(char *buf, size_t maxlen) { | |||
is_.read(buf, maxlen); | |||
return is_.gcount(); | |||
} | |||
/* | |||
* ISStream | |||
*/ | |||
inline size_t ISStream::read(char *buf, size_t maxlen) { | |||
size_t left = str_.size() - idx_; | |||
size_t len = maxlen < left ? maxlen : left; | |||
idx_ += len; | |||
memcpy(buf, str_.c_str(), len); | |||
return len; | |||
} | |||
/* | |||
* OFStream | |||
*/ | |||
inline OFStream::OFStream(const char *path) { | |||
os_.exceptions(std::ofstream::badbit); | |||
os_.open(path); | |||
if (!os_.good()) { | |||
throw std::system_error(errno, std::generic_category(), path); | |||
} | |||
} | |||
inline void OFStream::write(const char *buf, size_t len) { | |||
os_.write(buf, len); | |||
} | |||
/* | |||
* IBuf | |||
*/ | |||
@@ -50,8 +138,7 @@ inline char IBuf<bufsiz>::get() { | |||
} | |||
idx_ = 0; | |||
is_.read(buf_, sizeof(buf_)); | |||
len_ = is_.gcount(); | |||
len_ = is_.read(buf_, sizeof(buf_)); | |||
if (len_ == 0) { | |||
return EOF; | |||
} | |||
@@ -60,25 +147,20 @@ inline char IBuf<bufsiz>::get() { | |||
} | |||
template<size_t bufsiz> | |||
inline int IBuf<bufsiz>::peek() { | |||
if (idx_ < len_) { | |||
return buf_[idx_]; | |||
inline int IBuf<bufsiz>::peek(size_t count) { | |||
size_t offset = count - 1; | |||
if (idx_ + offset < len_) { | |||
return buf_[idx_ + offset]; | |||
} else { | |||
return is_.peek(); | |||
} | |||
} | |||
len_ -= idx_; | |||
memcpy(buf_, buf_ + idx_, len_); | |||
idx_ = 0; | |||
len_ += is_.read(buf_ + len_, sizeof(buf_) - len_); | |||
if (len_ <= offset) { | |||
return EOF; | |||
} | |||
template<size_t bufsiz> | |||
inline int IBuf<bufsiz>::peek2() { | |||
if (idx_ + 1 < len_) { | |||
return buf_[idx_ + 1]; | |||
} else if (idx_ < len_) { | |||
return is_.peek(); | |||
} else { | |||
is_.get(); | |||
int ch = is_.peek(); | |||
is_.unget(); | |||
return ch; | |||
return buf_[idx_ + offset]; | |||
} | |||
} | |||
@@ -63,7 +63,7 @@ static void findDeps( | |||
subvars = variables; | |||
varsptr = &subvars; | |||
std::ifstream stream = sys::ifstream("build.bx"); | |||
bufio::IFStream stream("build.bx"); | |||
BXParser parser(stream, BXParser::FLAG_NONE); | |||
parser.parse(subvars); | |||
@@ -101,7 +101,7 @@ static std::string findTargetName(const BXVariables &variables) { | |||
std::unique_ptr<DepNode> buildDepTree(const std::string &outDir, BXVariables variables) { | |||
// Read config from file | |||
if (sys::fileExists("build.bx")) { | |||
std::ifstream stream = sys::ifstream("build.bx"); | |||
bufio::IFStream stream("build.bx"); | |||
BXParser parser(stream, BXParser::FLAG_NONE); | |||
parser.parse(variables); | |||
} |
@@ -10,7 +10,7 @@ namespace compdb { | |||
class Writer { | |||
public: | |||
Writer(std::ostream &stream): buf_(stream) {} | |||
Writer(bufio::OStream &stream): buf_(stream) {} | |||
~Writer(); | |||
void write( |
@@ -44,13 +44,13 @@ static void run(std::vector<std::string> args, std::vector<std::pair<std::string | |||
auto buildVariables = [&]() -> BXVariables { | |||
BXVariables variables; | |||
if (sys::fileExists(path + "/.config.bx")) { | |||
std::ifstream f = sys::ifstream(path + "/.config.bx"); | |||
bufio::IFStream f(path + "/.config.bx"); | |||
BXParser parser(f, BXParser::FLAG_NONE); | |||
parser.parse(variables); | |||
} | |||
for (auto &pair: kwargs) { | |||
std::stringstream ss(pair.second); | |||
bufio::ISStream ss(pair.second); | |||
BXParser parser(ss, BXParser::FLAG_NONE); | |||
auto &list = variables[pair.first]; | |||
list.clear(); | |||
@@ -58,7 +58,7 @@ static void run(std::vector<std::string> args, std::vector<std::pair<std::string | |||
} | |||
if (kwargs.size() > 0) { | |||
std::ofstream f = sys::ofstream(path + "/.config.bx"); | |||
bufio::OFStream f(path + "/.config.bx"); | |||
BXWriter w(f); | |||
w.write(variables); | |||
} | |||
@@ -71,7 +71,7 @@ static void run(std::vector<std::string> args, std::vector<std::pair<std::string | |||
}; | |||
auto buildCompileCommands = [&](DepNode &root) { | |||
std::ofstream f = sys::ofstream(path + "/compile_commands.json"); | |||
bufio::OFStream f(path + "/compile_commands.json"); | |||
compdb::Writer w(f); | |||
root.writeCompDB(path, w); | |||
sys::symlink(path + "/compile_commands.json", "compile_commands.json"); | |||
@@ -113,7 +113,7 @@ static void run(std::vector<std::string> args, std::vector<std::pair<std::string | |||
sys::rmrf(path); | |||
sys::rmrf("compile_commands.json"); | |||
sys::mkdirp(path); | |||
std::ofstream f = sys::ofstream(path + "/.config.bx"); | |||
bufio::OFStream f(path + "/.config.bx"); | |||
BXWriter w(f); | |||
w.write(variables); | |||
@@ -224,24 +224,4 @@ std::string dirname(const std::string &path) { | |||
return std::string(dir); | |||
} | |||
std::ofstream ofstream(const std::string &path) { | |||
std::ofstream f; | |||
f.exceptions(std::ofstream::badbit); | |||
f.open(path); | |||
if (!f.good()) { | |||
throw std::system_error(errno, std::generic_category(), path); | |||
} | |||
return f; | |||
} | |||
std::ifstream ifstream(const std::string &path) { | |||
std::ifstream f; | |||
f.exceptions(std::ifstream::badbit); | |||
f.open(path); | |||
if (!f.good()) { | |||
throw std::system_error(errno, std::generic_category(), path); | |||
} | |||
return f; | |||
} | |||
} |
@@ -28,7 +28,4 @@ std::string cwd(); | |||
void symlink(const std::string &from, const std::string &to); | |||
std::string dirname(const std::string &path); | |||
std::ofstream ofstream(const std::string &path); | |||
std::ifstream ifstream(const std::string &path); | |||
} |