* readline.c: Always provide scm_init_readline, also if readline
[bpt/guile.git] / guile-readline / readline.c
index 3d27b2d..9f3d14f 100644 (file)
@@ -1,6 +1,6 @@
 /* readline.c --- line editing support for Guile */
 
-/*     Copyright (C) 1997,1999 Free Software Foundation, Inc.
+/*     Copyright (C) 1997,1999, 2000 Free Software Foundation, Inc.
  * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * Boston, MA 02111-1307 USA
  *
  */
+
+/* Software engineering face-lift by Greg J. Badros, 11-Dec-1999,
+   gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */
+
 \f
 
 #include "libguile/_scm.h"
-#if defined (HAVE_RL_GETC_FUNCTION)
-#include "libguile/libguile.h"
+#ifdef HAVE_RL_GETC_FUNCTION
+#include "libguile.h"
 #include "libguile/gh.h"
 #include "libguile/iselect.h"
 
@@ -30,7 +34,8 @@
 #include <readline/history.h>
 #include <sys/time.h>
 
-#include "readline.h"
+#include "libguile/validate.h"
+#include "guile-readline/readline.h"
 
 scm_option scm_readline_opts[] = {
   { SCM_OPTION_BOOLEAN, "history-file", 1,
@@ -43,19 +48,19 @@ scm_option scm_readline_opts[] = {
 
 extern void stifle_history (int max);
 
-SCM_PROC (s_readline_options, "readline-options-interface", 0, 1, 0, scm_readline_options);
-
-SCM
-scm_readline_options (setting)
-     SCM setting;
+SCM_DEFINE (scm_readline_options, "readline-options-interface", 0, 1, 0, 
+            (SCM setting),
+"")
+#define FUNC_NAME s_scm_readline_options
 {
   SCM ans = scm_options (setting,
                         scm_readline_opts,
                         SCM_N_READLINE_OPTIONS,
-                        s_readline_options);
+                        FUNC_NAME);
   stifle_history (SCM_HISTORY_LENGTH);
   return ans;
 }
+#undef FUNC_NAME
 
 #ifndef HAVE_STRDUP
 static char *
@@ -120,14 +125,12 @@ static SCM before_read;
 static int
 current_input_getc (FILE *in)
 {
-  SCM ans;
   if (promptp && SCM_NIMP (before_read))
     {
       scm_apply (before_read, SCM_EOL, SCM_EOL);
       promptp = 0;
     }
-  ans = scm_getc (input_port);
-  return ans;
+  return scm_getc (input_port);
 }
 
 static void
@@ -137,13 +140,81 @@ redisplay ()
   /* promptp = 1; */
 }
 
-SCM_PROC (s_readline, "%readline", 0, 4, 0, scm_readline);
-
 static int in_readline = 0;
 #ifdef USE_THREADS
 static scm_mutex_t reentry_barrier_mutex;
 #endif
 
+static SCM internal_readline (SCM text);
+static SCM handle_error (void *data, SCM tag, SCM args);
+static void reentry_barrier ();
+
+
+SCM_DEFINE (scm_readline, "%readline", 0, 4, 0, 
+            (SCM text, SCM inp, SCM outp, SCM read_hook),
+"")
+#define FUNC_NAME s_scm_readline
+{
+  SCM ans;
+  
+  reentry_barrier ();
+  
+  before_read = SCM_BOOL_F;
+
+  if (!SCM_UNBNDP (text))
+    {
+      if (!(SCM_NIMP (text) && SCM_STRINGP (text)))
+       {
+         --in_readline;
+         scm_wrong_type_arg (s_scm_readline, SCM_ARG1, text);
+       }
+      SCM_COERCE_SUBSTR (text);
+    }
+  
+  if (!((SCM_UNBNDP (inp) && SCM_NIMP (scm_cur_inp) && SCM_OPINFPORTP (inp))
+       || SCM_NIMP (inp) && SCM_OPINFPORTP (inp)))
+    {
+      --in_readline;
+      scm_misc_error (s_scm_readline,
+                     "Input port is not open or not a file port",
+                     SCM_EOL);
+    }
+  
+  if (!((SCM_UNBNDP (outp) && SCM_NIMP (scm_cur_outp) && SCM_OPINFPORTP (outp))
+       || (SCM_NIMP (outp) && SCM_OPOUTFPORTP (outp))))
+    {
+      --in_readline;
+      scm_misc_error (s_scm_readline,
+                     "Output port is not open or not a file port",
+                     SCM_EOL);
+    }
+
+  if (!(SCM_UNBNDP (read_hook) || SCM_FALSEP (read_hook)))
+    {
+      if (!(SCM_NFALSEP (scm_thunk_p (read_hook))))
+       {
+         --in_readline;
+         scm_wrong_type_arg (s_scm_readline, SCM_ARG4, read_hook);
+       }
+      before_read = read_hook;
+    }
+
+  scm_readline_init_ports (inp, outp);
+
+  ans = scm_internal_catch (SCM_BOOL_T,
+                           (scm_catch_body_t) internal_readline,
+                           (void *) SCM_UNPACK (text),
+                           handle_error, 0);
+
+  fclose (rl_instream);
+  fclose (rl_outstream);
+
+  --in_readline;
+  return ans;
+}
+#undef FUNC_NAME
+
+
 static void
 reentry_barrier ()
 {
@@ -160,7 +231,7 @@ reentry_barrier ()
   scm_mutex_unlock (&reentry_barrier_mutex);
 #endif
   if (reentryp)
-    scm_misc_error (s_readline, "readline is not reentrant", SCM_EOL);
+    scm_misc_error (s_scm_readline, "readline is not reentrant", SCM_EOL);
 }
 
 static SCM
@@ -240,79 +311,19 @@ scm_readline_init_ports (SCM inp, SCM outp)
   }
 
   input_port = inp;
