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.

399 lines
12 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. protected:
  100. NETLIST* m_netlist; ///< The net list to read the file(s) into.
  101. bool m_loadFootprintFilters; ///< Load the component footprint filters section if true.
  102. bool m_loadNets; ///< Load the nets section of the netlist file if true.
  103. LINE_READER* m_lineReader; ///< The line reader of the netlist.
  104. /// The reader used to load the footprint links. If NULL, footprint links are not read.
  105. CMP_READER* m_footprintReader;
  106. public:
  107. enum NETLIST_FILE_T
  108. {
  109. UNKNOWN = -1,
  110. ORCAD,
  111. LEGACY,
  112. KICAD,
  113. // Add new types here. Don't forget to create the appropriate class derived from
  114. // NETCLASS_READER and add the entry to the NETLIST_READER::GetNetlistReader()
  115. // function.
  116. };
  117. NETLIST_READER( LINE_READER* aLineReader,
  118. NETLIST* aNetlist,
  119. CMP_READER* aFootprintLinkReader = NULL )
  120. {
  121. wxASSERT( aLineReader != NULL );
  122. m_lineReader = aLineReader;
  123. m_footprintReader = aFootprintLinkReader;
  124. m_netlist = aNetlist;
  125. m_loadFootprintFilters = true;
  126. m_loadNets = true;
  127. }
  128. virtual ~NETLIST_READER();
  129. /**
  130. * Function GuessNetlistFileType
  131. * looks at \a aFileHeaderLine to see if it matches any of the netlist file types it
  132. * knows about.
  133. *
  134. * @param aLineReader is the #LINE_READER object containing lines from the netlist to test.
  135. * @return the #NETLIST_FILE_T of \a aLineReader.
  136. */
  137. static NETLIST_FILE_T GuessNetlistFileType( LINE_READER* aLineReader );
  138. /**
  139. * Function GetNetlistReader
  140. * attempts to determine the net list file type of \a aNetlistFileName and return the
  141. * appropriate NETLIST_READER type.
  142. *
  143. * @param aNetlist is the netlist to load \a aNetlistFileName into.
  144. * @param aNetlistFileName is the full path and file name of the net list to read.
  145. * @param aCompFootprintFileName is the full path and file name of the component footprint
  146. * associations to read. Set to wxEmptyString if loading the
  147. * footprint association file is not required.
  148. * @return the appropriate NETLIST_READER if \a aNetlistFileName is a valid netlist or
  149. * NULL if \a aNetlistFileName is not a valid netlist files.
  150. */
  151. static NETLIST_READER* GetNetlistReader( NETLIST* aNetlist,
  152. const wxString& aNetlistFileName,
  153. const wxString& aCompFootprintFileName = wxEmptyString )
  154. throw( IO_ERROR );
  155. /**
  156. * Function LoadNetlist
  157. * loads the contents of the netlist file into \a aNetlist.
  158. *
  159. * @throw IO_ERROR if a file IO error occurs.
  160. * @throw PARSE_ERROR if an error occurs while parsing the file.
  161. */
  162. virtual void LoadNetlist() throw( IO_ERROR, PARSE_ERROR, boost::bad_pointer ) = 0;
  163. /**
  164. * Function GetLineReader()
  165. * @return the #LINE_READER associated with the #NETLIST_READER.
  166. */
  167. LINE_READER* GetLineReader();
  168. };
  169. /**
  170. * Class LEGACY_NETLIST_READER
  171. * reads the KiCad legacy and the old Orcad netlist formats.
  172. *
  173. * The KiCad legacy netlist format was derived directly from an old Orcad netlist format. The
  174. * primary difference is the header was changed so this reader can read both formats.
  175. */
  176. class LEGACY_NETLIST_READER : public NETLIST_READER
  177. {
  178. /**
  179. * Function loadComponent
  180. * read the \a aLine containing the description of a component from a legacy format
  181. * netlist and add it to the netlist.
  182. *
  183. * Analyze the first line of a component description in netlist:
  184. * ( /40C08647 $noname R20 4.7K {Lib=R}
  185. *
  186. * @param aText contains the first line of description
  187. * @return the new component created by parsing \a aLine
  188. * @throw PARSE_ERROR when \a aLine is not a valid component description.
  189. */
  190. COMPONENT* loadComponent( char* aText ) throw( PARSE_ERROR, boost::bad_pointer );
  191. /**
  192. * Function loadFootprintFilters
  193. * loads the footprint filter section of netlist file.
  194. *
  195. * Sample legacy footprint filter section:
  196. * { Allowed footprints by component:
  197. * $component R11
  198. * R?
  199. * SM0603
  200. * SM0805
  201. * R?-*
  202. * SM1206
  203. * $endlist
  204. * $endfootprintlist
  205. * }
  206. *
  207. * @throw IO_ERROR if a file IO error occurs.
  208. * @throw PARSE_ERROR if an error occurs while parsing the file.
  209. */
  210. void loadFootprintFilters() throw( IO_ERROR, PARSE_ERROR );
  211. /**
  212. * Function loadNet
  213. * read a component net description from \a aText.
  214. *
  215. * @param aText is current line read from the netlist.
  216. * @param aComponent is the component to add the net to.
  217. * @throw PARSE_ERROR if a error occurs reading \a aText.
  218. */
  219. void loadNet( char* aText, COMPONENT* aComponent ) throw( PARSE_ERROR );
  220. public:
  221. LEGACY_NETLIST_READER( LINE_READER* aLineReader,
  222. NETLIST* aNetlist,
  223. CMP_READER* aFootprintLinkReader = NULL ) :
  224. NETLIST_READER( aLineReader, aNetlist, aFootprintLinkReader )
  225. {
  226. }
  227. /**
  228. * Function LoadNetlist
  229. * read the netlist file in the legacy format into \a aNetlist.
  230. *
  231. * The legacy netlist format is:
  232. * \# EESchema Netlist Version 1.0 generee le 18/5/2005-12:30:22
  233. * (
  234. * ( 40C08647 $noname R20 4,7K {Lib=R}
  235. * ( 1 VCC )
  236. * ( 2 MODB_1 )
  237. * )
  238. * ( 40C0863F $noname R18 4,7_k {Lib=R}
  239. * ( 1 VCC )
  240. * ( 2 MODA_1 )
  241. * )
  242. * }
  243. * \#End
  244. *
  245. * @throw IO_ERROR if a file IO error occurs.
  246. * @throw PARSE_ERROR if an error occurs while parsing the file.
  247. */
  248. virtual void LoadNetlist() throw ( IO_ERROR, PARSE_ERROR, boost::bad_pointer );
  249. };
  250. /**
  251. * Class KICAD_NETLIST_PARSER
  252. * is the parser for reading the KiCad s-expression netlist format.
  253. */
  254. class KICAD_NETLIST_PARSER : public NETLIST_LEXER
  255. {
  256. private:
  257. NL_T::T token;
  258. LINE_READER* m_lineReader; ///< The line reader used to parse the netlist. Not owned.
  259. NETLIST* m_netlist; ///< The netlist to parse into. Not owned.
  260. /**
  261. * Function skipCurrent
  262. * Skip the current token level, i.e
  263. * search for the RIGHT parenthesis which closes the current description
  264. */
  265. void skipCurrent() throw( IO_ERROR, PARSE_ERROR );
  266. /**
  267. * Function parseComponent
  268. * parse a component description:
  269. * (comp (ref P1)
  270. * (value DB25FEMELLE)
  271. * (footprint DB25FC)
  272. * (libsource (lib conn) (part DB25))
  273. * (sheetpath (names /) (tstamps /))
  274. * (tstamp 3256759C))
  275. */
  276. void parseComponent() throw( IO_ERROR, PARSE_ERROR, boost::bad_pointer );
  277. /**
  278. * Function parseNet
  279. * Parses a section like
  280. * (net (code 20) (name /PC-A0)
  281. * (node (ref BUS1) (pin 62))
  282. * (node (ref U3) (pin 3))
  283. * (node (ref U9) (pin M6)))
  284. *
  285. * and set the corresponding pads netnames
  286. */
  287. void parseNet() throw( IO_ERROR, PARSE_ERROR );
  288. /**
  289. * Function parseLibPartList
  290. * reads the section "libparts" in the netlist:
  291. * (libparts
  292. * (libpart (lib device) (part C)
  293. * (description "Condensateur non polarise")
  294. * (footprints
  295. * (fp SM*)
  296. * (fp C?)
  297. * (fp C1-1))
  298. * (fields
  299. * (field (name Reference) C)
  300. * (field (name Value) C))
  301. * (pins
  302. * (pin (num 1) (name ~) (type passive))
  303. * (pin (num 2) (name ~) (type passive))))
  304. *
  305. * And add the strings giving the footprint filter (subsection footprints)
  306. * of the corresponding module info
  307. * <p>This section is used by CvPcb, and is not useful in Pcbnew,
  308. * therefore it it not always read </p>
  309. */
  310. void parseLibPartList() throw( IO_ERROR, PARSE_ERROR );
  311. public:
  312. KICAD_NETLIST_PARSER( LINE_READER* aReader, NETLIST* aNetlist );
  313. void SetLineReader( LINE_READER* aLineReader );
  314. void SetNetlist( NETLIST* aNetlist ) { m_netlist = aNetlist; }
  315. /**
  316. * Function Parse
  317. * parse the full netlist
  318. */
  319. void Parse() throw( IO_ERROR, PARSE_ERROR, boost::bad_pointer );
  320. // Useful for debug only:
  321. const char* getTokenName( NL_T::T aTok )
  322. {
  323. return NETLIST_LEXER::TokenName( aTok );
  324. }
  325. };
  326. /**
  327. * Class KICAD_NETLIST_READER
  328. * read the new s-expression based KiCad netlist format.
  329. */
  330. class KICAD_NETLIST_READER : public NETLIST_READER
  331. {
  332. KICAD_NETLIST_PARSER* m_parser; ///< The s-expression format parser.
  333. public:
  334. KICAD_NETLIST_READER( LINE_READER* aLineReader,
  335. NETLIST* aNetlist,
  336. CMP_READER* aFootprintLinkReader = NULL ) :
  337. NETLIST_READER( aLineReader, aNetlist, aFootprintLinkReader ),
  338. m_parser( new KICAD_NETLIST_PARSER( aLineReader, aNetlist ) )
  339. {
  340. }
  341. virtual ~KICAD_NETLIST_READER()
  342. {
  343. if( m_parser )
  344. delete m_parser;
  345. }
  346. virtual void LoadNetlist() throw ( IO_ERROR, PARSE_ERROR, boost::bad_pointer );
  347. };
  348. #endif // NETLIST_READER_H