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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "wine/port.h"
27 /* Items that are swapped in arguments after the symbol structure
30 static const char *swap_after[] =
32 "\r", " ", /* Remove whitespace, normalise pointers and brackets */
41 "wchar_t", "WCHAR", /* Help with Unicode compliles */
48 /* Items containing these substrings are assumed to be wide character
49 * strings, unless they contain more that one '*'. A preceding 'LP'
50 * counts as a '*', so 'LPWCSTR *' is a pointer, not a string
52 static const char *wide_strings[] =
57 /* Items containing these substrings are assumed to be wide characters,
58 * unless they contain one '*'. A preceding 'LP' counts as a '*',
59 * so 'WCHAR *' is string, while 'LPWCHAR *' is a pointer
61 static const char *wide_chars[] =
66 /* Items containing these substrings are assumed to be ASCII character
69 static const char *ascii_strings[] =
75 /* Items containing these substrings are assumed to be ASCII characters,
78 static const char *ascii_chars[] =
83 /* Any type other than the following will produce a FIXME warning with -v
84 * when mapped to a long, to allow fixups
86 static const char *known_longs[] =
88 "char", "CHAR", "float", "int", "INT", "short", "SHORT", "long", "LONG",
89 "WCHAR", "BOOL", "bool", "INT16", "WORD", "DWORD", NULL
92 int symbol_init(parsed_symbol* sym, const char* name)
94 memset(sym, 0, sizeof(parsed_symbol));
95 sym->symbol = strdup(name);
99 /*******************************************************************
102 * Free the memory used by a symbol and initialise it
104 void symbol_clear(parsed_symbol *sym)
109 assert (sym->symbol);
113 if (sym->return_text)
114 free (sym->return_text);
116 if (sym->function_name)
117 free (sym->function_name);
119 for (i = sym->argc - 1; i >= 0; i--)
121 if (sym->arg_text [i])
122 free (sym->arg_text [i]);
123 if (sym->arg_name [i])
124 free (sym->arg_name [i]);
126 memset (sym, 0, sizeof (parsed_symbol));
130 /*******************************************************************
133 * Check if a symbol is a valid C identifier
135 int symbol_is_valid_c(const parsed_symbol *sym)
140 assert (sym->symbol);
146 if (!isalnum (*name) && *name != '_')
154 /*******************************************************************
155 * symbol_get_call_convention
157 * Return the calling convention of a symbol
159 const char *symbol_get_call_convention(const parsed_symbol *sym)
161 int call = sym->flags ? sym->flags : CALLING_CONVENTION;
164 assert (sym->symbol);
166 if (call & SYM_CDECL)
172 /*******************************************************************
173 * symbol_get_spec_type
175 * Get the .spec file text for a symbols argument
177 const char *symbol_get_spec_type (const parsed_symbol *sym, size_t arg)
179 assert (arg < sym->argc);
180 switch (sym->arg_type [arg])
182 case ARG_STRING: return "str";
183 case ARG_WIDE_STRING: return "wstr";
184 case ARG_POINTER: return "ptr";
185 case ARG_DOUBLE: return "double";
188 case ARG_LONG: return "long";
195 /*******************************************************************
198 * Get the ARG_ constant for a type string
200 int symbol_get_type (const char *string)
202 const char *iter = string;
206 while (*iter && isspace(*iter))
208 if (*iter == 'P' || *iter == 'H')
209 ptrs++; /* Win32 type pointer */
214 if (*iter == '*' || (*iter == 'L' && iter[1] == 'P')
215 || (*iter == '[' && iter[1] == ']'))
225 if (strstr (string, tab[-1]))
227 if (ptrs < 2) return ARG_WIDE_STRING;
228 else return ARG_POINTER;
232 if (strstr (string, tab[-1]))
234 if (!ptrs) return ARG_LONG;
235 else return ARG_WIDE_STRING;
239 if (strstr (string, tab[-1]))
241 if (ptrs < 2) return ARG_STRING;
242 else return ARG_POINTER;
246 if (strstr (string, tab[-1]))
248 if (!ptrs) return ARG_LONG;
250 if (!strstr (string, "unsigned")) /* unsigned char * => ptr */
256 return ARG_POINTER; /* Pointer to some other type */
259 if (strstr (string, "double"))
262 if (strstr (string, "float") || strstr (string, "FLOAT"))
265 if (strstr (string, "void") || strstr (string, "VOID"))
268 if (strstr (string, "struct") || strstr (string, "union"))
269 return ARG_STRUCT; /* Struct by value, ugh */
277 if (strstr (string, tab[-1]))
282 /* Unknown types passed by value can be 'grep'ed out for fixup later */
284 printf ("/* FIXME: By value type: Assumed 'int' */ typedef int %s;\n",
291 /*******************************************************************
292 * symbol_clean_string
294 * Make a type string more Wine-friendly. Logically const :-)
296 void symbol_clean_string (const char *string)
298 const char **tab = swap_after;
299 char *str = (char *)string;
301 #define SWAP(i, p, x, y) do { i = p; while ((i = str_replace (i, x, y))); } while(0)
306 SWAP (p, str, tab [0], tab [1]);
309 if (str [strlen (str) - 1] == ' ')
310 str [strlen (str) - 1] = '\0'; /* no trailing space */
313 memmove (str, str + 1, strlen (str)); /* No leading spaces */