@@ -5,10 +5,10 @@ SRCS = \ | |||
HDRS = \ | |||
src/BXParser.h src/build.h src/compdb.h src/CompileStep.h src/DepNode.h \ | |||
src/globals.h src/LinkStep.h src/logger.h src/parallel.h src/sys.h \ | |||
src/toolchain.h | |||
src/toolchain.h src/bufio.h | |||
BUILD = build | |||
OBJS = $(patsubst %,$(BUILD)/%.o,$(SRCS)) | |||
CFLAGS = -g -O3 -Wall -Wextra -Wno-unused-parameter | |||
CFLAGS = -O3 -g -Wall -Wextra -Wno-unused-parameter | |||
LDLIBS = -lpthread | |||
$(BUILD)/%.cc.o: %.cc $(HDRS) |
@@ -6,37 +6,22 @@ | |||
#include <errno.h> | |||
int BXParser::get() { | |||
if (bufidx_ < buflen_) { | |||
return buf_[bufidx_++]; | |||
int c = buf_.get(); | |||
ch_ += 1; | |||
if (c == '\n') { | |||
ch_ = 1; | |||
line_ += 1; | |||
} | |||
bufidx_ = 0; | |||
stream_.read(buf_, sizeof(buf_)); | |||
buflen_ = stream_.gcount(); | |||
if (buflen_ == 0) { | |||
return EOF; | |||
} | |||
return buf_[bufidx_++]; | |||
return c; | |||
} | |||
int BXParser::peek() { | |||
if (bufidx_ < buflen_) { | |||
return buf_[bufidx_]; | |||
} else { | |||
return stream_.peek(); | |||
} | |||
return buf_.peek(); | |||
} | |||
int BXParser::peek2() { | |||
if (bufidx_ + 1 < buflen_) { | |||
return buf_[bufidx_ + 1]; | |||
} else { | |||
stream_.get(); | |||
int ch = stream_.peek(); | |||
stream_.unget(); | |||
return ch; | |||
} | |||
return buf_.peek2(); | |||
} | |||
BXParser::Operator BXParser::readOperator() { | |||
@@ -380,65 +365,34 @@ void BXParser::parseList(const BXVariables &vars, std::vector<std::string> &valu | |||
} | |||
} | |||
BXWriter::~BXWriter() { | |||
if (bufidx_ > 0) { | |||
stream_.write(buf_, bufidx_); | |||
} | |||
} | |||
void BXWriter::put(char ch) { | |||
buf_[bufidx_++] = ch; | |||
if (bufidx_ == sizeof(buf_)) { | |||
stream_.write(buf_, sizeof(buf_)); | |||
bufidx_ = 0; | |||
} | |||
} | |||
void BXWriter::put(const std::string &str) { | |||
size_t w = sizeof(buf_) - bufidx_; | |||
if (w > str.size()) { | |||
w = str.size(); | |||
} | |||
memcpy(buf_ + bufidx_, str.c_str(), w); | |||
if (str.size() - w > 0) { | |||
stream_.write(buf_, bufidx_ + w); | |||
stream_.write(str.c_str() + w, str.size() - w); | |||
bufidx_ = 0; | |||
} else { | |||
bufidx_ += w; | |||
} | |||
} | |||
void BXWriter::escape(const std::string &str) { | |||
put('"'); | |||
buf_.put('"'); | |||
for (char ch: str) { | |||
if (ch == '$' || ch == '"' || ch == '\\') { | |||
put('\\'); | |||
buf_.put('\\'); | |||
} | |||
put(ch); | |||
buf_.put(ch); | |||
} | |||
put('"'); | |||
buf_.put('"'); | |||
} | |||
void BXWriter::write(const BXVariables &vars) { | |||
for (const auto &pair: vars) { | |||
size_t chars = 0; | |||
put(pair.first); | |||
put(" :="); | |||
buf_.put(pair.first); | |||
buf_.put(" :="); | |||
for (auto &val: pair.second) { | |||
if (chars >= 80) { | |||
put('\n'); | |||
put('\t'); | |||
buf_.put('\n'); | |||
buf_.put('\t'); | |||
chars = 0; | |||
} else { | |||
put(' '); | |||
buf_.put(' '); | |||
} | |||
escape(val); | |||
chars += val.size(); | |||
} | |||
put('\n'); | |||
buf_.put('\n'); | |||
} | |||
} |
@@ -6,6 +6,8 @@ | |||
#include <iostream> | |||
#include <exception> | |||
#include "bufio.h" | |||
struct BXParseError: std::exception { | |||
BXParseError(std::string msg): message(msg) {} | |||
std::string message; | |||
@@ -23,7 +25,7 @@ public: | |||
static const int FLAG_ONE_LINE = 1 << 0; | |||
BXParser(std::istream &stream, int flags, int line = 1, int ch = 1): | |||
flags_(flags), line_(line), ch_(ch), stream_(stream) {} | |||
flags_(flags), line_(line), ch_(ch), buf_(stream) {} | |||
void parse(BXVariables &vars); | |||
void parseList(const BXVariables &vars, std::vector<std::string> &values); | |||
@@ -62,26 +64,18 @@ private: | |||
int line_; | |||
int ch_; | |||
std::istream &stream_; | |||
char buf_[1024]; | |||
size_t bufidx_ = 0; | |||
size_t buflen_ = 0; | |||
bufio::IBuf<> buf_; | |||
}; | |||
class BXWriter { | |||
public: | |||
BXWriter(std::ostream &stream): stream_(stream) {} | |||
~BXWriter(); | |||
BXWriter(std::ostream &stream): buf_(stream) {} | |||
void write(const BXVariables &vars); | |||
private: | |||
void put(char ch); | |||
void put(const std::string &str); | |||
void newline(); | |||
void escape(const std::string &str); | |||
std::ostream &stream_; | |||
char buf_[1024]; | |||
size_t bufidx_ = 0; | |||
bufio::OBuf<> buf_; | |||
}; |
@@ -85,7 +85,7 @@ void DepNode::joinBuild() { | |||
} | |||
void DepNode::writeCompDB(const std::string &outDir, compdb::Writer &w) { | |||
std::unique_lock<std::mutex> lock(mut_);\ | |||
std::unique_lock<std::mutex> lock(mut_); | |||
doWriteCompDB(outDir, w); | |||
lock.unlock(); | |||
@@ -0,0 +1,123 @@ | |||
#pragma once | |||
#include <iostream> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
namespace bufio { | |||
template<size_t bufsiz = 1024> | |||
class IBuf { | |||
public: | |||
IBuf(std::istream &is): is_(is) {} | |||
char get(); | |||
int peek(); | |||
int peek2(); | |||
private: | |||
std::istream &is_; | |||
char buf_[bufsiz]; | |||
size_t idx_ = 0; | |||
size_t len_ = 0; | |||
}; | |||
template<size_t bufsiz = 1024> | |||
class OBuf { | |||
public: | |||
OBuf(std::ostream &os): os_(os) {} | |||
~OBuf(); | |||
void put(char ch); | |||
void put(const char *str, size_t len); | |||
void put(const char *str) { put(str, strlen(str)); } | |||
void put(const std::string &str) { put(str.c_str(), str.size()); } | |||
private: | |||
std::ostream &os_; | |||
char buf_[bufsiz]; | |||
size_t idx_ = 0; | |||
}; | |||
/* | |||
* IBuf | |||
*/ | |||
template<size_t bufsiz> | |||
inline char IBuf<bufsiz>::get() { | |||
if (idx_ < len_) { | |||
return buf_[idx_++]; | |||
} | |||
idx_ = 0; | |||
is_.read(buf_, sizeof(buf_)); | |||
len_ = is_.gcount(); | |||
if (len_ == 0) { | |||
return EOF; | |||
} | |||
return buf_[idx_++]; | |||
} | |||
template<size_t bufsiz> | |||
inline int IBuf<bufsiz>::peek() { | |||
if (idx_ < len_) { | |||
return buf_[idx_]; | |||
} else { | |||
return is_.peek(); | |||
} | |||
} | |||
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; | |||
} | |||
} | |||
/* | |||
* OBuf | |||
*/ | |||
template<size_t bufsiz> | |||
inline OBuf<bufsiz>::~OBuf() { | |||
if (idx_ > 0) { | |||
os_.write(buf_, idx_); | |||
} | |||
} | |||
template<size_t bufsiz> | |||
inline void OBuf<bufsiz>::put(char ch) { | |||
buf_[idx_++] = ch; | |||
if (idx_ == sizeof(buf_)) { | |||
os_.write(buf_, sizeof(buf_)); | |||
idx_ = 0; | |||
} | |||
} | |||
template<size_t bufsiz> | |||
inline void OBuf<bufsiz>::put(const char *str, size_t len) { | |||
size_t w = sizeof(buf_) - idx_ - 1; | |||
if (w > len) { | |||
w = len; | |||
} | |||
memcpy(buf_ + idx_, str, w); | |||
if (len - w > 0) { | |||
os_.write(buf_, idx_ + w); | |||
os_.write(str + w, len - w); | |||
idx_ = 0; | |||
} else { | |||
idx_ += w; | |||
} | |||
} | |||
} |
@@ -29,29 +29,34 @@ void Writer::write( | |||
const std::string &dir, const std::string &file, | |||
const std::vector<std::string> &cmd) { | |||
if (first_) { | |||
stream_ << "[\n\t{\n"; | |||
buf_.put("[\n\t{\n"); | |||
first_ = false; | |||
} else { | |||
stream_ << ", {\n"; | |||
buf_.put(", {\n"); | |||
} | |||
stream_ | |||
<< "\t\t\"directory\": \"" << escape(dir) << "\",\n" | |||
<< "\t\t\"file\": \"" << escape(file) << "\",\n" | |||
<< "\t\t\"command\": \"" << escape(cmd[0]); | |||
buf_.put("\t\t\"directory\": \""); | |||
buf_.put(escape(dir)); | |||
buf_.put("\",\n"); | |||
buf_.put("\t\t\"file\": \""); | |||
buf_.put(escape(file)); | |||
buf_.put("\",\n"); | |||
buf_.put("\t\t\"command\": \""); | |||
buf_.put(escape(cmd[0])); | |||
for (size_t i = 1; i < cmd.size(); ++i) { | |||
stream_ << ' ' << escape('"' + escape(cmd[i]) + '"'); | |||
buf_.put(' '); | |||
buf_.put(escape('"' + escape(cmd[i]) + '"')); | |||
} | |||
stream_ << "\"\n\t}"; | |||
buf_.put("\"\n\t}"); | |||
} | |||
Writer::~Writer() { | |||
if (first_) { | |||
stream_ << "[]\n"; | |||
buf_.put("[]\n"); | |||
} else { | |||
stream_ << "\n]\n"; | |||
buf_.put("\n]\n"); | |||
} | |||
} | |||
@@ -4,11 +4,13 @@ | |||
#include <vector> | |||
#include <ostream> | |||
#include "bufio.h" | |||
namespace compdb { | |||
class Writer { | |||
public: | |||
Writer(std::ostream &stream): stream_(stream) {} | |||
Writer(std::ostream &stream): buf_(stream) {} | |||
~Writer(); | |||
void write( | |||
@@ -16,7 +18,7 @@ public: | |||
const std::vector<std::string> &cmd); | |||
private: | |||
std::ostream &stream_; | |||
bufio::OBuf<> buf_; | |||
bool first_ = true; | |||
}; | |||