bug-gnulib
[Top][All Lists]
Advanced

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

Re: [bug-gnulib] wcwidth on mingw


From: Bruno Haible
Subject: Re: [bug-gnulib] wcwidth on mingw
Date: Wed, 28 Jun 2006 19:01:56 +0200
User-agent: KMail/1.9.1

Eric Blake wrote:
> By the way, is it safe to assume wchar_t exists

No it isn't. Good point. Either the module description should have

  #if HAVE_WCHAR_T
  # include "wcwidth.h"
  #endif

or wcwidth.h should protect against this case itself. The latter is
obviously better.

> Also, on mingw, where sizeof(wchar_t)==2 but
> sizeof(int)==4, a prototype of
> int wcwidth()
> is incompatible with a declaration of
> int wcwidth(wchar_t wc)
> because of promotion rules.

Yes, but that's not a reason for removing the declaration and not
testing HAVE_DECL_WCWIDTH any more.

If wchar_t is really only 16 bit, and if we write
  extern int wcwidth(wchar_t wc);
some compilers on some platforms might not zero/sign-extend the argument
when passing a 16-bit value. (I.e. they might pass garbage in the upper
16 bits of the argument word.) Whereas when we write
  extern int wcwidth(int wc);
we tell the compiler to do a zero/sign-extend. This is safer.

Further issues:
- In mbswidth.c you removed the includes of <wchar.h> and <wctype.h>.
  But they are needed for iswcntrl(). Things are more maintainable if
  you write down the includes, even if they are *currently* redundant,
  because when someone will change wcwidth.h in the future, he will
  certainly not look at recompiling mbswidth.c.
- When 'inline' is used, we must arrange to invoke AC_C_INLINE.

I fixed these, patch appended.

Bruno


diff -c -3 -r1.1 wcwidth.h
*** lib/wcwidth.h       28 Jun 2006 13:11:03 -0000      1.1
--- lib/wcwidth.h       28 Jun 2006 16:52:51 -0000
***************
*** 18,43 ****
  #ifndef _gl_WCWIDTH_H
  #define _gl_WCWIDTH_H
  
  /* Get wcwidth if available, along with wchar_t.  */
! #if HAVE_WCHAR_H
  /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
     <wchar.h>.
     BSD/OS 4.1 has a bug: <stdio.h> and <time.h> must be included before
     <wchar.h>.  */
! # include <stdio.h>
! # include <time.h>
! # include <wchar.h>
! #endif
  
  /* Get iswprint.  */
! #if HAVE_WCTYPE_H
! # include <wctype.h>
! #endif
! #if !defined iswprint && !HAVE_ISWPRINT
! # define iswprint(wc) 1
! #endif
  
! #if !defined wcwidth && !HAVE_WCWIDTH
  
  /* wcwidth doesn't exist, so assume all printable characters have
     width 1.  */
--- 18,49 ----
  #ifndef _gl_WCWIDTH_H
  #define _gl_WCWIDTH_H
  
+ #if HAVE_WCHAR_T
+ 
  /* Get wcwidth if available, along with wchar_t.  */
! # if HAVE_WCHAR_H
  /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
     <wchar.h>.
     BSD/OS 4.1 has a bug: <stdio.h> and <time.h> must be included before
     <wchar.h>.  */
! #  include <stdio.h>
! #  include <time.h>
! #  include <wchar.h>
! # endif
  
  /* Get iswprint.  */
! # if HAVE_WCTYPE_H
! #  include <wctype.h>
! # endif
! # if !defined iswprint && !HAVE_ISWPRINT
! #  define iswprint(wc) 1
! # endif
  
! # ifndef HAVE_DECL_WCWIDTH
! "this configure-time declaration test was not run"
! # endif
! # ifndef wcwidth
! #  if !HAVE_WCWIDTH
  
  /* wcwidth doesn't exist, so assume all printable characters have
     width 1.  */
***************
*** 47,52 ****
    return wc == 0 ? 0 : iswprint (wc) ? 1 : -1;
  }
  
! #endif
  
  #endif /* _gl_WCWIDTH_H */
--- 53,70 ----
    return wc == 0 ? 0 : iswprint (wc) ? 1 : -1;
  }
  
