| 1 |
unit debug; |
| 2 |
{$IFDEF FPC} |
| 3 |
{$MODE DELPHI}{$H+} |
| 4 |
{$ENDIF} |
| 5 |
(***************************************) |
| 6 |
(* Copyright (C) 2003, SHIRAISHI Kazuo *) |
| 7 |
(***************************************) |
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
interface |
| 12 |
uses struct; |
| 13 |
//function inspectBox(statement:TStatement):boolean; |
| 14 |
procedure ShowCurrentLine(lineNumb:integer); |
| 15 |
procedure DeshowCurrentLine; |
| 16 |
var |
| 17 |
CurrentLineNumb:integer; |
| 18 |
|
| 19 |
implementation |
| 20 |
|
| 21 |
uses StdCtrls, Graphics, Forms, ComCtrls, SysUtils, Dialogs, |
| 22 |
myutils, express,base,texthand,variabl,textfile,helpctex,tracefrm, |
| 23 |
compiler,base0; |
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
var |
| 28 |
prevline:integer; |
| 29 |
|
| 30 |
procedure ShowCurrentLine(lineNumb:integer); |
| 31 |
begin |
| 32 |
CurrentLineNumb:=LineNumb; |
| 33 |
SelectLine(TextHand.memo,LineNumb); |
| 34 |
(* |
| 35 |
with TextHand.memo do |
| 36 |
begin |
| 37 |
Lines.BeginUpdate; |
| 38 |
HideSelection:=true; |
| 39 |
SelStart:=SendMessage(Handle,EM_LINEINDEX,LineNumb,0); |
| 40 |
SelLength:=Length(Lines[LineNumb]); |
| 41 |
SelAttributes.Color:=clGreen; |
| 42 |
SelAttributes.Style:=SelAttributes.Style+[fsBold]; |
| 43 |
|
| 44 |
SelLength:=0; |
| 45 |
SelAttributes.Color:=DefAttributes.Color; |
| 46 |
SelAttributes.Style:=DefAttributes.Style; |
| 47 |
SendMessage(Handle,EM_SCROLLCARET,0,0) ; |
| 48 |
Lines.EndUpdate; |
| 49 |
(owner as TForm).BringToFront; |
| 50 |
end; |
| 51 |
*) |
| 52 |
end; |
| 53 |
|
| 54 |
procedure DeshowCurrentLine; |
| 55 |
begin |
| 56 |
with Texthand.memo do SelEnd:=SelStart; //Texthand.memo.SelLength:=0; |
| 57 |
(* |
| 58 |
with Texthand.memo do |
| 59 |
begin |
| 60 |
Lines.BeginUpdate; |
| 61 |
SelStart:=SendMessage(Handle,EM_LINEINDEX,CurrentLineNumb,0); |
| 62 |
SelStart:=LineIndex(lines.Text,CurrentLineNumb); |
| 63 |
SelLength:=Length(Lines[CurrentLineNumb]); |
| 64 |
if fsUnderLine in SelAttributes.Style then |
| 65 |
SelAttributes.Color:=BreakPointColor |
| 66 |
else |
| 67 |
SelAttributes.Color:=DefAttributes.color; |
| 68 |
SelAttributes.Style:=SelAttributes.Style-[fsBold]; |
| 69 |
SelLength:=0; |
| 70 |
HideSelection:=false; |
| 71 |
Lines.EndUpdate; |
| 72 |
end; |
| 73 |
*) |
| 74 |
end; |
| 75 |
(* |
| 76 |
function inspectBox(statement:TStatement):boolean;far; |
| 77 |
begin |
| 78 |
inspectBox:=true; |
| 79 |
if (extype<0) or (statement.ClassType=TStatement) then exit; |
| 80 |
with statement do |
| 81 |
begin |
| 82 |
if (bkdirective=bkstep) and (prevline=linenumb) |
| 83 |
and (previous<>nil) and (previous.linenumb=linenumb) then exit; {1998.9.24������} |
| 84 |
|
| 85 |
prevline:=linenumb; |
| 86 |
showCurrentLine(linenumb); |
| 87 |
setDebugDlg(statement); |
| 88 |
|
| 89 |
// FrameForm.StatusBar1.Panels[3].text:=ProgramOnRunning; |
| 90 |
FrameForm.StatusBar1.update; |
| 91 |
|
| 92 |
with DebugDlg do |
| 93 |
begin |
| 94 |
RadioGroup1.visible:=true; |
| 95 |
RadioGroup1.ItemIndex:=Ord(bkDirective); |
| 96 |
CheckBox1.Checked:=BreakFlags.TraceMode; |
| 97 |
|
| 98 |
Execute;; |
| 99 |
// showModal ; //CLX������Execute������hang������ |
| 100 |
|
| 101 |
|
| 102 |
BreakFlags.TraceMode:=CheckBox1.Checked; |
| 103 |
BkDirective:=RadioGroup1.ItemIndex; |
| 104 |
if sr=srCancel then |
| 105 |
BkDirective:=BkCancel; |
| 106 |
end; |
| 107 |
case bkdirective of |
| 108 |
bkcontinue: |
| 109 |
ctrlBreakHit:=false; |
| 110 |
bkstep: |
| 111 |
ctrlBreakHit:=true; |
| 112 |
bkcancel: |
| 113 |
begin |
| 114 |
ctrlBreakHit:=true; |
| 115 |
raise EStop.create; |
| 116 |
inspectbox:=false |
| 117 |
end; |
| 118 |
end; |
| 119 |
if BreakFlags.TraceMode then |
| 120 |
with TraceForm do |
| 121 |
begin |
| 122 |
visible:=true; |
| 123 |
if WindowState=wsMinimized then WindowState:=wsNormal; |
| 124 |
end; |
| 125 |
|
| 126 |
DeshowCurrentLine; |
| 127 |
|
| 128 |
end; |
| 129 |
end; |
| 130 |
*) |
| 131 |
|
| 132 |
|
| 133 |
type |
| 134 |
TBreak=class(TStatement) |
| 135 |
//procedure exec;override; |
| 136 |
function Code:Ansistring;override; |
| 137 |
end; |
| 138 |
(* |
| 139 |
procedure TBreak.exec; |
| 140 |
begin |
| 141 |
if not Punit.debug then exit; |
| 142 |
if InsideOfWhen then |
| 143 |
setexception(10007) |
| 144 |
else |
| 145 |
inspectbox(self); |
| 146 |
end; |
| 147 |
*) |
| 148 |
|
| 149 |
|
| 150 |
type |
| 151 |
|
| 152 |
TDebug=class(TStatement) |
| 153 |
state:boolean; |
| 154 |
constructor create(prev,eld:TStatement); |
| 155 |
//procedure exec;override; |
| 156 |
function Code:Ansistring;override; |
| 157 |
end; |
| 158 |
|
| 159 |
TTRace=class(TStatement) |
| 160 |
state:boolean; |
| 161 |
chn:TPrincipal; |
| 162 |
constructor create(prev,eld:TStatement); |
| 163 |
//procedure exec;override; |
| 164 |
function Code:Ansistring;override; |
| 165 |
end; |
| 166 |
|
| 167 |
constructor TDebug.create(prev,eld:TStatement); |
| 168 |
begin |
| 169 |
inherited create(prev,eld); |
| 170 |
if token='ON' then |
| 171 |
begin |
| 172 |
gettoken; |
| 173 |
state:=true; |
| 174 |
end |
| 175 |
else if token='OFF' then |
| 176 |
begin |
| 177 |
gettoken; |
| 178 |
state:=false; |
| 179 |
end |
| 180 |
else |
| 181 |
seterrExpected('ON or OFF',IDH_DEBUG); |
| 182 |
end; |
| 183 |
|
| 184 |
constructor TTrace.create(prev,eld:TStatement); |
| 185 |
begin |
| 186 |
inherited create(prev,eld); |
| 187 |
if token='ON' then |
| 188 |
begin |
| 189 |
gettoken; |
| 190 |
state:=true; |
| 191 |
if Token='TO' then |
| 192 |
begin |
| 193 |
GetToken; |
| 194 |
Check('#',IDH_DEBUG); |
| 195 |
chn:=NExpression; |
| 196 |
end; |
| 197 |
Punit.haveTraceSt:=true; //2010.9.10 for code gen. |
| 198 |
end |
| 199 |
else if token='OFF' then |
| 200 |
begin |
| 201 |
gettoken; |
| 202 |
state:=false; |
| 203 |
end |
| 204 |
else |
| 205 |
seterrExpected('ON or OFF',IDH_DEBUG); |
| 206 |
end; |
| 207 |
(* |
| 208 |
procedure TDebug.exec; |
| 209 |
begin |
| 210 |
Punit.debug:=state; |
| 211 |
end; |
| 212 |
|
| 213 |
procedure TTrace.exec; |
| 214 |
var |
| 215 |
i:longint; |
| 216 |
ch:TTextDevice; |
| 217 |
traceChannel:integer; |
| 218 |
begin |
| 219 |
if PUnit.Debug then |
| 220 |
if state then |
| 221 |
begin |
| 222 |
TraceChannel:=0; |
| 223 |
if chn<>nil then |
| 224 |
begin |
| 225 |
i:=chn.evalInteger; |
| 226 |
if i>=0 then |
| 227 |
begin |
| 228 |
ch:=PUnit.channel(i); |
| 229 |
if ch<>nil then |
| 230 |
with ch do |
| 231 |
if isOpen and (AMode in [amOutIn,amOutput]) |
| 232 |
and (RecType=rcDisplay) then |
| 233 |
TraceChannel:=i |
| 234 |
else |
| 235 |
setexception(7402) |
| 236 |
|
| 237 |
else |
| 238 |
setexception(7401) |
| 239 |
end |
| 240 |
else |
| 241 |
Setexception(7001) ; |
| 242 |
end |
| 243 |
end |
| 244 |
else |
| 245 |
TraceChannel:=-1; |
| 246 |
BreakFlags.TraceChannelPlus1:=TraceChannel+1 |
| 247 |
end; |
| 248 |
*) |
| 249 |
function DEBUGst(prev,eld:TStatement):TStatement;far; |
| 250 |
begin |
| 251 |
DEBUGst:=TDebug.create(prev,eld); |
| 252 |
end; |
| 253 |
|
| 254 |
function BREAKst(prev,eld:TStatement):TStatement;far; |
| 255 |
begin |
| 256 |
BREAKst:=TBreak.create(prev,eld); |
| 257 |
end; |
| 258 |
|
| 259 |
function TRACEst(prev,eld:TStatement):TStatement;far; |
| 260 |
begin |
| 261 |
TRACEst:=TTRACE.create(prev,eld); |
| 262 |
TextMode:=true; |
| 263 |
end; |
| 264 |
|
| 265 |
function TBreak.code:ansistring; |
| 266 |
begin |
| 267 |
DebugVariables.add('var Debug'+IntToStr(PUNIT.LineNumb+1)+':boolean=false;'); |
| 268 |
result:='if Debug'+IntToStr(PUNIT.LineNumb+1) |
| 269 |
+ ' then BreakPr('+QuotedStr(TextHand.memo.lines[linenumb])+');'; |
| 270 |
end; |
| 271 |
|
| 272 |
function TDebug.code:ansistring; |
| 273 |
begin |
| 274 |
DebugVariables.add('var Debug'+IntToStr(PUNIT.LineNumb+1)+':boolean=false;'); |
| 275 |
result:='Debug'+IntToStr(PUNIT.LineNumb+1)+':='+TruthLiteral(state)+';' |
| 276 |
end; |
| 277 |
|
| 278 |
function TTrace.code:ansistring; |
| 279 |
begin |
| 280 |
DebugVariables.add('var Trace'+IntToStr(PUNIT.LineNumb+1)+':TTextDevice=nil;'); |
| 281 |
result := 'if Debug'+IntToStr(PUNIT.LineNumb+1)+ |
| 282 |
' then Trace' + IntToStr(PUNIT.LineNumb+1) + ':='; |
| 283 |
if state then |
| 284 |
if chn <>nil then |
| 285 |
result:=result + 'ChannelList.channel(' + chn.code + ');' |
| 286 |
else |
| 287 |
result:=result + 'console;' |
| 288 |
else |
| 289 |
result:=result + 'nil;' ; |
| 290 |
|
| 291 |
end; |
| 292 |
|
| 293 |
{**********} |
| 294 |
{initialize} |
| 295 |
{**********} |
| 296 |
procedure statementTableinit;far; |
| 297 |
begin |
| 298 |
statementTableinitImperative('DEBUG',DEBUGst); |
| 299 |
statementTableinitImperative('BREAK',BREAKst); |
| 300 |
statementTableinitImperative('TRACE',TRACEst); |
| 301 |
prevline:=-1; |
| 302 |
end; |
| 303 |
|
| 304 |
|
| 305 |
begin |
| 306 |
if TableInitProcs=nil then |
| 307 |
TableInitProcs:=TProcsCollection.create; // |
| 308 |
tableInitProcs.accept(statementTableinit); |
| 309 |
end. |