← Back to team overview

kicad-developers team mailing list archive

Using FILE_LINE_READER in pcbnew

 

Hi,

When discussing the possibility to save plotting options into board
files earlier, Dick suggested that it might be a good idea to start
using FILE_LINE_READER in pcbnew. I made a patch that basically
changes GetLine to use a LINE_READER instead of a file directly. The
old function was renamed to GetLineD, since it is still currently used
somewhere else outside pcbnew in its old form. Changing the rest of
the code to use the new GetLine seems to be fairly trivial in most
places:

Old code:

char line[1024]
GetLine( file, line, ...)
...

New code:

char* line;
GetLine( &fileLineReader )
line = (char*) fileLineReader;
...

Because it's a rather large patch, I thought that I should post it
here for comments before committing. If my approach seems reasonable,
I can clean up and amend the patch so that the new GetLine is used
everywhere (including eeschema) and GetLineD is not needed anymore.

marco
=== modified file '3d-viewer/3d_read_mesh.cpp'
--- 3d-viewer/3d_read_mesh.cpp	2010-10-04 11:50:43 +0000
+++ 3d-viewer/3d_read_mesh.cpp	2011-01-11 17:35:34 +0000
@@ -50,12 +50,12 @@
     // Switch the locale to standard C (needed to print floating point
     // numbers like 1.3)
     SetLocaleTo_C_standard();
