// file : libbuild2/in/rule.hxx -*- C++ -*- // license : MIT; see accompanying LICENSE file #ifndef LIBBUILD2_IN_RULE_HXX #define LIBBUILD2_IN_RULE_HXX #include #include // depdb #include #include #include namespace build2 { namespace in { // Preprocess an .in file. // // Note that a derived rule can use the target data pad to cache data // (e.g., in match() or apply()) to be used in substitute/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 null = nullopt) : rule_id_ (move (rule_id)), program_ (move (program)), symbol_ (symbol), strict_ (strict), null_ (move (null)) {} virtual bool match (action, target&, const string&) 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; // 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 flags, const optional& null) const; // Perform variable substitution. Return nullopt if it should be // ignored. // virtual optional substitute (const location&, action, const target&, const string& name, optional flags, bool strict, const optional& null) const; // Call the above version and do any necessary depdb saving. // optional substitute (const location&, action, const target&, depdb& dd, size_t dd_skip, const string& name, optional flags, bool strict, const optional& 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& 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 null_; }; } } #endif // LIBBUILD2_IN_RULE_HXX