fallback: drop fallbacks for C99/C++0x wide character functions

Drops configure check for wcsdup, wcslen, wcscasecmp, wcsncasecmp,
wcwidth, wcswidth, wcstok, fputwc, fgetwc, and wcstol. Drop the fallback
implementations of these on non-Snow Leopard platforms.

Work on #2999.
This commit is contained in:
David Adam 2016-05-15 23:19:27 +00:00
parent 44757c81af
commit db18449f4c
3 changed files with 6 additions and 276 deletions

View file

@ -307,12 +307,12 @@ AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec])
AC_STRUCT_DIRENT_D_TYPE
#
# Check for presense of various functions used by fish
# Check for presence of various functions used by fish
#
AC_CHECK_FUNCS( wcsdup wcsndup wcslen wcscasecmp wcsncasecmp )
AC_CHECK_FUNCS( futimes wcwidth wcswidth wcstok fputwc fgetwc )
AC_CHECK_FUNCS( wcstol wcslcat wcslcpy lrand48_r killpg )
AC_CHECK_FUNCS( wcsndup )
AC_CHECK_FUNCS( futimes )
AC_CHECK_FUNCS( wcslcat wcslcpy lrand48_r killpg )
AC_CHECK_FUNCS( backtrace backtrace_symbols_fd getifaddrs )
AC_CHECK_FUNCS( futimens clock_gettime )

View file

