mirror of
https://github.com/reactos/reactos.git
synced 2024-10-01 23:14:53 +00:00
[SPEC2DEF] Improve error output
This commit is contained in:
parent
05f0b08085
commit
c95b5e6f9b
|
@ -2,6 +2,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define strcasecmp(_String1, _String2) _stricmp(_String1, _String2)
|
#define strcasecmp(_String1, _String2) _stricmp(_String1, _String2)
|
||||||
|
@ -711,6 +712,73 @@ OutputLine_def(FILE *fileDest, EXPORT *pexp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Fatalv(
|
||||||
|
const char* filename,
|
||||||
|
unsigned nLine,
|
||||||
|
char *pcLine,
|
||||||
|
char *pc,
|
||||||
|
size_t errorlen,
|
||||||
|
const char *format,
|
||||||
|
va_list argptr)
|
||||||
|
{
|
||||||
|
unsigned i, errorpos, len;
|
||||||
|
const char* pcLineEnd;
|
||||||
|
|
||||||
|
/* Get the length of the line */
|
||||||
|
pcLineEnd = strpbrk(pcLine, "\r\n");
|
||||||
|
len = pcLineEnd - pcLine;
|
||||||
|
|
||||||
|
if (pc == NULL)
|
||||||
|
{
|
||||||
|
pc = pcLine + len - 1;
|
||||||
|
errorlen = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
errorpos = (unsigned)(pc - pcLine);
|
||||||
|
|
||||||
|
/* Output the error message */
|
||||||
|
fprintf(stderr, "ERROR: (%s:%u:%u): ", filename, nLine, errorpos);
|
||||||
|
vfprintf(stderr, format, argptr);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
|
/* Output the line with the error */
|
||||||
|
fprintf(stderr, "> %.*s\n", len, pcLine);
|
||||||
|
|
||||||
|
if (errorlen == 0)
|
||||||
|
{
|
||||||
|
errorlen = TokenLength(pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < errorpos + 2; i++)
|
||||||
|
{
|
||||||
|
fprintf(stderr, " ");
|
||||||
|
}
|
||||||
|
for (i = 0; i < errorlen; i++)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "~");
|
||||||
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Fatal(
|
||||||
|
const char* filename,
|
||||||
|
unsigned nLine,
|
||||||
|
char *pcLine,
|
||||||
|
char *pc,
|
||||||
|
size_t errorlen,
|
||||||
|
const char *format,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
va_list argptr;
|
||||||
|
|
||||||
|
va_start(argptr, format);
|
||||||
|
Fatalv(filename, nLine, pcLine, pc, errorlen, format, argptr);
|
||||||
|
va_end(argptr);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
|
ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
|
||||||
{
|
{
|
||||||
|
@ -743,20 +811,38 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
|
||||||
|
|
||||||
/* Now we should get either an ordinal or @ */
|
/* Now we should get either an ordinal or @ */
|
||||||
if (*pc == '@')
|
if (*pc == '@')
|
||||||
exp.nOrdinal = -1;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
exp.nOrdinal = atol(pc);
|
exp.nOrdinal = -1;
|
||||||
|
}
|
||||||
|
else if ((*pc >= '0') && (*pc <= '9'))
|
||||||
|
{
|
||||||
|
char* end;
|
||||||
|
long int number = strtol(pc, &end, 10);
|
||||||
|
if ((*end != ' ') && (*end != '\t'))
|
||||||
|
{
|
||||||
|
Fatal(pszSourceFileName, nLine, pcLine, end, 0, "Unexpected character(s) after ordinal");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((number < 0) || (number > 0xFFFE))
|
||||||
|
{
|
||||||
|
Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Invalid value for ordinal");
|
||||||
|
}
|
||||||
|
|
||||||
|
exp.nOrdinal = number;
|
||||||
|
|
||||||
/* The import lib should contain the ordinal only if -ordinal was specified */
|
/* The import lib should contain the ordinal only if -ordinal was specified */
|
||||||
if (!gbImportLib)
|
if (!gbImportLib)
|
||||||
exp.uFlags |= FL_ORDINAL;
|
exp.uFlags |= FL_ORDINAL;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Expected '@' or ordinal");
|
||||||
|
}
|
||||||
|
|
||||||
/* Go to next token (type) */
|
/* Go to next token (type) */
|
||||||
if (!(pc = NextToken(pc)))
|
if (!(pc = NextToken(pc)))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s line %d: error: unexpected end of line\n", pszSourceFileName, nLine);
|
Fatal(pszSourceFileName, nLine, pcLine, pc, 1, "Unexpected end of line");
|
||||||
return -10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//fprintf(stderr, "info: Token:'%.*s'\n", TokenLength(pc), pc);
|
//fprintf(stderr, "info: Token:'%.*s'\n", TokenLength(pc), pc);
|
||||||
|
@ -789,16 +875,13 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s line %d: error: expected callconv, got '%.*s' %d\n",
|
Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Invalid calling convention");
|
||||||
pszSourceFileName, nLine, TokenLength(pc), pc, *pc);
|
|
||||||
return -11;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Go to next token (options or name) */
|
/* Go to next token (options or name) */
|
||||||
if (!(pc = NextToken(pc)))
|
if (!(pc = NextToken(pc)))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "fail2\n");
|
Fatal(pszSourceFileName, nLine, pcLine, pc, 1, "Unexpected end of line");
|
||||||
return -12;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle options */
|
/* Handle options */
|
||||||
|
@ -832,6 +915,8 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
|
||||||
}
|
}
|
||||||
else if (CompareToken(pc, "-version="))
|
else if (CompareToken(pc, "-version="))
|
||||||
{
|
{
|
||||||
|
char * pcVersionStart = pc + 9;
|
||||||
|
|
||||||
/* Default to not included */
|
/* Default to not included */
|
||||||
version_included = 0;
|
version_included = 0;
|
||||||
pc += 8;
|
pc += 8;
|
||||||
|
@ -865,8 +950,12 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
|
||||||
/* Check for degenerate range */
|
/* Check for degenerate range */
|
||||||
if (version > endversion)
|
if (version > endversion)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s line %d: error: invalid version rangen\n", pszSourceFileName, nLine);
|
Fatal(pszSourceFileName,
|
||||||
return -1;
|
nLine,
|
||||||
|
pcLine,
|
||||||
|
pcVersionStart,
|
||||||
|
pc - pcVersionStart,
|
||||||
|
"Invalid version range");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now compare the range with our version */
|
/* Now compare the range with our version */
|
||||||
|
@ -915,8 +1004,12 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr, "info: ignored option: '%.*s'\n",
|
fprintf(stdout,
|
||||||
TokenLength(pc), pc);
|
"INFO: %s line %d: Ignored option: '%.*s'\n",
|
||||||
|
pszSourceFileName,
|
||||||
|
nLine,
|
||||||
|
TokenLength(pc),
|
||||||
|
pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Go to next token */
|
/* Go to next token */
|
||||||
|
@ -931,7 +1024,7 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
|
||||||
/* Get name */
|
/* Get name */
|
||||||
exp.strName.buf = pc;
|
exp.strName.buf = pc;
|
||||||
exp.strName.len = TokenLength(pc);
|
exp.strName.len = TokenLength(pc);
|
||||||
DbgPrint("Got name: '%.*s'\n", exp.strName.len, exp.strName.buf);
|
//DbgPrint("Got name: '%.*s'\n", exp.strName.len, exp.strName.buf);
|
||||||
|
|
||||||
/* Check for autoname */
|
/* Check for autoname */
|
||||||
if ((exp.strName.len == 1) && (exp.strName.buf[0] == '@'))
|
if ((exp.strName.len == 1) && (exp.strName.buf[0] == '@'))
|
||||||
|
@ -950,15 +1043,13 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
|
||||||
/* Go to next token */
|
/* Go to next token */
|
||||||
if (!(pc = NextToken(pc)))
|
if (!(pc = NextToken(pc)))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s line %d: error: expected token\n", pszSourceFileName, nLine);
|
Fatal(pszSourceFileName, nLine, pcLine, pc, 1, "Unexpected end of line");
|
||||||
return -13;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Verify syntax */
|
/* Verify syntax */
|
||||||
if (*pc++ != '(')
|
if (*pc++ != '(')
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s line %d: error: expected '('\n", pszSourceFileName, nLine);
|
Fatal(pszSourceFileName, nLine, pcLine, pc - 1, 0, "Expected '('");
|
||||||
return -14;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip whitespaces */
|
/* Skip whitespaces */
|
||||||
|
@ -1008,23 +1099,23 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
|
||||||
exp.anArgs[exp.nArgCount] = ARG_FLOAT;
|
exp.anArgs[exp.nArgCount] = ARG_FLOAT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fprintf(stderr, "%s line %d: error: expected type, got: %.10s\n", pszSourceFileName, nLine, pc);
|
{
|
||||||
|
Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Unrecognized type");
|
||||||
|
}
|
||||||
|
|
||||||
exp.nArgCount++;
|
exp.nArgCount++;
|
||||||
|
|
||||||
/* Go to next parameter */
|
/* Go to next parameter */
|
||||||
if (!(pc = NextToken(pc)))
|
if (!(pc = NextToken(pc)))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "fail5\n");
|
Fatal(pszSourceFileName, nLine, pcLine, pc, 1, "Unexpected end of line");
|
||||||
return -15;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check syntax */
|
/* Check syntax */
|
||||||
if (*pc++ != ')')
|
if (*pc++ != ')')
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s line %d: error: expected ')'\n", pszSourceFileName, nLine);
|
Fatal(pszSourceFileName, nLine, pcLine, pc - 1, 0, "Expected ')'");
|
||||||
return -16;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1049,8 +1140,7 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
|
||||||
exp.strName.len = (int)(p - pc);
|
exp.strName.len = (int)(p - pc);
|
||||||
if (exp.strName.len < 1)
|
if (exp.strName.len < 1)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s line %d: error: unexpected @ found\n", pszSourceFileName, nLine);
|
Fatal(pszSourceFileName, nLine, pcLine, p, 1, "Unexpected @");
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
exp.nStackBytes = atoi(p + 1);
|
exp.nStackBytes = atoi(p + 1);
|
||||||
exp.nArgCount = exp.nStackBytes / 4;
|
exp.nArgCount = exp.nStackBytes / 4;
|
||||||
|
@ -1072,8 +1162,7 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
|
||||||
/* Check syntax (end of line) */
|
/* Check syntax (end of line) */
|
||||||
if (NextToken(pc))
|
if (NextToken(pc))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s line %d: error: additional tokens after ')'\n", pszSourceFileName, nLine);
|
Fatal(pszSourceFileName, nLine, pcLine, NextToken(pc), 0, "Excess token(s) at end of definition");
|
||||||
return -17;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't relay-trace forwarded functions */
|
/* Don't relay-trace forwarded functions */
|
||||||
|
@ -1088,8 +1177,7 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
|
||||||
/* Check for no-name without ordinal */
|
/* Check for no-name without ordinal */
|
||||||
if ((exp.uFlags & FL_ORDINAL) && (exp.nOrdinal == -1))
|
if ((exp.uFlags & FL_ORDINAL) && (exp.nOrdinal == -1))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s line %d: error: ordinal export without ordinal!\n", pszSourceFileName, nLine);
|
Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Ordinal export without ordinal");
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1113,12 +1201,12 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
|
||||||
/* The current export is an OLE export: display the corresponding warning */
|
/* The current export is an OLE export: display the corresponding warning */
|
||||||
if (bIsNotPrivate)
|
if (bIsNotPrivate)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s line %d: warning: exported symbol '%.*s' should be PRIVATE\n",
|
fprintf(stderr, "WARNING: %s line %d: Exported symbol '%.*s' should be PRIVATE\n",
|
||||||
pszSourceFileName, nLine, exp.strName.len, exp.strName.buf);
|
pszSourceFileName, nLine, exp.strName.len, exp.strName.buf);
|
||||||
}
|
}
|
||||||
if (bHasOrdinal)
|
if (bHasOrdinal)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s line %d: warning: exported symbol '%.*s' should not be assigned an ordinal\n",
|
fprintf(stderr, "WARNING: %s line %d: exported symbol '%.*s' should not be assigned an ordinal\n",
|
||||||
pszSourceFileName, nLine, exp.strName.len, exp.strName.buf);
|
pszSourceFileName, nLine, exp.strName.len, exp.strName.buf);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue