/* parens.c -- implementation of matching parentheses feature. */

/* Copyright (C) 1987, 1989, 1992-2009 Free Software Foundation, Inc.

   This file is part of the GNU Readline Library (Readline), a library
   for reading lines of text with interactive input and history editing.      

   Readline is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   Readline is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
*/

#define READLINE_LIBRARY

#if defined (__TANDEM)
#  include <floss.h>
#endif

#include "rlconf.h"

#if defined (HAVE_CONFIG_H)
#  include <config.h>
#endif

#include <stdio.h>
#include <sys/types.h>

#if defined (HAVE_UNISTD_H)
#  include <unistd.h>
#endif

#include "posixselect.h"

#if defined (HAVE_STRING_H)
#  include <string.h>
#else /* !HAVE_STRING_H */
#  include <strings.h>
#endif /* !HAVE_STRING_H */

#if !defined (strchr) && !defined (__STDC__)
extern char *strchr (), *strrchr ();
#endif /* !strchr && !__STDC__ */

#include "readline.h"
#include "rlprivate.h"

static int find_matching_open PARAMS((char *, int, int));

/* Non-zero means try to blink the matching open parenthesis when the
   close parenthesis is inserted. */
#if defined (HAVE_SELECT)
int rl_blink_matching_paren = 1;
#else /* !HAVE_SELECT */
int rl_blink_matching_paren = 0;
#endif /* !HAVE_SELECT */

static int _paren_blink_usec = 500000;

/* Change emacs_standard_keymap to have bindings for paren matching when
   ON_OR_OFF is 1, change them back to self_insert when ON_OR_OFF == 0. */
void
_rl_enable_paren_matching (on_or_off)
     int on_or_off;
{
  if (on_or_off)
    {	/* ([{ */
      rl_bind_key_in_map (')', rl_insert_close, emacs_standard_keymap);
      rl_bind_key_in_map (']', rl_insert_close, emacs_standard_keymap);
      rl_bind_key_in_map ('}', rl_insert_close, emacs_standard_keymap);
    }
  else
    {	/* ([{ */
      rl_bind_key_in_map (')', rl_insert, emacs_standard_keymap);
      rl_bind_key_in_map (']', rl_insert, emacs_standard_keymap);
      rl_bind_key_in_map ('}', rl_insert, emacs_standard_keymap);
    }
}

int
rl_set_paren_blink_timeout (u)
     int u;
{
  int o;

  o = _paren_blink_usec;
  if (u > 0)
    _paren_blink_usec = u;
  return (o);
}

int
rl_insert_close (count, invoking_key)
     int count, invoking_key;
{
  if (rl_explicit_arg || !rl_blink_matching_paren)
    _rl_insert_char (count, invoking_key);
  else
    {
#if defined (HAVE_SELECT)
      int orig_point, match_point, ready;
      struct timeval timer;
      fd_set readfds;

      _rl_insert_char (1, invoking_key);
      (*rl_redisplay_function) ();
      match_point =
	find_matching_open (rl_line_buffer, rl_point - 2, invoking_key);

      /* Emacs might message or ring the bell here, but I don't. */
      if (match_point < 0)
	return -1;

      FD_ZERO (&readfds);
      FD_SET (fileno (rl_instream), &readfds);
      USEC_TO_TIMEVAL (_paren_blink_usec, timer);

      orig_point = rl_point;
      rl_point = match_point;
      (*rl_redisplay_function) ();
      ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
      rl_point = orig_point;
#else /* !HAVE_SELECT */
      _rl_insert_char (count, invoking_key);
#endif /* !HAVE_SELECT */
    }
  return 0;
}

static int
find_matching_open (string, from, closer)
     char *string;
     int from, closer;
{
  register int i;
  int opener, level, delimiter;

  switch (closer)
    {
    case ']': opener = '['; break;
    case '}': opener = '{'; break;
    case ')': opener = '('; break;
    default:
      return (-1);
    }

  level = 1;			/* The closer passed in counts as 1. */
  delimiter = 0;		/* Delimited state unknown. */

  for (i = from; i > -1; i--)
    {
      if (delimiter && (string[i] == delimiter))
	delimiter = 0;
      else if (rl_basic_quote_characters && strchr (rl_basic_quote_characters, string[i]))
	delimiter = string[i];
      else if (!delimiter && (string[i] == closer))
	level++;
      else if (!delimiter && (string[i] == opener))
	level--;

      if (!level)
	break;
    }
  return (i);
}
