1# wcwidth.m4 serial 31
2dnl Copyright (C) 2006-2020 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it,
5dnl with or without modifications, as long as this notice is preserved.
6
7AC_DEFUN([gl_FUNC_WCWIDTH],
8[
9  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
10  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
11
12  dnl Persuade glibc <wchar.h> to declare wcwidth().
13  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
14
15  AC_REQUIRE([gt_TYPE_WCHAR_T])
16  AC_REQUIRE([gt_TYPE_WINT_T])
17
18  AC_CHECK_HEADERS_ONCE([wchar.h])
19  AC_CHECK_FUNCS_ONCE([wcwidth])
20
21  AC_CHECK_DECLS([wcwidth], [], [], [[
22/* AIX 3.2.5 declares wcwidth in <string.h>. */
23#include <string.h>
24/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
25   <wchar.h>.
26   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be included
27   before <wchar.h>.  */
28#include <stddef.h>
29#include <stdio.h>
30#include <time.h>
31#include <wchar.h>
32]])
33  if test $ac_cv_have_decl_wcwidth != yes; then
34    HAVE_DECL_WCWIDTH=0
35  fi
36
37  if test $ac_cv_func_wcwidth != yes; then
38    AC_CACHE_CHECK([whether wcwidth is a macro],
39      [gl_cv_func_wcwidth_macro],
40      [AC_EGREP_CPP([wchar_header_defines_wcwidth], [
41#include <wchar.h>
42#ifdef wcwidth
43 wchar_header_defines_wcwidth
44#endif],
45         [gl_cv_func_wcwidth_macro=yes],
46         [gl_cv_func_wcwidth_macro=no])
47      ])
48  fi
49
50  if test $ac_cv_func_wcwidth = yes || test $gl_cv_func_wcwidth_macro = yes; then
51    HAVE_WCWIDTH=1
52    dnl On Mac OS X 10.3, wcwidth(0x0301) (COMBINING ACUTE ACCENT) returns 1.
53    dnl On NetBSD 9.0, OpenBSD 5.0, wcwidth(0x05B0) (HEBREW POINT SHEVA) returns 1.
54    dnl On NetBSD 9.0, OSF/1 5.1, wcwidth(0x200B) (ZERO WIDTH SPACE) returns 1.
55    dnl On OpenBSD 5.8, wcwidth(0xFF1A) (FULLWIDTH COLON) returns 0.
56    dnl This leads to bugs in 'ls' (coreutils).
57    dnl On Solaris 11.4, wcwidth(0x2202) (PARTIAL DIFFERENTIAL) returns 2,
58    dnl even in Western locales.
59    AC_CACHE_CHECK([whether wcwidth works reasonably in UTF-8 locales],
60      [gl_cv_func_wcwidth_works],
61      [
62        AC_RUN_IFELSE(
63          [AC_LANG_SOURCE([[
64#include <locale.h>
65/* AIX 3.2.5 declares wcwidth in <string.h>. */
66#include <string.h>
67/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
68   <wchar.h>.
69   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be included
70   before <wchar.h>.  */
71#include <stddef.h>
72#include <stdio.h>
73#include <time.h>
74#include <wchar.h>
75#if !HAVE_DECL_WCWIDTH
76extern
77# ifdef __cplusplus
78"C"
79# endif
80int wcwidth (int);
81#endif
82int main ()
83{
84  int result = 0;
85  if (setlocale (LC_ALL, "en_US.UTF-8") != NULL)
86    {
87      if (wcwidth (0x0301) > 0)
88        result |= 1;
89      if (wcwidth (0x05B0) > 0)
90        result |= 2;
91      if (wcwidth (0x200B) > 0)
92        result |= 4;
93      if (wcwidth (0xFF1A) == 0)
94        result |= 8;
95      if (wcwidth (0x2202) > 1)
96        result |= 16;
97    }
98  return result;
99}]])],
100          [gl_cv_func_wcwidth_works=yes],
101          [gl_cv_func_wcwidth_works=no],
102          [
103changequote(,)dnl
104           case "$host_os" in
105                            # Guess yes on glibc systems.
106             *-gnu* | gnu*) gl_cv_func_wcwidth_works="guessing yes";;
107                            # Guess yes on musl systems.
108             *-musl*)       gl_cv_func_wcwidth_works="guessing yes";;
109                            # Guess yes on AIX 7 systems.
110             aix[7-9]*)     gl_cv_func_wcwidth_works="guessing yes";;
111             *)             gl_cv_func_wcwidth_works="$gl_cross_guess_normal";;
112           esac
113changequote([,])dnl
114          ])
115      ])
116    case "$gl_cv_func_wcwidth_works" in
117      *yes) ;;
118      *no) REPLACE_WCWIDTH=1 ;;
119    esac
120  else
121    HAVE_WCWIDTH=0
122  fi
123  dnl We don't substitute HAVE_WCWIDTH. We assume that if the system does not
124  dnl have the wcwidth function, then it does not declare it.
125])
126
127# Prerequisites of lib/wcwidth.c.
128AC_DEFUN([gl_PREREQ_WCWIDTH], [
129  AC_REQUIRE([AC_C_INLINE])
130  :
131])
132