30#include <wx/filename.h>
61 if( opA->
size() == 0 )
64 std::list<IDF_SEGMENT*>::iterator olAs = opA->
begin();
65 std::list<IDF_SEGMENT*>::iterator olAe = opA->
end();
66 std::list<IDF_SEGMENT*>::iterator olBs = opB->
begin();
70 if( !(*olAs)->MatchesStart( (*olBs)->startPoint ) )
73 if( !(*olAs)->MatchesEnd( (*olBs)->endPoint ) )
112 double aXoff,
double aYoff,
113 double aZoff,
double aAngleOff )
131#ifndef DISABLE_IDF_OWNERSHIP
137 ostr << __FILE__ <<
":" << aSourceLine <<
":" << aSourceFunc <<
"():\n";
138 ostr <<
"* BUG: IDF3_COMP_OUTLINE_DATA::parent not set; cannot enforce ownership rules\n";
159 ostr <<
"* " << __FILE__ <<
":" << aSourceLine <<
":" << aSourceFunc <<
"():\n";
160 ostr <<
"* ownership violation; CAD type is ";
178 double aZoff,
double aAngleOff )
180#ifndef DISABLE_IDF_OWNERSHIP
194 double& aZoff,
double& aAngleOff )
211#ifndef DISABLE_IDF_OWNERSHIP
229 IDF_VERSION aIdfVersion,
bool aNoSubstituteOutlines )
232 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
233 "\n* BUG: invoked with no reference to the parent IDF_BOARD" ) );
251 while( !
FetchIDFLine( aBoardFile, iline, isComment, pos ) && aBoardFile.good() );
253 if( ( !aBoardFile.good() && !aBoardFile.eof() ) || iline.empty() )
257 ostr <<
"invalid IDF file\n";
258 ostr <<
"* violation: could not read PLACEMENT section\n";
259 ostr <<
"* file position: " << pos;
261 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
268 ostr <<
"invalid IDF file\n";
269 ostr <<
"* violation: comment within PLACEMENT section\n";
270 ostr <<
"* line: '" << iline <<
"'\n";
271 ostr <<
"* file position: " << pos;
273 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
279 if( !quoted &&
CompareToken(
".END_PLACEMENT", token ) )
285 std::string ngeom = token;
291 ostr <<
"invalid IDF file\n";
292 ostr <<
"* violation: no PART NAME in PLACEMENT RECORD2\n";
293 ostr <<
"* line: '" << iline <<
"'\n";
294 ostr <<
"* file position: " << pos;
296 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
299 std::string npart = token;
300 uid = ngeom +
"_" + npart;
306 ostr <<
"invalid IDF file\n";
307 ostr <<
"* violation: no REFDES in PLACEMENT RECORD2\n";
308 ostr <<
"* line: '" << iline <<
"'\n";
309 ostr <<
"* file position: " << pos;
311 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
329 ostr <<
"UNSUPPORTED FEATURE\n";
330 ostr <<
"* RefDes is 'BOARD', indicating this is a PANEL FILE (not supported)\n";
331 ostr <<
"* line: '" << iline <<
"'\n";
332 ostr <<
"* file position: " << pos;
334 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
340 ostr <<
"invalid IDF file\n";
341 ostr <<
"* violation: RefDes in PLACEMENT RECORD2 is 'PANEL'\n";
342 ostr <<
"* line: '" << iline <<
"'\n";
343 ostr <<
"* file position: " << pos;
345 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
347 else if( token.empty() )
351 ostr <<
"invalid IDF file\n";
352 ostr <<
"* violation: empty RefDes string in PLACEMENT RECORD2\n";
353 ostr <<
"* line: '" << iline <<
"'\n";
354 ostr <<
"* file position: " << pos;
356 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
366 while( !
FetchIDFLine( aBoardFile, iline, isComment, pos ) && aBoardFile.good() );
368 if( !aBoardFile.good() )
372 ostr <<
"invalid IDF file\n";
373 ostr <<
"* problems reading PLACEMENT SECTION, RECORD 3\n";
374 ostr <<
"* file position: " << pos;
376 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
383 ostr <<
"invalid IDF file\n";
384 ostr <<
"* violation: comment within PLACEMENT section\n";
385 ostr <<
"* line: '" << iline <<
"'\n";
386 ostr <<
"* file position: " << pos;
388 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
398 ostr <<
"invalid IDF file\n";
399 ostr <<
"* violation: X value must not be in quotes (PLACEMENT RECORD 3)\n";
400 ostr <<
"* line: '" << iline <<
"'\n";
401 ostr <<
"* file position: " << pos;
403 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
414 ostr <<
"invalid IDF file\n";
415 ostr <<
"* violation: X value is not numeric (PLACEMENT RECORD 3)\n";
416 ostr <<
"* line: '" << iline <<
"'\n";
417 ostr <<
"* file position: " << pos;
419 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
426 ostr <<
"invalid IDF file\n";
427 ostr <<
"* violation: no Y value (PLACEMENT RECORD 3)\n";
428 ostr <<
"* line: '" << iline <<
"'\n";
429 ostr <<
"* file position: " << pos;
431 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
442 ostr <<
"invalid IDF file\n";
443 ostr <<
"* violation: Y value is not numeric (PLACEMENT RECORD 3)\n";
444 ostr <<
"* line: '" << iline <<
"'\n";
445 ostr <<
"* file position: " << pos;
447 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
456 ostr <<
"invalid IDFv3 file\n";
457 ostr <<
"* violation: no Z value (PLACEMENT RECORD 3)\n";
458 ostr <<
"* line: '" << iline <<
"'\n";
459 ostr <<
"* file position: " << pos;
461 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
472 ostr <<
"invalid IDFv3 file\n";
473 ostr <<
"* violation: Z value is not numeric (PLACEMENT RECORD 3)\n";
474 ostr <<
"* line: '" << iline <<
"'\n";
475 ostr <<
"* file position: " << pos;
477 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
485 ostr <<
"invalid IDF file\n";
486 ostr <<
"* violation: no rotation value (PLACEMENT RECORD 3)\n";
487 ostr <<
"* line: '" << iline <<
"'\n";
488 ostr <<
"* file position: " << pos;
490 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
501 ostr <<
"invalid IDF file\n";
502 ostr <<
"* violation: rotation value is not numeric (PLACEMENT RECORD 3)\n";
503 ostr <<
"* line: '" << iline <<
"'\n";
504 ostr <<
"* file position: " << pos;
506 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
513 ostr <<
"invalid IDF file\n";
514 ostr <<
"* violation: no SIDE value (PLACEMENT RECORD 3)\n";
515 ostr <<
"* line: '" << iline <<
"'\n";
516 ostr <<
"* file position: " << pos;
518 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
533 ostr <<
"invalid IDF file\n";
534 ostr <<
"* violation: invalid SIDE value in PLACEMENT RECORD 3 ('";
535 ostr << token <<
"'); must be one of TOP/BOTTOM\n";
536 ostr <<
"* line: '" << iline <<
"'\n";
537 ostr <<
"* file position: " << pos;
539 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
546 ostr <<
"invalid IDF file\n";
547 ostr <<
"* violation: no PLACEMENT value in PLACEMENT RECORD 3\n";
548 ostr <<
"* line: '" << iline <<
"'\n";
549 ostr <<
"* file position: " << pos;
551 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
581 ostr <<
"invalid IDF file\n";
582 ostr <<
"* violation: invalid PLACEMENT value ('";
583 ostr << token <<
"') in PLACEMENT RECORD 3\n";
584 ostr <<
"* line: '" << iline <<
"'\n";
585 ostr <<
"* file position: " << pos;
587 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
592 if(
outline ==
nullptr && !aNoSubstituteOutlines )
595 cerr <<
"* GeomName( " << ngeom <<
" ), PartName( " << npart <<
" )\n";
596 cerr <<
"* Substituting default outline.\n";
600 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
601 "\n* missing outline: cannot create default" ) );
621 catch( std::bad_alloc& )
625 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
626 "cannot create component object" ) );
646 if(
parent->GetPosition( tX, tY, tA, tL ) )
653 ostr <<
"invalid IDF file\n";
654 ostr <<
"* violation: inconsistent PLACEMENT data; ";
657 ostr <<
"* line: '" << iline <<
"'\n";
658 ostr <<
"* file position: " << pos;
660 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
670 parent->SetPlacement( placement );
677 if( placement !=
parent->GetPlacement() )
682 ostr <<
"invalid IDF file\n";
683 ostr <<
"* violation: inconsistent PLACEMENT data; ";
684 ostr <<
"* PLACEMENT value has changed from ";
687 ostr <<
"* line: '" << iline <<
"'\n";
688 ostr <<
"* file position: " << pos;
690 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
701 if( !
parent->AddOutlineData( cdp ) )
705 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
706 "could not add outline data object" ) );
714 double aXpos,
double aYpos,
double aAngle,
715 const std::string& aRefDes,
722 if(
outline->GetUID().empty() )
723 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
724 "empty GEOM and PART names" ) );
728 ERROR_IDF <<
"placement invalid (" << aRefDes <<
":";
736 ostr <<
"must be TOP or BOTTOM\n";
738 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
742 double xpos, ypos, ang;
759 std::string arefdes = aRefDes;
761 if( arefdes.empty() || !arefdes.compare(
"~" )
762 || ( arefdes.size() >= 8 &&
CompareToken(
"NOREFDES", arefdes.substr(0, 8) ) ) )
763 arefdes =
"NOREFDES";
765 aBoardFile <<
"\"" <<
outline->GetGeomName() <<
"\" \"" <<
outline->GetPartName() <<
"\" "
775 aBoardFile << setiosflags(ios::fixed) << setprecision(5) << xpos <<
" "
776 << ypos <<
" " << setprecision(3) <<
zoff <<
" "
781 aBoardFile << setiosflags(ios::fixed) << setprecision(1) << (xpos /
IDF_THOU_TO_MM) <<
" "
783 << setprecision(3) << ang <<
" ";
791 aBoardFile <<
" PLACED\n";
795 aBoardFile <<
" UNPLACED\n";
799 aBoardFile <<
" MCAD\n";
803 aBoardFile <<
" ECAD\n";
825 std::list< IDF3_COMP_OUTLINE_DATA* >::iterator itcS =
components.begin();
826 std::list< IDF3_COMP_OUTLINE_DATA* >::iterator itcE =
components.end();
828 while( itcS != itcE )
836 std::list< IDF_DRILL_DATA* >::iterator itdS =
drills.begin();
837 std::list< IDF_DRILL_DATA* >::iterator itdE =
drills.end();
839 while( itdS != itdE )
849#ifndef DISABLE_IDF_OWNERSHIP
855 ostr << __FILE__ <<
":" << aSourceLine <<
":" << aSourceFunc <<
"():\n";
856 ostr <<
"\n* BUG: parent not set";
876 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
877 ostr <<
"\n* ownership violation; internal CAD type (MCAD) conflicts with "
892 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
893 ostr <<
"\n* ownership violation; internal CAD type (MCAD) conflicts with "
906 ostr <<
"\n* BUG: unhandled internal placement value (" <<
static_cast<int>(
placement ) <<
")";
929 return parent->GetCadType();
944#ifndef DISABLE_IDF_OWNERSHIP
949 if( aRefDes.empty() )
952 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"(): invalid RefDes (empty)";
961 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
962 ostr <<
"* BUG: PANEL is a reserved designator and may not be used by components";
981 const std::string& aHoleType,
990 catch( std::bad_alloc& )
1009 cerr <<
"\n* BUG: PANEL drills not supported at component level\n";
1016 cerr <<
"\n* BUG: pushing an incorrect REFDES ('" << aDrilledHole->
GetDrillRefDes();
1017 cerr <<
"') to component ('" <<
refdes <<
"')\n";
1021 drills.push_back( aDrilledHole );
1023 return aDrilledHole;
1029#ifndef DISABLE_IDF_OWNERSHIP
1041 list< IDF_DRILL_DATA* >::iterator itS =
drills.begin();
1042 list< IDF_DRILL_DATA* >::iterator itE =
drills.end();
1044 while( !
drills.empty() && itS != itE )
1046 if( (*itS)->Matches( aDia, aXpos, aYpos ) )
1050 itS =
drills.erase( itS );
1063#ifndef DISABLE_IDF_OWNERSHIP
1073 list< IDF_DRILL_DATA* >::iterator itS =
drills.begin();
1074 list< IDF_DRILL_DATA* >::iterator itE =
drills.end();
1076 while( !
drills.empty() && itS != itE )
1078 if( *itS == aDrill )
1099 if( aComponentOutline ==
nullptr )
1102 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
1103 "(): invalid aComponentOutline (nullptr)";
1118#ifndef DISABLE_IDF_OWNERSHIP
1126 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"(): component list is empty";
1132 if( aComponentOutline ==
nullptr )
1135 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
1136 "(): invalid aComponentOutline (nullptr)";
1144 std::list< IDF3_COMP_OUTLINE_DATA* >::iterator itS =
components.begin();
1145 std::list< IDF3_COMP_OUTLINE_DATA* >::iterator itE =
components.end();
1149 if( *itS == aComponentOutline )
1165#ifndef DISABLE_IDF_OWNERSHIP
1173 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
1174 ostr <<
"* aIndex (" << aIndex <<
") out of range; list size is " <<
components.size();
1180 std::list< IDF3_COMP_OUTLINE_DATA* >::iterator itS =
components.begin();
1181 std::list< IDF3_COMP_OUTLINE_DATA* >::iterator itE =
components.end();
1238#ifndef DISABLE_IDF_OWNERSHIP
1255 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
1256 ostr <<
"\n* invalid side (must be TOP or BOTTOM only): " <<
1289 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
1290 ostr <<
"\n* invalid PLACEMENT value (" <<
static_cast<int>( aPlacementValue ) <<
")";
1296#ifndef DISABLE_IDF_OWNERSHIP
1312 std::list< IDF_DRILL_DATA* >::iterator itS =
drills.begin();
1313 std::list< IDF_DRILL_DATA* >::iterator itE =
drills.end();
1317 (*itS)->write( aBoardFile,
GetUnit() );
1330 std::list< IDF3_COMP_OUTLINE_DATA* >::iterator itS =
components.begin();
1331 std::list< IDF3_COMP_OUTLINE_DATA* >::iterator itE =
components.end();
1385#ifndef DISABLE_IDF_OWNERSHIP
1392 ostr << __FILE__ <<
":" << aSourceLine <<
":" << aSourceFunc;
1393 ostr <<
"(): Invalid component pointer (nullptr)";
1413 ostr <<
"* " << __FILE__ <<
":" << aSourceLine <<
":" << aSourceFunc <<
"():\n";
1414 ostr <<
"* ownership violation; CAD type is ";
1441 ERROR_IDF <<
"\n* TNM unit is not supported; defaulting to mm\n";
1449 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
1450 ostr <<
"* invalid board unit (" <<
static_cast<int>( aUnit ) <<
")";
1466 std::map<std::string, OTHER_OUTLINE*>::iterator its =
m_otherOutlines.begin();
1467 std::map<std::string, OTHER_OUTLINE*>::iterator ite =
m_otherOutlines.end();
1471 its->second->SetUnit( aUnit );
1484 (*its)->SetUnit( aUnit );
1497 (*its)->SetUnit( aUnit );
1510 (*its)->SetUnit( aUnit );
1523 (*its)->SetUnit( aUnit );
1536 (*its)->SetUnit( aUnit );
1544 std::multimap<std::string, GROUP_OUTLINE*>::iterator its =
m_groupOutlines.begin();
1545 std::multimap<std::string, GROUP_OUTLINE*>::iterator ite =
m_groupOutlines.end();
1549 its->second->SetUnit( aUnit );
1564 its->second->SetUnit( aUnit );
1576 if( aBoardThickness <= 0.0 )
1579 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"(): ";
1580 ostr <<
"board thickness (" << aBoardThickness <<
") must be > 0";
1615 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1616 "\n* BUG: could not add drill data; cannot continue reading the file" ) );
1636 bool aNoSubstituteOutlines )
1650 bool quoted =
false;
1654 while( !
FetchIDFLine( aBoardFile, iline, isComment, pos ) && aBoardFile.good() );
1656 if( !aBoardFile.good() )
1657 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"problems reading board header" ) );
1661 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1662 "invalid IDF file\n"
1663 "* Violation of specification: first line must be .HEADER\n" ) );
1668 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1669 "invalid IDF file\n"
1670 "* Violation of specification:\n"
1671 "* first line must be .HEADER and have no quotes or trailing text" ) );
1680 while( !
FetchIDFLine( aBoardFile, iline, isComment, pos ) && aBoardFile.good() );
1682 if( !aBoardFile.good() )
1683 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"problems reading board header, RECORD 2" ) );
1687 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1688 "invalid IDF file\n"
1689 "* Violation of specification: comment within .HEADER section" ) );
1697 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1698 "invalid IDF file\n"
1699 "* Violation of specification:\n"
1700 "* File Type in HEADER section must not be in quotes" ) );
1709 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1710 "not a board file\n"
1711 "* PANEL_FILE is not supported (expecting BOARD_FILE)" ) );
1715 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1716 "invalid IDF file\n"
1717 "* Expecting string: BOARD_FILE" ) );
1723 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1724 "invalid IDF file\n"
1725 "* Violation of specification: HEADER section, RECORD 2: no FIELD 2" ) );
1730 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1731 "invalid IDF file\n"
1732 "* Violation of specification: IDF Version must not be in quotes" ) );
1735 if( !token.compare(
"3.0" ) || !token.compare(
"3." ) || !token.compare(
"3" ) )
1739 else if( !token.compare(
"2.0" ) || !token.compare(
"2." ) || !token.compare(
"2" ) )
1747 ostr <<
"unsupported IDF version\n";
1748 ostr <<
"* Expecting version to be a variant of '3.0', '2.0' (value: '" << token <<
"')\n";
1750 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
1755 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1756 "invalid IDF file\n"
1757 "* Violation of specification:\n"
1758 "* HEADER section, RECORD 2, FIELD 3: no Source System string" ) );
1765 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1766 "invalid IDF file\n"
1767 "* Violation of specification:\n"
1768 "* HEADER section, RECORD 2, FIELD 4: no Date string" ) );
1775 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1776 "invalid IDF file\n"
1777 "* Violation of specification:\n"
1778 "* HEADER section, RECORD 2, FIELD 5: no Board File Version number" ) );
1781 std::istringstream istr;
1788 ERROR_IDF <<
"invalid Board File Version in header\n";
1789 cerr <<
"* Setting default version of 1\n";
1795 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1796 "invalid IDF file\n"
1797 "* Violation of specification:\n"
1798 "* HEADER section, RECORD 2, FIELD 5: Board File Version must not be in quotes" ) );
1804 while( !
FetchIDFLine( aBoardFile, iline, isComment, pos ) && aBoardFile.good() );
1806 if( !aBoardFile.good() )
1807 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"\n* problems reading board header, RECORD 2" ) );
1811 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1812 "invalid IDF file\n"
1813 "* Violation of specification: comment within .HEADER section" ) );
1823 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1824 "invalid IDF file\n"
1825 "* Violation of specification:\n"
1826 "* HEADER section, RECORD 3, FIELD 1: no Board Name" ) );
1831 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1832 "invalid IDF file\n"
1833 "* Violation of specification:\n"
1834 "* HEADER section, RECORD 3, FIELD 2: UNIT may not be in quotes" ) );
1853 ostr <<
"invalid IDF file\n";
1854 ostr <<
"* HEADER section, RECORD 3, FIELD 2: expecting MM or THOU (got '" << token <<
1857 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
1864 while( !
FetchIDFLine( aBoardFile, iline, isComment, pos ) && aBoardFile.good() );
1866 if( ( !aBoardFile.good() && !aBoardFile.eof() ) || iline.empty() )
1867 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"problems reading board header, RECORD 4" ) );
1871 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1872 "invalid IDF file\n"
1873 "* Violation of specification: comment within .HEADER section\n" ) );
1880 ostr <<
"invalid IDF file\n";
1881 ostr <<
"* Violation of specification: expected .END_HEADER\n";
1882 ostr <<
"* line: '" << iline <<
"'";
1884 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
1892 bool aNoSubstituteOutlines )
1894 std::list< std::string > comments;
1914 bool quoted =
false;
1917 while( aBoardFile.good() )
1919 while( !
FetchIDFLine( aBoardFile, iline, isComment, pos ) && aBoardFile.good() );
1921 if( !aBoardFile.good() )
1926 if( !comments.empty() )
1927 ERROR_IDF <<
"[warning]: trailing comments in IDF file (comments will be lost)\n";
1932 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1933 "problems reading board section" ) );
1938 comments.push_back( iline );
1949 ostr <<
"invalid IDF file\n";
1950 ostr <<
"* Violation of specification: quoted string where SECTION HEADER expected\n";
1951 ostr <<
"* line: '" << iline <<
"'";
1952 ostr <<
"* position: " << pos;
1954 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
1962 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1963 "invalid IDF file\n"
1964 "* Violation of specification: no HEADER section" ) );
1969 if( !comments.empty() )
1971 std::list<std::string>::iterator its = comments.begin();
1972 std::list<std::string>::iterator ite = comments.end();
1986 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"PANEL_OUTLINE not supported" ) );
1991 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
1992 "invalid IDF file\n"
1993 "* Violation of specification: expecting .BOARD_OUTLINE, have .OTHER_OUTLINE" ) );
2001 catch( std::bad_alloc& )
2003 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2004 "could not create OTHER_OUTLINE object" ) );
2012 if( !comments.empty() )
2014 std::list<std::string>::iterator its = comments.begin();
2015 std::list<std::string>::iterator ite = comments.end();
2027 ostr <<
"invalid IDF file\n";
2028 ostr <<
"* Violation of specification. Non-unique ID in OTHER_OUTLINE '";
2030 ostr <<
"* line: '" << iline <<
"'\n";
2031 ostr <<
"* pos: " << pos;
2034 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
2044 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2045 "invalid IDF file\n"
2046 "* Violation of specification: expecting .BOARD_OUTLINE, have .ROUTE_OUTLINE" ) );
2055 catch( std::bad_alloc& )
2057 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2058 "could not create ROUTE_OUTLINE object" ) );
2064 if( !comments.empty() )
2066 std::list<std::string>::iterator its = comments.begin();
2067 std::list<std::string>::iterator ite = comments.end();
2085 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2086 "invalid IDF file\n"
2087 "* Violation of specification: expecting .BOARD_OUTLINE, have .PLACE_OUTLINE" ) );
2096 catch( std::bad_alloc& )
2098 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2099 "could not create PLACE_OUTLINE object" ) );
2105 if( !comments.empty() )
2107 std::list<std::string>::iterator its = comments.begin();
2108 std::list<std::string>::iterator ite = comments.end();
2126 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2127 "invalid IDF file\n"
2128 "* Violation of specification: expecting .BOARD_OUTLINE, have .ROUTE_KEEPOUT" ) );
2137 catch( std::bad_alloc& )
2139 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2140 "could not create ROUTE_KEEPOUT object" ) );
2146 if( !comments.empty() )
2148 std::list<std::string>::iterator its = comments.begin();
2149 std::list<std::string>::iterator ite = comments.end();
2167 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2168 "invalid IDF file\n"
2169 "* Violation of specification: expecting .BOARD_OUTLINE, have .VIA_KEEPOUT" ) );
2178 catch( std::bad_alloc& )
2180 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"could not create VIA_KEEPOUT object" ) );
2186 if( !comments.empty() )
2188 std::list<std::string>::iterator its = comments.begin();
2189 std::list<std::string>::iterator ite = comments.end();
2207 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2208 "invalid IDF file\n"
2209 "* Violation of specification: expecting .BOARD_OUTLINE, have .PLACE_KEEPOUT" ) );
2217 catch( std::bad_alloc& )
2219 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"could not create PLACE_KEEPOUT object" ) );
2225 if( !comments.empty() )
2227 std::list<std::string>::iterator its = comments.begin();
2228 std::list<std::string>::iterator ite = comments.end();
2246 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2247 "invalid IDF file\n"
2248 "* Violation of specification: expecting .BOARD_OUTLINE, have .PLACE_REGION" ) );
2257 catch( std::bad_alloc& )
2259 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"could not create PLACE_REGION object" ) );
2265 if( !comments.empty() )
2267 std::list<std::string>::iterator its = comments.begin();
2268 std::list<std::string>::iterator ite = comments.end();
2286 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2287 "invalid IDF file\n"
2288 "* Violation of specification: expecting .BOARD_OUTLINE, have .DRILLED_HOLES" ) );
2293 if( !comments.empty() )
2295 std::list<std::string>::iterator its = comments.begin();
2296 std::list<std::string>::iterator ite = comments.end();
2312 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2313 "invalid IDF file\n"
2314 "* Violation of specification: expecting .BOARD_OUTLINE, have .NOTES" ) );
2319 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2320 "invalid IDFv2 file\n"
2321 "* Violation of specification: NOTES section not in specification" ) );
2326 if( !comments.empty() )
2328 std::list<std::string>::iterator its = comments.begin();
2329 std::list<std::string>::iterator ite = comments.end();
2345 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2346 "invalid IDF file\n"
2347 "* Violation of specification: expecting .BOARD_OUTLINE, have .PLACEMENT" ) );
2352 if( !comments.empty() )
2354 std::list<std::string>::iterator its = comments.begin();
2355 std::list<std::string>::iterator ite = comments.end();
2376 brd.exceptions ( std::ios_base::badbit );
2381 ostr <<
"\n* could not open file: '" << aFileName <<
"'";
2383 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
2386 brd.imbue( std::locale(
"C" ) );
2420 ostr <<
"\n* empty IDF file: '" << aFileName <<
"'";
2422 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
2431 while( !
FetchIDFLine( brd, iline, isComment, pos ) && brd.good() );
2434 if( ( !brd.good() && !brd.eof() ) || iline.empty() )
2439 ERROR_IDF <<
"[warning]: trailing comments after PLACEMENT\n";
2444 ostr <<
"\n* problems reading file: '" << aFileName <<
"'";
2446 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2447 "invalid IDF file\n"
2448 "* Violation of specification: non-comment lines after PLACEMENT section" ) );
2453 catch(
const std::exception& )
2455 brd.exceptions ( std::ios_base::goodbit );
2467 if( aBoard ==
nullptr )
2469 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2470 "\n* BUG: invoked with nullptr reference aBoard" ) );
2473 std::list< std::string > comments;
2480 bool quoted =
false;
2488 catch( std::bad_alloc& )
2490 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"\n* memory allocation failure" ) );
2493 while( aLibFile.good() )
2495 while( !
FetchIDFLine( aLibFile, iline, isComment, pos ) && aLibFile.good() );
2497 if( !aLibFile.good() && !aLibFile.eof() )
2500 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"problems reading library section" ) );
2512 comments.push_back( iline );
2522 ostr <<
"invalid IDF library\n";
2523 ostr <<
"* Violation of specification: quoted string where .ELECTRICAL or .MECHANICAL expected\n";
2524 ostr <<
"* line: '" << iline <<
"'\n";
2525 ostr <<
"* pos: " << pos;
2528 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
2535 if( !comments.empty() )
2537 std::list<std::string>::iterator its = comments.begin();
2538 std::list<std::string>::iterator ite = comments.end();
2549 if( cop ==
nullptr )
2563 ostr <<
"invalid IDF library\n";
2564 ostr <<
"duplicate Component Outline: '" << pout->
GetUID() <<
"'\n";
2565 ostr <<
"* Violation of specification: multiple outlines have the same GEOM and PART name\n";
2566 ostr <<
"* line: '" << iline <<
"'\n";
2567 ostr <<
"* pos: " << pos;
2570 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
2578 ostr <<
"invalid IDF library\n";
2579 ostr <<
"* Expecting .ELECTRICAL or .MECHANICAL, got '" << token <<
"'\n";
2580 ostr <<
"* line: '" << iline <<
"'\n";
2581 ostr <<
"* pos: " << pos;
2584 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
2590 if( !aLibFile.eof() )
2591 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"problems reading IDF library file" ) );
2602 bool quoted =
false;
2606 while( !
FetchIDFLine( aLibFile, iline, isComment, pos ) && aLibFile.good() );
2608 if( !aLibFile.good() )
2610 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2611 "invalid IDF library file\n"
2612 "* premature end of file (no HEADER)" ) );
2617 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2618 "invalid IDF library file\n"
2619 "* Violation of specification: first line must be .HEADER" ) );
2624 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2625 "invalid IDF library file\n"
2626 "* Violation of specification:\n"
2627 "* first line must be .HEADER and have no quotes or trailing text" ) );
2636 while( !
FetchIDFLine( aLibFile, iline, isComment, pos ) && aLibFile.good() );
2638 if( !aLibFile.good() )
2640 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2641 "invalid IDF library file\n"
2642 "* premature end of HEADER" ) );
2647 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2648 "invalid IDF library file\n"
2649 "* Violation of specification: comment within .HEADER section" ) );
2657 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2658 "invalid IDF library file\n"
2659 "* Violation of specification:\n"
2660 "* file Type in HEADER section must not be in quotes" ) );
2666 ostr <<
"invalid IDF library\n";
2667 ostr <<
"* Expecting string: LIBRARY_FILE (got '" << token <<
"')\n";
2669 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
2674 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2675 "invalid IDF library file\n"
2676 "* Violation of specification: HEADER section, RECORD 2: no FIELD 2" ) );
2681 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2682 "invalid IDF library file\n"
2683 "* Violation of specification: IDF Version must not be in quotes" ) );
2686 if( !token.compare(
"3.0" ) || !token.compare(
"3." ) || !token.compare(
"3" ) )
2690 else if( !token.compare(
"2.0" ) || !token.compare(
"2." ) || !token.compare(
"2" ) )
2698 ostr <<
"unsupported IDF version\n";
2699 ostr <<
"* Expecting version to be a variant of '3.0', '2.0' (value: '" << token <<
"')\n";
2701 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
2706 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2707 "invalid IDF library file\n"
2708 "* Violation of specification:\n"
2709 "* HEADER section, RECORD 2, FIELD 3: no Source System string" ) );
2716 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2717 "invalid IDF library file\n"
2718 "* Violation of specification:\n"
2719 "* HEADER section, RECORD 2, FIELD 4: no Date string" ) );
2726 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2727 "invalid IDF library file\n"
2728 "* Violation of specification:\n"
2729 "* HEADER section, RECORD 2, FIELD 5: no Board File Version number" ) );
2732 std::istringstream istr;
2739 ERROR_IDF <<
"invalid Library File Version in header\n";
2740 cerr <<
"* Setting default version of 1\n";
2746 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2747 "invalid IDF library file\n"
2748 "* Violation of specification:\n"
2749 "* HEADER section, RECORD 2, FIELD 5: Library File Version must not be in quotes" ) );
2754 while( !
FetchIDFLine( aLibFile, iline, isComment, pos ) && aLibFile.good() );
2756 if( ( !aLibFile.good() && !aLibFile.eof() ) || iline.empty() )
2757 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"problems reading library header, RECORD 3" ) );
2761 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
2762 "invalid IDF library file\n"
2763 "* Violation of specification: comment within .HEADER section" ) );
2769 ostr <<
"invalid IDF header\n";
2770 ostr <<
"* Violation of specification: expected .END_HEADER (got '" << iline <<
"')\n";
2772 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
2785 lib.exceptions ( std::ios_base::badbit );
2790 ostr <<
"\n* could not open file: '" << aFileName <<
"'";
2792 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
2795 lib.imbue( std::locale(
"C" ) );
2802 catch(
const std::exception& )
2804 lib.exceptions ( std::ios_base::goodbit );
2819 wxFileName brdname( aFullFileName );
2820 wxFileName libname( aFullFileName );
2821 wxString ext = brdname.GetExt();
2823 if( !ext.Cmp( wxT(
"EMN" ) ) )
2825 libname.SetExt( wxT(
"EMP" ) );
2827 else if( !ext.Cmp( wxT(
"emn" ) ) )
2829 libname.SetExt( wxT(
"emp" ) );
2834 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
2835 ostr <<
"* [INFO] invalid file name: '" << aFullFileName.ToUTF8() <<
"'";
2841 brdname.SetExt( wxT(
"emn" ) );
2843 std::string bfname =
TO_UTF8( aFullFileName );
2845 if( !wxFileExists( bfname ) )
2847 brdname.SetExt( wxT(
"EMN" ) );
2848 libname.SetExt( wxT(
"EMP" ) );
2853 if( !brdname.IsOk() )
2856 ostr <<
"\n* invalid file name: '" << aFullFileName.ToUTF8() <<
"'";
2858 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
2861 if( !brdname.FileExists() )
2864 ostr <<
"\n* no such file: '" << aFullFileName.ToUTF8() <<
"'";
2866 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
2869 if( !brdname.IsFileReadable() )
2872 ostr <<
"\n* cannot read file: '" << bfname <<
"'";
2874 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
2877 bfname =
TO_UTF8( brdname.GetFullPath() );
2878 std::string lfname =
TO_UTF8( libname.GetFullPath() );
2880 if( !libname.FileExists() )
2886 cerr <<
"no associated library file (*.emp)\n";
2888 else if( !libname.IsFileReadable() )
2891 ostr <<
"\n* cannot read library file: '" << lfname <<
"'";
2893 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
2904 catch(
const std::exception& e )
2922 lib.exceptions( std::ios_base::failbit );
2927 ostr <<
"\n* could not open file: '" << aFileName <<
"'";
2929 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
2932 lib.imbue( std::locale(
"C" ) );
2933 wxDateTime tdate( time(
nullptr ) );
2938 ostringstream fileDate;
2939 fileDate << setfill(
'0' ) << setw(4) << tdate.GetYear();
2940 fileDate <<
"/" << setw(2) << tdate.GetMonth() <<
"/" << tdate.GetDay();
2941 fileDate <<
"." << tdate.GetHour() <<
":" << tdate.GetMinute() <<
":" << tdate.GetSecond();
2945 lib <<
"LIBRARY_FILE 3.0 \"Created by " <<
m_idfSource;
2947 lib <<
".END_HEADER\n\n";
2954 its->second->writeData( lib );
2959 catch(
const std::exception& )
2961 lib.exceptions( std::ios_base::goodbit );
2977 brd.exceptions( std::ostream::failbit );
2982 ostr <<
"\n* could not open file: '" << aFileName <<
"'";
2984 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
2987 brd.imbue( std::locale(
"C" ) );
2988 wxDateTime tdate( time(
nullptr ) );
2993 ostringstream fileDate;
2994 fileDate << setfill(
'0' ) << setw(4) << tdate.GetYear();
2995 fileDate <<
"/" << setw(2) << tdate.GetMonth() <<
"/" << tdate.GetDay();
2996 fileDate <<
"." << tdate.GetHour() <<
":" << tdate.GetMinute() <<
":" << tdate.GetSecond();
3000 brd <<
"BOARD_FILE 3.0 \"Created by " <<
m_idfSource;
3004 brd <<
"\"BOARD WITH NO NAME\" ";
3008 brd << setw(1) << setfill(
' ' );
3015 brd <<
".END_HEADER\n\n";
3023 std::map<std::string, OTHER_OUTLINE*>::iterator its =
m_otherOutlines.begin();
3024 std::map<std::string, OTHER_OUTLINE*>::iterator ite =
m_otherOutlines.end();
3028 its->second->writeData( brd );
3042 (*its)->writeData( brd );
3056 (*its)->writeData( brd );
3070 (*its)->writeData( brd );
3084 (*its)->writeData( brd );
3098 (*its)->writeData( brd );
3107 std::multimap<std::string, GROUP_OUTLINE*>::iterator its =
m_groupOutlines.begin();
3108 std::multimap<std::string, GROUP_OUTLINE*>::iterator ite =
m_groupOutlines.end();
3112 its->second->writeData( brd );
3124 while( itds != itde )
3126 brd <<
"# " << *itds <<
"\n";
3130 brd <<
".DRILLED_HOLES\n";
3132 std::list<IDF_DRILL_DATA*>::iterator itbs =
m_drills.begin();
3133 std::list<IDF_DRILL_DATA*>::iterator itbe =
m_drills.end();
3135 while( itbs != itbe )
3137 (*itbs)->write( brd,
m_unit );
3141 std::map<std::string, IDF3_COMPONENT*>::iterator itcs =
m_components.begin();
3142 std::map<std::string, IDF3_COMPONENT*>::iterator itce =
m_components.end();
3144 while( itcs != itce )
3146 itcs->second->writeDrillData( brd );
3150 brd <<
".END_DRILLED_HOLES\n\n";
3159 while( itncs != itnce )
3161 brd <<
"# " << *itncs <<
"\n";
3167 std::list<IDF_NOTE*>::iterator itns =
m_notes.begin();
3168 std::list<IDF_NOTE*>::iterator itne =
m_notes.end();
3170 while( itns != itne )
3172 (*itns)->writeNote( brd,
m_unit );
3176 brd <<
".END_NOTES\n\n";
3186 while( itpcs != itpce )
3188 brd <<
"# " << *itpcs <<
"\n";
3192 std::map< std::string, IDF3_COMPONENT*>::iterator itcs =
m_components.begin();
3193 std::map< std::string, IDF3_COMPONENT*>::iterator itce =
m_components.end();
3200 bool hasOutlines =
false;
3202 while( itcs != itce )
3204 if( itcs->second->GetOutlinesSize() > 0 )
3216 brd <<
".PLACEMENT\n";
3218 while( itcs != itce )
3220 itcs->second->writePlaceData( brd );
3224 brd <<
".END_PLACEMENT\n";
3230 catch(
const std::exception& )
3232 brd.exceptions( std::ios_base::goodbit );
3245 wxFileName brdname( aFullFileName );
3246 wxFileName libname( aFullFileName );
3251 std::string bfname =
TO_UTF8( aFullFileName );
3255 if( !brdname.IsOk() )
3259 aReporter->
Report( wxString::Format(
_(
"Invalid output path: %s" ), brdname.GetFullPath() ),
3266 if( brdname.FileExists() && !brdname.IsFileWritable() )
3270 aReporter->
Report( wxString::Format(
_(
"Cannot overwrite file: %s" ), brdname.GetFullPath() ),
3277 bfname =
TO_UTF8( brdname.GetFullPath() );
3278 std::string lfname =
TO_UTF8( libname.GetFullPath() );
3280 if( libname.FileExists() && !libname.IsFileWritable() )
3284 aReporter->
Report( wxString::Format(
_(
"Cannot overwrite file: %s" ), libname.GetFullPath() ),
3294 catch(
const std::exception& e )
3313 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
3314 ostr <<
"* board version (" << aVersion <<
") must be >= 0";
3331 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
3332 ostr <<
"* library version (" << aVersion <<
") must be >= 0";
3346 if( aScaleFactor == 0.0 )
3349 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
3350 ostr <<
"* BUG: user scale factor must not be 0";
3363 if( aPrecision < 1 || aPrecision > 8 )
3366 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
3367 ostr <<
"* precision value (" << aPrecision <<
") must be 1..8";
3437 const std::string& aHoleType,
3444 drill =
new IDF_DRILL_DATA( aDia, aXpos, aYpos, aPlating,
"BOARD", aHoleType, aOwner );
3446 catch( std::bad_alloc& )
3467 m_drills.push_back( aDrilledHole );
3468 return aDrilledHole;
3479 std::list<IDF_DRILL_DATA*>::iterator sp =
m_drills.begin();
3480 std::list<IDF_DRILL_DATA*>::iterator ep =
m_drills.end();
3485 if( (*sp)->Matches( aDia, aXpos, aYpos ) )
3487#ifndef DISABLE_IDF_OWNERSHIP
3501 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
3502 ostr <<
"* ownership violation; drill owner (";
3515 ostr <<
"invalid: " <<
static_cast<int>( keyo );
3519 ostr <<
") may not be modified by ";
3551 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
3552 ostr <<
"* slot width (" << aWidth <<
") must be >= " <<
IDF_MIN_DIA_MM;
3561 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
3562 ostr <<
"* slot length (" << aLength <<
") must be >= " <<
IDF_MIN_DIA_MM;
3571 double a1 = aOrientation / 180.0 *
M_PI;
3572 double a2 = a1 + M_PI_2;
3573 double d1 = aLength / 2.0;
3574 double d2 = aWidth / 2.0;
3575 double sa1 = sin( a1 );
3576 double ca1 = cos( a1 );
3577 double dsa2 = d2 * sin( a2 );
3578 double dca2 = d2 * cos( a2 );
3580 c[0].
x = aX + d1 * ca1;
3581 c[0].
y = aY + d1 * sa1;
3583 c[1].
x = aX - d1 * ca1;
3584 c[1].
y = aY - d1 * sa1;
3586 pt[0].
x = c[0].
x - dca2;
3587 pt[0].
y = c[0].
y - dsa2;
3589 pt[1].
x = c[1].
x - dca2;
3590 pt[1].
y = c[1].
y - dsa2;
3592 pt[2].
x = c[1].
x + dca2;
3593 pt[2].
y = c[1].
y + dsa2;
3595 pt[3].
x = c[0].
x + dca2;
3596 pt[3].
y = c[0].
y + dsa2;
3604 catch( std::bad_alloc& )
3607 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
3608 ostr <<
"* could not create an outline object";
3616 outline->
push( seg );
3619 seg =
new IDF_SEGMENT( c[1], pt[1], -180.0,
true );
3620 outline->
push( seg );
3624 outline->
push( seg );
3627 seg =
new IDF_SEGMENT( c[0], pt[3], -180.0,
true );
3628 outline->
push( seg );
3642 const std::string& aHoleType,
3644 const std::string& aRefDes )
3654 std::string refdes = aRefDes;
3659 if( refdes.empty() )
3660 refdes =
"NOREFDES";
3664 return AddBoardDrill( aDia, aXpos, aYpos, aPlating, aHoleType, aOwner );
3669 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
3670 ostr <<
"* PANEL data not supported";
3676 std::map<std::string, IDF3_COMPONENT*>::iterator ref =
m_components.find( refdes );
3686 catch( std::bad_alloc& )
3689 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
3690 ostr <<
"* could not create new component object";
3696 comp->SetParent(
this );
3697 comp->SetRefDes( refdes );
3702 IDF_DRILL_DATA* dp = ref->second->AddDrill( aDia, aXpos, aYpos, aPlating, aHoleType, aOwner );
3719 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"(): nullptr pointer";
3728 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
3729 ostr <<
"* PANEL data not supported";
3745 catch( std::bad_alloc& )
3748 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
3749 ostr <<
"* could not create new component object";
3755 comp->SetParent(
this );
3776 std::map<std::string, IDF3_COMPONENT*>::iterator ref =
m_components.find( aRefDes );
3781 if( !ref->second->DelDrill( aDia, aXpos, aYpos ) )
3796 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__;
3797 ostr <<
"(): Invalid component pointer (nullptr)";
3806 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"(): \n";
3807 ostr <<
"* duplicate RefDes ('" << aComponent->
GetRefDes() <<
"')";
3821#ifndef DISABLE_IDF_OWNERSHIP
3843 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"(): \n";
3844 ostr <<
"* aIndex (" << aIndex <<
") out of range (" <<
m_components.size() <<
")";
3850 std::map<std::string, IDF3_COMPONENT*>::iterator it =
m_components.begin();
3852 while( aIndex-- > 0 ) ++it;
3854#ifndef DISABLE_IDF_OWNERSHIP
3880 std::map<std::string, IDF3_COMPONENT*>::iterator it =
m_components.find( aRefDes );
3891 std::string fname =
TO_UTF8( aFullFileName );
3892 wxFileName idflib( aFullFileName );
3894 if( !idflib.IsOk() )
3897 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"(): \n";
3898 cerr <<
"* invalid file name: '" << fname <<
"'";
3904 if( !idflib.FileExists() )
3907 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"(): \n";
3908 cerr <<
"* no such file: '" << fname <<
"'";
3914 if( !idflib.IsFileReadable() )
3917 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"(): \n";
3918 cerr <<
"* cannot read file: '" << fname <<
"'";
3924 std::map<std::string, std::string>::iterator itm =
m_uidFileList.find( fname );
3935 catch( std::bad_alloc& )
3938 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"(): \n";
3939 cerr <<
"* failed to create outline\n";
3940 cerr <<
"* filename: '" << fname <<
"'";
3950 model.exceptions ( std::ios_base::badbit );
3955 ostr <<
"\n* could not open file: '" << fname <<
"'";
3957 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
3960 model.imbue( std::locale(
"C" ) );
3972 ostr <<
"\n* problems reading file: '" << fname <<
"'";
3973 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
3991 ostr <<
"faulty IDF component definition\n";
3992 ostr <<
"* Expecting .ELECTRICAL or .MECHANICAL, got '" << iline <<
"'\n";
3993 cerr <<
"* File: '" << fname <<
"'\n";
3995 throw(
IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
3999 catch(
const std::exception& e )
4002 model.exceptions ( std::ios_base::goodbit );
4011 std::list<std::string>::iterator lsts =
m_uidLibList.begin();
4012 std::list<std::string>::iterator lste =
m_uidLibList.end();
4013 std::string uid = cp->
GetUID();
4016 while( lsts != lste )
4018 if( ! lsts->compare( uid ) )
4037 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
4038 ostr <<
"* duplicate UID for different Component Outlines: '" << uid <<
"'\n";
4039 ostr <<
"* original loaded from library, duplicate in current file\n";
4040 ostr <<
"* file: '" << fname <<
"'";
4053 if( oldp ==
nullptr )
4077 std::map<std::string, std::string>::iterator ufls =
m_uidFileList.begin();
4078 std::map<std::string, std::string>::iterator ufle =
m_uidFileList.end();
4079 std::string oldfname;
4081 while( ufls != ufle )
4083 if( ! ufls->second.compare( uid ) )
4085 oldfname = ufls->first;
4093 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
4094 ostr <<
"* duplicate UID for different Component Outlines: '" << uid <<
"'\n";
4095 ostr <<
"* original file: '" << oldfname <<
"'\n";
4096 ostr <<
"* this file: '" << fname <<
"'";
4105 std::map< std::string, IDF3_COMP_OUTLINE*>::iterator its =
m_componentOutlines.find( aComponentID );
4115 const std::string& aPartName )
4126 catch( std::bad_alloc& )
4129 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"(): \n";
4130 cerr <<
"could not create new outline";
4145 const std::string& aPartName )
4150 if( aGeomName.empty() && aPartName.empty() )
4152 uid =
"NOGEOM_NOPART";
4157 uid = aGeomName +
"_" + aPartName;
4169 catch( std::bad_alloc& )
4172 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"(): ";
4173 cerr <<
"could not create new outline";
4222 std::list<IDF_DRILL_DATA*>::iterator ds =
m_drills.begin();
4223 std::list<IDF_DRILL_DATA*>::iterator de =
m_drills.end();
4238 std::map<std::string, IDF3_COMPONENT*>::iterator cs =
m_components.begin();
4239 std::map<std::string, IDF3_COMPONENT*>::iterator ce =
m_components.end();
4270 std::map<std::string, OTHER_OUTLINE*>::iterator os =
m_otherOutlines.begin();
4271 std::map<std::string, OTHER_OUTLINE*>::iterator oe =
m_otherOutlines.end();
4366 std::multimap<std::string, GROUP_OUTLINE*>::iterator os =
m_groupOutlines.begin();
4367 std::multimap<std::string, GROUP_OUTLINE*>::iterator oe =
m_groupOutlines.end();
IDF_OUTLINE * GetOutline(size_t aIndex)
Return a pointer to the outline as specified by aIndex.
size_t OutlinesSize(void)
virtual bool SetUnit(IDF3::IDF_UNIT aUnit)
Function SetUnit sets the native unit of the outline; except for component outlines this must be the ...
void AddComment(const std::string &aComment)
Add a comment to the outline data.
Regions and layers in which user-specified features or components may be placed.
virtual void readData(std::istream &aBoardFile, const std::string &aHeader, IDF3::IDF_VERSION aIdfVersion) override
Read GROUP_OUTLINE data from an open IDFv3 file.
virtual const std::string & GetGroupName(void)
Return a reference to the (non-unique) group name.
void GetUserOffset(double &aXoff, double &aYoff)
bool WriteFile(const wxString &aFullFileName, IDF3::IDF_UNIT aUnits, REPORTER *aReporter=nullptr)
std::list< std::string > m_uidLibList
std::list< IDF_DRILL_DATA * > m_drills
void readLibFile(const std::string &aFileName)
void readLibSection(std::istream &aLibFile, IDF3::FILE_STATE &aLibState, IDF3_BOARD *aBoard)
std::list< VIA_KO_OUTLINE * > m_viaKeepoutOutlines
bool SetBoardThickness(double aBoardThickness)
bool SetLibraryVersion(int aVersion)
std::map< std::string, OTHER_OUTLINE * > m_otherOutlines
bool setUnit(IDF3::IDF_UNIT aUnit, bool convert=false)
std::list< std::string > m_placeComments
IDF3_COMP_OUTLINE * GetComponentOutline(const wxString &aFullFileName)
const std::string & GetNewRefDes(void)
std::map< std::string, IDF3_COMP_OUTLINE * > m_componentOutlines
std::list< IDF_NOTE * > m_notes
bool writeLibFile(const std::string &aFileName)
void SetUserOffset(double aXoff, double aYoff)
void readBrdNotes(std::istream &aBoardFile, IDF3::FILE_STATE &aBoardState)
std::map< std::string, std::string > m_uidFileList
std::list< PLACE_OUTLINE * > m_placeOutlines
std::list< ROUTE_KO_OUTLINE * > m_routeKeepoutOutlines
IDF3::CAD_TYPE GetCadType(void)
std::string m_refDesString
std::multimap< std::string, GROUP_OUTLINE * > m_groupOutlines
bool DelBoardOutline(IDF_OUTLINE *aOutline)
IDF_DRILL_DATA * AddBoardDrill(double aDia, double aXpos, double aYpos, IDF3::KEY_PLATING aPlating, const std::string &aHoleType, IDF3::KEY_OWNER aOwner)
IDF3::IDF_VERSION m_idfVer
bool ReadFile(const wxString &aFullFileName, bool aNoSubstituteOutlines=false)
bool delCompDrill(double aDia, double aXpos, double aYpos, const std::string &aRefDes)
void writeBoardFile(const std::string &aFileName)
std::map< std::string, IDF3_COMPONENT * > * GetComponents(void)
IDF3_COMPONENT * FindComponent(const std::string &aRefDes)
IDF_DRILL_DATA * AddDrill(IDF_DRILL_DATA *aDrilledHole)
void readBrdHeader(std::istream &aBoardFile, IDF3::FILE_STATE &aBoardState)
size_t GetComponentsSize(void)
double GetBoardThickness(void)
void readLibHeader(std::istream &aLibFile, IDF3::FILE_STATE &aLibState)
bool AddComponent(IDF3_COMPONENT *aComponent)
void readBrdDrills(std::istream &aBoardFile, IDF3::FILE_STATE &aBoardState)
size_t GetBoardOutlinesSize(void)
bool SetUserScale(double aScaleFactor)
std::list< ROUTE_OUTLINE * > m_routeOutlines
bool checkComponentOwnership(int aSourceLine, const char *aSourceFunc, IDF3_COMPONENT *aComponent)
void readBoardFile(const std::string &aFileName, bool aNoSubstituteOutlines)
void readBrdPlacement(std::istream &aBoardFile, IDF3::FILE_STATE &aBoardState, bool aNoSubstituteOutlines)
void readBrdSection(std::istream &aBoardFile, IDF3::FILE_STATE &aBoardState, bool aNoSubstituteOutlines)
IDF3::IDF_UNIT GetUnit(void) const
bool SetUserPrecision(int aPrecision)
std::list< PLACE_KO_OUTLINE * > m_placeKeepoutOutlines
bool DelBoardDrill(double aDia, double aXpos, double aYpos)
BOARD_OUTLINE m_boardOutline
IDF3_BOARD(IDF3::CAD_TYPE aCadType)
IDF3_COMP_OUTLINE * GetInvalidOutline(const std::string &aGeomName, const std::string &aPartName)
std::list< std::string > m_drillComments
bool DelComponent(IDF3_COMPONENT *aComponent)
bool AddSlot(double aWidth, double aLength, double aOrientation, double aX, double aY)
bool SetBoardVersion(int aVersion)
bool AddBoardOutline(IDF_OUTLINE *aOutline)
std::map< std::string, IDF3_COMPONENT * > m_components
IDF_DRILL_DATA * addCompDrill(double aDia, double aXpos, double aYpos, IDF3::KEY_PLATING aPlating, const std::string &aHoleType, IDF3::KEY_OWNER aOwner, const std::string &aRefDes)
std::list< std::string > m_noteComments
const std::list< IDF3_COMP_OUTLINE_DATA * > * GetOutlinesData(void)
IDF3::IDF_PLACEMENT placement
const std::string & GetRefDes(void)
Retrieve the Reference Designator (RefDes) of this component.
bool SetPlacement(IDF3::IDF_PLACEMENT aPlacementValue)
Set the placement value of the component subject to ownership rules.
bool writeDrillData(std::ostream &aBoardFile)
Write the internal drill data to an IDFv3 .DRILLED_HOLES section.
bool DeleteOutlineData(IDF3_COMP_OUTLINE_DATA *aComponentOutline)
Remove outline data based on the pointer provided.
std::list< IDF_DRILL_DATA * > drills
IDF3_COMPONENT(IDF3_BOARD *aParent)
Set the parent object and initializes other internal parameters to default values.
bool SetPosition(double aXpos, double aYpos, double aAngle, IDF3::IDF_LAYER aLayer)
Set the internal position parameters and returns true if the position was set, false if the position ...
std::list< IDF3_COMP_OUTLINE_DATA * > components
const std::list< IDF_DRILL_DATA * > * GetDrills(void)
Return the internal list of drills.
bool SetRefDes(const std::string &aRefDes)
Set the Reference Designator (RefDes) of this component.
void SetParent(IDF3_BOARD *aParent)
Set the parent object.
IDF3::IDF_UNIT GetUnit(void)
IDF3::CAD_TYPE GetCadType(void)
bool hasPosition
True after SetPosition is called once.
bool checkOwnership(int aSourceLine, const char *aSourceFunc)
bool writePlaceData(std::ostream &aBoardFile)
Write the component placement data to an IDFv3 .PLACEMENT section.
IDF_DRILL_DATA * AddDrill(double aDia, double aXpos, double aYpos, IDF3::KEY_PLATING aPlating, const std::string &aHoleType, IDF3::KEY_OWNER aOwner)
Add a drill entry to the component and returns its pointer.
std::string refdes
Reference Description (MUST BE UNIQUE)
size_t GetOutlinesSize(void)
bool GetPosition(double &aXpos, double &aYpos, double &aAngle, IDF3::IDF_LAYER &aLayer)
Retrieve the internal position parameters and returns true if the position was previously set,...
bool DelDrill(double aDia, double aXpos, double aYpos)
Delete a drill entry based on its size and location.
IDF3::IDF_PLACEMENT GetPlacement(void)
bool AddOutlineData(IDF3_COMP_OUTLINE_DATA *aComponentOutline)
Add the given component outline data to this component.
bool checkOwnership(int aSourceLine, const char *aSourceFunc)
bool readPlaceData(std::istream &aBoardFile, IDF3::FILE_STATE &aBoardState, IDF3_BOARD *aBoard, IDF3::IDF_VERSION aIdfVersion, bool aNoSubstituteOutlines)
Read placement data from an open IDFv3 file.
void GetOffsets(double &aXoff, double &aYoff, double &aZoff, double &aAngleOff)
Retrieve the position and orientation of this outline item in relation to its parent.
IDF3_COMP_OUTLINE * outline
void writePlaceData(std::ostream &aBoardFile, double aXpos, double aYpos, double aAngle, const std::string &aRefDes, IDF3::IDF_PLACEMENT aPlacement, IDF3::IDF_LAYER aSide)
Write RECORD 2 and RECORD 3 of a PLACEMENT section as per IDFv3 specification.
IDF3_COMP_OUTLINE_DATA()
Create an object with default settings and no parent or associated outline.
~IDF3_COMP_OUTLINE_DATA()
void SetParent(IDF3_COMPONENT *aParent)
Set the parent object.
bool SetOutline(IDF3_COMP_OUTLINE *aOutline)
Set the outline whose position is managed by this object.
bool SetOffsets(double aXoff, double aYoff, double aZoff, double aAngleOff)
Set the position and orientation of this outline item in relation to its parent.
friend class IDF3_COMPONENT
A component's outline as stored in an IDF library file.
void SetPartName(const std::string &aPartName)
Set the Part Name (Part Number, IDFv3 spec) of the component outline.
const std::string & GetUID(void)
virtual void readData(std::istream &aLibFile, const std::string &aHeader, IDF3::IDF_VERSION aIdfVersion) override
Read a component outline from an open IDFv3 file.
IDF3::COMP_TYPE GetComponentClass(void)
bool CreateDefaultOutline(const std::string &aGeom, const std::string &aPart)
Create a default outline with the given Geometry and Part names.
void SetGeomName(const std::string &aGeomName)
Set the Geometry Name (Package Name, IDFv3 spec) of the component outline.
int incrementRef(void)
Increment the internal reference counter to keep track of the number of components referring to this ...
const std::string & GetDrillRefDes()
bool read(std::istream &aBoardFile, IDF3::IDF_UNIT aBoardUnit, IDF3::FILE_STATE aBoardState, IDF3::IDF_VERSION aIdfVersion)
Read a drill entry from an IDFv3 file.
An entry in the NOTE section of an IDF file.
bool readNote(std::istream &aBoardFile, IDF3::FILE_STATE &aBoardState, IDF3::IDF_UNIT aBoardUnit)
Read a note entry from an IDFv3 file.
A segment and winding information for an IDF outline.
std::list< IDF_SEGMENT * >::iterator end()
std::list< IDF_SEGMENT * >::iterator begin()
bool push(IDF_SEGMENT *item)
Add a segment to the internal segment list.
A point as used by the various IDF related classes.
A segment as used in IDFv3 outlines.
Miscellaneous extrusions on the board.
virtual void readData(std::istream &aBoardFile, const std::string &aHeader, IDF3::IDF_VERSION aIdfVersion) override
Read an OTHER_OUTLINE data from an IDFv3 file.
virtual const std::string & GetOutlineIdentifier(void)
Function GetOutlineIdentifier returns the object's Outline Identifier.
Regions and layers in which no component may be placed or on which a maximum component height is in e...
Area on the board for placing components.
virtual void readData(std::istream &aBoardFile, const std::string &aHeader, IDF3::IDF_VERSION aIdfVersion) override
Read PLACE_OUTLINE data from an open IDFv3 file.
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Regions and layers where no electrical routing is permitted.
Routing areas on the board.
virtual void readData(std::istream &aBoardFile, const std::string &aHeader, IDF3::IDF_VERSION aIdfVersion) override
Read ROUTE_OUTLINE data from an IDFv3 file.
Region in which vias are prohibited.
static bool empty(const wxTextEntryBase *aCtrl)
static const std::string IdfV3LibraryFileExtension
static const std::string IdfV3BoardFileExtension
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
static bool MatchCompOutline(IDF3_COMP_OUTLINE *aOutlineA, IDF3_COMP_OUTLINE *aOutlineB)
std::string GetPlacementString(IDF3::IDF_PLACEMENT aPlacement)
Return a string representing the given IDF Placement type.
FILE_STATE
State values for the IDF parser's input.
KEY_PLATING
The plating condition of a hole.
IDF_PLACEMENT
The placement status of a component.
bool GetIDFString(const std::string &aLine, std::string &aIDFString, bool &hasQuotes, int &aIndex)
Parse a line retrieved via FetchIDFLine() and returns the first IDF string found from the starting po...
CAD_TYPE
The class of CAD program which is opening or modifying a file.
bool FetchIDFLine(std::istream &aModel, std::string &aLine, bool &isComment, std::streampos &aFilePos)
Retrieve a single line from an IDF file and performs minimal processing.
IDF_VERSION
The supported IDF versions (3.0 and 2.0 ONLY).
IDF_UNIT
The native unit of the board and of component outlines.
bool CompareToken(const char *aTokenString, const std::string &aInputString)
Perform a case-insensitive comparison of a token string and an input string.
IDF_LAYER
The various IDF layer classes and groupings.
KEY_OWNER
The type of CAD which has ownership an object.
bool WriteLayersText(std::ostream &aBoardFile, IDF3::IDF_LAYER aLayer)
Write out text corresponding to the given IDF Layer type.
std::string GetLayerString(IDF3::IDF_LAYER aLayer)
Return a string representing the given IDF Layer type.
#define OPEN_OSTREAM(var, name)
#define CLOSE_STREAM(var)
#define OPEN_ISTREAM(var, name)
Definition of file extensions used in Kicad.