help-libidn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: unistd.h include in stringprep.h


From: Bruno Haible
Subject: Re: unistd.h include in stringprep.h
Date: Sun, 27 Nov 2011 02:27:58 +0100
User-agent: KMail/1.13.6 (Linux/2.6.37.6-0.5-desktop; KDE/4.6.0; x86_64; ; )

Hi Simon,

> > * mingw with MSVC 9 as compiler
> >
> > Compilation failure:
> >
> > make[3]: Entering directory 
> > `/home/bruno/multibuild-1530/msvc9/libidn-1.23/lib'
> >   CC     nfkc.lo
> > nfkc.c
> > c:\cygwin\home\bruno\multibuild-1530\msvc9\libidn-1.23\lib\stringprep.h(39) 
> > : fatal error C1083: include file cannot be opened: "unistd.h": No such 
> > file or directory
> >
> > The following copies of unistd.h exist:
> >
> >    gl/unistd.h
> >    win32/include/unistd.h
> >
> > You should probably include the 'unistd' module if you want to #include 
> > <unistd.h>
> > unconditionally. Or add an option -I../gl .
> 
> The #include happens in an installed header file, so the gnulib module
> wouldn't help here.

Oh, I see. A file that contains public API of libidn.

> However, the only reason we include unistd.h is in order to get ssize_t.

ssize_t on MSVC 9 was handled in
<http://lists.gnu.org/archive/html/bug-gnulib/2011-09/msg00200.html>.

In summary, to get ssize_t defined, you need the 'ssize_t' module or
- equivalent - an invocation of gt_TYPE_SSIZE_T.

> GnuTLS generates its header files that contains this:
> 
> /* Get ssize_t. */
> #ifndef HAVE_SSIZE_T
> #define HAVE_SSIZE_T
> /* *INDENT-OFF* */
> @DEFINE_SSIZE_T@
> /* *INDENT-ON* */
> #endif
> 
> and then have a configure.ac check looking like this:
> 
> AC_CHECK_TYPE(ssize_t,
>   [
>     DEFINE_SSIZE_T="#include <sys/types.h>"
>     AC_SUBST(DEFINE_SSIZE_T)
>   ], [
>     AC_DEFINE([NO_SSIZE_T], 1, [no ssize_t type was found])
>     DEFINE_SSIZE_T="typedef int ssize_t;"
>     AC_SUBST(DEFINE_SSIZE_T)
>   ], [
>     #include <sys/types.h>
>   ])

It is not safe to define a type like 'ssize_t' in a public header file
of your library, because it will conflict with packages that want to
define ssize_t for their internal purpose.

The public API that uses ssize_t is:

  extern IDNAPI uint32_t *stringprep_utf8_to_ucs4 (const char *str,
                                                   ssize_t len,
                                                   size_t * items_written);
  extern IDNAPI char *stringprep_ucs4_to_utf8 (const uint32_t * str,
                                               ssize_t len,
                                               size_t * items_read,
                                               size_t * items_written);
  extern IDNAPI char *stringprep_utf8_nfkc_normalize (const char *str,
                                                      ssize_t len);
  extern IDNAPI uint32_t *stringprep_ucs4_nfkc_normalize (uint32_t * str,
                                                          ssize_t len);

Note that ssize_t values are only passed by value, not through pointers.
Therefore it's easy. I see two possible solutions:

  1) Use size_t instead of ssize_t. This is backward compatible at the
     source code level, except for uses of the 4 functions via function
     pointers, and is also backward compatible at the ABI level.

  2) Use 'long' instead of ssize_t. This is backward compatible at the
     source code level, except for uses of the 4 functions via function
     pointers. For ABI level backward compatibility you need to use
     versioning (such as
       #define stringprep_utf8_to_ucs4 stringprep_utf8_to_ucs4_v2
     and a .c file that provides a definition of
       stringprep_utf8_to_ucs4
     followed by
       #undef stringprep_utf8_to_ucs4
     and a definition of stringprep_utf8_to_ucs4; similarly for the other
     functions).

Bruno
-- 
In memoriam Gavriel Holtzberg <http://en.wikipedia.org/wiki/Gavriel_Holtzberg>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]