31#include <fmt/format.h>
35#include <wx/mstream.h>
36#include <wx/tokenzr.h>
74using namespace TSCHEMATIC_T;
79 unsigned aLineCount,
SCH_SHEET* aRootSheet,
80 bool aIsAppending,
bool aIsSheetLoad ) :
81 SCHEMATIC_LEXER( aLineReader ),
101 unsigned progressDelta = std::max( 50u,
m_lineCount / 10 );
120 KIID id( FromUTF8() );
137 else if( token == T_no )
140 Expecting(
"yes or no" );
149 wxString key = FromUTF8();
151 wxString value = FromUTF8();
160 wxString key = FromUTF8();
162 wxString value = FromUTF8();
173 bool ret = aDefaultValue;
175 if( PrevTok() == T_LEFT )
180 if(
static_cast<int>( token ) ==
DSN_RIGHT )
181 return aDefaultValue;
185 else if( token == T_no )
188 Expecting(
"yes or no" );
195 return aDefaultValue;
213 bool versionChecked =
false;
224 versionChecked =
true;
227 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
229 if( token != T_LEFT )
255 case T_generator_version:
278 aSymbolLibMap[symbol->
GetName()] = symbol;
283 wxString warning = wxString::Format(
284 _(
"Error parsing symbol at line %d: %s\nSkipping symbol and continuing." ),
285 CurLineNumber(), e.
What() );
297 Expecting(
"symbol, generator, or generator_version" );
310 if( CurTok() == T_LEFT )
314 if( CurTok() == T_symbol )
319 const std::vector<wxString>* embeddedFonts =
326 textItem->ResolveFont( embeddedFonts );
332 wxString msg = wxString::Format(
_(
"Cannot parse %s as a symbol" ), GetTokenString( CurTok() ) );
343 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
344 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
351 std::unique_ptr<LIB_SYMBOL> symbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
353 symbol->SetUnitCount( 1,
true );
357 if( !IsSymbol( token ) )
358 THROW_PARSE_ERROR(
_(
"Invalid symbol name" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
365 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
372 if(
static_cast<int>(
name.size() ) > bad_pos )
374 wxString msg = wxString::Format(
_(
"Symbol %s contains invalid character '%c'" ),
382 THROW_PARSE_ERROR(
_(
"Invalid library identifier" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
387 symbol->SetLibId(
id );
389 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
391 if( token != T_LEFT )
399 symbol->SetGlobalPower();
402 if( token == T_RIGHT )
405 if( token == T_local )
406 symbol->SetLocalPower();
407 else if( token != T_global )
408 Expecting(
"global or local" );
425 case T_associated_footprints:
433 case T_exclude_from_sim:
434 symbol->SetExcludedFromSim(
parseBool() );
439 symbol->SetExcludedFromBOM( !
parseBool() );
444 symbol->SetExcludedFromBoard( !
parseBool() );
449 symbol->SetExcludedFromPosFiles( !
parseBool() );
453 case T_duplicate_pin_numbers_are_jumpers:
454 symbol->SetDuplicatePinNumbersAreJumpers(
parseBool() );
458 case T_jumper_pin_groups:
461 std::set<wxString> names;
462 bool inGroup =
false;
464 for( token = NextTok(); inGroup || token != T_RIGHT; token = NextTok() )
466 switch(
static_cast<int>( token ) )
470 Expecting(
"list of pin names" );
477 Expecting(
"list of pin names" );
479 names.insert( FromUTF8() );
491 Expecting(
"list of pin names" );
506 if( !IsSymbol( token ) )
509 CurLineNumber(), CurOffset() );
517 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
519 symbol->SetParentName(
name );
528 if( !IsSymbol( token ) )
531 CurLineNumber(), CurOffset() );
539 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
543 error.Printf(
_(
"Invalid symbol unit name prefix %s" ),
name.c_str() );
544 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
549 wxStringTokenizer tokenizer(
name,
"_" );
551 if( tokenizer.CountTokens() != 2 )
553 error.Printf(
_(
"Invalid symbol unit name suffix %s" ),
name.c_str() );
554 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
557 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
559 error.Printf(
_(
"Invalid symbol unit number %s" ),
name.c_str() );
560 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
563 m_unit =
static_cast<int>( tmp );
565 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
567 error.Printf(
_(
"Invalid symbol body style number %s" ),
name.c_str() );
568 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
573 if(
m_unit > symbol->GetUnitCount() )
574 symbol->SetUnitCount(
m_unit,
false );
576 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
578 if( token != T_LEFT )
588 if( IsSymbol( token ) )
589 symbol->GetUnitDisplayNames()[
m_unit] = FromUTF8();
606 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
609 symbol->AddDrawItem( item,
false );
613 Expecting(
"arc, bezier, circle, ellipse, ellipse_arc, pin, polyline, "
614 "rectangle, or text" );
635 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
638 symbol->AddDrawItem( item,
false );
641 case T_embedded_fonts:
643 symbol->SetAreFontsEmbedded(
parseBool() );
648 case T_embedded_files:
651 embeddedFilesParser.SyncLineReaderWith( *
this );
655 embeddedFilesParser.
ParseEmbedded( symbol->GetEmbeddedFiles() );
663 for(
int tok = embeddedFilesParser.NextTok();
665 tok = embeddedFilesParser.NextTok() )
669 else if( tok ==
DSN_RIGHT && --depth < 0 )
674 SyncLineReaderWith( embeddedFilesParser );
679 Expecting(
"pin_names, pin_numbers, arc, bezier, circle, ellipse, ellipse_arc, "
680 "pin, polyline, rectangle, or text" );
684 symbol->GetDrawItems().sort();
687 const std::vector<wxString>* embeddedFonts = symbol->GetEmbeddedFiles()->UpdateFontFiles();
689 symbol->RunOnChildren(
693 textItem->ResolveFont( embeddedFonts );
701 symbol->SetHasDeMorganBodyStyles( symbol->HasLegacyAlternateBodyStyle() );
705 symbol->PruneBodyStyleDrawItems( symbol->GetBodyStyleCount() );
707 symbol->RefreshLibraryTreeCaches();
709 return symbol.release();
727 default: Expecting(
"arc, bezier, circle, ellipse, ellipse_arc, pin, polyline, rectangle, or text" );
741 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
743 return KiROUND( std::clamp( retval, -int_limit, int_limit ) );
751 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
753 return KiROUND( std::clamp( retval, -int_limit, int_limit ) );
760 strokeParser.SyncLineReaderWith( *
this );
763 SyncLineReaderWith( strokeParser );
779 default: Expecting(
"arrow, circle, square, arrow_open, or none" );
783 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
785 if( token != T_LEFT )
810 default: Expecting(
"length, width, or stroke" );
818 wxCHECK_RET( CurTok() == T_fill,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a fill." );
825 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
827 if( token != T_LEFT )
847 default: Expecting(
"none, outline, hatch, reverse_hatch, "
848 "cross_hatch, color or background" );
862 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
869 Expecting(
"type or color" );
876 bool aEnforceMinTextSize )
878 wxCHECK_RET( aText && ( CurTok() == T_effects || CurTok() == T_href ),
879 "Cannot parse " + GetTokenString( CurTok() ) +
" as an EDA_TEXT." );
896 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
898 if( token == T_LEFT )
904 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
906 if( token == T_LEFT )
946 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
957 Expecting(
"face, size, thickness, line_spacing, bold, or italic" );
964 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
973 case T_mirror:
break;
974 default: Expecting(
"left, right, top, bottom, or mirror" );
983 wxString hyperlink = FromUTF8();
988 CurSource(), CurLine(), CurLineNumber(), CurOffset() );
1007 Expecting(
"font, justify, hide or href" );
1018 if( CurTok() != aHeaderType )
1020 THROW_PARSE_ERROR( wxString::Format(
_(
"Cannot parse '%s' as a header." ), GetTokenString( CurTok() ) ),
1021 CurSource(), CurLine(), CurLineNumber(), CurOffset() );
1028 if( tok == T_version )
1042 wxCHECK_RET( CurTok() == T_body_styles,
1043 "Cannot parse " + GetTokenString( CurTok() ) +
" as a body_styles token." );
1045 std::vector<wxString> names;
1047 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1049 if( token == T_demorgan )
1051 aSymbol->SetHasDeMorganBodyStyles(
true );
1054 else if( !IsSymbol( token ) )
1056 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
1060 names.push_back( FromUTF8() );
1063 if( !names.empty() )
1064 aSymbol->SetBodyStyleNames( names );
1070 wxCHECK_RET( CurTok() == T_pin_names,
1071 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_name token." );
1081 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1084 if( token == T_hide )
1086 aSymbol->SetShowPinNames(
false );
1090 if( token != T_LEFT )
1092 Expecting( T_LEFT );
1105 aSymbol->SetShowPinNames( !
parseBool() );
1110 Expecting(
"offset or hide" );
1118 wxCHECK_RET( CurTok() == T_pin_numbers,
1119 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_number token." );
1128 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1131 if( token == T_hide )
1133 aSymbol->SetShowPinNumbers(
false );
1137 if( token != T_LEFT )
1138 Expecting( T_LEFT );
1145 aSymbol->SetShowPinNumbers( !
parseBool() );
1150 Expecting(
"hide" );
1159 wxCHECK_RET( CurTok() == T_associated_footprints,
1160 "Cannot parse " + GetTokenString( CurTok() ) +
" as an associated_footprints token." );
1169 std::vector<ASSOCIATED_FOOTPRINT> list;
1171 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1173 if( token != T_LEFT )
1174 Expecting( T_LEFT );
1178 if( token != T_footprint )
1179 Expecting(
"footprint" );
1183 if( !IsSymbol( token ) )
1184 Expecting(
"footprint library identifier" );
1189 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1191 if( token != T_LEFT )
1192 Expecting( T_LEFT );
1201 if( !IsSymbol( token ) )
1202 Expecting(
"map name" );
1214 list.push_back( std::move( assoc ) );
1217 aSymbol->SetAssociatedFootprints( std::move( list ) );
1223 wxCHECK_RET( CurTok() == T_pin_maps,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_maps token." );
1234 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1236 if( token != T_LEFT )
1237 Expecting( T_LEFT );
1241 if( token != T_pin_map )
1242 Expecting(
"pin_map" );
1247 aSymbol->SetPinMaps( set );
1253 wxCHECK_MSG( CurTok() == T_pin_map,
PIN_MAP(),
1254 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_map token." );
1256 T token = NextTok();
1258 if( !IsSymbol( token ) )
1259 Expecting(
"pin map name" );
1263 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1265 if( token != T_LEFT )
1266 Expecting( T_LEFT );
1270 if( token != T_entry )
1271 Expecting(
"entry" );
1275 if( !IsSymbol( token ) )
1276 Expecting(
"pin number" );
1278 wxString pinNumber = FromUTF8();
1282 if( !IsSymbol( token ) )
1283 Expecting(
"pad number" );
1285 map.
SetEntry( pinNumber, FromUTF8() );
1297 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_map_override token." );
1309 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1311 if( token != T_LEFT )
1312 Expecting( T_LEFT );
1327 default: Expecting(
"library_default, named_map, identity, or delegate" );
1336 if( !IsSymbol( token ) )
1337 Expecting(
"map name" );
1339 override.m_ActiveMapName = FromUTF8();
1347 if( !IsSymbol( token ) )
1348 Expecting(
"pin number" );
1350 wxString pinNumber = FromUTF8();
1354 if( !IsSymbol( token ) )
1355 Expecting(
"pad number" );
1357 override.m_Edits.push_back( { pinNumber, FromUTF8() } );
1362 default: Expecting(
"mode, map, or edit" );
1372 wxCHECK_MSG( CurTok() == T_symbol_override,
LIB_ID(),
1373 "Cannot parse " + GetTokenString( CurTok() ) +
" as a symbol_override token." );
1375 T token = NextTok();
1377 if( !IsSymbol( token ) )
1378 Expecting(
"symbol LIB_ID" );
1380 wxString
name = FromUTF8();
1386 if(
static_cast<int>(
name.size() ) > bad_pos )
1388 wxString msg = wxString::Format(
_(
"Variant symbol override contains invalid character '%c'" ),
1394 THROW_PARSE_ERROR(
_(
"Invalid variant symbol override LIB_ID" ), CurSource(), CurLine(),
1395 CurLineNumber(), CurOffset() );
1405 wxCHECK_MSG( CurTok() == T_property,
nullptr,
1406 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a property." ) );
1407 wxCHECK( aSymbol,
nullptr );
1412 bool isPrivate =
false;
1413 bool isVisible =
true;
1415 T token = NextTok();
1417 if( token == T_private )
1423 if( !IsSymbol( token ) )
1424 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
1428 if(
name.IsEmpty() )
1429 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
1441 auto field = std::make_unique<SCH_FIELD>( aSymbol.get(), fieldId,
name );
1442 field->SetPrivate( isPrivate );
1443 field->SetVisible( isVisible );
1447 if( !IsSymbol( token ) )
1448 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
1453 value = wxEmptyString;
1457 field->SetText( value );
1459 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1461 if( token != T_LEFT )
1462 Expecting( T_LEFT );
1474 field->SetPosition(
parseXY(
true ) );
1492 field->SetNameShown( show );
1496 case T_do_not_autoplace:
1499 field->SetCanAutoplace( !doNotAutoplace );
1503 case T_custom_property:
1508 Expecting(
"id, at, hide, show_name, do_not_autoplace, effects, or custom_property" );
1514 if( field->IsMandatory() )
1516 existingField = aSymbol->GetField( field->GetId() );
1518 *existingField = *field;
1519 return existingField;
1521 else if(
name ==
"ki_keywords" )
1524 aSymbol->SetKeyWords( value );
1528 else if(
name ==
"ki_description" )
1530 aSymbol->SetDescription( value );
1533 else if(
name ==
"ki_fp_filters" )
1537 wxStringTokenizer tokenizer( value,
" \t\r\n", wxTOKEN_STRTOK );
1539 while( tokenizer.HasMoreTokens() )
1541 wxString curr_token =
UnescapeString( tokenizer.GetNextToken() );
1545 aSymbol->SetFPFilters(
filters );
1548 else if(
name ==
"ki_locked" )
1552 aSymbol->LockUnits(
true );
1558 existingField = aSymbol->GetField( field->GetUntranslatedName() );
1566 wxString base_name = field->GetUntranslatedName();
1569 for(
int ii = 1; ii < 10 && existingField; ii++ )
1571 wxString newname = base_name;
1572 newname <<
'_' << ii;
1574 existingField = aSymbol->GetField( newname );
1576 if( !existingField )
1577 field->SetName( newname );
1581 if( !existingField )
1583 aSymbol->AddDrawItem( field.get(),
false );
1584 return field.release();
1597 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
1598 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
1604 bool hasMidPoint =
false;
1612 bool hasAngles =
false;
1621 if( token == T_private )
1623 arc->SetPrivate(
true );
1627 for( ; token != T_RIGHT; token = NextTok() )
1629 if( token != T_LEFT )
1630 Expecting( T_LEFT );
1653 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1655 if( token != T_LEFT )
1656 Expecting( T_LEFT );
1684 Expecting(
"at, length, or angles" );
1692 arc->SetStroke( stroke );
1698 arc->SetFillColor( fill.
m_Color );
1705 arc->SetStartEnding( ending );
1713 arc->SetEndEnding( ending );
1717 case T_custom_property:
1722 Expecting(
"start, mid, end, radius, stroke, fill, start_shape, end_shape, or custom_property" );
1728 arc->SetArcOrLine( startPoint, midPoint, endPoint );
1739 EDA_ANGLE arc_start, arc_end, arc_angle;
1740 arc->CalcArcAngles( arc_start, arc_end );
1741 arc_angle = arc_end - arc_start;
1746 arc->SetStart( endPoint );
1747 arc->SetEnd( startPoint );
1749 arc->SetCenter( new_center );
1754 arc->SetCenter( new_center );
1758 else if( hasAngles )
1760 arc->SetCenter(
center );
1766 arc->SetStart( endPoint );
1767 arc->SetEnd( startPoint );
1771 EDA_ANGLE arc_start, arc_end, arc_angle;
1772 arc->CalcArcAngles( arc_start, arc_end );
1773 arc_angle = arc_end - arc_start;
1779 arc->SetStart( startPoint );
1780 arc->SetEnd( endPoint );
1788 arc->SetStart( startPoint );
1789 arc->SetEnd( endPoint );
1793 arc->SetCenter( new_center );
1799 wxFAIL_MSG(
"Setting arc without either midpoint or angles not implemented." );
1802 return arc.release();
1808 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
1809 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
1817 bezier->SetUnit(
m_unit );
1822 if( token == T_private )
1824 bezier->SetPrivate(
true );
1828 for( ; token != T_RIGHT; token = NextTok() )
1830 if( token != T_LEFT )
1831 Expecting( T_LEFT );
1841 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
1843 if( token != T_LEFT )
1844 Expecting( T_LEFT );
1853 case 0: bezier->SetStart(
parseXY(
true ) );
break;
1854 case 1: bezier->SetBezierC1(
parseXY(
true ) );
break;
1855 case 2: bezier->SetBezierC2(
parseXY(
true ) );
break;
1856 case 3: bezier->SetEnd(
parseXY(
true ) );
break;
1857 default: Unexpected(
"control point" );
break;
1867 bezier->SetStroke( stroke );
1873 bezier->SetFillColor( fill.
m_Color );
1880 bezier->SetStartEnding( ending );
1888 bezier->SetEndEnding( ending );
1892 case T_custom_property:
1897 Expecting(
"pts, stroke, fill, start_shape, end_shape, or custom_property" );
1901 bezier->RebuildBezierToSegmentsPointsList(
m_maxError );
1903 return bezier.release();
1909 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
1910 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
1925 if( token == T_private )
1927 circle->SetPrivate(
true );
1931 for( ; token != T_RIGHT; token = NextTok() )
1933 if( token != T_LEFT )
1934 Expecting( T_LEFT );
1952 circle->SetStroke( stroke );
1961 case T_custom_property:
1966 Expecting(
"center, radius, stroke, fill, or custom_property" );
1979 wxCHECK_MSG( CurTok() == T_ellipse,
nullptr,
1980 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an ellipse." ) );
1983 ellipse->SetUnit(
m_unit );
1986 T token = NextTok();
1988 if( token == T_private )
1990 ellipse->SetPrivate(
true );
1995 return ellipse.release();
2001 wxCHECK_MSG( CurTok() == T_ellipse_arc,
nullptr,
2002 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an elliptical arc." ) );
2008 T token = NextTok();
2010 if( token == T_private )
2012 arc->SetPrivate(
true );
2017 return arc.release();
2043 Expecting(
"input, output, bidirectional, tri_state, passive, unspecified, power_in, "
2044 "power_out, open_collector, open_emitter, free, or no_connect" );
2065 Expecting(
"line, inverted, clock, inverted_clock, input_low, clock_low, output_low, "
2066 "edge_clock_high, or non_logic" );
2071 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
2072 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a pin token." ) );
2075 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>(
nullptr );
2082 pin->SetType( parseType( token ) );
2086 pin->SetShape( parseShape( token ) );
2088 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2091 if( token == T_hide )
2093 pin->SetVisible(
false );
2097 if( token != T_LEFT )
2098 Expecting( T_LEFT );
2107 switch(
parseInt(
"pin orientation" ) )
2113 default: Expecting(
"0, 90, 180, or 270" );
2132 if( !IsSymbol( token ) )
2133 THROW_PARSE_ERROR(
_(
"Invalid pin name" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
2136 pin->SetName( wxEmptyString );
2140 pin->SetName( FromUTF8() );
2144 if( token != T_RIGHT )
2148 if( token == T_effects )
2155 pin->SetNameTextSize(
text.GetTextHeight() );
2160 Expecting(
"effects" );
2169 if( !IsSymbol( token ) )
2170 THROW_PARSE_ERROR(
_(
"Invalid pin number" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
2173 pin->SetNumber( wxEmptyString );
2177 pin->SetNumber( FromUTF8() );
2181 if( token != T_RIGHT )
2185 if( token == T_effects )
2192 pin->SetNumberTextSize(
text.GetTextHeight() );
2197 Expecting(
"effects" );
2209 if( !IsSymbol( token ) )
2212 CurLineNumber(), CurOffset() );
2218 alt.
m_Type = parseType( token );
2221 alt.
m_Shape = parseShape( token );
2223 pin->GetAlternates()[ alt.
m_Name ] = alt;
2229 case T_custom_property:
2234 Expecting(
"at, name, number, hide, length, alternate, or custom_property" );
2238 return pin.release();
2244 wxCHECK_MSG( CurTok() == T_polyline,
nullptr,
2245 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a poly." ) );
2257 if( token == T_private )
2259 poly->SetPrivate(
true );
2263 for( ; token != T_RIGHT; token = NextTok() )
2265 if( token != T_LEFT )
2266 Expecting( T_LEFT );
2273 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2275 if( token != T_LEFT )
2276 Expecting( T_LEFT );
2283 poly->AddPoint(
parseXY(
true ) );
2292 poly->SetStroke( stroke );
2298 poly->SetFillColor( fill.
m_Color );
2305 poly->SetStartEnding( ending );
2313 poly->SetEndEnding( ending );
2317 default: Expecting(
"pts, stroke, fill, start_shape, or end_shape" );
2321 if( poly->GetFillMode() !=
FILL_T::NO_FILL && poly->GetPolyShape().OutlineCount() > 0 )
2331 return poly.release();
2337 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
2338 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
2345 rectangle->SetUnit(
m_unit );
2350 if( token == T_private )
2352 rectangle->SetPrivate(
true );
2356 for( ; token != T_RIGHT; token = NextTok() )
2358 if( token != T_LEFT )
2359 Expecting( T_LEFT );
2366 rectangle->SetPosition(
parseXY(
true ) );
2371 rectangle->SetEnd(
parseXY(
true ) );
2382 rectangle->SetStroke( stroke );
2388 rectangle->SetFillColor( fill.
m_Color );
2392 Expecting(
"start, end, stroke, or fill" );
2396 return rectangle.release();
2402 wxCHECK_MSG( CurTok() == T_text,
nullptr,
2403 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text token." ) );
2406 std::unique_ptr<SCH_TEXT>
text = std::make_unique<SCH_TEXT>();
2413 if( token == T_private )
2415 text->SetPrivate(
true );
2419 if( !IsSymbol( token ) )
2420 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
2422 text->SetText( FromUTF8() );
2424 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2426 if( token != T_LEFT )
2427 Expecting( T_LEFT );
2444 case T_custom_property:
2449 Expecting(
"at, effects, or custom_property" );
2454 if( !
text->IsVisible() )
2457 return text.release();
2463 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
2464 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
2476 bool foundEnd =
false;
2477 bool foundSize =
false;
2478 bool foundMargins =
false;
2480 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>(
LAYER_DEVICE );
2482 textBox->SetUnit(
m_unit );
2486 if( token == T_private )
2488 textBox->SetPrivate(
true );
2492 if( !IsSymbol( token ) )
2493 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
2495 textBox->SetText( FromUTF8() );
2497 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2499 if( token != T_LEFT )
2500 Expecting( T_LEFT );
2531 textBox->SetStroke( stroke );
2537 textBox->SetFillColor( fill.
m_Color );
2542 textBox->SetMarginLeft(
left );
2543 textBox->SetMarginTop(
top );
2544 textBox->SetMarginRight(
right );
2545 textBox->SetMarginBottom( bottom );
2546 foundMargins =
true;
2554 case T_custom_property:
2559 Expecting(
"at, size, stroke, fill, effects, or custom_property" );
2563 textBox->SetPosition( pos );
2566 textBox->SetEnd(
end );
2567 else if( foundSize )
2568 textBox->SetEnd( pos + size );
2570 Expecting(
"size" );
2574 int margin = textBox->GetLegacyTextMargin();
2575 textBox->SetMarginLeft( margin );
2576 textBox->SetMarginTop( margin );
2577 textBox->SetMarginRight( margin );
2578 textBox->SetMarginBottom( margin );
2581 return textBox.release();
2587 wxCHECK_RET( ( CurTok() == T_page &&
m_requiredVersion <= 20200506 ) || CurTok() == T_paper,
2588 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a PAGE_INFO." ) );
2594 wxString pageType = FromUTF8();
2596 if( !aPageInfo.
SetType( pageType ) )
2597 THROW_PARSE_ERROR(
_(
"Invalid page type" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
2622 if( token == T_portrait )
2627 else if( token != T_RIGHT )
2629 Expecting(
"portrait" );
2636 wxCHECK_RET( CurTok() == T_title_block,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a TITLE_BLOCK." );
2640 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2642 if( token != T_LEFT )
2643 Expecting( T_LEFT );
2651 aTitleBlock.
SetTitle( FromUTF8() );
2656 aTitleBlock.
SetDate( FromUTF8() );
2671 int commentNumber =
parseInt(
"comment" );
2673 switch( commentNumber )
2722 CurLine(), CurLineNumber(), CurOffset() );
2729 Expecting(
"title, date, rev, company, or comment" );
2739 wxCHECK_MSG( CurTok() == T_property,
nullptr,
2740 "Cannot parse " + GetTokenString( CurTok() ) +
" as a property token." );
2742 bool is_private =
false;
2744 T token = NextTok();
2746 if( token == T_private )
2752 if( !IsSymbol( token ) )
2753 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
2755 wxString
name = FromUTF8();
2757 if(
name.IsEmpty() )
2758 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
2765 name = wxT(
"Netclass" );
2769 if( !IsSymbol( token ) )
2770 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
2776 value = wxEmptyString;
2808 if(
name.CmpNoCase( wxT(
"Sheet name" ) ) == 0 )
2810 else if(
name.CmpNoCase( wxT(
"Sheet file" ) ) == 0 )
2825 if(
name.CmpNoCase( wxT(
"Intersheet References" ) ) == 0 )
2829 std::unique_ptr<SCH_FIELD> field = std::make_unique<SCH_FIELD>( aParent, fieldId,
name );
2830 field->SetText( value );
2833 field->SetPrivate( is_private );
2835 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2837 if( token != T_LEFT )
2838 Expecting( T_LEFT );
2850 field->SetPosition(
parseXY() );
2867 field->SetNameShown( show );
2871 case T_do_not_autoplace:
2874 field->SetCanAutoplace( !doNotAutoplace );
2878 case T_custom_property:
2883 Expecting(
"id, at, hide, show_name, do_not_autoplace or effects" );
2887 return field.release();
2893 wxCHECK_MSG( aSheet !=
nullptr,
nullptr,
"" );
2894 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a sheet pin token." );
2896 T token = NextTok();
2898 if( !IsSymbol( token ) )
2900 THROW_PARSE_ERROR(
_(
"Invalid sheet pin name" ), CurSource(), CurLine(), CurLineNumber(),
2904 wxString
name = FromUTF8();
2908 auto sheetPin = std::make_unique<SCH_SHEET_PIN>( aSheet,
VECTOR2I( 0, 0 ),
name );
2920 Expecting(
"input, output, bidirectional, tri_state, or passive" );
2923 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2925 if( token != T_LEFT )
2926 Expecting( T_LEFT );
2934 sheetPin->SetPosition(
parseXY() );
2936 double angle =
parseDouble(
"sheet pin angle (side)" );
2940 else if( angle == 90.0 )
2942 else if( angle == 180.0 )
2944 else if( angle == 270.0 )
2947 Expecting(
"0, 90, 180, or 270" );
2964 Expecting(
"at, uuid or effects" );
2968 return sheetPin.release();
2974 wxCHECK_RET( CurTok() == T_sheet_instances,
2975 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
2976 wxCHECK( aScreen, );
2980 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2982 if( token != T_LEFT )
2983 Expecting( T_LEFT );
3001 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3003 if( token != T_LEFT )
3004 Expecting( T_LEFT );
3008 std::vector<wxString> whitespaces = { wxT(
"\r" ), wxT(
"\n" ), wxT(
"\t" ),
3011 size_t numReplacements = 0;
3029 for(
const wxString& ch : whitespaces )
3030 numReplacements += instance.
m_PageNumber.Replace( ch, wxEmptyString );
3035 if( numReplacements > 0 )
3042 Expecting(
"path or page" );
3047 && ( instance.
m_Path.empty() ) )
3063 Expecting(
"path" );
3071 wxCHECK_RET( CurTok() == T_symbol_instances,
3072 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
3073 wxCHECK( aScreen, );
3078 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3080 if( token != T_LEFT )
3081 Expecting( T_LEFT );
3098 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3100 if( token != T_LEFT )
3101 Expecting( T_LEFT );
3122 instance.
m_Value = wxEmptyString;
3124 instance.
m_Value = FromUTF8();
3141 Expecting(
"path, unit, value or footprint" );
3150 Expecting(
"path" );
3159 wxCHECK( aSheet !=
nullptr, );
3163 wxCHECK( screen !=
nullptr, );
3166 m_maxError = schematic->Settings().m_MaxError;
3168 if( aIsCopyableOnly )
3171 bool fileHasUuid =
false;
3184 if( !aIsCopyableOnly )
3189 if( CurTok() != T_kicad_sch )
3190 Expecting(
"kicad_sch" );
3209 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3211 if( aIsCopyableOnly && token == T_EOF )
3214 if( token != T_LEFT )
3215 Expecting( T_LEFT );
3249 case T_generator_version:
3275 if( aIsCopyableOnly )
3276 Unexpected( T_paper );
3286 if( aIsCopyableOnly )
3287 Unexpected( T_page );
3291 NeedSYMBOLorNUMBER();
3292 NeedSYMBOLorNUMBER();
3299 if( aIsCopyableOnly )
3300 Unexpected( T_title_block );
3314 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3316 if( token != T_LEFT )
3317 Expecting( T_LEFT );
3329 Expecting(
"symbol" );
3386 THROW_PARSE_ERROR(
_(
"Schematic polyline has too few points" ), CurSource(), CurLine(),
3387 CurLineNumber(), CurOffset() );
3443 case T_netclass_flag:
3448 case T_global_label:
3449 case T_hierarchical_label:
3450 case T_directive_label:
3466 case T_sheet_instances:
3470 case T_symbol_instances:
3475 if( aIsCopyableOnly )
3476 Unexpected( T_bus_alias );
3481 case T_embedded_fonts:
3486 THROW_PARSE_ERROR(
_(
"No schematic object" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
3500 case T_embedded_files:
3506 CurLineNumber(), CurOffset() );
3509 embeddedFilesParser.SyncLineReaderWith( *
this );
3521 for(
int tok = embeddedFilesParser.NextTok();
3523 tok = embeddedFilesParser.NextTok() )
3527 else if( tok ==
DSN_RIGHT && --depth < 0 )
3532 SyncLineReaderWith( embeddedFilesParser );
3538 Expecting(
"arc, bezier, bitmap, bus, bus_alias, bus_entry, circle, class_label, "
3539 "directive_label, ellipse, ellipse_arc, embedded_fonts, embedded_files, "
3540 "global_label, hierarchical_label, image, junction, lib_symbols, "
3541 "netclass_flag, no_connect, polyline, rectangle, rule_area, sheet, "
3542 "sheet_instances, signal, symbol, symbol_instances, table, text, "
3543 "text_box, title_block, uuid, wire" );
3563 THROW_PARSE_ERROR(
_(
"No schematic object" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
3567 std::vector<std::string> fontNames;
3568 Fontconfig()->ListFonts( fontNames, std::string(
Pgm().GetLanguageTag().utf8_str() ),
3578 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
3579 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
3584 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
3586 std::set<int> fieldIDsRead;
3591 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3593 if( token != T_LEFT )
3594 Expecting( T_LEFT );
3606 if( !IsSymbol( token ) )
3609 CurLineNumber(), CurOffset() );
3612 libName = FromUTF8();
3616 libName.Replace(
"{slash}",
"/" );
3626 if( !IsSymbol( token ) && token != T_NUMBER )
3627 Expecting(
"symbol|number" );
3630 wxString
name = FromUTF8();
3634 name.Replace(
"{slash}",
"/" );
3640 if(
static_cast<int>(
name.size() ) > bad_pos )
3642 wxString msg = wxString::Format(
_(
"Symbol %s contains invalid character '%c'" ),
3650 CurLineNumber(), CurOffset() );
3653 symbol->SetLibId( libId );
3659 symbol->SetPosition(
parseXY() );
3661 switch(
static_cast<int>(
parseDouble(
"symbol orientation" ) ) )
3664 case 90: transform =
TRANSFORM( 0, 1, -1, 0 );
break;
3665 case 180: transform =
TRANSFORM( -1, 0, 0, -1 );
break;
3666 case 270: transform =
TRANSFORM( 0, -1, 1, 0 );
break;
3667 default: Expecting(
"0, 90, 180, or 270" );
3670 symbol->SetTransform( transform );
3679 else if( token == T_y )
3682 Expecting(
"x or y" );
3688 symbol->SetUnit(
parseInt(
"symbol unit" ) );
3694 symbol->SetBodyStyle(
parseInt(
"symbol body style" ) );
3698 case T_exclude_from_sim:
3699 symbol->SetExcludedFromSim(
parseBool() );
3704 symbol->SetExcludedFromBOM( !
parseBool() );
3709 symbol->SetExcludedFromBoard( !
parseBool() );
3713 case T_in_pos_files:
3714 symbol->SetExcludedFromPosFiles( !
parseBool() );
3723 case T_pin_map_override:
3738 if( !IsSymbol( t ) )
3739 Expecting(
"default, block or force" );
3741 wxString mode = FromUTF8();
3743 if( mode.IsSameAs( wxT(
"default"),
false ) )
3745 else if( mode.IsSameAs( wxT(
"block"),
false ) )
3747 else if( mode.IsSameAs( wxT(
"force"),
false ) )
3750 Expecting(
"default, block or force" );
3756 case T_fields_autoplaced:
3768 case T_default_instance:
3772 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3774 if( token != T_LEFT )
3775 Expecting( T_LEFT );
3796 symbol->SetValueFieldText( wxEmptyString );
3798 symbol->SetValueFieldText( FromUTF8() );
3807 symbol->SetFootprintFieldText( wxEmptyString );
3809 symbol->SetFootprintFieldText( FromUTF8() );
3815 Expecting(
"reference, unit, value or footprint" );
3824 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3826 if( token != T_LEFT )
3827 Expecting( T_LEFT );
3831 if( token != T_project )
3832 Expecting(
"project" );
3836 wxString projectName = FromUTF8();
3838 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3840 if( token != T_LEFT )
3841 Expecting( T_LEFT );
3845 if( token != T_path )
3846 Expecting(
"path" );
3855 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3857 if( token != T_LEFT )
3858 Expecting( T_LEFT );
3879 symbol->SetValueFieldText( wxEmptyString );
3881 symbol->SetValueFieldText( FromUTF8() );
3890 symbol->SetFootprintFieldText( wxEmptyString );
3892 symbol->SetFootprintFieldText( FromUTF8() );
3903 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3905 if( token != T_LEFT )
3906 Expecting( T_LEFT );
3914 variant.
m_Name = FromUTF8();
3923 case T_exclude_from_sim:
3945 case T_in_pos_files:
3953 wxString fieldValue;
3955 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3957 if( token != T_LEFT )
3958 Expecting( T_LEFT );
3966 fieldName = FromUTF8();
3972 fieldValue = FromUTF8();
3977 Expecting(
"name or value" );
3981 variant.
m_Fields[fieldName] = fieldValue;
3990 Expecting(
"dnp, exclude_from_sim, field, in_bom, in_pos_files, name, "
3991 "on_board, pin_map_override, or symbol_override" );
4001 Expecting(
"reference, unit, value, footprint, or variant" );
4005 symbol->AddHierarchicalReference( instance );
4021 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"0" ) );
4029 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"N" ) );
4037 existing = symbol->GetField( field->
GetId() );
4039 existing = symbol->GetField( field->
GetName() );
4045 wxString base_name = field->
GetName();
4048 for(
int ii = 1; ii < 10 && existing; ii++ )
4050 wxString newname = base_name;
4051 newname <<
'_' << ii;
4053 existing = symbol->GetField( newname );
4063 symbol->AddField( *field );
4066 symbol->UpdatePrefix();
4079 number = FromUTF8();
4081 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4083 if( token != T_LEFT )
4084 Expecting( T_LEFT );
4108 Expecting(
"alternate or uuid" );
4112 symbol->GetRawPins().emplace_back( std::make_unique<SCH_PIN>( symbol.get(), number, alt, uuid ) );
4116 case T_custom_property:
4121 Expecting(
"lib_id, lib_name, at, mirror, uuid, exclude_from_sim, on_board, in_bom, dnp, passthrough, "
4122 "default_instance, property, pin, instances, or custom_property" );
4126 if( !libName.IsEmpty() && ( symbol->GetLibId().Format().wx_str() != libName ) )
4127 symbol->SetSchSymbolLibraryName( libName );
4130 symbol->ClearFlags();
4132 return symbol.release();
4138 wxCHECK_MSG( CurTok() == T_image,
nullptr,
4139 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an image." ) );
4142 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>();
4145 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4147 if( token != T_LEFT )
4148 Expecting( T_LEFT );
4155 bitmap->SetPosition(
parseXY() );
4191 data.reserve( 1 << 17 );
4193 while( token != T_RIGHT )
4195 if( !IsSymbol( token ) )
4196 Expecting(
"base64 image data" );
4202 wxMemoryBuffer buffer = wxBase64Decode( data );
4215 case T_custom_property:
4219 default: Expecting(
"at, rotate, opacity, scale, uuid, data, locked, or custom_property" );
4237 int legacyPPI =
image.GetLegacyPPI();
4239 if( legacyPPI > 0 &&
image.GetPPI() != legacyPPI )
4243 return bitmap.release();
4249 wxCHECK_MSG( CurTok() == T_sheet,
nullptr,
4250 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a sheet." ) );
4256 std::vector<SCH_FIELD> fields;
4257 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>();
4258 std::set<int> fieldIDsRead;
4263 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4265 if( token != T_LEFT )
4266 Expecting( T_LEFT );
4273 sheet->SetPosition(
parseXY() );
4282 sheet->SetSize( size );
4287 case T_exclude_from_sim:
4288 sheet->SetExcludedFromSim(
parseBool() );
4293 sheet->SetExcludedFromBOM( !
parseBool() );
4298 sheet->SetExcludedFromBoard( !
parseBool() );
4312 case T_fields_autoplaced:
4320 sheet->SetBorderWidth( stroke.
GetWidth() );
4321 sheet->SetBorderColor( stroke.
GetColor() );
4326 sheet->SetBackgroundColor( fill.
m_Color );
4343 if( fields.empty() )
4349 fields.emplace_back( *field );
4360 std::vector<SCH_SHEET_INSTANCE> instances;
4362 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4364 if( token != T_LEFT )
4365 Expecting( T_LEFT );
4369 if( token != T_project )
4370 Expecting(
"project" );
4374 wxString projectName = FromUTF8();
4376 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4378 if( token != T_LEFT )
4379 Expecting( T_LEFT );
4383 if( token != T_path )
4384 Expecting(
"path" );
4393 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4395 if( token != T_LEFT )
4396 Expecting( T_LEFT );
4416 static std::vector<wxString> whitespaces =
4422 for( wxString ch : whitespaces )
4435 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4437 if( token != T_LEFT )
4438 Expecting( T_LEFT );
4446 variant.
m_Name = FromUTF8();
4455 case T_exclude_from_sim:
4477 case T_in_pos_files:
4485 wxString fieldValue;
4487 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4489 if( token != T_LEFT )
4490 Expecting( T_LEFT );
4498 fieldName = FromUTF8();
4504 fieldValue = FromUTF8();
4509 Expecting(
"name or value" );
4513 variant.
m_Fields[fieldName] = fieldValue;
4518 Expecting(
"dnp, exclude_from_sim, field, in_bom, in_pos_files, name, or on_board" );
4528 Expecting(
"page or variant" );
4532 instances.emplace_back( instance );
4536 sheet->setInstances( instances );
4540 case T_custom_property:
4545 Expecting(
"at, size, stroke, background, instances, uuid, property, pin, or custom_property" );
4549 sheet->SetFields( fields );
4554 CurLineNumber(), CurOffset() );
4560 CurLineNumber(), CurOffset() );
4563 return sheet.release();
4569 wxCHECK_MSG( CurTok() == T_junction,
nullptr,
4570 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a junction." ) );
4573 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
4575 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4577 if( token != T_LEFT )
4578 Expecting( T_LEFT );
4585 junction->SetPosition(
parseXY() );
4601 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
4603 junction->SetColor( color );
4619 case T_custom_property:
4624 Expecting(
"at, diameter, color, uuid, locked, or custom_property" );
4628 return junction.release();
4634 wxCHECK_MSG( CurTok() == T_no_connect,
nullptr,
4635 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a no connect." ) );
4638 std::unique_ptr<SCH_NO_CONNECT> no_connect = std::make_unique<SCH_NO_CONNECT>();
4640 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4642 if( token != T_LEFT )
4643 Expecting( T_LEFT );
4650 no_connect->SetPosition(
parseXY() );
4665 case T_custom_property:
4670 Expecting(
"at, uuid, locked, or custom_property" );
4674 return no_connect.release();
4680 wxCHECK_MSG( CurTok() == T_bus_entry,
nullptr,
4681 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus entry." ) );
4685 std::unique_ptr<SCH_BUS_WIRE_ENTRY> busEntry = std::make_unique<SCH_BUS_WIRE_ENTRY>();
4687 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4689 if( token != T_LEFT )
4690 Expecting( T_LEFT );
4697 busEntry->SetPosition(
parseXY() );
4707 busEntry->SetSize( size );
4714 busEntry->SetStroke( stroke );
4728 case T_custom_property:
4733 Expecting(
"at, size, stroke, uuid, locked, or custom_property" );
4737 return busEntry.release();
4759 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4761 if( token != T_LEFT )
4762 Expecting( T_LEFT );
4769 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4771 if( token != T_LEFT )
4772 Expecting( T_LEFT );
4779 polyline->AddPoint(
parseXY() );
4792 polyline->SetStroke( stroke );
4798 polyline->SetFillColor( fill.
m_Color );
4806 polyline->SetStartEnding( ending );
4814 polyline->SetEndEnding( ending );
4829 case T_custom_property:
4834 Expecting(
"pts, stroke, fill, start_shape, end_shape, uuid, locked, or custom_property" );
4838 if( polyline->GetFillMode() !=
FILL_T::NO_FILL && polyline->GetPolyShape().OutlineCount() > 0 )
4848 return polyline.release();
4867 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a line." );
4870 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>(
VECTOR2I(), layer );
4872 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4874 if( token != T_LEFT )
4875 Expecting( T_LEFT );
4888 line->SetStartPoint(
parseXY() );
4896 line->SetEndPoint(
parseXY() );
4903 line->SetStroke( stroke );
4910 line->SetStartEnding( ending );
4918 line->SetEndEnding( ending );
4933 case T_custom_property:
4938 Expecting(
"pts, stroke, start_shape, end_shape, uuid, locked, or custom_property" );
4942 return line.release();
4948 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
4949 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
4957 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>(
SHAPE_T::ARC );
4959 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4961 if( token != T_LEFT )
4962 Expecting( T_LEFT );
4985 arc->SetStroke( stroke );
4991 arc->SetFillColor( fill.
m_Color );
4999 arc->SetStartEnding( ending );
5007 arc->SetEndEnding( ending );
5022 case T_custom_property:
5027 Expecting(
"start, mid, end, stroke, fill, start_shape, end_shape, uuid, locked, or custom_property" );
5031 arc->SetArcOrLine( startPoint, midPoint, endPoint );
5033 return arc.release();
5039 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
5040 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
5049 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5051 if( token != T_LEFT )
5052 Expecting( T_LEFT );
5070 circle->SetStroke( stroke );
5091 case T_custom_property:
5096 Expecting(
"center, radius, stroke, fill, uuid, locked, or custom_property" );
5109 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
5110 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
5115 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>(
SHAPE_T::RECTANGLE );
5117 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5119 if( token != T_LEFT )
5120 Expecting( T_LEFT );
5127 rectangle->SetPosition(
parseXY() );
5132 rectangle->SetEnd(
parseXY() );
5143 rectangle->SetStroke( stroke );
5149 rectangle->SetFillColor( fill.
m_Color );
5164 case T_custom_property:
5169 Expecting(
"start, end, radius, stroke, fill, uuid, locked, or custom_property" );
5173 return rectangle.release();
5179 wxCHECK_MSG( CurTok() == T_rule_area,
nullptr,
5180 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rule area." ) );
5185 std::unique_ptr<SCH_RULE_AREA> ruleArea = std::make_unique<SCH_RULE_AREA>();
5187 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5189 if( token != T_LEFT )
5190 Expecting( T_LEFT );
5204 ruleArea->SetPolyShape( sch_rule_poly );
5206 ruleArea->SetStroke( poly->GetStroke() );
5207 ruleArea->SetFillMode( poly->GetFillMode() );
5208 ruleArea->SetFillColor( poly->GetFillColor() );
5211 const_cast<KIID&
>( ruleArea->m_Uuid ) = poly->m_Uuid;
5215 case T_exclude_from_sim:
5216 ruleArea->SetExcludedFromSim(
parseBool() );
5221 ruleArea->SetExcludedFromBOM( !
parseBool() );
5226 ruleArea->SetExcludedFromBoard( !
parseBool() );
5240 case T_custom_property:
5245 Expecting(
"polyline, exclude_from_sim, on_board, in_bom, dnp, locked, or custom_property" );
5249 return ruleArea.release();
5255 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
5256 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
5261 std::unique_ptr<SCH_SHAPE> bezier = std::make_unique<SCH_SHAPE>(
SHAPE_T::BEZIER );
5263 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5265 if( token != T_LEFT )
5266 Expecting( T_LEFT );
5276 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
5278 if( token != T_LEFT )
5279 Expecting( T_LEFT );
5288 case 0: bezier->SetStart(
parseXY() );
break;
5289 case 1: bezier->SetBezierC1(
parseXY() );
break;
5290 case 2: bezier->SetBezierC2(
parseXY() );
break;
5291 case 3: bezier->SetEnd(
parseXY() );
break;
5292 default: Unexpected(
"control point" );
break;
5302 bezier->SetStroke( stroke );
5308 bezier->SetFillColor( fill.
m_Color );
5316 bezier->SetStartEnding( ending );
5324 bezier->SetEndEnding( ending );
5339 case T_custom_property:
5344 Expecting(
"pts, stroke, fill, start_shape, end_shape, uuid, locked, or custom_property" );
5348 bezier->RebuildBezierToSegmentsPointsList(
m_maxError );
5350 return bezier.release();
5355 TSCHEMATIC_T::T aFirstTok )
5361 int majorRadius = 1;
5362 int minorRadius = 1;
5369 for(
T token = aFirstTok; token != T_RIGHT; token = NextTok() )
5371 if( token != T_LEFT )
5372 Expecting( T_LEFT );
5384 case T_major_radius:
5389 case T_minor_radius:
5394 case T_rotation_angle:
5401 Expecting(
"start_angle only valid inside ellipse_arc" );
5408 Expecting(
"end_angle only valid inside ellipse_arc" );
5428 Expecting(
"uuid only valid in schematic context" );
5436 Expecting(
"locked only valid in schematic context" );
5441 case T_custom_property:
5446 Expecting(
"center, major_radius, minor_radius, rotation_angle, start_angle, end_angle, "
5447 "stroke, fill, uuid, locked, or custom_property" );
5466 wxCHECK_MSG( CurTok() == T_ellipse,
nullptr,
5467 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an ellipse." ) );
5471 return ellipse.release();
5477 wxCHECK_MSG( CurTok() == T_ellipse_arc,
nullptr,
5478 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an elliptical arc." ) );
5482 return arc.release();
5489 std::unique_ptr<SCH_TEXT>
text;
5493 case T_text:
text = std::make_unique<SCH_TEXT>();
break;
5494 case T_label:
text = std::make_unique<SCH_LABEL>();
break;
5495 case T_global_label:
text = std::make_unique<SCH_GLOBALLABEL>();
break;
5496 case T_hierarchical_label:
text = std::make_unique<SCH_HIERLABEL>();
break;
5497 case T_netclass_flag:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
5498 case T_directive_label:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
5500 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as text." );
5508 text->SetText( FromUTF8() );
5510 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5512 if( token != T_LEFT )
5513 Expecting( T_LEFT );
5519 case T_exclude_from_sim:
5530 switch(
static_cast<int>( label->GetTextAngle().AsDegrees() ) )
5546 Unexpected( T_shape );
5564 Expecting(
"input, output, bidirectional, tri_state, passive, dot, round, diamond"
5575 Unexpected( T_length );
5584 case T_fields_autoplaced:
5594 text->SetVisible(
true );
5619 Unexpected( T_property );
5643 case T_custom_property:
5648 Expecting(
"at, shape, iref, uuid, effects, locked, or custom_property" );
5654 if( label && label->
GetFields().empty() )
5657 return text.release();
5663 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
5664 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
5666 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>();
5670 return textBox.release();
5676 wxCHECK_MSG( CurTok() == T_table_cell,
nullptr,
5677 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table cell." ) );
5679 std::unique_ptr<SCH_TABLECELL> cell = std::make_unique<SCH_TABLECELL>();
5683 return cell.release();
5699 bool foundEnd =
false;
5700 bool foundSize =
false;
5701 bool foundMargins =
false;
5705 aTextBox->
SetText( FromUTF8() );
5707 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5709 if( token != T_LEFT )
5710 Expecting( T_LEFT );
5716 case T_exclude_from_sim:
5747 cell->SetColSpan(
parseInt(
"column span" ) );
5748 cell->SetRowSpan(
parseInt(
"row span" ) );
5752 Expecting(
"at, size, stroke, fill, effects or uuid" );
5776 foundMargins =
true;
5795 case T_custom_property:
5801 Expecting(
"at, size, stroke, fill, effects, span, uuid, locked, or custom_property" );
5803 Expecting(
"at, size, stroke, fill, effects, uuid, locked, or custom_property" );
5811 else if( foundSize )
5812 aTextBox->
SetEnd( pos + size );
5814 Expecting(
"size" );
5829 wxCHECK_MSG( CurTok() == T_table,
nullptr,
5830 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table." ) );
5836 std::unique_ptr<SCH_TABLE>
table = std::make_unique<SCH_TABLE>( defaultLineWidth );
5838 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5840 if( token != T_LEFT )
5841 Expecting( T_LEFT );
5847 case T_column_count:
5852 case T_column_widths:
5856 while( ( token = NextTok() ) != T_RIGHT )
5866 while( ( token = NextTok() ) != T_RIGHT )
5873 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5875 if( token != T_LEFT )
5876 Expecting( T_LEFT );
5880 if( token != T_table_cell )
5881 Expecting(
"table_cell" );
5889 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5891 if( token != T_LEFT )
5892 Expecting( T_LEFT );
5910 table->SetBorderStroke( borderStroke );
5914 Expecting(
"external, header or stroke" );
5922 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5924 if( token != T_LEFT )
5925 Expecting( T_LEFT );
5943 table->SetSeparatorsStroke( separatorsStroke );
5947 Expecting(
"rows, cols, or stroke" );
5965 case T_custom_property:
5970 Expecting(
"columns, col_widths, row_heights, border, separators, uuid, locked, header, cells, "
5971 "or custom_property" );
5975 if( !
table->GetCell( 0, 0 ) )
5977 THROW_PARSE_ERROR(
_(
"Invalid table: no cells defined" ), CurSource(), CurLine(), CurLineNumber(),
5981 if(
table->GetColCount() <= 0 )
5983 THROW_PARSE_ERROR(
_(
"Invalid table: column count must be positive" ), CurSource(), CurLine(), CurLineNumber(),
5987 if(
table->GetCells().size() %
table->GetColCount() != 0 )
5989 THROW_PARSE_ERROR(
_(
"Invalid table: incomplete row" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
5992 return table.release();
5998 wxCHECK_RET( CurTok() == T_bus_alias,
5999 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus alias." ) );
6000 wxCHECK( aScreen, );
6003 std::shared_ptr<BUS_ALIAS> busAlias = std::make_shared<BUS_ALIAS>();
6014 busAlias->SetName( alias );
6019 if( token != T_members )
6020 Expecting(
"members" );
6024 while( token != T_RIGHT )
6026 if( !IsSymbol( token ) )
6027 Expecting(
"quoted string" );
6029 member = FromUTF8();
6034 busAlias->AddMember( member );
6055 wxString
name = FromUTF8();
6059 wxString fromRef, fromPin, toRef, toPin;
6060 std::set<wxString> memberNets;
6062 for(
T tok = NextTok(); tok != T_RIGHT; tok = NextTok() )
6069 NeedSYMBOLorNUMBER();
6071 NeedSYMBOLorNUMBER();
6075 else if( tok == T_to )
6077 NeedSYMBOLorNUMBER();
6079 NeedSYMBOLorNUMBER();
6083 else if( tok == T_net_class )
6085 NeedSYMBOLorNUMBER();
6086 netClass = FromUTF8();
6089 else if( tok == T_color )
6095 color =
COLOR4D( r / 255.0, g / 255.0, b / 255.0, al );
6098 else if( tok == T_nets )
6100 for(
T inner = NextTok(); inner != T_RIGHT; inner = NextTok() )
6102 if( !IsSymbol( inner ) && inner != T_NUMBER )
6103 Expecting(
"net name" );
6105 memberNets.insert( FromUTF8() );
6115 T inner = NextTok();
6117 if( inner == T_EOF )
6120 if( inner == T_LEFT )
6122 else if( inner == T_RIGHT )
6128 if( !fromRef.IsEmpty() && !toRef.IsEmpty() )
6133 if( !netClass.IsEmpty() )
6139 if( !memberNets.empty() )
6148 while( ( token = NextTok() ) != T_RIGHT )
6153 KIID uuid( CurStr() );
6161 wxCHECK_RET( CurTok() == T_group,
6162 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GROUP." ) );
6169 while( ( token = NextTok() ) != T_LEFT )
6171 if( token == T_STRING )
6172 groupInfo.
name = FromUTF8();
6174 Expecting(
"group name or locked" );
6177 for( ; token != T_RIGHT; token = NextTok() )
6179 if( token != T_LEFT )
6180 Expecting( T_LEFT );
6196 if( !IsSymbol( token ) && token != T_NUMBER )
6197 Expecting(
"symbol|number" );
6200 wxString
name = FromUTF8();
6204 name.Replace(
"{slash}",
"/" );
6210 if(
static_cast<int>(
name.size() ) > bad_pos )
6212 wxString msg = wxString::Format(
_(
"Group library link %s contains invalid character '%c'" ),
name,
6218 THROW_PARSE_ERROR(
_(
"Invalid library ID" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
6236 case T_custom_property:
6241 Expecting(
"uuid, lib_id, members, locked" );
6253 [&](
const KIID& aId )
6259 if( item->m_Uuid == aId )
6278 group->SetName( groupInfo.name );
6280 const_cast<KIID&
>(
group->m_Uuid ) = groupInfo.uuid;
6282 if( groupInfo.libId.IsValid() )
6283 group->SetDesignBlockLibId( groupInfo.libId );
6285 group->SetLocked( groupInfo.locked );
6286 group->SetCustomProperties( groupInfo.customProperties );
6297 for(
const KIID& aUuid : groupInfo.memberUuids )
6299 if(
SCH_ITEM* gItem = getItem( aUuid ) )
6300 group->AddItem( gItem );
6315 T token = NextTok();
6317 if( token == T_EOF )
6319 else if( token == T_LEFT )
6321 else if( token == T_RIGHT )
constexpr EDA_IU_SCALE schIUScale
constexpr double ARC_LOW_DEF_MM
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
void SetContentModified(bool aModified=true)
This class handle bitmap images in KiCad.
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
A base class for most all the KiCad significant classes used in schematics and boards.
KICAD_T Type() const
Returns the type of object.
EDA_ITEM * GetParent() const
void SetCustomProperty(const wxString &aKey, const wxString &aValue)
virtual void SetParent(EDA_ITEM *aParent)
virtual void SetEnd(const VECTOR2I &aEnd)
FILL_T GetFillMode() const
SHAPE_POLY_SET & GetPolyShape()
virtual void SetEllipseEndAngle(const EDA_ANGLE &aA)
virtual void SetEllipseRotation(const EDA_ANGLE &aA)
void SetFillColor(const COLOR4D &aColor)
int GetPointCount() const
virtual void SetEllipseCenter(const VECTOR2I &aPt)
virtual void SetEllipseMinorRadius(int aR)
virtual void SetEllipseMajorRadius(int aR)
const LINE_ENDING & GetStartEnding() const
virtual void SetEllipseStartAngle(const EDA_ANGLE &aA)
const LINE_ENDING & GetEndEnding() const
void SetFillMode(FILL_T aFill)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
void SetTextColor(const COLOR4D &aColor)
virtual void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
void SetUnresolvedFontName(const wxString &aFontName)
virtual const wxString & GetText() const
Return the string associated with the text object.
virtual void SetTextPos(const VECTOR2I &aPoint)
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
void SetBoldFlag(bool aBold)
Set only the bold flag, without changing the font.
virtual void SetVisible(bool aVisible)
void MigrateLegacyBoldStrokeWidth()
Migrate a pre-v11 bold stroke text so its stored thickness holds the base (non-bold) width.
void SetLineSpacing(double aLineSpacing)
virtual 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 SetItalicFlag(bool aItalic)
Set only the italic flag, without changing the font.
void SetHyperlink(wxString aLink)
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
void ParseEmbedded(EMBEDDED_FILES *aFiles)
const std::vector< wxString > * UpdateFontFiles()
Helper function to get a list of fonts for fontconfig to add to the library.
const std::vector< wxString > * GetFontFiles() const
If we just need the cached version of the font files, we can use this function which is const and wil...
void SetAreFontsEmbedded(bool aEmbedFonts)
bool GetAreFontsEmbedded() const
Simple container to manage fill parameters.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
Represents an (ordered) list of JUMPER_GROUP objects.
void Add(JUMPER_GROUP aGroup)
Add a JUMPER_GROUP to the set.
static std::optional< JUMPER_GROUP > Make(std::set< wxString > aNames)
Factory method to create a JUMPER_GROUP from a set of names.
A color representation with 4 components: red, green, blue, alpha.
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
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.
Define a library symbol object.
wxString GetName() const override
void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction, RECURSE_MODE aMode) override
EMBEDDED_FILES * GetEmbeddedFiles() override
Decorative shape (arrowhead, circle, square) at the start or end of a graphic line,...
void SetStroke(const STROKE_PARAMS &aStroke)
void SetLength(int aLength)
void SetStyle(LINE_ENDING_STYLE aStyle)
void SetWidth(int aWidth)
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
Describe the page size and margins of a paper page on which to eventually print or plot.
void SetPortrait(bool aIsPortrait)
Rotate the paper page 90 degrees.
bool SetType(PAGE_SIZE_TYPE aPageSize, bool aIsPortrait=false)
Set the name of the page type and also the sizes and margins commonly associated with that type name.
void SetWidthMM(double aWidthInMM)
void SetHeightMM(double aHeightInMM)
const PAGE_SIZE_TYPE & GetType() const
A symbol-owned ordered set of named pin maps.
void AddOrReplace(PIN_MAP aMap)
Insert aMap, replacing any existing entry with the same name.
void SetEntry(const wxString &aPinNumber, const wxString &aPadNumber)
Set the pad number for a symbol pin.
A progress reporter interface for use in multi-threaded environments.
A REFERENCE_IMAGE is a wrapper around a BITMAP_IMAGE that is displayed in an editor as a reference fo...
bool ReadImageFile(const wxString &aFullFilename)
Read and store an image file.
void SetOrientation(const EDA_ANGLE &aAngle)
Set the rotation of the image content relative to the stored raster.
void SetOpacity(double aOpacity)
const BITMAP_BASE & GetImage() const
Get the underlying image.
double GetImageScale() const
void SetImageScale(double aScale)
Set the image "zoom" value.
Holds all the data relating to one schematic.
EMBEDDED_FILES * GetEmbeddedFiles() override
bool HasProjectBusAliases() const
Object to handle a bitmap image that can be inserted in a schematic.
Class for a wire to bus entry.
void SetPinLength(int aLength)
virtual const wxString & GetText() const override
Return the string associated with the text object.
wxString GetUntranslatedName() const
Get the untranslated field name for storage, variable look-up, etc.
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
void SetName(const wxString &aName)
static bool IsNetclassLabelFieldName(const wxString &aName)
Test whether aName is one of the known translations of the directive-label net class field name (used...
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this label.
A set of SCH_ITEMs (i.e., without duplicates).
SCH_ITEM * ParseSymbolDrawItem()
SCH_SHAPE * parseSymbolPolyLine()
SCH_TABLE * parseSchTable()
bool m_appending
Appending load status.
unsigned m_lastProgressLine
SCH_FIELD * parseSchField(SCH_ITEM *aParent)
SCH_SHAPE * parseSchCircle()
SCH_TEXT * parseSchText()
SCH_TABLECELL * parseSchTableCell()
void parseSchSymbolInstances(SCH_SCREEN *aScreen)
void parsePinNumbers(std::unique_ptr< LIB_SYMBOL > &aSymbol)
LIB_SYMBOL * parseLibSymbol(LIB_SYMBOL_MAP &aSymbolLibMap)
void parseEllipseBody(SCH_SHAPE *aShape, bool aIsArc, bool aIsSchematic, TSCHEMATIC_T::T aFirstTok)
SCH_RULE_AREA * parseSchRuleArea()
SCH_SHAPE * parseSymbolEllipseArc()
SCH_ITEM * parseSymbolText()
PROGRESS_REPORTER * m_progressReporter
void parseFill(FILL_PARAMS &aFill)
SCH_TEXTBOX * parseSymbolTextBox()
void parseBusAlias(SCH_SCREEN *aScreen)
void parseTITLE_BLOCK(TITLE_BLOCK &aTitleBlock)
void parseGroupMembers(GROUP_INFO &aGroupInfo)
LIB_ID parseSymbolOverride()
void parseLineEnding(LINE_ENDING &aEnding)
Parse a line ending definition from the token stream.
void parseStroke(STROKE_PARAMS &aStroke)
Parse stroke definition aStroke.
int m_unit
The current unit being parsed.
std::map< wxString, std::set< wxString > > m_netChainMemberNets
SCH_SHAPE * parseSymbolBezier()
void parseEDA_TEXT(EDA_TEXT *aText, bool aConvertOverbarSyntax, bool aEnforceMinTextSize=true)
SCH_TEXTBOX * parseSchTextBox()
void resolveGroups(SCH_SCREEN *aParent)
std::map< wxString, wxString > m_netChainNetClasses
SCH_SHEET * m_rootSheet
The rootsheet for full project loads or null for importing a schematic.
SCH_SHAPE * parseSchArc()
SCH_SHAPE * parseSchPolyLine()
SCH_BITMAP * parseImage()
SCH_SHAPE * parseSymbolCircle()
wxString m_generatorVersion
void ParseLib(LIB_SYMBOL_MAP &aSymbolLibMap)
SCH_PIN * parseSymbolPin()
std::vector< GROUP_INFO > m_groupInfos
void parseHeader(TSCHEMATIC_T::T aHeaderType, int aFileVersion)
void parseBodyStyles(std::unique_ptr< LIB_SYMBOL > &aSymbol)
SCH_SHAPE * parseSchEllipse()
void parsePinMaps(std::unique_ptr< LIB_SYMBOL > &aSymbol)
void parseMargins(int &aLeft, int &aTop, int &aRight, int &aBottom)
wxString m_symbolName
The current symbol name.
std::map< wxString, CHAIN_TERMINALS > m_netChainTerminalRefs
VECTOR2I parseXY(bool aInvertY=false)
SCH_SHAPE * parseSymbolRectangle()
void parsePinNames(std::unique_ptr< LIB_SYMBOL > &aSymbol)
void parseAssociatedFootprints(std::unique_ptr< LIB_SYMBOL > &aSymbol)
void ParseSchematic(SCH_SHEET *aSheet, bool aIsCopyableOnly=false, int aFileVersion=SEXPR_SCHEMATIC_FILE_VERSION)
Parse the internal LINE_READER object into aSheet.
SCH_SHAPE * parseSchBezier()
std::vector< wxString > m_parseWarnings
Non-fatal warnings collected during parsing.
SCH_JUNCTION * parseJunction()
SCH_SHEET_PIN * parseSchSheetPin(SCH_SHEET *aSheet)
int m_bodyStyle
The current body style being parsed.
SCH_NO_CONNECT * parseNoConnect()
SCH_SHAPE * parseSymbolArc()
void parseCustomProperty(EDA_ITEM *aItem)
SCH_BUS_WIRE_ENTRY * parseBusEntry()
SCH_SHAPE * parseSymbolEllipse()
PIN_MAP_INSTANCE_OVERRIDE parsePinMapOverride()
std::map< wxString, COLOR4D > m_netChainColors
SCH_SHAPE * parseSchRectangle()
SCH_FIELD * parseProperty(std::unique_ptr< LIB_SYMBOL > &aSymbol)
SCH_SYMBOL * parseSchematicSymbol()
void parseSchTextBoxContent(SCH_TEXTBOX *aTextBox)
bool parseMaybeAbsentBool(bool aDefaultValue)
Parses a boolean flag inside a list that existed before boolean normalization.
void parsePAGE_INFO(PAGE_INFO &aPageInfo)
int m_requiredVersion
Set to the symbol library file version required.
int m_maxError
Max deviation allowed when approximating bezier curves.
const LINE_READER * m_lineReader
LIB_SYMBOL * ParseSymbol(LIB_SYMBOL_MAP &aSymbolLibMap, int aFileVersion=SEXPR_SYMBOL_LIB_FILE_VERSION)
Parse internal LINE_READER object into symbols and return all found.
void skipToBlockEnd(int aDepth=1)
Skip tokens until we reach the end of the current S-expression block.
void parseSchSheetInstances(SCH_SHEET *aRootSheet, SCH_SCREEN *aScreen)
SCH_SHAPE * parseSchEllipseArc()
bool m_sheetLoad
Loading a sheet into an already open schematic.
SCH_IO_KICAD_SEXPR_PARSER(LINE_READER *aLineReader=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr, unsigned aLineCount=0, SCH_SHEET *aRootSheet=nullptr, bool aIsAppending=false, bool aIsSheetLoad=false)
Base class for any item which can be embedded within the SCHEMATIC container class,...
void SetLocked(bool aLocked) override
bool IsLocked() const override
void SetFieldsAutoplaced(AUTOPLACE_ALGO aAlgo)
void SetShape(LABEL_FLAG_SHAPE aShape)
std::vector< SCH_FIELD > & GetFields()
Segment description base class to describe items which have 2 end points (track, wire,...
void SetStartPoint(const VECTOR2I &aPosition)
void SetEndEnding(const LINE_ENDING &aEnding)
void SetStartEnding(const LINE_ENDING &aEnding)
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.
void SetPageSettings(const PAGE_INFO &aPageSettings)
EE_RTREE & Items()
Get the full RTree, usually for iterating.
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.
SCHEMATIC * Schematic() const
void FixupEmbeddedData()
After loading a file from disk, the library symbols do not yet contain the full data for their embedd...
int GetFileFormatVersionAtLoad() const
wxString GroupsSanityCheck(bool repair=false)
Consistency check of internal m_groups structure.
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.
void SetPosition(const VECTOR2I &aPos) override
void SetStroke(const STROKE_PARAMS &aStroke) override
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.
Variant information for a schematic sheet.
void InitializeAttributes(const SCH_SHEET &aSheet)
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
void SyncUuidToScreen()
Take the identity of the screen this sheet owns.
SCH_SCREEN * GetScreen() const
Variant information for a schematic symbol.
PIN_MAP_INSTANCE_OVERRIDE m_PinMapOverride
Per-instance pin-to-pad map override for this variant (issue #2282).
std::optional< LIB_ID > m_SymbolOverride
Alternate library symbol to substitute for the base symbol in this variant, if any.
void InitializeAttributes(const SCH_SYMBOL &aSymbol)
void SetMarginBottom(int aBottom)
int GetLegacyTextMargin() const
void SetMarginLeft(int aLeft)
void SetMarginRight(int aRight)
void SetExcludedFromSim(bool aExclude, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
void SetMarginTop(int aTop)
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetPoint(int aIndex, const VECTOR2I &aPos)
Move a point to a specific location.
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
int PointCount() const
Return the number of points (vertices) in this line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
const VECTOR2I & CLastPoint() const
Return the last point in the line chain.
Represent a set of closed polygons.
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.
void SetLineStyle(LINE_STYLE aLineStyle)
LINE_STYLE GetLineStyle() const
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.
std::map< wxString, wxString > m_Fields
bool m_ExcludedFromPosFiles
#define DEFAULT_LINE_WIDTH_MILS
The default line width in mils. (can be changed in preference menu)
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_360
static constexpr EDA_ANGLE ANGLE_180
@ FILLED_WITH_BG_BODYCOLOR
@ FILLED_SHAPE
Fill with object color.
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
FONTCONFIG * Fontconfig()
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#define THROW_IO_CANCELLED()
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
static wxString From_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
#define MAX_PAGE_SIZE_EESCHEMA_MM
#define MIN_PAGE_SIZE_MM
Min and max page sizes for clamping, in mm.
PGM_BASE & Pgm()
The global program "get" accessor.
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
@ PT_INPUT
usual pin input: must be connected
@ PT_NC
not connected (must be left open)
@ PT_TRISTATE
tri state bus pin
@ PT_NIC
not internally connected (may be connected to anything)
@ PT_BIDI
input or output (like port for a microprocessor)
@ PT_OPENEMITTER
pin type open emitter
@ PT_POWER_OUT
output of a regulator: intended to be connected to power input pins
@ PT_OPENCOLLECTOR
pin type open collector
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
@ PT_UNSPECIFIED
unknown electrical properties: creates always a warning when connected
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin.
@ PIN_UP
The pin extends upwards from the connection point: Probably on the bottom side of the symbol.
@ PIN_RIGHT
The pin extends rightwards from the connection point.
@ PIN_LEFT
The pin extends leftwards from the connection point: Probably on the right side of the symbol.
@ PIN_DOWN
The pin extends downwards from the connection: Probably on the top side of the symbol.
static const std::vector< std::string > filters
const SCH_FIELD * FindField(const std::vector< SCH_FIELD > &aFields, FIELD_T aFieldId)
#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.
Class to handle a set of SCH_ITEMs.
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 ...
void fixupSchFillMode(SCH_SHAPE *aShape)
#define SIM_LEGACY_ENABLE_FIELD
#define SIM_LEGACY_ENABLE_FIELD_V7
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
wxString UnescapeString(const wxString &aSource)
A filename or source description, a problem input line, a line number, a byte offset,...
ELECTRICAL_PINTYPE m_Type
Per-instance override of the active pin map and a sparse delta on top.
std::vector< KIID > memberUuids
std::map< wxString, wxString > customProperties
A simple container for sheet instance information.
std::map< wxString, SCH_SHEET_VARIANT > m_Variants
A list of sheet variants.
A simple container for schematic symbol instance information.
std::map< wxString, SCH_SYMBOL_VARIANT > m_Variants
A list of symbol variants.
std::map< wxString, LIB_SYMBOL *, LibSymbolMapSort > LIB_SYMBOL_MAP
Symbol library map sorted by the symbol name.
wxString GetDefaultFieldName(FIELD_T aFieldId, TRANSLATION aTranslation)
Return a default symbol field name for a mandatory field type.
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ USER
The field ID hasn't been set yet; field is invalid.
@ INTERSHEET_REFS
Global label cross-reference page numbers.
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
#define SHEET_MANDATORY_FIELDS
#define GLOBALLABEL_MANDATORY_FIELDS
KIBIS top(path, &reporter)
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
static constexpr double IU_PER_MM
Mock up a conversion function.
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.
VECTOR2< int32_t > VECTOR2I