| @@ -1,7 +1,7 @@ | |||
| SRCS = \ | |||
| src/BBBParser.cc src/SourceFile.cc src/toolchain.cc src/globals.cc \ | |||
| src/BBParser.cc src/SourceFile.cc src/toolchain.cc src/globals.cc \ | |||
| src/logger.cc src/sys.cc src/parallel.cc src/main.cc | |||
| HDRS = src/BBBParser.h src/SourceFile.h src/toolchain.h src/globals.h \ | |||
| HDRS = src/BBParser.h src/SourceFile.h src/toolchain.h src/globals.h \ | |||
| src/logger.h src/sys.h src/parallel.h | |||
| BUILD = build | |||
| OBJS = $(patsubst %,$(BUILD)/%.o,$(SRCS)) | |||
| @@ -16,11 +16,11 @@ as easy as possible. | |||
| `//#bb ldlibs := -lpthread ldflags := -fsanitize=address cflags := -fsanitize=address` | |||
| * A source file is automatically recompiled if it has changed, or if any | |||
| included header files have changed. | |||
| * If your project grows, you can put global configs in a `build.bbb` file. | |||
| Each directory can have a build.bbb file, and each directory inherits the | |||
| * If your project grows, you can put global configs in a `build.bb` file. | |||
| Each directory can have a build.bb file, and each directory inherits the | |||
| configuration of its parent. | |||
| * Files can be specified instead of discovered automatically by setting the | |||
| `files` variable in a `build.bbb` file. | |||
| `files` variable in a `build.bb` file. | |||
| ## Building | |||
| @@ -30,11 +30,11 @@ The only dependency is `pthreads`. | |||
| ## TODO | |||
| * Add `--print-compile-commands` | |||
| * Consider changing the config file format name from BBB to BB | |||
| * ~~Consider changing the config file format name from BBB to BB~~ | |||
| * Support different build configurations (requires conditionals in the BBB parser) | |||
| * Re-work the command-line interface | |||
| * Save build configuration in the output dir | |||
| * Support one "main" build.bbb file which specifies things like the target name | |||
| * ~~Support one "main" build.bb file which specifies things like the target name~~ | |||
| * Support creating shared/static libraries too, not just binaries | |||
| * Implement recursive mkdir in C++ instead of shelling out to mkdir | |||
| * Support subprojects | |||
| @@ -1,11 +1,11 @@ | |||
| #include "BBBParser.h" | |||
| #include "BBParser.h" | |||
| #include <stdlib.h> | |||
| #include <stdio.h> | |||
| #include <string.h> | |||
| #include <errno.h> | |||
| int BBBParser::get() { | |||
| int BBParser::get() { | |||
| int ch = stream_.get(); | |||
| if (ch == '\n') { | |||
| line_ += 1; | |||
| @@ -17,7 +17,7 @@ int BBBParser::get() { | |||
| return ch; | |||
| } | |||
| BBBParser::Operator BBBParser::readOperator() { | |||
| BBParser::Operator BBParser::readOperator() { | |||
| int ch2 = peek2(); | |||
| if (peek() == ':' && ch2 == '=') { | |||
| skip(); // ':' | |||
| @@ -36,7 +36,7 @@ BBBParser::Operator BBBParser::readOperator() { | |||
| return Operator::NONE; | |||
| } | |||
| void BBBParser::skip(char expected) { | |||
| void BBParser::skip(char expected) { | |||
| int ch = get(); | |||
| if (ch == EOF) { | |||
| error(std::string("Expected '") + expected + "', got EOF"); | |||
| @@ -45,8 +45,8 @@ void BBBParser::skip(char expected) { | |||
| } | |||
| } | |||
| [[noreturn]] void BBBParser::error(std::string msg) { | |||
| throw BBBParseError(std::to_string(line_) + ":" + std::to_string(ch_) + ": " + msg); | |||
| [[noreturn]] void BBParser::error(std::string msg) { | |||
| throw BBParseError(std::to_string(line_) + ":" + std::to_string(ch_) + ": " + msg); | |||
| } | |||
| static bool isWhitespace(int ch) { | |||
| @@ -55,7 +55,7 @@ static bool isWhitespace(int ch) { | |||
| return false; | |||
| } | |||
| void BBBParser::skipWhitespace() { | |||
| void BBParser::skipWhitespace() { | |||
| if (flags_ & FLAG_ONE_LINE) { | |||
| int ch; | |||
| while (isWhitespace(ch = peek()) && ch != '\r' && ch != '\n') | |||
| @@ -66,7 +66,7 @@ void BBBParser::skipWhitespace() { | |||
| } | |||
| } | |||
| char BBBParser::parseEscape() { | |||
| char BBParser::parseEscape() { | |||
| skip(); // '\' | |||
| int ch; | |||
| switch (ch = get()) { | |||
| @@ -88,7 +88,7 @@ char BBBParser::parseEscape() { | |||
| } | |||
| static void appendVariableToString( | |||
| const BBBParser::Variables &vars, std::string &name, | |||
| const BBParser::Variables &vars, std::string &name, | |||
| std::string &value) { | |||
| if (name.size() == 0) | |||
| return; | |||
| @@ -110,7 +110,7 @@ static void appendVariableToString( | |||
| } | |||
| static void appendVariableToArray( | |||
| const BBBParser::Variables &vars, const std::string &name, | |||
| const BBParser::Variables &vars, const std::string &name, | |||
| std::vector<std::string> &values) { | |||
| if (name.size() == 0) | |||
| return; | |||
| @@ -125,7 +125,7 @@ static void appendVariableToArray( | |||
| } | |||
| } | |||
| void BBBParser::parseExpansion(const Variables &vars, std::vector<std::string> &values) { | |||
| void BBParser::parseExpansion(const Variables &vars, std::vector<std::string> &values) { | |||
| skip(); // '$' | |||
| std::string str; | |||
| @@ -147,7 +147,7 @@ void BBBParser::parseExpansion(const Variables &vars, std::vector<std::string> & | |||
| } | |||
| } | |||
| void BBBParser::parseQuotedExpansion(const Variables &vars, std::string &content) { | |||
| void BBParser::parseQuotedExpansion(const Variables &vars, std::string &content) { | |||
| skip(); // '$' | |||
| std::string str; | |||
| @@ -169,7 +169,7 @@ void BBBParser::parseQuotedExpansion(const Variables &vars, std::string &content | |||
| } | |||
| } | |||
| void BBBParser::parseQuotedString(const Variables &vars, std::string &content) { | |||
| void BBParser::parseQuotedString(const Variables &vars, std::string &content) { | |||
| skip(); // '"' | |||
| int ch; | |||
| @@ -197,7 +197,7 @@ void BBBParser::parseQuotedString(const Variables &vars, std::string &content) { | |||
| } | |||
| } | |||
| bool BBBParser::parseString(const Variables &vars, std::string &content, int sep) { | |||
| bool BBParser::parseString(const Variables &vars, std::string &content, int sep) { | |||
| bool success = false; | |||
| int ch; | |||
| while (1) { | |||
| @@ -236,7 +236,7 @@ bool BBBParser::parseString(const Variables &vars, std::string &content, int sep | |||
| } | |||
| } | |||
| bool BBBParser::parseIdentifier(std::string &content) { | |||
| bool BBParser::parseIdentifier(std::string &content) { | |||
| int ch = peek(); | |||
| if (!( | |||
| (ch >= 'a' && ch <= 'z') || | |||
| @@ -261,7 +261,7 @@ bool BBBParser::parseIdentifier(std::string &content) { | |||
| } | |||
| } | |||
| void BBBParser::parse(Variables &vars) { | |||
| void BBParser::parse(Variables &vars) { | |||
| std::string key, value; | |||
| std::vector<std::string> values; | |||
| @@ -6,8 +6,8 @@ | |||
| #include <iostream> | |||
| #include <exception> | |||
| struct BBBParseError: std::exception { | |||
| BBBParseError(std::string msg): message(msg) {} | |||
| struct BBParseError: std::exception { | |||
| BBParseError(std::string msg): message(msg) {} | |||
| std::string message; | |||
| const char *what() const noexcept override { | |||
| @@ -15,14 +15,14 @@ struct BBBParseError: std::exception { | |||
| } | |||
| }; | |||
| class BBBParser { | |||
| class BBParser { | |||
| public: | |||
| using Variables = std::unordered_map<std::string, std::vector<std::string>>; | |||
| static const int FLAG_NONE = 0; | |||
| static const int FLAG_ONE_LINE = 1 << 0; | |||
| BBBParser(std::istream &stream, int flags, int line = 1, int ch = 1): | |||
| BBParser(std::istream &stream, int flags, int line = 1, int ch = 1): | |||
| flags_(flags), line_(line), ch_(ch), stream_(stream) {} | |||
| void parse(Variables &vars); | |||
| @@ -9,7 +9,7 @@ | |||
| #include "logger.h" | |||
| #include "globals.h" | |||
| static bool startsWith(BBBParser &parser, const char *str) { | |||
| static bool startsWith(BBParser &parser, const char *str) { | |||
| for (size_t i = 0; str[i] != '\0'; ++i) { | |||
| if (parser.peek() != str[i]) | |||
| return false; | |||
| @@ -43,12 +43,12 @@ SourceFile::FileType SourceFile::fileTypeFrom(const std::string &name) { | |||
| SourceFile::SourceFile( | |||
| std::string dir, std::string name, | |||
| FileType type, BBBParser::Variables vars): | |||
| FileType type, BBParser::Variables vars): | |||
| dir_(std::move(dir)), name_(std::move(name)), | |||
| type_(type), vars_(std::move(vars)) { | |||
| std::ifstream file(dir_ + "/" + name_); | |||
| BBBParser parser(file, BBBParser::FLAG_ONE_LINE); | |||
| BBParser parser(file, BBParser::FLAG_ONE_LINE); | |||
| while (file.good()) { | |||
| if (startsWith(parser, "//#bb")) { | |||
| @@ -4,7 +4,7 @@ | |||
| #include <string> | |||
| #include <optional> | |||
| #include "BBBParser.h" | |||
| #include "BBParser.h" | |||
| #include "sys.h" | |||
| class SourceFile { | |||
| @@ -17,13 +17,13 @@ public: | |||
| SourceFile( | |||
| std::string dir, std::string name, | |||
| FileType type, BBBParser::Variables vars); | |||
| FileType type, BBParser::Variables vars); | |||
| const std::string &dir() const { return dir_; } | |||
| const std::string &name() const { return name_; } | |||
| std::string path() const { return dir_ + '/' + name_; } | |||
| FileType type() const { return type_; } | |||
| const BBBParser::Variables &vars() const { return vars_; } | |||
| const BBParser::Variables &vars() const { return vars_; } | |||
| std::string objectPath(const std::string &outDir) const; | |||
| const std::vector<std::string> *variable(const std::string &name) const; | |||
| @@ -40,7 +40,7 @@ private: | |||
| std::string dir_; | |||
| std::string name_; | |||
| FileType type_; | |||
| BBBParser::Variables vars_; | |||
| BBParser::Variables vars_; | |||
| // Compile flags are cached, because they're used multiple times | |||
| mutable std::vector<std::string> compileFlags_; | |||
| @@ -11,23 +11,23 @@ | |||
| #include <mutex> | |||
| #include "SourceFile.h" | |||
| #include "BBBParser.h" | |||
| #include "BBParser.h" | |||
| #include "parallel.h" | |||
| #include "toolchain.h" | |||
| #include "globals.h" | |||
| #include "logger.h" | |||
| static void findSourcesInDir(std::string dir, std::vector<SourceFile> &sources, | |||
| BBBParser::Variables vars); | |||
| BBParser::Variables vars); | |||
| static void findSources(std::string dir, std::string name, | |||
| std::vector<SourceFile> &sources, BBBParser::Variables vars) { | |||
| std::vector<SourceFile> &sources, BBParser::Variables vars) { | |||
| std::string path = dir + "/" + name; | |||
| sys::FileInfo finfo = sys::fileInfo(path); | |||
| if (finfo.isDir) { | |||
| // We don't want to send 'files' | |||
| BBBParser::Variables subvars = vars; | |||
| BBParser::Variables subvars = vars; | |||
| subvars.erase("files"); | |||
| findSourcesInDir(path, sources, std::move(subvars)); | |||
| } else { | |||
| @@ -39,14 +39,14 @@ static void findSources(std::string dir, std::string name, | |||
| } | |||
| static void findSourcesInDir(std::string dir, std::vector<SourceFile> &sources, | |||
| BBBParser::Variables vars) { | |||
| std::ifstream buildFile(dir + "/build.bbb"); | |||
| BBParser::Variables vars) { | |||
| std::ifstream buildFile(dir + "/build.bb"); | |||
| std::vector<std::string> files; | |||
| bool hasFiles = false; | |||
| // Parse $dir/build.bbb, see if it specifies a 'files' value. | |||
| // Parse $dir/build.bb, see if it specifies a 'files' value. | |||
| if (buildFile.good()) { | |||
| BBBParser parser(buildFile, BBBParser::FLAG_NONE); | |||
| BBParser parser(buildFile, BBParser::FLAG_NONE); | |||
| parser.parse(vars); | |||
| auto it = vars.find("files"); | |||
| @@ -56,7 +56,7 @@ static void findSourcesInDir(std::string dir, std::vector<SourceFile> &sources, | |||
| } | |||
| } | |||
| // If build.bbb didn't specify 'files', we have to readdir | |||
| // If build.bb didn't specify 'files', we have to readdir | |||
| if (!hasFiles) { | |||
| sys::readDir(dir, files); | |||
| } | |||
| @@ -64,7 +64,7 @@ static void findSourcesInDir(std::string dir, std::vector<SourceFile> &sources, | |||
| // Go through files | |||
| for (auto &ent: files) { | |||
| std::string path = dir + "/" + ent; | |||
| BBBParser::Variables subvars = vars; | |||
| BBParser::Variables subvars = vars; | |||
| findSources(dir, ent, sources, vars); | |||
| } | |||
| } | |||
| @@ -256,17 +256,17 @@ int main(int argc, char **argv) { | |||
| } | |||
| // Read config from file | |||
| BBBParser::Variables variables; | |||
| if (sys::fileExists("build.bbb")) { | |||
| std::ifstream stream("build.bbb"); | |||
| BBBParser parser(stream, BBBParser::FLAG_NONE); | |||
| BBParser::Variables variables; | |||
| if (sys::fileExists("build.bb")) { | |||
| std::ifstream stream("build.bb"); | |||
| BBParser parser(stream, BBParser::FLAG_NONE); | |||
| parser.parse(variables); | |||
| } | |||
| // Read variables from argv | |||
| while (optind < argc) { | |||
| std::istringstream stream(argv[optind++]); | |||
| BBBParser parser(stream, BBBParser::FLAG_ONE_LINE); | |||
| BBParser parser(stream, BBParser::FLAG_ONE_LINE); | |||
| parser.parse(variables); | |||
| } | |||