Commit 7c9309be authored by Kenton Varda's avatar Kenton Varda

Implement more compiler options.

parent d67392cf
......@@ -73,6 +73,13 @@ public:
context, "Cap'n Proto compiler version 0.2",
"Compiles Cap'n Proto schema files and generates corresponding source code in one or "
"more languages.")
.addOptionWithArg({'I', "import-path"}, KJ_BIND_METHOD(*this, addImportPath), "<dir>",
"Add <dir> to the list of directories searched for non-relative "
"imports (ones that start with a '/').")
.addOption({"no-standard-import"}, KJ_BIND_METHOD(*this, noStandardImport),
"Do not add any default import paths; use only those specified by -I. "
"Otherwise, typically /usr/include and /usr/local/include are added by "
"default.")
.addOptionWithArg({'o', "output"}, KJ_BIND_METHOD(*this, addOutput), "<lang>[:<dir>]",
"Generate source code for language <lang> in directory <dir> (default: "
"current directory). <lang> actually specifies a plugin to use. If "
......@@ -80,11 +87,29 @@ public:
"'capnpc-<lang>' in $PATH. If <lang> is a file path containing slashes, "
"it is interpreted as the exact plugin executable file name, and $PATH "
"is not searched.")
.addOptionWithArg({"src-prefix"}, KJ_BIND_METHOD(*this, addSourcePrefix), "<prefix>",
"If a file specified for compilation starts with <prefix>, remove "
"the prefix for the purpose of deciding the names of output files. "
"For example, the following command:\n"
" capnp --src-prefix=foo/bar -oc++:corge foo/bar/baz/qux.capnp\n"
"would generate the files corge/baz/qux.capnp.{h,c++}.")
.addOption({'i', "generate-id"}, KJ_BIND_METHOD(*this, generateId),
"Generate a new 64-bit unique ID for use in a Cap'n Proto schema.")
.expectOneOrMoreArgs("source", KJ_BIND_METHOD(*this, addSource))
.callAfterParsing(KJ_BIND_METHOD(*this, generateOutput))
.build();
}
kj::MainBuilder::Validity addImportPath(kj::StringPtr path) {
loader.addImportPath(kj::heapString(path));
return true;
}
kj::MainBuilder::Validity noStandardImport() {
addStandardImportPaths = false;
return true;
}
kj::MainBuilder::Validity addOutput(kj::StringPtr spec) {
KJ_IF_MAYBE(split, spec.findFirst(':')) {
kj::StringPtr dir = spec.slice(*split + 1);
......@@ -100,8 +125,35 @@ public:
return true;
}
kj::MainBuilder::Validity addSourcePrefix(kj::StringPtr prefix) {
if (prefix.endsWith("/")) {
sourcePrefixes.add(kj::heapString(prefix));
} else {
sourcePrefixes.add(kj::str(prefix, '/'));
}
return true;
}
kj::MainBuilder::Validity generateId() {
context.exitInfo(kj::str("@0x", kj::hex(generateRandomId())));
}
kj::MainBuilder::Validity addSource(kj::StringPtr file) {
KJ_IF_MAYBE(module, loader.loadModule(file, file)) {
if (addStandardImportPaths) {
loader.addImportPath(kj::heapString("/usr/local/include"));
loader.addImportPath(kj::heapString("/usr/include"));
addStandardImportPaths = false;
}
size_t longestPrefix = 0;
for (auto& prefix: sourcePrefixes) {
if (file.startsWith(prefix)) {
longestPrefix = kj::max(longestPrefix, prefix.size());
}
}
KJ_IF_MAYBE(module, loader.loadModule(file, file.slice(longestPrefix))) {
sourceIds.add(compiler.add(*module, Compiler::EAGER));
} else {
return "no such file";
......@@ -219,6 +271,9 @@ private:
ModuleLoader loader;
Compiler compiler;
kj::Vector<kj::String> sourcePrefixes;
bool addStandardImportPaths = true;
kj::Vector<uint64_t> sourceIds;
struct OutputDirective {
......
......@@ -33,9 +33,7 @@
namespace capnp {
namespace compiler {
namespace {
uint64_t randomId() {
uint64_t generateRandomId() {
uint64_t result;
int fd;
......@@ -48,8 +46,6 @@ uint64_t randomId() {
return result | (1ull << 63);
}
} // namespace
void parseFile(List<Statement>::Reader statements, ParsedFile::Builder result,
const ErrorReporter& errorReporter) {
CapnpParser parser(Orphanage::getForMessageContaining(result), errorReporter);
......@@ -87,7 +83,7 @@ void parseFile(List<Statement>::Reader statements, ParsedFile::Builder result,
}
if (fileDecl.getId().which() != Declaration::Id::UID) {
uint64_t id = randomId();
uint64_t id = generateRandomId();
fileDecl.getId().initUid().setValue(id);
errorReporter.addError(0, 0,
kj::str("File does not declare an ID. I've generated one for you. Add this line to your "
......
......@@ -40,6 +40,9 @@ void parseFile(List<Statement>::Reader statements, ParsedFile::Builder result,
// If any errors are reported, then the output is not usable. However, it may be passed on through
// later stages of compilation in order to detect additional errors.
uint64_t generateRandomId();
// Generate a new random unique ID. This lives here mostly for lack of a better location.
class CapnpParser {
// Advanced parser interface. This interface exposes the inner parsers so that you can embed
// them into your own parsers.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment