123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- /*
- * Symbol functions
- *
- * Copyright 2000 Jon Griffiths
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
- #include "config.h"
- #include "winedump.h"
- /* Items that are swapped in arguments after the symbol structure
- * has been populated
- */
- static const char * const swap_after[] =
- {
- "\r", " ", /* Remove whitespace, normalise pointers and brackets */
- "\t", " ",
- " ", " ",
- " * ", " *",
- "* *", "**",
- "* ", "*",
- " ,", ",",
- "( ", "(",
- " )", ")",
- "wchar_t", "WCHAR", /* Help with Unicode compiles */
- "wctype_t", "WCHAR",
- "wint_t", "WCHAR",
- NULL, NULL
- };
- /* Items containing these substrings are assumed to be wide character
- * strings, unless they contain more that one '*'. A preceding 'LP'
- * counts as a '*', so 'LPWCSTR *' is a pointer, not a string
- */
- static const char * const wide_strings[] =
- {
- "WSTR", "WCSTR", NULL
- };
- /* Items containing these substrings are assumed to be wide characters,
- * unless they contain one '*'. A preceding 'LP' counts as a '*',
- * so 'WCHAR *' is string, while 'LPWCHAR *' is a pointer
- */
- static const char * const wide_chars[] =
- {
- "WCHAR", NULL
- };
- /* Items containing these substrings are assumed to be ASCII character
- * strings, as above
- */
- static const char * const ascii_strings[] =
- {
- "STR", "CSTR", NULL
- };
- /* Items containing these substrings are assumed to be ASCII characters,
- * as above
- */
- static const char * const ascii_chars[] =
- {
- "CHAR", "char", NULL
- };
- /* Any type other than the following will produce a FIXME warning with -v
- * when mapped to a long, to allow fixups
- */
- static const char * const known_longs[] =
- {
- "char", "CHAR", "float", "int", "INT", "short", "SHORT", "long", "LONG",
- "WCHAR", "BOOL", "bool", "INT16", "WORD", "DWORD", NULL
- };
- void symbol_init(parsed_symbol* sym, const char* name)
- {
- memset(sym, 0, sizeof(parsed_symbol));
- sym->symbol = xstrdup(name);
- }
- /*******************************************************************
- * symbol_clear
- *
- * Free the memory used by a symbol and initialise it
- */
- void symbol_clear(parsed_symbol *sym)
- {
- int i;
- assert (sym);
- assert (sym->symbol);
- free (sym->symbol);
- free (sym->return_text);
- free (sym->function_name);
- for (i = sym->argc - 1; i >= 0; i--)
- {
- free (sym->arg_text [i]);
- free (sym->arg_name [i]);
- }
- memset (sym, 0, sizeof (parsed_symbol));
- }
- /*******************************************************************
- * symbol_is_valid_c
- *
- * Check if a symbol is a valid C identifier
- */
- BOOL symbol_is_valid_c(const parsed_symbol *sym)
- {
- char *name;
- assert (sym);
- assert (sym->symbol);
- name = sym->symbol;
- while (*name)
- {
- if (!isalnum (*name) && *name != '_')
- return FALSE;
- name++;
- }
- return TRUE;
- }
- /*******************************************************************
- * symbol_get_call_convention
- *
- * Return the calling convention of a symbol
- */
- const char *symbol_get_call_convention(const parsed_symbol *sym)
- {
- int call = sym->flags ? sym->flags : CALLING_CONVENTION;
- assert (sym);
- assert (sym->symbol);
- if (call & SYM_CDECL)
- return "cdecl";
- return "stdcall";
- }
- /*******************************************************************
- * symbol_get_spec_type
- *
- * Get the .spec file text for a symbol's argument
- */
- const char *symbol_get_spec_type (const parsed_symbol *sym, size_t arg)
- {
- assert (arg < sym->argc);
- switch (sym->arg_type [arg])
- {
- case ARG_STRING: return "str";
- case ARG_WIDE_STRING: return "wstr";
- case ARG_POINTER: return "ptr";
- case ARG_DOUBLE: return "double";
- case ARG_STRUCT:
- case ARG_FLOAT:
- case ARG_LONG: return "long";
- }
- assert (0);
- return NULL;
- }
- /*******************************************************************
- * symbol_get_type
- *
- * Get the ARG_ constant for a type string
- */
- int symbol_get_type (const char *string)
- {
- const char *iter = string;
- const char * const *tab;
- int ptrs = 0;
- while (*iter && isspace(*iter))
- iter++;
- if (*iter == 'P' || *iter == 'H')
- ptrs++; /* Win32 type pointer */
- iter = string;
- while (*iter)
- {
- if (*iter == '*' || (*iter == 'L' && iter[1] == 'P')
- || (*iter == '[' && iter[1] == ']'))
- ptrs++;
- if (ptrs > 1)
- return ARG_POINTER;
- iter++;
- }
- /* 0 or 1 pointer */
- tab = wide_strings;
- while (*tab++)
- if (strstr (string, tab[-1]))
- {
- if (ptrs < 2) return ARG_WIDE_STRING;
- else return ARG_POINTER;
- }
- tab = wide_chars;
- while (*tab++)
- if (strstr (string, tab[-1]))
- {
- if (!ptrs) return ARG_LONG;
- else return ARG_WIDE_STRING;
- }
- tab = ascii_strings;
- while (*tab++)
- if (strstr (string, tab[-1]))
- {
- if (ptrs < 2) return ARG_STRING;
- else return ARG_POINTER;
- }
- tab = ascii_chars;
- while (*tab++)
- if (strstr (string, tab[-1]))
- {
- if (!ptrs) return ARG_LONG;
- else {
- if (!strstr (string, "unsigned")) /* unsigned char * => ptr */
- return ARG_STRING;
- }
- }
- if (ptrs)
- return ARG_POINTER; /* Pointer to some other type */
- /* No pointers */
- if (strstr (string, "double"))
- return ARG_DOUBLE;
- if (strstr (string, "float") || strstr (string, "FLOAT"))
- return ARG_FLOAT;
- if (strstr (string, "void") || strstr (string, "VOID"))
- return ARG_VOID;
- if (strstr (string, "struct") || strstr (string, "union"))
- return ARG_STRUCT; /* Struct by value, ugh */
- if (VERBOSE)
- {
- BOOL known = FALSE;
- tab = known_longs;
- while (*tab++)
- if (strstr (string, tab[-1]))
- {
- known = TRUE;
- break;
- }
- /* Unknown types passed by value can be 'grep'ed out for fixup later */
- if (!known)
- printf ("/* FIXME: By value type: Assumed 'int' */ typedef int %s;\n",
- string);
- }
- return ARG_LONG;
- }
- /*******************************************************************
- * symbol_clean_string
- *
- * Make a type string more Wine-friendly. Logically const :-)
- */
- void symbol_clean_string (char *str)
- {
- const char * const *tab = swap_after;
- #define SWAP(i, p, x, y) do { i = p; while ((i = str_replace (i, x, y))); } while(0)
- while (tab [0])
- {
- char *p;
- SWAP (p, str, tab [0], tab [1]);
- tab += 2;
- }
- if (str [strlen (str) - 1] == ' ')
- str [strlen (str) - 1] = '\0'; /* no trailing space */
- if (*str == ' ')
- memmove (str, str + 1, strlen (str)); /* No leading spaces */
- }
|