diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-10-03 18:47:16 +0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-10-03 21:29:40 +0200 |
commit | 104e55bb7f593b1ac3c54ffda48a9d72af7fbe6b (patch) | |
tree | 92eea5af2736190ec196a4bc68c16ea5f16dff2f /src | |
parent | 3800f441e49af78b95d403014459dbb9bb646e8a (diff) |
nix-env: Add regular expression support in selectors
So you can now do things like:
$ nix-env -qa '.*zip.*'
$ nix-env -qa '.*(firefox|chromium).*'
Diffstat (limited to 'src')
-rw-r--r-- | src/libexpr/names.cc | 6 | ||||
-rw-r--r-- | src/libutil/regex.cc | 33 | ||||
-rw-r--r-- | src/libutil/regex.hh | 22 |
3 files changed, 60 insertions, 1 deletions
diff --git a/src/libexpr/names.cc b/src/libexpr/names.cc index 781c2b646..c2b273334 100644 --- a/src/libexpr/names.cc +++ b/src/libexpr/names.cc @@ -1,5 +1,6 @@ #include "names.hh" #include "util.hh" +#include "regex.hh" namespace nix { @@ -32,7 +33,10 @@ DrvName::DrvName(const string & s) : hits(0) bool DrvName::matches(DrvName & n) { - if (name != "*" && name != n.name) return false; + if (name != "*") { + Regex regex(name); + if (!regex.matches(n.name)) return false; + } if (version != "" && version != n.version) return false; return true; } diff --git a/src/libutil/regex.cc b/src/libutil/regex.cc new file mode 100644 index 000000000..36c8458ce --- /dev/null +++ b/src/libutil/regex.cc @@ -0,0 +1,33 @@ +#include "regex.hh" +#include "types.hh" + +namespace nix { + +Regex::Regex(const string & pattern) +{ + /* Patterns must match the entire string. */ + int err = regcomp(&preg, ("^(" + pattern + ")$").c_str(), REG_NOSUB | REG_EXTENDED); + if (err) throw Error(format("compiling pattern ‘%1%’: %2%") % pattern % showError(err)); +} + +Regex::~Regex() +{ + regfree(&preg); +} + +bool Regex::matches(const string & s) +{ + int err = regexec(&preg, s.c_str(), 0, 0, 0); + if (err == 0) return true; + else if (err == REG_NOMATCH) return false; + throw Error(format("matching string ‘%1%’: %2%") % s % showError(err)); +} + +string Regex::showError(int err) +{ + char buf[256]; + regerror(err, &preg, buf, sizeof(buf)); + return string(buf); +} + +} diff --git a/src/libutil/regex.hh b/src/libutil/regex.hh new file mode 100644 index 000000000..aa012b721 --- /dev/null +++ b/src/libutil/regex.hh @@ -0,0 +1,22 @@ +#pragma once + +#include "types.hh" + +#include <sys/types.h> +#include <regex.h> + +namespace nix { + +class Regex +{ +public: + Regex(const string & pattern); + ~Regex(); + bool matches(const string & s); + +private: + regex_t preg; + string showError(int err); +}; + +} |