Added hierarchy info about source file inclusion in diagnostic output.
Fixed presumed names of source files in disgnosis. Fixed line number of source files in debug output.
This commit is contained in:
@@ -1471,7 +1471,7 @@ void CS_Output (CodeSeg* S)
|
|||||||
/* Add line debug info */
|
/* Add line debug info */
|
||||||
if (DebugInfo) {
|
if (DebugInfo) {
|
||||||
WriteOutput ("\t.dbg\tline, \"%s\", %u\n",
|
WriteOutput ("\t.dbg\tline, \"%s\", %u\n",
|
||||||
GetInputName (LI), GetInputLine (LI));
|
GetActualFileName (LI), GetActualLineNum (LI));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Output the code */
|
/* Output the code */
|
||||||
|
|||||||
123
src/cc65/error.c
123
src/cc65/error.c
@@ -120,13 +120,46 @@ Collection DiagnosticStrBufs;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void PrintFileInclusionInfo (const LineInfo* LI)
|
||||||
|
/* Print hierarchy of file inclusion */
|
||||||
|
{
|
||||||
|
if (LI->IncFiles != 0) {
|
||||||
|
unsigned FileCount = CollCount (LI->IncFiles);
|
||||||
|
if (FileCount > 0) {
|
||||||
|
const char* Str = "In file included from %s:%u%c\n";
|
||||||
|
|
||||||
|
while (FileCount-- > 0) {
|
||||||
|
LineInfoFile* LIF = CollAtUnchecked (LI->IncFiles, FileCount);
|
||||||
|
char C = FileCount > 0 ? ',' : ':';
|
||||||
|
|
||||||
|
fprintf (stderr, Str, LIF->Name, LIF->LineNum, C);
|
||||||
|
Str = " from %s:%u%c\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static LineInfo* GetDiagnosticLI (void)
|
||||||
|
/* Get the line info where the diagnostic info refers to */
|
||||||
|
{
|
||||||
|
if (CurTok.LI) {
|
||||||
|
return CurTok.LI;
|
||||||
|
} else {
|
||||||
|
return GetCurLineInfo ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const char* GetDiagnosticFileName (void)
|
static const char* GetDiagnosticFileName (void)
|
||||||
/* Get the source file name where the diagnostic info refers to */
|
/* Get the source file name where the diagnostic info refers to */
|
||||||
{
|
{
|
||||||
if (CurTok.LI) {
|
if (CurTok.LI) {
|
||||||
return GetInputName (CurTok.LI);
|
return GetPresumedFileName (CurTok.LI);
|
||||||
} else {
|
} else {
|
||||||
return GetCurrentFilename ();
|
return GetCurrentFileName ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +169,7 @@ static unsigned GetDiagnosticLineNum (void)
|
|||||||
/* Get the source line number where the diagnostic info refers to */
|
/* Get the source line number where the diagnostic info refers to */
|
||||||
{
|
{
|
||||||
if (CurTok.LI) {
|
if (CurTok.LI) {
|
||||||
return GetInputLine (CurTok.LI);
|
return GetPresumedLineNum (CurTok.LI);
|
||||||
} else {
|
} else {
|
||||||
return GetCurrentLineNum ();
|
return GetCurrentLineNum ();
|
||||||
}
|
}
|
||||||
@@ -199,10 +232,18 @@ void Internal (const char* Format, ...)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void IntError (errcat_t EC, const char* Filename, unsigned LineNo, const char* Msg, va_list ap)
|
static void IntError (errcat_t EC, LineInfo* LI, const char* Msg, va_list ap)
|
||||||
/* Print an error message - internal function */
|
/* Print an error message - internal function */
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s:%u: Error: ", Filename, LineNo);
|
unsigned LineNo = GetPresumedLineNum (LI);
|
||||||
|
|
||||||
|
/* Print file inclusion if appropriate */
|
||||||
|
if (HasFileInclusionChanged (LI)) {
|
||||||
|
PrintFileInclusionInfo (LI);
|
||||||
|
}
|
||||||
|
RememberCheckedLI (LI);
|
||||||
|
|
||||||
|
fprintf (stderr, "%s:%u: Error: ", GetPresumedFileName (LI), LineNo);
|
||||||
vfprintf (stderr, Msg, ap);
|
vfprintf (stderr, Msg, ap);
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
|
|
||||||
@@ -229,23 +270,23 @@ static void IntError (errcat_t EC, const char* Filename, unsigned LineNo, const
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Error (const char* Format, ...)
|
void LIError (errcat_t EC, LineInfo* LI, const char* Format, ...)
|
||||||
/* Print an error message */
|
/* Print an error message with the line info given explicitly */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntError (EC_PARSER, GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap);
|
IntError (EC, LI, Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void LIError (errcat_t EC, const LineInfo* LI, const char* Format, ...)
|
void Error (const char* Format, ...)
|
||||||
/* Print an error message with the line info given explicitly */
|
/* Print an error message */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntError (EC, GetInputName (LI), GetInputLine (LI), Format, ap);
|
IntError (EC_PARSER, GetDiagnosticLI (), Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +297,7 @@ void PPError (const char* Format, ...)
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntError (EC_PP, GetCurrentFilename(), GetCurrentLineNum(), Format, ap);
|
IntError (EC_PP, GetCurLineInfo (), Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,17 +309,25 @@ void PPError (const char* Format, ...)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void IntWarning (errcat_t EC, const char* Filename, unsigned LineNo, const char* Msg, va_list ap)
|
static void IntWarning (errcat_t EC, LineInfo* LI, const char* Msg, va_list ap)
|
||||||
/* Print a warning message - internal function */
|
/* Print a warning message - internal function */
|
||||||
{
|
{
|
||||||
if (IS_Get (&WarningsAreErrors)) {
|
if (IS_Get (&WarningsAreErrors)) {
|
||||||
|
|
||||||
/* Treat the warning as an error */
|
/* Treat the warning as an error */
|
||||||
IntError (EC, Filename, LineNo, Msg, ap);
|
IntError (EC, LI, Msg, ap);
|
||||||
|
|
||||||
} else if (IS_Get (&WarnEnable)) {
|
} else if (IS_Get (&WarnEnable)) {
|
||||||
|
|
||||||
fprintf (stderr, "%s:%u: Warning: ", Filename, LineNo);
|
unsigned LineNo = GetPresumedLineNum (LI);
|
||||||
|
|
||||||
|
/* Print file inclusion if appropriate */
|
||||||
|
if (HasFileInclusionChanged (LI)) {
|
||||||
|
PrintFileInclusionInfo (LI);
|
||||||
|
}
|
||||||
|
RememberCheckedLI (LI);
|
||||||
|
|
||||||
|
fprintf (stderr, "%s:%u: Warning: ", GetPresumedFileName (LI), LineNo);
|
||||||
vfprintf (stderr, Msg, ap);
|
vfprintf (stderr, Msg, ap);
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
|
|
||||||
@@ -297,23 +346,23 @@ static void IntWarning (errcat_t EC, const char* Filename, unsigned LineNo, cons
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Warning (const char* Format, ...)
|
void LIWarning (errcat_t EC, LineInfo* LI, const char* Format, ...)
|
||||||
/* Print a warning message */
|
/* Print a warning message with the line info given explicitly */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntWarning (EC_PARSER, GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap);
|
IntWarning (EC, LI, Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void LIWarning (errcat_t EC, const LineInfo* LI, const char* Format, ...)
|
void Warning (const char* Format, ...)
|
||||||
/* Print a warning message with the line info given explicitly */
|
/* Print a warning message */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntWarning (EC, GetInputName (LI), GetInputLine (LI), Format, ap);
|
IntWarning (EC_PARSER, GetDiagnosticLI (), Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,7 +373,7 @@ void PPWarning (const char* Format, ...)
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntWarning (EC_PP, GetCurrentFilename(), GetCurrentLineNum(), Format, ap);
|
IntWarning (EC_PP, GetCurLineInfo (), Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,33 +414,33 @@ void ListWarnings (FILE* F)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void IntNote (const char* Filename, unsigned LineNo, const char* Msg, va_list ap)
|
static void IntNote (const LineInfo* LI, const char* Msg, va_list ap)
|
||||||
/* Print a note message - internal function */
|
/* Print a note message - internal function */
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s:%u: Note: ", Filename, LineNo);
|
fprintf (stderr, "%s:%u: Note: ", GetPresumedFileName (LI), GetPresumedLineNum (LI));
|
||||||
vfprintf (stderr, Msg, ap);
|
vfprintf (stderr, Msg, ap);
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Note (const char* Format, ...)
|
|
||||||
/* Print a note message */
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start (ap, Format);
|
|
||||||
IntNote (GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap);
|
|
||||||
va_end (ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void LINote (const LineInfo* LI, const char* Format, ...)
|
void LINote (const LineInfo* LI, const char* Format, ...)
|
||||||
/* Print a note message with the line info given explicitly */
|
/* Print a note message with the line info given explicitly */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntNote (GetInputName (LI), GetInputLine (LI), Format, ap);
|
IntNote (LI, Format, ap);
|
||||||
|
va_end (ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Note (const char* Format, ...)
|
||||||
|
/* Print a note message */
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start (ap, Format);
|
||||||
|
IntNote (GetDiagnosticLI (), Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,7 +451,7 @@ void PPNote (const char* Format, ...)
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntNote (GetCurrentFilename(), GetCurrentLineNum(), Format, ap);
|
IntNote (GetDiagnosticLI (), Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,6 +100,9 @@ struct StrBuf;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void PrintFileInclusionInfo (const LineInfo* LI);
|
||||||
|
/* Print hierarchy of file inclusion */
|
||||||
|
|
||||||
void Fatal (const char* Format, ...) attribute ((noreturn, format (printf, 1, 2)));
|
void Fatal (const char* Format, ...) attribute ((noreturn, format (printf, 1, 2)));
|
||||||
/* Print a message about a fatal error and die */
|
/* Print a message about a fatal error and die */
|
||||||
|
|
||||||
@@ -109,7 +112,7 @@ void Internal (const char* Format, ...) attribute ((noreturn, format (printf, 1,
|
|||||||
void Error (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
void Error (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||||
/* Print an error message */
|
/* Print an error message */
|
||||||
|
|
||||||
void LIError (errcat_t EC, const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 3, 4)));
|
void LIError (errcat_t EC, LineInfo* LI, const char* Format, ...) attribute ((format (printf, 3, 4)));
|
||||||
/* Print an error message with the line info given explicitly */
|
/* Print an error message with the line info given explicitly */
|
||||||
|
|
||||||
void PPError (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
void PPError (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||||
@@ -118,7 +121,7 @@ void PPError (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
|||||||
void Warning (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
void Warning (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||||
/* Print a warning message */
|
/* Print a warning message */
|
||||||
|
|
||||||
void LIWarning (errcat_t EC, const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 3, 4)));
|
void LIWarning (errcat_t EC, LineInfo* LI, const char* Format, ...) attribute ((format (printf, 3, 4)));
|
||||||
/* Print a warning message with the line info given explicitly */
|
/* Print a warning message with the line info given explicitly */
|
||||||
|
|
||||||
void PPWarning (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
void PPWarning (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||||
|
|||||||
165
src/cc65/input.c
165
src/cc65/input.c
@@ -91,10 +91,11 @@ struct IFile {
|
|||||||
/* Struct that describes an active input file */
|
/* Struct that describes an active input file */
|
||||||
typedef struct AFile AFile;
|
typedef struct AFile AFile;
|
||||||
struct AFile {
|
struct AFile {
|
||||||
unsigned Line; /* Line number for this file */
|
unsigned LineNum; /* Actual line number for this file */
|
||||||
FILE* F; /* Input file stream */
|
FILE* F; /* Input file stream */
|
||||||
IFile* Input; /* Points to corresponding IFile */
|
IFile* Input; /* Points to corresponding IFile */
|
||||||
int SearchPath; /* True if we've added a path for this file */
|
int SearchPath; /* True if we've added a path for this file */
|
||||||
|
unsigned LineOffs; /* Offset to presumed line number for this file */
|
||||||
char* PName; /* Presumed name of the file */
|
char* PName; /* Presumed name of the file */
|
||||||
PPIfStack IfStack; /* PP #if stack */
|
PPIfStack IfStack; /* PP #if stack */
|
||||||
int MissingNL; /* Last input line was missing a newline */
|
int MissingNL; /* Last input line was missing a newline */
|
||||||
@@ -111,6 +112,7 @@ static Collection* CurrentInputStack;
|
|||||||
|
|
||||||
/* Counter for the __COUNTER__ macro */
|
/* Counter for the __COUNTER__ macro */
|
||||||
static unsigned MainFileCounter;
|
static unsigned MainFileCounter;
|
||||||
|
LineInfo* PrevDiagnosticLI;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -163,10 +165,11 @@ static AFile* NewAFile (IFile* IF, FILE* F)
|
|||||||
AFile* AF = (AFile*) xmalloc (sizeof (AFile));
|
AFile* AF = (AFile*) xmalloc (sizeof (AFile));
|
||||||
|
|
||||||
/* Initialize the fields */
|
/* Initialize the fields */
|
||||||
AF->Line = 0;
|
AF->LineNum = 0;
|
||||||
AF->F = F;
|
AF->F = F;
|
||||||
AF->Input = IF;
|
AF->Input = IF;
|
||||||
AF->PName = 0;
|
AF->LineOffs = 0;
|
||||||
|
AF->PName = 0;
|
||||||
AF->IfStack.Index = -1;
|
AF->IfStack.Index = -1;
|
||||||
AF->MissingNL = 0;
|
AF->MissingNL = 0;
|
||||||
|
|
||||||
@@ -285,7 +288,7 @@ void OpenMainFile (const char* Name)
|
|||||||
/* Update the line infos, so we have a valid line info even at start of
|
/* Update the line infos, so we have a valid line info even at start of
|
||||||
** the main file before the first line is read.
|
** the main file before the first line is read.
|
||||||
*/
|
*/
|
||||||
UpdateLineInfo (MainFile->Input, MainFile->Line, Line);
|
UpdateCurrentLineInfo (Line);
|
||||||
|
|
||||||
/* Initialize the __COUNTER__ counter */
|
/* Initialize the __COUNTER__ counter */
|
||||||
MainFileCounter = 0;
|
MainFileCounter = 0;
|
||||||
@@ -553,7 +556,7 @@ int NextLine (void)
|
|||||||
if (!Input->MissingNL || SB_NotEmpty (Line)) {
|
if (!Input->MissingNL || SB_NotEmpty (Line)) {
|
||||||
|
|
||||||
/* Accept files without a newline at the end */
|
/* Accept files without a newline at the end */
|
||||||
++Input->Line;
|
++Input->LineNum;
|
||||||
|
|
||||||
/* Assume no new line */
|
/* Assume no new line */
|
||||||
Input->MissingNL = 1;
|
Input->MissingNL = 1;
|
||||||
@@ -569,7 +572,7 @@ int NextLine (void)
|
|||||||
if (C == '\n') {
|
if (C == '\n') {
|
||||||
|
|
||||||
/* We got a new line */
|
/* We got a new line */
|
||||||
++Input->Line;
|
++Input->LineNum;
|
||||||
|
|
||||||
/* If the \n is preceeded by a \r, remove the \r, so we can read
|
/* If the \n is preceeded by a \r, remove the \r, so we can read
|
||||||
** DOS/Windows files under *nix.
|
** DOS/Windows files under *nix.
|
||||||
@@ -605,7 +608,7 @@ int NextLine (void)
|
|||||||
InitLine (Line);
|
InitLine (Line);
|
||||||
|
|
||||||
/* Create line information for this line */
|
/* Create line information for this line */
|
||||||
UpdateLineInfo (Input->Input, Input->Line, Line);
|
UpdateCurrentLineInfo (Line);
|
||||||
|
|
||||||
/* Done */
|
/* Done */
|
||||||
return C != EOF || SB_NotEmpty (Line);
|
return C != EOF || SB_NotEmpty (Line);
|
||||||
@@ -645,15 +648,145 @@ int PreprocessNextLine (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char* GetInputFile (const struct IFile* IF)
|
static LineInfoFile* NewLineInfoFile (const AFile* AF)
|
||||||
/* Return a filename from an IFile struct */
|
{
|
||||||
|
const char* Name = AF->PName == 0 ? AF->Input->Name : AF->PName;
|
||||||
|
unsigned Len = strlen (Name);
|
||||||
|
|
||||||
|
/* Allocate memory for the file info and the file name */
|
||||||
|
LineInfoFile* LIF = xmalloc (sizeof (LineInfoFile) + Len);
|
||||||
|
|
||||||
|
/* Copy info */
|
||||||
|
LIF->InputFile = AF->Input;
|
||||||
|
LIF->LineNum = AF->LineNum + AF->LineOffs;
|
||||||
|
memcpy (LIF->Name, Name, Len + 1);
|
||||||
|
|
||||||
|
return LIF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void GetFileInclusionInfo (struct LineInfo* LI)
|
||||||
|
/* Get info about source file inclusion for LineInfo struct */
|
||||||
|
{
|
||||||
|
unsigned FileCount = CollCount (&AFiles);
|
||||||
|
|
||||||
|
CHECK (FileCount > 0);
|
||||||
|
|
||||||
|
/* Get the correct index */
|
||||||
|
--FileCount;
|
||||||
|
|
||||||
|
if (LI->IncFiles != 0) {
|
||||||
|
FreeFileInclusionInfo (LI);
|
||||||
|
}
|
||||||
|
LI->IncFiles = 0;
|
||||||
|
|
||||||
|
if (LI->File != 0) {
|
||||||
|
xfree (LI->File);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy info from the AFile */
|
||||||
|
LI->File = NewLineInfoFile (CollAtUnchecked (&AFiles, FileCount));
|
||||||
|
|
||||||
|
/* Remember the actual line number */
|
||||||
|
LI->ActualLineNum = ((AFile*)CollAtUnchecked (&AFiles, FileCount))->LineNum;
|
||||||
|
|
||||||
|
if (FileCount > 0) {
|
||||||
|
/* The file is included from another */
|
||||||
|
|
||||||
|
/* Always use a new collection */
|
||||||
|
LI->IncFiles = NewCollection ();
|
||||||
|
|
||||||
|
while (FileCount-- > 0) {
|
||||||
|
/* Copy info from the AFile */
|
||||||
|
LineInfoFile* LIF = NewLineInfoFile (CollAtUnchecked (&AFiles, FileCount));
|
||||||
|
|
||||||
|
/* Add this file */
|
||||||
|
CollAppend (LI->IncFiles, LIF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FreeFileInclusionInfo (struct LineInfo* LI)
|
||||||
|
/* Free info about source file inclusion for LineInfo struct */
|
||||||
|
{
|
||||||
|
if (LI->File != 0) {
|
||||||
|
xfree (LI->File);
|
||||||
|
LI->File = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LI->IncFiles != 0) {
|
||||||
|
unsigned I;
|
||||||
|
for (I = 0; I < CollCount (LI->IncFiles); ++I) {
|
||||||
|
CollAtUnchecked (LI->IncFiles, I);
|
||||||
|
}
|
||||||
|
FreeCollection (LI->IncFiles);
|
||||||
|
LI->IncFiles = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int IsDifferentLineInfoFile (const LineInfoFile* Lhs, const LineInfoFile* Rhs)
|
||||||
|
/* Return true if the two files are different */
|
||||||
|
{
|
||||||
|
/* If the input files are the same but their presumed names are different,
|
||||||
|
** we still consider the files same.
|
||||||
|
*/
|
||||||
|
return Lhs->InputFile != Rhs->InputFile || Lhs->LineNum != Rhs->LineNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int HasFileInclusionChanged (const struct LineInfo* LI)
|
||||||
|
/* Return true if file inclusion has changed from last time */
|
||||||
|
{
|
||||||
|
if (LI->File != 0) {
|
||||||
|
LineInfo* PrevLI = GetPrevCheckedLI ();
|
||||||
|
|
||||||
|
if (LI == PrevLI) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PrevLI == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LI->IncFiles != 0) {
|
||||||
|
unsigned I;
|
||||||
|
|
||||||
|
if (PrevLI->IncFiles == 0 ||
|
||||||
|
CollCount (LI->IncFiles) != CollCount (PrevLI->IncFiles)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (I = 0; I < CollCount (LI->IncFiles); ++I) {
|
||||||
|
/* If this refers to a different file, then the inclusion has changed */
|
||||||
|
if (IsDifferentLineInfoFile (CollAtUnchecked (LI->IncFiles, I),
|
||||||
|
CollAtUnchecked (PrevLI->IncFiles, I))) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unchanged */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char* GetInputFileName (const struct IFile* IF)
|
||||||
|
/* Return the name of the file from an IFile struct */
|
||||||
{
|
{
|
||||||
return IF->Name;
|
return IF->Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char* GetCurrentFilename (void)
|
const char* GetCurrentFileName (void)
|
||||||
/* Return the name of the current input file */
|
/* Return the name of the current input file */
|
||||||
{
|
{
|
||||||
unsigned AFileCount = CollCount (&AFiles);
|
unsigned AFileCount = CollCount (&AFiles);
|
||||||
@@ -674,7 +807,7 @@ unsigned GetCurrentLineNum (void)
|
|||||||
unsigned AFileCount = CollCount (&AFiles);
|
unsigned AFileCount = CollCount (&AFiles);
|
||||||
if (AFileCount > 0) {
|
if (AFileCount > 0) {
|
||||||
const AFile* AF = CollLast (&AFiles);
|
const AFile* AF = CollLast (&AFiles);
|
||||||
return AF->Line;
|
return AF->LineNum + AF->LineOffs;
|
||||||
} else {
|
} else {
|
||||||
/* No open file */
|
/* No open file */
|
||||||
return 0;
|
return 0;
|
||||||
@@ -684,18 +817,18 @@ unsigned GetCurrentLineNum (void)
|
|||||||
|
|
||||||
|
|
||||||
void SetCurrentLineNum (unsigned LineNum)
|
void SetCurrentLineNum (unsigned LineNum)
|
||||||
/* Set the line number in the current input file */
|
/* Set the presumed line number in the current input file */
|
||||||
{
|
{
|
||||||
unsigned AFileCount = CollCount (&AFiles);
|
unsigned AFileCount = CollCount (&AFiles);
|
||||||
if (AFileCount > 0) {
|
if (AFileCount > 0) {
|
||||||
AFile* AF = CollLast (&AFiles);
|
AFile* AF = CollLast (&AFiles);
|
||||||
AF->Line = LineNum;
|
AF->LineOffs = LineNum - AF->LineNum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SetCurrentFilename (const char* Name)
|
void SetCurrentFileName (const char* Name)
|
||||||
/* Set the presumed name of the current input file */
|
/* Set the presumed name of the current input file */
|
||||||
{
|
{
|
||||||
unsigned AFileCount = CollCount (&AFiles);
|
unsigned AFileCount = CollCount (&AFiles);
|
||||||
|
|||||||
@@ -52,6 +52,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Forwards */
|
||||||
|
struct IFile;
|
||||||
|
struct LineInfo;
|
||||||
|
|
||||||
/* An enum that describes different types of input files. The members are
|
/* An enum that describes different types of input files. The members are
|
||||||
** choosen so that it is possible to combine them to bitsets
|
** choosen so that it is possible to combine them to bitsets
|
||||||
*/
|
*/
|
||||||
@@ -61,9 +65,6 @@ typedef enum {
|
|||||||
IT_USRINC = 0x04, /* User include file (using "") */
|
IT_USRINC = 0x04, /* User include file (using "") */
|
||||||
} InputType;
|
} InputType;
|
||||||
|
|
||||||
/* Forward for an IFile structure */
|
|
||||||
struct IFile;
|
|
||||||
|
|
||||||
/* The current input line */
|
/* The current input line */
|
||||||
extern StrBuf* Line;
|
extern StrBuf* Line;
|
||||||
|
|
||||||
@@ -125,10 +126,19 @@ int PreprocessNextLine (void);
|
|||||||
** main file.
|
** main file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const char* GetInputFile (const struct IFile* IF);
|
void GetFileInclusionInfo (struct LineInfo* LI);
|
||||||
/* Return a filename from an IFile struct */
|
/* Get info about source file inclusion for LineInfo struct */
|
||||||
|
|
||||||
const char* GetCurrentFilename (void);
|
void FreeFileInclusionInfo (struct LineInfo* LI);
|
||||||
|
/* Free info about source file inclusion for LineInfo struct */
|
||||||
|
|
||||||
|
int HasFileInclusionChanged (const struct LineInfo* LI);
|
||||||
|
/* Return true if file inclusion has changed from last time */
|
||||||
|
|
||||||
|
const char* GetInputFileName (const struct IFile* IF);
|
||||||
|
/* Return the name of the file from an IFile struct */
|
||||||
|
|
||||||
|
const char* GetCurrentFileName (void);
|
||||||
/* Return the name of the current input file */
|
/* Return the name of the current input file */
|
||||||
|
|
||||||
unsigned GetCurrentLineNum (void);
|
unsigned GetCurrentLineNum (void);
|
||||||
@@ -137,7 +147,7 @@ unsigned GetCurrentLineNum (void);
|
|||||||
void SetCurrentLineNum (unsigned LineNum);
|
void SetCurrentLineNum (unsigned LineNum);
|
||||||
/* Set the line number in the current input file */
|
/* Set the line number in the current input file */
|
||||||
|
|
||||||
void SetCurrentFilename (const char* Name);
|
void SetCurrentFileName (const char* Name);
|
||||||
/* Set the presumed name of the current input file */
|
/* Set the presumed name of the current input file */
|
||||||
|
|
||||||
unsigned GetCurrentCounter (void);
|
unsigned GetCurrentCounter (void);
|
||||||
|
|||||||
@@ -56,6 +56,9 @@
|
|||||||
/* Global pointer to line information for the current line */
|
/* Global pointer to line information for the current line */
|
||||||
static LineInfo* CurLineInfo = 0;
|
static LineInfo* CurLineInfo = 0;
|
||||||
|
|
||||||
|
/* Global pointer to previously checked line information about file inclusion hierarchy */
|
||||||
|
static LineInfo* PrevCheckedLI = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -64,7 +67,7 @@ static LineInfo* CurLineInfo = 0;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static LineInfo* NewLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* Line)
|
static LineInfo* NewLineInfo (const StrBuf* Line)
|
||||||
/* Create and return a new line info. Ref count will be 1. */
|
/* Create and return a new line info. Ref count will be 1. */
|
||||||
{
|
{
|
||||||
unsigned Len;
|
unsigned Len;
|
||||||
@@ -87,8 +90,9 @@ static LineInfo* NewLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* L
|
|||||||
|
|
||||||
/* Initialize the fields */
|
/* Initialize the fields */
|
||||||
LI->RefCount = 1;
|
LI->RefCount = 1;
|
||||||
LI->InputFile = F;
|
LI->File = 0;
|
||||||
LI->LineNum = LineNum;
|
LI->IncFiles = 0;
|
||||||
|
GetFileInclusionInfo (LI);
|
||||||
|
|
||||||
/* Copy the line, replacing tabs by spaces in the given line since tabs
|
/* Copy the line, replacing tabs by spaces in the given line since tabs
|
||||||
** will give rather arbitrary results when used in the output later, and
|
** will give rather arbitrary results when used in the output later, and
|
||||||
@@ -117,6 +121,7 @@ static LineInfo* NewLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* L
|
|||||||
static void FreeLineInfo (LineInfo* LI)
|
static void FreeLineInfo (LineInfo* LI)
|
||||||
/* Free a LineInfo structure */
|
/* Free a LineInfo structure */
|
||||||
{
|
{
|
||||||
|
FreeFileInclusionInfo (LI);
|
||||||
xfree (LI);
|
xfree (LI);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,8 +161,8 @@ LineInfo* GetCurLineInfo (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void UpdateLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* Line)
|
void UpdateCurrentLineInfo (const StrBuf* Line)
|
||||||
/* Update the line info - called if a new line is read */
|
/* Update the current line info - called if a new line is read */
|
||||||
{
|
{
|
||||||
/* If a current line info exists, release it */
|
/* If a current line info exists, release it */
|
||||||
if (CurLineInfo) {
|
if (CurLineInfo) {
|
||||||
@@ -172,23 +177,60 @@ void UpdateLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* Line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new line info */
|
/* Create a new line info */
|
||||||
CurLineInfo = NewLineInfo (F, LineNum, Line);
|
CurLineInfo = NewLineInfo (Line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char* GetInputName (const LineInfo* LI)
|
void RememberCheckedLI (LineInfo* LI)
|
||||||
/* Return the file name from a line info */
|
/* Remember the latest checked line info struct */
|
||||||
|
{
|
||||||
|
if (PrevCheckedLI != LI) {
|
||||||
|
if (PrevCheckedLI != 0) {
|
||||||
|
ReleaseLineInfo (PrevCheckedLI);
|
||||||
|
}
|
||||||
|
PrevCheckedLI = UseLineInfo (LI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LineInfo* GetPrevCheckedLI (void)
|
||||||
|
/* Get the latest checked line info struct */
|
||||||
|
{
|
||||||
|
return PrevCheckedLI;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char* GetPresumedFileName (const LineInfo* LI)
|
||||||
|
/* Return the presumed file name from a line info */
|
||||||
{
|
{
|
||||||
PRECONDITION (LI != 0);
|
PRECONDITION (LI != 0);
|
||||||
return GetInputFile (LI->InputFile);
|
return LI->File->Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned GetInputLine (const LineInfo* LI)
|
unsigned GetPresumedLineNum (const LineInfo* LI)
|
||||||
/* Return the line number from a line info */
|
/* Return the presumed line number from a line info */
|
||||||
{
|
{
|
||||||
PRECONDITION (LI != 0);
|
PRECONDITION (LI != 0);
|
||||||
return LI->LineNum;
|
return LI->File->LineNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char* GetActualFileName (const struct LineInfo* LI)
|
||||||
|
/* Return the actual name of the source file from a line info struct */
|
||||||
|
{
|
||||||
|
return LI->File != 0 ? GetInputFileName (LI->File->InputFile) : "<out of filescope>";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned GetActualLineNum (const struct LineInfo* LI)
|
||||||
|
/* Return the actual line number of the source file from a line info struct */
|
||||||
|
{
|
||||||
|
return LI->ActualLineNum;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,15 +60,24 @@ struct IFile;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Struct that describes an input file for line info */
|
||||||
|
typedef struct LineInfoFile LineInfoFile;
|
||||||
|
struct LineInfoFile {
|
||||||
|
struct IFile* InputFile; /* Points to corresponding IFile */
|
||||||
|
unsigned LineNum; /* Presumed line number for this file */
|
||||||
|
char Name[1]; /* Presumed name of the file */
|
||||||
|
};
|
||||||
|
|
||||||
/* The text for the actual line is allocated at the end of the structure, so
|
/* The text for the actual line is allocated at the end of the structure, so
|
||||||
** the size of the structure varies.
|
** the size of the structure varies.
|
||||||
*/
|
*/
|
||||||
typedef struct LineInfo LineInfo;
|
typedef struct LineInfo LineInfo;
|
||||||
struct LineInfo {
|
struct LineInfo {
|
||||||
unsigned RefCount; /* Reference counter */
|
unsigned RefCount; /* Reference counter */
|
||||||
struct IFile* InputFile; /* Input file for this line */
|
LineInfoFile* File; /* Presumed input files for this line */
|
||||||
unsigned LineNum; /* Line number */
|
unsigned ActualLineNum; /* Actual line number for this file */
|
||||||
char Line[1]; /* Source code line */
|
struct Collection* IncFiles; /* Presumed inclusion input files */
|
||||||
|
char Line[1]; /* Text of source code line */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -92,14 +101,26 @@ LineInfo* GetCurLineInfo (void);
|
|||||||
** increased, use UseLineInfo for that purpose.
|
** increased, use UseLineInfo for that purpose.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void UpdateLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* Line);
|
void UpdateCurrentLineInfo (const StrBuf* Line);
|
||||||
/* Update the line info - called if a new line is read */
|
/* Update the current line info - called if a new line is read */
|
||||||
|
|
||||||
const char* GetInputName (const LineInfo* LI);
|
void RememberCheckedLI (struct LineInfo* LI);
|
||||||
/* Return the file name from a line info */
|
/* Remember the latest checked line info struct */
|
||||||
|
|
||||||
unsigned GetInputLine (const LineInfo* LI);
|
LineInfo* GetPrevCheckedLI (void);
|
||||||
/* Return the line number from a line info */
|
/* Get the latest checked line info struct */
|
||||||
|
|
||||||
|
const char* GetPresumedFileName (const LineInfo* LI);
|
||||||
|
/* Return the presumed file name from a line info */
|
||||||
|
|
||||||
|
unsigned GetPresumedLineNum (const LineInfo* LI);
|
||||||
|
/* Return the presumed line number from a line info */
|
||||||
|
|
||||||
|
const char* GetActualFileName (const struct LineInfo* LI);
|
||||||
|
/* Return the actual name of the source file from a line info struct */
|
||||||
|
|
||||||
|
unsigned GetActualLineNum (const struct LineInfo* LI);
|
||||||
|
/* Return the actual line number of the source file from a line info struct */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -842,7 +842,7 @@ static void AddPreLine (StrBuf* Str)
|
|||||||
SB_AppendChar (Str, '\n');
|
SB_AppendChar (Str, '\n');
|
||||||
}
|
}
|
||||||
SB_Printf (&Comment, "#line %u \"%s\"\n",
|
SB_Printf (&Comment, "#line %u \"%s\"\n",
|
||||||
GetCurrentLineNum () - ContinuedLines, GetCurrentFilename ());
|
GetCurrentLineNum () - ContinuedLines, GetCurrentFileName ());
|
||||||
SB_Append (Str, &Comment);
|
SB_Append (Str, &Comment);
|
||||||
} else {
|
} else {
|
||||||
/* Output new lines */
|
/* Output new lines */
|
||||||
@@ -2943,7 +2943,7 @@ static void DoLine (void)
|
|||||||
StrBuf Filename = AUTO_STRBUF_INITIALIZER;
|
StrBuf Filename = AUTO_STRBUF_INITIALIZER;
|
||||||
if (SB_GetString (Line, &Filename)) {
|
if (SB_GetString (Line, &Filename)) {
|
||||||
SB_Terminate (&Filename);
|
SB_Terminate (&Filename);
|
||||||
SetCurrentFilename (SB_GetConstBuf (&Filename));
|
SetCurrentFileName (SB_GetConstBuf (&Filename));
|
||||||
} else {
|
} else {
|
||||||
PPError ("Invalid filename for #line directive");
|
PPError ("Invalid filename for #line directive");
|
||||||
LineNum = 0;
|
LineNum = 0;
|
||||||
@@ -3220,7 +3220,7 @@ void HandleSpecialMacro (Macro* M, const char* Name)
|
|||||||
} else if (strcmp (Name, "__FILE__") == 0) {
|
} else if (strcmp (Name, "__FILE__") == 0) {
|
||||||
/* Replace __FILE__ with the current filename */
|
/* Replace __FILE__ with the current filename */
|
||||||
StrBuf B = AUTO_STRBUF_INITIALIZER;
|
StrBuf B = AUTO_STRBUF_INITIALIZER;
|
||||||
SB_InitFromString (&B, GetCurrentFilename ());
|
SB_InitFromString (&B, GetCurrentFileName ());
|
||||||
SB_Clear (&M->Replacement);
|
SB_Clear (&M->Replacement);
|
||||||
Stringize (&B, &M->Replacement);
|
Stringize (&B, &M->Replacement);
|
||||||
SB_Done (&B);
|
SB_Done (&B);
|
||||||
@@ -3332,7 +3332,7 @@ void Preprocess (void)
|
|||||||
PLine = InitLine (PLine);
|
PLine = InitLine (PLine);
|
||||||
|
|
||||||
if (Verbosity > 1 && SB_NotEmpty (Line)) {
|
if (Verbosity > 1 && SB_NotEmpty (Line)) {
|
||||||
printf ("%s:%u: %.*s\n", GetCurrentFilename (), GetCurrentLineNum (),
|
printf ("%s:%u: %.*s\n", GetCurrentFileName (), GetCurrentLineNum (),
|
||||||
(int) SB_GetLen (Line), SB_GetConstBuf (Line));
|
(int) SB_GetLen (Line), SB_GetConstBuf (Line));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user