mirror of https://gitlab.com/basile.b/dexed.git
sdsdg
This commit is contained in:
parent
60c81b5e34
commit
8bee2dc308
307
src/ce_gdb.pas
307
src/ce_gdb.pas
|
@ -11,7 +11,8 @@ uses
|
||||||
ObjectInspector,
|
ObjectInspector,
|
||||||
ce_common, ce_interfaces, ce_widget, ce_processes, ce_observer, ce_synmemo,
|
ce_common, ce_interfaces, ce_widget, ce_processes, ce_observer, ce_synmemo,
|
||||||
ce_sharedres, ce_stringrange, ce_dsgncontrols, ce_dialogs, ce_dbgitf,
|
ce_sharedres, ce_stringrange, ce_dsgncontrols, ce_dialogs, ce_dbgitf,
|
||||||
ce_ddemangle, ce_writableComponent, EditBtn, strutils, ce_controls;
|
ce_ddemangle, ce_writableComponent, EditBtn, strutils, ce_controls,
|
||||||
|
ce_gdbmi2json;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
|
@ -472,7 +473,6 @@ type
|
||||||
fDoc: TCESynMemo;
|
fDoc: TCESynMemo;
|
||||||
fDbgRunnable: boolean;
|
fDbgRunnable: boolean;
|
||||||
fProj: ICECommonProject;
|
fProj: ICECommonProject;
|
||||||
fJson: TJsonObject;
|
|
||||||
fLog: TStringList;
|
fLog: TStringList;
|
||||||
fDocHandler: ICEMultiDocHandler;
|
fDocHandler: ICEMultiDocHandler;
|
||||||
fMsg: ICEMessagesDisplay;
|
fMsg: ICEMessagesDisplay;
|
||||||
|
@ -509,7 +509,7 @@ type
|
||||||
// GDB output processors
|
// GDB output processors
|
||||||
procedure gdboutQuiet(sender: TObject);
|
procedure gdboutQuiet(sender: TObject);
|
||||||
procedure gdboutJsonize(sender: TObject);
|
procedure gdboutJsonize(sender: TObject);
|
||||||
procedure interpretJson;
|
procedure interpret(json: TJSONObject);
|
||||||
// GDB commands & actions
|
// GDB commands & actions
|
||||||
procedure gdbCommand(aCommand: string; gdbOutProcessor: TNotifyEvent = nil);
|
procedure gdbCommand(aCommand: string; gdbOutProcessor: TNotifyEvent = nil);
|
||||||
procedure infoRegs;
|
procedure infoRegs;
|
||||||
|
@ -1194,7 +1194,6 @@ begin
|
||||||
fMsg:= getMessageDisplay;
|
fMsg:= getMessageDisplay;
|
||||||
fLog := TStringList.Create;
|
fLog := TStringList.Create;
|
||||||
fInspState := TInspectableCPU.Create(@setGpr, @setSsr, @setFlag, @setFpr);
|
fInspState := TInspectableCPU.Create(@setGpr, @setSsr, @setFlag, @setFpr);
|
||||||
fJson := TJsonObject.Create;
|
|
||||||
fStackItems := TStackItems.create;
|
fStackItems := TStackItems.create;
|
||||||
fSubj:= TCEDebugObserverSubject.Create;
|
fSubj:= TCEDebugObserverSubject.Create;
|
||||||
fOptions:= TCEDebugOptions.create(self);
|
fOptions:= TCEDebugOptions.create(self);
|
||||||
|
@ -1244,7 +1243,6 @@ begin
|
||||||
fLog.Free;
|
fLog.Free;
|
||||||
killGdb;
|
killGdb;
|
||||||
fInspState.Free;
|
fInspState.Free;
|
||||||
fJson.Free;
|
|
||||||
fStackItems.Free;
|
fStackItems.Free;
|
||||||
fSynchronizedDocuments.Free;
|
fSynchronizedDocuments.Free;
|
||||||
EntitiesConnector.removeObserver(self);
|
EntitiesConnector.removeObserver(self);
|
||||||
|
@ -1875,211 +1873,7 @@ end;
|
||||||
{$ENDREGION}
|
{$ENDREGION}
|
||||||
|
|
||||||
{$REGION GDB output processors -------------------------------------------------}
|
{$REGION GDB output processors -------------------------------------------------}
|
||||||
procedure parseGdbout(const str: string; var json: TJSONObject);
|
procedure TCEGdbWidget.interpret(json: TJSONObject);
|
||||||
|
|
||||||
procedure parseProperty(node: TJSONObject; r: PStringRange); forward;
|
|
||||||
procedure parseProperty(node: TJSONArray; r: PStringRange); forward;
|
|
||||||
|
|
||||||
procedure parseCLI(node: TJSONObject; r: PStringRange);
|
|
||||||
var
|
|
||||||
lne: TStringRange;
|
|
||||||
msg: string = '';
|
|
||||||
begin
|
|
||||||
if r^.front = '"' then
|
|
||||||
r^.popFront;
|
|
||||||
while true do
|
|
||||||
begin
|
|
||||||
lne := r^.takeUntil(['\', '"']);
|
|
||||||
if (r^.empty) then
|
|
||||||
break
|
|
||||||
else if r^.front = '\' then
|
|
||||||
begin
|
|
||||||
r^.popFront;
|
|
||||||
if r^.front = 'n' then
|
|
||||||
begin
|
|
||||||
r^.popFront;
|
|
||||||
node.Arrays['CLI'].Add(msg + lne.yield);
|
|
||||||
msg := '';
|
|
||||||
end else
|
|
||||||
msg += lne.yield;
|
|
||||||
end
|
|
||||||
else if r^.front = '"' then
|
|
||||||
begin
|
|
||||||
r^.popFront;
|
|
||||||
if r^.front = #10 then
|
|
||||||
begin
|
|
||||||
r^.popFront;
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure parseProperty(node: TJSONArray; r: PStringRange);
|
|
||||||
var
|
|
||||||
c: char;
|
|
||||||
begin
|
|
||||||
while true do
|
|
||||||
begin
|
|
||||||
if r^.empty then
|
|
||||||
exit;
|
|
||||||
c := r^.front;
|
|
||||||
case c of
|
|
||||||
'a'..'z':
|
|
||||||
begin
|
|
||||||
r^.takeUntil('=').yield;
|
|
||||||
r^.popFront;
|
|
||||||
end;
|
|
||||||
'"':
|
|
||||||
begin
|
|
||||||
r^.popFront;
|
|
||||||
node.Strings[node.Count] := r^.takeUntil('"').yield;
|
|
||||||
r^.popFront;
|
|
||||||
end;
|
|
||||||
'{':
|
|
||||||
begin
|
|
||||||
r^.popFront;
|
|
||||||
node.Objects[node.Count] := TJSONObject.Create;
|
|
||||||
parseProperty(node.Objects[node.Count-1], r);
|
|
||||||
end;
|
|
||||||
']':
|
|
||||||
begin
|
|
||||||
r^.popFront;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
',': r^.popFront;
|
|
||||||
#10:
|
|
||||||
begin
|
|
||||||
r^.popFront;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure parseProperty(node: TJSONObject; r: PStringRange);
|
|
||||||
var
|
|
||||||
idt: string = '';
|
|
||||||
v: string;
|
|
||||||
c: char;
|
|
||||||
begin
|
|
||||||
while true do
|
|
||||||
begin
|
|
||||||
if r^.empty then
|
|
||||||
exit;
|
|
||||||
c := r^.front;
|
|
||||||
case c of
|
|
||||||
',':
|
|
||||||
begin
|
|
||||||
r^.popFront;
|
|
||||||
end;
|
|
||||||
'a'..'z':
|
|
||||||
begin
|
|
||||||
idt := r^.takeUntil('=').yield;
|
|
||||||
r^.popFront;
|
|
||||||
end;
|
|
||||||
'"':
|
|
||||||
begin
|
|
||||||
v := '';
|
|
||||||
r^.popFront;
|
|
||||||
while true do
|
|
||||||
begin
|
|
||||||
v += r^.takeUntil(['"','\']).yield;
|
|
||||||
if r^.front = '\' then
|
|
||||||
begin
|
|
||||||
v += '\';
|
|
||||||
r^.popFront;
|
|
||||||
if r^.front = '"' then
|
|
||||||
begin
|
|
||||||
r^.popFront;
|
|
||||||
v += '"';
|
|
||||||
end;
|
|
||||||
end else
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
node.Strings[idt] := v;
|
|
||||||
r^.popFront;
|
|
||||||
end;
|
|
||||||
'{':
|
|
||||||
begin
|
|
||||||
r^.popFront;
|
|
||||||
node.Objects[idt] := TJSONObject.Create;
|
|
||||||
parseProperty(node.Objects[idt], r);
|
|
||||||
end;
|
|
||||||
'[':
|
|
||||||
begin
|
|
||||||
r^.popFront;
|
|
||||||
node.Arrays[idt] := TJSONArray.Create;
|
|
||||||
parseProperty(node.Arrays[idt], r);
|
|
||||||
end;
|
|
||||||
'}', ']':
|
|
||||||
begin
|
|
||||||
r^.popFront;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
' ', #9:
|
|
||||||
r^.popFront;
|
|
||||||
#10:
|
|
||||||
begin
|
|
||||||
r^.popFront;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
var
|
|
||||||
rng: TStringRange = (ptr: nil; pos: 0; len: 0);
|
|
||||||
begin
|
|
||||||
json.Clear;
|
|
||||||
if str.length = 0 then
|
|
||||||
exit;
|
|
||||||
rng.init(str);
|
|
||||||
json.Arrays['OUT'] := TJSONArray.Create;
|
|
||||||
json.Arrays['CLI'] := TJSONArray.Create;
|
|
||||||
while true do
|
|
||||||
begin
|
|
||||||
if rng.empty then
|
|
||||||
exit;
|
|
||||||
case rng.front of
|
|
||||||
// event
|
|
||||||
'*':
|
|
||||||
begin
|
|
||||||
parseProperty(json, rng.popUntil(',')^.popFront);
|
|
||||||
end;
|
|
||||||
// command answer (can be a simple '^done')
|
|
||||||
'^':
|
|
||||||
begin
|
|
||||||
parseProperty(json, rng.popUntil([',', #10]));
|
|
||||||
end;
|
|
||||||
// what would be output in a console by gdb
|
|
||||||
'~':
|
|
||||||
begin
|
|
||||||
parseCLI(json, rng.popFront);
|
|
||||||
end;
|
|
||||||
// internal gdb messages
|
|
||||||
'&':
|
|
||||||
begin
|
|
||||||
parseCLI(json, rng.popFront);
|
|
||||||
end;
|
|
||||||
// async notify / status / out stream when remote (@)
|
|
||||||
'=', '+','@':
|
|
||||||
begin
|
|
||||||
rng.popUntil(#10);
|
|
||||||
if not rng.empty then
|
|
||||||
rng.popFront;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
rng.popUntil(#10);
|
|
||||||
if not rng.empty then
|
|
||||||
rng.popFront;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TCEGdbWidget.interpretJson;
|
|
||||||
|
|
||||||
procedure selectAsmInstr;
|
procedure selectAsmInstr;
|
||||||
var
|
var
|
||||||
|
@ -2107,7 +1901,7 @@ procedure TCEGdbWidget.interpretJson;
|
||||||
|
|
||||||
var
|
var
|
||||||
r: shortint;
|
r: shortint;
|
||||||
i,j: integer;
|
i,j, wx: integer;
|
||||||
val: TJSONData;
|
val: TJSONData;
|
||||||
obj: TJSONObject;
|
obj: TJSONObject;
|
||||||
arr: TJSONArray;
|
arr: TJSONArray;
|
||||||
|
@ -2128,9 +1922,26 @@ var
|
||||||
fpustr: string;
|
fpustr: string;
|
||||||
fFpuExtended: extended;
|
fFpuExtended: extended;
|
||||||
fFpuRaw: array[0..9] of Byte absolute fFpuExtended;
|
fFpuRaw: array[0..9] of Byte absolute fFpuExtended;
|
||||||
|
|
||||||
|
a: TJSONArray;
|
||||||
|
o: TJSONObject;
|
||||||
|
s: TJSONData;
|
||||||
|
|
||||||
|
result_class: string = '';
|
||||||
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
if fJson.findAny('reason', val) then
|
// "done" | "running" | "connected" | "error" | "exit"
|
||||||
|
if json.findArray('out-of-band-records', a) then
|
||||||
|
for wx:= 0 to a.Count -1 do
|
||||||
|
begin
|
||||||
|
if not assigned(a.Objects[wx]) then
|
||||||
|
continue;
|
||||||
|
o := a.Objects[wx];
|
||||||
|
if not assigned(o) then
|
||||||
|
continue;
|
||||||
|
if o.findAny('reason', val) then
|
||||||
begin
|
begin
|
||||||
reason := val.AsString;
|
reason := val.AsString;
|
||||||
r := stopReasons.match(reason);
|
r := stopReasons.match(reason);
|
||||||
|
@ -2146,7 +1957,7 @@ begin
|
||||||
end;
|
end;
|
||||||
if brkreason = dbWatch then
|
if brkreason = dbWatch then
|
||||||
begin
|
begin
|
||||||
if fJson.findObject('wpt', obj) and obj.findAny('exp', val) then
|
if o.findObject('wpt', obj) and obj.findAny('exp', val) then
|
||||||
begin
|
begin
|
||||||
if lstVariables.items.findCaption(val.AsString, k) then
|
if lstVariables.items.findCaption(val.AsString, k) then
|
||||||
begin
|
begin
|
||||||
|
@ -2155,7 +1966,7 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if fJson.findObject('frame', obj) then
|
if o.findObject('frame', obj) then
|
||||||
begin
|
begin
|
||||||
if obj.FindAny('addr', val) then
|
if obj.FindAny('addr', val) then
|
||||||
fLastOffset:=val.AsString;
|
fLastOffset:=val.AsString;
|
||||||
|
@ -2191,7 +2002,7 @@ begin
|
||||||
begin
|
begin
|
||||||
signame := 'unknown signal';
|
signame := 'unknown signal';
|
||||||
sigmean := 'unknown meaning';
|
sigmean := 'unknown meaning';
|
||||||
if fJson.findAny('signal-name', val) then
|
if o.findAny('signal-name', val) then
|
||||||
signame := val.AsString;
|
signame := val.AsString;
|
||||||
if (fOptions.ignoredSignals.Count <> 0) and
|
if (fOptions.ignoredSignals.Count <> 0) and
|
||||||
(fOptions.ignoredSignals.IndexOf(signame) <> -1) then
|
(fOptions.ignoredSignals.IndexOf(signame) <> -1) then
|
||||||
|
@ -2199,9 +2010,9 @@ begin
|
||||||
continueDebugging;
|
continueDebugging;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
if fJson.findAny('signal-meaning', val) then
|
if o.findAny('signal-meaning', val) then
|
||||||
sigmean := val.AsString;
|
sigmean := val.AsString;
|
||||||
if fJson.findObject('frame', obj) then
|
if o.findObject('frame', obj) then
|
||||||
begin
|
begin
|
||||||
if obj.findAny('addr', val) then
|
if obj.findAny('addr', val) then
|
||||||
fLastOffset:=val.AsString;
|
fLastOffset:=val.AsString;
|
||||||
|
@ -2261,12 +2072,13 @@ begin
|
||||||
updateDebugeeOptionsEditor;
|
updateDebugeeOptionsEditor;
|
||||||
killGdb;
|
killGdb;
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if fJson.findAny('msg', val) then
|
if o.findAny('msg', val) then
|
||||||
fMsg.message(val.AsString, nil, amcMisc, amkAuto);
|
fMsg.message(val.AsString, nil, amcMisc, amkAuto);
|
||||||
|
|
||||||
if fJson.findArray('register-values', arr) then
|
if o.findArray('register-values', arr) then
|
||||||
begin
|
begin
|
||||||
for i := 0 to arr.Count-1 do
|
for i := 0 to arr.Count-1 do
|
||||||
begin
|
begin
|
||||||
|
@ -2317,7 +2129,7 @@ begin
|
||||||
cpuViewer.RefreshPropertyValues;
|
cpuViewer.RefreshPropertyValues;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if fJson.findArray('stack', arr) then
|
if o.findArray('stack', arr) then
|
||||||
begin
|
begin
|
||||||
fStackItems.clear;
|
fStackItems.clear;
|
||||||
lstCallStack.Clear;
|
lstCallStack.Clear;
|
||||||
|
@ -2348,9 +2160,9 @@ begin
|
||||||
fStackItems.assignToList(lstCallStack);
|
fStackItems.assignToList(lstCallStack);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
val := fJson.Find('variables');
|
val := o.Find('variables');
|
||||||
if val.isNil then
|
if val.isNil then
|
||||||
val := fJson.Find('locals');
|
val := o.Find('locals');
|
||||||
if val.isNotNil and (val.JSONType = jtArray) then
|
if val.isNotNil and (val.JSONType = jtArray) then
|
||||||
begin
|
begin
|
||||||
j := lstVariables.ItemIndex;
|
j := lstVariables.ItemIndex;
|
||||||
|
@ -2379,7 +2191,7 @@ begin
|
||||||
lstVariables.EndUpdate;
|
lstVariables.EndUpdate;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if fJson.findArray('asm_insns', arr) then
|
if o.findArray('asm_insns', arr) then
|
||||||
begin
|
begin
|
||||||
lstAsm.BeginUpdate;
|
lstAsm.BeginUpdate;
|
||||||
lstAsm.Clear;
|
lstAsm.Clear;
|
||||||
|
@ -2409,7 +2221,7 @@ begin
|
||||||
selectAsmInstr;
|
selectAsmInstr;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if fJson.findArray('threads', arr) then
|
if o.findArray('threads', arr) then
|
||||||
begin
|
begin
|
||||||
lstThreads.BeginUpdate;
|
lstThreads.BeginUpdate;
|
||||||
lstThreads.Clear;
|
lstThreads.Clear;
|
||||||
|
@ -2445,19 +2257,24 @@ begin
|
||||||
lstThreads.EndUpdate;
|
lstThreads.EndUpdate;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if fOptions.showGdbOutput or fShowFromCustomCommand then
|
|
||||||
begin
|
|
||||||
fShowFromCustomCommand := false;
|
|
||||||
if fJson.findArray('CLI', arr) then
|
//if fOptions.showGdbOutput or fShowFromCustomCommand then
|
||||||
for i := 0 to arr.Count-1 do
|
//begin
|
||||||
fMsg.message(arr.Strings[i], nil, amcMisc, amkAuto);
|
// fShowFromCustomCommand := false;
|
||||||
end;
|
// if json.findArray('CLI', arr) then
|
||||||
|
// for i := 0 to arr.Count-1 do
|
||||||
|
// fMsg.message(arr.Strings[i], nil, amcMisc, amkAuto);
|
||||||
|
//end;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEGdbWidget.gdboutJsonize(sender: TObject);
|
procedure TCEGdbWidget.gdboutJsonize(sender: TObject);
|
||||||
var
|
var
|
||||||
str: string;
|
s: string;
|
||||||
|
o: TJSONObject;
|
||||||
|
m: TMemoryStream;
|
||||||
begin
|
begin
|
||||||
if fMsg = nil then
|
if fMsg = nil then
|
||||||
exit;
|
exit;
|
||||||
|
@ -2465,16 +2282,34 @@ begin
|
||||||
fLog.Clear;
|
fLog.Clear;
|
||||||
fGdb.getFullLines(fLog);
|
fGdb.getFullLines(fLog);
|
||||||
if fOptions.showRawMiOutput then
|
if fOptions.showRawMiOutput then
|
||||||
for str in fLog do
|
for s in fLog do
|
||||||
fMsg.message(str, nil, amcMisc, amkAuto);
|
fMsg.message(s, nil, amcMisc, amkAuto);
|
||||||
|
|
||||||
fCommandProcessed := true;
|
fCommandProcessed := true;
|
||||||
|
|
||||||
if flog.Text.isEmpty then
|
if flog.Text.isEmpty then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
parseGdbout(fLog.Text, fJson);
|
fLog.SaveToFile('/home/basile/b.txt');
|
||||||
interpretJson;
|
|
||||||
|
o := gdbmi2json(fLog.Text);
|
||||||
|
|
||||||
|
s := o.FormatJSON();
|
||||||
|
m := TMemoryStream.Create;
|
||||||
|
try
|
||||||
|
m.Write(s[1], length(s));
|
||||||
|
m.SaveToFile('/home/basile/a.txt');
|
||||||
|
finally
|
||||||
|
m.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
try
|
||||||
|
if assigned(o) then
|
||||||
|
interpret(o);
|
||||||
|
finally
|
||||||
|
o.free;
|
||||||
|
end;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEGdbWidget.readOutput;
|
procedure TCEGdbWidget.readOutput;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
unit ce_gdbmi2json;
|
unit ce_gdbmi2json;
|
||||||
|
|
||||||
{$I ce_defines.inc}
|
{$I ce_defines.inc}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
@ -48,7 +49,10 @@ type
|
||||||
TGdbMiNodeKind = (
|
TGdbMiNodeKind = (
|
||||||
gnkLogStreamOutput,
|
gnkLogStreamOutput,
|
||||||
gnkTargetStreamOutput,
|
gnkTargetStreamOutput,
|
||||||
gnkConsoleStreamOutput
|
gnkConsoleStreamOutput,
|
||||||
|
gnkExecAsyncOutput,
|
||||||
|
gnkStatusAsyncOutput,
|
||||||
|
gnkNotifyAsyncOutput
|
||||||
);
|
);
|
||||||
|
|
||||||
(**
|
(**
|
||||||
|
@ -68,7 +72,7 @@ var
|
||||||
|
|
||||||
procedure TTokenList.popFront();
|
procedure TTokenList.popFront();
|
||||||
begin
|
begin
|
||||||
dispose(Items[0]);
|
//dispose(Items[0]);
|
||||||
Delete(0);
|
Delete(0);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -288,7 +292,7 @@ begin
|
||||||
if tokens[0]^.kind <> TTokenKind.tkAnd then
|
if tokens[0]^.kind <> TTokenKind.tkAnd then
|
||||||
exit(nil);
|
exit(nil);
|
||||||
tokens.popFront();
|
tokens.popFront();
|
||||||
if tokens[0]^.kind <> TTokenKind.tkToken then
|
if tokens[0]^.kind <> TTokenKind.tkString then
|
||||||
exit(nil);
|
exit(nil);
|
||||||
s := tokens[0]^.text();
|
s := tokens[0]^.text();
|
||||||
tokens.popFront();
|
tokens.popFront();
|
||||||
|
@ -310,7 +314,7 @@ begin
|
||||||
if tokens[0]^.kind <> TTokenKind.tkAt then
|
if tokens[0]^.kind <> TTokenKind.tkAt then
|
||||||
exit(nil);
|
exit(nil);
|
||||||
tokens.popFront();
|
tokens.popFront();
|
||||||
if tokens[0]^.kind <> TTokenKind.tkToken then
|
if tokens[0]^.kind <> TTokenKind.tkString then
|
||||||
exit(nil);
|
exit(nil);
|
||||||
s := tokens[0]^.text();
|
s := tokens[0]^.text();
|
||||||
tokens.popFront();
|
tokens.popFront();
|
||||||
|
@ -332,7 +336,7 @@ begin
|
||||||
if tokens[0]^.kind <> TTokenKind.tkTiddle then
|
if tokens[0]^.kind <> TTokenKind.tkTiddle then
|
||||||
exit(nil);
|
exit(nil);
|
||||||
tokens.popFront();
|
tokens.popFront();
|
||||||
if tokens[0]^.kind <> TTokenKind.tkToken then
|
if tokens[0]^.kind <> TTokenKind.tkString then
|
||||||
exit(nil);
|
exit(nil);
|
||||||
s := tokens[0]^.text();
|
s := tokens[0]^.text();
|
||||||
tokens.popFront();
|
tokens.popFront();
|
||||||
|
@ -368,6 +372,7 @@ begin
|
||||||
begin
|
begin
|
||||||
result := parseListValue(tokens);
|
result := parseListValue(tokens);
|
||||||
end;
|
end;
|
||||||
|
else assert(false);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -391,8 +396,7 @@ begin
|
||||||
r := parseValue(tokens);
|
r := parseValue(tokens);
|
||||||
if r = nil then
|
if r = nil then
|
||||||
begin
|
begin
|
||||||
result.Free;
|
freeAndNil(result);
|
||||||
result := nil;
|
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
result.Items[0] := r;
|
result.Items[0] := r;
|
||||||
|
@ -402,16 +406,15 @@ begin
|
||||||
r := parseValue(tokens);
|
r := parseValue(tokens);
|
||||||
if r = nil then
|
if r = nil then
|
||||||
begin
|
begin
|
||||||
result.Free;
|
freeAndNil(result);
|
||||||
result := nil;
|
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
result.Items[result.Count] := r;
|
result.Items[result.Count] := r;
|
||||||
end;
|
end;
|
||||||
if tokens[0]^.kind <> tkRightSquare then
|
if tokens[0]^.kind <> tkRightSquare then
|
||||||
begin
|
begin
|
||||||
result.Free;
|
freeAndNil(result);
|
||||||
result := nil;
|
exit;
|
||||||
end;
|
end;
|
||||||
tokens.popFront();
|
tokens.popFront();
|
||||||
end;
|
end;
|
||||||
|
@ -433,8 +436,7 @@ begin
|
||||||
end;
|
end;
|
||||||
if not parseResult(tokens, result) then
|
if not parseResult(tokens, result) then
|
||||||
begin
|
begin
|
||||||
result.Free;
|
freeAndNil(result);
|
||||||
result := nil;
|
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
while tokens[0]^.kind = tkComma do
|
while tokens[0]^.kind = tkComma do
|
||||||
|
@ -442,15 +444,14 @@ begin
|
||||||
tokens.popFront();
|
tokens.popFront();
|
||||||
if not parseResult(tokens, result) then
|
if not parseResult(tokens, result) then
|
||||||
begin
|
begin
|
||||||
result.Free;
|
freeAndNil(result);
|
||||||
result := nil;
|
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if tokens[0]^.kind <> tkRightCurly then
|
if tokens[0]^.kind <> tkRightCurly then
|
||||||
begin
|
begin
|
||||||
result.Free;
|
freeAndNil(result);
|
||||||
result := nil;
|
exit;
|
||||||
end;
|
end;
|
||||||
tokens.popFront();
|
tokens.popFront();
|
||||||
end;
|
end;
|
||||||
|
@ -461,17 +462,15 @@ end;
|
||||||
function parseResult(tokens: TTokenList; obj: TJSONObject): boolean;
|
function parseResult(tokens: TTokenList; obj: TJSONObject): boolean;
|
||||||
var
|
var
|
||||||
v: TJSONData;
|
v: TJSONData;
|
||||||
s: string;
|
s: ansistring;
|
||||||
begin
|
begin
|
||||||
result := false;
|
result := false;
|
||||||
if tokens[0]^.kind <> TTokenKind.tkToken then
|
if tokens[0]^.kind <> TTokenKind.tkToken then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
s := tokens[0]^.text();
|
s := tokens[0]^.text();
|
||||||
tokens.popFront();
|
tokens.popFront();
|
||||||
if tokens[0]^.kind <> TTokenKind.tkAss then
|
if tokens[0]^.kind <> TTokenKind.tkAss then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
tokens.popFront();
|
tokens.popFront();
|
||||||
v := parseValue(tokens);
|
v := parseValue(tokens);
|
||||||
if v = nil then
|
if v = nil then
|
||||||
|
@ -496,14 +495,14 @@ begin
|
||||||
end;
|
end;
|
||||||
if tokens[0]^.kind <> TTokenKind.tkHat then
|
if tokens[0]^.kind <> TTokenKind.tkHat then
|
||||||
begin
|
begin
|
||||||
result.free;
|
freeAndNil(result);
|
||||||
exit(nil);
|
exit;
|
||||||
end;
|
end;
|
||||||
tokens.popFront();
|
tokens.popFront();
|
||||||
if tokens[0]^.kind <> TTokenKind.tkToken then
|
if tokens[0]^.kind <> TTokenKind.tkToken then
|
||||||
begin
|
begin
|
||||||
result.free;
|
freeAndNil(result);
|
||||||
exit(nil);
|
exit;
|
||||||
end;
|
end;
|
||||||
result['result-class'] := TJSONString.Create(tokens[0]^.text());
|
result['result-class'] := TJSONString.Create(tokens[0]^.text());
|
||||||
tokens.popFront();
|
tokens.popFront();
|
||||||
|
@ -515,22 +514,56 @@ begin
|
||||||
tokens.popFront();
|
tokens.popFront();
|
||||||
if not parseResult(tokens, r) then
|
if not parseResult(tokens, r) then
|
||||||
begin
|
begin
|
||||||
result.free;
|
freeAndNil(result);
|
||||||
result := nil;
|
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
(**
|
(**
|
||||||
* BNF: async-record → exec-async-output | status-async-output | notify-async-output
|
* BNF: async-record → [ token ] ("*" | "+" | "=") async-class ( "," result )* nl
|
||||||
*)
|
*)
|
||||||
function parseAsyncRecord(tokens: TTokenList): TJSonObject;
|
function parseAsyncRecord(tokens: TTokenList): TJSONObject;
|
||||||
|
var
|
||||||
|
r: TJSONObject;
|
||||||
begin
|
begin
|
||||||
//TODO-cGDB: parse async records
|
result := TJSONObject.Create;
|
||||||
while tokens[0]^.kind <> tkNl do
|
if tokens[0]^.kind = TTokenKind.tkToken then
|
||||||
|
begin
|
||||||
|
result['token'] := TJSONString.Create(tokens[0]^.text());
|
||||||
tokens.popFront();
|
tokens.popFront();
|
||||||
result := nil;
|
end;
|
||||||
|
case tokens[0]^.kind of
|
||||||
|
tkStar: result['type'] := TJSONIntegerNumber.Create(integer(gnkExecAsyncOutput));
|
||||||
|
tkPlus: result['type'] := TJSONIntegerNumber.Create(integer(gnkStatusAsyncOutput));
|
||||||
|
tkAss: result['type'] := TJSONIntegerNumber.Create(integer(gnkNotifyAsyncOutput));
|
||||||
|
end;
|
||||||
|
tokens.popFront();
|
||||||
|
if tokens[0]^.kind <> TTokenKind.tkToken then
|
||||||
|
begin
|
||||||
|
freeAndNil(result);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
result['async-class'] := TJSONString.Create(tokens[0]^.text());
|
||||||
|
tokens.popFront();
|
||||||
|
|
||||||
|
r := TJSONObject.Create();
|
||||||
|
while tokens[0]^.kind = TTokenKind.tkComma do
|
||||||
|
begin
|
||||||
|
tokens.popFront();
|
||||||
|
if not parseResult(tokens, r) then
|
||||||
|
begin
|
||||||
|
freeAndNil(result);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if tokens[0]^.kind <> TTokenKind.tkNl then
|
||||||
|
begin
|
||||||
|
freeAndNil(result);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
tokens.popFront();
|
||||||
|
result['results'] := r;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
(**
|
(**
|
||||||
|
@ -580,7 +613,8 @@ end;
|
||||||
*)
|
*)
|
||||||
function parseOutput(tokens: TTokenList): TJSonObject;
|
function parseOutput(tokens: TTokenList): TJSonObject;
|
||||||
var
|
var
|
||||||
a: TJSonArray;
|
a: TJSONArray;
|
||||||
|
o: TJSONObject;
|
||||||
begin
|
begin
|
||||||
result := TJSonObject.Create;
|
result := TJSonObject.Create;
|
||||||
if outOfBandRecordBegins(tokens) then
|
if outOfBandRecordBegins(tokens) then
|
||||||
|
@ -588,7 +622,11 @@ begin
|
||||||
a := TJSONArray.Create;
|
a := TJSONArray.Create;
|
||||||
result['out-of-band-records'] := a;
|
result['out-of-band-records'] := a;
|
||||||
while outOfBandRecordBegins(tokens) do
|
while outOfBandRecordBegins(tokens) do
|
||||||
a.Items[a.Count] := parseOutOfBandRecord(tokens);
|
begin
|
||||||
|
o := parseOutOfBandRecord(tokens);
|
||||||
|
if assigned(o) then
|
||||||
|
a.Add(o);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
if tokens[0]^.kind <> tkGdb then
|
if tokens[0]^.kind <> tkGdb then
|
||||||
begin
|
begin
|
||||||
|
@ -596,21 +634,23 @@ begin
|
||||||
end;
|
end;
|
||||||
if tokens[0]^.kind <> tkGdb then
|
if tokens[0]^.kind <> tkGdb then
|
||||||
begin
|
begin
|
||||||
result.Free;
|
//result.Free;
|
||||||
result := nil;
|
//result := nil;
|
||||||
end;
|
end;
|
||||||
tokens.popFront();
|
tokens.popFront();
|
||||||
if tokens[0]^.kind <> tkNl then
|
//assert(tokens.Count > 0);
|
||||||
|
//if tokens[0]^.kind <> tkNl then
|
||||||
begin
|
begin
|
||||||
result.Free;
|
//result.Free;
|
||||||
result := nil;
|
//result := nil;
|
||||||
end;
|
|
||||||
tokens.popFront();
|
|
||||||
if tokens[0]^.kind <> tkEOF then
|
|
||||||
begin
|
|
||||||
result.Free;
|
|
||||||
result := nil;
|
|
||||||
end;
|
end;
|
||||||
|
//tokens.popFront();
|
||||||
|
//assert(tokens.Count > 0);
|
||||||
|
//if tokens[0]^.kind <> tkEOF then
|
||||||
|
//begin
|
||||||
|
// result.Free;
|
||||||
|
// result := nil;
|
||||||
|
//end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function gdbmi2json(const str: string): TJSONObject;
|
function gdbmi2json(const str: string): TJSONObject;
|
||||||
|
|
Loading…
Reference in New Issue