KiCad PCB EDA Suite
SCH_SEXPR_PARSER Class Reference

Object to parser s-expression symbol library and schematic file formats. More...

#include <sch_sexpr_parser.h>

Inheritance diagram for SCH_SEXPR_PARSER:

Public Member Functions

 SCH_SEXPR_PARSER (LINE_READER *aLineReader=nullptr)
 
void ParseLib (LIB_PART_MAP &aSymbolLibMap)
 
LIB_PARTParseSymbol (LIB_PART_MAP &aSymbolLibMap, int aFileVersion=SEXPR_SYMBOL_LIB_FILE_VERSION)
 
LIB_ITEMParseDrawItem ()
 
void ParseSchematic (SCH_SHEET *aSheet, bool aIsCopyablyOnly=false, int aFileVersion=SEXPR_SCHEMATIC_FILE_VERSION)
 Parse the internal LINE_READER object into aSheet. More...
 
bool IsTooRecent () const
 Return whether a version number, if any was parsed, was too recent. More...
 

Private Member Functions

void parseHeader (TSCHEMATIC_T::T aHeaderType, int aFileVersion)
 
long parseHex ()
 
int parseInt ()
 
int parseInt (const char *aExpected)
 
double parseDouble ()
 Parse the current token as an ASCII numeric string with possible leading whitespace into a double precision floating point number. More...
 
double parseDouble (const char *aExpected)
 
double parseDouble (TSCHEMATIC_T::T aToken)
 
int parseInternalUnits ()
 
int parseInternalUnits (const char *aExpected)
 
int parseInternalUnits (TSCHEMATIC_T::T aToken)
 
wxPoint parseXY ()
 
bool parseBool ()
 
void parseStroke (STROKE_PARAMS &aStroke)
 Parse stroke definition aStroke. More...
 
void parseFill (FILL_PARAMS &aFill)
 
void parseEDA_TEXT (EDA_TEXT *aText)
 
void parsePinNames (std::unique_ptr< LIB_PART > &aSymbol)
 
void parseProperty (std::unique_ptr< LIB_PART > &aSymbol)
 
LIB_ARCparseArc ()
 
LIB_BEZIERparseBezier ()
 
LIB_CIRCLEparseCircle ()
 
LIB_PINparsePin ()
 
LIB_POLYLINEparsePolyLine ()
 
LIB_RECTANGLEparseRectangle ()
 
LIB_TEXTparseText ()
 
void parsePAGE_INFO (PAGE_INFO &aPageInfo)
 
void parseTITLE_BLOCK (TITLE_BLOCK &aTitleBlock)
 
void parseSchSymbolInstances (SCH_SCREEN *aScreen)
 
SCH_SHEET_PINparseSchSheetPin (SCH_SHEET *aSheet)
 
SCH_FIELDparseSchField (SCH_ITEM *aParent)
 
SCH_COMPONENTparseSchematicSymbol ()
 
SCH_BITMAPparseImage ()
 
SCH_SHEETparseSheet ()
 
SCH_JUNCTIONparseJunction ()
 
SCH_NO_CONNECTparseNoConnect ()
 
SCH_BUS_WIRE_ENTRYparseBusEntry ()
 
SCH_LINEparseLine ()
 
SCH_TEXTparseSchText ()
 
void parseBusAlias (SCH_SCREEN *aScreen)
 

Private Attributes

int m_requiredVersion
 Set to the symbol library file version required. More...
 
int m_fieldId
 The current field ID. More...
 
int m_unit
 The current unit being parsed. More...
 
int m_convert
 The current body style being parsed. More...
 
wxString m_symbolName
 The current symbol name. More...
 

Detailed Description

Object to parser s-expression symbol library and schematic file formats.

Definition at line 79 of file sch_sexpr_parser.h.

Constructor & Destructor Documentation

◆ SCH_SEXPR_PARSER()

SCH_SEXPR_PARSER::SCH_SEXPR_PARSER ( LINE_READER aLineReader = nullptr)

Definition at line 61 of file sch_sexpr_parser.cpp.

61  :
62  SCHEMATIC_LEXER( aLineReader ),
63  m_requiredVersion( 0 ),
64  m_fieldId( 0 ),
65  m_unit( 1 ),
66  m_convert( 1 )
67 {
68 }
int m_fieldId
The current field ID.
int m_unit
The current unit being parsed.
int m_convert
The current body style being parsed.
int m_requiredVersion
Set to the symbol library file version required.

Member Function Documentation

◆ IsTooRecent()

bool SCH_SEXPR_PARSER::IsTooRecent ( ) const

Return whether a version number, if any was parsed, was too recent.

Definition at line 86 of file sch_sexpr_parser.cpp.

87 {
89 }
#define SEXPR_SYMBOL_LIB_FILE_VERSION
This file contains the file format version information for the s-expression schematic and symbol libr...
int m_requiredVersion
Set to the symbol library file version required.

References m_requiredVersion, and SEXPR_SYMBOL_LIB_FILE_VERSION.

◆ parseArc()

LIB_ARC * SCH_SEXPR_PARSER::parseArc ( )
private

Definition at line 827 of file sch_sexpr_parser.cpp.

