← Back to team overview

kicad-developers team mailing list archive

Re: Using FILE_LINE_READER in pcbnew

 

I guess that the strtok was there to take care of situations where a
file saved in windows is opened in linux (?). Opening a board having
\r\n line endings seems to work using FILE_LINE_READER. A file using
\r's only would not work. Such files should be rare, though.

I renamed the old GetLine to GetLineD to get compile-time errors so
that I would know where to replace the old GetLine with the new one.
The idea was to get rid of GetLineD before committing the final patch.
I don't think that I introduced GetLine into new places, either.

Anyways, I've attached a new patch. GetLine is not used anymore with
FILE_LINE_READER, and GetLineD is renamed back to GetLine. Lines are
read by calling FILTER_READER's ReadLine() directly, which also takes
care of getting rid of comments. I added filter_reader.h/cpp in
include/common subdirectories. The headers are copied from richio.*
(is that ok?).

marco

On Wed, Jan 12, 2011 at 6:52 AM, Dick Hollenbeck <dick@xxxxxxxxxxx> wrote:
> Marco,
>
>
> *))))))))) First the good:
>
> 1) The idea of passing a LINE_READER* to the major functions is correct
>   I think.  For example, this is good:
>
> -bool DIMENSION::ReadDimensionDescr( FILE* File, int* LineNum )
> +bool DIMENSION::ReadDimensionDescr( LINE_READER* aReader )
>
> 2) Not worrying about the trailing /r/n or /n or /r at the end of line is good.
>   I think and would hope that client code is not going to be too affected
>   because you removed the strtok() call.  /n and /r/n or /r is all just
> whitespace,
>   no different than a tab or space, at least to me or code I would write.
>   But it depends on client code, I assume you have some feel for how stupid
>   the client code might be in this regard.  Your risk is low here and the
>   strtok() being removed is reasonable.
>
>
> *)))))))) Then the bad:
>
> I don't like the GetLineD() introduction. I would say just overload
> GetLine() since
> it returns the same type.  Code can use either, with *same* function name.
> This way existing code is not affected by this change in direction.
>
> I am not that fond of GetLine() in any case, and surely would not want to
> introduce
> it into places that it is not already being used.  All it does now is strip out
> blank lines and comments.  For an alternative, made possible by a commit I
> just made
> this evening to base class LINE_READER, take a look at class
> new/filter_reader.cpp.
>
> If you like this, move it up into /include and /common library.  Otherwise,
> it can just stay in /new as an example or for future reference.
>
> filter_reader.cpp is *also* attached for reference.
>
> Thank you for your efforts!
>
> Dick
=== modified file 'common/CMakeLists.txt'
--- common/CMakeLists.txt	2010-12-27 16:49:39 +0000
+++ common/CMakeLists.txt	2011-01-12 17:13:39 +0000
@@ -50,6 +50,7 @@
     edaappl.cpp
     eda_dde.cpp
     eda_doc.cpp
+    filter_reader.cpp
     gestfich.cpp
     gr_basic.cpp
     hotkeys_basic.cpp

=== added file 'common/filter_reader.cpp'
--- common/filter_reader.cpp	1970-01-01 00:00:00 +0000
+++ common/filter_reader.cpp	2011-01-12 17:12:25 +0000
@@ -0,0 +1,40 @@
+
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2010 SoftPLC Corporation, Dick Hollenbeck <dick@xxxxxxxxxxx>
+ * Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include <string.h>
+#include "richio.h"
+#include "filter_reader.h"
+
+unsigned FILTER_READER::ReadLine() throw( IO_ERROR )
+{
+    unsigned ret;
+
+    while( ( ret = reader.ReadLine() ) != 0 )
+    {
+        if( !strchr( "#\n\r", reader[0] ) )
+            break;
+    }
+    return ret;
+}

