2006-02-28 21:17:16 +08:00
|
|
|
#ifndef FISH_FALLBACK_H
|
|
|
|
#define FISH_FALLBACK_H
|
|
|
|
|
2016-04-21 14:00:54 +08:00
|
|
|
#include "config.h"
|
|
|
|
|
2017-02-13 12:24:22 +08:00
|
|
|
#include <stddef.h>
|
2016-04-30 10:01:36 +08:00
|
|
|
#include <stdint.h>
|
2016-04-21 14:00:54 +08:00
|
|
|
#include <unistd.h>
|
|
|
|
// The following include must be kept despite what IWYU says. That's because of the interaction
|
|
|
|
// between the weak linking of `wcsdup` and `wcscasecmp` via `#define`s below and the declarations
|
|
|
|
// in <wchar.h>. At least on OS X if we don't do this we get compilation errors do to the macro
|
|
|
|
// substitution if wchar.h is included after this header.
|
|
|
|
#include <wchar.h> // IWYU pragma: keep
|
2006-03-06 05:24:11 +08:00
|
|
|
|
2018-08-19 06:38:05 +08:00
|
|
|
/// The column width of ambiguous East Asian characters.
|
|
|
|
extern int g_fish_ambiguous_width;
|
|
|
|
|
2018-02-26 09:43:29 +08:00
|
|
|
/// The column width of emoji characters. This must be configurable because the value changed
|
|
|
|
/// between Unicode 8 and Unicode 9, wcwidth() is emoji-ignorant, and terminal emulators do
|
|
|
|
/// different things. See issues like #4539 and https://github.com/neovim/neovim/issues/4976 for how
|
|
|
|
/// painful this is. A value of 0 means to use the guessed value.
|
|
|
|
extern int g_fish_emoji_width;
|
|
|
|
|
|
|
|
/// The guessed value of the emoji width based on TERM.
|
|
|
|
extern int g_guessed_fish_emoji_width;
|
|
|
|
|
2016-04-30 10:01:36 +08:00
|
|
|
/// fish's internal versions of wcwidth and wcswidth, which can use an internal implementation if
|
|
|
|
/// the system one is busted.
|
2012-07-16 01:45:18 +08:00
|
|
|
int fish_wcwidth(wchar_t wc);
|
|
|
|
int fish_wcswidth(const wchar_t *str, size_t n);
|
|
|
|
|
2017-01-08 17:32:49 +08:00
|
|
|
// Replacement for mkostemp(str, O_CLOEXEC)
|
|
|
|
// This uses mkostemp if available,
|
|
|
|
// otherwise it uses mkstemp followed by fcntl
|
|
|
|
int fish_mkstemp_cloexec(char *);
|
|
|
|
|
2006-05-10 00:42:22 +08:00
|
|
|
#ifndef WCHAR_MAX
|
2016-04-30 10:01:36 +08:00
|
|
|
/// This _should_ be defined by wchar.h, but e.g. OpenBSD doesn't.
|
2006-05-19 17:59:48 +08:00
|
|
|
#define WCHAR_MAX INT_MAX
|
2006-05-10 00:42:22 +08:00
|
|
|
#endif
|
|
|
|
|
2016-04-30 10:01:36 +08:00
|
|
|
/// Under curses, tputs expects an int (*func)(char) as its last parameter, but in ncurses, tputs
|
|
|
|
/// expects a int (*func)(int) as its last parameter. tputs_arg_t is defined to always be what tputs
|
|
|
|
/// expects. Hopefully.
|
2018-12-11 23:48:30 +08:00
|
|
|
#if defined(NCURSES_VERSION) || defined(__NetBSD__)
|
2006-03-14 08:08:01 +08:00
|
|
|
typedef int tputs_arg_t;
|
|
|
|
#else
|
|
|
|
typedef char tputs_arg_t;
|
|
|
|
#endif
|
|
|
|
|
2006-07-31 04:55:44 +08:00
|
|
|
#ifndef HAVE_WINSIZE
|
2016-04-30 10:01:36 +08:00
|
|
|
/// Structure used to get the size of a terminal window.
|
|
|
|
struct winsize {
|
|
|
|
/// Number of rows.
|
2012-11-19 08:30:30 +08:00
|
|
|
unsigned short ws_row;
|
2016-04-30 10:01:36 +08:00
|
|
|
/// Number of columns.
|
2012-11-19 08:30:30 +08:00
|
|
|
unsigned short ws_col;
|
2016-04-30 10:01:36 +08:00
|
|
|
};
|
2006-07-31 04:55:44 +08:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2018-12-11 23:48:11 +08:00
|
|
|
#if defined(TPARM_SOLARIS_KLUDGE)
|
2017-10-31 16:48:35 +08:00
|
|
|
/// Solaris tparm has a set fixed of paramters in its curses implementation, work around this here.
|
2007-08-22 15:57:41 +08:00
|
|
|
#define tparm tparm_solaris_kludge
|
2017-10-31 16:48:35 +08:00
|
|
|
char *tparm_solaris_kludge(char *str, long p1 = 0, long p2 = 0, long p3 = 0, long p4 = 0,
|
|
|
|
long p5 = 0, long p6 = 0, long p7 = 0, long p8 = 0, long p9 = 0);
|
2007-08-22 15:57:41 +08:00
|
|
|
#endif
|
|
|
|
|
2016-04-30 10:01:36 +08:00
|
|
|
/// 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
|
|
|
|
/// wcscasecmp. This lets us use the same binary on SnowLeopard (10.6) and Lion+ (10.7), even though
|
|
|
|
/// these functions only exist on 10.7+.
|
|
|
|
///
|
|
|
|
/// On other platforms, use what's detected at build time.
|
2016-05-19 08:46:13 +08:00
|
|
|
#if __APPLE__
|
|
|
|
#if __DARWIN_C_LEVEL >= 200809L
|
2017-01-08 17:18:47 +08:00
|
|
|
// We have to explicitly redeclare these as weak,
|
|
|
|
// since we are forced to set the MIN_REQUIRED availability macro to 10.7
|
|
|
|
// to use libc++, which in turn exposes these as strong
|
2019-02-10 20:20:01 +08:00
|
|
|
[[clang::weak_import]] wchar_t *wcsdup(const wchar_t *);
|
|
|
|
[[clang::weak_import]] int wcscasecmp(const wchar_t *, const wchar_t *);
|
|
|
|
[[clang::weak_import]] int wcsncasecmp(const wchar_t *, const wchar_t *, size_t n);
|
2012-11-19 08:30:30 +08:00
|
|
|
wchar_t *wcsdup_use_weak(const wchar_t *);
|
|
|
|
int wcscasecmp_use_weak(const wchar_t *, const wchar_t *);
|
2013-05-17 10:44:21 +08:00
|
|
|
int wcsncasecmp_use_weak(const wchar_t *s1, const wchar_t *s2, size_t n);
|
2012-11-19 08:30:30 +08:00
|
|
|
#define wcsdup(a) wcsdup_use_weak((a))
|
|
|
|
#define wcscasecmp(a, b) wcscasecmp_use_weak((a), (b))
|
2013-05-17 10:44:21 +08:00
|
|
|
#define wcsncasecmp(a, b, c) wcsncasecmp_use_weak((a), (b), (c))
|
2016-05-19 08:46:13 +08:00
|
|
|
#else
|
|
|
|
wchar_t *wcsdup(const wchar_t *in);
|
|
|
|
int wcscasecmp(const wchar_t *a, const wchar_t *b);
|
|
|
|
int wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n);
|
|
|
|
wchar_t *wcsndup(const wchar_t *in, size_t c);
|
|
|
|
#endif
|
2016-12-11 12:48:07 +08:00
|
|
|
#else //__APPLE__
|
2012-07-21 05:33:08 +08:00
|
|
|
|
2017-03-06 21:23:24 +08:00
|
|
|
/// These functions are missing from Solaris 10, and only accessible from
|
|
|
|
/// Solaris 11 in the std:: namespace.
|
2016-12-08 08:21:08 +08:00
|
|
|
#ifndef HAVE_WCSDUP
|
2017-03-06 21:23:24 +08:00
|
|
|
#ifdef HAVE_STD__WCSDUP
|
|
|
|
using std::wcsdup;
|
|
|
|
#else
|
2016-12-08 08:21:08 +08:00
|
|
|
wchar_t *wcsdup(const wchar_t *in);
|
2017-03-16 05:06:58 +08:00
|
|
|
#endif // HAVE_STD__WCSDUP
|
|
|
|
#endif // HAVE_WCSDUP
|
2017-03-06 21:23:24 +08:00
|
|
|
|
2016-12-08 08:21:08 +08:00
|
|
|
#ifndef HAVE_WCSCASECMP
|
2017-03-06 21:23:24 +08:00
|
|
|
#ifdef HAVE_STD__WCSCASECMP
|
|
|
|
using std::wcscasecmp;
|
|
|
|
#else
|
2016-12-08 08:21:08 +08:00
|
|
|
int wcscasecmp(const wchar_t *a, const wchar_t *b);
|
2017-03-16 05:06:58 +08:00
|
|
|
#endif // HAVE_STD__WCSCASECMP
|
|
|
|
#endif // HAVE_WCSCASECMP
|
2017-03-06 21:23:24 +08:00
|
|
|
|
2016-12-08 08:21:08 +08:00
|
|
|
#ifndef HAVE_WCSNCASECMP
|
2017-03-06 21:23:24 +08:00
|
|
|
#ifdef HAVE_STD__WCSNCASECMP
|
|
|
|
using std::wcsncasecmp;
|
|
|
|
#else
|
2016-12-08 08:21:08 +08:00
|
|
|
int wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n);
|
2017-03-16 05:06:58 +08:00
|
|
|
#endif // HAVE_STD__WCSNCASECMP
|
|
|
|
#endif // HAVE_WCSNCASECMP
|
2017-03-06 21:23:24 +08:00
|
|
|
|
2016-12-08 08:21:08 +08:00
|
|
|
#ifndef HAVE_DIRFD
|
|
|
|
#ifndef __XOPEN_OR_POSIX
|
|
|
|
#define dirfd(d) (d->dd_fd)
|
|
|
|
#else
|
|
|
|
#define dirfd(d) (d->d_fd)
|
|
|
|
#endif
|
|
|
|
#endif
|
2016-12-11 12:48:07 +08:00
|
|
|
#endif
|
2016-12-08 08:21:08 +08:00
|
|
|
|
2006-03-26 00:21:03 +08:00
|
|
|
#ifndef HAVE_WCSNDUP
|
2016-04-30 10:01:36 +08:00
|
|
|
/// Fallback for wcsndup function. Returns a copy of \c in, truncated to a maximum length of \c c.
|
2012-11-19 08:30:30 +08:00
|
|
|
wchar_t *wcsndup(const wchar_t *in, size_t c);
|
2006-03-26 00:21:03 +08:00
|
|
|
#endif
|
|
|
|
|
2006-04-19 17:56:28 +08:00
|
|
|
#ifndef HAVE_WCSLCPY
|
2016-04-30 10:01:36 +08:00
|
|
|
/// Copy src to string dst of size siz. At most siz-1 characters will be copied. Always NUL
|
|
|
|
/// terminates (unless siz == 0). Returns wcslen(src); if retval >= siz, truncation occurred.
|
|
|
|
///
|
|
|
|
/// This is the OpenBSD strlcpy function, modified for wide characters, and renamed to reflect this
|
|
|
|
/// change.
|
2012-11-19 08:30:30 +08:00
|
|
|
size_t wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz);
|
2006-03-26 00:21:03 +08:00
|
|
|
#endif
|
2006-02-28 21:17:16 +08:00
|
|
|
|
2017-05-05 13:42:42 +08:00
|
|
|
#if 0
|
|
|
|
// These are not currently used.
|
2006-06-15 18:53:15 +08:00
|
|
|
#ifndef HAVE_LRAND48_R
|
2016-05-29 13:28:26 +08:00
|
|
|
/// Data structure for the lrand48_r fallback implementation.
|
2016-04-30 10:01:36 +08:00
|
|
|
struct drand48_data {
|
2012-11-19 08:30:30 +08:00
|
|
|
unsigned int seed;
|
2016-04-30 10:01:36 +08:00
|
|
|
};
|
2006-06-15 18:53:15 +08:00
|
|
|
|
2016-04-30 10:01:36 +08:00
|
|
|
/// Fallback implementation of lrand48_r. Internally uses rand_r, so it is pretty weak.
|
2012-11-19 08:30:30 +08:00
|
|
|
int lrand48_r(struct drand48_data *buffer, long int *result);
|
2006-06-20 08:50:10 +08:00
|
|
|
|
2016-04-30 10:01:36 +08:00
|
|
|
/// Fallback implementation of srand48_r, the seed function for lrand48_r.
|
2012-11-19 08:30:30 +08:00
|
|
|
int srand48_r(long int seedval, struct drand48_data *buffer);
|
2006-02-28 21:17:16 +08:00
|
|
|
#endif
|
2017-05-05 13:42:42 +08:00
|
|
|
#endif
|
2006-06-15 18:53:15 +08:00
|
|
|
|
2006-06-21 22:15:44 +08:00
|
|
|
#ifndef HAVE_FUTIMES
|
2012-11-19 08:30:30 +08:00
|
|
|
int futimes(int fd, const struct timeval *times);
|
2006-06-21 22:15:44 +08:00
|
|
|
#endif
|
|
|
|
|
2016-04-30 10:01:36 +08:00
|
|
|
// autoconf may fail to detect gettext (645), so don't define a function call gettext or we'll get
|
|
|
|
// build errors.
|
2006-07-20 06:55:49 +08:00
|
|
|
|
2016-04-30 10:01:36 +08:00
|
|
|
/// Cover for gettext().
|
|
|
|
char *fish_gettext(const char *msgid);
|
2006-07-20 07:11:49 +08:00
|
|
|
|
2016-04-30 10:01:36 +08:00
|
|
|
/// Cover for bindtextdomain().
|
|
|
|
char *fish_bindtextdomain(const char *domainname, const char *dirname);
|
2006-07-20 06:55:49 +08:00
|
|
|
|
2016-04-30 10:01:36 +08:00
|
|
|
/// Cover for textdomain().
|
|
|
|
char *fish_textdomain(const char *domainname);
|
2006-07-20 06:55:49 +08:00
|
|
|
|
2006-07-31 04:59:41 +08:00
|
|
|
#ifndef HAVE_KILLPG
|
2016-04-30 10:01:36 +08:00
|
|
|
/// Send specified signal to specified process group.
|
2012-11-19 08:30:30 +08:00
|
|
|
int killpg(int pgr, int sig);
|
2006-07-31 04:59:41 +08:00
|
|
|
#endif
|
|
|
|
|
2016-11-22 09:35:24 +08:00
|
|
|
#ifndef HAVE_FLOCK
|
2017-05-11 12:08:36 +08:00
|
|
|
/// Fallback implementation of flock in terms of fcntl.
|
2016-11-22 09:35:24 +08:00
|
|
|
/// Danger! The semantics of flock and fcntl locking are very different.
|
|
|
|
/// Use with caution.
|
|
|
|
int flock(int fd, int op);
|
|
|
|
|
2016-12-04 12:12:53 +08:00
|
|
|
#define LOCK_SH 1 // Shared lock.
|
|
|
|
#define LOCK_EX 2 // Exclusive lock.
|
|
|
|
#define LOCK_UN 8 // Unlock.
|
|
|
|
#define LOCK_NB 4 // Don't block when locking.
|
2016-11-22 09:35:24 +08:00
|
|
|
#endif
|
|
|
|
|
2006-06-15 18:53:15 +08:00
|
|
|
#endif
|
2018-12-12 22:12:12 +08:00
|
|
|
|
2019-01-21 01:33:04 +08:00
|
|
|
// NetBSD _has_ wcstod_l, but it's doing some weak linking hullabaloo that I don't get.
|
|
|
|
// Since it doesn't have uselocale (yes, the standard function isn't there, the non-standard extension is),
|
|
|
|
// we can't try to use the fallback.
|
|
|
|
#if !defined(HAVE_WCSTOD_L) && !defined(__NetBSD__)
|
2019-01-03 07:25:33 +08:00
|
|
|
// On some platforms if this is incorrectly detected and a system-defined
|
|
|
|
// defined version of `wcstod_l` exists, calling `wcstod` from our own
|
|
|
|
// `wcstod_l` can call back into `wcstod_l` causing infinite recursion.
|
|
|
|
// e.g. FreeBSD defines `wcstod(x, y)` as `wcstod_l(x, y, __get_locale())`.
|
|
|
|
// Solution: namespace our implementation to make sure there is no symbol
|
|
|
|
// duplication.
|
|
|
|
#undef wcstod_l
|
|
|
|
namespace fish_compat {
|
|
|
|
double wcstod_l(const wchar_t *enptr, wchar_t **endptr, locale_t loc);
|
|
|
|
}
|
|
|
|
#define wcstod_l(x, y, z) fish_compat::wcstod_l(x, y, z)
|
2018-12-12 22:12:12 +08:00
|
|
|
#endif
|