20#include <magic_enum.hpp>
38#define LIB_VERSION_MAJOR 2
39#define LIB_VERSION_MINOR 4
41#define LIB_VERSION( major, minor ) ( major * 100 + minor )
44#define LIBFILE_IDENT "EESchema-LIBRARY Version"
47#define DOCFILE_IDENT "EESchema-DOCLIB Version 2.0"
55#define USE_OLD_DOC_FILE_FORMAT( major, minor ) \
56 ( LIB_VERSION( major, minor ) <= LIB_VERSION( 2, 4 ) )
79 wxString::Format(
"Cannot use relative file paths in legacy plugin to "
90 const char* line = reader.
Line();
92 if( !
strCompare(
"EESchema-LIBRARY Version", line, &line ) )
96 if( !
strCompare(
"EESchema-LIB Version", line, &line ) )
97 SCH_PARSE_ERROR(
"file is not a valid symbol or symbol library file", reader, line );
113 SCH_PARSE_ERROR(
"invalid file version formatting in header", reader, line );
120 if(
m_versionMajor < 1 || m_versionMinor < 0 || m_versionMinor > 99 )
139 line = reader.
Line();
141 if( *line ==
'#' || isspace( *line ) )
180 if( !fn.FileExists() )
183 if( !fn.IsFileReadable() )
185 THROW_IO_ERROR( wxString::Format(
_(
"Insufficient permissions to read library '%s'." ),
186 fn.GetFullPath() ) );
198 SCH_PARSE_ERROR(
"invalid document library file version formatting in header",
204 line = reader.
Line();
212 aliasName = wxString::FromUTF8( line );
215 LIB_SYMBOL_MAP::iterator it =
m_symbols.find( aliasName );
219 wxLogWarning(
"Symbol '%s' not found in library:\n\n"
220 "'%s'\n\nat line %d offset %d",
224 (
int) (line - reader.
Line() ) );
236 line = reader.
Line();
273 SCH_PARSE_ERROR(
"expected token in symbol definition", reader, line );
282 const char* line = aReader.
Line();
284 wxASSERT(
strCompare(
"$HEADER", line, &line ) );
288 line = (
char*) aReader;
294 else if(
strCompare(
"$ENDHEADER", line, &line ) )
305 const char* line = aReader.
Line();
307 while( *line ==
'#' )
315 wxString utf8Line = wxString::FromUTF8( line );
316 wxStringTokenizer tokens( utf8Line,
" \r\n\t" );
318 if( tokens.CountTokens() < 8 )
322 std::unique_ptr<LIB_SYMBOL> symbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
324 wxString
name, prefix, tmp;
326 name = tokens.GetNextToken();
333 pos +=
name.size() + 1;
335 prefix = tokens.GetNextToken();
336 pos += prefix.size() + 1;
338 tmp = tokens.GetNextToken();
339 pos += tmp.size() + 1;
341 tmp = tokens.GetNextToken();
343 if( !tmp.ToLong( &num ) )
349 pos += tmp.size() + 1;
352 tmp = tokens.GetNextToken();
354 if( !( tmp ==
"Y" || tmp ==
"N") )
358 pos += tmp.size() + 1;
359 symbol->SetShowPinNumbers( ( tmp ==
"N" ) ?
false :
true );
361 tmp = tokens.GetNextToken();
363 if( !( tmp ==
"Y" || tmp ==
"N") )
369 pos += tmp.size() + 1;
370 symbol->SetShowPinNames( ( tmp ==
"N" ) ?
false :
true );
372 tmp = tokens.GetNextToken();
374 if( !tmp.ToLong( &num ) )
380 pos += tmp.size() + 1;
381 symbol->SetUnitCount( (
int)num );
384 if( symbol->GetUnitCount() < 1 )
385 symbol->SetUnitCount( 1 );
392 symbol->SetName(
"~" );
394 else if(
name[0] !=
'~' )
396 symbol->SetName(
name );
400 symbol->SetName(
name.Right(
name.Length() - 1 ) );
401 symbol->GetValueField().SetVisible(
false );
405 symbol->SetLibId(
LIB_ID( wxEmptyString, symbol->GetName() ) );
407 SCH_FIELD& reference = symbol->GetReferenceField();
421 if(
LIB_VERSION( aMajorVersion, aMinorVersion ) > 0
426 tmp = tokens.GetNextToken();
427 pos += tmp.size() + 1;
431 tmp = tokens.GetNextToken();
434 symbol->LockUnits(
true );
435 else if( tmp ==
"F" || tmp ==
"0" )
436 symbol->LockUnits(
false );
441 pos += tmp.size() + 1;
445 if( tokens.HasMoreTokens() )
447 tmp = tokens.GetNextToken();
451 else if( tmp ==
"N" )
469 else if( *line ==
'F' )
473 else if(
strCompare(
"$FPLIST", line, &line ) )
475 else if(
strCompare(
"ENDDEF", line, &line ) )
477 return symbol.release();
491 wxString newAliasName;
492 const char* line = aReader.
Line();
494 wxCHECK_RET(
strCompare(
"ALIAS", line, &line ),
"Invalid ALIAS section" );
496 wxString utf8Line = wxString::FromUTF8( line );
497 wxStringTokenizer tokens( utf8Line,
" \r\n\t" );
500 while( tokens.HasMoreTokens() )
502 newAliasName = tokens.GetNextToken();
516 SCH_FIELD* parentField = aSymbol->GetFieldById( fieldId );
518 wxASSERT( parentField );
520 *field = *parentField;
523 field->
SetText( newAliasName );
531 (*aMap)[ newSymbol->
GetName() ] = newSymbol;
540 const char* line = aReader.
Line();
542 wxCHECK_RET( *line ==
'F',
"Invalid field line" );
547 if( sscanf( line + 1,
"%d", &
id ) != 1 ||
id < 0 )
556 field = aSymbol->GetFieldById(
id );
565 id = aSymbol->GetNextAvailableFieldId();
566 field =
new SCH_FIELD( aSymbol.get(),
id );
567 aSymbol->AddDrawItem( field,
false );
571 while( *line !=
'"' && *line != 0 )
586 if(
text.size() == 1 &&
text[0] ==
'~' )
587 field->
SetText( wxEmptyString );
602 char textOrient =
parseChar( aReader, line, &line );
604 if( textOrient ==
'H' )
606 else if( textOrient ==
'V' )
609 SCH_PARSE_ERROR(
"invalid field text orientation parameter", aReader, line );
611 char textVisible =
parseChar( aReader, line, &line );
613 if( textVisible ==
'V' )
615 else if ( textVisible ==
'I' )
618 SCH_PARSE_ERROR(
"invalid field text visibility parameter", aReader, line );
624 if( *line != 0 && *line !=
'"' )
626 char textHJustify =
parseChar( aReader, line, &line );
628 if( textHJustify ==
'C' )
630 else if( textHJustify ==
'L' )
632 else if( textHJustify ==
'R' )
635 SCH_PARSE_ERROR(
"invalid field text horizontal justification", aReader, line );
641 size_t attrSize = attributes.size();
643 if( !(attrSize == 3 || attrSize == 1 ) )
644 SCH_PARSE_ERROR(
"invalid field text attributes size", aReader, line );
646 switch( (wxChar) attributes[0] )
651 default:
SCH_PARSE_ERROR(
"invalid field text vertical justification", aReader, line );
656 wxChar attr_1 = attributes[1];
657 wxChar attr_2 = attributes[2];
661 else if( attr_1 !=
'N' )
662 SCH_PARSE_ERROR(
"invalid field text italic parameter", aReader, line );
666 else if( attr_2 !=
'N' )
682 field->
SetText( aSymbol->GetName() );
686 wxString fieldName = wxEmptyString;
689 if( fieldName.IsEmpty() )
692 wxString candidateFieldName = fieldName;
696 while( aSymbol->FindField( candidateFieldName ) !=
nullptr )
697 candidateFieldName = wxString::Format(
"%s_%d", fieldName, ++suffix );
699 field->
SetName( candidateFieldName );
709 const char* line = aReader.
Line();
711 wxCHECK_RET(
strCompare(
"DRAW", line, &line ),
"Invalid DRAW section" );
719 aSymbol->GetDrawItems().sort();
726 aSymbol->AddDrawItem(
loadArc( aReader ),
false );
730 aSymbol->AddDrawItem(
loadCircle( aReader ),
false );
734 aSymbol->AddDrawItem(
loadText( aReader, aMajorVersion, aMinorVersion ),
false );
738 aSymbol->AddDrawItem(
loadRect( aReader ),
false );
742 aSymbol->AddDrawItem(
loadPin( aSymbol, aReader ),
false );
750 aSymbol->AddDrawItem(
loadBezier( aReader ),
false );
766 SCH_PARSE_ERROR(
"File ended prematurely loading symbol draw element.", aReader, line );
771 const char** aOutput )
773 switch (
parseChar( aReader, aLine, aOutput ) )
775 case 'F':
return FILL_T::FILLED_SHAPE;
776 case 'f':
return FILL_T::FILLED_WITH_BG_BODYCOLOR;
777 case 'N':
return FILL_T::NO_FILL;
781 SCH_PARSE_ERROR(
"invalid fill type, expected f, F, or N", aReader, aLine );
791 auto DECIDEG2RAD = [](
double deg ) ->
double
793 return deg * M_PI / 1800.0;
800 delta = *aAngle2 - *aAngle1;
808 x = cos( DECIDEG2RAD( *aAngle1 ) );
809 y = -sin( DECIDEG2RAD( *aAngle1 ) );
812 x = cos( DECIDEG2RAD( *aAngle2 ) );
813 y = -sin( DECIDEG2RAD( *aAngle2 ) );
819 if( *aAngle2 < *aAngle1 )
822 if( *aAngle2 - *aAngle1 > 1800 )
824 angle = ( *aAngle1 );
825 *aAngle1 = ( *aAngle2 );
831 if( *aAngle2 < *aAngle1 )
849 const char* line = aReader.
Line();
851 wxCHECK_MSG(
strCompare(
"A", line, &line ),
nullptr,
"Invalid arc definition" );
863 int angle1 =
parseInt( aReader, line, &line );
864 int angle2 =
parseInt( aReader, line, &line );
930 const char* line = aReader.
Line();
932 wxCHECK_MSG(
strCompare(
"C", line, &line ),
nullptr,
"Invalid circle definition" );
961 int aMajorVersion,
int aMinorVersion )
963 const char* line = aReader.
Line();
965 wxCHECK_MSG(
strCompare(
"T", line, &line ),
nullptr,
"Invalid SCH_TEXT definition" );
967 double angleInTenths;
975 angleInTenths =
parseInt( aReader, line, &line );
980 visible = !
parseInt( aReader, line, &line );
981 unit =
parseInt( aReader, line, &line );
982 bodyStyle =
parseInt( aReader, line, &line );
996 str.Replace(
"~",
" " );
1002 str.Replace(
"''",
"\"" );
1007 text->SetTextSize( size );
1008 text->SetVisible( visible );
1009 text->SetUnit( unit );
1010 text->SetBodyStyle( bodyStyle );
1019 if(
LIB_VERSION( aMajorVersion, aMinorVersion ) > 0
1024 text->SetItalicFlag(
true );
1025 else if( !
strCompare(
"Normal", line, &line ) )
1026 SCH_PARSE_ERROR(
"invalid text stype, expected 'Normal' or 'Italic'", aReader, line );
1028 if(
parseInt( aReader, line, &line ) > 0 )
1029 text->SetBoldFlag(
true );
1034 switch(
parseChar( aReader, line, &line ) )
1039 default:
SCH_PARSE_ERROR(
"invalid horizontal text justication; expected L, C, or R",
1043 switch(
parseChar( aReader, line, &line ) )
1048 default:
SCH_PARSE_ERROR(
"invalid vertical text justication; expected T, C, or B",
1060 const char* line = aReader.
Line();
1062 wxCHECK_MSG(
strCompare(
"S", line, &line ),
nullptr,
"Invalid rectangle definition" );
1082 LINE_STYLE::SOLID );
1097 const char* line = aReader.
Line();
1099 wxCHECK_MSG(
strCompare(
"X", line, &line ),
nullptr,
"Invalid SCH_PIN definition" );
1106 wxString utf8Line = wxString::FromUTF8( line );
1107 wxStringTokenizer tokens( utf8Line,
" \r\n\t" );
1109 if( tokens.CountTokens() < 11 )
1112 tmp = tokens.GetNextToken();
1114 pos += tmp.size() + 1;
1116 tmp = tokens.GetNextToken();
1118 pos += tmp.size() + 1;
1123 tmp = tokens.GetNextToken();
1125 if( !tmp.ToLong( &num ) )
1131 pos += tmp.size() + 1;
1134 tmp = tokens.GetNextToken();
1136 if( !tmp.ToLong( &num ) )
1142 pos += tmp.size() + 1;
1145 tmp = tokens.GetNextToken();
1147 if( !tmp.ToLong( &num ) )
1153 pos += tmp.size() + 1;
1157 tmp = tokens.GetNextToken();
1159 if( tmp.size() > 1 )
1165 pos += tmp.size() + 1;
1169 switch(
static_cast<char>( tmp[0] ) )
1171 case 'U': orientation = PIN_ORIENTATION::PIN_UP;
break;
1172 case 'D': orientation = PIN_ORIENTATION::PIN_DOWN;
break;
1173 case 'L': orientation = PIN_ORIENTATION::PIN_LEFT;
break;
1175 default: orientation = PIN_ORIENTATION::PIN_RIGHT;
break;
1178 tmp = tokens.GetNextToken();
1180 if( !tmp.ToLong( &num ) )
1186 pos += tmp.size() + 1;
1189 tmp = tokens.GetNextToken();
1191 if( !tmp.ToLong( &num ) )
1197 pos += tmp.size() + 1;
1200 tmp = tokens.GetNextToken();
1202 if( !tmp.ToLong( &num ) )
1208 pos += tmp.size() + 1;
1209 int unit = (int) num;
1211 tmp = tokens.GetNextToken();
1213 if( !tmp.ToLong( &num ) )
1219 pos += tmp.size() + 1;
1222 tmp = tokens.GetNextToken();
1224 if( tmp.size() != 1 )
1230 pos += tmp.size() + 1;
1236 case 'I': pinType = ELECTRICAL_PINTYPE::PT_INPUT;
break;
1237 case 'O': pinType = ELECTRICAL_PINTYPE::PT_OUTPUT;
break;
1238 case 'B': pinType = ELECTRICAL_PINTYPE::PT_BIDI;
break;
1239 case 'T': pinType = ELECTRICAL_PINTYPE::PT_TRISTATE;
break;
1240 case 'P': pinType = ELECTRICAL_PINTYPE::PT_PASSIVE;
break;
1241 case 'U': pinType = ELECTRICAL_PINTYPE::PT_UNSPECIFIED;
break;
1242 case 'W': pinType = ELECTRICAL_PINTYPE::PT_POWER_IN;
break;
1243 case 'w': pinType = ELECTRICAL_PINTYPE::PT_POWER_OUT;
break;
1244 case 'C': pinType = ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR;
break;
1245 case 'E': pinType = ELECTRICAL_PINTYPE::PT_OPENEMITTER;
break;
1246 case 'N': pinType = ELECTRICAL_PINTYPE::PT_NC;
break;
1265 if( tokens.HasMoreTokens() )
1267 tmp = tokens.GetNextToken();
1273 LOWLEVEL_IN = 1 << 2,
1274 LOWLEVEL_OUT = 1 << 3,
1275 FALLING_EDGE = 1 << 4,
1281 for(
int j = (
int) tmp.size(); j > 0; )
1283 switch( tmp[--j].GetValue() )
1286 case 'N':
pin->SetVisible(
false );
break;
1287 case 'I': flags |=
INVERTED;
break;
1288 case 'C': flags |=
CLOCK;
break;
1289 case 'L': flags |= LOWLEVEL_IN;
break;
1290 case 'V': flags |= LOWLEVEL_OUT;
break;
1291 case 'F': flags |= FALLING_EDGE;
break;
1292 case 'X': flags |=
NONLOGIC;
break;
1302 case 0:
pin->SetShape( GRAPHIC_PINSHAPE::LINE );
break;
1303 case INVERTED:
pin->SetShape( GRAPHIC_PINSHAPE::INVERTED );
break;
1304 case CLOCK:
pin->SetShape( GRAPHIC_PINSHAPE::CLOCK );
break;
1305 case INVERTED |
CLOCK:
pin->SetShape( GRAPHIC_PINSHAPE::INVERTED_CLOCK );
break;
1306 case LOWLEVEL_IN:
pin->SetShape( GRAPHIC_PINSHAPE::INPUT_LOW );
break;
1307 case LOWLEVEL_IN |
CLOCK:
pin->SetShape( GRAPHIC_PINSHAPE::CLOCK_LOW );
break;
1308 case LOWLEVEL_OUT:
pin->SetShape( GRAPHIC_PINSHAPE::OUTPUT_LOW );
break;
1309 case FALLING_EDGE:
pin->SetShape( GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK );
break;
1310 case NONLOGIC:
pin->SetShape( GRAPHIC_PINSHAPE::NONLOGIC );
break;
1312 SCH_PARSE_ERROR(
"pin attributes do not define a valid pin shape", aReader, line );
1322 const char* line = aReader.
Line();
1324 wxCHECK_MSG(
strCompare(
"P", line, &line ),
nullptr,
"Invalid poly definition" );
1328 int points =
parseInt( aReader, line, &line );
1333 LINE_STYLE::SOLID );
1339 for(
int i = 0; i < points; i++ )
1355 const char* line = aReader.
Line();
1357 wxCHECK_MSG(
strCompare(
"B", line, &line ),
nullptr,
"Invalid Bezier definition" );
1359 int points =
parseInt( aReader, line, &line );
1361 wxCHECK_MSG( points == 4, NULL,
"Invalid Bezier curve definition" );
1369 LINE_STYLE::SOLID );
1403 const char* line = aReader.
Line();
1405 wxCHECK_RET(
strCompare(
"$FPLIST", line, &line ),
"Invalid footprint filter list" );
1409 wxArrayString footprintFilters;
1413 if(
strCompare(
"$ENDFPLIST", line, &line ) )
1415 aSymbol->SetFPFilters( footprintFilters );
1422 footprintFilters.Add( footprint );
1426 SCH_PARSE_ERROR(
"File ended prematurely while loading footprint filters.", aReader, line );
1434 bool doSaveDocFile = *aOpt;
1442 auto formatter = std::make_unique<FILE_OUTPUTFORMATTER>( fn.GetFullPath() );
1444 formatter->Print( 0,
"#encoding utf-8\n");
1448 if( !it->second->IsRoot() )
1454 formatter->Print( 0,
"#\n#End Library\n" );
1474 wxCHECK_RET( aSymbol && aSymbol->
IsRoot(),
"Invalid LIB_SYMBOL pointer." );
1478 wxArrayString aliasNames;
1482 for(
auto& entry : *aMap )
1487 aliasNames.Add( symbol->
GetName() );
1497 aFormatter.
Print( 0,
"DEF" );
1502 if( !reference.
GetText().IsEmpty() )
1505 aFormatter.
Print( 0,
" ~" );
1507 aFormatter.
Print( 0,
" %d %d %c %c %d %c %c\n",
1512 aSymbol->
IsPower() ?
'P' :
'N' );
1516 if( dateModified != 0 )
1518 int sec = dateModified & 63;
1519 int min = ( dateModified >> 6 ) & 63;
1520 int hour = ( dateModified >> 12 ) & 31;
1521 int day = ( dateModified >> 17 ) & 31;
1522 int mon = ( dateModified >> 22 ) & 15;
1523 int year = ( dateModified >> 26 ) + 1990;
1525 aFormatter.
Print( 0,
"Ti %d/%d/%d %d:%d:%d\n", year, mon, day, hour, min, sec );
1528 std::vector<SCH_FIELD*> fields;
1537 if( field->IsMandatory() )
1547 if( field->IsMandatory() )
1553 if( !field->GetText().IsEmpty() )
1555 field->SetId( fieldId++ );
1561 if( !aliasNames.IsEmpty() )
1563 aFormatter.
Print( 0,
"ALIAS" );
1565 for(
unsigned i = 0; i < aliasNames.GetCount(); i++ )
1566 aFormatter.
Print( 0,
" %s",
TO_UTF8( aliasNames[i] ) );
1568 aFormatter.
Print( 0,
"\n" );
1574 if( footprints.GetCount() != 0 )
1576 aFormatter.
Print( 0,
"$FPLIST\n" );
1578 for(
unsigned i = 0; i < footprints.GetCount(); i++ )
1579 aFormatter.
Print( 0,
" %s\n",
TO_UTF8( footprints[i] ) );
1581 aFormatter.
Print( 0,
"$ENDFPLIST\n" );
1590 aFormatter.
Print( 0,
"DRAW\n" );
1594 switch( item.Type() )
1610 case SHAPE_T::ARC:
saveArc( &shape, aFormatter );
break;
1611 case SHAPE_T::BEZIER:
saveBezier( &shape, aFormatter );
break;
1612 case SHAPE_T::CIRCLE:
saveCircle( &shape, aFormatter );
break;
1613 case SHAPE_T::POLY:
savePolyLine( &shape, aFormatter );
break;
1614 case SHAPE_T::RECTANGLE:
saveRectangle( &shape, aFormatter );
break;
1626 aFormatter.
Print( 0,
"ENDDRAW\n" );
1629 aFormatter.
Print( 0,
"ENDDEF\n" );
1635 wxCHECK_RET( aArc && aArc->
GetShape() == SHAPE_T::ARC,
"Invalid ARC object." );
1643 aFormatter.
Print( 0,
"A %d %d %d %d %d %d %d %d %c %d %d %d %d\n",
1662 wxCHECK_RET( aBezier && aBezier->
GetShape() == SHAPE_T::BEZIER,
"Invalid BEZIER object." );
1664 aFormatter.
Print( 0,
"B 4 %d %d %d",
1669 aFormatter.
Print( 0,
" %d %d %d %d %d %d %d %d",
1685 wxCHECK_RET( aCircle && aCircle->
GetShape() == SHAPE_T::CIRCLE,
"Invalid CIRCLE object." );
1687 aFormatter.
Print( 0,
"C %d %d %d %d %d %d %c\n",
1701 wxCHECK_RET( aField && aField->
Type() ==
SCH_FIELD_T,
"Invalid SCH_FIELD object." );
1703 int hjustify, vjustify;
1704 int id = aField->
GetId();
1721 aFormatter.
Print( 0,
"F%d %s %d %d %d %c %c %c %c%c%c",
1731 aField->
IsBold() ?
'B' :
'N' );
1736 && !aField->
GetName().IsEmpty()
1742 aFormatter.
Print( 0,
"\n" );
1748 wxCHECK_RET( aPin && aPin->
Type() ==
SCH_PIN_T,
"Invalid SCH_PIN object." );
1755 case ELECTRICAL_PINTYPE::PT_INPUT: Etype =
'I';
break;
1756 case ELECTRICAL_PINTYPE::PT_OUTPUT: Etype =
'O';
break;
1757 case ELECTRICAL_PINTYPE::PT_BIDI: Etype =
'B';
break;
1758 case ELECTRICAL_PINTYPE::PT_TRISTATE: Etype =
'T';
break;
1759 case ELECTRICAL_PINTYPE::PT_PASSIVE: Etype =
'P';
break;
1760 case ELECTRICAL_PINTYPE::PT_UNSPECIFIED: Etype =
'U';
break;
1761 case ELECTRICAL_PINTYPE::PT_POWER_IN: Etype =
'W';
break;
1762 case ELECTRICAL_PINTYPE::PT_POWER_OUT: Etype =
'w';
break;
1763 case ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR: Etype =
'C';
break;
1764 case ELECTRICAL_PINTYPE::PT_OPENEMITTER: Etype =
'E';
break;
1765 case ELECTRICAL_PINTYPE::PT_NC: Etype =
'N';
break;
1768 if( !aPin->
GetName().IsEmpty() )
1771 aFormatter.
Print( 0,
"X ~" );
1773 int pin_orient =
'L';
1777 case PIN_ORIENTATION::PIN_RIGHT: pin_orient =
'R';
break;
1778 case PIN_ORIENTATION::PIN_LEFT: pin_orient =
'L';
break;
1779 case PIN_ORIENTATION::PIN_UP: pin_orient =
'U';
break;
1780 case PIN_ORIENTATION::PIN_DOWN: pin_orient =
'D';
break;
1781 case PIN_ORIENTATION::INHERIT: pin_orient =
'L';
break;
1784 aFormatter.
Print( 0,
" %s %d %d %d %c %d %d %d %d %c",
1797 aFormatter.
Print( 0,
" " );
1800 aFormatter.
Print( 0,
"N" );
1804 case GRAPHIC_PINSHAPE::LINE:
break;
1805 case GRAPHIC_PINSHAPE::INVERTED: aFormatter.
Print( 0,
"I" );
break;
1806 case GRAPHIC_PINSHAPE::CLOCK: aFormatter.
Print( 0,
"C" );
break;
1807 case GRAPHIC_PINSHAPE::INVERTED_CLOCK: aFormatter.
Print( 0,
"IC" );
break;
1808 case GRAPHIC_PINSHAPE::INPUT_LOW: aFormatter.
Print( 0,
"L" );
break;
1809 case GRAPHIC_PINSHAPE::CLOCK_LOW: aFormatter.
Print( 0,
"CL" );
break;
1810 case GRAPHIC_PINSHAPE::OUTPUT_LOW: aFormatter.
Print( 0,
"V" );
break;
1811 case GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK: aFormatter.
Print( 0,
"F" );
break;
1812 case GRAPHIC_PINSHAPE::NONLOGIC: aFormatter.
Print( 0,
"X" );
break;
1813 default: wxFAIL_MSG(
"Invalid pin shape" );
1816 aFormatter.
Print( 0,
"\n" );
1825 wxCHECK_RET( aPolyLine && aPolyLine->
GetShape() == SHAPE_T::POLY,
"Invalid POLY object." );
1827 aFormatter.
Print( 0,
"P %d %d %d %d",
1843 wxCHECK_RET( aRectangle && aRectangle->
GetShape() == SHAPE_T::RECTANGLE,
1844 "Invalid RECT object." );
1846 aFormatter.
Print( 0,
"S %d %d %d %d %d %d %d %c\n",
1860 wxCHECK_RET( aText && aText->
Type() ==
SCH_TEXT_T,
"Invalid SCH_TEXT object." );
1864 if(
text.Contains( wxT(
" " ) ) ||
text.Contains( wxT(
"~" ) ) ||
text.Contains( wxT(
"\"" ) ) )
1867 text.Replace( wxT(
"\"" ), wxT(
"''" ) );
1868 text = wxT(
"\"" ) +
text + wxT(
"\"" );
1871 aFormatter.
Print( 0,
"T %g %d %d %d %d %d %d %s",
1881 aFormatter.
Print( 0,
" %s %d", aText->
IsItalic() ?
"Italic" :
"Normal", aText->
IsBold() );
1883 char hjustify =
'C';
1890 char vjustify =
'C';
1897 aFormatter.
Print( 0,
" %c %c\n", hjustify, vjustify );
1918 wxString description = it->second->GetDescription();
1919 wxString keyWords = it->second->GetKeyWords();
1920 wxString docFileName = it->second->GetDatasheetField().GetText();
1922 if( description.IsEmpty() && keyWords.IsEmpty() && docFileName.IsEmpty() )
1925 formatter.
Print( 0,
"#\n$CMP %s\n",
TO_UTF8( it->second->GetName() ) );
1927 if( !description.IsEmpty() )
1928 formatter.
Print( 0,
"D %s\n",
TO_UTF8( description ) );
1930 if( !keyWords.IsEmpty() )
1933 if( !docFileName.IsEmpty() )
1934 formatter.
Print( 0,
"F %s\n",
TO_UTF8( docFileName ) );
1936 formatter.
Print( 0,
"$ENDCMP\n" );
1939 formatter.
Print( 0,
"#\n#End Doc Library\n" );
1945 LIB_SYMBOL_MAP::iterator it =
m_symbols.find( aSymbolName );
1948 THROW_IO_ERROR( wxString::Format(
_(
"library %s does not contain a symbol named %s" ),
1960 LIB_SYMBOL_MAP::iterator it1 =
m_symbols.begin();
1964 if( it1->second->IsAlias()
1965 && it1->second->GetParent().lock() == rootSymbol->
SharedPtr() )
constexpr EDA_IU_SCALE schIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
int AsTenthsOfADegree() const
bool IsHorizontal() const
KICAD_T Type() const
Returns the type of object.
virtual void SetParent(EDA_ITEM *aParent)
const VECTOR2I & GetBezierC2() const
void SetBezierC2(const VECTOR2I &aPt)
FILL_T GetFillMode() const
SHAPE_POLY_SET & GetPolyShape()
void CalcArcAngles(EDA_ANGLE &aStartAngle, EDA_ANGLE &aEndAngle) const
Calc arc start and end angles such that aStartAngle < aEndAngle.
void RebuildBezierToSegmentsPointsList(int aMaxError)
Rebuild the m_bezierPoints vertex list that approximate the Bezier curve by a list of segments.
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
void SetStart(const VECTOR2I &aStart)
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
void SetEnd(const VECTOR2I &aEnd)
void SetBezierC1(const VECTOR2I &aPt)
const VECTOR2I & GetBezierC1() const
virtual int GetWidth() const
void SetFillMode(FILL_T aFill)
const VECTOR2I & GetTextPos() const
const EDA_ANGLE & GetTextAngle() const
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
virtual const wxString & GetText() const
Return the string associated with the text object.
virtual bool IsVisible() const
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
GR_TEXT_H_ALIGN_T GetHorizJustify() const
void SetBoldFlag(bool aBold)
Set only the italic flag, without changing the font.
virtual void SetVisible(bool aVisible)
void SetItalicFlag(bool aItalic)
Set only the italic flag, without changing the font.
GR_TEXT_V_ALIGN_T GetVertJustify() const
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
A LINE_READER that reads from an open file.
char * ReadLine() override
Read a line of text into the buffer and increments the line number counter.
A logical library item identifier and consists of various portions much like a URI.
Define a library symbol object.
bool IsPower() const override
bool UnitsLocked() const
Check whether symbol units are interchangeable.
bool IsRoot() const override
For symbols derived from other symbols, IsRoot() indicates no derivation.
SCH_FIELD & GetValueField() const
Return reference to the value field.
timestamp_t GetLastModDate() const
SCH_FIELD * GetFieldById(int aId) const
Return pointer to the requested field.
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
void SetParent(LIB_SYMBOL *aParent=nullptr)
wxString GetName() const override
void SetDescription(const wxString &aDescription)
Gets the Description field text value */.
void GetFields(std::vector< SCH_FIELD * > &aList, bool aVisibleOnly=false) override
Return a list of fields within this symbol.
void SetKeyWords(const wxString &aKeyWords)
SCH_FIELD & GetReferenceField() const
Return reference to the reference designator field.
wxArrayString GetFPFilters() const
LIB_SYMBOL_SPTR SharedPtr() const
int GetUnitCount() const override
LIB_SYMBOL_REF & GetParent()
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
virtual char * ReadLine()=0
Read a line of text into the buffer and increments the line number counter.
virtual const wxString & GetSource() const
Returns the name of the source of the lines in an abstract sense.
virtual unsigned LineNumber() const
Return the line number of the last line read from this LINE_READER.
char * Line() const
Return a pointer to the last line that was read in.
bool empty(int aType=UNDEFINED_TYPE) const
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
void SetPosition(const VECTOR2I &aPosition) override
void SetName(const wxString &aName)
void SetText(const wxString &aText) override
SCH_IO_KICAD_LEGACY_LIB_CACHE(const wxString &aLibraryPath)
static void loadDrawEntries(std::unique_ptr< LIB_SYMBOL > &aSymbol, LINE_READER &aReader, int aMajorVersion, int aMinorVersion)
void loadHeader(FILE_LINE_READER &aReader)
static SCH_SHAPE * loadBezier(LINE_READER &aReader)
static void saveArc(SCH_SHAPE *aArc, OUTPUTFORMATTER &aFormatter)
static void saveCircle(SCH_SHAPE *aCircle, OUTPUTFORMATTER &aFormatter)
static SCH_SHAPE * loadArc(LINE_READER &aReader)
static void loadField(std::unique_ptr< LIB_SYMBOL > &aSymbol, LINE_READER &aReader)
static void saveField(const SCH_FIELD *aField, OUTPUTFORMATTER &aFormatter)
static LIB_SYMBOL * LoadPart(LINE_READER &aReader, int aMajorVersion, int aMinorVersion, LIB_SYMBOL_MAP *aMap=nullptr)
static void savePolyLine(SCH_SHAPE *aPolyLine, OUTPUTFORMATTER &aFormatter)
static SCH_SHAPE * loadPolyLine(LINE_READER &aReader)
static void saveBezier(SCH_SHAPE *aBezier, OUTPUTFORMATTER &aFormatter)
static SCH_SHAPE * loadCircle(LINE_READER &aReader)
void Save(const std::optional< bool > &aOpt) override
Save the entire library to file m_libFileName;.
static SCH_SHAPE * loadRect(LINE_READER &aReader)
static void loadAliases(std::unique_ptr< LIB_SYMBOL > &aSymbol, LINE_READER &aReader, LIB_SYMBOL_MAP *aMap=nullptr)
static void loadFootprintFilters(std::unique_ptr< LIB_SYMBOL > &aSymbol, LINE_READER &aReader)
static SCH_TEXT * loadText(LINE_READER &aReader, int aMajorVersion, int aMinorVersion)
void DeleteSymbol(const wxString &aName) override
static void savePin(const SCH_PIN *aPin, OUTPUTFORMATTER &aFormatter)
static SCH_PIN * loadPin(std::unique_ptr< LIB_SYMBOL > &aSymbol, LINE_READER &aReader)
static FILL_T parseFillMode(LINE_READER &aReader, const char *aLine, const char **aOutput)
static void saveRectangle(SCH_SHAPE *aRectangle, OUTPUTFORMATTER &aFormatter)
static void SaveSymbol(LIB_SYMBOL *aSymbol, OUTPUTFORMATTER &aFormatter, LIB_SYMBOL_MAP *aMap=nullptr)
static void saveText(const SCH_TEXT *aText, OUTPUTFORMATTER &aFormatter)
A base cache assistant implementation for the symbol library portion of the SCH_IO API.
wxDateTime GetLibModificationTime()
wxFileName GetRealFile() const
void IncrementModifyHash()
Base class for any item which can be embedded within the SCHEMATIC container class,...
virtual void SetBodyStyle(int aBodyStyle)
virtual void SetUnit(int aUnit)
int GetNumberTextSize() const
const wxString & GetName() const
PIN_ORIENTATION GetOrientation() const
VECTOR2I GetPosition() const override
int GetNameTextSize() const
const wxString & GetNumber() const
GRAPHIC_PINSHAPE GetShape() const
ELECTRICAL_PINTYPE GetType() const
void SetPosition(const VECTOR2I &aPos) override
void SetStroke(const STROKE_PARAMS &aStroke) override
VECTOR2I GetCenter() const
void AddPoint(const VECTOR2I &aPosition)
VECTOR2I GetPosition() const override
virtual size_t GetPointCount() const override
const std::vector< VECTOR2I > & CPoints() const
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
Simple container to manage line stroke parameters.
int GetPinNameOffset() const
virtual bool GetShowPinNames() const
virtual bool GetShowPinNumbers() const
static constexpr EDA_ANGLE ANGLE_VERTICAL
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
#define IS_CHANGED
Item was edited, and modified.
static const std::string LegacySymbolDocumentFileExtension
const wxChar *const traceSchLegacyPlugin
Flag to enable legacy schematic plugin debug output.
std::chrono::steady_clock CLOCK
#define THROW_IO_ERROR(msg)
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
uint32_t timestamp_t
timestamp_t is our type to represent unique IDs for all kinds of elements; historically simply the ti...
This file contains miscellaneous commonly used macros and functions.
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
PIN_ORIENTATION
The symbol library pin object orientations.
int parseInt(LINE_READER &aReader, const char *aLine, const char **aOutput)
Parse an ASCII integer string with possible leading whitespace into an integer and updates the pointe...
bool strCompare(const char *aString, const char *aLine, const char **aOutput)
Compare aString to the string starting at aLine and advances the character point to the end of String...
void parseQuotedString(wxString &aString, LINE_READER &aReader, const char *aCurrentToken, const char **aNextToken, bool aCanBeEmpty)
Parse an quoted ASCII utf8 and updates the pointer at aOutput if it is not NULL.
void parseUnquotedString(wxString &aString, LINE_READER &aReader, const char *aCurrentToken, const char **aNextToken, bool aCanBeEmpty)
Parse an unquoted utf8 string and updates the pointer at aOutput if it is not NULL.
char parseChar(LINE_READER &aReader, const char *aCurrentToken, const char **aNextToken)
Parse a single ASCII character and updates the pointer at aOutput if it is not NULL.
#define SCH_PARSE_ERROR(text, reader, pos)
static bool MapAnglesV6(int *aAngle1, int *aAngle2)
This function based on version 6.0 is required for reading legacy arcs.
#define LIB_VERSION_MINOR
Legacy symbol library minor version.
#define LIBFILE_IDENT
Legacy symbol library (.lib) file header.
#define USE_OLD_DOC_FILE_FORMAT(major, minor)
Library versions 2.4 and lower use the old separate library (.lib) and document (....
#define LIB_VERSION(major, minor)
#define DOCFILE_IDENT
Legacy symbol library document (.dcm) file header.
#define LIB_VERSION_MAJOR
Legacy symbol library major version.
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)
std::string EscapedUTF8(const wxString &aString)
Return an 8 bit UTF8 string given aString in Unicode form.
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
constexpr int IUToMils(int iu) const
constexpr int MilsToIU(int mils) const
std::map< wxString, LIB_SYMBOL *, LibSymbolMapSort > LIB_SYMBOL_MAP
wxString GetUserFieldName(int aFieldNdx, bool aTranslateForHI)
wxString GetCanonicalFieldName(int idx)
@ DATASHEET_FIELD
name of datasheet
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ MANDATORY_FIELD_COUNT
The first 5 are mandatory, and must be instantiated in SCH_COMPONENT, LIB_PART, and FOOTPRINT constru...
@ DESCRIPTION_FIELD
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
wxLogTrace helper definitions.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
void NORMALIZE_ANGLE_POS(T &Angle)
double RAD2DECIDEG(double rad)
VECTOR2< int32_t > VECTOR2I
Definition of file extensions used in Kicad.