[gdb/testsuite] Fix gdb.fortran/info-types.exp regexp
[deliverable/binutils-gdb.git] / gdb / mingw-hdep.c
CommitLineData
121ce6e5
DJ
1/* Host support routines for MinGW, for GDB, the GNU debugger.
2
42a4f53d 3 Copyright (C) 2006-2019 Free Software Foundation, Inc.
121ce6e5
DJ
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
121ce6e5
DJ
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
121ce6e5
DJ
19
20#include "defs.h"
d9ac0664 21#include "main.h"
0ea3f30e 22#include "serial.h"
b803fb0f 23#include "event-loop.h"
121ce6e5 24
0ea3f30e 25#include "gdb_select.h"
121ce6e5
DJ
26
27#include <windows.h>
28
d9ac0664
EZ
29/* Return an absolute file name of the running GDB, if possible, or
30 ARGV0 if not. The return value is in malloc'ed storage. */
31
32char *
33windows_get_absolute_argv0 (const char *argv0)
34{
35 char full_name[PATH_MAX];
36
37 if (GetModuleFileName (NULL, full_name, PATH_MAX))
38 return xstrdup (full_name);
39 return xstrdup (argv0);
40}
41
0ea3f30e
DJ
42/* Wrapper for select. On Windows systems, where the select interface
43 only works for sockets, this uses the GDB serial abstraction to
44 handle sockets, consoles, pipes, and serial ports.
45
46 The arguments to this function are the same as the traditional
47 arguments to select on POSIX platforms. */
48
49int
50gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
51 struct timeval *timeout)
52{
53 static HANDLE never_handle;
54 HANDLE handles[MAXIMUM_WAIT_OBJECTS];
55 HANDLE h;
56 DWORD event;
57 DWORD num_handles;
4577549b
DJ
58 /* SCBS contains serial control objects corresponding to file
59 descriptors in READFDS and WRITEFDS. */
60 struct serial *scbs[MAXIMUM_WAIT_OBJECTS];
61 /* The number of valid entries in SCBS. */
62 size_t num_scbs;
0ea3f30e
DJ
63 int fd;
64 int num_ready;
4577549b 65 size_t indx;
0ea3f30e
DJ
66
67 num_ready = 0;
68 num_handles = 0;
4577549b 69 num_scbs = 0;
0ea3f30e
DJ
70 for (fd = 0; fd < n; ++fd)
71 {
72 HANDLE read = NULL, except = NULL;
73 struct serial *scb;
74
75 /* There is no support yet for WRITEFDS. At present, this isn't
76 used by GDB -- but we do not want to silently ignore WRITEFDS
77 if something starts using it. */
78 gdb_assert (!writefds || !FD_ISSET (fd, writefds));
79
98739726
DJ
80 if ((!readfds || !FD_ISSET (fd, readfds))
81 && (!exceptfds || !FD_ISSET (fd, exceptfds)))
0ea3f30e 82 continue;
0ea3f30e
DJ
83
84 scb = serial_for_fd (fd);
85 if (scb)
4577549b
DJ
86 {
87 serial_wait_handle (scb, &read, &except);
88 scbs[num_scbs++] = scb;
89 }
0ea3f30e
DJ
90
91 if (read == NULL)
4577549b 92 read = (HANDLE) _get_osfhandle (fd);
0ea3f30e
DJ
93 if (except == NULL)
94 {
95 if (!never_handle)
96 never_handle = CreateEvent (0, FALSE, FALSE, 0);
97
98 except = never_handle;
99 }
100
98739726 101 if (readfds && FD_ISSET (fd, readfds))
0ea3f30e
DJ
102 {
103 gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
104 handles[num_handles++] = read;
105 }
106
98739726 107 if (exceptfds && FD_ISSET (fd, exceptfds))
0ea3f30e
DJ
108 {
109 gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
110 handles[num_handles++] = except;
111 }
112 }
0ea3f30e 113
585a46a2 114 gdb_assert (num_handles <= MAXIMUM_WAIT_OBJECTS);
0ea3f30e
DJ
115
116 event = WaitForMultipleObjects (num_handles,
117 handles,
118 FALSE,
119 timeout
120 ? (timeout->tv_sec * 1000
121 + timeout->tv_usec / 1000)
122 : INFINITE);
123 /* EVENT can only be a value in the WAIT_ABANDONED_0 range if the
124 HANDLES included an abandoned mutex. Since GDB doesn't use
125 mutexes, that should never occur. */
126 gdb_assert (!(WAIT_ABANDONED_0 <= event
127 && event < WAIT_ABANDONED_0 + num_handles));
4577549b
DJ
128 /* We no longer need the helper threads to check for activity. */
129 for (indx = 0; indx < num_scbs; ++indx)
130 serial_done_wait_handle (scbs[indx]);
0ea3f30e
DJ
131 if (event == WAIT_FAILED)
132 return -1;
133 if (event == WAIT_TIMEOUT)
134 return 0;
135 /* Run through the READFDS, clearing bits corresponding to descriptors
136 for which input is unavailable. */
137 h = handles[event - WAIT_OBJECT_0];
138 for (fd = 0, indx = 0; fd < n; ++fd)
139 {
140 HANDLE fd_h;
c3e2b812 141
98739726
DJ
142 if ((!readfds || !FD_ISSET (fd, readfds))
143 && (!exceptfds || !FD_ISSET (fd, exceptfds)))
c3e2b812 144 continue;
0ea3f30e 145
98739726 146 if (readfds && FD_ISSET (fd, readfds))
0ea3f30e
DJ
147 {
148 fd_h = handles[indx++];
149 /* This handle might be ready, even though it wasn't the handle
150 returned by WaitForMultipleObjects. */
151 if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
152 FD_CLR (fd, readfds);
153 else
154 num_ready++;
155 }
156
98739726 157 if (exceptfds && FD_ISSET (fd, exceptfds))
0ea3f30e
DJ
158 {
159 fd_h = handles[indx++];
160 /* This handle might be ready, even though it wasn't the handle
161 returned by WaitForMultipleObjects. */
162 if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
163 FD_CLR (fd, exceptfds);
164 else
165 num_ready++;
166 }
167 }
168
169 return num_ready;
170}
e4adb939
EZ
171
172/* Map COLOR's RGB triplet, with 8 bits per component, into 16 Windows
173 console colors, where each component has just 1 bit, plus a single
174 intensity bit which affects all 3 components. */
175static int
176rgb_to_16colors (const ui_file_style::color &color)
177{
178 uint8_t rgb[3];
179 color.get_rgb (rgb);
180
181 int retval = 0;
182 for (int i = 0; i < 3; i++)
183 {
184 /* Subdivide 256 possible values of each RGB component into 3
185 regions: no color, normal color, bright color. 256 / 3 = 85,
186 but ui-style.c follows xterm and uses 92 for R and G
187 components of the bright-blue color, so we bias the divisor a
188 bit to have the bright colors between 9 and 15 identical to
189 what ui-style.c expects. */
190 int bits = rgb[i] / 93;
191 retval |= ((bits > 0) << (2 - i)) | ((bits > 1) << 3);
192 }
193
194 return retval;
195}
196
197/* Zero if not yet initialized, 1 if stdout is a console device, else -1. */
198static int mingw_console_initialized;
199
200/* Handle to stdout . */
201static HANDLE hstdout = INVALID_HANDLE_VALUE;
202
203/* Text attribute to use for normal text (the "none" pseudo-color). */
204static SHORT norm_attr;
205
206/* The most recently applied style. */
207static ui_file_style last_style;
208
209/* Alternative for the libc 'fputs' which handles embedded SGR
210 sequences in support of styling. */
211
212int
213gdb_console_fputs (const char *linebuf, FILE *fstream)
214{
215 if (!mingw_console_initialized)
216 {
217 hstdout = (HANDLE)_get_osfhandle (fileno (fstream));
218 DWORD cmode;
219 CONSOLE_SCREEN_BUFFER_INFO csbi;
220
221 if (hstdout != INVALID_HANDLE_VALUE
222 && GetConsoleMode (hstdout, &cmode) != 0
223 && GetConsoleScreenBufferInfo (hstdout, &csbi))
224 {
225 norm_attr = csbi.wAttributes;
226 mingw_console_initialized = 1;
227 }
228 else if (hstdout != INVALID_HANDLE_VALUE)
229 mingw_console_initialized = -1; /* valid, but not a console device */
230 }
231 /* If our stdout is not a console device, let the default 'fputs'
232 handle the task. */
233 if (mingw_console_initialized <= 0)
234 return 0;
235
236 /* Mapping between 8 ANSI colors and Windows console attributes. */
237 static int fg_color[] = {
238 0, /* black */
239 FOREGROUND_RED, /* red */
240 FOREGROUND_GREEN, /* green */
241 FOREGROUND_GREEN | FOREGROUND_RED, /* yellow */
242 FOREGROUND_BLUE, /* blue */
243 FOREGROUND_BLUE | FOREGROUND_RED, /* magenta */
244 FOREGROUND_BLUE | FOREGROUND_GREEN, /* cyan */
245 FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE /* gray */
246 };
247 static int bg_color[] = {
248 0, /* black */
249 BACKGROUND_RED, /* red */
250 BACKGROUND_GREEN, /* green */
251 BACKGROUND_GREEN | BACKGROUND_RED, /* yellow */
252 BACKGROUND_BLUE, /* blue */
253 BACKGROUND_BLUE | BACKGROUND_RED, /* magenta */
254 BACKGROUND_BLUE | BACKGROUND_GREEN, /* cyan */
255 BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE /* gray */
256 };
257
258 ui_file_style style = last_style;
259 unsigned char c;
260 size_t n_read;
261
262 for ( ; (c = *linebuf) != 0; linebuf += n_read)
263 {
264 if (c == '\033')
265 {
266 fflush (fstream);
267 bool parsed = style.parse (linebuf, &n_read);
268 if (n_read <= 0) /* should never happen */
269 n_read = 1;
270 if (!parsed)
271 {
272 /* This means we silently swallow SGR sequences we
273 cannot parse. */
274 continue;
275 }
276 /* Colors. */
277 const ui_file_style::color &fg = style.get_foreground ();
278 const ui_file_style::color &bg = style.get_background ();
279 int fgcolor, bgcolor, bright, inverse;
280 if (fg.is_none ())
281 fgcolor = norm_attr & 15;
282 else if (fg.is_basic ())
283 fgcolor = fg_color[fg.get_value () & 15];
284 else
285 fgcolor = rgb_to_16colors (fg);
286 if (bg.is_none ())
287 bgcolor = norm_attr & (15 << 4);
288 else if (bg.is_basic ())
289 bgcolor = bg_color[bg.get_value () & 15];
290 else
291 bgcolor = rgb_to_16colors (bg) << 4;
292
293 /* Intensity. */
294 switch (style.get_intensity ())
295 {
296 case ui_file_style::NORMAL:
297 case ui_file_style::DIM:
298 bright = 0;
299 break;
300 case ui_file_style::BOLD:
301 bright = 1;
302 break;
303 default:
304 gdb_assert_not_reached ("invalid intensity");
305 }
306
307 /* Inverse video. */
308 if (style.is_reverse ())
309 inverse = 1;
310 else
311 inverse = 0;
312
313 /* Construct the attribute. */
314 if (inverse)
315 {
316 int t = fgcolor;
317 fgcolor = (bgcolor >> 4);
318 bgcolor = (t << 4);
319 }
320 if (bright)
321 fgcolor |= FOREGROUND_INTENSITY;
322
323 SHORT attr = (bgcolor & (15 << 4)) | (fgcolor & 15);
324
325 /* Apply the attribute. */
326 SetConsoleTextAttribute (hstdout, attr);
327 }
328 else
329 {
330 /* When we are about to write newline, we need to clear to
331 EOL with the normal attribute, to avoid spilling the
332 colors to the next screen line. We assume here that no
333 non-default attribute extends beyond the newline. */
334 if (c == '\n')
335 {
336 DWORD nchars;
337 COORD start_pos;
338 DWORD written;
339 CONSOLE_SCREEN_BUFFER_INFO csbi;
340
341 fflush (fstream);
342 GetConsoleScreenBufferInfo (hstdout, &csbi);
343
344 if (csbi.wAttributes != norm_attr)
345 {
346 start_pos = csbi.dwCursorPosition;
347 nchars = csbi.dwSize.X - start_pos.X;
348
349 FillConsoleOutputAttribute (hstdout, norm_attr, nchars,
350 start_pos, &written);
351 FillConsoleOutputCharacter (hstdout, ' ', nchars,
352 start_pos, &written);
353 }
354 }
355 fputc (c, fstream);
356 n_read = 1;
357 }
358 }
359
360 last_style = style;
361 return 1;
362}
This page took 1.236325 seconds and 4 git commands to generate.