diff --git a/include/flatbuffers/util.h b/include/flatbuffers/util.h index fa1b60ccf..38402154b 100644 --- a/include/flatbuffers/util.h +++ b/include/flatbuffers/util.h @@ -22,6 +22,11 @@ #include #include #include +#ifdef _WIN32 +#include +#else +#include +#endif namespace flatbuffers { @@ -103,25 +108,40 @@ inline bool SaveFile(const char *name, const std::string &buf, bool binary) { static const char kPosixPathSeparator = '/'; #ifdef _WIN32 static const char kPathSeparator = '\\'; -static const char *PathSeparatorSet = "\\:/"; +static const char *PathSeparatorSet = "\\/"; // Intentionally no ':' #else static const char kPathSeparator = kPosixPathSeparator; static const char *PathSeparatorSet = "/"; #endif // _WIN32 +// Returns the path with the extension, if any, removed. inline std::string StripExtension(const std::string &filepath) { size_t i = filepath.find_last_of("."); return i != std::string::npos ? filepath.substr(0, i) : filepath; } +// Return the last component of the path, after the last separator. inline std::string StripPath(const std::string &filepath) { size_t i = filepath.find_last_of(PathSeparatorSet); return i != std::string::npos ? filepath.substr(i + 1) : filepath; } +// Strip the last component of the path + separator. inline std::string StripFileName(const std::string &filepath) { size_t i = filepath.find_last_of(PathSeparatorSet); - return i != std::string::npos ? filepath.substr(0, i + 1) : ""; + return i != std::string::npos ? filepath.substr(0, i) : ""; +} + +// This function ensure a directory exists, by recursively +// creating dirs for any parts of the path that don't exist yet. +inline void EnsureDirExists(const std::string &filepath) { + auto parent = StripFileName(filepath); + if (parent.length()) EnsureDirExists(parent); + #ifdef _WIN32 + _mkdir(filepath.c_str()) + #else + mkdir(filepath.c_str(), S_IRWXU|S_IRGRP|S_IXGRP); + #endif } // To and from UTF-8 unicode conversion functions diff --git a/src/flatc.cpp b/src/flatc.cpp index 0bc964d21..599a9c8c1 100755 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -180,6 +180,7 @@ int main(int argc, const char *argv[]) { for (size_t i = 0; i < num_generators; ++i) { if (generator_enabled[i]) { + flatbuffers::EnsureDirExists(output_path); if (!generators[i].generate(parser, output_path, filebase, opts)) { Error((std::string("Unable to generate ") + generators[i].name + diff --git a/src/idl_gen_java.cpp b/src/idl_gen_java.cpp index b6fc148b4..3009d4b0c 100755 --- a/src/idl_gen_java.cpp +++ b/src/idl_gen_java.cpp @@ -20,13 +20,6 @@ #include "flatbuffers/idl.h" #include "flatbuffers/util.h" -#ifdef _WIN32 -#include -#define mkdir(n, m) _mkdir(n) -#else -#include -#endif - namespace flatbuffers { namespace java { @@ -351,8 +344,8 @@ static bool SaveClass(const Parser &parser, const Definition &def, } namespace_java += *it; namespace_dir += *it; - mkdir(namespace_dir.c_str(), S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); } + EnsureDirExists(namespace_dir); std::string code = "// automatically generated, do not modify\n\n"; code += "package " + namespace_java + ";\n\n"; diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index 2eb6441dd..d3b95192e 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -838,7 +838,8 @@ bool Parser::Parse(const char *source, const char *filepath) { while (IsNext(kTokenInclude)) { auto name = attribute_; Expect(kTokenStringConstant); - name = StripFileName(filepath) + name; + auto path = StripFileName(filepath); + if (path.length()) name = path + kPathSeparator + name; if (included_files_.find(name) == included_files_.end()) { // We found an include file that we have not parsed yet. // Load it and parse it.