From e814c484c3de5056dc96a3436872d67abad41014 Mon Sep 17 00:00:00 2001 From: cuz Date: Wed, 16 Feb 2005 23:30:05 +0000 Subject: [PATCH] Added new comment feature git-svn-id: svn://svn.cc65.org/cc65/trunk@3388 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/da65/asminc.c | 15 ++++++- src/da65/attrtab.c | 102 +++++++++++++++++++++++++++++++++++++------- src/da65/attrtab.h | 18 +++++--- src/da65/data.c | 4 +- src/da65/handler.c | 6 +-- src/da65/infofile.c | 74 +++++++++++++++++++++++--------- src/da65/main.c | 8 +++- src/da65/output.c | 9 ++++ src/da65/output.h | 3 ++ src/da65/scanner.c | 13 +++++- src/da65/scanner.h | 1 + 11 files changed, 200 insertions(+), 53 deletions(-) diff --git a/src/da65/asminc.c b/src/da65/asminc.c index b326edbce..4708a42e3 100644 --- a/src/da65/asminc.c +++ b/src/da65/asminc.c @@ -81,6 +81,7 @@ void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown) { char Buf[1024]; char* L; + const char* Comment; unsigned Line; unsigned Len; long Val; @@ -147,7 +148,7 @@ void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown) } else { if (!IgnoreUnknown) { Error ("%s(%u): Missing `='", Filename, Line); - } + } continue; } @@ -198,6 +199,16 @@ void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown) /* Skip whitespace again */ L = SkipWhitespace (L); + /* Check for a comment */ + if (*L == CommentStart) { + Comment = SkipWhitespace (L+1); + if (*Comment == '\0') { + Comment = 0; + } + } else { + Comment = 0; + } + /* Check for a comment character or end of line */ if (*L != CommentStart && *L != '\0') { if (!IgnoreUnknown) { @@ -210,7 +221,7 @@ void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown) Val *= Sign; /* Define the symbol */ - AddExtLabelRange (Val, SB_GetConstBuf (&Ident), 1); + AddExtLabel (Val, SB_GetConstBuf (&Ident), Comment); } diff --git a/src/da65/attrtab.c b/src/da65/attrtab.c index 4cce152fd..1eb7d9f2c 100644 --- a/src/da65/attrtab.c +++ b/src/da65/attrtab.c @@ -55,11 +55,53 @@ +/* Label + comment */ +typedef struct { + const char* Name; + const char* Comment; +} Label; + +/* A whole lot of Labels, so we don't have to allocate them separately */ +static Label* LabelHeap = 0; +static unsigned LabelsLeft = 0; + /* Attribute table */ static unsigned char AttrTab [0x10000]; /* Symbol table */ -static const char* SymTab [0x10000]; +static const Label* SymTab [0x10000]; + + + +/*****************************************************************************/ +/* struct Label */ +/*****************************************************************************/ + + + +Label* NewLabel (const char* Name, const char* Comment) +/* Create a new Label structure, initialize and return it */ +{ + Label* L; + + /* Check if we have some free labels left */ + if (LabelsLeft == 0) { + /* Allocate a new block of memory */ + LabelsLeft = 200; + LabelHeap = xmalloc (LabelsLeft * sizeof (Label)); + } + + /* Get a new one from the buffer */ + L = LabelHeap++; + --LabelsLeft; + + /* Initialize the new label */ + L->Name = xstrdup (Name); + L->Comment = Comment? xstrdup (Comment) : 0; + + /* Return the new label */ + return L; +} @@ -133,7 +175,7 @@ void MarkAddr (unsigned Addr, attr_t Attr) -const char* MakeLabelName (unsigned Addr) +static const char* MakeLabelName (unsigned Addr) /* Make the default label name from the given address and return it in a * static buffer. */ @@ -145,7 +187,7 @@ const char* MakeLabelName (unsigned Addr) -void AddLabel (unsigned Addr, attr_t Attr, const char* Name) +void AddLabel (unsigned Addr, attr_t Attr, const char* Name, const char* Comment) /* Add a label */ { /* Get an existing label attribute */ @@ -154,14 +196,14 @@ void AddLabel (unsigned Addr, attr_t Attr, const char* Name) /* Must not have two symbols for one address */ if (ExistingAttr != atNoLabel) { /* Allow redefinition if identical */ - if (ExistingAttr == Attr && strcmp (SymTab[Addr], Name) == 0) { + if (ExistingAttr == Attr && strcmp (SymTab[Addr]->Name, Name) == 0) { return; } - Error ("Duplicate label for address $%04X: %s/%s", Addr, SymTab[Addr], Name); + Error ("Duplicate label for address $%04X: %s/%s", Addr, SymTab[Addr]->Name, Name); } /* Create a new label */ - SymTab[Addr] = xstrdup (Name); + SymTab[Addr] = NewLabel (Name, Comment); /* Remember the attribute */ AttrTab[Addr] |= Attr; @@ -169,6 +211,22 @@ void AddLabel (unsigned Addr, attr_t Attr, const char* Name) +void AddIntLabel (unsigned Addr) +/* Add an internal label using the address to generate the name. */ +{ + AddLabel (Addr, atIntLabel, MakeLabelName (Addr), 0); +} + + + +void AddExtLabel (unsigned Addr, const char* Name, const char* Comment) +/* Add an external label */ +{ + AddLabel (Addr, atExtLabel, Name, Comment); +} + + + void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Offs) /* Add a dependent label at the given address using "base name+Offs" as the new * name. @@ -186,7 +244,7 @@ void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Off } /* Define the labels */ - AddLabel (Addr, Attr | atDepLabel, DepName); + AddLabel (Addr, Attr | atDepLabel, DepName, 0); /* Free the name buffer */ xfree (DepName); @@ -194,13 +252,15 @@ void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Off -static void AddLabelRange (unsigned Addr, attr_t Attr, const char* Name, unsigned Count) +static void AddLabelRange (unsigned Addr, attr_t Attr, + const char* Name, const char* Comment, + unsigned Count) /* Add a label for a range. The first entry gets the label "Name" while the * others get "Name+offs". */ { /* Define the label */ - AddLabel (Addr, Attr, Name); + AddLabel (Addr, Attr, Name, Comment); /* Define dependent labels if necessary */ if (Count > 1) { @@ -221,7 +281,7 @@ static void AddLabelRange (unsigned Addr, attr_t Attr, const char* Name, unsigne /* Define the labels */ for (Offs = 1; Offs < Count; ++Offs) { sprintf (DepOffs, Format, Offs); - AddLabel (Addr + Offs, Attr | atDepLabel, DepName); + AddLabel (Addr + Offs, Attr | atDepLabel, DepName, 0); } /* Free the name buffer */ @@ -237,18 +297,18 @@ void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count) */ { /* Define the label range */ - AddLabelRange (Addr, atIntLabel, Name, Count); + AddLabelRange (Addr, atIntLabel, Name, 0, Count); } -void AddExtLabelRange (unsigned Addr, const char* Name, unsigned Count) +void AddExtLabelRange (unsigned Addr, const char* Name, const char* Comment, unsigned Count) /* Add an external label for a range. The first entry gets the label "Name" * while the others get "Name+offs". */ { /* Define the label range */ - AddLabelRange (Addr, atExtLabel, Name, Count); + AddLabelRange (Addr, atExtLabel, Name, Comment, Count); } @@ -286,7 +346,19 @@ const char* GetLabel (unsigned Addr) AddrCheck (Addr); /* Return the label if any */ - return SymTab[Addr]; + return SymTab[Addr]? SymTab[Addr]->Name : 0; +} + + + +const char* GetComment (unsigned Addr) +/* Return the comment for an address */ +{ + /* Check the given address */ + AddrCheck (Addr); + + /* Return the label if any */ + return SymTab[Addr]? SymTab[Addr]->Comment : 0; } @@ -318,7 +390,7 @@ unsigned char GetLabelAttr (unsigned Addr) static void DefineConst (unsigned Addr) /* Define an address constant */ { - Output ("%s", SymTab [Addr]); + Output ("%s", SymTab[Addr]->Name); Indent (AIndent); Output ("= $%04X", Addr); LineFeed (); diff --git a/src/da65/attrtab.h b/src/da65/attrtab.h index 2e64be067..aba6bd65f 100644 --- a/src/da65/attrtab.h +++ b/src/da65/attrtab.h @@ -86,14 +86,15 @@ void MarkRange (unsigned Start, unsigned End, attr_t Attr); void MarkAddr (unsigned Addr, attr_t Attr); /* Mark an address with an attribute */ -const char* MakeLabelName (unsigned Addr); -/* Make the default label name from the given address and return it in a - * static buffer. - */ - -void AddLabel (unsigned Addr, attr_t Attr, const char* Name); +void AddLabel (unsigned Addr, attr_t Attr, const char* Name, const char* Comment); /* Add a label */ +void AddIntLabel (unsigned Addr); +/* Add an internal label using the address to generate the name. */ + +void AddExtLabel (unsigned Addr, const char* Name, const char* Comment); +/* Add an external label */ + void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Offs); /* Add a dependent label at the given address using "base name+Offs" as the new * name. @@ -104,7 +105,7 @@ void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count); * while the others get "Name+offs". */ -void AddExtLabelRange (unsigned Addr, const char* Name, unsigned Count); +void AddExtLabelRange (unsigned Addr, const char* Name, const char* Comment, unsigned Count); /* Add an external label for a range. The first entry gets the label "Name" * while the others get "Name+offs". */ @@ -120,6 +121,9 @@ int MustDefLabel (unsigned Addr); const char* GetLabel (unsigned Addr); /* Return the label for an address or NULL if there is none */ +const char* GetComment (unsigned Addr); +/* Return the comment for an address */ + unsigned char GetStyleAttr (unsigned Addr); /* Return the style attribute for the given address */ diff --git a/src/da65/data.c b/src/da65/data.c index 2056ab822..98f303d62 100644 --- a/src/da65/data.c +++ b/src/da65/data.c @@ -183,7 +183,7 @@ unsigned AddrTable (void) /* In pass 1, define a label, in pass 2 output the line */ if (Pass == 1) { if (!HaveLabel (Addr)) { - AddLabel (Addr, atIntLabel, MakeLabelName (Addr)); + AddIntLabel (Addr); } } else { const char* Label = GetLabel (Addr); @@ -243,7 +243,7 @@ unsigned RtsTable (void) /* In pass 1, define a label, in pass 2 output the line */ if (Pass == 1) { if (!HaveLabel (Addr)) { - AddLabel (Addr, atIntLabel, MakeLabelName (Addr)); + AddIntLabel (Addr); } } else { const char* Label = GetLabel (Addr); diff --git a/src/da65/handler.c b/src/da65/handler.c index 5cb33ba41..071913c96 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -145,7 +145,7 @@ static void GenerateLabel (unsigned Flags, unsigned Addr) if (Granularity == 1) { /* Just add the label */ - AddLabel (Addr, atIntLabel, MakeLabelName (Addr)); + AddIntLabel (Addr); } else { /* Search for the start of the range or the last non dependent * label in the range. @@ -170,13 +170,13 @@ static void GenerateLabel (unsigned Flags, unsigned Addr) /* If the proposed label address doesn't have a label, define one */ if ((GetLabelAttr (LabelAddr) & (atIntLabel|atExtLabel)) == 0) { - AddLabel (LabelAddr, atIntLabel, MakeLabelName (LabelAddr)); + AddIntLabel (LabelAddr); } /* Create the label */ Offs = Addr - LabelAddr; if (Offs == 0) { - AddLabel (Addr, atIntLabel, MakeLabelName (Addr)); + AddIntLabel (Addr); } else { AddDepLabel (Addr, atIntLabel, GetLabel (LabelAddr), Offs); } diff --git a/src/da65/infofile.c b/src/da65/infofile.c index cf20411fd..44a6f9e1f 100644 --- a/src/da65/infofile.c +++ b/src/da65/infofile.c @@ -205,6 +205,7 @@ static void RangeSection (void) /* Parse a range section */ { static const IdentTok RangeDefs[] = { + { "COMMENT", INFOTOK_COMMENT }, { "END", INFOTOK_END }, { "NAME", INFOTOK_NAME }, { "START", INFOTOK_START }, @@ -212,11 +213,11 @@ static void RangeSection (void) }; static const IdentTok TypeDefs[] = { - { "ADDRTABLE", INFOTOK_ADDRTAB }, + { "ADDRTABLE", INFOTOK_ADDRTAB }, { "BYTETABLE", INFOTOK_BYTETAB }, { "CODE", INFOTOK_CODE }, { "DBYTETABLE", INFOTOK_DBYTETAB }, - { "DWORDTABLE", INFOTOK_DWORDTAB }, + { "DWORDTABLE", INFOTOK_DWORDTAB }, { "RTSTABLE", INFOTOK_RTSTAB }, { "SKIP", INFOTOK_SKIP }, { "TEXTTABLE", INFOTOK_TEXTTAB }, @@ -231,6 +232,7 @@ static void RangeSection (void) tEnd = 0x02, tType = 0x04, tName = 0x08, + tComment= 0x10, tNeeded = (tStart | tEnd | tType) }; unsigned Attributes = tNone; @@ -240,6 +242,7 @@ static void RangeSection (void) unsigned End = 0; unsigned char Type = 0; char* Name = 0; + char* Comment = 0; unsigned MemberSize = 0; @@ -258,6 +261,18 @@ static void RangeSection (void) /* Look at the token */ switch (InfoTok) { + case INFOTOK_COMMENT: + AddAttr ("COMMENT", &Attributes, tComment); + InfoNextTok (); + InfoAssureStr (); + if (InfoSVal[0] == '\0') { + InfoError ("Comment may not be empty"); + } + Comment = xstrdup (InfoSVal); + Attributes |= tComment; + InfoNextTok (); + break; + case INFOTOK_END: AddAttr ("END", &Attributes, tEnd); InfoNextTok (); @@ -333,9 +348,10 @@ static void RangeSection (void) /* Do we have a label? */ if (Attributes & tName) { /* Define a label for the table */ - AddLabel (Start, atExtLabel, Name); - /* Delete the name */ + AddExtLabel (Start, Name, Comment); + /* Delete name and comment */ xfree (Name); + xfree (Comment); } /* Consume the closing brace */ @@ -348,15 +364,17 @@ static void LabelSection (void) /* Parse a label section */ { static const IdentTok LabelDefs[] = { - { "NAME", INFOTOK_NAME }, + { "COMMENT", INFOTOK_COMMENT }, { "ADDR", INFOTOK_ADDR }, + { "NAME", INFOTOK_NAME }, { "SIZE", INFOTOK_SIZE }, }; /* Locals - initialize to avoid gcc warnings */ - char* Name = 0; - long Value = -1; - long Size = -1; + char* Name = 0; + char* Comment = 0; + long Value = -1; + long Size = -1; /* Skip the token */ InfoNextTok (); @@ -373,6 +391,30 @@ static void LabelSection (void) /* Look at the token */ switch (InfoTok) { + case INFOTOK_ADDR: + InfoNextTok (); + if (Value >= 0) { + InfoError ("Value already given"); + } + InfoAssureInt (); + InfoRangeCheck (0, 0xFFFF); + Value = InfoIVal; + InfoNextTok (); + break; + + case INFOTOK_COMMENT: + InfoNextTok (); + if (Comment) { + InfoError ("Comment already given"); + } + InfoAssureStr (); + if (InfoSVal[0] == '\0') { + InfoError ("Comment may not be empty"); + } + Comment = xstrdup (InfoSVal); + InfoNextTok (); + break; + case INFOTOK_NAME: InfoNextTok (); if (Name) { @@ -386,17 +428,6 @@ static void LabelSection (void) InfoNextTok (); break; - case INFOTOK_ADDR: - InfoNextTok (); - if (Value >= 0) { - InfoError ("Value already given"); - } - InfoAssureInt (); - InfoRangeCheck (0, 0xFFFF); - Value = InfoIVal; - InfoNextTok (); - break; - case INFOTOK_SIZE: InfoNextTok (); if (Size >= 0) { @@ -433,10 +464,11 @@ static void LabelSection (void) } /* Define the label(s) */ - AddExtLabelRange ((unsigned) Value, Name, Size); + AddExtLabelRange ((unsigned) Value, Name, Comment, Size); - /* Delete the dynamically allocated memory for Name */ + /* Delete the dynamically allocated memory for Name and Comment */ xfree (Name); + xfree (Comment); /* Consume the closing brace */ InfoConsumeRCurly (); diff --git a/src/da65/main.c b/src/da65/main.c index 8fa43ca9a..454450b2e 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -251,10 +251,14 @@ static void OneOpcode (unsigned RemainingBytes) /* Get the output style for the current PC */ attr_t Style = GetStyleAttr (PC); - /* If we have a label at this address, output the label, provided that - * we aren't in a skip area. + /* If we have a label at this address, output the label and an attached + * comment, provided that we aren't in a skip area. */ if (Style != atSkip && MustDefLabel (PC)) { + const char* Comment = GetComment (PC); + if (Comment) { + UserComment (Comment); + } DefLabel (GetLabel (PC)); } diff --git a/src/da65/output.c b/src/da65/output.c index e02f2d99b..60541c93f 100644 --- a/src/da65/output.c +++ b/src/da65/output.c @@ -267,6 +267,15 @@ void SeparatorLine (void) +void UserComment (const char* Comment) +/* Output a comment line */ +{ + Output ("; %s", Comment); + LineFeed (); +} + + + void LineComment (unsigned PC, unsigned Count) /* Add a line comment with the PC and data bytes */ { diff --git a/src/da65/output.h b/src/da65/output.h index 8a44f9316..161a12f39 100644 --- a/src/da65/output.h +++ b/src/da65/output.h @@ -85,6 +85,9 @@ void DataDWordLine (unsigned ByteCount); void SeparatorLine (void); /* Print a separator line */ +void UserComment (const char* Comment); +/* Output a comment line */ + void LineComment (unsigned PC, unsigned Count); /* Add a line comment with the PC and data bytes */ diff --git a/src/da65/scanner.c b/src/da65/scanner.c index 9b58981df..176a6869e 100644 --- a/src/da65/scanner.c +++ b/src/da65/scanner.c @@ -153,7 +153,7 @@ void InfoNextTok (void) /* Read the next token from the input stream */ { unsigned I; - + int Esc; Again: /* Skip whitespace */ @@ -249,9 +249,20 @@ Again: NextChar (); I = 0; while (C != '\"') { + Esc = (C == '\\'); + if (Esc) { + NextChar (); + } if (C == EOF || C == '\n') { InfoError ("Unterminated string"); } + if (Esc) { + switch (C) { + case '\"': C = '\"'; break; + case '\'': C = '\''; break; + default: InfoError ("Invalid escape char: %c", C); + } + } if (I < CFG_MAX_IDENT_LEN) { InfoSVal [I++] = C; } diff --git a/src/da65/scanner.h b/src/da65/scanner.h index 5e3f6efab..2bd96be4a 100644 --- a/src/da65/scanner.h +++ b/src/da65/scanner.h @@ -94,6 +94,7 @@ typedef enum token_t { /* Label section */ INFOTOK_NAME, + INFOTOK_COMMENT, INFOTOK_ADDR, INFOTOK_SIZE, -- 2.39.5