Louis Granboulan on Mon, 6 Jul 1998 14:52:16 +0200


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Using readline with C++


Since the headers provided with readline (up to readline 2.2)
don't declare the full prototypes of the functions, you may
need to apply the following patch.
Some compilers like g++ warn about missing declarations, but
the C++ compiler (version 4.2) sold by Sun makes an error if
you don't apply this patch.

The first part of this patch helps "Configure" to detect
older versions of readline headers. The flag HAS_RL_MESSAGE
is defined for recent versions.
The second part patches gp_rl.c with explicit complete
function types. There should be a cleaner way to do this,
but the macros Bind and Defun showed me this way !

Bench with Sun's CC (WorkShop Compilers 4.2 30 Oct 1996 C++)

UltraSPARC   167MHz    Solaris-2.5   CC  X11 -     15778   16400   2.0.9    LG

*** pari-2.0.9.alpha/Configure.orig	Mon Jun 29 14:48:15 1998
--- pari-2.0.9.alpha/Configure	Mon Jul  6 14:22:32 1998
***************
*** 457,462 ****
--- 457,465 ----
      CPPF_defined=''
      case $x in
       ?:/*|/*) rl_include=`echo $x | sed -e 's/\/readline.h//'`
+          if (grep rl_message  $x 2>&1 > /dev/null); then
+            rl_message=yes
+          fi
           if (grep CPPFunction $x 2>&1 > /dev/null); then
             CPPF_defined=yes
           fi;;
***************
*** 1071,1077 ****
    DLLD DLSUFFIX somake sodest DLLDFLAGS EXTRADLLDFLAGS \
    runpath runpathprefix LDDYN LIBS DYNLIBS DYNFLAGS DYNRELOC \
    ranlib zcat gunzip perl ctags emacs ln_s make_sh exe_suff \
!   readline completionfun CPPF_defined rl_appendchar rl_save_prompt RLINCLUDE RLLIBS \
    sizeof_long endian has_exp2\
    has_getrusage has_times has_ulong has_ftime has_strftime\
    has_sigrelse has_sigsetmask has_dlopen has_TIOCGWINSZ\
--- 1074,1081 ----
    DLLD DLSUFFIX somake sodest DLLDFLAGS EXTRADLLDFLAGS \
    runpath runpathprefix LDDYN LIBS DYNLIBS DYNFLAGS DYNRELOC \
    ranlib zcat gunzip perl ctags emacs ln_s make_sh exe_suff \
!   readline completionfun CPPF_defined rl_appendchar rl_save_prompt rl_message \
!   RLINCLUDE RLLIBS \
    sizeof_long endian has_exp2\
    has_getrusage has_times has_ulong has_ftime has_strftime\
    has_sigrelse has_sigsetmask has_dlopen has_TIOCGWINSZ\
*** pari-2.0.9.alpha/config/config.h.SH.orig	Tue Jun  9 12:54:14 1998
--- pari-2.0.9.alpha/config/config.h.SH	Mon Jul  6 14:23:27 1998
***************
*** 81,86 ****
--- 81,89 ----
    if test -n "$rl_save_prompt"; then
      echo '#define HAS_RL_SAVE_PROMPT' >> $file
    fi
+   if test -n "$rl_message"; then
+     echo '#define HAS_RL_MESSAGE' >> $file
+   fi
    echo >> $file
  fi
  
*** pari-2.0.9.alpha/src/gp/gp_rl.c.orig	Tue Jun  9 13:45:40 1998
--- pari-2.0.9.alpha/src/gp/gp_rl.c	Mon Jul  6 14:43:39 1998
***************
*** 11,32 ****
  #include "gp.h"
  
  #ifdef READLINE
  BEGINEXTERN
  #  ifdef READLINE_LIBRARY
  #    include <readline.h>
  #  else
  #    include <readline/readline.h>
  #  endif
! char **pari_completion(char *text, int start, int end);
  extern char *filename_completion_function(char *text,int state);
  extern char *username_completion_function(char *text,int state);
  extern int rl_completion_query_items;
  extern int rl_bind_key_in_map();
  ENDEXTERN
  
- typedef char** (*CF)(char*, char* (*)()); /* completion function */
- typedef char* (*GF)(char*, int); /* generator function */
- 
  void print_fun_list(char **matches, int nbli);
  void aide(char *s, int flag);
  
