source:
patches/bash-3.2-fixes-7.patch@
0417e7d
Last change on this file since 0417e7d was a60e4c5, checked in by , 17 years ago | |
---|---|
|
|
File size: 130.9 KB |
-
array.c
Submitted By: Jim Gifford (jim at linuxfromscratch dot org) Date: 12-20-2007 Initial Package Version: 3.2 Origin: Upstream Upstream Status: Applied Description: Contains all upstream patches up to 3.2-033 diff -Naur bash-3.2.orig/array.c bash-3.2/array.c
old new 120 120 return(a1); 121 121 } 122 122 123 #ifdef INCLUDE_UNUSED124 123 /* 125 124 * Make and return a new array composed of the elements in array A from 126 125 * S to E, inclusive. … … 141 140 for (p = s, i = 0; p != e; p = element_forw(p), i++) { 142 141 n = array_create_element (element_index(p), element_value(p)); 143 142 ADD_BEFORE(a->head, n); 144 mi = element_index( ae);143 mi = element_index(n); 145 144 } 146 145 a->num_elements = i; 147 146 a->max_index = mi; 148 147 return a; 149 148 } 150 #endif151 149 152 150 /* 153 151 * Walk the array, calling FUNC once for each element, with the array … … 300 298 return array; 301 299 } 302 300 301 ARRAY * 302 array_quote_escapes(array) 303 ARRAY *array; 304 { 305 ARRAY_ELEMENT *a; 306 char *t; 307 308 if (array == 0 || array_head(array) == 0 || array_empty(array)) 309 return (ARRAY *)NULL; 310 for (a = element_forw(array->head); a != array->head; a = element_forw(a)) { 311 t = quote_escapes (a->value); 312 FREE(a->value); 313 a->value = t; 314 } 315 return array; 316 } 317 303 318 /* 304 319 * Return a string whose elements are the members of array A beginning at 305 320 * index START and spanning NELEM members. Null elements are counted. … … 311 326 arrayind_t start, nelem; 312 327 int starsub, quoted; 313 328 { 329 ARRAY *a2; 314 330 ARRAY_ELEMENT *h, *p; 315 331 arrayind_t i; 316 char *ifs, sep[2] ;332 char *ifs, sep[2], *t; 317 333 318 334 p = a ? array_head (a) : 0; 319 335 if (p == 0 || array_empty (a) || start > array_max_index(a)) … … 336 352 for (i = 0, h = p; p != a->head && i < nelem; i++, p = element_forw(p)) 337 353 ; 338 354 355 a2 = array_slice(a, h, p); 356 357 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) 358 array_quote(a2); 359 else 360 array_quote_escapes(a2); 361 339 362 if (starsub && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) { 340 363 ifs = getifs(); 341 364 sep[0] = ifs ? *ifs : '\0'; … … 343 366 sep[0] = ' '; 344 367 sep[1] = '\0'; 345 368 346 return (array_to_string_internal (h, p, sep, quoted)); 369 t = array_to_string (a2, sep, 0); 370 array_dispose(a2); 371 372 return t; 347 373 } 348 374 349 375 char * … … 367 393 } 368 394 369 395 if (mflags & MATCH_QUOTED) 370 array_quote (a2); 396 array_quote(a2); 397 else 398 array_quote_escapes(a2); 371 399 if (mflags & MATCH_STARSUB) { 372 400 ifs = getifs(); 373 401 sifs[0] = ifs ? *ifs : '\0'; -
array.h
diff -Naur bash-3.2.orig/array.h bash-3.2/array.h
old new 55 55 extern ARRAY_ELEMENT *array_unshift_element __P((ARRAY *)); 56 56 extern int array_shift_element __P((ARRAY *, char *)); 57 57 extern ARRAY *array_quote __P((ARRAY *)); 58 extern ARRAY *array_quote_escapes __P((ARRAY *)); 58 59 59 60 extern char *array_subrange __P((ARRAY *, arrayind_t, arrayind_t, int, int)); 60 61 extern char *array_patsub __P((ARRAY *, char *, char *, int)); -
arrayfunc.c
diff -Naur bash-3.2.orig/arrayfunc.c bash-3.2/arrayfunc.c
old new 618 618 if (expok == 0) 619 619 { 620 620 last_command_exit_value = EXECUTION_FAILURE; 621 622 top_level_cleanup (); 621 623 jump_to_top_level (DISCARD); 622 624 } 623 625 return val; … … 720 722 if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']') 721 723 { 722 724 if (rtype) 723 *rtype = 1;725 *rtype = (t[0] == '*') ? 1 : 2; 724 726 if (allow_all == 0) 725 727 { 726 728 err_badarraysub (s); -
builtins/common.c
diff -Naur bash-3.2.orig/builtins/common.c bash-3.2/builtins/common.c
old new 1 /* Copyright (C) 1987-200 5Free Software Foundation, Inc.1 /* Copyright (C) 1987-2007 Free Software Foundation, Inc. 2 2 3 3 This file is part of GNU Bash, the Bourne Again SHell. 4 4 … … 131 131 if (list) 132 132 { 133 133 builtin_error (_("too many arguments")); 134 top_level_cleanup (); 134 135 jump_to_top_level (DISCARD); 135 136 } 136 137 } … … 395 396 if (fatal) 396 397 throw_to_top_level (); 397 398 else 398 jump_to_top_level (DISCARD); 399 { 400 top_level_cleanup (); 401 jump_to_top_level (DISCARD); 402 } 399 403 } 400 404 no_args (list->next); 401 405 } … … 475 479 476 480 if (the_current_working_directory == 0) 477 481 { 482 #if defined (GETCWD_BROKEN) 483 the_current_working_directory = getcwd (0, PATH_MAX); 484 #else 478 485 the_current_working_directory = getcwd (0, 0); 486 #endif 479 487 if (the_current_working_directory == 0) 480 488 { 481 489 fprintf (stderr, _("%s: error retrieving current directory: %s: %s\n"), -
builtins/printf.def
diff -Naur bash-3.2.orig/builtins/printf.def bash-3.2/builtins/printf.def
old new 1 1 This file is printf.def, from which is created printf.c. 2 2 It implements the builtin "printf" in Bash. 3 3 4 Copyright (C) 1997-200 5Free Software Foundation, Inc.4 Copyright (C) 1997-2007 Free Software Foundation, Inc. 5 5 6 6 This file is part of GNU Bash, the Bourne Again SHell. 7 7 … … 49 49 # define INT_MIN (-2147483647-1) 50 50 #endif 51 51 52 #if defined (PREFER_STDARG) 53 # include <stdarg.h> 54 #else 55 # include <varargs.h> 56 #endif 57 52 58 #include <stdio.h> 53 59 #include <chartypes.h> 54 60 … … 64 70 #include "bashgetopt.h" 65 71 #include "common.h" 66 72 73 #if defined (PRI_MACROS_BROKEN) 74 # undef PRIdMAX 75 #endif 76 67 77 #if !defined (PRIdMAX) 68 78 # if HAVE_LONG_LONG 69 79 # define PRIdMAX "lld" … … 151 161 #define SKIP1 "#'-+ 0" 152 162 #define LENMODS "hjlLtz" 153 163 164 #ifndef HAVE_ASPRINTF 165 extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3))); 166 #endif 167 154 168 static void printf_erange __P((char *)); 155 169 static int printstr __P((char *, char *, int, int, int)); 156 170 static int tescape __P((char *, char *, int *)); -
builtins/read.def
diff -Naur bash-3.2.orig/builtins/read.def bash-3.2/builtins/read.def
old new 127 127 WORD_LIST *list; 128 128 { 129 129 register char *varname; 130 int size, i, nr, pass_next, saw_escape, eof, opt, retval, code ;131 int input_is_tty, input_is_pipe, unbuffered_read ;130 int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2; 131 int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul; 132 132 int raw, edit, nchars, silent, have_timeout, fd; 133 133 unsigned int tmout; 134 134 intmax_t intval; 135 135 char c; 136 136 char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname; 137 char *e, *t, *t1 ;137 char *e, *t, *t1, *ps2; 138 138 struct stat tsb; 139 139 SHELL_VAR *var; 140 140 #if defined (ARRAY_VARS) … … 148 148 USE_VAR(size); 149 149 USE_VAR(i); 150 150 USE_VAR(pass_next); 151 USE_VAR(print_ps2); 151 152 USE_VAR(saw_escape); 152 153 USE_VAR(input_is_pipe); 153 154 /* USE_VAR(raw); */ … … 163 164 USE_VAR(rlind); 164 165 #endif 165 166 USE_VAR(list); 167 USE_VAR(ps2); 166 168 167 169 i = 0; /* Index into the string that we are reading. */ 168 170 raw = edit = 0; /* Not reading raw input by default. */ … … 386 388 setmode (0, O_TEXT); 387 389 #endif 388 390 389 for (eof = retval = 0;;) 391 ps2 = 0; 392 for (print_ps2 = eof = retval = 0;;) 390 393 { 391 394 #if defined (READLINE) 392 395 if (edit) … … 412 415 { 413 416 #endif 414 417 418 if (print_ps2) 419 { 420 if (ps2 == 0) 421 ps2 = get_string_value ("PS2"); 422 fprintf (stderr, "%s", ps2 ? ps2 : ""); 423 fflush (stderr); 424 print_ps2 = 0; 425 } 426 415 427 if (unbuffered_read) 416 428 retval = zread (fd, &c, 1); 417 429 else … … 440 452 { 441 453 pass_next = 0; 442 454 if (c == '\n') 443 i--; /* back up over the CTLESC */ 455 { 456 i--; /* back up over the CTLESC */ 457 if (interactive && input_is_tty && raw == 0) 458 print_ps2 = 1; 459 } 444 460 else 445 461 goto add_char; 446 462 continue; -
config-bot.h
diff -Naur bash-3.2.orig/config-bot.h bash-3.2/config-bot.h
old new 1 1 /* config-bot.h */ 2 2 /* modify settings or make new ones based on what autoconf tells us. */ 3 3 4 /* Copyright (C) 1989-200 2Free Software Foundation, Inc.4 /* Copyright (C) 1989-2007 Free Software Foundation, Inc. 5 5 6 6 This file is part of GNU Bash, the Bourne Again SHell. 7 7 … … 70 70 # define TERMIOS_MISSING 71 71 #endif 72 72 73 /* If we have a getcwd(3), but it calls popen(), #undef HAVE_GETCWD so 74 the replacement in getcwd.c will be built. */ 75 #if defined (HAVE_GETCWD) && defined (GETCWD_BROKEN) 73 /* If we have a getcwd(3), but one that does not dynamically allocate memory, 74 #undef HAVE_GETCWD so the replacement in getcwd.c will be built. We do 75 not do this on Solaris, because their implementation of loopback mounts 76 breaks the traditional file system assumptions that getcwd uses. */ 77 #if defined (HAVE_GETCWD) && defined (GETCWD_BROKEN) && !defined (SOLARIS) 76 78 # undef HAVE_GETCWD 77 79 #endif 78 80 -
config.h.in
diff -Naur bash-3.2.orig/config.h.in bash-3.2/config.h.in
old new 1 1 /* config.h -- Configuration file for bash. */ 2 2 3 /* Copyright (C) 1987-200 6Free Software Foundation, Inc.3 /* Copyright (C) 1987-2007 Free Software Foundation, Inc. 4 4 5 5 This file is part of GNU Bash, the Bourne Again SHell. 6 6 … … 413 413 414 414 #undef HAVE_DECL_STRTOLD 415 415 416 #undef PRI_MACROS_BROKEN 417 416 418 #undef STRTOLD_BROKEN 417 419 418 420 /* Define if WCONTINUED is defined in system headers, but rejected by waitpid */ … … 1006 1008 /* Define if you have the `dcgettext' function. */ 1007 1009 #undef HAVE_DCGETTEXT 1008 1010 1011 /* Define if you have the `localeconv' function. */ 1012 #undef HAVE_LOCALECONV 1013 1009 1014 /* Define if your system has a working `malloc' function. */ 1010 1015 /* #undef HAVE_MALLOC */ 1011 1016 -
configure
diff -Naur bash-3.2.orig/configure bash-3.2/configure
old new 4871 4871 # static version specified as -llibname to override the 4872 4872 # dynamic version 4873 4873 case "${host_os}" in 4874 darwin 8*) READLINE_LIB='${READLINE_LIBRARY}' ;;4874 darwin[89]*) READLINE_LIB='${READLINE_LIBRARY}' ;; 4875 4875 *) READLINE_LIB=-lreadline ;; 4876 4876 esac 4877 4877 fi … … 27316 27316 sco3.2v4*) LOCAL_CFLAGS="-DMUST_UNBLOCK_CHLD -DPATH_MAX=1024" ;; 27317 27317 sco3.2*) LOCAL_CFLAGS=-DMUST_UNBLOCK_CHLD ;; 27318 27318 sunos4*) LOCAL_CFLAGS=-DSunOS4 ;; 27319 solaris2.5*) LOCAL_CFLAGS=-DSunOS5 ;; 27319 solaris2.5*) LOCAL_CFLAGS="-DSunOS5 -DSOLARIS" ;; 27320 solaris2*) LOCAL_CFLAGS=-DSOLARIS ;; 27320 27321 lynxos*) LOCAL_CFLAGS=-DRECYCLES_PIDS ;; 27321 27322 linux*) LOCAL_LDFLAGS=-rdynamic # allow dynamic loading 27322 27323 case "`uname -r`" in -
configure.in
diff -Naur bash-3.2.orig/configure.in bash-3.2/configure.in
old new 5 5 dnl 6 6 dnl Process this file with autoconf to produce a configure script. 7 7 8 # Copyright (C) 1987-200 6Free Software Foundation, Inc.8 # Copyright (C) 1987-2007 Free Software Foundation, Inc. 9 9 10 10 # This program is free software; you can redistribute it and/or modify 11 11 # it under the terms of the GNU General Public License as published by … … 518 518 # static version specified as -llibname to override the 519 519 # dynamic version 520 520 case "${host_os}" in 521 darwin 8*) READLINE_LIB='${READLINE_LIBRARY}' ;;521 darwin[[89]]*) READLINE_LIB='${READLINE_LIBRARY}' ;; 522 522 *) READLINE_LIB=-lreadline ;; 523 523 esac 524 524 fi … … 991 991 sco3.2v4*) LOCAL_CFLAGS="-DMUST_UNBLOCK_CHLD -DPATH_MAX=1024" ;; 992 992 sco3.2*) LOCAL_CFLAGS=-DMUST_UNBLOCK_CHLD ;; 993 993 sunos4*) LOCAL_CFLAGS=-DSunOS4 ;; 994 solaris2.5*) LOCAL_CFLAGS=-DSunOS5 ;; 994 solaris2.5*) LOCAL_CFLAGS="-DSunOS5 -DSOLARIS" ;; 995 solaris2*) LOCAL_CFLAGS=-DSOLARIS ;; 995 996 lynxos*) LOCAL_CFLAGS=-DRECYCLES_PIDS ;; 996 997 linux*) LOCAL_LDFLAGS=-rdynamic # allow dynamic loading 997 998 case "`uname -r`" in -
execute_cmd.c
diff -Naur bash-3.2.orig/execute_cmd.c bash-3.2/execute_cmd.c
old new 1 1 /* execute_cmd.c -- Execute a COMMAND structure. */ 2 2 3 /* Copyright (C) 1987-200 5Free Software Foundation, Inc.3 /* Copyright (C) 1987-2007 Free Software Foundation, Inc. 4 4 5 5 This file is part of GNU Bash, the Bourne Again SHell. 6 6 … … 614 614 cleanup_redirects (redirection_undo_list); 615 615 redirection_undo_list = (REDIRECT *)NULL; 616 616 dispose_exec_redirects (); 617 return ( EXECUTION_FAILURE);617 return (last_command_exit_value = EXECUTION_FAILURE); 618 618 } 619 619 620 620 if (redirection_undo_list) … … 2546 2546 arg1 = cond_expand_word (cond->left->op, 0); 2547 2547 if (arg1 == 0) 2548 2548 arg1 = nullstr; 2549 arg2 = cond_expand_word (cond->right->op, patmatch||rmatch);2549 arg2 = cond_expand_word (cond->right->op, rmatch ? 2 : (patmatch ? 1 : 0)); 2550 2550 if (arg2 == 0) 2551 2551 arg2 = nullstr; 2552 2552 … … 3050 3050 if (command_line == 0) 3051 3051 command_line = savestring (the_printed_command_except_trap); 3052 3052 3053 #if defined (PROCESS_SUBSTITUTION) 3054 if ((subshell_environment & SUBSHELL_COMSUB) && (simple_command->flags & CMD_NO_FORK) && fifos_pending() > 0) 3055 simple_command->flags &= ~CMD_NO_FORK; 3056 #endif 3057 3053 3058 execute_disk_command (words, simple_command->redirects, command_line, 3054 3059 pipe_in, pipe_out, async, fds_to_close, 3055 3060 simple_command->flags); -
bash-3.2
diff -Naur bash-3.2.orig/expr.c bash-3.2/expr.c
old new 286 286 free (expr_stack[expr_depth]); 287 287 } 288 288 free (expr_stack[expr_depth]); /* free the allocated EXPR_CONTEXT */ 289 290 noeval = 0; /* XXX */ 289 291 } 290 292 291 293 static void … … 319 321 procenv_t oevalbuf; 320 322 321 323 val = 0; 324 noeval = 0; 322 325 323 326 FASTCOPY (evalbuf, oevalbuf, sizeof (evalbuf)); 324 327 … … 929 932 if (interactive_shell) 930 933 { 931 934 expr_unwind (); 935 top_level_cleanup (); 932 936 jump_to_top_level (DISCARD); 933 937 } 934 938 else -
findcmd.c
diff -Naur bash-3.2.orig/findcmd.c bash-3.2/findcmd.c
old new 308 308 if (hashed_file && (posixly_correct || check_hashed_filenames)) 309 309 { 310 310 st = file_status (hashed_file); 311 if ((st ^ (FS_EXISTS | FS_EXECABLE)) != 0)311 if ((st & (FS_EXISTS|FS_EXECABLE)) != (FS_EXISTS|FS_EXECABLE)) 312 312 { 313 313 phash_remove (pathname); 314 314 free (hashed_file); -
bash-3.2
diff -Naur bash-3.2.orig/jobs.c bash-3.2/jobs.c
old new 783 783 if (jobs[js.j_firstj] == 0) 784 784 { 785 785 old = js.j_firstj++; 786 if (old >= js.j_jobslots) 787 old = js.j_jobslots - 1; 786 788 while (js.j_firstj != old) 787 789 { 788 790 if (js.j_firstj >= js.j_jobslots) 789 791 js.j_firstj = 0; 790 if (jobs[js.j_firstj] )792 if (jobs[js.j_firstj] || js.j_firstj == old) /* needed if old == 0 */ 791 793 break; 792 794 js.j_firstj++; 793 795 } … … 797 799 if (jobs[js.j_lastj] == 0) 798 800 { 799 801 old = js.j_lastj--; 802 if (old < 0) 803 old = 0; 800 804 while (js.j_lastj != old) 801 805 { 802 806 if (js.j_lastj < 0) 803 807 js.j_lastj = js.j_jobslots - 1; 804 if (jobs[js.j_lastj] )808 if (jobs[js.j_lastj] || js.j_lastj == old) /* needed if old == js.j_jobslots */ 805 809 break; 806 810 js.j_lastj--; 807 811 } … … 963 967 reap_dead_jobs (); 964 968 realloc_jobs_list (); 965 969 966 return (js.j_lastj); 970 #ifdef DEBUG 971 itrace("compact_jobs_list: returning %d", (js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0); 972 #endif 973 974 return ((js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0); 967 975 } 968 976 969 977 /* Delete the job at INDEX from the job list. Must be called … … 984 992 temp = jobs[job_index]; 985 993 if (temp == 0) 986 994 return; 987 if (job_index == js.j_current || job_index == js.j_previous)988 reset_current ();989 995 990 996 if ((dflags & DEL_NOBGPID) == 0) 991 997 { … … 1028 1034 js.j_firstj = js.j_lastj = 0; 1029 1035 else if (jobs[js.j_firstj] == 0 || jobs[js.j_lastj] == 0) 1030 1036 reset_job_indices (); 1037 1038 if (job_index == js.j_current || job_index == js.j_previous) 1039 reset_current (); 1031 1040 } 1032 1041 1033 1042 /* Must be called with SIGCHLD blocked. */ -
lib/readline/complete.c
diff -Naur bash-3.2.orig/lib/readline/complete.c bash-3.2/lib/readline/complete.c
old new 428 428 return (1); 429 429 if (c == 'n' || c == 'N' || c == RUBOUT) 430 430 return (0); 431 if (c == ABORT_CHAR )431 if (c == ABORT_CHAR || c < 0) 432 432 _rl_abort_internal (); 433 433 if (for_pager && (c == NEWLINE || c == RETURN)) 434 434 return (2); -
lib/readline/display.c
diff -Naur bash-3.2.orig/lib/readline/display.c bash-3.2/lib/readline/display.c
old new 391 391 t = ++p; 392 392 local_prompt = expand_prompt (p, &prompt_visible_length, 393 393 &prompt_last_invisible, 394 (int *)NULL,394 &prompt_invis_chars_first_line, 395 395 &prompt_physical_chars); 396 396 c = *t; *t = '\0'; 397 397 /* The portion of the prompt string up to and including the 398 398 final newline is now null-terminated. */ 399 399 local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length, 400 400 (int *)NULL, 401 &prompt_invis_chars_first_line,401 (int *)NULL, 402 402 (int *)NULL); 403 403 *t = c; 404 404 local_prompt_len = local_prompt ? strlen (local_prompt) : 0; … … 561 561 wrap_offset = prompt_invis_chars_first_line = 0; 562 562 } 563 563 564 #if defined (HANDLE_MULTIBYTE) 565 #define CHECK_INV_LBREAKS() \ 566 do { \ 567 if (newlines >= (inv_lbsize - 2)) \ 568 { \ 569 inv_lbsize *= 2; \ 570 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ 571 _rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \ 572 } \ 573 } while (0) 574 #else 564 575 #define CHECK_INV_LBREAKS() \ 565 576 do { \ 566 577 if (newlines >= (inv_lbsize - 2)) \ … … 569 580 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ 570 581 } \ 571 582 } while (0) 583 #endif /* HANDLE_MULTIBYTE */ 572 584 573 585 #if defined (HANDLE_MULTIBYTE) 574 586 #define CHECK_LPOS() \ … … 1036 1048 tx = _rl_col_width (&visible_line[pos], 0, nleft) - visible_wrap_offset; 1037 1049 else 1038 1050 tx = nleft; 1039 if ( _rl_last_c_pos > tx)1051 if (tx >= 0 && _rl_last_c_pos > tx) 1040 1052 { 1041 1053 _rl_backspace (_rl_last_c_pos - tx); /* XXX */ 1042 1054 _rl_last_c_pos = tx; … … 1192 1204 int current_line, omax, nmax, inv_botlin; 1193 1205 { 1194 1206 register char *ofd, *ols, *oe, *nfd, *nls, *ne; 1195 int temp, lendiff, wsatend, od, nd ;1207 int temp, lendiff, wsatend, od, nd, o_cpos; 1196 1208 int current_invis_chars; 1197 1209 int col_lendiff, col_temp; 1198 1210 #if defined (HANDLE_MULTIBYTE) … … 1453 1465 _rl_last_c_pos = lendiff; 1454 1466 } 1455 1467 1468 o_cpos = _rl_last_c_pos; 1469 1456 1470 /* When this function returns, _rl_last_c_pos is correct, and an absolute 1457 1471 cursor postion in multibyte mode, but a buffer index when not in a 1458 1472 multibyte locale. */ … … 1462 1476 /* We need to indicate that the cursor position is correct in the presence of 1463 1477 invisible characters in the prompt string. Let's see if setting this when 1464 1478 we make sure we're at the end of the drawn prompt string works. */ 1465 if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 && _rl_last_c_pos == prompt_physical_chars) 1479 if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 && 1480 (_rl_last_c_pos > 0 || o_cpos > 0) && 1481 _rl_last_c_pos == prompt_physical_chars) 1466 1482 cpos_adjusted = 1; 1467 1483 #endif 1468 1484 #endif … … 1506 1522 { 1507 1523 /* Non-zero if we're increasing the number of lines. */ 1508 1524 int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin; 1525 /* If col_lendiff is > 0, implying that the new string takes up more 1526 screen real estate than the old, but lendiff is < 0, meaning that it 1527 takes fewer bytes, we need to just output the characters starting 1528 from the first difference. These will overwrite what is on the 1529 display, so there's no reason to do a smart update. This can really 1530 only happen in a multibyte environment. */ 1531 if (lendiff < 0) 1532 { 1533 _rl_output_some_chars (nfd, temp); 1534 _rl_last_c_pos += _rl_col_width (nfd, 0, temp); 1535 /* If nfd begins before any invisible characters in the prompt, 1536 adjust _rl_last_c_pos to account for wrap_offset and set 1537 cpos_adjusted to let the caller know. */ 1538 if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible)) 1539 { 1540 _rl_last_c_pos -= wrap_offset; 1541 cpos_adjusted = 1; 1542 } 1543 return; 1544 } 1509 1545 /* Sometimes it is cheaper to print the characters rather than 1510 1546 use the terminal's capabilities. If we're growing the number 1511 1547 of lines, make sure we actually cause the new line to wrap 1512 1548 around on auto-wrapping terminals. */ 1513 if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))1549 else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl)) 1514 1550 { 1515 1551 /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and 1516 1552 _rl_horizontal_scroll_mode == 1, inserting the characters with … … 1533 1569 } 1534 1570 else 1535 1571 { 1536 /* We have horizontal scrolling and we are not inserting at1537 the end. We have invisible characters in this line. This1538 is a dumb update. */1539 1572 _rl_output_some_chars (nfd, temp); 1540 1573 _rl_last_c_pos += col_temp; 1574 /* If nfd begins before any invisible characters in the prompt, 1575 adjust _rl_last_c_pos to account for wrap_offset and set 1576 cpos_adjusted to let the caller know. */ 1577 if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible)) 1578 { 1579 _rl_last_c_pos -= wrap_offset; 1580 cpos_adjusted = 1; 1581 } 1541 1582 return; 1542 1583 } 1543 1584 /* Copy (new) chars to screen from first diff to last match. */ … … 1586 1627 temp = nls - nfd; 1587 1628 if (temp > 0) 1588 1629 { 1630 /* If nfd begins at the prompt, or before the invisible 1631 characters in the prompt, we need to adjust _rl_last_c_pos 1632 in a multibyte locale to account for the wrap offset and 1633 set cpos_adjusted accordingly. */ 1589 1634 _rl_output_some_chars (nfd, temp); 1590 _rl_last_c_pos += _rl_col_width (nfd, 0, temp);; 1635 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1636 { 1637 _rl_last_c_pos += _rl_col_width (nfd, 0, temp); 1638 if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible)) 1639 { 1640 _rl_last_c_pos -= wrap_offset; 1641 cpos_adjusted = 1; 1642 } 1643 } 1644 else 1645 _rl_last_c_pos += temp; 1591 1646 } 1592 1647 } 1593 1648 /* Otherwise, print over the existing material. */ … … 1595 1650 { 1596 1651 if (temp > 0) 1597 1652 { 1653 /* If nfd begins at the prompt, or before the invisible 1654 characters in the prompt, we need to adjust _rl_last_c_pos 1655 in a multibyte locale to account for the wrap offset and 1656 set cpos_adjusted accordingly. */ 1598 1657 _rl_output_some_chars (nfd, temp); 1599 1658 _rl_last_c_pos += col_temp; /* XXX */ 1659 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1660 { 1661 if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible)) 1662 { 1663 _rl_last_c_pos -= wrap_offset; 1664 cpos_adjusted = 1; 1665 } 1666 } 1600 1667 } 1601 1668 lendiff = (oe - old) - (ne - new); 1602 1669 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) … … 1732 1799 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1733 1800 { 1734 1801 dpos = _rl_col_width (data, 0, new); 1735 if (dpos > prompt_last_invisible) /* XXX - don't use woff here */ 1802 /* Use NEW when comparing against the last invisible character in the 1803 prompt string, since they're both buffer indices and DPOS is a 1804 desired display position. */ 1805 if (new > prompt_last_invisible) /* XXX - don't use woff here */ 1736 1806 { 1737 1807 dpos -= woff; 1738 1808 /* Since this will be assigned to _rl_last_c_pos at the end (more … … 2380 2450 2381 2451 if (end <= start) 2382 2452 return 0; 2453 if (MB_CUR_MAX == 1 || rl_byte_oriented) 2454 return (end - start); 2383 2455 2384 2456 memset (&ps, 0, sizeof (mbstate_t)); 2385 2457 -
lib/readline/display.c.orig
diff -Naur bash-3.2.orig/lib/readline/display.c.orig bash-3.2/lib/readline/display.c.orig
old new 1 /* display.c -- readline redisplay facility. */ 2 3 /* Copyright (C) 1987-2006 Free Software Foundation, Inc. 4 5 This file is part of the GNU Readline Library, a library for 6 reading lines of text with interactive input and history editing. 7 8 The GNU Readline Library is free software; you can redistribute it 9 and/or modify it under the terms of the GNU General Public License 10 as published by the Free Software Foundation; either version 2, or 11 (at your option) any later version. 12 13 The GNU Readline Library is distributed in the hope that it will be 14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty 15 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 The GNU General Public License is often shipped with GNU software, and 19 is generally kept in a file called COPYING or LICENSE. If you do not 20 have a copy of the license, write to the Free Software Foundation, 21 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ 22 #define READLINE_LIBRARY 23 24 #if defined (HAVE_CONFIG_H) 25 # include <config.h> 26 #endif 27 28 #include <sys/types.h> 29 30 #if defined (HAVE_UNISTD_H) 31 # include <unistd.h> 32 #endif /* HAVE_UNISTD_H */ 33 34 #include "posixstat.h" 35 36 #if defined (HAVE_STDLIB_H) 37 # include <stdlib.h> 38 #else 39 # include "ansi_stdlib.h" 40 #endif /* HAVE_STDLIB_H */ 41 42 #include <stdio.h> 43 44 /* System-specific feature definitions and include files. */ 45 #include "rldefs.h" 46 #include "rlmbutil.h" 47 48 /* Termcap library stuff. */ 49 #include "tcap.h" 50 51 /* Some standard library routines. */ 52 #include "readline.h" 53 #include "history.h" 54 55 #include "rlprivate.h" 56 #include "xmalloc.h" 57 58 #if !defined (strchr) && !defined (__STDC__) 59 extern char *strchr (), *strrchr (); 60 #endif /* !strchr && !__STDC__ */ 61 62 static void update_line PARAMS((char *, char *, int, int, int, int)); 63 static void space_to_eol PARAMS((int)); 64 static void delete_chars PARAMS((int)); 65 static void insert_some_chars PARAMS((char *, int, int)); 66 static void cr PARAMS((void)); 67 68 #if defined (HANDLE_MULTIBYTE) 69 static int _rl_col_width PARAMS((const char *, int, int)); 70 static int *_rl_wrapped_line; 71 #else 72 # define _rl_col_width(l, s, e) (((e) <= (s)) ? 0 : (e) - (s)) 73 #endif 74 75 static int *inv_lbreaks, *vis_lbreaks; 76 static int inv_lbsize, vis_lbsize; 77 78 /* Heuristic used to decide whether it is faster to move from CUR to NEW 79 by backing up or outputting a carriage return and moving forward. CUR 80 and NEW are either both buffer positions or absolute screen positions. */ 81 #define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new))) 82 83 /* _rl_last_c_pos is an absolute cursor position in multibyte locales and a 84 buffer index in others. This macro is used when deciding whether the 85 current cursor position is in the middle of a prompt string containing 86 invisible characters. */ 87 #define PROMPT_ENDING_INDEX \ 88 ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1) 89 90 91 /* **************************************************************** */ 92 /* */ 93 /* Display stuff */ 94 /* */ 95 /* **************************************************************** */ 96 97 /* This is the stuff that is hard for me. I never seem to write good 98 display routines in C. Let's see how I do this time. */ 99 100 /* (PWP) Well... Good for a simple line updater, but totally ignores 101 the problems of input lines longer than the screen width. 102 103 update_line and the code that calls it makes a multiple line, 104 automatically wrapping line update. Careful attention needs 105 to be paid to the vertical position variables. */ 106 107 /* Keep two buffers; one which reflects the current contents of the 108 screen, and the other to draw what we think the new contents should 109 be. Then compare the buffers, and make whatever changes to the 110 screen itself that we should. Finally, make the buffer that we 111 just drew into be the one which reflects the current contents of the 112 screen, and place the cursor where it belongs. 113 114 Commands that want to can fix the display themselves, and then let 115 this function know that the display has been fixed by setting the 116 RL_DISPLAY_FIXED variable. This is good for efficiency. */ 117 118 /* Application-specific redisplay function. */ 119 rl_voidfunc_t *rl_redisplay_function = rl_redisplay; 120 121 /* Global variables declared here. */ 122 /* What YOU turn on when you have handled all redisplay yourself. */ 123 int rl_display_fixed = 0; 124 125 int _rl_suppress_redisplay = 0; 126 int _rl_want_redisplay = 0; 127 128 /* The stuff that gets printed out before the actual text of the line. 129 This is usually pointing to rl_prompt. */ 130 char *rl_display_prompt = (char *)NULL; 131 132 /* Pseudo-global variables declared here. */ 133 134 /* The visible cursor position. If you print some text, adjust this. */ 135 /* NOTE: _rl_last_c_pos is used as a buffer index when not in a locale 136 supporting multibyte characters, and an absolute cursor position when 137 in such a locale. This is an artifact of the donated multibyte support. 138 Care must be taken when modifying its value. */ 139 int _rl_last_c_pos = 0; 140 int _rl_last_v_pos = 0; 141 142 static int cpos_adjusted; 143 static int cpos_buffer_position; 144 145 /* Number of lines currently on screen minus 1. */ 146 int _rl_vis_botlin = 0; 147 148 /* Variables used only in this file. */ 149 /* The last left edge of text that was displayed. This is used when 150 doing horizontal scrolling. It shifts in thirds of a screenwidth. */ 151 static int last_lmargin; 152 153 /* The line display buffers. One is the line currently displayed on 154 the screen. The other is the line about to be displayed. */ 155 static char *visible_line = (char *)NULL; 156 static char *invisible_line = (char *)NULL; 157 158 /* A buffer for `modeline' messages. */ 159 static char msg_buf[128]; 160 161 /* Non-zero forces the redisplay even if we thought it was unnecessary. */ 162 static int forced_display; 163 164 /* Default and initial buffer size. Can grow. */ 165 static int line_size = 1024; 166 167 /* Variables to keep track of the expanded prompt string, which may 168 include invisible characters. */ 169 170 static char *local_prompt, *local_prompt_prefix; 171 static int local_prompt_len; 172 static int prompt_visible_length, prompt_prefix_length; 173 174 /* The number of invisible characters in the line currently being 175 displayed on the screen. */ 176 static int visible_wrap_offset; 177 178 /* The number of invisible characters in the prompt string. Static so it 179 can be shared between rl_redisplay and update_line */ 180 static int wrap_offset; 181 182 /* The index of the last invisible character in the prompt string. */ 183 static int prompt_last_invisible; 184 185 /* The length (buffer offset) of the first line of the last (possibly 186 multi-line) buffer displayed on the screen. */ 187 static int visible_first_line_len; 188 189 /* Number of invisible characters on the first physical line of the prompt. 190 Only valid when the number of physical characters in the prompt exceeds 191 (or is equal to) _rl_screenwidth. */ 192 static int prompt_invis_chars_first_line; 193 194 static int prompt_last_screen_line; 195 196 static int prompt_physical_chars; 197 198 /* Variables to save and restore prompt and display information. */ 199 200 /* These are getting numerous enough that it's time to create a struct. */ 201 202 static char *saved_local_prompt; 203 static char *saved_local_prefix; 204 static int saved_last_invisible; 205 static int saved_visible_length; 206 static int saved_prefix_length; 207 static int saved_local_length; 208 static int saved_invis_chars_first_line; 209 static int saved_physical_chars; 210 211 /* Expand the prompt string S and return the number of visible 212 characters in *LP, if LP is not null. This is currently more-or-less 213 a placeholder for expansion. LIP, if non-null is a place to store the 214 index of the last invisible character in the returned string. NIFLP, 215 if non-zero, is a place to store the number of invisible characters in 216 the first prompt line. The previous are used as byte counts -- indexes 217 into a character buffer. */ 218 219 /* Current implementation: 220 \001 (^A) start non-visible characters 221 \002 (^B) end non-visible characters 222 all characters except \001 and \002 (following a \001) are copied to 223 the returned string; all characters except those between \001 and 224 \002 are assumed to be `visible'. */ 225 226 static char * 227 expand_prompt (pmt, lp, lip, niflp, vlp) 228 char *pmt; 229 int *lp, *lip, *niflp, *vlp; 230 { 231 char *r, *ret, *p, *igstart; 232 int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars; 233 234 /* Short-circuit if we can. */ 235 if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0) 236 { 237 r = savestring (pmt); 238 if (lp) 239 *lp = strlen (r); 240 if (lip) 241 *lip = 0; 242 if (niflp) 243 *niflp = 0; 244 if (vlp) 245 *vlp = lp ? *lp : strlen (r); 246 return r; 247 } 248 249 l = strlen (pmt); 250 r = ret = (char *)xmalloc (l + 1); 251 252 invfl = 0; /* invisible chars in first line of prompt */ 253 invflset = 0; /* we only want to set invfl once */ 254 255 igstart = 0; 256 for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++) 257 { 258 /* This code strips the invisible character string markers 259 RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */ 260 if (ignoring == 0 && *p == RL_PROMPT_START_IGNORE) /* XXX - check ignoring? */ 261 { 262 ignoring = 1; 263 igstart = p; 264 continue; 265 } 266 else if (ignoring && *p == RL_PROMPT_END_IGNORE) 267 { 268 ignoring = 0; 269 if (p != (igstart + 1)) 270 last = r - ret - 1; 271 continue; 272 } 273 else 274 { 275 #if defined (HANDLE_MULTIBYTE) 276 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 277 { 278 pind = p - pmt; 279 ind = _rl_find_next_mbchar (pmt, pind, 1, MB_FIND_NONZERO); 280 l = ind - pind; 281 while (l--) 282 *r++ = *p++; 283 if (!ignoring) 284 { 285 rl += ind - pind; 286 physchars += _rl_col_width (pmt, pind, ind); 287 } 288 else 289 ninvis += ind - pind; 290 p--; /* compensate for later increment */ 291 } 292 else 293 #endif 294 { 295 *r++ = *p; 296 if (!ignoring) 297 { 298 rl++; /* visible length byte counter */ 299 physchars++; 300 } 301 else 302 ninvis++; /* invisible chars byte counter */ 303 } 304 305 if (invflset == 0 && rl >= _rl_screenwidth) 306 { 307 invfl = ninvis; 308 invflset = 1; 309 } 310 } 311 } 312 313 if (rl < _rl_screenwidth) 314 invfl = ninvis; 315 316 *r = '\0'; 317 if (lp) 318 *lp = rl; 319 if (lip) 320 *lip = last; 321 if (niflp) 322 *niflp = invfl; 323 if (vlp) 324 *vlp = physchars; 325 return ret; 326 } 327 328 /* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from 329 PMT and return the rest of PMT. */ 330 char * 331 _rl_strip_prompt (pmt) 332 char *pmt; 333 { 334 char *ret; 335 336 ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL); 337 return ret; 338 } 339 340 /* 341 * Expand the prompt string into the various display components, if 342 * necessary. 343 * 344 * local_prompt = expanded last line of string in rl_display_prompt 345 * (portion after the final newline) 346 * local_prompt_prefix = portion before last newline of rl_display_prompt, 347 * expanded via expand_prompt 348 * prompt_visible_length = number of visible characters in local_prompt 349 * prompt_prefix_length = number of visible characters in local_prompt_prefix 350 * 351 * This function is called once per call to readline(). It may also be 352 * called arbitrarily to expand the primary prompt. 353 * 354 * The return value is the number of visible characters on the last line 355 * of the (possibly multi-line) prompt. 356 */ 357 int 358 rl_expand_prompt (prompt) 359 char *prompt; 360 { 361 char *p, *t; 362 int c; 363 364 /* Clear out any saved values. */ 365 FREE (local_prompt); 366 FREE (local_prompt_prefix); 367 368 local_prompt = local_prompt_prefix = (char *)0; 369 local_prompt_len = 0; 370 prompt_last_invisible = prompt_invis_chars_first_line = 0; 371 prompt_visible_length = prompt_physical_chars = 0; 372 373 if (prompt == 0 || *prompt == 0) 374 return (0); 375 376 p = strrchr (prompt, '\n'); 377 if (!p) 378 { 379 /* The prompt is only one logical line, though it might wrap. */ 380 local_prompt = expand_prompt (prompt, &prompt_visible_length, 381 &prompt_last_invisible, 382 &prompt_invis_chars_first_line, 383 &prompt_physical_chars); 384 local_prompt_prefix = (char *)0; 385 local_prompt_len = local_prompt ? strlen (local_prompt) : 0; 386 return (prompt_visible_length); 387 } 388 else 389 { 390 /* The prompt spans multiple lines. */ 391 t = ++p; 392 local_prompt = expand_prompt (p, &prompt_visible_length, 393 &prompt_last_invisible, 394 &prompt_invis_chars_first_line, 395 &prompt_physical_chars); 396 c = *t; *t = '\0'; 397 /* The portion of the prompt string up to and including the 398 final newline is now null-terminated. */ 399 local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length, 400 (int *)NULL, 401 (int *)NULL, 402 (int *)NULL); 403 *t = c; 404 local_prompt_len = local_prompt ? strlen (local_prompt) : 0; 405 return (prompt_prefix_length); 406 } 407 } 408 409 /* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated 410 arrays of line break markers. MINSIZE is the minimum size of VISIBLE_LINE 411 and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is 412 increased. If the lines have already been allocated, this ensures that 413 they can hold at least MINSIZE characters. */ 414 static void 415 init_line_structures (minsize) 416 int minsize; 417 { 418 register int n; 419 420 if (invisible_line == 0) /* initialize it */ 421 { 422 if (line_size < minsize) 423 line_size = minsize; 424 visible_line = (char *)xmalloc (line_size); 425 invisible_line = (char *)xmalloc (line_size); 426 } 427 else if (line_size < minsize) /* ensure it can hold MINSIZE chars */ 428 { 429 line_size *= 2; 430 if (line_size < minsize) 431 line_size = minsize; 432 visible_line = (char *)xrealloc (visible_line, line_size); 433 invisible_line = (char *)xrealloc (invisible_line, line_size); 434 } 435 436 for (n = minsize; n < line_size; n++) 437 { 438 visible_line[n] = 0; 439 invisible_line[n] = 1; 440 } 441 442 if (vis_lbreaks == 0) 443 { 444 /* should be enough. */ 445 inv_lbsize = vis_lbsize = 256; 446 inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int)); 447 vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int)); 448 #if defined (HANDLE_MULTIBYTE) 449 _rl_wrapped_line = (int *)xmalloc (vis_lbsize * sizeof (int)); 450 #endif 451 inv_lbreaks[0] = vis_lbreaks[0] = 0; 452 } 453 } 454 455 /* Basic redisplay algorithm. */ 456 void 457 rl_redisplay () 458 { 459 register int in, out, c, linenum, cursor_linenum; 460 register char *line; 461 int inv_botlin, lb_botlin, lb_linenum, o_cpos; 462 int newlines, lpos, temp, modmark, n0, num; 463 char *prompt_this_line; 464 #if defined (HANDLE_MULTIBYTE) 465 wchar_t wc; 466 size_t wc_bytes; 467 int wc_width; 468 mbstate_t ps; 469 int _rl_wrapped_multicolumn = 0; 470 #endif 471 472 if (!readline_echoing_p) 473 return; 474 475 if (!rl_display_prompt) 476 rl_display_prompt = ""; 477 478 if (invisible_line == 0 || vis_lbreaks == 0) 479 { 480 init_line_structures (0); 481 rl_on_new_line (); 482 } 483 484 /* Draw the line into the buffer. */ 485 cpos_buffer_position = -1; 486 487 line = invisible_line; 488 out = inv_botlin = 0; 489 490 /* Mark the line as modified or not. We only do this for history 491 lines. */ 492 modmark = 0; 493 if (_rl_mark_modified_lines && current_history () && rl_undo_list) 494 { 495 line[out++] = '*'; 496 line[out] = '\0'; 497 modmark = 1; 498 } 499 500 /* If someone thought that the redisplay was handled, but the currently 501 visible line has a different modification state than the one about 502 to become visible, then correct the caller's misconception. */ 503 if (visible_line[0] != invisible_line[0]) 504 rl_display_fixed = 0; 505 506 /* If the prompt to be displayed is the `primary' readline prompt (the 507 one passed to readline()), use the values we have already expanded. 508 If not, use what's already in rl_display_prompt. WRAP_OFFSET is the 509 number of non-visible characters in the prompt string. */ 510 if (rl_display_prompt == rl_prompt || local_prompt) 511 { 512 if (local_prompt_prefix && forced_display) 513 _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix)); 514 515 if (local_prompt_len > 0) 516 { 517 temp = local_prompt_len + out + 2; 518 if (temp >= line_size) 519 { 520 line_size = (temp + 1024) - (temp % 1024); 521 visible_line = (char *)xrealloc (visible_line, line_size); 522 line = invisible_line = (char *)xrealloc (invisible_line, line_size); 523 } 524 strncpy (line + out, local_prompt, local_prompt_len); 525 out += local_prompt_len; 526 } 527 line[out] = '\0'; 528 wrap_offset = local_prompt_len - prompt_visible_length; 529 } 530 else 531 { 532 int pmtlen; 533 prompt_this_line = strrchr (rl_display_prompt, '\n'); 534 if (!prompt_this_line) 535 prompt_this_line = rl_display_prompt; 536 else 537 { 538 prompt_this_line++; 539 pmtlen = prompt_this_line - rl_display_prompt; /* temp var */ 540 if (forced_display) 541 { 542 _rl_output_some_chars (rl_display_prompt, pmtlen); 543 /* Make sure we are at column zero even after a newline, 544 regardless of the state of terminal output processing. */ 545 if (pmtlen < 2 || prompt_this_line[-2] != '\r') 546 cr (); 547 } 548 } 549 550 prompt_physical_chars = pmtlen = strlen (prompt_this_line); 551 temp = pmtlen + out + 2; 552 if (temp >= line_size) 553 { 554 line_size = (temp + 1024) - (temp % 1024); 555 visible_line = (char *)xrealloc (visible_line, line_size); 556 line = invisible_line = (char *)xrealloc (invisible_line, line_size); 557 } 558 strncpy (line + out, prompt_this_line, pmtlen); 559 out += pmtlen; 560 line[out] = '\0'; 561 wrap_offset = prompt_invis_chars_first_line = 0; 562 } 563 564 #if defined (HANDLE_MULTIBYTE) 565 #define CHECK_INV_LBREAKS() \ 566 do { \ 567 if (newlines >= (inv_lbsize - 2)) \ 568 { \ 569 inv_lbsize *= 2; \ 570 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ 571 _rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \ 572 } \ 573 } while (0) 574 #else 575 #define CHECK_INV_LBREAKS() \ 576 do { \ 577 if (newlines >= (inv_lbsize - 2)) \ 578 { \ 579 inv_lbsize *= 2; \ 580 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ 581 } \ 582 } while (0) 583 #endif /* HANDLE_MULTIBYTE */ 584 585 #if defined (HANDLE_MULTIBYTE) 586 #define CHECK_LPOS() \ 587 do { \ 588 lpos++; \ 589 if (lpos >= _rl_screenwidth) \ 590 { \ 591 if (newlines >= (inv_lbsize - 2)) \ 592 { \ 593 inv_lbsize *= 2; \ 594 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ 595 _rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \ 596 } \ 597 inv_lbreaks[++newlines] = out; \ 598 _rl_wrapped_line[newlines] = _rl_wrapped_multicolumn; \ 599 lpos = 0; \ 600 } \ 601 } while (0) 602 #else 603 #define CHECK_LPOS() \ 604 do { \ 605 lpos++; \ 606 if (lpos >= _rl_screenwidth) \ 607 { \ 608 if (newlines >= (inv_lbsize - 2)) \ 609 { \ 610 inv_lbsize *= 2; \ 611 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ 612 } \ 613 inv_lbreaks[++newlines] = out; \ 614 lpos = 0; \ 615 } \ 616 } while (0) 617 #endif 618 619 /* inv_lbreaks[i] is where line i starts in the buffer. */ 620 inv_lbreaks[newlines = 0] = 0; 621 #if 0 622 lpos = out - wrap_offset; 623 #else 624 lpos = prompt_physical_chars + modmark; 625 #endif 626 627 #if defined (HANDLE_MULTIBYTE) 628 memset (_rl_wrapped_line, 0, vis_lbsize); 629 num = 0; 630 #endif 631 632 /* prompt_invis_chars_first_line is the number of invisible characters in 633 the first physical line of the prompt. 634 wrap_offset - prompt_invis_chars_first_line is the number of invis 635 chars on the second line. */ 636 637 /* what if lpos is already >= _rl_screenwidth before we start drawing the 638 contents of the command line? */ 639 while (lpos >= _rl_screenwidth) 640 { 641 int z; 642 /* fix from Darin Johnson <darin@acuson.com> for prompt string with 643 invisible characters that is longer than the screen width. The 644 prompt_invis_chars_first_line variable could be made into an array 645 saying how many invisible characters there are per line, but that's 646 probably too much work for the benefit gained. How many people have 647 prompts that exceed two physical lines? 648 Additional logic fix from Edward Catmur <ed@catmur.co.uk> */ 649 #if defined (HANDLE_MULTIBYTE) 650 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 651 { 652 n0 = num; 653 temp = local_prompt_len; 654 while (num < temp) 655 { 656 z = _rl_col_width (local_prompt, n0, num); 657 if (z > _rl_screenwidth) 658 { 659 num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY); 660 break; 661 } 662 else if (z == _rl_screenwidth) 663 break; 664 num++; 665 } 666 temp = num; 667 } 668 else 669 #endif /* !HANDLE_MULTIBYTE */ 670 temp = ((newlines + 1) * _rl_screenwidth); 671 672 /* Now account for invisible characters in the current line. */ 673 temp += ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line 674 : ((newlines == 1) ? wrap_offset : 0)) 675 : ((newlines == 0) ? wrap_offset :0)); 676 677 inv_lbreaks[++newlines] = temp; 678 #if defined (HANDLE_MULTIBYTE) 679 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 680 lpos -= _rl_col_width (local_prompt, n0, num); 681 else 682 #endif 683 lpos -= _rl_screenwidth; 684 } 685 686 prompt_last_screen_line = newlines; 687 688 /* Draw the rest of the line (after the prompt) into invisible_line, keeping 689 track of where the cursor is (cpos_buffer_position), the number of the line containing 690 the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin). 691 It maintains an array of line breaks for display (inv_lbreaks). 692 This handles expanding tabs for display and displaying meta characters. */ 693 lb_linenum = 0; 694 #if defined (HANDLE_MULTIBYTE) 695 in = 0; 696 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 697 { 698 memset (&ps, 0, sizeof (mbstate_t)); 699 wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps); 700 } 701 else 702 wc_bytes = 1; 703 while (in < rl_end) 704 #else 705 for (in = 0; in < rl_end; in++) 706 #endif 707 { 708 c = (unsigned char)rl_line_buffer[in]; 709 710 #if defined (HANDLE_MULTIBYTE) 711 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 712 { 713 if (MB_INVALIDCH (wc_bytes)) 714 { 715 /* Byte sequence is invalid or shortened. Assume that the 716 first byte represents a character. */ 717 wc_bytes = 1; 718 /* Assume that a character occupies a single column. */ 719 wc_width = 1; 720 memset (&ps, 0, sizeof (mbstate_t)); 721 } 722 else if (MB_NULLWCH (wc_bytes)) 723 break; /* Found '\0' */ 724 else 725 { 726 temp = wcwidth (wc); 727 wc_width = (temp >= 0) ? temp : 1; 728 } 729 } 730 #endif 731 732 if (out + 8 >= line_size) /* XXX - 8 for \t */ 733 { 734 line_size *= 2; 735 visible_line = (char *)xrealloc (visible_line, line_size); 736 invisible_line = (char *)xrealloc (invisible_line, line_size); 737 line = invisible_line; 738 } 739 740 if (in == rl_point) 741 { 742 cpos_buffer_position = out; 743 lb_linenum = newlines; 744 } 745 746 #if defined (HANDLE_MULTIBYTE) 747 if (META_CHAR (c) && _rl_output_meta_chars == 0) /* XXX - clean up */ 748 #else 749 if (META_CHAR (c)) 750 #endif 751 { 752 if (_rl_output_meta_chars == 0) 753 { 754 sprintf (line + out, "\\%o", c); 755 756 if (lpos + 4 >= _rl_screenwidth) 757 { 758 temp = _rl_screenwidth - lpos; 759 CHECK_INV_LBREAKS (); 760 inv_lbreaks[++newlines] = out + temp; 761 lpos = 4 - temp; 762 } 763 else 764 lpos += 4; 765 766 out += 4; 767 } 768 else 769 { 770 line[out++] = c; 771 CHECK_LPOS(); 772 } 773 } 774 #if defined (DISPLAY_TABS) 775 else if (c == '\t') 776 { 777 register int newout; 778 779 #if 0 780 newout = (out | (int)7) + 1; 781 #else 782 newout = out + 8 - lpos % 8; 783 #endif 784 temp = newout - out; 785 if (lpos + temp >= _rl_screenwidth) 786 { 787 register int temp2; 788 temp2 = _rl_screenwidth - lpos; 789 CHECK_INV_LBREAKS (); 790 inv_lbreaks[++newlines] = out + temp2; 791 lpos = temp - temp2; 792 while (out < newout) 793 line[out++] = ' '; 794 } 795 else 796 { 797 while (out < newout) 798 line[out++] = ' '; 799 lpos += temp; 800 } 801 } 802 #endif 803 else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up) 804 { 805 line[out++] = '\0'; /* XXX - sentinel */ 806 CHECK_INV_LBREAKS (); 807 inv_lbreaks[++newlines] = out; 808 lpos = 0; 809 } 810 else if (CTRL_CHAR (c) || c == RUBOUT) 811 { 812 line[out++] = '^'; 813 CHECK_LPOS(); 814 line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?'; 815 CHECK_LPOS(); 816 } 817 else 818 { 819 #if defined (HANDLE_MULTIBYTE) 820 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 821 { 822 register int i; 823 824 _rl_wrapped_multicolumn = 0; 825 826 if (_rl_screenwidth < lpos + wc_width) 827 for (i = lpos; i < _rl_screenwidth; i++) 828 { 829 /* The space will be removed in update_line() */ 830 line[out++] = ' '; 831 _rl_wrapped_multicolumn++; 832 CHECK_LPOS(); 833 } 834 if (in == rl_point) 835 { 836 cpos_buffer_position = out; 837 lb_linenum = newlines; 838 } 839 for (i = in; i < in+wc_bytes; i++) 840 line[out++] = rl_line_buffer[i]; 841 for (i = 0; i < wc_width; i++) 842 CHECK_LPOS(); 843 } 844 else 845 { 846 line[out++] = c; 847 CHECK_LPOS(); 848 } 849 #else 850 line[out++] = c; 851 CHECK_LPOS(); 852 #endif 853 } 854 855 #if defined (HANDLE_MULTIBYTE) 856 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 857 { 858 in += wc_bytes; 859 wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps); 860 } 861 else 862 in++; 863 #endif 864 865 } 866 line[out] = '\0'; 867 if (cpos_buffer_position < 0) 868 { 869 cpos_buffer_position = out; 870 lb_linenum = newlines; 871 } 872 873 inv_botlin = lb_botlin = newlines; 874 CHECK_INV_LBREAKS (); 875 inv_lbreaks[newlines+1] = out; 876 cursor_linenum = lb_linenum; 877 878 /* CPOS_BUFFER_POSITION == position in buffer where cursor should be placed. 879 CURSOR_LINENUM == line number where the cursor should be placed. */ 880 881 /* PWP: now is when things get a bit hairy. The visible and invisible 882 line buffers are really multiple lines, which would wrap every 883 (screenwidth - 1) characters. Go through each in turn, finding 884 the changed region and updating it. The line order is top to bottom. */ 885 886 /* If we can move the cursor up and down, then use multiple lines, 887 otherwise, let long lines display in a single terminal line, and 888 horizontally scroll it. */ 889 890 if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up) 891 { 892 int nleft, pos, changed_screen_line, tx; 893 894 if (!rl_display_fixed || forced_display) 895 { 896 forced_display = 0; 897 898 /* If we have more than a screenful of material to display, then 899 only display a screenful. We should display the last screen, 900 not the first. */ 901 if (out >= _rl_screenchars) 902 { 903 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 904 out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY); 905 else 906 out = _rl_screenchars - 1; 907 } 908 909 /* The first line is at character position 0 in the buffer. The 910 second and subsequent lines start at inv_lbreaks[N], offset by 911 OFFSET (which has already been calculated above). */ 912 913 #define W_OFFSET(line, offset) ((line) == 0 ? offset : 0) 914 #define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l])) 915 #define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l]) 916 #define VIS_CHARS(line) (visible_line + vis_lbreaks[line]) 917 #define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line) 918 #define INV_LINE(line) (invisible_line + inv_lbreaks[line]) 919 920 /* For each line in the buffer, do the updating display. */ 921 for (linenum = 0; linenum <= inv_botlin; linenum++) 922 { 923 /* This can lead us astray if we execute a program that changes 924 the locale from a non-multibyte to a multibyte one. */ 925 o_cpos = _rl_last_c_pos; 926 cpos_adjusted = 0; 927 update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum, 928 VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin); 929 930 /* update_line potentially changes _rl_last_c_pos, but doesn't 931 take invisible characters into account, since _rl_last_c_pos 932 is an absolute cursor position in a multibyte locale. See 933 if compensating here is the right thing, or if we have to 934 change update_line itself. There is one case in which 935 update_line adjusts _rl_last_c_pos itself (so it can pass 936 _rl_move_cursor_relative accurate values); it communicates 937 this back by setting cpos_adjusted. If we assume that 938 _rl_last_c_pos is correct (an absolute cursor position) each 939 time update_line is called, then we can assume in our 940 calculations that o_cpos does not need to be adjusted by 941 wrap_offset. */ 942 if (linenum == 0 && (MB_CUR_MAX > 1 && rl_byte_oriented == 0) && 943 cpos_adjusted == 0 && 944 _rl_last_c_pos != o_cpos && 945 _rl_last_c_pos > wrap_offset && 946 o_cpos < prompt_last_invisible) 947 _rl_last_c_pos -= wrap_offset; 948 949 /* If this is the line with the prompt, we might need to 950 compensate for invisible characters in the new line. Do 951 this only if there is not more than one new line (which 952 implies that we completely overwrite the old visible line) 953 and the new line is shorter than the old. Make sure we are 954 at the end of the new line before clearing. */ 955 if (linenum == 0 && 956 inv_botlin == 0 && _rl_last_c_pos == out && 957 (wrap_offset > visible_wrap_offset) && 958 (_rl_last_c_pos < visible_first_line_len)) 959 { 960 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 961 nleft = _rl_screenwidth - _rl_last_c_pos; 962 else 963 nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos; 964 if (nleft) 965 _rl_clear_to_eol (nleft); 966 } 967 968 /* Since the new first line is now visible, save its length. */ 969 if (linenum == 0) 970 visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset; 971 } 972 973 /* We may have deleted some lines. If so, clear the left over 974 blank ones at the bottom out. */ 975 if (_rl_vis_botlin > inv_botlin) 976 { 977 char *tt; 978 for (; linenum <= _rl_vis_botlin; linenum++) 979 { 980 tt = VIS_CHARS (linenum); 981 _rl_move_vert (linenum); 982 _rl_move_cursor_relative (0, tt); 983 _rl_clear_to_eol 984 ((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth); 985 } 986 } 987 _rl_vis_botlin = inv_botlin; 988 989 /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a 990 different screen line during this redisplay. */ 991 changed_screen_line = _rl_last_v_pos != cursor_linenum; 992 if (changed_screen_line) 993 { 994 _rl_move_vert (cursor_linenum); 995 /* If we moved up to the line with the prompt using _rl_term_up, 996 the physical cursor position on the screen stays the same, 997 but the buffer position needs to be adjusted to account 998 for invisible characters. */ 999 if ((MB_CUR_MAX == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset) 1000 _rl_last_c_pos += wrap_offset; 1001 } 1002 1003 /* We have to reprint the prompt if it contains invisible 1004 characters, since it's not generally OK to just reprint 1005 the characters from the current cursor position. But we 1006 only need to reprint it if the cursor is before the last 1007 invisible character in the prompt string. */ 1008 nleft = prompt_visible_length + wrap_offset; 1009 if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 && 1010 #if 0 1011 _rl_last_c_pos <= PROMPT_ENDING_INDEX && local_prompt) 1012 #else 1013 _rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt) 1014 #endif 1015 { 1016 #if defined (__MSDOS__) 1017 putc ('\r', rl_outstream); 1018 #else 1019 if (_rl_term_cr) 1020 tputs (_rl_term_cr, 1, _rl_output_character_function); 1021 #endif 1022 _rl_output_some_chars (local_prompt, nleft); 1023 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1024 _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft) - wrap_offset; 1025 else 1026 _rl_last_c_pos = nleft; 1027 } 1028 1029 /* Where on that line? And where does that line start 1030 in the buffer? */ 1031 pos = inv_lbreaks[cursor_linenum]; 1032 /* nleft == number of characters in the line buffer between the 1033 start of the line and the desired cursor position. */ 1034 nleft = cpos_buffer_position - pos; 1035 1036 /* NLEFT is now a number of characters in a buffer. When in a 1037 multibyte locale, however, _rl_last_c_pos is an absolute cursor 1038 position that doesn't take invisible characters in the prompt 1039 into account. We use a fudge factor to compensate. */ 1040 1041 /* Since _rl_backspace() doesn't know about invisible characters in the 1042 prompt, and there's no good way to tell it, we compensate for 1043 those characters here and call _rl_backspace() directly. */ 1044 if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos) 1045 { 1046 /* TX == new physical cursor position in multibyte locale. */ 1047 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1048 tx = _rl_col_width (&visible_line[pos], 0, nleft) - visible_wrap_offset; 1049 else 1050 tx = nleft; 1051 if (tx >= 0 && _rl_last_c_pos > tx) 1052 { 1053 _rl_backspace (_rl_last_c_pos - tx); /* XXX */ 1054 _rl_last_c_pos = tx; 1055 } 1056 } 1057 1058 /* We need to note that in a multibyte locale we are dealing with 1059 _rl_last_c_pos as an absolute cursor position, but moving to a 1060 point specified by a buffer position (NLEFT) that doesn't take 1061 invisible characters into account. */ 1062 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1063 _rl_move_cursor_relative (nleft, &invisible_line[pos]); 1064 else if (nleft != _rl_last_c_pos) 1065 _rl_move_cursor_relative (nleft, &invisible_line[pos]); 1066 } 1067 } 1068 else /* Do horizontal scrolling. */ 1069 { 1070 #define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0) 1071 int lmargin, ndisp, nleft, phys_c_pos, t; 1072 1073 /* Always at top line. */ 1074 _rl_last_v_pos = 0; 1075 1076 /* Compute where in the buffer the displayed line should start. This 1077 will be LMARGIN. */ 1078 1079 /* The number of characters that will be displayed before the cursor. */ 1080 ndisp = cpos_buffer_position - wrap_offset; 1081 nleft = prompt_visible_length + wrap_offset; 1082 /* Where the new cursor position will be on the screen. This can be 1083 longer than SCREENWIDTH; if it is, lmargin will be adjusted. */ 1084 phys_c_pos = cpos_buffer_position - (last_lmargin ? last_lmargin : wrap_offset); 1085 t = _rl_screenwidth / 3; 1086 1087 /* If the number of characters had already exceeded the screenwidth, 1088 last_lmargin will be > 0. */ 1089 1090 /* If the number of characters to be displayed is more than the screen 1091 width, compute the starting offset so that the cursor is about 1092 two-thirds of the way across the screen. */ 1093 if (phys_c_pos > _rl_screenwidth - 2) 1094 { 1095 lmargin = cpos_buffer_position - (2 * t); 1096 if (lmargin < 0) 1097 lmargin = 0; 1098 /* If the left margin would be in the middle of a prompt with 1099 invisible characters, don't display the prompt at all. */ 1100 if (wrap_offset && lmargin > 0 && lmargin < nleft) 1101 lmargin = nleft; 1102 } 1103 else if (ndisp < _rl_screenwidth - 2) /* XXX - was -1 */ 1104 lmargin = 0; 1105 else if (phys_c_pos < 1) 1106 { 1107 /* If we are moving back towards the beginning of the line and 1108 the last margin is no longer correct, compute a new one. */ 1109 lmargin = ((cpos_buffer_position - 1) / t) * t; /* XXX */ 1110 if (wrap_offset && lmargin > 0 && lmargin < nleft) 1111 lmargin = nleft; 1112 } 1113 else 1114 lmargin = last_lmargin; 1115 1116 /* If the first character on the screen isn't the first character 1117 in the display line, indicate this with a special character. */ 1118 if (lmargin > 0) 1119 line[lmargin] = '<'; 1120 1121 /* If SCREENWIDTH characters starting at LMARGIN do not encompass 1122 the whole line, indicate that with a special character at the 1123 right edge of the screen. If LMARGIN is 0, we need to take the 1124 wrap offset into account. */ 1125 t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth; 1126 if (t < out) 1127 line[t - 1] = '>'; 1128 1129 if (!rl_display_fixed || forced_display || lmargin != last_lmargin) 1130 { 1131 forced_display = 0; 1132 update_line (&visible_line[last_lmargin], 1133 &invisible_line[lmargin], 1134 0, 1135 _rl_screenwidth + visible_wrap_offset, 1136 _rl_screenwidth + (lmargin ? 0 : wrap_offset), 1137 0); 1138 1139 /* If the visible new line is shorter than the old, but the number 1140 of invisible characters is greater, and we are at the end of 1141 the new line, we need to clear to eol. */ 1142 t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset); 1143 if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) && 1144 (_rl_last_c_pos == out) && 1145 t < visible_first_line_len) 1146 { 1147 nleft = _rl_screenwidth - t; 1148 _rl_clear_to_eol (nleft); 1149 } 1150 visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset); 1151 if (visible_first_line_len > _rl_screenwidth) 1152 visible_first_line_len = _rl_screenwidth; 1153 1154 _rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin]); 1155 last_lmargin = lmargin; 1156 } 1157 } 1158 fflush (rl_outstream); 1159 1160 /* Swap visible and non-visible lines. */ 1161 { 1162 char *vtemp = visible_line; 1163 int *itemp = vis_lbreaks, ntemp = vis_lbsize; 1164 1165 visible_line = invisible_line; 1166 invisible_line = vtemp; 1167 1168 vis_lbreaks = inv_lbreaks; 1169 inv_lbreaks = itemp; 1170 1171 vis_lbsize = inv_lbsize; 1172 inv_lbsize = ntemp; 1173 1174 rl_display_fixed = 0; 1175 /* If we are displaying on a single line, and last_lmargin is > 0, we 1176 are not displaying any invisible characters, so set visible_wrap_offset 1177 to 0. */ 1178 if (_rl_horizontal_scroll_mode && last_lmargin) 1179 visible_wrap_offset = 0; 1180 else 1181 visible_wrap_offset = wrap_offset; 1182 } 1183 } 1184 1185 /* PWP: update_line() is based on finding the middle difference of each 1186 line on the screen; vis: 1187 1188 /old first difference 1189 /beginning of line | /old last same /old EOL 1190 v v v v 1191 old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as 1192 new: eddie> Oh, my little buggy says to me, as lurgid as 1193 ^ ^ ^ ^ 1194 \beginning of line | \new last same \new end of line 1195 \new first difference 1196 1197 All are character pointers for the sake of speed. Special cases for 1198 no differences, as well as for end of line additions must be handled. 1199 1200 Could be made even smarter, but this works well enough */ 1201 static void 1202 update_line (old, new, current_line, omax, nmax, inv_botlin) 1203 register char *old, *new; 1204 int current_line, omax, nmax, inv_botlin; 1205 { 1206 register char *ofd, *ols, *oe, *nfd, *nls, *ne; 1207 int temp, lendiff, wsatend, od, nd, o_cpos; 1208 int current_invis_chars; 1209 int col_lendiff, col_temp; 1210 #if defined (HANDLE_MULTIBYTE) 1211 mbstate_t ps_new, ps_old; 1212 int new_offset, old_offset; 1213 #endif 1214 1215 /* If we're at the right edge of a terminal that supports xn, we're 1216 ready to wrap around, so do so. This fixes problems with knowing 1217 the exact cursor position and cut-and-paste with certain terminal 1218 emulators. In this calculation, TEMP is the physical screen 1219 position of the cursor. */ 1220 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1221 temp = _rl_last_c_pos; 1222 else 1223 temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset); 1224 if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode 1225 && _rl_last_v_pos == current_line - 1) 1226 { 1227 #if defined (HANDLE_MULTIBYTE) 1228 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1229 { 1230 wchar_t wc; 1231 mbstate_t ps; 1232 int tempwidth, bytes; 1233 size_t ret; 1234 1235 /* This fixes only double-column characters, but if the wrapped 1236 character comsumes more than three columns, spaces will be 1237 inserted in the string buffer. */ 1238 if (_rl_wrapped_line[current_line] > 0) 1239 _rl_clear_to_eol (_rl_wrapped_line[current_line]); 1240 1241 memset (&ps, 0, sizeof (mbstate_t)); 1242 ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps); 1243 if (MB_INVALIDCH (ret)) 1244 { 1245 tempwidth = 1; 1246 ret = 1; 1247 } 1248 else if (MB_NULLWCH (ret)) 1249 tempwidth = 0; 1250 else 1251 tempwidth = wcwidth (wc); 1252 1253 if (tempwidth > 0) 1254 { 1255 int count; 1256 bytes = ret; 1257 for (count = 0; count < bytes; count++) 1258 putc (new[count], rl_outstream); 1259 _rl_last_c_pos = tempwidth; 1260 _rl_last_v_pos++; 1261 memset (&ps, 0, sizeof (mbstate_t)); 1262 ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps); 1263 if (ret != 0 && bytes != 0) 1264 { 1265 if (MB_INVALIDCH (ret)) 1266 memmove (old+bytes, old+1, strlen (old+1)); 1267 else 1268 memmove (old+bytes, old+ret, strlen (old+ret)); 1269 memcpy (old, new, bytes); 1270 } 1271 } 1272 else 1273 { 1274 putc (' ', rl_outstream); 1275 _rl_last_c_pos = 1; 1276 _rl_last_v_pos++; 1277 if (old[0] && new[0]) 1278 old[0] = new[0]; 1279 } 1280 } 1281 else 1282 #endif 1283 { 1284 if (new[0]) 1285 putc (new[0], rl_outstream); 1286 else 1287 putc (' ', rl_outstream); 1288 _rl_last_c_pos = 1; 1289 _rl_last_v_pos++; 1290 if (old[0] && new[0]) 1291 old[0] = new[0]; 1292 } 1293 } 1294 1295 1296 /* Find first difference. */ 1297 #if defined (HANDLE_MULTIBYTE) 1298 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1299 { 1300 /* See if the old line is a subset of the new line, so that the 1301 only change is adding characters. */ 1302 temp = (omax < nmax) ? omax : nmax; 1303 if (memcmp (old, new, temp) == 0) 1304 { 1305 ofd = old + temp; 1306 nfd = new + temp; 1307 } 1308 else 1309 { 1310 memset (&ps_new, 0, sizeof(mbstate_t)); 1311 memset (&ps_old, 0, sizeof(mbstate_t)); 1312 1313 if (omax == nmax && STREQN (new, old, omax)) 1314 { 1315 ofd = old + omax; 1316 nfd = new + nmax; 1317 } 1318 else 1319 { 1320 new_offset = old_offset = 0; 1321 for (ofd = old, nfd = new; 1322 (ofd - old < omax) && *ofd && 1323 _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); ) 1324 { 1325 old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY); 1326 new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY); 1327 ofd = old + old_offset; 1328 nfd = new + new_offset; 1329 } 1330 } 1331 } 1332 } 1333 else 1334 #endif 1335 for (ofd = old, nfd = new; 1336 (ofd - old < omax) && *ofd && (*ofd == *nfd); 1337 ofd++, nfd++) 1338 ; 1339 1340 /* Move to the end of the screen line. ND and OD are used to keep track 1341 of the distance between ne and new and oe and old, respectively, to 1342 move a subtraction out of each loop. */ 1343 for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++); 1344 for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++); 1345 1346 /* If no difference, continue to next line. */ 1347 if (ofd == oe && nfd == ne) 1348 return; 1349 1350 wsatend = 1; /* flag for trailing whitespace */ 1351 1352 #if defined (HANDLE_MULTIBYTE) 1353 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1354 { 1355 ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY); 1356 nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY); 1357 while ((ols > ofd) && (nls > nfd)) 1358 { 1359 memset (&ps_old, 0, sizeof (mbstate_t)); 1360 memset (&ps_new, 0, sizeof (mbstate_t)); 1361 1362 #if 0 1363 /* On advice from jir@yamato.ibm.com */ 1364 _rl_adjust_point (old, ols - old, &ps_old); 1365 _rl_adjust_point (new, nls - new, &ps_new); 1366 #endif 1367 1368 if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0) 1369 break; 1370 1371 if (*ols == ' ') 1372 wsatend = 0; 1373 1374 ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY); 1375 nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY); 1376 } 1377 } 1378 else 1379 { 1380 #endif /* HANDLE_MULTIBYTE */ 1381 ols = oe - 1; /* find last same */ 1382 nls = ne - 1; 1383 while ((ols > ofd) && (nls > nfd) && (*ols == *nls)) 1384 { 1385 if (*ols != ' ') 1386 wsatend = 0; 1387 ols--; 1388 nls--; 1389 } 1390 #if defined (HANDLE_MULTIBYTE) 1391 } 1392 #endif 1393 1394 if (wsatend) 1395 { 1396 ols = oe; 1397 nls = ne; 1398 } 1399 #if defined (HANDLE_MULTIBYTE) 1400 /* This may not work for stateful encoding, but who cares? To handle 1401 stateful encoding properly, we have to scan each string from the 1402 beginning and compare. */ 1403 else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0) 1404 #else 1405 else if (*ols != *nls) 1406 #endif 1407 { 1408 if (*ols) /* don't step past the NUL */ 1409 { 1410 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1411 ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY); 1412 else 1413 ols++; 1414 } 1415 if (*nls) 1416 { 1417 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1418 nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY); 1419 else 1420 nls++; 1421 } 1422 } 1423 1424 /* count of invisible characters in the current invisible line. */ 1425 current_invis_chars = W_OFFSET (current_line, wrap_offset); 1426 if (_rl_last_v_pos != current_line) 1427 { 1428 _rl_move_vert (current_line); 1429 if ((MB_CUR_MAX == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset) 1430 _rl_last_c_pos += visible_wrap_offset; 1431 } 1432 1433 /* If this is the first line and there are invisible characters in the 1434 prompt string, and the prompt string has not changed, and the current 1435 cursor position is before the last invisible character in the prompt, 1436 and the index of the character to move to is past the end of the prompt 1437 string, then redraw the entire prompt string. We can only do this 1438 reliably if the terminal supports a `cr' capability. 1439 1440 This is not an efficiency hack -- there is a problem with redrawing 1441 portions of the prompt string if they contain terminal escape 1442 sequences (like drawing the `unbold' sequence without a corresponding 1443 `bold') that manifests itself on certain terminals. */ 1444 1445 lendiff = local_prompt_len; 1446 od = ofd - old; /* index of first difference in visible line */ 1447 if (current_line == 0 && !_rl_horizontal_scroll_mode && 1448 _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 && 1449 od >= lendiff && _rl_last_c_pos < PROMPT_ENDING_INDEX) 1450 { 1451 #if defined (__MSDOS__) 1452 putc ('\r', rl_outstream); 1453 #else 1454 tputs (_rl_term_cr, 1, _rl_output_character_function); 1455 #endif 1456 _rl_output_some_chars (local_prompt, lendiff); 1457 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1458 { 1459 /* We take wrap_offset into account here so we can pass correct 1460 information to _rl_move_cursor_relative. */ 1461 _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff) - wrap_offset; 1462 cpos_adjusted = 1; 1463 } 1464 else 1465 _rl_last_c_pos = lendiff; 1466 } 1467 1468 o_cpos = _rl_last_c_pos; 1469 1470 /* When this function returns, _rl_last_c_pos is correct, and an absolute 1471 cursor postion in multibyte mode, but a buffer index when not in a 1472 multibyte locale. */ 1473 _rl_move_cursor_relative (od, old); 1474 #if 1 1475 #if defined (HANDLE_MULTIBYTE) 1476 /* We need to indicate that the cursor position is correct in the presence of 1477 invisible characters in the prompt string. Let's see if setting this when 1478 we make sure we're at the end of the drawn prompt string works. */ 1479 if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 && 1480 (_rl_last_c_pos > 0 || o_cpos > 0) && 1481 _rl_last_c_pos == prompt_physical_chars) 1482 cpos_adjusted = 1; 1483 #endif 1484 #endif 1485 1486 /* if (len (new) > len (old)) 1487 lendiff == difference in buffer 1488 col_lendiff == difference on screen 1489 When not using multibyte characters, these are equal */ 1490 lendiff = (nls - nfd) - (ols - ofd); 1491 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1492 col_lendiff = _rl_col_width (new, nfd - new, nls - new) - _rl_col_width (old, ofd - old, ols - old); 1493 else 1494 col_lendiff = lendiff; 1495 1496 /* If we are changing the number of invisible characters in a line, and 1497 the spot of first difference is before the end of the invisible chars, 1498 lendiff needs to be adjusted. */ 1499 if (current_line == 0 && !_rl_horizontal_scroll_mode && 1500 current_invis_chars != visible_wrap_offset) 1501 { 1502 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1503 { 1504 lendiff += visible_wrap_offset - current_invis_chars; 1505 col_lendiff += visible_wrap_offset - current_invis_chars; 1506 } 1507 else 1508 { 1509 lendiff += visible_wrap_offset - current_invis_chars; 1510 col_lendiff = lendiff; 1511 } 1512 } 1513 1514 /* Insert (diff (len (old), len (new)) ch. */ 1515 temp = ne - nfd; 1516 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1517 col_temp = _rl_col_width (new, nfd - new, ne - new); 1518 else 1519 col_temp = temp; 1520 1521 if (col_lendiff > 0) /* XXX - was lendiff */ 1522 { 1523 /* Non-zero if we're increasing the number of lines. */ 1524 int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin; 1525 /* If col_lendiff is > 0, implying that the new string takes up more 1526 screen real estate than the old, but lendiff is < 0, meaning that it 1527 takes fewer bytes, we need to just output the characters starting 1528 from the first difference. These will overwrite what is on the 1529 display, so there's no reason to do a smart update. This can really 1530 only happen in a multibyte environment. */ 1531 if (lendiff < 0) 1532 { 1533 _rl_output_some_chars (nfd, temp); 1534 _rl_last_c_pos += _rl_col_width (nfd, 0, temp); 1535 /* If nfd begins before any invisible characters in the prompt, 1536 adjust _rl_last_c_pos to account for wrap_offset and set 1537 cpos_adjusted to let the caller know. */ 1538 if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible)) 1539 { 1540 _rl_last_c_pos -= wrap_offset; 1541 cpos_adjusted = 1; 1542 } 1543 return; 1544 } 1545 /* Sometimes it is cheaper to print the characters rather than 1546 use the terminal's capabilities. If we're growing the number 1547 of lines, make sure we actually cause the new line to wrap 1548 around on auto-wrapping terminals. */ 1549 else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl)) 1550 { 1551 /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and 1552 _rl_horizontal_scroll_mode == 1, inserting the characters with 1553 _rl_term_IC or _rl_term_ic will screw up the screen because of the 1554 invisible characters. We need to just draw them. */ 1555 if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 || 1556 lendiff <= prompt_visible_length || !current_invis_chars)) 1557 { 1558 insert_some_chars (nfd, lendiff, col_lendiff); 1559 _rl_last_c_pos += col_lendiff; 1560 } 1561 else if ((MB_CUR_MAX == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0) 1562 { 1563 /* At the end of a line the characters do not have to 1564 be "inserted". They can just be placed on the screen. */ 1565 /* However, this screws up the rest of this block, which 1566 assumes you've done the insert because you can. */ 1567 _rl_output_some_chars (nfd, lendiff); 1568 _rl_last_c_pos += col_lendiff; 1569 } 1570 else 1571 { 1572 /* We have horizontal scrolling and we are not inserting at 1573 the end. We have invisible characters in this line. This 1574 is a dumb update. */ 1575 _rl_output_some_chars (nfd, temp); 1576 _rl_last_c_pos += col_temp; 1577 return; 1578 } 1579 /* Copy (new) chars to screen from first diff to last match. */ 1580 temp = nls - nfd; 1581 if ((temp - lendiff) > 0) 1582 { 1583 _rl_output_some_chars (nfd + lendiff, temp - lendiff); 1584 #if 1 1585 /* XXX -- this bears closer inspection. Fixes a redisplay bug 1586 reported against bash-3.0-alpha by Andreas Schwab involving 1587 multibyte characters and prompt strings with invisible 1588 characters, but was previously disabled. */ 1589 _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-col_lendiff); 1590 #else 1591 _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-lendiff); 1592 #endif 1593 } 1594 } 1595 else 1596 { 1597 /* cannot insert chars, write to EOL */ 1598 _rl_output_some_chars (nfd, temp); 1599 _rl_last_c_pos += col_temp; 1600 /* If we're in a multibyte locale and were before the last invisible 1601 char in the current line (which implies we just output some invisible 1602 characters) we need to adjust _rl_last_c_pos, since it represents 1603 a physical character position. */ 1604 } 1605 } 1606 else /* Delete characters from line. */ 1607 { 1608 /* If possible and inexpensive to use terminal deletion, then do so. */ 1609 if (_rl_term_dc && (2 * col_temp) >= -col_lendiff) 1610 { 1611 /* If all we're doing is erasing the invisible characters in the 1612 prompt string, don't bother. It screws up the assumptions 1613 about what's on the screen. */ 1614 if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 && 1615 -lendiff == visible_wrap_offset) 1616 col_lendiff = 0; 1617 1618 if (col_lendiff) 1619 delete_chars (-col_lendiff); /* delete (diff) characters */ 1620 1621 /* Copy (new) chars to screen from first diff to last match */ 1622 temp = nls - nfd; 1623 if (temp > 0) 1624 { 1625 /* If nfd begins at the prompt, or before the invisible 1626 characters in the prompt, we need to adjust _rl_last_c_pos 1627 in a multibyte locale to account for the wrap offset and 1628 set cpos_adjusted accordingly. */ 1629 _rl_output_some_chars (nfd, temp); 1630 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1631 { 1632 _rl_last_c_pos += _rl_col_width (nfd, 0, temp); 1633 if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible)) 1634 { 1635 _rl_last_c_pos -= wrap_offset; 1636 cpos_adjusted = 1; 1637 } 1638 } 1639 else 1640 _rl_last_c_pos += temp; 1641 } 1642 } 1643 /* Otherwise, print over the existing material. */ 1644 else 1645 { 1646 if (temp > 0) 1647 { 1648 /* If nfd begins at the prompt, or before the invisible 1649 characters in the prompt, we need to adjust _rl_last_c_pos 1650 in a multibyte locale to account for the wrap offset and 1651 set cpos_adjusted accordingly. */ 1652 _rl_output_some_chars (nfd, temp); 1653 _rl_last_c_pos += col_temp; /* XXX */ 1654 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1655 { 1656 if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible)) 1657 { 1658 _rl_last_c_pos -= wrap_offset; 1659 cpos_adjusted = 1; 1660 } 1661 } 1662 } 1663 lendiff = (oe - old) - (ne - new); 1664 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1665 col_lendiff = _rl_col_width (old, 0, oe - old) - _rl_col_width (new, 0, ne - new); 1666 else 1667 col_lendiff = lendiff; 1668 1669 if (col_lendiff) 1670 { 1671 if (_rl_term_autowrap && current_line < inv_botlin) 1672 space_to_eol (col_lendiff); 1673 else 1674 _rl_clear_to_eol (col_lendiff); 1675 } 1676 } 1677 } 1678 } 1679 1680 /* Tell the update routines that we have moved onto a new (empty) line. */ 1681 int 1682 rl_on_new_line () 1683 { 1684 if (visible_line) 1685 visible_line[0] = '\0'; 1686 1687 _rl_last_c_pos = _rl_last_v_pos = 0; 1688 _rl_vis_botlin = last_lmargin = 0; 1689 if (vis_lbreaks) 1690 vis_lbreaks[0] = vis_lbreaks[1] = 0; 1691 visible_wrap_offset = 0; 1692 return 0; 1693 } 1694 1695 /* Tell the update routines that we have moved onto a new line with the 1696 prompt already displayed. Code originally from the version of readline 1697 distributed with CLISP. rl_expand_prompt must have already been called 1698 (explicitly or implicitly). This still doesn't work exactly right. */ 1699 int 1700 rl_on_new_line_with_prompt () 1701 { 1702 int prompt_size, i, l, real_screenwidth, newlines; 1703 char *prompt_last_line, *lprompt; 1704 1705 /* Initialize visible_line and invisible_line to ensure that they can hold 1706 the already-displayed prompt. */ 1707 prompt_size = strlen (rl_prompt) + 1; 1708 init_line_structures (prompt_size); 1709 1710 /* Make sure the line structures hold the already-displayed prompt for 1711 redisplay. */ 1712 lprompt = local_prompt ? local_prompt : rl_prompt; 1713 strcpy (visible_line, lprompt); 1714 strcpy (invisible_line, lprompt); 1715 1716 /* If the prompt contains newlines, take the last tail. */ 1717 prompt_last_line = strrchr (rl_prompt, '\n'); 1718 if (!prompt_last_line) 1719 prompt_last_line = rl_prompt; 1720 1721 l = strlen (prompt_last_line); 1722 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1723 _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l); /* XXX */ 1724 else 1725 _rl_last_c_pos = l; 1726 1727 /* Dissect prompt_last_line into screen lines. Note that here we have 1728 to use the real screenwidth. Readline's notion of screenwidth might be 1729 one less, see terminal.c. */ 1730 real_screenwidth = _rl_screenwidth + (_rl_term_autowrap ? 0 : 1); 1731 _rl_last_v_pos = l / real_screenwidth; 1732 /* If the prompt length is a multiple of real_screenwidth, we don't know 1733 whether the cursor is at the end of the last line, or already at the 1734 beginning of the next line. Output a newline just to be safe. */ 1735 if (l > 0 && (l % real_screenwidth) == 0) 1736 _rl_output_some_chars ("\n", 1); 1737 last_lmargin = 0; 1738 1739 newlines = 0; i = 0; 1740 while (i <= l) 1741 { 1742 _rl_vis_botlin = newlines; 1743 vis_lbreaks[newlines++] = i; 1744 i += real_screenwidth; 1745 } 1746 vis_lbreaks[newlines] = l; 1747 visible_wrap_offset = 0; 1748 1749 rl_display_prompt = rl_prompt; /* XXX - make sure it's set */ 1750 1751 return 0; 1752 } 1753 1754 /* Actually update the display, period. */ 1755 int 1756 rl_forced_update_display () 1757 { 1758 register char *temp; 1759 1760 if (visible_line) 1761 { 1762 temp = visible_line; 1763 while (*temp) 1764 *temp++ = '\0'; 1765 } 1766 rl_on_new_line (); 1767 forced_display++; 1768 (*rl_redisplay_function) (); 1769 return 0; 1770 } 1771 1772 /* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices. 1773 (Well, when we don't have multibyte characters, _rl_last_c_pos is a 1774 buffer index.) 1775 DATA is the contents of the screen line of interest; i.e., where 1776 the movement is being done. */ 1777 void 1778 _rl_move_cursor_relative (new, data) 1779 int new; 1780 const char *data; 1781 { 1782 register int i; 1783 int woff; /* number of invisible chars on current line */ 1784 int cpos, dpos; /* current and desired cursor positions */ 1785 1786 woff = W_OFFSET (_rl_last_v_pos, wrap_offset); 1787 cpos = _rl_last_c_pos; 1788 #if defined (HANDLE_MULTIBYTE) 1789 /* If we have multibyte characters, NEW is indexed by the buffer point in 1790 a multibyte string, but _rl_last_c_pos is the display position. In 1791 this case, NEW's display position is not obvious and must be 1792 calculated. We need to account for invisible characters in this line, 1793 as long as we are past them and they are counted by _rl_col_width. */ 1794 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1795 { 1796 dpos = _rl_col_width (data, 0, new); 1797 /* Use NEW when comparing against the last invisible character in the 1798 prompt string, since they're both buffer indices and DPOS is a 1799 desired display position. */ 1800 if (new > prompt_last_invisible) /* XXX - don't use woff here */ 1801 { 1802 dpos -= woff; 1803 /* Since this will be assigned to _rl_last_c_pos at the end (more 1804 precisely, _rl_last_c_pos == dpos when this function returns), 1805 let the caller know. */ 1806 cpos_adjusted = 1; 1807 } 1808 } 1809 else 1810 #endif 1811 dpos = new; 1812 1813 /* If we don't have to do anything, then return. */ 1814 if (cpos == dpos) 1815 return; 1816 1817 /* It may be faster to output a CR, and then move forwards instead 1818 of moving backwards. */ 1819 /* i == current physical cursor position. */ 1820 #if defined (HANDLE_MULTIBYTE) 1821 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1822 i = _rl_last_c_pos; 1823 else 1824 #endif 1825 i = _rl_last_c_pos - woff; 1826 if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) || 1827 (_rl_term_autowrap && i == _rl_screenwidth)) 1828 { 1829 #if defined (__MSDOS__) 1830 putc ('\r', rl_outstream); 1831 #else 1832 tputs (_rl_term_cr, 1, _rl_output_character_function); 1833 #endif /* !__MSDOS__ */ 1834 cpos = _rl_last_c_pos = 0; 1835 } 1836 1837 if (cpos < dpos) 1838 { 1839 /* Move the cursor forward. We do it by printing the command 1840 to move the cursor forward if there is one, else print that 1841 portion of the output buffer again. Which is cheaper? */ 1842 1843 /* The above comment is left here for posterity. It is faster 1844 to print one character (non-control) than to print a control 1845 sequence telling the terminal to move forward one character. 1846 That kind of control is for people who don't know what the 1847 data is underneath the cursor. */ 1848 1849 /* However, we need a handle on where the current display position is 1850 in the buffer for the immediately preceding comment to be true. 1851 In multibyte locales, we don't currently have that info available. 1852 Without it, we don't know where the data we have to display begins 1853 in the buffer and we have to go back to the beginning of the screen 1854 line. In this case, we can use the terminal sequence to move forward 1855 if it's available. */ 1856 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1857 { 1858 if (_rl_term_forward_char) 1859 { 1860 for (i = cpos; i < dpos; i++) 1861 tputs (_rl_term_forward_char, 1, _rl_output_character_function); 1862 } 1863 else 1864 { 1865 tputs (_rl_term_cr, 1, _rl_output_character_function); 1866 for (i = 0; i < new; i++) 1867 putc (data[i], rl_outstream); 1868 } 1869 } 1870 else 1871 for (i = cpos; i < new; i++) 1872 putc (data[i], rl_outstream); 1873 } 1874 1875 #if defined (HANDLE_MULTIBYTE) 1876 /* NEW points to the buffer point, but _rl_last_c_pos is the display point. 1877 The byte length of the string is probably bigger than the column width 1878 of the string, which means that if NEW == _rl_last_c_pos, then NEW's 1879 display point is less than _rl_last_c_pos. */ 1880 #endif 1881 else if (cpos > dpos) 1882 _rl_backspace (cpos - dpos); 1883 1884 _rl_last_c_pos = dpos; 1885 } 1886 1887 /* PWP: move the cursor up or down. */ 1888 void 1889 _rl_move_vert (to) 1890 int to; 1891 { 1892 register int delta, i; 1893 1894 if (_rl_last_v_pos == to || to > _rl_screenheight) 1895 return; 1896 1897 if ((delta = to - _rl_last_v_pos) > 0) 1898 { 1899 for (i = 0; i < delta; i++) 1900 putc ('\n', rl_outstream); 1901 #if defined (__MSDOS__) 1902 putc ('\r', rl_outstream); 1903 #else 1904 tputs (_rl_term_cr, 1, _rl_output_character_function); 1905 #endif 1906 _rl_last_c_pos = 0; 1907 } 1908 else 1909 { /* delta < 0 */ 1910 if (_rl_term_up && *_rl_term_up) 1911 for (i = 0; i < -delta; i++) 1912 tputs (_rl_term_up, 1, _rl_output_character_function); 1913 } 1914 1915 _rl_last_v_pos = to; /* Now TO is here */ 1916 } 1917 1918 /* Physically print C on rl_outstream. This is for functions which know 1919 how to optimize the display. Return the number of characters output. */ 1920 int 1921 rl_show_char (c) 1922 int c; 1923 { 1924 int n = 1; 1925 if (META_CHAR (c) && (_rl_output_meta_chars == 0)) 1926 { 1927 fprintf (rl_outstream, "M-"); 1928 n += 2; 1929 c = UNMETA (c); 1930 } 1931 1932 #if defined (DISPLAY_TABS) 1933 if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT) 1934 #else 1935 if (CTRL_CHAR (c) || c == RUBOUT) 1936 #endif /* !DISPLAY_TABS */ 1937 { 1938 fprintf (rl_outstream, "C-"); 1939 n += 2; 1940 c = CTRL_CHAR (c) ? UNCTRL (c) : '?'; 1941 } 1942 1943 putc (c, rl_outstream); 1944 fflush (rl_outstream); 1945 return n; 1946 } 1947 1948 int 1949 rl_character_len (c, pos) 1950 register int c, pos; 1951 { 1952 unsigned char uc; 1953 1954 uc = (unsigned char)c; 1955 1956 if (META_CHAR (uc)) 1957 return ((_rl_output_meta_chars == 0) ? 4 : 1); 1958 1959 if (uc == '\t') 1960 { 1961 #if defined (DISPLAY_TABS) 1962 return (((pos | 7) + 1) - pos); 1963 #else 1964 return (2); 1965 #endif /* !DISPLAY_TABS */ 1966 } 1967 1968 if (CTRL_CHAR (c) || c == RUBOUT) 1969 return (2); 1970 1971 return ((ISPRINT (uc)) ? 1 : 2); 1972 } 1973 /* How to print things in the "echo-area". The prompt is treated as a 1974 mini-modeline. */ 1975 static int msg_saved_prompt = 0; 1976 1977 #if defined (USE_VARARGS) 1978 int 1979 #if defined (PREFER_STDARG) 1980 rl_message (const char *format, ...) 1981 #else 1982 rl_message (va_alist) 1983 va_dcl 1984 #endif 1985 { 1986 va_list args; 1987 #if defined (PREFER_VARARGS) 1988 char *format; 1989 #endif 1990 1991 #if defined (PREFER_STDARG) 1992 va_start (args, format); 1993 #else 1994 va_start (args); 1995 format = va_arg (args, char *); 1996 #endif 1997 1998 #if defined (HAVE_VSNPRINTF) 1999 vsnprintf (msg_buf, sizeof (msg_buf) - 1, format, args); 2000 #else 2001 vsprintf (msg_buf, format, args); 2002 msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */ 2003 #endif 2004 va_end (args); 2005 2006 if (saved_local_prompt == 0) 2007 { 2008 rl_save_prompt (); 2009 msg_saved_prompt = 1; 2010 } 2011 rl_display_prompt = msg_buf; 2012 local_prompt = expand_prompt (msg_buf, &prompt_visible_length, 2013 &prompt_last_invisible, 2014 &prompt_invis_chars_first_line, 2015 &prompt_physical_chars); 2016 local_prompt_prefix = (char *)NULL; 2017 local_prompt_len = local_prompt ? strlen (local_prompt) : 0; 2018 (*rl_redisplay_function) (); 2019 2020 return 0; 2021 } 2022 #else /* !USE_VARARGS */ 2023 int 2024 rl_message (format, arg1, arg2) 2025 char *format; 2026 { 2027 sprintf (msg_buf, format, arg1, arg2); 2028 msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */ 2029 2030 rl_display_prompt = msg_buf; 2031 if (saved_local_prompt == 0) 2032 { 2033 rl_save_prompt (); 2034 msg_saved_prompt = 1; 2035 } 2036 local_prompt = expand_prompt (msg_buf, &prompt_visible_length, 2037 &prompt_last_invisible, 2038 &prompt_invis_chars_first_line, 2039 &prompt_physical_chars); 2040 local_prompt_prefix = (char *)NULL; 2041 local_prompt_len = local_prompt ? strlen (local_prompt) : 0; 2042 (*rl_redisplay_function) (); 2043 2044 return 0; 2045 } 2046 #endif /* !USE_VARARGS */ 2047 2048 /* How to clear things from the "echo-area". */ 2049 int 2050 rl_clear_message () 2051 { 2052 rl_display_prompt = rl_prompt; 2053 if (msg_saved_prompt) 2054 { 2055 rl_restore_prompt (); 2056 msg_saved_prompt = 0; 2057 } 2058 (*rl_redisplay_function) (); 2059 return 0; 2060 } 2061 2062 int 2063 rl_reset_line_state () 2064 { 2065 rl_on_new_line (); 2066 2067 rl_display_prompt = rl_prompt ? rl_prompt : ""; 2068 forced_display = 1; 2069 return 0; 2070 } 2071 2072 void 2073 rl_save_prompt () 2074 { 2075 saved_local_prompt = local_prompt; 2076 saved_local_prefix = local_prompt_prefix; 2077 saved_prefix_length = prompt_prefix_length; 2078 saved_local_length = local_prompt_len; 2079 saved_last_invisible = prompt_last_invisible; 2080 saved_visible_length = prompt_visible_length; 2081 saved_invis_chars_first_line = prompt_invis_chars_first_line; 2082 saved_physical_chars = prompt_physical_chars; 2083 2084 local_prompt = local_prompt_prefix = (char *)0; 2085 local_prompt_len = 0; 2086 prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0; 2087 prompt_invis_chars_first_line = prompt_physical_chars = 0; 2088 } 2089 2090 void 2091 rl_restore_prompt () 2092 { 2093 FREE (local_prompt); 2094 FREE (local_prompt_prefix); 2095 2096 local_prompt = saved_local_prompt; 2097 local_prompt_prefix = saved_local_prefix; 2098 local_prompt_len = saved_local_length; 2099 prompt_prefix_length = saved_prefix_length; 2100 prompt_last_invisible = saved_last_invisible; 2101 prompt_visible_length = saved_visible_length; 2102 prompt_invis_chars_first_line = saved_invis_chars_first_line; 2103 prompt_physical_chars = saved_physical_chars; 2104 2105 /* can test saved_local_prompt to see if prompt info has been saved. */ 2106 saved_local_prompt = saved_local_prefix = (char *)0; 2107 saved_local_length = 0; 2108 saved_last_invisible = saved_visible_length = saved_prefix_length = 0; 2109 saved_invis_chars_first_line = saved_physical_chars = 0; 2110 } 2111 2112 char * 2113 _rl_make_prompt_for_search (pchar) 2114 int pchar; 2115 { 2116 int len; 2117 char *pmt, *p; 2118 2119 rl_save_prompt (); 2120 2121 /* We've saved the prompt, and can do anything with the various prompt 2122 strings we need before they're restored. We want the unexpanded 2123 portion of the prompt string after any final newline. */ 2124 p = rl_prompt ? strrchr (rl_prompt, '\n') : 0; 2125 if (p == 0) 2126 { 2127 len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0; 2128 pmt = (char *)xmalloc (len + 2); 2129 if (len) 2130 strcpy (pmt, rl_prompt); 2131 pmt[len] = pchar; 2132 pmt[len+1] = '\0'; 2133 } 2134 else 2135 { 2136 p++; 2137 len = strlen (p); 2138 pmt = (char *)xmalloc (len + 2); 2139 if (len) 2140 strcpy (pmt, p); 2141 pmt[len] = pchar; 2142 pmt[len+1] = '\0'; 2143 } 2144 2145 /* will be overwritten by expand_prompt, called from rl_message */ 2146 prompt_physical_chars = saved_physical_chars + 1; 2147 return pmt; 2148 } 2149 2150 /* Quick redisplay hack when erasing characters at the end of the line. */ 2151 void 2152 _rl_erase_at_end_of_line (l) 2153 int l; 2154 { 2155 register int i; 2156 2157 _rl_backspace (l); 2158 for (i = 0; i < l; i++) 2159 putc (' ', rl_outstream); 2160 _rl_backspace (l); 2161 for (i = 0; i < l; i++) 2162 visible_line[--_rl_last_c_pos] = '\0'; 2163 rl_display_fixed++; 2164 } 2165 2166 /* Clear to the end of the line. COUNT is the minimum 2167 number of character spaces to clear, */ 2168 void 2169 _rl_clear_to_eol (count) 2170 int count; 2171 { 2172 if (_rl_term_clreol) 2173 tputs (_rl_term_clreol, 1, _rl_output_character_function); 2174 else if (count) 2175 space_to_eol (count); 2176 } 2177 2178 /* Clear to the end of the line using spaces. COUNT is the minimum 2179 number of character spaces to clear, */ 2180 static void 2181 space_to_eol (count) 2182 int count; 2183 { 2184 register int i; 2185 2186 for (i = 0; i < count; i++) 2187 putc (' ', rl_outstream); 2188 2189 _rl_last_c_pos += count; 2190 } 2191 2192 void 2193 _rl_clear_screen () 2194 { 2195 if (_rl_term_clrpag) 2196 tputs (_rl_term_clrpag, 1, _rl_output_character_function); 2197 else 2198 rl_crlf (); 2199 } 2200 2201 /* Insert COUNT characters from STRING to the output stream at column COL. */ 2202 static void 2203 insert_some_chars (string, count, col) 2204 char *string; 2205 int count, col; 2206 { 2207 #if defined (__MSDOS__) || defined (__MINGW32__) 2208 _rl_output_some_chars (string, count); 2209 #else 2210 /* DEBUGGING */ 2211 if (MB_CUR_MAX == 1 || rl_byte_oriented) 2212 if (count != col) 2213 fprintf(stderr, "readline: debug: insert_some_chars: count (%d) != col (%d)\n", count, col); 2214 2215 /* If IC is defined, then we do not have to "enter" insert mode. */ 2216 if (_rl_term_IC) 2217 { 2218 char *buffer; 2219 2220 buffer = tgoto (_rl_term_IC, 0, col); 2221 tputs (buffer, 1, _rl_output_character_function); 2222 _rl_output_some_chars (string, count); 2223 } 2224 else 2225 { 2226 register int i; 2227 2228 /* If we have to turn on insert-mode, then do so. */ 2229 if (_rl_term_im && *_rl_term_im) 2230 tputs (_rl_term_im, 1, _rl_output_character_function); 2231 2232 /* If there is a special command for inserting characters, then 2233 use that first to open up the space. */ 2234 if (_rl_term_ic && *_rl_term_ic) 2235 { 2236 for (i = col; i--; ) 2237 tputs (_rl_term_ic, 1, _rl_output_character_function); 2238 } 2239 2240 /* Print the text. */ 2241 _rl_output_some_chars (string, count); 2242 2243 /* If there is a string to turn off insert mode, we had best use 2244 it now. */ 2245 if (_rl_term_ei && *_rl_term_ei) 2246 tputs (_rl_term_ei, 1, _rl_output_character_function); 2247 } 2248 #endif /* __MSDOS__ || __MINGW32__ */ 2249 } 2250 2251 /* Delete COUNT characters from the display line. */ 2252 static void 2253 delete_chars (count) 2254 int count; 2255 { 2256 if (count > _rl_screenwidth) /* XXX */ 2257 return; 2258 2259 #if !defined (__MSDOS__) && !defined (__MINGW32__) 2260 if (_rl_term_DC && *_rl_term_DC) 2261 { 2262 char *buffer; 2263 buffer = tgoto (_rl_term_DC, count, count); 2264 tputs (buffer, count, _rl_output_character_function); 2265 } 2266 else 2267 { 2268 if (_rl_term_dc && *_rl_term_dc) 2269 while (count--) 2270 tputs (_rl_term_dc, 1, _rl_output_character_function); 2271 } 2272 #endif /* !__MSDOS__ && !__MINGW32__ */ 2273 } 2274 2275 void 2276 _rl_update_final () 2277 { 2278 int full_lines; 2279 2280 full_lines = 0; 2281 /* If the cursor is the only thing on an otherwise-blank last line, 2282 compensate so we don't print an extra CRLF. */ 2283 if (_rl_vis_botlin && _rl_last_c_pos == 0 && 2284 visible_line[vis_lbreaks[_rl_vis_botlin]] == 0) 2285 { 2286 _rl_vis_botlin--; 2287 full_lines = 1; 2288 } 2289 _rl_move_vert (_rl_vis_botlin); 2290 /* If we've wrapped lines, remove the final xterm line-wrap flag. */ 2291 if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == _rl_screenwidth)) 2292 { 2293 char *last_line; 2294 2295 last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]]; 2296 cpos_buffer_position = -1; /* don't know where we are in buffer */ 2297 _rl_move_cursor_relative (_rl_screenwidth - 1, last_line); /* XXX */ 2298 _rl_clear_to_eol (0); 2299 putc (last_line[_rl_screenwidth - 1], rl_outstream); 2300 } 2301 _rl_vis_botlin = 0; 2302 rl_crlf (); 2303 fflush (rl_outstream); 2304 rl_display_fixed++; 2305 } 2306 2307 /* Move to the start of the current line. */ 2308 static void 2309 cr () 2310 { 2311 if (_rl_term_cr) 2312 { 2313 #if defined (__MSDOS__) 2314 putc ('\r', rl_outstream); 2315 #else 2316 tputs (_rl_term_cr, 1, _rl_output_character_function); 2317 #endif 2318 _rl_last_c_pos = 0; 2319 } 2320 } 2321 2322 /* Redraw the last line of a multi-line prompt that may possibly contain 2323 terminal escape sequences. Called with the cursor at column 0 of the 2324 line to draw the prompt on. */ 2325 static void 2326 redraw_prompt (t) 2327 char *t; 2328 { 2329 char *oldp; 2330 2331 oldp = rl_display_prompt; 2332 rl_save_prompt (); 2333 2334 rl_display_prompt = t; 2335 local_prompt = expand_prompt (t, &prompt_visible_length, 2336 &prompt_last_invisible, 2337 &prompt_invis_chars_first_line, 2338 &prompt_physical_chars); 2339 local_prompt_prefix = (char *)NULL; 2340 local_prompt_len = local_prompt ? strlen (local_prompt) : 0; 2341 2342 rl_forced_update_display (); 2343 2344 rl_display_prompt = oldp; 2345 rl_restore_prompt(); 2346 } 2347 2348 /* Redisplay the current line after a SIGWINCH is received. */ 2349 void 2350 _rl_redisplay_after_sigwinch () 2351 { 2352 char *t; 2353 2354 /* Clear the current line and put the cursor at column 0. Make sure 2355 the right thing happens if we have wrapped to a new screen line. */ 2356 if (_rl_term_cr) 2357 { 2358 #if defined (__MSDOS__) 2359 putc ('\r', rl_outstream); 2360 #else 2361 tputs (_rl_term_cr, 1, _rl_output_character_function); 2362 #endif 2363 _rl_last_c_pos = 0; 2364 #if defined (__MSDOS__) 2365 space_to_eol (_rl_screenwidth); 2366 putc ('\r', rl_outstream); 2367 #else 2368 if (_rl_term_clreol) 2369 tputs (_rl_term_clreol, 1, _rl_output_character_function); 2370 else 2371 { 2372 space_to_eol (_rl_screenwidth); 2373 tputs (_rl_term_cr, 1, _rl_output_character_function); 2374 } 2375 #endif 2376 if (_rl_last_v_pos > 0) 2377 _rl_move_vert (0); 2378 } 2379 else 2380 rl_crlf (); 2381 2382 /* Redraw only the last line of a multi-line prompt. */ 2383 t = strrchr (rl_display_prompt, '\n'); 2384 if (t) 2385 redraw_prompt (++t); 2386 else 2387 rl_forced_update_display (); 2388 } 2389 2390 void 2391 _rl_clean_up_for_exit () 2392 { 2393 if (readline_echoing_p) 2394 { 2395 _rl_move_vert (_rl_vis_botlin); 2396 _rl_vis_botlin = 0; 2397 fflush (rl_outstream); 2398 rl_restart_output (1, 0); 2399 } 2400 } 2401 2402 void 2403 _rl_erase_entire_line () 2404 { 2405 cr (); 2406 _rl_clear_to_eol (0); 2407 cr (); 2408 fflush (rl_outstream); 2409 } 2410 2411 /* return the `current display line' of the cursor -- the number of lines to 2412 move up to get to the first screen line of the current readline line. */ 2413 int 2414 _rl_current_display_line () 2415 { 2416 int ret, nleft; 2417 2418 /* Find out whether or not there might be invisible characters in the 2419 editing buffer. */ 2420 if (rl_display_prompt == rl_prompt) 2421 nleft = _rl_last_c_pos - _rl_screenwidth - rl_visible_prompt_length; 2422 else 2423 nleft = _rl_last_c_pos - _rl_screenwidth; 2424 2425 if (nleft > 0) 2426 ret = 1 + nleft / _rl_screenwidth; 2427 else 2428 ret = 0; 2429 2430 return ret; 2431 } 2432 2433 #if defined (HANDLE_MULTIBYTE) 2434 /* Calculate the number of screen columns occupied by STR from START to END. 2435 In the case of multibyte characters with stateful encoding, we have to 2436 scan from the beginning of the string to take the state into account. */ 2437 static int 2438 _rl_col_width (str, start, end) 2439 const char *str; 2440 int start, end; 2441 { 2442 wchar_t wc; 2443 mbstate_t ps; 2444 int tmp, point, width, max; 2445 2446 if (end <= start) 2447 return 0; 2448 if (MB_CUR_MAX == 1 || rl_byte_oriented) 2449 return (end - start); 2450 2451 memset (&ps, 0, sizeof (mbstate_t)); 2452 2453 point = 0; 2454 max = end; 2455 2456 while (point < start) 2457 { 2458 tmp = mbrlen (str + point, max, &ps); 2459 if (MB_INVALIDCH ((size_t)tmp)) 2460 { 2461 /* In this case, the bytes are invalid or too short to compose a 2462 multibyte character, so we assume that the first byte represents 2463 a single character. */ 2464 point++; 2465 max--; 2466 2467 /* Clear the state of the byte sequence, because in this case the 2468 effect of mbstate is undefined. */ 2469 memset (&ps, 0, sizeof (mbstate_t)); 2470 } 2471 else if (MB_NULLWCH (tmp)) 2472 break; /* Found '\0' */ 2473 else 2474 { 2475 point += tmp; 2476 max -= tmp; 2477 } 2478 } 2479 2480 /* If START is not a byte that starts a character, then POINT will be 2481 greater than START. In this case, assume that (POINT - START) gives 2482 a byte count that is the number of columns of difference. */ 2483 width = point - start; 2484 2485 while (point < end) 2486 { 2487 tmp = mbrtowc (&wc, str + point, max, &ps); 2488 if (MB_INVALIDCH ((size_t)tmp)) 2489 { 2490 /* In this case, the bytes are invalid or too short to compose a 2491 multibyte character, so we assume that the first byte represents 2492 a single character. */ 2493 point++; 2494 max--; 2495 2496 /* and assume that the byte occupies a single column. */ 2497 width++; 2498 2499 /* Clear the state of the byte sequence, because in this case the 2500 effect of mbstate is undefined. */ 2501 memset (&ps, 0, sizeof (mbstate_t)); 2502 } 2503 else if (MB_NULLWCH (tmp)) 2504 break; /* Found '\0' */ 2505 else 2506 { 2507 point += tmp; 2508 max -= tmp; 2509 tmp = wcwidth(wc); 2510 width += (tmp >= 0) ? tmp : 1; 2511 } 2512 } 2513 2514 width += point - end; 2515 2516 return width; 2517 } 2518 #endif /* HANDLE_MULTIBYTE */ -
lib/readline/input.c
diff -Naur bash-3.2.orig/lib/readline/input.c bash-3.2/lib/readline/input.c
old new 133 133 return (0); 134 134 135 135 *key = ibuffer[pop_index++]; 136 136 #if 0 137 137 if (pop_index >= ibuffer_len) 138 #else 139 if (pop_index > ibuffer_len) 140 #endif 138 141 pop_index = 0; 139 142 140 143 return (1); … … 151 154 { 152 155 pop_index--; 153 156 if (pop_index < 0) 154 pop_index = ibuffer_len - 1;157 pop_index = ibuffer_len; 155 158 ibuffer[pop_index] = key; 156 159 return (1); 157 160 } … … 250 253 while (chars_avail--) 251 254 { 252 255 k = (*rl_getc_function) (rl_instream); 253 rl_stuff_char (k); 256 if (rl_stuff_char (k) == 0) 257 break; /* some problem; no more room */ 254 258 if (k == NEWLINE || k == RETURN) 255 259 break; 256 260 } … … 373 377 RL_SETSTATE (RL_STATE_INPUTPENDING); 374 378 } 375 379 ibuffer[push_index++] = key; 380 #if 0 376 381 if (push_index >= ibuffer_len) 382 #else 383 if (push_index > ibuffer_len) 384 #endif 377 385 push_index = 0; 378 386 379 387 return 1; … … 513 521 char *mbchar; 514 522 int size; 515 523 { 516 int mb_len = 0;524 int mb_len, c; 517 525 size_t mbchar_bytes_length; 518 526 wchar_t wc; 519 527 mbstate_t ps, ps_back; 520 528 521 529 memset(&ps, 0, sizeof (mbstate_t)); 522 530 memset(&ps_back, 0, sizeof (mbstate_t)); 523 531 532 mb_len = 0; 524 533 while (mb_len < size) 525 534 { 526 535 RL_SETSTATE(RL_STATE_MOREINPUT); 527 mbchar[mb_len++]= rl_read_key ();536 c = rl_read_key (); 528 537 RL_UNSETSTATE(RL_STATE_MOREINPUT); 529 538 539 if (c < 0) 540 break; 541 542 mbchar[mb_len++] = c; 543 530 544 mbchar_bytes_length = mbrtowc (&wc, mbchar, mb_len, &ps); 531 545 if (mbchar_bytes_length == (size_t)(-1)) 532 546 break; /* invalid byte sequence for the current locale */ … … 564 578 565 579 c = first; 566 580 memset (mb, 0, mlen); 567 for (i = 0; i < mlen; i++)581 for (i = 0; c >= 0 && i < mlen; i++) 568 582 { 569 583 mb[i] = (char)c; 570 584 memset (&ps, 0, sizeof (mbstate_t)); -
lib/readline/isearch.c
diff -Naur bash-3.2.orig/lib/readline/isearch.c bash-3.2/lib/readline/isearch.c
old new 327 327 rl_command_func_t *f; 328 328 329 329 f = (rl_command_func_t *)NULL; 330 331 /* Translate the keys we do something with to opcodes. */ 330 331 if (c < 0) 332 { 333 cxt->sflags |= SF_FAILED; 334 cxt->history_pos = cxt->last_found_line; 335 return -1; 336 } 337 338 /* Translate the keys we do something with to opcodes. */ 332 339 if (c >= 0 && _rl_keymap[c].type == ISFUNC) 333 340 { 334 341 f = _rl_keymap[c].function; -
lib/readline/misc.c
diff -Naur bash-3.2.orig/lib/readline/misc.c bash-3.2/lib/readline/misc.c
old new 146 146 rl_restore_prompt (); 147 147 rl_clear_message (); 148 148 RL_UNSETSTATE(RL_STATE_NUMERICARG); 149 if (key < 0) 150 return -1; 149 151 return (_rl_dispatch (key, _rl_keymap)); 150 152 } 151 153 } -
lib/readline/readline.c
diff -Naur bash-3.2.orig/lib/readline/readline.c bash-3.2/lib/readline/readline.c
old new 645 645 if ((cxt->flags & KSEQ_DISPATCHED) == 0) 646 646 { 647 647 nkey = _rl_subseq_getchar (cxt->okey); 648 if (nkey < 0) 649 { 650 _rl_abort_internal (); 651 return -1; 652 } 648 653 r = _rl_dispatch_subseq (nkey, cxt->dmap, cxt->subseq_arg); 649 654 cxt->flags |= KSEQ_DISPATCHED; 650 655 } -
lib/readline/text.c
diff -Naur bash-3.2.orig/lib/readline/text.c bash-3.2/lib/readline/text.c
old new 857 857 c = rl_read_key (); 858 858 RL_UNSETSTATE(RL_STATE_MOREINPUT); 859 859 860 if (c < 0) 861 return -1; 862 860 863 #if defined (HANDLE_SIGNALS) 861 864 if (RL_ISSTATE (RL_STATE_CALLBACK) == 0) 862 865 _rl_restore_tty_signals (); … … 1520 1523 1521 1524 mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX); 1522 1525 1526 if (mb_len <= 0) 1527 return -1; 1528 1523 1529 if (count < 0) 1524 1530 return (_rl_char_search_internal (-count, bdir, mbchar, mb_len)); 1525 1531 else … … 1536 1542 c = rl_read_key (); 1537 1543 RL_UNSETSTATE(RL_STATE_MOREINPUT); 1538 1544 1545 if (c < 0) 1546 return -1; 1547 1539 1548 if (count < 0) 1540 1549 return (_rl_char_search_internal (-count, bdir, c)); 1541 1550 else -
lib/readline/vi_mode.c
diff -Naur bash-3.2.orig/lib/readline/vi_mode.c bash-3.2/lib/readline/vi_mode.c
old new 886 886 RL_SETSTATE(RL_STATE_MOREINPUT); 887 887 c = rl_read_key (); 888 888 RL_UNSETSTATE(RL_STATE_MOREINPUT); 889 890 if (c < 0) 891 { 892 *nextkey = 0; 893 return -1; 894 } 895 889 896 *nextkey = c; 890 897 891 898 if (!member (c, vi_motion)) … … 902 909 RL_SETSTATE(RL_STATE_MOREINPUT); 903 910 c = rl_read_key (); /* real command */ 904 911 RL_UNSETSTATE(RL_STATE_MOREINPUT); 912 if (c < 0) 913 { 914 *nextkey = 0; 915 return -1; 916 } 905 917 *nextkey = c; 906 918 } 907 919 else if (key == c && (key == 'd' || key == 'y' || key == 'c')) … … 1224 1236 _rl_vi_callback_char_search (data) 1225 1237 _rl_callback_generic_arg *data; 1226 1238 { 1239 int c; 1227 1240 #if defined (HANDLE_MULTIBYTE) 1228 _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);1241 c = _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX); 1229 1242 #else 1230 1243 RL_SETSTATE(RL_STATE_MOREINPUT); 1231 _rl_vi_last_search_char= rl_read_key ();1244 c = rl_read_key (); 1232 1245 RL_UNSETSTATE(RL_STATE_MOREINPUT); 1233 1246 #endif 1234 1247 1248 if (c <= 0) 1249 return -1; 1250 1251 #if !defined (HANDLE_MULTIBYTE) 1252 _rl_vi_last_search_char = c; 1253 #endif 1254 1235 1255 _rl_callback_func = 0; 1236 1256 _rl_want_redisplay = 1; 1237 1257 … … 1247 1267 rl_vi_char_search (count, key) 1248 1268 int count, key; 1249 1269 { 1270 int c; 1250 1271 #if defined (HANDLE_MULTIBYTE) 1251 1272 static char *target; 1252 1273 static int tlen; … … 1293 1314 else 1294 1315 { 1295 1316 #if defined (HANDLE_MULTIBYTE) 1296 _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX); 1317 c = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX); 1318 if (c <= 0) 1319 return -1; 1320 _rl_vi_last_search_mblen = c; 1297 1321 #else 1298 1322 RL_SETSTATE(RL_STATE_MOREINPUT); 1299 _rl_vi_last_search_char= rl_read_key ();1323 c = rl_read_key (); 1300 1324 RL_UNSETSTATE(RL_STATE_MOREINPUT); 1325 if (c < 0) 1326 return -1; 1327 _rl_vi_last_search_char = c; 1301 1328 #endif 1302 1329 } 1303 1330 } … … 1467 1494 c = rl_read_key (); 1468 1495 RL_UNSETSTATE(RL_STATE_MOREINPUT); 1469 1496 1497 if (c < 0) 1498 return -1; 1499 1470 1500 #if defined (HANDLE_MULTIBYTE) 1471 1501 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 1472 1502 c = _rl_read_mbstring (c, mb, mlen); … … 1485 1515 1486 1516 _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX); 1487 1517 1518 if (c < 0) 1519 return -1; 1520 1488 1521 _rl_callback_func = 0; 1489 1522 _rl_want_redisplay = 1; 1490 1523 … … 1516 1549 else 1517 1550 _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX); 1518 1551 1552 if (c < 0) 1553 return -1; 1554 1519 1555 return (_rl_vi_change_char (count, c, mb)); 1520 1556 } 1521 1557 … … 1650 1686 ch = rl_read_key (); 1651 1687 RL_UNSETSTATE(RL_STATE_MOREINPUT); 1652 1688 1653 if (ch < 'a' || ch > 'z')1689 if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */ 1654 1690 { 1655 1691 rl_ding (); 1656 1692 return -1; … … 1702 1738 rl_point = rl_mark; 1703 1739 return 0; 1704 1740 } 1705 else if (ch < 'a' || ch > 'z')1741 else if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */ 1706 1742 { 1707 1743 rl_ding (); 1708 1744 return -1; -
lib/sh/snprintf.c
diff -Naur bash-3.2.orig/lib/sh/snprintf.c bash-3.2/lib/sh/snprintf.c
old new 471 471 10^x ~= r 472 472 * log_10(200) = 2; 473 473 * log_10(250) = 2; 474 * 475 * NOTE: do not call this with r == 0 -- an infinite loop results. 474 476 */ 475 477 static int 476 478 log_10(r) … … 576 578 { 577 579 integral_part[0] = '0'; 578 580 integral_part[1] = '\0'; 579 fraction_part[0] = '0'; 580 fraction_part[1] = '\0'; 581 /* The fractional part has to take the precision into account */ 582 for (ch = 0; ch < precision-1; ch++) 583 fraction_part[ch] = '0'; 584 fraction_part[ch] = '0'; 585 fraction_part[ch+1] = '\0'; 581 586 if (fract) 582 587 *fract = fraction_part; 583 588 return integral_part; … … 663 668 p->flags &= ~PF_ZEROPAD; 664 669 665 670 sd = d; /* signed for ' ' padding in base 10 */ 666 flags = (*p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0; 671 flags = 0; 672 flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0; 667 673 if (*p->pf == 'X') 668 674 flags |= FL_HEXUPPER; 669 675 … … 733 739 p->flags &= ~PF_ZEROPAD; 734 740 735 741 sd = d; /* signed for ' ' padding in base 10 */ 736 flags = (*p->pf == ' u' || *p->pf == 'U') ? FL_UNSIGNED : 0;742 flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0; 737 743 if (*p->pf == 'X') 738 744 flags |= FL_HEXUPPER; 739 745 … … 805 811 PUT_CHAR(*tmp, p); 806 812 tmp++; 807 813 } 814 808 815 PAD_LEFT(p); 809 816 } 810 817 … … 972 979 if ((p->flags & PF_THOUSANDS) && grouping && (t = groupnum (tmp))) 973 980 tmp = t; 974 981 982 if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0) 983 { 984 /* smash the trailing zeros unless altform */ 985 for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--) 986 tmp2[i] = '\0'; 987 if (tmp2[0] == '\0') 988 p->precision = 0; 989 } 990 975 991 /* calculate the padding. 1 for the dot */ 976 992 p->width = p->width - 977 993 ((d > 0. && p->justify == RIGHT) ? 1:0) - 978 994 ((p->flags & PF_SPACE) ? 1:0) - 979 strlen(tmp) - p->precision - 1; 995 strlen(tmp) - p->precision - 996 ((p->precision != 0 || (p->flags & PF_ALTFORM)) ? 1 : 0); /* radix char */ 980 997 PAD_RIGHT(p); 981 998 PUT_PLUS(d, p, 0.); 982 999 PUT_SPACE(d, p, 0.); … … 991 1008 if (p->precision != 0 || (p->flags & PF_ALTFORM)) 992 1009 PUT_CHAR(decpoint, p); /* put the '.' */ 993 1010 994 if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0)995 /* smash the trailing zeros unless altform */996 for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)997 tmp2[i] = '\0';998 999 1011 for (; *tmp2; tmp2++) 1000 1012 PUT_CHAR(*tmp2, p); /* the fraction */ 1001 1013 … … 1011 1023 char *tmp, *tmp2; 1012 1024 int j, i; 1013 1025 1014 if ( chkinfnan(p, d, 1) || chkinfnan(p, d, 2))1026 if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2))) 1015 1027 return; /* already printed nan or inf */ 1016 1028 1017 1029 GETLOCALEDATA(decpoint, thoussep, grouping); 1018 1030 DEF_PREC(p); 1019 j = log_10(d); 1020 d = d / pow_10(j); /* get the Mantissa */ 1021 d = ROUND(d, p); 1031 if (d == 0.) 1032 j = 0; 1033 else 1034 { 1035 j = log_10(d); 1036 d = d / pow_10(j); /* get the Mantissa */ 1037 d = ROUND(d, p); 1038 } 1022 1039 tmp = dtoa(d, p->precision, &tmp2); 1023 1040 1024 1041 /* 1 for unit, 1 for the '.', 1 for 'e|E', … … 1076 1093 PUT_CHAR(*tmp, p); 1077 1094 tmp++; 1078 1095 } 1096 1079 1097 PAD_LEFT(p); 1080 1098 } 1081 1099 #endif … … 1358 1376 STAR_ARGS(data); 1359 1377 DEF_PREC(data); 1360 1378 d = GETDOUBLE(data); 1361 i = log_10(d);1379 i = (d != 0.) ? log_10(d) : -1; 1362 1380 /* 1363 1381 * for '%g|%G' ANSI: use f if exponent 1364 1382 * is in the range or [-4,p] exclusively -
parse.y
diff -Naur bash-3.2.orig/parse.y bash-3.2/parse.y
old new 1029 1029 #define PST_CMDTOKEN 0x1000 /* command token OK - unused */ 1030 1030 #define PST_COMPASSIGN 0x2000 /* parsing x=(...) compound assignment */ 1031 1031 #define PST_ASSIGNOK 0x4000 /* assignment statement ok in this context */ 1032 #define PST_REGEXP 0x8000 /* parsing an ERE/BRE as a single word */ 1032 1033 1033 1034 /* Initial size to allocate for tokens, and the 1034 1035 amount to grow them by. */ … … 2591 2592 return (character); 2592 2593 } 2593 2594 2595 if (parser_state & PST_REGEXP) 2596 goto tokword; 2597 2594 2598 /* Shell meta-characters. */ 2595 2599 if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0)) 2596 2600 { … … 2698 2702 if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND)) 2699 2703 return (character); 2700 2704 2705 tokword: 2701 2706 /* Okay, if we got this far, we have to read a word. Read one, 2702 2707 and then check it against the known ones. */ 2703 2708 result = read_token_word (character); … … 2735 2740 /* itrace("parse_matched_pair: open = %c close = %c", open, close); */ 2736 2741 count = 1; 2737 2742 pass_next_character = backq_backslash = was_dollar = in_comment = 0; 2738 check_comment = (flags & P_COMMAND) && qc != ' \'' && qc != '"' && (flags & P_DQUOTE) == 0;2743 check_comment = (flags & P_COMMAND) && qc != '`' && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0; 2739 2744 2740 2745 /* RFLAGS is the set of flags we want to pass to recursive calls. */ 2741 2746 rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE); … … 3202 3207 if (tok == WORD && test_binop (yylval.word->word)) 3203 3208 op = yylval.word; 3204 3209 #if defined (COND_REGEXP) 3205 else if (tok == WORD && STREQ (yylval.word->word,"=~")) 3206 op = yylval.word; 3210 else if (tok == WORD && STREQ (yylval.word->word, "=~")) 3211 { 3212 op = yylval.word; 3213 parser_state |= PST_REGEXP; 3214 } 3207 3215 #endif 3208 3216 else if (tok == '<' || tok == '>') 3209 3217 op = make_word_from_token (tok); /* ( */ … … 3234 3242 3235 3243 /* rhs */ 3236 3244 tok = read_token (READ); 3245 parser_state &= ~PST_REGEXP; 3237 3246 if (tok == WORD) 3238 3247 { 3239 3248 tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL); … … 3367 3376 if (pass_next_character) 3368 3377 { 3369 3378 pass_next_character = 0; 3370 goto got_ character;3379 goto got_escaped_character; 3371 3380 } 3372 3381 3373 3382 cd = current_delimiter (dstack); … … 3419 3428 goto next_character; 3420 3429 } 3421 3430 3431 #ifdef COND_REGEXP 3432 /* When parsing a regexp as a single word inside a conditional command, 3433 we need to special-case characters special to both the shell and 3434 regular expressions. Right now, that is only '(' and '|'. */ /*)*/ 3435 if MBTEST((parser_state & PST_REGEXP) && (character == '(' || character == '|')) /*)*/ 3436 { 3437 if (character == '|') 3438 goto got_character; 3439 3440 push_delimiter (dstack, character); 3441 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0); 3442 pop_delimiter (dstack); 3443 if (ttok == &matched_pair_error) 3444 return -1; /* Bail immediately. */ 3445 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2, 3446 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE); 3447 token[token_index++] = character; 3448 strcpy (token + token_index, ttok); 3449 token_index += ttoklen; 3450 FREE (ttok); 3451 dollar_present = all_digit_token = 0; 3452 goto next_character; 3453 } 3454 #endif /* COND_REGEXP */ 3455 3422 3456 #ifdef EXTENDED_GLOB 3423 3457 /* Parse a ksh-style extended pattern matching specification. */ 3424 if (extended_glob && PATTERN_CHAR (character))3458 if MBTEST(extended_glob && PATTERN_CHAR (character)) 3425 3459 { 3426 3460 peek_char = shell_getc (1); 3427 3461 if MBTEST(peek_char == '(') /* ) */ … … 3616 3650 3617 3651 got_character: 3618 3652 3619 all_digit_token &= DIGIT (character);3620 dollar_present |= character == '$';3621 3622 3653 if (character == CTLESC || character == CTLNUL) 3623 3654 token[token_index++] = CTLESC; 3624 3655 3656 got_escaped_character: 3657 3658 all_digit_token &= DIGIT (character); 3659 dollar_present |= character == '$'; 3660 3625 3661 token[token_index++] = character; 3626 3662 3627 3663 RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size, -
patchlevel.h
diff -Naur bash-3.2.orig/patchlevel.h bash-3.2/patchlevel.h
old new 25 25 regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh 26 26 looks for to find the patch level (for the sccs version string). */ 27 27 28 #define PATCHLEVEL 028 #define PATCHLEVEL 33 29 29 30 30 #endif /* _PATCHLEVEL_H_ */ -
pathexp.c
diff -Naur bash-3.2.orig/pathexp.c bash-3.2/pathexp.c
old new 1 1 /* pathexp.c -- The shell interface to the globbing library. */ 2 2 3 /* Copyright (C) 1995-200 2Free Software Foundation, Inc.3 /* Copyright (C) 1995-2007 Free Software Foundation, Inc. 4 4 5 5 This file is part of GNU Bash, the Bourne Again SHell. 6 6 … … 110 110 return (0); 111 111 } 112 112 113 /* Return 1 if C is a character that is `special' in a POSIX ERE and needs to 114 be quoted to match itself. */ 115 static inline int 116 ere_char (c) 117 int c; 118 { 119 switch (c) 120 { 121 case '.': 122 case '[': 123 case '\\': 124 case '(': 125 case ')': 126 case '*': 127 case '+': 128 case '?': 129 case '{': 130 case '|': 131 case '^': 132 case '$': 133 return 1; 134 default: 135 return 0; 136 } 137 return (0); 138 } 139 113 140 /* PATHNAME can contain characters prefixed by CTLESC; this indicates 114 141 that the character is to be quoted. We quote it here in the style 115 142 that the glob library recognizes. If flags includes QGLOB_CVTNULL, … … 142 169 { 143 170 if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/') 144 171 continue; 172 if ((qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0) 173 continue; 145 174 temp[j++] = '\\'; 146 175 i++; 147 176 if (pathname[i] == '\0') -
pathexp.h
diff -Naur bash-3.2.orig/pathexp.h bash-3.2/pathexp.h
old new 1 1 /* pathexp.h -- The shell interface to the globbing library. */ 2 2 3 /* Copyright (C) 1987-200 5Free Software Foundation, Inc.3 /* Copyright (C) 1987-2007 Free Software Foundation, Inc. 4 4 5 5 This file is part of GNU Bash, the Bourne Again SHell. 6 6 … … 32 32 /* Flag values for quote_string_for_globbing */ 33 33 #define QGLOB_CVTNULL 0x01 /* convert QUOTED_NULL strings to '\0' */ 34 34 #define QGLOB_FILENAME 0x02 /* do correct quoting for matching filenames */ 35 #define QGLOB_REGEXP 0x04 /* quote an ERE for regcomp/regexec */ 35 36 36 37 #if defined (EXTENDED_GLOB) 37 38 /* Flags to OR with other flag args to strmatch() to enabled the extended -
po/ru.po
diff -Naur bash-3.2.orig/po/ru.po bash-3.2/po/ru.po
old new 12 12 "Last-Translator: Evgeniy Dushistov <dushistov@mail.ru>\n" 13 13 "Language-Team: Russian <ru@li.org>\n" 14 14 "MIME-Version: 1.0\n" 15 "Content-Type: text/plain; charset= UTF-8\n"15 "Content-Type: text/plain; charset=KOI8-R\n" 16 16 "Content-Transfer-Encoding: 8bit\n" 17 17 "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" 18 18 -
bash-3.2
diff -Naur bash-3.2.orig/sig.c bash-3.2/sig.c
old new 350 350 #undef XSIG 351 351 #undef XHANDLER 352 352 353 /* Run some of the cleanups that should be performed when we run 354 jump_to_top_level from a builtin command context. XXX - might want to 355 also call reset_parser here. */ 356 void 357 top_level_cleanup () 358 { 359 /* Clean up string parser environment. */ 360 while (parse_and_execute_level) 361 parse_and_execute_cleanup (); 362 363 #if defined (PROCESS_SUBSTITUTION) 364 unlink_fifo_list (); 365 #endif /* PROCESS_SUBSTITUTION */ 366 367 run_unwind_protects (); 368 loop_level = continuing = breaking = 0; 369 return_catch_flag = 0; 370 } 371 353 372 /* What to do when we've been interrupted, and it is safe to handle it. */ 354 373 void 355 374 throw_to_top_level () -
bash-3.2
diff -Naur bash-3.2.orig/sig.h bash-3.2/sig.h
old new 121 121 extern void initialize_signals __P((int)); 122 122 extern void initialize_terminating_signals __P((void)); 123 123 extern void reset_terminating_signals __P((void)); 124 extern void top_level_cleanup __P((void)); 124 125 extern void throw_to_top_level __P((void)); 125 126 extern void jump_to_top_level __P((int)) __attribute__((__noreturn__)); 126 127 -
subst.c
diff -Naur bash-3.2.orig/subst.c bash-3.2/subst.c
old new 4 4 /* ``Have a little faith, there's magic in the night. You ain't a 5 5 beauty, but, hey, you're alright.'' */ 6 6 7 /* Copyright (C) 1987-200 6Free Software Foundation, Inc.7 /* Copyright (C) 1987-2007 Free Software Foundation, Inc. 8 8 9 9 This file is part of GNU Bash, the Bourne Again SHell. 10 10 … … 1278 1278 { 1279 1279 if (no_longjmp_on_fatal_error == 0) 1280 1280 { /* { */ 1281 report_error ( "bad substitution: no closing `%s' in %s", "}", string);1281 report_error (_("bad substitution: no closing `%s' in %s"), "}", string); 1282 1282 last_command_exit_value = EXECUTION_FAILURE; 1283 1283 exp_jump_to_top_level (DISCARD); 1284 1284 } … … 1887 1887 sep[1] = '\0'; 1888 1888 #endif 1889 1889 1890 /* XXX -- why call quote_list if ifs == 0? we can get away without doing 1891 it now that quote_escapes quotes spaces */ 1892 #if 0 1890 1893 tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0)) 1894 #else 1895 tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) 1896 #endif 1891 1897 ? quote_list (list) 1892 1898 : list_quote_escapes (list); 1893 1899 … … 2646 2652 2647 2653 /* This needs better error handling. */ 2648 2654 /* Expand W for use as an argument to a unary or binary operator in a 2649 [[...]] expression. If SPECIAL is nonzero, this is the rhs argument2655 [[...]] expression. If SPECIAL is 1, this is the rhs argument 2650 2656 to the != or == operator, and should be treated as a pattern. In 2651 this case, we quote the string specially for the globbing code. The 2652 caller is responsible for removing the backslashes if the unquoted 2653 words is needed later. */ 2657 this case, we quote the string specially for the globbing code. If 2658 SPECIAL is 2, this is an rhs argument for the =~ operator, and should 2659 be quoted appropriately for regcomp/regexec. The caller is responsible 2660 for removing the backslashes if the unquoted word is needed later. */ 2654 2661 char * 2655 2662 cond_expand_word (w, special) 2656 2663 WORD_DESC *w; … … 2658 2665 { 2659 2666 char *r, *p; 2660 2667 WORD_LIST *l; 2668 int qflags; 2661 2669 2662 2670 if (w->word == 0 || w->word[0] == '\0') 2663 2671 return ((char *)NULL); … … 2672 2680 } 2673 2681 else 2674 2682 { 2683 qflags = QGLOB_CVTNULL; 2684 if (special == 2) 2685 qflags |= QGLOB_REGEXP; 2675 2686 p = string_list (l); 2676 r = quote_string_for_globbing (p, QGLOB_CVTNULL);2687 r = quote_string_for_globbing (p, qflags); 2677 2688 free (p); 2678 2689 } 2679 2690 dispose_words (l); … … 2916 2927 2917 2928 /* Quote escape characters in string s, but no other characters. This is 2918 2929 used to protect CTLESC and CTLNUL in variable values from the rest of 2919 the word expansion process after the variable is expanded. */ 2930 the word expansion process after the variable is expanded. If IFS is 2931 null, we quote spaces as well, just in case we split on spaces later 2932 (in the case of unquoted $@, we will eventually attempt to split the 2933 entire word on spaces). Corresponding code exists in dequote_escapes. 2934 Even if we don't end up splitting on spaces, quoting spaces is not a 2935 problem. */ 2920 2936 char * 2921 2937 quote_escapes (string) 2922 2938 char *string; … … 2924 2940 register char *s, *t; 2925 2941 size_t slen; 2926 2942 char *result, *send; 2943 int quote_spaces; 2927 2944 DECLARE_MBSTATE; 2928 2945 2929 2946 slen = strlen (string); 2930 2947 send = string + slen; 2931 2948 2949 quote_spaces = (ifs_value && *ifs_value == 0); 2932 2950 t = result = (char *)xmalloc ((slen * 2) + 1); 2933 2951 s = string; 2934 2952 2935 2953 while (*s) 2936 2954 { 2937 if (*s == CTLESC || *s == CTLNUL )2955 if (*s == CTLESC || *s == CTLNUL || (quote_spaces && *s == ' ')) 2938 2956 *t++ = CTLESC; 2939 2957 COPY_CHAR_P (t, s, send); 2940 2958 } … … 2976 2994 register char *s, *t; 2977 2995 size_t slen; 2978 2996 char *result, *send; 2997 int quote_spaces; 2979 2998 DECLARE_MBSTATE; 2980 2999 2981 3000 if (string == 0) … … 2990 3009 if (strchr (string, CTLESC) == 0) 2991 3010 return (strcpy (result, s)); 2992 3011 3012 quote_spaces = (ifs_value && *ifs_value == 0); 2993 3013 while (*s) 2994 3014 { 2995 if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL ))3015 if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' '))) 2996 3016 { 2997 3017 s++; 2998 3018 if (*s == '\0') … … 3954 3974 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT) 3955 3975 patstr++; 3956 3976 3957 pattern = getpattern (patstr, quoted, 1); 3977 /* Need to pass getpattern newly-allocated memory in case of expansion -- 3978 the expansion code will free the passed string on an error. */ 3979 temp1 = savestring (patstr); 3980 pattern = getpattern (temp1, quoted, 1); 3981 free (temp1); 3958 3982 3959 3983 temp1 = (char *)NULL; /* shut up gcc */ 3960 3984 switch (vtype) … … 4123 4147 nfifo = 0; 4124 4148 } 4125 4149 4150 int 4151 fifos_pending () 4152 { 4153 return nfifo; 4154 } 4155 4126 4156 static char * 4127 4157 make_named_pipe () 4128 4158 { … … 4172 4202 nfds++; 4173 4203 } 4174 4204 4205 int 4206 fifos_pending () 4207 { 4208 return 0; /* used for cleanup; not needed with /dev/fd */ 4209 } 4210 4175 4211 void 4176 4212 unlink_fifo_list () 4177 4213 { … … 4456 4492 /* Add the character to ISTRING, possibly after resizing it. */ 4457 4493 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE); 4458 4494 4459 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || c == CTLESC || c == CTLNUL) 4495 /* This is essentially quote_string inline */ 4496 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */) 4497 istring[istring_index++] = CTLESC; 4498 /* Escape CTLESC and CTLNUL in the output to protect those characters 4499 from the rest of the word expansions (word splitting and globbing.) 4500 This is essentially quote_escapes inline. */ 4501 else if (c == CTLESC) 4502 istring[istring_index++] = CTLESC; 4503 else if (c == CTLNUL || (c == ' ' && (ifs_value && *ifs_value == 0))) 4460 4504 istring[istring_index++] = CTLESC; 4461 4505 4462 4506 istring[istring_index++] = c; … … 4665 4709 4666 4710 last_command_exit_value = rc; 4667 4711 rc = run_exit_trap (); 4712 #if defined (PROCESS_SUBSTITUTION) 4713 unlink_fifo_list (); 4714 #endif 4668 4715 exit (rc); 4669 4716 } 4670 4717 else … … 4860 4907 char *temp, *tt; 4861 4908 intmax_t arg_index; 4862 4909 SHELL_VAR *var; 4863 int atype ;4910 int atype, rflags; 4864 4911 4865 4912 ret = 0; 4866 4913 temp = 0; 4914 rflags = 0; 4867 4915 4868 4916 /* Handle multiple digit arguments, as in ${11}. */ 4869 4917 if (legal_number (name, &arg_index)) … … 4896 4944 temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) 4897 4945 ? quote_string (temp) 4898 4946 : quote_escapes (temp); 4947 else if (atype == 1 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) 4948 rflags |= W_HASQUOTEDNULL; 4899 4949 } 4900 4950 #endif 4901 4951 else if (var = find_variable (name)) … … 4923 4973 { 4924 4974 ret = alloc_word_desc (); 4925 4975 ret->word = temp; 4976 ret->flags |= rflags; 4926 4977 } 4927 4978 return ret; 4928 4979 } … … 5546 5597 so verify_substring_values just returns the numbers specified and we 5547 5598 rely on array_subrange to understand how to deal with them). */ 5548 5599 tt = array_subrange (array_cell (v), e1, e2, starsub, quoted); 5600 #if 0 5601 /* array_subrange now calls array_quote_escapes as appropriate, so the 5602 caller no longer needs to. */ 5549 5603 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0) 5550 5604 { 5551 5605 temp = tt ? quote_escapes (tt) : (char *)NULL; 5552 5606 FREE (tt); 5553 5607 } 5554 5608 else 5609 #endif 5555 5610 temp = tt; 5556 5611 break; 5557 5612 #endif … … 5707 5762 vtype &= ~VT_STARSUB; 5708 5763 5709 5764 mflags = 0; 5765 if (patsub && *patsub == '/') 5766 { 5767 mflags |= MATCH_GLOBREP; 5768 patsub++; 5769 } 5710 5770 5711 5771 /* Malloc this because expand_string_if_necessary or one of the expansion 5712 5772 functions in its call chain may free it on a substitution error. */ … … 5741 5801 } 5742 5802 5743 5803 /* ksh93 doesn't allow the match specifier to be a part of the expanded 5744 pattern. This is an extension. */ 5804 pattern. This is an extension. Make sure we don't anchor the pattern 5805 at the beginning or end of the string if we're doing global replacement, 5806 though. */ 5745 5807 p = pat; 5746 if (pat && pat[0] == '/') 5747 { 5748 mflags |= MATCH_GLOBREP|MATCH_ANY; 5749 p++; 5750 } 5808 if (mflags & MATCH_GLOBREP) 5809 mflags |= MATCH_ANY; 5751 5810 else if (pat && pat[0] == '#') 5752 5811 { 5753 5812 mflags |= MATCH_BEG; … … 5798 5857 #if defined (ARRAY_VARS) 5799 5858 case VT_ARRAYVAR: 5800 5859 temp = array_patsub (array_cell (v), p, rep, mflags); 5860 #if 0 5861 /* Don't need to do this anymore; array_patsub calls array_quote_escapes 5862 as appropriate before adding the space separators. */ 5801 5863 if (temp && (mflags & MATCH_QUOTED) == 0) 5802 5864 { 5803 5865 tt = quote_escapes (temp); 5804 5866 free (temp); 5805 5867 temp = tt; 5806 5868 } 5869 #endif 5807 5870 break; 5808 5871 #endif 5809 5872 } … … 7607 7670 expand_no_split_dollar_star = 0; /* XXX */ 7608 7671 expanding_redir = 0; 7609 7672 7673 top_level_cleanup (); /* from sig.c */ 7674 7610 7675 jump_to_top_level (v); 7611 7676 } 7612 7677 … … 7824 7889 else if (fail_glob_expansion != 0) 7825 7890 { 7826 7891 report_error (_("no match: %s"), tlist->word->word); 7827 jump_to_top_level (DISCARD);7892 exp_jump_to_top_level (DISCARD); 7828 7893 } 7829 7894 else if (allow_null_glob_expansion == 0) 7830 7895 { -
subst.h
diff -Naur bash-3.2.orig/subst.h bash-3.2/subst.h
old new 222 222 extern char *command_substitute __P((char *, int)); 223 223 extern char *pat_subst __P((char *, char *, char *, int)); 224 224 225 extern int fifos_pending __P((void)); 225 226 extern void unlink_fifo_list __P((void)); 226 227 227 228 extern WORD_LIST *list_string_with_quotes __P((char *)); -
tests/new-exp.right
diff -Naur bash-3.2.orig/tests/new-exp.right bash-3.2/tests/new-exp.right
old new 430 430 Case06---1---A B C::--- 431 431 Case07---3---A:B:C--- 432 432 Case08---3---A:B:C--- 433 ./new-exp.tests: line 506: /${$(($#-1))}: bad substitution433 ./new-exp.tests: line 506: ${$(($#-1))}: bad substitution 434 434 argv[1] = <a> 435 435 argv[2] = <b> 436 436 argv[3] = <c> -
variables.c
diff -Naur bash-3.2.orig/variables.c bash-3.2/variables.c
old new 1821 1821 oval = value_cell (var); 1822 1822 lval = evalexp (oval, &expok); /* ksh93 seems to do this */ 1823 1823 if (expok == 0) 1824 jump_to_top_level (DISCARD); 1824 { 1825 top_level_cleanup (); 1826 jump_to_top_level (DISCARD); 1827 } 1825 1828 } 1826 1829 rval = evalexp (value, &expok); 1827 1830 if (expok == 0) 1828 jump_to_top_level (DISCARD); 1831 { 1832 top_level_cleanup (); 1833 jump_to_top_level (DISCARD); 1834 } 1829 1835 if (flags & ASS_APPEND) 1830 1836 rval += lval; 1831 1837 retval = itos (rval); -
version.c
diff -Naur bash-3.2.orig/version.c bash-3.2/version.c
old new 79 79 { 80 80 printf ("GNU bash, version %s (%s)\n", shell_version_string (), MACHTYPE); 81 81 if (extended) 82 printf (_("Copyright (C) 200 5Free Software Foundation, Inc.\n"));82 printf (_("Copyright (C) 2007 Free Software Foundation, Inc.\n")); 83 83 }
Note:
See TracBrowser
for help on using the repository browser.