-  rl_instream = stream_from_fport (inp, "r", s_readline);
-  rl_outstream = stream_from_fport (outp, "w", s_readline);
+  rl_instream = stream_from_fport (inp, "r", s_scm_readline);
+  rl_outstream = stream_from_fport (outp, "w", s_scm_readline);
 }
 
-SCM
-scm_readline (SCM text, SCM inp, SCM outp, SCM read_hook)
-{
-  SCM ans;
-  
-  reentry_barrier ();
-  
-  before_read = SCM_BOOL_F;
-
-  if (!SCM_UNBNDP (text))
-    {
-      if (!(SCM_NIMP (text) && SCM_STRINGP (text)))
-       {
-         --in_readline;
-         scm_wrong_type_arg (s_readline, SCM_ARG1, text);
-       }
-      SCM_COERCE_SUBSTR (text);
-    }
-  
-  if (!((SCM_UNBNDP (inp) && SCM_NIMP (scm_cur_inp) && SCM_OPINFPORTP (inp))
-       || SCM_NIMP (inp) && SCM_OPINFPORTP (inp)))
-    {
-      --in_readline;
-      scm_misc_error (s_readline,
-                     "Input port is not open or not a file port",
-                     SCM_EOL);
-    }
-  
-  if (!((SCM_UNBNDP (outp) && SCM_NIMP (scm_cur_outp) && SCM_OPINFPORTP (outp))
-       || (SCM_NIMP (outp) && SCM_OPOUTFPORTP (outp))))
-    {
-      --in_readline;
-      scm_misc_error (s_readline,
-                     "Output port is not open or not a file port",
-                     SCM_EOL);
-    }
 
-  if (!(SCM_UNBNDP (read_hook) || SCM_FALSEP (read_hook)))
-    {
-      if (!(SCM_NFALSEP (scm_thunk_p (read_hook))))
-       {
-         --in_readline;
-         scm_wrong_type_arg (s_readline, SCM_ARG4, read_hook);
-       }
-      before_read = read_hook;
-    }
-
-  scm_readline_init_ports (inp, outp);
-
-  ans = scm_internal_catch (SCM_BOOL_T,
-                           (scm_catch_body_t) internal_readline,
-                           (void *) text,
-                           handle_error, 0);
-
-  fclose (rl_instream);
-  fclose (rl_outstream);
-
-  --in_readline;
-  return ans;
-}
-
-SCM_PROC (s_add_history, "add-history", 1, 0, 0, scm_add_history);
 
