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" );
311 if( CurTok() == T_LEFT )
315 if( CurTok() == T_symbol )
320 const std::vector<wxString>* embeddedFonts =
327 textItem->ResolveFont( embeddedFonts );
333 wxString msg = wxString::Format(
_(
"Cannot parse %s as a symbol" ),
334 GetTokenString( CurTok() ) );
345 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
346 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
353 std::unique_ptr<LIB_SYMBOL> symbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
355 symbol->SetUnitCount( 1,
true );
359 if( !IsSymbol( token ) )
360 THROW_PARSE_ERROR(
_(
"Invalid symbol name" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
367 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
374 if(
static_cast<int>(
name.size() ) > bad_pos )
376 wxString msg = wxString::Format(
_(
"Symbol %s contains invalid character '%c'" ),
385 CurLineNumber(), CurOffset() );
390 symbol->SetLibId(
id );
392 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
394 if( token != T_LEFT )
402 symbol->SetGlobalPower();
405 if( token == T_RIGHT )
408 if( token == T_local )
409 symbol->SetLocalPower();
410 else if( token != T_global )
411 Expecting(
"global or local" );
432 case T_exclude_from_sim:
433 symbol->SetExcludedFromSim(
parseBool() );
438 symbol->SetExcludedFromBOM( !
parseBool() );
443 symbol->SetExcludedFromBoard( !
parseBool() );
448 symbol->SetExcludedFromPosFiles( !
parseBool() );
452 case T_duplicate_pin_numbers_are_jumpers:
453 symbol->SetDuplicatePinNumbersAreJumpers(
parseBool() );
457 case T_jumper_pin_groups:
460 std::set<wxString> names;
461 bool inGroup =
false;
463 for( token = NextTok(); inGroup || token != T_RIGHT; token = NextTok() )
465 switch(
static_cast<int>( token ) )
469 Expecting(
"list of pin names" );
476 Expecting(
"list of pin names" );
478 names.insert( FromUTF8() );
490 Expecting(
"list of pin names" );
505 if( !IsSymbol( token ) )
508 CurLineNumber(), CurOffset() );
516 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
518 symbol->SetParentName(
name );
527 if( !IsSymbol( token ) )
530 CurLineNumber(), CurOffset() );
538 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
542 error.Printf(
_(
"Invalid symbol unit name prefix %s" ),
name.c_str() );
543 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
548 wxStringTokenizer tokenizer(
name,
"_" );
550 if( tokenizer.CountTokens() != 2 )
552 error.Printf(
_(
"Invalid symbol unit name suffix %s" ),
name.c_str() );
553 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
556 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
558 error.Printf(
_(
"Invalid symbol unit number %s" ),
name.c_str() );
559 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
562 m_unit =
static_cast<int>( tmp );
564 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
566 error.Printf(
_(
"Invalid symbol body style number %s" ),
name.c_str() );
567 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
572 if(
m_unit > symbol->GetUnitCount() )
573 symbol->SetUnitCount(
m_unit,
false );
575 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
577 if( token != T_LEFT )
587 if( IsSymbol( token ) )
588 symbol->GetUnitDisplayNames()[
m_unit] = FromUTF8();
605 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
608 symbol->AddDrawItem( item,
false );
612 Expecting(
"arc, bezier, circle, ellipse, ellipse_arc, pin, polyline, "
613 "rectangle, or text" );
634 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
637 symbol->AddDrawItem( item,
false );
640 case T_embedded_fonts:
642 symbol->SetAreFontsEmbedded(
parseBool() );
647 case T_embedded_files:
650 embeddedFilesParser.SyncLineReaderWith( *
this );
654 embeddedFilesParser.
ParseEmbedded( symbol->GetEmbeddedFiles() );
662 for(
int tok = embeddedFilesParser.NextTok();
664 tok = embeddedFilesParser.NextTok() )
668 else if( tok ==
DSN_RIGHT && --depth < 0 )
673 SyncLineReaderWith( embeddedFilesParser );
678 Expecting(
"pin_names, pin_numbers, arc, bezier, circle, ellipse, ellipse_arc, "
679 "pin, polyline, rectangle, or text" );
683 symbol->GetDrawItems().sort();
686 const std::vector<wxString>* embeddedFonts = symbol->GetEmbeddedFiles()->UpdateFontFiles();
688 symbol->RunOnChildren(
692 textItem->ResolveFont( embeddedFonts );
700 symbol->SetHasDeMorganBodyStyles( symbol->HasLegacyAlternateBodyStyle() );
704 symbol->PruneBodyStyleDrawItems( symbol->GetBodyStyleCount() );
706 symbol->RefreshLibraryTreeCaches();
708 return symbol.release();
727 Expecting(
"arc, bezier, circle, ellipse, ellipse_arc, pin, "
728 "polyline, rectangle, or text" );
742 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
744 return KiROUND( std::clamp( retval, -int_limit, int_limit ) );
752 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
754 return KiROUND( std::clamp( retval, -int_limit, int_limit ) );
761 strokeParser.SyncLineReaderWith( *
this );
764 SyncLineReaderWith( strokeParser );
780 default: Expecting(
"arrow, circle, square, arrow_open, or none" );
784 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
786 if( token != T_LEFT )
811 default: Expecting(
"length, width, or stroke" );
819 wxCHECK_RET( CurTok() == T_fill,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a fill." );
826 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
828 if( token != T_LEFT )
848 default: Expecting(
"none, outline, hatch, reverse_hatch, "
849 "cross_hatch, color or background" );
863 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
870 Expecting(
"type or color" );
877 bool aEnforceMinTextSize )
879 wxCHECK_RET( aText && ( CurTok() == T_effects || CurTok() == T_href ),
880 "Cannot parse " + GetTokenString( CurTok() ) +
" as an EDA_TEXT." );
897 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
899 if( token == T_LEFT )
905 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
907 if( token == T_LEFT )
947 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
958 Expecting(
"face, size, thickness, line_spacing, bold, or italic" );
965 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
974 case T_mirror:
break;
975 default: Expecting(
"left, right, top, bottom, or mirror" );
984 wxString hyperlink = FromUTF8();
989 CurSource(), CurLine(), CurLineNumber(), CurOffset() );
1008 Expecting(
"font, justify, hide or href" );
1019 if( CurTok() != aHeaderType )
1022 GetTokenString( CurTok() ) ),
1023 CurSource(), CurLine(), CurLineNumber(), CurOffset() );
1030 if( tok == T_version )
1044 wxCHECK_RET( CurTok() == T_body_styles,
1045 "Cannot parse " + GetTokenString( CurTok() ) +
" as a body_styles token." );
1047 std::vector<wxString> names;
1049 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1051 if( token == T_demorgan )
1053 aSymbol->SetHasDeMorganBodyStyles(
true );
1056 else if( !IsSymbol( token ) )
1058 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
1062 names.push_back( FromUTF8() );
1065 if( !names.empty() )
1066 aSymbol->SetBodyStyleNames( names );
1072 wxCHECK_RET( CurTok() == T_pin_names,
1073 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_name token." );
1083 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1086 if( token == T_hide )
1088 aSymbol->SetShowPinNames(
false );
1092 if( token != T_LEFT )
1094 Expecting( T_LEFT );
1107 aSymbol->SetShowPinNames( !
parseBool() );
1112 Expecting(
"offset or hide" );
1120 wxCHECK_RET( CurTok() == T_pin_numbers,
1121 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_number token." );
1130 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1133 if( token == T_hide )
1135 aSymbol->SetShowPinNumbers(
false );
1139 if( token != T_LEFT )
1141 Expecting( T_LEFT );
1149 aSymbol->SetShowPinNumbers( !
parseBool() );
1154 Expecting(
"hide" );
1163 wxCHECK_RET( CurTok() == T_associated_footprints,
1164 "Cannot parse " + GetTokenString( CurTok() ) +
" as an associated_footprints token." );
1173 std::vector<ASSOCIATED_FOOTPRINT> list;
1175 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1177 if( token != T_LEFT )
1178 Expecting( T_LEFT );
1182 if( token != T_footprint )
1183 Expecting(
"footprint" );
1187 if( !IsSymbol( token ) )
1188 Expecting(
"footprint library identifier" );
1193 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1195 if( token != T_LEFT )
1196 Expecting( T_LEFT );
1205 if( !IsSymbol( token ) )
1206 Expecting(
"map name" );
1212 default: Expecting(
"map" );
break;
1216 list.push_back( std::move( assoc ) );
1219 aSymbol->SetAssociatedFootprints( std::move( list ) );
1225 wxCHECK_RET( CurTok() == T_pin_maps,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_maps token." );
1236 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1238 if( token != T_LEFT )
1239 Expecting( T_LEFT );
1243 if( token != T_pin_map )
1244 Expecting(
"pin_map" );
1249 aSymbol->SetPinMaps( set );
1255 wxCHECK_MSG( CurTok() == T_pin_map,
PIN_MAP(),
1256 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_map token." );
1258 T token = NextTok();
1260 if( !IsSymbol( token ) )
1261 Expecting(
"pin map name" );
1265 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1267 if( token != T_LEFT )
1268 Expecting( T_LEFT );
1272 if( token != T_entry )
1273 Expecting(
"entry" );
1277 if( !IsSymbol( token ) )
1278 Expecting(
"pin number" );
1280 wxString pinNumber = FromUTF8();
1284 if( !IsSymbol( token ) )
1285 Expecting(
"pad number" );
1287 map.
SetEntry( pinNumber, FromUTF8() );
1299 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_map_override token." );
1311 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1313 if( token != T_LEFT )
1314 Expecting( T_LEFT );
1329 default: Expecting(
"library_default, named_map, identity, or delegate" );
1338 if( !IsSymbol( token ) )
1339 Expecting(
"map name" );
1341 override.m_ActiveMapName = FromUTF8();
1349 if( !IsSymbol( token ) )
1350 Expecting(
"pin number" );
1352 wxString pinNumber = FromUTF8();
1356 if( !IsSymbol( token ) )
1357 Expecting(
"pad number" );
1359 override.m_Edits.push_back( { pinNumber, FromUTF8() } );
1364 default: Expecting(
"mode, map, or edit" );
1374 wxCHECK_MSG( CurTok() == T_symbol_override,
LIB_ID(),
1375 "Cannot parse " + GetTokenString( CurTok() ) +
" as a symbol_override token." );
1377 T token = NextTok();
1379 if( !IsSymbol( token ) )
1380 Expecting(
"symbol LIB_ID" );
1382 wxString
name = FromUTF8();
1388 if(
static_cast<int>(
name.size() ) > bad_pos )
1390 wxString msg = wxString::Format(
_(
"Variant symbol override contains invalid character '%c'" ),
1396 THROW_PARSE_ERROR(
_(
"Invalid variant symbol override LIB_ID" ), CurSource(), CurLine(),
1397 CurLineNumber(), CurOffset() );
1407 wxCHECK_MSG( CurTok() == T_property,
nullptr,
1408 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a property." ) );
1409 wxCHECK( aSymbol,
nullptr );
1414 bool isPrivate =
false;
1415 bool isVisible =
true;
1417 T token = NextTok();
1419 if( token == T_private )
1425 if( !IsSymbol( token ) )
1427 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
1433 if(
name.IsEmpty() )
1435 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
1449 auto field = std::make_unique<SCH_FIELD>( aSymbol.get(), fieldId,
name );
1450 field->SetPrivate( isPrivate );
1451 field->SetVisible( isVisible );
1455 if( !IsSymbol( token ) )
1457 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
1464 value = wxEmptyString;
1468 field->SetText( value );
1470 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1472 if( token != T_LEFT )
1473 Expecting( T_LEFT );
1485 field->SetPosition(
parseXY(
true ) );
1503 field->SetNameShown( show );
1507 case T_do_not_autoplace:
1510 field->SetCanAutoplace( !doNotAutoplace );
1514 case T_custom_property:
1519 Expecting(
"id, at, hide, show_name, do_not_autoplace, or effects" );
1525 if( field->IsMandatory() )
1527 existingField = aSymbol->GetField( field->GetId() );
1529 *existingField = *field;
1530 return existingField;
1532 else if(
name ==
"ki_keywords" )
1535 aSymbol->SetKeyWords( value );
1539 else if(
name ==
"ki_description" )
1541 aSymbol->SetDescription( value );
1544 else if(
name ==
"ki_fp_filters" )
1548 wxStringTokenizer tokenizer( value,
" \t\r\n", wxTOKEN_STRTOK );
1550 while( tokenizer.HasMoreTokens() )
1552 wxString curr_token =
UnescapeString( tokenizer.GetNextToken() );
1556 aSymbol->SetFPFilters(
filters );
1559 else if(
name ==
"ki_locked" )
1563 aSymbol->LockUnits(
true );
1569 existingField = aSymbol->GetField( field->GetUntranslatedName() );
1577 wxString base_name = field->GetUntranslatedName();
1580 for(
int ii = 1; ii < 10 && existingField; ii++ )
1582 wxString newname = base_name;
1583 newname <<
'_' << ii;
1585 existingField = aSymbol->GetField( newname );
1587 if( !existingField )
1588 field->SetName( newname );
1592 if( !existingField )
1594 aSymbol->AddDrawItem( field.get(),
false );
1595 return field.release();
1608 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
1609 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
1615 bool hasMidPoint =
false;
1623 bool hasAngles =
false;
1632 if( token == T_private )
1634 arc->SetPrivate(
true );
1638 for( ; token != T_RIGHT; token = NextTok() )
1640 if( token != T_LEFT )
1641 Expecting( T_LEFT );
1664 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1666 if( token != T_LEFT )
1667 Expecting( T_LEFT );
1695 Expecting(
"at, length, or angles" );
1703 arc->SetStroke( stroke );
1709 arc->SetFillColor( fill.
m_Color );
1716 arc->SetStartEnding( ending );
1724 arc->SetEndEnding( ending );
1728 default: Expecting(
"start, mid, end, radius, stroke, fill, start_shape, or end_shape" );
1734 arc->SetArcGeometry( startPoint, midPoint, endPoint );
1745 EDA_ANGLE arc_start, arc_end, arc_angle;
1746 arc->CalcArcAngles( arc_start, arc_end );
1747 arc_angle = arc_end - arc_start;
1752 arc->SetStart( endPoint );
1753 arc->SetEnd( startPoint );
1756 arc->SetCenter( new_center );
1762 arc->SetCenter( new_center );
1766 else if( hasAngles )
1768 arc->SetCenter(
center );
1774 arc->SetStart( endPoint );
1775 arc->SetEnd( startPoint );
1779 EDA_ANGLE arc_start, arc_end, arc_angle;
1780 arc->CalcArcAngles( arc_start, arc_end );
1781 arc_angle = arc_end - arc_start;
1787 arc->SetStart( startPoint );
1788 arc->SetEnd( endPoint );
1796 arc->SetStart( startPoint );
1797 arc->SetEnd( endPoint );
1801 arc->SetCenter( new_center );
1807 wxFAIL_MSG(
"Setting arc without either midpoint or angles not implemented." );
1810 return arc.release();
1816 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
1817 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
1825 bezier->SetUnit(
m_unit );
1830 if( token == T_private )
1832 bezier->SetPrivate(
true );
1836 for( ; token != T_RIGHT; token = NextTok() )
1838 if( token != T_LEFT )
1839 Expecting( T_LEFT );
1849 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
1851 if( token != T_LEFT )
1852 Expecting( T_LEFT );
1861 case 0: bezier->SetStart(
parseXY(
true ) );
break;
1862 case 1: bezier->SetBezierC1(
parseXY(
true ) );
break;
1863 case 2: bezier->SetBezierC2(
parseXY(
true ) );
break;
1864 case 3: bezier->SetEnd(
parseXY(
true ) );
break;
1865 default: Unexpected(
"control point" );
break;
1875 bezier->SetStroke( stroke );
1881 bezier->SetFillColor( fill.
m_Color );
1888 bezier->SetStartEnding( ending );
1896 bezier->SetEndEnding( ending );
1900 default: Expecting(
"pts, stroke, fill, start_shape, or end_shape" );
1904 bezier->RebuildBezierToSegmentsPointsList(
m_maxError );
1906 return bezier.release();
1912 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
1913 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
1928 if( token == T_private )
1930 circle->SetPrivate(
true );
1934 for( ; token != T_RIGHT; token = NextTok() )
1936 if( token != T_LEFT )
1937 Expecting( T_LEFT );
1955 circle->SetStroke( stroke );
1965 Expecting(
"center, radius, stroke, or fill" );
1978 wxCHECK_MSG( CurTok() == T_ellipse,
nullptr,
1979 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an ellipse." ) );
1982 ellipse->SetUnit(
m_unit );
1985 T token = NextTok();
1987 if( token == T_private )
1989 ellipse->SetPrivate(
true );
1994 return ellipse.release();
2000 wxCHECK_MSG( CurTok() == T_ellipse_arc,
nullptr,
2001 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an elliptical arc." ) );
2007 T token = NextTok();
2009 if( token == T_private )
2011 arc->SetPrivate(
true );
2016 return arc.release();
2042 Expecting(
"input, output, bidirectional, tri_state, passive, unspecified, "
2043 "power_in, power_out, open_collector, open_emitter, free or "
2065 Expecting(
"line, inverted, clock, inverted_clock, input_low, clock_low, "
2066 "output_low, edge_clock_high, 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 ) )
2139 pin->SetName( wxEmptyString );
2143 pin->SetName( FromUTF8() );
2147 if( token != T_RIGHT )
2151 if( token == T_effects )
2158 pin->SetNameTextSize(
text.GetTextHeight() );
2163 Expecting(
"effects" );
2172 if( !IsSymbol( token ) )
2175 CurLineNumber(), CurOffset() );
2179 pin->SetNumber( wxEmptyString );
2183 pin->SetNumber( FromUTF8() );
2187 if( token != T_RIGHT )
2191 if( token == T_effects )
2198 pin->SetNumberTextSize(
text.GetTextHeight() );
2203 Expecting(
"effects" );
2215 if( !IsSymbol( token ) )
2218 CurLineNumber(), CurOffset() );
2224 alt.
m_Type = parseType( token );
2227 alt.
m_Shape = parseShape( token );
2229 pin->GetAlternates()[ alt.
m_Name ] = alt;
2235 case T_custom_property:
2240 Expecting(
"at, name, number, hide, length, or alternate" );
2244 return pin.release();
2250 wxCHECK_MSG( CurTok() == T_polyline,
nullptr,
2251 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a poly." ) );
2263 if( token == T_private )
2265 poly->SetPrivate(
true );
2269 for( ; token != T_RIGHT; token = NextTok() )
2271 if( token != T_LEFT )
2272 Expecting( T_LEFT );
2279 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2281 if( token != T_LEFT )
2282 Expecting( T_LEFT );
2289 poly->AddPoint(
parseXY(
true ) );
2298 poly->SetStroke( stroke );
2304 poly->SetFillColor( fill.
m_Color );
2311 poly->SetStartEnding( ending );
2319 poly->SetEndEnding( ending );
2323 default: Expecting(
"pts, stroke, fill, start_shape, or end_shape" );
2327 if( poly->GetFillMode() !=
FILL_T::NO_FILL && poly->GetPolyShape().OutlineCount() > 0 )
2337 return poly.release();
2343 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
2344 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
2351 rectangle->SetUnit(
m_unit );
2356 if( token == T_private )
2358 rectangle->SetPrivate(
true );
2362 for( ; token != T_RIGHT; token = NextTok() )
2364 if( token != T_LEFT )
2365 Expecting( T_LEFT );
2372 rectangle->SetPosition(
parseXY(
true ) );
2377 rectangle->SetEnd(
parseXY(
true ) );
2388 rectangle->SetStroke( stroke );
2394 rectangle->SetFillColor( fill.
m_Color );
2398 Expecting(
"start, end, stroke, or fill" );
2402 return rectangle.release();
2408 wxCHECK_MSG( CurTok() == T_text,
nullptr,
2409 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text token." ) );
2412 std::unique_ptr<SCH_TEXT>
text = std::make_unique<SCH_TEXT>();
2419 if( token == T_private )
2421 text->SetPrivate(
true );
2425 if( !IsSymbol( token ) )
2427 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
2431 text->SetText( FromUTF8() );
2433 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2435 if( token != T_LEFT )
2436 Expecting( T_LEFT );
2453 case T_custom_property:
2458 Expecting(
"at or effects" );
2463 if( !
text->IsVisible() )
2466 return text.release();
2472 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
2473 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
2485 bool foundEnd =
false;
2486 bool foundSize =
false;
2487 bool foundMargins =
false;
2489 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>(
LAYER_DEVICE );
2491 textBox->SetUnit(
m_unit );
2495 if( token == T_private )
2497 textBox->SetPrivate(
true );
2501 if( !IsSymbol( token ) )
2503 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
2507 textBox->SetText( FromUTF8() );
2509 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2511 if( token != T_LEFT )
2512 Expecting( T_LEFT );
2543 textBox->SetStroke( stroke );
2549 textBox->SetFillColor( fill.
m_Color );
2554 textBox->SetMarginLeft(
left );
2555 textBox->SetMarginTop(
top );
2556 textBox->SetMarginRight(
right );
2557 textBox->SetMarginBottom( bottom );
2558 foundMargins =
true;
2566 case T_custom_property:
2571 Expecting(
"at, size, stroke, fill or effects" );
2575 textBox->SetPosition( pos );
2578 textBox->SetEnd(
end );
2579 else if( foundSize )
2580 textBox->SetEnd( pos + size );
2582 Expecting(
"size" );
2586 int margin = textBox->GetLegacyTextMargin();
2587 textBox->SetMarginLeft( margin );
2588 textBox->SetMarginTop( margin );
2589 textBox->SetMarginRight( margin );
2590 textBox->SetMarginBottom( margin );
2593 return textBox.release();
2599 wxCHECK_RET( ( CurTok() == T_page &&
m_requiredVersion <= 20200506 ) || CurTok() == T_paper,
2600 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a PAGE_INFO." ) );
2606 wxString pageType = FromUTF8();
2608 if( !aPageInfo.
SetType( pageType ) )
2610 THROW_PARSE_ERROR(
_(
"Invalid page type" ), CurSource(), CurLine(), CurLineNumber(),
2637 if( token == T_portrait )
2642 else if( token != T_RIGHT )
2644 Expecting(
"portrait" );
2651 wxCHECK_RET( CurTok() == T_title_block,
2652 "Cannot parse " + GetTokenString( CurTok() ) +
" as a TITLE_BLOCK." );
2656 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2658 if( token != T_LEFT )
2659 Expecting( T_LEFT );
2667 aTitleBlock.
SetTitle( FromUTF8() );
2672 aTitleBlock.
SetDate( FromUTF8() );
2687 int commentNumber =
parseInt(
"comment" );
2689 switch( commentNumber )
2738 CurLine(), CurLineNumber(), CurOffset() );
2745 Expecting(
"title, date, rev, company, or comment" );
2755 wxCHECK_MSG( CurTok() == T_property,
nullptr,
2756 "Cannot parse " + GetTokenString( CurTok() ) +
" as a property token." );
2758 bool is_private =
false;
2760 T token = NextTok();
2762 if( token == T_private )
2768 if( !IsSymbol( token ) )
2770 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
2774 wxString
name = FromUTF8();
2776 if(
name.IsEmpty() )
2778 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
2787 name = wxT(
"Netclass" );
2791 if( !IsSymbol( token ) )
2793 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
2801 value = wxEmptyString;
2833 if(
name.CmpNoCase( wxT(
"Sheet name" ) ) == 0 )
2835 else if(
name.CmpNoCase( wxT(
"Sheet file" ) ) == 0 )
2850 if(
name.CmpNoCase( wxT(
"Intersheet References" ) ) == 0 )
2854 std::unique_ptr<SCH_FIELD> field = std::make_unique<SCH_FIELD>( aParent, fieldId,
name );
2855 field->SetText( value );
2858 field->SetPrivate( is_private );
2860 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2862 if( token != T_LEFT )
2863 Expecting( T_LEFT );
2875 field->SetPosition(
parseXY() );
2893 field->SetNameShown( show );
2897 case T_do_not_autoplace:
2900 field->SetCanAutoplace( !doNotAutoplace );
2904 case T_custom_property:
2909 Expecting(
"id, at, hide, show_name, do_not_autoplace or effects" );
2913 return field.release();
2919 wxCHECK_MSG( aSheet !=
nullptr,
nullptr,
"" );
2920 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
2921 "Cannot parse " + GetTokenString( CurTok() ) +
" as a sheet pin token." );
2923 T token = NextTok();
2925 if( !IsSymbol( token ) )
2927 THROW_PARSE_ERROR(
_(
"Invalid sheet pin name" ), CurSource(), CurLine(), CurLineNumber(),
2931 wxString
name = FromUTF8();
2935 auto sheetPin = std::make_unique<SCH_SHEET_PIN>( aSheet,
VECTOR2I( 0, 0 ),
name );
2947 Expecting(
"input, output, bidirectional, tri_state, or passive" );
2950 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2952 if( token != T_LEFT )
2953 Expecting( T_LEFT );
2961 sheetPin->SetPosition(
parseXY() );
2963 double angle =
parseDouble(
"sheet pin angle (side)" );
2967 else if( angle == 90.0 )
2969 else if( angle == 180.0 )
2971 else if( angle == 270.0 )
2974 Expecting(
"0, 90, 180, or 270" );
2991 Expecting(
"at, uuid or effects" );
2995 return sheetPin.release();
3001 wxCHECK_RET( CurTok() == T_sheet_instances,
3002 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
3003 wxCHECK( aScreen, );
3007 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3009 if( token != T_LEFT )
3010 Expecting( T_LEFT );
3028 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3030 if( token != T_LEFT )
3031 Expecting( T_LEFT );
3035 std::vector<wxString> whitespaces = { wxT(
"\r" ), wxT(
"\n" ), wxT(
"\t" ),
3038 size_t numReplacements = 0;
3056 for(
const wxString& ch : whitespaces )
3057 numReplacements += instance.
m_PageNumber.Replace( ch, wxEmptyString );
3062 if( numReplacements > 0 )
3069 Expecting(
"path or page" );
3074 && ( instance.
m_Path.empty() ) )
3090 Expecting(
"path" );
3098 wxCHECK_RET( CurTok() == T_symbol_instances,
3099 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
3100 wxCHECK( aScreen, );
3105 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3107 if( token != T_LEFT )
3108 Expecting( T_LEFT );
3125 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3127 if( token != T_LEFT )
3128 Expecting( T_LEFT );
3149 instance.
m_Value = wxEmptyString;
3151 instance.
m_Value = FromUTF8();
3168 Expecting(
"path, unit, value or footprint" );
3177 Expecting(
"path" );
3186 wxCHECK( aSheet !=
nullptr, );
3190 wxCHECK( screen !=
nullptr, );
3193 m_maxError = schematic->Settings().m_MaxError;
3195 if( aIsCopyableOnly )
3198 bool fileHasUuid =
false;
3212 if( !aIsCopyableOnly )
3217 if( CurTok() != T_kicad_sch )
3218 Expecting(
"kicad_sch" );
3237 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3239 if( aIsCopyableOnly && token == T_EOF )
3242 if( token != T_LEFT )
3243 Expecting( T_LEFT );
3277 case T_generator_version:
3303 if( aIsCopyableOnly )
3304 Unexpected( T_paper );
3314 if( aIsCopyableOnly )
3315 Unexpected( T_page );
3319 NeedSYMBOLorNUMBER();
3320 NeedSYMBOLorNUMBER();
3327 if( aIsCopyableOnly )
3328 Unexpected( T_title_block );
3342 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3344 if( token != T_LEFT )
3345 Expecting( T_LEFT );
3357 Expecting(
"symbol" );
3414 THROW_PARSE_ERROR(
_(
"Schematic polyline has too few points" ), CurSource(), CurLine(),
3415 CurLineNumber(), CurOffset() );
3471 case T_netclass_flag:
3476 case T_global_label:
3477 case T_hierarchical_label:
3478 case T_directive_label:
3494 case T_sheet_instances:
3498 case T_symbol_instances:
3503 if( aIsCopyableOnly )
3504 Unexpected( T_bus_alias );
3509 case T_embedded_fonts:
3515 CurLineNumber(), CurOffset() );
3529 case T_embedded_files:
3535 CurLineNumber(), CurOffset() );
3538 embeddedFilesParser.SyncLineReaderWith( *
this );
3550 for(
int tok = embeddedFilesParser.NextTok();
3552 tok = embeddedFilesParser.NextTok() )
3556 else if( tok ==
DSN_RIGHT && --depth < 0 )
3561 SyncLineReaderWith( embeddedFilesParser );
3567 Expecting(
"arc, bezier, bitmap, bus, bus_alias, bus_entry, circle, class_label, "
3568 "directive_label, ellipse, ellipse_arc, embedded_fonts, embedded_files, "
3569 "global_label, hierarchical_label, image, junction, lib_symbols, "
3570 "netclass_flag, no_connect, polyline, rectangle, rule_area, sheet, "
3571 "sheet_instances, signal, symbol, symbol_instances, table, text, "
3572 "text_box, title_block, uuid, wire" );
3593 CurLineNumber(), CurOffset() );
3597 std::vector<std::string> fontNames;
3598 Fontconfig()->ListFonts( fontNames, std::string(
Pgm().GetLanguageTag().utf8_str() ),
3608 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
3609 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
3614 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
3616 std::set<int> fieldIDsRead;
3621 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3623 if( token != T_LEFT )
3624 Expecting( T_LEFT );
3636 if( !IsSymbol( token ) )
3639 CurLineNumber(), CurOffset() );
3642 libName = FromUTF8();
3646 libName.Replace(
"{slash}",
"/" );
3656 if( !IsSymbol( token ) && token != T_NUMBER )
3657 Expecting(
"symbol|number" );
3660 wxString
name = FromUTF8();
3664 name.Replace(
"{slash}",
"/" );
3670 if(
static_cast<int>(
name.size() ) > bad_pos )
3672 wxString msg = wxString::Format(
_(
"Symbol %s contains invalid character '%c'" ),
3680 CurLineNumber(), CurOffset() );
3683 symbol->SetLibId( libId );
3689 symbol->SetPosition(
parseXY() );
3691 switch(
static_cast<int>(
parseDouble(
"symbol orientation" ) ) )
3694 case 90: transform =
TRANSFORM( 0, 1, -1, 0 );
break;
3695 case 180: transform =
TRANSFORM( -1, 0, 0, -1 );
break;
3696 case 270: transform =
TRANSFORM( 0, -1, 1, 0 );
break;
3697 default: Expecting(
"0, 90, 180, or 270" );
3700 symbol->SetTransform( transform );
3709 else if( token == T_y )
3712 Expecting(
"x or y" );
3718 symbol->SetUnit(
parseInt(
"symbol unit" ) );
3724 symbol->SetBodyStyle(
parseInt(
"symbol body style" ) );
3728 case T_exclude_from_sim:
3729 symbol->SetExcludedFromSim(
parseBool() );
3734 symbol->SetExcludedFromBOM( !
parseBool() );
3739 symbol->SetExcludedFromBoard( !
parseBool() );
3743 case T_in_pos_files:
3744 symbol->SetExcludedFromPosFiles( !
parseBool() );
3766 if( !IsSymbol( t ) )
3767 Expecting(
"default, block or force" );
3769 wxString mode = FromUTF8();
3771 if( mode.IsSameAs( wxT(
"default"),
false ) )
3773 else if( mode.IsSameAs( wxT(
"block"),
false ) )
3775 else if( mode.IsSameAs( wxT(
"force"),
false ) )
3778 Expecting(
"default, block or force" );
3784 case T_fields_autoplaced:
3796 case T_default_instance:
3800 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3802 if( token != T_LEFT )
3803 Expecting( T_LEFT );
3824 symbol->SetValueFieldText( wxEmptyString );
3826 symbol->SetValueFieldText( FromUTF8() );
3835 symbol->SetFootprintFieldText( wxEmptyString );
3837 symbol->SetFootprintFieldText( FromUTF8() );
3843 Expecting(
"reference, unit, value or footprint" );
3852 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3854 if( token != T_LEFT )
3855 Expecting( T_LEFT );
3859 if( token != T_project )
3860 Expecting(
"project" );
3864 wxString projectName = FromUTF8();
3866 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3868 if( token != T_LEFT )
3869 Expecting( T_LEFT );
3873 if( token != T_path )
3874 Expecting(
"path" );
3883 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3885 if( token != T_LEFT )
3886 Expecting( T_LEFT );
3907 symbol->SetValueFieldText( wxEmptyString );
3909 symbol->SetValueFieldText( FromUTF8() );
3918 symbol->SetFootprintFieldText( wxEmptyString );
3920 symbol->SetFootprintFieldText( FromUTF8() );
3931 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3933 if( token != T_LEFT )
3934 Expecting( T_LEFT );
3942 variant.
m_Name = FromUTF8();
3951 case T_exclude_from_sim:
3973 case T_in_pos_files:
3981 wxString fieldValue;
3983 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3985 if( token != T_LEFT )
3986 Expecting( T_LEFT );
3994 fieldName = FromUTF8();
4000 fieldValue = FromUTF8();
4005 Expecting(
"name or value" );
4009 variant.
m_Fields[fieldName] = fieldValue;
4018 Expecting(
"dnp, exclude_from_sim, field, in_bom, in_pos_files, name, "
4019 "on_board, pin_map_override, or symbol_override" );
4029 Expecting(
"reference, unit, value, footprint, or variant" );
4033 symbol->AddHierarchicalReference( instance );
4049 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"0" ) );
4057 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"N" ) );
4065 existing = symbol->GetField( field->
GetId() );
4067 existing = symbol->GetField( field->
GetName() );
4073 wxString base_name = field->
GetName();
4076 for(
int ii = 1; ii < 10 && existing; ii++ )
4078 wxString newname = base_name;
4079 newname <<
'_' << ii;
4081 existing = symbol->GetField( newname );
4091 symbol->AddField( *field );
4094 symbol->UpdatePrefix();
4107 number = FromUTF8();
4109 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4111 if( token != T_LEFT )
4112 Expecting( T_LEFT );
4136 Expecting(
"alternate or uuid" );
4140 symbol->GetRawPins().emplace_back( std::make_unique<SCH_PIN>( symbol.get(), number,
4145 case T_custom_property:
4150 Expecting(
"lib_id, lib_name, at, mirror, uuid, exclude_from_sim, on_board, in_bom, dnp, passthrough, "
4151 "default_instance, property, pin, or instances" );
4155 if( !libName.IsEmpty() && ( symbol->GetLibId().Format().wx_str() != libName ) )
4156 symbol->SetSchSymbolLibraryName( libName );
4159 symbol->ClearFlags();
4161 return symbol.release();
4167 wxCHECK_MSG( CurTok() == T_image,
nullptr,
4168 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an image." ) );
4171 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>();
4174 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4176 if( token != T_LEFT )
4177 Expecting( T_LEFT );
4184 bitmap->SetPosition(
parseXY() );
4210 data.reserve( 1 << 17 );
4212 while( token != T_RIGHT )
4214 if( !IsSymbol( token ) )
4215 Expecting(
"base64 image data" );
4221 wxMemoryBuffer buffer = wxBase64Decode( data );
4234 case T_custom_property:
4239 Expecting(
"at, scale, uuid, data or locked" );
4257 int legacyPPI =
image.GetLegacyPPI();
4259 if( legacyPPI > 0 &&
image.GetPPI() != legacyPPI )
4263 return bitmap.release();
4269 wxCHECK_MSG( CurTok() == T_sheet,
nullptr,
4270 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a sheet." ) );
4276 std::vector<SCH_FIELD> fields;
4277 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>();
4278 std::set<int> fieldIDsRead;
4283 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4285 if( token != T_LEFT )
4286 Expecting( T_LEFT );
4293 sheet->SetPosition(
parseXY() );
4302 sheet->SetSize( size );
4307 case T_exclude_from_sim:
4308 sheet->SetExcludedFromSim(
parseBool() );
4313 sheet->SetExcludedFromBOM( !
parseBool() );
4318 sheet->SetExcludedFromBoard( !
parseBool() );
4332 case T_fields_autoplaced:
4340 sheet->SetBorderWidth( stroke.
GetWidth() );
4341 sheet->SetBorderColor( stroke.
GetColor() );
4346 sheet->SetBackgroundColor( fill.
m_Color );
4363 if( fields.empty() )
4369 fields.emplace_back( *field );
4380 std::vector<SCH_SHEET_INSTANCE> instances;
4382 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4384 if( token != T_LEFT )
4385 Expecting( T_LEFT );
4389 if( token != T_project )
4390 Expecting(
"project" );
4394 wxString projectName = FromUTF8();
4396 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4398 if( token != T_LEFT )
4399 Expecting( T_LEFT );
4403 if( token != T_path )
4404 Expecting(
"path" );
4413 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4415 if( token != T_LEFT )
4416 Expecting( T_LEFT );
4436 static std::vector<wxString> whitespaces =
4442 for( wxString ch : whitespaces )
4455 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4457 if( token != T_LEFT )
4458 Expecting( T_LEFT );
4466 variant.
m_Name = FromUTF8();
4475 case T_exclude_from_sim:
4497 case T_in_pos_files:
4505 wxString fieldValue;
4507 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4509 if( token != T_LEFT )
4510 Expecting( T_LEFT );
4518 fieldName = FromUTF8();
4524 fieldValue = FromUTF8();
4529 Expecting(
"name or value" );
4533 variant.
m_Fields[fieldName] = fieldValue;
4538 Expecting(
"dnp, exclude_from_sim, field, in_bom, in_pos_files, name, or on_board" );
4548 Expecting(
"page or variant" );
4552 instances.emplace_back( instance );
4556 sheet->setInstances( instances );
4560 case T_custom_property:
4565 Expecting(
"at, size, stroke, background, instances, uuid, property, or pin" );
4569 sheet->SetFields( fields );
4574 CurLineNumber(), CurOffset() );
4580 CurLineNumber(), CurOffset() );
4583 return sheet.release();
4589 wxCHECK_MSG( CurTok() == T_junction,
nullptr,
4590 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a junction." ) );
4593 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
4595 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4597 if( token != T_LEFT )
4598 Expecting( T_LEFT );
4605 junction->SetPosition(
parseXY() );
4621 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
4623 junction->SetColor( color );
4639 case T_custom_property:
4644 Expecting(
"at, diameter, color, uuid or locked" );
4648 return junction.release();
4654 wxCHECK_MSG( CurTok() == T_no_connect,
nullptr,
4655 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a no connect." ) );
4658 std::unique_ptr<SCH_NO_CONNECT> no_connect = std::make_unique<SCH_NO_CONNECT>();
4660 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4662 if( token != T_LEFT )
4663 Expecting( T_LEFT );
4670 no_connect->SetPosition(
parseXY() );
4685 case T_custom_property:
4690 Expecting(
"at, uuid or locked" );
4694 return no_connect.release();
4700 wxCHECK_MSG( CurTok() == T_bus_entry,
nullptr,
4701 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus entry." ) );
4705 std::unique_ptr<SCH_BUS_WIRE_ENTRY> busEntry = std::make_unique<SCH_BUS_WIRE_ENTRY>();
4707 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4709 if( token != T_LEFT )
4710 Expecting( T_LEFT );
4717 busEntry->SetPosition(
parseXY() );
4727 busEntry->SetSize( size );
4734 busEntry->SetStroke( stroke );
4748 case T_custom_property:
4753 Expecting(
"at, size, uuid, stroke or locked" );
4757 return busEntry.release();
4779 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4781 if( token != T_LEFT )
4782 Expecting( T_LEFT );
4789 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4791 if( token != T_LEFT )
4792 Expecting( T_LEFT );
4799 polyline->AddPoint(
parseXY() );
4812 polyline->SetStroke( stroke );
4818 polyline->SetFillColor( fill.
m_Color );
4826 polyline->SetStartEnding( ending );
4834 polyline->SetEndEnding( ending );
4849 default: Expecting(
"pts, uuid, stroke, fill, locked, start_shape, or end_shape" );
4853 if( polyline->GetFillMode() !=
FILL_T::NO_FILL && polyline->GetPolyShape().OutlineCount() > 0 )
4863 return polyline.release();
4882 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a line." );
4885 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>(
VECTOR2I(), layer );
4887 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4889 if( token != T_LEFT )
4890 Expecting( T_LEFT );
4903 line->SetStartPoint(
parseXY() );
4911 line->SetEndPoint(
parseXY() );
4918 line->SetStroke( stroke );
4925 line->SetStartEnding( ending );
4933 line->SetEndEnding( ending );
4948 case T_custom_property:
4952 default: Expecting(
"pts, uuid, stroke, locked, start_shape, or end_shape" );
4956 return line.release();
4962 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
4963 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
4971 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>(
SHAPE_T::ARC );
4973 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4975 if( token != T_LEFT )
4976 Expecting( T_LEFT );
4999 arc->SetStroke( stroke );
5005 arc->SetFillColor( fill.
m_Color );
5013 arc->SetStartEnding( ending );
5021 arc->SetEndEnding( ending );
5036 default: Expecting(
"start, mid, end, stroke, fill, locked, start_shape, end_shape, or uuid" );
5040 arc->SetArcGeometry( startPoint, midPoint, endPoint );
5042 return arc.release();
5048 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
5049 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
5058 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5060 if( token != T_LEFT )
5061 Expecting( T_LEFT );
5079 circle->SetStroke( stroke );
5101 Expecting(
"center, radius, stroke, fill, uuid or locked" );
5114 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
5115 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
5120 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>(
SHAPE_T::RECTANGLE );
5122 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5124 if( token != T_LEFT )
5125 Expecting( T_LEFT );
5132 rectangle->SetPosition(
parseXY() );
5137 rectangle->SetEnd(
parseXY() );
5148 rectangle->SetStroke( stroke );
5154 rectangle->SetFillColor( fill.
m_Color );
5170 Expecting(
"start, end, stroke, fill, uuid or locked" );
5174 return rectangle.release();
5180 wxCHECK_MSG( CurTok() == T_rule_area,
nullptr,
5181 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rule area." ) );
5186 std::unique_ptr<SCH_RULE_AREA> ruleArea = std::make_unique<SCH_RULE_AREA>();
5188 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5190 if( token != T_LEFT )
5191 Expecting( T_LEFT );
5205 ruleArea->SetPolyShape( sch_rule_poly );
5207 ruleArea->SetStroke( poly->GetStroke() );
5208 ruleArea->SetFillMode( poly->GetFillMode() );
5209 ruleArea->SetFillColor( poly->GetFillColor() );
5212 const_cast<KIID&
>( ruleArea->m_Uuid ) = poly->m_Uuid;
5216 case T_exclude_from_sim:
5217 ruleArea->SetExcludedFromSim(
parseBool() );
5222 ruleArea->SetExcludedFromBOM( !
parseBool() );
5227 ruleArea->SetExcludedFromBoard( !
parseBool() );
5241 case T_custom_property:
5246 Expecting(
"exclude_from_sim, on_board, in_bom, dnp, locked, or polyline" );
5250 return ruleArea.release();
5256 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
5257 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
5262 std::unique_ptr<SCH_SHAPE> bezier = std::make_unique<SCH_SHAPE>(
SHAPE_T::BEZIER );
5264 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5266 if( token != T_LEFT )
5267 Expecting( T_LEFT );
5277 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
5279 if( token != T_LEFT )
5280 Expecting( T_LEFT );
5289 case 0: bezier->SetStart(
parseXY() );
break;
5290 case 1: bezier->SetBezierC1(
parseXY() );
break;
5291 case 2: bezier->SetBezierC2(
parseXY() );
break;
5292 case 3: bezier->SetEnd(
parseXY() );
break;
5293 default: Unexpected(
"control point" );
break;
5303 bezier->SetStroke( stroke );
5309 bezier->SetFillColor( fill.
m_Color );
5317 bezier->SetStartEnding( ending );
5325 bezier->SetEndEnding( ending );
5340 default: Expecting(
"pts, stroke, fill, locked, start_shape, end_shape, or uuid" );
5344 bezier->RebuildBezierToSegmentsPointsList(
m_maxError );
5346 return bezier.release();
5351 TSCHEMATIC_T::T aFirstTok )
5357 int majorRadius = 1;
5358 int minorRadius = 1;
5365 for(
T token = aFirstTok; token != T_RIGHT; token = NextTok() )
5367 if( token != T_LEFT )
5368 Expecting( T_LEFT );
5380 case T_major_radius:
5385 case T_minor_radius:
5390 case T_rotation_angle:
5397 Expecting(
"start_angle only valid inside ellipse_arc" );
5404 Expecting(
"end_angle only valid inside ellipse_arc" );
5424 Expecting(
"uuid only valid in schematic context" );
5432 Expecting(
"locked only valid in schematic context" );
5438 Expecting(
"center, major_radius, minor_radius, rotation_angle, "
5439 "start_angle, end_angle, stroke, fill, uuid, or locked" );
5458 wxCHECK_MSG( CurTok() == T_ellipse,
nullptr,
5459 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an ellipse." ) );
5463 return ellipse.release();
5469 wxCHECK_MSG( CurTok() == T_ellipse_arc,
nullptr,
5470 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an elliptical arc." ) );
5474 return arc.release();
5481 std::unique_ptr<SCH_TEXT>
text;
5485 case T_text:
text = std::make_unique<SCH_TEXT>();
break;
5486 case T_label:
text = std::make_unique<SCH_LABEL>();
break;
5487 case T_global_label:
text = std::make_unique<SCH_GLOBALLABEL>();
break;
5488 case T_hierarchical_label:
text = std::make_unique<SCH_HIERLABEL>();
break;
5489 case T_netclass_flag:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
5490 case T_directive_label:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
5492 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as text." );
5500 text->SetText( FromUTF8() );
5502 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5504 if( token != T_LEFT )
5505 Expecting( T_LEFT );
5511 case T_exclude_from_sim:
5522 switch(
static_cast<int>( label->GetTextAngle().AsDegrees() ) )
5538 Unexpected( T_shape );
5556 Expecting(
"input, output, bidirectional, tri_state, passive, dot, round, diamond"
5567 Unexpected( T_length );
5576 case T_fields_autoplaced:
5586 text->SetVisible(
true );
5611 Unexpected( T_property );
5635 case T_custom_property:
5640 Expecting(
"at, shape, iref, uuid, effects or locked" );
5646 if( label && label->
GetFields().empty() )
5649 return text.release();
5655 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
5656 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
5658 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>();
5662 return textBox.release();
5668 wxCHECK_MSG( CurTok() == T_table_cell,
nullptr,
5669 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table cell." ) );
5671 std::unique_ptr<SCH_TABLECELL> cell = std::make_unique<SCH_TABLECELL>();
5675 return cell.release();
5691 bool foundEnd =
false;
5692 bool foundSize =
false;
5693 bool foundMargins =
false;
5697 aTextBox->
SetText( FromUTF8() );
5699 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5701 if( token != T_LEFT )
5702 Expecting( T_LEFT );
5708 case T_exclude_from_sim:
5739 cell->SetColSpan(
parseInt(
"column span" ) );
5740 cell->SetRowSpan(
parseInt(
"row span" ) );
5744 Expecting(
"at, size, stroke, fill, effects or uuid" );
5768 foundMargins =
true;
5787 case T_custom_property:
5793 Expecting(
"at, size, stroke, fill, effects, span, uuid or locked" );
5795 Expecting(
"at, size, stroke, fill, effects, uuid or locked" );
5803 else if( foundSize )
5804 aTextBox->
SetEnd( pos + size );
5806 Expecting(
"size" );
5821 wxCHECK_MSG( CurTok() == T_table,
nullptr,
5822 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table." ) );
5828 std::unique_ptr<SCH_TABLE>
table = std::make_unique<SCH_TABLE>( defaultLineWidth );
5830 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5832 if( token != T_LEFT )
5833 Expecting( T_LEFT );
5839 case T_column_count:
5844 case T_column_widths:
5848 while( ( token = NextTok() ) != T_RIGHT )
5858 while( ( token = NextTok() ) != T_RIGHT )
5865 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5867 if( token != T_LEFT )
5868 Expecting( T_LEFT );
5872 if( token != T_table_cell )
5873 Expecting(
"table_cell" );
5881 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5883 if( token != T_LEFT )
5884 Expecting( T_LEFT );
5902 table->SetBorderStroke( borderStroke );
5906 Expecting(
"external, header or stroke" );
5914 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5916 if( token != T_LEFT )
5917 Expecting( T_LEFT );
5935 table->SetSeparatorsStroke( separatorsStroke );
5939 Expecting(
"rows, cols, or stroke" );
5957 case T_custom_property:
5962 Expecting(
"columns, col_widths, row_heights, border, separators, uuid, locked, header or cells" );
5966 if( !
table->GetCell( 0, 0 ) )
5968 THROW_PARSE_ERROR(
_(
"Invalid table: no cells defined" ), CurSource(), CurLine(), CurLineNumber(),
5972 if(
table->GetColCount() <= 0 )
5974 THROW_PARSE_ERROR(
_(
"Invalid table: column count must be positive" ), CurSource(), CurLine(), CurLineNumber(),
5978 if(
table->GetCells().size() %
table->GetColCount() != 0 )
5980 THROW_PARSE_ERROR(
_(
"Invalid table: incomplete row" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
5983 return table.release();
5989 wxCHECK_RET( CurTok() == T_bus_alias,
5990 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus alias." ) );
5991 wxCHECK( aScreen, );
5994 std::shared_ptr<BUS_ALIAS> busAlias = std::make_shared<BUS_ALIAS>();
6005 busAlias->SetName( alias );
6010 if( token != T_members )
6011 Expecting(
"members" );
6015 while( token != T_RIGHT )
6017 if( !IsSymbol( token ) )
6018 Expecting(
"quoted string" );
6020 member = FromUTF8();
6025 busAlias->AddMember( member );
6046 wxString
name = FromUTF8();
6050 wxString fromRef, fromPin, toRef, toPin;
6051 std::set<wxString> memberNets;
6053 for(
T tok = NextTok(); tok != T_RIGHT; tok = NextTok() )
6060 NeedSYMBOLorNUMBER();
6062 NeedSYMBOLorNUMBER();
6066 else if( tok == T_to )
6068 NeedSYMBOLorNUMBER();
6070 NeedSYMBOLorNUMBER();
6074 else if( tok == T_net_class )
6076 NeedSYMBOLorNUMBER();
6077 netClass = FromUTF8();
6080 else if( tok == T_color )
6086 color =
COLOR4D( r / 255.0, g / 255.0, b / 255.0, al );
6089 else if( tok == T_nets )
6091 for(
T inner = NextTok(); inner != T_RIGHT; inner = NextTok() )
6093 if( !IsSymbol( inner ) && inner != T_NUMBER )
6094 Expecting(
"net name" );
6096 memberNets.insert( FromUTF8() );
6106 T inner = NextTok();
6108 if( inner == T_EOF )
6111 if( inner == T_LEFT )
6113 else if( inner == T_RIGHT )
6119 if( !fromRef.IsEmpty() && !toRef.IsEmpty() )
6124 if( !netClass.IsEmpty() )
6130 if( !memberNets.empty() )
6139 while( ( token = NextTok() ) != T_RIGHT )
6144 KIID uuid( CurStr() );
6152 wxCHECK_RET( CurTok() == T_group,
6153 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GROUP." ) );
6160 while( ( token = NextTok() ) != T_LEFT )
6162 if( token == T_STRING )
6163 groupInfo.
name = FromUTF8();
6165 Expecting(
"group name or locked" );
6168 for( ; token != T_RIGHT; token = NextTok() )
6170 if( token != T_LEFT )
6171 Expecting( T_LEFT );
6187 if( !IsSymbol( token ) && token != T_NUMBER )
6188 Expecting(
"symbol|number" );
6191 wxString
name = FromUTF8();
6195 name.Replace(
"{slash}",
"/" );
6201 if(
static_cast<int>(
name.size() ) > bad_pos )
6203 wxString msg = wxString::Format(
_(
"Group library link %s contains invalid character '%c'" ),
name,
6209 THROW_PARSE_ERROR(
_(
"Invalid library ID" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
6227 case T_custom_property:
6232 Expecting(
"uuid, lib_id, members, locked" );
6244 [&](
const KIID& aId )
6250 if( item->m_Uuid == aId )
6269 group->SetName( groupInfo.name );
6271 const_cast<KIID&
>(
group->m_Uuid ) = groupInfo.uuid;
6273 if( groupInfo.libId.IsValid() )
6274 group->SetDesignBlockLibId( groupInfo.libId );
6276 group->SetLocked( groupInfo.locked );
6277 group->SetCustomProperties( groupInfo.customProperties );
6288 for(
const KIID& aUuid : groupInfo.memberUuids )
6290 if(
SCH_ITEM* gItem = getItem( aUuid ) )
6291 group->AddItem( gItem );
6306 T token = NextTok();
6308 if( token == T_EOF )
6310 else if( token == T_LEFT )
6312 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.
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