This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[eliz@is.elta.co.il: GDB: DJGPP-related problems in readline]


------- Start of forwarded message -------
Date: Sun, 27 Jun 1999 19:20:06 +0300 (IDT)
From: Eli Zaretskii <eliz@is.elta.co.il>
X-Sender: eliz@is
To: DJ Delorie <dj@delorie.com>
cc: Robert Hoehne <robert.hoehne@gmx.net>
Subject: GDB: DJGPP-related problems in readline
Content-Type: TEXT/PLAIN; charset=US-ASCII
Note-from-DJ: This may be spam

1999-06-26  Eli Zaretskii  <eliz@is.elta.co.il>

	* complete.c (username_completion_function) [__WIN32__]: Don't
	return NULL under DJGPP.
	(filename_completion_function) [__WIN32__ || __MSDOS__]: Handle
	drive-relative file names like "d:foo/bar".

	* bind.c (O_BINARY): If not defined, define to zero.
	(_rl_read_file): Open file in binary mode.  Strip \r characters
	before every \n, and update the buffer size.
	(rl_read_init_file) [__MSDOS__]: Try ~/_inputrc if ~/.inputrc
	failed.

	* rltty.c [__GO32__]: Don't disable signals, don't include
	<pc.h>.
	(prepare_terminal_settings) [__GO32__]: No need to ifdef away,
	termios is supported now.
	(rl_prep_terminal): Ditto.
	(rl_deprep_terminal): Ditto.

	* input.c [__GO32__]: Don't include <pc.h>.
	(rl_gather_tyi) [__GO32__]: Remove ifdef'ed code; DJGPP now
	supports `select'.
	(rl_getc) [__GO32__]: Remove ifdef'ed code; DJGPP supports
	termios, single-character read's, and signals.

	* readline.c [__GO32__]: Don't disable signal handling.
	(rl_refresh_line) [__GO32__]: Remove old buggy code.

	* terminal.c (_rl_get_screen_size) [__DJGPP__]: Call ScreenCols
	and ScreenRows to get the screen size.
	(_rl_init_terminal_io) [__GO32__]: Call _rl_get_screen_size to set
	the screen size.
	(ding) [__DJGPP__]: Support visible bell.

	* signals.c [__DJGPP__]: Don't disable signal handling.  Include
	<pc.h>.

	* histfile.c (read_history_range) [__MSDOS__]: Allow the default
	history file to begin with an underscore.  Don't fail if the
	number of characters read is smaller than the file's size, due to
	stripped \r characters.
	(history_truncate_file) [__MSDOS__]: Allow the default history
	file to begin with an underscore.  Use the actual number of chars
	read as the number of characters to write back.
	(history_do_write) [__MSDOS__]: Allow the default history file to
	begin with an underscore.

	* display.c (_rl_move_vert) [__GO32__]: fflush the output, to make
	sure the cursor position is updated.
	(_rl_clear_screen) [__GO32__]: Clear the text-mode screen.
	(insert_some_chars, delete_chars) [__GO32__]: Make these two
	functions a no-op: they are not called in the DJGPP version, and
	the code will crash if it runs.

*** cvs/readline/complete.c	Fri Apr 16 04:34:52 1999
- --- ./readline/complete.c	Wed Jun  2 22:53:00 1999
*************** username_completion_function (text, stat
*** 1361,1369 ****
       int state;
       char *text;
  {
! #if defined (__GO32__) || defined (__WIN32__)
    return (char *)NULL;
! #else /* !__GO32__ */
    static char *username = (char *)NULL;
    static struct passwd *entry;
    static int namelen, first_char, first_char_loc;
- --- 1361,1369 ----
       int state;
       char *text;
  {
! #if defined (__WIN32__)
    return (char *)NULL;
! #else /* !__WIN32__ */
    static char *username = (char *)NULL;
    static struct passwd *entry;
    static int namelen, first_char, first_char_loc;
*************** username_completion_function (text, stat
*** 1406,1412 ****
  
        return (value);
      }
! #endif /* !__GO32__ */
  }
  
  /* Okay, now we write the entry_function for filename completion.  In the
- --- 1406,1412 ----
  
        return (value);
      }
! #endif /* !__WIN32__ */
  }
  
  /* Okay, now we write the entry_function for filename completion.  In the
*************** filename_completion_function (text, stat
*** 1453,1458 ****
- --- 1453,1466 ----
  	  strcpy (filename, ++temp);
  	  *temp = '\0';
  	}
+ #if defined (__WIN32__) || defined (__MSDOS__)
+       /* Handle the drive-relative names "d:foo/bar".  */
+       else if (dirname[1] == ':')
+ 	{
+ 	  strcpy (filename, dirname + 2);
+ 	  dirname[2] = '\0';
+ 	}
+ #endif
        else
  	{
  	  dirname[0] = '.';
*** cvs/readline/bind.c	Fri Apr 16 04:34:52 1999
- --- ./readline/bind.c	Thu Jun  3 18:58:04 1999
*************** extern int errno;
*** 62,67 ****
- --- 62,71 ----
  extern char *strchr (), *strrchr ();
  #endif /* !strchr && !__STDC__ */
  
+ #ifndef O_BINARY
+ # define O_BINARY 0
+ #endif
+ 
  extern int _rl_horizontal_scroll_mode;
  extern int _rl_mark_modified_lines;
  extern int _rl_bell_preference;
*************** _rl_read_file (filename, sizep)
*** 642,648 ****
    char *buffer;
    int i, file;
  
!   if ((stat (filename, &finfo) < 0) || (file = open (filename, O_RDONLY, 0666)) < 0)
      return ((char *)NULL);
  
    file_size = (size_t)finfo.st_size;
- --- 646,652 ----
    char *buffer;
    int i, file;
  
!   if ((stat (filename, &finfo) < 0) || (file = open (filename, O_RDONLY|O_BINARY, 0666)) < 0)
      return ((char *)NULL);
  
    file_size = (size_t)finfo.st_size;
*************** _rl_read_file (filename, sizep)
*** 670,675 ****
- --- 674,703 ----
      }
  
    buffer[file_size] = '\0';
+ 
+ #if O_BINARY
+   {
+     /* Systems which distinguish between text and binary files need
+        to strip the CR characters before each Newline, otherwise the
+        parsing functions won't work.  */
+     char *s, *d;
+     size_t removed = 0;
+ 
+     for (s = buffer, d = buffer; s < buffer + file_size; s++)
+       {
+ 	if (removed)
+ 	  *d = *s;
+ 	if (*s != '\r' || s[1] != '\n')
+ 	  d++;
+ 	else
+ 	  removed++;
+       }
+ 
+     file_size -= removed;
+     buffer[file_size] = '\0';
+   }
+ #endif
+ 
    if (sizep)
      *sizep = file_size;
    return (buffer);
*************** rl_re_read_init_file (count, ignore)
*** 691,696 ****
- --- 719,725 ----
       1. the filename used for the previous call
       2. the value of the shell variable `INPUTRC'
       3. ~/.inputrc
