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:
459 std::vector<std::set<wxString>>& groups = symbol->JumperPinGroups();
460 std::set<wxString>* currentGroup =
nullptr;
462 for( token = NextTok(); currentGroup || token != T_RIGHT; token = NextTok() )
464 switch(
static_cast<int>( token ) )
467 currentGroup = &groups.emplace_back();
471 currentGroup->insert( FromUTF8() );
475 currentGroup =
nullptr;
479 Expecting(
"list of pin names" );
494 if( !IsSymbol( token ) )
497 CurLineNumber(), CurOffset() );
505 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
507 symbol->SetParentName(
name );
516 if( !IsSymbol( token ) )
519 CurLineNumber(), CurOffset() );
527 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
531 error.Printf(
_(
"Invalid symbol unit name prefix %s" ),
name.c_str() );
532 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
537 wxStringTokenizer tokenizer(
name,
"_" );
539 if( tokenizer.CountTokens() != 2 )
541 error.Printf(
_(
"Invalid symbol unit name suffix %s" ),
name.c_str() );
542 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
545 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
547 error.Printf(
_(
"Invalid symbol unit number %s" ),
name.c_str() );
548 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
551 m_unit =
static_cast<int>( tmp );
553 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
555 error.Printf(
_(
"Invalid symbol body style number %s" ),
name.c_str() );
556 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
561 if(
m_unit > symbol->GetUnitCount() )
562 symbol->SetUnitCount(
m_unit,
false );
564 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
566 if( token != T_LEFT )
576 if( IsSymbol( token ) )
577 symbol->GetUnitDisplayNames()[
m_unit] = FromUTF8();
594 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
597 symbol->AddDrawItem( item,
false );
601 Expecting(
"arc, bezier, circle, ellipse, ellipse_arc, pin, polyline, "
602 "rectangle, or text" );
623 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
626 symbol->AddDrawItem( item,
false );
629 case T_embedded_fonts:
631 symbol->SetAreFontsEmbedded(
parseBool() );
636 case T_embedded_files:
639 embeddedFilesParser.SyncLineReaderWith( *
this );
643 embeddedFilesParser.
ParseEmbedded( symbol->GetEmbeddedFiles() );
651 for(
int tok = embeddedFilesParser.NextTok();
653 tok = embeddedFilesParser.NextTok() )
657 else if( tok ==
DSN_RIGHT && --depth < 0 )
662 SyncLineReaderWith( embeddedFilesParser );
667 Expecting(
"pin_names, pin_numbers, arc, bezier, circle, ellipse, ellipse_arc, "
668 "pin, polyline, rectangle, or text" );
672 symbol->GetDrawItems().sort();
675 const std::vector<wxString>* embeddedFonts = symbol->GetEmbeddedFiles()->UpdateFontFiles();
677 symbol->RunOnChildren(
681 textItem->ResolveFont( embeddedFonts );
689 symbol->SetHasDeMorganBodyStyles( symbol->HasLegacyAlternateBodyStyle() );
693 symbol->PruneBodyStyleDrawItems( symbol->GetBodyStyleCount() );
695 symbol->RefreshLibraryTreeCaches();
697 return symbol.release();
716 Expecting(
"arc, bezier, circle, ellipse, ellipse_arc, pin, "
717 "polyline, rectangle, or text" );
731 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
733 return KiROUND( std::clamp( retval, -int_limit, int_limit ) );
741 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
743 return KiROUND( std::clamp( retval, -int_limit, int_limit ) );
750 strokeParser.SyncLineReaderWith( *
this );
753 SyncLineReaderWith( strokeParser );
769 default: Expecting(
"arrow, circle, square, arrow_open, or none" );
773 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
775 if( token != T_LEFT )
800 default: Expecting(
"length, width, or stroke" );
808 wxCHECK_RET( CurTok() == T_fill,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a fill." );
815 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
817 if( token != T_LEFT )
837 default: Expecting(
"none, outline, hatch, reverse_hatch, "
838 "cross_hatch, color or background" );
852 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
859 Expecting(
"type or color" );
866 bool aEnforceMinTextSize )
868 wxCHECK_RET( aText && ( CurTok() == T_effects || CurTok() == T_href ),
869 "Cannot parse " + GetTokenString( CurTok() ) +
" as an EDA_TEXT." );
886 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
888 if( token == T_LEFT )
894 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
896 if( token == T_LEFT )
936 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
947 Expecting(
"face, size, thickness, line_spacing, bold, or italic" );
954 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
963 case T_mirror:
break;
964 default: Expecting(
"left, right, top, bottom, or mirror" );
973 wxString hyperlink = FromUTF8();
978 CurSource(), CurLine(), CurLineNumber(), CurOffset() );
997 Expecting(
"font, justify, hide or href" );
1008 if( CurTok() != aHeaderType )
1011 GetTokenString( CurTok() ) ),
1012 CurSource(), CurLine(), CurLineNumber(), CurOffset() );
1019 if( tok == T_version )
1033 wxCHECK_RET( CurTok() == T_body_styles,
1034 "Cannot parse " + GetTokenString( CurTok() ) +
" as a body_styles token." );
1036 std::vector<wxString> names;
1038 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1040 if( token == T_demorgan )
1042 aSymbol->SetHasDeMorganBodyStyles(
true );
1045 else if( !IsSymbol( token ) )
1047 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
1051 names.push_back( FromUTF8() );
1054 if( !names.empty() )
1055 aSymbol->SetBodyStyleNames( names );
1061 wxCHECK_RET( CurTok() == T_pin_names,
1062 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_name token." );
1072 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1075 if( token == T_hide )
1077 aSymbol->SetShowPinNames(
false );
1081 if( token != T_LEFT )
1083 Expecting( T_LEFT );
1096 aSymbol->SetShowPinNames( !
parseBool() );
1101 Expecting(
"offset or hide" );
1109 wxCHECK_RET( CurTok() == T_pin_numbers,
1110 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_number token." );
1119 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1122 if( token == T_hide )
1124 aSymbol->SetShowPinNumbers(
false );
1128 if( token != T_LEFT )
1130 Expecting( T_LEFT );
1138 aSymbol->SetShowPinNumbers( !
parseBool() );
1143 Expecting(
"hide" );
1152 wxCHECK_RET( CurTok() == T_associated_footprints,
1153 "Cannot parse " + GetTokenString( CurTok() ) +
" as an associated_footprints token." );
1162 std::vector<ASSOCIATED_FOOTPRINT> list;
1164 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1166 if( token != T_LEFT )
1167 Expecting( T_LEFT );
1171 if( token != T_footprint )
1172 Expecting(
"footprint" );
1176 if( !IsSymbol( token ) )
1177 Expecting(
"footprint library identifier" );
1182 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1184 if( token != T_LEFT )
1185 Expecting( T_LEFT );
1194 if( !IsSymbol( token ) )
1195 Expecting(
"map name" );
1201 default: Expecting(
"map" );
break;
1205 list.push_back( std::move( assoc ) );
1208 aSymbol->SetAssociatedFootprints( std::move( list ) );
1214 wxCHECK_RET( CurTok() == T_pin_maps,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_maps token." );
1225 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1227 if( token != T_LEFT )
1228 Expecting( T_LEFT );
1232 if( token != T_pin_map )
1233 Expecting(
"pin_map" );
1238 aSymbol->SetPinMaps( set );
1244 wxCHECK_MSG( CurTok() == T_pin_map,
PIN_MAP(),
1245 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_map token." );
1247 T token = NextTok();
1249 if( !IsSymbol( token ) )
1250 Expecting(
"pin map name" );
1254 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1256 if( token != T_LEFT )
1257 Expecting( T_LEFT );
1261 if( token != T_entry )
1262 Expecting(
"entry" );
1266 if( !IsSymbol( token ) )
1267 Expecting(
"pin number" );
1269 wxString pinNumber = FromUTF8();
1273 if( !IsSymbol( token ) )
1274 Expecting(
"pad number" );
1276 map.
SetEntry( pinNumber, FromUTF8() );
1288 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_map_override token." );
1300 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1302 if( token != T_LEFT )
1303 Expecting( T_LEFT );
1318 default: Expecting(
"library_default, named_map, identity, or delegate" );
1327 if( !IsSymbol( token ) )
1328 Expecting(
"map name" );
1330 override.m_ActiveMapName = FromUTF8();
1338 if( !IsSymbol( token ) )
1339 Expecting(
"pin number" );
1341 wxString pinNumber = FromUTF8();
1345 if( !IsSymbol( token ) )
1346 Expecting(
"pad number" );
1348 override.m_Edits.push_back( { pinNumber, FromUTF8() } );
1353 default: Expecting(
"mode, map, or edit" );
1363 wxCHECK_MSG( CurTok() == T_symbol_override,
LIB_ID(),
1364 "Cannot parse " + GetTokenString( CurTok() ) +
" as a symbol_override token." );
1366 T token = NextTok();
1368 if( !IsSymbol( token ) )
1369 Expecting(
"symbol LIB_ID" );
1371 wxString
name = FromUTF8();
1377 if(
static_cast<int>(
name.size() ) > bad_pos )
1379 wxString msg = wxString::Format(
_(
"Variant symbol override contains invalid character '%c'" ),
1385 THROW_PARSE_ERROR(
_(
"Invalid variant symbol override LIB_ID" ), CurSource(), CurLine(),
1386 CurLineNumber(), CurOffset() );
1396 wxCHECK_MSG( CurTok() == T_property,
nullptr,
1397 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a property." ) );
1398 wxCHECK( aSymbol,
nullptr );
1403 bool isPrivate =
false;
1404 bool isVisible =
true;
1406 T token = NextTok();
1408 if( token == T_private )
1414 if( !IsSymbol( token ) )
1416 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
1422 if(
name.IsEmpty() )
1424 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
1438 auto field = std::make_unique<SCH_FIELD>( aSymbol.get(), fieldId,
name );
1439 field->SetPrivate( isPrivate );
1440 field->SetVisible( isVisible );
1444 if( !IsSymbol( token ) )
1446 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
1453 value = wxEmptyString;
1457 field->SetText( value );
1459 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1461 if( token != T_LEFT )
1462 Expecting( T_LEFT );
1474 field->SetPosition(
parseXY(
true ) );
1492 field->SetNameShown( show );
1496 case T_do_not_autoplace:
1499 field->SetCanAutoplace( !doNotAutoplace );
1503 case T_custom_property:
1508 Expecting(
"id, at, hide, show_name, do_not_autoplace, or effects" );
1514 if( field->IsMandatory() )
1516 existingField = aSymbol->GetField( field->GetId() );
1518 *existingField = *field;
1519 return existingField;
1521 else if(
name ==
"ki_keywords" )
1524 aSymbol->SetKeyWords( value );
1528 else if(
name ==
"ki_description" )
1530 aSymbol->SetDescription( value );
1533 else if(
name ==
"ki_fp_filters" )
1536 wxArrayString filters;
1537 wxStringTokenizer tokenizer( value,
" \t\r\n", wxTOKEN_STRTOK );
1539 while( tokenizer.HasMoreTokens() )
1541 wxString curr_token =
UnescapeString( tokenizer.GetNextToken() );
1542 filters.Add( curr_token );
1545 aSymbol->SetFPFilters( filters );
1548 else if(
name ==
"ki_locked" )
1552 aSymbol->LockUnits(
true );
1558 existingField = aSymbol->GetField( field->GetUntranslatedName() );
1566 wxString base_name = field->GetUntranslatedName();
1569 for(
int ii = 1; ii < 10 && existingField; ii++ )
1571 wxString newname = base_name;
1572 newname <<
'_' << ii;
1574 existingField = aSymbol->GetField( newname );
1576 if( !existingField )
1577 field->SetName( newname );
1581 if( !existingField )
1583 aSymbol->AddDrawItem( field.get(),
false );
1584 return field.release();
1597 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
1598 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
1604 bool hasMidPoint =
false;
1612 bool hasAngles =
false;
1621 if( token == T_private )
1623 arc->SetPrivate(
true );
1627 for( ; token != T_RIGHT; token = NextTok() )
1629 if( token != T_LEFT )
1630 Expecting( T_LEFT );
1653 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1655 if( token != T_LEFT )
1656 Expecting( T_LEFT );
1684 Expecting(
"at, length, or angles" );
1692 arc->SetStroke( stroke );
1698 arc->SetFillColor( fill.
m_Color );
1705 arc->SetStartEnding( ending );
1713 arc->SetEndEnding( ending );
1717 default: Expecting(
"start, mid, end, radius, stroke, fill, start_shape, or end_shape" );
1723 arc->SetArcGeometry( startPoint, midPoint, endPoint );
1734 EDA_ANGLE arc_start, arc_end, arc_angle;
1735 arc->CalcArcAngles( arc_start, arc_end );
1736 arc_angle = arc_end - arc_start;
1741 arc->SetStart( endPoint );
1742 arc->SetEnd( startPoint );
1745 arc->SetCenter( new_center );
1751 arc->SetCenter( new_center );
1755 else if( hasAngles )
1757 arc->SetCenter(
center );
1763 arc->SetStart( endPoint );
1764 arc->SetEnd( startPoint );
1768 EDA_ANGLE arc_start, arc_end, arc_angle;
1769 arc->CalcArcAngles( arc_start, arc_end );
1770 arc_angle = arc_end - arc_start;
1776 arc->SetStart( startPoint );
1777 arc->SetEnd( endPoint );
1785 arc->SetStart( startPoint );
1786 arc->SetEnd( endPoint );
1790 arc->SetCenter( new_center );
1796 wxFAIL_MSG(
"Setting arc without either midpoint or angles not implemented." );
1799 return arc.release();
1805 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
1806 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
1814 bezier->SetUnit(
m_unit );
1819 if( token == T_private )
1821 bezier->SetPrivate(
true );
1825 for( ; token != T_RIGHT; token = NextTok() )
1827 if( token != T_LEFT )
1828 Expecting( T_LEFT );
1838 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
1840 if( token != T_LEFT )
1841 Expecting( T_LEFT );
1850 case 0: bezier->SetStart(
parseXY(
true ) );
break;
1851 case 1: bezier->SetBezierC1(
parseXY(
true ) );
break;
1852 case 2: bezier->SetBezierC2(
parseXY(
true ) );
break;
1853 case 3: bezier->SetEnd(
parseXY(
true ) );
break;
1854 default: Unexpected(
"control point" );
break;
1864 bezier->SetStroke( stroke );
1870 bezier->SetFillColor( fill.
m_Color );
1877 bezier->SetStartEnding( ending );
1885 bezier->SetEndEnding( ending );
1889 default: Expecting(
"pts, stroke, fill, start_shape, or end_shape" );
1893 bezier->RebuildBezierToSegmentsPointsList(
m_maxError );
1895 return bezier.release();
1901 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
1902 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
1917 if( token == T_private )
1919 circle->SetPrivate(
true );
1923 for( ; token != T_RIGHT; token = NextTok() )
1925 if( token != T_LEFT )
1926 Expecting( T_LEFT );
1944 circle->SetStroke( stroke );
1954 Expecting(
"center, radius, stroke, or fill" );
1967 wxCHECK_MSG( CurTok() == T_ellipse,
nullptr,
1968 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an ellipse." ) );
1971 ellipse->SetUnit(
m_unit );
1974 T token = NextTok();
1976 if( token == T_private )
1978 ellipse->SetPrivate(
true );
1983 return ellipse.release();
1989 wxCHECK_MSG( CurTok() == T_ellipse_arc,
nullptr,
1990 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an elliptical arc." ) );
1996 T token = NextTok();
1998 if( token == T_private )
2000 arc->SetPrivate(
true );
2005 return arc.release();
2031 Expecting(
"input, output, bidirectional, tri_state, passive, unspecified, "
2032 "power_in, power_out, open_collector, open_emitter, free or "
2054 Expecting(
"line, inverted, clock, inverted_clock, input_low, clock_low, "
2055 "output_low, edge_clock_high, non_logic" );
2060 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
2061 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a pin token." ) );
2064 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>(
nullptr );
2071 pin->SetType( parseType( token ) );
2075 pin->SetShape( parseShape( token ) );
2077 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2080 if( token == T_hide )
2082 pin->SetVisible(
false );
2086 if( token != T_LEFT )
2087 Expecting( T_LEFT );
2096 switch(
parseInt(
"pin orientation" ) )
2102 default: Expecting(
"0, 90, 180, or 270" );
2121 if( !IsSymbol( token ) )
2128 pin->SetName( wxEmptyString );
2132 pin->SetName( FromUTF8() );
2136 if( token != T_RIGHT )
2140 if( token == T_effects )
2147 pin->SetNameTextSize(
text.GetTextHeight() );
2152 Expecting(
"effects" );
2161 if( !IsSymbol( token ) )
2164 CurLineNumber(), CurOffset() );
2168 pin->SetNumber( wxEmptyString );
2172 pin->SetNumber( FromUTF8() );
2176 if( token != T_RIGHT )
2180 if( token == T_effects )
2187 pin->SetNumberTextSize(
text.GetTextHeight() );
2192 Expecting(
"effects" );
2204 if( !IsSymbol( token ) )
2207 CurLineNumber(), CurOffset() );
2213 alt.
m_Type = parseType( token );
2216 alt.
m_Shape = parseShape( token );
2218 pin->GetAlternates()[ alt.
m_Name ] = alt;
2224 case T_custom_property:
2229 Expecting(
"at, name, number, hide, length, or alternate" );
2233 return pin.release();
2239 wxCHECK_MSG( CurTok() == T_polyline,
nullptr,
2240 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a poly." ) );
2252 if( token == T_private )
2254 poly->SetPrivate(
true );
2258 for( ; token != T_RIGHT; token = NextTok() )
2260 if( token != T_LEFT )
2261 Expecting( T_LEFT );
2268 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2270 if( token != T_LEFT )
2271 Expecting( T_LEFT );
2278 poly->AddPoint(
parseXY(
true ) );
2287 poly->SetStroke( stroke );
2293 poly->SetFillColor( fill.
m_Color );
2300 poly->SetStartEnding( ending );
2308 poly->SetEndEnding( ending );
2312 default: Expecting(
"pts, stroke, fill, start_shape, or end_shape" );
2316 if( poly->GetFillMode() !=
FILL_T::NO_FILL && poly->GetPolyShape().OutlineCount() > 0 )
2326 return poly.release();
2332 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
2333 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
2340 rectangle->SetUnit(
m_unit );
2345 if( token == T_private )
2347 rectangle->SetPrivate(
true );
2351 for( ; token != T_RIGHT; token = NextTok() )
2353 if( token != T_LEFT )
2354 Expecting( T_LEFT );
2361 rectangle->SetPosition(
parseXY(
true ) );
2366 rectangle->SetEnd(
parseXY(
true ) );
2377 rectangle->SetStroke( stroke );
2383 rectangle->SetFillColor( fill.
m_Color );
2387 Expecting(
"start, end, stroke, or fill" );
2391 return rectangle.release();
2397 wxCHECK_MSG( CurTok() == T_text,
nullptr,
2398 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text token." ) );
2401 std::unique_ptr<SCH_TEXT>
text = std::make_unique<SCH_TEXT>();
2408 if( token == T_private )
2410 text->SetPrivate(
true );
2414 if( !IsSymbol( token ) )
2416 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
2420 text->SetText( FromUTF8() );
2422 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2424 if( token != T_LEFT )
2425 Expecting( T_LEFT );
2442 case T_custom_property:
2447 Expecting(
"at or effects" );
2452 if( !
text->IsVisible() )
2455 return text.release();
2461 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
2462 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
2474 bool foundEnd =
false;
2475 bool foundSize =
false;
2476 bool foundMargins =
false;
2478 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>(
LAYER_DEVICE );
2480 textBox->SetUnit(
m_unit );
2484 if( token == T_private )
2486 textBox->SetPrivate(
true );
2490 if( !IsSymbol( token ) )
2492 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
2496 textBox->SetText( FromUTF8() );
2498 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2500 if( token != T_LEFT )
2501 Expecting( T_LEFT );
2532 textBox->SetStroke( stroke );
2538 textBox->SetFillColor( fill.
m_Color );
2543 textBox->SetMarginLeft(
left );
2544 textBox->SetMarginTop(
top );
2545 textBox->SetMarginRight(
right );
2546 textBox->SetMarginBottom( bottom );
2547 foundMargins =
true;
2555 case T_custom_property:
2560 Expecting(
"at, size, stroke, fill or effects" );
2564 textBox->SetPosition( pos );
2567 textBox->SetEnd(
end );
2568 else if( foundSize )
2569 textBox->SetEnd( pos + size );
2571 Expecting(
"size" );
2575 int margin = textBox->GetLegacyTextMargin();
2576 textBox->SetMarginLeft( margin );
2577 textBox->SetMarginTop( margin );
2578 textBox->SetMarginRight( margin );
2579 textBox->SetMarginBottom( margin );
2582 return textBox.release();
2588 wxCHECK_RET( ( CurTok() == T_page &&
m_requiredVersion <= 20200506 ) || CurTok() == T_paper,
2589 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a PAGE_INFO." ) );
2595 wxString pageType = FromUTF8();
2597 if( !aPageInfo.
SetType( pageType ) )
2599 THROW_PARSE_ERROR(
_(
"Invalid page type" ), CurSource(), CurLine(), CurLineNumber(),
2626 if( token == T_portrait )
2631 else if( token != T_RIGHT )
2633 Expecting(
"portrait" );
2640 wxCHECK_RET( CurTok() == T_title_block,
2641 "Cannot parse " + GetTokenString( CurTok() ) +
" as a TITLE_BLOCK." );
2645 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2647 if( token != T_LEFT )
2648 Expecting( T_LEFT );
2656 aTitleBlock.
SetTitle( FromUTF8() );
2661 aTitleBlock.
SetDate( FromUTF8() );
2676 int commentNumber =
parseInt(
"comment" );
2678 switch( commentNumber )
2727 CurLine(), CurLineNumber(), CurOffset() );
2734 Expecting(
"title, date, rev, company, or comment" );
2744 wxCHECK_MSG( CurTok() == T_property,
nullptr,
2745 "Cannot parse " + GetTokenString( CurTok() ) +
" as a property token." );
2747 bool is_private =
false;
2749 T token = NextTok();
2751 if( token == T_private )
2757 if( !IsSymbol( token ) )
2759 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
2763 wxString
name = FromUTF8();
2765 if(
name.IsEmpty() )
2767 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
2776 name = wxT(
"Netclass" );
2780 if( !IsSymbol( token ) )
2782 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
2790 value = wxEmptyString;
2822 if(
name.CmpNoCase( wxT(
"Sheet name" ) ) == 0 )
2824 else if(
name.CmpNoCase( wxT(
"Sheet file" ) ) == 0 )
2839 if(
name.CmpNoCase( wxT(
"Intersheet References" ) ) == 0 )
2843 std::unique_ptr<SCH_FIELD> field = std::make_unique<SCH_FIELD>( aParent, fieldId,
name );
2844 field->SetText( value );
2847 field->SetPrivate( is_private );
2849 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2851 if( token != T_LEFT )
2852 Expecting( T_LEFT );
2864 field->SetPosition(
parseXY() );
2882 field->SetNameShown( show );
2886 case T_do_not_autoplace:
2889 field->SetCanAutoplace( !doNotAutoplace );
2893 case T_custom_property:
2898 Expecting(
"id, at, hide, show_name, do_not_autoplace or effects" );
2902 return field.release();
2908 wxCHECK_MSG( aSheet !=
nullptr,
nullptr,
"" );
2909 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
2910 "Cannot parse " + GetTokenString( CurTok() ) +
" as a sheet pin token." );
2912 T token = NextTok();
2914 if( !IsSymbol( token ) )
2916 THROW_PARSE_ERROR(
_(
"Invalid sheet pin name" ), CurSource(), CurLine(), CurLineNumber(),
2920 wxString
name = FromUTF8();
2924 auto sheetPin = std::make_unique<SCH_SHEET_PIN>( aSheet,
VECTOR2I( 0, 0 ),
name );
2936 Expecting(
"input, output, bidirectional, tri_state, or passive" );
2939 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2941 if( token != T_LEFT )
2942 Expecting( T_LEFT );
2950 sheetPin->SetPosition(
parseXY() );
2952 double angle =
parseDouble(
"sheet pin angle (side)" );
2956 else if( angle == 90.0 )
2958 else if( angle == 180.0 )
2960 else if( angle == 270.0 )
2963 Expecting(
"0, 90, 180, or 270" );
2980 Expecting(
"at, uuid or effects" );
2984 return sheetPin.release();
2990 wxCHECK_RET( CurTok() == T_sheet_instances,
2991 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
2992 wxCHECK( aScreen, );
2996 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2998 if( token != T_LEFT )
2999 Expecting( T_LEFT );
3017 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3019 if( token != T_LEFT )
3020 Expecting( T_LEFT );
3024 std::vector<wxString> whitespaces = { wxT(
"\r" ), wxT(
"\n" ), wxT(
"\t" ),
3027 size_t numReplacements = 0;
3045 for(
const wxString& ch : whitespaces )
3046 numReplacements += instance.
m_PageNumber.Replace( ch, wxEmptyString );
3051 if( numReplacements > 0 )
3058 Expecting(
"path or page" );
3063 && ( instance.
m_Path.empty() ) )
3079 Expecting(
"path" );
3087 wxCHECK_RET( CurTok() == T_symbol_instances,
3088 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
3089 wxCHECK( aScreen, );
3094 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3096 if( token != T_LEFT )
3097 Expecting( T_LEFT );
3114 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3116 if( token != T_LEFT )
3117 Expecting( T_LEFT );
3138 instance.
m_Value = wxEmptyString;
3140 instance.
m_Value = FromUTF8();
3157 Expecting(
"path, unit, value or footprint" );
3166 Expecting(
"path" );
3175 wxCHECK( aSheet !=
nullptr, );
3179 wxCHECK( screen !=
nullptr, );
3182 m_maxError = schematic->Settings().m_MaxError;
3184 if( aIsCopyableOnly )
3187 bool fileHasUuid =
false;
3201 if( !aIsCopyableOnly )
3206 if( CurTok() != T_kicad_sch )
3207 Expecting(
"kicad_sch" );
3226 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3228 if( aIsCopyableOnly && token == T_EOF )
3231 if( token != T_LEFT )
3232 Expecting( T_LEFT );
3266 case T_generator_version:
3292 if( aIsCopyableOnly )
3293 Unexpected( T_paper );
3303 if( aIsCopyableOnly )
3304 Unexpected( T_page );
3308 NeedSYMBOLorNUMBER();
3309 NeedSYMBOLorNUMBER();
3316 if( aIsCopyableOnly )
3317 Unexpected( T_title_block );
3331 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3333 if( token != T_LEFT )
3334 Expecting( T_LEFT );
3346 Expecting(
"symbol" );
3403 THROW_PARSE_ERROR(
_(
"Schematic polyline has too few points" ), CurSource(), CurLine(),
3404 CurLineNumber(), CurOffset() );
3460 case T_netclass_flag:
3465 case T_global_label:
3466 case T_hierarchical_label:
3467 case T_directive_label:
3483 case T_sheet_instances:
3487 case T_symbol_instances:
3492 if( aIsCopyableOnly )
3493 Unexpected( T_bus_alias );
3498 case T_embedded_fonts:
3504 CurLineNumber(), CurOffset() );
3518 case T_embedded_files:
3524 CurLineNumber(), CurOffset() );
3527 embeddedFilesParser.SyncLineReaderWith( *
this );
3539 for(
int tok = embeddedFilesParser.NextTok();
3541 tok = embeddedFilesParser.NextTok() )
3545 else if( tok ==
DSN_RIGHT && --depth < 0 )
3550 SyncLineReaderWith( embeddedFilesParser );
3556 Expecting(
"arc, bezier, bitmap, bus, bus_alias, bus_entry, circle, class_label, "
3557 "directive_label, ellipse, ellipse_arc, embedded_fonts, embedded_files, "
3558 "global_label, hierarchical_label, image, junction, lib_symbols, "
3559 "netclass_flag, no_connect, polyline, rectangle, rule_area, sheet, "
3560 "sheet_instances, signal, symbol, symbol_instances, table, text, "
3561 "text_box, title_block, uuid, wire" );
3582 CurLineNumber(), CurOffset() );
3586 std::vector<std::string> fontNames;
3587 Fontconfig()->ListFonts( fontNames, std::string(
Pgm().GetLanguageTag().utf8_str() ),
3597 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
3598 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
3603 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
3605 std::set<int> fieldIDsRead;
3610 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3612 if( token != T_LEFT )
3613 Expecting( T_LEFT );
3625 if( !IsSymbol( token ) )
3628 CurLineNumber(), CurOffset() );
3631 libName = FromUTF8();
3635 libName.Replace(
"{slash}",
"/" );
3645 if( !IsSymbol( token ) && token != T_NUMBER )
3646 Expecting(
"symbol|number" );
3649 wxString
name = FromUTF8();
3653 name.Replace(
"{slash}",
"/" );
3659 if(
static_cast<int>(
name.size() ) > bad_pos )
3661 wxString msg = wxString::Format(
_(
"Symbol %s contains invalid character '%c'" ),
3669 CurLineNumber(), CurOffset() );
3672 symbol->SetLibId( libId );
3678 symbol->SetPosition(
parseXY() );
3680 switch(
static_cast<int>(
parseDouble(
"symbol orientation" ) ) )
3683 case 90: transform =
TRANSFORM( 0, 1, -1, 0 );
break;
3684 case 180: transform =
TRANSFORM( -1, 0, 0, -1 );
break;
3685 case 270: transform =
TRANSFORM( 0, -1, 1, 0 );
break;
3686 default: Expecting(
"0, 90, 180, or 270" );
3689 symbol->SetTransform( transform );
3698 else if( token == T_y )
3701 Expecting(
"x or y" );
3707 symbol->SetUnit(
parseInt(
"symbol unit" ) );
3713 symbol->SetBodyStyle(
parseInt(
"symbol body style" ) );
3717 case T_exclude_from_sim:
3718 symbol->SetExcludedFromSim(
parseBool() );
3723 symbol->SetExcludedFromBOM( !
parseBool() );
3728 symbol->SetExcludedFromBoard( !
parseBool() );
3732 case T_in_pos_files:
3733 symbol->SetExcludedFromPosFiles( !
parseBool() );
3755 if( !IsSymbol( t ) )
3756 Expecting(
"default, block or force" );
3758 wxString mode = FromUTF8();
3760 if( mode.IsSameAs( wxT(
"default"),
false ) )
3762 else if( mode.IsSameAs( wxT(
"block"),
false ) )
3764 else if( mode.IsSameAs( wxT(
"force"),
false ) )
3767 Expecting(
"default, block or force" );
3773 case T_fields_autoplaced:
3785 case T_default_instance:
3789 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3791 if( token != T_LEFT )
3792 Expecting( T_LEFT );
3813 symbol->SetValueFieldText( wxEmptyString );
3815 symbol->SetValueFieldText( FromUTF8() );
3824 symbol->SetFootprintFieldText( wxEmptyString );
3826 symbol->SetFootprintFieldText( FromUTF8() );
3832 Expecting(
"reference, unit, value or footprint" );
3841 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3843 if( token != T_LEFT )
3844 Expecting( T_LEFT );
3848 if( token != T_project )
3849 Expecting(
"project" );
3853 wxString projectName = FromUTF8();
3855 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3857 if( token != T_LEFT )
3858 Expecting( T_LEFT );
3862 if( token != T_path )
3863 Expecting(
"path" );
3872 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3874 if( token != T_LEFT )
3875 Expecting( T_LEFT );
3896 symbol->SetValueFieldText( wxEmptyString );
3898 symbol->SetValueFieldText( FromUTF8() );
3907 symbol->SetFootprintFieldText( wxEmptyString );
3909 symbol->SetFootprintFieldText( FromUTF8() );
3920 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3922 if( token != T_LEFT )
3923 Expecting( T_LEFT );
3931 variant.
m_Name = FromUTF8();
3940 case T_exclude_from_sim:
3962 case T_in_pos_files:
3970 wxString fieldValue;
3972 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3974 if( token != T_LEFT )
3975 Expecting( T_LEFT );
3983 fieldName = FromUTF8();
3989 fieldValue = FromUTF8();
3994 Expecting(
"name or value" );
3998 variant.
m_Fields[fieldName] = fieldValue;
4007 Expecting(
"dnp, exclude_from_sim, field, in_bom, in_pos_files, name, "
4008 "on_board, pin_map_override, or symbol_override" );
4018 Expecting(
"reference, unit, value, footprint, or variant" );
4022 symbol->AddHierarchicalReference( instance );
4038 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"0" ) );
4046 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"N" ) );
4054 existing = symbol->GetField( field->
GetId() );
4056 existing = symbol->GetField( field->
GetName() );
4062 wxString base_name = field->
GetName();
4065 for(
int ii = 1; ii < 10 && existing; ii++ )
4067 wxString newname = base_name;
4068 newname <<
'_' << ii;
4070 existing = symbol->GetField( newname );
4080 symbol->AddField( *field );
4083 symbol->UpdatePrefix();
4096 number = FromUTF8();
4098 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4100 if( token != T_LEFT )
4101 Expecting( T_LEFT );
4125 Expecting(
"alternate or uuid" );
4129 symbol->GetRawPins().emplace_back( std::make_unique<SCH_PIN>( symbol.get(), number,
4134 case T_custom_property:
4139 Expecting(
"lib_id, lib_name, at, mirror, uuid, exclude_from_sim, on_board, in_bom, dnp, passthrough, "
4140 "default_instance, property, pin, or instances" );
4144 if( !libName.IsEmpty() && ( symbol->GetLibId().Format().wx_str() != libName ) )
4145 symbol->SetSchSymbolLibraryName( libName );
4148 symbol->ClearFlags();
4150 return symbol.release();
4156 wxCHECK_MSG( CurTok() == T_image,
nullptr,
4157 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an image." ) );
4160 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>();
4163 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4165 if( token != T_LEFT )
4166 Expecting( T_LEFT );
4173 bitmap->SetPosition(
parseXY() );
4199 data.reserve( 1 << 17 );
4201 while( token != T_RIGHT )
4203 if( !IsSymbol( token ) )
4204 Expecting(
"base64 image data" );
4210 wxMemoryBuffer buffer = wxBase64Decode( data );
4223 case T_custom_property:
4228 Expecting(
"at, scale, uuid, data or locked" );
4246 int legacyPPI =
image.GetLegacyPPI();
4248 if( legacyPPI > 0 &&
image.GetPPI() != legacyPPI )
4252 return bitmap.release();
4258 wxCHECK_MSG( CurTok() == T_sheet,
nullptr,
4259 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a sheet." ) );
4265 std::vector<SCH_FIELD> fields;
4266 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>();
4267 std::set<int> fieldIDsRead;
4272 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4274 if( token != T_LEFT )
4275 Expecting( T_LEFT );
4282 sheet->SetPosition(
parseXY() );
4291 sheet->SetSize( size );
4296 case T_exclude_from_sim:
4297 sheet->SetExcludedFromSim(
parseBool() );
4302 sheet->SetExcludedFromBOM( !
parseBool() );
4307 sheet->SetExcludedFromBoard( !
parseBool() );
4321 case T_fields_autoplaced:
4329 sheet->SetBorderWidth( stroke.
GetWidth() );
4330 sheet->SetBorderColor( stroke.
GetColor() );
4335 sheet->SetBackgroundColor( fill.
m_Color );
4352 if( fields.empty() )
4358 fields.emplace_back( *field );
4369 std::vector<SCH_SHEET_INSTANCE> instances;
4371 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4373 if( token != T_LEFT )
4374 Expecting( T_LEFT );
4378 if( token != T_project )
4379 Expecting(
"project" );
4383 wxString projectName = FromUTF8();
4385 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4387 if( token != T_LEFT )
4388 Expecting( T_LEFT );
4392 if( token != T_path )
4393 Expecting(
"path" );
4402 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4404 if( token != T_LEFT )
4405 Expecting( T_LEFT );
4425 static std::vector<wxString> whitespaces =
4431 for( wxString ch : whitespaces )
4444 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4446 if( token != T_LEFT )
4447 Expecting( T_LEFT );
4455 variant.
m_Name = FromUTF8();
4464 case T_exclude_from_sim:
4486 case T_in_pos_files:
4494 wxString fieldValue;
4496 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4498 if( token != T_LEFT )
4499 Expecting( T_LEFT );
4507 fieldName = FromUTF8();
4513 fieldValue = FromUTF8();
4518 Expecting(
"name or value" );
4522 variant.
m_Fields[fieldName] = fieldValue;
4527 Expecting(
"dnp, exclude_from_sim, field, in_bom, in_pos_files, name, or on_board" );
4537 Expecting(
"page or variant" );
4541 instances.emplace_back( instance );
4545 sheet->setInstances( instances );
4549 case T_custom_property:
4554 Expecting(
"at, size, stroke, background, instances, uuid, property, or pin" );
4558 sheet->SetFields( fields );
4563 CurLineNumber(), CurOffset() );
4569 CurLineNumber(), CurOffset() );
4572 return sheet.release();
4578 wxCHECK_MSG( CurTok() == T_junction,
nullptr,
4579 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a junction." ) );
4582 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
4584 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4586 if( token != T_LEFT )
4587 Expecting( T_LEFT );
4594 junction->SetPosition(
parseXY() );
4610 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
4612 junction->SetColor( color );
4628 case T_custom_property:
4633 Expecting(
"at, diameter, color, uuid or locked" );
4637 return junction.release();
4643 wxCHECK_MSG( CurTok() == T_no_connect,
nullptr,
4644 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a no connect." ) );
4647 std::unique_ptr<SCH_NO_CONNECT> no_connect = std::make_unique<SCH_NO_CONNECT>();
4649 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4651 if( token != T_LEFT )
4652 Expecting( T_LEFT );
4659 no_connect->SetPosition(
parseXY() );
4674 case T_custom_property:
4679 Expecting(
"at, uuid or locked" );
4683 return no_connect.release();
4689 wxCHECK_MSG( CurTok() == T_bus_entry,
nullptr,
4690 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus entry." ) );
4694 std::unique_ptr<SCH_BUS_WIRE_ENTRY> busEntry = std::make_unique<SCH_BUS_WIRE_ENTRY>();
4696 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4698 if( token != T_LEFT )
4699 Expecting( T_LEFT );
4706 busEntry->SetPosition(
parseXY() );
4716 busEntry->SetSize( size );
4723 busEntry->SetStroke( stroke );
4737 case T_custom_property:
4742 Expecting(
"at, size, uuid, stroke or locked" );
4746 return busEntry.release();
4768 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4770 if( token != T_LEFT )
4771 Expecting( T_LEFT );
4778 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4780 if( token != T_LEFT )
4781 Expecting( T_LEFT );
4788 polyline->AddPoint(
parseXY() );
4801 polyline->SetStroke( stroke );
4807 polyline->SetFillColor( fill.
m_Color );
4815 polyline->SetStartEnding( ending );
4823 polyline->SetEndEnding( ending );
4838 default: Expecting(
"pts, uuid, stroke, fill, locked, start_shape, or end_shape" );
4842 if( polyline->GetFillMode() !=
FILL_T::NO_FILL && polyline->GetPolyShape().OutlineCount() > 0 )
4852 return polyline.release();
4871 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a line." );
4874 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>(
VECTOR2I(), layer );
4876 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4878 if( token != T_LEFT )
4879 Expecting( T_LEFT );
4892 line->SetStartPoint(
parseXY() );
4900 line->SetEndPoint(
parseXY() );
4907 line->SetStroke( stroke );
4914 line->SetStartEnding( ending );
4922 line->SetEndEnding( ending );
4937 case T_custom_property:
4941 default: Expecting(
"pts, uuid, stroke, locked, start_shape, or end_shape" );
4945 return line.release();
4951 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
4952 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
4960 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>(
SHAPE_T::ARC );
4962 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4964 if( token != T_LEFT )
4965 Expecting( T_LEFT );
4988 arc->SetStroke( stroke );
4994 arc->SetFillColor( fill.
m_Color );
5002 arc->SetStartEnding( ending );
5010 arc->SetEndEnding( ending );
5025 default: Expecting(
"start, mid, end, stroke, fill, locked, start_shape, end_shape, or uuid" );
5029 arc->SetArcGeometry( startPoint, midPoint, endPoint );
5031 return arc.release();
5037 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
5038 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
5047 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5049 if( token != T_LEFT )
5050 Expecting( T_LEFT );
5068 circle->SetStroke( stroke );
5090 Expecting(
"center, radius, stroke, fill, uuid or locked" );
5103 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
5104 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
5109 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>(
SHAPE_T::RECTANGLE );
5111 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5113 if( token != T_LEFT )
5114 Expecting( T_LEFT );
5121 rectangle->SetPosition(
parseXY() );
5126 rectangle->SetEnd(
parseXY() );
5137 rectangle->SetStroke( stroke );
5143 rectangle->SetFillColor( fill.
m_Color );
5159 Expecting(
"start, end, stroke, fill, uuid or locked" );
5163 return rectangle.release();
5169 wxCHECK_MSG( CurTok() == T_rule_area,
nullptr,
5170 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rule area." ) );
5175 std::unique_ptr<SCH_RULE_AREA> ruleArea = std::make_unique<SCH_RULE_AREA>();
5177 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5179 if( token != T_LEFT )
5180 Expecting( T_LEFT );
5194 ruleArea->SetPolyShape( sch_rule_poly );
5196 ruleArea->SetStroke( poly->GetStroke() );
5197 ruleArea->SetFillMode( poly->GetFillMode() );
5198 ruleArea->SetFillColor( poly->GetFillColor() );
5201 const_cast<KIID&
>( ruleArea->m_Uuid ) = poly->m_Uuid;
5205 case T_exclude_from_sim:
5206 ruleArea->SetExcludedFromSim(
parseBool() );
5211 ruleArea->SetExcludedFromBOM( !
parseBool() );
5216 ruleArea->SetExcludedFromBoard( !
parseBool() );
5230 case T_custom_property:
5235 Expecting(
"exclude_from_sim, on_board, in_bom, dnp, locked, or polyline" );
5239 return ruleArea.release();
5245 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
5246 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
5251 std::unique_ptr<SCH_SHAPE> bezier = std::make_unique<SCH_SHAPE>(
SHAPE_T::BEZIER );
5253 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5255 if( token != T_LEFT )
5256 Expecting( T_LEFT );
5266 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
5268 if( token != T_LEFT )
5269 Expecting( T_LEFT );
5278 case 0: bezier->SetStart(
parseXY() );
break;
5279 case 1: bezier->SetBezierC1(
parseXY() );
break;
5280 case 2: bezier->SetBezierC2(
parseXY() );
break;
5281 case 3: bezier->SetEnd(
parseXY() );
break;
5282 default: Unexpected(
"control point" );
break;
5292 bezier->SetStroke( stroke );
5298 bezier->SetFillColor( fill.
m_Color );
5306 bezier->SetStartEnding( ending );
5314 bezier->SetEndEnding( ending );
5329 default: Expecting(
"pts, stroke, fill, locked, start_shape, end_shape, or uuid" );
5333 bezier->RebuildBezierToSegmentsPointsList(
m_maxError );
5335 return bezier.release();
5340 TSCHEMATIC_T::T aFirstTok )
5346 int majorRadius = 1;
5347 int minorRadius = 1;
5354 for(
T token = aFirstTok; token != T_RIGHT; token = NextTok() )
5356 if( token != T_LEFT )
5357 Expecting( T_LEFT );
5369 case T_major_radius:
5374 case T_minor_radius:
5379 case T_rotation_angle:
5386 Expecting(
"start_angle only valid inside ellipse_arc" );
5393 Expecting(
"end_angle only valid inside ellipse_arc" );
5413 Expecting(
"uuid only valid in schematic context" );
5421 Expecting(
"locked only valid in schematic context" );
5427 Expecting(
"center, major_radius, minor_radius, rotation_angle, "
5428 "start_angle, end_angle, stroke, fill, uuid, or locked" );
5447 wxCHECK_MSG( CurTok() == T_ellipse,
nullptr,
5448 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an ellipse." ) );
5452 return ellipse.release();
5458 wxCHECK_MSG( CurTok() == T_ellipse_arc,
nullptr,
5459 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an elliptical arc." ) );
5463 return arc.release();
5470 std::unique_ptr<SCH_TEXT>
text;
5474 case T_text:
text = std::make_unique<SCH_TEXT>();
break;
5475 case T_label:
text = std::make_unique<SCH_LABEL>();
break;
5476 case T_global_label:
text = std::make_unique<SCH_GLOBALLABEL>();
break;
5477 case T_hierarchical_label:
text = std::make_unique<SCH_HIERLABEL>();
break;
5478 case T_netclass_flag:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
5479 case T_directive_label:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
5481 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as text." );
5489 text->SetText( FromUTF8() );
5491 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5493 if( token != T_LEFT )
5494 Expecting( T_LEFT );
5500 case T_exclude_from_sim:
5511 switch(
static_cast<int>( label->GetTextAngle().AsDegrees() ) )
5527 Unexpected( T_shape );
5545 Expecting(
"input, output, bidirectional, tri_state, passive, dot, round, diamond"
5556 Unexpected( T_length );
5565 case T_fields_autoplaced:
5575 text->SetVisible(
true );
5600 Unexpected( T_property );
5624 case T_custom_property:
5629 Expecting(
"at, shape, iref, uuid, effects or locked" );
5635 if( label && label->
GetFields().empty() )
5638 return text.release();
5644 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
5645 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
5647 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>();
5651 return textBox.release();
5657 wxCHECK_MSG( CurTok() == T_table_cell,
nullptr,
5658 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table cell." ) );
5660 std::unique_ptr<SCH_TABLECELL> cell = std::make_unique<SCH_TABLECELL>();
5664 return cell.release();
5680 bool foundEnd =
false;
5681 bool foundSize =
false;
5682 bool foundMargins =
false;
5686 aTextBox->
SetText( FromUTF8() );
5688 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5690 if( token != T_LEFT )
5691 Expecting( T_LEFT );
5697 case T_exclude_from_sim:
5728 cell->SetColSpan(
parseInt(
"column span" ) );
5729 cell->SetRowSpan(
parseInt(
"row span" ) );
5733 Expecting(
"at, size, stroke, fill, effects or uuid" );
5757 foundMargins =
true;
5776 case T_custom_property:
5782 Expecting(
"at, size, stroke, fill, effects, span, uuid or locked" );
5784 Expecting(
"at, size, stroke, fill, effects, uuid or locked" );
5792 else if( foundSize )
5793 aTextBox->
SetEnd( pos + size );
5795 Expecting(
"size" );
5810 wxCHECK_MSG( CurTok() == T_table,
nullptr,
5811 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table." ) );
5817 std::unique_ptr<SCH_TABLE>
table = std::make_unique<SCH_TABLE>( defaultLineWidth );
5819 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5821 if( token != T_LEFT )
5822 Expecting( T_LEFT );
5828 case T_column_count:
5833 case T_column_widths:
5837 while( ( token = NextTok() ) != T_RIGHT )
5847 while( ( token = NextTok() ) != T_RIGHT )
5854 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5856 if( token != T_LEFT )
5857 Expecting( T_LEFT );
5861 if( token != T_table_cell )
5862 Expecting(
"table_cell" );
5870 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5872 if( token != T_LEFT )
5873 Expecting( T_LEFT );
5891 table->SetBorderStroke( borderStroke );
5895 Expecting(
"external, header or stroke" );
5903 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5905 if( token != T_LEFT )
5906 Expecting( T_LEFT );
5924 table->SetSeparatorsStroke( separatorsStroke );
5928 Expecting(
"rows, cols, or stroke" );
5946 case T_custom_property:
5951 Expecting(
"columns, col_widths, row_heights, border, separators, uuid, locked, header or cells" );
5955 if( !
table->GetCell( 0, 0 ) )
5957 THROW_PARSE_ERROR(
_(
"Invalid table: no cells defined" ), CurSource(), CurLine(), CurLineNumber(),
5961 return table.release();
5967 wxCHECK_RET( CurTok() == T_bus_alias,
5968 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus alias." ) );
5969 wxCHECK( aScreen, );
5972 std::shared_ptr<BUS_ALIAS> busAlias = std::make_shared<BUS_ALIAS>();
5983 busAlias->SetName( alias );
5988 if( token != T_members )
5989 Expecting(
"members" );
5993 while( token != T_RIGHT )
5995 if( !IsSymbol( token ) )
5996 Expecting(
"quoted string" );
5998 member = FromUTF8();
6003 busAlias->AddMember( member );
6019 wxString
name = FromUTF8();
6023 wxString fromRef, fromPin, toRef, toPin;
6024 std::set<wxString> memberNets;
6026 for(
T tok = NextTok(); tok != T_RIGHT; tok = NextTok() )
6033 NeedSYMBOLorNUMBER();
6035 NeedSYMBOLorNUMBER();
6039 else if( tok == T_to )
6041 NeedSYMBOLorNUMBER();
6043 NeedSYMBOLorNUMBER();
6047 else if( tok == T_net_class )
6049 NeedSYMBOLorNUMBER();
6050 netClass = FromUTF8();
6053 else if( tok == T_color )
6059 color =
COLOR4D( r / 255.0, g / 255.0, b / 255.0, al );
6062 else if( tok == T_nets )
6064 for(
T inner = NextTok(); inner != T_RIGHT; inner = NextTok() )
6066 if( !IsSymbol( inner ) && inner != T_NUMBER )
6067 Expecting(
"net name" );
6069 memberNets.insert( FromUTF8() );
6079 T inner = NextTok();
6081 if( inner == T_EOF )
6084 if( inner == T_LEFT )
6086 else if( inner == T_RIGHT )
6092 if( !fromRef.IsEmpty() && !toRef.IsEmpty() )
6097 if( !netClass.IsEmpty() )
6103 if( !memberNets.empty() )
6112 while( ( token = NextTok() ) != T_RIGHT )
6117 KIID uuid( CurStr() );
6125 wxCHECK_RET( CurTok() == T_group,
6126 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GROUP." ) );
6133 while( ( token = NextTok() ) != T_LEFT )
6135 if( token == T_STRING )
6136 groupInfo.
name = FromUTF8();
6138 Expecting(
"group name or locked" );
6141 for( ; token != T_RIGHT; token = NextTok() )
6143 if( token != T_LEFT )
6144 Expecting( T_LEFT );
6160 if( !IsSymbol( token ) && token != T_NUMBER )
6161 Expecting(
"symbol|number" );
6164 wxString
name = FromUTF8();
6168 name.Replace(
"{slash}",
"/" );
6174 if(
static_cast<int>(
name.size() ) > bad_pos )
6176 wxString msg = wxString::Format(
_(
"Group library link %s contains invalid character '%c'" ),
name,
6182 THROW_PARSE_ERROR(
_(
"Invalid library ID" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
6200 case T_custom_property:
6205 Expecting(
"uuid, lib_id, members, locked" );
6217 [&](
const KIID& aId )
6223 if( item->m_Uuid == aId )
6242 group->SetName( groupInfo.name );
6244 const_cast<KIID&
>(
group->m_Uuid ) = groupInfo.uuid;
6246 if( groupInfo.libId.IsValid() )
6247 group->SetDesignBlockLibId( groupInfo.libId );
6249 group->SetLocked( groupInfo.locked );
6250 group->SetCustomProperties( groupInfo.customProperties );
6261 for(
const KIID& aUuid : groupInfo.memberUuids )
6263 if(
SCH_ITEM* gItem = getItem( aUuid ) )
6264 group->AddItem( gItem );
6279 T token = NextTok();
6281 if( token == T_EOF )
6283 else if( token == T_LEFT )
6285 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()
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
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)
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()
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 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
@ 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)
#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,...
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
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