diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/project.cc | 62 | ||||
-rw-r--r-- | common/project.h | 5 |
2 files changed, 52 insertions, 15 deletions
diff --git a/common/project.cc b/common/project.cc index 244ca761..949f6878 100644 --- a/common/project.cc +++ b/common/project.cc @@ -26,19 +26,53 @@ NEXTPNR_NAMESPACE_BEGIN +boost::filesystem::path make_relative(boost::filesystem::path child, boost::filesystem::path parent) +{ + boost::filesystem::path::const_iterator parentIter = parent.begin(); + boost::filesystem::path::const_iterator childIter = child.begin(); + + while (parentIter != parent.end() && childIter != child.end() && (*childIter) == (*parentIter)) { + ++childIter; + ++parentIter; + } + + boost::filesystem::path finalPath; + while (parentIter != parent.end()) { + finalPath /= ".."; + ++parentIter; + } + + while (childIter != child.end()) { + finalPath /= *childIter; + ++childIter; + } + + return finalPath; +} + void ProjectHandler::save(Context *ctx, std::string filename) { - std::ofstream f(filename); - pt::ptree root; - root.put("project.version", 1); - root.put("project.name", boost::filesystem::basename(filename)); - root.put("project.arch.name", ctx->archId().c_str(ctx)); - root.put("project.arch.type", ctx->archArgsToId(ctx->archArgs()).c_str(ctx)); - /* root.put("project.input.json", );*/ - root.put("project.params.freq", int(ctx->target_freq / 1e6)); - root.put("project.params.seed", ctx->rngstate); - saveArch(ctx, root); - pt::write_json(f, root); + try { + boost::filesystem::path proj(filename); + std::ofstream f(filename); + pt::ptree root; + + log_info("Saving project %s...\n", filename.c_str()); + log_break(); + + root.put("project.version", 1); + root.put("project.name", boost::filesystem::basename(filename)); + root.put("project.arch.name", ctx->archId().c_str(ctx)); + root.put("project.arch.type", ctx->archArgsToId(ctx->archArgs()).c_str(ctx)); + std::string fn = ctx->settings[ctx->id("project/input/json")]; + root.put("project.input.json", make_relative(fn, proj.parent_path()).string()); + root.put("project.params.freq", int(ctx->target_freq / 1e6)); + root.put("project.params.seed", ctx->rngstate); + saveArch(ctx, root, proj.parent_path().string()); + pt::write_json(f, root); + } catch (...) { + log_error("Error saving project file.\n"); + } } std::unique_ptr<Context> ProjectHandler::load(std::string filename) @@ -63,10 +97,10 @@ std::unique_ptr<Context> ProjectHandler::load(std::string filename) auto project = root.get_child("project"); auto input = project.get_child("input"); - std::string filename = input.get<std::string>("json"); - boost::filesystem::path json = proj.parent_path() / filename; + std::string fn = input.get<std::string>("json"); + boost::filesystem::path json = proj.parent_path() / fn; std::ifstream f(json.string()); - if (!parse_json_file(f, filename, ctx.get())) + if (!parse_json_file(f, fn, ctx.get())) log_error("Loading design failed.\n"); if (project.count("params")) { diff --git a/common/project.h b/common/project.h index 14f03ecd..03b4b7b5 100644 --- a/common/project.h +++ b/common/project.h @@ -20,6 +20,7 @@ #ifndef PROJECT_H #define PROJECT_H +#include <boost/filesystem/convenience.hpp> #include <boost/property_tree/ptree.hpp> #include "nextpnr.h" @@ -32,11 +33,13 @@ struct ProjectHandler void save(Context *ctx, std::string filename); std::unique_ptr<Context> load(std::string filename); // implemented per arch - void saveArch(Context *ctx, pt::ptree &root); + void saveArch(Context *ctx, pt::ptree &root, std::string path); std::unique_ptr<Context> createContext(pt::ptree &root); void loadArch(Context *ctx, pt::ptree &root, std::string path); }; +boost::filesystem::path make_relative(boost::filesystem::path child, boost::filesystem::path parent); + NEXTPNR_NAMESPACE_END #endif // PROJECT_H |