Browse Source

progress

feature/dependency-graph
Martin Dørum 4 years ago
parent
commit
5341131447
6 changed files with 204 additions and 92 deletions
  1. 9
    0
      example-project/main.c
  2. 68
    67
      src/BBBParser.cc
  3. 6
    3
      src/BBBParser.h
  4. 3
    4
      src/SourceFile.cc
  5. 4
    0
      src/SourceFile.h
  6. 114
    18
      src/main.cc

+ 9
- 0
example-project/main.c View File

@@ -0,0 +1,9 @@
#include <math.h>
#include <stdio.h>

//#bb ldflags := -lm
//#bb pkgs := libsdl cairo

int main() {
printf("sin(PI) is %f\n", sin(M_PI));
}

+ 68
- 67
src/BBBParser.cc View File

@@ -130,20 +130,20 @@ void BBBParser::parseExpansion(const Variables &vars, std::vector<std::string> &

std::string str;
switch (peek()) {
case '{':
skip();
parseString(vars, str, '}');
skip('}');
appendVariableToArray(vars, str, values);
break;
default:
if (!parseIdentifier(str)) {
error("No identifier after $.");
}
case '{':
skip();
parseString(vars, str, '}');
skip('}');
appendVariableToArray(vars, str, values);
break;
default:
if (!parseIdentifier(str)) {
error("No identifier after $.");
}

appendVariableToArray(vars, str, values);
break;
appendVariableToArray(vars, str, values);
break;
}
}

@@ -152,20 +152,20 @@ void BBBParser::parseQuotedExpansion(const Variables &vars, std::string &content

std::string str;
switch (peek()) {
case '{':
skip();
parseString(vars, str, '}');
skip('}');
appendVariableToString(vars, str, content);
break;

default:
if (!parseIdentifier(str)) {
error("No identifier after $.");
}
case '{':
skip();
parseString(vars, str, '}');
skip('}');
appendVariableToString(vars, str, content);
break;

appendVariableToString(vars, str, content);
break;
default:
if (!parseIdentifier(str)) {
error("No identifier after $.");
}

appendVariableToString(vars, str, content);
break;
}
}

@@ -175,24 +175,24 @@ void BBBParser::parseQuotedString(const Variables &vars, std::string &content) {
int ch;
while ((ch = peek()) != EOF) {
switch (ch) {
case EOF:
error("Unexpected EOF");
case EOF:
error("Unexpected EOF");

case '\\':
content.push_back(parseEscape());
break;
case '\\':
content.push_back(parseEscape());
break;

case '$':
parseQuotedExpansion(vars, content);
break;
case '$':
parseQuotedExpansion(vars, content);
break;

case '"':
skip();
return;
case '"':
skip();
return;

default:
content.push_back(get());
break;
default:
content.push_back(get());
break;
}
}
}
@@ -207,31 +207,31 @@ bool BBBParser::parseString(const Variables &vars, std::string &content, int sep
}

