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();
450 symbol->SetGlobalPower();
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();
512 SCH_FIELD* parentField = aSymbol->GetField( fieldId );
514 *field = *parentField;
516 if( fieldId == FIELD_T::VALUE )
517 field->
SetText( newAliasName );
525 (*aMap)[ newSymbol->
GetName() ] = newSymbol;
534 const char* line = aReader.
Line();
536 wxCHECK_RET( *line ==
'F',
"Invalid field line" );
541 if( sscanf( line + 1,
"%d", &legacy_field_id ) != 1 || legacy_field_id < 0 )
548 switch( legacy_field_id )
550 case 0:
id = FIELD_T::REFERENCE;
break;
551 case 1:
id = FIELD_T::VALUE;
break;
552 case 2:
id = FIELD_T::FOOTPRINT;
break;
553 case 3:
id = FIELD_T::DATASHEET;
break;
556 if(
id != FIELD_T::USER )
558 field = aSymbol->GetField(
id );
562 field =
new SCH_FIELD( aSymbol.get(),
id );
563 aSymbol->AddDrawItem( field,
false );
567 while( *line !=
'"' && *line != 0 )
577 if(
id == FIELD_T::VALUE )
582 if(
text.size() == 1 &&
text[0] ==
'~' )
583 field->
SetText( wxEmptyString );
598 char textOrient =
parseChar( aReader, line, &line );
600 if( textOrient ==
'H' )
602 else if( textOrient ==
'V' )
605 SCH_PARSE_ERROR(
"invalid field text orientation parameter", aReader, line );
607 char textVisible =
parseChar( aReader, line, &line );
609 if( textVisible ==
'V' )
611 else if ( textVisible ==
'I' )
614 SCH_PARSE_ERROR(
"invalid field text visibility parameter", aReader, line );
620 if( *line != 0 && *line !=
'"' )
622 char textHJustify =
parseChar( aReader, line, &line );
624 if( textHJustify ==
'C' )
626 else if( textHJustify ==
'L' )
628 else if( textHJustify ==
'R' )
631 SCH_PARSE_ERROR(
"invalid field text horizontal justification", aReader, line );
637 size_t attrSize = attributes.size();
639 if( !(attrSize == 3 || attrSize == 1 ) )
640 SCH_PARSE_ERROR(
"invalid field text attributes size", aReader, line );
642 switch( (wxChar) attributes[0] )
647 default:
SCH_PARSE_ERROR(
"invalid field text vertical justification", aReader, line );
652 wxChar attr_1 = attributes[1];
653 wxChar attr_2 = attributes[2];
657 else if( attr_1 !=
'N' )
658 SCH_PARSE_ERROR(
"invalid field text italic parameter", aReader, line );
662 else if( attr_2 !=
'N' )
677 if(
id == FIELD_T::VALUE )
678 field->
SetText( aSymbol->GetName() );
682 wxString fieldName = wxEmptyString;
685 if( fieldName.IsEmpty() )
688 wxString candidateFieldName = fieldName;
692 while( aSymbol->GetField( candidateFieldName ) !=
nullptr )
693 candidateFieldName = wxString::Format(
"%s_%d", fieldName, ++suffix );
695 field->
SetName( candidateFieldName );
705 const char* line = aReader.
Line();
707 wxCHECK_RET(
strCompare(
"DRAW", line, &line ),
"Invalid DRAW section" );
715 aSymbol->GetDrawItems().sort();
722 aSymbol->AddDrawItem(
loadArc( aReader ),
false );
726 aSymbol->AddDrawItem(
loadCircle( aReader ),
false );
730 aSymbol->AddDrawItem(
loadText( aReader, aMajorVersion, aMinorVersion ),
false );
734 aSymbol->AddDrawItem(
loadRect( aReader ),
false );
738 aSymbol->AddDrawItem(
loadPin( aSymbol, aReader ),
false );
746 aSymbol->AddDrawItem(
loadBezier( aReader ),
false );
762 SCH_PARSE_ERROR(
"File ended prematurely loading symbol draw element.", aReader, line );
767 const char** aOutput )
769 switch (
parseChar( aReader, aLine, aOutput ) )
771 case 'F':
return FILL_T::FILLED_SHAPE;
772 case 'f':
return FILL_T::FILLED_WITH_BG_BODYCOLOR;
773 case 'N':
return FILL_T::NO_FILL;
777 SCH_PARSE_ERROR(
"invalid fill type, expected f, F, or N", aReader, aLine );
787 auto DECIDEG2RAD = [](
double deg ) ->
double
789 return deg * M_PI / 1800.0;
796 delta = *aAngle2 - *aAngle1;
804 x = cos( DECIDEG2RAD( *aAngle1 ) );
805 y = -sin( DECIDEG2RAD( *aAngle1 ) );
808 x = cos( DECIDEG2RAD( *aAngle2 ) );
809 y = -sin( DECIDEG2RAD( *aAngle2 ) );
815 if( *aAngle2 < *aAngle1 )
818 if( *aAngle2 - *aAngle1 > 1800 )
820 angle = ( *aAngle1 );
821 *aAngle1 = ( *aAngle2 );
827 if( *aAngle2 < *aAngle1 )
845 const char* line = aReader.
Line();
847 wxCHECK_MSG(
strCompare(
"A", line, &line ),
nullptr,
"Invalid arc definition" );
859 int angle1 =
parseInt( aReader, line, &line );
860 int angle2 =
parseInt( aReader, line, &line );
926 const char* line = aReader.
Line();
928 wxCHECK_MSG(
strCompare(
"C", line, &line ),
nullptr,
"Invalid circle definition" );
947 circle->SetStroke( stroke );
957 int aMajorVersion,
int aMinorVersion )
959 const char* line = aReader.
Line();
961 wxCHECK_MSG(
strCompare(
"T", line, &line ),
nullptr,
"Invalid SCH_TEXT definition" );
963 double angleInTenths;
971 angleInTenths =
parseInt( aReader, line, &line );
976 visible = !
parseInt( aReader, line, &line );
977 unit =
parseInt( aReader, line, &line );
978 bodyStyle =
parseInt( aReader, line, &line );
992 str.Replace(
"~",
" " );
998 str.Replace(
"''",
"\"" );
1013 sch_item = sch_text;
1014 eda_text = sch_text;
1031 if(
LIB_VERSION( aMajorVersion, aMinorVersion ) > 0
1037 else if( !
strCompare(
"Normal", line, &line ) )
1038 SCH_PARSE_ERROR(
"invalid eda_text stype, expected 'Normal' or 'Italic'", aReader, line );
1040 if(
parseInt( aReader, line, &line ) > 0 )
1046 switch(
parseChar( aReader, line, &line ) )
1051 default:
SCH_PARSE_ERROR(
"invalid horizontal eda_text justication; expected L, C, or R",
1055 switch(
parseChar( aReader, line, &line ) )
1060 default:
SCH_PARSE_ERROR(
"invalid vertical eda_text justication; expected T, C, or B",
1072 const char* line = aReader.
Line();
1074 wxCHECK_MSG(
strCompare(
"S", line, &line ),
nullptr,
"Invalid rectangle definition" );
1094 LINE_STYLE::SOLID );
1109 const char* line = aReader.
Line();
1111 wxCHECK_MSG(
strCompare(
"X", line, &line ),
nullptr,
"Invalid SCH_PIN definition" );
1118 wxString utf8Line = wxString::FromUTF8( line );
1119 wxStringTokenizer tokens( utf8Line,
" \r\n\t" );
1121 if( tokens.CountTokens() < 11 )
1124 tmp = tokens.GetNextToken();
1126 pos += tmp.size() + 1;
1128 tmp = tokens.GetNextToken();
1130 pos += tmp.size() + 1;
1135 tmp = tokens.GetNextToken();
1137 if( !tmp.ToLong( &num ) )
1143 pos += tmp.size() + 1;
1146 tmp = tokens.GetNextToken();
1148 if( !tmp.ToLong( &num ) )
1154 pos += tmp.size() + 1;
1157 tmp = tokens.GetNextToken();
1159 if( !tmp.ToLong( &num ) )
1165 pos += tmp.size() + 1;
1169 tmp = tokens.GetNextToken();
1171 if( tmp.size() > 1 )
1177 pos += tmp.size() + 1;
1181 switch(
static_cast<char>( tmp[0] ) )
1183 case 'U': orientation = PIN_ORIENTATION::PIN_UP;
break;
1184 case 'D': orientation = PIN_ORIENTATION::PIN_DOWN;
break;
1185 case 'L': orientation = PIN_ORIENTATION::PIN_LEFT;
break;
1187 default: orientation = PIN_ORIENTATION::PIN_RIGHT;
break;
1190 tmp = tokens.GetNextToken();
1192 if( !tmp.ToLong( &num ) )
1198 pos += tmp.size() + 1;
1201 tmp = tokens.GetNextToken();
1203 if( !tmp.ToLong( &num ) )
1209 pos += tmp.size() + 1;
1212 tmp = tokens.GetNextToken();
1214 if( !tmp.ToLong( &num ) )
1220 pos += tmp.size() + 1;
1221 int unit = (int) num;
1223 tmp = tokens.GetNextToken();
1225 if( !tmp.ToLong( &num ) )
1231 pos += tmp.size() + 1;
1234 tmp = tokens.GetNextToken();
1236 if( tmp.size() != 1 )
1242 pos += tmp.size() + 1;
1248 case 'I': pinType = ELECTRICAL_PINTYPE::PT_INPUT;
break;
1249 case 'O': pinType = ELECTRICAL_PINTYPE::PT_OUTPUT;
break;
1250 case 'B': pinType = ELECTRICAL_PINTYPE::PT_BIDI;
break;
1251 case 'T': pinType = ELECTRICAL_PINTYPE::PT_TRISTATE;
break;
1252 case 'P': pinType = ELECTRICAL_PINTYPE::PT_PASSIVE;
break;
1253 case 'U': pinType = ELECTRICAL_PINTYPE::PT_UNSPECIFIED;
break;
1254 case 'W': pinType = ELECTRICAL_PINTYPE::PT_POWER_IN;
break;
1255 case 'w': pinType = ELECTRICAL_PINTYPE::PT_POWER_OUT;
break;
1256 case 'C': pinType = ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR;
break;
1257 case 'E': pinType = ELECTRICAL_PINTYPE::PT_OPENEMITTER;
break;
1258 case 'N': pinType = ELECTRICAL_PINTYPE::PT_NC;
break;
1277 if( tokens.HasMoreTokens() )
1279 tmp = tokens.GetNextToken();
1285 LOWLEVEL_IN = 1 << 2,
1286 LOWLEVEL_OUT = 1 << 3,
1287 FALLING_EDGE = 1 << 4,
1293 for(
int j = (
int) tmp.size(); j > 0; )
1295 switch( tmp[--j].GetValue() )
1298 case 'N':
pin->SetVisible(
false );
break;
1299 case 'I': flags |=
INVERTED;
break;
1300 case 'C': flags |=
CLOCK;
break;
1301 case 'L': flags |= LOWLEVEL_IN;
break;
1302 case 'V': flags |= LOWLEVEL_OUT;
break;
1303 case 'F': flags |= FALLING_EDGE;
break;
1304 case 'X': flags |=
NONLOGIC;
break;
1314 case 0:
pin->SetShape( GRAPHIC_PINSHAPE::LINE );
break;
1315 case INVERTED:
pin->SetShape( GRAPHIC_PINSHAPE::INVERTED );
break;
1316 case CLOCK:
pin->SetShape( GRAPHIC_PINSHAPE::CLOCK );
break;
1317 case INVERTED |
CLOCK:
pin->SetShape( GRAPHIC_PINSHAPE::INVERTED_CLOCK );
break;
1318 case LOWLEVEL_IN:
pin->SetShape( GRAPHIC_PINSHAPE::INPUT_LOW );
break;
1319 case LOWLEVEL_IN |
CLOCK:
pin->SetShape( GRAPHIC_PINSHAPE::CLOCK_LOW );
break;
1320 case LOWLEVEL_OUT:
pin->SetShape( GRAPHIC_PINSHAPE::OUTPUT_LOW );
break;
1321 case FALLING_EDGE:
pin->SetShape( GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK );
break;
1322 case NONLOGIC:
pin->SetShape( GRAPHIC_PINSHAPE::NONLOGIC );
break;
1324 SCH_PARSE_ERROR(
"pin attributes do not define a valid pin shape", aReader, line );
1334 const char* line = aReader.
Line();
1336 wxCHECK_MSG(
strCompare(
"P", line, &line ),
nullptr,
"Invalid poly definition" );
1340 int points =
parseInt( aReader, line, &line );
1345 LINE_STYLE::SOLID );
1351 for(
int i = 0; i < points; i++ )
1367 const char* line = aReader.
Line();
1369 wxCHECK_MSG(
strCompare(
"B", line, &line ),
nullptr,
"Invalid Bezier definition" );
1371 int points =
parseInt( aReader, line, &line );
1373 wxCHECK_MSG( points == 4, NULL,
"Invalid Bezier curve definition" );
1381 LINE_STYLE::SOLID );
1415 const char* line = aReader.
Line();
1417 wxCHECK_RET(
strCompare(
"$FPLIST", line, &line ),
"Invalid footprint filter list" );
1421 wxArrayString footprintFilters;
1425 if(
strCompare(
"$ENDFPLIST", line, &line ) )
1427 aSymbol->SetFPFilters( footprintFilters );
1434 footprintFilters.Add( footprint );
1438 SCH_PARSE_ERROR(
"File ended prematurely while loading footprint filters.", aReader, line );
1446 bool doSaveDocFile = *aOpt;
1454 auto formatter = std::make_unique<FILE_OUTPUTFORMATTER>( fn.GetFullPath() );
1456 formatter->Print( 0,
"#encoding utf-8\n");
1460 if( !it->second->IsRoot() )
1466 formatter->Print( 0,
"#\n#End Library\n" );
1486 wxCHECK_RET( aSymbol && aSymbol->
IsRoot(),
"Invalid LIB_SYMBOL pointer." );
1490 wxArrayString aliasNames;
1494 for(
auto& entry : *aMap )
1499 aliasNames.Add( symbol->
GetName() );
1509 aFormatter.
Print( 0,
"DEF" );
1514 if( !reference.
GetText().IsEmpty() )
1517 aFormatter.
Print( 0,
" ~" );
1519 aFormatter.
Print( 0,
" %d %d %c %c %d %c %c\n",
1528 if( dateModified != 0 )
1530 int sec = dateModified & 63;
1531 int min = ( dateModified >> 6 ) & 63;
1532 int hour = ( dateModified >> 12 ) & 31;
1533 int day = ( dateModified >> 17 ) & 31;
1534 int mon = ( dateModified >> 22 ) & 15;
1535 int year = ( dateModified >> 26 ) + 1990;
1537 aFormatter.
Print( 0,
"Ti %d/%d/%d %d:%d:%d\n", year, mon, day, hour, min, sec );
1540 std::vector<SCH_FIELD*> orderedFields;
1544 int legacy_field_id = 0;
1547 saveField( field, legacy_field_id++, aFormatter );
1550 if( !aliasNames.IsEmpty() )
1552 aFormatter.
Print( 0,
"ALIAS" );
1554 for(
unsigned i = 0; i < aliasNames.GetCount(); i++ )
1555 aFormatter.
Print( 0,
" %s",
TO_UTF8( aliasNames[i] ) );
1557 aFormatter.
Print( 0,
"\n" );
1563 if( footprints.GetCount() != 0 )
1565 aFormatter.
Print( 0,
"$FPLIST\n" );
1567 for(
unsigned i = 0; i < footprints.GetCount(); i++ )
1568 aFormatter.
Print( 0,
" %s\n",
TO_UTF8( footprints[i] ) );
1570 aFormatter.
Print( 0,
"$ENDFPLIST\n" );
1579 aFormatter.
Print( 0,
"DRAW\n" );
1583 switch( item.Type() )
1599 case SHAPE_T::ARC:
saveArc( &shape, aFormatter );
break;
1600 case SHAPE_T::BEZIER:
saveBezier( &shape, aFormatter );
break;
1601 case SHAPE_T::CIRCLE:
saveCircle( &shape, aFormatter );
break;
1602 case SHAPE_T::POLY:
savePolyLine( &shape, aFormatter );
break;
1603 case SHAPE_T::RECTANGLE:
saveRectangle( &shape, aFormatter );
break;
1615 aFormatter.
Print( 0,
"ENDDRAW\n" );
1618 aFormatter.
Print( 0,
"ENDDEF\n" );
1624 wxCHECK_RET( aArc && aArc->
GetShape() == SHAPE_T::ARC,
"Invalid ARC object." );
1632 aFormatter.
Print( 0,
"A %d %d %d %d %d %d %d %d %c %d %d %d %d\n",
1651 wxCHECK_RET( aBezier && aBezier->
GetShape() == SHAPE_T::BEZIER,
"Invalid BEZIER object." );
1653 aFormatter.
Print( 0,
"B 4 %d %d %d",
1658 aFormatter.
Print( 0,
" %d %d %d %d %d %d %d %d",
1674 wxCHECK_RET( aCircle && aCircle->
GetShape() == SHAPE_T::CIRCLE,
"Invalid CIRCLE object." );
1676 aFormatter.
Print( 0,
"C %d %d %d %d %d %d %c\n",
1690 wxCHECK_RET( aField && aField->
Type() ==
SCH_FIELD_T,
"Invalid SCH_FIELD object." );
1692 int hjustify, vjustify;
1709 aFormatter.
Print( 0,
"F%d %s %d %d %d %c %c %c %c%c%c",
1719 aField->
IsBold() ?
'B' :
'N' );
1724 && !aField->
GetName().IsEmpty()
1730 aFormatter.
Print( 0,
"\n" );
1736 wxCHECK_RET( aPin && aPin->
Type() ==
SCH_PIN_T,
"Invalid SCH_PIN object." );
1743 case ELECTRICAL_PINTYPE::PT_INPUT: Etype =
'I';
break;
1744 case ELECTRICAL_PINTYPE::PT_OUTPUT: Etype =
'O';
break;
1745 case ELECTRICAL_PINTYPE::PT_BIDI: Etype =
'B';
break;
1746 case ELECTRICAL_PINTYPE::PT_TRISTATE: Etype =
'T';
break;
1747 case ELECTRICAL_PINTYPE::PT_PASSIVE: Etype =
'P';
break;
1748 case ELECTRICAL_PINTYPE::PT_UNSPECIFIED: Etype =
'U';
break;
1749 case ELECTRICAL_PINTYPE::PT_POWER_IN: Etype =
'W';
break;
1750 case ELECTRICAL_PINTYPE::PT_POWER_OUT: Etype =
'w';
break;
1751 case ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR: Etype =
'C';
break;
1752 case ELECTRICAL_PINTYPE::PT_OPENEMITTER: Etype =
'E';
break;
1753 case ELECTRICAL_PINTYPE::PT_NC: Etype =
'N';
break;
1756 if( !aPin->
GetName().IsEmpty() )
1759 aFormatter.
Print( 0,
"X ~" );
1761 int pin_orient =
'L';
1765 case PIN_ORIENTATION::PIN_RIGHT: pin_orient =
'R';
break;
1766 case PIN_ORIENTATION::PIN_LEFT: pin_orient =
'L';
break;
1767 case PIN_ORIENTATION::PIN_UP: pin_orient =
'U';
break;
1768 case PIN_ORIENTATION::PIN_DOWN: pin_orient =
'D';
break;
1769 case PIN_ORIENTATION::INHERIT: pin_orient =
'L';
break;
1772 aFormatter.
Print( 0,
" %s %d %d %d %c %d %d %d %d %c",
1785 aFormatter.
Print( 0,
" " );
1788 aFormatter.
Print( 0,
"N" );
1792 case GRAPHIC_PINSHAPE::LINE:
break;
1793 case GRAPHIC_PINSHAPE::INVERTED: aFormatter.
Print( 0,
"I" );
break;
1794 case GRAPHIC_PINSHAPE::CLOCK: aFormatter.
Print( 0,
"C" );
break;
1795 case GRAPHIC_PINSHAPE::INVERTED_CLOCK: aFormatter.
Print( 0,
"IC" );
break;
1796 case GRAPHIC_PINSHAPE::INPUT_LOW: aFormatter.
Print( 0,
"L" );
break;
1797 case GRAPHIC_PINSHAPE::CLOCK_LOW: aFormatter.
Print( 0,
"CL" );
break;
1798 case GRAPHIC_PINSHAPE::OUTPUT_LOW: aFormatter.
Print( 0,
"V" );
break;
1799 case GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK: aFormatter.
Print( 0,
"F" );
break;
1800 case GRAPHIC_PINSHAPE::NONLOGIC: aFormatter.
Print( 0,
"X" );
break;
1801 default: wxFAIL_MSG(
"Invalid pin shape" );
1804 aFormatter.
Print( 0,
"\n" );
1813 wxCHECK_RET( aPolyLine && aPolyLine->
GetShape() == SHAPE_T::POLY,
"Invalid POLY object." );
1815 aFormatter.
Print( 0,
"P %d %d %d %d",
1831 wxCHECK_RET( aRectangle && aRectangle->
GetShape() == SHAPE_T::RECTANGLE,
1832 "Invalid RECT object." );
1834 aFormatter.
Print( 0,
"S %d %d %d %d %d %d %d %c\n",
1848 wxCHECK_RET( aText && aText->
Type() ==
SCH_TEXT_T,
"Invalid SCH_TEXT object." );
1852 if(
text.Contains( wxT(
" " ) ) ||
text.Contains( wxT(
"~" ) ) ||
text.Contains( wxT(
"\"" ) ) )
1855 text.Replace( wxT(
"\"" ), wxT(
"''" ) );
1856 text = wxT(
"\"" ) +
text + wxT(
"\"" );
1859 aFormatter.
Print( 0,
"T %g %d %d %d %d %d %d %s",
1869 aFormatter.
Print( 0,
" %s %d", aText->
IsItalic() ?
"Italic" :
"Normal", aText->
IsBold() );
1871 char hjustify =
'C';
1878 char vjustify =
'C';
1885 aFormatter.
Print( 0,
" %c %c\n", hjustify, vjustify );
1906 wxString description = it->second->GetDescription();
1907 wxString keyWords = it->second->GetKeyWords();
1908 wxString docFileName = it->second->GetDatasheetField().GetText();
1910 if( description.IsEmpty() && keyWords.IsEmpty() && docFileName.IsEmpty() )
1913 formatter.
Print( 0,
"#\n$CMP %s\n",
TO_UTF8( it->second->GetName() ) );
1915 if( !description.IsEmpty() )
1916 formatter.
Print( 0,
"D %s\n",
TO_UTF8( description ) );
1918 if( !keyWords.IsEmpty() )
1921 if( !docFileName.IsEmpty() )
1922 formatter.
Print( 0,
"F %s\n",
TO_UTF8( docFileName ) );
1924 formatter.
Print( 0,
"$ENDCMP\n" );
1927 formatter.
Print( 0,
"#\n#End Doc Library\n" );
1933 LIB_SYMBOL_MAP::iterator it =
m_symbols.find( aSymbolName );
1936 THROW_IO_ERROR( wxString::Format(
_(
"library %s does not contain a symbol named %s" ),
1948 LIB_SYMBOL_MAP::iterator it1 =
m_symbols.begin();
1952 if( it1->second->IsDerived()
1953 && 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 SetTextPos(const VECTOR2I &aPoint)
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.
void GetFields(std::vector< SCH_FIELD * > &aList, bool aVisibleOnly=false) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
bool UnitsLocked() const
Check whether symbol units are interchangeable.
bool IsRoot() const override
For symbols derived from other symbols, IsRoot() indicates no derivation.
timestamp_t GetLastModDate() const
SCH_FIELD * GetField(const wxString &aFieldName)
Find a field within this symbol matching aFieldName; return nullptr if not found.
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 SetKeyWords(const wxString &aKeyWords)
SCH_FIELD & GetValueField()
Return reference to the value 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.
bool IsGlobalPower() const override
int GetUnitCount() const override
LIB_SYMBOL_REF & GetParent()
SCH_FIELD & GetReferenceField()
Return reference to the reference designator field.
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
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 saveField(const SCH_FIELD *aField, int aLegacyFieldIdx, OUTPUTFORMATTER &aFormatter)
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 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)
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
wxString GetCanonicalFieldName(FIELD_T aFieldType)
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
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.