From be31fbc4ad6e5752e1a077da8e6c7f71b6df4648 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 21 Feb 2024 20:06:44 +0100 Subject: [PATCH] LazDebuggerGdbmi: Return more values via the new API. Moved handling of Displayformat to IDE. --- components/lazdebuggergdbmi/debugutils.pp | 6 +- components/lazdebuggergdbmi/gdbmidebugger.pp | 238 +++++++----------- components/lazdebuggergdbmi/gdbtypeinfo.pp | 26 ++ .../lazdebuggergdbmi/test/TestGdbmi.lpi | 5 +- .../test/gdbmitestutils/testwatchutils.pas | 7 + .../lazdebuggergdbmi/test/testwatches.pas | 90 +++---- 6 files changed, 178 insertions(+), 194 deletions(-) diff --git a/components/lazdebuggergdbmi/debugutils.pp b/components/lazdebuggergdbmi/debugutils.pp index 89501d2b88..146ec4fdfc 100644 --- a/components/lazdebuggergdbmi/debugutils.pp +++ b/components/lazdebuggergdbmi/debugutils.pp @@ -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]; diff --git a/components/lazdebuggergdbmi/gdbmidebugger.pp b/components/lazdebuggergdbmi/gdbmidebugger.pp index 48716776cf..17edb892b6 100644 --- a/components/lazdebuggergdbmi/gdbmidebugger.pp +++ b/components/lazdebuggergdbmi/gdbmidebugger.pp @@ -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 := ''; - // 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 := ''; - 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; diff --git a/components/lazdebuggergdbmi/gdbtypeinfo.pp b/components/lazdebuggergdbmi/gdbtypeinfo.pp index 474323424b..f9dffcaf5b 100644 --- a/components/lazdebuggergdbmi/gdbtypeinfo.pp +++ b/components/lazdebuggergdbmi/gdbtypeinfo.pp @@ -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; diff --git a/components/lazdebuggergdbmi/test/TestGdbmi.lpi b/components/lazdebuggergdbmi/test/TestGdbmi.lpi index aebff00580..07f0cba03f 100644 --- a/components/lazdebuggergdbmi/test/TestGdbmi.lpi +++ b/components/lazdebuggergdbmi/test/TestGdbmi.lpi @@ -123,7 +123,7 @@ - + @@ -145,6 +145,9 @@ + + + diff --git a/components/lazdebuggergdbmi/test/gdbmitestutils/testwatchutils.pas b/components/lazdebuggergdbmi/test/gdbmitestutils/testwatchutils.pas index e0f28caf81..af5ee79f1b 100644 --- a/components/lazdebuggergdbmi/test/gdbmitestutils/testwatchutils.pas +++ b/components/lazdebuggergdbmi/test/gdbmitestutils/testwatchutils.pas @@ -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); diff --git a/components/lazdebuggergdbmi/test/testwatches.pas b/components/lazdebuggergdbmi/test/testwatches.pas index 165be507b0..564f643f99 100644 --- a/components/lazdebuggergdbmi/test/testwatches.pas +++ b/components/lazdebuggergdbmi/test/testwatches.pas @@ -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 * }