From 4f7c7eb174ad858768a1b70c17b8c74d6e8db327 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Thu, 26 Sep 2013 00:29:54 -0500 Subject: [PATCH] Make pretty prettier by striving for single line module pads. Add slick std::string based strprintf(), twice. --- common/fp_lib_table.cpp | 10 +++--- common/richio.cpp | 57 +++++++++++++++++++++++++++++++++-- include/dsnlexer.h | 9 ++++++ include/richio.h | 39 +++++++++++++++++++++++- pcbnew/kicad_plugin.cpp | 67 +++++++++++++++++++++-------------------- pcbnew/kicad_plugin.h | 4 ++- pcbnew/loadcmp.cpp | 2 +- 7 files changed, 146 insertions(+), 42 deletions(-) diff --git a/common/fp_lib_table.cpp b/common/fp_lib_table.cpp index 5c85243a3d..2fe60f2070 100644 --- a/common/fp_lib_table.cpp +++ b/common/fp_lib_table.cpp @@ -144,7 +144,7 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR row.SetOptions( in->FromUTF8() ); // create PROPERTIES* from options, set into the ROW - row.properties = ParseOptions( in->CurText() ); + row.properties = ParseOptions( in->CurStr() ); break; case T_descr: @@ -228,9 +228,9 @@ PROPERTIES* FP_LIB_TABLE::ParseOptions( const std::string& aOptionsList ) ++cp; // Find the end of pair/field - while( cpbegin(); it != aProperties->end(); ++it ) + for( PROPERTIES::const_iterator it = aProperties->begin(); it != aProperties->end(); ++it ) { const std::string& name = it->first; const std::string& value = it->second; diff --git a/common/richio.cpp b/common/richio.cpp index 664958e55f..08b3ffcfad 100644 --- a/common/richio.cpp +++ b/common/richio.cpp @@ -35,11 +35,64 @@ #endif -// This file defines 3 classes useful for working with DSN text files and is named -// "richio" after its author, Richard Hollenbeck, aka Dick Hollenbeck. +// This file defines 3 classes and some functions useful for working with text files +// and is named "richio" after its author, Richard Hollenbeck, aka Dick Hollenbeck. +int vprint( std::string* result, const char* format, va_list ap ) +{ + char msg[512]; + size_t len = vsnprintf( msg, sizeof(msg), format, ap ); + + if( len < sizeof(msg) ) // the output fit into msg + { + result->append( msg, msg + len ); + } + else + { + // output was too big, so now incur the expense of allocating + // a buf for holding suffient characters. + + std::vector buf; + + buf.reserve( len+1 ); // reserve(), not resize() which writes. +1 for trailing nul. + + len = vsnprintf( &buf[0], len+1, format, ap ); + + result->append( &buf[0], &buf[0] + len ); + } + + return len; +} + + +int strprintf( std::string* result, const char* format, ... ) +{ + va_list args; + + va_start( args, format ); + int ret = vprint( result, format, args ); + va_end( args ); + + return ret; +} + + +std::string strprintf( const char* format, ... ) +{ + std::string ret; + va_list args; + + va_start( args, format ); + int ignore = vprint( &ret, format, args ); + (void) ignore; + va_end( args ); + + return ret; +} + + void IO_ERROR::init( const char* aThrowersFile, const char* aThrowersLoc, const wxString& aMsg ) { errorText.Printf( IO_FORMAT, aMsg.GetData(), diff --git a/include/dsnlexer.h b/include/dsnlexer.h index c85a6bd982..fcb4433d6c 100644 --- a/include/dsnlexer.h +++ b/include/dsnlexer.h @@ -462,6 +462,15 @@ public: return curText.c_str(); } + /** + * Function CurStr + * returns a reference to current token in std::string form. + */ + const std::string& CurStr() + { + return curText; + } + /** * Function FromUTF8 * returns the current token text as a wxString, assuming that the input diff --git a/include/richio.h b/include/richio.h index 72bd733298..17d3851793 100644 --- a/include/richio.h +++ b/include/richio.h @@ -38,6 +38,44 @@ #include +/** + * Function vprint + * is like vsprintf() but the output is appended to a std::string instead of to a + * character array. + * @param result is the string to append to, previous text is not clear()ed. + * @param format is a printf() style format string. + * @param ap is a va_list argument stack pointer which gives the + * modifying data for the format string. + */ +int vprint( std::string* result, const char* format, va_list ap ); + + +/** + * Function strprintf + * is like sprintf() but the output is appended to a std::string instead of to a + * character array. + * @param result is the string to append to, previous text is not clear()ed. + * @param format is a printf() style format string. + * @param ap is a va_list argument stack pointer which gives the + * modifying data for the format string. + * + * @return int - the count of bytes appended to the result string, no terminating nul is included. + */ +int strprintf( std::string* result, const char* format, ... ); + + +/** + * Function strprintf + * is like sprintf() but the output is returned in a std::string instead of to a + * character array. + * @param result is the string to append to, previous text is not clear()ed. + * @param format is a printf() style format string. + * @param ap is a va_list argument stack pointer which gives the + * modifying data for the format string. + */ +std::string strprintf( const char* format, ... ); + + /** * @ingroup exception_types * @{ @@ -648,5 +686,4 @@ protected: //---------------------------------------------------- }; - #endif // RICHIO_H_ diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 6e973a618c..98af5080f2 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -1031,7 +1031,7 @@ void PCB_IO::format( MODULE* aModule, int aNestLevel ) const // Save pads. for( D_PAD* pad = aModule->Pads(); pad; pad = pad->Next() ) - Format( pad, aNestLevel+1 ); + format( pad, aNestLevel+1 ); // Save 3D info. for( S3D_MASTER* t3D = aModule->Models(); t3D; t3D = t3D->Next() ) @@ -1067,7 +1067,12 @@ void PCB_IO::format( MODULE* aModule, int aNestLevel ) const void PCB_IO::formatLayers( LAYER_MSK aLayerMask, int aNestLevel ) const throw( IO_ERROR ) { - m_out->Print( aNestLevel, "(layers" ); + std::string output; + + if( aNestLevel == 0 ) + output += ' '; + + output += "(layers"; LAYER_MSK cuMask = ALL_CU_LAYERS; @@ -1078,36 +1083,36 @@ void PCB_IO::formatLayers( LAYER_MSK aLayerMask, int aNestLevel ) const if( ( aLayerMask & cuMask ) == cuMask ) { - m_out->Print( 0, " *.Cu" ); + output += " *.Cu"; aLayerMask &= ~ALL_CU_LAYERS; // clear bits, so they are not output again below } else if( ( aLayerMask & cuMask ) == (LAYER_BACK | LAYER_FRONT) ) { - m_out->Print( 0, " F&B.Cu" ); + output += " F&B.Cu"; aLayerMask &= ~(LAYER_BACK | LAYER_FRONT); } if( ( aLayerMask & (ADHESIVE_LAYER_BACK | ADHESIVE_LAYER_FRONT)) == (ADHESIVE_LAYER_BACK | ADHESIVE_LAYER_FRONT) ) { - m_out->Print( 0, " *.Adhes" ); + output += " *.Adhes"; aLayerMask &= ~(ADHESIVE_LAYER_BACK | ADHESIVE_LAYER_FRONT); } if( ( aLayerMask & (SOLDERPASTE_LAYER_BACK | SOLDERPASTE_LAYER_FRONT)) == (SOLDERPASTE_LAYER_BACK | SOLDERPASTE_LAYER_FRONT) ) { - m_out->Print( 0, " *.Paste" ); + output += " *.Paste"; aLayerMask &= ~(SOLDERPASTE_LAYER_BACK | SOLDERPASTE_LAYER_FRONT); } if( ( aLayerMask & (SILKSCREEN_LAYER_BACK | SILKSCREEN_LAYER_FRONT)) == (SILKSCREEN_LAYER_BACK | SILKSCREEN_LAYER_FRONT) ) { - m_out->Print( 0, " *.SilkS" ); + output += " *.SilkS"; aLayerMask &= ~(SILKSCREEN_LAYER_BACK | SILKSCREEN_LAYER_FRONT); } if( ( aLayerMask & (SOLDERMASK_LAYER_BACK | SOLDERMASK_LAYER_FRONT)) == (SOLDERMASK_LAYER_BACK | SOLDERMASK_LAYER_FRONT) ) { - m_out->Print( 0, " *.Mask" ); + output += " *.Mask"; aLayerMask &= ~(SOLDERMASK_LAYER_BACK | SOLDERMASK_LAYER_FRONT); } @@ -1128,11 +1133,12 @@ void PCB_IO::formatLayers( LAYER_MSK aLayerMask, int aNestLevel ) const else // I am being called from FootprintSave() layerName = BOARD::GetStandardLayerName( layer ); - m_out->Print( 0, " %s", m_out->Quotew( layerName ).c_str() ); + output += ' '; + output += m_out->Quotew( layerName ); } } - m_out->Print( 0, ")\n" ); + m_out->Print( aNestLevel, "%s)", output.c_str() ); } @@ -1203,49 +1209,46 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const m_out->Print( 0, ")" ); } - m_out->Print( 0, "\n" ); + formatLayers( aPad->GetLayerMask(), 0 ); - formatLayers( aPad->GetLayerMask(), aNestLevel+1 ); + std::string output; // Unconnected pad is default net so don't save it. if( !(m_ctl & CTL_OMIT_NETS) && aPad->GetNet() != 0 ) - { - m_out->Print( aNestLevel+1, "(net %d %s)\n", - aPad->GetNet(), m_out->Quotew( aPad->GetNetname() ).c_str() ); - } + strprintf( &output, " (net %d %s)", aPad->GetNet(), m_out->Quotew( aPad->GetNetname() ).c_str() ); if( aPad->GetPadToDieLength() != 0 ) - m_out->Print( aNestLevel+1, "(die_length %s)\n", - FMT_IU( aPad->GetPadToDieLength() ).c_str() ); + strprintf( &output, " (die_length %s)", FMT_IU( aPad->GetPadToDieLength() ).c_str() ); if( aPad->GetLocalSolderMaskMargin() != 0 ) - m_out->Print( aNestLevel+1, "(solder_mask_margin %s)\n", - FMT_IU( aPad->GetLocalSolderMaskMargin() ).c_str() ); + strprintf( &output, " (solder_mask_margin %s)", FMT_IU( aPad->GetLocalSolderMaskMargin() ).c_str() ); if( aPad->GetLocalSolderPasteMargin() != 0 ) - m_out->Print( aNestLevel+1, "(solder_paste_margin %s)\n", - FMT_IU( aPad->GetLocalSolderPasteMargin() ).c_str() ); + strprintf( &output, " (solder_paste_margin %s)", FMT_IU( aPad->GetLocalSolderPasteMargin() ).c_str() ); if( aPad->GetLocalSolderPasteMarginRatio() != 0 ) - m_out->Print( aNestLevel+1, "(solder_paste_margin_ratio %s)\n", - Double2Str( aPad->GetLocalSolderPasteMarginRatio() ).c_str() ); + strprintf( &output, " (solder_paste_margin_ratio %s)", + Double2Str( aPad->GetLocalSolderPasteMarginRatio() ).c_str() ); if( aPad->GetLocalClearance() != 0 ) - m_out->Print( aNestLevel+1, "(clearance %s)\n", - FMT_IU( aPad->GetLocalClearance() ).c_str() ); + strprintf( &output, " (clearance %s)", FMT_IU( aPad->GetLocalClearance() ).c_str() ); if( aPad->GetZoneConnection() != UNDEFINED_CONNECTION ) - m_out->Print( aNestLevel+1, "(zone_connect %d)\n", aPad->GetZoneConnection() ); + strprintf( &output, " (zone_connect %d)", aPad->GetZoneConnection() ); if( aPad->GetThermalWidth() != 0 ) - m_out->Print( aNestLevel+1, "(thermal_width %s)\n", - FMT_IU( aPad->GetThermalWidth() ).c_str() ); + strprintf( &output, " (thermal_width %s)", FMT_IU( aPad->GetThermalWidth() ).c_str() ); if( aPad->GetThermalGap() != 0 ) - m_out->Print( aNestLevel+1, "(thermal_gap %s)\n", - FMT_IU( aPad->GetThermalGap() ).c_str() ); + strprintf( &output, " (thermal_gap %s)", FMT_IU( aPad->GetThermalGap() ).c_str() ); - m_out->Print( aNestLevel, ")\n" ); + if( output.size() ) + { + m_out->Print( 0, "\n" ); + m_out->Print( aNestLevel+1, "%s", output.c_str() + 1 ); // +1 skips initial space on first element + } + + m_out->Print( 0, ")\n" ); } diff --git a/pcbnew/kicad_plugin.h b/pcbnew/kicad_plugin.h index 5b18ae3e3f..4a23ae6306 100644 --- a/pcbnew/kicad_plugin.h +++ b/pcbnew/kicad_plugin.h @@ -156,7 +156,9 @@ protected: wxString m_error; ///< for throwing exceptions BOARD* m_board; ///< which BOARD, no ownership here - const PROPERTIES* m_props; ///< passed via Save() or Load(), no ownership, may be NULL. + + const + PROPERTIES* m_props; ///< passed via Save() or Load(), no ownership, may be NULL. FP_CACHE* m_cache; ///< Footprint library cache. LINE_READER* m_reader; ///< no ownership here. diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index 376fd83600..6d7d3db020 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -154,7 +154,7 @@ MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary, bool aUseFootprintViewer, wxDC* aDC ) { - MODULE* module; + MODULE* module = NULL; wxPoint curspos = GetCrossHairPosition(); wxString moduleName, keys; wxString libName = aLibrary;