Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

a display problem apparently caused by rlwrap #194

Open
yowipo1 opened this issue Dec 14, 2024 · 0 comments
Open

a display problem apparently caused by rlwrap #194

yowipo1 opened this issue Dec 14, 2024 · 0 comments

Comments

@yowipo1
Copy link

yowipo1 commented Dec 14, 2024

This issue is coming from this request for help at comp.unix.questions

https://comp.unix.questions.narkive.com/PyZWXzFH/xterm-rlwrap-sbcl

which could be useful in providing more information.

When I invoke sbcl without rlwrap, I get the normal, expected
behavior:

$ sbcl
This is SBCL 2.4.9, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
* (format t "hello~%")
hello
NIL
*

If I invoke with rlwrap, however, we find a little imperfection as
soon as we press RET after the command given to SBCL:

$ rlwrap sbcl
This is SBCL 2.4.9, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (f(format t "hello~%")
hello
NIL

Trying rlwrap out with other programs, we find other problematic
behavior.  For instance, a sample program called history's normal
behavior is:

$ ./history
prompt> hello1
hello1: command not found
prompt> hello2
hello2: command not found
prompt> Good-bye!
$

Under rlwrap, we get:

$ rlwrap ./history
prompt> hello1  hello1
hello1: command not found
prompt> hello2  hello2
hello2: command not found
Good-bye!

$

It makes the command given to history be repeated. Upon ^D, we also
find an extra newline at the end. Notice that history does not use a
readline library in any way. Is this an rlwrap problem? Or is it a
terminal configuration that I'm not doing? This is happening on:

$ uname -a
FreeBSD antartida.xyz 14.1-RELEASE-p5 FreeBSD 14.1-RELEASE-p5 GENERIC amd64

$ echo $TERM
vt100

Here's the source code of history.c (in case it matters):

#include <stdio.h>
#include <stdlib.h>
#include "getln.h"
#include "list.h"

#define MAXLINE 100

List* HISTORY = NULL;

struct command {
  char *name;
  int (*handler)(char *ln); /* pointer to function returning int */
  char *help;
};

struct command table[];

struct command * lookup(char *cmd, struct command * table) {
  struct command *p;
  for (p = table; p->handler != NULL ; p++) {
    if (strncmp(cmd, p->name, strlen(cmd)) == 0)
      return p;
  }
  return NULL; /* not found */
}

void history_show(List *ls)
{
  char *data;
  if (IS_EMPTY(ls)) { return; }
  data = first(ls);
  printf("history: %s\n", data);
  history_show(rest(ls));
}

int f_history(char *ln) {
  history_show(HISTORY);
  return 0;
}

int f_quit(char *ln) {
  printf("Good-bye!\n"); fflush(stdout);
  destroy(HISTORY); exit(0); return 0;
}

int f_list(char *ln) {
  struct command *p;
  for (p = table; p->handler != NULL; p++) {
    printf("%s: %s\n", p->name, p->help);
  }
  return 0;
}

struct command table[] = {
  {"list", f_list, "lists the command table"},
  {"help!", f_list, "same as list"},
  {"history", f_history, "shows the command history"},
  {"quit", f_quit, "terminates the program"},
  {NULL, NULL, NULL}
};

int prompt_getln(char *prompt, char *ln, int size_of_ln) {
  memset(ln, '\0', size_of_ln);
  printf("%s", prompt); fflush(stdout);
  return getln(ln, size_of_ln);
}

int main(int argc, char *argv[])
{
  for (;;) {
    char ln[MAXLINE]; struct command *c; int r;

    r = prompt_getln("prompt> ", ln, sizeof ln);
    if (r == 0) {
      /* We got EOF, so we quit. */
      f_quit(ln);
    }
    if (r == 1) { continue; }

    /* Keeps a history of all commands. */
    HISTORY = cons(ln, strlen(ln) + 1, HISTORY);

    if ((c = lookup(ln, table)) != NULL) {
      r = c->handler(ln); /* Run it. */
    } else {
      printf("%s: command not found\n", ln);
    }
  }
  return 0;
}

I appreciate any help on this. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant