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.

374 lines
12 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2012 CERN
  5. * Copyright (C) 2012-2019 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. /**
  25. * @file pcb_parser.h
  26. * @brief Pcbnew s-expression file format parser definition.
  27. */
  28. #ifndef _PCBNEW_PARSER_H_
  29. #define _PCBNEW_PARSER_H_
  30. #include <convert_to_biu.h> // IU_PER_MM
  31. #include <hashtables.h>
  32. #include <layers_id_colors_and_visibility.h> // PCB_LAYER_ID
  33. #include <math/util.h> // KiROUND, Clamp
  34. #include <pcb_lexer.h>
  35. #include <unordered_map>
  36. class ARC;
  37. class BOARD;
  38. class BOARD_ITEM;
  39. class BOARD_ITEM_CONTAINER;
  40. class D_PAD;
  41. class BOARD_DESIGN_SETTINGS;
  42. class DIMENSION;
  43. class DRAWSEGMENT;
  44. class EDA_TEXT;
  45. class EDGE_MODULE;
  46. class TEXTE_MODULE;
  47. class TEXTE_PCB;
  48. class TRACK;
  49. class MODULE;
  50. class PCB_TARGET;
  51. class VIA;
  52. class ZONE_CONTAINER;
  53. class MARKER_PCB;
  54. class MODULE_3D_SETTINGS;
  55. struct LAYER;
  56. /**
  57. * PCB_PARSER
  58. * reads a Pcbnew s-expression formatted #LINE_READER object and returns the appropriate
  59. * #BOARD_ITEM object.
  60. */
  61. class PCB_PARSER : public PCB_LEXER
  62. {
  63. typedef std::unordered_map< std::string, PCB_LAYER_ID > LAYER_ID_MAP;
  64. typedef std::unordered_map< std::string, LSET > LSET_MAP;
  65. BOARD* m_board;
  66. LAYER_ID_MAP m_layerIndices; ///< map layer name to it's index
  67. LSET_MAP m_layerMasks; ///< map layer names to their masks
  68. std::set<wxString> m_undefinedLayers; ///< set of layers not defined in layers section
  69. std::vector<int> m_netCodes; ///< net codes mapping for boards being loaded
  70. bool m_tooRecent; ///< true if version parses as later than supported
  71. int m_requiredVersion; ///< set to the KiCad format version this board requires
  72. bool m_showLegacyZoneWarning;
  73. ///> Converts net code using the mapping table if available,
  74. ///> otherwise returns unchanged net code if < 0 or if is is out of range
  75. inline int getNetCode( int aNetCode )
  76. {
  77. if( ( aNetCode >= 0 ) && ( aNetCode < (int) m_netCodes.size() ) )
  78. return m_netCodes[aNetCode];
  79. return aNetCode;
  80. }
  81. /**
  82. * function pushValueIntoMap
  83. * Add aValue value in netcode mapping (m_netCodes) at index aIndex
  84. * ensure there is room in m_netCodes for that, and add room if needed.
  85. * @param aIndex = the index ( expected >=0 )of the location to use in m_netCodes
  86. * @param aValue = the netcode value to map
  87. */
  88. void pushValueIntoMap( int aIndex, int aValue );
  89. /**
  90. * Function init
  91. * clears and re-establishes m_layerMap with the default layer names.
  92. * m_layerMap will have some of its entries overwritten whenever a (new) board
  93. * is encountered.
  94. */
  95. void init();
  96. /**
  97. * Creates a mapping from the (short-lived) bug where layer names were translated
  98. * TODO: Remove this once we support custom layer names
  99. *
  100. * @param aMap string mapping from translated to English layer names
  101. */
  102. void createOldLayerMapping( std::unordered_map< std::string, std::string >& aMap );
  103. /**
  104. * Function skipCurrent
  105. * Skip the current token level, i.e
  106. * search for the RIGHT parenthesis which closes the current description
  107. */
  108. void skipCurrent();
  109. void parseHeader();
  110. void parseGeneralSection();
  111. void parsePAGE_INFO();
  112. void parseTITLE_BLOCK();
  113. void parseLayers();
  114. void parseLayer( LAYER* aLayer );
  115. void parseBoardStackup();
  116. void parseSetup();
  117. void parseDefaults( BOARD_DESIGN_SETTINGS& aSettings );
  118. void parseDefaultTextDims( BOARD_DESIGN_SETTINGS& aSettings, int aLayer );
  119. void parseNETINFO_ITEM();
  120. void parseNETCLASS();
  121. /** Read a DRAWSEGMENT description.
  122. * @param aAllowCirclesZeroWidth = true to allow items with 0 width
  123. * Only used in custom pad shapes for filled circles.
  124. */
  125. DRAWSEGMENT* parseDRAWSEGMENT( bool aAllowCirclesZeroWidth = false );
  126. TEXTE_PCB* parseTEXTE_PCB();
  127. DIMENSION* parseDIMENSION();
  128. /**
  129. * Function parseMODULE_unchecked
  130. * Parse a module, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR automatically.
  131. */
  132. MODULE* parseMODULE_unchecked( wxArrayString* aInitialComments = 0 );
  133. TEXTE_MODULE* parseTEXTE_MODULE();
  134. EDGE_MODULE* parseEDGE_MODULE();
  135. D_PAD* parseD_PAD( MODULE* aParent = NULL );
  136. // Parse only the (option ...) inside a pad description
  137. bool parseD_PAD_option( D_PAD* aPad );
  138. ARC* parseARC();
  139. TRACK* parseTRACK();
  140. VIA* parseVIA();
  141. ZONE_CONTAINER* parseZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent );
  142. PCB_TARGET* parsePCB_TARGET();
  143. MARKER_PCB* parseMARKER( BOARD_ITEM_CONTAINER* aParent );
  144. BOARD* parseBOARD();
  145. /**
  146. * Function parseBOARD_unchecked
  147. * Parse a module, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR automatically.
  148. */
  149. BOARD* parseBOARD_unchecked();
  150. /**
  151. * Function lookUpLayer
  152. * parses the current token for the layer definition of a #BOARD_ITEM object.
  153. *
  154. * @param aMap is the LAYER_{NUM|MSK}_MAP to use for the lookup.
  155. *
  156. * @throw IO_ERROR if the layer is not valid.
  157. * @throw PARSE_ERROR if the layer syntax is incorrect.
  158. * @return int - The result of the parsed #BOARD_ITEM layer or set designator.
  159. */
  160. template<class T, class M>
  161. T lookUpLayer( const M& aMap );
  162. /**
  163. * Function parseBoardItemLayer
  164. * parses the layer definition of a #BOARD_ITEM object.
  165. *
  166. * @throw IO_ERROR if the layer is not valid.
  167. * @throw PARSE_ERROR if the layer syntax is incorrect.
  168. * @return The index the parsed #BOARD_ITEM layer.
  169. */
  170. PCB_LAYER_ID parseBoardItemLayer();
  171. /**
  172. * Function parseBoardItemLayersAsMask
  173. * parses the layers definition of a #BOARD_ITEM object.
  174. *
  175. * @throw IO_ERROR if any of the layers is not valid.
  176. * @throw PARSE_ERROR if the layers syntax is incorrect.
  177. * @return The mask of layers the parsed #BOARD_ITEM is on.
  178. */
  179. LSET parseBoardItemLayersAsMask();
  180. /**
  181. * Function parseXY
  182. * parses a coordinate pair (xy X Y) in board units (mm).
  183. *
  184. * The parser checks if the previous token was T_LEFT and parses the remainder of
  185. * the token syntax. This is used when parsing a list of coordinate points. This
  186. * way the parser can be used in either case.
  187. *
  188. * @throw PARSE_ERROR if the coordinate pair syntax is incorrect.
  189. * @return A wxPoint object containing the coordinate pair.
  190. */
  191. wxPoint parseXY();
  192. void parseXY( int* aX, int* aY );
  193. /**
  194. * Function parseEDA_TEXT
  195. * parses the common settings for any object derived from #EDA_TEXT.
  196. *
  197. * @throw PARSE_ERROR if the text syntax is not valid.
  198. * @param aText A point to the #EDA_TEXT object to save the parsed settings into.
  199. */
  200. void parseEDA_TEXT( EDA_TEXT* aText );
  201. MODULE_3D_SETTINGS* parse3DModel();
  202. /**
  203. * Function parseDouble
  204. * parses the current token as an ASCII numeric string with possible leading
  205. * whitespace into a double precision floating point number.
  206. *
  207. * @throw IO_ERROR if an error occurs attempting to convert the current token.
  208. * @return The result of the parsed token.
  209. */
  210. double parseDouble();
  211. inline double parseDouble( const char* aExpected )
  212. {
  213. NeedNUMBER( aExpected );
  214. return parseDouble();
  215. }
  216. inline double parseDouble( PCB_KEYS_T::T aToken )
  217. {
  218. return parseDouble( GetTokenText( aToken ) );
  219. }
  220. inline int parseBoardUnits()
  221. {
  222. // There should be no major rounding issues here, since the values in
  223. // the file are in mm and get converted to nano-meters.
  224. // See test program tools/test-nm-biu-to-ascii-mm-round-tripping.cpp
  225. // to confirm or experiment. Use a similar strategy in both places, here
  226. // and in the test program. Make that program with:
  227. // $ make test-nm-biu-to-ascii-mm-round-tripping
  228. auto retval = parseDouble() * IU_PER_MM;
  229. // N.B. we currently represent board units as integers. Any values that are
  230. // larger or smaller than those board units represent undefined behavior for
  231. // the system. We limit values to the largest that is visible on the screen
  232. // This is the diagonal distance of the full screen ~1.5m
  233. double int_limit = std::numeric_limits<int>::max() * 0.7071; // 0.7071 = roughly 1/sqrt(2)
  234. return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
  235. }
  236. inline int parseBoardUnits( const char* aExpected )
  237. {
  238. auto retval = parseDouble( aExpected ) * IU_PER_MM;
  239. // N.B. we currently represent board units as integers. Any values that are
  240. // larger or smaller than those board units represent undefined behavior for
  241. // the system. We limit values to the largest that is visible on the screen
  242. double int_limit = std::numeric_limits<int>::max() * 0.7071;
  243. // Use here KiROUND, not KIROUND (see comments about them)
  244. // when having a function as argument, because it will be called twice
  245. // with KIROUND
  246. return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
  247. }
  248. inline int parseBoardUnits( PCB_KEYS_T::T aToken )
  249. {
  250. return parseBoardUnits( GetTokenText( aToken ) );
  251. }
  252. inline int parseInt()
  253. {
  254. return (int)strtol( CurText(), NULL, 10 );
  255. }
  256. inline int parseInt( const char* aExpected )
  257. {
  258. NeedNUMBER( aExpected );
  259. return parseInt();
  260. }
  261. inline long parseHex()
  262. {
  263. NextTok();
  264. return strtol( CurText(), NULL, 16 );
  265. }
  266. bool parseBool();
  267. /**
  268. * Parse a format version tag like (version 20160417) return the version.
  269. * Expects to start on 'version', and eats the closing paren.
  270. */
  271. int parseVersion();
  272. public:
  273. PCB_PARSER( LINE_READER* aReader = NULL ) :
  274. PCB_LEXER( aReader ),
  275. m_board( 0 )
  276. {
  277. init();
  278. }
  279. // ~PCB_PARSER() {}
  280. /**
  281. * Function SetLineReader
  282. * sets @a aLineReader into the parser, and returns the previous one, if any.
  283. * @param aReader is what to read from for tokens, no ownership is received.
  284. * @return LINE_READER* - previous LINE_READER or NULL if none.
  285. */
  286. LINE_READER* SetLineReader( LINE_READER* aReader )
  287. {
  288. LINE_READER* ret = PopReader();
  289. PushReader( aReader );
  290. return ret;
  291. }
  292. void SetBoard( BOARD* aBoard )
  293. {
  294. init();
  295. m_board = aBoard;
  296. }
  297. BOARD_ITEM* Parse();
  298. /**
  299. * Function parseMODULE
  300. * @param aInitialComments may be a pointer to a heap allocated initial comment block
  301. * or NULL. If not NULL, then caller has given ownership of a wxArrayString to
  302. * this function and care must be taken to delete it even on exception.
  303. */
  304. MODULE* parseMODULE( wxArrayString* aInitialComments = 0 );
  305. /**
  306. * Return whether a version number, if any was parsed, was too recent
  307. */
  308. bool IsTooRecent()
  309. {
  310. return m_tooRecent;
  311. }
  312. /**
  313. * Return a string representing the version of kicad required to open this
  314. * file. Not particularly meaningful if IsTooRecent() returns false.
  315. */
  316. wxString GetRequiredVersion();
  317. };
  318. #endif // _PCBNEW_PARSER_H_