+      4. (for __MSDOS__ only) ~/_inputrc
     If the file existed and could be opened and read, 0 is returned,
     otherwise errno is returned. */
  int
*************** rl_read_init_file (filename)
*** 710,715 ****
- --- 739,758 ----
    if (*filename == 0)
      filename = DEFAULT_INPUTRC;
  
+ #ifdef __MSDOS__
+   {
+     /* DOS doesn't allow leading dots in file names.  If the original
+        name fails (it could work if we are on Windows), fall back to
+        ~/_inputrc.  */
+     int retval = _rl_read_init_file (filename, 0);
+ 
+     if (retval == 0)
+       return retval;
+     else if (strcmp (filename, "~/.inputrc") == 0)
+       filename = "~/_inputrc";
+   }
+ #endif
+ 
    return (_rl_read_init_file (filename, 0));
  }
  
*** cvs/readline/rltty.c	Fri Apr 16 04:34:52 1999
- --- ./readline/rltty.c	Thu May 20 19:20:02 1999
*************** extern int _rl_enable_keypad, _rl_enable
*** 55,65 ****
  
  extern void _rl_control_keypad ();
  
- - #if defined (__GO32__)
- - #  include <pc.h>
- - #  undef HANDLE_SIGNALS
- - #endif /* __GO32__ */
- - 
  /* Indirect functions to allow apps control over terminal management. */
  extern void rl_prep_terminal (), rl_deprep_terminal ();
  
