source: clfs-sysroot/patches/bash-3.2-fixes-7.patch@ 12e747fb

Last change on this file since 12e747fb was e1234d4, checked in by Joe Ciccone <jciccone@…>, 16 years ago

First round of patches changes.

  • Property mode set to 100644
File size: 130.9 KB
RevLine 
[e1234d4]1Submitted By: Jim Gifford (jim at linuxfromscratch dot org)
2Date: 12-20-2007
3Initial Package Version: 3.2
4Origin: Upstream
5Upstream Status: Applied
6Description: Contains all upstream patches up to 3.2-033
7
8diff -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';
107diff -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));
118diff -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);
139diff -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"),
180diff -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 *));
227diff -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;
303diff -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
330diff -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
360diff -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
382diff -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
413diff -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);
454diff -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
482diff -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);
494diff -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. */
559diff -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);
571diff -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
774diff -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 */
3296diff -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));
3382diff -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;
3403diff -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 }
3415diff -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 }
3430diff -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
3463diff -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;
3593diff -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
3722diff -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,
3845diff -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_ */
3856diff -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')
3910diff -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
3929diff -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
3941diff -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 ()
3970diff -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
3981diff -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 {
4288diff -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 *));
4299diff -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>
4311diff -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);
4334diff -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 }
Note: See TracBrowser for help on using the repository browser.