From d18fd210aaba5f7dbde515defa30ad3cc403259d Mon Sep 17 00:00:00 2001 From: uz Date: Thu, 7 Jul 2011 20:07:29 +0000 Subject: [PATCH] The line counter got confused for lines with more than 256 chars. Removed the restriction alltogether, so lines with arbitrary length should be handled correctly. Not that it is of much use for an assembler, but this has really been a somewhat ancient limitation. git-svn-id: svn://svn.cc65.org/cc65/trunk@5072 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ca65/listing.c | 15 ++++---- src/ca65/listing.h | 23 +++++++++--- src/ca65/scanner.c | 91 ++++++++++++++++++++++++++++++---------------- 3 files changed, 84 insertions(+), 45 deletions(-) diff --git a/src/ca65/listing.c b/src/ca65/listing.c index 6eb2330bf..4994f690f 100644 --- a/src/ca65/listing.c +++ b/src/ca65/listing.c @@ -41,6 +41,7 @@ #include "check.h" #include "fname.h" #include "fragdefs.h" +#include "strbuf.h" #include "version.h" #include "xmalloc.h" @@ -81,7 +82,7 @@ static int ListingEnabled = 1; /* Enabled if > 0 */ -void NewListingLine (const char* Line, unsigned char File, unsigned char Depth) +void NewListingLine (const StrBuf* Line, unsigned char File, unsigned char Depth) /* Create a new ListLine struct and insert it */ { /* Store only if listing is enabled */ @@ -90,10 +91,10 @@ void NewListingLine (const char* Line, unsigned char File, unsigned char Depth) ListLine* L; /* Get the length of the line */ - unsigned Len = strlen (Line); + unsigned Len = SB_GetLen (Line); /* Ignore trailing newlines */ - while (Len > 0 && Line[Len-1] == '\n') { + while (Len > 0 && SB_AtUnchecked (Line, Len-1) == '\n') { --Len; } @@ -110,8 +111,8 @@ void NewListingLine (const char* Line, unsigned char File, unsigned char Depth) L->Depth = Depth; L->Output = (ListingEnabled > 0); L->ListBytes = (unsigned char) ListBytes; - memcpy (L->Line, Line, Len); - L->Line [Len] = '\0'; + memcpy (L->Line, SB_GetConstBuf (Line), Len); + L->Line[Len] = '\0'; /* Insert the line into the list of lines */ if (LineList == 0) { @@ -303,8 +304,8 @@ void CreateListing (void) /* Open the real listing file */ F = fopen (SB_GetConstBuf (&ListingName), "w"); if (F == 0) { - Fatal ("Cannot open listing file `%s': %s", - SB_GetConstBuf (&ListingName), + Fatal ("Cannot open listing file `%s': %s", + SB_GetConstBuf (&ListingName), strerror (errno)); } diff --git a/src/ca65/listing.h b/src/ca65/listing.h index 01df0c360..33debd524 100644 --- a/src/ca65/listing.h +++ b/src/ca65/listing.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* 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 */ @@ -44,7 +44,17 @@ /*****************************************************************************/ -/* Data */ +/* Forwards */ +/*****************************************************************************/ + + + +struct StrBuf; + + + +/*****************************************************************************/ +/* Data */ /*****************************************************************************/ @@ -89,7 +99,8 @@ extern int PageLength; /* Length of a listing page */ -void NewListingLine (const char* Line, unsigned char File, unsigned char Depth); +void NewListingLine (const struct StrBuf* Line, unsigned char File, + unsigned char Depth); /* Create a new ListLine struct */ void EnableListing (void); diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 723978a86..40b99041a 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -80,10 +80,10 @@ struct InputFile { FilePos Pos; /* Position in file */ token_t Tok; /* Last token */ int C; /* Last character */ - char Line[256]; /* The current input line */ + StrBuf Line; /* The current input line */ int IncSearchPath; /* True if we've added a search path */ int BinSearchPath; /* True if we've added a search path */ - InputFile* Next; /* Linked list of input files */ + InputFile* Next; /* Linked list of input files */ }; /* Struct to handle textual input data */ @@ -91,10 +91,10 @@ typedef struct InputData InputData; struct InputData { char* Text; /* Pointer to the text data */ const char* Pos; /* Pointer to current position */ - int Malloced; /* Memory was malloced */ + int Malloced; /* Memory was malloced */ token_t Tok; /* Last token */ - int C; /* Last character */ - InputData* Next; /* Linked list of input data */ + int C; /* Last character */ + InputData* Next; /* Linked list of input data */ }; /* Input source: Either file or data */ @@ -267,7 +267,7 @@ struct DotKeyword { { ".SEGMENT", TOK_SEGMENT }, { ".SET", TOK_SET }, { ".SETCPU", TOK_SETCPU }, - { ".SHL", TOK_SHL }, + { ".SHL", TOK_SHL }, { ".SHR", TOK_SHR }, { ".SIZEOF", TOK_SIZEOF }, { ".SMART", TOK_SMART }, @@ -363,47 +363,71 @@ static void IFNextChar (CharSource* S) /* Read the next character from the input file */ { /* Check for end of line, read the next line if needed */ - while (S->V.File.Line [S->V.File.Pos.Col] == '\0') { + while (SB_GetIndex (&S->V.File.Line) >= SB_GetLen (&S->V.File.Line)) { - unsigned Len, Removed; + unsigned Len; /* End of current line reached, read next line */ - if (fgets (S->V.File.Line, sizeof (S->V.File.Line), S->V.File.F) == 0) { - /* End of file. Add an empty line to the listing. This is a - * small hack needed to keep the PC output in sync. - */ - NewListingLine ("", S->V.File.Pos.Name, FCount); - C = EOF; - return; + SB_Clear (&S->V.File.Line); + while (1) { + + int N = fgetc (S->V.File.F); + if (N == EOF) { + /* End of file. Accept files without a newline at the end */ + if (SB_NotEmpty (&S->V.File.Line)) { + break; + } + + /* No more data - add an empty line to the listing. This + * is a small hack needed to keep the PC output in sync. + */ + NewListingLine (&EmptyStrBuf, S->V.File.Pos.Name, FCount); + C = EOF; + return; + + /* Check for end of line */ + } else if (N == '\n') { + + /* End of line */ + break; + + /* Collect other stuff */ + } else { + + /* Append data to line */ + SB_AppendChar (&S->V.File.Line, N); + + } } - /* For better handling of files with unusual line endings (DOS - * files that are accidently translated on Unix for example), - * first remove all whitespace at the end, then add a single - * newline. + + /* If we come here, we have a new input line. To avoid problems + * with strange line terminators, remove all whitespace from the + * end of the line, the add a single newline. */ - Len = strlen (S->V.File.Line); - Removed = 0; - while (Len > 0 && IsSpace (S->V.File.Line[Len-1])) { - ++Removed; + Len = SB_GetLen (&S->V.File.Line); + while (Len > 0 && IsSpace (SB_AtUnchecked (&S->V.File.Line, Len-1))) { --Len; } - if (Removed) { - S->V.File.Line[Len+0] = '\n'; - S->V.File.Line[Len+1] = '\0'; - } + SB_Drop (&S->V.File.Line, SB_GetLen (&S->V.File.Line) - Len); + SB_AppendChar (&S->V.File.Line, '\n'); + + /* Terminate the string buffer */ + SB_Terminate (&S->V.File.Line); /* One more line */ S->V.File.Pos.Line++; - S->V.File.Pos.Col = 0; /* Remember the new line for the listing */ - NewListingLine (S->V.File.Line, S->V.File.Pos.Name, FCount); + NewListingLine (&S->V.File.Line, S->V.File.Pos.Name, FCount); } - /* Return the next character from the file */ - C = S->V.File.Line [S->V.File.Pos.Col++]; + /* Set the column pointer */ + S->V.File.Pos.Col = SB_GetIndex (&S->V.File.Line); + + /* Return the next character from the buffer */ + C = SB_Get (&S->V.File.Line); } @@ -427,6 +451,9 @@ void IFDone (CharSource* S) PopSearchPath (BinSearchPath); } + /* Free the line buffer */ + SB_Done (&S->V.File.Line); + /* Close the input file and decrement the file count. We will ignore * errors here, since we were just reading from the file. */ @@ -508,7 +535,7 @@ int NewInputFile (const char* Name) S->V.File.Pos.Line = 0; S->V.File.Pos.Col = 0; S->V.File.Pos.Name = FileIdx; - S->V.File.Line[0] = '\0'; + SB_Init (&S->V.File.Line); /* Push the path for this file onto the include search lists */ SB_CopyBuf (&Path, Name, FindName (Name) - Name); -- 2.39.5