#pragma once #include #include #include #include namespace ninja { enum class NinjaError { NONE, VARIABLE_ALREADY_DEFINED, RULE_ALREADY_DEFINED, INVALID_NAME }; class NinjaException : public std::runtime_error { public: NinjaException(const NinjaError _errorCode, const std::string &errMsg = "") : std::runtime_error(errMsg), errorCode(_errorCode) { } const NinjaError errorCode; }; struct NinjaVariable { NinjaVariable(const std::string &name); const std::string name; }; class NinjaBuildFile; class NinjaArg { public: enum class Type { NONE, VALUE, VARIABLE, RAW }; NinjaArg() : type(Type::NONE) {} NinjaArg(const std::string &value) : type(Type::VALUE), arg(value) {} NinjaArg(const NinjaVariable &var) : type(Type::VARIABLE), arg(var.name) {} static NinjaArg createRaw(const std::string &value) { NinjaArg arg; arg.type = Type::RAW; arg.arg = value; return arg; } Type type; std::string arg; }; struct NinjaArgValue { const NinjaVariable arg; const std::string value; }; // Functions throw NinjaException on failure class NinjaRule { public: NinjaRule(NinjaBuildFile *buildFile, const std::string &name, const std::string &command); void build(const std::string &in, const std::string &out, const std::vector &additionalArgs); const std::string name; const std::string command; std::string depFile; private: NinjaBuildFile *buildFile; }; struct NinjaBuild { const NinjaRule *rule; const std::string in; const std::string out; const std::vector additionalArgs; }; // Functions throw NinjaException on failure class NinjaBuildFile { public: ~NinjaBuildFile(); void defineGlobalVariable(const std::string &name, const std::string &value); NinjaRule* createRule(const std::string &name, const std::vector &commandArgs); void build(const NinjaRule *rule, const std::string &in, const std::string &out, const std::vector &additionalArgs); std::string generate() const; private: std::unordered_map globalVariables; std::unordered_map rules; std::vector builds; }; }