34#include <wx/mstream.h>
35#include <wx/tokenzr.h>
65using namespace TSCHEMATIC_T;
69 unsigned aLineCount,
SCH_SHEET* aRootSheet,
71 SCHEMATIC_LEXER( aLineReader ),
72 m_requiredVersion( 0 ),
76 m_appending( aIsAppending ),
77 m_progressReporter( aProgressReporter ),
78 m_lineReader( aLineReader ),
79 m_lastProgressLine( 0 ),
80 m_lineCount( aLineCount ),
81 m_rootSheet( aRootSheet )
88 const unsigned PROGRESS_DELTA = 250;
110 KIID id( FromUTF8() );
127 else if( token == T_no )
130 Expecting(
"yes or no" );
144 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
146 if( token != T_LEFT )
151 if( token == T_symbol )
156 aSymbolLibMap[symbol->
GetName()] = symbol;
160 Expecting(
"symbol" );
168 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
169 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
175 wxString unitDisplayName;
177 std::unique_ptr<LIB_SYMBOL> symbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
180 symbol->SetUnitCount( 1 );
187 if( !IsSymbol( token ) )
189 THROW_PARSE_ERROR(
_(
"Invalid symbol name" ), CurSource(), CurLine(), CurLineNumber(),
200 if(
static_cast<int>(
name.size() ) > bad_pos )
202 wxString msg = wxString::Format(
203 _(
"Symbol %s contains invalid character '%c'" ),
name,
211 CurLineNumber(), CurOffset() );
216 symbol->SetLibId(
id );
218 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
220 if( token != T_LEFT )
239 if( token != T_hide )
242 symbol->SetShowPinNumbers(
false );
252 symbol->SetIncludeOnBoard(
parseBool() );
264 if( !IsSymbol( token ) )
267 CurLineNumber(), CurOffset() );
271 auto it = aSymbolLibMap.find(
name );
273 if( it == aSymbolLibMap.end() )
275 error.Printf(
_(
"No parent for extended symbol %s" ),
name.c_str() );
276 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
279 symbol->SetParent( it->second );
288 if( !IsSymbol( token ) )
291 CurLineNumber(), CurOffset() );
298 error.Printf(
_(
"Invalid symbol unit name prefix %s" ),
name.c_str() );
299 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
304 wxStringTokenizer tokenizer(
name,
"_" );
306 if( tokenizer.CountTokens() != 2 )
308 error.Printf(
_(
"Invalid symbol unit name suffix %s" ),
name.c_str() );
309 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
312 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
314 error.Printf(
_(
"Invalid symbol unit number %s" ),
name.c_str() );
315 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
318 m_unit =
static_cast<int>( tmp );
320 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
322 error.Printf(
_(
"Invalid symbol convert number %s" ),
name.c_str() );
323 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
329 symbol->SetConversion(
true,
false );
331 if(
m_unit > symbol->GetUnitCount() )
332 symbol->SetUnitCount(
m_unit,
false );
334 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
336 if( token != T_LEFT )
346 if( IsSymbol( token ) )
348 unitDisplayName = FromUTF8();
349 symbol->SetUnitDisplayName(
m_unit, unitDisplayName );
364 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
367 symbol->AddDrawItem( item,
false );
371 Expecting(
"arc, bezier, circle, pin, polyline, rectangle, or text" );
390 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
393 symbol->AddDrawItem( item,
false );
397 Expecting(
"pin_names, pin_numbers, arc, bezier, circle, pin, polyline, "
398 "rectangle, or text" );
402 symbol->GetDrawItems().sort();
405 return symbol.release();
446 Expecting(
"arc, bezier, circle, pin, polyline, rectangle, or text" );
460 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
462 return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
470 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
472 return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
479 strokeParser.SyncLineReaderWith( *
this );
482 SyncLineReaderWith( strokeParser );
488 wxCHECK_RET( CurTok() == T_fill,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a fill." );
491 aFill.
m_Color = COLOR4D::UNSPECIFIED;
495 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
497 if( token != T_LEFT )
510 case T_none: aFill.
m_FillType = FILL_T::NO_FILL;
break;
511 case T_outline: aFill.
m_FillType = FILL_T::FILLED_SHAPE;
break;
512 case T_background: aFill.
m_FillType = FILL_T::FILLED_WITH_BG_BODYCOLOR;
break;
513 case T_color: aFill.
m_FillType = FILL_T::FILLED_WITH_COLOR;
break;
514 default: Expecting(
"none, outline, color or background" );
535 Expecting(
"type or color" );
543 wxCHECK_RET( aText && ( CurTok() == T_effects || CurTok() == T_href ),
544 "Cannot parse " + GetTokenString( CurTok() ) +
" as an EDA_TEXT." );
560 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
562 if( token == T_LEFT )
568 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
570 if( token == T_LEFT )
577 faceName = FromUTF8();
619 Expecting(
"face, size, thickness, line_spacing, bold, or italic" );
623 if( !faceName.IsEmpty() )
632 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
641 case T_mirror:
break;
642 default: Expecting(
"left, right, top, bottom, or mirror" );
651 wxString hyperlink = FromUTF8();
656 CurSource(), CurLine(), CurLineNumber(), CurOffset() );
672 Expecting(
"font, justify, hide or href" );
680 wxCHECK_RET( CurTok() == aHeaderType,
681 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a header." ) );
687 if( tok == T_version )
720 wxCHECK_RET( CurTok() == T_pin_names,
721 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_name token." );
725 if( token == T_LEFT )
729 if( token != T_offset )
730 Expecting(
"offset" );
737 if( token == T_hide )
739 aSymbol->SetShowPinNames(
false );
742 else if( token != T_RIGHT )
745 CurLineNumber(), CurOffset() );
752 wxCHECK_MSG( CurTok() == T_property,
nullptr,
753 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a property." ) );
754 wxCHECK( aSymbol,
nullptr );
758 std::unique_ptr<LIB_FIELD> field = std::make_unique<LIB_FIELD>( aSymbol.get(),
763 if( !IsSymbol( token ) )
765 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
773 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
777 field->SetName(
name );
792 if( !IsSymbol( token ) )
794 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
801 field->SetText( value );
803 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
805 if( token != T_LEFT )
813 field->SetId(
parseInt(
"field ID" ) );
818 field->SetPosition(
parseXY() );
828 field->SetNameShown();
832 case T_do_not_autoplace:
833 field->SetCanAutoplace(
false );
838 Expecting(
"id, at, show_name, do_not_autoplace, or effects" );
847 int nextAvailableId = field->GetId() + 1;
850 nextAvailableId += 1;
852 field->SetId( nextAvailableId );
859 existingField = aSymbol->GetFieldById( field->GetId() );
861 *existingField = *field;
863 return existingField;
865 else if(
name ==
"ki_keywords" )
868 aSymbol->SetKeyWords( value );
871 else if(
name ==
"ki_description" )
874 aSymbol->SetDescription( value );
877 else if(
name ==
"ki_fp_filters" )
880 wxArrayString filters;
881 wxStringTokenizer tokenizer( value );
883 while( tokenizer.HasMoreTokens() )
886 filters.Add( curr_token );
889 aSymbol->SetFPFilters( filters );
892 else if(
name ==
"ki_locked" )
896 aSymbol->LockUnits(
true );
902 existingField = aSymbol->FindField( field->GetCanonicalName() );
913 for(
int ii = 1; ii < 10 && existingField; ii++ )
915 wxString newname = base_name;
916 newname <<
'_' << ii;
918 existingField = aSymbol->FindField( newname );
921 field->SetName( newname );
927 aSymbol->AddDrawItem( field.get(),
false );
929 return field.release();
942 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
943 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
949 bool hasMidPoint =
false;
957 bool hasAngles =
false;
959 std::unique_ptr<LIB_SHAPE> arc = std::make_unique<LIB_SHAPE>(
nullptr, SHAPE_T::ARC );
966 if( token == T_private )
968 arc->SetPrivate(
true );
972 for( ; token != T_RIGHT; token = NextTok() )
974 if( token != T_LEFT )
998 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1000 if( token != T_LEFT )
1001 Expecting( T_LEFT );
1029 Expecting(
"at, length, or angles" );
1037 arc->SetStroke( stroke );
1043 arc->SetFillColor( fill.
m_Color );
1047 Expecting(
"start, mid, end, radius, stroke, or fill" );
1053 arc->SetArcGeometry( startPoint, midPoint, endPoint );
1063 EDA_ANGLE arc_start, arc_end, arc_angle;
1064 arc->CalcArcAngles( arc_start, arc_end );
1065 arc_angle = arc_end - arc_start;
1070 arc->SetStart( endPoint );
1071 arc->SetEnd( startPoint );
1074 arc->SetCenter( new_center );
1080 arc->SetCenter( new_center );
1084 else if( hasAngles )
1086 arc->SetCenter( center );
1092 arc->SetStart( endPoint );
1093 arc->SetEnd( startPoint );
1097 EDA_ANGLE arc_start, arc_end, arc_angle;
1098 arc->CalcArcAngles( arc_start, arc_end );
1099 arc_angle = arc_end - arc_start;
1105 arc->SetStart( startPoint );
1106 arc->SetEnd( endPoint );
1110 arc->SetStart( startPoint );
1111 arc->SetEnd( endPoint );
1114 arc->SetCenter( new_center );
1119 wxFAIL_MSG(
"Setting arc without either midpoint or angles not implemented." );
1122 return arc.release();
1128 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
1129 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
1135 std::unique_ptr<LIB_SHAPE> bezier = std::make_unique<LIB_SHAPE>(
nullptr, SHAPE_T::BEZIER );
1137 bezier->SetUnit(
m_unit );
1142 if( token == T_private )
1144 bezier->SetPrivate(
true );
1148 for( ; token != T_RIGHT; token = NextTok() )
1150 if( token != T_LEFT )
1151 Expecting( T_LEFT );
1161 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
1163 if( token != T_LEFT )
1164 Expecting( T_LEFT );
1173 case 0: bezier->SetStart(
parseXY() );
break;
1174 case 1: bezier->SetBezierC1(
parseXY() );
break;
1175 case 2: bezier->SetBezierC2(
parseXY() );
break;
1176 case 3: bezier->SetEnd(
parseXY() );
break;
1177 default: Unexpected(
"control point" );
break;
1187 bezier->SetStroke( stroke );
1193 bezier->SetFillColor( fill.
m_Color );
1197 Expecting(
"pts, stroke, or fill" );
1201 bezier->RebuildBezierToSegmentsPointsList( bezier->GetWidth() );
1203 return bezier.release();
1209 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
1210 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
1218 std::unique_ptr<LIB_SHAPE> circle = std::make_unique<LIB_SHAPE>(
nullptr, SHAPE_T::CIRCLE );
1220 circle->SetUnit(
m_unit );
1225 if( token == T_private )
1227 circle->SetPrivate(
true );
1231 for( ; token != T_RIGHT; token = NextTok() )
1233 if( token != T_LEFT )
1234 Expecting( T_LEFT );
1252 circle->SetStroke( stroke );
1258 circle->SetFillColor( fill.
m_Color );
1262 Expecting(
"center, radius, stroke, or fill" );
1266 circle->SetCenter( center );
1267 circle->SetEnd(
VECTOR2I( center.
x + radius, center.
y ) );
1269 return circle.release();
1279 case T_input:
return ELECTRICAL_PINTYPE::PT_INPUT;
1280 case T_output:
return ELECTRICAL_PINTYPE::PT_OUTPUT;
1281 case T_bidirectional:
return ELECTRICAL_PINTYPE::PT_BIDI;
1282 case T_tri_state:
return ELECTRICAL_PINTYPE::PT_TRISTATE;
1283 case T_passive:
return ELECTRICAL_PINTYPE::PT_PASSIVE;
1284 case T_unspecified:
return ELECTRICAL_PINTYPE::PT_UNSPECIFIED;
1285 case T_power_in:
return ELECTRICAL_PINTYPE::PT_POWER_IN;
1286 case T_power_out:
return ELECTRICAL_PINTYPE::PT_POWER_OUT;
1287 case T_open_collector:
return ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR;
1288 case T_open_emitter:
return ELECTRICAL_PINTYPE::PT_OPENEMITTER;
1290 case T_no_connect:
return ELECTRICAL_PINTYPE::PT_NC;
1291 case T_free:
return ELECTRICAL_PINTYPE::PT_NIC;
1294 Expecting(
"input, output, bidirectional, tri_state, passive, "
1295 "unspecified, power_in, power_out, open_collector, "
1296 "open_emitter, free or no_connect" );
1297 return ELECTRICAL_PINTYPE::PT_UNSPECIFIED;
1305 case T_line:
return GRAPHIC_PINSHAPE::LINE;
1306 case T_inverted:
return GRAPHIC_PINSHAPE::INVERTED;
1307 case T_clock:
return GRAPHIC_PINSHAPE::CLOCK;
1308 case T_inverted_clock:
return GRAPHIC_PINSHAPE::INVERTED_CLOCK;
1309 case T_input_low:
return GRAPHIC_PINSHAPE::INPUT_LOW;
1310 case T_clock_low:
return GRAPHIC_PINSHAPE::CLOCK_LOW;
1311 case T_output_low:
return GRAPHIC_PINSHAPE::OUTPUT_LOW;
1312 case T_edge_clock_high:
return GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK;
1313 case T_non_logic:
return GRAPHIC_PINSHAPE::NONLOGIC;
1316 Expecting(
"line, inverted, clock, inverted_clock, input_low, "
1317 "clock_low, output_low, edge_clock_high, non_logic" );
1318 return GRAPHIC_PINSHAPE::LINE;
1322 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
1323 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a pin token." ) );
1328 std::unique_ptr<LIB_PIN>
pin = std::make_unique<LIB_PIN>(
nullptr );
1335 pin->SetType( parseType( token ) );
1341 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1343 if( token == T_hide )
1345 pin->SetVisible(
false );
1349 if( token != T_LEFT )
1350 Expecting( T_LEFT );
1359 switch(
parseInt(
"pin orientation" ) )
1362 case 90:
pin->SetOrientation(
PIN_UP );
break;
1365 default: Expecting(
"0, 90, 180, or 270" );
1379 if( !IsSymbol( token ) )
1388 pin->SetName( FromUTF8() );
1392 if( token != T_RIGHT )
1396 if( token == T_effects )
1403 pin->SetNameTextSize(
text.GetTextHeight() );
1408 Expecting(
"effects" );
1417 if( !IsSymbol( token ) )
1420 CurLineNumber(), CurOffset() );
1423 pin->SetNumber( FromUTF8() );
1426 if( token != T_RIGHT )
1430 if( token == T_effects )
1437 pin->SetNumberTextSize(
text.GetTextHeight() );
1442 Expecting(
"effects" );
1454 if( !IsSymbol( token ) )
1457 CurLineNumber(), CurOffset() );
1463 alt.
m_Type = parseType( token );
1468 pin->GetAlternates()[ alt.
m_Name ] = alt;
1475 Expecting(
"at, name, number, length, or alternate" );
1479 return pin.release();
1485 wxCHECK_MSG( CurTok() == T_polyline,
nullptr,
1486 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a poly." ) );
1491 std::unique_ptr<LIB_SHAPE> poly = std::make_unique<LIB_SHAPE>(
nullptr, SHAPE_T::POLY );
1498 if( token == T_private )
1500 poly->SetPrivate(
true );
1504 for( ; token != T_RIGHT; token = NextTok() )
1506 if( token != T_LEFT )
1507 Expecting( T_LEFT );
1514 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1516 if( token != T_LEFT )
1517 Expecting( T_LEFT );
1533 poly->SetStroke( stroke );
1539 poly->SetFillColor( fill.
m_Color );
1543 Expecting(
"pts, stroke, or fill" );
1547 return poly.release();
1553 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
1554 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
1559 std::unique_ptr<LIB_SHAPE> rectangle = std::make_unique<LIB_SHAPE>(
nullptr, SHAPE_T::RECT );
1561 rectangle->SetUnit(
m_unit );
1566 if( token == T_private )
1568 rectangle->SetPrivate(
true );
1572 for( ; token != T_RIGHT; token = NextTok() )
1574 if( token != T_LEFT )
1575 Expecting( T_LEFT );
1582 rectangle->SetPosition(
parseXY() );
1587 rectangle->SetEnd(
parseXY() );
1593 rectangle->SetStroke( stroke );
1599 rectangle->SetFillColor( fill.
m_Color );
1603 Expecting(
"start, end, stroke, or fill" );
1607 return rectangle.release();
1613 wxCHECK_MSG( CurTok() == T_text,
nullptr,
1614 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text token." ) );
1617 std::unique_ptr<LIB_TEXT>
text = std::make_unique<LIB_TEXT>(
nullptr );
1623 if( token == T_private )
1625 text->SetPrivate(
true );
1629 if( !IsSymbol( token ) )
1631 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
1635 text->SetText( FromUTF8() );
1637 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1639 if( token != T_LEFT )
1640 Expecting( T_LEFT );
1658 Expecting(
"at or effects" );
1662 return text.release();
1668 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
1669 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
1675 bool foundEnd =
false;
1676 bool foundSize =
false;
1679 std::unique_ptr<LIB_TEXTBOX> textBox = std::make_unique<LIB_TEXTBOX>(
nullptr );
1683 if( token == T_private )
1685 textBox->SetPrivate(
true );
1689 if( !IsSymbol( token ) )
1691 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
1695 textBox->SetText( FromUTF8() );
1697 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1699 if( token != T_LEFT )
1700 Expecting( T_LEFT );
1731 textBox->SetStroke( stroke );
1737 textBox->SetFillColor( fill.
m_Color );
1745 Expecting(
"at, size, stroke, fill or effects" );
1749 textBox->SetPosition( pos );
1752 textBox->SetEnd( end );
1753 else if( foundSize )
1754 textBox->SetEnd( pos + size );
1756 Expecting(
"size" );
1758 return textBox.release();
1764 wxCHECK_RET( ( CurTok() == T_page &&
m_requiredVersion <= 20200506 ) || CurTok() == T_paper,
1765 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a PAGE_INFO." ) );
1771 wxString pageType = FromUTF8();
1773 if( !aPageInfo.
SetType( pageType ) )
1775 THROW_PARSE_ERROR(
_(
"Invalid page type" ), CurSource(), CurLine(), CurLineNumber(),
1802 if( token == T_portrait )
1807 else if( token != T_RIGHT )
1809 Expecting(
"portrait" );
1816 wxCHECK_RET( CurTok() == T_title_block,
1817 "Cannot parse " + GetTokenString( CurTok() ) +
" as a TITLE_BLOCK." );
1821 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1823 if( token != T_LEFT )
1824 Expecting( T_LEFT );
1832 aTitleBlock.
SetTitle( FromUTF8() );
1837 aTitleBlock.
SetDate( FromUTF8() );
1852 int commentNumber =
parseInt(
"comment" );
1854 switch( commentNumber )
1903 CurLine(), CurLineNumber(), CurOffset() );
1910 Expecting(
"title, date, rev, company, or comment" );
1920 wxCHECK_MSG( CurTok() == T_property,
nullptr,
1921 "Cannot parse " + GetTokenString( CurTok() ) +
" as a property token." );
1923 T token = NextTok();
1925 if( !IsSymbol( token ) )
1927 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
1931 wxString
name = FromUTF8();
1933 if(
name.IsEmpty() )
1935 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
1941 if( !IsSymbol( token ) )
1943 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
1948 wxString value = FromUTF8();
1950 std::unique_ptr<SCH_FIELD> field = std::make_unique<SCH_FIELD>(
VECTOR2I(-1,-1), -1,
1952 field->SetText( value );
1953 field->SetVisible(
true );
1980 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1982 if( token != T_LEFT )
1983 Expecting( T_LEFT );
1990 field->SetId(
parseInt(
"field ID" ) );
1995 field->SetPosition(
parseXY() );
2005 field->SetNameShown();
2009 case T_do_not_autoplace:
2010 field->SetCanAutoplace(
false );
2015 Expecting(
"id, at, show_name, do_not_autoplace or effects" );
2019 return field.release();
2025 wxCHECK_MSG( aSheet !=
nullptr,
nullptr,
"" );
2026 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
2027 "Cannot parse " + GetTokenString( CurTok() ) +
" as a sheet pin token." );
2029 T token = NextTok();
2031 if( !IsSymbol( token ) )
2033 THROW_PARSE_ERROR(
_(
"Invalid sheet pin name" ), CurSource(), CurLine(), CurLineNumber(),
2037 wxString
name = FromUTF8();
2039 if(
name.IsEmpty() )
2041 THROW_PARSE_ERROR(
_(
"Empty sheet pin name" ), CurSource(), CurLine(), CurLineNumber(),
2045 auto sheetPin = std::make_unique<SCH_SHEET_PIN>( aSheet,
VECTOR2I( 0, 0 ),
name );
2051 case T_input: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_INPUT );
break;
2052 case T_output: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
break;
2053 case T_bidirectional: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_BIDI );
break;
2054 case T_tri_state: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_TRISTATE );
break;
2055 case T_passive: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
break;
2057 Expecting(
"input, output, bidirectional, tri_state, or passive" );
2060 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2062 if( token != T_LEFT )
2063 Expecting( T_LEFT );
2071 sheetPin->SetPosition(
parseXY() );
2073 double angle =
parseDouble(
"sheet pin angle (side)" );
2076 sheetPin->SetSide( SHEET_SIDE::RIGHT );
2077 else if( angle == 90.0 )
2078 sheetPin->SetSide( SHEET_SIDE::TOP );
2079 else if( angle == 180.0 )
2080 sheetPin->SetSide( SHEET_SIDE::LEFT );
2081 else if( angle == 270.0 )
2082 sheetPin->SetSide( SHEET_SIDE::BOTTOM );
2084 Expecting(
"0, 90, 180, or 270" );
2101 Expecting(
"at, uuid or effects" );
2105 return sheetPin.release();
2111 wxCHECK_RET( CurTok() == T_sheet_instances,
2112 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
2113 wxCHECK( aScreen, );
2117 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2119 if( token != T_LEFT )
2120 Expecting( T_LEFT );
2138 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2140 if( token != T_LEFT )
2141 Expecting( T_LEFT );
2145 std::vector<wxString> whitespaces = { wxT(
"\r" ), wxT(
"\n" ), wxT(
"\t" ),
2148 size_t numReplacements = 0;
2166 for( wxString ch : whitespaces )
2167 numReplacements += instance.
m_PageNumber.Replace( ch, wxEmptyString );
2172 if( numReplacements > 0 )
2179 Expecting(
"path or page" );
2184 && ( instance.
m_Path.empty() ) )
2200 Expecting(
"path" );
2208 wxCHECK_RET( CurTok() == T_symbol_instances,
2209 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
2210 wxCHECK( aScreen, );
2215 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2217 if( token != T_LEFT )
2218 Expecting( T_LEFT );
2235 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2237 if( token != T_LEFT )
2238 Expecting( T_LEFT );
2257 instance.
m_Value = FromUTF8();
2268 Expecting(
"path, unit, value or footprint" );
2277 Expecting(
"path" );
2285 wxCHECK( aSheet !=
nullptr, );
2289 wxCHECK( screen !=
nullptr, );
2291 if( aIsCopyableOnly )
2294 bool fileHasUuid =
false;
2298 if( !aIsCopyableOnly )
2303 if( CurTok() != T_kicad_sch )
2304 Expecting(
"kicad_sch" );
2316 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2318 if( aIsCopyableOnly && token == T_EOF )
2321 if( token != T_LEFT )
2322 Expecting( T_LEFT );
2352 if( aIsCopyableOnly )
2353 Unexpected( T_paper );
2363 if( aIsCopyableOnly )
2364 Unexpected( T_page );
2368 NeedSYMBOLorNUMBER();
2369 NeedSYMBOLorNUMBER();
2376 if( aIsCopyableOnly )
2377 Unexpected( T_title_block );
2391 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2393 if( token != T_LEFT )
2394 Expecting( T_LEFT );
2407 Expecting(
"symbol" );
2504 case T_netclass_flag:
2509 case T_global_label:
2510 case T_hierarchical_label:
2511 case T_directive_label:
2519 case T_sheet_instances:
2523 case T_symbol_instances:
2528 if( aIsCopyableOnly )
2529 Unexpected( T_bus_alias );
2535 Expecting(
"symbol, paper, page, title_block, bitmap, sheet, junction, no_connect, "
2536 "bus_entry, line, bus, text, label, class_label, global_label, "
2537 "hierarchical_label, symbol_instances, or bus_alias" );
2558 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
2559 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
2564 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
2566 std::set<int> fieldIDsRead;
2569 symbol->ClearFieldsAutoplaced();
2574 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2576 if( token != T_LEFT )
2577 Expecting( T_LEFT );
2589 if( !IsSymbol( token ) )
2592 CurLineNumber(), CurOffset() );
2595 libName = FromUTF8();
2604 if( !IsSymbol( token ) && token != T_NUMBER )
2605 Expecting(
"symbol|number" );
2608 wxString
name = FromUTF8();
2613 if(
static_cast<int>(
name.size() ) > bad_pos )
2615 wxString msg = wxString::Format(
2616 _(
"Symbol %s contains invalid character '%c'" ),
name,
2623 CurLineNumber(), CurOffset() );
2626 symbol->SetLibId( libId );
2632 symbol->SetPosition(
parseXY() );
2634 switch(
static_cast<int>(
parseDouble(
"symbol orientation" ) ) )
2637 case 90: transform =
TRANSFORM( 0, -1, -1, 0 );
break;
2638 case 180: transform =
TRANSFORM( -1, 0, 0, 1 );
break;
2639 case 270: transform =
TRANSFORM( 0, 1, 1, 0 );
break;
2640 default: Expecting(
"0, 90, 180, or 270" );
2643 symbol->SetTransform( transform );
2652 else if( token == T_y )
2655 Expecting(
"x or y" );
2661 symbol->SetUnit(
parseInt(
"symbol unit" ) );
2666 symbol->SetConvert(
parseInt(
"symbol convert" ) );
2676 symbol->SetIncludeOnBoard(
parseBool() );
2685 case T_fields_autoplaced:
2686 symbol->SetFieldsAutoplaced();
2696 case T_default_instance:
2700 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2702 if( token != T_LEFT )
2703 Expecting( T_LEFT );
2722 symbol->SetValueFieldText( FromUTF8() );
2728 symbol->SetFootprintFieldText( FromUTF8() );
2733 Expecting(
"reference, unit, value or footprint" );
2742 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2744 if( token != T_LEFT )
2745 Expecting( T_LEFT );
2749 if( token != T_project )
2750 Expecting(
"project" );
2754 wxString projectName = FromUTF8();
2756 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2758 if( token != T_LEFT )
2759 Expecting( T_LEFT );
2763 if( token != T_path )
2764 Expecting(
"path" );
2773 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2775 if( token != T_LEFT )
2776 Expecting( T_LEFT );
2795 symbol->SetValueFieldText( FromUTF8() );
2801 symbol->SetFootprintFieldText( FromUTF8() );
2806 Expecting(
"reference, unit, value or footprint" );
2809 symbol->AddHierarchicalReference( instance );
2824 int nextAvailableId = field->
GetId() + 1;
2827 nextAvailableId += 1;
2829 field->
SetId( nextAvailableId );
2832 if( symbol->GetFieldById( field->
GetId() ) )
2833 *symbol->GetFieldById( field->
GetId() ) = *field;
2835 symbol->AddField( *field );
2838 symbol->UpdatePrefix();
2853 number = FromUTF8();
2855 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2857 if( token != T_LEFT )
2858 Expecting( T_LEFT );
2882 Expecting(
"alternate or uuid" );
2886 symbol->GetRawPins().emplace_back( std::make_unique<SCH_PIN>( symbol.get(),
2889 const_cast<KIID&
>( symbol->GetRawPins().back()->m_Uuid ) = uuid;
2894 Expecting(
"lib_id, lib_name, at, mirror, uuid, on_board, in_bom, dnp, "
2895 "default_instance, property, pin, or instances" );
2899 if( !libName.IsEmpty() && ( symbol->GetLibId().Format().wx_str() != libName ) )
2900 symbol->SetSchSymbolLibraryName( libName );
2903 symbol->ClearFlags();
2905 return symbol.release();
2911 wxCHECK_MSG( CurTok() == T_image,
nullptr,
2912 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an image." ) );
2915 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>();
2917 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2919 if( token != T_LEFT )
2920 Expecting( T_LEFT );
2927 bitmap->SetPosition(
parseXY() );
2932 bitmap->GetImage()->SetScale(
parseDouble(
"image scale factor" ) );
2934 if( !std::isnormal( bitmap->GetImage()->GetScale() ) )
2935 bitmap->GetImage()->SetScale( 1.0 );
2954 data.reserve( 1 << 17 );
2956 while( token != T_RIGHT )
2958 if( !IsSymbol( token ) )
2959 Expecting(
"base64 image data" );
2965 wxMemoryBuffer buffer = wxBase64Decode( data );
2966 wxMemoryOutputStream stream( buffer.GetData(), buffer.GetBufSize() );
2967 wxImage*
image =
new wxImage();
2968 wxMemoryInputStream istream( stream );
2969 image->LoadFile( istream, wxBITMAP_TYPE_PNG );
2970 bitmap->SetImage(
image );
2975 Expecting(
"at, scale, uuid or data" );
2987 return bitmap.release();
2993 wxCHECK_MSG( CurTok() == T_sheet,
nullptr,
2994 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a sheet." ) );
3000 std::vector<SCH_FIELD> fields;
3001 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>();
3002 std::set<int> fieldIDsRead;
3005 sheet->ClearFieldsAutoplaced();
3007 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3009 if( token != T_LEFT )
3010 Expecting( T_LEFT );
3017 sheet->SetPosition(
parseXY() );
3026 sheet->SetSize( size );
3031 case T_fields_autoplaced:
3032 sheet->SetFieldsAutoplaced();
3038 sheet->SetBorderWidth( stroke.
GetWidth() );
3039 sheet->SetBorderColor( stroke.
GetColor() );
3044 sheet->SetBackgroundColor( fill.
m_Color );
3061 if( fields.empty() )
3075 if( field->
GetId() < 0 )
3078 while( !fieldIDsRead.insert( field->
GetId() ).second )
3081 fields.emplace_back( *field );
3091 std::vector<SCH_SHEET_INSTANCE> instances;
3093 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3095 if( token != T_LEFT )
3096 Expecting( T_LEFT );
3100 if( token != T_project )
3101 Expecting(
"project" );
3105 wxString projectName = FromUTF8();
3107 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3109 if( token != T_LEFT )
3110 Expecting( T_LEFT );
3114 if( token != T_path )
3115 Expecting(
"path" );
3124 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3126 if( token != T_LEFT )
3127 Expecting( T_LEFT );
3147 std::vector<wxString> whitespaces = { wxT(
"\r" ), wxT(
"\n" ),
3148 wxT(
"\t" ), wxT(
" " ) };
3150 for( wxString ch : whitespaces )
3159 Expecting(
"page" );
3163 instances.emplace_back( instance );
3167 sheet->setInstances( instances );
3172 Expecting(
"at, size, stroke, background, instances, uuid, property, or pin" );
3176 sheet->SetFields( fields );
3178 return sheet.release();
3184 wxCHECK_MSG( CurTok() == T_junction,
nullptr,
3185 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a junction." ) );
3188 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
3190 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3192 if( token != T_LEFT )
3193 Expecting( T_LEFT );
3200 junction->SetPosition(
parseXY() );
3218 junction->SetColor(
color );
3230 Expecting(
"at, diameter, color or uuid" );
3234 return junction.release();
3240 wxCHECK_MSG( CurTok() == T_no_connect,
nullptr,
3241 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a no connect." ) );
3244 std::unique_ptr<SCH_NO_CONNECT> no_connect = std::make_unique<SCH_NO_CONNECT>();
3246 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3248 if( token != T_LEFT )
3249 Expecting( T_LEFT );
3256 no_connect->SetPosition(
parseXY() );
3267 Expecting(
"at or uuid" );
3271 return no_connect.release();
3277 wxCHECK_MSG( CurTok() == T_bus_entry,
nullptr,
3278 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus entry." ) );
3282 std::unique_ptr<SCH_BUS_WIRE_ENTRY> busEntry = std::make_unique<SCH_BUS_WIRE_ENTRY>();
3284 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3286 if( token != T_LEFT )
3287 Expecting( T_LEFT );
3294 busEntry->SetPosition(
parseXY() );
3304 busEntry->SetSize( size );
3311 busEntry->SetStroke( stroke );
3321 Expecting(
"at, size, uuid or stroke" );
3325 return busEntry.release();
3336 std::unique_ptr<SCH_SHAPE> polyline = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY, layer );
3338 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3340 if( token != T_LEFT )
3341 Expecting( T_LEFT );
3348 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3350 if( token != T_LEFT )
3351 Expecting( T_LEFT );
3358 polyline->AddPoint(
parseXY() );
3366 polyline->SetStroke( stroke );
3372 polyline->SetFillColor( fill.
m_Color );
3382 Expecting(
"pts, uuid, stroke, or fill" );
3386 return polyline.release();
3405 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a line." );
3408 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>(
VECTOR2I(), layer );
3410 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3412 if( token != T_LEFT )
3413 Expecting( T_LEFT );
3426 line->SetStartPoint(
parseXY() );
3434 line->SetEndPoint(
parseXY() );
3441 line->SetStroke( stroke );
3451 Expecting(
"at, uuid or stroke" );
3455 return line.release();
3461 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
3462 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
3470 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>( SHAPE_T::ARC );
3472 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3474 if( token != T_LEFT )
3475 Expecting( T_LEFT );
3498 arc->SetStroke( stroke );
3504 arc->SetFillColor( fill.
m_Color );
3509 const_cast<KIID&
>( arc->m_Uuid ) =
KIID( FromUTF8() );
3514 Expecting(
"start, mid, end, stroke, fill or uuid" );
3518 arc->SetArcGeometry( startPoint, midPoint, endPoint );
3520 return arc.release();
3526 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
3527 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
3534 std::unique_ptr<SCH_SHAPE> circle = std::make_unique<SCH_SHAPE>( SHAPE_T::CIRCLE );
3536 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3538 if( token != T_LEFT )
3539 Expecting( T_LEFT );
3557 circle->SetStroke( stroke );
3563 circle->SetFillColor( fill.
m_Color );
3568 const_cast<KIID&
>( circle->m_Uuid ) =
KIID( FromUTF8() );
3573 Expecting(
"center, radius, stroke, fill or uuid" );
3577 circle->SetCenter( center );
3578 circle->SetEnd(
VECTOR2I( center.
x + radius, center.
y ) );
3580 return circle.release();
3586 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
3587 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
3592 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>( SHAPE_T::RECT );
3594 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3596 if( token != T_LEFT )
3597 Expecting( T_LEFT );
3604 rectangle->SetPosition(
parseXY() );
3609 rectangle->SetEnd(
parseXY() );
3615 rectangle->SetStroke( stroke );
3621 rectangle->SetFillColor( fill.
m_Color );
3626 const_cast<KIID&
>( rectangle->m_Uuid ) =
KIID( FromUTF8() );
3631 Expecting(
"start, end, stroke, fill or uuid" );
3635 return rectangle.release();
3641 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
3642 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
3647 std::unique_ptr<SCH_SHAPE> bezier = std::make_unique<SCH_SHAPE>( SHAPE_T::BEZIER );
3649 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3651 if( token != T_LEFT )
3652 Expecting( T_LEFT );
3659 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3661 if( token != T_LEFT )
3662 Expecting( T_LEFT );
3669 bezier->AddPoint(
parseXY() );
3678 bezier->SetStroke( stroke );
3684 bezier->SetFillColor( fill.
m_Color );
3689 const_cast<KIID&
>( bezier->m_Uuid ) =
KIID( FromUTF8() );
3694 Expecting(
"pts, stroke, fill or uuid" );
3698 return bezier.release();
3705 std::unique_ptr<SCH_TEXT>
text;
3709 case T_text:
text = std::make_unique<SCH_TEXT>();
break;
3710 case T_label:
text = std::make_unique<SCH_LABEL>();
break;
3711 case T_global_label:
text = std::make_unique<SCH_GLOBALLABEL>();
break;
3712 case T_hierarchical_label:
text = std::make_unique<SCH_HIERLABEL>();
break;
3713 case T_netclass_flag:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
3714 case T_directive_label:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
3716 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as text." );
3720 text->ClearFieldsAutoplaced();
3724 text->SetText( FromUTF8() );
3726 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3728 if( token != T_LEFT )
3729 Expecting( T_LEFT );
3735 case T_exclude_from_sim:
3743 switch(
static_cast<int>(
parseDouble(
"text angle" ) ) )
3761 Unexpected( T_shape );
3769 case T_input: label->
SetShape( LABEL_FLAG_SHAPE::L_INPUT );
break;
3770 case T_output: label->
SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
break;
3771 case T_bidirectional: label->
SetShape( LABEL_FLAG_SHAPE::L_BIDI );
break;
3772 case T_tri_state: label->
SetShape( LABEL_FLAG_SHAPE::L_TRISTATE );
break;
3773 case T_passive: label->
SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
break;
3774 case T_dot: label->
SetShape( LABEL_FLAG_SHAPE::F_DOT );
break;
3775 case T_round: label->
SetShape( LABEL_FLAG_SHAPE::F_ROUND );
break;
3776 case T_diamond: label->
SetShape( LABEL_FLAG_SHAPE::F_DIAMOND );
break;
3777 case T_rectangle: label->
SetShape( LABEL_FLAG_SHAPE::F_RECTANGLE );
break;
3779 Expecting(
"input, output, bidirectional, tri_state, passive, dot, round, diamond"
3790 Unexpected( T_length );
3799 case T_fields_autoplaced:
3800 text->SetFieldsAutoplaced();
3811 &&
text->GetTextAngle().IsVertical() )
3818 &&
text->GetTextAngle().IsHorizontal() )
3850 Unexpected( T_property );
3877 Expecting(
"at, shape, iref, uuid or effects" );
3883 if( label && label->
GetFields().empty() )
3886 return text.release();
3892 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
3893 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
3899 bool foundEnd =
false;
3900 bool foundSize =
false;
3903 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>();
3907 textBox->SetText( FromUTF8() );
3909 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3911 if( token != T_LEFT )
3912 Expecting( T_LEFT );
3918 case T_exclude_from_sim:
3919 textBox->SetExcludeFromSim(
parseBool() );
3948 textBox->SetStroke( stroke );
3954 textBox->SetFillColor( fill.
m_Color );
3963 const_cast<KIID&
>( textBox->m_Uuid ) =
KIID( FromUTF8() );
3968 Expecting(
"at, size, stroke, fill, effects or uuid" );
3972 textBox->SetPosition( pos );
3975 textBox->SetEnd( end );
3976 else if( foundSize )
3977 textBox->SetEnd( pos + size );
3979 Expecting(
"size" );
3981 return textBox.release();
3987 wxCHECK_RET( CurTok() == T_bus_alias,
3988 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus alias." ) );
3989 wxCHECK( aScreen, );
3992 std::shared_ptr<BUS_ALIAS> busAlias = std::make_shared<BUS_ALIAS>( aScreen );
4003 busAlias->SetName( alias );
4008 if( token != T_members )
4009 Expecting(
"members" );
4013 while( token != T_RIGHT )
4015 if( !IsSymbol( token ) )
4016 Expecting(
"quoted string" );
4018 member = FromUTF8();
4023 busAlias->Members().emplace_back( member );
constexpr EDA_IU_SCALE schIUScale
void SetContentModified(bool aModified=true)
This class handle bitmap images in KiCad.
KICAD_T Type() const
Returns the type of object.
virtual void SetParent(EDA_ITEM *aParent)
SHAPE_POLY_SET & GetPolyShape()
int GetPointCount() const
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
void SetTextColor(const COLOR4D &aColor)
virtual const wxString & GetText() const
Return the string associated with the text object.
void SetTextPos(const VECTOR2I &aPoint)
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
void SetLineSpacing(double aLineSpacing)
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
static bool ValidateHyperlink(const wxString &aURL)
Check if aURL is a valid hyperlink.
void SetHyperlink(wxString aLink)
void SetTextSize(const VECTOR2I &aNewSize)
virtual void SetText(const wxString &aText)
void SetItalic(bool aItalic)
void SetFont(KIFONT::FONT *aFont)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Simple container to manage fill parameters.
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false)
A color representation with 4 components: red, green, blue, alpha.
Field object used in symbol libraries.
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
A logical library item identifier and consists of various portions much like a URI.
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
The base class for drawable items used by schematic library symbols.
Define a library symbol object.
wxString GetName() const override
int UpdateFieldOrdinals()
Order optional field indices.
Define a symbol library graphical text item.
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
virtual unsigned LineNumber() const
Return the line number of the last line read from this LINE_READER.
Describe the page size and margins of a paper page on which to eventually print or plot.
void SetWidthMils(int aWidthInMils)
void SetPortrait(bool aIsPortrait)
Rotate the paper page 90 degrees.
static const wxChar Custom[]
"User" defined page type
void SetHeightMils(int aHeightInMils)
bool SetType(const wxString &aStandardPageDescriptionName, bool aIsPortrait=false)
Set the name of the page type and also the sizes and margins commonly associated with that type name.
A progress reporter interface for use in multi-threaded environments.
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).
Object to handle a bitmap image that can be inserted in a schematic.
Class for a wire to bus entry.
void SetPinLength(int aLength)
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
const wxString & GetInternalName()
Get the initial name of the field set at creation (or set by SetName()).
Base class for any item which can be embedded within the SCHEMATIC container class,...
void SetFieldsAutoplaced()
void SetShape(LABEL_FLAG_SHAPE aShape) override
std::vector< SCH_FIELD > & GetFields()
Segment description base class to describe items which have 2 end points (track, wire,...
void SetStartPoint(const VECTOR2I &aPosition)
virtual void SetStroke(const STROKE_PARAMS &aStroke) override
void SetEndPoint(const VECTOR2I &aPosition)
void SetFileFormatVersionAtLoad(int aVersion)
std::vector< SCH_SHEET_INSTANCE > m_sheetInstances
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
void AddLibSymbol(LIB_SYMBOL *aLibSymbol)
Add aLibSymbol to the library symbol map.
void AddBusAlias(std::shared_ptr< BUS_ALIAS > aAlias)
Add a bus alias definition (and transfers ownership of the pointer).
void SetPageSettings(const PAGE_INFO &aPageSettings)
const KIID & GetUuid() const
void UpdateLocalLibSymbolLinks()
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in this schematic with the local projec...
void SetLegacySymbolInstanceData()
Update the symbol value and footprint instance data for legacy designs.
int GetFileFormatVersionAtLoad() const
KIID m_uuid
A unique identifier for each schematic file.
std::vector< SCH_SYMBOL_INSTANCE > m_symbolInstances
The list of symbol instances loaded from the schematic file.
std::set< int > m_fieldIDsRead
Field IDs that have been read so far for the current symbol.
void parseBusAlias(SCH_SCREEN *aScreen)
int m_convert
The current body style being parsed.
SCH_SHEET_PIN * parseSchSheetPin(SCH_SHEET *aSheet)
void parseSchSheetInstances(SCH_SHEET *aRootSheet, SCH_SCREEN *aScreen)
SCH_BUS_WIRE_ENTRY * parseBusEntry()
void ParseLib(LIB_SYMBOL_MAP &aSymbolLibMap)
SCH_JUNCTION * parseJunction()
int m_fieldId
The current field ID.
void ParseSchematic(SCH_SHEET *aSheet, bool aIsCopyablyOnly=false, int aFileVersion=SEXPR_SCHEMATIC_FILE_VERSION)
Parse the internal LINE_READER object into aSheet.
LIB_ITEM * ParseDrawItem()
void parseHeader(TSCHEMATIC_T::T aHeaderType, int aFileVersion)
SCH_NO_CONNECT * parseNoConnect()
LIB_SHAPE * parseBezier()
SCH_SHAPE * parseSchCircle()
int m_unit
The current unit being parsed.
LIB_SHAPE * parseCircle()
SCH_SHAPE * parseSchRectangle()
SCH_SYMBOL * parseSchematicSymbol()
const LINE_READER * m_lineReader
SCH_BITMAP * parseImage()
SCH_SHAPE * parseSchBezier()
SCH_SHAPE * parseSchArc()
LIB_FIELD * parseProperty(std::unique_ptr< LIB_SYMBOL > &aSymbol)
void parseStroke(STROKE_PARAMS &aStroke)
Parse stroke definition aStroke.
LIB_SHAPE * parseRectangle()
SCH_SEXPR_PARSER(LINE_READER *aLineReader=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr, unsigned aLineCount=0, SCH_SHEET *aRootSheet=nullptr, bool aIsAppending=false)
void parseTITLE_BLOCK(TITLE_BLOCK &aTitleBlock)
LIB_SHAPE * parsePolyLine()
int m_requiredVersion
Set to the symbol library file version required.
SCH_TEXTBOX * parseSchTextBox()
SCH_TEXT * parseSchText()
LIB_TEXTBOX * parseTextBox()
wxString m_symbolName
The current symbol name.
SCH_FIELD * parseSchField(SCH_ITEM *aParent)
void parseEDA_TEXT(EDA_TEXT *aText, bool aConvertOverbarSyntax)
PROGRESS_REPORTER * m_progressReporter
void parseFill(FILL_PARAMS &aFill)
void parseSchSymbolInstances(SCH_SCREEN *aScreen)
void parsePinNames(std::unique_ptr< LIB_SYMBOL > &aSymbol)
unsigned m_lastProgressLine
void parsePAGE_INFO(PAGE_INFO &aPageInfo)
LIB_SYMBOL * ParseSymbol(LIB_SYMBOL_MAP &aSymbolLibMap, int aFileVersion=SEXPR_SYMBOL_LIB_FILE_VERSION)
SCH_SHEET * m_rootSheet
The rootsheet for full project loads or null for importing a schematic.
SCH_SHAPE * parseSchPolyLine()
bool m_appending
Appending load status.
STROKE_PARAMS GetStroke() const override
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslated=true)
SCH_SCREEN * GetScreen() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
void ParseStroke(STROKE_PARAMS &aStroke)
Simple container to manage line stroke parameters.
KIGFX::COLOR4D GetColor() const
Hold the information shown in the lower right corner of a plot, printout, or editing view.
void SetRevision(const wxString &aRevision)
void SetComment(int aIdx, const wxString &aComment)
void SetTitle(const wxString &aTitle)
void SetCompany(const wxString &aCompany)
void SetDate(const wxString &aDate)
Set the date field, and defaults to the current time and date.
#define DEFAULT_LINE_WIDTH_MILS
The default wire width in mils. (can be changed in preference menu)
static constexpr EDA_ANGLE & ANGLE_180
static constexpr EDA_ANGLE & ANGLE_360
static constexpr EDA_ANGLE & ANGLE_90
static constexpr EDA_ANGLE & ANGLE_0
#define DEFAULT_SIZE_TEXT
This is the "default-of-the-default" hardcoded text size; individual application define their own def...
#define THROW_IO_ERROR(msg)
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
int Mm2mils(double aVal)
Convert mm to mils.
#define MIN_PAGE_SIZE_MILS
Min and max page sizes for clamping, in mils.
#define MAX_PAGE_SIZE_EESCHEMA_MILS
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
static std::shared_ptr< SHAPE > parseShape(SHAPE_TYPE expectedType, wxStringTokenizer &aTokens)
#define SEXPR_SYMBOL_LIB_FILE_VERSION
This file contains the file format version information for the s-expression schematic and symbol libr...
#define SEXPR_SCHEMATIC_FILE_VERSION
Schematic file version.
double parseDouble(LINE_READER &aReader, const char *aLine, const char **aOutput)
Parses an ASCII point string with possible leading whitespace into a double precision floating point ...
Schematic and symbol library s-expression file format parser definitions.
@ SHEET_MANDATORY_FIELDS
The first 2 are mandatory, and must be instantiated in SCH_SHEET.
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
wxString UnescapeString(const wxString &aSource)
constexpr int MilsToIU(int mils) const
ELECTRICAL_PINTYPE m_Type
A simple container for sheet instance information.
A simple container for schematic symbol instance information.
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslateForHI=false)
Return a default symbol field name for field aFieldNdx for all components.
std::map< wxString, LIB_SYMBOL *, LibSymbolMapSort > LIB_SYMBOL_MAP
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ MANDATORY_FIELDS
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
const VECTOR2I CalcArcCenter(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Determine the center of an arc or circle given three points on its circumference.
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
constexpr T Clamp(const T &lower, const T &value, const T &upper)
Limit value within the range lower <= value <= upper.