! #  elif !HAVE_DECL_WCWIDTH
! 
! /* wcwidth exists but is not declared.  */
! extern
! #   ifdef __cplusplus
! "C"
! #   endif
! int wcwidth (int /* actually wchar_t */);
! 
! #  endif
! # endif
! 
! #endif /* HAVE_WCHAR_H */
  
  #endif /* _gl_WCWIDTH_H */
diff -c -3 -r1.15 mbswidth.c
*** lib/mbswidth.c      28 Jun 2006 13:11:03 -0000      1.15
--- lib/mbswidth.c      28 Jun 2006 16:52:51 -0000
***************
*** 32,41 ****
  /* Get isprint().  */
  #include <ctype.h>
  
! /* Get mbstate_t, mbrtowc(), mbsinit(), wcwidth().  */
  #include "wcwidth.h"
  
  /* Get iswcntrl().  */
  #if !defined iswcntrl && !HAVE_ISWCNTRL
  # define iswcntrl(wc) 0
  #endif
--- 32,55 ----
  /* Get isprint().  */
  #include <ctype.h>
  
! /* Get mbstate_t, mbrtowc(), mbsinit().  */
! #if HAVE_WCHAR_H
! /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
!    <wchar.h>.
!    BSD/OS 4.1 has a bug: <stdio.h> and <time.h> must be included before
!    <wchar.h>.  */
! # include <stdio.h>
! # include <time.h>
! # include <wchar.h>
! #endif
! 
! /* Get wcwidth().  */
  #include "wcwidth.h"
  
  /* Get iswcntrl().  */
+ #if HAVE_WCTYPE_H
+ # include <wctype.h>
+ #endif
  #if !defined iswcntrl && !HAVE_ISWCNTRL
  # define iswcntrl(wc) 0
  #endif
diff -c -3 -r1.1 wcwidth.m4
*** m4/wcwidth.m4       28 Jun 2006 13:10:13 -0000      1.1
--- m4/wcwidth.m4       28 Jun 2006 16:52:52 -0000
***************
*** 1,17 ****
! # wcwidth.m4 serial 1
  dnl Copyright (C) 2006 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
  dnl with or without modifications, as long as this notice is preserved.
  
- dnl autoconf tests required for use of mbswidth.c
- 
  AC_DEFUN([gl_FUNC_WCWIDTH],
! [ AC_CHECK_HEADERS_ONCE([wchar.h wctype.h])
!   AC_CHECK_FUNCS_ONCE([iswprint wcwidth])
! 
    AC_REQUIRE([AC_GNU_SOURCE])
  
    AC_CACHE_CHECK([whether wcwidth is declared], [ac_cv_have_decl_wcwidth],
      [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
  /* AIX 3.2.5 declares wcwidth in <string.h>. */
--- 1,20 ----
! # wcwidth.m4 serial 2
  dnl Copyright (C) 2006 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
  dnl with or without modifications, as long as this notice is preserved.
  
  AC_DEFUN([gl_FUNC_WCWIDTH],
! [
!   dnl Persuade glibc <wchar.h> to declare wcwidth().
    AC_REQUIRE([AC_GNU_SOURCE])
  
+   AC_REQUIRE([AC_C_INLINE])
+   AC_REQUIRE([gt_TYPE_WCHAR_T])
+ 
+   AC_CHECK_HEADERS_ONCE([wchar.h wctype.h])
+   AC_CHECK_FUNCS_ONCE([iswprint wcwidth])
+ 
    AC_CACHE_CHECK([whether wcwidth is declared], [ac_cv_have_decl_wcwidth],
      [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
  /* AIX 3.2.5 declares wcwidth in <string.h>. */
diff -c -3 -r1.1 wcwidth
*** modules/wcwidth     28 Jun 2006 13:11:32 -0000      1.1
--- modules/wcwidth     28 Jun 2006 16:52:52 -0000
***************
*** 4,9 ****
--- 4,10 ----
  Files:
  lib/wcwidth.h
  m4/wcwidth.m4
+ m4/wchar_t.m4
  
  Depends-on:
  




reply via email to

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