]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20070712 snapshot
authorChet Ramey <chet.ramey@case.edu>
Wed, 7 Dec 2011 14:10:14 +0000 (09:10 -0500)
committerChet Ramey <chet.ramey@case.edu>
Wed, 7 Dec 2011 14:10:14 +0000 (09:10 -0500)
16 files changed:
CWRU/CWRU.chlog
CWRU/CWRU.chlog~
MANIFEST
examples/INDEX.html
examples/INDEX.txt
examples/obashdb/README
examples/obashdb/bashdb [changed mode: 0644->0755]
examples/obashdb/bashdb.el [new file with mode: 0644]
examples/obashdb/bashdb.vaughan [new file with mode: 0644]
lib/readline/display.c
lib/readline/display.c~
lib/readline/rltty.c
lib/sh/getcwd.c
lib/sh/getcwd.c~ [new file with mode: 0644]
variables.c
variables.c~

index 2e7f5c150a7014163d285e4780cf7f5e744f7ac8..be430f41c860285b52d269ceb2da360874240ab8 100644 (file)
@@ -14759,3 +14759,28 @@ lib/readline/display.c
          second line and the redisplay draws the invisible character.  Fixes
          redisplay bug reported by Andreas Schwab <schwab@suse.de>
 
+
+                                  7/11
+                                  ----
+
+lib/readline/rltty.c
+       - enable flush-output code for systems other than AIX 4.1.  Problem
+         reported by Jan Kratochvil <jan.kratochvil@redhat.com>
+
+                                  7/12
+                                  ----
+lib/readline/display.c
+       - set prompt_invis_chars_first_line from the portion of the prompt
+         following the final newline, instead of from the prefix.  Fixes
+         bug reported on the Ubuntu bug list by dAniel hAhler
+         <ubuntu@thequod.de>
+
+                                  7/13
+                                  ----
+variables.c
+       - use native __QNX__ and __QNXNTO__ cpp defines instead of qnx and
+         qnx6, respectively.  Patch from Sean Boudreau <seanb@qnx.com>
+
+lib/sh/getcwd.c
+       - #undef HAVE_LSTAT on qnx, so it uses stat instead.  Patch from
+         Sean Boudreau <seanb@qnx.com>
index 4539215023acc81b883a35e471fb7ba544dbabc2..84ca791017082f62a06caf0a8369b54fbe530884 100644 (file)
@@ -14757,5 +14757,26 @@ lib/readline/display.c
        - change _rl_move_cursor_relative to adjust _rl_last_c_pos in a
          multibyte environment when the prompt has invisible chars on the
          second line and the redisplay draws the invisible character.  Fixes
-         bug reported by Andreas Schwab <schwab@suse.de>
+         redisplay bug reported by Andreas Schwab <schwab@suse.de>
 
+
+                                  7/11
+                                  ----
+
+lib/readline/rltty.c
+       - enable flush-output code for systems other than AIX 4.1.  Problem
+         reported by Jan Kratochvil <jan.kratochvil@redhat.com>
+
+                                  7/12
+                                  ----
+lib/readline/display.c
+       - set prompt_invis_chars_first_line from the portion of the prompt
+         following the final newline, instead of from the prefix.  Fixes
+         bug reported on the Ubuntu bug list by dAniel hAhler
+         <ubuntu@thequod.de>
+
+                                  7/13
+                                  ----
+variables.c
+       - use native __QNX__ and __QNXNTO__ cpp defines instead of qnx and
+         qnx6, respectively.  Patch from Sean Boudreau <seanb@qnx.com>
index e788f4ff9d6426131a173b97b9da70587374b964..0d0506ebeedefdbc947abf706c6557e55ba41221 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -10,7 +10,6 @@ builtins      d
 cross-build    d
 doc    d
 examples       d
-examples/bashdb        d
 examples/obashdb       d
 examples/complete      d
 examples/functions d
@@ -535,15 +534,10 @@ support/shobj-conf        f       755
 support/rlvers.sh      f       755
 examples/INDEX.txt     f
 examples/INDEX.html    f
-examples/bashdb/PERMISSION     f
-examples/bashdb/README f
-examples/bashdb/bashdb         f
-examples/bashdb/bashdb.el      f
 examples/obashdb/PERMISSION    f
 examples/obashdb/README        f
-examples/obashdb/bashdb        f
-examples/obashdb/bashdb.fns    f
-examples/obashdb/bashdb.pre    f
+examples/obashdb/bashdb                f
+examples/obashdb/bashdb.el     f
 examples/complete/complete-examples    f
 examples/complete/complete.ianmac      f
 examples/complete/complete2.ianmac     f
index c3ba24d79bd22530d9079bfb54491840ea12b880..150701cac77de1a0377733d31df6270d3328b997 100644 (file)
@@ -5,7 +5,7 @@
     <th>X-Ref</th>
   </tr>
   <tr>
-    <td>./bashdb</td>
+    <td>./obashdb</td>
     <td>Deprecated sample implementation of a bash debugger</td>
   </tr>
   <tr>
   </tr>
   <tr>
   </tr>
-  <tr>
-    <td>./obashdb</td>
-    <td>Modified version of the Korn Shell debugger from Bill Rosenblatt's 'Learning the Korn Shell'.</td>
-  </tr>
-  <tr>
-  </tr>
   <tr>
     <td>./scripts.noah</td>
     <td>Noah Friedman's collection of scripts (updated to bash v2 syntax by Chet Ramey)</td>
index 1be1cc631c7f29450cfb81e8b0d9aa0d48b819bf..ab69e6cbc2336d32d4329cb637edd2f157fcff37 100644 (file)
@@ -1,5 +1,5 @@
 Path   Description     X-Ref
-./bashdb       Deprecated sample implementation of a bash debugger     
+./obashdb      Deprecated sample implementation of a bash debugger     
 
 ./complete     Shell completion code   
 
@@ -103,8 +103,6 @@ Path        Description     X-Ref
 ./misc/README  README  
 ./misc/suncmd.termcap  SunView TERMCAP string. 
 
-./obashdb      Modified version of the Korn Shell debugger from Bill Rosenblatt's 'Learning the Korn Shell'.   
-
 ./scripts.noah Noah Friedman's collection of scripts (updated to bash v2 syntax by Chet Ramey) 
 ./scripts.noah/aref.bash       Pseudo-arrays and substring indexing examples.  
 ./scripts.noah/bash.sub.bash   Library functions used by require.bash. 
index 3373f5f80479098ed1faff2a08de7847d010ccee..2f643d1968018e105c565cf1530d315abd3f5038 100644 (file)
@@ -1,12 +1,3 @@
-This is a modified version of the Korn Shell debugger from Bill
-Rosenblatt's `Learning the Korn Shell', published by O'Reilly
-and Associates (ISBN 1-56592-054-6).
-
-The original `kshdb' is available for anonymous FTP with the URL
-
-http://examples.oreilly.com/korn/ksh.tar.Z
-A revised edition is available at:
-
-http://examples.oreilly.com/korn2/korn2_examples.tar.gz
-
+This is a sample implementation of a bash debugger.  It is not the same
+as the project available from http://bashdb.sourceforge.net, and has been
+deprecated in favor of that implementation.
old mode 100644 (file)
new mode 100755 (executable)
index 97d287d..560cb7c
-# kshdb - Korn Shell Debugger main file
-# adapted from 'Learning the Korn Shell' by Bill Rosenblatt (O'Reilly)
-# by Cigy Cyriac (cigy@felix.tulblr.unisys.com)
-# Main driver: constructs full script (with preamble) and runs it
+#! /bin/bash
+# bashdb - Bash shell debugger
+#
+# Adapted from an idea in O'Reilly's `Learning the Korn Shell'
+# Copyright (C) 1993-1994 O'Reilly and Associates, Inc.
+# Copyright (C) 1998, 1999, 2001 Gary V. Vaughan <gvv@techie.com>>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
 
