2016-04-27 23:10:14 +00:00
|
|
|
// Prototypes for various functions, mostly string utilities, that are used by most parts of fish.
|
2005-10-04 15:11:39 +00:00
|
|
|
#ifndef FISH_COMMON_H
|
|
|
|
#define FISH_COMMON_H
|
2017-04-20 06:43:02 +00:00
|
|
|
#include "config.h" // IWYU pragma: keep
|
2005-10-04 15:11:39 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
#include <errno.h>
|
2017-09-26 13:19:33 +00:00
|
|
|
#include <limits.h>
|
2019-02-13 13:08:43 +00:00
|
|
|
// Needed for va_list et al.
|
2019-05-05 10:09:25 +00:00
|
|
|
#include <stdarg.h> // IWYU pragma: keep
|
2017-07-08 21:17:35 +00:00
|
|
|
#ifdef HAVE_SYS_IOCTL_H
|
|
|
|
#include <sys/ioctl.h> // IWYU pragma: keep
|
|
|
|
#endif
|
2017-02-14 04:37:27 +00:00
|
|
|
|
2018-08-12 02:55:06 +00:00
|
|
|
#include <algorithm>
|
2019-05-04 22:28:20 +00:00
|
|
|
#include <atomic>
|
2018-10-02 22:10:14 +00:00
|
|
|
#include <functional>
|
2016-06-24 00:24:19 +00:00
|
|
|
#include <memory>
|
2017-08-18 19:26:35 +00:00
|
|
|
#include <mutex>
|
2016-04-27 23:10:14 +00:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2016-04-21 06:00:54 +00:00
|
|
|
|
|
|
|
#include "fallback.h" // IWYU pragma: keep
|
2018-09-28 02:22:55 +00:00
|
|
|
#include "maybe.h"
|
2005-09-20 13:26:39 +00:00
|
|
|
|
2020-11-20 20:11:03 +00:00
|
|
|
// Create a generic define for all BSD platforms
|
|
|
|
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
|
|
|
|
#define __BSD__
|
|
|
|
#endif
|
|
|
|
|
2019-02-06 04:36:38 +00:00
|
|
|
// PATH_MAX may not exist.
|
|
|
|
#ifndef PATH_MAX
|
|
|
|
#define PATH_MAX 4096
|
|
|
|
#endif
|
|
|
|
|
2016-06-17 20:08:25 +00:00
|
|
|
// Define a symbol we can use elsewhere in our code to determine if we're being built on MS Windows
|
|
|
|
// under Cygwin.
|
|
|
|
#if defined(_WIN32) || defined(_WIN64) || defined(WIN32) || defined(__CYGWIN__) || \
|
|
|
|
defined(__WIN32__)
|
|
|
|
#define OS_IS_CYGWIN
|
|
|
|
#endif
|
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
// Common string type.
|
2011-12-27 03:18:46 +00:00
|
|
|
typedef std::wstring wcstring;
|
2011-12-27 08:06:07 +00:00
|
|
|
typedef std::vector<wcstring> wcstring_list_t;
|
2011-12-27 03:18:46 +00:00
|
|
|
|
2020-06-08 01:47:27 +00:00
|
|
|
struct termsize_t;
|
|
|
|
|
2016-01-22 03:56:39 +00:00
|
|
|
// Maximum number of bytes used by a single utf-8 character.
|
2005-09-20 13:26:39 +00:00
|
|
|
#define MAX_UTF8_BYTES 6
|
|
|
|
|
2016-01-22 03:56:39 +00:00
|
|
|
// Highest legal ASCII value.
|
2006-05-26 16:46:38 +00:00
|
|
|
#define ASCII_MAX 127u
|
|
|
|
|
2016-01-22 03:56:39 +00:00
|
|
|
// Highest legal 16-bit Unicode value.
|
|
|
|
#define UCS2_MAX 0xFFFFu
|
2006-05-26 16:46:38 +00:00
|
|
|
|
2016-01-22 03:56:39 +00:00
|
|
|
// Highest legal byte value.
|
|
|
|
#define BYTE_MAX 0xFFu
|
2006-05-26 16:46:38 +00:00
|
|
|
|
2016-01-22 03:56:39 +00:00
|
|
|
// Unicode BOM value.
|
2014-11-01 23:25:28 +00:00
|
|
|
#define UTF8_BOM_WCHAR 0xFEFFu
|
|
|
|
|
2016-01-22 03:56:39 +00:00
|
|
|
// Unicode replacement character.
|
|
|
|
#define REPLACEMENT_WCHAR 0xFFFDu
|
|
|
|
|
|
|
|
// Use Unicode "noncharacters" for internal characters as much as we can. This
|
|
|
|
// gives us 32 "characters" for internal use that we can guarantee should not
|
|
|
|
// appear in our input stream. See http://www.unicode.org/faq/private_use.html.
|
2020-04-08 23:56:59 +00:00
|
|
|
#define RESERVED_CHAR_BASE static_cast<wchar_t>(0xFDD0)
|
|
|
|
#define RESERVED_CHAR_END static_cast<wchar_t>(0xFDF0)
|
2016-01-22 03:56:39 +00:00
|
|
|
// Split the available noncharacter values into two ranges to ensure there are
|
|
|
|
// no conflicts among the places we use these special characters.
|
|
|
|
#define EXPAND_RESERVED_BASE RESERVED_CHAR_BASE
|
2016-04-27 23:10:14 +00:00
|
|
|
#define EXPAND_RESERVED_END (EXPAND_RESERVED_BASE + 16)
|
2016-01-22 03:56:39 +00:00
|
|
|
#define WILDCARD_RESERVED_BASE EXPAND_RESERVED_END
|
2016-04-27 23:10:14 +00:00
|
|
|
#define WILDCARD_RESERVED_END (WILDCARD_RESERVED_BASE + 16)
|
2016-01-22 03:56:39 +00:00
|
|
|
// Make sure the ranges defined above don't exceed the range for noncharacters.
|
|
|
|
// This is to make sure we didn't do something stupid in subdividing the
|
|
|
|
// Unicode range for our needs.
|
2016-10-09 21:36:08 +00:00
|
|
|
//#if WILDCARD_RESERVED_END > RESERVED_CHAR_END
|
|
|
|
//#error
|
|
|
|
//#endif
|
2016-01-22 03:56:39 +00:00
|
|
|
|
|
|
|
// These are in the Unicode private-use range. We really shouldn't use this
|
|
|
|
// range but have little choice in the matter given how our lexer/parser works.
|
|
|
|
// We can't use non-characters for these two ranges because there are only 66 of
|
|
|
|
// them and we need at least 256 + 64.
|
|
|
|
//
|
|
|
|
// If sizeof(wchar_t))==4 we could avoid using private-use chars; however, that
|
|
|
|
// would result in fish having different behavior on machines with 16 versus 32
|
|
|
|
// bit wchar_t. It's better that fish behave the same on both types of systems.
|
|
|
|
//
|
|
|
|
// Note: We don't use the highest 8 bit range (0xF800 - 0xF8FF) because we know
|
|
|
|
// of at least one use of a codepoint in that range: the Apple symbol (0xF8FF)
|
|
|
|
// on Mac OS X. See http://www.unicode.org/faq/private_use.html.
|
2020-04-08 23:56:59 +00:00
|
|
|
#define ENCODE_DIRECT_BASE static_cast<wchar_t>(0xF600)
|
2016-04-27 23:10:14 +00:00
|
|
|
#define ENCODE_DIRECT_END (ENCODE_DIRECT_BASE + 256)
|
|
|
|
|
2017-09-26 13:19:33 +00:00
|
|
|
// NAME_MAX is not defined on Solaris
|
|
|
|
#if !defined(NAME_MAX)
|
|
|
|
#include <sys/param.h>
|
|
|
|
#if defined(MAXNAMELEN)
|
|
|
|
// MAXNAMELEN is defined on Linux, BSD, and Solaris among others
|
|
|
|
#define NAME_MAX MAXNAMELEN
|
|
|
|
#else
|
|
|
|
static_assert(false, "Neither NAME_MAX nor MAXNAMELEN is defined!");
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2018-10-10 03:33:20 +00:00
|
|
|
// PATH_MAX may not exist.
|
|
|
|
#ifndef PATH_MAX
|
|
|
|
#ifdef MAXPATHLEN
|
|
|
|
#define PATH_MAX MAXPATHLEN
|
|
|
|
#else
|
|
|
|
/// Fallback length of MAXPATHLEN. Hopefully a sane value.
|
|
|
|
#define PATH_MAX 4096
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2018-11-15 05:30:11 +00:00
|
|
|
enum escape_string_style_t {
|
|
|
|
STRING_STYLE_SCRIPT,
|
|
|
|
STRING_STYLE_URL,
|
|
|
|
STRING_STYLE_VAR,
|
2018-11-17 02:21:05 +00:00
|
|
|
STRING_STYLE_REGEX,
|
2018-11-15 05:30:11 +00:00
|
|
|
};
|
2017-06-21 04:55:16 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
// Flags for unescape_string functions.
|
|
|
|
enum {
|
2020-03-26 19:45:40 +00:00
|
|
|
UNESCAPE_DEFAULT = 0, // default behavior
|
|
|
|
UNESCAPE_SPECIAL = 1 << 0, // escape special fish syntax characters like the semicolon
|
|
|
|
UNESCAPE_INCOMPLETE = 1 << 1, // allow incomplete escape sequences
|
2020-03-08 13:03:15 +00:00
|
|
|
UNESCAPE_NO_BACKSLASHES = 1 << 2, // don't handle backslash escapes
|
2013-11-25 06:57:49 +00:00
|
|
|
};
|
|
|
|
typedef unsigned int unescape_flags_t;
|
2007-01-18 16:02:46 +00:00
|
|
|
|
2017-06-21 04:55:16 +00:00
|
|
|
// Flags for the escape_string() and escape_string() functions. These are only applicable when the
|
|
|
|
// escape style is "script" (i.e., STRING_STYLE_SCRIPT).
|
2016-04-27 23:10:14 +00:00
|
|
|
enum {
|
|
|
|
/// Escape all characters, including magic characters like the semicolon.
|
2012-11-19 00:30:30 +00:00
|
|
|
ESCAPE_ALL = 1 << 0,
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Do not try to use 'simplified' quoted escapes, and do not use empty quotes as the empty
|
|
|
|
/// string.
|
2012-07-06 21:34:53 +00:00
|
|
|
ESCAPE_NO_QUOTED = 1 << 1,
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Do not escape tildes.
|
2019-09-19 06:32:40 +00:00
|
|
|
ESCAPE_NO_TILDE = 1 << 2
|
2012-07-06 21:34:53 +00:00
|
|
|
};
|
|
|
|
typedef unsigned int escape_flags_t;
|
2007-10-06 10:51:31 +00:00
|
|
|
|
2017-01-03 05:11:53 +00:00
|
|
|
/// Issue a debug message with printf-style string formating and automatic line breaking. The string
|
|
|
|
/// will begin with the string \c program_name, followed by a colon and a whitespace.
|
|
|
|
///
|
|
|
|
/// Because debug is often called to tell the user about an error, before using wperror to give a
|
|
|
|
/// specific error message, debug will never ever modify the value of errno.
|
|
|
|
///
|
|
|
|
/// \param level the priority of the message. Lower number means higher priority. Messages with a
|
|
|
|
/// priority_number higher than \c debug_level will be ignored..
|
|
|
|
/// \param msg the message format string.
|
|
|
|
///
|
|
|
|
/// Example:
|
|
|
|
///
|
|
|
|
/// <code>debug( 1, L"Pi = %.3f", M_PI );</code>
|
|
|
|
///
|
|
|
|
/// will print the string 'fish: Pi = 3.141', given that debug_level is 1 or higher, and that
|
|
|
|
/// program_name is 'fish'.
|
2019-02-10 12:20:01 +00:00
|
|
|
[[gnu::noinline, gnu::format(printf, 2, 3)]] void debug_impl(int level, const char *msg, ...);
|
|
|
|
[[gnu::noinline]] void debug_impl(int level, const wchar_t *msg, ...);
|
2017-12-22 23:19:08 +00:00
|
|
|
|
|
|
|
/// The verbosity level of fish. If a call to debug has a severity level higher than \c debug_level,
|
|
|
|
/// it will not be printed.
|
2019-05-04 22:28:20 +00:00
|
|
|
extern std::atomic<int> debug_level;
|
2017-12-22 23:19:08 +00:00
|
|
|
|
2019-05-04 22:28:20 +00:00
|
|
|
inline bool should_debug(int level) { return level <= debug_level.load(std::memory_order_relaxed); }
|
2017-12-22 23:19:08 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Exits without invoking destructors (via _exit), useful for code after fork.
|
2016-11-29 09:41:03 +00:00
|
|
|
[[noreturn]] void exit_without_destructors(int code);
|
2012-01-05 21:58:48 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Save the shell mode on startup so we can restore them on exit.
|
2012-11-19 00:30:30 +00:00
|
|
|
extern struct termios shell_modes;
|
2005-09-20 13:26:39 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// The character to use where the text has been truncated. Is an ellipsis on unicode system and a $
|
|
|
|
/// on other systems.
|
2019-04-28 22:00:36 +00:00
|
|
|
wchar_t get_ellipsis_char();
|
|
|
|
|
2018-09-28 02:28:39 +00:00
|
|
|
/// The character or string to use where text has been truncated (ellipsis if possible, otherwise
|
|
|
|
/// ...)
|
2019-04-28 22:00:36 +00:00
|
|
|
const wchar_t *get_ellipsis_str();
|
2012-11-05 08:05:42 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Character representing an omitted newline at the end of text.
|
2019-04-28 22:00:36 +00:00
|
|
|
const wchar_t *get_omitted_newline_str();
|
|
|
|
int get_omitted_newline_width();
|
2012-12-01 23:44:09 +00:00
|
|
|
|
2017-04-09 18:48:21 +00:00
|
|
|
/// Character used for the silent mode of the read command
|
2019-04-28 22:00:36 +00:00
|
|
|
wchar_t get_obfuscation_read_char();
|
2017-04-09 18:48:21 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Profiling flag. True if commands should be profiled.
|
2014-02-09 22:04:43 +00:00
|
|
|
extern bool g_profiling_active;
|
2005-09-20 13:26:39 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Name of the current program. Should be set at startup. Used by the debug function.
|
2018-11-28 14:08:24 +00:00
|
|
|
extern const wchar_t *program_name;
|
2005-10-25 09:39:45 +00:00
|
|
|
|
2018-09-29 04:20:50 +00:00
|
|
|
/// Set to false if it's been determined we can't trust the last modified timestamp on the tty.
|
|
|
|
extern const bool has_working_tty_timestamps;
|
2016-06-17 20:08:25 +00:00
|
|
|
|
2016-11-29 09:41:03 +00:00
|
|
|
// Pause for input, then exit the program. If supported, print a backtrace first.
|
2016-10-30 00:25:48 +00:00
|
|
|
// The `return` will never be run but silences oclint warnings. Especially when this is called
|
|
|
|
// from within a `switch` block. As of the time I'm writing this oclint doesn't recognize the
|
|
|
|
// `__attribute__((noreturn))` on the exit_without_destructors() function.
|
2016-11-29 09:41:03 +00:00
|
|
|
// TODO: we use C++11 [[noreturn]] now, does that change things?
|
2017-08-18 19:26:35 +00:00
|
|
|
#define FATAL_EXIT() \
|
2019-11-20 06:17:30 +00:00
|
|
|
do { \
|
2017-08-18 19:26:35 +00:00
|
|
|
char exit_read_buff; \
|
|
|
|
show_stackframe(L'E'); \
|
2017-08-12 14:54:26 +00:00
|
|
|
ignore_result(read(0, &exit_read_buff, 1)); \
|
2017-08-18 19:26:35 +00:00
|
|
|
exit_without_destructors(1); \
|
2019-11-20 06:17:30 +00:00
|
|
|
} while (0)
|
2006-07-19 22:55:49 +00:00
|
|
|
|
2017-02-14 04:37:27 +00:00
|
|
|
/// Exit the program at once after emitting an error message and stack trace if possible.
|
|
|
|
/// We use our own private implementation of `assert()` for two reasons. First, some implementations
|
|
|
|
/// are subtly broken. For example, using `printf()` which can cause problems when mixed with wide
|
|
|
|
/// stdio functions and should be writing the message to stderr rather than stdout. Second, if
|
|
|
|
/// possible it is useful to provide additional context such as a stack backtrace.
|
|
|
|
#undef assert
|
2017-06-17 04:50:08 +00:00
|
|
|
#define assert(e) (e) ? ((void)0) : __fish_assert(#e, __FILE__, __LINE__, 0)
|
|
|
|
#define assert_with_errno(e) (e) ? ((void)0) : __fish_assert(#e, __FILE__, __LINE__, errno)
|
|
|
|
#define DIE(msg) __fish_assert(msg, __FILE__, __LINE__, 0)
|
|
|
|
#define DIE_WITH_ERRNO(msg) __fish_assert(msg, __FILE__, __LINE__, errno)
|
2017-02-15 05:09:15 +00:00
|
|
|
/// This macro is meant to be used with functions that return zero on success otherwise return an
|
|
|
|
/// errno value. Most notably the pthread family of functions which we never expect to fail.
|
2017-06-24 06:19:09 +00:00
|
|
|
#define DIE_ON_FAILURE(e) \
|
|
|
|
do { \
|
|
|
|
int status = e; \
|
|
|
|
if (status != 0) { \
|
2017-06-17 04:50:08 +00:00
|
|
|
__fish_assert(#e, __FILE__, __LINE__, status); \
|
2017-06-24 06:19:09 +00:00
|
|
|
} \
|
2017-02-15 05:09:15 +00:00
|
|
|
} while (0)
|
|
|
|
|
2017-06-17 04:50:08 +00:00
|
|
|
[[noreturn]] void __fish_assert(const char *msg, const char *file, size_t line, int error);
|
2007-04-16 21:40:41 +00:00
|
|
|
|
2019-05-05 10:09:25 +00:00
|
|
|
/// Shorthand for wgettext call in situations where a C-style string is needed (e.g.,
|
|
|
|
/// std::fwprintf()).
|
2016-06-02 05:03:27 +00:00
|
|
|
#define _(wstr) wgettext(wstr).c_str()
|
2005-09-20 13:26:39 +00:00
|
|
|
|
2016-06-15 02:55:30 +00:00
|
|
|
/// Noop, used to tell xgettext that a string should be translated. Use this when a string cannot be
|
|
|
|
/// passed through wgettext() at the point where it is used. For example, when initializing a
|
|
|
|
/// static array or structure. You must pass the string through wgettext() when it is used.
|
|
|
|
/// See https://developer.gnome.org/glib/stable/glib-I18N.html#N-:CAPS
|
2016-04-27 23:10:14 +00:00
|
|
|
#define N_(wstr) wstr
|
2005-09-20 13:26:39 +00:00
|
|
|
|
2018-09-29 04:58:44 +00:00
|
|
|
/// Test if a collection contains a value.
|
|
|
|
template <typename Col, typename T2>
|
|
|
|
bool contains(const Col &col, const T2 &val) {
|
|
|
|
return std::find(std::begin(col), std::end(col), val) != std::end(col);
|
2018-08-12 02:55:06 +00:00
|
|
|
}
|
2012-07-16 19:05:36 +00:00
|
|
|
|
2018-09-10 01:32:15 +00:00
|
|
|
/// Append a vector \p donator to the vector \p receiver.
|
|
|
|
template <typename T>
|
|
|
|
void vec_append(std::vector<T> &receiver, std::vector<T> &&donator) {
|
2020-12-01 19:36:38 +00:00
|
|
|
if (receiver.empty()) {
|
|
|
|
receiver = std::move(donator);
|
|
|
|
} else {
|
|
|
|
receiver.insert(receiver.end(), std::make_move_iterator(donator.begin()),
|
|
|
|
std::make_move_iterator(donator.end()));
|
|
|
|
}
|
2018-09-10 01:32:15 +00:00
|
|
|
}
|
|
|
|
|
2019-02-13 23:17:07 +00:00
|
|
|
/// Move an object into a shared_ptr.
|
|
|
|
template <typename T>
|
|
|
|
std::shared_ptr<T> move_to_sharedptr(T &&v) {
|
|
|
|
return std::make_shared<T>(std::move(v));
|
|
|
|
}
|
|
|
|
|
2020-01-16 01:14:47 +00:00
|
|
|
/// A function type to check for cancellation.
|
|
|
|
/// \return true if execution should cancel.
|
|
|
|
using cancel_checker_t = std::function<bool()>;
|
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Print a stack trace to stderr.
|
2016-10-21 01:53:31 +00:00
|
|
|
void show_stackframe(const wchar_t msg_level, int frame_count = 100, int skip_levels = 0);
|
2006-06-17 13:07:08 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Returns a wide character string equivalent of the specified multibyte character string.
|
|
|
|
///
|
|
|
|
/// This function encodes illegal character sequences in a reversible way using the private use
|
|
|
|
/// area.
|
2012-11-19 00:30:30 +00:00
|
|
|
wcstring str2wcstring(const char *in);
|
2012-12-19 21:31:06 +00:00
|
|
|
wcstring str2wcstring(const char *in, size_t len);
|
2012-11-19 00:30:30 +00:00
|
|
|
wcstring str2wcstring(const std::string &in);
|
2017-12-19 10:05:20 +00:00
|
|
|
wcstring str2wcstring(const std::string &in, size_t len);
|
2011-12-27 03:18:46 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Returns a newly allocated multibyte character string equivalent of the specified wide character
|
|
|
|
/// string.
|
|
|
|
///
|
|
|
|
/// This function decodes illegal character sequences in a reversible way using the private use
|
|
|
|
/// area.
|
2011-12-27 03:18:46 +00:00
|
|
|
std::string wcs2string(const wcstring &input);
|
|
|
|
|
2016-12-03 21:27:50 +00:00
|
|
|
// Check if we are running in the test mode, where we should suppress error output
|
2018-11-28 14:08:24 +00:00
|
|
|
#define TESTS_PROGRAM_NAME L"(ignore)"
|
2016-12-03 21:27:50 +00:00
|
|
|
bool should_suppress_stderr_for_tests();
|
|
|
|
|
2011-12-27 03:18:46 +00:00
|
|
|
void assert_is_main_thread(const char *who);
|
|
|
|
#define ASSERT_IS_MAIN_THREAD_TRAMPOLINE(x) assert_is_main_thread(x)
|
|
|
|
#define ASSERT_IS_MAIN_THREAD() ASSERT_IS_MAIN_THREAD_TRAMPOLINE(__FUNCTION__)
|
|
|
|
|
|
|
|
void assert_is_background_thread(const char *who);
|
|
|
|
#define ASSERT_IS_BACKGROUND_THREAD_TRAMPOLINE(x) assert_is_background_thread(x)
|
|
|
|
#define ASSERT_IS_BACKGROUND_THREAD() ASSERT_IS_BACKGROUND_THREAD_TRAMPOLINE(__FUNCTION__)
|
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Useful macro for asserting that a lock is locked. This doesn't check whether this thread locked
|
|
|
|
/// it, which it would be nice if it did, but here it is anyways.
|
2018-12-31 02:15:49 +00:00
|
|
|
void assert_is_locked(void *mutex, const char *who, const char *caller);
|
2020-04-08 23:56:59 +00:00
|
|
|
#define ASSERT_IS_LOCKED(x) assert_is_locked(reinterpret_cast<void *>(&x), #x, __FUNCTION__)
|
2005-09-20 13:26:39 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Format the specified size (in bytes, kilobytes, etc.) into the specified stringbuffer.
|
2012-03-05 18:18:42 +00:00
|
|
|
wcstring format_size(long long sz);
|
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Version of format_size that does not allocate memory.
|
2012-03-05 18:18:42 +00:00
|
|
|
void format_size_safe(char buff[128], unsigned long long sz);
|
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Our crappier versions of debug which is guaranteed to not allocate any memory, or do anything
|
|
|
|
/// other than call write(). This is useful after a call to fork() with threads.
|
2019-11-19 02:34:50 +00:00
|
|
|
void debug_safe(int level, const char *msg, const char *param1 = nullptr,
|
|
|
|
const char *param2 = nullptr, const char *param3 = nullptr,
|
|
|
|
const char *param4 = nullptr, const char *param5 = nullptr,
|
|
|
|
const char *param6 = nullptr, const char *param7 = nullptr,
|
|
|
|
const char *param8 = nullptr, const char *param9 = nullptr,
|
|
|
|
const char *param10 = nullptr, const char *param11 = nullptr,
|
|
|
|
const char *param12 = nullptr);
|
2012-03-05 18:18:42 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Writes out a long safely.
|
2014-01-12 21:53:59 +00:00
|
|
|
void format_long_safe(char buff[64], long val);
|
|
|
|
void format_long_safe(wchar_t buff[64], long val);
|
2019-02-04 00:06:10 +00:00
|
|
|
void format_ullong_safe(wchar_t buff[64], unsigned long long val);
|
2012-03-05 18:18:42 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// "Narrows" a wide character string. This just grabs any ASCII characters and trunactes.
|
2016-02-28 09:38:28 +00:00
|
|
|
void narrow_string_safe(char buff[64], const wchar_t *s);
|
|
|
|
|
2018-12-31 02:15:49 +00:00
|
|
|
typedef std::lock_guard<std::mutex> scoped_lock;
|
2017-08-18 19:26:35 +00:00
|
|
|
typedef std::lock_guard<std::recursive_mutex> scoped_rlock;
|
2013-02-22 14:34:30 +00:00
|
|
|
|
2017-01-29 20:37:04 +00:00
|
|
|
// An object wrapping a scoped lock and a value
|
|
|
|
// This is returned from owning_lock.acquire()
|
|
|
|
// Sample usage:
|
|
|
|
// owning_lock<string> locked_name;
|
|
|
|
// acquired_lock<string> name = name.acquire();
|
|
|
|
// name.value = "derp"
|
|
|
|
//
|
|
|
|
// Or for simple cases:
|
|
|
|
// name.acquire().value = "derp"
|
|
|
|
//
|
2019-05-10 16:10:43 +00:00
|
|
|
template <typename Data>
|
2017-01-29 20:37:04 +00:00
|
|
|
class acquired_lock {
|
2017-02-08 05:52:35 +00:00
|
|
|
template <typename T>
|
2017-01-29 20:37:04 +00:00
|
|
|
friend class owning_lock;
|
|
|
|
|
2019-06-15 00:18:43 +00:00
|
|
|
template <typename T>
|
|
|
|
friend class acquired_lock;
|
|
|
|
|
|
|
|
acquired_lock(std::mutex &lk, Data *v) : lock(lk), value(v) {}
|
|
|
|
acquired_lock(std::unique_lock<std::mutex> &&lk, Data *v) : lock(std::move(lk)), value(v) {}
|
|
|
|
|
|
|
|
std::unique_lock<std::mutex> lock;
|
2019-05-10 16:10:43 +00:00
|
|
|
Data *value;
|
2018-09-01 20:11:42 +00:00
|
|
|
|
2017-02-08 05:52:35 +00:00
|
|
|
public:
|
2018-09-01 20:11:42 +00:00
|
|
|
// No copying, move construction only
|
2017-01-29 20:37:04 +00:00
|
|
|
acquired_lock &operator=(const acquired_lock &) = delete;
|
|
|
|
acquired_lock(const acquired_lock &) = delete;
|
|
|
|
acquired_lock(acquired_lock &&) = default;
|
|
|
|
acquired_lock &operator=(acquired_lock &&) = default;
|
|
|
|
|
2019-05-10 16:10:43 +00:00
|
|
|
Data *operator->() { return value; }
|
|
|
|
const Data *operator->() const { return value; }
|
|
|
|
Data &operator*() { return *value; }
|
|
|
|
const Data &operator*() const { return *value; }
|
|
|
|
|
2019-06-15 00:18:43 +00:00
|
|
|
/// Implicit conversion to const version.
|
|
|
|
operator acquired_lock<const Data>() {
|
|
|
|
// We're about to give up our lock, don't hold onto the data.
|
|
|
|
const Data *cvalue = value;
|
|
|
|
value = nullptr;
|
|
|
|
return acquired_lock<const Data>(std::move(lock), cvalue);
|
|
|
|
}
|
|
|
|
|
2019-05-10 16:10:43 +00:00
|
|
|
/// Create from a global lock.
|
|
|
|
/// This is used in weird cases where a global lock protects more than one piece of data.
|
|
|
|
static acquired_lock from_global(std::mutex &lk, Data *v) { return acquired_lock{lk, v}; }
|
2019-05-31 16:13:21 +00:00
|
|
|
|
|
|
|
/// \return a reference to the lock, for use with a condition variable.
|
|
|
|
std::unique_lock<std::mutex> &get_lock() { return lock; }
|
2017-01-29 20:37:04 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// A lock that owns a piece of data
|
|
|
|
// Access to the data is only provided by taking the lock
|
2019-04-27 19:04:36 +00:00
|
|
|
template <typename Data>
|
2017-01-29 20:37:04 +00:00
|
|
|
class owning_lock {
|
|
|
|
// No copying
|
|
|
|
owning_lock &operator=(const scoped_lock &) = delete;
|
|
|
|
owning_lock(const scoped_lock &) = delete;
|
|
|
|
owning_lock(owning_lock &&) = default;
|
|
|
|
owning_lock &operator=(owning_lock &&) = default;
|
|
|
|
|
2018-12-31 02:15:49 +00:00
|
|
|
std::mutex lock;
|
2019-04-27 19:04:36 +00:00
|
|
|
Data data;
|
2017-01-29 20:37:04 +00:00
|
|
|
|
2017-02-08 05:52:35 +00:00
|
|
|
public:
|
2019-04-27 19:04:36 +00:00
|
|
|
owning_lock(Data &&d) : data(std::move(d)) {}
|
2019-05-12 19:33:13 +00:00
|
|
|
owning_lock(const Data &d) : data(d) {}
|
2017-01-29 20:37:04 +00:00
|
|
|
owning_lock() : data() {}
|
|
|
|
|
2019-04-27 19:04:36 +00:00
|
|
|
acquired_lock<Data> acquire() { return {lock, &data}; }
|
2017-01-29 20:37:04 +00:00
|
|
|
};
|
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// A scoped manager to save the current value of some variable, and optionally set it to a new
|
|
|
|
/// value. On destruction it restores the variable to its old value.
|
|
|
|
///
|
|
|
|
/// This can be handy when there are multiple code paths to exit a block.
|
2013-02-22 14:34:30 +00:00
|
|
|
template <typename T>
|
2016-04-27 23:10:14 +00:00
|
|
|
class scoped_push {
|
|
|
|
T *const ref;
|
2013-02-22 14:34:30 +00:00
|
|
|
T saved_value;
|
|
|
|
bool restored;
|
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
public:
|
|
|
|
explicit scoped_push(T *r) : ref(r), saved_value(*r), restored(false) {}
|
2013-02-22 14:34:30 +00:00
|
|
|
|
2017-01-27 00:14:50 +00:00
|
|
|
scoped_push(T *r, T new_value) : ref(r), restored(false) {
|
|
|
|
saved_value = std::move(*ref);
|
|
|
|
*ref = std::move(new_value);
|
2013-02-22 14:34:30 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
~scoped_push() { restore(); }
|
2013-02-22 14:34:30 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
void restore() {
|
|
|
|
if (!restored) {
|
2017-01-27 00:14:50 +00:00
|
|
|
*ref = std::move(saved_value);
|
2013-02-27 20:03:30 +00:00
|
|
|
restored = true;
|
|
|
|
}
|
2013-02-22 14:34:30 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-09-01 21:05:59 +00:00
|
|
|
/// A helper class for managing and automatically closing a file descriptor.
|
|
|
|
class autoclose_fd_t {
|
|
|
|
int fd_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
// Closes the fd if not already closed.
|
|
|
|
void close();
|
|
|
|
|
|
|
|
// Returns the fd.
|
|
|
|
int fd() const { return fd_; }
|
|
|
|
|
|
|
|
// Returns the fd, transferring ownership to the caller.
|
|
|
|
int acquire() {
|
|
|
|
int temp = fd_;
|
|
|
|
fd_ = -1;
|
|
|
|
return temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Resets to a new fd, taking ownership.
|
|
|
|
void reset(int fd) {
|
|
|
|
if (fd == fd_) return;
|
|
|
|
close();
|
|
|
|
fd_ = fd;
|
|
|
|
}
|
|
|
|
|
2019-02-01 00:05:42 +00:00
|
|
|
// \return if this has a valid fd.
|
|
|
|
bool valid() const { return fd_ >= 0; }
|
|
|
|
|
2018-09-01 21:05:59 +00:00
|
|
|
autoclose_fd_t(const autoclose_fd_t &) = delete;
|
|
|
|
void operator=(const autoclose_fd_t &) = delete;
|
|
|
|
autoclose_fd_t(autoclose_fd_t &&rhs) : fd_(rhs.fd_) { rhs.fd_ = -1; }
|
|
|
|
|
|
|
|
void operator=(autoclose_fd_t &&rhs) {
|
|
|
|
close();
|
|
|
|
std::swap(this->fd_, rhs.fd_);
|
|
|
|
}
|
|
|
|
|
|
|
|
explicit autoclose_fd_t(int fd = -1) : fd_(fd) {}
|
|
|
|
~autoclose_fd_t() { close(); }
|
|
|
|
};
|
|
|
|
|
2020-01-29 21:55:10 +00:00
|
|
|
/// Close a file descriptor \p fd, retrying on EINTR.
|
|
|
|
void exec_close(int fd);
|
|
|
|
|
2011-12-27 03:18:46 +00:00
|
|
|
wcstring format_string(const wchar_t *format, ...);
|
2012-02-10 02:43:36 +00:00
|
|
|
wcstring vformat_string(const wchar_t *format, va_list va_orig);
|
2012-02-22 18:51:06 +00:00
|
|
|
void append_format(wcstring &str, const wchar_t *format, ...);
|
2019-11-19 00:54:36 +00:00
|
|
|
void append_formatv(wcstring &target, const wchar_t *format, va_list va_orig);
|
2011-12-27 03:18:46 +00:00
|
|
|
|
2018-01-31 05:43:05 +00:00
|
|
|
#ifdef HAVE_STD__MAKE_UNIQUE
|
2017-01-22 08:32:08 +00:00
|
|
|
using std::make_unique;
|
|
|
|
#else
|
2017-01-21 23:02:41 +00:00
|
|
|
/// make_unique implementation
|
2017-01-27 04:00:43 +00:00
|
|
|
template <typename T, typename... Args>
|
2020-11-22 13:39:48 +00:00
|
|
|
std::unique_ptr<T> make_unique(Args &&...args) {
|
2017-01-21 23:02:41 +00:00
|
|
|
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
|
|
|
}
|
2017-01-22 08:32:08 +00:00
|
|
|
#endif
|
2017-01-21 23:02:41 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// This functions returns the end of the quoted substring beginning at \c in. The type of quoting
|
|
|
|
/// character is detemrined by examining \c in. Returns 0 on error.
|
|
|
|
///
|
|
|
|
/// \param in the position of the opening quote.
|
2019-11-19 00:54:36 +00:00
|
|
|
wchar_t *quote_end(const wchar_t *pos);
|
2005-09-20 13:26:39 +00:00
|
|
|
|
2016-06-04 02:05:13 +00:00
|
|
|
/// This function should be called after calling `setlocale()` to perform fish specific locale
|
|
|
|
/// initialization.
|
|
|
|
void fish_setlocale();
|
2005-09-20 13:26:39 +00:00
|
|
|
|
2019-02-06 07:20:43 +00:00
|
|
|
/// Call read, blocking and repeating on EINTR. Exits on EAGAIN.
|
|
|
|
/// \return the number of bytes read, or 0 on EOF. On EAGAIN, returns -1 if nothing was read.
|
2012-08-04 22:11:43 +00:00
|
|
|
long read_blocked(int fd, void *buf, size_t count);
|
2005-09-20 13:26:39 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Loop a write request while failure is non-critical. Return -1 and set errno in case of critical
|
|
|
|
/// error.
|
2012-01-14 11:41:50 +00:00
|
|
|
ssize_t write_loop(int fd, const char *buff, size_t count);
|
2009-02-22 20:28:52 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Loop a read request while failure is non-critical. Return -1 and set errno in case of critical
|
|
|
|
/// error.
|
2012-03-01 01:55:50 +00:00
|
|
|
ssize_t read_loop(int fd, void *buff, size_t count);
|
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Replace special characters with backslash escape sequences. Newline is replaced with \n, etc.
|
|
|
|
///
|
|
|
|
/// \param in The string to be escaped
|
|
|
|
/// \param flags Flags to control the escaping
|
|
|
|
/// \return The escaped string
|
2017-06-21 04:55:16 +00:00
|
|
|
wcstring escape_string(const wchar_t *in, escape_flags_t flags,
|
2017-06-24 06:19:09 +00:00
|
|
|
escape_string_style_t style = STRING_STYLE_SCRIPT);
|
2017-06-21 04:55:16 +00:00
|
|
|
wcstring escape_string(const wcstring &in, escape_flags_t flags,
|
2017-06-24 06:19:09 +00:00
|
|
|
escape_string_style_t style = STRING_STYLE_SCRIPT);
|
2005-09-20 13:26:39 +00:00
|
|
|
|
2018-06-23 20:15:32 +00:00
|
|
|
/// \return a string representation suitable for debugging (not for presenting to the user). This
|
|
|
|
/// replaces non-ASCII characters with either tokens like <BRACE_SEP> or <\xfdd7>. No other escapes
|
|
|
|
/// are made (i.e. this is a lossy escape).
|
|
|
|
wcstring debug_escape(const wcstring &in);
|
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Expand backslashed escapes and substitute them with their unescaped counterparts. Also
|
|
|
|
/// optionally change the wildcards, the tilde character and a few more into constants which are
|
|
|
|
/// defined in a private use area of Unicode. This assumes wchar_t is a unicode character set.
|
2005-09-20 13:26:39 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Given a null terminated string starting with a backslash, read the escape as if it is unquoted,
|
2018-09-28 02:22:55 +00:00
|
|
|
/// appending to result. Return the number of characters consumed, or none() on error.
|
|
|
|
maybe_t<size_t> read_unquoted_escape(const wchar_t *input, wcstring *result, bool allow_incomplete,
|
|
|
|
bool unescape_special);
|
2015-09-12 19:59:40 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Unescapes a string in-place. A true result indicates the string was unescaped, a false result
|
|
|
|
/// indicates the string was unmodified.
|
2013-11-25 06:57:49 +00:00
|
|
|
bool unescape_string_in_place(wcstring *str, unescape_flags_t escape_special);
|
|
|
|
|
2017-06-23 03:47:54 +00:00
|
|
|
/// Reverse the effects of calling `escape_string`. Returns the unescaped value by reference. On
|
|
|
|
/// failure, the output is set to an empty string.
|
|
|
|
bool unescape_string(const wchar_t *input, wcstring *output, unescape_flags_t escape_special,
|
|
|
|
escape_string_style_t style = STRING_STYLE_SCRIPT);
|
|
|
|
|
|
|
|
bool unescape_string(const wcstring &input, wcstring *output, unescape_flags_t escape_special,
|
|
|
|
escape_string_style_t style = STRING_STYLE_SCRIPT);
|
2011-12-27 03:18:46 +00:00
|
|
|
|
2020-06-08 01:47:27 +00:00
|
|
|
/// Write the given paragraph of output, redoing linebreaks to fit \p termsize.
|
|
|
|
wcstring reformat_for_screen(const wcstring &msg, const termsize_t &termsize);
|
2006-01-15 11:58:05 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Print a short message about how to file a bug report to stderr.
|
2006-11-17 14:58:25 +00:00
|
|
|
void bugreport();
|
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Return the number of seconds from the UNIX epoch, with subsecond precision. This function uses
|
2016-06-25 02:25:48 +00:00
|
|
|
/// the gettimeofday function and will have the same precision as that function.
|
2009-02-02 22:46:45 +00:00
|
|
|
double timef();
|
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Call the following function early in main to set the main thread. This is our replacement for
|
|
|
|
/// pthread_main_np().
|
2012-01-05 21:58:48 +00:00
|
|
|
void set_main_thread();
|
2012-03-19 18:52:18 +00:00
|
|
|
bool is_main_thread();
|
2012-01-05 21:58:48 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Configures thread assertions for testing.
|
2012-05-14 03:19:02 +00:00
|
|
|
void configure_thread_assertions_for_testing();
|
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Set up a guard to complain if we try to do certain things (like take a lock) after calling fork.
|
2012-02-28 02:43:24 +00:00
|
|
|
void setup_fork_guards(void);
|
2012-01-05 21:58:48 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Save the value of tcgetpgrp so we can restore it on exit.
|
2020-05-31 21:11:39 +00:00
|
|
|
void save_term_foreground_process_group();
|
|
|
|
void restore_term_foreground_process_group_for_exit();
|
2012-11-18 10:16:14 +00:00
|
|
|
|
2016-04-27 23:10:14 +00:00
|
|
|
/// Return whether we are the child of a fork.
|
2012-02-28 02:43:24 +00:00
|
|
|
bool is_forked_child(void);
|
|
|
|
void assert_is_not_forked_child(const char *who);
|
|
|
|
#define ASSERT_IS_NOT_FORKED_CHILD_TRAMPOLINE(x) assert_is_not_forked_child(x)
|
|
|
|
#define ASSERT_IS_NOT_FORKED_CHILD() ASSERT_IS_NOT_FORKED_CHILD_TRAMPOLINE(__FUNCTION__)
|
2009-02-02 22:46:45 +00:00
|
|
|
|
2019-02-14 23:53:07 +00:00
|
|
|
/// Determines if we are running under Microsoft's Windows Subsystem for Linux to work around
|
|
|
|
/// some known limitations and/or bugs.
|
2018-03-09 20:40:35 +00:00
|
|
|
/// See https://github.com/Microsoft/WSL/issues/423 and Microsoft/WSL#2997
|
2019-02-14 23:53:07 +00:00
|
|
|
bool is_windows_subsystem_for_linux();
|
2017-12-25 00:29:12 +00:00
|
|
|
|
2019-01-02 06:12:07 +00:00
|
|
|
/// Detect if we are running under Cygwin or Cgywin64
|
|
|
|
constexpr bool is_cygwin() {
|
2019-01-22 02:06:16 +00:00
|
|
|
#ifdef __CYGWIN__
|
2019-01-02 06:12:07 +00:00
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2012-03-01 01:55:50 +00:00
|
|
|
extern "C" {
|
2019-02-10 12:20:01 +00:00
|
|
|
[[gnu::noinline]] void debug_thread_error(void);
|
2012-03-01 01:55:50 +00:00
|
|
|
}
|
|
|
|
|
2016-05-16 21:30:31 +00:00
|
|
|
/// Converts from wide char to digit in the specified base. If d is not a valid digit in the
|
|
|
|
/// specified base, return -1.
|
|
|
|
long convert_digit(wchar_t d, int base);
|
|
|
|
|
2016-10-09 21:38:26 +00:00
|
|
|
/// This is a macro that can be used to silence "unused parameter" warnings from the compiler for
|
|
|
|
/// functions which need to accept parameters they do not use because they need to be compatible
|
|
|
|
/// with an interface. It's similar to the Python idiom of doing `_ = expr` at the top of a
|
|
|
|
/// function in the same situation.
|
2016-10-11 02:52:22 +00:00
|
|
|
#define UNUSED(expr) \
|
|
|
|
do { \
|
|
|
|
(void)(expr); \
|
|
|
|
} while (0)
|
2016-10-09 21:38:26 +00:00
|
|
|
|
2016-10-17 23:23:29 +00:00
|
|
|
// Return true if the character is in a range reserved for fish's private use.
|
|
|
|
bool fish_reserved_codepoint(wchar_t c);
|
2016-11-08 23:30:52 +00:00
|
|
|
|
2016-11-11 23:26:16 +00:00
|
|
|
/// Used for constructing mappings between enums and strings. The resulting array must be sorted
|
|
|
|
/// according to the `str` member since str_to_enum() does a binary search. Also the last entry must
|
|
|
|
/// have NULL for the `str` member and the default value for `val` to be returned if the string
|
|
|
|
/// isn't found.
|
2016-11-08 23:30:52 +00:00
|
|
|
template <typename T>
|
|
|
|
struct enum_map {
|
|
|
|
T val;
|
|
|
|
const wchar_t *const str;
|
|
|
|
};
|
|
|
|
|
2020-02-29 23:56:52 +00:00
|
|
|
/// Given a string return the matching enum. Return the sentinel enum if no match is made. The map
|
2016-11-11 23:26:16 +00:00
|
|
|
/// must be sorted by the `str` member. A binary search is twice as fast as a linear search with 16
|
|
|
|
/// elements in the map.
|
2016-11-08 23:30:52 +00:00
|
|
|
template <typename T>
|
2016-11-11 23:26:16 +00:00
|
|
|
static T str_to_enum(const wchar_t *name, const enum_map<T> map[], int len) {
|
|
|
|
// Ignore the sentinel value when searching as it is the "not found" value.
|
|
|
|
size_t left = 0, right = len - 1;
|
|
|
|
|
|
|
|
while (left < right) {
|
|
|
|
size_t mid = left + (right - left) / 2;
|
2019-03-12 21:06:01 +00:00
|
|
|
int cmp = std::wcscmp(name, map[mid].str);
|
2016-11-11 23:26:16 +00:00
|
|
|
if (cmp < 0) {
|
|
|
|
right = mid; // name was smaller than mid
|
|
|
|
} else if (cmp > 0) {
|
|
|
|
left = mid + 1; // name was larger than mid
|
|
|
|
} else {
|
|
|
|
return map[mid].val; // found it
|
2016-11-08 23:30:52 +00:00
|
|
|
}
|
|
|
|
}
|
2016-11-11 23:26:16 +00:00
|
|
|
return map[len - 1].val; // return the sentinel value
|
|
|
|
}
|
2016-11-08 23:30:52 +00:00
|
|
|
|
|
|
|
/// Given an enum return the matching string.
|
|
|
|
template <typename T>
|
|
|
|
static const wchar_t *enum_to_str(T enum_val, const enum_map<T> map[]) {
|
|
|
|
for (const enum_map<T> *entry = map; entry->str; entry++) {
|
|
|
|
if (enum_val == entry->val) {
|
|
|
|
return entry->str;
|
|
|
|
}
|
|
|
|
}
|
2019-11-19 02:34:50 +00:00
|
|
|
return nullptr;
|
2016-11-08 23:30:52 +00:00
|
|
|
};
|
|
|
|
|
2017-01-18 21:54:54 +00:00
|
|
|
void redirect_tty_output();
|
|
|
|
|
2019-02-06 04:36:38 +00:00
|
|
|
std::string get_path_to_tmp_dir();
|
|
|
|
|
2017-04-20 06:43:02 +00:00
|
|
|
bool valid_var_name_char(wchar_t chr);
|
|
|
|
bool valid_var_name(const wcstring &str);
|
|
|
|
bool valid_func_name(const wcstring &str);
|
2017-05-02 07:39:50 +00:00
|
|
|
|
|
|
|
// Return values (`$status` values for fish scripts) for various situations.
|
|
|
|
enum {
|
|
|
|
/// The status code used for normal exit in a command.
|
2017-05-04 07:18:02 +00:00
|
|
|
STATUS_CMD_OK = 0,
|
2017-05-02 07:39:50 +00:00
|
|
|
/// The status code used for failure exit in a command (but not if the args were invalid).
|
2017-05-04 07:18:02 +00:00
|
|
|
STATUS_CMD_ERROR = 1,
|
2018-12-16 05:05:27 +00:00
|
|
|
/// The status code used for invalid arguments given to a command. This is distinct from valid
|
|
|
|
/// arguments that might result in a command failure. An invalid args condition is something
|
|
|
|
/// like an unrecognized flag, missing or too many arguments, an invalid integer, etc. But
|
|
|
|
STATUS_INVALID_ARGS = 2,
|
|
|
|
|
2017-05-02 07:39:50 +00:00
|
|
|
/// The status code used when a command was not found.
|
2017-05-04 07:18:02 +00:00
|
|
|
STATUS_CMD_UNKNOWN = 127,
|
2017-05-02 07:39:50 +00:00
|
|
|
/// TODO: Figure out why we have two distinct failure codes for when an external command cannot
|
|
|
|
/// be run.
|
|
|
|
///
|
|
|
|
/// The status code used when an external command can not be run.
|
|
|
|
STATUS_NOT_EXECUTABLE = 126,
|
|
|
|
/// The status code used when an external command can not be run.
|
|
|
|
STATUS_EXEC_FAIL = 125,
|
|
|
|
|
|
|
|
/// The status code used when a wildcard had no matches.
|
|
|
|
STATUS_UNMATCHED_WILDCARD = 124,
|
|
|
|
/// The status code used when illegal command name is encountered.
|
|
|
|
STATUS_ILLEGAL_CMD = 123,
|
|
|
|
/// The status code used when `read` is asked to consume too much data.
|
|
|
|
STATUS_READ_TOO_MUCH = 122,
|
2020-01-24 01:34:46 +00:00
|
|
|
/// The status code when an expansion fails, for example, "$foo["
|
|
|
|
STATUS_EXPAND_ERROR = 121,
|
2017-05-02 07:39:50 +00:00
|
|
|
};
|
2017-08-12 14:54:26 +00:00
|
|
|
|
|
|
|
/* Normally casting an expression to void discards its value, but GCC
|
|
|
|
versions 3.4 and newer have __attribute__ ((__warn_unused_result__))
|
|
|
|
which may cause unwanted diagnostics in that case. Use __typeof__
|
|
|
|
and __extension__ to work around the problem, if the workaround is
|
|
|
|
known to be needed. */
|
|
|
|
#if 3 < __GNUC__ + (4 <= __GNUC_MINOR__)
|
2017-08-18 19:26:35 +00:00
|
|
|
#define ignore_result(x) \
|
|
|
|
(__extension__({ \
|
|
|
|
__typeof__(x) __x = (x); \
|
|
|
|
(void)__x; \
|
|
|
|
}))
|
2017-08-12 14:54:26 +00:00
|
|
|
#else
|
2017-08-18 19:26:35 +00:00
|
|
|
#define ignore_result(x) ((void)(x))
|
2017-08-12 14:54:26 +00:00
|
|
|
#endif
|
|
|
|
|
2017-08-19 16:55:06 +00:00
|
|
|
// Custom hash function used by unordered_map/unordered_set when key is const
|
|
|
|
#ifndef CONST_WCSTRING_HASH
|
|
|
|
#define CONST_WCSTRING_HASH 1
|
|
|
|
namespace std {
|
2017-08-19 18:47:16 +00:00
|
|
|
template <>
|
|
|
|
struct hash<const wcstring> {
|
2017-08-19 23:27:24 +00:00
|
|
|
std::size_t operator()(const wcstring &w) const {
|
|
|
|
std::hash<wcstring> hasher;
|
2020-05-01 20:30:22 +00:00
|
|
|
return hasher(w);
|
2017-08-19 23:27:24 +00:00
|
|
|
}
|
2017-08-19 18:47:16 +00:00
|
|
|
};
|
2018-09-28 02:28:39 +00:00
|
|
|
} // namespace std
|
2017-08-19 16:55:06 +00:00
|
|
|
#endif
|
2017-08-19 23:27:24 +00:00
|
|
|
|
2018-10-10 03:33:20 +00:00
|
|
|
/// Get the absolute path to the fish executable itself
|
2019-11-19 00:54:36 +00:00
|
|
|
std::string get_executable_path(const char *argv0);
|
2018-10-10 03:33:20 +00:00
|
|
|
|
2018-10-02 22:10:14 +00:00
|
|
|
/// A RAII wrapper for resources that don't recur, so we don't have to create a separate RAII
|
|
|
|
/// wrapper for each function. Avoids needing to call "return cleanup()" or similar / everywhere.
|
|
|
|
struct cleanup_t {
|
2019-05-05 10:09:25 +00:00
|
|
|
private:
|
2018-10-02 22:10:14 +00:00
|
|
|
const std::function<void()> cleanup;
|
2019-05-05 10:09:25 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
cleanup_t(std::function<void()> exit_actions) : cleanup{std::move(exit_actions)} {}
|
|
|
|
~cleanup_t() { cleanup(); }
|
2018-10-02 22:10:14 +00:00
|
|
|
};
|
|
|
|
|
2019-01-30 01:59:41 +00:00
|
|
|
bool is_console_session();
|
|
|
|
|
2019-05-05 10:09:25 +00:00
|
|
|
#endif // FISH_COMMON_H
|