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
76 /*******************************************************************
79 * Free the memory used by a symbol and initialise it
81 void symbol_clear(parsed_symbol
*sym
)
91 free (sym
->return_text
);
93 if (sym
->function_name
)
94 free (sym
->function_name
);
96 for (i
= sym
->argc
- 1; i
>= 0; i
--)
98 if (sym
->arg_text
[i
])
99 free (sym
->arg_text
[i
]);
100 if (sym
->arg_name
[i
])
101 free (sym
->arg_name
[i
]);
103 memset (sym
, 0, sizeof (parsed_symbol
));
107 /*******************************************************************
110 * Check if a symbol is a valid C identifier
112 int symbol_is_valid_c(const parsed_symbol
*sym
)
117 assert (sym
->symbol
);
123 if (!isalnum (*name
) && *name
!= '_')
131 /*******************************************************************
132 * symbol_get_call_convention
134 * Return the calling convention of a symbol
136 const char *symbol_get_call_convention(const parsed_symbol
*sym
)
138 int call
= sym
->flags
? sym
->flags
: CALLING_CONVENTION
;
141 assert (sym
->symbol
);
143 if (call
& SYM_CDECL
)
149 /*******************************************************************
150 * symbol_get_spec_type
152 * Get the .spec file text for a symbols argument
154 const char *symbol_get_spec_type (const parsed_symbol
*sym
, size_t arg
)
156 assert (arg
< sym
->argc
);
157 switch (sym
->arg_type
[arg
])
159 case ARG_STRING
: return "str";
160 case ARG_WIDE_STRING
: return "wstr";
161 case ARG_POINTER
: return "ptr";
162 case ARG_DOUBLE
: return "double";
165 case ARG_LONG
: return "long";
172 /*******************************************************************
175 * Get the ARG_ constant for a type string
177 int symbol_get_type (const char *string
)
179 const char *iter
= string
;
183 while (*iter
&& isspace(*iter
))
185 if (*iter
== 'P' || *iter
== 'H')
186 ptrs
++; /* Win32 type pointer */
191 if (*iter
== '*' || (*iter
== 'L' && iter
[1] == 'P')
192 || (*iter
== '[' && iter
[1] == ']'))
202 if (strstr (string
, tab
[-1]))
204 if (ptrs
< 2) return ARG_WIDE_STRING
;
205 else return ARG_POINTER
;
209 if (strstr (string
, tab
[-1]))
211 if (!ptrs
) return ARG_LONG
;
212 else return ARG_WIDE_STRING
;
216 if (strstr (string
, tab
[-1]))
218 if (ptrs
< 2) return ARG_STRING
;
219 else return ARG_POINTER
;
223 if (strstr (string
, tab
[-1]))
225 if (!ptrs
) return ARG_LONG
;
227 if (!strstr (string
, "unsigned")) /* unsigned char * => ptr */
233 return ARG_POINTER
; /* Pointer to some other type */
236 if (strstr (string
, "double"))
239 if (strstr (string
, "void") || strstr (string
, "VOID"))
242 if (strstr (string
, "struct") || strstr (string
, "union"))
243 return ARG_STRUCT
; /* Struct by value, ugh */
251 if (strstr (string
, tab
[-1]))
256 /* Unknown types passed by value can be 'grep'ed out for fixup later */
258 printf ("/* FIXME: By value type: Assumed 'int' */ typedef int %s;\n",
265 /*******************************************************************
266 * symbol_clean_string
268 * Make a type string more Wine-friendly. Logically const :-)
270 void symbol_clean_string (const char *string
)
272 const char **tab
= swap_after
;
273 char *str
= (char *)string
;
275 #define SWAP(i, p, x, y) do { i = p; while ((i = str_replace (i, x, y))); } while(0)
280 SWAP (p
, str
, tab
[0], tab
[1]);
283 if (str
[strlen (str
) - 1] == ' ')
284 str
[strlen (str
) - 1] = '\0'; /* no trailing space */
287 memmove (str
, str
+ 1, strlen (str
)); /* No leading spaces */