34#include <wx/mstream.h>
35#include <wx/tokenzr.h>
66using namespace TSCHEMATIC_T;
70 unsigned aLineCount,
SCH_SHEET* aRootSheet,
72 SCHEMATIC_LEXER( aLineReader ),
73 m_requiredVersion( 0 ),
76 m_appending( aIsAppending ),
77 m_progressReporter( aProgressReporter ),
78 m_lineReader( aLineReader ),
79 m_lastProgressLine( 0 ),
80 m_lineCount( aLineCount ),
81 m_rootSheet( aRootSheet )
88 const unsigned PROGRESS_DELTA = 250;
110 KIID id( FromUTF8() );
127 else if( token == T_no )
130 Expecting(
"yes or no" );
144 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
146 if( token != T_LEFT )
151 if( token == T_symbol )
156 aSymbolLibMap[symbol->
GetName()] = symbol;
160 Expecting(
"symbol" );
173 if( CurTok() == T_LEFT )
177 if( CurTok() == T_symbol )
184 wxString msg = wxString::Format(
_(
"Cannot parse %s as a symbol" ),
185 GetTokenString( CurTok() ) );
196 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
197 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
203 wxString unitDisplayName;
205 std::unique_ptr<LIB_SYMBOL> symbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
207 symbol->SetUnitCount( 1 );
219 if( !IsSymbol( token ) )
221 THROW_PARSE_ERROR(
_(
"Invalid symbol name" ), CurSource(), CurLine(), CurLineNumber(),
232 if(
static_cast<int>(
name.size() ) > bad_pos )
234 wxString msg = wxString::Format(
235 _(
"Symbol %s contains invalid character '%c'" ),
name,
243 CurLineNumber(), CurOffset() );
248 symbol->SetLibId(
id );
250 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
252 if( token != T_LEFT )
271 if( token != T_hide )
274 symbol->SetShowPinNumbers(
false );
278 case T_exclude_from_sim:
279 symbol->SetExcludedFromSim(
parseBool() );
284 symbol->SetExcludedFromBOM( !
parseBool() );
289 symbol->SetExcludedFromBoard( !
parseBool() );
301 if( !IsSymbol( token ) )
304 CurLineNumber(), CurOffset() );
308 auto it = aSymbolLibMap.find(
name );
310 if( it == aSymbolLibMap.end() )
312 error.Printf(
_(
"No parent for extended symbol %s" ),
name.c_str() );
313 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
316 symbol->SetParent( it->second );
325 if( !IsSymbol( token ) )
328 CurLineNumber(), CurOffset() );
335 error.Printf(
_(
"Invalid symbol unit name prefix %s" ),
name.c_str() );
336 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
341 wxStringTokenizer tokenizer(
name,
"_" );
343 if( tokenizer.CountTokens() != 2 )
345 error.Printf(
_(
"Invalid symbol unit name suffix %s" ),
name.c_str() );
346 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
349 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
351 error.Printf(
_(
"Invalid symbol unit number %s" ),
name.c_str() );
352 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
355 m_unit =
static_cast<int>( tmp );
357 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
359 error.Printf(
_(
"Invalid symbol convert number %s" ),
name.c_str() );
360 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
366 symbol->SetConversion(
true,
false );
368 if(
m_unit > symbol->GetUnitCount() )
369 symbol->SetUnitCount(
m_unit,
false );
371 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
373 if( token != T_LEFT )
383 if( IsSymbol( token ) )
385 unitDisplayName = FromUTF8();
386 symbol->SetUnitDisplayName(
m_unit, unitDisplayName );
401 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
404 symbol->AddDrawItem( item,
false );
408 Expecting(
"arc, bezier, circle, pin, polyline, rectangle, or text" );
427 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
430 symbol->AddDrawItem( item,
false );
434 Expecting(
"pin_names, pin_numbers, arc, bezier, circle, pin, polyline, "
435 "rectangle, or text" );
439 symbol->GetDrawItems().sort();
442 return symbol.release();
483 Expecting(
"arc, bezier, circle, pin, polyline, rectangle, or text" );
497 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
499 return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
507 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
509 return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
516 strokeParser.SyncLineReaderWith( *
this );
519 SyncLineReaderWith( strokeParser );
525 wxCHECK_RET( CurTok() == T_fill,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a fill." );
528 aFill.
m_Color = COLOR4D::UNSPECIFIED;
532 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
534 if( token != T_LEFT )
547 case T_none: aFill.
m_FillType = FILL_T::NO_FILL;
break;
548 case T_outline: aFill.
m_FillType = FILL_T::FILLED_SHAPE;
break;
549 case T_background: aFill.
m_FillType = FILL_T::FILLED_WITH_BG_BODYCOLOR;
break;
550 case T_color: aFill.
m_FillType = FILL_T::FILLED_WITH_COLOR;
break;
551 default: Expecting(
"none, outline, color or background" );
572 Expecting(
"type or color" );
580 wxCHECK_RET( aText && ( CurTok() == T_effects || CurTok() == T_href ),
581 "Cannot parse " + GetTokenString( CurTok() ) +
" as an EDA_TEXT." );
597 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
599 if( token == T_LEFT )
605 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
607 if( token == T_LEFT )
614 faceName = FromUTF8();
656 Expecting(
"face, size, thickness, line_spacing, bold, or italic" );
660 if( !faceName.IsEmpty() )
669 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
678 case T_mirror:
break;
679 default: Expecting(
"left, right, top, bottom, or mirror" );
688 wxString hyperlink = FromUTF8();
693 CurSource(), CurLine(), CurLineNumber(), CurOffset() );
709 Expecting(
"font, justify, hide or href" );
717 wxCHECK_RET( CurTok() == aHeaderType,
718 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a header." ) );
724 if( tok == T_version )
757 wxCHECK_RET( CurTok() == T_pin_names,
758 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_name token." );
762 if( token == T_LEFT )
766 if( token != T_offset )
767 Expecting(
"offset" );
774 if( token == T_hide )
776 aSymbol->SetShowPinNames(
false );
779 else if( token != T_RIGHT )
782 CurLineNumber(), CurOffset() );
789 wxCHECK_MSG( CurTok() == T_property,
nullptr,
790 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a property." ) );
791 wxCHECK( aSymbol,
nullptr );
795 std::unique_ptr<LIB_FIELD> field = std::make_unique<LIB_FIELD>( aSymbol.get(),
800 if( !IsSymbol( token ) )
802 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
810 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
814 field->SetName(
name );
829 if( !IsSymbol( token ) )
831 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
838 field->SetText( value );
840 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
842 if( token != T_LEFT )
861 field->SetPosition(
parseXY() );
871 field->SetNameShown();
875 case T_do_not_autoplace:
876 field->SetCanAutoplace(
false );
881 Expecting(
"id, at, show_name, do_not_autoplace, or effects" );
890 int nextAvailableId = field->GetId() + 1;
893 nextAvailableId += 1;
895 field->SetId( nextAvailableId );
902 existingField = aSymbol->GetFieldById( field->GetId() );
904 *existingField = *field;
906 return existingField;
908 else if(
name ==
"ki_keywords" )
911 aSymbol->SetKeyWords( value );
915 else if(
name ==
"ki_description" )
917 aSymbol->SetDescription( value );
920 else if(
name ==
"ki_fp_filters" )
923 wxArrayString filters;
924 wxStringTokenizer tokenizer( value );
926 while( tokenizer.HasMoreTokens() )
929 filters.Add( curr_token );
932 aSymbol->SetFPFilters( filters );
935 else if(
name ==
"ki_locked" )
939 aSymbol->LockUnits(
true );
945 existingField = aSymbol->FindField( field->GetCanonicalName() );
956 for(
int ii = 1; ii < 10 && existingField; ii++ )
958 wxString newname = base_name;
959 newname <<
'_' << ii;
961 existingField = aSymbol->FindField( newname );
964 field->SetName( newname );
970 aSymbol->AddDrawItem( field.get(),
false );
972 return field.release();
985 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
986 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
992 bool hasMidPoint =
false;
1000 bool hasAngles =
false;
1002 std::unique_ptr<LIB_SHAPE> arc = std::make_unique<LIB_SHAPE>(
nullptr, SHAPE_T::ARC );
1009 if( token == T_private )
1011 arc->SetPrivate(
true );
1015 for( ; token != T_RIGHT; token = NextTok() )
1017 if( token != T_LEFT )
1018 Expecting( T_LEFT );
1041 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1043 if( token != T_LEFT )
1044 Expecting( T_LEFT );
1072 Expecting(
"at, length, or angles" );
1080 arc->SetStroke( stroke );
1086 arc->SetFillColor( fill.
m_Color );
1090 Expecting(
"start, mid, end, radius, stroke, or fill" );
1096 arc->SetArcGeometry( startPoint, midPoint, endPoint );
1107 EDA_ANGLE arc_start, arc_end, arc_angle;
1108 arc->CalcArcAngles( arc_start, arc_end );
1109 arc_angle = arc_end - arc_start;
1114 arc->SetStart( endPoint );
1115 arc->SetEnd( startPoint );
1118 arc->SetCenter( new_center );
1124 arc->SetCenter( new_center );
1128 else if( hasAngles )
1130 arc->SetCenter( center );
1136 arc->SetStart( endPoint );
1137 arc->SetEnd( startPoint );
1141 EDA_ANGLE arc_start, arc_end, arc_angle;
1142 arc->CalcArcAngles( arc_start, arc_end );
1143 arc_angle = arc_end - arc_start;
1149 arc->SetStart( startPoint );
1150 arc->SetEnd( endPoint );
1154 arc->SetStart( startPoint );
1155 arc->SetEnd( endPoint );
1158 arc->SetCenter( new_center );
1163 wxFAIL_MSG(
"Setting arc without either midpoint or angles not implemented." );
1166 return arc.release();
1172 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
1173 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
1179 std::unique_ptr<LIB_SHAPE> bezier = std::make_unique<LIB_SHAPE>(
nullptr, SHAPE_T::BEZIER );
1181 bezier->SetUnit(
m_unit );
1186 if( token == T_private )
1188 bezier->SetPrivate(
true );
1192 for( ; token != T_RIGHT; token = NextTok() )
1194 if( token != T_LEFT )
1195 Expecting( T_LEFT );
1205 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
1207 if( token != T_LEFT )
1208 Expecting( T_LEFT );
1217 case 0: bezier->SetStart(
parseXY() );
break;
1218 case 1: bezier->SetBezierC1(
parseXY() );
break;
1219 case 2: bezier->SetBezierC2(
parseXY() );
break;
1220 case 3: bezier->SetEnd(
parseXY() );
break;
1221 default: Unexpected(
"control point" );
break;
1231 bezier->SetStroke( stroke );
1237 bezier->SetFillColor( fill.
m_Color );
1241 Expecting(
"pts, stroke, or fill" );
1245 bezier->RebuildBezierToSegmentsPointsList( bezier->GetWidth() );
1247 return bezier.release();
1253 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
1254 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
1262 std::unique_ptr<LIB_SHAPE> circle = std::make_unique<LIB_SHAPE>(
nullptr, SHAPE_T::CIRCLE );
1264 circle->SetUnit(
m_unit );
1269 if( token == T_private )
1271 circle->SetPrivate(
true );
1275 for( ; token != T_RIGHT; token = NextTok() )
1277 if( token != T_LEFT )
1278 Expecting( T_LEFT );
1296 circle->SetStroke( stroke );
1302 circle->SetFillColor( fill.
m_Color );
1306 Expecting(
"center, radius, stroke, or fill" );
1310 circle->SetCenter( center );
1311 circle->SetEnd(
VECTOR2I( center.
x + radius, center.
y ) );
1313 return circle.release();
1323 case T_input:
return ELECTRICAL_PINTYPE::PT_INPUT;
1324 case T_output:
return ELECTRICAL_PINTYPE::PT_OUTPUT;
1325 case T_bidirectional:
return ELECTRICAL_PINTYPE::PT_BIDI;
1326 case T_tri_state:
return ELECTRICAL_PINTYPE::PT_TRISTATE;
1327 case T_passive:
return ELECTRICAL_PINTYPE::PT_PASSIVE;
1328 case T_unspecified:
return ELECTRICAL_PINTYPE::PT_UNSPECIFIED;
1329 case T_power_in:
return ELECTRICAL_PINTYPE::PT_POWER_IN;
1330 case T_power_out:
return ELECTRICAL_PINTYPE::PT_POWER_OUT;
1331 case T_open_collector:
return ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR;
1332 case T_open_emitter:
return ELECTRICAL_PINTYPE::PT_OPENEMITTER;
1334 case T_no_connect:
return ELECTRICAL_PINTYPE::PT_NC;
1335 case T_free:
return ELECTRICAL_PINTYPE::PT_NIC;
1338 Expecting(
"input, output, bidirectional, tri_state, passive, "
1339 "unspecified, power_in, power_out, open_collector, "
1340 "open_emitter, free or no_connect" );
1341 return ELECTRICAL_PINTYPE::PT_UNSPECIFIED;
1349 case T_line:
return GRAPHIC_PINSHAPE::LINE;
1350 case T_inverted:
return GRAPHIC_PINSHAPE::INVERTED;
1351 case T_clock:
return GRAPHIC_PINSHAPE::CLOCK;
1352 case T_inverted_clock:
return GRAPHIC_PINSHAPE::INVERTED_CLOCK;
1353 case T_input_low:
return GRAPHIC_PINSHAPE::INPUT_LOW;
1354 case T_clock_low:
return GRAPHIC_PINSHAPE::CLOCK_LOW;
1355 case T_output_low:
return GRAPHIC_PINSHAPE::OUTPUT_LOW;
1356 case T_edge_clock_high:
return GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK;
1357 case T_non_logic:
return GRAPHIC_PINSHAPE::NONLOGIC;
1360 Expecting(
"line, inverted, clock, inverted_clock, input_low, "
1361 "clock_low, output_low, edge_clock_high, non_logic" );
1362 return GRAPHIC_PINSHAPE::LINE;
1366 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
1367 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a pin token." ) );
1372 std::unique_ptr<LIB_PIN>
pin = std::make_unique<LIB_PIN>(
nullptr );
1379 pin->SetType( parseType( token ) );
1385 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1387 if( token == T_hide )
1389 pin->SetVisible(
false );
1393 if( token != T_LEFT )
1394 Expecting( T_LEFT );
1403 switch(
parseInt(
"pin orientation" ) )
1405 case 0:
pin->SetOrientation( PIN_ORIENTATION::PIN_RIGHT );
break;
1406 case 90:
pin->SetOrientation( PIN_ORIENTATION::PIN_UP );
break;
1407 case 180:
pin->SetOrientation( PIN_ORIENTATION::PIN_LEFT );
break;
1408 case 270:
pin->SetOrientation( PIN_ORIENTATION::PIN_DOWN );
break;
1409 default: Expecting(
"0, 90, 180, or 270" );
1423 if( !IsSymbol( token ) )
1432 pin->SetName( FromUTF8() );
1436 if( token != T_RIGHT )
1440 if( token == T_effects )
1447 pin->SetNameTextSize(
text.GetTextHeight() );
1452 Expecting(
"effects" );
1461 if( !IsSymbol( token ) )
1464 CurLineNumber(), CurOffset() );
1467 pin->SetNumber( FromUTF8() );
1470 if( token != T_RIGHT )
1474 if( token == T_effects )
1481 pin->SetNumberTextSize(
text.GetTextHeight() );
1486 Expecting(
"effects" );
1498 if( !IsSymbol( token ) )
1501 CurLineNumber(), CurOffset() );
1507 alt.
m_Type = parseType( token );
1512 pin->GetAlternates()[ alt.
m_Name ] = alt;
1519 Expecting(
"at, name, number, length, or alternate" );
1523 return pin.release();
1529 wxCHECK_MSG( CurTok() == T_polyline,
nullptr,
1530 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a poly." ) );
1535 std::unique_ptr<LIB_SHAPE> poly = std::make_unique<LIB_SHAPE>(
nullptr, SHAPE_T::POLY );
1542 if( token == T_private )
1544 poly->SetPrivate(
true );
1548 for( ; token != T_RIGHT; token = NextTok() )
1550 if( token != T_LEFT )
1551 Expecting( T_LEFT );
1558 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1560 if( token != T_LEFT )
1561 Expecting( T_LEFT );
1577 poly->SetStroke( stroke );
1583 poly->SetFillColor( fill.
m_Color );
1587 Expecting(
"pts, stroke, or fill" );
1591 return poly.release();
1597 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
1598 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
1603 std::unique_ptr<LIB_SHAPE> rectangle = std::make_unique<LIB_SHAPE>(
nullptr, SHAPE_T::RECTANGLE );
1605 rectangle->SetUnit(
m_unit );
1610 if( token == T_private )
1612 rectangle->SetPrivate(
true );
1616 for( ; token != T_RIGHT; token = NextTok() )
1618 if( token != T_LEFT )
1619 Expecting( T_LEFT );
1626 rectangle->SetPosition(
parseXY() );
1631 rectangle->SetEnd(
parseXY() );
1637 rectangle->SetStroke( stroke );
1643 rectangle->SetFillColor( fill.
m_Color );
1647 Expecting(
"start, end, stroke, or fill" );
1651 return rectangle.release();
1657 wxCHECK_MSG( CurTok() == T_text,
nullptr,
1658 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text token." ) );
1661 std::unique_ptr<LIB_TEXT>
text = std::make_unique<LIB_TEXT>(
nullptr );
1667 if( token == T_private )
1669 text->SetPrivate(
true );
1673 if( !IsSymbol( token ) )
1675 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
1679 text->SetText( FromUTF8() );
1681 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1683 if( token != T_LEFT )
1684 Expecting( T_LEFT );
1702 Expecting(
"at or effects" );
1706 return text.release();
1712 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
1713 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
1719 bool foundEnd =
false;
1720 bool foundSize =
false;
1723 std::unique_ptr<LIB_TEXTBOX> textBox = std::make_unique<LIB_TEXTBOX>(
nullptr );
1727 if( token == T_private )
1729 textBox->SetPrivate(
true );
1733 if( !IsSymbol( token ) )
1735 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
1739 textBox->SetText( FromUTF8() );
1741 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1743 if( token != T_LEFT )
1744 Expecting( T_LEFT );
1775 textBox->SetStroke( stroke );
1781 textBox->SetFillColor( fill.
m_Color );
1789 Expecting(
"at, size, stroke, fill or effects" );
1793 textBox->SetPosition( pos );
1796 textBox->SetEnd( end );
1797 else if( foundSize )
1798 textBox->SetEnd( pos + size );
1800 Expecting(
"size" );
1802 return textBox.release();
1808 wxCHECK_RET( ( CurTok() == T_page &&
m_requiredVersion <= 20200506 ) || CurTok() == T_paper,
1809 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a PAGE_INFO." ) );
1815 wxString pageType = FromUTF8();
1817 if( !aPageInfo.
SetType( pageType ) )
1819 THROW_PARSE_ERROR(
_(
"Invalid page type" ), CurSource(), CurLine(), CurLineNumber(),
1846 if( token == T_portrait )
1851 else if( token != T_RIGHT )
1853 Expecting(
"portrait" );
1860 wxCHECK_RET( CurTok() == T_title_block,
1861 "Cannot parse " + GetTokenString( CurTok() ) +
" as a TITLE_BLOCK." );
1865 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1867 if( token != T_LEFT )
1868 Expecting( T_LEFT );
1876 aTitleBlock.
SetTitle( FromUTF8() );
1881 aTitleBlock.
SetDate( FromUTF8() );
1896 int commentNumber =
parseInt(
"comment" );
1898 switch( commentNumber )
1947 CurLine(), CurLineNumber(), CurOffset() );
1954 Expecting(
"title, date, rev, company, or comment" );
1964 wxCHECK_MSG( CurTok() == T_property,
nullptr,
1965 "Cannot parse " + GetTokenString( CurTok() ) +
" as a property token." );
1967 T token = NextTok();
1969 if( !IsSymbol( token ) )
1971 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
1975 wxString
name = FromUTF8();
1977 if(
name.IsEmpty() )
1979 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
1985 if( !IsSymbol( token ) )
1987 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
1992 wxString value = FromUTF8();
1994 int mandatoryFieldCount = 0;
2001 std::unique_ptr<SCH_FIELD> field =
2002 std::make_unique<SCH_FIELD>(
VECTOR2I( -1, -1 ), mandatoryFieldCount, aParent,
name );
2003 field->SetText( value );
2004 field->SetVisible(
true );
2029 else if( !
name.CmpNoCase( wxT(
"Sheet name" ) ) )
2034 else if( !
name.CmpNoCase( wxT(
"Sheet file" ) ) )
2042 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2044 if( token != T_LEFT )
2045 Expecting( T_LEFT );
2056 if(
id >= mandatoryFieldCount )
2063 field->SetPosition(
parseXY() );
2073 field->SetNameShown();
2077 case T_do_not_autoplace:
2078 field->SetCanAutoplace(
false );
2083 Expecting(
"id, at, show_name, do_not_autoplace or effects" );
2087 return field.release();
2093 wxCHECK_MSG( aSheet !=
nullptr,
nullptr,
"" );
2094 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
2095 "Cannot parse " + GetTokenString( CurTok() ) +
" as a sheet pin token." );
2097 T token = NextTok();
2099 if( !IsSymbol( token ) )
2101 THROW_PARSE_ERROR(
_(
"Invalid sheet pin name" ), CurSource(), CurLine(), CurLineNumber(),
2105 wxString
name = FromUTF8();
2107 if(
name.IsEmpty() )
2109 THROW_PARSE_ERROR(
_(
"Empty sheet pin name" ), CurSource(), CurLine(), CurLineNumber(),
2113 auto sheetPin = std::make_unique<SCH_SHEET_PIN>( aSheet,
VECTOR2I( 0, 0 ),
name );
2119 case T_input: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_INPUT );
break;
2120 case T_output: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
break;
2121 case T_bidirectional: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_BIDI );
break;
2122 case T_tri_state: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_TRISTATE );
break;
2123 case T_passive: sheetPin->SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
break;
2125 Expecting(
"input, output, bidirectional, tri_state, or passive" );
2128 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2130 if( token != T_LEFT )
2131 Expecting( T_LEFT );
2139 sheetPin->SetPosition(
parseXY() );
2141 double angle =
parseDouble(
"sheet pin angle (side)" );
2144 sheetPin->SetSide( SHEET_SIDE::RIGHT );
2145 else if( angle == 90.0 )
2146 sheetPin->SetSide( SHEET_SIDE::TOP );
2147 else if( angle == 180.0 )
2148 sheetPin->SetSide( SHEET_SIDE::LEFT );
2149 else if( angle == 270.0 )
2150 sheetPin->SetSide( SHEET_SIDE::BOTTOM );
2152 Expecting(
"0, 90, 180, or 270" );
2169 Expecting(
"at, uuid or effects" );
2173 return sheetPin.release();
2179 wxCHECK_RET( CurTok() == T_sheet_instances,
2180 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
2181 wxCHECK( aScreen, );
2185 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2187 if( token != T_LEFT )
2188 Expecting( T_LEFT );
2206 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2208 if( token != T_LEFT )
2209 Expecting( T_LEFT );
2213 std::vector<wxString> whitespaces = { wxT(
"\r" ), wxT(
"\n" ), wxT(
"\t" ),
2216 size_t numReplacements = 0;
2234 for( wxString ch : whitespaces )
2235 numReplacements += instance.
m_PageNumber.Replace( ch, wxEmptyString );
2240 if( numReplacements > 0 )
2247 Expecting(
"path or page" );
2252 && ( instance.
m_Path.empty() ) )
2268 Expecting(
"path" );
2276 wxCHECK_RET( CurTok() == T_symbol_instances,
2277 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
2278 wxCHECK( aScreen, );
2283 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2285 if( token != T_LEFT )
2286 Expecting( T_LEFT );
2303 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2305 if( token != T_LEFT )
2306 Expecting( T_LEFT );
2325 instance.
m_Value = FromUTF8();
2336 Expecting(
"path, unit, value or footprint" );
2345 Expecting(
"path" );
2353 wxCHECK( aSheet !=
nullptr, );
2357 wxCHECK( screen !=
nullptr, );
2359 if( aIsCopyableOnly )
2362 bool fileHasUuid =
false;
2366 if( !aIsCopyableOnly )
2371 if( CurTok() != T_kicad_sch )
2372 Expecting(
"kicad_sch" );
2384 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2386 if( aIsCopyableOnly && token == T_EOF )
2389 if( token != T_LEFT )
2390 Expecting( T_LEFT );
2420 if( aIsCopyableOnly )
2421 Unexpected( T_paper );
2431 if( aIsCopyableOnly )
2432 Unexpected( T_page );
2436 NeedSYMBOLorNUMBER();
2437 NeedSYMBOLorNUMBER();
2444 if( aIsCopyableOnly )
2445 Unexpected( T_title_block );
2459 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2461 if( token != T_LEFT )
2462 Expecting( T_LEFT );
2475 Expecting(
"symbol" );
2572 case T_netclass_flag:
2577 case T_global_label:
2578 case T_hierarchical_label:
2579 case T_directive_label:
2587 case T_sheet_instances:
2591 case T_symbol_instances:
2596 if( aIsCopyableOnly )
2597 Unexpected( T_bus_alias );
2603 Expecting(
"symbol, paper, page, title_block, bitmap, sheet, junction, no_connect, "
2604 "bus_entry, line, bus, text, label, class_label, global_label, "
2605 "hierarchical_label, symbol_instances, or bus_alias" );
2626 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
2627 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
2632 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
2634 std::set<int> fieldIDsRead;
2637 symbol->ClearFieldsAutoplaced();
2647 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2649 if( token != T_LEFT )
2650 Expecting( T_LEFT );
2662 if( !IsSymbol( token ) )
2665 CurLineNumber(), CurOffset() );
2668 libName = FromUTF8();
2677 if( !IsSymbol( token ) && token != T_NUMBER )
2678 Expecting(
"symbol|number" );
2681 wxString
name = FromUTF8();
2686 if(
static_cast<int>(
name.size() ) > bad_pos )
2688 wxString msg = wxString::Format(
2689 _(
"Symbol %s contains invalid character '%c'" ),
name,
2696 CurLineNumber(), CurOffset() );
2699 symbol->SetLibId( libId );
2705 symbol->SetPosition(
parseXY() );
2707 switch(
static_cast<int>(
parseDouble(
"symbol orientation" ) ) )
2710 case 90: transform =
TRANSFORM( 0, -1, -1, 0 );
break;
2711 case 180: transform =
TRANSFORM( -1, 0, 0, 1 );
break;
2712 case 270: transform =
TRANSFORM( 0, 1, 1, 0 );
break;
2713 default: Expecting(
"0, 90, 180, or 270" );
2716 symbol->SetTransform( transform );
2725 else if( token == T_y )
2728 Expecting(
"x or y" );
2734 symbol->SetUnit(
parseInt(
"symbol unit" ) );
2739 symbol->SetConvert(
parseInt(
"symbol convert" ) );
2743 case T_exclude_from_sim:
2744 symbol->SetExcludedFromSim(
parseBool() );
2749 symbol->SetExcludedFromBOM( !
parseBool() );
2754 symbol->SetExcludedFromBoard( !
parseBool() );
2763 case T_fields_autoplaced:
2764 symbol->SetFieldsAutoplaced();
2774 case T_default_instance:
2778 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2780 if( token != T_LEFT )
2781 Expecting( T_LEFT );
2800 symbol->SetValueFieldText( FromUTF8() );
2806 symbol->SetFootprintFieldText( FromUTF8() );
2811 Expecting(
"reference, unit, value or footprint" );
2820 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2822 if( token != T_LEFT )
2823 Expecting( T_LEFT );
2827 if( token != T_project )
2828 Expecting(
"project" );
2832 wxString projectName = FromUTF8();
2834 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2836 if( token != T_LEFT )
2837 Expecting( T_LEFT );
2841 if( token != T_path )
2842 Expecting(
"path" );
2851 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2853 if( token != T_LEFT )
2854 Expecting( T_LEFT );
2873 symbol->SetValueFieldText( FromUTF8() );
2879 symbol->SetFootprintFieldText( FromUTF8() );
2884 Expecting(
"reference, unit, value or footprint" );
2887 symbol->AddHierarchicalReference( instance );
2904 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"0" ) );
2911 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"N" ) );
2917 int nextAvailableId = field->
GetId() + 1;
2920 nextAvailableId += 1;
2922 field->
SetId( nextAvailableId );
2925 if( symbol->GetFieldById( field->
GetId() ) )
2926 *symbol->GetFieldById( field->
GetId() ) = *field;
2928 symbol->AddField( *field );
2931 symbol->UpdatePrefix();
2946 number = FromUTF8();
2948 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2950 if( token != T_LEFT )
2951 Expecting( T_LEFT );
2975 Expecting(
"alternate or uuid" );
2979 symbol->GetRawPins().emplace_back( std::make_unique<SCH_PIN>( symbol.get(),
2982 const_cast<KIID&
>( symbol->GetRawPins().back()->m_Uuid ) = uuid;
2987 Expecting(
"lib_id, lib_name, at, mirror, uuid, on_board, in_bom, dnp, "
2988 "default_instance, property, pin, or instances" );
2992 if( !libName.IsEmpty() && ( symbol->GetLibId().Format().wx_str() != libName ) )
2993 symbol->SetSchSymbolLibraryName( libName );
2996 symbol->ClearFlags();
2998 return symbol.release();
3004 wxCHECK_MSG( CurTok() == T_image,
nullptr,
3005 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an image." ) );
3008 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>();
3010 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3012 if( token != T_LEFT )
3013 Expecting( T_LEFT );
3020 bitmap->SetPosition(
parseXY() );
3025 bitmap->GetImage()->SetScale(
parseDouble(
"image scale factor" ) );
3027 if( !std::isnormal( bitmap->GetImage()->GetScale() ) )
3028 bitmap->GetImage()->SetScale( 1.0 );
3047 data.reserve( 1 << 17 );
3049 while( token != T_RIGHT )
3051 if( !IsSymbol( token ) )
3052 Expecting(
"base64 image data" );
3058 wxMemoryBuffer buffer = wxBase64Decode( data );
3060 if( !bitmap->GetImage()->ReadImageFile( buffer ) )
3067 Expecting(
"at, scale, uuid or data" );
3079 return bitmap.release();
3085 wxCHECK_MSG( CurTok() == T_sheet,
nullptr,
3086 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a sheet." ) );
3092 std::vector<SCH_FIELD> fields;
3093 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>();
3094 std::set<int> fieldIDsRead;
3097 sheet->ClearFieldsAutoplaced();
3099 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3101 if( token != T_LEFT )
3102 Expecting( T_LEFT );
3109 sheet->SetPosition(
parseXY() );
3118 sheet->SetSize( size );
3123 case T_fields_autoplaced:
3124 sheet->SetFieldsAutoplaced();
3130 sheet->SetBorderWidth( stroke.
GetWidth() );
3131 sheet->SetBorderColor( stroke.
GetColor() );
3136 sheet->SetBackgroundColor( fill.
m_Color );
3153 if( fields.empty() )
3167 if( field->
GetId() < 0 )
3170 while( !fieldIDsRead.insert( field->
GetId() ).second )
3173 fields.emplace_back( *field );
3183 std::vector<SCH_SHEET_INSTANCE> instances;
3185 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3187 if( token != T_LEFT )
3188 Expecting( T_LEFT );
3192 if( token != T_project )
3193 Expecting(
"project" );
3197 wxString projectName = FromUTF8();
3199 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3201 if( token != T_LEFT )
3202 Expecting( T_LEFT );
3206 if( token != T_path )
3207 Expecting(
"path" );
3216 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3218 if( token != T_LEFT )
3219 Expecting( T_LEFT );
3239 std::vector<wxString> whitespaces = { wxT(
"\r" ), wxT(
"\n" ),
3240 wxT(
"\t" ), wxT(
" " ) };
3242 for( wxString ch : whitespaces )
3251 Expecting(
"page" );
3255 instances.emplace_back( instance );
3259 sheet->setInstances( instances );
3264 Expecting(
"at, size, stroke, background, instances, uuid, property, or pin" );
3268 sheet->SetFields( fields );
3270 return sheet.release();
3276 wxCHECK_MSG( CurTok() == T_junction,
nullptr,
3277 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a junction." ) );
3280 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
3282 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3284 if( token != T_LEFT )
3285 Expecting( T_LEFT );
3292 junction->SetPosition(
parseXY() );
3310 junction->SetColor(
color );
3322 Expecting(
"at, diameter, color or uuid" );
3326 return junction.release();
3332 wxCHECK_MSG( CurTok() == T_no_connect,
nullptr,
3333 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a no connect." ) );
3336 std::unique_ptr<SCH_NO_CONNECT> no_connect = std::make_unique<SCH_NO_CONNECT>();
3338 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3340 if( token != T_LEFT )
3341 Expecting( T_LEFT );
3348 no_connect->SetPosition(
parseXY() );
3359 Expecting(
"at or uuid" );
3363 return no_connect.release();
3369 wxCHECK_MSG( CurTok() == T_bus_entry,
nullptr,
3370 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus entry." ) );
3374 std::unique_ptr<SCH_BUS_WIRE_ENTRY> busEntry = std::make_unique<SCH_BUS_WIRE_ENTRY>();
3376 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3378 if( token != T_LEFT )
3379 Expecting( T_LEFT );
3386 busEntry->SetPosition(
parseXY() );
3396 busEntry->SetSize( size );
3403 busEntry->SetStroke( stroke );
3413 Expecting(
"at, size, uuid or stroke" );
3417 return busEntry.release();
3428 std::unique_ptr<SCH_SHAPE> polyline = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY, layer );
3430 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3432 if( token != T_LEFT )
3433 Expecting( T_LEFT );
3440 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3442 if( token != T_LEFT )
3443 Expecting( T_LEFT );
3450 polyline->AddPoint(
parseXY() );
3458 polyline->SetStroke( stroke );
3464 polyline->SetFillColor( fill.
m_Color );
3474 Expecting(
"pts, uuid, stroke, or fill" );
3478 return polyline.release();
3497 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a line." );
3500 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>(
VECTOR2I(), layer );
3502 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3504 if( token != T_LEFT )
3505 Expecting( T_LEFT );
3518 line->SetStartPoint(
parseXY() );
3526 line->SetEndPoint(
parseXY() );
3533 line->SetStroke( stroke );
3543 Expecting(
"at, uuid or stroke" );
3547 return line.release();
3553 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
3554 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
3562 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>( SHAPE_T::ARC );
3564 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3566 if( token != T_LEFT )
3567 Expecting( T_LEFT );
3590 arc->SetStroke( stroke );
3596 arc->SetFillColor( fill.
m_Color );
3601 const_cast<KIID&
>( arc->m_Uuid ) =
KIID( FromUTF8() );
3606 Expecting(
"start, mid, end, stroke, fill or uuid" );
3610 arc->SetArcGeometry( startPoint, midPoint, endPoint );
3612 return arc.release();
3618 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
3619 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
3626 std::unique_ptr<SCH_SHAPE> circle = std::make_unique<SCH_SHAPE>( SHAPE_T::CIRCLE );
3628 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3630 if( token != T_LEFT )
3631 Expecting( T_LEFT );
3649 circle->SetStroke( stroke );
3655 circle->SetFillColor( fill.
m_Color );
3660 const_cast<KIID&
>( circle->m_Uuid ) =
KIID( FromUTF8() );
3665 Expecting(
"center, radius, stroke, fill or uuid" );
3669 circle->SetCenter( center );
3670 circle->SetEnd(
VECTOR2I( center.
x + radius, center.
y ) );
3672 return circle.release();
3678 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
3679 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
3684 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>( SHAPE_T::RECTANGLE );
3686 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3688 if( token != T_LEFT )
3689 Expecting( T_LEFT );
3696 rectangle->SetPosition(
parseXY() );
3701 rectangle->SetEnd(
parseXY() );
3707 rectangle->SetStroke( stroke );
3713 rectangle->SetFillColor( fill.
m_Color );
3718 const_cast<KIID&
>( rectangle->m_Uuid ) =
KIID( FromUTF8() );
3723 Expecting(
"start, end, stroke, fill or uuid" );
3727 return rectangle.release();
3733 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
3734 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
3739 std::unique_ptr<SCH_SHAPE> bezier = std::make_unique<SCH_SHAPE>( SHAPE_T::BEZIER );
3741 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3743 if( token != T_LEFT )
3744 Expecting( T_LEFT );
3751 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3753 if( token != T_LEFT )
3754 Expecting( T_LEFT );
3761 bezier->AddPoint(
parseXY() );
3770 bezier->SetStroke( stroke );
3776 bezier->SetFillColor( fill.
m_Color );
3781 const_cast<KIID&
>( bezier->m_Uuid ) =
KIID( FromUTF8() );
3786 Expecting(
"pts, stroke, fill or uuid" );
3790 return bezier.release();
3797 std::unique_ptr<SCH_TEXT>
text;
3801 case T_text:
text = std::make_unique<SCH_TEXT>();
break;
3802 case T_label:
text = std::make_unique<SCH_LABEL>();
break;
3803 case T_global_label:
text = std::make_unique<SCH_GLOBALLABEL>();
break;
3804 case T_hierarchical_label:
text = std::make_unique<SCH_HIERLABEL>();
break;
3805 case T_netclass_flag:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
3806 case T_directive_label:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
3808 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as text." );
3812 text->ClearFieldsAutoplaced();
3816 text->SetText( FromUTF8() );
3818 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3820 if( token != T_LEFT )
3821 Expecting( T_LEFT );
3827 case T_exclude_from_sim:
3838 switch(
static_cast<int>( label->GetTextAngle().AsDegrees() ) )
3854 Unexpected( T_shape );
3862 case T_input: label->
SetShape( LABEL_FLAG_SHAPE::L_INPUT );
break;
3863 case T_output: label->
SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
break;
3864 case T_bidirectional: label->
SetShape( LABEL_FLAG_SHAPE::L_BIDI );
break;
3865 case T_tri_state: label->
SetShape( LABEL_FLAG_SHAPE::L_TRISTATE );
break;
3866 case T_passive: label->
SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
break;
3867 case T_dot: label->
SetShape( LABEL_FLAG_SHAPE::F_DOT );
break;
3868 case T_round: label->
SetShape( LABEL_FLAG_SHAPE::F_ROUND );
break;
3869 case T_diamond: label->
SetShape( LABEL_FLAG_SHAPE::F_DIAMOND );
break;
3870 case T_rectangle: label->
SetShape( LABEL_FLAG_SHAPE::F_RECTANGLE );
break;
3872 Expecting(
"input, output, bidirectional, tri_state, passive, dot, round, diamond"
3883 Unexpected( T_length );
3892 case T_fields_autoplaced:
3893 text->SetFieldsAutoplaced();
3923 Unexpected( T_property );
3950 Expecting(
"at, shape, iref, uuid or effects" );
3956 if( label && label->
GetFields().empty() )
3959 return text.release();
3965 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
3966 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
3972 bool foundEnd =
false;
3973 bool foundSize =
false;
3976 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>();
3980 textBox->SetText( FromUTF8() );
3982 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3984 if( token != T_LEFT )
3985 Expecting( T_LEFT );
3991 case T_exclude_from_sim:
3992 textBox->SetExcludedFromSim(
parseBool() );
4021 textBox->SetStroke( stroke );
4027 textBox->SetFillColor( fill.
m_Color );
4036 const_cast<KIID&
>( textBox->m_Uuid ) =
KIID( FromUTF8() );
4041 Expecting(
"at, size, stroke, fill, effects or uuid" );
4045 textBox->SetPosition( pos );
4048 textBox->SetEnd( end );
4049 else if( foundSize )
4050 textBox->SetEnd( pos + size );
4052 Expecting(
"size" );
4054 return textBox.release();
4060 wxCHECK_RET( CurTok() == T_bus_alias,
4061 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus alias." ) );
4062 wxCHECK( aScreen, );
4065 std::shared_ptr<BUS_ALIAS> busAlias = std::make_shared<BUS_ALIAS>( aScreen );
4076 busAlias->SetName( alias );
4081 if( token != T_members )
4082 Expecting(
"members" );
4086 while( token != T_RIGHT )
4088 if( !IsSymbol( token ) )
4089 Expecting(
"quoted string" );
4091 member = FromUTF8();
4096 busAlias->Members().emplace_back( member );
constexpr EDA_IU_SCALE schIUScale
void SetContentModified(bool aModified=true)
This class handle bitmap images in KiCad.
KICAD_T Type() const
Returns the type of object.
virtual void SetParent(EDA_ITEM *aParent)
SHAPE_POLY_SET & GetPolyShape()
int GetPointCount() const
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
void SetTextColor(const COLOR4D &aColor)
void SetTextSize(VECTOR2I aNewSize)
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)
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 SetHyperlink(wxString aLink)
virtual void SetText(const wxString &aText)
void SetItalic(bool aItalic)
void SetFont(KIFONT::FONT *aFont)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Simple container to manage fill parameters.
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false)
A color representation with 4 components: red, green, blue, alpha.
Field object used in symbol libraries.
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
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.
The base class for drawable items used by schematic library symbols.
Define a library symbol object.
wxString GetName() const override
int UpdateFieldOrdinals()
Order optional field indices.
Define a symbol library graphical text item.
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 SetWidthMils(int aWidthInMils)
void SetPortrait(bool aIsPortrait)
Rotate the paper page 90 degrees.
static const wxChar Custom[]
"User" defined page type
void SetHeightMils(int aHeightInMils)
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).
Object to handle a bitmap image that can be inserted in a schematic.
Class for a wire to bus entry.
void SetPinLength(int aLength)
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
const wxString & GetInternalName()
Get the initial name of the field set at creation (or set by SetName()).
Base class for any item which can be embedded within the SCHEMATIC container class,...
void SetFieldsAutoplaced()
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)
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.
int GetFileFormatVersionAtLoad() const
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.
std::set< int > m_fieldIDsRead
Field IDs that have been read so far for the current symbol.
void parseBusAlias(SCH_SCREEN *aScreen)
int m_convert
The current body style being parsed.
SCH_SHEET_PIN * parseSchSheetPin(SCH_SHEET *aSheet)
void parseSchSheetInstances(SCH_SHEET *aRootSheet, SCH_SCREEN *aScreen)
SCH_BUS_WIRE_ENTRY * parseBusEntry()
void ParseLib(LIB_SYMBOL_MAP &aSymbolLibMap)
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.
LIB_ITEM * ParseDrawItem()
void parseHeader(TSCHEMATIC_T::T aHeaderType, int aFileVersion)
SCH_NO_CONNECT * parseNoConnect()
LIB_SHAPE * parseBezier()
SCH_SHAPE * parseSchCircle()
int m_unit
The current unit being parsed.
LIB_SHAPE * parseCircle()
SCH_SHAPE * parseSchRectangle()
LIB_SYMBOL * parseLibSymbol(LIB_SYMBOL_MAP &aSymbolLibMap)
SCH_SYMBOL * parseSchematicSymbol()
const LINE_READER * m_lineReader
SCH_BITMAP * parseImage()
SCH_SHAPE * parseSchBezier()
SCH_SHAPE * parseSchArc()
LIB_FIELD * parseProperty(std::unique_ptr< LIB_SYMBOL > &aSymbol)
void parseStroke(STROKE_PARAMS &aStroke)
Parse stroke definition aStroke.
LIB_SHAPE * parseRectangle()
SCH_SEXPR_PARSER(LINE_READER *aLineReader=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr, unsigned aLineCount=0, SCH_SHEET *aRootSheet=nullptr, bool aIsAppending=false)
void parseTITLE_BLOCK(TITLE_BLOCK &aTitleBlock)
LIB_SHAPE * parsePolyLine()
int m_requiredVersion
Set to the symbol library file version required.
SCH_TEXTBOX * parseSchTextBox()
SCH_TEXT * parseSchText()
LIB_TEXTBOX * parseTextBox()
wxString m_symbolName
The current symbol name.
SCH_FIELD * parseSchField(SCH_ITEM *aParent)
void parseEDA_TEXT(EDA_TEXT *aText, bool aConvertOverbarSyntax)
PROGRESS_REPORTER * m_progressReporter
void parseFill(FILL_PARAMS &aFill)
void parseSchSymbolInstances(SCH_SCREEN *aScreen)
void parsePinNames(std::unique_ptr< LIB_SYMBOL > &aSymbol)
unsigned m_lastProgressLine
void parsePAGE_INFO(PAGE_INFO &aPageInfo)
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.
SCH_SHEET * m_rootSheet
The rootsheet for full project loads or null for importing a schematic.
SCH_SHAPE * parseSchPolyLine()
bool m_appending
Appending load status.
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.
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslated=true)
SCH_SCREEN * GetScreen() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
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.
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_180
static constexpr EDA_ANGLE & ANGLE_360
static constexpr EDA_ANGLE & ANGLE_90
static constexpr EDA_ANGLE & ANGLE_0
#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 ...
KICOMMON_API int Mm2mils(double aVal)
Convert mm to mils.
#define MIN_PAGE_SIZE_MILS
Min and max page sizes for clamping, in mils.
#define MAX_PAGE_SIZE_EESCHEMA_MILS
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
std::shared_ptr< SHAPE > parseShape(SHAPE_TYPE expectedType, wxStringTokenizer &aTokens)
#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.
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 ...
Schematic and symbol library s-expression file format parser definitions.
@ SHEET_MANDATORY_FIELDS
The first 2 are mandatory, and must be instantiated in SCH_SHEET.
#define SIM_LEGACY_ENABLE_FIELD
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
ELECTRICAL_PINTYPE m_Type
A simple container for sheet instance information.
A simple container for schematic symbol instance information.
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslateForHI=false)
Return a default symbol field name for field aFieldNdx for all components.
std::map< wxString, LIB_SYMBOL *, LibSymbolMapSort > LIB_SYMBOL_MAP
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ MANDATORY_FIELDS
The first 5 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
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.
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
constexpr T Clamp(const T &lower, const T &value, const T &upper)
Limit value within the range lower <= value <= upper.