diff --git a/sdk/tools/spec2def/spec2def.c b/sdk/tools/spec2def/spec2def.c index 926cb328df9..324f88405fd 100644 --- a/sdk/tools/spec2def/spec2def.c +++ b/sdk/tools/spec2def/spec2def.c @@ -28,8 +28,29 @@ typedef struct int anArgs[30]; unsigned int uFlags; int nNumber; + unsigned nStartVersion; + unsigned nEndVersion; + int bVersionIncluded; } EXPORT; +#if 0 // Debug helper function +void +PrintExport(EXPORT *pexp) +{ + fprintf(stderr, "strName='%.*s'\n", pexp->strName.len, pexp->strName.buf); + fprintf(stderr, "strName='%.*s'\n", pexp->strTarget.len, pexp->strTarget.buf); + fprintf(stderr, "nCallingConvention=%u\n", pexp->nCallingConvention); + fprintf(stderr, "nOrdinal=%u\n", pexp->nOrdinal); + fprintf(stderr, "nStackBytes=%u\n", pexp->nStackBytes); + fprintf(stderr, "nArgCount=%u\n", pexp->nArgCount); + fprintf(stderr, "uFlags=0x%x\n", pexp->uFlags); + fprintf(stderr, "nNumber=%u\n", pexp->nNumber); + fprintf(stderr, "nStartVersion=%u\n", pexp->nStartVersion); + fprintf(stderr, "nEndVersion=%u\n", pexp->nEndVersion); + fprintf(stderr, "bVersionIncluded=%u\n", pexp->bVersionIncluded); +} +#endif + enum _ARCH { ARCH_X86, @@ -509,7 +530,7 @@ PrintName(FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco) const char *pcName = pstr->buf; int nNameLength = pstr->len; const char* pcDot, *pcAt; - char namebuffer[16]; + char namebuffer[19]; if ((nNameLength == 1) && (pcName[0] == '@')) { @@ -803,17 +824,34 @@ Fatal( va_end(argptr); } -int -ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine) +EXPORT * +ParseFile(char* pcStart, FILE *fileDest, unsigned *cExports) { + EXPORT *pexports; const char *pc, *pcLine; - int nLine; + int cLines, nLine; EXPORT exp; - int included, version_included; + int included; unsigned int i; + *cExports = 0; + //fprintf(stderr, "info: line %d, pcStart:'%.30s'\n", nLine, pcStart); + /* Count the lines */ + for (cLines = 1, pcLine = pcStart; *pcLine; pcLine = NextLine(pcLine), cLines++) + { + /* Nothing */ + } + + /* Allocate an array of EXPORT structures */ + pexports = malloc(cLines * sizeof(EXPORT)); + if (pexports == NULL) + { + fprintf(stderr, "ERROR: %s: failed to allocate EXPORT array of %u elements\n", pszSourceFileName, cLines); + return NULL; + } + /* Loop all lines */ nLine = 1; exp.nNumber = 0; @@ -821,16 +859,32 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine) { pc = pcLine; + exp.strName.buf = NULL; + exp.strName.len = 0; + exp.strTarget.buf = NULL; + exp.strTarget.len = 0; exp.nArgCount = 0; exp.uFlags = 0; exp.nNumber++; + exp.nStartVersion = 0; + exp.nEndVersion = 0xFFFFFFFF; + exp.bVersionIncluded = 1; /* Skip white spaces */ while (*pc == ' ' || *pc == '\t') pc++; - /* Skip empty lines, stop at EOF */ - if (*pc == ';' || *pc <= '#') continue; - if (*pc == 0) return 0; + /* Check for line break or comment */ + if ((*pc == '\r') || (*pc == '\n') || + (*pc == ';') || (*pc == '#')) + { + continue; + } + + /* On EOF we are done */ + if (*pc == 0) + { + return pexports; + } /* Now we should get either an ordinal or @ */ if (*pc == '@') @@ -909,7 +963,6 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine) /* Handle options */ included = 1; - version_included = 1; while (*pc == '-') { if (CompareToken(pc, "-arch=")) @@ -941,7 +994,7 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine) const char *pcVersionStart = pc + 9; /* Default to not included */ - version_included = 0; + exp.bVersionIncluded = 0; pc += 8; /* Look if we are included */ @@ -981,11 +1034,14 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine) "Invalid version range"); } + exp.nStartVersion = version; + exp.nEndVersion = endversion; + /* Now compare the range with our version */ if ((guOsVersion >= version) && (guOsVersion <= endversion)) { - version_included = 1; + exp.bVersionIncluded = 1; } /* Skip to next arch or end */ @@ -1042,7 +1098,7 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine) //fprintf(stderr, "info: Name:'%.10s'\n", pc); /* If arch didn't match ours, skip this entry */ - if (!included || !version_included) continue; + if (!included) continue; /* Get name */ exp.strName.buf = pc; @@ -1235,11 +1291,12 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine) } } - OutputLine(fileDest, &exp); + pexports[*cExports] = exp; + (*cExports)++; gbDebug = 0; } - return 0; + return pexports; } void usage(void) @@ -1265,7 +1322,8 @@ int main(int argc, char *argv[]) const char* pszVersionOption = "--version=0x"; char achDllName[40]; FILE *file; - int result = 0, i; + unsigned cExports = 0, i; + EXPORT *pexports; if (argc < 2) { @@ -1274,7 +1332,7 @@ int main(int argc, char *argv[]) } /* Read options */ - for (i = 1; i < argc && *argv[i] == '-'; i++) + for (i = 1; i < (unsigned)argc && *argv[i] == '-'; i++) { if ((strcasecmp(argv[i], "--help") == 0) || (strcasecmp(argv[i], "-h") == 0)) @@ -1404,6 +1462,13 @@ int main(int argc, char *argv[]) /* Zero terminate the source */ pszSource[nFileSize] = '\0'; + pexports = ParseFile(pszSource, file, &cExports); + if (pexports == NULL) + { + fprintf(stderr, "Failed to allocate memory for export data!\n"); + return -1; + } + if (pszDefFileName) { /* Open output file */ @@ -1415,7 +1480,13 @@ int main(int argc, char *argv[]) } OutputHeader_def(file, pszDllName); - result = ParseFile(pszSource, file, OutputLine_def); + + for (i = 0; i < cExports; i++) + { + if (pexports[i].bVersionIncluded) + OutputLine_def(file, &pexports[i]); + } + fclose(file); } @@ -1430,7 +1501,13 @@ int main(int argc, char *argv[]) } OutputHeader_stub(file); - result = ParseFile(pszSource, file, OutputLine_stub); + + for (i = 0; i < cExports; i++) + { + if (pexports[i].bVersionIncluded) + OutputLine_stub(file, &pexports[i]); + } + fclose(file); } @@ -1445,10 +1522,18 @@ int main(int argc, char *argv[]) } OutputHeader_asmstub(file, pszDllName); - result = ParseFile(pszSource, file, OutputLine_asmstub); + + for (i = 0; i < cExports; i++) + { + if (pexports[i].bVersionIncluded) + OutputLine_asmstub(file, &pexports[i]); + } + fprintf(file, "\n END\n"); fclose(file); } - return result; + free(pexports); + + return 0; }