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
22 #include "wine/port.h"
27 /* Items that are swapped in arguments after the symbol structure
30 static const char * const swap_after
[] =
32 "\r", " ", /* Remove whitespace, normalise pointers and brackets */
41 "wchar_t", "WCHAR", /* Help with Unicode compiles */
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 * const 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 * const wide_chars
[] =
66 /* Items containing these substrings are assumed to be ASCII character
69 static const char * const ascii_strings
[] =
75 /* Items containing these substrings are assumed to be ASCII characters,
78 static const char * const 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 * const known_longs
[] =
88 "char", "CHAR", "float", "int", "INT", "short", "SHORT", "long", "LONG",
89 "WCHAR", "BOOL", "bool", "INT16", "WORD", "DWORD", NULL
92 void symbol_init(parsed_symbol
* sym
, const char* name
)
94 memset(sym
, 0, sizeof(parsed_symbol
));
95 sym
->symbol
= strdup(name
);
98 /*******************************************************************
101 * Free the memory used by a symbol and initialise it
103 void symbol_clear(parsed_symbol
*sym
)
108 assert (sym
->symbol
);
111 free (sym
->return_text
);
112 free (sym
->function_name
);
114 for (i
= sym
->argc
- 1; i
>= 0; i
--)
116 free (sym
->arg_text
[i
]);
117 free (sym
->arg_name
[i
]);
119 memset (sym
, 0, sizeof (parsed_symbol
));
123 /*******************************************************************
126 * Check if a symbol is a valid C identifier
128 BOOL
symbol_is_valid_c(const parsed_symbol
*sym
)
133 assert (sym
->symbol
);
139 if (!isalnum (*name
) && *name
!= '_')
147 /*******************************************************************
148 * symbol_get_call_convention
150 * Return the calling convention of a symbol
152 const char *symbol_get_call_convention(const parsed_symbol
*sym
)
154 int call
= sym
->flags
? sym
->flags
: CALLING_CONVENTION
;
157 assert (sym
->symbol
);
159 if (call
& SYM_CDECL
)
165 /*******************************************************************
166 * symbol_get_spec_type
168 * Get the .spec file text for a symbol's argument
170 const char *symbol_get_spec_type (const parsed_symbol
*sym
, size_t arg
)
172 assert (arg
< sym
->argc
);
173 switch (sym
->arg_type
[arg
])
175 case ARG_STRING
: return "str";
176 case ARG_WIDE_STRING
: return "wstr";
177 case ARG_POINTER
: return "ptr";
178 case ARG_DOUBLE
: return "double";
181 case ARG_LONG
: return "long";
188 /*******************************************************************
191 * Get the ARG_ constant for a type string
193 int symbol_get_type (const char *string
)
195 const char *iter
= string
;
196 const char * const *tab
;
199 while (*iter
&& isspace(*iter
))
201 if (*iter
== 'P' || *iter
== 'H')
202 ptrs
++; /* Win32 type pointer */
207 if (*iter
== '*' || (*iter
== 'L' && iter
[1] == 'P')
208 || (*iter
== '[' && iter
[1] == ']'))
218 if (strstr (string
, tab
[-1]))
220 if (ptrs
< 2) return ARG_WIDE_STRING
;
221 else return ARG_POINTER
;
225 if (strstr (string
, tab
[-1]))
227 if (!ptrs
) return ARG_LONG
;
228 else return ARG_WIDE_STRING
;
232 if (strstr (string
, tab
[-1]))
234 if (ptrs
< 2) return ARG_STRING
;
235 else return ARG_POINTER
;
239 if (strstr (string
, tab
[-1]))
241 if (!ptrs
) return ARG_LONG
;
243 if (!strstr (string
, "unsigned")) /* unsigned char * => ptr */
249 return ARG_POINTER
; /* Pointer to some other type */
252 if (strstr (string
, "double"))
255 if (strstr (string
, "float") || strstr (string
, "FLOAT"))
258 if (strstr (string
, "void") || strstr (string
, "VOID"))
261 if (strstr (string
, "struct") || strstr (string
, "union"))
262 return ARG_STRUCT
; /* Struct by value, ugh */
270 if (strstr (string
, tab
[-1]))
275 /* Unknown types passed by value can be 'grep'ed out for fixup later */
277 printf ("/* FIXME: By value type: Assumed 'int' */ typedef int %s;\n",
284 /*******************************************************************
285 * symbol_clean_string
287 * Make a type string more Wine-friendly. Logically const :-)
289 void symbol_clean_string (char *str
)
291 const char * const *tab
= swap_after
;
293 #define SWAP(i, p, x, y) do { i = p; while ((i = str_replace (i, x, y))); } while(0)
298 SWAP (p
, str
, tab
[0], tab
[1]);
301 if (str
[strlen (str
) - 1] == ' ')
302 str
[strlen (str
) - 1] = '\0'; /* no trailing space */
305 memmove (str
, str
+ 1, strlen (str
)); /* No leading spaces */