Browse Source

Convert sprintf to snprintf in most files

newinvert
Nimish Telang 3 years ago
committed by Seth Hillbrand
parent
commit
51e55dd750
  1. 138
      bitmap2component/bitmap2component.cpp
  2. 2
      common/gbr_metadata.cpp
  3. 73
      common/plotters/GERBER_plotter.cpp
  4. 4
      common/plotters/PDF_plotter.cpp
  5. 8
      common/tool/tool_event.cpp
  6. 17
      pcbnew/exporters/gendrill_Excellon_writer.cpp
  7. 2
      pcbnew/exporters/gendrill_Excellon_writer.h
  8. 4
      pcbnew/exporters/gerber_jobfile_writer.cpp
  9. 10
      pcbnew/files.cpp
  10. 8
      pcbnew/specctra_import_export/specctra.h
  11. 30
      pcbnew/specctra_import_export/specctra_export.cpp
  12. 9
      pcbnew/tools/pcb_control.cpp
  13. 5
      qa/tools/pns/label_manager.cpp
  14. 13
      qa/tools/pns/pns_log_viewer_frame.cpp
  15. 7
      scripting/python_scripting.cpp

138
bitmap2component/bitmap2component.cpp

@ -83,7 +83,7 @@ int BITMAPCONV_INFO::ConvertBitmap( potrace_bitmap_t* aPotrace_bitmap, OUTPUT_FM
if( !param ) if( !param )
{ {
char msg[256]; char msg[256];
sprintf( msg, "Error allocating parameters: %s\n", strerror( errno ) );
snprintf( msg, sizeof( msg ), "Error allocating parameters: %s\n", strerror( errno ) );
m_errors += msg; m_errors += msg;
return 1; return 1;
} }
@ -191,14 +191,15 @@ void BITMAPCONV_INFO::outputDataHeader( const char * aBrdLayerName )
{ {
double Ypos = ( m_PixmapHeight / 2 * m_ScaleY ); // fields Y position in mm double Ypos = ( m_PixmapHeight / 2 * m_ScaleY ); // fields Y position in mm
double fieldSize; // fields text size in mm double fieldSize; // fields text size in mm
char strbuf[1024];
char strbuf[1024];
switch( m_Format ) switch( m_Format )
{ {
case POSTSCRIPT_FMT: case POSTSCRIPT_FMT:
/* output vector data, e.g. as a rudimentary EPS file */ /* output vector data, e.g. as a rudimentary EPS file */
m_Data += "%%!PS-Adobe-3.0 EPSF-3.0\n"; m_Data += "%%!PS-Adobe-3.0 EPSF-3.0\n";
sprintf( strbuf, "%%%%BoundingBox: 0 0 %d %d\n", m_PixmapWidth, m_PixmapHeight );
snprintf( strbuf, sizeof( strbuf ), "%%%%BoundingBox: 0 0 %d %d\n", m_PixmapWidth,
m_PixmapHeight );
m_Data += strbuf; m_Data += strbuf;
m_Data += "gsave\n"; m_Data += "gsave\n";
break; break;
@ -206,26 +207,27 @@ void BITMAPCONV_INFO::outputDataHeader( const char * aBrdLayerName )
case PCBNEW_KICAD_MOD: case PCBNEW_KICAD_MOD:
// fields text size = 1.5 mm // fields text size = 1.5 mm
// fields text thickness = 1.5 / 5 = 0.3mm // fields text thickness = 1.5 / 5 = 0.3mm
sprintf( strbuf,
"(footprint \"%s\" (version 20221018) (generator bitmap2component)\n"
" (layer \"F.Cu\")\n",
m_CmpName.c_str() );
snprintf( strbuf, sizeof( strbuf ),
"(footprint \"%s\" (version 20221018) (generator bitmap2component)\n"
" (layer \"F.Cu\")\n",
m_CmpName.c_str() );
m_Data += strbuf; m_Data += strbuf;
sprintf( strbuf, " (attr board_only exclude_from_pos_files exclude_from_bom)\n" );
snprintf( strbuf, sizeof( strbuf ),
" (attr board_only exclude_from_pos_files exclude_from_bom)\n" );
m_Data += strbuf; m_Data += strbuf;
sprintf( strbuf,
" (fp_text reference \"G***\" (at 0 0) (layer \"%s\")\n"
" (effects (font (size 1.5 1.5) (thickness 0.3)))\n"
" (tstamp %s)\n )\n",
aBrdLayerName, KIID().AsString().ToStdString().c_str() );
snprintf( strbuf, sizeof( strbuf ),
" (fp_text reference \"G***\" (at 0 0) (layer \"%s\")\n"
" (effects (font (size 1.5 1.5) (thickness 0.3)))\n"
" (tstamp %s)\n )\n",
aBrdLayerName, KIID().AsString().ToStdString().c_str() );
m_Data += strbuf; m_Data += strbuf;
sprintf( strbuf,
" (fp_text value \"%s\" (at 0.75 0) (layer \"%s\") hide\n"
" (effects (font (size 1.5 1.5) (thickness 0.3)))\n"
" (tstamp %s)\n )\n",
m_CmpName.c_str(), aBrdLayerName, KIID().AsString().ToStdString().c_str() );
snprintf( strbuf, sizeof( strbuf ),
" (fp_text value \"%s\" (at 0.75 0) (layer \"%s\") hide\n"
" (effects (font (size 1.5 1.5) (thickness 0.3)))\n"
" (tstamp %s)\n )\n",
m_CmpName.c_str(), aBrdLayerName, KIID().AsString().ToStdString().c_str() );
m_Data += strbuf; m_Data += strbuf;
break; break;
@ -241,38 +243,38 @@ void BITMAPCONV_INFO::outputDataHeader( const char * aBrdLayerName )
fieldSize = 1.27; // fields text size in mm (= 50 mils) fieldSize = 1.27; // fields text size in mm (= 50 mils)
Ypos /= SCH_IU_PER_MM; Ypos /= SCH_IU_PER_MM;
Ypos += fieldSize / 2; Ypos += fieldSize / 2;
// sprintf( strbuf, "# pixmap size w = %d, h = %d\n#\n", m_PixmapWidth, m_PixmapHeight );
sprintf( strbuf,
"(kicad_symbol_lib (version 20220914) (generator bitmap2component)\n"
" (symbol \"%s\" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)\n",
m_CmpName.c_str() );
// snprintf( strbuf, sizeof(strbuf), "# pixmap size w = %d, h = %d\n#\n", m_PixmapWidth, m_PixmapHeight );
snprintf( strbuf, sizeof( strbuf ),
"(kicad_symbol_lib (version 20220914) (generator bitmap2component)\n"
" (symbol \"%s\" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)\n",
m_CmpName.c_str() );
m_Data += strbuf; m_Data += strbuf;
sprintf( strbuf,
" (property \"Reference\" \"#G\" (at 0 %g 0)\n"
" (effects (font (size %g %g)) hide)\n )\n",
-Ypos, fieldSize, fieldSize );
snprintf( strbuf, sizeof( strbuf ),
" (property \"Reference\" \"#G\" (at 0 %g 0)\n"
" (effects (font (size %g %g)) hide)\n )\n",
-Ypos, fieldSize, fieldSize );
m_Data += strbuf; m_Data += strbuf;
sprintf( strbuf,
" (property \"Value\" \"%s\" (at 0 %g 0)\n"
" (effects (font (size %g %g)) hide)\n )\n",
m_CmpName.c_str(), Ypos, fieldSize, fieldSize );
snprintf( strbuf, sizeof( strbuf ),
" (property \"Value\" \"%s\" (at 0 %g 0)\n"
" (effects (font (size %g %g)) hide)\n )\n",
m_CmpName.c_str(), Ypos, fieldSize, fieldSize );
m_Data += strbuf; m_Data += strbuf;
sprintf( strbuf,
" (property \"Footprint\" \"\" (at 0 0 0)\n"
" (effects (font (size %g %g)) hide)\n )\n",
fieldSize, fieldSize );
snprintf( strbuf, sizeof( strbuf ),
" (property \"Footprint\" \"\" (at 0 0 0)\n"
" (effects (font (size %g %g)) hide)\n )\n",
fieldSize, fieldSize );
m_Data += strbuf; m_Data += strbuf;
sprintf( strbuf,
" (property \"Datasheet\" \"\" (at 0 0 0)\n"
" (effects (font (size %g %g)) hide)\n )\n",
fieldSize, fieldSize );
snprintf( strbuf, sizeof( strbuf ),
" (property \"Datasheet\" \"\" (at 0 0 0)\n"
" (effects (font (size %g %g)) hide)\n )\n",
fieldSize, fieldSize );
m_Data += strbuf; m_Data += strbuf;
sprintf( strbuf, " (symbol \"%s_0_0\"\n", m_CmpName.c_str() );
snprintf( strbuf, sizeof( strbuf ), " (symbol \"%s_0_0\"\n", m_CmpName.c_str() );
m_Data += strbuf; m_Data += strbuf;
break; break;
} }
@ -311,7 +313,7 @@ void BITMAPCONV_INFO::outputOnePolygon( SHAPE_LINE_CHAIN& aPolygon, const char*
// coordinates are expected in target unit. // coordinates are expected in target unit.
int ii, jj; int ii, jj;
VECTOR2I currpoint; VECTOR2I currpoint;
char strbuf[1024];
char strbuf[1024];
int offsetX = (int)( m_PixmapWidth / 2 * m_ScaleX ); int offsetX = (int)( m_PixmapWidth / 2 * m_ScaleX );
int offsetY = (int)( m_PixmapHeight / 2 * m_ScaleY ); int offsetY = (int)( m_PixmapHeight / 2 * m_ScaleY );
@ -322,14 +324,16 @@ void BITMAPCONV_INFO::outputOnePolygon( SHAPE_LINE_CHAIN& aPolygon, const char*
{ {
case POSTSCRIPT_FMT: case POSTSCRIPT_FMT:
offsetY = (int)( m_PixmapHeight * m_ScaleY ); offsetY = (int)( m_PixmapHeight * m_ScaleY );
sprintf( strbuf, "newpath\n%d %d moveto\n", startpoint.x, offsetY - startpoint.y );
snprintf( strbuf, sizeof( strbuf ), "newpath\n%d %d moveto\n", startpoint.x,
offsetY - startpoint.y );
m_Data += strbuf; m_Data += strbuf;
jj = 0; jj = 0;
for( ii = 1; ii < aPolygon.PointCount(); ii++ ) for( ii = 1; ii < aPolygon.PointCount(); ii++ )
{ {
currpoint = aPolygon.CPoint( ii ); currpoint = aPolygon.CPoint( ii );
sprintf( strbuf, " %d %d lineto", currpoint.x, offsetY - currpoint.y );
snprintf( strbuf, sizeof( strbuf ), " %d %d lineto", currpoint.x,
offsetY - currpoint.y );
m_Data += strbuf; m_Data += strbuf;
if( jj++ > 6 ) if( jj++ > 6 )
@ -352,17 +356,17 @@ void BITMAPCONV_INFO::outputOnePolygon( SHAPE_LINE_CHAIN& aPolygon, const char*
for( ii = 0; ii < aPolygon.PointCount(); ii++ ) for( ii = 0; ii < aPolygon.PointCount(); ii++ )
{ {
currpoint = aPolygon.CPoint( ii ); currpoint = aPolygon.CPoint( ii );
sprintf( strbuf, " (xy %f %f)\n",
( currpoint.x - offsetX ) / PCB_IU_PER_MM,
( currpoint.y - offsetY ) / PCB_IU_PER_MM );
snprintf( strbuf, sizeof( strbuf ), " (xy %f %f)\n",
( currpoint.x - offsetX ) / PCB_IU_PER_MM,
( currpoint.y - offsetY ) / PCB_IU_PER_MM );
m_Data += strbuf; m_Data += strbuf;
} }
// No need to close polygon // No need to close polygon
m_Data += " )\n\n"; m_Data += " )\n\n";
sprintf( strbuf,
" (stroke (width %f) (type solid)) (fill solid) (layer \"%s\") (tstamp %s))\n",
width, aBrdLayerName, KIID().AsString().ToStdString().c_str() );
snprintf( strbuf, sizeof( strbuf ),
" (stroke (width %f) (type solid)) (fill solid) (layer \"%s\") (tstamp %s))\n",
width, aBrdLayerName, KIID().AsString().ToStdString().c_str() );
m_Data += strbuf; m_Data += strbuf;
} }
@ -377,9 +381,9 @@ void BITMAPCONV_INFO::outputOnePolygon( SHAPE_LINE_CHAIN& aPolygon, const char*
for( ii = 0; ii < aPolygon.PointCount(); ii++ ) for( ii = 0; ii < aPolygon.PointCount(); ii++ )
{ {
currpoint = aPolygon.CPoint( ii ); currpoint = aPolygon.CPoint( ii );
sprintf( strbuf, " (xy %.3f %.3f)",
( currpoint.x - offsetX ) / PL_IU_PER_MM,
( currpoint.y - offsetY ) / PL_IU_PER_MM );
snprintf( strbuf, sizeof( strbuf ), " (xy %.3f %.3f)",
( currpoint.x - offsetX ) / PL_IU_PER_MM,
( currpoint.y - offsetY ) / PL_IU_PER_MM );
m_Data += strbuf; m_Data += strbuf;
if( jj++ > 4 ) if( jj++ > 4 )
@ -390,40 +394,40 @@ void BITMAPCONV_INFO::outputOnePolygon( SHAPE_LINE_CHAIN& aPolygon, const char*
} }
// Close polygon // Close polygon
sprintf( strbuf, " (xy %.3f %.3f) )\n",
( startpoint.x - offsetX ) / PL_IU_PER_MM,
( startpoint.y - offsetY ) / PL_IU_PER_MM );
snprintf( strbuf, sizeof( strbuf ), " (xy %.3f %.3f) )\n",
( startpoint.x - offsetX ) / PL_IU_PER_MM,
( startpoint.y - offsetY ) / PL_IU_PER_MM );
m_Data += strbuf; m_Data += strbuf;
break; break;
case EESCHEMA_FMT: case EESCHEMA_FMT:
// The polygon outline thickness is fixed here to 0.01 ( 0.0 is the default thickness) // The polygon outline thickness is fixed here to 0.01 ( 0.0 is the default thickness)
#define SCH_LINE_THICKNESS_MM 0.01
//sprintf( strbuf, "P %d 0 0 %d", (int) aPolygon.PointCount() + 1, EE_LINE_THICKNESS );
#define SCH_LINE_THICKNESS_MM 0.01
//snprintf( strbuf, sizeof(strbuf), "P %d 0 0 %d", (int) aPolygon.PointCount() + 1, EE_LINE_THICKNESS );
m_Data += " (polyline\n (pts\n"; m_Data += " (polyline\n (pts\n";
for( ii = 0; ii < aPolygon.PointCount(); ii++ ) for( ii = 0; ii < aPolygon.PointCount(); ii++ )
{ {
currpoint = aPolygon.CPoint( ii ); currpoint = aPolygon.CPoint( ii );
sprintf( strbuf, " (xy %f %f)\n",
( currpoint.x - offsetX ) / SCH_IU_PER_MM,
( currpoint.y - offsetY ) / SCH_IU_PER_MM );
snprintf( strbuf, sizeof( strbuf ), " (xy %f %f)\n",
( currpoint.x - offsetX ) / SCH_IU_PER_MM,
( currpoint.y - offsetY ) / SCH_IU_PER_MM );
m_Data += strbuf; m_Data += strbuf;
} }
// Close polygon // Close polygon
sprintf( strbuf, " (xy %f %f)\n",
( startpoint.x - offsetX ) / SCH_IU_PER_MM,
( startpoint.y - offsetY ) / SCH_IU_PER_MM );
snprintf( strbuf, sizeof( strbuf ), " (xy %f %f)\n",
( startpoint.x - offsetX ) / SCH_IU_PER_MM,
( startpoint.y - offsetY ) / SCH_IU_PER_MM );
m_Data += strbuf; m_Data += strbuf;
m_Data += " )\n"; // end pts m_Data += " )\n"; // end pts
sprintf( strbuf,
" (stroke (width %g) (type default))\n (fill (type outline))\n",
SCH_LINE_THICKNESS_MM );
snprintf( strbuf, sizeof( strbuf ),
" (stroke (width %g) (type default))\n (fill (type outline))\n",
SCH_LINE_THICKNESS_MM );
m_Data += strbuf; m_Data += strbuf;
m_Data += " )\n"; // end polyline
m_Data += " )\n"; // end polyline
break; break;
} }
} }

2
common/gbr_metadata.cpp

@ -478,7 +478,7 @@ wxString ConvertNotAllowedCharsInGerber( const wxString& aString, bool aAllowUtf
// (Gerber allows only 4 hexadecimal digit) in escape seq: // (Gerber allows only 4 hexadecimal digit) in escape seq:
// "\uXXXX", XXXX is the Unicode 16 bits hexa value // "\uXXXX", XXXX is the Unicode 16 bits hexa value
char hexa[32]; char hexa[32];
sprintf( hexa,"\\u%4.4X", code & 0xFFFF);
std::snprintf( hexa, sizeof( hexa ), "\\u%4.4X", code & 0xFFFF );
txt += hexa; txt += hexa;
} }
else else

73
common/plotters/GERBER_plotter.cpp

@ -29,6 +29,7 @@
#include <math/util.h> // for KiROUND #include <math/util.h> // for KiROUND
#include <trigo.h> #include <trigo.h>
#include <wx/log.h> #include <wx/log.h>
#include <cstdio>
#include <build_version.h> #include <build_version.h>
@ -571,8 +572,6 @@ void GERBER_PLOTTER::selectAperture( int aDiameter, const EDA_ANGLE& aPolygonRot
void GERBER_PLOTTER::writeApertureList() void GERBER_PLOTTER::writeApertureList()
{ {
wxASSERT( m_outputFile ); wxASSERT( m_outputFile );
char cbuf[1024];
std::string buffer;
bool useX1StructuredComment = false; bool useX1StructuredComment = false;
@ -598,8 +597,7 @@ void GERBER_PLOTTER::writeApertureList()
useX1StructuredComment ).c_str(), m_outputFile ); useX1StructuredComment ).c_str(), m_outputFile );
} }
sprintf( cbuf, "%%ADD%d", tool.m_DCode );
buffer = cbuf;
fprintf( m_outputFile, "%%ADD%d", tool.m_DCode );
/* Please note: the Gerber specs for mass parameters say that /* Please note: the Gerber specs for mass parameters say that
exponential syntax is *not* allowed and the decimal point should exponential syntax is *not* allowed and the decimal point should
@ -611,21 +609,21 @@ void GERBER_PLOTTER::writeApertureList()
switch( tool.m_Type ) switch( tool.m_Type )
{ {
case APERTURE::AT_CIRCLE: case APERTURE::AT_CIRCLE:
sprintf( cbuf, "C,%#f*%%\n", tool.GetDiameter() * fscale );
fprintf( m_outputFile, "C,%#f*%%\n", tool.GetDiameter() * fscale );
break; break;
case APERTURE::AT_RECT: case APERTURE::AT_RECT:
sprintf( cbuf, "R,%#fX%#f*%%\n", tool.m_Size.x * fscale,
tool.m_Size.y * fscale );
fprintf( m_outputFile, "R,%#fX%#f*%%\n", tool.m_Size.x * fscale,
tool.m_Size.y * fscale );
break; break;
case APERTURE::AT_PLOTTING: case APERTURE::AT_PLOTTING:
sprintf( cbuf, "C,%#f*%%\n", tool.m_Size.x * fscale );
fprintf( m_outputFile, "C,%#f*%%\n", tool.m_Size.x * fscale );
break; break;
case APERTURE::AT_OVAL: case APERTURE::AT_OVAL:
sprintf( cbuf, "O,%#fX%#f*%%\n", tool.m_Size.x * fscale,
tool.m_Size.y * fscale );
fprintf( m_outputFile, "O,%#fX%#f*%%\n", tool.m_Size.x * fscale,
tool.m_Size.y * fscale );
break; break;
case APERTURE::AT_REGULAR_POLY: case APERTURE::AT_REGULAR_POLY:
@ -639,7 +637,7 @@ void GERBER_PLOTTER::writeApertureList()
case APERTURE::AT_REGULAR_POLY10: case APERTURE::AT_REGULAR_POLY10:
case APERTURE::AT_REGULAR_POLY11: case APERTURE::AT_REGULAR_POLY11:
case APERTURE::AT_REGULAR_POLY12: case APERTURE::AT_REGULAR_POLY12:
sprintf( cbuf, "P,%#fX%dX%#f*%%\n", tool.GetDiameter() * fscale,
fprintf( m_outputFile, "P,%#fX%dX%#f*%%\n", tool.GetDiameter() * fscale,
tool.GetRegPolyVerticeCount(), tool.GetRotation().AsDegrees() ); tool.GetRegPolyVerticeCount(), tool.GetRotation().AsDegrees() );
break; break;
@ -658,26 +656,21 @@ void GERBER_PLOTTER::writeApertureList()
for( int ii = 0; ii < 4; ii++ ) for( int ii = 0; ii < 4; ii++ )
RotatePoint( corners[ii], -tool.m_Rotation ); RotatePoint( corners[ii], -tool.m_Rotation );
sprintf( cbuf, "%s,%#fX", APER_MACRO_ROUNDRECT_NAME,
tool.m_Radius * fscale );
buffer += cbuf;
fprintf( m_outputFile, "%s,%#fX", APER_MACRO_ROUNDRECT_NAME, tool.m_Radius * fscale );
// Add each corner // Add each corner
for( int ii = 0; ii < 4; ii++ ) for( int ii = 0; ii < 4; ii++ )
{ {
sprintf( cbuf, "%#fX%#fX",
corners[ii].x * fscale, corners[ii].y * fscale );
buffer += cbuf;
fprintf( m_outputFile, "%#fX%#fX", corners[ii].x * fscale, corners[ii].y * fscale );
} }
sprintf( cbuf, "0*%%\n" );
fprintf( m_outputFile, "0*%%\n" );
} }
break; break;
case APERTURE::AM_ROT_RECT: // Aperture macro for rotated rect pads case APERTURE::AM_ROT_RECT: // Aperture macro for rotated rect pads
sprintf( cbuf, "%s,%#fX%#fX%#f*%%\n", APER_MACRO_ROT_RECT_NAME,
tool.m_Size.x * fscale, tool.m_Size.y * fscale,
tool.m_Rotation.AsDegrees() );
fprintf( m_outputFile, "%s,%#fX%#fX%#f*%%\n", APER_MACRO_ROT_RECT_NAME,
tool.m_Size.x * fscale, tool.m_Size.y * fscale, tool.m_Rotation.AsDegrees() );
break; break;
case APERTURE::APER_MACRO_OUTLINE4P: // Aperture macro for trapezoid pads case APERTURE::APER_MACRO_OUTLINE4P: // Aperture macro for trapezoid pads
@ -688,33 +681,36 @@ void GERBER_PLOTTER::writeApertureList()
switch( tool.m_Type ) switch( tool.m_Type )
{ {
case APERTURE::APER_MACRO_OUTLINE4P: case APERTURE::APER_MACRO_OUTLINE4P:
sprintf( cbuf, "%s,", APER_MACRO_OUTLINE4P_NAME ); break;
fprintf( m_outputFile, "%s,", APER_MACRO_OUTLINE4P_NAME );
break;
case APERTURE::APER_MACRO_OUTLINE5P: case APERTURE::APER_MACRO_OUTLINE5P:
sprintf( cbuf, "%s,", APER_MACRO_OUTLINE5P_NAME ); break;
fprintf( m_outputFile, "%s,", APER_MACRO_OUTLINE5P_NAME );
break;
case APERTURE::APER_MACRO_OUTLINE6P: case APERTURE::APER_MACRO_OUTLINE6P:
sprintf( cbuf, "%s,", APER_MACRO_OUTLINE6P_NAME ); break;
fprintf( m_outputFile, "%s,", APER_MACRO_OUTLINE6P_NAME );
break;
case APERTURE::APER_MACRO_OUTLINE7P: case APERTURE::APER_MACRO_OUTLINE7P:
sprintf( cbuf, "%s,", APER_MACRO_OUTLINE7P_NAME ); break;
fprintf( m_outputFile, "%s,", APER_MACRO_OUTLINE7P_NAME );
break;
case APERTURE::APER_MACRO_OUTLINE8P: case APERTURE::APER_MACRO_OUTLINE8P:
sprintf( cbuf, "%s,", APER_MACRO_OUTLINE8P_NAME ); break;
fprintf( m_outputFile, "%s,", APER_MACRO_OUTLINE8P_NAME );
break;
default: default:
break; break;
} }
buffer += cbuf;
// Output all corners (should be 4 to 8 corners) // Output all corners (should be 4 to 8 corners)
// Remember: the Y coordinate must be negated, due to the fact in Pcbnew // Remember: the Y coordinate must be negated, due to the fact in Pcbnew
// the Y axis is from top to bottom // the Y axis is from top to bottom
for( size_t ii = 0; ii < tool.m_Corners.size(); ii++ ) for( size_t ii = 0; ii < tool.m_Corners.size(); ii++ )
{ {
sprintf( cbuf, "%#fX%#fX",
tool.m_Corners[ii].x * fscale, -tool.m_Corners[ii].y * fscale );
buffer += cbuf;
fprintf( m_outputFile, "%#fX%#fX", tool.m_Corners[ii].x * fscale,
-tool.m_Corners[ii].y * fscale );
} }
// close outline and output rotation // close outline and output rotation
sprintf( cbuf, "%#f*%%\n", tool.m_Rotation.AsDegrees() );
fprintf( m_outputFile, "%#f*%%\n", tool.m_Rotation.AsDegrees() );
break; break;
case APERTURE::AM_ROTATED_OVAL: // Aperture macro for rotated oval pads case APERTURE::AM_ROTATED_OVAL: // Aperture macro for rotated oval pads
@ -732,10 +728,10 @@ void GERBER_PLOTTER::writeApertureList()
RotatePoint( start, tool.m_Rotation ); RotatePoint( start, tool.m_Rotation );
RotatePoint( end, tool.m_Rotation ); RotatePoint( end, tool.m_Rotation );
sprintf( cbuf, "%s,%#fX%#fX%#fX%#fX%#fX0*%%\n", APER_MACRO_SHAPE_OVAL_NAME,
tool.m_Size.y * fscale, // width
start.x * fscale, -start.y * fscale, // X,Y corner start pos
end.x * fscale, -end.y * fscale ); // X,Y cornerend pos
fprintf( m_outputFile, "%s,%#fX%#fX%#fX%#fX%#fX0*%%\n", APER_MACRO_SHAPE_OVAL_NAME,
tool.m_Size.y * fscale, // width
start.x * fscale, -start.y * fscale, // X,Y corner start pos
end.x * fscale, -end.y * fscale ); // X,Y cornerend pos
} }
break; break;
@ -747,17 +743,12 @@ void GERBER_PLOTTER::writeApertureList()
// Write DCODE id ( "%ADDxx" is already in buffer) and rotation // Write DCODE id ( "%ADDxx" is already in buffer) and rotation
// the full line is something like :%ADD12FreePoly1,45.000000*% // the full line is something like :%ADD12FreePoly1,45.000000*%
sprintf( cbuf, "%s%d,%#f*%%\n",
AM_FREEPOLY_BASENAME,
idx,
fprintf( m_outputFile, "%s%d,%#f*%%\n", AM_FREEPOLY_BASENAME, idx,
tool.m_Rotation.AsDegrees() ); tool.m_Rotation.AsDegrees() );
break; break;
} }
} }
buffer += cbuf;
fputs( buffer.c_str(), m_outputFile );
m_apertureAttribute = attribute; m_apertureAttribute = attribute;
// Currently reset the aperture attribute. Perhaps a better optimization // Currently reset the aperture attribute. Perhaps a better optimization

4
common/plotters/PDF_plotter.cpp

@ -28,6 +28,7 @@
*/ */
#include <algorithm> #include <algorithm>
#include <cstdio> // snprintf
#include <wx/filename.h> #include <wx/filename.h>
#include <wx/mstream.h> #include <wx/mstream.h>
@ -93,11 +94,12 @@ std::string PDF_PLOTTER::encodeStringForPlotter( const wxString& aText )
{ {
result = "<FEFF"; result = "<FEFF";
for( size_t ii = 0; ii < aText.Len(); ii++ ) for( size_t ii = 0; ii < aText.Len(); ii++ )
{ {
unsigned int code = aText[ii]; unsigned int code = aText[ii];
char buffer[16]; char buffer[16];
sprintf( buffer, "%4.4X", code );
std::snprintf( buffer, sizeof( buffer ), "%4.4X", code );
result += buffer; result += buffer;
} }

8
common/tool/tool_event.cpp

@ -155,9 +155,7 @@ const std::string TOOL_EVENT::Format() const
if( m_actions & TA_KEYBOARD ) if( m_actions & TA_KEYBOARD )
{ {
char tmp[128];
sprintf( tmp, "key: %d", m_keyCode );
ev += tmp;
ev += "key: " + std::to_string( m_keyCode );
} }
if( m_actions & ( TA_MOUSE | TA_KEYBOARD ) ) if( m_actions & ( TA_MOUSE | TA_KEYBOARD ) )
@ -168,9 +166,7 @@ const std::string TOOL_EVENT::Format() const
if( m_commandId ) if( m_commandId )
{ {
char tmp[128];
sprintf( tmp, "cmd-id: %d", *m_commandId );
ev += tmp;
ev += "cmd-id: " + std::to_string( *m_commandId );
} }
ev += "cmd-str: " + m_commandStr; ev += "cmd-str: " + m_commandStr;

17
pcbnew/exporters/gendrill_Excellon_writer.cpp

@ -249,7 +249,7 @@ int EXCELLON_WRITER::createDrillFile( FILE* aFile, DRILL_LAYER_PAIR aLayerPair,
xt = x0 * m_conversionUnits; xt = x0 * m_conversionUnits;
yt = y0 * m_conversionUnits; yt = y0 * m_conversionUnits;
writeCoordinates( line, xt, yt );
writeCoordinates( line, sizeof( line ), xt, yt );
fputs( line, m_file ); fputs( line, m_file );
holes_count++; holes_count++;
@ -311,7 +311,7 @@ int EXCELLON_WRITER::createDrillFile( FILE* aFile, DRILL_LAYER_PAIR aLayerPair,
if( m_useRouteModeForOval ) if( m_useRouteModeForOval )
fputs( "G00", m_file ); // Select the routing mode fputs( "G00", m_file ); // Select the routing mode
writeCoordinates( line, xt, yt );
writeCoordinates( line, sizeof( line ), xt, yt );
if( !m_useRouteModeForOval ) if( !m_useRouteModeForOval )
{ {
@ -334,7 +334,7 @@ int EXCELLON_WRITER::createDrillFile( FILE* aFile, DRILL_LAYER_PAIR aLayerPair,
xt = xf * m_conversionUnits; xt = xf * m_conversionUnits;
yt = yf * m_conversionUnits; yt = yf * m_conversionUnits;
writeCoordinates( line, xt, yt );
writeCoordinates( line, sizeof( line ), xt, yt );
fputs( line, m_file ); fputs( line, m_file );
@ -376,7 +376,8 @@ void EXCELLON_WRITER::SetFormat( bool aMetric, ZEROS_FMT aZerosFmt, int aLeftDig
} }
void EXCELLON_WRITER::writeCoordinates( char* aLine, double aCoordX, double aCoordY )
void EXCELLON_WRITER::writeCoordinates( char* aLine, size_t aLineSize, double aCoordX,
double aCoordY )
{ {
wxString xs, ys; wxString xs, ys;
int xpad = m_precision.m_Lhs + m_precision.m_Rhs; int xpad = m_precision.m_Lhs + m_precision.m_Rhs;
@ -419,7 +420,7 @@ void EXCELLON_WRITER::writeCoordinates( char* aLine, double aCoordX, double aCoo
if( ys.Last() == '.' ) if( ys.Last() == '.' )
ys << '0'; ys << '0';
sprintf( aLine, "X%sY%s\n", TO_UTF8( xs ), TO_UTF8( ys ) );
std::snprintf( aLine, aLineSize, "X%sY%s\n", TO_UTF8( xs ), TO_UTF8( ys ) );
break; break;
case SUPPRESS_LEADING: case SUPPRESS_LEADING:
@ -428,7 +429,7 @@ void EXCELLON_WRITER::writeCoordinates( char* aLine, double aCoordX, double aCoo
aCoordX *= 10; aCoordY *= 10; aCoordX *= 10; aCoordY *= 10;
} }
sprintf( aLine, "X%dY%d\n", KiROUND( aCoordX ), KiROUND( aCoordY ) );
std::snprintf( aLine, aLineSize, "X%dY%d\n", KiROUND( aCoordX ), KiROUND( aCoordY ) );
break; break;
case SUPPRESS_TRAILING: case SUPPRESS_TRAILING:
@ -458,7 +459,7 @@ void EXCELLON_WRITER::writeCoordinates( char* aLine, double aCoordX, double aCoo
while( ys[j] == '0' && j ) while( ys[j] == '0' && j )
ys.Truncate( j-- ); ys.Truncate( j-- );
sprintf( aLine, "X%sY%s\n", TO_UTF8( xs ), TO_UTF8( ys ) );
std::snprintf( aLine, aLineSize, "X%sY%s\n", TO_UTF8( xs ), TO_UTF8( ys ) );
break; break;
} }
@ -476,7 +477,7 @@ void EXCELLON_WRITER::writeCoordinates( char* aLine, double aCoordX, double aCoo
xs.Printf( wxT( "%0*d" ), xpad, KiROUND( aCoordX ) ); xs.Printf( wxT( "%0*d" ), xpad, KiROUND( aCoordX ) );
ys.Printf( wxT( "%0*d" ), ypad, KiROUND( aCoordY ) ); ys.Printf( wxT( "%0*d" ), ypad, KiROUND( aCoordY ) );
sprintf( aLine, "X%sY%s\n", TO_UTF8( xs ), TO_UTF8( ys ) );
std::snprintf( aLine, aLineSize, "X%sY%s\n", TO_UTF8( xs ), TO_UTF8( ys ) );
break; break;
} }
} }

2
pcbnew/exporters/gendrill_Excellon_writer.h

@ -143,7 +143,7 @@ private:
/** /**
* Create a line like according to the selected format. * Create a line like according to the selected format.
*/ */
void writeCoordinates( char* aLine, double aCoordX, double aCoordY );
void writeCoordinates( char* aLine, size_t aLineSize, double aCoordX, double aCoordY );
/** /**
* Write a comment string giving the hole attribute. * Write a comment string giving the hole attribute.

4
pcbnew/exporters/gerber_jobfile_writer.cpp

@ -69,7 +69,7 @@ std::string GERBER_JOBFILE_WRITER::formatStringFromUTF32( const wxString& aText
else else
{ {
char buff[16]; char buff[16];
sprintf( buff, "\\u%4.4lX", letter );
std::snprintf( buff, sizeof( buff ), "\\u%4.4lX", letter );
fmt_text += buff; fmt_text += buff;
} }
} }
@ -221,7 +221,7 @@ double GERBER_JOBFILE_WRITER::mapValue( double aUiValue )
// i.e. displays values truncated in 0.1 microns. // i.e. displays values truncated in 0.1 microns.
// This is enough for a Json file // This is enough for a Json file
char buffer[128]; char buffer[128];
sprintf( buffer, "%.4f", aUiValue * m_conversionUnits );
std::snprintf( buffer, sizeof( buffer ), "%.4f", aUiValue * m_conversionUnits );
long double output; long double output;
sscanf( buffer, "%Lg", &output ); sscanf( buffer, "%Lg", &output );

10
pcbnew/files.cpp

@ -57,6 +57,7 @@
#include <plugins/cadstar/cadstar_pcb_archive_plugin.h> #include <plugins/cadstar/cadstar_pcb_archive_plugin.h>
#include <plugins/kicad/pcb_plugin.h> #include <plugins/kicad/pcb_plugin.h>
#include <dialogs/dialog_imported_layers.h> #include <dialogs/dialog_imported_layers.h>
#include <string>
#include <tools/pcb_actions.h> #include <tools/pcb_actions.h>
#include "footprint_info_impl.h" #include "footprint_info_impl.h"
#include "board_commit.h" #include "board_commit.h"
@ -712,15 +713,10 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
try try
{ {
STRING_UTF8_MAP props; STRING_UTF8_MAP props;
char xbuf[30];
char ybuf[30];
// EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet. // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet.
snprintf( xbuf, sizeof(xbuf), "%d", GetPageSizeIU().x );
snprintf( ybuf, sizeof(ybuf), "%d", GetPageSizeIU().y );
props["page_width"] = xbuf;
props["page_height"] = ybuf;
props["page_width"] = std::to_string( GetPageSizeIU().x );
props["page_height"] = std::to_string( GetPageSizeIU().y );
pi->SetQueryUserCallback( pi->SetQueryUserCallback(
[&]( wxString aTitle, int aIcon, wxString aMessage, wxString aAction ) -> bool [&]( wxString aTitle, int aIcon, wxString aMessage, wxString aAction ) -> bool

8
pcbnew/specctra_import_export/specctra.h

@ -2032,13 +2032,7 @@ public:
{ {
if( m_duplicated ) if( m_duplicated )
{ {
char buf[32];
std::string ret = m_image_id;
ret += "::";
sprintf( buf, "%d", m_duplicated );
ret += buf;
return ret;
return m_image_id + "::" + std::to_string( m_duplicated );
} }
return m_image_id; return m_image_id;

30
pcbnew/specctra_import_export/specctra_export.cpp

@ -300,7 +300,7 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, PAD* aPad )
dsnOffset = mapPt( offset ); dsnOffset = mapPt( offset );
// using () would cause padstack name to be quoted, and {} locks freerouter, so use []. // using () would cause padstack name to be quoted, and {} locks freerouter, so use [].
sprintf( offsetTxt, "[%.6g,%.6g]", dsnOffset.x, dsnOffset.y );
std::snprintf( offsetTxt, sizeof( offsetTxt ), "[%.6g,%.6g]", dsnOffset.x, dsnOffset.y );
uniqifier += offsetTxt; uniqifier += offsetTxt;
} }
@ -682,12 +682,10 @@ IMAGE* SPECCTRA_DB::makeIMAGE( BOARD* aBoard, FOOTPRINT* aFootprint )
} }
else // pad name is a duplicate within this footprint else // pad name is a duplicate within this footprint
{ {
char buf[32];
int duplicates = ++pinmap[ padNumber ]; int duplicates = ++pinmap[ padNumber ];
sprintf( buf, "@%d", duplicates );
pin->m_pin_id += buf; // append "@1" or "@2", etc. to pin name
pin->m_pin_id +=
"@" + std::to_string( duplicates ); // append "@1" or "@2", etc. to pin name
} }
pin->m_kiNetCode = pad->GetNetCode(); pin->m_kiNetCode = pad->GetNetCode();
@ -1157,9 +1155,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
layer->properties.push_back( PROPERTY() ); layer->properties.push_back( PROPERTY() );
PROPERTY* property = &layer->properties.back(); PROPERTY* property = &layer->properties.back();
property->name = "index"; property->name = "index";
char temp[32];
sprintf( temp, "%d", pcbNdx );
property->value = temp;
property->value = std::to_string( pcbNdx );
} }
} }
@ -1195,10 +1191,10 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
STRINGS& rules = m_pcb->m_structure->m_rules->m_rules; STRINGS& rules = m_pcb->m_structure->m_rules->m_rules;
sprintf( rule, "(width %.6g)", scale( defaultTrackWidth ) );
std::snprintf( rule, sizeof( rule ), "(width %.6g)", scale( defaultTrackWidth ) );
rules.push_back( rule ); rules.push_back( rule );
sprintf( rule, "(clearance %.6g)", clearance + safetyMargin );
std::snprintf( rule, sizeof( rule ), "(clearance %.6g)", clearance + safetyMargin );
rules.push_back( rule ); rules.push_back( rule );
// On a high density board (4 mil tracks, 4 mil spacing) a typical solder mask clearance // On a high density board (4 mil tracks, 4 mil spacing) a typical solder mask clearance
@ -1212,7 +1208,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
if( default_smd <= 6.0 ) if( default_smd <= 6.0 )
default_smd = 6.0; default_smd = 6.0;
sprintf( rule, "(clearance %.6g (type default_smd))", default_smd );
std::snprintf( rule, sizeof( rule ), "(clearance %.6g (type default_smd))", default_smd );
rules.push_back( rule ); rules.push_back( rule );
@ -1221,7 +1217,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
// clearance to freerouter. // clearance to freerouter.
clearance = scale( defaultClearance ) / 4; clearance = scale( defaultClearance ) / 4;
sprintf( rule, "(clearance %.6g (type smd_smd))", clearance );
std::snprintf( rule, sizeof( rule ), "(clearance %.6g (type smd_smd))", clearance );
rules.push_back( rule ); rules.push_back( rule );
} }
@ -1262,14 +1258,12 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
if( plane->m_name.size() == 0 ) if( plane->m_name.size() == 0 )
{ {
char name[32];
// This is one of those no connection zones, netcode=0, and it has no name. // This is one of those no connection zones, netcode=0, and it has no name.
// Create a unique, bogus netname. // Create a unique, bogus netname.
NET* no_net = new NET( m_pcb->m_network ); NET* no_net = new NET( m_pcb->m_network );
sprintf( name, "@:no_net_%d", netlessZones++ );
no_net->m_net_id = name;
no_net->m_net_id = "@:no_net_" + std::to_string( netlessZones++ );
// add the bogus net name to network->nets. // add the bogus net name to network->nets.
m_pcb->m_network->m_nets.push_back( no_net ); m_pcb->m_network->m_nets.push_back( no_net );
@ -1785,12 +1779,12 @@ void SPECCTRA_DB::exportNETCLASS( const std::shared_ptr<NETCLASS>& aNetClass, BO
// output the track width. // output the track width.
int trackWidth = aNetClass->GetTrackWidth(); int trackWidth = aNetClass->GetTrackWidth();
sprintf( text, "(width %.6g)", scale( trackWidth ) );
std::snprintf( text, sizeof( text ), "(width %.6g)", scale( trackWidth ) );
clazz->m_rules->m_rules.push_back( text ); clazz->m_rules->m_rules.push_back( text );
// output the clearance. // output the clearance.
int clearance = aNetClass->GetClearance(); int clearance = aNetClass->GetClearance();
sprintf( text, "(clearance %.6g)", scale( clearance ) + safetyMargin );
std::snprintf( text, sizeof( text ), "(clearance %.6g)", scale( clearance ) + safetyMargin );
clazz->m_rules->m_rules.push_back( text ); clazz->m_rules->m_rules.push_back( text );
if( aNetClass->GetName() == NETCLASS::Default ) if( aNetClass->GetName() == NETCLASS::Default )

9
pcbnew/tools/pcb_control.cpp

@ -54,6 +54,7 @@
#include <pcb_painter.h> #include <pcb_painter.h>
#include <string_utf8_map.h> #include <string_utf8_map.h>
#include <settings/color_settings.h> #include <settings/color_settings.h>
#include <string>
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
#include <footprint_edit_frame.h> #include <footprint_edit_frame.h>
#include <widgets/wx_progress_reporters.h> #include <widgets/wx_progress_reporters.h>
@ -1208,15 +1209,11 @@ int PCB_CONTROL::AppendBoard( PLUGIN& pi, wxString& fileName )
try try
{ {
STRING_UTF8_MAP props; STRING_UTF8_MAP props;
char xbuf[30];
char ybuf[30];
// EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet. // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet.
snprintf( xbuf, sizeof(xbuf), "%d", editFrame->GetPageSizeIU().x );
snprintf( ybuf, sizeof(ybuf), "%d", editFrame->GetPageSizeIU().y );
props["page_width"] = xbuf;
props["page_height"] = ybuf;
props["page_width"] = std::to_string( editFrame->GetPageSizeIU().x );
props["page_height"] = std::to_string( editFrame->GetPageSizeIU().y );
pi.SetQueryUserCallback( pi.SetQueryUserCallback(
[&]( wxString aTitle, int aIcon, wxString aMessage, wxString aAction ) -> bool [&]( wxString aTitle, int aIcon, wxString aMessage, wxString aAction ) -> bool

5
qa/tools/pns/label_manager.cpp

@ -24,6 +24,7 @@
#include <gal/graphics_abstraction_layer.h> #include <gal/graphics_abstraction_layer.h>
#include <gal/color4d.h> #include <gal/color4d.h>
#include <view/view_overlay.h> #include <view/view_overlay.h>
#include <string>
#include "label_manager.h" #include "label_manager.h"
@ -65,9 +66,7 @@ void LABEL_MANAGER::Add( const SHAPE_LINE_CHAIN& aL, COLOR4D color )
{ {
for( int i = 0; i < aL.PointCount(); i++ ) for( int i = 0; i < aL.PointCount(); i++ )
{ {
char msg[1024];
snprintf( msg, sizeof( msg ), "%d", i );
Add( aL.CPoint( i ), msg, color );
Add( aL.CPoint( i ), std::to_string( i ), color );
} }
} }

13
qa/tools/pns/pns_log_viewer_frame.cpp

@ -24,6 +24,7 @@
// WARNING - this Tom's crappy PNS hack tool code. Please don't complain about its quality // WARNING - this Tom's crappy PNS hack tool code. Please don't complain about its quality
// (unless you want to improve it). // (unless you want to improve it).
#include <string>
#include <wx/clipbrd.h> #include <wx/clipbrd.h>
#include <pgm_base.h> #include <pgm_base.h>
@ -403,9 +404,7 @@ void PNS_LOG_VIEWER_FRAME::onRewindScroll( wxScrollEvent& event )
drawLoggedItems( m_rewindIter ); drawLoggedItems( m_rewindIter );
updateDumpPanel( m_rewindIter ); updateDumpPanel( m_rewindIter );
updatePnsPreviewItems( m_rewindIter ); updatePnsPreviewItems( m_rewindIter );
char str[128];
sprintf( str, "%d", m_rewindIter );
m_rewindPos->SetValue( str );
m_rewindPos->SetValue( std::to_string( m_rewindIter ) );
event.Skip(); event.Skip();
} }
@ -418,9 +417,7 @@ void PNS_LOG_VIEWER_FRAME::onBtnRewindLeft( wxCommandEvent& event )
drawLoggedItems( m_rewindIter ); drawLoggedItems( m_rewindIter );
updateDumpPanel( m_rewindIter ); updateDumpPanel( m_rewindIter );
updatePnsPreviewItems( m_rewindIter ); updatePnsPreviewItems( m_rewindIter );
char str[128];
sprintf( str, "%d", m_rewindIter );
m_rewindPos->SetValue( str );
m_rewindPos->SetValue( std::to_string( m_rewindIter ) );
} }
} }
@ -436,9 +433,7 @@ void PNS_LOG_VIEWER_FRAME::onBtnRewindRight( wxCommandEvent& event )
drawLoggedItems( m_rewindIter ); drawLoggedItems( m_rewindIter );
updateDumpPanel( m_rewindIter ); updateDumpPanel( m_rewindIter );
updatePnsPreviewItems( m_rewindIter ); updatePnsPreviewItems( m_rewindIter );
char str[128];
sprintf( str, "%d", m_rewindIter );
m_rewindPos->SetValue( str );
m_rewindPos->SetValue( std::to_string( m_rewindIter ) );
} }
} }

7
scripting/python_scripting.cpp

@ -32,7 +32,7 @@
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <Python.h> #include <Python.h>
#include <sstream>
#include <string>
#include <eda_base_frame.h> #include <eda_base_frame.h>
#include <gal/color4d.h> #include <gal/color4d.h>
@ -347,12 +347,11 @@ static void RunPythonMethodWithReturnedString( const char* aMethodName, wxString
Py_DECREF( builtins ); Py_DECREF( builtins );
// Build the python code // Build the python code
char cmd[1024];
snprintf( cmd, sizeof(cmd), "result = %s()", aMethodName );
std::string cmd = "result = " + std::string( aMethodName ) + "()";
// Execute the python code and get the returned data // Execute the python code and get the returned data
PyObject* localDict = PyDict_New(); PyObject* localDict = PyDict_New();
PyObject* pobj = PyRun_String( cmd, Py_file_input, globals, localDict);
PyObject* pobj = PyRun_String( cmd.c_str(), Py_file_input, globals, localDict );
Py_DECREF( globals ); Py_DECREF( globals );
if( pobj ) if( pobj )

Loading…
Cancel
Save