# Copyright 2002, 2003 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 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.  

# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu

# This file tests MI thread commands.
# Specifically, we are testing the MI command set and the console (in MI)
# command set ("interpreter-exec") and that the commands that are executed
# via these command pathways are properly executed. Console commands
# executed via MI should use MI output wrappers, MI event handlers, etc.

# This only works with native configurations
if {![isnative]} {
  return
}

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

gdb_exit
if {[mi_gdb_start]} {
    continue
}

# The procs below dealing with parsing cli/mi output for the threadlist
# is duplicated in gdb669.exp. Any changes here will probably need to
# be made there as well.

proc get_mi_thread_list {name} {
  global expect_out

  # MI will return a list of thread ids:
  #
  # -thread-list-ids
  # ^done,thread-ids=[thread-id="1",thread-id="2",...],number-of-threads="N"
  # (gdb)
  mi_gdb_test "-thread-list-ids" \
    {\^done,thread-ids={(thread-id="[0-9]+"(,)?)+},number-of-threads="[0-9]+"} \
    "-thread_list_ids ($name)"

  set output {}
  if {[info exists expect_out(buffer)]} {
    set output $expect_out(buffer)
  }

  set thread_list {}
  if {![regexp {thread-ids=\{(thread-id="[0-9]+"(,)?)*\}} $output threads]} {
    fail "finding threads in MI output ($name)"
  } else {
    pass "finding threads in MI output ($name)"

    # Make list of console threads
    set start [expr {[string first \{ $threads] + 1}]
    set end   [expr {[string first \} $threads] - 1}]
    set threads [string range $threads $start $end]
    foreach thread [split $threads ,] {
      if {[scan $thread {thread-id="%d"} num]} {
	lappend thread_list $num
      }
    }
  }

  return $thread_list
}

# Check that MI and the console know of the same threads.
# Appends NAME to all test names.
proc check_mi_and_console_threads {name} {
  global expect_out

  mi_gdb_test "-thread-list-ids" \
    {\^done,thread-ids={(thread-id="[0-9]+"(,)*)+},number-of-threads="[0-9]+"} \
    "-thread-list-ids ($name)"
  set mi_output {}
  if {[info exists expect_out(buffer)]} {
    set mi_output $expect_out(buffer)
  }

  # GDB will return a list of thread ids and some more info:
  #
  # (gdb) 
  # -interpreter-exec console "info threads"
  # ~"  4 Thread 2051 (LWP 7734)  0x401166b1 in __libc_nanosleep () at __libc_nanosleep:-1"
  # ~"  3 Thread 1026 (LWP 7733)   () at __libc_nanosleep:-1"
  # ~"  2 Thread 2049 (LWP 7732)  0x401411f8 in __poll (fds=0x804bb24, nfds=1, timeout=2000) at ../sysdeps/unix/sysv/linux/poll.c:63"
  # ~"* 1 Thread 1024 (LWP 7731)  main (argc=1, argv=0xbfffdd94) at ../../../src/gdb/testsuite/gdb.mi/pthreads.c:160"
  # FIXME: kseitz/2002-09-05: Don't use the hack-cli method.
  mi_gdb_test "info threads" \
    {.*(~".*"[\r\n]*)+.*} \
    "info threads ($name)"
  set console_output {}
  if {[info exists $expect_out(buffer)]} {
    set console_output $expect_out(buffer)
  }

  # Make a list of all known threads to console (gdb's thread IDs)
  set console_thread_list {}
  foreach line [split $console_output \n] {
    if {[string index $line 0] == "~"} {
      # This is a line from the console; trim off "~", " ", "*", and "\""
      set line [string trim $line ~\ \"\*]
      if {[scan $line "%d" id] == 1} {
	lappend console_thread_list $id
      }
    }
  }

  # Now find the result string from MI
  set mi_result ""
  foreach line [split $mi_output \n] {
    if {[string range $line 0 4] == "^done"} {
      set mi_result $line
    }
  }
  if {$mi_result == ""} {
    fail "finding MI result string ($name)"
  } else {
    pass "finding MI result string ($name)"
  }

  # Finally, extract the thread ids and compare them to the console
  set num_mi_threads_str ""
  if {![regexp {number-of-threads="[0-9]+"} $mi_result num_mi_threads_str]} {
    fail "finding number of threads in MI output ($name)"
  } else {
    pass "finding number of threads in MI output ($name)"

    # Extract the number of threads from the MI result
    if {![scan $num_mi_threads_str {number-of-threads="%d"} num_mi_threads]} {
      fail "got number of threads from MI ($name)"
    } else {
      pass "got number of threads from MI ($name)"

      # Check if MI and console have same number of threads
      if {$num_mi_threads != [llength $console_thread_list]} {
	fail "console and MI have same number of threads ($name)"
      } else {
	pass "console and MI have same number of threads ($name)"

	# Get MI thread list
	set mi_thread_list [get_mi_thread_list $name]

	# Check if MI and console have the same threads
	set fails 0
	foreach ct [lsort $console_thread_list] mt [lsort $mi_thread_list] {
	  if {$ct != $mt} {
	    incr fails
	  }
	}
	if {$fails > 0} {
	  fail "MI and console have same threads ($name)"

	  # Send a list of failures to the log
	  send_log "Console has thread ids: $console_thread_list\n"
	  send_log "MI has thread ids: $mi_thread_list\n"
	} else {
	  pass "MI and console have same threads ($name)"
	}
      }
    }
  }
}

# This procedure tests the various thread commands in MI.
proc check_mi_thread_command_set {} {

  mi_runto done_making_threads

  set thread_list [get_mi_thread_list "in check_mi_thread_command_set"]
  
  mi_gdb_test "-thread-select" \
    {\^error,msg="mi_cmd_thread_select: USAGE: threadnum."} \
    "check_mi_thread_command_set: -thread-select"

  mi_gdb_test "-thread-select 123456789" \
    {\^error,msg="Thread ID 123456789 not known\."} \
    "check_mi_thread_command_set: -thread-select 123456789"

  foreach thread $thread_list {
    # line and file are optional.
    # many of the threads are blocked in libc calls,
    # and many people have libc's with no symbols.
    mi_gdb_test "-thread-select $thread" \
      "\\^done,new-thread-id=\"$thread\",frame={.*}(,line=\"(-)?\[0-9\]+\",file=\".*\")?" \
      "check_mi_thread_command_set: -thread-select $thread"
  }
}

#
# Start here
#
set testfile "pthreads"
set srcfile "$testfile.c"
set binfile "$objdir/$subdir/$testfile"

set options [list debug incdir=$objdir]
if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" $binfile executable $options] != "" } {
    return -1
}

mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load $binfile

check_mi_thread_command_set

mi_gdb_exit

