From 7eb1a136f1f8dc119df9eb34c4bb24da303d672b Mon Sep 17 00:00:00 2001
From: jean-pierre charras <jp.charras@wanadoo.fr>
Date: Thu, 26 Jan 2012 10:37:36 +0100
Subject: [PATCH] Pcbnew:  First draft to use a new netlist format ( containing
 the same info as the intermediate netlist, but using S expressions) *
 Eeschema can generate this netlist format. *   Pcbnew can use (automatic
 identification) the current format or the new format. *   Cvpcb does not use
 yet the new format.

---
 CHANGELOG.txt                         |   10 +
 INSTALL.txt                           |  207 ----
 demos/interf_u/interf_u.net           | 1295 ++++++++++++++++---------
 eeschema/netform.cpp                  |  196 ++--
 eeschema/netlist_control.cpp          |   88 +-
 eeschema/netlist_control.h            |   13 +-
 include/wxEeschemaStruct.h            |   36 +-
 include/wxPcbStruct.h                 |    7 +-
 license_for_documentation.txt         |   61 ++
 pcbnew/CMakeLists.txt                 |    2 +
 pcbnew/clean.cpp                      |   16 +-
 pcbnew/netlist.cpp                    | 1034 ++++++--------------
 pcbnew/netlist_reader.h               |  295 ++++++
 pcbnew/netlist_reader_firstformat.cpp |  315 ++++++
 pcbnew/netlist_reader_kicad.cpp       |  325 +++++++
 15 files changed, 2392 insertions(+), 1508 deletions(-)
 delete mode 100644 INSTALL.txt
 create mode 100644 license_for_documentation.txt
 create mode 100644 pcbnew/netlist_reader.h
 create mode 100644 pcbnew/netlist_reader_firstformat.cpp
 create mode 100644 pcbnew/netlist_reader_kicad.cpp

diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 37aae3265f..5b5a466e2f 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -4,6 +4,16 @@ KiCad ChangeLog 2012
 Please add newer entries at the top, list the date and your name with
 email address.
 
+2012-Jan-26, UPDATE Jean-Pierre Charras <jp.charras@wanadoo.fr>
+================================================================================
+Pcbnew:
+    First draft to use a new netlist format (using S expressions)
+    Eeschema can generate this netlist format.
+    Pcbnew can use (automatic identification) the current format or the new format.
+    Cvpcb does not use yet the new format.
+    To do:
+        New format in Cvpcb: how to use the .cmp file with the new netlist format
+
 
 2012-Jan-22 UPDATE Dick Hollenbeck <dick@softplc.com>
 ================================================================================