-SCM
-scm_add_history (SCM text)
+SCM_DEFINE (scm_add_history, "add-history", 1, 0, 0, 
+            (SCM text),
+"")
+#define FUNC_NAME s_scm_add_history
 {
   char* s;
-  SCM_ASSERT ((SCM_NIMP(text) && SCM_STRINGP(text)), text, SCM_ARG1,
-             s_add_history);
+  SCM_VALIDATE_STRING (1,text);
   SCM_COERCE_SUBSTR (text);
 
   s = SCM_CHARS (text);
@@ -320,47 +331,46 @@ scm_add_history (SCM text)
 
   return SCM_UNSPECIFIED;
 }
+#undef FUNC_NAME
 
 
-SCM_PROC (s_read_history, "read-history", 1, 0, 0, scm_read_history);
-
-SCM
-scm_read_history (SCM file)
+SCM_DEFINE (scm_read_history, "read-history", 1, 0, 0, 
+            (SCM file),
+"")
+#define FUNC_NAME s_scm_read_history
 {
-  SCM_ASSERT (SCM_NIMP (file) && SCM_STRINGP (file),
-             file, SCM_ARG1, s_read_history);
-  return read_history (SCM_ROCHARS (file)) ? SCM_BOOL_F : SCM_BOOL_T;
+  SCM_VALIDATE_STRING (1,file);
+  return SCM_NEGATE_BOOL(read_history (SCM_ROCHARS (file)));
 }
+#undef FUNC_NAME
 
 
-SCM_PROC (s_write_history, "write-history", 1, 0, 0, scm_write_history);
-
-SCM
-scm_write_history (SCM file)
+SCM_DEFINE (scm_write_history, "write-history", 1, 0, 0, 
+            (SCM file),
+"")
+#define FUNC_NAME s_scm_write_history
 {
-  SCM_ASSERT (SCM_NIMP (file) && SCM_STRINGP (file),
-             file, SCM_ARG1, s_write_history);
-  return write_history (SCM_ROCHARS (file)) ? SCM_BOOL_F : SCM_BOOL_T;
+  SCM_VALIDATE_STRING (1,file);
+  return SCM_NEGATE_BOOL(write_history (SCM_ROCHARS (file)));
 }
+#undef FUNC_NAME
 
 
-SCM_PROC (s_filename_completion_function, "filename-completion-function", 2, 0, 0, scm_filename_completion_function);
-
-SCM
-scm_filename_completion_function (SCM text, SCM continuep)
+SCM_DEFINE (scm_filename_completion_function, "filename-completion-function", 2, 0, 0, 
+            (SCM text, SCM continuep),
+"")
+#define FUNC_NAME s_scm_filename_completion_function
 {
   char *s;
   SCM ans;
-  SCM_ASSERT (SCM_NIMP (text) && SCM_STRINGP (text),
-             text,
-             SCM_ARG1,
-             s_filename_completion_function);
+  SCM_VALIDATE_STRING (1,text);
   SCM_COERCE_SUBSTR (text);
   s = filename_completion_function (SCM_CHARS (text), SCM_NFALSEP (continuep));
   ans = scm_makfrom0str (s);
   free (s);
   return ans;
 }
+#undef FUNC_NAME
 
 /*
  * The following has been modified from code contributed by
@@ -387,7 +397,7 @@ completion_function (char *text, int continuep)
        return NULL;
   
       if (!(SCM_NIMP (res) && SCM_STRINGP (res)))
-       scm_misc_error (s_readline,
+       scm_misc_error (s_scm_readline,
                        "Completion function returned bogus value: %S",
                        SCM_LIST1 (res));
       SCM_COERCE_SUBSTR (res);
@@ -397,18 +407,19 @@ completion_function (char *text, int continuep)
 
 /*Bouncing parenthesis (reimplemented by GH, 11/23/98, since readline is strict gpl)*/
 
