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: