kicad/pcbnew/netlist_reader.h

440 lines
16 KiB
C++

#ifndef NETLIST_READER_H
#define NETLIST_READER_H
/**
* @file netlist_reader.h
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Jean-Pierre Charras.
* Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <algorithm>
#include <boost/ptr_container/ptr_vector.hpp>
#include <fctsys.h>
#include <kicad_string.h>
#include <wxPcbStruct.h>
#include <richio.h>
#include <macros.h>
#include <class_board.h>
#include <class_module.h>
#include <pcbnew.h>
/*
* Helper class, to store for a footprint the footprint filter info,
* found in new format KiCad netlist.
* For CvPcb only
* Note: features for CvPcb are for a temporary use.
* They could be removed when CvPcb is modified
* (perhaps when it does not use anumore a netlist to build the component to footprint link)
*/
class LIPBART_INFO
{
public:
wxString m_Libpart; // the libpart name.
wxArrayString m_FootprintFilter; // an array of footprint filters found in netlist,
// for this footprint
public:
LIPBART_INFO( const wxString& aLibpart )
{
m_Libpart = aLibpart;
}
};
typedef std::vector <LIPBART_INFO *> LIPBART_INFO_LIST;
/*
* Helper class, to store components and footprints info found in netlist.
* (component reference and time stamp, footprint name ...
*/
class COMPONENT_INFO
{
public:
wxString m_Footprint; // the footprint name found in netlist, the in .cmp file
wxString m_Reference; // the schematic reference found in netlist
wxString m_Value; // the schematic value found in netlist
wxString m_TimeStamp; // the schematic full time stamp found in netlist
wxString m_Libpart; // the schematic libpart found in netlist
wxArrayString m_FootprintFilter; // a footprint filters list found in old format netlist
int m_pinCount; // the number of pins found in the netlist
public: COMPONENT_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;
m_pinCount = 0;
}
~COMPONENT_INFO() { };
};
enum typenetlist
{
NETLIST_TYPE_UNSPECIFIED = 0,
NETLIST_TYPE_ORCADPCB2, // the basic format used by pcbnew
NETLIST_TYPE_PCBNEW, // the format used by pcbnew, basic format + more info
NETLIST_TYPE_KICAD // new format using common S expression
};
typedef std::vector <COMPONENT_INFO*> COMPONENT_INFO_LIST;
/*
* Helper class, to read a netlist.
*/
class NETLIST_READER
{
private:
PCB_EDIT_FRAME* m_pcbframe; // the main Pcbnew frame (or NULL for CvPcb)
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
COMPONENT_INFO_LIST m_componentsInNetlist; // The list of footprints, found in netlist
// (must be loaded from libraries)
COMPONENT_INFO_LIST m_newModulesList; // The list of new footprints,
// found in netlist, but not on board
// (must be loaded from libraries)
LIPBART_INFO_LIST m_libpartList; // For Kicad new netlist format:
// list of libpart found in netlist
// A libpart contains the footprint filters for CvPcb
bool m_buildModuleListOnly; // if true read netlist, populates m_componentsInNetlist
// but do not read and change nets and modules on board
bool m_readLibpartSection; // if true read Libparts section,
// and therefore the footprints filters
enum typenetlist m_typeNetlist; // type opt the netlist currently read
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;
m_readLibpartSection = false;
m_typeNetlist = NETLIST_TYPE_UNSPECIFIED;
}
~NETLIST_READER()
{
// Free modules info list:
for( unsigned ii = 0; ii < m_newModulesList.size(); ii++ )
delete m_componentsInNetlist[ii];
m_componentsInNetlist.clear();
m_newModulesList.clear();
// Free libpart info list:
for( unsigned ii = 0; ii < m_libpartList.size(); ii++ )
delete m_libpartList[ii];
m_libpartList.clear();
}
/**
* Function GetNetlistType
* @return the type of netlist read:
* NETLIST_TYPE_UNSPECIFIED: Unknown format
* NETLIST_TYPE_ORCADPCB2: the basic format used by pcbnew
* NETLIST_TYPE_PCBNEW: the format used by pcbnew, basic format + more info
* NETLIST_TYPE_KICAD: the new format
*/
int GetNetlistType()
{
return m_typeNetlist;
}
/**
* Function GetComponentInfoList
* @return the component info list built from the netlist
*/
COMPONENT_INFO_LIST& GetComponentInfoList()
{
return m_componentsInNetlist;
}
/**
* Function GetComponentInfoList
* @return a reference to the libpart info corresponding to a given part
* @param aPartname = the name of the libpart
*/
LIPBART_INFO* GetLibpart(const wxString & aPartname);
/**
* Function IsCvPcbMode
* @return true if the netlist is read by CvPcb
* In cvpcb mode, nets are stored in module info,
* and the footprint filters list is read.
* There is also no board in CvPcb
*/
bool IsCvPcbMode() { return m_pcbframe == 0; }
/**
* 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( COMPONENT_INFO* aModInfo )
{
m_componentsInNetlist.push_back( aModInfo );
}
/**
* Function AddLibpartInfo
* LIPBART_INFO items (and therefore footprint filter strings) are stored in
* m_libpartList
* @param aPartInfo = a refernce to the LIPBART_INFO to add in list
*/
void AddLibpartInfo( LIPBART_INFO * aPartInfo )
{
m_libpartList.push_back( aPartInfo );
}
/**
* Function ReadLibpartSectionSetOpt
* Set to true or false the read Partlists section.
* footprint filters are found in this section
* When this option is false, the Partlists section is ignored
* When this option is true, the Partlists section is read,
* Libpart items (and therefore footprint filter strings) are stored in
* m_libpartList
* @param aOpt = the value of option
*/
void ReadLibpartSectionSetOpt( bool aOpt )
{
m_readLibpartSection = aOpt;
}
/**
* Function ReadLibpartSectionOpt
* @return the readPartlist option
*/
bool ReadLibpartSectionOpt() { return m_readLibpartSection; }
/**
* Function BuildModuleListOnlySetOpt
* 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 BuildModuleListOnlySetOpt( bool aOpt )
{
m_buildModuleListOnly = aOpt;
}
/**
* Function BuildModuleListOnlyOpt
* Get the Build Module List Only option state
* @return the state of option (true/false)
*/
bool BuildModuleListOnlyOpt()
{
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 ReadOldFmtFootprintFilterList
* Read the section "Allowed footprints" like:
* { Allowed footprints by component:
* $component R11
* R?
* SM0603
* SM0805
* R?-*
* SM1206
* $endlist
* $endfootprintlist
* }
*
* And add the strings giving the footprint filter to m_FootprintFilter
* of the corresponding module info
* <p>This section is used by CvPcb, and is not useful in Pcbnew,
* therefore it it not always read </p>
*/
bool ReadOldFmtFootprintFilterList( FILE_LINE_READER& aNetlistReader );
/**
* 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 SetPadsNetName
* Update pads netnames for a given module.
* Because a pad name can be found more than once in this module,
* all pads matching the pad name are updated
* @param aModule = module reference
* @param aPadname = pad name (pad num)
* @param aNetname = new net name of the pad
* @param aPadList = a std::vector<D_PAD*>& buffer where the updated pads can be stored
* @return the pad count
*/
int SetPadsNetName( const wxString & aModule, const wxString & aPadname,
const wxString & aNetname, std::vector<D_PAD*> & aPadList );
private:
/**
* Function FindModule
* search for a module id the modules existing in the current BOARD.
* @param aId = the key to identify the module to find:
* The reference or the full time stamp, according to m_UseTimeStamp
* @return the module found, or NULL.
*/
MODULE* FindModule( const wxString& aId );
/**
* Function SetPadNetName
* Update a pad netname using the current footprint
* from the netlist (line format: ( \<pad number\> \<net name\> ) )
* @param aText = current line read from netlist
*/
bool SetPadNetName( char* aText );
/**
* Function ReadOldFmtNetlistModuleDescr
* Read the full description of a footprint, from the netlist
* and update the corresponding module.
* @param aBuildList bool to switch between 2 modes:
* aBuildList = true:
* add module info added to m_newModulesList
* aBuildList = false:
* The module is searched in the board modules list
* @param aText contains the first line of description
* This function uses m_useFichCmp as a flag to know the footprint name:
* If true: component file *.cmp is used
* If false: the netlist only is used
* This flag is reset to false if the .cmp file is not found
* @return if aBuildList = true, a reference to the COMPONENT_INFO
* if aBuildList = false, a reference to the corresponding MODULE on board (NULL if not found)
*/
void* 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_componentsInNetlist,
* 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