[e1234d4] | 1 | Submitted By: Jim Gifford (jim at linuxfromscratch dot org)
|
---|
| 2 | Date: 12-20-2007
|
---|
| 3 | Initial Package Version: 3.2
|
---|
| 4 | Origin: Upstream
|
---|
| 5 | Upstream Status: Applied
|
---|
| 6 | Description: Contains all upstream patches up to 3.2-033
|
---|
| 7 |
|
---|
| 8 | diff -Naur bash-3.2.orig/array.c bash-3.2/array.c
|
---|
| 9 | --- bash-3.2.orig/array.c 2005-06-01 16:39:22.000000000 -0400
|
---|
| 10 | +++ bash-3.2/array.c 2007-12-20 23:53:03.000000000 -0500
|
---|
| 11 | @@ -120,7 +120,6 @@
|
---|
| 12 | return(a1);
|
---|
| 13 | }
|
---|
| 14 |
|
---|
| 15 | -#ifdef INCLUDE_UNUSED
|
---|
| 16 | /*
|
---|
| 17 | * Make and return a new array composed of the elements in array A from
|
---|
| 18 | * S to E, inclusive.
|
---|
| 19 | @@ -141,13 +140,12 @@
|
---|
| 20 | for (p = s, i = 0; p != e; p = element_forw(p), i++) {
|
---|
| 21 | n = array_create_element (element_index(p), element_value(p));
|
---|
| 22 | ADD_BEFORE(a->head, n);
|
---|
| 23 | - mi = element_index(ae);
|
---|
| 24 | + mi = element_index(n);
|
---|
| 25 | }
|
---|
| 26 | a->num_elements = i;
|
---|
| 27 | a->max_index = mi;
|
---|
| 28 | return a;
|
---|
| 29 | }
|
---|
| 30 | -#endif
|
---|
| 31 |
|
---|
| 32 | /*
|
---|
| 33 | * Walk the array, calling FUNC once for each element, with the array
|
---|
| 34 | @@ -300,6 +298,23 @@
|
---|
| 35 | return array;
|
---|
| 36 | }
|
---|
| 37 |
|
---|
| 38 | +ARRAY *
|
---|
| 39 | +array_quote_escapes(array)
|
---|
| 40 | +ARRAY *array;
|
---|
| 41 | +{
|
---|
| 42 | + ARRAY_ELEMENT *a;
|
---|
| 43 | + char *t;
|
---|
| 44 | +
|
---|
| 45 | + if (array == 0 || array_head(array) == 0 || array_empty(array))
|
---|
| 46 | + return (ARRAY *)NULL;
|
---|
| 47 | + for (a = element_forw(array->head); a != array->head; a = element_forw(a)) {
|
---|
| 48 | + t = quote_escapes (a->value);
|
---|
| 49 | + FREE(a->value);
|
---|
| 50 | + a->value = t;
|
---|
| 51 | + }
|
---|
| 52 | + return array;
|
---|
| 53 | +}
|
---|
| 54 | +
|
---|
| 55 | /*
|
---|
| 56 | * Return a string whose elements are the members of array A beginning at
|
---|
| 57 | * index START and spanning NELEM members. Null elements are counted.
|
---|
| 58 | @@ -311,9 +326,10 @@
|
---|
| 59 | arrayind_t start, nelem;
|
---|
| 60 | int starsub, quoted;
|
---|
| 61 | {
|
---|
| 62 | + ARRAY *a2;
|
---|
| 63 | ARRAY_ELEMENT *h, *p;
|
---|
| 64 | arrayind_t i;
|
---|
| 65 | - char *ifs, sep[2];
|
---|
| 66 | + char *ifs, sep[2], *t;
|
---|
| 67 |
|
---|
| 68 | p = a ? array_head (a) : 0;
|
---|
| 69 | if (p == 0 || array_empty (a) || start > array_max_index(a))
|
---|
| 70 | @@ -336,6 +352,13 @@
|
---|
| 71 | for (i = 0, h = p; p != a->head && i < nelem; i++, p = element_forw(p))
|
---|
| 72 | ;
|
---|
| 73 |
|
---|
| 74 | + a2 = array_slice(a, h, p);
|
---|
| 75 | +
|
---|
| 76 | + if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
|
---|
| 77 | + array_quote(a2);
|
---|
| 78 | + else
|
---|
| 79 | + array_quote_escapes(a2);
|
---|
| 80 | +
|
---|
| 81 | if (starsub && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) {
|
---|
| 82 | ifs = getifs();
|
---|
| 83 | sep[0] = ifs ? *ifs : '\0';
|
---|
| 84 | @@ -343,7 +366,10 @@
|
---|
| 85 | sep[0] = ' ';
|
---|
| 86 | sep[1] = '\0';
|
---|
| 87 |
|
---|
| 88 | - return (array_to_string_internal (h, p, sep, quoted));
|
---|
| 89 | + t = array_to_string (a2, sep, 0);
|
---|
| 90 | + array_dispose(a2);
|
---|
| 91 | +
|
---|
| 92 | + return t;
|
---|
| 93 | }
|
---|
| 94 |
|
---|
| 95 | char *
|
---|
| 96 | @@ -367,7 +393,9 @@
|
---|
| 97 | }
|
---|
| 98 |
|
---|
| 99 | if (mflags & MATCH_QUOTED)
|
---|
| 100 | - array_quote (a2);
|
---|
| 101 | + array_quote(a2);
|
---|
| 102 | + else
|
---|
| 103 | + array_quote_escapes(a2);
|
---|
| 104 | if (mflags & MATCH_STARSUB) {
|
---|
| 105 | ifs = getifs();
|
---|
| 106 | sifs[0] = ifs ? *ifs : '\0';
|
---|
| 107 | diff -Naur bash-3.2.orig/array.h bash-3.2/array.h
|
---|
| 108 | --- bash-3.2.orig/array.h 2003-06-01 15:50:30.000000000 -0400
|
---|
| 109 | +++ bash-3.2/array.h 2007-12-20 23:53:03.000000000 -0500
|
---|
| 110 | @@ -55,6 +55,7 @@
|
---|
| 111 | extern ARRAY_ELEMENT *array_unshift_element __P((ARRAY *));
|
---|
| 112 | extern int array_shift_element __P((ARRAY *, char *));
|
---|
| 113 | extern ARRAY *array_quote __P((ARRAY *));
|
---|
| 114 | +extern ARRAY *array_quote_escapes __P((ARRAY *));
|
---|
| 115 |
|
---|
| 116 | extern char *array_subrange __P((ARRAY *, arrayind_t, arrayind_t, int, int));
|
---|
| 117 | extern char *array_patsub __P((ARRAY *, char *, char *, int));
|
---|
| 118 | diff -Naur bash-3.2.orig/arrayfunc.c bash-3.2/arrayfunc.c
|
---|
| 119 | --- bash-3.2.orig/arrayfunc.c 2006-07-27 09:37:59.000000000 -0400
|
---|
| 120 | +++ bash-3.2/arrayfunc.c 2007-12-20 23:53:18.000000000 -0500
|
---|
| 121 | @@ -618,6 +618,8 @@
|
---|
| 122 | if (expok == 0)
|
---|
| 123 | {
|
---|
| 124 | last_command_exit_value = EXECUTION_FAILURE;
|
---|
| 125 | +
|
---|
| 126 | + top_level_cleanup ();
|
---|
| 127 | jump_to_top_level (DISCARD);
|
---|
| 128 | }
|
---|
| 129 | return val;
|
---|
| 130 | @@ -720,7 +722,7 @@
|
---|
| 131 | if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
|
---|
| 132 | {
|
---|
| 133 | if (rtype)
|
---|
| 134 | - *rtype = 1;
|
---|
| 135 | + *rtype = (t[0] == '*') ? 1 : 2;
|
---|
| 136 | if (allow_all == 0)
|
---|
| 137 | {
|
---|
| 138 | err_badarraysub (s);
|
---|
| 139 | diff -Naur bash-3.2.orig/builtins/common.c bash-3.2/builtins/common.c
|
---|
| 140 | --- bash-3.2.orig/builtins/common.c 2006-07-27 09:39:51.000000000 -0400
|
---|
| 141 | +++ bash-3.2/builtins/common.c 2007-12-20 23:53:10.000000000 -0500
|
---|
| 142 | @@ -1,4 +1,4 @@
|
---|
| 143 | -/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
|
---|
| 144 | +/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
|
---|
| 145 |
|
---|
| 146 | This file is part of GNU Bash, the Bourne Again SHell.
|
---|
| 147 |
|
---|
| 148 | @@ -131,6 +131,7 @@
|
---|
| 149 | if (list)
|
---|
| 150 | {
|
---|
| 151 | builtin_error (_("too many arguments"));
|
---|
| 152 | + top_level_cleanup ();
|
---|
| 153 | jump_to_top_level (DISCARD);
|
---|
| 154 | }
|
---|
| 155 | }
|
---|
| 156 | @@ -395,7 +396,10 @@
|
---|
| 157 | if (fatal)
|
---|
| 158 | throw_to_top_level ();
|
---|
| 159 | else
|
---|
| 160 | - jump_to_top_level (DISCARD);
|
---|
| 161 | + {
|
---|
| 162 | + top_level_cleanup ();
|
---|
| 163 | + jump_to_top_level (DISCARD);
|
---|
| 164 | + }
|
---|
| 165 | }
|
---|
| 166 | no_args (list->next);
|
---|
| 167 | }
|
---|
| 168 | @@ -475,7 +479,11 @@
|
---|
| 169 |
|
---|
| 170 | if (the_current_working_directory == 0)
|
---|
| 171 | {
|
---|
| 172 | +#if defined (GETCWD_BROKEN)
|
---|
| 173 | + the_current_working_directory = getcwd (0, PATH_MAX);
|
---|
| 174 | +#else
|
---|
| 175 | the_current_working_directory = getcwd (0, 0);
|
---|
| 176 | +#endif
|
---|
| 177 | if (the_current_working_directory == 0)
|
---|
| 178 | {
|
---|
| 179 | fprintf (stderr, _("%s: error retrieving current directory: %s: %s\n"),
|
---|
| 180 | diff -Naur bash-3.2.orig/builtins/printf.def bash-3.2/builtins/printf.def
|
---|
| 181 | --- bash-3.2.orig/builtins/printf.def 2006-09-18 08:48:42.000000000 -0400
|
---|
| 182 | +++ bash-3.2/builtins/printf.def 2007-12-20 23:53:02.000000000 -0500
|
---|
| 183 | @@ -1,7 +1,7 @@
|
---|
| 184 | This file is printf.def, from which is created printf.c.
|
---|
| 185 | It implements the builtin "printf" in Bash.
|
---|
| 186 |
|
---|
| 187 | -Copyright (C) 1997-2005 Free Software Foundation, Inc.
|
---|
| 188 | +Copyright (C) 1997-2007 Free Software Foundation, Inc.
|
---|
| 189 |
|
---|
| 190 | This file is part of GNU Bash, the Bourne Again SHell.
|
---|
| 191 |
|
---|
| 192 | @@ -49,6 +49,12 @@
|
---|
| 193 | # define INT_MIN (-2147483647-1)
|
---|
| 194 | #endif
|
---|
| 195 |
|
---|
| 196 | +#if defined (PREFER_STDARG)
|
---|
| 197 | +# include <stdarg.h>
|
---|
| 198 | +#else
|
---|
| 199 | +# include <varargs.h>
|
---|
| 200 | +#endif
|
---|
| 201 | +
|
---|
| 202 | #include <stdio.h>
|
---|
| 203 | #include <chartypes.h>
|
---|
| 204 |
|
---|
| 205 | @@ -64,6 +70,10 @@
|
---|
| 206 | #include "bashgetopt.h"
|
---|
| 207 | #include "common.h"
|
---|
| 208 |
|
---|
| 209 | +#if defined (PRI_MACROS_BROKEN)
|
---|
| 210 | +# undef PRIdMAX
|
---|
| 211 | +#endif
|
---|
| 212 | +
|
---|
| 213 | #if !defined (PRIdMAX)
|
---|
| 214 | # if HAVE_LONG_LONG
|
---|
| 215 | # define PRIdMAX "lld"
|
---|
| 216 | @@ -151,6 +161,10 @@
|
---|
| 217 | #define SKIP1 "#'-+ 0"
|
---|
| 218 | #define LENMODS "hjlLtz"
|
---|
| 219 |
|
---|
| 220 | +#ifndef HAVE_ASPRINTF
|
---|
| 221 | +extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
|
---|
| 222 | +#endif
|
---|
| 223 | +
|
---|
| 224 | static void printf_erange __P((char *));
|
---|
| 225 | static int printstr __P((char *, char *, int, int, int));
|
---|
| 226 | static int tescape __P((char *, char *, int *));
|
---|
| 227 | diff -Naur bash-3.2.orig/builtins/read.def bash-3.2/builtins/read.def
|
---|
| 228 | --- bash-3.2.orig/builtins/read.def 2006-09-19 08:45:48.000000000 -0400
|
---|
| 229 | +++ bash-3.2/builtins/read.def 2007-12-20 23:53:11.000000000 -0500
|
---|
| 230 | @@ -127,14 +127,14 @@
|
---|
| 231 | WORD_LIST *list;
|
---|
| 232 | {
|
---|
| 233 | register char *varname;
|
---|
| 234 | - int size, i, nr, pass_next, saw_escape, eof, opt, retval, code;
|
---|
| 235 | - int input_is_tty, input_is_pipe, unbuffered_read;
|
---|
| 236 | + int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2;
|
---|
| 237 | + int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul;
|
---|
| 238 | int raw, edit, nchars, silent, have_timeout, fd;
|
---|
| 239 | unsigned int tmout;
|
---|
| 240 | intmax_t intval;
|
---|
| 241 | char c;
|
---|
| 242 | char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname;
|
---|
| 243 | - char *e, *t, *t1;
|
---|
| 244 | + char *e, *t, *t1, *ps2;
|
---|
| 245 | struct stat tsb;
|
---|
| 246 | SHELL_VAR *var;
|
---|
| 247 | #if defined (ARRAY_VARS)
|
---|
| 248 | @@ -148,6 +148,7 @@
|
---|
| 249 | USE_VAR(size);
|
---|
| 250 | USE_VAR(i);
|
---|
| 251 | USE_VAR(pass_next);
|
---|
| 252 | + USE_VAR(print_ps2);
|
---|
| 253 | USE_VAR(saw_escape);
|
---|
| 254 | USE_VAR(input_is_pipe);
|
---|
| 255 | /* USE_VAR(raw); */
|
---|
| 256 | @@ -163,6 +164,7 @@
|
---|
| 257 | USE_VAR(rlind);
|
---|
| 258 | #endif
|
---|
| 259 | USE_VAR(list);
|
---|
| 260 | + USE_VAR(ps2);
|
---|
| 261 |
|
---|
| 262 | i = 0; /* Index into the string that we are reading. */
|
---|
| 263 | raw = edit = 0; /* Not reading raw input by default. */
|
---|
| 264 | @@ -386,7 +388,8 @@
|
---|
| 265 | setmode (0, O_TEXT);
|
---|
| 266 | #endif
|
---|
| 267 |
|
---|
| 268 | - for (eof = retval = 0;;)
|
---|
| 269 | + ps2 = 0;
|
---|
| 270 | + for (print_ps2 = eof = retval = 0;;)
|
---|
| 271 | {
|
---|
| 272 | #if defined (READLINE)
|
---|
| 273 | if (edit)
|
---|
| 274 | @@ -412,6 +415,15 @@
|
---|
| 275 | {
|
---|
| 276 | #endif
|
---|
| 277 |
|
---|
| 278 | + if (print_ps2)
|
---|
| 279 | + {
|
---|
| 280 | + if (ps2 == 0)
|
---|
| 281 | + ps2 = get_string_value ("PS2");
|
---|
| 282 | + fprintf (stderr, "%s", ps2 ? ps2 : "");
|
---|
| 283 | + fflush (stderr);
|
---|
| 284 | + print_ps2 = 0;
|
---|
| 285 | + }
|
---|
| 286 | +
|
---|
| 287 | if (unbuffered_read)
|
---|
| 288 | retval = zread (fd, &c, 1);
|
---|
| 289 | else
|
---|
| 290 | @@ -440,7 +452,11 @@
|
---|
| 291 | {
|
---|
| 292 | pass_next = 0;
|
---|
| 293 | if (c == '\n')
|
---|
| 294 | - i--; /* back up over the CTLESC */
|
---|
| 295 | + {
|
---|
| 296 | + i--; /* back up over the CTLESC */
|
---|
| 297 | + if (interactive && input_is_tty && raw == 0)
|
---|
| 298 | + print_ps2 = 1;
|
---|
| 299 | + }
|
---|
| 300 | else
|
---|
| 301 | goto add_char;
|
---|
| 302 | continue;
|
---|
| 303 | diff -Naur bash-3.2.orig/config-bot.h bash-3.2/config-bot.h
|
---|
| 304 | --- bash-3.2.orig/config-bot.h 2006-09-12 16:43:04.000000000 -0400
|
---|
| 305 | +++ bash-3.2/config-bot.h 2007-12-20 23:53:01.000000000 -0500
|
---|
| 306 | @@ -1,7 +1,7 @@
|
---|
| 307 | /* config-bot.h */
|
---|
| 308 | /* modify settings or make new ones based on what autoconf tells us. */
|
---|
| 309 |
|
---|
| 310 | -/* Copyright (C) 1989-2002 Free Software Foundation, Inc.
|
---|
| 311 | +/* Copyright (C) 1989-2007 Free Software Foundation, Inc.
|
---|
| 312 |
|
---|
| 313 | This file is part of GNU Bash, the Bourne Again SHell.
|
---|
| 314 |
|
---|
| 315 | @@ -70,9 +70,11 @@
|
---|
| 316 | # define TERMIOS_MISSING
|
---|
| 317 | #endif
|
---|
| 318 |
|
---|
| 319 | -/* If we have a getcwd(3), but it calls popen(), #undef HAVE_GETCWD so
|
---|
| 320 | - the replacement in getcwd.c will be built. */
|
---|
| 321 | -#if defined (HAVE_GETCWD) && defined (GETCWD_BROKEN)
|
---|
| 322 | +/* If we have a getcwd(3), but one that does not dynamically allocate memory,
|
---|
| 323 | + #undef HAVE_GETCWD so the replacement in getcwd.c will be built. We do
|
---|
| 324 | + not do this on Solaris, because their implementation of loopback mounts
|
---|
| 325 | + breaks the traditional file system assumptions that getcwd uses. */
|
---|
| 326 | +#if defined (HAVE_GETCWD) && defined (GETCWD_BROKEN) && !defined (SOLARIS)
|
---|
| 327 | # undef HAVE_GETCWD
|
---|
| 328 | #endif
|
---|
| 329 |
|
---|
| 330 | diff -Naur bash-3.2.orig/config.h.in bash-3.2/config.h.in
|
---|
| 331 | --- bash-3.2.orig/config.h.in 2006-09-12 16:00:54.000000000 -0400
|
---|
| 332 | +++ bash-3.2/config.h.in 2007-12-20 23:53:02.000000000 -0500
|
---|
| 333 | @@ -1,6 +1,6 @@
|
---|
| 334 | /* config.h -- Configuration file for bash. */
|
---|
| 335 |
|
---|
| 336 | -/* Copyright (C) 1987-2006 Free Software Foundation, Inc.
|
---|
| 337 | +/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
|
---|
| 338 |
|
---|
| 339 | This file is part of GNU Bash, the Bourne Again SHell.
|
---|
| 340 |
|
---|
| 341 | @@ -413,6 +413,8 @@
|
---|
| 342 |
|
---|
| 343 | #undef HAVE_DECL_STRTOLD
|
---|
| 344 |
|
---|
| 345 | +#undef PRI_MACROS_BROKEN
|
---|
| 346 | +
|
---|
| 347 | #undef STRTOLD_BROKEN
|
---|
| 348 |
|
---|
| 349 | /* Define if WCONTINUED is defined in system headers, but rejected by waitpid */
|
---|
| 350 | @@ -1006,6 +1008,9 @@
|
---|
| 351 | /* Define if you have the `dcgettext' function. */
|
---|
| 352 | #undef HAVE_DCGETTEXT
|
---|
| 353 |
|
---|
| 354 | +/* Define if you have the `localeconv' function. */
|
---|
| 355 | +#undef HAVE_LOCALECONV
|
---|
| 356 | +
|
---|
| 357 | /* Define if your system has a working `malloc' function. */
|
---|
| 358 | /* #undef HAVE_MALLOC */
|
---|
| 359 |
|
---|
| 360 | diff -Naur bash-3.2.orig/configure bash-3.2/configure
|
---|
| 361 | --- bash-3.2.orig/configure 2006-09-26 11:06:01.000000000 -0400
|
---|
| 362 | +++ bash-3.2/configure 2007-12-20 23:53:13.000000000 -0500
|
---|
| 363 | @@ -4871,7 +4871,7 @@
|
---|
| 364 | # static version specified as -llibname to override the
|
---|
| 365 | # dynamic version
|
---|
| 366 | case "${host_os}" in
|
---|
| 367 | - darwin8*) READLINE_LIB='${READLINE_LIBRARY}' ;;
|
---|
| 368 | + darwin[89]*) READLINE_LIB='${READLINE_LIBRARY}' ;;
|
---|
| 369 | *) READLINE_LIB=-lreadline ;;
|
---|
| 370 | esac
|
---|
| 371 | fi
|
---|
| 372 | @@ -27316,7 +27316,8 @@
|
---|
| 373 | sco3.2v4*) LOCAL_CFLAGS="-DMUST_UNBLOCK_CHLD -DPATH_MAX=1024" ;;
|
---|
| 374 | sco3.2*) LOCAL_CFLAGS=-DMUST_UNBLOCK_CHLD ;;
|
---|
| 375 | sunos4*) LOCAL_CFLAGS=-DSunOS4 ;;
|
---|
| 376 | -solaris2.5*) LOCAL_CFLAGS=-DSunOS5 ;;
|
---|
| 377 | +solaris2.5*) LOCAL_CFLAGS="-DSunOS5 -DSOLARIS" ;;
|
---|
| 378 | +solaris2*) LOCAL_CFLAGS=-DSOLARIS ;;
|
---|
| 379 | lynxos*) LOCAL_CFLAGS=-DRECYCLES_PIDS ;;
|
---|
| 380 | linux*) LOCAL_LDFLAGS=-rdynamic # allow dynamic loading
|
---|
| 381 | case "`uname -r`" in
|
---|
| 382 | diff -Naur bash-3.2.orig/configure.in bash-3.2/configure.in
|
---|
| 383 | --- bash-3.2.orig/configure.in 2006-09-26 11:05:45.000000000 -0400
|
---|
| 384 | +++ bash-3.2/configure.in 2007-12-20 23:53:13.000000000 -0500
|
---|
| 385 | @@ -5,7 +5,7 @@
|
---|
| 386 | dnl
|
---|
| 387 | dnl Process this file with autoconf to produce a configure script.
|
---|
| 388 |
|
---|
| 389 | -# Copyright (C) 1987-2006 Free Software Foundation, Inc.
|
---|
| 390 | +# Copyright (C) 1987-2007 Free Software Foundation, Inc.
|
---|
| 391 |
|
---|
| 392 | # This program is free software; you can redistribute it and/or modify
|
---|
| 393 | # it under the terms of the GNU General Public License as published by
|
---|
| 394 | @@ -518,7 +518,7 @@
|
---|
| 395 | # static version specified as -llibname to override the
|
---|
| 396 | # dynamic version
|
---|
| 397 | case "${host_os}" in
|
---|
| 398 | - darwin8*) READLINE_LIB='${READLINE_LIBRARY}' ;;
|
---|
| 399 | + darwin[[89]]*) READLINE_LIB='${READLINE_LIBRARY}' ;;
|
---|
| 400 | *) READLINE_LIB=-lreadline ;;
|
---|
| 401 | esac
|
---|
| 402 | fi
|
---|
| 403 | @@ -991,7 +991,8 @@
|
---|
| 404 | sco3.2v4*) LOCAL_CFLAGS="-DMUST_UNBLOCK_CHLD -DPATH_MAX=1024" ;;
|
---|
| 405 | sco3.2*) LOCAL_CFLAGS=-DMUST_UNBLOCK_CHLD ;;
|
---|
| 406 | sunos4*) LOCAL_CFLAGS=-DSunOS4 ;;
|
---|
| 407 | -solaris2.5*) LOCAL_CFLAGS=-DSunOS5 ;;
|
---|
| 408 | +solaris2.5*) LOCAL_CFLAGS="-DSunOS5 -DSOLARIS" ;;
|
---|
| 409 | +solaris2*) LOCAL_CFLAGS=-DSOLARIS ;;
|
---|
| 410 | lynxos*) LOCAL_CFLAGS=-DRECYCLES_PIDS ;;
|
---|
| 411 | linux*) LOCAL_LDFLAGS=-rdynamic # allow dynamic loading
|
---|
| 412 | case "`uname -r`" in
|
---|
| 413 | diff -Naur bash-3.2.orig/execute_cmd.c bash-3.2/execute_cmd.c
|
---|
| 414 | --- bash-3.2.orig/execute_cmd.c 2006-08-26 00:23:17.000000000 -0400
|
---|
| 415 | +++ bash-3.2/execute_cmd.c 2007-12-20 23:53:16.000000000 -0500
|
---|
| 416 | @@ -1,6 +1,6 @@
|
---|
| 417 | /* execute_cmd.c -- Execute a COMMAND structure. */
|
---|
| 418 |
|
---|
| 419 | -/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
|
---|
| 420 | +/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
|
---|
| 421 |
|
---|
| 422 | This file is part of GNU Bash, the Bourne Again SHell.
|
---|
| 423 |
|
---|
| 424 | @@ -614,7 +614,7 @@
|
---|
| 425 | cleanup_redirects (redirection_undo_list);
|
---|
| 426 | redirection_undo_list = (REDIRECT *)NULL;
|
---|
| 427 | dispose_exec_redirects ();
|
---|
| 428 | - return (EXECUTION_FAILURE);
|
---|
| 429 | + return (last_command_exit_value = EXECUTION_FAILURE);
|
---|
| 430 | }
|
---|
| 431 |
|
---|
| 432 | if (redirection_undo_list)
|
---|
| 433 | @@ -2546,7 +2546,7 @@
|
---|
| 434 | arg1 = cond_expand_word (cond->left->op, 0);
|
---|
| 435 | if (arg1 == 0)
|
---|
| 436 | arg1 = nullstr;
|
---|
| 437 | - arg2 = cond_expand_word (cond->right->op, patmatch||rmatch);
|
---|
| 438 | + arg2 = cond_expand_word (cond->right->op, rmatch ? 2 : (patmatch ? 1 : 0));
|
---|
| 439 | if (arg2 == 0)
|
---|
| 440 | arg2 = nullstr;
|
---|
| 441 |
|
---|
| 442 | @@ -3050,6 +3050,11 @@
|
---|
| 443 | if (command_line == 0)
|
---|
| 444 | command_line = savestring (the_printed_command_except_trap);
|
---|
| 445 |
|
---|
| 446 | +#if defined (PROCESS_SUBSTITUTION)
|
---|
| 447 | + if ((subshell_environment & SUBSHELL_COMSUB) && (simple_command->flags & CMD_NO_FORK) && fifos_pending() > 0)
|
---|
| 448 | + simple_command->flags &= ~CMD_NO_FORK;
|
---|
| 449 | +#endif
|
---|
| 450 | +
|
---|
| 451 | execute_disk_command (words, simple_command->redirects, command_line,
|
---|
| 452 | pipe_in, pipe_out, async, fds_to_close,
|
---|
| 453 | simple_command->flags);
|
---|
| 454 | diff -Naur bash-3.2.orig/expr.c bash-3.2/expr.c
|
---|
| 455 | --- bash-3.2.orig/expr.c 2005-12-28 17:47:03.000000000 -0500
|
---|
| 456 | +++ bash-3.2/expr.c 2007-12-20 23:53:15.000000000 -0500
|
---|
| 457 | @@ -286,6 +286,8 @@
|
---|
| 458 | free (expr_stack[expr_depth]);
|
---|
| 459 | }
|
---|
| 460 | free (expr_stack[expr_depth]); /* free the allocated EXPR_CONTEXT */
|
---|
| 461 | +
|
---|
| 462 | + noeval = 0; /* XXX */
|
---|
| 463 | }
|
---|
| 464 |
|
---|
| 465 | static void
|
---|
| 466 | @@ -319,6 +321,7 @@
|
---|
| 467 | procenv_t oevalbuf;
|
---|
| 468 |
|
---|
| 469 | val = 0;
|
---|
| 470 | + noeval = 0;
|
---|
| 471 |
|
---|
| 472 | FASTCOPY (evalbuf, oevalbuf, sizeof (evalbuf));
|
---|
| 473 |
|
---|
| 474 | @@ -929,6 +932,7 @@
|
---|
| 475 | if (interactive_shell)
|
---|
| 476 | {
|
---|
| 477 | expr_unwind ();
|
---|
| 478 | + top_level_cleanup ();
|
---|
| 479 | jump_to_top_level (DISCARD);
|
---|
| 480 | }
|
---|
| 481 | else
|
---|
| 482 | diff -Naur bash-3.2.orig/findcmd.c bash-3.2/findcmd.c
|
---|
| 483 | --- bash-3.2.orig/findcmd.c 2005-08-17 16:49:54.000000000 -0400
|
---|
| 484 | +++ bash-3.2/findcmd.c 2007-12-20 23:52:59.000000000 -0500
|
---|
| 485 | @@ -308,7 +308,7 @@
|
---|
| 486 | if (hashed_file && (posixly_correct || check_hashed_filenames))
|
---|
| 487 | {
|
---|
| 488 | st = file_status (hashed_file);
|
---|
| 489 | - if ((st ^ (FS_EXISTS | FS_EXECABLE)) != 0)
|
---|
| 490 | + if ((st & (FS_EXISTS|FS_EXECABLE)) != (FS_EXISTS|FS_EXECABLE))
|
---|
| 491 | {
|
---|
| 492 | phash_remove (pathname);
|
---|
| 493 | free (hashed_file);
|
---|
| 494 | diff -Naur bash-3.2.orig/jobs.c bash-3.2/jobs.c
|
---|
| 495 | --- bash-3.2.orig/jobs.c 2006-07-29 16:40:48.000000000 -0400
|
---|
| 496 | +++ bash-3.2/jobs.c 2007-12-20 23:53:05.000000000 -0500
|
---|
| 497 | @@ -783,11 +783,13 @@
|
---|
| 498 | if (jobs[js.j_firstj] == 0)
|
---|
| 499 | {
|
---|
| 500 | old = js.j_firstj++;
|
---|
| 501 | + if (old >= js.j_jobslots)
|
---|
| 502 | + old = js.j_jobslots - 1;
|
---|
| 503 | while (js.j_firstj != old)
|
---|
| 504 | {
|
---|
| 505 | if (js.j_firstj >= js.j_jobslots)
|
---|
| 506 | js.j_firstj = 0;
|
---|
| 507 | - if (jobs[js.j_firstj])
|
---|
| 508 | + if (jobs[js.j_firstj] || js.j_firstj == old) /* needed if old == 0 */
|
---|
| 509 | break;
|
---|
| 510 | js.j_firstj++;
|
---|
| 511 | }
|
---|
| 512 | @@ -797,11 +799,13 @@
|
---|
| 513 | if (jobs[js.j_lastj] == 0)
|
---|
| 514 | {
|
---|
| 515 | old = js.j_lastj--;
|
---|
| 516 | + if (old < 0)
|
---|
| 517 | + old = 0;
|
---|
| 518 | while (js.j_lastj != old)
|
---|
| 519 | {
|
---|
| 520 | if (js.j_lastj < 0)
|
---|
| 521 | js.j_lastj = js.j_jobslots - 1;
|
---|
| 522 | - if (jobs[js.j_lastj])
|
---|
| 523 | + if (jobs[js.j_lastj] || js.j_lastj == old) /* needed if old == js.j_jobslots */
|
---|
| 524 | break;
|
---|
| 525 | js.j_lastj--;
|
---|
| 526 | }
|
---|
| 527 | @@ -963,7 +967,11 @@
|
---|
| 528 | reap_dead_jobs ();
|
---|
| 529 | realloc_jobs_list ();
|
---|
| 530 |
|
---|
| 531 | - return (js.j_lastj);
|
---|
| 532 | +#ifdef DEBUG
|
---|
| 533 | + itrace("compact_jobs_list: returning %d", (js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0);
|
---|
| 534 | +#endif
|
---|
| 535 | +
|
---|
| 536 | + return ((js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0);
|
---|
| 537 | }
|
---|
| 538 |
|
---|
| 539 | /* Delete the job at INDEX from the job list. Must be called
|
---|
| 540 | @@ -984,8 +992,6 @@
|
---|
| 541 | temp = jobs[job_index];
|
---|
| 542 | if (temp == 0)
|
---|
| 543 | return;
|
---|
| 544 | - if (job_index == js.j_current || job_index == js.j_previous)
|
---|
| 545 | - reset_current ();
|
---|
| 546 |
|
---|
| 547 | if ((dflags & DEL_NOBGPID) == 0)
|
---|
| 548 | {
|
---|
| 549 | @@ -1028,6 +1034,9 @@
|
---|
| 550 | js.j_firstj = js.j_lastj = 0;
|
---|
| 551 | else if (jobs[js.j_firstj] == 0 || jobs[js.j_lastj] == 0)
|
---|
| 552 | reset_job_indices ();
|
---|
| 553 | +
|
---|
| 554 | + if (job_index == js.j_current || job_index == js.j_previous)
|
---|
| 555 | + reset_current ();
|
---|
| 556 | }
|
---|
| 557 |
|
---|
| 558 | /* Must be called with SIGCHLD blocked. */
|
---|
| 559 | diff -Naur bash-3.2.orig/lib/readline/complete.c bash-3.2/lib/readline/complete.c
|
---|
| 560 | --- bash-3.2.orig/lib/readline/complete.c 2006-07-28 11:35:49.000000000 -0400
|
---|
| 561 | +++ bash-3.2/lib/readline/complete.c 2007-12-20 23:53:09.000000000 -0500
|
---|
| 562 | @@ -428,7 +428,7 @@
|
---|
| 563 | return (1);
|
---|
| 564 | if (c == 'n' || c == 'N' || c == RUBOUT)
|
---|
| 565 | return (0);
|
---|
| 566 | - if (c == ABORT_CHAR)
|
---|
| 567 | + if (c == ABORT_CHAR || c < 0)
|
---|
| 568 | _rl_abort_internal ();
|
---|
| 569 | if (for_pager && (c == NEWLINE || c == RETURN))
|
---|
| 570 | return (2);
|
---|
| 571 | diff -Naur bash-3.2.orig/lib/readline/display.c bash-3.2/lib/readline/display.c
|
---|
| 572 | --- bash-3.2.orig/lib/readline/display.c 2006-09-14 14:20:12.000000000 -0400
|
---|
| 573 | +++ bash-3.2/lib/readline/display.c 2007-12-20 23:53:16.000000000 -0500
|
---|
| 574 | @@ -391,14 +391,14 @@
|
---|
| 575 | t = ++p;
|
---|
| 576 | local_prompt = expand_prompt (p, &prompt_visible_length,
|
---|
| 577 | &prompt_last_invisible,
|
---|
| 578 | - (int *)NULL,
|
---|
| 579 | + &prompt_invis_chars_first_line,
|
---|
| 580 | &prompt_physical_chars);
|
---|
| 581 | c = *t; *t = '\0';
|
---|
| 582 | /* The portion of the prompt string up to and including the
|
---|
| 583 | final newline is now null-terminated. */
|
---|
| 584 | local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
|
---|
| 585 | (int *)NULL,
|
---|
| 586 | - &prompt_invis_chars_first_line,
|
---|
| 587 | + (int *)NULL,
|
---|
| 588 | (int *)NULL);
|
---|
| 589 | *t = c;
|
---|
| 590 | local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
|
---|
| 591 | @@ -561,6 +561,17 @@
|
---|
| 592 | wrap_offset = prompt_invis_chars_first_line = 0;
|
---|
| 593 | }
|
---|
| 594 |
|
---|
| 595 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 596 | +#define CHECK_INV_LBREAKS() \
|
---|
| 597 | + do { \
|
---|
| 598 | + if (newlines >= (inv_lbsize - 2)) \
|
---|
| 599 | + { \
|
---|
| 600 | + inv_lbsize *= 2; \
|
---|
| 601 | + inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
|
---|
| 602 | + _rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \
|
---|
| 603 | + } \
|
---|
| 604 | + } while (0)
|
---|
| 605 | +#else
|
---|
| 606 | #define CHECK_INV_LBREAKS() \
|
---|
| 607 | do { \
|
---|
| 608 | if (newlines >= (inv_lbsize - 2)) \
|
---|
| 609 | @@ -569,6 +580,7 @@
|
---|
| 610 | inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
|
---|
| 611 | } \
|
---|
| 612 | } while (0)
|
---|
| 613 | +#endif /* HANDLE_MULTIBYTE */
|
---|
| 614 |
|
---|
| 615 | #if defined (HANDLE_MULTIBYTE)
|
---|
| 616 | #define CHECK_LPOS() \
|
---|
| 617 | @@ -1036,7 +1048,7 @@
|
---|
| 618 | tx = _rl_col_width (&visible_line[pos], 0, nleft) - visible_wrap_offset;
|
---|
| 619 | else
|
---|
| 620 | tx = nleft;
|
---|
| 621 | - if (_rl_last_c_pos > tx)
|
---|
| 622 | + if (tx >= 0 && _rl_last_c_pos > tx)
|
---|
| 623 | {
|
---|
| 624 | _rl_backspace (_rl_last_c_pos - tx); /* XXX */
|
---|
| 625 | _rl_last_c_pos = tx;
|
---|
| 626 | @@ -1192,7 +1204,7 @@
|
---|
| 627 | int current_line, omax, nmax, inv_botlin;
|
---|
| 628 | {
|
---|
| 629 | register char *ofd, *ols, *oe, *nfd, *nls, *ne;
|
---|
| 630 | - int temp, lendiff, wsatend, od, nd;
|
---|
| 631 | + int temp, lendiff, wsatend, od, nd, o_cpos;
|
---|
| 632 | int current_invis_chars;
|
---|
| 633 | int col_lendiff, col_temp;
|
---|
| 634 | #if defined (HANDLE_MULTIBYTE)
|
---|
| 635 | @@ -1453,6 +1465,8 @@
|
---|
| 636 | _rl_last_c_pos = lendiff;
|
---|
| 637 | }
|
---|
| 638 |
|
---|
| 639 | + o_cpos = _rl_last_c_pos;
|
---|
| 640 | +
|
---|
| 641 | /* When this function returns, _rl_last_c_pos is correct, and an absolute
|
---|
| 642 | cursor postion in multibyte mode, but a buffer index when not in a
|
---|
| 643 | multibyte locale. */
|
---|
| 644 | @@ -1462,7 +1476,9 @@
|
---|
| 645 | /* We need to indicate that the cursor position is correct in the presence of
|
---|
| 646 | invisible characters in the prompt string. Let's see if setting this when
|
---|
| 647 | we make sure we're at the end of the drawn prompt string works. */
|
---|
| 648 | - if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 && _rl_last_c_pos == prompt_physical_chars)
|
---|
| 649 | + if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 &&
|
---|
| 650 | + (_rl_last_c_pos > 0 || o_cpos > 0) &&
|
---|
| 651 | + _rl_last_c_pos == prompt_physical_chars)
|
---|
| 652 | cpos_adjusted = 1;
|
---|
| 653 | #endif
|
---|
| 654 | #endif
|
---|
| 655 | @@ -1506,11 +1522,31 @@
|
---|
| 656 | {
|
---|
| 657 | /* Non-zero if we're increasing the number of lines. */
|
---|
| 658 | int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
|
---|
| 659 | + /* If col_lendiff is > 0, implying that the new string takes up more
|
---|
| 660 | + screen real estate than the old, but lendiff is < 0, meaning that it
|
---|
| 661 | + takes fewer bytes, we need to just output the characters starting
|
---|
| 662 | + from the first difference. These will overwrite what is on the
|
---|
| 663 | + display, so there's no reason to do a smart update. This can really
|
---|
| 664 | + only happen in a multibyte environment. */
|
---|
| 665 | + if (lendiff < 0)
|
---|
| 666 | + {
|
---|
| 667 | + _rl_output_some_chars (nfd, temp);
|
---|
| 668 | + _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
|
---|
| 669 | + /* If nfd begins before any invisible characters in the prompt,
|
---|
| 670 | + adjust _rl_last_c_pos to account for wrap_offset and set
|
---|
| 671 | + cpos_adjusted to let the caller know. */
|
---|
| 672 | + if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
|
---|
| 673 | + {
|
---|
| 674 | + _rl_last_c_pos -= wrap_offset;
|
---|
| 675 | + cpos_adjusted = 1;
|
---|
| 676 | + }
|
---|
| 677 | + return;
|
---|
| 678 | + }
|
---|
| 679 | /* Sometimes it is cheaper to print the characters rather than
|
---|
| 680 | use the terminal's capabilities. If we're growing the number
|
---|
| 681 | of lines, make sure we actually cause the new line to wrap
|
---|
| 682 | around on auto-wrapping terminals. */
|
---|
| 683 | - if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
|
---|
| 684 | + else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
|
---|
| 685 | {
|
---|
| 686 | /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
|
---|
| 687 | _rl_horizontal_scroll_mode == 1, inserting the characters with
|
---|
| 688 | @@ -1533,11 +1569,16 @@
|
---|
| 689 | }
|
---|
| 690 | else
|
---|
| 691 | {
|
---|
| 692 | - /* We have horizontal scrolling and we are not inserting at
|
---|
| 693 | - the end. We have invisible characters in this line. This
|
---|
| 694 | - is a dumb update. */
|
---|
| 695 | _rl_output_some_chars (nfd, temp);
|
---|
| 696 | _rl_last_c_pos += col_temp;
|
---|
| 697 | + /* If nfd begins before any invisible characters in the prompt,
|
---|
| 698 | + adjust _rl_last_c_pos to account for wrap_offset and set
|
---|
| 699 | + cpos_adjusted to let the caller know. */
|
---|
| 700 | + if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
|
---|
| 701 | + {
|
---|
| 702 | + _rl_last_c_pos -= wrap_offset;
|
---|
| 703 | + cpos_adjusted = 1;
|
---|
| 704 | + }
|
---|
| 705 | return;
|
---|
| 706 | }
|
---|
| 707 | /* Copy (new) chars to screen from first diff to last match. */
|
---|
| 708 | @@ -1586,8 +1627,22 @@
|
---|
| 709 | temp = nls - nfd;
|
---|
| 710 | if (temp > 0)
|
---|
| 711 | {
|
---|
| 712 | + /* If nfd begins at the prompt, or before the invisible
|
---|
| 713 | + characters in the prompt, we need to adjust _rl_last_c_pos
|
---|
| 714 | + in a multibyte locale to account for the wrap offset and
|
---|
| 715 | + set cpos_adjusted accordingly. */
|
---|
| 716 | _rl_output_some_chars (nfd, temp);
|
---|
| 717 | - _rl_last_c_pos += _rl_col_width (nfd, 0, temp);;
|
---|
| 718 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 719 | + {
|
---|
| 720 | + _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
|
---|
| 721 | + if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
|
---|
| 722 | + {
|
---|
| 723 | + _rl_last_c_pos -= wrap_offset;
|
---|
| 724 | + cpos_adjusted = 1;
|
---|
| 725 | + }
|
---|
| 726 | + }
|
---|
| 727 | + else
|
---|
| 728 | + _rl_last_c_pos += temp;
|
---|
| 729 | }
|
---|
| 730 | }
|
---|
| 731 | /* Otherwise, print over the existing material. */
|
---|
| 732 | @@ -1595,8 +1650,20 @@
|
---|
| 733 | {
|
---|
| 734 | if (temp > 0)
|
---|
| 735 | {
|
---|
| 736 | + /* If nfd begins at the prompt, or before the invisible
|
---|
| 737 | + characters in the prompt, we need to adjust _rl_last_c_pos
|
---|
| 738 | + in a multibyte locale to account for the wrap offset and
|
---|
| 739 | + set cpos_adjusted accordingly. */
|
---|
| 740 | _rl_output_some_chars (nfd, temp);
|
---|
| 741 | _rl_last_c_pos += col_temp; /* XXX */
|
---|
| 742 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 743 | + {
|
---|
| 744 | + if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
|
---|
| 745 | + {
|
---|
| 746 | + _rl_last_c_pos -= wrap_offset;
|
---|
| 747 | + cpos_adjusted = 1;
|
---|
| 748 | + }
|
---|
| 749 | + }
|
---|
| 750 | }
|
---|
| 751 | lendiff = (oe - old) - (ne - new);
|
---|
| 752 | if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 753 | @@ -1732,7 +1799,10 @@
|
---|
| 754 | if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 755 | {
|
---|
| 756 | dpos = _rl_col_width (data, 0, new);
|
---|
| 757 | - if (dpos > prompt_last_invisible) /* XXX - don't use woff here */
|
---|
| 758 | + /* Use NEW when comparing against the last invisible character in the
|
---|
| 759 | + prompt string, since they're both buffer indices and DPOS is a
|
---|
| 760 | + desired display position. */
|
---|
| 761 | + if (new > prompt_last_invisible) /* XXX - don't use woff here */
|
---|
| 762 | {
|
---|
| 763 | dpos -= woff;
|
---|
| 764 | /* Since this will be assigned to _rl_last_c_pos at the end (more
|
---|
| 765 | @@ -2380,6 +2450,8 @@
|
---|
| 766 |
|
---|
| 767 | if (end <= start)
|
---|
| 768 | return 0;
|
---|
| 769 | + if (MB_CUR_MAX == 1 || rl_byte_oriented)
|
---|
| 770 | + return (end - start);
|
---|
| 771 |
|
---|
| 772 | memset (&ps, 0, sizeof (mbstate_t));
|
---|
| 773 |
|
---|
| 774 | diff -Naur bash-3.2.orig/lib/readline/display.c.orig bash-3.2/lib/readline/display.c.orig
|
---|
| 775 | --- bash-3.2.orig/lib/readline/display.c.orig 1969-12-31 19:00:00.000000000 -0500
|
---|
| 776 | +++ bash-3.2/lib/readline/display.c.orig 2007-12-20 23:53:14.000000000 -0500
|
---|
| 777 | @@ -0,0 +1,2518 @@
|
---|
| 778 | +/* display.c -- readline redisplay facility. */
|
---|
| 779 | +
|
---|
| 780 | +/* Copyright (C) 1987-2006 Free Software Foundation, Inc.
|
---|
| 781 | +
|
---|
| 782 | + This file is part of the GNU Readline Library, a library for
|
---|
| 783 | + reading lines of text with interactive input and history editing.
|
---|
| 784 | +
|
---|
| 785 | + The GNU Readline Library is free software; you can redistribute it
|
---|
| 786 | + and/or modify it under the terms of the GNU General Public License
|
---|
| 787 | + as published by the Free Software Foundation; either version 2, or
|
---|
| 788 | + (at your option) any later version.
|
---|
| 789 | +
|
---|
| 790 | + The GNU Readline Library is distributed in the hope that it will be
|
---|
| 791 | + useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
---|
| 792 | + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
| 793 | + GNU General Public License for more details.
|
---|
| 794 | +
|
---|
| 795 | + The GNU General Public License is often shipped with GNU software, and
|
---|
| 796 | + is generally kept in a file called COPYING or LICENSE. If you do not
|
---|
| 797 | + have a copy of the license, write to the Free Software Foundation,
|
---|
| 798 | + 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
---|
| 799 | +#define READLINE_LIBRARY
|
---|
| 800 | +
|
---|
| 801 | +#if defined (HAVE_CONFIG_H)
|
---|
| 802 | +# include <config.h>
|
---|
| 803 | +#endif
|
---|
| 804 | +
|
---|
| 805 | +#include <sys/types.h>
|
---|
| 806 | +
|
---|
| 807 | +#if defined (HAVE_UNISTD_H)
|
---|
| 808 | +# include <unistd.h>
|
---|
| 809 | +#endif /* HAVE_UNISTD_H */
|
---|
| 810 | +
|
---|
| 811 | +#include "posixstat.h"
|
---|
| 812 | +
|
---|
| 813 | +#if defined (HAVE_STDLIB_H)
|
---|
| 814 | +# include <stdlib.h>
|
---|
| 815 | +#else
|
---|
| 816 | +# include "ansi_stdlib.h"
|
---|
| 817 | +#endif /* HAVE_STDLIB_H */
|
---|
| 818 | +
|
---|
| 819 | +#include <stdio.h>
|
---|
| 820 | +
|
---|
| 821 | +/* System-specific feature definitions and include files. */
|
---|
| 822 | +#include "rldefs.h"
|
---|
| 823 | +#include "rlmbutil.h"
|
---|
| 824 | +
|
---|
| 825 | +/* Termcap library stuff. */
|
---|
| 826 | +#include "tcap.h"
|
---|
| 827 | +
|
---|
| 828 | +/* Some standard library routines. */
|
---|
| 829 | +#include "readline.h"
|
---|
| 830 | +#include "history.h"
|
---|
| 831 | +
|
---|
| 832 | +#include "rlprivate.h"
|
---|
| 833 | +#include "xmalloc.h"
|
---|
| 834 | +
|
---|
| 835 | +#if !defined (strchr) && !defined (__STDC__)
|
---|
| 836 | +extern char *strchr (), *strrchr ();
|
---|
| 837 | +#endif /* !strchr && !__STDC__ */
|
---|
| 838 | +
|
---|
| 839 | +static void update_line PARAMS((char *, char *, int, int, int, int));
|
---|
| 840 | +static void space_to_eol PARAMS((int));
|
---|
| 841 | +static void delete_chars PARAMS((int));
|
---|
| 842 | +static void insert_some_chars PARAMS((char *, int, int));
|
---|
| 843 | +static void cr PARAMS((void));
|
---|
| 844 | +
|
---|
| 845 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 846 | +static int _rl_col_width PARAMS((const char *, int, int));
|
---|
| 847 | +static int *_rl_wrapped_line;
|
---|
| 848 | +#else
|
---|
| 849 | +# define _rl_col_width(l, s, e) (((e) <= (s)) ? 0 : (e) - (s))
|
---|
| 850 | +#endif
|
---|
| 851 | +
|
---|
| 852 | +static int *inv_lbreaks, *vis_lbreaks;
|
---|
| 853 | +static int inv_lbsize, vis_lbsize;
|
---|
| 854 | +
|
---|
| 855 | +/* Heuristic used to decide whether it is faster to move from CUR to NEW
|
---|
| 856 | + by backing up or outputting a carriage return and moving forward. CUR
|
---|
| 857 | + and NEW are either both buffer positions or absolute screen positions. */
|
---|
| 858 | +#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
|
---|
| 859 | +
|
---|
| 860 | +/* _rl_last_c_pos is an absolute cursor position in multibyte locales and a
|
---|
| 861 | + buffer index in others. This macro is used when deciding whether the
|
---|
| 862 | + current cursor position is in the middle of a prompt string containing
|
---|
| 863 | + invisible characters. */
|
---|
| 864 | +#define PROMPT_ENDING_INDEX \
|
---|
| 865 | + ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1)
|
---|
| 866 | +
|
---|
| 867 | +
|
---|
| 868 | +/* **************************************************************** */
|
---|
| 869 | +/* */
|
---|
| 870 | +/* Display stuff */
|
---|
| 871 | +/* */
|
---|
| 872 | +/* **************************************************************** */
|
---|
| 873 | +
|
---|
| 874 | +/* This is the stuff that is hard for me. I never seem to write good
|
---|
| 875 | + display routines in C. Let's see how I do this time. */
|
---|
| 876 | +
|
---|
| 877 | +/* (PWP) Well... Good for a simple line updater, but totally ignores
|
---|
| 878 | + the problems of input lines longer than the screen width.
|
---|
| 879 | +
|
---|
| 880 | + update_line and the code that calls it makes a multiple line,
|
---|
| 881 | + automatically wrapping line update. Careful attention needs
|
---|
| 882 | + to be paid to the vertical position variables. */
|
---|
| 883 | +
|
---|
| 884 | +/* Keep two buffers; one which reflects the current contents of the
|
---|
| 885 | + screen, and the other to draw what we think the new contents should
|
---|
| 886 | + be. Then compare the buffers, and make whatever changes to the
|
---|
| 887 | + screen itself that we should. Finally, make the buffer that we
|
---|
| 888 | + just drew into be the one which reflects the current contents of the
|
---|
| 889 | + screen, and place the cursor where it belongs.
|
---|
| 890 | +
|
---|
| 891 | + Commands that want to can fix the display themselves, and then let
|
---|
| 892 | + this function know that the display has been fixed by setting the
|
---|
| 893 | + RL_DISPLAY_FIXED variable. This is good for efficiency. */
|
---|
| 894 | +
|
---|
| 895 | +/* Application-specific redisplay function. */
|
---|
| 896 | +rl_voidfunc_t *rl_redisplay_function = rl_redisplay;
|
---|
| 897 | +
|
---|
| 898 | +/* Global variables declared here. */
|
---|
| 899 | +/* What YOU turn on when you have handled all redisplay yourself. */
|
---|
| 900 | +int rl_display_fixed = 0;
|
---|
| 901 | +
|
---|
| 902 | +int _rl_suppress_redisplay = 0;
|
---|
| 903 | +int _rl_want_redisplay = 0;
|
---|
| 904 | +
|
---|
| 905 | +/* The stuff that gets printed out before the actual text of the line.
|
---|
| 906 | + This is usually pointing to rl_prompt. */
|
---|
| 907 | +char *rl_display_prompt = (char *)NULL;
|
---|
| 908 | +
|
---|
| 909 | +/* Pseudo-global variables declared here. */
|
---|
| 910 | +
|
---|
| 911 | +/* The visible cursor position. If you print some text, adjust this. */
|
---|
| 912 | +/* NOTE: _rl_last_c_pos is used as a buffer index when not in a locale
|
---|
| 913 | + supporting multibyte characters, and an absolute cursor position when
|
---|
| 914 | + in such a locale. This is an artifact of the donated multibyte support.
|
---|
| 915 | + Care must be taken when modifying its value. */
|
---|
| 916 | +int _rl_last_c_pos = 0;
|
---|
| 917 | +int _rl_last_v_pos = 0;
|
---|
| 918 | +
|
---|
| 919 | +static int cpos_adjusted;
|
---|
| 920 | +static int cpos_buffer_position;
|
---|
| 921 | +
|
---|
| 922 | +/* Number of lines currently on screen minus 1. */
|
---|
| 923 | +int _rl_vis_botlin = 0;
|
---|
| 924 | +
|
---|
| 925 | +/* Variables used only in this file. */
|
---|
| 926 | +/* The last left edge of text that was displayed. This is used when
|
---|
| 927 | + doing horizontal scrolling. It shifts in thirds of a screenwidth. */
|
---|
| 928 | +static int last_lmargin;
|
---|
| 929 | +
|
---|
| 930 | +/* The line display buffers. One is the line currently displayed on
|
---|
| 931 | + the screen. The other is the line about to be displayed. */
|
---|
| 932 | +static char *visible_line = (char *)NULL;
|
---|
| 933 | +static char *invisible_line = (char *)NULL;
|
---|
| 934 | +
|
---|
| 935 | +/* A buffer for `modeline' messages. */
|
---|
| 936 | +static char msg_buf[128];
|
---|
| 937 | +
|
---|
| 938 | +/* Non-zero forces the redisplay even if we thought it was unnecessary. */
|
---|
| 939 | +static int forced_display;
|
---|
| 940 | +
|
---|
| 941 | +/* Default and initial buffer size. Can grow. */
|
---|
| 942 | +static int line_size = 1024;
|
---|
| 943 | +
|
---|
| 944 | +/* Variables to keep track of the expanded prompt string, which may
|
---|
| 945 | + include invisible characters. */
|
---|
| 946 | +
|
---|
| 947 | +static char *local_prompt, *local_prompt_prefix;
|
---|
| 948 | +static int local_prompt_len;
|
---|
| 949 | +static int prompt_visible_length, prompt_prefix_length;
|
---|
| 950 | +
|
---|
| 951 | +/* The number of invisible characters in the line currently being
|
---|
| 952 | + displayed on the screen. */
|
---|
| 953 | +static int visible_wrap_offset;
|
---|
| 954 | +
|
---|
| 955 | +/* The number of invisible characters in the prompt string. Static so it
|
---|
| 956 | + can be shared between rl_redisplay and update_line */
|
---|
| 957 | +static int wrap_offset;
|
---|
| 958 | +
|
---|
| 959 | +/* The index of the last invisible character in the prompt string. */
|
---|
| 960 | +static int prompt_last_invisible;
|
---|
| 961 | +
|
---|
| 962 | +/* The length (buffer offset) of the first line of the last (possibly
|
---|
| 963 | + multi-line) buffer displayed on the screen. */
|
---|
| 964 | +static int visible_first_line_len;
|
---|
| 965 | +
|
---|
| 966 | +/* Number of invisible characters on the first physical line of the prompt.
|
---|
| 967 | + Only valid when the number of physical characters in the prompt exceeds
|
---|
| 968 | + (or is equal to) _rl_screenwidth. */
|
---|
| 969 | +static int prompt_invis_chars_first_line;
|
---|
| 970 | +
|
---|
| 971 | +static int prompt_last_screen_line;
|
---|
| 972 | +
|
---|
| 973 | +static int prompt_physical_chars;
|
---|
| 974 | +
|
---|
| 975 | +/* Variables to save and restore prompt and display information. */
|
---|
| 976 | +
|
---|
| 977 | +/* These are getting numerous enough that it's time to create a struct. */
|
---|
| 978 | +
|
---|
| 979 | +static char *saved_local_prompt;
|
---|
| 980 | +static char *saved_local_prefix;
|
---|
| 981 | +static int saved_last_invisible;
|
---|
| 982 | +static int saved_visible_length;
|
---|
| 983 | +static int saved_prefix_length;
|
---|
| 984 | +static int saved_local_length;
|
---|
| 985 | +static int saved_invis_chars_first_line;
|
---|
| 986 | +static int saved_physical_chars;
|
---|
| 987 | +
|
---|
| 988 | +/* Expand the prompt string S and return the number of visible
|
---|
| 989 | + characters in *LP, if LP is not null. This is currently more-or-less
|
---|
| 990 | + a placeholder for expansion. LIP, if non-null is a place to store the
|
---|
| 991 | + index of the last invisible character in the returned string. NIFLP,
|
---|
| 992 | + if non-zero, is a place to store the number of invisible characters in
|
---|
| 993 | + the first prompt line. The previous are used as byte counts -- indexes
|
---|
| 994 | + into a character buffer. */
|
---|
| 995 | +
|
---|
| 996 | +/* Current implementation:
|
---|
| 997 | + \001 (^A) start non-visible characters
|
---|
| 998 | + \002 (^B) end non-visible characters
|
---|
| 999 | + all characters except \001 and \002 (following a \001) are copied to
|
---|
| 1000 | + the returned string; all characters except those between \001 and
|
---|
| 1001 | + \002 are assumed to be `visible'. */
|
---|
| 1002 | +
|
---|
| 1003 | +static char *
|
---|
| 1004 | +expand_prompt (pmt, lp, lip, niflp, vlp)
|
---|
| 1005 | + char *pmt;
|
---|
| 1006 | + int *lp, *lip, *niflp, *vlp;
|
---|
| 1007 | +{
|
---|
| 1008 | + char *r, *ret, *p, *igstart;
|
---|
| 1009 | + int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
|
---|
| 1010 | +
|
---|
| 1011 | + /* Short-circuit if we can. */
|
---|
| 1012 | + if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
|
---|
| 1013 | + {
|
---|
| 1014 | + r = savestring (pmt);
|
---|
| 1015 | + if (lp)
|
---|
| 1016 | + *lp = strlen (r);
|
---|
| 1017 | + if (lip)
|
---|
| 1018 | + *lip = 0;
|
---|
| 1019 | + if (niflp)
|
---|
| 1020 | + *niflp = 0;
|
---|
| 1021 | + if (vlp)
|
---|
| 1022 | + *vlp = lp ? *lp : strlen (r);
|
---|
| 1023 | + return r;
|
---|
| 1024 | + }
|
---|
| 1025 | +
|
---|
| 1026 | + l = strlen (pmt);
|
---|
| 1027 | + r = ret = (char *)xmalloc (l + 1);
|
---|
| 1028 | +
|
---|
| 1029 | + invfl = 0; /* invisible chars in first line of prompt */
|
---|
| 1030 | + invflset = 0; /* we only want to set invfl once */
|
---|
| 1031 | +
|
---|
| 1032 | + igstart = 0;
|
---|
| 1033 | + for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++)
|
---|
| 1034 | + {
|
---|
| 1035 | + /* This code strips the invisible character string markers
|
---|
| 1036 | + RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
|
---|
| 1037 | + if (ignoring == 0 && *p == RL_PROMPT_START_IGNORE) /* XXX - check ignoring? */
|
---|
| 1038 | + {
|
---|
| 1039 | + ignoring = 1;
|
---|
| 1040 | + igstart = p;
|
---|
| 1041 | + continue;
|
---|
| 1042 | + }
|
---|
| 1043 | + else if (ignoring && *p == RL_PROMPT_END_IGNORE)
|
---|
| 1044 | + {
|
---|
| 1045 | + ignoring = 0;
|
---|
| 1046 | + if (p != (igstart + 1))
|
---|
| 1047 | + last = r - ret - 1;
|
---|
| 1048 | + continue;
|
---|
| 1049 | + }
|
---|
| 1050 | + else
|
---|
| 1051 | + {
|
---|
| 1052 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 1053 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 1054 | + {
|
---|
| 1055 | + pind = p - pmt;
|
---|
| 1056 | + ind = _rl_find_next_mbchar (pmt, pind, 1, MB_FIND_NONZERO);
|
---|
| 1057 | + l = ind - pind;
|
---|
| 1058 | + while (l--)
|
---|
| 1059 | + *r++ = *p++;
|
---|
| 1060 | + if (!ignoring)
|
---|
| 1061 | + {
|
---|
| 1062 | + rl += ind - pind;
|
---|
| 1063 | + physchars += _rl_col_width (pmt, pind, ind);
|
---|
| 1064 | + }
|
---|
| 1065 | + else
|
---|
| 1066 | + ninvis += ind - pind;
|
---|
| 1067 | + p--; /* compensate for later increment */
|
---|
| 1068 | + }
|
---|
| 1069 | + else
|
---|
| 1070 | +#endif
|
---|
| 1071 | + {
|
---|
| 1072 | + *r++ = *p;
|
---|
| 1073 | + if (!ignoring)
|
---|
| 1074 | + {
|
---|
| 1075 | + rl++; /* visible length byte counter */
|
---|
| 1076 | + physchars++;
|
---|
| 1077 | + }
|
---|
| 1078 | + else
|
---|
| 1079 | + ninvis++; /* invisible chars byte counter */
|
---|
| 1080 | + }
|
---|
| 1081 | +
|
---|
| 1082 | + if (invflset == 0 && rl >= _rl_screenwidth)
|
---|
| 1083 | + {
|
---|
| 1084 | + invfl = ninvis;
|
---|
| 1085 | + invflset = 1;
|
---|
| 1086 | + }
|
---|
| 1087 | + }
|
---|
| 1088 | + }
|
---|
| 1089 | +
|
---|
| 1090 | + if (rl < _rl_screenwidth)
|
---|
| 1091 | + invfl = ninvis;
|
---|
| 1092 | +
|
---|
| 1093 | + *r = '\0';
|
---|
| 1094 | + if (lp)
|
---|
| 1095 | + *lp = rl;
|
---|
| 1096 | + if (lip)
|
---|
| 1097 | + *lip = last;
|
---|
| 1098 | + if (niflp)
|
---|
| 1099 | + *niflp = invfl;
|
---|
| 1100 | + if (vlp)
|
---|
| 1101 | + *vlp = physchars;
|
---|
| 1102 | + return ret;
|
---|
| 1103 | +}
|
---|
| 1104 | +
|
---|
| 1105 | +/* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from
|
---|
| 1106 | + PMT and return the rest of PMT. */
|
---|
| 1107 | +char *
|
---|
| 1108 | +_rl_strip_prompt (pmt)
|
---|
| 1109 | + char *pmt;
|
---|
| 1110 | +{
|
---|
| 1111 | + char *ret;
|
---|
| 1112 | +
|
---|
| 1113 | + ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL);
|
---|
| 1114 | + return ret;
|
---|
| 1115 | +}
|
---|
| 1116 | +
|
---|
| 1117 | +/*
|
---|
| 1118 | + * Expand the prompt string into the various display components, if
|
---|
| 1119 | + * necessary.
|
---|
| 1120 | + *
|
---|
| 1121 | + * local_prompt = expanded last line of string in rl_display_prompt
|
---|
| 1122 | + * (portion after the final newline)
|
---|
| 1123 | + * local_prompt_prefix = portion before last newline of rl_display_prompt,
|
---|
| 1124 | + * expanded via expand_prompt
|
---|
| 1125 | + * prompt_visible_length = number of visible characters in local_prompt
|
---|
| 1126 | + * prompt_prefix_length = number of visible characters in local_prompt_prefix
|
---|
| 1127 | + *
|
---|
| 1128 | + * This function is called once per call to readline(). It may also be
|
---|
| 1129 | + * called arbitrarily to expand the primary prompt.
|
---|
| 1130 | + *
|
---|
| 1131 | + * The return value is the number of visible characters on the last line
|
---|
| 1132 | + * of the (possibly multi-line) prompt.
|
---|
| 1133 | + */
|
---|
| 1134 | +int
|
---|
| 1135 | +rl_expand_prompt (prompt)
|
---|
| 1136 | + char *prompt;
|
---|
| 1137 | +{
|
---|
| 1138 | + char *p, *t;
|
---|
| 1139 | + int c;
|
---|
| 1140 | +
|
---|
| 1141 | + /* Clear out any saved values. */
|
---|
| 1142 | + FREE (local_prompt);
|
---|
| 1143 | + FREE (local_prompt_prefix);
|
---|
| 1144 | +
|
---|
| 1145 | + local_prompt = local_prompt_prefix = (char *)0;
|
---|
| 1146 | + local_prompt_len = 0;
|
---|
| 1147 | + prompt_last_invisible = prompt_invis_chars_first_line = 0;
|
---|
| 1148 | + prompt_visible_length = prompt_physical_chars = 0;
|
---|
| 1149 | +
|
---|
| 1150 | + if (prompt == 0 || *prompt == 0)
|
---|
| 1151 | + return (0);
|
---|
| 1152 | +
|
---|
| 1153 | + p = strrchr (prompt, '\n');
|
---|
| 1154 | + if (!p)
|
---|
| 1155 | + {
|
---|
| 1156 | + /* The prompt is only one logical line, though it might wrap. */
|
---|
| 1157 | + local_prompt = expand_prompt (prompt, &prompt_visible_length,
|
---|
| 1158 | + &prompt_last_invisible,
|
---|
| 1159 | + &prompt_invis_chars_first_line,
|
---|
| 1160 | + &prompt_physical_chars);
|
---|
| 1161 | + local_prompt_prefix = (char *)0;
|
---|
| 1162 | + local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
|
---|
| 1163 | + return (prompt_visible_length);
|
---|
| 1164 | + }
|
---|
| 1165 | + else
|
---|
| 1166 | + {
|
---|
| 1167 | + /* The prompt spans multiple lines. */
|
---|
| 1168 | + t = ++p;
|
---|
| 1169 | + local_prompt = expand_prompt (p, &prompt_visible_length,
|
---|
| 1170 | + &prompt_last_invisible,
|
---|
| 1171 | + &prompt_invis_chars_first_line,
|
---|
| 1172 | + &prompt_physical_chars);
|
---|
| 1173 | + c = *t; *t = '\0';
|
---|
| 1174 | + /* The portion of the prompt string up to and including the
|
---|
| 1175 | + final newline is now null-terminated. */
|
---|
| 1176 | + local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
|
---|
| 1177 | + (int *)NULL,
|
---|
| 1178 | + (int *)NULL,
|
---|
| 1179 | + (int *)NULL);
|
---|
| 1180 | + *t = c;
|
---|
| 1181 | + local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
|
---|
| 1182 | + return (prompt_prefix_length);
|
---|
| 1183 | + }
|
---|
| 1184 | +}
|
---|
| 1185 | +
|
---|
| 1186 | +/* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated
|
---|
| 1187 | + arrays of line break markers. MINSIZE is the minimum size of VISIBLE_LINE
|
---|
| 1188 | + and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is
|
---|
| 1189 | + increased. If the lines have already been allocated, this ensures that
|
---|
| 1190 | + they can hold at least MINSIZE characters. */
|
---|
| 1191 | +static void
|
---|
| 1192 | +init_line_structures (minsize)
|
---|
| 1193 | + int minsize;
|
---|
| 1194 | +{
|
---|
| 1195 | + register int n;
|
---|
| 1196 | +
|
---|
| 1197 | + if (invisible_line == 0) /* initialize it */
|
---|
| 1198 | + {
|
---|
| 1199 | + if (line_size < minsize)
|
---|
| 1200 | + line_size = minsize;
|
---|
| 1201 | + visible_line = (char *)xmalloc (line_size);
|
---|
| 1202 | + invisible_line = (char *)xmalloc (line_size);
|
---|
| 1203 | + }
|
---|
| 1204 | + else if (line_size < minsize) /* ensure it can hold MINSIZE chars */
|
---|
| 1205 | + {
|
---|
| 1206 | + line_size *= 2;
|
---|
| 1207 | + if (line_size < minsize)
|
---|
| 1208 | + line_size = minsize;
|
---|
| 1209 | + visible_line = (char *)xrealloc (visible_line, line_size);
|
---|
| 1210 | + invisible_line = (char *)xrealloc (invisible_line, line_size);
|
---|
| 1211 | + }
|
---|
| 1212 | +
|
---|
| 1213 | + for (n = minsize; n < line_size; n++)
|
---|
| 1214 | + {
|
---|
| 1215 | + visible_line[n] = 0;
|
---|
| 1216 | + invisible_line[n] = 1;
|
---|
| 1217 | + }
|
---|
| 1218 | +
|
---|
| 1219 | + if (vis_lbreaks == 0)
|
---|
| 1220 | + {
|
---|
| 1221 | + /* should be enough. */
|
---|
| 1222 | + inv_lbsize = vis_lbsize = 256;
|
---|
| 1223 | + inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int));
|
---|
| 1224 | + vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int));
|
---|
| 1225 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 1226 | + _rl_wrapped_line = (int *)xmalloc (vis_lbsize * sizeof (int));
|
---|
| 1227 | +#endif
|
---|
| 1228 | + inv_lbreaks[0] = vis_lbreaks[0] = 0;
|
---|
| 1229 | + }
|
---|
| 1230 | +}
|
---|
| 1231 | +
|
---|
| 1232 | +/* Basic redisplay algorithm. */
|
---|
| 1233 | +void
|
---|
| 1234 | +rl_redisplay ()
|
---|
| 1235 | +{
|
---|
| 1236 | + register int in, out, c, linenum, cursor_linenum;
|
---|
| 1237 | + register char *line;
|
---|
| 1238 | + int inv_botlin, lb_botlin, lb_linenum, o_cpos;
|
---|
| 1239 | + int newlines, lpos, temp, modmark, n0, num;
|
---|
| 1240 | + char *prompt_this_line;
|
---|
| 1241 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 1242 | + wchar_t wc;
|
---|
| 1243 | + size_t wc_bytes;
|
---|
| 1244 | + int wc_width;
|
---|
| 1245 | + mbstate_t ps;
|
---|
| 1246 | + int _rl_wrapped_multicolumn = 0;
|
---|
| 1247 | +#endif
|
---|
| 1248 | +
|
---|
| 1249 | + if (!readline_echoing_p)
|
---|
| 1250 | + return;
|
---|
| 1251 | +
|
---|
| 1252 | + if (!rl_display_prompt)
|
---|
| 1253 | + rl_display_prompt = "";
|
---|
| 1254 | +
|
---|
| 1255 | + if (invisible_line == 0 || vis_lbreaks == 0)
|
---|
| 1256 | + {
|
---|
| 1257 | + init_line_structures (0);
|
---|
| 1258 | + rl_on_new_line ();
|
---|
| 1259 | + }
|
---|
| 1260 | +
|
---|
| 1261 | + /* Draw the line into the buffer. */
|
---|
| 1262 | + cpos_buffer_position = -1;
|
---|
| 1263 | +
|
---|
| 1264 | + line = invisible_line;
|
---|
| 1265 | + out = inv_botlin = 0;
|
---|
| 1266 | +
|
---|
| 1267 | + /* Mark the line as modified or not. We only do this for history
|
---|
| 1268 | + lines. */
|
---|
| 1269 | + modmark = 0;
|
---|
| 1270 | + if (_rl_mark_modified_lines && current_history () && rl_undo_list)
|
---|
| 1271 | + {
|
---|
| 1272 | + line[out++] = '*';
|
---|
| 1273 | + line[out] = '\0';
|
---|
| 1274 | + modmark = 1;
|
---|
| 1275 | + }
|
---|
| 1276 | +
|
---|
| 1277 | + /* If someone thought that the redisplay was handled, but the currently
|
---|
| 1278 | + visible line has a different modification state than the one about
|
---|
| 1279 | + to become visible, then correct the caller's misconception. */
|
---|
| 1280 | + if (visible_line[0] != invisible_line[0])
|
---|
| 1281 | + rl_display_fixed = 0;
|
---|
| 1282 | +
|
---|
| 1283 | + /* If the prompt to be displayed is the `primary' readline prompt (the
|
---|
| 1284 | + one passed to readline()), use the values we have already expanded.
|
---|
| 1285 | + If not, use what's already in rl_display_prompt. WRAP_OFFSET is the
|
---|
| 1286 | + number of non-visible characters in the prompt string. */
|
---|
| 1287 | + if (rl_display_prompt == rl_prompt || local_prompt)
|
---|
| 1288 | + {
|
---|
| 1289 | + if (local_prompt_prefix && forced_display)
|
---|
| 1290 | + _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
|
---|
| 1291 | +
|
---|
| 1292 | + if (local_prompt_len > 0)
|
---|
| 1293 | + {
|
---|
| 1294 | + temp = local_prompt_len + out + 2;
|
---|
| 1295 | + if (temp >= line_size)
|
---|
| 1296 | + {
|
---|
| 1297 | + line_size = (temp + 1024) - (temp % 1024);
|
---|
| 1298 | + visible_line = (char *)xrealloc (visible_line, line_size);
|
---|
| 1299 | + line = invisible_line = (char *)xrealloc (invisible_line, line_size);
|
---|
| 1300 | + }
|
---|
| 1301 | + strncpy (line + out, local_prompt, local_prompt_len);
|
---|
| 1302 | + out += local_prompt_len;
|
---|
| 1303 | + }
|
---|
| 1304 | + line[out] = '\0';
|
---|
| 1305 | + wrap_offset = local_prompt_len - prompt_visible_length;
|
---|
| 1306 | + }
|
---|
| 1307 | + else
|
---|
| 1308 | + {
|
---|
| 1309 | + int pmtlen;
|
---|
| 1310 | + prompt_this_line = strrchr (rl_display_prompt, '\n');
|
---|
| 1311 | + if (!prompt_this_line)
|
---|
| 1312 | + prompt_this_line = rl_display_prompt;
|
---|
| 1313 | + else
|
---|
| 1314 | + {
|
---|
| 1315 | + prompt_this_line++;
|
---|
| 1316 | + pmtlen = prompt_this_line - rl_display_prompt; /* temp var */
|
---|
| 1317 | + if (forced_display)
|
---|
| 1318 | + {
|
---|
| 1319 | + _rl_output_some_chars (rl_display_prompt, pmtlen);
|
---|
| 1320 | + /* Make sure we are at column zero even after a newline,
|
---|
| 1321 | + regardless of the state of terminal output processing. */
|
---|
| 1322 | + if (pmtlen < 2 || prompt_this_line[-2] != '\r')
|
---|
| 1323 | + cr ();
|
---|
| 1324 | + }
|
---|
| 1325 | + }
|
---|
| 1326 | +
|
---|
| 1327 | + prompt_physical_chars = pmtlen = strlen (prompt_this_line);
|
---|
| 1328 | + temp = pmtlen + out + 2;
|
---|
| 1329 | + if (temp >= line_size)
|
---|
| 1330 | + {
|
---|
| 1331 | + line_size = (temp + 1024) - (temp % 1024);
|
---|
| 1332 | + visible_line = (char *)xrealloc (visible_line, line_size);
|
---|
| 1333 | + line = invisible_line = (char *)xrealloc (invisible_line, line_size);
|
---|
| 1334 | + }
|
---|
| 1335 | + strncpy (line + out, prompt_this_line, pmtlen);
|
---|
| 1336 | + out += pmtlen;
|
---|
| 1337 | + line[out] = '\0';
|
---|
| 1338 | + wrap_offset = prompt_invis_chars_first_line = 0;
|
---|
| 1339 | + }
|
---|
| 1340 | +
|
---|
| 1341 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 1342 | +#define CHECK_INV_LBREAKS() \
|
---|
| 1343 | + do { \
|
---|
| 1344 | + if (newlines >= (inv_lbsize - 2)) \
|
---|
| 1345 | + { \
|
---|
| 1346 | + inv_lbsize *= 2; \
|
---|
| 1347 | + inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
|
---|
| 1348 | + _rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \
|
---|
| 1349 | + } \
|
---|
| 1350 | + } while (0)
|
---|
| 1351 | +#else
|
---|
| 1352 | +#define CHECK_INV_LBREAKS() \
|
---|
| 1353 | + do { \
|
---|
| 1354 | + if (newlines >= (inv_lbsize - 2)) \
|
---|
| 1355 | + { \
|
---|
| 1356 | + inv_lbsize *= 2; \
|
---|
| 1357 | + inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
|
---|
| 1358 | + } \
|
---|
| 1359 | + } while (0)
|
---|
| 1360 | +#endif /* HANDLE_MULTIBYTE */
|
---|
| 1361 | +
|
---|
| 1362 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 1363 | +#define CHECK_LPOS() \
|
---|
| 1364 | + do { \
|
---|
| 1365 | + lpos++; \
|
---|
| 1366 | + if (lpos >= _rl_screenwidth) \
|
---|
| 1367 | + { \
|
---|
| 1368 | + if (newlines >= (inv_lbsize - 2)) \
|
---|
| 1369 | + { \
|
---|
| 1370 | + inv_lbsize *= 2; \
|
---|
| 1371 | + inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
|
---|
| 1372 | + _rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \
|
---|
| 1373 | + } \
|
---|
| 1374 | + inv_lbreaks[++newlines] = out; \
|
---|
| 1375 | + _rl_wrapped_line[newlines] = _rl_wrapped_multicolumn; \
|
---|
| 1376 | + lpos = 0; \
|
---|
| 1377 | + } \
|
---|
| 1378 | + } while (0)
|
---|
| 1379 | +#else
|
---|
| 1380 | +#define CHECK_LPOS() \
|
---|
| 1381 | + do { \
|
---|
| 1382 | + lpos++; \
|
---|
| 1383 | + if (lpos >= _rl_screenwidth) \
|
---|
| 1384 | + { \
|
---|
| 1385 | + if (newlines >= (inv_lbsize - 2)) \
|
---|
| 1386 | + { \
|
---|
| 1387 | + inv_lbsize *= 2; \
|
---|
| 1388 | + inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
|
---|
| 1389 | + } \
|
---|
| 1390 | + inv_lbreaks[++newlines] = out; \
|
---|
| 1391 | + lpos = 0; \
|
---|
| 1392 | + } \
|
---|
| 1393 | + } while (0)
|
---|
| 1394 | +#endif
|
---|
| 1395 | +
|
---|
| 1396 | + /* inv_lbreaks[i] is where line i starts in the buffer. */
|
---|
| 1397 | + inv_lbreaks[newlines = 0] = 0;
|
---|
| 1398 | +#if 0
|
---|
| 1399 | + lpos = out - wrap_offset;
|
---|
| 1400 | +#else
|
---|
| 1401 | + lpos = prompt_physical_chars + modmark;
|
---|
| 1402 | +#endif
|
---|
| 1403 | +
|
---|
| 1404 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 1405 | + memset (_rl_wrapped_line, 0, vis_lbsize);
|
---|
| 1406 | + num = 0;
|
---|
| 1407 | +#endif
|
---|
| 1408 | +
|
---|
| 1409 | + /* prompt_invis_chars_first_line is the number of invisible characters in
|
---|
| 1410 | + the first physical line of the prompt.
|
---|
| 1411 | + wrap_offset - prompt_invis_chars_first_line is the number of invis
|
---|
| 1412 | + chars on the second line. */
|
---|
| 1413 | +
|
---|
| 1414 | + /* what if lpos is already >= _rl_screenwidth before we start drawing the
|
---|
| 1415 | + contents of the command line? */
|
---|
| 1416 | + while (lpos >= _rl_screenwidth)
|
---|
| 1417 | + {
|
---|
| 1418 | + int z;
|
---|
| 1419 | + /* fix from Darin Johnson <darin@acuson.com> for prompt string with
|
---|
| 1420 | + invisible characters that is longer than the screen width. The
|
---|
| 1421 | + prompt_invis_chars_first_line variable could be made into an array
|
---|
| 1422 | + saying how many invisible characters there are per line, but that's
|
---|
| 1423 | + probably too much work for the benefit gained. How many people have
|
---|
| 1424 | + prompts that exceed two physical lines?
|
---|
| 1425 | + Additional logic fix from Edward Catmur <ed@catmur.co.uk> */
|
---|
| 1426 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 1427 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 1428 | + {
|
---|
| 1429 | + n0 = num;
|
---|
| 1430 | + temp = local_prompt_len;
|
---|
| 1431 | + while (num < temp)
|
---|
| 1432 | + {
|
---|
| 1433 | + z = _rl_col_width (local_prompt, n0, num);
|
---|
| 1434 | + if (z > _rl_screenwidth)
|
---|
| 1435 | + {
|
---|
| 1436 | + num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
|
---|
| 1437 | + break;
|
---|
| 1438 | + }
|
---|
| 1439 | + else if (z == _rl_screenwidth)
|
---|
| 1440 | + break;
|
---|
| 1441 | + num++;
|
---|
| 1442 | + }
|
---|
| 1443 | + temp = num;
|
---|
| 1444 | + }
|
---|
| 1445 | + else
|
---|
| 1446 | +#endif /* !HANDLE_MULTIBYTE */
|
---|
| 1447 | + temp = ((newlines + 1) * _rl_screenwidth);
|
---|
| 1448 | +
|
---|
| 1449 | + /* Now account for invisible characters in the current line. */
|
---|
| 1450 | + temp += ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
|
---|
| 1451 | + : ((newlines == 1) ? wrap_offset : 0))
|
---|
| 1452 | + : ((newlines == 0) ? wrap_offset :0));
|
---|
| 1453 | +
|
---|
| 1454 | + inv_lbreaks[++newlines] = temp;
|
---|
| 1455 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 1456 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 1457 | + lpos -= _rl_col_width (local_prompt, n0, num);
|
---|
| 1458 | + else
|
---|
| 1459 | +#endif
|
---|
| 1460 | + lpos -= _rl_screenwidth;
|
---|
| 1461 | + }
|
---|
| 1462 | +
|
---|
| 1463 | + prompt_last_screen_line = newlines;
|
---|
| 1464 | +
|
---|
| 1465 | + /* Draw the rest of the line (after the prompt) into invisible_line, keeping
|
---|
| 1466 | + track of where the cursor is (cpos_buffer_position), the number of the line containing
|
---|
| 1467 | + the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin).
|
---|
| 1468 | + It maintains an array of line breaks for display (inv_lbreaks).
|
---|
| 1469 | + This handles expanding tabs for display and displaying meta characters. */
|
---|
| 1470 | + lb_linenum = 0;
|
---|
| 1471 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 1472 | + in = 0;
|
---|
| 1473 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 1474 | + {
|
---|
| 1475 | + memset (&ps, 0, sizeof (mbstate_t));
|
---|
| 1476 | + wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps);
|
---|
| 1477 | + }
|
---|
| 1478 | + else
|
---|
| 1479 | + wc_bytes = 1;
|
---|
| 1480 | + while (in < rl_end)
|
---|
| 1481 | +#else
|
---|
| 1482 | + for (in = 0; in < rl_end; in++)
|
---|
| 1483 | +#endif
|
---|
| 1484 | + {
|
---|
| 1485 | + c = (unsigned char)rl_line_buffer[in];
|
---|
| 1486 | +
|
---|
| 1487 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 1488 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 1489 | + {
|
---|
| 1490 | + if (MB_INVALIDCH (wc_bytes))
|
---|
| 1491 | + {
|
---|
| 1492 | + /* Byte sequence is invalid or shortened. Assume that the
|
---|
| 1493 | + first byte represents a character. */
|
---|
| 1494 | + wc_bytes = 1;
|
---|
| 1495 | + /* Assume that a character occupies a single column. */
|
---|
| 1496 | + wc_width = 1;
|
---|
| 1497 | + memset (&ps, 0, sizeof (mbstate_t));
|
---|
| 1498 | + }
|
---|
| 1499 | + else if (MB_NULLWCH (wc_bytes))
|
---|
| 1500 | + break; /* Found '\0' */
|
---|
| 1501 | + else
|
---|
| 1502 | + {
|
---|
| 1503 | + temp = wcwidth (wc);
|
---|
| 1504 | + wc_width = (temp >= 0) ? temp : 1;
|
---|
| 1505 | + }
|
---|
| 1506 | + }
|
---|
| 1507 | +#endif
|
---|
| 1508 | +
|
---|
| 1509 | + if (out + 8 >= line_size) /* XXX - 8 for \t */
|
---|
| 1510 | + {
|
---|
| 1511 | + line_size *= 2;
|
---|
| 1512 | + visible_line = (char *)xrealloc (visible_line, line_size);
|
---|
| 1513 | + invisible_line = (char *)xrealloc (invisible_line, line_size);
|
---|
| 1514 | + line = invisible_line;
|
---|
| 1515 | + }
|
---|
| 1516 | +
|
---|
| 1517 | + if (in == rl_point)
|
---|
| 1518 | + {
|
---|
| 1519 | + cpos_buffer_position = out;
|
---|
| 1520 | + lb_linenum = newlines;
|
---|
| 1521 | + }
|
---|
| 1522 | +
|
---|
| 1523 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 1524 | + if (META_CHAR (c) && _rl_output_meta_chars == 0) /* XXX - clean up */
|
---|
| 1525 | +#else
|
---|
| 1526 | + if (META_CHAR (c))
|
---|
| 1527 | +#endif
|
---|
| 1528 | + {
|
---|
| 1529 | + if (_rl_output_meta_chars == 0)
|
---|
| 1530 | + {
|
---|
| 1531 | + sprintf (line + out, "\\%o", c);
|
---|
| 1532 | +
|
---|
| 1533 | + if (lpos + 4 >= _rl_screenwidth)
|
---|
| 1534 | + {
|
---|
| 1535 | + temp = _rl_screenwidth - lpos;
|
---|
| 1536 | + CHECK_INV_LBREAKS ();
|
---|
| 1537 | + inv_lbreaks[++newlines] = out + temp;
|
---|
| 1538 | + lpos = 4 - temp;
|
---|
| 1539 | + }
|
---|
| 1540 | + else
|
---|
| 1541 | + lpos += 4;
|
---|
| 1542 | +
|
---|
| 1543 | + out += 4;
|
---|
| 1544 | + }
|
---|
| 1545 | + else
|
---|
| 1546 | + {
|
---|
| 1547 | + line[out++] = c;
|
---|
| 1548 | + CHECK_LPOS();
|
---|
| 1549 | + }
|
---|
| 1550 | + }
|
---|
| 1551 | +#if defined (DISPLAY_TABS)
|
---|
| 1552 | + else if (c == '\t')
|
---|
| 1553 | + {
|
---|
| 1554 | + register int newout;
|
---|
| 1555 | +
|
---|
| 1556 | +#if 0
|
---|
| 1557 | + newout = (out | (int)7) + 1;
|
---|
| 1558 | +#else
|
---|
| 1559 | + newout = out + 8 - lpos % 8;
|
---|
| 1560 | +#endif
|
---|
| 1561 | + temp = newout - out;
|
---|
| 1562 | + if (lpos + temp >= _rl_screenwidth)
|
---|
| 1563 | + {
|
---|
| 1564 | + register int temp2;
|
---|
| 1565 | + temp2 = _rl_screenwidth - lpos;
|
---|
| 1566 | + CHECK_INV_LBREAKS ();
|
---|
| 1567 | + inv_lbreaks[++newlines] = out + temp2;
|
---|
| 1568 | + lpos = temp - temp2;
|
---|
| 1569 | + while (out < newout)
|
---|
| 1570 | + line[out++] = ' ';
|
---|
| 1571 | + }
|
---|
| 1572 | + else
|
---|
| 1573 | + {
|
---|
| 1574 | + while (out < newout)
|
---|
| 1575 | + line[out++] = ' ';
|
---|
| 1576 | + lpos += temp;
|
---|
| 1577 | + }
|
---|
| 1578 | + }
|
---|
| 1579 | +#endif
|
---|
| 1580 | + else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
|
---|
| 1581 | + {
|
---|
| 1582 | + line[out++] = '\0'; /* XXX - sentinel */
|
---|
| 1583 | + CHECK_INV_LBREAKS ();
|
---|
| 1584 | + inv_lbreaks[++newlines] = out;
|
---|
| 1585 | + lpos = 0;
|
---|
| 1586 | + }
|
---|
| 1587 | + else if (CTRL_CHAR (c) || c == RUBOUT)
|
---|
| 1588 | + {
|
---|
| 1589 | + line[out++] = '^';
|
---|
| 1590 | + CHECK_LPOS();
|
---|
| 1591 | + line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
|
---|
| 1592 | + CHECK_LPOS();
|
---|
| 1593 | + }
|
---|
| 1594 | + else
|
---|
| 1595 | + {
|
---|
| 1596 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 1597 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 1598 | + {
|
---|
| 1599 | + register int i;
|
---|
| 1600 | +
|
---|
| 1601 | + _rl_wrapped_multicolumn = 0;
|
---|
| 1602 | +
|
---|
| 1603 | + if (_rl_screenwidth < lpos + wc_width)
|
---|
| 1604 | + for (i = lpos; i < _rl_screenwidth; i++)
|
---|
| 1605 | + {
|
---|
| 1606 | + /* The space will be removed in update_line() */
|
---|
| 1607 | + line[out++] = ' ';
|
---|
| 1608 | + _rl_wrapped_multicolumn++;
|
---|
| 1609 | + CHECK_LPOS();
|
---|
| 1610 | + }
|
---|
| 1611 | + if (in == rl_point)
|
---|
| 1612 | + {
|
---|
| 1613 | + cpos_buffer_position = out;
|
---|
| 1614 | + lb_linenum = newlines;
|
---|
| 1615 | + }
|
---|
| 1616 | + for (i = in; i < in+wc_bytes; i++)
|
---|
| 1617 | + line[out++] = rl_line_buffer[i];
|
---|
| 1618 | + for (i = 0; i < wc_width; i++)
|
---|
| 1619 | + CHECK_LPOS();
|
---|
| 1620 | + }
|
---|
| 1621 | + else
|
---|
| 1622 | + {
|
---|
| 1623 | + line[out++] = c;
|
---|
| 1624 | + CHECK_LPOS();
|
---|
| 1625 | + }
|
---|
| 1626 | +#else
|
---|
| 1627 | + line[out++] = c;
|
---|
| 1628 | + CHECK_LPOS();
|
---|
| 1629 | +#endif
|
---|
| 1630 | + }
|
---|
| 1631 | +
|
---|
| 1632 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 1633 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 1634 | + {
|
---|
| 1635 | + in += wc_bytes;
|
---|
| 1636 | + wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps);
|
---|
| 1637 | + }
|
---|
| 1638 | + else
|
---|
| 1639 | + in++;
|
---|
| 1640 | +#endif
|
---|
| 1641 | +
|
---|
| 1642 | + }
|
---|
| 1643 | + line[out] = '\0';
|
---|
| 1644 | + if (cpos_buffer_position < 0)
|
---|
| 1645 | + {
|
---|
| 1646 | + cpos_buffer_position = out;
|
---|
| 1647 | + lb_linenum = newlines;
|
---|
| 1648 | + }
|
---|
| 1649 | +
|
---|
| 1650 | + inv_botlin = lb_botlin = newlines;
|
---|
| 1651 | + CHECK_INV_LBREAKS ();
|
---|
| 1652 | + inv_lbreaks[newlines+1] = out;
|
---|
| 1653 | + cursor_linenum = lb_linenum;
|
---|
| 1654 | +
|
---|
| 1655 | + /* CPOS_BUFFER_POSITION == position in buffer where cursor should be placed.
|
---|
| 1656 | + CURSOR_LINENUM == line number where the cursor should be placed. */
|
---|
| 1657 | +
|
---|
| 1658 | + /* PWP: now is when things get a bit hairy. The visible and invisible
|
---|
| 1659 | + line buffers are really multiple lines, which would wrap every
|
---|
| 1660 | + (screenwidth - 1) characters. Go through each in turn, finding
|
---|
| 1661 | + the changed region and updating it. The line order is top to bottom. */
|
---|
| 1662 | +
|
---|
| 1663 | + /* If we can move the cursor up and down, then use multiple lines,
|
---|
| 1664 | + otherwise, let long lines display in a single terminal line, and
|
---|
| 1665 | + horizontally scroll it. */
|
---|
| 1666 | +
|
---|
| 1667 | + if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
|
---|
| 1668 | + {
|
---|
| 1669 | + int nleft, pos, changed_screen_line, tx;
|
---|
| 1670 | +
|
---|
| 1671 | + if (!rl_display_fixed || forced_display)
|
---|
| 1672 | + {
|
---|
| 1673 | + forced_display = 0;
|
---|
| 1674 | +
|
---|
| 1675 | + /* If we have more than a screenful of material to display, then
|
---|
| 1676 | + only display a screenful. We should display the last screen,
|
---|
| 1677 | + not the first. */
|
---|
| 1678 | + if (out >= _rl_screenchars)
|
---|
| 1679 | + {
|
---|
| 1680 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 1681 | + out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY);
|
---|
| 1682 | + else
|
---|
| 1683 | + out = _rl_screenchars - 1;
|
---|
| 1684 | + }
|
---|
| 1685 | +
|
---|
| 1686 | + /* The first line is at character position 0 in the buffer. The
|
---|
| 1687 | + second and subsequent lines start at inv_lbreaks[N], offset by
|
---|
| 1688 | + OFFSET (which has already been calculated above). */
|
---|
| 1689 | +
|
---|
| 1690 | +#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
|
---|
| 1691 | +#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
|
---|
| 1692 | +#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
|
---|
| 1693 | +#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
|
---|
| 1694 | +#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
|
---|
| 1695 | +#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
|
---|
| 1696 | +
|
---|
| 1697 | + /* For each line in the buffer, do the updating display. */
|
---|
| 1698 | + for (linenum = 0; linenum <= inv_botlin; linenum++)
|
---|
| 1699 | + {
|
---|
| 1700 | + /* This can lead us astray if we execute a program that changes
|
---|
| 1701 | + the locale from a non-multibyte to a multibyte one. */
|
---|
| 1702 | + o_cpos = _rl_last_c_pos;
|
---|
| 1703 | + cpos_adjusted = 0;
|
---|
| 1704 | + update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
|
---|
| 1705 | + VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
|
---|
| 1706 | +
|
---|
| 1707 | + /* update_line potentially changes _rl_last_c_pos, but doesn't
|
---|
| 1708 | + take invisible characters into account, since _rl_last_c_pos
|
---|
| 1709 | + is an absolute cursor position in a multibyte locale. See
|
---|
| 1710 | + if compensating here is the right thing, or if we have to
|
---|
| 1711 | + change update_line itself. There is one case in which
|
---|
| 1712 | + update_line adjusts _rl_last_c_pos itself (so it can pass
|
---|
| 1713 | + _rl_move_cursor_relative accurate values); it communicates
|
---|
| 1714 | + this back by setting cpos_adjusted. If we assume that
|
---|
| 1715 | + _rl_last_c_pos is correct (an absolute cursor position) each
|
---|
| 1716 | + time update_line is called, then we can assume in our
|
---|
| 1717 | + calculations that o_cpos does not need to be adjusted by
|
---|
| 1718 | + wrap_offset. */
|
---|
| 1719 | + if (linenum == 0 && (MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
|
---|
| 1720 | + cpos_adjusted == 0 &&
|
---|
| 1721 | + _rl_last_c_pos != o_cpos &&
|
---|
| 1722 | + _rl_last_c_pos > wrap_offset &&
|
---|
| 1723 | + o_cpos < prompt_last_invisible)
|
---|
| 1724 | + _rl_last_c_pos -= wrap_offset;
|
---|
| 1725 | +
|
---|
| 1726 | + /* If this is the line with the prompt, we might need to
|
---|
| 1727 | + compensate for invisible characters in the new line. Do
|
---|
| 1728 | + this only if there is not more than one new line (which
|
---|
| 1729 | + implies that we completely overwrite the old visible line)
|
---|
| 1730 | + and the new line is shorter than the old. Make sure we are
|
---|
| 1731 | + at the end of the new line before clearing. */
|
---|
| 1732 | + if (linenum == 0 &&
|
---|
| 1733 | + inv_botlin == 0 && _rl_last_c_pos == out &&
|
---|
| 1734 | + (wrap_offset > visible_wrap_offset) &&
|
---|
| 1735 | + (_rl_last_c_pos < visible_first_line_len))
|
---|
| 1736 | + {
|
---|
| 1737 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 1738 | + nleft = _rl_screenwidth - _rl_last_c_pos;
|
---|
| 1739 | + else
|
---|
| 1740 | + nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
|
---|
| 1741 | + if (nleft)
|
---|
| 1742 | + _rl_clear_to_eol (nleft);
|
---|
| 1743 | + }
|
---|
| 1744 | +
|
---|
| 1745 | + /* Since the new first line is now visible, save its length. */
|
---|
| 1746 | + if (linenum == 0)
|
---|
| 1747 | + visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
|
---|
| 1748 | + }
|
---|
| 1749 | +
|
---|
| 1750 | + /* We may have deleted some lines. If so, clear the left over
|
---|
| 1751 | + blank ones at the bottom out. */
|
---|
| 1752 | + if (_rl_vis_botlin > inv_botlin)
|
---|
| 1753 | + {
|
---|
| 1754 | + char *tt;
|
---|
| 1755 | + for (; linenum <= _rl_vis_botlin; linenum++)
|
---|
| 1756 | + {
|
---|
| 1757 | + tt = VIS_CHARS (linenum);
|
---|
| 1758 | + _rl_move_vert (linenum);
|
---|
| 1759 | + _rl_move_cursor_relative (0, tt);
|
---|
| 1760 | + _rl_clear_to_eol
|
---|
| 1761 | + ((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth);
|
---|
| 1762 | + }
|
---|
| 1763 | + }
|
---|
| 1764 | + _rl_vis_botlin = inv_botlin;
|
---|
| 1765 | +
|
---|
| 1766 | + /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
|
---|
| 1767 | + different screen line during this redisplay. */
|
---|
| 1768 | + changed_screen_line = _rl_last_v_pos != cursor_linenum;
|
---|
| 1769 | + if (changed_screen_line)
|
---|
| 1770 | + {
|
---|
| 1771 | + _rl_move_vert (cursor_linenum);
|
---|
| 1772 | + /* If we moved up to the line with the prompt using _rl_term_up,
|
---|
| 1773 | + the physical cursor position on the screen stays the same,
|
---|
| 1774 | + but the buffer position needs to be adjusted to account
|
---|
| 1775 | + for invisible characters. */
|
---|
| 1776 | + if ((MB_CUR_MAX == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset)
|
---|
| 1777 | + _rl_last_c_pos += wrap_offset;
|
---|
| 1778 | + }
|
---|
| 1779 | +
|
---|
| 1780 | + /* We have to reprint the prompt if it contains invisible
|
---|
| 1781 | + characters, since it's not generally OK to just reprint
|
---|
| 1782 | + the characters from the current cursor position. But we
|
---|
| 1783 | + only need to reprint it if the cursor is before the last
|
---|
| 1784 | + invisible character in the prompt string. */
|
---|
| 1785 | + nleft = prompt_visible_length + wrap_offset;
|
---|
| 1786 | + if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
|
---|
| 1787 | +#if 0
|
---|
| 1788 | + _rl_last_c_pos <= PROMPT_ENDING_INDEX && local_prompt)
|
---|
| 1789 | +#else
|
---|
| 1790 | + _rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt)
|
---|
| 1791 | +#endif
|
---|
| 1792 | + {
|
---|
| 1793 | +#if defined (__MSDOS__)
|
---|
| 1794 | + putc ('\r', rl_outstream);
|
---|
| 1795 | +#else
|
---|
| 1796 | + if (_rl_term_cr)
|
---|
| 1797 | + tputs (_rl_term_cr, 1, _rl_output_character_function);
|
---|
| 1798 | +#endif
|
---|
| 1799 | + _rl_output_some_chars (local_prompt, nleft);
|
---|
| 1800 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 1801 | + _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft) - wrap_offset;
|
---|
| 1802 | + else
|
---|
| 1803 | + _rl_last_c_pos = nleft;
|
---|
| 1804 | + }
|
---|
| 1805 | +
|
---|
| 1806 | + /* Where on that line? And where does that line start
|
---|
| 1807 | + in the buffer? */
|
---|
| 1808 | + pos = inv_lbreaks[cursor_linenum];
|
---|
| 1809 | + /* nleft == number of characters in the line buffer between the
|
---|
| 1810 | + start of the line and the desired cursor position. */
|
---|
| 1811 | + nleft = cpos_buffer_position - pos;
|
---|
| 1812 | +
|
---|
| 1813 | + /* NLEFT is now a number of characters in a buffer. When in a
|
---|
| 1814 | + multibyte locale, however, _rl_last_c_pos is an absolute cursor
|
---|
| 1815 | + position that doesn't take invisible characters in the prompt
|
---|
| 1816 | + into account. We use a fudge factor to compensate. */
|
---|
| 1817 | +
|
---|
| 1818 | + /* Since _rl_backspace() doesn't know about invisible characters in the
|
---|
| 1819 | + prompt, and there's no good way to tell it, we compensate for
|
---|
| 1820 | + those characters here and call _rl_backspace() directly. */
|
---|
| 1821 | + if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
|
---|
| 1822 | + {
|
---|
| 1823 | + /* TX == new physical cursor position in multibyte locale. */
|
---|
| 1824 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 1825 | + tx = _rl_col_width (&visible_line[pos], 0, nleft) - visible_wrap_offset;
|
---|
| 1826 | + else
|
---|
| 1827 | + tx = nleft;
|
---|
| 1828 | + if (tx >= 0 && _rl_last_c_pos > tx)
|
---|
| 1829 | + {
|
---|
| 1830 | + _rl_backspace (_rl_last_c_pos - tx); /* XXX */
|
---|
| 1831 | + _rl_last_c_pos = tx;
|
---|
| 1832 | + }
|
---|
| 1833 | + }
|
---|
| 1834 | +
|
---|
| 1835 | + /* We need to note that in a multibyte locale we are dealing with
|
---|
| 1836 | + _rl_last_c_pos as an absolute cursor position, but moving to a
|
---|
| 1837 | + point specified by a buffer position (NLEFT) that doesn't take
|
---|
| 1838 | + invisible characters into account. */
|
---|
| 1839 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 1840 | + _rl_move_cursor_relative (nleft, &invisible_line[pos]);
|
---|
| 1841 | + else if (nleft != _rl_last_c_pos)
|
---|
| 1842 | + _rl_move_cursor_relative (nleft, &invisible_line[pos]);
|
---|
| 1843 | + }
|
---|
| 1844 | + }
|
---|
| 1845 | + else /* Do horizontal scrolling. */
|
---|
| 1846 | + {
|
---|
| 1847 | +#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
|
---|
| 1848 | + int lmargin, ndisp, nleft, phys_c_pos, t;
|
---|
| 1849 | +
|
---|
| 1850 | + /* Always at top line. */
|
---|
| 1851 | + _rl_last_v_pos = 0;
|
---|
| 1852 | +
|
---|
| 1853 | + /* Compute where in the buffer the displayed line should start. This
|
---|
| 1854 | + will be LMARGIN. */
|
---|
| 1855 | +
|
---|
| 1856 | + /* The number of characters that will be displayed before the cursor. */
|
---|
| 1857 | + ndisp = cpos_buffer_position - wrap_offset;
|
---|
| 1858 | + nleft = prompt_visible_length + wrap_offset;
|
---|
| 1859 | + /* Where the new cursor position will be on the screen. This can be
|
---|
| 1860 | + longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
|
---|
| 1861 | + phys_c_pos = cpos_buffer_position - (last_lmargin ? last_lmargin : wrap_offset);
|
---|
| 1862 | + t = _rl_screenwidth / 3;
|
---|
| 1863 | +
|
---|
| 1864 | + /* If the number of characters had already exceeded the screenwidth,
|
---|
| 1865 | + last_lmargin will be > 0. */
|
---|
| 1866 | +
|
---|
| 1867 | + /* If the number of characters to be displayed is more than the screen
|
---|
| 1868 | + width, compute the starting offset so that the cursor is about
|
---|
| 1869 | + two-thirds of the way across the screen. */
|
---|
| 1870 | + if (phys_c_pos > _rl_screenwidth - 2)
|
---|
| 1871 | + {
|
---|
| 1872 | + lmargin = cpos_buffer_position - (2 * t);
|
---|
| 1873 | + if (lmargin < 0)
|
---|
| 1874 | + lmargin = 0;
|
---|
| 1875 | + /* If the left margin would be in the middle of a prompt with
|
---|
| 1876 | + invisible characters, don't display the prompt at all. */
|
---|
| 1877 | + if (wrap_offset && lmargin > 0 && lmargin < nleft)
|
---|
| 1878 | + lmargin = nleft;
|
---|
| 1879 | + }
|
---|
| 1880 | + else if (ndisp < _rl_screenwidth - 2) /* XXX - was -1 */
|
---|
| 1881 | + lmargin = 0;
|
---|
| 1882 | + else if (phys_c_pos < 1)
|
---|
| 1883 | + {
|
---|
| 1884 | + /* If we are moving back towards the beginning of the line and
|
---|
| 1885 | + the last margin is no longer correct, compute a new one. */
|
---|
| 1886 | + lmargin = ((cpos_buffer_position - 1) / t) * t; /* XXX */
|
---|
| 1887 | + if (wrap_offset && lmargin > 0 && lmargin < nleft)
|
---|
| 1888 | + lmargin = nleft;
|
---|
| 1889 | + }
|
---|
| 1890 | + else
|
---|
| 1891 | + lmargin = last_lmargin;
|
---|
| 1892 | +
|
---|
| 1893 | + /* If the first character on the screen isn't the first character
|
---|
| 1894 | + in the display line, indicate this with a special character. */
|
---|
| 1895 | + if (lmargin > 0)
|
---|
| 1896 | + line[lmargin] = '<';
|
---|
| 1897 | +
|
---|
| 1898 | + /* If SCREENWIDTH characters starting at LMARGIN do not encompass
|
---|
| 1899 | + the whole line, indicate that with a special character at the
|
---|
| 1900 | + right edge of the screen. If LMARGIN is 0, we need to take the
|
---|
| 1901 | + wrap offset into account. */
|
---|
| 1902 | + t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth;
|
---|
| 1903 | + if (t < out)
|
---|
| 1904 | + line[t - 1] = '>';
|
---|
| 1905 | +
|
---|
| 1906 | + if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
|
---|
| 1907 | + {
|
---|
| 1908 | + forced_display = 0;
|
---|
| 1909 | + update_line (&visible_line[last_lmargin],
|
---|
| 1910 | + &invisible_line[lmargin],
|
---|
| 1911 | + 0,
|
---|
| 1912 | + _rl_screenwidth + visible_wrap_offset,
|
---|
| 1913 | + _rl_screenwidth + (lmargin ? 0 : wrap_offset),
|
---|
| 1914 | + 0);
|
---|
| 1915 | +
|
---|
| 1916 | + /* If the visible new line is shorter than the old, but the number
|
---|
| 1917 | + of invisible characters is greater, and we are at the end of
|
---|
| 1918 | + the new line, we need to clear to eol. */
|
---|
| 1919 | + t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
|
---|
| 1920 | + if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
|
---|
| 1921 | + (_rl_last_c_pos == out) &&
|
---|
| 1922 | + t < visible_first_line_len)
|
---|
| 1923 | + {
|
---|
| 1924 | + nleft = _rl_screenwidth - t;
|
---|
| 1925 | + _rl_clear_to_eol (nleft);
|
---|
| 1926 | + }
|
---|
| 1927 | + visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
|
---|
| 1928 | + if (visible_first_line_len > _rl_screenwidth)
|
---|
| 1929 | + visible_first_line_len = _rl_screenwidth;
|
---|
| 1930 | +
|
---|
| 1931 | + _rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin]);
|
---|
| 1932 | + last_lmargin = lmargin;
|
---|
| 1933 | + }
|
---|
| 1934 | + }
|
---|
| 1935 | + fflush (rl_outstream);
|
---|
| 1936 | +
|
---|
| 1937 | + /* Swap visible and non-visible lines. */
|
---|
| 1938 | + {
|
---|
| 1939 | + char *vtemp = visible_line;
|
---|
| 1940 | + int *itemp = vis_lbreaks, ntemp = vis_lbsize;
|
---|
| 1941 | +
|
---|
| 1942 | + visible_line = invisible_line;
|
---|
| 1943 | + invisible_line = vtemp;
|
---|
| 1944 | +
|
---|
| 1945 | + vis_lbreaks = inv_lbreaks;
|
---|
| 1946 | + inv_lbreaks = itemp;
|
---|
| 1947 | +
|
---|
| 1948 | + vis_lbsize = inv_lbsize;
|
---|
| 1949 | + inv_lbsize = ntemp;
|
---|
| 1950 | +
|
---|
| 1951 | + rl_display_fixed = 0;
|
---|
| 1952 | + /* If we are displaying on a single line, and last_lmargin is > 0, we
|
---|
| 1953 | + are not displaying any invisible characters, so set visible_wrap_offset
|
---|
| 1954 | + to 0. */
|
---|
| 1955 | + if (_rl_horizontal_scroll_mode && last_lmargin)
|
---|
| 1956 | + visible_wrap_offset = 0;
|
---|
| 1957 | + else
|
---|
| 1958 | + visible_wrap_offset = wrap_offset;
|
---|
| 1959 | + }
|
---|
| 1960 | +}
|
---|
| 1961 | +
|
---|
| 1962 | +/* PWP: update_line() is based on finding the middle difference of each
|
---|
| 1963 | + line on the screen; vis:
|
---|
| 1964 | +
|
---|
| 1965 | + /old first difference
|
---|
| 1966 | + /beginning of line | /old last same /old EOL
|
---|
| 1967 | + v v v v
|
---|
| 1968 | +old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as
|
---|
| 1969 | +new: eddie> Oh, my little buggy says to me, as lurgid as
|
---|
| 1970 | + ^ ^ ^ ^
|
---|
| 1971 | + \beginning of line | \new last same \new end of line
|
---|
| 1972 | + \new first difference
|
---|
| 1973 | +
|
---|
| 1974 | + All are character pointers for the sake of speed. Special cases for
|
---|
| 1975 | + no differences, as well as for end of line additions must be handled.
|
---|
| 1976 | +
|
---|
| 1977 | + Could be made even smarter, but this works well enough */
|
---|
| 1978 | +static void
|
---|
| 1979 | +update_line (old, new, current_line, omax, nmax, inv_botlin)
|
---|
| 1980 | + register char *old, *new;
|
---|
| 1981 | + int current_line, omax, nmax, inv_botlin;
|
---|
| 1982 | +{
|
---|
| 1983 | + register char *ofd, *ols, *oe, *nfd, *nls, *ne;
|
---|
| 1984 | + int temp, lendiff, wsatend, od, nd, o_cpos;
|
---|
| 1985 | + int current_invis_chars;
|
---|
| 1986 | + int col_lendiff, col_temp;
|
---|
| 1987 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 1988 | + mbstate_t ps_new, ps_old;
|
---|
| 1989 | + int new_offset, old_offset;
|
---|
| 1990 | +#endif
|
---|
| 1991 | +
|
---|
| 1992 | + /* If we're at the right edge of a terminal that supports xn, we're
|
---|
| 1993 | + ready to wrap around, so do so. This fixes problems with knowing
|
---|
| 1994 | + the exact cursor position and cut-and-paste with certain terminal
|
---|
| 1995 | + emulators. In this calculation, TEMP is the physical screen
|
---|
| 1996 | + position of the cursor. */
|
---|
| 1997 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 1998 | + temp = _rl_last_c_pos;
|
---|
| 1999 | + else
|
---|
| 2000 | + temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
|
---|
| 2001 | + if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
|
---|
| 2002 | + && _rl_last_v_pos == current_line - 1)
|
---|
| 2003 | + {
|
---|
| 2004 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 2005 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 2006 | + {
|
---|
| 2007 | + wchar_t wc;
|
---|
| 2008 | + mbstate_t ps;
|
---|
| 2009 | + int tempwidth, bytes;
|
---|
| 2010 | + size_t ret;
|
---|
| 2011 | +
|
---|
| 2012 | + /* This fixes only double-column characters, but if the wrapped
|
---|
| 2013 | + character comsumes more than three columns, spaces will be
|
---|
| 2014 | + inserted in the string buffer. */
|
---|
| 2015 | + if (_rl_wrapped_line[current_line] > 0)
|
---|
| 2016 | + _rl_clear_to_eol (_rl_wrapped_line[current_line]);
|
---|
| 2017 | +
|
---|
| 2018 | + memset (&ps, 0, sizeof (mbstate_t));
|
---|
| 2019 | + ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps);
|
---|
| 2020 | + if (MB_INVALIDCH (ret))
|
---|
| 2021 | + {
|
---|
| 2022 | + tempwidth = 1;
|
---|
| 2023 | + ret = 1;
|
---|
| 2024 | + }
|
---|
| 2025 | + else if (MB_NULLWCH (ret))
|
---|
| 2026 | + tempwidth = 0;
|
---|
| 2027 | + else
|
---|
| 2028 | + tempwidth = wcwidth (wc);
|
---|
| 2029 | +
|
---|
| 2030 | + if (tempwidth > 0)
|
---|
| 2031 | + {
|
---|
| 2032 | + int count;
|
---|
| 2033 | + bytes = ret;
|
---|
| 2034 | + for (count = 0; count < bytes; count++)
|
---|
| 2035 | + putc (new[count], rl_outstream);
|
---|
| 2036 | + _rl_last_c_pos = tempwidth;
|
---|
| 2037 | + _rl_last_v_pos++;
|
---|
| 2038 | + memset (&ps, 0, sizeof (mbstate_t));
|
---|
| 2039 | + ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps);
|
---|
| 2040 | + if (ret != 0 && bytes != 0)
|
---|
| 2041 | + {
|
---|
| 2042 | + if (MB_INVALIDCH (ret))
|
---|
| 2043 | + memmove (old+bytes, old+1, strlen (old+1));
|
---|
| 2044 | + else
|
---|
| 2045 | + memmove (old+bytes, old+ret, strlen (old+ret));
|
---|
| 2046 | + memcpy (old, new, bytes);
|
---|
| 2047 | + }
|
---|
| 2048 | + }
|
---|
| 2049 | + else
|
---|
| 2050 | + {
|
---|
| 2051 | + putc (' ', rl_outstream);
|
---|
| 2052 | + _rl_last_c_pos = 1;
|
---|
| 2053 | + _rl_last_v_pos++;
|
---|
| 2054 | + if (old[0] && new[0])
|
---|
| 2055 | + old[0] = new[0];
|
---|
| 2056 | + }
|
---|
| 2057 | + }
|
---|
| 2058 | + else
|
---|
| 2059 | +#endif
|
---|
| 2060 | + {
|
---|
| 2061 | + if (new[0])
|
---|
| 2062 | + putc (new[0], rl_outstream);
|
---|
| 2063 | + else
|
---|
| 2064 | + putc (' ', rl_outstream);
|
---|
| 2065 | + _rl_last_c_pos = 1;
|
---|
| 2066 | + _rl_last_v_pos++;
|
---|
| 2067 | + if (old[0] && new[0])
|
---|
| 2068 | + old[0] = new[0];
|
---|
| 2069 | + }
|
---|
| 2070 | + }
|
---|
| 2071 | +
|
---|
| 2072 | +
|
---|
| 2073 | + /* Find first difference. */
|
---|
| 2074 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 2075 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 2076 | + {
|
---|
| 2077 | + /* See if the old line is a subset of the new line, so that the
|
---|
| 2078 | + only change is adding characters. */
|
---|
| 2079 | + temp = (omax < nmax) ? omax : nmax;
|
---|
| 2080 | + if (memcmp (old, new, temp) == 0)
|
---|
| 2081 | + {
|
---|
| 2082 | + ofd = old + temp;
|
---|
| 2083 | + nfd = new + temp;
|
---|
| 2084 | + }
|
---|
| 2085 | + else
|
---|
| 2086 | + {
|
---|
| 2087 | + memset (&ps_new, 0, sizeof(mbstate_t));
|
---|
| 2088 | + memset (&ps_old, 0, sizeof(mbstate_t));
|
---|
| 2089 | +
|
---|
| 2090 | + if (omax == nmax && STREQN (new, old, omax))
|
---|
| 2091 | + {
|
---|
| 2092 | + ofd = old + omax;
|
---|
| 2093 | + nfd = new + nmax;
|
---|
| 2094 | + }
|
---|
| 2095 | + else
|
---|
| 2096 | + {
|
---|
| 2097 | + new_offset = old_offset = 0;
|
---|
| 2098 | + for (ofd = old, nfd = new;
|
---|
| 2099 | + (ofd - old < omax) && *ofd &&
|
---|
| 2100 | + _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
|
---|
| 2101 | + {
|
---|
| 2102 | + old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
|
---|
| 2103 | + new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
|
---|
| 2104 | + ofd = old + old_offset;
|
---|
| 2105 | + nfd = new + new_offset;
|
---|
| 2106 | + }
|
---|
| 2107 | + }
|
---|
| 2108 | + }
|
---|
| 2109 | + }
|
---|
| 2110 | + else
|
---|
| 2111 | +#endif
|
---|
| 2112 | + for (ofd = old, nfd = new;
|
---|
| 2113 | + (ofd - old < omax) && *ofd && (*ofd == *nfd);
|
---|
| 2114 | + ofd++, nfd++)
|
---|
| 2115 | + ;
|
---|
| 2116 | +
|
---|
| 2117 | + /* Move to the end of the screen line. ND and OD are used to keep track
|
---|
| 2118 | + of the distance between ne and new and oe and old, respectively, to
|
---|
| 2119 | + move a subtraction out of each loop. */
|
---|
| 2120 | + for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
|
---|
| 2121 | + for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
|
---|
| 2122 | +
|
---|
| 2123 | + /* If no difference, continue to next line. */
|
---|
| 2124 | + if (ofd == oe && nfd == ne)
|
---|
| 2125 | + return;
|
---|
| 2126 | +
|
---|
| 2127 | + wsatend = 1; /* flag for trailing whitespace */
|
---|
| 2128 | +
|
---|
| 2129 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 2130 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 2131 | + {
|
---|
| 2132 | + ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY);
|
---|
| 2133 | + nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY);
|
---|
| 2134 | + while ((ols > ofd) && (nls > nfd))
|
---|
| 2135 | + {
|
---|
| 2136 | + memset (&ps_old, 0, sizeof (mbstate_t));
|
---|
| 2137 | + memset (&ps_new, 0, sizeof (mbstate_t));
|
---|
| 2138 | +
|
---|
| 2139 | +#if 0
|
---|
| 2140 | + /* On advice from jir@yamato.ibm.com */
|
---|
| 2141 | + _rl_adjust_point (old, ols - old, &ps_old);
|
---|
| 2142 | + _rl_adjust_point (new, nls - new, &ps_new);
|
---|
| 2143 | +#endif
|
---|
| 2144 | +
|
---|
| 2145 | + if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
|
---|
| 2146 | + break;
|
---|
| 2147 | +
|
---|
| 2148 | + if (*ols == ' ')
|
---|
| 2149 | + wsatend = 0;
|
---|
| 2150 | +
|
---|
| 2151 | + ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY);
|
---|
| 2152 | + nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY);
|
---|
| 2153 | + }
|
---|
| 2154 | + }
|
---|
| 2155 | + else
|
---|
| 2156 | + {
|
---|
| 2157 | +#endif /* HANDLE_MULTIBYTE */
|
---|
| 2158 | + ols = oe - 1; /* find last same */
|
---|
| 2159 | + nls = ne - 1;
|
---|
| 2160 | + while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
|
---|
| 2161 | + {
|
---|
| 2162 | + if (*ols != ' ')
|
---|
| 2163 | + wsatend = 0;
|
---|
| 2164 | + ols--;
|
---|
| 2165 | + nls--;
|
---|
| 2166 | + }
|
---|
| 2167 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 2168 | + }
|
---|
| 2169 | +#endif
|
---|
| 2170 | +
|
---|
| 2171 | + if (wsatend)
|
---|
| 2172 | + {
|
---|
| 2173 | + ols = oe;
|
---|
| 2174 | + nls = ne;
|
---|
| 2175 | + }
|
---|
| 2176 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 2177 | + /* This may not work for stateful encoding, but who cares? To handle
|
---|
| 2178 | + stateful encoding properly, we have to scan each string from the
|
---|
| 2179 | + beginning and compare. */
|
---|
| 2180 | + else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0)
|
---|
| 2181 | +#else
|
---|
| 2182 | + else if (*ols != *nls)
|
---|
| 2183 | +#endif
|
---|
| 2184 | + {
|
---|
| 2185 | + if (*ols) /* don't step past the NUL */
|
---|
| 2186 | + {
|
---|
| 2187 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 2188 | + ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY);
|
---|
| 2189 | + else
|
---|
| 2190 | + ols++;
|
---|
| 2191 | + }
|
---|
| 2192 | + if (*nls)
|
---|
| 2193 | + {
|
---|
| 2194 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 2195 | + nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY);
|
---|
| 2196 | + else
|
---|
| 2197 | + nls++;
|
---|
| 2198 | + }
|
---|
| 2199 | + }
|
---|
| 2200 | +
|
---|
| 2201 | + /* count of invisible characters in the current invisible line. */
|
---|
| 2202 | + current_invis_chars = W_OFFSET (current_line, wrap_offset);
|
---|
| 2203 | + if (_rl_last_v_pos != current_line)
|
---|
| 2204 | + {
|
---|
| 2205 | + _rl_move_vert (current_line);
|
---|
| 2206 | + if ((MB_CUR_MAX == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset)
|
---|
| 2207 | + _rl_last_c_pos += visible_wrap_offset;
|
---|
| 2208 | + }
|
---|
| 2209 | +
|
---|
| 2210 | + /* If this is the first line and there are invisible characters in the
|
---|
| 2211 | + prompt string, and the prompt string has not changed, and the current
|
---|
| 2212 | + cursor position is before the last invisible character in the prompt,
|
---|
| 2213 | + and the index of the character to move to is past the end of the prompt
|
---|
| 2214 | + string, then redraw the entire prompt string. We can only do this
|
---|
| 2215 | + reliably if the terminal supports a `cr' capability.
|
---|
| 2216 | +
|
---|
| 2217 | + This is not an efficiency hack -- there is a problem with redrawing
|
---|
| 2218 | + portions of the prompt string if they contain terminal escape
|
---|
| 2219 | + sequences (like drawing the `unbold' sequence without a corresponding
|
---|
| 2220 | + `bold') that manifests itself on certain terminals. */
|
---|
| 2221 | +
|
---|
| 2222 | + lendiff = local_prompt_len;
|
---|
| 2223 | + od = ofd - old; /* index of first difference in visible line */
|
---|
| 2224 | + if (current_line == 0 && !_rl_horizontal_scroll_mode &&
|
---|
| 2225 | + _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 &&
|
---|
| 2226 | + od >= lendiff && _rl_last_c_pos < PROMPT_ENDING_INDEX)
|
---|
| 2227 | + {
|
---|
| 2228 | +#if defined (__MSDOS__)
|
---|
| 2229 | + putc ('\r', rl_outstream);
|
---|
| 2230 | +#else
|
---|
| 2231 | + tputs (_rl_term_cr, 1, _rl_output_character_function);
|
---|
| 2232 | +#endif
|
---|
| 2233 | + _rl_output_some_chars (local_prompt, lendiff);
|
---|
| 2234 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 2235 | + {
|
---|
| 2236 | + /* We take wrap_offset into account here so we can pass correct
|
---|
| 2237 | + information to _rl_move_cursor_relative. */
|
---|
| 2238 | + _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff) - wrap_offset;
|
---|
| 2239 | + cpos_adjusted = 1;
|
---|
| 2240 | + }
|
---|
| 2241 | + else
|
---|
| 2242 | + _rl_last_c_pos = lendiff;
|
---|
| 2243 | + }
|
---|
| 2244 | +
|
---|
| 2245 | + o_cpos = _rl_last_c_pos;
|
---|
| 2246 | +
|
---|
| 2247 | + /* When this function returns, _rl_last_c_pos is correct, and an absolute
|
---|
| 2248 | + cursor postion in multibyte mode, but a buffer index when not in a
|
---|
| 2249 | + multibyte locale. */
|
---|
| 2250 | + _rl_move_cursor_relative (od, old);
|
---|
| 2251 | +#if 1
|
---|
| 2252 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 2253 | + /* We need to indicate that the cursor position is correct in the presence of
|
---|
| 2254 | + invisible characters in the prompt string. Let's see if setting this when
|
---|
| 2255 | + we make sure we're at the end of the drawn prompt string works. */
|
---|
| 2256 | + if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 &&
|
---|
| 2257 | + (_rl_last_c_pos > 0 || o_cpos > 0) &&
|
---|
| 2258 | + _rl_last_c_pos == prompt_physical_chars)
|
---|
| 2259 | + cpos_adjusted = 1;
|
---|
| 2260 | +#endif
|
---|
| 2261 | +#endif
|
---|
| 2262 | +
|
---|
| 2263 | + /* if (len (new) > len (old))
|
---|
| 2264 | + lendiff == difference in buffer
|
---|
| 2265 | + col_lendiff == difference on screen
|
---|
| 2266 | + When not using multibyte characters, these are equal */
|
---|
| 2267 | + lendiff = (nls - nfd) - (ols - ofd);
|
---|
| 2268 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 2269 | + col_lendiff = _rl_col_width (new, nfd - new, nls - new) - _rl_col_width (old, ofd - old, ols - old);
|
---|
| 2270 | + else
|
---|
| 2271 | + col_lendiff = lendiff;
|
---|
| 2272 | +
|
---|
| 2273 | + /* If we are changing the number of invisible characters in a line, and
|
---|
| 2274 | + the spot of first difference is before the end of the invisible chars,
|
---|
| 2275 | + lendiff needs to be adjusted. */
|
---|
| 2276 | + if (current_line == 0 && !_rl_horizontal_scroll_mode &&
|
---|
| 2277 | + current_invis_chars != visible_wrap_offset)
|
---|
| 2278 | + {
|
---|
| 2279 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 2280 | + {
|
---|
| 2281 | + lendiff += visible_wrap_offset - current_invis_chars;
|
---|
| 2282 | + col_lendiff += visible_wrap_offset - current_invis_chars;
|
---|
| 2283 | + }
|
---|
| 2284 | + else
|
---|
| 2285 | + {
|
---|
| 2286 | + lendiff += visible_wrap_offset - current_invis_chars;
|
---|
| 2287 | + col_lendiff = lendiff;
|
---|
| 2288 | + }
|
---|
| 2289 | + }
|
---|
| 2290 | +
|
---|
| 2291 | + /* Insert (diff (len (old), len (new)) ch. */
|
---|
| 2292 | + temp = ne - nfd;
|
---|
| 2293 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 2294 | + col_temp = _rl_col_width (new, nfd - new, ne - new);
|
---|
| 2295 | + else
|
---|
| 2296 | + col_temp = temp;
|
---|
| 2297 | +
|
---|
| 2298 | + if (col_lendiff > 0) /* XXX - was lendiff */
|
---|
| 2299 | + {
|
---|
| 2300 | + /* Non-zero if we're increasing the number of lines. */
|
---|
| 2301 | + int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
|
---|
| 2302 | + /* If col_lendiff is > 0, implying that the new string takes up more
|
---|
| 2303 | + screen real estate than the old, but lendiff is < 0, meaning that it
|
---|
| 2304 | + takes fewer bytes, we need to just output the characters starting
|
---|
| 2305 | + from the first difference. These will overwrite what is on the
|
---|
| 2306 | + display, so there's no reason to do a smart update. This can really
|
---|
| 2307 | + only happen in a multibyte environment. */
|
---|
| 2308 | + if (lendiff < 0)
|
---|
| 2309 | + {
|
---|
| 2310 | + _rl_output_some_chars (nfd, temp);
|
---|
| 2311 | + _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
|
---|
| 2312 | + /* If nfd begins before any invisible characters in the prompt,
|
---|
| 2313 | + adjust _rl_last_c_pos to account for wrap_offset and set
|
---|
| 2314 | + cpos_adjusted to let the caller know. */
|
---|
| 2315 | + if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
|
---|
| 2316 | + {
|
---|
| 2317 | + _rl_last_c_pos -= wrap_offset;
|
---|
| 2318 | + cpos_adjusted = 1;
|
---|
| 2319 | + }
|
---|
| 2320 | + return;
|
---|
| 2321 | + }
|
---|
| 2322 | + /* Sometimes it is cheaper to print the characters rather than
|
---|
| 2323 | + use the terminal's capabilities. If we're growing the number
|
---|
| 2324 | + of lines, make sure we actually cause the new line to wrap
|
---|
| 2325 | + around on auto-wrapping terminals. */
|
---|
| 2326 | + else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
|
---|
| 2327 | + {
|
---|
| 2328 | + /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
|
---|
| 2329 | + _rl_horizontal_scroll_mode == 1, inserting the characters with
|
---|
| 2330 | + _rl_term_IC or _rl_term_ic will screw up the screen because of the
|
---|
| 2331 | + invisible characters. We need to just draw them. */
|
---|
| 2332 | + if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||
|
---|
| 2333 | + lendiff <= prompt_visible_length || !current_invis_chars))
|
---|
| 2334 | + {
|
---|
| 2335 | + insert_some_chars (nfd, lendiff, col_lendiff);
|
---|
| 2336 | + _rl_last_c_pos += col_lendiff;
|
---|
| 2337 | + }
|
---|
| 2338 | + else if ((MB_CUR_MAX == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0)
|
---|
| 2339 | + {
|
---|
| 2340 | + /* At the end of a line the characters do not have to
|
---|
| 2341 | + be "inserted". They can just be placed on the screen. */
|
---|
| 2342 | + /* However, this screws up the rest of this block, which
|
---|
| 2343 | + assumes you've done the insert because you can. */
|
---|
| 2344 | + _rl_output_some_chars (nfd, lendiff);
|
---|
| 2345 | + _rl_last_c_pos += col_lendiff;
|
---|
| 2346 | + }
|
---|
| 2347 | + else
|
---|
| 2348 | + {
|
---|
| 2349 | + /* We have horizontal scrolling and we are not inserting at
|
---|
| 2350 | + the end. We have invisible characters in this line. This
|
---|
| 2351 | + is a dumb update. */
|
---|
| 2352 | + _rl_output_some_chars (nfd, temp);
|
---|
| 2353 | + _rl_last_c_pos += col_temp;
|
---|
| 2354 | + return;
|
---|
| 2355 | + }
|
---|
| 2356 | + /* Copy (new) chars to screen from first diff to last match. */
|
---|
| 2357 | + temp = nls - nfd;
|
---|
| 2358 | + if ((temp - lendiff) > 0)
|
---|
| 2359 | + {
|
---|
| 2360 | + _rl_output_some_chars (nfd + lendiff, temp - lendiff);
|
---|
| 2361 | +#if 1
|
---|
| 2362 | + /* XXX -- this bears closer inspection. Fixes a redisplay bug
|
---|
| 2363 | + reported against bash-3.0-alpha by Andreas Schwab involving
|
---|
| 2364 | + multibyte characters and prompt strings with invisible
|
---|
| 2365 | + characters, but was previously disabled. */
|
---|
| 2366 | + _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-col_lendiff);
|
---|
| 2367 | +#else
|
---|
| 2368 | + _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-lendiff);
|
---|
| 2369 | +#endif
|
---|
| 2370 | + }
|
---|
| 2371 | + }
|
---|
| 2372 | + else
|
---|
| 2373 | + {
|
---|
| 2374 | + /* cannot insert chars, write to EOL */
|
---|
| 2375 | + _rl_output_some_chars (nfd, temp);
|
---|
| 2376 | + _rl_last_c_pos += col_temp;
|
---|
| 2377 | + /* If we're in a multibyte locale and were before the last invisible
|
---|
| 2378 | + char in the current line (which implies we just output some invisible
|
---|
| 2379 | + characters) we need to adjust _rl_last_c_pos, since it represents
|
---|
| 2380 | + a physical character position. */
|
---|
| 2381 | + }
|
---|
| 2382 | + }
|
---|
| 2383 | + else /* Delete characters from line. */
|
---|
| 2384 | + {
|
---|
| 2385 | + /* If possible and inexpensive to use terminal deletion, then do so. */
|
---|
| 2386 | + if (_rl_term_dc && (2 * col_temp) >= -col_lendiff)
|
---|
| 2387 | + {
|
---|
| 2388 | + /* If all we're doing is erasing the invisible characters in the
|
---|
| 2389 | + prompt string, don't bother. It screws up the assumptions
|
---|
| 2390 | + about what's on the screen. */
|
---|
| 2391 | + if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
|
---|
| 2392 | + -lendiff == visible_wrap_offset)
|
---|
| 2393 | + col_lendiff = 0;
|
---|
| 2394 | +
|
---|
| 2395 | + if (col_lendiff)
|
---|
| 2396 | + delete_chars (-col_lendiff); /* delete (diff) characters */
|
---|
| 2397 | +
|
---|
| 2398 | + /* Copy (new) chars to screen from first diff to last match */
|
---|
| 2399 | + temp = nls - nfd;
|
---|
| 2400 | + if (temp > 0)
|
---|
| 2401 | + {
|
---|
| 2402 | + /* If nfd begins at the prompt, or before the invisible
|
---|
| 2403 | + characters in the prompt, we need to adjust _rl_last_c_pos
|
---|
| 2404 | + in a multibyte locale to account for the wrap offset and
|
---|
| 2405 | + set cpos_adjusted accordingly. */
|
---|
| 2406 | + _rl_output_some_chars (nfd, temp);
|
---|
| 2407 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 2408 | + {
|
---|
| 2409 | + _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
|
---|
| 2410 | + if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
|
---|
| 2411 | + {
|
---|
| 2412 | + _rl_last_c_pos -= wrap_offset;
|
---|
| 2413 | + cpos_adjusted = 1;
|
---|
| 2414 | + }
|
---|
| 2415 | + }
|
---|
| 2416 | + else
|
---|
| 2417 | + _rl_last_c_pos += temp;
|
---|
| 2418 | + }
|
---|
| 2419 | + }
|
---|
| 2420 | + /* Otherwise, print over the existing material. */
|
---|
| 2421 | + else
|
---|
| 2422 | + {
|
---|
| 2423 | + if (temp > 0)
|
---|
| 2424 | + {
|
---|
| 2425 | + /* If nfd begins at the prompt, or before the invisible
|
---|
| 2426 | + characters in the prompt, we need to adjust _rl_last_c_pos
|
---|
| 2427 | + in a multibyte locale to account for the wrap offset and
|
---|
| 2428 | + set cpos_adjusted accordingly. */
|
---|
| 2429 | + _rl_output_some_chars (nfd, temp);
|
---|
| 2430 | + _rl_last_c_pos += col_temp; /* XXX */
|
---|
| 2431 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 2432 | + {
|
---|
| 2433 | + if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
|
---|
| 2434 | + {
|
---|
| 2435 | + _rl_last_c_pos -= wrap_offset;
|
---|
| 2436 | + cpos_adjusted = 1;
|
---|
| 2437 | + }
|
---|
| 2438 | + }
|
---|
| 2439 | + }
|
---|
| 2440 | + lendiff = (oe - old) - (ne - new);
|
---|
| 2441 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 2442 | + col_lendiff = _rl_col_width (old, 0, oe - old) - _rl_col_width (new, 0, ne - new);
|
---|
| 2443 | + else
|
---|
| 2444 | + col_lendiff = lendiff;
|
---|
| 2445 | +
|
---|
| 2446 | + if (col_lendiff)
|
---|
| 2447 | + {
|
---|
| 2448 | + if (_rl_term_autowrap && current_line < inv_botlin)
|
---|
| 2449 | + space_to_eol (col_lendiff);
|
---|
| 2450 | + else
|
---|
| 2451 | + _rl_clear_to_eol (col_lendiff);
|
---|
| 2452 | + }
|
---|
| 2453 | + }
|
---|
| 2454 | + }
|
---|
| 2455 | +}
|
---|
| 2456 | +
|
---|
| 2457 | +/* Tell the update routines that we have moved onto a new (empty) line. */
|
---|
| 2458 | +int
|
---|
| 2459 | +rl_on_new_line ()
|
---|
| 2460 | +{
|
---|
| 2461 | + if (visible_line)
|
---|
| 2462 | + visible_line[0] = '\0';
|
---|
| 2463 | +
|
---|
| 2464 | + _rl_last_c_pos = _rl_last_v_pos = 0;
|
---|
| 2465 | + _rl_vis_botlin = last_lmargin = 0;
|
---|
| 2466 | + if (vis_lbreaks)
|
---|
| 2467 | + vis_lbreaks[0] = vis_lbreaks[1] = 0;
|
---|
| 2468 | + visible_wrap_offset = 0;
|
---|
| 2469 | + return 0;
|
---|
| 2470 | +}
|
---|
| 2471 | +
|
---|
| 2472 | +/* Tell the update routines that we have moved onto a new line with the
|
---|
| 2473 | + prompt already displayed. Code originally from the version of readline
|
---|
| 2474 | + distributed with CLISP. rl_expand_prompt must have already been called
|
---|
| 2475 | + (explicitly or implicitly). This still doesn't work exactly right. */
|
---|
| 2476 | +int
|
---|
| 2477 | +rl_on_new_line_with_prompt ()
|
---|
| 2478 | +{
|
---|
| 2479 | + int prompt_size, i, l, real_screenwidth, newlines;
|
---|
| 2480 | + char *prompt_last_line, *lprompt;
|
---|
| 2481 | +
|
---|
| 2482 | + /* Initialize visible_line and invisible_line to ensure that they can hold
|
---|
| 2483 | + the already-displayed prompt. */
|
---|
| 2484 | + prompt_size = strlen (rl_prompt) + 1;
|
---|
| 2485 | + init_line_structures (prompt_size);
|
---|
| 2486 | +
|
---|
| 2487 | + /* Make sure the line structures hold the already-displayed prompt for
|
---|
| 2488 | + redisplay. */
|
---|
| 2489 | + lprompt = local_prompt ? local_prompt : rl_prompt;
|
---|
| 2490 | + strcpy (visible_line, lprompt);
|
---|
| 2491 | + strcpy (invisible_line, lprompt);
|
---|
| 2492 | +
|
---|
| 2493 | + /* If the prompt contains newlines, take the last tail. */
|
---|
| 2494 | + prompt_last_line = strrchr (rl_prompt, '\n');
|
---|
| 2495 | + if (!prompt_last_line)
|
---|
| 2496 | + prompt_last_line = rl_prompt;
|
---|
| 2497 | +
|
---|
| 2498 | + l = strlen (prompt_last_line);
|
---|
| 2499 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 2500 | + _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l); /* XXX */
|
---|
| 2501 | + else
|
---|
| 2502 | + _rl_last_c_pos = l;
|
---|
| 2503 | +
|
---|
| 2504 | + /* Dissect prompt_last_line into screen lines. Note that here we have
|
---|
| 2505 | + to use the real screenwidth. Readline's notion of screenwidth might be
|
---|
| 2506 | + one less, see terminal.c. */
|
---|
| 2507 | + real_screenwidth = _rl_screenwidth + (_rl_term_autowrap ? 0 : 1);
|
---|
| 2508 | + _rl_last_v_pos = l / real_screenwidth;
|
---|
| 2509 | + /* If the prompt length is a multiple of real_screenwidth, we don't know
|
---|
| 2510 | + whether the cursor is at the end of the last line, or already at the
|
---|
| 2511 | + beginning of the next line. Output a newline just to be safe. */
|
---|
| 2512 | + if (l > 0 && (l % real_screenwidth) == 0)
|
---|
| 2513 | + _rl_output_some_chars ("\n", 1);
|
---|
| 2514 | + last_lmargin = 0;
|
---|
| 2515 | +
|
---|
| 2516 | + newlines = 0; i = 0;
|
---|
| 2517 | + while (i <= l)
|
---|
| 2518 | + {
|
---|
| 2519 | + _rl_vis_botlin = newlines;
|
---|
| 2520 | + vis_lbreaks[newlines++] = i;
|
---|
| 2521 | + i += real_screenwidth;
|
---|
| 2522 | + }
|
---|
| 2523 | + vis_lbreaks[newlines] = l;
|
---|
| 2524 | + visible_wrap_offset = 0;
|
---|
| 2525 | +
|
---|
| 2526 | + rl_display_prompt = rl_prompt; /* XXX - make sure it's set */
|
---|
| 2527 | +
|
---|
| 2528 | + return 0;
|
---|
| 2529 | +}
|
---|
| 2530 | +
|
---|
| 2531 | +/* Actually update the display, period. */
|
---|
| 2532 | +int
|
---|
| 2533 | +rl_forced_update_display ()
|
---|
| 2534 | +{
|
---|
| 2535 | + register char *temp;
|
---|
| 2536 | +
|
---|
| 2537 | + if (visible_line)
|
---|
| 2538 | + {
|
---|
| 2539 | + temp = visible_line;
|
---|
| 2540 | + while (*temp)
|
---|
| 2541 | + *temp++ = '\0';
|
---|
| 2542 | + }
|
---|
| 2543 | + rl_on_new_line ();
|
---|
| 2544 | + forced_display++;
|
---|
| 2545 | + (*rl_redisplay_function) ();
|
---|
| 2546 | + return 0;
|
---|
| 2547 | +}
|
---|
| 2548 | +
|
---|
| 2549 | +/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
|
---|
| 2550 | + (Well, when we don't have multibyte characters, _rl_last_c_pos is a
|
---|
| 2551 | + buffer index.)
|
---|
| 2552 | + DATA is the contents of the screen line of interest; i.e., where
|
---|
| 2553 | + the movement is being done. */
|
---|
| 2554 | +void
|
---|
| 2555 | +_rl_move_cursor_relative (new, data)
|
---|
| 2556 | + int new;
|
---|
| 2557 | + const char *data;
|
---|
| 2558 | +{
|
---|
| 2559 | + register int i;
|
---|
| 2560 | + int woff; /* number of invisible chars on current line */
|
---|
| 2561 | + int cpos, dpos; /* current and desired cursor positions */
|
---|
| 2562 | +
|
---|
| 2563 | + woff = W_OFFSET (_rl_last_v_pos, wrap_offset);
|
---|
| 2564 | + cpos = _rl_last_c_pos;
|
---|
| 2565 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 2566 | + /* If we have multibyte characters, NEW is indexed by the buffer point in
|
---|
| 2567 | + a multibyte string, but _rl_last_c_pos is the display position. In
|
---|
| 2568 | + this case, NEW's display position is not obvious and must be
|
---|
| 2569 | + calculated. We need to account for invisible characters in this line,
|
---|
| 2570 | + as long as we are past them and they are counted by _rl_col_width. */
|
---|
| 2571 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 2572 | + {
|
---|
| 2573 | + dpos = _rl_col_width (data, 0, new);
|
---|
| 2574 | + /* Use NEW when comparing against the last invisible character in the
|
---|
| 2575 | + prompt string, since they're both buffer indices and DPOS is a
|
---|
| 2576 | + desired display position. */
|
---|
| 2577 | + if (new > prompt_last_invisible) /* XXX - don't use woff here */
|
---|
| 2578 | + {
|
---|
| 2579 | + dpos -= woff;
|
---|
| 2580 | + /* Since this will be assigned to _rl_last_c_pos at the end (more
|
---|
| 2581 | + precisely, _rl_last_c_pos == dpos when this function returns),
|
---|
| 2582 | + let the caller know. */
|
---|
| 2583 | + cpos_adjusted = 1;
|
---|
| 2584 | + }
|
---|
| 2585 | + }
|
---|
| 2586 | + else
|
---|
| 2587 | +#endif
|
---|
| 2588 | + dpos = new;
|
---|
| 2589 | +
|
---|
| 2590 | + /* If we don't have to do anything, then return. */
|
---|
| 2591 | + if (cpos == dpos)
|
---|
| 2592 | + return;
|
---|
| 2593 | +
|
---|
| 2594 | + /* It may be faster to output a CR, and then move forwards instead
|
---|
| 2595 | + of moving backwards. */
|
---|
| 2596 | + /* i == current physical cursor position. */
|
---|
| 2597 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 2598 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 2599 | + i = _rl_last_c_pos;
|
---|
| 2600 | + else
|
---|
| 2601 | +#endif
|
---|
| 2602 | + i = _rl_last_c_pos - woff;
|
---|
| 2603 | + if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) ||
|
---|
| 2604 | + (_rl_term_autowrap && i == _rl_screenwidth))
|
---|
| 2605 | + {
|
---|
| 2606 | +#if defined (__MSDOS__)
|
---|
| 2607 | + putc ('\r', rl_outstream);
|
---|
| 2608 | +#else
|
---|
| 2609 | + tputs (_rl_term_cr, 1, _rl_output_character_function);
|
---|
| 2610 | +#endif /* !__MSDOS__ */
|
---|
| 2611 | + cpos = _rl_last_c_pos = 0;
|
---|
| 2612 | + }
|
---|
| 2613 | +
|
---|
| 2614 | + if (cpos < dpos)
|
---|
| 2615 | + {
|
---|
| 2616 | + /* Move the cursor forward. We do it by printing the command
|
---|
| 2617 | + to move the cursor forward if there is one, else print that
|
---|
| 2618 | + portion of the output buffer again. Which is cheaper? */
|
---|
| 2619 | +
|
---|
| 2620 | + /* The above comment is left here for posterity. It is faster
|
---|
| 2621 | + to print one character (non-control) than to print a control
|
---|
| 2622 | + sequence telling the terminal to move forward one character.
|
---|
| 2623 | + That kind of control is for people who don't know what the
|
---|
| 2624 | + data is underneath the cursor. */
|
---|
| 2625 | +
|
---|
| 2626 | + /* However, we need a handle on where the current display position is
|
---|
| 2627 | + in the buffer for the immediately preceding comment to be true.
|
---|
| 2628 | + In multibyte locales, we don't currently have that info available.
|
---|
| 2629 | + Without it, we don't know where the data we have to display begins
|
---|
| 2630 | + in the buffer and we have to go back to the beginning of the screen
|
---|
| 2631 | + line. In this case, we can use the terminal sequence to move forward
|
---|
| 2632 | + if it's available. */
|
---|
| 2633 | + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 2634 | + {
|
---|
| 2635 | + if (_rl_term_forward_char)
|
---|
| 2636 | + {
|
---|
| 2637 | + for (i = cpos; i < dpos; i++)
|
---|
| 2638 | + tputs (_rl_term_forward_char, 1, _rl_output_character_function);
|
---|
| 2639 | + }
|
---|
| 2640 | + else
|
---|
| 2641 | + {
|
---|
| 2642 | + tputs (_rl_term_cr, 1, _rl_output_character_function);
|
---|
| 2643 | + for (i = 0; i < new; i++)
|
---|
| 2644 | + putc (data[i], rl_outstream);
|
---|
| 2645 | + }
|
---|
| 2646 | + }
|
---|
| 2647 | + else
|
---|
| 2648 | + for (i = cpos; i < new; i++)
|
---|
| 2649 | + putc (data[i], rl_outstream);
|
---|
| 2650 | + }
|
---|
| 2651 | +
|
---|
| 2652 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 2653 | + /* NEW points to the buffer point, but _rl_last_c_pos is the display point.
|
---|
| 2654 | + The byte length of the string is probably bigger than the column width
|
---|
| 2655 | + of the string, which means that if NEW == _rl_last_c_pos, then NEW's
|
---|
| 2656 | + display point is less than _rl_last_c_pos. */
|
---|
| 2657 | +#endif
|
---|
| 2658 | + else if (cpos > dpos)
|
---|
| 2659 | + _rl_backspace (cpos - dpos);
|
---|
| 2660 | +
|
---|
| 2661 | + _rl_last_c_pos = dpos;
|
---|
| 2662 | +}
|
---|
| 2663 | +
|
---|
| 2664 | +/* PWP: move the cursor up or down. */
|
---|
| 2665 | +void
|
---|
| 2666 | +_rl_move_vert (to)
|
---|
| 2667 | + int to;
|
---|
| 2668 | +{
|
---|
| 2669 | + register int delta, i;
|
---|
| 2670 | +
|
---|
| 2671 | + if (_rl_last_v_pos == to || to > _rl_screenheight)
|
---|
| 2672 | + return;
|
---|
| 2673 | +
|
---|
| 2674 | + if ((delta = to - _rl_last_v_pos) > 0)
|
---|
| 2675 | + {
|
---|
| 2676 | + for (i = 0; i < delta; i++)
|
---|
| 2677 | + putc ('\n', rl_outstream);
|
---|
| 2678 | +#if defined (__MSDOS__)
|
---|
| 2679 | + putc ('\r', rl_outstream);
|
---|
| 2680 | +#else
|
---|
| 2681 | + tputs (_rl_term_cr, 1, _rl_output_character_function);
|
---|
| 2682 | +#endif
|
---|
| 2683 | + _rl_last_c_pos = 0;
|
---|
| 2684 | + }
|
---|
| 2685 | + else
|
---|
| 2686 | + { /* delta < 0 */
|
---|
| 2687 | + if (_rl_term_up && *_rl_term_up)
|
---|
| 2688 | + for (i = 0; i < -delta; i++)
|
---|
| 2689 | + tputs (_rl_term_up, 1, _rl_output_character_function);
|
---|
| 2690 | + }
|
---|
| 2691 | +
|
---|
| 2692 | + _rl_last_v_pos = to; /* Now TO is here */
|
---|
| 2693 | +}
|
---|
| 2694 | +
|
---|
| 2695 | +/* Physically print C on rl_outstream. This is for functions which know
|
---|
| 2696 | + how to optimize the display. Return the number of characters output. */
|
---|
| 2697 | +int
|
---|
| 2698 | +rl_show_char (c)
|
---|
| 2699 | + int c;
|
---|
| 2700 | +{
|
---|
| 2701 | + int n = 1;
|
---|
| 2702 | + if (META_CHAR (c) && (_rl_output_meta_chars == 0))
|
---|
| 2703 | + {
|
---|
| 2704 | + fprintf (rl_outstream, "M-");
|
---|
| 2705 | + n += 2;
|
---|
| 2706 | + c = UNMETA (c);
|
---|
| 2707 | + }
|
---|
| 2708 | +
|
---|
| 2709 | +#if defined (DISPLAY_TABS)
|
---|
| 2710 | + if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
|
---|
| 2711 | +#else
|
---|
| 2712 | + if (CTRL_CHAR (c) || c == RUBOUT)
|
---|
| 2713 | +#endif /* !DISPLAY_TABS */
|
---|
| 2714 | + {
|
---|
| 2715 | + fprintf (rl_outstream, "C-");
|
---|
| 2716 | + n += 2;
|
---|
| 2717 | + c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
|
---|
| 2718 | + }
|
---|
| 2719 | +
|
---|
| 2720 | + putc (c, rl_outstream);
|
---|
| 2721 | + fflush (rl_outstream);
|
---|
| 2722 | + return n;
|
---|
| 2723 | +}
|
---|
| 2724 | +
|
---|
| 2725 | +int
|
---|
| 2726 | +rl_character_len (c, pos)
|
---|
| 2727 | + register int c, pos;
|
---|
| 2728 | +{
|
---|
| 2729 | + unsigned char uc;
|
---|
| 2730 | +
|
---|
| 2731 | + uc = (unsigned char)c;
|
---|
| 2732 | +
|
---|
| 2733 | + if (META_CHAR (uc))
|
---|
| 2734 | + return ((_rl_output_meta_chars == 0) ? 4 : 1);
|
---|
| 2735 | +
|
---|
| 2736 | + if (uc == '\t')
|
---|
| 2737 | + {
|
---|
| 2738 | +#if defined (DISPLAY_TABS)
|
---|
| 2739 | + return (((pos | 7) + 1) - pos);
|
---|
| 2740 | +#else
|
---|
| 2741 | + return (2);
|
---|
| 2742 | +#endif /* !DISPLAY_TABS */
|
---|
| 2743 | + }
|
---|
| 2744 | +
|
---|
| 2745 | + if (CTRL_CHAR (c) || c == RUBOUT)
|
---|
| 2746 | + return (2);
|
---|
| 2747 | +
|
---|
| 2748 | + return ((ISPRINT (uc)) ? 1 : 2);
|
---|
| 2749 | +}
|
---|
| 2750 | +/* How to print things in the "echo-area". The prompt is treated as a
|
---|
| 2751 | + mini-modeline. */
|
---|
| 2752 | +static int msg_saved_prompt = 0;
|
---|
| 2753 | +
|
---|
| 2754 | +#if defined (USE_VARARGS)
|
---|
| 2755 | +int
|
---|
| 2756 | +#if defined (PREFER_STDARG)
|
---|
| 2757 | +rl_message (const char *format, ...)
|
---|
| 2758 | +#else
|
---|
| 2759 | +rl_message (va_alist)
|
---|
| 2760 | + va_dcl
|
---|
| 2761 | +#endif
|
---|
| 2762 | +{
|
---|
| 2763 | + va_list args;
|
---|
| 2764 | +#if defined (PREFER_VARARGS)
|
---|
| 2765 | + char *format;
|
---|
| 2766 | +#endif
|
---|
| 2767 | +
|
---|
| 2768 | +#if defined (PREFER_STDARG)
|
---|
| 2769 | + va_start (args, format);
|
---|
| 2770 | +#else
|
---|
| 2771 | + va_start (args);
|
---|
| 2772 | + format = va_arg (args, char *);
|
---|
| 2773 | +#endif
|
---|
| 2774 | +
|
---|
| 2775 | +#if defined (HAVE_VSNPRINTF)
|
---|
| 2776 | + vsnprintf (msg_buf, sizeof (msg_buf) - 1, format, args);
|
---|
| 2777 | +#else
|
---|
| 2778 | + vsprintf (msg_buf, format, args);
|
---|
| 2779 | + msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
|
---|
| 2780 | +#endif
|
---|
| 2781 | + va_end (args);
|
---|
| 2782 | +
|
---|
| 2783 | + if (saved_local_prompt == 0)
|
---|
| 2784 | + {
|
---|
| 2785 | + rl_save_prompt ();
|
---|
| 2786 | + msg_saved_prompt = 1;
|
---|
| 2787 | + }
|
---|
| 2788 | + rl_display_prompt = msg_buf;
|
---|
| 2789 | + local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
|
---|
| 2790 | + &prompt_last_invisible,
|
---|
| 2791 | + &prompt_invis_chars_first_line,
|
---|
| 2792 | + &prompt_physical_chars);
|
---|
| 2793 | + local_prompt_prefix = (char *)NULL;
|
---|
| 2794 | + local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
|
---|
| 2795 | + (*rl_redisplay_function) ();
|
---|
| 2796 | +
|
---|
| 2797 | + return 0;
|
---|
| 2798 | +}
|
---|
| 2799 | +#else /* !USE_VARARGS */
|
---|
| 2800 | +int
|
---|
| 2801 | +rl_message (format, arg1, arg2)
|
---|
| 2802 | + char *format;
|
---|
| 2803 | +{
|
---|
| 2804 | + sprintf (msg_buf, format, arg1, arg2);
|
---|
| 2805 | + msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
|
---|
| 2806 | +
|
---|
| 2807 | + rl_display_prompt = msg_buf;
|
---|
| 2808 | + if (saved_local_prompt == 0)
|
---|
| 2809 | + {
|
---|
| 2810 | + rl_save_prompt ();
|
---|
| 2811 | + msg_saved_prompt = 1;
|
---|
| 2812 | + }
|
---|
| 2813 | + local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
|
---|
| 2814 | + &prompt_last_invisible,
|
---|
| 2815 | + &prompt_invis_chars_first_line,
|
---|
| 2816 | + &prompt_physical_chars);
|
---|
| 2817 | + local_prompt_prefix = (char *)NULL;
|
---|
| 2818 | + local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
|
---|
| 2819 | + (*rl_redisplay_function) ();
|
---|
| 2820 | +
|
---|
| 2821 | + return 0;
|
---|
| 2822 | +}
|
---|
| 2823 | +#endif /* !USE_VARARGS */
|
---|
| 2824 | +
|
---|
| 2825 | +/* How to clear things from the "echo-area". */
|
---|
| 2826 | +int
|
---|
| 2827 | +rl_clear_message ()
|
---|
| 2828 | +{
|
---|
| 2829 | + rl_display_prompt = rl_prompt;
|
---|
| 2830 | + if (msg_saved_prompt)
|
---|
| 2831 | + {
|
---|
| 2832 | + rl_restore_prompt ();
|
---|
| 2833 | + msg_saved_prompt = 0;
|
---|
| 2834 | + }
|
---|
| 2835 | + (*rl_redisplay_function) ();
|
---|
| 2836 | + return 0;
|
---|
| 2837 | +}
|
---|
| 2838 | +
|
---|
| 2839 | +int
|
---|
| 2840 | +rl_reset_line_state ()
|
---|
| 2841 | +{
|
---|
| 2842 | + rl_on_new_line ();
|
---|
| 2843 | +
|
---|
| 2844 | + rl_display_prompt = rl_prompt ? rl_prompt : "";
|
---|
| 2845 | + forced_display = 1;
|
---|
| 2846 | + return 0;
|
---|
| 2847 | +}
|
---|
| 2848 | +
|
---|
| 2849 | +void
|
---|
| 2850 | +rl_save_prompt ()
|
---|
| 2851 | +{
|
---|
| 2852 | + saved_local_prompt = local_prompt;
|
---|
| 2853 | + saved_local_prefix = local_prompt_prefix;
|
---|
| 2854 | + saved_prefix_length = prompt_prefix_length;
|
---|
| 2855 | + saved_local_length = local_prompt_len;
|
---|
| 2856 | + saved_last_invisible = prompt_last_invisible;
|
---|
| 2857 | + saved_visible_length = prompt_visible_length;
|
---|
| 2858 | + saved_invis_chars_first_line = prompt_invis_chars_first_line;
|
---|
| 2859 | + saved_physical_chars = prompt_physical_chars;
|
---|
| 2860 | +
|
---|
| 2861 | + local_prompt = local_prompt_prefix = (char *)0;
|
---|
| 2862 | + local_prompt_len = 0;
|
---|
| 2863 | + prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0;
|
---|
| 2864 | + prompt_invis_chars_first_line = prompt_physical_chars = 0;
|
---|
| 2865 | +}
|
---|
| 2866 | +
|
---|
| 2867 | +void
|
---|
| 2868 | +rl_restore_prompt ()
|
---|
| 2869 | +{
|
---|
| 2870 | + FREE (local_prompt);
|
---|
| 2871 | + FREE (local_prompt_prefix);
|
---|
| 2872 | +
|
---|
| 2873 | + local_prompt = saved_local_prompt;
|
---|
| 2874 | + local_prompt_prefix = saved_local_prefix;
|
---|
| 2875 | + local_prompt_len = saved_local_length;
|
---|
| 2876 | + prompt_prefix_length = saved_prefix_length;
|
---|
| 2877 | + prompt_last_invisible = saved_last_invisible;
|
---|
| 2878 | + prompt_visible_length = saved_visible_length;
|
---|
| 2879 | + prompt_invis_chars_first_line = saved_invis_chars_first_line;
|
---|
| 2880 | + prompt_physical_chars = saved_physical_chars;
|
---|
| 2881 | +
|
---|
| 2882 | + /* can test saved_local_prompt to see if prompt info has been saved. */
|
---|
| 2883 | + saved_local_prompt = saved_local_prefix = (char *)0;
|
---|
| 2884 | + saved_local_length = 0;
|
---|
| 2885 | + saved_last_invisible = saved_visible_length = saved_prefix_length = 0;
|
---|
| 2886 | + saved_invis_chars_first_line = saved_physical_chars = 0;
|
---|
| 2887 | +}
|
---|
| 2888 | +
|
---|
| 2889 | +char *
|
---|
| 2890 | +_rl_make_prompt_for_search (pchar)
|
---|
| 2891 | + int pchar;
|
---|
| 2892 | +{
|
---|
| 2893 | + int len;
|
---|
| 2894 | + char *pmt, *p;
|
---|
| 2895 | +
|
---|
| 2896 | + rl_save_prompt ();
|
---|
| 2897 | +
|
---|
| 2898 | + /* We've saved the prompt, and can do anything with the various prompt
|
---|
| 2899 | + strings we need before they're restored. We want the unexpanded
|
---|
| 2900 | + portion of the prompt string after any final newline. */
|
---|
| 2901 | + p = rl_prompt ? strrchr (rl_prompt, '\n') : 0;
|
---|
| 2902 | + if (p == 0)
|
---|
| 2903 | + {
|
---|
| 2904 | + len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
|
---|
| 2905 | + pmt = (char *)xmalloc (len + 2);
|
---|
| 2906 | + if (len)
|
---|
| 2907 | + strcpy (pmt, rl_prompt);
|
---|
| 2908 | + pmt[len] = pchar;
|
---|
| 2909 | + pmt[len+1] = '\0';
|
---|
| 2910 | + }
|
---|
| 2911 | + else
|
---|
| 2912 | + {
|
---|
| 2913 | + p++;
|
---|
| 2914 | + len = strlen (p);
|
---|
| 2915 | + pmt = (char *)xmalloc (len + 2);
|
---|
| 2916 | + if (len)
|
---|
| 2917 | + strcpy (pmt, p);
|
---|
| 2918 | + pmt[len] = pchar;
|
---|
| 2919 | + pmt[len+1] = '\0';
|
---|
| 2920 | + }
|
---|
| 2921 | +
|
---|
| 2922 | + /* will be overwritten by expand_prompt, called from rl_message */
|
---|
| 2923 | + prompt_physical_chars = saved_physical_chars + 1;
|
---|
| 2924 | + return pmt;
|
---|
| 2925 | +}
|
---|
| 2926 | +
|
---|
| 2927 | +/* Quick redisplay hack when erasing characters at the end of the line. */
|
---|
| 2928 | +void
|
---|
| 2929 | +_rl_erase_at_end_of_line (l)
|
---|
| 2930 | + int l;
|
---|
| 2931 | +{
|
---|
| 2932 | + register int i;
|
---|
| 2933 | +
|
---|
| 2934 | + _rl_backspace (l);
|
---|
| 2935 | + for (i = 0; i < l; i++)
|
---|
| 2936 | + putc (' ', rl_outstream);
|
---|
| 2937 | + _rl_backspace (l);
|
---|
| 2938 | + for (i = 0; i < l; i++)
|
---|
| 2939 | + visible_line[--_rl_last_c_pos] = '\0';
|
---|
| 2940 | + rl_display_fixed++;
|
---|
| 2941 | +}
|
---|
| 2942 | +
|
---|
| 2943 | +/* Clear to the end of the line. COUNT is the minimum
|
---|
| 2944 | + number of character spaces to clear, */
|
---|
| 2945 | +void
|
---|
| 2946 | +_rl_clear_to_eol (count)
|
---|
| 2947 | + int count;
|
---|
| 2948 | +{
|
---|
| 2949 | + if (_rl_term_clreol)
|
---|
| 2950 | + tputs (_rl_term_clreol, 1, _rl_output_character_function);
|
---|
| 2951 | + else if (count)
|
---|
| 2952 | + space_to_eol (count);
|
---|
| 2953 | +}
|
---|
| 2954 | +
|
---|
| 2955 | +/* Clear to the end of the line using spaces. COUNT is the minimum
|
---|
| 2956 | + number of character spaces to clear, */
|
---|
| 2957 | +static void
|
---|
| 2958 | +space_to_eol (count)
|
---|
| 2959 | + int count;
|
---|
| 2960 | +{
|
---|
| 2961 | + register int i;
|
---|
| 2962 | +
|
---|
| 2963 | + for (i = 0; i < count; i++)
|
---|
| 2964 | + putc (' ', rl_outstream);
|
---|
| 2965 | +
|
---|
| 2966 | + _rl_last_c_pos += count;
|
---|
| 2967 | +}
|
---|
| 2968 | +
|
---|
| 2969 | +void
|
---|
| 2970 | +_rl_clear_screen ()
|
---|
| 2971 | +{
|
---|
| 2972 | + if (_rl_term_clrpag)
|
---|
| 2973 | + tputs (_rl_term_clrpag, 1, _rl_output_character_function);
|
---|
| 2974 | + else
|
---|
| 2975 | + rl_crlf ();
|
---|
| 2976 | +}
|
---|
| 2977 | +
|
---|
| 2978 | +/* Insert COUNT characters from STRING to the output stream at column COL. */
|
---|
| 2979 | +static void
|
---|
| 2980 | +insert_some_chars (string, count, col)
|
---|
| 2981 | + char *string;
|
---|
| 2982 | + int count, col;
|
---|
| 2983 | +{
|
---|
| 2984 | +#if defined (__MSDOS__) || defined (__MINGW32__)
|
---|
| 2985 | + _rl_output_some_chars (string, count);
|
---|
| 2986 | +#else
|
---|
| 2987 | + /* DEBUGGING */
|
---|
| 2988 | + if (MB_CUR_MAX == 1 || rl_byte_oriented)
|
---|
| 2989 | + if (count != col)
|
---|
| 2990 | + fprintf(stderr, "readline: debug: insert_some_chars: count (%d) != col (%d)\n", count, col);
|
---|
| 2991 | +
|
---|
| 2992 | + /* If IC is defined, then we do not have to "enter" insert mode. */
|
---|
| 2993 | + if (_rl_term_IC)
|
---|
| 2994 | + {
|
---|
| 2995 | + char *buffer;
|
---|
| 2996 | +
|
---|
| 2997 | + buffer = tgoto (_rl_term_IC, 0, col);
|
---|
| 2998 | + tputs (buffer, 1, _rl_output_character_function);
|
---|
| 2999 | + _rl_output_some_chars (string, count);
|
---|
| 3000 | + }
|
---|
| 3001 | + else
|
---|
| 3002 | + {
|
---|
| 3003 | + register int i;
|
---|
| 3004 | +
|
---|
| 3005 | + /* If we have to turn on insert-mode, then do so. */
|
---|
| 3006 | + if (_rl_term_im && *_rl_term_im)
|
---|
| 3007 | + tputs (_rl_term_im, 1, _rl_output_character_function);
|
---|
| 3008 | +
|
---|
| 3009 | + /* If there is a special command for inserting characters, then
|
---|
| 3010 | + use that first to open up the space. */
|
---|
| 3011 | + if (_rl_term_ic && *_rl_term_ic)
|
---|
| 3012 | + {
|
---|
| 3013 | + for (i = col; i--; )
|
---|
| 3014 | + tputs (_rl_term_ic, 1, _rl_output_character_function);
|
---|
| 3015 | + }
|
---|
| 3016 | +
|
---|
| 3017 | + /* Print the text. */
|
---|
| 3018 | + _rl_output_some_chars (string, count);
|
---|
| 3019 | +
|
---|
| 3020 | + /* If there is a string to turn off insert mode, we had best use
|
---|
| 3021 | + it now. */
|
---|
| 3022 | + if (_rl_term_ei && *_rl_term_ei)
|
---|
| 3023 | + tputs (_rl_term_ei, 1, _rl_output_character_function);
|
---|
| 3024 | + }
|
---|
| 3025 | +#endif /* __MSDOS__ || __MINGW32__ */
|
---|
| 3026 | +}
|
---|
| 3027 | +
|
---|
| 3028 | +/* Delete COUNT characters from the display line. */
|
---|
| 3029 | +static void
|
---|
| 3030 | +delete_chars (count)
|
---|
| 3031 | + int count;
|
---|
| 3032 | +{
|
---|
| 3033 | + if (count > _rl_screenwidth) /* XXX */
|
---|
| 3034 | + return;
|
---|
| 3035 | +
|
---|
| 3036 | +#if !defined (__MSDOS__) && !defined (__MINGW32__)
|
---|
| 3037 | + if (_rl_term_DC && *_rl_term_DC)
|
---|
| 3038 | + {
|
---|
| 3039 | + char *buffer;
|
---|
| 3040 | + buffer = tgoto (_rl_term_DC, count, count);
|
---|
| 3041 | + tputs (buffer, count, _rl_output_character_function);
|
---|
| 3042 | + }
|
---|
| 3043 | + else
|
---|
| 3044 | + {
|
---|
| 3045 | + if (_rl_term_dc && *_rl_term_dc)
|
---|
| 3046 | + while (count--)
|
---|
| 3047 | + tputs (_rl_term_dc, 1, _rl_output_character_function);
|
---|
| 3048 | + }
|
---|
| 3049 | +#endif /* !__MSDOS__ && !__MINGW32__ */
|
---|
| 3050 | +}
|
---|
| 3051 | +
|
---|
| 3052 | +void
|
---|
| 3053 | +_rl_update_final ()
|
---|
| 3054 | +{
|
---|
| 3055 | + int full_lines;
|
---|
| 3056 | +
|
---|
| 3057 | + full_lines = 0;
|
---|
| 3058 | + /* If the cursor is the only thing on an otherwise-blank last line,
|
---|
| 3059 | + compensate so we don't print an extra CRLF. */
|
---|
| 3060 | + if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
|
---|
| 3061 | + visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
|
---|
| 3062 | + {
|
---|
| 3063 | + _rl_vis_botlin--;
|
---|
| 3064 | + full_lines = 1;
|
---|
| 3065 | + }
|
---|
| 3066 | + _rl_move_vert (_rl_vis_botlin);
|
---|
| 3067 | + /* If we've wrapped lines, remove the final xterm line-wrap flag. */
|
---|
| 3068 | + if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == _rl_screenwidth))
|
---|
| 3069 | + {
|
---|
| 3070 | + char *last_line;
|
---|
| 3071 | +
|
---|
| 3072 | + last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]];
|
---|
| 3073 | + cpos_buffer_position = -1; /* don't know where we are in buffer */
|
---|
| 3074 | + _rl_move_cursor_relative (_rl_screenwidth - 1, last_line); /* XXX */
|
---|
| 3075 | + _rl_clear_to_eol (0);
|
---|
| 3076 | + putc (last_line[_rl_screenwidth - 1], rl_outstream);
|
---|
| 3077 | + }
|
---|
| 3078 | + _rl_vis_botlin = 0;
|
---|
| 3079 | + rl_crlf ();
|
---|
| 3080 | + fflush (rl_outstream);
|
---|
| 3081 | + rl_display_fixed++;
|
---|
| 3082 | +}
|
---|
| 3083 | +
|
---|
| 3084 | +/* Move to the start of the current line. */
|
---|
| 3085 | +static void
|
---|
| 3086 | +cr ()
|
---|
| 3087 | +{
|
---|
| 3088 | + if (_rl_term_cr)
|
---|
| 3089 | + {
|
---|
| 3090 | +#if defined (__MSDOS__)
|
---|
| 3091 | + putc ('\r', rl_outstream);
|
---|
| 3092 | +#else
|
---|
| 3093 | + tputs (_rl_term_cr, 1, _rl_output_character_function);
|
---|
| 3094 | +#endif
|
---|
| 3095 | + _rl_last_c_pos = 0;
|
---|
| 3096 | + }
|
---|
| 3097 | +}
|
---|
| 3098 | +
|
---|
| 3099 | +/* Redraw the last line of a multi-line prompt that may possibly contain
|
---|
| 3100 | + terminal escape sequences. Called with the cursor at column 0 of the
|
---|
| 3101 | + line to draw the prompt on. */
|
---|
| 3102 | +static void
|
---|
| 3103 | +redraw_prompt (t)
|
---|
| 3104 | + char *t;
|
---|
| 3105 | +{
|
---|
| 3106 | + char *oldp;
|
---|
| 3107 | +
|
---|
| 3108 | + oldp = rl_display_prompt;
|
---|
| 3109 | + rl_save_prompt ();
|
---|
| 3110 | +
|
---|
| 3111 | + rl_display_prompt = t;
|
---|
| 3112 | + local_prompt = expand_prompt (t, &prompt_visible_length,
|
---|
| 3113 | + &prompt_last_invisible,
|
---|
| 3114 | + &prompt_invis_chars_first_line,
|
---|
| 3115 | + &prompt_physical_chars);
|
---|
| 3116 | + local_prompt_prefix = (char *)NULL;
|
---|
| 3117 | + local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
|
---|
| 3118 | +
|
---|
| 3119 | + rl_forced_update_display ();
|
---|
| 3120 | +
|
---|
| 3121 | + rl_display_prompt = oldp;
|
---|
| 3122 | + rl_restore_prompt();
|
---|
| 3123 | +}
|
---|
| 3124 | +
|
---|
| 3125 | +/* Redisplay the current line after a SIGWINCH is received. */
|
---|
| 3126 | +void
|
---|
| 3127 | +_rl_redisplay_after_sigwinch ()
|
---|
| 3128 | +{
|
---|
| 3129 | + char *t;
|
---|
| 3130 | +
|
---|
| 3131 | + /* Clear the current line and put the cursor at column 0. Make sure
|
---|
| 3132 | + the right thing happens if we have wrapped to a new screen line. */
|
---|
| 3133 | + if (_rl_term_cr)
|
---|
| 3134 | + {
|
---|
| 3135 | +#if defined (__MSDOS__)
|
---|
| 3136 | + putc ('\r', rl_outstream);
|
---|
| 3137 | +#else
|
---|
| 3138 | + tputs (_rl_term_cr, 1, _rl_output_character_function);
|
---|
| 3139 | +#endif
|
---|
| 3140 | + _rl_last_c_pos = 0;
|
---|
| 3141 | +#if defined (__MSDOS__)
|
---|
| 3142 | + space_to_eol (_rl_screenwidth);
|
---|
| 3143 | + putc ('\r', rl_outstream);
|
---|
| 3144 | +#else
|
---|
| 3145 | + if (_rl_term_clreol)
|
---|
| 3146 | + tputs (_rl_term_clreol, 1, _rl_output_character_function);
|
---|
| 3147 | + else
|
---|
| 3148 | + {
|
---|
| 3149 | + space_to_eol (_rl_screenwidth);
|
---|
| 3150 | + tputs (_rl_term_cr, 1, _rl_output_character_function);
|
---|
| 3151 | + }
|
---|
| 3152 | +#endif
|
---|
| 3153 | + if (_rl_last_v_pos > 0)
|
---|
| 3154 | + _rl_move_vert (0);
|
---|
| 3155 | + }
|
---|
| 3156 | + else
|
---|
| 3157 | + rl_crlf ();
|
---|
| 3158 | +
|
---|
| 3159 | + /* Redraw only the last line of a multi-line prompt. */
|
---|
| 3160 | + t = strrchr (rl_display_prompt, '\n');
|
---|
| 3161 | + if (t)
|
---|
| 3162 | + redraw_prompt (++t);
|
---|
| 3163 | + else
|
---|
| 3164 | + rl_forced_update_display ();
|
---|
| 3165 | +}
|
---|
| 3166 | +
|
---|
| 3167 | +void
|
---|
| 3168 | +_rl_clean_up_for_exit ()
|
---|
| 3169 | +{
|
---|
| 3170 | + if (readline_echoing_p)
|
---|
| 3171 | + {
|
---|
| 3172 | + _rl_move_vert (_rl_vis_botlin);
|
---|
| 3173 | + _rl_vis_botlin = 0;
|
---|
| 3174 | + fflush (rl_outstream);
|
---|
| 3175 | + rl_restart_output (1, 0);
|
---|
| 3176 | + }
|
---|
| 3177 | +}
|
---|
| 3178 | +
|
---|
| 3179 | +void
|
---|
| 3180 | +_rl_erase_entire_line ()
|
---|
| 3181 | +{
|
---|
| 3182 | + cr ();
|
---|
| 3183 | + _rl_clear_to_eol (0);
|
---|
| 3184 | + cr ();
|
---|
| 3185 | + fflush (rl_outstream);
|
---|
| 3186 | +}
|
---|
| 3187 | +
|
---|
| 3188 | +/* return the `current display line' of the cursor -- the number of lines to
|
---|
| 3189 | + move up to get to the first screen line of the current readline line. */
|
---|
| 3190 | +int
|
---|
| 3191 | +_rl_current_display_line ()
|
---|
| 3192 | +{
|
---|
| 3193 | + int ret, nleft;
|
---|
| 3194 | +
|
---|
| 3195 | + /* Find out whether or not there might be invisible characters in the
|
---|
| 3196 | + editing buffer. */
|
---|
| 3197 | + if (rl_display_prompt == rl_prompt)
|
---|
| 3198 | + nleft = _rl_last_c_pos - _rl_screenwidth - rl_visible_prompt_length;
|
---|
| 3199 | + else
|
---|
| 3200 | + nleft = _rl_last_c_pos - _rl_screenwidth;
|
---|
| 3201 | +
|
---|
| 3202 | + if (nleft > 0)
|
---|
| 3203 | + ret = 1 + nleft / _rl_screenwidth;
|
---|
| 3204 | + else
|
---|
| 3205 | + ret = 0;
|
---|
| 3206 | +
|
---|
| 3207 | + return ret;
|
---|
| 3208 | +}
|
---|
| 3209 | +
|
---|
| 3210 | +#if defined (HANDLE_MULTIBYTE)
|
---|
| 3211 | +/* Calculate the number of screen columns occupied by STR from START to END.
|
---|
| 3212 | + In the case of multibyte characters with stateful encoding, we have to
|
---|
| 3213 | + scan from the beginning of the string to take the state into account. */
|
---|
| 3214 | +static int
|
---|
| 3215 | +_rl_col_width (str, start, end)
|
---|
| 3216 | + const char *str;
|
---|
| 3217 | + int start, end;
|
---|
| 3218 | +{
|
---|
| 3219 | + wchar_t wc;
|
---|
| 3220 | + mbstate_t ps;
|
---|
| 3221 | + int tmp, point, width, max;
|
---|
| 3222 | +
|
---|
| 3223 | + if (end <= start)
|
---|
| 3224 | + return 0;
|
---|
| 3225 | + if (MB_CUR_MAX == 1 || rl_byte_oriented)
|
---|
| 3226 | + return (end - start);
|
---|
| 3227 | +
|
---|
| 3228 | + memset (&ps, 0, sizeof (mbstate_t));
|
---|
| 3229 | +
|
---|
| 3230 | + point = 0;
|
---|
| 3231 | + max = end;
|
---|
| 3232 | +
|
---|
| 3233 | + while (point < start)
|
---|
| 3234 | + {
|
---|
| 3235 | + tmp = mbrlen (str + point, max, &ps);
|
---|
| 3236 | + if (MB_INVALIDCH ((size_t)tmp))
|
---|
| 3237 | + {
|
---|
| 3238 | + /* In this case, the bytes are invalid or too short to compose a
|
---|
| 3239 | + multibyte character, so we assume that the first byte represents
|
---|
| 3240 | + a single character. */
|
---|
| 3241 | + point++;
|
---|
| 3242 | + max--;
|
---|
| 3243 | +
|
---|
| 3244 | + /* Clear the state of the byte sequence, because in this case the
|
---|
| 3245 | + effect of mbstate is undefined. */
|
---|
| 3246 | + memset (&ps, 0, sizeof (mbstate_t));
|
---|
| 3247 | + }
|
---|
| 3248 | + else if (MB_NULLWCH (tmp))
|
---|
| 3249 | + break; /* Found '\0' */
|
---|
| 3250 | + else
|
---|
| 3251 | + {
|
---|
| 3252 | + point += tmp;
|
---|
| 3253 | + max -= tmp;
|
---|
| 3254 | + }
|
---|
| 3255 | + }
|
---|
| 3256 | +
|
---|
| 3257 | + /* If START is not a byte that starts a character, then POINT will be
|
---|
| 3258 | + greater than START. In this case, assume that (POINT - START) gives
|
---|
| 3259 | + a byte count that is the number of columns of difference. */
|
---|
| 3260 | + width = point - start;
|
---|
| 3261 | +
|
---|
| 3262 | + while (point < end)
|
---|
| 3263 | + {
|
---|
| 3264 | + tmp = mbrtowc (&wc, str + point, max, &ps);
|
---|
| 3265 | + if (MB_INVALIDCH ((size_t)tmp))
|
---|
| 3266 | + {
|
---|
| 3267 | + /* In this case, the bytes are invalid or too short to compose a
|
---|
| 3268 | + multibyte character, so we assume that the first byte represents
|
---|
| 3269 | + a single character. */
|
---|
| 3270 | + point++;
|
---|
| 3271 | + max--;
|
---|
| 3272 | +
|
---|
| 3273 | + /* and assume that the byte occupies a single column. */
|
---|
| 3274 | + width++;
|
---|
| 3275 | +
|
---|
| 3276 | + /* Clear the state of the byte sequence, because in this case the
|
---|
| 3277 | + effect of mbstate is undefined. */
|
---|
| 3278 | + memset (&ps, 0, sizeof (mbstate_t));
|
---|
| 3279 | + }
|
---|
| 3280 | + else if (MB_NULLWCH (tmp))
|
---|
| 3281 | + break; /* Found '\0' */
|
---|
| 3282 | + else
|
---|
| 3283 | + {
|
---|
| 3284 | + point += tmp;
|
---|
| 3285 | + max -= tmp;
|
---|
| 3286 | + tmp = wcwidth(wc);
|
---|
| 3287 | + width += (tmp >= 0) ? tmp : 1;
|
---|
| 3288 | + }
|
---|
| 3289 | + }
|
---|
| 3290 | +
|
---|
| 3291 | + width += point - end;
|
---|
| 3292 | +
|
---|
| 3293 | + return width;
|
---|
| 3294 | +}
|
---|
| 3295 | +#endif /* HANDLE_MULTIBYTE */
|
---|
| 3296 | diff -Naur bash-3.2.orig/lib/readline/input.c bash-3.2/lib/readline/input.c
|
---|
| 3297 | --- bash-3.2.orig/lib/readline/input.c 2006-08-16 15:15:16.000000000 -0400
|
---|
| 3298 | +++ bash-3.2/lib/readline/input.c 2007-12-20 23:53:17.000000000 -0500
|
---|
| 3299 | @@ -133,8 +133,11 @@
|
---|
| 3300 | return (0);
|
---|
| 3301 |
|
---|
| 3302 | *key = ibuffer[pop_index++];
|
---|
| 3303 | -
|
---|
| 3304 | +#if 0
|
---|
| 3305 | if (pop_index >= ibuffer_len)
|
---|
| 3306 | +#else
|
---|
| 3307 | + if (pop_index > ibuffer_len)
|
---|
| 3308 | +#endif
|
---|
| 3309 | pop_index = 0;
|
---|
| 3310 |
|
---|
| 3311 | return (1);
|
---|
| 3312 | @@ -151,7 +154,7 @@
|
---|
| 3313 | {
|
---|
| 3314 | pop_index--;
|
---|
| 3315 | if (pop_index < 0)
|
---|
| 3316 | - pop_index = ibuffer_len - 1;
|
---|
| 3317 | + pop_index = ibuffer_len;
|
---|
| 3318 | ibuffer[pop_index] = key;
|
---|
| 3319 | return (1);
|
---|
| 3320 | }
|
---|
| 3321 | @@ -250,7 +253,8 @@
|
---|
| 3322 | while (chars_avail--)
|
---|
| 3323 | {
|
---|
| 3324 | k = (*rl_getc_function) (rl_instream);
|
---|
| 3325 | - rl_stuff_char (k);
|
---|
| 3326 | + if (rl_stuff_char (k) == 0)
|
---|
| 3327 | + break; /* some problem; no more room */
|
---|
| 3328 | if (k == NEWLINE || k == RETURN)
|
---|
| 3329 | break;
|
---|
| 3330 | }
|
---|
| 3331 | @@ -373,7 +377,11 @@
|
---|
| 3332 | RL_SETSTATE (RL_STATE_INPUTPENDING);
|
---|
| 3333 | }
|
---|
| 3334 | ibuffer[push_index++] = key;
|
---|
| 3335 | +#if 0
|
---|
| 3336 | if (push_index >= ibuffer_len)
|
---|
| 3337 | +#else
|
---|
| 3338 | + if (push_index > ibuffer_len)
|
---|
| 3339 | +#endif
|
---|
| 3340 | push_index = 0;
|
---|
| 3341 |
|
---|
| 3342 | return 1;
|
---|
| 3343 | @@ -513,20 +521,26 @@
|
---|
| 3344 | char *mbchar;
|
---|
| 3345 | int size;
|
---|
| 3346 | {
|
---|
| 3347 | - int mb_len = 0;
|
---|
| 3348 | + int mb_len, c;
|
---|
| 3349 | size_t mbchar_bytes_length;
|
---|
| 3350 | wchar_t wc;
|
---|
| 3351 | mbstate_t ps, ps_back;
|
---|
| 3352 |
|
---|
| 3353 | memset(&ps, 0, sizeof (mbstate_t));
|
---|
| 3354 | memset(&ps_back, 0, sizeof (mbstate_t));
|
---|
| 3355 | -
|
---|
| 3356 | +
|
---|
| 3357 | + mb_len = 0;
|
---|
| 3358 | while (mb_len < size)
|
---|
| 3359 | {
|
---|
| 3360 | RL_SETSTATE(RL_STATE_MOREINPUT);
|
---|
| 3361 | - mbchar[mb_len++] = rl_read_key ();
|
---|
| 3362 | + c = rl_read_key ();
|
---|
| 3363 | RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
---|
| 3364 |
|
---|
| 3365 | + if (c < 0)
|
---|
| 3366 | + break;
|
---|
| 3367 | +
|
---|
| 3368 | + mbchar[mb_len++] = c;
|
---|
| 3369 | +
|
---|
| 3370 | mbchar_bytes_length = mbrtowc (&wc, mbchar, mb_len, &ps);
|
---|
| 3371 | if (mbchar_bytes_length == (size_t)(-1))
|
---|
| 3372 | break; /* invalid byte sequence for the current locale */
|
---|
| 3373 | @@ -564,7 +578,7 @@
|
---|
| 3374 |
|
---|
| 3375 | c = first;
|
---|
| 3376 | memset (mb, 0, mlen);
|
---|
| 3377 | - for (i = 0; i < mlen; i++)
|
---|
| 3378 | + for (i = 0; c >= 0 && i < mlen; i++)
|
---|
| 3379 | {
|
---|
| 3380 | mb[i] = (char)c;
|
---|
| 3381 | memset (&ps, 0, sizeof (mbstate_t));
|
---|
| 3382 | diff -Naur bash-3.2.orig/lib/readline/isearch.c bash-3.2/lib/readline/isearch.c
|
---|
| 3383 | --- bash-3.2.orig/lib/readline/isearch.c 2005-12-26 17:18:53.000000000 -0500
|
---|
| 3384 | +++ bash-3.2/lib/readline/isearch.c 2007-12-20 23:53:09.000000000 -0500
|
---|
| 3385 | @@ -327,8 +327,15 @@
|
---|
| 3386 | rl_command_func_t *f;
|
---|
| 3387 |
|
---|
| 3388 | f = (rl_command_func_t *)NULL;
|
---|
| 3389 | -
|
---|
| 3390 | - /* Translate the keys we do something with to opcodes. */
|
---|
| 3391 | +
|
---|
| 3392 | + if (c < 0)
|
---|
| 3393 | + {
|
---|
| 3394 | + cxt->sflags |= SF_FAILED;
|
---|
| 3395 | + cxt->history_pos = cxt->last_found_line;
|
---|
| 3396 | + return -1;
|
---|
| 3397 | + }
|
---|
| 3398 | +
|
---|
| 3399 | + /* Translate the keys we do something with to opcodes. */
|
---|
| 3400 | if (c >= 0 && _rl_keymap[c].type == ISFUNC)
|
---|
| 3401 | {
|
---|
| 3402 | f = _rl_keymap[c].function;
|
---|
| 3403 | diff -Naur bash-3.2.orig/lib/readline/misc.c bash-3.2/lib/readline/misc.c
|
---|
| 3404 | --- bash-3.2.orig/lib/readline/misc.c 2005-12-26 17:20:46.000000000 -0500
|
---|
| 3405 | +++ bash-3.2/lib/readline/misc.c 2007-12-20 23:53:09.000000000 -0500
|
---|
| 3406 | @@ -146,6 +146,8 @@
|
---|
| 3407 | rl_restore_prompt ();
|
---|
| 3408 | rl_clear_message ();
|
---|
| 3409 | RL_UNSETSTATE(RL_STATE_NUMERICARG);
|
---|
| 3410 | + if (key < 0)
|
---|
| 3411 | + return -1;
|
---|
| 3412 | return (_rl_dispatch (key, _rl_keymap));
|
---|
| 3413 | }
|
---|
| 3414 | }
|
---|
| 3415 | diff -Naur bash-3.2.orig/lib/readline/readline.c bash-3.2/lib/readline/readline.c
|
---|
| 3416 | --- bash-3.2.orig/lib/readline/readline.c 2006-08-16 15:00:36.000000000 -0400
|
---|
| 3417 | +++ bash-3.2/lib/readline/readline.c 2007-12-20 23:53:09.000000000 -0500
|
---|
| 3418 | @@ -645,6 +645,11 @@
|
---|
| 3419 | if ((cxt->flags & KSEQ_DISPATCHED) == 0)
|
---|
| 3420 | {
|
---|
| 3421 | nkey = _rl_subseq_getchar (cxt->okey);
|
---|
| 3422 | + if (nkey < 0)
|
---|
| 3423 | + {
|
---|
| 3424 | + _rl_abort_internal ();
|
---|
| 3425 | + return -1;
|
---|
| 3426 | + }
|
---|
| 3427 | r = _rl_dispatch_subseq (nkey, cxt->dmap, cxt->subseq_arg);
|
---|
| 3428 | cxt->flags |= KSEQ_DISPATCHED;
|
---|
| 3429 | }
|
---|
| 3430 | diff -Naur bash-3.2.orig/lib/readline/text.c bash-3.2/lib/readline/text.c
|
---|
| 3431 | --- bash-3.2.orig/lib/readline/text.c 2006-07-28 11:55:27.000000000 -0400
|
---|
| 3432 | +++ bash-3.2/lib/readline/text.c 2007-12-20 23:53:09.000000000 -0500
|
---|
| 3433 | @@ -857,6 +857,9 @@
|
---|
| 3434 | c = rl_read_key ();
|
---|
| 3435 | RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
---|
| 3436 |
|
---|
| 3437 | + if (c < 0)
|
---|
| 3438 | + return -1;
|
---|
| 3439 | +
|
---|
| 3440 | #if defined (HANDLE_SIGNALS)
|
---|
| 3441 | if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
|
---|
| 3442 | _rl_restore_tty_signals ();
|
---|
| 3443 | @@ -1520,6 +1523,9 @@
|
---|
| 3444 |
|
---|
| 3445 | mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
|
---|
| 3446 |
|
---|
| 3447 | + if (mb_len <= 0)
|
---|
| 3448 | + return -1;
|
---|
| 3449 | +
|
---|
| 3450 | if (count < 0)
|
---|
| 3451 | return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
|
---|
| 3452 | else
|
---|
| 3453 | @@ -1536,6 +1542,9 @@
|
---|
| 3454 | c = rl_read_key ();
|
---|
| 3455 | RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
---|
| 3456 |
|
---|
| 3457 | + if (c < 0)
|
---|
| 3458 | + return -1;
|
---|
| 3459 | +
|
---|
| 3460 | if (count < 0)
|
---|
| 3461 | return (_rl_char_search_internal (-count, bdir, c));
|
---|
| 3462 | else
|
---|
| 3463 | diff -Naur bash-3.2.orig/lib/readline/vi_mode.c bash-3.2/lib/readline/vi_mode.c
|
---|
| 3464 | --- bash-3.2.orig/lib/readline/vi_mode.c 2006-07-29 16:42:28.000000000 -0400
|
---|
| 3465 | +++ bash-3.2/lib/readline/vi_mode.c 2007-12-20 23:53:09.000000000 -0500
|
---|
| 3466 | @@ -886,6 +886,13 @@
|
---|
| 3467 | RL_SETSTATE(RL_STATE_MOREINPUT);
|
---|
| 3468 | c = rl_read_key ();
|
---|
| 3469 | RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
---|
| 3470 | +
|
---|
| 3471 | + if (c < 0)
|
---|
| 3472 | + {
|
---|
| 3473 | + *nextkey = 0;
|
---|
| 3474 | + return -1;
|
---|
| 3475 | + }
|
---|
| 3476 | +
|
---|
| 3477 | *nextkey = c;
|
---|
| 3478 |
|
---|
| 3479 | if (!member (c, vi_motion))
|
---|
| 3480 | @@ -902,6 +909,11 @@
|
---|
| 3481 | RL_SETSTATE(RL_STATE_MOREINPUT);
|
---|
| 3482 | c = rl_read_key (); /* real command */
|
---|
| 3483 | RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
---|
| 3484 | + if (c < 0)
|
---|
| 3485 | + {
|
---|
| 3486 | + *nextkey = 0;
|
---|
| 3487 | + return -1;
|
---|
| 3488 | + }
|
---|
| 3489 | *nextkey = c;
|
---|
| 3490 | }
|
---|
| 3491 | else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
|
---|
| 3492 | @@ -1224,14 +1236,22 @@
|
---|
| 3493 | _rl_vi_callback_char_search (data)
|
---|
| 3494 | _rl_callback_generic_arg *data;
|
---|
| 3495 | {
|
---|
| 3496 | + int c;
|
---|
| 3497 | #if defined (HANDLE_MULTIBYTE)
|
---|
| 3498 | - _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
|
---|
| 3499 | + c = _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
|
---|
| 3500 | #else
|
---|
| 3501 | RL_SETSTATE(RL_STATE_MOREINPUT);
|
---|
| 3502 | - _rl_vi_last_search_char = rl_read_key ();
|
---|
| 3503 | + c = rl_read_key ();
|
---|
| 3504 | RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
---|
| 3505 | #endif
|
---|
| 3506 |
|
---|
| 3507 | + if (c <= 0)
|
---|
| 3508 | + return -1;
|
---|
| 3509 | +
|
---|
| 3510 | +#if !defined (HANDLE_MULTIBYTE)
|
---|
| 3511 | + _rl_vi_last_search_char = c;
|
---|
| 3512 | +#endif
|
---|
| 3513 | +
|
---|
| 3514 | _rl_callback_func = 0;
|
---|
| 3515 | _rl_want_redisplay = 1;
|
---|
| 3516 |
|
---|
| 3517 | @@ -1247,6 +1267,7 @@
|
---|
| 3518 | rl_vi_char_search (count, key)
|
---|
| 3519 | int count, key;
|
---|
| 3520 | {
|
---|
| 3521 | + int c;
|
---|
| 3522 | #if defined (HANDLE_MULTIBYTE)
|
---|
| 3523 | static char *target;
|
---|
| 3524 | static int tlen;
|
---|
| 3525 | @@ -1293,11 +1314,17 @@
|
---|
| 3526 | else
|
---|
| 3527 | {
|
---|
| 3528 | #if defined (HANDLE_MULTIBYTE)
|
---|
| 3529 | - _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
|
---|
| 3530 | + c = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
|
---|
| 3531 | + if (c <= 0)
|
---|
| 3532 | + return -1;
|
---|
| 3533 | + _rl_vi_last_search_mblen = c;
|
---|
| 3534 | #else
|
---|
| 3535 | RL_SETSTATE(RL_STATE_MOREINPUT);
|
---|
| 3536 | - _rl_vi_last_search_char = rl_read_key ();
|
---|
| 3537 | + c = rl_read_key ();
|
---|
| 3538 | RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
---|
| 3539 | + if (c < 0)
|
---|
| 3540 | + return -1;
|
---|
| 3541 | + _rl_vi_last_search_char = c;
|
---|
| 3542 | #endif
|
---|
| 3543 | }
|
---|
| 3544 | }
|
---|
| 3545 | @@ -1467,6 +1494,9 @@
|
---|
| 3546 | c = rl_read_key ();
|
---|
| 3547 | RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
---|
| 3548 |
|
---|
| 3549 | + if (c < 0)
|
---|
| 3550 | + return -1;
|
---|
| 3551 | +
|
---|
| 3552 | #if defined (HANDLE_MULTIBYTE)
|
---|
| 3553 | if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
| 3554 | c = _rl_read_mbstring (c, mb, mlen);
|
---|
| 3555 | @@ -1485,6 +1515,9 @@
|
---|
| 3556 |
|
---|
| 3557 | _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
|
---|
| 3558 |
|
---|
| 3559 | + if (c < 0)
|
---|
| 3560 | + return -1;
|
---|
| 3561 | +
|
---|
| 3562 | _rl_callback_func = 0;
|
---|
| 3563 | _rl_want_redisplay = 1;
|
---|
| 3564 |
|
---|
| 3565 | @@ -1516,6 +1549,9 @@
|
---|
| 3566 | else
|
---|
| 3567 | _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
|
---|
| 3568 |
|
---|
| 3569 | + if (c < 0)
|
---|
| 3570 | + return -1;
|
---|
| 3571 | +
|
---|
| 3572 | return (_rl_vi_change_char (count, c, mb));
|
---|
| 3573 | }
|
---|
| 3574 |
|
---|
| 3575 | @@ -1650,7 +1686,7 @@
|
---|
| 3576 | ch = rl_read_key ();
|
---|
| 3577 | RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
---|
| 3578 |
|
---|
| 3579 | - if (ch < 'a' || ch > 'z')
|
---|
| 3580 | + if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */
|
---|
| 3581 | {
|
---|
| 3582 | rl_ding ();
|
---|
| 3583 | return -1;
|
---|
| 3584 | @@ -1702,7 +1738,7 @@
|
---|
| 3585 | rl_point = rl_mark;
|
---|
| 3586 | return 0;
|
---|
| 3587 | }
|
---|
| 3588 | - else if (ch < 'a' || ch > 'z')
|
---|
| 3589 | + else if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */
|
---|
| 3590 | {
|
---|
| 3591 | rl_ding ();
|
---|
| 3592 | return -1;
|
---|
| 3593 | diff -Naur bash-3.2.orig/lib/sh/snprintf.c bash-3.2/lib/sh/snprintf.c
|
---|
| 3594 | --- bash-3.2.orig/lib/sh/snprintf.c 2006-04-06 09:48:40.000000000 -0400
|
---|
| 3595 | +++ bash-3.2/lib/sh/snprintf.c 2007-12-20 23:53:00.000000000 -0500
|
---|
| 3596 | @@ -471,6 +471,8 @@
|
---|
| 3597 | 10^x ~= r
|
---|
| 3598 | * log_10(200) = 2;
|
---|
| 3599 | * log_10(250) = 2;
|
---|
| 3600 | + *
|
---|
| 3601 | + * NOTE: do not call this with r == 0 -- an infinite loop results.
|
---|
| 3602 | */
|
---|
| 3603 | static int
|
---|
| 3604 | log_10(r)
|
---|
| 3605 | @@ -576,8 +578,11 @@
|
---|
| 3606 | {
|
---|
| 3607 | integral_part[0] = '0';
|
---|
| 3608 | integral_part[1] = '\0';
|
---|
| 3609 | - fraction_part[0] = '0';
|
---|
| 3610 | - fraction_part[1] = '\0';
|
---|
| 3611 | + /* The fractional part has to take the precision into account */
|
---|
| 3612 | + for (ch = 0; ch < precision-1; ch++)
|
---|
| 3613 | + fraction_part[ch] = '0';
|
---|
| 3614 | + fraction_part[ch] = '0';
|
---|
| 3615 | + fraction_part[ch+1] = '\0';
|
---|
| 3616 | if (fract)
|
---|
| 3617 | *fract = fraction_part;
|
---|
| 3618 | return integral_part;
|
---|
| 3619 | @@ -663,7 +668,8 @@
|
---|
| 3620 | p->flags &= ~PF_ZEROPAD;
|
---|
| 3621 |
|
---|
| 3622 | sd = d; /* signed for ' ' padding in base 10 */
|
---|
| 3623 | - flags = (*p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
|
---|
| 3624 | + flags = 0;
|
---|
| 3625 | + flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
|
---|
| 3626 | if (*p->pf == 'X')
|
---|
| 3627 | flags |= FL_HEXUPPER;
|
---|
| 3628 |
|
---|
| 3629 | @@ -733,7 +739,7 @@
|
---|
| 3630 | p->flags &= ~PF_ZEROPAD;
|
---|
| 3631 |
|
---|
| 3632 | sd = d; /* signed for ' ' padding in base 10 */
|
---|
| 3633 | - flags = (*p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
|
---|
| 3634 | + flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
|
---|
| 3635 | if (*p->pf == 'X')
|
---|
| 3636 | flags |= FL_HEXUPPER;
|
---|
| 3637 |
|
---|
| 3638 | @@ -805,6 +811,7 @@
|
---|
| 3639 | PUT_CHAR(*tmp, p);
|
---|
| 3640 | tmp++;
|
---|
| 3641 | }
|
---|
| 3642 | +
|
---|
| 3643 | PAD_LEFT(p);
|
---|
| 3644 | }
|
---|
| 3645 |
|
---|
| 3646 | @@ -972,11 +979,21 @@
|
---|
| 3647 | if ((p->flags & PF_THOUSANDS) && grouping && (t = groupnum (tmp)))
|
---|
| 3648 | tmp = t;
|
---|
| 3649 |
|
---|
| 3650 | + if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0)
|
---|
| 3651 | + {
|
---|
| 3652 | + /* smash the trailing zeros unless altform */
|
---|
| 3653 | + for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
|
---|
| 3654 | + tmp2[i] = '\0';
|
---|
| 3655 | + if (tmp2[0] == '\0')
|
---|
| 3656 | + p->precision = 0;
|
---|
| 3657 | + }
|
---|
| 3658 | +
|
---|
| 3659 | /* calculate the padding. 1 for the dot */
|
---|
| 3660 | p->width = p->width -
|
---|
| 3661 | ((d > 0. && p->justify == RIGHT) ? 1:0) -
|
---|
| 3662 | ((p->flags & PF_SPACE) ? 1:0) -
|
---|
| 3663 | - strlen(tmp) - p->precision - 1;
|
---|
| 3664 | + strlen(tmp) - p->precision -
|
---|
| 3665 | + ((p->precision != 0 || (p->flags & PF_ALTFORM)) ? 1 : 0); /* radix char */
|
---|
| 3666 | PAD_RIGHT(p);
|
---|
| 3667 | PUT_PLUS(d, p, 0.);
|
---|
| 3668 | PUT_SPACE(d, p, 0.);
|
---|
| 3669 | @@ -991,11 +1008,6 @@
|
---|
| 3670 | if (p->precision != 0 || (p->flags & PF_ALTFORM))
|
---|
| 3671 | PUT_CHAR(decpoint, p); /* put the '.' */
|
---|
| 3672 |
|
---|
| 3673 | - if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0)
|
---|
| 3674 | - /* smash the trailing zeros unless altform */
|
---|
| 3675 | - for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
|
---|
| 3676 | - tmp2[i] = '\0';
|
---|
| 3677 | -
|
---|
| 3678 | for (; *tmp2; tmp2++)
|
---|
| 3679 | PUT_CHAR(*tmp2, p); /* the fraction */
|
---|
| 3680 |
|
---|
| 3681 | @@ -1011,14 +1023,19 @@
|
---|
| 3682 | char *tmp, *tmp2;
|
---|
| 3683 | int j, i;
|
---|
| 3684 |
|
---|
| 3685 | - if (chkinfnan(p, d, 1) || chkinfnan(p, d, 2))
|
---|
| 3686 | + if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2)))
|
---|
| 3687 | return; /* already printed nan or inf */
|
---|
| 3688 |
|
---|
| 3689 | GETLOCALEDATA(decpoint, thoussep, grouping);
|
---|
| 3690 | DEF_PREC(p);
|
---|
| 3691 | - j = log_10(d);
|
---|
| 3692 | - d = d / pow_10(j); /* get the Mantissa */
|
---|
| 3693 | - d = ROUND(d, p);
|
---|
| 3694 | + if (d == 0.)
|
---|
| 3695 | + j = 0;
|
---|
| 3696 | + else
|
---|
| 3697 | + {
|
---|
| 3698 | + j = log_10(d);
|
---|
| 3699 | + d = d / pow_10(j); /* get the Mantissa */
|
---|
| 3700 | + d = ROUND(d, p);
|
---|
| 3701 | + }
|
---|
| 3702 | tmp = dtoa(d, p->precision, &tmp2);
|
---|
| 3703 |
|
---|
| 3704 | /* 1 for unit, 1 for the '.', 1 for 'e|E',
|
---|
| 3705 | @@ -1076,6 +1093,7 @@
|
---|
| 3706 | PUT_CHAR(*tmp, p);
|
---|
| 3707 | tmp++;
|
---|
| 3708 | }
|
---|
| 3709 | +
|
---|
| 3710 | PAD_LEFT(p);
|
---|
| 3711 | }
|
---|
| 3712 | #endif
|
---|
| 3713 | @@ -1358,7 +1376,7 @@
|
---|
| 3714 | STAR_ARGS(data);
|
---|
| 3715 | DEF_PREC(data);
|
---|
| 3716 | d = GETDOUBLE(data);
|
---|
| 3717 | - i = log_10(d);
|
---|
| 3718 | + i = (d != 0.) ? log_10(d) : -1;
|
---|
| 3719 | /*
|
---|
| 3720 | * for '%g|%G' ANSI: use f if exponent
|
---|
| 3721 | * is in the range or [-4,p] exclusively
|
---|
| 3722 | diff -Naur bash-3.2.orig/parse.y bash-3.2/parse.y
|
---|
| 3723 | --- bash-3.2.orig/parse.y 2006-09-19 16:37:21.000000000 -0400
|
---|
| 3724 | +++ bash-3.2/parse.y 2007-12-20 23:53:10.000000000 -0500
|
---|
| 3725 | @@ -1029,6 +1029,7 @@
|
---|
| 3726 | #define PST_CMDTOKEN 0x1000 /* command token OK - unused */
|
---|
| 3727 | #define PST_COMPASSIGN 0x2000 /* parsing x=(...) compound assignment */
|
---|
| 3728 | #define PST_ASSIGNOK 0x4000 /* assignment statement ok in this context */
|
---|
| 3729 | +#define PST_REGEXP 0x8000 /* parsing an ERE/BRE as a single word */
|
---|
| 3730 |
|
---|
| 3731 | /* Initial size to allocate for tokens, and the
|
---|
| 3732 | amount to grow them by. */
|
---|
| 3733 | @@ -2591,6 +2592,9 @@
|
---|
| 3734 | return (character);
|
---|
| 3735 | }
|
---|
| 3736 |
|
---|
| 3737 | + if (parser_state & PST_REGEXP)
|
---|
| 3738 | + goto tokword;
|
---|
| 3739 | +
|
---|
| 3740 | /* Shell meta-characters. */
|
---|
| 3741 | if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
|
---|
| 3742 | {
|
---|
| 3743 | @@ -2698,6 +2702,7 @@
|
---|
| 3744 | if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
|
---|
| 3745 | return (character);
|
---|
| 3746 |
|
---|
| 3747 | +tokword:
|
---|
| 3748 | /* Okay, if we got this far, we have to read a word. Read one,
|
---|
| 3749 | and then check it against the known ones. */
|
---|
| 3750 | result = read_token_word (character);
|
---|
| 3751 | @@ -2735,7 +2740,7 @@
|
---|
| 3752 | /* itrace("parse_matched_pair: open = %c close = %c", open, close); */
|
---|
| 3753 | count = 1;
|
---|
| 3754 | pass_next_character = backq_backslash = was_dollar = in_comment = 0;
|
---|
| 3755 | - check_comment = (flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0;
|
---|
| 3756 | + check_comment = (flags & P_COMMAND) && qc != '`' && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0;
|
---|
| 3757 |
|
---|
| 3758 | /* RFLAGS is the set of flags we want to pass to recursive calls. */
|
---|
| 3759 | rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE);
|
---|
| 3760 | @@ -3202,8 +3207,11 @@
|
---|
| 3761 | if (tok == WORD && test_binop (yylval.word->word))
|
---|
| 3762 | op = yylval.word;
|
---|
| 3763 | #if defined (COND_REGEXP)
|
---|
| 3764 | - else if (tok == WORD && STREQ (yylval.word->word,"=~"))
|
---|
| 3765 | - op = yylval.word;
|
---|
| 3766 | + else if (tok == WORD && STREQ (yylval.word->word, "=~"))
|
---|
| 3767 | + {
|
---|
| 3768 | + op = yylval.word;
|
---|
| 3769 | + parser_state |= PST_REGEXP;
|
---|
| 3770 | + }
|
---|
| 3771 | #endif
|
---|
| 3772 | else if (tok == '<' || tok == '>')
|
---|
| 3773 | op = make_word_from_token (tok); /* ( */
|
---|
| 3774 | @@ -3234,6 +3242,7 @@
|
---|
| 3775 |
|
---|
| 3776 | /* rhs */
|
---|
| 3777 | tok = read_token (READ);
|
---|
| 3778 | + parser_state &= ~PST_REGEXP;
|
---|
| 3779 | if (tok == WORD)
|
---|
| 3780 | {
|
---|
| 3781 | tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
|
---|
| 3782 | @@ -3367,7 +3376,7 @@
|
---|
| 3783 | if (pass_next_character)
|
---|
| 3784 | {
|
---|
| 3785 | pass_next_character = 0;
|
---|
| 3786 | - goto got_character;
|
---|
| 3787 | + goto got_escaped_character;
|
---|
| 3788 | }
|
---|
| 3789 |
|
---|
| 3790 | cd = current_delimiter (dstack);
|
---|
| 3791 | @@ -3419,9 +3428,34 @@
|
---|
| 3792 | goto next_character;
|
---|
| 3793 | }
|
---|
| 3794 |
|
---|
| 3795 | +#ifdef COND_REGEXP
|
---|
| 3796 | + /* When parsing a regexp as a single word inside a conditional command,
|
---|
| 3797 | + we need to special-case characters special to both the shell and
|
---|
| 3798 | + regular expressions. Right now, that is only '(' and '|'. */ /*)*/
|
---|
| 3799 | + if MBTEST((parser_state & PST_REGEXP) && (character == '(' || character == '|')) /*)*/
|
---|
| 3800 | + {
|
---|
| 3801 | + if (character == '|')
|
---|
| 3802 | + goto got_character;
|
---|
| 3803 | +
|
---|
| 3804 | + push_delimiter (dstack, character);
|
---|
| 3805 | + ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
|
---|
| 3806 | + pop_delimiter (dstack);
|
---|
| 3807 | + if (ttok == &matched_pair_error)
|
---|
| 3808 | + return -1; /* Bail immediately. */
|
---|
| 3809 | + RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
|
---|
| 3810 | + token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
|
---|
| 3811 | + token[token_index++] = character;
|
---|
| 3812 | + strcpy (token + token_index, ttok);
|
---|
| 3813 | + token_index += ttoklen;
|
---|
| 3814 | + FREE (ttok);
|
---|
| 3815 | + dollar_present = all_digit_token = 0;
|
---|
| 3816 | + goto next_character;
|
---|
| 3817 | + }
|
---|
| 3818 | +#endif /* COND_REGEXP */
|
---|
| 3819 | +
|
---|
| 3820 | #ifdef EXTENDED_GLOB
|
---|
| 3821 | /* Parse a ksh-style extended pattern matching specification. */
|
---|
| 3822 | - if (extended_glob && PATTERN_CHAR (character))
|
---|
| 3823 | + if MBTEST(extended_glob && PATTERN_CHAR (character))
|
---|
| 3824 | {
|
---|
| 3825 | peek_char = shell_getc (1);
|
---|
| 3826 | if MBTEST(peek_char == '(') /* ) */
|
---|
| 3827 | @@ -3616,12 +3650,14 @@
|
---|
| 3828 |
|
---|
| 3829 | got_character:
|
---|
| 3830 |
|
---|
| 3831 | - all_digit_token &= DIGIT (character);
|
---|
| 3832 | - dollar_present |= character == '$';
|
---|
| 3833 | -
|
---|
| 3834 | if (character == CTLESC || character == CTLNUL)
|
---|
| 3835 | token[token_index++] = CTLESC;
|
---|
| 3836 |
|
---|
| 3837 | + got_escaped_character:
|
---|
| 3838 | +
|
---|
| 3839 | + all_digit_token &= DIGIT (character);
|
---|
| 3840 | + dollar_present |= character == '$';
|
---|
| 3841 | +
|
---|
| 3842 | token[token_index++] = character;
|
---|
| 3843 |
|
---|
| 3844 | RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
|
---|
| 3845 | diff -Naur bash-3.2.orig/patchlevel.h bash-3.2/patchlevel.h
|
---|
| 3846 | --- bash-3.2.orig/patchlevel.h 2006-04-13 08:31:04.000000000 -0400
|
---|
| 3847 | +++ bash-3.2/patchlevel.h 2007-12-20 23:53:18.000000000 -0500
|
---|
| 3848 | @@ -25,6 +25,6 @@
|
---|
| 3849 | regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
---|
| 3850 | looks for to find the patch level (for the sccs version string). */
|
---|
| 3851 |
|
---|
| 3852 | -#define PATCHLEVEL 0
|
---|
| 3853 | +#define PATCHLEVEL 33
|
---|
| 3854 |
|
---|
| 3855 | #endif /* _PATCHLEVEL_H_ */
|
---|
| 3856 | diff -Naur bash-3.2.orig/pathexp.c bash-3.2/pathexp.c
|
---|
| 3857 | --- bash-3.2.orig/pathexp.c 2002-05-06 13:43:05.000000000 -0400
|
---|
| 3858 | +++ bash-3.2/pathexp.c 2007-12-20 23:53:00.000000000 -0500
|
---|
| 3859 | @@ -1,6 +1,6 @@
|
---|
| 3860 | /* pathexp.c -- The shell interface to the globbing library. */
|
---|
| 3861 |
|
---|
| 3862 | -/* Copyright (C) 1995-2002 Free Software Foundation, Inc.
|
---|
| 3863 | +/* Copyright (C) 1995-2007 Free Software Foundation, Inc.
|
---|
| 3864 |
|
---|
| 3865 | This file is part of GNU Bash, the Bourne Again SHell.
|
---|
| 3866 |
|
---|
| 3867 | @@ -110,6 +110,33 @@
|
---|
| 3868 | return (0);
|
---|
| 3869 | }
|
---|
| 3870 |
|
---|
| 3871 | +/* Return 1 if C is a character that is `special' in a POSIX ERE and needs to
|
---|
| 3872 | + be quoted to match itself. */
|
---|
| 3873 | +static inline int
|
---|
| 3874 | +ere_char (c)
|
---|
| 3875 | + int c;
|
---|
| 3876 | +{
|
---|
| 3877 | + switch (c)
|
---|
| 3878 | + {
|
---|
| 3879 | + case '.':
|
---|
| 3880 | + case '[':
|
---|
| 3881 | + case '\\':
|
---|
| 3882 | + case '(':
|
---|
| 3883 | + case ')':
|
---|
| 3884 | + case '*':
|
---|
| 3885 | + case '+':
|
---|
| 3886 | + case '?':
|
---|
| 3887 | + case '{':
|
---|
| 3888 | + case '|':
|
---|
| 3889 | + case '^':
|
---|
| 3890 | + case '$':
|
---|
| 3891 | + return 1;
|
---|
| 3892 | + default:
|
---|
| 3893 | + return 0;
|
---|
| 3894 | + }
|
---|
| 3895 | + return (0);
|
---|
| 3896 | +}
|
---|
| 3897 | +
|
---|
| 3898 | /* PATHNAME can contain characters prefixed by CTLESC; this indicates
|
---|
| 3899 | that the character is to be quoted. We quote it here in the style
|
---|
| 3900 | that the glob library recognizes. If flags includes QGLOB_CVTNULL,
|
---|
| 3901 | @@ -142,6 +169,8 @@
|
---|
| 3902 | {
|
---|
| 3903 | if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/')
|
---|
| 3904 | continue;
|
---|
| 3905 | + if ((qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0)
|
---|
| 3906 | + continue;
|
---|
| 3907 | temp[j++] = '\\';
|
---|
| 3908 | i++;
|
---|
| 3909 | if (pathname[i] == '\0')
|
---|
| 3910 | diff -Naur bash-3.2.orig/pathexp.h bash-3.2/pathexp.h
|
---|
| 3911 | --- bash-3.2.orig/pathexp.h 2005-02-19 17:23:18.000000000 -0500
|
---|
| 3912 | +++ bash-3.2/pathexp.h 2007-12-20 23:53:00.000000000 -0500
|
---|
| 3913 | @@ -1,6 +1,6 @@
|
---|
| 3914 | /* pathexp.h -- The shell interface to the globbing library. */
|
---|
| 3915 |
|
---|
| 3916 | -/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
|
---|
| 3917 | +/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
|
---|
| 3918 |
|
---|
| 3919 | This file is part of GNU Bash, the Bourne Again SHell.
|
---|
| 3920 |
|
---|
| 3921 | @@ -32,6 +32,7 @@
|
---|
| 3922 | /* Flag values for quote_string_for_globbing */
|
---|
| 3923 | #define QGLOB_CVTNULL 0x01 /* convert QUOTED_NULL strings to '\0' */
|
---|
| 3924 | #define QGLOB_FILENAME 0x02 /* do correct quoting for matching filenames */
|
---|
| 3925 | +#define QGLOB_REGEXP 0x04 /* quote an ERE for regcomp/regexec */
|
---|
| 3926 |
|
---|
| 3927 | #if defined (EXTENDED_GLOB)
|
---|
| 3928 | /* Flags to OR with other flag args to strmatch() to enabled the extended
|
---|
| 3929 | diff -Naur bash-3.2.orig/po/ru.po bash-3.2/po/ru.po
|
---|
| 3930 | --- bash-3.2.orig/po/ru.po 2006-01-10 17:51:03.000000000 -0500
|
---|
| 3931 | +++ bash-3.2/po/ru.po 2007-12-20 23:52:54.000000000 -0500
|
---|
| 3932 | @@ -12,7 +12,7 @@
|
---|
| 3933 | "Last-Translator: Evgeniy Dushistov <dushistov@mail.ru>\n"
|
---|
| 3934 | "Language-Team: Russian <ru@li.org>\n"
|
---|
| 3935 | "MIME-Version: 1.0\n"
|
---|
| 3936 | -"Content-Type: text/plain; charset=UTF-8\n"
|
---|
| 3937 | +"Content-Type: text/plain; charset=KOI8-R\n"
|
---|
| 3938 | "Content-Transfer-Encoding: 8bit\n"
|
---|
| 3939 | "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"
|
---|
| 3940 |
|
---|
| 3941 | diff -Naur bash-3.2.orig/sig.c bash-3.2/sig.c
|
---|
| 3942 | --- bash-3.2.orig/sig.c 2006-01-25 14:57:59.000000000 -0500
|
---|
| 3943 | +++ bash-3.2/sig.c 2007-12-20 23:53:10.000000000 -0500
|
---|
| 3944 | @@ -350,6 +350,25 @@
|
---|
| 3945 | #undef XSIG
|
---|
| 3946 | #undef XHANDLER
|
---|
| 3947 |
|
---|
| 3948 | +/* Run some of the cleanups that should be performed when we run
|
---|
| 3949 | + jump_to_top_level from a builtin command context. XXX - might want to
|
---|
| 3950 | + also call reset_parser here. */
|
---|
| 3951 | +void
|
---|
| 3952 | +top_level_cleanup ()
|
---|
| 3953 | +{
|
---|
| 3954 | + /* Clean up string parser environment. */
|
---|
| 3955 | + while (parse_and_execute_level)
|
---|
| 3956 | + parse_and_execute_cleanup ();
|
---|
| 3957 | +
|
---|
| 3958 | +#if defined (PROCESS_SUBSTITUTION)
|
---|
| 3959 | + unlink_fifo_list ();
|
---|
| 3960 | +#endif /* PROCESS_SUBSTITUTION */
|
---|
| 3961 | +
|
---|
| 3962 | + run_unwind_protects ();
|
---|
| 3963 | + loop_level = continuing = breaking = 0;
|
---|
| 3964 | + return_catch_flag = 0;
|
---|
| 3965 | +}
|
---|
| 3966 | +
|
---|
| 3967 | /* What to do when we've been interrupted, and it is safe to handle it. */
|
---|
| 3968 | void
|
---|
| 3969 | throw_to_top_level ()
|
---|
| 3970 | diff -Naur bash-3.2.orig/sig.h bash-3.2/sig.h
|
---|
| 3971 | --- bash-3.2.orig/sig.h 2006-01-25 14:50:27.000000000 -0500
|
---|
| 3972 | +++ bash-3.2/sig.h 2007-12-20 23:53:10.000000000 -0500
|
---|
| 3973 | @@ -121,6 +121,7 @@
|
---|
| 3974 | extern void initialize_signals __P((int));
|
---|
| 3975 | extern void initialize_terminating_signals __P((void));
|
---|
| 3976 | extern void reset_terminating_signals __P((void));
|
---|
| 3977 | +extern void top_level_cleanup __P((void));
|
---|
| 3978 | extern void throw_to_top_level __P((void));
|
---|
| 3979 | extern void jump_to_top_level __P((int)) __attribute__((__noreturn__));
|
---|
| 3980 |
|
---|
| 3981 | diff -Naur bash-3.2.orig/subst.c bash-3.2/subst.c
|
---|
| 3982 | --- bash-3.2.orig/subst.c 2006-09-19 08:35:09.000000000 -0400
|
---|
| 3983 | +++ bash-3.2/subst.c 2007-12-20 23:53:18.000000000 -0500
|
---|
| 3984 | @@ -4,7 +4,7 @@
|
---|
| 3985 | /* ``Have a little faith, there's magic in the night. You ain't a
|
---|
| 3986 | beauty, but, hey, you're alright.'' */
|
---|
| 3987 |
|
---|
| 3988 | -/* Copyright (C) 1987-2006 Free Software Foundation, Inc.
|
---|
| 3989 | +/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
|
---|
| 3990 |
|
---|
| 3991 | This file is part of GNU Bash, the Bourne Again SHell.
|
---|
| 3992 |
|
---|
| 3993 | @@ -1278,7 +1278,7 @@
|
---|
| 3994 | {
|
---|
| 3995 | if (no_longjmp_on_fatal_error == 0)
|
---|
| 3996 | { /* { */
|
---|
| 3997 | - report_error ("bad substitution: no closing `%s' in %s", "}", string);
|
---|
| 3998 | + report_error (_("bad substitution: no closing `%s' in %s"), "}", string);
|
---|
| 3999 | last_command_exit_value = EXECUTION_FAILURE;
|
---|
| 4000 | exp_jump_to_top_level (DISCARD);
|
---|
| 4001 | }
|
---|
| 4002 | @@ -1887,7 +1887,13 @@
|
---|
| 4003 | sep[1] = '\0';
|
---|
| 4004 | #endif
|
---|
| 4005 |
|
---|
| 4006 | + /* XXX -- why call quote_list if ifs == 0? we can get away without doing
|
---|
| 4007 | + it now that quote_escapes quotes spaces */
|
---|
| 4008 | +#if 0
|
---|
| 4009 | tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
|
---|
| 4010 | +#else
|
---|
| 4011 | + tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
|
---|
| 4012 | +#endif
|
---|
| 4013 | ? quote_list (list)
|
---|
| 4014 | : list_quote_escapes (list);
|
---|
| 4015 |
|
---|
| 4016 | @@ -2646,11 +2652,12 @@
|
---|
| 4017 |
|
---|
| 4018 | /* This needs better error handling. */
|
---|
| 4019 | /* Expand W for use as an argument to a unary or binary operator in a
|
---|
| 4020 | - [[...]] expression. If SPECIAL is nonzero, this is the rhs argument
|
---|
| 4021 | + [[...]] expression. If SPECIAL is 1, this is the rhs argument
|
---|
| 4022 | to the != or == operator, and should be treated as a pattern. In
|
---|
| 4023 | - this case, we quote the string specially for the globbing code. The
|
---|
| 4024 | - caller is responsible for removing the backslashes if the unquoted
|
---|
| 4025 | - words is needed later. */
|
---|
| 4026 | + this case, we quote the string specially for the globbing code. If
|
---|
| 4027 | + SPECIAL is 2, this is an rhs argument for the =~ operator, and should
|
---|
| 4028 | + be quoted appropriately for regcomp/regexec. The caller is responsible
|
---|
| 4029 | + for removing the backslashes if the unquoted word is needed later. */
|
---|
| 4030 | char *
|
---|
| 4031 | cond_expand_word (w, special)
|
---|
| 4032 | WORD_DESC *w;
|
---|
| 4033 | @@ -2658,6 +2665,7 @@
|
---|
| 4034 | {
|
---|
| 4035 | char *r, *p;
|
---|
| 4036 | WORD_LIST *l;
|
---|
| 4037 | + int qflags;
|
---|
| 4038 |
|
---|
| 4039 | if (w->word == 0 || w->word[0] == '\0')
|
---|
| 4040 | return ((char *)NULL);
|
---|
| 4041 | @@ -2672,8 +2680,11 @@
|
---|
| 4042 | }
|
---|
| 4043 | else
|
---|
| 4044 | {
|
---|
| 4045 | + qflags = QGLOB_CVTNULL;
|
---|
| 4046 | + if (special == 2)
|
---|
| 4047 | + qflags |= QGLOB_REGEXP;
|
---|
| 4048 | p = string_list (l);
|
---|
| 4049 | - r = quote_string_for_globbing (p, QGLOB_CVTNULL);
|
---|
| 4050 | + r = quote_string_for_globbing (p, qflags);
|
---|
| 4051 | free (p);
|
---|
| 4052 | }
|
---|
| 4053 | dispose_words (l);
|
---|
| 4054 | @@ -2916,7 +2927,12 @@
|
---|
| 4055 |
|
---|
| 4056 | /* Quote escape characters in string s, but no other characters. This is
|
---|
| 4057 | used to protect CTLESC and CTLNUL in variable values from the rest of
|
---|
| 4058 | - the word expansion process after the variable is expanded. */
|
---|
| 4059 | + the word expansion process after the variable is expanded. If IFS is
|
---|
| 4060 | + null, we quote spaces as well, just in case we split on spaces later
|
---|
| 4061 | + (in the case of unquoted $@, we will eventually attempt to split the
|
---|
| 4062 | + entire word on spaces). Corresponding code exists in dequote_escapes.
|
---|
| 4063 | + Even if we don't end up splitting on spaces, quoting spaces is not a
|
---|
| 4064 | + problem. */
|
---|
| 4065 | char *
|
---|
| 4066 | quote_escapes (string)
|
---|
| 4067 | char *string;
|
---|
| 4068 | @@ -2924,17 +2940,19 @@
|
---|
| 4069 | register char *s, *t;
|
---|
| 4070 | size_t slen;
|
---|
| 4071 | char *result, *send;
|
---|
| 4072 | + int quote_spaces;
|
---|
| 4073 | DECLARE_MBSTATE;
|
---|
| 4074 |
|
---|
| 4075 | slen = strlen (string);
|
---|
| 4076 | send = string + slen;
|
---|
| 4077 |
|
---|
| 4078 | + quote_spaces = (ifs_value && *ifs_value == 0);
|
---|
| 4079 | t = result = (char *)xmalloc ((slen * 2) + 1);
|
---|
| 4080 | s = string;
|
---|
| 4081 |
|
---|
| 4082 | while (*s)
|
---|
| 4083 | {
|
---|
| 4084 | - if (*s == CTLESC || *s == CTLNUL)
|
---|
| 4085 | + if (*s == CTLESC || *s == CTLNUL || (quote_spaces && *s == ' '))
|
---|
| 4086 | *t++ = CTLESC;
|
---|
| 4087 | COPY_CHAR_P (t, s, send);
|
---|
| 4088 | }
|
---|
| 4089 | @@ -2976,6 +2994,7 @@
|
---|
| 4090 | register char *s, *t;
|
---|
| 4091 | size_t slen;
|
---|
| 4092 | char *result, *send;
|
---|
| 4093 | + int quote_spaces;
|
---|
| 4094 | DECLARE_MBSTATE;
|
---|
| 4095 |
|
---|
| 4096 | if (string == 0)
|
---|
| 4097 | @@ -2990,9 +3009,10 @@
|
---|
| 4098 | if (strchr (string, CTLESC) == 0)
|
---|
| 4099 | return (strcpy (result, s));
|
---|
| 4100 |
|
---|
| 4101 | + quote_spaces = (ifs_value && *ifs_value == 0);
|
---|
| 4102 | while (*s)
|
---|
| 4103 | {
|
---|
| 4104 | - if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL))
|
---|
| 4105 | + if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' ')))
|
---|
| 4106 | {
|
---|
| 4107 | s++;
|
---|
| 4108 | if (*s == '\0')
|
---|
| 4109 | @@ -3954,7 +3974,11 @@
|
---|
| 4110 | if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
|
---|
| 4111 | patstr++;
|
---|
| 4112 |
|
---|
| 4113 | - pattern = getpattern (patstr, quoted, 1);
|
---|
| 4114 | + /* Need to pass getpattern newly-allocated memory in case of expansion --
|
---|
| 4115 | + the expansion code will free the passed string on an error. */
|
---|
| 4116 | + temp1 = savestring (patstr);
|
---|
| 4117 | + pattern = getpattern (temp1, quoted, 1);
|
---|
| 4118 | + free (temp1);
|
---|
| 4119 |
|
---|
| 4120 | temp1 = (char *)NULL; /* shut up gcc */
|
---|
| 4121 | switch (vtype)
|
---|
| 4122 | @@ -4123,6 +4147,12 @@
|
---|
| 4123 | nfifo = 0;
|
---|
| 4124 | }
|
---|
| 4125 |
|
---|
| 4126 | +int
|
---|
| 4127 | +fifos_pending ()
|
---|
| 4128 | +{
|
---|
| 4129 | + return nfifo;
|
---|
| 4130 | +}
|
---|
| 4131 | +
|
---|
| 4132 | static char *
|
---|
| 4133 | make_named_pipe ()
|
---|
| 4134 | {
|
---|
| 4135 | @@ -4172,6 +4202,12 @@
|
---|
| 4136 | nfds++;
|
---|
| 4137 | }
|
---|
| 4138 |
|
---|
| 4139 | +int
|
---|
| 4140 | +fifos_pending ()
|
---|
| 4141 | +{
|
---|
| 4142 | + return 0; /* used for cleanup; not needed with /dev/fd */
|
---|
| 4143 | +}
|
---|
| 4144 | +
|
---|
| 4145 | void
|
---|
| 4146 | unlink_fifo_list ()
|
---|
| 4147 | {
|
---|
| 4148 | @@ -4456,7 +4492,15 @@
|
---|
| 4149 | /* Add the character to ISTRING, possibly after resizing it. */
|
---|
| 4150 | RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
|
---|
| 4151 |
|
---|
| 4152 | - if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || c == CTLESC || c == CTLNUL)
|
---|
| 4153 | + /* This is essentially quote_string inline */
|
---|
| 4154 | + if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
|
---|
| 4155 | + istring[istring_index++] = CTLESC;
|
---|
| 4156 | + /* Escape CTLESC and CTLNUL in the output to protect those characters
|
---|
| 4157 | + from the rest of the word expansions (word splitting and globbing.)
|
---|
| 4158 | + This is essentially quote_escapes inline. */
|
---|
| 4159 | + else if (c == CTLESC)
|
---|
| 4160 | + istring[istring_index++] = CTLESC;
|
---|
| 4161 | + else if (c == CTLNUL || (c == ' ' && (ifs_value && *ifs_value == 0)))
|
---|
| 4162 | istring[istring_index++] = CTLESC;
|
---|
| 4163 |
|
---|
| 4164 | istring[istring_index++] = c;
|
---|
| 4165 | @@ -4665,6 +4709,9 @@
|
---|
| 4166 |
|
---|
| 4167 | last_command_exit_value = rc;
|
---|
| 4168 | rc = run_exit_trap ();
|
---|
| 4169 | +#if defined (PROCESS_SUBSTITUTION)
|
---|
| 4170 | + unlink_fifo_list ();
|
---|
| 4171 | +#endif
|
---|
| 4172 | exit (rc);
|
---|
| 4173 | }
|
---|
| 4174 | else
|
---|
| 4175 | @@ -4860,10 +4907,11 @@
|
---|
| 4176 | char *temp, *tt;
|
---|
| 4177 | intmax_t arg_index;
|
---|
| 4178 | SHELL_VAR *var;
|
---|
| 4179 | - int atype;
|
---|
| 4180 | + int atype, rflags;
|
---|
| 4181 |
|
---|
| 4182 | ret = 0;
|
---|
| 4183 | temp = 0;
|
---|
| 4184 | + rflags = 0;
|
---|
| 4185 |
|
---|
| 4186 | /* Handle multiple digit arguments, as in ${11}. */
|
---|
| 4187 | if (legal_number (name, &arg_index))
|
---|
| 4188 | @@ -4896,6 +4944,8 @@
|
---|
| 4189 | temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
|
---|
| 4190 | ? quote_string (temp)
|
---|
| 4191 | : quote_escapes (temp);
|
---|
| 4192 | + else if (atype == 1 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
|
---|
| 4193 | + rflags |= W_HASQUOTEDNULL;
|
---|
| 4194 | }
|
---|
| 4195 | #endif
|
---|
| 4196 | else if (var = find_variable (name))
|
---|
| 4197 | @@ -4923,6 +4973,7 @@
|
---|
| 4198 | {
|
---|
| 4199 | ret = alloc_word_desc ();
|
---|
| 4200 | ret->word = temp;
|
---|
| 4201 | + ret->flags |= rflags;
|
---|
| 4202 | }
|
---|
| 4203 | return ret;
|
---|
| 4204 | }
|
---|
| 4205 | @@ -5546,12 +5597,16 @@
|
---|
| 4206 | so verify_substring_values just returns the numbers specified and we
|
---|
| 4207 | rely on array_subrange to understand how to deal with them). */
|
---|
| 4208 | tt = array_subrange (array_cell (v), e1, e2, starsub, quoted);
|
---|
| 4209 | +#if 0
|
---|
| 4210 | + /* array_subrange now calls array_quote_escapes as appropriate, so the
|
---|
| 4211 | + caller no longer needs to. */
|
---|
| 4212 | if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
|
---|
| 4213 | {
|
---|
| 4214 | temp = tt ? quote_escapes (tt) : (char *)NULL;
|
---|
| 4215 | FREE (tt);
|
---|
| 4216 | }
|
---|
| 4217 | else
|
---|
| 4218 | +#endif
|
---|
| 4219 | temp = tt;
|
---|
| 4220 | break;
|
---|
| 4221 | #endif
|
---|
| 4222 | @@ -5707,6 +5762,11 @@
|
---|
| 4223 | vtype &= ~VT_STARSUB;
|
---|
| 4224 |
|
---|
| 4225 | mflags = 0;
|
---|
| 4226 | + if (patsub && *patsub == '/')
|
---|
| 4227 | + {
|
---|
| 4228 | + mflags |= MATCH_GLOBREP;
|
---|
| 4229 | + patsub++;
|
---|
| 4230 | + }
|
---|
| 4231 |
|
---|
| 4232 | /* Malloc this because expand_string_if_necessary or one of the expansion
|
---|
| 4233 | functions in its call chain may free it on a substitution error. */
|
---|
| 4234 | @@ -5741,13 +5801,12 @@
|
---|
| 4235 | }
|
---|
| 4236 |
|
---|
| 4237 | /* ksh93 doesn't allow the match specifier to be a part of the expanded
|
---|
| 4238 | - pattern. This is an extension. */
|
---|
| 4239 | + pattern. This is an extension. Make sure we don't anchor the pattern
|
---|
| 4240 | + at the beginning or end of the string if we're doing global replacement,
|
---|
| 4241 | + though. */
|
---|
| 4242 | p = pat;
|
---|
| 4243 | - if (pat && pat[0] == '/')
|
---|
| 4244 | - {
|
---|
| 4245 | - mflags |= MATCH_GLOBREP|MATCH_ANY;
|
---|
| 4246 | - p++;
|
---|
| 4247 | - }
|
---|
| 4248 | + if (mflags & MATCH_GLOBREP)
|
---|
| 4249 | + mflags |= MATCH_ANY;
|
---|
| 4250 | else if (pat && pat[0] == '#')
|
---|
| 4251 | {
|
---|
| 4252 | mflags |= MATCH_BEG;
|
---|
| 4253 | @@ -5798,12 +5857,16 @@
|
---|
| 4254 | #if defined (ARRAY_VARS)
|
---|
| 4255 | case VT_ARRAYVAR:
|
---|
| 4256 | temp = array_patsub (array_cell (v), p, rep, mflags);
|
---|
| 4257 | +#if 0
|
---|
| 4258 | + /* Don't need to do this anymore; array_patsub calls array_quote_escapes
|
---|
| 4259 | + as appropriate before adding the space separators. */
|
---|
| 4260 | if (temp && (mflags & MATCH_QUOTED) == 0)
|
---|
| 4261 | {
|
---|
| 4262 | tt = quote_escapes (temp);
|
---|
| 4263 | free (temp);
|
---|
| 4264 | temp = tt;
|
---|
| 4265 | }
|
---|
| 4266 | +#endif
|
---|
| 4267 | break;
|
---|
| 4268 | #endif
|
---|
| 4269 | }
|
---|
| 4270 | @@ -7607,6 +7670,8 @@
|
---|
| 4271 | expand_no_split_dollar_star = 0; /* XXX */
|
---|
| 4272 | expanding_redir = 0;
|
---|
| 4273 |
|
---|
| 4274 | + top_level_cleanup (); /* from sig.c */
|
---|
| 4275 | +
|
---|
| 4276 | jump_to_top_level (v);
|
---|
| 4277 | }
|
---|
| 4278 |
|
---|
| 4279 | @@ -7824,7 +7889,7 @@
|
---|
| 4280 | else if (fail_glob_expansion != 0)
|
---|
| 4281 | {
|
---|
| 4282 | report_error (_("no match: %s"), tlist->word->word);
|
---|
| 4283 | - jump_to_top_level (DISCARD);
|
---|
| 4284 | + exp_jump_to_top_level (DISCARD);
|
---|
| 4285 | }
|
---|
| 4286 | else if (allow_null_glob_expansion == 0)
|
---|
| 4287 | {
|
---|
| 4288 | diff -Naur bash-3.2.orig/subst.h bash-3.2/subst.h
|
---|
| 4289 | --- bash-3.2.orig/subst.h 2006-09-19 08:34:41.000000000 -0400
|
---|
| 4290 | +++ bash-3.2/subst.h 2007-12-20 23:53:04.000000000 -0500
|
---|
| 4291 | @@ -222,6 +222,7 @@
|
---|
| 4292 | extern char *command_substitute __P((char *, int));
|
---|
| 4293 | extern char *pat_subst __P((char *, char *, char *, int));
|
---|
| 4294 |
|
---|
| 4295 | +extern int fifos_pending __P((void));
|
---|
| 4296 | extern void unlink_fifo_list __P((void));
|
---|
| 4297 |
|
---|
| 4298 | extern WORD_LIST *list_string_with_quotes __P((char *));
|
---|
| 4299 | diff -Naur bash-3.2.orig/tests/new-exp.right bash-3.2/tests/new-exp.right
|
---|
| 4300 | --- bash-3.2.orig/tests/new-exp.right 2006-08-10 12:00:00.000000000 -0400
|
---|
| 4301 | +++ bash-3.2/tests/new-exp.right 2007-12-20 23:52:56.000000000 -0500
|
---|
| 4302 | @@ -430,7 +430,7 @@
|
---|
| 4303 | Case06---1---A B C::---
|
---|
| 4304 | Case07---3---A:B:C---
|
---|
| 4305 | Case08---3---A:B:C---
|
---|
| 4306 | -./new-exp.tests: line 506: /${$(($#-1))}: bad substitution
|
---|
| 4307 | +./new-exp.tests: line 506: ${$(($#-1))}: bad substitution
|
---|
| 4308 | argv[1] = <a>
|
---|
| 4309 | argv[2] = <b>
|
---|
| 4310 | argv[3] = <c>
|
---|
| 4311 | diff -Naur bash-3.2.orig/variables.c bash-3.2/variables.c
|
---|
| 4312 | --- bash-3.2.orig/variables.c 2006-09-08 13:33:32.000000000 -0400
|
---|
| 4313 | +++ bash-3.2/variables.c 2007-12-20 23:53:10.000000000 -0500
|
---|
| 4314 | @@ -1821,11 +1821,17 @@
|
---|
| 4315 | oval = value_cell (var);
|
---|
| 4316 | lval = evalexp (oval, &expok); /* ksh93 seems to do this */
|
---|
| 4317 | if (expok == 0)
|
---|
| 4318 | - jump_to_top_level (DISCARD);
|
---|
| 4319 | + {
|
---|
| 4320 | + top_level_cleanup ();
|
---|
| 4321 | + jump_to_top_level (DISCARD);
|
---|
| 4322 | + }
|
---|
| 4323 | }
|
---|
| 4324 | rval = evalexp (value, &expok);
|
---|
| 4325 | if (expok == 0)
|
---|
| 4326 | - jump_to_top_level (DISCARD);
|
---|
| 4327 | + {
|
---|
| 4328 | + top_level_cleanup ();
|
---|
| 4329 | + jump_to_top_level (DISCARD);
|
---|
| 4330 | + }
|
---|
| 4331 | if (flags & ASS_APPEND)
|
---|
| 4332 | rval += lval;
|
---|
| 4333 | retval = itos (rval);
|
---|
| 4334 | diff -Naur bash-3.2.orig/version.c bash-3.2/version.c
|
---|
| 4335 | --- bash-3.2.orig/version.c 2005-05-16 11:58:34.000000000 -0400
|
---|
| 4336 | +++ bash-3.2/version.c 2007-12-20 23:53:13.000000000 -0500
|
---|
| 4337 | @@ -79,5 +79,5 @@
|
---|
| 4338 | {
|
---|
| 4339 | printf ("GNU bash, version %s (%s)\n", shell_version_string (), MACHTYPE);
|
---|
| 4340 | if (extended)
|
---|
| 4341 | - printf (_("Copyright (C) 2005 Free Software Foundation, Inc.\n"));
|
---|
| 4342 | + printf (_("Copyright (C) 2007 Free Software Foundation, Inc.\n"));
|
---|
| 4343 | }
|
---|