# Copyright 2002, 2003, 2007, 2008, 2009, 2010, 2011
# Free Software Foundation, Inc.

# 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 3 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, see <http://www.gnu.org/licenses/>.

# This file was written by Tom Tromey <tromey@redhat.com>

# This file is part of the gdb testsuite.

#
# Tests for readline operations.
#

# This function is used to test operate-and-get-next.
# NAME is the name of the test.
# ARGS is a list of alternating commands and expected results.
proc operate_and_get_next {name args} {
  global gdb_prompt

  set my_gdb_prompt "($gdb_prompt| >)"

  set reverse {}
  foreach {item result} $args {
    verbose "sending $item"
    sleep 1

    # We can't use gdb_test here because we might see a " >" prompt.
    set status 0
    send_gdb "$item\n"
    gdb_expect {
      -re "$item" {
	# Ok
      }
      timeout {
	set status 1
      }
    }

    if {! $status} {
      gdb_expect {
	-re "$result" {
	  # Ok.
	}
	timeout {
	  set status 1
	}
      }
    }

    if {$status} {
      fail "$name - send $item"
      return 0
    }
    pass "$name - send $item"

    set reverse [linsert $reverse 0 $item $result]
  }

  # Now use C-p to go back to the start.
  foreach {item result} $reverse {
    # Actually send C-p followed by C-l.  This lets us recognize the
    # command when gdb prints it again.
    send_gdb "\x10\x0c"
    set status 0
    gdb_expect {
      -re "$item" {
	# Ok
      }
      timeout {
	set status 1
      }
    }
    if {$status} {
      fail "$name - C-p to $item"
      return 0
    }
    pass "$name - C-p to $item"
  }

  # Now C-o through the list.  Don't send the command, since it is
  # already there.  Strip off the first command from the list so we
  # can see the next command inside the loop.
  set count 0
  foreach {item result} $args {
    set status 0

    # If this isn't the first item, make sure we see the command at
    # the prompt.
    if {$count > 0} {
      gdb_expect {
	-re ".*$item" {
	  # Ok
	}
	timeout {
	  set status 1
	}
      }
    }

    if {! $status} {
      # For the last item, send a simple \n instead of C-o.
      if {$count == [llength $args] - 2} {
	send_gdb "\n"
      } else {
	# 15 is C-o.
	send_gdb [format %c 15]
      }
      set status 0
      gdb_expect {
	-re "$result" {
	  # Ok
	}
	timeout {
	  set status 1
	}
      }
    }

    if {$status} {
      fail "$name - C-o for $item"
      return 0
    }
    pass "$name - C-o for $item"

    set count [expr {$count + 2}]
  }

  # Match the prompt so the next test starts at the right place.
  gdb_test "" ".*" "$name - final prompt"

  return 1
}


if $tracelevel {
  strace $tracelevel
}

gdb_start
gdb_reinitialize_dir $srcdir/$subdir

set oldtimeout1 $timeout
set timeout 30


# A simple test of operate-and-get-next.
operate_and_get_next "Simple operate-and-get-next" \
  "p 1" ".* = 1" \
  "p 2" ".* = 2" \
  "p 3" ".* = 3"

# Test operate-and-get-next with a secondary prompt.
operate_and_get_next "operate-and-get-next with secondary prompt" \
  "if 1 > 0" "" \
  "p 5" "" \
  "end" ".* = 5"

# Verify that arrow keys work in secondary prompts.  The control
# sequence is a hard-coded VT100 up arrow.
gdb_test "print 42" "\\\$\[0-9\]* = 42"
set msg "arrow keys with secondary prompt"
gdb_test_multiple "if 1 > 0\n\033\[A\033\[A\nend" $msg {
    -re ".*\\\$\[0-9\]* = 42\r\n$gdb_prompt $" {
	pass $msg
    }
    -re ".*Undefined command:.*$gdb_prompt $" {
	fail $msg
    }
}

# Now repeat the first test with a history file that fills the entire
# history list.

if [info exists env(GDBHISTFILE)] {
    set old_gdbhistfile $env(GDBHISTFILE)
}
if [info exists env(HISTSIZE)] {
    set old_histsize $env(HISTSIZE)
}
set env(GDBHISTFILE) "${srcdir}/${subdir}/gdb_history"
set env(HISTSIZE) "10"

gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir

operate_and_get_next "Simple operate-and-get-next" \
  "p 7" ".* = 7" \
  "p 8" ".* = 8" \
  "p 9" ".* = 9"


# Restore globals modified in this test...
if [info exists old_gdbhistfile] {
    set env(GDBHISTFILE) $old_gdbhistfile
} else {
    unset env(GDBHISTFILE)
}
if [info exists old_histsize] {
    set env(HISTSIZE) $old_histsize
} else {
    unset env(HISTSIZE)
}
set timeout $oldtimeout1

return 0
