Merge branch 'regex' of https://github.com/groxxda/nix
This commit is contained in:
		
						commit
						795d9b8668
					
				
					 5 changed files with 16 additions and 93 deletions
				
			
		| 
						 | 
				
			
			@ -33,8 +33,8 @@ DrvName::DrvName(const string & s) : hits(0)
 | 
			
		|||
bool DrvName::matches(DrvName & n)
 | 
			
		||||
{
 | 
			
		||||
    if (name != "*") {
 | 
			
		||||
        if (!regex) regex = std::shared_ptr<Regex>(new Regex(name));
 | 
			
		||||
        if (!regex->matches(n.name)) return false;
 | 
			
		||||
        if (!regex) regex = std::unique_ptr<std::regex>(new std::regex(name, std::regex::extended));
 | 
			
		||||
        if (!std::regex_match(n.name, *regex)) return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (version != "" && version != n.version) return false;
 | 
			
		||||
    return true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,7 @@
 | 
			
		|||
#include <memory>
 | 
			
		||||
 | 
			
		||||
#include "types.hh"
 | 
			
		||||
#include "regex.hh"
 | 
			
		||||
#include <regex>
 | 
			
		||||
 | 
			
		||||
namespace nix {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ struct DrvName
 | 
			
		|||
    bool matches(DrvName & n);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    std::shared_ptr<Regex> regex;
 | 
			
		||||
    std::unique_ptr<std::regex> regex;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef list<DrvName> DrvNames;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@
 | 
			
		|||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <regex>
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1618,25 +1619,26 @@ static void prim_hashString(EvalState & state, const Pos & pos, Value * * args,
 | 
			
		|||
   ‘null’ or a list containing substring matches. */
 | 
			
		||||
static void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v)
 | 
			
		||||
{
 | 
			
		||||
    Regex regex(state.forceStringNoCtx(*args[0], pos), true);
 | 
			
		||||
    std::regex regex(state.forceStringNoCtx(*args[0], pos), std::regex::extended);
 | 
			
		||||
 | 
			
		||||
    PathSet context;
 | 
			
		||||
    string s = state.forceString(*args[1], context, pos);
 | 
			
		||||
    const std::string str = state.forceString(*args[1], context, pos);
 | 
			
		||||
 | 
			
		||||
    Regex::Subs subs;
 | 
			
		||||
    if (!regex.matches(s, subs)) {
 | 
			
		||||
 | 
			
		||||
    std::smatch match;
 | 
			
		||||
    if (!std::regex_match(str, match, regex)) {
 | 
			
		||||
        mkNull(v);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsigned int len = subs.empty() ? 0 : subs.rbegin()->first + 1;
 | 
			
		||||
    // the first match is the whole string
 | 
			
		||||
    const size_t len = match.size() - 1;
 | 
			
		||||
    state.mkList(v, len);
 | 
			
		||||
    for (unsigned int n = 0; n < len; ++n) {
 | 
			
		||||
        auto i = subs.find(n);
 | 
			
		||||
        if (i == subs.end())
 | 
			
		||||
            mkNull(*(v.listElems()[n] = state.allocValue()));
 | 
			
		||||
    for (size_t i = 0; i < len; ++i) {
 | 
			
		||||
        if (!match[i+1].matched)
 | 
			
		||||
            mkNull(*(v.listElems()[i] = state.allocValue()));
 | 
			
		||||
        else
 | 
			
		||||
            mkString(*(v.listElems()[n] = state.allocValue()), i->second);
 | 
			
		||||
            mkString(*(v.listElems()[i] = state.allocValue()), match[i + 1].str().c_str());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,50 +0,0 @@
 | 
			
		|||
#include "regex.hh"
 | 
			
		||||
#include "types.hh"
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
namespace nix {
 | 
			
		||||
 | 
			
		||||
Regex::Regex(const string & pattern, bool subs)
 | 
			
		||||
{
 | 
			
		||||
    /* Patterns must match the entire string. */
 | 
			
		||||
    int err = regcomp(&preg, ("^(" + pattern + ")$").c_str(), (subs ? 0 : REG_NOSUB) | REG_EXTENDED);
 | 
			
		||||
    if (err) throw RegexError(format("compiling pattern ‘%1%’: %2%") % pattern % showError(err));
 | 
			
		||||
    nrParens = subs ? std::count(pattern.begin(), pattern.end(), '(') : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Regex::matches(const string & s, Subs & subs)
 | 
			
		||||
{
 | 
			
		||||
    regmatch_t pmatch[nrParens + 2];
 | 
			
		||||
    int err = regexec(&preg, s.c_str(), nrParens + 2, pmatch, 0);
 | 
			
		||||
    if (err == 0) {
 | 
			
		||||
        for (unsigned int n = 2; n < nrParens + 2; ++n)
 | 
			
		||||
            if (pmatch[n].rm_eo != -1)
 | 
			
		||||
                subs[n - 2] = string(s, pmatch[n].rm_so, pmatch[n].rm_eo - pmatch[n].rm_so);
 | 
			
		||||
        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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,29 +0,0 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "types.hh"
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <regex.h>
 | 
			
		||||
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
namespace nix {
 | 
			
		||||
 | 
			
		||||
MakeError(RegexError, Error)
 | 
			
		||||
 | 
			
		||||
class Regex
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    Regex(const string & pattern, bool subs = false);
 | 
			
		||||
    ~Regex();
 | 
			
		||||
    bool matches(const string & s);
 | 
			
		||||
    typedef std::map<unsigned int, string> Subs;
 | 
			
		||||
    bool matches(const string & s, Subs & subs);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    unsigned nrParens;
 | 
			
		||||
    regex_t preg;
 | 
			
		||||
    string showError(int err);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue