#ifndef FISH_FALLBACK_H #define FISH_FALLBACK_H #include "config.h" // IWYU likes to recommend adding when we want . If we add it breaks // compiling several modules that include this header because they use symbols which are defined as // macros in . // IWYU pragma: no_include #include #include #include // 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 . 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 // IWYU pragma: keep #if HAVE_NCURSES_H #include // IWYU pragma: keep #endif /// fish's internal versions of wcwidth and wcswidth, which can use an internal implementation if /// the system one is busted. int fish_wcwidth(wchar_t wc); int fish_wcswidth(const wchar_t *str, size_t n); #ifndef WCHAR_MAX /// This _should_ be defined by wchar.h, but e.g. OpenBSD doesn't. #define WCHAR_MAX INT_MAX #endif /// 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. #ifdef NCURSES_VERSION typedef int tputs_arg_t; #else 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 { /// Number of rows. unsigned short ws_row; /// Number of columns. unsigned short ws_col; }; #endif #ifdef TPUTS_KLUDGE /// Linux on PPC seems to have a tputs implementation that sometimes behaves strangely. This /// fallback seems to fix things. int tputs(const char *str, int affcnt, int (*fish_putc)(tputs_arg_t)); #endif #ifdef TPARM_SOLARIS_KLUDGE /// Solaris tparm has a set fixed of paramters in it's curses implementation, work around this here. #define tparm tparm_solaris_kludge char *tparm_solaris_kludge(char *str, ...); #endif #ifndef HAVE_FWPRINTF /// Print formated string. Some operating systems (Like NetBSD) do not have wide string formating /// functions. Therefore we implement our own. Not at all complete. Supports wide and narrow /// characters, strings and decimal numbers, position (%n), field width and precision. int fwprintf(FILE *f, const wchar_t *format, ...); /// Print formated string. Some operating systems (Like NetBSD) do not have wide string formating /// functions. Therefore we define our own. Not at all complete. Supports wide and narrow /// characters, strings and decimal numbers, position (%n), field width and precision. int swprintf(wchar_t *str, size_t l, const wchar_t *format, ...); /// Print formated string. Some operating systems (Like NetBSD) do not have wide string formating /// functions. Therefore we define our own. Not at all complete. Supports wide and narrow /// characters, strings and decimal numbers, position (%n), field width and precision. int wprintf(const wchar_t *format, ...); /// Print formated string. Some operating systems (Like NetBSD) do not have wide string formating /// functions. Therefore we define our own. Not at all complete. Supports wide and narrow /// characters, strings and decimal numbers, position (%n), field width and precision. int vwprintf(const wchar_t *filter, va_list va); /// Print formated string. Some operating systems (Like NetBSD) do not have wide string formating /// functions. Therefore we define our own. Not at all complete. Supports wide and narrow /// characters, strings and decimal numbers, position (%n), field width and precision. int vfwprintf(FILE *f, const wchar_t *filter, va_list va); /// Print formated string. Some operating systems (Like NetBSD) do not have wide string formating /// functions. Therefore we define our own. Not at all complete. Supports wide and narrow /// characters, strings and decimal numbers, position (%n), field width and precision. int vswprintf(wchar_t *out, size_t n, const wchar_t *filter, va_list va); #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 /// 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. #if __APPLE__ && __DARWIN_C_LEVEL >= 200809L wchar_t *wcsdup_use_weak(const wchar_t *); int wcscasecmp_use_weak(const wchar_t *, const wchar_t *); 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); #endif /// Converts from wide char to digit in the specified base. If d is not a valid digit in the /// specified base, return -1. This is a helper function for wcstol, but it is useful itself, so it /// 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 <= /// wcslen(dst)). Returns wcslen(src) + MIN(siz, wcslen(initial dst)). If retval >= siz, /// truncation occurred. /// /// This is the OpenBSD strlcat function, modified for wide characters, and renamed to reflect this /// change. size_t wcslcat(wchar_t *dst, const wchar_t *src, size_t siz); #endif #ifndef HAVE_WCSLCPY /// 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. size_t wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz); #endif #ifndef HAVE_LRAND48_R /// Datastructure for the lrand48_r fallback implementation. struct drand48_data { unsigned int seed; }; /// Fallback implementation of lrand48_r. Internally uses rand_r, so it is pretty weak. int lrand48_r(struct drand48_data *buffer, long int *result); /// Fallback implementation of srand48_r, the seed function for lrand48_r. int srand48_r(long int seedval, struct drand48_data *buffer); #endif #ifndef HAVE_FUTIMES int futimes(int fd, const struct timeval *times); #endif // autoconf may fail to detect gettext (645), so don't define a function call gettext or we'll get // build errors. /// Cover for gettext(). char *fish_gettext(const char *msgid); /// Cover for bindtextdomain(). char *fish_bindtextdomain(const char *domainname, const char *dirname); /// Cover for textdomain(). char *fish_textdomain(const char *domainname); /// Cover for dcgettext. char *fish_dcgettext(const char *domainname, const char *msgid, int category); #ifndef HAVE__NL_MSG_CAT_CNTR /// Some gettext implementation use have this variable, and by increasing it, one can tell the /// system that the translations need to be reloaded. extern int _nl_msg_cat_cntr; #endif #ifndef HAVE_KILLPG /// Send specified signal to specified process group. int killpg(int pgr, int sig); #endif #ifndef HAVE_SYSCONF #define _SC_ARG_MAX 1 long sysconf(int name); #endif #ifndef HAVE_NAN double nan(char *tagp); #endif #ifndef HAVE_BACKTRACE int backtrace(void **buffer, int size); #endif #ifndef HAVE_BACKTRACE_SYMBOLS_FD char **backtrace_symbols_fd(void *const *buffer, int size, int fd); #endif #endif