fb5c953a6c436b25c6e80f383a8f8f73e4ed59c8
[binutils-gdb.git] / gdb / testsuite / lib / gdb-utils.exp
1 # Copyright 2014-2023 Free Software Foundation, Inc.
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16 # Utility procedures, shared between test suite domains.
17
18 # A helper procedure to retrieve commands to send to GDB before a program
19 # is started.
20
21 proc gdb_init_commands {} {
22 set commands ""
23 if [target_info exists gdb_init_command] {
24 lappend commands [target_info gdb_init_command]
25 }
26 if [target_info exists gdb_init_commands] {
27 set commands [concat $commands [target_info gdb_init_commands]]
28 }
29 return $commands
30 }
31
32 # Given an input string, adds backslashes as needed to create a
33 # regexp that will match the string.
34
35 proc string_to_regexp {str} {
36 set result $str
37 regsub -all {[]?*+.|(){}^$\[\\]} $str {\\&} result
38 return $result
39 }
40
41 # Given a list of strings, adds backslashes as needed to each string to
42 # create a regexp that will match the string, and join the result.
43
44 proc string_list_to_regexp { args } {
45 set result ""
46 foreach arg $args {
47 set arg [string_to_regexp $arg]
48 append result $arg
49 }
50 return $result
51 }
52
53 # Wrap STR in an ANSI terminal escape sequences -- one to set the
54 # style to STYLE, and one to reset the style to the default. The
55 # return value is suitable for use as a regular expression.
56
57 # STYLE can either be the payload part of an ANSI terminal sequence,
58 # or a shorthand for one of the gdb standard styles: "file",
59 # "function", "variable", or "address".
60
61 proc style {str style} {
62 switch -exact -- $style {
63 title { set style 1 }
64 file { set style 32 }
65 function { set style 33 }
66 highlight { set style 31 }
67 variable { set style 36 }
68 address { set style 34 }
69 metadata { set style 2 }
70 version { set style "35;1" }
71 none { return $str }
72 }
73 return "\033\\\[${style}m${str}\033\\\[m"
74 }
75
76 # gdb_get_bp_addr num
77 #
78 # Purpose:
79 # Get address of a particular breakpoint.
80 #
81 # Parameter:
82 # The parameter "num" indicates the number of the breakpoint to get.
83 # Note that *currently* this parameter must be an integer value.
84 # E.g., -1 means that we're gonna get the first internal breakpoint;
85 # 2 means to get the second user-defined breakpoint.
86 #
87 # Return:
88 # First address for a particular breakpoint.
89 #
90 # TODO:
91 # It would be nice if this procedure could accept floating point value.
92 # E.g., 'gdb_get_bp_addr 1.2' means to get the address of the second
93 # location of breakpoint #1.
94 #
95 proc gdb_get_bp_addr { num } {
96 gdb_test_multiple "maint info break $num" "find address of specified bp $num" {
97 -re -wrap ".*(0x\[0-9a-f\]+).*" {
98 return $expect_out(1,string)
99 }
100 }
101 return ""
102 }
103
104 # Compare the version numbers in L1 to those in L2 using OP, and return
105 # 1 if the comparison is true.
106
107 proc version_compare { l1 op l2 } {
108 set len [llength $l1]
109 if { $len != [llength $l2] } {
110 error "l2 not the same length as l1"
111 }
112
113 switch -exact $op {
114 "==" -
115 "<" {}
116 "<=" { return [expr [version_compare $l1 < $l2] \
117 || [version_compare $l1 == $l2]]}
118 default { error "unsupported op: $op" }
119 }
120
121 # Handle ops < and ==.
122 set idx 0
123 foreach v1 $l1 {
124 set v2 [lindex $l2 $idx]
125 incr idx
126 set last [expr $len == $idx]
127
128 set cmp [expr $v1 $op $v2]
129 if { $op == "==" } {
130 if { $cmp } {
131 continue
132 } else {
133 return 0
134 }
135 } else {
136 # $op == "<".
137 if { $cmp } {
138 return 1
139 } else {
140 if { !$last && $v1 == $v2 } {
141 continue
142 }
143 return 0
144 }
145 }
146 }
147
148 return 1
149 }