From 7eb1a136f1f8dc119df9eb34c4bb24da303d672b Mon Sep 17 00:00:00 2001 From: jean-pierre charras 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 +================================================================================ +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 ================================================================================ 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= - - If you want to uninstall KiCad again type "make uninstall" from within the -build directory. - - -Important parameters to cmake ------------------------------ - --DCMAKE_BUILD_TYPE= - may current one of "Debug" and "Release". - --DCMAKE_INSTALL_PREFIX= -Default to "/usr/local". - --DwxWidgets_ROOT_DIR= -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= -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 - - #include // also nests: #include @@ -57,13 +55,6 @@ #include -/** - * @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 to reduce code volume @@ -196,7 +188,7 @@ class EXPORT_HELP * - 6 CA *

*/ - 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 // 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 + *
    + *
  • test for some issues (missing or duplicate references and sheet names) + *
  • build netlist info + *
  • create the netlist file (different formats) + *
* @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. + *

+ * 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 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. + *

+ * 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 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 #include @@ -40,157 +64,10 @@ #include #include - #include #include - -// 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 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: ( \ \ ) ) - * @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 /** @@ -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: ( ) - * 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 & 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 + +#include +#include +#include +#include +#include + +#include +#include +#include + + +/* + * 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 m_modulesInNetlist; // The list of footprints, found in netlist + // (must be loaded from libraries) + std::vector 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 & 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: ( \ \ ) ) + * @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 +#include +#include +#include + +#include +#include +#include + +#include + +// 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: ( = ) + * 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 +#include // netlist_lexer is common to Eeschema and Pcbnew +#include + +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 ) + 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; +}