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" );
409 case T_exclude_from_sim:
410 symbol->SetExcludedFromSim(
parseBool() );
415 symbol->SetExcludedFromBOM( !
parseBool() );
420 symbol->SetExcludedFromBoard( !
parseBool() );
425 symbol->SetExcludedFromPosFiles( !
parseBool() );
429 case T_duplicate_pin_numbers_are_jumpers:
430 symbol->SetDuplicatePinNumbersAreJumpers(
parseBool() );
434 case T_jumper_pin_groups:
436 std::vector<std::set<wxString>>& groups = symbol->JumperPinGroups();
437 std::set<wxString>* currentGroup =
nullptr;
439 for( token = NextTok(); currentGroup || token != T_RIGHT; token = NextTok() )
441 switch(
static_cast<int>( token ) )
444 currentGroup = &groups.emplace_back();
448 currentGroup->insert( FromUTF8() );
452 currentGroup =
nullptr;
456 Expecting(
"list of pin names" );
471 if( !IsSymbol( token ) )
474 CurLineNumber(), CurOffset() );
482 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
484 symbol->SetParentName(
name );
493 if( !IsSymbol( token ) )
496 CurLineNumber(), CurOffset() );
504 name.Replace( wxS(
"{slash}" ), wxT(
"/" ) );
508 error.Printf(
_(
"Invalid symbol unit name prefix %s" ),
name.c_str() );
509 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
514 wxStringTokenizer tokenizer(
name,
"_" );
516 if( tokenizer.CountTokens() != 2 )
518 error.Printf(
_(
"Invalid symbol unit name suffix %s" ),
name.c_str() );
519 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
522 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
524 error.Printf(
_(
"Invalid symbol unit number %s" ),
name.c_str() );
525 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
528 m_unit =
static_cast<int>( tmp );
530 if( !tokenizer.GetNextToken().ToLong( &tmp ) )
532 error.Printf(
_(
"Invalid symbol body style number %s" ),
name.c_str() );
533 THROW_PARSE_ERROR( error, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
539 symbol->SetBodyStyleCount(
m_bodyStyle,
false,
false );
541 if(
m_unit > symbol->GetUnitCount() )
542 symbol->SetUnitCount(
m_unit,
false );
544 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
546 if( token != T_LEFT )
556 if( IsSymbol( token ) )
557 symbol->GetUnitDisplayNames()[
m_unit] = FromUTF8();
574 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
577 symbol->AddDrawItem( item,
false );
581 Expecting(
"arc, bezier, circle, ellipse, ellipse_arc, pin, polyline, "
582 "rectangle, or text" );
603 wxCHECK_MSG( item,
nullptr,
"Invalid draw item pointer." );
606 symbol->AddDrawItem( item,
false );
609 case T_embedded_fonts:
611 symbol->SetAreFontsEmbedded(
parseBool() );
616 case T_embedded_files:
619 embeddedFilesParser.SyncLineReaderWith( *
this );
623 embeddedFilesParser.
ParseEmbedded( symbol->GetEmbeddedFiles() );
631 for(
int tok = embeddedFilesParser.NextTok();
633 tok = embeddedFilesParser.NextTok() )
637 else if( tok ==
DSN_RIGHT && --depth < 0 )
642 SyncLineReaderWith( embeddedFilesParser );
647 Expecting(
"pin_names, pin_numbers, arc, bezier, circle, ellipse, ellipse_arc, "
648 "pin, polyline, rectangle, or text" );
652 symbol->GetDrawItems().sort();
655 const std::vector<wxString>* embeddedFonts = symbol->GetEmbeddedFiles()->UpdateFontFiles();
657 symbol->RunOnChildren(
661 textItem->ResolveFont( embeddedFonts );
668 symbol->SetHasDeMorganBodyStyles( symbol->HasLegacyAlternateBodyStyle() );
670 symbol->RefreshLibraryTreeCaches();
672 return symbol.release();
691 Expecting(
"arc, bezier, circle, ellipse, ellipse_arc, pin, "
692 "polyline, rectangle, or text" );
706 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
708 return KiROUND( std::clamp( retval, -int_limit, int_limit ) );
716 constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
718 return KiROUND( std::clamp( retval, -int_limit, int_limit ) );
725 strokeParser.SyncLineReaderWith( *
this );
728 SyncLineReaderWith( strokeParser );
734 wxCHECK_RET( CurTok() == T_fill,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a fill." );
741 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
743 if( token != T_LEFT )
763 default: Expecting(
"none, outline, hatch, reverse_hatch, "
764 "cross_hatch, color or background" );
778 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
785 Expecting(
"type or color" );
792 bool aEnforceMinTextSize )
794 wxCHECK_RET( aText && ( CurTok() == T_effects || CurTok() == T_href ),
795 "Cannot parse " + GetTokenString( CurTok() ) +
" as an EDA_TEXT." );
812 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
814 if( token == T_LEFT )
820 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
822 if( token == T_LEFT )
862 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
873 Expecting(
"face, size, thickness, line_spacing, bold, or italic" );
880 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
889 case T_mirror:
break;
890 default: Expecting(
"left, right, top, bottom, or mirror" );
899 wxString hyperlink = FromUTF8();
904 CurSource(), CurLine(), CurLineNumber(), CurOffset() );
923 Expecting(
"font, justify, hide or href" );
931 if( CurTok() != aHeaderType )
934 GetTokenString( CurTok() ) ),
935 CurSource(), CurLine(), CurLineNumber(), CurOffset() );
942 if( tok == T_version )
956 wxCHECK_RET( CurTok() == T_body_styles,
957 "Cannot parse " + GetTokenString( CurTok() ) +
" as a body_styles token." );
959 std::vector<wxString> names;
961 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
963 if( token == T_demorgan )
965 aSymbol->SetHasDeMorganBodyStyles(
true );
968 else if( !IsSymbol( token ) )
970 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
974 names.push_back( FromUTF8() );
978 aSymbol->SetBodyStyleNames( names );
984 wxCHECK_RET( CurTok() == T_pin_names,
985 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_name token." );
995 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
998 if( token == T_hide )
1000 aSymbol->SetShowPinNames(
false );
1004 if( token != T_LEFT )
1006 Expecting( T_LEFT );
1019 aSymbol->SetShowPinNames( !
parseBool() );
1024 Expecting(
"offset or hide" );
1032 wxCHECK_RET( CurTok() == T_pin_numbers,
1033 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_number token." );
1042 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1045 if( token == T_hide )
1047 aSymbol->SetShowPinNumbers(
false );
1051 if( token != T_LEFT )
1053 Expecting( T_LEFT );
1061 aSymbol->SetShowPinNumbers( !
parseBool() );
1066 Expecting(
"hide" );
1075 wxCHECK_RET( CurTok() == T_associated_footprints,
1076 "Cannot parse " + GetTokenString( CurTok() ) +
" as an associated_footprints token." );
1085 std::vector<ASSOCIATED_FOOTPRINT> list;
1087 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1089 if( token != T_LEFT )
1090 Expecting( T_LEFT );
1094 if( token != T_footprint )
1095 Expecting(
"footprint" );
1099 if( !IsSymbol( token ) )
1100 Expecting(
"footprint library identifier" );
1105 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1107 if( token != T_LEFT )
1108 Expecting( T_LEFT );
1117 if( !IsSymbol( token ) )
1118 Expecting(
"map name" );
1124 default: Expecting(
"map" );
break;
1128 list.push_back( std::move( assoc ) );
1131 aSymbol->SetAssociatedFootprints( std::move( list ) );
1137 wxCHECK_RET( CurTok() == T_pin_maps,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_maps token." );
1148 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1150 if( token != T_LEFT )
1151 Expecting( T_LEFT );
1155 if( token != T_pin_map )
1156 Expecting(
"pin_map" );
1161 aSymbol->SetPinMaps( set );
1167 wxCHECK_MSG( CurTok() == T_pin_map,
PIN_MAP(),
1168 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_map token." );
1170 T token = NextTok();
1172 if( !IsSymbol( token ) )
1173 Expecting(
"pin map name" );
1177 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1179 if( token != T_LEFT )
1180 Expecting( T_LEFT );
1184 if( token != T_entry )
1185 Expecting(
"entry" );
1189 if( !IsSymbol( token ) )
1190 Expecting(
"pin number" );
1192 wxString pinNumber = FromUTF8();
1196 if( !IsSymbol( token ) )
1197 Expecting(
"pad number" );
1199 map.
SetEntry( pinNumber, FromUTF8() );
1211 "Cannot parse " + GetTokenString( CurTok() ) +
" as a pin_map_override token." );
1223 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
1225 if( token != T_LEFT )
1226 Expecting( T_LEFT );
1241 default: Expecting(
"library_default, named_map, identity, or delegate" );
1250 if( !IsSymbol( token ) )
1251 Expecting(
"map name" );
1253 override.m_ActiveMapName = FromUTF8();
1261 if( !IsSymbol( token ) )
1262 Expecting(
"pin number" );
1264 wxString pinNumber = FromUTF8();
1268 if( !IsSymbol( token ) )
1269 Expecting(
"pad number" );
1271 override.m_Edits.push_back( { pinNumber, FromUTF8() } );
1276 default: Expecting(
"mode, map, or edit" );
1286 wxCHECK_MSG( CurTok() == T_property,
nullptr,
1287 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a property." ) );
1288 wxCHECK( aSymbol,
nullptr );
1293 bool isPrivate =
false;
1294 bool isVisible =
true;
1296 T token = NextTok();
1298 if( token == T_private )
1304 if( !IsSymbol( token ) )
1306 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
1312 if(
name.IsEmpty() )
1314 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
1328 auto field = std::make_unique<SCH_FIELD>( aSymbol.get(), fieldId,
name );
1329 field->SetPrivate( isPrivate );
1330 field->SetVisible( isVisible );
1334 if( !IsSymbol( token ) )
1336 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
1343 value = wxEmptyString;
1347 field->SetText( value );
1349 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1351 if( token != T_LEFT )
1352 Expecting( T_LEFT );
1364 field->SetPosition(
parseXY(
true ) );
1382 field->SetNameShown( show );
1386 case T_do_not_autoplace:
1389 field->SetCanAutoplace( !doNotAutoplace );
1394 Expecting(
"id, at, hide, show_name, do_not_autoplace, or effects" );
1400 if( field->IsMandatory() )
1402 existingField = aSymbol->GetField( field->GetId() );
1404 *existingField = *field;
1405 return existingField;
1407 else if(
name ==
"ki_keywords" )
1410 aSymbol->SetKeyWords( value );
1414 else if(
name ==
"ki_description" )
1416 aSymbol->SetDescription( value );
1419 else if(
name ==
"ki_fp_filters" )
1422 wxArrayString filters;
1423 wxStringTokenizer tokenizer( value,
" \t\r\n", wxTOKEN_STRTOK );
1425 while( tokenizer.HasMoreTokens() )
1427 wxString curr_token =
UnescapeString( tokenizer.GetNextToken() );
1428 filters.Add( curr_token );
1431 aSymbol->SetFPFilters( filters );
1434 else if(
name ==
"ki_locked" )
1438 aSymbol->LockUnits(
true );
1444 existingField = aSymbol->GetField( field->GetCanonicalName() );
1452 wxString base_name = field->GetCanonicalName();
1455 for(
int ii = 1; ii < 10 && existingField; ii++ )
1457 wxString newname = base_name;
1458 newname <<
'_' << ii;
1460 existingField = aSymbol->GetField( newname );
1462 if( !existingField )
1463 field->SetName( newname );
1467 if( !existingField )
1469 aSymbol->AddDrawItem( field.get(),
false );
1470 return field.release();
1483 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
1484 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
1490 bool hasMidPoint =
false;
1498 bool hasAngles =
false;
1507 if( token == T_private )
1509 arc->SetPrivate(
true );
1513 for( ; token != T_RIGHT; token = NextTok() )
1515 if( token != T_LEFT )
1516 Expecting( T_LEFT );
1539 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1541 if( token != T_LEFT )
1542 Expecting( T_LEFT );
1570 Expecting(
"at, length, or angles" );
1578 arc->SetStroke( stroke );
1584 arc->SetFillColor( fill.
m_Color );
1588 Expecting(
"start, mid, end, radius, stroke, or fill" );
1594 arc->SetArcGeometry( startPoint, midPoint, endPoint );
1605 EDA_ANGLE arc_start, arc_end, arc_angle;
1606 arc->CalcArcAngles( arc_start, arc_end );
1607 arc_angle = arc_end - arc_start;
1612 arc->SetStart( endPoint );
1613 arc->SetEnd( startPoint );
1616 arc->SetCenter( new_center );
1622 arc->SetCenter( new_center );
1626 else if( hasAngles )
1628 arc->SetCenter(
center );
1634 arc->SetStart( endPoint );
1635 arc->SetEnd( startPoint );
1639 EDA_ANGLE arc_start, arc_end, arc_angle;
1640 arc->CalcArcAngles( arc_start, arc_end );
1641 arc_angle = arc_end - arc_start;
1647 arc->SetStart( startPoint );
1648 arc->SetEnd( endPoint );
1656 arc->SetStart( startPoint );
1657 arc->SetEnd( endPoint );
1661 arc->SetCenter( new_center );
1667 wxFAIL_MSG(
"Setting arc without either midpoint or angles not implemented." );
1670 return arc.release();
1676 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
1677 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
1685 bezier->SetUnit(
m_unit );
1690 if( token == T_private )
1692 bezier->SetPrivate(
true );
1696 for( ; token != T_RIGHT; token = NextTok() )
1698 if( token != T_LEFT )
1699 Expecting( T_LEFT );
1709 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
1711 if( token != T_LEFT )
1712 Expecting( T_LEFT );
1721 case 0: bezier->SetStart(
parseXY(
true ) );
break;
1722 case 1: bezier->SetBezierC1(
parseXY(
true ) );
break;
1723 case 2: bezier->SetBezierC2(
parseXY(
true ) );
break;
1724 case 3: bezier->SetEnd(
parseXY(
true ) );
break;
1725 default: Unexpected(
"control point" );
break;
1735 bezier->SetStroke( stroke );
1741 bezier->SetFillColor( fill.
m_Color );
1745 Expecting(
"pts, stroke, or fill" );
1749 bezier->RebuildBezierToSegmentsPointsList(
m_maxError );
1751 return bezier.release();
1757 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
1758 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
1773 if( token == T_private )
1775 circle->SetPrivate(
true );
1779 for( ; token != T_RIGHT; token = NextTok() )
1781 if( token != T_LEFT )
1782 Expecting( T_LEFT );
1800 circle->SetStroke( stroke );
1810 Expecting(
"center, radius, stroke, or fill" );
1823 wxCHECK_MSG( CurTok() == T_ellipse,
nullptr,
1824 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an ellipse." ) );
1827 ellipse->SetUnit(
m_unit );
1830 T token = NextTok();
1832 if( token == T_private )
1834 ellipse->SetPrivate(
true );
1839 return ellipse.release();
1845 wxCHECK_MSG( CurTok() == T_ellipse_arc,
nullptr,
1846 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an elliptical arc." ) );
1852 T token = NextTok();
1854 if( token == T_private )
1856 arc->SetPrivate(
true );
1861 return arc.release();
1887 Expecting(
"input, output, bidirectional, tri_state, passive, unspecified, "
1888 "power_in, power_out, open_collector, open_emitter, free or "
1910 Expecting(
"line, inverted, clock, inverted_clock, input_low, clock_low, "
1911 "output_low, edge_clock_high, non_logic" );
1916 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
1917 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a pin token." ) );
1920 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>(
nullptr );
1927 pin->SetType( parseType( token ) );
1931 pin->SetShape( parseShape( token ) );
1933 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1936 if( token == T_hide )
1938 pin->SetVisible(
false );
1942 if( token != T_LEFT )
1943 Expecting( T_LEFT );
1952 switch(
parseInt(
"pin orientation" ) )
1958 default: Expecting(
"0, 90, 180, or 270" );
1977 if( !IsSymbol( token ) )
1984 pin->SetName( wxEmptyString );
1988 pin->SetName( FromUTF8() );
1992 if( token != T_RIGHT )
1996 if( token == T_effects )
2003 pin->SetNameTextSize(
text.GetTextHeight() );
2008 Expecting(
"effects" );
2017 if( !IsSymbol( token ) )
2020 CurLineNumber(), CurOffset() );
2024 pin->SetNumber( wxEmptyString );
2028 pin->SetNumber( FromUTF8() );
2032 if( token != T_RIGHT )
2036 if( token == T_effects )
2043 pin->SetNumberTextSize(
text.GetTextHeight() );
2048 Expecting(
"effects" );
2060 if( !IsSymbol( token ) )
2063 CurLineNumber(), CurOffset() );
2069 alt.
m_Type = parseType( token );
2072 alt.
m_Shape = parseShape( token );
2074 pin->GetAlternates()[ alt.
m_Name ] = alt;
2081 Expecting(
"at, name, number, hide, length, or alternate" );
2085 return pin.release();
2091 wxCHECK_MSG( CurTok() == T_polyline,
nullptr,
2092 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a poly." ) );
2104 if( token == T_private )
2106 poly->SetPrivate(
true );
2110 for( ; token != T_RIGHT; token = NextTok() )
2112 if( token != T_LEFT )
2113 Expecting( T_LEFT );
2120 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2122 if( token != T_LEFT )
2123 Expecting( T_LEFT );
2130 poly->AddPoint(
parseXY(
true ) );
2139 poly->SetStroke( stroke );
2145 poly->SetFillColor( fill.
m_Color );
2149 Expecting(
"pts, stroke, or fill" );
2153 return poly.release();
2159 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
2160 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
2167 rectangle->SetUnit(
m_unit );
2172 if( token == T_private )
2174 rectangle->SetPrivate(
true );
2178 for( ; token != T_RIGHT; token = NextTok() )
2180 if( token != T_LEFT )
2181 Expecting( T_LEFT );
2188 rectangle->SetPosition(
parseXY(
true ) );
2193 rectangle->SetEnd(
parseXY(
true ) );
2204 rectangle->SetStroke( stroke );
2210 rectangle->SetFillColor( fill.
m_Color );
2214 Expecting(
"start, end, stroke, or fill" );
2218 return rectangle.release();
2224 wxCHECK_MSG( CurTok() == T_text,
nullptr,
2225 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text token." ) );
2228 std::unique_ptr<SCH_TEXT>
text = std::make_unique<SCH_TEXT>();
2235 if( token == T_private )
2237 text->SetPrivate(
true );
2241 if( !IsSymbol( token ) )
2243 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
2247 text->SetText( FromUTF8() );
2249 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2251 if( token != T_LEFT )
2252 Expecting( T_LEFT );
2270 Expecting(
"at or effects" );
2275 if( !
text->IsVisible() )
2278 return text.release();
2284 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
2285 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
2297 bool foundEnd =
false;
2298 bool foundSize =
false;
2299 bool foundMargins =
false;
2301 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>(
LAYER_DEVICE );
2303 textBox->SetUnit(
m_unit );
2307 if( token == T_private )
2309 textBox->SetPrivate(
true );
2313 if( !IsSymbol( token ) )
2315 THROW_PARSE_ERROR(
_(
"Invalid text string" ), CurSource(), CurLine(), CurLineNumber(),
2319 textBox->SetText( FromUTF8() );
2321 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2323 if( token != T_LEFT )
2324 Expecting( T_LEFT );
2355 textBox->SetStroke( stroke );
2361 textBox->SetFillColor( fill.
m_Color );
2366 textBox->SetMarginLeft(
left );
2367 textBox->SetMarginTop(
top );
2368 textBox->SetMarginRight(
right );
2369 textBox->SetMarginBottom( bottom );
2370 foundMargins =
true;
2379 Expecting(
"at, size, stroke, fill or effects" );
2383 textBox->SetPosition( pos );
2386 textBox->SetEnd(
end );
2387 else if( foundSize )
2388 textBox->SetEnd( pos + size );
2390 Expecting(
"size" );
2394 int margin = textBox->GetLegacyTextMargin();
2395 textBox->SetMarginLeft( margin );
2396 textBox->SetMarginTop( margin );
2397 textBox->SetMarginRight( margin );
2398 textBox->SetMarginBottom( margin );
2401 return textBox.release();
2407 wxCHECK_RET( ( CurTok() == T_page &&
m_requiredVersion <= 20200506 ) || CurTok() == T_paper,
2408 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a PAGE_INFO." ) );
2414 wxString pageType = FromUTF8();
2416 if( !aPageInfo.
SetType( pageType ) )
2418 THROW_PARSE_ERROR(
_(
"Invalid page type" ), CurSource(), CurLine(), CurLineNumber(),
2445 if( token == T_portrait )
2450 else if( token != T_RIGHT )
2452 Expecting(
"portrait" );
2459 wxCHECK_RET( CurTok() == T_title_block,
2460 "Cannot parse " + GetTokenString( CurTok() ) +
" as a TITLE_BLOCK." );
2464 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2466 if( token != T_LEFT )
2467 Expecting( T_LEFT );
2475 aTitleBlock.
SetTitle( FromUTF8() );
2480 aTitleBlock.
SetDate( FromUTF8() );
2495 int commentNumber =
parseInt(
"comment" );
2497 switch( commentNumber )
2546 CurLine(), CurLineNumber(), CurOffset() );
2553 Expecting(
"title, date, rev, company, or comment" );
2563 wxCHECK_MSG( CurTok() == T_property,
nullptr,
2564 "Cannot parse " + GetTokenString( CurTok() ) +
" as a property token." );
2566 bool is_private =
false;
2568 T token = NextTok();
2570 if( token == T_private )
2576 if( !IsSymbol( token ) )
2578 THROW_PARSE_ERROR(
_(
"Invalid property name" ), CurSource(), CurLine(), CurLineNumber(),
2582 wxString
name = FromUTF8();
2584 if(
name.IsEmpty() )
2586 THROW_PARSE_ERROR(
_(
"Empty property name" ), CurSource(), CurLine(), CurLineNumber(),
2595 name = wxT(
"Netclass" );
2599 if( !IsSymbol( token ) )
2601 THROW_PARSE_ERROR(
_(
"Invalid property value" ), CurSource(), CurLine(), CurLineNumber(),
2609 value = wxEmptyString;
2641 if(
name.CmpNoCase( wxT(
"Sheet name" ) ) == 0 )
2643 else if(
name.CmpNoCase( wxT(
"Sheet file" ) ) == 0 )
2658 if(
name.CmpNoCase( wxT(
"Intersheet References" ) ) == 0 )
2662 std::unique_ptr<SCH_FIELD> field = std::make_unique<SCH_FIELD>( aParent, fieldId,
name );
2663 field->SetText( value );
2666 field->SetPrivate( is_private );
2668 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2670 if( token != T_LEFT )
2671 Expecting( T_LEFT );
2683 field->SetPosition(
parseXY() );
2701 field->SetNameShown( show );
2705 case T_do_not_autoplace:
2708 field->SetCanAutoplace( !doNotAutoplace );
2713 Expecting(
"id, at, hide, show_name, do_not_autoplace or effects" );
2717 return field.release();
2723 wxCHECK_MSG( aSheet !=
nullptr,
nullptr,
"" );
2724 wxCHECK_MSG( CurTok() == T_pin,
nullptr,
2725 "Cannot parse " + GetTokenString( CurTok() ) +
" as a sheet pin token." );
2727 T token = NextTok();
2729 if( !IsSymbol( token ) )
2731 THROW_PARSE_ERROR(
_(
"Invalid sheet pin name" ), CurSource(), CurLine(), CurLineNumber(),
2735 wxString
name = FromUTF8();
2737 if(
name.IsEmpty() )
2739 THROW_PARSE_ERROR(
_(
"Empty sheet pin name" ), CurSource(), CurLine(), CurLineNumber(),
2743 auto sheetPin = std::make_unique<SCH_SHEET_PIN>( aSheet,
VECTOR2I( 0, 0 ),
name );
2755 Expecting(
"input, output, bidirectional, tri_state, or passive" );
2758 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2760 if( token != T_LEFT )
2761 Expecting( T_LEFT );
2769 sheetPin->SetPosition(
parseXY() );
2771 double angle =
parseDouble(
"sheet pin angle (side)" );
2775 else if( angle == 90.0 )
2777 else if( angle == 180.0 )
2779 else if( angle == 270.0 )
2782 Expecting(
"0, 90, 180, or 270" );
2799 Expecting(
"at, uuid or effects" );
2803 return sheetPin.release();
2809 wxCHECK_RET( CurTok() == T_sheet_instances,
2810 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
2811 wxCHECK( aScreen, );
2815 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2817 if( token != T_LEFT )
2818 Expecting( T_LEFT );
2836 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2838 if( token != T_LEFT )
2839 Expecting( T_LEFT );
2843 std::vector<wxString> whitespaces = { wxT(
"\r" ), wxT(
"\n" ), wxT(
"\t" ),
2846 size_t numReplacements = 0;
2864 for(
const wxString& ch : whitespaces )
2865 numReplacements += instance.
m_PageNumber.Replace( ch, wxEmptyString );
2870 if( numReplacements > 0 )
2877 Expecting(
"path or page" );
2882 && ( instance.
m_Path.empty() ) )
2898 Expecting(
"path" );
2906 wxCHECK_RET( CurTok() == T_symbol_instances,
2907 "Cannot parse " + GetTokenString( CurTok() ) +
" as an instances token." );
2908 wxCHECK( aScreen, );
2913 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2915 if( token != T_LEFT )
2916 Expecting( T_LEFT );
2933 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2935 if( token != T_LEFT )
2936 Expecting( T_LEFT );
2957 instance.
m_Value = wxEmptyString;
2959 instance.
m_Value = FromUTF8();
2976 Expecting(
"path, unit, value or footprint" );
2985 Expecting(
"path" );
2994 wxCHECK( aSheet !=
nullptr, );
2998 wxCHECK( screen !=
nullptr, );
3001 m_maxError = schematic->Settings().m_MaxError;
3003 if( aIsCopyableOnly )
3006 bool fileHasUuid =
false;
3020 if( !aIsCopyableOnly )
3025 if( CurTok() != T_kicad_sch )
3026 Expecting(
"kicad_sch" );
3045 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3047 if( aIsCopyableOnly && token == T_EOF )
3050 if( token != T_LEFT )
3051 Expecting( T_LEFT );
3085 case T_generator_version:
3111 if( aIsCopyableOnly )
3112 Unexpected( T_paper );
3122 if( aIsCopyableOnly )
3123 Unexpected( T_page );
3127 NeedSYMBOLorNUMBER();
3128 NeedSYMBOLorNUMBER();
3135 if( aIsCopyableOnly )
3136 Unexpected( T_title_block );
3150 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3152 if( token != T_LEFT )
3153 Expecting( T_LEFT );
3165 Expecting(
"symbol" );
3222 THROW_PARSE_ERROR(
_(
"Schematic polyline has too few points" ), CurSource(), CurLine(),
3223 CurLineNumber(), CurOffset() );
3277 case T_netclass_flag:
3282 case T_global_label:
3283 case T_hierarchical_label:
3284 case T_directive_label:
3300 case T_sheet_instances:
3304 case T_symbol_instances:
3309 if( aIsCopyableOnly )
3310 Unexpected( T_bus_alias );
3315 case T_embedded_fonts:
3321 CurLineNumber(), CurOffset() );
3323 schematic->GetEmbeddedFiles()->SetAreFontsEmbedded(
parseBool() );
3328 case T_embedded_files:
3334 CurLineNumber(), CurOffset() );
3337 embeddedFilesParser.SyncLineReaderWith( *
this );
3341 embeddedFilesParser.
ParseEmbedded( schematic->GetEmbeddedFiles() );
3349 for(
int tok = embeddedFilesParser.NextTok();
3351 tok = embeddedFilesParser.NextTok() )
3355 else if( tok ==
DSN_RIGHT && --depth < 0 )
3360 SyncLineReaderWith( embeddedFilesParser );
3366 Expecting(
"arc, bezier, bitmap, bus, bus_alias, bus_entry, circle, class_label, "
3367 "directive_label, ellipse, ellipse_arc, embedded_fonts, embedded_files, "
3368 "global_label, hierarchical_label, image, junction, lib_symbols, "
3369 "netclass_flag, no_connect, polyline, rectangle, rule_area, sheet, "
3370 "sheet_instances, signal, symbol, symbol_instances, table, text, "
3371 "text_box, title_block, uuid, wire" );
3392 CurLineNumber(), CurOffset() );
3396 std::vector<std::string> fontNames;
3397 Fontconfig()->ListFonts( fontNames, std::string(
Pgm().GetLanguageTag().utf8_str() ),
3398 schematic->GetEmbeddedFiles()->GetFontFiles(),
true );
3407 wxCHECK_MSG( CurTok() == T_symbol,
nullptr,
3408 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a symbol." ) );
3413 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
3415 std::set<int> fieldIDsRead;
3420 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3422 if( token != T_LEFT )
3423 Expecting( T_LEFT );
3435 if( !IsSymbol( token ) )
3438 CurLineNumber(), CurOffset() );
3441 libName = FromUTF8();
3445 libName.Replace(
"{slash}",
"/" );
3455 if( !IsSymbol( token ) && token != T_NUMBER )
3456 Expecting(
"symbol|number" );
3459 wxString
name = FromUTF8();
3463 name.Replace(
"{slash}",
"/" );
3469 if(
static_cast<int>(
name.size() ) > bad_pos )
3471 wxString msg = wxString::Format(
_(
"Symbol %s contains invalid character '%c'" ),
3479 CurLineNumber(), CurOffset() );
3482 symbol->SetLibId( libId );
3488 symbol->SetPosition(
parseXY() );
3490 switch(
static_cast<int>(
parseDouble(
"symbol orientation" ) ) )
3493 case 90: transform =
TRANSFORM( 0, 1, -1, 0 );
break;
3494 case 180: transform =
TRANSFORM( -1, 0, 0, -1 );
break;
3495 case 270: transform =
TRANSFORM( 0, -1, 1, 0 );
break;
3496 default: Expecting(
"0, 90, 180, or 270" );
3499 symbol->SetTransform( transform );
3508 else if( token == T_y )
3511 Expecting(
"x or y" );
3517 symbol->SetUnit(
parseInt(
"symbol unit" ) );
3523 symbol->SetBodyStyle(
parseInt(
"symbol body style" ) );
3527 case T_exclude_from_sim:
3528 symbol->SetExcludedFromSim(
parseBool() );
3533 symbol->SetExcludedFromBOM( !
parseBool() );
3538 symbol->SetExcludedFromBoard( !
parseBool() );
3542 case T_in_pos_files:
3543 symbol->SetExcludedFromPosFiles( !
parseBool() );
3565 if( !IsSymbol( t ) )
3566 Expecting(
"default, block or force" );
3568 wxString mode = FromUTF8();
3570 if( mode.IsSameAs( wxT(
"default"),
false ) )
3572 else if( mode.IsSameAs( wxT(
"block"),
false ) )
3574 else if( mode.IsSameAs( wxT(
"force"),
false ) )
3577 Expecting(
"default, block or force" );
3583 case T_fields_autoplaced:
3595 case T_default_instance:
3599 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3601 if( token != T_LEFT )
3602 Expecting( T_LEFT );
3623 symbol->SetValueFieldText( wxEmptyString );
3625 symbol->SetValueFieldText( FromUTF8() );
3634 symbol->SetFootprintFieldText( wxEmptyString );
3636 symbol->SetFootprintFieldText( FromUTF8() );
3642 Expecting(
"reference, unit, value or footprint" );
3651 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3653 if( token != T_LEFT )
3654 Expecting( T_LEFT );
3658 if( token != T_project )
3659 Expecting(
"project" );
3663 wxString projectName = FromUTF8();
3665 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3667 if( token != T_LEFT )
3668 Expecting( T_LEFT );
3672 if( token != T_path )
3673 Expecting(
"path" );
3682 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3684 if( token != T_LEFT )
3685 Expecting( T_LEFT );
3706 symbol->SetValueFieldText( wxEmptyString );
3708 symbol->SetValueFieldText( FromUTF8() );
3717 symbol->SetFootprintFieldText( wxEmptyString );
3719 symbol->SetFootprintFieldText( FromUTF8() );
3730 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3732 if( token != T_LEFT )
3733 Expecting( T_LEFT );
3741 variant.
m_Name = FromUTF8();
3750 case T_exclude_from_sim:
3772 case T_in_pos_files:
3780 wxString fieldValue;
3782 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3784 if( token != T_LEFT )
3785 Expecting( T_LEFT );
3793 fieldName = FromUTF8();
3799 fieldValue = FromUTF8();
3804 Expecting(
"name or value" );
3808 variant.
m_Fields[fieldName] = fieldValue;
3815 Expecting(
"dnp, exclude_from_sim, field, in_bom, in_pos_files, name, "
3816 "on_board, or pin_map_override" );
3826 Expecting(
"reference, unit, value, footprint, or variant" );
3830 symbol->AddHierarchicalReference( instance );
3846 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"0" ) );
3854 symbol->SetExcludedFromSim( field->
GetText() == wxS(
"N" ) );
3862 existing = symbol->GetField( field->
GetId() );
3864 existing = symbol->GetField( field->
GetName() );
3869 symbol->AddField( *field );
3872 symbol->UpdatePrefix();
3885 number = FromUTF8();
3887 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3889 if( token != T_LEFT )
3890 Expecting( T_LEFT );
3914 Expecting(
"alternate or uuid" );
3918 symbol->GetRawPins().emplace_back( std::make_unique<SCH_PIN>( symbol.get(), number,
3924 Expecting(
"lib_id, lib_name, at, mirror, uuid, exclude_from_sim, on_board, in_bom, dnp, passthrough, "
3925 "default_instance, property, pin, or instances" );
3929 if( !libName.IsEmpty() && ( symbol->GetLibId().Format().wx_str() != libName ) )
3930 symbol->SetSchSymbolLibraryName( libName );
3933 symbol->ClearFlags();
3935 return symbol.release();
3941 wxCHECK_MSG( CurTok() == T_image,
nullptr,
3942 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an image." ) );
3945 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>();
3948 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3950 if( token != T_LEFT )
3951 Expecting( T_LEFT );
3958 bitmap->SetPosition(
parseXY() );
3984 data.reserve( 1 << 17 );
3986 while( token != T_RIGHT )
3988 if( !IsSymbol( token ) )
3989 Expecting(
"base64 image data" );
3995 wxMemoryBuffer buffer = wxBase64Decode( data );
4009 Expecting(
"at, scale, uuid, data or locked" );
4027 int legacyPPI =
image.GetLegacyPPI();
4029 if( legacyPPI > 0 &&
image.GetPPI() != legacyPPI )
4033 return bitmap.release();
4039 wxCHECK_MSG( CurTok() == T_sheet,
nullptr,
4040 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a sheet." ) );
4046 std::vector<SCH_FIELD> fields;
4047 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>();
4048 std::set<int> fieldIDsRead;
4053 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4055 if( token != T_LEFT )
4056 Expecting( T_LEFT );
4063 sheet->SetPosition(
parseXY() );
4072 sheet->SetSize( size );
4077 case T_exclude_from_sim:
4078 sheet->SetExcludedFromSim(
parseBool() );
4083 sheet->SetExcludedFromBOM( !
parseBool() );
4088 sheet->SetExcludedFromBoard( !
parseBool() );
4102 case T_fields_autoplaced:
4110 sheet->SetBorderWidth( stroke.
GetWidth() );
4111 sheet->SetBorderColor( stroke.
GetColor() );
4116 sheet->SetBackgroundColor( fill.
m_Color );
4133 if( fields.empty() )
4139 fields.emplace_back( *field );
4150 std::vector<SCH_SHEET_INSTANCE> instances;
4152 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4154 if( token != T_LEFT )
4155 Expecting( T_LEFT );
4159 if( token != T_project )
4160 Expecting(
"project" );
4164 wxString projectName = FromUTF8();
4166 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4168 if( token != T_LEFT )
4169 Expecting( T_LEFT );
4173 if( token != T_path )
4174 Expecting(
"path" );
4183 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4185 if( token != T_LEFT )
4186 Expecting( T_LEFT );
4206 static std::vector<wxString> whitespaces =
4212 for( wxString ch : whitespaces )
4225 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4227 if( token != T_LEFT )
4228 Expecting( T_LEFT );
4236 variant.
m_Name = FromUTF8();
4245 case T_exclude_from_sim:
4267 case T_in_pos_files:
4275 wxString fieldValue;
4277 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4279 if( token != T_LEFT )
4280 Expecting( T_LEFT );
4288 fieldName = FromUTF8();
4294 fieldValue = FromUTF8();
4299 Expecting(
"name or value" );
4303 variant.
m_Fields[fieldName] = fieldValue;
4308 Expecting(
"dnp, exclude_from_sim, field, in_bom, in_pos_files, name, or on_board" );
4318 Expecting(
"page or variant" );
4322 instances.emplace_back( instance );
4326 sheet->setInstances( instances );
4331 Expecting(
"at, size, stroke, background, instances, uuid, property, or pin" );
4335 sheet->SetFields( fields );
4340 CurLineNumber(), CurOffset() );
4346 CurLineNumber(), CurOffset() );
4349 return sheet.release();
4355 wxCHECK_MSG( CurTok() == T_junction,
nullptr,
4356 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a junction." ) );
4359 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
4361 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4363 if( token != T_LEFT )
4364 Expecting( T_LEFT );
4371 junction->SetPosition(
parseXY() );
4387 color.
a = std::clamp(
parseDouble(
"alpha" ), 0.0, 1.0 );
4389 junction->SetColor( color );
4406 Expecting(
"at, diameter, color, uuid or locked" );
4410 return junction.release();
4416 wxCHECK_MSG( CurTok() == T_no_connect,
nullptr,
4417 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a no connect." ) );
4420 std::unique_ptr<SCH_NO_CONNECT> no_connect = std::make_unique<SCH_NO_CONNECT>();
4422 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4424 if( token != T_LEFT )
4425 Expecting( T_LEFT );
4432 no_connect->SetPosition(
parseXY() );
4448 Expecting(
"at, uuid or locked" );
4452 return no_connect.release();
4458 wxCHECK_MSG( CurTok() == T_bus_entry,
nullptr,
4459 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus entry." ) );
4463 std::unique_ptr<SCH_BUS_WIRE_ENTRY> busEntry = std::make_unique<SCH_BUS_WIRE_ENTRY>();
4465 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4467 if( token != T_LEFT )
4468 Expecting( T_LEFT );
4475 busEntry->SetPosition(
parseXY() );
4485 busEntry->SetSize( size );
4492 busEntry->SetStroke( stroke );
4507 Expecting(
"at, size, uuid, stroke or locked" );
4511 return busEntry.release();
4533 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4535 if( token != T_LEFT )
4536 Expecting( T_LEFT );
4543 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4545 if( token != T_LEFT )
4546 Expecting( T_LEFT );
4553 polyline->AddPoint(
parseXY() );
4566 polyline->SetStroke( stroke );
4572 polyline->SetFillColor( fill.
m_Color );
4588 Expecting(
"pts, uuid, stroke, fill or locked" );
4592 return polyline.release();
4611 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as a line." );
4614 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>(
VECTOR2I(), layer );
4616 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4618 if( token != T_LEFT )
4619 Expecting( T_LEFT );
4632 line->SetStartPoint(
parseXY() );
4640 line->SetEndPoint(
parseXY() );
4647 line->SetStroke( stroke );
4662 Expecting(
"pts, uuid, stroke or locked" );
4666 return line.release();
4672 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
4673 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an arc." ) );
4681 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>(
SHAPE_T::ARC );
4683 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4685 if( token != T_LEFT )
4686 Expecting( T_LEFT );
4709 arc->SetStroke( stroke );
4715 arc->SetFillColor( fill.
m_Color );
4731 Expecting(
"start, mid, end, stroke, fill, uuid or locked" );
4735 arc->SetArcGeometry( startPoint, midPoint, endPoint );
4737 return arc.release();
4743 wxCHECK_MSG( CurTok() == T_circle,
nullptr,
4744 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a circle." ) );
4753 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4755 if( token != T_LEFT )
4756 Expecting( T_LEFT );
4774 circle->SetStroke( stroke );
4796 Expecting(
"center, radius, stroke, fill, uuid or locked" );
4809 wxCHECK_MSG( CurTok() == T_rectangle,
nullptr,
4810 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rectangle." ) );
4815 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>(
SHAPE_T::RECTANGLE );
4817 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4819 if( token != T_LEFT )
4820 Expecting( T_LEFT );
4827 rectangle->SetPosition(
parseXY() );
4832 rectangle->SetEnd(
parseXY() );
4843 rectangle->SetStroke( stroke );
4849 rectangle->SetFillColor( fill.
m_Color );
4865 Expecting(
"start, end, stroke, fill, uuid or locked" );
4869 return rectangle.release();
4875 wxCHECK_MSG( CurTok() == T_rule_area,
nullptr,
4876 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a rule area." ) );
4881 std::unique_ptr<SCH_RULE_AREA> ruleArea = std::make_unique<SCH_RULE_AREA>();
4883 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4885 if( token != T_LEFT )
4886 Expecting( T_LEFT );
4900 ruleArea->SetPolyShape( sch_rule_poly );
4902 ruleArea->SetStroke( poly->GetStroke() );
4903 ruleArea->SetFillMode( poly->GetFillMode() );
4904 ruleArea->SetFillColor( poly->GetFillColor() );
4907 const_cast<KIID&
>( ruleArea->m_Uuid ) = poly->m_Uuid;
4911 case T_exclude_from_sim:
4912 ruleArea->SetExcludedFromSim(
parseBool() );
4917 ruleArea->SetExcludedFromBOM( !
parseBool() );
4922 ruleArea->SetExcludedFromBoard( !
parseBool() );
4937 Expecting(
"exclude_from_sim, on_board, in_bom, dnp, locked, or polyline" );
4941 return ruleArea.release();
4947 wxCHECK_MSG( CurTok() == T_bezier,
nullptr,
4948 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bezier." ) );
4953 std::unique_ptr<SCH_SHAPE> bezier = std::make_unique<SCH_SHAPE>(
SHAPE_T::BEZIER );
4955 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4957 if( token != T_LEFT )
4958 Expecting( T_LEFT );
4968 for( token = NextTok(); token != T_RIGHT; token = NextTok(), ++ii )
4970 if( token != T_LEFT )
4971 Expecting( T_LEFT );
4980 case 0: bezier->SetStart(
parseXY() );
break;
4981 case 1: bezier->SetBezierC1(
parseXY() );
break;
4982 case 2: bezier->SetBezierC2(
parseXY() );
break;
4983 case 3: bezier->SetEnd(
parseXY() );
break;
4984 default: Unexpected(
"control point" );
break;
4994 bezier->SetStroke( stroke );
5000 bezier->SetFillColor( fill.
m_Color );
5016 Expecting(
"pts, stroke, fill, uuid or locked" );
5020 bezier->RebuildBezierToSegmentsPointsList(
m_maxError );
5022 return bezier.release();
5027 TSCHEMATIC_T::T aFirstTok )
5033 int majorRadius = 1;
5034 int minorRadius = 1;
5041 for(
T token = aFirstTok; token != T_RIGHT; token = NextTok() )
5043 if( token != T_LEFT )
5044 Expecting( T_LEFT );
5056 case T_major_radius:
5061 case T_minor_radius:
5066 case T_rotation_angle:
5073 Expecting(
"start_angle only valid inside ellipse_arc" );
5080 Expecting(
"end_angle only valid inside ellipse_arc" );
5100 Expecting(
"uuid only valid in schematic context" );
5108 Expecting(
"locked only valid in schematic context" );
5114 Expecting(
"center, major_radius, minor_radius, rotation_angle, "
5115 "start_angle, end_angle, stroke, fill, uuid, or locked" );
5134 wxCHECK_MSG( CurTok() == T_ellipse,
nullptr,
5135 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an ellipse." ) );
5139 return ellipse.release();
5145 wxCHECK_MSG( CurTok() == T_ellipse_arc,
nullptr,
5146 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an elliptical arc." ) );
5150 return arc.release();
5157 std::unique_ptr<SCH_TEXT>
text;
5161 case T_text:
text = std::make_unique<SCH_TEXT>();
break;
5162 case T_label:
text = std::make_unique<SCH_LABEL>();
break;
5163 case T_global_label:
text = std::make_unique<SCH_GLOBALLABEL>();
break;
5164 case T_hierarchical_label:
text = std::make_unique<SCH_HIERLABEL>();
break;
5165 case T_netclass_flag:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
5166 case T_directive_label:
text = std::make_unique<SCH_DIRECTIVE_LABEL>();
break;
5168 wxCHECK_MSG(
false,
nullptr,
"Cannot parse " + GetTokenString( CurTok() ) +
" as text." );
5176 text->SetText( FromUTF8() );
5178 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5180 if( token != T_LEFT )
5181 Expecting( T_LEFT );
5187 case T_exclude_from_sim:
5198 switch(
static_cast<int>( label->GetTextAngle().AsDegrees() ) )
5214 Unexpected( T_shape );
5232 Expecting(
"input, output, bidirectional, tri_state, passive, dot, round, diamond"
5243 Unexpected( T_length );
5252 case T_fields_autoplaced:
5262 text->SetVisible(
true );
5287 Unexpected( T_property );
5312 Expecting(
"at, shape, iref, uuid, effects or locked" );
5318 if( label && label->
GetFields().empty() )
5321 return text.release();
5327 wxCHECK_MSG( CurTok() == T_text_box,
nullptr,
5328 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a text box." ) );
5330 std::unique_ptr<SCH_TEXTBOX> textBox = std::make_unique<SCH_TEXTBOX>();
5334 return textBox.release();
5340 wxCHECK_MSG( CurTok() == T_table_cell,
nullptr,
5341 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table cell." ) );
5343 std::unique_ptr<SCH_TABLECELL> cell = std::make_unique<SCH_TABLECELL>();
5347 return cell.release();
5363 bool foundEnd =
false;
5364 bool foundSize =
false;
5365 bool foundMargins =
false;
5369 aTextBox->
SetText( FromUTF8() );
5371 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5373 if( token != T_LEFT )
5374 Expecting( T_LEFT );
5380 case T_exclude_from_sim:
5411 cell->SetColSpan(
parseInt(
"column span" ) );
5412 cell->SetRowSpan(
parseInt(
"row span" ) );
5416 Expecting(
"at, size, stroke, fill, effects or uuid" );
5440 foundMargins =
true;
5461 Expecting(
"at, size, stroke, fill, effects, span, uuid or locked" );
5463 Expecting(
"at, size, stroke, fill, effects, uuid or locked" );
5471 else if( foundSize )
5472 aTextBox->
SetEnd( pos + size );
5474 Expecting(
"size" );
5489 wxCHECK_MSG( CurTok() == T_table,
nullptr,
5490 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table." ) );
5496 std::unique_ptr<SCH_TABLE>
table = std::make_unique<SCH_TABLE>( defaultLineWidth );
5498 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5500 if( token != T_LEFT )
5501 Expecting( T_LEFT );
5507 case T_column_count:
5512 case T_column_widths:
5516 while( ( token = NextTok() ) != T_RIGHT )
5526 while( ( token = NextTok() ) != T_RIGHT )
5533 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5535 if( token != T_LEFT )
5536 Expecting( T_LEFT );
5540 if( token != T_table_cell )
5541 Expecting(
"table_cell" );
5549 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5551 if( token != T_LEFT )
5552 Expecting( T_LEFT );
5570 table->SetBorderStroke( borderStroke );
5574 Expecting(
"external, header or stroke" );
5582 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5584 if( token != T_LEFT )
5585 Expecting( T_LEFT );
5603 table->SetSeparatorsStroke( separatorsStroke );
5607 Expecting(
"rows, cols, or stroke" );
5626 Expecting(
"columns, col_widths, row_heights, border, separators, uuid, locked, header or cells" );
5630 if( !
table->GetCell( 0, 0 ) )
5632 THROW_PARSE_ERROR(
_(
"Invalid table: no cells defined" ), CurSource(), CurLine(), CurLineNumber(),
5636 return table.release();
5642 wxCHECK_RET( CurTok() == T_bus_alias,
5643 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a bus alias." ) );
5644 wxCHECK( aScreen, );
5647 std::shared_ptr<BUS_ALIAS> busAlias = std::make_shared<BUS_ALIAS>();
5658 busAlias->SetName( alias );
5663 if( token != T_members )
5664 Expecting(
"members" );
5668 while( token != T_RIGHT )
5670 if( !IsSymbol( token ) )
5671 Expecting(
"quoted string" );
5673 member = FromUTF8();
5678 busAlias->AddMember( member );
5694 wxString
name = FromUTF8();
5698 wxString fromRef, fromPin, toRef, toPin;
5699 std::set<wxString> memberNets;
5701 for(
T tok = NextTok(); tok != T_RIGHT; tok = NextTok() )
5708 NeedSYMBOLorNUMBER();
5710 NeedSYMBOLorNUMBER();
5714 else if( tok == T_to )
5716 NeedSYMBOLorNUMBER();
5718 NeedSYMBOLorNUMBER();
5722 else if( tok == T_net_class )
5724 NeedSYMBOLorNUMBER();
5725 netClass = FromUTF8();
5728 else if( tok == T_color )
5734 color =
COLOR4D( r / 255.0, g / 255.0, b / 255.0, al );
5737 else if( tok == T_nets )
5739 for(
T inner = NextTok(); inner != T_RIGHT; inner = NextTok() )
5741 if( !IsSymbol( inner ) && inner != T_NUMBER )
5742 Expecting(
"net name" );
5744 memberNets.insert( FromUTF8() );
5754 T inner = NextTok();
5756 if( inner == T_EOF )
5759 if( inner == T_LEFT )
5761 else if( inner == T_RIGHT )
5767 if( !fromRef.IsEmpty() && !toRef.IsEmpty() )
5772 if( !netClass.IsEmpty() )
5778 if( !memberNets.empty() )
5787 while( ( token = NextTok() ) != T_RIGHT )
5792 KIID uuid( CurStr() );
5800 wxCHECK_RET( CurTok() == T_group,
5801 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GROUP." ) );
5808 while( ( token = NextTok() ) != T_LEFT )
5810 if( token == T_STRING )
5811 groupInfo.
name = FromUTF8();
5813 Expecting(
"group name or locked" );
5816 for( ; token != T_RIGHT; token = NextTok() )
5818 if( token != T_LEFT )
5819 Expecting( T_LEFT );
5835 if( !IsSymbol( token ) && token != T_NUMBER )
5836 Expecting(
"symbol|number" );
5839 wxString
name = FromUTF8();
5843 name.Replace(
"{slash}",
"/" );
5849 if(
static_cast<int>(
name.size() ) > bad_pos )
5851 wxString msg = wxString::Format(
_(
"Group library link %s contains invalid character '%c'" ),
name,
5857 THROW_PARSE_ERROR(
_(
"Invalid library ID" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
5876 Expecting(
"uuid, lib_id, members, locked" );
5888 [&](
const KIID& aId )
5894 if( item->m_Uuid == aId )
5913 group->SetName( groupInfo.name );
5915 const_cast<KIID&
>(
group->m_Uuid ) = groupInfo.uuid;
5917 if( groupInfo.libId.IsValid() )
5918 group->SetDesignBlockLibId( groupInfo.libId );
5920 group->SetLocked( groupInfo.locked );
5931 for(
const KIID& aUuid : groupInfo.memberUuids )
5933 if(
SCH_ITEM* gItem = getItem( aUuid ) )
5934 group->AddItem( gItem );
5949 T token = NextTok();
5951 if( token == T_EOF )
5953 else if( token == T_LEFT )
5955 else if( token == T_RIGHT )
constexpr EDA_IU_SCALE schIUScale
constexpr double ARC_LOW_DEF_MM
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
void SetContentModified(bool aModified=true)
This class handle bitmap images in KiCad.
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
KICAD_T Type() const
Returns the type of object.
EDA_ITEM * GetParent() const
virtual void SetParent(EDA_ITEM *aParent)
virtual void SetEnd(const VECTOR2I &aEnd)
FILL_T GetFillMode() const
SHAPE_POLY_SET & GetPolyShape()
virtual void SetEllipseEndAngle(const EDA_ANGLE &aA)
virtual void SetEllipseRotation(const EDA_ANGLE &aA)
void SetFillColor(const COLOR4D &aColor)
int GetPointCount() const
virtual void SetEllipseCenter(const VECTOR2I &aPt)
virtual void SetEllipseMinorRadius(int aR)
virtual void SetEllipseMajorRadius(int aR)
virtual void SetEllipseStartAngle(const EDA_ANGLE &aA)
void SetFillMode(FILL_T aFill)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
void SetTextColor(const COLOR4D &aColor)
virtual void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
void SetUnresolvedFontName(const wxString &aFontName)
virtual const wxString & GetText() const
Return the string associated with the text object.
virtual void SetTextPos(const VECTOR2I &aPoint)
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
void SetBoldFlag(bool aBold)
Set only the bold flag, without changing the font.
virtual void SetVisible(bool aVisible)
void SetLineSpacing(double aLineSpacing)
virtual void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
static bool ValidateHyperlink(const wxString &aURL)
Check if aURL is a valid hyperlink.
void SetItalicFlag(bool aItalic)
Set only the italic flag, without changing the font.
void SetHyperlink(wxString aLink)
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
void ParseEmbedded(EMBEDDED_FILES *aFiles)
const std::vector< wxString > * UpdateFontFiles()
Helper function to get a list of fonts for fontconfig to add to the library.
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 symbol-owned ordered set of named pin maps.
void AddOrReplace(PIN_MAP aMap)
Insert aMap, replacing any existing entry with the same name.
void SetEntry(const wxString &aPinNumber, const wxString &aPadNumber)
Set the pad number for a symbol pin.
A progress reporter interface for use in multi-threaded environments.
A REFERENCE_IMAGE is a wrapper around a BITMAP_IMAGE that is displayed in an editor as a reference fo...
bool ReadImageFile(const wxString &aFullFilename)
Read and store an image file.
const BITMAP_BASE & GetImage() const
Get the underlying image.
double GetImageScale() const
void SetImageScale(double aScale)
Set the image "zoom" value.
Holds all the data relating to one schematic.
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).
static bool IsNetclassLabelFieldName(const wxString &aName)
Test whether aName is one of the known translations of the directive-label net class field name (used...
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this label.
A set of SCH_ITEMs (i.e., without duplicates).
SCH_ITEM * ParseSymbolDrawItem()
SCH_SHAPE * parseSymbolPolyLine()
SCH_TABLE * parseSchTable()
bool m_appending
Appending load status.
unsigned m_lastProgressLine
SCH_FIELD * parseSchField(SCH_ITEM *aParent)
SCH_SHAPE * parseSchCircle()
SCH_TEXT * parseSchText()
SCH_TABLECELL * parseSchTableCell()
void parseSchSymbolInstances(SCH_SCREEN *aScreen)
void parsePinNumbers(std::unique_ptr< LIB_SYMBOL > &aSymbol)
LIB_SYMBOL * parseLibSymbol(LIB_SYMBOL_MAP &aSymbolLibMap)
void parseEllipseBody(SCH_SHAPE *aShape, bool aIsArc, bool aIsSchematic, TSCHEMATIC_T::T aFirstTok)
SCH_RULE_AREA * parseSchRuleArea()
SCH_SHAPE * parseSymbolEllipseArc()
SCH_ITEM * parseSymbolText()
PROGRESS_REPORTER * m_progressReporter
void parseFill(FILL_PARAMS &aFill)
SCH_TEXTBOX * parseSymbolTextBox()
void parseBusAlias(SCH_SCREEN *aScreen)
void parseTITLE_BLOCK(TITLE_BLOCK &aTitleBlock)
void parseGroupMembers(GROUP_INFO &aGroupInfo)
void parseStroke(STROKE_PARAMS &aStroke)
Parse stroke definition aStroke.
int m_unit
The current unit being parsed.
std::map< wxString, std::set< wxString > > m_netChainMemberNets
SCH_SHAPE * parseSymbolBezier()
void parseEDA_TEXT(EDA_TEXT *aText, bool aConvertOverbarSyntax, bool aEnforceMinTextSize=true)
SCH_TEXTBOX * parseSchTextBox()
void resolveGroups(SCH_SCREEN *aParent)
std::map< wxString, wxString > m_netChainNetClasses
SCH_SHEET * m_rootSheet
The rootsheet for full project loads or null for importing a schematic.
SCH_SHAPE * parseSchArc()
SCH_SHAPE * parseSchPolyLine()
SCH_BITMAP * parseImage()
SCH_SHAPE * parseSymbolCircle()
wxString m_generatorVersion
void ParseLib(LIB_SYMBOL_MAP &aSymbolLibMap)
SCH_PIN * parseSymbolPin()
std::vector< GROUP_INFO > m_groupInfos
void parseHeader(TSCHEMATIC_T::T aHeaderType, int aFileVersion)
void parseBodyStyles(std::unique_ptr< LIB_SYMBOL > &aSymbol)
SCH_SHAPE * parseSchEllipse()
void parsePinMaps(std::unique_ptr< LIB_SYMBOL > &aSymbol)
void parseMargins(int &aLeft, int &aTop, int &aRight, int &aBottom)
wxString m_symbolName
The current symbol name.
std::map< wxString, CHAIN_TERMINALS > m_netChainTerminalRefs
VECTOR2I parseXY(bool aInvertY=false)
SCH_SHAPE * parseSymbolRectangle()
void parsePinNames(std::unique_ptr< LIB_SYMBOL > &aSymbol)
void parseAssociatedFootprints(std::unique_ptr< LIB_SYMBOL > &aSymbol)
SCH_SHAPE * parseSchBezier()
std::vector< wxString > m_parseWarnings
Non-fatal warnings collected during parsing.
SCH_JUNCTION * parseJunction()
void ParseSchematic(SCH_SHEET *aSheet, bool aIsCopyablyOnly=false, int aFileVersion=SEXPR_SCHEMATIC_FILE_VERSION)
Parse the internal LINE_READER object into aSheet.
SCH_SHEET_PIN * parseSchSheetPin(SCH_SHEET *aSheet)
int m_bodyStyle
The current body style being parsed.
SCH_NO_CONNECT * parseNoConnect()
SCH_SHAPE * parseSymbolArc()
SCH_BUS_WIRE_ENTRY * parseBusEntry()
SCH_SHAPE * parseSymbolEllipse()
PIN_MAP_INSTANCE_OVERRIDE parsePinMapOverride()
std::map< wxString, COLOR4D > m_netChainColors
SCH_SHAPE * parseSchRectangle()
SCH_FIELD * parseProperty(std::unique_ptr< LIB_SYMBOL > &aSymbol)
SCH_SYMBOL * parseSchematicSymbol()
void parseSchTextBoxContent(SCH_TEXTBOX *aTextBox)
bool parseMaybeAbsentBool(bool aDefaultValue)
Parses a boolean flag inside a list that existed before boolean normalization.
void parsePAGE_INFO(PAGE_INFO &aPageInfo)
int m_requiredVersion
Set to the symbol library file version required.
int m_maxError
Max deviation allowed when approximating bezier curves.
const LINE_READER * m_lineReader
LIB_SYMBOL * ParseSymbol(LIB_SYMBOL_MAP &aSymbolLibMap, int aFileVersion=SEXPR_SYMBOL_LIB_FILE_VERSION)
Parse internal LINE_READER object into symbols and return all found.
void skipToBlockEnd(int aDepth=1)
Skip tokens until we reach the end of the current S-expression block.
void parseSchSheetInstances(SCH_SHEET *aRootSheet, SCH_SCREEN *aScreen)
SCH_SHAPE * parseSchEllipseArc()
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.
PIN_MAP_INSTANCE_OVERRIDE m_PinMapOverride
Per-instance pin-to-pad map override for this variant (issue #2282).
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,...
Per-instance override of the active pin map and a sparse delta on top.
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