[Top][All Lists]
[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>