--- 11,47 ----
  #include "gp.h"
  
  #ifdef READLINE
+ typedef char** (*CF)(char*, char* (*)()); /* completion function */
+ typedef char* (*GF)(char*, int); /* generator function */
+ typedef int (*RLCI)(int, int); /* rl_complete and rl_insert functions */
+ 
  BEGINEXTERN
+ #  ifdef HAS_RL_MESSAGE
+ #    define USE_VARARGS
+ #    define PREFER_STDARG
+ #  endif
  #  ifdef READLINE_LIBRARY
  #    include <readline.h>
  #  else
  #    include <readline/readline.h>
  #  endif
! #  ifndef HAS_RL_MESSAGE
! extern int rl_message (const char *, ...);
! extern int rl_clear_message ();
! extern int rl_begin_undo_group (), rl_end_undo_group ();
! extern int rl_stuff_char (int), rl_read_key ();
  extern char *filename_completion_function(char *text,int state);
  extern char *username_completion_function(char *text,int state);
+ #  else
+ #    define rl_stuff_char ((int(*)(int)) rl_stuff_char)
+ #    define filename_completion_function ((GF) filename_completion_function)
+ #    define username_completion_function ((GF) username_completion_function)
+ #  endif
+ char **pari_completion(char *text, int start, int end);
  extern int rl_completion_query_items;
  extern int rl_bind_key_in_map();
  ENDEXTERN
  
  void print_fun_list(char **matches, int nbli);
  void aide(char *s, int flag);
  
***************
*** 36,42 ****
  static entree *current_ep = NULL;
  
  static int pari_rl_back;
! extern Function *rl_last_func;
  static int do_args_complete = 1;
  static int do_matched_insert = 1;
  
--- 51,57 ----
  static entree *current_ep = NULL;
  
  static int pari_rl_back;
! extern RLCI rl_last_func;
  static int do_args_complete = 1;
  static int do_matched_insert = 1;
  
***************
*** 80,87 ****
        
    rl_begin_undo_group();
    if (rl_last_func == pari_rl_complete)
!     rl_last_func = rl_complete;	/* Make repeated TABs different */
!   ret = rl_complete(count,key);
    if (pari_rl_back && (pari_rl_back <= rl_point))
      rl_point -= pari_rl_back;
    rl_end_undo_group(); return ret;
--- 95,103 ----
        
    rl_begin_undo_group();
    if (rl_last_func == pari_rl_complete)
!     /* Make repeated TABs different */
!     rl_last_func = (RLCI) rl_complete;
!   ret = ((RLCI) rl_complete)(count,key);
    if (pari_rl_back && (pari_rl_back <= rl_point))
      rl_point -= pari_rl_back;
    rl_end_undo_group(); return ret;
***************
*** 100,109 ****
      return change_state("electric parens", &do_matched_insert, count);
    while (paropen[i] && paropen[i] != key) i++;
    if (!paropen[i] || !do_matched_insert)
!     return rl_insert(count,key);
    rl_begin_undo_group();
!   rl_insert(count,key);
!   ret = rl_insert(count,parclose[i]);
    rl_point -= count;
    rl_end_undo_group(); return ret;
  }
--- 116,125 ----
      return change_state("electric parens", &do_matched_insert, count);
    while (paropen[i] && paropen[i] != key) i++;
    if (!paropen[i] || !do_matched_insert)
!     return ((RLCI) rl_insert)(count,key);
    rl_begin_undo_group();
!   ((RLCI) rl_insert)(count,key);
!   ret = ((RLCI) rl_insert)(count,parclose[i]);
    rl_point -= count;
    rl_end_undo_group(); return ret;
  }