Topics

fldigi 4.1.14.65 posted


Dave
 

at http://www.w1hkj.com/alpha/fldigi/

  1. Added FMT unknown/reference reset buttons. (see FMTusage)
  2. Changed tracking check box to tracking button for both unknown and reference
  3. Changed order of FMT main dialog controls

73, David, W1HKJ


Peter Loeffler
 

dave, is there a special reason why you don't answer my email ?

--
Disclaimer: May be opened and read by the NSA, CIA, GCHQ, KGB, BND, and whoever else it may NOT concern.


Am Di., 6. Okt. 2020 um 02:46 Uhr schrieb Dave <w1hkj@...>:

at http://www.w1hkj.com/alpha/fldigi/

  1. Added FMT unknown/reference reset buttons. (see FMTusage)
  2. Changed tracking check box to tracking button for both unknown and reference
  3. Changed order of FMT main dialog controls

73, David, W1HKJ


Dave
 

My apologies Peter,

I tagged your email as important and then it slipped above an ensuing 400 emails that followed yours.  Monitoring emails from >10,000 users sometimes produces a large number of needed responses.

The man page for sprintf, the function call for printing the double xmlrpc value states:

       For some numeric conversions a radix character ("decimal point")  or  thousands'  grouping
       character  is  used.   The  actual  character  used  depends on the LC_NUMERIC part of the
       locale.  (See setlocale(3).)  The POSIX locale uses '.' as radix character, and  does  not
       have a grouping character.  Thus,

               printf("%'.2f", 1234567.89);

       results  in  "1234567.89" in the POSIX locale, in "1234567,89" in the nl_NL locale, and in
       "1.234.567,89" in the da_DK locale.

Which tells me that your suggested change will not produce the double string with the period as the decimal separator.  Am I correct in assuming that your locale is set to "de_DE.UTF-8 UTF-8"

You would have to change these two functions in the file XmlRpcValue.cpp

  // Double
  bool XmlRpcValue::doubleFromXml(std::string const& valueXml, int* offset)
  {
    const char* valueStart = valueXml.c_str() + *offset;
    char* valueEnd;

    std::string mylocale = std::setlocale(LC_NUMERIC, NULL);
    std::setlocale(LC_NUMERIC, "en_US.UTF-8");   // decimal dot will be US preference, period

    double dvalue = strtod(valueStart, &valueEnd);
    if (valueEnd == valueStart)
      return false;

    _type = TypeDouble;
    _value.asDouble = dvalue;
    *offset += int(valueEnd - valueStart);

    std::setlocale(LC_NUMERIC, mylocale.c_str());   // restore users preferred LC_NUMERIC locale

    return true;
  }

  std::string XmlRpcValue::doubleToXml() const
  {
    char fmtbuf[256], buf[256];
    snprintf(fmtbuf, sizeof(fmtbuf)-1, "<value><double>%s</double></value>", getDoubleFormat().c_str());
    fmtbuf[sizeof(fmtbuf)-1] = 0;

    std::string mylocale = std::setlocale(LC_NUMERIC, NULL);
    std::setlocale(LC_NUMERIC, "en_US.UTF-8");   // decimal dot will be US preference, period

    snprintf(buf, sizeof(buf)-1, fmtbuf, _value.asDouble);

    buf[sizeof(buf)-1] = 0;

    std::setlocale(LC_NUMERIC, mylocale.c_str());   // restore users preferred LC_NUMERIC locale

    return std::string(buf);
  }

to change all the decimal separator to period independent of the users locale.

Please let me know if you test this change, and whether or not it produces the desired result.

73, David, W1HKJ


On 10/7/20 7:13 AM, Peter Loeffler wrote:
dave, is there a special reason why you don't answer my email ?


Dave
 

Peter,

My suggested change to XmlRpcValue.cpp may have to be modified based on further testing on my development system.

Try this on your system:

#include <iostream>
#include <locale.h>
#include <locale>
#include <string>

int main()
{
    std::locale user_locale("");         // get global locale
    std::cout.imbue(user_locale);        // imbue global locale

    std::cout << "User-preferred locale setting is " << user_locale.name().c_str() << std::endl;
    std::cout << "std::cout: " << 12233.4455 << std::endl;
    printf("printf: %f\n", 12233.4455);

    // replace the C++ global locale as well as the C locale with the user-preferred locale
    std::locale::global(std::locale("de_DE.UTF-8"));   // should be "en_US.UTF-8" for your tests

    // use the new global locale for future wide character output
    std::cout.imbue(std::locale());

    // output the same number again
    std::cout << "New locale setting is " << std::locale().name().c_str() << std::endl;
    std::cout << "std::cout: " << 12233.4455 << std::endl;
    printf("printf: %f\n", 12233.4455);

    // restore user_locale
    std::locale::global(user_locale);
    std::cout.imbue(std::locale());

    std::cout << "restored user preferred locale setting" << std::endl;
    std::cout << "std::cout: " << 12233.4455 << std::endl;
    printf("printf: %f\n", 12233.4455);
}

My results:

[dave]$ g++ locale_test.cxx -o locale_test
[dave]$ ./locale_test
User-preferred locale setting is en_US.UTF-8
std::cout: 12,233.4
printf: 12233.445500
New locale setting is de_DE.UTF-8
std::cout: 12.233,4
printf: 12233,445500
restored user preferred locale setting
std::cout: 12,233.4
printf: 12233.445500

73, David, W1HKJ



Dave
 

A more extensive test illustrating the difference between the C style printf and C++ std::cout / std::wcout functions:
#include <iostream>
#include <locale.h>
#include <locale>
#include <string>

int main()
{
    {
        std::cout << "----------------------" << std::endl;
        std::cout << "std::cout numeric format tests" << std::endl;

        std::locale user_locale("");        // get global locale
        std::cout << "User-preferred locale setting is " << user_locale.name().c_str() << std::endl;
        std::cout.imbue(user_locale);        // imbue global locale
        std::cout << "std::cout: " << 12233.4455 << std::endl;

    // replace the C++ global locale as well as the C locale with the user-preferred locale
        std::locale::global(std::locale("de_DE.UTF-8"));
        std::cout << "New locale setting is " << std::locale().name().c_str() << std::endl;
        std::cout.imbue(std::locale());
        std::cout << "std::cout: " << 12233.4455 << std::endl;

    // restore user_locale
        std::locale::global(user_locale);
        std::cout << "restored user preferred locale setting" << std::endl;
        std::cout.imbue(std::locale());
        std::cout << "std::cout: " << 12233.4455 << std::endl;
        std::cout << "----------------------" << std::endl;
    }

    {
        printf("printf numeric format tests\n");
        std::locale user_locale("");        // get global locale
        printf("User-preferred locale setting is %s\n", user_locale.name().c_str());
        printf("%f\n", 12233.4455);

    // replace the C++ global locale as well as the C locale with the user-preferred locale
        std::locale::global(std::locale("de_DE.UTF-8"));
        printf("New locale setting is %s\n", std::locale().name().c_str());
        printf("%f\n", 12233.4455);

    // restore user_locale
        std::locale::global(user_locale);
        printf("restored user preferred locale setting\n");
        printf("%f\n", 12233.4455);
        printf("----------------------\n");
    }
}

73, David