Merge remote-tracking branch 'upstream/stable' into merge_stable

This commit is contained in:
Martin Nowak 2017-08-16 12:17:39 +02:00
commit deb28da3ee
4 changed files with 86 additions and 18 deletions

View file

@ -15,7 +15,7 @@ $(TR $(TH Function Name) $(TH Description)
$(TD Joins a couple of functions into one that executes the original
functions independently and returns a tuple with all the results.
))
$(TR $(TD $(LREF compose)), $(LREF pipe)
$(TR $(TD $(LREF compose), $(LREF pipe))
$(TD Join a couple of functions into one that executes the original
functions one after the other, using one function's result for the next
function's argument.
@ -23,7 +23,7 @@ $(TR $(TH Function Name) $(TH Description)
$(TR $(TD $(LREF forward))
$(TD Forwards function arguments while saving ref-ness.
))
$(TR $(TD $(LREF lessThan)), $(LREF greaterThan)), $(D $(LREF equalTo)
$(TR $(TD $(LREF lessThan), $(LREF greaterThan), $(LREF equalTo))
$(TD Ready-made predicate functions to compare two values.
))
$(TR $(TD $(LREF memoize))
@ -36,13 +36,13 @@ $(TR $(TH Function Name) $(TH Description)
$(TD Creates a function that binds the first argument of a given function
to a given value.
))
$(TR $(TD $(LREF reverseArgs)), $(LREF binaryReverseArgs)
$(TR $(TD $(LREF reverseArgs), $(LREF binaryReverseArgs))
$(TD Predicate that reverses the order of its arguments.
))
$(TR $(TD $(LREF toDelegate))
$(TD Converts a callable to a delegate.
))
$(TR $(TD $(LREF unaryFun)), $(LREF binaryFun)
$(TR $(TD $(LREF unaryFun), $(LREF binaryFun))
$(TD Create a unary or binary function from a string. Most often
used when defining algorithms on ranges.
))

View file

@ -1182,6 +1182,8 @@ if (isForwardRange!R && is(ElementType!R : dchar))
state = State.Start;
break;
default:
if (current >= privateUseStart && current <= privateUseEnd)
enforce(false, "no matching ']' found while parsing character class");
enforce(false, "invalid escape sequence");
}
break;
@ -1256,8 +1258,17 @@ if (isForwardRange!R && is(ElementType!R : dchar))
end = parseUniHex(pat, 8);
break;
default:
if (current >= privateUseStart && current <= privateUseEnd)
enforce(false, "no matching ']' found while parsing character class");
error("invalid escape sequence");
}
// Lookahead to check if it's a \T
// where T is sub-pattern terminator in multi-pattern scheme
if (end == '\\' && !pat.empty)
{
if (pat.front >= privateUseStart && pat.front <= privateUseEnd)
enforce(false, "invalid escape sequence");
}
enforce(last <= end,"inverted range");
set.add(last, end + 1);
state = State.Start;
@ -1293,6 +1304,7 @@ if (isForwardRange!R && is(ElementType!R : dchar))
switch (op)
{
case Operator.Negate:
enforce(!stack.empty, "no operand for '^'");
stack.top = stack.top.inverted;
break;
case Operator.Union:
@ -1364,8 +1376,7 @@ if (isForwardRange!R && is(ElementType!R : dchar))
"character class syntax error");
enforce(!opstack.empty, "unmatched ']'");
opstack.pop();
next();
if (opstack.empty)
if (!next() || opstack.empty)
break L_CharsetLoop;
auto pair = parseCharTerm();
if (!pair[0].empty)//not only operator e.g. -- or ~~
@ -1390,10 +1401,13 @@ if (isForwardRange!R && is(ElementType!R : dchar))
}
vstack.push(pair[0]);
}
}while (!empty || !opstack.empty);
while (!opstack.empty)
apply(opstack.pop(),vstack);
{
enforce(opstack.top != Operator.Open,
"no matching ']' found while parsing character class");
apply(opstack.pop(), vstack);
}
assert(vstack.length == 1);
g.charsetToIr(vstack.top);
}
@ -1483,6 +1497,13 @@ if (isForwardRange!R && is(ElementType!R : dchar))
g.markBackref(nref);
break;
default:
// Lookahead to check if it's a \T
// where T is sub-pattern terminator in multi-pattern scheme
if (current == '\\' && !pat.empty)
{
if (pat.front >= privateUseStart && current <= privateUseEnd)
enforce(false, "invalid escape sequence");
}
if (current >= privateUseStart && current <= privateUseEnd)
{
g.endPattern(current - privateUseStart + 1);

View file

@ -1082,3 +1082,27 @@ alias Sequence(int B, int E) = staticIota!(B, E);
assert(equal!equal(s.matchAll(ctr), outcomes));
assert(equal!equal(s.bmatch(r), outcomes));
}
// bugzilla 17667
@safe unittest
{
import std.algorithm.searching : canFind;
void willThrow(T)(T arg, string msg)
{
auto e = collectException(regex(arg));
assert(e.msg.canFind(msg), e.msg);
}
willThrow([r".", r"[\(\{[\]\}\)]"], "no matching ']' found while parsing character class");
willThrow([r"[\", r"123"], "no matching ']' found while parsing character class");
willThrow([r"[a-", r"123"], "no matching ']' found while parsing character class");
willThrow([r"[a-\", r"123"], "invalid escape sequence");
willThrow([r"\", r"123"], "invalid escape sequence");
}
// bugzilla 17668
@safe unittest
{
import std.algorithm.searching;
auto e = collectException!RegexException(regex(q"<[^]>"));
assert(e.msg.canFind("no operand for '^'"));
}

View file

@ -1262,20 +1262,32 @@ If a parameter doesn't have the default value, $(D void) is returned instead.
template ParameterDefaults(func...)
if (func.length == 1 && isCallable!func)
{
alias param_names = ParameterIdentifierTuple!func;
static if (is(FunctionTypeOf!(func[0]) PT == __parameters))
{
template Get(size_t i)
{
// workaround scope escape check, see
// https://issues.dlang.org/show_bug.cgi?id=16582
// should use return scope once available
enum get = (PT[i .. i+1] __args) @trusted
{
// If __args[0] is lazy, we force it to be evaluated like this.
PT[i] __pd_value = __args[0];
PT[i]* __pd_val = &__pd_value; // workaround Bugzilla 16582
return *__pd_val;
};
// `PT[i .. i+1]` declares a parameter with an arbitrary name.
// To avoid a name clash, generate local names that are distinct
// from the parameter name, and mix them in.
enum name = param_names[i];
enum args = "args" ~ (name == "args" ? "_" : "");
enum val = "val" ~ (name == "val" ? "_" : "");
enum ptr = "ptr" ~ (name == "ptr" ? "_" : "");
mixin("
// workaround scope escape check, see
// https://issues.dlang.org/show_bug.cgi?id=16582
// should use return scope once available
enum get = (PT[i .. i+1] " ~ args ~ ") @trusted
{
// If the parameter is lazy, we force it to be evaluated
// like this.
auto " ~ val ~ " = " ~ args ~ "[0];
auto " ~ ptr ~ " = &" ~ val ~ ";
// workaround Bugzilla 16582
return *" ~ ptr ~ ";
};
");
static if (is(typeof(get())))
enum Get = get();
else
@ -1313,6 +1325,17 @@ template ParameterDefaults(func...)
static assert( ParameterDefaults!foo[3] == 0);
}
@safe unittest // issue 17192
{
static void func(int i, int PT, int __pd_value, int __pd_val, int __args,
int name, int args, int val, int ptr, int args_, int val_, int ptr_)
{
}
alias Voids = ParameterDefaults!func;
static assert(Voids.length == 12);
foreach (V; Voids) static assert(is(V == void));
}
/**
* Alternate name for $(LREF ParameterDefaults), kept for legacy compatibility.
*/