switch (ch) {
case EOF:
return success;
case EOF:
return success;

case '\\':
content.push_back(parseEscape());
success = true;
break;
case '\\':
content.push_back(parseEscape());
success = true;
break;

case '$':
parseQuotedExpansion(vars, content);
success = true;
break;
case '$':
parseQuotedExpansion(vars, content);
success = true;
break;

case '"':
parseQuotedString(vars, content);
success = true;
break;
case '"':
parseQuotedString(vars, content);
success = true;
break;

default:
if (ch == ':' && peek2() == '=')
return success;
default:
if (ch == ':' && peek2() == '=')
return success;

content.push_back(get());
success = true;
break;
content.push_back(get());
success = true;
break;
}
}
}
@@ -239,9 +239,9 @@ bool BBBParser::parseString(const Variables &vars, std::string &content, int sep
bool BBBParser::parseIdentifier(std::string &content) {
int ch = peek();
if (!(
(ch >= 'a' && ch <= 'z') ||
(ch >= 'A' && ch <= 'Z') ||
(ch == '_'))) {
(ch >= 'a' && ch <= 'z') ||
(ch >= 'A' && ch <= 'Z') ||
(ch == '_'))) {
return false;
}

@@ -250,10 +250,10 @@ bool BBBParser::parseIdentifier(std::string &content) {
while (1) {
ch = peek();
if (!(
(ch >= '0' && ch <= '9') ||
(ch >= 'a' && ch <= 'z') ||
(ch >= 'A' && ch <= 'Z') ||
(ch == '_'))) {
(ch >= '0' && ch <= '9') ||
(ch >= 'a' && ch <= 'z') ||
(ch >= 'A' && ch <= 'Z') ||
(ch == '_'))) {
return true;
}

@@ -270,6 +270,7 @@ void BBBParser::parse(Variables &vars) {
return;
}

skipWhitespace();
Operator prevOper = readOperator();
if (prevOper == Operator::NONE) {
error("Expected operator.");

+ 6
- 3
src/BBBParser.h View File

@@ -33,9 +33,8 @@ public:
void skip(char);
void skip() { get(); }

int flags_;
int line_;
int ch_;
int line() const { return line_; }
int ch() const { return ch_; }

private:
enum class Operator {
@@ -57,5 +56,9 @@ private:
bool parseString(const Variables &vars, std::string &content, int sep = -1);
bool parseIdentifier(std::string &content);


int flags_;
int line_;
int ch_;
std::istream &stream_;
};

+ 3
- 4
src/SourceFile.cc View File

@@ -6,8 +6,9 @@

static bool startsWith(BBBParser &parser, const char *str) {
for (size_t i = 0; str[i] != '\0'; ++i) {
if (parser.get() != str[i])
if (parser.peek() != str[i])
return false;
parser.skip();
}

return true;
@@ -19,13 +20,11 @@ SourceFile::SourceFile(std::string dir, std::string name, BBBParser::Variables v
std::ifstream file(dir_ + "/" + name_);
BBBParser parser(file, BBBParser::FLAG_ONE_LINE);

bool freshLine = true;
while (file.good()) {
if (freshLine && startsWith(parser, "//#bb")) {
if (startsWith(parser, "//#bb")) {
parser.parse(vars_);
} else {
while (file.good() && parser.get() != '\n');
freshLine = true;
}
}
}

+ 4
- 0
src/SourceFile.h View File

@@ -9,6 +9,10 @@ class SourceFile {
public:
SourceFile(std::string dir, std::string name, BBBParser::Variables vars);

const std::string &dir() const { return dir_; }
const std::string &name() const { return name_; }
const BBBParser::Variables &vars() const { return vars_; }

private:
std::string dir_;
std::string name_;

+ 114
- 18
src/main.cc View File

@@ -1,16 +1,40 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <getopt.h>
#include <dirent.h>
#include <stdexcept>
#include <string.h>
#include <errno.h>
#include <fstream>
#include <iostream>

#include "SourceFile.h"
#include "BBBParser.h"

void readDir(std::string dir, std::vector<SourceFile> &sources, BBBParser::Variables vars) {
static void readDir(std::string dir, std::vector<SourceFile> &sources,
BBBParser::Variables vars);

static void readPath(std::string dir, std::string name,
std::vector<SourceFile> &sources, BBBParser::Variables vars) {
std::string path = dir + "/" + name;
struct stat st;
if (stat(path.c_str(), &st) < 0) {
throw std::runtime_error("stat '" + path + "': " + strerror(errno));
}

if (S_ISDIR(st.st_mode)) {
// We don't want to send 'files'
BBBParser::Variables subvars = vars;
subvars.erase("files");
readDir(path, sources, std::move(subvars));
} else {
sources.emplace_back(dir, name, vars);
}
}

static void readDir(std::string dir, std::vector<SourceFile> &sources,
BBBParser::Variables vars) {
std::ifstream buildFile(dir + "/build.bbb");
std::vector<std::string> files;
bool hasFiles = false;
@@ -37,6 +61,8 @@ void readDir(std::string dir, std::vector<SourceFile> &sources, BBBParser::Varia

struct dirent *ent;
while ((ent = readdir(d)) != NULL) {
if (ent->d_name[0] == '.')
continue;
files.emplace_back(ent->d_name);
}

@@ -46,31 +72,101 @@ void readDir(std::string dir, std::vector<SourceFile> &sources, BBBParser::Varia
// Go through files
for (auto &ent: files) {
std::string path = dir + "/" + ent;
struct stat st;
if (stat(path.c_str(), &st) < 0) {
throw std::runtime_error("stat '" + path + "': " + strerror(errno));
}
BBBParser::Variables subvars = vars;
readPath(dir, ent, sources, vars);
}
}

if (S_ISDIR(st.st_mode)) {
readDir(path, sources, vars);
} else {
sources.emplace_back(dir, ent, vars);
void printState(const std::vector<SourceFile> &sources) {
for (auto &source: sources) {
std::cout << source.dir() << '/' << source.name() << ":\n";
for (auto &kv: source.vars()) {
std::cout << " " << kv.first << ":\n";
for (auto &val: kv.second) {
std::cout << " " << val << '\n';
}
}
}
}

int main(int argc, char **argv) {
std::ifstream file("sample.bbb");
BBBParser parser(file, BBBParser::FLAG_NONE);
std::vector<std::string> srcDirs;
std::string outdir = "bbbuild";

enum class Action {
BUILD, PRINT_STATE,
};
Action action = Action::BUILD;

BBBParser::Variables vars;
parser.parse(vars);
const char *shortopts = "o:hp";
const struct option opts[] = {
{ "help", no_argument, NULL, 'h' },
{ "output", required_argument, NULL, 'o' },
{ "print-state", no_argument, NULL, 'p' },
{},
};

std::cout << "\nVariables found:\n";
for (auto &kv: vars) {
std::cout << kv.first << ":\n";
for (auto &val: kv.second) {
std::cout << "\t'" << val << "'\n";
const char usage[] =
"Usage: bbbuild [options...] [sources]\n"
"\n"
" -h, --help "
"Show this help text.\n"
" -o, --output <dir> "
"Set output directory.\n"
" -p, --print-state "
"Print the state instead of building.\n";

// Parse options from argv
while (1) {
int optidx;
int c = getopt_long(argc, argv, shortopts, opts, &optidx);

if (c < 0) {
break;
}

switch (c) {
case 'h':
puts(usage);
return 0;

case 'o':
outdir = optarg;
break;

case 'p':
action = Action::PRINT_STATE;
break;

default:
printf("Unknown option: '%c'.\n%s", (char)c, usage);
break;
return 1;
}
}

// Parse non-opt argv as source dirs
if (optind < argc) {
while (optind < argc) {
srcDirs.push_back(argv[optind++]);
}
} else {
srcDirs.push_back(".");
}

// Read configs from source dirs
std::vector<SourceFile> sources;
for (std::string &dir: srcDirs) {
readDir(dir, sources, {});
}

switch (action) {
case Action::BUILD:
std::cerr << "Building is not implemented yet.\n";
abort();

case Action::PRINT_STATE:
printState(sources);
break;
}
}

Loading…
Cancel
Save