=== modified file 'cvpcb/loadcmp.cpp'
--- cvpcb/loadcmp.cpp	2010-02-01 21:23:27 +0000
+++ cvpcb/loadcmp.cpp	2011-01-12 17:43:42 +0000
@@ -15,6 +15,8 @@
 #include "protos.h"
 #include "cvstruct.h"
 #include "class_DisplayFootprintsFrame.h"
+#include "richio.h"
+#include "filter_reader.h"
 
 
 /**
@@ -27,9 +29,10 @@
  */
 MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& CmpName )
 {
-    int        LineNum, Found = 0;
+    int        Found = 0;
     unsigned   ii;
-    char       Line[1024], Name[255];
+    char*      Line;
+    char       Name[255];
     wxString   tmp, msg;
     wxFileName fn;
     MODULE*    Module = NULL;
@@ -61,9 +64,13 @@
             continue;
         }
 
+        FILE_LINE_READER fileReader( file, tmp );
+
+        FILTER_READER reader( fileReader );
+
         /* Read header. */
-        LineNum = 0;
-        GetLine( file, Line, &LineNum );
+        reader.ReadLine();
+        Line = reader.Line();
         StrPurge( Line );
 
         if( strnicmp( Line, ENTETE_LIBRAIRIE, L_ENTETE_LIB ) != 0 )
@@ -76,15 +83,17 @@
         }
 
         Found = 0;
-        while( !Found && GetLine( file, Line, &LineNum ) )
+        while( !Found && reader.ReadLine() )
         {
+            Line = reader.Line();
             if( strncmp( Line, "$MODULE", 6 ) == 0 )
                 break;
 
             if( strnicmp( Line, "$INDEX", 6 ) == 0 )
             {
-                while( GetLine( file, Line, &LineNum ) )
+                while( reader.ReadLine() )
                 {
+                    Line = reader.Line();
                     if( strnicmp( Line, "$EndINDEX", 9 ) == 0 )
                         break;
 
@@ -98,8 +107,9 @@
             }
         }
 
-        while( Found && GetLine( file, Line, &LineNum ) )
+        while( Found && reader.ReadLine() )
         {
+            Line = reader.Line();
             if( Line[0] != '$' )
                 continue;
 
@@ -117,15 +127,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;
     }
 

=== added file 'include/filter_reader.h'
--- include/filter_reader.h	1970-01-01 00:00:00 +0000
+++ include/filter_reader.h	2011-01-12 17:38:42 +0000
@@ -0,0 +1,76 @@
+
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2010 SoftPLC Corporation, Dick Hollenbeck <dick@xxxxxxxxxxx>
+ * Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#ifndef FILTER_READER_H_
+#define FILTER_READER_H_
+
+#include <wx/wx.h>
+#include "richio.h"
+
+
+/**
+ * Class FILTER_READER
+ * reads lines of text from another LINE_READER, but only returns non-comment
+ * lines and non-blank lines from its ReadLine() function.
+ */
+class FILTER_READER : public LINE_READER
+{
+    LINE_READER&  reader;
+
+public:
+
+    /**
+     * Constructor ( LINE_READER& )
+     * does not take ownership over @a aReader, so will not destroy it.
+     */
+    FILTER_READER( LINE_READER& aReader ) :
+       reader( aReader )
+    {
+    }
+
+    unsigned ReadLine() throw( IO_ERROR );
+
+    const wxString& GetSource() const
+    {
+        return reader.GetSource();
+    }
+
+    char* Line() const
+    {
+        return reader.Line();
+    }
+
+    unsigned LineNumber() const
+    {
+        return reader.LineNumber();
+    }
+
+    unsigned Length() const
+    {
+        return reader.Length();
+    }
+};
+
+#endif // FILTER_READER_H_

=== modified file 'include/wxBasePcbFrame.h'
--- include/wxBasePcbFrame.h	2011-01-09 11:17:28 +0000
+++ include/wxBasePcbFrame.h	2011-01-12 16:45:02 +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-12 16:45: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 );

