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 )
96 const unsigned PROGRESS_DELTA = 500;
118 KIID id( FromUTF8() );
135 else if( token == T_no )
138 Expecting(
"yes or no" );
149 bool ret = aDefaultValue;
151 if( PrevTok() == T_LEFT )
156 if(
static_cast<int>( token ) ==
DSN_RIGHT )
157 return aDefaultValue;
161 else if( token == T_no )
164 Expecting(
"yes or no" );
171 return aDefaultValue;
186 bool versionChecked =
false;
197 versionChecked =
true;
200 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
202 if( token != T_LEFT )
228 case T_generator_version:
248 aSymbolLibMap[symbol->
GetName()] = symbol;
253 Expecting(
"symbol, generator, or generator_version" );
267 if( CurTok() == T_LEFT )
271 if( CurTok() == T_symbol )
276 const std::vector<wxString>* embeddedFonts =
283 textItem->ResolveFont( embeddedFonts );
285 RECURSE_MODE::NO_RECURSE );
289 wxString msg = wxString::Format(
_(
"Cannot parse %s as a symbol" ),
290 GetTokenString( CurTok() ) );
301 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
302 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
308 wxString unitDisplayName;
310 std::unique_ptr<LIB_SYMBOL> symbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
312 symbol->SetUnitCount( 1 );
316 if( !IsSymbol( token ) )
318 THROW_PARSE_ERROR(
_(
"Invalid symbol name" ), CurSource(), CurLine(), CurLineNumber(),
327 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
334 if(
static_cast<int>(
name.size() ) > bad_pos )
336 wxString msg = wxString::Format(
_(
"Symbol %s contains invalid character '%c'" ),
345 CurLineNumber(), CurOffset() );
350 symbol->SetLibId(
id );
352 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
354 if( token != T_LEFT )
362 symbol->SetGlobalPower();
365 if( token == T_RIGHT )
368 if( token == T_local )
369 symbol->SetLocalPower();
370 else if( token != T_global )
371 Expecting(
"global or local" );
384 case T_exclude_from_sim:
385 symbol->SetExcludedFromSim(
parseBool() );
390 symbol->SetExcludedFromBOM( !
parseBool() );
395 symbol->SetExcludedFromBoard( !
parseBool() );
399 case T_duplicate_pin_numbers_are_jumpers:
400 symbol->SetDuplicatePinNumbersAreJumpers(
parseBool() );
404 case T_jumper_pin_groups:
407 std::vector<std::set<wxString>>& groups = symbol->JumperPinGroups();
408 std::set<wxString>* currentGroup =
nullptr;
410 for( token = NextTok(); currentGroup || token != T_RIGHT; token = NextTok() )
412 switch(
static_cast<int>( token ) )
415 currentGroup = &groups.emplace_back();
419 currentGroup->insert( FromUTF8() );
423 currentGroup =
nullptr;
427 Expecting(
"list of pin names" );
442 if( !IsSymbol( token ) )
445 CurLineNumber(), CurOffset() );
453 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
455 auto it = aSymbolLibMap.find(
name );
457 if( it == aSymbolLibMap.end() )
459 error.Printf(
_(
"No parent for extended symbol %s" ),
name.c_str() );
460 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
463 symbol->SetParent( it->second );
472 if( !IsSymbol( token ) )
475 CurLineNumber(), CurOffset() );
483 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
487 error.Printf(
_(
"Invalid symbol unit name prefix %s" ),
name.c_str() );
488 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
493 wxStringTokenizer tokenizer(
name,
"_" );
495 if( tokenizer.CountTokens() != 2 )
497 error.Printf(
_(
"Invalid symbol unit name suffix %s" ),
name.c_str() );
498 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
501 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
503 error.Printf(
_(
"Invalid symbol unit number %s" ),
name.c_str() );
504 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
507 m_unit =
static_cast<int>( tmp );
509 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
511 error.Printf(
_(
"Invalid symbol convert number %s" ),
name.c_str() );
512 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
518 symbol->SetHasAlternateBodyStyle(
true,
false );
520 if(
m_unit > symbol->GetUnitCount() )
521 symbol->SetUnitCount(
m_unit,
false );
523 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
525 if( token != T_LEFT )
535 if( IsSymbol( token ) )
537 unitDisplayName = FromUTF8();
538 symbol->SetUnitDisplayName(
m_unit, unitDisplayName );
554 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
557 symbol->AddDrawItem( item,
false );
561 Expecting(
"arc, bezier, circle, pin, polyline, rectangle, or text" );
580 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
583 symbol->AddDrawItem( item,
false );
586 case T_embedded_fonts:
588 symbol->SetAreFontsEmbedded(
parseBool() );
593 case T_embedded_files:
596 embeddedFilesParser.SyncLineReaderWith( *
this );
600 embeddedFilesParser.
ParseEmbedded( symbol->GetEmbeddedFiles() );
604 wxLogError( e.
What() );
607 SyncLineReaderWith( embeddedFilesParser );
612 Expecting(
"pin_names, pin_numbers, arc, bezier, circle, pin, polyline, "
613 "rectangle, or text" );
617 symbol->GetDrawItems().sort();
620 const std::vector<wxString>* embeddedFonts =
621 symbol->GetEmbeddedFiles()->UpdateFontFiles();
623 symbol->RunOnChildren(
627 textItem->ResolveFont( embeddedFonts );
629 RECURSE_MODE::NO_RECURSE );
631 return symbol.release();
647 default: Expecting(
"arc, bezier, circle, pin, polyline, rectangle, or text" );
661 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
663 return KiROUND( std::clamp( retval, -int_limit, int_limit ) );
671 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
673 return KiROUND( std::clamp( retval, -int_limit, int_limit ) );
680 strokeParser.SyncLineReaderWith( *
this );
683 SyncLineReaderWith( strokeParser );
689 wxCHECK_RET( CurTok() == T_fill,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a fill." );
692 aFill.
m_Color = COLOR4D::UNSPECIFIED;
696 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
698 if( token != T_LEFT )
711 case T_none: aFill.
m_FillType = FILL_T::NO_FILL;
break;
712 case T_outline: aFill.
m_FillType = FILL_T::FILLED_SHAPE;
break;
713 case T_background: aFill.
m_FillType = FILL_T::FILLED_WITH_BG_BODYCOLOR;
break;
714 case T_color: aFill.
m_FillType = FILL_T::FILLED_WITH_COLOR;
break;
715 case T_hatch: aFill.
m_FillType = FILL_T::HATCH;
break;
716 case T_reverse_hatch: aFill.
m_FillType = FILL_T::REVERSE_HATCH;
break;
717 case T_cross_hatch: aFill.
m_FillType = FILL_T::CROSS_HATCH;
break;
718 default: Expecting(
"none, outline, hatch, reverse_hatch, "
719 "cross_hatch, color or background" );
740 Expecting(
"type or color" );
747 bool aEnforceMinTextSize )
749 wxCHECK_RET( aText && ( CurTok() == T_effects || CurTok() == T_href ),
750 "Cannot parse " + GetTokenString( CurTok() ) +
" as an EDA_TEXT." );
767 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
769 if( token == T_LEFT )
775 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
777 if( token == T_LEFT )
828 Expecting(
"face, size, thickness, line_spacing, bold, or italic" );
835 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
844 case T_mirror:
break;
845 default: Expecting(
"left, right, top, bottom, or mirror" );
854 wxString hyperlink = FromUTF8();
859 CurSource(), CurLine(), CurLineNumber(), CurOffset() );
878 Expecting(
"font, justify, hide or href" );
886 wxCHECK_RET( CurTok() == aHeaderType,
887 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a header." ) );
893 if( tok == T_version )
907 wxCHECK_RET( CurTok() == T_pin_names,
908 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_name token." );
918 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
921 if( token == T_hide )
923 aSymbol->SetShowPinNames(
false );
927 if( token != T_LEFT )
942 aSymbol->SetShowPinNames( !
parseBool() );
947 Expecting(
"offset or hide" );
955 wxCHECK_RET( CurTok() == T_pin_numbers,
956 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_number token." );
965 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
968 if( token == T_hide )
970 aSymbol->SetShowPinNumbers(
false );
974 if( token != T_LEFT )
984 aSymbol->SetShowPinNumbers( !
parseBool() );
998 wxCHECK_MSG( CurTok() == T_property,
nullptr,
999 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a property." ) );
1000 wxCHECK( aSymbol,
nullptr );
1002 FIELD_T fieldId = FIELD_T::USER;
1005 bool isPrivate =
false;
1006 bool isVisible =
true;
1008 T token = NextTok();
1010 if( token == T_private )
1016 if( !IsSymbol( token ) )
1018 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
1024 if(
name.IsEmpty() )
1026 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
1040 auto field = std::make_unique<SCH_FIELD>( aSymbol.get(), fieldId,
name );
1041 field->SetPrivate( isPrivate );
1042 field->SetVisible( isVisible );
1046 if( !IsSymbol( token ) )
1048 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
1055 value = wxEmptyString;
1059 field->SetText( value );
1061 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1063 if( token != T_LEFT )
1064 Expecting( T_LEFT );
1076 field->SetPosition(
parseXY(
true ) );
1088 field->GetId() == FIELD_T::VALUE );
1094 field->SetNameShown( show );
1098 case T_do_not_autoplace:
1101 field->SetCanAutoplace( !doNotAutoplace );
1106 Expecting(
"id, at, hide, show_name, do_not_autoplace, or effects" );
1112 if( field->IsMandatory() )
1114 existingField = aSymbol->GetField( field->GetId() );
1116 *existingField = *field;
1117 return existingField;
1119 else if(
name ==
"ki_keywords" )
1122 aSymbol->SetKeyWords( value );
1126 else if(
name ==
"ki_description" )
1128 aSymbol->SetDescription( value );
1131 else if(
name ==
"ki_fp_filters" )
1134 wxArrayString filters;
1135 wxStringTokenizer tokenizer( value );
1137 while( tokenizer.HasMoreTokens() )
1139 wxString curr_token =
UnescapeString( tokenizer.GetNextToken() );
1140 filters.Add( curr_token );
1143 aSymbol->SetFPFilters( filters );
1146 else if(
name ==
"ki_locked" )
1150 aSymbol->LockUnits(
true );
1156 existingField = aSymbol->GetField( field->GetCanonicalName() );
1167 for(
int ii = 1; ii < 10 && existingField; ii++ )
1169 wxString newname = base_name;
1170 newname <<
'_' << ii;
1172 existingField = aSymbol->GetField( newname );
1174 if( !existingField )
1175 field->SetName( newname );
1179 if( !existingField )
1181 aSymbol->AddDrawItem( field.get(),
false );
1182 return field.release();
1195 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
1196 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
1202 bool hasMidPoint =
false;
1210 bool hasAngles =
false;
1212 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>( SHAPE_T::ARC,
LAYER_DEVICE );
1219 if( token == T_private )
1221 arc->SetPrivate(
true );
1225 for( ; token != T_RIGHT; token = NextTok() )
1227 if( token != T_LEFT )
1228 Expecting( T_LEFT );
1251 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1253 if( token != T_LEFT )
1254 Expecting( T_LEFT );
1282 Expecting(
"at, length, or angles" );
1290 arc->SetStroke( stroke );
1296 arc->SetFillColor( fill.
m_Color );
1300 Expecting(
"start, mid, end, radius, stroke, or fill" );
1306 arc->SetArcGeometry( startPoint, midPoint, endPoint );
1317 EDA_ANGLE arc_start, arc_end, arc_angle;
1318 arc->CalcArcAngles( arc_start, arc_end );
1319 arc_angle = arc_end - arc_start;
1324 arc->SetStart( endPoint );
1325 arc->SetEnd( startPoint );
1328 arc->SetCenter( new_center );
1334 arc->SetCenter( new_center );
1338 else if( hasAngles )
1340 arc->SetCenter(
center );
1346 arc->SetStart( endPoint );
1347 arc->SetEnd( startPoint );
1351 EDA_ANGLE arc_start, arc_end, arc_angle;
1352 arc->CalcArcAngles( arc_start, arc_end );
1353 arc_angle = arc_end - arc_start;
1359 arc->SetStart( startPoint );
1360 arc->SetEnd( endPoint );
1368 arc->SetStart( startPoint );
1369 arc->SetEnd( endPoint );
1373 arc->SetCenter( new_center );
1379 wxFAIL_MSG(
"Setting arc without either midpoint or angles not implemented." );
1382 return arc.release();
1388 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
1389 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
1395 std::unique_ptr<SCH_SHAPE> bezier = std::make_unique<SCH_SHAPE>( SHAPE_T::BEZIER,
LAYER_DEVICE );
1397 bezier->SetUnit(
m_unit );
1402 if( token == T_private )
1404 bezier->SetPrivate(
true );
1408 for( ; token != T_RIGHT; token = NextTok() )
1410 if( token != T_LEFT )
1411 Expecting( T_LEFT );
1421 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
1423 if( token != T_LEFT )
1424 Expecting( T_LEFT );
1433 case 0: bezier->SetStart(
parseXY(
true ) );
break;
1434 case 1: bezier->SetBezierC1(
parseXY(
true ) );
break;
1435 case 2: bezier->SetBezierC2(
parseXY(
true ) );
break;
1436 case 3: bezier->SetEnd(
parseXY(
true ) );
break;
1437 default: Unexpected(
"control point" );
break;
1447 bezier->SetStroke( stroke );
1453 bezier->SetFillColor( fill.
m_Color );
1457 Expecting(
"pts, stroke, or fill" );
1461 bezier->RebuildBezierToSegmentsPointsList( bezier->GetPenWidth() / 2 );
1463 return bezier.release();
1469 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
1470 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
1478 std::unique_ptr<SCH_SHAPE>
circle = std::make_unique<SCH_SHAPE>( SHAPE_T::CIRCLE,
LAYER_DEVICE );
1485 if( token == T_private )
1487 circle->SetPrivate(
true );
1491 for( ; token != T_RIGHT; token = NextTok() )
1493 if( token != T_LEFT )
1494 Expecting( T_LEFT );
1512 circle->SetStroke( stroke );
1522 Expecting(
"center, radius, stroke, or fill" );
1540 case T_input:
return ELECTRICAL_PINTYPE::PT_INPUT;
1541 case T_output:
return ELECTRICAL_PINTYPE::PT_OUTPUT;
1542 case T_bidirectional:
return ELECTRICAL_PINTYPE::PT_BIDI;
1543 case T_tri_state:
return ELECTRICAL_PINTYPE::PT_TRISTATE;
1544 case T_passive:
return ELECTRICAL_PINTYPE::PT_PASSIVE;
1545 case T_unspecified:
return ELECTRICAL_PINTYPE::PT_UNSPECIFIED;
1546 case T_power_in:
return ELECTRICAL_PINTYPE::PT_POWER_IN;
1547 case T_power_out:
return ELECTRICAL_PINTYPE::PT_POWER_OUT;
1548 case T_open_collector:
return ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR;
1549 case T_open_emitter:
return ELECTRICAL_PINTYPE::PT_OPENEMITTER;
1551 case T_no_connect:
return ELECTRICAL_PINTYPE::PT_NC;
1552 case T_free:
return ELECTRICAL_PINTYPE::PT_NIC;
1555 Expecting(
"input, output, bidirectional, tri_state, passive, unspecified, "
1556 "power_in, power_out, open_collector, open_emitter, free or "
1558 return ELECTRICAL_PINTYPE::PT_UNSPECIFIED;
1567 case T_line:
return GRAPHIC_PINSHAPE::LINE;
1568 case T_inverted:
return GRAPHIC_PINSHAPE::INVERTED;
1569 case T_clock:
return GRAPHIC_PINSHAPE::CLOCK;
1570 case T_inverted_clock:
return GRAPHIC_PINSHAPE::INVERTED_CLOCK;
1571 case T_input_low:
return GRAPHIC_PINSHAPE::INPUT_LOW;
1572 case T_clock_low:
return GRAPHIC_PINSHAPE::CLOCK_LOW;
1573 case T_output_low:
return GRAPHIC_PINSHAPE::OUTPUT_LOW;
1574 case T_edge_clock_high:
return GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK;
1575 case T_non_logic:
return GRAPHIC_PINSHAPE::NONLOGIC;
1578 Expecting(
"line, inverted, clock, inverted_clock, input_low, clock_low, "
1579 "output_low, edge_clock_high, non_logic" );
1580 return GRAPHIC_PINSHAPE::LINE;
1584 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
1585 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a pin token." ) );
1590 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>(
nullptr );
1597 pin->SetType( parseType( token ) );
1601 pin->SetShape( parseShape( token ) );
1603 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1606 if( token == T_hide )
1608 pin->SetVisible(
false );
1612 if( token != T_LEFT )
1613 Expecting( T_LEFT );
1622 switch(
parseInt(
"pin orientation" ) )
1624 case 0:
pin->SetOrientation( PIN_ORIENTATION::PIN_RIGHT );
break;
1625 case 90:
pin->SetOrientation( PIN_ORIENTATION::PIN_UP );
break;
1626 case 180:
pin->SetOrientation( PIN_ORIENTATION::PIN_LEFT );
break;
1627 case 270:
pin->SetOrientation( PIN_ORIENTATION::PIN_DOWN );
break;
1628 default: Expecting(
"0, 90, 180, or 270" );
1647 if( !IsSymbol( token ) )
1654 pin->SetName( wxEmptyString );
1658 pin->SetName( FromUTF8() );
1662 if( token != T_RIGHT )
1666 if( token == T_effects )
1673 pin->SetNameTextSize(
text.GetTextHeight() );
1678 Expecting(
"effects" );
1687 if( !IsSymbol( token ) )
1690 CurLineNumber(), CurOffset() );
1694 pin->SetNumber( wxEmptyString );
1698 pin->SetNumber( FromUTF8() );
1702 if( token != T_RIGHT )
1706 if( token == T_effects )
1713 pin->SetNumberTextSize(
text.GetTextHeight() );
1718 Expecting(
"effects" );
1730 if( !IsSymbol( token ) )
1733 CurLineNumber(), CurOffset() );
1739 alt.
m_Type = parseType( token );
1742 alt.
m_Shape = parseShape( token );
1744 pin->GetAlternates()[ alt.
m_Name ] = alt;
1751 Expecting(
"at, name, number, hide, length, or alternate" );
1755 return pin.release();
1761 wxCHECK_MSG( CurTok() == T_polyline,
nullptr,
1762 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a poly." ) );
1767 std::unique_ptr<SCH_SHAPE> poly = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY,
LAYER_DEVICE );
1774 if( token == T_private )
1776 poly->SetPrivate(
true );
1780 for( ; token != T_RIGHT; token = NextTok() )
1782 if( token != T_LEFT )
1783 Expecting( T_LEFT );
1790 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1792 if( token != T_LEFT )
1793 Expecting( T_LEFT );
1800 poly->AddPoint(
parseXY(
true ) );
1809 poly->SetStroke( stroke );
1815 poly->SetFillColor( fill.
m_Color );
1819 Expecting(
"pts, stroke, or fill" );
1823 return poly.release();
1829 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
1830 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
1835 auto rectangle = std::make_unique<SCH_SHAPE>( SHAPE_T::RECTANGLE,
LAYER_DEVICE );
1837 rectangle->SetUnit(
m_unit );
1842 if( token == T_private )
1844 rectangle->SetPrivate(
true );
1848 for( ; token != T_RIGHT; token = NextTok() )
1850 if( token != T_LEFT )
1851 Expecting( T_LEFT );
1858 rectangle->SetPosition(
parseXY(
true ) );
1863 rectangle->SetEnd(
parseXY(
true ) );
1869 rectangle->SetStroke( stroke );
1875 rectangle->SetFillColor( fill.
m_Color );
1879 Expecting(
"start, end, stroke, or fill" );
1883 return rectangle.release();
1889 wxCHECK_MSG( CurTok() == T_text,
nullptr,
1890 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text token." ) );
1893 std::unique_ptr<SCH_TEXT>
text = std::make_unique<SCH_TEXT>();
1900 if( token == T_private )
1902 text->SetPrivate(
true );
1906 if( !IsSymbol( token ) )
1908 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
1912 text->SetText( FromUTF8() );
1914 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1916 if( token != T_LEFT )
1917 Expecting( T_LEFT );
1935 Expecting(
"at or effects" );
1940 if( !
text->IsVisible() )
1943 return text.release();
1949 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
1950 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
1962 bool foundEnd =
false;
1963 bool foundSize =
false;
1964 bool foundMargins =
false;
1966 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>(
LAYER_DEVICE );
1968 textBox->SetUnit(
m_unit );
1972 if( token == T_private )
1974 textBox->SetPrivate(
true );
1978 if( !IsSymbol( token ) )
1980 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
1984 textBox->SetText( FromUTF8() );
1986 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1988 if( token != T_LEFT )
1989 Expecting( T_LEFT );
2020 textBox->SetStroke( stroke );
2026 textBox->SetFillColor( fill.
m_Color );
2031 textBox->SetMarginLeft(
left );
2032 textBox->SetMarginTop( top );
2033 textBox->SetMarginRight(
right );
2034 textBox->SetMarginBottom( bottom );
2035 foundMargins =
true;
2044 Expecting(
"at, size, stroke, fill or effects" );
2048 textBox->SetPosition( pos );
2051 textBox->SetEnd(
end );
2052 else if( foundSize )
2053 textBox->SetEnd( pos + size );
2055 Expecting(
"size" );
2059 int margin = textBox->GetLegacyTextMargin();
2060 textBox->SetMarginLeft( margin );
2061 textBox->SetMarginTop( margin );
2062 textBox->SetMarginRight( margin );
2063 textBox->SetMarginBottom( margin );
2066 return textBox.release();
2072 wxCHECK_RET( ( CurTok() == T_page &&
m_requiredVersion <= 20200506 ) || CurTok() == T_paper,
2073 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a PAGE_INFO." ) );
2079 wxString pageType = FromUTF8();
2081 if( !aPageInfo.
SetType( pageType ) )
2083 THROW_PARSE_ERROR(
_(
"Invalid page type" ), CurSource(), CurLine(), CurLineNumber(),
2110 if( token == T_portrait )
2115 else if( token != T_RIGHT )
2117 Expecting(
"portrait" );
2124 wxCHECK_RET( CurTok() == T_title_block,
2125 "Cannot parse " + GetTokenString( CurTok() ) +
" as a TITLE_BLOCK." );
2129 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2131 if( token != T_LEFT )
2132 Expecting( T_LEFT );
2140 aTitleBlock.
SetTitle( FromUTF8() );
2145 aTitleBlock.
SetDate( FromUTF8() );
2160 int commentNumber =
parseInt(
"comment" );
2162 switch( commentNumber )
2211 CurLine(), CurLineNumber(), CurOffset() );
2218 Expecting(
"title, date, rev, company, or comment" );
2228 wxCHECK_MSG( CurTok() == T_property,
nullptr,
2229 "Cannot parse " + GetTokenString( CurTok() ) +
" as a property token." );
2231 bool is_private =
false;
2233 T token = NextTok();
2235 if( token == T_private )
2241 if( !IsSymbol( token ) )
2243 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
2247 wxString
name = FromUTF8();
2249 if(
name.IsEmpty() )
2251 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
2257 if( !IsSymbol( token ) )
2259 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
2267 value = wxEmptyString;
2271 FIELD_T fieldId = FIELD_T::USER;
2297 if(
name.CmpNoCase( wxT(
"Sheet name" ) ) == 0 )
2298 fieldId = FIELD_T::SHEET_NAME;
2299 else if(
name.CmpNoCase( wxT(
"Sheet file" ) ) == 0 )
2300 fieldId = FIELD_T::SHEET_FILENAME;
2314 if(
name.CmpNoCase( wxT(
"Intersheet References" ) ) == 0 )
2315 fieldId = FIELD_T::INTERSHEET_REFS;
2318 std::unique_ptr<SCH_FIELD> field = std::make_unique<SCH_FIELD>( aParent, fieldId,
name );
2319 field->SetText( value );
2321 if( fieldId == FIELD_T::USER )
2322 field->SetPrivate( is_private );
2324 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2326 if( token != T_LEFT )
2327 Expecting( T_LEFT );
2339 field->SetPosition(
parseXY() );
2351 field->GetId() == FIELD_T::VALUE );
2357 field->SetNameShown( show );
2361 case T_do_not_autoplace:
2364 field->SetCanAutoplace( !doNotAutoplace );
2369 Expecting(
"id, at, hide, show_name, do_not_autoplace or effects" );
2373 return field.release();
2379 wxCHECK_MSG( aSheet !=
nullptr,
nullptr,
"" );
2380 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
2381 "Cannot parse " + GetTokenString( CurTok() ) +
" as a sheet pin token." );
2383 T token = NextTok();
2385 if( !IsSymbol( token ) )
2387 THROW_PARSE_ERROR(
_(
"Invalid sheet pin name" ), CurSource(), CurLine(), CurLineNumber(),
2391 wxString
name = FromUTF8();
2393 if(
name.IsEmpty() )
2395 THROW_PARSE_ERROR(
_(
"Empty sheet pin name" ), CurSource(), CurLine(), CurLineNumber(),
2399 auto sheetPin = std::make_unique<SCH_SHEET_PIN>( aSheet,
VECTOR2I( 0, 0 ),
name );
2405 case T_input: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_INPUT );
break;
2406 case T_output: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
break;
2407 case T_bidirectional: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_BIDI );
break;
2408 case T_tri_state: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_TRISTATE );
break;
2409 case T_passive: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
break;
2411 Expecting(
"input, output, bidirectional, tri_state, or passive" );
2414 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2416 if( token != T_LEFT )
2417 Expecting( T_LEFT );
2425 sheetPin->SetPosition(
parseXY() );
2427 double angle =
parseDouble(
"sheet pin angle (side)" );
2430 sheetPin->SetSide( SHEET_SIDE::RIGHT );
2431 else if( angle == 90.0 )
2432 sheetPin->SetSide( SHEET_SIDE::TOP );
2433 else if( angle == 180.0 )
2434 sheetPin->SetSide( SHEET_SIDE::LEFT );
2435 else if( angle == 270.0 )
2436 sheetPin->SetSide( SHEET_SIDE::BOTTOM );
2438 Expecting(
"0, 90, 180, or 270" );
2455 Expecting(
"at, uuid or effects" );
2459 return sheetPin.release();
2465 wxCHECK_RET( CurTok() == T_sheet_instances,
2466 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
2467 wxCHECK( aScreen, );
2471 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2473 if( token != T_LEFT )
2474 Expecting( T_LEFT );
2492 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2494 if( token != T_LEFT )
2495 Expecting( T_LEFT );
2499 std::vector<wxString> whitespaces = { wxT(
"\r" ), wxT(
"\n" ), wxT(
"\t" ),
2502 size_t numReplacements = 0;
2520 for(
const wxString& ch : whitespaces )
2521 numReplacements += instance.
m_PageNumber.Replace( ch, wxEmptyString );
2526 if( numReplacements > 0 )
2533 Expecting(
"path or page" );
2538 && ( instance.
m_Path.empty() ) )
2554 Expecting(
"path" );
2562 wxCHECK_RET( CurTok() == T_symbol_instances,
2563 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
2564 wxCHECK( aScreen, );
2569 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2571 if( token != T_LEFT )
2572 Expecting( T_LEFT );
2589 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2591 if( token != T_LEFT )
2592 Expecting( T_LEFT );
2613 instance.
m_Value = wxEmptyString;
2615 instance.
m_Value = FromUTF8();
2632 Expecting(
"path, unit, value or footprint" );
2641 Expecting(
"path" );
2650 wxCHECK( aSheet !=
nullptr, );
2654 wxCHECK( screen !=
nullptr, );
2656 if( aIsCopyableOnly )
2659 bool fileHasUuid =
false;
2673 if( !aIsCopyableOnly )
2678 if( CurTok() != T_kicad_sch )
2679 Expecting(
"kicad_sch" );
2695 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2697 if( aIsCopyableOnly && token == T_EOF )
2700 if( token != T_LEFT )
2701 Expecting( T_LEFT );
2735 case T_generator_version:
2761 if( aIsCopyableOnly )
2762 Unexpected( T_paper );
2772 if( aIsCopyableOnly )
2773 Unexpected( T_page );
2777 NeedSYMBOLorNUMBER();
2778 NeedSYMBOLorNUMBER();
2785 if( aIsCopyableOnly )
2786 Unexpected( T_title_block );
2800 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2802 if( token != T_LEFT )
2803 Expecting( T_LEFT );
2815 Expecting(
"symbol" );
2916 case T_netclass_flag:
2921 case T_global_label:
2922 case T_hierarchical_label:
2923 case T_directive_label:
2935 case T_sheet_instances:
2939 case T_symbol_instances:
2944 if( aIsCopyableOnly )
2945 Unexpected( T_bus_alias );
2950 case T_embedded_fonts:
2956 CurLineNumber(), CurOffset() );
2963 case T_embedded_files:
2969 CurLineNumber(), CurOffset() );
2972 embeddedFilesParser.SyncLineReaderWith( *
this );
2980 wxLogError( e.
What() );
2983 SyncLineReaderWith( embeddedFilesParser );
2989 Expecting(
"bitmap, bus, bus_alias, bus_entry, class_label, embedded_files, global_label, "
2990 "hierarchical_label, junction, label, line, no_connect, page, paper, rule_area, "
2991 "sheet, symbol, symbol_instances, text, title_block" );
3012 CurLineNumber(), CurOffset() );
3016 std::vector<std::string> fontNames;
3017 Fontconfig()->ListFonts( fontNames, std::string(
Pgm().GetLanguageTag().utf8_str() ),
3027 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
3028 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
3033 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
3035 std::set<int> fieldIDsRead;
3040 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3042 if( token != T_LEFT )
3043 Expecting( T_LEFT );
3055 if( !IsSymbol( token ) )
3058 CurLineNumber(), CurOffset() );
3061 libName = FromUTF8();
3065 libName.Replace(
"{slash}",
"/" );
3075 if( !IsSymbol( token ) && token != T_NUMBER )
3076 Expecting(
"symbol|number" );
3079 wxString
name = FromUTF8();
3083 name.Replace(
"{slash}",
"/" );
3089 if(
static_cast<int>(
name.size() ) > bad_pos )
3091 wxString msg = wxString::Format(
3092 _(
"Symbol %s contains invalid character '%c'" ),
name,
3099 CurLineNumber(), CurOffset() );
3102 symbol->SetLibId( libId );
3108 symbol->SetPosition(
parseXY() );
3110 switch(
static_cast<int>(
parseDouble(
"symbol orientation" ) ) )
3113 case 90: transform =
TRANSFORM( 0, 1, -1, 0 );
break;
3114 case 180: transform =
TRANSFORM( -1, 0, 0, -1 );
break;
3115 case 270: transform =
TRANSFORM( 0, -1, 1, 0 );
break;
3116 default: Expecting(
"0, 90, 180, or 270" );
3119 symbol->SetTransform( transform );
3128 else if( token == T_y )
3131 Expecting(
"x or y" );
3137 symbol->SetUnit(
parseInt(
"symbol unit" ) );
3144 symbol->SetBodyStyleUnconditional(
parseInt(
"symbol body style" ) );
3148 case T_exclude_from_sim:
3149 symbol->SetExcludedFromSim(
parseBool() );
3154 symbol->SetExcludedFromBOM( !
parseBool() );
3159 symbol->SetExcludedFromBoard( !
parseBool() );
3168 case T_fields_autoplaced:
3180 case T_default_instance:
3184 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3186 if( token != T_LEFT )
3187 Expecting( T_LEFT );
3208 symbol->SetValueFieldText( wxEmptyString );
3210 symbol->SetValueFieldText( FromUTF8() );
3219 symbol->SetFootprintFieldText( wxEmptyString );
3221 symbol->SetFootprintFieldText( FromUTF8() );
3227 Expecting(
"reference, unit, value or footprint" );
3236 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3238 if( token != T_LEFT )
3239 Expecting( T_LEFT );
3243 if( token != T_project )
3244 Expecting(
"project" );
3248 wxString projectName = FromUTF8();
3250 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3252 if( token != T_LEFT )
3253 Expecting( T_LEFT );
3257 if( token != T_path )
3258 Expecting(
"path" );
3267 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3269 if( token != T_LEFT )
3270 Expecting( T_LEFT );
3291 symbol->SetValueFieldText( wxEmptyString );
3293 symbol->SetValueFieldText( FromUTF8() );
3302 symbol->SetFootprintFieldText( wxEmptyString );
3304 symbol->SetFootprintFieldText( FromUTF8() );
3310 Expecting(
"reference, unit, value or footprint" );
3313 symbol->AddHierarchicalReference( instance );
3330 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"0" ) );
3337 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"N" ) );
3344 existing = symbol->GetField( field->
GetId() );
3346 existing = symbol->GetField( field->
GetName() );
3351 symbol->AddField( *field );
3353 if( field->
GetId() == FIELD_T::REFERENCE )
3354 symbol->UpdatePrefix();
3367 number = FromUTF8();
3369 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3371 if( token != T_LEFT )
3372 Expecting( T_LEFT );
3396 Expecting(
"alternate or uuid" );
3400 symbol->GetRawPins().emplace_back( std::make_unique<SCH_PIN>( symbol.get(), number,
3406 Expecting(
"lib_id, lib_name, at, mirror, uuid, on_board, in_bom, dnp, "
3407 "default_instance, property, pin, or instances" );
3411 if( !libName.IsEmpty() && ( symbol->GetLibId().Format().wx_str() != libName ) )
3412 symbol->SetSchSymbolLibraryName( libName );
3415 symbol->ClearFlags();
3417 return symbol.release();
3423 wxCHECK_MSG( CurTok() == T_image,
nullptr,
3424 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an image." ) );
3427 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>();
3430 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3432 if( token != T_LEFT )
3433 Expecting( T_LEFT );
3440 bitmap->SetPosition(
parseXY() );
3466 data.reserve( 1 << 17 );
3468 while( token != T_RIGHT )
3470 if( !IsSymbol( token ) )
3471 Expecting(
"base64 image data" );
3477 wxMemoryBuffer buffer = wxBase64Decode( data );
3486 Expecting(
"at, scale, uuid or data" );
3499 return bitmap.release();
3505 wxCHECK_MSG( CurTok() == T_sheet,
nullptr,
3506 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a sheet." ) );
3512 std::vector<SCH_FIELD> fields;
3513 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>();
3514 std::set<int> fieldIDsRead;
3519 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3521 if( token != T_LEFT )
3522 Expecting( T_LEFT );
3529 sheet->SetPosition(
parseXY() );
3538 sheet->SetSize( size );
3543 case T_exclude_from_sim:
3544 sheet->SetExcludedFromSim(
parseBool() );
3549 sheet->SetExcludedFromBOM( !
parseBool() );
3554 sheet->SetExcludedFromBoard( !
parseBool() );
3563 case T_fields_autoplaced:
3571 sheet->SetBorderWidth( stroke.
GetWidth() );
3572 sheet->SetBorderColor( stroke.
GetColor() );
3577 sheet->SetBackgroundColor( fill.
m_Color );
3594 if( fields.empty() )
3595 field->
setId( FIELD_T::SHEET_NAME );
3597 field->
setId( FIELD_T::SHEET_FILENAME );
3600 fields.emplace_back( *field );
3611 std::vector<SCH_SHEET_INSTANCE> instances;
3613 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3615 if( token != T_LEFT )
3616 Expecting( T_LEFT );
3620 if( token != T_project )
3621 Expecting(
"project" );
3625 wxString projectName = FromUTF8();
3627 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3629 if( token != T_LEFT )
3630 Expecting( T_LEFT );
3634 if( token != T_path )
3635 Expecting(
"path" );
3644 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3646 if( token != T_LEFT )
3647 Expecting( T_LEFT );
3667 static std::vector<wxString> whitespaces =
3673 for( wxString ch : whitespaces )
3682 Expecting(
"page" );
3686 instances.emplace_back( instance );
3690 sheet->setInstances( instances );
3695 Expecting(
"at, size, stroke, background, instances, uuid, property, or pin" );
3699 sheet->SetFields( fields );
3701 return sheet.release();
3707 wxCHECK_MSG( CurTok() == T_junction,
nullptr,
3708 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a junction." ) );
3711 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
3713 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3715 if( token != T_LEFT )
3716 Expecting( T_LEFT );
3723 junction->SetPosition(
parseXY() );
3741 junction->SetColor(
color );
3753 Expecting(
"at, diameter, color or uuid" );
3757 return junction.release();
3763 wxCHECK_MSG( CurTok() == T_no_connect,
nullptr,
3764 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a no connect." ) );
3767 std::unique_ptr<SCH_NO_CONNECT> no_connect = std::make_unique<SCH_NO_CONNECT>();
3769 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3771 if( token != T_LEFT )
3772 Expecting( T_LEFT );
3779 no_connect->SetPosition(
parseXY() );
3790 Expecting(
"at or uuid" );
3794 return no_connect.release();
3800 wxCHECK_MSG( CurTok() == T_bus_entry,
nullptr,
3801 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus entry." ) );
3805 std::unique_ptr<SCH_BUS_WIRE_ENTRY> busEntry = std::make_unique<SCH_BUS_WIRE_ENTRY>();
3807 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3809 if( token != T_LEFT )
3810 Expecting( T_LEFT );
3817 busEntry->SetPosition(
parseXY() );
3827 busEntry->SetSize( size );
3834 busEntry->SetStroke( stroke );
3844 Expecting(
"at, size, uuid or stroke" );
3848 return busEntry.release();
3868 std::unique_ptr<SCH_SHAPE> polyline = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY,
LAYER_NOTES );
3870 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3872 if( token != T_LEFT )
3873 Expecting( T_LEFT );
3880 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3882 if( token != T_LEFT )
3883 Expecting( T_LEFT );
3890 polyline->AddPoint(
parseXY() );
3903 polyline->SetStroke( stroke );
3909 polyline->SetFillColor( fill.
m_Color );
3920 Expecting(
"pts, uuid, stroke, or fill" );
3924 return polyline.release();
3943 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a line." );
3946 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>(
VECTOR2I(), layer );
3948 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3950 if( token != T_LEFT )
3951 Expecting( T_LEFT );
3964 line->SetStartPoint(
parseXY() );
3972 line->SetEndPoint(
parseXY() );
3979 line->SetStroke( stroke );
3989 Expecting(
"at, uuid or stroke" );
3993 return line.release();
3999 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
4000 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
4008 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>( SHAPE_T::ARC );
4010 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4012 if( token != T_LEFT )
4013 Expecting( T_LEFT );
4036 arc->SetStroke( stroke );
4042 arc->SetFillColor( fill.
m_Color );
4048 const_cast<KIID&
>( arc->m_Uuid ) =
KIID( FromUTF8() );
4053 Expecting(
"start, mid, end, stroke, fill or uuid" );
4057 arc->SetArcGeometry( startPoint, midPoint, endPoint );
4059 return arc.release();
4065 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
4066 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
4073 std::unique_ptr<SCH_SHAPE>
circle = std::make_unique<SCH_SHAPE>( SHAPE_T::CIRCLE );
4075 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4077 if( token != T_LEFT )
4078 Expecting( T_LEFT );
4096 circle->SetStroke( stroke );
4113 Expecting(
"center, radius, stroke, fill or uuid" );
4126 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
4127 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
4132 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>( SHAPE_T::RECTANGLE );
4134 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4136 if( token != T_LEFT )
4137 Expecting( T_LEFT );
4144 rectangle->SetPosition(
parseXY() );
4149 rectangle->SetEnd(
parseXY() );
4155 rectangle->SetStroke( stroke );
4161 rectangle->SetFillColor( fill.
m_Color );
4167 const_cast<KIID&
>( rectangle->m_Uuid ) =
KIID( FromUTF8() );
4172 Expecting(
"start, end, stroke, fill or uuid" );
4176 return rectangle.release();
4182 wxCHECK_MSG( CurTok() == T_rule_area,
nullptr,
4183 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rule area." ) );
4188 std::unique_ptr<SCH_RULE_AREA> ruleArea = std::make_unique<SCH_RULE_AREA>();
4190 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4192 if( token != T_LEFT )
4193 Expecting( T_LEFT );
4207 ruleArea->SetPolyShape( sch_rule_poly );
4209 ruleArea->SetStroke( poly->GetStroke() );
4210 ruleArea->SetFillMode( poly->GetFillMode() );
4211 ruleArea->SetFillColor( poly->GetFillColor() );
4215 Expecting(
"polyline" );
4219 return ruleArea.release();
4225 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
4226 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
4231 std::unique_ptr<SCH_SHAPE> bezier = std::make_unique<SCH_SHAPE>( SHAPE_T::BEZIER );
4233 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4235 if( token != T_LEFT )
4236 Expecting( T_LEFT );
4246 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
4248 if( token != T_LEFT )
4249 Expecting( T_LEFT );
4258 case 0: bezier->SetStart(
parseXY() );
break;
4259 case 1: bezier->SetBezierC1(
parseXY() );
break;
4260 case 2: bezier->SetBezierC2(
parseXY() );
break;
4261 case 3: bezier->SetEnd(
parseXY() );
break;
4262 default: Unexpected(
"control point" );
break;
4272 bezier->SetStroke( stroke );
4278 bezier->SetFillColor( fill.
m_Color );
4284 const_cast<KIID&
>( bezier->m_Uuid ) =
KIID( FromUTF8() );
4289 Expecting(
"pts, stroke, fill or uuid" );
4293 bezier->RebuildBezierToSegmentsPointsList( bezier->GetPenWidth() / 2 );
4295 return bezier.release();
4302 std::unique_ptr<SCH_TEXT>
text;
4306 case T_text:
text = std::make_unique<SCH_TEXT>();
break;
4307 case T_label:
text = std::make_unique<SCH_LABEL>();
break;
4308 case T_global_label:
text = std::make_unique<SCH_GLOBALLABEL>();
break;
4309 case T_hierarchical_label:
text = std::make_unique<SCH_HIERLABEL>();
break;
4310 case T_netclass_flag:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
4311 case T_directive_label:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
4313 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as text." );
4321 text->SetText( FromUTF8() );
4323 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4325 if( token != T_LEFT )
4326 Expecting( T_LEFT );
4332 case T_exclude_from_sim:
4343 switch(
static_cast<int>( label->GetTextAngle().AsDegrees() ) )
4359 Unexpected( T_shape );
4367 case T_input: label->
SetShape( LABEL_FLAG_SHAPE::L_INPUT );
break;
4368 case T_output: label->
SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
break;
4369 case T_bidirectional: label->
SetShape( LABEL_FLAG_SHAPE::L_BIDI );
break;
4370 case T_tri_state: label->
SetShape( LABEL_FLAG_SHAPE::L_TRISTATE );
break;
4371 case T_passive: label->
SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
break;
4372 case T_dot: label->
SetShape( LABEL_FLAG_SHAPE::F_DOT );
break;
4373 case T_round: label->
SetShape( LABEL_FLAG_SHAPE::F_ROUND );
break;
4374 case T_diamond: label->
SetShape( LABEL_FLAG_SHAPE::F_DIAMOND );
break;
4375 case T_rectangle: label->
SetShape( LABEL_FLAG_SHAPE::F_RECTANGLE );
break;
4377 Expecting(
"input, output, bidirectional, tri_state, passive, dot, round, diamond"
4388 Unexpected( T_length );
4397 case T_fields_autoplaced:
4407 text->SetVisible(
true );
4432 Unexpected( T_property );
4452 Expecting(
"at, shape, iref, uuid or effects" );
4458 if( label && label->
GetFields().empty() )
4461 return text.release();
4467 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
4468 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
4470 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>();
4474 return textBox.release();
4480 wxCHECK_MSG( CurTok() == T_table_cell,
nullptr,
4481 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table cell." ) );
4483 std::unique_ptr<SCH_TABLECELL> cell = std::make_unique<SCH_TABLECELL>();
4487 return cell.release();
4503 bool foundEnd =
false;
4504 bool foundSize =
false;
4505 bool foundMargins =
false;
4509 aTextBox->
SetText( FromUTF8() );
4511 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4513 if( token != T_LEFT )
4514 Expecting( T_LEFT );
4520 case T_exclude_from_sim:
4551 cell->SetColSpan(
parseInt(
"column span" ) );
4552 cell->SetRowSpan(
parseInt(
"row span" ) );
4556 Expecting(
"at, size, stroke, fill, effects or uuid" );
4580 foundMargins =
true;
4596 Expecting(
"at, size, stroke, fill, effects, span or uuid" );
4598 Expecting(
"at, size, stroke, fill, effects or uuid" );
4606 else if( foundSize )
4607 aTextBox->
SetEnd( pos + size );
4609 Expecting(
"size" );
4624 wxCHECK_MSG( CurTok() == T_table,
nullptr,
4625 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table." ) );
4629 STROKE_PARAMS borderStroke( defaultLineWidth, LINE_STYLE::DEFAULT );
4630 STROKE_PARAMS separatorsStroke( defaultLineWidth, LINE_STYLE::DEFAULT );
4631 std::unique_ptr<SCH_TABLE>
table = std::make_unique<SCH_TABLE>( defaultLineWidth );
4633 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4635 if( token != T_LEFT )
4636 Expecting( T_LEFT );
4642 case T_column_count:
4647 case T_column_widths:
4651 while( ( token = NextTok() ) != T_RIGHT )
4661 while( ( token = NextTok() ) != T_RIGHT )
4668 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4670 if( token != T_LEFT )
4671 Expecting( T_LEFT );
4675 if( token != T_table_cell )
4676 Expecting(
"table_cell" );
4684 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4686 if( token != T_LEFT )
4687 Expecting( T_LEFT );
4705 table->SetBorderStroke( borderStroke );
4709 Expecting(
"external, header or stroke" );
4717 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4719 if( token != T_LEFT )
4720 Expecting( T_LEFT );
4738 table->SetSeparatorsStroke( separatorsStroke );
4742 Expecting(
"rows, cols, or stroke" );
4756 Expecting(
"columns, col_widths, row_heights, border, separators, uuid, header or cells" );
4760 return table.release();
4766 wxCHECK_RET( CurTok() == T_bus_alias,
4767 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus alias." ) );
4768 wxCHECK( aScreen, );
4771 std::shared_ptr<BUS_ALIAS> busAlias = std::make_shared<BUS_ALIAS>( aScreen );
4782 busAlias->SetName( alias );
4787 if( token != T_members )
4788 Expecting(
"members" );
4792 while( token != T_RIGHT )
4794 if( !IsSymbol( token ) )
4795 Expecting(
"quoted string" );
4797 member = FromUTF8();
4802 busAlias->Members().emplace_back( member );
4817 while( ( token = NextTok() ) != T_RIGHT )
4822 KIID uuid( CurStr() );
4830 wxCHECK_RET( CurTok() == T_group,
4831 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GROUP." ) );
4838 while( ( token = NextTok() ) != T_LEFT )
4840 if( token == T_STRING )
4841 groupInfo.
name = FromUTF8();
4843 Expecting(
"group name or locked" );
4846 for( ; token != T_RIGHT; token = NextTok() )
4848 if( token != T_LEFT )
4849 Expecting( T_LEFT );
4865 if( !IsSymbol( token ) && token != T_NUMBER )
4866 Expecting(
"symbol|number" );
4868 wxString
name = FromUTF8();
4872 name.Replace(
"{slash}",
"/" );
4878 if(
static_cast<int>(
name.size() ) > bad_pos )
4880 wxString msg = wxString::Format(
_(
"Group library link %s contains invalid character '%c'" ),
name,
4886 THROW_PARSE_ERROR(
_(
"Invalid library ID" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
4900 Expecting(
"uuid, lib_id, members" );
4912 [&](
const KIID& aId )
4918 if( item->m_Uuid == aId )
4937 group->SetName( groupInfo.name );
4939 const_cast<KIID&
>(
group->m_Uuid ) = groupInfo.uuid;
4941 if( groupInfo.libId.IsValid() )
4942 group->SetDesignBlockLibId( groupInfo.libId );
4953 for(
const KIID& aUuid : groupInfo.memberUuids )
4955 SCH_ITEM* gItem = getItem( aUuid );
4963 group->AddItem( gItem );
constexpr EDA_IU_SCALE schIUScale
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)
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.
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)
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.
@ NOT_USED
the 3d code uses this value
VECTOR2< int32_t > VECTOR2I