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(
"''",
"\"" );
1017 sch_item = sch_text;
1018 eda_text = sch_text;
1034 if(
LIB_VERSION( aMajorVersion, aMinorVersion ) > 0
1040 else if( !
strCompare(
"Normal", line, &line ) )
1041 SCH_PARSE_ERROR(
"invalid eda_text stype, expected 'Normal' or 'Italic'", aReader, line );
1043 if(
parseInt( aReader, line, &line ) > 0 )
1049 switch(
parseChar( aReader, line, &line ) )
1054 default:
SCH_PARSE_ERROR(
"invalid horizontal eda_text justication; expected L, C, or R",
1058 switch(
parseChar( aReader, line, &line ) )
1063 default:
SCH_PARSE_ERROR(
"invalid vertical eda_text justication; expected T, C, or B",
1075 const char* line = aReader.
Line();
1077 wxCHECK_MSG(
strCompare(
"S", line, &line ),
nullptr,
"Invalid rectangle definition" );
1097 LINE_STYLE::SOLID );
1112 const char* line = aReader.
Line();
1114 wxCHECK_MSG(
strCompare(
"X", line, &line ),
nullptr,
"Invalid SCH_PIN definition" );
1121 wxString utf8Line = wxString::FromUTF8( line );
1122 wxStringTokenizer tokens( utf8Line,
" \r\n\t" );
1124 if( tokens.CountTokens() < 11 )
1127 tmp = tokens.GetNextToken();
1129 pos += tmp.size() + 1;
1131 tmp = tokens.GetNextToken();
1133 pos += tmp.size() + 1;
1138 tmp = tokens.GetNextToken();
1140 if( !tmp.ToLong( &num ) )
1146 pos += tmp.size() + 1;
1149 tmp = tokens.GetNextToken();
1151 if( !tmp.ToLong( &num ) )
1157 pos += tmp.size() + 1;
1160 tmp = tokens.GetNextToken();
1162 if( !tmp.ToLong( &num ) )
1168 pos += tmp.size() + 1;
1172 tmp = tokens.GetNextToken();
1174 if( tmp.size() > 1 )
1180 pos += tmp.size() + 1;
1184 switch(
static_cast<char>( tmp[0] ) )
1186 case 'U': orientation = PIN_ORIENTATION::PIN_UP;
break;
1187 case 'D': orientation = PIN_ORIENTATION::PIN_DOWN;
break;
1188 case 'L': orientation = PIN_ORIENTATION::PIN_LEFT;
break;
1190 default: orientation = PIN_ORIENTATION::PIN_RIGHT;
break;
1193 tmp = tokens.GetNextToken();
1195 if( !tmp.ToLong( &num ) )
1201 pos += tmp.size() + 1;
1204 tmp = tokens.GetNextToken();
1206 if( !tmp.ToLong( &num ) )
1212 pos += tmp.size() + 1;
1215 tmp = tokens.GetNextToken();
1217 if( !tmp.ToLong( &num ) )
1223 pos += tmp.size() + 1;
1224 int unit = (int) num;
1226 tmp = tokens.GetNextToken();
1228 if( !tmp.ToLong( &num ) )
1234 pos += tmp.size() + 1;
1237 tmp = tokens.GetNextToken();
1239 if( tmp.size() != 1 )
1245 pos += tmp.size() + 1;
1251 case 'I': pinType = ELECTRICAL_PINTYPE::PT_INPUT;
break;
1252 case 'O': pinType = ELECTRICAL_PINTYPE::PT_OUTPUT;
break;
1253 case 'B': pinType = ELECTRICAL_PINTYPE::PT_BIDI;
break;
1254 case 'T': pinType = ELECTRICAL_PINTYPE::PT_TRISTATE;
break;
1255 case 'P': pinType = ELECTRICAL_PINTYPE::PT_PASSIVE;
break;
1256 case 'U': pinType = ELECTRICAL_PINTYPE::PT_UNSPECIFIED;
break;
1257 case 'W': pinType = ELECTRICAL_PINTYPE::PT_POWER_IN;
break;
1258 case 'w': pinType = ELECTRICAL_PINTYPE::PT_POWER_OUT;
break;
1259 case 'C': pinType = ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR;
break;
1260 case 'E': pinType = ELECTRICAL_PINTYPE::PT_OPENEMITTER;
break;
1261 case 'N': pinType = ELECTRICAL_PINTYPE::PT_NC;
break;
1280 if( tokens.HasMoreTokens() )
1282 tmp = tokens.GetNextToken();
1288 LOWLEVEL_IN = 1 << 2,
1289 LOWLEVEL_OUT = 1 << 3,
1290 FALLING_EDGE = 1 << 4,
1296 for(
int j = (
int) tmp.size(); j > 0; )
1298 switch( tmp[--j].GetValue() )
1301 case 'N':
pin->SetVisible(
false );
break;
1302 case 'I': flags |=
INVERTED;
break;
1303 case 'C': flags |=
CLOCK;
break;
1304 case 'L': flags |= LOWLEVEL_IN;
break;
1305 case 'V': flags |= LOWLEVEL_OUT;
break;
1306 case 'F': flags |= FALLING_EDGE;
break;
1307 case 'X': flags |=
NONLOGIC;
break;
1317 case 0:
pin->SetShape( GRAPHIC_PINSHAPE::LINE );
break;
1318 case INVERTED:
pin->SetShape( GRAPHIC_PINSHAPE::INVERTED );
break;
1319 case CLOCK:
pin->SetShape( GRAPHIC_PINSHAPE::CLOCK );
break;
1320 case INVERTED |
CLOCK:
pin->SetShape( GRAPHIC_PINSHAPE::INVERTED_CLOCK );
break;
1321 case LOWLEVEL_IN:
pin->SetShape( GRAPHIC_PINSHAPE::INPUT_LOW );
break;
1322 case LOWLEVEL_IN |
CLOCK:
pin->SetShape( GRAPHIC_PINSHAPE::CLOCK_LOW );
break;
1323 case LOWLEVEL_OUT:
pin->SetShape( GRAPHIC_PINSHAPE::OUTPUT_LOW );
break;
1324 case FALLING_EDGE:
pin->SetShape( GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK );
break;
1325 case NONLOGIC:
pin->SetShape( GRAPHIC_PINSHAPE::NONLOGIC );
break;
1327 SCH_PARSE_ERROR(
"pin attributes do not define a valid pin shape", aReader, line );
1337 const char* line = aReader.
Line();
1339 wxCHECK_MSG(
strCompare(
"P", line, &line ),
nullptr,
"Invalid poly definition" );
1343 int points =
parseInt( aReader, line, &line );
1348 LINE_STYLE::SOLID );
1354 for(
int i = 0; i < points; i++ )
1370 const char* line = aReader.
Line();
1372 wxCHECK_MSG(
strCompare(
"B", line, &line ),
nullptr,
"Invalid Bezier definition" );
1374 int points =
parseInt( aReader, line, &line );
1376 wxCHECK_MSG( points == 4, NULL,
"Invalid Bezier curve definition" );
1384 LINE_STYLE::SOLID );
1418 const char* line = aReader.
Line();
1420 wxCHECK_RET(
strCompare(
"$FPLIST", line, &line ),
"Invalid footprint filter list" );
1424 wxArrayString footprintFilters;
1428 if(
strCompare(
"$ENDFPLIST", line, &line ) )
1430 aSymbol->SetFPFilters( footprintFilters );
1437 footprintFilters.Add( footprint );
1441 SCH_PARSE_ERROR(
"File ended prematurely while loading footprint filters.", aReader, line );
1449 bool doSaveDocFile = *aOpt;
1457 auto formatter = std::make_unique<FILE_OUTPUTFORMATTER>( fn.GetFullPath() );
1459 formatter->Print( 0,
"#encoding utf-8\n");
1463 if( !it->second->IsRoot() )
1469 formatter->Print( 0,
"#\n#End Library\n" );
1489 wxCHECK_RET( aSymbol && aSymbol->
IsRoot(),
"Invalid LIB_SYMBOL pointer." );
1493 wxArrayString aliasNames;
1497 for(
auto& entry : *aMap )
1502 aliasNames.Add( symbol->
GetName() );
1512 aFormatter.
Print( 0,
"DEF" );
1517 if( !reference.
GetText().IsEmpty() )
1520 aFormatter.
Print( 0,
" ~" );
1522 aFormatter.
Print( 0,
" %d %d %c %c %d %c %c\n",
1527 aSymbol->
IsPower() ?
'P' :
'N' );
1531 if( dateModified != 0 )
1533 int sec = dateModified & 63;
1534 int min = ( dateModified >> 6 ) & 63;
1535 int hour = ( dateModified >> 12 ) & 31;
1536 int day = ( dateModified >> 17 ) & 31;
1537 int mon = ( dateModified >> 22 ) & 15;
1538 int year = ( dateModified >> 26 ) + 1990;
1540 aFormatter.
Print( 0,
"Ti %d/%d/%d %d:%d:%d\n", year, mon, day, hour, min, sec );
1543 std::vector<SCH_FIELD*> fields;
1552 if( field->IsMandatory() )
1562 if( field->IsMandatory() )
1568 if( !field->GetText().IsEmpty() )
1570 field->SetId( fieldId++ );
1576 if( !aliasNames.IsEmpty() )
1578 aFormatter.
Print( 0,
"ALIAS" );
1580 for(
unsigned i = 0; i < aliasNames.GetCount(); i++ )
1581 aFormatter.
Print( 0,
" %s",
TO_UTF8( aliasNames[i] ) );
1583 aFormatter.
Print( 0,
"\n" );
1589 if( footprints.GetCount() != 0 )
1591 aFormatter.
Print( 0,
"$FPLIST\n" );
1593 for(
unsigned i = 0; i < footprints.GetCount(); i++ )
1594 aFormatter.
Print( 0,
" %s\n",
TO_UTF8( footprints[i] ) );
1596 aFormatter.
Print( 0,
"$ENDFPLIST\n" );
1605 aFormatter.
Print( 0,
"DRAW\n" );
1609 switch( item.Type() )
1625 case SHAPE_T::ARC:
saveArc( &shape, aFormatter );
break;
1626 case SHAPE_T::BEZIER:
saveBezier( &shape, aFormatter );
break;
1627 case SHAPE_T::CIRCLE:
saveCircle( &shape, aFormatter );
break;
1628 case SHAPE_T::POLY:
savePolyLine( &shape, aFormatter );
break;
1629 case SHAPE_T::RECTANGLE:
saveRectangle( &shape, aFormatter );
break;
1641 aFormatter.
Print( 0,
"ENDDRAW\n" );
1644 aFormatter.
Print( 0,
"ENDDEF\n" );
1650 wxCHECK_RET( aArc && aArc->
GetShape() == SHAPE_T::ARC,
"Invalid ARC object." );
1658 aFormatter.
Print( 0,
"A %d %d %d %d %d %d %d %d %c %d %d %d %d\n",
1677 wxCHECK_RET( aBezier && aBezier->
GetShape() == SHAPE_T::BEZIER,
"Invalid BEZIER object." );
1679 aFormatter.
Print( 0,
"B 4 %d %d %d",
1684 aFormatter.
Print( 0,
" %d %d %d %d %d %d %d %d",
1700 wxCHECK_RET( aCircle && aCircle->
GetShape() == SHAPE_T::CIRCLE,
"Invalid CIRCLE object." );
1702 aFormatter.
Print( 0,
"C %d %d %d %d %d %d %c\n",
1716 wxCHECK_RET( aField && aField->
Type() ==
SCH_FIELD_T,
"Invalid SCH_FIELD object." );
1718 int hjustify, vjustify;
1719 int id = aField->
GetId();
1736 aFormatter.
Print( 0,
"F%d %s %d %d %d %c %c %c %c%c%c",
1746 aField->
IsBold() ?
'B' :
'N' );
1751 && !aField->
GetName().IsEmpty()
1757 aFormatter.
Print( 0,
"\n" );
1763 wxCHECK_RET( aPin && aPin->
Type() ==
SCH_PIN_T,
"Invalid SCH_PIN object." );
1770 case ELECTRICAL_PINTYPE::PT_INPUT: Etype =
'I';
break;
1771 case ELECTRICAL_PINTYPE::PT_OUTPUT: Etype =
'O';
break;
1772 case ELECTRICAL_PINTYPE::PT_BIDI: Etype =
'B';
break;
1773 case ELECTRICAL_PINTYPE::PT_TRISTATE: Etype =
'T';
break;
1774 case ELECTRICAL_PINTYPE::PT_PASSIVE: Etype =
'P';
break;
1775 case ELECTRICAL_PINTYPE::PT_UNSPECIFIED: Etype =
'U';
break;
1776 case ELECTRICAL_PINTYPE::PT_POWER_IN: Etype =
'W';
break;
1777 case ELECTRICAL_PINTYPE::PT_POWER_OUT: Etype =
'w';
break;
1778 case ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR: Etype =
'C';
break;
1779 case ELECTRICAL_PINTYPE::PT_OPENEMITTER: Etype =
'E';
break;
1780 case ELECTRICAL_PINTYPE::PT_NC: Etype =
'N';
break;
1783 if( !aPin->
GetName().IsEmpty() )
1786 aFormatter.
Print( 0,
"X ~" );
1788 int pin_orient =
'L';
1792 case PIN_ORIENTATION::PIN_RIGHT: pin_orient =
'R';
break;
1793 case PIN_ORIENTATION::PIN_LEFT: pin_orient =
'L';
break;
1794 case PIN_ORIENTATION::PIN_UP: pin_orient =
'U';
break;
1795 case PIN_ORIENTATION::PIN_DOWN: pin_orient =
'D';
break;
1796 case PIN_ORIENTATION::INHERIT: pin_orient =
'L';
break;
1799 aFormatter.
Print( 0,
" %s %d %d %d %c %d %d %d %d %c",
1812 aFormatter.
Print( 0,
" " );
1815 aFormatter.
Print( 0,
"N" );
1819 case GRAPHIC_PINSHAPE::LINE:
break;
1820 case GRAPHIC_PINSHAPE::INVERTED: aFormatter.
Print( 0,
"I" );
break;
1821 case GRAPHIC_PINSHAPE::CLOCK: aFormatter.
Print( 0,
"C" );
break;
1822 case GRAPHIC_PINSHAPE::INVERTED_CLOCK: aFormatter.
Print( 0,
"IC" );
break;
1823 case GRAPHIC_PINSHAPE::INPUT_LOW: aFormatter.
Print( 0,
"L" );
break;
1824 case GRAPHIC_PINSHAPE::CLOCK_LOW: aFormatter.
Print( 0,
"CL" );
break;
1825 case GRAPHIC_PINSHAPE::OUTPUT_LOW: aFormatter.
Print( 0,
"V" );
break;
1826 case GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK: aFormatter.
Print( 0,
"F" );
break;
1827 case GRAPHIC_PINSHAPE::NONLOGIC: aFormatter.
Print( 0,
"X" );
break;
1828 default: wxFAIL_MSG(
"Invalid pin shape" );
1831 aFormatter.
Print( 0,
"\n" );
1840 wxCHECK_RET( aPolyLine && aPolyLine->
GetShape() == SHAPE_T::POLY,
"Invalid POLY object." );
1842 aFormatter.
Print( 0,
"P %d %d %d %d",
1858 wxCHECK_RET( aRectangle && aRectangle->
GetShape() == SHAPE_T::RECTANGLE,
1859 "Invalid RECT object." );
1861 aFormatter.
Print( 0,
"S %d %d %d %d %d %d %d %c\n",
1875 wxCHECK_RET( aText && aText->
Type() ==
SCH_TEXT_T,
"Invalid SCH_TEXT object." );
1879 if(
text.Contains( wxT(
" " ) ) ||
text.Contains( wxT(
"~" ) ) ||
text.Contains( wxT(
"\"" ) ) )
1882 text.Replace( wxT(
"\"" ), wxT(
"''" ) );
1883 text = wxT(
"\"" ) +
text + wxT(
"\"" );
1886 aFormatter.
Print( 0,
"T %g %d %d %d %d %d %d %s",
1896 aFormatter.
Print( 0,
" %s %d", aText->
IsItalic() ?
"Italic" :
"Normal", aText->
IsBold() );
1898 char hjustify =
'C';
1905 char vjustify =
'C';
1912 aFormatter.
Print( 0,
" %c %c\n", hjustify, vjustify );
1933 wxString description = it->second->GetDescription();
1934 wxString keyWords = it->second->GetKeyWords();
1935 wxString docFileName = it->second->GetDatasheetField().GetText();
1937 if( description.IsEmpty() && keyWords.IsEmpty() && docFileName.IsEmpty() )
1940 formatter.
Print( 0,
"#\n$CMP %s\n",
TO_UTF8( it->second->GetName() ) );
1942 if( !description.IsEmpty() )
1943 formatter.
Print( 0,
"D %s\n",
TO_UTF8( description ) );
1945 if( !keyWords.IsEmpty() )
1948 if( !docFileName.IsEmpty() )
1949 formatter.
Print( 0,
"F %s\n",
TO_UTF8( docFileName ) );
1951 formatter.
Print( 0,
"$ENDCMP\n" );
1954 formatter.
Print( 0,
"#\n#End Doc Library\n" );
1960 LIB_SYMBOL_MAP::iterator it =
m_symbols.find( aSymbolName );
1963 THROW_IO_ERROR( wxString::Format(
_(
"library %s does not contain a symbol named %s" ),
1975 LIB_SYMBOL_MAP::iterator it1 =
m_symbols.begin();
1979 if( it1->second->IsAlias()
1980 && 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)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
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 bold 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
http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared.
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)
static SCH_ITEM * loadText(LINE_READER &aReader, int aMajorVersion, int aMinorVersion)
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)
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.