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,
81 SCHEMATIC_LEXER( aLineReader ),
100 unsigned progressDelta = std::max( 50u,
m_lineCount / 10 );
119 KIID id( FromUTF8() );
136 else if( token == T_no )
139 Expecting(
"yes or no" );
150 bool ret = aDefaultValue;
152 if( PrevTok() == T_LEFT )
157 if(
static_cast<int>( token ) ==
DSN_RIGHT )
158 return aDefaultValue;
162 else if( token == T_no )
165 Expecting(
"yes or no" );
172 return aDefaultValue;
190 bool versionChecked =
false;
201 versionChecked =
true;
204 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
206 if( token != T_LEFT )
232 case T_generator_version:
255 aSymbolLibMap[symbol->
GetName()] = symbol;
260 wxString warning = wxString::Format(
261 _(
"Error parsing symbol at line %d: %s\nSkipping symbol and continuing." ),
262 CurLineNumber(), e.
What() );
274 Expecting(
"symbol, generator, or generator_version" );
288 if( CurTok() == T_LEFT )
292 if( CurTok() == T_symbol )
297 const std::vector<wxString>* embeddedFonts =
304 textItem->ResolveFont( embeddedFonts );
310 wxString msg = wxString::Format(
_(
"Cannot parse %s as a symbol" ),
311 GetTokenString( CurTok() ) );
322 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
323 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
330 std::unique_ptr<LIB_SYMBOL> symbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
332 symbol->SetUnitCount( 1,
true );
336 if( !IsSymbol( token ) )
337 THROW_PARSE_ERROR(
_(
"Invalid symbol name" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
344 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
351 if(
static_cast<int>(
name.size() ) > bad_pos )
353 wxString msg = wxString::Format(
_(
"Symbol %s contains invalid character '%c'" ),
362 CurLineNumber(), CurOffset() );
367 symbol->SetLibId(
id );
369 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
371 if( token != T_LEFT )
379 symbol->SetGlobalPower();
382 if( token == T_RIGHT )
385 if( token == T_local )
386 symbol->SetLocalPower();
387 else if( token != T_global )
388 Expecting(
"global or local" );
409 case T_exclude_from_sim:
410 symbol->SetExcludedFromSim(
parseBool() );
415 symbol->SetExcludedFromBOM( !
parseBool() );
420 symbol->SetExcludedFromBoard( !
parseBool() );
425 symbol->SetExcludedFromPosFiles( !
parseBool() );
429 case T_duplicate_pin_numbers_are_jumpers:
430 symbol->SetDuplicatePinNumbersAreJumpers(
parseBool() );
434 case T_jumper_pin_groups:
436 std::vector<std::set<wxString>>& groups = symbol->JumperPinGroups();
437 std::set<wxString>* currentGroup =
nullptr;
439 for( token = NextTok(); currentGroup || token != T_RIGHT; token = NextTok() )
441 switch(
static_cast<int>( token ) )
444 currentGroup = &groups.emplace_back();
448 currentGroup->insert( FromUTF8() );
452 currentGroup =
nullptr;
456 Expecting(
"list of pin names" );
471 if( !IsSymbol( token ) )
474 CurLineNumber(), CurOffset() );
482 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
484 symbol->SetParentName(
name );
493 if( !IsSymbol( token ) )
496 CurLineNumber(), CurOffset() );
504 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
508 error.Printf(
_(
"Invalid symbol unit name prefix %s" ),
name.c_str() );
509 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
514 wxStringTokenizer tokenizer(
name,
"_" );
516 if( tokenizer.CountTokens() != 2 )
518 error.Printf(
_(
"Invalid symbol unit name suffix %s" ),
name.c_str() );
519 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
522 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
524 error.Printf(
_(
"Invalid symbol unit number %s" ),
name.c_str() );
525 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
528 m_unit =
static_cast<int>( tmp );
530 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
532 error.Printf(
_(
"Invalid symbol body style number %s" ),
name.c_str() );
533 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
539 symbol->SetBodyStyleCount(
m_bodyStyle,
false,
false );
541 if(
m_unit > symbol->GetUnitCount() )
542 symbol->SetUnitCount(
m_unit,
false );
544 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
546 if( token != T_LEFT )
556 if( IsSymbol( token ) )
557 symbol->GetUnitDisplayNames()[
m_unit] = FromUTF8();
574 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
577 symbol->AddDrawItem( item,
false );
581 Expecting(
"arc, bezier, circle, ellipse, ellipse_arc, pin, polyline, "
582 "rectangle, or text" );
603 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
606 symbol->AddDrawItem( item,
false );
609 case T_embedded_fonts:
611 symbol->SetAreFontsEmbedded(
parseBool() );
616 case T_embedded_files:
619 embeddedFilesParser.SyncLineReaderWith( *
this );
623 embeddedFilesParser.
ParseEmbedded( symbol->GetEmbeddedFiles() );
631 for(
int tok = embeddedFilesParser.NextTok();
633 tok = embeddedFilesParser.NextTok() )
637 else if( tok ==
DSN_RIGHT && --depth < 0 )
642 SyncLineReaderWith( embeddedFilesParser );
647 Expecting(
"pin_names, pin_numbers, arc, bezier, circle, ellipse, ellipse_arc, "
648 "pin, polyline, rectangle, or text" );
652 symbol->GetDrawItems().sort();
655 const std::vector<wxString>* embeddedFonts = symbol->GetEmbeddedFiles()->UpdateFontFiles();
657 symbol->RunOnChildren(
661 textItem->ResolveFont( embeddedFonts );
668 symbol->SetHasDeMorganBodyStyles( symbol->HasLegacyAlternateBodyStyle() );
670 symbol->RefreshLibraryTreeCaches();
672 return symbol.release();
691 Expecting(
"arc, bezier, circle, ellipse, ellipse_arc, pin, "
692 "polyline, rectangle, or text" );
706 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
708 return KiROUND( std::clamp( retval, -int_limit, int_limit ) );
716 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
718 return KiROUND( std::clamp( retval, -int_limit, int_limit ) );
725 strokeParser.SyncLineReaderWith( *
this );
728 SyncLineReaderWith( strokeParser );
734 wxCHECK_RET( CurTok() == T_fill,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a fill." );
741 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
743 if( token != T_LEFT )
763 default: Expecting(
"none, outline, hatch, reverse_hatch, "
764 "cross_hatch, color or background" );
778 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
785 Expecting(
"type or color" );
792 bool aEnforceMinTextSize )
794 wxCHECK_RET( aText && ( CurTok() == T_effects || CurTok() == T_href ),
795 "Cannot parse " + GetTokenString( CurTok() ) +
" as an EDA_TEXT." );
812 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
814 if( token == T_LEFT )
820 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
822 if( token == T_LEFT )
862 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
873 Expecting(
"face, size, thickness, line_spacing, bold, or italic" );
880 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
889 case T_mirror:
break;
890 default: Expecting(
"left, right, top, bottom, or mirror" );
899 wxString hyperlink = FromUTF8();
904 CurSource(), CurLine(), CurLineNumber(), CurOffset() );
923 Expecting(
"font, justify, hide or href" );
931 if( CurTok() != aHeaderType )
934 GetTokenString( CurTok() ) ),
935 CurSource(), CurLine(), CurLineNumber(), CurOffset() );
942 if( tok == T_version )
956 wxCHECK_RET( CurTok() == T_body_styles,
957 "Cannot parse " + GetTokenString( CurTok() ) +
" as a body_styles token." );
959 std::vector<wxString> names;
961 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
963 if( token == T_demorgan )
965 aSymbol->SetHasDeMorganBodyStyles(
true );
968 else if( !IsSymbol( token ) )
970 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
974 names.push_back( FromUTF8() );
978 aSymbol->SetBodyStyleNames( names );
984 wxCHECK_RET( CurTok() == T_pin_names,
985 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_name token." );
995 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
998 if( token == T_hide )
1000 aSymbol->SetShowPinNames(
false );
1004 if( token != T_LEFT )
1006 Expecting( T_LEFT );
1019 aSymbol->SetShowPinNames( !
parseBool() );
1024 Expecting(
"offset or hide" );
1032 wxCHECK_RET( CurTok() == T_pin_numbers,
1033 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_number token." );
1042 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1045 if( token == T_hide )
1047 aSymbol->SetShowPinNumbers(
false );
1051 if( token != T_LEFT )
1053 Expecting( T_LEFT );
1061 aSymbol->SetShowPinNumbers( !
parseBool() );
1066 Expecting(
"hide" );
1075 wxCHECK_RET( CurTok() == T_associated_footprints,
1076 "Cannot parse " + GetTokenString( CurTok() ) +
" as an associated_footprints token." );
1085 std::vector<ASSOCIATED_FOOTPRINT> list;
1087 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1089 if( token != T_LEFT )
1090 Expecting( T_LEFT );
1094 if( token != T_footprint )
1095 Expecting(
"footprint" );
1099 if( !IsSymbol( token ) )
1100 Expecting(
"footprint library identifier" );
1105 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1107 if( token != T_LEFT )
1108 Expecting( T_LEFT );
1117 if( !IsSymbol( token ) )
1118 Expecting(
"map name" );
1124 default: Expecting(
"map" );
break;
1128 list.push_back( std::move( assoc ) );
1131 aSymbol->SetAssociatedFootprints( std::move( list ) );
1137 wxCHECK_RET( CurTok() == T_pin_maps,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_maps token." );
1148 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1150 if( token != T_LEFT )
1151 Expecting( T_LEFT );
1155 if( token != T_pin_map )
1156 Expecting(
"pin_map" );
1161 aSymbol->SetPinMaps( set );
1167 wxCHECK_MSG( CurTok() == T_pin_map,
PIN_MAP(),
1168 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_map token." );
1170 T token = NextTok();
1172 if( !IsSymbol( token ) )
1173 Expecting(
"pin map name" );
1177 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1179 if( token != T_LEFT )
1180 Expecting( T_LEFT );
1184 if( token != T_entry )
1185 Expecting(
"entry" );
1189 if( !IsSymbol( token ) )
1190 Expecting(
"pin number" );
1192 wxString pinNumber = FromUTF8();
1196 if( !IsSymbol( token ) )
1197 Expecting(
"pad number" );
1199 map.
SetEntry( pinNumber, FromUTF8() );
1211 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_map_override token." );
1223 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1225 if( token != T_LEFT )
1226 Expecting( T_LEFT );
1241 default: Expecting(
"library_default, named_map, identity, or delegate" );
1250 if( !IsSymbol( token ) )
1251 Expecting(
"map name" );
1253 override.m_ActiveMapName = FromUTF8();
1261 if( !IsSymbol( token ) )
1262 Expecting(
"pin number" );
1264 wxString pinNumber = FromUTF8();
1268 if( !IsSymbol( token ) )
1269 Expecting(
"pad number" );
1271 override.m_Edits.push_back( { pinNumber, FromUTF8() } );
1276 default: Expecting(
"mode, map, or edit" );
1286 wxCHECK_MSG( CurTok() == T_symbol_override,
LIB_ID(),
1287 "Cannot parse " + GetTokenString( CurTok() ) +
" as a symbol_override token." );
1289 T token = NextTok();
1291 if( !IsSymbol( token ) )
1292 Expecting(
"symbol LIB_ID" );
1294 wxString
name = FromUTF8();
1300 if(
static_cast<int>(
name.size() ) > bad_pos )
1302 wxString msg = wxString::Format(
_(
"Variant symbol override contains invalid character '%c'" ),
1308 THROW_PARSE_ERROR(
_(
"Invalid variant symbol override LIB_ID" ), CurSource(), CurLine(),
1309 CurLineNumber(), CurOffset() );
1319 wxCHECK_MSG( CurTok() == T_property,
nullptr,
1320 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a property." ) );
1321 wxCHECK( aSymbol,
nullptr );
1326 bool isPrivate =
false;
1327 bool isVisible =
true;
1329 T token = NextTok();
1331 if( token == T_private )
1337 if( !IsSymbol( token ) )
1339 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
1345 if(
name.IsEmpty() )
1347 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
1361 auto field = std::make_unique<SCH_FIELD>( aSymbol.get(), fieldId,
name );
1362 field->SetPrivate( isPrivate );
1363 field->SetVisible( isVisible );
1367 if( !IsSymbol( token ) )
1369 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
1376 value = wxEmptyString;
1380 field->SetText( value );
1382 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1384 if( token != T_LEFT )
1385 Expecting( T_LEFT );
1397 field->SetPosition(
parseXY(
true ) );
1415 field->SetNameShown( show );
1419 case T_do_not_autoplace:
1422 field->SetCanAutoplace( !doNotAutoplace );
1427 Expecting(
"id, at, hide, show_name, do_not_autoplace, or effects" );
1433 if( field->IsMandatory() )
1435 existingField = aSymbol->GetField( field->GetId() );
1437 *existingField = *field;
1438 return existingField;
1440 else if(
name ==
"ki_keywords" )
1443 aSymbol->SetKeyWords( value );
1447 else if(
name ==
"ki_description" )
1449 aSymbol->SetDescription( value );
1452 else if(
name ==
"ki_fp_filters" )
1455 wxArrayString filters;
1456 wxStringTokenizer tokenizer( value,
" \t\r\n", wxTOKEN_STRTOK );
1458 while( tokenizer.HasMoreTokens() )
1460 wxString curr_token =
UnescapeString( tokenizer.GetNextToken() );
1461 filters.Add( curr_token );
1464 aSymbol->SetFPFilters( filters );
1467 else if(
name ==
"ki_locked" )
1471 aSymbol->LockUnits(
true );
1477 existingField = aSymbol->GetField( field->GetCanonicalName() );
1485 wxString base_name = field->GetCanonicalName();
1488 for(
int ii = 1; ii < 10 && existingField; ii++ )
1490 wxString newname = base_name;
1491 newname <<
'_' << ii;
1493 existingField = aSymbol->GetField( newname );
1495 if( !existingField )
1496 field->SetName( newname );
1500 if( !existingField )
1502 aSymbol->AddDrawItem( field.get(),
false );
1503 return field.release();
1516 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
1517 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
1523 bool hasMidPoint =
false;
1531 bool hasAngles =
false;
1540 if( token == T_private )
1542 arc->SetPrivate(
true );
1546 for( ; token != T_RIGHT; token = NextTok() )
1548 if( token != T_LEFT )
1549 Expecting( T_LEFT );
1572 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1574 if( token != T_LEFT )
1575 Expecting( T_LEFT );
1603 Expecting(
"at, length, or angles" );
1611 arc->SetStroke( stroke );
1617 arc->SetFillColor( fill.
m_Color );
1621 Expecting(
"start, mid, end, radius, stroke, or fill" );
1627 arc->SetArcGeometry( startPoint, midPoint, endPoint );
1638 EDA_ANGLE arc_start, arc_end, arc_angle;
1639 arc->CalcArcAngles( arc_start, arc_end );
1640 arc_angle = arc_end - arc_start;
1645 arc->SetStart( endPoint );
1646 arc->SetEnd( startPoint );
1649 arc->SetCenter( new_center );
1655 arc->SetCenter( new_center );
1659 else if( hasAngles )
1661 arc->SetCenter(
center );
1667 arc->SetStart( endPoint );
1668 arc->SetEnd( startPoint );
1672 EDA_ANGLE arc_start, arc_end, arc_angle;
1673 arc->CalcArcAngles( arc_start, arc_end );
1674 arc_angle = arc_end - arc_start;
1680 arc->SetStart( startPoint );
1681 arc->SetEnd( endPoint );
1689 arc->SetStart( startPoint );
1690 arc->SetEnd( endPoint );
1694 arc->SetCenter( new_center );
1700 wxFAIL_MSG(
"Setting arc without either midpoint or angles not implemented." );
1703 return arc.release();
1709 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
1710 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
1718 bezier->SetUnit(
m_unit );
1723 if( token == T_private )
1725 bezier->SetPrivate(
true );
1729 for( ; token != T_RIGHT; token = NextTok() )
1731 if( token != T_LEFT )
1732 Expecting( T_LEFT );
1742 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
1744 if( token != T_LEFT )
1745 Expecting( T_LEFT );
1754 case 0: bezier->SetStart(
parseXY(
true ) );
break;
1755 case 1: bezier->SetBezierC1(
parseXY(
true ) );
break;
1756 case 2: bezier->SetBezierC2(
parseXY(
true ) );
break;
1757 case 3: bezier->SetEnd(
parseXY(
true ) );
break;
1758 default: Unexpected(
"control point" );
break;
1768 bezier->SetStroke( stroke );
1774 bezier->SetFillColor( fill.
m_Color );
1778 Expecting(
"pts, stroke, or fill" );
1782 bezier->RebuildBezierToSegmentsPointsList(
m_maxError );
1784 return bezier.release();
1790 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
1791 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
1806 if( token == T_private )
1808 circle->SetPrivate(
true );
1812 for( ; token != T_RIGHT; token = NextTok() )
1814 if( token != T_LEFT )
1815 Expecting( T_LEFT );
1833 circle->SetStroke( stroke );
1843 Expecting(
"center, radius, stroke, or fill" );
1856 wxCHECK_MSG( CurTok() == T_ellipse,
nullptr,
1857 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an ellipse." ) );
1860 ellipse->SetUnit(
m_unit );
1863 T token = NextTok();
1865 if( token == T_private )
1867 ellipse->SetPrivate(
true );
1872 return ellipse.release();
1878 wxCHECK_MSG( CurTok() == T_ellipse_arc,
nullptr,
1879 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an elliptical arc." ) );
1885 T token = NextTok();
1887 if( token == T_private )
1889 arc->SetPrivate(
true );
1894 return arc.release();
1920 Expecting(
"input, output, bidirectional, tri_state, passive, unspecified, "
1921 "power_in, power_out, open_collector, open_emitter, free or "
1943 Expecting(
"line, inverted, clock, inverted_clock, input_low, clock_low, "
1944 "output_low, edge_clock_high, non_logic" );
1949 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
1950 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a pin token." ) );
1953 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>(
nullptr );
1960 pin->SetType( parseType( token ) );
1964 pin->SetShape( parseShape( token ) );
1966 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1969 if( token == T_hide )
1971 pin->SetVisible(
false );
1975 if( token != T_LEFT )
1976 Expecting( T_LEFT );
1985 switch(
parseInt(
"pin orientation" ) )
1991 default: Expecting(
"0, 90, 180, or 270" );
2010 if( !IsSymbol( token ) )
2017 pin->SetName( wxEmptyString );
2021 pin->SetName( FromUTF8() );
2025 if( token != T_RIGHT )
2029 if( token == T_effects )
2036 pin->SetNameTextSize(
text.GetTextHeight() );
2041 Expecting(
"effects" );
2050 if( !IsSymbol( token ) )
2053 CurLineNumber(), CurOffset() );
2057 pin->SetNumber( wxEmptyString );
2061 pin->SetNumber( FromUTF8() );
2065 if( token != T_RIGHT )
2069 if( token == T_effects )
2076 pin->SetNumberTextSize(
text.GetTextHeight() );
2081 Expecting(
"effects" );
2093 if( !IsSymbol( token ) )
2096 CurLineNumber(), CurOffset() );
2102 alt.
m_Type = parseType( token );
2105 alt.
m_Shape = parseShape( token );
2107 pin->GetAlternates()[ alt.
m_Name ] = alt;
2114 Expecting(
"at, name, number, hide, length, or alternate" );
2118 return pin.release();
2124 wxCHECK_MSG( CurTok() == T_polyline,
nullptr,
2125 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a poly." ) );
2137 if( token == T_private )
2139 poly->SetPrivate(
true );
2143 for( ; token != T_RIGHT; token = NextTok() )
2145 if( token != T_LEFT )
2146 Expecting( T_LEFT );
2153 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2155 if( token != T_LEFT )
2156 Expecting( T_LEFT );
2163 poly->AddPoint(
parseXY(
true ) );
2172 poly->SetStroke( stroke );
2178 poly->SetFillColor( fill.
m_Color );
2182 Expecting(
"pts, stroke, or fill" );
2186 return poly.release();
2192 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
2193 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
2200 rectangle->SetUnit(
m_unit );
2205 if( token == T_private )
2207 rectangle->SetPrivate(
true );
2211 for( ; token != T_RIGHT; token = NextTok() )
2213 if( token != T_LEFT )
2214 Expecting( T_LEFT );
2221 rectangle->SetPosition(
parseXY(
true ) );
2226 rectangle->SetEnd(
parseXY(
true ) );
2237 rectangle->SetStroke( stroke );
2243 rectangle->SetFillColor( fill.
m_Color );
2247 Expecting(
"start, end, stroke, or fill" );
2251 return rectangle.release();
2257 wxCHECK_MSG( CurTok() == T_text,
nullptr,
2258 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text token." ) );
2261 std::unique_ptr<SCH_TEXT>
text = std::make_unique<SCH_TEXT>();
2268 if( token == T_private )
2270 text->SetPrivate(
true );
2274 if( !IsSymbol( token ) )
2276 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
2280 text->SetText( FromUTF8() );
2282 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2284 if( token != T_LEFT )
2285 Expecting( T_LEFT );
2303 Expecting(
"at or effects" );
2308 if( !
text->IsVisible() )
2311 return text.release();
2317 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
2318 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
2330 bool foundEnd =
false;
2331 bool foundSize =
false;
2332 bool foundMargins =
false;
2334 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>(
LAYER_DEVICE );
2336 textBox->SetUnit(
m_unit );
2340 if( token == T_private )
2342 textBox->SetPrivate(
true );
2346 if( !IsSymbol( token ) )
2348 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
2352 textBox->SetText( FromUTF8() );
2354 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2356 if( token != T_LEFT )
2357 Expecting( T_LEFT );
2388 textBox->SetStroke( stroke );
2394 textBox->SetFillColor( fill.
m_Color );
2399 textBox->SetMarginLeft(
left );
2400 textBox->SetMarginTop(
top );
2401 textBox->SetMarginRight(
right );
2402 textBox->SetMarginBottom( bottom );
2403 foundMargins =
true;
2412 Expecting(
"at, size, stroke, fill or effects" );
2416 textBox->SetPosition( pos );
2419 textBox->SetEnd(
end );
2420 else if( foundSize )
2421 textBox->SetEnd( pos + size );
2423 Expecting(
"size" );
2427 int margin = textBox->GetLegacyTextMargin();
2428 textBox->SetMarginLeft( margin );
2429 textBox->SetMarginTop( margin );
2430 textBox->SetMarginRight( margin );
2431 textBox->SetMarginBottom( margin );
2434 return textBox.release();
2440 wxCHECK_RET( ( CurTok() == T_page &&
m_requiredVersion <= 20200506 ) || CurTok() == T_paper,
2441 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a PAGE_INFO." ) );
2447 wxString pageType = FromUTF8();
2449 if( !aPageInfo.
SetType( pageType ) )
2451 THROW_PARSE_ERROR(
_(
"Invalid page type" ), CurSource(), CurLine(), CurLineNumber(),
2478 if( token == T_portrait )
2483 else if( token != T_RIGHT )
2485 Expecting(
"portrait" );
2492 wxCHECK_RET( CurTok() == T_title_block,
2493 "Cannot parse " + GetTokenString( CurTok() ) +
" as a TITLE_BLOCK." );
2497 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2499 if( token != T_LEFT )
2500 Expecting( T_LEFT );
2508 aTitleBlock.
SetTitle( FromUTF8() );
2513 aTitleBlock.
SetDate( FromUTF8() );
2528 int commentNumber =
parseInt(
"comment" );
2530 switch( commentNumber )
2579 CurLine(), CurLineNumber(), CurOffset() );
2586 Expecting(
"title, date, rev, company, or comment" );
2596 wxCHECK_MSG( CurTok() == T_property,
nullptr,
2597 "Cannot parse " + GetTokenString( CurTok() ) +
" as a property token." );
2599 bool is_private =
false;
2601 T token = NextTok();
2603 if( token == T_private )
2609 if( !IsSymbol( token ) )
2611 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
2615 wxString
name = FromUTF8();
2617 if(
name.IsEmpty() )
2619 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
2628 name = wxT(
"Netclass" );
2632 if( !IsSymbol( token ) )
2634 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
2642 value = wxEmptyString;
2674 if(
name.CmpNoCase( wxT(
"Sheet name" ) ) == 0 )
2676 else if(
name.CmpNoCase( wxT(
"Sheet file" ) ) == 0 )
2691 if(
name.CmpNoCase( wxT(
"Intersheet References" ) ) == 0 )
2695 std::unique_ptr<SCH_FIELD> field = std::make_unique<SCH_FIELD>( aParent, fieldId,
name );
2696 field->SetText( value );
2699 field->SetPrivate( is_private );
2701 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2703 if( token != T_LEFT )
2704 Expecting( T_LEFT );
2716 field->SetPosition(
parseXY() );
2734 field->SetNameShown( show );
2738 case T_do_not_autoplace:
2741 field->SetCanAutoplace( !doNotAutoplace );
2746 Expecting(
"id, at, hide, show_name, do_not_autoplace or effects" );
2750 return field.release();
2756 wxCHECK_MSG( aSheet !=
nullptr,
nullptr,
"" );
2757 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
2758 "Cannot parse " + GetTokenString( CurTok() ) +
" as a sheet pin token." );
2760 T token = NextTok();
2762 if( !IsSymbol( token ) )
2764 THROW_PARSE_ERROR(
_(
"Invalid sheet pin name" ), CurSource(), CurLine(), CurLineNumber(),
2768 wxString
name = FromUTF8();
2770 if(
name.IsEmpty() )
2772 THROW_PARSE_ERROR(
_(
"Empty sheet pin name" ), CurSource(), CurLine(), CurLineNumber(),
2776 auto sheetPin = std::make_unique<SCH_SHEET_PIN>( aSheet,
VECTOR2I( 0, 0 ),
name );
2788 Expecting(
"input, output, bidirectional, tri_state, or passive" );
2791 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2793 if( token != T_LEFT )
2794 Expecting( T_LEFT );
2802 sheetPin->SetPosition(
parseXY() );
2804 double angle =
parseDouble(
"sheet pin angle (side)" );
2808 else if( angle == 90.0 )
2810 else if( angle == 180.0 )
2812 else if( angle == 270.0 )
2815 Expecting(
"0, 90, 180, or 270" );
2832 Expecting(
"at, uuid or effects" );
2836 return sheetPin.release();
2842 wxCHECK_RET( CurTok() == T_sheet_instances,
2843 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
2844 wxCHECK( aScreen, );
2848 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2850 if( token != T_LEFT )
2851 Expecting( T_LEFT );
2869 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2871 if( token != T_LEFT )
2872 Expecting( T_LEFT );
2876 std::vector<wxString> whitespaces = { wxT(
"\r" ), wxT(
"\n" ), wxT(
"\t" ),
2879 size_t numReplacements = 0;
2897 for(
const wxString& ch : whitespaces )
2898 numReplacements += instance.
m_PageNumber.Replace( ch, wxEmptyString );
2903 if( numReplacements > 0 )
2910 Expecting(
"path or page" );
2915 && ( instance.
m_Path.empty() ) )
2931 Expecting(
"path" );
2939 wxCHECK_RET( CurTok() == T_symbol_instances,
2940 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
2941 wxCHECK( aScreen, );
2946 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2948 if( token != T_LEFT )
2949 Expecting( T_LEFT );
2966 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2968 if( token != T_LEFT )
2969 Expecting( T_LEFT );
2990 instance.
m_Value = wxEmptyString;
2992 instance.
m_Value = FromUTF8();
3009 Expecting(
"path, unit, value or footprint" );
3018 Expecting(
"path" );
3027 wxCHECK( aSheet !=
nullptr, );
3031 wxCHECK( screen !=
nullptr, );
3034 m_maxError = schematic->Settings().m_MaxError;
3036 if( aIsCopyableOnly )
3039 bool fileHasUuid =
false;
3053 if( !aIsCopyableOnly )
3058 if( CurTok() != T_kicad_sch )
3059 Expecting(
"kicad_sch" );
3078 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3080 if( aIsCopyableOnly && token == T_EOF )
3083 if( token != T_LEFT )
3084 Expecting( T_LEFT );
3118 case T_generator_version:
3144 if( aIsCopyableOnly )
3145 Unexpected( T_paper );
3155 if( aIsCopyableOnly )
3156 Unexpected( T_page );
3160 NeedSYMBOLorNUMBER();
3161 NeedSYMBOLorNUMBER();
3168 if( aIsCopyableOnly )
3169 Unexpected( T_title_block );
3183 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3185 if( token != T_LEFT )
3186 Expecting( T_LEFT );
3198 Expecting(
"symbol" );
3255 THROW_PARSE_ERROR(
_(
"Schematic polyline has too few points" ), CurSource(), CurLine(),
3256 CurLineNumber(), CurOffset() );
3310 case T_netclass_flag:
3315 case T_global_label:
3316 case T_hierarchical_label:
3317 case T_directive_label:
3333 case T_sheet_instances:
3337 case T_symbol_instances:
3342 if( aIsCopyableOnly )
3343 Unexpected( T_bus_alias );
3348 case T_embedded_fonts:
3354 CurLineNumber(), CurOffset() );
3356 schematic->GetEmbeddedFiles()->SetAreFontsEmbedded(
parseBool() );
3361 case T_embedded_files:
3367 CurLineNumber(), CurOffset() );
3370 embeddedFilesParser.SyncLineReaderWith( *
this );
3374 embeddedFilesParser.
ParseEmbedded( schematic->GetEmbeddedFiles() );
3382 for(
int tok = embeddedFilesParser.NextTok();
3384 tok = embeddedFilesParser.NextTok() )
3388 else if( tok ==
DSN_RIGHT && --depth < 0 )
3393 SyncLineReaderWith( embeddedFilesParser );
3399 Expecting(
"arc, bezier, bitmap, bus, bus_alias, bus_entry, circle, class_label, "
3400 "directive_label, ellipse, ellipse_arc, embedded_fonts, embedded_files, "
3401 "global_label, hierarchical_label, image, junction, lib_symbols, "
3402 "netclass_flag, no_connect, polyline, rectangle, rule_area, sheet, "
3403 "sheet_instances, signal, symbol, symbol_instances, table, text, "
3404 "text_box, title_block, uuid, wire" );
3425 CurLineNumber(), CurOffset() );
3429 std::vector<std::string> fontNames;
3430 Fontconfig()->ListFonts( fontNames, std::string(
Pgm().GetLanguageTag().utf8_str() ),
3431 schematic->GetEmbeddedFiles()->GetFontFiles(),
true );
3440 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
3441 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
3446 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
3448 std::set<int> fieldIDsRead;
3453 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3455 if( token != T_LEFT )
3456 Expecting( T_LEFT );
3468 if( !IsSymbol( token ) )
3471 CurLineNumber(), CurOffset() );
3474 libName = FromUTF8();
3478 libName.Replace(
"{slash}",
"/" );
3488 if( !IsSymbol( token ) && token != T_NUMBER )
3489 Expecting(
"symbol|number" );
3492 wxString
name = FromUTF8();
3496 name.Replace(
"{slash}",
"/" );
3502 if(
static_cast<int>(
name.size() ) > bad_pos )
3504 wxString msg = wxString::Format(
_(
"Symbol %s contains invalid character '%c'" ),
3512 CurLineNumber(), CurOffset() );
3515 symbol->SetLibId( libId );
3521 symbol->SetPosition(
parseXY() );
3523 switch(
static_cast<int>(
parseDouble(
"symbol orientation" ) ) )
3526 case 90: transform =
TRANSFORM( 0, 1, -1, 0 );
break;
3527 case 180: transform =
TRANSFORM( -1, 0, 0, -1 );
break;
3528 case 270: transform =
TRANSFORM( 0, -1, 1, 0 );
break;
3529 default: Expecting(
"0, 90, 180, or 270" );
3532 symbol->SetTransform( transform );
3541 else if( token == T_y )
3544 Expecting(
"x or y" );
3550 symbol->SetUnit(
parseInt(
"symbol unit" ) );
3556 symbol->SetBodyStyle(
parseInt(
"symbol body style" ) );
3560 case T_exclude_from_sim:
3561 symbol->SetExcludedFromSim(
parseBool() );
3566 symbol->SetExcludedFromBOM( !
parseBool() );
3571 symbol->SetExcludedFromBoard( !
parseBool() );
3575 case T_in_pos_files:
3576 symbol->SetExcludedFromPosFiles( !
parseBool() );
3598 if( !IsSymbol( t ) )
3599 Expecting(
"default, block or force" );
3601 wxString mode = FromUTF8();
3603 if( mode.IsSameAs( wxT(
"default"),
false ) )
3605 else if( mode.IsSameAs( wxT(
"block"),
false ) )
3607 else if( mode.IsSameAs( wxT(
"force"),
false ) )
3610 Expecting(
"default, block or force" );
3616 case T_fields_autoplaced:
3628 case T_default_instance:
3632 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3634 if( token != T_LEFT )
3635 Expecting( T_LEFT );
3656 symbol->SetValueFieldText( wxEmptyString );
3658 symbol->SetValueFieldText( FromUTF8() );
3667 symbol->SetFootprintFieldText( wxEmptyString );
3669 symbol->SetFootprintFieldText( FromUTF8() );
3675 Expecting(
"reference, unit, value or footprint" );
3684 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3686 if( token != T_LEFT )
3687 Expecting( T_LEFT );
3691 if( token != T_project )
3692 Expecting(
"project" );
3696 wxString projectName = FromUTF8();
3698 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3700 if( token != T_LEFT )
3701 Expecting( T_LEFT );
3705 if( token != T_path )
3706 Expecting(
"path" );
3715 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3717 if( token != T_LEFT )
3718 Expecting( T_LEFT );
3739 symbol->SetValueFieldText( wxEmptyString );
3741 symbol->SetValueFieldText( FromUTF8() );
3750 symbol->SetFootprintFieldText( wxEmptyString );
3752 symbol->SetFootprintFieldText( FromUTF8() );
3763 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3765 if( token != T_LEFT )
3766 Expecting( T_LEFT );
3774 variant.
m_Name = FromUTF8();
3783 case T_exclude_from_sim:
3805 case T_in_pos_files:
3813 wxString fieldValue;
3815 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3817 if( token != T_LEFT )
3818 Expecting( T_LEFT );
3826 fieldName = FromUTF8();
3832 fieldValue = FromUTF8();
3837 Expecting(
"name or value" );
3841 variant.
m_Fields[fieldName] = fieldValue;
3850 Expecting(
"dnp, exclude_from_sim, field, in_bom, in_pos_files, name, "
3851 "on_board, pin_map_override, or symbol_override" );
3861 Expecting(
"reference, unit, value, footprint, or variant" );
3865 symbol->AddHierarchicalReference( instance );
3881 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"0" ) );
3889 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"N" ) );
3897 existing = symbol->GetField( field->
GetId() );
3899 existing = symbol->GetField( field->
GetName() );
3904 symbol->AddField( *field );
3907 symbol->UpdatePrefix();
3920 number = FromUTF8();
3922 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3924 if( token != T_LEFT )
3925 Expecting( T_LEFT );
3949 Expecting(
"alternate or uuid" );
3953 symbol->GetRawPins().emplace_back( std::make_unique<SCH_PIN>( symbol.get(), number,
3959 Expecting(
"lib_id, lib_name, at, mirror, uuid, exclude_from_sim, on_board, in_bom, dnp, passthrough, "
3960 "default_instance, property, pin, or instances" );
3964 if( !libName.IsEmpty() && ( symbol->GetLibId().Format().wx_str() != libName ) )
3965 symbol->SetSchSymbolLibraryName( libName );
3968 symbol->ClearFlags();
3970 return symbol.release();
3976 wxCHECK_MSG( CurTok() == T_image,
nullptr,
3977 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an image." ) );
3980 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>();
3983 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3985 if( token != T_LEFT )
3986 Expecting( T_LEFT );
3993 bitmap->SetPosition(
parseXY() );
4019 data.reserve( 1 << 17 );
4021 while( token != T_RIGHT )
4023 if( !IsSymbol( token ) )
4024 Expecting(
"base64 image data" );
4030 wxMemoryBuffer buffer = wxBase64Decode( data );
4044 Expecting(
"at, scale, uuid, data or locked" );
4062 int legacyPPI =
image.GetLegacyPPI();
4064 if( legacyPPI > 0 &&
image.GetPPI() != legacyPPI )
4068 return bitmap.release();
4074 wxCHECK_MSG( CurTok() == T_sheet,
nullptr,
4075 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a sheet." ) );
4081 std::vector<SCH_FIELD> fields;
4082 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>();
4083 std::set<int> fieldIDsRead;
4088 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4090 if( token != T_LEFT )
4091 Expecting( T_LEFT );
4098 sheet->SetPosition(
parseXY() );
4107 sheet->SetSize( size );
4112 case T_exclude_from_sim:
4113 sheet->SetExcludedFromSim(
parseBool() );
4118 sheet->SetExcludedFromBOM( !
parseBool() );
4123 sheet->SetExcludedFromBoard( !
parseBool() );
4137 case T_fields_autoplaced:
4145 sheet->SetBorderWidth( stroke.
GetWidth() );
4146 sheet->SetBorderColor( stroke.
GetColor() );
4151 sheet->SetBackgroundColor( fill.
m_Color );
4168 if( fields.empty() )
4174 fields.emplace_back( *field );
4185 std::vector<SCH_SHEET_INSTANCE> instances;
4187 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4189 if( token != T_LEFT )
4190 Expecting( T_LEFT );
4194 if( token != T_project )
4195 Expecting(
"project" );
4199 wxString projectName = FromUTF8();
4201 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4203 if( token != T_LEFT )
4204 Expecting( T_LEFT );
4208 if( token != T_path )
4209 Expecting(
"path" );
4218 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4220 if( token != T_LEFT )
4221 Expecting( T_LEFT );
4241 static std::vector<wxString> whitespaces =
4247 for( wxString ch : whitespaces )
4260 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4262 if( token != T_LEFT )
4263 Expecting( T_LEFT );
4271 variant.
m_Name = FromUTF8();
4280 case T_exclude_from_sim:
4302 case T_in_pos_files:
4310 wxString fieldValue;
4312 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4314 if( token != T_LEFT )
4315 Expecting( T_LEFT );
4323 fieldName = FromUTF8();
4329 fieldValue = FromUTF8();
4334 Expecting(
"name or value" );
4338 variant.
m_Fields[fieldName] = fieldValue;
4343 Expecting(
"dnp, exclude_from_sim, field, in_bom, in_pos_files, name, or on_board" );
4353 Expecting(
"page or variant" );
4357 instances.emplace_back( instance );
4361 sheet->setInstances( instances );
4366 Expecting(
"at, size, stroke, background, instances, uuid, property, or pin" );
4370 sheet->SetFields( fields );
4375 CurLineNumber(), CurOffset() );
4381 CurLineNumber(), CurOffset() );
4384 return sheet.release();
4390 wxCHECK_MSG( CurTok() == T_junction,
nullptr,
4391 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a junction." ) );
4394 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
4396 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4398 if( token != T_LEFT )
4399 Expecting( T_LEFT );
4406 junction->SetPosition(
parseXY() );
4422 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
4424 junction->SetColor( color );
4441 Expecting(
"at, diameter, color, uuid or locked" );
4445 return junction.release();
4451 wxCHECK_MSG( CurTok() == T_no_connect,
nullptr,
4452 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a no connect." ) );
4455 std::unique_ptr<SCH_NO_CONNECT> no_connect = std::make_unique<SCH_NO_CONNECT>();
4457 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4459 if( token != T_LEFT )
4460 Expecting( T_LEFT );
4467 no_connect->SetPosition(
parseXY() );
4483 Expecting(
"at, uuid or locked" );
4487 return no_connect.release();
4493 wxCHECK_MSG( CurTok() == T_bus_entry,
nullptr,
4494 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus entry." ) );
4498 std::unique_ptr<SCH_BUS_WIRE_ENTRY> busEntry = std::make_unique<SCH_BUS_WIRE_ENTRY>();
4500 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4502 if( token != T_LEFT )
4503 Expecting( T_LEFT );
4510 busEntry->SetPosition(
parseXY() );
4520 busEntry->SetSize( size );
4527 busEntry->SetStroke( stroke );
4542 Expecting(
"at, size, uuid, stroke or locked" );
4546 return busEntry.release();
4568 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4570 if( token != T_LEFT )
4571 Expecting( T_LEFT );
4578 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4580 if( token != T_LEFT )
4581 Expecting( T_LEFT );
4588 polyline->AddPoint(
parseXY() );
4601 polyline->SetStroke( stroke );
4607 polyline->SetFillColor( fill.
m_Color );
4623 Expecting(
"pts, uuid, stroke, fill or locked" );
4627 return polyline.release();
4646 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a line." );
4649 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>(
VECTOR2I(), layer );
4651 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4653 if( token != T_LEFT )
4654 Expecting( T_LEFT );
4667 line->SetStartPoint(
parseXY() );
4675 line->SetEndPoint(
parseXY() );
4682 line->SetStroke( stroke );
4697 Expecting(
"pts, uuid, stroke or locked" );
4701 return line.release();
4707 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
4708 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
4716 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>(
SHAPE_T::ARC );
4718 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4720 if( token != T_LEFT )
4721 Expecting( T_LEFT );
4744 arc->SetStroke( stroke );
4750 arc->SetFillColor( fill.
m_Color );
4766 Expecting(
"start, mid, end, stroke, fill, uuid or locked" );
4770 arc->SetArcGeometry( startPoint, midPoint, endPoint );
4772 return arc.release();
4778 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
4779 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
4788 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4790 if( token != T_LEFT )
4791 Expecting( T_LEFT );
4809 circle->SetStroke( stroke );
4831 Expecting(
"center, radius, stroke, fill, uuid or locked" );
4844 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
4845 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
4850 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>(
SHAPE_T::RECTANGLE );
4852 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4854 if( token != T_LEFT )
4855 Expecting( T_LEFT );
4862 rectangle->SetPosition(
parseXY() );
4867 rectangle->SetEnd(
parseXY() );
4878 rectangle->SetStroke( stroke );
4884 rectangle->SetFillColor( fill.
m_Color );
4900 Expecting(
"start, end, stroke, fill, uuid or locked" );
4904 return rectangle.release();
4910 wxCHECK_MSG( CurTok() == T_rule_area,
nullptr,
4911 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rule area." ) );
4916 std::unique_ptr<SCH_RULE_AREA> ruleArea = std::make_unique<SCH_RULE_AREA>();
4918 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4920 if( token != T_LEFT )
4921 Expecting( T_LEFT );
4935 ruleArea->SetPolyShape( sch_rule_poly );
4937 ruleArea->SetStroke( poly->GetStroke() );
4938 ruleArea->SetFillMode( poly->GetFillMode() );
4939 ruleArea->SetFillColor( poly->GetFillColor() );
4942 const_cast<KIID&
>( ruleArea->m_Uuid ) = poly->m_Uuid;
4946 case T_exclude_from_sim:
4947 ruleArea->SetExcludedFromSim(
parseBool() );
4952 ruleArea->SetExcludedFromBOM( !
parseBool() );
4957 ruleArea->SetExcludedFromBoard( !
parseBool() );
4972 Expecting(
"exclude_from_sim, on_board, in_bom, dnp, locked, or polyline" );
4976 return ruleArea.release();
4982 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
4983 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
4988 std::unique_ptr<SCH_SHAPE> bezier = std::make_unique<SCH_SHAPE>(
SHAPE_T::BEZIER );
4990 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4992 if( token != T_LEFT )
4993 Expecting( T_LEFT );
5003 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
5005 if( token != T_LEFT )
5006 Expecting( T_LEFT );
5015 case 0: bezier->SetStart(
parseXY() );
break;
5016 case 1: bezier->SetBezierC1(
parseXY() );
break;
5017 case 2: bezier->SetBezierC2(
parseXY() );
break;
5018 case 3: bezier->SetEnd(
parseXY() );
break;
5019 default: Unexpected(
"control point" );
break;
5029 bezier->SetStroke( stroke );
5035 bezier->SetFillColor( fill.
m_Color );
5051 Expecting(
"pts, stroke, fill, uuid or locked" );
5055 bezier->RebuildBezierToSegmentsPointsList(
m_maxError );
5057 return bezier.release();
5062 TSCHEMATIC_T::T aFirstTok )
5068 int majorRadius = 1;
5069 int minorRadius = 1;
5076 for(
T token = aFirstTok; token != T_RIGHT; token = NextTok() )
5078 if( token != T_LEFT )
5079 Expecting( T_LEFT );
5091 case T_major_radius:
5096 case T_minor_radius:
5101 case T_rotation_angle:
5108 Expecting(
"start_angle only valid inside ellipse_arc" );
5115 Expecting(
"end_angle only valid inside ellipse_arc" );
5135 Expecting(
"uuid only valid in schematic context" );
5143 Expecting(
"locked only valid in schematic context" );
5149 Expecting(
"center, major_radius, minor_radius, rotation_angle, "
5150 "start_angle, end_angle, stroke, fill, uuid, or locked" );
5169 wxCHECK_MSG( CurTok() == T_ellipse,
nullptr,
5170 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an ellipse." ) );
5174 return ellipse.release();
5180 wxCHECK_MSG( CurTok() == T_ellipse_arc,
nullptr,
5181 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an elliptical arc." ) );
5185 return arc.release();
5192 std::unique_ptr<SCH_TEXT>
text;
5196 case T_text:
text = std::make_unique<SCH_TEXT>();
break;
5197 case T_label:
text = std::make_unique<SCH_LABEL>();
break;
5198 case T_global_label:
text = std::make_unique<SCH_GLOBALLABEL>();
break;
5199 case T_hierarchical_label:
text = std::make_unique<SCH_HIERLABEL>();
break;
5200 case T_netclass_flag:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
5201 case T_directive_label:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
5203 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as text." );
5211 text->SetText( FromUTF8() );
5213 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5215 if( token != T_LEFT )
5216 Expecting( T_LEFT );
5222 case T_exclude_from_sim:
5233 switch(
static_cast<int>( label->GetTextAngle().AsDegrees() ) )
5249 Unexpected( T_shape );
5267 Expecting(
"input, output, bidirectional, tri_state, passive, dot, round, diamond"
5278 Unexpected( T_length );
5287 case T_fields_autoplaced:
5297 text->SetVisible(
true );
5322 Unexpected( T_property );
5347 Expecting(
"at, shape, iref, uuid, effects or locked" );
5353 if( label && label->
GetFields().empty() )
5356 return text.release();
5362 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
5363 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
5365 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>();
5369 return textBox.release();
5375 wxCHECK_MSG( CurTok() == T_table_cell,
nullptr,
5376 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table cell." ) );
5378 std::unique_ptr<SCH_TABLECELL> cell = std::make_unique<SCH_TABLECELL>();
5382 return cell.release();
5398 bool foundEnd =
false;
5399 bool foundSize =
false;
5400 bool foundMargins =
false;
5404 aTextBox->
SetText( FromUTF8() );
5406 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5408 if( token != T_LEFT )
5409 Expecting( T_LEFT );
5415 case T_exclude_from_sim:
5446 cell->SetColSpan(
parseInt(
"column span" ) );
5447 cell->SetRowSpan(
parseInt(
"row span" ) );
5451 Expecting(
"at, size, stroke, fill, effects or uuid" );
5475 foundMargins =
true;
5496 Expecting(
"at, size, stroke, fill, effects, span, uuid or locked" );
5498 Expecting(
"at, size, stroke, fill, effects, uuid or locked" );
5506 else if( foundSize )
5507 aTextBox->
SetEnd( pos + size );
5509 Expecting(
"size" );
5524 wxCHECK_MSG( CurTok() == T_table,
nullptr,
5525 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table." ) );
5531 std::unique_ptr<SCH_TABLE>
table = std::make_unique<SCH_TABLE>( defaultLineWidth );
5533 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5535 if( token != T_LEFT )
5536 Expecting( T_LEFT );
5542 case T_column_count:
5547 case T_column_widths:
5551 while( ( token = NextTok() ) != T_RIGHT )
5561 while( ( token = NextTok() ) != T_RIGHT )
5568 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5570 if( token != T_LEFT )
5571 Expecting( T_LEFT );
5575 if( token != T_table_cell )
5576 Expecting(
"table_cell" );
5584 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5586 if( token != T_LEFT )
5587 Expecting( T_LEFT );
5605 table->SetBorderStroke( borderStroke );
5609 Expecting(
"external, header or stroke" );
5617 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5619 if( token != T_LEFT )
5620 Expecting( T_LEFT );
5638 table->SetSeparatorsStroke( separatorsStroke );
5642 Expecting(
"rows, cols, or stroke" );
5661 Expecting(
"columns, col_widths, row_heights, border, separators, uuid, locked, header or cells" );
5665 if( !
table->GetCell( 0, 0 ) )
5667 THROW_PARSE_ERROR(
_(
"Invalid table: no cells defined" ), CurSource(), CurLine(), CurLineNumber(),
5671 return table.release();
5677 wxCHECK_RET( CurTok() == T_bus_alias,
5678 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus alias." ) );
5679 wxCHECK( aScreen, );
5682 std::shared_ptr<BUS_ALIAS> busAlias = std::make_shared<BUS_ALIAS>();
5693 busAlias->SetName( alias );
5698 if( token != T_members )
5699 Expecting(
"members" );
5703 while( token != T_RIGHT )
5705 if( !IsSymbol( token ) )
5706 Expecting(
"quoted string" );
5708 member = FromUTF8();
5713 busAlias->AddMember( member );
5729 wxString
name = FromUTF8();
5733 wxString fromRef, fromPin, toRef, toPin;
5734 std::set<wxString> memberNets;
5736 for(
T tok = NextTok(); tok != T_RIGHT; tok = NextTok() )
5743 NeedSYMBOLorNUMBER();
5745 NeedSYMBOLorNUMBER();
5749 else if( tok == T_to )
5751 NeedSYMBOLorNUMBER();
5753 NeedSYMBOLorNUMBER();
5757 else if( tok == T_net_class )
5759 NeedSYMBOLorNUMBER();
5760 netClass = FromUTF8();
5763 else if( tok == T_color )
5769 color =
COLOR4D( r / 255.0, g / 255.0, b / 255.0, al );
5772 else if( tok == T_nets )
5774 for(
T inner = NextTok(); inner != T_RIGHT; inner = NextTok() )
5776 if( !IsSymbol( inner ) && inner != T_NUMBER )
5777 Expecting(
"net name" );
5779 memberNets.insert( FromUTF8() );
5789 T inner = NextTok();
5791 if( inner == T_EOF )
5794 if( inner == T_LEFT )
5796 else if( inner == T_RIGHT )
5802 if( !fromRef.IsEmpty() && !toRef.IsEmpty() )
5807 if( !netClass.IsEmpty() )
5813 if( !memberNets.empty() )
5822 while( ( token = NextTok() ) != T_RIGHT )
5827 KIID uuid( CurStr() );
5835 wxCHECK_RET( CurTok() == T_group,
5836 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GROUP." ) );
5843 while( ( token = NextTok() ) != T_LEFT )
5845 if( token == T_STRING )
5846 groupInfo.
name = FromUTF8();
5848 Expecting(
"group name or locked" );
5851 for( ; token != T_RIGHT; token = NextTok() )
5853 if( token != T_LEFT )
5854 Expecting( T_LEFT );
5870 if( !IsSymbol( token ) && token != T_NUMBER )
5871 Expecting(
"symbol|number" );
5874 wxString
name = FromUTF8();
5878 name.Replace(
"{slash}",
"/" );
5884 if(
static_cast<int>(
name.size() ) > bad_pos )
5886 wxString msg = wxString::Format(
_(
"Group library link %s contains invalid character '%c'" ),
name,
5892 THROW_PARSE_ERROR(
_(
"Invalid library ID" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
5911 Expecting(
"uuid, lib_id, members, locked" );
5923 [&](
const KIID& aId )
5929 if( item->m_Uuid == aId )
5948 group->SetName( groupInfo.name );
5950 const_cast<KIID&
>(
group->m_Uuid ) = groupInfo.uuid;
5952 if( groupInfo.libId.IsValid() )
5953 group->SetDesignBlockLibId( groupInfo.libId );
5955 group->SetLocked( groupInfo.locked );
5966 for(
const KIID& aUuid : groupInfo.memberUuids )
5968 if(
SCH_ITEM* gItem = getItem( aUuid ) )
5969 group->AddItem( gItem );
5984 T token = NextTok();
5986 if( token == T_EOF )
5988 else if( token == T_LEFT )
5990 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.
KICAD_T Type() const
Returns the type of object.
EDA_ITEM * GetParent() const
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)
virtual void SetEllipseStartAngle(const EDA_ANGLE &aA)
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 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.
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()
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
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.
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 GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
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 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)
SCH_SHAPE * parseSchBezier()
std::vector< wxString > m_parseWarnings
Non-fatal warnings collected during parsing.
SCH_JUNCTION * parseJunction()
void ParseSchematic(SCH_SHEET *aSheet, bool aIsCopyablyOnly=false, int aFileVersion=SEXPR_SCHEMATIC_FILE_VERSION)
Parse the internal LINE_READER object into aSheet.
SCH_SHEET_PIN * parseSchSheetPin(SCH_SHEET *aSheet)
int m_bodyStyle
The current body style being parsed.
SCH_NO_CONNECT * parseNoConnect()
SCH_SHAPE * parseSymbolArc()
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()
SCH_IO_KICAD_SEXPR_PARSER(LINE_READER *aLineReader=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr, unsigned aLineCount=0, SCH_SHEET *aRootSheet=nullptr, bool aIsAppending=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)
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.
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 SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given 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 wire 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
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
@ FILLED_WITH_BG_BODYCOLOR
@ FILLED_SHAPE
Fill with object color.
FONTCONFIG * Fontconfig()
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
#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.
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)
wxString From_UTF8(const char *cstring)
A filename or source description, a problem input line, a line number, a byte offset,...
Per-instance override of the active pin map and a sparse delta on top.
std::vector< KIID > memberUuids
ELECTRICAL_PINTYPE m_Type
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
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
wxString GetCanonicalFieldName(FIELD_T aFieldType)
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