diff --git a/common/drawing_sheet/ds_data_model_io.cpp b/common/drawing_sheet/ds_data_model_io.cpp index 714b857653..ca2c175a13 100644 --- a/common/drawing_sheet/ds_data_model_io.cpp +++ b/common/drawing_sheet/ds_data_model_io.cpp @@ -56,17 +56,17 @@ public: void Format( DS_DATA_MODEL* aSheet ) const; void Format( DS_DATA_MODEL* aModel, std::vector<DS_DATA_ITEM*>& aItemsList ) const; - void Format( DS_DATA_MODEL* aModel, DS_DATA_ITEM* aItem, int aNestLevel ) const; + void Format( DS_DATA_MODEL* aModel, DS_DATA_ITEM* aItem ) const; protected: DS_DATA_MODEL_IO() { m_out = NULL; } virtual ~DS_DATA_MODEL_IO() {} private: - void format( DS_DATA_ITEM_TEXT* aItem, int aNestLevel ) const; - void format( DS_DATA_MODEL* aModel, DS_DATA_ITEM* aItem, int aNestLevel ) const; - void format( DS_DATA_ITEM_POLYGONS* aItem, int aNestLevel ) const; - void format( DS_DATA_ITEM_BITMAP* aItem, int aNestLevel ) const; + void format( DS_DATA_ITEM_TEXT* aItem ) const; + void format( DS_DATA_MODEL* aModel, DS_DATA_ITEM* aItem ) const; + void format( DS_DATA_ITEM_POLYGONS* aItem ) const; + void format( DS_DATA_ITEM_BITMAP* aItem ) const; void formatCoordinate( const char* aToken, POINT_COORD& aCoord ) const; void formatRepeatParameters( DS_DATA_ITEM* aItem ) const; void formatOptions( DS_DATA_ITEM* aItem ) const; @@ -161,35 +161,36 @@ void DS_DATA_MODEL_IO::Format( DS_DATA_MODEL* aModel, std::vector<DS_DATA_ITEM*> { LOCALE_IO toggle; // switch on/off the locale "C" notation - m_out->Print( 0, "(kicad_wks (version %d) (generator \"pl_editor\") (generator_version \"%s\")\n", - SEXPR_WORKSHEET_FILE_VERSION, GetMajorMinorVersion().c_str().AsChar() ); + m_out->Print( "(kicad_wks (version %d) (generator \"pl_editor\") (generator_version %s)", + SEXPR_WORKSHEET_FILE_VERSION, + m_out->Quotew( GetMajorMinorVersion() ).c_str() ); for( DS_DATA_ITEM* item : aItemsList ) - Format( aModel, item, 1 ); + Format( aModel, item ); - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); } -void DS_DATA_MODEL_IO::Format( DS_DATA_MODEL* aModel, DS_DATA_ITEM* aItem, int aNestLevel ) const +void DS_DATA_MODEL_IO::Format( DS_DATA_MODEL* aModel, DS_DATA_ITEM* aItem ) const { switch( aItem->GetType() ) { case DS_DATA_ITEM::DS_TEXT: - format( (DS_DATA_ITEM_TEXT*) aItem, aNestLevel ); + format( (DS_DATA_ITEM_TEXT*) aItem ); break; case DS_DATA_ITEM::DS_SEGMENT: case DS_DATA_ITEM::DS_RECT: - format( aModel, aItem, aNestLevel ); + format( aModel, aItem ); break; case DS_DATA_ITEM::DS_POLYPOLYGON: - format( (DS_DATA_ITEM_POLYGONS*) aItem, aNestLevel ); + format( (DS_DATA_ITEM_POLYGONS*) aItem ); break; case DS_DATA_ITEM::DS_BITMAP: - format( (DS_DATA_ITEM_BITMAP*) aItem, aNestLevel ); + format( (DS_DATA_ITEM_BITMAP*) aItem ); break; default: @@ -202,49 +203,49 @@ void DS_DATA_MODEL_IO::Format( DS_DATA_MODEL* aSheet ) const { LOCALE_IO toggle; // switch on/off the locale "C" notation - m_out->Print( 0, "(kicad_wks (version %d) (generator \"pl_editor\") (generator_version \"%s\")\n", - SEXPR_WORKSHEET_FILE_VERSION, GetMajorMinorVersion().c_str().AsChar() ); + m_out->Print( "(kicad_wks (version %d) (generator \"pl_editor\") (generator_version %s)", + SEXPR_WORKSHEET_FILE_VERSION, + m_out->Quotew( GetMajorMinorVersion() ).c_str() ); // Setup - int nestLevel = 1; + // Write default values: - m_out->Print( nestLevel, "(setup " ); - m_out->Print( 0, "(textsize %s %s)", + m_out->Print( "(setup" ); + m_out->Print( "(textsize %s %s)", FormatDouble2Str( aSheet->m_DefaultTextSize.x ).c_str(), FormatDouble2Str( aSheet->m_DefaultTextSize.y ).c_str() ); - m_out->Print( 0, "(linewidth %s)", FormatDouble2Str( aSheet->m_DefaultLineWidth ).c_str() ); - m_out->Print( 0, "(textlinewidth %s)", FormatDouble2Str( aSheet->m_DefaultTextThickness ).c_str() ); - m_out->Print( 0, "\n" ); + m_out->Print( "(linewidth %s)", FormatDouble2Str( aSheet->m_DefaultLineWidth ).c_str() ); + m_out->Print( "(textlinewidth %s)", FormatDouble2Str( aSheet->m_DefaultTextThickness ).c_str() ); // Write margin values - m_out->Print( nestLevel, "(left_margin %s)", FormatDouble2Str( aSheet->GetLeftMargin() ).c_str() ); - m_out->Print( 0, "(right_margin %s)", FormatDouble2Str( aSheet->GetRightMargin() ).c_str() ); - m_out->Print( 0, "(top_margin %s)", FormatDouble2Str( aSheet->GetTopMargin() ).c_str() ); - m_out->Print( 0, "(bottom_margin %s)", FormatDouble2Str( aSheet->GetBottomMargin() ).c_str() ); - m_out->Print( 0, ")\n" ); + m_out->Print( "(left_margin %s)", FormatDouble2Str( aSheet->GetLeftMargin() ).c_str() ); + m_out->Print( "(right_margin %s)", FormatDouble2Str( aSheet->GetRightMargin() ).c_str() ); + m_out->Print( "(top_margin %s)", FormatDouble2Str( aSheet->GetTopMargin() ).c_str() ); + m_out->Print( "(bottom_margin %s)", FormatDouble2Str( aSheet->GetBottomMargin() ).c_str() ); + + m_out->Print( ")" ); // Save the graphical items on the drawing sheet for( unsigned ii = 0; ii < aSheet->GetCount(); ii++ ) { DS_DATA_ITEM* item = aSheet->GetItem( ii ); - Format( aSheet, item, nestLevel ); + Format( aSheet, item ); } - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); } -void DS_DATA_MODEL_IO::format( DS_DATA_ITEM_TEXT* aItem, int aNestLevel ) const +void DS_DATA_MODEL_IO::format( DS_DATA_ITEM_TEXT* aItem ) const { - m_out->Print( aNestLevel, "(tbtext" ); - m_out->Print( 0, " %s", m_out->Quotew( aItem->m_TextBase ).c_str() ); - m_out->Print( 0, " (name %s)", m_out->Quotew( aItem->m_Name ).c_str() ); + m_out->Print( "(tbtext %s", m_out->Quotew( aItem->m_TextBase ).c_str() ); + m_out->Print( "(name %s)", m_out->Quotew( aItem->m_Name ).c_str() ); formatCoordinate( getTokenName( T_pos ), aItem->m_Pos ); formatOptions( aItem ); if( aItem->m_Orient ) - m_out->Print( 0, " (rotate %s)", FormatDouble2Str( aItem->m_Orient ).c_str() ); + m_out->Print( "(rotate %s)", FormatDouble2Str( aItem->m_Orient ).c_str() ); // Write font info, only if it is not the default setup bool write_size = aItem->m_TextSize.x != 0.0 || aItem->m_TextSize.y != 0.0; @@ -254,172 +255,162 @@ void DS_DATA_MODEL_IO::format( DS_DATA_ITEM_TEXT* aItem, int aNestLevel ) const if( write_thickness || write_size || aItem->m_Bold || aItem->m_Italic || write_face || aItem->m_TextColor != COLOR4D::UNSPECIFIED ) { - m_out->Print( 0, " (font" ); + m_out->Print( "(font" ); if( write_face ) - m_out->Print( 0, " (face \"%s\")", aItem->m_Font->NameAsToken() ); + m_out->Print( "(face %s)", m_out->Quotew( aItem->m_Font->NameAsToken() ).c_str() ); if( write_thickness ) - m_out->Print( 0, " (linewidth %s)", FormatDouble2Str( aItem->m_LineWidth ).c_str() ); + m_out->Print( "(linewidth %s)", FormatDouble2Str( aItem->m_LineWidth ).c_str() ); if( write_size ) { - m_out->Print( 0, " (size %s %s)", + m_out->Print( "(size %s %s)", FormatDouble2Str( aItem->m_TextSize.x ).c_str(), FormatDouble2Str( aItem->m_TextSize.y ).c_str() ); } if( aItem->m_Bold ) - m_out->Print( 0, " bold" ); + m_out->Print( " bold" ); if( aItem->m_Italic ) - m_out->Print( 0, " italic" ); + m_out->Print( " italic" ); if( aItem->m_TextColor != COLOR4D::UNSPECIFIED ) { - m_out->Print( 0, " (color %d %d %d %s)", + m_out->Print( "(color %d %d %d %s)", KiROUND( aItem->m_TextColor.r * 255.0 ), KiROUND( aItem->m_TextColor.g * 255.0 ), KiROUND( aItem->m_TextColor.b * 255.0 ), FormatDouble2Str( aItem->m_TextColor.a ).c_str() ); } - m_out->Print( 0, ")" ); + m_out->Print( ")" ); } // Write text justification if( aItem->m_Hjustify != GR_TEXT_H_ALIGN_LEFT || aItem->m_Vjustify != GR_TEXT_V_ALIGN_CENTER ) { - m_out->Print( 0, " (justify" ); + m_out->Print( "(justify" ); // Write T_center opt first, because it is // also a center for both m_Hjustify and m_Vjustify if( aItem->m_Hjustify == GR_TEXT_H_ALIGN_CENTER ) - m_out->Print( 0, " center" ); + m_out->Print( " center" ); else if( aItem->m_Hjustify == GR_TEXT_H_ALIGN_RIGHT ) - m_out->Print( 0, " right" ); + m_out->Print( " right" ); if( aItem->m_Vjustify == GR_TEXT_V_ALIGN_TOP ) - m_out->Print( 0, " top" ); + m_out->Print( " top" ); else if( aItem->m_Vjustify == GR_TEXT_V_ALIGN_BOTTOM ) - m_out->Print( 0, " bottom" ); + m_out->Print( " bottom" ); - m_out->Print( 0, ")" ); + m_out->Print( ")" ); } // write constraints if( aItem->m_BoundingBoxSize.x ) - m_out->Print( 0, " (maxlen %s)", FormatDouble2Str( aItem->m_BoundingBoxSize.x ).c_str() ); + m_out->Print( "(maxlen %s)", FormatDouble2Str( aItem->m_BoundingBoxSize.x ).c_str() ); if( aItem->m_BoundingBoxSize.y ) - m_out->Print( 0, " (maxheight %s)", FormatDouble2Str(aItem->m_BoundingBoxSize.y ).c_str() ); + m_out->Print( "(maxheight %s)", FormatDouble2Str(aItem->m_BoundingBoxSize.y ).c_str() ); formatRepeatParameters( aItem ); if( !aItem->m_Info.IsEmpty() ) - m_out->Print( 0, " (comment %s)\n", m_out->Quotew( aItem->m_Info ).c_str() ); + m_out->Print( "(comment %s)", m_out->Quotew( aItem->m_Info ).c_str() ); - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); } -void DS_DATA_MODEL_IO::format( DS_DATA_MODEL* aModel, DS_DATA_ITEM* aItem, int aNestLevel ) const +void DS_DATA_MODEL_IO::format( DS_DATA_MODEL* aModel, DS_DATA_ITEM* aItem ) const { if( aItem->GetType() == DS_DATA_ITEM::DS_RECT ) - m_out->Print( aNestLevel, "(rect" ); + m_out->Print( "(rect" ); else - m_out->Print( aNestLevel, "(line" ); + m_out->Print( "(line" ); - m_out->Print( 0, " (name %s)", m_out->Quotew( aItem->m_Name ).c_str() ); + m_out->Print( "(name %s)", m_out->Quotew( aItem->m_Name ).c_str() ); formatCoordinate( getTokenName( T_start ), aItem->m_Pos ); formatCoordinate( getTokenName( T_end ), aItem->m_End ); formatOptions( aItem ); if( aItem->m_LineWidth && aItem->m_LineWidth != aModel->m_DefaultLineWidth ) - m_out->Print( 0, " (linewidth %s)", FormatDouble2Str( aItem->m_LineWidth ).c_str() ); + m_out->Print( "(linewidth %s)", FormatDouble2Str( aItem->m_LineWidth ).c_str() ); formatRepeatParameters( aItem ); if( !aItem->m_Info.IsEmpty() ) - m_out->Print( 0, " (comment %s)\n", m_out->Quotew( aItem->m_Info ).c_str() ); + m_out->Print( "(comment %s)", m_out->Quotew( aItem->m_Info ).c_str() ); - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); } -void DS_DATA_MODEL_IO::format( DS_DATA_ITEM_POLYGONS* aItem, int aNestLevel ) const +void DS_DATA_MODEL_IO::format( DS_DATA_ITEM_POLYGONS* aItem ) const { - m_out->Print( aNestLevel, "(polygon" ); - m_out->Print( 0, " (name %s)", m_out->Quotew( aItem->m_Name ).c_str() ); + m_out->Print( "(polygon" ); + m_out->Print( "(name %s)", m_out->Quotew( aItem->m_Name ).c_str() ); formatCoordinate( "pos", aItem->m_Pos ); formatOptions( aItem ); formatRepeatParameters( aItem ); if( !aItem->m_Orient.IsZero() ) - m_out->Print( 0, " (rotate %s)", FormatDouble2Str( aItem->m_Orient.AsDegrees() ).c_str() ); + m_out->Print( "(rotate %s)", FormatDouble2Str( aItem->m_Orient.AsDegrees() ).c_str() ); if( aItem->m_LineWidth ) - m_out->Print( 0, " (linewidth %s)\n", FormatDouble2Str( aItem->m_LineWidth ).c_str() ); + m_out->Print( "(linewidth %s)", FormatDouble2Str( aItem->m_LineWidth ).c_str() ); if( !aItem->m_Info.IsEmpty() ) - m_out->Print( 0, " (comment %s)\n", m_out->Quotew( aItem->m_Info ).c_str() ); + m_out->Print( "(comment %s)", m_out->Quotew( aItem->m_Info ).c_str() ); // Write polygon corners list for( int kk = 0; kk < aItem->GetPolyCount(); kk++ ) { - m_out->Print( aNestLevel+1, "(pts" ); + m_out->Print( "(pts" ); + // Create current polygon corners list unsigned ist = aItem->GetPolyIndexStart( kk ); unsigned iend = aItem->GetPolyIndexEnd( kk ); - int ii = 0; while( ist <= iend ) { VECTOR2D pos = aItem->m_Corners[ist++]; - int nestLevel = 0; - - if( ii++ > 4) - { - m_out->Print( 0, "\n" ); - nestLevel = aNestLevel+2; - ii = 0; - } - - m_out->Print( nestLevel, " (xy %s %s)", + m_out->Print( "(xy %s %s)", FormatDouble2Str( pos.x ).c_str(), FormatDouble2Str( pos.y ).c_str() ); } - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); } - m_out->Print( aNestLevel, ")\n" ); + m_out->Print( ")" ); } -void DS_DATA_MODEL_IO::format( DS_DATA_ITEM_BITMAP* aItem, int aNestLevel ) const +void DS_DATA_MODEL_IO::format( DS_DATA_ITEM_BITMAP* aItem ) const { // Don't save empty images if( !aItem->m_ImageBitmap->GetOriginalImageData() ) return; - m_out->Print( aNestLevel, "(bitmap" ); - m_out->Print( 0, " (name %s)", m_out->Quotew( aItem->m_Name ).c_str() ); + m_out->Print( "(bitmap" ); + m_out->Print( "(name %s)", m_out->Quotew( aItem->m_Name ).c_str() ); formatCoordinate( "pos", aItem->m_Pos ); formatOptions( aItem ); - m_out->Print( 0, " (scale %s)", FormatDouble2Str( aItem->m_ImageBitmap->GetScale() ).c_str() ); + m_out->Print( "(scale %s)", FormatDouble2Str( aItem->m_ImageBitmap->GetScale() ).c_str() ); formatRepeatParameters( aItem ); - m_out->Print( 0,"\n"); if( !aItem->m_Info.IsEmpty() ) - m_out->Print( 0, " (comment %s)\n", m_out->Quotew( aItem->m_Info ).c_str() ); + m_out->Print( "(comment %s)", m_out->Quotew( aItem->m_Info ).c_str() ); // Write image in png readable format - m_out->Print( aNestLevel, "(data" ); + m_out->Print( "(data" ); wxString out = wxBase64Encode( aItem->m_ImageBitmap->GetImageDataBuffer() ); @@ -431,32 +422,30 @@ void DS_DATA_MODEL_IO::format( DS_DATA_ITEM_BITMAP* aItem, int aNestLevel ) cons while( first < out.Length() ) { - m_out->Print( 0, "\n" ); - m_out->Print( aNestLevel + 1, "\"%s\"", TO_UTF8( out( first, MIME_BASE64_LENGTH ) ) ); + m_out->Print( "\n\"%s\"", TO_UTF8( out( first, MIME_BASE64_LENGTH ) ) ); first += MIME_BASE64_LENGTH; } - m_out->Print( 0, "\n" ); - m_out->Print( aNestLevel, ")\n" ); // Closes data token. - m_out->Print( aNestLevel, ")\n" ); // Closes bitmap token. + m_out->Print( ")" ); // Closes data token. + m_out->Print( ")" ); // Closes bitmap token. } void DS_DATA_MODEL_IO::formatCoordinate( const char * aToken, POINT_COORD & aCoord ) const { - m_out->Print( 0, " (%s %s %s", aToken, + m_out->Print( "(%s %s %s", aToken, FormatDouble2Str( aCoord.m_Pos.x ).c_str(), FormatDouble2Str( aCoord.m_Pos.y ).c_str() ); switch( aCoord.m_Anchor ) { case RB_CORNER: break; - case LT_CORNER: m_out->Print( 0, " ltcorner" ); break; - case LB_CORNER: m_out->Print( 0, " lbcorner" ); break; - case RT_CORNER: m_out->Print( 0, " rtcorner" ); break; + case LT_CORNER: m_out->Print( " ltcorner" ); break; + case LB_CORNER: m_out->Print( " lbcorner" ); break; + case RT_CORNER: m_out->Print( " rtcorner" ); break; } - m_out->Print( 0, ")" ); + m_out->Print( ")" ); } @@ -465,23 +454,23 @@ void DS_DATA_MODEL_IO::formatRepeatParameters( DS_DATA_ITEM* aItem ) const if( aItem->m_RepeatCount <= 1 ) return; - m_out->Print( 0, " (repeat %d)", aItem->m_RepeatCount ); + m_out->Print( "(repeat %d)", aItem->m_RepeatCount ); if( aItem->m_IncrementVector.x ) - m_out->Print( 0, " (incrx %s)", FormatDouble2Str( aItem->m_IncrementVector.x ).c_str() ); + m_out->Print( "(incrx %s)", FormatDouble2Str( aItem->m_IncrementVector.x ).c_str() ); if( aItem->m_IncrementVector.y ) - m_out->Print( 0, " (incry %s)", FormatDouble2Str( aItem->m_IncrementVector.y ).c_str() ); + m_out->Print( "(incry %s)", FormatDouble2Str( aItem->m_IncrementVector.y ).c_str() ); if( aItem->m_IncrementLabel != 1 && aItem->GetType() == DS_DATA_ITEM::DS_TEXT ) - m_out->Print( 0, " (incrlabel %d)", aItem->m_IncrementLabel ); + m_out->Print( "(incrlabel %d)", aItem->m_IncrementLabel ); } void DS_DATA_MODEL_IO::formatOptions( DS_DATA_ITEM* aItem ) const { if( aItem->GetPage1Option() == FIRST_PAGE_ONLY ) - m_out->Print( 0, " (option page1only)" ); + m_out->Print( "(option page1only)" ); else if( aItem->GetPage1Option() == SUBSEQUENT_PAGES ) - m_out->Print( 0, " (option notonpage1)" ); + m_out->Print( "(option notonpage1)" ); } diff --git a/common/eda_text.cpp b/common/eda_text.cpp index f6303ca62a..c3c8873759 100644 --- a/common/eda_text.cpp +++ b/common/eda_text.cpp @@ -53,12 +53,12 @@ #include <wx/debug.h> // for wxASSERT #include <wx/string.h> #include <wx/url.h> // for wxURL +#include <io/kicad/kicad_io_utils.h> #include "font/kicad_font_name.h" #include "font/fontconfig.h" #include "pgm_base.h" class OUTPUTFORMATTER; -class wxFindReplaceData; GR_TEXT_H_ALIGN_T EDA_TEXT::MapHorizJustify( int aHorizJustify ) @@ -948,75 +948,75 @@ bool EDA_TEXT::IsDefaultFormatting() const } -void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const +void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aControlBits ) const { - aFormatter->Print( aNestLevel + 1, "(effects" ); + aFormatter->Print( "(effects" ); - aFormatter->Print( 0, " (font" ); + aFormatter->Print( "(font" ); if( GetFont() && !GetFont()->GetName().IsEmpty() ) - aFormatter->Print( 0, " (face \"%s\")", GetFont()->NameAsToken() ); + aFormatter->Print( "(face %s)", aFormatter->Quotew( GetFont()->NameAsToken() ).c_str() ); // Text size - aFormatter->Print( 0, " (size %s %s)", + aFormatter->Print( "(size %s %s)", EDA_UNIT_UTILS::FormatInternalUnits( m_IuScale, GetTextHeight() ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( m_IuScale, GetTextWidth() ).c_str() ); if( GetLineSpacing() != 1.0 ) { - aFormatter->Print( 0, " (line_spacing %s)", + aFormatter->Print( "(line_spacing %s)", FormatDouble2Str( GetLineSpacing() ).c_str() ); } if( GetTextThickness() ) { - aFormatter->Print( 0, " (thickness %s)", + aFormatter->Print( "(thickness %s)", EDA_UNIT_UTILS::FormatInternalUnits( m_IuScale, GetTextThickness() ).c_str() ); } if( IsBold() ) - aFormatter->Print( 0, " (bold yes)" ); + KICAD_FORMAT::FormatBool( aFormatter, "bold", true ); if( IsItalic() ) - aFormatter->Print( 0, " (italic yes)" ); + KICAD_FORMAT::FormatBool( aFormatter, "italic", true ); if( !( aControlBits & CTL_OMIT_COLOR ) && GetTextColor() != COLOR4D::UNSPECIFIED ) { - aFormatter->Print( 0, " (color %d %d %d %s)", + aFormatter->Print( "(color %d %d %d %s)", KiROUND( GetTextColor().r * 255.0 ), KiROUND( GetTextColor().g * 255.0 ), KiROUND( GetTextColor().b * 255.0 ), FormatDouble2Str( GetTextColor().a ).c_str() ); } - aFormatter->Print( 0, ")"); // (font + aFormatter->Print( ")"); // (font if( IsMirrored() || GetHorizJustify() != GR_TEXT_H_ALIGN_CENTER || GetVertJustify() != GR_TEXT_V_ALIGN_CENTER ) { - aFormatter->Print( 0, " (justify"); + aFormatter->Print( "(justify"); if( GetHorizJustify() != GR_TEXT_H_ALIGN_CENTER ) - aFormatter->Print( 0, GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT ? " left" : " right" ); + aFormatter->Print( GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT ? " left" : " right" ); if( GetVertJustify() != GR_TEXT_V_ALIGN_CENTER ) - aFormatter->Print( 0, GetVertJustify() == GR_TEXT_V_ALIGN_TOP ? " top" : " bottom" ); + aFormatter->Print( GetVertJustify() == GR_TEXT_V_ALIGN_TOP ? " top" : " bottom" ); if( IsMirrored() ) - aFormatter->Print( 0, " mirror" ); + aFormatter->Print( " mirror" ); - aFormatter->Print( 0, ")" ); // (justify + aFormatter->Print( ")" ); // (justify } if( !( aControlBits & CTL_OMIT_HIDE ) && !IsVisible() ) - aFormatter->Print( 0, " (hide yes)" ); + KICAD_FORMAT::FormatBool( aFormatter, "hide", true ); if( !( aControlBits & CTL_OMIT_HYPERLINK ) && HasHyperlink() ) { - aFormatter->Print( 0, " (href %s)", aFormatter->Quotew( GetHyperlink() ).c_str() ); + aFormatter->Print( "(href %s)", aFormatter->Quotew( GetHyperlink() ).c_str() ); } - aFormatter->Print( 0, ")\n" ); // (effects + aFormatter->Print( ")" ); // (effects } diff --git a/common/embedded_files.cpp b/common/embedded_files.cpp index ce4d33e209..0fac6a4fda 100644 --- a/common/embedded_files.cpp +++ b/common/embedded_files.cpp @@ -22,7 +22,6 @@ #include <wx/base64.h> #include <wx/debug.h> -#include <wx/file.h> #include <wx/filename.h> #include <wx/log.h> #include <wx/mstream.h> @@ -146,45 +145,34 @@ void EMBEDDED_FILES::ClearEmbeddedFonts() // Write the collection of files to a disk file in the specified format -void EMBEDDED_FILES::WriteEmbeddedFiles( OUTPUTFORMATTER& aOut, int aNestLevel, - bool aWriteData ) const +void EMBEDDED_FILES::WriteEmbeddedFiles( OUTPUTFORMATTER& aOut, bool aWriteData ) const { ssize_t MIME_BASE64_LENGTH = 76; - aOut.Print( aNestLevel, "(embedded_files\n" ); + aOut.Print( "(embedded_files " ); for( const auto& [name, entry] : m_files ) { const EMBEDDED_FILE& file = *entry; - aOut.Print( aNestLevel + 1, "(file\n" ); - aOut.Print( aNestLevel + 2, "(name \"%s\")\n", file.name.c_str().AsChar() ); + aOut.Print( "(file " ); + aOut.Print( "(name %s)", aOut.Quotew( file.name ).c_str() ); const char* type = nullptr; switch( file.type ) { - case EMBEDDED_FILE::FILE_TYPE::DATASHEET: - type = "datasheet"; - break; - case EMBEDDED_FILE::FILE_TYPE::FONT: - type = "font"; - break; - case EMBEDDED_FILE::FILE_TYPE::MODEL: - type = "model"; - break; - case EMBEDDED_FILE::FILE_TYPE::WORKSHEET: - type = "worksheet"; - break; - default: - type = "other"; - break; + case EMBEDDED_FILE::FILE_TYPE::DATASHEET: type = "datasheet"; break; + case EMBEDDED_FILE::FILE_TYPE::FONT: type = "font"; break; + case EMBEDDED_FILE::FILE_TYPE::MODEL: type = "model"; break; + case EMBEDDED_FILE::FILE_TYPE::WORKSHEET: type = "worksheet"; break; + default: type = "other"; break; } - aOut.Print( aNestLevel + 2, "(type %s)\n", type ); + aOut.Print( "(type %s)", type ); if( aWriteData ) { - aOut.Print( 2, "(data\n" ); + aOut.Print( "(data" ); size_t first = 0; @@ -195,18 +183,18 @@ void EMBEDDED_FILES::WriteEmbeddedFiles( OUTPUTFORMATTER& aOut, int aNestLevel, std::string_view view( file.compressedEncodedData.data() + first, length ); - aOut.Print( aNestLevel + 3, "%1s%.*s%s\n", first ? "" : "|", length, view.data(), + aOut.Print( "\n%1s%.*s%s\n", first ? "" : "|", length, view.data(), remaining == length ? "|" : "" ); first += MIME_BASE64_LENGTH; } - aOut.Print( aNestLevel + 2, ")\n" ); // Close data + aOut.Print( ")" ); // Close data } - aOut.Print( aNestLevel + 2, "(checksum \"%s\")\n", file.data_hash.c_str() ); - aOut.Print( aNestLevel + 1, ")\n" ); // Close file + aOut.Print( "(checksum %s)", aOut.Quotew( file.data_hash ).c_str() ); + aOut.Print( ")" ); // Close file } - aOut.Print( aNestLevel, ")\n" ); // Close embedded_files + aOut.Print( ")" ); // Close embedded_files } // Compress and Base64 encode data diff --git a/common/io/kicad/kicad_io_utils.cpp b/common/io/kicad/kicad_io_utils.cpp index 3d7871284d..2b998522cd 100644 --- a/common/io/kicad/kicad_io_utils.cpp +++ b/common/io/kicad/kicad_io_utils.cpp @@ -26,28 +26,15 @@ namespace KICAD_FORMAT { -void FormatBool( OUTPUTFORMATTER* aOut, int aNestLevel, const wxString& aKey, bool aValue, - char aSuffix ) +void FormatBool( OUTPUTFORMATTER* aOut, const wxString& aKey, bool aValue ) { - if( aNestLevel ) - aOut->Print( aNestLevel, "(%ls %s)", aKey.wc_str(), aValue ? "yes" : "no" ); - else - aOut->Print( 0, " (%ls %s)", aKey.wc_str(), aValue ? "yes" : "no" ); - - if( aSuffix ) - aOut->Print( 0, "%c", aSuffix ); + aOut->Print( "(%ls %s)", aKey.wc_str(), aValue ? "yes" : "no" ); } -void FormatUuid( OUTPUTFORMATTER* aOut, int aNestLevel, const KIID& aUuid, char aSuffix ) +void FormatUuid( OUTPUTFORMATTER* aOut, const KIID& aUuid ) { - if( aNestLevel ) - aOut->Print( aNestLevel, "(uuid \"%s\")", TO_UTF8( aUuid.AsString() ) ); - else - aOut->Print( 0, " (uuid \"%s\")", TO_UTF8( aUuid.AsString() ) ); - - if( aSuffix ) - aOut->Print( 0, "%c", aSuffix ); + aOut->Print( "(uuid %s)", aOut->Quotew( aUuid.AsString() ).c_str() ); } /* @@ -70,9 +57,10 @@ void FormatUuid( OUTPUTFORMATTER* aOut, int aNestLevel, const KIID& aUuid, char * ) * ) */ -void Prettify( std::string& aSource, char aQuoteChar ) +void Prettify( std::string& aSource, bool aCompactSave ) { // Configuration + const char quoteChar = '"'; const char indentChar = '\t'; const int indentSize = 1; @@ -97,6 +85,8 @@ void Prettify( std::string& aSource, char aQuoteChar ) bool hasInsertedSpace = false; bool inMultiLineList = false; bool inXY = false; + bool inShortForm = false; + int shortFormDepth = 0; int column = 0; int backslashCount = 0; // Count of successive backslash read since any other char @@ -136,6 +126,19 @@ void Prettify( std::string& aSource, char aQuoteChar ) return true; }; + auto isShortForm = + [&]( std::string::iterator aIt ) + { + seek = aIt; + std::string token; + + while( ++seek != aSource.end() && isalpha( *seek ) ) + token += *seek; + + return token == "font" || token == "stroke" || token == "fill" + || token == "offset" || token == "rotate" || token == "scale"; + }; + while( cursor != aSource.end() ) { char next = nextNonWhitespace( cursor ); @@ -150,11 +153,15 @@ void Prettify( std::string& aSource, char aQuoteChar ) { if( inXY || column < consecutiveTokenWrapThreshold ) { - // Note that we only insert spaces here, no matter what kind of whitespace is in - // the input. Newlines will be inserted as needed by the logic below. + // Note that we only insert spaces here, no matter what kind of whitespace is + // in the input. Newlines will be inserted as needed by the logic below. formatted.push_back( ' ' ); column++; } + else if( inShortForm ) + { + formatted.push_back( ' ' ); + } else { formatted += fmt::format( "\n{}", @@ -173,8 +180,9 @@ void Prettify( std::string& aSource, char aQuoteChar ) if( *cursor == '(' && !inQuote ) { bool currentIsXY = isXY( cursor ); + bool currentIsShortForm = aCompactSave && isShortForm( cursor ); - if( listDepth == 0 ) + if( formatted.empty() ) { formatted.push_back( '(' ); column++; @@ -184,7 +192,11 @@ void Prettify( std::string& aSource, char aQuoteChar ) // List-of-points special case formatted += " ("; column += 2; - inXY = true; + } + else if( inShortForm ) + { + formatted += " ("; + column += 2; } else { @@ -194,6 +206,13 @@ void Prettify( std::string& aSource, char aQuoteChar ) } inXY = currentIsXY; + + if( currentIsShortForm ) + { + inShortForm = true; + shortFormDepth = listDepth; + } + listDepth++; } else if( *cursor == ')' && !inQuote ) @@ -201,7 +220,12 @@ void Prettify( std::string& aSource, char aQuoteChar ) if( listDepth > 0 ) listDepth--; - if( lastNonWhitespace == ')' || inMultiLineList ) + if( inShortForm ) + { + formatted.push_back( ')' ); + column++; + } + else if( lastNonWhitespace == ')' || inMultiLineList ) { formatted += fmt::format( "\n{})", std::string( listDepth * indentSize, indentChar ) ); @@ -213,6 +237,12 @@ void Prettify( std::string& aSource, char aQuoteChar ) formatted.push_back( ')' ); column++; } + + if( shortFormDepth == listDepth ) + { + inShortForm = false; + shortFormDepth = 0; + } } else { @@ -221,7 +251,7 @@ void Prettify( std::string& aSource, char aQuoteChar ) // therefore a '\' is attached to a '"' if a odd number of '\' is detected if( *cursor == '\\' ) backslashCount++; - else if( *cursor == aQuoteChar && ( backslashCount & 1 ) == 0 ) + else if( *cursor == quoteChar && ( backslashCount & 1 ) == 0 ) inQuote = !inQuote; if( *cursor != '\\' ) diff --git a/common/page_info.cpp b/common/page_info.cpp index b9da8f405d..32db2f5c29 100644 --- a/common/page_info.cpp +++ b/common/page_info.cpp @@ -22,8 +22,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#include <common.h> #include <page_info.h> #include <macros.h> #include <eda_units.h> @@ -272,19 +270,21 @@ void PAGE_INFO::SetHeightMils( double aHeightInMils ) } -void PAGE_INFO::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const +void PAGE_INFO::Format( OUTPUTFORMATTER* aFormatter ) const { - aFormatter->Print( aNestLevel, "(paper %s", aFormatter->Quotew( GetType() ).c_str() ); + aFormatter->Print( "(paper %s", aFormatter->Quotew( GetType() ).c_str() ); // The page dimensions are only required for user defined page sizes. // Internally, the page size is in mils if( GetType() == PAGE_INFO::Custom ) - aFormatter->Print( 0, " %g %g", + { + aFormatter->Print( " %g %g", GetWidthMils() * 25.4 / 1000.0, GetHeightMils() * 25.4 / 1000.0 ); + } if( !IsCustom() && IsPortrait() ) - aFormatter->Print( 0, " portrait" ); + aFormatter->Print( " portrait" ); - aFormatter->Print( 0, ")\n" ); + aFormatter->Print( ")" ); } diff --git a/common/richio.cpp b/common/richio.cpp index c676fd6694..697cf42c3a 100644 --- a/common/richio.cpp +++ b/common/richio.cpp @@ -30,9 +30,9 @@ #include <core/ignore.h> #include <richio.h> #include <errno.h> +#include <advanced_config.h> #include <io/kicad/kicad_io_utils.h> -#include <wx/file.h> #include <wx/translation.h> @@ -484,6 +484,23 @@ int OUTPUTFORMATTER::Print( int nestLevel, const char* fmt, ... ) } +int OUTPUTFORMATTER::Print( const char* fmt, ... ) +{ + va_list args; + + va_start( args, fmt ); + + int result = 0; + + // no error checking needed, an exception indicates an error. + result = vprint( fmt, args ); + + va_end( args ); + + return result; +} + + std::string OUTPUTFORMATTER::Quotes( const std::string& aWrapee ) const { std::string ret; @@ -611,7 +628,7 @@ bool PRETTIFIED_FILE_OUTPUTFORMATTER::Finish() if( !m_fp ) return false; - KICAD_FORMAT::Prettify( m_buf ); + KICAD_FORMAT::Prettify( m_buf, ADVANCED_CFG::GetCfg().m_CompactSave ); if( fwrite( m_buf.c_str(), m_buf.length(), 1, m_fp ) != 1 ) THROW_IO_ERROR( strerror( errno ) ); diff --git a/common/stroke_params.cpp b/common/stroke_params.cpp index d68286b46a..0deb41c679 100644 --- a/common/stroke_params.cpp +++ b/common/stroke_params.cpp @@ -276,20 +276,19 @@ void STROKE_PARAMS::GetMsgPanelInfo( UNITS_PROVIDER* aUnitsProvider, } -void STROKE_PARAMS::Format( OUTPUTFORMATTER* aFormatter, const EDA_IU_SCALE& aIuScale, - int aNestLevel ) const +void STROKE_PARAMS::Format( OUTPUTFORMATTER* aFormatter, const EDA_IU_SCALE& aIuScale ) const { wxASSERT( aFormatter != nullptr ); if( GetColor() == KIGFX::COLOR4D::UNSPECIFIED ) { - aFormatter->Print( aNestLevel, "(stroke (width %s) (type %s))", + aFormatter->Print( "(stroke (width %s) (type %s))", EDA_UNIT_UTILS::FormatInternalUnits( aIuScale, GetWidth() ).c_str(), TO_UTF8( GetLineStyleToken( GetLineStyle() ) ) ); } else { - aFormatter->Print( aNestLevel, "(stroke (width %s) (type %s) (color %d %d %d %s))", + aFormatter->Print( "(stroke (width %s) (type %s) (color %d %d %d %s))", EDA_UNIT_UTILS::FormatInternalUnits( aIuScale, GetWidth() ).c_str(), TO_UTF8( GetLineStyleToken( GetLineStyle() ) ), KiROUND( GetColor().r * 255.0 ), @@ -322,12 +321,12 @@ void STROKE_PARAMS_PARSER::ParseStroke( STROKE_PARAMS& aStroke ) switch( token ) { - case T_dash: aStroke.SetLineStyle( LINE_STYLE::DASH ); break; - case T_dot: aStroke.SetLineStyle( LINE_STYLE::DOT ); break; - case T_dash_dot: aStroke.SetLineStyle( LINE_STYLE::DASHDOT ); break; + case T_dash: aStroke.SetLineStyle( LINE_STYLE::DASH ); break; + case T_dot: aStroke.SetLineStyle( LINE_STYLE::DOT ); break; + case T_dash_dot: aStroke.SetLineStyle( LINE_STYLE::DASHDOT ); break; case T_dash_dot_dot: aStroke.SetLineStyle( LINE_STYLE::DASHDOTDOT ); break; - case T_solid: aStroke.SetLineStyle( LINE_STYLE::SOLID ); break; - case T_default: aStroke.SetLineStyle( LINE_STYLE::DEFAULT ); break; + case T_solid: aStroke.SetLineStyle( LINE_STYLE::SOLID ); break; + case T_default: aStroke.SetLineStyle( LINE_STYLE::DEFAULT ); break; default: Expecting( "solid, dash, dash_dot, dash_dot_dot, dot or default" ); } diff --git a/common/template_fieldnames.cpp b/common/template_fieldnames.cpp index 5c37ec0ed3..b7ea9df9c0 100644 --- a/common/template_fieldnames.cpp +++ b/common/template_fieldnames.cpp @@ -27,7 +27,6 @@ #include <mutex> #include <template_fieldnames_lexer.h> -#include <pgm_base.h> #include <string_utils.h> using namespace TFIELD_T; @@ -80,17 +79,17 @@ const wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx, bool aTra } -void TEMPLATE_FIELDNAME::Format( OUTPUTFORMATTER* out, int nestLevel ) const +void TEMPLATE_FIELDNAME::Format( OUTPUTFORMATTER* out ) const { - out->Print( nestLevel, "(field (name %s)", out->Quotew( m_Name ).c_str() ); + out->Print( "(field (name %s)", out->Quotew( m_Name ).c_str() ); if( m_Visible ) - out->Print( 0, " visible" ); + out->Print( " visible" ); if( m_URL ) - out->Print( 0, " url" ); + out->Print( " url" ); - out->Print( 0, ")\n" ); + out->Print( ")" ); } @@ -139,21 +138,21 @@ void TEMPLATE_FIELDNAME::Parse( TEMPLATE_FIELDNAMES_LEXER* in ) } -void TEMPLATES::Format( OUTPUTFORMATTER* out, int nestLevel, bool aGlobal ) const +void TEMPLATES::Format( OUTPUTFORMATTER* out, bool aGlobal ) const { // We'll keep this general, and include the \n, even though the only known // use at this time will not want the newlines or the indentation. - out->Print( nestLevel, "(templatefields" ); + out->Print( "(templatefields" ); const TEMPLATE_FIELDNAMES& source = aGlobal ? m_globals : m_project; for( const TEMPLATE_FIELDNAME& temp : source ) { if( !temp.m_Name.IsEmpty() ) - temp.Format( out, nestLevel+1 ); + temp.Format( out ); } - out->Print( 0, ")\n" ); + out->Print( ")" ); } diff --git a/common/title_block.cpp b/common/title_block.cpp index 79cf03c131..83f72f4715 100644 --- a/common/title_block.cpp +++ b/common/title_block.cpp @@ -27,7 +27,7 @@ #include <title_block.h> #include <core/kicad_algo.h> -void TITLE_BLOCK::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const +void TITLE_BLOCK::Format( OUTPUTFORMATTER* aFormatter ) const { // Don't write the title block information if there is nothing to write. bool isempty = true; @@ -42,32 +42,31 @@ void TITLE_BLOCK::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aCont if( !isempty ) { - aFormatter->Print( aNestLevel, "(title_block\n" ); + aFormatter->Print( "(title_block" ); if( !GetTitle().IsEmpty() ) - aFormatter->Print( aNestLevel+1, "(title %s)\n", - aFormatter->Quotew( GetTitle() ).c_str() ); + aFormatter->Print( "(title %s)", aFormatter->Quotew( GetTitle() ).c_str() ); if( !GetDate().IsEmpty() ) - aFormatter->Print( aNestLevel+1, "(date %s)\n", - aFormatter->Quotew( GetDate() ).c_str() ); + aFormatter->Print( "(date %s)", aFormatter->Quotew( GetDate() ).c_str() ); if( !GetRevision().IsEmpty() ) - aFormatter->Print( aNestLevel+1, "(rev %s)\n", - aFormatter->Quotew( GetRevision() ).c_str() ); + aFormatter->Print( "(rev %s)", aFormatter->Quotew( GetRevision() ).c_str() ); if( !GetCompany().IsEmpty() ) - aFormatter->Print( aNestLevel+1, "(company %s)\n", - aFormatter->Quotew( GetCompany() ).c_str() ); + aFormatter->Print( "(company %s)", aFormatter->Quotew( GetCompany() ).c_str() ); for( int ii = 0; ii < 9; ii++ ) { if( !GetComment(ii).IsEmpty() ) - aFormatter->Print( aNestLevel+1, "(comment %d %s)\n", ii+1, - aFormatter->Quotew( GetComment(ii) ).c_str() ); + { + aFormatter->Print( "(comment %d %s)", + ii+1, + aFormatter->Quotew( GetComment(ii) ).c_str() ); + } } - aFormatter->Print( aNestLevel, ")\n\n" ); + aFormatter->Print( ")" ); } } diff --git a/eeschema/dialogs/panel_template_fieldnames.cpp b/eeschema/dialogs/panel_template_fieldnames.cpp index 0717aab873..2d40bcce68 100644 --- a/eeschema/dialogs/panel_template_fieldnames.cpp +++ b/eeschema/dialogs/panel_template_fieldnames.cpp @@ -235,10 +235,9 @@ bool PANEL_TEMPLATE_FIELDNAMES::TransferDataFromWindow() { // Save global fieldname templates STRING_FORMATTER sf; - m_templateMgr->Format( &sf, 0, true ); + m_templateMgr->Format( &sf, true ); wxString record = From_UTF8( sf.GetString().c_str() ); - record.Replace( wxT("\n"), wxT(""), true ); // strip all newlines record.Replace( wxT(" "), wxT(" "), true ); // double space to single cfg->m_Drawing.field_names = record.ToStdString(); diff --git a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.cpp b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.cpp index 1367f2d786..1f9d8c962e 100644 --- a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.cpp +++ b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.cpp @@ -28,9 +28,7 @@ #include <wx/base64.h> #include <wx/log.h> #include <wx/mstream.h> -#include <boost/algorithm/string/join.hpp> -#include <advanced_config.h> #include <base_units.h> #include <bitmap_base.h> #include <build_version.h> @@ -65,7 +63,6 @@ #include <string_utils.h> #include <symbol_lib_table.h> // for PropPowerSymsOnly definition. #include <trace_helpers.h> -#include <wx_filename.h> // for ::ResolvePossibleSymlinks() using namespace TSCHEMATIC_T; @@ -381,25 +378,25 @@ void SCH_IO_KICAD_SEXPR::Format( SCH_SHEET* aSheet ) else m_schematic->GetEmbeddedFiles()->ClearEmbeddedFonts(); - m_out->Print( 0, "(kicad_sch (version %d) (generator \"eeschema\") (generator_version \"%s\")\n\n", - SEXPR_SCHEMATIC_FILE_VERSION, GetMajorMinorVersion().c_str().AsChar() ); + m_out->Print( "(kicad_sch (version %d) (generator \"eeschema\") (generator_version %s)", + SEXPR_SCHEMATIC_FILE_VERSION, + m_out->Quotew( GetMajorMinorVersion() ).c_str() ); - KICAD_FORMAT::FormatUuid( m_out, 0, screen->m_uuid, '\n' ); + KICAD_FORMAT::FormatUuid( m_out, screen->m_uuid ); - screen->GetPageSettings().Format( m_out, 1, 0 ); - m_out->Print( 0, "\n" ); - screen->GetTitleBlock().Format( m_out, 1, 0 ); + screen->GetPageSettings().Format( m_out ); + screen->GetTitleBlock().Format( m_out ); // Save cache library. - m_out->Print( 1, "(lib_symbols\n" ); + m_out->Print( "(lib_symbols" ); for( const auto& [ libItemName, libSymbol ] : screen->GetLibSymbols() ) - SCH_IO_KICAD_SEXPR_LIB_CACHE::SaveSymbol( libSymbol, *m_out, 2, libItemName ); + SCH_IO_KICAD_SEXPR_LIB_CACHE::SaveSymbol( libSymbol, *m_out, libItemName ); - m_out->Print( 1, ")\n\n" ); + m_out->Print( ")" ); for( const std::shared_ptr<BUS_ALIAS>& alias : screen->GetBusAliases() ) - saveBusAlias( alias, 1 ); + saveBusAlias( alias ); // Enforce item ordering auto cmp = @@ -420,75 +417,45 @@ void SCH_IO_KICAD_SEXPR::Format( SCH_SHEET* aSheet ) save_map.insert( item ); } - KICAD_T itemType = TYPE_NOT_INIT; - SCH_LAYER_ID layer = SCH_LAYER_ID_START; - for( SCH_ITEM* item : save_map ) { - if( itemType != item->Type() ) - { - itemType = item->Type(); - - if( itemType != SCH_SYMBOL_T - && itemType != SCH_JUNCTION_T - && itemType != SCH_SHEET_T ) - { - m_out->Print( 0, "\n" ); - } - } - switch( item->Type() ) { case SCH_SYMBOL_T: - m_out->Print( 0, "\n" ); - saveSymbol( static_cast<SCH_SYMBOL*>( item ), *m_schematic, sheets, 1, false ); + saveSymbol( static_cast<SCH_SYMBOL*>( item ), *m_schematic, sheets, false ); break; case SCH_BITMAP_T: - saveBitmap( static_cast<SCH_BITMAP&>( *item ), 1 ); + saveBitmap( static_cast<SCH_BITMAP&>( *item ) ); break; case SCH_SHEET_T: - m_out->Print( 0, "\n" ); - saveSheet( static_cast<SCH_SHEET*>( item ), sheets, 1 ); + saveSheet( static_cast<SCH_SHEET*>( item ), sheets ); break; case SCH_JUNCTION_T: - saveJunction( static_cast<SCH_JUNCTION*>( item ), 1 ); + saveJunction( static_cast<SCH_JUNCTION*>( item ) ); break; case SCH_NO_CONNECT_T: - saveNoConnect( static_cast<SCH_NO_CONNECT*>( item ), 1 ); + saveNoConnect( static_cast<SCH_NO_CONNECT*>( item ) ); break; case SCH_BUS_WIRE_ENTRY_T: case SCH_BUS_BUS_ENTRY_T: - saveBusEntry( static_cast<SCH_BUS_ENTRY_BASE*>( item ), 1 ); + saveBusEntry( static_cast<SCH_BUS_ENTRY_BASE*>( item ) ); break; case SCH_LINE_T: - if( layer != item->GetLayer() ) - { - if( layer == SCH_LAYER_ID_START ) - { - layer = item->GetLayer(); - } - else - { - layer = item->GetLayer(); - m_out->Print( 0, "\n" ); - } - } - - saveLine( static_cast<SCH_LINE*>( item ), 1 ); + saveLine( static_cast<SCH_LINE*>( item ) ); break; case SCH_SHAPE_T: - saveShape( static_cast<SCH_SHAPE*>( item ), 1 ); + saveShape( static_cast<SCH_SHAPE*>( item ) ); break; case SCH_RULE_AREA_T: - saveRuleArea( static_cast<SCH_RULE_AREA*>( item ), 1 ); + saveRuleArea( static_cast<SCH_RULE_AREA*>( item ) ); break; case SCH_TEXT_T: @@ -496,15 +463,15 @@ void SCH_IO_KICAD_SEXPR::Format( SCH_SHEET* aSheet ) case SCH_GLOBAL_LABEL_T: case SCH_HIER_LABEL_T: case SCH_DIRECTIVE_LABEL_T: - saveText( static_cast<SCH_TEXT*>( item ), 1 ); + saveText( static_cast<SCH_TEXT*>( item ) ); break; case SCH_TEXTBOX_T: - saveTextBox( static_cast<SCH_TEXTBOX*>( item ), 1 ); + saveTextBox( static_cast<SCH_TEXTBOX*>( item ) ); break; case SCH_TABLE_T: - saveTable( static_cast<SCH_TABLE*>( item ), 1 ); + saveTable( static_cast<SCH_TABLE*>( item ) ); break; default: @@ -517,17 +484,16 @@ void SCH_IO_KICAD_SEXPR::Format( SCH_SHEET* aSheet ) std::vector< SCH_SHEET_INSTANCE> instances; instances.emplace_back( aSheet->GetRootInstance() ); - saveInstances( instances, 1 ); + saveInstances( instances ); - m_out->Print( 1, "(embedded_fonts %s)\n", - m_schematic->GetAreFontsEmbedded() ? "yes" : "no" ); + KICAD_FORMAT::FormatBool( m_out, "embedded_fonts", m_schematic->GetAreFontsEmbedded() ); // Save any embedded files if( !m_schematic->GetEmbeddedFiles()->IsEmpty() ) - m_schematic->WriteEmbeddedFiles( *m_out, 1, true ); + m_schematic->WriteEmbeddedFiles( *m_out, true ); } - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); } @@ -575,15 +541,15 @@ void SCH_IO_KICAD_SEXPR::Format( EE_SELECTION* aSelection, SCH_SHEET_PATH* aSele if( !libSymbols.empty() ) { - m_out->Print( 0, "(lib_symbols\n" ); + m_out->Print( "(lib_symbols" ); for( const std::pair<const wxString, LIB_SYMBOL*>& libSymbol : libSymbols ) { - SCH_IO_KICAD_SEXPR_LIB_CACHE::SaveSymbol( libSymbol.second, *m_out, 1, - libSymbol.first, false ); + SCH_IO_KICAD_SEXPR_LIB_CACHE::SaveSymbol( libSymbol.second, *m_out, libSymbol.first, + false ); } - m_out->Print( 0, ")\n\n" ); + m_out->Print( ")" ); } for( i = 0; i < aSelection->GetSize(); ++i ) @@ -593,41 +559,41 @@ void SCH_IO_KICAD_SEXPR::Format( EE_SELECTION* aSelection, SCH_SHEET_PATH* aSele switch( item->Type() ) { case SCH_SYMBOL_T: - saveSymbol( static_cast<SCH_SYMBOL*>( item ), aSchematic, 0, aForClipboard, + saveSymbol( static_cast<SCH_SYMBOL*>( item ), aSchematic, sheets, aForClipboard, aSelectionPath ); break; case SCH_BITMAP_T: - saveBitmap( static_cast< SCH_BITMAP& >( *item ), 0 ); + saveBitmap( static_cast< SCH_BITMAP& >( *item ) ); break; case SCH_SHEET_T: - saveSheet( static_cast< SCH_SHEET* >( item ), sheets, 0 ); + saveSheet( static_cast< SCH_SHEET* >( item ), sheets ); break; case SCH_JUNCTION_T: - saveJunction( static_cast< SCH_JUNCTION* >( item ), 0 ); + saveJunction( static_cast< SCH_JUNCTION* >( item ) ); break; case SCH_NO_CONNECT_T: - saveNoConnect( static_cast< SCH_NO_CONNECT* >( item ), 0 ); + saveNoConnect( static_cast< SCH_NO_CONNECT* >( item ) ); break; case SCH_BUS_WIRE_ENTRY_T: case SCH_BUS_BUS_ENTRY_T: - saveBusEntry( static_cast< SCH_BUS_ENTRY_BASE* >( item ), 0 ); + saveBusEntry( static_cast< SCH_BUS_ENTRY_BASE* >( item ) ); break; case SCH_LINE_T: - saveLine( static_cast< SCH_LINE* >( item ), 0 ); + saveLine( static_cast< SCH_LINE* >( item ) ); break; case SCH_SHAPE_T: - saveShape( static_cast<SCH_SHAPE*>( item ), 0 ); + saveShape( static_cast<SCH_SHAPE*>( item ) ); break; case SCH_RULE_AREA_T: - saveRuleArea( static_cast<SCH_RULE_AREA*>( item ), 0 ); + saveRuleArea( static_cast<SCH_RULE_AREA*>( item ) ); break; case SCH_TEXT_T: @@ -635,11 +601,11 @@ void SCH_IO_KICAD_SEXPR::Format( EE_SELECTION* aSelection, SCH_SHEET_PATH* aSele case SCH_GLOBAL_LABEL_T: case SCH_HIER_LABEL_T: case SCH_DIRECTIVE_LABEL_T: - saveText( static_cast<SCH_TEXT*>( item ), 0 ); + saveText( static_cast<SCH_TEXT*>( item ) ); break; case SCH_TEXTBOX_T: - saveTextBox( static_cast<SCH_TEXTBOX*>( item ), 0 ); + saveTextBox( static_cast<SCH_TEXTBOX*>( item ) ); break; case SCH_TABLECELL_T: @@ -650,7 +616,7 @@ void SCH_IO_KICAD_SEXPR::Format( EE_SELECTION* aSelection, SCH_SHEET_PATH* aSele break; table->SetFlags( SKIP_STRUCT ); - saveTable( table, 0 ); + saveTable( table ); table->ClearFlags( SKIP_STRUCT ); promotedTables.insert( table ); break; @@ -658,7 +624,7 @@ void SCH_IO_KICAD_SEXPR::Format( EE_SELECTION* aSelection, SCH_SHEET_PATH* aSele case SCH_TABLE_T: item->ClearFlags( SKIP_STRUCT ); - saveTable( static_cast<SCH_TABLE*>( item ), 0 ); + saveTable( static_cast<SCH_TABLE*>( item ) ); break; default: @@ -669,8 +635,7 @@ void SCH_IO_KICAD_SEXPR::Format( EE_SELECTION* aSelection, SCH_SHEET_PATH* aSele void SCH_IO_KICAD_SEXPR::saveSymbol( SCH_SYMBOL* aSymbol, const SCHEMATIC& aSchematic, - const SCH_SHEET_LIST& aSheetList, - int aNestLevel, bool aForClipboard, + const SCH_SHEET_LIST& aSheetList, bool aForClipboard, const SCH_SHEET_PATH* aRelativePath ) { wxCHECK_RET( aSymbol != nullptr && m_out != nullptr, "" ); @@ -700,15 +665,15 @@ void SCH_IO_KICAD_SEXPR::saveSymbol( SCH_SYMBOL* aSymbol, const SCHEMATIC& aSche else angle = ANGLE_0; - m_out->Print( aNestLevel, "(symbol" ); + m_out->Print( "(symbol" ); if( !aSymbol->UseLibIdLookup() ) { - m_out->Print( 0, " (lib_name %s)", + m_out->Print( "(lib_name %s)", m_out->Quotew( aSymbol->GetSchSymbolLibraryName() ).c_str() ); } - m_out->Print( 0, " (lib_id %s) (at %s %s %s)", + m_out->Print( "(lib_id %s) (at %s %s %s)", m_out->Quotew( aSymbol->GetLibId().Format().wx_str() ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aSymbol->GetPosition().x ).c_str(), @@ -721,15 +686,9 @@ void SCH_IO_KICAD_SEXPR::saveSymbol( SCH_SYMBOL* aSymbol, const SCHEMATIC& aSche if( mirrorX || mirrorY ) { - m_out->Print( 0, " (mirror" ); - - if( mirrorX ) - m_out->Print( 0, " x" ); - - if( mirrorY ) - m_out->Print( 0, " y" ); - - m_out->Print( 0, ")" ); + m_out->Print( "(mirror %s %s)", + mirrorX ? "x" : "", + mirrorY ? "y" : "" ); } // The symbol unit is always set to the first instance regardless of the current sheet @@ -745,25 +704,20 @@ void SCH_IO_KICAD_SEXPR::saveSymbol( SCH_SYMBOL* aSymbol, const SCHEMATIC& aSche unit = unitInstance.m_Unit; } - m_out->Print( 0, " (unit %d)", unit ); + m_out->Print( "(unit %d)", unit ); if( aSymbol->GetBodyStyle() == BODY_STYLE::DEMORGAN ) - m_out->Print( 0, " (convert %d)", aSymbol->GetBodyStyle() ); + m_out->Print( "(convert %d)", aSymbol->GetBodyStyle() ); - m_out->Print( 0, "\n" ); - - m_out->Print( aNestLevel + 1, "(exclude_from_sim %s)", - ( aSymbol->GetExcludedFromSim() ) ? "yes" : "no" ); - m_out->Print( 0, " (in_bom %s)", ( aSymbol->GetExcludedFromBOM() ) ? "no" : "yes" ); - m_out->Print( 0, " (on_board %s)", ( aSymbol->GetExcludedFromBoard() ) ? "no" : "yes" ); - m_out->Print( 0, " (dnp %s)", ( aSymbol->GetDNP() ) ? "yes" : "no" ); + KICAD_FORMAT::FormatBool( m_out, "exclude_from_sim", aSymbol->GetExcludedFromSim() ); + KICAD_FORMAT::FormatBool( m_out, "in_bom", !aSymbol->GetExcludedFromBOM() ); + KICAD_FORMAT::FormatBool( m_out, "on_board", !aSymbol->GetExcludedFromBoard() ); + KICAD_FORMAT::FormatBool( m_out, "dnp", aSymbol->GetDNP() ); if( aSymbol->GetFieldsAutoplaced() != FIELDS_AUTOPLACED_NO ) - m_out->Print( 0, " (fields_autoplaced yes)" ); + KICAD_FORMAT::FormatBool( m_out, "fields_autoplaced", true ); - m_out->Print( 0, "\n" ); - - KICAD_FORMAT::FormatUuid( m_out, aNestLevel + 1, aSymbol->m_Uuid, '\n' ); + KICAD_FORMAT::FormatUuid( m_out, aSymbol->m_Uuid ); m_nextFreeFieldId = MANDATORY_FIELDS; @@ -800,7 +754,7 @@ void SCH_IO_KICAD_SEXPR::saveSymbol( SCH_SYMBOL* aSymbol, const SCHEMATIC& aSche try { - saveField( &field, aNestLevel + 1 ); + saveField( &field ); } catch( ... ) { @@ -819,15 +773,15 @@ void SCH_IO_KICAD_SEXPR::saveSymbol( SCH_SYMBOL* aSymbol, const SCHEMATIC& aSche { if( pin->GetAlt().IsEmpty() ) { - m_out->Print( aNestLevel + 1, "(pin %s", m_out->Quotew( pin->GetNumber() ).c_str() ); - KICAD_FORMAT::FormatUuid( m_out, 0, pin->m_Uuid ); - m_out->Print( 0, ")\n" ); + m_out->Print( "(pin %s", m_out->Quotew( pin->GetNumber() ).c_str() ); + KICAD_FORMAT::FormatUuid( m_out, pin->m_Uuid ); + m_out->Print( ")" ); } else { - m_out->Print( aNestLevel + 1, "(pin %s", m_out->Quotew( pin->GetNumber() ).c_str() ); - KICAD_FORMAT::FormatUuid( m_out, 0, pin->m_Uuid ); - m_out->Print( 0, " (alternate %s))\n", m_out->Quotew( pin->GetAlt() ).c_str() ); + m_out->Print( "(pin %s", m_out->Quotew( pin->GetNumber() ).c_str() ); + KICAD_FORMAT::FormatUuid( m_out, pin->m_Uuid ); + m_out->Print( "(alternate %s))", m_out->Quotew( pin->GetAlt() ).c_str() ); } } @@ -835,11 +789,10 @@ void SCH_IO_KICAD_SEXPR::saveSymbol( SCH_SYMBOL* aSymbol, const SCHEMATIC& aSche { std::map<KIID, std::vector<SCH_SYMBOL_INSTANCE>> projectInstances; - m_out->Print( aNestLevel + 1, "(instances\n" ); + m_out->Print( "(instances" ); wxString projectName; - KIID lastProjectUuid; - KIID rootSheetUuid = aSchematic.Root().m_Uuid; + KIID rootSheetUuid = aSchematic.Root().m_Uuid; for( const SCH_SYMBOL_INSTANCE& inst : aSymbol->GetInstances() ) { @@ -859,13 +812,9 @@ void SCH_IO_KICAD_SEXPR::saveSymbol( SCH_SYMBOL* aSymbol, const SCHEMATIC& aSche auto it = projectInstances.find( inst.m_Path[0] ); if( it == projectInstances.end() ) - { projectInstances[ inst.m_Path[0] ] = { inst }; - } else - { it->second.emplace_back( inst ); - } } for( auto& [uuid, instances] : projectInstances ) @@ -881,8 +830,7 @@ void SCH_IO_KICAD_SEXPR::saveSymbol( SCH_SYMBOL* aSymbol, const SCHEMATIC& aSche projectName = instances[0].m_ProjectName; - m_out->Print( aNestLevel + 2, "(project %s\n", - m_out->Quotew( projectName ).c_str() ); + m_out->Print( "(project %s", m_out->Quotew( projectName ).c_str() ); for( const SCH_SYMBOL_INSTANCE& instance : instances ) { @@ -894,25 +842,23 @@ void SCH_IO_KICAD_SEXPR::saveSymbol( SCH_SYMBOL* aSymbol, const SCHEMATIC& aSche path = tmp.AsString(); - m_out->Print( aNestLevel + 3, "(path %s\n", - m_out->Quotew( path ).c_str() ); - m_out->Print( aNestLevel + 4, "(reference %s) (unit %d)\n", + m_out->Print( "(path %s (reference %s) (unit %d))", + m_out->Quotew( path ).c_str(), m_out->Quotew( instance.m_Reference ).c_str(), instance.m_Unit ); - m_out->Print( aNestLevel + 3, ")\n" ); } - m_out->Print( aNestLevel + 2, ")\n" ); // Closes `project`. + m_out->Print( ")" ); // Closes `project`. } - m_out->Print( aNestLevel + 1, ")\n" ); // Closes `instances`. + m_out->Print( ")" ); // Closes `instances`. } - m_out->Print( aNestLevel, ")\n" ); // Closes `symbol`. + m_out->Print( ")" ); // Closes `symbol`. } -void SCH_IO_KICAD_SEXPR::saveField( SCH_FIELD* aField, int aNestLevel ) +void SCH_IO_KICAD_SEXPR::saveField( SCH_FIELD* aField ) { wxCHECK_RET( aField != nullptr && m_out != nullptr, "" ); @@ -935,7 +881,7 @@ void SCH_IO_KICAD_SEXPR::saveField( SCH_FIELD* aField, int aNestLevel ) m_nextFreeFieldId = aField->GetId() + 1; } - m_out->Print( aNestLevel, "(property %s %s (at %s %s %s)", + m_out->Print( "(property %s %s (at %s %s %s)", m_out->Quotew( fieldName ).c_str(), m_out->Quotew( aField->GetText() ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, @@ -945,26 +891,22 @@ void SCH_IO_KICAD_SEXPR::saveField( SCH_FIELD* aField, int aNestLevel ) EDA_UNIT_UTILS::FormatAngle( aField->GetTextAngle() ).c_str() ); if( aField->IsNameShown() ) - m_out->Print( 0, " (show_name yes)" ); + KICAD_FORMAT::FormatBool( m_out, "show_name", true ); if( !aField->CanAutoplace() ) - m_out->Print( 0, " (do_not_autoplace yes)" ); + KICAD_FORMAT::FormatBool( m_out, "do_not_autoplace", true ); if( !aField->IsDefaultFormatting() - || ( aField->GetTextHeight() != schIUScale.MilsToIU( DEFAULT_SIZE_TEXT ) ) ) + || ( aField->GetTextHeight() != schIUScale.MilsToIU( DEFAULT_SIZE_TEXT ) ) ) { - m_out->Print( 0, "\n" ); - aField->Format( m_out, aNestLevel, 0 ); - m_out->Print( aNestLevel, ")\n" ); // Closes property token with font effects. - } - else - { - m_out->Print( 0, ")\n" ); // Closes property token without font effects. + aField->Format( m_out, 0 ); } + + m_out->Print( ")" ); // Closes `property` token } -void SCH_IO_KICAD_SEXPR::saveBitmap( const SCH_BITMAP& aBitmap, int aNestLevel ) +void SCH_IO_KICAD_SEXPR::saveBitmap( const SCH_BITMAP& aBitmap ) { wxCHECK_RET( m_out != nullptr, "" ); @@ -975,7 +917,7 @@ void SCH_IO_KICAD_SEXPR::saveBitmap( const SCH_BITMAP& aBitmap, int aNestLevel ) wxCHECK_RET( image != nullptr, "wxImage* is NULL" ); - m_out->Print( aNestLevel, "(image (at %s %s)", + m_out->Print( "(image (at %s %s)", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, refImage.GetPosition().x ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, @@ -986,16 +928,14 @@ void SCH_IO_KICAD_SEXPR::saveBitmap( const SCH_BITMAP& aBitmap, int aNestLevel ) // 20230121 or older file format versions assumed 300 image PPI at load/save. // Let's keep compatibility by changing image scale. if( SEXPR_SCHEMATIC_FILE_VERSION <= 20230121 ) - { scale = scale * 300.0 / bitmapBase.GetPPI(); - } if( scale != 1.0 ) - m_out->Print( 0, " (scale %g)", scale ); + m_out->Print( "(scale %g)", scale ); - KICAD_FORMAT::FormatUuid( m_out, 0, aBitmap.m_Uuid, '\n' ); + KICAD_FORMAT::FormatUuid( m_out, aBitmap.m_Uuid ); - m_out->Print( aNestLevel + 1, "(data" ); + m_out->Print( "(data" ); wxString out = wxBase64Encode( bitmapBase.GetImageDataBuffer() ); @@ -1007,23 +947,20 @@ void SCH_IO_KICAD_SEXPR::saveBitmap( const SCH_BITMAP& aBitmap, int aNestLevel ) while( first < out.Length() ) { - m_out->Print( 0, "\n" ); - m_out->Print( aNestLevel + 2, "\"%s\"", TO_UTF8( out( first, MIME_BASE64_LENGTH ) ) ); + m_out->Print( "\n\"%s\"", TO_UTF8( out( first, MIME_BASE64_LENGTH ) ) ); first += MIME_BASE64_LENGTH; } - m_out->Print( 0, "\n" ); - m_out->Print( aNestLevel + 1, ")\n" ); // Closes data token. - m_out->Print( aNestLevel, ")\n" ); // Closes image token. + m_out->Print( ")" ); // Closes data token. + m_out->Print( ")" ); // Closes image token. } -void SCH_IO_KICAD_SEXPR::saveSheet( SCH_SHEET* aSheet, const SCH_SHEET_LIST& aSheetList, - int aNestLevel ) +void SCH_IO_KICAD_SEXPR::saveSheet( SCH_SHEET* aSheet, const SCH_SHEET_LIST& aSheetList ) { wxCHECK_RET( aSheet != nullptr && m_out != nullptr, "" ); - m_out->Print( aNestLevel, "(sheet (at %s %s) (size %s %s)", + m_out->Print( "(sheet (at %s %s) (size %s %s)", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aSheet->GetPosition().x ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, @@ -1033,41 +970,35 @@ void SCH_IO_KICAD_SEXPR::saveSheet( SCH_SHEET* aSheet, const SCH_SHEET_LIST& aSh EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aSheet->GetSize().y ).c_str() ); - m_out->Print( 0, " (exclude_from_sim %s)", ( aSheet->GetExcludedFromSim() ) ? "yes" : "no" ); - m_out->Print( 0, " (in_bom %s)", ( aSheet->GetExcludedFromBOM() ) ? "no" : "yes" ); - m_out->Print( 0, " (on_board %s)", ( aSheet->GetExcludedFromBoard() ) ? "no" : "yes" ); - m_out->Print( 0, " (dnp %s)", ( aSheet->GetDNP() ) ? "yes" : "no" ); + KICAD_FORMAT::FormatBool( m_out, "exclude_from_sim", aSheet->GetExcludedFromSim() ); + KICAD_FORMAT::FormatBool( m_out, "in_bom", !aSheet->GetExcludedFromBOM() ); + KICAD_FORMAT::FormatBool( m_out, "on_board", !aSheet->GetExcludedFromBoard() ); + KICAD_FORMAT::FormatBool( m_out, "dnp", aSheet->GetDNP() ); if( aSheet->GetFieldsAutoplaced() != FIELDS_AUTOPLACED_NO ) - m_out->Print( 0, " (fields_autoplaced yes)" ); - - m_out->Print( 0, "\n" ); + KICAD_FORMAT::FormatBool( m_out, "fields_autoplaced", true ); STROKE_PARAMS stroke( aSheet->GetBorderWidth(), LINE_STYLE::SOLID, aSheet->GetBorderColor() ); stroke.SetWidth( aSheet->GetBorderWidth() ); - stroke.Format( m_out, schIUScale, aNestLevel + 1 ); + stroke.Format( m_out, schIUScale ); - m_out->Print( 0, "\n" ); - - m_out->Print( aNestLevel + 1, "(fill (color %d %d %d %0.4f))\n", + m_out->Print( "(fill (color %d %d %d %0.4f))", KiROUND( aSheet->GetBackgroundColor().r * 255.0 ), KiROUND( aSheet->GetBackgroundColor().g * 255.0 ), KiROUND( aSheet->GetBackgroundColor().b * 255.0 ), aSheet->GetBackgroundColor().a ); - KICAD_FORMAT::FormatUuid( m_out, aNestLevel + 1, aSheet->m_Uuid, '\n' ); + KICAD_FORMAT::FormatUuid( m_out, aSheet->m_Uuid ); m_nextFreeFieldId = SHEET_MANDATORY_FIELDS; for( SCH_FIELD& field : aSheet->GetFields() ) - { - saveField( &field, aNestLevel + 1 ); - } + saveField( &field ); for( const SCH_SHEET_PIN* pin : aSheet->GetPins() ) { - m_out->Print( aNestLevel + 1, "(pin %s %s (at %s %s %s)", + m_out->Print( "(pin %s %s (at %s %s %s)", EscapedUTF8( pin->GetText() ).c_str(), getSheetPinShapeToken( pin->GetShape() ), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, @@ -1076,11 +1007,11 @@ void SCH_IO_KICAD_SEXPR::saveSheet( SCH_SHEET* aSheet, const SCH_SHEET_LIST& aSh pin->GetPosition().y ).c_str(), EDA_UNIT_UTILS::FormatAngle( getSheetPinAngle( pin->GetSide() ) ).c_str() ); - KICAD_FORMAT::FormatUuid( m_out, 0, pin->m_Uuid, '\n' ); + KICAD_FORMAT::FormatUuid( m_out, pin->m_Uuid ); - pin->Format( m_out, aNestLevel + 2, 0 ); + pin->Format( m_out, 0 ); - m_out->Print( aNestLevel + 1, ")\n" ); // Closes pin token. + m_out->Print( ")" ); // Closes pin token. } // Save all sheet instances here except the root sheet instance. @@ -1098,11 +1029,11 @@ void SCH_IO_KICAD_SEXPR::saveSheet( SCH_SHEET* aSheet, const SCH_SHEET_LIST& aSh if( !sheetInstances.empty() ) { - m_out->Print( aNestLevel + 1, "(instances\n" ); + m_out->Print( "(instances" ); KIID lastProjectUuid; KIID rootSheetUuid = m_schematic->Root().m_Uuid; - bool project_open = false; + bool inProjectClause = false; for( size_t i = 0; i < sheetInstances.size(); i++ ) { @@ -1112,13 +1043,13 @@ void SCH_IO_KICAD_SEXPR::saveSheet( SCH_SHEET* aSheet, const SCH_SHEET_LIST& aSh // // Keep all instance data when copying to the clipboard. It may be needed on paste. if( ( sheetInstances[i].m_Path[0] == rootSheetUuid ) - && !aSheetList.GetSheetPathByKIIDPath( sheetInstances[i].m_Path, false ) ) + && !aSheetList.GetSheetPathByKIIDPath( sheetInstances[i].m_Path, false ) ) { - if( project_open && ( ( i + 1 == sheetInstances.size() ) - || lastProjectUuid != sheetInstances[i+1].m_Path[0] ) ) + if( inProjectClause && ( ( i + 1 == sheetInstances.size() ) + || lastProjectUuid != sheetInstances[i+1].m_Path[0] ) ) { - m_out->Print( aNestLevel + 2, ")\n" ); // Closes `project` token. - project_open = false; + m_out->Print( ")" ); // Closes `project` token. + inProjectClause = false; } continue; @@ -1134,37 +1065,36 @@ void SCH_IO_KICAD_SEXPR::saveSheet( SCH_SHEET* aSheet, const SCH_SHEET_LIST& aSh projectName = sheetInstances[i].m_ProjectName; lastProjectUuid = sheetInstances[i].m_Path[0]; - m_out->Print( aNestLevel + 2, "(project %s\n", - m_out->Quotew( projectName ).c_str() ); - project_open = true; + m_out->Print( "(project %s", m_out->Quotew( projectName ).c_str() ); + inProjectClause = true; } wxString path = sheetInstances[i].m_Path.AsString(); - m_out->Print( aNestLevel + 3, "(path %s (page %s))\n", + m_out->Print( "(path %s (page %s))", m_out->Quotew( path ).c_str(), m_out->Quotew( sheetInstances[i].m_PageNumber ).c_str() ); - if( project_open && ( ( i + 1 == sheetInstances.size() ) - || lastProjectUuid != sheetInstances[i+1].m_Path[0] ) ) + if( inProjectClause && ( ( i + 1 == sheetInstances.size() ) + || lastProjectUuid != sheetInstances[i+1].m_Path[0] ) ) { - m_out->Print( aNestLevel + 2, ")\n" ); // Closes `project` token. - project_open = false; + m_out->Print( ")" ); // Closes `project` token. + inProjectClause = false; } } - m_out->Print( aNestLevel + 1, ")\n" ); // Closes `instances` token. + m_out->Print( ")" ); // Closes `instances` token. } - m_out->Print( aNestLevel, ")\n" ); // Closes sheet token. + m_out->Print( ")" ); // Closes sheet token. } -void SCH_IO_KICAD_SEXPR::saveJunction( SCH_JUNCTION* aJunction, int aNestLevel ) +void SCH_IO_KICAD_SEXPR::saveJunction( SCH_JUNCTION* aJunction ) { wxCHECK_RET( aJunction != nullptr && m_out != nullptr, "" ); - m_out->Print( aNestLevel, "(junction (at %s %s) (diameter %s) (color %d %d %d %s)\n", + m_out->Print( "(junction (at %s %s) (diameter %s) (color %d %d %d %s)", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aJunction->GetPosition().x ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, @@ -1176,26 +1106,27 @@ void SCH_IO_KICAD_SEXPR::saveJunction( SCH_JUNCTION* aJunction, int aNestLevel ) KiROUND( aJunction->GetColor().b * 255.0 ), FormatDouble2Str( aJunction->GetColor().a ).c_str() ); - KICAD_FORMAT::FormatUuid( m_out, aNestLevel + 1, aJunction->m_Uuid ); - m_out->Print( 0, ")\n" ); + KICAD_FORMAT::FormatUuid( m_out, aJunction->m_Uuid ); + m_out->Print( ")" ); } -void SCH_IO_KICAD_SEXPR::saveNoConnect( SCH_NO_CONNECT* aNoConnect, int aNestLevel ) +void SCH_IO_KICAD_SEXPR::saveNoConnect( SCH_NO_CONNECT* aNoConnect ) { wxCHECK_RET( aNoConnect != nullptr && m_out != nullptr, "" ); - m_out->Print( aNestLevel, "(no_connect (at %s %s)", + m_out->Print( "(no_connect (at %s %s)", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aNoConnect->GetPosition().x ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aNoConnect->GetPosition().y ).c_str() ); - KICAD_FORMAT::FormatUuid( m_out, 0, aNoConnect->m_Uuid ); - m_out->Print( 0, ")\n" ); + + KICAD_FORMAT::FormatUuid( m_out, aNoConnect->m_Uuid ); + m_out->Print( ")" ); } -void SCH_IO_KICAD_SEXPR::saveBusEntry( SCH_BUS_ENTRY_BASE* aBusEntry, int aNestLevel ) +void SCH_IO_KICAD_SEXPR::saveBusEntry( SCH_BUS_ENTRY_BASE* aBusEntry ) { wxCHECK_RET( aBusEntry != nullptr && m_out != nullptr, "" ); @@ -1205,58 +1136,54 @@ void SCH_IO_KICAD_SEXPR::saveBusEntry( SCH_BUS_ENTRY_BASE* aBusEntry, int aNestL SCH_LINE busEntryLine( aBusEntry->GetPosition(), LAYER_BUS ); busEntryLine.SetEndPoint( aBusEntry->GetEnd() ); - saveLine( &busEntryLine, aNestLevel ); + saveLine( &busEntryLine ); + return; } - else - { - m_out->Print( aNestLevel, "(bus_entry (at %s %s) (size %s %s)\n", - EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, - aBusEntry->GetPosition().x ).c_str(), - EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, - aBusEntry->GetPosition().y ).c_str(), - EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, - aBusEntry->GetSize().x ).c_str(), - EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, - aBusEntry->GetSize().y ).c_str() ); - aBusEntry->GetStroke().Format( m_out, schIUScale, aNestLevel + 1 ); + m_out->Print( "(bus_entry (at %s %s) (size %s %s)", + EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, + aBusEntry->GetPosition().x ).c_str(), + EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, + aBusEntry->GetPosition().y ).c_str(), + EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, + aBusEntry->GetSize().x ).c_str(), + EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, + aBusEntry->GetSize().y ).c_str() ); - m_out->Print( 0, "\n" ); - - KICAD_FORMAT::FormatUuid( m_out, aNestLevel + 1, aBusEntry->m_Uuid ); - m_out->Print( 0, ")\n" ); - } + aBusEntry->GetStroke().Format( m_out, schIUScale ); + KICAD_FORMAT::FormatUuid( m_out, aBusEntry->m_Uuid ); + m_out->Print( ")" ); } -void SCH_IO_KICAD_SEXPR::saveShape( SCH_SHAPE* aShape, int aNestLevel ) +void SCH_IO_KICAD_SEXPR::saveShape( SCH_SHAPE* aShape ) { wxCHECK_RET( aShape != nullptr && m_out != nullptr, "" ); switch( aShape->GetShape() ) { case SHAPE_T::ARC: - formatArc( m_out, aNestLevel, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), + formatArc( m_out, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), aShape->GetFillColor(), false, aShape->m_Uuid ); break; case SHAPE_T::CIRCLE: - formatCircle( m_out, aNestLevel, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), + formatCircle( m_out, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), aShape->GetFillColor(), false, aShape->m_Uuid ); break; case SHAPE_T::RECTANGLE: - formatRect( m_out, aNestLevel, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), + formatRect( m_out, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), aShape->GetFillColor(), false, aShape->m_Uuid ); break; case SHAPE_T::BEZIER: - formatBezier( m_out, aNestLevel, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), + formatBezier( m_out, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), aShape->GetFillColor(), false, aShape->m_Uuid ); break; case SHAPE_T::POLY: - formatPoly( m_out, aNestLevel, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), + formatPoly( m_out, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), aShape->GetFillColor(), false, aShape->m_Uuid ); break; @@ -1266,17 +1193,17 @@ void SCH_IO_KICAD_SEXPR::saveShape( SCH_SHAPE* aShape, int aNestLevel ) } -void SCH_IO_KICAD_SEXPR::saveRuleArea( SCH_RULE_AREA* aRuleArea, int aNestLevel ) +void SCH_IO_KICAD_SEXPR::saveRuleArea( SCH_RULE_AREA* aRuleArea ) { wxCHECK_RET( aRuleArea != nullptr && m_out != nullptr, "" ); - m_out->Print( aNestLevel, "(rule_area " ); - saveShape( aRuleArea, aNestLevel + 1 ); - m_out->Print( aNestLevel, ")\n" ); + m_out->Print( "(rule_area " ); + saveShape( aRuleArea ); + m_out->Print( ")" ); } -void SCH_IO_KICAD_SEXPR::saveLine( SCH_LINE* aLine, int aNestLevel ) +void SCH_IO_KICAD_SEXPR::saveLine( SCH_LINE* aLine ) { wxCHECK_RET( aLine != nullptr && m_out != nullptr, "" ); @@ -1293,7 +1220,7 @@ void SCH_IO_KICAD_SEXPR::saveLine( SCH_LINE* aLine, int aNestLevel ) UNIMPLEMENTED_FOR( LayerName( aLine->GetLayer() ) ); } - m_out->Print( aNestLevel, "(%s (pts (xy %s %s) (xy %s %s))\n", + m_out->Print( "(%s (pts (xy %s %s) (xy %s %s))", TO_UTF8( lineType ), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aLine->GetStartPoint().x ).c_str(), @@ -1304,34 +1231,31 @@ void SCH_IO_KICAD_SEXPR::saveLine( SCH_LINE* aLine, int aNestLevel ) EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aLine->GetEndPoint().y ).c_str() ); - line_stroke.Format( m_out, schIUScale, aNestLevel + 1 ); - m_out->Print( 0, "\n" ); - - KICAD_FORMAT::FormatUuid( m_out, aNestLevel + 1, aLine->m_Uuid ); - m_out->Print( 0, ")\n" ); + line_stroke.Format( m_out, schIUScale ); + KICAD_FORMAT::FormatUuid( m_out, aLine->m_Uuid ); + m_out->Print( ")" ); } -void SCH_IO_KICAD_SEXPR::saveText( SCH_TEXT* aText, int aNestLevel ) +void SCH_IO_KICAD_SEXPR::saveText( SCH_TEXT* aText ) { wxCHECK_RET( aText != nullptr && m_out != nullptr, "" ); // Note: label is nullptr SCH_TEXT, but not for SCH_LABEL_XXX, SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( aText ); - m_out->Print( aNestLevel, "(%s %s", + m_out->Print( "(%s %s", getTextTypeToken( aText->Type() ), m_out->Quotew( aText->GetText() ).c_str() ); if( aText->Type() == SCH_TEXT_T ) - { - m_out->Print( 0, " (exclude_from_sim %s)\n", aText->GetExcludedFromSim() ? "yes" : "no" ); - } - else if( aText->Type() == SCH_DIRECTIVE_LABEL_T ) + KICAD_FORMAT::FormatBool( m_out, "exclude_from_sim", aText->GetExcludedFromSim() ); + + if( aText->Type() == SCH_DIRECTIVE_LABEL_T ) { SCH_DIRECTIVE_LABEL* flag = static_cast<SCH_DIRECTIVE_LABEL*>( aText ); - m_out->Print( 0, " (length %s)", + m_out->Print( "(length %s)", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, flag->GetPinLength() ).c_str() ); } @@ -1344,7 +1268,7 @@ void SCH_IO_KICAD_SEXPR::saveText( SCH_TEXT* aText, int aNestLevel ) || label->Type() == SCH_HIER_LABEL_T || label->Type() == SCH_DIRECTIVE_LABEL_T ) { - m_out->Print( 0, " (shape %s)", getSheetPinShapeToken( label->GetShape() ) ); + m_out->Print( "(shape %s)", getSheetPinShapeToken( label->GetShape() ) ); } // The angle of the text is always 0 or 90 degrees for readibility reasons, @@ -1361,7 +1285,7 @@ void SCH_IO_KICAD_SEXPR::saveText( SCH_TEXT* aText, int aNestLevel ) if( aText->GetText().Length() < 50 ) { - m_out->Print( 0, " (at %s %s %s)", + m_out->Print( "(at %s %s %s)", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aText->GetPosition().x ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, @@ -1370,8 +1294,7 @@ void SCH_IO_KICAD_SEXPR::saveText( SCH_TEXT* aText, int aNestLevel ) } else { - m_out->Print( 0, "\n" ); - m_out->Print( aNestLevel + 1, "(at %s %s %s)", + m_out->Print( "(at %s %s %s)", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aText->GetPosition().x ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, @@ -1380,36 +1303,35 @@ void SCH_IO_KICAD_SEXPR::saveText( SCH_TEXT* aText, int aNestLevel ) } if( aText->GetFieldsAutoplaced() != FIELDS_AUTOPLACED_NO ) - m_out->Print( 0, " (fields_autoplaced yes)" ); + KICAD_FORMAT::FormatBool( m_out, "fields_autoplaced", true ); - m_out->Print( 0, "\n" ); - aText->EDA_TEXT::Format( m_out, aNestLevel + 1, 0 ); - - KICAD_FORMAT::FormatUuid( m_out, aNestLevel + 1, aText->m_Uuid ); + aText->EDA_TEXT::Format( m_out, 0 ); + KICAD_FORMAT::FormatUuid( m_out, aText->m_Uuid ); if( label ) { for( SCH_FIELD& field : label->GetFields() ) - saveField( &field, aNestLevel + 1 ); + saveField( &field ); } - m_out->Print( 0, ")\n" ); // Closes text token. + m_out->Print( ")" ); // Closes text token. } -void SCH_IO_KICAD_SEXPR::saveTextBox( SCH_TEXTBOX* aTextBox, int aNestLevel ) +void SCH_IO_KICAD_SEXPR::saveTextBox( SCH_TEXTBOX* aTextBox ) { wxCHECK_RET( aTextBox != nullptr && m_out != nullptr, "" ); - m_out->Print( aNestLevel, "(%s %s\n", + m_out->Print( "(%s %s", aTextBox->Type() == SCH_TABLECELL_T ? "table_cell" : "text_box", m_out->Quotew( aTextBox->GetText() ).c_str() ); + KICAD_FORMAT::FormatBool( m_out, "exclude_from_sim", aTextBox->GetExcludedFromSim() ); + VECTOR2I pos = aTextBox->GetStart(); VECTOR2I size = aTextBox->GetEnd() - pos; - m_out->Print( aNestLevel + 1, "(exclude_from_sim %s) (at %s %s %s) (size %s %s) (margins %s %s %s %s)", - aTextBox->GetExcludedFromSim() ? "yes" : "no", + m_out->Print( "(at %s %s %s) (size %s %s) (margins %s %s %s %s)", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pos.x ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pos.y ).c_str(), EDA_UNIT_UTILS::FormatAngle( aTextBox->GetTextAngle() ).c_str(), @@ -1421,29 +1343,19 @@ void SCH_IO_KICAD_SEXPR::saveTextBox( SCH_TEXTBOX* aTextBox, int aNestLevel ) EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aTextBox->GetMarginBottom() ).c_str() ); if( SCH_TABLECELL* cell = dynamic_cast<SCH_TABLECELL*>( aTextBox ) ) - m_out->Print( 0, " (span %d %d)", cell->GetColSpan(), cell->GetRowSpan() ); - - m_out->Print( 0, "\n" ); + m_out->Print( "(span %d %d)", cell->GetColSpan(), cell->GetRowSpan() ); if( aTextBox->Type() != SCH_TABLECELL_T ) - { - aTextBox->GetStroke().Format( m_out, schIUScale, aNestLevel + 1 ); - m_out->Print( 0, "\n" ); - } + aTextBox->GetStroke().Format( m_out, schIUScale ); - formatFill( m_out, aNestLevel + 1, aTextBox->GetFillMode(), aTextBox->GetFillColor() ); - m_out->Print( 0, "\n" ); - - aTextBox->EDA_TEXT::Format( m_out, aNestLevel, 0 ); - - if( aTextBox->m_Uuid != niluuid ) - KICAD_FORMAT::FormatUuid( m_out, aNestLevel + 1, aTextBox->m_Uuid ); - - m_out->Print( 0, ")\n" ); + formatFill( m_out, aTextBox->GetFillMode(), aTextBox->GetFillColor() ); + aTextBox->EDA_TEXT::Format( m_out, 0 ); + KICAD_FORMAT::FormatUuid( m_out, aTextBox->m_Uuid ); + m_out->Print( ")" ); } -void SCH_IO_KICAD_SEXPR::saveTable( SCH_TABLE* aTable, int aNestLevel ) +void SCH_IO_KICAD_SEXPR::saveTable( SCH_TABLE* aTable ) { if( aTable->GetFlags() & SKIP_STRUCT ) { @@ -1492,69 +1404,62 @@ void SCH_IO_KICAD_SEXPR::saveTable( SCH_TABLE* aTable, int aNestLevel ) wxCHECK_RET( aTable != nullptr && m_out != nullptr, "" ); - m_out->Print( aNestLevel, "(table (column_count %d)\n", - aTable->GetColCount() ); + m_out->Print( "(table (column_count %d)", aTable->GetColCount() ); - m_out->Print( aNestLevel + 1, "(border (external %s) (header %s)", - aTable->StrokeExternal() ? "yes" : "no", - aTable->StrokeHeader() ? "yes" : "no" ); + m_out->Print( "(border" ); + KICAD_FORMAT::FormatBool( m_out, "external", aTable->StrokeExternal() ); + KICAD_FORMAT::FormatBool( m_out, "header", aTable->StrokeHeader() ); if( aTable->StrokeExternal() || aTable->StrokeHeader() ) - { - m_out->Print( 0, " " ); - aTable->GetBorderStroke().Format( m_out, schIUScale, 0 ); - } + aTable->GetBorderStroke().Format( m_out, schIUScale ); - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); // Close `border` token. - m_out->Print( aNestLevel + 1, "(separators (rows %s) (cols %s)", - aTable->StrokeRows() ? "yes" : "no", - aTable->StrokeColumns() ? "yes" : "no" ); + m_out->Print( "(separators" ); + KICAD_FORMAT::FormatBool( m_out, "rows", aTable->StrokeRows() ); + KICAD_FORMAT::FormatBool( m_out, "cols", aTable->StrokeColumns() ); if( aTable->StrokeRows() || aTable->StrokeColumns() ) - { - m_out->Print( 0, " " ); - aTable->GetSeparatorsStroke().Format( m_out, schIUScale, 0 ); - } + aTable->GetSeparatorsStroke().Format( m_out, schIUScale ); - m_out->Print( 0, ")\n" ); // Close `separators` token. + m_out->Print( ")" ); // Close `separators` token. - m_out->Print( aNestLevel + 1, "(column_widths" ); + m_out->Print( "(column_widths" ); for( int col = 0; col < aTable->GetColCount(); ++col ) { - m_out->Print( 0, " %s", + m_out->Print( " %s", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aTable->GetColWidth( col ) ).c_str() ); } - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); - m_out->Print( aNestLevel + 1, "(row_heights" ); + m_out->Print( "(row_heights" ); for( int row = 0; row < aTable->GetRowCount(); ++row ) { - m_out->Print( 0, " %s", + m_out->Print( " %s", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aTable->GetRowHeight( row ) ).c_str() ); } - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); - m_out->Print( aNestLevel + 1, "(cells\n" ); + m_out->Print( "(cells" ); for( SCH_TABLECELL* cell : aTable->GetCells() ) - saveTextBox( cell, aNestLevel + 2 ); + saveTextBox( cell ); - m_out->Print( aNestLevel + 1, ")\n" ); // Close `cells` token. - m_out->Print( aNestLevel, ")\n" ); // Close `table` token. + m_out->Print( ")" ); // Close `cells` token. + m_out->Print( ")" ); // Close `table` token. if( aTable->GetFlags() & SKIP_STRUCT ) delete aTable; } -void SCH_IO_KICAD_SEXPR::saveBusAlias( std::shared_ptr<BUS_ALIAS> aAlias, int aNestLevel ) +void SCH_IO_KICAD_SEXPR::saveBusAlias( std::shared_ptr<BUS_ALIAS> aAlias ) { wxCHECK_RET( aAlias != nullptr, "BUS_ALIAS* is NULL" ); @@ -1568,19 +1473,17 @@ void SCH_IO_KICAD_SEXPR::saveBusAlias( std::shared_ptr<BUS_ALIAS> aAlias, int aN members += m_out->Quotew( member ); } - m_out->Print( aNestLevel, "(bus_alias %s (members %s))\n", + m_out->Print( "(bus_alias %s (members %s))", m_out->Quotew( aAlias->GetName() ).c_str(), TO_UTF8( members ) ); } -void SCH_IO_KICAD_SEXPR::saveInstances( const std::vector<SCH_SHEET_INSTANCE>& aInstances, - int aNestLevel ) +void SCH_IO_KICAD_SEXPR::saveInstances( const std::vector<SCH_SHEET_INSTANCE>& aInstances ) { if( aInstances.size() ) { - m_out->Print( 0, "\n" ); - m_out->Print( aNestLevel, "(sheet_instances\n" ); + m_out->Print( "(sheet_instances" ); for( const SCH_SHEET_INSTANCE& instance : aInstances ) { @@ -1589,12 +1492,12 @@ void SCH_IO_KICAD_SEXPR::saveInstances( const std::vector<SCH_SHEET_INSTANCE>& a if( path.IsEmpty() ) path = wxT( "/" ); // Root path - m_out->Print( aNestLevel + 1, "(path %s (page %s))\n", + m_out->Print( "(path %s (page %s))", m_out->Quotew( path ).c_str(), m_out->Quotew( instance.m_PageNumber ).c_str() ); } - m_out->Print( aNestLevel, ")\n" ); // Close sheet instances token. + m_out->Print( ")" ); // Close sheet instances token. } } diff --git a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.h b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.h index d454442c4a..b324a16da8 100644 --- a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.h +++ b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.h @@ -142,22 +142,22 @@ private: void loadFile( const wxString& aFileName, SCH_SHEET* aSheet ); void saveSymbol( SCH_SYMBOL* aSymbol, const SCHEMATIC& aSchematic, - const SCH_SHEET_LIST& aSheetList, int aNestLevel, - bool aForClipboard, const SCH_SHEET_PATH* aRelativePath = nullptr ); - void saveField( SCH_FIELD* aField, int aNestLevel ); - void saveBitmap( const SCH_BITMAP& aBitmap, int aNestLevel ); - void saveSheet( SCH_SHEET* aSheet, const SCH_SHEET_LIST& aSheetList, int aNestLevel ); - void saveJunction( SCH_JUNCTION* aJunction, int aNestLevel ); - void saveNoConnect( SCH_NO_CONNECT* aNoConnect, int aNestLevel ); - void saveBusEntry( SCH_BUS_ENTRY_BASE* aBusEntry, int aNestLevel ); - void saveLine( SCH_LINE* aLine, int aNestLevel ); - void saveShape( SCH_SHAPE* aShape, int aNestLevel ); - void saveRuleArea( SCH_RULE_AREA* aRuleArea, int aNestLevel ); - void saveText( SCH_TEXT* aText, int aNestLevel ); - void saveTextBox( SCH_TEXTBOX* aText, int aNestLevel ); - void saveTable( SCH_TABLE* aTable, int aNestLevel ); - void saveBusAlias( std::shared_ptr<BUS_ALIAS> aAlias, int aNestLevel ); - void saveInstances( const std::vector<SCH_SHEET_INSTANCE>& aSheets, int aNestLevel ); + const SCH_SHEET_LIST& aSheetList, bool aForClipboard, + const SCH_SHEET_PATH* aRelativePath = nullptr ); + void saveField( SCH_FIELD* aField ); + void saveBitmap( const SCH_BITMAP& aBitmap ); + void saveSheet( SCH_SHEET* aSheet, const SCH_SHEET_LIST& aSheetList ); + void saveJunction( SCH_JUNCTION* aJunction ); + void saveNoConnect( SCH_NO_CONNECT* aNoConnect ); + void saveBusEntry( SCH_BUS_ENTRY_BASE* aBusEntry ); + void saveLine( SCH_LINE* aLine ); + void saveShape( SCH_SHAPE* aShape ); + void saveRuleArea( SCH_RULE_AREA* aRuleArea ); + void saveText( SCH_TEXT* aText ); + void saveTextBox( SCH_TEXTBOX* aText ); + void saveTable( SCH_TABLE* aTable ); + void saveBusAlias( std::shared_ptr<BUS_ALIAS> aAlias ); + void saveInstances( const std::vector<SCH_SHEET_INSTANCE>& aSheets ); void cacheLib( const wxString& aLibraryFileName, const std::map<std::string, UTF8>* aProperties ); bool isBuffering( const std::map<std::string, UTF8>* aProperties ); diff --git a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_common.cpp b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_common.cpp index 973632a659..bb56ebc71f 100644 --- a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_common.cpp +++ b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_common.cpp @@ -17,7 +17,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <advanced_config.h> #include <base_units.h> #include <macros.h> #include <schematic_lexer.h> @@ -31,8 +30,7 @@ using namespace TSCHEMATIC_T; static const char* emptyString = ""; -void formatFill( OUTPUTFORMATTER* aFormatter, int aNestLevel, FILL_T aFillMode, - const COLOR4D& aFillColor ) +void formatFill( OUTPUTFORMATTER* aFormatter, FILL_T aFillMode, const COLOR4D& aFillColor ) { const char* fillType; @@ -47,7 +45,7 @@ void formatFill( OUTPUTFORMATTER* aFormatter, int aNestLevel, FILL_T aFillMode, if( aFillMode == FILL_T::FILLED_WITH_COLOR ) { - aFormatter->Print( aNestLevel, "(fill (type %s) (color %d %d %d %s))", + aFormatter->Print( "(fill (type %s) (color %d %d %d %s))", fillType, KiROUND( aFillColor.r * 255.0 ), KiROUND( aFillColor.g * 255.0 ), @@ -56,7 +54,7 @@ void formatFill( OUTPUTFORMATTER* aFormatter, int aNestLevel, FILL_T aFillMode, } else { - aFormatter->Print( aNestLevel, "(fill (type %s))", + aFormatter->Print( "(fill (type %s))", fillType ); } } @@ -221,140 +219,105 @@ std::string formatIU( const VECTOR2I& aPt, bool aInvertY ) } -void formatArc( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aArc, - bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, - const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid ) +void formatArc( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aArc, bool aIsPrivate, + const STROKE_PARAMS& aStroke, FILL_T aFillMode, const COLOR4D& aFillColor, + bool aInvertY, const KIID& aUuid ) { - aFormatter->Print( aNestLevel, "(arc%s (start %s) (mid %s) (end %s)\n", - aIsPrivate ? " private" : "", + aFormatter->Print( "(arc %s (start %s) (mid %s) (end %s)", + aIsPrivate ? "private" : "", formatIU( aArc->GetStart(), aInvertY ).c_str(), formatIU( aArc->GetArcMid(), aInvertY ).c_str(), formatIU( aArc->GetEnd(), aInvertY ).c_str() ); - aStroke.Format( aFormatter, schIUScale, aNestLevel + 1 ); - aFormatter->Print( 0, "\n" ); - formatFill( aFormatter, aNestLevel + 1, aFillMode, aFillColor ); - aFormatter->Print( 0, "\n" ); + aStroke.Format( aFormatter, schIUScale ); + formatFill( aFormatter, aFillMode, aFillColor ); if( aUuid != niluuid ) - aFormatter->Print( aNestLevel + 1, "(uuid %s)\n", TO_UTF8( aUuid.AsString() ) ); + aFormatter->Print( "(uuid %s)", TO_UTF8( aUuid.AsString() ) ); - aFormatter->Print( aNestLevel, ")\n" ); + aFormatter->Print( ")" ); } -void formatCircle( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aCircle, - bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, - const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid ) +void formatCircle( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aCircle, bool aIsPrivate, + const STROKE_PARAMS& aStroke, FILL_T aFillMode, const COLOR4D& aFillColor, + bool aInvertY, const KIID& aUuid ) { - aFormatter->Print( aNestLevel, "(circle%s (center %s) (radius %s)\n", - aIsPrivate ? " private" : "", + aFormatter->Print( "(circle %s (center %s) (radius %s)", + aIsPrivate ? "private" : "", formatIU( aCircle->GetStart(), aInvertY ).c_str(), formatIU( aCircle->GetRadius() ).c_str() ); - aStroke.Format( aFormatter, schIUScale, aNestLevel + 1 ); - aFormatter->Print( 0, "\n" ); - formatFill( aFormatter, aNestLevel + 1, aFillMode, aFillColor ); - aFormatter->Print( 0, "\n" ); + aStroke.Format( aFormatter, schIUScale ); + formatFill( aFormatter, aFillMode, aFillColor ); if( aUuid != niluuid ) - aFormatter->Print( aNestLevel + 1, "(uuid %s)\n", TO_UTF8( aUuid.AsString() ) ); + aFormatter->Print( "(uuid %s)", TO_UTF8( aUuid.AsString() ) ); - aFormatter->Print( aNestLevel, ")\n" ); + aFormatter->Print( ")" ); } -void formatRect( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aRect, - bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, - const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid ) +void formatRect( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aRect, bool aIsPrivate, + const STROKE_PARAMS& aStroke, FILL_T aFillMode, const COLOR4D& aFillColor, + bool aInvertY, const KIID& aUuid ) { - aFormatter->Print( aNestLevel, "(rectangle%s (start %s) (end %s)\n", - aIsPrivate ? " private" : "", + aFormatter->Print( "(rectangle %s (start %s) (end %s)", + aIsPrivate ? "private" : "", formatIU( aRect->GetStart(), aInvertY ).c_str(), formatIU( aRect->GetEnd(), aInvertY ).c_str() ); - aStroke.Format( aFormatter, schIUScale, aNestLevel + 1 ); - aFormatter->Print( 0, "\n" ); - formatFill( aFormatter, aNestLevel + 1, aFillMode, aFillColor ); - aFormatter->Print( 0, "\n" ); + aStroke.Format( aFormatter, schIUScale ); + formatFill( aFormatter, aFillMode, aFillColor ); if( aUuid != niluuid ) - aFormatter->Print( aNestLevel + 1, "(uuid %s)\n", TO_UTF8( aUuid.AsString() ) ); + aFormatter->Print( "(uuid %s)", TO_UTF8( aUuid.AsString() ) ); - aFormatter->Print( aNestLevel, ")\n" ); + aFormatter->Print( ")" ); } -void formatBezier( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aBezier, - bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, - const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid ) +void formatBezier( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aBezier, bool aIsPrivate, + const STROKE_PARAMS& aStroke, FILL_T aFillMode, const COLOR4D& aFillColor, + bool aInvertY, const KIID& aUuid ) { - aFormatter->Print( aNestLevel, "(bezier%s (pts ", - aIsPrivate ? " private" : "" ); + aFormatter->Print( "(bezier %s (pts ", + aIsPrivate ? "private" : "" ); for( const VECTOR2I& pt : { aBezier->GetStart(), aBezier->GetBezierC1(), aBezier->GetBezierC2(), aBezier->GetEnd() } ) { - aFormatter->Print( 0, " (xy %s)", - formatIU( pt, aInvertY ).c_str() ); + aFormatter->Print( "(xy %s)", formatIU( pt, aInvertY ).c_str() ); } - aFormatter->Print( 0, ")\n" ); // Closes pts token on same line. + aFormatter->Print( ")" ); // Closes pts token - aStroke.Format( aFormatter, schIUScale, aNestLevel + 1 ); - aFormatter->Print( 0, "\n" ); - formatFill( aFormatter, aNestLevel + 1, aFillMode, aFillColor ); - aFormatter->Print( 0, "\n" ); + aStroke.Format( aFormatter, schIUScale ); + formatFill( aFormatter, aFillMode, aFillColor ); if( aUuid != niluuid ) - aFormatter->Print( aNestLevel + 1, "(uuid %s)\n", TO_UTF8( aUuid.AsString() ) ); + aFormatter->Print( "(uuid %s)", TO_UTF8( aUuid.AsString() ) ); - aFormatter->Print( aNestLevel, ")\n" ); + aFormatter->Print( ")" ); } -void formatPoly( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aPolyLine, - bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, - const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid ) +void formatPoly( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aPolyLine, bool aIsPrivate, + const STROKE_PARAMS& aStroke, FILL_T aFillMode, const COLOR4D& aFillColor, + bool aInvertY, const KIID& aUuid ) { - int newLine = 0; - int lineCount = 1; - aFormatter->Print( aNestLevel, "(polyline%s\n", aIsPrivate ? " private" : "" ); - aFormatter->Print( aNestLevel + 1, "(pts" ); + aFormatter->Print( "(polyline %s (pts ", + aIsPrivate ? "private" : "" ); for( const VECTOR2I& pt : aPolyLine->GetPolyShape().Outline( 0 ).CPoints() ) - { - if( newLine == 4 || !ADVANCED_CFG::GetCfg().m_CompactSave ) - { - aFormatter->Print( 0, "\n" ); - aFormatter->Print( aNestLevel + 2, "(xy %s)", formatIU( pt, aInvertY ).c_str() ); - newLine = 0; - lineCount += 1; - } - else - { - aFormatter->Print( 0, " (xy %s)", formatIU( pt, aInvertY ).c_str() ); - } + aFormatter->Print( "(xy %s)", formatIU( pt, aInvertY ).c_str() ); - newLine += 1; - } + aFormatter->Print( ")" ); // Closes pts token - if( lineCount == 1 ) - { - aFormatter->Print( 0, ")\n" ); // Closes pts token on same line. - } - else - { - aFormatter->Print( 0, "\n" ); - aFormatter->Print( aNestLevel + 1, ")\n" ); // Closes pts token with multiple lines. - } - - aStroke.Format( aFormatter, schIUScale, aNestLevel + 1 ); - aFormatter->Print( 0, "\n" ); - formatFill( aFormatter, aNestLevel + 1, aFillMode, aFillColor ); - aFormatter->Print( 0, "\n" ); + aStroke.Format( aFormatter, schIUScale ); + formatFill( aFormatter, aFillMode, aFillColor ); if( aUuid != niluuid ) - aFormatter->Print( aNestLevel + 1, "(uuid %s)\n", TO_UTF8( aUuid.AsString() ) ); + aFormatter->Print( "(uuid %s)", TO_UTF8( aUuid.AsString() ) ); - aFormatter->Print( aNestLevel, ")\n" ); + aFormatter->Print( ")" ); } diff --git a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_common.h b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_common.h index 2e9a71220d..25d8a9c029 100644 --- a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_common.h +++ b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_common.h @@ -36,8 +36,7 @@ class STROKE_PARAMS; /** * Fill token formatting helper. */ -extern void formatFill( OUTPUTFORMATTER* aFormatter, int aNestLevel, FILL_T aFillMode, - const COLOR4D& aFillColor ); +extern void formatFill( OUTPUTFORMATTER* aFormatter, FILL_T aFillMode, const COLOR4D& aFillColor ); extern const char* getPinElectricalTypeToken( ELECTRICAL_PINTYPE aType ); @@ -51,24 +50,24 @@ extern EDA_ANGLE getSheetPinAngle( SHEET_SIDE aSide ); extern const char* getTextTypeToken( KICAD_T aType ); -extern void formatArc( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aArc, - bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, - const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid = niluuid ); +extern void formatArc( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aArc, bool aIsPrivate, + const STROKE_PARAMS& aStroke, FILL_T aFillMode, const COLOR4D& aFillColor, + bool aInvertY, const KIID& aUuid = niluuid ); -extern void formatCircle( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aCircle, - bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, - const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid = niluuid ); +extern void formatCircle( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aCircle, bool aIsPrivate, + const STROKE_PARAMS& aStroke, FILL_T aFillMode, const COLOR4D& aFillColor, + bool aInvertY, const KIID& aUuid = niluuid ); -extern void formatRect( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aRect, - bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, - const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid = niluuid ); +extern void formatRect( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aRect, bool aIsPrivate, + const STROKE_PARAMS& aStroke, FILL_T aFillMode, const COLOR4D& aFillColor, + bool aInvertY, const KIID& aUuid = niluuid ); -extern void formatBezier( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aBezier, - bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, - const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid = niluuid ); +extern void formatBezier( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aBezier, bool aIsPrivate, + const STROKE_PARAMS& aStroke, FILL_T aFillMode, const COLOR4D& aFillColor, + bool aInvertY, const KIID& aUuid = niluuid ); -extern void formatPoly( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aPolyLine, - bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode, - const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid = niluuid ); +extern void formatPoly( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aPolyLine, bool aIsPrivate, + const STROKE_PARAMS& aStroke, FILL_T aFillMode, const COLOR4D& aFillColor, + bool aInvertY, const KIID& aUuid = niluuid ); #endif // SCH_IO_KICAD_SEXPR_COMMON_H_ diff --git a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_lib_cache.cpp b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_lib_cache.cpp index 719383d3fb..cfb5ed5216 100644 --- a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_lib_cache.cpp +++ b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_lib_cache.cpp @@ -33,6 +33,7 @@ #include "sch_io_kicad_sexpr_parser.h" #include <string_utils.h> #include <trace_helpers.h> +#include <io/kicad/kicad_io_utils.h> SCH_IO_KICAD_SEXPR_LIB_CACHE::SCH_IO_KICAD_SEXPR_LIB_CACHE( const wxString& aFullPathAndFileName ) : @@ -92,9 +93,10 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::Save( const std::optional<bool>& aOpt ) auto formatter = std::make_unique<PRETTIFIED_FILE_OUTPUTFORMATTER>( fn.GetFullPath() ); - formatter->Print( 0, "(kicad_symbol_lib (version %d) (generator \"kicad_symbol_editor\") " - "(generator_version \"%s\")\n", - SEXPR_SYMBOL_LIB_FILE_VERSION, GetMajorMinorVersion().c_str().AsChar() ); + formatter->Print( "(kicad_symbol_lib (version %d) (generator \"kicad_symbol_editor\") " + "(generator_version \"%s\")", + SEXPR_SYMBOL_LIB_FILE_VERSION, + GetMajorMinorVersion().c_str().AsChar() ); std::vector<LIB_SYMBOL*> orderedSymbols; @@ -118,9 +120,9 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::Save( const std::optional<bool>& aOpt ) } ); for( LIB_SYMBOL* symbol : orderedSymbols ) - SaveSymbol( symbol, *formatter.get(), 1 ); + SaveSymbol( symbol, *formatter.get() ); - formatter->Print( 0, ")\n" ); + formatter->Print( ")" ); formatter.reset(); @@ -130,7 +132,7 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::Save( const std::optional<bool>& aOpt ) void SCH_IO_KICAD_SEXPR_LIB_CACHE::SaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMATTER& aFormatter, - int aNestLevel, const wxString& aLibName, bool aIncludeData ) + const wxString& aLibName, bool aIncludeData ) { wxCHECK_RET( aSymbol, "Invalid LIB_SYMBOL pointer." ); @@ -165,51 +167,48 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::SaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMAT if( aSymbol->IsRoot() ) { - aFormatter.Print( aNestLevel, "(symbol %s", name.c_str() ); + aFormatter.Print( "(symbol %s", name.c_str() ); if( aSymbol->IsPower() ) - aFormatter.Print( 0, " (power)" ); + aFormatter.Print( "(power)" ); // TODO: add uuid token here. // TODO: add anchor position token here. if( !aSymbol->GetShowPinNumbers() ) - aFormatter.Print( 0, " (pin_numbers (hide yes))" ); + aFormatter.Print( "(pin_numbers (hide yes))" ); if( aSymbol->GetPinNameOffset() != schIUScale.MilsToIU( DEFAULT_PIN_NAME_OFFSET ) || !aSymbol->GetShowPinNames() ) { - aFormatter.Print( 0, " (pin_names" ); + aFormatter.Print( "(pin_names" ); if( aSymbol->GetPinNameOffset() != schIUScale.MilsToIU( DEFAULT_PIN_NAME_OFFSET ) ) { - aFormatter.Print( 0, " (offset %s)", + aFormatter.Print( "(offset %s)", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aSymbol->GetPinNameOffset() ).c_str() ); } if( !aSymbol->GetShowPinNames() ) - aFormatter.Print( 0, " (hide yes)" ); + KICAD_FORMAT::FormatBool( &aFormatter, "hide", true ); - aFormatter.Print( 0, ")" ); + aFormatter.Print( ")" ); } - aFormatter.Print( 0, " (exclude_from_sim %s)", - ( aSymbol->GetExcludedFromSim() ) ? "yes" : "no" ); - aFormatter.Print( 0, " (in_bom %s)", ( aSymbol->GetExcludedFromBOM() ) ? "no" : "yes" ); - aFormatter.Print( 0, " (on_board %s)", ( aSymbol->GetExcludedFromBoard() ) ? "no" : "yes" ); + KICAD_FORMAT::FormatBool( &aFormatter, "exclude_from_sim", aSymbol->GetExcludedFromSim() ); + KICAD_FORMAT::FormatBool( &aFormatter, "in_bom", !aSymbol->GetExcludedFromBOM() ); + KICAD_FORMAT::FormatBool( &aFormatter, "on_board", !aSymbol->GetExcludedFromBoard() ); // TODO: add atomic token here. // TODO: add required token here." - aFormatter.Print( 0, "\n" ); - aSymbol->GetFields( fields ); for( SCH_FIELD* field : fields ) - saveField( field, aFormatter, aNestLevel + 1 ); + saveField( field, aFormatter ); nextFreeFieldId = aSymbol->GetNextAvailableFieldId(); @@ -219,11 +218,11 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::SaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMAT if( aSymbol->UnitsLocked() ) { SCH_FIELD locked( nullptr, nextFreeFieldId, "ki_locked" ); - saveField( &locked, aFormatter, aNestLevel + 1 ); + saveField( &locked, aFormatter ); nextFreeFieldId += 1; } - saveDcmInfoAsFields( aSymbol, aFormatter, nextFreeFieldId, aNestLevel ); + saveDcmInfoAsFields( aSymbol, aFormatter, nextFreeFieldId ); // Save the draw items grouped by units. std::vector<LIB_SYMBOL_UNIT> units = aSymbol->GetUnitDrawItems(); @@ -242,7 +241,7 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::SaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMAT name = aFormatter.Quotes( unitName ); name.pop_back(); // Remove last char: the quote ending the string. - aFormatter.Print( aNestLevel + 1, "(symbol %s_%d_%d\"\n", + aFormatter.Print( "(symbol %s_%d_%d\"", name.c_str(), unit.m_unit, unit.m_bodyStyle ); @@ -251,9 +250,9 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::SaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMAT if( aSymbol->HasUnitDisplayName( unit.m_unit ) ) { name = aSymbol->GetUnitDisplayName( unit.m_unit ); - aFormatter.Print( aNestLevel + 2, "(unit_name %s)\n", - aFormatter.Quotes( name ).c_str() ); + aFormatter.Print( "(unit_name %s)", aFormatter.Quotes( name ).c_str() ); } + // Enforce item ordering auto cmp = []( const SCH_ITEM* a, const SCH_ITEM* b ) @@ -267,16 +266,15 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::SaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMAT save_map.insert( item ); for( SCH_ITEM* item : save_map ) - saveSymbolDrawItem( item, aFormatter, aNestLevel + 2 ); + saveSymbolDrawItem( item, aFormatter ); - aFormatter.Print( aNestLevel + 1, ")\n" ); + aFormatter.Print( ")" ); } - aFormatter.Print( aNestLevel + 1, "(embedded_fonts %s)\n", - aSymbol->GetAreFontsEmbedded() ? "yes" : "no" ); + KICAD_FORMAT::FormatBool( &aFormatter, "embedded_fonts", aSymbol->GetAreFontsEmbedded() ); if( !aSymbol->EmbeddedFileMap().empty() ) - aSymbol->WriteEmbeddedFiles( aFormatter, aNestLevel + 1, aIncludeData ); + aSymbol->WriteEmbeddedFiles( aFormatter, aIncludeData ); } else { @@ -284,27 +282,27 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::SaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMAT wxASSERT( parent ); - aFormatter.Print( aNestLevel, "(symbol %s (extends %s)\n", + aFormatter.Print( "(symbol %s (extends %s)", name.c_str(), aFormatter.Quotew( parent->GetName() ).c_str() ); aSymbol->GetFields( fields ); for( SCH_FIELD* field : fields ) - saveField( field, aFormatter, aNestLevel + 1 ); + saveField( field, aFormatter ); nextFreeFieldId = aSymbol->GetNextAvailableFieldId(); - saveDcmInfoAsFields( aSymbol, aFormatter, nextFreeFieldId, aNestLevel ); + saveDcmInfoAsFields( aSymbol, aFormatter, nextFreeFieldId ); } - aFormatter.Print( aNestLevel, ")\n" ); + aFormatter.Print( ")" ); } void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveDcmInfoAsFields( LIB_SYMBOL* aSymbol, OUTPUTFORMATTER& aFormatter, - int& aNextFreeFieldId, int aNestLevel ) + int& aNextFreeFieldId ) { wxCHECK_RET( aSymbol, "Invalid LIB_SYMBOL pointer." ); @@ -313,7 +311,7 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveDcmInfoAsFields( LIB_SYMBOL* aSymbol, SCH_FIELD keywords( nullptr, aNextFreeFieldId, wxString( "ki_keywords" ) ); keywords.SetVisible( false ); keywords.SetText( aSymbol->GetKeyWords() ); - saveField( &keywords, aFormatter, aNestLevel + 1 ); + saveField( &keywords, aFormatter ); aNextFreeFieldId += 1; } @@ -337,14 +335,13 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveDcmInfoAsFields( LIB_SYMBOL* aSymbol, SCH_FIELD description( nullptr, aNextFreeFieldId, wxString( "ki_fp_filters" ) ); description.SetVisible( false ); description.SetText( tmp ); - saveField( &description, aFormatter, aNestLevel + 1 ); + saveField( &description, aFormatter ); aNextFreeFieldId += 1; } } -void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveSymbolDrawItem( SCH_ITEM* aItem, OUTPUTFORMATTER& aFormatter, - int aNestLevel ) +void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveSymbolDrawItem( SCH_ITEM* aItem, OUTPUTFORMATTER& aFormatter ) { wxCHECK_RET( aItem, "Invalid SCH_ITEM pointer." ); @@ -361,23 +358,23 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveSymbolDrawItem( SCH_ITEM* aItem, OUTPUTFO switch( shape->GetShape() ) { case SHAPE_T::ARC: - formatArc( &aFormatter, aNestLevel, shape, isPrivate, stroke, fillMode, fillColor, true ); + formatArc( &aFormatter, shape, isPrivate, stroke, fillMode, fillColor, true ); break; case SHAPE_T::CIRCLE: - formatCircle( &aFormatter, aNestLevel, shape, isPrivate, stroke, fillMode, fillColor, true ); + formatCircle( &aFormatter, shape, isPrivate, stroke, fillMode, fillColor, true ); break; case SHAPE_T::RECTANGLE: - formatRect( &aFormatter, aNestLevel, shape, isPrivate, stroke, fillMode, fillColor, true ); + formatRect( &aFormatter, shape, isPrivate, stroke, fillMode, fillColor, true ); break; case SHAPE_T::BEZIER: - formatBezier(&aFormatter, aNestLevel, shape, isPrivate, stroke, fillMode, fillColor, true ); + formatBezier(&aFormatter, shape, isPrivate, stroke, fillMode, fillColor, true ); break; case SHAPE_T::POLY: - formatPoly( &aFormatter, aNestLevel, shape, isPrivate, stroke, fillMode, fillColor, true ); + formatPoly( &aFormatter, shape, isPrivate, stroke, fillMode, fillColor, true ); break; default: @@ -388,15 +385,15 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveSymbolDrawItem( SCH_ITEM* aItem, OUTPUTFO } case SCH_PIN_T: - savePin( static_cast<SCH_PIN*>( aItem ), aFormatter, aNestLevel ); + savePin( static_cast<SCH_PIN*>( aItem ), aFormatter ); break; case SCH_TEXT_T: - saveText( static_cast<SCH_TEXT*>( aItem ), aFormatter, aNestLevel ); + saveText( static_cast<SCH_TEXT*>( aItem ), aFormatter ); break; case SCH_TEXTBOX_T: - saveTextBox( static_cast<SCH_TEXTBOX*>( aItem ), aFormatter, aNestLevel ); + saveTextBox( static_cast<SCH_TEXTBOX*>( aItem ), aFormatter ); break; default: @@ -405,8 +402,7 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveSymbolDrawItem( SCH_ITEM* aItem, OUTPUTFO } -void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveField( SCH_FIELD* aField, OUTPUTFORMATTER& aFormatter, - int aNestLevel ) +void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveField( SCH_FIELD* aField, OUTPUTFORMATTER& aFormatter ) { wxCHECK_RET( aField && aField->Type() == SCH_FIELD_T, "Invalid SCH_FIELD object." ); @@ -415,7 +411,7 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveField( SCH_FIELD* aField, OUTPUTFORMATTER if( aField->IsMandatory() ) fieldName = GetCanonicalFieldName( aField->GetId() ); - aFormatter.Print( aNestLevel, "(property %s %s (at %s %s %g)", + aFormatter.Print( "(property %s %s (at %s %s %g)", aFormatter.Quotew( fieldName ).c_str(), aFormatter.Quotew( aField->GetText() ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, @@ -425,25 +421,23 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveField( SCH_FIELD* aField, OUTPUTFORMATTER aField->GetTextAngle().AsDegrees() ); if( aField->IsNameShown() ) - aFormatter.Print( 0, " (show_name)" ); + aFormatter.Print( "(show_name)" ); if( !aField->CanAutoplace() ) - aFormatter.Print( 0, " (do_not_autoplace)" ); + aFormatter.Print( "(do_not_autoplace)" ); - aFormatter.Print( 0, "\n" ); - aField->Format( &aFormatter, aNestLevel, 0 ); - aFormatter.Print( aNestLevel, ")\n" ); + aField->Format( &aFormatter, 0 ); + aFormatter.Print( ")" ); } -void SCH_IO_KICAD_SEXPR_LIB_CACHE::savePin( SCH_PIN* aPin, OUTPUTFORMATTER& aFormatter, - int aNestLevel ) +void SCH_IO_KICAD_SEXPR_LIB_CACHE::savePin( SCH_PIN* aPin, OUTPUTFORMATTER& aFormatter ) { wxCHECK_RET( aPin && aPin->Type() == SCH_PIN_T, "Invalid SCH_PIN object." ); aPin->ClearFlags( IS_CHANGED ); - aFormatter.Print( aNestLevel, "(pin %s %s (at %s %s %s) (length %s)", + aFormatter.Print( "(pin %s %s (at %s %s %s) (length %s)", getPinElectricalTypeToken( aPin->GetType() ), getPinShapeToken( aPin->GetShape() ), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, @@ -455,19 +449,17 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::savePin( SCH_PIN* aPin, OUTPUTFORMATTER& aFor aPin->GetLength() ).c_str() ); if( !aPin->IsVisible() ) - aFormatter.Print( 0, " (hide yes)\n" ); - else - aFormatter.Print( 0, "\n" ); + KICAD_FORMAT::FormatBool( &aFormatter, "hide", true ); // This follows the EDA_TEXT effects formatting for future expansion. - aFormatter.Print( aNestLevel + 1, "(name %s (effects (font (size %s %s))))\n", + aFormatter.Print( "(name %s (effects (font (size %s %s))))", aFormatter.Quotew( aPin->GetName() ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aPin->GetNameTextSize() ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aPin->GetNameTextSize() ).c_str() ); - aFormatter.Print( aNestLevel + 1, "(number %s (effects (font (size %s %s))))\n", + aFormatter.Print( "(number %s (effects (font (size %s %s))))", aFormatter.Quotew( aPin->GetNumber() ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aPin->GetNumberTextSize() ).c_str(), @@ -477,23 +469,22 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::savePin( SCH_PIN* aPin, OUTPUTFORMATTER& aFor for( const std::pair<const wxString, SCH_PIN::ALT>& alt : aPin->GetAlternates() ) { - aFormatter.Print( aNestLevel + 1, "(alternate %s %s %s)\n", + aFormatter.Print( "(alternate %s %s %s)", aFormatter.Quotew( alt.second.m_Name ).c_str(), getPinElectricalTypeToken( alt.second.m_Type ), getPinShapeToken( alt.second.m_Shape ) ); } - aFormatter.Print( aNestLevel, ")\n" ); + aFormatter.Print( ")" ); } -void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveText( SCH_TEXT* aText, OUTPUTFORMATTER& aFormatter, - int aNestLevel ) +void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveText( SCH_TEXT* aText, OUTPUTFORMATTER& aFormatter ) { wxCHECK_RET( aText && aText->Type() == SCH_TEXT_T, "Invalid SCH_TEXT object." ); - aFormatter.Print( aNestLevel, "(text%s %s (at %s %s %g)\n", - aText->IsPrivate() ? " private" : "", + aFormatter.Print( "(text %s %s (at %s %s %g)", + aText->IsPrivate() ? "private" : "", aFormatter.Quotew( aText->GetText() ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aText->GetPosition().x ).c_str(), @@ -501,24 +492,23 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveText( SCH_TEXT* aText, OUTPUTFORMATTER& a -aText->GetPosition().y ).c_str(), (double) aText->GetTextAngle().AsTenthsOfADegree() ); - aText->EDA_TEXT::Format( &aFormatter, aNestLevel, 0 ); - aFormatter.Print( aNestLevel, ")\n" ); + aText->EDA_TEXT::Format( &aFormatter, 0 ); + aFormatter.Print( ")" ); } -void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveTextBox( SCH_TEXTBOX* aTextBox, OUTPUTFORMATTER& aFormatter, - int aNestLevel ) +void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveTextBox( SCH_TEXTBOX* aTextBox, OUTPUTFORMATTER& aFormatter ) { wxCHECK_RET( aTextBox && aTextBox->Type() == SCH_TEXTBOX_T, "Invalid SCH_TEXTBOX object." ); - aFormatter.Print( aNestLevel, "(text_box%s %s\n", - aTextBox->IsPrivate() ? " private" : "", + aFormatter.Print( "(text_box %s %s", + aTextBox->IsPrivate() ? "private" : "", aFormatter.Quotew( aTextBox->GetText() ).c_str() ); VECTOR2I pos = aTextBox->GetStart(); VECTOR2I size = aTextBox->GetEnd() - pos; - aFormatter.Print( aNestLevel + 1, "(at %s %s %s) (size %s %s) (margins %s %s %s %s)\n", + aFormatter.Print( "(at %s %s %s) (size %s %s) (margins %s %s %s %s)", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pos.x ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, -pos.y ).c_str(), EDA_UNIT_UTILS::FormatAngle( aTextBox->GetTextAngle() ).c_str(), @@ -529,14 +519,10 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::saveTextBox( SCH_TEXTBOX* aTextBox, OUTPUTFOR EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aTextBox->GetMarginRight() ).c_str(), EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aTextBox->GetMarginBottom() ).c_str() ); - aTextBox->GetStroke().Format( &aFormatter, schIUScale, aNestLevel + 1 ); - aFormatter.Print( 0, "\n" ); - - formatFill( &aFormatter, aNestLevel + 1, aTextBox->GetFillMode(), aTextBox->GetFillColor() ); - aFormatter.Print( 0, "\n" ); - - aTextBox->EDA_TEXT::Format( &aFormatter, aNestLevel, 0 ); - aFormatter.Print( aNestLevel, ")\n" ); + aTextBox->GetStroke().Format( &aFormatter, schIUScale ); + formatFill( &aFormatter, aTextBox->GetFillMode(), aTextBox->GetFillColor() ); + aTextBox->EDA_TEXT::Format( &aFormatter, 0 ); + aFormatter.Print( ")" ); } diff --git a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_lib_cache.h b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_lib_cache.h index 8f4ef30dec..e5121ba99a 100644 --- a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_lib_cache.h +++ b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_lib_cache.h @@ -51,7 +51,7 @@ public: void DeleteSymbol( const wxString& aName ) override; - static void SaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMATTER& aFormatter, int aNestLevel = 0, + static void SaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMATTER& aFormatter, const wxString& aLibName = wxEmptyString, bool aIncludeData = true ); void SetFileFormatVersionAtLoad( int aVersion ) { m_fileFormatVersionAtLoad = aVersion; } @@ -62,16 +62,14 @@ private: int m_fileFormatVersionAtLoad; - static void saveSymbolDrawItem( SCH_ITEM* aItem, OUTPUTFORMATTER& aFormatter, - int aNestLevel ); - static void saveField( SCH_FIELD* aField, OUTPUTFORMATTER& aFormatter, int aNestLevel ); - static void savePin( SCH_PIN* aPin, OUTPUTFORMATTER& aFormatter, int aNestLevel = 0 ); - static void saveText( SCH_TEXT* aText, OUTPUTFORMATTER& aFormatter, int aNestLevel = 0 ); - static void saveTextBox( SCH_TEXTBOX* aTextBox, OUTPUTFORMATTER& aFormatter, - int aNestLevel = 0 ); + static void saveSymbolDrawItem( SCH_ITEM* aItem, OUTPUTFORMATTER& aFormatter ); + static void saveField( SCH_FIELD* aField, OUTPUTFORMATTER& aFormatter ); + static void savePin( SCH_PIN* aPin, OUTPUTFORMATTER& aFormatter ); + static void saveText( SCH_TEXT* aText, OUTPUTFORMATTER& aFormatter ); + static void saveTextBox( SCH_TEXTBOX* aTextBox, OUTPUTFORMATTER& aFormatter ); static void saveDcmInfoAsFields( LIB_SYMBOL* aSymbol, OUTPUTFORMATTER& aFormatter, - int& aNextFreeFieldId, int aNestLevel ); + int& aNextFreeFieldId ); }; #endif // SCH_IO_KICAD_SEXPR_LIB_CACHE_H_ diff --git a/eeschema/symbol_editor/symbol_editor.cpp b/eeschema/symbol_editor/symbol_editor.cpp index f943d25bf7..9a42b3cc86 100644 --- a/eeschema/symbol_editor/symbol_editor.cpp +++ b/eeschema/symbol_editor/symbol_editor.cpp @@ -1215,7 +1215,7 @@ void SYMBOL_EDIT_FRAME::CopySymbolToClipboard() } std::string prettyData = formatter.GetString(); - KICAD_FORMAT::Prettify( prettyData ); + KICAD_FORMAT::Prettify( prettyData, true ); wxLogNull doNotLog; // disable logging of failed clipboard actions diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index 3f160e89e1..a4d44e659e 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -1343,7 +1343,7 @@ bool SCH_EDITOR_CONTROL::doCopy( bool aUseDuplicateClipboard ) plugin.Format( &selection, &selPath, schematic, &formatter, true ); std::string prettyData = formatter.GetString(); - KICAD_FORMAT::Prettify( prettyData ); + KICAD_FORMAT::Prettify( prettyData, true ); if( selection.IsHover() ) m_toolMgr->RunAction( EE_ACTIONS::clearSelection ); diff --git a/eeschema/tools/symbol_editor_edit_tool.cpp b/eeschema/tools/symbol_editor_edit_tool.cpp index 40926fd806..5fd5f9ac58 100644 --- a/eeschema/tools/symbol_editor_edit_tool.cpp +++ b/eeschema/tools/symbol_editor_edit_tool.cpp @@ -921,7 +921,7 @@ int SYMBOL_EDITOR_EDIT_TOOL::Copy( const TOOL_EVENT& aEvent ) item.ClearFlags( STRUCT_DELETED ); std::string prettyData = formatter.GetString(); - KICAD_FORMAT::Prettify( prettyData ); + KICAD_FORMAT::Prettify( prettyData, true ); if( SaveClipboard( prettyData ) ) return 0; diff --git a/include/eda_text.h b/include/eda_text.h index 0c59ea2072..ace35040bd 100644 --- a/include/eda_text.h +++ b/include/eda_text.h @@ -350,11 +350,10 @@ public: * Output the object to \a aFormatter in s-expression form. * * @param aFormatter The #OUTPUTFORMATTER object to write to. - * @param aNestLevel The indentation next level. * @param aControlBits The control bit definition for object specific formatting. * @throw IO_ERROR on write error. */ - virtual void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const; + virtual void Format( OUTPUTFORMATTER* aFormatter, int aControlBits ) const; virtual EDA_ANGLE GetDrawRotation() const { return GetTextAngle(); } virtual VECTOR2I GetDrawPos() const { return GetTextPos(); } diff --git a/include/embedded_files.h b/include/embedded_files.h index 90d4fabc43..760cb629bd 100644 --- a/include/embedded_files.h +++ b/include/embedded_files.h @@ -121,11 +121,11 @@ public: /** * Output formatter for the embedded files. * @param aOut is the output formatter. - * @param aNestLevel is the current indentation level. - * @param aWriteData is true if the actual data should be written. This is false when writing an element - * that is already embedded in a file that itself has embedded files (boards, schematics, etc.) + * @param aWriteData is true if the actual data should be written. This is false when writing + * an element that is already embedded in a file that itself has embedded + * files (boards, schematics, etc.) */ - void WriteEmbeddedFiles( OUTPUTFORMATTER& aOut, int aNestLevel, bool aWriteData ) const; + void WriteEmbeddedFiles( OUTPUTFORMATTER& aOut, bool aWriteData ) const; /** * Returns the link for an embedded file. diff --git a/include/io/kicad/kicad_io_utils.h b/include/io/kicad/kicad_io_utils.h index 8d0d13eb4a..c7c657624d 100644 --- a/include/io/kicad/kicad_io_utils.h +++ b/include/io/kicad/kicad_io_utils.h @@ -31,18 +31,14 @@ namespace KICAD_FORMAT { * Writes a boolean to the formatter, in the style (aKey [yes|no]) * * @param aOut is the output formatter to write to - * @param aNestLevel is passed to the output formatter to control indentation * @param aKey is the name of the boolean flag * @param aValue is the value to write - * @param aSuffix is the character to format after the end of the boolean (after the close paren) */ -KICOMMON_API void FormatBool( OUTPUTFORMATTER* aOut, int aNestLevel, const wxString& aKey, - bool aValue, char aSuffix = 0 ); +KICOMMON_API void FormatBool( OUTPUTFORMATTER* aOut, const wxString& aKey, bool aValue ); -KICOMMON_API void FormatUuid( OUTPUTFORMATTER* aOut, int aNestLevel, const KIID& aUuid, - char aSuffix = 0 ); +KICOMMON_API void FormatUuid( OUTPUTFORMATTER* aOut, const KIID& aUuid ); -KICOMMON_API void Prettify( std::string& aSource, char aQuoteChar = '"' ); +KICOMMON_API void Prettify( std::string& aSource, bool aCompactSave ); } // namespace KICAD_FORMAT diff --git a/include/page_info.h b/include/page_info.h index 3bad59c24f..1dcb48e497 100644 --- a/include/page_info.h +++ b/include/page_info.h @@ -199,11 +199,9 @@ public: * Output the page class to \a aFormatter in s-expression form. * * @param aFormatter The #OUTPUTFORMATTER object to write to. - * @param aNestLevel The indentation next level. - * @param aControlBits The control bit definition for object specific formatting. * @throw IO_ERROR on write error. */ - void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const; + void Format( OUTPUTFORMATTER* aFormatter ) const; protected: // only the class implementation(s) may use this constructor diff --git a/include/richio.h b/include/richio.h index 5f33ed5b27..fc20b818a7 100644 --- a/include/richio.h +++ b/include/richio.h @@ -355,8 +355,10 @@ protected: // so increase the STRING-INDEX and FIRST-TO_CHECK by one. // See http://docs.freebsd.org/info/gcc/gcc.info.Function_Attributes.html // Then to get format checking during the compile, compile with -Wall or -Wformat -#define PRINTF_FUNC __attribute__( ( format( printf, 3, 4 ) ) ) +#define PRINTF_FUNC_N __attribute__( ( format( printf, 3, 4 ) ) ) +#define PRINTF_FUNC __attribute__( ( format( printf, 2, 3 ) ) ) #else +#define PRINTF_FUNC_N // nothing #define PRINTF_FUNC // nothing #endif @@ -376,7 +378,18 @@ public: * @return int - the number of characters output. * @throw IO_ERROR, if there is a problem outputting, such as a full disk. */ - int PRINTF_FUNC Print( int nestLevel, const char* fmt, ... ); + int PRINTF_FUNC_N Print( int nestLevel, const char* fmt, ... ); + + /** + * Format and write text to the output stream. + * + * @param fmt A printf() style format string. + * @param ... a variable list of parameters that will get blended into + * the output under control of the format string. + * @return int - the number of characters output. + * @throw IO_ERROR, if there is a problem outputting, such as a full disk. + */ + int PRINTF_FUNC Print( const char* fmt, ... ); /** * Perform quote character need determination. diff --git a/include/stroke_params.h b/include/stroke_params.h index 6591cb7aff..48f4564ea2 100644 --- a/include/stroke_params.h +++ b/include/stroke_params.h @@ -102,7 +102,7 @@ public: || m_color != aOther.m_color; } - void Format( OUTPUTFORMATTER* out, const EDA_IU_SCALE& aIuScale, int nestLevel ) const; + void Format( OUTPUTFORMATTER* out, const EDA_IU_SCALE& aIuScale ) const; void GetMsgPanelInfo( UNITS_PROVIDER* aUnitsProvider, std::vector<MSG_PANEL_ITEM>& aList, bool aIncludeStyle = true, bool aIncludeWidth = true ); diff --git a/include/template_fieldnames.h b/include/template_fieldnames.h index b14570537d..0eaa71ef86 100644 --- a/include/template_fieldnames.h +++ b/include/template_fieldnames.h @@ -84,7 +84,7 @@ struct TEMPLATE_FIELDNAME /** * Serialize this object out as text into the given #OUTPUTFORMATTER. */ - void Format( OUTPUTFORMATTER* out, int nestLevel ) const ; + void Format( OUTPUTFORMATTER* out ) const ; /** * Fill this object from information in the input stream \a aSpec, which is a @@ -139,7 +139,7 @@ public: /** * Serialize this object out as text into the given #OUTPUTFORMATTER. */ - void Format( OUTPUTFORMATTER* out, int nestLevel, bool aGlobal ) const ; + void Format( OUTPUTFORMATTER* out, bool aGlobal ) const ; /** * Insert or append a wanted symbol field name into the field names template. diff --git a/include/title_block.h b/include/title_block.h index afca0d4ea1..7e457811cf 100644 --- a/include/title_block.h +++ b/include/title_block.h @@ -122,11 +122,9 @@ public: * Output the object to \a aFormatter in s-expression form. * * @param aFormatter The #OUTPUTFORMATTER object to write to. - * @param aNestLevel The indentation next level. - * @param aControlBits The control bit definition for object specific formatting. * @throw IO_ERROR on write error. */ - virtual void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const; + virtual void Format( OUTPUTFORMATTER* aFormatter ) const; private: wxArrayString m_tbTexts; diff --git a/pcbnew/board_stackup_manager/board_stackup.cpp b/pcbnew/board_stackup_manager/board_stackup.cpp index 3aaa8aa8d0..e820ed25f3 100644 --- a/pcbnew/board_stackup_manager/board_stackup.cpp +++ b/pcbnew/board_stackup_manager/board_stackup.cpp @@ -26,6 +26,7 @@ #include <board_design_settings.h> #include <board.h> #include <i18n_utility.h> // For _HKI definition +#include <io/kicad/kicad_io_utils.h> #include "stackup_predefined_prms.h" #include <richio.h> #include <google/protobuf/any.pb.h> @@ -721,16 +722,14 @@ void BOARD_STACKUP::BuildDefaultStackupList( const BOARD_DESIGN_SETTINGS* aSetti } -void BOARD_STACKUP::FormatBoardStackup( OUTPUTFORMATTER* aFormatter, - const BOARD* aBoard, int aNestLevel ) const +void BOARD_STACKUP::FormatBoardStackup( OUTPUTFORMATTER* aFormatter, const BOARD* aBoard ) const { // Board stackup is the ordered list from top to bottom of // physical layers and substrate used to build the board. if( m_list.empty() ) return; - aFormatter->Print( aNestLevel, "(stackup\n" ); - int nest_level = aNestLevel+1; + aFormatter->Print( "(stackup" ); // Note: // Unspecified parameters are not stored in file. @@ -743,73 +742,71 @@ void BOARD_STACKUP::FormatBoardStackup( OUTPUTFORMATTER* aFormatter, else layer_name = LSET::Name( item->GetBrdLayerId() ); - aFormatter->Print( nest_level, "(layer %s (type %s)", + aFormatter->Print( "(layer %s (type %s)", aFormatter->Quotew( layer_name ).c_str(), aFormatter->Quotew( item->GetTypeName() ).c_str() ); - // Output other parameters ( in sub layer list there is at least one item) + // Output other parameters (in sub layer list there is at least one item) for( int idx = 0; idx < item->GetSublayersCount(); idx++ ) { if( idx ) // not for the main (first) layer. - { - aFormatter->Print( 0, "\n" ); - aFormatter->Print( nest_level+1, "addsublayer" ); - } + aFormatter->Print( " addsublayer" ); if( item->IsColorEditable() && IsPrmSpecified( item->GetColor( idx ) ) ) { - aFormatter->Print( 0, " (color %s)", + aFormatter->Print( "(color %s)", aFormatter->Quotew( item->GetColor( idx ) ).c_str() ); } if( item->IsThicknessEditable() ) { + aFormatter->Print( "(thickness %s", + EDA_UNIT_UTILS::FormatInternalUnits( pcbIUScale, item->GetThickness( idx ) ).c_str() ); + if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC && item->IsThicknessLocked( idx ) ) - aFormatter->Print( 0, " (thickness %s locked)", - EDA_UNIT_UTILS::FormatInternalUnits( pcbIUScale, item->GetThickness( idx ) ).c_str() ); - else - aFormatter->Print( 0, " (thickness %s)", - EDA_UNIT_UTILS::FormatInternalUnits( pcbIUScale, item->GetThickness( idx ) ).c_str() ); + aFormatter->Print( " locked" ); + + aFormatter->Print( ")" ); } if( item->HasMaterialValue( idx ) ) - aFormatter->Print( 0, " (material %s)", + { + aFormatter->Print( "(material %s)", aFormatter->Quotew( item->GetMaterial( idx ) ).c_str() ); + } if( item->HasEpsilonRValue() && item->HasMaterialValue( idx ) ) - aFormatter->Print( 0, " (epsilon_r %g)", item->GetEpsilonR( idx ) ); + aFormatter->Print( "(epsilon_r %g)", item->GetEpsilonR( idx ) ); if( item->HasLossTangentValue() && item->HasMaterialValue( idx ) ) - aFormatter->Print( 0, " (loss_tangent %s)", + { + aFormatter->Print( "(loss_tangent %s)", FormatDouble2Str( item->GetLossTangent( idx ) ).c_str() ); + } } - aFormatter->Print( 0, ")\n" ); + aFormatter->Print( ")" ); } // Other infos about board, related to layers and other fabrication specifications if( IsPrmSpecified( m_FinishType ) ) - { - aFormatter->Print( nest_level, "(copper_finish %s)\n", - aFormatter->Quotew( m_FinishType ).c_str() ); - } + aFormatter->Print( "(copper_finish %s)", aFormatter->Quotew( m_FinishType ).c_str() ); - aFormatter->Print( nest_level, "(dielectric_constraints %s)\n", - m_HasDielectricConstrains ? "yes" : "no" ); + KICAD_FORMAT::FormatBool( aFormatter, "dielectric_constraints", m_HasDielectricConstrains ); if( m_EdgeConnectorConstraints > 0 ) { - aFormatter->Print( nest_level, "(edge_connector %s)\n", + aFormatter->Print( "(edge_connector %s)", m_EdgeConnectorConstraints > 1 ? "bevelled": "yes" ); } if( m_CastellatedPads ) - aFormatter->Print( nest_level, "(castellated_pads yes)\n" ); + KICAD_FORMAT::FormatBool( aFormatter, "castellated_pads", true ); if( m_EdgePlating ) - aFormatter->Print( nest_level, "(edge_plating yes)\n" ); + KICAD_FORMAT::FormatBool( aFormatter, "edge_plating", true ); - aFormatter->Print( aNestLevel, ")\n" ); + aFormatter->Print( ")" ); } diff --git a/pcbnew/board_stackup_manager/board_stackup.h b/pcbnew/board_stackup_manager/board_stackup.h index dbaef41e8b..10564c7471 100644 --- a/pcbnew/board_stackup_manager/board_stackup.h +++ b/pcbnew/board_stackup_manager/board_stackup.h @@ -283,10 +283,8 @@ public: * Write the stackup info on board file * @param aFormatter is the OUTPUTFORMATTER used to create the file * @param aBoard is the board - * @param aNestLevel is the index to nest level to indent the lines in file */ - void FormatBoardStackup( OUTPUTFORMATTER* aFormatter, - const BOARD* aBoard, int aNestLevel ) const; + void FormatBoardStackup( OUTPUTFORMATTER* aFormatter, const BOARD* aBoard ) const; /** * Calculate the distance (height) between the two given copper layers. diff --git a/pcbnew/board_stackup_manager/panel_board_stackup.cpp b/pcbnew/board_stackup_manager/panel_board_stackup.cpp index fbc0e84217..253d9fecda 100644 --- a/pcbnew/board_stackup_manager/panel_board_stackup.cpp +++ b/pcbnew/board_stackup_manager/panel_board_stackup.cpp @@ -1296,7 +1296,7 @@ bool PANEL_SETUP_BOARD_STACKUP::TransferDataFromWindow() // FormatBoardStackup() (using FormatInternalUnits()) expects a "C" locale // to execute some tests. So switch to the suitable locale LOCALE_IO dummy; - brd_stackup.FormatBoardStackup( &old_stackup, m_board, 0 ); + brd_stackup.FormatBoardStackup( &old_stackup, m_board ); // copy enabled items to the new board stackup brd_stackup.RemoveAll(); @@ -1308,7 +1308,7 @@ bool PANEL_SETUP_BOARD_STACKUP::TransferDataFromWindow() } STRING_FORMATTER new_stackup; - brd_stackup.FormatBoardStackup( &new_stackup, m_board, 0 ); + brd_stackup.FormatBoardStackup( &new_stackup, m_board ); bool modified = old_stackup.GetString() != new_stackup.GetString(); int thickness = brd_stackup.BuildBoardThicknessFromStackup(); diff --git a/pcbnew/kicad_clipboard.cpp b/pcbnew/kicad_clipboard.cpp index 35cb8d3393..cabca4a079 100644 --- a/pcbnew/kicad_clipboard.cpp +++ b/pcbnew/kicad_clipboard.cpp @@ -263,7 +263,7 @@ void CLIPBOARD_IO::SaveSelection( const PCB_SELECTION& aSelected, bool isFootpri for( PCB_TABLE* table : promotedTables ) deleteUnselectedCells( table ); - Format( &partialFootprint, 0 ); + Format( &partialFootprint ); partialFootprint.SetParent( nullptr ); } @@ -273,16 +273,13 @@ void CLIPBOARD_IO::SaveSelection( const PCB_SELECTION& aSelected, bool isFootpri // This means we also need layers and nets LOCALE_IO io; - m_formatter.Print( 0, "(kicad_pcb (version %d) (generator \"pcbnew\") (generator_version \"%s\")\n", - SEXPR_BOARD_FILE_VERSION, GetMajorMinorVersion().c_str().AsChar() ); - - m_formatter.Print( 0, "\n" ); + m_formatter.Print( "(kicad_pcb (version %d) (generator \"pcbnew\") (generator_version %s)", + SEXPR_BOARD_FILE_VERSION, + m_formatter.Quotew( GetMajorMinorVersion() ).c_str() ); formatBoardLayers( m_board ); formatNetInformation( m_board ); - m_formatter.Print( 0, "\n" ); - for( EDA_ITEM* item : aSelected ) { if( !item->IsBOARD_ITEM() ) @@ -378,7 +375,7 @@ void CLIPBOARD_IO::SaveSelection( const PCB_SELECTION& aSelected, bool isFootpri deleteUnselectedCells( table ); } - Format( copy, 1 ); + Format( copy ); if( copy->Type() == PCB_GROUP_T || copy->Type() == PCB_GENERATOR_T ) { @@ -386,7 +383,7 @@ void CLIPBOARD_IO::SaveSelection( const PCB_SELECTION& aSelected, bool isFootpri [&]( BOARD_ITEM* descendant ) { descendant->SetLocked( false ); - Format( descendant, 1 ); + Format( descendant ); } ); } @@ -395,11 +392,11 @@ void CLIPBOARD_IO::SaveSelection( const PCB_SELECTION& aSelected, bool isFootpri } } - m_formatter.Print( 0, "\n)" ); + m_formatter.Print( ")" ); } std::string prettyData = m_formatter.GetString(); - KICAD_FORMAT::Prettify( prettyData ); + KICAD_FORMAT::Prettify( prettyData, true ); // These are placed at the end to minimize the open time of the clipboard wxLogNull doNotLog; // disable logging of failed clipboard actions @@ -478,13 +475,13 @@ void CLIPBOARD_IO::SaveBoard( const wxString& aFileName, BOARD* aBoard, m_out = &formatter; - m_out->Print( 0, "(kicad_pcb (version %d) (generator \"pcbnew\") (generator_version \"%s\")\n", + m_out->Print( "(kicad_pcb (version %d) (generator \"pcbnew\") (generator_version %s)", SEXPR_BOARD_FILE_VERSION, - GetMajorMinorVersion().c_str().AsChar() ); + m_out->Quotew( GetMajorMinorVersion() ).c_str() ); - Format( aBoard, 1 ); + Format( aBoard ); - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); wxLogNull doNotLog; // disable logging of failed clipboard actions diff --git a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp index 2b1290294f..5c92132e5d 100644 --- a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp +++ b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp @@ -31,7 +31,6 @@ #include <wx/msgdlg.h> #include <wx/mstream.h> -#include <advanced_config.h> #include <board.h> #include <board_design_settings.h> #include <callback_gal.h> @@ -308,7 +307,7 @@ bool PCB_IO_KICAD_SEXPR::CanReadBoard( const wxString& aFileName ) const void PCB_IO_KICAD_SEXPR::SaveBoard( const wxString& aFileName, BOARD* aBoard, - const std::map<std::string, UTF8>* aProperties ) + const std::map<std::string, UTF8>* aProperties ) { LOCALE_IO toggle; // toggles on, then off, the C locale. @@ -344,12 +343,13 @@ void PCB_IO_KICAD_SEXPR::SaveBoard( const wxString& aFileName, BOARD* aBoard, m_out = &formatter; // no ownership - m_out->Print( 0, "(kicad_pcb (version %d) (generator \"pcbnew\") (generator_version \"%s\")\n", - SEXPR_BOARD_FILE_VERSION, GetMajorMinorVersion().c_str().AsChar() ); + m_out->Print( "(kicad_pcb (version %d) (generator \"pcbnew\") (generator_version %s)", + SEXPR_BOARD_FILE_VERSION, + m_out->Quotew( GetMajorMinorVersion() ).c_str() ); - Format( aBoard, 1 ); + Format( aBoard ); - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); m_out->Finish(); m_out = nullptr; @@ -377,14 +377,14 @@ BOARD_ITEM* PCB_IO_KICAD_SEXPR::Parse( const wxString& aClipboardSourceInput ) } -void PCB_IO_KICAD_SEXPR::Format( const BOARD_ITEM* aItem, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::Format( const BOARD_ITEM* aItem ) const { LOCALE_IO toggle; // public API function, perform anything convenient for caller switch( aItem->Type() ) { case PCB_T: - format( static_cast<const BOARD*>( aItem ), aNestLevel ); + format( static_cast<const BOARD*>( aItem ) ); break; case PCB_DIM_ALIGNED_T: @@ -392,27 +392,27 @@ void PCB_IO_KICAD_SEXPR::Format( const BOARD_ITEM* aItem, int aNestLevel ) const case PCB_DIM_RADIAL_T: case PCB_DIM_ORTHOGONAL_T: case PCB_DIM_LEADER_T: - format( static_cast<const PCB_DIMENSION_BASE*>( aItem ), aNestLevel ); + format( static_cast<const PCB_DIMENSION_BASE*>( aItem ) ); break; case PCB_SHAPE_T: - format( static_cast<const PCB_SHAPE*>( aItem ), aNestLevel ); + format( static_cast<const PCB_SHAPE*>( aItem ) ); break; case PCB_REFERENCE_IMAGE_T: - format( static_cast<const PCB_REFERENCE_IMAGE*>( aItem ), aNestLevel ); + format( static_cast<const PCB_REFERENCE_IMAGE*>( aItem ) ); break; case PCB_TARGET_T: - format( static_cast<const PCB_TARGET*>( aItem ), aNestLevel ); + format( static_cast<const PCB_TARGET*>( aItem ) ); break; case PCB_FOOTPRINT_T: - format( static_cast<const FOOTPRINT*>( aItem ), aNestLevel ); + format( static_cast<const FOOTPRINT*>( aItem ) ); break; case PCB_PAD_T: - format( static_cast<const PAD*>( aItem ), aNestLevel ); + format( static_cast<const PAD*>( aItem ) ); break; case PCB_FIELD_T: @@ -420,33 +420,33 @@ void PCB_IO_KICAD_SEXPR::Format( const BOARD_ITEM* aItem, int aNestLevel ) const break; case PCB_TEXT_T: - format( static_cast<const PCB_TEXT*>( aItem ), aNestLevel ); + format( static_cast<const PCB_TEXT*>( aItem ) ); break; case PCB_TEXTBOX_T: - format( static_cast<const PCB_TEXTBOX*>( aItem ), aNestLevel ); + format( static_cast<const PCB_TEXTBOX*>( aItem ) ); break; case PCB_TABLE_T: - format( static_cast<const PCB_TABLE*>( aItem ), aNestLevel ); + format( static_cast<const PCB_TABLE*>( aItem ) ); break; case PCB_GROUP_T: - format( static_cast<const PCB_GROUP*>( aItem ), aNestLevel ); + format( static_cast<const PCB_GROUP*>( aItem ) ); break; case PCB_GENERATOR_T: - format( static_cast<const PCB_GENERATOR*>( aItem ), aNestLevel ); + format( static_cast<const PCB_GENERATOR*>( aItem ) ); break; case PCB_TRACE_T: case PCB_ARC_T: case PCB_VIA_T: - format( static_cast<const PCB_TRACK*>( aItem ), aNestLevel ); + format( static_cast<const PCB_TRACK*>( aItem ) ); break; case PCB_ZONE_T: - format( static_cast<const ZONE*>( aItem ), aNestLevel ); + format( static_cast<const ZONE*>( aItem ) ); break; default: @@ -482,20 +482,16 @@ std::string formatInternalUnits( const VECTOR2I& aCoord, const FOOTPRINT* aParen void PCB_IO_KICAD_SEXPR::formatLayer( PCB_LAYER_ID aLayer, bool aIsKnockout ) const { - m_out->Print( 0, " (layer %s%s)", + m_out->Print( "(layer %s %s)", m_out->Quotew( LSET::Name( aLayer ) ).c_str(), - aIsKnockout ? " knockout" : "" ); + aIsKnockout ? "knockout" : "" ); } -void PCB_IO_KICAD_SEXPR::formatPolyPts( const SHAPE_LINE_CHAIN& outline, int aNestLevel, - bool aCompact, const FOOTPRINT* aParentFP ) const +void PCB_IO_KICAD_SEXPR::formatPolyPts( const SHAPE_LINE_CHAIN& outline, + const FOOTPRINT* aParentFP ) const { - m_out->Print( aNestLevel + 1, "(pts\n" ); - - bool needNewline = false; - int nestLevel = aNestLevel + 2; - int shapesAdded = 0; + m_out->Print( "(pts" ); for( int ii = 0; ii < outline.PointCount(); ++ii ) { @@ -503,18 +499,16 @@ void PCB_IO_KICAD_SEXPR::formatPolyPts( const SHAPE_LINE_CHAIN& outline, int aNe if( ind < 0 ) { - m_out->Print( nestLevel, "(xy %s)", + m_out->Print( "(xy %s)", formatInternalUnits( outline.CPoint( ii ), aParentFP ).c_str() ); - needNewline = true; } else { const SHAPE_ARC& arc = outline.Arc( ind ); - m_out->Print( nestLevel, "(arc (start %s) (mid %s) (end %s))", + m_out->Print( "(arc (start %s) (mid %s) (end %s))", formatInternalUnits( arc.GetP0(), aParentFP ).c_str(), formatInternalUnits( arc.GetArcMid(), aParentFP ).c_str(), formatInternalUnits( arc.GetP1(), aParentFP ).c_str() ); - needNewline = true; do { @@ -523,31 +517,19 @@ void PCB_IO_KICAD_SEXPR::formatPolyPts( const SHAPE_LINE_CHAIN& outline, int aNe --ii; } - - ++shapesAdded; - - if( !( shapesAdded % 4 ) || !aCompact ) - { - // newline every 4 shapes if compact save - m_out->Print( 0, "\n" ); - needNewline = false; - } } - if( needNewline ) - m_out->Print( 0, "\n" ); - - m_out->Print( aNestLevel + 1, ")\n" ); + m_out->Print( ")" ); } -void PCB_IO_KICAD_SEXPR::formatRenderCache( const EDA_TEXT* aText, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::formatRenderCache( const EDA_TEXT* aText ) const { wxString resolvedText( aText->GetShownText( true ) ); std::vector<std::unique_ptr<KIFONT::GLYPH>>* cache = aText->GetRenderCache( aText->GetFont(), resolvedText ); - m_out->Print( aNestLevel, "(render_cache %s %s\n", + m_out->Print( "(render_cache %s %s", m_out->Quotew( resolvedText ).c_str(), EDA_UNIT_UTILS::FormatAngle( aText->GetDrawRotation() ).c_str() ); @@ -557,76 +539,71 @@ void PCB_IO_KICAD_SEXPR::formatRenderCache( const EDA_TEXT* aText, int aNestLeve // Polygon callback [&]( const SHAPE_LINE_CHAIN& aPoly ) { - m_out->Print( aNestLevel + 1, "(polygon\n" ); - formatPolyPts( aPoly, aNestLevel + 1, true ); - m_out->Print( aNestLevel + 1, ")\n" ); + m_out->Print( "(polygon" ); + formatPolyPts( aPoly ); + m_out->Print( ")" ); } ); callback_gal.SetLineWidth( aText->GetTextThickness() ); callback_gal.DrawGlyphs( *cache ); - m_out->Print( aNestLevel, ")\n" ); + m_out->Print( ")" ); } -void PCB_IO_KICAD_SEXPR::formatSetup( const BOARD* aBoard, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::formatSetup( const BOARD* aBoard ) const { // Setup - m_out->Print( aNestLevel, "(setup\n" ); + m_out->Print( "(setup" ); // Save the board physical stackup structure const BOARD_STACKUP& stackup = aBoard->GetDesignSettings().GetStackupDescriptor(); if( aBoard->GetDesignSettings().m_HasStackup ) - stackup.FormatBoardStackup( m_out, aBoard, aNestLevel+1 ); + stackup.FormatBoardStackup( m_out, aBoard ); BOARD_DESIGN_SETTINGS& dsnSettings = aBoard->GetDesignSettings(); - m_out->Print( aNestLevel+1, "(pad_to_mask_clearance %s)\n", + m_out->Print( "(pad_to_mask_clearance %s)", formatInternalUnits( dsnSettings.m_SolderMaskExpansion ).c_str() ); if( dsnSettings.m_SolderMaskMinWidth ) { - m_out->Print( aNestLevel+1, "(solder_mask_min_width %s)\n", + m_out->Print( "(solder_mask_min_width %s)", formatInternalUnits( dsnSettings.m_SolderMaskMinWidth ).c_str() ); } if( dsnSettings.m_SolderPasteMargin != 0 ) { - m_out->Print( aNestLevel+1, "(pad_to_paste_clearance %s)\n", + m_out->Print( "(pad_to_paste_clearance %s)", formatInternalUnits( dsnSettings.m_SolderPasteMargin ).c_str() ); } if( dsnSettings.m_SolderPasteMarginRatio != 0 ) { - m_out->Print( aNestLevel+1, "(pad_to_paste_clearance_ratio %s)\n", + m_out->Print( "(pad_to_paste_clearance_ratio %s)", FormatDouble2Str( dsnSettings.m_SolderPasteMarginRatio ).c_str() ); } - KICAD_FORMAT::FormatBool( m_out, aNestLevel + 1, "allow_soldermask_bridges_in_footprints", - dsnSettings.m_AllowSoldermaskBridgesInFPs, '\n' ); - - m_out->Print( aNestLevel + 1, "(tenting" ); + KICAD_FORMAT::FormatBool( m_out, "allow_soldermask_bridges_in_footprints", + dsnSettings.m_AllowSoldermaskBridgesInFPs ); if( dsnSettings.m_TentViasFront || dsnSettings.m_TentViasBack ) { - if( dsnSettings.m_TentViasFront ) - m_out->Print( 0, " front" ); - if( dsnSettings.m_TentViasBack ) - m_out->Print( 0, " back" ); - - m_out->Print( 0, ")\n" ); + m_out->Print( "(tenting %s %s)", + dsnSettings.m_TentViasFront ? "front" : "", + dsnSettings.m_TentViasBack ? "back" : "" ); } else { - m_out->Print( 0, " none)\n" ); + m_out->Print( "(tenting none)" ); } VECTOR2I origin = dsnSettings.GetAuxOrigin(); if( origin != VECTOR2I( 0, 0 ) ) { - m_out->Print( aNestLevel+1, "(aux_axis_origin %s %s)\n", + m_out->Print( "(aux_axis_origin %s %s)", formatInternalUnits( origin.x ).c_str(), formatInternalUnits( origin.y ).c_str() ); } @@ -635,55 +612,51 @@ void PCB_IO_KICAD_SEXPR::formatSetup( const BOARD* aBoard, int aNestLevel ) cons if( origin != VECTOR2I( 0, 0 ) ) { - m_out->Print( aNestLevel+1, "(grid_origin %s %s)\n", + m_out->Print( "(grid_origin %s %s)", formatInternalUnits( origin.x ).c_str(), formatInternalUnits( origin.y ).c_str() ); } - aBoard->GetPlotOptions().Format( m_out, aNestLevel+1 ); + aBoard->GetPlotOptions().Format( m_out ); - m_out->Print( aNestLevel, ")\n\n" ); + m_out->Print( ")" ); } -void PCB_IO_KICAD_SEXPR::formatGeneral( const BOARD* aBoard, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::formatGeneral( const BOARD* aBoard ) const { const BOARD_DESIGN_SETTINGS& dsnSettings = aBoard->GetDesignSettings(); - m_out->Print( 0, "\n" ); - m_out->Print( aNestLevel, "(general\n" ); + m_out->Print( "(general" ); - m_out->Print( aNestLevel+1, "(thickness %s)\n", + m_out->Print( "(thickness %s)", formatInternalUnits( dsnSettings.GetBoardThickness() ).c_str() ); - KICAD_FORMAT::FormatBool( m_out, aNestLevel + 1, "legacy_teardrops", - aBoard->LegacyTeardrops(), '\n' ); + KICAD_FORMAT::FormatBool( m_out, "legacy_teardrops", aBoard->LegacyTeardrops() ); - m_out->Print( aNestLevel, ")\n\n" ); + m_out->Print( ")" ); - aBoard->GetPageSettings().Format( m_out, aNestLevel, m_ctl ); - aBoard->GetTitleBlock().Format( m_out, aNestLevel, m_ctl ); + aBoard->GetPageSettings().Format( m_out ); + aBoard->GetTitleBlock().Format( m_out ); } -void PCB_IO_KICAD_SEXPR::formatBoardLayers( const BOARD* aBoard, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::formatBoardLayers( const BOARD* aBoard ) const { - m_out->Print( aNestLevel, "(layers\n" ); + m_out->Print( "(layers" ); // Save only the used copper layers from front to back. for( PCB_LAYER_ID layer : aBoard->GetEnabledLayers().CuStack() ) { - - m_out->Print( aNestLevel+1, "(%d %s %s", + m_out->Print( "(%d %s %s %s)", layer, m_out->Quotew( LSET::Name( layer ) ).c_str(), - LAYER::ShowType( aBoard->GetLayerType( layer ) ) ); + LAYER::ShowType( aBoard->GetLayerType( layer ) ), + LSET::Name( layer ) == m_board->GetLayerName( layer ) + ? "" + : m_out->Quotew( m_board->GetLayerName( layer ) ).c_str() ); - if( LSET::Name( layer ) != m_board->GetLayerName( layer ) ) - m_out->Print( 0, " %s", m_out->Quotew( m_board->GetLayerName( layer ) ).c_str() ); - - m_out->Print( 0, ")\n" ); } // Save used non-copper layers in the order they are defined. @@ -691,70 +664,61 @@ void PCB_IO_KICAD_SEXPR::formatBoardLayers( const BOARD* aBoard, int aNestLevel for( PCB_LAYER_ID layer : seq ) { - m_out->Print( aNestLevel+1, "(%d %s", + m_out->Print( "(%d %s %s %s)", layer, - m_out->Quotew( LSET::Name( layer ) ).c_str() ); - - if( layer >= User_1 && layer <= User_9 ) - m_out->Print( 0, " %s", LAYER::ShowType( aBoard->GetLayerType( layer ) ) ); - else - m_out->Print( 0, " user" ); - - if( m_board->GetLayerName( layer ) != LSET::Name( layer ) ) - m_out->Print( 0, " %s", m_out->Quotew( m_board->GetLayerName( layer ) ).c_str() ); - - m_out->Print( 0, ")\n" ); + m_out->Quotew( LSET::Name( layer ) ).c_str(), + layer >= User_1 && layer <= User_9 + ? LAYER::ShowType( aBoard->GetLayerType( layer ) ) + : "user", + m_board->GetLayerName( layer ) == LSET::Name( layer ) + ? "" + : m_out->Quotew( m_board->GetLayerName( layer ) ).c_str() ); } - m_out->Print( aNestLevel, ")\n\n" ); + m_out->Print( ")" ); } -void PCB_IO_KICAD_SEXPR::formatNetInformation( const BOARD* aBoard, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::formatNetInformation( const BOARD* aBoard ) const { for( NETINFO_ITEM* net : *m_mapping ) { if( net == nullptr ) // Skip not actually existing nets (orphan nets) continue; - m_out->Print( aNestLevel, "(net %d %s)\n", - m_mapping->Translate( net->GetNetCode() ), - m_out->Quotew( net->GetNetname() ).c_str() ); + m_out->Print( "(net %d %s)", + m_mapping->Translate( net->GetNetCode() ), + m_out->Quotew( net->GetNetname() ).c_str() ); } - - m_out->Print( 0, "\n" ); } -void PCB_IO_KICAD_SEXPR::formatProperties( const BOARD* aBoard, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::formatProperties( const BOARD* aBoard ) const { for( const std::pair<const wxString, wxString>& prop : aBoard->GetProperties() ) { - m_out->Print( aNestLevel, "(property %s %s)\n", + m_out->Print( "(property %s %s)", m_out->Quotew( prop.first ).c_str(), m_out->Quotew( prop.second ).c_str() ); } - - if( !aBoard->GetProperties().empty() ) - m_out->Print( 0, "\n" ); } -void PCB_IO_KICAD_SEXPR::formatHeader( const BOARD* aBoard, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::formatHeader( const BOARD* aBoard ) const { - formatGeneral( aBoard, aNestLevel ); + formatGeneral( aBoard ); // Layers list. - formatBoardLayers( aBoard, aNestLevel ); + formatBoardLayers( aBoard ); // Setup - formatSetup( aBoard, aNestLevel ); + formatSetup( aBoard ); // Properties - formatProperties( aBoard, aNestLevel ); + formatProperties( aBoard ); // Save net codes and names - formatNetInformation( aBoard, aNestLevel ); + formatNetInformation( aBoard ); } @@ -774,12 +738,10 @@ bool isDefaultTeardropParameters( const TEARDROP_PARAMETERS& tdParams ) } -void PCB_IO_KICAD_SEXPR::formatTeardropParameters( const TEARDROP_PARAMETERS& tdParams, - int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::formatTeardropParameters( const TEARDROP_PARAMETERS& tdParams ) const { - m_out->Print( aNestLevel, "(teardrops (best_length_ratio %s) (max_length %s) " - "(best_width_ratio %s) (max_width %s) (curve_points %d) " - "(filter_ratio %s)", + m_out->Print( "(teardrops (best_length_ratio %s) (max_length %s) (best_width_ratio %s) " + "(max_width %s) (curve_points %d) (filter_ratio %s)", FormatDouble2Str( tdParams.m_BestLengthRatio ).c_str(), formatInternalUnits( tdParams.m_TdMaxLen ).c_str(), FormatDouble2Str( tdParams.m_BestWidthRatio ).c_str(), @@ -787,14 +749,14 @@ void PCB_IO_KICAD_SEXPR::formatTeardropParameters( const TEARDROP_PARAMETERS& td tdParams.m_CurveSegCount, FormatDouble2Str( tdParams.m_WidthtoSizeFilterRatio ).c_str() ); - KICAD_FORMAT::FormatBool( m_out, 0, "enabled", tdParams.m_Enabled ); - KICAD_FORMAT::FormatBool( m_out, 0, "allow_two_segments", tdParams.m_AllowUseTwoTracks ); - KICAD_FORMAT::FormatBool( m_out, 0, "prefer_zone_connections", !tdParams.m_TdOnPadsInZones ); - m_out->Print( aNestLevel, ")" ); + KICAD_FORMAT::FormatBool( m_out, "enabled", tdParams.m_Enabled ); + KICAD_FORMAT::FormatBool( m_out, "allow_two_segments", tdParams.m_AllowUseTwoTracks ); + KICAD_FORMAT::FormatBool( m_out, "prefer_zone_connections", !tdParams.m_TdOnPadsInZones ); + m_out->Print( ")" ); } -void PCB_IO_KICAD_SEXPR::format( const BOARD* aBoard, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::format( const BOARD* aBoard ) const { std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_footprints( aBoard->Footprints().begin(), aBoard->Footprints().end() ); @@ -808,42 +770,33 @@ void PCB_IO_KICAD_SEXPR::format( const BOARD* aBoard, int aNestLevel ) const aBoard->Groups().end() ); std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_generators( aBoard->Generators().begin(), aBoard->Generators().end() ); - formatHeader( aBoard, aNestLevel ); + formatHeader( aBoard ); // Save the footprints. for( BOARD_ITEM* footprint : sorted_footprints ) - { - Format( footprint, aNestLevel ); - m_out->Print( 0, "\n" ); - } + Format( footprint ); // Save the graphical items on the board (not owned by a footprint) for( BOARD_ITEM* item : sorted_drawings ) - Format( item, aNestLevel ); - - if( sorted_drawings.size() ) - m_out->Print( 0, "\n" ); + Format( item ); // Do not save PCB_MARKERs, they can be regenerated easily. // Save the tracks and vias. for( PCB_TRACK* track : sorted_tracks ) - Format( track, aNestLevel ); - - if( sorted_tracks.size() ) - m_out->Print( 0, "\n" ); + Format( track ); // Save the polygon (which are the newer technology) zones. for( auto zone : sorted_zones ) - Format( zone, aNestLevel ); + Format( zone ); // Save the groups for( BOARD_ITEM* group : sorted_groups ) - Format( group, aNestLevel ); + Format( group ); // Save the generators for( BOARD_ITEM* gen : sorted_generators ) - Format( gen, aNestLevel ); + Format( gen ); // Save any embedded files // Consolidate the embedded models in footprints into a single map @@ -861,18 +814,18 @@ void PCB_IO_KICAD_SEXPR::format( const BOARD* aBoard, int aNestLevel ) const files_to_write.AddFile( file.second ); } - m_out->Print( aNestLevel + 1, "(embedded_fonts %s)\n", + m_out->Print( "(embedded_fonts %s)", aBoard->GetEmbeddedFiles()->GetAreFontsEmbedded() ? "yes" : "no" ); if( !files_to_write.IsEmpty() ) - files_to_write.WriteEmbeddedFiles( *m_out, aNestLevel + 1, ( m_ctl & CTL_FOR_BOARD ) ); + files_to_write.WriteEmbeddedFiles( *m_out, ( m_ctl & CTL_FOR_BOARD ) ); // Remove the files so that they are not freed in the DTOR files_to_write.ClearEmbeddedFiles( false ); } -void PCB_IO_KICAD_SEXPR::format( const PCB_DIMENSION_BASE* aDimension, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::format( const PCB_DIMENSION_BASE* aDimension ) const { const PCB_DIM_ALIGNED* aligned = dynamic_cast<const PCB_DIM_ALIGNED*>( aDimension ); const PCB_DIM_ORTHOGONAL* ortho = dynamic_cast<const PCB_DIM_ORTHOGONAL*>( aDimension ); @@ -880,56 +833,50 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_DIMENSION_BASE* aDimension, int aNest const PCB_DIM_RADIAL* radial = dynamic_cast<const PCB_DIM_RADIAL*>( aDimension ); const PCB_DIM_LEADER* leader = dynamic_cast<const PCB_DIM_LEADER*>( aDimension ); - m_out->Print( aNestLevel, "(dimension" ); + m_out->Print( "(dimension" ); if( ortho ) // must be tested before aligned, because ortho is derived from aligned // and aligned is not null - m_out->Print( 0, " (type orthogonal)" ); + m_out->Print( "(type orthogonal)" ); else if( aligned ) - m_out->Print( 0, " (type aligned)" ); + m_out->Print( "(type aligned)" ); else if( leader ) - m_out->Print( 0, " (type leader)" ); + m_out->Print( "(type leader)" ); else if( center ) - m_out->Print( 0, " (type center)" ); + m_out->Print( "(type center)" ); else if( radial ) - m_out->Print( 0, " (type radial)" ); + m_out->Print( "(type radial)" ); else wxFAIL_MSG( wxT( "Cannot format unknown dimension type!" ) ); if( aDimension->IsLocked() ) - KICAD_FORMAT::FormatBool( m_out, 0, "locked", aDimension->IsLocked() ); + KICAD_FORMAT::FormatBool( m_out, "locked", aDimension->IsLocked() ); formatLayer( aDimension->GetLayer() ); - KICAD_FORMAT::FormatUuid( m_out, 0, aDimension->m_Uuid, '\n' ); + KICAD_FORMAT::FormatUuid( m_out, aDimension->m_Uuid ); - m_out->Print( aNestLevel+1, "(pts (xy %s %s) (xy %s %s))\n", + m_out->Print( "(pts (xy %s %s) (xy %s %s))", formatInternalUnits( aDimension->GetStart().x ).c_str(), formatInternalUnits( aDimension->GetStart().y ).c_str(), formatInternalUnits( aDimension->GetEnd().x ).c_str(), formatInternalUnits( aDimension->GetEnd().y ).c_str() ); if( aligned ) - { - m_out->Print( aNestLevel+1, "(height %s)\n", - formatInternalUnits( aligned->GetHeight() ).c_str() ); - } + m_out->Print( "(height %s)", formatInternalUnits( aligned->GetHeight() ).c_str() ); if( radial ) { - m_out->Print( aNestLevel+1, "(leader_length %s)\n", + m_out->Print( "(leader_length %s)", formatInternalUnits( radial->GetLeaderLength() ).c_str() ); } if( ortho ) - { - m_out->Print( aNestLevel+1, "(orientation %d)\n", - static_cast<int>( ortho->GetOrientation() ) ); - } + m_out->Print( "(orientation %d)", static_cast<int>( ortho->GetOrientation() ) ); if( !center ) { - m_out->Print( aNestLevel + 1, "(format (prefix %s) (suffix %s) (units %d) (units_format %d) (precision %d)", + m_out->Print( "(format (prefix %s) (suffix %s) (units %d) (units_format %d) (precision %d)", m_out->Quotew( aDimension->GetPrefix() ).c_str(), m_out->Quotew( aDimension->GetSuffix() ).c_str(), static_cast<int>( aDimension->GetUnitsMode() ), @@ -938,20 +885,17 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_DIMENSION_BASE* aDimension, int aNest if( aDimension->GetOverrideTextEnabled() ) { - m_out->Print( 0, " (override_value %s)", + m_out->Print( "(override_value %s)", m_out->Quotew( aDimension->GetOverrideText() ).c_str() ); } + if( aDimension->GetSuppressZeroes() ) + KICAD_FORMAT::FormatBool( m_out, "suppress_zeroes", true ); - if( bool suppressZeroes = aDimension->GetSuppressZeroes() ) - { - KICAD_FORMAT::FormatBool( m_out, 0, "suppress_zeroes", suppressZeroes ); - } - - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); } - m_out->Print( aNestLevel+1, "(style (thickness %s) (arrow_length %s) (text_position_mode %d)", + m_out->Print( "(style (thickness %s) (arrow_length %s) (text_position_mode %d)", formatInternalUnits( aDimension->GetLineThickness() ).c_str(), formatInternalUnits( aDimension->GetArrowLength() ).c_str(), static_cast<int>( aDimension->GetTextPositionMode() ) ); @@ -961,10 +905,10 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_DIMENSION_BASE* aDimension, int aNest switch( aDimension->GetArrowDirection() ) { case DIM_ARROW_DIRECTION::OUTWARD: - m_out->Print( 0, " (arrow_direction outward)" ); + m_out->Print( "(arrow_direction outward)" ); break; case DIM_ARROW_DIRECTION::INWARD: - m_out->Print( 0, " (arrow_direction inward)" ); + m_out->Print( "(arrow_direction inward)" ); break; // No default, handle all cases } @@ -972,31 +916,31 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_DIMENSION_BASE* aDimension, int aNest if( aligned ) { - m_out->Print( 0, " (extension_height %s)", + m_out->Print( "(extension_height %s)", formatInternalUnits( aligned->GetExtensionHeight() ).c_str() ); } if( leader ) - m_out->Print( 0, " (text_frame %d)", static_cast<int>( leader->GetTextBorder() ) ); + m_out->Print( "(text_frame %d)", static_cast<int>( leader->GetTextBorder() ) ); - m_out->Print( 0, " (extension_offset %s)", + m_out->Print( "(extension_offset %s)", formatInternalUnits( aDimension->GetExtensionOffset() ).c_str() ); if( aDimension->GetKeepTextAligned() ) - m_out->Print( 0, " keep_text_aligned" ); + m_out->Print( " keep_text_aligned" ); - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); // Write dimension text after all other options to be sure the // text options are known when reading the file if( !center ) - format( static_cast<const PCB_TEXT*>( aDimension ), aNestLevel + 1 ); + format( static_cast<const PCB_TEXT*>( aDimension ) ); - m_out->Print( aNestLevel, ")\n" ); + m_out->Print( ")" ); } -void PCB_IO_KICAD_SEXPR::format( const PCB_SHAPE* aShape, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::format( const PCB_SHAPE* aShape ) const { FOOTPRINT* parentFP = aShape->GetParentFootprint(); std::string prefix = parentFP ? "fp" : "gr"; @@ -1004,28 +948,28 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_SHAPE* aShape, int aNestLevel ) const switch( aShape->GetShape() ) { case SHAPE_T::SEGMENT: - m_out->Print( aNestLevel, "(%s_line (start %s) (end %s)\n", + m_out->Print( "(%s_line (start %s) (end %s)", prefix.c_str(), formatInternalUnits( aShape->GetStart(), parentFP ).c_str(), formatInternalUnits( aShape->GetEnd(), parentFP ).c_str() ); break; case SHAPE_T::RECTANGLE: - m_out->Print( aNestLevel, "(%s_rect (start %s) (end %s)\n", + m_out->Print( "(%s_rect (start %s) (end %s)", prefix.c_str(), formatInternalUnits( aShape->GetStart(), parentFP ).c_str(), formatInternalUnits( aShape->GetEnd(), parentFP ).c_str() ); break; case SHAPE_T::CIRCLE: - m_out->Print( aNestLevel, "(%s_circle (center %s) (end %s)\n", + m_out->Print( "(%s_circle (center %s) (end %s)", prefix.c_str(), formatInternalUnits( aShape->GetStart(), parentFP ).c_str(), formatInternalUnits( aShape->GetEnd(), parentFP ).c_str() ); break; case SHAPE_T::ARC: - m_out->Print( aNestLevel, "(%s_arc (start %s) (mid %s) (end %s)\n", + m_out->Print( "(%s_arc (start %s) (mid %s) (end %s)", prefix.c_str(), formatInternalUnits( aShape->GetStart(), parentFP ).c_str(), formatInternalUnits( aShape->GetArcMid(), parentFP ).c_str(), @@ -1038,8 +982,8 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_SHAPE* aShape, int aNestLevel ) const const SHAPE_POLY_SET& poly = aShape->GetPolyShape(); const SHAPE_LINE_CHAIN& outline = poly.Outline( 0 ); - m_out->Print( aNestLevel, "(%s_poly\n", prefix.c_str() ); - formatPolyPts( outline, aNestLevel, ADVANCED_CFG::GetCfg().m_CompactSave, parentFP ); + m_out->Print( "(%s_poly", prefix.c_str() ); + formatPolyPts( outline, parentFP ); } else { @@ -1050,7 +994,7 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_SHAPE* aShape, int aNestLevel ) const break; case SHAPE_T::BEZIER: - m_out->Print( aNestLevel, "(%s_curve (pts (xy %s) (xy %s) (xy %s) (xy %s))\n", + m_out->Print( "(%s_curve (pts (xy %s) (xy %s) (xy %s) (xy %s))", prefix.c_str(), formatInternalUnits( aShape->GetStart(), parentFP ).c_str(), formatInternalUnits( aShape->GetBezierC1(), parentFP ).c_str(), @@ -1063,18 +1007,18 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_SHAPE* aShape, int aNestLevel ) const return; }; - aShape->GetStroke().Format( m_out, pcbIUScale, aNestLevel + 1 ); + aShape->GetStroke().Format( m_out, pcbIUScale ); // The filled flag represents if a solid fill is present on circles, rectangles and polygons if( ( aShape->GetShape() == SHAPE_T::POLY ) || ( aShape->GetShape() == SHAPE_T::RECTANGLE ) || ( aShape->GetShape() == SHAPE_T::CIRCLE ) ) { - m_out->Print( 0, aShape->IsFilled() ? " (fill solid)" : " (fill none)" ); + m_out->Print( aShape->IsFilled() ? "(fill solid)" : "(fill none)" ); } if( aShape->IsLocked() ) - KICAD_FORMAT::FormatBool( m_out, 0, "locked", aShape->IsLocked() ); + KICAD_FORMAT::FormatBool( m_out, "locked", true ); if( aShape->GetLayerSet().count() > 1 ) formatLayers( aShape->GetLayerSet() ); @@ -1085,20 +1029,19 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_SHAPE* aShape, int aNestLevel ) const && aShape->GetLocalSolderMaskMargin().has_value() && IsExternalCopperLayer( aShape->GetLayer() ) ) { - m_out->Print( 0, " (solder_mask_margin %s)", + m_out->Print( "(solder_mask_margin %s)", formatInternalUnits( aShape->GetLocalSolderMaskMargin().value() ).c_str() ); } if( aShape->GetNetCode() > 0 ) - m_out->Print( 0, " (net %d)", m_mapping->Translate( aShape->GetNetCode() ) ); + m_out->Print( "(net %d)", m_mapping->Translate( aShape->GetNetCode() ) ); - KICAD_FORMAT::FormatUuid( m_out, 0, aShape->m_Uuid ); - - m_out->Print( 0, ")\n" ); + KICAD_FORMAT::FormatUuid( m_out, aShape->m_Uuid ); + m_out->Print( ")" ); } -void PCB_IO_KICAD_SEXPR::format( const PCB_REFERENCE_IMAGE* aBitmap, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::format( const PCB_REFERENCE_IMAGE* aBitmap ) const { wxCHECK_RET( aBitmap != nullptr && m_out != nullptr, "" ); @@ -1108,20 +1051,19 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_REFERENCE_IMAGE* aBitmap, int aNestLe wxCHECK_RET( image != nullptr, "wxImage* is NULL" ); - m_out->Print( aNestLevel, "(image (at %s %s)", + m_out->Print( "(image (at %s %s)", formatInternalUnits( aBitmap->GetPosition().x ).c_str(), formatInternalUnits( aBitmap->GetPosition().y ).c_str() ); formatLayer( aBitmap->GetLayer() ); if( refImage.GetImageScale() != 1.0 ) - m_out->Print( 0, "(scale %g)", refImage.GetImageScale() ); + m_out->Print( "(scale %g)", refImage.GetImageScale() ); - if( const bool locked = aBitmap->IsLocked() ) - KICAD_FORMAT::FormatBool( m_out, 0, "locked", locked ); + if( aBitmap->IsLocked() ) + KICAD_FORMAT::FormatBool( m_out, "locked", true ); - m_out->Print( 0, "\n" ); - m_out->Print( aNestLevel + 1, "(data" ); + m_out->Print( "(data" ); wxString out = wxBase64Encode( refImage.GetImage().GetImageDataBuffer() ); @@ -1133,37 +1075,34 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_REFERENCE_IMAGE* aBitmap, int aNestLe while( first < out.Length() ) { - m_out->Print( 0, "\n" ); - m_out->Print( aNestLevel + 2, "\"%s\"", TO_UTF8( out( first, MIME_BASE64_LENGTH ) ) ); + m_out->Print( "\n\"%s\"", TO_UTF8( out( first, MIME_BASE64_LENGTH ) ) ); first += MIME_BASE64_LENGTH; } - m_out->Print( 0, "\n" ); - m_out->Print( aNestLevel + 1, ")\n" ); // Closes data token. + m_out->Print( ")" ); // Closes data token. - KICAD_FORMAT::FormatUuid( m_out, aNestLevel + 1, aBitmap->m_Uuid ); - m_out->Print( 0, ")\n" ); // Closes image token. + KICAD_FORMAT::FormatUuid( m_out, aBitmap->m_Uuid ); + m_out->Print( ")" ); // Closes image token. } -void PCB_IO_KICAD_SEXPR::format( const PCB_TARGET* aTarget, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::format( const PCB_TARGET* aTarget ) const { - m_out->Print( aNestLevel, "(target %s (at %s) (size %s)", + m_out->Print( "(target %s (at %s) (size %s)", ( aTarget->GetShape() ) ? "x" : "plus", formatInternalUnits( aTarget->GetPosition() ).c_str(), formatInternalUnits( aTarget->GetSize() ).c_str() ); if( aTarget->GetWidth() != 0 ) - m_out->Print( 0, " (width %s)", formatInternalUnits( aTarget->GetWidth() ).c_str() ); + m_out->Print( "(width %s)", formatInternalUnits( aTarget->GetWidth() ).c_str() ); formatLayer( aTarget->GetLayer() ); - - KICAD_FORMAT::FormatUuid( m_out, 0, aTarget->m_Uuid ); - m_out->Print( 0, ")\n" ); + KICAD_FORMAT::FormatUuid( m_out, aTarget->m_Uuid ); + m_out->Print( ")" ); } -void PCB_IO_KICAD_SEXPR::format( const FOOTPRINT* aFootprint, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::format( const FOOTPRINT* aFootprint ) const { if( !( m_ctl & CTL_OMIT_INITIAL_COMMENTS ) ) { @@ -1172,200 +1111,180 @@ void PCB_IO_KICAD_SEXPR::format( const FOOTPRINT* aFootprint, int aNestLevel ) c if( initial_comments ) { for( unsigned i = 0; i < initial_comments->GetCount(); ++i ) - m_out->Print( aNestLevel, "%s\n", TO_UTF8( (*initial_comments)[i] ) ); - - m_out->Print( 0, "\n" ); // improve readability? + m_out->Print( "%s\n", TO_UTF8( (*initial_comments)[i] ) ); } } if( m_ctl & CTL_OMIT_LIBNAME ) { - m_out->Print( aNestLevel, "(footprint %s", + m_out->Print( "(footprint %s", m_out->Quotes( aFootprint->GetFPID().GetLibItemName() ).c_str() ); } else { - m_out->Print( aNestLevel, "(footprint %s", + m_out->Print( "(footprint %s", m_out->Quotes( aFootprint->GetFPID().Format() ).c_str() ); } if( !( m_ctl & CTL_OMIT_FOOTPRINT_VERSION ) ) - m_out->Print( 0, " (version %d) (generator \"pcbnew\") (generator_version \"%s\")\n ", - SEXPR_BOARD_FILE_VERSION, GetMajorMinorVersion().c_str().AsChar() ); + { + m_out->Print( "(version %d) (generator \"pcbnew\") (generator_version %s)", + SEXPR_BOARD_FILE_VERSION, + m_out->Quotew( GetMajorMinorVersion() ).c_str() ); + } - if( const bool locked = aFootprint->IsLocked() ) - KICAD_FORMAT::FormatBool( m_out, aNestLevel + 1, "locked", locked, '\n' ); + if( aFootprint->IsLocked() ) + KICAD_FORMAT::FormatBool( m_out, "locked", true ); - if( const bool placed = aFootprint->IsPlaced() ) - KICAD_FORMAT::FormatBool( m_out, aNestLevel + 1, "placed", placed, '\n' ); + if( aFootprint->IsPlaced() ) + KICAD_FORMAT::FormatBool( m_out, "placed", true ); - m_out->Print( aNestLevel + 1, "" ); formatLayer( aFootprint->GetLayer() ); - m_out->Print( 0, "\n" ); if( !( m_ctl & CTL_OMIT_UUIDS ) ) - KICAD_FORMAT::FormatUuid( m_out, aNestLevel+1, aFootprint->m_Uuid, '\n' ); + KICAD_FORMAT::FormatUuid( m_out, aFootprint->m_Uuid ); if( !( m_ctl & CTL_OMIT_AT ) ) { - m_out->Print( aNestLevel+1, "(at %s", formatInternalUnits( aFootprint->GetPosition() ).c_str() ); - - if( !aFootprint->GetOrientation().IsZero() ) - m_out->Print( 0, " %s", EDA_UNIT_UTILS::FormatAngle( aFootprint->GetOrientation() ).c_str() ); - - m_out->Print( 0, ")\n" ); + m_out->Print( "(at %s %s)", + formatInternalUnits( aFootprint->GetPosition() ).c_str(), + aFootprint->GetOrientation().IsZero() + ? "" + : EDA_UNIT_UTILS::FormatAngle( aFootprint->GetOrientation() ).c_str() ); } if( !aFootprint->GetLibDescription().IsEmpty() ) - { - m_out->Print( aNestLevel + 1, "(descr %s)\n", - m_out->Quotew( aFootprint->GetLibDescription() ).c_str() ); - } + m_out->Print( "(descr %s)", m_out->Quotew( aFootprint->GetLibDescription() ).c_str() ); if( !aFootprint->GetKeywords().IsEmpty() ) - { - m_out->Print( aNestLevel+1, "(tags %s)\n", - m_out->Quotew( aFootprint->GetKeywords() ).c_str() ); - } + m_out->Print( "(tags %s)", m_out->Quotew( aFootprint->GetKeywords() ).c_str() ); for( const PCB_FIELD* field : aFootprint->GetFields() ) { - m_out->Print( aNestLevel + 1, "(property %s %s", + m_out->Print( "(property %s %s", m_out->Quotew( field->GetCanonicalName() ).c_str(), m_out->Quotew( field->GetText() ).c_str() ); - format( field, aNestLevel + 1 ); + format( field ); - m_out->Print( aNestLevel + 1, ")\n" ); + m_out->Print( ")" ); } if( const COMPONENT_CLASS* compClass = aFootprint->GetComponentClass() ) { if( !compClass->IsEmpty() ) { - m_out->Print( aNestLevel + 1, "(component_classes\n" ); + m_out->Print( "(component_classes" ); for( const COMPONENT_CLASS* constituent : compClass->GetConstituentClasses() ) - { - m_out->Print( aNestLevel + 2, "(class %s)\n", - m_out->Quotew( constituent->GetFullName() ).c_str() ); - } + m_out->Print( "(class %s)", m_out->Quotew( constituent->GetFullName() ).c_str() ); - m_out->Print( aNestLevel + 1, ")\n" ); + m_out->Print( ")" ); } } if( !aFootprint->GetFilters().empty() ) { - m_out->Print( aNestLevel + 1, "(property ki_fp_filters %s)\n", + m_out->Print( "(property ki_fp_filters %s)", m_out->Quotew( aFootprint->GetFilters() ).c_str() ); } if( !( m_ctl & CTL_OMIT_PATH ) && !aFootprint->GetPath().empty() ) - { - m_out->Print( aNestLevel+1, "(path %s)\n", - m_out->Quotew( aFootprint->GetPath().AsString() ).c_str() ); - } + m_out->Print( "(path %s)", m_out->Quotew( aFootprint->GetPath().AsString() ).c_str() ); if( !aFootprint->GetSheetname().empty() ) - { - m_out->Print( aNestLevel + 1, "(sheetname %s)\n", - m_out->Quotew( aFootprint->GetSheetname() ).c_str() ); - } + m_out->Print( "(sheetname %s)", m_out->Quotew( aFootprint->GetSheetname() ).c_str() ); if( !aFootprint->GetSheetfile().empty() ) - { - m_out->Print( aNestLevel + 1, "(sheetfile %s)\n", - m_out->Quotew( aFootprint->GetSheetfile() ).c_str() ); - } + m_out->Print( "(sheetfile %s)", m_out->Quotew( aFootprint->GetSheetfile() ).c_str() ); if( aFootprint->GetLocalSolderMaskMargin().has_value() ) { - m_out->Print( aNestLevel+1, "(solder_mask_margin %s)\n", + m_out->Print( "(solder_mask_margin %s)", formatInternalUnits( aFootprint->GetLocalSolderMaskMargin().value() ).c_str() ); } if( aFootprint->GetLocalSolderPasteMargin().has_value() ) { - m_out->Print( aNestLevel+1, "(solder_paste_margin %s)\n", + m_out->Print( "(solder_paste_margin %s)", formatInternalUnits( aFootprint->GetLocalSolderPasteMargin().value() ).c_str() ); } if( aFootprint->GetLocalSolderPasteMarginRatio().has_value() ) { - m_out->Print( aNestLevel+1, "(solder_paste_margin_ratio %s)\n", + m_out->Print( "(solder_paste_margin_ratio %s)", FormatDouble2Str( aFootprint->GetLocalSolderPasteMarginRatio().value() ).c_str() ); } if( aFootprint->GetLocalClearance().has_value() ) { - m_out->Print( aNestLevel+1, "(clearance %s)\n", + m_out->Print( "(clearance %s)", formatInternalUnits( aFootprint->GetLocalClearance().value() ).c_str() ); } if( aFootprint->GetLocalZoneConnection() != ZONE_CONNECTION::INHERITED ) { - m_out->Print( aNestLevel+1, "(zone_connect %d)\n", - static_cast<int>( aFootprint->GetLocalZoneConnection() ) ); + m_out->Print( "(zone_connect %d)", + static_cast<int>( aFootprint->GetLocalZoneConnection() ) ); } // Attributes if( aFootprint->GetAttributes() ) { - m_out->Print( aNestLevel+1, "(attr" ); + m_out->Print( "(attr" ); if( aFootprint->GetAttributes() & FP_SMD ) - m_out->Print( 0, " smd" ); + m_out->Print( " smd" ); if( aFootprint->GetAttributes() & FP_THROUGH_HOLE ) - m_out->Print( 0, " through_hole" ); + m_out->Print( " through_hole" ); if( aFootprint->GetAttributes() & FP_BOARD_ONLY ) - m_out->Print( 0, " board_only" ); + m_out->Print( " board_only" ); if( aFootprint->GetAttributes() & FP_EXCLUDE_FROM_POS_FILES ) - m_out->Print( 0, " exclude_from_pos_files" ); + m_out->Print( " exclude_from_pos_files" ); if( aFootprint->GetAttributes() & FP_EXCLUDE_FROM_BOM ) - m_out->Print( 0, " exclude_from_bom" ); + m_out->Print( " exclude_from_bom" ); if( aFootprint->GetAttributes() & FP_ALLOW_MISSING_COURTYARD ) - m_out->Print( 0, " allow_missing_courtyard" ); + m_out->Print( " allow_missing_courtyard" ); if( aFootprint->GetAttributes() & FP_DNP ) - m_out->Print( 0, " dnp" ); + m_out->Print( " dnp" ); if( aFootprint->GetAttributes() & FP_ALLOW_SOLDERMASK_BRIDGES ) - m_out->Print( 0, " allow_soldermask_bridges" ); + m_out->Print( " allow_soldermask_bridges" ); - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); } if( aFootprint->GetPrivateLayers().any() ) { - m_out->Print( aNestLevel+1, "(private_layers" ); + m_out->Print( "(private_layers" ); for( PCB_LAYER_ID layer : aFootprint->GetPrivateLayers().Seq() ) { wxString canonicalName( LSET::Name( layer ) ); - m_out->Print( 0, " \"%s\"", canonicalName.ToStdString().c_str() ); + m_out->Print( " %s", m_out->Quotew( canonicalName ).c_str() ); } - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); } if( aFootprint->IsNetTie() ) { - m_out->Print( aNestLevel+1, "(net_tie_pad_groups" ); + m_out->Print( "(net_tie_pad_groups" ); for( const wxString& group : aFootprint->GetNetTiePadGroups() ) - m_out->Print( 0, " \"%s\"", EscapeString( group, CTX_QUOTED_STR ).ToStdString().c_str() ); + m_out->Print( " %s", m_out->Quotew( group ).c_str() ); - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); } - Format( (BOARD_ITEM*) &aFootprint->Reference(), aNestLevel + 1 ); - Format( (BOARD_ITEM*) &aFootprint->Value(), aNestLevel + 1 ); + Format( (BOARD_ITEM*) &aFootprint->Reference() ); + Format( (BOARD_ITEM*) &aFootprint->Value() ); std::set<PAD*, FOOTPRINT::cmp_pads> sorted_pads( aFootprint->Pads().begin(), aFootprint->Pads().end() ); @@ -1380,27 +1299,25 @@ void PCB_IO_KICAD_SEXPR::format( const FOOTPRINT* aFootprint, int aNestLevel ) c // Save drawing elements. for( BOARD_ITEM* gr : sorted_drawings ) - Format( gr, aNestLevel+1 ); + Format( gr ); // Save pads. for( PAD* pad : sorted_pads ) - Format( pad, aNestLevel+1 ); + Format( pad ); // Save zones. for( BOARD_ITEM* zone : sorted_zones ) - Format( zone, aNestLevel + 1 ); + Format( zone ); // Save groups. for( BOARD_ITEM* group : sorted_groups ) - Format( group, aNestLevel + 1 ); + Format( group ); - m_out->Print( aNestLevel + 1, "(embedded_fonts %s)\n", - aFootprint->GetEmbeddedFiles()->GetAreFontsEmbedded() ? "yes" : "no" ); + KICAD_FORMAT::FormatBool( m_out, "embedded_fonts", + aFootprint->GetEmbeddedFiles()->GetAreFontsEmbedded() ); if( !aFootprint->GetEmbeddedFiles()->IsEmpty() ) - { - aFootprint->WriteEmbeddedFiles( *m_out, aNestLevel + 1, !( m_ctl & CTL_FOR_BOARD ) ); - } + aFootprint->WriteEmbeddedFiles( *m_out, !( m_ctl & CTL_FOR_BOARD ) ); // Save 3D info. auto bs3D = aFootprint->Models().begin(); @@ -1410,49 +1327,41 @@ void PCB_IO_KICAD_SEXPR::format( const FOOTPRINT* aFootprint, int aNestLevel ) c { if( !bs3D->m_Filename.IsEmpty() ) { - m_out->Print( aNestLevel+1, "(model %s\n", - m_out->Quotew( bs3D->m_Filename ).c_str() ); + m_out->Print( "(model %s", m_out->Quotew( bs3D->m_Filename ).c_str() ); if( !bs3D->m_Show ) - KICAD_FORMAT::FormatBool( m_out, aNestLevel + 1, "hide", !bs3D->m_Show, '\n' ); + KICAD_FORMAT::FormatBool( m_out, "hide", !bs3D->m_Show ); if( bs3D->m_Opacity != 1.0 ) - m_out->Print( aNestLevel+2, "(opacity %0.4f)", bs3D->m_Opacity ); + m_out->Print( "(opacity %0.4f)", bs3D->m_Opacity ); - m_out->Print( aNestLevel+2, "(offset (xyz %s %s %s))\n", + m_out->Print( "(offset (xyz %s %s %s))", FormatDouble2Str( bs3D->m_Offset.x ).c_str(), FormatDouble2Str( bs3D->m_Offset.y ).c_str(), FormatDouble2Str( bs3D->m_Offset.z ).c_str() ); - m_out->Print( aNestLevel+2, "(scale (xyz %s %s %s))\n", + m_out->Print( "(scale (xyz %s %s %s))", FormatDouble2Str( bs3D->m_Scale.x ).c_str(), FormatDouble2Str( bs3D->m_Scale.y ).c_str(), FormatDouble2Str( bs3D->m_Scale.z ).c_str() ); - m_out->Print( aNestLevel+2, "(rotate (xyz %s %s %s))\n", + m_out->Print( "(rotate (xyz %s %s %s))", FormatDouble2Str( bs3D->m_Rotation.x ).c_str(), FormatDouble2Str( bs3D->m_Rotation.y ).c_str(), FormatDouble2Str( bs3D->m_Rotation.z ).c_str() ); - m_out->Print( aNestLevel+1, ")\n" ); + m_out->Print( ")" ); } ++bs3D; } - m_out->Print( aNestLevel, ")\n" ); + m_out->Print( ")" ); } -void PCB_IO_KICAD_SEXPR::formatLayers( LSET aLayerMask, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::formatLayers( LSET aLayerMask ) const { - std::string output; - - if( aNestLevel == 0 ) - output += ' '; - - output += "(layers"; - static const LSET cu_all( LSET::AllCuMask() ); static const LSET fr_bk( { B_Cu, F_Cu } ); static const LSET adhes( { B_Adhes, F_Adhes } ); @@ -1464,6 +1373,8 @@ void PCB_IO_KICAD_SEXPR::formatLayers( LSET aLayerMask, int aNestLevel ) const LSET cu_mask = cu_all; + std::string output; + // output copper layers first, then non copper if( ( aLayerMask & cu_mask ) == cu_mask ) @@ -1519,18 +1430,14 @@ void PCB_IO_KICAD_SEXPR::formatLayers( LSET aLayerMask, int aNestLevel ) const for( int layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer ) { if( aLayerMask[layer] ) - { - layerName = LSET::Name( PCB_LAYER_ID( layer ) ); - output += ' '; - output += m_out->Quotew( layerName ); - } + output += ' ' + m_out->Quotew( LSET::Name( PCB_LAYER_ID( layer ) ) ); } - m_out->Print( aNestLevel, "%s)", output.c_str() ); + m_out->Print( "(layers %s)", output.c_str() ); } -void PCB_IO_KICAD_SEXPR::format( const PAD* aPad, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::format( const PAD* aPad ) const { const BOARD* board = aPad->GetBoard(); @@ -1585,24 +1492,23 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad, int aNestLevel ) const aPad->GetProperty() ) ); } - m_out->Print( aNestLevel, "(pad %s %s %s", + m_out->Print( "(pad %s %s %s", m_out->Quotew( aPad->GetNumber() ).c_str(), type, shapeName( PADSTACK::ALL_LAYERS ) ); - m_out->Print( 0, " (at %s", formatInternalUnits( aPad->GetFPRelativePosition() ).c_str() ); + m_out->Print( "(at %s %s)", + formatInternalUnits( aPad->GetFPRelativePosition() ).c_str(), + aPad->GetOrientation().IsZero() + ? "" + : EDA_UNIT_UTILS::FormatAngle( aPad->GetOrientation() ).c_str() ); - if( !aPad->GetOrientation().IsZero() ) - m_out->Print( 0, " %s", EDA_UNIT_UTILS::FormatAngle( aPad->GetOrientation() ).c_str() ); - - m_out->Print( 0, ")" ); - - m_out->Print( 0, " (size %s)", formatInternalUnits( aPad->GetSize( PADSTACK::ALL_LAYERS ) ).c_str() ); + m_out->Print( "(size %s)", formatInternalUnits( aPad->GetSize( PADSTACK::ALL_LAYERS ) ).c_str() ); if( aPad->GetDelta( PADSTACK::ALL_LAYERS ).x != 0 || aPad->GetDelta( PADSTACK::ALL_LAYERS ).y != 0 ) { - m_out->Print( 0, " (rect_delta %s)", + m_out->Print( "(rect_delta %s)", formatInternalUnits( aPad->GetDelta( PADSTACK::ALL_LAYERS ) ).c_str() ); } @@ -1612,16 +1518,16 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad, int aNestLevel ) const if( (sz.x > 0) || (sz.y > 0) || (shapeoffset.x != 0) || (shapeoffset.y != 0) ) { - m_out->Print( 0, " (drill" ); + m_out->Print( "(drill" ); if( aPad->GetDrillShape() == PAD_DRILL_SHAPE::OBLONG ) - m_out->Print( 0, " oval" ); + m_out->Print( " oval" ); if( sz.x > 0 ) - m_out->Print( 0, " %s", formatInternalUnits( sz.x ).c_str() ); + m_out->Print( " %s", formatInternalUnits( sz.x ).c_str() ); if( sz.y > 0 && sz.x != sz.y ) - m_out->Print( 0, " %s", formatInternalUnits( sz.y ).c_str() ); + m_out->Print( " %s", formatInternalUnits( sz.y ).c_str() ); // NOTE: Shape offest is a property of the copper shape, not of the drill, but this was put // in the file format under the drill section. So, it is left here to minimize file format @@ -1629,38 +1535,38 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad, int aNestLevel ) const // separately. if( shapeoffset.x != 0 || shapeoffset.y != 0 ) { - m_out->Print( 0, " (offset %s)", + m_out->Print( "(offset %s)", formatInternalUnits( aPad->GetOffset( PADSTACK::ALL_LAYERS ) ).c_str() ); } - m_out->Print( 0, ")" ); + m_out->Print( ")" ); } // Add pad property, if exists. if( property ) - m_out->Print( 0, " (property %s)", property ); + m_out->Print( "(property %s)", property ); formatLayers( aPad->GetLayerSet() ); if( aPad->GetAttribute() == PAD_ATTRIB::PTH ) { - KICAD_FORMAT::FormatBool( m_out, 0, "remove_unused_layers", aPad->GetRemoveUnconnected() ); + KICAD_FORMAT::FormatBool( m_out, "remove_unused_layers", aPad->GetRemoveUnconnected() ); if( aPad->GetRemoveUnconnected() ) { - KICAD_FORMAT::FormatBool( m_out, 0, "keep_end_layers", aPad->GetKeepTopBottom() ); + KICAD_FORMAT::FormatBool( m_out, "keep_end_layers", aPad->GetKeepTopBottom() ); if( board ) // Will be nullptr in footprint library { - m_out->Print( 0, " (zone_layer_connections" ); + m_out->Print( "(zone_layer_connections" ); for( PCB_LAYER_ID layer : board->GetEnabledLayers().CuStack() ) { if( aPad->GetZoneLayerOverride( layer ) == ZLO_FORCE_FLASHED ) - m_out->Print( 0, " %s", m_out->Quotew( LSET::Name( layer ) ).c_str() ); + m_out->Print( " %s", m_out->Quotew( LSET::Name( layer ) ).c_str() ); } - m_out->Print( 0, ")" ); + m_out->Print( ")" ); } } } @@ -1672,33 +1578,31 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad, int aNestLevel ) const if( aPad->GetShape( aLayer ) == PAD_SHAPE::ROUNDRECT || aPad->GetShape( aLayer ) == PAD_SHAPE::CHAMFERED_RECT) { - m_out->Print( 0, " (roundrect_rratio %s)", + m_out->Print( "(roundrect_rratio %s)", FormatDouble2Str( aPad->GetRoundRectRadiusRatio( aLayer ) ).c_str() ); } // Output the chamfer corners for chamfered rect pads if( aPad->GetShape( aLayer ) == PAD_SHAPE::CHAMFERED_RECT) { - m_out->Print( 0, "\n" ); - - m_out->Print( aNestLevel+1, "(chamfer_ratio %s)", + m_out->Print( "(chamfer_ratio %s)", FormatDouble2Str( aPad->GetChamferRectRatio( aLayer ) ).c_str() ); - m_out->Print( 0, " (chamfer" ); + m_out->Print( "(chamfer" ); if( ( aPad->GetChamferPositions( aLayer ) & RECT_CHAMFER_TOP_LEFT ) ) - m_out->Print( 0, " top_left" ); + m_out->Print( " top_left" ); if( ( aPad->GetChamferPositions( aLayer ) & RECT_CHAMFER_TOP_RIGHT ) ) - m_out->Print( 0, " top_right" ); + m_out->Print( " top_right" ); if( ( aPad->GetChamferPositions( aLayer ) & RECT_CHAMFER_BOTTOM_LEFT ) ) - m_out->Print( 0, " bottom_left" ); + m_out->Print( " bottom_left" ); if( ( aPad->GetChamferPositions( aLayer ) & RECT_CHAMFER_BOTTOM_RIGHT ) ) - m_out->Print( 0, " bottom_right" ); + m_out->Print( " bottom_right" ); - m_out->Print( 0, ")" ); + m_out->Print( ")" ); } }; @@ -1707,13 +1611,11 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad, int aNestLevel ) const // will represent the front layer properties, and other layers will be formatted below formatCornerProperties( PADSTACK::ALL_LAYERS ); - std::string output; - // Unconnected pad is default net so don't save it. if( !( m_ctl & CTL_OMIT_PAD_NETS ) && aPad->GetNetCode() != NETINFO_LIST::UNCONNECTED ) { - StrPrintf( &output, " (net %d %s)", m_mapping->Translate( aPad->GetNetCode() ), - m_out->Quotew( aPad->GetNetname() ).c_str() ); + m_out->Print( "(net %d %s)", m_mapping->Translate( aPad->GetNetCode() ), + m_out->Quotew( aPad->GetNetname() ).c_str() ); } // Pin functions and types are closely related to nets, so if CTL_OMIT_NETS is set, omit @@ -1721,58 +1623,52 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad, int aNestLevel ) const if( !( m_ctl & CTL_OMIT_PAD_NETS ) ) { if( !aPad->GetPinFunction().IsEmpty() ) - { - StrPrintf( &output, " (pinfunction %s)", - m_out->Quotew( aPad->GetPinFunction() ).c_str() ); - } + m_out->Print( "(pinfunction %s)", m_out->Quotew( aPad->GetPinFunction() ).c_str() ); if( !aPad->GetPinType().IsEmpty() ) - { - StrPrintf( &output, " (pintype %s)", - m_out->Quotew( aPad->GetPinType() ).c_str() ); - } + m_out->Print( "(pintype %s)", m_out->Quotew( aPad->GetPinType() ).c_str() ); } if( aPad->GetPadToDieLength() != 0 ) { - StrPrintf( &output, " (die_length %s)", - formatInternalUnits( aPad->GetPadToDieLength() ).c_str() ); + m_out->Print( "(die_length %s)", + formatInternalUnits( aPad->GetPadToDieLength() ).c_str() ); } if( aPad->GetLocalSolderMaskMargin().has_value() ) { - StrPrintf( &output, " (solder_mask_margin %s)", - formatInternalUnits( aPad->GetLocalSolderMaskMargin().value() ).c_str() ); + m_out->Print( "(solder_mask_margin %s)", + formatInternalUnits( aPad->GetLocalSolderMaskMargin().value() ).c_str() ); } if( aPad->GetLocalSolderPasteMargin().has_value() ) { - StrPrintf( &output, " (solder_paste_margin %s)", - formatInternalUnits( aPad->GetLocalSolderPasteMargin().value() ).c_str() ); + m_out->Print( "(solder_paste_margin %s)", + formatInternalUnits( aPad->GetLocalSolderPasteMargin().value() ).c_str() ); } if( aPad->GetLocalSolderPasteMarginRatio().has_value() ) { - StrPrintf( &output, " (solder_paste_margin_ratio %s)", - FormatDouble2Str( aPad->GetLocalSolderPasteMarginRatio().value() ).c_str() ); + m_out->Print( "(solder_paste_margin_ratio %s)", + FormatDouble2Str( aPad->GetLocalSolderPasteMarginRatio().value() ).c_str() ); } if( aPad->GetLocalClearance().has_value() ) { - StrPrintf( &output, " (clearance %s)", - formatInternalUnits( aPad->GetLocalClearance().value() ).c_str() ); + m_out->Print( "(clearance %s)", + formatInternalUnits( aPad->GetLocalClearance().value() ).c_str() ); } if( aPad->GetLocalZoneConnection() != ZONE_CONNECTION::INHERITED ) { - StrPrintf( &output, " (zone_connect %d)", - static_cast<int>( aPad->GetLocalZoneConnection() ) ); + m_out->Print( "(zone_connect %d)", + static_cast<int>( aPad->GetLocalZoneConnection() ) ); } if( aPad->GetThermalSpokeWidth() != 0 ) { - StrPrintf( &output, " (thermal_bridge_width %s)", - formatInternalUnits( aPad->GetThermalSpokeWidth() ).c_str() ); + m_out->Print( "(thermal_bridge_width %s)", + formatInternalUnits( aPad->GetThermalSpokeWidth() ).c_str() ); } EDA_ANGLE defaultThermalSpokeAngle = ANGLE_90; @@ -1786,20 +1682,14 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad, int aNestLevel ) const if( aPad->GetThermalSpokeAngle() != defaultThermalSpokeAngle ) { - StrPrintf( &output, " (thermal_bridge_angle %s)", - EDA_UNIT_UTILS::FormatAngle( aPad->GetThermalSpokeAngle() ).c_str() ); + m_out->Print( "(thermal_bridge_angle %s)", + EDA_UNIT_UTILS::FormatAngle( aPad->GetThermalSpokeAngle() ).c_str() ); } if( aPad->GetThermalGap() != 0 ) { - StrPrintf( &output, " (thermal_gap %s)", - formatInternalUnits( aPad->GetThermalGap() ).c_str() ); - } - - if( output.size() ) - { - m_out->Print( 0, "\n" ); - m_out->Print( aNestLevel+1, "%s", output.c_str()+1 ); // +1 skips 1st space on 1st element + m_out->Print( "(thermal_gap %s)", + formatInternalUnits( aPad->GetThermalGap() ).c_str() ); } auto anchorShape = @@ -1816,27 +1706,23 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad, int aNestLevel ) const auto formatPrimitives = [&]( PCB_LAYER_ID aLayer ) { - m_out->Print( aNestLevel+1, "(primitives" ); - - int nested_level = aNestLevel+2; + m_out->Print( "(primitives" ); // Output all basic shapes for( const std::shared_ptr<PCB_SHAPE>& primitive : aPad->GetPrimitives( aLayer ) ) { - m_out->Print( 0, "\n"); - switch( primitive->GetShape() ) { case SHAPE_T::SEGMENT: if( primitive->IsProxyItem() ) { - m_out->Print( nested_level, "(gr_vector (start %s) (end %s)", + m_out->Print( "(gr_vector (start %s) (end %s)", formatInternalUnits( primitive->GetStart() ).c_str(), formatInternalUnits( primitive->GetEnd() ).c_str() ); } else { - m_out->Print( nested_level, "(gr_line (start %s) (end %s)", + m_out->Print( "(gr_line (start %s) (end %s)", formatInternalUnits( primitive->GetStart() ).c_str(), formatInternalUnits( primitive->GetEnd() ).c_str() ); } @@ -1845,33 +1731,33 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad, int aNestLevel ) const case SHAPE_T::RECTANGLE: if( primitive->IsProxyItem() ) { - m_out->Print( nested_level, "(gr_bbox (start %s) (end %s)", + m_out->Print( "(gr_bbox (start %s) (end %s)", formatInternalUnits( primitive->GetStart() ).c_str(), formatInternalUnits( primitive->GetEnd() ).c_str() ); } else { - m_out->Print( nested_level, "(gr_rect (start %s) (end %s)", + m_out->Print( "(gr_rect (start %s) (end %s)", formatInternalUnits( primitive->GetStart() ).c_str(), formatInternalUnits( primitive->GetEnd() ).c_str() ); } break; case SHAPE_T::ARC: - m_out->Print( nested_level, "(gr_arc (start %s) (mid %s) (end %s)", + m_out->Print( "(gr_arc (start %s) (mid %s) (end %s)", formatInternalUnits( primitive->GetStart() ).c_str(), formatInternalUnits( primitive->GetArcMid() ).c_str(), formatInternalUnits( primitive->GetEnd() ).c_str() ); break; case SHAPE_T::CIRCLE: - m_out->Print( nested_level, "(gr_circle (center %s) (end %s)", + m_out->Print( "(gr_circle (center %s) (end %s)", formatInternalUnits( primitive->GetStart() ).c_str(), formatInternalUnits( primitive->GetEnd() ).c_str() ); break; case SHAPE_T::BEZIER: - m_out->Print( nested_level, "(gr_curve (pts (xy %s) (xy %s) (xy %s) (xy %s))", + m_out->Print( "(gr_curve (pts (xy %s) (xy %s) (xy %s) (xy %s))", formatInternalUnits( primitive->GetStart() ).c_str(), formatInternalUnits( primitive->GetBezierC1() ).c_str(), formatInternalUnits( primitive->GetBezierC2() ).c_str(), @@ -1884,11 +1770,8 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad, int aNestLevel ) const const SHAPE_POLY_SET& poly = primitive->GetPolyShape(); const SHAPE_LINE_CHAIN& outline = poly.Outline( 0 ); - m_out->Print( nested_level, "(gr_poly\n" ); - formatPolyPts( outline, nested_level, ADVANCED_CFG::GetCfg().m_CompactSave ); - - // Align the next info at the right place. - m_out->Print( nested_level, " " ); + m_out->Print( "(gr_poly" ); + formatPolyPts( outline ); } break; @@ -1897,7 +1780,7 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad, int aNestLevel ) const } if( !primitive->IsProxyItem() ) - m_out->Print( 0, " (width %s)", formatInternalUnits( primitive->GetWidth() ).c_str() ); + m_out->Print( "(width %s)", formatInternalUnits( primitive->GetWidth() ).c_str() ); // The filled flag represents if a solid fill is present on circles, // rectangles and polygons @@ -1905,47 +1788,39 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad, int aNestLevel ) const || ( primitive->GetShape() == SHAPE_T::RECTANGLE ) || ( primitive->GetShape() == SHAPE_T::CIRCLE ) ) { - KICAD_FORMAT::FormatBool( m_out, 0, "fill", primitive->IsFilled() ); + KICAD_FORMAT::FormatBool( m_out, "fill", primitive->IsFilled() ); } - m_out->Print( 0, ")" ); + m_out->Print( ")" ); } - m_out->Print( 0, "\n" ); - m_out->Print( aNestLevel+1, ")" ); // end of (primitives + m_out->Print( ")" ); // end of (primitives }; if( aPad->GetShape( PADSTACK::ALL_LAYERS ) == PAD_SHAPE::CUSTOM ) { - m_out->Print( 0, "\n"); - m_out->Print( aNestLevel+1, "(options" ); + m_out->Print( "(options" ); if( aPad->GetCustomShapeInZoneOpt() == PADSTACK::CUSTOM_SHAPE_ZONE_MODE::CONVEXHULL ) - m_out->Print( 0, " (clearance convexhull)" ); - #if 1 // Set to 1 to output the default option + m_out->Print( "(clearance convexhull)" ); else - m_out->Print( 0, " (clearance outline)" ); - #endif + m_out->Print( "(clearance outline)" ); // Output the anchor pad shape (circle/rect) - m_out->Print( 0, " (anchor %s)", anchorShape( PADSTACK::ALL_LAYERS ) ); + m_out->Print( "(anchor %s)", anchorShape( PADSTACK::ALL_LAYERS ) ); - m_out->Print( 0, ")"); // end of (options ... + m_out->Print( ")"); // end of (options ... // Output graphic primitive of the pad shape - m_out->Print( 0, "\n"); formatPrimitives( PADSTACK::ALL_LAYERS ); } if( !isDefaultTeardropParameters( aPad->GetTeardropParams() ) ) - { - m_out->Print( 0, "\n" ); - formatTeardropParameters( aPad->GetTeardropParams(), aNestLevel+1 ); - } + formatTeardropParameters( aPad->GetTeardropParams() ); formatTenting( aPad->Padstack() ); - KICAD_FORMAT::FormatUuid( m_out, 0, aPad->m_Uuid ); + KICAD_FORMAT::FormatUuid( m_out, aPad->m_Uuid ); // TODO: Refactor so that we call formatPadLayer( ALL_LAYERS ) above instead of redundant code auto formatPadLayer = @@ -1953,31 +1828,29 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad, int aNestLevel ) const { const PADSTACK& padstack = aPad->Padstack(); - m_out->Print( 0, " (shape %s)", shapeName( aLayer ) ); - - m_out->Print( 0, " (size %s)", - formatInternalUnits( aPad->GetSize( aLayer ) ).c_str() ); + m_out->Print( "(shape %s)", shapeName( aLayer ) ); + m_out->Print( "(size %s)", formatInternalUnits( aPad->GetSize( aLayer ) ).c_str() ); const VECTOR2I& delta = aPad->GetDelta( aLayer ); if( delta.x != 0 || delta.y != 0 ) - m_out->Print( 0, " (rect_delta %s)", formatInternalUnits( delta ).c_str() ); + m_out->Print( "(rect_delta %s)", formatInternalUnits( delta ).c_str() ); shapeoffset = aPad->GetOffset( aLayer ); if( shapeoffset.x != 0 || shapeoffset.y != 0 ) - m_out->Print( 0, " (offset %s)", formatInternalUnits( shapeoffset ).c_str() ); + m_out->Print( "(offset %s)", formatInternalUnits( shapeoffset ).c_str() ); formatCornerProperties( aLayer ); if( aPad->GetShape( aLayer ) == PAD_SHAPE::CUSTOM ) { - m_out->Print( aNestLevel + 1, "(options" ); + m_out->Print( "(options" ); // Output the anchor pad shape (circle/rect) - m_out->Print( 0, " (anchor %s)", anchorShape( aLayer ) ); + m_out->Print( "(anchor %s)", anchorShape( aLayer ) ); - m_out->Print( 0, ")" ); // end of (options ... + m_out->Print( ")" ); // end of (options ... // Output graphic primitive of the pad shape formatPrimitives( aLayer ); @@ -1996,53 +1869,52 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad, int aNestLevel ) const if( layerSpokeAngle != defaultLayerAngle ) { - StrPrintf( &output, " (thermal_bridge_angle %s)", - EDA_UNIT_UTILS::FormatAngle( layerSpokeAngle ).c_str() ); + m_out->Print( "(thermal_bridge_angle %s)", + EDA_UNIT_UTILS::FormatAngle( layerSpokeAngle ).c_str() ); } if( padstack.ThermalGap( aLayer ).has_value() ) { - StrPrintf( &output, " (thermal_gap %s)", - formatInternalUnits( *padstack.ThermalGap( aLayer ) ).c_str() ); + m_out->Print( "(thermal_gap %s)", + formatInternalUnits( *padstack.ThermalGap( aLayer ) ).c_str() ); } if( padstack.ThermalSpokeWidth( aLayer ).has_value() ) { - StrPrintf( &output, " (thermal_bridge_width %s)", - formatInternalUnits( *padstack.ThermalSpokeWidth( aLayer ) ).c_str() ); + m_out->Print( "(thermal_bridge_width %s)", + formatInternalUnits( *padstack.ThermalSpokeWidth( aLayer ) ).c_str() ); } if( padstack.Clearance( aLayer ).has_value() ) { - StrPrintf( &output, " (clearance %s)", - formatInternalUnits( *padstack.Clearance( aLayer ) ).c_str() ); + m_out->Print( "(clearance %s)", + formatInternalUnits( *padstack.Clearance( aLayer ) ).c_str() ); } if( padstack.ZoneConnection( aLayer ).has_value() ) { - StrPrintf( &output, " (zone_connect %d)", - static_cast<int>( *padstack.ZoneConnection( aLayer ) ) ); + m_out->Print( "(zone_connect %d)", + static_cast<int>( *padstack.ZoneConnection( aLayer ) ) ); } }; if( aPad->Padstack().Mode() != PADSTACK::MODE::NORMAL ) { - m_out->Print( 0, "\n" ); - if( aPad->Padstack().Mode() == PADSTACK::MODE::FRONT_INNER_BACK ) { - m_out->Print( aNestLevel+1, "(padstack (mode front_inner_back)" ); + m_out->Print( "(padstack (mode front_inner_back)" ); - m_out->Print( 0, " (layer \"Inner\"" ); + m_out->Print( "(layer \"Inner\"" ); formatPadLayer( PADSTACK::INNER_LAYERS ); - m_out->Print( 0, ") (layer \"B.Cu\"" ); + m_out->Print( ")" ); + m_out->Print( "(layer \"B.Cu\"" ); formatPadLayer( B_Cu ); - m_out->Print( 0, ")" ); + m_out->Print( ")" ); } else { - m_out->Print( aNestLevel+1, "(padstack (mode custom)" ); + m_out->Print( "(padstack (mode custom)" ); int layerCount = board ? board->GetCopperLayerCount() : MAX_CU_LAYERS; @@ -2051,16 +1923,16 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad, int aNestLevel ) const if( layer == F_Cu ) continue; - m_out->Print( 0, " (layer %s", m_out->Quotew( LSET::Name( layer ) ).c_str() ); + m_out->Print( "(layer %s", m_out->Quotew( LSET::Name( layer ) ).c_str() ); formatPadLayer( layer ); - m_out->Print( 0, ")" ); + m_out->Print( ")" ); } } - m_out->Print( 0, ")" ); + m_out->Print( ")" ); } - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); } @@ -2073,24 +1945,19 @@ void PCB_IO_KICAD_SEXPR::formatTenting( const PADSTACK& aPadstack ) const { if( front.value_or( false ) || back.value_or( false ) ) { - m_out->Print( 0, " (tenting " ); - - if( front.value_or( false ) ) - m_out->Print( 0, " front" ); - if( back.value_or( false ) ) - m_out->Print( 0, " back" ); - - m_out->Print( 0, ")" ); + m_out->Print( "(tenting %s %s)", + front.value_or( false ) ? "front" : "", + back.value_or( false ) ? "back" : "" ); } else { - m_out->Print( 0, " (tenting none)" ); + m_out->Print( "(tenting none)" ); } } } -void PCB_IO_KICAD_SEXPR::format( const PCB_TEXT* aText, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::format( const PCB_TEXT* aText ) const { FOOTPRINT* parentFP = aText->GetParentFootprint(); std::string prefix; @@ -2105,7 +1972,7 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TEXT* aText, int aNestLevel ) const if( parentFP ) { prefix = "fp"; - type = " user"; + type = "user"; pos -= parentFP->GetPosition(); RotatePoint( pos, -parentFP->GetOrientation() ); @@ -2117,30 +1984,28 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TEXT* aText, int aNestLevel ) const if( !isField ) { - m_out->Print( aNestLevel, "(%s_text%s %s", prefix.c_str(), type.c_str(), + m_out->Print( "(%s_text %s %s", + prefix.c_str(), + type.c_str(), m_out->Quotew( aText->GetText() ).c_str() ); if( aText->IsLocked() ) - KICAD_FORMAT::FormatBool( m_out, 0, "locked", aText->IsLocked() ); + KICAD_FORMAT::FormatBool( m_out, "locked", true ); } - m_out->Print( 0, " (at %s", formatInternalUnits( pos ).c_str() ); - - // Due to Pcbnew history, fp_text angle is saved as an absolute on screen angle. - // To avoid issues in the future, always save the angle, even if it is 0 - m_out->Print( 0, " %s", EDA_UNIT_UTILS::FormatAngle( aText->GetTextAngle() ).c_str() ); - - m_out->Print( 0, ")" ); + m_out->Print( "(at %s %s)", + formatInternalUnits( pos ).c_str(), + EDA_UNIT_UTILS::FormatAngle( aText->GetTextAngle() ).c_str() ); if( parentFP && !aText->IsKeepUpright() ) - KICAD_FORMAT::FormatBool( m_out, 0, "unlocked", !aText->IsKeepUpright() ); + KICAD_FORMAT::FormatBool( m_out, "unlocked", true ); formatLayer( aText->GetLayer(), aText->IsKnockout() ); if( parentFP && !aText->IsVisible() ) - KICAD_FORMAT::FormatBool( m_out, 0, "hide", !aText->IsVisible() ); + KICAD_FORMAT::FormatBool( m_out, "hide", true ); - KICAD_FORMAT::FormatUuid( m_out, 0, aText->m_Uuid ); + KICAD_FORMAT::FormatUuid( m_out, aText->m_Uuid ); int ctl_flags = m_ctl | CTL_OMIT_HIDE; @@ -2148,33 +2013,32 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TEXT* aText, int aNestLevel ) const // so ensure they are never written in kicad_pcb file ctl_flags |= CTL_OMIT_COLOR | CTL_OMIT_HYPERLINK; - m_out->Print( 0, "\n" ); - aText->EDA_TEXT::Format( m_out, aNestLevel, ctl_flags ); + aText->EDA_TEXT::Format( m_out, ctl_flags ); if( aText->GetFont() && aText->GetFont()->IsOutline() ) - formatRenderCache( aText, aNestLevel + 1 ); + formatRenderCache( aText ); if( !isField ) - m_out->Print( aNestLevel, ")\n" ); + m_out->Print( ")" ); } -void PCB_IO_KICAD_SEXPR::format( const PCB_TEXTBOX* aTextBox, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::format( const PCB_TEXTBOX* aTextBox ) const { FOOTPRINT* parentFP = aTextBox->GetParentFootprint(); - m_out->Print( aNestLevel, "(%s %s\n", + m_out->Print( "(%s %s", aTextBox->Type() == PCB_TABLECELL_T ? "table_cell" : parentFP ? "fp_text_box" : "gr_text_box", m_out->Quotew( aTextBox->GetText() ).c_str() ); if( aTextBox->IsLocked() ) - KICAD_FORMAT::FormatBool( m_out, aNestLevel, "locked", aTextBox->IsLocked(), '\n' ); + KICAD_FORMAT::FormatBool( m_out, "locked", true ); if( aTextBox->GetShape() == SHAPE_T::RECTANGLE ) { - m_out->Print( aNestLevel + 1, "(start %s) (end %s)", + m_out->Print( "(start %s) (end %s)", formatInternalUnits( aTextBox->GetStart(), parentFP ).c_str(), formatInternalUnits( aTextBox->GetEnd(), parentFP ).c_str() ); } @@ -2183,21 +2047,21 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TEXTBOX* aTextBox, int aNestLevel ) c const SHAPE_POLY_SET& poly = aTextBox->GetPolyShape(); const SHAPE_LINE_CHAIN& outline = poly.Outline( 0 ); - formatPolyPts( outline, aNestLevel, true, parentFP ); + formatPolyPts( outline, parentFP ); } else { UNIMPLEMENTED_FOR( aTextBox->SHAPE_T_asString() ); } - m_out->Print( 0, " (margins %s %s %s %s)", + m_out->Print( "(margins %s %s %s %s)", formatInternalUnits( aTextBox->GetMarginLeft() ).c_str(), formatInternalUnits( aTextBox->GetMarginTop() ).c_str(), formatInternalUnits( aTextBox->GetMarginRight() ).c_str(), formatInternalUnits( aTextBox->GetMarginBottom() ).c_str() ); if( const PCB_TABLECELL* cell = dynamic_cast<const PCB_TABLECELL*>( aTextBox ) ) - m_out->Print( 0, " (span %d %d)", cell->GetColSpan(), cell->GetRowSpan() ); + m_out->Print( "(span %d %d)", cell->GetColSpan(), cell->GetRowSpan() ); EDA_ANGLE angle = aTextBox->GetTextAngle(); @@ -2208,39 +2072,36 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TEXTBOX* aTextBox, int aNestLevel ) c } if( !angle.IsZero() ) - m_out->Print( aNestLevel + 1, "(angle %s)", EDA_UNIT_UTILS::FormatAngle( angle ).c_str() ); + m_out->Print( "(angle %s)", EDA_UNIT_UTILS::FormatAngle( angle ).c_str() ); formatLayer( aTextBox->GetLayer() ); - KICAD_FORMAT::FormatUuid( m_out, 0, aTextBox->m_Uuid ); + KICAD_FORMAT::FormatUuid( m_out, aTextBox->m_Uuid ); // PCB_TEXTBOXes are never hidden, so always omit "hide" attribute - m_out->Print( 0, "\n" ); - aTextBox->EDA_TEXT::Format( m_out, aNestLevel, m_ctl | CTL_OMIT_HIDE ); + aTextBox->EDA_TEXT::Format( m_out, m_ctl | CTL_OMIT_HIDE ); if( aTextBox->Type() != PCB_TABLECELL_T ) { - KICAD_FORMAT::FormatBool( m_out, aNestLevel + 1, "border", aTextBox->IsBorderEnabled(), '\n' ); - - aTextBox->GetStroke().Format( m_out, pcbIUScale, aNestLevel + 1 ); + KICAD_FORMAT::FormatBool( m_out, "border", aTextBox->IsBorderEnabled() ); + aTextBox->GetStroke().Format( m_out, pcbIUScale ); } if( aTextBox->GetFont() && aTextBox->GetFont()->IsOutline() ) - formatRenderCache( aTextBox, aNestLevel + 1 ); + formatRenderCache( aTextBox ); - m_out->Print( aNestLevel, ")\n" ); + m_out->Print( ")" ); } -void PCB_IO_KICAD_SEXPR::format( const PCB_TABLE* aTable, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::format( const PCB_TABLE* aTable ) const { wxCHECK_RET( aTable != nullptr && m_out != nullptr, "" ); - m_out->Print( aNestLevel, "(table (column_count %d)", - aTable->GetColCount() ); + m_out->Print( "(table (column_count %d)", aTable->GetColCount() ); if( aTable->IsLocked() ) - KICAD_FORMAT::FormatBool( m_out, 0, "locked", aTable->IsLocked() ); + KICAD_FORMAT::FormatBool( m_out, "locked", true ); EDA_ANGLE angle = aTable->GetOrientation(); @@ -2251,75 +2112,64 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TABLE* aTable, int aNestLevel ) const } if( !angle.IsZero() ) - m_out->Print( 0, " (angle %s)", EDA_UNIT_UTILS::FormatAngle( angle ).c_str() ); + m_out->Print( "(angle %s)", EDA_UNIT_UTILS::FormatAngle( angle ).c_str() ); formatLayer( aTable->GetLayer() ); - m_out->Print( 0, "\n" ); - - m_out->Print( aNestLevel + 1, "(border (external %s) (header %s)", - aTable->StrokeExternal() ? "yes" : "no", - aTable->StrokeHeader() ? "yes" : "no" ); + m_out->Print( "(border" ); + KICAD_FORMAT::FormatBool( m_out, "external", aTable->StrokeExternal() ); + KICAD_FORMAT::FormatBool( m_out, "header", aTable->StrokeHeader() ); if( aTable->StrokeExternal() || aTable->StrokeHeader() ) - { - m_out->Print( 0, " " ); - aTable->GetBorderStroke().Format( m_out, pcbIUScale, 0 ); - } + aTable->GetBorderStroke().Format( m_out, pcbIUScale ); - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); // Close `border` token. - m_out->Print( aNestLevel + 1, "(separators (rows %s) (cols %s)", - aTable->StrokeRows() ? "yes" : "no", - aTable->StrokeColumns() ? "yes" : "no" ); + m_out->Print( "(separators" ); + KICAD_FORMAT::FormatBool( m_out, "rows", aTable->StrokeRows() ); + KICAD_FORMAT::FormatBool( m_out, "cols", aTable->StrokeColumns() ); if( aTable->StrokeRows() || aTable->StrokeColumns() ) - { - m_out->Print( 0, " " ); - aTable->GetSeparatorsStroke().Format( m_out, pcbIUScale, 0 ); - } + aTable->GetSeparatorsStroke().Format( m_out, pcbIUScale ); - m_out->Print( 0, ")\n" ); // Close `separators` token. + m_out->Print( ")" ); // Close `separators` token. - m_out->Print( aNestLevel + 1, "(column_widths" ); + m_out->Print( "(column_widths" ); for( int col = 0; col < aTable->GetColCount(); ++col ) - m_out->Print( 0, " %s", formatInternalUnits( aTable->GetColWidth( col ) ).c_str() ); + m_out->Print( " %s", formatInternalUnits( aTable->GetColWidth( col ) ).c_str() ); - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); - m_out->Print( aNestLevel + 1, "(row_heights" ); + m_out->Print( "(row_heights" ); for( int row = 0; row < aTable->GetRowCount(); ++row ) - m_out->Print( 0, " %s", formatInternalUnits( aTable->GetRowHeight( row ) ).c_str() ); + m_out->Print( " %s", formatInternalUnits( aTable->GetRowHeight( row ) ).c_str() ); - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); - m_out->Print( aNestLevel + 1, "(cells\n" ); + m_out->Print( "(cells" ); for( PCB_TABLECELL* cell : aTable->GetCells() ) - format( static_cast<PCB_TEXTBOX*>( cell ), aNestLevel + 2 ); + format( static_cast<PCB_TEXTBOX*>( cell ) ); - m_out->Print( aNestLevel + 1, ")\n" ); // Close `cells` token. - m_out->Print( aNestLevel, ")\n" ); // Close `table` token. + m_out->Print( ")" ); // Close `cells` token. + m_out->Print( ")" ); // Close `table` token. } -void PCB_IO_KICAD_SEXPR::format( const PCB_GROUP* aGroup, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::format( const PCB_GROUP* aGroup ) const { // Don't write empty groups if( aGroup->GetItems().empty() ) return; - m_out->Print( aNestLevel, "(group %s\n", m_out->Quotew( aGroup->GetName() ).c_str() ); + m_out->Print( "(group %s", m_out->Quotew( aGroup->GetName() ).c_str() ); - KICAD_FORMAT::FormatUuid( m_out, 0, aGroup->m_Uuid ); + KICAD_FORMAT::FormatUuid( m_out, aGroup->m_Uuid ); if( aGroup->IsLocked() ) - KICAD_FORMAT::FormatBool( m_out, 0, "locked", aGroup->IsLocked() ); - - m_out->Print( 0, "\n" ); - m_out->Print( aNestLevel + 1, "(members\n" ); + KICAD_FORMAT::FormatBool( m_out, "locked", true ); wxArrayString memberIds; @@ -2328,30 +2178,29 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_GROUP* aGroup, int aNestLevel ) const memberIds.Sort(); - for( const wxString& memberId : memberIds ) - m_out->Print( aNestLevel + 2, "\"%s\"\n", TO_UTF8( memberId ) ); + m_out->Print( "(members" ); - m_out->Print( aNestLevel + 1, ")\n" ); // Close `members` token. - m_out->Print( aNestLevel, ")\n" ); // Close `group` token. + for( const wxString& memberId : memberIds ) + m_out->Print( " %s", m_out->Quotew( memberId ).c_str() ); + + m_out->Print( ")" ); // Close `members` token. + m_out->Print( ")" ); // Close `group` token. } -void PCB_IO_KICAD_SEXPR::format( const PCB_GENERATOR* aGenerator, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::format( const PCB_GENERATOR* aGenerator ) const { - m_out->Print( aNestLevel, "(generated" ); + m_out->Print( "(generated" ); - KICAD_FORMAT::FormatUuid( m_out, 0, aGenerator->m_Uuid ); + KICAD_FORMAT::FormatUuid( m_out, aGenerator->m_Uuid ); - m_out->Print( 0, "(type %s) (name %s)\n", + m_out->Print( "(type %s) (name %s) (layer %s)", TO_UTF8( aGenerator->GetGeneratorType() ), - m_out->Quotew( aGenerator->GetName() ).c_str() ); - - m_out->Print( aNestLevel + 1, "(layer %s)", + m_out->Quotew( aGenerator->GetName() ).c_str(), m_out->Quotew( LSET::Name( aGenerator->GetLayer() ) ).c_str() ); - if( const bool locked = aGenerator->IsLocked() ) { - KICAD_FORMAT::FormatBool( m_out, 0, "locked", locked ); - } + if( aGenerator->IsLocked() ) + KICAD_FORMAT::FormatBool( m_out, "locked", true ); for( const auto& [key, value] : aGenerator->GetProperties() ) { @@ -2366,21 +2215,22 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_GENERATOR* aGenerator, int aNestLevel std::string buf = fmt::format( "{:.10g}", val ); // Don't quote numbers - m_out->Print( aNestLevel + 1, "(%s %s)\n", key.c_str(), buf.c_str() ); + m_out->Print( "(%s %s)", key.c_str(), buf.c_str() ); } else if( value.CheckType<bool>() ) { bool val; value.GetAs( &val ); - m_out->Print( aNestLevel + 1, "(%s %s)\n", key.c_str(), val ? "yes" : "no" ); + KICAD_FORMAT::FormatBool( m_out, key, val ); } else if( value.CheckType<VECTOR2I>() ) { VECTOR2I val; value.GetAs( &val ); - m_out->Print( aNestLevel + 1, "(%s (xy %s))\n", key.c_str(), + m_out->Print( "(%s (xy %s))", + key.c_str(), formatInternalUnits( val ).c_str() ); } else if( value.CheckType<SHAPE_LINE_CHAIN>() ) @@ -2388,12 +2238,9 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_GENERATOR* aGenerator, int aNestLevel SHAPE_LINE_CHAIN val; value.GetAs( &val ); - m_out->Print( aNestLevel + 1, "(%s (pts\n", key.c_str() ); - - for( const VECTOR2I& pt : val.CPoints() ) - m_out->Print( aNestLevel + 2, "(xy %s)\n", formatInternalUnits( pt ).c_str() ); - - m_out->Print( aNestLevel + 1, "))\n" ); + m_out->Print( "(%s ", key.c_str() ); + formatPolyPts( val ); + m_out->Print( ")" ); } else { @@ -2411,12 +2258,10 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_GENERATOR* aGenerator, int aNestLevel val = wxString::FromUTF8( str ); } - m_out->Print( aNestLevel + 1, "(%s %s)\n", key.c_str(), m_out->Quotew( val ).c_str() ); + m_out->Print( "(%s %s)", key.c_str(), m_out->Quotew( val ).c_str() ); } } - m_out->Print( aNestLevel + 1, "(members\n" ); - wxArrayString memberIds; for( BOARD_ITEM* member : aGenerator->GetItems() ) @@ -2424,16 +2269,17 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_GENERATOR* aGenerator, int aNestLevel memberIds.Sort(); + m_out->Print( "(members" ); + for( const wxString& memberId : memberIds ) - m_out->Print( aNestLevel + 2, "%s\n", TO_UTF8( memberId ) ); + m_out->Print( " %s", m_out->Quotew( memberId ).c_str() ); - m_out->Print( aNestLevel + 1, ")\n" ); // Close `members` token. - - m_out->Print( aNestLevel, ")\n" ); // Close `generator` token. + m_out->Print( ")" ); // Close `members` token. + m_out->Print( ")" ); // Close `generated` token. } -void PCB_IO_KICAD_SEXPR::format( const PCB_TRACK* aTrack, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::format( const PCB_TRACK* aTrack ) const { if( aTrack->Type() == PCB_VIA_T ) { @@ -2444,7 +2290,7 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TRACK* aTrack, int aNestLevel ) const wxCHECK_RET( board != nullptr, wxT( "Via has no parent." ) ); - m_out->Print( aNestLevel, "(via" ); + m_out->Print( "(via" ); via->LayerPair( &layer1, &layer2 ); @@ -2454,18 +2300,18 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TRACK* aTrack, int aNestLevel ) const break; case VIATYPE::BLIND_BURIED: - m_out->Print( 0, " blind" ); + m_out->Print( " blind " ); break; case VIATYPE::MICROVIA: - m_out->Print( 0, " micro" ); + m_out->Print( " micro " ); break; default: THROW_IO_ERROR( wxString::Format( _( "unknown via type %d" ), via->GetViaType() ) ); } - m_out->Print( 0, " (at %s) (size %s)", + m_out->Print( "(at %s) (size %s)", formatInternalUnits( aTrack->GetStart() ).c_str(), formatInternalUnits( via->GetWidth( F_Cu ) ).c_str() ); @@ -2475,24 +2321,24 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TRACK* aTrack, int aNestLevel ) const // always store the drill value, because netclass value is not stored in the board file. // Otherwise the drill value of some (old) vias can be unknown if( via->GetDrill() != UNDEFINED_DRILL_DIAMETER ) - m_out->Print( 0, " (drill %s)", formatInternalUnits( via->GetDrill() ).c_str() ); + m_out->Print( "(drill %s)", formatInternalUnits( via->GetDrill() ).c_str() ); else - m_out->Print( 0, " (drill %s)", formatInternalUnits( via->GetDrillValue() ).c_str() ); + m_out->Print( "(drill %s)", formatInternalUnits( via->GetDrillValue() ).c_str() ); - m_out->Print( 0, " (layers %s %s)", + m_out->Print( "(layers %s %s)", m_out->Quotew( LSET::Name( layer1 ) ).c_str(), m_out->Quotew( LSET::Name( layer2 ) ).c_str() ); switch( via->Padstack().UnconnectedLayerMode() ) { case PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_ALL: - m_out->Print( 0, "(remove_unused_layers yes)" ); - m_out->Print( 0, "(keep_end_layers no)" ); + KICAD_FORMAT::FormatBool( m_out, "remove_unused_layers", true ); + KICAD_FORMAT::FormatBool( m_out, "keep_end_layers", false ); break; case PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_EXCEPT_START_AND_END: - m_out->Print( 0, "(remove_unused_layers yes)" ); - m_out->Print( 0, "(keep_end_layers yes)" ); + KICAD_FORMAT::FormatBool( m_out, "remove_unused_layers", true ); + KICAD_FORMAT::FormatBool( m_out, "keep_end_layers", true ); break; case PADSTACK::UNCONNECTED_LAYER_MODE::KEEP_ALL: @@ -2500,22 +2346,22 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TRACK* aTrack, int aNestLevel ) const } if( via->IsLocked() ) - KICAD_FORMAT::FormatBool( m_out, 0, "locked", via->IsLocked() ); + KICAD_FORMAT::FormatBool( m_out, "locked", true ); if( via->GetIsFree() ) - KICAD_FORMAT::FormatBool( m_out, 0, "free", via->GetIsFree() ); + KICAD_FORMAT::FormatBool( m_out, "free", true ); if( via->GetRemoveUnconnected() ) { - m_out->Print( 0, " (zone_layer_connections" ); + m_out->Print( "(zone_layer_connections" ); for( PCB_LAYER_ID layer : board->GetEnabledLayers().CuStack() ) { if( via->GetZoneLayerOverride( layer ) == ZLO_FORCE_FLASHED ) - m_out->Print( 0, " %s", m_out->Quotew( LSET::Name( layer ) ).c_str() ); + m_out->Print( " %s", m_out->Quotew( LSET::Name( layer ) ).c_str() ); } - m_out->Print( 0, ")" ); + m_out->Print( ")" ); } const PADSTACK& padstack = via->Padstack(); @@ -2524,42 +2370,42 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TRACK* aTrack, int aNestLevel ) const if( padstack.Mode() != PADSTACK::MODE::NORMAL ) { - std::string mode = - padstack.Mode() == PADSTACK::MODE::CUSTOM ? "custom" : "front_inner_back"; - m_out->Print( 0, "(padstack (mode %s)", mode.c_str() ); + m_out->Print( "(padstack" ); if( padstack.Mode() == PADSTACK::MODE::FRONT_INNER_BACK ) { - m_out->Print( 0, "(layer \"Inner\"" ); - m_out->Print( 0, " (size %s)", - formatInternalUnits( padstack.Size( PADSTACK::INNER_LAYERS ).x ).c_str() ); - m_out->Print( 0, ")(layer \"B.Cu\"" ); - m_out->Print( 0, " (size %s)", - formatInternalUnits( padstack.Size( B_Cu ).x ).c_str() ); - m_out->Print( 0, ")" ); + m_out->Print( "(mode front_inner_back)" ); + + m_out->Print( "(layer \"Inner\"" ); + m_out->Print( "(size %s)", + formatInternalUnits( padstack.Size( PADSTACK::INNER_LAYERS ).x ).c_str() ); + m_out->Print( ")" ); + m_out->Print( "(layer \"B.Cu\"" ); + m_out->Print( "(size %s)", + formatInternalUnits( padstack.Size( B_Cu ).x ).c_str() ); + m_out->Print( ")" ); } else { + m_out->Print( "(mode custom)" ); + for( PCB_LAYER_ID layer : LAYER_RANGE( F_Cu, B_Cu, board->GetCopperLayerCount() ) ) { if( layer == F_Cu ) continue; - m_out->Print( 0, "(layer %s", m_out->Quotew( LSET::Name( layer ) ).c_str() ); - m_out->Print( 0, " (size %s)", - formatInternalUnits( padstack.Size( layer ).x ).c_str() ); - m_out->Print( 0, ")" ); + m_out->Print( "(layer %s", m_out->Quotew( LSET::Name( layer ) ).c_str() ); + m_out->Print( "(size %s)", + formatInternalUnits( padstack.Size( layer ).x ).c_str() ); + m_out->Print( ")" ); } } - m_out->Print( 0, ")" ); + m_out->Print( ")" ); } if( !isDefaultTeardropParameters( via->GetTeardropParams() ) ) - { - m_out->Print( 0, "\n" ); - formatTeardropParameters( via->GetTeardropParams(), aNestLevel+1 ); - } + formatTeardropParameters( via->GetTeardropParams() ); } else { @@ -2567,7 +2413,7 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TRACK* aTrack, int aNestLevel ) const { const PCB_ARC* arc = static_cast<const PCB_ARC*>( aTrack ); - m_out->Print( aNestLevel, "(arc (start %s) (mid %s) (end %s) (width %s)", + m_out->Print( "(arc (start %s) (mid %s) (end %s) (width %s)", formatInternalUnits( arc->GetStart() ).c_str(), formatInternalUnits( arc->GetMid() ).c_str(), formatInternalUnits( arc->GetEnd() ).c_str(), @@ -2575,14 +2421,14 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TRACK* aTrack, int aNestLevel ) const } else { - m_out->Print( aNestLevel, "(segment (start %s) (end %s) (width %s)", + m_out->Print( "(segment (start %s) (end %s) (width %s)", formatInternalUnits( aTrack->GetStart() ).c_str(), formatInternalUnits( aTrack->GetEnd() ).c_str(), formatInternalUnits( aTrack->GetWidth() ).c_str() ); } if( aTrack->IsLocked() ) - KICAD_FORMAT::FormatBool( m_out, 0, "locked", aTrack->IsLocked() ); + KICAD_FORMAT::FormatBool( m_out, "locked", true ); if( aTrack->GetLayerSet().count() > 1 ) formatLayers( aTrack->GetLayerSet() ); @@ -2593,19 +2439,19 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TRACK* aTrack, int aNestLevel ) const && aTrack->GetLocalSolderMaskMargin().has_value() && ( aTrack->IsOnLayer( F_Cu ) || aTrack->IsOnLayer( B_Cu ) ) ) { - m_out->Print( 0, " (solder_mask_margin %s)", + m_out->Print( "(solder_mask_margin %s)", formatInternalUnits( aTrack->GetLocalSolderMaskMargin().value() ).c_str() ); } } - m_out->Print( 0, " (net %d)", m_mapping->Translate( aTrack->GetNetCode() ) ); + m_out->Print( "(net %d)", m_mapping->Translate( aTrack->GetNetCode() ) ); - KICAD_FORMAT::FormatUuid( m_out, 0, aTrack->m_Uuid ); - m_out->Print( 0, ")\n" ); + KICAD_FORMAT::FormatUuid( m_out, aTrack->m_Uuid ); + m_out->Print( ")" ); } -void PCB_IO_KICAD_SEXPR::format( const ZONE* aZone, int aNestLevel ) const +void PCB_IO_KICAD_SEXPR::format( const ZONE* aZone ) const { // Save the NET info. // For keepout and non copper zones, net code and net name are irrelevant @@ -2614,12 +2460,12 @@ void PCB_IO_KICAD_SEXPR::format( const ZONE* aZone, int aNestLevel ) const bool has_no_net = aZone->GetIsRuleArea() || !aZone->IsOnCopperLayer(); - m_out->Print( aNestLevel, "(zone (net %d) (net_name %s)", + m_out->Print( "(zone (net %d) (net_name %s)", has_no_net ? 0 : m_mapping->Translate( aZone->GetNetCode() ), m_out->Quotew( has_no_net ? wxString( wxT("") ) : aZone->GetNetname() ).c_str() ); if( aZone->IsLocked() ) - KICAD_FORMAT::FormatBool( m_out, 0, "locked", aZone->IsLocked() ); + KICAD_FORMAT::FormatBool( m_out, "locked", true ); // If a zone exists on multiple layers, format accordingly LSET layers = aZone->GetLayerSet(); @@ -2628,18 +2474,14 @@ void PCB_IO_KICAD_SEXPR::format( const ZONE* aZone, int aNestLevel ) const layers &= aZone->GetBoard()->GetEnabledLayers(); if( layers.count() > 1 ) - { formatLayers( layers ); - } else - { formatLayer( aZone->GetFirstLayer() ); - } - KICAD_FORMAT::FormatUuid( m_out, 0, aZone->m_Uuid ); + KICAD_FORMAT::FormatUuid( m_out, aZone->m_Uuid ); if( !aZone->GetZoneName().empty() ) - m_out->Print( 0, " (name %s)", m_out->Quotew( aZone->GetZoneName() ).c_str() ); + m_out->Print( "(name %s)", m_out->Quotew( aZone->GetZoneName() ).c_str() ); // Save the outline aux info std::string hatch; @@ -2652,35 +2494,24 @@ void PCB_IO_KICAD_SEXPR::format( const ZONE* aZone, int aNestLevel ) const case ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL: hatch = "full"; break; } - m_out->Print( 0, " (hatch %s %s)\n", hatch.c_str(), + m_out->Print( "(hatch %s %s)", hatch.c_str(), formatInternalUnits( aZone->GetBorderHatchPitch() ).c_str() ); if( aZone->GetAssignedPriority() > 0 ) - m_out->Print( aNestLevel+1, "(priority %d)\n", aZone->GetAssignedPriority() ); + m_out->Print( "(priority %d)", aZone->GetAssignedPriority() ); // Add teardrop keywords in file: (attr (teardrop (type xxx)))where xxx is the teardrop type if( aZone->IsTeardropArea() ) { - const char* td_type; - - switch( aZone->GetTeardropAreaType() ) - { - case TEARDROP_TYPE::TD_VIAPAD: // a teardrop on a via or pad - td_type = "padvia"; - break; - - default: - case TEARDROP_TYPE::TD_TRACKEND: // a teardrop on a track end - td_type = "track_end"; - break; - } - - m_out->Print( aNestLevel+1, "(attr (teardrop (type %s)))\n", td_type ); + m_out->Print( "(attr (teardrop (type %s)))", + aZone->GetTeardropAreaType() == TEARDROP_TYPE::TD_VIAPAD + ? "padvia" + : "track_end" ); } - m_out->Print( aNestLevel+1, "(connect_pads" ); + m_out->Print( "(connect_pads" ); switch( aZone->GetPadConnection() ) { @@ -2689,35 +2520,33 @@ void PCB_IO_KICAD_SEXPR::format( const ZONE* aZone, int aNestLevel ) const break; case ZONE_CONNECTION::THT_THERMAL: - m_out->Print( 0, " thru_hole_only" ); + m_out->Print( " thru_hole_only" ); break; case ZONE_CONNECTION::FULL: - m_out->Print( 0, " yes" ); + m_out->Print( " yes" ); break; case ZONE_CONNECTION::NONE: - m_out->Print( 0, " no" ); + m_out->Print( " no" ); break; } - m_out->Print( 0, " (clearance %s))\n", + m_out->Print( "(clearance %s)", formatInternalUnits( aZone->GetLocalClearance().value() ).c_str() ); - m_out->Print( aNestLevel+1, "(min_thickness %s)", + m_out->Print( ")" ); + + m_out->Print( "(min_thickness %s)", formatInternalUnits( aZone->GetMinThickness() ).c_str() ); // We continue to write this for 3rd-party parsers, but we no longer read it (as of V7). - m_out->Print( 0, " (filled_areas_thickness no)" ); - - m_out->Print( 0, "\n" ); + m_out->Print( "(filled_areas_thickness no)" ); if( aZone->GetIsRuleArea() ) { // Keepout settings - m_out->Print( aNestLevel + 1, - "(keepout (tracks %s) (vias %s) (pads %s) (copperpour %s) " - "(footprints %s))\n", + m_out->Print( "(keepout (tracks %s) (vias %s) (pads %s) (copperpour %s) (footprints %s))", aZone->GetDoNotAllowTracks() ? "not_allowed" : "allowed", aZone->GetDoNotAllowVias() ? "not_allowed" : "allowed", aZone->GetDoNotAllowPads() ? "not_allowed" : "allowed", @@ -2725,107 +2554,96 @@ void PCB_IO_KICAD_SEXPR::format( const ZONE* aZone, int aNestLevel ) const aZone->GetDoNotAllowFootprints() ? "not_allowed" : "allowed" ); // Multichannel settings - m_out->Print( aNestLevel + 1, "(placement" ); - m_out->Print( aNestLevel + 2, "(enabled " ); - - if( aZone->GetRuleAreaPlacementEnabled() ) - m_out->Print( aNestLevel + 2, "yes)" ); - else - m_out->Print( aNestLevel + 2, "no)" ); + m_out->Print( "(placement" ); + KICAD_FORMAT::FormatBool( m_out, "enabled", aZone->GetRuleAreaPlacementEnabled() ); switch( aZone->GetRuleAreaPlacementSourceType() ) { case RULE_AREA_PLACEMENT_SOURCE_TYPE::SHEETNAME: - m_out->Print( aNestLevel + 2, "(sheetname %s)", + m_out->Print( "(sheetname %s)", m_out->Quotew( aZone->GetRuleAreaPlacementSource() ).c_str() ); break; case RULE_AREA_PLACEMENT_SOURCE_TYPE::COMPONENT_CLASS: - m_out->Print( aNestLevel + 2, "(component_class %s)", + m_out->Print( "(component_class %s)", m_out->Quotew( aZone->GetRuleAreaPlacementSource() ).c_str() ); break; } - m_out->Print( aNestLevel + 1, ")" ); + m_out->Print( ")" ); } - m_out->Print( aNestLevel + 1, "(fill" ); + m_out->Print( "(fill" ); // Default is not filled. if( aZone->IsFilled() ) - m_out->Print( 0, " yes" ); + m_out->Print( " yes" ); // Default is polygon filled. if( aZone->GetFillMode() == ZONE_FILL_MODE::HATCH_PATTERN ) - m_out->Print( 0, " (mode hatch)" ); + m_out->Print( "(mode hatch)" ); - m_out->Print( 0, " (thermal_gap %s) (thermal_bridge_width %s)", + m_out->Print( "(thermal_gap %s) (thermal_bridge_width %s)", formatInternalUnits( aZone->GetThermalReliefGap() ).c_str(), formatInternalUnits( aZone->GetThermalReliefSpokeWidth() ).c_str() ); if( aZone->GetCornerSmoothingType() != ZONE_SETTINGS::SMOOTHING_NONE ) { - m_out->Print( 0, " (smoothing" ); - switch( aZone->GetCornerSmoothingType() ) { case ZONE_SETTINGS::SMOOTHING_CHAMFER: - m_out->Print( 0, " chamfer" ); + m_out->Print( "(smoothing chamfer)" ); break; case ZONE_SETTINGS::SMOOTHING_FILLET: - m_out->Print( 0, " fillet" ); + m_out->Print( "(smoothing fillet)" ); break; default: THROW_IO_ERROR( wxString::Format( _( "unknown zone corner smoothing type %d" ), aZone->GetCornerSmoothingType() ) ); } - m_out->Print( 0, ")" ); if( aZone->GetCornerRadius() != 0 ) - m_out->Print( 0, " (radius %s)", formatInternalUnits( aZone->GetCornerRadius() ).c_str() ); + m_out->Print( "(radius %s)", formatInternalUnits( aZone->GetCornerRadius() ).c_str() ); } if( aZone->GetIslandRemovalMode() != ISLAND_REMOVAL_MODE::ALWAYS ) { - m_out->Print( 0, " (island_removal_mode %d) (island_area_min %s)", + m_out->Print( "(island_removal_mode %d) (island_area_min %s)", static_cast<int>( aZone->GetIslandRemovalMode() ), formatInternalUnits( aZone->GetMinIslandArea() / pcbIUScale.IU_PER_MM ).c_str() ); } if( aZone->GetFillMode() == ZONE_FILL_MODE::HATCH_PATTERN ) { - m_out->Print( 0, "\n" ); - m_out->Print( aNestLevel+2, "(hatch_thickness %s) (hatch_gap %s) (hatch_orientation %s)", + m_out->Print( "(hatch_thickness %s) (hatch_gap %s) (hatch_orientation %s)", formatInternalUnits( aZone->GetHatchThickness() ).c_str(), formatInternalUnits( aZone->GetHatchGap() ).c_str(), FormatDouble2Str( aZone->GetHatchOrientation().AsDegrees() ).c_str() ); if( aZone->GetHatchSmoothingLevel() > 0 ) { - m_out->Print( 0, "\n" ); - m_out->Print( aNestLevel+2, "(hatch_smoothing_level %d) (hatch_smoothing_value %s)", + m_out->Print( "(hatch_smoothing_level %d) (hatch_smoothing_value %s)", aZone->GetHatchSmoothingLevel(), FormatDouble2Str( aZone->GetHatchSmoothingValue() ).c_str() ); } - m_out->Print( 0, "\n" ); - m_out->Print( aNestLevel+2, "(hatch_border_algorithm %s) (hatch_min_hole_area %s)", + m_out->Print( "(hatch_border_algorithm %s) (hatch_min_hole_area %s)", aZone->GetHatchBorderAlgorithm() ? "hatch_thickness" : "min_thickness", FormatDouble2Str( aZone->GetHatchHoleMinArea() ).c_str() ); } - m_out->Print( 0, ")\n" ); + m_out->Print( ")" ); if( aZone->GetNumCorners() ) { SHAPE_POLY_SET::POLYGON poly = aZone->Outline()->Polygon(0); - for( auto& chain : poly ) + for( const SHAPE_LINE_CHAIN& chain : poly ) { - m_out->Print( aNestLevel + 1, "(polygon\n" ); - formatPolyPts( chain, aNestLevel + 1, ADVANCED_CFG::GetCfg().m_CompactSave ); - m_out->Print( aNestLevel + 1, ")\n" ); + m_out->Print( "(polygon" ); + formatPolyPts( chain ); + m_out->Print( ")" ); } } @@ -2836,21 +2654,20 @@ void PCB_IO_KICAD_SEXPR::format( const ZONE* aZone, int aNestLevel ) const for( int ii = 0; ii < fv->OutlineCount(); ++ii ) { - m_out->Print( aNestLevel + 1, "(filled_polygon\n" ); - m_out->Print( aNestLevel + 2, "(layer %s)\n", - m_out->Quotew( LSET::Name( layer ) ).c_str() ); + m_out->Print( "(filled_polygon" ); + m_out->Print( "(layer %s)", m_out->Quotew( LSET::Name( layer ) ).c_str() ); if( aZone->IsIsland( layer, ii ) ) - m_out->Print( aNestLevel + 2, "(island)\n" ); + m_out->Print( "(island)" ); const SHAPE_LINE_CHAIN& chain = fv->COutline( ii ); - formatPolyPts( chain, aNestLevel + 1, ADVANCED_CFG::GetCfg().m_CompactSave ); - m_out->Print( aNestLevel + 1, ")\n" ); + formatPolyPts( chain ); + m_out->Print( ")" ); } } - m_out->Print( aNestLevel, ")\n" ); + m_out->Print( ")" ); } diff --git a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h index 4d47a1b734..fbd1cbd6eb 100644 --- a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h +++ b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h @@ -366,10 +366,9 @@ public: * Output \a aItem to \a aFormatter in s-expression format. * * @param aItem A pointer the an #BOARD_ITEM object to format. - * @param aNestLevel The indentation nest level. * @throw IO_ERROR on write error. */ - void Format( const BOARD_ITEM* aItem, int aNestLevel = 0 ) const; + void Format( const BOARD_ITEM* aItem ) const; std::string GetStringOutput( bool doClear ) { @@ -394,61 +393,61 @@ protected: void init( const std::map<std::string, UTF8>* aProperties ); /// formats the board setup information - void formatSetup( const BOARD* aBoard, int aNestLevel = 0 ) const; + void formatSetup( const BOARD* aBoard ) const; /// formats the General section of the file - void formatGeneral( const BOARD* aBoard, int aNestLevel = 0 ) const; + void formatGeneral( const BOARD* aBoard ) const; /// formats the board layer information - void formatBoardLayers( const BOARD* aBoard, int aNestLevel = 0 ) const; + void formatBoardLayers( const BOARD* aBoard ) const; /// formats the Nets and Netclasses - void formatNetInformation( const BOARD* aBoard, int aNestLevel = 0 ) const; + void formatNetInformation( const BOARD* aBoard ) const; /// formats the Nets and Netclasses - void formatProperties( const BOARD* aBoard, int aNestLevel = 0 ) const; + void formatProperties( const BOARD* aBoard ) const; /// writes everything that comes before the board_items, like settings and layers etc - void formatHeader( const BOARD* aBoard, int aNestLevel = 0 ) const; + void formatHeader( const BOARD* aBoard ) const; - void formatTeardropParameters( const TEARDROP_PARAMETERS& tdParams, int aNestLevel = 0 ) const; + void formatTeardropParameters( const TEARDROP_PARAMETERS& tdParams ) const; private: - void format( const BOARD* aBoard, int aNestLevel = 0 ) const; + void format( const BOARD* aBoard ) const; - void format( const PCB_DIMENSION_BASE* aDimension, int aNestLevel = 0 ) const; + void format( const PCB_DIMENSION_BASE* aDimension ) const; - void format( const PCB_REFERENCE_IMAGE* aBitmap, int aNestLevel = 0 ) const; + void format( const PCB_REFERENCE_IMAGE* aBitmap ) const; - void format( const PCB_GROUP* aGroup, int aNestLevel = 0 ) const; + void format( const PCB_GROUP* aGroup ) const; - void format( const PCB_SHAPE* aSegment, int aNestLevel = 0 ) const; + void format( const PCB_SHAPE* aSegment ) const; - void format( const PCB_TARGET* aTarget, int aNestLevel = 0 ) const; + void format( const PCB_TARGET* aTarget ) const; - void format( const FOOTPRINT* aFootprint, int aNestLevel = 0 ) const; + void format( const FOOTPRINT* aFootprint ) const; - void format( const PAD* aPad, int aNestLevel = 0 ) const; + void format( const PAD* aPad ) const; - void format( const PCB_TEXT* aText, int aNestLevel = 0 ) const; - void format( const PCB_TEXTBOX* aTextBox, int aNestLevel = 0 ) const; + void format( const PCB_TEXT* aText ) const; + void format( const PCB_TEXTBOX* aTextBox ) const; - void format( const PCB_TABLE* aTable, int aNestLevel = 0 ) const; + void format( const PCB_TABLE* aTable ) const; - void format( const PCB_GENERATOR* aGenerator, int aNestLevel = 0 ) const; + void format( const PCB_GENERATOR* aGenerator ) const; - void format( const PCB_TRACK* aTrack, int aNestLevel = 0 ) const; + void format( const PCB_TRACK* aTrack ) const; - void format( const ZONE* aZone, int aNestLevel = 0 ) const; + void format( const ZONE* aZone ) const; - void formatPolyPts( const SHAPE_LINE_CHAIN& outline, int aNestLevel, bool aCompact, + void formatPolyPts( const SHAPE_LINE_CHAIN& outline, const FOOTPRINT* aParentFP = nullptr ) const; - void formatRenderCache( const EDA_TEXT* aText, int aNestLevel ) const; + void formatRenderCache( const EDA_TEXT* aText ) const; void formatLayer( PCB_LAYER_ID aLayer, bool aIsKnockout = false ) const; - void formatLayers( LSET aLayerMask, int aNestLevel = 0 ) const; + void formatLayers( LSET aLayerMask ) const; void formatTenting( const PADSTACK& aPadstack ) const; diff --git a/pcbnew/pcb_plot_params.cpp b/pcbnew/pcb_plot_params.cpp index b5256bf742..7f734e77f2 100644 --- a/pcbnew/pcb_plot_params.cpp +++ b/pcbnew/pcb_plot_params.cpp @@ -173,91 +173,71 @@ void PCB_PLOT_PARAMS::SetSvgPrecision( unsigned aPrecision ) } -void PCB_PLOT_PARAMS::Format( OUTPUTFORMATTER* aFormatter, - int aNestLevel, int aControl ) const +void PCB_PLOT_PARAMS::Format( OUTPUTFORMATTER* aFormatter ) const { - aFormatter->Print( aNestLevel, "(pcbplotparams\n" ); + aFormatter->Print( "(pcbplotparams" ); - aFormatter->Print( aNestLevel+1, "(layerselection 0x%s)\n", - m_layerSelection.FmtHex().c_str() ); + aFormatter->Print( "(layerselection 0x%s)", m_layerSelection.FmtHex().c_str() ); - aFormatter->Print( aNestLevel+1, "(plot_on_all_layers_selection 0x%s)\n", + aFormatter->Print( "(plot_on_all_layers_selection 0x%s)", m_plotOnAllLayersSelection.FmtHex().c_str() ); - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "disableapertmacros", - m_gerberDisableApertMacros, '\n' ); - - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "usegerberextensions", - m_useGerberProtelExtensions, '\n' ); - - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "usegerberattributes", - GetUseGerberX2format(), '\n' ); - - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "usegerberadvancedattributes", - GetIncludeGerberNetlistInfo(), '\n' ); - - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "creategerberjobfile", - GetCreateGerberJobFile(), '\n' ); + KICAD_FORMAT::FormatBool( aFormatter, "disableapertmacros", m_gerberDisableApertMacros ); + KICAD_FORMAT::FormatBool( aFormatter, "usegerberextensions", m_useGerberProtelExtensions ); + KICAD_FORMAT::FormatBool( aFormatter, "usegerberattributes", GetUseGerberX2format() ); + KICAD_FORMAT::FormatBool( aFormatter, "usegerberadvancedattributes", GetIncludeGerberNetlistInfo() ); + KICAD_FORMAT::FormatBool( aFormatter, "creategerberjobfile", GetCreateGerberJobFile() ); // save this option only if it is not the default value, // to avoid incompatibility with older Pcbnew version if( m_gerberPrecision != gbrDefaultPrecision ) - aFormatter->Print( aNestLevel+1, "(gerberprecision %d)\n", m_gerberPrecision ); + aFormatter->Print( "(gerberprecision %d)", m_gerberPrecision ); - aFormatter->Print( aNestLevel+1, "(dashed_line_dash_ratio %f)\n", GetDashedLineDashRatio() ); - aFormatter->Print( aNestLevel+1, "(dashed_line_gap_ratio %f)\n", GetDashedLineGapRatio() ); + aFormatter->Print( "(dashed_line_dash_ratio %f)", GetDashedLineDashRatio() ); + aFormatter->Print( "(dashed_line_gap_ratio %f)", GetDashedLineGapRatio() ); // SVG options - aFormatter->Print( aNestLevel+1, "(svgprecision %d)\n", m_svgPrecision ); + aFormatter->Print( "(svgprecision %d)", m_svgPrecision ); - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "plotframeref", m_plotDrawingSheet, '\n' ); - aFormatter->Print( aNestLevel+1, "(mode %d)\n", GetPlotMode() == SKETCH ? 2 : 1 ); - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "useauxorigin", m_useAuxOrigin, '\n' ); + KICAD_FORMAT::FormatBool( aFormatter, "plotframeref", m_plotDrawingSheet ); + aFormatter->Print( "(mode %d)", GetPlotMode() == SKETCH ? 2 : 1 ); + KICAD_FORMAT::FormatBool( aFormatter, "useauxorigin", m_useAuxOrigin ); // HPGL options - aFormatter->Print( aNestLevel+1, "(hpglpennumber %d)\n", m_HPGLPenNum ); - aFormatter->Print( aNestLevel+1, "(hpglpenspeed %d)\n", m_HPGLPenSpeed ); - aFormatter->Print( aNestLevel+1, "(hpglpendiameter %f)\n", m_HPGLPenDiam ); + aFormatter->Print( "(hpglpennumber %d)", m_HPGLPenNum ); + aFormatter->Print( "(hpglpenspeed %d)", m_HPGLPenSpeed ); + aFormatter->Print( "(hpglpendiameter %f)", m_HPGLPenDiam ); // PDF options - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, - getTokenName( T_pdf_front_fp_property_popups ), - m_PDFFrontFPPropertyPopups, '\n' ); - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, - getTokenName( T_pdf_back_fp_property_popups ), - m_PDFBackFPPropertyPopups, '\n' ); - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, - getTokenName( T_pdf_metadata ), - m_PDFMetadata, '\n' ); + KICAD_FORMAT::FormatBool( aFormatter, getTokenName( T_pdf_front_fp_property_popups ), + m_PDFFrontFPPropertyPopups ); + KICAD_FORMAT::FormatBool( aFormatter, getTokenName( T_pdf_back_fp_property_popups ), + m_PDFBackFPPropertyPopups ); + KICAD_FORMAT::FormatBool( aFormatter, getTokenName( T_pdf_metadata ), m_PDFMetadata ); // DXF options - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, getTokenName( T_dxfpolygonmode ), - m_DXFPolygonMode, '\n' ); - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, getTokenName( T_dxfimperialunits ), - m_DXFUnits == DXF_UNITS::INCHES, '\n' ); - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, getTokenName( T_dxfusepcbnewfont ), - m_textMode != PLOT_TEXT_MODE::NATIVE, '\n' ); + KICAD_FORMAT::FormatBool( aFormatter, getTokenName( T_dxfpolygonmode ), m_DXFPolygonMode ); + KICAD_FORMAT::FormatBool( aFormatter, getTokenName( T_dxfimperialunits ), + m_DXFUnits == DXF_UNITS::INCHES ); + KICAD_FORMAT::FormatBool( aFormatter, getTokenName( T_dxfusepcbnewfont ), + m_textMode != PLOT_TEXT_MODE::NATIVE ); - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, getTokenName( T_psnegative ), - m_negative, '\n' ); - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, getTokenName( T_psa4output ), - m_A4Output, '\n' ); + KICAD_FORMAT::FormatBool( aFormatter, getTokenName( T_psnegative ), m_negative ); + KICAD_FORMAT::FormatBool( aFormatter, getTokenName( T_psa4output ), m_A4Output ); - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "plotinvisibletext", m_plotInvisibleText, '\n' ); - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "sketchpadsonfab", m_sketchPadsOnFabLayers, '\n' ); - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "plotpadnumbers", m_plotPadNumbers, '\n' ); - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "hidednponfab", m_hideDNPFPsOnFabLayers, '\n' ); - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "sketchdnponfab", m_sketchDNPFPsOnFabLayers, '\n' ); - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "crossoutdnponfab", m_crossoutDNPFPsOnFabLayers, '\n' ); - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "subtractmaskfromsilk", m_subtractMaskFromSilk, '\n' ); - aFormatter->Print( aNestLevel+1, "(outputformat %d)\n", static_cast<int>( m_format ) ); - KICAD_FORMAT::FormatBool( aFormatter, aNestLevel + 1, "mirror", m_mirror, '\n' ); - aFormatter->Print( aNestLevel+1, "(drillshape %d)\n", (int)m_drillMarks ); - aFormatter->Print( aNestLevel+1, "(scaleselection %d)\n", m_scaleSelection ); - aFormatter->Print( aNestLevel+1, "(outputdirectory \"%s\")", - (const char*) m_outputDirectory.utf8_str() ); - aFormatter->Print( 0, "\n" ); - aFormatter->Print( aNestLevel, ")\n" ); + KICAD_FORMAT::FormatBool( aFormatter, "plotinvisibletext", m_plotInvisibleText ); + KICAD_FORMAT::FormatBool( aFormatter, "sketchpadsonfab", m_sketchPadsOnFabLayers ); + KICAD_FORMAT::FormatBool( aFormatter, "plotpadnumbers", m_plotPadNumbers ); + KICAD_FORMAT::FormatBool( aFormatter, "hidednponfab", m_hideDNPFPsOnFabLayers ); + KICAD_FORMAT::FormatBool( aFormatter, "sketchdnponfab", m_sketchDNPFPsOnFabLayers ); + KICAD_FORMAT::FormatBool( aFormatter, "crossoutdnponfab", m_crossoutDNPFPsOnFabLayers ); + KICAD_FORMAT::FormatBool( aFormatter, "subtractmaskfromsilk", m_subtractMaskFromSilk ); + aFormatter->Print( "(outputformat %d)", static_cast<int>( m_format ) ); + KICAD_FORMAT::FormatBool( aFormatter, "mirror", m_mirror ); + aFormatter->Print( "(drillshape %d)", (int)m_drillMarks ); + aFormatter->Print( "(scaleselection %d)", m_scaleSelection ); + aFormatter->Print( "(outputdirectory %s)", aFormatter->Quotew( m_outputDirectory ).c_str() ); + aFormatter->Print( ")" ); } diff --git a/pcbnew/pcb_plot_params.h b/pcbnew/pcb_plot_params.h index 1414deef33..313d0b8d78 100644 --- a/pcbnew/pcb_plot_params.h +++ b/pcbnew/pcb_plot_params.h @@ -41,7 +41,7 @@ public: void SetSkipPlotNPTH_Pads( bool aSkip ) { m_skipNPTH_Pads = aSkip; } bool GetSkipPlotNPTH_Pads() const { return m_skipNPTH_Pads; } - void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl=0 ) const; + void Format( OUTPUTFORMATTER* aFormatter ) const; void Parse( PCB_PLOT_PARAMS_PARSER* aParser ); /** diff --git a/qa/tests/pcbnew/test_prettifier.cpp b/qa/tests/pcbnew/test_prettifier.cpp index 348cf62fd9..b4b1d09069 100644 --- a/qa/tests/pcbnew/test_prettifier.cpp +++ b/qa/tests/pcbnew/test_prettifier.cpp @@ -90,7 +90,7 @@ BOOST_FIXTURE_TEST_CASE( BoardAndFootprintPrettifier, PRETTIFIER_TEST_FIXTURE ) BOOST_REQUIRE( original.get() ); } - KICAD_FORMAT::Prettify( inData ); + KICAD_FORMAT::Prettify( inData, false ); // For diagnosis of test failures std::string tempPath = fmt::format( "{}/{}", tempLibPath, testCaseName );