lint cleanup: eliminate "redundant" errors
This removes some pointless parentheses but the primary focus is removing redundancies like unnecessary "else" clauses.
This commit is contained in:
parent
527e5f52ba
commit
79f342b954
@ -412,26 +412,25 @@ static int builtin_bind_erase(wchar_t **seq, int all, const wchar_t *mode, int u
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
int res = 0;
|
||||
|
||||
if (mode == NULL) mode = DEFAULT_BIND_MODE;
|
||||
|
||||
while (*seq) {
|
||||
if (use_terminfo) {
|
||||
wcstring seq2;
|
||||
if (get_terminfo_sequence(*seq++, &seq2, streams)) {
|
||||
input_mapping_erase(seq2, mode);
|
||||
} else {
|
||||
res = 1;
|
||||
}
|
||||
} else {
|
||||
input_mapping_erase(*seq++, mode);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int res = 0;
|
||||
if (mode == NULL) mode = DEFAULT_BIND_MODE;
|
||||
|
||||
while (*seq) {
|
||||
if (use_terminfo) {
|
||||
wcstring seq2;
|
||||
if (get_terminfo_sequence(*seq++, &seq2, streams)) {
|
||||
input_mapping_erase(seq2, mode);
|
||||
} else {
|
||||
res = 1;
|
||||
}
|
||||
} else {
|
||||
input_mapping_erase(*seq++, mode);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/// The bind builtin, used for setting character sequences.
|
||||
@ -1454,11 +1453,10 @@ static int builtin_pwd(parser_t &parser, io_streams_t &streams, wchar_t **argv)
|
||||
wcstring res = wgetcwd();
|
||||
if (res.empty()) {
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
} else {
|
||||
streams.out.append(res);
|
||||
streams.out.push_back(L'\n');
|
||||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
streams.out.append(res);
|
||||
streams.out.push_back(L'\n');
|
||||
return STATUS_BUILTIN_OK;
|
||||
}
|
||||
|
||||
/// Adds a function to the function set. It calls into function.cpp to perform any heavy lifting.
|
||||
@ -2638,10 +2636,10 @@ static int send_to_bg(parser_t &parser, io_streams_t &streams, job_t *j, const w
|
||||
L"bg", j->job_id, j->command_wcstr());
|
||||
builtin_print_help(parser, streams, L"bg", streams.err);
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
} else {
|
||||
streams.err.append_format(_(L"Send job %d '%ls' to background\n"), j->job_id,
|
||||
j->command_wcstr());
|
||||
}
|
||||
|
||||
streams.err.append_format(_(L"Send job %d '%ls' to background\n"), j->job_id,
|
||||
j->command_wcstr());
|
||||
make_first(j);
|
||||
job_set_flag(j, JOB_FOREGROUND, 0);
|
||||
job_continue(j, job_is_stopped(j));
|
||||
@ -3087,9 +3085,8 @@ static const builtin_data_t *builtin_lookup(const wcstring &name) {
|
||||
const builtin_data_t *found = std::lower_bound(builtin_datas, array_end, name);
|
||||
if (found != array_end && name == found->name) {
|
||||
return found;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void builtin_init() {
|
||||
@ -3127,14 +3124,10 @@ int builtin_run(parser_t &parser, const wchar_t *const *argv, io_streams_t &stre
|
||||
}
|
||||
|
||||
if (data != NULL) {
|
||||
int status;
|
||||
|
||||
status = cmd(parser, streams, argv);
|
||||
return status;
|
||||
|
||||
} else {
|
||||
debug(0, UNKNOWN_BUILTIN_ERR_MSG, argv[0]);
|
||||
return cmd(parser, streams, argv);
|
||||
}
|
||||
|
||||
debug(0, UNKNOWN_BUILTIN_ERR_MSG, argv[0]);
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
}
|
||||
|
||||
|
@ -436,11 +436,10 @@ int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv)
|
||||
current_buffer = reader_get_buffer();
|
||||
new_pos = maxi(0L, mini(new_pos, (long)wcslen(current_buffer)));
|
||||
reader_set_buffer(current_buffer, (size_t)new_pos);
|
||||
return 0;
|
||||
} else {
|
||||
streams.out.append_format(L"%lu\n", (unsigned long)reader_get_cursor_pos());
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (line_mode) {
|
||||
|
@ -67,9 +67,8 @@ static const wchar_t *string_get_arg_stdin(wcstring *storage, const io_streams_t
|
||||
if (rc == 0) { // EOF
|
||||
if (arg.empty()) {
|
||||
return 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch == '\n') {
|
||||
@ -84,16 +83,15 @@ static const wchar_t *string_get_arg_stdin(wcstring *storage, const io_streams_t
|
||||
}
|
||||
|
||||
static const wchar_t *string_get_arg_argv(int *argidx, wchar_t **argv) {
|
||||
return (argv && argv[*argidx]) ? argv[(*argidx)++] : 0;
|
||||
return argv && argv[*argidx] ? argv[(*argidx)++] : 0;
|
||||
}
|
||||
|
||||
static const wchar_t *string_get_arg(int *argidx, wchar_t **argv, wcstring *storage,
|
||||
const io_streams_t &streams) {
|
||||
if (string_args_from_stdin(streams)) {
|
||||
return string_get_arg_stdin(storage, streams);
|
||||
} else {
|
||||
return string_get_arg_argv(argidx, argv);
|
||||
}
|
||||
return string_get_arg_argv(argidx, argv);
|
||||
}
|
||||
|
||||
static int string_escape(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
|
||||
@ -138,7 +136,7 @@ static int string_escape(parser_t &parser, io_streams_t &streams, int argc, wcha
|
||||
nesc++;
|
||||
}
|
||||
|
||||
return (nesc > 0) ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
|
||||
return nesc > 0 ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
|
||||
}
|
||||
|
||||
static int string_join(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
|
||||
@ -195,7 +193,7 @@ static int string_join(parser_t &parser, io_streams_t &streams, int argc, wchar_
|
||||
streams.out.push_back(L'\n');
|
||||
}
|
||||
|
||||
return (nargs > 1) ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
|
||||
return nargs > 1 ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
|
||||
}
|
||||
|
||||
static int string_length(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
|
||||
@ -245,7 +243,7 @@ static int string_length(parser_t &parser, io_streams_t &streams, int argc, wcha
|
||||
}
|
||||
}
|
||||
|
||||
return (nnonempty > 0) ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
|
||||
return nnonempty > 0 ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
|
||||
}
|
||||
|
||||
struct match_options_t {
|
||||
@ -923,7 +921,7 @@ static int string_split(parser_t &parser, io_streams_t &streams, int argc, wchar
|
||||
}
|
||||
|
||||
// We split something if we have more split values than args.
|
||||
return (splits.size() > arg_count) ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
|
||||
return splits.size() > arg_count ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
|
||||
}
|
||||
|
||||
static int string_sub(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
|
||||
@ -1028,7 +1026,7 @@ static int string_sub(parser_t &parser, io_streams_t &streams, int argc, wchar_t
|
||||
nsub++;
|
||||
}
|
||||
|
||||
return (nsub > 0) ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
|
||||
return nsub > 0 ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
|
||||
}
|
||||
|
||||
static int string_trim(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
|
||||
@ -1118,7 +1116,7 @@ static int string_trim(parser_t &parser, io_streams_t &streams, int argc, wchar_
|
||||
}
|
||||
}
|
||||
|
||||
return (ntrim > 0) ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
|
||||
return ntrim > 0 ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
|
||||
}
|
||||
|
||||
static const struct string_subcommand {
|
||||
|
@ -281,12 +281,10 @@ expression *test_parser::parse_unary_expression(unsigned int start, unsigned int
|
||||
expr_ref_t subject(parse_unary_expression(start + 1, end));
|
||||
if (subject.get()) {
|
||||
return new unary_operator(tok, range_t(start, subject->range.end), subject);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
return parse_primary(start, end);
|
||||
return NULL;
|
||||
}
|
||||
return parse_primary(start, end);
|
||||
}
|
||||
|
||||
/// Parse a combining expression (AND, OR).
|
||||
@ -330,14 +328,12 @@ expression *test_parser::parse_combining_expression(unsigned int start, unsigned
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (!subjects.empty()) {
|
||||
// Our new expression takes ownership of all expressions we created. The token we pass is
|
||||
// irrelevant.
|
||||
return new combining_expression(test_combine_and, range_t(start, idx), subjects, combiners);
|
||||
} else {
|
||||
// No subjects.
|
||||
return NULL;
|
||||
if (subjects.empty()) {
|
||||
return NULL; // no subjects
|
||||
}
|
||||
// Our new expression takes ownership of all expressions we created. The token we pass is
|
||||
// irrelevant.
|
||||
return new combining_expression(test_combine_and, range_t(start, idx), subjects, combiners);
|
||||
}
|
||||
|
||||
expression *test_parser::parse_unary_primary(unsigned int start, unsigned int end) {
|
||||
@ -824,18 +820,18 @@ int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
#endif
|
||||
streams.err.append(err);
|
||||
return BUILTIN_TEST_FAIL;
|
||||
} else {
|
||||
wcstring_list_t eval_errors;
|
||||
bool result = expr->evaluate(eval_errors);
|
||||
if (!eval_errors.empty()) {
|
||||
printf("test returned eval errors:\n");
|
||||
for (size_t i = 0; i < eval_errors.size(); i++) {
|
||||
printf("\t%ls\n", eval_errors.at(i).c_str());
|
||||
}
|
||||
}
|
||||
delete expr;
|
||||
return result ? BUILTIN_TEST_SUCCESS : BUILTIN_TEST_FAIL;
|
||||
}
|
||||
|
||||
wcstring_list_t eval_errors;
|
||||
bool result = expr->evaluate(eval_errors);
|
||||
if (!eval_errors.empty()) {
|
||||
printf("test returned eval errors:\n");
|
||||
for (size_t i = 0; i < eval_errors.size(); i++) {
|
||||
printf("\t%ls\n", eval_errors.at(i).c_str());
|
||||
}
|
||||
}
|
||||
delete expr;
|
||||
return result ? BUILTIN_TEST_SUCCESS : BUILTIN_TEST_FAIL;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
@ -283,13 +283,9 @@ color24_t rgb_color_t::to_color24() const {
|
||||
|
||||
unsigned char rgb_color_t::to_name_index() const {
|
||||
assert(type == type_named || type == type_rgb);
|
||||
if (type == type_named) {
|
||||
return data.name_idx;
|
||||
} else if (type == type_rgb) {
|
||||
return term8_color_for_rgb(data.color.rgb);
|
||||
} else {
|
||||
return (unsigned char)-1; // this is an error
|
||||
}
|
||||
if (type == type_named) return data.name_idx;
|
||||
if (type == type_rgb) return term8_color_for_rgb(data.color.rgb);
|
||||
return (unsigned char)-1; // this is an error
|
||||
}
|
||||
|
||||
void rgb_color_t::parse(const wcstring &str) {
|
||||
|
@ -194,20 +194,15 @@ char *wcs2str(const wchar_t *in) {
|
||||
if (result) {
|
||||
// It converted into the local buffer, so copy it.
|
||||
result = strdup(result);
|
||||
if (!result) {
|
||||
DIE_MEM();
|
||||
}
|
||||
if (!result) DIE_MEM();
|
||||
}
|
||||
return result;
|
||||
|
||||
} else {
|
||||
// Here we probably allocate a buffer probably much larger than necessary.
|
||||
char *out = (char *)malloc(MAX_UTF8_BYTES * wcslen(in) + 1);
|
||||
if (!out) {
|
||||
DIE_MEM();
|
||||
}
|
||||
return wcs2str_internal(in, out);
|
||||
}
|
||||
|
||||
// Here we probably allocate a buffer probably much larger than necessary.
|
||||
char *out = (char *)malloc(MAX_UTF8_BYTES * wcslen(in) + 1);
|
||||
if (!out) DIE_MEM();
|
||||
return wcs2str_internal(in, out);
|
||||
}
|
||||
|
||||
char *wcs2str(const wcstring &in) { return wcs2str(in.c_str()); }
|
||||
@ -411,10 +406,8 @@ wcstring wsetlocale(int category, const wchar_t *locale) {
|
||||
// U+23CE is the "return" character
|
||||
omitted_newline_char = (wcwidth(L'\x23CE') > 0) ? L'\x23CE' : L'~';
|
||||
|
||||
if (!res)
|
||||
return wcstring();
|
||||
else
|
||||
return format_string(L"%s", res);
|
||||
if (!res) return wcstring();
|
||||
return format_string(L"%s", res);
|
||||
}
|
||||
|
||||
bool contains_internal(const wchar_t *a, int vararg_handle, ...) {
|
||||
|
@ -71,9 +71,8 @@ void complete_set_variable_names(const wcstring_list_t *names) {
|
||||
static inline wcstring_list_t complete_get_variable_names(void) {
|
||||
if (s_override_variable_names != NULL) {
|
||||
return *s_override_variable_names;
|
||||
} else {
|
||||
return env_get_names(0);
|
||||
}
|
||||
return env_get_names(0);
|
||||
}
|
||||
|
||||
/// Struct describing a completion option entry.
|
||||
@ -161,9 +160,8 @@ struct completion_entry_set_comparer {
|
||||
// Paths always come last for no particular reason.
|
||||
if (p1.cmd_is_path != p2.cmd_is_path) {
|
||||
return p1.cmd_is_path < p2.cmd_is_path;
|
||||
} else {
|
||||
return p1.cmd < p2.cmd;
|
||||
}
|
||||
return p1.cmd < p2.cmd;
|
||||
}
|
||||
};
|
||||
typedef std::set<completion_entry_t, completion_entry_set_comparer> completion_entry_set_t;
|
||||
@ -285,8 +283,7 @@ class completer_t {
|
||||
enum complete_type_t { COMPLETE_DEFAULT, COMPLETE_AUTOSUGGEST };
|
||||
|
||||
complete_type_t type() const {
|
||||
return (flags & COMPLETION_REQUEST_AUTOSUGGESTION) ? COMPLETE_AUTOSUGGEST
|
||||
: COMPLETE_DEFAULT;
|
||||
return flags & COMPLETION_REQUEST_AUTOSUGGESTION ? COMPLETE_AUTOSUGGEST : COMPLETE_DEFAULT;
|
||||
}
|
||||
|
||||
bool wants_descriptions() const { return !!(flags & COMPLETION_REQUEST_DESCRIPTIONS); }
|
||||
@ -295,8 +292,8 @@ class completer_t {
|
||||
|
||||
fuzzy_match_type_t max_fuzzy_match_type() const {
|
||||
// If we are doing fuzzy matching, request all types; if not request only prefix matching.
|
||||
return (flags & COMPLETION_REQUEST_FUZZY_MATCH) ? fuzzy_match_none
|
||||
: fuzzy_match_prefix_case_insensitive;
|
||||
if (flags & COMPLETION_REQUEST_FUZZY_MATCH) return fuzzy_match_none;
|
||||
return fuzzy_match_prefix_case_insensitive;
|
||||
}
|
||||
|
||||
public:
|
||||
@ -1313,7 +1310,7 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
|
||||
tree.get_child(*plain_statement, 0, parse_token_type_string);
|
||||
|
||||
// Get the actual command string.
|
||||
if (cmd_node != NULL) current_command = cmd_node->get_source(cmd);
|
||||
if (cmd_node) current_command = cmd_node->get_source(cmd);
|
||||
|
||||
// Check the decoration.
|
||||
switch (tree.decoration_for_plain_statement(*plain_statement)) {
|
||||
@ -1341,7 +1338,7 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd_node && cmd_node->location_in_or_at_end_of_source_range(pos)) {
|
||||
if (cmd_node && cmd_node->location_in_or_at_end_of_source_range(pos)) {
|
||||
// Complete command filename.
|
||||
completer.complete_cmd(current_token, use_function, use_builtin, use_command,
|
||||
use_implicit_cd);
|
||||
|
11
src/env.cpp
11
src/env.cpp
@ -609,9 +609,8 @@ static bool try_remove(env_node_t *n, const wchar_t *key, int var_mode) {
|
||||
|
||||
if (n->new_scope) {
|
||||
return try_remove(global_env, key, var_mode);
|
||||
} else {
|
||||
return try_remove(n->next, key, var_mode);
|
||||
}
|
||||
return try_remove(n->next, key, var_mode);
|
||||
}
|
||||
|
||||
int env_remove(const wcstring &key, int var_mode) {
|
||||
@ -713,9 +712,8 @@ env_var_t env_get_string(const wcstring &key, env_mode_flags_t mode) {
|
||||
if (entry != NULL && (entry->exportv ? search_exported : search_unexported)) {
|
||||
if (entry->val == ENV_NULL) {
|
||||
return env_var_t::missing_var();
|
||||
} else {
|
||||
return entry->val;
|
||||
}
|
||||
return entry->val;
|
||||
}
|
||||
|
||||
if (has_scope) {
|
||||
@ -1074,10 +1072,9 @@ env_var_t env_vars_snapshot_t::get(const wcstring &key) const {
|
||||
// If we represent the current state, bounce to env_get_string.
|
||||
if (this->is_current()) {
|
||||
return env_get_string(key);
|
||||
} else {
|
||||
std::map<wcstring, wcstring>::const_iterator iter = vars.find(key);
|
||||
return (iter == vars.end() ? env_var_t::missing_var() : env_var_t(iter->second));
|
||||
}
|
||||
std::map<wcstring, wcstring>::const_iterator iter = vars.find(key);
|
||||
return iter == vars.end() ? env_var_t::missing_var() : env_var_t(iter->second);
|
||||
}
|
||||
|
||||
const wchar_t *const env_vars_snapshot_t::highlighting_keys[] = {L"PATH", L"CDPATH",
|
||||
|
@ -85,7 +85,10 @@ static wcstring vars_filename_in_directory(const wcstring &wdir) {
|
||||
}
|
||||
|
||||
static const wcstring &default_vars_path() {
|
||||
static wcstring cached_result = vars_filename_in_directory(fishd_get_config());
|
||||
// Oclint complains about this being a "redundant local variable"; however it isn't because the
|
||||
// assignment to a static var is needed to keep the object from being deleted when this function
|
||||
// returns.
|
||||
static wcstring cached_result = vars_filename_in_directory(fishd_get_config()); //!OCLINT
|
||||
return cached_result;
|
||||
}
|
||||
|
||||
@ -1121,9 +1124,8 @@ class universal_notifier_shmem_poller_t : public universal_notifier_t {
|
||||
unsigned long usec_per_sec = 1000000;
|
||||
if (get_time() - last_change_time < 5LL * usec_per_sec) {
|
||||
return usec_per_sec / 10; // 10 times a second
|
||||
} else {
|
||||
return usec_per_sec / 3; // 3 times a second
|
||||
}
|
||||
return usec_per_sec / 3; // 3 times a second
|
||||
}
|
||||
};
|
||||
|
||||
@ -1287,10 +1289,9 @@ class universal_notifier_named_pipe_t : public universal_notifier_t {
|
||||
// We are in polling mode because we think our fd is readable. This means that, if we
|
||||
// return it to be select()'d on, we'll be called back immediately. So don't return it.
|
||||
return -1;
|
||||
} else {
|
||||
// We are not in polling mode. Return the fd so it can be watched.
|
||||
return pipe_fd;
|
||||
}
|
||||
// We are not in polling mode. Return the fd so it can be watched.
|
||||
return pipe_fd;
|
||||
}
|
||||
|
||||
bool notification_fd_became_readable(int fd) {
|
||||
|
@ -229,9 +229,8 @@ static wcstring event_desc_compact(const event_t &event) {
|
||||
}
|
||||
if (event.function_name.size()) {
|
||||
return format_string(L"%ls: \"%ls\"", res.c_str(), event.function_name.c_str());
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void event_add_handler(const event_t &event) {
|
||||
|
@ -145,13 +145,14 @@ char *get_interpreter(const char *command, char *interpreter, size_t buff_size)
|
||||
interpreter[idx++] = '\0';
|
||||
close(fd);
|
||||
}
|
||||
|
||||
if (strncmp(interpreter, "#! /", 4) == 0) {
|
||||
return interpreter + 3;
|
||||
} else if (strncmp(interpreter, "#!/", 3) == 0) {
|
||||
return interpreter + 2;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// This function is executed by the child process created by a call to fork(). It should be called
|
||||
|
123
src/expand.cpp
123
src/expand.cpp
@ -907,54 +907,54 @@ static int expand_variables(const wcstring &instr, std::vector<completion_t> *ou
|
||||
}
|
||||
|
||||
return is_ok;
|
||||
} else {
|
||||
// Even with no value, we still need to parse out slice syntax. Behave as though we
|
||||
// had 1 value, so $foo[1] always works.
|
||||
const size_t slice_start = stop_pos;
|
||||
if (slice_start < insize && instr.at(slice_start) == L'[') {
|
||||
const wchar_t *in = instr.c_str();
|
||||
wchar_t *slice_end;
|
||||
size_t bad_pos;
|
||||
}
|
||||
|
||||
bad_pos =
|
||||
parse_slice(in + slice_start, &slice_end, var_idx_list, var_pos_list, 1);
|
||||
if (bad_pos != 0) {
|
||||
append_syntax_error(errors, stop_pos + bad_pos, L"Invalid index value");
|
||||
// Even with no value, we still need to parse out slice syntax. Behave as though we
|
||||
// had 1 value, so $foo[1] always works.
|
||||
const size_t slice_start = stop_pos;
|
||||
if (slice_start < insize && instr.at(slice_start) == L'[') {
|
||||
const wchar_t *in = instr.c_str();
|
||||
wchar_t *slice_end;
|
||||
size_t bad_pos;
|
||||
|
||||
bad_pos =
|
||||
parse_slice(in + slice_start, &slice_end, var_idx_list, var_pos_list, 1);
|
||||
if (bad_pos != 0) {
|
||||
append_syntax_error(errors, stop_pos + bad_pos, L"Invalid index value");
|
||||
is_ok = 0;
|
||||
return is_ok;
|
||||
}
|
||||
stop_pos = (slice_end - in);
|
||||
|
||||
// Validate that the parsed indexes are valid.
|
||||
for (size_t j = 0; j < var_idx_list.size(); j++) {
|
||||
long tmp = var_idx_list.at(j);
|
||||
if (tmp != 1) {
|
||||
size_t var_src_pos = var_pos_list.at(j);
|
||||
append_syntax_error(errors, slice_start + var_src_pos,
|
||||
ARRAY_BOUNDS_ERR);
|
||||
is_ok = 0;
|
||||
return is_ok;
|
||||
}
|
||||
stop_pos = (slice_end - in);
|
||||
|
||||
// Validate that the parsed indexes are valid.
|
||||
for (size_t j = 0; j < var_idx_list.size(); j++) {
|
||||
long tmp = var_idx_list.at(j);
|
||||
if (tmp != 1) {
|
||||
size_t var_src_pos = var_pos_list.at(j);
|
||||
append_syntax_error(errors, slice_start + var_src_pos,
|
||||
ARRAY_BOUNDS_ERR);
|
||||
is_ok = 0;
|
||||
return is_ok;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Expand a non-existing variable.
|
||||
if (c == VARIABLE_EXPAND) {
|
||||
// Regular expansion, i.e. expand this argument to nothing.
|
||||
empty = true;
|
||||
} else {
|
||||
// Expansion to single argument.
|
||||
wcstring res;
|
||||
res.append(instr, 0, i);
|
||||
if (i > 0 && instr.at(i - 1) == VARIABLE_EXPAND_SINGLE) {
|
||||
res.push_back(VARIABLE_EXPAND_EMPTY);
|
||||
}
|
||||
assert(stop_pos <= insize);
|
||||
res.append(instr, stop_pos, insize - stop_pos);
|
||||
|
||||
is_ok &= expand_variables(res, out, i, errors);
|
||||
return is_ok;
|
||||
// Expand a non-existing variable.
|
||||
if (c == VARIABLE_EXPAND) {
|
||||
// Regular expansion, i.e. expand this argument to nothing.
|
||||
empty = true;
|
||||
} else {
|
||||
// Expansion to single argument.
|
||||
wcstring res;
|
||||
res.append(instr, 0, i);
|
||||
if (i > 0 && instr.at(i - 1) == VARIABLE_EXPAND_SINGLE) {
|
||||
res.push_back(VARIABLE_EXPAND_EMPTY);
|
||||
}
|
||||
assert(stop_pos <= insize);
|
||||
res.append(instr, stop_pos, insize - stop_pos);
|
||||
|
||||
is_ok &= expand_variables(res, out, i, errors);
|
||||
return is_ok;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1113,25 +1113,25 @@ static int expand_cmdsubst(const wcstring &input, std::vector<completion_t> *out
|
||||
if (bad_pos != 0) {
|
||||
append_syntax_error(errors, slice_begin - in + bad_pos, L"Invalid index value");
|
||||
return 0;
|
||||
} else {
|
||||
wcstring_list_t sub_res2;
|
||||
tail_begin = slice_end;
|
||||
for (i = 0; i < slice_idx.size(); i++) {
|
||||
long idx = slice_idx.at(i);
|
||||
if (idx < 1 || (size_t)idx > sub_res.size()) {
|
||||
size_t pos = slice_source_positions.at(i);
|
||||
append_syntax_error(errors, slice_begin - in + pos, ARRAY_BOUNDS_ERR);
|
||||
return 0;
|
||||
}
|
||||
idx = idx - 1;
|
||||
|
||||
sub_res2.push_back(sub_res.at(idx));
|
||||
// debug( 0, L"Pushing item '%ls' with index %d onto sliced result", al_get(
|
||||
// sub_res, idx ), idx );
|
||||
// sub_res[idx] = 0; // ??
|
||||
}
|
||||
sub_res = sub_res2;
|
||||
}
|
||||
|
||||
wcstring_list_t sub_res2;
|
||||
tail_begin = slice_end;
|
||||
for (i = 0; i < slice_idx.size(); i++) {
|
||||
long idx = slice_idx.at(i);
|
||||
if (idx < 1 || (size_t)idx > sub_res.size()) {
|
||||
size_t pos = slice_source_positions.at(i);
|
||||
append_syntax_error(errors, slice_begin - in + pos, ARRAY_BOUNDS_ERR);
|
||||
return 0;
|
||||
}
|
||||
idx = idx - 1;
|
||||
|
||||
sub_res2.push_back(sub_res.at(idx));
|
||||
// debug( 0, L"Pushing item '%ls' with index %d onto sliced result", al_get(
|
||||
// sub_res, idx ), idx );
|
||||
// sub_res[idx] = 0; // ??
|
||||
}
|
||||
sub_res = sub_res2;
|
||||
}
|
||||
|
||||
// Recursively call ourselves to expand any remaining command substitutions. The result of this
|
||||
@ -1385,9 +1385,8 @@ static expand_error_t expand_stage_home_and_pid(const wcstring &input,
|
||||
if (!next.empty() && next.at(0) == PROCESS_EXPAND) {
|
||||
expand_pid(next, flags, out, NULL);
|
||||
return EXPAND_OK;
|
||||
} else {
|
||||
append_completion(out, next);
|
||||
}
|
||||
append_completion(out, next);
|
||||
} else if (!expand_pid(next, flags, out, errors)) {
|
||||
return EXPAND_ERROR;
|
||||
}
|
||||
@ -1399,7 +1398,7 @@ static expand_error_t expand_stage_wildcards(const wcstring &input, std::vector<
|
||||
expand_error_t result = EXPAND_OK;
|
||||
wcstring path_to_expand = input;
|
||||
|
||||
remove_internal_separator(&path_to_expand, (EXPAND_SKIP_WILDCARDS & flags) ? true : false);
|
||||
remove_internal_separator(&path_to_expand, flags & EXPAND_SKIP_WILDCARDS);
|
||||
const bool has_wildcard = wildcard_has(path_to_expand, true /* internal, i.e. ANY_CHAR */);
|
||||
|
||||
if (has_wildcard && (flags & EXECUTABLES_ONLY)) {
|
||||
|
@ -658,15 +658,15 @@ __attribute__((unused)) static wchar_t *wcsdup_fallback(const wchar_t *in) {
|
||||
|
||||
__attribute__((unused)) static int wcscasecmp_fallback(const wchar_t *a, const wchar_t *b) {
|
||||
if (*a == 0) {
|
||||
return (*b == 0) ? 0 : -1;
|
||||
return *b == 0 ? 0 : -1;
|
||||
} else if (*b == 0) {
|
||||
return 1;
|
||||
}
|
||||
int diff = towlower(*a) - towlower(*b);
|
||||
if (diff != 0)
|
||||
if (diff != 0) {
|
||||
return diff;
|
||||
else
|
||||
return wcscasecmp_fallback(a + 1, b + 1);
|
||||
}
|
||||
return wcscasecmp_fallback(a + 1, b + 1);
|
||||
}
|
||||
|
||||
__attribute__((unused)) static int wcsncasecmp_fallback(const wchar_t *a, const wchar_t *b,
|
||||
@ -674,15 +674,13 @@ __attribute__((unused)) static int wcsncasecmp_fallback(const wchar_t *a, const
|
||||
if (count == 0) return 0;
|
||||
|
||||
if (*a == 0) {
|
||||
return (*b == 0) ? 0 : -1;
|
||||
return *b == 0 ? 0 : -1;
|
||||
} else if (*b == 0) {
|
||||
return 1;
|
||||
}
|
||||
int diff = towlower(*a) - towlower(*b);
|
||||
if (diff != 0)
|
||||
return diff;
|
||||
else
|
||||
return wcsncasecmp_fallback(a + 1, b + 1, count - 1);
|
||||
if (diff != 0) return diff;
|
||||
return wcsncasecmp_fallback(a + 1, b + 1, count - 1);
|
||||
}
|
||||
|
||||
#if __APPLE__ && __DARWIN_C_LEVEL >= 200809L
|
||||
@ -827,7 +825,7 @@ size_t wcslcat(wchar_t *dst, const wchar_t *src, size_t siz) {
|
||||
dlen = d - dst;
|
||||
n = siz - dlen;
|
||||
|
||||
if (n == 0) return (dlen + wcslen(s));
|
||||
if (n == 0) return dlen + wcslen(s);
|
||||
|
||||
while (*s != '\0') {
|
||||
if (n != 1) {
|
||||
@ -838,7 +836,7 @@ size_t wcslcat(wchar_t *dst, const wchar_t *src, size_t siz) {
|
||||
}
|
||||
*d = '\0';
|
||||
|
||||
return (dlen + (s - src));
|
||||
return dlen + (s - src);
|
||||
/* count does not include NUL */
|
||||
}
|
||||
|
||||
@ -882,7 +880,7 @@ size_t wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz) {
|
||||
while (*s++)
|
||||
;
|
||||
}
|
||||
return (s - src - 1);
|
||||
return s - src - 1;
|
||||
// Count does not include NUL.
|
||||
}
|
||||
|
||||
|
@ -3963,6 +3963,6 @@ int main(int argc, char **argv) {
|
||||
proc_destroy();
|
||||
|
||||
if (err_count != 0) {
|
||||
return (1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -230,9 +230,8 @@ static const function_info_t *function_get(const wcstring &name) {
|
||||
function_map_t::iterator iter = loaded_functions.find(name);
|
||||
if (iter == loaded_functions.end()) {
|
||||
return NULL;
|
||||
} else {
|
||||
return &iter->second;
|
||||
}
|
||||
return &iter->second;
|
||||
}
|
||||
|
||||
bool function_get_definition(const wcstring &name, wcstring *out_definition) {
|
||||
|
@ -214,8 +214,7 @@ static bool is_potential_cd_path(const wcstring &path, const wcstring &working_d
|
||||
}
|
||||
|
||||
// Call is_potential_path with all of these directories.
|
||||
bool result = is_potential_path(path, directories, flags | PATH_REQUIRE_DIR);
|
||||
return result;
|
||||
return is_potential_path(path, directories, flags | PATH_REQUIRE_DIR);
|
||||
}
|
||||
|
||||
// Given a plain statement node in a parse tree, get the command and return it, expanded
|
||||
|
@ -442,17 +442,17 @@ static size_t offset_of_next_item_fish_1_x(const char *begin, size_t mmap_length
|
||||
break;
|
||||
}
|
||||
case '\n': {
|
||||
if (ignore_newline) {
|
||||
ignore_newline = false;
|
||||
} else {
|
||||
if (!ignore_newline) {
|
||||
// Note: pos will be left pointing just after this newline, because of the ++ in
|
||||
// the loop.
|
||||
all_done = true;
|
||||
}
|
||||
ignore_newline = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*inout_cursor = (pos - begin);
|
||||
return result;
|
||||
}
|
||||
@ -707,11 +707,11 @@ static size_t read_line(const char *base, size_t cursor, size_t len, std::string
|
||||
result.assign(start, newline - start);
|
||||
// Return the amount to advance the cursor; skip over the newline.
|
||||
return newline - start + 1;
|
||||
} else {
|
||||
// We ran off the end.
|
||||
result.clear();
|
||||
return len - cursor;
|
||||
}
|
||||
|
||||
// We ran off the end.
|
||||
result.clear();
|
||||
return len - cursor;
|
||||
}
|
||||
|
||||
/// Trims leading spaces in the given string, returning how many there were.
|
||||
|
@ -535,13 +535,12 @@ static bool input_mapping_is_match(const input_mapping_t &m) {
|
||||
// m.command.c_str());
|
||||
// We matched the entire sequence.
|
||||
return true;
|
||||
} else {
|
||||
int k;
|
||||
// Return the read characters.
|
||||
input_common_next_ch(c);
|
||||
for (k = j - 1; k >= 0; k--) {
|
||||
input_common_next_ch(m.seq[k]);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the read characters.
|
||||
input_common_next_ch(c);
|
||||
for (int k = j - 1; k >= 0; k--) {
|
||||
input_common_next_ch(m.seq[k]);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -630,12 +629,12 @@ wint_t input_readch(bool allow_commands) {
|
||||
case R_AND: {
|
||||
if (input_function_status) {
|
||||
return input_readch();
|
||||
} else {
|
||||
while ((c = input_common_readch(0)) && c >= R_MIN && c <= R_MAX)
|
||||
;
|
||||
input_common_next_ch(c);
|
||||
return input_readch();
|
||||
}
|
||||
while ((c = input_common_readch(0)) && c >= R_MIN && c <= R_MAX) {
|
||||
// do nothing
|
||||
}
|
||||
input_common_next_ch(c);
|
||||
return input_readch();
|
||||
}
|
||||
default: { return c; }
|
||||
}
|
||||
|
@ -92,10 +92,9 @@ const wchar_t *kill_yank_rotate() {
|
||||
// Move the first element to the end.
|
||||
if (kill_list.empty()) {
|
||||
return NULL;
|
||||
} else {
|
||||
kill_list.splice(kill_list.end(), kill_list, kill_list.begin());
|
||||
return kill_list.front().c_str();
|
||||
}
|
||||
kill_list.splice(kill_list.end(), kill_list, kill_list.begin());
|
||||
return kill_list.front().c_str();
|
||||
}
|
||||
|
||||
/// Check the X clipboard. If it has been changed, add the new clipboard contents to the fish
|
||||
@ -132,9 +131,8 @@ const wchar_t *kill_yank() {
|
||||
kill_check_x_buffer();
|
||||
if (kill_list.empty()) {
|
||||
return L"";
|
||||
} else {
|
||||
return kill_list.front().c_str();
|
||||
}
|
||||
return kill_list.front().c_str();
|
||||
}
|
||||
|
||||
void kill_sanity_check() {}
|
||||
|
@ -58,9 +58,8 @@ void output_set_color_support(color_support_t val) { color_support = val; }
|
||||
unsigned char index_for_color(rgb_color_t c) {
|
||||
if (c.is_named() || !(output_get_color_support() & color_support_term256)) {
|
||||
return c.to_name_index();
|
||||
} else {
|
||||
return c.to_term256_index();
|
||||
}
|
||||
return c.to_term256_index();
|
||||
}
|
||||
|
||||
static bool write_color_escape(char *todo, unsigned char idx, bool is_fg) {
|
||||
@ -95,9 +94,8 @@ static bool write_foreground_color(unsigned char idx) {
|
||||
return write_color_escape(set_a_foreground, idx, true);
|
||||
} else if (set_foreground && set_foreground[0]) {
|
||||
return write_color_escape(set_foreground, idx, true);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool write_background_color(unsigned char idx) {
|
||||
@ -105,9 +103,8 @@ static bool write_background_color(unsigned char idx) {
|
||||
return write_color_escape(set_a_background, idx, false);
|
||||
} else if (set_background && set_background[0]) {
|
||||
return write_color_escape(set_background, idx, false);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void write_color(rgb_color_t color, bool is_fg) {
|
||||
|
@ -213,16 +213,18 @@ parse_execution_context_t::execution_cancellation_reason_t
|
||||
parse_execution_context_t::cancellation_reason(const block_t *block) const {
|
||||
if (shell_is_exiting()) {
|
||||
return execution_cancellation_exit;
|
||||
} else if (parser && parser->cancellation_requested) {
|
||||
}
|
||||
if (parser && parser->cancellation_requested) {
|
||||
return execution_cancellation_skip;
|
||||
} else if (block && block->loop_status != LOOP_NORMAL) {
|
||||
}
|
||||
if (block && block->loop_status != LOOP_NORMAL) {
|
||||
// Nasty hack - break and continue set the 'skip' flag as well as the loop status flag.
|
||||
return execution_cancellation_loop_control;
|
||||
} else if (block && block->skip) {
|
||||
return execution_cancellation_skip;
|
||||
} else {
|
||||
return execution_cancellation_none;
|
||||
}
|
||||
if (block && block->skip) {
|
||||
return execution_cancellation_skip;
|
||||
}
|
||||
return execution_cancellation_none;
|
||||
}
|
||||
|
||||
/// Return whether the job contains a single statement, of block type, with no redirections.
|
||||
@ -1042,10 +1044,9 @@ parse_execution_result_t parse_execution_context_t::populate_boolean_process(
|
||||
|
||||
if (skip_job) {
|
||||
return parse_execution_skipped;
|
||||
} else {
|
||||
const parse_node_t &subject = *tree.get_child(bool_statement, 1, symbol_statement);
|
||||
return this->populate_job_process(job, proc, subject);
|
||||
}
|
||||
const parse_node_t &subject = *tree.get_child(bool_statement, 1, symbol_statement);
|
||||
return this->populate_job_process(job, proc, subject);
|
||||
}
|
||||
|
||||
parse_execution_result_t parse_execution_context_t::populate_block_process(
|
||||
|
@ -1349,10 +1349,10 @@ static bool node_has_ancestor(const parse_node_tree_t &tree, const parse_node_t
|
||||
return true; // found it
|
||||
} else if (node.parent == NODE_OFFSET_INVALID) {
|
||||
return false; // no more parents
|
||||
} else {
|
||||
// Recurse to the parent.
|
||||
return node_has_ancestor(tree, tree.at(node.parent), proposed_ancestor);
|
||||
}
|
||||
|
||||
// Recurse to the parent.
|
||||
return node_has_ancestor(tree, tree.at(node.parent), proposed_ancestor);
|
||||
}
|
||||
|
||||
const parse_node_t *parse_node_tree_t::find_last_node_of_type(parse_token_type_t type,
|
||||
|
@ -67,7 +67,7 @@ size_t parse_util_get_offset_from_line(const wcstring &str, int line) {
|
||||
int count = 0;
|
||||
|
||||
if (line < 0) {
|
||||
return (size_t)(-1);
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
if (line == 0) return 0;
|
||||
@ -779,8 +779,7 @@ bool parse_util_argument_is_help(const wchar_t *s, int min_match) {
|
||||
|
||||
min_match = maxi(min_match, 3);
|
||||
|
||||
return (wcscmp(L"-h", s) == 0) ||
|
||||
(len >= (size_t)min_match && (wcsncmp(L"--help", s, len) == 0));
|
||||
return wcscmp(L"-h", s) == 0 || (len >= (size_t)min_match && (wcsncmp(L"--help", s, len) == 0));
|
||||
}
|
||||
|
||||
/// Check if the first argument under the given node is --help.
|
||||
@ -1036,33 +1035,33 @@ parser_test_error_bits_t parse_util_detect_errors_in_argument(const parse_node_t
|
||||
working_copy.c_str());
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
// Check for invalid variable expansions.
|
||||
const size_t unesc_size = unesc.size();
|
||||
for (size_t idx = 0; idx < unesc_size; idx++) {
|
||||
switch (unesc.at(idx)) {
|
||||
case VARIABLE_EXPAND:
|
||||
case VARIABLE_EXPAND_SINGLE: {
|
||||
wchar_t next_char = idx + 1 < unesc_size ? unesc.at(idx + 1) : L'\0';
|
||||
}
|
||||
|
||||
if (next_char != VARIABLE_EXPAND && next_char != VARIABLE_EXPAND_SINGLE &&
|
||||
!wcsvarchr(next_char)) {
|
||||
err = 1;
|
||||
if (out_errors) {
|
||||
// We have something like $$$^.... Back up until we reach the first $.
|
||||
size_t first_dollar = idx;
|
||||
while (first_dollar > 0 &&
|
||||
(unesc.at(first_dollar - 1) == VARIABLE_EXPAND ||
|
||||
unesc.at(first_dollar - 1) == VARIABLE_EXPAND_SINGLE)) {
|
||||
first_dollar--;
|
||||
}
|
||||
parse_util_expand_variable_error(unesc, node.source_start, first_dollar,
|
||||
out_errors);
|
||||
// Check for invalid variable expansions.
|
||||
const size_t unesc_size = unesc.size();
|
||||
for (size_t idx = 0; idx < unesc_size; idx++) {
|
||||
switch (unesc.at(idx)) {
|
||||
case VARIABLE_EXPAND:
|
||||
case VARIABLE_EXPAND_SINGLE: {
|
||||
wchar_t next_char = idx + 1 < unesc_size ? unesc.at(idx + 1) : L'\0';
|
||||
|
||||
if (next_char != VARIABLE_EXPAND && next_char != VARIABLE_EXPAND_SINGLE &&
|
||||
!wcsvarchr(next_char)) {
|
||||
err = 1;
|
||||
if (out_errors) {
|
||||
// We have something like $$$^.... Back up until we reach the first $.
|
||||
size_t first_dollar = idx;
|
||||
while (first_dollar > 0 &&
|
||||
(unesc.at(first_dollar - 1) == VARIABLE_EXPAND ||
|
||||
unesc.at(first_dollar - 1) == VARIABLE_EXPAND_SINGLE)) {
|
||||
first_dollar--;
|
||||
}
|
||||
parse_util_expand_variable_error(unesc, node.source_start, first_dollar,
|
||||
out_errors);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -670,9 +670,8 @@ int parser_t::eval_block_node(node_offset_t node_idx, const io_chain_t &io,
|
||||
if (this->cancellation_requested) {
|
||||
if (!block_stack.empty()) {
|
||||
return 1;
|
||||
} else {
|
||||
this->cancellation_requested = false;
|
||||
}
|
||||
this->cancellation_requested = false;
|
||||
}
|
||||
|
||||
// Only certain blocks are allowed.
|
||||
|
137
src/path.cpp
137
src/path.cpp
@ -22,71 +22,66 @@
|
||||
static bool path_get_path_core(const wcstring &cmd, wcstring *out_path,
|
||||
const env_var_t &bin_path_var) {
|
||||
int err = ENOENT;
|
||||
|
||||
debug(3, L"path_get_path( '%ls' )", cmd.c_str());
|
||||
|
||||
// If the command has a slash, it must be a full path.
|
||||
if (cmd.find(L'/') != wcstring::npos) {
|
||||
if (waccess(cmd, X_OK) == 0) {
|
||||
struct stat buff;
|
||||
if (wstat(cmd, &buff)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (S_ISREG(buff.st_mode)) {
|
||||
if (out_path) out_path->assign(cmd);
|
||||
return true;
|
||||
} else {
|
||||
errno = EACCES;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (waccess(cmd, X_OK) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
wcstring bin_path;
|
||||
if (!bin_path_var.missing()) {
|
||||
bin_path = bin_path_var;
|
||||
} else {
|
||||
if (contains(PREFIX L"/bin", L"/bin", L"/usr/bin")) {
|
||||
bin_path = L"/bin" ARRAY_SEP_STR L"/usr/bin";
|
||||
} else {
|
||||
bin_path = L"/bin" ARRAY_SEP_STR L"/usr/bin" ARRAY_SEP_STR PREFIX L"/bin";
|
||||
}
|
||||
struct stat buff;
|
||||
if (wstat(cmd, &buff)) {
|
||||
return false;
|
||||
}
|
||||
if (S_ISREG(buff.st_mode)) {
|
||||
if (out_path) out_path->assign(cmd);
|
||||
return true;
|
||||
}
|
||||
errno = EACCES;
|
||||
return false;
|
||||
}
|
||||
|
||||
wcstring nxt_path;
|
||||
wcstokenizer tokenizer(bin_path, ARRAY_SEP_STR);
|
||||
while (tokenizer.next(nxt_path)) {
|
||||
if (nxt_path.empty()) continue;
|
||||
append_path_component(nxt_path, cmd);
|
||||
if (waccess(nxt_path, X_OK) == 0) {
|
||||
struct stat buff;
|
||||
if (wstat(nxt_path, &buff) == -1) {
|
||||
if (errno != EACCES) {
|
||||
wperror(L"stat");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (S_ISREG(buff.st_mode)) {
|
||||
if (out_path) out_path->swap(nxt_path);
|
||||
return true;
|
||||
}
|
||||
err = EACCES;
|
||||
wcstring bin_path;
|
||||
if (!bin_path_var.missing()) {
|
||||
bin_path = bin_path_var;
|
||||
} else {
|
||||
if (contains(PREFIX L"/bin", L"/bin", L"/usr/bin")) {
|
||||
bin_path = L"/bin" ARRAY_SEP_STR L"/usr/bin";
|
||||
} else {
|
||||
bin_path = L"/bin" ARRAY_SEP_STR L"/usr/bin" ARRAY_SEP_STR PREFIX L"/bin";
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
switch (errno) {
|
||||
case ENOENT:
|
||||
case ENAMETOOLONG:
|
||||
case EACCES:
|
||||
case ENOTDIR: {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
debug(1, MISSING_COMMAND_ERR_MSG, nxt_path.c_str());
|
||||
wperror(L"access");
|
||||
}
|
||||
wcstring nxt_path;
|
||||
wcstokenizer tokenizer(bin_path, ARRAY_SEP_STR);
|
||||
while (tokenizer.next(nxt_path)) {
|
||||
if (nxt_path.empty()) continue;
|
||||
append_path_component(nxt_path, cmd);
|
||||
if (waccess(nxt_path, X_OK) == 0) {
|
||||
struct stat buff;
|
||||
if (wstat(nxt_path, &buff) == -1) {
|
||||
if (errno != EACCES) {
|
||||
wperror(L"stat");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (S_ISREG(buff.st_mode)) {
|
||||
if (out_path) out_path->swap(nxt_path);
|
||||
return true;
|
||||
}
|
||||
err = EACCES;
|
||||
} else {
|
||||
switch (errno) {
|
||||
case ENOENT:
|
||||
case ENAMETOOLONG:
|
||||
case EACCES:
|
||||
case ENOTDIR: {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
debug(1, MISSING_COMMAND_ERR_MSG, nxt_path.c_str());
|
||||
wperror(L"access");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -208,23 +203,23 @@ wcstring path_apply_working_directory(const wcstring &path, const wcstring &work
|
||||
if (!prepend_wd) {
|
||||
// No need to prepend the wd, so just return the path we were given.
|
||||
return path;
|
||||
} else {
|
||||
// Remove up to one "./".
|
||||
wcstring path_component = path;
|
||||
if (string_prefixes_string(L"./", path_component)) {
|
||||
path_component.erase(0, 2);
|
||||
}
|
||||
|
||||
// Removing leading /s.
|
||||
while (string_prefixes_string(L"/", path_component)) {
|
||||
path_component.erase(0, 1);
|
||||
}
|
||||
|
||||
// Construct and return a new path.
|
||||
wcstring new_path = working_directory;
|
||||
append_path_component(new_path, path_component);
|
||||
return new_path;
|
||||
}
|
||||
|
||||
// Remove up to one "./".
|
||||
wcstring path_component = path;
|
||||
if (string_prefixes_string(L"./", path_component)) {
|
||||
path_component.erase(0, 2);
|
||||
}
|
||||
|
||||
// Removing leading /s.
|
||||
while (string_prefixes_string(L"/", path_component)) {
|
||||
path_component.erase(0, 1);
|
||||
}
|
||||
|
||||
// Construct and return a new path.
|
||||
wcstring new_path = working_directory;
|
||||
append_path_component(new_path, path_component);
|
||||
return new_path;
|
||||
}
|
||||
|
||||
static wcstring path_create_config() {
|
||||
|
19
src/proc.cpp
19
src/proc.cpp
@ -175,12 +175,12 @@ job_id_t acquire_job_id(void) {
|
||||
// We found a slot. Note that slot 0 corresponds to job ID 1.
|
||||
*slot = true;
|
||||
return (job_id_t)(slot - consumed_job_ids.begin() + 1);
|
||||
} else {
|
||||
// We did not find a slot; create a new slot. The size of the vector is now the job ID
|
||||
// (since it is one larger than the slot).
|
||||
consumed_job_ids.push_back(true);
|
||||
return (job_id_t)consumed_job_ids.size();
|
||||
}
|
||||
|
||||
// We did not find a slot; create a new slot. The size of the vector is now the job ID
|
||||
// (since it is one larger than the slot).
|
||||
consumed_job_ids.push_back(true);
|
||||
return (job_id_t)consumed_job_ids.size();
|
||||
}
|
||||
|
||||
void release_job_id(job_id_t jid) {
|
||||
@ -368,14 +368,14 @@ process_t::process_t()
|
||||
}
|
||||
|
||||
process_t::~process_t() {
|
||||
if (this->next != NULL) delete this->next;
|
||||
delete this->next;
|
||||
}
|
||||
|
||||
job_t::job_t(job_id_t jobid, const io_chain_t &bio)
|
||||
: block_io(bio), first_process(NULL), pgid(0), tmodes(), job_id(jobid), flags(0) {}
|
||||
|
||||
job_t::~job_t() {
|
||||
if (first_process != NULL) delete first_process;
|
||||
delete first_process;
|
||||
release_job_id(job_id);
|
||||
}
|
||||
|
||||
@ -451,10 +451,9 @@ static int process_mark_finished_children(bool wants_await) {
|
||||
|
||||
if (got_error) {
|
||||
return -1;
|
||||
} else {
|
||||
s_last_processed_sigchld_generation_count = local_count;
|
||||
return processed_count;
|
||||
}
|
||||
s_last_processed_sigchld_generation_count = local_count;
|
||||
return processed_count;
|
||||
}
|
||||
|
||||
/// This is called from a signal handler. The signal is always SIGCHLD.
|
||||
|
107
src/reader.cpp
107
src/reader.cpp
@ -232,9 +232,8 @@ class reader_data_t {
|
||||
editable_line_t *active_edit_line() {
|
||||
if (this->is_navigating_pager_contents() && this->pager.is_search_field_shown()) {
|
||||
return &this->pager.search_field_line;
|
||||
} else {
|
||||
return &this->command_line;
|
||||
}
|
||||
return &this->command_line;
|
||||
}
|
||||
|
||||
/// Do what we need to do whenever our command line changes.
|
||||
@ -1070,55 +1069,55 @@ wcstring completion_apply_to_command_line(const wcstring &val_str, complete_flag
|
||||
size_t new_cursor_pos = (begin - buff) + move_cursor;
|
||||
*inout_cursor_pos = new_cursor_pos;
|
||||
return sb;
|
||||
} else {
|
||||
wchar_t quote = L'\0';
|
||||
wcstring replaced;
|
||||
if (do_escape) {
|
||||
// Note that we ignore COMPLETE_DONT_ESCAPE_TILDES here. We get away with this because
|
||||
// unexpand_tildes only operates on completions that have COMPLETE_REPLACES_TOKEN set,
|
||||
// but we ought to respect them.
|
||||
parse_util_get_parameter_info(command_line, cursor_pos, "e, NULL, NULL);
|
||||
|
||||
// If the token is reported as unquoted, but ends with a (unescaped) quote, and we can
|
||||
// modify the command line, then delete the trailing quote so that we can insert within
|
||||
// the quotes instead of after them. See issue #552.
|
||||
if (quote == L'\0' && !append_only && cursor_pos > 0) {
|
||||
// The entire token is reported as unquoted...see if the last character is an
|
||||
// unescaped quote.
|
||||
wchar_t trailing_quote = unescaped_quote(command_line, cursor_pos - 1);
|
||||
if (trailing_quote != L'\0') {
|
||||
quote = trailing_quote;
|
||||
back_into_trailing_quote = true;
|
||||
}
|
||||
}
|
||||
|
||||
replaced = parse_util_escape_string_with_quote(val_str, quote);
|
||||
} else {
|
||||
replaced = val;
|
||||
}
|
||||
|
||||
size_t insertion_point = cursor_pos;
|
||||
if (back_into_trailing_quote) {
|
||||
// Move the character back one so we enter the terminal quote.
|
||||
assert(insertion_point > 0);
|
||||
insertion_point--;
|
||||
}
|
||||
|
||||
// Perform the insertion and compute the new location.
|
||||
wcstring result = command_line;
|
||||
result.insert(insertion_point, replaced);
|
||||
size_t new_cursor_pos =
|
||||
insertion_point + replaced.size() + (back_into_trailing_quote ? 1 : 0);
|
||||
if (add_space) {
|
||||
if (quote != L'\0' && unescaped_quote(command_line, insertion_point) != quote) {
|
||||
// This is a quoted parameter, first print a quote.
|
||||
result.insert(new_cursor_pos++, wcstring("e, 1));
|
||||
}
|
||||
result.insert(new_cursor_pos++, L" ");
|
||||
}
|
||||
*inout_cursor_pos = new_cursor_pos;
|
||||
return result;
|
||||
}
|
||||
|
||||
wchar_t quote = L'\0';
|
||||
wcstring replaced;
|
||||
if (do_escape) {
|
||||
// Note that we ignore COMPLETE_DONT_ESCAPE_TILDES here. We get away with this because
|
||||
// unexpand_tildes only operates on completions that have COMPLETE_REPLACES_TOKEN set,
|
||||
// but we ought to respect them.
|
||||
parse_util_get_parameter_info(command_line, cursor_pos, "e, NULL, NULL);
|
||||
|
||||
// If the token is reported as unquoted, but ends with a (unescaped) quote, and we can
|
||||
// modify the command line, then delete the trailing quote so that we can insert within
|
||||
// the quotes instead of after them. See issue #552.
|
||||
if (quote == L'\0' && !append_only && cursor_pos > 0) {
|
||||
// The entire token is reported as unquoted...see if the last character is an
|
||||
// unescaped quote.
|
||||
wchar_t trailing_quote = unescaped_quote(command_line, cursor_pos - 1);
|
||||
if (trailing_quote != L'\0') {
|
||||
quote = trailing_quote;
|
||||
back_into_trailing_quote = true;
|
||||
}
|
||||
}
|
||||
|
||||
replaced = parse_util_escape_string_with_quote(val_str, quote);
|
||||
} else {
|
||||
replaced = val;
|
||||
}
|
||||
|
||||
size_t insertion_point = cursor_pos;
|
||||
if (back_into_trailing_quote) {
|
||||
// Move the character back one so we enter the terminal quote.
|
||||
assert(insertion_point > 0);
|
||||
insertion_point--;
|
||||
}
|
||||
|
||||
// Perform the insertion and compute the new location.
|
||||
wcstring result = command_line;
|
||||
result.insert(insertion_point, replaced);
|
||||
size_t new_cursor_pos =
|
||||
insertion_point + replaced.size() + (back_into_trailing_quote ? 1 : 0);
|
||||
if (add_space) {
|
||||
if (quote != L'\0' && unescaped_quote(command_line, insertion_point) != quote) {
|
||||
// This is a quoted parameter, first print a quote.
|
||||
result.insert(new_cursor_pos++, wcstring("e, 1));
|
||||
}
|
||||
result.insert(new_cursor_pos++, L" ");
|
||||
}
|
||||
*inout_cursor_pos = new_cursor_pos;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Insert the string at the current cursor position. The function checks if the string is quoted or
|
||||
@ -1926,7 +1925,7 @@ void reader_set_buffer(const wcstring &b, size_t pos) {
|
||||
}
|
||||
|
||||
size_t reader_get_cursor_pos() {
|
||||
if (!data) return (size_t)(-1);
|
||||
if (!data) return (size_t)-1;
|
||||
|
||||
return data->command_line.position;
|
||||
}
|
||||
@ -2357,9 +2356,9 @@ static int can_read(int fd) {
|
||||
//
|
||||
// TODO: Actually implement the replacement as documented above.
|
||||
static int wchar_private(wchar_t c) {
|
||||
return ((c >= RESERVED_CHAR_BASE && c < RESERVED_CHAR_END) ||
|
||||
(c >= ENCODE_DIRECT_BASE && c < ENCODE_DIRECT_END) ||
|
||||
(c >= INPUT_COMMON_BASE && c < INPUT_COMMON_END));
|
||||
return (c >= RESERVED_CHAR_BASE && c < RESERVED_CHAR_END) ||
|
||||
(c >= ENCODE_DIRECT_BASE && c < ENCODE_DIRECT_END) ||
|
||||
(c >= INPUT_COMMON_BASE && c < INPUT_COMMON_END);
|
||||
}
|
||||
|
||||
/// Test if the specified character in the specified string is backslashed. pos may be at the end of
|
||||
|
@ -111,7 +111,7 @@ history_t *reader_get_history(void);
|
||||
void reader_set_buffer(const wcstring &b, size_t p);
|
||||
|
||||
/// Get the current cursor position in the command line. If interactive mode is uninitialized,
|
||||
/// return (size_t)(-1).
|
||||
/// return (size_t)-1.
|
||||
size_t reader_get_cursor_pos();
|
||||
|
||||
/// Get the current selection range in the command line. Returns false if there is no active
|
||||
|
@ -167,12 +167,11 @@ void tokenizer_t::read_string() {
|
||||
TOK_CALL_ERROR(this, TOK_UNTERMINATED_ESCAPE, UNTERMINATED_ESCAPE_ERROR,
|
||||
error_location);
|
||||
return;
|
||||
} else {
|
||||
// Since we are about to increment tok->buff, decrement it first so the
|
||||
// increment doesn't go past the end of the buffer. See issue #389.
|
||||
this->buff--;
|
||||
do_loop = 0;
|
||||
}
|
||||
// Since we are about to increment tok->buff, decrement it first so the
|
||||
// increment doesn't go past the end of the buffer. See issue #389.
|
||||
this->buff--;
|
||||
do_loop = 0;
|
||||
}
|
||||
|
||||
this->buff++;
|
||||
@ -502,17 +501,12 @@ void tokenizer_t::tok_next() {
|
||||
this->read_comment();
|
||||
|
||||
if (this->buff[0] == L'\n' && this->continue_line_after_comment) this->buff++;
|
||||
|
||||
return;
|
||||
} else {
|
||||
while (*(this->buff) != L'\n' && *(this->buff) != L'\0') this->buff++;
|
||||
|
||||
if (this->buff[0] == L'\n' && this->continue_line_after_comment) this->buff++;
|
||||
}
|
||||
|
||||
while (my_iswspace(*(this->buff))) {
|
||||
this->buff++;
|
||||
}
|
||||
while (*(this->buff) != L'\n' && *(this->buff) != L'\0') this->buff++;
|
||||
if (this->buff[0] == L'\n' && this->continue_line_after_comment) this->buff++;
|
||||
while (my_iswspace(*(this->buff))) this->buff++;
|
||||
}
|
||||
|
||||
this->continue_line_after_comment = false;
|
||||
|
28
src/utf8.cpp
28
src/utf8.cpp
@ -238,9 +238,8 @@ static size_t utf8_to_wchar_internal(const char *in, size_t insize, utf8_wstring
|
||||
if (__wchar_forbitten(out_val) != 0) {
|
||||
if ((flags & UTF8_IGNORE_ERROR) == 0) {
|
||||
return 0; // forbidden character
|
||||
} else {
|
||||
skip = true;
|
||||
}
|
||||
skip = true;
|
||||
} else if (out_val == _BOM && (flags & UTF8_SKIP_BOM) != 0) {
|
||||
skip = true;
|
||||
}
|
||||
@ -286,10 +285,8 @@ static size_t wchar_to_utf8_internal(const utf8_wchar_t *in, size_t insize, char
|
||||
total = 0;
|
||||
for (; w < wlim; w++) {
|
||||
if (__wchar_forbitten(*w) != 0) {
|
||||
if ((flags & UTF8_IGNORE_ERROR) == 0)
|
||||
return 0;
|
||||
else
|
||||
continue;
|
||||
if ((flags & UTF8_IGNORE_ERROR) == 0) return 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*w == _BOM && (flags & UTF8_SKIP_BOM) != 0) continue;
|
||||
@ -298,18 +295,13 @@ static size_t wchar_to_utf8_internal(const utf8_wchar_t *in, size_t insize, char
|
||||
if (w_wide < 0) {
|
||||
if ((flags & UTF8_IGNORE_ERROR) == 0) return 0;
|
||||
continue;
|
||||
} else if (w_wide <= 0x0000007f)
|
||||
n = 1;
|
||||
else if (w_wide <= 0x000007ff)
|
||||
n = 2;
|
||||
else if (w_wide <= 0x0000ffff)
|
||||
n = 3;
|
||||
else if (w_wide <= 0x001fffff)
|
||||
n = 4;
|
||||
else if (w_wide <= 0x03ffffff)
|
||||
n = 5;
|
||||
else /// if (w_wide <= 0x7fffffff)
|
||||
n = 6;
|
||||
}
|
||||
if (w_wide <= 0x0000007f) n = 1;
|
||||
else if (w_wide <= 0x000007ff) n = 2;
|
||||
else if (w_wide <= 0x0000ffff) n = 3;
|
||||
else if (w_wide <= 0x001fffff) n = 4;
|
||||
else if (w_wide <= 0x03ffffff) n = 5;
|
||||
else n = 6; /// if (w_wide <= 0x7fffffff)
|
||||
|
||||
total += n;
|
||||
|
||||
|
@ -50,7 +50,7 @@ int wcsfilecmp(const wchar_t *a, const wchar_t *b) {
|
||||
b = bend - 1;
|
||||
} else {
|
||||
int diff = towlower(*a) - towlower(*b);
|
||||
if (diff != 0) return (diff > 0) ? 2 : -2;
|
||||
if (diff != 0) return diff > 0 ? 2 : -2;
|
||||
|
||||
secondary_diff = *a - *b;
|
||||
}
|
||||
|
@ -22,8 +22,8 @@ wcstring_range wcstring_tok(wcstring& str, const wcstring& needle, wcstring_rang
|
||||
size_type next_pos = str.find_first_of(needle, pos);
|
||||
if (next_pos == wcstring::npos) {
|
||||
return std::make_pair(pos, wcstring::npos);
|
||||
} else {
|
||||
str[next_pos] = L'\0';
|
||||
return std::make_pair(pos, next_pos - pos);
|
||||
}
|
||||
|
||||
str[next_pos] = L'\0';
|
||||
return std::make_pair(pos, next_pos - pos);
|
||||
}
|
||||
|
148
src/wildcard.cpp
148
src/wildcard.cpp
@ -150,14 +150,13 @@ static wcstring resolve_description(wcstring *completion, const wchar_t *explici
|
||||
const wcstring description = completion->substr(complete_sep_loc + 1);
|
||||
completion->resize(complete_sep_loc);
|
||||
return description;
|
||||
} else {
|
||||
const wcstring func_result = (desc_func ? desc_func(*completion) : wcstring());
|
||||
if (!func_result.empty()) {
|
||||
return func_result;
|
||||
} else {
|
||||
return explicit_desc ? explicit_desc : L"";
|
||||
}
|
||||
}
|
||||
|
||||
const wcstring func_result = (desc_func ? desc_func(*completion) : wcstring());
|
||||
if (!func_result.empty()) {
|
||||
return func_result;
|
||||
}
|
||||
return explicit_desc ? explicit_desc : L"";
|
||||
}
|
||||
|
||||
// A transient parameter pack needed by wildcard_complete.
|
||||
@ -240,64 +239,60 @@ static bool wildcard_complete_internal(const wchar_t *str, const wchar_t *wc,
|
||||
// Normal match.
|
||||
return wildcard_complete_internal(str + next_wc_char_pos, wc + next_wc_char_pos, params,
|
||||
flags, out);
|
||||
} else if (wcsncasecmp(str, wc, next_wc_char_pos) == 0) {
|
||||
}
|
||||
if (wcsncasecmp(str, wc, next_wc_char_pos) == 0) {
|
||||
// Case insensitive match.
|
||||
return wildcard_complete_internal(str + next_wc_char_pos, wc + next_wc_char_pos, params,
|
||||
flags | COMPLETE_REPLACES_TOKEN, out);
|
||||
} else {
|
||||
// No match.
|
||||
return false;
|
||||
}
|
||||
assert(0 && "Unreachable code reached");
|
||||
} else {
|
||||
// Our first character is a wildcard.
|
||||
assert(next_wc_char_pos == 0);
|
||||
switch (wc[0]) {
|
||||
case ANY_CHAR: {
|
||||
if (str[0] == L'\0') {
|
||||
return false;
|
||||
} else {
|
||||
return wildcard_complete_internal(str + 1, wc + 1, params, flags, out);
|
||||
}
|
||||
break;
|
||||
return false; // no match
|
||||
}
|
||||
|
||||
// Our first character is a wildcard.
|
||||
assert(next_wc_char_pos == 0);
|
||||
switch (wc[0]) {
|
||||
case ANY_CHAR: {
|
||||
if (str[0] == L'\0') {
|
||||
return false;
|
||||
}
|
||||
return wildcard_complete_internal(str + 1, wc + 1, params, flags, out);
|
||||
}
|
||||
case ANY_STRING: {
|
||||
// Hackish. If this is the last character of the wildcard, then just complete with
|
||||
// the empty string. This fixes cases like "f*<tab>" -> "f*o".
|
||||
if (wc[1] == L'\0') {
|
||||
return wildcard_complete_internal(L"", L"", params, flags, out);
|
||||
}
|
||||
case ANY_STRING: {
|
||||
// Hackish. If this is the last character of the wildcard, then just complete with
|
||||
// the empty string. This fixes cases like "f*<tab>" -> "f*o".
|
||||
if (wc[1] == L'\0') {
|
||||
return wildcard_complete_internal(L"", L"", params, flags, out);
|
||||
}
|
||||
|
||||
// Try all submatches. Issue #929: if the recursive call gives us a prefix match,
|
||||
// just stop. This is sloppy - what we really want to do is say, once we've seen a
|
||||
// match of a particular type, ignore all matches of that type further down the
|
||||
// string, such that the wildcard produces the "minimal match.".
|
||||
bool has_match = false;
|
||||
for (size_t i = 0; str[i] != L'\0'; i++) {
|
||||
const size_t before_count = out ? out->size() : 0;
|
||||
if (wildcard_complete_internal(str + i, wc + 1, params, flags, out)) {
|
||||
// We found a match.
|
||||
has_match = true;
|
||||
// Try all submatches. Issue #929: if the recursive call gives us a prefix match,
|
||||
// just stop. This is sloppy - what we really want to do is say, once we've seen a
|
||||
// match of a particular type, ignore all matches of that type further down the
|
||||
// string, such that the wildcard produces the "minimal match.".
|
||||
bool has_match = false;
|
||||
for (size_t i = 0; str[i] != L'\0'; i++) {
|
||||
const size_t before_count = out ? out->size() : 0;
|
||||
if (wildcard_complete_internal(str + i, wc + 1, params, flags, out)) {
|
||||
// We found a match.
|
||||
has_match = true;
|
||||
|
||||
// If out is NULL, we don't care about the actual matches. If out is not
|
||||
// NULL but we have a prefix match, stop there.
|
||||
if (out == NULL || has_prefix_match(out, before_count)) {
|
||||
break;
|
||||
}
|
||||
// If out is NULL, we don't care about the actual matches. If out is not
|
||||
// NULL but we have a prefix match, stop there.
|
||||
if (out == NULL || has_prefix_match(out, before_count)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return has_match;
|
||||
}
|
||||
case ANY_STRING_RECURSIVE: {
|
||||
// We don't even try with this one.
|
||||
return false;
|
||||
}
|
||||
default: {
|
||||
assert(0 && "Unreachable code reached");
|
||||
return false;
|
||||
}
|
||||
return has_match;
|
||||
}
|
||||
case ANY_STRING_RECURSIVE: {
|
||||
// We don't even try with this one.
|
||||
return false;
|
||||
}
|
||||
default: {
|
||||
assert(0 && "Unreachable code reached");
|
||||
}
|
||||
}
|
||||
|
||||
assert(0 && "Unreachable code reached");
|
||||
}
|
||||
|
||||
@ -333,33 +328,32 @@ static wcstring file_get_desc(const wcstring &filename, int lstat_res, const str
|
||||
if (!stat_res) {
|
||||
if (S_ISDIR(buf.st_mode)) {
|
||||
return COMPLETE_DIRECTORY_SYMLINK_DESC;
|
||||
} else {
|
||||
if (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
|
||||
if (waccess(filename, X_OK) == 0) {
|
||||
// Weird group permissions and other such issues make it non-trivial to
|
||||
// find out if we can actually execute a file using the result from
|
||||
// stat. It is much safer to use the access function, since it tells us
|
||||
// exactly what we want to know.
|
||||
return COMPLETE_EXEC_LINK_DESC;
|
||||
}
|
||||
}
|
||||
if (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
|
||||
if (waccess(filename, X_OK) == 0) {
|
||||
// Weird group permissions and other such issues make it non-trivial to
|
||||
// find out if we can actually execute a file using the result from
|
||||
// stat. It is much safer to use the access function, since it tells us
|
||||
// exactly what we want to know.
|
||||
return COMPLETE_EXEC_LINK_DESC;
|
||||
}
|
||||
}
|
||||
|
||||
return COMPLETE_SYMLINK_DESC;
|
||||
|
||||
} else {
|
||||
switch (err) {
|
||||
case ENOENT: {
|
||||
return COMPLETE_ROTTEN_SYMLINK_DESC;
|
||||
}
|
||||
case ELOOP: {
|
||||
return COMPLETE_LOOP_SYMLINK_DESC;
|
||||
}
|
||||
}
|
||||
// On unknown errors we do nothing. The file will be given the default 'File'
|
||||
// description or one based on the suffix.
|
||||
}
|
||||
|
||||
switch (err) {
|
||||
case ENOENT: {
|
||||
return COMPLETE_ROTTEN_SYMLINK_DESC;
|
||||
}
|
||||
case ELOOP: {
|
||||
return COMPLETE_LOOP_SYMLINK_DESC;
|
||||
}
|
||||
default: {
|
||||
// On unknown errors we do nothing. The file will be given the default 'File'
|
||||
// description or one based on the suffix.
|
||||
}
|
||||
}
|
||||
} else if (S_ISCHR(buf.st_mode)) {
|
||||
return COMPLETE_CHAR_DESC;
|
||||
} else if (S_ISBLK(buf.st_mode)) {
|
||||
@ -449,9 +443,8 @@ static bool wildcard_test_flags_then_complete(const wcstring &filepath, const wc
|
||||
if (is_directory) {
|
||||
return wildcard_complete(filename + L'/', wc, desc.c_str(), NULL, out, expand_flags,
|
||||
COMPLETE_NO_SPACE);
|
||||
} else {
|
||||
return wildcard_complete(filename, wc, desc.c_str(), NULL, out, expand_flags, 0);
|
||||
}
|
||||
return wildcard_complete(filename, wc, desc.c_str(), NULL, out, expand_flags, 0);
|
||||
}
|
||||
|
||||
class wildcard_expander_t {
|
||||
@ -637,9 +630,8 @@ class wildcard_expander_t {
|
||||
int status_code() const {
|
||||
if (this->did_interrupt) {
|
||||
return -1;
|
||||
} else {
|
||||
return this->did_add ? 1 : 0;
|
||||
}
|
||||
return this->did_add ? 1 : 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -292,24 +292,20 @@ const char *safe_strerror(int err) {
|
||||
return &_sys_errs[_sys_index[err]];
|
||||
}
|
||||
#endif // either HAVE__SYS__ERRS or HAVE_SYS_ERRLIST
|
||||
else
|
||||
#endif // defined(HAVE__SYS__ERRS) || defined(HAVE_SYS_ERRLIST)
|
||||
{
|
||||
int saved_err = errno;
|
||||
|
||||
// Use a shared buffer for this case.
|
||||
static char buff[384];
|
||||
char errnum_buff[64];
|
||||
format_long_safe(errnum_buff, err);
|
||||
int saved_err = errno;
|
||||
static char buff[384]; // use a shared buffer for this case
|
||||
char errnum_buff[64];
|
||||
format_long_safe(errnum_buff, err);
|
||||
|
||||
buff[0] = '\0';
|
||||
safe_append(buff, "unknown error (errno was ", sizeof buff);
|
||||
safe_append(buff, errnum_buff, sizeof buff);
|
||||
safe_append(buff, ")", sizeof buff);
|
||||
buff[0] = '\0';
|
||||
safe_append(buff, "unknown error (errno was ", sizeof buff);
|
||||
safe_append(buff, errnum_buff, sizeof buff);
|
||||
safe_append(buff, ")", sizeof buff);
|
||||
|
||||
errno = saved_err;
|
||||
return buff;
|
||||
}
|
||||
errno = saved_err;
|
||||
return buff;
|
||||
}
|
||||
|
||||
void safe_perror(const char *message) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user