diff options
Diffstat (limited to 'tools/moddesc/moddesc.c')
-rw-r--r-- | tools/moddesc/moddesc.c | 519 |
1 files changed, 519 insertions, 0 deletions
diff --git a/tools/moddesc/moddesc.c b/tools/moddesc/moddesc.c new file mode 100644 index 0000000..7d56a1b --- /dev/null +++ b/tools/moddesc/moddesc.c @@ -0,0 +1,519 @@ +/* + * Copyright © 2006-2011 SplinterGU (Fenix/Bennugd) + * + * This file is part of Bennu - Game Development + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ + +#include <loadlib.h> /* Must be fist include */ + +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <stdlib.h> +#include <stdarg.h> + +#include <bgddl.h> +#include <dlvaracc.h> +#include <files_st.h> + +/* ----------------------------------------------------------------- */ + +int onlyfenixexport = 0; +int interactive = 1; +int all = 1, functions = 0, locals = 0, globals = 0, types = 0, constants = 0, hooks_callbacks = 0, dependencies = 0, locals_dep = 0, globals_dep = 0; + +/* ----------------------------------------------------------------- */ + +void describe_type( int type ) +{ + switch ( type ) + { + case TYPE_DWORD: + printf( "DWORD" ) ; + break ; + case TYPE_INT: + printf( "INT" ) ; + break ; + case TYPE_SHORT: + printf( "SHORT" ) ; + break ; + case TYPE_WORD: + printf( "WORD" ) ; + break ; + case TYPE_BYTE: + printf( "BYTE" ) ; + break ; + case TYPE_SBYTE: + printf( "SIGNED BYTE" ) ; + break ; + case TYPE_CHAR: + printf( "CHAR" ) ; + break ; + case TYPE_STRING: + printf( "STRING" ) ; + break ; + case TYPE_FLOAT: + printf( "FLOAT" ) ; + break ; + case TYPE_POINTER: + printf( "POINTER" ) ; + break ; + case TYPE_UNDEFINED: + printf( "UNDEFINED" ); + break ; + } +} + +/* ----------------------------------------------------------------- */ + +void * fnc_import( const char * name ) +{ + if ( !onlyfenixexport ) printf( "Import %s\n", name ); + return NULL; +} + +/* ----------------------------------------------------------------- */ + +int describe_func( char * name, char * paramtypes, int type, void * func ) +{ + int param; + if ( func ) printf( "Export " ); + describe_type( type ); + printf( " %s(", name ); + param = 0; + while ( paramtypes && paramtypes[param] ) + { + switch ( paramtypes[param] ) + { + case 'I': + printf( "INTEGER" ); + break; + + case 'B': + printf( "BYTE" ); + break; + + case 'W': + printf( "WORD" ); + break; + + case 'S': + printf( "STRING" ); + break; + + case 'P': + printf( "POINTER" ); + break; + + case 'F': + printf( "FLOAT" ); + break; + + case 'V': + printf( "VARIABLE" ); + param += 2; + break; + + default: + printf( "[PARAM ERROR]" ) ; + } + + if ( paramtypes[param+1] ) printf( ", " ); + param++; + } + printf( ")\n" ); + + return 0 ; +} + +/* ----------------------------------------------------------------- */ + +static char * modules_exts[] = +{ + ".dll", + ".dylib", + ".so", + NULL +} ; + +/* ----------------------------------------------------------------- */ + +void describe_module( char *filename ) +{ + void * library = NULL; + + char ** types_def = NULL; + char ** globals_def = NULL; + char ** locals_def = NULL; + DLCONSTANT * constants_def = NULL; + DLSYSFUNCS * functions_exports = NULL; + char ** modules_dependency = NULL; + + DLVARFIXUP * globals_fixup = NULL; + DLVARFIXUP * locals_fixup = NULL; + HOOK * handler_hooks = NULL; + + void ( * RegisterFunctions )( void *( * )( const char * ), int ( * )( char *, char *, int, void * ) ) = NULL ; + int misc = 0; + + char soname[1024]; + char * ptr; + char ** pex; + +#if defined( WIN32 ) +#define DLLEXT ".dll" +#elif defined(TARGET_MAC) +#define DLLEXT ".dylib" +#else +#define DLLEXT ".so" +#endif + + strncpy ( soname, filename, sizeof ( soname ) ); + + for ( ptr = soname; *ptr; ptr++ ) + { + *ptr = tolower( *ptr ); + } + + pex = modules_exts; + while ( pex && * pex ) + { + int nlen = strlen ( soname ); + int elen = strlen ( *pex ); + if ( nlen > elen && strcmp( &soname[nlen - elen], *pex ) == 0 ) + { + soname[nlen - elen] = '\0' ; + pex = modules_exts; + } + else + { + pex++; + } + } + + strcat( soname, DLLEXT ); + + filename = soname; + + library = dlibopen( filename ) ; + if ( !library ) + { + printf( "ERROR: %s library not found\n", filename ) ; + return; + } + + printf( "Module name: %s\n\n", filename ); + + if ( all || constants ) + { + constants_def = ( DLCONSTANT * ) _dlibaddr( library, "constants_def" ) ; + if ( constants_def ) + { + printf( "Constants:\n\n" ); fflush( stdout ); + while ( constants_def->name ) + { + describe_type( constants_def->type ); fflush( stdout ); + printf( " %s = %d\n", constants_def->name, constants_def->code ); fflush( stdout ); + constants_def++ ; + } + printf( "\n\n" ); + } + } + + if ( all || types ) + { + types_def = ( char ** ) _dlibaddr( library, "types_def" ) ; + if ( types_def && *types_def ) + { + printf( "Types:\n\n%s\n\n", *types_def ); + } + } + + if ( all || globals ) + { + globals_def = ( char ** ) _dlibaddr( library, "globals_def" ) ; + if ( globals_def && *globals_def ) + { + printf( "Globals:\n\n%s\n\n", *globals_def ); + } + } + + if ( all || locals ) + { + locals_def = ( char ** ) _dlibaddr( library, "locals_def" ) ; + if ( locals_def && *locals_def ) + { + printf( "Locals:\n\n%s\n\n", *locals_def ); + } + } + + if ( all || functions ) + { + functions_exports = ( DLSYSFUNCS * ) _dlibaddr( library, "functions_exports" ) ; + if ( functions_exports ) + { + printf( "Functions:\n\n" ); + while ( functions_exports->name ) + { + describe_func( functions_exports->name, functions_exports->paramtypes, functions_exports->type, NULL ); + functions_exports++; + } + printf( "\n\n" ); + } + } + + if ( all || dependencies ) + { + modules_dependency = ( char ** ) _dlibaddr( library, "modules_dependency" ) ; + if ( modules_dependency ) + { + printf( "Module Dependency:\n\n" ); + while ( *modules_dependency ) + { + printf( "%s\n", *modules_dependency ); + modules_dependency++; + } + printf( "\n\n" ); + } + } + + if ( all || globals_dep ) + { + globals_fixup = ( DLVARFIXUP * ) _dlibaddr( library, "globals_fixup" ) ; + if ( globals_fixup ) + { + printf( "Globals vars dependency:\n\n" ); + while ( globals_fixup->var ) + { + printf( "%s\n", globals_fixup->var ); + globals_fixup++; + } + printf( "\n\n" ); + } + } + + if ( all || locals_dep ) + { + locals_fixup = ( DLVARFIXUP * ) _dlibaddr( library, "locals_fixup" ) ; + if ( locals_fixup ) + { + printf( "Locals vars dependency:\n\n" ); + while ( locals_fixup->var ) + { + printf( "%s\n", locals_fixup->var ); + locals_fixup++; + } + printf( "\n\n" ); + } + } + + if ( all || hooks_callbacks ) + { + #define CallbackHeaders() if (!misc) { misc = 1; printf ("Internals callbacks:\n\n"); } + + if ( _dlibaddr( library, "module_initialize" ) ) + { + CallbackHeaders(); printf( "module_initialize\n" ); + } + if ( _dlibaddr( library, "module_finalize" ) ) + { + CallbackHeaders(); printf( "module_finalize\n" ); + } + if ( _dlibaddr( library, "instance_create_hook" ) ) + { + CallbackHeaders(); printf( "instance_create_hook\n" ); + } + if ( _dlibaddr( library, "instance_destroy_hook" ) ) + { + CallbackHeaders(); printf( "instance_destroy_hook\n" ); + } + if ( _dlibaddr( library, "instance_pre_execute_hook" ) ) + { + CallbackHeaders(); printf( "instance_pre_execute_hook\n" ); + } + if ( _dlibaddr( library, "instance_pos_execute_hook" ) ) + { + CallbackHeaders(); printf( "instance_pos_execute_hook\n" ); + } + if ( _dlibaddr( library, "process_exec_hook" ) ) + { + CallbackHeaders(); printf( "process_exec_hook\n" ); + } + + if ( misc ) printf( "\n\n" ); + + handler_hooks = ( HOOK * ) _dlibaddr( library, "handler_hooks" ) ; + if ( handler_hooks ) + { + int i = 0; + printf( "Hooks at priorities: " ); + while ( handler_hooks->hook ) + { + printf( "%d", handler_hooks->prio ); + handler_hooks++; + if ( handler_hooks->hook ) printf( ", " ); + i++; + } + printf( "\n\n" ); + } + } + + if ( all ) + { + RegisterFunctions = _dlibaddr( library, "RegisterFunctions" ) ; + if ( RegisterFunctions ) + { + printf( "Fenix support:\n\n" ); + ( *RegisterFunctions )( fnc_import, describe_func ) ; + } + } +} + +/* ----------------------------------------------------------------- */ + +void help( char *argv[] ) +{ + printf( "Usage: %s [options] modulename \n" + "\n" + " -e On fenix, only report exported functions\n" + " -F only report funcions\n" + " -L only report locals\n" + " -G only report globals\n" + " -T only report types\n" + " -C only report constants\n" + " -H only report hooks/callbacks\n" + " -D only report modules/libs dependencies\n" + " -l only report locals dependencies\n" + " -g only report globals dependencies\n" + " -h This help\n" + "\n", argv[0] ) ; + +#if _WIN32 + if ( interactive ) + { + printf( "\nPress any key to continue...\n" ); + fflush( stdout ); + char a; scanf( "%c", &a ) ; + } +#endif +} + +/* ----------------------------------------------------------------- */ + +int main( int argc, char *argv[] ) +{ + int i = 1; + char * modname = NULL; + + printf( "Module Describe v1.1 (Build: %s %s)\n" + "Copyright (C) 2009 SplinterGU\n" + "This utility comes with ABSOLUTELY NO WARRANTY.\n" + "%s -h for details\n\n", __DATE__, __TIME__, argv[0] ) ; + + if ( argc <= 1 ) + { + help( argv ) ; + exit( 0 ) ; + } + + while ( i < argc ) + { + if ( argv[i][0] == '-' ) + { + switch ( argv[i][1] ) + { + case 'e': + onlyfenixexport = 1 ; + break; + + case 'F': + all = 0; + functions = 1; + break; + + case 'L': + all = 0; + locals = 1; + break; + + case 'G': + all = 0; + globals = 1; + break; + + case 'T': + all = 0; + types = 1; + break; + + case 'C': + all = 0; + constants = 1; + break; + + case 'H': + all = 0; + hooks_callbacks = 1; + break; + + case 'D': + all = 0; + dependencies = 1; + break; + + case 'l': + all = 0; + locals_dep = 1; + break; + + case 'g': + all = 0; + globals_dep = 1; + break; + + default: + case 'h': + help( argv ) ; + exit( 0 ); + break; + } + } + else + { + modname = argv[i]; + } + i++; + } + + if ( !modname ) + { + help( argv ) ; + exit( 0 ) ; + } + + describe_module( modname ); + + exit( 0 ); +} + +/* ----------------------------------------------------------------- */ |