Author: tkreuzer Date: Mon Nov 29 17:53:20 2010 New Revision: 49862
URL: http://svn.reactos.org/svn/reactos?rev=49862&view=rev Log: [SPEC2DEF] - add support for stubs generation - add support for "proper" stubs, with calling convention and parameter dump - handle -private - change invokation a bit [CMAKE] - remove the old VARIANT hack
Modified: branches/cmake-bringup/gcc.cmake branches/cmake-bringup/msc.cmake branches/cmake-bringup/tools/spec2def/spec2def.c
Modified: branches/cmake-bringup/gcc.cmake URL: http://svn.reactos.org/svn/reactos/branches/cmake-bringup/gcc.cmake?rev=4986... ============================================================================== --- branches/cmake-bringup/gcc.cmake [iso-8859-1] (original) +++ branches/cmake-bringup/gcc.cmake [iso-8859-1] Mon Nov 29 17:53:20 2010 @@ -201,7 +201,7 @@ get_filename_component(_file ${_spec_file} NAME_WE) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_file}.def - COMMAND native-spec2def --dll ${_dllname} ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} ${CMAKE_CURRENT_BINARY_DIR}/${_file}.def + COMMAND native-spec2def -n=${_dllname} -d=${CMAKE_CURRENT_BINARY_DIR}/${_file}.def ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file}) set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${_file}.def PROPERTIES GENERATED TRUE EXTERNAL_OBJECT TRUE)
Modified: branches/cmake-bringup/msc.cmake URL: http://svn.reactos.org/svn/reactos/branches/cmake-bringup/msc.cmake?rev=4986... ============================================================================== --- branches/cmake-bringup/msc.cmake [iso-8859-1] (original) +++ branches/cmake-bringup/msc.cmake [iso-8859-1] Mon Nov 29 17:53:20 2010 @@ -131,7 +131,7 @@
#idl files support set(IDL_COMPILER midl) -set(IDL_FLAGS /win32 /DIEnumVARIANT=IEnumXVARIANT) +set(IDL_FLAGS /win32) set(IDL_HEADER_ARG /h) #.h set(IDL_TYPELIB_ARG /tlb) #.tlb set(IDL_SERVER_ARG /sstub) #.c for stub server library @@ -146,13 +146,13 @@ # Generate the asm stub file add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/importlibs/lib${_name}_stubs.asm - COMMAND native-spec2def -s ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} ${CMAKE_BINARY_DIR}/importlibs/lib${_name}_stubs.asm + COMMAND native-spec2def -l=${CMAKE_BINARY_DIR}/importlibs/lib${_name}_stubs.asm ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file})
# Generate a the export def file add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/importlibs/lib${_name}_exp.def - COMMAND native-spec2def -n -r ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} ${CMAKE_BINARY_DIR}/importlibs/lib${_name}_exp.def + COMMAND native-spec2def -@ -r -d=${CMAKE_BINARY_DIR}/importlibs/lib${_name}_exp.def ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file})
# Assemble the file @@ -196,7 +196,7 @@ get_filename_component(_file ${_spec_file} NAME_WE) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_file}.def - COMMAND native-spec2def -n --dll ${_dllname} ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} ${CMAKE_CURRENT_BINARY_DIR}/${_file}.def + COMMAND native-spec2def -@ -n=${_dllname} -d=${CMAKE_CURRENT_BINARY_DIR}/${_file}.def ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file}) set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${_file}.def PROPERTIES GENERATED TRUE)
Modified: branches/cmake-bringup/tools/spec2def/spec2def.c URL: http://svn.reactos.org/svn/reactos/branches/cmake-bringup/tools/spec2def/spe... ============================================================================== --- branches/cmake-bringup/tools/spec2def/spec2def.c [iso-8859-1] (original) +++ branches/cmake-bringup/tools/spec2def/spec2def.c [iso-8859-1] Mon Nov 29 17:53:20 2010 @@ -12,14 +12,23 @@ int nCallingConvention; int nOrdinal; int nStackBytes; + int nArgCount; + int anArgs[30]; + unsigned int uFlags; } EXPORT;
-int (*OutputLine)(FILE *, EXPORT *); -void (*OutputHeader)(FILE *, char *); +typedef int (*PFNOUTLINE)(FILE *, EXPORT *); int no_decoration = 0; int no_redirections = 0; char *pszArchString = "i386"; char *pszArchString2; +char *pszDllName = 0; + +enum +{ + FL_PRIVATE = 1, + FL_STUB = 2, +};
enum { @@ -27,6 +36,16 @@ CC_CDECL, CC_FASTCALL, CC_EXTERN, + CC_STUB, +}; + +enum +{ + ARG_LONG, + ARG_PTR, + ARG_STR, + ARG_WSTR, + ARG_DBL };
char* astrCallingConventions[] = @@ -109,16 +128,100 @@ }
void -OutputHeader_stub(FILE *file, char *libname) +OutputHeader_stub(FILE *file) +{ + fprintf(file, "/* This file is autogenerated, do not edit. */\n\n" + "#include <stubs.h>\n\n"); +} + +int +OutputLine_stub(FILE *file, EXPORT *pexp) +{ + int i; + + if (pexp->nCallingConvention != CC_STUB && + (pexp->uFlags & FL_STUB) == 0) return 0; + + fprintf(file, "int "); + if (strcmp(pszArchString, "i386") == 0 && + pexp->nCallingConvention == CC_STDCALL) + { + fprintf(file, "__stdcall "); + } + + fprintf(file, "%.*s(", pexp->nNameLength, pexp->pcName); + + for (i = 0; i < pexp->nArgCount; i++) + { + if (i != 0) fprintf(file, ", "); + switch (pexp->anArgs[i]) + { + case ARG_LONG: fprintf(file, "long"); break; + case ARG_PTR: fprintf(file, "void*"); break; + case ARG_STR: fprintf(file, "char*"); break; + case ARG_WSTR: fprintf(file, "wchar_t*"); break; + case ARG_DBL: fprintf(file, "__int64"); break; + } + fprintf(file, " a%d", i); + } + fprintf(file, ")\n{\n\tDPRINT1("WARNING: calling stub %.*s(", + pexp->nNameLength, pexp->pcName); + + for (i = 0; i < pexp->nArgCount; i++) + { + if (i != 0) fprintf(file, ","); + switch (pexp->anArgs[i]) + { + case ARG_LONG: fprintf(file, "0x%%lx"); break; + case ARG_PTR: fprintf(file, "0x%%p"); break; + case ARG_STR: fprintf(file, "'%%s'"); break; + case ARG_WSTR: fprintf(file, "'%%ws'"); break; + case ARG_DBL: fprintf(file, "%%"PRix64""); break; + } + } + fprintf(file, ")\n", "); + + for (i = 0; i < pexp->nArgCount; i++) + { + if (i != 0) fprintf(file, ", "); + switch (pexp->anArgs[i]) + { + case ARG_LONG: fprintf(file, "(long)a%d", i); break; + case ARG_PTR: fprintf(file, "(void*)a%d", i); break; + case ARG_STR: fprintf(file, "(char*)a%d", i); break; + case ARG_WSTR: fprintf(file, "(wchar_t*)a%d", i); break; + case ARG_DBL: fprintf(file, "(__int64)a%d", i); break; + } + } + fprintf(file, ");\n"); + + if (pexp->nCallingConvention == CC_STUB) + { + fprintf(file, "\t__wine_spec_unimplemented_stub("%s", __FUNCTION__);\n", pszDllName); + } + + fprintf(file, "\treturn 0;\n}\n\n"); + + return 1; +} + +void +OutputHeader_asmstub(FILE *file, char *libname) { fprintf(file, "; File generated automatically, do not edit! \n\n" ".586\n.model flat\n.code\n"); }
int -OutputLine_stub(FILE *fileDest, EXPORT *pexp) -{ - if (pexp->nCallingConvention == CC_STDCALL) +OutputLine_asmstub(FILE *fileDest, EXPORT *pexp) +{ + /* Handle autoname */ + if (pexp->nNameLength == 1 && pexp->pcName[0] == '@') + { + fprintf(fileDest, "PUBLIC ordinal%d\nordinal%d: nop\n", + pexp->nOrdinal, pexp->nOrdinal); + } + else if (pexp->nCallingConvention == CC_STDCALL) { fprintf(fileDest, "PUBLIC _%.*s@%d\n_%.*s@%d: nop\n", pexp->nNameLength, pexp->pcName, pexp->nStackBytes, @@ -130,7 +233,8 @@ pexp->nNameLength, pexp->pcName, pexp->nStackBytes, pexp->nNameLength, pexp->pcName, pexp->nStackBytes); } - else if (pexp->nCallingConvention == CC_CDECL) + else if (pexp->nCallingConvention == CC_CDECL || + pexp->nCallingConvention == CC_STUB) { fprintf(fileDest, "PUBLIC _%.*s\n_%.*s: nop\n", pexp->nNameLength, pexp->pcName, @@ -157,63 +261,77 @@ }
int -OutputLine_def(FILE *fileDest, EXPORT *exp) +OutputLine_def(FILE *fileDest, EXPORT *pexp) { fprintf(fileDest, " "); - if (exp->nCallingConvention == CC_FASTCALL && !no_decoration) - { - fprintf(fileDest, "@"); - } - - fprintf(fileDest, "%.*s", exp->nNameLength, exp->pcName); - - if ((exp->nCallingConvention == CC_STDCALL || - exp->nCallingConvention == CC_FASTCALL) && !no_decoration) - { - fprintf(fileDest, "@%d", exp->nStackBytes); - } - - if (exp->pcRedirection && !no_redirections) + + /* Handle autoname */ + if (pexp->nNameLength == 1 && pexp->pcName[0] == '@') + { + fprintf(fileDest, "ordinal%d", pexp->nOrdinal); + } + else + { + if (pexp->nCallingConvention == CC_FASTCALL && !no_decoration) + { + fprintf(fileDest, "@"); + } + + fprintf(fileDest, "%.*s", pexp->nNameLength, pexp->pcName); + + if ((pexp->nCallingConvention == CC_STDCALL || + pexp->nCallingConvention == CC_FASTCALL) && !no_decoration) + { + fprintf(fileDest, "@%d", pexp->nStackBytes); + } + } + + if (pexp->pcRedirection && !no_redirections) { int bAddDecorations = 1;
fprintf(fileDest, "=");
/* No decorations, if switch was passed or this is an external */ - if (no_decoration || ScanToken(exp->pcRedirection, '.')) + if (no_decoration || ScanToken(pexp->pcRedirection, '.')) { bAddDecorations = 0; }
- if (exp->nCallingConvention == CC_FASTCALL && bAddDecorations) + if (pexp->nCallingConvention == CC_FASTCALL && bAddDecorations) { fprintf(fileDest, "@"); } - fprintf(fileDest, "%.*s", exp->nRedirectionLength, exp->pcRedirection); - if ((exp->nCallingConvention == CC_STDCALL || - exp->nCallingConvention == CC_FASTCALL) && bAddDecorations) - { - fprintf(fileDest, "@%d", exp->nStackBytes); - } - } - - if (exp->nOrdinal != -1) - { - fprintf(fileDest, " @%d", exp->nOrdinal); - } - - if (exp->nCallingConvention == CC_EXTERN) + fprintf(fileDest, "%.*s", pexp->nRedirectionLength, pexp->pcRedirection); + if ((pexp->nCallingConvention == CC_STDCALL || + pexp->nCallingConvention == CC_FASTCALL) && bAddDecorations) + { + fprintf(fileDest, "@%d", pexp->nStackBytes); + } + } + + if (pexp->nOrdinal != -1) + { + fprintf(fileDest, " @%d", pexp->nOrdinal); + } + + if (pexp->nCallingConvention == CC_EXTERN) { fprintf(fileDest, " DATA"); }
+ if (pexp->uFlags & FL_PRIVATE) + { + fprintf(fileDest, " PRIVATE"); + } + fprintf(fileDest, "\n");
return 1; }
int -ParseFile(char* pcStart, FILE *fileDest) +ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine) { char *pc, *pcLine; int nLine; @@ -228,6 +346,9 @@ { pc = pcLine;
+ exp.nArgCount = 0; + exp.uFlags = 0; + //fprintf(stderr, "info: line %d, token:'%d, %.20s'\n", // nLine, TokenLength(pcLine), pcLine);
@@ -264,8 +385,7 @@ { exp.nCallingConvention = CC_CDECL; } - else if (CompareToken(pc, "fastcall") || - CompareToken(pc, "FASTCALL")) + else if (CompareToken(pc, "fastcall")) { exp.nCallingConvention = CC_FASTCALL; } @@ -275,9 +395,7 @@ } else if (CompareToken(pc, "stub")) { - pc = NextToken(pc); - printf("warning: stub skipped: %.*s\n", TokenLength(pc), pc); - continue; + exp.nCallingConvention = CC_STUB; } else { @@ -323,10 +441,17 @@ { if (_stricmp(pszArchString, "i386") != 0) included = 0; } + else if (CompareToken(pc, "-private")) + { + exp.uFlags |= FL_PRIVATE; + } + else if (CompareToken(pc, "-stub")) + { + exp.uFlags |= FL_STUB; + } else if (CompareToken(pc, "-noname") || CompareToken(pc, "-norelay") || - CompareToken(pc, "-ret64") || - CompareToken(pc, "-private")) + CompareToken(pc, "-ret64")) { /* silently ignore these */ } @@ -351,7 +476,8 @@
/* Handle parameters */ exp.nStackBytes = 0; - if (exp.nCallingConvention != CC_EXTERN) + if (exp.nCallingConvention != CC_EXTERN && + exp.nCallingConvention != CC_STUB) { //fprintf(stderr, "info: options:'%.10s'\n", pc); /* Go to next token */ @@ -375,15 +501,26 @@ while (*pc >= '0') { if (CompareToken(pc, "long")) + { exp.nStackBytes += 4; + exp.anArgs[exp.nArgCount] = ARG_LONG; + } else if (CompareToken(pc, "double")) + { exp.nStackBytes += 8; + exp.anArgs[exp.nArgCount] = ARG_DBL; + } else if (CompareToken(pc, "ptr") || CompareToken(pc, "str") || CompareToken(pc, "wstr")) + { exp.nStackBytes += sizeof(void*); + exp.anArgs[exp.nArgCount] = ARG_PTR; // FIXME: handle strings + } else fprintf(stderr, "error: line %d, expected type, got: %.10s\n", nLine, pc); + + exp.nArgCount++;
/* Go to next parameter */ if (!(pc = NextToken(pc))) @@ -431,17 +568,20 @@ { printf("syntax: spec2pdef [<options> ...] <source file> <dest file>\n" "Possible options:\n" - " -d=<file> --dll=<file> names the dll\n" " -h --help prints this screen\n" - " -s --stubs generates an asm lib stub\n" - " -n --no-decoration removes @xx decorations from def file\n" - " --arch <arch> Set architecture to <arch>. (i386, x86_64, arm)\n"); + " -l=<file> generates an asm lib stub\n" + " -d=<file> generates a def file\n" + " -s=<file> generates a stub file\n" + " -n=<file> names the dll\n" + " -@ removes @xx decorations from def file\n" + " -r removes redirections from def file\n" + " -a=<arch> Set architecture to <arch>. (i386, x86_64, arm)\n"); }
int main(int argc, char *argv[]) { size_t nFileSize; - char *pszSource, *pszDllName = 0; + char *pszSource, *pszDefFileName = 0, *pszStubFileName = 0, *pszLibStubName = 0; char achDllName[40]; FILE *file; int result, i; @@ -452,10 +592,6 @@ return -1; }
- /* Default to def file */ - OutputLine = OutputLine_def; - OutputHeader = OutputHeader_def; - /* Read options */ for (i = 1; i < argc && *argv[i] == '-'; i++) { @@ -465,32 +601,33 @@ usage(); return 0; } - else if ((_stricmp(argv[i], "--stublib") == 0) || - (_stricmp(argv[i], "-s") == 0)) - { - OutputLine = OutputLine_stub; - OutputHeader = OutputHeader_stub; - } - else if ((_stricmp(argv[i], "--dll") == 0) || - (_stricmp(argv[i], "-d") == 0)) - { - pszDllName = argv[i + 1]; - i++; - } - else if ((_stricmp(argv[i], "--no-decoration") == 0) || - (_stricmp(argv[i], "-n") == 0)) + else if (argv[i][1] == 'd' && argv[i][2] == '=') + { + pszDefFileName = argv[i] + 3; + } + else if (argv[i][1] == 'l' && argv[i][2] == '=') + { + pszLibStubName = argv[i] + 3; + } + else if (argv[i][1] == 's' && argv[i][2] == '=') + { + pszStubFileName = argv[i] + 3; + } + else if (argv[i][1] == 'n' && argv[i][2] == '=') + { + pszDllName = argv[i] + 3; + } + else if ((_stricmp(argv[i], "-@") == 0)) { no_decoration = 1; } - else if ((_stricmp(argv[i], "--no-redirection") == 0) || - (_stricmp(argv[i], "-r") == 0)) + else if ((_stricmp(argv[i], "-r") == 0)) { no_redirections = 1; } - else if ((_stricmp(argv[i], "--arch") == 0)) - { - pszArchString = argv[i + 1]; - i++; + else if (argv[i][1] == 'a' && argv[i][1] == '=') + { + pszArchString = argv[i] + 3; } else { @@ -555,21 +692,52 @@ /* Zero terminate the source */ pszSource[nFileSize] = '\0';
- /* Open output file */ - file = fopen(argv[i + 1], "w"); - if (!file) - { - fprintf(stderr, "error: could not open output file %s ", argv[i + 1]); - return -5; - } - - OutputHeader(file, pszDllName); - - result = ParseFile(pszSource, file); - - if (OutputHeader == OutputHeader_stub) fprintf(file, "\nEND\n"); - - fclose(file); + if (pszDefFileName) + { + /* Open output file */ + file = fopen(pszDefFileName, "w"); + if (!file) + { + fprintf(stderr, "error: could not open output file %s ", argv[i + 1]); + return -5; + } + + OutputHeader_def(file, pszDllName); + result = ParseFile(pszSource, file, OutputLine_def); + fclose(file); + } + + if (pszStubFileName) + { + /* Open output file */ + file = fopen(pszStubFileName, "w"); + if (!file) + { + fprintf(stderr, "error: could not open output file %s ", argv[i + 1]); + return -5; + } + + OutputHeader_stub(file); + result = ParseFile(pszSource, file, OutputLine_stub); + fclose(file); + } + + if (pszLibStubName) + { + /* Open output file */ + file = fopen(pszLibStubName, "w"); + if (!file) + { + fprintf(stderr, "error: could not open output file %s ", argv[i + 1]); + return -5; + } + + OutputHeader_asmstub(file, pszDllName); + result = ParseFile(pszSource, file, OutputLine_asmstub); + fprintf(file, "\nEND\n"); + fclose(file); + } +
return result; }