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=498…
==============================================================================
--- 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=498…
==============================================================================
--- 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/sp…
==============================================================================
--- 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;
}