31#include <fmt/format.h>
35#include <wx/mstream.h>
36#include <wx/tokenzr.h>
73using namespace TSCHEMATIC_T;
78 unsigned aLineCount,
SCH_SHEET* aRootSheet,
80 SCHEMATIC_LEXER( aLineReader ),
81 m_requiredVersion( 0 ),
84 m_appending( aIsAppending ),
85 m_progressReporter( aProgressReporter ),
86 m_lineReader( aLineReader ),
87 m_lastProgressLine( 0 ),
88 m_lineCount( aLineCount ),
89 m_rootSheet( aRootSheet ),
97 const unsigned PROGRESS_DELTA = 500;
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:
252 aSymbolLibMap[symbol->
GetName()] = symbol;
257 Expecting(
"symbol, generator, or generator_version" );
271 if( CurTok() == T_LEFT )
275 if( CurTok() == T_symbol )
280 const std::vector<wxString>* embeddedFonts =
287 textItem->ResolveFont( embeddedFonts );
289 RECURSE_MODE::NO_RECURSE );
293 wxString msg = wxString::Format(
_(
"Cannot parse %s as a symbol" ),
294 GetTokenString( CurTok() ) );
305 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
306 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
312 wxString unitDisplayName;
314 std::unique_ptr<LIB_SYMBOL> symbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
316 symbol->SetUnitCount( 1 );
320 if( !IsSymbol( token ) )
322 THROW_PARSE_ERROR(
_(
"Invalid symbol name" ), CurSource(), CurLine(), CurLineNumber(),
331 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
338 if(
static_cast<int>(
name.size() ) > bad_pos )
340 wxString msg = wxString::Format(
_(
"Symbol %s contains invalid character '%c'" ),
349 CurLineNumber(), CurOffset() );
354 symbol->SetLibId(
id );
356 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
358 if( token != T_LEFT )
366 symbol->SetGlobalPower();
369 if( token == T_RIGHT )
372 if( token == T_local )
373 symbol->SetLocalPower();
374 else if( token != T_global )
375 Expecting(
"global or local" );
388 case T_exclude_from_sim:
389 symbol->SetExcludedFromSim(
parseBool() );
394 symbol->SetExcludedFromBOM( !
parseBool() );
399 symbol->SetExcludedFromBoard( !
parseBool() );
403 case T_duplicate_pin_numbers_are_jumpers:
404 symbol->SetDuplicatePinNumbersAreJumpers(
parseBool() );
408 case T_jumper_pin_groups:
411 std::vector<std::set<wxString>>& groups = symbol->JumperPinGroups();
412 std::set<wxString>* currentGroup =
nullptr;
414 for( token = NextTok(); currentGroup || token != T_RIGHT; token = NextTok() )
416 switch(
static_cast<int>( token ) )
419 currentGroup = &groups.emplace_back();
423 currentGroup->insert( FromUTF8() );
427 currentGroup =
nullptr;
431 Expecting(
"list of pin names" );
446 if( !IsSymbol( token ) )
449 CurLineNumber(), CurOffset() );
457 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
459 auto it = aSymbolLibMap.find(
name );
461 if( it == aSymbolLibMap.end() )
463 error.Printf(
_(
"No parent for extended symbol %s" ),
name.c_str() );
464 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
467 symbol->SetParent( it->second );
476 if( !IsSymbol( token ) )
479 CurLineNumber(), CurOffset() );
487 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
491 error.Printf(
_(
"Invalid symbol unit name prefix %s" ),
name.c_str() );
492 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
497 wxStringTokenizer tokenizer(
name,
"_" );
499 if( tokenizer.CountTokens() != 2 )
501 error.Printf(
_(
"Invalid symbol unit name suffix %s" ),
name.c_str() );
502 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
505 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
507 error.Printf(
_(
"Invalid symbol unit number %s" ),
name.c_str() );
508 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
511 m_unit =
static_cast<int>( tmp );
513 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
515 error.Printf(
_(
"Invalid symbol convert number %s" ),
name.c_str() );
516 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
522 symbol->SetHasAlternateBodyStyle(
true,
false );
524 if(
m_unit > symbol->GetUnitCount() )
525 symbol->SetUnitCount(
m_unit,
false );
527 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
529 if( token != T_LEFT )
539 if( IsSymbol( token ) )
541 unitDisplayName = FromUTF8();
542 symbol->SetUnitDisplayName(
m_unit, unitDisplayName );
558 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
561 symbol->AddDrawItem( item,
false );
565 Expecting(
"arc, bezier, circle, pin, polyline, rectangle, or text" );
584 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
587 symbol->AddDrawItem( item,
false );
590 case T_embedded_fonts:
592 symbol->SetAreFontsEmbedded(
parseBool() );
597 case T_embedded_files:
600 embeddedFilesParser.SyncLineReaderWith( *
this );
604 embeddedFilesParser.
ParseEmbedded( symbol->GetEmbeddedFiles() );
608 wxLogError( e.
What() );
611 SyncLineReaderWith( embeddedFilesParser );
616 Expecting(
"pin_names, pin_numbers, arc, bezier, circle, pin, polyline, "
617 "rectangle, or text" );
621 symbol->GetDrawItems().sort();
624 const std::vector<wxString>* embeddedFonts =
625 symbol->GetEmbeddedFiles()->UpdateFontFiles();
627 symbol->RunOnChildren(
631 textItem->ResolveFont( embeddedFonts );
633 RECURSE_MODE::NO_RECURSE );
635 return symbol.release();
651 default: Expecting(
"arc, bezier, circle, pin, polyline, rectangle, or text" );
665 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
667 return KiROUND( std::clamp( retval, -int_limit, int_limit ) );
675 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
677 return KiROUND( std::clamp( retval, -int_limit, int_limit ) );
684 strokeParser.SyncLineReaderWith( *
this );
687 SyncLineReaderWith( strokeParser );
693 wxCHECK_RET( CurTok() == T_fill,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a fill." );
696 aFill.
m_Color = COLOR4D::UNSPECIFIED;
700 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
702 if( token != T_LEFT )
715 case T_none: aFill.
m_FillType = FILL_T::NO_FILL;
break;
716 case T_outline: aFill.
m_FillType = FILL_T::FILLED_SHAPE;
break;
717 case T_background: aFill.
m_FillType = FILL_T::FILLED_WITH_BG_BODYCOLOR;
break;
718 case T_color: aFill.
m_FillType = FILL_T::FILLED_WITH_COLOR;
break;
719 case T_hatch: aFill.
m_FillType = FILL_T::HATCH;
break;
720 case T_reverse_hatch: aFill.
m_FillType = FILL_T::REVERSE_HATCH;
break;
721 case T_cross_hatch: aFill.
m_FillType = FILL_T::CROSS_HATCH;
break;
722 default: Expecting(
"none, outline, hatch, reverse_hatch, "
723 "cross_hatch, color or background" );
744 Expecting(
"type or color" );
751 bool aEnforceMinTextSize )
753 wxCHECK_RET( aText && ( CurTok() == T_effects || CurTok() == T_href ),
754 "Cannot parse " + GetTokenString( CurTok() ) +
" as an EDA_TEXT." );
771 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
773 if( token == T_LEFT )
779 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
781 if( token == T_LEFT )
832 Expecting(
"face, size, thickness, line_spacing, bold, or italic" );
839 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
848 case T_mirror:
break;
849 default: Expecting(
"left, right, top, bottom, or mirror" );
858 wxString hyperlink = FromUTF8();
863 CurSource(), CurLine(), CurLineNumber(), CurOffset() );
882 Expecting(
"font, justify, hide or href" );
890 wxCHECK_RET( CurTok() == aHeaderType,
891 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a header." ) );
897 if( tok == T_version )
911 wxCHECK_RET( CurTok() == T_pin_names,
912 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_name token." );
922 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
925 if( token == T_hide )
927 aSymbol->SetShowPinNames(
false );
931 if( token != T_LEFT )
946 aSymbol->SetShowPinNames( !
parseBool() );
951 Expecting(
"offset or hide" );
959 wxCHECK_RET( CurTok() == T_pin_numbers,
960 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_number token." );
969 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
972 if( token == T_hide )
974 aSymbol->SetShowPinNumbers(
false );
978 if( token != T_LEFT )
988 aSymbol->SetShowPinNumbers( !
parseBool() );
1002 wxCHECK_MSG( CurTok() == T_property,
nullptr,
1003 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a property." ) );
1004 wxCHECK( aSymbol,
nullptr );
1006 FIELD_T fieldId = FIELD_T::USER;
1009 bool isPrivate =
false;
1010 bool isVisible =
true;
1012 T token = NextTok();
1014 if( token == T_private )
1020 if( !IsSymbol( token ) )
1022 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
1028 if(
name.IsEmpty() )
1030 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
1044 auto field = std::make_unique<SCH_FIELD>( aSymbol.get(), fieldId,
name );
1045 field->SetPrivate( isPrivate );
1046 field->SetVisible( isVisible );
1050 if( !IsSymbol( token ) )
1052 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
1059 value = wxEmptyString;
1063 field->SetText( value );
1065 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1067 if( token != T_LEFT )
1068 Expecting( T_LEFT );
1080 field->SetPosition(
parseXY(
true ) );
1092 field->GetId() == FIELD_T::VALUE );
1098 field->SetNameShown( show );
1102 case T_do_not_autoplace:
1105 field->SetCanAutoplace( !doNotAutoplace );
1110 Expecting(
"id, at, hide, show_name, do_not_autoplace, or effects" );
1116 if( field->IsMandatory() )
1118 existingField = aSymbol->GetField( field->GetId() );
1120 *existingField = *field;
1121 return existingField;
1123 else if(
name ==
"ki_keywords" )
1126 aSymbol->SetKeyWords( value );
1130 else if(
name ==
"ki_description" )
1132 aSymbol->SetDescription( value );
1135 else if(
name ==
"ki_fp_filters" )
1138 wxArrayString filters;
1139 wxStringTokenizer tokenizer( value );
1141 while( tokenizer.HasMoreTokens() )
1143 wxString curr_token =
UnescapeString( tokenizer.GetNextToken() );
1144 filters.Add( curr_token );
1147 aSymbol->SetFPFilters( filters );
1150 else if(
name ==
"ki_locked" )
1154 aSymbol->LockUnits(
true );
1160 existingField = aSymbol->GetField( field->GetCanonicalName() );
1171 for(
int ii = 1; ii < 10 && existingField; ii++ )
1173 wxString newname = base_name;
1174 newname <<
'_' << ii;
1176 existingField = aSymbol->GetField( newname );
1178 if( !existingField )
1179 field->SetName( newname );
1183 if( !existingField )
1185 aSymbol->AddDrawItem( field.get(),
false );
1186 return field.release();
1199 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
1200 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
1206 bool hasMidPoint =
false;
1214 bool hasAngles =
false;
1216 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>( SHAPE_T::ARC,
LAYER_DEVICE );
1223 if( token == T_private )
1225 arc->SetPrivate(
true );
1229 for( ; token != T_RIGHT; token = NextTok() )
1231 if( token != T_LEFT )
1232 Expecting( T_LEFT );
1255 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1257 if( token != T_LEFT )
1258 Expecting( T_LEFT );
1286 Expecting(
"at, length, or angles" );
1294 arc->SetStroke( stroke );
1300 arc->SetFillColor( fill.
m_Color );
1304 Expecting(
"start, mid, end, radius, stroke, or fill" );
1310 arc->SetArcGeometry( startPoint, midPoint, endPoint );
1321 EDA_ANGLE arc_start, arc_end, arc_angle;
1322 arc->CalcArcAngles( arc_start, arc_end );
1323 arc_angle = arc_end - arc_start;
1328 arc->SetStart( endPoint );
1329 arc->SetEnd( startPoint );
1332 arc->SetCenter( new_center );
1338 arc->SetCenter( new_center );
1342 else if( hasAngles )
1344 arc->SetCenter(
center );
1350 arc->SetStart( endPoint );
1351 arc->SetEnd( startPoint );
1355 EDA_ANGLE arc_start, arc_end, arc_angle;
1356 arc->CalcArcAngles( arc_start, arc_end );
1357 arc_angle = arc_end - arc_start;
1363 arc->SetStart( startPoint );
1364 arc->SetEnd( endPoint );
1372 arc->SetStart( startPoint );
1373 arc->SetEnd( endPoint );
1377 arc->SetCenter( new_center );
1383 wxFAIL_MSG(
"Setting arc without either midpoint or angles not implemented." );
1386 return arc.release();
1392 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
1393 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
1399 std::unique_ptr<SCH_SHAPE> bezier = std::make_unique<SCH_SHAPE>( SHAPE_T::BEZIER,
LAYER_DEVICE );
1401 bezier->SetUnit(
m_unit );
1406 if( token == T_private )
1408 bezier->SetPrivate(
true );
1412 for( ; token != T_RIGHT; token = NextTok() )
1414 if( token != T_LEFT )
1415 Expecting( T_LEFT );
1425 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
1427 if( token != T_LEFT )
1428 Expecting( T_LEFT );
1437 case 0: bezier->SetStart(
parseXY(
true ) );
break;
1438 case 1: bezier->SetBezierC1(
parseXY(
true ) );
break;
1439 case 2: bezier->SetBezierC2(
parseXY(
true ) );
break;
1440 case 3: bezier->SetEnd(
parseXY(
true ) );
break;
1441 default: Unexpected(
"control point" );
break;
1451 bezier->SetStroke( stroke );
1457 bezier->SetFillColor( fill.
m_Color );
1461 Expecting(
"pts, stroke, or fill" );
1465 bezier->RebuildBezierToSegmentsPointsList(
m_maxError );
1467 return bezier.release();
1473 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
1474 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
1482 std::unique_ptr<SCH_SHAPE>
circle = std::make_unique<SCH_SHAPE>( SHAPE_T::CIRCLE,
LAYER_DEVICE );
1489 if( token == T_private )
1491 circle->SetPrivate(
true );
1495 for( ; token != T_RIGHT; token = NextTok() )
1497 if( token != T_LEFT )
1498 Expecting( T_LEFT );
1516 circle->SetStroke( stroke );
1526 Expecting(
"center, radius, stroke, or fill" );
1544 case T_input:
return ELECTRICAL_PINTYPE::PT_INPUT;
1545 case T_output:
return ELECTRICAL_PINTYPE::PT_OUTPUT;
1546 case T_bidirectional:
return ELECTRICAL_PINTYPE::PT_BIDI;
1547 case T_tri_state:
return ELECTRICAL_PINTYPE::PT_TRISTATE;
1548 case T_passive:
return ELECTRICAL_PINTYPE::PT_PASSIVE;
1549 case T_unspecified:
return ELECTRICAL_PINTYPE::PT_UNSPECIFIED;
1550 case T_power_in:
return ELECTRICAL_PINTYPE::PT_POWER_IN;
1551 case T_power_out:
return ELECTRICAL_PINTYPE::PT_POWER_OUT;
1552 case T_open_collector:
return ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR;
1553 case T_open_emitter:
return ELECTRICAL_PINTYPE::PT_OPENEMITTER;
1555 case T_no_connect:
return ELECTRICAL_PINTYPE::PT_NC;
1556 case T_free:
return ELECTRICAL_PINTYPE::PT_NIC;
1559 Expecting(
"input, output, bidirectional, tri_state, passive, unspecified, "
1560 "power_in, power_out, open_collector, open_emitter, free or "
1562 return ELECTRICAL_PINTYPE::PT_UNSPECIFIED;
1571 case T_line:
return GRAPHIC_PINSHAPE::LINE;
1572 case T_inverted:
return GRAPHIC_PINSHAPE::INVERTED;
1573 case T_clock:
return GRAPHIC_PINSHAPE::CLOCK;
1574 case T_inverted_clock:
return GRAPHIC_PINSHAPE::INVERTED_CLOCK;
1575 case T_input_low:
return GRAPHIC_PINSHAPE::INPUT_LOW;
1576 case T_clock_low:
return GRAPHIC_PINSHAPE::CLOCK_LOW;
1577 case T_output_low:
return GRAPHIC_PINSHAPE::OUTPUT_LOW;
1578 case T_edge_clock_high:
return GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK;
1579 case T_non_logic:
return GRAPHIC_PINSHAPE::NONLOGIC;
1582 Expecting(
"line, inverted, clock, inverted_clock, input_low, clock_low, "
1583 "output_low, edge_clock_high, non_logic" );
1584 return GRAPHIC_PINSHAPE::LINE;
1588 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
1589 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a pin token." ) );
1592 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>(
nullptr );
1599 pin->SetType( parseType( token ) );
1603 pin->SetShape( parseShape( token ) );
1605 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1608 if( token == T_hide )
1610 pin->SetVisible(
false );
1614 if( token != T_LEFT )
1615 Expecting( T_LEFT );
1624 switch(
parseInt(
"pin orientation" ) )
1626 case 0:
pin->SetOrientation( PIN_ORIENTATION::PIN_RIGHT );
break;
1627 case 90:
pin->SetOrientation( PIN_ORIENTATION::PIN_UP );
break;
1628 case 180:
pin->SetOrientation( PIN_ORIENTATION::PIN_LEFT );
break;
1629 case 270:
pin->SetOrientation( PIN_ORIENTATION::PIN_DOWN );
break;
1630 default: Expecting(
"0, 90, 180, or 270" );
1649 if( !IsSymbol( token ) )
1656 pin->SetName( wxEmptyString );
1660 pin->SetName( FromUTF8() );
1664 if( token != T_RIGHT )
1668 if( token == T_effects )
1675 pin->SetNameTextSize(
text.GetTextHeight() );
1680 Expecting(
"effects" );
1689 if( !IsSymbol( token ) )
1692 CurLineNumber(), CurOffset() );
1696 pin->SetNumber( wxEmptyString );
1700 pin->SetNumber( FromUTF8() );
1704 if( token != T_RIGHT )
1708 if( token == T_effects )
1715 pin->SetNumberTextSize(
text.GetTextHeight() );
1720 Expecting(
"effects" );
1732 if( !IsSymbol( token ) )
1735 CurLineNumber(), CurOffset() );
1741 alt.
m_Type = parseType( token );
1744 alt.
m_Shape = parseShape( token );
1746 pin->GetAlternates()[ alt.
m_Name ] = alt;
1753 Expecting(
"at, name, number, hide, length, or alternate" );
1757 return pin.release();
1763 wxCHECK_MSG( CurTok() == T_polyline,
nullptr,
1764 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a poly." ) );
1769 std::unique_ptr<SCH_SHAPE> poly = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY,
LAYER_DEVICE );
1776 if( token == T_private )
1778 poly->SetPrivate(
true );
1782 for( ; token != T_RIGHT; token = NextTok() )
1784 if( token != T_LEFT )
1785 Expecting( T_LEFT );
1792 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1794 if( token != T_LEFT )
1795 Expecting( T_LEFT );
1802 poly->AddPoint(
parseXY(
true ) );
1811 poly->SetStroke( stroke );
1817 poly->SetFillColor( fill.
m_Color );
1821 Expecting(
"pts, stroke, or fill" );
1825 return poly.release();
1831 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
1832 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
1837 auto rectangle = std::make_unique<SCH_SHAPE>( SHAPE_T::RECTANGLE,
LAYER_DEVICE );
1839 rectangle->SetUnit(
m_unit );
1844 if( token == T_private )
1846 rectangle->SetPrivate(
true );
1850 for( ; token != T_RIGHT; token = NextTok() )
1852 if( token != T_LEFT )
1853 Expecting( T_LEFT );
1860 rectangle->SetPosition(
parseXY(
true ) );
1865 rectangle->SetEnd(
parseXY(
true ) );
1871 rectangle->SetStroke( stroke );
1877 rectangle->SetFillColor( fill.
m_Color );
1881 Expecting(
"start, end, stroke, or fill" );
1885 return rectangle.release();
1891 wxCHECK_MSG( CurTok() == T_text,
nullptr,
1892 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text token." ) );
1895 std::unique_ptr<SCH_TEXT>
text = std::make_unique<SCH_TEXT>();
1902 if( token == T_private )
1904 text->SetPrivate(
true );
1908 if( !IsSymbol( token ) )
1910 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
1914 text->SetText( FromUTF8() );
1916 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1918 if( token != T_LEFT )
1919 Expecting( T_LEFT );
1937 Expecting(
"at or effects" );
1942 if( !
text->IsVisible() )
1945 return text.release();
1951 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
1952 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
1964 bool foundEnd =
false;
1965 bool foundSize =
false;
1966 bool foundMargins =
false;
1968 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>(
LAYER_DEVICE );
1970 textBox->SetUnit(
m_unit );
1974 if( token == T_private )
1976 textBox->SetPrivate(
true );
1980 if( !IsSymbol( token ) )
1982 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
1986 textBox->SetText( FromUTF8() );
1988 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1990 if( token != T_LEFT )
1991 Expecting( T_LEFT );
2022 textBox->SetStroke( stroke );
2028 textBox->SetFillColor( fill.
m_Color );
2033 textBox->SetMarginLeft(
left );
2034 textBox->SetMarginTop( top );
2035 textBox->SetMarginRight(
right );
2036 textBox->SetMarginBottom( bottom );
2037 foundMargins =
true;
2046 Expecting(
"at, size, stroke, fill or effects" );
2050 textBox->SetPosition( pos );
2053 textBox->SetEnd(
end );
2054 else if( foundSize )
2055 textBox->SetEnd( pos + size );
2057 Expecting(
"size" );
2061 int margin = textBox->GetLegacyTextMargin();
2062 textBox->SetMarginLeft( margin );
2063 textBox->SetMarginTop( margin );
2064 textBox->SetMarginRight( margin );
2065 textBox->SetMarginBottom( margin );
2068 return textBox.release();
2074 wxCHECK_RET( ( CurTok() == T_page &&
m_requiredVersion <= 20200506 ) || CurTok() == T_paper,
2075 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a PAGE_INFO." ) );
2081 wxString pageType = FromUTF8();
2083 if( !aPageInfo.
SetType( pageType ) )
2085 THROW_PARSE_ERROR(
_(
"Invalid page type" ), CurSource(), CurLine(), CurLineNumber(),
2112 if( token == T_portrait )
2117 else if( token != T_RIGHT )
2119 Expecting(
"portrait" );
2126 wxCHECK_RET( CurTok() == T_title_block,
2127 "Cannot parse " + GetTokenString( CurTok() ) +
" as a TITLE_BLOCK." );
2131 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2133 if( token != T_LEFT )
2134 Expecting( T_LEFT );
2142 aTitleBlock.
SetTitle( FromUTF8() );
2147 aTitleBlock.
SetDate( FromUTF8() );
2162 int commentNumber =
parseInt(
"comment" );
2164 switch( commentNumber )
2213 CurLine(), CurLineNumber(), CurOffset() );
2220 Expecting(
"title, date, rev, company, or comment" );
2230 wxCHECK_MSG( CurTok() == T_property,
nullptr,
2231 "Cannot parse " + GetTokenString( CurTok() ) +
" as a property token." );
2233 bool is_private =
false;
2235 T token = NextTok();
2237 if( token == T_private )
2243 if( !IsSymbol( token ) )
2245 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
2249 wxString
name = FromUTF8();
2251 if(
name.IsEmpty() )
2253 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
2259 if( !IsSymbol( token ) )
2261 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
2269 value = wxEmptyString;
2273 FIELD_T fieldId = FIELD_T::USER;
2299 if(
name.CmpNoCase( wxT(
"Sheet name" ) ) == 0 )
2300 fieldId = FIELD_T::SHEET_NAME;
2301 else if(
name.CmpNoCase( wxT(
"Sheet file" ) ) == 0 )
2302 fieldId = FIELD_T::SHEET_FILENAME;
2316 if(
name.CmpNoCase( wxT(
"Intersheet References" ) ) == 0 )
2317 fieldId = FIELD_T::INTERSHEET_REFS;
2320 std::unique_ptr<SCH_FIELD> field = std::make_unique<SCH_FIELD>( aParent, fieldId,
name );
2321 field->SetText( value );
2323 if( fieldId == FIELD_T::USER )
2324 field->SetPrivate( is_private );
2326 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2328 if( token != T_LEFT )
2329 Expecting( T_LEFT );
2341 field->SetPosition(
parseXY() );
2353 field->GetId() == FIELD_T::VALUE );
2359 field->SetNameShown( show );
2363 case T_do_not_autoplace:
2366 field->SetCanAutoplace( !doNotAutoplace );
2371 Expecting(
"id, at, hide, show_name, do_not_autoplace or effects" );
2375 return field.release();
2381 wxCHECK_MSG( aSheet !=
nullptr,
nullptr,
"" );
2382 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
2383 "Cannot parse " + GetTokenString( CurTok() ) +
" as a sheet pin token." );
2385 T token = NextTok();
2387 if( !IsSymbol( token ) )
2389 THROW_PARSE_ERROR(
_(
"Invalid sheet pin name" ), CurSource(), CurLine(), CurLineNumber(),
2393 wxString
name = FromUTF8();
2395 if(
name.IsEmpty() )
2397 THROW_PARSE_ERROR(
_(
"Empty sheet pin name" ), CurSource(), CurLine(), CurLineNumber(),
2401 auto sheetPin = std::make_unique<SCH_SHEET_PIN>( aSheet,
VECTOR2I( 0, 0 ),
name );
2407 case T_input: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_INPUT );
break;
2408 case T_output: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
break;
2409 case T_bidirectional: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_BIDI );
break;
2410 case T_tri_state: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_TRISTATE );
break;
2411 case T_passive: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
break;
2413 Expecting(
"input, output, bidirectional, tri_state, or passive" );
2416 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2418 if( token != T_LEFT )
2419 Expecting( T_LEFT );
2427 sheetPin->SetPosition(
parseXY() );
2429 double angle =
parseDouble(
"sheet pin angle (side)" );
2432 sheetPin->SetSide( SHEET_SIDE::RIGHT );
2433 else if( angle == 90.0 )
2434 sheetPin->SetSide( SHEET_SIDE::TOP );
2435 else if( angle == 180.0 )
2436 sheetPin->SetSide( SHEET_SIDE::LEFT );
2437 else if( angle == 270.0 )
2438 sheetPin->SetSide( SHEET_SIDE::BOTTOM );
2440 Expecting(
"0, 90, 180, or 270" );
2457 Expecting(
"at, uuid or effects" );
2461 return sheetPin.release();
2467 wxCHECK_RET( CurTok() == T_sheet_instances,
2468 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
2469 wxCHECK( aScreen, );
2473 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2475 if( token != T_LEFT )
2476 Expecting( T_LEFT );
2494 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2496 if( token != T_LEFT )
2497 Expecting( T_LEFT );
2501 std::vector<wxString> whitespaces = { wxT(
"\r" ), wxT(
"\n" ), wxT(
"\t" ),
2504 size_t numReplacements = 0;
2522 for(
const wxString& ch : whitespaces )
2523 numReplacements += instance.
m_PageNumber.Replace( ch, wxEmptyString );
2528 if( numReplacements > 0 )
2535 Expecting(
"path or page" );
2540 && ( instance.
m_Path.empty() ) )
2556 Expecting(
"path" );
2564 wxCHECK_RET( CurTok() == T_symbol_instances,
2565 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
2566 wxCHECK( aScreen, );
2571 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2573 if( token != T_LEFT )
2574 Expecting( T_LEFT );
2591 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2593 if( token != T_LEFT )
2594 Expecting( T_LEFT );
2615 instance.
m_Value = wxEmptyString;
2617 instance.
m_Value = FromUTF8();
2634 Expecting(
"path, unit, value or footprint" );
2643 Expecting(
"path" );
2652 wxCHECK( aSheet !=
nullptr, );
2656 wxCHECK( screen !=
nullptr, );
2659 m_maxError = schematic->Settings().m_MaxError;
2661 if( aIsCopyableOnly )
2664 bool fileHasUuid =
false;
2678 if( !aIsCopyableOnly )
2683 if( CurTok() != T_kicad_sch )
2684 Expecting(
"kicad_sch" );
2703 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2705 if( aIsCopyableOnly && token == T_EOF )
2708 if( token != T_LEFT )
2709 Expecting( T_LEFT );
2743 case T_generator_version:
2769 if( aIsCopyableOnly )
2770 Unexpected( T_paper );
2780 if( aIsCopyableOnly )
2781 Unexpected( T_page );
2785 NeedSYMBOLorNUMBER();
2786 NeedSYMBOLorNUMBER();
2793 if( aIsCopyableOnly )
2794 Unexpected( T_title_block );
2808 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2810 if( token != T_LEFT )
2811 Expecting( T_LEFT );
2823 Expecting(
"symbol" );
2924 case T_netclass_flag:
2929 case T_global_label:
2930 case T_hierarchical_label:
2931 case T_directive_label:
2943 case T_sheet_instances:
2947 case T_symbol_instances:
2952 if( aIsCopyableOnly )
2953 Unexpected( T_bus_alias );
2958 case T_embedded_fonts:
2964 CurLineNumber(), CurOffset() );
2971 case T_embedded_files:
2977 CurLineNumber(), CurOffset() );
2980 embeddedFilesParser.SyncLineReaderWith( *
this );
2988 wxLogError( e.
What() );
2991 SyncLineReaderWith( embeddedFilesParser );
2997 Expecting(
"bitmap, bus, bus_alias, bus_entry, class_label, embedded_files, global_label, "
2998 "hierarchical_label, junction, label, line, no_connect, page, paper, rule_area, "
2999 "sheet, symbol, symbol_instances, text, title_block" );
3020 CurLineNumber(), CurOffset() );
3024 std::vector<std::string> fontNames;
3025 Fontconfig()->ListFonts( fontNames, std::string(
Pgm().GetLanguageTag().utf8_str() ),
3035 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
3036 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
3041 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
3043 std::set<int> fieldIDsRead;
3048 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3050 if( token != T_LEFT )
3051 Expecting( T_LEFT );
3063 if( !IsSymbol( token ) )
3066 CurLineNumber(), CurOffset() );
3069 libName = FromUTF8();
3073 libName.Replace(
"{slash}",
"/" );
3083 if( !IsSymbol( token ) && token != T_NUMBER )
3084 Expecting(
"symbol|number" );
3087 wxString
name = FromUTF8();
3091 name.Replace(
"{slash}",
"/" );
3097 if(
static_cast<int>(
name.size() ) > bad_pos )
3099 wxString msg = wxString::Format(
_(
"Symbol %s contains invalid character '%c'" ),
3107 CurLineNumber(), CurOffset() );
3110 symbol->SetLibId( libId );
3116 symbol->SetPosition(
parseXY() );
3118 switch(
static_cast<int>(
parseDouble(
"symbol orientation" ) ) )
3121 case 90: transform =
TRANSFORM( 0, 1, -1, 0 );
break;
3122 case 180: transform =
TRANSFORM( -1, 0, 0, -1 );
break;
3123 case 270: transform =
TRANSFORM( 0, -1, 1, 0 );
break;
3124 default: Expecting(
"0, 90, 180, or 270" );
3127 symbol->SetTransform( transform );
3136 else if( token == T_y )
3139 Expecting(
"x or y" );
3145 symbol->SetUnit(
parseInt(
"symbol unit" ) );
3152 symbol->SetBodyStyleUnconditional(
parseInt(
"symbol body style" ) );
3156 case T_exclude_from_sim:
3157 symbol->SetExcludedFromSim(
parseBool() );
3162 symbol->SetExcludedFromBOM( !
parseBool() );
3167 symbol->SetExcludedFromBoard( !
parseBool() );
3176 case T_fields_autoplaced:
3188 case T_default_instance:
3192 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3194 if( token != T_LEFT )
3195 Expecting( T_LEFT );
3216 symbol->SetValueFieldText( wxEmptyString );
3218 symbol->SetValueFieldText( FromUTF8() );
3227 symbol->SetFootprintFieldText( wxEmptyString );
3229 symbol->SetFootprintFieldText( FromUTF8() );
3235 Expecting(
"reference, unit, value or footprint" );
3244 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3246 if( token != T_LEFT )
3247 Expecting( T_LEFT );
3251 if( token != T_project )
3252 Expecting(
"project" );
3256 wxString projectName = FromUTF8();
3258 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3260 if( token != T_LEFT )
3261 Expecting( T_LEFT );
3265 if( token != T_path )
3266 Expecting(
"path" );
3275 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3277 if( token != T_LEFT )
3278 Expecting( T_LEFT );
3299 symbol->SetValueFieldText( wxEmptyString );
3301 symbol->SetValueFieldText( FromUTF8() );
3310 symbol->SetFootprintFieldText( wxEmptyString );
3312 symbol->SetFootprintFieldText( FromUTF8() );
3318 Expecting(
"reference, unit, value or footprint" );
3321 symbol->AddHierarchicalReference( instance );
3338 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"0" ) );
3345 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"N" ) );
3352 existing = symbol->GetField( field->
GetId() );
3354 existing = symbol->GetField( field->
GetName() );
3359 symbol->AddField( *field );
3361 if( field->
GetId() == FIELD_T::REFERENCE )
3362 symbol->UpdatePrefix();
3375 number = FromUTF8();
3377 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3379 if( token != T_LEFT )
3380 Expecting( T_LEFT );
3404 Expecting(
"alternate or uuid" );
3408 symbol->GetRawPins().emplace_back( std::make_unique<SCH_PIN>( symbol.get(), number,
3414 Expecting(
"lib_id, lib_name, at, mirror, uuid, exclude_from_sim, on_board, in_bom, dnp, "
3415 "default_instance, property, pin, or instances" );
3419 if( !libName.IsEmpty() && ( symbol->GetLibId().Format().wx_str() != libName ) )
3420 symbol->SetSchSymbolLibraryName( libName );
3423 symbol->ClearFlags();
3425 return symbol.release();
3431 wxCHECK_MSG( CurTok() == T_image,
nullptr,
3432 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an image." ) );
3435 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>();
3438 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3440 if( token != T_LEFT )
3441 Expecting( T_LEFT );
3448 bitmap->SetPosition(
parseXY() );
3474 data.reserve( 1 << 17 );
3476 while( token != T_RIGHT )
3478 if( !IsSymbol( token ) )
3479 Expecting(
"base64 image data" );
3485 wxMemoryBuffer buffer = wxBase64Decode( data );
3494 Expecting(
"at, scale, uuid or data" );
3507 return bitmap.release();
3513 wxCHECK_MSG( CurTok() == T_sheet,
nullptr,
3514 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a sheet." ) );
3520 std::vector<SCH_FIELD> fields;
3521 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>();
3522 std::set<int> fieldIDsRead;
3527 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3529 if( token != T_LEFT )
3530 Expecting( T_LEFT );
3537 sheet->SetPosition(
parseXY() );
3546 sheet->SetSize( size );
3551 case T_exclude_from_sim:
3552 sheet->SetExcludedFromSim(
parseBool() );
3557 sheet->SetExcludedFromBOM( !
parseBool() );
3562 sheet->SetExcludedFromBoard( !
parseBool() );
3571 case T_fields_autoplaced:
3579 sheet->SetBorderWidth( stroke.
GetWidth() );
3580 sheet->SetBorderColor( stroke.
GetColor() );
3585 sheet->SetBackgroundColor( fill.
m_Color );
3602 if( fields.empty() )
3603 field->
setId( FIELD_T::SHEET_NAME );
3605 field->
setId( FIELD_T::SHEET_FILENAME );
3608 fields.emplace_back( *field );
3619 std::vector<SCH_SHEET_INSTANCE> instances;
3621 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3623 if( token != T_LEFT )
3624 Expecting( T_LEFT );
3628 if( token != T_project )
3629 Expecting(
"project" );
3633 wxString projectName = FromUTF8();
3635 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3637 if( token != T_LEFT )
3638 Expecting( T_LEFT );
3642 if( token != T_path )
3643 Expecting(
"path" );
3652 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3654 if( token != T_LEFT )
3655 Expecting( T_LEFT );
3675 static std::vector<wxString> whitespaces =
3681 for( wxString ch : whitespaces )
3690 Expecting(
"page" );
3694 instances.emplace_back( instance );
3698 sheet->setInstances( instances );
3703 Expecting(
"at, size, stroke, background, instances, uuid, property, or pin" );
3707 sheet->SetFields( fields );
3709 return sheet.release();
3715 wxCHECK_MSG( CurTok() == T_junction,
nullptr,
3716 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a junction." ) );
3719 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
3721 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3723 if( token != T_LEFT )
3724 Expecting( T_LEFT );
3731 junction->SetPosition(
parseXY() );
3749 junction->SetColor(
color );
3761 Expecting(
"at, diameter, color or uuid" );
3765 return junction.release();
3771 wxCHECK_MSG( CurTok() == T_no_connect,
nullptr,
3772 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a no connect." ) );
3775 std::unique_ptr<SCH_NO_CONNECT> no_connect = std::make_unique<SCH_NO_CONNECT>();
3777 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3779 if( token != T_LEFT )
3780 Expecting( T_LEFT );
3787 no_connect->SetPosition(
parseXY() );
3798 Expecting(
"at or uuid" );
3802 return no_connect.release();
3808 wxCHECK_MSG( CurTok() == T_bus_entry,
nullptr,
3809 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus entry." ) );
3813 std::unique_ptr<SCH_BUS_WIRE_ENTRY> busEntry = std::make_unique<SCH_BUS_WIRE_ENTRY>();
3815 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3817 if( token != T_LEFT )
3818 Expecting( T_LEFT );
3825 busEntry->SetPosition(
parseXY() );
3835 busEntry->SetSize( size );
3842 busEntry->SetStroke( stroke );
3852 Expecting(
"at, size, uuid or stroke" );
3856 return busEntry.release();
3876 std::unique_ptr<SCH_SHAPE> polyline = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY,
LAYER_NOTES );
3878 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3880 if( token != T_LEFT )
3881 Expecting( T_LEFT );
3888 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3890 if( token != T_LEFT )
3891 Expecting( T_LEFT );
3898 polyline->AddPoint(
parseXY() );
3911 polyline->SetStroke( stroke );
3917 polyline->SetFillColor( fill.
m_Color );
3928 Expecting(
"pts, uuid, stroke, or fill" );
3932 return polyline.release();
3951 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a line." );
3954 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>(
VECTOR2I(), layer );
3956 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3958 if( token != T_LEFT )
3959 Expecting( T_LEFT );
3972 line->SetStartPoint(
parseXY() );
3980 line->SetEndPoint(
parseXY() );
3987 line->SetStroke( stroke );
3997 Expecting(
"at, uuid or stroke" );
4001 return line.release();
4007 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
4008 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
4016 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>( SHAPE_T::ARC );
4018 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4020 if( token != T_LEFT )
4021 Expecting( T_LEFT );
4044 arc->SetStroke( stroke );
4050 arc->SetFillColor( fill.
m_Color );
4056 const_cast<KIID&
>( arc->m_Uuid ) =
KIID( FromUTF8() );
4061 Expecting(
"start, mid, end, stroke, fill or uuid" );
4065 arc->SetArcGeometry( startPoint, midPoint, endPoint );
4067 return arc.release();
4073 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
4074 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
4081 std::unique_ptr<SCH_SHAPE>
circle = std::make_unique<SCH_SHAPE>( SHAPE_T::CIRCLE );
4083 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4085 if( token != T_LEFT )
4086 Expecting( T_LEFT );
4104 circle->SetStroke( stroke );
4121 Expecting(
"center, radius, stroke, fill or uuid" );
4134 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
4135 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
4140 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>( SHAPE_T::RECTANGLE );
4142 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4144 if( token != T_LEFT )
4145 Expecting( T_LEFT );
4152 rectangle->SetPosition(
parseXY() );
4157 rectangle->SetEnd(
parseXY() );
4163 rectangle->SetStroke( stroke );
4169 rectangle->SetFillColor( fill.
m_Color );
4175 const_cast<KIID&
>( rectangle->m_Uuid ) =
KIID( FromUTF8() );
4180 Expecting(
"start, end, stroke, fill or uuid" );
4184 return rectangle.release();
4190 wxCHECK_MSG( CurTok() == T_rule_area,
nullptr,
4191 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rule area." ) );
4196 std::unique_ptr<SCH_RULE_AREA> ruleArea = std::make_unique<SCH_RULE_AREA>();
4198 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4200 if( token != T_LEFT )
4201 Expecting( T_LEFT );
4215 ruleArea->SetPolyShape( sch_rule_poly );
4217 ruleArea->SetStroke( poly->GetStroke() );
4218 ruleArea->SetFillMode( poly->GetFillMode() );
4219 ruleArea->SetFillColor( poly->GetFillColor() );
4222 const_cast<KIID&
>( ruleArea->m_Uuid ) = poly->m_Uuid;
4226 case T_exclude_from_sim:
4227 ruleArea->SetExcludedFromSim(
parseBool() );
4232 ruleArea->SetExcludedFromBOM( !
parseBool() );
4237 ruleArea->SetExcludedFromBoard( !
parseBool() );
4247 Expecting(
"exclude_from_sim, on_board, in_bom, dnp, or polyline" );
4251 return ruleArea.release();
4257 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
4258 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
4263 std::unique_ptr<SCH_SHAPE> bezier = std::make_unique<SCH_SHAPE>( SHAPE_T::BEZIER );
4265 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4267 if( token != T_LEFT )
4268 Expecting( T_LEFT );
4278 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
4280 if( token != T_LEFT )
4281 Expecting( T_LEFT );
4290 case 0: bezier->SetStart(
parseXY() );
break;
4291 case 1: bezier->SetBezierC1(
parseXY() );
break;
4292 case 2: bezier->SetBezierC2(
parseXY() );
break;
4293 case 3: bezier->SetEnd(
parseXY() );
break;
4294 default: Unexpected(
"control point" );
break;
4304 bezier->SetStroke( stroke );
4310 bezier->SetFillColor( fill.
m_Color );
4316 const_cast<KIID&
>( bezier->m_Uuid ) =
KIID( FromUTF8() );
4321 Expecting(
"pts, stroke, fill or uuid" );
4325 bezier->RebuildBezierToSegmentsPointsList(
m_maxError );
4327 return bezier.release();
4334 std::unique_ptr<SCH_TEXT>
text;
4338 case T_text:
text = std::make_unique<SCH_TEXT>();
break;
4339 case T_label:
text = std::make_unique<SCH_LABEL>();
break;
4340 case T_global_label:
text = std::make_unique<SCH_GLOBALLABEL>();
break;
4341 case T_hierarchical_label:
text = std::make_unique<SCH_HIERLABEL>();
break;
4342 case T_netclass_flag:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
4343 case T_directive_label:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
4345 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as text." );
4353 text->SetText( FromUTF8() );
4355 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4357 if( token != T_LEFT )
4358 Expecting( T_LEFT );
4364 case T_exclude_from_sim:
4375 switch(
static_cast<int>( label->GetTextAngle().AsDegrees() ) )
4391 Unexpected( T_shape );
4399 case T_input: label->
SetShape( LABEL_FLAG_SHAPE::L_INPUT );
break;
4400 case T_output: label->
SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
break;
4401 case T_bidirectional: label->
SetShape( LABEL_FLAG_SHAPE::L_BIDI );
break;
4402 case T_tri_state: label->
SetShape( LABEL_FLAG_SHAPE::L_TRISTATE );
break;
4403 case T_passive: label->
SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
break;
4404 case T_dot: label->
SetShape( LABEL_FLAG_SHAPE::F_DOT );
break;
4405 case T_round: label->
SetShape( LABEL_FLAG_SHAPE::F_ROUND );
break;
4406 case T_diamond: label->
SetShape( LABEL_FLAG_SHAPE::F_DIAMOND );
break;
4407 case T_rectangle: label->
SetShape( LABEL_FLAG_SHAPE::F_RECTANGLE );
break;
4409 Expecting(
"input, output, bidirectional, tri_state, passive, dot, round, diamond"
4420 Unexpected( T_length );
4429 case T_fields_autoplaced:
4439 text->SetVisible(
true );
4464 Unexpected( T_property );
4484 Expecting(
"at, shape, iref, uuid or effects" );
4490 if( label && label->
GetFields().empty() )
4493 return text.release();
4499 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
4500 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
4502 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>();
4506 return textBox.release();
4512 wxCHECK_MSG( CurTok() == T_table_cell,
nullptr,
4513 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table cell." ) );
4515 std::unique_ptr<SCH_TABLECELL> cell = std::make_unique<SCH_TABLECELL>();
4519 return cell.release();
4535 bool foundEnd =
false;
4536 bool foundSize =
false;
4537 bool foundMargins =
false;
4541 aTextBox->
SetText( FromUTF8() );
4543 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4545 if( token != T_LEFT )
4546 Expecting( T_LEFT );
4552 case T_exclude_from_sim:
4583 cell->SetColSpan(
parseInt(
"column span" ) );
4584 cell->SetRowSpan(
parseInt(
"row span" ) );
4588 Expecting(
"at, size, stroke, fill, effects or uuid" );
4612 foundMargins =
true;
4628 Expecting(
"at, size, stroke, fill, effects, span or uuid" );
4630 Expecting(
"at, size, stroke, fill, effects or uuid" );
4638 else if( foundSize )
4639 aTextBox->
SetEnd( pos + size );
4641 Expecting(
"size" );
4656 wxCHECK_MSG( CurTok() == T_table,
nullptr,
4657 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table." ) );
4661 STROKE_PARAMS borderStroke( defaultLineWidth, LINE_STYLE::DEFAULT );
4662 STROKE_PARAMS separatorsStroke( defaultLineWidth, LINE_STYLE::DEFAULT );
4663 std::unique_ptr<SCH_TABLE>
table = std::make_unique<SCH_TABLE>( defaultLineWidth );
4665 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4667 if( token != T_LEFT )
4668 Expecting( T_LEFT );
4674 case T_column_count:
4679 case T_column_widths:
4683 while( ( token = NextTok() ) != T_RIGHT )
4693 while( ( token = NextTok() ) != T_RIGHT )
4700 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4702 if( token != T_LEFT )
4703 Expecting( T_LEFT );
4707 if( token != T_table_cell )
4708 Expecting(
"table_cell" );
4716 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4718 if( token != T_LEFT )
4719 Expecting( T_LEFT );
4737 table->SetBorderStroke( borderStroke );
4741 Expecting(
"external, header or stroke" );
4749 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4751 if( token != T_LEFT )
4752 Expecting( T_LEFT );
4770 table->SetSeparatorsStroke( separatorsStroke );
4774 Expecting(
"rows, cols, or stroke" );
4788 Expecting(
"columns, col_widths, row_heights, border, separators, uuid, header or cells" );
4792 return table.release();
4798 wxCHECK_RET( CurTok() == T_bus_alias,
4799 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus alias." ) );
4800 wxCHECK( aScreen, );
4803 std::shared_ptr<BUS_ALIAS> busAlias = std::make_shared<BUS_ALIAS>( aScreen );
4814 busAlias->SetName( alias );
4819 if( token != T_members )
4820 Expecting(
"members" );
4824 while( token != T_RIGHT )
4826 if( !IsSymbol( token ) )
4827 Expecting(
"quoted string" );
4829 member = FromUTF8();
4834 busAlias->Members().emplace_back( member );
4849 while( ( token = NextTok() ) != T_RIGHT )
4854 KIID uuid( CurStr() );
4862 wxCHECK_RET( CurTok() == T_group,
4863 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GROUP." ) );
4870 while( ( token = NextTok() ) != T_LEFT )
4872 if( token == T_STRING )
4873 groupInfo.
name = FromUTF8();
4875 Expecting(
"group name or locked" );
4878 for( ; token != T_RIGHT; token = NextTok() )
4880 if( token != T_LEFT )
4881 Expecting( T_LEFT );
4897 if( !IsSymbol( token ) && token != T_NUMBER )
4898 Expecting(
"symbol|number" );
4901 wxString
name = FromUTF8();
4905 name.Replace(
"{slash}",
"/" );
4911 if(
static_cast<int>(
name.size() ) > bad_pos )
4913 wxString msg = wxString::Format(
_(
"Group library link %s contains invalid character '%c'" ),
name,
4919 THROW_PARSE_ERROR(
_(
"Invalid library ID" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
4933 Expecting(
"uuid, lib_id, members" );
4945 [&](
const KIID& aId )
4951 if( item->m_Uuid == aId )
4970 group->SetName( groupInfo.name );
4972 const_cast<KIID&
>(
group->m_Uuid ) = groupInfo.uuid;
4974 if( groupInfo.libId.IsValid() )
4975 group->SetDesignBlockLibId( groupInfo.libId );
4986 for(
const KIID& aUuid : groupInfo.memberUuids )
4988 if(
SCH_ITEM* gItem = getItem( aUuid ) )
4989 group->AddItem( gItem );
constexpr EDA_IU_SCALE schIUScale
constexpr double ARC_LOW_DEF_MM
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
void SetContentModified(bool aModified=true)
KICAD_T Type() const
Returns the type of object.
virtual void SetParent(EDA_ITEM *aParent)
EDA_ITEM * GetParent() const
FILL_T GetFillMode() const
SHAPE_POLY_SET & GetPolyShape()
void SetFillColor(const COLOR4D &aColor)
int GetPointCount() const
void SetEnd(const VECTOR2I &aEnd)
void SetFillMode(FILL_T aFill)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
void SetTextColor(const COLOR4D &aColor)
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.
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)
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)
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.
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...
virtual unsigned LineNumber() const
Return the line number of the last line read from this LINE_READER.
Describe the page size and margins of a paper page on which to eventually print or plot.
void SetPortrait(bool aIsPortrait)
Rotate the paper page 90 degrees.
static const wxChar Custom[]
"User" defined page type
void SetWidthMM(double aWidthInMM)
void SetHeightMM(double aHeightInMM)
bool SetType(const wxString &aStandardPageDescriptionName, bool aIsPortrait=false)
Set the name of the page type and also the sizes and margins commonly associated with that type name.
A progress reporter interface for use in multi-threaded environments.
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).
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)
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).
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)
SCH_RULE_AREA * parseSchRuleArea()
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)
void parseStroke(STROKE_PARAMS &aStroke)
Parse stroke definition aStroke.
int m_unit
The current unit being parsed.
SCH_SHAPE * parseSymbolBezier()
void parseEDA_TEXT(EDA_TEXT *aText, bool aConvertOverbarSyntax, bool aEnforceMinTextSize=true)
SCH_TEXTBOX * parseSchTextBox()
void resolveGroups(SCH_SCREEN *aParent)
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 parseMargins(int &aLeft, int &aTop, int &aRight, int &aBottom)
wxString m_symbolName
The current symbol name.
VECTOR2I parseXY(bool aInvertY=false)
SCH_SHAPE * parseSymbolRectangle()
void parsePinNames(std::unique_ptr< LIB_SYMBOL > &aSymbol)
SCH_SHAPE * parseSchBezier()
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 * 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 parseSchSheetInstances(SCH_SHEET *aRootSheet, SCH_SCREEN *aScreen)
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 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 (and transfers ownership of the pointer).
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.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
SCH_SCREEN * GetScreen() const
void SetMarginBottom(int aBottom)
int GetLegacyTextMargin() const
void SetMarginLeft(int aLeft)
void SetMarginRight(int aRight)
void SetMarginTop(int aTop)
void SetExcludedFromSim(bool aExclude) override
void SetCenter(const VECTOR2I &aCenter)
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.
#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_SHAPE
Fill with object color.
FONTCONFIG * Fontconfig()
#define THROW_IO_ERROR(msg)
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
#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.
#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)
constexpr int MilsToIU(int mils) const
A filename or source description, a problem input line, a line number, a byte offset,...
std::vector< KIID > memberUuids
ELECTRICAL_PINTYPE m_Type
A simple container for sheet instance information.
A simple container for schematic symbol instance information.
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...
#define SHEET_MANDATORY_FIELDS
#define GLOBALLABEL_MANDATORY_FIELDS
wxString GetCanonicalFieldName(FIELD_T aFieldType)
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