aboutsummaryrefslogtreecommitdiffhomepage
path: root/builtin.cpp
diff options
context:
space:
mode:
authorGravatar Joseph Tannhuber <sepp.tannhuber@yahoo.de>2014-08-19 14:28:08 +0200
committerGravatar Kevin Ballard <kevin@sb.org>2014-09-03 22:48:37 -0700
commit4acea72700a7738f1a3258cab226f6153a65ea94 (patch)
treed7604b0291aade38efd1fc810351014436645687 /builtin.cpp
parent677cee44ad192ddcd9a397e82092a3dd27386521 (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.cpp56
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)