mirror of
https://github.com/cc65/cc65.git
synced 2024-12-27 15:29:46 +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:
commit
ea83b9fa53
@ -1471,7 +1471,7 @@ void CS_Output (CodeSeg* S)
|
||||
/* Add line debug info */
|
||||
if (DebugInfo) {
|
||||
WriteOutput ("\t.dbg\tline, \"%s\", %u\n",
|
||||
GetInputName (LI), GetInputLine (LI));
|
||||
GetActualFileName (LI), GetActualLineNum (LI));
|
||||
}
|
||||
}
|
||||
/* 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)
|
||||
/* Get the source file name where the diagnostic info refers to */
|
||||
{
|
||||
if (CurTok.LI) {
|
||||
return GetInputName (CurTok.LI);
|
||||
return GetPresumedFileName (CurTok.LI);
|
||||
} else {
|
||||
return GetCurrentFilename ();
|
||||
return GetCurrentFileName ();
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,7 +169,7 @@ static unsigned GetDiagnosticLineNum (void)
|
||||
/* Get the source line number where the diagnostic info refers to */
|
||||
{
|
||||
if (CurTok.LI) {
|
||||
return GetInputLine (CurTok.LI);
|
||||
return GetPresumedLineNum (CurTok.LI);
|
||||
} else {
|
||||
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 */
|
||||
{
|
||||
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);
|
||||
fprintf (stderr, "\n");
|
||||
|
||||
@ -229,23 +270,23 @@ static void IntError (errcat_t EC, const char* Filename, unsigned LineNo, const
|
||||
|
||||
|
||||
|
||||
void Error (const char* Format, ...)
|
||||
/* Print an error message */
|
||||
void LIError (errcat_t EC, LineInfo* LI, const char* Format, ...)
|
||||
/* Print an error message with the line info given explicitly */
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, Format);
|
||||
IntError (EC_PARSER, GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap);
|
||||
IntError (EC, LI, Format, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LIError (errcat_t EC, const LineInfo* LI, const char* Format, ...)
|
||||
/* Print an error message with the line info given explicitly */
|
||||
void Error (const char* Format, ...)
|
||||
/* Print an error message */
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, Format);
|
||||
IntError (EC, GetInputName (LI), GetInputLine (LI), Format, ap);
|
||||
IntError (EC_PARSER, GetDiagnosticLI (), Format, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
@ -256,7 +297,7 @@ void PPError (const char* Format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, Format);
|
||||
IntError (EC_PP, GetCurrentFilename(), GetCurrentLineNum(), Format, ap);
|
||||
IntError (EC_PP, GetCurLineInfo (), Format, 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 */
|
||||
{
|
||||
if (IS_Get (&WarningsAreErrors)) {
|
||||
|
||||
/* Treat the warning as an error */
|
||||
IntError (EC, Filename, LineNo, Msg, ap);
|
||||
IntError (EC, LI, Msg, ap);
|
||||
|
||||
} 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);
|
||||
fprintf (stderr, "\n");
|
||||
|
||||
@ -297,23 +346,23 @@ static void IntWarning (errcat_t EC, const char* Filename, unsigned LineNo, cons
|
||||
|
||||
|
||||
|
||||
void Warning (const char* Format, ...)
|
||||
/* Print a warning message */
|
||||
void LIWarning (errcat_t EC, LineInfo* LI, const char* Format, ...)
|
||||
/* Print a warning message with the line info given explicitly */
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, Format);
|
||||
IntWarning (EC_PARSER, GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap);
|
||||
IntWarning (EC, LI, Format, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LIWarning (errcat_t EC, const LineInfo* LI, const char* Format, ...)
|
||||
/* Print a warning message with the line info given explicitly */
|
||||
void Warning (const char* Format, ...)
|
||||
/* Print a warning message */
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, Format);
|
||||
IntWarning (EC, GetInputName (LI), GetInputLine (LI), Format, ap);
|
||||
IntWarning (EC_PARSER, GetDiagnosticLI (), Format, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
@ -324,7 +373,7 @@ void PPWarning (const char* Format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, Format);
|
||||
IntWarning (EC_PP, GetCurrentFilename(), GetCurrentLineNum(), Format, ap);
|
||||
IntWarning (EC_PP, GetCurLineInfo (), Format, 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 */
|
||||
{
|
||||
fprintf (stderr, "%s:%u: Note: ", Filename, LineNo);
|
||||
fprintf (stderr, "%s:%u: Note: ", GetPresumedFileName (LI), GetPresumedLineNum (LI));
|
||||
vfprintf (stderr, Msg, ap);
|
||||
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, ...)
|
||||
/* Print a note message with the line info given explicitly */
|
||||
{
|
||||
va_list ap;
|
||||
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);
|
||||
}
|
||||
|
||||
@ -402,7 +451,7 @@ void PPNote (const char* Format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, Format);
|
||||
IntNote (GetCurrentFilename(), GetCurrentLineNum(), Format, ap);
|
||||
IntNote (GetDiagnosticLI (), Format, 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)));
|
||||
/* 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)));
|
||||
/* 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 */
|
||||
|
||||
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)));
|
||||
/* 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 */
|
||||
|
||||
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 */
|
||||
typedef struct AFile AFile;
|
||||
struct AFile {
|
||||
unsigned Line; /* Line number for this file */
|
||||
unsigned LineNum; /* Actual line number for this file */
|
||||
FILE* F; /* Input file stream */
|
||||
IFile* Input; /* Points to corresponding IFile */
|
||||
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 */
|
||||
PPIfStack IfStack; /* PP #if stack */
|
||||
int MissingNL; /* Last input line was missing a newline */
|
||||
@ -111,6 +112,7 @@ static Collection* CurrentInputStack;
|
||||
|
||||
/* Counter for the __COUNTER__ macro */
|
||||
static unsigned MainFileCounter;
|
||||
LineInfo* PrevDiagnosticLI;
|
||||
|
||||
|
||||
|
||||
@ -163,10 +165,11 @@ static AFile* NewAFile (IFile* IF, FILE* F)
|
||||
AFile* AF = (AFile*) xmalloc (sizeof (AFile));
|
||||
|
||||
/* Initialize the fields */
|
||||
AF->Line = 0;
|
||||
AF->F = F;
|
||||
AF->Input = IF;
|
||||
AF->PName = 0;
|
||||
AF->LineNum = 0;
|
||||
AF->F = F;
|
||||
AF->Input = IF;
|
||||
AF->LineOffs = 0;
|
||||
AF->PName = 0;
|
||||
AF->IfStack.Index = -1;
|
||||
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
|
||||
** the main file before the first line is read.
|
||||
*/
|
||||
UpdateLineInfo (MainFile->Input, MainFile->Line, Line);
|
||||
UpdateCurrentLineInfo (Line);
|
||||
|
||||
/* Initialize the __COUNTER__ counter */
|
||||
MainFileCounter = 0;
|
||||
@ -553,7 +556,7 @@ int NextLine (void)
|
||||
if (!Input->MissingNL || SB_NotEmpty (Line)) {
|
||||
|
||||
/* Accept files without a newline at the end */
|
||||
++Input->Line;
|
||||
++Input->LineNum;
|
||||
|
||||
/* Assume no new line */
|
||||
Input->MissingNL = 1;
|
||||
@ -569,7 +572,7 @@ int NextLine (void)
|
||||
if (C == '\n') {
|
||||
|
||||
/* We got a new line */
|
||||
++Input->Line;
|
||||
++Input->LineNum;
|
||||
|
||||
/* If the \n is preceeded by a \r, remove the \r, so we can read
|
||||
** DOS/Windows files under *nix.
|
||||
@ -605,7 +608,7 @@ int NextLine (void)
|
||||
InitLine (Line);
|
||||
|
||||
/* Create line information for this line */
|
||||
UpdateLineInfo (Input->Input, Input->Line, Line);
|
||||
UpdateCurrentLineInfo (Line);
|
||||
|
||||
/* Done */
|
||||
return C != EOF || SB_NotEmpty (Line);
|
||||
@ -645,15 +648,145 @@ int PreprocessNextLine (void)
|
||||
|
||||
|
||||
|
||||
const char* GetInputFile (const struct IFile* IF)
|
||||
/* Return a filename from an IFile struct */
|
||||
static LineInfoFile* NewLineInfoFile (const AFile* AF)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char* GetCurrentFilename (void)
|
||||
const char* GetCurrentFileName (void)
|
||||
/* Return the name of the current input file */
|
||||
{
|
||||
unsigned AFileCount = CollCount (&AFiles);
|
||||
@ -674,7 +807,7 @@ unsigned GetCurrentLineNum (void)
|
||||
unsigned AFileCount = CollCount (&AFiles);
|
||||
if (AFileCount > 0) {
|
||||
const AFile* AF = CollLast (&AFiles);
|
||||
return AF->Line;
|
||||
return AF->LineNum + AF->LineOffs;
|
||||
} else {
|
||||
/* No open file */
|
||||
return 0;
|
||||
@ -684,18 +817,18 @@ unsigned GetCurrentLineNum (void)
|
||||
|
||||
|
||||
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);
|
||||
if (AFileCount > 0) {
|
||||
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 */
|
||||
{
|
||||
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
|
||||
** choosen so that it is possible to combine them to bitsets
|
||||
*/
|
||||
@ -61,9 +65,6 @@ typedef enum {
|
||||
IT_USRINC = 0x04, /* User include file (using "") */
|
||||
} InputType;
|
||||
|
||||
/* Forward for an IFile structure */
|
||||
struct IFile;
|
||||
|
||||
/* The current input line */
|
||||
extern StrBuf* Line;
|
||||
|
||||
@ -125,10 +126,19 @@ int PreprocessNextLine (void);
|
||||
** main file.
|
||||
*/
|
||||
|
||||
const char* GetInputFile (const struct IFile* IF);
|
||||
/* Return a filename from an IFile struct */
|
||||
void GetFileInclusionInfo (struct LineInfo* LI);
|
||||
/* 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 */
|
||||
|
||||
unsigned GetCurrentLineNum (void);
|
||||
@ -137,7 +147,7 @@ unsigned GetCurrentLineNum (void);
|
||||
void SetCurrentLineNum (unsigned LineNum);
|
||||
/* 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 */
|
||||
|
||||
unsigned GetCurrentCounter (void);
|
||||
|
@ -56,6 +56,9 @@
|
||||
/* Global pointer to line information for the current line */
|
||||
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. */
|
||||
{
|
||||
unsigned Len;
|
||||
@ -87,8 +90,9 @@ static LineInfo* NewLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* L
|
||||
|
||||
/* Initialize the fields */
|
||||
LI->RefCount = 1;
|
||||
LI->InputFile = F;
|
||||
LI->LineNum = LineNum;
|
||||
LI->File = 0;
|
||||
LI->IncFiles = 0;
|
||||
GetFileInclusionInfo (LI);
|
||||
|
||||
/* 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
|
||||
@ -117,6 +121,7 @@ static LineInfo* NewLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* L
|
||||
static void FreeLineInfo (LineInfo* LI)
|
||||
/* Free a LineInfo structure */
|
||||
{
|
||||
FreeFileInclusionInfo (LI);
|
||||
xfree (LI);
|
||||
}
|
||||
|
||||
@ -156,8 +161,8 @@ LineInfo* GetCurLineInfo (void)
|
||||
|
||||
|
||||
|
||||
void UpdateLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* Line)
|
||||
/* Update the line info - called if a new line is read */
|
||||
void UpdateCurrentLineInfo (const StrBuf* Line)
|
||||
/* Update the current line info - called if a new line is read */
|
||||
{
|
||||
/* If a current line info exists, release it */
|
||||
if (CurLineInfo) {
|
||||
@ -172,23 +177,60 @@ void UpdateLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* Line)
|
||||
}
|
||||
|
||||
/* Create a new line info */
|
||||
CurLineInfo = NewLineInfo (F, LineNum, Line);
|
||||
CurLineInfo = NewLineInfo (Line);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char* GetInputName (const LineInfo* LI)
|
||||
/* Return the file name from a line info */
|
||||
void RememberCheckedLI (LineInfo* LI)
|
||||
/* 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);
|
||||
return GetInputFile (LI->InputFile);
|
||||
return LI->File->Name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned GetInputLine (const LineInfo* LI)
|
||||
/* Return the line number from a line info */
|
||||
unsigned GetPresumedLineNum (const LineInfo* LI)
|
||||
/* Return the presumed line number from a line info */
|
||||
{
|
||||
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 size of the structure varies.
|
||||
*/
|
||||
typedef struct LineInfo LineInfo;
|
||||
struct LineInfo {
|
||||
unsigned RefCount; /* Reference counter */
|
||||
struct IFile* InputFile; /* Input file for this line */
|
||||
unsigned LineNum; /* Line number */
|
||||
char Line[1]; /* Source code line */
|
||||
unsigned RefCount; /* Reference counter */
|
||||
LineInfoFile* File; /* Presumed input files for this line */
|
||||
unsigned ActualLineNum; /* Actual line number for this file */
|
||||
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.
|
||||
*/
|
||||
|
||||
void UpdateLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* Line);
|
||||
/* Update the line info - called if a new line is read */
|
||||
void UpdateCurrentLineInfo (const StrBuf* Line);
|
||||
/* Update the current line info - called if a new line is read */
|
||||
|
||||
const char* GetInputName (const LineInfo* LI);
|
||||
/* Return the file name from a line info */
|
||||
void RememberCheckedLI (struct LineInfo* LI);
|
||||
/* Remember the latest checked line info struct */
|
||||
|
||||
unsigned GetInputLine (const LineInfo* LI);
|
||||
/* Return the line number from a line info */
|
||||
LineInfo* GetPrevCheckedLI (void);
|
||||
/* 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_Printf (&Comment, "#line %u \"%s\"\n",
|
||||
GetCurrentLineNum () - ContinuedLines, GetCurrentFilename ());
|
||||
GetCurrentLineNum () - ContinuedLines, GetCurrentFileName ());
|
||||
SB_Append (Str, &Comment);
|
||||
} else {
|
||||
/* Output new lines */
|
||||
@ -2943,7 +2943,7 @@ static void DoLine (void)
|
||||
StrBuf Filename = AUTO_STRBUF_INITIALIZER;
|
||||
if (SB_GetString (Line, &Filename)) {
|
||||
SB_Terminate (&Filename);
|
||||
SetCurrentFilename (SB_GetConstBuf (&Filename));
|
||||
SetCurrentFileName (SB_GetConstBuf (&Filename));
|
||||
} else {
|
||||
PPError ("Invalid filename for #line directive");
|
||||
LineNum = 0;
|
||||
@ -3220,7 +3220,7 @@ void HandleSpecialMacro (Macro* M, const char* Name)
|
||||
} else if (strcmp (Name, "__FILE__") == 0) {
|
||||
/* Replace __FILE__ with the current filename */
|
||||
StrBuf B = AUTO_STRBUF_INITIALIZER;
|
||||
SB_InitFromString (&B, GetCurrentFilename ());
|
||||
SB_InitFromString (&B, GetCurrentFileName ());
|
||||
SB_Clear (&M->Replacement);
|
||||
Stringize (&B, &M->Replacement);
|
||||
SB_Done (&B);
|
||||
@ -3332,7 +3332,7 @@ void Preprocess (void)
|
||||
PLine = InitLine (PLine);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user