mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-04 19:00:27 +02:00
LazUtils: Masks: since wqFilenameEnd (internally) requires mocAnyCharOrNone, include the latter in MaskOpCodes if wqFilenameEnd is used.
Also include mocAnyCharOrNone in DefaultMaskOpcodes, otherwise the default behaviour between TMask and TWindowsMask for a mask containing [?] would differ. Add comments to the long and winding if then else blocks in CompileRange
This commit is contained in:
parent
46a1f547f0
commit
78148e42f5
@ -120,7 +120,7 @@ const
|
|||||||
mocSet,
|
mocSet,
|
||||||
mocNegateGroup];
|
mocNegateGroup];
|
||||||
|
|
||||||
DefaultMaskOpCodes=MaskOpCodesNoEscape;
|
DefaultMaskOpCodes=AllMaskOpCodes-[mocEscapeChar];//MaskOpCodesNoEscape;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -504,11 +504,21 @@ end;
|
|||||||
{ TWindowsMaskList }
|
{ TWindowsMaskList }
|
||||||
|
|
||||||
procedure TWindowsMaskList.SetQuirks(AValue: TWindowsQuirks);
|
procedure TWindowsMaskList.SetQuirks(AValue: TWindowsQuirks);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
if fWindowsQuirks = AValue then Exit;
|
if fWindowsQuirks = AValue then Exit;
|
||||||
fWindowsQuirks := AValue;
|
fWindowsQuirks := AValue;
|
||||||
fMasks.Clear;
|
if (wqFilenameEnd in fWindowsQuirks) then
|
||||||
AddMasksToList(fMask, fSeparator, fCaseSensitive, fMaskOpCodes);
|
Include(fMaskOpcodes, mocAnyCharOrNone);
|
||||||
|
for i := 0 to fMasks.Count - 1 do
|
||||||
|
begin
|
||||||
|
TWindowsMask(fMasks.Items[i]).Quirks := FWindowsQuirks;
|
||||||
|
TWindowsMask(fMasks.Items[i]).MaskOpCodes := fMaskOpcodes;
|
||||||
|
//TWindowsMask(fMasks.Items[i]).Compile; //to apply Quirks
|
||||||
|
end;
|
||||||
|
//fMasks.Clear;
|
||||||
|
//AddMasksToList(fMask, fSeparator, fCaseSensitive, fMaskOpCodes);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TWindowsMaskList.GetMaskClass: TMaskClass;
|
function TWindowsMaskList.GetMaskClass: TMaskClass;
|
||||||
@ -537,6 +547,8 @@ constructor TWindowsMaskList.Create(const aValue: String; aSeparator: Char;
|
|||||||
aWindowsQuirksAllowed: TWindowsQuirks);
|
aWindowsQuirksAllowed: TWindowsQuirks);
|
||||||
begin
|
begin
|
||||||
fWindowsQuirks := aWindowsQuirksAllowed;
|
fWindowsQuirks := aWindowsQuirksAllowed;
|
||||||
|
if (wqFilenameEnd in aWindowsQuirksAllowed) then
|
||||||
|
Include(aOpcodesAllowed, mocAnyCharOrNone);
|
||||||
inherited Create(aValue, aSeparator, aCaseSensitive, aOpcodesAllowed);
|
inherited Create(aValue, aSeparator, aCaseSensitive, aOpcodesAllowed);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -773,6 +785,7 @@ procedure TMaskUTF8.CompileRange;
|
|||||||
var
|
var
|
||||||
lCharsGroupInsertSize, lFirstRange, lSecondRange: integer;
|
lCharsGroupInsertSize, lFirstRange, lSecondRange: integer;
|
||||||
begin
|
begin
|
||||||
|
//writeln('CompileRange');
|
||||||
fLastOC:=TMaskParsedCode.CharsGroupBegin;
|
fLastOC:=TMaskParsedCode.CharsGroupBegin;
|
||||||
Add(TMaskParsedCode.CharsGroupBegin);
|
Add(TMaskParsedCode.CharsGroupBegin);
|
||||||
inc(fMatchMinimumLiteralBytes,1);
|
inc(fMatchMinimumLiteralBytes,1);
|
||||||
@ -791,7 +804,7 @@ begin
|
|||||||
|
|
||||||
while fMaskInd<=fMaskLimit do begin
|
while fMaskInd<=fMaskLimit do begin
|
||||||
fCPLength:=UTF8CodepointSizeFast(@fMask[fMaskInd]);
|
fCPLength:=UTF8CodepointSizeFast(@fMask[fMaskInd]);
|
||||||
if (fMask[fMaskInd]='?') and (mocAnyCharOrNone in fMaskOpcodesAllowed) then begin
|
if (fMask[fMaskInd]='?') and (mocAnyCharOrNone in fMaskOpcodesAllowed) then begin //mocAnyCharOrNone and '?' found
|
||||||
// This syntax is permitted [??] but not this one [?a] or [a?]
|
// This syntax is permitted [??] but not this one [?a] or [a?]
|
||||||
if (fLastOC=TMaskParsedCode.CharsGroupBegin) or (fLastOC=TMaskParsedCode.AnyCharOrNone) then begin
|
if (fLastOC=TMaskParsedCode.CharsGroupBegin) or (fLastOC=TMaskParsedCode.AnyCharOrNone) then begin
|
||||||
if fLastOC=TMaskParsedCode.AnyCharOrNone then begin
|
if fLastOC=TMaskParsedCode.AnyCharOrNone then begin
|
||||||
@ -814,14 +827,17 @@ begin
|
|||||||
fLastOC:=TMaskParsedCode.AnyCharOrNone;
|
fLastOC:=TMaskParsedCode.AnyCharOrNone;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Exception_InvalidCharMask(fMask[fMaskInd],fMaskInd);
|
begin
|
||||||
end
|
Exception_InvalidCharMask(fMask[fMaskInd],fMaskInd);
|
||||||
else if (fLastOC=TMaskParsedCode.AnyCharOrNone) and (fMask[fMaskInd]<>']') then begin
|
end;
|
||||||
|
end //mocAnyCharOrNone and '?' found
|
||||||
|
else if (fLastOC=TMaskParsedCode.AnyCharOrNone) and (fMask[fMaskInd]<>']') then begin //mocAnyCharOrNone and inside [?
|
||||||
|
//writeln('Compile found not ? after [?: ',fMask[fMaskInd]);
|
||||||
//fMask[fMaskInd] is not '?', but previous mask was '?' and it is an invalid sequence.
|
//fMask[fMaskInd] is not '?', but previous mask was '?' and it is an invalid sequence.
|
||||||
// "[??] = Valid" // "[a?] or [?a] = Invalid"
|
// "[??] = Valid" // "[a?] or [?a] = Invalid"
|
||||||
Exception_InvalidCharMask(fMask[fMaskInd],fMaskInd);
|
Exception_InvalidCharMask(fMask[fMaskInd],fMaskInd);
|
||||||
end
|
end
|
||||||
else if (mocRange in fMaskOpcodesAllowed) and IsARange(fMaskInd,lFirstRange,lSecondRange) then begin
|
else if (mocRange in fMaskOpcodesAllowed) and IsARange(fMaskInd,lFirstRange,lSecondRange) then begin //is a range
|
||||||
Add(TMaskParsedCode.Range);
|
Add(TMaskParsedCode.Range);
|
||||||
// Check if reverse range is needed
|
// Check if reverse range is needed
|
||||||
if (not fAutoReverseRange)
|
if (not fAutoReverseRange)
|
||||||
@ -831,15 +847,20 @@ begin
|
|||||||
ReverseRange(lFirstRange, lSecondRange);
|
ReverseRange(lFirstRange, lSecondRange);
|
||||||
fLastOC:=TMaskParsedCode.Range;
|
fLastOC:=TMaskParsedCode.Range;
|
||||||
|
|
||||||
end else if fMask[fMaskInd]=']' then begin
|
end //is a range
|
||||||
|
else if fMask[fMaskInd]=']' then begin //found ]
|
||||||
if (fLastOC=TMaskParsedCode.CharsGroupBegin) or (fLastOC=TMaskParsedCode.Negate) then
|
if (fLastOC=TMaskParsedCode.CharsGroupBegin) or (fLastOC=TMaskParsedCode.Negate) then
|
||||||
Exception_InvalidCharMask(fMask[fMaskInd],fMaskInd); //Error empty match
|
begin //empty set or range
|
||||||
|
//writeln('CompileRange: empty match');
|
||||||
|
Exception_InvalidCharMask(fMask[fMaskInd],fMaskInd); //Error empty match
|
||||||
|
end; //empty set or range
|
||||||
// Insert the new offset in case of a positive match in CharsGroup
|
// Insert the new offset in case of a positive match in CharsGroup
|
||||||
PInteger(@fMaskCompiled[lCharsGroupInsertSize])^:=fMaskCompiledIndex;
|
PInteger(@fMaskCompiled[lCharsGroupInsertSize])^:=fMaskCompiledIndex;
|
||||||
Add(TMaskParsedCode.CharsGroupEnd);
|
Add(TMaskParsedCode.CharsGroupEnd);
|
||||||
fLastOC:=TMaskParsedCode.CharsGroupEnd;
|
fLastOC:=TMaskParsedCode.CharsGroupEnd;
|
||||||
break;
|
break;
|
||||||
end else begin
|
end // end of range or set
|
||||||
|
else begin //not a range, not AnyCharOrNone, must be a set
|
||||||
// handle escaping if mocSet is enabled, but mocRange not
|
// handle escaping if mocSet is enabled, but mocRange not
|
||||||
if (fMask[fMaskInd]=FMaskEscapeChar) and (mocEscapeChar in fMaskOpcodesAllowed) then begin
|
if (fMask[fMaskInd]=FMaskEscapeChar) and (mocEscapeChar in fMaskOpcodesAllowed) then begin
|
||||||
// next is optional char in set or literal
|
// next is optional char in set or literal
|
||||||
@ -847,6 +868,7 @@ begin
|
|||||||
if fMaskInd<=fMaskLimit then begin
|
if fMaskInd<=fMaskLimit then begin
|
||||||
fCPLength:=UTF8CodepointSizeFast(@fMask[fMaskInd]);
|
fCPLength:=UTF8CodepointSizeFast(@fMask[fMaskInd]);
|
||||||
end else begin
|
end else begin
|
||||||
|
//writeln('CompileRange: incomplete mask');
|
||||||
Exception_IncompleteMask();
|
Exception_IncompleteMask();
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -856,6 +878,7 @@ begin
|
|||||||
Add(fCPLength,@fMask[fMaskInd]);
|
Add(fCPLength,@fMask[fMaskInd]);
|
||||||
fLastOC:=TMaskParsedCode.OptionalChar;
|
fLastOC:=TMaskParsedCode.OptionalChar;
|
||||||
end else begin
|
end else begin
|
||||||
|
//writeln('CompileRange: exception but why??');
|
||||||
Exception_InvalidCharMask(fMask[fMaskInd],fMaskInd);
|
Exception_InvalidCharMask(fMask[fMaskInd],fMaskInd);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -863,6 +886,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
if fMaskInd>fMaskLimit then
|
if fMaskInd>fMaskLimit then
|
||||||
Exception_MissingCloseChar(']',fMaskLimit);
|
Exception_MissingCloseChar(']',fMaskLimit);
|
||||||
|
//writeln('CompileRange end.');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TMaskUTF8.GetMask: String;
|
function TMaskUTF8.GetMask: String;
|
||||||
@ -1194,6 +1218,8 @@ procedure TWindowsMaskUTF8.SetWindowsQuirkAllowed(AValue: TWindowsQuirks);
|
|||||||
begin
|
begin
|
||||||
if fWindowsQuirkAllowed = AValue then Exit;
|
if fWindowsQuirkAllowed = AValue then Exit;
|
||||||
fWindowsQuirkAllowed := AValue;
|
fWindowsQuirkAllowed := AValue;
|
||||||
|
if (wqFilenameEnd in fWindowsQuirkAllowed) then
|
||||||
|
Include(fMaskOpcodesAllowed, mocAnyCharOrNone);
|
||||||
fMaskIsCompiled := False;
|
fMaskIsCompiled := False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1236,6 +1262,8 @@ constructor TWindowsMaskUTF8.Create(const aMask: String; aCaseSensitive: Boolean
|
|||||||
begin
|
begin
|
||||||
fWindowsQuirkAllowed:=aWindowsQuirksAllowed;
|
fWindowsQuirkAllowed:=aWindowsQuirksAllowed;
|
||||||
fWindowsMask:=aMask;
|
fWindowsMask:=aMask;
|
||||||
|
if (wqFilenameEnd in fWindowsQuirkAllowed) then
|
||||||
|
Include(aOpcodesAllowed, mocAnyCharOrNone);
|
||||||
inherited Create(aMask,aCaseSensitive,aOpcodesAllowed);
|
inherited Create(aMask,aCaseSensitive,aOpcodesAllowed);
|
||||||
//don't compile on create: we do NOT want a crash in the constructor
|
//don't compile on create: we do NOT want a crash in the constructor
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user