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.

1561 lines
40 KiB

15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2011 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  5. * Copyright (C) 2010 KiCad Developers, see change_log.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. #include <sch_sweet_parser.h>
  25. #include <sch_part.h>
  26. #include <sch_lib_table.h>
  27. #include <sch_lpid.h>
  28. #include <macros.h>
  29. using namespace SCH;
  30. using namespace PR;
  31. #define MAX_INHERITANCE_NESTING 6 ///< max depth of inheritance, no problem going larger
  32. static inline int internal( const STRING& aCoord )
  33. {
  34. return LogicalToInternal( strtod( aCoord.c_str(), NULL ) );
  35. }
  36. static inline int fromWidth( const STRING& aWidth )
  37. {
  38. return WidthToInternal( strtod( aWidth.c_str(), NULL ) );
  39. }
  40. static inline int fromFontz( const STRING& aFontSize )
  41. {
  42. return FontzToInternal( strtod( aFontSize.c_str(), NULL ) );
  43. }
  44. /**
  45. * Enum PartBit
  46. * is a set of bit positions that can be used to create flag bits within
  47. * PART::contains to indicate what state the PART is in and what it contains, i.e.
  48. * whether the PART has been parsed, and what the PART contains, categorically.
  49. */
  50. enum PartBit
  51. {
  52. parsed, ///< have parsed this part already, otherwise 'body' text must be parsed
  53. extends, ///< saw "extends" keyword, inheriting from another PART
  54. value,
  55. anchor,
  56. reference,
  57. footprint,
  58. datasheet,
  59. model,
  60. keywords,
  61. };
  62. /// Function PB
  63. /// is a PartBit shifter for PART::contains field.
  64. static inline const int PB( PartBit oneBitOnly )
  65. {
  66. return ( 1 << oneBitOnly );
  67. }
  68. void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_ERROR )
  69. {
  70. T tok;
  71. libs = aTable;
  72. // empty everything out, could be re-parsing this object and it may not be empty.
  73. me->clear();
  74. #if 0
  75. // Be flexible regarding the starting point of the stream.
  76. // Caller may not have read the first two tokens out of the
  77. // stream: T_LEFT and T_part, so ignore them if seen here.
  78. // The 1st two tokens T_LEFT and T_part are then optional in the grammar.
  79. if( ( tok = NextTok() ) == T_LEFT )
  80. {
  81. if( ( tok = NextTok() ) != T_part )
  82. Expecting( T_part );
  83. }
  84. #else
  85. // "( part" are not optional
  86. NeedLEFT();
  87. if( ( tok = NextTok() ) != T_part )
  88. Expecting( T_part );
  89. #endif
  90. NeedSYMBOLorNUMBER(); // toss NAME_HINT
  91. tok = NextTok();
  92. // extends must be _first_ thing, if it is present at all, after NAME_HINT
  93. if( tok == T_extends )
  94. {
  95. parseExtends( me );
  96. tok = NextTok();
  97. }
  98. for( ; tok!=T_RIGHT; tok = NextTok() )
  99. {
  100. if( tok == T_LEFT )
  101. {
  102. PROPERTY* prop;
  103. tok = NextTok();
  104. // because exceptions are thrown, any 'new' allocation has to be stored
  105. // somewhere other than on the stack, ASAP.
  106. switch( tok )
  107. {
  108. default:
  109. // describe what we expect at this level
  110. Expecting(
  111. "anchor|value|footprint|model|keywords|alternates\n"
  112. "|property\n"
  113. " |property_del\n"
  114. "|pin\n"
  115. " |pin_merge|pin_swap|pin_renum|pin_rename|route_pin_swap\n"
  116. "|polyline|line|rectangle|circle|arc|bezier|text"
  117. );
  118. break;
  119. case T_anchor:
  120. if( contains & PB(anchor) )
  121. Duplicate( tok );
  122. NeedNUMBER( "anchor x" );
  123. me->anchor.x = internal( CurText() );
  124. NeedNUMBER( "anchor y" );
  125. me->anchor.y = internal( CurText() );
  126. contains |= PB(anchor);
  127. break;
  128. case T_line:
  129. case T_polyline:
  130. POLY_LINE* pl;
  131. pl = new POLY_LINE( me );
  132. me->graphics.push_back( pl );
  133. parsePolyLine( pl );
  134. break;
  135. case T_rectangle:
  136. RECTANGLE* rect;
  137. rect = new RECTANGLE( me );
  138. me->graphics.push_back( rect );
  139. parseRectangle( rect );
  140. break;
  141. case T_circle:
  142. CIRCLE* circ;
  143. circ = new CIRCLE( me );
  144. me->graphics.push_back( circ );
  145. parseCircle( circ );
  146. break;
  147. case T_arc:
  148. ARC* arc;
  149. arc = new ARC( me );
  150. me->graphics.push_back( arc );
  151. parseArc( arc );
  152. break;
  153. case T_bezier:
  154. BEZIER* bezier;
  155. bezier = new BEZIER( me );
  156. me->graphics.push_back( bezier );
  157. parseBezier( bezier );
  158. break;
  159. case T_text:
  160. GR_TEXT* text;
  161. text = new GR_TEXT( me );
  162. me->graphics.push_back( text );
  163. parseText( text );
  164. break;
  165. case T_property:
  166. prop = new PROPERTY( me );
  167. // @todo check for uniqueness
  168. me->properties.push_back( prop );
  169. NeedSYMBOLorNUMBER();
  170. prop->name = FromUTF8();
  171. L_prop:
  172. NeedSYMBOLorNUMBER();
  173. prop->text = FromUTF8();
  174. tok = NextTok();
  175. if( tok == T_LEFT )
  176. {
  177. tok = NextTok();
  178. if( tok != T_effects )
  179. Expecting( T_effects );
  180. parseTextEffects( prop->EffectsLookup() );
  181. NeedRIGHT();
  182. }
  183. else if( tok != T_RIGHT )
  184. Expecting( ") | effects" );
  185. break;
  186. case T_property_del:
  187. parsePropertyDel( me );
  188. break;
  189. // reference in a PART is incomplete, it is just the prefix of an
  190. // unannotated reference. Only components have full reference designators.
  191. case T_reference:
  192. if( contains & PB(reference) )
  193. Duplicate( tok );
  194. contains |= PB(reference);
  195. prop = me->FieldLookup( PART::REFERENCE );
  196. goto L_prop;
  197. case T_value:
  198. if( contains & PB(value) )
  199. Duplicate( tok );
  200. contains |= PB(value);
  201. prop = me->FieldLookup( PART::VALUE );
  202. goto L_prop;
  203. case T_footprint:
  204. if( contains & PB(footprint) )
  205. Duplicate( tok );
  206. contains |= PB(footprint);
  207. prop = me->FieldLookup( PART::FOOTPRINT );
  208. goto L_prop;
  209. case T_datasheet:
  210. if( contains & PB(datasheet) )
  211. Duplicate( tok );
  212. contains |= PB(datasheet);
  213. prop = me->FieldLookup( PART::DATASHEET );
  214. goto L_prop;
  215. case T_model:
  216. if( contains & PB(model) )
  217. Duplicate( tok );
  218. contains |= PB(model);
  219. prop = me->FieldLookup( PART::MODEL );
  220. goto L_prop;
  221. case T_keywords:
  222. parseKeywords( me );
  223. break;
  224. case T_alternates:
  225. // @todo: do we want to inherit alternates?
  226. parseAlternates( me );
  227. break;
  228. case T_pin:
  229. // @todo PADNAMEs must be unique
  230. PIN* pin;
  231. pin = new PIN( me );
  232. me->pins.push_back( pin );
  233. parsePin( pin );
  234. break;
  235. case T_pin_del:
  236. parsePinDel( me );
  237. break;
  238. case T_pin_swap:
  239. parsePinSwap( me );
  240. break;
  241. case T_pin_renum:
  242. parsePinRenum( me );
  243. break;
  244. case T_pin_rename:
  245. parsePinRename( me );
  246. break;
  247. case T_pin_merge:
  248. parsePinMerge( me );
  249. break;
  250. /*
  251. @todo
  252. case T_route_pin_swap:
  253. break;
  254. */
  255. }
  256. }
  257. else
  258. {
  259. switch( tok )
  260. {
  261. default:
  262. Unexpected( tok );
  263. }
  264. }
  265. }
  266. contains |= PB(parsed);
  267. me->contains |= contains;
  268. }
  269. void SWEET_PARSER::parseExtends( PART* me )
  270. {
  271. PART* base;
  272. int offset;
  273. if( contains & PB(extends) )
  274. Duplicate( T_extends );
  275. NeedSYMBOLorNUMBER();
  276. me->setExtends( new LPID() );
  277. offset = me->extends->Parse( CurText() );
  278. if( offset > -1 ) // -1 is success
  279. THROW_PARSE_ERROR( _("invalid extends LPID"),
  280. CurSource(),
  281. CurLine(),
  282. CurLineNumber(),
  283. CurOffset() + offset );
  284. base = libs->LookupPart( *me->extends, me->Owner() );
  285. // we could be going in circles here, recursively, or too deep, set limits
  286. // and disallow extending from self (even indirectly)
  287. int extendsDepth = 0;
  288. for( const PART* ancestor = base; ancestor && extendsDepth<MAX_INHERITANCE_NESTING;
  289. ++extendsDepth, ancestor = ancestor->base )
  290. {
  291. if( ancestor == me )
  292. {
  293. THROW_PARSE_ERROR( _("'extends' may not have self as any ancestor"),
  294. CurSource(),
  295. CurLine(),
  296. CurLineNumber(),
  297. CurOffset() );
  298. }
  299. }
  300. if( extendsDepth == MAX_INHERITANCE_NESTING )
  301. {
  302. THROW_PARSE_ERROR( _("max allowed extends depth exceeded"),
  303. CurSource(),
  304. CurLine(),
  305. CurLineNumber(),
  306. CurOffset() );
  307. }
  308. me->inherit( *base );
  309. me->base = base;
  310. contains |= PB(extends);
  311. }
  312. void SWEET_PARSER::parseAlternates( PART* me )
  313. {
  314. T tok;
  315. PART_REF lpid;
  316. int offset;
  317. while( ( tok = NextTok() ) != T_RIGHT )
  318. {
  319. if( !IsSymbol( tok ) && tok != T_NUMBER )
  320. Expecting( "lpid" );
  321. // lpid.clear(); Parse does this
  322. offset = lpid.Parse( CurText() );
  323. if( offset > -1 )
  324. THROW_PARSE_ERROR( _("invalid alternates LPID"),
  325. CurSource(),
  326. CurLine(),
  327. CurLineNumber(),
  328. CurOffset() + offset );
  329. // PART_REF assignment should be OK, it contains no ownership
  330. me->alternates.push_back( lpid );
  331. }
  332. }
  333. void SWEET_PARSER::parseKeywords( PART* me )
  334. {
  335. T tok;
  336. while( ( tok = NextTok() ) != T_RIGHT )
  337. {
  338. if( !IsSymbol( tok ) && tok!=T_NUMBER )
  339. Expecting( "symbol|number" );
  340. // just insert them, duplicates are silently removed and tossed.
  341. me->keywords.insert( FromUTF8() );
  342. }
  343. }
  344. void SWEET_PARSER::parseFont( FONT* me )
  345. {
  346. /*
  347. # The FONT value needs to be defined. Currently, EESchema does not support
  348. # different fonts. In the future this feature may be implemented and at
  349. # that time FONT will have to be defined. Initially, only the font size and
  350. # style are required. Italic and bold styles are optional. The font size
  351. # height and width are in units yet to be determined.
  352. (font [FONT] (size HEIGHT WIDTH) [italic] [bold])
  353. */
  354. // handle the [FONT] 'position dependently', i.e. first
  355. T tok = NextTok();
  356. bool sawBold = false;
  357. bool sawItalic = false;
  358. bool sawSize = false;
  359. if( IsSymbol( tok ) )
  360. {
  361. me->name = FromUTF8();
  362. tok = NextTok();
  363. }
  364. for( ; tok != T_RIGHT; tok = NextTok() )
  365. {
  366. if( tok == T_LEFT )
  367. {
  368. tok = NextTok();
  369. switch( tok )
  370. {
  371. case T_size:
  372. if( sawSize )
  373. Duplicate( T_size );
  374. sawSize = true;
  375. NeedNUMBER( "size height" );
  376. me->size.height = fromFontz( CurText() );
  377. NeedNUMBER( "size width" );
  378. me->size.width = fromFontz( CurText() );
  379. NeedRIGHT();
  380. break;
  381. default:
  382. Expecting( "size" );
  383. }
  384. }
  385. else
  386. {
  387. switch( tok )
  388. {
  389. case T_bold:
  390. if( sawBold )
  391. Duplicate( T_bold );
  392. sawBold = true;
  393. me->bold = true;
  394. break;
  395. case T_italic:
  396. if( sawItalic )
  397. Duplicate( T_italic );
  398. sawItalic = true;
  399. me->italic = true;
  400. break;
  401. default:
  402. Unexpected( "bold|italic" );
  403. }
  404. }
  405. }
  406. }
  407. void SWEET_PARSER::parseBool( bool* aBool )
  408. {
  409. T tok = NeedSYMBOL();
  410. switch( tok )
  411. {
  412. case T_yes:
  413. case T_no:
  414. *aBool = (tok == T_yes);
  415. break;
  416. default:
  417. Expecting( "yes|no" );
  418. }
  419. }
  420. void SWEET_PARSER::parseStroke( STROKE* me )
  421. {
  422. /*
  423. (stroke [WIDTH] [(style [(dashed...)]...)])
  424. future place holder for arrow heads, dashed lines, all line glamour
  425. */
  426. NeedNUMBER( "stroke" );
  427. *me = fromWidth( CurText() );
  428. NeedRIGHT();
  429. }
  430. void SWEET_PARSER::parsePinText( PINTEXT* me )
  431. {
  432. /* either:
  433. (signal SIGNAL (font [FONT] (size HEIGHT WIDTH) [italic] [bold])(visible YES))
  434. or
  435. (pad PADNAME (font [FONT] (size HEIGHT WIDTH) [italic] [bold])(visible YES))
  436. */
  437. T tok;
  438. bool sawFont = false;
  439. bool sawVis = false;
  440. // pad or signal text
  441. NeedSYMBOLorNUMBER();
  442. me->text = FromUTF8();
  443. while( ( tok = NextTok() ) != T_RIGHT )
  444. {
  445. if( tok == T_LEFT )
  446. {
  447. tok = NextTok();
  448. switch( tok )
  449. {
  450. case T_font:
  451. if( sawFont )
  452. Duplicate( tok );
  453. sawFont = true;
  454. parseFont( &me->font );
  455. break;
  456. case T_visible:
  457. if( sawVis )
  458. Duplicate( tok );
  459. sawVis = true;
  460. parseBool( &me->isVisible );
  461. NeedRIGHT();
  462. break;
  463. default:
  464. Expecting( "font" );
  465. }
  466. }
  467. else
  468. {
  469. switch( tok )
  470. {
  471. default:
  472. Expecting( T_LEFT );
  473. }
  474. }
  475. }
  476. }
  477. void SWEET_PARSER::parsePin( PIN* me )
  478. {
  479. /*
  480. (pin TYPE SHAPE
  481. (at X Y [ANGLE])
  482. (length LENGTH)
  483. (signal NAME (font [FONT] (size HEIGHT WIDTH) [italic] [bold])(visible YES))
  484. (pad NUMBER (font [FONT] (size HEIGHT WIDTH) [italic] [bold] (visible YES))
  485. (visible YES)
  486. )
  487. */
  488. T tok;
  489. bool sawShape = false;
  490. bool sawType = false;
  491. bool sawAt = false;
  492. bool sawLen = false;
  493. bool sawSignal = false;
  494. bool sawPad = false;
  495. bool sawVis = false;
  496. while( ( tok = NextTok() ) != T_RIGHT )
  497. {
  498. if( tok == T_LEFT )
  499. {
  500. tok = NextTok();
  501. switch( tok )
  502. {
  503. case T_at:
  504. if( sawAt )
  505. Duplicate( tok );
  506. sawAt = true;
  507. parseAt( &me->pos, &me->angle );
  508. break;
  509. case T_length:
  510. if( sawLen )
  511. Duplicate( tok );
  512. sawLen = true;
  513. NeedNUMBER( "length" );
  514. me->length = internal( CurText() );
  515. NeedRIGHT();
  516. break;
  517. case T_signal:
  518. if( sawSignal )
  519. Duplicate( tok );
  520. sawSignal = true;
  521. parsePinText( &me->signal );
  522. break;
  523. case T_pad:
  524. if( sawPad )
  525. Duplicate( tok );
  526. sawPad = true;
  527. parsePinText( &me->pad );
  528. break;
  529. case T_visible:
  530. if( sawVis )
  531. Duplicate( tok );
  532. sawVis = true;
  533. parseBool( &me->isVisible );
  534. NeedRIGHT();
  535. break;
  536. default:
  537. Unexpected( tok );
  538. }
  539. }
  540. else // not wrapped in parentheses
  541. {
  542. switch( tok )
  543. {
  544. case T_in:
  545. case T_out:
  546. case T_inout:
  547. case T_tristate:
  548. case T_passive:
  549. case T_unspecified:
  550. case T_power_in:
  551. case T_power_out:
  552. case T_open_collector:
  553. case T_open_emitter:
  554. case T_unconnected:
  555. if( sawType )
  556. Duplicate( tok );
  557. sawType = true;
  558. me->connectionType = tok;
  559. break;
  560. case T_none:
  561. case T_line:
  562. case T_inverted:
  563. case T_clock:
  564. case T_inverted_clk:
  565. case T_input_low:
  566. case T_clock_low:
  567. case T_falling_edge:
  568. case T_non_logic:
  569. if( sawShape )
  570. Duplicate( tok );
  571. sawShape = true;
  572. me->shape = tok;
  573. break;
  574. default:
  575. Unexpected( tok );
  576. }
  577. }
  578. }
  579. }
  580. void SWEET_PARSER::parsePinDel( PART* me )
  581. {
  582. wxString pad;
  583. // we do this somewhat unorthodoxically because we want to avoid doing two lookups,
  584. // which would need to be done to 1) find pin, and 2) delete pin. Only one
  585. // lookup is needed with this scheme.
  586. NeedSYMBOLorNUMBER();
  587. pad = FromUTF8();
  588. // lookup now while CurOffset() is still meaningful.
  589. PINS::iterator it = me->pinFindByPad( pad );
  590. if( it == me->pins.end() )
  591. {
  592. THROW_PARSE_ERROR( _("undefined pin"),
  593. CurSource(),
  594. CurLine(),
  595. CurLineNumber(),
  596. CurOffset() );
  597. }
  598. /* enable in future, but not now while testing
  599. if( (*it)->birthplace == me )
  600. {
  601. THROW_PARSE_ERROR( _("pin_del allowed for inherited pins only"),
  602. CurSource(),
  603. CurLine(),
  604. CurLineNumber(),
  605. CurOffset() );
  606. }
  607. */
  608. NeedRIGHT();
  609. delete *it; // good thing I'm a friend.
  610. me->pins.erase( it );
  611. }
  612. void SWEET_PARSER::parsePinSwap( PART* me )
  613. {
  614. PIN* pin1;
  615. PIN* pin2;
  616. wxString pad;
  617. NeedSYMBOLorNUMBER();
  618. pad = FromUTF8();
  619. // lookup now while CurOffset() is still meaningful.
  620. pin1 = me->PinFindByPad( pad );
  621. if( !pin1 )
  622. {
  623. THROW_PARSE_ERROR( _("undefined pin"),
  624. CurSource(),
  625. CurLine(),
  626. CurLineNumber(),
  627. CurOffset() );
  628. }
  629. NeedSYMBOLorNUMBER();
  630. pad = FromUTF8();
  631. pin2 = me->PinFindByPad( pad );
  632. if( !pin2 )
  633. {
  634. THROW_PARSE_ERROR( _("undefined pin"),
  635. CurSource(),
  636. CurLine(),
  637. CurLineNumber(),
  638. CurOffset() );
  639. }
  640. NeedRIGHT();
  641. // swap only the text, but might want to swap entire PIN_TEXTs
  642. pin2->pad.text = pin1->pad.text;
  643. pin1->pad.text = pad;
  644. }
  645. void SWEET_PARSER::parsePinRenum( PART* me )
  646. {
  647. PIN* pin;
  648. wxString oldPad;
  649. wxString newPad;
  650. NeedSYMBOLorNUMBER();
  651. oldPad = FromUTF8();
  652. // lookup now while CurOffset() is still meaningful.
  653. pin = me->PinFindByPad( oldPad );
  654. if( !pin )
  655. {
  656. THROW_PARSE_ERROR( _("undefined pin"),
  657. CurSource(),
  658. CurLine(),
  659. CurLineNumber(),
  660. CurOffset() );
  661. }
  662. NeedSYMBOLorNUMBER();
  663. newPad = FromUTF8();
  664. NeedRIGHT();
  665. // @todo: check for pad legalities
  666. pin->pad.text = newPad;
  667. }
  668. void SWEET_PARSER::parsePinRename( PART* me )
  669. {
  670. PIN* pin;
  671. wxString pad;
  672. wxString newSignal;
  673. NeedSYMBOLorNUMBER();
  674. pad = FromUTF8();
  675. // lookup now while CurOffset() is still meaningful.
  676. pin = me->PinFindByPad( pad );
  677. if( !pin )
  678. {
  679. THROW_PARSE_ERROR( _("undefined pin"),
  680. CurSource(),
  681. CurLine(),
  682. CurLineNumber(),
  683. CurOffset() );
  684. }
  685. NeedSYMBOLorNUMBER();
  686. newSignal = FromUTF8();
  687. NeedRIGHT();
  688. pin->signal.text = newSignal;
  689. }
  690. void SWEET_PARSER::parsePinMerge( PART* me )
  691. {
  692. T tok;
  693. wxString pad;
  694. wxString signal;
  695. wxString msg;
  696. NeedSYMBOLorNUMBER();
  697. wxString anchorPad = FromUTF8();
  698. // lookup now while CurOffset() is still good.
  699. PINS::iterator pit = me->pinFindByPad( anchorPad );
  700. if( pit == me->pins.end() )
  701. {
  702. msg.Printf( _( "undefined pin %s" ), anchorPad.GetData() );
  703. THROW_PARSE_ERROR( msg,
  704. CurSource(),
  705. CurLine(),
  706. CurLineNumber(),
  707. CurOffset() );
  708. }
  709. if( !(*pit)->pin_merge.IsEmpty() && anchorPad != (*pit)->pin_merge )
  710. {
  711. msg.Printf( _( "pin %s already in pin_merge group %s" ),
  712. anchorPad.GetData(), (*pit)->pin_merge.GetData() );
  713. THROW_PARSE_ERROR( msg,
  714. CurSource(),
  715. CurLine(),
  716. CurLineNumber(),
  717. CurOffset() );
  718. }
  719. (*pit)->isVisible = true;
  720. (*pit)->pin_merge = anchorPad;
  721. // allocate or find a MERGE_SET;
  722. MERGE_SET& ms = me->pin_merges[anchorPad];
  723. while( ( tok = NextTok() ) != T_RIGHT )
  724. {
  725. if( tok == T_LEFT )
  726. {
  727. tok = NextTok();
  728. switch( tok )
  729. {
  730. case T_signals:
  731. {
  732. PINS sigPins; // no ownership
  733. while( ( tok = NextTok() ) != T_RIGHT )
  734. {
  735. if( !IsSymbol( tok ) && tok != T_NUMBER )
  736. Expecting( "signal" );
  737. signal = FromUTF8();
  738. sigPins.clear();
  739. me->PinsFindBySignal( &sigPins, signal );
  740. if( !sigPins.size() )
  741. {
  742. msg.Printf( _( "no pins with signal %s" ), signal.GetData() );
  743. THROW_PARSE_ERROR( msg,
  744. CurSource(),
  745. CurLine(),
  746. CurLineNumber(),
  747. CurOffset() );
  748. }
  749. for( pit = sigPins.begin(); pit != sigPins.end(); ++pit )
  750. {
  751. if( !(*pit)->pin_merge.IsEmpty() && anchorPad != (*pit)->pin_merge )
  752. {
  753. msg.Printf( _( "signal pin %s already in pin_merge group %s" ),
  754. pad.GetData(), (*pit)->pin_merge.GetData() );
  755. THROW_PARSE_ERROR( msg,
  756. CurSource(),
  757. CurLine(),
  758. CurLineNumber(),
  759. CurOffset() );
  760. }
  761. (*pit)->isVisible = true;
  762. (*pit)->pin_merge = anchorPad;
  763. ms.insert( pad );
  764. }
  765. }
  766. }
  767. break;
  768. case T_pads:
  769. while( ( tok = NextTok() ) != T_RIGHT )
  770. {
  771. if( !IsSymbol( tok ) && tok != T_NUMBER )
  772. Expecting( "pad" );
  773. pad = FromUTF8();
  774. D(printf("pad=%s\n", TO_UTF8( pad ) );)
  775. // find the PIN and mark it as being in this MERGE_SET or throw
  776. // error if already in another MERGET_SET.
  777. pit = me->pinFindByPad( pad );
  778. if( pit == me->pins.end() )
  779. {
  780. msg.Printf( _( "undefined pin %s" ), pad.GetData() );
  781. THROW_PARSE_ERROR( msg,
  782. CurSource(),
  783. CurLine(),
  784. CurLineNumber(),
  785. CurOffset() );
  786. }
  787. if( !(*pit)->pin_merge.IsEmpty() /* && anchorPad != (*pit)->pin_merge */ )
  788. {
  789. msg.Printf( _( "pin %s already in pin_merge group %s" ),
  790. pad.GetData(), (*pit)->pin_merge.GetData() );
  791. THROW_PARSE_ERROR( msg,
  792. CurSource(),
  793. CurLine(),
  794. CurLineNumber(),
  795. CurOffset() );
  796. }
  797. (*pit)->isVisible = false;
  798. (*pit)->pin_merge = anchorPad;
  799. ms.insert( pad );
  800. }
  801. break;
  802. default:
  803. Expecting( "pads|signals" );
  804. break;
  805. }
  806. }
  807. else
  808. {
  809. Expecting( T_LEFT );
  810. }
  811. }
  812. }
  813. void SWEET_PARSER::parsePropertyDel( PART* me )
  814. {
  815. NeedSYMBOLorNUMBER();
  816. wxString propertyName = FromUTF8();
  817. if( !me->PropDelete( propertyName ) )
  818. {
  819. wxString msg;
  820. msg.Printf( _( "Unable to find property: %s" ), propertyName.GetData() );
  821. THROW_IO_ERROR( msg );
  822. }
  823. NeedRIGHT();
  824. }
  825. void SWEET_PARSER::parseTextEffects( TEXT_EFFECTS* me )
  826. {
  827. /*
  828. (effects [PROPERTY]
  829. # Position requires X and Y coordinates. Position coordinates can be
  830. # non-intergr. Angle is in degrees and defaults to 0 if not defined.
  831. (at X Y [ANGLE])
  832. # The FONT value needs to be defined. Currently, EESchema does not support
  833. # different fonts. In the future this feature may be implemented and at
  834. # that time FONT will have to be defined. Initially, only the font size and
  835. # style are required. Italic and bold styles are optional. The font size
  836. # height and width are in units yet to be determined.
  837. (font [FONT] (size HEIGHT WIDTH) [italic] [bold])
  838. # Valid visibility values are yes and no.
  839. (visible YES)
  840. )
  841. */
  842. bool sawFont = false;
  843. bool sawAt = false;
  844. bool sawVis = false;
  845. T tok = NextTok();
  846. if( IsSymbol( tok ) )
  847. {
  848. me->propName = FromUTF8();
  849. tok = NextTok();
  850. }
  851. for( ; tok != T_RIGHT; tok = NextTok() )
  852. {
  853. if( tok != T_LEFT )
  854. Expecting( T_LEFT );
  855. tok = NextTok();
  856. switch( tok )
  857. {
  858. case T_at:
  859. if( sawAt )
  860. Duplicate( tok );
  861. sawAt = true;
  862. parseAt( &me->pos, &me->angle );
  863. break;
  864. case T_font:
  865. if( sawFont )
  866. Duplicate( tok );
  867. sawFont = true;
  868. parseFont( &me->font );
  869. break;
  870. case T_visible:
  871. if( sawVis )
  872. Duplicate( sawVis );
  873. sawVis = true;
  874. parseBool( &me->isVisible );
  875. NeedRIGHT();
  876. break;
  877. default:
  878. Expecting( "at|font|visible" );
  879. }
  880. }
  881. }
  882. void SWEET_PARSER::parsePolyLine( POLY_LINE* me )
  883. {
  884. /*
  885. (polyline|line
  886. (pts (xy X Y) (xy X Y) (xy X Y) (xy X Y) (xy X Y))
  887. # Line widths are in percent of a pin delta
  888. [(stroke [WIDTH] [(style [(dashed...)]...)])]
  889. # Valid fill types are none, filled, and transparent.
  890. (fill FILL_TYPE)
  891. )
  892. */
  893. T tok;
  894. int count = 0;
  895. bool sawStroke = false;
  896. bool sawFill = false;
  897. while( ( tok = NextTok() ) != T_RIGHT )
  898. {
  899. if( tok != T_LEFT )
  900. Expecting( T_LEFT );
  901. tok = NextTok();
  902. switch( tok )
  903. {
  904. case T_stroke:
  905. if( sawStroke )
  906. Duplicate( tok );
  907. sawStroke = true;
  908. parseStroke( &me->stroke );
  909. break;
  910. case T_pts:
  911. if( count )
  912. Duplicate( tok );
  913. for( ; ( tok = NextTok() ) != T_RIGHT; ++count )
  914. {
  915. if( tok != T_LEFT )
  916. Expecting( T_LEFT );
  917. tok = NeedSYMBOL();
  918. if( tok != T_xy )
  919. Expecting( T_xy );
  920. me->pts.push_back( POINT() );
  921. NeedNUMBER( "x" );
  922. me->pts.back().x = internal( CurText() );
  923. NeedNUMBER( "y" );
  924. me->pts.back().y = internal( CurText() );
  925. NeedRIGHT();
  926. }
  927. if( count < 2 )
  928. Expecting( ">= 2 pts" );
  929. break;
  930. case T_fill:
  931. if( sawFill )
  932. Duplicate( tok );
  933. tok = NeedSYMBOL();
  934. switch( tok )
  935. {
  936. case T_none:
  937. case T_filled:
  938. case T_transparent:
  939. me->fillType = tok;
  940. break;
  941. default:
  942. Expecting( "none|filled|transparent" );
  943. }
  944. NeedRIGHT();
  945. sawFill = true;
  946. break;
  947. default:
  948. Expecting( "pts|stroke|fill" );
  949. }
  950. }
  951. }
  952. void SWEET_PARSER::parseBezier( BEZIER* me )
  953. {
  954. parsePolyLine( me );
  955. }
  956. void SWEET_PARSER::parseRectangle( RECTANGLE* me )
  957. {
  958. /*
  959. (rectangle (start X Y) (end X Y) (stroke WIDTH) (fill FILL_TYPE))
  960. */
  961. T tok;
  962. bool sawStart = false;
  963. bool sawEnd = false;
  964. bool sawStroke = false;
  965. bool sawFill = false;
  966. while( ( tok = NextTok() ) != T_RIGHT )
  967. {
  968. if( tok != T_LEFT )
  969. Expecting( T_LEFT );
  970. tok = NextTok();
  971. switch( tok )
  972. {
  973. case T_stroke:
  974. if( sawStroke )
  975. Duplicate( tok );
  976. sawStroke = true;
  977. parseStroke( &me->stroke );
  978. break;
  979. case T_fill:
  980. if( sawFill )
  981. Duplicate( tok );
  982. sawFill = true;
  983. tok = NeedSYMBOL();
  984. switch( tok )
  985. {
  986. case T_none:
  987. case T_filled:
  988. case T_transparent:
  989. me->fillType = tok;
  990. break;
  991. default:
  992. Expecting( "none|filled|transparent" );
  993. }
  994. NeedRIGHT();
  995. break;
  996. case T_start:
  997. if( sawStart )
  998. Duplicate( tok );
  999. sawStart = true;
  1000. NeedNUMBER( "x" );
  1001. me->start.x = internal( CurText() );
  1002. NeedNUMBER( "y" );
  1003. me->start.y = internal( CurText() );
  1004. NeedRIGHT();
  1005. break;
  1006. case T_end:
  1007. if( sawEnd )
  1008. Duplicate( tok );
  1009. sawEnd = true;
  1010. NeedNUMBER( "x" );
  1011. me->end.x = internal( CurText() );
  1012. NeedNUMBER( "y" );
  1013. me->end.y = internal( CurText() );
  1014. NeedRIGHT();
  1015. break;
  1016. default:
  1017. Expecting( "start|end|stroke|fill" );
  1018. }
  1019. }
  1020. }
  1021. void SWEET_PARSER::parseCircle( CIRCLE* me )
  1022. {
  1023. /*
  1024. (circle (center X Y)
  1025. # Radius length is in units if defined or mils.
  1026. (radius LENGTH)
  1027. (stroke WIDTH)
  1028. (fill FILL_TYPE)
  1029. )
  1030. */
  1031. T tok;
  1032. bool sawCenter = false;
  1033. bool sawRadius = false;
  1034. bool sawStroke = false;
  1035. bool sawFill = false;
  1036. while( ( tok = NextTok() ) != T_RIGHT )
  1037. {
  1038. if( tok != T_LEFT )
  1039. Expecting( T_LEFT );
  1040. tok = NextTok();
  1041. switch( tok )
  1042. {
  1043. case T_stroke:
  1044. if( sawStroke )
  1045. Duplicate( tok );
  1046. sawStroke = true;
  1047. parseStroke( &me->stroke );
  1048. break;
  1049. case T_fill:
  1050. if( sawFill )
  1051. Duplicate( tok );
  1052. sawFill = true;
  1053. tok = NeedSYMBOL();
  1054. switch( tok )
  1055. {
  1056. case T_none:
  1057. case T_filled:
  1058. case T_transparent:
  1059. me->fillType = tok;
  1060. break;
  1061. default:
  1062. Expecting( "none|filled|transparent" );
  1063. }
  1064. NeedRIGHT();
  1065. break;
  1066. case T_center:
  1067. if( sawCenter )
  1068. Duplicate( tok );
  1069. sawCenter = true;
  1070. NeedNUMBER( "center x" );
  1071. me->center.x = internal( CurText() );
  1072. NeedNUMBER( "center y" );
  1073. me->center.y = internal( CurText() );
  1074. NeedRIGHT();
  1075. break;
  1076. case T_radius:
  1077. if( sawRadius )
  1078. Duplicate( tok );
  1079. sawRadius = true;
  1080. NeedNUMBER( "radius" );
  1081. me->radius = internal( CurText() );
  1082. NeedRIGHT();
  1083. break;
  1084. default:
  1085. Expecting( "center|radius|stroke|fill" );
  1086. }
  1087. }
  1088. }
  1089. void SWEET_PARSER::parseArc( ARC* me )
  1090. {
  1091. /*
  1092. (arc (pos X Y) (radius RADIUS) (start X Y) (end X Y)
  1093. (stroke WIDTH)
  1094. (fill FILL_TYPE)
  1095. )
  1096. */
  1097. T tok;
  1098. bool sawPos = false;
  1099. bool sawStart = false;
  1100. bool sawEnd = false;
  1101. bool sawRadius = false;
  1102. bool sawStroke = false;
  1103. bool sawFill = false;
  1104. while( ( tok = NextTok() ) != T_RIGHT )
  1105. {
  1106. if( tok != T_LEFT )
  1107. Expecting( T_LEFT );
  1108. tok = NextTok();
  1109. switch( tok )
  1110. {
  1111. case T_stroke:
  1112. if( sawStroke )
  1113. Duplicate( tok );
  1114. sawStroke = true;
  1115. parseStroke( &me->stroke );
  1116. break;
  1117. case T_fill:
  1118. if( sawFill )
  1119. Duplicate( tok );
  1120. sawFill = true;
  1121. tok = NeedSYMBOL();
  1122. switch( tok )
  1123. {
  1124. case T_none:
  1125. case T_filled:
  1126. case T_transparent:
  1127. me->fillType = tok;
  1128. break;
  1129. default:
  1130. Expecting( "none|filled|transparent" );
  1131. }
  1132. NeedRIGHT();
  1133. break;
  1134. case T_pos:
  1135. if( sawPos )
  1136. Duplicate( tok );
  1137. sawPos = true;
  1138. NeedNUMBER( "pos x" );
  1139. me->pos.x = internal( CurText() );
  1140. NeedNUMBER( "pos y" );
  1141. me->pos.y = internal( CurText() );
  1142. NeedRIGHT();
  1143. break;
  1144. case T_radius:
  1145. if( sawRadius )
  1146. Duplicate( tok );
  1147. sawRadius = true;
  1148. NeedNUMBER( "radius" );
  1149. me->radius = internal( CurText() );
  1150. NeedRIGHT();
  1151. break;
  1152. case T_start:
  1153. if( sawStart )
  1154. Duplicate( tok );
  1155. sawStart = true;
  1156. NeedNUMBER( "start x" );
  1157. me->start.x = internal( CurText() );
  1158. NeedNUMBER( "start y" );
  1159. me->start.y = internal( CurText() );
  1160. NeedRIGHT();
  1161. break;
  1162. case T_end:
  1163. if( sawEnd )
  1164. Duplicate( tok );
  1165. sawEnd = true;
  1166. NeedNUMBER( "end x" );
  1167. me->end.x = internal( CurText() );
  1168. NeedNUMBER( "end y" );
  1169. me->end.y = internal( CurText() );
  1170. NeedRIGHT();
  1171. break;
  1172. default:
  1173. Expecting( "center|radius|stroke|fill" );
  1174. }
  1175. }
  1176. }
  1177. void SWEET_PARSER::parseAt( POINT* pos, float* angle )
  1178. {
  1179. T tok;
  1180. NeedNUMBER( "at x" );
  1181. pos->x = internal( CurText() );
  1182. NeedNUMBER( "at y" );
  1183. pos->y = internal( CurText() );
  1184. tok = NextTok();
  1185. if( angle && tok == T_NUMBER )
  1186. {
  1187. *angle = strtod( CurText(), NULL );
  1188. tok = NextTok();
  1189. }
  1190. if( tok != T_RIGHT )
  1191. Expecting( T_RIGHT );
  1192. }
  1193. void SWEET_PARSER::parseText( GR_TEXT* me )
  1194. {
  1195. /*
  1196. (text "This is the text that gets drawn."
  1197. (at X Y [ANGLE])
  1198. # Valid horizontal justification values are center, right, and left. Valid
  1199. # vertical justification values are center, top, bottom.
  1200. (justify HORIZONTAL_JUSTIFY VERTICAL_JUSTIFY)
  1201. (font [FONT] (size HEIGHT WIDTH) [italic] [bold])
  1202. (visible YES)
  1203. (fill FILL_TYPE)
  1204. )
  1205. */
  1206. T tok;
  1207. bool sawAt = false;
  1208. bool sawFill = false;
  1209. bool sawFont = false;
  1210. bool sawVis = false;
  1211. bool sawJust = false;
  1212. bool sawText = false;
  1213. while( ( tok = NextTok() ) != T_RIGHT )
  1214. {
  1215. if( tok == T_LEFT )
  1216. {
  1217. tok = NextTok();
  1218. switch( tok )
  1219. {
  1220. case T_at:
  1221. if( sawAt )
  1222. Duplicate( tok );
  1223. parseAt( &me->pos, &me->angle );
  1224. sawAt = true;
  1225. break;
  1226. case T_fill:
  1227. if( sawFill )
  1228. Duplicate( tok );
  1229. tok = NeedSYMBOL();
  1230. switch( tok )
  1231. {
  1232. case T_none:
  1233. case T_filled:
  1234. case T_transparent:
  1235. me->fillType = tok;
  1236. break;
  1237. default:
  1238. Expecting( "none|filled|transparent" );
  1239. }
  1240. NeedRIGHT();
  1241. sawFill = true;
  1242. break;
  1243. case T_justify:
  1244. if( sawJust )
  1245. Duplicate( tok );
  1246. tok = NeedSYMBOL();
  1247. switch( tok )
  1248. {
  1249. case T_center:
  1250. case T_right:
  1251. case T_left:
  1252. me->hjustify = tok;
  1253. break;
  1254. default:
  1255. Expecting( "center|right|left" );
  1256. }
  1257. tok = NeedSYMBOL();
  1258. switch( tok )
  1259. {
  1260. case T_center:
  1261. case T_top:
  1262. case T_bottom:
  1263. me->vjustify = tok;
  1264. break;
  1265. default:
  1266. Expecting( "center|top|bottom" );
  1267. }
  1268. NeedRIGHT();
  1269. sawJust = true;
  1270. break;
  1271. case T_visible:
  1272. if( sawVis )
  1273. Duplicate( tok );
  1274. parseBool( &me->isVisible );
  1275. NeedRIGHT();
  1276. sawVis = true;
  1277. break;
  1278. case T_font:
  1279. if( sawFont )
  1280. Duplicate( tok );
  1281. sawFont = true;
  1282. parseFont( &me->font );
  1283. break;
  1284. default:
  1285. Expecting( "at|justify|font|visible|fill" );
  1286. }
  1287. }
  1288. else
  1289. {
  1290. if( !IsSymbol( tok ) && tok != T_NUMBER )
  1291. Expecting( T_STRING );
  1292. if( sawText )
  1293. Duplicate( tok );
  1294. sawText = true;
  1295. me->text = wxString::FromUTF8( CurText() );
  1296. }
  1297. }
  1298. }