|  | # Copyright (C) 2016-2025 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 expression parsing and evaluation, without requiring a | 
|  | # Rust compiler.  This serves as a smoke test. | 
|  |  | 
|  | load_lib "rust-support.exp" | 
|  | require allow_rust_tests | 
|  |  | 
|  | gdb_start | 
|  |  | 
|  | gdb_test_no_output "set var \$something = 27" | 
|  |  | 
|  | if {![set_lang_rust]} { | 
|  | warning "Rust expression tests suppressed." | 
|  | return | 
|  | } | 
|  |  | 
|  | gdb_test "print 9__97" " = 997" | 
|  | gdb_test "print -5" " = -5" | 
|  | gdb_test "print +5" " = 5" | 
|  | gdb_test "print +-+-5" " = 5" | 
|  | gdb_test "print 3_2i32" " = 32" | 
|  | gdb_test "print 32i64" " = 32" | 
|  | gdb_test "print 8u8" " = 8" | 
|  | gdb_test "print 0x1f" " = 31" | 
|  | gdb_test "print 0o07" " = 7" | 
|  | gdb_test "print 0o70" " = 56" | 
|  | gdb_test "print 0b1_111" " = 15" | 
|  | gdb_test "print 32usize" " = 32" | 
|  | gdb_test "print 0x_4" " = 4" | 
|  |  | 
|  | gdb_test "print 'z'" " = 122 'z'" | 
|  | gdb_test "print '\\t'" " = 9 '\\\\t'" | 
|  | gdb_test "print '\\n'" " = 10 '\\\\n'" | 
|  | gdb_test "print '\\r'" " = 13 '\\\\r'" | 
|  | gdb_test "print '\\\\'" " = 92 '\\\\\\\\'" | 
|  | gdb_test "print '\\0'" " = 0 '\\\\0'" | 
|  | gdb_test "print '\\''" " = 39 '\\\\''" | 
|  | gdb_test "print '\\\"'" " = 34 '\"'" | 
|  | gdb_test "print '\\xff'" " = 255 '\\\\xff'" | 
|  | gdb_test "print '\\xFF'" " = 255 '\\\\xff'" | 
|  | gdb_test "print '\\u\{F0eF\}'" " = 61679 '\\\\u\\{00f0ef\\}'" | 
|  |  | 
|  | gdb_test "print b'z'" " = 122" | 
|  | gdb_test "print b'\\xfe'" " = 254" | 
|  | gdb_test "print b'\\t'" " = 9" | 
|  | gdb_test "print b'\\n'" " = 10" | 
|  | gdb_test "print b'\\r'" " = 13" | 
|  | gdb_test "print b'\\\\'" " = 92" | 
|  | gdb_test "print b'\\0'" " = 0" | 
|  | gdb_test "print b'\\''" " = 39" | 
|  | gdb_test "print b'\\\"'" " = 34" | 
|  | gdb_test "print b'\\xff'" " = 255" | 
|  |  | 
|  | gdb_test "print 23.5" " = 23.5" | 
|  | gdb_test "print 23.5e1" " = 235" | 
|  | gdb_test "print 2e4" " = 20000" | 
|  | gdb_test "print 2_E+4_f64" " = 20000" | 
|  | gdb_test "print 5e-1" " = 0.5" | 
|  | gdb_test "print 5e-1f32" " = 0.5" | 
|  |  | 
|  | gdb_test "print false" " = false" | 
|  | gdb_test "print true" " = true" | 
|  |  | 
|  | gdb_test "print 1+2" " = 3" | 
|  | gdb_test "print 1i32 + 2i32" " = 3" | 
|  | gdb_test "print 2.0 - 1.0" " = 1" | 
|  | gdb_test "print !false" " = true" | 
|  | gdb_test "print !true" " = false" | 
|  | gdb_test "print !0u8" " = 255" | 
|  | gdb_test "print 7 * 7" " = 49" | 
|  | gdb_test "print 7usize * 7usize" " = 49" | 
|  | gdb_test "print 42 / 7" " = 6" | 
|  | gdb_test "print 42 % 7" " = 0" | 
|  | gdb_test "print 1.0 / 2.0" " = 0.5" | 
|  | gdb_test "print 1 < 2" " = true" | 
|  | gdb_test "print !(1 < 2)" " = false" | 
|  | gdb_test "print 3 + 4 * 7" " = 31" | 
|  | gdb_test "print 1 > 2" " = false" | 
|  | gdb_test "print 1 | 2" " = 3" | 
|  | gdb_test "print 1 & 2" " = 0" | 
|  | gdb_test "print 3 & 2" " = 2" | 
|  | gdb_test "print 3 ^ 2" " = 1" | 
|  | gdb_test "print (1 < 0) || true" " = true" | 
|  | gdb_test "print (1 > 0) && false" " = false" | 
|  | gdb_test "print 'z' == 'z'" " = true" | 
|  | gdb_test "print '\\u{1016f}' != 'q'" " = true" | 
|  | gdb_test "print 32 <= 32" " = true" | 
|  | gdb_test "print 32 >= 32" " = true" | 
|  | gdb_test "print 1 << 5" " = 32" | 
|  | gdb_test "print 32usize >> 5" " = 1" | 
|  | gdb_test "ptype 32i32 as f64" "type = f64" | 
|  |  | 
|  | gdb_test "ptype 0xf9f9f9f90000" "type = i64" | 
|  |  | 
|  | gdb_test "print ()" " = \\(\\)" | 
|  |  | 
|  | gdb_test "print \[1,2,3,4\]" " = \\\[1, 2, 3, 4\\\]" | 
|  | gdb_test "ptype \[1,2,3,4\]" "type = \\\[i32; 4\\\]" | 
|  | gdb_test "print \[mut 1,2,3,4\]" " = \\\[1, 2, 3, 4\\\]" | 
|  | gdb_test "print \[1,2 3" "',' or ']' expected" | 
|  | gdb_test "print \[1 2" "',', ';', or ']' expected" | 
|  | gdb_test "print \[23\]" " = \\\[23\\\]" | 
|  |  | 
|  | gdb_test "print \[0;0\]" " = \\\[\\\]" | 
|  | gdb_test "print \[1;0\]" " = \\\[\\\]" | 
|  | gdb_test "print \[0;1\]" " = \\\[0\\\]" | 
|  |  | 
|  | gdb_test "print b\"hi rust\"" " = b\"hi rust\"" | 
|  | # This isn't rusty syntax yet, but that's another bug -- this is just | 
|  | # testing that byte escapes work properly. | 
|  | gdb_test "print b\"\\xddhi bob\"" " = b\"\\\\335hi bob\"" | 
|  | gdb_test "print b\"has\\0nul\"" " = b\"has\\\\000nul\"" | 
|  |  | 
|  | gdb_test "print br##\"hi\"##" " = b\"hi\"" | 
|  | gdb_test "print br##\"hi" "Unexpected EOF in string" | 
|  | gdb_test "print br##\"hi\"" "Unexpected EOF in string" | 
|  | gdb_test "print br##\"hi\"#" "Unexpected EOF in string" | 
|  |  | 
|  | # Test that convenience variables and functions work with the Rust | 
|  | # parser. | 
|  | gdb_test "print \$something" " = 27" | 
|  | gdb_test "print \$_isvoid(\$nosuchvariable)" " = 1" | 
|  | gdb_test "print \$_isvoid(\$something)" " = 0" | 
|  |  | 
|  | gdb_test "print \[23usize; 4\]" " = \\\[23, 23, 23, 23\\\]" | 
|  | gdb_test "ptype \[23usize; 4\]" " = \\\[usize; 4\\\]" | 
|  | gdb_test "print \[mut 23usize; 4\]" " = \\\[23, 23, 23, 23\\\]" | 
|  |  | 
|  | # Test lexer corner cases. | 
|  | gdb_test "print 0x0 as *mut ()" " = \\\(\\*mut \\\(\\\)\\\) 0x0" | 
|  | gdb_test "print 0x0 as fn(i64) -> ()" " = \\\(\\*mut fn \\\(i64\\\) -> \\\(\\\)\\\) 0x0" | 
|  |  | 
|  | # The lexer doesn't treat this as a failure, but rather as two tokens, | 
|  | # and we error out while trying to look up 'r'.  This is fine, though | 
|  | # -- what's important is that it isn't accepted. | 
|  | gdb_test "print r#" "No symbol 'r' in current context" | 
|  |  | 
|  | gdb_test "printf \"%d %d\\n\", 23+1, 23-1" "24 22" | 
|  |  | 
|  | gdb_test "print 5," "Syntax error near ','" | 
|  |  | 
|  | # Check expression debug works for strings. | 
|  | gdb_test "with debug expression 1 -- print \"foo\"" \ | 
|  | [multi_line \ | 
|  | "Operation: OP_AGGREGATE" \ | 
|  | " Type: &str" \ | 
|  | " nullptr" \ | 
|  | " Vector:" \ | 
|  | "  String: data_ptr" \ | 
|  | "  Operation: UNOP_ADDR" \ | 
|  | "   Operation: OP_STRING" \ | 
|  | "    String: foo" \ | 
|  | "  String: length" \ | 
|  | "  Operation: OP_LONG" \ | 
|  | "   Type: usize" \ | 
|  | "   Constant: 3" \ | 
|  | "Operation: OP_LONG" \ | 
|  | " Type: i32" \ | 
|  | " Constant: 0" \ | 
|  | "evaluation of this expression requires the target program to be active"] \ | 
|  | "print a string with expression debug turned on" | 
|  |  | 
|  | # PR rust/31082 - truncating to a pointer would fail.  Depending on | 
|  | # the default host architecture, this may or may not print a warning. | 
|  | gdb_test "print (0xffffffd00000009a as *mut u64)" \ | 
|  | "(warning: value truncated\[\r\n\]+)?.* = \\(\\*mut u64\\) $hex" |