forked from zsaleeba/picoc
-
Notifications
You must be signed in to change notification settings - Fork 2
/
debug.c
126 lines (105 loc) · 3.86 KB
/
debug.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* picoc interactive debugger */
#ifndef NO_DEBUGGER
#include "interpreter.h"
#define BREAKPOINT_HASH(p) ( ((uintptr_t)(p)->FileName) ^ (((p)->Line << 16) | ((p)->CharacterPos << 16)) )
/* initialise the debugger by clearing the breakpoint table */
void DebugInit(Picoc *pc)
{
TableInitTable(&pc->BreakpointTable, &pc->BreakpointHashTable[0], BREAKPOINT_TABLE_SIZE, TRUE);
pc->BreakpointCount = 0;
}
/* free the contents of the breakpoint table */
void DebugCleanup(Picoc *pc)
{
struct TableEntry *Entry;
struct TableEntry *NextEntry;
int Count;
for (Count = 0; Count < pc->BreakpointTable.Size; Count++)
{
for (Entry = pc->BreakpointHashTable[Count]; Entry != NULL; Entry = NextEntry)
{
NextEntry = Entry->Next;
HeapFreeMem(pc, Entry);
}
}
}
/* search the table for a breakpoint */
static struct TableEntry *DebugTableSearchBreakpoint(struct ParseState *Parser, int *AddAt)
{
struct TableEntry *Entry;
Picoc *pc = Parser->pc;
int HashValue = BREAKPOINT_HASH(Parser) % pc->BreakpointTable.Size;
for (Entry = pc->BreakpointHashTable[HashValue]; Entry != NULL; Entry = Entry->Next)
{
if (Entry->p.b.FileName == Parser->FileName && Entry->p.b.Line == Parser->Line && Entry->p.b.CharacterPos == Parser->CharacterPos)
return Entry; /* found */
}
*AddAt = HashValue; /* didn't find it in the chain */
return NULL;
}
/* set a breakpoint in the table */
void DebugSetBreakpoint(struct ParseState *Parser)
{
int AddAt;
struct TableEntry *FoundEntry = DebugTableSearchBreakpoint(Parser, &AddAt);
Picoc *pc = Parser->pc;
if (FoundEntry == NULL)
{
/* add it to the table */
struct TableEntry *NewEntry = (struct TableEntry *) HeapCallocMem(pc, sizeof(struct TableEntry));
if (NewEntry == NULL)
ProgramFailNoParser(pc, "out of memory");
NewEntry->p.b.FileName = Parser->FileName;
NewEntry->p.b.Line = Parser->Line;
NewEntry->p.b.CharacterPos = Parser->CharacterPos;
NewEntry->Next = pc->BreakpointHashTable[AddAt];
pc->BreakpointHashTable[AddAt] = NewEntry;
pc->BreakpointCount++;
}
}
/* delete a breakpoint from the hash table */
int DebugClearBreakpoint(struct ParseState *Parser)
{
struct TableEntry **EntryPtr;
Picoc *pc = Parser->pc;
int HashValue = BREAKPOINT_HASH(Parser) % pc->BreakpointTable.Size;
for (EntryPtr = &pc->BreakpointHashTable[HashValue]; *EntryPtr != NULL; EntryPtr = &(*EntryPtr)->Next)
{
struct TableEntry *DeleteEntry = *EntryPtr;
if (DeleteEntry->p.b.FileName == Parser->FileName && DeleteEntry->p.b.Line == Parser->Line && DeleteEntry->p.b.CharacterPos == Parser->CharacterPos)
{
*EntryPtr = DeleteEntry->Next;
HeapFreeMem(pc, DeleteEntry);
pc->BreakpointCount--;
return TRUE;
}
}
return FALSE;
}
/* before we run a statement, check if there's anything we have to do with the debugger here */
void DebugCheckStatement(struct ParseState *Parser)
{
int DoBreak = FALSE;
int AddAt;
Picoc *pc = Parser->pc;
/* has the user manually pressed break? */
if (pc->DebugManualBreak)
{
PlatformPrintf(pc->CStdOut, "break\n");
DoBreak = TRUE;
pc->DebugManualBreak = FALSE;
}
/* is this a breakpoint location? */
if (Parser->pc->BreakpointCount != 0 && DebugTableSearchBreakpoint(Parser, &AddAt) != NULL)
DoBreak = TRUE;
/* handle a break */
if (DoBreak)
{
PlatformPrintf(pc->CStdOut, "Handling a break\n");
PicocParseInteractiveNoStartPrompt(pc, FALSE);
}
}
void DebugStep()
{
}
#endif /* !NO_DEBUGGER */