Release 9.12.
[wine.git] / tools / winedump / symbol.c
blob90d34e3375617cf976eef6c41e84407dede09ae8
1 /*
2 * Symbol functions
4 * Copyright 2000 Jon Griffiths
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
23 #include "winedump.h"
26 /* Items that are swapped in arguments after the symbol structure
27 * has been populated
29 static const char * const swap_after[] =
31 "\r", " ", /* Remove whitespace, normalise pointers and brackets */
32 "\t", " ",
33 " ", " ",
34 " * ", " *",
35 "* *", "**",
36 "* ", "*",
37 " ,", ",",
38 "( ", "(",
39 " )", ")",
40 "wchar_t", "WCHAR", /* Help with Unicode compiles */
41 "wctype_t", "WCHAR",
42 "wint_t", "WCHAR",
43 NULL, NULL
47 /* Items containing these substrings are assumed to be wide character
48 * strings, unless they contain more that one '*'. A preceding 'LP'
49 * counts as a '*', so 'LPWCSTR *' is a pointer, not a string
51 static const char * const wide_strings[] =
53 "WSTR", "WCSTR", NULL
56 /* Items containing these substrings are assumed to be wide characters,
57 * unless they contain one '*'. A preceding 'LP' counts as a '*',
58 * so 'WCHAR *' is string, while 'LPWCHAR *' is a pointer
60 static const char * const wide_chars[] =
62 "WCHAR", NULL
65 /* Items containing these substrings are assumed to be ASCII character
66 * strings, as above
68 static const char * const ascii_strings[] =
70 "STR", "CSTR", NULL
74 /* Items containing these substrings are assumed to be ASCII characters,
75 * as above
77 static const char * const ascii_chars[] =
79 "CHAR", "char", NULL
82 /* Any type other than the following will produce a FIXME warning with -v
83 * when mapped to a long, to allow fixups
85 static const char * const known_longs[] =
87 "char", "CHAR", "float", "int", "INT", "short", "SHORT", "long", "LONG",
88 "WCHAR", "BOOL", "bool", "INT16", "WORD", "DWORD", NULL
91 void symbol_init(parsed_symbol* sym, const char* name)
93 memset(sym, 0, sizeof(parsed_symbol));
94 sym->symbol = xstrdup(name);
97 /*******************************************************************
98 * symbol_clear
100 * Free the memory used by a symbol and initialise it
102 void symbol_clear(parsed_symbol *sym)
104 int i;
106 assert (sym);
107 assert (sym->symbol);
109 free (sym->symbol);
110 free (sym->return_text);
111 free (sym->function_name);
113 for (i = sym->argc - 1; i >= 0; i--)
115 free (sym->arg_text [i]);
116 free (sym->arg_name [i]);
118 memset (sym, 0, sizeof (parsed_symbol));
122 /*******************************************************************
123 * symbol_is_valid_c
125 * Check if a symbol is a valid C identifier
127 BOOL symbol_is_valid_c(const parsed_symbol *sym)
129 char *name;
131 assert (sym);
132 assert (sym->symbol);
134 name = sym->symbol;
136 while (*name)
138 if (!isalnum (*name) && *name != '_')
139 return FALSE;
140 name++;
142 return TRUE;
146 /*******************************************************************
147 * symbol_get_call_convention
149 * Return the calling convention of a symbol
151 const char *symbol_get_call_convention(const parsed_symbol *sym)
153 int call = sym->flags ? sym->flags : CALLING_CONVENTION;
155 assert (sym);
156 assert (sym->symbol);
158 if (call & SYM_CDECL)
159 return "cdecl";
160 return "stdcall";
164 /*******************************************************************
165 * symbol_get_spec_type
167 * Get the .spec file text for a symbol's argument
169 const char *symbol_get_spec_type (const parsed_symbol *sym, size_t arg)
171 assert (arg < sym->argc);
172 switch (sym->arg_type [arg])
174 case ARG_STRING: return "str";
175 case ARG_WIDE_STRING: return "wstr";
176 case ARG_POINTER: return "ptr";
177 case ARG_DOUBLE: return "double";
178 case ARG_STRUCT:
179 case ARG_FLOAT:
180 case ARG_LONG: return "long";
182 assert (0);
183 return NULL;
187 /*******************************************************************
188 * symbol_get_type
190 * Get the ARG_ constant for a type string
192 int symbol_get_type (const char *string)
194 const char *iter = string;
195 const char * const *tab;
196 int ptrs = 0;
198 while (*iter && isspace(*iter))
199 iter++;
200 if (*iter == 'P' || *iter == 'H')
201 ptrs++; /* Win32 type pointer */
203 iter = string;
204 while (*iter)
206 if (*iter == '*' || (*iter == 'L' && iter[1] == 'P')
207 || (*iter == '[' && iter[1] == ']'))
208 ptrs++;
209 if (ptrs > 1)
210 return ARG_POINTER;
211 iter++;
214 /* 0 or 1 pointer */
215 tab = wide_strings;
216 while (*tab++)
217 if (strstr (string, tab[-1]))
219 if (ptrs < 2) return ARG_WIDE_STRING;
220 else return ARG_POINTER;
222 tab = wide_chars;
223 while (*tab++)
224 if (strstr (string, tab[-1]))
226 if (!ptrs) return ARG_LONG;
227 else return ARG_WIDE_STRING;
229 tab = ascii_strings;
230 while (*tab++)
231 if (strstr (string, tab[-1]))
233 if (ptrs < 2) return ARG_STRING;
234 else return ARG_POINTER;
236 tab = ascii_chars;
237 while (*tab++)
238 if (strstr (string, tab[-1]))
240 if (!ptrs) return ARG_LONG;
241 else {
242 if (!strstr (string, "unsigned")) /* unsigned char * => ptr */
243 return ARG_STRING;
247 if (ptrs)
248 return ARG_POINTER; /* Pointer to some other type */
250 /* No pointers */
251 if (strstr (string, "double"))
252 return ARG_DOUBLE;
254 if (strstr (string, "float") || strstr (string, "FLOAT"))
255 return ARG_FLOAT;
257 if (strstr (string, "void") || strstr (string, "VOID"))
258 return ARG_VOID;
260 if (strstr (string, "struct") || strstr (string, "union"))
261 return ARG_STRUCT; /* Struct by value, ugh */
263 if (VERBOSE)
265 BOOL known = FALSE;
267 tab = known_longs;
268 while (*tab++)
269 if (strstr (string, tab[-1]))
271 known = TRUE;
272 break;
274 /* Unknown types passed by value can be 'grep'ed out for fixup later */
275 if (!known)
276 printf ("/* FIXME: By value type: Assumed 'int' */ typedef int %s;\n",
277 string);
279 return ARG_LONG;
283 /*******************************************************************
284 * symbol_clean_string
286 * Make a type string more Wine-friendly. Logically const :-)
288 void symbol_clean_string (char *str)
290 const char * const *tab = swap_after;
292 #define SWAP(i, p, x, y) do { i = p; while ((i = str_replace (i, x, y))); } while(0)
294 while (tab [0])
296 char *p;
297 SWAP (p, str, tab [0], tab [1]);
298 tab += 2;
300 if (str [strlen (str) - 1] == ' ')
301 str [strlen (str) - 1] = '\0'; /* no trailing space */
303 if (*str == ' ')
304 memmove (str, str + 1, strlen (str)); /* No leading spaces */