[SPEC2DEF]

Rewrite the code for generating def files. Remove useless switches. Seperate code for GCC and MSVC for easier maintainability. Make use of the new dlltool feature implemented by Kai Tietz, that allows to specify the name of an import/export. It is now possible to both export stdcall and fastcall decorated symbols as well as import from them.

svn path=/trunk/; revision=61024
This commit is contained in:
Timo Kreuzer 2013-11-17 22:11:04 +00:00
parent 35897825f8
commit 6c26b58f06
3 changed files with 208 additions and 95 deletions

View file

@ -96,6 +96,7 @@ endif()
if(ARCH STREQUAL "i386") if(ARCH STREQUAL "i386")
add_compile_flags("-mpreferred-stack-boundary=3 -fno-set-stack-executable -fno-optimize-sibling-calls -fno-omit-frame-pointer") add_compile_flags("-mpreferred-stack-boundary=3 -fno-set-stack-executable -fno-optimize-sibling-calls -fno-omit-frame-pointer")
# FIXME: this doesn't work. CMAKE_BUILD_TYPE is always "Debug"
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
add_compile_flags("-momit-leaf-frame-pointer") add_compile_flags("-momit-leaf-frame-pointer")
endif() endif()
@ -241,7 +242,7 @@ function(generate_import_lib _libname _dllname _spec_file)
# generate the def for the import lib # generate the def for the import lib
add_custom_command( add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def
COMMAND native-spec2def -n=${_dllname} -a=${ARCH2} -d=${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} COMMAND native-spec2def -n=${_dllname} -a=${ARCH2} --implib -d=${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} native-spec2def) DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} native-spec2def)
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def PROPERTIES EXTERNAL_OBJECT TRUE) set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def PROPERTIES EXTERNAL_OBJECT TRUE)

View file

@ -176,7 +176,7 @@ function(generate_import_lib _libname _dllname _spec_file)
# Generate the asm stub file and the def file for import library # Generate the asm stub file and the def file for import library
add_custom_command( add_custom_command(
OUTPUT ${_asm_stubs_file} ${_def_file} OUTPUT ${_asm_stubs_file} ${_def_file}
COMMAND native-spec2def --ms --kill-at -a=${SPEC2DEF_ARCH} --implib -n=${_dllname} -d=${_def_file} -l=${_asm_stubs_file} ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} COMMAND native-spec2def --ms -a=${SPEC2DEF_ARCH} --implib -n=${_dllname} -d=${_def_file} -l=${_asm_stubs_file} ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} native-spec2def) DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} native-spec2def)
if(MSVC_IDE) if(MSVC_IDE)
@ -233,7 +233,7 @@ function(spec2def _dllname _spec_file)
#generate def for the DLL and C stubs file #generate def for the DLL and C stubs file
add_custom_command( add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_file}.def ${CMAKE_CURRENT_BINARY_DIR}/${_file}_stubs.c OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_file}.def ${CMAKE_CURRENT_BINARY_DIR}/${_file}_stubs.c
COMMAND native-spec2def --ms --kill-at -a=${SPEC2DEF_ARCH} -n=${_dllname} -d=${CMAKE_CURRENT_BINARY_DIR}/${_file}.def -s=${CMAKE_CURRENT_BINARY_DIR}/${_file}_stubs.c ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} COMMAND native-spec2def --ms -a=${SPEC2DEF_ARCH} -n=${_dllname} -d=${CMAKE_CURRENT_BINARY_DIR}/${_file}.def -s=${CMAKE_CURRENT_BINARY_DIR}/${_file}_stubs.c ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} native-spec2def) DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} native-spec2def)
if(__add_importlib) if(__add_importlib)

View file