- --- 55,60 ----
*************** prepare_terminal_settings (meta_flag, ot
*** 260,266 ****
       int meta_flag;
       TIOTYPE otio, *tiop;
  {
- - #if !defined (__GO32__)
    readline_echoing_p = (otio.sgttyb.sg_flags & ECHO);
  
    /* Copy the original settings to the structure we're going to use for
- --- 255,260 ----
*************** prepare_terminal_settings (meta_flag, ot
*** 326,332 ****
    tiop->ltchars.t_dsuspc = -1;	/* C-y */
    tiop->ltchars.t_lnextc = -1;	/* C-v */
  #endif /* TIOCGLTC */
- - #endif /* !__GO32__ */
  }
  
  #else  /* !defined (NEW_TTY_DRIVER) */
- --- 320,325 ----
*************** void
*** 521,527 ****
  rl_prep_terminal (meta_flag)
       int meta_flag;
  {
- - #if !defined (__GO32__)
    int tty;
    TIOTYPE tio;
  
- --- 514,519 ----
*************** rl_prep_terminal (meta_flag)
*** 556,569 ****
    terminal_prepped = 1;
  
    release_sigint ();
- - #endif /* !__GO32__ */
  }
  
  /* Restore the terminal's normal settings and modes. */
  void
  rl_deprep_terminal ()
  {
- - #if !defined (__GO32__)
    int tty;
  
    if (!terminal_prepped)
- --- 548,559 ----
*************** rl_deprep_terminal ()
*** 588,594 ****
    terminal_prepped = 0;
  
    release_sigint ();
- - #endif /* !__GO32__ */
  }
  
  /* **************************************************************** */
- --- 578,583 ----
*** cvs/readline/input.c	Fri Apr 16 04:34:52 1999
- --- ./readline/input.c	Wed May 19 22:26:44 1999
*************** extern Keymap _rl_keymap;
*** 96,105 ****
  
  extern int _rl_convert_meta_chars_to_ascii;
  
- - #if defined (__GO32__)
- - #  include <pc.h>
- - #endif /* __GO32__ */
- - 
  /* Non-null means it is a pointer to a function to run while waiting for
     character input. */
  Function *rl_event_hook = (Function *)NULL;
- --- 96,101 ----
*************** rl_unget_char (key)
*** 201,217 ****
  static void
  rl_gather_tyi ()
  {
- - #if defined (__GO32__)
- -   char input;
- - 
- -   if (isatty (0) && kbhit () && ibuffer_space ())
- -     {
- -       int i;
- -       i = (*rl_getc_function) (rl_instream);
- -       rl_stuff_char (i);
- -     }
- - #else /* !__GO32__ */
- - 
    int tty;
    register int tem, result;
    int chars_avail;
- --- 197,202 ----
*************** rl_gather_tyi ()
*** 280,286 ****
        if (chars_avail)
  	rl_stuff_char (input);
      }
- - #endif /* !__GO32__ */
  }
  
  /* Is there input available to be read on the readline input file
- --- 265,270 ----
*************** rl_getc (stream)
*** 392,402 ****
    int result, flags;
    unsigned char c;
  
- - #if defined (__GO32__)
- -   if (isatty (0))
- -     return (getkey () & 0x7F);
- - #endif /* __GO32__ */
- - 
    while (1)
      {
        result = read (fileno (stream), &c, sizeof (unsigned char));
- --- 376,381 ----
*************** rl_getc (stream)
*** 438,449 ****
  	}
  #endif /* _POSIX_VERSION && EAGAIN && O_NONBLOCK */
  
- - #if !defined (__GO32__)
        /* If the error that we received was SIGINT, then try again,
  	 this is simply an interrupted system call to read ().
  	 Otherwise, some error ocurred, also signifying EOF. */
        if (errno != EINTR)
  	return (EOF);
- - #endif /* !__GO32__ */
      }
  }
