core: Fix libdwarf and Qt build failure
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / SourcesWin.cpp
1 //
2 // SourcesWin.cpp - Sources tracing window
3 //
4 // by Jean-Paul Mari
5 //
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
7 //
8 // Who When What
9 // --- ---------- -------------------------------------------------------------
10 // JPM 08/23/2019 Created this file
11 // JPM Apr./2021 Fixed potential crash with the tabs reset
12
13 // STILL TO DO:
14 // Use the CloseTab signal's value instead to close the current tab
15 //
16
17 #include <stdlib.h>
18 #include <string.h>
19 #include "DBGManager.h"
20 #include "debugger/SourceCWin.h"
21 #include "debugger/SourcesWin.h"
22 #include "m68000/m68kinterface.h"
23
24
25 //
26 SourcesWindow::SourcesWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog),
27 layout(new QVBoxLayout),
28 sourcestabWidget(new QTabWidget),
29 sourcesinfostab(0),
30 NbSourcesInfos(0),
31 CurrentTab(0),
32 OldCurrentTab(0),
33 OldCurrentNumLineSrc(0),
34 indexErrorTab(-1),
35 sourceErrorTab(0)
36 {
37 // prepare layout
38 sourcestabWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
39 sourcestabWidget->setTabsClosable(true);
40 layout->addWidget(sourcestabWidget);
41
42 // set layout
43 setLayout(layout);
44
45 // connect the signals
46 connect(sourcestabWidget, SIGNAL(currentChanged(const int)), this, SLOT(SelectTab(const int)));
47 connect(sourcestabWidget, SIGNAL(tabCloseRequested(const int)), this, SLOT(CloseTab(const int)));
48 }
49
50
51 // Close #tab
52 void SourcesWindow::CloseTab(const int)
53 {
54 CloseCurrentTab();
55 }
56
57
58 // Select tab
59 void SourcesWindow::SelectTab(const int)
60 {
61 #if 0
62 size_t i = 0;
63 QString t = sourcestabWidget->tabText(index);
64 while ((i < NbSourcesInfos) && strcmp(sourcesinfostab[i++].Filename, t.toLatin1().data()));
65
66 if ((i != NbSourcesInfos) && (sourcesinfostab[i - 1].IndexTab != -1) && (CurrentTab == (i - 1)))
67 {
68 sourcesinfostab[(i - 1)].sourceCtab->RefreshContents();
69 }
70 #endif
71 }
72
73
74 // Sources initialisation
75 // Prepare tabs for every available source code file
76 void SourcesWindow::Init(void)
77 {
78 size_t i, j;
79 char *Ptr, *Ptr1;
80
81 // get number of sources
82 NbSourcesInfos = DBGManager_GetNbSources();
83 if (NbSourcesInfos)
84 {
85 // alloc structure for the source informations
86 sourcesinfostab = (SourcesInfos *)calloc(NbSourcesInfos, sizeof(SourcesInfos));
87
88 // fill sources information
89 for (i = 0; i < NbSourcesInfos; i++)
90 {
91 // get source filename without misguiding information
92 Ptr = DBGManager_GetNumSourceFilename(i);
93 Ptr1 = sourcesinfostab[i].Filename = (char *)malloc(strlen(Ptr) + 1);
94 while (((*Ptr == '.') || ((*Ptr == '/') || (*Ptr == '\\'))) && Ptr++);
95 strcpy(Ptr1, Ptr);
96 // get texts dedicated information
97 for (j = 0; j < 2; j++)
98 {
99 sourcesinfostab[i].NbLinesText[j] = DBGManager_GetSrcNbListPtrFromIndex(i, j);
100 }
101 sourcesinfostab[i].NumLinesUsed = DBGManager_GetSrcNumLinesPtrFromIndex(i, true);
102 sourcesinfostab[i].SourceText = DBGManager_GetSrcListPtrFromIndex(i, false);
103 // get remaining information
104 sourcesinfostab[i].Language = DBGManager_GetSrcLanguageFromIndex(i);
105 sourcesinfostab[i].IndexTab = -1;
106 }
107 }
108 else
109 {
110 // no source files exist
111 sourcesinfostab = NULL;
112 }
113 }
114
115
116 // Get the tracing status
117 bool SourcesWindow::GetTraceStatus(void)
118 {
119 if (NbSourcesInfos)
120 {
121 switch (sourcesinfostab[CurrentTab].Language)
122 {
123 case DBG_LANG_VASM_Assembler:
124 break;
125
126 default:
127 return true;
128 break;
129 }
130 }
131
132 return false;
133 }
134
135
136 // Check if the line's number has changed across the tabs
137 // Return true in case of the line is different, otherwise return false
138 bool SourcesWindow::CheckChangeLine(void)
139 {
140 size_t NumLine;
141
142 // get the line number based on the current M68K PC address
143 if (NumLine = DBGManager_GetNumLineFromAdr(m68k_get_reg(NULL, M68K_REG_PC), DBG_NO_TAG))
144 {
145 if (OldCurrentTab == CurrentTab)
146 {
147 if (OldCurrentNumLineSrc != NumLine)
148 {
149 OldCurrentNumLineSrc = NumLine;
150 return true;
151 }
152 }
153 else
154 {
155 OldCurrentTab = CurrentTab;
156 OldCurrentNumLineSrc = 0;
157 }
158 }
159
160 return false;
161 }
162
163
164 // Refresh tabs
165 // Open a new tab for a file source code
166 // Set a unique tab for unavailable source code
167 void SourcesWindow::RefreshContents(void)
168 {
169 size_t m68kPC = m68k_get_reg(NULL, M68K_REG_PC);
170 int index = 0;
171 size_t i;
172 DBGstatus Status;
173 char *Filename;
174
175 // check valid M68K PC address
176 if (m68kPC && NbSourcesInfos)
177 {
178 // get source filename pointed by PC address
179 Filename = DBGManager_GetFullSourceFilenameFromAdr(m68kPC, &Status);
180 if (!Status && Filename)
181 {
182 // look for a new tab
183 for (i = 0; i < NbSourcesInfos; i++, !index)
184 {
185 if (sourcesinfostab[i].Filename)
186 {
187 if (strstr(Filename, sourcesinfostab[i].Filename))
188 {
189 // open a new tab for a source code
190 if (sourcesinfostab[i].IndexTab == -1)
191 {
192 sourcesinfostab[i].IndexTab = index = sourcestabWidget->addTab(sourcesinfostab[i].sourceCtab = new(SourceCWindow), tr(sourcesinfostab[i].Filename));
193 sourcesinfostab[i].sourceCtab->FillTab(i, sourcesinfostab[i].SourceText, sourcesinfostab[i].NbLinesText, sourcesinfostab[i].NumLinesUsed);
194 }
195
196 sourcestabWidget->setCurrentIndex(sourcesinfostab[i].IndexTab);
197 sourcesinfostab[CurrentTab].sourceCtab->SetCursorTrace(sourcesinfostab[CurrentTab].CurrentNumLineSrc, true);
198 sourcesinfostab[i].sourceCtab->SetCursorTrace(sourcesinfostab[i].CurrentNumLineSrc = (int)DBGManager_GetNumLineFromAdr(m68kPC, DBG_NO_TAG), false);
199 sourcesinfostab[i].sourceCtab->RefreshContents();
200 CurrentTab = i;
201 }
202 }
203 }
204 }
205 else
206 {
207 // source file doesn't exist
208 if (indexErrorTab == -1)
209 {
210 indexErrorTab = sourcestabWidget->addTab(sourceErrorTab = new(SourceCWindow), tr("Source file not available"));
211 //sourceErrorTab->hide();
212 }
213 sourcestabWidget->setCurrentIndex(indexErrorTab);
214 }
215 }
216 }
217
218
219 // Close / Remove current tab
220 void SourcesWindow::CloseCurrentTab(void)
221 {
222 size_t i = 0;
223 int Index;
224 QString t = sourcestabWidget->tabText((Index = sourcestabWidget->currentIndex()));
225
226 // check error tab presence
227 if (indexErrorTab == Index)
228 {
229 // close the error tab
230 indexErrorTab = -1;
231 }
232 else
233 {
234 // close source code text tab
235 while ((i < NbSourcesInfos) && strcmp(sourcesinfostab[i++].Filename, t.toLatin1().data()));
236 sourcesinfostab[(i - 1)].IndexTab = -1;
237 }
238
239 // remove the tab
240 sourcestabWidget->removeTab(Index);
241 }
242
243
244 // Handle keyboard
245 void SourcesWindow::keyPressEvent(QKeyEvent * e)
246 {
247 // close/remove the current tab
248 if (e->key() == Qt::Key_Escape)
249 {
250 CloseCurrentTab();
251 }
252 }
253
254
255 // Reset all source files tab
256 void SourcesWindow::Reset(void)
257 {
258 // clear the tabs
259 sourcestabWidget->clear();
260
261 // clear tab information
262 while (NbSourcesInfos)
263 {
264 free(sourcesinfostab[--NbSourcesInfos].Filename);
265 }
266 free(sourcesinfostab);
267 }
268
269
270 //
271 void SourcesWindow::Close(void)
272 {
273 Reset();
274 }