You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

404 lines
13 KiB

  1. #ifndef NETLIST_READER_H
  2. #define NETLIST_READER_H
  3. /**
  4. * @file netlist_reader.h
  5. */
  6. /*
  7. * This program source code file is part of KiCad, a free EDA CAD application.
  8. *
  9. * Copyright (C) 2012 Jean-Pierre Charras.
  10. * Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>.
  11. * Copyright (C) 2012-2015 KiCad Developers, see CHANGELOG.TXT for contributors.
  12. *
  13. * This program is free software; you can redistribute it and/or
  14. * modify it under the terms of the GNU General Public License
  15. * as published by the Free Software Foundation; either version 2
  16. * of the License, or (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, you may find one here:
  25. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  26. * or you may search the http://www.gnu.org website for the version 2 license,
  27. * or you may write to the Free Software Foundation, Inc.,
  28. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  29. */
  30. #include <boost/ptr_container/ptr_vector.hpp>
  31. #include <fctsys.h>
  32. #include <macros.h>
  33. #include <fpid.h>
  34. #include <netlist_lexer.h> // netlist_lexer is common to Eeschema and Pcbnew
  35. class NETLIST;
  36. class COMPONENT;
  37. /**
  38. * Class CMP_READER
  39. * reads a component footprint link file (*.cmp) format.
  40. */
  41. class CMP_READER
  42. {
  43. LINE_READER* m_lineReader; ///< The line reader to read.
  44. public:
  45. /**
  46. * CMP_READER constructor.
  47. * @param aLineReader is a LINE_READER (in fact a FILE_LINE_READER)
  48. * which is owned by me ( and deleted by me) to read
  49. * the component footprint link file.
  50. */
  51. CMP_READER( LINE_READER* aLineReader )
  52. {
  53. m_lineReader = aLineReader;
  54. }
  55. ~CMP_READER()
  56. {
  57. if( m_lineReader )
  58. {
  59. delete m_lineReader;
  60. m_lineReader = NULL;
  61. }
  62. }
  63. /**
  64. * Function Load
  65. * read the *.cmp file format contains the component footprint assignments created by CvPcb
  66. * into \a aNetlist.
  67. *
  68. * @param aNetlist is the #NETLIST to read into.
  69. *
  70. * @todo At some point in the future, use the footprint field in the new s-expression
  71. * netlist file to assign a footprint to a component instead of using a secondary
  72. * (*.cmp) file.
  73. *
  74. * Sample file footprint assignment entry:
  75. *
  76. * Cmp-Mod V01 Genere by CvPcb 29/10/2003-13: 11:6 *
  77. * BeginCmp
  78. * TimeStamp = /32307DE2/AA450F67;
  79. * Reference = C1;
  80. * ValeurCmp = 47uF;
  81. * IdModule = CP6;
  82. * EndCmp
  83. *
  84. * @throw IO_ERROR if a the #LINE_READER IO error occurs.
  85. * @throw PARSE_ERROR if an error occurs while parsing the file.
  86. * @return true if OK, false if a component reference found in the
  87. * .cmp file is not found in netlist, which means the .cmp file
  88. * is not updated. This is an usual case, in CvPcb, but can be used to
  89. * print a warning in Pcbnew.
  90. */
  91. bool Load( NETLIST* aNetlist ) throw( IO_ERROR, PARSE_ERROR );
  92. };
  93. /**
  94. * Class NETLIST_READER
  95. * is a pure virtual class to derive a specific type of netlist reader from.
  96. */
  97. class NETLIST_READER
  98. {
  99. public:
  100. enum NETLIST_FILE_T
  101. {
  102. UNKNOWN = -1,
  103. ORCAD,
  104. LEGACY,
  105. KICAD,
  106. // Add new types here. Don't forget to create the appropriate class derived from
  107. // NETCLASS_READER and add the entry to the NETLIST_READER::GetNetlistReader()
  108. // function.
  109. };
  110. /**
  111. * Constructor
  112. * @param aLineReader ownership is taken of this LINE_READER.
  113. * @param aFootprintLinkReader ownership is taken of this CMP_READER.
  114. */
  115. NETLIST_READER( LINE_READER* aLineReader,
  116. NETLIST* aNetlist,
  117. CMP_READER* aFootprintLinkReader = NULL )
  118. {
  119. wxASSERT( aLineReader != NULL );
  120. m_lineReader = aLineReader;
  121. m_footprintReader = aFootprintLinkReader;
  122. m_netlist = aNetlist;
  123. m_loadFootprintFilters = true;
  124. m_loadNets = true;
  125. }
  126. virtual ~NETLIST_READER();
  127. /**
  128. * Function GuessNetlistFileType
  129. * looks at \a aFileHeaderLine to see if it matches any of the netlist file types it
  130. * knows about.
  131. *
  132. * @param aLineReader is the #LINE_READER object containing lines from the netlist to test.
  133. * @return the #NETLIST_FILE_T of \a aLineReader.
  134. */
  135. static NETLIST_FILE_T GuessNetlistFileType( LINE_READER* aLineReader );
  136. /**
  137. * Function GetNetlistReader
  138. * attempts to determine the net list file type of \a aNetlistFileName and return the
  139. * appropriate NETLIST_READER type.
  140. *
  141. * @param aNetlist is the netlist to load \a aNetlistFileName into.
  142. * @param aNetlistFileName is the full path and file name of the net list to read.
  143. * @param aCompFootprintFileName is the full path and file name of the component footprint
  144. * associations to read. Set to wxEmptyString if loading the
  145. * footprint association file is not required.
  146. * @return the appropriate NETLIST_READER if \a aNetlistFileName is a valid netlist or
  147. * NULL if \a aNetlistFileName is not a valid netlist files.
  148. */
  149. static NETLIST_READER* GetNetlistReader( NETLIST* aNetlist,
  150. const wxString& aNetlistFileName,
  151. const wxString& aCompFootprintFileName = wxEmptyString )
  152. throw( IO_ERROR );
  153. /**
  154. * Function LoadNetlist
  155. * loads the contents of the netlist file into \a aNetlist.
  156. *
  157. * @throw IO_ERROR if a file IO error occurs.
  158. * @throw PARSE_ERROR if an error occurs while parsing the file.
  159. */
  160. virtual void LoadNetlist() throw( IO_ERROR, PARSE_ERROR, boost::bad_pointer ) = 0;
  161. /**
  162. * Function GetLineReader()
  163. * @return the #LINE_READER associated with the #NETLIST_READER.
  164. */
  165. LINE_READER* GetLineReader();
  166. protected:
  167. NETLIST* m_netlist; ///< The net list to read the file(s) into.
  168. bool m_loadFootprintFilters; ///< Load the component footprint filters section if true.
  169. bool m_loadNets; ///< Load the nets section of the netlist file if true.
  170. LINE_READER* m_lineReader; ///< The line reader of the netlist.
  171. /// The reader used to load the footprint links. If NULL, footprint links are not read.
  172. CMP_READER* m_footprintReader;
  173. };
  174. /**
  175. * Class LEGACY_NETLIST_READER
  176. * reads the KiCad legacy and the old Orcad netlist formats.
  177. *
  178. * The KiCad legacy netlist format was derived directly from an old Orcad netlist format. The
  179. * primary difference is the header was changed so this reader can read both formats.
  180. */
  181. class LEGACY_NETLIST_READER : public NETLIST_READER
  182. {
  183. /**
  184. * Function loadComponent
  185. * read the \a aLine containing the description of a component from a legacy format
  186. * netlist and add it to the netlist.
  187. *
  188. * Analyze the first line of a component description in netlist:
  189. * ( /40C08647 $noname R20 4.7K {Lib=R}
  190. *
  191. * @param aText contains the first line of description
  192. * @return the new component created by parsing \a aLine
  193. * @throw PARSE_ERROR when \a aLine is not a valid component description.
  194. */
  195. COMPONENT* loadComponent( char* aText ) throw( PARSE_ERROR, boost::bad_pointer );
  196. /**
  197. * Function loadFootprintFilters
  198. * loads the footprint filter section of netlist file.
  199. *
  200. * Sample legacy footprint filter section:
  201. * { Allowed footprints by component:
  202. * $component R11
  203. * R?
  204. * SM0603
  205. * SM0805
  206. * R?-*
  207. * SM1206
  208. * $endlist
  209. * $endfootprintlist
  210. * }
  211. *
  212. * @throw IO_ERROR if a file IO error occurs.
  213. * @throw PARSE_ERROR if an error occurs while parsing the file.
  214. */
  215. void loadFootprintFilters() throw( IO_ERROR, PARSE_ERROR );
  216. /**
  217. * Function loadNet
  218. * read a component net description from \a aText.
  219. *
  220. * @param aText is current line read from the netlist.
  221. * @param aComponent is the component to add the net to.
  222. * @throw PARSE_ERROR if a error occurs reading \a aText.
  223. */
  224. void loadNet( char* aText, COMPONENT* aComponent ) throw( PARSE_ERROR );
  225. public:
  226. LEGACY_NETLIST_READER( LINE_READER* aLineReader,
  227. NETLIST* aNetlist,
  228. CMP_READER* aFootprintLinkReader = NULL ) :
  229. NETLIST_READER( aLineReader, aNetlist, aFootprintLinkReader )
  230. {
  231. }
  232. /**
  233. * Function LoadNetlist
  234. * read the netlist file in the legacy format into \a aNetlist.
  235. *
  236. * The legacy netlist format is:
  237. * \# EESchema Netlist Version 1.0 generee le 18/5/2005-12:30:22
  238. * (
  239. * ( 40C08647 $noname R20 4,7K {Lib=R}
  240. * ( 1 VCC )
  241. * ( 2 MODB_1 )
  242. * )
  243. * ( 40C0863F $noname R18 4,7_k {Lib=R}
  244. * ( 1 VCC )
  245. * ( 2 MODA_1 )
  246. * )
  247. * }
  248. * \#End
  249. *
  250. * @throw IO_ERROR if a file IO error occurs.
  251. * @throw PARSE_ERROR if an error occurs while parsing the file.
  252. */
  253. virtual void LoadNetlist() throw ( IO_ERROR, PARSE_ERROR, boost::bad_pointer );
  254. };
  255. /**
  256. * Class KICAD_NETLIST_PARSER
  257. * is the parser for reading the KiCad s-expression netlist format.
  258. */
  259. class KICAD_NETLIST_PARSER : public NETLIST_LEXER
  260. {
  261. private:
  262. NL_T::T token;
  263. LINE_READER* m_lineReader; ///< The line reader used to parse the netlist. Not owned.
  264. NETLIST* m_netlist; ///< The netlist to parse into. Not owned.
  265. /**
  266. * Function skipCurrent
  267. * Skip the current token level, i.e
  268. * search for the RIGHT parenthesis which closes the current description
  269. */
  270. void skipCurrent() throw( IO_ERROR, PARSE_ERROR );
  271. /**
  272. * Function parseComponent
  273. * parse a component description:
  274. * (comp (ref P1)
  275. * (value DB25FEMELLE)
  276. * (footprint DB25FC)
  277. * (libsource (lib conn) (part DB25))
  278. * (sheetpath (names /) (tstamps /))
  279. * (tstamp 3256759C))
  280. */
  281. void parseComponent() throw( IO_ERROR, PARSE_ERROR, boost::bad_pointer );
  282. /**
  283. * Function parseNet
  284. * Parses a section like
  285. * (net (code 20) (name /PC-A0)
  286. * (node (ref BUS1) (pin 62))
  287. * (node (ref U3) (pin 3))
  288. * (node (ref U9) (pin M6)))
  289. *
  290. * and set the corresponding pads netnames
  291. */
  292. void parseNet() throw( IO_ERROR, PARSE_ERROR );
  293. /**
  294. * Function parseLibPartList
  295. * reads the section "libparts" in the netlist:
  296. * (libparts
  297. * (libpart (lib device) (part C)
  298. * (description "Condensateur non polarise")
  299. * (footprints
  300. * (fp SM*)
  301. * (fp C?)
  302. * (fp C1-1))
  303. * (fields
  304. * (field (name Reference) C)
  305. * (field (name Value) C))
  306. * (pins
  307. * (pin (num 1) (name ~) (type passive))
  308. * (pin (num 2) (name ~) (type passive))))
  309. *
  310. * And add the strings giving the footprint filter (subsection footprints)
  311. * of the corresponding module info
  312. * <p>This section is used by CvPcb, and is not useful in Pcbnew,
  313. * therefore it it not always read </p>
  314. */
  315. void parseLibPartList() throw( IO_ERROR, PARSE_ERROR );
  316. public:
  317. KICAD_NETLIST_PARSER( LINE_READER* aReader, NETLIST* aNetlist );
  318. void SetLineReader( LINE_READER* aLineReader );
  319. void SetNetlist( NETLIST* aNetlist ) { m_netlist = aNetlist; }
  320. /**
  321. * Function Parse
  322. * parse the full netlist
  323. */
  324. void Parse() throw( IO_ERROR, PARSE_ERROR, boost::bad_pointer );
  325. // Useful for debug only:
  326. const char* getTokenName( NL_T::T aTok )
  327. {
  328. return NETLIST_LEXER::TokenName( aTok );
  329. }
  330. };
  331. /**
  332. * Class KICAD_NETLIST_READER
  333. * read the new s-expression based KiCad netlist format.
  334. */
  335. class KICAD_NETLIST_READER : public NETLIST_READER
  336. {
  337. KICAD_NETLIST_PARSER* m_parser; ///< The s-expression format parser.
  338. public:
  339. KICAD_NETLIST_READER( LINE_READER* aLineReader,
  340. NETLIST* aNetlist,
  341. CMP_READER* aFootprintLinkReader = NULL ) :
  342. NETLIST_READER( aLineReader, aNetlist, aFootprintLinkReader ),
  343. m_parser( new KICAD_NETLIST_PARSER( aLineReader, aNetlist ) )
  344. {
  345. }
  346. virtual ~KICAD_NETLIST_READER()
  347. {
  348. delete m_parser;
  349. }
  350. virtual void LoadNetlist() throw ( IO_ERROR, PARSE_ERROR, boost::bad_pointer );
  351. };
  352. #endif // NETLIST_READER_H