@ -7,12 +7,16 @@
#define strcasecmp _stricmp #define strcasecmp _stricmp
#endif #endif
typedef struct _STRING
{
const char *buf;
int len;
} STRING, *PSTRING;
typedef struct typedef struct
{ {
char *pcName; STRING strName;
int nNameLength; STRING strTarget;
char *pcRedirection;
int nRedirectionLength;
int nCallingConvention; int nCallingConvention;
int nOrdinal; int nOrdinal;
int nStackBytes; int nStackBytes;
@ -32,15 +36,15 @@ enum _ARCH
}; };
typedef int (*PFNOUTLINE)(FILE *, EXPORT *); typedef int (*PFNOUTLINE)(FILE *, EXPORT *);
int gbKillAt = 0;
int gbMSComp = 0; int gbMSComp = 0;
int gbImportLib = 0; int gbImportLib = 0;
int no_redirections = 0;
int giArch = ARCH_X86; int giArch = ARCH_X86;
char *pszArchString = "i386"; char *pszArchString = "i386";
char *pszArchString2; char *pszArchString2;
char *pszDllName = 0; char *pszDllName = 0;
char *gpszUnderscore = ""; char *gpszUnderscore = "";
int gbDebug;
#define DbgPrint(...) (!gbDebug || fprintf(stderr, __VA_ARGS__))
enum enum
{ {
@ -101,12 +105,13 @@ CompareToken(const char *token, const char *comparand)
return 1; return 1;
} }
int const char *
ScanToken(const char *token, char chr) ScanToken(const char *token, char chr)
{ {
while (!IsSeparator(*token)) while (!IsSeparator(*token))
{ {
if (*token++ == chr) return 1; if (*token == chr) return token;
token++;
} }
return 0; return 0;
} }
@ -174,13 +179,13 @@ OutputLine_stub(FILE *file, EXPORT *pexp)
} }
/* Check for C++ */ /* Check for C++ */
if (pexp->pcName[0] == '?') if (pexp->strName.buf[0] == '?')
{ {
fprintf(file, "stub_function%d(", pexp->nNumber); fprintf(file, "stub_function%d(", pexp->nNumber);
} }
else else
{ {
fprintf(file, "%.*s(", pexp->nNameLength, pexp->pcName); fprintf(file, "%.*s(", pexp->strName.len, pexp->strName.buf);
} }
for (i = 0; i < pexp->nArgCount; i++) for (i = 0; i < pexp->nArgCount; i++)
@ -200,7 +205,7 @@ OutputLine_stub(FILE *file, EXPORT *pexp)
fprintf(file, " a%d", i); fprintf(file, " a%d", i);
} }
fprintf(file, ")\n{\n\tDPRINT1(\"WARNING: calling stub %.*s(", fprintf(file, ")\n{\n\tDPRINT1(\"WARNING: calling stub %.*s(",
pexp->nNameLength, pexp->pcName); pexp->strName.len, pexp->strName.buf);
for (i = 0; i < pexp->nArgCount; i++) for (i = 0; i < pexp->nArgCount; i++)
{ {
@ -261,7 +266,7 @@ int
OutputLine_asmstub(FILE *fileDest, EXPORT *pexp) OutputLine_asmstub(FILE *fileDest, EXPORT *pexp)
{ {
/* Handle autoname */ /* Handle autoname */
if (pexp->nNameLength == 1 && pexp->pcName[0] == '@') if (pexp->strName.len == 1 && pexp->strName.buf[0] == '@')
{ {
fprintf(fileDest, "PUBLIC %sordinal%d\n%sordinal%d: nop\n", fprintf(fileDest, "PUBLIC %sordinal%d\n%sordinal%d: nop\n",
gpszUnderscore, pexp->nOrdinal, gpszUnderscore, pexp->nOrdinal); gpszUnderscore, pexp->nOrdinal, gpszUnderscore, pexp->nOrdinal);
@ -269,33 +274,33 @@ OutputLine_asmstub(FILE *fileDest, EXPORT *pexp)
else if (giArch != ARCH_X86) else if (giArch != ARCH_X86)
{ {
fprintf(fileDest, "PUBLIC _stub_%.*s\n_stub_%.*s: nop\n", fprintf(fileDest, "PUBLIC _stub_%.*s\n_stub_%.*s: nop\n",
pexp->nNameLength, pexp->pcName, pexp->strName.len, pexp->strName.buf,
pexp->nNameLength, pexp->pcName); pexp->strName.len, pexp->strName.buf);
} }
else if (pexp->nCallingConvention == CC_STDCALL) else if (pexp->nCallingConvention == CC_STDCALL)
{ {
fprintf(fileDest, "PUBLIC __stub_%.*s@%d\n__stub_%.*s@%d: nop\n", fprintf(fileDest, "PUBLIC __stub_%.*s@%d\n__stub_%.*s@%d: nop\n",
pexp->nNameLength, pexp->pcName, pexp->nStackBytes, pexp->strName.len, pexp->strName.buf, pexp->nStackBytes,
pexp->nNameLength, pexp->pcName, pexp->nStackBytes); pexp->strName.len, pexp->strName.buf, pexp->nStackBytes);
} }
else if (pexp->nCallingConvention == CC_FASTCALL) else if (pexp->nCallingConvention == CC_FASTCALL)
{ {
fprintf(fileDest, "PUBLIC @_stub_%.*s@%d\n@_stub_%.*s@%d: nop\n", fprintf(fileDest, "PUBLIC @_stub_%.*s@%d\n@_stub_%.*s@%d: nop\n",
pexp->nNameLength, pexp->pcName, pexp->nStackBytes, pexp->strName.len, pexp->strName.buf, pexp->nStackBytes,
pexp->nNameLength, pexp->pcName, pexp->nStackBytes); pexp->strName.len, pexp->strName.buf, pexp->nStackBytes);
} }
else if (pexp->nCallingConvention == CC_CDECL || else if (pexp->nCallingConvention == CC_CDECL ||
pexp->nCallingConvention == CC_STUB) pexp->nCallingConvention == CC_STUB)
{ {
fprintf(fileDest, "PUBLIC __stub_%.*s\n__stub_%.*s: nop\n", fprintf(fileDest, "PUBLIC __stub_%.*s\n__stub_%.*s: nop\n",
pexp->nNameLength, pexp->pcName, pexp->strName.len, pexp->strName.buf,
pexp->nNameLength, pexp->pcName); pexp->strName.len, pexp->strName.buf);
} }
else if (pexp->nCallingConvention == CC_EXTERN) else if (pexp->nCallingConvention == CC_EXTERN)
{ {
fprintf(fileDest, "PUBLIC __stub_%.*s\n__stub_%.*s:\n", fprintf(fileDest, "PUBLIC __stub_%.*s\n__stub_%.*s:\n",
pexp->nNameLength, pexp->pcName, pexp->strName.len, pexp->strName.buf,
pexp->nNameLength, pexp->pcName); pexp->strName.len, pexp->strName.buf);
} }
return 1; return 1;
@ -312,25 +317,151 @@ OutputHeader_def(FILE *file, char *libname)
} }
void void
PrintName(FILE *fileDest, EXPORT *pexp, char *pszPrefix, int fRedir, int fDeco) PrintName(FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco)
{ {
char *pcName = fRedir ? pexp->pcRedirection : pexp->pcName; const char *pcName = pstr->buf;
int nNameLength = fRedir ? pexp->nRedirectionLength : pexp->nNameLength; int nNameLength = pstr->len;
const char* pcDot, *pcAt;
/* Handle autoname */ if ((giArch == ARCH_X86) && fDeco &&
if (nNameLength == 1 && pcName[0] == '@') ((pexp->nCallingConvention == CC_STDCALL) ||
(pexp->nCallingConvention == CC_FASTCALL)))
{ {
fprintf(fileDest, "ordinal%d", pexp->nOrdinal); /* Scan for a dll forwarding dot */
pcDot = ScanToken(pcName, '.');
if (pcDot)
{
/* First print the dll name, followed by a dot */
nNameLength = pcDot - pcName;
fprintf(fileDest, "%.*s.", nNameLength, pcName);
/* Now the actual function name */
pcName = pcDot + 1;
nNameLength = pexp->strTarget.len - nNameLength - 1;
}
/* Does the string already have decoration? */
pcAt = ScanToken(pcName, '@');
if (pcAt && (pcAt < (pcName + nNameLength)))
{
/* On GCC, we need to remove the leading stdcall underscore */
if (!gbMSComp && (pexp->nCallingConvention == CC_STDCALL))
{
pcName++;
nNameLength--;
}
/* Print the already decorated function name */
fprintf(fileDest, "%.*s", nNameLength, pcName);
}
else
{
/* Print the prefix, but skip it for (GCC && stdcall) */
if (gbMSComp || (pexp->nCallingConvention != CC_STDCALL))
{
fprintf(fileDest, "%c%", pexp->nCallingConvention == CC_FASTCALL ? '@' : '_');
}
/* Print the name with trailing decoration */
fprintf(fileDest, "%.*s@%d", nNameLength, pcName, pexp->nStackBytes);
}
} }
else else
{ {
if (fDeco && pexp->nCallingConvention == CC_FASTCALL) /* Print the undecorated function name */
fprintf(fileDest, "@"); fprintf(fileDest, "%.*s", nNameLength, pcName);
fprintf(fileDest, "%s%.*s", pszPrefix, nNameLength, pcName); }
if ((pexp->nCallingConvention == CC_STDCALL || }
pexp->nCallingConvention == CC_FASTCALL) && fDeco)
void
OutputLine_def_MS(FILE *fileDest, EXPORT *pexp)
{
PrintName(fileDest, pexp, &pexp->strName, 0);
if (gbImportLib)
{
/* Redirect to a stub function, to get the right decoration in the lib */
fprintf(fileDest, "=_stub_%.*s", pexp->strName.len, pexp->strName.buf);
}
else if (pexp->strTarget.buf)
{
if (pexp->strName.buf[0] == '?')
{ {
fprintf(fileDest, "@%d", pexp->nStackBytes); fprintf(stderr, "warning: ignoring C++ redirection %.*s -> %.*s\n",
pexp->strName.len, pexp->strName.buf, pexp->strTarget.len, pexp->strTarget.buf);
}
else
{
fprintf(fileDest, "=");
/* If the original name was decorated, use decoration in the forwarder as well */
if ((giArch == ARCH_X86) && ScanToken(pexp->strName.buf, '@') &&
!ScanToken(pexp->strTarget.buf, '@') &&
((pexp->nCallingConvention == CC_STDCALL) ||
(pexp->nCallingConvention == CC_FASTCALL)) )
{
PrintName(fileDest, pexp, &pexp->strTarget, 1);
}
else
{
/* Write the undecorated redirection name */
fprintf(fileDest, "%.*s", pexp->strTarget.len, pexp->strTarget.buf);
}
}
}
else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
(pexp->strName.buf[0] == '?'))
{
/* C++ stubs are forwarded to C stubs */
fprintf(fileDest, "=stub_function%d", pexp->nNumber);
}
}
void
OutputLine_def_GCC(FILE *fileDest, EXPORT *pexp)
{
/* Print the function name, with decoration for export libs */
PrintName(fileDest, pexp, &pexp->strName, gbImportLib);
DbgPrint("Generating def line for '%.*s'\n", pexp->strName.len, pexp->strName.buf);
/* Check if this is a forwarded export */
if (pexp->strTarget.buf)
{
DbgPrint("Got redirect '%.*s'\n", pexp->strTarget.len, pexp->strTarget.buf);
int fIsExternal = !!ScanToken(pexp->strTarget.buf, '.');
/* print the target name, don't decorate if it is external */
fprintf(fileDest, "=");
PrintName(fileDest, pexp, &pexp->strTarget, !fIsExternal);
}
else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
(pexp->strName.buf[0] == '?'))
{
/* C++ stubs are forwarded to C stubs */
fprintf(fileDest, "=stub_function%d", pexp->nNumber);
}
/* Special handling for stdcall and fastcall */
if ((giArch == ARCH_X86) &&
((pexp->nCallingConvention == CC_STDCALL) ||
(pexp->nCallingConvention == CC_FASTCALL)))
{
/* Is this the import lib? */
if (gbImportLib)
{
/* Is the name in the spec file decorated? */
const char* pcDeco = ScanToken(pexp->strName.buf, '@');
if (pcDeco && (pcDeco < pexp->strName.buf + pexp->strName.len))
{
/* Write the name including the leading @ */
fprintf(fileDest, "==%.*s", pexp->strName.len, pexp->strName.buf);
}
}
else if (!pexp->strTarget.buf)
{
/* Write a forwarder to the actual decorated symbol */
fprintf(fileDest, "=");
PrintName(fileDest, pexp, &pexp->strName, 1);
} }
} }
} }
@ -340,43 +471,10 @@ OutputLine_def(FILE *fileDest, EXPORT *pexp)
{ {
fprintf(fileDest, " "); fprintf(fileDest, " ");
PrintName(fileDest, pexp, "", 0, (giArch == ARCH_X86) && !gbKillAt); if (gbMSComp)
OutputLine_def_MS(fileDest, pexp);
if (gbImportLib) else
{ OutputLine_def_GCC(fileDest, pexp);
fprintf(fileDest, "=");
PrintName(fileDest, pexp, "_stub_", 0, 0);
}
else if (pexp->pcRedirection)
{
if (gbMSComp && (pexp->pcName[0] == '?'))
{
fprintf(stderr, "warning: ignoring C++ redirection %.*s -> %.*s\n",
pexp->nNameLength, pexp->pcName, pexp->nRedirectionLength, pexp->pcRedirection);
}
else
{
int fDeco;
fDeco = ((giArch == ARCH_X86) && !ScanToken(pexp->pcRedirection, '.'));
fprintf(fileDest, "=");
PrintName(fileDest, pexp, "", 1, fDeco && !gbMSComp);
}
}
else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
(pexp->pcName[0] == '?'))
{
/* C++ stubs are forwarded to C stubs */
fprintf(fileDest, "=");
fprintf(fileDest, "stub_function%d", pexp->nNumber);
}
else if ((giArch == ARCH_X86) && gbKillAt && !gbMSComp &&
(pexp->nCallingConvention == CC_STDCALL ||
pexp->nCallingConvention == CC_FASTCALL))
{
fprintf(fileDest, "=");
PrintName(fileDest, pexp, "", 0, 1);
}
if (pexp->nOrdinal != -1) if (pexp->nOrdinal != -1)
{ {
@ -410,6 +508,7 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
int nLine; int nLine;
EXPORT exp; EXPORT exp;
int included; int included;
char namebuffer[16];
//fprintf(stderr, "info: line %d, pcStart:'%.30s'\n", nLine, pcStart); //fprintf(stderr, "info: line %d, pcStart:'%.30s'\n", nLine, pcStart);
@ -424,6 +523,10 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
exp.uFlags = 0; exp.uFlags = 0;
exp.nNumber++; exp.nNumber++;
//if (!strncmp(pcLine, "22 stdcall @(long) MPR_Alloc",28))
// gbDebug = 1;
//fprintf(stderr, "info: line %d, token:'%d, %.20s'\n", //fprintf(stderr, "info: line %d, token:'%d, %.20s'\n",
// nLine, TokenLength(pcLine), pcLine); // nLine, TokenLength(pcLine), pcLine);
@ -448,7 +551,7 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
return -10; return -10;
} }
//fprintf(stderr, "info: Token:'%.10s'\n", pc); //fprintf(stderr, "info: Token:'%.*s'\n", TokenLength(pc), pc);
/* Now we should get the type */ /* Now we should get the type */
if (CompareToken(pc, "stdcall")) if (CompareToken(pc, "stdcall"))
@ -478,7 +581,7 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
} }
else else
{ {
fprintf(stderr, "error: line %d, expected type, got '%.*s' %d\n", fprintf(stderr, "error: line %d, expected callconv, got '%.*s' %d\n",
nLine, TokenLength(pc), pc, *pc); nLine, TokenLength(pc), pc, *pc);
return -11; return -11;
} }
@ -555,8 +658,17 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
if (!included) continue; if (!included) continue;
/* Get name */ /* Get name */
exp.pcName = pc; exp.strName.buf = pc;
exp.nNameLength = TokenLength(pc); exp.strName.len = TokenLength(pc);
/* Check for autoname */
if ((exp.strName.len == 1) && (exp.strName.buf[0] == '@'))
{
sprintf(namebuffer, "ordinal%d", exp.nOrdinal);
exp.strName.len = strlen(namebuffer);
exp.strName.buf = namebuffer;
exp.uFlags |= FL_NONAME;
}
/* Handle parameters */ /* Handle parameters */
exp.nStackBytes = 0; exp.nStackBytes = 0;
@ -649,12 +761,14 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
else else
{ {
/* Check for stdcall name */ /* Check for stdcall name */
char *p = strchr(pc, '@'); const char *p = ScanToken(pc, '@');
if (p && (p - pc < exp.nNameLength)) if (p && (p - pc < exp.strName.len))
{ {
int i; int i;
exp.nNameLength = (int)(p - pc);
if (exp.nNameLength < 1) /* Truncate the name to before the @ */
exp.strName.len = (int)(p - pc);
if (exp.strName.len < 1)
{ {
fprintf(stderr, "error, @ in line %d\n", nLine); fprintf(stderr, "error, @ in line %d\n", nLine);
return -1; return -1;
@ -673,8 +787,8 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
pc = NextToken(pc); pc = NextToken(pc);
if (pc) if (pc)
{ {
exp.pcRedirection = pc; exp.strTarget.buf = pc;
exp.nRedirectionLength = TokenLength(pc); exp.strTarget.len = TokenLength(pc);
/* Check syntax (end of line) */ /* Check syntax (end of line) */
if (NextToken(pc)) if (NextToken(pc))
@ -685,11 +799,18 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
} }
else else
{ {
exp.pcRedirection = 0; exp.strTarget.buf = 0;
exp.nRedirectionLength = 0; exp.strTarget.len = 0;
}
/* Check for no-name without ordinal */
if ((exp.uFlags & FL_NONAME) && (exp.nOrdinal == -1))
{
fprintf(stderr, "error: line %d, noname export without ordinal!\n", nLine);
} }
OutputLine(fileDest, &exp); OutputLine(fileDest, &exp);
gbDebug = 0;
} }
return 0; return 0;
@ -752,21 +873,12 @@ int main(int argc, char *argv[])
} }
else if ((strcasecmp(argv[i], "--implib") == 0)) else if ((strcasecmp(argv[i], "--implib") == 0))
{ {
no_redirections = 1;
gbImportLib = 1; gbImportLib = 1;
} }
else if ((strcasecmp(argv[i], "--kill-at") == 0))
{
gbKillAt = 1;
}
else if ((strcasecmp(argv[i], "--ms") == 0)) else if ((strcasecmp(argv[i], "--ms") == 0))
{ {
gbMSComp = 1; gbMSComp = 1;
} }
else if ((strcasecmp(argv[i], "-r") == 0))
{
no_redirections = 1;
}
else if (argv[i][1] == 'a' && argv[i][2] == '=') else if (argv[i][1] == 'a' && argv[i][2] == '=')
{ {
pszArchString = argv[i] + 3; pszArchString = argv[i] + 3;