Stub implementations for AbortPrinter, AddPortEx{A,W},
[wine] / programs / winedbg / display.c
1 /*
2  * File display.c - display handling for Wine internal debugger.
3  *
4  * Copyright (C) 1997, Eric Youngdale.
5  * Copyright (C) 2003, Michal Miroslaw
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library 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 GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include "debugger.h"
26 #include "wine/debug.h"
27
28 WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
29
30 /* needs to be power of 2, search for MARK to see why :) */
31 #define DISPTAB_DELTA 8
32
33 struct display
34 {
35     struct expr*        exp;
36     int                 count;
37     char                format;
38     char                enabled;
39     char                func_buffer[sizeof(SYMBOL_INFO) + 256];
40     SYMBOL_INFO*        func;
41 };
42
43 static struct display *displaypoints = NULL;
44 static unsigned int maxdisplays = 0, ndisplays = 0;
45
46 #define OFFSET_OF(_f,_s)        ((unsigned)(&(((_s*)NULL)->_f)))
47
48 static inline BOOL cmp_symbol(const SYMBOL_INFO* si1, const SYMBOL_INFO* si2)
49 {
50     /* FIXME: !memcmp(si1, si2, sizeof(SYMBOL_INFO) + si1->NameLen)
51      * is wrong because sizeof(SYMBOL_INFO) can be aligned on 4-byte boundary
52      * Note: we also need to zero out the structures before calling 
53      * stack_get_frame, so that un-touched fields by stack_get_frame
54      * get the same value!!
55      */
56     return !memcmp(si1, si2, OFFSET_OF(Name, SYMBOL_INFO)) &&
57         !memcmp(si1->Name, si2->Name, si1->NameLen);
58 }
59
60 int display_add(struct expr *exp, int count, char format)
61 {
62     int         i;
63     int         local_binding = FALSE;
64
65     for (i = 0; i < ndisplays; i++)
66         if (displaypoints[i].exp == NULL)
67             break;
68
69     if (i == maxdisplays)
70     {
71         /* no space left - expand */
72         maxdisplays += DISPTAB_DELTA;
73         displaypoints = dbg_heap_realloc(displaypoints,
74                                          maxdisplays * sizeof(*displaypoints));
75     }
76
77     if (i == ndisplays) ndisplays++;
78
79     displaypoints[i].exp           = expr_clone(exp, &local_binding);
80     displaypoints[i].count         = count;
81     displaypoints[i].format        = format;
82     displaypoints[i].enabled       = TRUE;
83     if (local_binding)
84     {
85         displaypoints[i].func = (SYMBOL_INFO*)displaypoints[i].func_buffer;
86         memset(displaypoints[i].func, 0, sizeof(SYMBOL_INFO));
87         displaypoints[i].func->SizeOfStruct = sizeof(SYMBOL_INFO);
88         displaypoints[i].func->MaxNameLen = sizeof(displaypoints[i].func_buffer) -
89             sizeof(*displaypoints[i].func);
90         if (!stack_get_frame(displaypoints[i].func, NULL))
91         {
92             expr_free(displaypoints[i].exp);
93             displaypoints[i].exp = NULL;
94             return FALSE;
95         }
96     }
97     else displaypoints[i].func = NULL;
98
99     return TRUE;
100 }
101
102 int display_info(void)
103 {
104     int                 i;
105     char                buffer[sizeof(SYMBOL_INFO) + 256];
106     SYMBOL_INFO*        func;
107     const char*         info;
108
109     func = (SYMBOL_INFO*)buffer;
110     memset(func, 0, sizeof(SYMBOL_INFO));
111     func->SizeOfStruct = sizeof(SYMBOL_INFO);
112     func->MaxNameLen = sizeof(buffer) - sizeof(*func);
113     if (!stack_get_frame(func, NULL)) return FALSE;
114
115     for (i = 0; i < ndisplays; i++)
116     {
117         if (displaypoints[i].exp == NULL) continue;
118
119         dbg_printf("%d: ", i + 1);
120         expr_print(displaypoints[i].exp);
121
122         if (displaypoints[i].enabled)
123         {
124             if (displaypoints[i].func && !cmp_symbol(displaypoints[i].func, func))
125                 info = " (out of scope)";
126             else
127                 info = "";
128         }
129         else
130             info = " (disabled)";
131         if (displaypoints[i].func)
132             dbg_printf(" in %s", displaypoints[i].func->Name);
133         dbg_printf("%s\n", info);
134     }
135     return TRUE;
136 }
137
138 static void print_one_display(int i)
139 {
140     struct dbg_lvalue   lvalue;
141
142     if (displaypoints[i].enabled) 
143     {
144         lvalue = expr_eval(displaypoints[i].exp);
145         if (lvalue.type.id == dbg_itype_none)
146         {
147             dbg_printf("Unable to evaluate expression ");
148             expr_print(displaypoints[i].exp);
149             dbg_printf("\nDisabling display %d ...\n", i + 1);
150             displaypoints[i].enabled = FALSE;
151             return;
152         }
153     }
154
155     dbg_printf("%d: ", i + 1);
156     expr_print(displaypoints[i].exp);
157     dbg_printf(" = ");
158     if (!displaypoints[i].enabled)
159         dbg_printf("(disabled)\n");
160     else
161         if (displaypoints[i].format == 'i')
162             memory_examine((void*)types_extract_as_integer(&lvalue), 
163                            displaypoints[i].count, displaypoints[i].format);
164         else
165             print_value(&lvalue, displaypoints[i].format, 0);
166 }
167
168 int display_print(void)
169 {
170     int                 i;
171     char                buffer[sizeof(SYMBOL_INFO) + 256];
172     SYMBOL_INFO*        func;
173
174     func = (SYMBOL_INFO*)buffer;
175     memset(func, 0, sizeof(SYMBOL_INFO));
176     func->SizeOfStruct = sizeof(SYMBOL_INFO);
177     func->MaxNameLen = sizeof(buffer) - sizeof(*func);
178     if (!stack_get_frame(func, NULL)) return FALSE;
179
180     for (i = 0; i < ndisplays; i++)
181     {
182         if (displaypoints[i].exp == NULL || !displaypoints[i].enabled)
183             continue;
184         if (displaypoints[i].func && !cmp_symbol(displaypoints[i].func, func))
185             continue;
186         print_one_display(i);
187     }
188
189     return TRUE;
190 }
191
192 int display_delete(int displaynum)
193 {
194     int i;
195
196     if (displaynum > ndisplays || displaynum == 0 || displaynum < -1 ||
197         displaypoints[displaynum - 1].exp == NULL)
198     {
199         dbg_printf("Invalid display number\n");
200         return TRUE;
201     }
202
203     if (displaynum == -1)
204     {
205         for (i = 0; i < ndisplays; i++)
206         {
207             if (displaypoints[i].exp != NULL) 
208             {
209                 expr_free(displaypoints[i].exp);
210                 displaypoints[i].exp = NULL;
211             }
212         }
213         maxdisplays = DISPTAB_DELTA;
214         displaypoints = dbg_heap_realloc(displaypoints,
215                                          (maxdisplays = DISPTAB_DELTA) * sizeof(*displaypoints));
216         ndisplays = 0;
217     }
218     else if (displaypoints[--displaynum].exp != NULL) 
219     {
220         expr_free(displaypoints[displaynum].exp);
221         displaypoints[displaynum].exp = NULL;
222         while (displaynum == ndisplays - 1 && displaypoints[displaynum].exp == NULL)
223         {
224             --ndisplays;
225             --displaynum;
226         }
227         if (maxdisplays - ndisplays >= 2 * DISPTAB_DELTA)
228         {
229             /* MARK */
230             maxdisplays = (ndisplays + DISPTAB_DELTA - 1) & ~(DISPTAB_DELTA - 1);
231             displaypoints = dbg_heap_realloc(displaypoints,
232                                              maxdisplays * sizeof(*displaypoints));
233         }
234     }
235     return TRUE;
236 }
237
238 int display_enable(int displaynum, int enable)
239 {
240     char                buffer[sizeof(SYMBOL_INFO) + 256];
241     SYMBOL_INFO*        func;
242
243     func = (SYMBOL_INFO*)buffer;
244     memset(func, 0, sizeof(SYMBOL_INFO));
245     func->SizeOfStruct = sizeof(SYMBOL_INFO);
246     func->MaxNameLen = sizeof(buffer) - sizeof(*func);
247     if (!stack_get_frame(func, NULL)) return FALSE;
248
249     --displaynum;
250     if (displaynum >= ndisplays || displaynum < 0 || 
251         displaypoints[displaynum].exp == NULL) 
252     {
253         dbg_printf("Invalid display number\n");
254         return TRUE;
255     }
256
257     displaypoints[displaynum].enabled = enable;
258     if (!displaypoints[displaynum].func || 
259         cmp_symbol(displaypoints[displaynum].func, func))
260     {
261         print_one_display(displaynum);
262     }
263
264     return TRUE;
265 }