mirror of
https://github.com/reactos/reactos.git
synced 2024-09-30 14:37:45 +00:00
[SPEC2DEF] Refactor to avoid parsing multiple times
This commit is contained in:
parent
9cff65970f
commit
e8ab2736e7
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue