aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/name.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/name.hxx')
-rw-r--r--libbuild2/name.hxx71
1 files changed, 64 insertions, 7 deletions
diff --git a/libbuild2/name.hxx b/libbuild2/name.hxx
index 8385e7c..f5cb2c5 100644
--- a/libbuild2/name.hxx
+++ b/libbuild2/name.hxx
@@ -33,13 +33,21 @@ namespace build2
// 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);}