- --- 417,426 ----
*** cvs/readline/readline.c	Fri Apr 16 04:34:52 1999
- --- ./readline/readline.c	Thu May 20 18:09:24 1999
*************** static void readline_default_bindings ()
*** 174,180 ****
  #if defined (__GO32__)
  #  include <go32.h>
  #  include <pc.h>
- - #  undef HANDLE_SIGNALS
  #endif /* __GO32__ */
  
  extern char *xmalloc (), *xrealloc ();
- --- 174,179 ----
*************** rl_refresh_line ()
*** 1249,1267 ****
  
    _rl_move_vert (curr_line);
    _rl_move_cursor_relative (0, the_line);   /* XXX is this right */
- - 
- - #if defined (__GO32__)
- -   {
- -     int row, col, width, row_start;
- - 
- -     ScreenGetCursor (&row, &col);
- -     width = ScreenCols ();
- -     row_start = ScreenPrimary + (row * width);
- -     memset (row_start + col, 0, (width - col) * 2);
- -   }
- - #else /* !__GO32__ */
    _rl_clear_to_eol (0);		/* arg of 0 means to not use spaces */
- - #endif /* !__GO32__ */
  
    rl_forced_update_display ();
    rl_display_fixed = 1;
- --- 1248,1254 ----
*** cvs/readline/terminal.c	Mon Apr 26 21:30:28 1999
- --- ./readline/terminal.c	Sat May 22 17:12:48 1999
*************** _rl_get_screen_size (tty, ignore_env)
*** 186,192 ****
        if (ignore_env == 0 && (ss = get_env_value ("COLUMNS")))
  	screenwidth = atoi (ss);
  
! #if !defined(__DJGPP__)
        if (screenwidth <= 0 && term_string_buffer)
  	screenwidth = tgetnum ("co");
  #endif
- --- 186,195 ----
        if (ignore_env == 0 && (ss = get_env_value ("COLUMNS")))
  	screenwidth = atoi (ss);
  
! #if defined(__DJGPP__)
!       if (screenwidth <= 0)
! 	screenwidth = ScreenCols ();
! #else
        if (screenwidth <= 0 && term_string_buffer)
  	screenwidth = tgetnum ("co");
  #endif
*************** _rl_get_screen_size (tty, ignore_env)
*** 199,205 ****
        if (ignore_env == 0 && (ss = get_env_value ("LINES")))
  	screenheight = atoi (ss);
  
! #if !defined(__DJGPP__)
        if (screenheight <= 0 && term_string_buffer)
  	screenheight = tgetnum ("li");
  #endif
- --- 202,211 ----
        if (ignore_env == 0 && (ss = get_env_value ("LINES")))
  	screenheight = atoi (ss);
  
! #if defined(__DJGPP__)
!       if (screenheight <= 0)
! 	screenheight = ScreenRows ();
! #else
        if (screenheight <= 0 && term_string_buffer)
  	screenheight = tgetnum ("li");
  #endif
