mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-26 10:43:47 +08:00
make comments Xcode friendly
The OS X Xcode IDE has a weird requirement that block comments preceding a function or class definition must begin with three slashes rather than two if you want the comment displayed in the "Quick Help" window.
This commit is contained in:
parent
9aeed0dc06
commit
bd4622a0d0
|
@ -84,6 +84,8 @@ The first word of global variable names should generally be `fish` for public va
|
|||
|
||||
1. Comments should always use the C++ style; i.e., each line of the comment should begin with a `//` and should be limited to 100 characters. Comments that do not begin a line should be separated from the previous text by two spaces.
|
||||
|
||||
1. Comments that document the purpose of a function or class should begin with three slashes, `///`, so that OS X Xcode (and possibly other ideas) will extract the comment and show it in the "Quick Help" window when the cursor is on the symbol.
|
||||
|
||||
## Testing
|
||||
|
||||
The source code for fish includes a large collection of tests. If you are making any changes to fish, running these tests is highly recommended to make sure the behaviour remains consistent.
|
||||
|
|
|
@ -122,7 +122,7 @@ static bool script_name_precedes_script_name(const builtin_script_t &script1,
|
|||
return wcscmp(script1.name, script2.name) < 0;
|
||||
}
|
||||
|
||||
// Check whether the given command is loaded.
|
||||
/// Check whether the given command is loaded.
|
||||
bool autoload_t::has_tried_loading(const wcstring &cmd) {
|
||||
scoped_lock locker(lock);
|
||||
autoload_function_t *func = this->get_node(cmd);
|
||||
|
@ -150,17 +150,17 @@ autoload_function_t *autoload_t::get_autoloaded_function_with_creation(const wcs
|
|||
return func;
|
||||
}
|
||||
|
||||
// This internal helper function does all the real work. By using two functions, the internal
|
||||
// function can return on various places in the code, and the caller can take care of various
|
||||
// cleanup work.
|
||||
//
|
||||
// cmd: the command name ('grep')
|
||||
// really_load: whether to actually parse it as a function, or just check it it exists
|
||||
// reload: whether to reload it if it's already loaded
|
||||
// path_list: the set of paths to check
|
||||
//
|
||||
// Result: if really_load is true, returns whether the function was loaded. Otherwise returns
|
||||
// whether the function existed.
|
||||
/// This internal helper function does all the real work. By using two functions, the internal
|
||||
/// function can return on various places in the code, and the caller can take care of various
|
||||
/// cleanup work.
|
||||
///
|
||||
/// cmd: the command name ('grep')
|
||||
/// really_load: whether to actually parse it as a function, or just check it it exists
|
||||
/// reload: whether to reload it if it's already loaded
|
||||
/// path_list: the set of paths to check
|
||||
///
|
||||
/// Result: if really_load is true, returns whether the function was loaded. Otherwise returns
|
||||
/// whether the function existed.
|
||||
bool autoload_t::locate_file_and_maybe_load_it(const wcstring &cmd, bool really_load, bool reload,
|
||||
const wcstring_list_t &path_list) {
|
||||
// Note that we are NOT locked in this function!
|
||||
|
|
146
src/builtin.cpp
146
src/builtin.cpp
|
@ -71,7 +71,7 @@
|
|||
// The send stuff to foreground message.
|
||||
#define FG_MSG _(L"Send job %d, '%ls' to foreground\n")
|
||||
|
||||
// Datastructure to describe a builtin.
|
||||
/// Datastructure to describe a builtin.
|
||||
struct builtin_data_t {
|
||||
// Name of the builtin.
|
||||
const wchar_t *name;
|
||||
|
@ -92,7 +92,7 @@ bool builtin_data_t::operator<(const builtin_data_t *other) const {
|
|||
return wcscmp(this->name, other->name) < 0;
|
||||
}
|
||||
|
||||
// Counts the number of non null pointers in the specified array.
|
||||
/// Counts the number of non null pointers in the specified array.
|
||||
int builtin_count_args(const wchar_t *const *argv) {
|
||||
int argc = 1;
|
||||
while (argv[argc] != NULL) {
|
||||
|
@ -101,8 +101,8 @@ int builtin_count_args(const wchar_t *const *argv) {
|
|||
return argc;
|
||||
}
|
||||
|
||||
// This function works like wperror, but it prints its result into the streams.err string instead of
|
||||
// to stderr. Used by the builtin commands.
|
||||
/// This function works like wperror, but it prints its result into the streams.err string instead
|
||||
/// to stderr. Used by the builtin commands.
|
||||
static void builtin_wperror(const wchar_t *s, io_streams_t &streams) {
|
||||
char *err = strerror(errno);
|
||||
if (s != NULL) {
|
||||
|
@ -116,7 +116,7 @@ static void builtin_wperror(const wchar_t *s, io_streams_t &streams) {
|
|||
}
|
||||
}
|
||||
|
||||
// Count the number of times the specified character occurs in the specified string.
|
||||
/// Count the number of times the specified character occurs in the specified string.
|
||||
static int count_char(const wchar_t *str, wchar_t c) {
|
||||
int res = 0;
|
||||
for (; *str; str++) {
|
||||
|
@ -148,10 +148,10 @@ wcstring builtin_help_get(parser_t &parser, io_streams_t &streams, const wchar_t
|
|||
return out;
|
||||
}
|
||||
|
||||
// Print help for the specified builtin. If \c b is sb_err, also print the line information.
|
||||
//
|
||||
// If \c b is the buffer representing standard error, and the help message is about to be printed to
|
||||
// an interactive screen, it may be shortened to fit the screen.
|
||||
/// Print help for the specified builtin. If \c b is sb_err, also print the line information.
|
||||
///
|
||||
/// If \c b is the buffer representing standard error, and the help message is about to be printed
|
||||
/// to an interactive screen, it may be shortened to fit the screen.
|
||||
void builtin_print_help(parser_t &parser, io_streams_t &streams, const wchar_t *cmd,
|
||||
output_stream_t &b) {
|
||||
bool is_stderr = (&b == &streams.err);
|
||||
|
@ -227,14 +227,14 @@ void builtin_print_help(parser_t &parser, io_streams_t &streams, const wchar_t *
|
|||
}
|
||||
}
|
||||
|
||||
// Perform error reporting for encounter with unknown option.
|
||||
/// Perform error reporting for encounter with unknown option.
|
||||
static void builtin_unknown_option(parser_t &parser, io_streams_t &streams, const wchar_t *cmd,
|
||||
const wchar_t *opt) {
|
||||
streams.err.append_format(BUILTIN_ERR_UNKNOWN, cmd, opt);
|
||||
builtin_print_help(parser, streams, cmd, streams.err);
|
||||
}
|
||||
|
||||
// Perform error reporting for encounter with missing argument.
|
||||
/// Perform error reporting for encounter with missing argument.
|
||||
static void builtin_missing_argument(parser_t &parser, io_streams_t &streams, const wchar_t *cmd,
|
||||
const wchar_t *opt) {
|
||||
streams.err.append_format(BUILTIN_ERR_MISSING, cmd, opt);
|
||||
|
@ -269,8 +269,8 @@ int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv);
|
|||
// builtin_string lives in builtin_string.cpp
|
||||
int builtin_string(parser_t &parser, io_streams_t &streams, wchar_t **argv);
|
||||
|
||||
// List a single key binding.
|
||||
// Returns false if no binding with that sequence and mode exists.
|
||||
/// List a single key binding.
|
||||
/// Returns false if no binding with that sequence and mode exists.
|
||||
static bool builtin_bind_list_one(const wcstring &seq, const wcstring &bind_mode,
|
||||
io_streams_t &streams) {
|
||||
std::vector<wcstring> ecmds;
|
||||
|
@ -317,7 +317,7 @@ static bool builtin_bind_list_one(const wcstring &seq, const wcstring &bind_mode
|
|||
return true;
|
||||
}
|
||||
|
||||
// List all current key bindings.
|
||||
/// List all current key bindings.
|
||||
static void builtin_bind_list(const wchar_t *bind_mode, io_streams_t &streams) {
|
||||
const std::vector<input_mapping_name_t> lst = input_mapping_get_names();
|
||||
|
||||
|
@ -331,10 +331,10 @@ static void builtin_bind_list(const wchar_t *bind_mode, io_streams_t &streams) {
|
|||
}
|
||||
}
|
||||
|
||||
// Print terminfo key binding names to string buffer used for standard output.
|
||||
//
|
||||
// \param all if set, all terminfo key binding names will be printed. If not set, only ones that
|
||||
// are defined for this terminal are printed.
|
||||
/// Print terminfo key binding names to string buffer used for standard output.
|
||||
///
|
||||
/// \param all if set, all terminfo key binding names will be printed. If not set, only ones that
|
||||
/// are defined for this terminal are printed.
|
||||
static void builtin_bind_key_names(int all, io_streams_t &streams) {
|
||||
const wcstring_list_t names = input_terminfo_get_names(!all);
|
||||
for (size_t i = 0; i < names.size(); i++) {
|
||||
|
@ -344,7 +344,7 @@ static void builtin_bind_key_names(int all, io_streams_t &streams) {
|
|||
}
|
||||
}
|
||||
|
||||
// Print all the special key binding functions to string buffer used for standard output.
|
||||
/// Print all the special key binding functions to string buffer used for standard output.
|
||||
static void builtin_bind_function_names(io_streams_t &streams) {
|
||||
wcstring_list_t names = input_function_get_names();
|
||||
|
||||
|
@ -354,7 +354,7 @@ static void builtin_bind_function_names(io_streams_t &streams) {
|
|||
}
|
||||
}
|
||||
|
||||
// Wraps input_terminfo_get_sequence(), appending the correct error messages as needed.
|
||||
/// Wraps input_terminfo_get_sequence(), appending the correct error messages as needed.
|
||||
static int get_terminfo_sequence(const wchar_t *seq, wcstring *out_seq, io_streams_t &streams) {
|
||||
if (input_terminfo_get_sequence(seq, out_seq)) {
|
||||
return 1;
|
||||
|
@ -380,7 +380,7 @@ static int get_terminfo_sequence(const wchar_t *seq, wcstring *out_seq, io_strea
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Add specified key binding.
|
||||
/// Add specified key binding.
|
||||
static int builtin_bind_add(const wchar_t *seq, const wchar_t *const *cmds, size_t cmds_len,
|
||||
const wchar_t *mode, const wchar_t *sets_mode, int terminfo,
|
||||
io_streams_t &streams) {
|
||||
|
@ -399,12 +399,12 @@ static int builtin_bind_add(const wchar_t *seq, const wchar_t *const *cmds, size
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Erase specified key bindings
|
||||
//
|
||||
// \param seq an array of all key bindings to erase
|
||||
// \param all if specified, _all_ key bindings will be erased
|
||||
// \param mode if specified, only bindings from that mode will be erased. If not given and \c all is
|
||||
// \c false, \c DEFAULT_BIND_MODE will be used.
|
||||
/// Erase specified key bindings
|
||||
///
|
||||
/// \param seq an array of all key bindings to erase
|
||||
/// \param all if specified, _all_ key bindings will be erased
|
||||
/// \param mode if specified, only bindings from that mode will be erased. If not given and \c all
|
||||
/// is \c false, \c DEFAULT_BIND_MODE will be used.
|
||||
static int builtin_bind_erase(wchar_t **seq, int all, const wchar_t *mode, int use_terminfo,
|
||||
io_streams_t &streams) {
|
||||
if (all) {
|
||||
|
@ -439,7 +439,7 @@ static int builtin_bind_erase(wchar_t **seq, int all, const wchar_t *mode, int u
|
|||
}
|
||||
}
|
||||
|
||||
// The bind builtin, used for setting character sequences.
|
||||
/// The bind builtin, used for setting character sequences.
|
||||
static int builtin_bind(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
wgetopter_t w;
|
||||
enum { BIND_INSERT, BIND_ERASE, BIND_KEY_NAMES, BIND_FUNCTION_NAMES };
|
||||
|
@ -594,7 +594,7 @@ static int builtin_bind(parser_t &parser, io_streams_t &streams, wchar_t **argv)
|
|||
return res;
|
||||
}
|
||||
|
||||
// The block builtin, used for temporarily blocking events.
|
||||
/// The block builtin, used for temporarily blocking events.
|
||||
static int builtin_block(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
wgetopter_t w;
|
||||
enum {
|
||||
|
@ -699,9 +699,9 @@ static int builtin_block(parser_t &parser, io_streams_t &streams, wchar_t **argv
|
|||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
|
||||
// The builtin builtin, used for giving builtins precedence over functions. Mostly handled by the
|
||||
// parser. All this code does is some additional operational modes, such as printing a list of all
|
||||
// builtins, printing help, etc.
|
||||
/// The builtin builtin, used for giving builtins precedence over functions. Mostly handled by the
|
||||
/// parser. All this code does is some additional operational modes, such as printing a list of all
|
||||
/// builtins, printing help, etc.
|
||||
static int builtin_builtin(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
int argc = builtin_count_args(argv);
|
||||
int list = 0;
|
||||
|
@ -753,7 +753,7 @@ static int builtin_builtin(parser_t &parser, io_streams_t &streams, wchar_t **ar
|
|||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
|
||||
// Implementation of the builtin emit command, used to create events.
|
||||
/// Implementation of the builtin emit command, used to create events.
|
||||
static int builtin_emit(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
wgetopter_t w;
|
||||
int argc = builtin_count_args(argv);
|
||||
|
@ -796,8 +796,8 @@ static int builtin_emit(parser_t &parser, io_streams_t &streams, wchar_t **argv)
|
|||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
|
||||
// Implementation of the builtin 'command'. Actual command running is handled by the parser, this
|
||||
// just processes the flags.
|
||||
/// Implementation of the builtin 'command'. Actual command running is handled by the parser, this
|
||||
/// just processes the flags.
|
||||
static int builtin_command(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
wgetopter_t w;
|
||||
int argc = builtin_count_args(argv);
|
||||
|
@ -856,8 +856,8 @@ static int builtin_command(parser_t &parser, io_streams_t &streams, wchar_t **ar
|
|||
return found ? STATUS_BUILTIN_OK : STATUS_BUILTIN_ERROR;
|
||||
}
|
||||
|
||||
// A generic bultin that only supports showing a help message. This is only a placeholder that
|
||||
// prints the help message. Useful for commands that live in the parser.
|
||||
/// A generic bultin that only supports showing a help message. This is only a placeholder that
|
||||
/// prints the help message. Useful for commands that live in the parser.
|
||||
static int builtin_generic(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
wgetopter_t w;
|
||||
int argc = builtin_count_args(argv);
|
||||
|
@ -898,7 +898,7 @@ static int builtin_generic(parser_t &parser, io_streams_t &streams, wchar_t **ar
|
|||
return STATUS_BUILTIN_ERROR;
|
||||
}
|
||||
|
||||
// Return a definition of the specified function. Used by the functions builtin.
|
||||
/// Return a definition of the specified function. Used by the functions builtin.
|
||||
static wcstring functions_def(const wcstring &name) {
|
||||
CHECK(!name.empty(), L"");
|
||||
wcstring out;
|
||||
|
@ -1004,7 +1004,7 @@ static wcstring functions_def(const wcstring &name) {
|
|||
return out;
|
||||
}
|
||||
|
||||
// The functions builtin, used for listing and erasing functions.
|
||||
/// The functions builtin, used for listing and erasing functions.
|
||||
static int builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
wgetopter_t w;
|
||||
int i;
|
||||
|
@ -1252,12 +1252,12 @@ static unsigned int builtin_echo_digit(wchar_t wc, unsigned int base) {
|
|||
return UINT_MAX;
|
||||
}
|
||||
|
||||
// Parse a numeric escape sequence in str, returning whether we succeeded. Also return the number of
|
||||
// characters consumed and the resulting value. Supported escape sequences:
|
||||
//
|
||||
// \0nnn: octal value, zero to three digits
|
||||
// \nnn: octal value, one to three digits
|
||||
// \xhh: hex value, one to two digits
|
||||
/// Parse a numeric escape sequence in str, returning whether we succeeded. Also return the number
|
||||
/// of characters consumed and the resulting value. Supported escape sequences:
|
||||
///
|
||||
/// \0nnn: octal value, zero to three digits
|
||||
/// \nnn: octal value, one to three digits
|
||||
/// \xhh: hex value, one to two digits
|
||||
static bool builtin_echo_parse_numeric_sequence(const wchar_t *str, size_t *consumed,
|
||||
unsigned char *out_val) {
|
||||
bool success = false;
|
||||
|
@ -1299,10 +1299,10 @@ static bool builtin_echo_parse_numeric_sequence(const wchar_t *str, size_t *cons
|
|||
return success;
|
||||
}
|
||||
|
||||
// The echo builtin.
|
||||
//
|
||||
// Bash only respects -n if it's the first argument. We'll do the same. We also support a new option
|
||||
// -s to mean "no spaces"
|
||||
/// The echo builtin.
|
||||
///
|
||||
/// Bash only respects -n if it's the first argument. We'll do the same. We also support a new
|
||||
/// option -s to mean "no spaces"
|
||||
static int builtin_echo(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
/* Skip first arg */
|
||||
if (!*argv++) return STATUS_BUILTIN_ERROR;
|
||||
|
@ -1453,8 +1453,8 @@ static int builtin_echo(parser_t &parser, io_streams_t &streams, wchar_t **argv)
|
|||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
|
||||
// The pwd builtin. We don't respect -P to resolve symbolic links because we
|
||||
// try to always resolve them.
|
||||
/// The pwd builtin. We don't respect -P to resolve symbolic links because we
|
||||
/// try to always resolve them.
|
||||
static int builtin_pwd(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
wcstring res = wgetcwd();
|
||||
if (res.empty()) {
|
||||
|
@ -1466,7 +1466,7 @@ static int builtin_pwd(parser_t &parser, io_streams_t &streams, wchar_t **argv)
|
|||
}
|
||||
}
|
||||
|
||||
// Adds a function to the function set. It calls into function.cpp to perform any heavy lifting.
|
||||
/// Adds a function to the function set. It calls into function.cpp to perform any heavy lifting.
|
||||
int define_function(parser_t &parser, io_streams_t &streams, const wcstring_list_t &c_args,
|
||||
const wcstring &contents, int definition_line_offset, wcstring *out_err) {
|
||||
wgetopter_t w;
|
||||
|
@ -1811,7 +1811,7 @@ static int builtin_random(parser_t &parser, io_streams_t &streams, wchar_t **arg
|
|||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
|
||||
// The read builtin. Reads from stdin and stores the values in environment variables.
|
||||
/// The read builtin. Reads from stdin and stores the values in environment variables.
|
||||
static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
wgetopter_t w;
|
||||
wcstring buff;
|
||||
|
@ -2134,7 +2134,7 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv)
|
|||
return exit_res;
|
||||
}
|
||||
|
||||
// The status builtin. Gives various status information on fish.
|
||||
/// The status builtin. Gives various status information on fish.
|
||||
static int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
wgetopter_t w;
|
||||
enum {
|
||||
|
@ -2304,7 +2304,7 @@ static int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **arg
|
|||
return res;
|
||||
}
|
||||
|
||||
// The exit builtin. Calls reader_exit to exit and returns the value specified.
|
||||
/// The exit builtin. Calls reader_exit to exit and returns the value specified.
|
||||
static int builtin_exit(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
int argc = builtin_count_args(argv);
|
||||
|
||||
|
@ -2337,8 +2337,8 @@ static int builtin_exit(parser_t &parser, io_streams_t &streams, wchar_t **argv)
|
|||
return (int)ec;
|
||||
}
|
||||
|
||||
// The cd builtin. Changes the current directory to the one specified or to $HOME if none is
|
||||
// specified. The directory can be relative to any directory in the CDPATH variable.
|
||||
/// The cd builtin. Changes the current directory to the one specified or to $HOME if none is
|
||||
/// specified. The directory can be relative to any directory in the CDPATH variable.
|
||||
static int builtin_cd(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
env_var_t dir_in;
|
||||
wcstring dir;
|
||||
|
@ -2404,7 +2404,7 @@ static int builtin_cd(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||
return res;
|
||||
}
|
||||
|
||||
// Implementation of the builtin count command, used to count the number of arguments sent to it.
|
||||
/// Implementation of the builtin count command, used to count the number of arguments sent to it.
|
||||
static int builtin_count(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
int argc;
|
||||
argc = builtin_count_args(argv);
|
||||
|
@ -2412,8 +2412,8 @@ static int builtin_count(parser_t &parser, io_streams_t &streams, wchar_t **argv
|
|||
return !(argc - 1);
|
||||
}
|
||||
|
||||
// Implementation of the builtin contains command, used to check if a specified string is part of a
|
||||
// list.
|
||||
/// Implementation of the builtin contains command, used to check if a specified string is part of
|
||||
/// a list.
|
||||
static int builtin_contains(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
wgetopter_t w;
|
||||
int argc;
|
||||
|
@ -2473,9 +2473,7 @@ static int builtin_contains(parser_t &parser, io_streams_t &streams, wchar_t **a
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
The . (dot) builtin, sometimes called source. Evaluates the contents of a file.
|
||||
*/
|
||||
/// The . (dot) builtin, sometimes called source. Evaluates the contents of a file.
|
||||
static int builtin_source(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
ASSERT_IS_MAIN_THREAD();
|
||||
int fd;
|
||||
|
@ -2539,11 +2537,11 @@ static int builtin_source(parser_t &parser, io_streams_t &streams, wchar_t **arg
|
|||
return res;
|
||||
}
|
||||
|
||||
// Make the specified job the first job of the job list. Moving jobs around in the list makes the
|
||||
// list reflect the order in which the jobs were used.
|
||||
/// Make the specified job the first job of the job list. Moving jobs around in the list makes the
|
||||
/// list reflect the order in which the jobs were used.
|
||||
static void make_first(job_t *j) { job_promote(j); }
|
||||
|
||||
// Builtin for putting a job in the foreground.
|
||||
/// Builtin for putting a job in the foreground.
|
||||
static int builtin_fg(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
job_t *j = NULL;
|
||||
|
||||
|
@ -2632,7 +2630,7 @@ static int builtin_fg(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||
return j != 0;
|
||||
}
|
||||
|
||||
// Helper function for builtin_bg().
|
||||
/// Helper function for builtin_bg().
|
||||
static int send_to_bg(parser_t &parser, io_streams_t &streams, job_t *j, const wchar_t *name) {
|
||||
if (j == 0) {
|
||||
streams.err.append_format(_(L"%ls: Unknown job '%ls'\n"), L"bg", name);
|
||||
|
@ -2654,7 +2652,7 @@ static int send_to_bg(parser_t &parser, io_streams_t &streams, job_t *j, const w
|
|||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
|
||||
// Builtin for putting a job in the background.
|
||||
/// Builtin for putting a job in the background.
|
||||
static int builtin_bg(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
int res = STATUS_BUILTIN_OK;
|
||||
|
||||
|
@ -2700,8 +2698,8 @@ static int builtin_bg(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||
return res;
|
||||
}
|
||||
|
||||
// This function handles both the 'continue' and the 'break' builtins that are used for loop
|
||||
// control.
|
||||
/// This function handles both the 'continue' and the 'break' builtins that are used for loop
|
||||
/// control.
|
||||
static int builtin_break_continue(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
int is_break = (wcscmp(argv[0], L"break") == 0);
|
||||
int argc = builtin_count_args(argv);
|
||||
|
@ -2740,7 +2738,7 @@ static int builtin_break_continue(parser_t &parser, io_streams_t &streams, wchar
|
|||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
|
||||
// Implementation of the builtin breakpoint command, used to launch the interactive debugger.
|
||||
/// Implementation of the builtin breakpoint command, used to launch the interactive debugger.
|
||||
static int builtin_breakpoint(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
parser.push_block(new breakpoint_block_t());
|
||||
|
||||
|
@ -2751,7 +2749,7 @@ static int builtin_breakpoint(parser_t &parser, io_streams_t &streams, wchar_t *
|
|||
return proc_get_last_status();
|
||||
}
|
||||
|
||||
// Function for handling the \c return builtin.
|
||||
/// Function for handling the \c return builtin.
|
||||
static int builtin_return(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
int argc = builtin_count_args(argv);
|
||||
int status = proc_get_last_status();
|
||||
|
@ -2801,7 +2799,7 @@ static int builtin_return(parser_t &parser, io_streams_t &streams, wchar_t **arg
|
|||
return status;
|
||||
}
|
||||
|
||||
// History of commands executed by user.
|
||||
/// History of commands executed by user.
|
||||
static int builtin_history(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
int argc = builtin_count_args(argv);
|
||||
|
||||
|
@ -3079,7 +3077,7 @@ void builtin_destroy() {}
|
|||
|
||||
int builtin_exists(const wcstring &cmd) { return !!builtin_lookup(cmd); }
|
||||
|
||||
// Return true if the specified builtin should handle it's own help, false otherwise.
|
||||
/// Return true if the specified builtin should handle it's own help, false otherwise.
|
||||
static int internal_help(const wchar_t *cmd) {
|
||||
CHECK(cmd, 0);
|
||||
return contains(cmd, L"for", L"while", L"function", L"if", L"end", L"switch", L"case", L"count",
|
||||
|
|
102
src/history.cpp
102
src/history.cpp
|
@ -51,9 +51,9 @@
|
|||
|
||||
namespace {
|
||||
|
||||
// Helper class for certain output. This is basically a string that allows us to ensure we only
|
||||
// flush at record boundaries, and avoids the copying of ostringstream. Have you ever tried to
|
||||
// implement your own streambuf? Total insanity.
|
||||
/// Helper class for certain output. This is basically a string that allows us to ensure we only
|
||||
/// flush at record boundaries, and avoids the copying of ostringstream. Have you ever tried to
|
||||
/// implement your own streambuf? Total insanity.
|
||||
class history_output_buffer_t {
|
||||
// A null-terminated C string.
|
||||
std::vector<char> buffer;
|
||||
|
@ -64,10 +64,10 @@ class history_output_buffer_t {
|
|||
static size_t safe_strlen(const char *s) { return s ? strlen(s) : 0; }
|
||||
|
||||
public:
|
||||
// Add a bit more to HISTORY_OUTPUT_BUFFER_SIZE because we flush once we've exceeded that size.
|
||||
/// Add a bit more to HISTORY_OUTPUT_BUFFER_SIZE because we flush once we've exceeded that size.
|
||||
history_output_buffer_t() : buffer(HISTORY_OUTPUT_BUFFER_SIZE + 128, '\0'), offset(0) {}
|
||||
|
||||
// Append one or more strings.
|
||||
/// Append one or more strings.
|
||||
void append(const char *s1, const char *s2 = NULL, const char *s3 = NULL) {
|
||||
const char *ptrs[4] = {s1, s2, s3, NULL};
|
||||
const size_t lengths[4] = {safe_strlen(s1), safe_strlen(s2), safe_strlen(s3), 0};
|
||||
|
@ -95,14 +95,14 @@ class history_output_buffer_t {
|
|||
assert(buffer.at(buffer.size() - 1) == '\0');
|
||||
}
|
||||
|
||||
// Output to a given fd, resetting our buffer. Returns true on success, false on error.
|
||||
/// Output to a given fd, resetting our buffer. Returns true on success, false on error.
|
||||
bool flush_to_fd(int fd) {
|
||||
bool result = write_loop(fd, &buffer.at(0), offset) >= 0;
|
||||
offset = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Return how much data we've accumulated.
|
||||
/// Return how much data we've accumulated.
|
||||
size_t output_size() const { return offset; }
|
||||
};
|
||||
|
||||
|
@ -126,7 +126,7 @@ class time_profiler_t {
|
|||
}
|
||||
};
|
||||
|
||||
// Lock a file via fcntl; returns true on success, false on failure.
|
||||
/// Lock a file via fcntl; returns true on success, false on failure.
|
||||
static bool history_file_lock(int fd, short type) {
|
||||
assert(type == F_RDLCK || type == F_WRLCK);
|
||||
struct flock flk = {};
|
||||
|
@ -136,8 +136,8 @@ static bool history_file_lock(int fd, short type) {
|
|||
return ret != -1;
|
||||
}
|
||||
|
||||
// Our LRU cache is used for restricting the amount of history we have, and limiting how long we
|
||||
// order it.
|
||||
/// Our LRU cache is used for restricting the amount of history we have, and limiting how long we
|
||||
/// order it.
|
||||
class history_lru_node_t : public lru_node_t {
|
||||
public:
|
||||
time_t timestamp;
|
||||
|
@ -150,13 +150,13 @@ class history_lru_node_t : public lru_node_t {
|
|||
|
||||
class history_lru_cache_t : public lru_cache_t<history_lru_node_t> {
|
||||
protected:
|
||||
// Override to delete evicted nodes.
|
||||
/// Override to delete evicted nodes.
|
||||
virtual void node_was_evicted(history_lru_node_t *node) { delete node; }
|
||||
|
||||
public:
|
||||
explicit history_lru_cache_t(size_t max) : lru_cache_t<history_lru_node_t>(max) {}
|
||||
|
||||
// Function to add a history item.
|
||||
/// Function to add a history item.
|
||||
void add_item(const history_item_t &item) {
|
||||
// Skip empty items.
|
||||
if (item.empty()) return;
|
||||
|
@ -197,15 +197,15 @@ static history_collection_t histories;
|
|||
|
||||
static wcstring history_filename(const wcstring &name, const wcstring &suffix);
|
||||
|
||||
// Replaces newlines with a literal backslash followed by an n, and replaces backslashes with two
|
||||
// backslashes.
|
||||
/// Replaces newlines with a literal backslash followed by an n, and replaces backslashes with two
|
||||
/// backslashes.
|
||||
static void escape_yaml(std::string *str);
|
||||
|
||||
// Inverse of escape_yaml.
|
||||
/// Inverse of escape_yaml.
|
||||
static void unescape_yaml(std::string *str);
|
||||
|
||||
// We can merge two items if they are the same command. We use the more recent timestamp, more
|
||||
// recent identifier, and the longer list of required paths.
|
||||
/// We can merge two items if they are the same command. We use the more recent timestamp, more
|
||||
/// recent identifier, and the longer list of required paths.
|
||||
bool history_item_t::merge(const history_item_t &item) {
|
||||
bool result = false;
|
||||
if (this->contents == item.contents) {
|
||||
|
@ -246,7 +246,7 @@ bool history_item_t::matches_search(const wcstring &term, enum history_search_ty
|
|||
}
|
||||
}
|
||||
|
||||
// Append our YAML history format to the provided vector at the given offset, updating the offset.
|
||||
/// Append our YAML history format to the provided vector at the given offset, updating the offset.
|
||||
static void append_yaml_to_buffer(const wcstring &wcmd, time_t timestamp,
|
||||
const path_list_t &required_paths,
|
||||
history_output_buffer_t *buffer) {
|
||||
|
@ -270,9 +270,9 @@ static void append_yaml_to_buffer(const wcstring &wcmd, time_t timestamp,
|
|||
}
|
||||
}
|
||||
|
||||
// Parse a timestamp line that looks like this: spaces, "when:", spaces, timestamp, newline
|
||||
// The string is NOT null terminated; however we do know it contains a newline, so stop when we
|
||||
// reach it
|
||||
/// Parse a timestamp line that looks like this: spaces, "when:", spaces, timestamp, newline
|
||||
/// The string is NOT null terminated; however we do know it contains a newline, so stop when we
|
||||
/// reach it.
|
||||
static bool parse_timestamp(const char *str, time_t *out_when) {
|
||||
const char *cursor = str;
|
||||
// Advance past spaces.
|
||||
|
@ -295,8 +295,8 @@ static bool parse_timestamp(const char *str, time_t *out_when) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Returns a pointer to the start of the next line, or NULL. The next line must itself end with a
|
||||
// newline. Note that the string is not null terminated.
|
||||
/// Returns a pointer to the start of the next line, or NULL. The next line must itself end with a
|
||||
/// newline. Note that the string is not null terminated.
|
||||
static const char *next_line(const char *start, size_t length) {
|
||||
// Handle the hopeless case.
|
||||
if (length < 1) return NULL;
|
||||
|
@ -323,11 +323,11 @@ static const char *next_line(const char *start, size_t length) {
|
|||
return nextline;
|
||||
}
|
||||
|
||||
// Support for iteratively locating the offsets of history items.
|
||||
// Pass the address and length of a mapped region.
|
||||
// Pass a pointer to a cursor size_t, initially 0.
|
||||
// If custoff_timestamp is nonzero, skip items created at or after that timestamp.
|
||||
// Returns (size_t)(-1) when done.
|
||||
/// Support for iteratively locating the offsets of history items.
|
||||
/// Pass the address and length of a mapped region.
|
||||
/// Pass a pointer to a cursor size_t, initially 0.
|
||||
/// If custoff_timestamp is nonzero, skip items created at or after that timestamp.
|
||||
/// Returns (size_t)(-1) when done.
|
||||
static size_t offset_of_next_item_fish_2_0(const char *begin, size_t mmap_length,
|
||||
size_t *inout_cursor, time_t cutoff_timestamp) {
|
||||
size_t cursor = *inout_cursor;
|
||||
|
@ -415,8 +415,8 @@ static size_t offset_of_next_item_fish_2_0(const char *begin, size_t mmap_length
|
|||
return result;
|
||||
}
|
||||
|
||||
// Same as offset_of_next_item_fish_2_0, but for fish 1.x (pre fishfish).
|
||||
// Adapted from history_populate_from_mmap in history.c
|
||||
/// Same as offset_of_next_item_fish_2_0, but for fish 1.x (pre fishfish).
|
||||
/// Adapted from history_populate_from_mmap in history.c
|
||||
static size_t offset_of_next_item_fish_1_x(const char *begin, size_t mmap_length,
|
||||
size_t *inout_cursor, time_t cutoff_timestamp) {
|
||||
if (mmap_length == 0 || *inout_cursor >= mmap_length) return (size_t)(-1);
|
||||
|
@ -456,7 +456,7 @@ static size_t offset_of_next_item_fish_1_x(const char *begin, size_t mmap_length
|
|||
return result;
|
||||
}
|
||||
|
||||
// Returns the offset of the next item based on the given history type, or -1.
|
||||
/// Returns the offset of the next item based on the given history type, or -1.
|
||||
static size_t offset_of_next_item(const char *begin, size_t mmap_length,
|
||||
history_file_type_t mmap_type, size_t *inout_cursor,
|
||||
time_t cutoff_timestamp) {
|
||||
|
@ -695,8 +695,8 @@ history_item_t history_t::item_at_index(size_t idx) {
|
|||
return history_item_t(wcstring(), 0);
|
||||
}
|
||||
|
||||
// Read one line, stripping off any newline, and updating cursor. Note that our input string is NOT
|
||||
// null terminated; it's just a memory mapped file.
|
||||
/// Read one line, stripping off any newline, and updating cursor. Note that our input string is NOT
|
||||
/// null terminated; it's just a memory mapped file.
|
||||
static size_t read_line(const char *base, size_t cursor, size_t len, std::string &result) {
|
||||
// Locate the newline.
|
||||
assert(cursor <= len);
|
||||
|
@ -713,7 +713,7 @@ static size_t read_line(const char *base, size_t cursor, size_t len, std::string
|
|||
}
|
||||
}
|
||||
|
||||
// Trims leading spaces in the given string, returning how many there were.
|
||||
/// Trims leading spaces in the given string, returning how many there were.
|
||||
static size_t trim_leading_spaces(std::string &str) {
|
||||
size_t i = 0, max = str.size();
|
||||
while (i < max && str[i] == ' ') i++;
|
||||
|
@ -738,7 +738,7 @@ static bool extract_prefix_and_unescape_yaml(std::string *key, std::string *valu
|
|||
return where != std::string::npos;
|
||||
}
|
||||
|
||||
// Decode an item via the fish 2.0 format.
|
||||
/// Decode an item via the fish 2.0 format.
|
||||
history_item_t history_t::decode_item_fish_2_0(const char *base, size_t len) {
|
||||
wcstring cmd;
|
||||
time_t when = 0;
|
||||
|
@ -812,8 +812,8 @@ history_item_t history_t::decode_item(const char *base, size_t len, history_file
|
|||
}
|
||||
}
|
||||
|
||||
// Remove backslashes from all newlines. This makes a string from the history file better formated
|
||||
// for on screen display.
|
||||
/// Remove backslashes from all newlines. This makes a string from the history file better formated
|
||||
/// for on screen display.
|
||||
static wcstring history_unescape_newlines_fish_1_x(const wcstring &in_str) {
|
||||
wcstring out;
|
||||
for (const wchar_t *in = in_str.c_str(); *in; in++) {
|
||||
|
@ -828,7 +828,7 @@ static wcstring history_unescape_newlines_fish_1_x(const wcstring &in_str) {
|
|||
return out;
|
||||
}
|
||||
|
||||
// Decode an item via the fish 1.x format. Adapted from fish 1.x's item_get().
|
||||
/// Decode an item via the fish 1.x format. Adapted from fish 1.x's item_get().
|
||||
history_item_t history_t::decode_item_fish_1_x(const char *begin, size_t length) {
|
||||
const char *end = begin + length;
|
||||
const char *pos = begin;
|
||||
|
@ -901,7 +901,7 @@ history_item_t history_t::decode_item_fish_1_x(const char *begin, size_t length)
|
|||
return history_item_t(out, timestamp);
|
||||
}
|
||||
|
||||
// Try to infer the history file type based on inspecting the data.
|
||||
/// Try to infer the history file type based on inspecting the data.
|
||||
static history_file_type_t infer_file_type(const char *data, size_t len) {
|
||||
history_file_type_t result = history_type_unknown;
|
||||
if (len > 0) { // old fish started with a #
|
||||
|
@ -928,8 +928,8 @@ void history_t::populate_from_mmap(void) {
|
|||
}
|
||||
}
|
||||
|
||||
// Do a private, read-only map of the entirety of a history file with the given name. Returns true
|
||||
// if successful. Returns the mapped memory region by reference.
|
||||
/// Do a private, read-only map of the entirety of a history file with the given name. Returns true
|
||||
/// if successful. Returns the mapped memory region by reference.
|
||||
bool history_t::map_file(const wcstring &name, const char **out_map_start, size_t *out_map_len,
|
||||
file_id_t *file_id) {
|
||||
bool result = false;
|
||||
|
@ -1042,13 +1042,13 @@ bool history_search_t::go_backwards() {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Goes to the end (forwards).
|
||||
/// Goes to the end (forwards).
|
||||
void history_search_t::go_to_end(void) { prev_matches.clear(); }
|
||||
|
||||
// Returns if we are at the end, which is where we start.
|
||||
/// Returns if we are at the end, which is where we start.
|
||||
bool history_search_t::is_at_end(void) const { return prev_matches.empty(); }
|
||||
|
||||
// Goes to the beginning (backwards).
|
||||
/// Goes to the beginning (backwards).
|
||||
void history_search_t::go_to_beginning(void) {
|
||||
// Go backwards as far as we can.
|
||||
while (go_backwards())
|
||||
|
@ -1087,7 +1087,7 @@ static void escape_yaml(std::string *str) {
|
|||
replace_all(str, "\n", "\\n"); // replace newline with backslash + literal n
|
||||
}
|
||||
|
||||
// This function is called frequently, so it ought to be fast.
|
||||
/// This function is called frequently, so it ought to be fast.
|
||||
static void unescape_yaml(std::string *str) {
|
||||
size_t cursor = 0, size = str->size();
|
||||
while (cursor < size) {
|
||||
|
@ -1397,7 +1397,7 @@ bool history_t::save_internal_via_appending() {
|
|||
return ok;
|
||||
}
|
||||
|
||||
// Save the specified mode to file; optionally also vacuums.
|
||||
/// Save the specified mode to file; optionally also vacuums.
|
||||
void history_t::save_internal(bool vacuum) {
|
||||
ASSERT_IS_LOCKED(lock);
|
||||
|
||||
|
@ -1475,9 +1475,9 @@ bool history_t::is_empty(void) {
|
|||
return empty;
|
||||
}
|
||||
|
||||
// Populates from older location (in config path, rather than data path) This is accomplished by
|
||||
// clearing ourselves, and copying the contents of the old history file to the new history file.
|
||||
// The new contents will automatically be re-mapped later.
|
||||
/// Populates from older location (in config path, rather than data path) This is accomplished by
|
||||
/// clearing ourselves, and copying the contents of the old history file to the new history file.
|
||||
/// The new contents will automatically be re-mapped later.
|
||||
void history_t::populate_from_config_path() {
|
||||
wcstring old_file;
|
||||
if (path_get_config(old_file)) {
|
||||
|
@ -1510,7 +1510,7 @@ void history_t::populate_from_config_path() {
|
|||
}
|
||||
}
|
||||
|
||||
// Indicate whether we ought to import the bash history file into fish.
|
||||
/// Indicate whether we ought to import the bash history file into fish.
|
||||
static bool should_import_bash_history_line(const std::string &line) {
|
||||
if (line.empty()) return false;
|
||||
|
||||
|
@ -1717,7 +1717,7 @@ void history_t::add_pending_with_file_detection(const wcstring &str) {
|
|||
}
|
||||
}
|
||||
|
||||
// Very simple, just mark that we have no more pending items.
|
||||
/// Very simple, just mark that we have no more pending items.
|
||||
void history_t::resolve_pending() {
|
||||
scoped_lock locker(lock);
|
||||
this->has_pending_item = false;
|
||||
|
|
Loading…
Reference in New Issue
Block a user