=== removed file 'new/filter_reader.cpp'
--- new/filter_reader.cpp	2011-01-12 04:51:29 +0000
+++ new/filter_reader.cpp	1970-01-01 00:00:00 +0000
@@ -1,59 +0,0 @@
-
-
-#include <richio.h>
-#include <string.h>
-
-
-/**
- * Class FILTER_READER
- * reads lines of text from another LINE_READER, but only returns non-comment
- * lines and non-blank lines from its ReadLine() function.
- */
-class FILTER_READER : public LINE_READER
-{
-    LINE_READER&  reader;
-
-public:
-
-    /**
-     * Constructor ( LINE_READER& )
-     * does not take ownership over @a aReader, so will not destroy it.
-     */
-    FILTER_READER( LINE_READER& aReader ) :
-       reader( aReader )
-    {
-    }
-
-    unsigned ReadLine() throw( IO_ERROR )
-    {
-        unsigned ret;
-
-        while( ( ret = reader.ReadLine() ) != 0 )
-        {
-            if( !strchr( "#\n\r", reader[0] ) )
-                break;
-        }
-        return ret;
-    }
-
-    const wxString& GetSource() const
-    {
-        return reader.GetSource();
-    }
-
-    char* Line() const
-    {
-        return reader.Line();
-    }
-
-    unsigned LineNumber() const
-    {
-        return reader.LineNumber();
-    }
-
-    unsigned Length() const
-    {
-        return reader.Length();
-    }
-};
-

