Make pretty prettier by striving for single line module pads. Add slick std::string based strprintf(), twice.

This commit is contained in:
Dick Hollenbeck 2013-09-26 00:29:54 -05:00
parent a0fbe422c7
commit 4f7c7eb174
7 changed files with 146 additions and 42 deletions

View File

@ -144,7 +144,7 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR
row.SetOptions( in->FromUTF8() ); row.SetOptions( in->FromUTF8() );
// create PROPERTIES* from options, set into the ROW // create PROPERTIES* from options, set into the ROW
row.properties = ParseOptions( in->CurText() ); row.properties = ParseOptions( in->CurStr() );
break; break;
case T_descr: case T_descr:
@ -228,9 +228,9 @@ PROPERTIES* FP_LIB_TABLE::ParseOptions( const std::string& aOptionsList )
++cp; ++cp;
// Find the end of pair/field // Find the end of pair/field
while( cp<end ) while( cp < end )
{ {
if( *cp == '\\' && cp+1 < end && cp[1]==OPT_SEP ) if( *cp=='\\' && cp+1<end && cp[1]==OPT_SEP )
{ {
++cp; // skip the escape ++cp; // skip the escape
pair += *cp++; // add the separator pair += *cp++; // add the separator
@ -261,7 +261,7 @@ PROPERTIES* FP_LIB_TABLE::ParseOptions( const std::string& aOptionsList )
} }
if( props.size() ) if( props.size() )
return new PROPERTIES( props ); return new PROPERTIES( props ); // the far less probable case
else else
return NULL; return NULL;
} }
@ -273,7 +273,7 @@ std::string FP_LIB_TABLE::FormatOptions( const PROPERTIES* aProperties )
if( aProperties ) if( aProperties )
{ {
for( PROPERTIES::const_iterator it = aProperties->begin(); it != aProperties->end(); ++it ) for( PROPERTIES::const_iterator it = aProperties->begin(); it != aProperties->end(); ++it )
{ {
const std::string& name = it->first; const std::string& name = it->first;
const std::string& value = it->second; const std::string& value = it->second;

View File

@ -35,11 +35,64 @@
#endif #endif
// This file defines 3 classes useful for working with DSN text files and is named // This file defines 3 classes and some functions useful for working with text files
// "richio" after its author, Richard Hollenbeck, aka Dick Hollenbeck. // 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<char> 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 ) void IO_ERROR::init( const char* aThrowersFile, const char* aThrowersLoc, const wxString& aMsg )
{ {
errorText.Printf( IO_FORMAT, aMsg.GetData(), errorText.Printf( IO_FORMAT, aMsg.GetData(),

View File

@ -462,6 +462,15 @@ public:
return curText.c_str(); return curText.c_str();
} }
/**
* Function CurStr
* returns a reference to current token in std::string form.
*/
const std::string& CurStr()
{
return curText;
}
/** /**
* Function FromUTF8 * Function FromUTF8
* returns the current token text as a wxString, assuming that the input * returns the current token text as a wxString, assuming that the input

View File

@ -38,6 +38,44 @@
#include <stdio.h> #include <stdio.h>
/**
* 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 * @ingroup exception_types
* @{ * @{
@ -648,5 +686,4 @@ protected:
//-----</OUTPUTFORMATTER>----------------------------------------------- //-----</OUTPUTFORMATTER>-----------------------------------------------
}; };
#endif // RICHIO_H_ #endif // RICHIO_H_

View File

@ -1031,7 +1031,7 @@ void PCB_IO::format( MODULE* aModule, int aNestLevel ) const
// Save pads. // Save pads.
for( D_PAD* pad = aModule->Pads(); pad; pad = pad->Next() ) for( D_PAD* pad = aModule->Pads(); pad; pad = pad->Next() )
Format( pad, aNestLevel+1 ); format( pad, aNestLevel+1 );
// Save 3D info. // Save 3D info.
for( S3D_MASTER* t3D = aModule->Models(); t3D; t3D = t3D->Next() ) 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 void PCB_IO::formatLayers( LAYER_MSK aLayerMask, int aNestLevel ) const
throw( IO_ERROR ) throw( IO_ERROR )
{ {
m_out->Print( aNestLevel, "(layers" ); std::string output;
if( aNestLevel == 0 )
output += ' ';
output += "(layers";
LAYER_MSK cuMask = ALL_CU_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 ) if( ( aLayerMask & cuMask ) == cuMask )
{ {
m_out->Print( 0, " *.Cu" ); output += " *.Cu";
aLayerMask &= ~ALL_CU_LAYERS; // clear bits, so they are not output again below aLayerMask &= ~ALL_CU_LAYERS; // clear bits, so they are not output again below
} }
else if( ( aLayerMask & cuMask ) == (LAYER_BACK | LAYER_FRONT) ) else if( ( aLayerMask & cuMask ) == (LAYER_BACK | LAYER_FRONT) )
{ {
m_out->Print( 0, " F&B.Cu" ); output += " F&B.Cu";
aLayerMask &= ~(LAYER_BACK | LAYER_FRONT); aLayerMask &= ~(LAYER_BACK | LAYER_FRONT);
} }
if( ( aLayerMask & (ADHESIVE_LAYER_BACK | ADHESIVE_LAYER_FRONT)) == (ADHESIVE_LAYER_BACK | ADHESIVE_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); aLayerMask &= ~(ADHESIVE_LAYER_BACK | ADHESIVE_LAYER_FRONT);
} }
if( ( aLayerMask & (SOLDERPASTE_LAYER_BACK | SOLDERPASTE_LAYER_FRONT)) == (SOLDERPASTE_LAYER_BACK | SOLDERPASTE_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); aLayerMask &= ~(SOLDERPASTE_LAYER_BACK | SOLDERPASTE_LAYER_FRONT);
} }
if( ( aLayerMask & (SILKSCREEN_LAYER_BACK | SILKSCREEN_LAYER_FRONT)) == (SILKSCREEN_LAYER_BACK | SILKSCREEN_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); aLayerMask &= ~(SILKSCREEN_LAYER_BACK | SILKSCREEN_LAYER_FRONT);
} }
if( ( aLayerMask & (SOLDERMASK_LAYER_BACK | SOLDERMASK_LAYER_FRONT)) == (SOLDERMASK_LAYER_BACK | SOLDERMASK_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); 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() else // I am being called from FootprintSave()
layerName = BOARD::GetStandardLayerName( layer ); 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, ")" );
} }
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. // Unconnected pad is default net so don't save it.
if( !(m_ctl & CTL_OMIT_NETS) && aPad->GetNet() != 0 ) if( !(m_ctl & CTL_OMIT_NETS) && aPad->GetNet() != 0 )
{ strprintf( &output, " (net %d %s)", aPad->GetNet(), m_out->Quotew( aPad->GetNetname() ).c_str() );
m_out->Print( aNestLevel+1, "(net %d %s)\n",
aPad->GetNet(), m_out->Quotew( aPad->GetNetname() ).c_str() );
}
if( aPad->GetPadToDieLength() != 0 ) if( aPad->GetPadToDieLength() != 0 )
m_out->Print( aNestLevel+1, "(die_length %s)\n", strprintf( &output, " (die_length %s)", FMT_IU( aPad->GetPadToDieLength() ).c_str() );
FMT_IU( aPad->GetPadToDieLength() ).c_str() );
if( aPad->GetLocalSolderMaskMargin() != 0 ) if( aPad->GetLocalSolderMaskMargin() != 0 )
m_out->Print( aNestLevel+1, "(solder_mask_margin %s)\n", strprintf( &output, " (solder_mask_margin %s)", FMT_IU( aPad->GetLocalSolderMaskMargin() ).c_str() );
FMT_IU( aPad->GetLocalSolderMaskMargin() ).c_str() );
if( aPad->GetLocalSolderPasteMargin() != 0 ) if( aPad->GetLocalSolderPasteMargin() != 0 )
m_out->Print( aNestLevel+1, "(solder_paste_margin %s)\n", strprintf( &output, " (solder_paste_margin %s)", FMT_IU( aPad->GetLocalSolderPasteMargin() ).c_str() );
FMT_IU( aPad->GetLocalSolderPasteMargin() ).c_str() );
if( aPad->GetLocalSolderPasteMarginRatio() != 0 ) if( aPad->GetLocalSolderPasteMarginRatio() != 0 )
m_out->Print( aNestLevel+1, "(solder_paste_margin_ratio %s)\n", strprintf( &output, " (solder_paste_margin_ratio %s)",
Double2Str( aPad->GetLocalSolderPasteMarginRatio() ).c_str() ); Double2Str( aPad->GetLocalSolderPasteMarginRatio() ).c_str() );
if( aPad->GetLocalClearance() != 0 ) if( aPad->GetLocalClearance() != 0 )
m_out->Print( aNestLevel+1, "(clearance %s)\n", strprintf( &output, " (clearance %s)", FMT_IU( aPad->GetLocalClearance() ).c_str() );
FMT_IU( aPad->GetLocalClearance() ).c_str() );
if( aPad->GetZoneConnection() != UNDEFINED_CONNECTION ) 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 ) if( aPad->GetThermalWidth() != 0 )
m_out->Print( aNestLevel+1, "(thermal_width %s)\n", strprintf( &output, " (thermal_width %s)", FMT_IU( aPad->GetThermalWidth() ).c_str() );
FMT_IU( aPad->GetThermalWidth() ).c_str() );
if( aPad->GetThermalGap() != 0 ) if( aPad->GetThermalGap() != 0 )
m_out->Print( aNestLevel+1, "(thermal_gap %s)\n", strprintf( &output, " (thermal_gap %s)", FMT_IU( aPad->GetThermalGap() ).c_str() );
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" );
} }

View File

@ -156,7 +156,9 @@ protected:
wxString m_error; ///< for throwing exceptions wxString m_error; ///< for throwing exceptions
BOARD* m_board; ///< which BOARD, no ownership here 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. FP_CACHE* m_cache; ///< Footprint library cache.
LINE_READER* m_reader; ///< no ownership here. LINE_READER* m_reader; ///< no ownership here.

View File

@ -154,7 +154,7 @@ MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary,
bool aUseFootprintViewer, bool aUseFootprintViewer,
wxDC* aDC ) wxDC* aDC )
{ {
MODULE* module; MODULE* module = NULL;
wxPoint curspos = GetCrossHairPosition(); wxPoint curspos = GetCrossHairPosition();
wxString moduleName, keys; wxString moduleName, keys;
wxString libName = aLibrary; wxString libName = aLibrary;