Hello,
I attach a short .c example to demonstrate the actual problem,
and I correct my message.
It is the sum history_base + history_length which causes me grief.
The behaviour of where_history() is unexpected to me, but I'm not
sure whether its usage in ngspice is correct.
Regards,
Robert
// adapted example from
// (compile "wget -O - https://cnswww.cns.cwru.edu/php/chet/readline/history.html#SEC18 | html2text | perl -ne 'print if(/^ #include/../^ }/)' > ex-0.c")
//
// (diff "ex-0.c" "ex-1.c" "-u0 -b -w")
//
// two compilation incantations, one for -lreadline, one for -ledit
// (compile "gcc -o ex-1.e -Wall -DEDITLINE ex-1.c -ledit")
// (compile "gcc -o ex-1.r -Wall -DREADLINE ex-1.c -lreadline")
//
// I expect history_base + history_length being the user visible position
// the thing one might use to print a "prompt"
// This works for -lreadline, but doesn't for -ledit
// It is not obvious for me, whether where_history() should do something
// similiar. It doesn't in different ways for both libraries
// In ngspice, there is a history_set_pos(history_length) before invoking
// readline(). then where_history() does the job, but only for -lreadline
//
// call ex-1.l and ex-1.r, enter some lines, and compare the printed values
// especially for history_base + history_length which does not increment beyond 1
// for libedit
// enter "list" for additional curiosity
// further experiment entering "bla", "bla", "save",
// then restart and enter "read", "bla"
// ==> history_length will jump as expected, but only after the next line
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef READLINE
#include <readline/history.h>
#endif
#ifdef EDITLINE
#include <editline/history.h>
#endif
int
main (argc, argv)
int argc;
char **argv;
{
char line[1024], *t;
int len, done = 0;
line[0] = 0;
using_history ();
// stifle_history(5);
while (!done)
{
// history_set_pos(history_length);
printf ("history wh=%d / hb+hl=%d / hb=%d hl=%d > ",
where_history(), history_base + history_length,
history_base, history_length);
fflush (stdout);
t = fgets (line, sizeof (line) - 1, stdin);
if (t && *t)
{
len = strlen (t);
if (t[len - 1] == '\n')
t[len - 1] = '\0';
}
if (!t)
strcpy (line, "quit");
if (line[0])
{
char *expansion;
int result;
result = history_expand (line, &expansion);
if (result)
fprintf (stderr, "%s\n", expansion);
if (result < 0 || result == 2)
{
free (expansion);
continue;
}
add_history (expansion);
strncpy (line, expansion, sizeof (line) - 1);
free (expansion);
}
if (strcmp (line, "quit") == 0)
done = 1;
else if (strcmp (line, "save") == 0)
write_history ("history_file");
else if (strcmp (line, "read") == 0)
read_history ("history_file");
else if (strcmp (line, "list") == 0)
{
register HIST_ENTRY **the_list = NULL;
register int i;
#ifdef READLINE
HISTORY_STATE *xx = history_get_history_state ();
// offset+length seems to be the actual user visible history position
the_list = history_list ();
fprintf(stderr, "history_list() = %p, history_get_history_state()->entries = %p, ->offset=%d ->length=%d, ->size=%d\n",
the_list, xx->entries, xx->offset, xx->length, xx->size);
#endif
fprintf (stderr, " wh=%d / hb=%d hl=%d\n",
where_history(), history_base, history_length);
if (the_list)
for (i = 0; the_list[i]; i++)
printf ("%d: %s\n", i + history_base, the_list[i]->line);
}
else if (strncmp (line, "delete", 6) == 0)
{
int which;
if ((sscanf (line + 6, "%d", &which)) == 1)
{
HIST_ENTRY *entry = remove_history (which);
if (!entry)
fprintf (stderr, "No such entry %d\n", which);
else
{
free ((char *) entry->line);
free (entry);
}
}
else
{
fprintf (stderr, "non-numeric arg given to `delete'\n");
}
}
}
exit(0);
}