aboutsummaryrefslogtreecommitdiffhomepage
path: root/reader.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 /reader.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 'reader.cpp')
-rw-r--r--reader.cpp23
1 files changed, 19 insertions, 4 deletions
diff --git a/reader.cpp b/reader.cpp
index c45e62b2..2a2c0897 100644
--- a/reader.cpp
+++ b/reader.cpp
@@ -2955,7 +2955,7 @@ static int read_i(void)
during evaluation.
*/
- const wchar_t *tmp = reader_readline();
+ const wchar_t *tmp = reader_readline(0);
if (data->end_loop)
{
@@ -3044,7 +3044,7 @@ static wchar_t unescaped_quote(const wcstring &str, size_t pos)
}
-const wchar_t *reader_readline(void)
+const wchar_t *reader_readline(int nchars)
{
wint_t c;
int last_char=0;
@@ -3084,6 +3084,13 @@ const wchar_t *reader_readline(void)
while (!finished && !data->end_loop)
{
+ if (0 < nchars && (size_t)nchars <= data->command_line.size())
+ {
+ // we've already hit the specified character limit
+ finished = 1;
+ break;
+ }
+
/*
Sometimes strange input sequences seem to generate a zero
byte. I believe these simply mean a character was pressed
@@ -3104,12 +3111,14 @@ const wchar_t *reader_readline(void)
{
wchar_t arr[READAHEAD_MAX+1];
- int i;
+ size_t i;
+ size_t limit = 0 < nchars ? std::min((size_t)nchars - data->command_line.size(), (size_t)READAHEAD_MAX)
+ : READAHEAD_MAX;
memset(arr, 0, sizeof(arr));
arr[0] = c;
- for (i=1; i<READAHEAD_MAX; i++)
+ for (i = 1; i < limit; ++i)
{
if (!can_read(0))
@@ -3137,6 +3146,12 @@ const wchar_t *reader_readline(void)
if (c != 0)
break;
+
+ if (0 < nchars && (size_t)nchars <= data->command_line.size())
+ {
+ c = R_NULL;
+ break;
+ }
}
/* If we get something other than a repaint, then stop coalescing them */