# Copyright 1999-2013 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/>.

#
# Test basic Machine interface (MI) operations
#
# Verify that, using the MI, we can load a program and do
# other basic things that are used by all test files through  mi_gdb_exit,
# mi_gdb_start, mi_delete_breakpoints, mi_gdb_reinitialize_dir and
# mi_gdb_load, so we can safely use those.
#
# The goal is not to test gdb functionality, which is done by other tests,
# but the command syntax and correct output response to MI operations.
#

load_lib mi-support.exp
set MIFLAGS "-i=mi"

gdb_exit
if [mi_gdb_start separate-inferior-tty] {
    continue
}

standard_testfile basics.c
set escapedobjdir [string_to_regexp ${objdir}]
set envirodir [string_to_regexp ${objdir}/${subdir}]

if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
     untested mi-basics.exp
     return -1
}

# In this file we want to test if the operations needed by the following
# procedures work, so it makes no sense using them here.

# mi_delete_breakpoints
# mi_gdb_reinitialize_dir $srcdir/$subdir
# mi_gdb_load ${binfile}

# Test if the MI interpreter has been configured

proc test_mi_interpreter_selection {} {
    global mi_gdb_prompt
    global gdb_prompt

    # All this test expects is to get the prompt back
    # with no syntax error message
    if ![mi_gdb_test "-gdb-version" "~\"GNU gdb.*" "acceptance of MI operations"] {
	return 1
    } 

    note "Skipping all other MI tests."
    return 0
}

proc test_exec_and_symbol_mi_operatons {} {
    global mi_gdb_prompt
    global binfile

    # Load symbols and specify executable on a single operation
    # Tests:
    # -file-exec-and-symbols

    if [mi_gdb_test "-file-exec-and-symbols ${binfile}" "\\\^done" \
       "file-exec-and-symbols operation"] {
	note "Skipping all other MI tests."
	return 0
    }

    # The following is not used by mi-support.exp, but we test here so
    # we get done with loading a program basics.

    # Do it again, but now load symbols and specify executable with
    # two separate operations
    # Tests:
    # -file-clear
    # -file-exec-file
    # -file-symbol-file

    # FIXME: file-clear is not implemented yet.
#   mi_gdb_test "-file-clear" \
#            "\\\^done" \
#            "file-clear operation"

    mi_gdb_test "-file-exec-file ${binfile}" \
             "\\\^done" \
             "file-exec-file operation"

    mi_gdb_test "-file-symbol-file ${binfile}" \
             "\\\^done" \
             "file-symbol-file operation"

    # We need to return != 0.
    return 1
}

proc test_breakpoints_deletion {} {
    global mi_gdb_prompt
    global srcfile

    # Clear all breakpoints and list to confirm
    # Tests:
    # -break-delete (all)
    # -break-list

    # The all parameter is actually no parameter.
    mi_gdb_test "200-break-delete" \
             "200\\\^done" \
             "break-delete (all) operation"

    mi_gdb_test "201-break-list" \
             ".*\\\^done,BreakpointTable=\\\{.*,body=\\\[\\\]\\\}" \
             "all breakpoints removed"
}

proc test_dir_specification {} {
    global mi_gdb_prompt
    global objdir
    global subdir
    global envirodir

    # Add to the search directories, display, then reset back to default
    # Tests:
    # -environment-directory arg
    # -environment-directory 
    # -environment-directory -r

    mi_gdb_test "202-environment-directory ${objdir}/${subdir}" \
             "202\\\^done,source-path=\"${envirodir}.\\\$cdir.\\\$cwd\"" \
             "environment-directory arg operation"

    mi_gdb_test "203-environment-directory" \
             "203\\\^done,source-path=\"${envirodir}.\\\$cdir.\\\$cwd\"" \
             "environment-directory empty-string operation"

    mi_gdb_test "204-environment-directory -r" \
             "204\\\^done,source-path=\"\\\$cdir.\\\$cwd\"" \
             "environment-directory operation"
}

proc test_cwd_specification {} {
    global mi_gdb_prompt
    global objdir
    global escapedobjdir
    global subdir

    # Change the working directory, then print the current working directory
    # Tests:
    # -environment-cd ${objdir}
    # -environment-pwd

    mi_gdb_test "205-environment-cd ${objdir}" \
             "205\\\^done" \
             "environment-cd arg operation"

    # The canonical name of the working directory may differ on a
    # remote host from that on the build system.
    if ![is_remote host] {
	mi_gdb_test "206-environment-pwd" \
             "206\\\^done,cwd=\"${escapedobjdir}\"" \
             "environment-pwd operation"
    }
}

proc test_path_specification {} {
    global mi_gdb_prompt
    global orig_path
    global objdir
    global subdir
    global escapedobjdir
    global envirodir
    global expect_out

    # Add to the path, display, then reset 
    # Tests:
    # -environment-path 
    # -environment-path dir1 dir2
    # -environment-path -r dir
    # -environment-path -r

    mi_gdb_test "-environment-path" "\\\^done,path=\"(.*)\"" "environment-path"
    set orig_path $expect_out(3,string)

    set orig_path [string_to_regexp ${orig_path}]
    set pathdir [string_to_regexp ${objdir}/${subdir}]

    mi_gdb_test "207-environment-path" \
             "207\\\^done,path=\"$orig_path\"" \
             "environment-path no-args operation"

    mi_gdb_test "208-environment-path $objdir ${objdir}/${subdir}" \
             "208\\\^done,path=\"$escapedobjdir.${envirodir}.$orig_path\"" \
             "environment-path dir1 dir2 operation"

    mi_gdb_test "209-environment-path -r $objdir" \
             "209\\\^done,path=\"$escapedobjdir.$orig_path\"" \
             "environment-path -r dir operation"

    mi_gdb_test "210-environment-path -r" \
             "210\\\^done,path=\"$orig_path\"" \
             "environment-path -r operation"

} 

proc test_setshow_inferior_tty {} {
    global mi_gdb_prompt
    global mi_inferior_tty_name

    # Test that the commands,
    #   -inferior-tty-set
    #   -inferior-tty-show
    # are setting/getting the same data in GDB.

    mi_gdb_test "301-inferior-tty-show" \
		"301\\\^done,inferior_tty_terminal=\"$mi_inferior_tty_name\"" \
		"initial tty is mi_inferior_tty_name"

    mi_gdb_test "302-inferior-tty-set /dev/pts/1" \
		"302\\\^done" \
		"set tty to /dev/pts/1"

    mi_gdb_test "303-inferior-tty-show" \
		"303\\\^done,inferior_tty_terminal=\"/dev/pts/1\"" \
		"tty was set correctly"

    mi_gdb_test "304-inferior-tty-set" \
		"304\\\^done" \
		"set tty to the empty string"

    mi_gdb_test "305-inferior-tty-show" \
		"305\\\^done" \
		"make sure tty is empty"

    mi_gdb_test "306-inferior-tty-set $mi_inferior_tty_name" \
		"306\\\^done" \
		"set tty to mi_inferior_tty_name (the way it was)"

    mi_gdb_test "307-inferior-tty-show" \
		"307\\\^done,inferior_tty_terminal=\"$mi_inferior_tty_name\"" \
		"verify tty is correct"
}

if { [test_mi_interpreter_selection]
      && [test_exec_and_symbol_mi_operatons] } {
  test_breakpoints_deletion
  test_dir_specification
  test_cwd_specification
  test_path_specification
  test_setshow_inferior_tty
}

mi_gdb_exit
return 0
