comctl32: A couple fixes for tab icon offsets.
[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     BOOL 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_current_symbol(displaypoints[i].func))
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_current_symbol(func)) 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(&lvalue, displaypoints[i].count, displaypoints[i].format);
163         else
164             print_value(&lvalue, displaypoints[i].format, 0);
165 }
166
167 int display_print(void)
168 {
169     int                 i;
170     char                buffer[sizeof(SYMBOL_INFO) + 256];
171     SYMBOL_INFO*        func;
172
173     func = (SYMBOL_INFO*)buffer;
174     memset(func, 0, sizeof(SYMBOL_INFO));
175     func->SizeOfStruct = sizeof(SYMBOL_INFO);
176     func->MaxNameLen = sizeof(buffer) - sizeof(*func);
177     if (!stack_get_current_symbol(func)) return FALSE;
178
179     for (i = 0; i < ndisplays; i++)
180     {
181         if (displaypoints[i].exp == NULL || !displaypoints[i].enabled)
182             continue;
183         if (displaypoints[i].func && !cmp_symbol(displaypoints[i].func, func))
184             continue;
185         print_one_display(i);
186     }
187
188     return TRUE;
189 }
190
191 int display_delete(int displaynum)
192 {
193     int i;
194
195     if (displaynum > ndisplays || displaynum == 0 || displaynum < -1 ||
196         displaypoints[displaynum - 1].exp == NULL)
197     {
198         dbg_printf("Invalid display number\n");
199         return TRUE;
200     }
201
202     if (displaynum == -1)
203     {
204         for (i = 0; i < ndisplays; i++)
205         {
206             if (displaypoints[i].exp != NULL) 
207             {
208                 expr_free(displaypoints[i].exp);
209                 displaypoints[i].exp = NULL;
210             }
211         }
212         maxdisplays = DISPTAB_DELTA;
213         displaypoints = dbg_heap_realloc(displaypoints,
214                                          (maxdisplays = DISPTAB_DELTA) * sizeof(*displaypoints));
215         ndisplays = 0;
216     }
217     else if (displaypoints[--displaynum].exp != NULL) 
218     {
219         expr_free(displaypoints[displaynum].exp);
220         displaypoints[displaynum].exp = NULL;
221         while (displaynum == ndisplays - 1 && displaypoints[displaynum].exp == NULL)
222         {
223             --ndisplays;
224             --displaynum;
225         }
226         if (maxdisplays - ndisplays >= 2 * DISPTAB_DELTA)
227         {
228             /* MARK */
229             maxdisplays = (ndisplays + DISPTAB_DELTA - 1) & ~(DISPTAB_DELTA - 1);
230             displaypoints = dbg_heap_realloc(displaypoints,
231                                              maxdisplays * sizeof(*displaypoints));
232         }
233     }
234     return TRUE;
235 }
236
237 int display_enable(int displaynum, int enable)
238 {
239     char                buffer[sizeof(SYMBOL_INFO) + 256];
240     SYMBOL_INFO*        func;
241
242     func = (SYMBOL_INFO*)buffer;
243     memset(func, 0, sizeof(SYMBOL_INFO));
244     func->SizeOfStruct = sizeof(SYMBOL_INFO);
245     func->MaxNameLen = sizeof(buffer) - sizeof(*func);
246     if (!stack_get_current_symbol(func)) return FALSE;
247
248     --displaynum;
249     if (displaynum >= ndisplays || displaynum < 0 || 
250         displaypoints[displaynum].exp == NULL) 
251     {
252         dbg_printf("Invalid display number\n");
253         return TRUE;
254     }
255
256     displaypoints[displaynum].enabled = enable;
257     if (!displaypoints[displaynum].func || 
258         cmp_symbol(displaypoints[displaynum].func, func))
259     {
260         print_one_display(displaynum);
261     }
262
263     return TRUE;
264 }