Subject: lib/14067: libedit suggestion - new el_set() operation
To: None <gnats-bugs@gnats.netbsd.org>
From: None <anthony.mallet@ficus.yi.org>
List: netbsd-bugs
Date: 09/26/2001 02:08:26
>Number: 14067
>Category: lib
>Synopsis: libedit suggestion - new el_set() operation
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: lib-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Tue Sep 25 17:09:02 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Anthony Mallet
>Release: 1.5Y
>Organization:
>Environment:
System: NetBSD ficus 1.5Y NetBSD 1.5Y (FICUS) #7: Sun Sep 23 01:15:49 CEST 2001 toto@ficus:/home/src/netbsd-current/sys/arch/i386/compile/FICUS i386
Architecture: i386
Machine: i386
>Description:
I need to add a new feature in libedit because:
i) I have to write an interactive program with line editing
functionalities that must also process events in the background (when
no input is available).
ii) The builtin "read_char()" function (in read.c) is declared "private"
and cannot be replaced easly. Furthermore this function insist on
reconfiguring the tty in blocking mode which is not what I want.
>How-To-Repeat:
Write some code which calls el_gets() or el_getc() to get user input.
Try to process events when no input is available, without relying on some
polling method (SIGALARM or so...).
>Fix:
The enclosed patch (see below) match my needs. It's of course only a
suggestion; I'm open to the discussion :)
This patch adds a new command for el_set() and el_get():
el_set(EditLine *el, EL_GETCFN, int (*f)(EditLine *, char *));
el_get(EditLine *el, EL_GETCFN, int (**f)(EditLine *, char *));
The first line sets a new read_char function to be used by the two
functions el_gets and el_getc. A predefined constant EL_BUILTIN_GETCFN
refers the default builtin function.
The second line returns the current read_char function (or
EL_BUILTIN_GETCFN if the default function is used).
Index: editline.3
===================================================================
RCS file: /usr/local/cvs_hilare/lib/libedit/dist/editline.3,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 editline.3
--- editline.3 25 Sep 2001 16:03:16 -0000 1.1.1.1
+++ editline.3 25 Sep 2001 23:46:38 -0000
@@ -368,6 +368,17 @@
(using
.Fn el_get )
to determine if editing should be enabled or not.
+.It Dv EL_GETCFN , Fa "int (*f)(EditLine *, char *c)"
+Define the character reading function as
+.Fa f ,
+which is to return the number of characters read and store them in
+.Fa c .
+This function is called internally by
+.Fn el_gets
+and
+.Fn el_getc .
+The builtin function can be set or restored with the special function
+name ``EL_BUILTIN_GETCFN''.
.El
.It Fn el_get
Get
@@ -399,6 +410,9 @@
above).
.It Dv EL_EDITMODE, Fa "int *"
Return non-zero if editing is enabled.
+.It Dv EL_GETCFN, Fa "int (**f)(EditLine *, char *)"
+Return a pointer to the function that read characters, which is equal to
+``EL_BUILTIN_GETCFN'' in the case of the default builtin function.
.El
.It Fn el_source
Initialise
Index: el.c
===================================================================
RCS file: /usr/local/cvs_hilare/lib/libedit/dist/el.c,v
retrieving revision 1.2
diff -u -r1.2 el.c
--- el.c 25 Sep 2001 16:08:09 -0000 1.2
+++ el.c 25 Sep 2001 23:46:39 -0000
@@ -92,6 +92,7 @@
(void) hist_init(el);
(void) prompt_init(el);
(void) sig_init(el);
+ (void) read_init(el);
return (el);
}
@@ -244,6 +245,13 @@
rv = 0;
break;
+ case EL_GETCFN:
+ {
+ el_rfunc_t rc = va_arg(va, el_rfunc_t);
+ rv = el_read_setfn(el, rc);
+ break;
+ }
+
default:
rv = -1;
}
@@ -353,6 +361,11 @@
}
break;
#endif /* XXX */
+
+ case EL_GETCFN:
+ *((el_rfunc_t *)ret) = el_read_getfn(el);
+ rv = 0;
+ break;
default:
rv = -1;
Index: el.h
===================================================================
RCS file: /usr/local/cvs_hilare/lib/libedit/dist/el.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 el.h
--- el.h 25 Sep 2001 16:03:17 -0000 1.1.1.1
+++ el.h 25 Sep 2001 23:46:39 -0000
@@ -106,6 +106,7 @@
#include "parse.h"
#include "sig.h"
#include "help.h"
+#include "read.h"
struct editline {
char *el_prog; /* the program name */
@@ -129,6 +130,7 @@
el_history_t el_history; /* History stuff */
el_search_t el_search; /* Search stuff */
el_signal_t el_signal; /* Signal handling stuff */
+ el_read_t el_read; /* Character reading stuff */
};
protected int el_editmode(EditLine *, int, char **);
Index: histedit.h
===================================================================
RCS file: /usr/local/cvs_hilare/lib/libedit/dist/histedit.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 histedit.h
--- histedit.h 25 Sep 2001 16:03:17 -0000 1.1.1.1
+++ histedit.h 25 Sep 2001 23:46:39 -0000
@@ -126,6 +126,9 @@
#define EL_HIST 10 /* , hist_fun_t, const char *); */
#define EL_EDITMODE 11 /* , int); */
#define EL_RPROMPT 12 /* , el_pfunc_t); */
+#define EL_GETCFN 13 /* , el_rfunc_t); */
+
+#define EL_BUILTIN_GETCFN (NULL)
/*
* Source named file or $PWD/.editrc or $HOME/.editrc
Index: read.c
===================================================================
RCS file: /usr/local/cvs_hilare/lib/libedit/dist/read.c,v
retrieving revision 1.2
diff -u -r1.2 read.c
--- read.c 25 Sep 2001 16:08:11 -0000 1.2
+++ read.c 25 Sep 2001 23:46:40 -0000
@@ -58,8 +58,38 @@
private int read__fixio(int, int);
private int read_preread(EditLine *);
-private int read_getcmd(EditLine *, el_action_t *, char *);
private int read_char(EditLine *, char *);
+private int read_getcmd(EditLine *, el_action_t *, char *);
+
+/* read_init():
+ * Initialize the read stuff
+ */
+protected int
+read_init(EditLine *el)
+{
+ /* builtin read_char */
+ el->el_read.read_char = read_char;
+
+ return 0;
+}
+
+protected int
+el_read_setfn(EditLine *el, el_rfunc_t rc)
+{
+ if (rc == EL_BUILTIN_GETCFN)
+ el->el_read.read_char = read_char;
+ else
+ el->el_read.read_char = rc;
+
+ return 0;
+}
+
+protected el_rfunc_t
+el_read_getfn(EditLine *el)
+{
+ return (el->el_read.read_char == read_char)?
+ EL_BUILTIN_GETCFN : el->el_read.read_char;
+}
#ifdef DEBUG_EDIT
private void
@@ -79,7 +109,6 @@
}
#endif /* DEBUG_EDIT */
-
/* read__fixio():
* Try to recover from a read error
*/
@@ -309,7 +338,7 @@
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Reading a character\n");
#endif /* DEBUG_READ */
- num_read = read_char(el, cp);
+ num_read = (el->el_read.read_char)(el, cp);
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Got it %c\n", *cp);
#endif /* DEBUG_READ */
@@ -335,7 +364,7 @@
char *cp = el->el_line.buffer;
size_t idx;
- while (read_char(el, cp) == 1) {
+ while ((el->el_read.read_char)(el, cp) == 1) {
/* make sure there is space for next character */
if (cp + 1 >= el->el_line.limit) {
idx = (cp - el->el_line.buffer);
@@ -380,7 +409,7 @@
term__flush();
- while (read_char(el, cp) == 1) {
+ while ((el->el_read.read_char)(el, cp) == 1) {
/* make sure there is space next character */
if (cp + 1 >= el->el_line.limit) {
idx = (cp - el->el_line.buffer);
Index: read.h
===================================================================
RCS file: read.h
diff -N read.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ read.h 25 Sep 2001 23:46:40 -0000
@@ -0,0 +1,23 @@
+/* $NetBSD: $ */
+
+/*-
+ * Some copyright information...
+ */
+
+/*
+ * el.read.h: Character reading functions
+ */
+#ifndef _h_el_read
+#define _h_el_read
+
+typedef int (*el_rfunc_t)(EditLine *, char *);
+
+typedef struct el_read_t {
+ el_rfunc_t read_char; /* Function to read a character */
+} el_read_t;
+
+protected int read_init(EditLine *);
+protected int el_read_setfn(EditLine *, el_rfunc_t);
+protected el_rfunc_t el_read_getfn(EditLine *);
+
+#endif /* _h_el_read */
>Release-Note:
>Audit-Trail:
>Unformatted: