Commit 4b596cc5 authored by Dick Hollenbeck's avatar Dick Hollenbeck
Browse files

legacy_plugin was not round tripping nanometers, add test program to verify new conversion strategy

parent 3a8bf14c
Loading
Loading
Loading
Loading
+28 −26
Original line number Original line Diff line number Diff line
@@ -2563,15 +2563,19 @@ void LEGACY_PLUGIN::loadPCB_TARGET()
}
}




#define SPBUFZ  50      // wire all usages of this together.

int LEGACY_PLUGIN::biuSprintf( char* buf, BIU aValue ) const
int LEGACY_PLUGIN::biuSprintf( char* buf, BIU aValue ) const
{
{
    double  engUnits = biuToDisk * aValue;
    long double engUnits = biuToDisk * aValue;
    int         len;
    int         len;


    if( engUnits != 0.0 && fabs( engUnits ) <= 0.0001 )
    if( engUnits != 0.0 && fabsl( engUnits ) <= 0.0001 )
    {
    {
        // printf( "f: " );
        // Windows printf and sprintf do not support long double, but MinGW replaces
        len = sprintf( buf, "%.10f", engUnits );
        // snprintf and vsnprintf only with versions that do.
        // http://gcc.gnu.org/ml/libstdc++/2008-02/msg00081.html
        len = snprintf( buf, SPBUFZ, "%.10Lf", engUnits );


        while( --len > 0 && buf[len] == '0' )
        while( --len > 0 && buf[len] == '0' )
            buf[len] = '\0';
            buf[len] = '\0';
@@ -2580,8 +2584,9 @@ int LEGACY_PLUGIN::biuSprintf( char* buf, BIU aValue ) const
    }
    }
    else
    else
    {
    {
        // printf( "g: " );
        // Windows printf and sprintf do not support long double, but MinGW replaces
        len = sprintf( buf, "%.10g", engUnits );
        // snprintf and vsnprintf only with versions that do.
        len = snprintf( buf, SPBUFZ, "%.10Lg", engUnits );
    }
    }
    return len;
    return len;
}
}
@@ -2589,7 +2594,7 @@ int LEGACY_PLUGIN::biuSprintf( char* buf, BIU aValue ) const


std::string LEGACY_PLUGIN::fmtBIU( BIU aValue ) const
std::string LEGACY_PLUGIN::fmtBIU( BIU aValue ) const
{
{
    char    temp[50];
    char    temp[SPBUFZ];


    int len = biuSprintf( temp, aValue );
    int len = biuSprintf( temp, aValue );


@@ -2603,7 +2608,8 @@ std::string LEGACY_PLUGIN::fmtDEG( double aAngle ) const


    // @todo a hook site to convert from tenths degrees to degrees for BOARD_FORMAT_VERSION 2.
    // @todo a hook site to convert from tenths degrees to degrees for BOARD_FORMAT_VERSION 2.


    int len = sprintf( temp, "%.10g", aAngle );
    // MINGW: snprintf() comes from gcc folks, sprintf() comes from Microsoft.
    int len = snprintf( temp, sizeof( temp ), "%.10g", aAngle );


    return std::string( temp, len );
    return std::string( temp, len );
}
}
@@ -2611,7 +2617,7 @@ std::string LEGACY_PLUGIN::fmtDEG( double aAngle ) const


std::string LEGACY_PLUGIN::fmtBIUPair( BIU first, BIU second ) const
std::string LEGACY_PLUGIN::fmtBIUPair( BIU first, BIU second ) const
{
{
    char    temp[100];
    char    temp[2*SPBUFZ+2];
    char*   cp = temp;
    char*   cp = temp;


    cp += biuSprintf( cp, first );
    cp += biuSprintf( cp, first );
@@ -2630,7 +2636,12 @@ BIU LEGACY_PLUGIN::biuParse( const char* aValue, const char** nptrptr )


    errno = 0;
    errno = 0;


    double fval = strtod( aValue, &nptr );
    // The strategy in this function, which utilizes "long double" was verified using
    // tools/test-nm-biu-to-ascii-mm-round-tripping.cpp.  For it to work "long double" must
    // have more precision than double.  gcc has this, and its all we care about.

    // MINGW does have a working strtold()
    long double fval = strtold( aValue, &nptr );


    if( errno )
    if( errno )
    {
    {
@@ -2651,20 +2662,11 @@ BIU LEGACY_PLUGIN::biuParse( const char* aValue, const char** nptrptr )
    if( nptrptr )
    if( nptrptr )
        *nptrptr = nptr;
        *nptrptr = nptr;


#if defined(DEBUG)
    fval *= diskToBiu;

    if( diskToBiu == 10000/25.4 )
    {
        // this is the special reverse trip mm -> deci-mils testing run,
        // only available in DEBUG mode.
        return BIU( KiROUND( fval * diskToBiu ) );
    }

#endif


    // There should be no rounding issues here, since the values in the file initially
    // fval is up into the whole number realm here, and should be bounded
    // came from integers via biuFmt(). In fact this product should be an integer, exactly.
    // within INT_MIN to INT_MAX since BIU's are nanometers.
    return BIU( fval * diskToBiu );
    return BIU( KiROUND( double( fval ) ) );
}
}




@@ -2706,9 +2708,9 @@ void LEGACY_PLUGIN::init( PROPERTIES* aProperties )


    // conversion factor for saving RAM BIUs to KICAD legacy file format.
    // conversion factor for saving RAM BIUs to KICAD legacy file format.
#if defined( USE_PCBNEW_NANOMETRES )
#if defined( USE_PCBNEW_NANOMETRES )
    biuToDisk = 1/IU_PER_MM;        // BIUs are nanometers & file is mm
    biuToDisk = 1.0L/IU_PER_MM;     // BIUs are nanometers & file is mm
#else
#else
    biuToDisk = 1.0;                // BIUs are deci-mils
    biuToDisk = 1.0L;               // BIUs are deci-mils
#endif
#endif


    // conversion factor for loading KICAD legacy file format into BIUs in RAM
    // conversion factor for loading KICAD legacy file format into BIUs in RAM
+7 −2
Original line number Original line Diff line number Diff line
@@ -130,8 +130,13 @@ protected:
    /// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
    /// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
    void    init( PROPERTIES* aProperties );
    void    init( PROPERTIES* aProperties );


    double  biuToDisk;      ///< convert from BIUs to disk engineering units with this scale factor
    // Use of long double might affect MSVC++'s ability to make KiCad.
    double  diskToBiu;      ///< convert from disk engineering units to BIUs with this scale factor

    long double  biuToDisk;         ///< convert from BIUs to disk engineering units
                                    ///< with this scale factor

    long double  diskToBiu;         ///< convert from disk engineering units to BIUs
                                    ///< with this scale factor


    /**
    /**
     * Function biuParse
     * Function biuParse
+4 −0
Original line number Original line Diff line number Diff line
@@ -60,6 +60,10 @@ target_link_libraries( container_test
    ${wxWidgets_LIBRARIES}
    ${wxWidgets_LIBRARIES}
    )
    )


add_executable( test-nm-biu-to-ascii-mm-round-tripping
    EXCLUDE_FROM_ALL
    test-nm-biu-to-ascii-mm-round-tripping.cpp
    )


add_executable( parser_gen
add_executable( parser_gen
    EXCLUDE_FROM_ALL
    EXCLUDE_FROM_ALL