/* Give a warning in some special cases */
if ((flags & CF_UNSIGNED) && val == 0) {
- Warning (WARN_COND_NEVER_TRUE);
+ Warning ("Condition is never true");
}
/* Look at the type */
/* Give a warning in some special cases */
if ((flags & CF_UNSIGNED) && val == 0) {
- Warning (WARN_COND_ALWAYS_TRUE);
+ Warning ("Condition is always true");
}
/* Look at the type */
*/
{
if ((D->Flags & DS_EXTRA_TYPE) == 0) {
- Warning (WARN_USELESS_DECL);
+ Warning ("Useless declaration");
}
}
-static char* WarnMsg [WARN_COUNT-1] = {
- "Unreachable code",
- "Condition is never true",
- "Condition is always true",
- "Converting pointer to integer without a cast",
- "Converting integer to pointer without a cast",
- "Function call without a prototype",
- "Unknown #pragma",
- "No case labels",
- "Function must be extern",
- "Parameter `%s' is never used",
- "`%s' is defined but never used",
- "Constant is long",
- "`/*' found inside a comment",
- "Useless declaration",
-};
-
-
-
/* Error messages sorted by ErrTypes */
static char* ErrMsg [ERR_COUNT-1] = {
- "Invalid character (%u)",
- "Unexpected newline",
- "End-of-file reached in comment starting at line %u",
"Syntax error",
"`\"' expected",
"`:' expected",
"Incompatible pointer types",
"Too many arguments in function call",
"Too few arguments in function call",
- "Macro argument count mismatch",
"Duplicate macro parameter: %s",
- "Macro redefinition is not identical",
"Variable identifier expected",
"Integer expression expected",
"Constant expression expected",
"No active loop",
- "`\"' or `<' expected",
- "Missing terminator or name too long",
- "Include file `%s' not found",
- "Cannot open include file `%s': %s",
- "Invalid #error directive",
- "#error: %s",
- "Unexpected `#endif'",
- "Unexpected `#else'",
- "`#endif' expected",
- "Compiler directive expected",
"Redefinition of `%s'",
"Conflicting types for `%s'",
"String literal expected",
"Unexpected `continue'",
"Undefined symbol: `%s'",
"Undefined label: `%s'",
- "Include nesting too deep",
"Too many local variables",
"Too many initializers",
"Cannot initialize incomplete type",
"Illegal function call",
"Illegal indirection",
"Illegal address",
- "Illegal macro call",
"Illegal hex digit",
"Illegal character constant",
"Illegal modifier",
-static char* FatMsg [FAT_COUNT-1] = {
- "Too many errors",
- "Cannot open output file: %s",
- "Cannot write to output file (disk full?)",
- "Cannot open input file: %s",
- "Out of memory",
- "Stack overflow",
- "Stack empty",
- "Out of string space",
- "Too many case labels",
-};
-
-
-
/* Count of errors/warnings */
unsigned ErrorCount = 0;
unsigned WarningCount = 0;
-void Warning (unsigned WarnNum, ...)
-/* Print warning message. */
+static void IntWarning (const char* Filename, unsigned Line, const char* Msg, va_list ap)
+/* Print warning message - internal function. */
{
- va_list ap;
-
if (!NoWarn) {
- fprintf (stderr, "%s(%u): Warning #%u: ",
- GetCurrentFile(), curpos, WarnNum);
-
- va_start (ap, WarnNum);
- vfprintf (stderr, WarnMsg [WarnNum-1], ap);
- va_end (ap);
+ fprintf (stderr, "%s(%u): Warning: ", Filename, Line);
+ vfprintf (stderr, Msg, ap);
fprintf (stderr, "\n");
if (Verbose) {
fprintf (stderr, "Line: %s\n", line);
}
+ ++WarningCount;
}
- ++ WarningCount;
}
-void PPWarning (unsigned WarnNum, ...)
-/* Print warning message. For use within the preprocessor. */
+void Warning (const char* Format, ...)
+/* Print warning message. */
{
va_list ap;
-
- if (!NoWarn) {
- fprintf (stderr, "%s(%u): Warning #%u: ",
- GetCurrentFile(), GetCurrentLine(), WarnNum);
-
- va_start (ap, WarnNum);
- vfprintf (stderr, WarnMsg [WarnNum-1], ap);
- va_end (ap);
- fprintf (stderr, "\n");
- }
- ++WarningCount;
+ va_start (ap, Format);
+ IntWarning (GetCurrentFile(), curpos, Format, ap);
+ va_end (ap);
}
-void Error (unsigned ErrNum, ...)
-/* Print an error message */
+void PPWarning (const char* Format, ...)
+/* Print warning message. For use within the preprocessor. */
{
va_list ap;
+ va_start (ap, Format);
+ IntWarning (GetCurrentFile(), GetCurrentLine(), Format, ap);
+ va_end (ap);
+}
- fprintf (stderr, "%s(%u): Error #%u: ",
- GetCurrentFile(), curpos, ErrNum);
- va_start (ap, ErrNum);
- vfprintf (stderr, ErrMsg [ErrNum-1], ap);
- va_end (ap);
+
+static void IntError (const char* Filename, unsigned Line, const char* Msg, va_list ap)
+/* Print an error message - internal function*/
+{
+ fprintf (stderr, "%s(%u): Error: ", Filename, Line);
+ vfprintf (stderr, Msg, ap);
fprintf (stderr, "\n");
if (Verbose) {
}
++ErrorCount;
if (ErrorCount > 10) {
- Fatal (FAT_TOO_MANY_ERRORS);
+ Fatal ("Too many errors");
}
}
-void PPError (unsigned ErrNum, ...)
-/* Print an error message. For use within the preprocessor. */
+void Error (unsigned ErrNum, ...)
+/* Print an error message */
{
va_list ap;
+ va_start (ap, ErrNum);
+ IntError (GetCurrentFile(), curpos, ErrMsg [ErrNum-1], ap);
+ va_end (ap);
+}
- fprintf (stderr, "%s(%u): Error #%u: ",
- GetCurrentFile(), GetCurrentLine(), ErrNum);
- va_start (ap, ErrNum);
- vfprintf (stderr, ErrMsg [ErrNum-1], ap);
+
+void MError (const char* Format, ...)
+/* Print an error message */
+{
+ va_list ap;
+ va_start (ap, Format);
+ IntError (GetCurrentFile(), curpos, Format, ap);
va_end (ap);
- fprintf (stderr, "\n");
+}
- ++ErrorCount;
- if (ErrorCount > 10) {
- Fatal (FAT_TOO_MANY_ERRORS);
- }
+
+
+void PPError (const char* Format, ...)
+/* Print an error message. For use within the preprocessor. */
+{
+ va_list ap;
+ va_start (ap, Format);
+ IntError (GetCurrentFile(), GetCurrentLine(), Format, ap);
+ va_end (ap);
}
-void Fatal (unsigned FatNum, ...)
+void Fatal (const char* Format, ...)
/* Print a message about a fatal error and die */
{
va_list ap;
- fprintf (stderr, "%s(%u): Fatal #%u: ",
- GetCurrentFile(), curpos, FatNum);
+ fprintf (stderr, "%s(%u): Fatal: ", GetCurrentFile(), curpos);
- va_start (ap, FatNum);
- vfprintf (stderr, FatMsg [FatNum-1], ap);
+ va_start (ap, Format);
+ vfprintf (stderr, Format, ap);
va_end (ap);
fprintf (stderr, "\n");
-/* Warning numbers */
-enum Warnings {
- WARN_NONE, /* No warning */
- WARN_UNREACHABLE_CODE,
- WARN_COND_NEVER_TRUE,
- WARN_COND_ALWAYS_TRUE,
- WARN_PTR_TO_INT_CONV,
- WARN_INT_TO_PTR_CONV,
- WARN_FUNC_WITHOUT_PROTO,
- WARN_UNKNOWN_PRAGMA,
- WARN_NO_CASE_LABELS,
- WARN_FUNC_MUST_BE_EXTERN,
- WARN_UNUSED_PARM,
- WARN_UNUSED_ITEM,
- WARN_CONSTANT_IS_LONG,
- WARN_NESTED_COMMENT,
- WARN_USELESS_DECL,
- WARN_COUNT /* Warning count */
-};
-
/* Error numbers */
-enum Errors {
+enum Errors {
ERR_NONE, /* No error */
- ERR_INVALID_CHAR,
- ERR_UNEXPECTED_NEWLINE,
- ERR_EOF_IN_COMMENT,
ERR_SYNTAX,
ERR_QUOTE_EXPECTED,
ERR_COLON_EXPECTED,
ERR_INCOMPATIBLE_POINTERS,
ERR_TOO_MANY_FUNC_ARGS,
ERR_TOO_FEW_FUNC_ARGS,
- ERR_MACRO_ARGCOUNT,
ERR_DUPLICATE_MACRO_ARG,
- ERR_MACRO_REDEF,
ERR_VAR_IDENT_EXPECTED,
ERR_INT_EXPR_EXPECTED,
ERR_CONST_EXPR_EXPECTED,
ERR_NO_ACTIVE_LOOP,
- ERR_INCLUDE_LTERM_EXPECTED,
- ERR_INCLUDE_RTERM_EXPECTED,
- ERR_INCLUDE_NOT_FOUND,
- ERR_INCLUDE_OPEN_FAILURE,
- ERR_INVALID_USER_ERROR,
- ERR_USER_ERROR,
- ERR_UNEXPECTED_CPP_ENDIF,
- ERR_UNEXPECTED_CPP_ELSE,
- ERR_CPP_ENDIF_EXPECTED,
- ERR_CPP_DIRECTIVE_EXPECTED,
ERR_MULTIPLE_DEFINITION,
ERR_CONFLICTING_TYPES,
ERR_STRLIT_EXPECTED,
ERR_UNEXPECTED_CONTINUE,
ERR_UNDEFINED_SYMBOL,
ERR_UNDEFINED_LABEL,
- ERR_INCLUDE_NESTING,
ERR_TOO_MANY_LOCALS,
ERR_TOO_MANY_INITIALIZERS,
ERR_INIT_INCOMPLETE_TYPE,
ERR_ILLEGAL_FUNC_CALL,
ERR_ILLEGAL_INDIRECT,
ERR_ILLEGAL_ADDRESS,
- ERR_ILLEGAL_MACRO_CALL,
ERR_ILLEGAL_HEX_DIGIT,
ERR_ILLEGAL_CHARCONST,
ERR_ILLEGAL_MODIFIER,
ERR_COUNT /* Error count */
};
-/* Fatal errors */
-enum Fatals {
- FAT_NONE,
- FAT_TOO_MANY_ERRORS,
- FAT_CANNOT_OPEN_OUTPUT,
- FAT_CANNOT_WRITE_OUTPUT,
- FAT_CANNOT_OPEN_INPUT,
- FAT_OUT_OF_MEMORY,
- FAT_STACK_OVERFLOW,
- FAT_STACK_EMPTY,
- FAT_OUT_OF_STRSPACE,
- FAT_TOO_MANY_CASE_LABELS,
- FAT_COUNT /* Fatal error count */
-};
-
-
-
/* Count of errors/warnings */
extern unsigned ErrorCount;
extern unsigned WarningCount;
-void Warning (unsigned WarnNum, ...);
+void Warning (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Print warning message. */
-void PPWarning (unsigned WarnNum, ...);
+void PPWarning (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Print warning message. For use within the preprocessor. */
void Error (unsigned ErrNum, ...);
/* Print an error message */
-void PPError (unsigned ErrNum, ...);
+void MError (const char* Format, ...) attribute ((format (printf, 1, 2)));
+/* Print an error message */
+
+void PPError (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Print an error message. For use within the preprocessor. */
-void Fatal (unsigned FatNum, ...);
+void Fatal (const char* Format, ...) attribute ((noreturn, format (printf, 1, 2)));
/* Print a message about a fatal error and die */
-void Internal (char* Format, ...) attribute ((noreturn));
+void Internal (char* Format, ...) attribute ((noreturn, format (printf, 1, 2)));
/* Print a message about an internal compiler error and die. */
void ErrorReport (void);
} else if (IsClassInt (lhst)) {
if (IsClassPtr (rhst)) {
/* Pointer -> int conversion */
- Warning (WARN_PTR_TO_INT_CONV);
+ Warning ("Converting pointer to integer without a cast");
} else if (!IsClassInt (rhst)) {
- Error (ERR_INCOMPATIBLE_TYPES);
+ Error (ERR_INCOMPATIBLE_TYPES);
} else {
/* Adjust the int types. To avoid manipulation of TOS mark lhs
* as const.
} else if (IsClassInt (rhst)) {
/* Int to pointer assignment is valid only for constant zero */
if ((rhs->e_flags & E_MCONST) == 0 || rhs->e_const != 0) {
- Warning (WARN_INT_TO_PTR_CONV);
+ Warning ("Converting integer to pointer without a cast");
}
} else if (IsTypeFuncPtr (lhst) && IsTypeFunc(rhst)) {
/* Assignment of function to function pointer is allowed, provided
* function signature for a function having an empty param list
* and returning int.
*/
- Warning (WARN_FUNC_WITHOUT_PROTO);
+ Warning ("Function call without a prototype");
Sym = AddGlobalSym (Ident, GetImplicitFuncType(), SC_EXTERN | SC_REF | SC_FUNC);
lval->e_tptr = Sym->Type;
lval->e_flags = E_MGLOBAL | E_MCONST | E_TGLAB;
/* Constant rvalue */
if (cond == 0 && lval.e_const == 0) {
g_jump (label);
- Warning (WARN_UNREACHABLE_CODE);
+ Warning ("Unreachable code");
} else if (cond && lval.e_const) {
g_jump (label);
}
FILE* F = fopen (Name, "r");
if (F == 0) {
/* Cannot open */
- Fatal (FAT_CANNOT_OPEN_INPUT, strerror (errno));
+ Fatal ("Cannot open input file `%s': %s", Name, strerror (errno));
}
/* Allocate a new AFile structure for the file */
/* Check for the maximum include nesting */
if (CollCount (&AFiles) > MAX_INC_NESTING) {
- PPError (ERR_INCLUDE_NESTING);
+ PPError ("Include nesting too deep");
return;
}
/* Search for the file */
N = FindInclude (Name, DirSpec);
if (N == 0) {
- PPError (ERR_INCLUDE_NOT_FOUND, Name);
+ PPError ("Include file `%s' not found", Name);
return;
}
F = fopen (IF->Name, "r");
if (F == 0) {
/* Error opening the file */
- PPError (ERR_INCLUDE_OPEN_FAILURE, IF->Name, strerror (errno));
+ PPError ("Cannot open include file `%s': %s", IF->Name, strerror (errno));
return;
}
/* Add one character to the literal pool */
{
if (LiteralOffs >= LITPOOL_SIZE) {
- Fatal (FAT_OUT_OF_STRSPACE);
+ Fatal ("Out of literal space");
}
LiteralPool[LiteralOffs++] = C;
}
if (IsTypeFunc (Decl.Type)) {
/* Function prototypes are always external */
if ((SC & SC_EXTERN) == 0) {
- Warning (WARN_FUNC_MUST_BE_EXTERN);
+ Warning ("Function must be extern");
}
SC |= SC_FUNC | SC_EXTERN;
default:
AbEnd ("Unknown target system type");
- }
+ }
/* Initialize the translation tables for the target system */
TgtTranslateInit ();
/* Open the file */
FILE* F = fopen (DepName, "w");
if (F == 0) {
- Fatal (FAT_CANNOT_OPEN_OUTPUT, strerror (errno));
+ Fatal ("Cannot open dependency file `%s': %s", DepName, strerror (errno));
}
/* Write the dependencies to the file */
/* Close the file, check for errors */
if (fclose (F) != 0) {
remove (DepName);
- Fatal (FAT_CANNOT_WRITE_OUTPUT);
+ Fatal ("Cannot write to dependeny file (disk full?)");
}
/* Free the name */
/* Open the file */
F = fopen (OutputFile, "w");
if (F == 0) {
- Fatal (FAT_CANNOT_OPEN_OUTPUT, strerror (errno));
+ Fatal ("Cannot open output file `%s': %s", OutputFile, strerror (errno));
}
/* Write the output to the file */
/* Close the file, check for errors */
if (fclose (F) != 0) {
remove (OutputFile);
- Fatal (FAT_CANNOT_WRITE_OUTPUT);
+ Fatal ("Cannot write to output file (disk full?)");
}
/* Create dependencies if requested */
Func (Name);
} else {
-
+
/* Segment name is invalid */
Error (ERR_ILLEGAL_SEG_NAME, Name);
* for unknown pragmas, however, we're allowed to warn - and we will
* do so. Otherwise one typo may give you hours of bug hunting...
*/
- Warning (WARN_UNKNOWN_PRAGMA);
+ Warning ("Unknown #pragma `%s'", CurTok.Ident);
return;
}
while (CurC != '*' || NextC != '/') {
if (CurC == '\0') {
if (NextLine () == 0) {
- PPError (ERR_EOF_IN_COMMENT, StartingLine);
+ PPError ("End-of-file reached in comment starting at line %u",
+ StartingLine);
return;
}
} else {
if (CurC == '/' && NextC == '*') {
- PPWarning (WARN_NESTED_COMMENT);
+ PPWarning ("`/*' found inside a comment");
}
NextChar ();
}
/* Get macro symbol name. If error, print message and clear line. */
{
if (IsSym (Ident) == 0) {
- PPError (ERR_IDENT_EXPECTED);
+ PPError ("Identifier expected");
ClearLine ();
return 0;
} else {
/* Expect an argument list */
SkipBlank ();
if (CurC != '(') {
- PPError (ERR_ILLEGAL_MACRO_CALL);
+ PPError ("Illegal macro call");
return 0;
}
/* Compare formal argument count with actual */
if (M->ArgCount != ArgCount) {
- PPError (ERR_MACRO_ARGCOUNT);
+ PPError ("Macro argument count mismatch");
/* Be sure to make enough empty arguments available */
while (ArgCount < M->ArgCount) {
M->ActualArgs [ArgCount++] = "";
/* Check for a right paren and eat it if we find one */
if (CurC != ')') {
- PPError (ERR_RPAREN_EXPECTED);
+ PPError ("`)' expected");
ClearLine ();
return;
}
*/
if (Existing) {
if (MacroCmp (M, Existing) != 0) {
- PPError (ERR_MACRO_REDEF);
+ PPError ("Macro redefinition is not identical");
}
}
}
SkipBlank();
}
if (!IsIdent (CurC)) {
- PPError (ERR_IDENT_EXPECTED);
+ PPError ("Identifier expected");
*mptr++ = '0';
} else {
SymName (Ident);
if (HaveParen) {
SkipBlank();
if (CurC != ')') {
- PPError (ERR_RPAREN_EXPECTED);
+ PPError ("`)' expected");
} else {
NextChar ();
}
break;
default:
- PPError (ERR_INCLUDE_LTERM_EXPECTED);
+ PPError ("`\"' or `<' expected");
goto Done;
}
NextChar ();
/* Check if we got a terminator */
if (CurC != RTerm) {
/* No terminator found */
- PPError (ERR_INCLUDE_RTERM_EXPECTED);
+ PPError ("Missing terminator or file name too long");
goto Done;
}
{
SkipBlank ();
if (CurC == '\0') {
- PPError (ERR_INVALID_USER_ERROR);
+ PPError ("Invalid #error directive");
} else {
- PPError (ERR_USER_ERROR, lptr);
+ PPError ("#error: %s", lptr);
}
/* clear rest of line */
continue;
}
if (!IsSym (Directive)) {
- PPError (ERR_CPP_DIRECTIVE_EXPECTED);
+ PPError ("Preprocessor directive expected");
ClearLine ();
} else {
switch (searchtok (Directive, pre_toks)) {
}
s_ifdef[i_ifdef] ^= 2;
} else {
- PPError (ERR_UNEXPECTED_CPP_ELSE);
+ PPError ("Unexpected `#else'");
}
break;
if (i_ifdef >= 0) {
Skip = s_ifdef[i_ifdef--] & 1;
} else {
- PPError (ERR_UNEXPECTED_CPP_ENDIF);
+ PPError ("Unexpected `#endif'");
}
break;
case PP_LINE:
/* Not allowed in strict ANSI mode */
if (ANSI) {
- PPError (ERR_CPP_DIRECTIVE_EXPECTED);
+ PPError ("Preprocessor directive expected");
ClearLine ();
}
break;
break;
default:
- PPError (ERR_CPP_DIRECTIVE_EXPECTED);
+ PPError ("Preprocessor directive expected");
ClearLine ();
}
}
}
if (NextLine () == 0) {
if (i_ifdef >= 0) {
- PPError (ERR_CPP_ENDIF_EXPECTED);
+ PPError ("`#endif' expected");
}
return;
}
static void unknown (char C)
/* Error message for unknown character */
{
- Error (ERR_INVALID_CHAR, C);
+ MError ("Invalid input character with code %02X", C & 0xFF);
NextChar (); /* Skip */
}
while (CurC != '\"') {
if (CurC == '\0') {
- Error (ERR_UNEXPECTED_NEWLINE);
+ MError ("Unexpected newline");
break;
}
AddLiteralChar (ParseChar ());
* warning.
*/
if (k <= 0xFFFF && (types & IT_UINT) == 0 && !HaveSuffix) {
- Warning (WARN_CONSTANT_IS_LONG);
+ Warning ("Constant is long");
}
}
if (k > 0xFFFF) {
} while (CurC == ' ');
if (!IsSym (token) || strcmp (token, "pragma") != 0) {
/* OOPS - should not happen */
- Error (ERR_CPP_DIRECTIVE_EXPECTED);
+ MError ("Preprocessor directive expected");
}
nxttok = TOK_PRAGMA;
break;
/* common */
#include "xmalloc.h"
-
+
/* cc65 */
#include "asmcode.h"
#include "asmlabel.h"
/* Check if we have any labels */
if (lcount == 0) {
- Warning (WARN_NO_CASE_LABELS);
+ Warning ("No case labels");
}
/* Eat the closing curly brace */
while (curtok != TOK_RCURLY) {
if (curtok == TOK_CASE || curtok == TOK_DEFAULT) {
if (lcount >= CASE_MAX) {
- Fatal (FAT_TOO_MANY_CASE_LABELS);
+ Fatal ("Too many case labels");
}
label = GetLabel ();
do {
/* Check if we have any labels */
if (lcount == 0) {
- Warning (WARN_NO_CASE_LABELS);
+ Warning ("No case labels");
}
/* Eat the closing curly brace */
if (((Flags & SC_AUTO) || (Flags & SC_STATIC)) && (Flags & SC_EXTERN) == 0) {
if ((Flags & SC_DEF) && !(Flags & SC_REF)) {
if (Flags & SC_PARAM) {
- Warning (WARN_UNUSED_PARM, Entry->Name);
+ Warning ("Parameter `%s' is never used", Entry->Name);
} else {
- Warning (WARN_UNUSED_ITEM, Entry->Name);
+ Warning ("`%s' is defined but never used", Entry->Name);
}
}
}
Error (ERR_UNDEFINED_LABEL, Entry->Name);
} else if ((Flags & SC_REF) == 0) {
/* Defined but not used */
- Warning (WARN_UNUSED_ITEM, Entry->Name);
+ Warning ("`%s' is defined but never used", Entry->Name);
}
}