[libcxx]handling missing linux implementations

Hi Larry,

Perhaps that a #warning along the return NULL would be sufficient ?

It seems to me that the user should definitely take care not to use (even if the result is “coherent”) until it’s properly implemented.

Matthieu.

Hi Larry,

Perhaps that a `#warning` along the return NULL would be sufficient?

Yes. That's better than '#pragma message ...'

It seems to me that the user should definitely take care not to use
(even if the result is "coherent") until it's properly implemented.

Matthieu.

[snip]
Mybe a proper implementation could be done using the 'uselocale'
described on p. 131 of:

  http://people.redhat.com/drepper/tllocale.ps.gz

(Thanks to Marc Glisse for suggesting uselocale here:

  http://llvm.org/bugs/show_bug.cgi?id=8992#c11

)

Uselocale could be used something like in the following code:

  #ifdef __linux__
    namespace std
    {
        size_t
      wcrtomb_l
        ( char* et
        , wchar_t it
        , mbstate_t* ps
        , locale_t locale_new
        )
        {
          locale_t locale_old uselocale(locale_new);
          wcrtomb(et,it,st);
          uselocale(locale_old);
        }
    }
  #endif

The above could be inserted just after the #include's in:

http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/locale.cpp?annotate=121510

Some similar could be done for other "missing _l suffixed functions".

Anyone have any alternatives to this solution to the missing _l
suffixed functions on linus (or really, in glibc)?

-regards,
Larry

I think this is a really promising direction. What we need to know now is: How available is uselocale on the platforms that this audience wants to port libc++ to? Does just Ubuntu have it? Other linux platforms? Windows?

The next question, assuming (at least Ubuntu-interested) people are happy with this approach, is where to implement missing functionality such as wcrtomb_l? It could go in the <locale> header as an inlined function. It could go in libc++'s locale.cpp source. Or it could go in the C library (for example) on the Ubuntu platform (thus being available to clients other than libc++).

Personally I'm only looking after the Darwin (Apple) implementation which already has wcrtomb_l et. al. and doesn't need this work. But I am very interested in getting this discussion started among those seeking to port libc++ to platforms other than Apple.

-Howard

Mybe a proper implementation could be done using the 'uselocale'
described on p. 131 of:

http://people.redhat.com/drepper/tllocale.ps.gz

(Thanks to Marc Glisse for suggesting uselocale here:

http://llvm.org/bugs/show_bug.cgi?id=8992#c11

)

Uselocale could be used something like in the following code:

#ifdef __linux__
   namespace std
   {
       size_t
     wcrtomb_l
       ( char* et
       , wchar_t it
       , mbstate_t* ps
       , locale_t locale_new
       )
       {
         locale_t locale_old uselocale(locale_new);
         wcrtomb(et,it,st);
         uselocale(locale_old);
       }
   }
#endif

The above could be inserted just after the #include's in:

http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/locale.cpp?annotate=121510

Some similar could be done for other "missing _l suffixed functions".

Anyone have any alternatives to this solution to the missing _l
suffixed functions on linus (or really, in glibc)?

I think this is a really promising direction. What we need to know
now is: How available is uselocale on the platforms that this
audience wants to port libc++ to? Does just Ubuntu have it? Other
linux platforms? Windows?

What about handling other platforms by inserting:

#ifndef __APPLE__
//Purpose:
// Provide functions whose name is suffixed with _l
// and which have locale_t as last argument, but
// which are missing on ubuntu (and presumably other
// unix type OS's).
//Method:
// Use uselocale to temporarlity change the current
// threads locale to the last argument, then
// perform the operation with the abbreviated function
// (i.e. same name except without _l suffix), and then
// restore the locale to previous value.
//

#if defined(__GLIBC__)
  #if __GLIBC__ > 1 && __GLIBC_MINOR__ > 2
    //From page 141 of http://people.redhat.com/drepper/tllocale.ps.gz:
    // Starting with glibc 2.3 everyting will be available
    //So, indicate that uselocale is available in glibc:
    #define _LIBCPP_HAS_USELOCALE
  #endif
#endif

  size_t
wcrtomb_l
  ( char* et
  , wchar_t it
  , mbstate_t* ps
  , locale_t locale_new
  )
  {
  #if defined(__LIBCPP_HAS_USELOCALE)
    locale_t locale_old=uselocale(locale_new);
  #endif
    size_t result=wcrtomb(et,it,ps);
  #ifdef defined(__LIBCPP_HAS_USELOCALE)
    uselocale(locale_old);
  #else
    #warning "wcrtomb_l improperly implemented for this config."
  #endif
    return result;
  }

#endif

just after the anonymous namespace open curly braces in locale.cpp
(IOW, just after line 26 of:

http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/locale.cpp?annotate=121510
)?

The #if __GLIB_* test would assure it would work for any platform
using glibc. For windows, since _LIBCPP_HAS_USELOCALE would be
undefined, the #warning would occur, but the result would be no worse
than the current implementation and the user would be notified of a
possible problem (thanks to Matthieu for this suggestion).

[snip]

-Larry

The Microsoft CRT has _l versions of most functions, but prefixed with another underscore (so, for example, _wctomb_l), so there should be no need for uselocale. Which it doesn't have.

Sebastian

My last post had a solution for linux for the wcrtomb_l function which
might work for the Microsoft compiler if it were changed as shown
below. If it does work for the Microsoft compiler it could be
mimicked for the other missing functions.

#ifndef __APPLE__
//Purpose:
// Provide functions whose name is suffixed with _l
// and which have locale_t as last argument, but
// which are missing om tje glibc library and have
// a different name in MS visualc++ library.
//Method:
// Use uselocale to temporarlity change the current
// threads locale to the last argument, then
// perform the operation with the abbreviated function
// (i.e. same name except without _l suffix), and then
// restore the locale to previous value.
//

#if defined(__GLIBC__)
  #if( __GLIBC__ > 1) && (__GLIBC_MINOR__ > 2)
    //From page 141 of http://people.redhat.com/drepper/tllocale.ps.gz:
    // Starting with glibc 2.3 everyting will be available
    //So, indicate that uselocale is available in glibc:
    #define _LIBCPP_HAS_USELOCALE
  #endif
#elif defined(_MSC_FULL_VER)
  //Using Microsoft visualc++ compiler, which
  //uses _XXX_l for corresponding apple function, XXX_l.
  #define _LIBCPP_MSC_LEAD_UNDERSCORE
#endif

  size_t
wcrtomb_l
  ( char* et
  , wchar_t it
  , mbstate_t* ps
  , locale_t locale_new
  )
  {
  #if defined(_LIBCPP_MSC_LEAD_UNDERSCORE)
    return _wcrtomp_l(et,it,ps,locale_new)
  #else
    #if defined(_LIBCPP_HAS_USELOCALE)
      locale_t locale_old=uselocale(locale_new);
    #endif
      size_t result=wcrtomb(et,it,ps);
    #if defined(_LIBCPP_HAS_USELOCALE)
      uselocale(locale_old);
    #else
      #warning "wcrtomb_l improperly implemented for this config."
    #endif
      return result;
  #endif
  }

#endif