Subject: [2.0.44] FvwmConsole fixes

From: "Paul D. Smith" <[email-masked]>
Date: Fri, 17 Jan 97 13:29:44 EST

Enclosed are some patches for extras/FvwmConsole.  I've been trying to
find the best version of these; FvwmTalk is nice in that it doesn't need
an xterm, but I can't paste multiple lines correctly for some reason (it
puts them all as one line and doesn't parse them correctly).  Plus the
code is a bit impenetrable to an X programming novice like myself :)

FvwmPipe looks quite promising and I have a cool idea or two for that.

But FvwmConsole seems to be the most complete, plus it has the option of
using readline which I like.

But I think it needed some tweaks, esp. the readline support.  Here's
what I did:

  - The Imakefile sets ADD_INCLUDE if you enable Readline but, at least
    in my X config (X11R6.3), that variable isn't used anywhere.  I
    changed it to EXTRA_INCLUDES.

  - Reworked the man page a bit.

  - Accept the command "exit" to make FvwmConsole quit.  The docs say
    C-d is bound to delete-char in Readline, but really it sends an
    EOF.  But, if someone did rebind it then we'd need another way to
    exit FvwmConsole gracefully; hence "exit".

  - Reworked the GNU readline support quite a bit:
      * Disable TAB-completion.  You can't cut/paste commands containing
        TABs into FvwmConsole when completion is enabled, plus why would
        you need filename completion in FvwmConsole?

      * Handle backslashed command lines, so you can paste directly from
        your .fvwm2rc more easily; stuff like this works verbatim:

          ButtonStyle 1 (Pixmap fvwm95/mini.destroy.xpm) \
                        ActiveDown (Pixmap fvwm95/mini-exp.xpm)

      * Defined PS1 and PS2 prompts for the GNU readline support.  PS2
        is used if the previous line ended in a backslash.

      * Allow "infinitely" large buffers for commands--I'm not sure if
        fvwm itself can handle single lines of larger than 255 chars,
        but FvwmConsole can build 'em as big as you like.

Probably some of the readline extras (esp. backslash support) should be
migrated into the "vanilla gets" interface as well.

--- Imakefile-dist	Sun Jul 21 01:40:35 1996
+++ Imakefile	Fri Jan 17 10:58:42 1997
@@ -34,8 +34,8 @@
 ComplexProgramTarget_1(FvwmConsole,$(LOCAL_LIBRARIES),)
 
 #ifdef HAVE_READLINE
-ADD_INCLUDE = -I/usr/local/include
-ADD_LIB = -lreadline -ltermcap
+EXTRA_INCLUDES = -I/usr/local/include
+ADD_LIB = -L/usr/local/lib -lreadline -ltermcap
 EXTRA_DEFINES = -DHAVE_READLINE
 #endif
 
--- FvwmConsole.man-dist	Wed Jul 17 01:20:35 1996
+++ FvwmConsole.man	Fri Jan 17 13:15:14 1997
@@ -4,23 +4,45 @@
 .UC
 
 .SH NAME
-FvwmConsole \- the FVWM command input interface
+FvwmConsole \- an FVWM command input interface
+
 .SH SYNOPSIS
 FvwmConsole is spawned by fvwm, so no command line invocation will work.
-From within the .fvwm2rc file or from a menu, FvwmConsole takes any
-options xterm will take, except -name, and -title.
+
+.SH DESCRIPTION
+FvwmConsole allows the user to type fvwm configuration commands
+interactively, and have them executed immediately.  This tool is
+particularly useful for testing new configuration ideas, or for
+implementing temporary changes to your environment.
+
+.SH INVOCATION
+FvwmConsole must be spawned as a module by fvwm.  FvwmConsole takes all
+\fIxterm\fP(1) options, except -name and -title.
+.PP
+FvwmConsole can be invoked by inserting the line 'Module FvwmConsole' in
+the .fvwm2rc file.  This can be placed on a line by itself, if
+FvwmConsole is to be spawned during fvwm's initialization, or can be
+bound to a menu or mouse button or keystroke to invoke it later.  Fvwm
+will search directory specified in the ModulePath configuration option
+to attempt to locate FvwmConsole.
+
+.SH CONFIGURATION OPTIONS
+FvwmConsole uses \fIxterm\fP(1).  All resources set for xterm are
+inherited unless overridden by command line options.
 
 .RS
 Module FvwmConsole -g 40x10 -fg black -bg green3
 .RE
 
- The option -e can be used to choose its front-end:
+The option -e can be used to choose an alternate front-end:
 
 .RS
-FvwmConsole -e /usr/X11/lib/fvwm2/FvwmConsoleC.pl
+Module FvwmConsole -e /usr/X11/lib/fvwm2/FvwmConsoleC.pl
 .RE
 
