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