mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-26 10:43:47 +08:00
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:
parent
44757c81af
commit
db18449f4c
|
@ -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 )
|
||||
|
||||
|
|
196
src/fallback.cpp
196
src/fallback.cpp
|
@ -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
|
||||
|
|
|
@ -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 <=
|
||||
|
|
Loading…
Reference in New Issue
Block a user