@ -90,135 +90,6 @@ char *tparm_solaris_kludge(char *str, ...) {
#endif
#ifndef HAVE_FGETWC
wint_t fgetwc(FILE *stream) {
wchar_t res;
mbstate_t state = {};
while (1) {
int b = fgetc(stream);
if (b == EOF) {
return WEOF;
}
if (MB_CUR_MAX == 1) // single-byte locale, all values are legal
{
return b;
}
char bb = b;
size_t sz = mbrtowc(&res, &bb, 1, &state);
switch (sz) {
case -1: {
return WEOF;
}
case -2: {
break;
}
case 0: {
return 0;
}
default: { return res; }
}
}
}
#endif
#ifndef HAVE_FPUTWC
wint_t fputwc(wchar_t wc, FILE *stream) {
int res = 0;
mbstate_t state = {};
char s[MB_CUR_MAX + 1] = {};
if (MB_CUR_MAX == 1) // single-byte locale (C/POSIX/ISO-8859)
{
// If `wc` contains a wide character we emit a question-mark.
if (wc & ~0xFF) {
wc = '?';
}
s[0] = (char)wc;
res = fputs(s, stream);
} else {
size_t len = wcrtomb(s, wc, &state);
if (len == (size_t)-1) {
debug(1, L"Wide character %d has no narrow representation", wc);
} else {
res = fputs(s, stream);
}
}
return res == EOF ? WEOF : wc;
}
#endif
#ifndef HAVE_WCSTOK
/// Used by fallback wcstok. Borrowed from glibc.
static size_t fish_wcsspn(const wchar_t *wcs, const wchar_t *accept) {
register const wchar_t *p;
register const wchar_t *a;
register size_t count = 0;
for (p = wcs; *p != L'\0'; ++p) {
for (a = accept; *a != L'\0'; ++a)
if (*p == *a) break;
if (*a == L'\0')
return count;
else
++count;
}
return count;
}
/// Used by fallback wcstok. Borrowed from glibc.
static wchar_t *fish_wcspbrk(const wchar_t *wcs, const wchar_t *accept) {
while (*wcs != L'\0')
if (wcschr(accept, *wcs) == NULL)
++wcs;
else
return (wchar_t *)wcs;
return NULL;
}
/// Fallback wcstok implementation. Borrowed from glibc.
wchar_t *wcstok(wchar_t *wcs, const wchar_t *delim, wchar_t **save_ptr) {
wchar_t *result;
if (wcs == NULL) {
if (*save_ptr == NULL) {
errno = EINVAL;
return NULL;
} else
wcs = *save_ptr;
}
// Scan leading delimiters.
wcs += fish_wcsspn(wcs, delim);
if (*wcs == L'\0') {
*save_ptr = NULL;
return NULL;
}
// Find the end of the token.
result = wcs;
wcs = fish_wcspbrk(result, delim);
if (wcs == NULL) {
// This token finishes the string.
*save_ptr = NULL;
} else {
// Terminate the token and make *SAVE_PTR point past it.
*wcs = L'\0';
*save_ptr = wcs + 1;
}
return result;
}
#endif
/// Fallback implementations of wcsdup and wcscasecmp. On systems where these are not needed (e.g.
/// building on Linux) these should end up just being stripped, as they are static functions that
/// are not referenced in this file.
@ -277,39 +148,8 @@ int wcsncasecmp_use_weak(const wchar_t *s1, const wchar_t *s2, size_t n) {
return wcsncasecmp_fallback(s1, s2, n);
}
#else //__APPLE__
#ifndef HAVE_WCSDUP
wchar_t *wcsdup(const wchar_t *in) { return wcsdup_fallback(in); }
#endif
#ifndef HAVE_WCSCASECMP
int wcscasecmp(const wchar_t *a, const wchar_t *b) { return wcscasecmp_fallback(a, b); }
#endif
#endif //__APPLE__
#ifndef HAVE_WCSLEN
size_t wcslen(const wchar_t *in) {
const wchar_t *end = in;
while (*end) end++;
return end - in;
}
#endif
#ifndef HAVE_WCSNCASECMP
int wcsncasecmp(const wchar_t *a, const wchar_t *b, size_t count) {
return wcsncasecmp_fallback(a, b, count);
}
#endif
#ifndef HAVE_WCWIDTH
int wcwidth(wchar_t c) {
if (c < 32) return 0;
if (c == 127) return 0;
return 1;
}
#endif
#ifndef HAVE_WCSNDUP
wchar_t *wcsndup(const wchar_t *in, size_t c) {
wchar_t *res = (wchar_t *)malloc(sizeof(wchar_t) * (c + 1));
@ -337,39 +177,6 @@ long convert_digit(wchar_t d, int base) {
return res;
}
#ifndef HAVE_WCSTOL
long wcstol(const wchar_t *nptr, wchar_t **endptr, int base) {
long long res = 0;
int is_set = 0;
if (base > 36) {
errno = EINVAL;
return 0;
}
while (1) {
long nxt = convert_digit(*nptr, base);
if (endptr != 0) *endptr = (wchar_t *)nptr;
if (nxt < 0) {
if (!is_set) {
errno = EINVAL;
}
return res;
}
res = (res * base) + nxt;
is_set = 1;
if (res > LONG_MAX) {
errno = ERANGE;
return LONG_MAX;
}
if (res < LONG_MIN) {
errno = ERANGE;
return LONG_MIN;
}
nptr++;
}
}
#endif
#ifndef HAVE_WCSLCAT
/*$OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $*/
@ -548,7 +355,8 @@ char **backtrace_symbols_fd(void *const *buffer, int size, int fd) { return 0; }
double nan(char *tagp) { return 0.0 / 0.0; }
#endif
// Big hack to use our versions of wcswidth where we know them to be broken, like on OS X.
// Big hack to use our versions of wcswidth where we know them to be broken, which is
// EVERYWHERE (https://github.com/fish-shell/fish-shell/issues/2199)
#ifndef HAVE_BROKEN_WCWIDTH
#define HAVE_BROKEN_WCWIDTH 1
#endif

View file

@ -38,14 +38,6 @@ typedef int tputs_arg_t;
typedef char tputs_arg_t;
#endif
#ifndef SIGIO
#define SIGIO SIGUSR1
#endif
#ifndef SIGWINCH
#define SIGWINCH SIGUSR2
#endif
#ifndef HAVE_WINSIZE
/// Structure used to get the size of a terminal window.
struct winsize {
@ -63,32 +55,6 @@ struct winsize {
char *tparm_solaris_kludge(char *str, ...);
#endif
#ifndef HAVE_FGETWC
// Fallback implementation of fgetwc.
wint_t fgetwc(FILE *stream);
#endif
#ifndef HAVE_FPUTWC
// Fallback implementation of fputwc.
wint_t fputwc(wchar_t wc, FILE *stream);
#endif
#ifndef HAVE_WCSTOK
/// Fallback implementation of wcstok. Uses code borrowed from glibc.
wchar_t *wcstok(wchar_t *wcs, const wchar_t *delim, wchar_t **ptr);
#endif
#ifndef HAVE_WCWIDTH
/// Return the number of columns used by a character. This is a libc function, but the prototype for
/// this function is missing in some libc implementations.
///
/// Fish has a fallback implementation in case the implementation is missing altogether. In locales
/// without a native wcwidth, Unicode is probably so broken that it isn't worth trying to implement
/// a real wcwidth. Therefore, the fallback wcwidth assumes any printing character takes up one
/// column and anything else uses 0 columns.
int wcwidth(wchar_t c);
#endif
/// On OS X, use weak linking for wcsdup and wcscasecmp. Weak linking allows you to call the
/// function only if it exists at runtime. You can detect it by testing the function pointer against
/// NULL. To avoid making the callers do that, redefine wcsdup to wcsdup_use_weak, and likewise with
@ -103,45 +69,8 @@ int wcsncasecmp_use_weak(const wchar_t *s1, const wchar_t *s2, size_t n);
#define wcsdup(a) wcsdup_use_weak((a))
#define wcscasecmp(a, b) wcscasecmp_use_weak((a), (b))
#define wcsncasecmp(a, b, c) wcsncasecmp_use_weak((a), (b), (c))
#else
#ifndef HAVE_WCSDUP
/// Create a duplicate string. Wide string version of strdup. Will automatically exit if out of
/// memory.
wchar_t *wcsdup(const wchar_t *in);
#endif
#ifndef HAVE_WCSCASECMP
/// Case insensitive string compare function. Wide string version of strcasecmp.
///
/// This implementation of wcscasecmp does not take into account esoteric locales where uppercase
/// and lowercase do not cleanly transform between each other. Hopefully this should be fine since
/// fish only uses this function with one of the strings supplied by fish and guaranteed to be a
/// sane, english word. Using wcscasecmp on a user-supplied string should be considered a bug.
int wcscasecmp(const wchar_t *a, const wchar_t *b);
#endif
#endif //__APPLE__
#ifndef HAVE_WCSLEN
/// Fallback for wclsen. Returns the length of the specified string.
size_t wcslen(const wchar_t *in);
#endif
#ifndef HAVE_WCSNCASECMP
/// Case insensitive string compare function. Wide string version of strncasecmp.
///
/// This implementation of wcsncasecmp does not take into account esoteric locales where uppercase
/// and lowercase do not cleanly transform between each other. Hopefully this should be fine since
/// fish only uses this function with one of the strings supplied by fish and guaranteed to be a
/// sane, english word. Using wcsncasecmp on a user-supplied string should be considered a bug.
int wcsncasecmp(const wchar_t *a, const wchar_t *b, size_t count);
/// Returns a newly allocated wide character string wich is a copy of the string in, but of length c
/// or shorter. The returned string is always null terminated, and the null is not included in the
/// string length.
#endif
#ifndef HAVE_WCSNDUP
/// Fallback for wcsndup function. Returns a copy of \c in, truncated to a maximum length of \c c.
wchar_t *wcsndup(const wchar_t *in, size_t c);
@ -152,13 +81,6 @@ wchar_t *wcsndup(const wchar_t *in, size_t c);
/// is exported.
long convert_digit(wchar_t d, int base);
#ifndef HAVE_WCSTOL
/// Fallback implementation. Convert a wide character string to a number in the specified base. This
/// functions is the wide character string equivalent of strtol. For bases of 10 or lower, 0..9 are
/// used to represent numbers. For bases below 36, a-z and A-Z are used to represent numbers higher
/// than 9. Higher bases than 36 are not supported.
long wcstol(const wchar_t *nptr, wchar_t **endptr, int base);
#endif
#ifndef HAVE_WCSLCAT
/// Appends src to string dst of size siz (unlike wcsncat, siz is the full size of dst, not space
/// left). At most siz-1 characters will be copied. Always NUL terminates (unless siz <=