LazDebuggerGdbmi: Return more values via the new API. Moved handling of Displayformat to IDE.

This commit is contained in:
Martin 2024-02-21 20:06:44 +01:00
parent 38e0022ccc
commit be31fbc4ad
6 changed files with 178 additions and 194 deletions

View File

@ -60,7 +60,7 @@ function UnEscapeBackslashed(const AValue: String; AFlags: TGdbUnEscapeFlags = [
function UnQuote(const AValue: String): String;
function Quote(const AValue: String; AForce: Boolean=False): String;
function ConvertGdbPathAndFile(const AValue: String): String; deprecated 'use ConvertPathFromGdbToLaz'; // fix path, delim, unescape, and to utf8
function ParseGDBString(const AValue: String): String; // remove quotes(') and convert #dd chars: #9'ab'#9'x'
function ParseGDBString(const AValue: String; KeepBackSlash: Boolean = False): String; // remove quotes(') and convert #dd chars: #9'ab'#9'x'
function GetLeadingAddr(var AValue: String; out AnAddr: TDBGPtr; ARemoveFromValue: Boolean = False): Boolean;
function UpperCaseSymbols(s: string): string;
function ConvertPascalExpression(var AExpression: String): Boolean;
@ -364,7 +364,7 @@ begin
Result := AnsiToUtf8(ConvertPathDelims(UnEscapeBackslashed(AValue, [uefOctal])));
end;
function ParseGDBString(const AValue: String): String;
function ParseGDBString(const AValue: String; KeepBackSlash: Boolean): String;
var
i, j, v: Integer;
InQuote: Boolean;
@ -396,7 +396,7 @@ begin
end;
continue;
end;
if (AValue[i] = '\' ) and (i < length(AValue)) then begin // gdb escapes some chars, even it not pascalish
if (not KeepBackSlash) and (AValue[i] = '\' ) and (i < length(AValue)) then begin // gdb escapes some chars, even it not pascalish
inc(j);
inc(i); // copy next char
Result[j] := AValue[i];

View File

@ -14400,6 +14400,8 @@ var
else
FTextValue := UnEscapeBackslashed(FTextValue); // TODO: Check for string
end;
skString, skAnsiString, skWideString:
exit; // dont call FormatResult
end;
PutValuesInTree;
@ -14473,33 +14475,6 @@ var
end;
function TryExecute(AnExpression: string): Boolean;
function PrepareExpr(var expr: string; NoAddressOp: Boolean = False): boolean;
begin
Assert(FTypeInfo = nil, 'Type info must be nil');
FTypeInfo := GetGDBTypeInfo(expr, defFullTypeInfo in FEvalFlags, TypeInfoFlags);
Result := FTypeInfo <> nil;
if (not Result) then begin
ParseLastError;
exit;
end;
if NoAddressOp
then expr := QuoteExpr(expr)
else expr := QuoteExpr(AddAddressOfToExpression(expr, FTypeInfo));
end;
procedure GetNumValue(const AExpression: String);
var
s: String;
begin
s := GetStrValue(AExpression, [], [cfNoMemLimits]);
FHasNumValue := nvUnsigned;
if (s <> '') and (s[1] = '-') then
FHasNumValue := nvSigned;
FNumValue := GetPtrValue(s);
end;
var
ResultList: TGDBMINameValueList;
R: TGDBMIExecResult;
@ -14512,109 +14487,44 @@ var
Result := False;
FHasNumValue := nvNone;
Assert(FTypeInfo = nil, 'Type info must be nil');
i := 0;
if FWatchValue <> nil then i := FWatchValue.RepeatCount;
FTypeInfo := GetGDBTypeInfo(AnExpression, defFullTypeInfo in FEvalFlags,
TypeInfoFlags+[gtcfExprEvaluate, gtcfExprEvalStrFixed], i);
Result := FTypeInfo <> nil;
if (not Result) then begin
ParseLastError;
exit;
end;
case FDisplayFormat of
wdfStructure:
begin
Result := ExecuteCommand('-data-evaluate-expression %s', [Quote(AnExpression)], R);
Result := Result and (R.State <> dsError);
if (not Result) then begin
ParseLastError;
exit;
end;
ResultList := TGDBMINameValueList.Create(R.Values);
if Result
then FTextValue := ResultList.Values['value']
else FTextValue := ResultList.Values['msg'];
FTextValue := DeleteEscapeChars(FTextValue);
ResultList.Free;
if Result
then begin
FixUpResult(AnExpression);
FValidity := ddsValid;
end;
end;
wdfChar:
begin
Result := PrepareExpr(AnExpression);
if not Result
then exit;
FValidity := ddsValid;
FTextValue := GetChar(AnExpression, []);
if LastExecResult.State = dsError
then ParseLastError;
end;
wdfString:
begin
Result := PrepareExpr(AnExpression);
if not Result
then exit;
FValidity := ddsValid;
FTextValue := GetText(AnExpression, []); // GetText takes Addr
if LastExecResult.State = dsError
then ParseLastError;
end;
wdfDecimal:
begin
Result := PrepareExpr(AnExpression, True);
if not Result
then exit;
FValidity := ddsValid;
GetNumValue(AnExpression);
FTextValue := IntToStr(Int64(FNumValue));
if LastExecResult.State = dsError
then ParseLastError;
end;
wdfUnsigned:
begin
Result := PrepareExpr(AnExpression, True);
if not Result
then exit;
FValidity := ddsValid;
GetNumValue(AnExpression);
FTextValue := IntToStr(FNumValue);
if LastExecResult.State = dsError
then ParseLastError;
end;
//wdfFloat:
// begin
// Result := PrepareExpr(AnExpression);
// if not Result
// then exit;
// FTextValue := GetFloat(AnExpression, []); // GetFloat takes address
// if LastExecResult.State = dsError
// then FTextValue := '<error>';
// end;
wdfHex:
begin
Result := PrepareExpr(AnExpression, True);
if not Result
then exit;
FValidity := ddsValid;
GetNumValue(AnExpression);
FTextValue := IntToHex(FNumValue, 2);
if length(FTextValue) mod 2 = 1
then FTextValue := '0'+FTextValue; // make it an even number of digets
if LastExecResult.State = dsError
then ParseLastError;
end;
wdfPointer:
begin
Result := PrepareExpr(AnExpression, True);
if not Result
then exit;
FValidity := ddsValid;
GetNumValue(AnExpression);
FTextValue := PascalizePointer('0x' + IntToHex(FNumValue, TargetInfo^.TargetPtrSize*2));
if LastExecResult.State = dsError
then FTextValue := '<error>';
end;
// wdfStructure:
// begin
// FreeAndNil(FTypeInfo);
// Result := ExecuteCommand('-data-evaluate-expression %s', [Quote(AnExpression)], R);
// Result := Result and (R.State <> dsError);
// if (not Result) then begin
// ParseLastError;
// exit;
// end;
//
// ResultList := TGDBMINameValueList.Create(R.Values);
// if Result
// then FTextValue := ResultList.Values['value']
// else FTextValue := ResultList.Values['msg'];
// FTextValue := DeleteEscapeChars(FTextValue);
// ResultList.Free;
//
// if Result
// then begin
// FixUpResult(AnExpression);
// FValidity := ddsValid;
// end;
// end;
wdfMemDump:
begin
Result := PrepareExpr(AnExpression);
if not Result
then exit;
AnExpression := QuoteExpr(AddAddressOfToExpression(AnExpression, FTypeInfo));
Result := False;
Size := 256;
@ -14638,26 +14548,9 @@ var
FTextValue := MemDump.AsText(0, MemDump.Count, TargetInfo^.TargetPtrSize*2);
MemDump.Free;
end;
wdfBinary:
begin
Result := PrepareExpr(AnExpression, True);
if not Result
then exit;
FValidity := ddsValid;
GetNumValue(AnExpression);
FTextValue := Concat('0b' + BinStr(FNumValue, TargetInfo^.TargetPtrSize*2));
if LastExecResult.State = dsError
then ParseLastError;
end;
else // wdfDefault
begin
Result := False;
Assert(FTypeInfo = nil, 'Type info must be nil');
i := 0;
if FWatchValue <> nil then i := FWatchValue.RepeatCount;
FTypeInfo := GetGDBTypeInfo(AnExpression, defFullTypeInfo in FEvalFlags,
TypeInfoFlags + [gtcfExprEvaluate, gtcfExprEvalStrFixed], i);
if (FTypeInfo = nil) or (dcsCanceled in SeenStates)
then begin
ParseLastError;
@ -14704,7 +14597,8 @@ var
var
S: String;
ResultList: TGDBMINameValueList;
frameidx: Integer;
frameidx, i: Integer;
DoneResData: Boolean;
{$IFDEF DBG_WITH_GDB_WATCHES} R: TGDBMIExecResult; {$ENDIF}
begin
SelectContext;
@ -14792,12 +14686,66 @@ begin
break;
end;
end;
if FTypeInfo <> nil then begin
DoneResData := True;
s := LowerCase(FTextValue);
case FTypeInfo.Kind of
//skProcedure: ;
//skFunction: ;
//skProcedureRef: ;
//skFunctionRef: ;
skBoolean:
if s = 'false' then
FWatchValue.ResData.CreateBoolValue(0)
else
if s = 'true' then
FWatchValue.ResData.CreateBoolValue(1)
else
DoneResData := False;
skChar:
if Length(s) = 1 then
FWatchValue.ResData.CreateCharValue(ord(FTextValue[1]), 1)
else
DoneResData := False;
//skFloat: ;
skString,
skAnsiString:
FWatchValue.ResData.CreateString(FTextValue);
skWideString:
FWatchValue.ResData.CreateWideString(FTextValue);
skEnum: begin
i := 0;
if FTypeInfo.Members <> nil then begin
i := FTypeInfo.Members.IndexOf(FTextValue);
if i < 0 then i := 0;
end;
FWatchValue.ResData.CreateEnumValue(i, FTextValue);
end;
//skEnumValue: ;
// FWatchValue.ResData.CreateEnumValue(0, FTextValue, 0 ,True);
//skSet: ;
//skRecord: ;
//skObject: ;
//skClass: ;
//skInterface: ;
//skArray: ;
else
DoneResData := False;
end;
if DoneResData then begin
FWatchValue.ResData.SetTypeName(FTypeInfo.TypeName);
FWatchValue.Validity := FValidity;
break;
end;
end;
FWatchValue.Value := FTextValue;
FWatchValue.TypeInfo := TypeInfo;
FTypeInfo := nil;
FWatchValue.Validity := FValidity;
until true;
FWatchValue.EndUpdate;
FreeAndNil(FTypeInfo);
end;
end;
end;

View File

@ -3356,6 +3356,8 @@ var
OldProcessState: TGDBTypeProcessState;
OldReqMade: TGDBTypeProcessRequests;
s: string;
i: Integer;
j: Longint;
begin
Result := False;
FEvalRequest := nil;
@ -3410,6 +3412,30 @@ begin
FKind := skSimple;
FreeAndNil(FFields);
end;
if (FKind = skSimple) and FHasExprEvaluatedAsText and (FExprEvaluatedAsText <> '') then begin
// check value for string or char
i := 1;
while (i <= Length(FExprEvaluatedAsText)) and (FExprEvaluatedAsText[i] in ['0'..'9']) do
inc(i);
if (i > 1) and (i + 1 < Length(FExprEvaluatedAsText)) and
(FExprEvaluatedAsText[i] in [#9, ' ']) and (FExprEvaluatedAsText[i+1] in ['#', '''']) and
TryStrToInt(copy(FExprEvaluatedAsText, 1 , i-1), j) and (j < 256)
then begin
//char
FKind := skChar;
Delete(FExprEvaluatedAsText, 1, i);
FExprEvaluatedAsText := ParseGDBString(UnEscapeBackslashed(FExprEvaluatedAsText), True);
end
else
if (Length(FExprEvaluatedAsText) > 1) and (FExprEvaluatedAsText[1] in ['#', '''']) then begin
// string
FKind := skString;
FExprEvaluatedAsText := ParseGDBString(UnEscapeBackslashed(FExprEvaluatedAsText), True);
end;
end;
if Value.AsString = '' then
Value.AsString := ExprEvaluatedAsText;

View File

@ -123,7 +123,7 @@
</Other>
</CompilerOptions>
<Debugging>
<Exceptions Count="7">
<Exceptions Count="8">
<Item1>
<Name Value="EAbort"/>
</Item1>
@ -145,6 +145,9 @@
<Item7>
<Name Value="EScannerError"/>
</Item7>
<Item8>
<Name Value="EConvertError"/>
</Item8>
</Exceptions>
</Debugging>
</CONFIG>

View File

@ -31,6 +31,7 @@ type
IgnKindDw2,
IgnKindDw3,
IgnKindSt,
acceptSkSimple, // also accept skSimple
IgnKindPtr, // Ignore skSimple, ONLY if got kind=skPointer
IgnKindPtrDw,
@ -491,14 +492,19 @@ begin
else
case wv.ResultData.ValueKind of
rdkString: s := 'skString';
rdkChar: s := 'skChar';
rdkWideString: s := 'skWideString';
rdkSignedNumVal: s := 'skSimple'; // 'skInteger'
rdkUnsignedNumVal: s := 'skSimple';
rdkPointerVal: s := 'skPointer';
rdkFloatVal: s := 'skFloat';
rdkEnum: s := 'skEnum';
rdkEnumVal: s := 'skEnumValue';
rdkBool: s := 'skBoolean';
end;
end;
WriteStr(s2, DataRes.ExpKind);
if (acceptSkSimple in DataRes.Flgs) and (s = 'skSimple') then s2 := 'skSimple';
IgnoreText := ''; if IgnoreKind then IgnoreText := 'Ignored by flag';
if IsValid and HasTpInfo then begin
if (not IgnoreKind) and IgnoreKindPtr and (WV.TypeInfo.Kind = skPointer) then IgnoreText := 'Ignored by flag (Kind may be Ptr)';
@ -645,6 +651,7 @@ end;
initialization
TheWatchPrinter := TWatchResultPrinter.Create;
TheWatchPrinter.FormatFlags := [];
finalization
FreeAndNil(Frx);

View File

@ -187,7 +187,7 @@ begin
// but the IDE only gets that with Dwarf-3
// might be prefixed, with address
Result := AddFmtDef(AnExpr, '''' + AMtch + '''$', skPOINTER, ATpNm, AFlgs );
UpdExpRes(Result, stDwarf3, skSimple);
UpdExpRes(Result, stDwarf3, '''' + AMtch + '''$', skString, ATpNm, AFlgs+[acceptSkSimple]);
end;
function TTestWatches.AddShortStrFmtDef(AnExpr, AMtch: string; ATpNm: string;
@ -196,7 +196,7 @@ begin
// TODO, encoding of special chars
// shortstring
// might be prefixed, with address
Result := AddFmtDef(AnExpr, '''' + AMtch + '''$', skSimple, ATpNm, AFlgs );
Result := AddFmtDef(AnExpr, '''' + AMtch + '''$', skString, ATpNm, AFlgs+[acceptSkSimple] );
end;
function TTestWatches.AddCharFmtDef(AnExpr, AMtch: string; ATpNm: string;
@ -204,7 +204,7 @@ function TTestWatches.AddCharFmtDef(AnExpr, AMtch: string; ATpNm: string;
begin
// TODO, encoding of special chars
// might be prefixed, with address
Result := AddFmtDef(AnExpr, '''' + AMtch + '''$', skSimple, ATpNm, AFlgs );
Result := AddFmtDef(AnExpr, '''' + AMtch + '''$', skChar, ATpNm, AFlgs+[acceptSkSimple] );
end;
function TTestWatches.AddPointerFmtDef(AnExpr, ATpNm: string;
@ -696,23 +696,23 @@ begin
// accessing char
// TODO: only works with dwarf 3
r:=AddFmtDef('ArgTMyAnsiString[1]', '.', skSimple, 'char', []);
UpdExpRes(r, stDwarf3, '''M''$', skSimple, 'char', []);
r:=AddFmtDef('VArgTMyAnsiString[1]', '.', skSimple, 'char', []);
UpdExpRes(r, stDwarf3, '''M''$', skSimple, 'char', []);
r:=AddFmtDef('ArgPMyAnsiString^[1]', '.', skSimple, 'char', []);
UpdExpRes(r, stDwarf3, '''M''$', skSimple, 'char', []);
r:=AddFmtDef('VArgPMyAnsiString^[1]', '.', skSimple, 'char', []);
r:=AddFmtDef('ArgTMyAnsiString[1]', '.', skChar, 'char', [acceptSkSimple]);
UpdExpRes(r, stDwarf3, '''M''$', skChar, 'char', [acceptSkSimple]);
r:=AddFmtDef('VArgTMyAnsiString[1]', '.', skChar, 'char', [acceptSkSimple]);
UpdExpRes(r, stDwarf3, '''M''$', skChar, 'char', [acceptSkSimple]);
r:=AddFmtDef('ArgPMyAnsiString^[1]', '.', skChar, 'char', [acceptSkSimple]);
UpdExpRes(r, stDwarf3, '''M''$', skChar, 'char', [acceptSkSimple]);
r:=AddFmtDef('VArgPMyAnsiString^[1]', '.', skChar, 'char', [acceptSkSimple]);
UpdResMinFpc(r, stDwarf, 020600); UpdResMinFpc(r, stDwarfSet, 020600);
UpdExpRes(r, stDwarf3, '''M''$', skSimple, 'char', []);
r:=AddFmtDef('AnsiString(ArgTMyAnsiString)[1]', '.', skSimple, 'char', []);
UpdExpRes(r, stDwarf3, '''M''$', skSimple, 'char', []);
r:=AddFmtDef('AnsiString(VArgTMyAnsiString)[1]', '.', skSimple, 'char', []);
UpdExpRes(r, stDwarf3, '''M''$', skSimple, 'char', []);
UpdExpRes(r, stDwarf3, '''M''$', skChar, 'char', [acceptSkSimple]);
r:=AddFmtDef('AnsiString(ArgTMyAnsiString)[1]', '.', skChar, 'char', [acceptSkSimple]);
UpdExpRes(r, stDwarf3, '''M''$', skChar, 'char', [acceptSkSimple]);
r:=AddFmtDef('AnsiString(VArgTMyAnsiString)[1]', '.', skChar, 'char', [acceptSkSimple]);
UpdExpRes(r, stDwarf3, '''M''$', skChar, 'char', [acceptSkSimple]);
// accessing char, after typecast
r:=AddFmtDef('AnsiString(ArgTMyAnsiString)[1]', '.', skSimple, 'char', []);
UpdExpRes(r, stDwarf3, '''M''$', skSimple, 'char', []);
r:=AddFmtDef('AnsiString(ArgTMyAnsiString)[1]', '.', skChar, 'char', [acceptSkSimple]);
UpdExpRes(r, stDwarf3, '''M''$', skChar, 'char', [acceptSkSimple]);
// string in array
@ -787,19 +787,19 @@ begin
r:=AddStringFmtDef('ArgTStringHolderObj.FTMyAnsiString', 'Obj1 MyAnsi', 'AnsiString', []);
r:=AddStringFmtDef('VArgTStringHolderObj.FTMyAnsiString', 'Obj2 MyAnsi', 'AnsiString', []);
r:=AddFmtDef('ArgTStringHolderObj.FTMyAnsiString[1]', '.$', skSimple, 'char', []);
UpdExpRes(r, stDwarf3, '''O''$', skSimple);
r:=AddFmtDef('VArgTStringHolderObj.FTMyAnsiString[1]', '.$', skSimple, 'char', []);
UpdExpRes(r, stDwarf3, '''O''$', skSimple);
r:=AddFmtDef('ArgTStringHolderObj.FTMyAnsiString[1]', '.$', skChar, 'char', [acceptSkSimple]);
UpdExpRes(r, stDwarf3, '''O''$', skChar, 'char', [acceptSkSimple]);
r:=AddFmtDef('VArgTStringHolderObj.FTMyAnsiString[1]', '.$', skChar, 'char', [acceptSkSimple]);
UpdExpRes(r, stDwarf3, '''O''$', skChar, 'char', [acceptSkSimple]);
// string in rec
r:=AddStringFmtDef('ArgTStringHolderRec.FTMyAnsiString', 'Rec1 MyAnsi', 'AnsiString', [fTstSkipDwarf3]);
r:=AddStringFmtDef('VArgTStringHolderRec.FTMyAnsiString', 'Rec2 MyAnsi', 'AnsiString', [fTstSkipDwarf3]);
r:=AddFmtDef('ArgTStringHolderRec.FTMyAnsiString[1]', '.$', skSimple, 'char', [fTstSkipDwarf3]);
UpdExpRes(r, stDwarf3, '''R''$', skSimple);
r:=AddFmtDef('VArgTStringHolderRec.FTMyAnsiString[1]', '.$', skSimple, 'char', [fTstSkipDwarf3]);
UpdExpRes(r, stDwarf3, '''R''$', skSimple);
r:=AddFmtDef('ArgTStringHolderRec.FTMyAnsiString[1]', '.$', skChar, 'char', [fTstSkipDwarf3, acceptSkSimple]);
UpdExpRes(r, stDwarf3, '''R''$', skChar, 'char', [fTstSkipDwarf3, acceptSkSimple]);
r:=AddFmtDef('VArgTStringHolderRec.FTMyAnsiString[1]', '.$', skChar, 'char', [fTstSkipDwarf3, acceptSkSimple]);
UpdExpRes(r, stDwarf3, '''R''$', skChar, 'char', [fTstSkipDwarf3, acceptSkSimple]);
//r:=AddFmtDef('ArgTNewAnsiString', '''NewAnsi''$', skPOINTER, '(TNew)?AnsiString', []);
@ -815,12 +815,12 @@ begin
AddFmtDef('ArgTMyShortString', '''short''$', skSimple, '^(TMy)?ShortString$', [fTpMtch]);
AddFmtDef('VArgTMyShortString', '''short''$', skSimple, '^(TMy)?ShortString$', [fTpMtch]);
AddFmtDef('ArgTMyShortString', '''short''$', skString, '^(TMy)?ShortString$', [fTpMtch, acceptSkSimple]);
AddFmtDef('VArgTMyShortString', '''short''$', skString, '^(TMy)?ShortString$', [fTpMtch, acceptSkSimple]);
AddFmtDef('ArgPMyShortString', Match_Pointer, skPointer, 'P(My)?ShortString', [fTpMtch]);
AddFmtDef('VArgPMyShortString', Match_Pointer, skPointer, 'P(My)?ShortString', [fTpMtch]);
AddFmtDef('ArgPMyShortString^', '''short''$', skSimple, '^(TMy)?ShortString$', [fTpMtch]);
r := AddFmtDef('VArgPMyShortString^', '''short''$', skSimple, '^(TMy)?ShortString$', [fTpMtch]);
AddFmtDef('ArgPMyShortString^', '''short''$', skString, '^(TMy)?ShortString$', [fTpMtch, acceptSkSimple]);
r := AddFmtDef('VArgPMyShortString^', '''short''$', skString, '^(TMy)?ShortString$', [fTpMtch, acceptSkSimple]);
UpdResMinFpc(r, stDwarf, 020600); UpdResMinFpc(r, stDwarfSet, 020600);
// string in array
@ -851,12 +851,12 @@ begin
r:=AddCharFmtDef('ArgTMyShortStringSArray[4][14]', '4', 'char', [IgnDwrf2]);
// string in obj
r:=AddFmtDef('ArgTStringHolderObj.FTMyShortString', '''Obj1 Short''$', skSimple, '^(TMy)?ShortString$', [fTpMtch, IgnDwrf3]);
r:=AddFmtDef('VArgTStringHolderObj.FTMyShortString', '''Obj2 Short''$', skSimple, '^(TMy)?ShortString$', [fTpMtch, IgnDwrf3]);
r:=AddFmtDef('ArgTStringHolderObj.FTMyShortString', '''Obj1 Short''$', skString, '^(TMy)?ShortString$', [fTpMtch, IgnDwrf3, acceptSkSimple]);
r:=AddFmtDef('VArgTStringHolderObj.FTMyShortString', '''Obj2 Short''$', skString, '^(TMy)?ShortString$', [fTpMtch, IgnDwrf3, acceptSkSimple]);
// string in rec
r:=AddFmtDef('ArgTStringHolderRec.FTMyShortString', '''Rec1 Short''$', skSimple, '^(TMy)?ShortString$', [fTpMtch, IgnDwrf3]);
r:=AddFmtDef('VArgTStringHolderRec.FTMyShortString', '''Rec2 Short''$', skSimple, '^(TMy)?ShortString$', [fTpMtch, IgnDwrf3]);
r:=AddFmtDef('ArgTStringHolderRec.FTMyShortString', '''Rec1 Short''$', skString, '^(TMy)?ShortString$', [fTpMtch, IgnDwrf3, acceptSkSimple]);
r:=AddFmtDef('VArgTStringHolderRec.FTMyShortString', '''Rec2 Short''$', skString, '^(TMy)?ShortString$', [fTpMtch, IgnDwrf3, acceptSkSimple]);
(*
@ -896,12 +896,12 @@ begin
// Utf8
// a single ', must appear double ''
// reg ex needs \\ for \
r:=AddStringFmtDef ('ConstUtf8TextAnsi', 'a üü1'''' \\\\t 2 \\t 3''#9''4''#13''5\\n6', 'AnsiString', []);
r:=AddShortStrFmtDef('ConstUtf8TextShort', 'a üü1'''' \\\\t 2 \\t 3''#9''4''#13''5\\n6', 'ShortString', []);
r:=AddShortStrFmtDef('ConstUtf8TextShortStr', 'a üü1'''' \\\\t 2 \\t 3''#9''4''#13''5\\n6', 'ShortString', []);
r:=AddStringFmtDef ('VarUtf8TextAnsi', 'a üü1'''' \\\\t 2 \\t 3''#9''4''#13''5\\n6', 'AnsiString', []);
r:=AddShortStrFmtDef('VarUtf8TextShort', 'a üü1'''' \\\\t 2 \\t 3''#9''4''#13''5\\n6', 'ShortString', []);
r:=AddShortStrFmtDef('VarUtf8TextShortStr', 'a üü1'''' \\\\t 2 \\t 3''#9''4''#13''5\\n6', 'ShortString', []);
r:=AddStringFmtDef ('ConstUtf8TextAnsi', 'a üü1'''' \\\\t 2 \\t 3''#\$?0*9''4''#(13|\$0*D)''5\\n6', 'AnsiString', []);
r:=AddShortStrFmtDef('ConstUtf8TextShort', 'a üü1'''' \\\\t 2 \\t 3''#\$?0*9''4''#(13|\$0*D)''5\\n6', 'ShortString', []);
r:=AddShortStrFmtDef('ConstUtf8TextShortStr', 'a üü1'''' \\\\t 2 \\t 3''#\$?0*9''4''#(13|\$0*D)''5\\n6', 'ShortString', []);
r:=AddStringFmtDef ('VarUtf8TextAnsi', 'a üü1'''' \\\\t 2 \\t 3''#\$?0*9''4''#(13|\$0*D)''5\\n6', 'AnsiString', []);
r:=AddShortStrFmtDef('VarUtf8TextShort', 'a üü1'''' \\\\t 2 \\t 3''#\$?0*9''4''#(13|\$0*D)''5\\n6', 'ShortString', []);
r:=AddShortStrFmtDef('VarUtf8TextShortStr', 'a üü1'''' \\\\t 2 \\t 3''#\$?0*9''4''#(13|\$0*D)''5\\n6', 'ShortString', []);
r:=AddStringFmtDef ('ConstUtf8TextAnsi2', 'üü''''1', 'AnsiString', []);
r:=AddShortStrFmtDef('ConstUtf8TextShort2', 'üü''''1', 'ShortString', []);
@ -910,12 +910,12 @@ begin
r:=AddShortStrFmtDef('VarUtf8TextShort2', 'üü''''1', 'ShortString', []);
r:=AddShortStrFmtDef('VarUtf8TextShortStr2', 'üü''''1', 'ShortString', []);
r:=AddStringFmtDef ('ConstUtf8TextAnsiBad', 'a ''#170''b', 'AnsiString', []);
r:=AddShortStrFmtDef('ConstUtf8TextShortBad', 'a ''#170''b', 'ShortString', []);
r:=AddShortStrFmtDef('ConstUtf8TextShortStrBad', 'a ''#170''b', 'ShortString', []);
r:=AddStringFmtDef ('VarUtf8TextAnsiBad', 'a ''#170''b', 'AnsiString', []);
r:=AddShortStrFmtDef('VarUtf8TextShortBad', 'a ''#170''b', 'ShortString', []);
r:=AddShortStrFmtDef('VarUtf8TextShortStrBad', 'a ''#170''b', 'ShortString', []);
r:=AddStringFmtDef ('ConstUtf8TextAnsiBad', 'a ''#(170|\$AA)''b', 'AnsiString', []);
r:=AddShortStrFmtDef('ConstUtf8TextShortBad', 'a ''#(170|\$AA)''b', 'ShortString', []);
r:=AddShortStrFmtDef('ConstUtf8TextShortStrBad', 'a ''#(170|\$AA)''b', 'ShortString', []);
r:=AddStringFmtDef ('VarUtf8TextAnsiBad', 'a ''#(170|\$AA)''b', 'AnsiString', []);
r:=AddShortStrFmtDef('VarUtf8TextShortBad', 'a ''#(170|\$AA)''b', 'ShortString', []);
r:=AddShortStrFmtDef('VarUtf8TextShortStrBad', 'a ''#(170|\$AA)''b', 'ShortString', []);
{%endregion * Strings * }