# Copyright 2019-2021 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 'info sources [-d | -b] [--] [REGEX]'

standard_testfile .c info_sources_base.c

if {[prepare_for_testing $testfile.exp $testfile \
	 [list $srcfile $srcfile2] debug]} {
    untested $testfile.exp
    return -1
}

# Executes "info sources " $args.
# EXPECT_SEEN_INFO_SOURCES 1 indicates that the source file info_sources.c must be seen
# in the output.  Similarly, EXPECT_SEEN_INFO_SOURCES_BASE indicates that the source file
# info_sources_base.c must be seen in the output.
proc test_info_sources {args expect_seen_info_sources expect_seen_info_sources_base} {
    global gdb_prompt srcfile srcfile2

    set seen_info_sources 0
    set seen_info_sources_base 0
    set cmd [concat "info sources " $args]
    gdb_test_multiple $cmd $cmd {
	-re "^\[^,\]*${srcfile}(, |\[\r\n\]+)" {
	    incr seen_info_sources
	    exp_continue
	}
	-re "^\[^,\]*${srcfile2}(, |\[\r\n\]+)" {
	    incr seen_info_sources_base 1
	    exp_continue
	}
	-re ", " {
	    exp_continue
	}
	-re "$gdb_prompt $" {
	    if {$seen_info_sources == $expect_seen_info_sources \
		    && $seen_info_sources_base == $expect_seen_info_sources_base} {
		pass $cmd
	    } else {
		fail $cmd
	    }
	}
    }
}

if ![runto_main] {
    return -1
}

# List both files with no regexp:
with_test_prefix "in main" {
    test_info_sources "" 1 1
}

gdb_test "break some_other_func" ""
gdb_test "continue"

# List both files with no regexp:
test_info_sources "" 1 1
# Same but with option terminator:
test_info_sources "--" 1 1

# List both files with regexp matching anywhere in the filenames:
test_info_sources "info_sources" 1 1
if { ! [is_remote host] } {
    test_info_sources "gdb.base" 1 1
}

# List both files with regexp matching the filename basenames,
# using various parts of the -basename option:
test_info_sources "-b info_sources" 1 1
test_info_sources "-basename info_sources" 1 1
test_info_sources "-b -- info_sources" 1 1
test_info_sources "-ba info_sources" 1 1
test_info_sources "-base -- info_sources" 1 1
test_info_sources "-basena info_sources" 1 1
test_info_sources "-basename -- info_sources" 1 1

# List only the file with basename matching regexp:
test_info_sources "-b base" 0 1

# List the files with dirname matching regexp,
# using various part of the -dirname option:
if { ! [is_remote host] } {
    test_info_sources "-d base" 1 1
    test_info_sources "-dirname base" 1 1
}

# Test non matching regexp, with option terminator:
test_info_sources "-b -- -d" 0 0
test_info_sources "-d -- -d" 0 0