828 {
829  wxCHECK_MSG( CurTok() == T_arc, nullptr,
830  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as an arc token." ) );
831 
832  T token;
833  wxPoint startPoint;
834  wxPoint midPoint;
835  wxPoint endPoint;
836  wxPoint pos;
837  FILL_PARAMS fill;
838  bool hasMidPoint = false;
839  std::unique_ptr<LIB_ARC> arc( new LIB_ARC( nullptr ) );
840 
841  arc->SetUnit( m_unit );
842  arc->SetConvert( m_convert );
843 
844  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
845  {
846  if( token != T_LEFT )
847  Expecting( T_LEFT );
848 
849  token = NextTok();
850 
851  switch( token )
852  {
853  case T_start:
854  startPoint = parseXY();
855  NeedRIGHT();
856  break;
857 
858  case T_mid:
859  midPoint = parseXY();
860  NeedRIGHT();
861  hasMidPoint = true;
862  break;
863 
864  case T_end:
865  endPoint = parseXY();
866  NeedRIGHT();
867  break;
868 
869  case T_radius:
870  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
871  {
872  if( token != T_LEFT )
873  Expecting( T_LEFT );
874 
875  token = NextTok();
876 
877  switch( token )
878  {
879  case T_at:
880  pos = parseXY();
881  NeedRIGHT();
882  break;
883 
884  case T_length:
885  arc->SetRadius( parseInternalUnits( "radius length" ) );
886  NeedRIGHT();
887  break;
888 
889  case T_angles:
890  {
891  int angle1 = KiROUND( parseDouble( "start radius angle" ) * 10.0 );
892  int angle2 = KiROUND( parseDouble( "end radius angle" ) * 10.0 );
893 
894  NORMALIZE_ANGLE_POS( angle1 );
895  NORMALIZE_ANGLE_POS( angle2 );
896  arc->SetFirstRadiusAngle( angle1 );
897  arc->SetSecondRadiusAngle( angle2 );
898  NeedRIGHT();
899  break;
900  }
901 
902  default:
903  Expecting( "at, length, or angle" );
904  }
905  }
906 
907  break;
908 
909  case T_stroke:
910  NeedLEFT();
911  token = NextTok();
912 
913  if( token != T_width )
914  Expecting( "width" );
915 
916  arc->SetWidth( parseInternalUnits( "stroke width" ) );
917  NeedRIGHT(); // Closes width token;
918  NeedRIGHT(); // Closes stroke token;
919  break;
920 
921  case T_fill:
922  parseFill( fill );
923  arc->SetFillMode( fill.m_FillType );
924  break;
925 
926  default:
927  Expecting( "start, end, radius, stroke, or fill" );
928  }
929  }
930 
931  arc->SetPosition( pos );
932  arc->SetStart( startPoint );
933  arc->SetEnd( endPoint );
934 
935  if( hasMidPoint )
936  {
937  VECTOR2I center = GetArcCenter( arc->GetStart(), midPoint, arc->GetEnd() );
938 
939  arc->SetPosition( wxPoint( center.x, center.y ) );
940 
941  // @todo Calculate the radius.
942 
943  arc->CalcRadiusAngles();
944  }
945 
946  return arc.release();
947 }
int m_unit
The current unit being parsed.
T
enum T contains all this lexer's tokens.
void NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:257
Simple container to manage fill parameters.
int m_convert
The current body style being parsed.
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68
void parseFill(FILL_PARAMS &aFill)
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...
const VECTOR2I GetArcCenter(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Determine the center of an arc or circle given three points on its circumference.
Definition: trigo.cpp:397

References GetArcCenter(), KiROUND(), m_convert, FILL_PARAMS::m_FillType, m_unit, NORMALIZE_ANGLE_POS(), parseDouble(), parseFill(), parseInternalUnits(), parseXY(), DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by ParseDrawItem().

◆ parseBezier()

LIB_BEZIER * SCH_SEXPR_PARSER::parseBezier ( )
private

Definition at line 950 of file sch_sexpr_parser.cpp.

951 {
952  wxCHECK_MSG( CurTok() == T_bezier, nullptr,
953  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a bezier." ) );
954 
955  T token;
956  FILL_PARAMS fill;
957  std::unique_ptr<LIB_BEZIER> bezier( new LIB_BEZIER( nullptr ) );
958 
959  bezier->SetUnit( m_unit );
960  bezier->SetConvert( m_convert );
961 
962  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
963  {
964  if( token != T_LEFT )
965  Expecting( T_LEFT );
966 
967  token = NextTok();
968 
969  switch( token )
970  {
971  case T_pts:
972  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
973  {
974  if( token != T_LEFT )
975  Expecting( T_LEFT );
976 
977  token = NextTok();
978 
979  if( token != T_xy )
980  Expecting( "xy" );
981 
982  bezier->AddPoint( parseXY() );
983 
984  NeedRIGHT();
985  }
986 
987  break;
988 
989  case T_stroke:
990  NeedLEFT();
991  token = NextTok();
992 
993  if( token != T_width )
994  Expecting( "width" );
995 
996  bezier->SetWidth( parseInternalUnits( "stroke width" ) );
997  NeedRIGHT(); // Closes width token;
998  NeedRIGHT(); // Closes stroke token;
999  break;
1000 
1001  case T_fill:
1002  parseFill( fill );
1003  bezier->SetFillMode( fill.m_FillType );
1004  break;
1005 
1006  default:
1007  Expecting( "pts, stroke, or fill" );
1008  }
1009  }
1010 
1011  return bezier.release();
1012 }
int m_unit
The current unit being parsed.
T
enum T contains all this lexer's tokens.
Simple container to manage fill parameters.
int m_convert
The current body style being parsed.
void parseFill(FILL_PARAMS &aFill)
Define a bezier curve graphic body item.
Definition: lib_bezier.h:34

References m_convert, FILL_PARAMS::m_FillType, m_unit, parseFill(), parseInternalUnits(), parseXY(), DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

Referenced by ParseDrawItem().

◆ parseBool()

bool SCH_SEXPR_PARSER::parseBool ( )
private

Definition at line 71 of file sch_sexpr_parser.cpp.

72 {
73  T token = NextTok();
74 
75  if( token == T_yes )
76  return true;
77  else if( token == T_no )
78  return false;
79  else
80  Expecting( "yes or no" );
81 
82  return false;
83 }
T
enum T contains all this lexer's tokens.

Referenced by parseSchematicSymbol().

◆ parseBusAlias()

void SCH_SEXPR_PARSER::parseBusAlias ( SCH_SCREEN aScreen)
private

Definition at line 2647 of file sch_sexpr_parser.cpp.

2648 {
2649  wxCHECK_RET( CurTok() == T_bus_alias,
2650  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a bus alias." ) );
2651  wxCHECK( aScreen, /* void */ );
2652 
2653  T token;
2654  auto busAlias = std::make_shared< BUS_ALIAS >( aScreen );
2655 
2656  NeedSYMBOL();
2657  busAlias->SetName( FromUTF8() );
2658  NeedLEFT();
2659  token = NextTok();
2660 
2661  if( token != T_members )
2662  Expecting( "members" );
2663 
2664  token = NextTok();
2665 
2666  while( token != T_RIGHT )
2667  {
2668  if( !IsSymbol( token ) )
2669  Expecting( "quoted string" );
2670 
2671  busAlias->AddMember( FromUTF8() );
2672  token = NextTok();
2673  }
2674 
2675  NeedRIGHT();
2676 
2677  aScreen->AddBusAlias( busAlias );
2678 }
T
enum T contains all this lexer's tokens.
void AddBusAlias(std::shared_ptr< BUS_ALIAS > aAlias)
Adds a bus alias definition (and transfers ownership of the pointer)

References SCH_SCREEN::AddBusAlias(), and DRCRULE_T::T_RIGHT.

Referenced by ParseSchematic().

◆ parseBusEntry()

SCH_BUS_WIRE_ENTRY * SCH_SEXPR_PARSER::parseBusEntry ( )
private

Definition at line 2456 of file sch_sexpr_parser.cpp.

2457 {
2458  wxCHECK_MSG( CurTok() == T_bus_entry, nullptr,
2459  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a bus entry." ) );
2460 
2461  T token;
2462  STROKE_PARAMS stroke;
2463  std::unique_ptr<SCH_BUS_WIRE_ENTRY> busEntry( new SCH_BUS_WIRE_ENTRY() );
2464 
2465  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2466  {
2467  if( token != T_LEFT )
2468  Expecting( T_LEFT );
2469 
2470  token = NextTok();
2471 
2472  switch( token )
2473  {
2474  case T_at:
2475  busEntry->SetPosition( parseXY() );
2476  NeedRIGHT();
2477  break;
2478 
2479  case T_size:
2480  {
2481  wxSize size;
2482 
2483  size.SetWidth( parseInternalUnits( "bus entry height" ) );
2484  size.SetHeight( parseInternalUnits( "bus entry width" ) );
2485  busEntry->SetSize( size );
2486  NeedRIGHT();
2487  break;
2488  }
2489 
2490  case T_stroke:
2491  parseStroke( stroke );
2492  busEntry->SetStroke( stroke );
2493  break;
2494 
2495  default:
2496  Expecting( "at, size, or stroke" );
2497  }
2498  }
2499 
2500  return busEntry.release();
2501 }
T
enum T contains all this lexer's tokens.
Simple container to manage line stroke parameters.
Definition: sch_item.h:153
Class for a wire to bus entry.
void parseStroke(STROKE_PARAMS &aStroke)
Parse stroke definition aStroke.

References parseInternalUnits(), parseStroke(), parseXY(), DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

Referenced by ParseSchematic().

◆ parseCircle()

LIB_CIRCLE * SCH_SEXPR_PARSER::parseCircle ( )
private

Definition at line 1015 of file sch_sexpr_parser.cpp.

1016 {
1017  wxCHECK_MSG( CurTok() == T_circle, nullptr,
1018  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a circle token." ) );
1019 
1020  T token;
1021  FILL_PARAMS fill;
1022  std::unique_ptr<LIB_CIRCLE> circle( new LIB_CIRCLE( nullptr ) );
1023 
1024  circle->SetUnit( m_unit );
1025  circle->SetConvert( m_convert );
1026 
1027  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1028  {
1029  if( token != T_LEFT )
1030  Expecting( T_LEFT );
1031 
1032  token = NextTok();
1033 
1034  switch( token )
1035  {
1036  case T_center:
1037  circle->SetPosition( parseXY() );
1038  NeedRIGHT();
1039  break;
1040 
1041  case T_radius:
1042  circle->SetRadius( parseInternalUnits( "radius length" ) );
1043  NeedRIGHT();
1044  break;
1045 
1046  case T_stroke:
1047  NeedLEFT();
1048  token = NextTok();
1049 
1050  if( token != T_width )
1051  Expecting( "width" );
1052 
1053  circle->SetWidth( parseInternalUnits( "stroke width" ) );
1054  NeedRIGHT(); // Closes width token;
1055  NeedRIGHT(); // Closes stroke token;
1056  break;
1057 
1058  case T_fill:
1059  parseFill( fill );
1060  circle->SetFillMode( fill.m_FillType );
1061  break;
1062 
1063  default:
1064  Expecting( "start, end, radius, stroke, or fill" );
1065  }
1066  }
1067 
1068  return circle.release();
1069 }
int m_unit
The current unit being parsed.
T
enum T contains all this lexer's tokens.
Simple container to manage fill parameters.
int m_convert
The current body style being parsed.
void parseFill(FILL_PARAMS &aFill)

References m_convert, FILL_PARAMS::m_FillType, m_unit, parseFill(), parseInternalUnits(), parseXY(), DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

Referenced by ParseDrawItem().

◆ parseDouble() [1/3]

double SCH_SEXPR_PARSER::parseDouble ( )
private

Parse the current token as an ASCII numeric string with possible leading whitespace into a double precision floating point number.

Exceptions
IO_ERRORif an error occurs attempting to convert the current token.
Returns
The result of the parsed token.

Definition at line 386 of file sch_sexpr_parser.cpp.

387 {
388  char* tmp;
389 
390  errno = 0;
391 
392  double fval = strtod( CurText(), &tmp );
393 
394  if( errno )
395  {
396  wxString error;
397  error.Printf( _( "Invalid floating point number in\nfile: \"%s\"\nline: %d\noffset: %d" ),
398  CurSource().c_str(), CurLineNumber(), CurOffset() );
399 
400  THROW_IO_ERROR( error );
401  }
402 
403  if( CurText() == tmp )
404  {
405  wxString error;
406  error.Printf( _( "Missing floating point number in\nfile: \"%s\"\nline: %d\noffset: %d" ),
407  CurSource().c_str(), CurLineNumber(), CurOffset() );
408 
409  THROW_IO_ERROR( error );
410  }
411 
412  return fval;
413 }
#define THROW_IO_ERROR(msg)
#define _(s)
Definition: 3d_actions.cpp:33

References _, and THROW_IO_ERROR.

Referenced by parseArc(), parseDouble(), parseFill(), parseImage(), parseInternalUnits(), parseJunction(), parsePAGE_INFO(), parseProperty(), parseSchematicSymbol(), parseSchField(), parseSchSheetPin(), parseSchText(), parseStroke(), and parseText().

◆ parseDouble() [2/3]

double SCH_SEXPR_PARSER::parseDouble ( const char *  aExpected)
inlineprivate

Definition at line 115 of file sch_sexpr_parser.h.

116  {
117  NeedNUMBER( aExpected );
118  return parseDouble();
119  }
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...

References parseDouble().

◆ parseDouble() [3/3]

double SCH_SEXPR_PARSER::parseDouble ( TSCHEMATIC_T::T  aToken)
inlineprivate

Definition at line 121 of file sch_sexpr_parser.h.

122  {
123  return parseDouble( GetTokenText( aToken ) );
124  }
const char * GetTokenText(T aTok)
Function GetTokenText is in the DSN namespace and returns the C string representing a SPECCTRA_DB::ke...
Definition: specctra.cpp:69
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...

References DSN::GetTokenText(), and parseDouble().

◆ ParseDrawItem()

LIB_ITEM * SCH_SEXPR_PARSER::ParseDrawItem ( )

Definition at line 346 of file sch_sexpr_parser.cpp.

347 {
348  switch( CurTok() )
349  {
350  case T_arc:
351  return static_cast<LIB_ITEM*>( parseArc() );
352  break;
353 
354  case T_bezier:
355  return static_cast<LIB_ITEM*>( parseBezier() );
356  break;
357 
358  case T_circle:
359  return static_cast<LIB_ITEM*>( parseCircle() );
360  break;
361 
362  case T_pin:
363  return static_cast<LIB_ITEM*>( parsePin() );
364  break;
365 
366  case T_polyline:
367  return static_cast<LIB_ITEM*>( parsePolyLine() );
368  break;
369 
370  case T_rectangle:
371  return static_cast<LIB_ITEM*>( parseRectangle() );
372  break;
373 
374  case T_text:
375  return static_cast<LIB_TEXT*>( parseText() );
376  break;
377 
378  default:
379  Expecting( "arc, bezier, circle, pin, polyline, rectangle, or text" );
380  }
381 
382  return nullptr;
383 }
LIB_POLYLINE * parsePolyLine()
LIB_RECTANGLE * parseRectangle()
LIB_BEZIER * parseBezier()
LIB_CIRCLE * parseCircle()

References parseArc(), parseBezier(), parseCircle(), parsePin(), parsePolyLine(), parseRectangle(), and parseText().

Referenced by ParseSymbol().

◆ parseEDA_TEXT()

void SCH_SEXPR_PARSER::parseEDA_TEXT ( EDA_TEXT aText)
private

Definition at line 537 of file sch_sexpr_parser.cpp.

538 {
539  wxCHECK_RET( aText && CurTok() == T_effects,
540  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as EDA_TEXT." ) );
541 
542  T token;
543 
544  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
545  {
546  if( token == T_LEFT )
547  token = NextTok();
548 
549  switch( token )
550  {
551  case T_font:
552  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
553  {
554  if( token == T_LEFT )
555  token = NextTok();
556 
557  switch( token )
558  {
559  case T_size:
560  {
561  wxSize sz;
562  sz.SetHeight( parseInternalUnits( "text height" ) );
563  sz.SetWidth( parseInternalUnits( "text width" ) );
564  aText->SetTextSize( sz );
565  NeedRIGHT();
566  break;
567  }
568 
569  case T_thickness:
570  aText->SetTextThickness( parseInternalUnits( "text thickness" ) );
571  NeedRIGHT();
572  break;
573 
574  case T_bold:
575  aText->SetBold( true );
576  break;
577 
578  case T_italic:
579  aText->SetItalic( true );
580  break;
581 
582  default:
583  Expecting( "size, bold, or italic" );
584  }
585  }
586 
587  break;
588 
589  case T_justify:
590  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
591  {
592  switch( token )
593  {
594  case T_left:
596  break;
597 
598  case T_right:
600  break;
601 
602  case T_top:
604  break;
605 
606  case T_bottom:
608  break;
609 
610  case T_mirror:
611  aText->SetMirrored( true );
612  break;
613 
614  default:
615  Expecting( "left, right, top, bottom, or mirror" );
616  }
617  }
618 
619  break;
620 
621  case T_hide:
622  aText->SetVisible( false );
623  break;
624 
625  default:
626  Expecting( "font, justify, or hide" );
627  }
628  }
629 }
void SetMirrored(bool isMirrored)
Definition: eda_text.h:187
void SetItalic(bool isItalic)
Definition: eda_text.h:178
void SetVisible(bool aVisible)
Definition: eda_text.h:184
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:237
T
enum T contains all this lexer's tokens.
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:202
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:201
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.h:157
void SetBold(bool aBold)
Definition: eda_text.h:181

References GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_BOTTOM, GR_TEXT_VJUSTIFY_TOP, parseInternalUnits(), EDA_TEXT::SetBold(), EDA_TEXT::SetHorizJustify(), EDA_TEXT::SetItalic(), EDA_TEXT::SetMirrored(), EDA_TEXT::SetTextSize(), EDA_TEXT::SetTextThickness(), EDA_TEXT::SetVertJustify(), EDA_TEXT::SetVisible(), DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

Referenced by parsePin(), parseProperty(), parseSchField(), parseSchSheetPin(), parseSchText(), and parseText().

◆ parseFill()

void SCH_SEXPR_PARSER::parseFill ( FILL_PARAMS aFill)
private

Definition at line 481 of file sch_sexpr_parser.cpp.

482 {
483  wxCHECK_RET( CurTok() == T_fill,
484  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as fill." ) );
485 
486  aFill.m_FillType = NO_FILL;
487  aFill.m_Color = COLOR4D::UNSPECIFIED;
488 
489  T token;
490 
491  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
492  {
493  if( token != T_LEFT )
494  Expecting( T_LEFT );
495 
496  token = NextTok();
497 
498  switch( token )
499  {
500  case T_type:
501  {
502  token = NextTok();
503 
504  switch( token )
505  {
506  case T_none: aFill.m_FillType = NO_FILL; break;
507  case T_outline: aFill.m_FillType = FILLED_SHAPE; break;
508  case T_background: aFill.m_FillType = FILLED_WITH_BG_BODYCOLOR; break;
509  default:
510  Expecting( "none, outline, or background" );
511  }
512 
513  NeedRIGHT();
514  break;
515  }
516 
517  case T_color:
518  {
519  COLOR4D color;
520 
521  color.r = parseInt( "red" ) / 255.0;
522  color.g = parseInt( "green" ) / 255.0;
523  color.b = parseInt( "blue" ) / 255.0;
524  color.a = Clamp( parseDouble( "alpha" ), 0.0, 1.0 );
525  aFill.m_Color = color;
526  NeedRIGHT();
527  break;
528  }
529 
530  default:
531  Expecting( "type or color" );
532  }
533  }
534 }
int color
Definition: DXF_plotter.cpp:61
T
enum T contains all this lexer's tokens.
const T & Clamp(const T &lower, const T &value, const T &upper)
Function Clamp limits value within the range lower <= value <= upper.
Definition: util.h:46
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:99

References Clamp(), color, FILLED_SHAPE, FILLED_WITH_BG_BODYCOLOR, FILL_PARAMS::m_Color, FILL_PARAMS::m_FillType, NO_FILL, parseDouble(), parseInt(), DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, and DRCRULE_T::T_type.

Referenced by parseArc(), parseBezier(), parseCircle(), parsePolyLine(), parseRectangle(), and parseSheet().

◆ parseHeader()

void SCH_SEXPR_PARSER::parseHeader ( TSCHEMATIC_T::T  aHeaderType,
int  aFileVersion 
)
private

Definition at line 632 of file sch_sexpr_parser.cpp.

633 {
634  wxCHECK_RET( CurTok() == aHeaderType,
635  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a header." ) );
636 
637  NeedLEFT();
638 
639  T tok = NextTok();
640 
641  if( tok == T_version )
642  {
643  m_requiredVersion = parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
644  NeedRIGHT();
645 
646  // Skip the host name and host build version information.
647  NeedLEFT();
648  NeedSYMBOL();
649  NeedSYMBOL();
650  NeedSYMBOL();
651  NeedRIGHT();
652  }
653  else
654  {
655  m_requiredVersion = aFileVersion;
656 
657  // Skip the host name and host build version information.
658  NeedSYMBOL();
659  NeedSYMBOL();
660  NeedRIGHT();
661  }
662 }
T
enum T contains all this lexer's tokens.
int m_requiredVersion
Set to the symbol library file version required.

References m_requiredVersion, parseInt(), and DRCRULE_T::T_version.

Referenced by ParseLib(), and ParseSchematic().

◆ parseHex()

long SCH_SEXPR_PARSER::parseHex ( )
inlineprivate

Definition at line 89 of file sch_sexpr_parser.h.

90  {
91  NextTok();
92  return strtol( CurText(), NULL, 16 );
93  }
#define NULL

References NULL.

◆ parseImage()

SCH_BITMAP * SCH_SEXPR_PARSER::parseImage ( )
private

Definition at line 2220 of file sch_sexpr_parser.cpp.

2221 {
2222  wxCHECK_MSG( CurTok() == T_image, nullptr,
2223  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as an image." ) );
2224 
2225  T token;
2226  std::unique_ptr<SCH_BITMAP> bitmap( new SCH_BITMAP() );
2227 
2228  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2229  {
2230  if( token != T_LEFT )
2231  Expecting( T_LEFT );
2232 
2233  token = NextTok();
2234 
2235  switch( token )
2236  {
2237  case T_at:
2238  bitmap->SetPosition( parseXY() );
2239  NeedRIGHT();
2240  break;
2241 
2242  case T_scale:
2243  bitmap->GetImage()->SetScale( parseDouble( "image scale factor" ) );
2244 
2245  if( !std::isnormal( bitmap->GetImage()->GetScale() ) )
2246  bitmap->GetImage()->SetScale( 1.0 );
2247 
2248  NeedRIGHT();
2249  break;
2250 
2251  case T_data:
2252  {
2253  token = NextTok();
2254 
2255  wxString data;
2256 
2257  // Reserve 128K because most image files are going to be larger than the default
2258  // 1K that wxString reserves.
2259  data.reserve( 1 << 17 );
2260 
2261  while( token != T_RIGHT )
2262  {
2263  if( !IsSymbol( token ) )
2264  Expecting( "base64 image data" );
2265 
2266  data += FromUTF8();
2267  token = NextTok();
2268  }
2269 
2270  wxMemoryBuffer buffer = wxBase64Decode( data );
2271  wxMemoryOutputStream stream( buffer.GetData(), buffer.GetBufSize() );
2272  wxImage* image = new wxImage();
2273  wxMemoryInputStream istream( stream );
2274  image->LoadFile( istream, wxBITMAP_TYPE_PNG );
2275  bitmap->GetImage()->SetImage( image );
2276  bitmap->GetImage()->SetBitmap( new wxBitmap( *image ) );
2277  break;
2278  }
2279 
2280  default:
2281  Expecting( "at, scale, or data" );
2282  }
2283  }
2284 
2285  return bitmap.release();
2286 }
T
enum T contains all this lexer's tokens.
Object to handle a bitmap image that can be inserted in a schematic.
Definition: sch_bitmap.h:42
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...

References parseDouble(), parseXY(), DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

Referenced by ParseSchematic().

◆ parseInt() [1/2]

int SCH_SEXPR_PARSER::parseInt ( )
inlineprivate

Definition at line 95 of file sch_sexpr_parser.h.

96  {
97  return (int)strtol( CurText(), NULL, 10 );
98  }
#define NULL

References NULL.

Referenced by parseFill(), parseHeader(), parseInt(), parseJunction(), parsePin(), parseProperty(), parseSchematicSymbol(), parseSchField(), parseSchSymbolInstances(), parseStroke(), and parseTITLE_BLOCK().

◆ parseInt() [2/2]

int SCH_SEXPR_PARSER::parseInt ( const char *  aExpected)
inlineprivate

Definition at line 100 of file sch_sexpr_parser.h.

101  {
102  NeedNUMBER( aExpected );
103  return parseInt();
104  }

References parseInt().

◆ parseInternalUnits() [1/3]

int SCH_SEXPR_PARSER::parseInternalUnits ( )
inlineprivate

Definition at line 126 of file sch_sexpr_parser.h.

127  {
128  auto retval = parseDouble() * IU_PER_MM;
129 
130  // Schematic internal units are represented as integers. Any values that are
131  // larger or smaller than the schematic units represent undefined behavior for
132  // the system. Limit values to the largest that can be displayed on the screen.
133  double int_limit = std::numeric_limits<int>::max() * 0.7071; // 0.7071 = roughly 1/sqrt(2)
134 
135  return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
136  }
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...

References KiROUND(), and parseDouble().

Referenced by parseArc(), parseBezier(), parseBusEntry(), parseCircle(), parseEDA_TEXT(), parseInternalUnits(), parseJunction(), parsePin(), parsePinNames(), parsePolyLine(), parseRectangle(), parseSheet(), parseStroke(), and parseXY().

◆ parseInternalUnits() [2/3]

int SCH_SEXPR_PARSER::parseInternalUnits ( const char *  aExpected)
inlineprivate

Definition at line 138 of file sch_sexpr_parser.h.

139  {
140  auto retval = parseDouble( aExpected ) * IU_PER_MM;
141 
142  double int_limit = std::numeric_limits<int>::max() * 0.7071;
143 
144  return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
145  }
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...

References KiROUND(), and parseDouble().

◆ parseInternalUnits() [3/3]

int SCH_SEXPR_PARSER::parseInternalUnits ( TSCHEMATIC_T::T  aToken)
inlineprivate

Definition at line 147 of file sch_sexpr_parser.h.

148  {
149  return parseInternalUnits( GetTokenText( aToken ) );
150  }
const char * GetTokenText(T aTok)
Function GetTokenText is in the DSN namespace and returns the C string representing a SPECCTRA_DB::ke...
Definition: specctra.cpp:69

References DSN::GetTokenText(), and parseInternalUnits().

◆ parseJunction()

SCH_JUNCTION * SCH_SEXPR_PARSER::parseJunction ( )
private

Definition at line 2375 of file sch_sexpr_parser.cpp.

2376 {
2377  wxCHECK_MSG( CurTok() == T_junction, nullptr,
2378  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a junction." ) );
2379 
2380  T token;
2381  std::unique_ptr<SCH_JUNCTION> junction( new SCH_JUNCTION() );
2382 
2383  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2384  {
2385  if( token != T_LEFT )
2386  Expecting( T_LEFT );
2387 
2388  token = NextTok();
2389 
2390  switch( token )
2391  {
2392  case T_at:
2393  junction->SetPosition( parseXY() );
2394  NeedRIGHT();
2395  break;
2396 
2397  case T_diameter:
2398  junction->SetDiameter( parseInternalUnits( "junction diameter" ) );
2399  NeedRIGHT();
2400  break;
2401 
2402  case T_color:
2403  {
2404  COLOR4D color;
2405 
2406  color.r = parseInt( "red" ) / 255.0;
2407  color.g = parseInt( "green" ) / 255.0;
2408  color.b = parseInt( "blue" ) / 255.0;
2409  color.a = Clamp( parseDouble( "alpha" ), 0.0, 1.0 );
2410 
2411  junction->SetColor( color );
2412  NeedRIGHT();
2413  break;
2414  }
2415 
2416  default:
2417  Expecting( "at" );
2418  }
2419  }
2420 
2421  return junction.release();
2422 }
int color
Definition: DXF_plotter.cpp:61
T
enum T contains all this lexer's tokens.
const T & Clamp(const T &lower, const T &value, const T &upper)
Function Clamp limits value within the range lower <= value <= upper.
Definition: util.h:46
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:99

References Clamp(), color, parseDouble(), parseInt(), parseInternalUnits(), parseXY(), DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

Referenced by ParseSchematic().

◆ ParseLib()

void SCH_SEXPR_PARSER::ParseLib ( LIB_PART_MAP aSymbolLibMap)

Definition at line 92 of file sch_sexpr_parser.cpp.

93 {
94  T token;
95 
96  NeedLEFT();
97  NextTok();
98  parseHeader( T_kicad_symbol_lib, SEXPR_SYMBOL_LIB_FILE_VERSION );
99 
100  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
101  {
102  if( token != T_LEFT )
103  Expecting( T_LEFT );
104 
105  token = NextTok();
106 
107  if( token == T_symbol )
108  {
109  m_unit = 1;
110  m_convert = 1;
111  LIB_PART* symbol = ParseSymbol( aSymbolLibMap, m_requiredVersion );
112  aSymbolLibMap[symbol->GetName()] = symbol;
113  }
114  else
115  {
116  Expecting( "symbol" );
117  }
118  }
119 }
LIB_PART * ParseSymbol(LIB_PART_MAP &aSymbolLibMap, int aFileVersion=SEXPR_SYMBOL_LIB_FILE_VERSION)
wxString GetName() const override
int m_unit
The current unit being parsed.
T
enum T contains all this lexer's tokens.
#define SEXPR_SYMBOL_LIB_FILE_VERSION
This file contains the file format version information for the s-expression schematic and symbol libr...
void parseHeader(TSCHEMATIC_T::T aHeaderType, int aFileVersion)
int m_convert
The current body style being parsed.
Define a library symbol object.
int m_requiredVersion
Set to the symbol library file version required.

References LIB_PART::GetName(), m_convert, m_requiredVersion, m_unit, parseHeader(), ParseSymbol(), SEXPR_SYMBOL_LIB_FILE_VERSION, DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

◆ parseLine()

SCH_LINE * SCH_SEXPR_PARSER::parseLine ( )
private

Definition at line 2504 of file sch_sexpr_parser.cpp.

2505 {
2506  T token;
2507  STROKE_PARAMS stroke;
2508  std::unique_ptr<SCH_LINE> line( new SCH_LINE() );
2509 
2510  switch( CurTok() )
2511  {
2512  case T_polyline: line->SetLayer( LAYER_NOTES ); break;
2513  case T_wire: line->SetLayer( LAYER_WIRE ); break;
2514  case T_bus: line->SetLayer( LAYER_BUS ); break;
2515  default:
2516  wxCHECK_MSG( false, nullptr,
2517  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a line." ) );
2518  }
2519 
2520  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2521  {
2522  if( token != T_LEFT )
2523  Expecting( T_LEFT );
2524 
2525  token = NextTok();
2526 
2527  switch( token )
2528  {
2529  case T_pts:
2530  NeedLEFT();
2531  token = NextTok();
2532 
2533  if( token != T_xy )
2534  Expecting( "xy" );
2535 
2536  line->SetStartPoint( parseXY() );
2537  NeedRIGHT();
2538  NeedLEFT();
2539  token = NextTok();
2540 
2541  if( token != T_xy )
2542  Expecting( "xy" );
2543 
2544  line->SetEndPoint( parseXY() );
2545  NeedRIGHT();
2546  NeedRIGHT();
2547  break;
2548 
2549  case T_stroke:
2550  parseStroke( stroke );
2551  line->SetStroke( stroke );
2552  break;
2553 
2554  default:
2555  Expecting( "at or stroke" );
2556  }
2557  }
2558 
2559  return line.release();
2560 }
T
enum T contains all this lexer's tokens.
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:37
Simple container to manage line stroke parameters.
Definition: sch_item.h:153
void parseStroke(STROKE_PARAMS &aStroke)
Parse stroke definition aStroke.

References LAYER_BUS, LAYER_NOTES, LAYER_WIRE, parseStroke(), parseXY(), DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

Referenced by ParseSchematic().

◆ parseNoConnect()

SCH_NO_CONNECT * SCH_SEXPR_PARSER::parseNoConnect ( )
private

Definition at line 2425 of file sch_sexpr_parser.cpp.

2426 {
2427  wxCHECK_MSG( CurTok() == T_no_connect, nullptr,
2428  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a no connect." ) );
2429 
2430  T token;
2431  std::unique_ptr<SCH_NO_CONNECT> no_connect( new SCH_NO_CONNECT() );
2432 
2433  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2434  {
2435  if( token != T_LEFT )
2436  Expecting( T_LEFT );
2437 
2438  token = NextTok();
2439 
2440  switch( token )
2441  {
2442  case T_at:
2443  no_connect->SetPosition( parseXY() );
2444  NeedRIGHT();
2445  break;
2446 
2447  default:
2448  Expecting( "at" );
2449  }
2450  }
2451 
2452  return no_connect.release();
2453 }
T
enum T contains all this lexer's tokens.

References parseXY(), DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

Referenced by ParseSchematic().

◆ parsePAGE_INFO()

void SCH_SEXPR_PARSER::parsePAGE_INFO ( PAGE_INFO aPageInfo)
private

Definition at line 1485 of file sch_sexpr_parser.cpp.

1486 {
1487  wxCHECK_RET( ( CurTok() == T_page && m_requiredVersion <= 20200506 ) || CurTok() == T_paper,
1488  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a PAGE_INFO." ) );
1489 
1490  T token;
1491 
1492  NeedSYMBOL();
1493 
1494  wxString pageType = FromUTF8();
1495 
1496  if( !aPageInfo.SetType( pageType ) )
1497  {
1498  wxString err;
1499  err.Printf( _( "Page type \"%s\" is not valid " ), GetChars( FromUTF8() ) );
1500  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
1501  }
1502 
1503  if( pageType == PAGE_INFO::Custom )
1504  {
1505  double width = parseDouble( "width" ); // width in mm
1506 
1507  // Perform some controls to avoid crashes if the size is edited by hands
1508  if( width < 100.0 )
1509  width = 100.0;
1510  else if( width > 1200.0 )
1511  width = 1200.0;
1512 
1513  double height = parseDouble( "height" ); // height in mm
1514 
1515  if( height < 100.0 )
1516  height = 100.0;
1517  else if( height > 1200.0 )
1518  height = 1200.0;
1519 
1520  aPageInfo.SetWidthMils( Mm2mils( width ) );
1521  aPageInfo.SetHeightMils( Mm2mils( height ) );
1522  }
1523 
1524  token = NextTok();
1525 
1526  if( token == T_portrait )
1527  {
1528  aPageInfo.SetPortrait( true );
1529  NeedRIGHT();
1530  }
1531  else if( token != T_RIGHT )
1532  {
1533  Expecting( "portrait" );
1534  }
1535 }
int Mm2mils(double x)
Convert mm to mils.
Definition: base_units.h:62
bool SetType(const wxString &aStandardPageDescriptionName, bool aIsPortrait=false)
Function SetType sets the name of the page type and also the sizes and margins commonly associated wi...
Definition: page_info.cpp:117
static const wxChar Custom[]
"User" defined page type
Definition: page_info.h:78
T
enum T contains all this lexer's tokens.
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
void SetHeightMils(int aHeightInMils)
Definition: page_info.cpp:253
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:153
int m_requiredVersion
Set to the symbol library file version required.
#define _(s)
Definition: 3d_actions.cpp:33
void SetWidthMils(int aWidthInMils)
Definition: page_info.cpp:239
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...
void SetPortrait(bool aIsPortrait)
Function SetPortrait will rotate the paper page 90 degrees.
Definition: page_info.cpp:182

References _, PAGE_INFO::Custom, GetChars(), m_requiredVersion, Mm2mils(), parseDouble(), PAGE_INFO::SetHeightMils(), PAGE_INFO::SetPortrait(), PAGE_INFO::SetType(), PAGE_INFO::SetWidthMils(), DRCRULE_T::T_RIGHT, and THROW_PARSE_ERROR.

Referenced by ParseSchematic().

◆ parsePin()

LIB_PIN * SCH_SEXPR_PARSER::parsePin ( )
private

Definition at line 1072 of file sch_sexpr_parser.cpp.

1073 {
1074  wxCHECK_MSG( CurTok() == T_pin, nullptr,
1075  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a pin token." ) );
1076 
1077  T token;
1078  wxString tmp;
1079  wxString error;
1080  std::unique_ptr<LIB_PIN> pin( new LIB_PIN( nullptr ) );
1081 
1082  pin->SetUnit( m_unit );
1083  pin->SetConvert( m_convert );
1084 
1085  // Pin electrical type.
1086  token = NextTok();
1087 
1088  switch( token )
1089  {
1090  case T_input:
1091  pin->SetType( ELECTRICAL_PINTYPE::PT_INPUT );
1092  break;
1093 
1094  case T_output:
1095  pin->SetType( ELECTRICAL_PINTYPE::PT_OUTPUT );
1096  break;
1097 
1098  case T_bidirectional:
1099  pin->SetType( ELECTRICAL_PINTYPE::PT_BIDI );
1100  break;
1101 
1102  case T_tri_state:
1103  pin->SetType( ELECTRICAL_PINTYPE::PT_TRISTATE );
1104  break;
1105 
1106  case T_passive:
1107  pin->SetType( ELECTRICAL_PINTYPE::PT_PASSIVE );
1108  break;
1109 
1110  case T_unspecified:
1111  pin->SetType( ELECTRICAL_PINTYPE::PT_UNSPECIFIED );
1112  break;
1113 
1114  case T_power_in:
1115  pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
1116  break;
1117 
1118  case T_power_out:
1119  pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_OUT );
1120  break;
1121 
1122  case T_open_collector:
1123  pin->SetType( ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR );
1124  break;
1125 
1126  case T_open_emitter:
1127  pin->SetType( ELECTRICAL_PINTYPE::PT_OPENEMITTER );
1128  break;
1129 
1130  case T_unconnected:
1131  pin->SetType( ELECTRICAL_PINTYPE::PT_NC );
1132  break;
1133 
1134  default:
1135  Expecting( "input, output, bidirectional, tri_state, passive, unspecified, "
1136  "power_in, power_out, open_collector, open_emitter, or unconnected" );
1137  }
1138 
1139  // Pin shape.
1140  token = NextTok();
1141 
1142  switch( token )
1143  {
1144  case T_line:
1145  pin->SetShape( GRAPHIC_PINSHAPE::LINE );
1146  break;
1147 
1148  case T_inverted:
1149  pin->SetShape( GRAPHIC_PINSHAPE::INVERTED );
1150  break;
1151 
1152  case T_clock:
1153  pin->SetShape( GRAPHIC_PINSHAPE::CLOCK );
1154  break;
1155 
1156  case T_inverted_clock:
1157  pin->SetShape( GRAPHIC_PINSHAPE::INVERTED_CLOCK );
1158  break;
1159 
1160  case T_input_low:
1161  pin->SetShape( GRAPHIC_PINSHAPE::INPUT_LOW );
1162  break;
1163 
1164  case T_clock_low:
1165  pin->SetShape( GRAPHIC_PINSHAPE::CLOCK_LOW );
1166  break;
1167 
1168  case T_output_low:
1169  pin->SetShape( GRAPHIC_PINSHAPE::OUTPUT_LOW );
1170  break;
1171 
1172  case T_edge_clock_high:
1173  pin->SetShape( GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK );
1174  break;
1175 
1176  case T_non_logic:
1177  pin->SetShape( GRAPHIC_PINSHAPE::NONLOGIC );
1178  break;
1179 
1180  default:
1181  Expecting( "line, inverted, clock, inverted_clock, input_low, clock_low, "
1182  "output_low, edge_clock_high, non_logic" );
1183  }
1184 
1185  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1186  {
1187  if( token == T_hide )
1188  {
1189  pin->SetVisible( false );
1190  continue;
1191  }
1192 
1193  if( token != T_LEFT )
1194  Expecting( T_LEFT );
1195 
1196  token = NextTok();
1197 
1198  switch( token )
1199  {
1200  case T_at:
1201  pin->SetPosition( parseXY() );
1202 
1203  switch( parseInt( "pin orientation" ) )
1204  {
1205  case 0:
1206  pin->SetOrientation( PIN_RIGHT );
1207  break;
1208 
1209  case 90:
1210  pin->SetOrientation( PIN_UP );
1211  break;
1212 
1213  case 180:
1214  pin->SetOrientation( PIN_LEFT );
1215  break;
1216 
1217  case 270:
1218  pin->SetOrientation( PIN_DOWN );
1219  break;
1220 
1221  default:
1222  Expecting( "0, 90, 180, or 270" );
1223  }
1224 
1225  NeedRIGHT();
1226  break;
1227 
1228  case T_length:
1229  pin->SetLength( parseInternalUnits( "pin length" ) );
1230  NeedRIGHT();
1231  break;
1232 
1233  case T_name:
1234  token = NextTok();
1235 
1236  if( !IsSymbol( token ) )
1237  {
1238  error.Printf( _( "Invalid pin name in\nfile: \"%s\"\nline: %d\noffset: %d" ),
1239  CurSource().c_str(), CurLineNumber(), CurOffset() );
1240  THROW_IO_ERROR( error );
1241  }
1242 
1243  pin->SetName( FromUTF8() );
1244  token = NextTok();
1245 
1246  if( token != T_RIGHT )
1247  {
1248  token = NextTok();
1249 
1250  if( token == T_effects )
1251  {
1252  // The EDA_TEXT font effects formatting is used so use and EDA_TEXT object
1253  // so duplicate parsing is not required.
1254  EDA_TEXT text;
1255 
1256  parseEDA_TEXT( &text );
1257  pin->SetNameTextSize( text.GetTextHeight() );
1258  NeedRIGHT();
1259  }
1260  else
1261  {
1262  Expecting( "effects" );
1263  }
1264  }
1265 
1266  break;
1267 
1268  case T_number:
1269  token = NextTok();
1270 
1271  if( !IsSymbol( token ) )
1272  {
1273  error.Printf( _( "Invalid pin number in\nfile: \"%s\"\nline: %d\noffset: %d" ),
1274  CurSource().c_str(), CurLineNumber(), CurOffset() );
1275  THROW_IO_ERROR( error );
1276  }
1277 
1278  pin->SetNumber( FromUTF8() );
1279  token = NextTok();
1280 
1281  if( token != T_RIGHT )
1282  {
1283  token = NextTok();
1284 
1285  if( token == T_effects )
1286  {
1287  // The EDA_TEXT font effects formatting is used so use and EDA_TEXT object
1288  // so duplicate parsing is not required.
1289  EDA_TEXT text;
1290 
1291  parseEDA_TEXT( &text );
1292  pin->SetNumberTextSize( text.GetTextHeight(), false );
1293  NeedRIGHT();
1294  }
1295  else
1296  {
1297  Expecting( "effects" );
1298  }
1299  }
1300 
1301  break;
1302 
1303  default:
1304  Expecting( "at, name, number, or length" );
1305  }
1306  }
1307 
1308  return pin.release();
1309 }
power input (GND, VCC for ICs). Must be connected to a power output.
void parseEDA_TEXT(EDA_TEXT *aText)
pin for passive components: must be connected, and can be connected to any pin
int m_unit
The current unit being parsed.
unknown electrical properties: creates always a warning when connected
T
enum T contains all this lexer's tokens.
Definition: lib_pin.h:58
int GetTextHeight() const
Definition: eda_text.h:244
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:112
int m_convert
The current body style being parsed.
#define THROW_IO_ERROR(msg)
#define _(s)
Definition: 3d_actions.cpp:33
usual pin input: must be connected
input or output (like port for a microprocessor)
not connected (must be left open)
output of a regulator: intended to be connected to power input pins

References _, CLOCK, CLOCK_LOW, FALLING_EDGE_CLOCK, EDA_TEXT::GetTextHeight(), INPUT_LOW, INVERTED, INVERTED_CLOCK, LINE, m_convert, m_unit, NONLOGIC, OUTPUT_LOW, parseEDA_TEXT(), parseInt(), parseInternalUnits(), parseXY(), PIN_DOWN, PIN_LEFT, PIN_RIGHT, PIN_UP, PT_BIDI, PT_INPUT, PT_NC, PT_OPENCOLLECTOR, PT_OPENEMITTER, PT_OUTPUT, PT_PASSIVE, PT_POWER_IN, PT_POWER_OUT, PT_TRISTATE, PT_UNSPECIFIED, DRCRULE_T::T_LEFT, DRCRULE_T::T_name, DRCRULE_T::T_RIGHT, and THROW_IO_ERROR.

Referenced by ParseDrawItem().

◆ parsePinNames()

void SCH_SEXPR_PARSER::parsePinNames ( std::unique_ptr< LIB_PART > &  aSymbol)
private

Definition at line 665 of file sch_sexpr_parser.cpp.

666 {
667  wxCHECK_RET( CurTok() == T_pin_names,
668  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
669  wxT( " as a pin_name token." ) );
670 
671  wxString error;
672 
673  T token = NextTok();
674 
675  if( token == T_LEFT )
676  {
677  token = NextTok();
678 
679  if( token != T_offset )
680  Expecting( "offset" );
681 
682  aSymbol->SetPinNameOffset( parseInternalUnits( "pin name offset" ) );
683  NeedRIGHT();
684  token = NextTok(); // Either ) or hide
685  }
686 
687  if( token == T_hide )
688  {
689  aSymbol->SetShowPinNames( false );
690  NeedRIGHT();
691  }
692  else if( token != T_RIGHT )
693  {
694  error.Printf(
695  _( "Invalid symbol names definition in\nfile: \"%s\"\nline: %d\noffset: %d" ),
696  CurSource().c_str(), CurLineNumber(), CurOffset() );
697  THROW_IO_ERROR( error );
698  }
699 }
T
enum T contains all this lexer's tokens.
#define THROW_IO_ERROR(msg)
#define _(s)
Definition: 3d_actions.cpp:33

References _, parseInternalUnits(), DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, and THROW_IO_ERROR.

Referenced by ParseSymbol().

◆ parsePolyLine()

LIB_POLYLINE * SCH_SEXPR_PARSER::parsePolyLine ( )
private

Definition at line 1312 of file sch_sexpr_parser.cpp.

1313 {
1314  wxCHECK_MSG( CurTok() == T_polyline, nullptr,
1315  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a polyline." ) );
1316 
1317  T token;
1318  FILL_PARAMS fill;
1319  std::unique_ptr<LIB_POLYLINE> polyLine( new LIB_POLYLINE( nullptr ) );
1320 
1321  polyLine->SetUnit( m_unit );
1322  polyLine->SetConvert( m_convert );
1323 
1324  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1325  {
1326  if( token != T_LEFT )
1327  Expecting( T_LEFT );
1328 
1329  token = NextTok();
1330 
1331  switch( token )
1332  {
1333  case T_pts:
1334  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1335  {
1336  if( token != T_LEFT )
1337  Expecting( T_LEFT );
1338 
1339  token = NextTok();
1340 
1341  if( token != T_xy )
1342  Expecting( "xy" );
1343 
1344  polyLine->AddPoint( parseXY() );
1345 
1346  NeedRIGHT();
1347  }
1348 
1349  break;
1350 
1351  case T_stroke:
1352  NeedLEFT();
1353  token = NextTok();
1354 
1355  if( token != T_width )
1356  Expecting( "width" );
1357 
1358  polyLine->SetWidth( parseInternalUnits( "stroke width" ) );
1359  NeedRIGHT(); // Closes width token;
1360  NeedRIGHT(); // Closes stroke token;
1361  break;
1362 
1363  case T_fill:
1364  parseFill( fill );
1365  polyLine->SetFillMode( fill.m_FillType );
1366  break;
1367 
1368  default:
1369  Expecting( "pts, stroke, or fill" );
1370  }
1371  }
1372 
1373  return polyLine.release();
1374 }
int m_unit
The current unit being parsed.
T
enum T contains all this lexer's tokens.
Simple container to manage fill parameters.
int m_convert
The current body style being parsed.
void parseFill(FILL_PARAMS &aFill)

References m_convert, FILL_PARAMS::m_FillType, m_unit, parseFill(), parseInternalUnits(), parseXY(), DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

Referenced by ParseDrawItem().

◆ parseProperty()

void SCH_SEXPR_PARSER::parseProperty ( std::unique_ptr< LIB_PART > &  aSymbol)
private

Definition at line 702 of file sch_sexpr_parser.cpp.

703 {
704  wxCHECK_RET( CurTok() == T_property,
705  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
706  wxT( " as a property token." ) );
707  wxCHECK( aSymbol, /* void */ );
708 
709  wxString error;
710  wxString name;
711  wxString value;
712  std::unique_ptr<LIB_FIELD> field( new LIB_FIELD( aSymbol.get(), MANDATORY_FIELDS ) );
713 
714  T token = NextTok();
715 
716  if( !IsSymbol( token ) )
717  {
718  error.Printf( _( "Invalid property name in\nfile: \"%s\"\nline: %d\noffset: %d" ),
719  CurSource().c_str(), CurLineNumber(), CurOffset() );
720  THROW_IO_ERROR( error );
721  }
722 
723  name = FromUTF8();
724 
725  if( name.IsEmpty() )
726  {
727  error.Printf( _( "Empty property name in\nfile: \"%s\"\nline: %d\noffset: %d" ),
728  CurSource().c_str(), CurLineNumber(), CurOffset() );
729  THROW_IO_ERROR( error );
730  }
731 
732  field->SetName( name );
733  token = NextTok();
734 
735  if( !IsSymbol( token ) )
736  {
737  error.Printf( _( "Invalid property value in\nfile: \"%s\"\nline: %d\noffset: %d" ),
738  CurSource().c_str(), CurLineNumber(), CurOffset() );
739  THROW_IO_ERROR( error );
740  }
741 
742  // Empty property values are valid.
743  value = FromUTF8();
744 
745  field->SetText( value );
746 
747  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
748  {
749  if( token != T_LEFT )
750  Expecting( T_LEFT );
751 
752  token = NextTok();
753 
754  switch( token )
755  {
756  case T_id:
757  field->SetId( parseInt( "field ID" ) );
758  NeedRIGHT();
759  break;
760 
761  case T_at:
762  field->SetPosition( parseXY() );
763  field->SetTextAngle( static_cast<int>( parseDouble( "text angle" ) * 10.0 ) );
764  NeedRIGHT();
765  break;
766 
767  case T_effects:
768  parseEDA_TEXT( static_cast<EDA_TEXT*>( field.get() ) );
769  break;
770 
771  default:
772  Expecting( "id, at or effects" );
773  }
774  }
775 
776  LIB_FIELD* existingField;
777 
778  if( field->GetId() < MANDATORY_FIELDS )
779  {
780  existingField = aSymbol->GetField( field->GetId() );
781 
782  *existingField = *field;
783  }
784  else if( name == "ki_keywords" )
785  {
786  // Not a LIB_FIELD object yet.
787  aSymbol->SetKeyWords( value );
788  }
789  else if( name == "ki_description" )
790  {
791  // Not a LIB_FIELD object yet.
792  aSymbol->SetDescription( value );
793  }
794  else if( name == "ki_fp_filters" )
795  {
796  // Not a LIB_FIELD object yet.
797  wxArrayString filters;
798  wxStringTokenizer tokenizer( value );
799 
800  while( tokenizer.HasMoreTokens() )
801  filters.Add( tokenizer.GetNextToken() );
802 
803  aSymbol->SetFootprintFilters( filters );
804  }
805  else if( name == "ki_locked" )
806  {
807  // This is a temporary LIB_FIELD object until interchangeable units are determined on
808  // the fly.
809  aSymbol->LockUnits( true );
810  }
811  else
812  {
813  existingField = aSymbol->GetField( field->GetId() );
814 
815  if( !existingField )
816  {
817  aSymbol->AddDrawItem( field.release() );
818  }
819  else
820  {
821  *existingField = *field;
822  }
823  }
824 }
void parseEDA_TEXT(EDA_TEXT *aText)
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
Field object used in symbol libraries.
Definition: lib_field.h:59
T
enum T contains all this lexer's tokens.
#define THROW_IO_ERROR(msg)
const char * name
Definition: DXF_plotter.cpp:60
#define _(s)
Definition: 3d_actions.cpp:33
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...

References _, MANDATORY_FIELDS, name, parseDouble(), parseEDA_TEXT(), parseInt(), parseXY(), DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, and THROW_IO_ERROR.

Referenced by ParseSymbol().

◆ parseRectangle()

LIB_RECTANGLE * SCH_SEXPR_PARSER::parseRectangle ( )
private

Definition at line 1377 of file sch_sexpr_parser.cpp.

1378 {
1379  wxCHECK_MSG( CurTok() == T_rectangle, nullptr,
1380  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a rectangle token." ) );
1381 
1382  T token;
1383  FILL_PARAMS fill;
1384  std::unique_ptr<LIB_RECTANGLE> rectangle( new LIB_RECTANGLE( nullptr ) );
1385 
1386  rectangle->SetUnit( m_unit );
1387  rectangle->SetConvert( m_convert );
1388 
1389  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1390  {
1391  if( token != T_LEFT )
1392  Expecting( T_LEFT );
1393 
1394  token = NextTok();
1395 
1396  switch( token )
1397  {
1398  case T_start:
1399  rectangle->SetPosition( parseXY() );
1400  NeedRIGHT();
1401  break;
1402 
1403  case T_end:
1404  rectangle->SetEnd( parseXY() );
1405  NeedRIGHT();
1406  break;
1407 
1408  case T_stroke:
1409  NeedLEFT();
1410  token = NextTok();
1411 
1412  if( token != T_width )
1413  Expecting( "width" );
1414 
1415  rectangle->SetWidth( parseInternalUnits( "stroke width" ) );
1416  NeedRIGHT(); // Closes width token;
1417  NeedRIGHT(); // Closes stroke token;
1418  break;
1419 
1420  case T_fill:
1421  parseFill( fill );
1422  rectangle->SetFillMode( fill.m_FillType );
1423  break;
1424 
1425  default:
1426  Expecting( "start, end, stroke, or fill" );
1427  }
1428  }
1429 
1430  return rectangle.release();
1431 }
int m_unit
The current unit being parsed.
T
enum T contains all this lexer's tokens.
Simple container to manage fill parameters.
int m_convert
The current body style being parsed.
void parseFill(FILL_PARAMS &aFill)

References m_convert, FILL_PARAMS::m_FillType, m_unit, parseFill(), parseInternalUnits(), parseXY(), DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

Referenced by ParseDrawItem().

◆ ParseSchematic()

void SCH_SEXPR_PARSER::ParseSchematic ( SCH_SHEET aSheet,
bool  aIsCopyablyOnly = false,
int  aFileVersion = SEXPR_SCHEMATIC_FILE_VERSION 
)

Parse the internal LINE_READER object into aSheet.

When aIsCopyableOnly is true, only schematic objects that are viewable on the canvas for copy and paste purposes are parsed. Other schematic content such as bus definitions or instance data will throw an IO_ERROR exception.

When aIsCopyableOnly is false, full schematic file parsing is performed.

Note
This does not load any sub-sheets or decent complex sheet hierarchies.
Parameters
aSheetThe SCH_SHEET object to store the parsed schematic file.
aIsCopyableOnlyLoad only the schematic objects that can be copied into aSheet if true. Otherwise, load the full schematic file format.
aFileVersionThe schematic file version to parser. Defaults to the schematic file being parsed when aIsCopyableOnly is false.

Definition at line 1871 of file sch_sexpr_parser.cpp.

1872 {
1873  wxCHECK( aSheet != nullptr, /* void */ );
1874 
1875  SCH_SCREEN* screen = aSheet->GetScreen();
1876 
1877  wxCHECK( screen != nullptr, /* void */ );
1878 
1879  if( aIsCopyableOnly )
1880  m_requiredVersion = aFileVersion;
1881 
1882  T token;
1883 
1884  if( !aIsCopyableOnly )
1885  {
1886  NeedLEFT();
1887  NextTok();
1888 
1889  if( CurTok() != T_kicad_sch )
1890  Expecting( "kicad_sch" );
1891 
1892  parseHeader( T_kicad_sch, SEXPR_SCHEMATIC_FILE_VERSION );
1893  }
1894 
1895  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1896  {
1897  if( aIsCopyableOnly && token == T_EOF )
1898  break;
1899 
1900  if( token != T_LEFT )
1901  Expecting( T_LEFT );
1902 
1903  token = NextTok();
1904 
1905  if( !aIsCopyableOnly && token == T_page && m_requiredVersion <= 20200506 )
1906  token = T_paper;
1907 
1908  switch( token )
1909  {
1910  case T_paper:
1911  {
1912  if( aIsCopyableOnly )
1913  Unexpected( T_paper );
1914 
1915  PAGE_INFO pageInfo;
1916  parsePAGE_INFO( pageInfo );
1917  screen->SetPageSettings( pageInfo );
1918  break;
1919  }
1920 
1921  case T_page:
1922  {
1923  if( aIsCopyableOnly )
1924  Unexpected( T_page );
1925 
1926  // Only saved for top-level sniffing in Kicad Manager frame and other external
1927  // tool usage with flat hierarchies
1928  NeedSYMBOLorNUMBER();
1929  NeedSYMBOLorNUMBER();
1930  NeedRIGHT();
1931  break;
1932  }
1933 
1934  case T_title_block:
1935  {
1936  if( aIsCopyableOnly )
1937  Unexpected( T_title_block );
1938 
1939  TITLE_BLOCK tb;
1940  parseTITLE_BLOCK( tb );
1941  screen->SetTitleBlock( tb );
1942  break;
1943  }
1944 
1945  case T_lib_symbols:
1946  {
1947  // Dummy map. No derived symbols are allowed in the library cache.
1948  LIB_PART_MAP symbolLibMap;
1949 
1950  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1951  {
1952  if( token != T_LEFT )
1953  Expecting( T_LEFT );
1954 
1955  token = NextTok();
1956 
1957  switch( token )
1958  {
1959  case T_symbol:
1960  screen->AddLibSymbol( ParseSymbol( symbolLibMap ) );
1961  break;
1962 
1963  default:
1964  Expecting( "symbol" );
1965  }
1966  }
1967 
1968  break;
1969  }
1970 
1971  case T_symbol:
1972  screen->Append( static_cast<SCH_ITEM*>( parseSchematicSymbol() ) );
1973  break;
1974 
1975  case T_image:
1976  screen->Append( static_cast<SCH_ITEM*>( parseImage() ) );
1977  break;
1978 
1979  case T_sheet:
1980  {
1981  SCH_SHEET* sheet = parseSheet();
1982 
1983  // Set the parent to aSheet. This effectively creates a method to find
1984  // the root sheet from any sheet so a pointer to the root sheet does not
1985  // need to be stored globally. Note: this is not the same as a hierarchy.
1986  // Complex hierarchies can have multiple copies of a sheet. This only
1987  // provides a simple tree to find the root sheet.
1988  sheet->SetParent( aSheet );
1989  screen->Append( static_cast<SCH_ITEM*>( sheet ) );
1990  break;
1991  }
1992 
1993  case T_junction:
1994  screen->Append( static_cast<SCH_ITEM*>( parseJunction() ) );
1995  break;
1996 
1997  case T_no_connect:
1998  screen->Append( static_cast<SCH_ITEM*>( parseNoConnect() ) );
1999  break;
2000 
2001  case T_bus_entry:
2002  screen->Append( static_cast<SCH_ITEM*>( parseBusEntry() ) );
2003  break;
2004 
2005  case T_polyline:
2006  case T_bus:
2007  case T_wire:
2008  screen->Append( static_cast<SCH_ITEM*>( parseLine() ) );
2009  break;
2010 
2011  case T_text:
2012  case T_label:
2013  case T_global_label:
2014  case T_hierarchical_label:
2015  screen->Append( static_cast<SCH_ITEM*>( parseSchText() ) );
2016  break;
2017 
2018  case T_symbol_instances:
2019  if( aIsCopyableOnly )
2020  Unexpected( T_symbol_instances );
2021 
2022  parseSchSymbolInstances( screen );
2023  break;
2024 
2025  case T_bus_alias:
2026  if( aIsCopyableOnly )
2027  Unexpected( T_bus_alias );
2028 
2029  parseBusAlias( screen );
2030  break;
2031 
2032  default:
2033  Expecting( "symbol, paper, page, title_block, bitmap, sheet, junction, no_connect, "
2034  "bus_entry, line, bus, text, label, global_label, hierarchical_label, "
2035  "symbol_instances, or bus_alias" );
2036  }
2037  }
2038 
2039  screen->UpdateLocalLibSymbolLinks();
2040 }
LIB_PART * ParseSymbol(LIB_PART_MAP &aSymbolLibMap, int aFileVersion=SEXPR_SYMBOL_LIB_FILE_VERSION)
void parseBusAlias(SCH_SCREEN *aScreen)
std::map< wxString, LIB_PART *, LibPartMapSort > LIB_PART_MAP
Part map used by part library object.
void parseTITLE_BLOCK(TITLE_BLOCK &aTitleBlock)
void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition: sch_screen.h:181
T
enum T contains all this lexer's tokens.
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:282
TITLE_BLOCK holds the information shown in the lower right corner of a plot, printout,...
Definition: title_block.h:40
void parseSchSymbolInstances(SCH_SCREEN *aScreen)
virtual void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:196
SCH_BUS_WIRE_ENTRY * parseBusEntry()
void UpdateLocalLibSymbolLinks()
Initialize the LIB_PART reference for each SCH_COMPONENT found in this schematic with the local proje...
Definition: sch_screen.cpp:684
void parseHeader(TSCHEMATIC_T::T aHeaderType, int aFileVersion)
SCH_JUNCTION * parseJunction()
PAGE_INFO describes the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:54
SCH_NO_CONNECT * parseNoConnect()
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
Definition: sch_screen.h:192
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:216
void parsePAGE_INFO(PAGE_INFO &aPageInfo)
int m_requiredVersion
Set to the symbol library file version required.
void AddLibSymbol(LIB_PART *aLibSymbol)
Add aLibSymbol to the the library symbol map.
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:133
SCH_BITMAP * parseImage()
SCH_TEXT * parseSchText()
#define SEXPR_SCHEMATIC_FILE_VERSION
Symbol library file version.
SCH_COMPONENT * parseSchematicSymbol()
SCH_SHEET * parseSheet()

References SCH_SCREEN::AddLibSymbol(), SCH_SCREEN::Append(), SCH_SHEET::GetScreen(), m_requiredVersion, parseBusAlias(), parseBusEntry(), parseHeader(), parseImage(), parseJunction(), parseLine(), parseNoConnect(), parsePAGE_INFO(), parseSchematicSymbol(), parseSchSymbolInstances(), parseSchText(), parseSheet(), ParseSymbol(), parseTITLE_BLOCK(), SCH_SCREEN::SetPageSettings(), EDA_ITEM::SetParent(), SCH_SCREEN::SetTitleBlock(), SEXPR_SCHEMATIC_FILE_VERSION, DRCRULE_T::T_EOF, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, and SCH_SCREEN::UpdateLocalLibSymbolLinks().

Referenced by SCH_SEXPR_PLUGIN::LoadContent(), and SCH_SEXPR_PLUGIN::loadFile().

◆ parseSchematicSymbol()

SCH_COMPONENT * SCH_SEXPR_PARSER::parseSchematicSymbol ( )
private

Definition at line 2043 of file sch_sexpr_parser.cpp.

2044 {
2045  wxCHECK_MSG( CurTok() == T_symbol, nullptr,
2046  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a symbol." ) );
2047 
2048  T token;
2049  wxString tmp;
2050  wxString error;
2051  wxString libName;
2052  SCH_FIELD* field;
2053  std::unique_ptr<SCH_COMPONENT> symbol( new SCH_COMPONENT() );
2054  TRANSFORM transform;
2055 
2057 
2058  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2059  {
2060  if( token != T_LEFT )
2061  Expecting( T_LEFT );
2062 
2063  token = NextTok();
2064 
2065  switch( token )
2066  {
2067  case T_lib_name:
2068  {
2069  LIB_ID libId;
2070 
2071  token = NextTok();
2072 
2073  if( !IsSymbol( token ) )
2074  {
2075  error.Printf( _( "Invalid symbol library name in\nfile: \"%s\"\n"
2076  "line: %d\noffset: %d" ),
2077  CurSource().c_str(), CurLineNumber(), CurOffset() );
2078  THROW_IO_ERROR( error );
2079  }
2080 
2081  libName = FromUTF8();
2082  NeedRIGHT();
2083  break;
2084  }
2085 
2086  case T_lib_id:
2087  {
2088  token = NextTok();
2089 
2090  if( !IsSymbol( token ) && token != T_NUMBER )
2091  Expecting( "symbol|number" );
2092 
2093  LIB_ID libId;
2094 
2095  if( libId.Parse( FromUTF8(), LIB_ID::ID_SCH ) >= 0 )
2096  {
2097  error.Printf( _( "Invalid symbol library ID in\nfile: \"%s\"\nline: %d\n"
2098  "offset: %d" ),
2099  GetChars( CurSource() ), CurLineNumber(), CurOffset() );
2100  THROW_IO_ERROR( error );
2101  }
2102 
2103  symbol->SetLibId( libId );
2104  NeedRIGHT();
2105  break;
2106  }
2107 
2108  case T_at:
2109  symbol->SetPosition( parseXY() );
2110 
2111  switch( static_cast<int>( parseDouble( "symbol orientation" ) ) )
2112  {
2113  case 0: transform = TRANSFORM(); break;
2114  case 90: transform = TRANSFORM( 0, -1, -1, 0 ); break;
2115  case 180: transform = TRANSFORM( -1, 0, 0, 1 ); break;
2116  case 270: transform = TRANSFORM( 0, 1, 1, 0 ); break;
2117  default: Expecting( "0, 90, 180, or 270" );
2118  }
2119 
2120  symbol->SetTransform( transform );
2121  NeedRIGHT();
2122  break;
2123 
2124  case T_mirror:
2125  token = NextTok();
2126 
2127  if( token == T_x )
2128  symbol->SetOrientation( CMP_MIRROR_X );
2129  else if( token == T_y )
2130  symbol->SetOrientation( CMP_MIRROR_Y );
2131  else
2132  Expecting( "x or y" );
2133 
2134  NeedRIGHT();
2135  break;
2136 
2137  case T_unit:
2138  symbol->SetUnit( parseInt( "symbol unit" ) );
2139  NeedRIGHT();
2140  break;
2141 
2142  case T_convert:
2143  symbol->SetConvert( parseInt( "symbol convert" ) );
2144  NeedRIGHT();
2145  break;
2146 
2147  case T_in_bom:
2148  symbol->SetIncludeInBom( parseBool() );
2149  NeedRIGHT();
2150  break;
2151 
2152  case T_on_board:
2153  symbol->SetIncludeOnBoard( parseBool() );
2154  NeedRIGHT();
2155  break;
2156 
2157  case T_uuid:
2158  NeedSYMBOL();
2159  const_cast<KIID&>( symbol->m_Uuid ) = KIID( FromUTF8() );
2160  NeedRIGHT();
2161  break;
2162 
2163  case T_property:
2164  {
2165  // The field parent symbol must be set and it's orientation must be set before
2166  // the field positions are set.
2167  field = parseSchField( symbol.get() );
2168 
2169  // Set the default symbol reference prefix.
2170  if( field->GetId() == REFERENCE )
2171  {
2172  wxString refDesignator = field->GetText();
2173 
2174  refDesignator.Replace( "~", " " );
2175 
2176  wxString prefix = refDesignator;
2177 
2178  while( prefix.Length() )
2179  {
2180  if( ( prefix.Last() < '0' || prefix.Last() > '9') && prefix.Last() != '?' )
2181  break;
2182 
2183  prefix.RemoveLast();
2184  }
2185 
2186  // Avoid a prefix containing trailing/leading spaces
2187  prefix.Trim( true );
2188  prefix.Trim( false );
2189 
2190  if( prefix.IsEmpty() )
2191  symbol->SetPrefix( wxString( "U" ) );
2192  else
2193  symbol->SetPrefix( prefix );
2194  }
2195 
2196  if( symbol->GetField( field->GetId() ) )
2197  *symbol->GetField( field->GetId() ) = *field;
2198  else
2199  symbol->AddField( *field );
2200 
2201  delete field;
2202  break;
2203  }
2204 
2205  default:
2206  Expecting( "lib_id, lib_name, at, mirror, uuid, property, or instances" );
2207  }
2208  }
2209 
2210  if( !libName.IsEmpty() && ( symbol->GetLibId().Format().wx_str() != libName ) )
2211  symbol->SetSchSymbolLibraryName( libName );
2212 
2213  // Ensure edit/status flags are cleared after these initializations:
2214  symbol->ClearFlags();
2215 
2216  return symbol.release();
2217 }
int m_fieldId
The current field ID.
SCH_FIELD instances are attached to a component and provide a place for the component's value,...
Definition: sch_field.h:52
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
int GetId() const
Definition: sch_field.h:114
T
enum T contains all this lexer's tokens.
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
Field Reference of part, i.e. "IC21".
Definition: common.h:68
for transforming drawing coordinates for a wxDC device context.
Definition: transform.h:45
#define THROW_IO_ERROR(msg)
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:153
#define _(s)
Definition: 3d_actions.cpp:33
SCH_FIELD * parseSchField(SCH_ITEM *aParent)
Schematic symbol object.
Definition: sch_component.h:88
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...
int Parse(const UTF8 &aId, LIB_ID_TYPE aType, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition: lib_id.cpp:122
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:126

References _, CMP_MIRROR_X, CMP_MIRROR_Y, GetChars(), SCH_FIELD::GetId(), EDA_TEXT::GetText(), LIB_ID::ID_SCH, m_fieldId, MANDATORY_FIELDS, LIB_ID::Parse(), parseBool(), parseDouble(), parseInt(), parseSchField(), parseXY(), REFERENCE, DRCRULE_T::T_LEFT, DRCRULE_T::T_NUMBER, DRCRULE_T::T_RIGHT, and THROW_IO_ERROR.

Referenced by ParseSchematic().

◆ parseSchField()

SCH_FIELD * SCH_SEXPR_PARSER::parseSchField ( SCH_ITEM aParent)
private

Definition at line 1644 of file sch_sexpr_parser.cpp.

1645 {
1646  wxCHECK_MSG( CurTok() == T_property, nullptr,
1647  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
1648  wxT( " as a property token." ) );
1649 
1650  wxString error;
1651  wxString name;
1652  wxString value;
1653 
1654  T token = NextTok();
1655 
1656  if( !IsSymbol( token ) )
1657  {
1658  error.Printf( _( "Invalid property name in\nfile: \"%s\"\nline: %d\noffset: %d" ),
1659  CurSource().c_str(), CurLineNumber(), CurOffset() );
1660  THROW_IO_ERROR( error );
1661  }
1662 
1663  name = FromUTF8();
1664 
1665  if( name.IsEmpty() )
1666  {
1667  error.Printf( _( "Empty property name in\nfile: \"%s\"\nline: %d\noffset: %d" ),
1668  CurSource().c_str(), CurLineNumber(), CurOffset() );
1669  THROW_IO_ERROR( error );
1670  }
1671 
1672  token = NextTok();
1673 
1674  if( !IsSymbol( token ) )
1675  {
1676  error.Printf( _( "Invalid property value in\nfile: \"%s\"\nline: %d\noffset: %d" ),
1677  CurSource().c_str(), CurLineNumber(), CurOffset() );
1678  THROW_IO_ERROR( error );
1679  }
1680 
1681  // Empty property values are valid.
1682  value = FromUTF8();
1683 
1684  std::unique_ptr<SCH_FIELD> field( new SCH_FIELD( wxDefaultPosition, -1, aParent, name ) );
1685 
1686  field->SetText( value );
1687  field->SetVisible( true );
1688 
1689  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1690  {
1691  if( token != T_LEFT )
1692  Expecting( T_LEFT );
1693 
1694  token = NextTok();
1695 
1696  switch( token )
1697  {
1698  case T_id:
1699  field->SetId( parseInt( "field ID" ) );
1700  NeedRIGHT();
1701  break;
1702 
1703  case T_at:
1704  field->SetPosition( parseXY() );
1705  field->SetTextAngle( static_cast<int>( parseDouble( "text angle" ) * 10.0 ) );
1706  NeedRIGHT();
1707  break;
1708 
1709  case T_effects:
1710  parseEDA_TEXT( static_cast<EDA_TEXT*>( field.get() ) );
1711  break;
1712 
1713  default:
1714  Expecting( "at or effects" );
1715  }
1716  }
1717 
1718  return field.release();
1719 }
SCH_FIELD instances are attached to a component and provide a place for the component's value,...
Definition: sch_field.h:52
void parseEDA_TEXT(EDA_TEXT *aText)
T
enum T contains all this lexer's tokens.
#define THROW_IO_ERROR(msg)
const char * name
Definition: DXF_plotter.cpp:60
#define _(s)
Definition: 3d_actions.cpp:33
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...

References _, name, parseDouble(), parseEDA_TEXT(), parseInt(), parseXY(), DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, and THROW_IO_ERROR.

Referenced by parseSchematicSymbol(), and parseSheet().

◆ parseSchSheetPin()

SCH_SHEET_PIN * SCH_SEXPR_PARSER::parseSchSheetPin ( SCH_SHEET aSheet)
private

Definition at line 1722 of file sch_sexpr_parser.cpp.

1723 {
1724  wxCHECK_MSG( aSheet != nullptr, nullptr, "" );
1725  wxCHECK_MSG( CurTok() == T_pin, nullptr,
1726  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
1727  wxT( " as a sheet pin token." ) );
1728 
1729  wxString error;
1730  wxString name;
1731  wxString shape;
1732 
1733  T token = NextTok();
1734 
1735  if( !IsSymbol( token ) )
1736  {
1737  error.Printf( _( "Invalid sheet pin name in\nfile: \"%s\"\nline: %d\noffset: %d" ),
1738  CurSource().c_str(), CurLineNumber(), CurOffset() );
1739  THROW_IO_ERROR( error );
1740  }
1741 
1742  name = FromUTF8();
1743 
1744  if( name.IsEmpty() )
1745  {
1746  error.Printf( _( "Empty sheet pin name in\nfile: \"%s\"\nline: %d\noffset: %d" ),
1747  CurSource().c_str(), CurLineNumber(), CurOffset() );
1748  THROW_IO_ERROR( error );
1749  }
1750 
1751  std::unique_ptr<SCH_SHEET_PIN> sheetPin( new SCH_SHEET_PIN( aSheet, wxPoint( 0, 0 ), name ) );
1752 
1753  token = NextTok();
1754 
1755  switch( token )
1756  {
1757  case T_input: sheetPin->SetShape( PINSHEETLABEL_SHAPE::PS_INPUT ); break;
1758  case T_output: sheetPin->SetShape( PINSHEETLABEL_SHAPE::PS_OUTPUT ); break;
1759  case T_bidirectional: sheetPin->SetShape( PINSHEETLABEL_SHAPE::PS_BIDI ); break;
1760  case T_tri_state: sheetPin->SetShape( PINSHEETLABEL_SHAPE::PS_TRISTATE ); break;
1761  case T_passive: sheetPin->SetShape( PINSHEETLABEL_SHAPE::PS_UNSPECIFIED ); break;
1762  default:
1763  Expecting( "input, output, bidirectional, tri_state, or passive" );
1764  }
1765 
1766  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1767  {
1768  if( token != T_LEFT )
1769  Expecting( T_LEFT );
1770 
1771  token = NextTok();
1772 
1773  switch( token )
1774  {
1775  case T_at:
1776  {
1777  sheetPin->SetPosition( parseXY() );
1778 
1779  double angle = parseDouble( "sheet pin angle (side)" );
1780 
1781  if( angle == 0.0 )
1782  sheetPin->SetEdge( SHEET_RIGHT_SIDE );
1783  else if( angle == 90.0 )
1784  sheetPin->SetEdge( SHEET_TOP_SIDE );
1785  else if( angle == 180.0 )
1786  sheetPin->SetEdge( SHEET_LEFT_SIDE );
1787  else if( angle == 270.0 )
1788  sheetPin->SetEdge( SHEET_BOTTOM_SIDE );
1789  else
1790  Expecting( "0, 90, 180, or 270" );
1791 
1792  NeedRIGHT();
1793  break;
1794  }
1795 
1796  case T_effects:
1797  parseEDA_TEXT( static_cast<EDA_TEXT*>( sheetPin.get() ) );
1798  break;
1799 
1800  default:
1801  Expecting( "at or effects" );
1802  }
1803  }
1804 
1805  return sheetPin.release();
1806 }
void parseEDA_TEXT(EDA_TEXT *aText)
T
enum T contains all this lexer's tokens.
#define THROW_IO_ERROR(msg)
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet.h:84
const char * name
Definition: DXF_plotter.cpp:60
#define _(s)
Definition: 3d_actions.cpp:33
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...

References _, PNS::angle(), name, parseDouble(), parseEDA_TEXT(), parseXY(), PS_BIDI, PS_INPUT, PS_OUTPUT, PS_TRISTATE, PS_UNSPECIFIED, SHEET_BOTTOM_SIDE, SHEET_LEFT_SIDE, SHEET_RIGHT_SIDE, SHEET_TOP_SIDE, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, and THROW_IO_ERROR.

Referenced by parseSheet().

◆ parseSchSymbolInstances()

void SCH_SEXPR_PARSER::parseSchSymbolInstances ( SCH_SCREEN aScreen)
private

Definition at line 1809 of file sch_sexpr_parser.cpp.

1810 {
1811  wxCHECK_RET( CurTok() == T_symbol_instances,
1812  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
1813  wxT( " as a instances token." ) );
1814  wxCHECK( aScreen, /* void */ );
1815 
1816  T token;
1817 
1818  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1819  {
1820  if( token != T_LEFT )
1821  Expecting( T_LEFT );
1822 
1823  token = NextTok();
1824 
1825  switch( token )
1826  {
1827  case T_path:
1828  {
1829  NeedSYMBOL();
1830 
1832 
1833  instance.m_Path = KIID_PATH( FromUTF8() );
1834 
1835  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1836  {
1837  if( token != T_LEFT )
1838  Expecting( T_LEFT );
1839 
1840  token = NextTok();
1841 
1842  switch( token )
1843  {
1844  case T_reference:
1845  NeedSYMBOL();
1846  instance.m_Reference = FromUTF8();
1847  NeedRIGHT();
1848  break;
1849 
1850  case T_unit:
1851  instance.m_Unit = parseInt( "symbol unit" );
1852  NeedRIGHT();
1853  break;
1854 
1855  default:
1856  Expecting( "path or unit" );
1857  }
1858  }
1859 
1860  aScreen->m_symbolInstances.emplace_back( instance );
1861  break;
1862  }
1863 
1864  default:
1865  Expecting( "path" );
1866  }
1867  }
1868 }
T
enum T contains all this lexer's tokens.
A simple container for schematic symbol instance infromation.
std::vector< COMPONENT_INSTANCE_REFERENCE > m_symbolInstances
The list of symbol instances loaded from the schematic file.
Definition: sch_screen.h:139

References COMPONENT_INSTANCE_REFERENCE::m_Path, COMPONENT_INSTANCE_REFERENCE::m_Reference, SCH_SCREEN::m_symbolInstances, COMPONENT_INSTANCE_REFERENCE::m_Unit, parseInt(), DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

Referenced by ParseSchematic().

◆ parseSchText()

SCH_TEXT * SCH_SEXPR_PARSER::parseSchText ( )
private

Definition at line 2563 of file sch_sexpr_parser.cpp.

2564 {
2565  T token;
2566  std::unique_ptr<SCH_TEXT> text;
2567 
2568  switch( CurTok() )
2569  {
2570  case T_text: text.reset( new SCH_TEXT ); break;
2571  case T_label: text.reset( new SCH_LABEL ); break;
2572  case T_global_label: text.reset( new SCH_GLOBALLABEL ); break;
2573  case T_hierarchical_label: text.reset( new SCH_HIERLABEL ); break;
2574  default:
2575  wxCHECK_MSG( false, nullptr,
2576  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as text." ) );
2577  }
2578 
2579  NeedSYMBOL();
2580 
2581  text->SetText( FromUTF8() );
2582 
2583  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2584  {
2585  if( token != T_LEFT )
2586  Expecting( T_LEFT );
2587 
2588  token = NextTok();
2589 
2590  switch( token )
2591  {
2592  case T_at:
2593  {
2594  text->SetPosition( parseXY() );
2595 
2596  switch( static_cast<int>( parseDouble( "text angle" ) ) )
2597  {
2598  case 0: text->SetLabelSpinStyle( LABEL_SPIN_STYLE::RIGHT ); break;
2599  case 90: text->SetLabelSpinStyle( LABEL_SPIN_STYLE::UP ); break;
2600  case 180: text->SetLabelSpinStyle( LABEL_SPIN_STYLE::LEFT ); break;
2601  case 270: text->SetLabelSpinStyle( LABEL_SPIN_STYLE::BOTTOM ); break;
2602  default:
2603  wxFAIL;
2604  text->SetLabelSpinStyle( LABEL_SPIN_STYLE::RIGHT );
2605  break;
2606  }
2607 
2608  NeedRIGHT();
2609  break;
2610  }
2611 
2612  case T_shape:
2613  {
2614  if( text->Type() == SCH_TEXT_T || text->Type() == SCH_LABEL_T )
2615  Unexpected( T_shape );
2616 
2617  token = NextTok();
2618 
2619  switch( token )
2620  {
2621  case T_input: text->SetShape( PINSHEETLABEL_SHAPE::PS_INPUT ); break;
2622  case T_output: text->SetShape( PINSHEETLABEL_SHAPE::PS_OUTPUT ); break;
2623  case T_bidirectional: text->SetShape( PINSHEETLABEL_SHAPE::PS_BIDI ); break;
2624  case T_tri_state: text->SetShape( PINSHEETLABEL_SHAPE::PS_TRISTATE ); break;
2625  case T_passive: text->SetShape( PINSHEETLABEL_SHAPE::PS_UNSPECIFIED ); break;
2626  default:
2627  Expecting( "input, output, bidirectional, tri_state, or passive" );
2628  }
2629 
2630  NeedRIGHT();
2631  break;
2632  }
2633 
2634  case T_effects:
2635  parseEDA_TEXT( static_cast<EDA_TEXT*>( text.get() ) );
2636  break;
2637 
2638  default:
2639  Expecting( "at, shape, or effects" );
2640  }
2641  }
2642 
2643  return text.release();
2644 }
void parseEDA_TEXT(EDA_TEXT *aText)
T
enum T contains all this lexer's tokens.
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...

References LABEL_SPIN_STYLE::BOTTOM, LABEL_SPIN_STYLE::LEFT, parseDouble(), parseEDA_TEXT(), parseXY(), PS_BIDI, PS_INPUT, PS_OUTPUT, PS_TRISTATE, PS_UNSPECIFIED, LABEL_SPIN_STYLE::RIGHT, SCH_LABEL_T, SCH_TEXT_T, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, and LABEL_SPIN_STYLE::UP.

Referenced by ParseSchematic().

◆ parseSheet()

SCH_SHEET * SCH_SEXPR_PARSER::parseSheet ( )
private

Definition at line 2289 of file sch_sexpr_parser.cpp.

2290 {
2291  wxCHECK_MSG( CurTok() == T_sheet, nullptr,
2292  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a sheet." ) );
2293 
2294  T token;
2295  STROKE_PARAMS stroke;
2296  FILL_PARAMS fill;
2297  SCH_FIELD* field;
2298  std::vector<SCH_FIELD> fields;
2299  std::unique_ptr<SCH_SHEET> sheet( new SCH_SHEET() );
2300 
2301  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2302  {
2303  if( token != T_LEFT )
2304  Expecting( T_LEFT );
2305 
2306  token = NextTok();
2307 
2308  switch( token )
2309  {
2310  case T_at:
2311  sheet->SetPosition( parseXY() );
2312  NeedRIGHT();
2313  break;
2314 
2315  case T_size:
2316  {
2317  wxSize size;
2318  size.SetWidth( parseInternalUnits( "sheet width" ) );
2319  size.SetHeight( parseInternalUnits( "sheet height" ) );
2320  sheet->SetSize( size );
2321  NeedRIGHT();
2322  break;
2323  }
2324 
2325  case T_stroke:
2326  parseStroke( stroke );
2327  sheet->SetBorderWidth( stroke.GetWidth() );
2328  sheet->SetBorderColor( stroke.GetColor() );
2329  break;
2330 
2331  case T_fill:
2332  parseFill( fill );
2333  sheet->SetBackgroundColor( fill.m_Color );
2334  break;
2335 
2336  case T_uuid:
2337  NeedSYMBOL();
2338  const_cast<KIID&>( sheet->m_Uuid ) = KIID( FromUTF8() );
2339  NeedRIGHT();
2340  break;
2341 
2342  case T_property:
2343  field = parseSchField( sheet.get() );
2344 
2345  if( m_requiredVersion <= 20200310 )
2346  {
2347  // Earlier versions had the wrong ids (and names) saved for sheet fields.
2348  // Fortunately they only saved the sheetname and sheetfilepath (and always
2349  // in that order), so we can hack in a recovery.
2350  if( fields.empty() )
2351  field->SetId( SHEETNAME );
2352  else
2353  field->SetId( SHEETFILENAME );
2354  }
2355 
2356  fields.emplace_back( *field );
2357  delete field;
2358  break;
2359 
2360  case T_pin:
2361  sheet->AddPin( parseSchSheetPin( sheet.get() ) );
2362  break;
2363 
2364  default:
2365  Expecting( "at, size, stroke, background, uuid, property, or pin" );
2366  }
2367  }
2368 
2369  sheet->SetFields( fields );
2370 
2371  return sheet.release();
2372 }
SCH_FIELD instances are attached to a component and provide a place for the component's value,...
Definition: sch_field.h:52
SCH_SHEET_PIN * parseSchSheetPin(SCH_SHEET *aSheet)
T
enum T contains all this lexer's tokens.
Definition: common.h:68
Simple container to manage fill parameters.
int GetWidth() const
Definition: sch_item.h:169
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:216
COLOR4D GetColor() const
Definition: sch_item.h:175
int m_requiredVersion
Set to the symbol library file version required.
Simple container to manage line stroke parameters.
Definition: sch_item.h:153
SCH_FIELD * parseSchField(SCH_ITEM *aParent)
void parseFill(FILL_PARAMS &aFill)
void SetId(int aId)
Definition: sch_field.cpp:76
void parseStroke(STROKE_PARAMS &aStroke)
Parse stroke definition aStroke.

References STROKE_PARAMS::GetColor(), STROKE_PARAMS::GetWidth(), FILL_PARAMS::m_Color, m_requiredVersion, parseFill(), parseInternalUnits(), parseSchField(), parseSchSheetPin(), parseStroke(), parseXY(), SCH_FIELD::SetId(), SHEETFILENAME, SHEETNAME, DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

Referenced by ParseSchematic().

◆ parseStroke()

void SCH_SEXPR_PARSER::parseStroke ( STROKE_PARAMS aStroke)
private

Parse stroke definition aStroke.

Parameters
aStrokeDefA reference to the STROKE_PARAMS structure to write to.

Definition at line 416 of file sch_sexpr_parser.cpp.

417 {
418  wxCHECK_RET( CurTok() == T_stroke,
419  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a stroke." ) );
420 
421  aStroke.SetWidth( Mils2iu( DEFAULT_LINE_THICKNESS ) );
422  aStroke.SetType( PLOT_DASH_TYPE::DEFAULT );
423  aStroke.SetColor( COLOR4D::UNSPECIFIED );
424 
425  T token;
426 
427  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
428  {
429  if( token != T_LEFT )
430  Expecting( T_LEFT );
431 
432  token = NextTok();
433 
434  switch( token )
435  {
436  case T_width:
437  aStroke.SetWidth( parseInternalUnits( "stroke width" ) );
438  NeedRIGHT();
439  break;
440 
441  case T_type:
442  {
443  token = NextTok();
444 
445  switch( token )
446  {
447  case T_dash: aStroke.SetType( PLOT_DASH_TYPE::DASH ); break;
448  case T_dot: aStroke.SetType( PLOT_DASH_TYPE::DOT ); break;
449  case T_dash_dot: aStroke.SetType( PLOT_DASH_TYPE::DASHDOT ); break;
450  case T_solid: aStroke.SetType( PLOT_DASH_TYPE::SOLID ); break;
451  default:
452  Expecting( "solid, dash, dash_dot, or dot" );
453  }
454 
455  NeedRIGHT();
456  break;
457  }
458 
459  case T_color:
460  {
461  COLOR4D color;
462 
463  color.r = parseInt( "red" ) / 255.0;
464  color.g = parseInt( "green" ) / 255.0;
465  color.b = parseInt( "blue" ) / 255.0;
466  color.a = Clamp( parseDouble( "alpha" ), 0.0, 1.0 );
467 
468  aStroke.SetColor( color );
469  NeedRIGHT();
470  break;
471  }
472 
473  default:
474  Expecting( "width, type, or color" );
475  }
476 
477  }
478 }
void SetWidth(int aWidth)
Definition: sch_item.h:170
int color
Definition: DXF_plotter.cpp:61
void SetType(PLOT_DASH_TYPE aType)
Definition: sch_item.h:173
T
enum T contains all this lexer's tokens.
#define DEFAULT_LINE_THICKNESS
The default wire width in mils. (can be changed in preference menu)
const T & Clamp(const T &lower, const T &value, const T &upper)
Function Clamp limits value within the range lower <= value <= upper.
Definition: util.h:46
void SetColor(const COLOR4D &aColor)
Definition: sch_item.h:176
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:99

References Clamp(), color, DASH, DASHDOT, DEFAULT, DEFAULT_LINE_THICKNESS, DOT, parseDouble(), parseInt(), parseInternalUnits(), STROKE_PARAMS::SetColor(), STROKE_PARAMS::SetType(), STROKE_PARAMS::SetWidth(), SOLID, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, and DRCRULE_T::T_type.

Referenced by parseBusEntry(), parseLine(), and parseSheet().

◆ ParseSymbol()

LIB_PART * SCH_SEXPR_PARSER::ParseSymbol ( LIB_PART_MAP aSymbolLibMap,
int  aFileVersion = SEXPR_SYMBOL_LIB_FILE_VERSION 
)

Definition at line 122 of file sch_sexpr_parser.cpp.

123 {
124  wxCHECK_MSG( CurTok() == T_symbol, nullptr,
125  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a symbol." ) );
126 
127  T token;
128  long tmp;
129  wxString name;
130  wxString error;
131  LIB_ITEM* item;
132  std::unique_ptr<LIB_PART> symbol( new LIB_PART( wxEmptyString ) );
133 
134  m_requiredVersion = aFileVersion;
135  symbol->SetUnitCount( 1 );
136 
138 
139  token = NextTok();
140 
141  if( !IsSymbol( token ) )
142  {
143  error.Printf( _( "Invalid symbol name in\nfile: \"%s\"\nline: %d\noffset: %d" ),
144  CurSource().c_str(), CurLineNumber(), CurOffset() );
145  THROW_IO_ERROR( error );
146  }
147 
148  name = FromUTF8();
149 
150  LIB_ID id;
151 
152  if( id.Parse( name, LIB_ID::ID_SCH ) >= 0 )
153  {
154  error.Printf( _( "Invalid library identifier in\nfile: \"%s\"\nline: %d\noffset: %d" ),
155  CurSource().c_str(), CurLineNumber(), CurOffset() );
156  THROW_IO_ERROR( error );
157  }
158 
159  m_symbolName = id.GetLibItemName().wx_str();
160  symbol->SetName( m_symbolName );
161  symbol->SetLibId( id );
162 
163  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
164  {
165  if( token != T_LEFT )
166  Expecting( T_LEFT );
167 
168  token = NextTok();
169 
170  switch( token )
171  {
172  case T_power:
173  symbol->SetPower();
174  NeedRIGHT();
175  break;
176 
177  case T_pin_names:
178  parsePinNames( symbol );
179  break;
180 
181  case T_pin_numbers:
182  token = NextTok();
183 
184  if( token != T_hide )
185  Expecting( "hide" );
186 
187  symbol->SetShowPinNumbers( false );
188  NeedRIGHT();
189  break;
190 
191  case T_property:
192  parseProperty( symbol );
193  break;
194 
195  case T_extends:
196  {
197  token = NextTok();
198 
199  if( !IsSymbol( token ) )
200  {
201  error.Printf(
202  _( "Invalid symbol extends name in\nfile: \"%s\"\nline: %d\noffset: %d" ),
203  CurSource().c_str(), CurLineNumber(), CurOffset() );
204  THROW_IO_ERROR( error );
205  }
206 
207  name = FromUTF8();
208  auto it = aSymbolLibMap.find( name );
209 
210  if( it == aSymbolLibMap.end() )
211  {
212  error.Printf(
213  _( "No parent for extended symbol %s in\nfile: \"%s\"\nline: %d\noffset: %d" ),
214  name.c_str(), CurSource().c_str(), CurLineNumber(), CurOffset() );
215  THROW_IO_ERROR( error );
216  }
217 
218  symbol->SetParent( it->second );
219  NeedRIGHT();
220  break;
221  }
222 
223  case T_symbol:
224  {
225  token = NextTok();
226 
227  if( !IsSymbol( token ) )
228  {
229  error.Printf(
230  _( "Invalid symbol unit name in\nfile: \"%s\"\nline: %d\noffset: %d" ),
231  CurSource().c_str(), CurLineNumber(), CurOffset() );
232  THROW_IO_ERROR( error );
233  }
234 
235  name = FromUTF8();
236 
237  if( !name.StartsWith( m_symbolName ) )
238  {
239  error.Printf(
240  _( "Invalid symbol unit name prefix %s in\nfile: \"%s\"\n"
241  "line: %d\noffset: %d" ),
242  name.c_str(), CurSource().c_str(), CurLineNumber(), CurOffset() );
243  THROW_IO_ERROR( error );
244  }
245 
246  name = name.Right( name.Length() - m_symbolName.Length() - 1 );
247 
248  wxStringTokenizer tokenizer( name, "_" );
249 
250  if( tokenizer.CountTokens() != 2 )
251  {
252  error.Printf(
253  _( "Invalid symbol unit name suffix %s in\nfile: \"%s\"\n"
254  "line: %d\noffset: %d" ),
255  name.c_str(), CurSource().c_str(), CurLineNumber(), CurOffset() );
256  THROW_IO_ERROR( error );
257  }
258 
259  if( !tokenizer.GetNextToken().ToLong( &tmp ) )
260  {
261  error.Printf(
262  _( "Invalid symbol unit number %s in\nfile: \"%s\"\nline: %d\noffset: %d" ),
263  name.c_str(), CurSource().c_str(), CurLineNumber(), CurOffset() );
264  THROW_IO_ERROR( error );
265  }
266 
267  m_unit = static_cast<int>( tmp );
268 
269  if( !tokenizer.GetNextToken().ToLong( &tmp ) )
270  {
271  error.Printf(
272  _( "Invalid symbol convert number %s in\nfile: \"%s\"\nline: %d\noffset: %d" ),
273  name.c_str(), CurSource().c_str(), CurLineNumber(), CurOffset() );
274  THROW_IO_ERROR( error );
275  }
276 
277  m_convert = static_cast<int>( tmp );
278 
279  if( m_convert > 1 )
280  symbol->SetConversion( true, false );
281 
282  if( m_unit > symbol->GetUnitCount() )
283  symbol->SetUnitCount( m_unit, false );
284 
285  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
286  {
287  if( token != T_LEFT )
288  Expecting( T_LEFT );
289 
290  token = NextTok();
291 
292  switch( token )
293  {
294  case T_arc:
295  case T_bezier:
296  case T_circle:
297  case T_pin:
298  case T_polyline:
299  case T_rectangle:
300  case T_text:
301  item = ParseDrawItem();
302 
303  wxCHECK_MSG( item, nullptr, "Invalid draw item pointer." );
304 
305  item->SetParent( symbol.get() );
306  symbol->AddDrawItem( item );
307  break;
308 
309  default:
310  Expecting( "arc, bezier, circle, pin, polyline, rectangle, or text" );
311  };
312  }
313 
314  m_unit = 1;
315  m_convert = 1;
316  break;
317  }
318 
319  case T_arc:
320  case T_bezier:
321  case T_circle:
322  case T_pin:
323  case T_polyline:
324  case T_rectangle:
325  case T_text:
326  item = ParseDrawItem();
327 
328  wxCHECK_MSG( item, nullptr, "Invalid draw item pointer." );
329 
330  item->SetParent( symbol.get() );
331  symbol->AddDrawItem( item );
332  break;
333 
334  default:
335  Expecting( "pin_names, pin_numbers, arc, bezier, circle, pin, polyline, "
336  "rectangle, or text" );
337  }
338  }
339 
340  m_symbolName.clear();
341 
342  return symbol.release();
343 }
int m_fieldId
The current field ID.
void parseProperty(std::unique_ptr< LIB_PART > &aSymbol)
void Parse(void *yyp, int yymajor, ParseTOKENTYPE yyminor ParseARG_PDECL)
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
int m_unit
The current unit being parsed.
T
enum T contains all this lexer's tokens.
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
virtual void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:196
The base class for drawable items used by schematic library components.
Definition: lib_item.h:61
wxString m_symbolName
The current symbol name.
int m_convert
The current body style being parsed.
Define a library symbol object.
#define THROW_IO_ERROR(msg)
LIB_ITEM * ParseDrawItem()
int m_requiredVersion
Set to the symbol library file version required.
const char * name
Definition: DXF_plotter.cpp:60
#define _(s)
Definition: 3d_actions.cpp:33
void parsePinNames(std::unique_ptr< LIB_PART > &aSymbol)

References _, LIB_ID::ID_SCH, m_convert, m_fieldId, m_requiredVersion, m_symbolName, m_unit, MANDATORY_FIELDS, name, numEval::Parse(), ParseDrawItem(), parsePinNames(), parseProperty(), EDA_ITEM::SetParent(), DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, and THROW_IO_ERROR.

Referenced by ParseLib(), SCH_SEXPR_PLUGIN::ParsePart(), and ParseSchematic().

◆ parseText()

LIB_TEXT * SCH_SEXPR_PARSER::parseText ( )
private

Definition at line 1434 of file sch_sexpr_parser.cpp.

1435 {
1436  wxCHECK_MSG( CurTok() == T_text, nullptr,
1437  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a text token." ) );
1438 
1439  T token;
1440  wxString tmp;
1441  wxString error;
1442  std::unique_ptr<LIB_TEXT> text( new LIB_TEXT( nullptr ) );
1443 
1444  text->SetUnit( m_unit );
1445  text->SetConvert( m_convert );
1446  token = NextTok();
1447 
1448  if( !IsSymbol( token ) )
1449  {
1450  error.Printf( _( "Invalid text string in\nfile: \"%s\"\nline: %d\noffset: %d" ),
1451  CurSource().c_str(), CurLineNumber(), CurOffset() );
1452  THROW_IO_ERROR( error );
1453  }
1454 
1455  text->SetText( FromUTF8() );
1456 
1457  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1458  {
1459  if( token != T_LEFT )
1460  Expecting( T_LEFT );
1461 
1462  token = NextTok();
1463 
1464  switch( token )
1465  {
1466  case T_at:
1467  text->SetPosition( parseXY() );
1468  text->SetTextAngle( parseDouble( "text angle" ) );
1469  NeedRIGHT();
1470  break;
1471 
1472  case T_effects:
1473  parseEDA_TEXT( static_cast<EDA_TEXT*>( text.get() ) );
1474  break;
1475 
1476  default:
1477  Expecting( "at or effects" );
1478  }
1479  }
1480 
1481  return text.release();
1482 }
void parseEDA_TEXT(EDA_TEXT *aText)
Define a symbol library graphical text item.
Definition: lib_text.h:40
int m_unit
The current unit being parsed.
T
enum T contains all this lexer's tokens.
int m_convert
The current body style being parsed.
#define THROW_IO_ERROR(msg)
#define _(s)
Definition: 3d_actions.cpp:33
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...

References _, m_convert, m_unit, parseDouble(), parseEDA_TEXT(), parseXY(), DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, and THROW_IO_ERROR.

Referenced by ParseDrawItem().

◆ parseTITLE_BLOCK()

void SCH_SEXPR_PARSER::parseTITLE_BLOCK ( TITLE_BLOCK aTitleBlock)
private

Definition at line 1538 of file sch_sexpr_parser.cpp.

1539 {
1540  wxCHECK_RET( CurTok() == T_title_block,
1541  wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
1542  wxT( " as TITLE_BLOCK." ) );
1543 
1544  T token;
1545 
1546  for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1547  {
1548  if( token != T_LEFT )
1549  Expecting( T_LEFT );
1550 
1551  token = NextTok();
1552 
1553  switch( token )
1554  {
1555  case T_title:
1556  NextTok();
1557  aTitleBlock.SetTitle( FromUTF8() );
1558  break;
1559 
1560  case T_date:
1561  NextTok();
1562  aTitleBlock.SetDate( FromUTF8() );
1563  break;
1564 
1565  case T_rev:
1566  NextTok();
1567  aTitleBlock.SetRevision( FromUTF8() );
1568  break;
1569 
1570  case T_company:
1571  NextTok();
1572  aTitleBlock.SetCompany( FromUTF8() );
1573  break;
1574 
1575  case T_comment:
1576  {
1577  int commentNumber = parseInt( "comment" );
1578 
1579  switch( commentNumber )
1580  {
1581  case 1:
1582  NextTok();
1583  aTitleBlock.SetComment( 0, FromUTF8() );
1584  break;
1585 
1586  case 2:
1587  NextTok();
1588  aTitleBlock.SetComment( 1, FromUTF8() );
1589  break;
1590 
1591  case 3:
1592  NextTok();
1593  aTitleBlock.SetComment( 2, FromUTF8() );
1594  break;
1595 
1596  case 4:
1597  NextTok();
1598  aTitleBlock.SetComment( 3, FromUTF8() );
1599  break;
1600 
1601  case 5:
1602  NextTok();
1603  aTitleBlock.SetComment( 4, FromUTF8() );
1604  break;
1605 
1606  case 6:
1607  NextTok();
1608  aTitleBlock.SetComment( 5, FromUTF8() );
1609  break;
1610 
1611  case 7:
1612  NextTok();
1613  aTitleBlock.SetComment( 6, FromUTF8() );
1614  break;
1615 
1616  case 8:
1617  NextTok();
1618  aTitleBlock.SetComment( 7, FromUTF8() );
1619  break;
1620 
1621  case 9:
1622  NextTok();
1623  aTitleBlock.SetComment( 8, FromUTF8() );
1624  break;
1625 
1626  default:
1627  wxString err;
1628  err.Printf( wxT( "%d is not a valid title block comment number" ), commentNumber );
1629  THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
1630  }
1631 
1632  break;
1633  }
1634 
1635  default:
1636  Expecting( "title, date, rev, company, or comment" );
1637  }
1638 
1639  NeedRIGHT();
1640  }
1641 }
void SetRevision(const wxString &aRevision)
Definition: title_block.h:84
void SetDate(const wxString &aDate)
Function SetDate sets the date field, and defaults to the current time and date.
Definition: title_block.h:74
T
enum T contains all this lexer's tokens.
void SetComment(int aIdx, const wxString &aComment)
Definition: title_block.h:104
void SetCompany(const wxString &aCompany)
Definition: title_block.h:94
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
void SetTitle(const wxString &aTitle)
Definition: title_block.h:60

References parseInt(), TITLE_BLOCK::SetComment(), TITLE_BLOCK::SetCompany(), TITLE_BLOCK::SetDate(), TITLE_BLOCK::SetRevision(), TITLE_BLOCK::SetTitle(), DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, and THROW_PARSE_ERROR.

Referenced by ParseSchematic().

◆ parseXY()

Member Data Documentation

◆ m_convert

int SCH_SEXPR_PARSER::m_convert
private

The current body style being parsed.

Definition at line 84 of file sch_sexpr_parser.h.

Referenced by parseArc(), parseBezier(), parseCircle(), ParseLib(), parsePin(), parsePolyLine(), parseRectangle(), ParseSymbol(), and parseText().

◆ m_fieldId

int SCH_SEXPR_PARSER::m_fieldId
private

The current field ID.

Definition at line 82 of file sch_sexpr_parser.h.

Referenced by parseSchematicSymbol(), and ParseSymbol().

◆ m_requiredVersion

int SCH_SEXPR_PARSER::m_requiredVersion
private

Set to the symbol library file version required.

Definition at line 81 of file sch_sexpr_parser.h.

Referenced by IsTooRecent(), parseHeader(), ParseLib(), parsePAGE_INFO(), ParseSchematic(), parseSheet(), and ParseSymbol().

◆ m_symbolName

wxString SCH_SEXPR_PARSER::m_symbolName
private

The current symbol name.

Definition at line 85 of file sch_sexpr_parser.h.

Referenced by ParseSymbol().

◆ m_unit

int SCH_SEXPR_PARSER::m_unit
private

The current unit being parsed.

Definition at line 83 of file sch_sexpr_parser.h.

Referenced by parseArc(), parseBezier(), parseCircle(), ParseLib(), parsePin(), parsePolyLine(), parseRectangle(), ParseSymbol(), and parseText().


The documentation for this class was generated from the following files: