summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorAkim Demaille <akim.demaille@gmail.com>2020-03-02 05:29:31 +0100
committerAkim Demaille <akim.demaille@gmail.com>2020-03-04 08:24:36 +0100
commit67793793e8dadd3fc015114f0080bab7c73061bc (patch)
treec064cd733ec837c453cf8ba7a4cade244ae63f6e /examples
parentf334775dbfa39c26a50039e7aac8c63ae85d1a04 (diff)
downloadbison-67793793e8dadd3fc015114f0080bab7c73061bc.tar.gz
bistromathic: properly compute the lcp, as expected by readline
Currently completion on "at" proposes only "atan", but does not actually complete "at" into "atan". * examples/c/bistromathic/parse.y (completion): Install the lcp in matches[0]. * examples/c/bistromathic/bistromathic.test: Check that case.
Diffstat (limited to 'examples')
-rwxr-xr-xexamples/c/bistromathic/bistromathic.test8
-rw-r--r--examples/c/bistromathic/parse.y17
2 files changed, 23 insertions, 2 deletions
diff --git a/examples/c/bistromathic/bistromathic.test b/examples/c/bistromathic/bistromathic.test
index 0bec1cb3..a877bea3 100755
--- a/examples/c/bistromathic/bistromathic.test
+++ b/examples/c/bistromathic/bistromathic.test
@@ -85,6 +85,7 @@ run 0 '> 1 / 0
## Completion. ##
## ------------ ##
+# Check completion after an operator.
sed -e 's/\\t/ /g' >input <<EOF
(1+\t\t
EOF
@@ -94,3 +95,10 @@ run 0 '> (1+
atan exp sqrt
> (1+
> err: 1.4: syntax error: expected - or ( or double precision number or function or variable before end of file'
+
+# Check the completion of a word.
+sed -e 's/\\t/ /g' >input <<EOF
+(at\t\t
+EOF
+run 0 '> (atan ( ''
+> err: 1.9: syntax error: expected - or ( or double precision number or function or variable before end of file'
diff --git a/examples/c/bistromathic/parse.y b/examples/c/bistromathic/parse.y
index d424cdfe..e1315ee5 100644
--- a/examples/c/bistromathic/parse.y
+++ b/examples/c/bistromathic/parse.y
@@ -384,8 +384,7 @@ completion (const char *text, int start, int end)
const int len = strlen (text);
// Need initial prefix and final NULL.
char **matches = calloc (ntokens + symbol_count () + 2, sizeof *matches);
- int match = 0;
- matches[match++] = strdup (text);
+ int match = 1;
for (int i = 0; i < ntokens; ++i)
if (tokens[i] == YYTRANSLATE (TOK_VAR))
{
@@ -406,6 +405,20 @@ completion (const char *text, int start, int end)
matches[match++] = strdup (token);
}
+ // Find the longest common prefix, and install it in matches[0], as
+ // required by readline.
+ if (match == 1)
+ matches[0] = strdup (text);
+ else
+ {
+ int lcplen = strlen (matches[1]);
+ for (int i = 2; i < match && lcplen; ++i)
+ for (int j = 0; j < lcplen; ++j)
+ if (matches[1][j] != matches[i][j])
+ lcplen = j;
+ matches[0] = strndup (matches[1], lcplen);
+ }
+
if (yydebug)
{
fprintf (stderr, "completion(\"%.*s[%.*s]%s\") = ",