#include "asserts.h"
#include "error.h"
#include "expr.h"
+#include "lineinfo.h"
#include "objfile.h"
-#include "scanner.h"
#include "spool.h"
ExprNode* Expr; /* Expression to evaluate */
AssertAction Action; /* Action to take */
unsigned Msg; /* Message to print (if any) */
- FilePos Pos; /* File position of assertion */
+ Collection LI; /* Line infos for the assertion */
};
/* Collection with all assertions for a module */
A->Expr = Expr;
A->Action = Action;
A->Msg = Msg;
- A->Pos = CurTok.Pos;
+ A->LI = EmptyCollection;
+ GetFullLineInfo (&A->LI);
/* Return the new struct */
return A;
switch (A->Action) {
case ASSERT_ACT_WARN:
- PWarning (&A->Pos, 0, "%s", Msg);
+ LIWarning (&A->LI, 0, "%s", Msg);
break;
case ASSERT_ACT_ERROR:
- PError (&A->Pos, "%s", Msg);
+ LIError (&A->LI, "%s", Msg);
break;
default:
WriteExpr (A->Expr);
ObjWriteVar ((unsigned) A->Action);
ObjWriteVar (A->Msg);
- ObjWritePos (&A->Pos);
+ WriteLineInfo (&A->LI);
}
/* Done writing the assertions */
-
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/* The line info slot used */
+static unsigned LineInfoSlot;
+
+
+
/*****************************************************************************/
/* Code */
/*****************************************************************************/
* follow, the last line info is terminated.
*/
if (CurTok.Tok == TOK_SEP) {
- ClearLineInfo ();
+ ClearLineInfo (LineInfoSlot);
return;
}
}
/* Remember the line info */
- GenLineInfo (Index, LineNum, 0);
+ GenLineInfo (LineInfoSlot, Index, LineNum, 0);
}
-
-
/* */
/* */
/* */
-/* (C) 2000-2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@cc65.org */
+/* (C) 2000-2011, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* ca65 */
#include "error.h"
#include "filetab.h"
+#include "lineinfo.h"
#include "nexttok.h"
+/*****************************************************************************/
+/* Helper functions */
+/*****************************************************************************/
+
+
+
+static int FindAsmEntry (const Collection* LineInfos)
+/* Return the last entry of type LI_TYPE_ASM in the given line infos. If none
+ * was found, return -1.
+ */
+{
+ unsigned I = CollCount (LineInfos);
+ while (I > 0) {
+ const LineInfo* LI = CollConstAt (LineInfos, --I);
+ if ((LI->Type & LI_MASK_TYPE) == LI_TYPE_ASM) {
+ /* Found */
+ return (int) I;
+ }
+ }
+
+ /* Not found */
+ return -1;
+}
+
+
+
/*****************************************************************************/
/* Warnings */
/*****************************************************************************/
+void LIWarning (const Collection* LineInfos, unsigned Level, const char* Format, ...)
+/* Print warning message using the given line infos */
+{
+ const LineInfo* LI;
+ va_list ap;
+
+ /* Search backwards in LI for the first entry of type LI_TYPE_ASM. */
+ int I = FindAsmEntry (LineInfos);
+
+ /* We must have such an entry */
+ CHECK (I >= 0);
+
+ /* Get the position for this entry */
+ LI = CollConstAt (LineInfos, I);
+
+ /* Output a warning for this position */
+ va_start (ap, Format);
+ WarningMsg (&LI->Pos, Level, Format, ap);
+ va_end (ap);
+}
+
+
+
/*****************************************************************************/
/* Errors */
/*****************************************************************************/
+void LIError (const Collection* LineInfos, const char* Format, ...)
+/* Print an error message using the given line infos. */
+{
+ const LineInfo* LI;
+ va_list ap;
+
+ /* Search backwards in LI for the first entry of type LI_TYPE_ASM. */
+ int I = FindAsmEntry (LineInfos);
+
+ /* We must have such an entry */
+ CHECK (I >= 0);
+
+ /* Get the position for this entry */
+ LI = CollConstAt (LineInfos, I);
+
+ /* Output an error for this position */
+ va_start (ap, Format);
+ ErrorMsg (&LI->Pos, Format, ap);
+ va_end (ap);
+}
+
+
+
void ErrorSkip (const char* Format, ...)
/* Print an error message and skip the rest of the line */
{
/* */
/* */
/* */
-/* (C) 1998-2008 Ullrich von Bassewitz */
-/* Roemerstrasse 52 */
-/* D-70794 Filderstadt */
-/* EMail: uz@cc65.org */
+/* (C) 1998-2011, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* common */
#include "attrib.h"
+#include "coll.h"
#include "filepos.h"
/*****************************************************************************/
-/* Data */
+/* Data */
/*****************************************************************************/
void PWarning (const FilePos* Pos, unsigned Level, const char* Format, ...) attribute ((format (printf, 3, 4)));
/* Print warning message giving an explicit file and position. */
+void LIWarning (const Collection* LineInfos, unsigned Level, const char* Format, ...) attribute ((format (printf, 3, 4)));
+/* Print warning message using the given line infos */
+
void Error (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Print an error message */
void PError (const FilePos* Pos, const char* Format, ...) attribute ((format (printf, 2, 3)));
/* Print an error message giving an explicit file and position. */
+void LIError (const Collection* LineInfos, const char* Format, ...) attribute ((format (printf, 2, 3)));
+/* Print an error message using the given line infos. */
+
void ErrorSkip (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Print an error message and skip the rest of the line */
/* ca65 */
#include "fragment.h"
-#include "lineinfo.h"
-#include "scanner.h"
/* Initialize it */
F->Next = 0;
F->LineList = 0;
- F->Pos = CurTok.Pos;
- F->LI = UseLineInfo (CurLineInfo);
+ F->LI = EmptyCollection;
+ GetFullLineInfo (&F->LI);
F->Len = Len;
F->Type = Type;
-
/* */
/* */
/* */
-/* (C) 1998-2003 Ullrich von Bassewitz */
-/* Römerstrasse 52 */
-/* D-70794 Filderstadt */
-/* EMail: uz@cc65.org */
+/* (C) 1998-2011, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* common */
#include "exprdefs.h"
-#include "filepos.h"
+#include "coll.h"
+
+/* ca65 */
+#include "lineinfo.h"
/*****************************************************************************/
-/* struct Fragment */
+/* struct Fragment */
/*****************************************************************************/
typedef struct Fragment Fragment;
struct Fragment {
- Fragment* Next; /* Pointer to next fragment in segment */
- Fragment* LineList; /* List of fragments for one src line */
- FilePos Pos; /* File position for this fragment */
- struct LineInfo* LI; /* Extra line info */
- unsigned short Len; /* Length for this fragment */
- unsigned char Type; /* Fragment type */
+ Fragment* Next; /* Pointer to next fragment in segment */
+ Fragment* LineList; /* List of fragments for one src line */
+ Collection LI; /* Line info for this fragment */
+ unsigned short Len; /* Length for this fragment */
+ unsigned char Type; /* Fragment type */
union {
- unsigned char Data[4]; /* Literal values */
- ExprNode* Expr; /* Expression */
+ unsigned char Data[4]; /* Literal values */
+ ExprNode* Expr; /* Expression */
} V;
};
+#include <string.h>
+#include <limits.h>
+
/* common */
#include "coll.h"
#include "xmalloc.h"
/* ca65 */
-#include "objfile.h"
+#include "global.h"
#include "lineinfo.h"
+#include "objfile.h"
/*****************************************************************************/
-/* Data */
+/* Data */
/*****************************************************************************/
+/* An invalid line info index */
+#define INV_LINEINFO_INDEX UINT_MAX
+
/* Collection containing all line infos */
-Collection LineInfoColl = STATIC_COLLECTION_INITIALIZER;
-unsigned LineInfoValid = 0; /* Valid, that is, used entries */
+static Collection LineInfoColl = STATIC_COLLECTION_INITIALIZER;
-/* Static pointer to last line info or NULL if not active */
-LineInfo* CurLineInfo = 0;
+/* Number of valid (=used) line infos in LineInfoColl */
+static unsigned UsedLineInfoCount;
+
+/* Entry in CurLineInfo */
+typedef struct LineInfoSlot LineInfoSlot;
+struct LineInfoSlot {
+ unsigned Type;
+ LineInfo* Info;
+};
+
+/* Dynamically allocated array of LineInfoSlots */
+static LineInfoSlot* CurLineInfo;
+static unsigned AllocatedSlots;
+static unsigned UsedSlots;
/*****************************************************************************/
-/* Code */
+/* struct LineInfo */
/*****************************************************************************/
-static LineInfo* NewLineInfo (unsigned File, unsigned long Line, unsigned Col)
+static LineInfo* NewLineInfo (unsigned Type, unsigned File,
+ unsigned long Line, unsigned Col)
/* Create and return a new line info. Usage will be zero. */
{
/* Allocate memory */
/* Initialize the fields */
LI->Usage = 0;
- LI->Index = 0; /* Currently invalid */
+ LI->Type = Type;
+ LI->Index = INV_LINEINFO_INDEX;
+ LI->Pos.Name = File;
LI->Pos.Line = Line;
LI->Pos.Col = Col;
- LI->Pos.Name = File;
-
- /* Insert this structure into the collection */
- CollAppend (&LineInfoColl, LI);
/* Return the new struct */
return LI;
-LineInfo* UseLineInfo (LineInfo* LI)
-/* Increase the reference count of the given line info and return it. The
- * function will gracefully accept NULL pointers and do nothing in this case.
+static void FreeLineInfo (LineInfo* LI)
+/* "Free" line info. If the usage counter is non zero, move it to the
+ * collection that contains all line infos, otherwise delete it.
+ * The function handles a NULL pointer transparently.
*/
{
if (LI) {
- if (LI->Usage++ == 0) {
- /* One more valid line info */
- ++LineInfoValid;
- }
+ if (LI->Usage > 0) {
+ CollAppend (&LineInfoColl, LI);
+ } else {
+ xfree (LI);
+ }
}
- return LI;
}
-void GenLineInfo (unsigned FileIndex, unsigned long LineNum, unsigned ColNum)
-/* Generate a new line info */
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+void InitLineInfo (void)
+/* Initialize the line infos */
+{
+ /* Allocate 8 slots */
+ AllocatedSlots = 8;
+ CurLineInfo = xmalloc (AllocatedSlots * sizeof (LineInfoSlot));
+
+ /* Initalize the predefined slots */
+ UsedSlots = 2;
+ CurLineInfo[LI_SLOT_ASM].Type = LI_TYPE_ASM;
+ CurLineInfo[LI_SLOT_ASM].Info = 0;
+ CurLineInfo[LI_SLOT_EXT].Type = LI_TYPE_EXT;
+ CurLineInfo[LI_SLOT_EXT].Info = 0;
+}
+
+
+
+unsigned AllocLineInfoSlot (unsigned Type)
+/* Allocate a line info slot of the given type and return the slot index */
+{
+ /* Grow the array if necessary */
+ if (UsedSlots >= AllocatedSlots) {
+ LineInfoSlot* NewLineInfo;
+ AllocatedSlots *= 2;
+ NewLineInfo = xmalloc (AllocatedSlots * sizeof (LineInfoSlot));
+ memcpy (NewLineInfo, CurLineInfo, UsedSlots * sizeof (LineInfoSlot));
+ xfree (CurLineInfo);
+ CurLineInfo = NewLineInfo;
+ }
+
+ /* Array is now big enough, add the new data */
+ CurLineInfo[UsedSlots].Type = Type;
+ CurLineInfo[UsedSlots].Info = 0;
+
+ /* Increment the count and return the index of the new slot */
+ return UsedSlots++;
+}
+
+
+
+void FreeLineInfoSlot (unsigned Slot)
+/* Free the line info in the given slot. Note: Alloc/Free must be used in
+ * FIFO order.
+ */
+{
+ /* Check the parameter */
+ PRECONDITION (Slot == UsedSlots - 1);
+
+ /* Free the last entry */
+ FreeLineInfo (CurLineInfo[Slot].Info);
+ --UsedSlots;
+}
+
+
+
+void GenLineInfo (unsigned Slot, unsigned File, unsigned long Line, unsigned Col)
+/* Generate a new line info in the given slot */
+{
+ /* Get a pointer to the slot */
+ LineInfoSlot* S = CurLineInfo + Slot;
+
+ /* Check if we already have data */
+ if (S->Info) {
+ /* Generate new data only if it is different from the existing. */
+ if (S->Info->Pos.Col == Col &&
+ S->Info->Pos.Line == Line &&
+ S->Info->Pos.Name == File) {
+ /* Already there */
+ return;
+ }
+
+ /* We have data, but it's not identical. If it is in use, copy it to
+ * line info collection, otherwise delete it.
+ */
+ FreeLineInfo (S->Info);
+
+ }
+
+ /* Allocate new data */
+ S->Info = NewLineInfo (S->Type, File, Line, Col);
+}
+
+
+
+void ClearLineInfo (unsigned Slot)
+/* Clear the line info in the given slot */
+{
+ /* Get a pointer to the slot */
+ LineInfoSlot* S = CurLineInfo + Slot;
+
+ /* Free the struct and zero the pointer */
+ FreeLineInfo (S->Info);
+ S->Info = 0;
+}
+
+
+
+LineInfo* GetLineInfo (unsigned Slot)
+/* Get the line info from the given slot */
{
- /* Create a new line info and make it current */
- CurLineInfo = NewLineInfo (FileIndex, LineNum, ColNum);
+ PRECONDITION (Slot < UsedSlots);
+ return CurLineInfo[Slot].Info;
+}
+
+
+
+void GetFullLineInfo (Collection* LineInfos)
+/* Return full line infos, that is line infos for all slots in LineInfos. The
+ * function does also increase the usage counter for all line infos returned.
+ */
+{
+ unsigned I;
+
+ /* Copy all valid line infos to the collection */
+ for (I = 0; I < UsedSlots; ++I) {
+
+ /* Get the slot */
+ LineInfoSlot* S = CurLineInfo + I;
+
+ /* Ignore empty slots */
+ if (S->Info) {
+ ++S->Info->Usage;
+ CollAppend (LineInfos, S->Info);
+ }
+ }
+}
+
+
+
+LineInfo* UseLineInfo (LineInfo* LI)
+/* Increase the reference count of the given line info and return it. The
+ * function will gracefully accept NULL pointers and do nothing in this case.
+ */
+{
+ if (LI) {
+ ++LI->Usage;
+ }
+ return LI;
}
-void ClearLineInfo (void)
-/* Clear the current line info */
+LineInfo* ReleaseLineInfo (LineInfo* LI)
+/* Decrease the reference count of the given line info and return it. The
+ * function will gracefully accept NULL pointers and do nothing in this case.
+ */
{
- CurLineInfo = 0;
+ if (LI) {
+ /* Cannot decrease below zero */
+ CHECK (LI->Usage != 0);
+ --LI->Usage;
+ }
+ return LI;
}
static int CmpLineInfo (void* Data attribute ((unused)),
- const void* LI1_, const void* LI2_)
+ const void* LI1_, const void* LI2_)
/* Compare function for the sort */
{
/* Cast the pointers */
const LineInfo* LI2 = LI2_;
/* Unreferenced line infos are always larger, otherwise sort by file,
- * then by line.
+ * then by line, then by column.
*/
if ((LI1->Usage == 0) == (LI2->Usage == 0)) {
/* Both are either referenced or unreferenced */
- if (LI1->Pos.Name< LI2->Pos.Name) {
- return -1;
- } else if (LI1->Pos.Name > LI2->Pos.Name) {
- return 1;
- } else if (LI1->Pos.Line < LI2->Pos.Line) {
- return -1;
- } else if (LI1->Pos.Line > LI2->Pos.Line) {
- return 1;
- } else {
- return 0;
- }
+ return CompareFilePos (&LI1->Pos, &LI2->Pos);
} else {
if (LI1->Usage > 0) {
return -1;
+void WriteLineInfo (const Collection* LineInfos)
+/* Write a list of line infos to the object file. MakeLineInfoIndex has to
+ * be called before!
+ */
+{
+ unsigned I;
+
+ /* Write the count */
+ ObjWriteVar (CollCount (LineInfos));
+
+ /* Write the line info indices */
+ for (I = 0; I < CollCount (LineInfos); ++I) {
+ ObjWriteVar (((const LineInfo*) CollConstAt (LineInfos, I))->Index);
+ }
+}
+
+
+
void MakeLineInfoIndex (void)
-/* Sort the line infos and drop all unreferenced ones */
+/* Index the line infos */
{
unsigned I;
/* Sort the collection */
CollSort (&LineInfoColl, CmpLineInfo, 0);
- /* Walk over the list and index the line infos. */
- for (I = 0; I < LineInfoValid; ++I) {
+ /* Walk over the list, index the line infos and count the used ones */
+ UsedLineInfoCount = 0;
+ for (I = 0; I < CollCount (&LineInfoColl); ++I) {
/* Get a pointer to this line info */
LineInfo* LI = CollAtUnchecked (&LineInfoColl, I);
- LI->Index = I;
+
+ /* If it is invalid, terminate the loop. All unused line infos were
+ * placed at the end of the collection by the sort.
+ */
+ if (LI->Usage == 0) {
+ break;
+ }
+
+ /* Index and count this one */
+ LI->Index = I;
+ ++UsedLineInfoCount;
}
}
-void WriteLineInfo (void)
+void WriteLineInfos (void)
/* Write a list of all line infos to the object file. */
{
/* Tell the object file module that we're about to write line infos */
unsigned I;
/* Write the line info count to the list */
- ObjWriteVar (LineInfoValid);
+ ObjWriteVar (UsedLineInfoCount);
- /* Walk through list and write all line infos that have references.
- * Because of the sort, this are exactly the first LineInfoValid
- * ones.
- */
- for (I = 0; I < LineInfoValid; ++I) {
+ /* Walk over the list and write all line infos */
+ for (I = 0; I < UsedLineInfoCount; ++I) {
/* Get a pointer to this line info */
- LineInfo* LI = CollAtUnchecked (&LineInfoColl, I);
+ LineInfo* LI = CollAt (&LineInfoColl, I);
/* Write the source file position */
ObjWritePos (&LI->Pos);
}
#include "coll.h"
#include "filepos.h"
-/* ca65 */
-#include "global.h"
-
/*****************************************************************************/
-/* Data */
+/* Data */
/*****************************************************************************/
+/* Predefined line info slots. These are allocated when initializing the
+ * module. Beware: Some code relies on the fact that slot zero is the basic
+ * standard line info. It is assumed to be always there.
+ */
+enum {
+ LI_SLOT_ASM = 0, /* Normal assembler source */
+ LI_SLOT_EXT = 1, /* Externally supplied line info */
+};
+
+/* Types of line infos. The low byte may be used for some sort of depth
+ * counter.
+ */
+enum {
+ LI_MASK_COUNT = 0x00FF, /* Mask to extract the count */
+
+ LI_TYPE_EXT = 0x0100, /* Externally supplied line info */
+ LI_TYPE_ASM = 0x0200, /* Normal assembler source */
+ LI_TYPE_MACRO = 0x0300, /* Macro expansion */
+ LI_MASK_TYPE = 0x7F00, /* Mask to extract the type */
+};
+
/* The LineInfo structure is shared between several fragments, so we need a
* reference counter.
*/
typedef struct LineInfo LineInfo;
struct LineInfo {
- unsigned Usage; /* Usage counter */
- unsigned Index; /* Index */
- FilePos Pos; /* File position */
+ unsigned Usage; /* Usage counter */
+ unsigned Type; /* Type of line info */
+ unsigned Index; /* Index */
+ FilePos Pos; /* File position */
};
-/* Collection containing all line infos */
-extern Collection LineInfoColl;
-extern unsigned LineInfoValid; /* Valid, that is, used entries */
-
-/* Global pointer to last line info or NULL if not active */
-extern LineInfo* CurLineInfo;
-
/*****************************************************************************/
+void InitLineInfo (void);
+/* Initialize the line infos */
+
+unsigned AllocLineInfoSlot (unsigned Type);
+/* Allocate a line info slot of the given type and return the slot index */
+
+void FreeLineInfoSlot (unsigned Slot);
+/* Free the line info in the given slot. Note: Alloc/Free must be used in
+ * FIFO order.
+ */
+
+void GenLineInfo (unsigned Slot, unsigned File, unsigned long Line, unsigned Col);
+/* Generate a new line info in the given slot */
+
+void ClearLineInfo (unsigned Slot);
+/* Clear the line info in the given slot */
+
+LineInfo* GetLineInfo (unsigned Slot);
+/* Get the line info from the given slot */
+
+void GetFullLineInfo (Collection* LineInfos);
+/* Return full line infos, that is line infos for all slots in LineInfos. The
+ * function does also increase the usage counter for all line infos returned.
+ */
+
LineInfo* UseLineInfo (LineInfo* LI);
/* Increase the reference count of the given line info and return it. The
* function will gracefully accept NULL pointers and do nothing in this case.
*/
-void GenLineInfo (unsigned FileIndex, unsigned long LineNum, unsigned ColNum);
-/* Generate a new line info */
+LineInfo* ReleaseLineInfo (LineInfo* LI);
+/* Decrease the reference count of the given line info and return it. The
+ * function will gracefully accept NULL pointers and do nothing in this case.
+ */
-void ClearLineInfo (void);
-/* Clear the current line info */
+void WriteLineInfo (const Collection* LineInfos);
+/* Write a list of line infos to the object file. MakeLineInfoIndex has to
+ * be called before!
+ */
void MakeLineInfoIndex (void);
-/* Walk over the line info list and make an index of all entries ignoring
- * those with a usage count of zero.
- */
+/* Index the line infos */
-void WriteLineInfo (void);
+void WriteLineInfos (void);
/* Write a list of all line infos to the object file. */
WriteDbgSyms ();
/* Write line infos if requested */
- WriteLineInfo ();
+ WriteLineInfos ();
/* Write the string pool */
WriteStrPool ();
break;
case 'o':
- OutFile = GetArg (&I, 2);
+ OutFile = GetArg (&I, 2);
break;
case 's':
break;
case 'U':
- OptAutoImport (Arg, 0);
+ OptAutoImport (Arg, 0);
break;
case 'V':
/* Initialize the segments */
InitSegments ();
+ /* Initialize the line infos */
+ InitLineInfo ();
+
/* Initialize the scanner, open the input file */
InitScanner (InFile);
if (Abs) {
/* Absolute value */
if (Val > 255) {
- PError (&F->Pos, "Range error (%ld not in [0..255])", Val);
+ LIError (&F->LI, "Range error (%ld not in [0..255])", Val);
}
} else {
/* PC relative value */
if (Val < -128 || Val > 127) {
- PError (&F->Pos, "Range error (%ld not in [-128..127])", Val);
+ LIError (&F->LI, "Range error (%ld not in [-128..127])", Val);
}
}
} else if (F->Len == 2) {
if (Abs) {
/* Absolute value */
if (Val > 65535) {
- PError (&F->Pos, "Range error (%ld not in [0..65535])", Val);
+ LIError (&F->LI, "Range error (%ld not in [0..65535])", Val);
}
} else {
/* PC relative value */
if (Val < -32768 || Val > 32767) {
- PError (&F->Pos, "Range error (%ld not in [-32768..32767])", Val);
+ LIError (&F->LI, "Range error (%ld not in [-32768..32767])", Val);
}
}
}
if ((F->Len == 1 && ED.AddrSize > ADDR_SIZE_ZP) ||
(F->Len == 2 && ED.AddrSize > ADDR_SIZE_ABS) ||
(F->Len == 3 && ED.AddrSize > ADDR_SIZE_FAR)) {
- PError (&F->Pos, "Range error");
+ LIError (&F->LI, "Range error");
}
}
/* Write one segment to the object file */
{
Fragment* Frag;
- unsigned LineInfoIndex;
unsigned long DataSize;
unsigned long EndPos;
}
- /* Write the file position of this fragment */
- ObjWritePos (&Frag->Pos);
-
- /* Write extra line info for this fragment. Zero is considered
- * "no line info", so add one to the value.
- */
- LineInfoIndex = Frag->LI? Frag->LI->Index + 1 : 0;
- ObjWriteVar (LineInfoIndex);
+ /* Write the line infos for this fragment */
+ WriteLineInfo (&Frag->LI);
/* Next fragment */
Frag = Frag->Next;
+