*************** _rl_init_terminal_io (terminal_name)
*** 295,303 ****
       char *terminal_name;
  {
  #if defined (__GO32__)
!   screenwidth = ScreenCols ();
!   screenheight = ScreenRows ();
!   screenchars = screenwidth * screenheight;
    term_cr = "\r";
    term_im = term_ei = term_ic = term_IC = (char *)NULL;
    term_up = term_dc = term_DC = visible_bell = (char *)NULL;
- --- 301,309 ----
       char *terminal_name;
  {
  #if defined (__GO32__)
!   screenwidth = screenheight = 0;
!   _rl_get_screen_size (rl_instream ? fileno (rl_instream) : 0, 0);
! 
    term_cr = "\r";
    term_im = term_ei = term_ic = term_IC = (char *)NULL;
    term_up = term_dc = term_DC = visible_bell = (char *)NULL;
*************** ding ()
*** 500,527 ****
  {
    if (readline_echoing_p)
      {
- - #if !defined (__GO32__)
        switch (_rl_bell_preference)
          {
  	case NO_BELL:
  	default:
  	  break;
  	case VISIBLE_BELL:
  	  if (visible_bell)
  	    {
  	      tputs (visible_bell, 1, _rl_output_character_function);
  	      break;
  	    }
  	  /* FALLTHROUGH */
  	case AUDIBLE_BELL:
  	  fprintf (stderr, "\007");
  	  fflush (stderr);
  	  break;
          }
- - #else /* __GO32__ */
- -       fprintf (stderr, "\007");
- -       fflush (stderr);
- - #endif /* __GO32__ */
        return (0);
      }
    return (-1);
- --- 506,533 ----
  {
    if (readline_echoing_p)
      {
        switch (_rl_bell_preference)
          {
  	case NO_BELL:
  	default:
  	  break;
  	case VISIBLE_BELL:
+ #ifdef __DJGPP__
+ 	  ScreenVisualBell ();
+ 	  break;
+ #else
  	  if (visible_bell)
  	    {
  	      tputs (visible_bell, 1, _rl_output_character_function);
  	      break;
  	    }
  	  /* FALLTHROUGH */
+ #endif
  	case AUDIBLE_BELL:
  	  fprintf (stderr, "\007");
  	  fflush (stderr);
  	  break;
          }
        return (0);
      }
    return (-1);
*** cvs/readline/signals.c	Fri Apr 16 04:34:54 1999
- --- ./readline/signals.c	Thu May 20 19:20:44 1999
***************
*** 40,48 ****
  #  include <sys/ioctl.h>
  #endif /* GWINSZ_IN_SYS_IOCTL */
  
! #if defined (__GO32__)
! #  undef HANDLE_SIGNALS
! #endif /* __GO32__ */
  
  #if defined (HANDLE_SIGNALS)
  /* Some standard library routines. */
- --- 40,48 ----
  #  include <sys/ioctl.h>
  #endif /* GWINSZ_IN_SYS_IOCTL */
  
! #ifdef __DJGPP__
! #  include <pc.h>
! #endif
  
  #if defined (HANDLE_SIGNALS)
  /* Some standard library routines. */
*** cvs/readline/histfile.c	Fri Apr 16 04:34:52 1999
- --- ./readline/histfile.c	Sat Jun  5 16:11:48 1999
*************** read_history_range (filename, from, to)
*** 140,145 ****
- --- 140,154 ----
    input = history_filename (filename);
    file = open (input, O_RDONLY|O_BINARY, 0666);
  
+ #ifdef __MSDOS__
+   /* MSDOS doesn't allow leading dots in file names.  Try again
+      with the dot replaced by an underscore.  */
+   if (file < 0 && !filename)
+     {
+       input[strlen (input) - 8] = '_';
+       file = open (input, O_RDONLY|O_BINARY, 0666);
+     }
+ #endif
    if ((file < 0) || (fstat (file, &finfo) == -1))
      goto error_and_exit;
  
*************** read_history_range (filename, from, to)
*** 155,161 ****
- --- 164,177 ----
      }
  
    buffer = xmalloc (file_size + 1);
+ #ifdef __MSDOS__
+   /* The actual number read might be smaller, due to CRs being
+      stripped.  */
+   file_size = read (file, buffer, file_size);
+   if (file_size < 0)
+ #else
    if (read (file, buffer, file_size) != file_size)
+ #endif
      {
    error_and_exit:
        if (file >= 0)
*************** history_truncate_file (fname, lines)
*** 229,234 ****
- --- 245,260 ----
    filename = history_filename (fname);
    file = open (filename, O_RDONLY|O_BINARY, 0666);
  
+ #ifdef __MSDOS__
+   /* MSDOS doesn't allow leading dots in file names.  Try again
+      with the dot replaced by an underscore.  */
+   if (file < 0 && !fname)
+     {
+       filename[strlen (filename) - 8] = '_';
+       file = open (filename, O_RDONLY|O_BINARY, 0666);
+     }
+ #endif
+ 
    if (file == -1 || fstat (file, &finfo) == -1)
      goto truncate_exit;
  
*************** history_truncate_file (fname, lines)
*** 275,281 ****
       truncate to. */
    if (i && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1))
      {
!       write (file, buffer + i, file_size - i);
        close (file);
      }
  
- --- 301,307 ----
       truncate to. */
    if (i && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1))
      {
!       write (file, buffer + i, chars_read - i);
        close (file);
      }
  
*************** history_do_write (filename, nelements, o
*** 302,311 ****
- --- 328,353 ----
    mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY;
    output = history_filename (filename);
  
+ 
    if ((file = open (output, mode, 0600)) == -1)
      {
+ #ifdef __MSDOS__
+       /* MSDOS doesn't allow leading dots in file names.  If this is
+ 	 the default file name, try again with the dot replaced by an
+ 	 underscore.  */
+       if (!filename)
+ 	{
+ 	  output[strlen (output) - 8] = '_';
+ 	  if ((file = open (output, mode, 0600)) == -1)
+ 	    {
+ 	      FREE (output);
+ 	      return (errno);
+ 	    }
+ 	}
+ #else
        FREE (output);
        return (errno);
+ #endif
      }
  
    if (nelements > history_length)
*** cvs/readline/display.c	Mon Apr 26 21:30:26 1999
- --- ./readline/display.c	Sat May 22 18:51:58 1999
*************** _rl_move_vert (to)
*** 1107,1112 ****
- --- 1107,1113 ----
    {
      int row, col;
  
+     fflush (rl_outstream);	/* make sure the cursor pos is current! */
      ScreenGetCursor (&row, &col);
      ScreenSetCursor ((row + to - _rl_last_v_pos), col);
    }
*************** void
*** 1333,1339 ****
  _rl_clear_to_eol (count)
       int count;
  {
! #if !defined (__GO32__)
    if (term_clreol)
      tputs (term_clreol, 1, _rl_output_character_function);
    else if (count)
- --- 1334,1340 ----
  _rl_clear_to_eol (count)
       int count;
  {
! #ifndef __GO32__
    if (term_clreol)
      tputs (term_clreol, 1, _rl_output_character_function);
    else if (count)
*************** space_to_eol (count)
*** 1358,1369 ****
  void
  _rl_clear_screen ()
  {
! #if !defined (__GO32__)
    if (term_clrpag)
      tputs (term_clrpag, 1, _rl_output_character_function);
    else
- - #endif /* !__GO32__ */
      crlf ();
  }
  
  /* Insert COUNT characters from STRING to the output stream. */
- --- 1359,1373 ----
  void
  _rl_clear_screen ()
  {
! #if defined (__GO32__)
!   ScreenClear ();	/* FIXME: only works in text modes */
!   ScreenSetCursor (0, 0);  /* term_clrpag is "cl" which homes the cursor */
! #else  /* !__GO32__ */
    if (term_clrpag)
      tputs (term_clrpag, 1, _rl_output_character_function);
    else
      crlf ();
+ #endif /* !__GO32__ */
  }
  
  /* Insert COUNT characters from STRING to the output stream. */
*************** insert_some_chars (string, count)
*** 1372,1391 ****
       char *string;
       int count;
  {
! #if defined (__GO32__)
!   int row, col, width;
!   char *row_start;
! 
!   ScreenGetCursor (&row, &col);
!   width = ScreenCols ();
!   row_start = ScreenPrimary + (row * width);
! 
!   memcpy (row_start + col + count, row_start + col, width - col - count);
! 
!   /* Place the text on the screen. */
!   _rl_output_some_chars (string, count);
! #else /* !_GO32 */
! 
    /* If IC is defined, then we do not have to "enter" insert mode. */
    if (term_IC)
      {
- --- 1376,1382 ----
       char *string;
       int count;
  {
! #ifndef __GO32__
    /* If IC is defined, then we do not have to "enter" insert mode. */
    if (term_IC)
      {
*************** static void
*** 1426,1443 ****
  delete_chars (count)
       int count;
  {
! #if defined (__GO32__)
!   int row, col, width;
!   char *row_start;
! 
!   ScreenGetCursor (&row, &col);
!   width = ScreenCols ();
!   row_start = ScreenPrimary + (row * width);
! 
!   memcpy (row_start + col, row_start + col + count, width - col - count);
!   memset (row_start + width - count, 0, count * 2);
! #else /* !_GO32 */
! 
    if (count > screenwidth)	/* XXX */
      return;
  
- --- 1417,1423 ----
  delete_chars (count)
       int count;
  {
! #ifndef __GO32__
    if (count > screenwidth)	/* XXX */
      return;
  
------- End of forwarded message -------

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]