31#include <fmt/format.h>
35#include <wx/mstream.h>
36#include <wx/tokenzr.h>
74using namespace TSCHEMATIC_T;
79 unsigned aLineCount,
SCH_SHEET* aRootSheet,
81 SCHEMATIC_LEXER( aLineReader ),
100 unsigned progressDelta = std::max( 50u,
m_lineCount / 10 );
119 KIID id( FromUTF8() );
136 else if( token == T_no )
139 Expecting(
"yes or no" );
150 bool ret = aDefaultValue;
152 if( PrevTok() == T_LEFT )
157 if(
static_cast<int>( token ) ==
DSN_RIGHT )
158 return aDefaultValue;
162 else if( token == T_no )
165 Expecting(
"yes or no" );
172 return aDefaultValue;
190 bool versionChecked =
false;
201 versionChecked =
true;
204 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
206 if( token != T_LEFT )
232 case T_generator_version:
255 aSymbolLibMap[symbol->
GetName()] = symbol;
260 wxString warning = wxString::Format(
261 _(
"Error parsing symbol at line %d: %s\nSkipping symbol and continuing." ),
262 CurLineNumber(), e.
What() );
274 Expecting(
"symbol, generator, or generator_version" );
288 if( CurTok() == T_LEFT )
292 if( CurTok() == T_symbol )
297 const std::vector<wxString>* embeddedFonts =
304 textItem->ResolveFont( embeddedFonts );
310 wxString msg = wxString::Format(
_(
"Cannot parse %s as a symbol" ),
311 GetTokenString( CurTok() ) );
322 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
323 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
330 std::unique_ptr<LIB_SYMBOL> symbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
332 symbol->SetUnitCount( 1,
true );
336 if( !IsSymbol( token ) )
337 THROW_PARSE_ERROR(
_(
"Invalid symbol name" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
344 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
351 if(
static_cast<int>(
name.size() ) > bad_pos )
353 wxString msg = wxString::Format(
_(
"Symbol %s contains invalid character '%c'" ),
362 CurLineNumber(), CurOffset() );
367 symbol->SetLibId(
id );
369 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
371 if( token != T_LEFT )
379 symbol->SetGlobalPower();
382 if( token == T_RIGHT )
385 if( token == T_local )
386 symbol->SetLocalPower();
387 else if( token != T_global )
388 Expecting(
"global or local" );
405 case T_exclude_from_sim:
406 symbol->SetExcludedFromSim(
parseBool() );
411 symbol->SetExcludedFromBOM( !
parseBool() );
416 symbol->SetExcludedFromBoard( !
parseBool() );
421 symbol->SetExcludedFromPosFiles( !
parseBool() );
425 case T_duplicate_pin_numbers_are_jumpers:
426 symbol->SetDuplicatePinNumbersAreJumpers(
parseBool() );
430 case T_jumper_pin_groups:
432 std::vector<std::set<wxString>>& groups = symbol->JumperPinGroups();
433 std::set<wxString>* currentGroup =
nullptr;
435 for( token = NextTok(); currentGroup || token != T_RIGHT; token = NextTok() )
437 switch(
static_cast<int>( token ) )
440 currentGroup = &groups.emplace_back();
444 currentGroup->insert( FromUTF8() );
448 currentGroup =
nullptr;
452 Expecting(
"list of pin names" );
467 if( !IsSymbol( token ) )
470 CurLineNumber(), CurOffset() );
478 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
480 symbol->SetParentName(
name );
489 if( !IsSymbol( token ) )
492 CurLineNumber(), CurOffset() );
500 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
504 error.Printf(
_(
"Invalid symbol unit name prefix %s" ),
name.c_str() );
505 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
510 wxStringTokenizer tokenizer(
name,
"_" );
512 if( tokenizer.CountTokens() != 2 )
514 error.Printf(
_(
"Invalid symbol unit name suffix %s" ),
name.c_str() );
515 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
518 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
520 error.Printf(
_(
"Invalid symbol unit number %s" ),
name.c_str() );
521 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
524 m_unit =
static_cast<int>( tmp );
526 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
528 error.Printf(
_(
"Invalid symbol body style number %s" ),
name.c_str() );
529 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
535 symbol->SetBodyStyleCount(
m_bodyStyle,
false,
false );
537 if(
m_unit > symbol->GetUnitCount() )
538 symbol->SetUnitCount(
m_unit,
false );
540 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
542 if( token != T_LEFT )
552 if( IsSymbol( token ) )
553 symbol->GetUnitDisplayNames()[
m_unit] = FromUTF8();
570 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
573 symbol->AddDrawItem( item,
false );
577 Expecting(
"arc, bezier, circle, ellipse, ellipse_arc, pin, polyline, "
578 "rectangle, or text" );
599 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
602 symbol->AddDrawItem( item,
false );
605 case T_embedded_fonts:
607 symbol->SetAreFontsEmbedded(
parseBool() );
612 case T_embedded_files:
615 embeddedFilesParser.SyncLineReaderWith( *
this );
619 embeddedFilesParser.
ParseEmbedded( symbol->GetEmbeddedFiles() );
627 for(
int tok = embeddedFilesParser.NextTok();
629 tok = embeddedFilesParser.NextTok() )
633 else if( tok ==
DSN_RIGHT && --depth < 0 )
638 SyncLineReaderWith( embeddedFilesParser );
643 Expecting(
"pin_names, pin_numbers, arc, bezier, circle, ellipse, ellipse_arc, "
644 "pin, polyline, rectangle, or text" );
648 symbol->GetDrawItems().sort();
651 const std::vector<wxString>* embeddedFonts = symbol->GetEmbeddedFiles()->UpdateFontFiles();
653 symbol->RunOnChildren(
657 textItem->ResolveFont( embeddedFonts );
664 symbol->SetHasDeMorganBodyStyles( symbol->HasLegacyAlternateBodyStyle() );
666 symbol->RefreshLibraryTreeCaches();
668 return symbol.release();
687 Expecting(
"arc, bezier, circle, ellipse, ellipse_arc, pin, "
688 "polyline, rectangle, or text" );
702 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
704 return KiROUND( std::clamp( retval, -int_limit, int_limit ) );
712 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
714 return KiROUND( std::clamp( retval, -int_limit, int_limit ) );
721 strokeParser.SyncLineReaderWith( *
this );
724 SyncLineReaderWith( strokeParser );
730 wxCHECK_RET( CurTok() == T_fill,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a fill." );
737 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
739 if( token != T_LEFT )
759 default: Expecting(
"none, outline, hatch, reverse_hatch, "
760 "cross_hatch, color or background" );
774 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
781 Expecting(
"type or color" );
788 bool aEnforceMinTextSize )
790 wxCHECK_RET( aText && ( CurTok() == T_effects || CurTok() == T_href ),
791 "Cannot parse " + GetTokenString( CurTok() ) +
" as an EDA_TEXT." );
808 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
810 if( token == T_LEFT )
816 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
818 if( token == T_LEFT )
858 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
869 Expecting(
"face, size, thickness, line_spacing, bold, or italic" );
876 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
885 case T_mirror:
break;
886 default: Expecting(
"left, right, top, bottom, or mirror" );
895 wxString hyperlink = FromUTF8();
900 CurSource(), CurLine(), CurLineNumber(), CurOffset() );
919 Expecting(
"font, justify, hide or href" );
927 if( CurTok() != aHeaderType )
930 GetTokenString( CurTok() ) ),
931 CurSource(), CurLine(), CurLineNumber(), CurOffset() );
938 if( tok == T_version )
952 wxCHECK_RET( CurTok() == T_body_styles,
953 "Cannot parse " + GetTokenString( CurTok() ) +
" as a body_styles token." );
955 std::vector<wxString> names;
957 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
959 if( token == T_demorgan )
961 aSymbol->SetHasDeMorganBodyStyles(
true );
964 else if( !IsSymbol( token ) )
966 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
970 names.push_back( FromUTF8() );
974 aSymbol->SetBodyStyleNames( names );
980 wxCHECK_RET( CurTok() == T_pin_names,
981 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_name token." );
991 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
994 if( token == T_hide )
996 aSymbol->SetShowPinNames(
false );
1000 if( token != T_LEFT )
1002 Expecting( T_LEFT );
1015 aSymbol->SetShowPinNames( !
parseBool() );
1020 Expecting(
"offset or hide" );
1028 wxCHECK_RET( CurTok() == T_pin_numbers,
1029 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_number token." );
1038 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1041 if( token == T_hide )
1043 aSymbol->SetShowPinNumbers(
false );
1047 if( token != T_LEFT )
1049 Expecting( T_LEFT );
1057 aSymbol->SetShowPinNumbers( !
parseBool() );
1062 Expecting(
"hide" );
1071 wxCHECK_MSG( CurTok() == T_property,
nullptr,
1072 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a property." ) );
1073 wxCHECK( aSymbol,
nullptr );
1078 bool isPrivate =
false;
1079 bool isVisible =
true;
1081 T token = NextTok();
1083 if( token == T_private )
1089 if( !IsSymbol( token ) )
1091 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
1097 if(
name.IsEmpty() )
1099 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
1113 auto field = std::make_unique<SCH_FIELD>( aSymbol.get(), fieldId,
name );
1114 field->SetPrivate( isPrivate );
1115 field->SetVisible( isVisible );
1119 if( !IsSymbol( token ) )
1121 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
1128 value = wxEmptyString;
1132 field->SetText( value );
1134 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1136 if( token != T_LEFT )
1137 Expecting( T_LEFT );
1149 field->SetPosition(
parseXY(
true ) );
1167 field->SetNameShown( show );
1171 case T_do_not_autoplace:
1174 field->SetCanAutoplace( !doNotAutoplace );
1179 Expecting(
"id, at, hide, show_name, do_not_autoplace, or effects" );
1185 if( field->IsMandatory() )
1187 existingField = aSymbol->GetField( field->GetId() );
1189 *existingField = *field;
1190 return existingField;
1192 else if(
name ==
"ki_keywords" )
1195 aSymbol->SetKeyWords( value );
1199 else if(
name ==
"ki_description" )
1201 aSymbol->SetDescription( value );
1204 else if(
name ==
"ki_fp_filters" )
1207 wxArrayString filters;
1208 wxStringTokenizer tokenizer( value,
" \t\r\n", wxTOKEN_STRTOK );
1210 while( tokenizer.HasMoreTokens() )
1212 wxString curr_token =
UnescapeString( tokenizer.GetNextToken() );
1213 filters.Add( curr_token );
1216 aSymbol->SetFPFilters( filters );
1219 else if(
name ==
"ki_locked" )
1223 aSymbol->LockUnits(
true );
1229 existingField = aSymbol->GetField( field->GetCanonicalName() );
1237 wxString base_name = field->GetCanonicalName();
1240 for(
int ii = 1; ii < 10 && existingField; ii++ )
1242 wxString newname = base_name;
1243 newname <<
'_' << ii;
1245 existingField = aSymbol->GetField( newname );
1247 if( !existingField )
1248 field->SetName( newname );
1252 if( !existingField )
1254 aSymbol->AddDrawItem( field.get(),
false );
1255 return field.release();
1268 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
1269 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
1275 bool hasMidPoint =
false;
1283 bool hasAngles =
false;
1292 if( token == T_private )
1294 arc->SetPrivate(
true );
1298 for( ; token != T_RIGHT; token = NextTok() )
1300 if( token != T_LEFT )
1301 Expecting( T_LEFT );
1324 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1326 if( token != T_LEFT )
1327 Expecting( T_LEFT );
1355 Expecting(
"at, length, or angles" );
1363 arc->SetStroke( stroke );
1369 arc->SetFillColor( fill.
m_Color );
1373 Expecting(
"start, mid, end, radius, stroke, or fill" );
1379 arc->SetArcGeometry( startPoint, midPoint, endPoint );
1390 EDA_ANGLE arc_start, arc_end, arc_angle;
1391 arc->CalcArcAngles( arc_start, arc_end );
1392 arc_angle = arc_end - arc_start;
1397 arc->SetStart( endPoint );
1398 arc->SetEnd( startPoint );
1401 arc->SetCenter( new_center );
1407 arc->SetCenter( new_center );
1411 else if( hasAngles )
1413 arc->SetCenter(
center );
1419 arc->SetStart( endPoint );
1420 arc->SetEnd( startPoint );
1424 EDA_ANGLE arc_start, arc_end, arc_angle;
1425 arc->CalcArcAngles( arc_start, arc_end );
1426 arc_angle = arc_end - arc_start;
1432 arc->SetStart( startPoint );
1433 arc->SetEnd( endPoint );
1441 arc->SetStart( startPoint );
1442 arc->SetEnd( endPoint );
1446 arc->SetCenter( new_center );
1452 wxFAIL_MSG(
"Setting arc without either midpoint or angles not implemented." );
1455 return arc.release();
1461 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
1462 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
1470 bezier->SetUnit(
m_unit );
1475 if( token == T_private )
1477 bezier->SetPrivate(
true );
1481 for( ; token != T_RIGHT; token = NextTok() )
1483 if( token != T_LEFT )
1484 Expecting( T_LEFT );
1494 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
1496 if( token != T_LEFT )
1497 Expecting( T_LEFT );
1506 case 0: bezier->SetStart(
parseXY(
true ) );
break;
1507 case 1: bezier->SetBezierC1(
parseXY(
true ) );
break;
1508 case 2: bezier->SetBezierC2(
parseXY(
true ) );
break;
1509 case 3: bezier->SetEnd(
parseXY(
true ) );
break;
1510 default: Unexpected(
"control point" );
break;
1520 bezier->SetStroke( stroke );
1526 bezier->SetFillColor( fill.
m_Color );
1530 Expecting(
"pts, stroke, or fill" );
1534 bezier->RebuildBezierToSegmentsPointsList(
m_maxError );
1536 return bezier.release();
1542 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
1543 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
1558 if( token == T_private )
1560 circle->SetPrivate(
true );
1564 for( ; token != T_RIGHT; token = NextTok() )
1566 if( token != T_LEFT )
1567 Expecting( T_LEFT );
1585 circle->SetStroke( stroke );
1595 Expecting(
"center, radius, stroke, or fill" );
1608 wxCHECK_MSG( CurTok() == T_ellipse,
nullptr,
1609 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an ellipse." ) );
1612 ellipse->SetUnit(
m_unit );
1615 T token = NextTok();
1617 if( token == T_private )
1619 ellipse->SetPrivate(
true );
1624 return ellipse.release();
1630 wxCHECK_MSG( CurTok() == T_ellipse_arc,
nullptr,
1631 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an elliptical arc." ) );
1637 T token = NextTok();
1639 if( token == T_private )
1641 arc->SetPrivate(
true );
1646 return arc.release();
1672 Expecting(
"input, output, bidirectional, tri_state, passive, unspecified, "
1673 "power_in, power_out, open_collector, open_emitter, free or "
1695 Expecting(
"line, inverted, clock, inverted_clock, input_low, clock_low, "
1696 "output_low, edge_clock_high, non_logic" );
1701 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
1702 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a pin token." ) );
1705 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>(
nullptr );
1712 pin->SetType( parseType( token ) );
1716 pin->SetShape( parseShape( token ) );
1718 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1721 if( token == T_hide )
1723 pin->SetVisible(
false );
1727 if( token != T_LEFT )
1728 Expecting( T_LEFT );
1737 switch(
parseInt(
"pin orientation" ) )
1743 default: Expecting(
"0, 90, 180, or 270" );
1762 if( !IsSymbol( token ) )
1769 pin->SetName( wxEmptyString );
1773 pin->SetName( FromUTF8() );
1777 if( token != T_RIGHT )
1781 if( token == T_effects )
1788 pin->SetNameTextSize(
text.GetTextHeight() );
1793 Expecting(
"effects" );
1802 if( !IsSymbol( token ) )
1805 CurLineNumber(), CurOffset() );
1809 pin->SetNumber( wxEmptyString );
1813 pin->SetNumber( FromUTF8() );
1817 if( token != T_RIGHT )
1821 if( token == T_effects )
1828 pin->SetNumberTextSize(
text.GetTextHeight() );
1833 Expecting(
"effects" );
1845 if( !IsSymbol( token ) )
1848 CurLineNumber(), CurOffset() );
1854 alt.
m_Type = parseType( token );
1857 alt.
m_Shape = parseShape( token );
1859 pin->GetAlternates()[ alt.
m_Name ] = alt;
1866 Expecting(
"at, name, number, hide, length, or alternate" );
1870 return pin.release();
1876 wxCHECK_MSG( CurTok() == T_polyline,
nullptr,
1877 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a poly." ) );
1889 if( token == T_private )
1891 poly->SetPrivate(
true );
1895 for( ; token != T_RIGHT; token = NextTok() )
1897 if( token != T_LEFT )
1898 Expecting( T_LEFT );
1905 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1907 if( token != T_LEFT )
1908 Expecting( T_LEFT );
1915 poly->AddPoint(
parseXY(
true ) );
1924 poly->SetStroke( stroke );
1930 poly->SetFillColor( fill.
m_Color );
1934 Expecting(
"pts, stroke, or fill" );
1938 return poly.release();
1944 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
1945 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
1952 rectangle->SetUnit(
m_unit );
1957 if( token == T_private )
1959 rectangle->SetPrivate(
true );
1963 for( ; token != T_RIGHT; token = NextTok() )
1965 if( token != T_LEFT )
1966 Expecting( T_LEFT );
1973 rectangle->SetPosition(
parseXY(
true ) );
1978 rectangle->SetEnd(
parseXY(
true ) );
1989 rectangle->SetStroke( stroke );
1995 rectangle->SetFillColor( fill.
m_Color );
1999 Expecting(
"start, end, stroke, or fill" );
2003 return rectangle.release();
2009 wxCHECK_MSG( CurTok() == T_text,
nullptr,
2010 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text token." ) );
2013 std::unique_ptr<SCH_TEXT>
text = std::make_unique<SCH_TEXT>();
2020 if( token == T_private )
2022 text->SetPrivate(
true );
2026 if( !IsSymbol( token ) )
2028 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
2032 text->SetText( FromUTF8() );
2034 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2036 if( token != T_LEFT )
2037 Expecting( T_LEFT );
2055 Expecting(
"at or effects" );
2060 if( !
text->IsVisible() )
2063 return text.release();
2069 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
2070 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
2082 bool foundEnd =
false;
2083 bool foundSize =
false;
2084 bool foundMargins =
false;
2086 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>(
LAYER_DEVICE );
2088 textBox->SetUnit(
m_unit );
2092 if( token == T_private )
2094 textBox->SetPrivate(
true );
2098 if( !IsSymbol( token ) )
2100 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
2104 textBox->SetText( FromUTF8() );
2106 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2108 if( token != T_LEFT )
2109 Expecting( T_LEFT );
2140 textBox->SetStroke( stroke );
2146 textBox->SetFillColor( fill.
m_Color );
2151 textBox->SetMarginLeft(
left );
2152 textBox->SetMarginTop(
top );
2153 textBox->SetMarginRight(
right );
2154 textBox->SetMarginBottom( bottom );
2155 foundMargins =
true;
2164 Expecting(
"at, size, stroke, fill or effects" );
2168 textBox->SetPosition( pos );
2171 textBox->SetEnd(
end );
2172 else if( foundSize )
2173 textBox->SetEnd( pos + size );
2175 Expecting(
"size" );
2179 int margin = textBox->GetLegacyTextMargin();
2180 textBox->SetMarginLeft( margin );
2181 textBox->SetMarginTop( margin );
2182 textBox->SetMarginRight( margin );
2183 textBox->SetMarginBottom( margin );
2186 return textBox.release();
2192 wxCHECK_RET( ( CurTok() == T_page &&
m_requiredVersion <= 20200506 ) || CurTok() == T_paper,
2193 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a PAGE_INFO." ) );
2199 wxString pageType = FromUTF8();
2201 if( !aPageInfo.
SetType( pageType ) )
2203 THROW_PARSE_ERROR(
_(
"Invalid page type" ), CurSource(), CurLine(), CurLineNumber(),
2230 if( token == T_portrait )
2235 else if( token != T_RIGHT )
2237 Expecting(
"portrait" );
2244 wxCHECK_RET( CurTok() == T_title_block,
2245 "Cannot parse " + GetTokenString( CurTok() ) +
" as a TITLE_BLOCK." );
2249 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2251 if( token != T_LEFT )
2252 Expecting( T_LEFT );
2260 aTitleBlock.
SetTitle( FromUTF8() );
2265 aTitleBlock.
SetDate( FromUTF8() );
2280 int commentNumber =
parseInt(
"comment" );
2282 switch( commentNumber )
2331 CurLine(), CurLineNumber(), CurOffset() );
2338 Expecting(
"title, date, rev, company, or comment" );
2348 wxCHECK_MSG( CurTok() == T_property,
nullptr,
2349 "Cannot parse " + GetTokenString( CurTok() ) +
" as a property token." );
2351 bool is_private =
false;
2353 T token = NextTok();
2355 if( token == T_private )
2361 if( !IsSymbol( token ) )
2363 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
2367 wxString
name = FromUTF8();
2369 if(
name.IsEmpty() )
2371 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
2377 if( !IsSymbol( token ) )
2379 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
2387 value = wxEmptyString;
2419 if(
name.CmpNoCase( wxT(
"Sheet name" ) ) == 0 )
2421 else if(
name.CmpNoCase( wxT(
"Sheet file" ) ) == 0 )
2436 if(
name.CmpNoCase( wxT(
"Intersheet References" ) ) == 0 )
2440 std::unique_ptr<SCH_FIELD> field = std::make_unique<SCH_FIELD>( aParent, fieldId,
name );
2441 field->SetText( value );
2444 field->SetPrivate( is_private );
2446 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2448 if( token != T_LEFT )
2449 Expecting( T_LEFT );
2461 field->SetPosition(
parseXY() );
2479 field->SetNameShown( show );
2483 case T_do_not_autoplace:
2486 field->SetCanAutoplace( !doNotAutoplace );
2491 Expecting(
"id, at, hide, show_name, do_not_autoplace or effects" );
2495 return field.release();
2501 wxCHECK_MSG( aSheet !=
nullptr,
nullptr,
"" );
2502 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
2503 "Cannot parse " + GetTokenString( CurTok() ) +
" as a sheet pin token." );
2505 T token = NextTok();
2507 if( !IsSymbol( token ) )
2509 THROW_PARSE_ERROR(
_(
"Invalid sheet pin name" ), CurSource(), CurLine(), CurLineNumber(),
2513 wxString
name = FromUTF8();
2515 if(
name.IsEmpty() )
2517 THROW_PARSE_ERROR(
_(
"Empty sheet pin name" ), CurSource(), CurLine(), CurLineNumber(),
2521 auto sheetPin = std::make_unique<SCH_SHEET_PIN>( aSheet,
VECTOR2I( 0, 0 ),
name );
2533 Expecting(
"input, output, bidirectional, tri_state, or passive" );
2536 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2538 if( token != T_LEFT )
2539 Expecting( T_LEFT );
2547 sheetPin->SetPosition(
parseXY() );
2549 double angle =
parseDouble(
"sheet pin angle (side)" );
2553 else if( angle == 90.0 )
2555 else if( angle == 180.0 )
2557 else if( angle == 270.0 )
2560 Expecting(
"0, 90, 180, or 270" );
2577 Expecting(
"at, uuid or effects" );
2581 return sheetPin.release();
2587 wxCHECK_RET( CurTok() == T_sheet_instances,
2588 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
2589 wxCHECK( aScreen, );
2593 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2595 if( token != T_LEFT )
2596 Expecting( T_LEFT );
2614 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2616 if( token != T_LEFT )
2617 Expecting( T_LEFT );
2621 std::vector<wxString> whitespaces = { wxT(
"\r" ), wxT(
"\n" ), wxT(
"\t" ),
2624 size_t numReplacements = 0;
2642 for(
const wxString& ch : whitespaces )
2643 numReplacements += instance.
m_PageNumber.Replace( ch, wxEmptyString );
2648 if( numReplacements > 0 )
2655 Expecting(
"path or page" );
2660 && ( instance.
m_Path.empty() ) )
2676 Expecting(
"path" );
2684 wxCHECK_RET( CurTok() == T_symbol_instances,
2685 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
2686 wxCHECK( aScreen, );
2691 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2693 if( token != T_LEFT )
2694 Expecting( T_LEFT );
2711 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2713 if( token != T_LEFT )
2714 Expecting( T_LEFT );
2735 instance.
m_Value = wxEmptyString;
2737 instance.
m_Value = FromUTF8();
2754 Expecting(
"path, unit, value or footprint" );
2763 Expecting(
"path" );
2772 wxCHECK( aSheet !=
nullptr, );
2776 wxCHECK( screen !=
nullptr, );
2779 m_maxError = schematic->Settings().m_MaxError;
2781 if( aIsCopyableOnly )
2784 bool fileHasUuid =
false;
2798 if( !aIsCopyableOnly )
2803 if( CurTok() != T_kicad_sch )
2804 Expecting(
"kicad_sch" );
2823 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2825 if( aIsCopyableOnly && token == T_EOF )
2828 if( token != T_LEFT )
2829 Expecting( T_LEFT );
2863 case T_generator_version:
2889 if( aIsCopyableOnly )
2890 Unexpected( T_paper );
2900 if( aIsCopyableOnly )
2901 Unexpected( T_page );
2905 NeedSYMBOLorNUMBER();
2906 NeedSYMBOLorNUMBER();
2913 if( aIsCopyableOnly )
2914 Unexpected( T_title_block );
2928 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2930 if( token != T_LEFT )
2931 Expecting( T_LEFT );
2943 Expecting(
"symbol" );
3000 THROW_PARSE_ERROR(
_(
"Schematic polyline has too few points" ), CurSource(), CurLine(),
3001 CurLineNumber(), CurOffset() );
3055 case T_netclass_flag:
3060 case T_global_label:
3061 case T_hierarchical_label:
3062 case T_directive_label:
3078 case T_sheet_instances:
3082 case T_symbol_instances:
3087 if( aIsCopyableOnly )
3088 Unexpected( T_bus_alias );
3093 case T_embedded_fonts:
3099 CurLineNumber(), CurOffset() );
3101 schematic->GetEmbeddedFiles()->SetAreFontsEmbedded(
parseBool() );
3106 case T_embedded_files:
3112 CurLineNumber(), CurOffset() );
3115 embeddedFilesParser.SyncLineReaderWith( *
this );
3119 embeddedFilesParser.
ParseEmbedded( schematic->GetEmbeddedFiles() );
3127 for(
int tok = embeddedFilesParser.NextTok();
3129 tok = embeddedFilesParser.NextTok() )
3133 else if( tok ==
DSN_RIGHT && --depth < 0 )
3138 SyncLineReaderWith( embeddedFilesParser );
3144 Expecting(
"arc, bezier, bitmap, bus, bus_alias, bus_entry, circle, class_label, "
3145 "directive_label, ellipse, ellipse_arc, embedded_fonts, embedded_files, "
3146 "global_label, hierarchical_label, image, junction, lib_symbols, "
3147 "netclass_flag, no_connect, polyline, rectangle, rule_area, sheet, "
3148 "sheet_instances, signal, symbol, symbol_instances, table, text, "
3149 "text_box, title_block, uuid, wire" );
3170 CurLineNumber(), CurOffset() );
3174 std::vector<std::string> fontNames;
3175 Fontconfig()->ListFonts( fontNames, std::string(
Pgm().GetLanguageTag().utf8_str() ),
3176 schematic->GetEmbeddedFiles()->GetFontFiles(),
true );
3185 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
3186 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
3191 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
3193 std::set<int> fieldIDsRead;
3198 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3200 if( token != T_LEFT )
3201 Expecting( T_LEFT );
3213 if( !IsSymbol( token ) )
3216 CurLineNumber(), CurOffset() );
3219 libName = FromUTF8();
3223 libName.Replace(
"{slash}",
"/" );
3233 if( !IsSymbol( token ) && token != T_NUMBER )
3234 Expecting(
"symbol|number" );
3237 wxString
name = FromUTF8();
3241 name.Replace(
"{slash}",
"/" );
3247 if(
static_cast<int>(
name.size() ) > bad_pos )
3249 wxString msg = wxString::Format(
_(
"Symbol %s contains invalid character '%c'" ),
3257 CurLineNumber(), CurOffset() );
3260 symbol->SetLibId( libId );
3266 symbol->SetPosition(
parseXY() );
3268 switch(
static_cast<int>(
parseDouble(
"symbol orientation" ) ) )
3271 case 90: transform =
TRANSFORM( 0, 1, -1, 0 );
break;
3272 case 180: transform =
TRANSFORM( -1, 0, 0, -1 );
break;
3273 case 270: transform =
TRANSFORM( 0, -1, 1, 0 );
break;
3274 default: Expecting(
"0, 90, 180, or 270" );
3277 symbol->SetTransform( transform );
3286 else if( token == T_y )
3289 Expecting(
"x or y" );
3295 symbol->SetUnit(
parseInt(
"symbol unit" ) );
3301 symbol->SetBodyStyle(
parseInt(
"symbol body style" ) );
3305 case T_exclude_from_sim:
3306 symbol->SetExcludedFromSim(
parseBool() );
3311 symbol->SetExcludedFromBOM( !
parseBool() );
3316 symbol->SetExcludedFromBoard( !
parseBool() );
3320 case T_in_pos_files:
3321 symbol->SetExcludedFromPosFiles( !
parseBool() );
3341 if( !IsSymbol( t ) )
3342 Expecting(
"default, block or force" );
3344 wxString mode = FromUTF8();
3346 if( mode.IsSameAs( wxT(
"default"),
false ) )
3348 else if( mode.IsSameAs( wxT(
"block"),
false ) )
3350 else if( mode.IsSameAs( wxT(
"force"),
false ) )
3353 Expecting(
"default, block or force" );
3359 case T_fields_autoplaced:
3371 case T_default_instance:
3375 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3377 if( token != T_LEFT )
3378 Expecting( T_LEFT );
3399 symbol->SetValueFieldText( wxEmptyString );
3401 symbol->SetValueFieldText( FromUTF8() );
3410 symbol->SetFootprintFieldText( wxEmptyString );
3412 symbol->SetFootprintFieldText( FromUTF8() );
3418 Expecting(
"reference, unit, value or footprint" );
3427 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3429 if( token != T_LEFT )
3430 Expecting( T_LEFT );
3434 if( token != T_project )
3435 Expecting(
"project" );
3439 wxString projectName = FromUTF8();
3441 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3443 if( token != T_LEFT )
3444 Expecting( T_LEFT );
3448 if( token != T_path )
3449 Expecting(
"path" );
3458 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3460 if( token != T_LEFT )
3461 Expecting( T_LEFT );
3482 symbol->SetValueFieldText( wxEmptyString );
3484 symbol->SetValueFieldText( FromUTF8() );
3493 symbol->SetFootprintFieldText( wxEmptyString );
3495 symbol->SetFootprintFieldText( FromUTF8() );
3506 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3508 if( token != T_LEFT )
3509 Expecting( T_LEFT );
3517 variant.
m_Name = FromUTF8();
3526 case T_exclude_from_sim:
3548 case T_in_pos_files:
3556 wxString fieldValue;
3558 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3560 if( token != T_LEFT )
3561 Expecting( T_LEFT );
3569 fieldName = FromUTF8();
3575 fieldValue = FromUTF8();
3580 Expecting(
"name or value" );
3584 variant.
m_Fields[fieldName] = fieldValue;
3589 Expecting(
"dnp, exclude_from_sim, field, in_bom, in_pos_files, name, or on_board" );
3599 Expecting(
"reference, unit, value, footprint, or variant" );
3603 symbol->AddHierarchicalReference( instance );
3619 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"0" ) );
3627 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"N" ) );
3635 existing = symbol->GetField( field->
GetId() );
3637 existing = symbol->GetField( field->
GetName() );
3642 symbol->AddField( *field );
3645 symbol->UpdatePrefix();
3658 number = FromUTF8();
3660 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3662 if( token != T_LEFT )
3663 Expecting( T_LEFT );
3687 Expecting(
"alternate or uuid" );
3691 symbol->GetRawPins().emplace_back( std::make_unique<SCH_PIN>( symbol.get(), number,
3697 Expecting(
"lib_id, lib_name, at, mirror, uuid, exclude_from_sim, on_board, in_bom, dnp, passthrough, "
3698 "default_instance, property, pin, or instances" );
3702 if( !libName.IsEmpty() && ( symbol->GetLibId().Format().wx_str() != libName ) )
3703 symbol->SetSchSymbolLibraryName( libName );
3706 symbol->ClearFlags();
3708 return symbol.release();
3714 wxCHECK_MSG( CurTok() == T_image,
nullptr,
3715 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an image." ) );
3718 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>();
3721 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3723 if( token != T_LEFT )
3724 Expecting( T_LEFT );
3731 bitmap->SetPosition(
parseXY() );
3757 data.reserve( 1 << 17 );
3759 while( token != T_RIGHT )
3761 if( !IsSymbol( token ) )
3762 Expecting(
"base64 image data" );
3768 wxMemoryBuffer buffer = wxBase64Decode( data );
3782 Expecting(
"at, scale, uuid, data or locked" );
3795 return bitmap.release();
3801 wxCHECK_MSG( CurTok() == T_sheet,
nullptr,
3802 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a sheet." ) );
3808 std::vector<SCH_FIELD> fields;
3809 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>();
3810 std::set<int> fieldIDsRead;
3815 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3817 if( token != T_LEFT )
3818 Expecting( T_LEFT );
3825 sheet->SetPosition(
parseXY() );
3834 sheet->SetSize( size );
3839 case T_exclude_from_sim:
3840 sheet->SetExcludedFromSim(
parseBool() );
3845 sheet->SetExcludedFromBOM( !
parseBool() );
3850 sheet->SetExcludedFromBoard( !
parseBool() );
3864 case T_fields_autoplaced:
3872 sheet->SetBorderWidth( stroke.
GetWidth() );
3873 sheet->SetBorderColor( stroke.
GetColor() );
3878 sheet->SetBackgroundColor( fill.
m_Color );
3895 if( fields.empty() )
3901 fields.emplace_back( *field );
3912 std::vector<SCH_SHEET_INSTANCE> instances;
3914 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3916 if( token != T_LEFT )
3917 Expecting( T_LEFT );
3921 if( token != T_project )
3922 Expecting(
"project" );
3926 wxString projectName = FromUTF8();
3928 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3930 if( token != T_LEFT )
3931 Expecting( T_LEFT );
3935 if( token != T_path )
3936 Expecting(
"path" );
3945 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3947 if( token != T_LEFT )
3948 Expecting( T_LEFT );
3968 static std::vector<wxString> whitespaces =
3974 for( wxString ch : whitespaces )
3987 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3989 if( token != T_LEFT )
3990 Expecting( T_LEFT );
3998 variant.
m_Name = FromUTF8();
4007 case T_exclude_from_sim:
4029 case T_in_pos_files:
4037 wxString fieldValue;
4039 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4041 if( token != T_LEFT )
4042 Expecting( T_LEFT );
4050 fieldName = FromUTF8();
4056 fieldValue = FromUTF8();
4061 Expecting(
"name or value" );
4065 variant.
m_Fields[fieldName] = fieldValue;
4070 Expecting(
"dnp, exclude_from_sim, field, in_bom, in_pos_files, name, or on_board" );
4080 Expecting(
"page or variant" );
4084 instances.emplace_back( instance );
4088 sheet->setInstances( instances );
4093 Expecting(
"at, size, stroke, background, instances, uuid, property, or pin" );
4097 sheet->SetFields( fields );
4102 CurLineNumber(), CurOffset() );
4108 CurLineNumber(), CurOffset() );
4111 return sheet.release();
4117 wxCHECK_MSG( CurTok() == T_junction,
nullptr,
4118 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a junction." ) );
4121 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
4123 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4125 if( token != T_LEFT )
4126 Expecting( T_LEFT );
4133 junction->SetPosition(
parseXY() );
4149 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
4151 junction->SetColor( color );
4168 Expecting(
"at, diameter, color, uuid or locked" );
4172 return junction.release();
4178 wxCHECK_MSG( CurTok() == T_no_connect,
nullptr,
4179 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a no connect." ) );
4182 std::unique_ptr<SCH_NO_CONNECT> no_connect = std::make_unique<SCH_NO_CONNECT>();
4184 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4186 if( token != T_LEFT )
4187 Expecting( T_LEFT );
4194 no_connect->SetPosition(
parseXY() );
4210 Expecting(
"at, uuid or locked" );
4214 return no_connect.release();
4220 wxCHECK_MSG( CurTok() == T_bus_entry,
nullptr,
4221 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus entry." ) );
4225 std::unique_ptr<SCH_BUS_WIRE_ENTRY> busEntry = std::make_unique<SCH_BUS_WIRE_ENTRY>();
4227 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4229 if( token != T_LEFT )
4230 Expecting( T_LEFT );
4237 busEntry->SetPosition(
parseXY() );
4247 busEntry->SetSize( size );
4254 busEntry->SetStroke( stroke );
4269 Expecting(
"at, size, uuid, stroke or locked" );
4273 return busEntry.release();
4295 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4297 if( token != T_LEFT )
4298 Expecting( T_LEFT );
4305 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4307 if( token != T_LEFT )
4308 Expecting( T_LEFT );
4315 polyline->AddPoint(
parseXY() );
4328 polyline->SetStroke( stroke );
4334 polyline->SetFillColor( fill.
m_Color );
4350 Expecting(
"pts, uuid, stroke, fill or locked" );
4354 return polyline.release();
4373 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a line." );
4376 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>(
VECTOR2I(), layer );
4378 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4380 if( token != T_LEFT )
4381 Expecting( T_LEFT );
4394 line->SetStartPoint(
parseXY() );
4402 line->SetEndPoint(
parseXY() );
4409 line->SetStroke( stroke );
4424 Expecting(
"pts, uuid, stroke or locked" );
4428 return line.release();
4434 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
4435 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
4443 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>(
SHAPE_T::ARC );
4445 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4447 if( token != T_LEFT )
4448 Expecting( T_LEFT );
4471 arc->SetStroke( stroke );
4477 arc->SetFillColor( fill.
m_Color );
4493 Expecting(
"start, mid, end, stroke, fill, uuid or locked" );
4497 arc->SetArcGeometry( startPoint, midPoint, endPoint );
4499 return arc.release();
4505 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
4506 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
4515 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4517 if( token != T_LEFT )
4518 Expecting( T_LEFT );
4536 circle->SetStroke( stroke );
4558 Expecting(
"center, radius, stroke, fill, uuid or locked" );
4571 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
4572 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
4577 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>(
SHAPE_T::RECTANGLE );
4579 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4581 if( token != T_LEFT )
4582 Expecting( T_LEFT );
4589 rectangle->SetPosition(
parseXY() );
4594 rectangle->SetEnd(
parseXY() );
4605 rectangle->SetStroke( stroke );
4611 rectangle->SetFillColor( fill.
m_Color );
4627 Expecting(
"start, end, stroke, fill, uuid or locked" );
4631 return rectangle.release();
4637 wxCHECK_MSG( CurTok() == T_rule_area,
nullptr,
4638 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rule area." ) );
4643 std::unique_ptr<SCH_RULE_AREA> ruleArea = std::make_unique<SCH_RULE_AREA>();
4645 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4647 if( token != T_LEFT )
4648 Expecting( T_LEFT );
4662 ruleArea->SetPolyShape( sch_rule_poly );
4664 ruleArea->SetStroke( poly->GetStroke() );
4665 ruleArea->SetFillMode( poly->GetFillMode() );
4666 ruleArea->SetFillColor( poly->GetFillColor() );
4669 const_cast<KIID&
>( ruleArea->m_Uuid ) = poly->m_Uuid;
4673 case T_exclude_from_sim:
4674 ruleArea->SetExcludedFromSim(
parseBool() );
4679 ruleArea->SetExcludedFromBOM( !
parseBool() );
4684 ruleArea->SetExcludedFromBoard( !
parseBool() );
4699 Expecting(
"exclude_from_sim, on_board, in_bom, dnp, locked, or polyline" );
4703 return ruleArea.release();
4709 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
4710 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
4715 std::unique_ptr<SCH_SHAPE> bezier = std::make_unique<SCH_SHAPE>(
SHAPE_T::BEZIER );
4717 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4719 if( token != T_LEFT )
4720 Expecting( T_LEFT );
4730 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
4732 if( token != T_LEFT )
4733 Expecting( T_LEFT );
4742 case 0: bezier->SetStart(
parseXY() );
break;
4743 case 1: bezier->SetBezierC1(
parseXY() );
break;
4744 case 2: bezier->SetBezierC2(
parseXY() );
break;
4745 case 3: bezier->SetEnd(
parseXY() );
break;
4746 default: Unexpected(
"control point" );
break;
4756 bezier->SetStroke( stroke );
4762 bezier->SetFillColor( fill.
m_Color );
4778 Expecting(
"pts, stroke, fill, uuid or locked" );
4782 bezier->RebuildBezierToSegmentsPointsList(
m_maxError );
4784 return bezier.release();
4789 TSCHEMATIC_T::T aFirstTok )
4795 int majorRadius = 1;
4796 int minorRadius = 1;
4803 for(
T token = aFirstTok; token != T_RIGHT; token = NextTok() )
4805 if( token != T_LEFT )
4806 Expecting( T_LEFT );
4818 case T_major_radius:
4823 case T_minor_radius:
4828 case T_rotation_angle:
4835 Expecting(
"start_angle only valid inside ellipse_arc" );
4842 Expecting(
"end_angle only valid inside ellipse_arc" );
4862 Expecting(
"uuid only valid in schematic context" );
4870 Expecting(
"locked only valid in schematic context" );
4876 Expecting(
"center, major_radius, minor_radius, rotation_angle, "
4877 "start_angle, end_angle, stroke, fill, uuid, or locked" );
4896 wxCHECK_MSG( CurTok() == T_ellipse,
nullptr,
4897 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an ellipse." ) );
4901 return ellipse.release();
4907 wxCHECK_MSG( CurTok() == T_ellipse_arc,
nullptr,
4908 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an elliptical arc." ) );
4912 return arc.release();
4919 std::unique_ptr<SCH_TEXT>
text;
4923 case T_text:
text = std::make_unique<SCH_TEXT>();
break;
4924 case T_label:
text = std::make_unique<SCH_LABEL>();
break;
4925 case T_global_label:
text = std::make_unique<SCH_GLOBALLABEL>();
break;
4926 case T_hierarchical_label:
text = std::make_unique<SCH_HIERLABEL>();
break;
4927 case T_netclass_flag:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
4928 case T_directive_label:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
4930 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as text." );
4938 text->SetText( FromUTF8() );
4940 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4942 if( token != T_LEFT )
4943 Expecting( T_LEFT );
4949 case T_exclude_from_sim:
4960 switch(
static_cast<int>( label->GetTextAngle().AsDegrees() ) )
4976 Unexpected( T_shape );
4994 Expecting(
"input, output, bidirectional, tri_state, passive, dot, round, diamond"
5005 Unexpected( T_length );
5014 case T_fields_autoplaced:
5024 text->SetVisible(
true );
5049 Unexpected( T_property );
5074 Expecting(
"at, shape, iref, uuid, effects or locked" );
5080 if( label && label->
GetFields().empty() )
5083 return text.release();
5089 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
5090 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
5092 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>();
5096 return textBox.release();
5102 wxCHECK_MSG( CurTok() == T_table_cell,
nullptr,
5103 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table cell." ) );
5105 std::unique_ptr<SCH_TABLECELL> cell = std::make_unique<SCH_TABLECELL>();
5109 return cell.release();
5125 bool foundEnd =
false;
5126 bool foundSize =
false;
5127 bool foundMargins =
false;
5131 aTextBox->
SetText( FromUTF8() );
5133 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5135 if( token != T_LEFT )
5136 Expecting( T_LEFT );
5142 case T_exclude_from_sim:
5173 cell->SetColSpan(
parseInt(
"column span" ) );
5174 cell->SetRowSpan(
parseInt(
"row span" ) );
5178 Expecting(
"at, size, stroke, fill, effects or uuid" );
5202 foundMargins =
true;
5223 Expecting(
"at, size, stroke, fill, effects, span, uuid or locked" );
5225 Expecting(
"at, size, stroke, fill, effects, uuid or locked" );
5233 else if( foundSize )
5234 aTextBox->
SetEnd( pos + size );
5236 Expecting(
"size" );
5251 wxCHECK_MSG( CurTok() == T_table,
nullptr,
5252 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table." ) );
5258 std::unique_ptr<SCH_TABLE>
table = std::make_unique<SCH_TABLE>( defaultLineWidth );
5260 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5262 if( token != T_LEFT )
5263 Expecting( T_LEFT );
5269 case T_column_count:
5274 case T_column_widths:
5278 while( ( token = NextTok() ) != T_RIGHT )
5288 while( ( token = NextTok() ) != T_RIGHT )
5295 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5297 if( token != T_LEFT )
5298 Expecting( T_LEFT );
5302 if( token != T_table_cell )
5303 Expecting(
"table_cell" );
5311 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5313 if( token != T_LEFT )
5314 Expecting( T_LEFT );
5332 table->SetBorderStroke( borderStroke );
5336 Expecting(
"external, header or stroke" );
5344 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5346 if( token != T_LEFT )
5347 Expecting( T_LEFT );
5365 table->SetSeparatorsStroke( separatorsStroke );
5369 Expecting(
"rows, cols, or stroke" );
5388 Expecting(
"columns, col_widths, row_heights, border, separators, uuid, locked, header or cells" );
5392 if( !
table->GetCell( 0, 0 ) )
5394 THROW_PARSE_ERROR(
_(
"Invalid table: no cells defined" ), CurSource(), CurLine(), CurLineNumber(),
5398 return table.release();
5404 wxCHECK_RET( CurTok() == T_bus_alias,
5405 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus alias." ) );
5406 wxCHECK( aScreen, );
5409 std::shared_ptr<BUS_ALIAS> busAlias = std::make_shared<BUS_ALIAS>();
5420 busAlias->SetName( alias );
5425 if( token != T_members )
5426 Expecting(
"members" );
5430 while( token != T_RIGHT )
5432 if( !IsSymbol( token ) )
5433 Expecting(
"quoted string" );
5435 member = FromUTF8();
5440 busAlias->AddMember( member );
5456 wxString
name = FromUTF8();
5460 wxString fromRef, fromPin, toRef, toPin;
5461 std::set<wxString> memberNets;
5463 for(
T tok = NextTok(); tok != T_RIGHT; tok = NextTok() )
5470 NeedSYMBOLorNUMBER();
5472 NeedSYMBOLorNUMBER();
5476 else if( tok == T_to )
5478 NeedSYMBOLorNUMBER();
5480 NeedSYMBOLorNUMBER();
5484 else if( tok == T_net_class )
5486 NeedSYMBOLorNUMBER();
5487 netClass = FromUTF8();
5490 else if( tok == T_color )
5496 color =
COLOR4D( r / 255.0, g / 255.0, b / 255.0, al );
5499 else if( tok == T_nets )
5501 for(
T inner = NextTok(); inner != T_RIGHT; inner = NextTok() )
5503 if( !IsSymbol( inner ) && inner != T_NUMBER )
5504 Expecting(
"net name" );
5506 memberNets.insert( FromUTF8() );
5516 T inner = NextTok();
5518 if( inner == T_EOF )
5521 if( inner == T_LEFT )
5523 else if( inner == T_RIGHT )
5529 if( !fromRef.IsEmpty() && !toRef.IsEmpty() )
5534 if( !netClass.IsEmpty() )
5540 if( !memberNets.empty() )
5549 while( ( token = NextTok() ) != T_RIGHT )
5554 KIID uuid( CurStr() );
5562 wxCHECK_RET( CurTok() == T_group,
5563 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GROUP." ) );
5570 while( ( token = NextTok() ) != T_LEFT )
5572 if( token == T_STRING )
5573 groupInfo.
name = FromUTF8();
5575 Expecting(
"group name or locked" );
5578 for( ; token != T_RIGHT; token = NextTok() )
5580 if( token != T_LEFT )
5581 Expecting( T_LEFT );
5597 if( !IsSymbol( token ) && token != T_NUMBER )
5598 Expecting(
"symbol|number" );
5601 wxString
name = FromUTF8();
5605 name.Replace(
"{slash}",
"/" );
5611 if(
static_cast<int>(
name.size() ) > bad_pos )
5613 wxString msg = wxString::Format(
_(
"Group library link %s contains invalid character '%c'" ),
name,
5619 THROW_PARSE_ERROR(
_(
"Invalid library ID" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
5638 Expecting(
"uuid, lib_id, members, locked" );
5650 [&](
const KIID& aId )
5656 if( item->m_Uuid == aId )
5675 group->SetName( groupInfo.name );
5677 const_cast<KIID&
>(
group->m_Uuid ) = groupInfo.uuid;
5679 if( groupInfo.libId.IsValid() )
5680 group->SetDesignBlockLibId( groupInfo.libId );
5682 group->SetLocked( groupInfo.locked );
5693 for(
const KIID& aUuid : groupInfo.memberUuids )
5695 if(
SCH_ITEM* gItem = getItem( aUuid ) )
5696 group->AddItem( gItem );
5711 T token = NextTok();
5713 if( token == T_EOF )
5715 else if( token == T_LEFT )
5717 else if( token == T_RIGHT )
constexpr EDA_IU_SCALE schIUScale
constexpr double ARC_LOW_DEF_MM
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
void SetContentModified(bool aModified=true)
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
KICAD_T Type() const
Returns the type of object.
EDA_ITEM * GetParent() const
virtual void SetParent(EDA_ITEM *aParent)
void SetEllipseRotation(const EDA_ANGLE &aA)
void SetEllipseCenter(const VECTOR2I &aPt)
FILL_T GetFillMode() const
void SetEllipseStartAngle(const EDA_ANGLE &aA)
SHAPE_POLY_SET & GetPolyShape()
void SetEllipseEndAngle(const EDA_ANGLE &aA)
void SetFillColor(const COLOR4D &aColor)
int GetPointCount() const
void SetEnd(const VECTOR2I &aEnd)
void SetEllipseMajorRadius(int aR)
void SetFillMode(FILL_T aFill)
void SetEllipseMinorRadius(int aR)
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.
Simple container to manage fill parameters.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
A color representation with 4 components: red, green, blue, alpha.
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
A logical library item identifier and consists of various portions much like a URI.
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Define a library symbol object.
wxString GetName() const override
void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction, RECURSE_MODE aMode) override
EMBEDDED_FILES * GetEmbeddedFiles() override
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
Describe the page size and margins of a paper page on which to eventually print or plot.
void SetPortrait(bool aIsPortrait)
Rotate the paper page 90 degrees.
bool SetType(PAGE_SIZE_TYPE aPageSize, bool aIsPortrait=false)
Set the name of the page type and also the sizes and margins commonly associated with that type name.
void SetWidthMM(double aWidthInMM)
void SetHeightMM(double aHeightInMM)
const PAGE_SIZE_TYPE & GetType() const
A progress reporter interface for use in multi-threaded environments.
A REFERENCE_IMAGE is a wrapper around a BITMAP_IMAGE that is displayed in an editor as a reference fo...
bool ReadImageFile(const wxString &aFullFilename)
Read and store an image file.
const BITMAP_BASE & GetImage() const
Get the underlying image.
double GetImageScale() const
void SetImageScale(double aScale)
Set the image "zoom" value.
Holds all the data relating to one schematic.
Object to handle a bitmap image that can be inserted in a schematic.
Class for a wire to bus entry.
void SetPinLength(int aLength)
virtual const wxString & GetText() const override
Return the string associated with the text object.
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this label.
A set of SCH_ITEMs (i.e., without duplicates).
SCH_ITEM * ParseSymbolDrawItem()
SCH_SHAPE * parseSymbolPolyLine()
SCH_TABLE * parseSchTable()
bool m_appending
Appending load status.
unsigned m_lastProgressLine
SCH_FIELD * parseSchField(SCH_ITEM *aParent)
SCH_SHAPE * parseSchCircle()
SCH_TEXT * parseSchText()
SCH_TABLECELL * parseSchTableCell()
void parseSchSymbolInstances(SCH_SCREEN *aScreen)
void parsePinNumbers(std::unique_ptr< LIB_SYMBOL > &aSymbol)
LIB_SYMBOL * parseLibSymbol(LIB_SYMBOL_MAP &aSymbolLibMap)
void parseEllipseBody(SCH_SHAPE *aShape, bool aIsArc, bool aIsSchematic, TSCHEMATIC_T::T aFirstTok)
SCH_RULE_AREA * parseSchRuleArea()
SCH_SHAPE * parseSymbolEllipseArc()
SCH_ITEM * parseSymbolText()
PROGRESS_REPORTER * m_progressReporter
void parseFill(FILL_PARAMS &aFill)
SCH_TEXTBOX * parseSymbolTextBox()
void parseBusAlias(SCH_SCREEN *aScreen)
void parseTITLE_BLOCK(TITLE_BLOCK &aTitleBlock)
void parseGroupMembers(GROUP_INFO &aGroupInfo)
void parseStroke(STROKE_PARAMS &aStroke)
Parse stroke definition aStroke.
int m_unit
The current unit being parsed.
std::map< wxString, std::set< wxString > > m_netChainMemberNets
SCH_SHAPE * parseSymbolBezier()
void parseEDA_TEXT(EDA_TEXT *aText, bool aConvertOverbarSyntax, bool aEnforceMinTextSize=true)
SCH_TEXTBOX * parseSchTextBox()
void resolveGroups(SCH_SCREEN *aParent)
std::map< wxString, wxString > m_netChainNetClasses
SCH_SHEET * m_rootSheet
The rootsheet for full project loads or null for importing a schematic.
SCH_SHAPE * parseSchArc()
SCH_SHAPE * parseSchPolyLine()
SCH_BITMAP * parseImage()
SCH_SHAPE * parseSymbolCircle()
wxString m_generatorVersion
void ParseLib(LIB_SYMBOL_MAP &aSymbolLibMap)
SCH_PIN * parseSymbolPin()
std::vector< GROUP_INFO > m_groupInfos
void parseHeader(TSCHEMATIC_T::T aHeaderType, int aFileVersion)
void parseBodyStyles(std::unique_ptr< LIB_SYMBOL > &aSymbol)
SCH_SHAPE * parseSchEllipse()
void parseMargins(int &aLeft, int &aTop, int &aRight, int &aBottom)
wxString m_symbolName
The current symbol name.
std::map< wxString, CHAIN_TERMINALS > m_netChainTerminalRefs
VECTOR2I parseXY(bool aInvertY=false)
SCH_SHAPE * parseSymbolRectangle()
void parsePinNames(std::unique_ptr< LIB_SYMBOL > &aSymbol)
SCH_SHAPE * parseSchBezier()
std::vector< wxString > m_parseWarnings
Non-fatal warnings collected during parsing.
SCH_JUNCTION * parseJunction()
void ParseSchematic(SCH_SHEET *aSheet, bool aIsCopyablyOnly=false, int aFileVersion=SEXPR_SCHEMATIC_FILE_VERSION)
Parse the internal LINE_READER object into aSheet.
SCH_SHEET_PIN * parseSchSheetPin(SCH_SHEET *aSheet)
int m_bodyStyle
The current body style being parsed.
SCH_NO_CONNECT * parseNoConnect()
SCH_SHAPE * parseSymbolArc()
SCH_BUS_WIRE_ENTRY * parseBusEntry()
SCH_SHAPE * parseSymbolEllipse()
std::map< wxString, COLOR4D > m_netChainColors
SCH_SHAPE * parseSchRectangle()
SCH_FIELD * parseProperty(std::unique_ptr< LIB_SYMBOL > &aSymbol)
SCH_SYMBOL * parseSchematicSymbol()
void parseSchTextBoxContent(SCH_TEXTBOX *aTextBox)
bool parseMaybeAbsentBool(bool aDefaultValue)
Parses a boolean flag inside a list that existed before boolean normalization.
void parsePAGE_INFO(PAGE_INFO &aPageInfo)
int m_requiredVersion
Set to the symbol library file version required.
int m_maxError
Max deviation allowed when approximating bezier curves.
const LINE_READER * m_lineReader
LIB_SYMBOL * ParseSymbol(LIB_SYMBOL_MAP &aSymbolLibMap, int aFileVersion=SEXPR_SYMBOL_LIB_FILE_VERSION)
Parse internal LINE_READER object into symbols and return all found.
void skipToBlockEnd(int aDepth=1)
Skip tokens until we reach the end of the current S-expression block.
void parseSchSheetInstances(SCH_SHEET *aRootSheet, SCH_SCREEN *aScreen)
SCH_SHAPE * parseSchEllipseArc()
SCH_IO_KICAD_SEXPR_PARSER(LINE_READER *aLineReader=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr, unsigned aLineCount=0, SCH_SHEET *aRootSheet=nullptr, bool aIsAppending=false)
Base class for any item which can be embedded within the SCHEMATIC container class,...
void SetLocked(bool aLocked) override
bool IsLocked() const override
void SetFieldsAutoplaced(AUTOPLACE_ALGO aAlgo)
void SetShape(LABEL_FLAG_SHAPE aShape)
std::vector< SCH_FIELD > & GetFields()
Segment description base class to describe items which have 2 end points (track, wire,...
void SetStartPoint(const VECTOR2I &aPosition)
virtual void SetStroke(const STROKE_PARAMS &aStroke) override
void SetEndPoint(const VECTOR2I &aPosition)
void SetFileFormatVersionAtLoad(int aVersion)
std::vector< SCH_SHEET_INSTANCE > m_sheetInstances
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
void AddLibSymbol(LIB_SYMBOL *aLibSymbol)
Add aLibSymbol to the library symbol map.
void AddBusAlias(std::shared_ptr< BUS_ALIAS > aAlias)
Add a bus alias definition.
void SetPageSettings(const PAGE_INFO &aPageSettings)
EE_RTREE & Items()
Get the full RTree, usually for iterating.
const KIID & GetUuid() const
void UpdateLocalLibSymbolLinks()
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in this schematic with the local projec...
void SetLegacySymbolInstanceData()
Update the symbol value and footprint instance data for legacy designs.
SCHEMATIC * Schematic() const
void FixupEmbeddedData()
After loading a file from disk, the library symbols do not yet contain the full data for their embedd...
int GetFileFormatVersionAtLoad() const
wxString GroupsSanityCheck(bool repair=false)
Consistency check of internal m_groups structure.
KIID m_uuid
A unique identifier for each schematic file.
std::vector< SCH_SYMBOL_INSTANCE > m_symbolInstances
The list of symbol instances loaded from the schematic file.
void SetPosition(const VECTOR2I &aPos) override
void SetStroke(const STROKE_PARAMS &aStroke) override
STROKE_PARAMS GetStroke() const override
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Variant information for a schematic sheet.
void InitializeAttributes(const SCH_SHEET &aSheet)
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
SCH_SCREEN * GetScreen() const
Variant information for a schematic symbol.
void InitializeAttributes(const SCH_SYMBOL &aSymbol)
void SetMarginBottom(int aBottom)
int GetLegacyTextMargin() const
void SetMarginLeft(int aLeft)
void SetMarginRight(int aRight)
void SetExcludedFromSim(bool aExclude, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
void SetMarginTop(int aTop)
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
void ParseStroke(STROKE_PARAMS &aStroke)
Simple container to manage line stroke parameters.
void SetLineStyle(LINE_STYLE aLineStyle)
LINE_STYLE GetLineStyle() const
KIGFX::COLOR4D GetColor() const
Hold the information shown in the lower right corner of a plot, printout, or editing view.
void SetRevision(const wxString &aRevision)
void SetComment(int aIdx, const wxString &aComment)
void SetTitle(const wxString &aTitle)
void SetCompany(const wxString &aCompany)
void SetDate(const wxString &aDate)
Set the date field, and defaults to the current time and date.
std::map< wxString, wxString > m_Fields
bool m_ExcludedFromPosFiles
#define DEFAULT_LINE_WIDTH_MILS
The default wire width in mils. (can be changed in preference menu)
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_360
static constexpr EDA_ANGLE ANGLE_180
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
@ FILLED_WITH_BG_BODYCOLOR
@ FILLED_SHAPE
Fill with object color.
FONTCONFIG * Fontconfig()
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
#define MAX_PAGE_SIZE_EESCHEMA_MM
#define MIN_PAGE_SIZE_MM
Min and max page sizes for clamping, in mm.
PGM_BASE & Pgm()
The global program "get" accessor.
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
@ PT_INPUT
usual pin input: must be connected
@ PT_NC
not connected (must be left open)
@ PT_TRISTATE
tri state bus pin
@ PT_NIC
not internally connected (may be connected to anything)
@ PT_BIDI
input or output (like port for a microprocessor)
@ PT_OPENEMITTER
pin type open emitter
@ PT_POWER_OUT
output of a regulator: intended to be connected to power input pins
@ PT_OPENCOLLECTOR
pin type open collector
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
@ PT_UNSPECIFIED
unknown electrical properties: creates always a warning when connected
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin.
@ PIN_UP
The pin extends upwards from the connection point: Probably on the bottom side of the symbol.
@ PIN_RIGHT
The pin extends rightwards from the connection point.
@ PIN_LEFT
The pin extends leftwards from the connection point: Probably on the right side of the symbol.
@ PIN_DOWN
The pin extends downwards from the connection: Probably on the top side of the symbol.
const SCH_FIELD * FindField(const std::vector< SCH_FIELD > &aFields, FIELD_T aFieldId)
#define SEXPR_SYMBOL_LIB_FILE_VERSION
This file contains the file format version information for the s-expression schematic and symbol libr...
#define SEXPR_SCHEMATIC_FILE_VERSION
Schematic file version.
Class to handle a set of SCH_ITEMs.
double parseDouble(LINE_READER &aReader, const char *aLine, const char **aOutput)
Parses an ASCII point string with possible leading whitespace into a double precision floating point ...
void fixupSchFillMode(SCH_SHAPE *aShape)
#define SIM_LEGACY_ENABLE_FIELD
#define SIM_LEGACY_ENABLE_FIELD_V7
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
wxString UnescapeString(const wxString &aSource)
wxString From_UTF8(const char *cstring)
A filename or source description, a problem input line, a line number, a byte offset,...
std::vector< KIID > memberUuids
ELECTRICAL_PINTYPE m_Type
A simple container for sheet instance information.
std::map< wxString, SCH_SHEET_VARIANT > m_Variants
A list of sheet variants.
A simple container for schematic symbol instance information.
std::map< wxString, SCH_SYMBOL_VARIANT > m_Variants
A list of symbol variants.
std::map< wxString, LIB_SYMBOL *, LibSymbolMapSort > LIB_SYMBOL_MAP
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ USER
The field ID hasn't been set yet; field is invalid.
@ INTERSHEET_REFS
Global label cross-reference page numbers.
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
#define SHEET_MANDATORY_FIELDS
#define GLOBALLABEL_MANDATORY_FIELDS
wxString GetCanonicalFieldName(FIELD_T aFieldType)
KIBIS top(path, &reporter)
std::vector< std::vector< std::string > > table
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