-    while( GetLine( file, line, &LineNum, 512 ) )
+    while( GetLineD( file, line, &LineNum, 512 ) )
     {
         text = strtok( line, " \t\n\r" );
         if( stricmp( text, "DEF" ) == 0 )
         {
-            while( GetLine( file, line, &LineNum, 512 ) )
+            while( GetLineD( file, line, &LineNum, 512 ) )
             {
                 text = strtok( line, " \t\n\r" );
                 if( text == NULL )
@@ -119,7 +119,7 @@
 
         Insert( material );
 
-        while( GetLine( file, line, LineNum, 512 ) )
+        while( GetLineD( file, line, LineNum, 512 ) )
         {
             text = strtok( line, " \t\n\r" );
             if( text == NULL )
@@ -181,7 +181,7 @@
 {
     char line[1024], * text;
 
-    while( GetLine( file, line, LineNum, 512 ) )
+    while( GetLineD( file, line, LineNum, 512 ) )
     {
         text = strtok( line, " \t\n\r" );
         if( *text == ']' )
@@ -209,7 +209,7 @@
     char line[1024], * text;
     int  err = 1;
 
-    while( GetLine( file, line, LineNum, 512 ) )
+    while( GetLineD( file, line, LineNum, 512 ) )
     {
         text = strtok( line, " \t\n\r" );
         if( *text == '}' )
@@ -242,7 +242,7 @@
     char line[1024], * text;
     int  err = 1;
 
-    while( GetLine( file, line, LineNum, 512 ) )
+    while( GetLineD( file, line, LineNum, 512 ) )
     {
         text = strtok( line, " \t\n\r" );
         if( *text == '}' )
@@ -301,7 +301,7 @@
         if( *text == 0 )  // Needs data !
         {
             text = text_buffer;
-            GetLine( file, text_buffer, LineNum, 512 );
+            GetLineD( file, text_buffer, LineNum, 512 );
         }
 
         while( !EndNode && *text )
@@ -373,7 +373,7 @@
     double* points = NULL;
     int*    index  = NULL;
 
-    while( GetLine( file, line, LineNum, 512 ) )
+    while( GetLineD( file, line, LineNum, 512 ) )
     {
         strcpy( buffer, line );
         text = strtok( buffer, " \t\n\r" );
@@ -417,7 +417,7 @@
         }
         if( stricmp( text, "normalIndex" ) == 0 )
         {
-            while( GetLine( file, line, LineNum, 512 ) )
+            while( GetLineD( file, line, LineNum, 512 ) )
             {
                 text = strtok( line, " ,\t\n\r" );
                 while( text )
@@ -445,7 +445,7 @@
         }
         if( stricmp( text, "colorIndex" ) == 0 )
         {
-            while( GetLine( file, line, LineNum, 512 ) )
+            while( GetLineD( file, line, LineNum, 512 ) )
             {
                 text = strtok( line, " ,\t\n\r" );
                 while( text )
@@ -472,7 +472,7 @@
             index = (int*) MyMalloc( nn * sizeof(int) );
             S3D_Vertex* coords =
                 (S3D_Vertex*) MyMalloc( nn * sizeof(S3D_Vertex) );
-            while( GetLine( file, line, LineNum, 512 ) )
+            while( GetLineD( file, line, LineNum, 512 ) )
             {
                 int coord_count = 0, jj;
                 text = strtok( line, " ,\t\n\r" );
@@ -529,7 +529,7 @@
 {
     char line[512];
 
-    while( GetLine( file, line, LineNum, 512 ) )
+    while( GetLineD( file, line, LineNum, 512 ) )
     {
     }
 

=== modified file 'common/string.cpp'
--- common/string.cpp	2010-08-03 02:13:33 +0000
+++ common/string.cpp	2011-01-11 20:46:10 +0000
@@ -6,7 +6,7 @@
 #include "fctsys.h"
 #include "macros.h"
 #include "kicad_string.h"
-
+#include "richio.h"
 
 /* read a double-quote delimited text from source and put it in in dest,
  *  read NbMaxChar bytes max
@@ -59,24 +59,34 @@
     return text;
 }
 
+char* GetLineD( FILE* File, char* Line, int* LineNum, int SizeLine )
+{
+     do  {
+        if( fgets( Line, SizeLine, File ) == NULL )
+             return NULL;
+        if( LineNum )
+            *LineNum += 1;
+    } while( Line[0] == '#' || Line[0] == '\n' ||  Line[0] == '\r'
+             || Line[0] == 0 );
+    strtok( Line, "\n\r" );
+    return Line;
+ }
 
 /* Read lines from File
  *  Skip void lines and comments (starting by #)
  *  return the first non void line.
  *  increments *LineNum for each line
  */
-char* GetLine( FILE* File, char* Line, int* LineNum, int SizeLine )
+char* GetLine( LINE_READER* aReader )
 {
+    char* line;
     do  {
-        if( fgets( Line, SizeLine, File ) == NULL )
+        if( !aReader->ReadLine() )
             return NULL;
-        if( LineNum )
-            *LineNum += 1;
-    } while( Line[0] == '#' || Line[0] == '\n' ||  Line[0] == '\r'
-             || Line[0] == 0 );
-
-    strtok( Line, "\n\r" );
-    return Line;
+        line = (char*)(*aReader);
+    } while( line[0] == '#' || line[0] == '\n' ||  line[0] == '\r'
+             || line[0] == 0 );
+    return line;
 }
 
 

=== modified file 'cvpcb/autosel.cpp'
--- cvpcb/autosel.cpp	2010-11-29 15:05:01 +0000
+++ cvpcb/autosel.cpp	2011-01-11 20:37:51 +0000
@@ -106,7 +106,7 @@
             continue;
         }
 
-        while( GetLine( file, Line, NULL, sizeof(Line) ) != NULL )
+        while( GetLineD( file, Line, NULL, sizeof(Line) ) != NULL )
         {
             char* text = Line;
             wxString value, footprint;

=== modified file 'cvpcb/listlib.cpp'
--- cvpcb/listlib.cpp	2009-11-23 21:03:26 +0000
+++ cvpcb/listlib.cpp	2011-01-11 20:38:39 +0000
@@ -181,7 +181,7 @@
     }
 
     /* Check if mdc file is valid */
-    GetLine( mdc_file, Line, NULL, sizeof(Line) - 1 );
+    GetLineD( mdc_file, Line, NULL, sizeof(Line) - 1 );
     if( strnicmp( Line, ENTETE_LIBDOC, L_ENTETE_LIB ) != 0 )
     {
         s_files_invalid += mdc_filename.GetFullPath() + wxT("\n");
@@ -189,7 +189,7 @@
     }
 
     /* Read the mdc file */
-    while( GetLine( mdc_file, Line, NULL, sizeof(Line) - 1 ) )
+    while( GetLineD( mdc_file, Line, NULL, sizeof(Line) - 1 ) )
     {
         NewMod = NULL;
         if( Line[0] != '$' )
@@ -199,7 +199,7 @@
         if( Line[1] == 'M' )
         {
             /* Parse file line by line */
-            while( GetLine( mdc_file, Line, NULL, sizeof(Line) - 1 ) )
+            while( GetLineD( mdc_file, Line, NULL, sizeof(Line) - 1 ) )
             {
                 /* $EndMODULE */
                 if( Line[0] == '$' )

=== modified file 'cvpcb/loadcmp.cpp'
--- cvpcb/loadcmp.cpp	2010-02-01 21:23:27 +0000
+++ cvpcb/loadcmp.cpp	2011-01-11 21:47:51 +0000
@@ -29,7 +29,8 @@
 {
     int        LineNum, Found = 0;
     unsigned   ii;
-    char       Line[1024], Name[255];
+    char*      Line;
+    char       Name[255];
     wxString   tmp, msg;
     wxFileName fn;
     MODULE*    Module = NULL;
@@ -61,9 +62,12 @@
             continue;
         }
 
+        FILE_LINE_READER reader( file, tmp );
+
         /* Read header. */
         LineNum = 0;
-        GetLine( file, Line, &LineNum );
+        GetLine( &reader );
+        Line = (char*) reader;
         StrPurge( Line );
 
         if( strnicmp( Line, ENTETE_LIBRAIRIE, L_ENTETE_LIB ) != 0 )
@@ -76,15 +80,17 @@
         }
 
         Found = 0;
-        while( !Found && GetLine( file, Line, &LineNum ) )
+        while( !Found && GetLine( &reader ) )
         {
+            Line = (char*) reader;
             if( strncmp( Line, "$MODULE", 6 ) == 0 )
                 break;
 
             if( strnicmp( Line, "$INDEX", 6 ) == 0 )
             {
-                while( GetLine( file, Line, &LineNum ) )
+                while( GetLine( &reader ) )
                 {
+                    Line = (char*) reader;
                     if( strnicmp( Line, "$EndINDEX", 9 ) == 0 )
                         break;
 
@@ -98,8 +104,9 @@
             }
         }
 
-        while( Found && GetLine( file, Line, &LineNum ) )
+        while( Found && GetLine( &reader ) )
         {
+            Line = (char*) reader;
             if( Line[0] != '$' )
                 continue;
 
@@ -117,15 +124,13 @@
                 // Switch the locale to standard C (needed to print floating
                 // point numbers like 1.3)
                 SetLocaleTo_C_standard();
-                Module->ReadDescr( file, &LineNum );
+                Module->ReadDescr( &reader );
                 SetLocaleTo_Default();       // revert to the current locale
                 Module->SetPosition( wxPoint( 0, 0 ) );
-                fclose( file );
                 return Module;
             }
         }
 
-        fclose( file );
         file = NULL;
     }
 

=== modified file 'eeschema/backanno.cpp'
--- eeschema/backanno.cpp	2010-12-14 15:56:30 +0000
+++ eeschema/backanno.cpp	2011-01-11 20:41:34 +0000
@@ -90,7 +90,7 @@
     int   LineNum = 0;
     char* cp, Ref[256], FootPrint[256], Line[1024];
 
-    while( GetLine( aFilename, Line, &LineNum, sizeof(Line) ) )
+    while( GetLineD( aFilename, Line, &LineNum, sizeof(Line) ) )
     {
         if( sscanf( Line, "comp = \"%s module = \"%s", Ref, FootPrint ) == 2 )
         {

=== modified file 'eeschema/class_libentry.cpp'
--- eeschema/class_libentry.cpp	2011-01-01 17:28:21 +0000
+++ eeschema/class_libentry.cpp	2011-01-11 20:42:07 +0000
@@ -715,7 +715,7 @@
         || sscanf( p, "%d", &m_unitCount ) != 1 )
     {
         aErrorMsg.Printf( wxT( "Wrong DEF format in line %d, skipped." ), *aLineNum );
-        while( GetLine( aFile, aLine, aLineNum, LINE_BUFFER_LEN_LARGE ) )
+        while( GetLineD( aFile, aLine, aLineNum, LINE_BUFFER_LEN_LARGE ) )
         {
             p = strtok( aLine, " \t\n" );
             if( stricmp( p, "ENDDEF" ) == 0 )
@@ -768,7 +768,7 @@
         m_options = ENTRY_POWER;
 
     /* Read next lines */
-    while( GetLine( aFile, aLine, aLineNum, LINE_BUFFER_LEN_LARGE ) )
+    while( GetLineD( aFile, aLine, aLineNum, LINE_BUFFER_LEN_LARGE ) )
     {
         p = strtok( aLine, " \t\n" );
 
@@ -817,7 +817,7 @@
 
     while( true )
     {
-        if( GetLine( aFile, aLine, aLineNum, LINE_BUFFER_LEN_LARGE ) == NULL )
+        if( GetLineD( aFile, aLine, aLineNum, LINE_BUFFER_LEN_LARGE ) == NULL )
         {
             aErrorMsg = wxT( "file ended prematurely loading component draw element" );
             return false;
@@ -872,7 +872,7 @@
             /* Flush till end of draw section */
             do
             {
-                if( GetLine( aFile, aLine, aLineNum, LINE_BUFFER_LEN_LARGE ) == NULL )
+                if( GetLineD( aFile, aLine, aLineNum, LINE_BUFFER_LEN_LARGE ) == NULL )
                 {
                     aErrorMsg = wxT( "file ended prematurely while attempting \
 to flush to end of drawing section." );
@@ -946,7 +946,7 @@
 {
     while( true )
     {
-        if( GetLine( aFile, aLine, aLineNum, LINE_BUFFER_LEN_LARGE ) == NULL )
+        if( GetLineD( aFile, aLine, aLineNum, LINE_BUFFER_LEN_LARGE ) == NULL )
         {
             aErrorMsg = wxT( "file ended prematurely while loading footprints" );
             return false;

=== modified file 'eeschema/class_library.cpp'
--- eeschema/class_library.cpp	2010-11-10 15:30:12 +0000
+++ eeschema/class_library.cpp	2011-01-11 20:42:33 +0000
@@ -419,7 +419,7 @@
         return false;
     }
 
-    if( GetLine( file, line, &lineNumber, sizeof( line ) ) == NULL )
+    if( GetLineD( file, line, &lineNumber, sizeof( line ) ) == NULL )
     {
         aErrorMsg = _( "The file is empty!" );
         fclose( file );
@@ -491,7 +491,7 @@
         }
     }
 
-    while( GetLine( file, line, &lineNumber, sizeof( line ) ) )
+    while( GetLineD( file, line, &lineNumber, sizeof( line ) ) )
     {
         if( type == LIBRARY_TYPE_EESCHEMA && strnicmp( line, "$HEADER", 7 ) == 0 )
         {
@@ -566,7 +566,7 @@
 {
     char Line[LINE_BUFFER_LEN], * text, * data;
 
-    while( GetLine( libfile, Line, LineNum, sizeof(Line) ) )
+    while( GetLineD( libfile, Line, LineNum, sizeof(Line) ) )
     {
         text = strtok( Line, " \t\r\n" );
         data = strtok( NULL, " \t\r\n" );
@@ -600,7 +600,7 @@
         return false;
     }
 
-    if( GetLine( file, line, &lineNumber, sizeof(line) ) == NULL )
+    if( GetLineD( file, line, &lineNumber, sizeof(line) ) == NULL )
     {
         aErrorMsg.Printf( _( "Component document library file <%s> is empty." ),
                           GetChars( fn.GetFullPath() ) );
@@ -616,7 +616,7 @@
         return false;
     }
 
-    while( GetLine( file, line, &lineNumber, sizeof(line) ) )
+    while( GetLineD( file, line, &lineNumber, sizeof(line) ) )
     {
         if( strncmp( line, "$CMP", 4 ) != 0 )
         {
@@ -632,7 +632,7 @@
 
         entry = FindEntry( cmpname );
 
-        while( GetLine( file, line, &lineNumber, sizeof(line) ) )
+        while( GetLineD( file, line, &lineNumber, sizeof(line) ) )
         {
             if( strncmp( line, "$ENDCMP", 7 ) == 0 )
                 break;

=== modified file 'include/kicad_string.h'
--- include/kicad_string.h	2010-12-19 21:42:55 +0000
+++ include/kicad_string.h	2011-01-11 17:34:42 +0000
@@ -10,6 +10,7 @@
 #define KICAD_STRING_H_
 
 #include <wx/string.h>
+#include "richio.h"
 
 char*    strupper( char* Text );
 char*    strlower( char* Text );
@@ -26,11 +27,17 @@
 /* Read one line line from a file.
  * Returns the first useful line read by eliminating blank lines and comments.
  */
-char*    GetLine( FILE* File,
+char*    GetLineD( FILE* File,
                   char* Line,
                   int*  LineNum = NULL,
                   int   SizeLine = 255 );
 
+/* Read one line line from a file.
+ * Returns the first useful line read by eliminating blank lines and comments.
+ */
+char*    GetLine( LINE_READER *aReader );
+
+
 /* Remove leading and trailing whitespace.
  */
 char*    StrPurge( char* text );

=== modified file 'include/wxBasePcbFrame.h'
--- include/wxBasePcbFrame.h	2011-01-09 11:17:28 +0000
+++ include/wxBasePcbFrame.h	2011-01-11 20:18:31 +0000
@@ -11,6 +11,7 @@
 
 #include "wxstruct.h"
 #include "base_struct.h"
+#include "richio.h"
 
 #ifndef PCB_INTERNAL_UNIT
 #define PCB_INTERNAL_UNIT 10000
@@ -121,15 +122,14 @@
 public:
 
     // Read/write functions:
-    EDA_ITEM* ReadDrawSegmentDescr( FILE* File, int* LineNum );
-    int             ReadListeSegmentDescr( FILE*  File,
+    EDA_ITEM* ReadDrawSegmentDescr( LINE_READER* aReader );
+    int             ReadListeSegmentDescr( LINE_READER* aReader,
                                            TRACK* PtSegm,
                                            int    StructType,
-                                           int*   LineNum,
                                            int    NumSegm );
 
-    int             ReadSetup( FILE* File, int* LineNum );
-    int             ReadGeneralDescrPcb( FILE* File, int* LineNum );
+    int             ReadSetup( LINE_READER* aReader );
+    int             ReadGeneralDescrPcb( LINE_READER* aReader );
 
 
     /**

=== modified file 'include/wxPcbStruct.h'
--- include/wxPcbStruct.h	2010-12-29 17:47:32 +0000
+++ include/wxPcbStruct.h	2011-01-11 19:57:02 +0000
@@ -10,6 +10,7 @@
 #include "base_struct.h"
 #include "param_config.h"
 #include "class_layerchoicebox.h"
+#include "richio.h"
 
 #ifndef PCB_INTERNAL_UNIT
 #define PCB_INTERNAL_UNIT 10000
@@ -594,7 +595,7 @@
      *               the file else all items of the board file are added to the
      *               existing board
      */
-    int  ReadPcbFile( FILE* File, bool Append );
+    int  ReadPcbFile( LINE_READER* aReader, bool Append );
 
     bool SavePcbFile( const wxString& FileName );
     int  SavePcbFormatAscii( FILE* File );

=== modified file 'pcbnew/class_dimension.cpp'
--- pcbnew/class_dimension.cpp	2010-12-29 17:47:32 +0000
+++ pcbnew/class_dimension.cpp	2011-01-11 17:38:08 +0000
@@ -13,6 +13,7 @@
 #include "colors_selection.h"
 #include "kicad_string.h"
 #include "protos.h"
+#include "richio.h"
 
 DIMENSION::DIMENSION( BOARD_ITEM* aParent ) :
     BOARD_ITEM( aParent, TYPE_DIMENSION )
@@ -100,12 +101,14 @@
 }
 
 
-bool DIMENSION::ReadDimensionDescr( FILE* File, int* LineNum )
+bool DIMENSION::ReadDimensionDescr( LINE_READER* aReader )
 {
-    char Line[2048], Text[2048];
+    char* Line;
+    char Text[2048];
 
-    while(  GetLine( File, Line, LineNum ) != NULL )
+    while(  GetLine( aReader ) != NULL )
     {
+        Line = (char*)(*aReader);
         if( strnicmp( Line, "$EndDIMENSION", 4 ) == 0 )
             return TRUE;
 

=== modified file 'pcbnew/class_dimension.h'
--- pcbnew/class_dimension.h	2010-12-29 17:47:32 +0000
+++ pcbnew/class_dimension.h	2011-01-11 17:36:37 +0000
@@ -5,6 +5,7 @@
 #define DIMENSION_H
 
 #include "base_struct.h"
+#include "richio.h"
 
 class DIMENSION : public BOARD_ITEM
 {
@@ -47,7 +48,7 @@
      */
     void AdjustDimensionDetails( bool aDoNotChangeText = false);
 
-    bool    ReadDimensionDescr( FILE* File, int* LineNum );
+    bool    ReadDimensionDescr( LINE_READER* aReader );
 
     /**
      * Function Save

=== modified file 'pcbnew/class_drawsegment.cpp'
--- pcbnew/class_drawsegment.cpp	2010-12-29 17:47:32 +0000
+++ pcbnew/class_drawsegment.cpp	2011-01-11 17:39:21 +0000
@@ -16,6 +16,7 @@
 
 #include "trigo.h"
 #include "protos.h"
+#include "richio.h"
 
 /* DRAWSEGMENT: constructor */
 DRAWSEGMENT::DRAWSEGMENT( BOARD_ITEM* aParent, KICAD_T idtype ) :
@@ -113,16 +114,17 @@
 
 
 /******************************************************************/
-bool DRAWSEGMENT::ReadDrawSegmentDescr( FILE* File, int* LineNum )
+bool DRAWSEGMENT::ReadDrawSegmentDescr( LINE_READER* aReader )
 /******************************************************************/
 
 /* Read a DRAWSEGMENT from a file
  */
 {
-    char Line[2048];
+    char* Line;
 
-    while( GetLine( File, Line, LineNum ) != NULL )
+    while( GetLine( aReader ) != NULL )
     {
+        Line = (char*)(*aReader);
         if( strnicmp( Line, "$End", 4 ) == 0 )
             return TRUE; /* End of description */
         if( Line[0] == 'P' )

=== modified file 'pcbnew/class_drawsegment.h'
--- pcbnew/class_drawsegment.h	2010-12-29 17:47:32 +0000
+++ pcbnew/class_drawsegment.h	2011-01-11 17:38:39 +0000
@@ -5,6 +5,7 @@
 #ifndef CLASS_DRAWSEGMENT_H
 #define CLASS_DRAWSEGMENT_H
 #include "PolyLine.h"
+#include "richio.h"
 
 class DRAWSEGMENT : public BOARD_ITEM
 {
@@ -59,7 +60,7 @@
      */
     bool         Save( FILE* aFile ) const;
 
-    bool         ReadDrawSegmentDescr( FILE* File, int* LineNum );
+    bool         ReadDrawSegmentDescr( LINE_READER* aReader );
 
     void         Copy( DRAWSEGMENT* source );
 

=== modified file 'pcbnew/class_edge_mod.cpp'
--- pcbnew/class_edge_mod.cpp	2011-01-05 17:28:55 +0000
+++ pcbnew/class_edge_mod.cpp	2011-01-11 18:03:12 +0000
@@ -14,6 +14,7 @@
 
 #include "pcbnew.h"
 #include "class_board_design_settings.h"
+#include "richio.h"
 
 #define MAX_WIDTH 10000     /* Thickness (in 1 / 10000 ") of maximum reasonable
                              * features, text... */
@@ -381,12 +382,14 @@
  *  - Polygon
  *
  */
-int EDGE_MODULE::ReadDescr( char* Line, FILE* File,
-                            int* LineNum )
+int EDGE_MODULE::ReadDescr( LINE_READER* aReader )
 {
     int  ii;
     int  error = 0;
-    char Buf[1024];
+    char* Buf;
+    char* Line;
+
+    Line = (char*)(*aReader);
 
     switch( Line[1] )
     {
@@ -439,13 +442,13 @@
                 &m_End0.x, &m_End0.y,
                 &pointCount, &m_Width, &m_Layer );
 
-        (*LineNum)++;
         m_PolyPoints.clear();
         m_PolyPoints.reserve( pointCount );
         for( ii = 0;  ii<pointCount;  ii++ )
         {
-            if( GetLine( File, Buf, LineNum, sizeof(Buf) - 1 ) != NULL )
+            if( GetLine( aReader ) != NULL )
             {
+                Buf = (char*)(*aReader);
                 if( strncmp( Buf, "Dl", 2 ) != 0 )
                 {
                     error = 1;
@@ -457,8 +460,6 @@
                 sscanf( Buf + 3, "%d %d\n", &x, &y );
 
                 m_PolyPoints.push_back( wxPoint( x, y ) );
-
-                (*LineNum)++;
             }
             else
             {

=== modified file 'pcbnew/class_edge_mod.h'
--- pcbnew/class_edge_mod.h	2010-12-10 19:47:44 +0000
+++ pcbnew/class_edge_mod.h	2011-01-11 17:40:20 +0000
@@ -2,6 +2,8 @@
 /* class_edge_module.h : EDGE_MODULE class definition. */
 /*******************************************************/
 
+#include "richio.h"
+
 class Pcb3D_GLCanvas;
 
 
@@ -53,7 +55,7 @@
      */
     bool             Save( FILE* aFile ) const;
 
-    int              ReadDescr( char* Line, FILE* File, int* LineNum = NULL );
+    int              ReadDescr( LINE_READER* aReader );
 
     void             SetDrawCoord();
 

=== modified file 'pcbnew/class_mire.cpp'
--- pcbnew/class_mire.cpp	2010-12-29 17:47:32 +0000
+++ pcbnew/class_mire.cpp	2011-01-11 18:08:25 +0000
@@ -13,6 +13,7 @@
 #include "colors_selection.h"
 #include "trigo.h"
 #include "protos.h"
+#include "richio.h"
 
 
 MIREPCB::MIREPCB( BOARD_ITEM* aParent ) :
@@ -41,12 +42,13 @@
 
 /* Read the description from the PCB file.
  */
-bool MIREPCB::ReadMirePcbDescr( FILE* File, int* LineNum )
+bool MIREPCB::ReadMirePcbDescr( LINE_READER* aReader )
 {
-    char Line[256];
+    char* Line;
 
-    while( GetLine( File, Line, LineNum ) != NULL )
+    while( GetLine( aReader ) != NULL )
     {
+        Line = (char*)(*aReader);
         if( strnicmp( Line, "$End", 4 ) == 0 )
             return TRUE;
         if( Line[0] == 'P' )

=== modified file 'pcbnew/class_mire.h'
--- pcbnew/class_mire.h	2010-12-29 17:47:32 +0000
+++ pcbnew/class_mire.h	2011-01-11 18:07:48 +0000
@@ -5,6 +5,7 @@
 #define MIRE_H
 
 #include "base_struct.h"
+#include "richio.h"
 
 
 class MIREPCB : public BOARD_ITEM
@@ -61,7 +62,7 @@
      */
     bool Save( FILE* aFile ) const;
 
-    bool    ReadMirePcbDescr( FILE* File, int* LineNum );
+    bool    ReadMirePcbDescr( LINE_READER* aReader );
 
     void    Copy( MIREPCB* source );
 

=== modified file 'pcbnew/class_module.cpp'
--- pcbnew/class_module.cpp	2010-12-29 17:47:32 +0000
+++ pcbnew/class_module.cpp	2011-01-11 20:53:19 +0000
@@ -409,9 +409,9 @@
  * The 1st line of descr ($MODULE) is assumed to be already read
  * Returns 0 if OK
  */
-int MODULE::Read_3D_Descr( FILE* File, int* LineNum )
+int MODULE::Read_3D_Descr( LINE_READER* aReader )
 {
-    char        Line[1024];
+    char*       Line = (char*)(*aReader);
     char*       text = Line + 3;
 
     S3D_MASTER* t3D = m_3D_Drawings;
@@ -425,8 +425,9 @@
         t3D = n3D;
     }
 
-    while( GetLine( File, Line, LineNum, sizeof(Line) - 1 ) != NULL )
+    while( GetLine( aReader ) != NULL )
     {
+        Line = (char*)(*aReader);
         switch( Line[0] )
         {
         case '$':
@@ -476,13 +477,15 @@
  *  The first description line ($MODULE) is already read
  *  @return 0 if no error
  */
-int MODULE::ReadDescr( FILE* File, int* LineNum )
+int MODULE::ReadDescr( LINE_READER* aReader )
 {
-    char Line[256], BufLine[256], BufCar1[128], * PtLine;
-    int  itmp1, itmp2;
+    char* Line;
+    char  BufLine[256], BufCar1[128], * PtLine;
+    int   itmp1, itmp2;
 
-    while( GetLine( File, Line, LineNum, sizeof(Line) - 1 ) != NULL )
+    while( GetLine( aReader ) != NULL )
     {
+        Line = (char*)(*aReader);
         if( Line[0] == '$' )
         {
             if( Line[1] == 'E' )
@@ -490,7 +493,7 @@
             if( Line[1] == 'P' )
             {
                 D_PAD* pad = new D_PAD( this );
-                pad->ReadDescr( File, LineNum );
+                pad->ReadDescr( aReader );
                 RotatePoint( &pad->m_Pos, m_Orient );
                 pad->m_Pos.x += m_Pos.x;
                 pad->m_Pos.y += m_Pos.y;
@@ -499,7 +502,7 @@
                 continue;
             }
             if( Line[1] == 'S' )
-                Read_3D_Descr( File, LineNum );
+                Read_3D_Descr( aReader );
         }
 
         if( strlen( Line ) < 4 )
@@ -584,14 +587,14 @@
                 textm = new TEXTE_MODULE( this );
                 m_Drawings.PushBack( textm );
             }
-            textm->ReadDescr( Line, File, LineNum );
+            textm->ReadDescr( aReader );
             break;
 
         case 'D':    /* read a drawing item */
             EDGE_MODULE * edge;
             edge = new EDGE_MODULE( this );
             m_Drawings.PushBack( edge );
-            edge->ReadDescr( Line, File, LineNum );
+            edge->ReadDescr( aReader );
             edge->SetDrawCoord();
             break;
 

=== modified file 'pcbnew/class_module.h'
--- pcbnew/class_module.h	2010-12-29 17:47:32 +0000
+++ pcbnew/class_module.h	2011-01-11 18:10:15 +0000
@@ -6,6 +6,8 @@
 class Pcb3D_GLCanvas;
 class S3D_MASTER;
 
+#include "richio.h"
+
 /************************************/
 /* Modules (footprints) description */
 /* pad are in class_pad.xx          */
@@ -210,7 +212,7 @@
     bool Save( FILE* aFile ) const;
 
     int  Write_3D_Descr( FILE* File ) const;
-    int  ReadDescr( FILE* File, int* LineNum = NULL );
+    int  ReadDescr( LINE_READER* aReader );
 
     /**
      * Function Read_GPCB_Descr
@@ -220,7 +222,7 @@
      * @return bool - true if success reading else false.
      */
     bool Read_GPCB_Descr( const wxString& CmpFullFileName );
-    int  Read_3D_Descr( FILE* File, int* LineNum = NULL );
+    int  Read_3D_Descr( LINE_READER* aReader );
 
     /* drawing functions */
 

=== modified file 'pcbnew/class_netclass.cpp'
--- pcbnew/class_netclass.cpp	2010-07-19 15:40:54 +0000
+++ pcbnew/class_netclass.cpp	2011-01-11 18:04:27 +0000
@@ -332,15 +332,16 @@
 
 
 
-bool NETCLASS::ReadDescr( FILE* aFile, int* aLineNum )
+bool NETCLASS::ReadDescr( LINE_READER* aReader )
 {
     bool        result = false;
-    char        Line[1024];
+    char*       Line;
     char        Buffer[1024];
     wxString    netname;
 
-    while( GetLine( aFile, Line, aLineNum, 1024 ) != NULL )
+    while( GetLine( aReader ) != NULL )
     {
+        Line = (char*)(*aReader);
         if( strnicmp( Line, "AddNet", 6 ) == 0 )
         {
             ReadDelimitedText( Buffer, Line + 6, sizeof(Buffer) );

=== modified file 'pcbnew/class_netclass.h'
--- pcbnew/class_netclass.h	2010-12-29 17:47:32 +0000
+++ pcbnew/class_netclass.h	2011-01-11 18:03:52 +0000
@@ -30,7 +30,7 @@
 
 #include <set>
 #include <map>
-
+#include "richio.h"
 
 /**
  * Class NETCLASS
@@ -210,7 +210,7 @@
      * @param aLineNum a pointer to a line number counter
      * @return bool - true if success reading else false.
      */
-    bool ReadDescr( FILE* aFile, int* aLineNum );
+    bool ReadDescr( LINE_READER* aReader );
 
 #if defined(DEBUG)
 

=== modified file 'pcbnew/class_netinfo.h'
--- pcbnew/class_netinfo.h	2010-12-29 17:47:32 +0000
+++ pcbnew/class_netinfo.h	2011-01-11 18:05:54 +0000
@@ -10,6 +10,7 @@
 #define __CLASSES_NETINFO__
 
 #include "class_netclass.h"
+#include "richio.h"
 
 class NETINFO_ITEM;
 
@@ -317,7 +318,7 @@
 #endif
 
     /* Reading and writing data on files */
-    int  ReadDescr( FILE* File, int* LineNum );
+    int  ReadDescr( LINE_READER* aReader );
 
     /**
      * Function Save

=== modified file 'pcbnew/class_netinfo_item.cpp'
--- pcbnew/class_netinfo_item.cpp	2010-12-29 17:47:32 +0000
+++ pcbnew/class_netinfo_item.cpp	2011-01-11 18:06:37 +0000
@@ -9,7 +9,7 @@
 #include "pcbnew.h"
 #include "class_board_design_settings.h"
 #include "colors_selection.h"
-
+#include "richio.h"
 
 /*********************************************************/
 /* class NETINFO_ITEM: handle data relative to a given net */
@@ -42,13 +42,15 @@
  * Returns 0 if OK
  * 1 if incomplete reading
  */
-int NETINFO_ITEM::ReadDescr( FILE* File, int* LineNum )
+int NETINFO_ITEM::ReadDescr( LINE_READER* aReader )
 {
-    char Line[1024], Ltmp[1024];
-    int  tmp;
+    char* Line;
+    char  Ltmp[1024];
+    int   tmp;
 
-    while( GetLine( File, Line, LineNum ) )
+    while( GetLine( aReader ) )
     {
+        Line = (char*)(*aReader);
         if( strnicmp( Line, "$End", 4 ) == 0 )
             return 0;
 

=== modified file 'pcbnew/class_pad.cpp'
--- pcbnew/class_pad.cpp	2010-12-29 17:47:32 +0000
+++ pcbnew/class_pad.cpp	2011-01-11 18:13:24 +0000
@@ -12,6 +12,7 @@
 #include "trigo.h"
 #include "pcbnew_id.h"             // ID_TRACK_BUTT
 #include "class_board_design_settings.h"
+#include "richio.h"
 
 int D_PAD::m_PadSketchModePenSize = 0;   // Pen size used to draw pads in sketch mode
 
@@ -355,14 +356,16 @@
  * Po 6000 -6000
  * $EndPAD
  */
-int D_PAD::ReadDescr( FILE* File, int* LineNum )
+int D_PAD::ReadDescr( LINE_READER* aReader )
 {
-    char  Line[1024], BufLine[1024], BufCar[256];
+    char* Line;
+    char  BufLine[1024], BufCar[256];
     char* PtLine;
     int   nn, ll, dx, dy;
 
-    while( GetLine( File, Line, LineNum ) != NULL )
+    while( GetLine( aReader ) != NULL )
     {
+        Line = (char*)(*aReader);
         if( Line[0] == '$' )
             return 0;
 

=== modified file 'pcbnew/class_pad.h'
--- pcbnew/class_pad.h	2010-12-29 17:47:32 +0000
+++ pcbnew/class_pad.h	2011-01-11 18:12:47 +0000
@@ -6,6 +6,7 @@
 
 #include "pad_shapes.h"
 #include "PolyLine.h"
+#include "richio.h"
 
 /* Default layers used for pads, according to the pad type.
  * this is default values only, they can be changed for a given pad
@@ -218,7 +219,7 @@
     wxSize        GetSolderPasteMargin();
 
     /* Reading and writing data on files */
-    int           ReadDescr( FILE* File, int* LineNum = NULL );
+    int           ReadDescr( LINE_READER* aReader );
 
     /**
      * Function Save

=== modified file 'pcbnew/class_pcb_text.cpp'
--- pcbnew/class_pcb_text.cpp	2010-12-29 17:47:32 +0000
+++ pcbnew/class_pcb_text.cpp	2011-01-11 18:31:10 +0000
@@ -15,6 +15,7 @@
 #include "colors_selection.h"
 #include "trigo.h"
 #include "protos.h"
+#include "richio.h"
 
 
 /*******************/
@@ -77,13 +78,15 @@
  * $EndTEXTPCB
  * Nl "line nn" is a line added to the current text
  */
-int TEXTE_PCB::ReadTextePcbDescr( FILE* File, int* LineNum )
+int TEXTE_PCB::ReadTextePcbDescr( LINE_READER* aReader )
 {
-    char text[1024], Line[1024];
-    char style[256];
+    char* Line;
+    char  text[1024];
+    char  style[256];
 
-    while( GetLine( File, Line, LineNum ) != NULL )
+    while( GetLine( aReader ) != NULL )
     {
+        Line = (char*)(*aReader);
         if( strnicmp( Line, "$EndTEXTPCB", 11 ) == 0 )
             return 0;
         if( strncmp( Line, "Te", 2 ) == 0 ) /* Text line (first line for multi line texts */

=== modified file 'pcbnew/class_pcb_text.h'
--- pcbnew/class_pcb_text.h	2010-12-29 17:47:32 +0000
+++ pcbnew/class_pcb_text.h	2011-01-11 18:30:28 +0000
@@ -6,6 +6,7 @@
 
 #include "base_struct.h"
 #include "PolyLine.h"
+#include "richio.h"
 
 class TEXTE_PCB : public BOARD_ITEM, public EDA_TextStruct
 {
@@ -57,7 +58,7 @@
                const wxPoint& offset = ZeroOffset );
 
     // File Operations:
-    int ReadTextePcbDescr( FILE* File, int* LineNum );
+    int ReadTextePcbDescr( LINE_READER* aReader );
 
     /**
      * Function Save

=== modified file 'pcbnew/class_text_mod.cpp'
--- pcbnew/class_text_mod.cpp	2011-01-09 11:17:28 +0000
+++ pcbnew/class_text_mod.cpp	2011-01-11 18:28:39 +0000
@@ -14,6 +14,7 @@
 #include "pcbcommon.h"
 #include "class_board_design_settings.h"
 #include "colors_selection.h"
+#include "richio.h"
 
 /*******************************************************************/
 /* Class TEXTE_MODULE base class type of text elements in a module */
@@ -100,12 +101,15 @@
  * @param aLineNum a point to the line count (currently not used).
  * @return int - > 0 if success reading else 0.
  */
-int TEXTE_MODULE::ReadDescr( char* aLine, FILE* aFile, int* aLineNum )
+int TEXTE_MODULE::ReadDescr( LINE_READER* aReader )
 {
     int  success = true;
     int  type;
     int  layer;
     char BufCar1[128], BufCar2[128], BufCar3[128], BufLine[256];
+    char *aLine;
+
+    aLine = (char*)(*aReader);
 
     layer = SILKSCREEN_N_FRONT;
     BufCar1[0] = 0;

=== modified file 'pcbnew/class_text_mod.h'
--- pcbnew/class_text_mod.h	2011-01-09 11:17:28 +0000
+++ pcbnew/class_text_mod.h	2011-01-11 18:27:54 +0000
@@ -6,6 +6,7 @@
 #ifndef TEXT_MODULE_H
 #define TEXT_MODULE_H
 
+#include "richio.h"
 
 #define TEXT_is_REFERENCE 0
 #define TEXT_is_VALUE     1
@@ -87,7 +88,7 @@
      * @param aLineNum a point to the line count (currently not used).
      * @return int - > 0 if success reading else 0.
      */
-    int      ReadDescr( char* aLine, FILE* aFile, int* aLineNum = NULL );
+    int      ReadDescr( LINE_READER* aReader );
 
     /* drawing functions */
     void     Draw( WinEDA_DrawPanel* panel,

=== modified file 'pcbnew/class_zone.cpp'
--- pcbnew/class_zone.cpp	2010-12-14 15:56:30 +0000
+++ pcbnew/class_zone.cpp	2011-01-11 18:36:19 +0000
@@ -17,6 +17,7 @@
 #include "colors_selection.h"
 
 #include "protos.h"
+#include "richio.h"
 
 /************************/
 /* class ZONE_CONTAINER */
@@ -215,7 +216,7 @@
 
 
 /**********************************************************/
-int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
+int ZONE_CONTAINER::ReadDescr( LINE_READER* aReader )
 /**********************************************************/
 
 /**
@@ -225,16 +226,17 @@
  * @return 1 if ok or 0
  */
 {
-    char Line[1024], * text;
-    char netname_buffer[1024];
-    int  ret;
-    int  n_corner_item = 0;
-    int  outline_hatch = CPolyLine::NO_HATCH;
-    bool error = false, has_corner = false;
+    char* Line, * text;
+    char  netname_buffer[1024];
+    int   ret;
+    int   n_corner_item = 0;
+    int   outline_hatch = CPolyLine::NO_HATCH;
+    bool  error = false, has_corner = false;
 
     netname_buffer[0] = 0;
-    while( GetLine( aFile, Line, aLineNum, sizeof(Line) - 1 ) != NULL )
+    while( GetLine( aReader ) != NULL )
     {
+        Line = (char*)(*aReader);
         if( strnicmp( Line, "ZCorner", 7 ) == 0 ) // new corner found
         {
             int x;
@@ -382,8 +384,9 @@
 
         else if( strnicmp( Line, "$POLYSCORNERS", 13 ) == 0  )  // Read the PolysList (polygons used for fill areas in the zone)
         {
-            while( GetLine( aFile, Line, aLineNum, sizeof(Line) - 1 ) != NULL )
+            while( GetLine( aReader ) != NULL )
             {
+                Line = (char*)(*aReader);
                 if( strnicmp( Line, "$endPOLYSCORNERS", 4 ) == 0  )
                     break;
                 CPolyPt corner;
@@ -401,8 +404,9 @@
         else if( strnicmp( Line, "$FILLSEGMENTS", 13) == 0  )
         {
             SEGMENT segm;
-            while( GetLine( aFile, Line, aLineNum, sizeof(Line) - 1 ) != NULL )
+            while( GetLine( aReader ) != NULL )
             {
+                Line = (char*)(*aReader);
                 if( strnicmp( Line, "$endFILLSEGMENTS", 4 ) == 0  )
                     break;
                 ret = sscanf( Line, "%d %d %d %d", &segm.m_Start.x, &segm.m_Start.y, &segm.m_End.x, &segm.m_End.y );

=== modified file 'pcbnew/class_zone.h'
--- pcbnew/class_zone.h	2010-12-14 15:56:30 +0000
+++ pcbnew/class_zone.h	2011-01-11 18:32:40 +0000
@@ -8,6 +8,7 @@
 #include <vector>
 #include "gr_basic.h"
 #include "PolyLine.h"
+#include "richio.h"
 
 /* a small class used when filling areas with segments */
 class SEGMENT
@@ -66,7 +67,7 @@
     ~ZONE_CONTAINER();
 
     bool     Save( FILE* aFile ) const;
-    int      ReadDescr( FILE* aFile, int* aLineNum = NULL );
+    int      ReadDescr( LINE_READER* aReader );
 
     /** virtual function GetPosition
      * @return a wxPoint, position of the first point of the outline

=== modified file 'pcbnew/files.cpp'
--- pcbnew/files.cpp	2010-12-29 17:47:32 +0000
+++ pcbnew/files.cpp	2011-01-11 20:48:38 +0000
@@ -13,6 +13,7 @@
 #include "protos.h"
 #include "pcbnew_id.h"
 #include "3d_viewer.h"
+#include "richio.h"
 
 #define BACKUP_FILE_EXT wxT( "000" )
 
@@ -134,10 +135,8 @@
 bool WinEDA_PcbFrame::LoadOnePcbFile( const wxString& aFileName, bool aAppend,
                                       bool aForceFileDialog )
 {
-    int      ii;
     FILE*    source;
     wxString msg;
-    char     cbuf[1024];
 
     ActiveScreen = GetScreen();
 
@@ -198,18 +197,18 @@
         return false;
     }
 
+    FILE_LINE_READER reader( source, GetScreen()->m_FileName );
 
     /* Read header and TEST if it is a PCB file format */
-    GetLine( source, cbuf, &ii );
-    if( strncmp( cbuf, "PCBNEW-BOARD", 12 ) != 0 )
+    GetLine( &reader );
+    if( strncmp( (char*) reader, "PCBNEW-BOARD", 12 ) != 0 )
     {
-        fclose( source );
         DisplayError( this, wxT( "Unknown file type" ) );
         return false;
     }
 
     int ver;
-    sscanf(cbuf, "PCBNEW-BOARD Version %d date", &ver );
+    sscanf( (char*) reader , "PCBNEW-BOARD Version %d date", &ver );
     if ( ver > g_CurrentVersionPCB )
     {
         DisplayInfoMessage( this, _( "This file was created by a more recent \
@@ -225,7 +224,7 @@
     // Reload the corresponding configuration file:
     wxSetWorkingDirectory( wxPathOnly( GetScreen()->m_FileName ) );
     if( aAppend )
-        ReadPcbFile( source, true );
+        ReadPcbFile( &reader, true );
     else
     {
         // Update the option toolbar
@@ -235,12 +234,10 @@
         m_DisplayPadFill = DisplayOpt.DisplayPadFill;
         m_DisplayViaFill = DisplayOpt.DisplayViaFill;
 
-        ReadPcbFile( source, false );
+        ReadPcbFile( &reader, false );
         LoadProjectSettings( GetScreen()->m_FileName );
     }
 
-    fclose( source );
-
     GetScreen()->ClrModify();
 
     /* If append option: change the initial board name to <oldname>-append.brd */

=== modified file 'pcbnew/gpcb_exchange.cpp'
--- pcbnew/gpcb_exchange.cpp	2010-12-28 11:24:42 +0000
+++ pcbnew/gpcb_exchange.cpp	2011-01-11 21:27:52 +0000
@@ -155,8 +155,7 @@
     double        conv_unit = NEW_GPCB_UNIT_CONV; // GPCB unit = 0.01 mils and pcbnew 0.1
     // Old version unit = 1 mil, so conv_unit is 10 or 0.1
     bool          success = true;
-    char          Line[1024];
-    int           NbLine = 0;
+    char*         Line;
     long          ibuf[100];
     EDGE_MODULE*  DrawSegm;
     D_PAD*        Pad;
@@ -166,7 +165,11 @@
     if( ( cmpfile = wxFopen( CmpFullFileName, wxT( "rt" ) ) ) == NULL )
         return false;
 
-    GetLine( cmpfile, Line, &NbLine );
+    FILE_LINE_READER reader( cmpfile, CmpFullFileName );
+
+    GetLine( &reader );
+
+    Line = (char*) reader;
 
     params.Clear();
     Extract_Parameters( params, Line );
@@ -176,7 +179,6 @@
 
     if( params[iprmcnt].CmpNoCase( wxT( "Element" ) ) != 0 )
     {
-        fclose( cmpfile );
         return false;
     }
 
@@ -232,8 +234,9 @@
     m_Value->m_Size   = m_Reference->m_Size;
     m_Value->m_Thickness  = m_Reference->m_Thickness;
 
-    while( GetLine( cmpfile, Line, &NbLine, sizeof(Line) - 1 ) != NULL )
+    while( GetLine( &reader ) != NULL )
     {
+        Line = (char*) reader;
         params.Clear();
         Extract_Parameters( params, Line );
         if( params.GetCount() > 3 )    // Test units value for a string line param (more than 3 params : ident [ xx ] )
@@ -409,8 +412,6 @@
         }
     }
 
-    fclose( cmpfile );
-
     if( m_Value->m_Text.IsEmpty() )
         m_Value->m_Text = wxT( "Val**" );
     if( m_Reference->m_Text.IsEmpty() )

=== modified file 'pcbnew/ioascii.cpp'
--- pcbnew/ioascii.cpp	2010-12-08 20:12:46 +0000
+++ pcbnew/ioascii.cpp	2011-01-11 21:17:47 +0000
@@ -80,21 +80,21 @@
 /** Read a list of segments (Tracks, zones)
  * @return items count or - count if no end block ($End...) found.
  */
-int WinEDA_BasePcbFrame::ReadListeSegmentDescr( FILE*  File,
+int WinEDA_BasePcbFrame::ReadListeSegmentDescr( LINE_READER* aReader,
                                                 TRACK* insertBeforeMe,
                                                 int    StructType,
-                                                int*   LineNum,
                                                 int    NumSegm )
 {
     int    shape, width, drill, layer, type, flags, net_code;
     int    ii = 0;
-    char   line1[256];
-    char   line2[256];
+    char*  line1, * line2;
 
     TRACK* newTrack;
 
-    while( GetLine( File, line1, LineNum ) )
+    while( GetLine( aReader ) )
     {
+        line1 = new char[ strlen( (char*)(*aReader) ) + 1 ];
+        strcpy( line1, (char*)(*aReader) );
         int           makeType;
         unsigned long timeStamp;
 
@@ -108,9 +108,11 @@
         // differentiates between TYPE_TRACK and TYPE_VIA.  With virtual
         // functions in use, it is critical to instantiate the TYPE_VIA
         // exactly.
-        if( GetLine( File, line2, LineNum ) == NULL )
+        if( GetLine( aReader ) == NULL )
             break;
 
+        line2 = (char*)(*aReader);
+
         if( line2[0] == '$' )
             break;
 
@@ -150,6 +152,8 @@
                                 &newTrack->m_End.x, &newTrack->m_End.y, &width,
                                 &drill );
 
+        delete[] line1;
+
         newTrack->m_Width = width;
         newTrack->m_Shape = shape;
 
@@ -176,12 +180,13 @@
 }
 
 
-int WinEDA_BasePcbFrame::ReadGeneralDescrPcb( FILE* File, int* LineNum )
+int WinEDA_BasePcbFrame::ReadGeneralDescrPcb( LINE_READER* aReader )
 {
-    char Line[1024], * data;
+    char* Line, * data;
 
-    while(  GetLine( File, Line, LineNum ) != NULL )
+    while(  GetLine( aReader ) != NULL )
     {
+        Line = (char*)(*aReader);
         data = strtok( Line, " =\n\r" );
         if( strnicmp( data, "$EndGENERAL", 10 ) == 0 )
             break;
@@ -294,15 +299,16 @@
 }
 
 
-int WinEDA_BasePcbFrame::ReadSetup( FILE* File, int* LineNum )
+int WinEDA_BasePcbFrame::ReadSetup( LINE_READER* aReader )
 {
-    char      Line[1024];
+    char*     Line;
     char*     data;
 
     NETCLASS* netclass_default = GetBoard()->m_NetClasses.GetDefault();
 
-    while(  GetLine( File, Line, LineNum ) != NULL )
+    while(  GetLine( aReader ) != NULL )
     {
+        Line = (char*)(*aReader);
         strtok( Line, " =\n\r" );
         data = strtok( NULL, " =\n\r" );
 
@@ -777,12 +783,13 @@
 }
 
 
-static bool ReadSheetDescr( BASE_SCREEN* screen, FILE* File, int* LineNum )
+static bool ReadSheetDescr( BASE_SCREEN* screen, LINE_READER* aReader )
 {
-    char Line[1024], buf[1024], * text;
+    char* Line, buf[1024], * text;
 
-    while(  GetLine( File, Line, LineNum ) != NULL )
+    while(  GetLine( aReader ) != NULL )
     {
+        Line = (char*)(*aReader);
         if( strnicmp( Line, "$End", 4 ) == 0 )
             return TRUE;
 
@@ -874,10 +881,9 @@
 }
 
 
-int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append )
+int WinEDA_PcbFrame::ReadPcbFile( LINE_READER* aReader, bool Append )
 {
-    char         Line[1024];
-    int          LineNum = 0;
+    char*        Line;
 
     wxBusyCursor dummy;
 
@@ -897,8 +903,9 @@
     // string.
 #define TESTLINE( x ) (strncmp( Line, "$" x, sizeof("$" x) - 1 ) == 0)
 
-    while( GetLine( File, Line, &LineNum ) != NULL )
+    while( GetLine( aReader ) != NULL )
     {
+        Line = (char*)(*aReader);
         // put the more frequent ones at the top
 
         if( TESTLINE( "MODULE" ) )
@@ -909,7 +916,7 @@
                 continue;
 
             board->Add( Module, ADD_APPEND );
-            Module->ReadDescr( File, &LineNum );
+            Module->ReadDescr( aReader );
             continue;
         }
 
@@ -917,7 +924,7 @@
         {
             DRAWSEGMENT* DrawSegm = new DRAWSEGMENT( board );
             board->Add( DrawSegm, ADD_APPEND );
-            DrawSegm->ReadDrawSegmentDescr( File, &LineNum );
+            DrawSegm->ReadDrawSegmentDescr( aReader );
             continue;
         }
 
@@ -925,7 +932,7 @@
         {
             NETINFO_ITEM* net = new NETINFO_ITEM( board );
             board->m_NetInfo->AppendNet( net );
-            net->ReadDescr( File, &LineNum );
+            net->ReadDescr( aReader );
             continue;
         }
 
@@ -933,7 +940,7 @@
         {
             TEXTE_PCB* pcbtxt = new TEXTE_PCB( board );
             board->Add( pcbtxt, ADD_APPEND );
-            pcbtxt->ReadTextePcbDescr( File, &LineNum );
+            pcbtxt->ReadTextePcbDescr( aReader );
             continue;
         }
 
@@ -941,8 +948,8 @@
         {
 #ifdef PCBNEW
             TRACK* insertBeforeMe = Append ? NULL : board->m_Track.GetFirst();
-            ReadListeSegmentDescr( File, insertBeforeMe, TYPE_TRACK,
-                                   &LineNum, NbTrack );
+            ReadListeSegmentDescr( aReader, insertBeforeMe, TYPE_TRACK,
+                                   NbTrack );
 #endif
             continue;
         }
@@ -953,7 +960,7 @@
             NETCLASS* netclass = new NETCLASS( board, wxEmptyString );
 
             // fill it from the *.brd file, and establish its name.
-            netclass->ReadDescr( File, &LineNum );
+            netclass->ReadDescr( aReader );
 
             if( !board->m_NetClasses.Add( netclass ) )
             {
@@ -971,7 +978,7 @@
         if( TESTLINE( "CZONE_OUTLINE" ) )
         {
             ZONE_CONTAINER* zone_descr = new ZONE_CONTAINER( board );
-            zone_descr->ReadDescr( File, &LineNum );
+            zone_descr->ReadDescr( aReader );
             if( zone_descr->GetNumCorners() > 2 )       // should always occur
                 board->Add( zone_descr );
             else
@@ -983,7 +990,7 @@
         {
             DIMENSION* Dimension = new DIMENSION( board );
             board->Add( Dimension, ADD_APPEND );
-            Dimension->ReadDimensionDescr( File, &LineNum );
+            Dimension->ReadDimensionDescr( aReader );
             continue;
         }
 
@@ -991,7 +998,7 @@
         {
             MIREPCB* Mire = new MIREPCB( board );
             board->Add( Mire, ADD_APPEND );
-            Mire->ReadMirePcbDescr( File, &LineNum );
+            Mire->ReadMirePcbDescr( aReader );
             continue;
         }
 
@@ -1000,21 +1007,21 @@
 #ifdef PCBNEW
             SEGZONE* insertBeforeMe = Append ? NULL : board->m_Zone.GetFirst();
 
-            ReadListeSegmentDescr( File, insertBeforeMe, TYPE_ZONE,
-                                   &LineNum, NbZone );
+            ReadListeSegmentDescr( aReader, insertBeforeMe, TYPE_ZONE,
+                                   NbZone );
 #endif
             continue;
         }
 
         if( TESTLINE( "GENERAL" ) )
         {
-            ReadGeneralDescrPcb( File, &LineNum );
+            ReadGeneralDescrPcb( aReader );
             continue;
         }
 
         if( TESTLINE( "SHEETDESCR" ) )
         {
-            ReadSheetDescr( GetScreen(), File, &LineNum );
+            ReadSheetDescr( GetScreen(), aReader );
             continue;
         }
 
@@ -1022,13 +1029,15 @@
         {
             if( !Append )
             {
-                ReadSetup( File, &LineNum );
+                ReadSetup( aReader );
             }
             else
             {
-                while( GetLine( File, Line, &LineNum ) != NULL )
+                while( GetLine( aReader ) != NULL ) {
+                    Line = (char*)(*aReader);
                     if( TESTLINE( "EndSETUP" ) )
                         break;
+                }
             }
             continue;
         }

=== modified file 'pcbnew/librairi.cpp'
--- pcbnew/librairi.cpp	2011-01-09 11:17:28 +0000
+++ pcbnew/librairi.cpp	2011-01-11 20:26:51 +0000
@@ -47,8 +47,7 @@
  */
 MODULE* WinEDA_ModuleEditFrame::Import_Module( )
 {
-    int       NbLine = 0;
-    char      Line[1024];
+    char*     Line;
     FILE*     file;
     MODULE*   module = NULL;
     bool      Footprint_Is_GPCB_Format = false;
@@ -76,6 +75,8 @@
         return NULL;
     }
 
+    FILE_LINE_READER reader( file, dlg.GetPath() );
+
     if( Config )    // Save file path
     {
         LastOpenedPathForLoading = wxPathOnly( dlg.GetPath() );
@@ -87,7 +88,8 @@
     SetLocaleTo_C_standard();
 
     /* Read header and test file type */
-    GetLine( file, Line, &NbLine );
+    GetLine( &reader );
+    Line = (char*) reader;
     if( strnicmp( Line, ENTETE_LIBRAIRIE, L_ENTETE_LIB ) != 0 )
     {
         if( strnicmp( Line, "Element", 7 ) == 0 )
@@ -103,7 +105,7 @@
     /* Read file: Search the description starting line (skip lib header)*/
     if( !Footprint_Is_GPCB_Format )
     {
-        while( GetLine( file, Line, &NbLine ) != NULL )
+        while( GetLine( &reader ) != NULL )
         {
             if( strnicmp( Line, "$MODULE", 7 ) == 0 )
                 break;
@@ -114,13 +116,11 @@
 
     if( Footprint_Is_GPCB_Format )
     {
-        fclose( file );
         module->Read_GPCB_Descr( dlg.GetPath() );
     }
     else
     {
-        module->ReadDescr( file, &NbLine );
-        fclose( file );
+        module->ReadDescr( &reader );
     }
     SetLocaleTo_Default();       // revert to the current locale
 
@@ -250,7 +250,7 @@
 
 
     /* Read header. */
-    GetLine( lib_module, Line, &LineNum );
+    GetLineD( lib_module, Line, &LineNum );
 
     if( strnicmp( Line, ENTETE_LIBRAIRIE, L_ENTETE_LIB ) != 0 )
     {
@@ -260,11 +260,11 @@
     }
 
     /* Read module names.  */
-    while( GetLine( lib_module, Line, &LineNum ) )
+    while( GetLineD( lib_module, Line, &LineNum ) )
     {
         if( strnicmp( Line, "$INDEX", 6 ) == 0 )
         {
-            while( GetLine( lib_module, Line, &LineNum ) )
+            while( GetLineD( lib_module, Line, &LineNum ) )
             {
                 StrPurge( Line );
                 msg = CONV_FROM_UTF8( Line );
@@ -308,15 +308,15 @@
     fprintf( dest, "  %s\n$INDEX\n", DateAndTime( Line ) );
 
     fseek( lib_module, 0, 0 );
-    GetLine( lib_module, Line, &ii );
+    GetLineD( lib_module, Line, &ii );
 
-    while( GetLine( lib_module, Line, &ii ) )
+    while( GetLineD( lib_module, Line, &ii ) )
     {
         if( strnicmp( Line, "$M", 2 ) == 0 )
             break;
         if( strnicmp( Line, "$INDEX", 6 ) == 0 )
         {
-            while( GetLine( lib_module, Line, &ii ) )
+            while( GetLineD( lib_module, Line, &ii ) )
             {
                 if( strnicmp( Line, "$EndINDEX", 9 ) == 0 )
                     break;
@@ -333,7 +333,7 @@
     fprintf( dest, "$EndINDEX\n" );
 
     /* Copy modules. */
-    while( GetLine( lib_module, Line, &LineNum ) )
+    while( GetLineD( lib_module, Line, &LineNum ) )
     {
         StrPurge( Line );
         if( strnicmp( Line, "$MODULE", 7 ) == 0 )
@@ -343,7 +343,7 @@
             if( msg.CmpNoCase( CmpName ) == 0 )
             {
                 /* Delete old module. */
-                while( GetLine( lib_module, Line, &LineNum ) )
+                while( GetLineD( lib_module, Line, &LineNum ) )
                 {
                     if( strnicmp( Line, "$EndMODULE", 9 ) == 0 )
                         break;
@@ -541,7 +541,7 @@
     }
 
     /* Read library file : library header */
-    GetLine( lib_module, Line, &LineNum );
+    GetLineD( lib_module, Line, &LineNum );
     if( strnicmp( Line, ENTETE_LIBRAIRIE, L_ENTETE_LIB ) != 0 )
     {
         fclose( lib_module );
@@ -553,14 +553,14 @@
 
     /* Read footprints in lib: - search for an existing footprint */
     newmodule = 1; end = 0;
-    while( !end && GetLine( lib_module, Line, &LineNum ) )
+    while( !end && GetLineD( lib_module, Line, &LineNum ) )
     {
         if( Line[0] != '$' )
             continue;
         if( strncmp( Line + 1, "INDEX", 5 ) != 0 )
             continue;
 
-        while( GetLine( lib_module, Line, &LineNum ) )
+        while( GetLineD( lib_module, Line, &LineNum ) )
         {
             if( strncmp( Line, "$EndINDEX", 9 ) == 0 )
             {
@@ -622,15 +622,15 @@
     fprintf( dest, "  %s\n$INDEX\n", DateAndTime( Line ) );
 
     LineNum = 0;
-    GetLine( lib_module, Line, &LineNum );
-    while( GetLine( lib_module, Line, &LineNum ) )
+    GetLineD( lib_module, Line, &LineNum );
+    while( GetLineD( lib_module, Line, &LineNum ) )
     {
         StrPurge( Line );
         if( strnicmp( Line, "$M", 2 ) == 0 )
             break;
         if( strnicmp( Line, "$INDEX", 6 ) == 0 )
         {
-            while( GetLine( lib_module, Line, &LineNum ) )
+            while( GetLineD( lib_module, Line, &LineNum ) )
             {
                 if( strnicmp( Line, "$EndINDEX", 9 ) == 0 )
                     break;
@@ -646,7 +646,7 @@
     fprintf( dest, "$EndINDEX\n" );
 
     /* Copy footprints, until the old footprint to delete */
-    while( GetLine( lib_module, Line, &LineNum ) )
+    while( GetLineD( lib_module, Line, &LineNum ) )
     {
         StrPurge( Line );
         if( strnicmp( Line, "$EndLIBRARY", 8 ) == 0 )
@@ -658,7 +658,7 @@
             if( msg.CmpNoCase( Name_Cmp ) == 0 )
             {
                 /* skip old footprint descr (delete from the lib) */
-                while( GetLine( lib_module, Line, &LineNum ) )
+                while( GetLineD( lib_module, Line, &LineNum ) )
                 {
                     if( strnicmp( Line, "$EndMODULE", 9 ) == 0 )
                         break;
@@ -853,7 +853,7 @@
         return false;
 
     /* Read library header. */
-    GetLine( LibMod, Line, NULL, sizeof(Line) - 1 );
+    GetLineD( LibMod, Line, NULL, sizeof(Line) - 1 );
     if( strnicmp( Line, ENTETE_LIBRAIRIE, L_ENTETE_LIB ) != 0 )
     {
         fclose( LibMod );
@@ -871,13 +871,13 @@
 
     /* Read library. */
     Name = Doc = KeyWord = wxEmptyString;
-    while( GetLine( LibMod, Line, NULL, sizeof(Line) - 1 ) )
+    while( GetLineD( LibMod, Line, NULL, sizeof(Line) - 1 ) )
     {
         if( Line[0] != '$' )
             continue;
         if( strnicmp( Line, "$MODULE", 6 ) == 0 )
         {
-            while( GetLine( LibMod, Line, NULL, sizeof(Line) - 1 ) )
+            while( GetLineD( LibMod, Line, NULL, sizeof(Line) - 1 ) )
             {
                 if( Line[0] == '$' )
                 {
@@ -885,7 +885,7 @@
                         break;
                     if( Line[1] == 'P' ) /* Pad Descr */
                     {
-                        while( GetLine( LibMod, Line, NULL, sizeof(Line) - 1 ) )
+                        while( GetLineD( LibMod, Line, NULL, sizeof(Line) - 1 ) )
                         {
                             if( (Line[0] == '$') && (Line[1] == 'E') )
                                 break;
@@ -921,7 +921,7 @@
 
         if( strnicmp( Line, "$INDEX", 6 ) == 0 )
         {
-            while( GetLine( LibMod, Line, NULL, sizeof(Line) - 1 ) )
+            while( GetLineD( LibMod, Line, NULL, sizeof(Line) - 1 ) )
             {
                 if( strnicmp( Line, "$EndINDEX", 9 ) == 0 )
                     break;

=== modified file 'pcbnew/loadcmp.cpp'
--- pcbnew/loadcmp.cpp	2010-12-29 17:47:32 +0000
+++ pcbnew/loadcmp.cpp	2011-01-11 20:33:47 +0000
@@ -215,7 +215,7 @@
 {
     int        LineNum, Found = 0;
     wxFileName fn;
-    char       Line[512];
+    char*      Line;
     wxString   Name;
     wxString   msg, tmp;
     MODULE*    NewModule;
@@ -256,12 +256,15 @@
             continue;
         }
 
+        FILE_LINE_READER reader( file, tmp );
+
         msg.Printf( _( "Scan Lib: %s" ), GetChars( tmp ) );
         Affiche_Message( msg );
 
         /* Reading header ENTETE_LIBRAIRIE */
         LineNum = 0;
-        GetLine( file, Line, &LineNum );
+        GetLine( &reader );
+        Line = (char*) reader;
         StrPurge( Line );
         if( strnicmp( Line, ENTETE_LIBRAIRIE, L_ENTETE_LIB ) != 0 )
         {
@@ -269,20 +272,21 @@
                         GetChars( tmp ) );
             wxMessageBox( msg, _( "Library Load Error" ),
                           wxOK | wxICON_ERROR, this );
-            fclose( file );
             return NULL;
         }
 
         /* Reading the list of modules in the library. */
         Found = 0;
-        while( !Found && GetLine( file, Line, &LineNum ) )
+        while( !Found && GetLine( &reader ) )
         {
+            Line = (char*) reader;
             if( strnicmp( Line, "$MODULE", 6 ) == 0 )
                 break;
             if( strnicmp( Line, "$INDEX", 6 ) == 0 )
             {
-                while( GetLine( file, Line, &LineNum ) )
+                while( GetLine( &reader ) )
                 {
+                    Line = (char*) reader;
                     if( strnicmp( Line, "$EndINDEX", 9 ) == 0 )
                         break;
                     StrPurge( Line );
@@ -297,8 +301,9 @@
         }
 
         /* Read library. */
-        while( Found && GetLine( file, Line, &LineNum ) )
+        while( Found && GetLine( &reader ) )
         {
+            Line = (char*) reader;
             if( Line[0] != '$' )
                 continue;
             if( Line[1] != 'M' )
@@ -315,16 +320,14 @@
                 // Switch the locale to standard C (needed to print
                 // floating point numbers like 1.3)
                 SetLocaleTo_C_standard();
-                NewModule->ReadDescr( file, &LineNum );
+                NewModule->ReadDescr( &reader );
                 SetLocaleTo_Default();         // revert to the current locale
                 GetBoard()->Add( NewModule, ADD_APPEND );
-                fclose( file );
                 Affiche_Message( wxEmptyString );
                 return NewModule;
             }
         }
 
-        fclose( file );
         if( one_lib )
             break;
     }
@@ -360,7 +363,7 @@
 {
     int             LineNum;
     unsigned        ii;
-    char            Line[1024];
+    char*           Line;
     wxFileName      fn;
     static wxString OldName;    /* Save the name of the last module loaded. */
     wxString        CmpName, tmp;
@@ -412,13 +415,16 @@
             continue;
         }
 
+        FILE_LINE_READER reader( file, tmp );
+
         // Statusbar library loaded message
         msg = _( "Library " ) + fn.GetFullPath() + _( " loaded" );
         Affiche_Message( msg );
 
         /* Read header. */
         LineNum = 0;
-        GetLine( file, Line, &LineNum, sizeof(Line) - 1 );
+        GetLine( &reader );
+        Line = (char*) reader;
 
         if( strnicmp( Line, ENTETE_LIBRAIRIE, L_ENTETE_LIB ) != 0 )
         {
@@ -426,21 +432,22 @@
                         GetChars( tmp ) );
             wxMessageBox( msg, _( "Library Load Error" ),
                           wxOK | wxICON_ERROR, this );
-            fclose( file );
             continue;
         }
 
         /* Read library. */
-        while( GetLine( file, Line, &LineNum, sizeof(Line) - 1 ) )
+        while( GetLine( &reader ) )
         {
+            Line = (char*) reader;
             if( Line[0] != '$' )
                 continue;
             if( strnicmp( Line, "$MODULE", 6 ) == 0 )
                 break;
             if( strnicmp( Line, "$INDEX", 6 ) == 0 )
             {
-                while( GetLine( file, Line, &LineNum ) )
+                while( GetLine( &reader ) )
                 {
+                    Line = (char*) reader;
                     if( strnicmp( Line, "$EndINDEX", 9 ) == 0 )
                         break;
                     strupper( Line );
@@ -454,7 +461,6 @@
         }
 
         /* End read library. */
-        fclose( file );
         file = NULL;
 
         if( !aLibraryFullFilename.IsEmpty() )
@@ -538,7 +544,7 @@
 static void ReadDocLib( const wxString& ModLibName )
 {
     ModList*   NewMod;
-    char       Line[1024];
+    char*      Line;
     FILE*      LibDoc;
     wxFileName fn = ModLibName;
 
@@ -547,12 +553,16 @@
     if( ( LibDoc = wxFopen( fn.GetFullPath(), wxT( "rt" ) ) ) == NULL )
         return;
 
-    GetLine( LibDoc, Line, NULL, sizeof(Line) - 1 );
+    FILE_LINE_READER reader( LibDoc, fn.GetFullPath() );
+
+    GetLine( &reader );
+    Line = (char*) reader;
     if( strnicmp( Line, ENTETE_LIBDOC, L_ENTETE_LIB ) != 0 )
         return;
 
-    while( GetLine( LibDoc, Line, NULL, sizeof(Line) - 1 ) )
+    while( GetLine( &reader ) )
     {
+        Line = (char*) reader;
         if( Line[0] != '$' )
             continue;
         if( Line[1] == 'E' )
@@ -562,8 +572,9 @@
             NewMod = new ModList();
             NewMod->Next = MList;
             MList = NewMod;
-            while( GetLine( LibDoc, Line, NULL, sizeof(Line) - 1 ) )
+            while( GetLine( &reader ) )
             {
+                Line = (char*) reader;
                 if( Line[0] ==  '$' ) /* $EndMODULE */
                     break;
 
@@ -585,7 +596,6 @@
         } /* End read 1 module. */
     }
 
-    fclose( LibDoc );
 }
 
 

=== modified file 'pcbnew/muonde.cpp'
--- pcbnew/muonde.cpp	2010-12-28 11:24:42 +0000
+++ pcbnew/muonde.cpp	2011-01-11 20:36:04 +0000
@@ -835,7 +835,7 @@
     wxString FullFileName;
     wxString ext, mask;
     FILE*    File;
-    char     Line[1024];
+    char*    Line;
     double   unitconv = 10000;
     char*    param1, * param2;
     int      bufsize;
@@ -862,14 +862,15 @@
         return;
     }
 
+    FILE_LINE_READER reader( File, FullFileName );
 
     bufsize = 100;
     ptbuf   = PolyEdges = (double*) MyZMalloc( bufsize * 2 * sizeof(double) );
 
     SetLocaleTo_C_standard();
-    int LineNum = 0;
-    while( GetLine( File, Line, &LineNum, sizeof(Line) - 1 ) != NULL )
+    while( GetLine( &reader ) != NULL )
     {
+        Line = (char*) reader;
         param1 = strtok( Line, " =\n\r" );
         param2 = strtok( NULL, " \t\n\r" );
 
@@ -884,8 +885,9 @@
             break;
         if( strnicmp( param1, "$COORD", 6 ) == 0 )
         {
-            while( GetLine( File, Line, &LineNum, sizeof(Line) - 1 ) != NULL )
+            while( GetLine( &reader ) != NULL )
             {
+                Line = (char*) reader;
                 param1 = strtok( Line, " \t\n\r" );
                 param2 = strtok( NULL, " \t\n\r" );
                 if( strnicmp( param1, "$ENDCOORD", 8 ) == 0 )
@@ -921,7 +923,6 @@
         free( PolyEdges );
         PolyEdges = NULL;
     }
-    fclose( File );
     SetLocaleTo_Default();       // revert to the current locale
 
     ShapeScaleX *= unitconv;


Follow ups