another step in fixing issue #3985

This changes all of the builtins to behave like `string` to return
STATUS_INVALID_ARGS (121) if the args passed to the command don't make
sense. Also change several of the builtins to use the existing symbols
(e.g., STATUS_CMD_OK and STATUS_CMD_ERROR) rather than hardcoded "0"
and "1" for consistency and to make it easier to find such values in
the future.

Fixes #3985
This commit is contained in:
Kurtis Rader 2017-05-04 21:35:41 -07:00
parent be2b6bfdc9
commit e6e1805c5f
13 changed files with 163 additions and 169 deletions

View file

@ -343,9 +343,9 @@ 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) { static bool get_terminfo_sequence(const wchar_t *seq, wcstring *out_seq, io_streams_t &streams) {
if (input_terminfo_get_sequence(seq, out_seq)) { if (input_terminfo_get_sequence(seq, out_seq)) {
return 1; return true;
} }
wcstring eseq = escape_string(seq, 0); wcstring eseq = escape_string(seq, 0);
@ -358,26 +358,26 @@ static int get_terminfo_sequence(const wchar_t *seq, wcstring *out_seq, io_strea
streams.err.append_format(_(L"%ls: Unknown error trying to bind to key named '%ls'\n"), streams.err.append_format(_(L"%ls: Unknown error trying to bind to key named '%ls'\n"),
L"bind", eseq.c_str()); L"bind", eseq.c_str());
} }
return 0; return false;
} }
/// 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, static bool 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, const wchar_t *mode, const wchar_t *sets_mode, int terminfo,
io_streams_t &streams) { io_streams_t &streams) {
if (terminfo) { if (terminfo) {
wcstring seq2; wcstring seq2;
if (get_terminfo_sequence(seq, &seq2, streams)) { if (get_terminfo_sequence(seq, &seq2, streams)) {
input_mapping_add(seq2.c_str(), cmds, cmds_len, mode, sets_mode); input_mapping_add(seq2.c_str(), cmds, cmds_len, mode, sets_mode);
} else { } else {
return 1; return true;
} }
} else { } else {
input_mapping_add(seq, cmds, cmds_len, mode, sets_mode); input_mapping_add(seq, cmds, cmds_len, mode, sets_mode);
} }
return 0; return false;
} }
/// Erase specified key bindings /// Erase specified key bindings
@ -392,8 +392,8 @@ static int builtin_bind_add(const wchar_t *seq, const wchar_t *const *cmds, size
/// @param use_terminfo /// @param use_terminfo
/// Whether to look use terminfo -k name /// Whether to look use terminfo -k name
/// ///
static int builtin_bind_erase(wchar_t **seq, int all, const wchar_t *mode, int use_terminfo, static bool builtin_bind_erase(wchar_t **seq, int all, const wchar_t *mode, int use_terminfo,
io_streams_t &streams) { io_streams_t &streams) {
if (all) { if (all) {
const std::vector<input_mapping_name_t> lst = input_mapping_get_names(); const std::vector<input_mapping_name_t> lst = input_mapping_get_names();
for (std::vector<input_mapping_name_t>::const_iterator it = lst.begin(), end = lst.end(); for (std::vector<input_mapping_name_t>::const_iterator it = lst.begin(), end = lst.end();
@ -403,10 +403,10 @@ static int builtin_bind_erase(wchar_t **seq, int all, const wchar_t *mode, int u
} }
} }
return 0; return false;
} }
int res = 0; bool res = false;
if (mode == NULL) mode = DEFAULT_BIND_MODE; //!OCLINT(parameter reassignment) if (mode == NULL) mode = DEFAULT_BIND_MODE; //!OCLINT(parameter reassignment)
while (*seq) { while (*seq) {
@ -415,7 +415,7 @@ static int builtin_bind_erase(wchar_t **seq, int all, const wchar_t *mode, int u
if (get_terminfo_sequence(*seq++, &seq2, streams)) { if (get_terminfo_sequence(*seq++, &seq2, streams)) {
input_mapping_erase(seq2, mode); input_mapping_erase(seq2, mode);
} else { } else {
res = 1; res = true;
} }
} else { } else {
input_mapping_erase(*seq++, mode); input_mapping_erase(*seq++, mode);
@ -497,7 +497,7 @@ static int builtin_bind(parser_t &parser, io_streams_t &streams, wchar_t **argv)
case L'M': { case L'M': {
if (!valid_var_name(w.woptarg)) { if (!valid_var_name(w.woptarg)) {
streams.err.append_format(BUILTIN_ERR_BIND_MODE, cmd, w.woptarg); streams.err.append_format(BUILTIN_ERR_BIND_MODE, cmd, w.woptarg);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
bind_mode = w.woptarg; bind_mode = w.woptarg;
bind_mode_given = true; bind_mode_given = true;
@ -506,7 +506,7 @@ static int builtin_bind(parser_t &parser, io_streams_t &streams, wchar_t **argv)
case L'm': { case L'm': {
if (!valid_var_name(w.woptarg)) { if (!valid_var_name(w.woptarg)) {
streams.err.append_format(BUILTIN_ERR_BIND_MODE, cmd, w.woptarg); streams.err.append_format(BUILTIN_ERR_BIND_MODE, cmd, w.woptarg);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
sets_bind_mode = w.woptarg; sets_bind_mode = w.woptarg;
break; break;
@ -517,7 +517,7 @@ static int builtin_bind(parser_t &parser, io_streams_t &streams, wchar_t **argv)
} }
case L'?': { case L'?': {
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
default: { default: {
DIE("unexpected retval from wgetopt_long_only"); DIE("unexpected retval from wgetopt_long_only");
@ -640,7 +640,7 @@ static int builtin_block(parser_t &parser, io_streams_t &streams, wchar_t **argv
} }
case '?': { case '?': {
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
default: { default: {
DIE("unexpected opt"); DIE("unexpected opt");
@ -653,7 +653,7 @@ static int builtin_block(parser_t &parser, io_streams_t &streams, wchar_t **argv
if (scope != UNSET) { if (scope != UNSET) {
streams.err.append_format(_(L"%ls: Can not specify scope when removing block\n"), streams.err.append_format(_(L"%ls: Can not specify scope when removing block\n"),
argv[0]); argv[0]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
if (parser.global_event_blocks.empty()) { if (parser.global_event_blocks.empty()) {
@ -738,7 +738,7 @@ static int builtin_builtin(parser_t &parser, io_streams_t &streams, wchar_t **ar
} }
case '?': { case '?': {
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
default: { default: {
DIE("unexpected opt"); DIE("unexpected opt");
@ -788,7 +788,7 @@ static int builtin_emit(parser_t &parser, io_streams_t &streams, wchar_t **argv)
} }
case '?': { case '?': {
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
default: { default: {
DIE("unexpected opt"); DIE("unexpected opt");
@ -799,7 +799,7 @@ static int builtin_emit(parser_t &parser, io_streams_t &streams, wchar_t **argv)
if (!argv[w.woptind]) { if (!argv[w.woptind]) {
streams.err.append_format(L"%ls: expected event name\n", argv[0]); streams.err.append_format(L"%ls: expected event name\n", argv[0]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
const wchar_t *eventname = argv[w.woptind]; const wchar_t *eventname = argv[w.woptind];
wcstring_list_t args(argv + w.woptind + 1, argv + argc); wcstring_list_t args(argv + w.woptind + 1, argv + argc);
@ -852,7 +852,7 @@ static int builtin_command(parser_t &parser, io_streams_t &streams, wchar_t **ar
} }
case '?': { case '?': {
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
default: { default: {
DIE("unexpected opt"); DIE("unexpected opt");
@ -863,7 +863,7 @@ static int builtin_command(parser_t &parser, io_streams_t &streams, wchar_t **ar
if (!find_path) { if (!find_path) {
builtin_print_help(parser, streams, argv[0], streams.out); builtin_print_help(parser, streams, argv[0], streams.out);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
int found = 0; int found = 0;
@ -889,7 +889,7 @@ static int builtin_generic(parser_t &parser, io_streams_t &streams, wchar_t **ar
// just print help. // just print help.
if (argc == 1) { if (argc == 1) {
builtin_print_help(parser, streams, argv[0], streams.out); builtin_print_help(parser, streams, argv[0], streams.out);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
static const struct woption long_options[] = {{L"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; static const struct woption long_options[] = {{L"help", no_argument, 0, 'h'}, {0, 0, 0, 0}};
@ -914,7 +914,7 @@ static int builtin_generic(parser_t &parser, io_streams_t &streams, wchar_t **ar
} }
case '?': { case '?': {
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
default: { default: {
DIE("unexpected opt"); DIE("unexpected opt");
@ -1138,7 +1138,7 @@ static int builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t **
} }
case '?': { case '?': {
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
default: { default: {
DIE("unexpected opt"); DIE("unexpected opt");
@ -1152,7 +1152,7 @@ static int builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t **
if (erase + describe + list + query + copy > 1) { if (erase + describe + list + query + copy > 1) {
streams.err.append_format(_(L"%ls: Invalid combination of options\n"), argv[0]); streams.err.append_format(_(L"%ls: Invalid combination of options\n"), argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
if (erase) { if (erase) {
@ -1164,7 +1164,7 @@ static int builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t **
if (argc - w.woptind != 1) { if (argc - w.woptind != 1) {
streams.err.append_format(_(L"%ls: Expected exactly one function name\n"), argv[0]); streams.err.append_format(_(L"%ls: Expected exactly one function name\n"), argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
func = argv[w.woptind]; func = argv[w.woptind];
@ -1180,7 +1180,7 @@ static int builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t **
if (argc - w.woptind != 1) { if (argc - w.woptind != 1) {
streams.err.append_format(_(L"%ls: Expected exactly one function name for --details\n"), streams.err.append_format(_(L"%ls: Expected exactly one function name for --details\n"),
argv[0]); argv[0]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
const wchar_t *funcname = argv[w.woptind]; const wchar_t *funcname = argv[w.woptind];
@ -1213,7 +1213,7 @@ static int builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t **
L"and new function name)\n"), L"and new function name)\n"),
argv[0]); argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
current_func = argv[w.woptind]; current_func = argv[w.woptind];
new_func = argv[w.woptind + 1]; new_func = argv[w.woptind + 1];
@ -1229,7 +1229,7 @@ static int builtin_functions(parser_t &parser, io_streams_t &streams, wchar_t **
streams.err.append_format(_(L"%ls: Illegal function name '%ls'\n"), argv[0], streams.err.append_format(_(L"%ls: Illegal function name '%ls'\n"), argv[0],
new_func.c_str()); new_func.c_str());
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
// Keep things simple: don't allow existing names to be copy targets. // Keep things simple: don't allow existing names to be copy targets.
@ -1376,7 +1376,7 @@ static bool builtin_echo_parse_numeric_sequence(const wchar_t *str, size_t *cons
static int builtin_echo(parser_t &parser, io_streams_t &streams, wchar_t **argv) { static int builtin_echo(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
UNUSED(parser); UNUSED(parser);
// Skip first arg // Skip first arg
if (!*argv++) return STATUS_CMD_ERROR; if (!*argv++) return STATUS_INVALID_ARGS;
// Process options. Options must come at the beginning - the first non-option kicks us out. // Process options. Options must come at the beginning - the first non-option kicks us out.
bool print_newline = true, print_spaces = true, interpret_special_chars = false; bool print_newline = true, print_spaces = true, interpret_special_chars = false;
@ -1530,7 +1530,7 @@ static int builtin_pwd(parser_t &parser, io_streams_t &streams, wchar_t **argv)
UNUSED(parser); UNUSED(parser);
if (argv[1] != NULL) { if (argv[1] != NULL) {
streams.err.append_format(BUILTIN_ERR_ARG_COUNT1, argv[0], 0, builtin_count_args(argv)); streams.err.append_format(BUILTIN_ERR_ARG_COUNT1, argv[0], 0, builtin_count_args(argv));
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
wcstring res = wgetcwd(); wcstring res = wgetcwd();
@ -1547,13 +1547,13 @@ static int validate_function_name(int argc, const wchar_t *const *argv, wcstring
if (argc < 2) { if (argc < 2) {
// This is currently impossible but let's be paranoid. // This is currently impossible but let's be paranoid.
append_format(*out_err, _(L"%ls: Expected function name"), cmd); append_format(*out_err, _(L"%ls: Expected function name"), cmd);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
function_name = argv[1]; function_name = argv[1];
if (!valid_func_name(function_name)) { if (!valid_func_name(function_name)) {
append_format(*out_err, _(L"%ls: Illegal function name '%ls'"), cmd, function_name.c_str()); append_format(*out_err, _(L"%ls: Illegal function name '%ls'"), cmd, function_name.c_str());
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
if (parser_keywords_is_reserved(function_name)) { if (parser_keywords_is_reserved(function_name)) {
@ -1561,7 +1561,7 @@ static int validate_function_name(int argc, const wchar_t *const *argv, wcstring
*out_err, *out_err,
_(L"%ls: The name '%ls' is reserved,\nand can not be used as a function name"), cmd, _(L"%ls: The name '%ls' is reserved,\nand can not be used as a function name"), cmd,
function_name.c_str()); function_name.c_str());
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
return STATUS_CMD_OK; return STATUS_CMD_OK;
@ -1614,7 +1614,7 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis
argv++; argv++;
argc--; argc--;
} else { } else {
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
int opt; int opt;
@ -1629,7 +1629,7 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis
int sig = wcs2sig(w.woptarg); int sig = wcs2sig(w.woptarg);
if (sig == -1) { if (sig == -1) {
append_format(*out_err, _(L"%ls: Unknown signal '%ls'"), cmd, w.woptarg); append_format(*out_err, _(L"%ls: Unknown signal '%ls'"), cmd, w.woptarg);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
events.push_back(event_t::signal_event(sig)); events.push_back(event_t::signal_event(sig));
break; break;
@ -1637,7 +1637,7 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis
case 'v': { case 'v': {
if (!valid_var_name(w.woptarg)) { if (!valid_var_name(w.woptarg)) {
append_format(*out_err, BUILTIN_ERR_VARNAME, cmd, w.woptarg); append_format(*out_err, BUILTIN_ERR_VARNAME, cmd, w.woptarg);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
events.push_back(event_t::variable_event(w.woptarg)); events.push_back(event_t::variable_event(w.woptarg));
@ -1674,7 +1674,7 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis
if (job_id == -1) { if (job_id == -1) {
append_format(*out_err, append_format(*out_err,
_(L"%ls: Cannot find calling job for event handler"), cmd); _(L"%ls: Cannot find calling job for event handler"), cmd);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
e.type = EVENT_JOB_ID; e.type = EVENT_JOB_ID;
e.param1.job_id = job_id; e.param1.job_id = job_id;
@ -1683,7 +1683,7 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis
if (errno || pid < 0) { if (errno || pid < 0) {
append_format(*out_err, _(L"%ls: Invalid process id '%ls'"), cmd, append_format(*out_err, _(L"%ls: Invalid process id '%ls'"), cmd,
w.woptarg); w.woptarg);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
e.type = EVENT_EXIT; e.type = EVENT_EXIT;
@ -1707,7 +1707,7 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis
case 'V': { case 'V': {
if (!valid_var_name(w.woptarg)) { if (!valid_var_name(w.woptarg)) {
append_format(*out_err, BUILTIN_ERR_VARNAME, cmd, w.woptarg); append_format(*out_err, BUILTIN_ERR_VARNAME, cmd, w.woptarg);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
inherit_vars.push_back(w.woptarg); inherit_vars.push_back(w.woptarg);
break; break;
@ -1718,11 +1718,11 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis
} }
case ':': { case ':': {
streams.err.append_format(BUILTIN_ERR_MISSING, cmd, argv[w.woptind - 1]); streams.err.append_format(BUILTIN_ERR_MISSING, cmd, argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
case '?': { case '?': {
builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]); builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
default: { default: {
DIE("unexpected retval from wgetopt_long"); DIE("unexpected retval from wgetopt_long");
@ -1739,7 +1739,7 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis
} else { } else {
append_format(*out_err, _(L"%ls: Unexpected positional argument '%ls'"), cmd, append_format(*out_err, _(L"%ls: Unexpected positional argument '%ls'"), cmd,
argv[w.woptind]); argv[w.woptind]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
} }
@ -1805,7 +1805,7 @@ static int builtin_random(parser_t &parser, io_streams_t &streams, wchar_t **arg
} }
case '?': { case '?': {
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
default: { default: {
DIE("unexpected opt"); DIE("unexpected opt");
@ -1821,7 +1821,7 @@ static int builtin_random(parser_t &parser, io_streams_t &streams, wchar_t **arg
if (arg_count >= 1 && !wcscmp(argv[w.woptind], L"choice")) { if (arg_count >= 1 && !wcscmp(argv[w.woptind], L"choice")) {
if (arg_count == 1) { if (arg_count == 1) {
streams.err.append_format(L"%ls: nothing to choose from\n", argv[0]); streams.err.append_format(L"%ls: nothing to choose from\n", argv[0]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
choice = true; choice = true;
start = 1; start = 1;
@ -1851,7 +1851,7 @@ static int builtin_random(parser_t &parser, io_streams_t &streams, wchar_t **arg
step = 1; step = 1;
} else if (arg_count == 1) { } else if (arg_count == 1) {
long long seed = parse_ll(argv[w.woptind]); long long seed = parse_ll(argv[w.woptind]);
if (parse_error) return STATUS_CMD_ERROR; if (parse_error) return STATUS_INVALID_ARGS;
engine.seed(static_cast<uint32_t>(seed)); engine.seed(static_cast<uint32_t>(seed));
return STATUS_CMD_OK; return STATUS_CMD_OK;
} else if (arg_count == 2) { } else if (arg_count == 2) {
@ -1864,17 +1864,17 @@ static int builtin_random(parser_t &parser, io_streams_t &streams, wchar_t **arg
end = parse_ll(argv[w.woptind + 2]); end = parse_ll(argv[w.woptind + 2]);
} else { } else {
streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]); streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
if (parse_error) { if (parse_error) {
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} else if (start >= end) { } else if (start >= end) {
streams.err.append_format(L"%ls: END must be greater than START\n", argv[0]); streams.err.append_format(L"%ls: END must be greater than START\n", argv[0]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} else if (step == 0) { } else if (step == 0) {
streams.err.append_format(L"%ls: STEP must be a positive integer\n", argv[0]); streams.err.append_format(L"%ls: STEP must be a positive integer\n", argv[0]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
} }
@ -1897,7 +1897,7 @@ static int builtin_random(parser_t &parser, io_streams_t &streams, wchar_t **arg
if (!choice && start == real_end) { if (!choice && start == real_end) {
streams.err.append_format(L"%ls: range contains only one possible value\n", argv[0]); streams.err.append_format(L"%ls: range contains only one possible value\n", argv[0]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
std::uniform_int_distribution<long long> dist(start, real_end); std::uniform_int_distribution<long long> dist(start, real_end);
@ -2164,13 +2164,13 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv)
streams.err.append_format(_(L"%ls: Argument '%ls' is out of range\n"), streams.err.append_format(_(L"%ls: Argument '%ls' is out of range\n"),
argv[0], w.woptarg); argv[0], w.woptarg);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
streams.err.append_format(_(L"%ls: Argument '%ls' must be an integer\n"), streams.err.append_format(_(L"%ls: Argument '%ls' must be an integer\n"),
argv[0], w.woptarg); argv[0], w.woptarg);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
break; break;
} }
@ -2196,11 +2196,11 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv)
} }
case ':': { case ':': {
streams.err.append_format(BUILTIN_ERR_MISSING, cmd, argv[w.woptind - 1]); streams.err.append_format(BUILTIN_ERR_MISSING, cmd, argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
case L'?': { case L'?': {
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
default: { default: {
DIE("unexpected retval from wgetopt_long"); DIE("unexpected retval from wgetopt_long");
@ -2212,7 +2212,7 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv)
if (prompt && prompt_str) { if (prompt && prompt_str) {
streams.err.append_format(_(L"%ls: You can't specify both -p and -P\n"), argv[0]); streams.err.append_format(_(L"%ls: You can't specify both -p and -P\n"), argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
if (prompt_str) { if (prompt_str) {
@ -2225,7 +2225,7 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv)
if ((place & ENV_UNEXPORT) && (place & ENV_EXPORT)) { if ((place & ENV_UNEXPORT) && (place & ENV_EXPORT)) {
streams.err.append_format(BUILTIN_ERR_EXPUNEXP, argv[0]); streams.err.append_format(BUILTIN_ERR_EXPUNEXP, argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
if ((place & ENV_LOCAL ? 1 : 0) + (place & ENV_GLOBAL ? 1 : 0) + if ((place & ENV_LOCAL ? 1 : 0) + (place & ENV_GLOBAL ? 1 : 0) +
@ -2234,7 +2234,7 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv)
streams.err.append_format(BUILTIN_ERR_GLOCAL, argv[0]); streams.err.append_format(BUILTIN_ERR_GLOCAL, argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
if (array && w.woptind + 1 != argc) { if (array && w.woptind + 1 != argc) {
@ -2242,7 +2242,7 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv)
argv[0]); argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
// Verify all variable names. // Verify all variable names.
@ -2250,7 +2250,7 @@ static int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv)
if (!valid_var_name(argv[i])) { if (!valid_var_name(argv[i])) {
streams.err.append_format(BUILTIN_ERR_VARNAME, cmd, argv[i]); streams.err.append_format(BUILTIN_ERR_VARNAME, cmd, argv[i]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
} }
@ -2384,7 +2384,7 @@ static bool set_status_cmd(wchar_t *const cmd, status_cmd_t *status_cmd, status_
const wchar_t *subcmd_str = enum_to_str(status_cmd, status_enum_map); \ const wchar_t *subcmd_str = enum_to_str(status_cmd, status_enum_map); \
if (!subcmd_str) subcmd_str = L"default"; \ if (!subcmd_str) subcmd_str = L"default"; \
streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd, subcmd_str, 0, args.size()); \ streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd, subcmd_str, 0, args.size()); \
status = STATUS_CMD_ERROR; \ status = STATUS_INVALID_ARGS; \
break; \ break; \
} }
@ -2507,11 +2507,11 @@ static int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **arg
} }
case ':': { case ':': {
builtin_missing_argument(parser, streams, argv[0], argv[w.woptind - 1]); builtin_missing_argument(parser, streams, argv[0], argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
case '?': { case '?': {
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
default: { default: {
DIE("unexpected retval from wgetopt_long"); DIE("unexpected retval from wgetopt_long");
@ -2561,7 +2561,7 @@ static int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **arg
const wchar_t *subcmd_str = enum_to_str(status_cmd, status_enum_map); const wchar_t *subcmd_str = enum_to_str(status_cmd, status_enum_map);
streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd, subcmd_str, 1, streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd, subcmd_str, 1,
args.size()); args.size());
status = STATUS_CMD_ERROR; status = STATUS_INVALID_ARGS;
break; break;
} }
new_job_control_mode = job_control_str_to_mode(args[0].c_str(), cmd, streams); new_job_control_mode = job_control_str_to_mode(args[0].c_str(), cmd, streams);
@ -2645,7 +2645,7 @@ static int builtin_exit(parser_t &parser, io_streams_t &streams, wchar_t **argv)
if (argc > 2) { if (argc > 2) {
streams.err.append_format(_(L"%ls: Too many arguments\n"), argv[0]); streams.err.append_format(_(L"%ls: Too many arguments\n"), argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
long ec; long ec;
@ -2657,7 +2657,7 @@ static int builtin_exit(parser_t &parser, io_streams_t &streams, wchar_t **argv)
streams.err.append_format(_(L"%ls: Argument '%ls' must be an integer\n"), argv[0], streams.err.append_format(_(L"%ls: Argument '%ls' must be an integer\n"), argv[0],
argv[1]); argv[1]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
} }
reader_exit(1, 0); reader_exit(1, 0);
@ -2777,11 +2777,11 @@ static int builtin_contains(parser_t &parser, io_streams_t &streams, wchar_t **a
} }
case ':': { case ':': {
builtin_missing_argument(parser, streams, argv[0], argv[w.woptind - 1]); builtin_missing_argument(parser, streams, argv[0], argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
case '?': { case '?': {
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
case 'i': { case 'i': {
should_output_index = true; should_output_index = true;
@ -2801,11 +2801,11 @@ static int builtin_contains(parser_t &parser, io_streams_t &streams, wchar_t **a
for (int i = w.woptind + 1; i < argc; i++) { for (int i = w.woptind + 1; i < argc; i++) {
if (!wcscmp(needle, argv[i])) { if (!wcscmp(needle, argv[i])) {
if (should_output_index) streams.out.append_format(L"%d\n", i - w.woptind); if (should_output_index) streams.out.append_format(L"%d\n", i - w.woptind);
return 0; return STATUS_CMD_OK;
} }
} }
} }
return 1; return STATUS_CMD_ERROR;
} }
/// The . (dot) builtin, sometimes called source. Evaluates the contents of a file. /// The . (dot) builtin, sometimes called source. Evaluates the contents of a file.
@ -2933,7 +2933,7 @@ static int builtin_fg(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
} }
if (!j) { if (!j) {
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
if (streams.err_is_redirected) { if (streams.err_is_redirected) {
@ -3008,12 +3008,12 @@ static int builtin_bg(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
if (errno || pid < 0) { if (errno || pid < 0) {
streams.err.append_format(_(L"%ls: '%ls' is not a valid job specifier\n"), L"bg", streams.err.append_format(_(L"%ls: '%ls' is not a valid job specifier\n"), L"bg",
argv[i]); argv[i]);
res = STATUS_CMD_ERROR; res = STATUS_INVALID_ARGS;
} }
pids.push_back(pid); pids.push_back(pid);
} }
if (res == STATUS_CMD_ERROR) return res; if (res != STATUS_CMD_OK) return res;
// Background all existing jobs that match the pids. // Background all existing jobs that match the pids.
// Non-existent jobs aren't an error, but information about them is useful. // Non-existent jobs aren't an error, but information about them is useful.
@ -3033,7 +3033,7 @@ static int disown_job(parser_t &parser, io_streams_t &streams, job_t *j) {
if (j == 0) { if (j == 0) {
streams.err.append_format(_(L"%ls: Unknown job '%ls'\n"), L"bg"); streams.err.append_format(_(L"%ls: Unknown job '%ls'\n"), L"bg");
builtin_print_help(parser, streams, L"disown", streams.err); builtin_print_help(parser, streams, L"disown", streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
// Stopped disowned jobs must be manually signalled; explain how to do so // Stopped disowned jobs must be manually signalled; explain how to do so
@ -3083,7 +3083,7 @@ static int builtin_disown(parser_t &parser, io_streams_t &streams, wchar_t **arg
if (errno || pid < 0) { if (errno || pid < 0) {
streams.err.append_format(_(L"%ls: '%ls' is not a valid job specifier\n"), argv[0], streams.err.append_format(_(L"%ls: '%ls' is not a valid job specifier\n"), argv[0],
argv[i]); argv[i]);
res = STATUS_CMD_ERROR; res = STATUS_INVALID_ARGS;
} else { } else {
if (job_t *j = parser.job_get_from_pid(pid)) { if (job_t *j = parser.job_get_from_pid(pid)) {
jobs.insert(j); jobs.insert(j);
@ -3092,7 +3092,7 @@ static int builtin_disown(parser_t &parser, io_streams_t &streams, wchar_t **arg
} }
} }
} }
if (res == STATUS_CMD_ERROR) { if (res != STATUS_CMD_OK) {
return res; return res;
} }
@ -3115,7 +3115,7 @@ static int builtin_break_continue(parser_t &parser, io_streams_t &streams, wchar
streams.err.append_format(BUILTIN_ERR_UNKNOWN, argv[0], argv[1]); streams.err.append_format(BUILTIN_ERR_UNKNOWN, argv[0], argv[1]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
// Find the index of the enclosing for or while loop. Recall that incrementing loop_idx goes // Find the index of the enclosing for or while loop. Recall that incrementing loop_idx goes
@ -3148,7 +3148,7 @@ static int builtin_break_continue(parser_t &parser, io_streams_t &streams, wchar
static int builtin_breakpoint(parser_t &parser, io_streams_t &streams, wchar_t **argv) { static int builtin_breakpoint(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
if (argv[1] != NULL) { if (argv[1] != NULL) {
streams.err.append_format(BUILTIN_ERR_ARG_COUNT1, argv[0], 0, builtin_count_args(argv)); streams.err.append_format(BUILTIN_ERR_ARG_COUNT1, argv[0], 0, builtin_count_args(argv));
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
const breakpoint_block_t *bpb = parser.push_block<breakpoint_block_t>(); const breakpoint_block_t *bpb = parser.push_block<breakpoint_block_t>();
@ -3167,7 +3167,7 @@ static int builtin_return(parser_t &parser, io_streams_t &streams, wchar_t **arg
if (argc > 2) { if (argc > 2) {
streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]); streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
int status; int status;
@ -3177,7 +3177,7 @@ static int builtin_return(parser_t &parser, io_streams_t &streams, wchar_t **arg
streams.err.append_format(_(L"%ls: Argument '%ls' must be an integer\n"), argv[0], streams.err.append_format(_(L"%ls: Argument '%ls' must be an integer\n"), argv[0],
argv[1]); argv[1]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
} else { } else {
status = proc_get_last_status(); status = proc_get_last_status();
@ -3234,13 +3234,13 @@ static bool set_hist_cmd(wchar_t *const cmd, hist_cmd_t *hist_cmd, hist_cmd_t su
const wchar_t *subcmd_str = enum_to_str(hist_cmd, hist_enum_map); \ const wchar_t *subcmd_str = enum_to_str(hist_cmd, hist_enum_map); \
streams.err.append_format(_(L"%ls: you cannot use any options with the %ls command\n"), \ streams.err.append_format(_(L"%ls: you cannot use any options with the %ls command\n"), \
cmd, subcmd_str); \ cmd, subcmd_str); \
status = STATUS_CMD_ERROR; \ status = STATUS_INVALID_ARGS; \
break; \ break; \
} \ } \
if (args.size() != 0) { \ if (args.size() != 0) { \
const wchar_t *subcmd_str = enum_to_str(hist_cmd, hist_enum_map); \ const wchar_t *subcmd_str = enum_to_str(hist_cmd, hist_enum_map); \
streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd, subcmd_str, 0, args.size()); \ streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd, subcmd_str, 0, args.size()); \
status = STATUS_CMD_ERROR; \ status = STATUS_INVALID_ARGS; \
break; \ break; \
} }
@ -3344,7 +3344,7 @@ static int builtin_history(parser_t &parser, io_streams_t &streams, wchar_t **ar
if (errno) { if (errno) {
streams.err.append_format(_(L"%ls: max value '%ls' is not a valid number\n"), streams.err.append_format(_(L"%ls: max value '%ls' is not a valid number\n"),
argv[0], w.woptarg); argv[0], w.woptarg);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
break; break;
} }
@ -3358,14 +3358,14 @@ static int builtin_history(parser_t &parser, io_streams_t &streams, wchar_t **ar
} }
case ':': { case ':': {
streams.err.append_format(BUILTIN_ERR_MISSING, cmd, argv[w.woptind - 1]); streams.err.append_format(BUILTIN_ERR_MISSING, cmd, argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
case '?': { case '?': {
// Try to parse it as a number; e.g., "-123". // Try to parse it as a number; e.g., "-123".
max_items = fish_wcstol(argv[w.woptind - 1] + 1); max_items = fish_wcstol(argv[w.woptind - 1] + 1);
if (errno) { if (errno) {
streams.err.append_format(BUILTIN_ERR_UNKNOWN, cmd, argv[w.woptind - 1]); streams.err.append_format(BUILTIN_ERR_UNKNOWN, cmd, argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
w.nextchar = NULL; w.nextchar = NULL;
break; break;
@ -3380,7 +3380,7 @@ static int builtin_history(parser_t &parser, io_streams_t &streams, wchar_t **ar
if (max_items <= 0) { if (max_items <= 0) {
streams.err.append_format(_(L"%ls: max value '%ls' is not a valid number\n"), argv[0], streams.err.append_format(_(L"%ls: max value '%ls' is not a valid number\n"), argv[0],
w.woptarg); w.woptarg);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
// If a history command hasn't already been specified via a flag check the first word. // If a history command hasn't already been specified via a flag check the first word.
@ -3390,7 +3390,7 @@ static int builtin_history(parser_t &parser, io_streams_t &streams, wchar_t **ar
hist_cmd_t subcmd = str_to_enum(argv[w.woptind], hist_enum_map, hist_enum_map_len); hist_cmd_t subcmd = str_to_enum(argv[w.woptind], hist_enum_map, hist_enum_map_len);
if (subcmd != HIST_UNDEF) { if (subcmd != HIST_UNDEF) {
if (!set_hist_cmd(cmd, &hist_cmd, subcmd, streams)) { if (!set_hist_cmd(cmd, &hist_cmd, subcmd, streams)) {
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
w.woptind++; w.woptind++;
} }
@ -3422,13 +3422,13 @@ static int builtin_history(parser_t &parser, io_streams_t &streams, wchar_t **ar
// be handled only by the history function's interactive delete feature. // be handled only by the history function's interactive delete feature.
if (search_type != HISTORY_SEARCH_TYPE_EXACT) { if (search_type != HISTORY_SEARCH_TYPE_EXACT) {
streams.err.append_format(_(L"builtin history delete only supports --exact\n")); streams.err.append_format(_(L"builtin history delete only supports --exact\n"));
status = STATUS_CMD_ERROR; status = STATUS_INVALID_ARGS;
break; break;
} }
if (!case_sensitive) { if (!case_sensitive) {
streams.err.append_format( streams.err.append_format(
_(L"builtin history delete only supports --case-sensitive\n")); _(L"builtin history delete only supports --case-sensitive\n"));
status = STATUS_CMD_ERROR; status = STATUS_INVALID_ARGS;
break; break;
} }
for (wcstring_list_t::const_iterator iter = args.begin(); iter != args.end(); ++iter) { for (wcstring_list_t::const_iterator iter = args.begin(); iter != args.end(); ++iter) {
@ -3516,8 +3516,8 @@ int builtin_true(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
UNUSED(parser); UNUSED(parser);
UNUSED(streams); UNUSED(streams);
if (argv[1] != NULL) { if (argv[1] != NULL) {
streams.err.append_format(BUILTIN_ERR_ARG_COUNT1, argv[0], 0, builtin_count_args(argv)); streams.err.append_format(BUILTIN_ERR_ARG_COUNT1, argv[0], 0, builtin_count_args(argv) - 1);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
return STATUS_CMD_OK; return STATUS_CMD_OK;
} }
@ -3526,8 +3526,8 @@ int builtin_false(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
UNUSED(parser); UNUSED(parser);
UNUSED(streams); UNUSED(streams);
if (argv[1] != NULL) { if (argv[1] != NULL) {
streams.err.append_format(BUILTIN_ERR_ARG_COUNT1, argv[0], 0, builtin_count_args(argv)); streams.err.append_format(BUILTIN_ERR_ARG_COUNT1, argv[0], 0, builtin_count_args(argv) - 1);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
return STATUS_CMD_ERROR; return STATUS_CMD_ERROR;
} }
@ -3542,7 +3542,7 @@ int builtin_realpath(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
if (argc != 2) { if (argc != 2) {
builtin_print_help(parser, streams, argv[0], streams.out); builtin_print_help(parser, streams, argv[0], streams.out);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
wchar_t *real_path = wrealpath(argv[1], NULL); wchar_t *real_path = wrealpath(argv[1], NULL);
@ -3667,7 +3667,7 @@ static bool builtin_handles_help(const wchar_t *cmd) {
int builtin_run(parser_t &parser, const wchar_t *const *argv, io_streams_t &streams) { int builtin_run(parser_t &parser, const wchar_t *const *argv, io_streams_t &streams) {
UNUSED(parser); UNUSED(parser);
UNUSED(streams); UNUSED(streams);
if (argv == NULL || argv[0] == NULL) return STATUS_CMD_ERROR; if (argv == NULL || argv[0] == NULL) return STATUS_INVALID_ARGS;
const builtin_data_t *data = builtin_lookup(argv[0]); const builtin_data_t *data = builtin_lookup(argv[0]);
if (argv[1] != NULL && !builtin_handles_help(argv[0]) && argv[2] == NULL && if (argv[1] != NULL && !builtin_handles_help(argv[0]) && argv[2] == NULL &&

View file

@ -201,13 +201,13 @@ int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv)
if (is_interactive_session) { if (is_interactive_session) {
// Prompt change requested while we don't have a prompt, most probably while reading the // Prompt change requested while we don't have a prompt, most probably while reading the
// init files. Just ignore it. // init files. Just ignore it.
return 1; return STATUS_CMD_ERROR;
} }
streams.err.append(argv[0]); streams.err.append(argv[0]);
streams.err.append(L": Can not set commandline in non-interactive mode\n"); streams.err.append(L": Can not set commandline in non-interactive mode\n");
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return 1; return STATUS_CMD_ERROR;
} }
w.woptind = 0; w.woptind = 0;
@ -244,7 +244,7 @@ int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv)
long_options[opt_index].name); long_options[opt_index].name);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return 1; return STATUS_CMD_ERROR;
} }
case L'a': { case L'a': {
append_mode = APPEND_MODE; append_mode = APPEND_MODE;
@ -313,11 +313,11 @@ int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv)
} }
case 'h': { case 'h': {
builtin_print_help(parser, streams, argv[0], streams.out); builtin_print_help(parser, streams, argv[0], streams.out);
return 0; return STATUS_CMD_OK;
} }
case L'?': { case L'?': {
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return 1; return STATUS_INVALID_ARGS;
} }
default: { default: {
DIE("unexpected opt"); DIE("unexpected opt");
@ -333,16 +333,14 @@ int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv)
if (buffer_part || cut_at_cursor || append_mode || tokenize || cursor_mode || line_mode || if (buffer_part || cut_at_cursor || append_mode || tokenize || cursor_mode || line_mode ||
search_mode || paging_mode) { search_mode || paging_mode) {
streams.err.append_format(BUILTIN_ERR_COMBO, argv[0]); streams.err.append_format(BUILTIN_ERR_COMBO, argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return 1; return STATUS_INVALID_ARGS;
} }
if (argc == w.woptind) { if (argc == w.woptind) {
streams.err.append_format(BUILTIN_ERR_MISSING, argv[0]); streams.err.append_format(BUILTIN_ERR_MISSING, argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return 1; return STATUS_INVALID_ARGS;
} }
for (i = w.woptind; i < argc; i++) { for (i = w.woptind; i < argc; i++) {
@ -355,11 +353,11 @@ int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv)
streams.err.append_format(_(L"%ls: Unknown input function '%ls'"), argv[0], streams.err.append_format(_(L"%ls: Unknown input function '%ls'"), argv[0],
argv[i]); argv[i]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return 1; return STATUS_INVALID_ARGS;
} }
} }
return 0; return STATUS_CMD_OK;
} }
if (selection_mode) { if (selection_mode) {
@ -368,40 +366,37 @@ int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv)
if (reader_get_selection(&start, &len)) { if (reader_get_selection(&start, &len)) {
streams.out.append(buffer + start, len); streams.out.append(buffer + start, len);
} }
return 0; return STATUS_CMD_OK;
} }
// Check for invalid switch combinations. // Check for invalid switch combinations.
if ((search_mode || line_mode || cursor_mode || paging_mode) && (argc - w.woptind > 1)) { if ((search_mode || line_mode || cursor_mode || paging_mode) && (argc - w.woptind > 1)) {
streams.err.append_format(L"%ls: Too many arguments", argv[0]); streams.err.append_format(L"%ls: Too many arguments", argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return 1; return STATUS_INVALID_ARGS;
} }
if ((buffer_part || tokenize || cut_at_cursor) && if ((buffer_part || tokenize || cut_at_cursor) &&
(cursor_mode || line_mode || search_mode || paging_mode)) { (cursor_mode || line_mode || search_mode || paging_mode)) {
streams.err.append_format(BUILTIN_ERR_COMBO, argv[0]); streams.err.append_format(BUILTIN_ERR_COMBO, argv[0]);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return 1; return STATUS_INVALID_ARGS;
} }
if ((tokenize || cut_at_cursor) && (argc - w.woptind)) { if ((tokenize || cut_at_cursor) && (argc - w.woptind)) {
streams.err.append_format( streams.err.append_format(
BUILTIN_ERR_COMBO2, argv[0], BUILTIN_ERR_COMBO2, argv[0],
L"--cut-at-cursor and --tokenize can not be used when setting the commandline"); L"--cut-at-cursor and --tokenize can not be used when setting the commandline");
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return 1; return STATUS_INVALID_ARGS;
} }
if (append_mode && !(argc - w.woptind)) { if (append_mode && !(argc - w.woptind)) {
streams.err.append_format( streams.err.append_format(
BUILTIN_ERR_COMBO2, argv[0], BUILTIN_ERR_COMBO2, argv[0],
L"insertion mode switches can not be used when not in insertion mode"); L"insertion mode switches can not be used when not in insertion mode");
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return 1; return STATUS_INVALID_ARGS;
} }
// Set default modes. // Set default modes.
@ -427,14 +422,14 @@ int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv)
} else { } else {
streams.out.append_format(L"%lu\n", (unsigned long)reader_get_cursor_pos()); streams.out.append_format(L"%lu\n", (unsigned long)reader_get_cursor_pos());
} }
return 0; return STATUS_CMD_OK;
} }
if (line_mode) { if (line_mode) {
size_t pos = reader_get_cursor_pos(); size_t pos = reader_get_cursor_pos();
const wchar_t *buff = reader_get_buffer(); const wchar_t *buff = reader_get_buffer();
streams.out.append_format(L"%lu\n", (unsigned long)parse_util_lineno(buff, pos)); streams.out.append_format(L"%lu\n", (unsigned long)parse_util_lineno(buff, pos));
return 0; return STATUS_CMD_OK;
} }
if (search_mode) { if (search_mode) {
@ -483,5 +478,5 @@ int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv)
replace_part(begin, end, sb.c_str(), append_mode); replace_part(begin, end, sb.c_str(), append_mode);
} }
return 0; return STATUS_CMD_OK;
} }

View file

@ -175,7 +175,7 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
cmd_to_complete.push_back(tmp); cmd_to_complete.push_back(tmp);
} else { } else {
streams.err.append_format(_(L"%ls: Invalid token '%ls'\n"), cmd, w.woptarg); streams.err.append_format(_(L"%ls: Invalid token '%ls'\n"), cmd, w.woptarg);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
break; break;
} }
@ -195,7 +195,7 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
short_opt.append(w.woptarg); short_opt.append(w.woptarg);
if (w.woptarg[0] == '\0') { if (w.woptarg[0] == '\0') {
streams.err.append_format(_(L"%ls: -s requires a non-empty string\n"), cmd); streams.err.append_format(_(L"%ls: -s requires a non-empty string\n"), cmd);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
break; break;
} }
@ -203,7 +203,7 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
gnu_opt.push_back(w.woptarg); gnu_opt.push_back(w.woptarg);
if (w.woptarg[0] == '\0') { if (w.woptarg[0] == '\0') {
streams.err.append_format(_(L"%ls: -l requires a non-empty string\n"), cmd); streams.err.append_format(_(L"%ls: -l requires a non-empty string\n"), cmd);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
break; break;
} }
@ -211,7 +211,7 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
old_opt.push_back(w.woptarg); old_opt.push_back(w.woptarg);
if (w.woptarg[0] == '\0') { if (w.woptarg[0] == '\0') {
streams.err.append_format(_(L"%ls: -o requires a non-empty string\n"), cmd); streams.err.append_format(_(L"%ls: -o requires a non-empty string\n"), cmd);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
break; break;
} }
@ -238,7 +238,7 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
// This corresponds to using 'complete -C' in non-interactive mode. // This corresponds to using 'complete -C' in non-interactive mode.
// See #2361. // See #2361.
builtin_missing_argument(parser, streams, cmd, argv[w.woptind - 1]); builtin_missing_argument(parser, streams, cmd, argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
do_complete_param = arg; do_complete_param = arg;
break; break;
@ -249,11 +249,11 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
} }
case ':': { case ':': {
builtin_missing_argument(parser, streams, cmd, argv[w.woptind - 1]); builtin_missing_argument(parser, streams, cmd, argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
case '?': { case '?': {
builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]); builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
default: { default: {
DIE("unexpected retval from wgetopt_long"); DIE("unexpected retval from wgetopt_long");
@ -265,7 +265,7 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
if (w.woptind != argc) { if (w.woptind != argc) {
streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, cmd); streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, cmd);
builtin_print_help(parser, streams, cmd, streams.err); builtin_print_help(parser, streams, cmd, streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
if (condition && wcslen(condition)) { if (condition && wcslen(condition)) {

View file

@ -155,11 +155,11 @@ int builtin_jobs(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
} }
case 'h': { case 'h': {
builtin_print_help(parser, streams, argv[0], streams.out); builtin_print_help(parser, streams, argv[0], streams.out);
return 0; return STATUS_CMD_OK;
} }
case '?': { case '?': {
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]); builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
return 1; return STATUS_INVALID_ARGS;
} }
default: { default: {
DIE("unexpected opt"); DIE("unexpected opt");
@ -175,7 +175,7 @@ int builtin_jobs(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
while ((j = jobs.next())) { while ((j = jobs.next())) {
if ((j->flags & JOB_CONSTRUCTED) && !job_is_completed(j)) { if ((j->flags & JOB_CONSTRUCTED) && !job_is_completed(j)) {
builtin_jobs_print(j, mode, !streams.out_is_redirected, streams); builtin_jobs_print(j, mode, !streams.out_is_redirected, streams);
return 0; return STATUS_CMD_ERROR;
} }
} }
@ -187,7 +187,7 @@ int builtin_jobs(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
int pid = fish_wcstoi(argv[i]); int pid = fish_wcstoi(argv[i]);
if (errno || pid < 0) { if (errno || pid < 0) {
streams.err.append_format(_(L"%ls: '%ls' is not a job\n"), argv[0], argv[i]); streams.err.append_format(_(L"%ls: '%ls' is not a job\n"), argv[0], argv[i]);
return 1; return STATUS_INVALID_ARGS;
} }
const job_t *j = job_get_from_pid(pid); const job_t *j = job_get_from_pid(pid);
@ -197,7 +197,7 @@ int builtin_jobs(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
found = 1; found = 1;
} else { } else {
streams.err.append_format(_(L"%ls: No suitable job: %d\n"), argv[0], pid); streams.err.append_format(_(L"%ls: No suitable job: %d\n"), argv[0], pid);
return 1; return STATUS_CMD_ERROR;
} }
} }
} else { } else {
@ -218,8 +218,8 @@ int builtin_jobs(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
if (!streams.out_is_redirected) { if (!streams.out_is_redirected) {
streams.out.append_format(_(L"%ls: There are no jobs\n"), argv[0]); streams.out.append_format(_(L"%ls: There are no jobs\n"), argv[0]);
} }
return 1; return STATUS_CMD_ERROR;
} }
return 0; return STATUS_CMD_OK;
} }

View file

@ -728,7 +728,7 @@ int builtin_printf(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
if (argc <= 1) { if (argc <= 1) {
state.fatal_error(_(L"printf: not enough arguments")); state.fatal_error(_(L"printf: not enough arguments"));
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
format = argv[1]; format = argv[1];

View file

@ -344,7 +344,7 @@ int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
// Variables used for performing the actual work. // Variables used for performing the actual work.
wchar_t *dest = 0; wchar_t *dest = 0;
int retcode = 0; int retcode = STATUS_CMD_OK;
int scope; int scope;
int slice = 0; int slice = 0;
@ -402,11 +402,11 @@ int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
} }
case 'h': { case 'h': {
builtin_print_help(parser, streams, cmd, streams.out); builtin_print_help(parser, streams, cmd, streams.out);
return 0; return STATUS_CMD_OK;
} }
case '?': { case '?': {
builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]); builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]);
return 1; return STATUS_INVALID_ARGS;
} }
default: { break; } default: { break; }
} }
@ -416,31 +416,29 @@ int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
// a variable (-q) we can not also specify scope. // a variable (-q) we can not also specify scope.
if (query && (erase || list)) { if (query && (erase || list)) {
streams.err.append_format(BUILTIN_ERR_COMBO, cmd); streams.err.append_format(BUILTIN_ERR_COMBO, cmd);
builtin_print_help(parser, streams, cmd, streams.err); builtin_print_help(parser, streams, cmd, streams.err);
return 1; return STATUS_INVALID_ARGS;
} }
// We can't both list and erase variables. // We can't both list and erase variables.
if (erase && list) { if (erase && list) {
streams.err.append_format(BUILTIN_ERR_COMBO, cmd); streams.err.append_format(BUILTIN_ERR_COMBO, cmd);
builtin_print_help(parser, streams, cmd, streams.err); builtin_print_help(parser, streams, cmd, streams.err);
return 1; return STATUS_INVALID_ARGS;
} }
// Variables can only have one scope. // Variables can only have one scope.
if (local + global + universal > 1) { if (local + global + universal > 1) {
streams.err.append_format(BUILTIN_ERR_GLOCAL, cmd); streams.err.append_format(BUILTIN_ERR_GLOCAL, cmd);
builtin_print_help(parser, streams, cmd, streams.err); builtin_print_help(parser, streams, cmd, streams.err);
return 1; return STATUS_INVALID_ARGS;
} }
// Variables can only have one export status. // Variables can only have one export status.
if (exportv && unexport) { if (exportv && unexport) {
streams.err.append_format(BUILTIN_ERR_EXPUNEXP, argv[0]); streams.err.append_format(BUILTIN_ERR_EXPUNEXP, argv[0]);
builtin_print_help(parser, streams, cmd, streams.err); builtin_print_help(parser, streams, cmd, streams.err);
return 1; return STATUS_INVALID_ARGS;
} }
// Calculate the scope value for variable assignement. // Calculate the scope value for variable assignement.
@ -496,16 +494,15 @@ int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
if (list) { if (list) {
// Maybe we should issue an error if there are any other arguments? // Maybe we should issue an error if there are any other arguments?
print_variables(0, 0, shorten_ok, scope, streams); print_variables(0, 0, shorten_ok, scope, streams);
return 0; return STATUS_CMD_OK;
} }
if (w.woptind == argc) { if (w.woptind == argc) {
// Print values of variables. // Print values of variables.
if (erase) { if (erase) {
streams.err.append_format(_(L"%ls: Erase needs a variable name\n"), cmd); streams.err.append_format(_(L"%ls: Erase needs a variable name\n"), cmd);
builtin_print_help(parser, streams, cmd, streams.err); builtin_print_help(parser, streams, cmd, streams.err);
retcode = 1; retcode = STATUS_INVALID_ARGS;
} else { } else {
print_variables(1, 1, shorten_ok, scope, streams); print_variables(1, 1, shorten_ok, scope, streams);
} }
@ -524,7 +521,7 @@ int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
if (!valid_var_name(dest)) { if (!valid_var_name(dest)) {
streams.err.append_format(BUILTIN_ERR_VARNAME, cmd, dest); streams.err.append_format(BUILTIN_ERR_VARNAME, cmd, dest);
builtin_print_help(parser, streams, argv[0], streams.err); builtin_print_help(parser, streams, argv[0], streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
// Set assignment can work in two modes, either using slices or using the whole array. We detect // Set assignment can work in two modes, either using slices or using the whole array. We detect

View file

@ -125,7 +125,7 @@ int builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
return STATUS_CMD_OK; return STATUS_CMD_OK;
} }
case '?': { case '?': {
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
default: { default: {
DIE("unexpected opt"); DIE("unexpected opt");
@ -140,7 +140,7 @@ int builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
rgb_color_t fg = rgb_color_t(argv[w.woptind]); rgb_color_t fg = rgb_color_t(argv[w.woptind]);
if (fg.is_none()) { if (fg.is_none()) {
streams.err.append_format(_(L"%ls: Unknown color '%ls'\n"), argv[0], argv[w.woptind]); streams.err.append_format(_(L"%ls: Unknown color '%ls'\n"), argv[0], argv[w.woptind]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
fgcolors.push_back(fg); fgcolors.push_back(fg);
} }
@ -148,7 +148,7 @@ int builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
if (fgcolors.empty() && bgcolor == NULL && !bold && !underline && !italics && !dim && if (fgcolors.empty() && bgcolor == NULL && !bold && !underline && !italics && !dim &&
!reverse) { !reverse) {
streams.err.append_format(_(L"%ls: Expected an argument\n"), argv[0]); streams.err.append_format(_(L"%ls: Expected an argument\n"), argv[0]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
// #1323: We may have multiple foreground colors. Choose the best one. If we had no foreground // #1323: We may have multiple foreground colors. Choose the best one. If we had no foreground
@ -159,7 +159,7 @@ int builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
const rgb_color_t bg = rgb_color_t(bgcolor ? bgcolor : L""); const rgb_color_t bg = rgb_color_t(bgcolor ? bgcolor : L"");
if (bgcolor && bg.is_none()) { if (bgcolor && bg.is_none()) {
streams.err.append_format(_(L"%ls: Unknown color '%ls'\n"), argv[0], bgcolor); streams.err.append_format(_(L"%ls: Unknown color '%ls'\n"), argv[0], bgcolor);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
// Test if we have at least basic support for setting fonts, colors and related bits - otherwise // Test if we have at least basic support for setting fonts, colors and related bits - otherwise

View file

@ -60,12 +60,12 @@ static const wchar_t *string_get_arg_stdin(wcstring *storage, const io_streams_t
long rc = read_blocked(streams.stdin_fd, &ch, 1); long rc = read_blocked(streams.stdin_fd, &ch, 1);
if (rc < 0) { // failure if (rc < 0) { // failure
return 0; return NULL;
} }
if (rc == 0) { // EOF if (rc == 0) { // EOF
if (arg.empty()) { if (arg.empty()) {
return 0; return NULL;
} }
break; break;
} }

View file

@ -591,7 +591,7 @@ bool combining_expression::evaluate(wcstring_list_t &errors) {
} }
errors.push_back(format_string(L"Unknown token type in %s", __func__)); errors.push_back(format_string(L"Unknown token type in %s", __func__));
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
bool parenthetical_expression::evaluate(wcstring_list_t &errors) { bool parenthetical_expression::evaluate(wcstring_list_t &errors) {
@ -741,7 +741,7 @@ int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
using namespace test_expressions; using namespace test_expressions;
// The first argument should be the name of the command ('test'). // The first argument should be the name of the command ('test').
if (!argv[0]) return STATUS_CMD_ERROR; if (!argv[0]) return STATUS_INVALID_ARGS;
// Whether we are invoked with bracket '[' or not. // Whether we are invoked with bracket '[' or not.
wchar_t *program_name = argv[0]; wchar_t *program_name = argv[0];
@ -758,7 +758,7 @@ int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
argc--; argc--;
} else { } else {
streams.err.append(L"[: the last argument must be ']'\n"); streams.err.append(L"[: the last argument must be ']'\n");
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
} }

View file

@ -240,15 +240,15 @@ int builtin_ulimit(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
#endif #endif
case 'h': { case 'h': {
builtin_print_help(parser, streams, cmd, streams.out); builtin_print_help(parser, streams, cmd, streams.out);
return 0; return STATUS_CMD_OK;
} }
case ':': { case ':': {
streams.err.append_format(BUILTIN_ERR_MISSING, cmd, argv[w.woptind - 1]); streams.err.append_format(BUILTIN_ERR_MISSING, cmd, argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
case '?': { case '?': {
builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]); builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
default: { default: {
DIE("unexpected retval from wgetopt_long"); DIE("unexpected retval from wgetopt_long");
@ -270,7 +270,7 @@ int builtin_ulimit(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
} else if (arg_count != 1) { } else if (arg_count != 1) {
streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, cmd); streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, cmd);
builtin_print_help(parser, streams, cmd, streams.err); builtin_print_help(parser, streams, cmd, streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
// Change current limit value. // Change current limit value.
@ -283,7 +283,7 @@ int builtin_ulimit(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
if (*argv[w.woptind] == L'\0') { if (*argv[w.woptind] == L'\0') {
streams.err.append_format(_(L"%ls: New limit cannot be an empty string\n"), cmd); streams.err.append_format(_(L"%ls: New limit cannot be an empty string\n"), cmd);
builtin_print_help(parser, streams, cmd, streams.err); builtin_print_help(parser, streams, cmd, streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} else if (wcscasecmp(argv[w.woptind], L"unlimited") == 0) { } else if (wcscasecmp(argv[w.woptind], L"unlimited") == 0) {
new_limit = RLIM_INFINITY; new_limit = RLIM_INFINITY;
} else if (wcscasecmp(argv[w.woptind], L"hard") == 0) { } else if (wcscasecmp(argv[w.woptind], L"hard") == 0) {
@ -295,7 +295,7 @@ int builtin_ulimit(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
if (errno) { if (errno) {
streams.err.append_format(_(L"%ls: Invalid limit '%ls'\n"), cmd, argv[w.woptind]); streams.err.append_format(_(L"%ls: Invalid limit '%ls'\n"), cmd, argv[w.woptind]);
builtin_print_help(parser, streams, cmd, streams.err); builtin_print_help(parser, streams, cmd, streams.err);
return STATUS_CMD_ERROR; return STATUS_INVALID_ARGS;
} }
new_limit *= get_multiplier(what); new_limit *= get_multiplier(what);
} }

View file

@ -874,7 +874,9 @@ enum {
STATUS_ILLEGAL_CMD = 123, STATUS_ILLEGAL_CMD = 123,
/// The status code used when `read` is asked to consume too much data. /// The status code used when `read` is asked to consume too much data.
STATUS_READ_TOO_MUCH = 122, STATUS_READ_TOO_MUCH = 122,
/// The status code used for erroneous argument combinations in a command. /// The status code used for invalid arguments given to a command. This is distinct from valid
/// arguments that might result in a command failure. An invalid args condition is something
/// like an unrecognized flag, missing or too many arguments, an invalid integer, etc. But
STATUS_INVALID_ARGS = 121, STATUS_INVALID_ARGS = 121,
}; };
#endif #endif

View file

@ -1271,7 +1271,7 @@ static bool expand_test(const wchar_t *in, expand_flags_t flags, ...) {
wcstring_list_t expected; wcstring_list_t expected;
va_start(va, flags); va_start(va, flags);
while ((arg = va_arg(va, wchar_t *)) != 0) { while ((arg = va_arg(va, wchar_t *)) != NULL) {
expected.push_back(wcstring(arg)); expected.push_back(wcstring(arg));
} }
va_end(va); va_end(va);
@ -3799,7 +3799,7 @@ static void run_one_string_test(const wchar_t **argv, int expected_rc,
streams.stdin_is_directly_redirected = false; // read from argv instead of stdin streams.stdin_is_directly_redirected = false; // read from argv instead of stdin
int rc = builtin_string(parser, streams, const_cast<wchar_t **>(argv)); int rc = builtin_string(parser, streams, const_cast<wchar_t **>(argv));
wcstring args; wcstring args;
for (int i = 0; argv[i] != 0; i++) { for (int i = 0; argv[i] != NULL; i++) {
args += escape_string(argv[i], ESCAPE_ALL) + L' '; args += escape_string(argv[i], ESCAPE_ALL) + L' ';
} }
args.resize(args.size() - 1); args.resize(args.size() - 1);
@ -4103,10 +4103,10 @@ static void test_string(void) {
{{L"string", L"trim", L"-c", L"\\/", L"\\a/"}, STATUS_CMD_OK, L"a\n"}, {{L"string", L"trim", L"-c", L"\\/", L"\\a/"}, STATUS_CMD_OK, L"a\n"},
{{L"string", L"trim", L"-c", L"", L".a."}, STATUS_CMD_ERROR, L".a.\n"}, {{L"string", L"trim", L"-c", L"", L".a."}, STATUS_CMD_ERROR, L".a.\n"},
{{0}, STATUS_CMD_ERROR, NULL}}; {{NULL}, STATUS_CMD_ERROR, NULL}};
struct string_test *t = string_tests; struct string_test *t = string_tests;
while (t->argv[0] != 0) { while (t->argv[0]) {
run_one_string_test(t->argv, t->expected_rc, t->expected_out); run_one_string_test(t->argv, t->expected_rc, t->expected_out);
t++; t++;
} }

View file

@ -31,7 +31,7 @@ Verify that set passes through exit status, except when passed -n or -q or -e
6 0 6 0
7 1 7 1
8 0 8 0
9 1 9 121
10 0 A 10 0 A
11 1 B 11 1 B
Verify set -ql behavior Verify set -ql behavior