diff --git a/INSTALL.txt b/INSTALL.txt
deleted file mode 100644
index 2936040779..0000000000
--- a/INSTALL.txt
+++ /dev/null
@@ -1,207 +0,0 @@
-KiCad installation
-==================
-
-The parts of KiCad
-------------------
-KiCad consists of 3 packages:
-
-kicad         - KiCad programs and core files.
-kicad-doc     - Documentation and interactive help (optional package).
-kicad-library - KiCad schematic, pcb & 3D-model libraries (optional package).
-
-
-Installation from binary packages
----------------------------------
-
-   KiCad binary packages exist for Linux and Windows (XP, 2000).
-
-   Data files (schematic, boards, libraries) are compatible with all platforms.
-
-*.zip  - KiCad packages for Windows.
-*.tbz2 - KiCad for Linux.
-
-
-Installation from binary packages for Windows
----------------------------------------------
-
-   KiCad can be installed in 'C:\kicad', 'D:\kicad', 'C:\Program files\kicad',
-'D:\Program files\kicad'.
-
-   For example, for an installation in the folder 'C:\kicad', unzip KiCad
-packages:
-
-  kicad-{version}.zip
-  kicad-doc-{version}.zip
-  kicad-library-{version}.zip
-
-to the folder 'C:\kicad'.
-
-   The main program is the project manager (kicad.exe) and from it you can run
-the other programs (schematic editor - eeschema, pcb editor - pcbnew,
-utilities: cvpcb and gerbview).
-
-   You can create a shortcut to 'C:\kicad\bin\kicad.exe'.
-
-
-Installation from binary packages for Linux
--------------------------------------------
-
-   KiCad can be installed in '/usr' or '/usr/local'.
-
-   You must have "root" access for installation.
-
-    cd /
-    tar -xjf kicad-{version}.tbz2
-    tar -xjf kicad-doc-{version}.tbz2
-    tar -xjf kicad-library-{version}.tbz2
-
-   The main program is '/usr/bin/kicad'.
-
-
-Windows KiCad tree
-------------------
-
-kicad/bin                      - Binaries (executable files).
-kicad/doc                      - Various documentation.
-kicad/doc/help                 - Interactive help.
-kicad/share/demos              - Sample schematics and printed boards.
-kicad/share/internat           - Interface localization files.
-kicad/share/library            - Libraries for schematic.
-kicad/share/modules            - Module libraries for printed boards.
-kicad/share/modules/packages3d - 3D component models (.wrl and .wings format).
-
-   Files '*.mod' are libraries, and files '*.brd' are printed boards you can
-view with pcbnew.
-   Files *.brd show the existing modules (and 3D shapes) in libraries.
-
-
-Linux KiCad tree
-----------------
-
-/usr/bin                            - Binaries (executable files).
-/usr/share/doc/kicad/               - Various documentation.
-/usr/share/doc/kicad/help           - Interactive help.
-/usr/share/kicad/demos              - Sample schematics and printed boards.
-/usr/share/kicad/internat           - Dictionaries for interface localization.
-/usr/share/kicad/library            - Interface localization files.
-/usr/share/kicad/modules            - Module libraries for printed boards.
-/usr/share/kicad/modules/packages3d - 3D component models (.wrl and .wings format).
-
-if not found search kicad in
-/usr/local/
-and if found, kicad uses the same tree as the Windows KiCad tree above
-
-   Files '*.mod' are the libraries, and files '*.brd' are printed boards you can
-view with pcbnew.
-   Files *.brd show the existing modules (and 3D shapes) in libraries.
-
-Warning:
-Do not change the KiCad tree, or the location of binary files,
-else KiCad will not be able to find its required files (configuration,
-libraries, etc.).
-
-Mac OS X KiCad tree
--------------------
-
-System wide files
-
-/Library/Application Support/kicad/demos
-/Library/Application Support/kicad/internat
-/Library/Application Support/kicad/library
-/Library/Application Support/kicad/modules
-/Library/Application Support/kicad/modules/packages3d
-
-User files can be the same as the system wide files but only inside the users home directory.
-
-$HOME/Library/Application Support/kicad
-
-Warning:
-These paths are hardcoded into KiCad, if you put them somewhere else KiCad will not find them when a new
-project is created.
-
-Installation from source code
------------------------------
-
-   Some dependencies must be satisfied for the correct installation of KiCad:
-
-wxWidgets           >= 2.8.11        http://www.wxwidgets.org/
-CMake               >= 2.6.4         http://www.cmake.org/
-Boost C++ Libraries  (files used by kicad are provided in kicad sources) http://www.boost.org/
-OpenGL
-  Linux:   Mesa 3D Graphics Library  http://www.mesa3d.org/
-  Windows: built-in
-Zlib Compression Library             http://www.zlib.net/
-
-   In source-tree-build are mostly unwanted, so make a subdir called "build" and
-change to it.
-
-   Call cmake with the path to KiCad. E.g., when your build-folder is "build"
-within source-tree, type "cmake ../".
-
-   Now your system get checked if it is able compiling KiCad and cmake generates
-the Makefiles.
-
-   After calling cmake just type "make" and build begins.
-
-   It is easy to build only a specific binary such as pcbnew alone:
-    make pcbnew
-
-   After "make" type "make install" and install begins.
-
-   You may install to a temporary-root with
-    make install DESTDIR=<temproot>
-
-   If you want to uninstall KiCad again type "make uninstall" from within the
-build directory.
-
-
-Important parameters to cmake
------------------------------
-
--DCMAKE_BUILD_TYPE=<buildtype>
-<buildtype> may current one of "Debug" and "Release".
-
--DCMAKE_INSTALL_PREFIX=<prefix>
-Default to "/usr/local".
-
--DwxWidgets_ROOT_DIR=<wxInstallDir>
-Required for Windows platform.
-
--DwxWidgets_USE_DEBUG=ON
-Can be used only with -DCMAKE_BUILD_TYPE=Debug
-
--DwxWidgets_USE_STATIC=ON
-For building statically linked executables. Can be used only if wxWidgets
-configured and builded with "--enable-monolithic --disable-shared" parameters.
-
--DwxWidgets_USE_STATIC=OFF
-For building dinamically linked executables. Can be used only if wxWidgets
-configured and builded with "--disable-monolithic --enable-shared" parameters.
-
--DwxUSE_UNICODE=ON
-Require on locale utf8 for build the KiCad with cyrillic fonts support.
-
--DKICAD_GOST=ON
-Build the KiCad with russian GOST support.
-
--DKICAD_KEEPCASE=ON
-Build the KiCad with no component name conversion to uppercase (if you want your
-ADuC.../Si.../bq... components named as just so).
-
--DCMAKE_CXX_FLAGS=<some extra flags>
-Extra flags for the c++ compiler for your system required.
-
--DCMAKE_VERBOSE_MAKEFILE=ON
-When more output is wanted use this cmake parameter or call "make VERBOSE=1".
-
-
-Extra CFLAGS and linker flags
------------------------------
-
-   If you require extra flags for compiler and linker you may give them via
-environment variables
-  "CXXFLAGS" (c++ compiler)
-  "LDFLAGS"  (for linker)
-  "CFLAGS"   (for c-compiler, not needed in kdesvn build)
-
-eg., it may usefull on 64bit systems "-m64" to CXXFLAGS and LDFLAGS.
diff --git a/demos/interf_u/interf_u.net b/demos/interf_u/interf_u.net
index 75ea8edd26..9bae13b9ef 100644
--- a/demos/interf_u/interf_u.net
+++ b/demos/interf_u/interf_u.net
@@ -1,442 +1,466 @@
-# EESchema Netlist Version 1.1 created  21/02/2011 18:31:31
+# EESchema Netlist Version 1.1 created  23/01/2012 08:38:24
 (
- ( /322D3011 BUS_PC BUS1 BUSPC
-  ( 1 GND )
-  ( 2 /PC-RST )
-  ( 3 VCC )
-  ( 4 ? )
-  ( 5 ? )
-  ( 6 ? )
-  ( 7 ? )
-  ( 8 ? )
-  ( 9 ? )
-  ( 10 ? )
-  ( 11 ? )
-  ( 12 ? )
-  ( 13 /PC-IOW )
-  ( 14 /PC-IOR )
-  ( 15 ? )
-  ( 16 ? )
-  ( 17 ? )
-  ( 18 ? )
-  ( 19 ? )
-  ( 20 ? )
-  ( 21 ? )
-  ( 22 ? )
-  ( 23 ? )
-  ( 24 ? )
-  ( 25 ? )
-  ( 26 ? )
-  ( 27 ? )
-  ( 28 ? )
-  ( 29 VCC )
-  ( 30 ? )
-  ( 31 GND )
-  ( 32 ? )
-  ( 33 /PC-DB7 )
-  ( 34 /PC-DB6 )
-  ( 35 /PC-DB5 )
-  ( 36 /PC-DB4 )
-  ( 37 /PC-DB3 )
-  ( 38 /PC-DB2 )
-  ( 39 /PC-DB1 )
-  ( 40 /PC-DB0 )
-  ( 41 ? )
-  ( 42 /PC-AEN )
-  ( 43 ? )
-  ( 44 ? )
-  ( 45 ? )
-  ( 46 ? )
-  ( 47 ? )
-  ( 48 ? )
-  ( 49 ? )
-  ( 50 ? )
-  ( 51 /PC-A11 )
-  ( 52 /PC-A10 )
-  ( 53 /PC-A9 )
-  ( 54 /PC-A8 )
-  ( 55 /PC-A7 )
-  ( 56 /PC-A6 )
-  ( 57 /PC-A5 )
-  ( 58 /PC-A4 )
-  ( 59 /PC-A3 )
-  ( 60 /PC-A2 )
-  ( 61 /PC-A1 )
-  ( 62 /PC-A0 )
+ ( /4A087146 $noname  U3 74LS541 {Lib=74LS541}
+  (    1 GND )
+  (    2 /PC-A1 )
+  (    3 /PC-A0 )
+  (    4 /PC-A2 )
+  (    5 /PC-A3 )
+  (    6 /PC-IOW )
+  (    7 /PC-IOR )
+  (    8 /PC-RST )
+  (    9 /PC-RST )
+  (   10 GND )
+  (   11 ? )
+  (   12 /RSTL )
+  (   13 /PC-RD )
+  (   14 /PC-WR )
+  (   15 N-000111 )
+  (   16 N-000110 )
+  (   17 N-000109 )
+  (   18 N-000108 )
+  (   19 GND )
+  (   20 VCC )
  )
- ( /32307DE2 CP6 C1 47uF
-  ( 1 VCC )
-  ( 2 GND )
+ ( /32568D1E pin_array_8x2  JP1 CONN_8X2 {Lib=CONN_8X2}
+  (    1 GND )
+  (    2 /REF10 )
+  (    3 GND )
+  (    4 /REF11 )
+  (    5 GND )
+  (    6 /REF7 )
+  (    7 GND )
+  (    8 /REF9 )
+  (    9 GND )
+  (   10 /REF6 )
+  (   11 GND )
+  (   12 /REF8 )
+  (   13 GND )
+  (   14 /REF4 )
+  (   15 GND )
+  (   16 /REF5 )
  )
- ( /32307ECF C1 C2 47pF
-  ( 1 N-000145 )
-  ( 2 GND )
+ ( /325679C1 r_pack9  RR1 9x1K {Lib=RR9}
+  (    1 VCC )
+  (    2 /REF5 )
+  (    3 /REF4 )
+  (    4 /REF8 )
+  (    5 /REF6 )
+  (    6 /REF9 )
+  (    7 /REF7 )
+  (    8 /REF11 )
+  (    9 /REF10 )
+  (   10 ? )
  )
- ( /32307ED4 C1 C3 47pF
-  ( 1 N-000146 )
-  ( 2 GND )
+ ( /3256759C DB25FC  P1 DB25FEMELLE {Lib=DB25}
+  (    1 /STROBE )
+  (    2 /BIT0 )
+  (    3 /BIT1 )
+  (    4 /BIT2 )
+  (    5 /BIT3 )
+  (    6 /BIT4 )
+  (    7 /BIT5 )
+  (    8 /BIT6 )
+  (    9 /BIT7 )
+  (   10 /ACK )
+  (   11 /BUST+ )
+  (   12 /PE+ )
+  (   13 /SLCT+ )
+  (   14 /AUTOFD- )
+  (   15 /ERROR- )
+  (   16 /INIT- )
+  (   17 /SLCTIN- )
+  (   18 GND )
+  (   19 GND )
+  (   20 GND )
+  (   21 GND )
+  (   22 GND )
+  (   23 GND )
+  (   24 GND )
+  (   25 GND )
  )
- ( /32307DCF CP6 C4 47uF
-  ( 1 VCC )
-  ( 2 GND )
+ ( /324002E6 R3  R3 10K {Lib=R}
+  (    1 N-000072 )
+  (    2 VCC )
  )
- ( /32307DCA CP6 C5 47uF
-  ( 1 VCC )
-  ( 2 GND )
+ ( /3240023F 32dip600  U5 628128 {Lib=628128}
+  (    2 /MA16 )
+  (    3 /MA14 )
+  (    4 /MA12 )
+  (    5 /MA7 )
+  (    6 /MA6 )
+  (    7 /MA5 )
+  (    8 /MA4 )
+  (    9 /MA3 )
+  (   10 /MA2 )
+  (   11 /MA1 )
+  (   12 /MA0 )
+  (   13 /MD0 )
+  (   14 /MD1 )
+  (   15 /MD2 )
+  (   16 GND )
+  (   17 /MD3 )
+  (   18 /MD4 )
+  (   19 /MD5 )
+  (   20 /MD6 )
+  (   21 /MD7 )
+  (   22 /CS1- )
+  (   23 /MA10 )
+  (   24 /OE- )
+  (   25 /MA11 )
+  (   26 /MA9 )
+  (   27 /MA8 )
+  (   28 /MA13 )
+  (   29 /WR- )
+  (   30 N-000072 )
+  (   31 /MA15 )
+  (   32 VCC )
  )
- ( /32307DC0 CP6 C6 47uF
-  ( 1 VCC )
-  ( 2 GND )
+ ( /32307ED4 C1  C3 47pF {Lib=C}
+  (    1 N-000146 )
+  (    2 GND )
  )
- ( /322D32AC LEDV D1 LED
-  ( 1 N-000105 )
-  ( 2 GND )
+ ( /32307ECF C1  C2 47pF {Lib=C}
+  (    1 N-000145 )
+  (    2 GND )
  )
- ( /322D32BE LEDV D2 LED
-  ( 1 N-000104 )
-  ( 2 GND )
+ ( /32307EC0 HC-18UH  X1 8MHz {Lib=CRYSTAL}
+  (    1 N-000145 )
+  (    2 N-000146 )
  )
- ( /32568D1E pin_array_8x2 JP1 CONN_8X2
-  ( 1 GND )
-  ( 2 /REF10 )
-  ( 3 GND )
-  ( 4 /REF11 )
-  ( 5 GND )
-  ( 6 /REF7 )
-  ( 7 GND )
-  ( 8 /REF9 )
-  ( 9 GND )
-  ( 10 /REF6 )
-  ( 11 GND )
-  ( 12 /REF8 )
-  ( 13 GND )
-  ( 14 /REF4 )
-  ( 15 GND )
-  ( 16 /REF5 )
+ ( /32307EAA R3  R2 1K {Lib=R}
+  (    1 /8MH-OUT )
+  (    2 N-000146 )
  )
- ( /3256759C DB25FC P1 DB25FEMELLE
-  ( 1 /STROBE )
-  ( 2 /BIT0 )
-  ( 3 /BIT1 )
-  ( 4 /BIT2 )
-  ( 5 /BIT3 )
-  ( 6 /BIT4 )
-  ( 7 /BIT5 )
-  ( 8 /BIT6 )
-  ( 9 /BIT7 )
-  ( 10 /ACK )
-  ( 11 /BUST+ )
-  ( 12 /PE+ )
-  ( 13 /SLCT+ )
-  ( 14 /AUTOFD- )
-  ( 15 /ERROR- )
-  ( 16 /INIT- )
-  ( 17 /SLCTIN- )
-  ( 18 GND )
-  ( 19 GND )
-  ( 20 GND )
-  ( 21 GND )
-  ( 22 GND )
-  ( 23 GND )
-  ( 24 GND )
-  ( 25 GND )
+ ( /32307EA1 R3  R1 100K {Lib=R}
+  (    1 N-000146 )
+  (    2 N-000145 )
  )
- ( /32307EA1 R3 R1 100K
-  ( 1 N-000146 )
-  ( 2 N-000145 )
+ ( /32307DE2 CP6  C1 47uF {Lib=CP}
+  (    1 VCC )
+  (    2 GND )
  )
- ( /32307EAA R3 R2 1K
-  ( 1 /8MH-OUT )
-  ( 2 N-000146 )
+ ( /32307DCF CP6  C4 47uF {Lib=CP}
+  (    1 VCC )
+  (    2 GND )
  )
- ( /324002E6 R3 R3 10K
-  ( 1 N-000071 )
-  ( 2 VCC )
+ ( /32307DCA CP6  C5 47uF {Lib=CP}
+  (    1 VCC )
+  (    2 GND )
  )
- ( /322D3295 R3 R4 330
-  ( 1 N-000105 )
-  ( 2 /LED1 )
+ ( /32307DC0 CP6  C6 47uF {Lib=CP}
+  (    1 VCC )
+  (    2 GND )
  )
- ( /322D32A0 R3 R5 330
-  ( 1 N-000104 )
-  ( 2 /LED2 )
+ ( /322D35B4 20dip300  U2 74LS688 {Lib=74LS688}
+  (    1 /PC-AEN )
+  (    2 /PC-A5 )
+  (    3 /REF5 )
+  (    4 /PC-A8 )
+  (    5 /REF8 )
+  (    6 /PC-A9 )
+  (    7 /REF9 )
+  (    8 /PC-A11 )
+  (    9 /REF11 )
+  (   10 GND )
+  (   11 /PC-A10 )
+  (   12 /REF10 )
+  (   13 /PC-A7 )
+  (   14 /REF7 )
+  (   15 /PC-A6 )
+  (   16 /REF6 )
+  (   17 /PC-A4 )
+  (   18 /REF4 )
+  (   19 /MATCHL )
+  (   20 VCC )
  )
- ( /325679C1 r_pack9 RR1 9x1K
-  ( 1 VCC )
-  ( 2 /REF5 )
-  ( 3 /REF4 )
-  ( 4 /REF8 )
-  ( 5 /REF6 )
-  ( 6 /REF9 )
-  ( 7 /REF7 )
-  ( 8 /REF11 )
-  ( 9 /REF10 )
-  ( 10 ? )
+ ( /322D32FA PGA120  U9 4003APG120 {Lib=4003APG120}
+  (   A1 ? )
+  (   A2 ? )
+  (   A3 ? )
+  (   A4 /MA9 )
+  (   A5 /MD1 )
+  (   A6 /MD3 )
+  (   A7 /MD4 )
+  (   A8 /MD5 )
+  (   A9 /MD6 )
+  (  A10 /CS1- )
+  (  A11 /MA0 )
+  (  A12 /STROBE )
+  (  A13 /WR- )
+  (   B1 ? )
+  (   B2 /MA1 )
+  (   B3 /MA7 )
+  (   B4 ? )
+  (   B5 ? )
+  (   B6 /MD2 )
+  (   B7 GND )
+  (   B8 /MD7 )
+  (   B9 /OE- )
+  (  B10 ? )
+  (  B11 VCC )
+  (  B12 VCC )
+  (  B13 ? )
+  (   C1 /MA13 )
+  (   C2 /MA3 )
+  (   C3 VCC )
+  (   C4 GND )
+  (   C5 ? )
+  (   C6 /MD0 )
+  (   C8 /MA16 )
+  (   C9 /MA10 )
+  (  C10 GND )
+  (  C11 VCC )
+  (  C12 /AUTOFD- )
+  (  C13 /MA5 )
+  (   D1 /MA14 )
+  (   D2 /MA11 )
+  (   D3 /MA2 )
+  (  D11 VCC )
+  (  D12 /BIT0 )
+  (  D13 /ERROR- )
+  (   E1 /MA4 )
+  (   E2 ? )
+  (   E3 ? )
+  (  E11 ? )
+  (  E12 /INIT- )
+  (  E13 /BIT1 )
+  (   F1 /MA15 )
+  (   F2 /MA6 )
+  (   F3 /MA12 )
+  (  F11 /SLCTIN- )
+  (  F12 /BIT2 )
+  (  F13 /LED2 )
+  (   G1 /MA8 )
+  (   G2 GND )
+  (  G11 GND )
+  (  G12 VCC )
+  (  G13 /BIT3 )
+  (   H1 /PC-A8 )
+  (   H2 /PC-A7 )
+  (   H3 /PC-A4 )
+  (  H11 /BIT7 )
+  (  H12 /BIT5 )
+  (  H13 /BIT4 )
+  (   J1 /PC-A6 )
+  (   J2 /PC-A5 )
+  (   J3 ? )
+  (  J11 ? )
+  (  J12 /BUST+ )
+  (  J13 /BIT6 )
+  (   K1 /8MH-OUT )
+  (   K2 /PC-A3 )
+  (   K3 GND )
+  (  K11 GND )
+  (  K12 ? )
+  (  K13 /ACK )
+  (   L1 N-000145 )
+  (   L2 /SEL_LPT )
+  (   L3 VCC )
+  (   L4 /CLKLCA )
+  (   L5 ? )
+  (   L6 ? )
+  (   L7 GND )
+  (   L8 /PC-A10 )
+  (   L9 ? )
+  (  L10 VCC )
+  (  L11 /DONE )
+  (  L12 /D7 )
+  (  L13 /PE+ )
+  (   M1 ? )
+  (   M2 ? )
+  (   M3 /LED1 )
+  (   M4 /CLKLCA )
+  (   M5 /PC-A2 )
+  (   M6 /PC-A0 )
+  (   M7 VCC )
+  (   M8 /PC-RD )
+  (   M9 /D3 )
+  (  M10 /D4 )
+  (  M11 /D6 )
+  (  M12 /PROG- )
+  (   N1 ? )
+  (   N2 /D0 )
+  (   N3 ? )
+  (   N4 /PC-A1 )
+  (   N5 ? )
+  (   N6 /PC-WR )
+  (   N7 /PC-A9 )
+  (   N8 /D1 )
+  (   N9 /D2 )
+  (  N10 /PC-AEN )
+  (  N11 /D5 )
+  (  N12 ? )
+  (  N13 /SLCT+ )
  )
- ( /322D31F4 20dip300 U1 74LS245
-  ( 1 /DIR )
-  ( 2 /PC-DB0 )
-  ( 3 /PC-DB1 )
-  ( 4 /PC-DB2 )
-  ( 5 /PC-DB3 )
-  ( 6 /PC-DB4 )
-  ( 7 /PC-DB5 )
-  ( 8 /PC-DB6 )
-  ( 9 /PC-DB7 )
-  ( 10 GND )
-  ( 11 /D7 )
-  ( 12 /D6 )
-  ( 13 /D5 )
-  ( 14 /D4 )
-  ( 15 /D3 )
-  ( 16 /D2 )
-  ( 17 /D1 )
-  ( 18 /D0 )
-  ( 19 /ENBBUF )
-  ( 20 VCC )
+ ( /322D32BE LEDV  D2 LED {Lib=LED}
+  (    1 N-000103 )
+  (    2 GND )
  )
- ( /322D35B4 20dip300 U2 74LS688
-  ( 1 /PC-AEN )
-  ( 2 /PC-A5 )
-  ( 3 /REF5 )
-  ( 4 /PC-A8 )
-  ( 5 /REF8 )
-  ( 6 /PC-A9 )
-  ( 7 /REF9 )
-  ( 8 /PC-A11 )
-  ( 9 /REF11 )
-  ( 10 GND )
-  ( 11 /PC-A10 )
-  ( 12 /REF10 )
-  ( 13 /PC-A7 )
-  ( 14 /REF7 )
-  ( 15 /PC-A6 )
-  ( 16 /REF6 )
-  ( 17 /PC-A4 )
-  ( 18 /REF4 )
-  ( 19 /MATCHL )
-  ( 20 VCC )
+ ( /322D32AC LEDV  D1 LED {Lib=LED}
+  (    1 N-000107 )
+  (    2 GND )
  )
- ( /4A087146 $noname$ U3 74LS541
-  ( 1 GND )
-  ( 2 /PC-A1 )
-  ( 3 /PC-A0 )
-  ( 4 /PC-A2 )
-  ( 5 /PC-A3 )
-  ( 6 /PC-IOW )
-  ( 7 /PC-IOR )
-  ( 8 /PC-RST )
-  ( 9 /PC-RST )
-  ( 10 GND )
-  ( 11 ? )
-  ( 12 /RSTL )
-  ( 13 /PC-RD )
-  ( 14 /PC-WR )
-  ( 15 N-000109 )
-  ( 16 N-000108 )
-  ( 17 N-000107 )
-  ( 18 N-000106 )
-  ( 19 GND )
-  ( 20 VCC )
+ ( /322D32A0 R3  R5 330 {Lib=R}
+  (    1 N-000103 )
+  (    2 /LED2 )
  )
- ( /3240023F 32dip600 U5 628128
-  ( 2 /MA16 )
-  ( 3 /MA14 )
-  ( 4 /MA12 )
-  ( 5 /MA7 )
-  ( 6 /MA6 )
-  ( 7 /MA5 )
-  ( 8 /MA4 )
-  ( 9 /MA3 )
-  ( 10 /MA2 )
-  ( 11 /MA1 )
-  ( 12 /MA0 )
-  ( 13 /MD0 )
-  ( 14 /MD1 )
-  ( 15 /MD2 )
-  ( 16 GND )
-  ( 17 /MD3 )
-  ( 18 /MD4 )
-  ( 19 /MD5 )
-  ( 20 /MD6 )
-  ( 21 /MD7 )
-  ( 22 /CS1- )
-  ( 23 /MA10 )
-  ( 24 /OE- )
-  ( 25 /MA11 )
-  ( 26 /MA9 )
-  ( 27 /MA8 )
-  ( 28 /MA13 )
-  ( 29 /WR- )
-  ( 30 N-000071 )
-  ( 31 /MA15 )
-  ( 32 VCC )
+ ( /322D3295 R3  R4 330 {Lib=R}
+  (    1 N-000107 )
+  (    2 /LED1 )
  )
- ( /322D321C 24dip300 U8 EP600
-  ( 1 GND )
-  ( 2 /MATCHL )
-  ( 3 N-000106 )
-  ( 4 N-000107 )
-  ( 5 N-000108 )
-  ( 6 N-000109 )
-  ( 7 /PC-WR )
-  ( 8 ? )
-  ( 9 ? )
-  ( 10 ? )
-  ( 11 /RSTL )
-  ( 12 GND )
-  ( 13 /WR_REG )
-  ( 14 /PC-RD )
-  ( 15 /WR_REG )
-  ( 16 /CLKLCA )
-  ( 17 /DIR )
-  ( 18 /SEL_LPT )
-  ( 19 /PROG- )
-  ( 20 /DONE )
-  ( 21 /D0 )
-  ( 22 /ENBBUF )
-  ( 23 VCC )
-  ( 24 VCC )
+ ( /322D321C 24dip300  U8 EP600 {Lib=EP600}
+  (    1 GND )
+  (    2 /MATCHL )
+  (    3 N-000108 )
+  (    4 N-000109 )
+  (    5 N-000110 )
+  (    6 N-000111 )
+  (    7 /PC-WR )
+  (    8 ? )
+  (    9 ? )
+  (   10 ? )
+  (   11 /RSTL )
+  (   12 GND )
+  (   13 /WR_REG )
+  (   14 /PC-RD )
+  (   15 /WR_REG )
+  (   16 /CLKLCA )
+  (   17 /DIR )
+  (   18 /SEL_LPT )
+  (   19 /PROG- )
+  (   20 /DONE )
+  (   21 /D0 )
+  (   22 /ENBBUF )
+  (   23 VCC )
+  (   24 VCC )
  )
- ( /322D32FA PGA120 U9 4003APG120
-  ( A1 ? )
-  ( A2 ? )
-  ( A3 ? )
-  ( A4 /MA9 )
-  ( A5 /MD1 )
-  ( A6 /MD3 )
-  ( A7 /MD4 )
-  ( A8 /MD5 )
-  ( A9 /MD6 )
-  ( A10 /CS1- )
-  ( A11 /MA0 )
-  ( A12 /STROBE )
-  ( A13 /WR- )
-  ( B1 ? )
-  ( B2 /MA1 )
-  ( B3 /MA7 )
-  ( B4 ? )
-  ( B5 ? )
-  ( B6 /MD2 )
-  ( B7 GND )
-  ( B8 /MD7 )
-  ( B9 /OE- )
-  ( B10 ? )
-  ( B11 VCC )
-  ( B12 VCC )
-  ( B13 ? )
-  ( C1 /MA13 )
-  ( C2 /MA3 )
-  ( C3 VCC )
-  ( C4 GND )
-  ( C5 ? )
-  ( C6 /MD0 )
-  ( C8 /MA16 )
-  ( C9 /MA10 )
-  ( C10 GND )
-  ( C11 VCC )
-  ( C12 /AUTOFD- )
-  ( C13 /MA5 )
-  ( D1 /MA14 )
-  ( D2 /MA11 )
-  ( D3 /MA2 )
-  ( D11 VCC )
-  ( D12 /BIT0 )
-  ( D13 /ERROR- )
-  ( E1 /MA4 )
-  ( E2 ? )
-  ( E3 ? )
-  ( E11 ? )
-  ( E12 /INIT- )
-  ( E13 /BIT1 )
-  ( F1 /MA15 )
-  ( F2 /MA6 )
-  ( F3 /MA12 )
-  ( F11 /SLCTIN- )
-  ( F12 /BIT2 )
-  ( F13 /LED2 )
-  ( G1 /MA8 )
-  ( G2 GND )
-  ( G11 GND )
-  ( G12 VCC )
-  ( G13 /BIT3 )
-  ( H1 /PC-A8 )
-  ( H2 /PC-A7 )
-  ( H3 /PC-A4 )
-  ( H11 /BIT7 )
-  ( H12 /BIT5 )
-  ( H13 /BIT4 )
-  ( J1 /PC-A6 )
-  ( J2 /PC-A5 )
-  ( J3 ? )
-  ( J11 ? )
-  ( J12 /BUST+ )
-  ( J13 /BIT6 )
-  ( K1 /8MH-OUT )
-  ( K2 /PC-A3 )
-  ( K3 GND )
-  ( K11 GND )
-  ( K12 ? )
-  ( K13 /ACK )
-  ( L1 N-000145 )
-  ( L2 /SEL_LPT )
-  ( L3 VCC )
-  ( L4 /CLKLCA )
-  ( L5 ? )
-  ( L6 ? )
-  ( L7 GND )
-  ( L8 /PC-A10 )
-  ( L9 ? )
-  ( L10 VCC )
-  ( L11 /DONE )
-  ( L12 /D7 )
-  ( L13 /PE+ )
-  ( M1 ? )
-  ( M2 ? )
-  ( M3 /LED1 )
-  ( M4 /CLKLCA )
-  ( M5 /PC-A2 )
-  ( M6 /PC-A0 )
-  ( M7 VCC )
-  ( M8 /PC-RD )
-  ( M9 /D3 )
-  ( M10 /D4 )
-  ( M11 /D6 )
-  ( M12 /PROG- )
-  ( N1 ? )
-  ( N2 /D0 )
-  ( N3 ? )
-  ( N4 /PC-A1 )
-  ( N5 ? )
-  ( N6 /PC-WR )
-  ( N7 /PC-A9 )
-  ( N8 /D1 )
-  ( N9 /D2 )
-  ( N10 /PC-AEN )
-  ( N11 /D5 )
-  ( N12 ? )
-  ( N13 /SLCT+ )
+ ( /322D31F4 20dip300  U1 74LS245 {Lib=74LS245}
+  (    1 /DIR )
+  (    2 /PC-DB0 )
+  (    3 /PC-DB1 )
+  (    4 /PC-DB2 )
+  (    5 /PC-DB3 )
+  (    6 /PC-DB4 )
+  (    7 /PC-DB5 )
+  (    8 /PC-DB6 )
+  (    9 /PC-DB7 )
+  (   10 GND )
+  (   11 /D7 )
+  (   12 /D6 )
+  (   13 /D5 )
+  (   14 /D4 )
+  (   15 /D3 )
+  (   16 /D2 )
+  (   17 /D1 )
+  (   18 /D0 )
+  (   19 /ENBBUF )
+  (   20 VCC )
  )
- ( /32307EC0 HC-18UH X1 8MHz
-  ( 1 N-000145 )
-  ( 2 N-000146 )
+ ( /322D3011 BUS_PC  BUS1 BUSPC {Lib=BUSPC}
+  (    1 GND )
+  (    2 /PC-RST )
+  (    3 VCC )
+  (    4 ? )
+  (    5 ? )
+  (    6 ? )
+  (    7 ? )
+  (    8 ? )
+  (    9 ? )
+  (   10 ? )
+  (   11 ? )
+  (   12 ? )
+  (   13 /PC-IOW )
+  (   14 /PC-IOR )
+  (   15 ? )
+  (   16 ? )
+  (   17 ? )
+  (   18 ? )
+  (   19 ? )
+  (   20 ? )
+  (   21 ? )
+  (   22 ? )
+  (   23 ? )
+  (   24 ? )
+  (   25 ? )
+  (   26 ? )
+  (   27 ? )
+  (   28 ? )
+  (   29 VCC )
+  (   30 ? )
+  (   31 GND )
+  (   32 ? )
+  (   33 /PC-DB7 )
+  (   34 /PC-DB6 )
+  (   35 /PC-DB5 )
+  (   36 /PC-DB4 )
+  (   37 /PC-DB3 )
+  (   38 /PC-DB2 )
+  (   39 /PC-DB1 )
+  (   40 /PC-DB0 )
+  (   41 ? )
+  (   42 /PC-AEN )
+  (   43 ? )
+  (   44 ? )
+  (   45 ? )
+  (   46 ? )
+  (   47 ? )
+  (   48 ? )
+  (   49 ? )
+  (   50 ? )
+  (   51 /PC-A11 )
+  (   52 /PC-A10 )
+  (   53 /PC-A9 )
+  (   54 /PC-A8 )
+  (   55 /PC-A7 )
+  (   56 /PC-A6 )
+  (   57 /PC-A5 )
+  (   58 /PC-A4 )
+  (   59 /PC-A3 )
+  (   60 /PC-A2 )
+  (   61 /PC-A1 )
+  (   62 /PC-A0 )
  )
 )
 *
 { Allowed footprints by component:
-$component C1
- CP*
+$component P1
+ DB25*
+$endlist
+$component R3
+ R?
+ SM0603
+ SM0805
+ R?-*
+ SM1206
+$endlist
+$component C3
  SM*
+ C?
+ C1-1
 $endlist
 $component C2
  SM*
  C?
  C1-1
 $endlist
-$component C3
+$component R2
+ R?
+ SM0603
+ SM0805
+ R?-*
+ SM1206
+$endlist
+$component R1
+ R?
+ SM0603
+ SM0805
+ R?-*
+ SM1206
+$endlist
+$component C1
+ CP*
  SM*
- C?
- C1-1
 $endlist
 $component C4
  CP*
@@ -450,15 +474,6 @@ $component C6
  CP*
  SM*
 $endlist
-$component D1
- LED-3MM
- LED-5MM
- LED-10MM
- LED-0603
- LED-0805
- LED-1206
- LEDV
-$endlist
 $component D2
  LED-3MM
  LED-5MM
@@ -468,24 +483,16 @@ $component D2
  LED-1206
  LEDV
 $endlist
-$component P1
- DB25*
+$component D1
+ LED-3MM
+ LED-5MM
+ LED-10MM
+ LED-0603
+ LED-0805
+ LED-1206
+ LEDV
 $endlist
-$component R1
- R?
- SM0603
- SM0805
- R?-*
- SM1206
-$endlist
-$component R2
- R?
- SM0603
- SM0805
- R?-*
- SM1206
-$endlist
-$component R3
+$component R5
  R?
  SM0603
  SM0805
@@ -499,12 +506,428 @@ $component R4
  R?-*
  SM1206
 $endlist
-$component R5
- R?
- SM0603
- SM0805
- R?-*
- SM1206
-$endlist
 $endfootprintlist
 }
+{ Pin List by Nets
+Net 15 "/PC-RST" "PC-RST"
+ BUS1 2
+ U3 8
+ U3 9
+Net 16 "/PC-IOR" "PC-IOR"
+ BUS1 14
+ U3 7
+Net 17 "/PC-IOW" "PC-IOW"
+ U3 6
+ BUS1 13
+Net 19 "/PC-A1" "PC-A1"
+ BUS1 61
+ U9 N4
+ U3 2
+Net 20 "/PC-A0" "PC-A0"
+ U9 M6
+ BUS1 62
+ U3 3
+Net 21 "GND" "GND"
+ P1 18
+ U9 G11
+ U9 K11
+ U9 C10
+ U9 G2
+ BUS1 1
+ D2 2
+ U1 10
+ U9 C4
+ P1 20
+ D1 2
+ U9 K3
+ U8 1
+ U9 L7
+ U9 B7
+ JP1 13
+ JP1 11
+ P1 25
+ U5 16
+ P1 24
+ P1 23
+ JP1 15
+ U8 12
+ P1 22
+ P1 21
+ C1 2
+ C4 2
+ C5 2
+ C6 2
+ U2 10
+ C3 2
+ U3 10
+ U3 19
+ U3 1
+ JP1 7
+ JP1 5
+ JP1 3
+ JP1 1
+ C2 2
+ BUS1 31
+ P1 19
+ JP1 9
+Net 22 "VCC" "VCC"
+ C1 1
+ C4 1
+ U8 24
+ C5 1
+ U8 23
+ C6 1
+ U2 20
+ U9 B12
+ U9 L3
+ U9 M7
+ U3 20
+ U9 D11
+ U1 20
+ U9 C11
+ U9 B11
+ R3 2
+ BUS1 3
+ BUS1 29
+ U9 G12
+ U5 32
+ U9 C3
+ U9 L10
+ RR1 1
+Net 23 "/PC-AEN" "PC-AEN"
+ U9 N10
+ BUS1 42
+ U2 1
+Net 52 "/MA8" "MA8"
+ U9 G1
+ U5 27
+Net 53 "/MD4" "MD4"
+ U9 A7
+ U5 18
+Net 54 "/MA13" "MA13"
+ U5 28
+ U9 C1
+Net 55 "/MD5" "MD5"
+ U9 A8
+ U5 19
+Net 56 "/WR-" "WR-"
+ U5 29
+ U9 A13
+Net 57 "/MD3" "MD3"
+ U5 17
+ U9 A6
+Net 61 "/RSTL" "RSTL"
+ U3 12
+ U8 11
+Net 63 "/MA16" "MA16"
+ U9 C8
+ U5 2
+Net 64 "/MA14" "MA14"
+ U5 3
+ U9 D1
+Net 65 "/MA12" "MA12"
+ U9 F3
+ U5 4
+Net 66 "/MA7" "MA7"
+ U5 5
+ U9 B3
+Net 67 "/MA6" "MA6"
+ U9 F2
+ U5 6
+Net 68 "/MA5" "MA5"
+ U9 C13
+ U5 7
+Net 69 "/MA4" "MA4"
+ U9 E1
+ U5 8
+Net 70 "/MA3" "MA3"
+ U5 9
+ U9 C2
+Net 71 "/MD6" "MD6"
+ U9 A9
+ U5 20
+Net 72 "" ""
+ R3 1
+ U5 30
+Net 73 "/MD7" "MD7"
+ U5 21
+ U9 B8
+Net 74 "/MA15" "MA15"
+ U5 31
+ U9 F1
+Net 75 "/MA0" "MA0"
+ U5 12
+ U9 A11
+Net 76 "/CS1-" "CS1-"
+ U9 A10
+ U5 22
+Net 77 "/MD0" "MD0"
+ U9 C6
+ U5 13
+Net 78 "/MA10" "MA10"
+ U5 23
+ U9 C9
+Net 79 "/MD1" "MD1"
+ U5 14
+ U9 A5
+Net 80 "/OE-" "OE-"
+ U5 24
+ U9 B9
+Net 81 "/MD2" "MD2"
+ U5 15
+ U9 B6
+Net 82 "/MA11" "MA11"
+ U5 25
+ U9 D2
+Net 83 "/MA9" "MA9"
+ U5 26
+ U9 A4
+Net 84 "/DIR" "DIR"
+ U8 17
+ U1 1
+Net 85 "/ENBBUF" "ENBBUF"
+ U8 22
+ U1 19
+Net 86 "/PC-RD" "PC-RD"
+ U8 14
+ U3 13
+ U9 M8
+Net 87 "/SEL_LPT" "SEL_LPT"
+ U8 18
+ U9 L2
+Net 88 "/PC-DB0" "PC-DB0"
+ U1 2
+ BUS1 40
+Net 89 "/PC-DB1" "PC-DB1"
+ U1 3
+ BUS1 39
+Net 90 "/PC-DB2" "PC-DB2"
+ U1 4
+ BUS1 38
+Net 91 "/PC-DB3" "PC-DB3"
+ U1 5
+ BUS1 37
+Net 92 "/PC-DB4" "PC-DB4"
+ BUS1 36
+ U1 6
+Net 93 "/PC-DB5" "PC-DB5"
+ U1 7
+ BUS1 35
+Net 94 "/PC-DB6" "PC-DB6"
+ U1 8
+ BUS1 34
+Net 95 "/PC-DB7" "PC-DB7"
+ BUS1 33
+ U1 9
+Net 96 "/D7" "D7"
+ U9 L12
+ U1 11
+Net 97 "/D6" "D6"
+ U9 M11
+ U1 12
+Net 98 "/D5" "D5"
+ U9 N11
+ U1 13
+Net 99 "/D4" "D4"
+ U9 M10
+ U1 14
+Net 100 "/D3" "D3"
+ U9 M9
+ U1 15
+Net 101 "/D2" "D2"
+ U1 16
+ U9 N9
+Net 102 "/D1" "D1"
+ U1 17
+ U9 N8
+Net 103 "" ""
+ D2 1
+ R5 1
+Net 105 "/LED2" "LED2"
+ R5 2
+ U9 F13
+Net 106 "/D0" "D0"
+ U8 21
+ U9 N2
+ U1 18
+Net 107 "" ""
+ D1 1
+ R4 1
+Net 108 "" ""
+ U3 18
+ U8 3
+Net 109 "" ""
+ U3 17
+ U8 4
+Net 110 "" ""
+ U3 16
+ U8 5
+Net 111 "" ""
+ U3 15
+ U8 6
+Net 112 "/PC-WR" "PC-WR"
+ U8 7
+ U9 N6
+ U3 14
+Net 113 "/PC-A6" "PC-A6"
+ U9 J1
+ BUS1 56
+ U2 15
+Net 114 "/PC-A9" "PC-A9"
+ U9 N7
+ BUS1 53
+ U2 6
+Net 115 "/PC-A8" "PC-A8"
+ U2 4
+ U9 H1
+ BUS1 54
+Net 116 "/PC-A7" "PC-A7"
+ BUS1 55
+ U9 H2
+ U2 13
+Net 117 "/PC-A5" "PC-A5"
+ BUS1 57
+ U2 2
+ U9 J2
+Net 118 "/PC-A4" "PC-A4"
+ BUS1 58
+ U9 H3
+ U2 17
+Net 119 "/PC-A3" "PC-A3"
+ U3 5
+ U9 K2
+ BUS1 59
+Net 120 "/PC-A2" "PC-A2"
+ U3 4
+ U9 M5
+ BUS1 60
+Net 121 "/PC-A11" "PC-A11"
+ U2 8
+ BUS1 51
+Net 122 "/PC-A10" "PC-A10"
+ U9 L8
+ BUS1 52
+ U2 11
+Net 123 "/LED1" "LED1"
+ U9 M3
+ R4 2
+Net 125 "/MA2" "MA2"
+ U9 D3
+ U5 10
+Net 128 "/CLKLCA" "CLKLCA"
+ U8 16
+ U9 L4
+ U9 M4
+Net 131 "/MATCHL" "MATCHL"
+ U2 19
+ U8 2
+Net 134 "/MA1" "MA1"
+ U5 11
+ U9 B2
+Net 137 "/DONE" "DONE"
+ U8 20
+ U9 L11
+Net 139 "/PROG-" "PROG-"
+ U8 19
+ U9 M12
+Net 144 "/WR_REG" "WR_REG"
+ U8 13
+ U8 15
+Net 145 "" ""
+ X1 1
+ C2 1
+ R1 2
+ U9 L1
+Net 146 "" ""
+ X1 2
+ R1 1
+ C3 1
+ R2 2
+Net 147 "/BIT6" "BIT6"
+ U9 J13
+ P1 8
+Net 148 "/BIT7" "BIT7"
+ P1 9
+ U9 H11
+Net 149 "/ACK" "ACK"
+ P1 10
+ U9 K13
+Net 150 "/BUST+" "BUST+"
+ U9 J12
+ P1 11
+Net 151 "/PE+" "PE+"
+ P1 12
+ U9 L13
+Net 152 "/SLCT+" "SLCT+"
+ P1 13
+ U9 N13
+Net 153 "/BIT5" "BIT5"
+ U9 H12
+ P1 7
+Net 154 "/8MH-OUT" "8MH-OUT"
+ R2 1
+ U9 K1
+Net 156 "/STROBE" "STROBE"
+ P1 1
+ U9 A12
+Net 157 "/AUTOFD-" "AUTOFD-"
+ P1 14
+ U9 C12
+Net 158 "/ERROR-" "ERROR-"
+ P1 15
+ U9 D13
+Net 159 "/BIT2" "BIT2"
+ U9 F12
+ P1 4
+Net 160 "/INIT-" "INIT-"
+ P1 16
+ U9 E12
+Net 161 "/SLCTIN-" "SLCTIN-"
+ P1 17
+ U9 F11
+Net 162 "/BIT0" "BIT0"
+ U9 D12
+ P1 2
+Net 163 "/BIT1" "BIT1"
+ P1 3
+ U9 E13
+Net 164 "/BIT3" "BIT3"
+ U9 G13
+ P1 5
+Net 165 "/BIT4" "BIT4"
+ P1 6
+ U9 H13
+Net 166 "/REF10" "REF10"
+ U2 12
+ JP1 2
+ RR1 9
+Net 167 "/REF11" "REF11"
+ JP1 4
+ RR1 8
+ U2 9
+Net 168 "/REF7" "REF7"
+ JP1 6
+ RR1 7
+ U2 14
+Net 169 "/REF9" "REF9"
+ JP1 8
+ U2 7
+ RR1 6
+Net 170 "/REF6" "REF6"
+ U2 16
+ RR1 5
+ JP1 10
+Net 171 "/REF8" "REF8"
+ RR1 4
+ U2 5
+ JP1 12
+Net 172 "/REF4" "REF4"
+ RR1 3
+ U2 18
+ JP1 14
+Net 173 "/REF5" "REF5"
+ JP1 16
+ RR1 2
+ U2 3
+}
+#End
diff --git a/eeschema/netform.cpp b/eeschema/netform.cpp
index 0bbd44f04a..66946b8223 100644
--- a/eeschema/netform.cpp
+++ b/eeschema/netform.cpp
@@ -24,7 +24,7 @@
  */
 
 /**
- * @file netform.cpp
+ * @file eeschema/netform.cpp
  * @brief Net list generation code.
  */
 
@@ -47,8 +47,6 @@
 
 #include <wx/tokenzr.h>
 
-
-
 #include <xnode.h>      // also nests: <wx/xml/xml.h>
 
 #include <build_version.h>
@@ -57,13 +55,6 @@
 
 #include <set>
 
-/**
- * @bug - Every place in this file where fprintf() is used and the return
- *        is not checked is a bug.  The fprintf() function can fail and
- *        returns a value less than 0 when it does.
- */
-
-
 /**
  * Class UNIQUE_STRINGS
  * tracks unique wxStrings and is useful in telling if a string
@@ -99,18 +90,19 @@ bool UNIQUE_STRINGS::Lookup( const wxString& aString )
 
 
 /**
- * Class EXPORT_HELP
+ * Class NETLIST_EXPORT_TOOL
  * is a private implementation class used in this source file to keep track
  * of and recycle datastructures used in the generation of various exported netlist
  * files.  Since it is private it is not in a header file.
  */
-class EXPORT_HELP
+class NETLIST_EXPORT_TOOL
 {
     /// Used to temporary store and filter the list of pins of a schematic component
     /// when generating schematic component data in netlist (comp section)
     NETLIST_OBJECT_LIST m_SortedComponentPinList;
 
-    /// Used for "multi parts per package" components, avoids processing a lib component more than once.
+    /// Used for "multi parts per package" components,
+    /// avoids processing a lib component more than once.
     UNIQUE_STRINGS      m_ReferencesAlreadyFound;
 
     // share a code generated std::set<void*> to reduce code volume
@@ -196,7 +188,7 @@ class EXPORT_HELP
      *   - 6 CA
      * </p>
      */
-    void writeListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList );
+    bool writeListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList );
 
     /**
      * Function makeGenericRoot
@@ -240,6 +232,16 @@ class EXPORT_HELP
 
 public:
 
+    /**
+     * Function WriteKiCadNetList
+     * creates a netlist, using the S expressions.
+     * the netlist creates the same data as the generic XML netlist,
+     * but using SWEET (or S expression), more easy to read and faster to parse
+     * @param aOutFileName = the full filename of the file to create
+     * @return bool - true if there were no errors, else false.
+     */
+    bool WriteKiCadNetList( const wxString& aOutFileName );
+
     /**
      * Function WriteGENERICNetList
      * creates a generic netlist, now in XML.
@@ -286,7 +288,7 @@ public:
      * .. B * T3 1
      *U1 * 14
      */
-    void WriteNetListCADSTAR( FILE* f );
+    bool WriteNetListCADSTAR( FILE* f );
 
     /**
      * Function WriteNetListPspice
@@ -338,7 +340,7 @@ public:
 };
 
 
-wxString EXPORT_HELP::MakeCommandLine( const wxString& aFormatString,
+wxString NETLIST_EXPORT_TOOL::MakeCommandLine( const wxString& aFormatString,
             const wxString& aTempfile, const wxString& aFinalFile )
 {
     wxString    ret  = aFormatString;
@@ -353,26 +355,29 @@ wxString EXPORT_HELP::MakeCommandLine( const wxString& aFormatString,
 }
 
 
-/**
- * Function  WriteNetListFile
+/* Function  WriteNetListFile
  * creates the netlist file. Netlist info must be existing
- * @param aFormat = netlist format (NET_TYPE_PCBNEW ...)
- * @param aFullFileName = full netlist file name
- * @param aUse_netnames = bool. if true, use net names from labels in schematic
- *                              if false, use net numbers (net codes)
- *   bool aUse_netnames is used only for Spice netlist
- * @param aUsePrefix = true, adds an 'X' prefix to any reference designator starting with "U" or "IC",
- *                     false to leave reference designator unchanged.
- * @return true if success.
+ * param aFormat = netlist format (NET_TYPE_PCBNEW ...)
+ * param aFullFileName = full netlist file name
+ * param aNetlistOptions = netlist options using OR'ed bits.
+ * For SPICE netlist only:
+ *      if NET_USE_NETNAMES is set, use net names from labels in schematic
+ *                             else use net numbers (net codes)
+ *      if NET_USE_X_PREFIX is set : change "U" and "IC" refernce prefix to "X"
+ * return true if success.
  */
 bool SCH_EDIT_FRAME::WriteNetListFile( int aFormat, const wxString& aFullFileName,
-                                       bool aUse_netnames, bool aUsePrefix )
+                                       unsigned aNetlistOptions )
 {
     bool        ret = true;
     FILE*       f = NULL;
-    EXPORT_HELP helper;
+    NETLIST_EXPORT_TOOL helper;
 
-    if( aFormat < NET_TYPE_CUSTOM1 )
+    bool open_file = aFormat < NET_TYPE_CUSTOM1;
+    if( (aFormat == NET_TYPE_PCBNEW) && (aNetlistOptions & NET_PCBNEW_USE_NEW_FORMAT ) )
+        open_file = false;
+
+    if( open_file )
     {
         if( ( f = wxFopen( aFullFileName, wxT( "wt" ) ) ) == NULL )
         {
@@ -387,8 +392,13 @@ bool SCH_EDIT_FRAME::WriteNetListFile( int aFormat, const wxString& aFullFileNam
     switch( aFormat )
     {
     case NET_TYPE_PCBNEW:
-        ret = helper.WriteNetListPCBNEW( f, true );
-        fclose( f );
+        if( (aNetlistOptions & NET_PCBNEW_USE_NEW_FORMAT ) )
+            ret = helper.WriteKiCadNetList( aFullFileName );
+        else
+        {
+            ret = helper.WriteNetListPCBNEW( f, true );
+            fclose( f );
+        }
         break;
 
     case NET_TYPE_ORCADPCB2:
@@ -397,12 +407,14 @@ bool SCH_EDIT_FRAME::WriteNetListFile( int aFormat, const wxString& aFullFileNam
         break;
 
     case NET_TYPE_CADSTAR:
-        helper.WriteNetListCADSTAR( f );
+        ret = helper.WriteNetListCADSTAR( f );
         fclose( f );
         break;
 
     case NET_TYPE_SPICE:
-        ret = helper.WriteNetListPspice( f, aUse_netnames, aUsePrefix );
+        ret = helper.WriteNetListPspice( f,
+                                         aNetlistOptions & NET_USE_NETNAMES,
+                                         aNetlistOptions & NET_USE_X_PREFIX );
         fclose( f );
         break;
 
@@ -425,7 +437,7 @@ bool SCH_EDIT_FRAME::WriteNetListFile( int aFormat, const wxString& aFullFileNam
             // "xsltproc -o %O /usr/local/lib/kicad/plugins/netlist_form_pads-pcb.xsl %I"
             // becomes, after the user selects /tmp/s1.net as the output file from the file dialog:
             // "xsltproc -o /tmp/s1.net /usr/local/lib/kicad/plugins/netlist_form_pads-pcb.xsl /tmp/s1.xml"
-            wxString commandLine = EXPORT_HELP::MakeCommandLine( m_netListerCommand,
+            wxString commandLine = NETLIST_EXPORT_TOOL::MakeCommandLine( m_netListerCommand,
                                                                  tmpFile.GetFullPath(),
                                                                  aFullFileName );
 
@@ -456,7 +468,7 @@ static bool sortPinsByNumber( LIB_PIN* aPin1, LIB_PIN* aPin2 )
 }
 
 
-void EXPORT_HELP::sprintPinNetName( wxString* aResult,
+void NETLIST_EXPORT_TOOL::sprintPinNetName( wxString* aResult,
                                     const wxString& aNetNameFormat, NETLIST_OBJECT* aPin )
 {
     int netcode = aPin->GetNet();
@@ -496,7 +508,7 @@ void EXPORT_HELP::sprintPinNetName( wxString* aResult,
 }
 
 
-SCH_COMPONENT* EXPORT_HELP::findNextComponent( EDA_ITEM* aItem, SCH_SHEET_PATH* aSheetPath )
+SCH_COMPONENT* NETLIST_EXPORT_TOOL::findNextComponent( EDA_ITEM* aItem, SCH_SHEET_PATH* aSheetPath )
 {
     wxString    ref;
 
@@ -543,7 +555,7 @@ SCH_COMPONENT* EXPORT_HELP::findNextComponent( EDA_ITEM* aItem, SCH_SHEET_PATH*
 }
 
 
-SCH_COMPONENT* EXPORT_HELP::findNextComponentAndCreatePinList( EDA_ITEM*       aItem,
+SCH_COMPONENT* NETLIST_EXPORT_TOOL::findNextComponentAndCreatePinList( EDA_ITEM*       aItem,
                                                               SCH_SHEET_PATH* aSheetPath )
 {
     wxString    ref;
@@ -643,7 +655,7 @@ static XNODE* node( const wxString& aName, const wxString& aTextualContent = wxE
 }
 
 
-XNODE* EXPORT_HELP::makeGenericDesignHeader()
+XNODE* NETLIST_EXPORT_TOOL::makeGenericDesignHeader()
 {
     XNODE*  xdesign = node( wxT("design") );
 
@@ -682,7 +694,7 @@ XNODE* EXPORT_HELP::makeGenericDesignHeader()
 }
 
 
-XNODE* EXPORT_HELP::makeGenericLibraries()
+XNODE* NETLIST_EXPORT_TOOL::makeGenericLibraries()
 {
     XNODE*  xlibs = node( wxT( "libraries" ) );     // auto_ptr
 
@@ -702,7 +714,7 @@ XNODE* EXPORT_HELP::makeGenericLibraries()
 }
 
 
-XNODE* EXPORT_HELP::makeGenericLibParts()
+XNODE* NETLIST_EXPORT_TOOL::makeGenericLibParts()
 {
     XNODE*      xlibparts = node( wxT( "libparts" ) );   // auto_ptr
     wxString    sLibpart  = wxT( "libpart" );
@@ -780,8 +792,8 @@ XNODE* EXPORT_HELP::makeGenericLibParts()
 
         /* we must erase redundant Pins references in pinList
          * These redundant pins exist because some pins
-         * are found more than one time when we have a component
-         * multiple parts per package or have 2 representations (DeMorgan conversion)
+         * are found more than one time when a component has
+         * multiple parts per package or has 2 representations (DeMorgan conversion)
          * For instance, a 74ls00 has DeMorgan conversion, with different pin shapes,
          * and therefore each pin  appears 2 times in the list.
          * Common pins (VCC, GND) can also be found more than once.
@@ -819,7 +831,7 @@ XNODE* EXPORT_HELP::makeGenericLibParts()
 }
 
 
-XNODE* EXPORT_HELP::makeGenericListOfNets()
+XNODE* NETLIST_EXPORT_TOOL::makeGenericListOfNets()
 {
     XNODE*      xnets = node( wxT( "nets" ) );      // auto_ptr if exceptions ever get used.
     wxString    netCodeTxt;
@@ -908,7 +920,7 @@ XNODE* EXPORT_HELP::makeGenericListOfNets()
 }
 
 
-XNODE* EXPORT_HELP::makeGenericRoot()
+XNODE* NETLIST_EXPORT_TOOL::makeGenericRoot()
 {
     XNODE*      xroot = node( wxT( "export" ) );
 
@@ -930,7 +942,7 @@ XNODE* EXPORT_HELP::makeGenericRoot()
 }
 
 
-XNODE* EXPORT_HELP::makeGenericComponents()
+XNODE* NETLIST_EXPORT_TOOL::makeGenericComponents()
 {
     XNODE*      xcomps = node( wxT( "components" ) );
 
@@ -1045,16 +1057,12 @@ XNODE* EXPORT_HELP::makeGenericComponents()
 
 #include <wx/wfstream.h>        // wxFFileOutputStream
 
-bool EXPORT_HELP::WriteGENERICNetList( const wxString& aOutFileName )
+bool NETLIST_EXPORT_TOOL::WriteKiCadNetList( const wxString& aOutFileName )
 {
     // Prepare list of nets generation
     for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ )
         g_NetObjectslist[ii]->m_Flag = 0;
 
-#if 0
-
-    // this code seems to work now, for S-expression support.
-
     bool rc = false;
     wxFFileOutputStream os( aOutFileName, wxT( "wt" ) );
 
@@ -1084,8 +1092,15 @@ bool EXPORT_HELP::WriteGENERICNetList( const wxString& aOutFileName )
     }
 
     return rc;
+}
 
-#elif 1
+bool NETLIST_EXPORT_TOOL::WriteGENERICNetList( const wxString& aOutFileName )
+{
+    // Prepare list of nets generation
+    for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ )
+        g_NetObjectslist[ii]->m_Flag = 0;
+
+#if 1
     // output the XML format netlist.
     wxXmlDocument   xdoc;
 
@@ -1187,7 +1202,7 @@ bool EXPORT_HELP::WriteGENERICNetList( const wxString& aOutFileName )
 }
 
 
-bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames, bool aUsePrefix )
+bool NETLIST_EXPORT_TOOL::WriteNetListPspice( FILE* f, bool use_netnames, bool aUsePrefix )
 {
     int                 ret = 0;
     int                 nbitems;
@@ -1289,7 +1304,7 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames, bool aUsePrefi
 
     for( SCH_SHEET_PATH* sheet = sheetList.GetFirst();  sheet;  sheet = sheetList.GetNext() )
     {
-        fprintf( f, "*Sheet Name:%s\n", TO_UTF8( sheet->PathHumanReadable() ) );
+        ret |= fprintf( f, "*Sheet Name:%s\n", TO_UTF8( sheet->PathHumanReadable() ) );
 
         for( EDA_ITEM* item = sheet->LastDrawList();  item;  item = item->Next() )
         {
@@ -1439,14 +1454,14 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames, bool aUsePrefi
             for( unsigned i = 0;  i < pinSequence.size();  ++i )
             {
                 if( i==0 )
-                    fprintf( f, ";Node Sequence Spec.<" );
+                    ret |= fprintf( f, ";Node Sequence Spec.<" );
 
-                fprintf( f, "%s", TO_UTF8( stdPinNameArray.Item( pinSequence[i] ) ) );
+                ret |= fprintf( f, "%s", TO_UTF8( stdPinNameArray.Item( pinSequence[i] ) ) );
 
                 if( i < pinSequence.size()-1 )
-                    fprintf( f, "," );
+                    ret |= fprintf( f, "," );
                 else
-                    fprintf( f, ">" );
+                    ret |= fprintf( f, ">" );
             }
 
             // Next Netlist line record:
@@ -1478,7 +1493,7 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames, bool aUsePrefi
 }
 
 
-bool EXPORT_HELP::WriteNetListPCBNEW( FILE* f, bool with_pcbnew )
+bool NETLIST_EXPORT_TOOL::WriteNetListPCBNEW( FILE* f, bool with_pcbnew )
 {
     wxString    field;
     wxString    footprint;
@@ -1623,7 +1638,7 @@ bool EXPORT_HELP::WriteNetListPCBNEW( FILE* f, bool with_pcbnew )
 }
 
 
-bool EXPORT_HELP::addPinToComponentPinList( SCH_COMPONENT* aComponent,
+bool NETLIST_EXPORT_TOOL::addPinToComponentPinList( SCH_COMPONENT* aComponent,
                                       SCH_SHEET_PATH* aSheetPath, LIB_PIN* aPin )
 {
     // Search the PIN description for Pin in g_NetObjectslist
@@ -1662,12 +1677,12 @@ bool EXPORT_HELP::addPinToComponentPinList( SCH_COMPONENT* aComponent,
  * remove duplicate pins from aPinList (list of pins relative to a given component)
  * (i.e. set pointer to duplicate pins to NULL in this list).
  * also set .m_Flag member of "removed" NETLIST_OBJECT pins to 1
+ * When pins are duplicated, not connected duplicate is removed
+ * (for instance when a multiple part per package component has its power pins connected
+ * only on a part).
  */
-void EXPORT_HELP::eraseDuplicatePins( )
+void NETLIST_EXPORT_TOOL::eraseDuplicatePins( )
 {
-    if( m_SortedComponentPinList.size() == 0 )  // Trivial case: component with no pin
-        return;
-
     for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ )
     {
         if( m_SortedComponentPinList[ii] == NULL ) /* already deleted */
@@ -1717,7 +1732,7 @@ void EXPORT_HELP::eraseDuplicatePins( )
 }
 
 
-void EXPORT_HELP::findAllInstancesOfComponent( SCH_COMPONENT*  aComponent,
+void NETLIST_EXPORT_TOOL::findAllInstancesOfComponent( SCH_COMPONENT*  aComponent,
                                          LIB_COMPONENT*  aEntry,
                                          SCH_SHEET_PATH* aSheetPath )
 {
@@ -1759,7 +1774,7 @@ void EXPORT_HELP::findAllInstancesOfComponent( SCH_COMPONENT*  aComponent,
 }
 
 
-bool EXPORT_HELP::writeGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
+bool NETLIST_EXPORT_TOOL::writeGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
 {
     int         ret = 0;
     int         netCode;
@@ -1852,8 +1867,9 @@ bool EXPORT_HELP::writeGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjects
 static wxString StartLine( wxT( "." ) );
 
 
-void EXPORT_HELP::WriteNetListCADSTAR( FILE* f )
+bool NETLIST_EXPORT_TOOL::WriteNetListCADSTAR( FILE* f )
 {
+    int ret = 0;
     wxString StartCmpDesc = StartLine + wxT( "ADD_COM" );
     wxString msg;
     wxString footprint;
@@ -1862,11 +1878,11 @@ void EXPORT_HELP::WriteNetListCADSTAR( FILE* f )
     SCH_COMPONENT* Component;
     wxString Title = wxGetApp().GetAppName() + wxT( " " ) + GetBuildVersion();
 
-    fprintf( f, "%sHEA\n", TO_UTF8( StartLine ) );
-    fprintf( f, "%sTIM %s\n", TO_UTF8( StartLine ), TO_UTF8( DateAndTime() ) );
-    fprintf( f, "%sAPP ", TO_UTF8( StartLine ) );
-    fprintf( f, "\"%s\"\n", TO_UTF8( Title ) );
-    fprintf( f, "\n" );
+    ret |= fprintf( f, "%sHEA\n", TO_UTF8( StartLine ) );
+    ret |= fprintf( f, "%sTIM %s\n", TO_UTF8( StartLine ), TO_UTF8( DateAndTime() ) );
+    ret |= fprintf( f, "%sAPP ", TO_UTF8( StartLine ) );
+    ret |= fprintf( f, "\"%s\"\n", TO_UTF8( Title ) );
+    ret |= fprintf( f, "\n" );
 
     // Prepare list of nets generation
     for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ )
@@ -1898,28 +1914,32 @@ void EXPORT_HELP::WriteNetListCADSTAR( FILE* f )
             */
 
             msg = Component->GetRef( sheet );
-            fprintf( f, "%s     ", TO_UTF8( StartCmpDesc ) );
-            fprintf( f, "%s", TO_UTF8( msg ) );
+            ret |= fprintf( f, "%s     ", TO_UTF8( StartCmpDesc ) );
+            ret |= fprintf( f, "%s", TO_UTF8( msg ) );
 
             msg = Component->GetField( VALUE )->m_Text;
             msg.Replace( wxT( " " ), wxT( "_" ) );
-            fprintf( f, "     \"%s\"", TO_UTF8( msg ) );
-            fprintf( f, "\n" );
+            ret |= fprintf( f, "     \"%s\"", TO_UTF8( msg ) );
+            ret |= fprintf( f, "\n" );
         }
     }
 
-    fprintf( f, "\n" );
+    ret |= fprintf( f, "\n" );
 
     m_SortedComponentPinList.clear();
 
-    writeListOfNetsCADSTAR( f, g_NetObjectslist );
+    if( ! writeListOfNetsCADSTAR( f, g_NetObjectslist ) )
+        ret = -1;   // set error
 
-    fprintf( f, "\n%sEND\n", TO_UTF8( StartLine ) );
+    ret |= fprintf( f, "\n%sEND\n", TO_UTF8( StartLine ) );
+
+    return ret >= 0;
 }
 
 
-void EXPORT_HELP::writeListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
+bool NETLIST_EXPORT_TOOL::writeListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
 {
+    int ret = 0;
     wxString InitNetDesc  = StartLine + wxT( "ADD_TER" );
     wxString StartNetDesc = StartLine + wxT( "TER" );
     wxString netcodeName, InitNetDescLine;
@@ -1991,21 +2011,23 @@ void EXPORT_HELP::writeListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjects
             break;
 
         case 1:
-            fprintf( f, "%s\n", TO_UTF8( InitNetDescLine ) );
-            fprintf( f, "%s       %s   %.4s\n",
-                     TO_UTF8( StartNetDesc ),
-                     TO_UTF8( refstr ),
-                     (char*) &aObjectsList[ii]->m_PinNum );
+            ret |= fprintf( f, "%s\n", TO_UTF8( InitNetDescLine ) );
+            ret |= fprintf( f, "%s       %s   %.4s\n",
+                            TO_UTF8( StartNetDesc ),
+                            TO_UTF8( refstr ),
+                            (char*) &aObjectsList[ii]->m_PinNum );
             print_ter++;
             break;
 
         default:
-            fprintf( f, "            %s   %.4s\n",
-                     TO_UTF8( refstr ),
-                     (char*) &aObjectsList[ii]->m_PinNum );
+            ret |= fprintf( f, "            %s   %.4s\n",
+                            TO_UTF8( refstr ),
+                            (char*) &aObjectsList[ii]->m_PinNum );
             break;
         }
 
         aObjectsList[ii]->m_Flag = 1;
     }
+
+    return ret >= 0;
 }
diff --git a/eeschema/netlist_control.cpp b/eeschema/netlist_control.cpp
index f0b347449d..0f38f7f9d8 100644
--- a/eeschema/netlist_control.cpp
+++ b/eeschema/netlist_control.cpp
@@ -126,6 +126,7 @@ NETLIST_PAGE_DIALOG::NETLIST_PAGE_DIALOG( wxNotebook*     parent,
     m_IsCurrentFormat   = NULL;
     m_AddSubPrefix = NULL;
     m_ButtonCancel = NULL;
+    m_NetOption = NULL;
 
     parent->AddPage( this, title, selected );
 
@@ -153,7 +154,18 @@ NETLIST_PAGE_DIALOG::NETLIST_PAGE_DIALOG( wxNotebook*     parent,
         m_IsCurrentFormat->SetValue( selected );
     }
 
-    /* Create the buttons: Create Neltist or browse Plugin and Cancel
+    if( id_NetType == NET_TYPE_PCBNEW )
+    {
+        wxString netlist_opt[2] = { _( "Pcbnew Format" ), _( "Advanced Format" ) };
+        m_NetOption = new wxRadioBox( this, -1, _( "Netlist Options:" ),
+                                      wxDefaultPosition, wxDefaultSize,
+                                      2, netlist_opt, 1,
+                                      wxRA_SPECIFY_COLS );
+        m_LeftBoxSizer->Add( m_NetOption, 0, wxGROW | wxALL, 5 );
+    }
+
+
+    /* Create the buttons: Create Netlist or browse Plugin and Cancel
      * and a third button for plugins : Remove or Ok button */
     if( idCreateFile )
     {
@@ -275,15 +287,15 @@ void NETLIST_DIALOG::InstallPageSpice()
 
 
     wxString netlist_opt[2] = { _( "Use Net Names" ), _( "Use Net Numbers" ) };
-    m_UseNetNamesInNetlist = new wxRadioBox( page, -1, _( "Netlist Options:" ),
-                                             wxDefaultPosition, wxDefaultSize,
-                                             2, netlist_opt, 1,
-                                             wxRA_SPECIFY_COLS );
+    page->m_NetOption = new wxRadioBox( page, -1, _( "Netlist Options:" ),
+                                        wxDefaultPosition, wxDefaultSize,
+                                        2, netlist_opt, 1,
+                                        wxRA_SPECIFY_COLS );
 
     if( !g_OptNetListUseNames )
-        m_UseNetNamesInNetlist->SetSelection( 1 );
+        page->m_NetOption->SetSelection( 1 );
 
-    page->m_LeftBoxSizer->Add( m_UseNetNamesInNetlist, 0, wxGROW | wxALL, 5 );
+    page->m_LeftBoxSizer->Add( page->m_NetOption, 0, wxGROW | wxALL, 5 );
 
     page->m_LowBoxSizer->Add( new wxStaticText( page, -1, _( "Simulator command:" ) ), 0,
                               wxGROW | wxLEFT | wxRIGHT | wxTOP | wxADJUST_MINSIZE, 5 );
@@ -496,7 +508,7 @@ void NETLIST_DIALOG::NetlistUpdateOpt()
 
     g_OptNetListUseNames = true; // Used for pspice, gnucap
 
-    if( m_UseNetNamesInNetlist->GetSelection() == 1 )
+    if( m_PanelNetType[PANELSPICE]->m_NetOption->GetSelection() == 1 )
         g_OptNetListUseNames = 	false;
 }
 
@@ -519,6 +531,8 @@ void NETLIST_DIALOG::GenNetlist( wxCommandEvent& event )
     NETLIST_PAGE_DIALOG* CurrPage;
     CurrPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
 
+    unsigned netlist_opt = 0;
+
     /* Calculate the netlist filename */
     fn = g_RootSheet->GetScreen()->GetFileName();
 
@@ -527,6 +541,11 @@ void NETLIST_DIALOG::GenNetlist( wxCommandEvent& event )
     case NET_TYPE_SPICE:
         fileExt = wxT( "cir" );
         fileWildcard = _( "SPICE netlist file (.cir)|*.cir" );
+        // Set spice netlist options:
+        if( g_OptNetListUseNames )
+            netlist_opt |= NET_USE_NETNAMES;
+        if( CurrPage->m_AddSubPrefix->GetValue() )
+            netlist_opt |= NET_USE_X_PREFIX;
         break;
 
     case NET_TYPE_CADSTAR:
@@ -535,13 +554,19 @@ void NETLIST_DIALOG::GenNetlist( wxCommandEvent& event )
         break;
 
     case NET_TYPE_PCBNEW:
+        if( CurrPage->m_NetOption->GetSelection() != 0 )
+            netlist_opt = NET_PCBNEW_USE_NEW_FORMAT;
+        fileExt = NetlistFileExtension;
+        fileWildcard = NetlistFileWildcard;
+        break;
+
     case NET_TYPE_ORCADPCB2:
         fileExt = NetlistFileExtension;
         fileWildcard = NetlistFileWildcard;
         break;
 
     default:    // custom, NET_TYPE_CUSTOM1 and greater
-        fileExt = wxEmptyString;    // wxT( "" );
+        fileExt = wxEmptyString;
         fileWildcard = AllFilesWildcard;
         title.Printf( _( "%s Export" ), CurrPage->m_TitleStringCtrl->GetValue().GetData() );
     }
@@ -562,12 +587,7 @@ void NETLIST_DIALOG::GenNetlist( wxCommandEvent& event )
     else
         m_Parent->SetNetListerCommand( wxEmptyString );
 
-    bool addSubPrefix = false;
-    if( CurrPage->m_AddSubPrefix )
-        addSubPrefix = CurrPage->m_AddSubPrefix->GetValue();
-
-    m_Parent->CreateNetlist( CurrPage->m_IdNetType, dlg.GetPath(), g_OptNetListUseNames,
-                             addSubPrefix );
+    m_Parent->CreateNetlist( CurrPage->m_IdNetType, dlg.GetPath(), netlist_opt );
 
     WriteCurrentNetlistSetup();
 
@@ -575,22 +595,17 @@ void NETLIST_DIALOG::GenNetlist( wxCommandEvent& event )
 }
 
 
-/**
- * Function CreateNetlist
- * Create a netlist file:
- *  build netlist info
- *  test issues
- *  create file
- * @param aFormat = netlist format (NET_TYPE_PCBNEW ...)
- * @param aFullFileName = full netlist file name
- * @param aUse_netnames = bool. if true, use net names from labels in schematic
- *                              if false, use net numbers (net codes)
- *   bool aUse_netnames is used only for Spice netlist
- * @return true if success.
+/* Function CreateNetlist
+ *  > test for some issues (missing or duplicate references and sheet names)
+ *  > build netlist info
+ *  > create the netlist file
+ * param aFormat = netlist format (NET_TYPE_PCBNEW ...)
+ * param aFullFileName = full netlist file name
+ * param aNetlistOptions = netlist options using OR'ed bits (see WriteNetListFile).
+ * return true if success.
  */
 bool SCH_EDIT_FRAME::CreateNetlist( int aFormat, const wxString& aFullFileName,
-                                    bool aUse_netnames,
-                                    bool aUsePrefix )
+                                    unsigned aNetlistOptions )
 {
     SCH_SHEET_LIST sheets;
     sheets.AnnotatePowerSymbols();
@@ -622,7 +637,7 @@ Do you want to annotate schematic?" ) ) )
     screens.SchematicCleanUp();
 
     BuildNetListBase();
-    bool success = WriteNetListFile( aFormat, aFullFileName, g_OptNetListUseNames, aUsePrefix );
+    bool success = WriteNetListFile( aFormat, aFullFileName, aNetlistOptions );
 
     return success;
 }
@@ -651,17 +666,20 @@ void NETLIST_DIALOG::RunSimulator( wxCommandEvent& event )
     fn.SetExt( wxT( "cir" ) );
     CommandLine += wxT( " \"" ) + fn.GetFullPath() + wxT( "\"" );
 
-    g_OptNetListUseNames = m_UseNetNamesInNetlist->GetSelection() == 0;
     NETLIST_PAGE_DIALOG* CurrPage;
     CurrPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
+    g_OptNetListUseNames = CurrPage->m_NetOption->GetSelection() == 0;
 
-    bool addSubPrefix = false;
+    // Set spice netlist options:
+    unsigned netlist_opt = 0;
 
-    if( CurrPage->m_AddSubPrefix )
-        addSubPrefix = CurrPage->m_AddSubPrefix->GetValue();
+    if( g_OptNetListUseNames )
+        netlist_opt |= NET_USE_NETNAMES;
+    if( CurrPage->m_AddSubPrefix && CurrPage->m_AddSubPrefix->GetValue() )
+        netlist_opt |= NET_USE_X_PREFIX;
 
     if( ! m_Parent->CreateNetlist( CurrPage->m_IdNetType, fn.GetFullPath(),
-                                   g_OptNetListUseNames,addSubPrefix ) )
+                                   netlist_opt ) )
         return;
 
     ExecuteFile( this, ExecFile, CommandLine );
diff --git a/eeschema/netlist_control.h b/eeschema/netlist_control.h
index d3b4f17ee3..2c5c2627f5 100644
--- a/eeschema/netlist_control.h
+++ b/eeschema/netlist_control.h
@@ -7,8 +7,6 @@
 #ifndef _NETLIST_CONTROL_H_
 #define _NETLIST_CONTROL_H_
 
-class WinEDA_EnterText;
-
 
 /* Event id for notebook page buttons: */
 enum id_netlist {
@@ -55,7 +53,9 @@ public:
     wxBoxSizer*       m_RightBoxSizer;
     wxBoxSizer*       m_RightOptionsBoxSizer;
     wxBoxSizer*       m_LowBoxSizer;
+    wxRadioBox*       m_NetOption;
 
+public:
     /** Contructor to create a setup page for one netlist format.
      * Used in Netlist format Dialog box creation
      * @param parent = wxNotebook * parent
@@ -75,7 +75,7 @@ public:
 
 #define CUSTOMPANEL_COUNTMAX 8  // Max number of netlist plugins
 
-/* Id to select netlist type */
+// Id to select netlist type
 enum  TypeNetForm {
     NET_TYPE_UNINIT = 0,
     NET_TYPE_PCBNEW,
@@ -90,6 +90,12 @@ enum  TypeNetForm {
     NET_TYPE_CUSTOM_MAX = NET_TYPE_CUSTOM1 + CUSTOMPANEL_COUNTMAX - 1
 };
 
+// Options for Spice netlist generation (OR'ed bits
+enum netlistOptions {
+    NET_USE_NETNAMES = 1,   // for Spice netlist : use netnames instead of numbers
+    NET_USE_X_PREFIX = 2,   // for Spice netlist : change "U" and "IC" refernce prefix to "X"
+    NET_PCBNEW_USE_NEW_FORMAT = 1,  // For Pcbnew use the new format (S expression and SWEET)
+};
 
 /* Dialog frame for creating netlists */
 class NETLIST_DIALOG : public wxDialog
@@ -98,7 +104,6 @@ public:
     SCH_EDIT_FRAME*   m_Parent;
     wxNotebook*       m_NoteBook;
     NETLIST_PAGE_DIALOG* m_PanelNetType[4 + CUSTOMPANEL_COUNTMAX];
-    wxRadioBox*       m_UseNetNamesInNetlist;
 
 public:
 
diff --git a/include/wxEeschemaStruct.h b/include/wxEeschemaStruct.h
index 3195dd27cb..bc69b0eb7c 100644
--- a/include/wxEeschemaStruct.h
+++ b/include/wxEeschemaStruct.h
@@ -445,37 +445,43 @@ public:
 
     /**
      * Function CreateNetlist
-     * Create a netlist file:
-     *  build netlist info
-     *  test issues
-     *  create file
+     * <ul>
+     * <li> test for some issues (missing or duplicate references and sheet names)
+     * <li> build netlist info
+     * <li> create the netlist file (different formats)
+     * </ul>
      * @param aFormat = netlist format (NET_TYPE_PCBNEW ...)
      * @param aFullFileName = full netlist file name
-     * @param aUse_netnames = bool. if true, use net names from labels in schematic
-     *                              if false, use net numbers (net codes)
-     *   bool aUse_netnames is used only for Spice netlist
-     * @param aUsePrefix Prefix reference designator with an 'X' for spice output.
+     * @param aNetlistOptions = netlist options using OR'ed bits.
+     * <p>
+     * For SPICE netlist only:
+     *      if NET_USE_NETNAMES is set, use net names from labels in schematic
+     *                             else use net numbers (net codes)
+     *      if NET_USE_X_PREFIX is set : change "U" and "IC" refernce prefix to "X"
+     * </p>
      * @return true if success.
      */
     bool CreateNetlist( int             aFormat,
                         const wxString& aFullFileName,
-                        bool            aUse_netnames,
-                        bool            aUsePrefix );
+                        unsigned        aNetlistOptions );
 
     /**
      * Function  WriteNetListFile
      * Create the netlist file. Netlist info must be existing
      * @param aFormat = netlist format (NET_TYPE_PCBNEW ...)
      * @param aFullFileName = full netlist file name
-     * @param aUse_netnames = bool. if true, use net names from labels in schematic
-     *                              if false, use net numbers (net codes)
-     *   bool aUse_netnames is used only for Spice netlist
+     * @param aNetlistOptions = netlist options using OR'ed bits.
+     * <p>
+     * For SPICE netlist only:
+     *      if NET_USE_NETNAMES is set, use net names from labels in schematic
+     *                             else use net numbers (net codes)
+     *      if NET_USE_X_PREFIX is set : change "U" and "IC" refernce prefix to "X"
+     * </p>
      * @return true if success.
      */
     bool WriteNetListFile( int             aFormat,
                            const wxString& aFullFileName,
-                           bool            aUse_netnames,
-                           bool            aUsePrefix );
+                           unsigned        aNetlistOptions );
 
     /**
      * Function DeleteAnnotation
diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h
index 0721cff94f..9e39644f10 100644
--- a/include/wxPcbStruct.h
+++ b/include/wxPcbStruct.h
@@ -1336,12 +1336,11 @@ public:
     /**
      * Function RemoveMisConnectedTracks
      * finds all track segments which are mis-connected (to more than one net).
-     * When such a bad segment is found, mark it as needing to be removed.
-     * and remove all tracks having at least one flagged segment.
-     * @param aDC = the current device context (can be NULL)
+     * When such a bad segment is found, it is flagged to be removed.
+     * All tracks having at least one flagged segment are removed.
      * @return true if any change is made
      */
-    bool RemoveMisConnectedTracks( wxDC* aDC );
+    bool RemoveMisConnectedTracks();
 
 
     // Autoplacement:
diff --git a/license_for_documentation.txt b/license_for_documentation.txt
new file mode 100644
index 0000000000..23750e5729
--- /dev/null
+++ b/license_for_documentation.txt
@@ -0,0 +1,61 @@
+                KiCad Free Documentation Licence
+                ================================
+
+  Copyright (c) jean-pierre Charras
+  Copyright (C) KiCad Developers
+
+  Everyone is permitted to copy and distribute verbatim copies
+  of this licence document, but changing it is not allowed.
+
+                   KICAD FREE DOCUMENTATION LICENCE
+     TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  1. Permission is granted to make and distribute verbatim copies of this
+  manual or piece of documentation provided any copyright notice and this
+  permission notice are preserved on all copies.
+
+  2. Permission is granted to process this file or document through a
+  document processing system and, at your option and the option of any third
+  party, print the results, provided a printed document carries a copying
+  permission notice identical to this one.
+
+  3. Permission is granted to copy and distribute modified versions of this
+  manual or piece of documentation under the conditions for verbatim
+  copying, provided also that any sections describing licensing conditions
+  for this manual, such as, in particular, the GNU General Public Licence,
+  the GNU Library General Public Licence, and any wxWindows Licence are
+  included exactly as in the original, and provided that the entire
+  resulting derived work is distributed under the terms of a permission
+  notice identical to this one.
+
+  4. Permission is granted to copy and distribute translations of this
+  manual or piece of documentation into another language, under the above
+  conditions for modified versions, except that sections related to
+  licensing, including this paragraph, may also be included in translations
+  approved by the copyright holders of the respective licence documents in
+  addition to the original French or English.
+
+                            WARRANTY DISCLAIMER
+
+  5. BECAUSE THIS MANUAL OR PIECE OF DOCUMENTATION IS LICENSED FREE OF CHARGE,
+  THERE IS NO WARRANTY FOR IT, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
+  PARTIES PROVIDE THIS MANUAL OR PIECE OF DOCUMENTATION "AS IS" WITHOUT
+  WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+  PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF
+  THE MANUAL OR PIECE OF DOCUMENTATION IS WITH YOU.  SHOULD THE MANUAL OR
+  PIECE OF DOCUMENTATION PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+  NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  6. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
+  ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+  REDISTRIBUTE THE MANUAL OR PIECE OF DOCUMENTATION AS PERMITTED ABOVE, BE
+  LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+  CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+  MANUAL OR PIECE OF DOCUMENTATION (INCLUDING BUT NOT LIMITED TO LOSS OF
+  DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+  PARTIES OR A FAILURE OF A PROGRAM BASED ON THE MANUAL OR PIECE OF
+  DOCUMENTATION TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR
+  OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt
index 6b9cfef883..8e4eb0693e 100644
--- a/pcbnew/CMakeLists.txt
+++ b/pcbnew/CMakeLists.txt
@@ -151,6 +151,8 @@ set(PCBNEW_SRCS
     muonde.cpp
     muwave_command.cpp
     netlist.cpp
+    netlist_reader_firstformat.cpp
+    netlist_reader_kicad.cpp
     onleftclick.cpp
     onrightclick.cpp
     pcb_plot_params.cpp
diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp
index 320b5448fa..0f1926b34f 100644
--- a/pcbnew/clean.cpp
+++ b/pcbnew/clean.cpp
@@ -686,8 +686,12 @@ TRACK* MergeColinearSegmentIfPossible( BOARD* aPcb, TRACK* aTrackRef, TRACK* aCa
 }
 
 
-bool PCB_EDIT_FRAME::RemoveMisConnectedTracks( wxDC* aDC )
+bool PCB_EDIT_FRAME::RemoveMisConnectedTracks()
 {
+     /* finds all track segments which are mis-connected (to more than one net).
+     * When such a bad segment is found, it is flagged to be removed.
+     * All tracks having at least one flagged segment are removed.
+     */
     TRACK*          segment;
     TRACK*          other;
     TRACK*          next;
@@ -735,14 +739,14 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks( wxDC* aDC )
         if( net_code_e < 0 )
             continue;           // the "end" of segment is not connected
 
-        // Netcodes do not agree, so mark the segment as needed to be removed
+        // Netcodes do not agree, so mark the segment as "to be removed"
         if( net_code_s != net_code_e )
         {
             segment->SetState( FLAG0, ON );
         }
     }
 
-    // Remove flagged segments
+    // Remove tracks having a flagged segment
     for( segment = GetBoard()->m_Track;  segment;  segment = next )
     {
         next = (TRACK*) segment->Next();
@@ -752,9 +756,11 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks( wxDC* aDC )
             segment->SetState( FLAG0, OFF );
             isModified = true;
             GetBoard()->m_Status_Pcb = 0;
-            Remove_One_Track( aDC, segment );
+            Remove_One_Track( NULL, segment );
 
-            // the current segment could be deleted, so restart to the beginning
+            // the current segment is deleted,
+            // we do not know the next "not yet tested" segment,
+            // so restart to the beginning
             next = GetBoard()->m_Track;
         }
     }
diff --git a/pcbnew/netlist.cpp b/pcbnew/netlist.cpp
index 9cd7d475a5..d7ccdb184b 100644
--- a/pcbnew/netlist.cpp
+++ b/pcbnew/netlist.cpp
@@ -1,21 +1,44 @@
 /**
  * @file pcbnew/netlist.cpp
  */
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2011 Jean-Pierre Charras.
+ * Copyright (C) 1992-2011 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
+ */
 
 /*
- *  Functions to read a netlist. They are:
+ *  Functions to read a netlist:
  *  - Load new footprints and initialize net info
  *  - Test for missing or extra footprints
  *  - Recalculate full connectivity info
  *
  *  Important remark:
- *  When reading a netlist Pcbnew must identify existing footprints (link
+ *  When reading a netlist, Pcbnew must identify existing footprints (link
  * between existing footprints an components in netlist)
- *  This identification can be from 2 fields:
+ *  This identification can be made from 2 fields:
  *      - The reference (U2, R5 ..): this is the normal mode
- *      - The Time Stamp (Signature Temporarily), useful after a full schematic
- * reannotation because references can be changed for the same schematic.
- * So when reading a netlist ReadPcbNetlist() can use references or time stamps
+ *      - The Time Stamp : useful after a full schematic
+ * reannotation because references can be changed for the component linked to its footprint.
+ * So when reading a netlist, ReadPcbNetlist() can use references or time stamps
  * to identify footprints on board and the corresponding component in schematic.
  *  If we want to fully reannotate a schematic this sequence must be used
  *   1 - SAVE your board !!!
@@ -26,6 +49,7 @@
  * (that reinit the new references)
  */
 
+
 #include <algorithm>
 
 #include <fctsys.h>
@@ -40,157 +64,10 @@
 
 #include <class_board.h>
 #include <class_module.h>
-
 #include <pcbnew.h>
 #include <dialog_netlist.h>
 
-
-// constants used by ReadNetlistModuleDescr():
-#define TESTONLY   true
-#define READMODULE false
-
-
-/*
- * Helper class, to store new footprints info found in netlist.
- * New footprints are footprints relative to new components found in netlist
- */
-class MODULE_INFO
-{
-public:
-    wxString m_LibName;
-    wxString m_CmpName;
-    wxString m_TimeStampPath;
-
-public: MODULE_INFO( const wxString& libname,
-                     const wxString& cmpname,
-                     const wxString& timestamp_path )
-    {
-        m_LibName = libname;
-        m_CmpName = cmpname;
-        m_TimeStampPath = timestamp_path;
-    }
-
-    ~MODULE_INFO() { };
-};
-
-
-/*
- * Helper class, to read a netlist.
- */
-class NETLIST_READER
-{
-private:
-    PCB_EDIT_FRAME*            m_pcbframe;          // the main Pcbnew frame
-    wxTextCtrl*                m_messageWindow;     // a textctrl to show messages (can be NULL)
-    wxString                   m_netlistFullName;   // The full netlist filename
-    wxString                   m_cmplistFullName;   // The full component/footprint association filename
-    MODULE*                    m_currModule;        // The footprint currently being read in netlist
-    std::vector <MODULE_INFO*> m_newModulesList;    // The list of new footprints,
-                                                    // found in netlist, but not on board
-                                                    // (must be loaded from libraries)
-    bool m_useCmpFile;                              // true to use .cmp files as component/footprint file link
-                                                    // false to use netlist only to know component/footprint link
-
-public:
-    bool m_UseTimeStamp;            // Set to true to identify footprints by time stamp
-                                    // false to use schematic reference
-    bool m_ChangeFootprints;        // Set to true to change existing footprints to new ones
-                                    // when netlist gives a different footprint name
-
-public:
-    NETLIST_READER( PCB_EDIT_FRAME* aFrame, wxTextCtrl* aMessageWindow = NULL )
-    {
-        m_pcbframe = aFrame;
-        m_messageWindow    = aMessageWindow;
-        m_UseTimeStamp     = false;
-        m_ChangeFootprints = false;
-        m_useCmpFile = true;
-    }
-
-    ~NETLIST_READER()
-    {
-        // Free new modules list:
-        for( unsigned ii = 0; ii < m_newModulesList.size(); ii++ )
-            delete m_newModulesList[ii];
-
-        m_newModulesList.clear();
-    }
-
-    /**
-     * Function ReadNetList
-     * The main function to read a netlist, and update the board
-     * @param aFile = the already opened file (will be closed by ReadNetList)
-     * @param aNetlistFileName = the netlist full file name (*.net file)
-     * @param aCmplistFileName = the auxiliary component full file name (*.cmp file)
-     * If the aCmplistFileName file is not given or not found,
-     * the netlist is used to know the component/footprint link.
-     */
-    bool ReadNetList( FILE* aFile, const wxString& aNetlistFileName,
-                      const wxString& aCmplistFileName );
-
-    /**
-     * Function BuildComponentsListFromNetlist
-     * Fill aBufName with component references read from the netlist.
-     * @param aNetlistFilename = netlist full file name
-     * @param aBufName = wxArrayString to fill with component references
-     * @return the component count, or -1 if netlist file cannot opened
-     */
-    int  BuildComponentsListFromNetlist( const wxString& aNetlistFilename,
-                                         wxArrayString&  aBufName );
-
-    /**
-     * function RemoveExtraFootprints
-     * Remove (delete) not locked footprints found on board, but not in netlist
-     * @param aNetlistFileName = the netlist full file name (*.net file)
-     */
-    void    RemoveExtraFootprints( const wxString& aNetlistFileName );
-
-private:
-
-    /**
-     * Function SetPadNetName
-     *  Update a pad netname using the current footprint
-     *  from the netlist (line format: ( \<pad number\> \<net name\> ) )
-     *  @param aText = current line read from netlist
-     */
-    bool    SetPadNetName( char* aText );
-
-    /**
-     * Function ReadNetlistModuleDescr
-     * Read the full description of a footprint, from the netlist
-     * and update the corresponding module.
-     * @param aTstOnly bool to switch between 2 modes:
-     *      aTstOnly = false:
-     *          if the module does not exist, it is added to m_newModulesList
-     *      aTstOnly = true:
-     *          if the module does not exist, it is loaded and added to the board module list
-     * @param  aText contains the first line of description
-     * This function uses m_useFichCmp as a flag to know the footprint name:
-     *      If true: component file *.cmp is used
-     *      If false: the netlist only is used
-     *      This flag is reset to false if the .cmp file is not found
-     */
-    MODULE* ReadNetlistModuleDescr( char* aText, bool aTstOnly );
-
-    /**
-     * Function loadNewModules
-     * Load from libraries new modules found in netlist and add them to the current Board.
-     * @return false if a footprint is not found, true if all footprints are loaded
-     */
-    bool    loadNewModules();
-
-    /**
-     * function readModuleComponentLinkfile
-     * read the *.cmp file ( filename in m_cmplistFullName )
-     * giving the equivalence between footprint names and components
-     * to find the footprint name corresponding to aCmpIdent
-     * @return true and the module name in aFootprintName, false if not found
-     *
-     * @param aCmpIdent = component identification: schematic reference or time stamp
-     * @param aFootprintName the footprint name corresponding to the component identification
-     */
-    bool    readModuleComponentLinkfile( const wxString* aCmpIdent, wxString& aFootprintName );
-};
+#include <netlist_reader.h>
 
 
 /**
@@ -200,7 +77,7 @@ private:
 static FILE* OpenNetlistFile( const wxString& aFullFileName )
 {
     if( aFullFileName.IsEmpty() )
-        return false;  // No filename: exit
+        return NULL;  // No filename: exit
 
     FILE* file = wxFopen( aFullFileName, wxT( "rt" ) );
 
@@ -215,16 +92,6 @@ static FILE* OpenNetlistFile( const wxString& aFullFileName )
 }
 
 
-/* Function to sort the footprint list.
- * the given list is sorted by name
- */
-static bool SortByLibName( MODULE_INFO* ref, MODULE_INFO* cmp )
-{
-    int ii = ref->m_LibName.CmpNoCase( cmp->m_LibName );
-
-    return ii > 0;
-}
-
 
 /**
  * Function ReadPcbNetlist
@@ -261,18 +128,27 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename,
 
     SetLastNetListRead( aNetlistFullFilename );
 
+    bool useCmpfile = ! aCmpFullFileName.IsEmpty() && wxFileExists( aCmpFullFileName );
+
     if( aMessageWindow )
     {
         wxString msg;
         msg.Printf( _( "Reading Netlist \"%s\"" ), GetChars( aNetlistFullFilename ) );
         aMessageWindow->AppendText( msg + wxT( "\n" ) );
 
-        if( ! aCmpFullFileName.IsEmpty() )
+        if( useCmpfile )
         {
             msg.Printf( _( "Using component/footprint link file \"%s\"" ),
                         GetChars( aCmpFullFileName ) );
             aMessageWindow->AppendText( msg + wxT( "\n" ) );
         }
+
+        if( aSelect_By_Timestamp )
+        {
+            msg.Printf( _( "Using time stamp selection" ),
+                        GetChars( aCmpFullFileName ) );
+            aMessageWindow->AppendText( msg + wxT( "\n" ) );
+        }
      }
 
     // Clear undo and redo lists to avoid inconsistencies between lists
@@ -289,12 +165,17 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename,
     NETLIST_READER netList_Reader( this, aMessageWindow );
     netList_Reader.m_UseTimeStamp     = aSelect_By_Timestamp;
     netList_Reader.m_ChangeFootprints = aChangeFootprint;
-    netList_Reader.ReadNetList( netfile, aNetlistFullFilename, aCmpFullFileName );
+    netList_Reader.m_UseCmpFile = useCmpfile;
+    netList_Reader.SetFilesnames( aNetlistFullFilename, aCmpFullFileName );
+
+    netList_Reader.ReadNetList( netfile );
 
     // Delete footprints not found in netlist:
     if( aDeleteExtraFootprints )
     {
-        netList_Reader.RemoveExtraFootprints( aNetlistFullFilename );
+        if( IsOK( NULL,
+            _( "Ok to delete not locked footprints not found in netlist?" ) ) )
+            netList_Reader.RemoveExtraFootprints();
     }
 
     // Rebuild the board connectivity:
@@ -303,8 +184,8 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename,
     if( aDeleteBadTracks && GetBoard()->m_Track )
     {
         // Remove erroneous tracks
-        RemoveMisConnectedTracks( NULL );
-        Compile_Ratsnest( NULL, true );
+        if( RemoveMisConnectedTracks() )
+            Compile_Ratsnest( NULL, true );
     }
 
     GetBoard()->DisplayInfo( this );
@@ -313,434 +194,237 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename,
     return true;
 }
 
+/*
+ * Function ReadNetList
+ * The main function to detect the netlist format,and run the right netlist reader
+ * aFile = the already opened file (will be closed by the netlist reader)
+ */
+bool NETLIST_READER::ReadNetList( FILE* aFile )
+{
+    // Try to determine the netlist type:
+    bool new_fmt = true;
+    std::string header( "(export" );
+    for( unsigned ii = 0; ii < header.size(); ii++ )
+    {
+        int data;
+        do
+        {
+            data = fgetc( aFile );
+        } while ( ( data == ' ' ) &&( EOF != data ) ) ;
+
+        if( (int)header[ii] == data )
+            continue;
+        new_fmt = false;
+        break;
+    }
+
+    rewind( aFile );
+
+    bool success;
+    if( new_fmt )
+        success = ReadKicadNetList( aFile );
+    else
+        success = ReadOldFmtdNetList( aFile );
+
+    return success;
+}
+
+bool NETLIST_READER::InitializeModules()
+{
+    if( m_UseCmpFile )  // Try to get footprint name from .cmp file
+    {
+        readModuleComponentLinkfile();
+    }
+
+    for( unsigned ii = 0; ii < m_modulesInNetlist.size(); ii++ )
+    {
+        MODULE_INFO* currmod_info = m_modulesInNetlist[ii];
+        // Test if module is already loaded.
+        wxString * idMod = m_UseTimeStamp?
+                           &currmod_info->m_TimeStamp : &currmod_info->m_Reference;
+
+        MODULE* module = FindModule( *idMod );
+        if( module == NULL )   // not existing, load it
+        {
+            m_newModulesList.push_back( currmod_info );
+        }
+    }
+
+    bool success = loadNewModules();
+
+    // Update modules fields
+    for( unsigned ii = 0; ii < m_modulesInNetlist.size(); ii++ )
+    {
+        MODULE_INFO* currmod_info =  m_modulesInNetlist[ii];
+        // Test if module is already loaded.
+        wxString * idMod = m_UseTimeStamp?
+                              &currmod_info->m_TimeStamp : &currmod_info->m_Reference;
+
+        MODULE* module = FindModule( *idMod );
+        if( module )
+        {
+             // Update current module ( reference, value and "Time Stamp")
+            module->m_Reference->m_Text = currmod_info->m_Reference;
+            module->m_Value->m_Text     = currmod_info->m_Value;
+            module->SetPath( currmod_info->m_TimeStamp );
+        }
+        else   // not existing
+        {
+        }
+    }
+
+    // clear pads netnames
+    for( MODULE* module = m_pcbframe->GetBoard()->m_Modules; module; module = module->Next() )
+    {
+        for( D_PAD* pad = module->m_Pads; pad; pad = pad->Next() )
+            pad->SetNetname( wxEmptyString );
+    }
+
+    return success;
+}
+
+void NETLIST_READER::TestFootprintsMatchingAndExchange()
+{
+    for( MODULE* module = m_pcbframe->GetBoard()->m_Modules; module; module = module->Next() )
+    {
+        // Search for the corresponding module info
+        MODULE_INFO * mod_info = NULL;
+        for( unsigned ii = 0; ii < m_modulesInNetlist.size(); ii++ )
+        {
+            MODULE_INFO * candidate =  m_modulesInNetlist[ii];
+            // Test if mod_info matches the current module:
+            if( candidate->m_Reference.CmpNoCase( module->GetReference() ) == 0 )
+            {
+                mod_info = candidate;
+                break;
+            }
+        }
+        if( mod_info == NULL )   // not found in netlist
+             continue;
+
+        if( module->GetLibRef().CmpNoCase( mod_info->m_Footprint ) != 0 )
+        {
+            if( m_ChangeFootprints )   // footprint exchange allowed.
+            {
+                MODULE* newModule = m_pcbframe->GetModuleLibrary( wxEmptyString,
+                                                                  mod_info->m_Footprint,
+                                                                  false );
+
+                if( newModule )
+                {
+                    // Change old module to the new module (and delete the old one)
+                    m_pcbframe->Exchange_Module( module, newModule, NULL );
+                    module = newModule;
+                }
+                else if( m_messageWindow )
+                {
+                wxString msg;
+                msg.Printf( _( "Component \"%s\": module [%s] not found\n" ),
+                            GetChars( mod_info->m_Reference ),
+                            GetChars( mod_info->m_Footprint ) );
+
+                m_messageWindow->AppendText( msg );
+                }
+            }
+            else if( m_messageWindow )
+            {
+                wxString msg;
+                msg.Printf( _( "Component \"%s\": Mismatch! module is [%s] and netlist said [%s]\n" ),
+                            GetChars( mod_info->m_Reference ),
+                            GetChars( module->GetLibRef() ),
+                            GetChars( mod_info->m_Footprint ) );
+
+                m_messageWindow->AppendText( msg );
+            }
+        }
+    }
+}
+
+/**
+ * Function SetPadNetName
+ *  Update a pad netname
+ *  @param aModule = module reference
+ *  @param aPadname = pad name (pad num)
+ *  @param aNetname = new net name of the pad
+ *  @return a pointer to the pad or NULL if the pad is not found
+ */
+D_PAD* NETLIST_READER::SetPadNetName( const wxString & aModule, const wxString & aPadname,
+                      const wxString & aNetname )
+{
+    MODULE* module = m_pcbframe->GetBoard()->FindModuleByReference( aModule );
+    if( module )
+    {
+        D_PAD * pad = module->FindPadByName( aPadname );
+        if( pad )
+        {
+            pad->SetNetname( aNetname );
+            return pad;
+        }
+        if( m_messageWindow )
+        {
+            wxString msg;
+            msg.Printf( _( "Module [%s]: Pad [%s] not found" ),
+                        GetChars( aModule ), GetChars( aPadname ) );
+            m_messageWindow->AppendText( msg + wxT( "\n" ) );
+        }
+    }
+
+    return NULL;
+}
+
 
 /* function RemoveExtraFootprints
  * Remove (delete) not locked footprints found on board, but not in netlist
  */
-void NETLIST_READER::RemoveExtraFootprints( const wxString& aNetlistFileName )
+void NETLIST_READER::RemoveExtraFootprints()
 {
-    wxArrayString componentsInNetlist;
-
-    // Build list of modules in the netlist
-    int modulesCount = BuildComponentsListFromNetlist( aNetlistFileName, componentsInNetlist );
-
-    if( modulesCount == 0 )
-        return;
-
     MODULE* nextModule;
-    MODULE* module = m_pcbframe->GetBoard()->m_Modules;
-    bool ask_user = true;
 
+    MODULE* module = m_pcbframe->GetBoard()->m_Modules;
     for( ; module != NULL; module = nextModule )
     {
-        int ii;
+        unsigned ii;
         nextModule = module->Next();
 
         if( module->m_ModuleStatus & MODULE_is_LOCKED )
             continue;
 
-        for( ii = 0; ii < modulesCount; ii++ )
+        for( ii = 0; ii < m_modulesInNetlist.size(); ii++ )
         {
-            if( module->m_Reference->m_Text.CmpNoCase( componentsInNetlist[ii] ) == 0 )
+            MODULE_INFO* mod_info = m_modulesInNetlist[ii];
+            if( module->m_Reference->m_Text.CmpNoCase( mod_info->m_Reference ) == 0 )
                 break; // Module is found in net list.
         }
 
-        if( ii == modulesCount )   // Module not found in netlist.
-        {
-            if( ask_user )
-            {
-                ask_user = false;
-
-                if( !IsOK( NULL,
-                    _( "Ok to delete not locked footprints not found in netlist?" ) ) )
-                    break;
-            }
-
+        if( ii == m_modulesInNetlist.size() )   // Module not found in netlist.
             module->DeleteStructure();
-        }
     }
 }
 
-/*
- * Function ReadNetlist
- * Update footprints (load missing footprints and delete on request extra
- * footprints)
- * Update References, values, "TIME STAMP" and connectivity data
- * return true if Ok
- *
- *  the format of the netlist is something like:
- * # EESchema Netlist Version 1.0 generee le  18/5/2005-12:30:22
- *  (
- *  ( 40C08647 $noname R20 4,7K {Lib=R}
- *  (    1 VCC )
- *  (    2 MODB_1 )
- *  )
- *  ( 40C0863F $noname R18 4,7_k {Lib=R}
- *  (    1 VCC )
- *  (    2 MODA_1 )
- *  )
- *  }
- * #End
+
+/* Search for a module id the modules existing in the current BOARD.
+ * aId is a key to identify the module to find:
+ * The reference or the full time stamp, according to m_UseTimeStamp
+ * Returns the module is found, NULL otherwise.
  */
-bool NETLIST_READER::ReadNetList( FILE*           aFile,
-                                  const wxString& aNetlistFileName,
-                                  const wxString& aCmplistFileName )
+MODULE* NETLIST_READER::FindModule( const wxString& aId )
 {
-    int state   = 0;
-    bool is_comment = false;
-
-    m_netlistFullName = aNetlistFileName;
-    m_cmplistFullName = aCmplistFileName;
-
-    m_useCmpFile = true;
-
-    /* First, read the netlist: Build the list of footprints to load (new
-     * footprints)
-     */
-
-    // netlineReader dtor will close aFile
-    FILE_LINE_READER netlineReader( aFile, m_netlistFullName );
-
-    while( netlineReader.ReadLine() )
-    {
-        char* line = StrPurge( netlineReader.Line() );
-
-        if( is_comment ) // Comments in progress
-        {
-            // Test for end of the current comment
-            if( ( line = strchr( line, '}' ) ) == NULL )
-                continue;
-
-            is_comment = false;
-        }
-        if( *line == '{' ) // Start Comment
-        {
-            is_comment = true;
-
-            if( ( line = strchr( line, '}' ) ) == NULL )
-                continue;
-        }
-
-        if( *line == '(' )
-            state++;
-
-        if( *line == ')' )
-            state--;
-
-        if( state == 2 )
-        {
-            ReadNetlistModuleDescr( line, TESTONLY );
-            continue;
-        }
-
-        if( state >= 3 ) // First pass: pad descriptions are not read here.
-        {
-            state--;
-        }
-    }
-
-    // Load new footprints
-    bool success = loadNewModules();
-
-    if( ! success )
-        wxMessageBox( _("Some footprints are not found in libraries") );
-
-    /* Second read , All footprints are on board.
-     * One must update the schematic info (pad netnames)
-     */
-    netlineReader.Rewind();
-    m_currModule = NULL;
-    state = 0;
-    is_comment = false;
-
-    while( netlineReader.ReadLine() )
-    {
-        char* line = StrPurge( netlineReader.Line() );
-
-        if( is_comment )   // we are reading a comment
-        {
-            // Test for end of the current comment
-            if( ( line = strchr( line, '}' ) ) == NULL )
-                continue;
-            is_comment = false;
-        }
-
-        if( *line == '{' ) // this is the beginning of a comment
-        {
-            is_comment = true;
-
-            if( ( line = strchr( line, '}' ) ) == NULL )
-                continue;
-        }
-
-        if( *line == '(' )
-            state++;
-
-        if( *line == ')' )
-            state--;
-
-        if( state == 2 )
-        {
-            m_currModule = ReadNetlistModuleDescr( line, READMODULE );
-
-            if( m_currModule == NULL ) // the module could not be created (perhaps
-            {
-                // footprint not found in library)
-                continue;
-            }
-            else // clear pads netnames
-            {
-                for( D_PAD* pad = m_currModule->m_Pads;  pad;  pad = pad->Next() )
-                {
-                    pad->SetNetname( wxEmptyString );
-                }
-            }
-
-            continue;
-        }
-
-        if( state >= 3 )
-        {
-            if( m_currModule )
-                SetPadNetName( line );
-            state--;
-        }
-    }
-
-    return true;
-}
-
-
-/* Function ReadNetlistModuleDescr
- * Read the full description of a footprint, from the netlist
- * and update the corresponding module.
- * param aTstOnly bool to switch between 2 modes:
- *      If aTstOnly == false:
- *          if the module does not exist, it is added to m_newModulesList
- *      If aTstOnly = true:
- *          if the module does not exist, it is loaded and added to the board module list
- * param  aText contains the first line of description
- * This function uses m_useFichCmp as a flag to know the footprint name:
- *      If true: component file *.cmp is used
- *      If false: the netlist only is used
- *      This flag is reset to false if the .cmp file is not found
- * Analyze lines like:
- * ( /40C08647 $noname R20 4.7K {Lib=R}
- * (1 VCC)
- * (2 MODB_1)
- * )
- */
-MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly )
-{
-    char*    text;
-    wxString timeStampPath;         // the full time stamp read from netlist
-    wxString textFootprintName;     // the footprint name read from netlist
-    wxString textValue;             // the component value read from netlist
-    wxString textCmpReference;      // the component schematic reference read from netlist
-    wxString cmpFootprintName;      // the footprint name read from the *.cmp file
-                                    // giving the equivalence between footprint names and components
-    bool     error = false;
-    char     line[1024];
-
-    strcpy( line, aText );
-
-    textValue = wxT( "~" );
-
-    // Read descr line like  /40C08647 $noname R20 4.7K {Lib=R}
-
-    // Read time stamp (first word)
-    if( ( text = strtok( line, " ()\t\n" ) ) == NULL )
-        error = true;
-    else
-        timeStampPath = FROM_UTF8( text );
-
-    // Read footprint name (second word)
-    if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
-        error = true;
-    else
-        textFootprintName = FROM_UTF8( text );
-
-    // Read schematic reference (third word)
-    if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
-        error = true;
-    else
-        textCmpReference = FROM_UTF8( text );
-
-    // Read schematic value (forth word)
-    if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
-        error = true;
-    else
-        textValue = FROM_UTF8( text );
-
-    if( error )
-        return NULL;
-
-    // Test if module is already loaded.
-    wxString * identMod = &textCmpReference;
-
-    if( m_UseTimeStamp )
-        identMod = &timeStampPath;
-
     MODULE* module = m_pcbframe->GetBoard()->m_Modules;
-    MODULE* nextModule;
-    bool    found = false;
-
-    for( ; module != NULL; module = nextModule )
+    for( ; module != NULL; module = module->Next() )
     {
-        nextModule = module->Next();
-
         if( m_UseTimeStamp ) // identification by time stamp
         {
-            if( timeStampPath.CmpNoCase( module->m_Path ) == 0 )
-                found = true;
+            if( aId.CmpNoCase( module->m_Path ) == 0 )
+                return module;
         }
         else    // identification by Reference
         {
-            if( textCmpReference.CmpNoCase( module->m_Reference->m_Text ) == 0 )
-                found = true;
-        }
-
-        if( found ) // The footprint corresponding to the component is already on board
-        {
-            // This footprint is already on board
-            // but if m_LibRef (existing footprint name) and the footprint name from netlist
-            // do not match, change this footprint on demand.
-            if( ! aTstOnly )
-            {
-                cmpFootprintName = textFootprintName;     // Use footprint name from netlist
-
-                if( m_useCmpFile )                        // Try to get footprint name from .cmp file
-                {
-                    m_useCmpFile = readModuleComponentLinkfile( identMod, cmpFootprintName );
-                }
-
-                /* Module mismatch: current footprint and footprint specified in
-                 * net list are different.
-                 */
-                if( module->m_LibRef.CmpNoCase( cmpFootprintName ) != 0 )
-                {
-                    if( m_ChangeFootprints )   // footprint exchange allowed.
-                    {
-                        MODULE* newModule = m_pcbframe->GetModuleLibrary( wxEmptyString,
-                                                                          cmpFootprintName,
-                                                                          true );
-
-                        if( newModule )
-                        {
-                            // Change old module to the new module (and delete the old one)
-                            m_pcbframe->Exchange_Module( module, newModule, NULL );
-                            module = newModule;
-                        }
-                    }
-                    else
-                    {
-                        wxString msg;
-                        msg.Printf( _( "Component \"%s\": Mismatch! module is [%s] and netlist said [%s]\n" ),
-                                    GetChars( textCmpReference ),
-                                    GetChars( module->m_LibRef ),
-                                    GetChars( cmpFootprintName ) );
-
-                        if( m_messageWindow )
-                            m_messageWindow->AppendText( msg );
-                    }
-                }
-            }
-
-            break;
+            if( aId.CmpNoCase( module->m_Reference->m_Text ) == 0 )
+                return module;
         }
     }
 
-    if( module == NULL )                    // a new module must be loaded from libs
-    {
-        cmpFootprintName = textFootprintName;   // Use footprint name from netlist
-
-        if( m_useCmpFile )                      // Try to get footprint name from .cmp file
-        {
-            m_useCmpFile = readModuleComponentLinkfile( identMod, cmpFootprintName );
-        }
-
-        if( aTstOnly )
-        {
-            MODULE_INFO* newMod;
-            newMod = new MODULE_INFO( cmpFootprintName, textCmpReference, timeStampPath );
-            m_newModulesList.push_back( newMod );
-        }
-        else
-        {
-            if( m_messageWindow )
-            {
-                wxString msg;
-                msg.Printf( _( "Component [%s] not found" ), GetChars( textCmpReference ) );
-                m_messageWindow->AppendText( msg + wxT( "\n" ) );
-            }
-        }
-
-        return NULL;    // The module could not be loaded.
-    }
-
-    // Update current module ( reference, value and "Time Stamp")
-    module->m_Reference->m_Text = textCmpReference;
-    module->m_Value->m_Text     = textValue;
-    module->m_Path = timeStampPath;
-
-    return module;
-}
-
-
-/*
- * Function SetPadNetName
- *  Update a pad netname using the current footprint
- *  Line format: ( <pad number> <net name> )
- *  Param aText = current line read from netlist
- */
-bool NETLIST_READER::SetPadNetName( char* aText )
-{
-    char*       p;
-    char        line[256];
-
-    if( m_currModule == NULL )
-        return false;
-
-    strncpy( line, aText, sizeof(line) );
-
-    if( ( p = strtok( line, " ()\t\n" ) ) == NULL )
-        return false;
-
-    wxString pinName = FROM_UTF8( p );
-
-    if( ( p = strtok( NULL, " ()\t\n" ) ) == NULL )
-        return false;
-
-    wxString netName = FROM_UTF8( p );
-
-    bool found = false;
-    for( D_PAD* pad = m_currModule->m_Pads;  pad;  pad = pad->Next() )
-    {
-        wxString padName = pad->GetPadName();
-
-        if( padName == pinName )
-        {
-            found = true;
-            if( (char) netName[0] != '?' )
-                pad->SetNetname( netName );
-            else
-                pad->SetNetname( wxEmptyString );
-        }
-    }
-
-    if( !found )
-    {
-        if( m_messageWindow )
-        {
-            wxString msg;
-            msg.Printf( _( "Module [%s]: Pad [%s] not found" ),
-                        GetChars( m_currModule->m_Reference->m_Text ),
-                        GetChars( pinName ) );
-            m_messageWindow->AppendText( msg + wxT( "\n" ) );
-        }
-    }
-
-    return found;
+    return NULL;
 }
 
 
@@ -796,11 +480,8 @@ MODULE* PCB_EDIT_FRAME::ListAndSelectModuleName( void )
 void PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints(
     const wxString& aNetlistFullFilename )
 {
-#define MAX_LEN_TXT 32
-    int           ii;
-    int           NbModulesNetListe, nberr = 0;
-    wxArrayString tmp;
-    wxArrayString list;
+    int           nberr = 0;
+    wxArrayString list;     // The list of messages to display
 
     if( GetBoard()->m_Modules == NULL )
     {
@@ -808,14 +489,21 @@ void PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints(
         return;
     }
 
+    FILE*   netfile = OpenNetlistFile( aNetlistFullFilename );
+    if( !netfile )
+        return;
+
+    SetLastNetListRead( aNetlistFullFilename );
     // Build the list of references of the net list modules.
     NETLIST_READER netList_Reader( this );
-    NbModulesNetListe = netList_Reader.BuildComponentsListFromNetlist( aNetlistFullFilename, tmp );
+    netList_Reader.SetFilesnames( aNetlistFullFilename, wxEmptyString );
+    netList_Reader.BuildModuleListOnly( true );
+    if( ! netList_Reader.ReadNetList( netfile ) )
+        return;  // error
 
-    if( NbModulesNetListe < 0 )
-        return;  // File not found
+    std::vector <MODULE_INFO*>& moduleInfoList = netList_Reader.GetModuleInfoList();
 
-    if( NbModulesNetListe == 0 )
+    if( moduleInfoList.size() == 0 )
     {
         wxMessageBox( _( "No modules in NetList" ) );
         return;
@@ -845,43 +533,35 @@ void PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints(
         }
     }
 
-    // Search for the missing module by the net list.
+    // Search for missing modules on board.
     list.Add( _( "Missing:" ) );
 
-    for( ii = 0; ii < NbModulesNetListe; ii++ )
+    for( unsigned ii = 0; ii < moduleInfoList.size(); ii++ )
     {
-        module = (MODULE*) GetBoard()->m_Modules;
-
-        for( ; module != NULL; module = module->Next() )
-        {
-            if( module->m_Reference->m_Text.CmpNoCase( tmp[ii] ) == 0 )
-            {
-                break;
-            }
-        }
-
+        MODULE_INFO* mod_info = moduleInfoList[ii];
+        module = GetBoard()->FindModuleByReference( mod_info->m_Reference );
         if( module == NULL )    // Module missing, not found in board
         {
-            list.Add( tmp[ii] );
+            list.Add( mod_info->m_Reference );
             nberr++;
         }
     }
 
-    // Search for modules not in net list.
+    // Search for modules found on board but not in net list.
     list.Add( _( "Not in Netlist:" ) );
 
     module = GetBoard()->m_Modules;
     for( ; module != NULL; module = module->Next() )
     {
-        for( ii = 0; ii < NbModulesNetListe; ii++ )
+        unsigned ii;
+        for( ii = 0; ii < moduleInfoList.size(); ii++ )
         {
-            if( module->m_Reference->m_Text.CmpNoCase( tmp[ii] ) == 0 )
-            {
+            MODULE_INFO* mod_info = moduleInfoList[ii];
+            if( module->m_Reference->m_Text.CmpNoCase( mod_info->m_Reference ) == 0 )
                 break; // Module is in net list.
-            }
         }
 
-        if( ii == NbModulesNetListe )   // Module not found in netlist
+        if( ii == moduleInfoList.size() )   // Module not found in netlist
         {
             list.Add( module->m_Reference->m_Text );
             nberr++;
@@ -895,105 +575,17 @@ void PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints(
 }
 
 
-/**
- * Function BuildComponentsListFromNetlist
- * Fill aBufName with component references read from the netlist.
- * @param aNetlistFilename = netlist full file name
- * @param aBufName = wxArrayString to fill with component references
- * @return component count, or -1 if netlist file cannot opened
- */
-int NETLIST_READER::BuildComponentsListFromNetlist( const wxString& aNetlistFilename,
-                                                    wxArrayString&  aBufName )
-{
-    int   component_count;
-    int   state;
-    bool  is_comment;
-    char* text;
-
-    FILE* netfile = OpenNetlistFile( aNetlistFilename );
-
-    if( netfile == NULL )
-        return -1;
-
-    FILE_LINE_READER netlineReader( netfile, aNetlistFilename );    // ctor will close netfile
-    char*            Line = netlineReader;
-
-    state = 0;
-    is_comment = false;
-    component_count = 0;
-
-    while( netlineReader.ReadLine() )
-    {
-        text = StrPurge( Line );
-
-        if( is_comment )
-        {
-            if( ( text = strchr( text, '}' ) ) == NULL )
-                continue;
-
-            is_comment = false;
-        }
-
-        if( *text == '{' ) // Comments.
-        {
-            is_comment = true;
-
-            if( ( text = strchr( text, '}' ) ) == NULL )
-                continue;
-        }
-
-        if( *text == '(' )
-            state++;
-
-        if( *text == ')' )
-            state--;
-
-        if( state == 2 )
-        {
-            // skip TimeStamp:
-            strtok( Line, " ()\t\n" );
-
-            // skip footprint name:
-            strtok( NULL, " ()\t\n" );
-
-            // Load the reference of the component:
-            text = strtok( NULL, " ()\t\n" );
-            component_count++;
-            aBufName.Add( FROM_UTF8( text ) );
-            continue;
-        }
-
-        if( state >= 3 )
-        {
-            state--;
-        }
-    }
-
-    return component_count;
-}
-
-
 /*
  * function readModuleComponentLinkfile
  * read the *.cmp file ( filename in m_cmplistFullName )
  * giving the equivalence Footprint_names / components
  * to find the footprint name corresponding to aCmpIdent
- * return true and the module name in aFootprintName, false if not found
- *
- * param aCmpIdent = component identification: schematic reference or time stamp
- * param aFootprintName the footprint name corresponding to the component identification
+ * return true if the file can be read
  *
  * Sample file:
  *
  * Cmp-Mod V01 Genere by Pcbnew 29/10/2003-13: 11:6 *
  *  BeginCmp
- *  TimeStamp = /322D3011;
- *  Reference = BUS1;
- *  ValeurCmp = BUSPC;
- *  IdModule  = BUS_PC;
- *  EndCmp
- *
- *  BeginCmp
  *  TimeStamp = /32307DE2/AA450F67;
  *  Reference = C1;
  *  ValeurCmp = 47uF;
@@ -1001,12 +593,12 @@ int NETLIST_READER::BuildComponentsListFromNetlist( const wxString& aNetlistFile
  *  EndCmp
  *
  */
-bool NETLIST_READER::readModuleComponentLinkfile( const wxString* aCmpIdent,
-                                                  wxString& aFootprintName )
+
+bool NETLIST_READER::readModuleComponentLinkfile()
 {
     wxString refcurrcmp;    // Stores value read from line like Reference = BUS1;
     wxString timestamp;     // Stores value read from line like TimeStamp = /32307DE2/AA450F67;
-    wxString idmod;         // Stores value read from line like IdModule  = CP6;
+    wxString footprint;     // Stores value read from line like IdModule  = CP6;
 
     FILE*    cmpFile = wxFopen( m_cmplistFullName, wxT( "rt" ) );
 
@@ -1035,7 +627,7 @@ bool NETLIST_READER::readModuleComponentLinkfile( const wxString* aCmpIdent,
 
         // Begin component description.
         refcurrcmp.Empty();
-        idmod.Empty();
+        footprint.Empty();
         timestamp.Empty();
 
         while( netlineReader.ReadLine() )
@@ -1059,7 +651,7 @@ bool NETLIST_READER::readModuleComponentLinkfile( const wxString* aCmpIdent,
 
             if( buffer.StartsWith( wxT("IdModule  =" ) ) )
             {
-                idmod = value;
+                footprint = value;
                 continue;
             }
 
@@ -1070,21 +662,28 @@ bool NETLIST_READER::readModuleComponentLinkfile( const wxString* aCmpIdent,
             }
         }
 
-        // Check if this component is the right component:
-        if( m_UseTimeStamp )    // Use schematic timestamp to locate the footprint
+        // Find the corresponding item in module info list:
+        for( unsigned ii = 0; ii < m_modulesInNetlist.size(); ii++ )
         {
-            if( aCmpIdent->CmpNoCase( timestamp ) == 0  && !timestamp.IsEmpty() )
-            {    // Found
-                aFootprintName = idmod;
-                return true;
-            }
-        }
-        else                   // Use schematic reference to locate the footprint
-        {
-            if( aCmpIdent->CmpNoCase( refcurrcmp ) == 0 )   // Found!
+            MODULE_INFO * mod_info = m_modulesInNetlist[ii];
+            if( m_UseTimeStamp )    // Use schematic timestamp to locate the footprint
             {
-                aFootprintName = idmod;
-                return true;
+                if( mod_info->m_TimeStamp.CmpNoCase( timestamp ) == 0  &&
+                    !timestamp.IsEmpty() )
+                {    // Found
+                    if( !footprint.IsEmpty() )
+                        mod_info->m_Footprint = footprint;
+                    break;
+                }
+            }
+            else                   // Use schematic reference to locate the footprint
+            {
+                if( mod_info->m_Reference.CmpNoCase( refcurrcmp ) == 0 )   // Found!
+                {
+                    if( !footprint.IsEmpty() )
+                        mod_info->m_Footprint = footprint;
+                    break;
+                }
             }
         }
     }
@@ -1093,6 +692,16 @@ bool NETLIST_READER::readModuleComponentLinkfile( const wxString* aCmpIdent,
 }
 
 
+/* Function to sort the footprint list, used by loadNewModules.
+ * the given list is sorted by name
+ */
+static bool SortByLibName( MODULE_INFO* ref, MODULE_INFO* cmp )
+{
+    int ii = ref->m_Footprint.CmpNoCase( cmp->m_Footprint );
+    return ii > 0;
+}
+
+
 /* Load new modules from library.
  * If a new module is already loaded it is duplicated, which avoids multiple
  * unnecessary disk or net access to read libraries.
@@ -1126,30 +735,25 @@ bool NETLIST_READER::loadNewModules()
     {
         cmp = m_newModulesList[ii];
 
-        if( (ii == 0) || ( ref->m_LibName != cmp->m_LibName) )
+        if( (ii == 0) || ( ref->m_Footprint != cmp->m_Footprint) )
         {
             // New footprint : must be loaded from a library
-            Module = m_pcbframe->GetModuleLibrary( wxEmptyString, cmp->m_LibName, false );
+            Module = m_pcbframe->GetModuleLibrary( wxEmptyString, cmp->m_Footprint, false );
             ref = cmp;
 
             if( Module == NULL )
             {
                 success = false;
-                wxString msg;
-                msg.Printf( _( "Component [%s]: footprint <%s> not found" ),
-                            GetChars( cmp->m_CmpName ),
-                            GetChars( cmp->m_LibName ) );
-
                 if( m_messageWindow )
                 {
+                    wxString msg;
+                    msg.Printf( _( "Component [%s]: footprint <%s> not found" ),
+                                GetChars( cmp->m_Reference ),
+                                GetChars( cmp->m_Footprint ) );
+
                     msg += wxT("\n");
                     m_messageWindow->AppendText( msg );
                 }
-                else
-                {
-                    DisplayError( NULL, msg );
-                }
-
                 continue;
             }
 
@@ -1157,9 +761,9 @@ bool NETLIST_READER::loadNewModules()
 
             /* Update schematic links : reference "Time Stamp" and schematic
              * hierarchical path */
-            Module->m_Reference->m_Text = cmp->m_CmpName;
+            Module->m_Reference->m_Text = cmp->m_Reference;
             Module->SetTimeStamp( GetNewTimeStamp() );
-            Module->m_Path = cmp->m_TimeStampPath;
+            Module->SetPath( cmp->m_TimeStamp );
         }
         else
         {
@@ -1173,9 +777,9 @@ bool NETLIST_READER::loadNewModules()
             pcb->Add( newmodule, ADD_APPEND );
 
             Module = newmodule;
-            Module->m_Reference->m_Text = cmp->m_CmpName;
+            Module->m_Reference->m_Text = cmp->m_Reference;
             Module->SetTimeStamp( GetNewTimeStamp() );
-            Module->m_Path = cmp->m_TimeStampPath;
+            Module->SetPath( cmp->m_TimeStamp );
         }
     }
 
diff --git a/pcbnew/netlist_reader.h b/pcbnew/netlist_reader.h
new file mode 100644
index 0000000000..782a084c34
--- /dev/null
+++ b/pcbnew/netlist_reader.h
@@ -0,0 +1,295 @@
+#ifndef NETLIST_READER_H
+#define  NETLIST_READER_H
+
+/**
+ * @file netlist_reader.h
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras.
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.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 <algorithm>
+
+#include <fctsys.h>
+#include <kicad_string.h>
+#include <wxPcbStruct.h>
+#include <richio.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <pcbnew.h>
+
+
+/*
+ * Helper class, to store new footprints info found in netlist.
+ * New footprints are footprints relative to new components found in netlist
+ */
+class MODULE_INFO
+{
+public:
+    wxString m_Footprint;
+    wxString m_Reference;
+    wxString m_Value;
+    wxString m_TimeStamp;
+
+public: MODULE_INFO( const wxString& libname,
+                     const wxString& cmpname,
+                     const wxString& value,
+                     const wxString& timestamp )
+    {
+        m_Footprint = libname;
+        m_Reference = cmpname;
+        m_Value = value;
+        m_TimeStamp = timestamp;
+    }
+
+    ~MODULE_INFO() { };
+};
+
+
+/*
+ * Helper class, to read a netlist.
+ */
+class NETLIST_READER
+{
+private:
+    PCB_EDIT_FRAME*            m_pcbframe;          // the main Pcbnew frame
+    wxTextCtrl*                m_messageWindow;     // a textctrl to show messages (can be NULL)
+    wxString                   m_netlistFullName;   // The full netlist filename
+    wxString                   m_cmplistFullName;   // The full component/footprint association filename
+    MODULE*                    m_currModule;        // The footprint currently being read in netlist
+    std::vector <MODULE_INFO*> m_modulesInNetlist;  // The list of footprints, found in netlist
+                                                    // (must be loaded from libraries)
+    std::vector <MODULE_INFO*> m_newModulesList;    // The list of new footprints,
+                                                    // found in netlist, but not on board
+                                                    // (must be loaded from libraries)
+    bool m_BuildModuleListOnly;     // if true read netlist, populates m_modulesInNetlist
+                                    // but do not read and change nets and modules on board
+
+public:
+    bool m_UseCmpFile;              // true to use .cmp files as component/footprint file link
+                                    // false to use netlist only to know component/footprint link
+    bool m_UseTimeStamp;            // Set to true to identify footprints by time stamp
+                                    // false to use schematic reference
+    bool m_ChangeFootprints;        // Set to true to change existing footprints to new ones
+                                    // when netlist gives a different footprint name
+
+public: NETLIST_READER( PCB_EDIT_FRAME* aFrame, wxTextCtrl* aMessageWindow = NULL )
+    {
+        m_pcbframe = aFrame;
+        m_messageWindow    = aMessageWindow;
+        m_UseTimeStamp     = false;
+        m_ChangeFootprints = false;
+        m_UseCmpFile = true;
+        m_BuildModuleListOnly = false;
+    }
+
+    ~NETLIST_READER()
+    {
+        // Free modules info list:
+        for( unsigned ii = 0; ii < m_newModulesList.size(); ii++ )
+            delete m_modulesInNetlist[ii];
+
+        m_modulesInNetlist.clear();
+        m_newModulesList.clear();
+    }
+
+    std::vector <MODULE_INFO*>& GetModuleInfoList()
+    {
+        return m_modulesInNetlist;
+    }
+
+    /**
+     * Function AddModuleInfo
+     * Add a new module info to the main list of modules ifo
+     * @param aModInfo = a reference to the item to add
+     */
+    void AddModuleInfo( MODULE_INFO* aModInfo )
+    {
+        m_modulesInNetlist.push_back( aModInfo );
+    }
+
+    /**
+     * Function BuildModuleListOnly
+     * Set to true or false the Build Module List Only option
+     * When this option is false, a full netlist read is made,
+     * and modules are added/modified
+     * When this option is true, a partial netlist read is made
+     * and only the list of modules found in netlist is built
+     * @param aOpt = the value of option
+     */
+    void BuildModuleListOnly( bool aOpt )
+    {
+        m_BuildModuleListOnly = aOpt;
+    }
+
+    /**
+     * Function BuildModuleListOnly
+     * Get the Build Module List Only option state
+     * @return the state of option (true/false)
+     */
+     bool BuildModuleListOnly()
+    {
+        return m_BuildModuleListOnly;
+    }
+
+    /**
+     * Function InitializeModules
+     * Called when reading a netlist and after the module info list is populated
+     * Load new module and clear pads netnames
+     * return true if all modules are loaded, false if some are missing
+     */
+    bool InitializeModules();
+
+    /**
+     * Function TestFootprintsMatchingAndExchange
+     * Called when reading a netlist, after the module info list is populated
+     * module reference updated (after a call to InitializeModules)
+     * Test, for each module, if the current footprint matches the footprint
+     * given by the netlist (or the cmp file, if used)
+     * print a list of mismatches od exchange footprints i
+     * m_ChangeFootprints == true
+     */
+    void TestFootprintsMatchingAndExchange();
+
+
+    /**
+     * Function SetFilesnames
+     * initialize filenames
+     * @param aNetlistFileName = full filename of netlist
+     * @param aCmplistFileName = full filename of components file (can be empty)
+     * and the components file will be non used
+     */
+     void SetFilesnames( const wxString& aNetlistFileName,
+                      const wxString& aCmplistFileName )
+    {
+        m_netlistFullName = aNetlistFileName;
+        m_cmplistFullName = aCmplistFileName;
+    }
+
+    /**
+     * Function ReadNetList
+     * The main function to detect a netlist format, read the netlist,
+     * and update the board
+     * depending on the detected format, calls ReadOldFmtdNetList or ReadKicadNetList
+     * @param aFile = the already opened file (will be closed by the netlist reader)
+     * @return true if success
+     */
+    bool ReadNetList( FILE* aFile );
+
+    /**
+     * Function ReadOldFmtdNetList
+     * The main function to read a netlist (old netlist format),
+     * and update the board
+     * @param aFile = the already opened file (will be closed by ReadOldFmtdNetList)
+     * @return true if success
+     */
+    bool ReadOldFmtdNetList( FILE* aFile );
+
+    /**
+     * Function ReadKicadNetList
+     * The main function to read a netlist (new netlist format, using S expressions),
+     * and update the board
+     * @param aFile = the already opened file (will be closed by ReadKicadNetList)
+     * @return true if success
+     */
+    bool ReadKicadNetList( FILE* aFile );
+
+    /**
+     * function RemoveExtraFootprints
+     * Remove (delete) not locked footprints found on board, but not in netlist
+     * The netlist is expected to be read, and the main module list info up to date
+     */
+    void  RemoveExtraFootprints( );
+
+    /**
+     * Function SetPadNetName
+     *  Update a pad netname
+     *  @param aModule = module reference
+     *  @param aPadname = pad name (pad num)
+     *  @param aNetname = new net name of the pad
+     *  @return a pointer to the pad or NULL if the pad is not found
+     */
+    D_PAD* SetPadNetName( const wxString & aModule, const wxString & aPadname,
+                          const wxString & aNetname );
+
+private:
+
+    /**
+     * Function FindModule
+     *  search for a module id the modules existing in the current BOARD.
+     *  @param aId = the key to identify the module to find:
+     *   The reference or the full time stamp, according to m_UseTimeStamp
+     * @return the module found, or NULL.
+     */
+    MODULE* FindModule( const wxString& aId );
+
+    /**
+     * Function SetPadNetName
+     *  Update a pad netname using the current footprint
+     *  from the netlist (line format: ( \<pad number\> \<net name\> ) )
+     *  @param aText = current line read from netlist
+     */
+    bool    SetPadNetName( char* aText );
+
+    /**
+     * Function ReadOldFmtNetlistModuleDescr
+     * Read the full description of a footprint, from the netlist
+     * and update the corresponding module.
+     * @param aBuildList bool to switch between 2 modes:
+     *      aBuildList = true:
+     *          add module info added to m_newModulesList
+     *      aBuildList = false:
+     *          The module is searched in the board modules list
+     * @param  aText contains the first line of description
+     * This function uses m_useFichCmp as a flag to know the footprint name:
+     *      If true: component file *.cmp is used
+     *      If false: the netlist only is used
+     *      This flag is reset to false if the .cmp file is not found
+     * @return a reference to the corresponding module on board (NULL if not found)
+     */
+    MODULE* ReadOldFmtNetlistModuleDescr( char* aText, bool aBuildList );
+
+    /**
+     * Function loadNewModules
+     * Load from libraries new modules found in netlist and add them to the current Board.
+     * modules to load come from m_newModulesList
+     * @return false if a footprint is not found, true if all footprints are loaded
+     */
+    bool    loadNewModules();
+
+    /**
+     * function readModuleComponentLinkfile
+     * read the *.cmp file ( filename in m_cmplistFullName )
+     * and initialize the m_Footprint member of each item in m_modulesInNetlist,
+     * when it is found in file, and with a non empty footprint value
+     * giving the equivalence between footprint names and components
+     * to find the footprint name corresponding to aCmpIdent
+     * @return true and the file can be read
+     */
+    bool    readModuleComponentLinkfile();
+};
+
+#endif  // NETLIST_READER_H
diff --git a/pcbnew/netlist_reader_firstformat.cpp b/pcbnew/netlist_reader_firstformat.cpp
new file mode 100644
index 0000000000..468ff3b436
--- /dev/null
+++ b/pcbnew/netlist_reader_firstformat.cpp
@@ -0,0 +1,315 @@
+/**
+ * @file pcbnew/netlist_reader_firstformat.cpp
+ */
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2011 Jean-Pierre Charras.
+ * Copyright (C) 1992-2011 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
+ */
+
+
+/*
+ *  Netlist reader using the first format of pcbnew netlist.
+ * This netlist reader build the list of modules found in netlist
+ * (list in m_modulesInNetlist)
+ * and update pads netnames
+ */
+
+#include <fctsys.h>
+#include <kicad_string.h>
+#include <wxPcbStruct.h>
+#include <richio.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <pcbnew.h>
+
+#include <netlist_reader.h>
+
+// constants used by ReadOldFmtNetlistModuleDescr():
+#define BUILDLIST   true
+#define READMODULE false
+
+
+/*
+ * Function ReadOldFmtdNetList
+ * Update footprints (load missing footprints and delete on request extra
+ * footprints)
+ * Update References, values, "TIME STAMP" and connectivity data
+ * return true if Ok
+ *
+ *  the format of the netlist is something like:
+ * # EESchema Netlist Version 1.0 generee le  18/5/2005-12:30:22
+ *  (
+ *  ( 40C08647 $noname R20 4,7K {Lib=R}
+ *  (    1 VCC )
+ *  (    2 MODB_1 )
+ *  )
+ *  ( 40C0863F $noname R18 4,7_k {Lib=R}
+ *  (    1 VCC )
+ *  (    2 MODA_1 )
+ *  )
+ *  }
+ * #End
+ */
+bool NETLIST_READER::ReadOldFmtdNetList( FILE* aFile )
+{
+    int state   = 0;
+    bool is_comment = false;
+
+    /* First, read the netlist: Build the list of footprints found in netlist
+     */
+    // netlineReader dtor will close aFile
+    FILE_LINE_READER netlineReader( aFile, m_netlistFullName );
+
+    while( netlineReader.ReadLine() )
+    {
+        char* line = StrPurge( netlineReader.Line() );
+
+        if( is_comment ) // Comments in progress
+        {
+            // Test for end of the current comment
+            if( ( line = strchr( line, '}' ) ) == NULL )
+                continue;
+
+            is_comment = false;
+        }
+        if( *line == '{' ) // Start Comment
+        {
+            is_comment = true;
+
+            if( ( line = strchr( line, '}' ) ) == NULL )
+                continue;
+        }
+
+        if( *line == '(' )
+            state++;
+
+        if( *line == ')' )
+            state--;
+
+        if( state == 2 )
+        {
+            ReadOldFmtNetlistModuleDescr( line, BUILDLIST );
+            continue;
+        }
+
+        if( state >= 3 ) // First pass: pad descriptions are not read here.
+        {
+            state--;
+        }
+    }
+
+    if( BuildModuleListOnly() )
+        return true; // at this point, the module list is read and built.
+
+    // Load new footprints
+    bool success = InitializeModules();
+
+    if( ! success )
+        wxMessageBox( _("Some footprints are not found in libraries") );
+
+    TestFootprintsMatchingAndExchange();
+
+    /* Second read , All footprints are on board.
+     * Update the schematic info (pad netnames)
+     */
+    netlineReader.Rewind();
+    m_currModule = NULL;
+    state = 0;
+    is_comment = false;
+
+    while( netlineReader.ReadLine() )
+    {
+        char* line = StrPurge( netlineReader.Line() );
+
+        if( is_comment )   // we are reading a comment
+        {
+            // Test for end of the current comment
+            if( ( line = strchr( line, '}' ) ) == NULL )
+                continue;
+            is_comment = false;
+        }
+
+        if( *line == '{' ) // this is the beginning of a comment
+        {
+            is_comment = true;
+
+            if( ( line = strchr( line, '}' ) ) == NULL )
+                continue;
+        }
+
+        if( *line == '(' )
+            state++;
+
+        if( *line == ')' )
+            state--;
+
+        if( state == 2 )
+        {
+            m_currModule = ReadOldFmtNetlistModuleDescr( line, READMODULE );
+            continue;
+        }
+
+        if( state >= 3 )
+        {
+            if( m_currModule )
+                SetPadNetName( line );
+            state--;
+        }
+    }
+
+    return true;
+}
+
+
+/* Function ReadOldFmtNetlistModuleDescr
+ * Read the beginning of a footprint  description, from the netlist
+ * and add a module info to m_modulesInNetlist
+ * Analyze lines like:
+ * ( /40C08647 $noname R20 4.7K {Lib=R}
+ * (1 VCC)
+ * (2 MODB_1)
+ * )
+ */
+MODULE* NETLIST_READER::ReadOldFmtNetlistModuleDescr( char* aText, bool aBuildList )
+{
+    char*    text;
+    wxString timeStampPath;         // the full time stamp read from netlist
+    wxString footprintName;         // the footprint name read from netlist
+    wxString cmpValue;             // the component value read from netlist
+    wxString cmpReference;      // the component schematic reference read from netlist
+    bool     error = false;
+    char     line[1024];
+
+    strcpy( line, aText );
+
+    cmpValue = wxT( "~" );
+
+    // Read descr line like  /40C08647 $noname R20 4.7K {Lib=R}
+
+    // Read time stamp (first word)
+    if( ( text = strtok( line, " ()\t\n" ) ) == NULL )
+        error = true;
+    else
+        timeStampPath = FROM_UTF8( text );
+
+    // Read footprint name (second word)
+    if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
+        error = true;
+    else
+        footprintName = FROM_UTF8( text );
+
+    // Read schematic reference (third word)
+    if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
+        error = true;
+    else
+        cmpReference = FROM_UTF8( text );
+
+    // Read schematic value (forth word)
+    if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
+        error = true;
+    else
+        cmpValue = FROM_UTF8( text );
+
+    if( error )
+        return NULL;
+
+    if( aBuildList )
+    {
+        MODULE_INFO* mod_info = new MODULE_INFO( footprintName, cmpReference,
+                                                cmpValue, timeStampPath );
+        AddModuleInfo( mod_info );
+        return NULL;
+    }
+
+    // search the module loaded on board
+    // reference and time stamps are already updated so we can used search by reference
+    MODULE* module = m_pcbframe->GetBoard()->FindModuleByReference( cmpReference );
+    if( module == NULL )
+    {
+        if( m_messageWindow )
+        {
+            wxString msg;
+            msg.Printf( _( "Component [%s] not found" ), GetChars( cmpReference ) );
+            m_messageWindow->AppendText( msg + wxT( "\n" ) );
+        }
+    }
+
+    return module;
+}
+
+
+/*
+ * Function SetPadNetName
+ *  Update a pad netname using the current footprint
+ *  Line format: ( <pad number> = <net name> )
+ *  Param aText = current line read from netlist
+ */
+bool NETLIST_READER::SetPadNetName( char* aText )
+{
+    char*       p;
+    char        line[256];
+
+    if( m_currModule == NULL )
+        return false;
+
+    strncpy( line, aText, sizeof(line) );
+
+    if( ( p = strtok( line, " ()\t\n" ) ) == NULL )
+        return false;
+
+    wxString pinName = FROM_UTF8( p );
+
+    if( ( p = strtok( NULL, " ()\t\n" ) ) == NULL )
+        return false;
+
+    wxString netName = FROM_UTF8( p );
+
+    bool found = false;
+    for( D_PAD* pad = m_currModule->m_Pads;  pad;  pad = pad->Next() )
+    {
+        wxString padName = pad->GetPadName();
+
+        if( padName == pinName )
+        {
+            found = true;
+            if( (char) netName[0] != '?' )
+                pad->SetNetname( netName );
+            else
+                pad->SetNetname( wxEmptyString );
+        }
+    }
+
+    if( !found )
+    {
+        if( m_messageWindow )
+        {
+            wxString msg;
+            msg.Printf( _( "Module [%s]: Pad [%s] not found" ),
+                        GetChars( m_currModule->m_Reference->m_Text ),
+                        GetChars( pinName ) );
+            m_messageWindow->AppendText( msg + wxT( "\n" ) );
+        }
+    }
+
+    return found;
+}
diff --git a/pcbnew/netlist_reader_kicad.cpp b/pcbnew/netlist_reader_kicad.cpp
new file mode 100644
index 0000000000..c2a0f37f9a
--- /dev/null
+++ b/pcbnew/netlist_reader_kicad.cpp
@@ -0,0 +1,325 @@
+/**
+ * @file pcbnew/netlist_reader_kicad.cpp
+ */
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2011 Jean-Pierre Charras.
+ * Copyright (C) 1992-2011 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 <wx/wx.h>
+#include <netlist_lexer.h>  // netlist_lexer is common to Eeschema and Pcbnew
+#include <netlist_reader.h>
+
+using namespace NL_T;
+
+/**
+ * Class PCB_PLOT_PARAMS_PARSER
+ * is the parser class for PCB_PLOT_PARAMS.
+ */
+class NETLIST_READER_KICAD_PARSER : public NETLIST_LEXER
+{
+private:
+    T token;
+    NETLIST_READER * netlist_reader;
+
+public:
+    NETLIST_READER_KICAD_PARSER( FILE_LINE_READER* aReader, NETLIST_READER *aNetlistReader );
+
+    /**
+     * Function Parse
+     * parse the full netlist
+     */
+    void Parse( BOARD * aBrd ) throw( IO_ERROR, PARSE_ERROR );
+
+    /**
+     * Function ParseComp
+     * parse the comp description like
+     * (comp (ref P1)
+     * (value DB25FEMELLE)
+     * (footprint DB25FC)
+     * (libsource (lib conn) (part DB25))
+     * (sheetpath (names /) (tstamps /))
+     * (tstamp 3256759C))
+     */
+    MODULE_INFO* ParseComp() throw( IO_ERROR, PARSE_ERROR );
+
+    void ParseNet( BOARD * aBrd ) throw( IO_ERROR, PARSE_ERROR );
+
+    /**
+     * Function SkipCurrent
+     * Skip the current token level, i.e
+     * search for the RIGHT parenthesis which closes the current description
+     */
+    void SkipCurrent() throw( IO_ERROR, PARSE_ERROR );
+
+    // Useful for debug only:
+    const char* getTokenName( T aTok )
+    {
+        return NETLIST_LEXER::TokenName( aTok );
+    }
+};
+
+
+bool NETLIST_READER::ReadKicadNetList( FILE* aFile )
+{
+    bool success = true;
+    BOARD * brd = m_pcbframe->GetBoard();
+
+        // netlineReader dtor will close aFile
+    FILE_LINE_READER netlineReader( aFile, m_netlistFullName );
+    NETLIST_READER_KICAD_PARSER netlist_parser( &netlineReader, this );
+
+    netlist_parser.Parse( brd );
+
+    return success;
+}
+
+
+
+// NETLIST_READER_KICAD_PARSER
+NETLIST_READER_KICAD_PARSER::NETLIST_READER_KICAD_PARSER( FILE_LINE_READER* aReader,
+                                                          NETLIST_READER *aNetlistReader ) :
+    NETLIST_LEXER( aReader )
+{
+    netlist_reader = aNetlistReader;
+}
+
+/**
+ * Function SkipCurrent
+ * Skip the current token level, i.e
+ * search for the RIGHT parenthesis which closes the current description
+ */
+void NETLIST_READER_KICAD_PARSER::SkipCurrent() throw( IO_ERROR, PARSE_ERROR )
+{
+    int curr_level = 0;
+    while( ( token = NextTok() ) != T_EOF )
+    {
+        if( token == T_LEFT )
+            curr_level--;
+        if( token == T_RIGHT )
+        {
+            curr_level++;
+            if( curr_level > 0 )
+                return;
+        }
+    }
+}
+
+
+void NETLIST_READER_KICAD_PARSER::Parse( BOARD * aBrd )
+    throw( IO_ERROR, PARSE_ERROR )
+{
+    wxString text;
+    while( ( token = NextTok() ) != T_EOF )
+    {
+        if( token == T_LEFT )
+            token = NextTok();
+        if( token == T_components )
+        {
+            // The section comp starts here.
+            while( ( token = NextTok() ) != T_RIGHT )
+            {
+                if( token == T_LEFT )
+                    token = NextTok();
+                if( token == T_comp )
+                {
+                    // A comp section if found. Read it
+                    MODULE_INFO* mod_info = ParseComp();
+                    netlist_reader->AddModuleInfo( mod_info );
+                }
+            }
+            if( netlist_reader->BuildModuleListOnly() )
+                return; // at this point, the module list is read and built.
+            // Load new footprints
+            netlist_reader->InitializeModules();
+            netlist_reader->TestFootprintsMatchingAndExchange();
+        }
+
+        if( token == T_nets )
+        {
+            // The section nets starts here.
+            while( ( token = NextTok() ) != T_RIGHT )
+            {
+                if( token == T_LEFT )
+                    token = NextTok();
+                if( token == T_net )
+                {
+                    // A net section if found. Read it
+                    ParseNet( aBrd );
+                }
+            }
+        }
+    }
+}
+
+void NETLIST_READER_KICAD_PARSER::ParseNet( BOARD * aBrd )
+    throw( IO_ERROR, PARSE_ERROR )
+{
+    /* Parses a section like
+     * (net (code 20) (name /PC-A0)
+     *  (node (ref BUS1) (pin 62))
+     *  (node (ref U3) (pin 3))
+     *  (node (ref U9) (pin M6)))
+     */
+
+    wxString code;
+    wxString name;
+    wxString cmpref;
+    wxString pin;
+    D_PAD * pad = NULL;
+    int nodecount = 0;
+    // The token net was read, so the next data is (code <number>)
+    while( (token = NextTok()) != T_RIGHT )
+    {
+        if( token == T_LEFT )
+            token = NextTok();
+        switch( token )
+        {
+        case T_code:
+            NeedSYMBOLorNUMBER();
+            code = FROM_UTF8( CurText() );
+            NeedRIGHT();
+        break;
+
+        case T_name:
+            NeedSYMBOLorNUMBER();
+            name = FROM_UTF8( CurText() );
+            NeedRIGHT();
+            if( name.IsEmpty() )      // Give a dummy net name like N-000109
+                name = wxT("N-00000") + code;
+            break;
+
+        case T_node:
+            while( (token = NextTok()) != T_RIGHT )
+            {
+                if( token == T_LEFT )
+                    token = NextTok();
+                switch( token )
+                {
+                case T_ref:
+                    NeedSYMBOLorNUMBER();
+                    cmpref = FROM_UTF8( CurText() );
+                    NeedRIGHT();
+                    break;
+
+                case T_pin:
+                    NeedSYMBOLorNUMBER();
+                    pin = FROM_UTF8( CurText() );
+                    NeedRIGHT();
+                    break;
+
+                default:
+                    SkipCurrent();
+                    break;
+                }
+            }
+            pad = netlist_reader->SetPadNetName( cmpref, pin, name );
+            nodecount++;
+            break;
+
+        default:
+            SkipCurrent();
+            break;
+        }
+    }
+
+    // When there is onlu one item in net, clear pad netname
+    if( nodecount < 2 && pad )
+        pad->SetNetname( wxEmptyString );
+}
+
+
+MODULE_INFO* NETLIST_READER_KICAD_PARSER::ParseComp()
+    throw( IO_ERROR, PARSE_ERROR )
+{
+   /* Parses a section like
+     * (comp (ref P1)
+     * (value DB25FEMELLE)
+     * (footprint DB25FC)
+     * (libsource (lib conn) (part DB25))
+     * (sheetpath (names /) (tstamps /))
+     * (tstamp 3256759C))
+     *
+     * other fields (unused) are skipped
+     * A component need a reference, value, foorprint name and a full time stamp
+     * The full time stamp is the sheetpath time stamp + the component time stamp
+     */
+    wxString ref;
+    wxString value;
+    wxString footprint;
+    wxString pathtimestamp, timestamp;
+    // The token comp was read, so the next data is (ref P1)
+
+    while( (token = NextTok()) != T_RIGHT )
+    {
+        if( token == T_LEFT )
+            token = NextTok();
+        switch( token )
+        {
+        case T_ref:
+            NeedSYMBOLorNUMBER();
+            ref = FROM_UTF8( CurText() );
+            NeedRIGHT();
+            break;
+
+        case T_value:
+            NeedSYMBOLorNUMBER();
+            value = FROM_UTF8( CurText() );
+            NeedRIGHT();
+            break;
+
+        case T_footprint:
+            NeedSYMBOLorNUMBER();
+            footprint = FROM_UTF8( CurText() );
+            NeedRIGHT();
+            break;
+
+        case T_libsource:
+            // Currently not used data, skip it
+            SkipCurrent();
+            break;
+
+        case T_sheetpath:
+            while( ( token = NextTok() ) != T_tstamps );
+            NeedSYMBOLorNUMBER();
+            pathtimestamp = FROM_UTF8( CurText() );
+            NeedRIGHT();
+            NeedRIGHT();
+            break;
+
+        case T_tstamp:
+            NeedSYMBOLorNUMBER();
+            timestamp = FROM_UTF8( CurText() );
+            NeedRIGHT();
+            break;
+
+        default:
+            // Skip not used data (i.e all other tokens)
+            SkipCurrent();
+            break;
+        }
+    }
+    pathtimestamp += timestamp;
+    MODULE_INFO* mod_info = new MODULE_INFO( footprint, ref, value, pathtimestamp );
+
+    return mod_info;
+}