source: patches/bash-3.2-fixes-7.patch@ 3dda813

clfs-1.2 clfs-2.1 clfs-3.0.0-systemd clfs-3.0.0-sysvinit systemd sysvinit
Last change on this file since 3dda813 was a60e4c5, checked in by Joe Ciccone <jciccone@…>, 17 years ago

Updated Various branch update patches.

  • Property mode set to 100644
File size: 130.9 KB
  • array.c

    Submitted By: Jim Gifford (jim at linuxfromscratch dot org)
    Date: 12-20-2007
    Initial Package Version: 3.2
    Origin: Upstream
    Upstream Status: Applied
    Description: Contains all upstream patches up to 3.2-033
    
    diff -Naur bash-3.2.orig/array.c bash-3.2/array.c
    old new  
    120120        return(a1);
    121121}
    122122
    123 #ifdef INCLUDE_UNUSED
    124123/*
    125124 * Make and return a new array composed of the elements in array A from
    126125 * S to E, inclusive.
     
    141140        for (p = s, i = 0; p != e; p = element_forw(p), i++) {
    142141                n = array_create_element (element_index(p), element_value(p));
    143142                ADD_BEFORE(a->head, n);
    144                 mi = element_index(ae);
     143                mi = element_index(n);
    145144        }
    146145        a->num_elements = i;
    147146        a->max_index = mi;
    148147        return a;
    149148}
    150 #endif
    151149
    152150/*
    153151 * Walk the array, calling FUNC once for each element, with the array
     
    300298        return array;
    301299}
    302300
     301ARRAY   *
     302array_quote_escapes(array)
     303ARRAY   *array;
     304{
     305        ARRAY_ELEMENT   *a;
     306        char    *t;
     307
     308        if (array == 0 || array_head(array) == 0 || array_empty(array))
     309                return (ARRAY *)NULL;
     310        for (a = element_forw(array->head); a != array->head; a = element_forw(a)) {
     311                t = quote_escapes (a->value);
     312                FREE(a->value);
     313                a->value = t;
     314        }
     315        return array;
     316}
     317
    303318/*
    304319 * Return a string whose elements are the members of array A beginning at
    305320 * index START and spanning NELEM members.  Null elements are counted.
     
    311326arrayind_t      start, nelem;
    312327int     starsub, quoted;
    313328{
     329        ARRAY           *a2;
    314330        ARRAY_ELEMENT   *h, *p;
    315331        arrayind_t      i;
    316         char            *ifs, sep[2];
     332        char            *ifs, sep[2], *t;
    317333
    318334        p = a ? array_head (a) : 0;
    319335        if (p == 0 || array_empty (a) || start > array_max_index(a))
     
    336352        for (i = 0, h = p; p != a->head && i < nelem; i++, p = element_forw(p))
    337353                ;
    338354
     355        a2 = array_slice(a, h, p);
     356
     357        if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
     358                array_quote(a2);
     359        else
     360                array_quote_escapes(a2);
     361
    339362        if (starsub && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) {
    340363                ifs = getifs();
    341364                sep[0] = ifs ? *ifs : '\0';
     
    343366                sep[0] = ' ';
    344367        sep[1] = '\0';
    345368
    346         return (array_to_string_internal (h, p, sep, quoted));
     369        t = array_to_string (a2, sep, 0);
     370        array_dispose(a2);
     371
     372        return t;
    347373}
    348374
    349375char *
     
    367393        }
    368394
    369395        if (mflags & MATCH_QUOTED)
    370                 array_quote (a2);
     396                array_quote(a2);
     397        else
     398                array_quote_escapes(a2);
    371399        if (mflags & MATCH_STARSUB) {
    372400                ifs = getifs();
    373401                sifs[0] = ifs ? *ifs : '\0';
  • array.h

    diff -Naur bash-3.2.orig/array.h bash-3.2/array.h
    old new  
    5555extern ARRAY_ELEMENT *array_unshift_element __P((ARRAY *));
    5656extern int      array_shift_element __P((ARRAY *, char *));
    5757extern ARRAY    *array_quote __P((ARRAY *));
     58extern ARRAY    *array_quote_escapes __P((ARRAY *));
    5859
    5960extern char     *array_subrange __P((ARRAY *, arrayind_t, arrayind_t, int, int));
    6061extern char     *array_patsub __P((ARRAY *, char *, char *, int));
  • arrayfunc.c

    diff -Naur bash-3.2.orig/arrayfunc.c bash-3.2/arrayfunc.c
    old new  
    618618  if (expok == 0)
    619619    {
    620620      last_command_exit_value = EXECUTION_FAILURE;
     621
     622      top_level_cleanup ();     
    621623      jump_to_top_level (DISCARD);
    622624    }
    623625  return val;
     
    720722  if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
    721723    {
    722724      if (rtype)
    723         *rtype = 1;
     725        *rtype = (t[0] == '*') ? 1 : 2;
    724726      if (allow_all == 0)
    725727        {
    726728          err_badarraysub (s);
  • builtins/common.c

    diff -Naur bash-3.2.orig/builtins/common.c bash-3.2/builtins/common.c
    old new  
    1 /* Copyright (C) 1987-2005 Free Software Foundation, Inc.
     1/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
    22
    33   This file is part of GNU Bash, the Bourne Again SHell.
    44
     
    131131  if (list)
    132132    {
    133133      builtin_error (_("too many arguments"));
     134      top_level_cleanup ();
    134135      jump_to_top_level (DISCARD);
    135136    }
    136137}
     
    395396          if (fatal)
    396397            throw_to_top_level ();
    397398          else
    398             jump_to_top_level (DISCARD);
     399            {
     400              top_level_cleanup ();
     401              jump_to_top_level (DISCARD);
     402            }
    399403        }
    400404      no_args (list->next);
    401405    }
     
    475479
    476480  if (the_current_working_directory == 0)
    477481    {
     482#if defined (GETCWD_BROKEN)
     483      the_current_working_directory = getcwd (0, PATH_MAX);
     484#else
    478485      the_current_working_directory = getcwd (0, 0);
     486#endif
    479487      if (the_current_working_directory == 0)
    480488        {
    481489          fprintf (stderr, _("%s: error retrieving current directory: %s: %s\n"),
  • builtins/printf.def

    diff -Naur bash-3.2.orig/builtins/printf.def bash-3.2/builtins/printf.def
    old new  
    11This file is printf.def, from which is created printf.c.
    22It implements the builtin "printf" in Bash.
    33
    4 Copyright (C) 1997-2005 Free Software Foundation, Inc.
     4Copyright (C) 1997-2007 Free Software Foundation, Inc.
    55
    66This file is part of GNU Bash, the Bourne Again SHell.
    77
     
    4949#  define INT_MIN               (-2147483647-1)
    5050#endif
    5151
     52#if defined (PREFER_STDARG)
     53#  include <stdarg.h>
     54#else
     55#  include <varargs.h>
     56#endif
     57
    5258#include <stdio.h>
    5359#include <chartypes.h>
    5460
     
    6470#include "bashgetopt.h"
    6571#include "common.h"
    6672
     73#if defined (PRI_MACROS_BROKEN)
     74#  undef PRIdMAX
     75#endif
     76
    6777#if !defined (PRIdMAX)
    6878#  if HAVE_LONG_LONG
    6979#    define PRIdMAX     "lld"
     
    151161#define SKIP1 "#'-+ 0"
    152162#define LENMODS "hjlLtz"
    153163
     164#ifndef HAVE_ASPRINTF
     165extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
     166#endif
     167
    154168static void printf_erange __P((char *));
    155169static int printstr __P((char *, char *, int, int, int));
    156170static int tescape __P((char *, char *, int *));
  • builtins/read.def

    diff -Naur bash-3.2.orig/builtins/read.def bash-3.2/builtins/read.def
    old new  
    127127     WORD_LIST *list;
    128128{
    129129  register char *varname;
    130   int size, i, nr, pass_next, saw_escape, eof, opt, retval, code;
    131   int input_is_tty, input_is_pipe, unbuffered_read;
     130  int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2;
     131  int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul;
    132132  int raw, edit, nchars, silent, have_timeout, fd;
    133133  unsigned int tmout;
    134134  intmax_t intval;
    135135  char c;
    136136  char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname;
    137   char *e, *t, *t1;
     137  char *e, *t, *t1, *ps2;
    138138  struct stat tsb;
    139139  SHELL_VAR *var;
    140140#if defined (ARRAY_VARS)
     
    148148  USE_VAR(size);
    149149  USE_VAR(i);
    150150  USE_VAR(pass_next);
     151  USE_VAR(print_ps2);
    151152  USE_VAR(saw_escape);
    152153  USE_VAR(input_is_pipe);
    153154/*  USE_VAR(raw); */
     
    163164  USE_VAR(rlind);
    164165#endif
    165166  USE_VAR(list);
     167  USE_VAR(ps2);
    166168
    167169  i = 0;                /* Index into the string that we are reading. */
    168170  raw = edit = 0;       /* Not reading raw input by default. */
     
    386388  setmode (0, O_TEXT);
    387389#endif
    388390
    389   for (eof = retval = 0;;)
     391  ps2 = 0;
     392  for (print_ps2 = eof = retval = 0;;)
    390393    {
    391394#if defined (READLINE)
    392395      if (edit)
     
    412415        {
    413416#endif
    414417
     418      if (print_ps2)
     419        {
     420          if (ps2 == 0)
     421            ps2 = get_string_value ("PS2");
     422          fprintf (stderr, "%s", ps2 ? ps2 : "");
     423          fflush (stderr);
     424          print_ps2 = 0;
     425        }
     426
    415427      if (unbuffered_read)
    416428        retval = zread (fd, &c, 1);
    417429      else
     
    440452        {
    441453          pass_next = 0;
    442454          if (c == '\n')
    443             i--;                /* back up over the CTLESC */
     455            {
     456              i--;              /* back up over the CTLESC */
     457              if (interactive && input_is_tty && raw == 0)
     458                print_ps2 = 1;
     459            }
    444460          else
    445461            goto add_char;
    446462          continue;
  • config-bot.h

    diff -Naur bash-3.2.orig/config-bot.h bash-3.2/config-bot.h
    old new  
    11/* config-bot.h */
    22/* modify settings or make new ones based on what autoconf tells us. */
    33
    4 /* Copyright (C) 1989-2002 Free Software Foundation, Inc.
     4/* Copyright (C) 1989-2007 Free Software Foundation, Inc.
    55
    66   This file is part of GNU Bash, the Bourne Again SHell.
    77
     
    7070#  define TERMIOS_MISSING
    7171#endif
    7272
    73 /* If we have a getcwd(3), but it calls popen(), #undef HAVE_GETCWD so
    74    the replacement in getcwd.c will be built. */
    75 #if defined (HAVE_GETCWD) && defined (GETCWD_BROKEN)
     73/* If we have a getcwd(3), but one that does not dynamically allocate memory,
     74   #undef HAVE_GETCWD so the replacement in getcwd.c will be built.  We do
     75   not do this on Solaris, because their implementation of loopback mounts
     76   breaks the traditional file system assumptions that getcwd uses. */
     77#if defined (HAVE_GETCWD) && defined (GETCWD_BROKEN) && !defined (SOLARIS)
    7678#  undef HAVE_GETCWD
    7779#endif
    7880
  • config.h.in

    diff -Naur bash-3.2.orig/config.h.in bash-3.2/config.h.in
    old new  
    11/* config.h -- Configuration file for bash. */
    22
    3 /* Copyright (C) 1987-2006 Free Software Foundation, Inc.
     3/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
    44
    55   This file is part of GNU Bash, the Bourne Again SHell.
    66
     
    413413
    414414#undef HAVE_DECL_STRTOLD
    415415
     416#undef PRI_MACROS_BROKEN
     417
    416418#undef STRTOLD_BROKEN
    417419
    418420/* Define if WCONTINUED is defined in system headers, but rejected by waitpid */
     
    10061008/* Define if you have the `dcgettext' function. */
    10071009#undef HAVE_DCGETTEXT
    10081010
     1011/* Define if you have the `localeconv' function. */
     1012#undef HAVE_LOCALECONV
     1013
    10091014/* Define if your system has a working `malloc' function. */
    10101015/* #undef HAVE_MALLOC */
    10111016
  • configure

    diff -Naur bash-3.2.orig/configure bash-3.2/configure
    old new  
    48714871                # static version specified as -llibname to override the
    48724872                # dynamic version
    48734873                case "${host_os}" in
    4874                 darwin8*)       READLINE_LIB='${READLINE_LIBRARY}' ;;
     4874                darwin[89]*)    READLINE_LIB='${READLINE_LIBRARY}' ;;
    48754875                *)              READLINE_LIB=-lreadline ;;
    48764876                esac
    48774877        fi
     
    2731627316sco3.2v4*)      LOCAL_CFLAGS="-DMUST_UNBLOCK_CHLD -DPATH_MAX=1024" ;;
    2731727317sco3.2*)        LOCAL_CFLAGS=-DMUST_UNBLOCK_CHLD ;;
    2731827318sunos4*)        LOCAL_CFLAGS=-DSunOS4 ;;
    27319 solaris2.5*)    LOCAL_CFLAGS=-DSunOS5 ;;
     27319solaris2.5*)    LOCAL_CFLAGS="-DSunOS5 -DSOLARIS" ;;
     27320solaris2*)      LOCAL_CFLAGS=-DSOLARIS ;;
    2732027321lynxos*)        LOCAL_CFLAGS=-DRECYCLES_PIDS ;;
    2732127322linux*)         LOCAL_LDFLAGS=-rdynamic          # allow dynamic loading
    2732227323                case "`uname -r`" in
  • configure.in

    diff -Naur bash-3.2.orig/configure.in bash-3.2/configure.in
    old new  
    55dnl
    66dnl Process this file with autoconf to produce a configure script.
    77
    8 # Copyright (C) 1987-2006 Free Software Foundation, Inc.
     8# Copyright (C) 1987-2007 Free Software Foundation, Inc.
    99
    1010# This program is free software; you can redistribute it and/or modify
    1111# it under the terms of the GNU General Public License as published by
     
    518518                # static version specified as -llibname to override the
    519519                # dynamic version
    520520                case "${host_os}" in
    521                 darwin8*)       READLINE_LIB='${READLINE_LIBRARY}' ;;
     521                darwin[[89]]*)  READLINE_LIB='${READLINE_LIBRARY}' ;;
    522522                *)              READLINE_LIB=-lreadline ;;
    523523                esac
    524524        fi
     
    991991sco3.2v4*)      LOCAL_CFLAGS="-DMUST_UNBLOCK_CHLD -DPATH_MAX=1024" ;;
    992992sco3.2*)        LOCAL_CFLAGS=-DMUST_UNBLOCK_CHLD ;;
    993993sunos4*)        LOCAL_CFLAGS=-DSunOS4 ;;
    994 solaris2.5*)    LOCAL_CFLAGS=-DSunOS5 ;;
     994solaris2.5*)    LOCAL_CFLAGS="-DSunOS5 -DSOLARIS" ;;
     995solaris2*)      LOCAL_CFLAGS=-DSOLARIS ;;
    995996lynxos*)        LOCAL_CFLAGS=-DRECYCLES_PIDS ;;
    996997linux*)         LOCAL_LDFLAGS=-rdynamic          # allow dynamic loading
    997998                case "`uname -r`" in
  • execute_cmd.c

    diff -Naur bash-3.2.orig/execute_cmd.c bash-3.2/execute_cmd.c
    old new  
    11/* execute_cmd.c -- Execute a COMMAND structure. */
    22
    3 /* Copyright (C) 1987-2005 Free Software Foundation, Inc.
     3/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
    44
    55   This file is part of GNU Bash, the Bourne Again SHell.
    66
     
    614614      cleanup_redirects (redirection_undo_list);
    615615      redirection_undo_list = (REDIRECT *)NULL;
    616616      dispose_exec_redirects ();
    617       return (EXECUTION_FAILURE);
     617      return (last_command_exit_value = EXECUTION_FAILURE);
    618618    }
    619619
    620620  if (redirection_undo_list)
     
    25462546      arg1 = cond_expand_word (cond->left->op, 0);
    25472547      if (arg1 == 0)
    25482548        arg1 = nullstr;
    2549       arg2 = cond_expand_word (cond->right->op, patmatch||rmatch);
     2549      arg2 = cond_expand_word (cond->right->op, rmatch ? 2 : (patmatch ? 1 : 0));
    25502550      if (arg2 == 0)
    25512551        arg2 = nullstr;
    25522552
     
    30503050  if (command_line == 0)
    30513051    command_line = savestring (the_printed_command_except_trap);
    30523052
     3053#if defined (PROCESS_SUBSTITUTION)
     3054  if ((subshell_environment & SUBSHELL_COMSUB) && (simple_command->flags & CMD_NO_FORK) && fifos_pending() > 0)
     3055    simple_command->flags &= ~CMD_NO_FORK;
     3056#endif
     3057
    30533058  execute_disk_command (words, simple_command->redirects, command_line,
    30543059                        pipe_in, pipe_out, async, fds_to_close,
    30553060                        simple_command->flags);
  • bash-3.2

    diff -Naur bash-3.2.orig/expr.c bash-3.2/expr.c
    old new  
    286286      free (expr_stack[expr_depth]);
    287287    }
    288288  free (expr_stack[expr_depth]);        /* free the allocated EXPR_CONTEXT */
     289
     290  noeval = 0;   /* XXX */
    289291}
    290292
    291293static void
     
    319321  procenv_t oevalbuf;
    320322
    321323  val = 0;
     324  noeval = 0;
    322325
    323326  FASTCOPY (evalbuf, oevalbuf, sizeof (evalbuf));
    324327
     
    929932      if (interactive_shell)
    930933        {
    931934          expr_unwind ();
     935          top_level_cleanup ();
    932936          jump_to_top_level (DISCARD);
    933937        }
    934938      else
  • findcmd.c

    diff -Naur bash-3.2.orig/findcmd.c bash-3.2/findcmd.c
    old new  
    308308  if (hashed_file && (posixly_correct || check_hashed_filenames))
    309309    {
    310310      st = file_status (hashed_file);
    311       if ((st ^ (FS_EXISTS | FS_EXECABLE)) != 0)
     311      if ((st & (FS_EXISTS|FS_EXECABLE)) != (FS_EXISTS|FS_EXECABLE))
    312312        {
    313313          phash_remove (pathname);
    314314          free (hashed_file);
  • bash-3.2

    diff -Naur bash-3.2.orig/jobs.c bash-3.2/jobs.c
    old new  
    783783  if (jobs[js.j_firstj] == 0)
    784784    {
    785785      old = js.j_firstj++;
     786      if (old >= js.j_jobslots)
     787        old = js.j_jobslots - 1;
    786788      while (js.j_firstj != old)
    787789        {
    788790          if (js.j_firstj >= js.j_jobslots)
    789791            js.j_firstj = 0;
    790           if (jobs[js.j_firstj])
     792          if (jobs[js.j_firstj] || js.j_firstj == old)  /* needed if old == 0 */
    791793            break;
    792794          js.j_firstj++;
    793795        }
     
    797799  if (jobs[js.j_lastj] == 0)
    798800    {
    799801      old = js.j_lastj--;
     802      if (old < 0)
     803        old = 0;
    800804      while (js.j_lastj != old)
    801805        {
    802806          if (js.j_lastj < 0)
    803807            js.j_lastj = js.j_jobslots - 1;
    804           if (jobs[js.j_lastj])
     808          if (jobs[js.j_lastj] || js.j_lastj == old)    /* needed if old == js.j_jobslots */
    805809            break;
    806810          js.j_lastj--;
    807811        }
     
    963967  reap_dead_jobs ();
    964968  realloc_jobs_list ();
    965969
    966   return (js.j_lastj);
     970#ifdef DEBUG
     971  itrace("compact_jobs_list: returning %d", (js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0);
     972#endif
     973
     974  return ((js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0);
    967975}
    968976
    969977/* Delete the job at INDEX from the job list.  Must be called
     
    984992  temp = jobs[job_index];
    985993  if (temp == 0)
    986994    return;
    987   if (job_index == js.j_current || job_index == js.j_previous)
    988     reset_current ();
    989995
    990996  if ((dflags & DEL_NOBGPID) == 0)
    991997    {
     
    10281034    js.j_firstj = js.j_lastj = 0;
    10291035  else if (jobs[js.j_firstj] == 0 || jobs[js.j_lastj] == 0)
    10301036    reset_job_indices ();
     1037
     1038  if (job_index == js.j_current || job_index == js.j_previous)
     1039    reset_current ();
    10311040}
    10321041
    10331042/* Must be called with SIGCHLD blocked. */
  • lib/readline/complete.c

    diff -Naur bash-3.2.orig/lib/readline/complete.c bash-3.2/lib/readline/complete.c
    old new  
    428428        return (1);
    429429      if (c == 'n' || c == 'N' || c == RUBOUT)
    430430        return (0);
    431       if (c == ABORT_CHAR)
     431      if (c == ABORT_CHAR || c < 0)
    432432        _rl_abort_internal ();
    433433      if (for_pager && (c == NEWLINE || c == RETURN))
    434434        return (2);
  • lib/readline/display.c

    diff -Naur bash-3.2.orig/lib/readline/display.c bash-3.2/lib/readline/display.c
    old new  
    391391      t = ++p;
    392392      local_prompt = expand_prompt (p, &prompt_visible_length,
    393393                                       &prompt_last_invisible,
    394                                        (int *)NULL,
     394                                       &prompt_invis_chars_first_line,
    395395                                       &prompt_physical_chars);
    396396      c = *t; *t = '\0';
    397397      /* The portion of the prompt string up to and including the
    398398         final newline is now null-terminated. */
    399399      local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
    400400                                                   (int *)NULL,
    401                                                    &prompt_invis_chars_first_line,
     401                                                   (int *)NULL,
    402402                                                   (int *)NULL);
    403403      *t = c;
    404404      local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
     
    561561      wrap_offset = prompt_invis_chars_first_line = 0;
    562562    }
    563563
     564#if defined (HANDLE_MULTIBYTE)
     565#define CHECK_INV_LBREAKS() \
     566      do { \
     567        if (newlines >= (inv_lbsize - 2)) \
     568          { \
     569            inv_lbsize *= 2; \
     570            inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
     571            _rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \
     572          } \
     573      } while (0)
     574#else
    564575#define CHECK_INV_LBREAKS() \
    565576      do { \
    566577        if (newlines >= (inv_lbsize - 2)) \
     
    569580            inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
    570581          } \
    571582      } while (0)
     583#endif /* HANDLE_MULTIBYTE */
    572584
    573585#if defined (HANDLE_MULTIBYTE)   
    574586#define CHECK_LPOS() \
     
    10361048                tx = _rl_col_width (&visible_line[pos], 0, nleft) - visible_wrap_offset;
    10371049              else
    10381050                tx = nleft;
    1039               if (_rl_last_c_pos > tx)
     1051              if (tx >= 0 && _rl_last_c_pos > tx)
    10401052                {
    10411053                  _rl_backspace (_rl_last_c_pos - tx);  /* XXX */
    10421054                  _rl_last_c_pos = tx;
     
    11921204     int current_line, omax, nmax, inv_botlin;
    11931205{
    11941206  register char *ofd, *ols, *oe, *nfd, *nls, *ne;
    1195   int temp, lendiff, wsatend, od, nd;
     1207  int temp, lendiff, wsatend, od, nd, o_cpos;
    11961208  int current_invis_chars;
    11971209  int col_lendiff, col_temp;
    11981210#if defined (HANDLE_MULTIBYTE)
     
    14531465        _rl_last_c_pos = lendiff;
    14541466    }
    14551467
     1468  o_cpos = _rl_last_c_pos;
     1469
    14561470  /* When this function returns, _rl_last_c_pos is correct, and an absolute
    14571471     cursor postion in multibyte mode, but a buffer index when not in a
    14581472     multibyte locale. */
     
    14621476  /* We need to indicate that the cursor position is correct in the presence of
    14631477     invisible characters in the prompt string.  Let's see if setting this when
    14641478     we make sure we're at the end of the drawn prompt string works. */
    1465   if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 && _rl_last_c_pos == prompt_physical_chars)
     1479  if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 &&
     1480      (_rl_last_c_pos > 0 || o_cpos > 0) &&
     1481      _rl_last_c_pos == prompt_physical_chars)
    14661482    cpos_adjusted = 1;
    14671483#endif
    14681484#endif
     
    15061522    {
    15071523      /* Non-zero if we're increasing the number of lines. */
    15081524      int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
     1525      /* If col_lendiff is > 0, implying that the new string takes up more
     1526         screen real estate than the old, but lendiff is < 0, meaning that it
     1527         takes fewer bytes, we need to just output the characters starting
     1528         from the first difference.  These will overwrite what is on the
     1529         display, so there's no reason to do a smart update.  This can really
     1530         only happen in a multibyte environment. */
     1531      if (lendiff < 0)
     1532        {
     1533          _rl_output_some_chars (nfd, temp);
     1534          _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
     1535          /* If nfd begins before any invisible characters in the prompt,
     1536             adjust _rl_last_c_pos to account for wrap_offset and set
     1537             cpos_adjusted to let the caller know. */
     1538          if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
     1539            {
     1540              _rl_last_c_pos -= wrap_offset;
     1541              cpos_adjusted = 1;
     1542            }
     1543          return;
     1544        }
    15091545      /* Sometimes it is cheaper to print the characters rather than
    15101546         use the terminal's capabilities.  If we're growing the number
    15111547         of lines, make sure we actually cause the new line to wrap
    15121548         around on auto-wrapping terminals. */
    1513       if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
     1549      else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
    15141550        {
    15151551          /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
    15161552             _rl_horizontal_scroll_mode == 1, inserting the characters with
     
    15331569            }
    15341570          else
    15351571            {
    1536               /* We have horizontal scrolling and we are not inserting at
    1537                  the end.  We have invisible characters in this line.  This
    1538                  is a dumb update. */
    15391572              _rl_output_some_chars (nfd, temp);
    15401573              _rl_last_c_pos += col_temp;
     1574              /* If nfd begins before any invisible characters in the prompt,
     1575                 adjust _rl_last_c_pos to account for wrap_offset and set
     1576                 cpos_adjusted to let the caller know. */
     1577              if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
     1578                {
     1579                  _rl_last_c_pos -= wrap_offset;
     1580                  cpos_adjusted = 1;
     1581                }
    15411582              return;
    15421583            }
    15431584          /* Copy (new) chars to screen from first diff to last match. */
     
    15861627          temp = nls - nfd;
    15871628          if (temp > 0)
    15881629            {
     1630              /* If nfd begins at the prompt, or before the invisible
     1631                 characters in the prompt, we need to adjust _rl_last_c_pos
     1632                 in a multibyte locale to account for the wrap offset and
     1633                 set cpos_adjusted accordingly. */
    15891634              _rl_output_some_chars (nfd, temp);
    1590               _rl_last_c_pos += _rl_col_width (nfd, 0, temp);;
     1635              if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1636                {
     1637                  _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
     1638                  if (current_line == 0 && wrap_offset &&  ((nfd - new) <= prompt_last_invisible))
     1639                    {
     1640                      _rl_last_c_pos -= wrap_offset;
     1641                      cpos_adjusted = 1;
     1642                    }
     1643                }
     1644              else
     1645                _rl_last_c_pos += temp;
    15911646            }
    15921647        }
    15931648      /* Otherwise, print over the existing material. */
     
    15951650        {
    15961651          if (temp > 0)
    15971652            {
     1653              /* If nfd begins at the prompt, or before the invisible
     1654                 characters in the prompt, we need to adjust _rl_last_c_pos
     1655                 in a multibyte locale to account for the wrap offset and
     1656                 set cpos_adjusted accordingly. */
    15981657              _rl_output_some_chars (nfd, temp);
    15991658              _rl_last_c_pos += col_temp;               /* XXX */
     1659              if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1660                {
     1661                  if (current_line == 0 && wrap_offset &&  ((nfd - new) <= prompt_last_invisible))
     1662                    {
     1663                      _rl_last_c_pos -= wrap_offset;
     1664                      cpos_adjusted = 1;
     1665                    }
     1666                }
    16001667            }
    16011668          lendiff = (oe - old) - (ne - new);
    16021669          if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     
    17321799  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
    17331800    {
    17341801      dpos = _rl_col_width (data, 0, new);
    1735       if (dpos > prompt_last_invisible)         /* XXX - don't use woff here */
     1802      /* Use NEW when comparing against the last invisible character in the
     1803         prompt string, since they're both buffer indices and DPOS is a
     1804         desired display position. */
     1805      if (new > prompt_last_invisible)          /* XXX - don't use woff here */
    17361806        {
    17371807          dpos -= woff;
    17381808          /* Since this will be assigned to _rl_last_c_pos at the end (more
     
    23802450
    23812451  if (end <= start)
    23822452    return 0;
     2453  if (MB_CUR_MAX == 1 || rl_byte_oriented)
     2454    return (end - start);
    23832455
    23842456  memset (&ps, 0, sizeof (mbstate_t));
    23852457
  • lib/readline/display.c.orig

    diff -Naur bash-3.2.orig/lib/readline/display.c.orig bash-3.2/lib/readline/display.c.orig
    old new  
     1/* display.c -- readline redisplay facility. */
     2
     3/* Copyright (C) 1987-2006 Free Software Foundation, Inc.
     4
     5   This file is part of the GNU Readline Library, a library for
     6   reading lines of text with interactive input and history editing.
     7
     8   The GNU Readline Library is free software; you can redistribute it
     9   and/or modify it under the terms of the GNU General Public License
     10   as published by the Free Software Foundation; either version 2, or
     11   (at your option) any later version.
     12
     13   The GNU Readline Library is distributed in the hope that it will be
     14   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
     15   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16   GNU General Public License for more details.
     17
     18   The GNU General Public License is often shipped with GNU software, and
     19   is generally kept in a file called COPYING or LICENSE.  If you do not
     20   have a copy of the license, write to the Free Software Foundation,
     21   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
     22#define READLINE_LIBRARY
     23
     24#if defined (HAVE_CONFIG_H)
     25#  include <config.h>
     26#endif
     27
     28#include <sys/types.h>
     29
     30#if defined (HAVE_UNISTD_H)
     31#  include <unistd.h>
     32#endif /* HAVE_UNISTD_H */
     33
     34#include "posixstat.h"
     35
     36#if defined (HAVE_STDLIB_H)
     37#  include <stdlib.h>
     38#else
     39#  include "ansi_stdlib.h"
     40#endif /* HAVE_STDLIB_H */
     41
     42#include <stdio.h>
     43
     44/* System-specific feature definitions and include files. */
     45#include "rldefs.h"
     46#include "rlmbutil.h"
     47
     48/* Termcap library stuff. */
     49#include "tcap.h"
     50
     51/* Some standard library routines. */
     52#include "readline.h"
     53#include "history.h"
     54
     55#include "rlprivate.h"
     56#include "xmalloc.h"
     57
     58#if !defined (strchr) && !defined (__STDC__)
     59extern char *strchr (), *strrchr ();
     60#endif /* !strchr && !__STDC__ */
     61
     62static void update_line PARAMS((char *, char *, int, int, int, int));
     63static void space_to_eol PARAMS((int));
     64static void delete_chars PARAMS((int));
     65static void insert_some_chars PARAMS((char *, int, int));
     66static void cr PARAMS((void));
     67
     68#if defined (HANDLE_MULTIBYTE)
     69static int _rl_col_width PARAMS((const char *, int, int));
     70static int *_rl_wrapped_line;
     71#else
     72#  define _rl_col_width(l, s, e)        (((e) <= (s)) ? 0 : (e) - (s))
     73#endif
     74
     75static int *inv_lbreaks, *vis_lbreaks;
     76static int inv_lbsize, vis_lbsize;
     77
     78/* Heuristic used to decide whether it is faster to move from CUR to NEW
     79   by backing up or outputting a carriage return and moving forward.  CUR
     80   and NEW are either both buffer positions or absolute screen positions. */
     81#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
     82
     83/* _rl_last_c_pos is an absolute cursor position in multibyte locales and a
     84   buffer index in others.  This macro is used when deciding whether the
     85   current cursor position is in the middle of a prompt string containing
     86   invisible characters. */
     87#define PROMPT_ENDING_INDEX \
     88  ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1)
     89 
     90
     91/* **************************************************************** */
     92/*                                                                  */
     93/*                      Display stuff                               */
     94/*                                                                  */
     95/* **************************************************************** */
     96
     97/* This is the stuff that is hard for me.  I never seem to write good
     98   display routines in C.  Let's see how I do this time. */
     99
     100/* (PWP) Well... Good for a simple line updater, but totally ignores
     101   the problems of input lines longer than the screen width.
     102
     103   update_line and the code that calls it makes a multiple line,
     104   automatically wrapping line update.  Careful attention needs
     105   to be paid to the vertical position variables. */
     106
     107/* Keep two buffers; one which reflects the current contents of the
     108   screen, and the other to draw what we think the new contents should
     109   be.  Then compare the buffers, and make whatever changes to the
     110   screen itself that we should.  Finally, make the buffer that we
     111   just drew into be the one which reflects the current contents of the
     112   screen, and place the cursor where it belongs.
     113
     114   Commands that want to can fix the display themselves, and then let
     115   this function know that the display has been fixed by setting the
     116   RL_DISPLAY_FIXED variable.  This is good for efficiency. */
     117
     118/* Application-specific redisplay function. */
     119rl_voidfunc_t *rl_redisplay_function = rl_redisplay;
     120
     121/* Global variables declared here. */
     122/* What YOU turn on when you have handled all redisplay yourself. */
     123int rl_display_fixed = 0;
     124
     125int _rl_suppress_redisplay = 0;
     126int _rl_want_redisplay = 0;
     127
     128/* The stuff that gets printed out before the actual text of the line.
     129   This is usually pointing to rl_prompt. */
     130char *rl_display_prompt = (char *)NULL;
     131
     132/* Pseudo-global variables declared here. */
     133
     134/* The visible cursor position.  If you print some text, adjust this. */
     135/* NOTE: _rl_last_c_pos is used as a buffer index when not in a locale
     136   supporting multibyte characters, and an absolute cursor position when
     137   in such a locale.  This is an artifact of the donated multibyte support.
     138   Care must be taken when modifying its value. */
     139int _rl_last_c_pos = 0;
     140int _rl_last_v_pos = 0;
     141
     142static int cpos_adjusted;
     143static int cpos_buffer_position;
     144
     145/* Number of lines currently on screen minus 1. */
     146int _rl_vis_botlin = 0;
     147
     148/* Variables used only in this file. */
     149/* The last left edge of text that was displayed.  This is used when
     150   doing horizontal scrolling.  It shifts in thirds of a screenwidth. */
     151static int last_lmargin;
     152
     153/* The line display buffers.  One is the line currently displayed on
     154   the screen.  The other is the line about to be displayed. */
     155static char *visible_line = (char *)NULL;
     156static char *invisible_line = (char *)NULL;
     157
     158/* A buffer for `modeline' messages. */
     159static char msg_buf[128];
     160
     161/* Non-zero forces the redisplay even if we thought it was unnecessary. */
     162static int forced_display;
     163
     164/* Default and initial buffer size.  Can grow. */
     165static int line_size = 1024;
     166
     167/* Variables to keep track of the expanded prompt string, which may
     168   include invisible characters. */
     169
     170static char *local_prompt, *local_prompt_prefix;
     171static int local_prompt_len;
     172static int prompt_visible_length, prompt_prefix_length;
     173
     174/* The number of invisible characters in the line currently being
     175   displayed on the screen. */
     176static int visible_wrap_offset;
     177
     178/* The number of invisible characters in the prompt string.  Static so it
     179   can be shared between rl_redisplay and update_line */
     180static int wrap_offset;
     181
     182/* The index of the last invisible character in the prompt string. */
     183static int prompt_last_invisible;
     184
     185/* The length (buffer offset) of the first line of the last (possibly
     186   multi-line) buffer displayed on the screen. */
     187static int visible_first_line_len;
     188
     189/* Number of invisible characters on the first physical line of the prompt.
     190   Only valid when the number of physical characters in the prompt exceeds
     191   (or is equal to) _rl_screenwidth. */
     192static int prompt_invis_chars_first_line;
     193
     194static int prompt_last_screen_line;
     195
     196static int prompt_physical_chars;
     197
     198/* Variables to save and restore prompt and display information. */
     199
     200/* These are getting numerous enough that it's time to create a struct. */
     201
     202static char *saved_local_prompt;
     203static char *saved_local_prefix;
     204static int saved_last_invisible;
     205static int saved_visible_length;
     206static int saved_prefix_length;
     207static int saved_local_length;
     208static int saved_invis_chars_first_line;
     209static int saved_physical_chars;
     210
     211/* Expand the prompt string S and return the number of visible
     212   characters in *LP, if LP is not null.  This is currently more-or-less
     213   a placeholder for expansion.  LIP, if non-null is a place to store the
     214   index of the last invisible character in the returned string. NIFLP,
     215   if non-zero, is a place to store the number of invisible characters in
     216   the first prompt line.  The previous are used as byte counts -- indexes
     217   into a character buffer. */
     218
     219/* Current implementation:
     220        \001 (^A) start non-visible characters
     221        \002 (^B) end non-visible characters
     222   all characters except \001 and \002 (following a \001) are copied to
     223   the returned string; all characters except those between \001 and
     224   \002 are assumed to be `visible'. */
     225
     226static char *
     227expand_prompt (pmt, lp, lip, niflp, vlp)
     228     char *pmt;
     229     int *lp, *lip, *niflp, *vlp;
     230{
     231  char *r, *ret, *p, *igstart;
     232  int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
     233
     234  /* Short-circuit if we can. */
     235  if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
     236    {
     237      r = savestring (pmt);
     238      if (lp)
     239        *lp = strlen (r);
     240      if (lip)
     241        *lip = 0;
     242      if (niflp)
     243        *niflp = 0;
     244      if (vlp)
     245        *vlp = lp ? *lp : strlen (r);
     246      return r;
     247    }
     248
     249  l = strlen (pmt);
     250  r = ret = (char *)xmalloc (l + 1);
     251
     252  invfl = 0;    /* invisible chars in first line of prompt */
     253  invflset = 0; /* we only want to set invfl once */
     254
     255  igstart = 0;
     256  for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++)
     257    {
     258      /* This code strips the invisible character string markers
     259         RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
     260      if (ignoring == 0 && *p == RL_PROMPT_START_IGNORE)                /* XXX - check ignoring? */
     261        {
     262          ignoring = 1;
     263          igstart = p;
     264          continue;
     265        }
     266      else if (ignoring && *p == RL_PROMPT_END_IGNORE)
     267        {
     268          ignoring = 0;
     269          if (p != (igstart + 1))
     270            last = r - ret - 1;
     271          continue;
     272        }
     273      else
     274        {
     275#if defined (HANDLE_MULTIBYTE)
     276          if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     277            {
     278              pind = p - pmt;
     279              ind = _rl_find_next_mbchar (pmt, pind, 1, MB_FIND_NONZERO);
     280              l = ind - pind;
     281              while (l--)
     282                *r++ = *p++;
     283              if (!ignoring)
     284                {
     285                  rl += ind - pind;
     286                  physchars += _rl_col_width (pmt, pind, ind);
     287                }
     288              else
     289                ninvis += ind - pind;
     290              p--;                      /* compensate for later increment */
     291            }
     292          else
     293#endif
     294            {
     295              *r++ = *p;
     296              if (!ignoring)
     297                {
     298                  rl++;                 /* visible length byte counter */
     299                  physchars++;
     300                }
     301              else
     302                ninvis++;               /* invisible chars byte counter */
     303            }
     304
     305          if (invflset == 0 && rl >= _rl_screenwidth)
     306            {
     307              invfl = ninvis;
     308              invflset = 1;
     309            }
     310        }
     311    }
     312
     313  if (rl < _rl_screenwidth)
     314    invfl = ninvis;
     315
     316  *r = '\0';
     317  if (lp)
     318    *lp = rl;
     319  if (lip)
     320    *lip = last;
     321  if (niflp)
     322    *niflp = invfl;
     323  if  (vlp)
     324    *vlp = physchars;
     325  return ret;
     326}
     327
     328/* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from
     329   PMT and return the rest of PMT. */
     330char *
     331_rl_strip_prompt (pmt)
     332     char *pmt;
     333{
     334  char *ret;
     335
     336  ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL);
     337  return ret;
     338}
     339
     340/*
     341 * Expand the prompt string into the various display components, if
     342 * necessary.
     343 *
     344 * local_prompt = expanded last line of string in rl_display_prompt
     345 *                (portion after the final newline)
     346 * local_prompt_prefix = portion before last newline of rl_display_prompt,
     347 *                       expanded via expand_prompt
     348 * prompt_visible_length = number of visible characters in local_prompt
     349 * prompt_prefix_length = number of visible characters in local_prompt_prefix
     350 *
     351 * This function is called once per call to readline().  It may also be
     352 * called arbitrarily to expand the primary prompt.
     353 *
     354 * The return value is the number of visible characters on the last line
     355 * of the (possibly multi-line) prompt.
     356 */
     357int
     358rl_expand_prompt (prompt)
     359     char *prompt;
     360{
     361  char *p, *t;
     362  int c;
     363
     364  /* Clear out any saved values. */
     365  FREE (local_prompt);
     366  FREE (local_prompt_prefix);
     367
     368  local_prompt = local_prompt_prefix = (char *)0;
     369  local_prompt_len = 0;
     370  prompt_last_invisible = prompt_invis_chars_first_line = 0;
     371  prompt_visible_length = prompt_physical_chars = 0;
     372
     373  if (prompt == 0 || *prompt == 0)
     374    return (0);
     375
     376  p = strrchr (prompt, '\n');
     377  if (!p)
     378    {
     379      /* The prompt is only one logical line, though it might wrap. */
     380      local_prompt = expand_prompt (prompt, &prompt_visible_length,
     381                                            &prompt_last_invisible,
     382                                            &prompt_invis_chars_first_line,
     383                                            &prompt_physical_chars);
     384      local_prompt_prefix = (char *)0;
     385      local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
     386      return (prompt_visible_length);
     387    }
     388  else
     389    {
     390      /* The prompt spans multiple lines. */
     391      t = ++p;
     392      local_prompt = expand_prompt (p, &prompt_visible_length,
     393                                       &prompt_last_invisible,
     394                                       &prompt_invis_chars_first_line,
     395                                       &prompt_physical_chars);
     396      c = *t; *t = '\0';
     397      /* The portion of the prompt string up to and including the
     398         final newline is now null-terminated. */
     399      local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
     400                                                   (int *)NULL,
     401                                                   (int *)NULL,
     402                                                   (int *)NULL);
     403      *t = c;
     404      local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
     405      return (prompt_prefix_length);
     406    }
     407}
     408
     409/* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated
     410   arrays of line break markers.  MINSIZE is the minimum size of VISIBLE_LINE
     411   and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is
     412   increased.  If the lines have already been allocated, this ensures that
     413   they can hold at least MINSIZE characters. */
     414static void
     415init_line_structures (minsize)
     416      int minsize;
     417{
     418  register int n;
     419
     420  if (invisible_line == 0)      /* initialize it */
     421    {
     422      if (line_size < minsize)
     423        line_size = minsize;
     424      visible_line = (char *)xmalloc (line_size);
     425      invisible_line = (char *)xmalloc (line_size);
     426    }
     427  else if (line_size < minsize) /* ensure it can hold MINSIZE chars */
     428    {
     429      line_size *= 2;
     430      if (line_size < minsize)
     431        line_size = minsize;
     432      visible_line = (char *)xrealloc (visible_line, line_size);
     433      invisible_line = (char *)xrealloc (invisible_line, line_size);
     434    }
     435
     436  for (n = minsize; n < line_size; n++)
     437    {
     438      visible_line[n] = 0;
     439      invisible_line[n] = 1;
     440    }
     441
     442  if (vis_lbreaks == 0)
     443    {
     444      /* should be enough. */
     445      inv_lbsize = vis_lbsize = 256;
     446      inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int));
     447      vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int));
     448#if defined (HANDLE_MULTIBYTE)
     449      _rl_wrapped_line = (int *)xmalloc (vis_lbsize * sizeof (int));
     450#endif
     451      inv_lbreaks[0] = vis_lbreaks[0] = 0;
     452    }
     453}
     454 
     455/* Basic redisplay algorithm. */
     456void
     457rl_redisplay ()
     458{
     459  register int in, out, c, linenum, cursor_linenum;
     460  register char *line;
     461  int inv_botlin, lb_botlin, lb_linenum, o_cpos;
     462  int newlines, lpos, temp, modmark, n0, num;
     463  char *prompt_this_line;
     464#if defined (HANDLE_MULTIBYTE)
     465  wchar_t wc;
     466  size_t wc_bytes;
     467  int wc_width;
     468  mbstate_t ps;
     469  int _rl_wrapped_multicolumn = 0;
     470#endif
     471
     472  if (!readline_echoing_p)
     473    return;
     474
     475  if (!rl_display_prompt)
     476    rl_display_prompt = "";
     477
     478  if (invisible_line == 0 || vis_lbreaks == 0)
     479    {
     480      init_line_structures (0);
     481      rl_on_new_line ();
     482    }
     483
     484  /* Draw the line into the buffer. */
     485  cpos_buffer_position = -1;
     486
     487  line = invisible_line;
     488  out = inv_botlin = 0;
     489
     490  /* Mark the line as modified or not.  We only do this for history
     491     lines. */
     492  modmark = 0;
     493  if (_rl_mark_modified_lines && current_history () && rl_undo_list)
     494    {
     495      line[out++] = '*';
     496      line[out] = '\0';
     497      modmark = 1;
     498    }
     499
     500  /* If someone thought that the redisplay was handled, but the currently
     501     visible line has a different modification state than the one about
     502     to become visible, then correct the caller's misconception. */
     503  if (visible_line[0] != invisible_line[0])
     504    rl_display_fixed = 0;
     505
     506  /* If the prompt to be displayed is the `primary' readline prompt (the
     507     one passed to readline()), use the values we have already expanded.
     508     If not, use what's already in rl_display_prompt.  WRAP_OFFSET is the
     509     number of non-visible characters in the prompt string. */
     510  if (rl_display_prompt == rl_prompt || local_prompt)
     511    {
     512      if (local_prompt_prefix && forced_display)
     513        _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
     514
     515      if (local_prompt_len > 0)
     516        {
     517          temp = local_prompt_len + out + 2;
     518          if (temp >= line_size)
     519            {
     520              line_size = (temp + 1024) - (temp % 1024);
     521              visible_line = (char *)xrealloc (visible_line, line_size);
     522              line = invisible_line = (char *)xrealloc (invisible_line, line_size);
     523            }
     524          strncpy (line + out, local_prompt, local_prompt_len);
     525          out += local_prompt_len;
     526        }
     527      line[out] = '\0';
     528      wrap_offset = local_prompt_len - prompt_visible_length;
     529    }
     530  else
     531    {
     532      int pmtlen;
     533      prompt_this_line = strrchr (rl_display_prompt, '\n');
     534      if (!prompt_this_line)
     535        prompt_this_line = rl_display_prompt;
     536      else
     537        {
     538          prompt_this_line++;
     539          pmtlen = prompt_this_line - rl_display_prompt;        /* temp var */
     540          if (forced_display)
     541            {
     542              _rl_output_some_chars (rl_display_prompt, pmtlen);
     543              /* Make sure we are at column zero even after a newline,
     544                 regardless of the state of terminal output processing. */
     545              if (pmtlen < 2 || prompt_this_line[-2] != '\r')
     546                cr ();
     547            }
     548        }
     549
     550      prompt_physical_chars = pmtlen = strlen (prompt_this_line);
     551      temp = pmtlen + out + 2;
     552      if (temp >= line_size)
     553        {
     554          line_size = (temp + 1024) - (temp % 1024);
     555          visible_line = (char *)xrealloc (visible_line, line_size);
     556          line = invisible_line = (char *)xrealloc (invisible_line, line_size);
     557        }
     558      strncpy (line + out,  prompt_this_line, pmtlen);
     559      out += pmtlen;
     560      line[out] = '\0';
     561      wrap_offset = prompt_invis_chars_first_line = 0;
     562    }
     563
     564#if defined (HANDLE_MULTIBYTE)
     565#define CHECK_INV_LBREAKS() \
     566      do { \
     567        if (newlines >= (inv_lbsize - 2)) \
     568          { \
     569            inv_lbsize *= 2; \
     570            inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
     571            _rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \
     572          } \
     573      } while (0)
     574#else
     575#define CHECK_INV_LBREAKS() \
     576      do { \
     577        if (newlines >= (inv_lbsize - 2)) \
     578          { \
     579            inv_lbsize *= 2; \
     580            inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
     581          } \
     582      } while (0)
     583#endif /* HANDLE_MULTIBYTE */
     584
     585#if defined (HANDLE_MULTIBYTE)   
     586#define CHECK_LPOS() \
     587      do { \
     588        lpos++; \
     589        if (lpos >= _rl_screenwidth) \
     590          { \
     591            if (newlines >= (inv_lbsize - 2)) \
     592              { \
     593                inv_lbsize *= 2; \
     594                inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
     595                _rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \
     596              } \
     597            inv_lbreaks[++newlines] = out; \
     598            _rl_wrapped_line[newlines] = _rl_wrapped_multicolumn; \
     599            lpos = 0; \
     600          } \
     601      } while (0)
     602#else
     603#define CHECK_LPOS() \
     604      do { \
     605        lpos++; \
     606        if (lpos >= _rl_screenwidth) \
     607          { \
     608            if (newlines >= (inv_lbsize - 2)) \
     609              { \
     610                inv_lbsize *= 2; \
     611                inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
     612              } \
     613            inv_lbreaks[++newlines] = out; \
     614            lpos = 0; \
     615          } \
     616      } while (0)
     617#endif
     618
     619  /* inv_lbreaks[i] is where line i starts in the buffer. */
     620  inv_lbreaks[newlines = 0] = 0;
     621#if 0
     622  lpos = out - wrap_offset;
     623#else
     624  lpos = prompt_physical_chars + modmark;
     625#endif
     626
     627#if defined (HANDLE_MULTIBYTE)
     628  memset (_rl_wrapped_line, 0, vis_lbsize);
     629  num = 0;
     630#endif
     631
     632  /* prompt_invis_chars_first_line is the number of invisible characters in
     633     the first physical line of the prompt.
     634     wrap_offset - prompt_invis_chars_first_line is the number of invis
     635     chars on the second line. */
     636
     637  /* what if lpos is already >= _rl_screenwidth before we start drawing the
     638     contents of the command line? */
     639  while (lpos >= _rl_screenwidth)
     640    {
     641      int z;
     642      /* fix from Darin Johnson <darin@acuson.com> for prompt string with
     643         invisible characters that is longer than the screen width.  The
     644         prompt_invis_chars_first_line variable could be made into an array
     645         saying how many invisible characters there are per line, but that's
     646         probably too much work for the benefit gained.  How many people have
     647         prompts that exceed two physical lines?
     648         Additional logic fix from Edward Catmur <ed@catmur.co.uk> */
     649#if defined (HANDLE_MULTIBYTE)
     650      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     651        {
     652          n0 = num;
     653          temp = local_prompt_len;
     654          while (num < temp)
     655            {
     656              z = _rl_col_width  (local_prompt, n0, num);
     657              if (z > _rl_screenwidth)
     658                {
     659                  num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
     660                  break;
     661                }
     662              else if (z == _rl_screenwidth)
     663                break;
     664              num++;
     665            }
     666          temp = num;
     667        }
     668      else
     669#endif /* !HANDLE_MULTIBYTE */
     670        temp = ((newlines + 1) * _rl_screenwidth);
     671
     672      /* Now account for invisible characters in the current line. */
     673      temp += ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
     674                                                             : ((newlines == 1) ? wrap_offset : 0))
     675                                          : ((newlines == 0) ? wrap_offset :0));
     676             
     677      inv_lbreaks[++newlines] = temp;
     678#if defined (HANDLE_MULTIBYTE)
     679      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     680        lpos -= _rl_col_width (local_prompt, n0, num);
     681      else
     682#endif
     683        lpos -= _rl_screenwidth;
     684    }
     685
     686  prompt_last_screen_line = newlines;
     687
     688  /* Draw the rest of the line (after the prompt) into invisible_line, keeping
     689     track of where the cursor is (cpos_buffer_position), the number of the line containing
     690     the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin).
     691     It maintains an array of line breaks for display (inv_lbreaks).
     692     This handles expanding tabs for display and displaying meta characters. */
     693  lb_linenum = 0;
     694#if defined (HANDLE_MULTIBYTE)
     695  in = 0;
     696  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     697    {
     698      memset (&ps, 0, sizeof (mbstate_t));
     699      wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps);
     700    }
     701  else
     702    wc_bytes = 1;
     703  while (in < rl_end)
     704#else
     705  for (in = 0; in < rl_end; in++)
     706#endif
     707    {
     708      c = (unsigned char)rl_line_buffer[in];
     709
     710#if defined (HANDLE_MULTIBYTE)
     711      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     712        {
     713          if (MB_INVALIDCH (wc_bytes))
     714            {
     715              /* Byte sequence is invalid or shortened.  Assume that the
     716                 first byte represents a character. */
     717              wc_bytes = 1;
     718              /* Assume that a character occupies a single column. */
     719              wc_width = 1;
     720              memset (&ps, 0, sizeof (mbstate_t));
     721            }
     722          else if (MB_NULLWCH (wc_bytes))
     723            break;                      /* Found '\0' */
     724          else
     725            {
     726              temp = wcwidth (wc);
     727              wc_width = (temp >= 0) ? temp : 1;
     728            }
     729        }
     730#endif
     731
     732      if (out + 8 >= line_size)         /* XXX - 8 for \t */
     733        {
     734          line_size *= 2;
     735          visible_line = (char *)xrealloc (visible_line, line_size);
     736          invisible_line = (char *)xrealloc (invisible_line, line_size);
     737          line = invisible_line;
     738        }
     739
     740      if (in == rl_point)
     741        {
     742          cpos_buffer_position = out;
     743          lb_linenum = newlines;
     744        }
     745
     746#if defined (HANDLE_MULTIBYTE)
     747      if (META_CHAR (c) && _rl_output_meta_chars == 0)  /* XXX - clean up */
     748#else
     749      if (META_CHAR (c))
     750#endif
     751        {
     752          if (_rl_output_meta_chars == 0)
     753            {
     754              sprintf (line + out, "\\%o", c);
     755
     756              if (lpos + 4 >= _rl_screenwidth)
     757                {
     758                  temp = _rl_screenwidth - lpos;
     759                  CHECK_INV_LBREAKS ();
     760                  inv_lbreaks[++newlines] = out + temp;
     761                  lpos = 4 - temp;
     762                }
     763              else
     764                lpos += 4;
     765
     766              out += 4;
     767            }
     768          else
     769            {
     770              line[out++] = c;
     771              CHECK_LPOS();
     772            }
     773        }
     774#if defined (DISPLAY_TABS)
     775      else if (c == '\t')
     776        {
     777          register int newout;
     778
     779#if 0
     780          newout = (out | (int)7) + 1;
     781#else
     782          newout = out + 8 - lpos % 8;
     783#endif
     784          temp = newout - out;
     785          if (lpos + temp >= _rl_screenwidth)
     786            {
     787              register int temp2;
     788              temp2 = _rl_screenwidth - lpos;
     789              CHECK_INV_LBREAKS ();
     790              inv_lbreaks[++newlines] = out + temp2;
     791              lpos = temp - temp2;
     792              while (out < newout)
     793                line[out++] = ' ';
     794            }
     795          else
     796            {
     797              while (out < newout)
     798                line[out++] = ' ';
     799              lpos += temp;
     800            }
     801        }
     802#endif
     803      else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
     804        {
     805          line[out++] = '\0';   /* XXX - sentinel */
     806          CHECK_INV_LBREAKS ();
     807          inv_lbreaks[++newlines] = out;
     808          lpos = 0;
     809        }
     810      else if (CTRL_CHAR (c) || c == RUBOUT)
     811        {
     812          line[out++] = '^';
     813          CHECK_LPOS();
     814          line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
     815          CHECK_LPOS();
     816        }
     817      else
     818        {
     819#if defined (HANDLE_MULTIBYTE)
     820          if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     821            {
     822              register int i;
     823
     824              _rl_wrapped_multicolumn = 0;
     825
     826              if (_rl_screenwidth < lpos + wc_width)
     827                for (i = lpos; i < _rl_screenwidth; i++)
     828                  {
     829                    /* The space will be removed in update_line() */
     830                    line[out++] = ' ';
     831                    _rl_wrapped_multicolumn++;
     832                    CHECK_LPOS();
     833                  }
     834              if (in == rl_point)
     835                {
     836                  cpos_buffer_position = out;
     837                  lb_linenum = newlines;
     838                }
     839              for (i = in; i < in+wc_bytes; i++)
     840                line[out++] = rl_line_buffer[i];
     841              for (i = 0; i < wc_width; i++)
     842                CHECK_LPOS();
     843            }
     844          else
     845            {
     846              line[out++] = c;
     847              CHECK_LPOS();
     848            }
     849#else
     850          line[out++] = c;
     851          CHECK_LPOS();
     852#endif
     853        }
     854
     855#if defined (HANDLE_MULTIBYTE)
     856      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     857        {
     858          in += wc_bytes;
     859          wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps);
     860        }
     861      else
     862        in++;
     863#endif
     864
     865    }
     866  line[out] = '\0';
     867  if (cpos_buffer_position < 0)
     868    {
     869      cpos_buffer_position = out;
     870      lb_linenum = newlines;
     871    }
     872
     873  inv_botlin = lb_botlin = newlines;
     874  CHECK_INV_LBREAKS ();
     875  inv_lbreaks[newlines+1] = out;
     876  cursor_linenum = lb_linenum;
     877
     878  /* CPOS_BUFFER_POSITION == position in buffer where cursor should be placed.
     879     CURSOR_LINENUM == line number where the cursor should be placed. */
     880
     881  /* PWP: now is when things get a bit hairy.  The visible and invisible
     882     line buffers are really multiple lines, which would wrap every
     883     (screenwidth - 1) characters.  Go through each in turn, finding
     884     the changed region and updating it.  The line order is top to bottom. */
     885
     886  /* If we can move the cursor up and down, then use multiple lines,
     887     otherwise, let long lines display in a single terminal line, and
     888     horizontally scroll it. */
     889
     890  if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
     891    {
     892      int nleft, pos, changed_screen_line, tx;
     893
     894      if (!rl_display_fixed || forced_display)
     895        {
     896          forced_display = 0;
     897
     898          /* If we have more than a screenful of material to display, then
     899             only display a screenful.  We should display the last screen,
     900             not the first.  */
     901          if (out >= _rl_screenchars)
     902            {
     903              if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     904                out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY);
     905              else
     906                out = _rl_screenchars - 1;
     907            }
     908
     909          /* The first line is at character position 0 in the buffer.  The
     910             second and subsequent lines start at inv_lbreaks[N], offset by
     911             OFFSET (which has already been calculated above).  */
     912
     913#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
     914#define VIS_LLEN(l)     ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
     915#define INV_LLEN(l)     (inv_lbreaks[l+1] - inv_lbreaks[l])
     916#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
     917#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
     918#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
     919
     920          /* For each line in the buffer, do the updating display. */
     921          for (linenum = 0; linenum <= inv_botlin; linenum++)
     922            {
     923              /* This can lead us astray if we execute a program that changes
     924                 the locale from a non-multibyte to a multibyte one. */
     925              o_cpos = _rl_last_c_pos;
     926              cpos_adjusted = 0;
     927              update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
     928                           VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
     929
     930              /* update_line potentially changes _rl_last_c_pos, but doesn't
     931                 take invisible characters into account, since _rl_last_c_pos
     932                 is an absolute cursor position in a multibyte locale.  See
     933                 if compensating here is the right thing, or if we have to
     934                 change update_line itself.  There is one case in which
     935                 update_line adjusts _rl_last_c_pos itself (so it can pass
     936                 _rl_move_cursor_relative accurate values); it communicates
     937                 this back by setting cpos_adjusted.  If we assume that
     938                 _rl_last_c_pos is correct (an absolute cursor position) each
     939                 time update_line is called, then we can assume in our
     940                 calculations that o_cpos does not need to be adjusted by
     941                 wrap_offset. */
     942              if (linenum == 0 && (MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
     943                  cpos_adjusted == 0 &&
     944                  _rl_last_c_pos != o_cpos &&
     945                  _rl_last_c_pos > wrap_offset &&
     946                  o_cpos < prompt_last_invisible)
     947                _rl_last_c_pos -= wrap_offset;
     948                 
     949              /* If this is the line with the prompt, we might need to
     950                 compensate for invisible characters in the new line. Do
     951                 this only if there is not more than one new line (which
     952                 implies that we completely overwrite the old visible line)
     953                 and the new line is shorter than the old.  Make sure we are
     954                 at the end of the new line before clearing. */
     955              if (linenum == 0 &&
     956                  inv_botlin == 0 && _rl_last_c_pos == out &&
     957                  (wrap_offset > visible_wrap_offset) &&
     958                  (_rl_last_c_pos < visible_first_line_len))
     959                {
     960                  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     961                    nleft = _rl_screenwidth - _rl_last_c_pos;
     962                  else
     963                    nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
     964                  if (nleft)
     965                    _rl_clear_to_eol (nleft);
     966                }
     967
     968              /* Since the new first line is now visible, save its length. */
     969              if (linenum == 0)
     970                visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
     971            }
     972
     973          /* We may have deleted some lines.  If so, clear the left over
     974             blank ones at the bottom out. */
     975          if (_rl_vis_botlin > inv_botlin)
     976            {
     977              char *tt;
     978              for (; linenum <= _rl_vis_botlin; linenum++)
     979                {
     980                  tt = VIS_CHARS (linenum);
     981                  _rl_move_vert (linenum);
     982                  _rl_move_cursor_relative (0, tt);
     983                  _rl_clear_to_eol
     984                    ((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth);
     985                }
     986            }
     987          _rl_vis_botlin = inv_botlin;
     988
     989          /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
     990             different screen line during this redisplay. */
     991          changed_screen_line = _rl_last_v_pos != cursor_linenum;
     992          if (changed_screen_line)
     993            {
     994              _rl_move_vert (cursor_linenum);
     995              /* If we moved up to the line with the prompt using _rl_term_up,
     996                 the physical cursor position on the screen stays the same,
     997                 but the buffer position needs to be adjusted to account
     998                 for invisible characters. */
     999              if ((MB_CUR_MAX == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset)
     1000                _rl_last_c_pos += wrap_offset;
     1001            }
     1002
     1003          /* We have to reprint the prompt if it contains invisible
     1004             characters, since it's not generally OK to just reprint
     1005             the characters from the current cursor position.  But we
     1006             only need to reprint it if the cursor is before the last
     1007             invisible character in the prompt string. */
     1008          nleft = prompt_visible_length + wrap_offset;
     1009          if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
     1010#if 0
     1011              _rl_last_c_pos <= PROMPT_ENDING_INDEX && local_prompt)
     1012#else
     1013              _rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt)
     1014#endif
     1015            {
     1016#if defined (__MSDOS__)
     1017              putc ('\r', rl_outstream);
     1018#else
     1019              if (_rl_term_cr)
     1020                tputs (_rl_term_cr, 1, _rl_output_character_function);
     1021#endif
     1022              _rl_output_some_chars (local_prompt, nleft);
     1023              if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1024                _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft) - wrap_offset;
     1025              else
     1026                _rl_last_c_pos = nleft;
     1027            }
     1028
     1029          /* Where on that line?  And where does that line start
     1030             in the buffer? */
     1031          pos = inv_lbreaks[cursor_linenum];
     1032          /* nleft == number of characters in the line buffer between the
     1033             start of the line and the desired cursor position. */
     1034          nleft = cpos_buffer_position - pos;
     1035
     1036          /* NLEFT is now a number of characters in a buffer.  When in a
     1037             multibyte locale, however, _rl_last_c_pos is an absolute cursor
     1038             position that doesn't take invisible characters in the prompt
     1039             into account.  We use a fudge factor to compensate. */
     1040
     1041          /* Since _rl_backspace() doesn't know about invisible characters in the
     1042             prompt, and there's no good way to tell it, we compensate for
     1043             those characters here and call _rl_backspace() directly. */
     1044          if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
     1045            {
     1046              /* TX == new physical cursor position in multibyte locale. */
     1047              if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1048                tx = _rl_col_width (&visible_line[pos], 0, nleft) - visible_wrap_offset;
     1049              else
     1050                tx = nleft;
     1051              if (tx >= 0 && _rl_last_c_pos > tx)
     1052                {
     1053                  _rl_backspace (_rl_last_c_pos - tx);  /* XXX */
     1054                  _rl_last_c_pos = tx;
     1055                }
     1056            }
     1057
     1058          /* We need to note that in a multibyte locale we are dealing with
     1059             _rl_last_c_pos as an absolute cursor position, but moving to a
     1060             point specified by a buffer position (NLEFT) that doesn't take
     1061             invisible characters into account. */
     1062          if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1063            _rl_move_cursor_relative (nleft, &invisible_line[pos]);
     1064          else if (nleft != _rl_last_c_pos)
     1065            _rl_move_cursor_relative (nleft, &invisible_line[pos]);
     1066        }
     1067    }
     1068  else                          /* Do horizontal scrolling. */
     1069    {
     1070#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
     1071      int lmargin, ndisp, nleft, phys_c_pos, t;
     1072
     1073      /* Always at top line. */
     1074      _rl_last_v_pos = 0;
     1075
     1076      /* Compute where in the buffer the displayed line should start.  This
     1077         will be LMARGIN. */
     1078
     1079      /* The number of characters that will be displayed before the cursor. */
     1080      ndisp = cpos_buffer_position - wrap_offset;
     1081      nleft  = prompt_visible_length + wrap_offset;
     1082      /* Where the new cursor position will be on the screen.  This can be
     1083         longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
     1084      phys_c_pos = cpos_buffer_position - (last_lmargin ? last_lmargin : wrap_offset);
     1085      t = _rl_screenwidth / 3;
     1086
     1087      /* If the number of characters had already exceeded the screenwidth,
     1088         last_lmargin will be > 0. */
     1089
     1090      /* If the number of characters to be displayed is more than the screen
     1091         width, compute the starting offset so that the cursor is about
     1092         two-thirds of the way across the screen. */
     1093      if (phys_c_pos > _rl_screenwidth - 2)
     1094        {
     1095          lmargin = cpos_buffer_position - (2 * t);
     1096          if (lmargin < 0)
     1097            lmargin = 0;
     1098          /* If the left margin would be in the middle of a prompt with
     1099             invisible characters, don't display the prompt at all. */
     1100          if (wrap_offset && lmargin > 0 && lmargin < nleft)
     1101            lmargin = nleft;
     1102        }
     1103      else if (ndisp < _rl_screenwidth - 2)             /* XXX - was -1 */
     1104        lmargin = 0;
     1105      else if (phys_c_pos < 1)
     1106        {
     1107          /* If we are moving back towards the beginning of the line and
     1108             the last margin is no longer correct, compute a new one. */
     1109          lmargin = ((cpos_buffer_position - 1) / t) * t;       /* XXX */
     1110          if (wrap_offset && lmargin > 0 && lmargin < nleft)
     1111            lmargin = nleft;
     1112        }
     1113      else
     1114        lmargin = last_lmargin;
     1115
     1116      /* If the first character on the screen isn't the first character
     1117         in the display line, indicate this with a special character. */
     1118      if (lmargin > 0)
     1119        line[lmargin] = '<';
     1120
     1121      /* If SCREENWIDTH characters starting at LMARGIN do not encompass
     1122         the whole line, indicate that with a special character at the
     1123         right edge of the screen.  If LMARGIN is 0, we need to take the
     1124         wrap offset into account. */
     1125      t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth;
     1126      if (t < out)
     1127        line[t - 1] = '>';
     1128
     1129      if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
     1130        {
     1131          forced_display = 0;
     1132          update_line (&visible_line[last_lmargin],
     1133                       &invisible_line[lmargin],
     1134                       0,
     1135                       _rl_screenwidth + visible_wrap_offset,
     1136                       _rl_screenwidth + (lmargin ? 0 : wrap_offset),
     1137                       0);
     1138
     1139          /* If the visible new line is shorter than the old, but the number
     1140             of invisible characters is greater, and we are at the end of
     1141             the new line, we need to clear to eol. */
     1142          t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
     1143          if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
     1144              (_rl_last_c_pos == out) &&
     1145              t < visible_first_line_len)
     1146            {
     1147              nleft = _rl_screenwidth - t;
     1148              _rl_clear_to_eol (nleft);
     1149            }
     1150          visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
     1151          if (visible_first_line_len > _rl_screenwidth)
     1152            visible_first_line_len = _rl_screenwidth;
     1153
     1154          _rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin]);
     1155          last_lmargin = lmargin;
     1156        }
     1157    }
     1158  fflush (rl_outstream);
     1159
     1160  /* Swap visible and non-visible lines. */
     1161  {
     1162    char *vtemp = visible_line;
     1163    int *itemp = vis_lbreaks, ntemp = vis_lbsize;
     1164
     1165    visible_line = invisible_line;
     1166    invisible_line = vtemp;
     1167
     1168    vis_lbreaks = inv_lbreaks;
     1169    inv_lbreaks = itemp;
     1170
     1171    vis_lbsize = inv_lbsize;
     1172    inv_lbsize = ntemp;
     1173
     1174    rl_display_fixed = 0;
     1175    /* If we are displaying on a single line, and last_lmargin is > 0, we
     1176       are not displaying any invisible characters, so set visible_wrap_offset
     1177       to 0. */
     1178    if (_rl_horizontal_scroll_mode && last_lmargin)
     1179      visible_wrap_offset = 0;
     1180    else
     1181      visible_wrap_offset = wrap_offset;
     1182  }
     1183}
     1184
     1185/* PWP: update_line() is based on finding the middle difference of each
     1186   line on the screen; vis:
     1187
     1188                             /old first difference
     1189        /beginning of line   |        /old last same       /old EOL
     1190        v                    v        v             v
     1191old:    eddie> Oh, my little gruntle-buggy is to me, as lurgid as
     1192new:    eddie> Oh, my little buggy says to me, as lurgid as
     1193        ^                    ^  ^                          ^
     1194        \beginning of line   |  \new last same     \new end of line
     1195                             \new first difference
     1196
     1197   All are character pointers for the sake of speed.  Special cases for
     1198   no differences, as well as for end of line additions must be handled.
     1199
     1200   Could be made even smarter, but this works well enough */
     1201static void
     1202update_line (old, new, current_line, omax, nmax, inv_botlin)
     1203     register char *old, *new;
     1204     int current_line, omax, nmax, inv_botlin;
     1205{
     1206  register char *ofd, *ols, *oe, *nfd, *nls, *ne;
     1207  int temp, lendiff, wsatend, od, nd, o_cpos;
     1208  int current_invis_chars;
     1209  int col_lendiff, col_temp;
     1210#if defined (HANDLE_MULTIBYTE)
     1211  mbstate_t ps_new, ps_old;
     1212  int new_offset, old_offset;
     1213#endif
     1214
     1215  /* If we're at the right edge of a terminal that supports xn, we're
     1216     ready to wrap around, so do so.  This fixes problems with knowing
     1217     the exact cursor position and cut-and-paste with certain terminal
     1218     emulators.  In this calculation, TEMP is the physical screen
     1219     position of the cursor. */
     1220  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1221    temp = _rl_last_c_pos;
     1222  else
     1223    temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
     1224  if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
     1225        && _rl_last_v_pos == current_line - 1)
     1226    {
     1227#if defined (HANDLE_MULTIBYTE)
     1228      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1229        {
     1230          wchar_t wc;
     1231          mbstate_t ps;
     1232          int tempwidth, bytes;
     1233          size_t ret;
     1234
     1235          /* This fixes only double-column characters, but if the wrapped
     1236             character comsumes more than three columns, spaces will be
     1237             inserted in the string buffer. */
     1238          if (_rl_wrapped_line[current_line] > 0)
     1239            _rl_clear_to_eol (_rl_wrapped_line[current_line]);
     1240
     1241          memset (&ps, 0, sizeof (mbstate_t));
     1242          ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps);
     1243          if (MB_INVALIDCH (ret))
     1244            {
     1245              tempwidth = 1;
     1246              ret = 1;
     1247            }
     1248          else if (MB_NULLWCH (ret))
     1249            tempwidth = 0;
     1250          else
     1251            tempwidth = wcwidth (wc);
     1252
     1253          if (tempwidth > 0)
     1254            {
     1255              int count;
     1256              bytes = ret;
     1257              for (count = 0; count < bytes; count++)
     1258                putc (new[count], rl_outstream);
     1259              _rl_last_c_pos = tempwidth;
     1260              _rl_last_v_pos++;
     1261              memset (&ps, 0, sizeof (mbstate_t));
     1262              ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps);
     1263              if (ret != 0 && bytes != 0)
     1264                {
     1265                  if (MB_INVALIDCH (ret))
     1266                    memmove (old+bytes, old+1, strlen (old+1));
     1267                  else
     1268                    memmove (old+bytes, old+ret, strlen (old+ret));
     1269                  memcpy (old, new, bytes);
     1270                }
     1271            }
     1272          else
     1273            {
     1274              putc (' ', rl_outstream);
     1275              _rl_last_c_pos = 1;
     1276              _rl_last_v_pos++;
     1277              if (old[0] && new[0])
     1278                old[0] = new[0];
     1279            }
     1280        }
     1281      else
     1282#endif
     1283        {
     1284          if (new[0])
     1285            putc (new[0], rl_outstream);
     1286          else
     1287            putc (' ', rl_outstream);
     1288          _rl_last_c_pos = 1;
     1289          _rl_last_v_pos++;
     1290          if (old[0] && new[0])
     1291            old[0] = new[0];
     1292        }
     1293    }
     1294
     1295     
     1296  /* Find first difference. */
     1297#if defined (HANDLE_MULTIBYTE)
     1298  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1299    {
     1300      /* See if the old line is a subset of the new line, so that the
     1301         only change is adding characters. */
     1302      temp = (omax < nmax) ? omax : nmax;
     1303      if (memcmp (old, new, temp) == 0)
     1304        {
     1305          ofd = old + temp;
     1306          nfd = new + temp;
     1307        }
     1308      else
     1309        {     
     1310          memset (&ps_new, 0, sizeof(mbstate_t));
     1311          memset (&ps_old, 0, sizeof(mbstate_t));
     1312
     1313          if (omax == nmax && STREQN (new, old, omax))
     1314            {
     1315              ofd = old + omax;
     1316              nfd = new + nmax;
     1317            }
     1318          else
     1319            {
     1320              new_offset = old_offset = 0;
     1321              for (ofd = old, nfd = new;
     1322                    (ofd - old < omax) && *ofd &&
     1323                    _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
     1324                {
     1325                  old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
     1326                  new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
     1327                  ofd = old + old_offset;
     1328                  nfd = new + new_offset;
     1329                }
     1330            }
     1331        }
     1332    }
     1333  else
     1334#endif
     1335  for (ofd = old, nfd = new;
     1336       (ofd - old < omax) && *ofd && (*ofd == *nfd);
     1337       ofd++, nfd++)
     1338    ;
     1339
     1340  /* Move to the end of the screen line.  ND and OD are used to keep track
     1341     of the distance between ne and new and oe and old, respectively, to
     1342     move a subtraction out of each loop. */
     1343  for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
     1344  for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
     1345
     1346  /* If no difference, continue to next line. */
     1347  if (ofd == oe && nfd == ne)
     1348    return;
     1349
     1350  wsatend = 1;                  /* flag for trailing whitespace */
     1351
     1352#if defined (HANDLE_MULTIBYTE)
     1353  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1354    {
     1355      ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY);
     1356      nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY);
     1357      while ((ols > ofd) && (nls > nfd))
     1358        {
     1359          memset (&ps_old, 0, sizeof (mbstate_t));
     1360          memset (&ps_new, 0, sizeof (mbstate_t));
     1361
     1362#if 0
     1363          /* On advice from jir@yamato.ibm.com */
     1364          _rl_adjust_point (old, ols - old, &ps_old);
     1365          _rl_adjust_point (new, nls - new, &ps_new);
     1366#endif
     1367
     1368          if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
     1369            break;
     1370
     1371          if (*ols == ' ')
     1372            wsatend = 0;
     1373
     1374          ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY);
     1375          nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY);
     1376        }
     1377    }
     1378  else
     1379    {
     1380#endif /* HANDLE_MULTIBYTE */
     1381  ols = oe - 1;                 /* find last same */
     1382  nls = ne - 1;
     1383  while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
     1384    {
     1385      if (*ols != ' ')
     1386        wsatend = 0;
     1387      ols--;
     1388      nls--;
     1389    }
     1390#if defined (HANDLE_MULTIBYTE)
     1391    }
     1392#endif
     1393
     1394  if (wsatend)
     1395    {
     1396      ols = oe;
     1397      nls = ne;
     1398    }
     1399#if defined (HANDLE_MULTIBYTE)
     1400  /* This may not work for stateful encoding, but who cares?  To handle
     1401     stateful encoding properly, we have to scan each string from the
     1402     beginning and compare. */
     1403  else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0)
     1404#else
     1405  else if (*ols != *nls)
     1406#endif
     1407    {
     1408      if (*ols)                 /* don't step past the NUL */
     1409        {
     1410          if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1411            ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY);
     1412          else
     1413            ols++;
     1414        }
     1415      if (*nls)
     1416        {
     1417          if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1418            nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY);
     1419          else
     1420            nls++;
     1421        }
     1422    }
     1423
     1424  /* count of invisible characters in the current invisible line. */
     1425  current_invis_chars = W_OFFSET (current_line, wrap_offset);
     1426  if (_rl_last_v_pos != current_line)
     1427    {
     1428      _rl_move_vert (current_line);
     1429      if ((MB_CUR_MAX == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset)
     1430        _rl_last_c_pos += visible_wrap_offset;
     1431    }
     1432
     1433  /* If this is the first line and there are invisible characters in the
     1434     prompt string, and the prompt string has not changed, and the current
     1435     cursor position is before the last invisible character in the prompt,
     1436     and the index of the character to move to is past the end of the prompt
     1437     string, then redraw the entire prompt string.  We can only do this
     1438     reliably if the terminal supports a `cr' capability.
     1439
     1440     This is not an efficiency hack -- there is a problem with redrawing
     1441     portions of the prompt string if they contain terminal escape
     1442     sequences (like drawing the `unbold' sequence without a corresponding
     1443     `bold') that manifests itself on certain terminals. */
     1444
     1445  lendiff = local_prompt_len;
     1446  od = ofd - old;       /* index of first difference in visible line */
     1447  if (current_line == 0 && !_rl_horizontal_scroll_mode &&
     1448      _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 &&
     1449      od >= lendiff && _rl_last_c_pos < PROMPT_ENDING_INDEX)
     1450    {
     1451#if defined (__MSDOS__)
     1452      putc ('\r', rl_outstream);
     1453#else
     1454      tputs (_rl_term_cr, 1, _rl_output_character_function);
     1455#endif
     1456      _rl_output_some_chars (local_prompt, lendiff);
     1457      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1458        {
     1459          /* We take wrap_offset into account here so we can pass correct
     1460             information to _rl_move_cursor_relative. */
     1461          _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff) - wrap_offset;
     1462          cpos_adjusted = 1;
     1463        }
     1464      else
     1465        _rl_last_c_pos = lendiff;
     1466    }
     1467
     1468  o_cpos = _rl_last_c_pos;
     1469
     1470  /* When this function returns, _rl_last_c_pos is correct, and an absolute
     1471     cursor postion in multibyte mode, but a buffer index when not in a
     1472     multibyte locale. */
     1473  _rl_move_cursor_relative (od, old);
     1474#if 1
     1475#if defined (HANDLE_MULTIBYTE)
     1476  /* We need to indicate that the cursor position is correct in the presence of
     1477     invisible characters in the prompt string.  Let's see if setting this when
     1478     we make sure we're at the end of the drawn prompt string works. */
     1479  if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 &&
     1480      (_rl_last_c_pos > 0 || o_cpos > 0) &&
     1481      _rl_last_c_pos == prompt_physical_chars)
     1482    cpos_adjusted = 1;
     1483#endif
     1484#endif
     1485
     1486  /* if (len (new) > len (old))
     1487     lendiff == difference in buffer
     1488     col_lendiff == difference on screen
     1489     When not using multibyte characters, these are equal */
     1490  lendiff = (nls - nfd) - (ols - ofd);
     1491  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1492    col_lendiff = _rl_col_width (new, nfd - new, nls - new) - _rl_col_width (old, ofd - old, ols - old);
     1493  else
     1494    col_lendiff = lendiff;
     1495
     1496  /* If we are changing the number of invisible characters in a line, and
     1497     the spot of first difference is before the end of the invisible chars,
     1498     lendiff needs to be adjusted. */
     1499  if (current_line == 0 && !_rl_horizontal_scroll_mode &&
     1500      current_invis_chars != visible_wrap_offset)
     1501    {
     1502      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1503        {
     1504          lendiff += visible_wrap_offset - current_invis_chars;
     1505          col_lendiff += visible_wrap_offset - current_invis_chars;
     1506        }
     1507      else
     1508        {
     1509          lendiff += visible_wrap_offset - current_invis_chars;
     1510          col_lendiff = lendiff;
     1511        }
     1512    }
     1513
     1514  /* Insert (diff (len (old), len (new)) ch. */
     1515  temp = ne - nfd;
     1516  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1517    col_temp = _rl_col_width (new, nfd - new, ne - new);
     1518  else
     1519    col_temp = temp;
     1520
     1521  if (col_lendiff > 0)  /* XXX - was lendiff */
     1522    {
     1523      /* Non-zero if we're increasing the number of lines. */
     1524      int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
     1525      /* If col_lendiff is > 0, implying that the new string takes up more
     1526         screen real estate than the old, but lendiff is < 0, meaning that it
     1527         takes fewer bytes, we need to just output the characters starting
     1528         from the first difference.  These will overwrite what is on the
     1529         display, so there's no reason to do a smart update.  This can really
     1530         only happen in a multibyte environment. */
     1531      if (lendiff < 0)
     1532        {
     1533          _rl_output_some_chars (nfd, temp);
     1534          _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
     1535          /* If nfd begins before any invisible characters in the prompt,
     1536             adjust _rl_last_c_pos to account for wrap_offset and set
     1537             cpos_adjusted to let the caller know. */
     1538          if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
     1539            {
     1540              _rl_last_c_pos -= wrap_offset;
     1541              cpos_adjusted = 1;
     1542            }
     1543          return;
     1544        }
     1545      /* Sometimes it is cheaper to print the characters rather than
     1546         use the terminal's capabilities.  If we're growing the number
     1547         of lines, make sure we actually cause the new line to wrap
     1548         around on auto-wrapping terminals. */
     1549      else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
     1550        {
     1551          /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
     1552             _rl_horizontal_scroll_mode == 1, inserting the characters with
     1553             _rl_term_IC or _rl_term_ic will screw up the screen because of the
     1554             invisible characters.  We need to just draw them. */
     1555          if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||
     1556                        lendiff <= prompt_visible_length || !current_invis_chars))
     1557            {
     1558              insert_some_chars (nfd, lendiff, col_lendiff);
     1559              _rl_last_c_pos += col_lendiff;
     1560            }
     1561          else if ((MB_CUR_MAX == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0)
     1562            {
     1563              /* At the end of a line the characters do not have to
     1564                 be "inserted".  They can just be placed on the screen. */
     1565              /* However, this screws up the rest of this block, which
     1566                 assumes you've done the insert because you can. */
     1567              _rl_output_some_chars (nfd, lendiff);
     1568              _rl_last_c_pos += col_lendiff;
     1569            }
     1570          else
     1571            {
     1572              /* We have horizontal scrolling and we are not inserting at
     1573                 the end.  We have invisible characters in this line.  This
     1574                 is a dumb update. */
     1575              _rl_output_some_chars (nfd, temp);
     1576              _rl_last_c_pos += col_temp;
     1577              return;
     1578            }
     1579          /* Copy (new) chars to screen from first diff to last match. */
     1580          temp = nls - nfd;
     1581          if ((temp - lendiff) > 0)
     1582            {
     1583              _rl_output_some_chars (nfd + lendiff, temp - lendiff);
     1584#if 1
     1585             /* XXX -- this bears closer inspection.  Fixes a redisplay bug
     1586                reported against bash-3.0-alpha by Andreas Schwab involving
     1587                multibyte characters and prompt strings with invisible
     1588                characters, but was previously disabled. */
     1589              _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-col_lendiff);
     1590#else
     1591              _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-lendiff);
     1592#endif
     1593            }
     1594        }
     1595      else
     1596        {
     1597          /* cannot insert chars, write to EOL */
     1598          _rl_output_some_chars (nfd, temp);
     1599          _rl_last_c_pos += col_temp;
     1600          /* If we're in a multibyte locale and were before the last invisible
     1601             char in the current line (which implies we just output some invisible
     1602             characters) we need to adjust _rl_last_c_pos, since it represents
     1603             a physical character position. */
     1604        }
     1605    }
     1606  else                          /* Delete characters from line. */
     1607    {
     1608      /* If possible and inexpensive to use terminal deletion, then do so. */
     1609      if (_rl_term_dc && (2 * col_temp) >= -col_lendiff)
     1610        {
     1611          /* If all we're doing is erasing the invisible characters in the
     1612             prompt string, don't bother.  It screws up the assumptions
     1613             about what's on the screen. */
     1614          if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
     1615              -lendiff == visible_wrap_offset)
     1616            col_lendiff = 0;
     1617
     1618          if (col_lendiff)
     1619            delete_chars (-col_lendiff); /* delete (diff) characters */
     1620
     1621          /* Copy (new) chars to screen from first diff to last match */
     1622          temp = nls - nfd;
     1623          if (temp > 0)
     1624            {
     1625              /* If nfd begins at the prompt, or before the invisible
     1626                 characters in the prompt, we need to adjust _rl_last_c_pos
     1627                 in a multibyte locale to account for the wrap offset and
     1628                 set cpos_adjusted accordingly. */
     1629              _rl_output_some_chars (nfd, temp);
     1630              if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1631                {
     1632                  _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
     1633                  if (current_line == 0 && wrap_offset &&  ((nfd - new) <= prompt_last_invisible))
     1634                    {
     1635                      _rl_last_c_pos -= wrap_offset;
     1636                      cpos_adjusted = 1;
     1637                    }
     1638                }
     1639              else
     1640                _rl_last_c_pos += temp;
     1641            }
     1642        }
     1643      /* Otherwise, print over the existing material. */
     1644      else
     1645        {
     1646          if (temp > 0)
     1647            {
     1648              /* If nfd begins at the prompt, or before the invisible
     1649                 characters in the prompt, we need to adjust _rl_last_c_pos
     1650                 in a multibyte locale to account for the wrap offset and
     1651                 set cpos_adjusted accordingly. */
     1652              _rl_output_some_chars (nfd, temp);
     1653              _rl_last_c_pos += col_temp;               /* XXX */
     1654              if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1655                {
     1656                  if (current_line == 0 && wrap_offset &&  ((nfd - new) <= prompt_last_invisible))
     1657                    {
     1658                      _rl_last_c_pos -= wrap_offset;
     1659                      cpos_adjusted = 1;
     1660                    }
     1661                }
     1662            }
     1663          lendiff = (oe - old) - (ne - new);
     1664          if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1665            col_lendiff = _rl_col_width (old, 0, oe - old) - _rl_col_width (new, 0, ne - new);
     1666          else
     1667            col_lendiff = lendiff;
     1668
     1669          if (col_lendiff)
     1670            {     
     1671              if (_rl_term_autowrap && current_line < inv_botlin)
     1672                space_to_eol (col_lendiff);
     1673              else
     1674                _rl_clear_to_eol (col_lendiff);
     1675            }
     1676        }
     1677    }
     1678}
     1679
     1680/* Tell the update routines that we have moved onto a new (empty) line. */
     1681int
     1682rl_on_new_line ()
     1683{
     1684  if (visible_line)
     1685    visible_line[0] = '\0';
     1686
     1687  _rl_last_c_pos = _rl_last_v_pos = 0;
     1688  _rl_vis_botlin = last_lmargin = 0;
     1689  if (vis_lbreaks)
     1690    vis_lbreaks[0] = vis_lbreaks[1] = 0;
     1691  visible_wrap_offset = 0;
     1692  return 0;
     1693}
     1694
     1695/* Tell the update routines that we have moved onto a new line with the
     1696   prompt already displayed.  Code originally from the version of readline
     1697   distributed with CLISP.  rl_expand_prompt must have already been called
     1698   (explicitly or implicitly).  This still doesn't work exactly right. */
     1699int
     1700rl_on_new_line_with_prompt ()
     1701{
     1702  int prompt_size, i, l, real_screenwidth, newlines;
     1703  char *prompt_last_line, *lprompt;
     1704
     1705  /* Initialize visible_line and invisible_line to ensure that they can hold
     1706     the already-displayed prompt. */
     1707  prompt_size = strlen (rl_prompt) + 1;
     1708  init_line_structures (prompt_size);
     1709
     1710  /* Make sure the line structures hold the already-displayed prompt for
     1711     redisplay. */
     1712  lprompt = local_prompt ? local_prompt : rl_prompt;
     1713  strcpy (visible_line, lprompt);
     1714  strcpy (invisible_line, lprompt);
     1715
     1716  /* If the prompt contains newlines, take the last tail. */
     1717  prompt_last_line = strrchr (rl_prompt, '\n');
     1718  if (!prompt_last_line)
     1719    prompt_last_line = rl_prompt;
     1720
     1721  l = strlen (prompt_last_line);
     1722  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1723    _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l);    /* XXX */
     1724  else
     1725    _rl_last_c_pos = l;
     1726
     1727  /* Dissect prompt_last_line into screen lines. Note that here we have
     1728     to use the real screenwidth. Readline's notion of screenwidth might be
     1729     one less, see terminal.c. */
     1730  real_screenwidth = _rl_screenwidth + (_rl_term_autowrap ? 0 : 1);
     1731  _rl_last_v_pos = l / real_screenwidth;
     1732  /* If the prompt length is a multiple of real_screenwidth, we don't know
     1733     whether the cursor is at the end of the last line, or already at the
     1734     beginning of the next line. Output a newline just to be safe. */
     1735  if (l > 0 && (l % real_screenwidth) == 0)
     1736    _rl_output_some_chars ("\n", 1);
     1737  last_lmargin = 0;
     1738
     1739  newlines = 0; i = 0;
     1740  while (i <= l)
     1741    {
     1742      _rl_vis_botlin = newlines;
     1743      vis_lbreaks[newlines++] = i;
     1744      i += real_screenwidth;
     1745    }
     1746  vis_lbreaks[newlines] = l;
     1747  visible_wrap_offset = 0;
     1748
     1749  rl_display_prompt = rl_prompt;        /* XXX - make sure it's set */
     1750
     1751  return 0;
     1752}
     1753
     1754/* Actually update the display, period. */
     1755int
     1756rl_forced_update_display ()
     1757{
     1758  register char *temp;
     1759
     1760  if (visible_line)
     1761    {
     1762      temp = visible_line;
     1763      while (*temp)
     1764        *temp++ = '\0';
     1765    }
     1766  rl_on_new_line ();
     1767  forced_display++;
     1768  (*rl_redisplay_function) ();
     1769  return 0;
     1770}
     1771
     1772/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
     1773   (Well, when we don't have multibyte characters, _rl_last_c_pos is a
     1774   buffer index.)
     1775   DATA is the contents of the screen line of interest; i.e., where
     1776   the movement is being done. */
     1777void
     1778_rl_move_cursor_relative (new, data)
     1779     int new;
     1780     const char *data;
     1781{
     1782  register int i;
     1783  int woff;                     /* number of invisible chars on current line */
     1784  int cpos, dpos;               /* current and desired cursor positions */
     1785
     1786  woff = W_OFFSET (_rl_last_v_pos, wrap_offset);
     1787  cpos = _rl_last_c_pos;
     1788#if defined (HANDLE_MULTIBYTE)
     1789  /* If we have multibyte characters, NEW is indexed by the buffer point in
     1790     a multibyte string, but _rl_last_c_pos is the display position.  In
     1791     this case, NEW's display position is not obvious and must be
     1792     calculated.  We need to account for invisible characters in this line,
     1793     as long as we are past them and they are counted by _rl_col_width. */
     1794  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1795    {
     1796      dpos = _rl_col_width (data, 0, new);
     1797      /* Use NEW when comparing against the last invisible character in the
     1798         prompt string, since they're both buffer indices and DPOS is a
     1799         desired display position. */
     1800      if (new > prompt_last_invisible)          /* XXX - don't use woff here */
     1801        {
     1802          dpos -= woff;
     1803          /* Since this will be assigned to _rl_last_c_pos at the end (more
     1804             precisely, _rl_last_c_pos == dpos when this function returns),
     1805             let the caller know. */
     1806          cpos_adjusted = 1;
     1807        }
     1808    }
     1809  else
     1810#endif
     1811    dpos = new;
     1812
     1813  /* If we don't have to do anything, then return. */
     1814  if (cpos == dpos)
     1815    return;
     1816
     1817  /* It may be faster to output a CR, and then move forwards instead
     1818     of moving backwards. */
     1819  /* i == current physical cursor position. */
     1820#if defined (HANDLE_MULTIBYTE)
     1821  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1822    i = _rl_last_c_pos;
     1823  else
     1824#endif
     1825  i = _rl_last_c_pos - woff;
     1826  if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) ||
     1827      (_rl_term_autowrap && i == _rl_screenwidth))
     1828    {
     1829#if defined (__MSDOS__)
     1830      putc ('\r', rl_outstream);
     1831#else
     1832      tputs (_rl_term_cr, 1, _rl_output_character_function);
     1833#endif /* !__MSDOS__ */
     1834      cpos = _rl_last_c_pos = 0;
     1835    }
     1836
     1837  if (cpos < dpos)
     1838    {
     1839      /* Move the cursor forward.  We do it by printing the command
     1840         to move the cursor forward if there is one, else print that
     1841         portion of the output buffer again.  Which is cheaper? */
     1842
     1843      /* The above comment is left here for posterity.  It is faster
     1844         to print one character (non-control) than to print a control
     1845         sequence telling the terminal to move forward one character.
     1846         That kind of control is for people who don't know what the
     1847         data is underneath the cursor. */
     1848
     1849      /* However, we need a handle on where the current display position is
     1850         in the buffer for the immediately preceding comment to be true.
     1851         In multibyte locales, we don't currently have that info available.
     1852         Without it, we don't know where the data we have to display begins
     1853         in the buffer and we have to go back to the beginning of the screen
     1854         line.  In this case, we can use the terminal sequence to move forward
     1855         if it's available. */
     1856      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     1857        {
     1858          if (_rl_term_forward_char)
     1859            {
     1860              for (i = cpos; i < dpos; i++)
     1861                tputs (_rl_term_forward_char, 1, _rl_output_character_function);
     1862            }
     1863          else
     1864            {
     1865              tputs (_rl_term_cr, 1, _rl_output_character_function);
     1866              for (i = 0; i < new; i++)
     1867                putc (data[i], rl_outstream);
     1868            }
     1869        }
     1870      else
     1871        for (i = cpos; i < new; i++)
     1872          putc (data[i], rl_outstream);
     1873    }
     1874
     1875#if defined (HANDLE_MULTIBYTE)
     1876  /* NEW points to the buffer point, but _rl_last_c_pos is the display point.
     1877     The byte length of the string is probably bigger than the column width
     1878     of the string, which means that if NEW == _rl_last_c_pos, then NEW's
     1879     display point is less than _rl_last_c_pos. */
     1880#endif
     1881  else if (cpos > dpos)
     1882    _rl_backspace (cpos - dpos);
     1883
     1884  _rl_last_c_pos = dpos;
     1885}
     1886
     1887/* PWP: move the cursor up or down. */
     1888void
     1889_rl_move_vert (to)
     1890     int to;
     1891{
     1892  register int delta, i;
     1893
     1894  if (_rl_last_v_pos == to || to > _rl_screenheight)
     1895    return;
     1896
     1897  if ((delta = to - _rl_last_v_pos) > 0)
     1898    {
     1899      for (i = 0; i < delta; i++)
     1900        putc ('\n', rl_outstream);
     1901#if defined (__MSDOS__)
     1902      putc ('\r', rl_outstream);
     1903#else
     1904      tputs (_rl_term_cr, 1, _rl_output_character_function);
     1905#endif
     1906      _rl_last_c_pos = 0;
     1907    }
     1908  else
     1909    {                   /* delta < 0 */
     1910      if (_rl_term_up && *_rl_term_up)
     1911        for (i = 0; i < -delta; i++)
     1912          tputs (_rl_term_up, 1, _rl_output_character_function);
     1913    }
     1914
     1915  _rl_last_v_pos = to;          /* Now TO is here */
     1916}
     1917
     1918/* Physically print C on rl_outstream.  This is for functions which know
     1919   how to optimize the display.  Return the number of characters output. */
     1920int
     1921rl_show_char (c)
     1922     int c;
     1923{
     1924  int n = 1;
     1925  if (META_CHAR (c) && (_rl_output_meta_chars == 0))
     1926    {
     1927      fprintf (rl_outstream, "M-");
     1928      n += 2;
     1929      c = UNMETA (c);
     1930    }
     1931
     1932#if defined (DISPLAY_TABS)
     1933  if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
     1934#else
     1935  if (CTRL_CHAR (c) || c == RUBOUT)
     1936#endif /* !DISPLAY_TABS */
     1937    {
     1938      fprintf (rl_outstream, "C-");
     1939      n += 2;
     1940      c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
     1941    }
     1942
     1943  putc (c, rl_outstream);
     1944  fflush (rl_outstream);
     1945  return n;
     1946}
     1947
     1948int
     1949rl_character_len (c, pos)
     1950     register int c, pos;
     1951{
     1952  unsigned char uc;
     1953
     1954  uc = (unsigned char)c;
     1955
     1956  if (META_CHAR (uc))
     1957    return ((_rl_output_meta_chars == 0) ? 4 : 1);
     1958
     1959  if (uc == '\t')
     1960    {
     1961#if defined (DISPLAY_TABS)
     1962      return (((pos | 7) + 1) - pos);
     1963#else
     1964      return (2);
     1965#endif /* !DISPLAY_TABS */
     1966    }
     1967
     1968  if (CTRL_CHAR (c) || c == RUBOUT)
     1969    return (2);
     1970
     1971  return ((ISPRINT (uc)) ? 1 : 2);
     1972}
     1973/* How to print things in the "echo-area".  The prompt is treated as a
     1974   mini-modeline. */
     1975static int msg_saved_prompt = 0;
     1976
     1977#if defined (USE_VARARGS)
     1978int
     1979#if defined (PREFER_STDARG)
     1980rl_message (const char *format, ...)
     1981#else
     1982rl_message (va_alist)
     1983     va_dcl
     1984#endif
     1985{
     1986  va_list args;
     1987#if defined (PREFER_VARARGS)
     1988  char *format;
     1989#endif
     1990
     1991#if defined (PREFER_STDARG)
     1992  va_start (args, format);
     1993#else
     1994  va_start (args);
     1995  format = va_arg (args, char *);
     1996#endif
     1997
     1998#if defined (HAVE_VSNPRINTF)
     1999  vsnprintf (msg_buf, sizeof (msg_buf) - 1, format, args);
     2000#else
     2001  vsprintf (msg_buf, format, args);
     2002  msg_buf[sizeof(msg_buf) - 1] = '\0';  /* overflow? */
     2003#endif
     2004  va_end (args);
     2005
     2006  if (saved_local_prompt == 0)
     2007    {
     2008      rl_save_prompt ();
     2009      msg_saved_prompt = 1;
     2010    }
     2011  rl_display_prompt = msg_buf;
     2012  local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
     2013                                         &prompt_last_invisible,
     2014                                         &prompt_invis_chars_first_line,
     2015                                         &prompt_physical_chars);
     2016  local_prompt_prefix = (char *)NULL;
     2017  local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
     2018  (*rl_redisplay_function) ();
     2019
     2020  return 0;
     2021}
     2022#else /* !USE_VARARGS */
     2023int
     2024rl_message (format, arg1, arg2)
     2025     char *format;
     2026{
     2027  sprintf (msg_buf, format, arg1, arg2);
     2028  msg_buf[sizeof(msg_buf) - 1] = '\0';  /* overflow? */
     2029
     2030  rl_display_prompt = msg_buf;
     2031  if (saved_local_prompt == 0)
     2032    {
     2033      rl_save_prompt ();
     2034      msg_saved_prompt = 1;
     2035    }
     2036  local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
     2037                                         &prompt_last_invisible,
     2038                                         &prompt_invis_chars_first_line,
     2039                                         &prompt_physical_chars);
     2040  local_prompt_prefix = (char *)NULL;
     2041  local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
     2042  (*rl_redisplay_function) ();
     2043     
     2044  return 0;
     2045}
     2046#endif /* !USE_VARARGS */
     2047
     2048/* How to clear things from the "echo-area". */
     2049int
     2050rl_clear_message ()
     2051{
     2052  rl_display_prompt = rl_prompt;
     2053  if (msg_saved_prompt)
     2054    {
     2055      rl_restore_prompt ();
     2056      msg_saved_prompt = 0;
     2057    }
     2058  (*rl_redisplay_function) ();
     2059  return 0;
     2060}
     2061
     2062int
     2063rl_reset_line_state ()
     2064{
     2065  rl_on_new_line ();
     2066
     2067  rl_display_prompt = rl_prompt ? rl_prompt : "";
     2068  forced_display = 1;
     2069  return 0;
     2070}
     2071
     2072void
     2073rl_save_prompt ()
     2074{
     2075  saved_local_prompt = local_prompt;
     2076  saved_local_prefix = local_prompt_prefix;
     2077  saved_prefix_length = prompt_prefix_length;
     2078  saved_local_length = local_prompt_len;
     2079  saved_last_invisible = prompt_last_invisible;
     2080  saved_visible_length = prompt_visible_length;
     2081  saved_invis_chars_first_line = prompt_invis_chars_first_line;
     2082  saved_physical_chars = prompt_physical_chars;
     2083
     2084  local_prompt = local_prompt_prefix = (char *)0;
     2085  local_prompt_len = 0;
     2086  prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0;
     2087  prompt_invis_chars_first_line = prompt_physical_chars = 0;
     2088}
     2089
     2090void
     2091rl_restore_prompt ()
     2092{
     2093  FREE (local_prompt);
     2094  FREE (local_prompt_prefix);
     2095
     2096  local_prompt = saved_local_prompt;
     2097  local_prompt_prefix = saved_local_prefix;
     2098  local_prompt_len = saved_local_length;
     2099  prompt_prefix_length = saved_prefix_length;
     2100  prompt_last_invisible = saved_last_invisible;
     2101  prompt_visible_length = saved_visible_length;
     2102  prompt_invis_chars_first_line = saved_invis_chars_first_line;
     2103  prompt_physical_chars = saved_physical_chars;
     2104
     2105  /* can test saved_local_prompt to see if prompt info has been saved. */
     2106  saved_local_prompt = saved_local_prefix = (char *)0;
     2107  saved_local_length = 0;
     2108  saved_last_invisible = saved_visible_length = saved_prefix_length = 0;
     2109  saved_invis_chars_first_line = saved_physical_chars = 0;
     2110}
     2111
     2112char *
     2113_rl_make_prompt_for_search (pchar)
     2114     int pchar;
     2115{
     2116  int len;
     2117  char *pmt, *p;
     2118
     2119  rl_save_prompt ();
     2120
     2121  /* We've saved the prompt, and can do anything with the various prompt
     2122     strings we need before they're restored.  We want the unexpanded
     2123     portion of the prompt string after any final newline. */
     2124  p = rl_prompt ? strrchr (rl_prompt, '\n') : 0;
     2125  if (p == 0)
     2126    {
     2127      len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
     2128      pmt = (char *)xmalloc (len + 2);
     2129      if (len)
     2130        strcpy (pmt, rl_prompt);
     2131      pmt[len] = pchar;
     2132      pmt[len+1] = '\0';
     2133    }
     2134  else
     2135    {
     2136      p++;
     2137      len = strlen (p);
     2138      pmt = (char *)xmalloc (len + 2);
     2139      if (len)
     2140        strcpy (pmt, p);
     2141      pmt[len] = pchar;
     2142      pmt[len+1] = '\0';
     2143    } 
     2144
     2145  /* will be overwritten by expand_prompt, called from rl_message */
     2146  prompt_physical_chars = saved_physical_chars + 1;
     2147  return pmt;
     2148}
     2149
     2150/* Quick redisplay hack when erasing characters at the end of the line. */
     2151void
     2152_rl_erase_at_end_of_line (l)
     2153     int l;
     2154{
     2155  register int i;
     2156
     2157  _rl_backspace (l);
     2158  for (i = 0; i < l; i++)
     2159    putc (' ', rl_outstream);
     2160  _rl_backspace (l);
     2161  for (i = 0; i < l; i++)
     2162    visible_line[--_rl_last_c_pos] = '\0';
     2163  rl_display_fixed++;
     2164}
     2165
     2166/* Clear to the end of the line.  COUNT is the minimum
     2167   number of character spaces to clear, */
     2168void
     2169_rl_clear_to_eol (count)
     2170     int count;
     2171{
     2172  if (_rl_term_clreol)
     2173    tputs (_rl_term_clreol, 1, _rl_output_character_function);
     2174  else if (count)
     2175    space_to_eol (count);
     2176}
     2177
     2178/* Clear to the end of the line using spaces.  COUNT is the minimum
     2179   number of character spaces to clear, */
     2180static void
     2181space_to_eol (count)
     2182     int count;
     2183{
     2184  register int i;
     2185
     2186  for (i = 0; i < count; i++)
     2187   putc (' ', rl_outstream);
     2188
     2189  _rl_last_c_pos += count;
     2190}
     2191
     2192void
     2193_rl_clear_screen ()
     2194{
     2195  if (_rl_term_clrpag)
     2196    tputs (_rl_term_clrpag, 1, _rl_output_character_function);
     2197  else
     2198    rl_crlf ();
     2199}
     2200
     2201/* Insert COUNT characters from STRING to the output stream at column COL. */
     2202static void
     2203insert_some_chars (string, count, col)
     2204     char *string;
     2205     int count, col;
     2206{
     2207#if defined (__MSDOS__) || defined (__MINGW32__)
     2208  _rl_output_some_chars (string, count);
     2209#else
     2210  /* DEBUGGING */
     2211  if (MB_CUR_MAX == 1 || rl_byte_oriented)
     2212    if (count != col)
     2213      fprintf(stderr, "readline: debug: insert_some_chars: count (%d) != col (%d)\n", count, col);
     2214
     2215  /* If IC is defined, then we do not have to "enter" insert mode. */
     2216  if (_rl_term_IC)
     2217    {
     2218      char *buffer;
     2219
     2220      buffer = tgoto (_rl_term_IC, 0, col);
     2221      tputs (buffer, 1, _rl_output_character_function);
     2222      _rl_output_some_chars (string, count);
     2223    }
     2224  else
     2225    {
     2226      register int i;
     2227
     2228      /* If we have to turn on insert-mode, then do so. */
     2229      if (_rl_term_im && *_rl_term_im)
     2230        tputs (_rl_term_im, 1, _rl_output_character_function);
     2231
     2232      /* If there is a special command for inserting characters, then
     2233         use that first to open up the space. */
     2234      if (_rl_term_ic && *_rl_term_ic)
     2235        {
     2236          for (i = col; i--; )
     2237            tputs (_rl_term_ic, 1, _rl_output_character_function);
     2238        }
     2239
     2240      /* Print the text. */
     2241      _rl_output_some_chars (string, count);
     2242
     2243      /* If there is a string to turn off insert mode, we had best use
     2244         it now. */
     2245      if (_rl_term_ei && *_rl_term_ei)
     2246        tputs (_rl_term_ei, 1, _rl_output_character_function);
     2247    }
     2248#endif /* __MSDOS__ || __MINGW32__ */
     2249}
     2250
     2251/* Delete COUNT characters from the display line. */
     2252static void
     2253delete_chars (count)
     2254     int count;
     2255{
     2256  if (count > _rl_screenwidth)  /* XXX */
     2257    return;
     2258
     2259#if !defined (__MSDOS__) && !defined (__MINGW32__)
     2260  if (_rl_term_DC && *_rl_term_DC)
     2261    {
     2262      char *buffer;
     2263      buffer = tgoto (_rl_term_DC, count, count);
     2264      tputs (buffer, count, _rl_output_character_function);
     2265    }
     2266  else
     2267    {
     2268      if (_rl_term_dc && *_rl_term_dc)
     2269        while (count--)
     2270          tputs (_rl_term_dc, 1, _rl_output_character_function);
     2271    }
     2272#endif /* !__MSDOS__ && !__MINGW32__ */
     2273}
     2274
     2275void
     2276_rl_update_final ()
     2277{
     2278  int full_lines;
     2279
     2280  full_lines = 0;
     2281  /* If the cursor is the only thing on an otherwise-blank last line,
     2282     compensate so we don't print an extra CRLF. */
     2283  if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
     2284        visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
     2285    {
     2286      _rl_vis_botlin--;
     2287      full_lines = 1;
     2288    }
     2289  _rl_move_vert (_rl_vis_botlin);
     2290  /* If we've wrapped lines, remove the final xterm line-wrap flag. */
     2291  if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == _rl_screenwidth))
     2292    {
     2293      char *last_line;
     2294
     2295      last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]];
     2296      cpos_buffer_position = -1;        /* don't know where we are in buffer */
     2297      _rl_move_cursor_relative (_rl_screenwidth - 1, last_line);        /* XXX */
     2298      _rl_clear_to_eol (0);
     2299      putc (last_line[_rl_screenwidth - 1], rl_outstream);
     2300    }
     2301  _rl_vis_botlin = 0;
     2302  rl_crlf ();
     2303  fflush (rl_outstream);
     2304  rl_display_fixed++;
     2305}
     2306
     2307/* Move to the start of the current line. */
     2308static void
     2309cr ()
     2310{
     2311  if (_rl_term_cr)
     2312    {
     2313#if defined (__MSDOS__)
     2314      putc ('\r', rl_outstream);
     2315#else
     2316      tputs (_rl_term_cr, 1, _rl_output_character_function);
     2317#endif
     2318      _rl_last_c_pos = 0;
     2319    }
     2320}
     2321
     2322/* Redraw the last line of a multi-line prompt that may possibly contain
     2323   terminal escape sequences.  Called with the cursor at column 0 of the
     2324   line to draw the prompt on. */
     2325static void
     2326redraw_prompt (t)
     2327     char *t;
     2328{
     2329  char *oldp;
     2330
     2331  oldp = rl_display_prompt;
     2332  rl_save_prompt ();
     2333
     2334  rl_display_prompt = t;
     2335  local_prompt = expand_prompt (t, &prompt_visible_length,
     2336                                   &prompt_last_invisible,
     2337                                   &prompt_invis_chars_first_line,
     2338                                   &prompt_physical_chars);
     2339  local_prompt_prefix = (char *)NULL;
     2340  local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
     2341
     2342  rl_forced_update_display ();
     2343
     2344  rl_display_prompt = oldp;
     2345  rl_restore_prompt();
     2346}
     2347     
     2348/* Redisplay the current line after a SIGWINCH is received. */
     2349void
     2350_rl_redisplay_after_sigwinch ()
     2351{
     2352  char *t;
     2353
     2354  /* Clear the current line and put the cursor at column 0.  Make sure
     2355     the right thing happens if we have wrapped to a new screen line. */
     2356  if (_rl_term_cr)
     2357    {
     2358#if defined (__MSDOS__)
     2359      putc ('\r', rl_outstream);
     2360#else
     2361      tputs (_rl_term_cr, 1, _rl_output_character_function);
     2362#endif
     2363      _rl_last_c_pos = 0;
     2364#if defined (__MSDOS__)
     2365      space_to_eol (_rl_screenwidth);
     2366      putc ('\r', rl_outstream);
     2367#else
     2368      if (_rl_term_clreol)
     2369        tputs (_rl_term_clreol, 1, _rl_output_character_function);
     2370      else
     2371        {
     2372          space_to_eol (_rl_screenwidth);
     2373          tputs (_rl_term_cr, 1, _rl_output_character_function);
     2374        }
     2375#endif
     2376      if (_rl_last_v_pos > 0)
     2377        _rl_move_vert (0);
     2378    }
     2379  else
     2380    rl_crlf ();
     2381
     2382  /* Redraw only the last line of a multi-line prompt. */
     2383  t = strrchr (rl_display_prompt, '\n');
     2384  if (t)
     2385    redraw_prompt (++t);
     2386  else
     2387    rl_forced_update_display ();
     2388}
     2389
     2390void
     2391_rl_clean_up_for_exit ()
     2392{
     2393  if (readline_echoing_p)
     2394    {
     2395      _rl_move_vert (_rl_vis_botlin);
     2396      _rl_vis_botlin = 0;
     2397      fflush (rl_outstream);
     2398      rl_restart_output (1, 0);
     2399    }
     2400}
     2401
     2402void
     2403_rl_erase_entire_line ()
     2404{
     2405  cr ();
     2406  _rl_clear_to_eol (0);
     2407  cr ();
     2408  fflush (rl_outstream);
     2409}
     2410
     2411/* return the `current display line' of the cursor -- the number of lines to
     2412   move up to get to the first screen line of the current readline line. */
     2413int
     2414_rl_current_display_line ()
     2415{
     2416  int ret, nleft;
     2417
     2418  /* Find out whether or not there might be invisible characters in the
     2419     editing buffer. */
     2420  if (rl_display_prompt == rl_prompt)
     2421    nleft = _rl_last_c_pos - _rl_screenwidth - rl_visible_prompt_length;
     2422  else
     2423    nleft = _rl_last_c_pos - _rl_screenwidth;
     2424
     2425  if (nleft > 0)
     2426    ret = 1 + nleft / _rl_screenwidth;
     2427  else
     2428    ret = 0;
     2429
     2430  return ret;
     2431}
     2432
     2433#if defined (HANDLE_MULTIBYTE)
     2434/* Calculate the number of screen columns occupied by STR from START to END.
     2435   In the case of multibyte characters with stateful encoding, we have to
     2436   scan from the beginning of the string to take the state into account. */
     2437static int
     2438_rl_col_width (str, start, end)
     2439     const char *str;
     2440     int start, end;
     2441{
     2442  wchar_t wc;
     2443  mbstate_t ps;
     2444  int tmp, point, width, max;
     2445
     2446  if (end <= start)
     2447    return 0;
     2448  if (MB_CUR_MAX == 1 || rl_byte_oriented)
     2449    return (end - start);
     2450
     2451  memset (&ps, 0, sizeof (mbstate_t));
     2452
     2453  point = 0;
     2454  max = end;
     2455
     2456  while (point < start)
     2457    {
     2458      tmp = mbrlen (str + point, max, &ps);
     2459      if (MB_INVALIDCH ((size_t)tmp))
     2460        {
     2461          /* In this case, the bytes are invalid or too short to compose a
     2462             multibyte character, so we assume that the first byte represents
     2463             a single character. */
     2464          point++;
     2465          max--;
     2466
     2467          /* Clear the state of the byte sequence, because in this case the
     2468             effect of mbstate is undefined. */
     2469          memset (&ps, 0, sizeof (mbstate_t));
     2470        }
     2471      else if (MB_NULLWCH (tmp))
     2472        break;          /* Found '\0' */
     2473      else
     2474        {
     2475          point += tmp;
     2476          max -= tmp;
     2477        }
     2478    }
     2479
     2480  /* If START is not a byte that starts a character, then POINT will be
     2481     greater than START.  In this case, assume that (POINT - START) gives
     2482     a byte count that is the number of columns of difference. */
     2483  width = point - start;
     2484
     2485  while (point < end)
     2486    {
     2487      tmp = mbrtowc (&wc, str + point, max, &ps);
     2488      if (MB_INVALIDCH ((size_t)tmp))
     2489        {
     2490          /* In this case, the bytes are invalid or too short to compose a
     2491             multibyte character, so we assume that the first byte represents
     2492             a single character. */
     2493          point++;
     2494          max--;
     2495
     2496          /* and assume that the byte occupies a single column. */
     2497          width++;
     2498
     2499          /* Clear the state of the byte sequence, because in this case the
     2500             effect of mbstate is undefined. */
     2501          memset (&ps, 0, sizeof (mbstate_t));
     2502        }
     2503      else if (MB_NULLWCH (tmp))
     2504        break;                  /* Found '\0' */
     2505      else
     2506        {
     2507          point += tmp;
     2508          max -= tmp;
     2509          tmp = wcwidth(wc);
     2510          width += (tmp >= 0) ? tmp : 1;
     2511        }
     2512    }
     2513
     2514  width += point - end;
     2515
     2516  return width;
     2517}
     2518#endif /* HANDLE_MULTIBYTE */
  • lib/readline/input.c

    diff -Naur bash-3.2.orig/lib/readline/input.c bash-3.2/lib/readline/input.c
    old new  
    133133    return (0);
    134134
    135135  *key = ibuffer[pop_index++];
    136 
     136#if 0
    137137  if (pop_index >= ibuffer_len)
     138#else
     139  if (pop_index > ibuffer_len)
     140#endif
    138141    pop_index = 0;
    139142
    140143  return (1);
     
    151154    {
    152155      pop_index--;
    153156      if (pop_index < 0)
    154         pop_index = ibuffer_len - 1;
     157        pop_index = ibuffer_len;
    155158      ibuffer[pop_index] = key;
    156159      return (1);
    157160    }
     
    250253      while (chars_avail--)
    251254        {
    252255          k = (*rl_getc_function) (rl_instream);
    253           rl_stuff_char (k);
     256          if (rl_stuff_char (k) == 0)
     257            break;                      /* some problem; no more room */
    254258          if (k == NEWLINE || k == RETURN)
    255259            break;
    256260        }
     
    373377      RL_SETSTATE (RL_STATE_INPUTPENDING);
    374378    }
    375379  ibuffer[push_index++] = key;
     380#if 0
    376381  if (push_index >= ibuffer_len)
     382#else
     383  if (push_index > ibuffer_len)
     384#endif
    377385    push_index = 0;
    378386
    379387  return 1;
     
    513521     char *mbchar;
    514522     int size;
    515523{
    516   int mb_len = 0;
     524  int mb_len, c;
    517525  size_t mbchar_bytes_length;
    518526  wchar_t wc;
    519527  mbstate_t ps, ps_back;
    520528
    521529  memset(&ps, 0, sizeof (mbstate_t));
    522530  memset(&ps_back, 0, sizeof (mbstate_t));
    523  
     531
     532  mb_len = 0; 
    524533  while (mb_len < size)
    525534    {
    526535      RL_SETSTATE(RL_STATE_MOREINPUT);
    527       mbchar[mb_len++] = rl_read_key ();
     536      c = rl_read_key ();
    528537      RL_UNSETSTATE(RL_STATE_MOREINPUT);
    529538
     539      if (c < 0)
     540        break;
     541
     542      mbchar[mb_len++] = c;
     543
    530544      mbchar_bytes_length = mbrtowc (&wc, mbchar, mb_len, &ps);
    531545      if (mbchar_bytes_length == (size_t)(-1))
    532546        break;          /* invalid byte sequence for the current locale */
     
    564578
    565579  c = first;
    566580  memset (mb, 0, mlen);
    567   for (i = 0; i < mlen; i++)
     581  for (i = 0; c >= 0 && i < mlen; i++)
    568582    {
    569583      mb[i] = (char)c;
    570584      memset (&ps, 0, sizeof (mbstate_t));
  • lib/readline/isearch.c

    diff -Naur bash-3.2.orig/lib/readline/isearch.c bash-3.2/lib/readline/isearch.c
    old new  
    327327  rl_command_func_t *f;
    328328
    329329  f = (rl_command_func_t *)NULL;
    330  
    331  /* Translate the keys we do something with to opcodes. */
     330
     331  if (c < 0)
     332    {
     333      cxt->sflags |= SF_FAILED;
     334      cxt->history_pos = cxt->last_found_line;
     335      return -1;
     336    }
     337
     338  /* Translate the keys we do something with to opcodes. */
    332339  if (c >= 0 && _rl_keymap[c].type == ISFUNC)
    333340    {
    334341      f = _rl_keymap[c].function;
  • lib/readline/misc.c

    diff -Naur bash-3.2.orig/lib/readline/misc.c bash-3.2/lib/readline/misc.c
    old new  
    146146          rl_restore_prompt ();
    147147          rl_clear_message ();
    148148          RL_UNSETSTATE(RL_STATE_NUMERICARG);
     149          if (key < 0)
     150            return -1;
    149151          return (_rl_dispatch (key, _rl_keymap));
    150152        }
    151153    }
  • lib/readline/readline.c

    diff -Naur bash-3.2.orig/lib/readline/readline.c bash-3.2/lib/readline/readline.c
    old new  
    645645  if ((cxt->flags & KSEQ_DISPATCHED) == 0)
    646646    {
    647647      nkey = _rl_subseq_getchar (cxt->okey);
     648      if (nkey < 0)
     649        {
     650          _rl_abort_internal ();
     651          return -1;
     652        }
    648653      r = _rl_dispatch_subseq (nkey, cxt->dmap, cxt->subseq_arg);
    649654      cxt->flags |= KSEQ_DISPATCHED;
    650655    }
  • lib/readline/text.c

    diff -Naur bash-3.2.orig/lib/readline/text.c bash-3.2/lib/readline/text.c
    old new  
    857857  c = rl_read_key ();
    858858  RL_UNSETSTATE(RL_STATE_MOREINPUT);
    859859
     860  if (c < 0)
     861    return -1;
     862
    860863#if defined (HANDLE_SIGNALS)
    861864  if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
    862865    _rl_restore_tty_signals ();
     
    15201523
    15211524  mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
    15221525
     1526  if (mb_len <= 0)
     1527    return -1;
     1528
    15231529  if (count < 0)
    15241530    return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
    15251531  else
     
    15361542  c = rl_read_key ();
    15371543  RL_UNSETSTATE(RL_STATE_MOREINPUT);
    15381544
     1545  if (c < 0)
     1546    return -1;
     1547
    15391548  if (count < 0)
    15401549    return (_rl_char_search_internal (-count, bdir, c));
    15411550  else
  • lib/readline/vi_mode.c

    diff -Naur bash-3.2.orig/lib/readline/vi_mode.c bash-3.2/lib/readline/vi_mode.c
    old new  
    886886  RL_SETSTATE(RL_STATE_MOREINPUT);
    887887  c = rl_read_key ();
    888888  RL_UNSETSTATE(RL_STATE_MOREINPUT);
     889
     890  if (c < 0)
     891    {
     892      *nextkey = 0;
     893      return -1;
     894    }
     895
    889896  *nextkey = c;
    890897
    891898  if (!member (c, vi_motion))
     
    902909          RL_SETSTATE(RL_STATE_MOREINPUT);
    903910          c = rl_read_key ();   /* real command */
    904911          RL_UNSETSTATE(RL_STATE_MOREINPUT);
     912          if (c < 0)
     913            {
     914              *nextkey = 0;
     915              return -1;
     916            }
    905917          *nextkey = c;
    906918        }
    907919      else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
     
    12241236_rl_vi_callback_char_search (data)
    12251237     _rl_callback_generic_arg *data;
    12261238{
     1239  int c;
    12271240#if defined (HANDLE_MULTIBYTE)
    1228   _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
     1241  c = _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
    12291242#else
    12301243  RL_SETSTATE(RL_STATE_MOREINPUT);
    1231   _rl_vi_last_search_char = rl_read_key ();
     1244  c = rl_read_key ();
    12321245  RL_UNSETSTATE(RL_STATE_MOREINPUT);
    12331246#endif
    12341247
     1248  if (c <= 0)
     1249    return -1;
     1250
     1251#if !defined (HANDLE_MULTIBYTE)
     1252  _rl_vi_last_search_char = c;
     1253#endif
     1254
    12351255  _rl_callback_func = 0;
    12361256  _rl_want_redisplay = 1;
    12371257
     
    12471267rl_vi_char_search (count, key)
    12481268     int count, key;
    12491269{
     1270  int c;
    12501271#if defined (HANDLE_MULTIBYTE)
    12511272  static char *target;
    12521273  static int tlen;
     
    12931314      else
    12941315        {
    12951316#if defined (HANDLE_MULTIBYTE)
    1296           _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
     1317          c = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
     1318          if (c <= 0)
     1319            return -1;
     1320          _rl_vi_last_search_mblen = c;
    12971321#else
    12981322          RL_SETSTATE(RL_STATE_MOREINPUT);
    1299           _rl_vi_last_search_char = rl_read_key ();
     1323          c = rl_read_key ();
    13001324          RL_UNSETSTATE(RL_STATE_MOREINPUT);
     1325          if (c < 0)
     1326            return -1;
     1327          _rl_vi_last_search_char = c;
    13011328#endif
    13021329        }
    13031330    }
     
    14671494  c = rl_read_key ();
    14681495  RL_UNSETSTATE(RL_STATE_MOREINPUT);
    14691496
     1497  if (c < 0)
     1498    return -1;
     1499
    14701500#if defined (HANDLE_MULTIBYTE)
    14711501  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
    14721502    c = _rl_read_mbstring (c, mb, mlen);
     
    14851515
    14861516  _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
    14871517
     1518  if (c < 0)
     1519    return -1;
     1520
    14881521  _rl_callback_func = 0;
    14891522  _rl_want_redisplay = 1;
    14901523
     
    15161549  else
    15171550    _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
    15181551
     1552  if (c < 0)
     1553    return -1;
     1554
    15191555  return (_rl_vi_change_char (count, c, mb));
    15201556}
    15211557
     
    16501686  ch = rl_read_key ();
    16511687  RL_UNSETSTATE(RL_STATE_MOREINPUT);
    16521688
    1653   if (ch < 'a' || ch > 'z')
     1689  if (ch < 0 || ch < 'a' || ch > 'z')   /* make test against 0 explicit */
    16541690    {
    16551691      rl_ding ();
    16561692      return -1;
     
    17021738      rl_point = rl_mark;
    17031739      return 0;
    17041740    }
    1705   else if (ch < 'a' || ch > 'z')
     1741  else if (ch < 0 || ch < 'a' || ch > 'z')      /* make test against 0 explicit */
    17061742    {
    17071743      rl_ding ();
    17081744      return -1;
  • lib/sh/snprintf.c

    diff -Naur bash-3.2.orig/lib/sh/snprintf.c bash-3.2/lib/sh/snprintf.c
    old new  
    471471          10^x ~= r
    472472 * log_10(200) = 2;
    473473 * log_10(250) = 2;
     474 *
     475 * NOTE: do not call this with r == 0 -- an infinite loop results.
    474476 */
    475477static int
    476478log_10(r)
     
    576578    {
    577579      integral_part[0] = '0';
    578580      integral_part[1] = '\0';
    579       fraction_part[0] = '0';
    580       fraction_part[1] = '\0';
     581      /* The fractional part has to take the precision into account */
     582      for (ch = 0; ch < precision-1; ch++)
     583        fraction_part[ch] = '0';
     584      fraction_part[ch] = '0';
     585      fraction_part[ch+1] = '\0';
    581586      if (fract)
    582587        *fract = fraction_part;
    583588      return integral_part;
     
    663668    p->flags &= ~PF_ZEROPAD;
    664669
    665670  sd = d;       /* signed for ' ' padding in base 10 */
    666   flags = (*p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
     671  flags = 0;
     672  flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
    667673  if (*p->pf == 'X')
    668674    flags |= FL_HEXUPPER;
    669675
     
    733739    p->flags &= ~PF_ZEROPAD;
    734740
    735741  sd = d;       /* signed for ' ' padding in base 10 */
    736   flags = (*p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
     742  flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
    737743  if (*p->pf == 'X')
    738744    flags |= FL_HEXUPPER;
    739745
     
    805811      PUT_CHAR(*tmp, p);
    806812      tmp++;
    807813    }
     814
    808815  PAD_LEFT(p);
    809816}
    810817
     
    972979  if ((p->flags & PF_THOUSANDS) && grouping && (t = groupnum (tmp)))
    973980    tmp = t;
    974981
     982  if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0)
     983    {
     984      /* smash the trailing zeros unless altform */
     985      for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
     986        tmp2[i] = '\0';
     987      if (tmp2[0] == '\0')
     988        p->precision = 0;
     989    }
     990
    975991  /* calculate the padding. 1 for the dot */
    976992  p->width = p->width -
    977993            ((d > 0. && p->justify == RIGHT) ? 1:0) -
    978994            ((p->flags & PF_SPACE) ? 1:0) -
    979             strlen(tmp) - p->precision - 1;
     995            strlen(tmp) - p->precision -
     996            ((p->precision != 0 || (p->flags & PF_ALTFORM)) ? 1 : 0);   /* radix char */
    980997  PAD_RIGHT(p); 
    981998  PUT_PLUS(d, p, 0.);
    982999  PUT_SPACE(d, p, 0.);
     
    9911008  if (p->precision != 0 || (p->flags & PF_ALTFORM))
    9921009    PUT_CHAR(decpoint, p);  /* put the '.' */
    9931010
    994   if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0)
    995     /* smash the trailing zeros unless altform */
    996     for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
    997       tmp2[i] = '\0';
    998 
    9991011  for (; *tmp2; tmp2++)
    10001012    PUT_CHAR(*tmp2, p); /* the fraction */
    10011013 
     
    10111023  char *tmp, *tmp2;
    10121024  int j, i;
    10131025
    1014   if (chkinfnan(p, d, 1) || chkinfnan(p, d, 2))
     1026  if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2)))
    10151027    return;     /* already printed nan or inf */
    10161028
    10171029  GETLOCALEDATA(decpoint, thoussep, grouping);
    10181030  DEF_PREC(p);
    1019   j = log_10(d);
    1020   d = d / pow_10(j);  /* get the Mantissa */
    1021   d = ROUND(d, p);               
     1031  if (d == 0.)
     1032    j = 0;
     1033  else
     1034    {
     1035      j = log_10(d);
     1036      d = d / pow_10(j);  /* get the Mantissa */
     1037      d = ROUND(d, p);           
     1038    }
    10221039  tmp = dtoa(d, p->precision, &tmp2);
    10231040
    10241041  /* 1 for unit, 1 for the '.', 1 for 'e|E',
     
    10761093       PUT_CHAR(*tmp, p);
    10771094       tmp++;
    10781095     }
     1096
    10791097   PAD_LEFT(p);
    10801098}
    10811099#endif
     
    13581376                STAR_ARGS(data);
    13591377                DEF_PREC(data);
    13601378                d = GETDOUBLE(data);
    1361                 i = log_10(d);
     1379                i = (d != 0.) ? log_10(d) : -1;
    13621380                /*
    13631381                 * for '%g|%G' ANSI: use f if exponent
    13641382                 * is in the range or [-4,p] exclusively
  • parse.y

    diff -Naur bash-3.2.orig/parse.y bash-3.2/parse.y
    old new  
    10291029#define PST_CMDTOKEN    0x1000          /* command token OK - unused */
    10301030#define PST_COMPASSIGN  0x2000          /* parsing x=(...) compound assignment */
    10311031#define PST_ASSIGNOK    0x4000          /* assignment statement ok in this context */
     1032#define PST_REGEXP      0x8000          /* parsing an ERE/BRE as a single word */
    10321033
    10331034/* Initial size to allocate for tokens, and the
    10341035   amount to grow them by. */
     
    25912592      return (character);
    25922593    }
    25932594
     2595  if (parser_state & PST_REGEXP)
     2596    goto tokword;
     2597
    25942598  /* Shell meta-characters. */
    25952599  if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
    25962600    {
     
    26982702  if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
    26992703    return (character);
    27002704
     2705tokword:
    27012706  /* Okay, if we got this far, we have to read a word.  Read one,
    27022707     and then check it against the known ones. */
    27032708  result = read_token_word (character);
     
    27352740/* itrace("parse_matched_pair: open = %c close = %c", open, close); */
    27362741  count = 1;
    27372742  pass_next_character = backq_backslash = was_dollar = in_comment = 0;
    2738   check_comment = (flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0;
     2743  check_comment = (flags & P_COMMAND) && qc != '`' && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0;
    27392744
    27402745  /* RFLAGS is the set of flags we want to pass to recursive calls. */
    27412746  rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE);
     
    32023207      if (tok == WORD && test_binop (yylval.word->word))
    32033208        op = yylval.word;
    32043209#if defined (COND_REGEXP)
    3205       else if (tok == WORD && STREQ (yylval.word->word,"=~"))
    3206         op = yylval.word;
     3210      else if (tok == WORD && STREQ (yylval.word->word, "=~"))
     3211        {
     3212          op = yylval.word;
     3213          parser_state |= PST_REGEXP;
     3214        }
    32073215#endif
    32083216      else if (tok == '<' || tok == '>')
    32093217        op = make_word_from_token (tok);  /* ( */
     
    32343242
    32353243      /* rhs */
    32363244      tok = read_token (READ);
     3245      parser_state &= ~PST_REGEXP;
    32373246      if (tok == WORD)
    32383247        {
    32393248          tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
     
    33673376      if (pass_next_character)
    33683377        {
    33693378          pass_next_character = 0;
    3370           goto got_character;
     3379          goto got_escaped_character;
    33713380        }
    33723381
    33733382      cd = current_delimiter (dstack);
     
    34193428          goto next_character;
    34203429        }
    34213430
     3431#ifdef COND_REGEXP
     3432      /* When parsing a regexp as a single word inside a conditional command,
     3433         we need to special-case characters special to both the shell and
     3434         regular expressions.  Right now, that is only '(' and '|'. */ /*)*/
     3435      if MBTEST((parser_state & PST_REGEXP) && (character == '(' || character == '|'))          /*)*/
     3436        {
     3437          if (character == '|')
     3438            goto got_character;
     3439
     3440          push_delimiter (dstack, character);
     3441          ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
     3442          pop_delimiter (dstack);
     3443          if (ttok == &matched_pair_error)
     3444            return -1;          /* Bail immediately. */
     3445          RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
     3446                                  token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
     3447          token[token_index++] = character;
     3448          strcpy (token + token_index, ttok);
     3449          token_index += ttoklen;
     3450          FREE (ttok);
     3451          dollar_present = all_digit_token = 0;
     3452          goto next_character;
     3453        }
     3454#endif /* COND_REGEXP */
     3455
    34223456#ifdef EXTENDED_GLOB
    34233457      /* Parse a ksh-style extended pattern matching specification. */
    3424       if (extended_glob && PATTERN_CHAR (character))
     3458      if MBTEST(extended_glob && PATTERN_CHAR (character))
    34253459        {
    34263460          peek_char = shell_getc (1);
    34273461          if MBTEST(peek_char == '(')           /* ) */
     
    36163650
    36173651    got_character:
    36183652
    3619       all_digit_token &= DIGIT (character);
    3620       dollar_present |= character == '$';
    3621 
    36223653      if (character == CTLESC || character == CTLNUL)
    36233654        token[token_index++] = CTLESC;
    36243655
     3656    got_escaped_character:
     3657
     3658      all_digit_token &= DIGIT (character);
     3659      dollar_present |= character == '$';
     3660
    36253661      token[token_index++] = character;
    36263662
    36273663      RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
  • patchlevel.h

    diff -Naur bash-3.2.orig/patchlevel.h bash-3.2/patchlevel.h
    old new  
    2525   regexp `^#define[    ]*PATCHLEVEL', since that's what support/mkversion.sh
    2626   looks for to find the patch level (for the sccs version string). */
    2727
    28 #define PATCHLEVEL 0
     28#define PATCHLEVEL 33
    2929
    3030#endif /* _PATCHLEVEL_H_ */
  • pathexp.c

    diff -Naur bash-3.2.orig/pathexp.c bash-3.2/pathexp.c
    old new  
    11/* pathexp.c -- The shell interface to the globbing library. */
    22
    3 /* Copyright (C) 1995-2002 Free Software Foundation, Inc.
     3/* Copyright (C) 1995-2007 Free Software Foundation, Inc.
    44
    55   This file is part of GNU Bash, the Bourne Again SHell.
    66
     
    110110  return (0);
    111111}
    112112
     113/* Return 1 if C is a character that is `special' in a POSIX ERE and needs to
     114   be quoted to match itself. */
     115static inline int
     116ere_char (c)
     117     int c;
     118{
     119  switch (c)
     120    {
     121    case '.':
     122    case '[':
     123    case '\\':
     124    case '(':
     125    case ')':
     126    case '*':
     127    case '+':
     128    case '?':
     129    case '{':
     130    case '|':
     131    case '^':
     132    case '$':
     133      return 1;
     134    default:
     135      return 0;
     136    }
     137  return (0);
     138}
     139
    113140/* PATHNAME can contain characters prefixed by CTLESC; this indicates
    114141   that the character is to be quoted.  We quote it here in the style
    115142   that the glob library recognizes.  If flags includes QGLOB_CVTNULL,
     
    142169        {
    143170          if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/')
    144171            continue;
     172          if ((qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0)
     173            continue;
    145174          temp[j++] = '\\';
    146175          i++;
    147176          if (pathname[i] == '\0')
  • pathexp.h

    diff -Naur bash-3.2.orig/pathexp.h bash-3.2/pathexp.h
    old new  
    11/* pathexp.h -- The shell interface to the globbing library. */
    22
    3 /* Copyright (C) 1987-2005 Free Software Foundation, Inc.
     3/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
    44
    55   This file is part of GNU Bash, the Bourne Again SHell.
    66
     
    3232/* Flag values for quote_string_for_globbing */
    3333#define QGLOB_CVTNULL   0x01    /* convert QUOTED_NULL strings to '\0' */
    3434#define QGLOB_FILENAME  0x02    /* do correct quoting for matching filenames */
     35#define QGLOB_REGEXP    0x04    /* quote an ERE for regcomp/regexec */
    3536
    3637#if defined (EXTENDED_GLOB)
    3738/* Flags to OR with other flag args to strmatch() to enabled the extended
  • po/ru.po

    diff -Naur bash-3.2.orig/po/ru.po bash-3.2/po/ru.po
    old new  
    1212"Last-Translator: Evgeniy Dushistov <dushistov@mail.ru>\n"
    1313"Language-Team: Russian <ru@li.org>\n"
    1414"MIME-Version: 1.0\n"
    15 "Content-Type: text/plain; charset=UTF-8\n"
     15"Content-Type: text/plain; charset=KOI8-R\n"
    1616"Content-Transfer-Encoding: 8bit\n"
    1717"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
    1818
  • bash-3.2

    diff -Naur bash-3.2.orig/sig.c bash-3.2/sig.c
    old new  
    350350#undef XSIG
    351351#undef XHANDLER
    352352
     353/* Run some of the cleanups that should be performed when we run
     354   jump_to_top_level from a builtin command context.  XXX - might want to
     355   also call reset_parser here. */
     356void
     357top_level_cleanup ()
     358{
     359  /* Clean up string parser environment. */
     360  while (parse_and_execute_level)
     361    parse_and_execute_cleanup ();
     362
     363#if defined (PROCESS_SUBSTITUTION)
     364  unlink_fifo_list ();
     365#endif /* PROCESS_SUBSTITUTION */
     366
     367  run_unwind_protects ();
     368  loop_level = continuing = breaking = 0;
     369  return_catch_flag = 0;
     370}
     371
    353372/* What to do when we've been interrupted, and it is safe to handle it. */
    354373void
    355374throw_to_top_level ()
  • bash-3.2

    diff -Naur bash-3.2.orig/sig.h bash-3.2/sig.h
    old new  
    121121extern void initialize_signals __P((int));
    122122extern void initialize_terminating_signals __P((void));
    123123extern void reset_terminating_signals __P((void));
     124extern void top_level_cleanup __P((void));
    124125extern void throw_to_top_level __P((void));
    125126extern void jump_to_top_level __P((int)) __attribute__((__noreturn__));
    126127
  • subst.c

    diff -Naur bash-3.2.orig/subst.c bash-3.2/subst.c
    old new  
    44/* ``Have a little faith, there's magic in the night.  You ain't a
    55     beauty, but, hey, you're alright.'' */
    66
    7 /* Copyright (C) 1987-2006 Free Software Foundation, Inc.
     7/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
    88
    99   This file is part of GNU Bash, the Bourne Again SHell.
    1010
     
    12781278    {
    12791279      if (no_longjmp_on_fatal_error == 0)
    12801280        {                       /* { */
    1281           report_error ("bad substitution: no closing `%s' in %s", "}", string);
     1281          report_error (_("bad substitution: no closing `%s' in %s"), "}", string);
    12821282          last_command_exit_value = EXECUTION_FAILURE;
    12831283          exp_jump_to_top_level (DISCARD);
    12841284        }
     
    18871887  sep[1] = '\0';
    18881888#endif
    18891889
     1890  /* XXX -- why call quote_list if ifs == 0?  we can get away without doing
     1891     it now that quote_escapes quotes spaces */
     1892#if 0
    18901893  tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
     1894#else
     1895  tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
     1896#endif
    18911897                ? quote_list (list)
    18921898                : list_quote_escapes (list);
    18931899
     
    26462652
    26472653/* This needs better error handling. */
    26482654/* Expand W for use as an argument to a unary or binary operator in a
    2649    [[...]] expression.  If SPECIAL is nonzero, this is the rhs argument
     2655   [[...]] expression.  If SPECIAL is 1, this is the rhs argument
    26502656   to the != or == operator, and should be treated as a pattern.  In
    2651    this case, we quote the string specially for the globbing code.  The
    2652    caller is responsible for removing the backslashes if the unquoted
    2653    words is needed later. */   
     2657   this case, we quote the string specially for the globbing code.  If
     2658   SPECIAL is 2, this is an rhs argument for the =~ operator, and should
     2659   be quoted appropriately for regcomp/regexec.  The caller is responsible
     2660   for removing the backslashes if the unquoted word is needed later. */   
    26542661char *
    26552662cond_expand_word (w, special)
    26562663     WORD_DESC *w;
     
    26582665{
    26592666  char *r, *p;
    26602667  WORD_LIST *l;
     2668  int qflags;
    26612669
    26622670  if (w->word == 0 || w->word[0] == '\0')
    26632671    return ((char *)NULL);
     
    26722680        }
    26732681      else
    26742682        {
     2683          qflags = QGLOB_CVTNULL;
     2684          if (special == 2)
     2685            qflags |= QGLOB_REGEXP;
    26752686          p = string_list (l);
    2676           r = quote_string_for_globbing (p, QGLOB_CVTNULL);
     2687          r = quote_string_for_globbing (p, qflags);
    26772688          free (p);
    26782689        }
    26792690      dispose_words (l);
     
    29162927
    29172928/* Quote escape characters in string s, but no other characters.  This is
    29182929   used to protect CTLESC and CTLNUL in variable values from the rest of
    2919    the word expansion process after the variable is expanded. */
     2930   the word expansion process after the variable is expanded.  If IFS is
     2931   null, we quote spaces as well, just in case we split on spaces later
     2932   (in the case of unquoted $@, we will eventually attempt to split the
     2933   entire word on spaces).  Corresponding code exists in dequote_escapes.
     2934   Even if we don't end up splitting on spaces, quoting spaces is not a
     2935   problem. */
    29202936char *
    29212937quote_escapes (string)
    29222938     char *string;
     
    29242940  register char *s, *t;
    29252941  size_t slen;
    29262942  char *result, *send;
     2943  int quote_spaces;
    29272944  DECLARE_MBSTATE;
    29282945
    29292946  slen = strlen (string);
    29302947  send = string + slen;
    29312948
     2949  quote_spaces = (ifs_value && *ifs_value == 0);
    29322950  t = result = (char *)xmalloc ((slen * 2) + 1);
    29332951  s = string;
    29342952
    29352953  while (*s)
    29362954    {
    2937       if (*s == CTLESC || *s == CTLNUL)
     2955      if (*s == CTLESC || *s == CTLNUL || (quote_spaces && *s == ' '))
    29382956        *t++ = CTLESC;
    29392957      COPY_CHAR_P (t, s, send);
    29402958    }
     
    29762994  register char *s, *t;
    29772995  size_t slen;
    29782996  char *result, *send;
     2997  int quote_spaces;
    29792998  DECLARE_MBSTATE;
    29802999
    29813000  if (string == 0)
     
    29903009  if (strchr (string, CTLESC) == 0)
    29913010    return (strcpy (result, s));
    29923011
     3012  quote_spaces = (ifs_value && *ifs_value == 0);
    29933013  while (*s)
    29943014    {
    2995       if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL))
     3015      if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' ')))
    29963016        {
    29973017          s++;
    29983018          if (*s == '\0')
     
    39543974  if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
    39553975    patstr++;
    39563976
    3957   pattern = getpattern (patstr, quoted, 1);
     3977  /* Need to pass getpattern newly-allocated memory in case of expansion --
     3978     the expansion code will free the passed string on an error. */
     3979  temp1 = savestring (patstr);
     3980  pattern = getpattern (temp1, quoted, 1);
     3981  free (temp1);
    39583982
    39593983  temp1 = (char *)NULL;         /* shut up gcc */
    39603984  switch (vtype)
     
    41234147    nfifo = 0;
    41244148}
    41254149
     4150int
     4151fifos_pending ()
     4152{
     4153  return nfifo;
     4154}
     4155
    41264156static char *
    41274157make_named_pipe ()
    41284158{
     
    41724202  nfds++;
    41734203}
    41744204
     4205int
     4206fifos_pending ()
     4207{
     4208  return 0;     /* used for cleanup; not needed with /dev/fd */
     4209}
     4210
    41754211void
    41764212unlink_fifo_list ()
    41774213{
     
    44564492      /* Add the character to ISTRING, possibly after resizing it. */
    44574493      RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
    44584494
    4459       if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || c == CTLESC || c == CTLNUL)
     4495      /* This is essentially quote_string inline */
     4496      if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
     4497        istring[istring_index++] = CTLESC;
     4498      /* Escape CTLESC and CTLNUL in the output to protect those characters
     4499         from the rest of the word expansions (word splitting and globbing.)
     4500         This is essentially quote_escapes inline. */
     4501      else if (c == CTLESC)
     4502        istring[istring_index++] = CTLESC;
     4503      else if (c == CTLNUL || (c == ' ' && (ifs_value && *ifs_value == 0)))
    44604504        istring[istring_index++] = CTLESC;
    44614505
    44624506      istring[istring_index++] = c;
     
    46654709
    46664710      last_command_exit_value = rc;
    46674711      rc = run_exit_trap ();
     4712#if defined (PROCESS_SUBSTITUTION)
     4713      unlink_fifo_list ();
     4714#endif
    46684715      exit (rc);
    46694716    }
    46704717  else
     
    48604907  char *temp, *tt;
    48614908  intmax_t arg_index;
    48624909  SHELL_VAR *var;
    4863   int atype;
     4910  int atype, rflags;
    48644911
    48654912  ret = 0;
    48664913  temp = 0;
     4914  rflags = 0;
    48674915
    48684916  /* Handle multiple digit arguments, as in ${11}. */ 
    48694917  if (legal_number (name, &arg_index))
     
    48964944        temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
    48974945                  ? quote_string (temp)
    48984946                  : quote_escapes (temp);
     4947      else if (atype == 1 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
     4948        rflags |= W_HASQUOTEDNULL;
    48994949    }
    49004950#endif
    49014951  else if (var = find_variable (name))
     
    49234973    {
    49244974      ret = alloc_word_desc ();
    49254975      ret->word = temp;
     4976      ret->flags |= rflags;
    49264977    }
    49274978  return ret;
    49284979}
     
    55465597         so verify_substring_values just returns the numbers specified and we
    55475598         rely on array_subrange to understand how to deal with them). */
    55485599      tt = array_subrange (array_cell (v), e1, e2, starsub, quoted);
     5600#if 0
     5601      /* array_subrange now calls array_quote_escapes as appropriate, so the
     5602         caller no longer needs to. */
    55495603      if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
    55505604        {
    55515605          temp = tt ? quote_escapes (tt) : (char *)NULL;
    55525606          FREE (tt);
    55535607        }
    55545608      else
     5609#endif
    55555610        temp = tt;
    55565611      break;
    55575612#endif
     
    57075762  vtype &= ~VT_STARSUB;
    57085763
    57095764  mflags = 0;
     5765  if (patsub && *patsub == '/')
     5766    {
     5767      mflags |= MATCH_GLOBREP;
     5768      patsub++;
     5769    }
    57105770
    57115771  /* Malloc this because expand_string_if_necessary or one of the expansion
    57125772     functions in its call chain may free it on a substitution error. */
     
    57415801    }
    57425802
    57435803  /* ksh93 doesn't allow the match specifier to be a part of the expanded
    5744      pattern.  This is an extension. */
     5804     pattern.  This is an extension.  Make sure we don't anchor the pattern
     5805     at the beginning or end of the string if we're doing global replacement,
     5806     though. */
    57455807  p = pat;
    5746   if (pat && pat[0] == '/')
    5747     {
    5748       mflags |= MATCH_GLOBREP|MATCH_ANY;
    5749       p++;
    5750     }
     5808  if (mflags & MATCH_GLOBREP)
     5809    mflags |= MATCH_ANY;
    57515810  else if (pat && pat[0] == '#')
    57525811    {
    57535812      mflags |= MATCH_BEG;
     
    57985857#if defined (ARRAY_VARS)
    57995858    case VT_ARRAYVAR:
    58005859      temp = array_patsub (array_cell (v), p, rep, mflags);
     5860#if 0
     5861      /* Don't need to do this anymore; array_patsub calls array_quote_escapes
     5862         as appropriate before adding the space separators. */
    58015863      if (temp && (mflags & MATCH_QUOTED) == 0)
    58025864        {
    58035865          tt = quote_escapes (temp);
    58045866          free (temp);
    58055867          temp = tt;
    58065868        }
     5869#endif
    58075870      break;
    58085871#endif
    58095872    }
     
    76077670  expand_no_split_dollar_star = 0;      /* XXX */
    76087671  expanding_redir = 0;
    76097672
     7673  top_level_cleanup ();                 /* from sig.c */
     7674
    76107675  jump_to_top_level (v);
    76117676}
    76127677
     
    78247889          else if (fail_glob_expansion != 0)
    78257890            {
    78267891              report_error (_("no match: %s"), tlist->word->word);
    7827               jump_to_top_level (DISCARD);
     7892              exp_jump_to_top_level (DISCARD);
    78287893            }
    78297894          else if (allow_null_glob_expansion == 0)
    78307895            {
  • subst.h

    diff -Naur bash-3.2.orig/subst.h bash-3.2/subst.h
    old new  
    222222extern char *command_substitute __P((char *, int));
    223223extern char *pat_subst __P((char *, char *, char *, int));
    224224
     225extern int fifos_pending __P((void));
    225226extern void unlink_fifo_list __P((void));
    226227
    227228extern WORD_LIST *list_string_with_quotes __P((char *));
  • tests/new-exp.right

    diff -Naur bash-3.2.orig/tests/new-exp.right bash-3.2/tests/new-exp.right
    old new  
    430430Case06---1---A B C::---
    431431Case07---3---A:B:C---
    432432Case08---3---A:B:C---
    433 ./new-exp.tests: line 506: /${$(($#-1))}: bad substitution
     433./new-exp.tests: line 506: ${$(($#-1))}: bad substitution
    434434argv[1] = <a>
    435435argv[2] = <b>
    436436argv[3] = <c>
  • variables.c

    diff -Naur bash-3.2.orig/variables.c bash-3.2/variables.c
    old new  
    18211821          oval = value_cell (var);
    18221822          lval = evalexp (oval, &expok);        /* ksh93 seems to do this */
    18231823          if (expok == 0)
    1824             jump_to_top_level (DISCARD);
     1824            {
     1825              top_level_cleanup ();
     1826              jump_to_top_level (DISCARD);
     1827            }
    18251828        }
    18261829      rval = evalexp (value, &expok);
    18271830      if (expok == 0)
    1828         jump_to_top_level (DISCARD);
     1831        {
     1832          top_level_cleanup ();
     1833          jump_to_top_level (DISCARD);
     1834        }
    18291835      if (flags & ASS_APPEND)
    18301836        rval += lval;
    18311837      retval = itos (rval);
  • version.c

    diff -Naur bash-3.2.orig/version.c bash-3.2/version.c
    old new  
    7979{
    8080  printf ("GNU bash, version %s (%s)\n", shell_version_string (), MACHTYPE);
    8181  if (extended)
    82     printf (_("Copyright (C) 2005 Free Software Foundation, Inc.\n"));
     82    printf (_("Copyright (C) 2007 Free Software Foundation, Inc.\n"));
    8383}
Note: See TracBrowser for help on using the repository browser.