diff options
author | 2014-08-19 14:28:08 +0200 | |
---|---|---|
committer | 2014-09-03 22:48:37 -0700 | |
commit | 4acea72700a7738f1a3258cab226f6153a65ea94 (patch) | |
tree | d7604b0291aade38efd1fc810351014436645687 /builtin.cpp | |
parent | 677cee44ad192ddcd9a397e82092a3dd27386521 (diff) |
New -n option for read builtin
Usage: read -n nchars
Reads maximum of nchars characters. If nchars <= 0, there's no limit.
Diffstat (limited to 'builtin.cpp')
-rw-r--r-- | builtin.cpp | 56 |
1 files changed, 53 insertions, 3 deletions
diff --git a/builtin.cpp b/builtin.cpp index da9429b1..cde4477f 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -2313,6 +2313,8 @@ static int builtin_read(parser_t &parser, wchar_t **argv) const wchar_t *commandline = L""; int exit_res=STATUS_BUILTIN_OK; const wchar_t *mode_name = READ_MODE_NAME; + int nchars=0; + wchar_t *end; int shell = 0; int array = 0; @@ -2356,6 +2358,10 @@ static int builtin_read(parser_t &parser, wchar_t **argv) } , { + L"nchars", required_argument, 0, 'n' + } + , + { L"shell", no_argument, 0, 's' } , @@ -2377,7 +2383,7 @@ static int builtin_read(parser_t &parser, wchar_t **argv) int opt = wgetopt_long(argc, argv, - L"xglUup:c:hm:sa", + L"xglUup:c:hm:n:sa", long_options, &opt_index); if (opt == -1) @@ -2428,6 +2434,32 @@ static int builtin_read(parser_t &parser, wchar_t **argv) mode_name = woptarg; break; + case L'n': + errno = 0; + nchars = fish_wcstoi(woptarg, &end, 10); + if (errno || *end != 0) + { + switch (errno) + { + case ERANGE: + append_format(stderr_buffer, + _(L"%ls: Argument '%ls' is out of range\n"), + argv[0], + woptarg); + builtin_print_help(parser, argv[0], stderr_buffer); + return STATUS_BUILTIN_ERROR; + + default: + append_format(stderr_buffer, + _(L"%ls: Argument '%ls' must be an integer\n"), + argv[0], + woptarg); + builtin_print_help(parser, argv[0], stderr_buffer); + return STATUS_BUILTIN_ERROR; + } + } + break; + case 's': shell = 1; break; @@ -2530,11 +2562,24 @@ static int builtin_read(parser_t &parser, wchar_t **argv) proc_push_interactive(1); event_fire_generic(L"fish_prompt"); - line = reader_readline(); + line = reader_readline(nchars); proc_pop_interactive(); if (line) { - buff = wcsdup(line); + if (0 < nchars && nchars < wcslen(line)) + { + // line may be longer than nchars if a keybinding used `commandline -i` + // note: we're deliberately throwing away the tail of the commandline. + // It shouldn't be unread because it was produced with `commandline -i`, + // not typed. + buff = (wchar_t *)malloc(((size_t)nchars + 1) * sizeof(wchar_t)); + wmemcpy(buff, line, (size_t)nchars); + buff[nchars] = 0; + } + else + { + buff = wcsdup(line); + } } else { @@ -2594,6 +2639,11 @@ static int builtin_read(parser_t &parser, wchar_t **argv) break; sb.push_back(res); + + if (0 < nchars && (size_t)nchars <= sb.size()) + { + break; + } } if (sb.size() < 2 && eof) |