-echo 'Bourne-Again Shell Debugger version 0.1'
+# NOTE:
+#
+# This program requires bash 2.x.
+# If bash 2.x is installed as "bash2", you can invoke  bashdb like this:
+#
+#   DEBUG_SHELL=/bin/bash2 /bin/bash2 bashdb script.sh
 
-_pname=${0##*/}
+# TODO:
+#
+# break [regexp]
+# cond [break] [condition]
+# tbreak [regexp|+lines]
+# restart
+# Variable watchpoints
+# Instrument `source' and `.' files in $_potbelliedpig
+# be cleverer about lines we allow breakpoints to be set on
+# break [function_name]
 
-[ $# -eq 0 ] && {
-       echo "${_pname}: usage: ${_pname} <script_file>"
-       exit 1
-}
+echo 'Bash Debugger version 1.2.4'
+
+export _dbname=${0##*/}
+
+if test $# -lt 1; then
+  echo "$_dbname: Usage: $_dbname filename" >&2
+  exit 1
+fi
 
 _guineapig=$1
 
-[ -r $_guineapig ] || {
-       echo "${_pname}: cannot read $_guineapig." >&2
-       exit 1
-}
+if test ! -r $1; then
+  echo "$_dbname: Cannot read file '$_guineapig'." >&2
+  exit 1
+fi
+
 shift
 
-_tmpdir=/tmp
-_libdir=.
-_dbgfile=$_tmpdir/bashdb$$             #temp file for script being debugged
+__debug=${TMPDIR-/tmp}/bashdb.$$
+sed -e '/^# bashdb - Bash shell debugger/,/^# -- DO NOT DELETE THIS LINE -- /d' "$0" > $__debug
+cat $_guineapig >> $__debug
+exec ${DEBUG_SHELL-bash} $__debug $_guineapig "$@"
 
-cat $_libdir/bashdb.pre $_guineapig > $_dbgfile
-if [ -f "$BASH" ]; then
-       exec $BASH $_dbgfile $_guineapig $_tmpdir $_libdir "$@"
-else
-       exec bash $_dbgfile $_guineapig $_tmpdir $_libdir "$@"
-fi
-# end of bashdb
+exit 1
+
+# -- DO NOT DELETE THIS LINE -- The program depends on it
+
+#bashdb preamble
+# $1 name of the original guinea pig script
+
+__debug=$0
+_guineapig=$1
+__steptrap_calls=0
+
+shift
+
+shopt -s extglob       # turn on extglob so we can parse the debugger funcs
+
+function _steptrap
+{
+  local i=0
+
+  _curline=$1
+
+  if (( ++__steptrap_calls > 1 && $_curline == 1 )); then
+    return
+  fi
+
+  if [ -n "$_disps" ]; then
+    while (( $i < ${#_disps[@]} ))
+    do
+      if [ -n "${_disps[$i]}" ]; then
+        _msg "${_disps[$i]}: \c"
+        eval _msg ${_disps[$i]}
+      fi
+      let i=$i+1
+    done
+  fi
+
+  if (( $_trace )); then
+    _showline $_curline
+  fi
+
+  if (( $_steps >= 0 )); then
+    let _steps="$_steps - 1"
+  fi
+
+  if _at_linenumbp ; then
+    _msg "Reached breakpoint at line $_curline"
+    _showline $_curline
+    _cmdloop
+  elif [ -n "$_brcond" ] && eval $_brcond; then
+    _msg "Break condition $_brcond true at line $_curline"
+    _showline $_curline
+    _cmdloop
+  elif (( $_steps == 0 )); then
+    # Assuming a real script will have the "#! /bin/sh" at line 1,
+    # assume that when $_curline == 1 we are inside backticks.
+    if (( ! $_trace )); then
+      _msg "Stopped at line $_curline"
+      _showline $_curline
+    fi
+    _cmdloop
+  fi
+}
+
+function _setbp
+{
+  local i f line _x
+
+  if [ -z "$1" ]; then
+    _listbp
+    return
+  fi
+
+  eval "$_seteglob"
+
+  if [[ $1 == *(\+)[1-9]*([0-9]) ]]; then
+    case $1 in
+    +*)
+      # normalize argument, then double it (+2 -> +2 + 2 = 4)
+      _x=${1##*([!1-9])}       # cut off non-numeric prefix
+      _x=${x%%*([!0-9])}       # cut off non-numeric suffix
+      f=$(( $1 + $_x ))
+      ;;
+    *)
+      f=$(( $1 ))
+      ;;
+    esac
+
+    # find the next valid line
+    line="${_lines[$f]}"
+    while _invalidbreakp $f
+    do
+      (( f++ ))
+      line="${_lines[$f]}"
+    done
+
+    if (( $f != $1 ))
+    then
+      _msg "Line $1 is not a valid breakpoint"
+    fi
+
+    if [ -n "${_lines[$f]}" ]; then
+      _linebp[$1]=$1;
+      _msg "Breakpoint set at line $f"
+    else
+      _msg "Breakpoints can only be set on executable lines"
+    fi
+  else
+    _msg "Please specify a numeric line number"
+  fi
+
+  eval "$_resteglob"
+}
+
+function _listbp
+{
+  local i
+  
+  if [ -n "$_linebp" ]; then
+    _msg "Breakpoints:"
+    for i in ${_linebp[*]}; do
+      _showline $i
+    done
+  else
+    _msg "No breakpoints have been set"
+  fi
+}
+
+function _clearbp
+{
+  local i
+
+  if [ -z "$1" ]; then
+    read -e -p "Delete all breakpoints? "
+    case $REPLY in
+    [yY]*)
+      unset _linebp[*]
+      _msg "All breakpoints have been cleared"
+      ;;
+    esac
+    return 0
+  fi
+
+  eval "$_seteglob"
+
+  if [[ $1 == [1-9]*([0-9]) ]]; then
+    unset _linebp[$1]
+    _msg "Breakpoint cleared at line $1"
+  else
+    _msg "Please specify a numeric line number"
+  fi
+
+  eval "$_resteglob"
+}
+
+function _setbc
+{
+  if (( $# > 0 )); then
+    _brcond=$@
+    _msg "Break when true: $_brcond"
+  else
+    _brcond=
+    _msg "Break condition cleared"
+  fi
+}
+
+function _setdisp
+{
+  if [ -z "$1" ]; then
+    _listdisp
+  else
+    _disps[${#_disps[@]}]="$1"
+    if (( ${#_disps[@]} < 10 ))
+    then
+      _msg " ${#_disps[@]}: $1"
+    else
+      _msg "${#_disps[@]}: $1"
+    fi
+  fi
+}
+
+function _listdisp
+{
+  local i=0 j
+  
+  if [ -n "$_disps" ]; then
+    while (( $i < ${#_disps[@]} ))
+    do
+      let j=$i+1
+    if (( ${#_disps[@]} < 10 ))
+    then
+      _msg " $j: ${_disps[$i]}"
+    else
+      _msg "$j: ${_disps[$i]}"
+    fi
+      let i=$j
+    done
+  else
+    _msg "No displays have been set"
+  fi
+}
+
+function _cleardisp
+{
+  if (( $# < 1 )) ; then
+    read -e -p "Delete all display expressions? "
+    case $REPLY in
+    [Yy]*)
+      unset _disps[*]
+      _msg "All breakpoints have been cleared"
+      ;;
+    esac
+    return 0
+  fi
+
+  eval "$_seteglob"
+
+  if [[ $1 == [1-9]*([0-9]) ]]; then
+    unset _disps[$1]
+    _msg "Display $i has been cleared"
+  else
+    _listdisp
+    _msg "Please specify a numeric display number"
+  fi
+
+  eval "$_resteglob"
+}   
+
+# usage _ftrace -u funcname [funcname...]
+function _ftrace
+{
+  local _opt=-t _tmsg="enabled" _func 
+  if [[ $1 == -u ]]; then
+       _opt=+t
+       _tmsg="disabled"
+       shift
+  fi
+  for _func; do
+         declare -f $_opt $_func
+         _msg "Tracing $_tmsg for function $_func"
+  done
+}
+
+function _cmdloop
+{
+  local cmd args
+
+  while read -e -p "bashdb> " cmd args; do
+    test -n "$cmd" && history -s "$cmd $args"  # save on history list
+    test -n "$cmd" || { set $_lastcmd; cmd=$1; shift; args=$*; }
+    if [ -n "$cmd" ]
+    then
+      case $cmd in
+       b|br|bre|brea|break)
+         _setbp $args
+         _lastcmd="break $args"
+         ;;
+       co|con)
+         _msg "ambiguous command: '$cmd', condition, continue?"
+         ;;
+       cond|condi|condit|conditi|conditio|condition)
+         _setbc $args
+         _lastcmd="condition $args"
+         ;;
+       c|cont|conti|contin|continu|continue)
+         _lastcmd="continue"
+         return
+         ;;
+       d)
+         _msg "ambiguous command: '$cmd', delete, display?"
+         ;;
+       de|del|dele|delet|delete)
+         _clearbp $args
+         _lastcmd="delete $args"
+         ;;
+       di|dis|disp|displ|displa|display)
+         _setdisp $args
+         _lastcmd="display $args"
+         ;;
+       f|ft|ftr|ftra|ftrace)
+         _ftrace $args
+         _lastcmd="ftrace $args"
+         ;;
+       \?|h|he|hel|help)
+         _menu
+         _lastcmd="help"
+         ;;
+       l|li|lis|list)
+         _displayscript $args
+         # _lastcmd is set in the _displayscript function
+         ;;
+       p|pr|pri|prin|print)
+         _examine $args
+         _lastcmd="print $args"
+         ;;
+       q|qu|qui|quit)
+         exit
+         ;;
+       s|st|ste|step|n|ne|nex|next)
+         let _steps=${args:-1}
+         _lastcmd="next $args"
+         return
+         ;;
+       t|tr|tra|trac|trace)
+         _xtrace
+         ;;
+       u|un|und|undi|undis|undisp|undispl|undispla|undisplay)
+         _cleardisp $args
+         _lastcmd="undisplay $args"
+         ;;
+       !*)
+         eval ${cmd#!} $args
+         _lastcmd="$cmd $args"
+         ;;
+       *)
+         _msg "Invalid command: '$cmd'"
+         ;;
+      esac
+    fi
+  done
+}
+
+function _at_linenumbp
+{
+  [[ -n ${_linebp[$_curline]} ]]
+}
+
+function _invalidbreakp
+{
+  local line=${_lines[$1]}
+
+  # XXX - should use shell patterns
+  if test -z "$line" \
+      || expr "$line" : '[ \t]*#.*' > /dev/null \
+      || expr "$line" : '[ \t]*;;[ \t]*$' > /dev/null \
+      || expr "$line" : '[ \t]*[^)]*)[ \t]*$' > /dev/null \
+      || expr "$line" : '[ \t]*;;[ \t]*#.**$' > /dev/null \
+      || expr "$line" : '[ \t]*[^)]*)[ \t]*;;[ \t]*$' > /dev/null \
+      || expr "$line" : '[ \t]*[^)]*)[ \t]*;;*[ \t]*#.*$' > /dev/null
+  then
+    return 0
+  fi
+
+  return 1
+}
+
+function _examine
+{
+  if [ -n "$*" ]; then
+    _msg "$args: \c"
+    eval _msg $args
+  else
+    _msg "Nothing to print"
+  fi
+}
+
+function _displayscript
+{
+  local i j start end bp cl
+
+  if (( $# == 1 )); then       # list 5 lines on either side of $1
+    if [ $1 = "%" ]; then
+      let start=1
+      let end=${#_lines[@]}
+    else
+      let start=$1-5
+      let end=$1+5
+    fi
+  elif (( $# > 1 )); then      # list between start and end
+    if [ $1 = "^" ]; then
+      let start=1
+    else
+      let start=$1
+    fi
+
+    if [ $2 = "\$" ]; then
+      let end=${#_lines[@]}
+    else
+      let end=$2
+    fi
+  else                         # list 5 lines on either side of current line
+    let start=$_curline-5
+    let end=$_curline+5
+  fi
+
+  # normalize start and end
+  if (( $start < 1 )); then
+    start=1
+  fi
+  if (( $end > ${#_lines[@]} )); then
+    end=${#_lines[@]}
+  fi
+
+  cl=$(( $end - $start ))
+  if (( $cl > ${LINES-24} )); then
+    pager=${PAGER-more}
+  else
+    pager=cat
+  fi
+  
+  i=$start
+  ( while (( $i <= $end )); do
+      _showline $i
+      let i=$i+1
+    done ) 2>&1 | $pager
+
+  # calculate the next block of lines
+  start=$(( $end + 1 ))
+  end=$(( $start + 11 ))
+  if (( $end > ${#_lines[@]} ))
+  then
+    end=${#_lines[@]}
+  fi
+
+  _lastcmd="list $start $end"
+}
+
+function _xtrace
+{
+  let _trace="! $_trace"
+  if (( $_trace )); then
+    _msg "Execution trace on"
+  else
+    _msg "Execution trace off"
+  fi
+}
+       
+function _msg
+{
+  echo -e "$@" >&2
+}
+
+function _showline
+{
+  local i=0 bp=' ' line=$1 cl=' '
+
+  if [[ -n ${_linebp[$line]} ]]; then
+    bp='*'
+  fi
+
+  if  (( $_curline == $line )); then
+    cl=">"
+  fi
+
+  if (( $line < 100 )); then
+    _msg "${_guineapig/*\//}:$line   $bp $cl${_lines[$line]}"
+  elif (( $line < 10 )); then
+    _msg "${_guineapig/*\//}:$line  $bp $cl${_lines[$line]}"
+  elif (( $line > 0 )); then
+    _msg "${_guineapig/*\//}:$line $bp $cl${_lines[$line]}"
+  fi
+}
+
+function _cleanup
+{
+  rm -f $__debug $_potbelliedpig 2> /dev/null
+}
+
+function _menu
+{
+  _msg 'bashdb commands:
+       break N         set breakpoint at line N
+       break           list breakpoints & break condition
+       condition foo   set break condition to foo
+       condition       clear break condition
+       delete N        clear breakpoint at line N
+       delete          clear all breakpoints
+       display EXP     evaluate and display EXP for each debug step
+       display         show a list of display expressions
+       undisplay N     remove display expression N
+       list N M        display all lines of script between N and M
+       list N          display 5 lines of script either side of line N
+       list            display 5 lines if script either side of current line
+       continue        continue execution upto next breakpoint
+       next [N]        execute [N] statements (default 1)
+       print expr      prints the value of an expression
+       trace           toggle execution trace on/off
+       ftrace [-u] func        make the debugger step into function FUNC
+                       (-u turns off tracing FUNC)
+       help            print this menu
+       ! string        passes string to a shell
+       quit            quit'
+}
+
+shopt -u extglob
+
+HISTFILE=~/.bashdb_history
+set -o history
+set +H
+
+# strings to save and restore the setting of `extglob' in debugger functions
+# that need it
+_seteglob='local __eopt=-u ; shopt -q extglob && __eopt=-s ; shopt -s extglob'
+_resteglob='shopt $__eopt extglob'
+
+_linebp=()
+let _trace=0
+let _i=1
+
+# Be careful about quoted newlines
+_potbelliedpig=${TMPDIR-/tmp}/${_guineapig/*\//}.$$
+sed 's,\\$,\\\\,' $_guineapig > $_potbelliedpig
+
+_msg "Reading source from file: $_guineapig"
+while read; do
+  _lines[$_i]=$REPLY
+  let _i=$_i+1
+done < $_potbelliedpig
+
+trap _cleanup EXIT
+# Assuming a real script will have the "#! /bin/sh" at line 1,
+# don't stop at line 1 on the first run
+let _steps=1
+LINENO=-1
+trap '_steptrap $LINENO' DEBUG
diff --git a/examples/obashdb/bashdb.el b/examples/obashdb/bashdb.el
new file mode 100644 (file)
index 0000000..40584dd
--- /dev/null
@@ -0,0 +1,177 @@
+;;; bashdb.el --- Grand Unified Debugger mode for running bashdb
+;; Copyright (C) 2000, 2001 Masatake YAMATO 
+
+;; Author: Masatake YAMATO <jet@gyve.org>
+
+;; This program is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software Foundation,
+;; Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+;; Commentary:
+;; This program may run on Emacs 21.0.91 and XEmacs 21.1. 
+;;
+;; Put 
+;; (autoload 'bashdb "bashdb" "Run bashdb" t nil)
+;;  to your .emacs.
+;; M-x bashdb
+;; Run bashdb (like this): bashdb target.sh
+;;
+;; About bashdb:
+;; You can get bashdb from
+;; http://www.oranda.demon.co.uk/development.html
+;;
+;; bashdb.el is based on perldb in gud.el in XEmacs 21.1.
+
+;; Revision:
+;; $Revision: 1.6 $
+;; $Log: bashdb.el,v $
+;; Revision 1.6  2001/01/06 12:18:06  masata-y
+;; Write note about XEmacs.
+;;
+;;
+
+
+;;; Code: 
+(require 'gud)
+
+;; User customizable variable
+(defcustom gud-bashdb-command-name "bashdb"
+  "File name for executing Bashdb."
+  :type 'string
+  :group 'gud)
+
+;; History of argument lists passed to bashdb.
+(defvar gud-bashdb-history nil)
+
+(defun gud-bashdb-massage-args (file args)
+  (if xemacsp
+      (cons (file-name-nondirectory file) args)        
+    args))
+
+;; There's no guarantee that Emacs will hand the filter the entire
+;; marker at once; it could be broken up across several strings.  We
+;; might even receive a big chunk with several markers in it.  If we
+;; receive a chunk of text which looks like it might contain the
+;; beginning of a marker, we save it here between calls to the
+;; filter.
+(if xemacsp
+    (defvar gud-bashdb-marker-acc ""))
+(defun gud-bashdb-marker-acc ()
+  (if xemacsp
+      gud-bashdb-marker-acc
+    gud-marker-acc))
+(defun gud-bashdb-marker-acc-quote ()
+  (if xemacsp
+      'gud-bashdb-marker-acc
+    'gud-marker-acc))
+
+(defun gud-bashdb-marker-filter (string)
+  (save-match-data
+    (set (gud-bashdb-marker-acc-quote)
+        (concat (gud-bashdb-marker-acc) string))
+    (let ((output ""))
+      ;; Process all the complete markers in this chunk.
+      (while (string-match "^\\([^:\n]+\\):\\([0-9]+\\)[ *]*>.*\n"
+                          (gud-bashdb-marker-acc))
+       (setq
+        ;; Extract the frame position from the marker.
+        gud-last-frame (cons
+                        (substring (gud-bashdb-marker-acc)
+                                   (match-beginning 1)
+                                   (match-end 1))
+                        (string-to-int 
+                         (substring (gud-bashdb-marker-acc)
+                                    (match-beginning 2) 
+                                    (match-end 2))))
+        ;; Append any text before the marker to the output we're going
+        ;; to return - we don't include the marker in this text.
+        output (concat output
+                       (substring (gud-bashdb-marker-acc) 0 (match-beginning 0))))
+        ;; Set the accumulator to the remaining text.
+       (set
+        (gud-bashdb-marker-acc-quote) (substring 
+                                       (gud-bashdb-marker-acc) (match-end 0))))
+
+      ;; Does the remaining text look like it might end with the
+      ;; beginning of another marker?  If it does, then keep it in
+      ;; (gud-bashdb-marker-acc) until we receive the rest of it.  Since we
+      ;; know the full marker regexp above failed, it's pretty simple to
+      ;; test for marker starts.
+      (if (string-match "^\\([^:\n]+\\):\\([0-9]+\\)[ *]*>" (gud-bashdb-marker-acc))
+         (progn
+           ;; Everything before the potential marker start can be output.
+           (setq output (concat output (substring (gud-bashdb-marker-acc)
+                                                  0 (match-beginning 0))))
+           ;; Everything after, we save, to combine with later input.
+           (set (gud-bashdb-marker-acc-quote)
+                (substring (gud-bashdb-marker-acc) (match-beginning 0))))
+       
+       (setq output (concat output (gud-bashdb-marker-acc)))
+       (set (gud-bashdb-marker-acc-quote) ""))
+      
+      output)))
+      
+(defun gud-bashdb-find-file (f)
+  (find-file-noselect f))
+
+;;;###autoload
+(defun bashdb (command-line)
+  "Run bashdb on program FILE in buffer *gud-FILE*.
+The directory containing FILE becomes the initial working directory
+and source-file directory for your debugger."
+  (interactive
+   (if xemacsp
+       (list (read-from-minibuffer "Run bashdb (like this): "
+                                  (if (consp gud-bashdb-history)
+                                      (car gud-bashdb-history)
+                                    (format "%s " gud-bashdb-command-name))
+                                  nil nil
+                                  '(gud-bashdb-history . 1)))
+     (list (gud-query-cmdline 'bashdb))
+     ))
+  
+  (if xemacsp
+      (progn
+       (gud-overload-functions '((gud-massage-args . gud-bashdb-massage-args)
+                                 (gud-marker-filter . gud-bashdb-marker-filter)
+                                 (gud-find-file . gud-bashdb-find-file)))
+       (gud-common-init command-line gud-bashdb-command-name))
+    (gud-common-init command-line 'gud-bashdb-massage-args
+                    'gud-bashdb-marker-filter 'gud-bashdb-find-file)
+    (set (make-local-variable 'gud-minor-mode) 'bashdb))
+
+;; Unsupported commands
+;;  condition foo      set break condition to foo
+;;  condition  clear break condition
+;;  display EXP        evaluate and display EXP for each debug step
+;;  display            show a list of display expressions
+;;  undisplay N        remove display expression N
+;;  ! string   passes string to a shell
+;;  quit               quit
+
+  (gud-def gud-break       "break %l"     "\C-b" "Set breakpoint at current line.")
+  (gud-def gud-list-break  "break"        "b"    "List breakpoints & break condition.")
+  (gud-def gud-remove      "delete %l"    "\C-d" "Remove breakpoint at current line")
+  (gud-def gud-remove-all  "delete"       "d"    "Clear all breakpoints")
+  (gud-def gud-cont   "continue"          "\C-r" "Continue with display.")
+  (gud-def gud-next   "next"              "\C-n" "Step one line (skip functions).")
+  (gud-def gud-print  "print %e"          "\C-p" "Evaluate bash expression at point.")
+  (gud-def gud-help   "help"              "h"    "Show all commands.")
+  (gud-def gud-trace  "trace"             "t"    "Toggle execution trace on/off")
+
+  (setq comint-prompt-regexp "^bashdb> ")
+  (setq paragraph-start comint-prompt-regexp)
+  (run-hooks 'bashdb-mode-hook))
+
+(provide 'bashdb)
+;; bashdb.el ends here
diff --git a/examples/obashdb/bashdb.vaughan b/examples/obashdb/bashdb.vaughan
new file mode 100644 (file)
index 0000000..6a24973
--- /dev/null
@@ -0,0 +1,561 @@
+#! /bin/bash
+# bashdb - Bash shell debugger
+#
+# Adapted from an idea in O'Reilly's `Learning the Korn Shell'
+# Copyright (C) 1993-1994 O'Reilly and Associates, Inc.
+# Copyright (C) 1998, 1999, 2001 Gary V. Vaughan <gvv@techie.com>>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# NOTE:
+#
+# This program requires bash 2.x.
+# If bash 2.x is installed as "bash2", you can invoke  bashdb like this:
+#
+#   DEBUG_SHELL=/bin/bash2 /bin/bash2 bashdb script.sh
+
+# TODO:
+#
+# break [regexp]
+# cond [break] [condition]
+# tbreak [regexp|+lines]
+# restart
+# Variable watchpoints
+# Output colourization
+# History with csh ^ substitution? Or write a readline frontend?
+# Instrument shell functions with the _steptrap in $_potbelliedpig
+# Instrument `source' and `.' files in $_potbelliedpig
+# be cleverer about lines we allow breakpoints to be set on
+# break [function_name]
+
+
+echo 'Bash Debugger version 1.2.4'
+
+export _dbname=$(echo "X$0"|sed -e 's,^X,,' -e 's,^.*/,,')
+
+if test $# -lt 1; then
+  echo "$_dbname: Usage: $_dbname <filename>" >&2
+  exit 1
+fi
+
+_guineapig=$1
+
+if test ! -r $1; then
+  echo "$_dbname: Cannot read file '$_guineapig'." >&2
+  exit 1
+fi
+
+shift
+
+__debug=${TMPDIR-/tmp}/bashdb.$$
+sed -e '/^# bashdb - Bash shell debugger/,/^# -- DO NOT DELETE THIS LINE -- /d' "$0" > $__debug
+cat $_guineapig >> $__debug
+exec ${DEBUG_SHELL-bash} $__debug $_guineapig "$@"
+
+exit 1
+
+# -- DO NOT DELETE THIS LINE -- The program depends on it
+
+#bashdb preamble
+# $1 name of the original guinea pig script
+
+__debug=$0
+_guineapig=$1
+
+shift
+
+function _steptrap
+{
+  local i=0
+  
+  _curline=$1
+
+  if [ -n "$_disps" ]
+  then
+    while (( $i < ${#_disps[@]} ))
+    do
+      if [ -n "${_disps[$i]}" ]
+      then
+        _msg "${_disps[$i]}: \c"
+        eval _msg ${_disps[$i]}
+      fi
+      let i=$i+1
+    done
+  fi
+
+  if (( $_trace )); then
+    _showline $_curline
+  fi
+  
+  if (( $_steps >= 0 )); then
+    let _steps="$_steps - 1"
+  fi
+
+  if _at_linenumbp ; then
+    _msg "Reached breakpoint at line $_curline"
+    _showline $_curline
+    _cmdloop
+  elif [ -n "$_brcond" ] && eval $_brcond; then
+    _msg "Break condition $_brcond true at line $_curline"
+    _showline $_curline
+    _cmdloop
+  elif (( $_steps == 0 && $_curline > 1)); then
+    # Assuming a real script will have the "#! /bin/sh" at line 1,
+    # assume that when $_curline == 1 we are inside backticks.
+    if (( ! $_trace )); then
+      _msg "Stopped at line $_curline"
+      _showline $_curline
+    fi
+    _cmdloop
+  fi
+}
+
+function _setbp
+{
+  local i f line
+
+  if [ -z "$1" ]
+  then
+    _listbp
+  elif [ $(echo $1 | grep '^\+*[1-9][0-9]*') ]
+  then
+    case $1 in
+    +*)
+      let f="$1 + `expr $1 : '+*\([1-9][0-9]*\)'`"
+      ;;
+    *)
+      let f=$1
+      ;;
+    esac
+
+    # find the next valid line
+    line="${_lines[$f]}"
+    while _invalidbreakp $f
+    do
+      let f="$f + 1"
+      line="${_lines[$f]}"
+    done
+
+    if (( $f != $1 ))
+    then
+      _msg "Line $1 is not a valid breakpoint"
+    fi
+
+    if [ -n "${_lines[$f]}" ]
+    then
+      _linebp=($(echo $( (for i in ${_linebp[*]} $1; do
+      echo $i; done) | sort -n) ))
+      _msg "Breakpoint set at line $f"
+    else
+      _msg "Breakpoints can only be set on executable lines"
+    fi
+  else
+    _msg "Please specify a numeric line number"
+  fi
+}
+
+function _listbp
+{
+  local i
+  
+  if [ -n "$_linebp" ]
+  then
+    _msg "Breakpoints:"
+    for i in ${_linebp[*]}; do
+      _showline $i
+    done
+  else
+    _msg "No breakpoints have been set"
+  fi
+}
+
+function _clearbp
+{
+  local i
+  if [ -z "$1" ]; then
+    read -e -p "Delete all breakpoints? "
+    case $REPLY in
+    y*)
+      unset _linebp[*]
+      _msg "All breakpoints have been cleared"
+      ;;
+    esac
+  elif [ $(echo $1 | grep '^[0-9]*') ]; then
+    _linebp=($(echo $(for i in ${_linebp[*]}; do
+              if (( $1 != $i )); then echo $1;  fi; done) ))
+    _msg "Breakpoint cleared at line $1"
+  else
+    _msg "Please specify a numeric line number"
+  fi
+}
+
+function _setbc
+{
+  if [ -n "$*" ]
+  then
+    _brcond=$args
+    _msg "Break when true: $_brcond"
+  else
+    _brcond=
+    _msg "Break condition cleared"
+  fi
+}
+
+function _setdisp
+{
+  if [ -z "$1" ]
+  then
+    _listdisp
+  else
+    _disps[${#_disps[@]}]="$1"
+    if (( ${#_disps[@]} < 10 ))
+    then
+      _msg " ${#_disps[@]}: $1"
+    else
+      _msg "${#_disps[@]}: $1"
+    fi
+  fi
+}
+
+function _listdisp
+{
+  local i=0 j
+  
+  if [ -n "$_disps" ]
+  then
+    while (( $i < ${#_disps[@]} ))
+    do
+      let j=$i+1
+    if (( ${#_disps[@]} < 10 ))
+    then
+      _msg " $j: ${_disps[$i]}"
+    else
+      _msg "$j: ${_disps[$i]}"
+    fi
+      let i=$j
+    done
+  else
+    _msg "No displays have been set"
+  fi
+}
+
+function _cleardisp
+{
+  if (( $# < 1 ))
+  then
+    read -e -p "Delete all display expressions? "
+    case $REPLY in
+    y*)
+      unset _disps[*]
+      _msg "All breakpoints have been cleared"
+      ;;
+    esac
+  elif [ $(echo $1 | grep '^[0-9]*') ]
+  then
+    unset _disps[$1]
+    _msg "Display $i has been cleared"
+  else
+    _listdisp
+    _msg "Please specify a numeric display number"
+  fi
+}   
+
+function _cmdloop
+{
+  local cmd args
+
+  while read -e -p "bashdb> " cmd args; do
+    test -n "$cmd" || { set $_lastcmd; cmd=$1; shift; args=$*; }
+    if [ -n "$cmd" ]
+    then
+      case $cmd in
+       b|br|bre|brea|break)
+         _setbp $args
+         _lastcmd="break $args"
+         ;;
+       co|con)
+         _msg "ambiguous command: '$cmd', condition, continue?"
+         ;;
+       cond|condi|condit|conditi|conditio|condition)
+         _setbc $args
+         _lastcmd="condition $args"
+         ;;
+       c|cont|conti|contin|continu|continue)
+         _lastcmd="continue"
+         return
+         ;;
+       d)
+         _msg "ambiguous command: '$cmd', delete, display?"
+         ;;
+       de|del|dele|delet|delete)
+         _clearbp $args
+         _lastcmd="delete $args"
+         ;;
+       di|dis|disp|displ|displa|display)
+         _setdisp $args
+         _lastcmd="display $args"
+         ;;
+       \?|h|he|hel|help)
+         _menu
+         _lastcmd="help"
+         ;;
+       l|li|lis|list)
+         _displayscript $args
+         # _lastcmd is set in the _displayscript function
+         ;;
+       p|pr|pri|prin|print)
+         _examine $args
+         _lastcmd="print $args"
+         ;;
+       q|qu|qui|quit)
+         exit
+         ;;
+       s|st|ste|step|n|ne|nex|next)
+         let _steps=${args:-1}
+         _lastcmd="next $args"
+         return
+         ;;
+       t|tr|tra|trac|trace)
+         _xtrace
+         ;;
+       u|un|und|undi|undis|undisp|undispl|undispla|undisplay)
+         _cleardisp $args
+         _lastcmd="undisplay $args"
+         ;;
+       !*)
+         eval ${cmd#!} $args
+         _lastcmd="$cmd $args"
+         ;;
+       *)
+         _msg "Invalid command: '$cmd'"
+         ;;
+      esac
+    fi
+  done
+}
+
+function _at_linenumbp
+{
+  local i=0
+
+  if [ "$_linebp" ]
+  then
+    while (( $i < ${#_linebp[@]} )); do
+      if (( ${_linebp[$i]} == $_curline )); then
+       return 0
+      fi
+      let i=$i+1
+    done
+  fi
+
+  return 1
+}
+
+function _invalidbreakp
+{
+  local line=${_lines[$1]}
+
+  if test -z "$line" \
+      || expr "$line" : '[ \t]*#.*' > /dev/null \
+      || expr "$line" : '[ \t]*;;[ \t]*$' > /dev/null \
+      || expr "$line" : '[ \t]*[^)]*)[ \t]*$' > /dev/null \
+      || expr "$line" : '[ \t]*;;[ \t]*#.**$' > /dev/null \
+      || expr "$line" : '[ \t]*[^)]*)[ \t]*;;[ \t]*$' > /dev/null \
+      || expr "$line" : '[ \t]*[^)]*)[ \t]*;;*[ \t]*#.*$' > /dev/null
+  then
+    return 0
+  fi
+
+  return 1
+}
+
+function _examine
+{
+  if [ -n "$*" ]
+  then
+    _msg "$args: \c"
+    eval _msg $args
+  else
+    _msg "Nothing to print"
+  fi
+}
+
+function _displayscript
+{
+  local i j start end bp cl
+
+  if (( $# == 1 ))
+  then
+    if test $1 = "%"
+    then
+      let start=1
+      let end=${#_lines[@]}
+    else
+      let start=$1-5
+      let end=$1+5
+    fi
+  elif (( $# > 1 ))
+  then
+    if test $1 = "^"
+    then
+      let start=1
+    else
+      let start=$1
+    fi
+
+    if test $2 = "\$"
+    then
+      let end=${#_lines[@]}
+    else
+      let end=$2
+    fi
+  else
+    let start=$_curline-5
+    let end=$_curline+5
+  fi
+
+  if (( $start < 1 ))
+  then
+    start=1
+  fi
+  if (( $end > ${#_lines[@]} ))
+  then
+    end=${#_lines[@]}
+  fi
+
+  let cl=$end-$start
+  if (( $cl > ${LINES-24} ))
+  then
+    pager=${PAGER-more}
+  else
+    pager=cat
+  fi
+  
+  i=$start
+  ( while (( $i <= $end )); do
+      _showline $i
+      let i=$i+1
+    done ) 2>&1 | $pager
+
+  # calculate the next block of lines
+  let start=$end+1
+  let end=$start+11
+  if (( $end > ${#_lines[@]} ))
+  then
+    end=${#_lines[@]}
+  fi
+
+  _lastcmd="list $start $end"
+}
+
+function _xtrace
+{
+  let _trace="! $_trace"
+  if (( $_trace )); then
+    _msg "Execution trace on"
+  else
+    _msg "Execution trace off"
+  fi
+}
+       
+function _msg
+{
+  echo -e "$@" >&2
+}
+
+function _showline
+{
+  local i=0 bp=' ' line=$1
+   
+  while (( $i < ${#_linebp[@]} ))
+  do
+    if [ ${_linebp[$i]} ] && (( ${_linebp[$i]} == $line ))
+    then
+      bp='*'
+    fi
+    let i=$i+1
+  done
+
+  if  (( $_curline == $line )); then
+    cl=">"
+  else
+    cl=" "
+  fi
+
+  if (( $line < 100 )); then
+    _msg "$_guineapig:$line   $bp $cl${_lines[$line]}"
+  elif (( $line < 10 )); then
+    _msg "$_guineapig:$line  $bp $cl${_lines[$line]}"
+  elif (( $line > 0 )); then
+    _msg "$_guineapig:$line $bp $cl${_lines[$line]}"
+  fi
+}
+
+function _cleanup
+{
+  rm -f $__debug $_potbelliedpig 2> /dev/null
+}
+
+function _menu
+{
+  _msg 'bashdb commands:
+       break N         set breakpoint at line N
+       break           list breakpoints & break condition
+       condition foo   set break condition to foo
+       condition       clear break condition
+       delete N        clear breakpoint at line N
+       delete          clear all breakpoints
+       display EXP     evaluate and display EXP for each debug step
+       display         show a list of display expressions
+       undisplay N     remove display expression N
+       list N M        display all lines of script between N and M
+       list N          display 5 lines of script either side of line N
+       list            display 5 lines if script either side of current line
+       continue        continue execution upto next breakpoint
+       next [N]        execute [N] statements (default 1)
+       print expr      prints the value of an expression
+       trace           toggle execution trace on/off
+       help            print this menu
+       ! string        passes string to a shell
+       quit            quit'
+}
+
+
+_linebp=
+let _trace=0
+let _i=1
+
+# Be careful about quoted newlines
+_potbelliedpig=${TMPDIR-/tmp}/$_guineapig.$$
+sed 's,\\$,\\\\,' $_guineapig > $_potbelliedpig
+
+_msg "Reading source from file: $_guineapig"
+while read; do
+  _lines[$_i]=$REPLY
+  let _i=$_i+1
+done < $_potbelliedpig
+
+trap _cleanup EXIT
+# Assuming a real script will have the "#! /bin/sh" at line 1,
+# don't stop at line 1 on the first run
+let _steps=2
+LINENO=-2
+trap '_steptrap $LINENO' DEBUG
+:
index e37a4181c21c7bcc1c132f011cc2518ad4f12e61..ddad1676ff3ca6f9285c0f1de8bea8df82855968 100644 (file)
@@ -419,14 +419,14 @@ rl_expand_prompt (prompt)
       t = ++p;
       local_prompt = expand_prompt (p, &prompt_visible_length,
                                       &prompt_last_invisible,
-                                      (int *)NULL,
+                                      &prompt_invis_chars_first_line,
                                       &prompt_physical_chars);
       c = *t; *t = '\0';
       /* The portion of the prompt string up to and including the
         final newline is now null-terminated. */
       local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
                                                   (int *)NULL,
-                                                  &prompt_invis_chars_first_line,
+                                                  (int *)NULL,
                                                   (int *)NULL);
       *t = c;
       local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
index acd261e8c5bb187eb37e9b76e46ad20e7ddb912c..3b964302bb269432b39da3df65dbeb33f7bcd579 100644 (file)
@@ -419,14 +419,14 @@ rl_expand_prompt (prompt)
       t = ++p;
       local_prompt = expand_prompt (p, &prompt_visible_length,
                                       &prompt_last_invisible,
-                                      (int *)NULL,
+                                      &prompt_invis_chars_first_line,
                                       &prompt_physical_chars);
       c = *t; *t = '\0';
       /* The portion of the prompt string up to and including the
         final newline is now null-terminated. */
       local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
                                                   (int *)NULL,
-                                                  &prompt_invis_chars_first_line,
+                                                  (int *)NULL,
                                                   (int *)NULL);
       *t = c;
       local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
@@ -938,7 +938,7 @@ rl_redisplay ()
             second and subsequent lines start at inv_lbreaks[N], offset by
             OFFSET (which has already been calculated above).  */
 
-#define WRAP_OFFSET(line, offset)  ((line == 0) \
+#define WRAP_OFFSET<(line, offset)  ((line == 0) \
                                        ? (offset ? prompt_invis_chars_first_line : 0) \
                                        : ((line == prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0))
 #define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
@@ -1009,7 +1009,8 @@ rl_redisplay ()
                 out (e.g., when printing the i-search prompt).  In general,
                 the case of the new line being shorter than the old.
                 Incomplete */
-             else if (linenum == 1 && prompt_physical_chars > _rl_screenwidth &&
+             else if (linenum == prompt_last_screen_line &&
+                      prompt_physical_chars > _rl_screenwidth &&
                       wrap_offset != prompt_invis_chars_first_line &&
                       _rl_last_c_pos == out &&
 #endif
@@ -1842,7 +1843,8 @@ _rl_move_cursor_relative (new, data)
         prompt string, since they're both buffer indices and DPOS is a
         desired display position. */
       if ((new > prompt_last_invisible) ||             /* XXX - don't use woff here */
-         (prompt_physical_chars > _rl_screenwidth && _rl_last_v_pos == 1 &&
+         (prompt_physical_chars > _rl_screenwidth &&
+          _rl_last_v_pos == prompt_last_screen_line &&
           wrap_offset != woff &&
           new > (prompt_last_invisible-_rl_screenwidth-wrap_offset)))
        {
index c455b1502711058d2fd8acb26a51187372242694..a51fe2dac31b7ea4cd362ef6da17b2b39731f2be 100644 (file)
@@ -500,7 +500,7 @@ _get_tty_settings (tty, tiop)
        }
       if (OUTPUT_BEING_FLUSHED (tiop))
        {
-#if defined (FLUSHO) && defined (_AIX41)
+#if defined (FLUSHO)
          _rl_errmsg ("warning: turning off output flushing");
          tiop->c_lflag &= ~FLUSHO;
          break;
index cd724f6f8d9bdc64b226fddabeddada6d0407918..694cc0660b68d17d073c7f8d907ce3cddbad8c4d 100644 (file)
   #pragma alloca
 #endif /* _AIX && RISC6000 && !__GNUC__ */
 
+#if defined (__QNX__)
+#  undef HAVE_LSTAT
+#endif
+
 #include <bashtypes.h>
 #include <errno.h>
 
diff --git a/lib/sh/getcwd.c~ b/lib/sh/getcwd.c~
new file mode 100644 (file)
index 0000000..cd724f6
--- /dev/null
@@ -0,0 +1,313 @@
+/* getcwd.c -- stolen from the GNU C library and modified to work with bash. */
+
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place, Suite 330, Boston, MA 02111 USA.  */
+
+#include <config.h>
+
+#if !defined (HAVE_GETCWD)
+
+#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
+  #pragma alloca
+#endif /* _AIX && RISC6000 && !__GNUC__ */
+
+#include <bashtypes.h>
+#include <errno.h>
+
+#if defined (HAVE_LIMITS_H)
+#  include <limits.h>
+#endif
+
+#if defined (HAVE_UNISTD_H)
+#  include <unistd.h>
+#endif
+
+#include <posixdir.h>
+#include <posixstat.h>
+#include <maxpath.h>
+#include <memalloc.h>
+
+#include <bashansi.h>
+
+#include <xmalloc.h>
+
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+#if !defined (HAVE_LSTAT)
+#  define lstat stat
+#endif
+
+#if !defined (NULL)
+#  define NULL 0
+#endif
+
+/* Get the pathname of the current working directory,
+   and put it in SIZE bytes of BUF.  Returns NULL if the
+   directory couldn't be determined or SIZE was too small.
+   If successful, returns BUF.  In GNU, if BUF is NULL,
+   an array is allocated with `malloc'; the array is SIZE
+   bytes long, unless SIZE <= 0, in which case it is as
+   big as necessary.  */
+#if defined (__STDC__)
+char *
+getcwd (char *buf, size_t size)
+#else /* !__STDC__ */
+char *
+getcwd (buf, size)
+     char *buf;
+     size_t size;
+#endif /* !__STDC__ */
+{
+  static const char dots[]
+    = "../../../../../../../../../../../../../../../../../../../../../../../\
+../../../../../../../../../../../../../../../../../../../../../../../../../../\
+../../../../../../../../../../../../../../../../../../../../../../../../../..";
+  const char *dotp, *dotlist;
+  size_t dotsize;
+  dev_t rootdev, thisdev;
+  ino_t rootino, thisino;
+  char path[PATH_MAX + 1];
+  register char *pathp;
+  char *pathbuf;
+  size_t pathsize;
+  struct stat st;
+  int saved_errno;
+
+  if (buf != NULL && size == 0)
+    {
+      errno = EINVAL;
+      return ((char *)NULL);
+    }
+
+  pathsize = sizeof (path);
+  pathp = &path[pathsize];
+  *--pathp = '\0';
+  pathbuf = path;
+
+  if (stat (".", &st) < 0)
+    return ((char *)NULL);
+  thisdev = st.st_dev;
+  thisino = st.st_ino;
+
+  if (stat ("/", &st) < 0)
+    return ((char *)NULL);
+  rootdev = st.st_dev;
+  rootino = st.st_ino;
+
+  saved_errno = 0;
+
+  dotsize = sizeof (dots) - 1;
+  dotp = &dots[sizeof (dots)];
+  dotlist = dots;
+  while (!(thisdev == rootdev && thisino == rootino))
+    {
+      register DIR *dirstream;
+      register struct dirent *d;
+      dev_t dotdev;
+      ino_t dotino;
+      char mount_point;
+      int namlen;
+
+      /* Look at the parent directory.  */
+      if (dotp == dotlist)
+       {
+         /* My, what a deep directory tree you have, Grandma.  */
+         char *new;
+         if (dotlist == dots)
+           {
+             new = (char *)malloc (dotsize * 2 + 1);
+             if (new == NULL)
+               goto lose;
+             memcpy (new, dots, dotsize);
+           }
+         else
+           {
+             new = (char *)realloc ((PTR_T) dotlist, dotsize * 2 + 1);
+             if (new == NULL)
+               goto lose;
+           }
+         memcpy (&new[dotsize], new, dotsize);
+         dotp = &new[dotsize];
+         dotsize *= 2;
+         new[dotsize] = '\0';
+         dotlist = new;
+       }
+
+      dotp -= 3;
+
+      /* Figure out if this directory is a mount point.  */
+      if (stat (dotp, &st) < 0)
+       goto lose;
+      dotdev = st.st_dev;
+      dotino = st.st_ino;
+      mount_point = dotdev != thisdev;
+
+      /* Search for the last directory.  */
+      dirstream = opendir (dotp);
+      if (dirstream == NULL)
+       goto lose;
+      while ((d = readdir (dirstream)) != NULL)
+       {
+         if (d->d_name[0] == '.' &&
+             (d->d_name[1] == '\0' ||
+               (d->d_name[1] == '.' && d->d_name[2] == '\0')))
+           continue;
+         if (mount_point || d->d_fileno == thisino)
+           {
+             char *name;
+
+             namlen = D_NAMLEN(d);
+             name = (char *)
+               alloca (dotlist + dotsize - dotp + 1 + namlen + 1);
+             memcpy (name, dotp, dotlist + dotsize - dotp);
+             name[dotlist + dotsize - dotp] = '/';
+             memcpy (&name[dotlist + dotsize - dotp + 1],
+                     d->d_name, namlen + 1);
+             if (lstat (name, &st) < 0)
+               {
+#if 0
+                 int save = errno;
+                 (void) closedir (dirstream);
+                 errno = save;
+                 goto lose;
+#else
+                 saved_errno = errno;
+#endif
+               }
+             if (st.st_dev == thisdev && st.st_ino == thisino)
+               break;
+           }
+       }
+      if (d == NULL)
+       {
+#if 0
+         int save = errno;
+#else
+         int save = errno ? errno : saved_errno;
+#endif
+         (void) closedir (dirstream);
+         errno = save;
+         goto lose;
+       }
+      else
+       {
+         size_t space;
+
+         while ((space = pathp - pathbuf) <= namlen)
+           {
+             char *new;
+
+             if (pathbuf == path)
+               {
+                 new = (char *)malloc (pathsize * 2);
+                 if (!new)
+                   goto lose;
+               }
+             else
+               {
+                 new = (char *)realloc ((PTR_T) pathbuf, (pathsize * 2));
+                 if (!new)
+                   goto lose;
+                 pathp = new + space;
+               }
+             (void) memcpy (new + pathsize + space, pathp, pathsize - space);
+             pathp = new + pathsize + space;
+             pathbuf = new;
+             pathsize *= 2;
+           }
+
+         pathp -= namlen;
+         (void) memcpy (pathp, d->d_name, namlen);
+         *--pathp = '/';
+         (void) closedir (dirstream);
+       }
+
+      thisdev = dotdev;
+      thisino = dotino;
+    }
+
+  if (pathp == &path[sizeof(path) - 1])
+    *--pathp = '/';
+
+  if (dotlist != dots)
+    free ((PTR_T) dotlist);
+
+  {
+    size_t len = pathbuf + pathsize - pathp;
+    if (buf == NULL)
+      {
+       if (len < (size_t) size)
+         len = size;
+       buf = (char *) malloc (len);
+       if (buf == NULL)
+         goto lose2;
+      }
+    else if ((size_t) size < len)
+      {
+       errno = ERANGE;
+       goto lose2;
+      }
+    (void) memcpy((PTR_T) buf, (PTR_T) pathp, len);
+  }
+
+  if (pathbuf != path)
+    free (pathbuf);
+
+  return (buf);
+
+ lose:
+  if ((dotlist != dots) && dotlist)
+    {
+      int e = errno;
+      free ((PTR_T) dotlist);
+      errno = e;
+    }
+
+ lose2:
+  if ((pathbuf != path) && pathbuf)
+    {
+      int e = errno;
+      free ((PTR_T) pathbuf);
+      errno = e;
+    }
+  return ((char *)NULL);
+}
+
+#if defined (TEST)
+#  include <stdio.h>
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  char b[PATH_MAX];
+
+  if (getcwd(b, sizeof(b)))
+    {
+      printf ("%s\n", b);
+      exit (0);
+    }
+  else
+    {
+      perror ("cwd: getcwd");
+      exit (1);
+    }
+}
+#endif /* TEST */
+#endif /* !HAVE_GETCWD */
index 3bb0ce796644a70a1c8a6591bf3b755384a3dfe8..b8645aa35aac191490189d25f04a46aef4d0da3d 100644 (file)
 #include "posixstat.h"
 #include "posixtime.h"
 
-#if defined (qnx)
-#  if defined (qnx6)
+#if defined (__QNX__)
+#  if defined (__QNXNTO__)
 #    include <sys/netmgr.h>
 #  else
 #    include <sys/vc.h>
-#  endif /* !qnx6 */
-#endif /* qnx */
+#  endif /* !__QNXNTO__ */
+#endif /* __QNX__ */
 
 #if defined (HAVE_UNISTD_H)
 #  include <unistd.h>
@@ -391,11 +391,11 @@ initialize_shell_variables (env, privmode)
   set_auto_export (temp_var);  /* XXX */
 #endif
 
-#if defined (qnx)
+#if defined (__QNX__)
   /* set node id -- don't import it from the environment */
   {
     char node_name[22];
-#  if defined (qnx6)
+#  if defined (__QNXNTO__)
     netmgr_ndtostr(ND2S_LOCAL_STR, ND_LOCAL_NODE, node_name, sizeof(node_name));
 #  else
     qnx_nidtostr (getnid (), node_name, sizeof (node_name));
index 0e37af212da8d7a29867ef5743215b87935f15da..3bb0ce796644a70a1c8a6591bf3b755384a3dfe8 100644 (file)
@@ -1604,7 +1604,11 @@ FUNCTION_DEF *
 find_function_def (name)
      const char *name;
 {
+#if defined (DEBUGGER)
   return ((FUNCTION_DEF *)hash_lookup (name, shell_function_defs));
+#else
+  return ((FUNCTION_DEF *)0);
+#endif
 }
 
 /* Return the value of VAR.  VAR is assumed to have been the result of a
@@ -2147,6 +2151,7 @@ bind_function (name, value)
   return (entry);
 }
 
+#if defined (DEBUGGER)
 /* Bind a function definition, which includes source file and line number
    information in addition to the command, into the FUNCTION_DEF hash table.*/
 void
@@ -2175,6 +2180,7 @@ bind_function_def (name, value)
       elt->data = (PTR_T *)entry;
     }
 }
+#endif /* DEBUGGER */
 
 /* Add STRING, which is of the form foo=bar, to the temporary environment
    HASH_TABLE (temporary_env).  The functions in execute_cmd.c are
@@ -2367,6 +2373,7 @@ unbind_func (name)
   return 0;  
 }
 
+#if defined (DEBUGGER)
 int
 unbind_function_def (name)
      const char *name;
@@ -2388,6 +2395,7 @@ unbind_function_def (name)
 
   return 0;  
 }
+#endif /* DEBUGGER */
 
 /* Make the variable associated with NAME go away.  HASH_LIST is the
    hash table from which this variable should be deleted (either