4 * Copyright 2000 Jon Griffiths
9 /* Items that are swapped in arguments after the symbol structure
12 static const char *swap_after[] =
14 "\r", " ", /* Remove whitespace, normalise pointers and brackets */
23 "wchar_t", "WCHAR", /* Help with Unicode compliles */
26 "unsigned __int64", "__uint64", /* Wine doesn't cope with unsigned i64's */
31 /* Items containing these substrings are assumed to be wide character
32 * strings, unless they contain more that one '*'. A preceeding 'LP'
33 * counts as a '*', so 'LPWCSTR *' is a pointer, not a string
35 static const char *wide_strings[] =
40 /* Items containing these substrings are assumed to be wide characters,
41 * unless they contain one '*'. A preceeding 'LP' counts as a '*',
42 * so 'WCHAR *' is string, while 'LPWCHAR *' is a pointer
44 static const char *wide_chars[] =
49 /* Items containing these substrings are assumed to be ASCII character
52 static const char *ascii_strings[] =
58 /* Items containing these substrings are assumed to be ASCII characters,
61 static const char *ascii_chars[] =
66 /* Any type other than the following will produce a FIXME warning with -v
67 * when mapped to a long, to allow fixups
69 static const char *known_longs[] =
71 "char", "CHAR", "float", "int", "INT", "short", "SHORT", "long", "LONG",
72 "WCHAR", "BOOL", "bool", "INT16", "WORD", "DWORD", NULL
75 int symbol_init(parsed_symbol* sym, const char* name)
77 memset(sym, 0, sizeof(parsed_symbol));
78 sym->symbol = strdup(name);
82 /*******************************************************************
85 * Free the memory used by a symbol and initialise it
87 void symbol_clear(parsed_symbol *sym)
97 free (sym->return_text);
99 if (sym->function_name)
100 free (sym->function_name);
102 for (i = sym->argc - 1; i >= 0; i--)
104 if (sym->arg_text [i])
105 free (sym->arg_text [i]);
106 if (sym->arg_name [i])
107 free (sym->arg_name [i]);
109 memset (sym, 0, sizeof (parsed_symbol));
113 /*******************************************************************
116 * Check if a symbol is a valid C identifier
118 int symbol_is_valid_c(const parsed_symbol *sym)
123 assert (sym->symbol);
129 if (!isalnum (*name) && *name != '_')
137 /*******************************************************************
138 * symbol_get_call_convention
140 * Return the calling convention of a symbol
142 const char *symbol_get_call_convention(const parsed_symbol *sym)
144 int call = sym->flags ? sym->flags : CALLING_CONVENTION;
147 assert (sym->symbol);
149 if (call & SYM_CDECL)
155 /*******************************************************************
156 * symbol_get_spec_type
158 * Get the .spec file text for a symbols argument
160 const char *symbol_get_spec_type (const parsed_symbol *sym, size_t arg)
162 assert (arg < sym->argc);
163 switch (sym->arg_type [arg])
165 case ARG_STRING: return "str";
166 case ARG_WIDE_STRING: return "wstr";
167 case ARG_POINTER: return "ptr";
168 case ARG_DOUBLE: return "double";
171 case ARG_LONG: return "long";
178 /*******************************************************************
181 * Get the ARG_ constant for a type string
183 int symbol_get_type (const char *string)
185 const char *iter = string;
189 while (*iter && isspace(*iter))
191 if (*iter == 'P' || *iter == 'H')
192 ptrs++; /* Win32 type pointer */
197 if (*iter == '*' || (*iter == 'L' && iter[1] == 'P')
198 || (*iter == '[' && iter[1] == ']'))
208 if (strstr (string, tab[-1]))
210 if (ptrs < 2) return ARG_WIDE_STRING;
211 else return ARG_POINTER;
215 if (strstr (string, tab[-1]))
217 if (!ptrs) return ARG_LONG;
218 else return ARG_WIDE_STRING;
222 if (strstr (string, tab[-1]))
224 if (ptrs < 2) return ARG_STRING;
225 else return ARG_POINTER;
229 if (strstr (string, tab[-1]))
231 if (!ptrs) return ARG_LONG;
233 if (!strstr (string, "unsigned")) /* unsigned char * => ptr */
239 return ARG_POINTER; /* Pointer to some other type */
242 if (strstr (string, "double"))
245 if (strstr (string, "void") || strstr (string, "VOID"))
248 if (strstr (string, "struct") || strstr (string, "union"))
249 return ARG_STRUCT; /* Struct by value, ugh */
257 if (strstr (string, tab[-1]))
262 /* Unknown types passed by value can be 'grep'ed out for fixup later */
264 printf ("/* FIXME: By value type: Assumed 'int' */ typedef int %s;\n",
271 /*******************************************************************
272 * symbol_clean_string
274 * Make a type string more Wine-friendly. Logically const :-)
276 void symbol_clean_string (const char *string)
278 const char **tab = swap_after;
279 char *str = (char *)string;
281 #define SWAP(i, p, x, y) do { i = p; while ((i = str_replace (i, x, y))); } while(0)
286 SWAP (p, str, tab [0], tab [1]);
289 if (str [strlen (str) - 1] == ' ')
290 str [strlen (str) - 1] = '\0'; /* no trailing space */
293 memmove (str, str + 1, strlen (str)); /* No leading spaces */