-static void match_paren(int x, int k);
-static int find_matching_paren(int k);
-static void init_bouncing_parens();
+static int match_paren (int x, int k);
+static int find_matching_paren (int k);
+static void init_bouncing_parens ();
 
 static void
-init_bouncing_parens()
+init_bouncing_parens ()
 {
-  if(strncmp(rl_get_keymap_name(rl_get_keymap()), "vi", 2)) {
-    rl_bind_key(')', match_paren);
-    rl_bind_key(']', match_paren);
-    rl_bind_key('}', match_paren);
-  }
+  if (strncmp (rl_get_keymap_name (rl_get_keymap ()), "vi", 2))
+    {
+      rl_bind_key (')', match_paren);
+      rl_bind_key (']', match_paren);
+      rl_bind_key ('}', match_paren);
+    }
 }
 
 static int
@@ -443,57 +454,66 @@ find_matching_paren(int k)
        }
       else if (rl_line_buffer[i] == c)
        {
-         if (end_parens_found==0) return i;
+         if (end_parens_found==0)
+           return i;
          else --end_parens_found;
        }
     }
   return -1;
 }
 
-static void
-match_paren(int x, int k)
+static int
+match_paren (int x, int k)
 {
-  int tmp;
-  fd_set readset;
+  int tmp, fno;
+  SELECT_TYPE readset;
   struct timeval timeout;
   
-  rl_insert(x, k);
+  rl_insert (x, k);
   if (!SCM_READLINE_BOUNCE_PARENS)
-    return;
+    return 0;
 
   /* Did we just insert a quoted paren?  If so, then don't bounce.  */
   if (rl_point - 1 >= 1
       && rl_line_buffer[rl_point - 2] == '\\')
-    return;
+    return 0;
 
   tmp = 1000 * SCM_READLINE_BOUNCE_PARENS;
   timeout.tv_sec = tmp / 1000000;
   timeout.tv_usec = tmp % 1000000;
-  FD_ZERO(&readset);
-  FD_SET(fileno(rl_instream), &readset);
+  FD_ZERO (&readset);
+  fno = fileno (rl_instream);
+  FD_SET (fno, &readset);
   
-  if(rl_point > 1) {
-    tmp = rl_point;
-    rl_point = find_matching_paren(k);
-    if(rl_point > -1) {
-      rl_redisplay();
-      scm_internal_select(1, &readset, NULL, NULL, &timeout);
+  if (rl_point > 1)
+    {
+      tmp = rl_point;
+      rl_point = find_matching_paren (k);
+      if (rl_point > -1)
+       {
+         rl_redisplay ();
+         scm_internal_select (fno + 1, &readset, NULL, NULL, &timeout);
+       }
+      rl_point = tmp;
     }
-    rl_point = tmp;
-  }
+  return 0;
 }
 
+#endif /* HAVE_RL_GETC_FUNCTION */
 
 void
 scm_init_readline ()
 {
-#include "readline.x"
+#ifdef HAVE_RL_GETC_FUNCTION
+#include "guile-readline/readline.x"
   scm_readline_completion_function_var
     = scm_sysintern ("*readline-completion-function*", SCM_BOOL_F);
   rl_getc_function = current_input_getc;
   rl_redisplay_function = redisplay;
   rl_completion_entry_function = (Function*) completion_function;
   rl_basic_word_break_characters = "\t\n\"'`;()";
+  rl_readline_name = "Guile";
+
 #ifdef USE_THREADS
   scm_mutex_init (&reentry_barrier_mutex);
 #endif
@@ -502,6 +522,11 @@ scm_init_readline ()
                 SCM_N_READLINE_OPTIONS);
   init_bouncing_parens();
   scm_add_feature ("readline");
+#endif /* HAVE_RL_GETC_FUNCTION */
 }
 
-#endif 
+/*
+  Local Variables:
+  c-file-style: "gnu"
+  End:
+*/