1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-08 15:29:37 +00:00

Merge pull request #2347 from acqn/SrcFile

[cc65] fixes and enhancements for source file info in diagnosis and debug output
This commit is contained in:
Bob Andrews 2024-01-23 22:15:31 +01:00 committed by GitHub
commit ea83b9fa53
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 347 additions and 89 deletions

View File

@ -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 */

View File

@ -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);
} }

View File

@ -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)));

View File

@ -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);

View File

@ -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);

View File

@ -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;
} }

View File

@ -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 */

View File

@ -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));
} }