-Also X resources can be set in .Xdefaults file
+(see \fIFvwmConsoleC.pl\fP(1)).
+.PP
+Also X resources can be set in your ~/.Xdefaults file:
 
 .RS
 FvwmConsole*VT100*geometry: 40x4
@@ -28,38 +50,30 @@
 FvwmConsole*font: 7x14
 .RE
 
-.SH DESCRIPTION
-FvwmConsole allows the user to type fvwm commands into xterm, and
-have them executed immediately. These commands are usually specified
-in the .fvwm2rc file, or are bound to menu/mouse items as specified
-in that file. This tools is particularly useful for testing new
-configuration ideas, or for implementing temporary changes to your
-environment.
-
 
-.SH Command Editor
+.SH "COMMAND EDITING"
 
-There are a few options. If GNU readline library is installed,
-add '#define HAVE_READLINE' in Imakefile and compile. 
-.br
+There are a few options.  If the GNU readline library is available, it
+can be used.
+.PP
 If Perl5 is installed, FvwmConsoleC.pl can be used as a command editor.
 This can be accomplished by either copying FvwmConsoleC.pl 
 to fvwmlib directory as FvwmConsoleC or
 invoking FvwmConsole with -e option.
 For example:
 
-.br
-FvwmConsole -e /usr/lib/X11/fvwm2/FvwmConsoleC.pl
-.br
+.RS
+Module FvwmConsole -e /usr/lib/X11/fvwm2/FvwmConsoleC.pl
+.RE
 
-If neither one is installed, command line editor will call 
-gets function, which doesn't have editing functions.
-.br
+If neither one is installed, a simple input reading function which
+doesn't have editing capabilities is used.
+.P
 GNU readline and FvwmConsoleC.pl have some frequent used commands
 in common as default.
 These commands are similar to emacs. 
 For more details, refer GNU readline man and info pages, and
-FvwmConsoleC.pl man pages.
+FvwmConsoleC.pl man page.
 
 .RS
 .PD 0
@@ -110,26 +124,22 @@
 - end of history
 .RE
 .PD
+
+.SH EXITING
+
+FvwmConsole can be stopped by entering the command "exit" at the command
+line, or the EOF character (usually CTRL-D).
+.PP
+\fBNote!\fP Do not use the "quit" command, as this is an fvwm builtin:
+typing "quit" at the FvwmConsole command line will cause fvwm to exit.
+
 .SH COPYRIGHTS
 Copyright 1996, Toshi Isogai. No guarantees or warranties are provided.
 Use this program at your own risk. Permission to use this program for
 any purpose is given, as long as the copyright is kept intact. 
 
-
-.SH INVOCATION
-FvwmConsole can be invoked by inserting the line 'Module FvwmConsole' in
-the .fvwm2rc file. This can be placed on a line by itself, if FvwmConsole
-is to be spawned during fvwm's initialization, or can be bound to a
-menu or mouse button or keystroke to invoke it later. Fvwm will search
-directory specified in the ModulePath configuration option to attempt
-to locate FvwmConsole.
-
-.SH CONFIGURATION OPTIONS
-FvwmConsole uses xterm. All resources set for xterm are inherited
-unless overridden by command line options.
-
 .SH SEE ALSO
-xterm(1), FvwmConsoleC.pl(1x), GNU readline library
+\fIxterm\fP(1), \fIFvwmConsoleC.pl\fP(1), GNU Readline library
 
 .SH AUTHOR
 Toshi Isogai  
--- FvwmConsole.h-dist	Tue Jul 16 23:58:52 1996
+++ FvwmConsole.h	Fri Jan 17 12:46:12 1997
@@ -32,11 +32,13 @@
 #endif

+/* Prompts for readline support */
+#define PS1     ""
+#define PS2     ">"

 #define S_NAME "/tmp/FvConSocket"
 #define BUFSIZE 511   /* maximum error message size */
-#define NEWLINE "\n"
 
 /* timeout for packet after issuing command*/
 #define TIMEOUT 400000
