// file : libbuild2/in/rule.hxx -*- C++ -*- // license : MIT; see accompanying LICENSE file #ifndef LIBBUILD2_IN_RULE_HXX #define LIBBUILD2_IN_RULE_HXX #include <libbuild2/types.hxx> #include <libbuild2/forward.hxx> // depdb #include <libbuild2/utility.hxx> #include <libbuild2/rule.hxx> #include <libbuild2/in/export.hxx> namespace build2 { namespace in { // Preprocess an .in file. // // Note that a derived rule can use the target auxiliary data storage to // cache data (e.g., in match() or apply()) to be used in substitute() and // lookup() calls. // // Note also that currently this rule ignores the dry-run mode (see // perform_update() for the rationale). // class LIBBUILD2_IN_SYMEXPORT rule: public simple_rule { public: // The rule id is used to form the rule name/version entry in depdb. The // program argument is the pseudo-program name to use in the command // line diagnostics. // rule (string rule_id, string program, char symbol = '$', bool strict = true, optional<string> null = nullopt) : rule_id_ (move (rule_id)), program_ (move (program)), symbol_ (symbol), strict_ (strict), null_ (move (null)) {} virtual bool match (action, target&) const override; virtual recipe apply (action, target&) const override; virtual target_state perform_update (action, const target&) const; // Customization hooks and helpers. // // Perform prerequisite search. // virtual prerequisite_target search (action, const target&, const prerequisite_member&, include_type) const; // Additional depdb entries. // virtual void perform_update_depdb (action, const target&, depdb&) const; // Pre/post update. // virtual void perform_update_pre (action, const target&, ofdstream&, const char* newline) const; virtual void perform_update_post (action, const target&, ofdstream&, const char* newline) const; // Perform variable lookup. // // Flags can be used by a custom implementation to alter the lookup // semantics, for example, for special substitutions. Note, however, // that one must make sure this semantics cannot change without changes // to the .in file (see the depdb logic for details). // virtual string lookup (const location&, action, const target&, const string& name, optional<uint64_t> flags, const optional<string>& null) const; // Perform variable substitution. Return nullopt if it should be // ignored. // virtual optional<string> substitute (const location&, action, const target&, const string& name, optional<uint64_t> flags, bool strict, const optional<string>& null) const; // Call the above version and do any necessary depdb saving. // optional<string> substitute (const location&, action, const target&, depdb& dd, size_t& dd_skip, const string& name, optional<uint64_t> flags, bool strict, const optional<string>& null) const; // Process a line of input from the specified position performing any // necessary substitutions. // virtual void process (const location&, action, const target&, depdb& dd, size_t& dd_skip, string& line, size_t pos, const char* newline, char sym, bool strict, const optional<string>& null) const; // Replace newlines in a multi-line value with the given newline // sequence. // static void replace_newlines (string& v, const char* newline) { for (size_t p (0), n; (p = v.find ('\n', p)) != string::npos; p += n) { n = 1; // Deal with CRLF in the value. // if (p != 0 && v[p - 1] == '\r') { --p; ++n; } v.replace (p, n, newline); } } protected: const string rule_id_; const string program_; char symbol_; bool strict_; optional<string> null_; }; } } #endif // LIBBUILD2_IN_RULE_HXX