diff options
Diffstat (limited to 'libbuild2/name.hxx')
-rw-r--r-- | libbuild2/name.hxx | 75 |
1 files changed, 66 insertions, 9 deletions
diff --git a/libbuild2/name.hxx b/libbuild2/name.hxx index b25a3e3..f5cb2c5 100644 --- a/libbuild2/name.hxx +++ b/libbuild2/name.hxx @@ -27,19 +27,27 @@ namespace build2 // empty, then it means the name is in a project other than our own (e.g., // it is installed). // - // A type or project can only be specified if either directory or value are - // not empty. + // A type can only be specified if either directory or value are not empty. + // We allow project-qualified empty names for reversibility. // // If pair is not '\0', then this name and the next in the list form a // pair. Can be used as a bool flag. // + // If pattern is present then this is a name pattern (e.g., file{*.txt}, + // file{~'/(.+)\.txt/i'}, file{^'/\1/'}). A directory name cannot be a regex + // pattern (since we would need to store it in dir_path and a regex is not + // necessarily a valid path). + // struct name { + enum class pattern_type: uint8_t {path, regex_pattern, regex_substitution}; + optional<project_name> proj; dir_path dir; string type; string value; char pair = '\0'; + optional<pattern_type> pattern; name () {} // = default; Clang needs this to initialize const object. name (string v): value (move (v)) {} @@ -57,6 +65,14 @@ namespace build2 name (optional<project_name> p, dir_path d, string t, string v) : proj (move (p)), dir (move (d)), type (move (t)), value (move (v)) {} + name (optional<project_name> p, + dir_path d, + string t, + string v, + optional<pattern_type> pt) + : proj (move (p)), dir (move (d)), type (move (t)), value (move (v)), + pattern (pt) {} + bool qualified () const {return proj.has_value ();} @@ -115,6 +131,13 @@ namespace build2 int compare (const name&) const; + + // Canonicalize the name by moving the directory component (if any) from + // value to dir. Throw invalid_argument if value would become empty. May + // also throw invalid_path. + // + void + canonicalize (); }; LIBBUILD2_SYMEXPORT extern const name empty_name; @@ -130,6 +153,10 @@ namespace build2 // Return string representation of a name. // + // Note that this function does not quote special characters and you should + // use the to_stream() function below if this is necessary. It also cannot + // be used on a name pattern. + // LIBBUILD2_SYMEXPORT string to_string (const name&); @@ -143,22 +170,44 @@ namespace build2 cs.append (n.type); cs.append (n.value); cs.append (n.pair); + if (n.pattern) + cs.append (static_cast<uint8_t> (*n.pattern)); } // Store a string in a name in a reversible way. If the string ends with a // trailing directory separator then it is stored as a directory, otherwise - // as a simple name. + // as a simple name. Note that the returned name is never a pattern. + // + // NOTE: this function does not parse the full name syntax. See context-less + // parser::parse_names() for a heavy-weight way to achieve this. // name to_name (string); // Serialize the name to the stream. If requested, the name components - // containing special characters are quoted. The special characters are: + // containing special characters are quoted and/or escaped. In the normal + // quoting mode the special characters are: // // {}[]$() \t\n#\"'% // + // And additionally, unless name is a pattern: + // + // *? + // + // As well as leading and if followed by a non-alphanumeric delimiter: + // + // ~^ + // + // As well as leading `+` if in the curly braces. + // + // In the effective quoting mode the special characters are: + // + // {}$( \t\n#"' + // + // As well as `\` if followed by any of the above characters or itself. + // // If the pair argument is not '\0', then it is added to the above special - // characters set. If the quote character is present in the component then + // characters sets. If the quote character is present in the component then // it is double quoted rather than single quoted. In this case the following // characters are escaped: // @@ -171,15 +220,23 @@ namespace build2 // Note that in the quoted mode empty unqualified name is printed as '', // not {}. // + enum class quote_mode + { + none, + normal, + effective + }; + LIBBUILD2_SYMEXPORT ostream& to_stream (ostream&, const name&, - bool quote, + quote_mode, char pair = '\0', bool escape = false); inline ostream& - operator<< (ostream& os, const name& n) {return to_stream (os, n, false);} + operator<< (ostream& os, const name& n) { + return to_stream (os, n, quote_mode::none);} // Vector of names. // @@ -198,13 +255,13 @@ namespace build2 LIBBUILD2_SYMEXPORT ostream& to_stream (ostream&, const names_view&, - bool quote, + quote_mode, char pair = '\0', bool escape = false); inline ostream& operator<< (ostream& os, const names_view& ns) { - return to_stream (os, ns, false);} + return to_stream (os, ns, quote_mode::none);} inline ostream& operator<< (ostream& os, const names& ns) {return os << names_view (ns);} |