--- FvwmConsoleC.c-dist	Sat Jul 13 23:51:26 1996
+++ FvwmConsoleC.c	Fri Jan 17 12:55:02 1997
@@ -69,7 +69,7 @@
 	while( 1 ) {
 
 	  cmd = getline();
-	  if( cmd == NULL  ) {
+	  if (cmd == NULL || !strcmp(cmd, "exit\n")) {
 		break;
 	  }
 	
--- getline.c-dist	Sun Jul 14 01:57:50 1996
+++ getline.c	Fri Jan 17 12:40:14 1997
@@ -1,8 +1,8 @@
 #include "FvwmConsole.h"
 
+#ifndef HAVE_READLINE
 static   char cmd[256];
 
-#ifndef HAVE_READLINE
 /* no readline - starts here */
 char *getline() {
   if( fgets(cmd,256,stdin) == NULL  ) {
@@ -16,35 +16,79 @@
 #include <readline/readline.h>
 #include <readline/history.h>
 
-#define PROMPT ""
+extern int rl_bind_key();
 
+static int cmdlen = 255;
+static char *cmd  = (char *)NULL;
 static char *line = (char *)NULL;
+static int done_init = 0;
 
-char *getline() {
+char *getline()
+{
+    char *prompt;
+    int len;
+
+    /* If initialization hasn't been done, do it now:
+     *  - We don't want TAB completion
+     *  - Start with a 256-char command buffer
+     */
+    if (!done_init) {
+        rl_bind_key('\t', rl_insert);
+
+        cmd = malloc(cmdlen + 1);
+        if (cmd == NULL)
+            exit(1);
 
-  /* If the buffer has already been allocated, return the memory to the free pool. */
-  if (line != (char *)NULL) {
-	free (line);
-	line = (char *)NULL;
+        done_init = 1;
   }
                              
+    /* Empty out the previous info */
+    len = 0;
+    *cmd = '\0';
+    prompt = PS1;
+
+    while (1) {
+        int linelen = 0;
+
+        /* If the buffer has already been allocated, free the memory. */
+        if (line != (char *)NULL)
+            free(line);
+
   /* Get a line from the user. */
-  line  = readline (PROMPT);
+        line  = readline(prompt);
+        if (line == NULL)
+            return (NULL);
+
+        /* Make sure we have enough space for the new line */
+        linelen = strlen(line);
+        if (len + linelen > cmdlen) {
+            cmdlen = len + linelen;
+            cmd = realloc(cmd, cmdlen + 1);
+            if (cmd == NULL)
+                exit(1);
+        }
      
-  if( line == NULL ) {
-	return(NULL);
+        /* Copy the new line onto the end of the current line */
+        strcat(cmd, line);
+
+        /* If the current line doesn't end with a backslash, we're done */
+        len = strlen(cmd);
+        if (cmd[len-1] != '\\')
+            break;
+
+        /* Otherwise, remove it and wait for more (add a space if needed) */
+        prompt = PS2;
+        cmd[len-1] = (cmd[len-2]==' ' || cmd[len-2]=='\t') ? '\0' : ' ';
   } 
 
-	/* If the line has any text in it, save it on the history. */
-	if (*line != '\0')
-	  add_history (line);
-	
-	/* add cr at the end*/
-	strncpy( cmd, line, 254 );
-	strcat( cmd, NEWLINE ); 
+    /* If the command has any text in it, save it on the history. */
+    if (*cmd != '\0')
+        add_history(cmd);
 
-  return (cmd);
+    cmd[len]   = '\n';
+    cmd[len+1] = '\0';
 
+    return (cmd);
 }
 /* readline - end here */
 #endif
--
Visit the official FVWM web page at <URL:http://www.hpc.uh.edu/fvwm/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked].

---

From: Toshi Isogai <[email-masked]>
Date: Tue, 21 Jan 1997 14:24:52 -0700 (MST)

I took this thread out from mailing list but put it back again....

On Tue, 21 Jan 1997, Paul D. Smith wrote:

> %% Toshi Isogai <[email-masked]> writes:
> 
>   ti> Just looking at quickly, fvwm itself can't handle a command longer
>   ti> than 255. If this isn't fixed, Console will just die when a long
>   ti> command is sent. A fixed size is easier to implement on fvwm side,
>   ti> so I suppose it is better to just increase the size to 1024 or
>   ti> something.
> 
> That's fine, or leave it at 255.  I don't much care, except that these
> days it's not hard for a Style line, for example, to get >255 chars in
> length, what with backslash continuation, etc.
> 
> 512 or 1024 would be fine.
> 
> HOWEVER, if this is indeed a hard limit there _really_ should be a
> #define constant in fvwmlib.h so that modules and other(?) libfvwm2.a
> clients can use that instead of magic numbers like 255.  I see a
> MAX_TOKEN_LENGTH but that's not the same thing, I don't think.
> 
> It'd be great to get this #define in ASAP, even if all the modules
> don't get changed to use it.
> 

It IS a magic number in function  HandleModuleInput. When I found this,
I just didn't think 255 was too short. Now, I see it, like you and others
mentioned. 

>   ti> I am going to apply the patch and try it out when I have a
chance. 
> 
> The malloc/realloc stuff is just fluff; the really important parts are
> the unbinding of TAB as a completion char (so you can paste text with
> TABs in it into FvwmConsole) and the ability to grok backslash
> continuation (again, for easier cut/paste support).
> 

I don't use readline but I know TAB is a problem. I thought I should
leave it to each user to configure key assignment. I agree it is better
off to change this now.

---------------------------
Toshi Isogai   
KENTEK Information Systems
[email-masked]