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,
const char *pcName = pstr->buf;
int nNameLength = pstr->len;
const char* pcDot, *pcAt;
- char namebuffer[16];
+ char namebuffer[19];
if ((nNameLength == 1) && (pcName[0] == '@'))
{
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;
{
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 == '@')
/* Handle options */
included = 1;
- version_included = 1;
while (*pc == '-')
{
if (CompareToken(pc, "-arch="))
const char *pcVersionStart = pc + 9;
/* Default to not included */
- version_included = 0;
+ exp.bVersionIncluded = 0;
pc += 8;
/* Look if we are included */
"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 */
//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;
}
}
- OutputLine(fileDest, &exp);
+ pexports[*cExports] = exp;
+ (*cExports)++;
gbDebug = 0;
}
- return 0;
+ return pexports;
}
void usage(void)
const char* pszVersionOption = "--version=0x";
char achDllName[40];
FILE *file;
- int result = 0, i;
+ unsigned cExports = 0, i;
+ EXPORT *pexports;
if (argc < 2)
{
}
/* 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))
/* 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 */
}
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);
}
}
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);
}
}
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;
}