137 lines
3.6 KiB
C++
137 lines
3.6 KiB
C++
#include <vector>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
|
|
struct project_t {
|
|
std::string output;
|
|
std::vector<std::string> deps;
|
|
};
|
|
|
|
std::string read_str(std::istream &f, const std::string &skip_chars, const std::string &end_chars, int &end_char) {
|
|
std::vector<char> res { };
|
|
int c;
|
|
|
|
while (true) {
|
|
c = f.get();
|
|
auto a = end_chars.find(c);
|
|
if (c == -1 || a != std::string::npos) {
|
|
end_char = c;
|
|
return "";
|
|
}
|
|
if ((a = skip_chars.find(c)) == std::string::npos) {
|
|
f.unget();
|
|
break;
|
|
}
|
|
}
|
|
|
|
while (true) {
|
|
c = f.get();
|
|
if (c == -1 || end_chars.find(c) != std::string::npos) {
|
|
end_char = c;
|
|
break;
|
|
}
|
|
|
|
res.push_back(c);
|
|
}
|
|
while (true) {
|
|
if (skip_chars.find(res.back()) != std::string::npos) res.pop_back();
|
|
else break;
|
|
}
|
|
|
|
return std::string { res.begin(), res.end() };
|
|
}
|
|
std::string read_str(std::istream &f, const std::string &skip_chars, const std::string &end_chars) {
|
|
int end_char;
|
|
return read_str(f, skip_chars, end_chars, end_char);
|
|
}
|
|
|
|
project_t read_project(std::istream &f) {
|
|
int end_ch;
|
|
std::string name = read_str(f, " \v\t\r\n", "\n", end_ch);
|
|
std::size_t cap = 16, n = 0;
|
|
std::vector<std::string> deps { };
|
|
|
|
if (name.length() == 0) {
|
|
throw (std::string)"The name of a project may not be empty.";
|
|
}
|
|
|
|
if (end_ch == -1) {
|
|
return project_t {
|
|
.output = name,
|
|
.deps = deps,
|
|
};
|
|
}
|
|
|
|
if (name.find(',') != std::string::npos || name.find(' ') != std::string::npos) {
|
|
throw (std::string)"The name of a project may not contain spaces or commas.";
|
|
}
|
|
|
|
while (true) {
|
|
std::string dep = read_str(f, " \v\t\r\n", ",\n", end_ch);
|
|
|
|
if (dep.find(' ') != std::string::npos) {
|
|
throw (std::string)"The name of a dependency may not contain spaces.";
|
|
}
|
|
|
|
if (dep.length()) {
|
|
deps.push_back(dep);
|
|
if (end_ch == '\n') break;
|
|
}
|
|
if (end_ch == -1) break;
|
|
}
|
|
|
|
return project_t {
|
|
.output = name,
|
|
.deps = deps,
|
|
};
|
|
}
|
|
|
|
void print_err(const std::string &error, const std::string &context) {
|
|
std::cerr << context << ": " << error;
|
|
}
|
|
|
|
int main(int argc, const char* argv[]) {
|
|
std::string proj_name = "";
|
|
try {
|
|
argc--;
|
|
argv++;
|
|
|
|
if (argc != 3) {
|
|
throw (std::string)"Incorrect usage. Syntax: [src-dir] [project-name] [output|deps].";
|
|
}
|
|
|
|
std::string proj_path = (std::string)argv[0] + "/" + argv[1] + ".proj";
|
|
proj_name = argv[1];
|
|
|
|
std::ifstream f { proj_path, std::ios_base::in };
|
|
|
|
if (!f.is_open()) {
|
|
throw (std::string)"The project '" + argv[1] +"' doesn't exist.";
|
|
}
|
|
|
|
project_t project = read_project(f);
|
|
f.close();
|
|
|
|
if ((std::string)argv[2] == "output") {
|
|
std::cout << project.output;
|
|
}
|
|
else if ((std::string)argv[2] == "deps") {
|
|
for (std::string dep : project.deps) {
|
|
std::cout << dep << " ";
|
|
}
|
|
}
|
|
else {
|
|
throw (std::string)"Invalid command given. Available commands: output, deps.";
|
|
}
|
|
|
|
std::cout << std::endl;
|
|
|
|
return 0;
|
|
}
|
|
catch (std::string err) {
|
|
if (proj_name.length()) std::cerr << "Error: " << proj_name << ": " << err << std::endl;
|
|
else std::cerr << "Error: " << err << std::endl;
|
|
}
|
|
return -1;
|
|
}
|