=== modified file 'pcbnew/class_dimension.cpp'
--- pcbnew/class_dimension.cpp	2010-12-29 17:47:32 +0000
+++ pcbnew/class_dimension.cpp	2011-01-12 18:37:14 +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( aReader->ReadLine() )
     {
+        Line = aReader->Line();
         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-12 16:45:02 +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-12 16:45:02 +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( aReader->ReadLine() )
     {
+        Line = aReader->Line();
         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-12 16:45:02 +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-12 16:45:02 +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 = aReader->Line();
 
     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( aReader->ReadLine() )
             {
+                Buf = aReader->Line();
                 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-12 16:45:02 +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-12 16:45:02 +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( aReader->ReadLine() )
     {
+        Line = aReader->Line();
         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-12 16:45:02 +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-12 16:45:02 +0000
@@ -21,6 +21,7 @@
 
 #include "3d_struct.h"
 #include "protos.h"
+#include "richio.h"
 
 
 /*********************************************/
@@ -409,9 +410,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 = aReader->Line();
     char*       text = Line + 3;
 
     S3D_MASTER* t3D = m_3D_Drawings;
@@ -425,8 +426,9 @@
         t3D = n3D;
     }
 
-    while( GetLine( File, Line, LineNum, sizeof(Line) - 1 ) != NULL )
+    while( aReader->ReadLine() )
     {
+        Line = aReader->Line();
         switch( Line[0] )
         {
         case '$':
@@ -476,13 +478,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( aReader->ReadLine() )
     {
+        Line = aReader->Line();
         if( Line[0] == '$' )
         {
             if( Line[1] == 'E' )
@@ -490,7 +494,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 +503,7 @@
                 continue;
             }
             if( Line[1] == 'S' )
-                Read_3D_Descr( File, LineNum );
+                Read_3D_Descr( aReader );
         }
 
         if( strlen( Line ) < 4 )
@@ -584,14 +588,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-12 16:45:02 +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-12 16:45:02 +0000
@@ -30,6 +30,7 @@
 #include "kicad_string.h"
 #include "pcbnew.h"
 #include "class_board_design_settings.h"
+#include "richio.h"
 
 // Current design settings (used also to read configs):
 extern BOARD_DESIGN_SETTINGS boardDesignSettings;
@@ -332,15 +333,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( aReader->ReadLine() )
     {
+        Line = aReader->Line();
         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-12 18:04:59 +0000
@@ -30,7 +30,7 @@
 
 #include <set>
 #include <map>
-
+#include "richio.h"
 
 /**
  * Class NETCLASS
@@ -205,12 +205,11 @@
 
     /**
      * Function ReadDescr
-     * reads the data structures for this object from a FILE in "*.brd" format.
-     * @param aFile The FILE to read to.
-     * @param aLineNum a pointer to a line number counter
+     * reads the data structures for this object from a LINE_READER in "*.brd" format.
+     * @param aReader is a pointer to a LINE_READER to read from.
      * @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-12 16:45:02 +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-12 16:45:02 +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( aReader->ReadLine() )
     {
+        Line = aReader->Line();
         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-12 16:45:02 +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( aReader->ReadLine() )
     {
+        Line = aReader->Line();
         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-12 16:45:02 +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-12 16:45:02 +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( aReader->ReadLine() )
     {
+        Line = aReader->Line();
         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-12 16:45:02 +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-12 16:45:02 +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 = aReader->Line();
 
     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-12 18:03:35 +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
@@ -81,13 +82,10 @@
     /**
      * Function ReadDescr
      * Read description from a given line in "*.brd" format.
-     * @param aLine The current line which contains the first line of
-     *              description.
-     * @param aFile The FILE to read next lines (currently not used).
-     * @param aLineNum a point to the line count (currently not used).
+     * @param aReader is a pointer to a LINE_READER to read from.
      * @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-12 18:05:28 +0000
@@ -17,6 +17,7 @@
 #include "colors_selection.h"
 
 #include "protos.h"
+#include "richio.h"
 
 /************************/
 /* class ZONE_CONTAINER */
@@ -215,26 +216,20 @@
 
 
 /**********************************************************/
-int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
+int ZONE_CONTAINER::ReadDescr( LINE_READER* aReader )
 /**********************************************************/
-
-/**
- * Function ReadDescr
- * @param aFile = opened file
- * @param aLineNum = pointer on a line number counter (can be NULL or missing)
- * @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( aReader->ReadLine() )
     {
+        Line = aReader->Line();
         if( strnicmp( Line, "ZCorner", 7 ) == 0 ) // new corner found
         {
             int x;
@@ -382,8 +377,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( aReader->ReadLine() )
             {
+                Line = aReader->Line();
                 if( strnicmp( Line, "$endPOLYSCORNERS", 4 ) == 0  )
                     break;
                 CPolyPt corner;
@@ -401,8 +397,9 @@
         else if( strnicmp( Line, "$FILLSEGMENTS", 13) == 0  )
         {
             SEGMENT segm;
-            while( GetLine( aFile, Line, aLineNum, sizeof(Line) - 1 ) != NULL )
+            while( aReader->ReadLine() )
             {
+                Line = aReader->Line();
                 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-12 20:32:11 +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,14 @@
     ~ZONE_CONTAINER();
 
     bool     Save( FILE* aFile ) const;
-    int      ReadDescr( FILE* aFile, int* aLineNum = NULL );
+
+     /**
+     * Function ReadDescr
+     * reads the data structures for this object from a LINE_READER in "*.brd" format.
+     * @param aReader is a pointer to a LINE_READER to read from.
+     * @return int - 1 if success, 0 if not.
+     */
+    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-12 17:14:49 +0000
@@ -13,6 +13,8 @@
 #include "protos.h"
 #include "pcbnew_id.h"
 #include "3d_viewer.h"
+#include "richio.h"
+#include "filter_reader.h"
 
 #define BACKUP_FILE_EXT wxT( "000" )
 
@@ -134,10 +136,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 +198,20 @@
         return false;
     }
 
+    FILE_LINE_READER fileReader( source, GetScreen()->m_FileName );
+
+    FILTER_READER reader( fileReader );
 
     /* Read header and TEST if it is a PCB file format */
-    GetLine( source, cbuf, &ii );
-    if( strncmp( cbuf, "PCBNEW-BOARD", 12 ) != 0 )
+    reader.ReadLine();
+    if( strncmp( reader.Line(), "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( reader.Line() , "PCBNEW-BOARD Version %d date", &ver );
     if ( ver > g_CurrentVersionPCB )
     {
         DisplayInfoMessage( this, _( "This file was created by a more recent \
@@ -225,7 +227,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 +237,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-12 17:16:08 +0000
@@ -7,7 +7,8 @@
 #include "kicad_string.h"
 #include "pcbnew.h"
 #include "trigo.h"
-
+#include "richio.h"
+#include "filter_reader.h"
 
 /* read parameters from a line, and return all params in a wxArrayString
  * each param is in one wxString, and double quotes removed if exists
@@ -155,8 +156,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 +166,13 @@
     if( ( cmpfile = wxFopen( CmpFullFileName, wxT( "rt" ) ) ) == NULL )
         return false;
 
-    GetLine( cmpfile, Line, &NbLine );
+    FILE_LINE_READER fileReader( cmpfile, CmpFullFileName );
+
+    FILTER_READER reader( fileReader );
+
+    reader.ReadLine();
+
+    Line = reader.Line();
 
     params.Clear();
     Extract_Parameters( params, Line );
@@ -176,7 +182,6 @@
 
     if( params[iprmcnt].CmpNoCase( wxT( "Element" ) ) != 0 )
     {
-        fclose( cmpfile );
         return false;
     }
 
@@ -232,8 +237,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( reader.ReadLine() )
     {
+        Line = reader.Line();
         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 +415,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-12 20:34:15 +0000
@@ -23,6 +23,7 @@
 #include "build_version.h"
 
 #include "pcbnew_id.h"
+#include "richio.h"
 
 /* ASCII format of structures:
  *
@@ -80,42 +81,50 @@
 /** 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    tempStartX, tempStartY;
+    int    tempEndX, tempEndY;
     int    ii = 0;
-    char   line1[256];
-    char   line2[256];
+    char*  line;
 
     TRACK* newTrack;
 
-    while( GetLine( File, line1, LineNum ) )
+    while( aReader->ReadLine() )
     {
+        line = aReader->Line();
         int           makeType;
         unsigned long timeStamp;
 
-        if( line1[0] == '$' )
+        if( line[0] == '$' )
         {
             return ii;      /* end of segmentlist: OK */
         }
 
+        int arg_count = sscanf( line + 2, " %d %d %d %d %d %d %d", &shape,
+                                &tempStartX, &tempStartY,
+                                &tempEndX, &tempEndY, &width,
+                                &drill );
+
         // Read the 2nd line to determine the exact type, one of:
         // TYPE_TRACK, TYPE_VIA, or TYPE_ZONE.  The type field in 2nd line
         // 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( !aReader->ReadLine() )
             break;
 
-        if( line2[0] == '$' )
+        line = aReader->Line();
+
+        if( line[0] == '$' )
             break;
 
         // parse the 2nd line first to determine the type of object
-        sscanf( line2 + 2, " %d %d %d %lX %X", &layer, &type, &net_code,
+        sscanf( line + 2, " %d %d %d %lX %X", &layer, &type, &net_code,
                 &timeStamp, &flags );
 
         if( StructType==TYPE_TRACK && type==1 )
@@ -145,10 +154,10 @@
 
         newTrack->m_TimeStamp = timeStamp;
 
-        int arg_count = sscanf( line1 + 2, " %d %d %d %d %d %d %d", &shape,
-                                &newTrack->m_Start.x, &newTrack->m_Start.y,
-                                &newTrack->m_End.x, &newTrack->m_End.y, &width,
-                                &drill );
+        newTrack->m_Start.x = tempStartX;
+        newTrack->m_Start.y = tempStartY;
+        newTrack->m_End.x = tempEndX;
+        newTrack->m_End.y = tempEndY;
 
         newTrack->m_Width = width;
         newTrack->m_Shape = shape;
@@ -176,12 +185,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(  aReader->ReadLine() )
     {
+        Line = aReader->Line();
         data = strtok( Line, " =\n\r" );
         if( strnicmp( data, "$EndGENERAL", 10 ) == 0 )
             break;
@@ -294,15 +304,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(  aReader->ReadLine() )
     {
+        Line = aReader->Line();
         strtok( Line, " =\n\r" );
         data = strtok( NULL, " =\n\r" );
 
@@ -777,12 +788,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(  aReader->ReadLine() )
     {
+        Line = aReader->Line();
         if( strnicmp( Line, "$End", 4 ) == 0 )
             return TRUE;
 
@@ -874,10 +886,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 +908,9 @@
     // string.
 #define TESTLINE( x ) (strncmp( Line, "$" x, sizeof("$" x) - 1 ) == 0)
 
-    while( GetLine( File, Line, &LineNum ) != NULL )
+    while( aReader->ReadLine() )
     {
+        Line = aReader->Line();
         // put the more frequent ones at the top
 
         if( TESTLINE( "MODULE" ) )
@@ -909,7 +921,7 @@
                 continue;
 
             board->Add( Module, ADD_APPEND );
-            Module->ReadDescr( File, &LineNum );
+            Module->ReadDescr( aReader );
             continue;
         }
 
@@ -917,7 +929,7 @@
         {
             DRAWSEGMENT* DrawSegm = new DRAWSEGMENT( board );
             board->Add( DrawSegm, ADD_APPEND );
-            DrawSegm->ReadDrawSegmentDescr( File, &LineNum );
+            DrawSegm->ReadDrawSegmentDescr( aReader );
             continue;
         }
 
@@ -925,7 +937,7 @@
         {
             NETINFO_ITEM* net = new NETINFO_ITEM( board );
             board->m_NetInfo->AppendNet( net );
-            net->ReadDescr( File, &LineNum );
+            net->ReadDescr( aReader );
             continue;
         }
 
@@ -933,7 +945,7 @@
         {
             TEXTE_PCB* pcbtxt = new TEXTE_PCB( board );
             board->Add( pcbtxt, ADD_APPEND );
-            pcbtxt->ReadTextePcbDescr( File, &LineNum );
+            pcbtxt->ReadTextePcbDescr( aReader );
             continue;
         }
 
@@ -941,8 +953,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 +965,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 +983,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 +995,7 @@
         {
             DIMENSION* Dimension = new DIMENSION( board );
             board->Add( Dimension, ADD_APPEND );
-            Dimension->ReadDimensionDescr( File, &LineNum );
+            Dimension->ReadDimensionDescr( aReader );
             continue;
         }
 
@@ -991,7 +1003,7 @@
         {
             MIREPCB* Mire = new MIREPCB( board );
             board->Add( Mire, ADD_APPEND );
-            Mire->ReadMirePcbDescr( File, &LineNum );
+            Mire->ReadMirePcbDescr( aReader );
             continue;
         }
 
@@ -1000,21 +1012,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 +1034,15 @@
         {
             if( !Append )
             {
-                ReadSetup( File, &LineNum );
+                ReadSetup( aReader );
             }
             else
             {
-                while( GetLine( File, Line, &LineNum ) != NULL )
+                while( aReader->ReadLine() ) {
+                    Line = aReader->Line();
                     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-12 17:16:47 +0000
@@ -13,6 +13,8 @@
 #include "wxPcbStruct.h"
 #include "module_editor_frame.h"
 #include "dialog_helpers.h"
+#include "richio.h"
+#include "filter_reader.h"
 
 /*
  * Module library header format:
@@ -47,8 +49,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 +77,10 @@
         return NULL;
     }
 
+    FILE_LINE_READER fileReader( file, dlg.GetPath() );
+
+    FILTER_READER reader( fileReader );
+
     if( Config )    // Save file path
     {
         LastOpenedPathForLoading = wxPathOnly( dlg.GetPath() );
@@ -87,7 +92,8 @@
     SetLocaleTo_C_standard();
 
     /* Read header and test file type */
-    GetLine( file, Line, &NbLine );
+    reader.ReadLine();
+    Line = reader.Line();
     if( strnicmp( Line, ENTETE_LIBRAIRIE, L_ENTETE_LIB ) != 0 )
     {
         if( strnicmp( Line, "Element", 7 ) == 0 )
@@ -103,7 +109,7 @@
     /* Read file: Search the description starting line (skip lib header)*/
     if( !Footprint_Is_GPCB_Format )
     {
-        while( GetLine( file, Line, &NbLine ) != NULL )
+        while( reader.ReadLine() )
         {
             if( strnicmp( Line, "$MODULE", 7 ) == 0 )
                 break;
@@ -114,13 +120,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
 

=== modified file 'pcbnew/loadcmp.cpp'
--- pcbnew/loadcmp.cpp	2010-12-29 17:47:32 +0000
+++ pcbnew/loadcmp.cpp	2011-01-12 18:01:28 +0000
@@ -17,6 +17,8 @@
 #include "wxPcbStruct.h"
 #include "module_editor_frame.h"
 #include "dialog_helpers.h"
+#include "richio.h"
+#include "filter_reader.h"
 
 class ModList
 {
@@ -213,9 +215,9 @@
     const wxString& aModuleName,
     bool            aDisplayMessageError )
 {
-    int        LineNum, Found = 0;
+    int        Found = 0;
     wxFileName fn;
-    char       Line[512];
+    char*      Line;
     wxString   Name;
     wxString   msg, tmp;
     MODULE*    NewModule;
@@ -256,12 +258,16 @@
             continue;
         }
 
+        FILE_LINE_READER fileReader( file, tmp );
+
+        FILTER_READER reader( fileReader );
+
         msg.Printf( _( "Scan Lib: %s" ), GetChars( tmp ) );
         Affiche_Message( msg );
 
         /* Reading header ENTETE_LIBRAIRIE */
-        LineNum = 0;
-        GetLine( file, Line, &LineNum );
+        reader.ReadLine();
+        Line = reader.Line();
         StrPurge( Line );
         if( strnicmp( Line, ENTETE_LIBRAIRIE, L_ENTETE_LIB ) != 0 )
         {
@@ -269,20 +275,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 && reader.ReadLine() )
         {
+            Line = reader.Line();
             if( strnicmp( Line, "$MODULE", 6 ) == 0 )
                 break;
             if( strnicmp( Line, "$INDEX", 6 ) == 0 )
             {
-                while( GetLine( file, Line, &LineNum ) )
+                while( reader.ReadLine() )
                 {
+                    Line = reader.Line();
                     if( strnicmp( Line, "$EndINDEX", 9 ) == 0 )
                         break;
                     StrPurge( Line );
@@ -297,8 +304,9 @@
         }
 
         /* Read library. */
-        while( Found && GetLine( file, Line, &LineNum ) )
+        while( Found && reader.ReadLine() )
         {
+            Line = reader.Line();
             if( Line[0] != '$' )
                 continue;
             if( Line[1] != 'M' )
@@ -315,16 +323,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;
     }
@@ -358,9 +364,8 @@
                                                          const wxString&   aMask,
                                                          const wxString&   aKeyWord )
 {
-    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 +417,17 @@
             continue;
         }
 
+        FILE_LINE_READER fileReader( file, tmp );
+
+        FILTER_READER reader( fileReader );
+
         // Statusbar library loaded message
         msg = _( "Library " ) + fn.GetFullPath() + _( " loaded" );
         Affiche_Message( msg );
 
         /* Read header. */
-        LineNum = 0;
-        GetLine( file, Line, &LineNum, sizeof(Line) - 1 );
+        reader.ReadLine();
+        Line = reader.Line();
 
         if( strnicmp( Line, ENTETE_LIBRAIRIE, L_ENTETE_LIB ) != 0 )
         {
@@ -426,21 +435,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( reader.ReadLine() )
         {
+            Line = reader.Line();
             if( Line[0] != '$' )
                 continue;
             if( strnicmp( Line, "$MODULE", 6 ) == 0 )
                 break;
             if( strnicmp( Line, "$INDEX", 6 ) == 0 )
             {
-                while( GetLine( file, Line, &LineNum ) )
+                while( reader.ReadLine() )
                 {
+                    Line = reader.Line();
                     if( strnicmp( Line, "$EndINDEX", 9 ) == 0 )
                         break;
                     strupper( Line );
@@ -454,7 +464,6 @@
         }
 
         /* End read library. */
-        fclose( file );
         file = NULL;
 
         if( !aLibraryFullFilename.IsEmpty() )
@@ -538,7 +547,7 @@
 static void ReadDocLib( const wxString& ModLibName )
 {
     ModList*   NewMod;
-    char       Line[1024];
+    char*      Line;
     FILE*      LibDoc;
     wxFileName fn = ModLibName;
 
@@ -547,12 +556,18 @@
     if( ( LibDoc = wxFopen( fn.GetFullPath(), wxT( "rt" ) ) ) == NULL )
         return;
 
-    GetLine( LibDoc, Line, NULL, sizeof(Line) - 1 );
+    FILE_LINE_READER fileReader( LibDoc, fn.GetFullPath() );
+
+    FILTER_READER reader( fileReader );
+
+    reader.ReadLine();
+    Line = reader.Line();
     if( strnicmp( Line, ENTETE_LIBDOC, L_ENTETE_LIB ) != 0 )
         return;
 
-    while( GetLine( LibDoc, Line, NULL, sizeof(Line) - 1 ) )
+    while( reader.ReadLine() )
     {
+        Line = reader.Line();
         if( Line[0] != '$' )
             continue;
         if( Line[1] == 'E' )
@@ -562,8 +577,9 @@
             NewMod = new ModList();
             NewMod->Next = MList;
             MList = NewMod;
-            while( GetLine( LibDoc, Line, NULL, sizeof(Line) - 1 ) )
+            while( reader.ReadLine() )
             {
+                Line = reader.Line();
                 if( Line[0] ==  '$' ) /* $EndMODULE */
                     break;
 
@@ -585,7 +601,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-12 17:18:06 +0000
@@ -14,7 +14,8 @@
 #include "class_board_design_settings.h"
 #include "protos.h"
 #include "dialog_helpers.h"
-
+#include "richio.h"
+#include "filter_reader.h"
 
 #define COEFF_COUNT 6
 static double* PolyEdges;
@@ -835,7 +836,7 @@
     wxString FullFileName;
     wxString ext, mask;
     FILE*    File;
-    char     Line[1024];
+    char*    Line;
     double   unitconv = 10000;
     char*    param1, * param2;
     int      bufsize;
@@ -862,14 +863,17 @@
         return;
     }
 
+    FILE_LINE_READER fileReader( File, FullFileName );
+
+    FILTER_READER reader( fileReader );
 
     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( reader.ReadLine() )
     {
+        Line = reader.Line();
         param1 = strtok( Line, " =\n\r" );
         param2 = strtok( NULL, " \t\n\r" );
 
@@ -884,8 +888,9 @@
             break;
         if( strnicmp( param1, "$COORD", 6 ) == 0 )
         {
-            while( GetLine( File, Line, &LineNum, sizeof(Line) - 1 ) != NULL )
+            while( reader.ReadLine() )
             {
+                Line = reader.Line();
                 param1 = strtok( Line, " \t\n\r" );
                 param2 = strtok( NULL, " \t\n\r" );
                 if( strnicmp( param1, "$ENDCOORD", 8 ) == 0 )
@@ -921,7 +926,6 @@
         free( PolyEdges );
         PolyEdges = NULL;
     }
-    fclose( File );
     SetLocaleTo_Default();       // revert to the current locale
 
     ShapeScaleX *= unitconv;


Follow ups

References