1# Test macro scoping. 2# Copyright 2002, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 3 4# This program is free software; you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation; either version 3 of the License, or 7# (at your option) any later version. 8# 9# This program is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17if $tracelevel then { 18 strace $tracelevel 19} 20 21 22set srcfile macscp1.c 23set testfile "macscp" 24set objfile ${objdir}/${subdir}/${testfile}.o 25set binfile ${objdir}/${subdir}/${testfile} 26 27set options { debug additional_flags=-DFROM_COMMANDLINE=ARG} 28 29get_compiler_info ${binfile} 30if [test_compiler_info gcc*] { 31 lappend options additional_flags=-g3 32} 33 34# Generate the intermediate object file. This is required by Darwin to 35# have access to the .debug_macinfo section. 36if {[gdb_compile "${srcdir}/${subdir}/macscp1.c" "${objfile}" \ 37 object $options] != "" 38 || [gdb_compile "${objfile}" "${binfile}" executable $options] != "" } { 39 untested macscp.exp 40 return -1 41} 42 43gdb_exit 44gdb_start 45gdb_reinitialize_dir $srcdir/$subdir 46gdb_load ${binfile} 47 48 49# Ask GDB to show the current definition of MACRO, and return a list 50# describing the result. 51# 52# The return value has the form {FILE1 FILE2 ... DEF}, which means 53# that MACRO has the definition `DEF', and was defined in `FILE1', 54# which was included from `FILE2', included from ... . 55# 56# If GDB says that MACRO has no definition, return the string `undefined'. 57# 58# If GDB complains that it doesn't have any information about 59# preprocessor macro definitions, return the string `no-macro-info'. 60# 61# If expect times out waiting for GDB, we return the string `timeout'. 62# 63# If GDB's output doesn't otherwise match what we're expecting, we 64# return the empty string. 65 66proc info_macro {macro} { 67 global gdb_prompt 68 69 set filepat {macscp[0-9]+\.[ch]} 70 set definition {} 71 set location {} 72 73 # Line number zero is set for macros defined from the compiler command-line. 74 # Such macros are not being tested by this function. 75 set nonzero {[1-9][0-9]*} 76 77 send_gdb "info macro ${macro}\n" 78 79 set debug_me 0 80 81 if {$debug_me} {exp_internal 1} 82 gdb_expect { 83 -re "Defined at \[^\r\n\]*(${filepat}):${nonzero}\[\r\n\]" { 84 # `location' and `definition' should be empty when we see 85 # this message. 86 if {[llength $location] == 0 && [llength $definition] == 0} { 87 set location $expect_out(1,string) 88 exp_continue 89 } else { 90 # Exit this expect loop, with a result indicating failure. 91 set definition {} 92 } 93 } 94 -re "The symbol `${macro}' has no definition as a C/C\\+\\+ preprocessor macro\[^\r\n\]*\[\r\n\]" { 95 # `location' and `definition' should be empty when we see 96 # this message. 97 if {[llength $location] == 0 && [llength $definition] == 0} { 98 set definition undefined 99 exp_continue 100 } else { 101 # Exit this expect loop, with a result indicating failure. 102 set definition {} 103 } 104 } 105 -re "^\[\r\n\]* included at \[^\r\n\]*(${filepat}):${nonzero}\[\r\n\]" { 106 # `location' should *not* be empty when we see this 107 # message. It should have recorded at least the initial 108 # `Defined at ' message (for definitions) or ` at' message 109 # (for undefined symbols). 110 if {[llength $location] != 0} { 111 lappend location $expect_out(1,string) 112 exp_continue 113 } else { 114 # Exit this expect loop, with a result indicating failure. 115 set definition {} 116 } 117 } 118 -re "^\[\r\n\]*at \[^\r\n\]*(${filepat}):${nonzero}\[\r\n\]" { 119 # This appears after a `has no definition' message. 120 # `location' should be empty when we see it. 121 if {[string compare $definition undefined] == 0 \ 122 && [llength $location] == 0} { 123 set location $expect_out(1,string) 124 exp_continue 125 } else { 126 # Exit this expect loop, with a result indicating failure. 127 set definition {} 128 } 129 } 130 -re "#define ${macro} (\[^\r\n\]*)\[\r\n\]" { 131 # `definition' should be empty when we see this message. 132 if {[string compare $definition ""] == 0} { 133 set definition $expect_out(1,string) 134 exp_continue 135 } else { 136 # Exit this expect loop, with a result indicating failure. 137 set definition {} 138 } 139 } 140 -re "has no preprocessor macro information.*$gdb_prompt $" { 141 set definition no-macro-info 142 } 143 -re "$gdb_prompt $" { 144 # Exit the expect loop; let the existing value of `definition' 145 # indicate failure or success. 146 } 147 timeout { 148 set definition timeout 149 } 150 } 151 if {$debug_me} {exp_internal 0} 152 153 switch -exact -- $definition { 154 no-macro-info { return no-macro-info } 155 timeout { return timeout } 156 undefined { return undefined } 157 default { 158 if {[llength $location] >= 1} { 159 return [concat $location [list $definition]] 160 } else { 161 return {} 162 } 163 } 164 } 165} 166 167 168# Call info_macro to show the definition of MACRO. Expect a result of 169# EXPECTED. Use WHERE in pass/fail messages to identify the context. 170# Return non-zero if we should abort the entire test file, or zero if 171# we can continue. 172proc check_macro {macro expected where} { 173 set func_def [info_macro $macro] 174 if {[string compare $func_def $expected] == 0} { 175 pass "info macro $macro $where" 176 } else { 177 switch -exact -- $func_def { 178 no-macro-info { 179 xfail "executable includes no macro debugging information" 180 return 1 181 } 182 undefined { 183 fail "info macro $macro $where (undefined)" 184 return 1 185 } 186 timeout { 187 fail "info macro $macro $where (timeout)" 188 } 189 default { 190 fail "info macro $macro $where" 191 } 192 } 193 } 194 return 0 195} 196 197 198# List the function FUNC, and then show the definition of MACRO, 199# expecting the result EXPECTED. 200proc list_and_check_macro {func macro expected} { 201 gdb_test "list $func" ".*${func}.*" "list $func for $macro" 202 return [check_macro $macro $expected "after `list $func'"] 203} 204 205gdb_test "list main" ".*main.*" "list main for support check" 206set macro_support "unknown" 207gdb_test_multiple "info source" "Test macro information" { 208 -re "Includes preprocessor macro info\..*$gdb_prompt $" { 209 set macro_support 1 210 verbose "Source has macro information" 211 } 212 -re "Does not include preprocessor macro info\..*$gdb_prompt $" { 213 set macro_support 0 214 verbose "Source has no macro information" 215 } 216 default { 217 warning "couldn't check macro support (no valid response)." 218 } 219} 220if {$macro_support == 0} { 221 unsupported "Skipping test because debug information does not include macro information." 222 return 0 223} 224 225list_and_check_macro main WHERE {macscp1.c {before macscp1_3}} 226list_and_check_macro macscp2_2 WHERE {macscp2.h macscp1.c {before macscp2_2}} 227list_and_check_macro macscp3_2 WHERE {macscp3.h macscp1.c {before macscp3_2}} 228 229 230# Assuming the current position inside program by `list' from above. 231gdb_test "info macro FROM_COMMANDLINE" \ 232 "Defined at \[^\r\n\]*:0\r\n-DFROM_COMMANDLINE=ARG" 233 234 235# Although GDB's macro table structures distinguish between multiple 236# #inclusions of the same file, GDB's other structures don't. So the 237# `list' command here doesn't reliably select one #inclusion or the 238# other, even though it could. It would be nice to eventually change 239# GDB's structures to handle this correctly. 240gdb_test "list macscp4_2_from_macscp2" ".*macscp4_2_, MACSCP4_INCLUSION.*" 241switch -exact -- [info_macro WHERE] { 242 {macscp4.h macscp2.h macscp1.c {before macscp4_2_..., from macscp2.h}} { 243 pass "info macro WHERE after `list macscp_4_2_from_macscp2'" 244 } 245 {macscp4.h macscp3.h macscp1.c {before macscp4_2_..., from macscp3.h}} { 246 setup_kfail "gdb/555" *-*-* 247 fail "info macro WHERE after `list macscp_4_2_from_macscp2' (gdb/555)" 248 } 249 timeout { 250 fail "info macro WHERE after `list macscp_4_2_from_macscp2' (timeout)" 251 } 252 default { fail "info macro WHERE after `list macscp_4_2_from_macscp2'" } 253} 254 255gdb_test "list macscp4_2_from_macscp3" ".*macscp4_2_, MACSCP4_INCLUSION.*" 256switch -exact -- [info_macro WHERE] { 257 {macscp4.h macscp3.h macscp1.c {before macscp4_2_..., from macscp3.h}} { 258 pass "info macro WHERE after `list macscp_4_2_from_macscp3'" 259 } 260 {macscp4.h macscp2.h macscp1.c {before macscp4_2_..., from macscp2.h}} { 261 setup_kfail "gdb/555" *-*-* 262 fail "info macro WHERE after `list macscp_4_2_from_macscp3' (gdb/555)" 263 } 264 timeout { 265 fail "info macro WHERE after `list macscp_4_2_from_macscp3' (timeout)" 266 } 267 default { fail "info macro WHERE after `list macscp_4_2_from_macscp3'" } 268} 269 270 271#### Test the selection of the macro scope by the current frame. 272 273### A table of functions, in the order they will be reached, which is 274### also the order they appear in the preprocessed output. Each entry 275### has the form {FUNCNAME WHERE KFAILWHERE}, where: 276### - FUNCNAME is the name of the function, 277### - WHERE is the definition we expect to see for the macro `WHERE', as 278### returned by `info_macro', and 279### - KFAILWHERE is an alternate definition which should be reported 280### as a `known failure', due to GDB's inability to distinguish multiple 281### #inclusions of the same file. 282### KFAILWHERE may be omitted. 283 284set funcs { 285 { 286 macscp1_1 287 {macscp1.c {before macscp1_1}} 288 } 289 { 290 macscp2_1 291 {macscp2.h macscp1.c {before macscp2_1}} 292 } 293 { 294 macscp4_1_from_macscp2 295 {macscp4.h macscp2.h macscp1.c {before macscp4_1_..., from macscp2.h}} 296 {macscp4.h macscp3.h macscp1.c {before macscp4_1_..., from macscp3.h}} 297 } 298 { 299 macscp4_2_from_macscp2 300 {macscp4.h macscp2.h macscp1.c {before macscp4_2_..., from macscp2.h}} 301 {macscp4.h macscp3.h macscp1.c {before macscp4_2_..., from macscp3.h}} 302 } 303 { 304 macscp2_2 305 {macscp2.h macscp1.c {before macscp2_2}} 306 } 307 { 308 macscp1_2 309 {macscp1.c {before macscp1_2}} 310 } 311 { 312 macscp3_1 313 {macscp3.h macscp1.c {before macscp3_1}} 314 } 315 { 316 macscp4_1_from_macscp3 317 {macscp4.h macscp3.h macscp1.c {before macscp4_1_..., from macscp3.h}} 318 {macscp4.h macscp2.h macscp1.c {before macscp4_1_..., from macscp2.h}} 319 } 320 { 321 macscp4_2_from_macscp3 322 {macscp4.h macscp3.h macscp1.c {before macscp4_2_..., from macscp3.h}} 323 {macscp4.h macscp2.h macscp1.c {before macscp4_2_..., from macscp2.h}} 324 } 325 { 326 macscp3_2 327 {macscp3.h macscp1.c {before macscp3_2}} 328 } 329 { 330 macscp1_3 331 {macscp1.c {before macscp1_3}} 332 } 333} 334 335proc maybe_kfail { func test_name } { 336 # We can't get the right scope info when we're stopped in 337 # the macro4_ functions. 338 if {[string match macscp4_* $func]} { 339 kfail gdb/555 "$test_name" 340 } else { 341 fail "$test_name" 342 } 343} 344 345# Start the program running. 346if {! [runto_main]} { 347 fail "macro tests suppressed: couldn't run to main" 348 return 0 349} 350 351# Set a breakpoint on each of the functions. 352foreach func_entry $funcs { 353 set func [lindex $func_entry 0] 354 gdb_test "break $func" "Breakpoint.*" 355} 356 357# Run to each of the breakpoints and check the definition (or lack 358# thereof) of each macro. 359for {set i 0} {$i < [llength $funcs]} {incr i} { 360 set func_entry [lindex $funcs $i] 361 set func [lindex $func_entry 0] 362 set expected [lindex $func_entry 1] 363 set kfail_expected [lindex $func_entry 2] 364 365 # Run to the breakpoint for $func. 366 gdb_test "continue" "Breakpoint $decimal, $func .*" "continue to $func" 367 368 # Check the macro WHERE. 369 set result [info_macro WHERE] 370 if {[string compare $result $expected] == 0} { 371 pass "info macro WHERE stopped in $func" 372 } elseif {[string compare $result $kfail_expected] == 0} { 373 setup_kfail "gdb/555" *-*-* 374 fail "info macro WHERE stopped in $func (gdb/555)" 375 } elseif {[string compare $result timeout] == 0} { 376 fail "info macro WHERE stopped in $func (timeout)" 377 } else { 378 fail "info macro WHERE stopped in $func" 379 } 380 381 # Check that the BEFORE_<func> macros for all prior functions are 382 # #defined, and that those for all subsequent functions are not. 383 for {set j 0} {$j < [llength $funcs]} {incr j} { 384 if {$j != $i} { 385 set func_j_entry [lindex $funcs $j] 386 set func_j [lindex $func_j_entry 0] 387 388 set before_macro "BEFORE_[string toupper $func_j]" 389 set test_name \ 390 "$before_macro defined/undefined when stopped at $func" 391 set result [info_macro $before_macro] 392 393 if {$j < $i} { 394 if {[llength $result] >= 2 && \ 395 [string compare [lindex $result end] {}] == 0} { 396 pass $test_name 397 } elseif {[string compare $result timeout] == 0} { 398 fail "$test_name (timeout)" 399 } else { 400 maybe_kfail $func "$test_name" 401 } 402 } elseif {$j > $i} { 403 switch -- [lindex $result end] { 404 undefined { pass $test_name } 405 timeout { fail "$test_name (timeout)" } 406 default { 407 maybe_kfail $func "$test_name" 408 } 409 } 410 } 411 412 set until_macro "UNTIL_[string toupper $func_j]" 413 set test_name \ 414 "$until_macro defined/undefined when stopped at $func" 415 set result [info_macro $until_macro] 416 417 if {$j <= $i} { 418 switch -- [lindex $result end] { 419 undefined { pass $test_name } 420 timeout { fail "$test_name (timeout)" } 421 default { 422 maybe_kfail $func "$test_name" 423 } 424 } 425 } elseif {$j > $i} { 426 if {[llength $result] >= 2 && \ 427 [string compare [lindex $result end] {}] == 0} { 428 pass $test_name 429 } elseif {[string compare $result timeout] == 0} { 430 fail "$test_name (timeout)" 431 } else { 432 maybe_kfail $func "$test_name" 433 } 434 } 435 } 436 } 437} 438 439gdb_test "break [gdb_get_line_number "set breakpoint here"]" \ 440 "Breakpoint.*at.* file .*, line.*" \ 441 "breakpoint macscp_expr" 442 443gdb_test "continue" "foo = 0;.*" "continue to macsp_expr" 444 445gdb_test "print address.addr" \ 446 " = 0" \ 447 "print address.addr" 448 449gdb_test "print MACRO_TO_EXPAND" \ 450 "No symbol \"MACRO_TO_EXPAND\" in current context\." \ 451 "print expression with macro before define." 452 453gdb_test "next" "foo = 1;" "next to definition 1" 454 455gdb_test "print MACRO_TO_EXPAND" \ 456 " = 0" \ 457 "print expression with macro in scope." 458 459gdb_test_no_output "macro define MACRO_TO_EXPAND 72" \ 460 "user macro override" 461 462gdb_test "print MACRO_TO_EXPAND" \ 463 " = 72" \ 464 "choose user macro" 465 466gdb_test_no_output "macro undef MACRO_TO_EXPAND" \ 467 "remove user override" 468 469gdb_test "print MACRO_TO_EXPAND" \ 470 " = 0" \ 471 "print expression with macro after removing override" 472 473gdb_test "next" "foo = 2;" "next to definition 2" 474 475gdb_test "print MACRO_TO_EXPAND" \ 476 "No symbol \"MACRO_TO_EXPAND\" in current context\." \ 477 "print expression with macro after undef." 478 479gdb_test_no_output "macro define MACRO_TO_EXPAND 5" \ 480 "basic macro define" 481 482gdb_test "print MACRO_TO_EXPAND" \ 483 " = 5" \ 484 "expansion of defined macro" 485 486gdb_test "macro list" \ 487 "macro define MACRO_TO_EXPAND 5" \ 488 "basic macro list" 489 490gdb_test_no_output "macro define MACRO_TO_EXPAND(x) x" \ 491 "basic redefine, macro with args" 492 493gdb_test "print MACRO_TO_EXPAND (7)" \ 494 " = 7" \ 495 "expansion of macro with arguments" 496 497gdb_test_no_output "macro undef MACRO_TO_EXPAND" \ 498 "basic macro undef" 499 500gdb_test "print MACRO_TO_EXPAND" \ 501 "No symbol \"MACRO_TO_EXPAND\" in current context\." \ 502 "print expression with macro after user undef." 503 504# Regression test; this used to crash. 505gdb_test "macro define" \ 506 "usage: macro define.*" \ 507 "macro define with no arguments" 508 509# Regression test; this used to crash. 510gdb_test "macro undef" \ 511 "usage: macro undef.*" \ 512 "macro undef with no arguments" 513 514# Completion tests. 515 516# The macro FIFTY_SEVEN is in scope at this point. 517send_gdb "p FIFTY_\t" 518gdb_expect { 519 -re "^p FIFTY_SEVEN $"\ 520 { send_gdb "\n" 521 gdb_expect { 522 -re "^.* = 57.*$gdb_prompt $"\ 523 { pass "complete 'p FIFTY_SEVEN'"} 524 -re ".*$gdb_prompt $" { fail "complete 'p FIFTY_SEVEN'"} 525 timeout {fail "(timeout) complete 'p FIFTY_SEVEN'"} 526 } 527 } 528 -re ".*$gdb_prompt $" { fail "complete 'p FIFTY_SEVEN'" } 529 timeout { fail "(timeout) complete 'p FIFTY_SEVEN' 2" } 530 } 531 532# The macro TWENTY_THREE is not in scope. 533send_gdb "p TWENTY_\t" 534gdb_expect { 535 -re "^p TWENTY_\\\x07$"\ 536 { send_gdb "\n" 537 gdb_expect { 538 -re "No symbol \"TWENTY_\" in current context\\..*$gdb_prompt $"\ 539 { pass "complete 'p TWENTY_'"} 540 -re ".*$gdb_prompt $" { fail "complete 'p TWENTY_'"} 541 timeout {fail "(timeout) complete 'p TWENTY_'"} 542 } 543 } 544 -re ".*$gdb_prompt $" { fail "complete 'p TWENTY_'" } 545 timeout { fail "(timeout) complete 'p TWENTY_' 2" } 546 } 547 548# The macro FORTY_EIGHT was undefined and thus is not in scope. 549send_gdb "p FORTY_\t" 550gdb_expect { 551 -re "^p FORTY_\\\x07$"\ 552 { send_gdb "\n" 553 gdb_expect { 554 -re "No symbol \"FORTY_\" in current context\\..*$gdb_prompt $"\ 555 { pass "complete 'p FORTY_'"} 556 -re ".*$gdb_prompt $" { fail "complete 'p FORTY_'"} 557 timeout {fail "(timeout) complete 'p FORTY_'"} 558 } 559 } 560 -re ".*$gdb_prompt $" { fail "complete 'p FORTY_'" } 561 timeout { fail "(timeout) complete 'p FORTY_' 2" } 562 } 563 564gdb_test_no_output "macro define TWENTY_THREE 25" \ 565 "defining TWENTY_THREE" 566 567# User-defined macros are always in scope. 568send_gdb "p TWENTY_\t" 569gdb_expect { 570 -re "^p TWENTY_THREE $"\ 571 { send_gdb "\n" 572 gdb_expect { 573 -re "^.* = 25.*$gdb_prompt $"\ 574 { pass "complete 'p TWENTY_THREE'"} 575 -re ".*$gdb_prompt $" { fail "complete 'p TWENTY_THREE'"} 576 timeout {fail "(timeout) complete 'p TWENTY_THREE'"} 577 } 578 } 579 -re ".*$gdb_prompt $" { fail "complete 'p TWENTY_THREE'" } 580 timeout { fail "(timeout) complete 'p TWENTY_THREE' 2" } 581 } 582 583# Splicing tests. 584 585gdb_test "macro expand SPLICE(x, y)" \ 586 "expands to: xy" \ 587 "basic macro splicing" 588 589gdb_test_no_output "macro define robotinvasion 2010" \ 590 "define splice helper" 591 592gdb_test "macro expand SPLICE(robot, invasion)" \ 593 "expands to: *2010" \ 594 "splicing plus expansion" 595 596# Varargs tests. 597 598gdb_test_no_output "macro define va_c99(...) varfunc (fixedarg, __VA_ARGS__)" \ 599 "define first varargs helper" 600 601gdb_test_no_output "macro define va2_c99(x, y, ...) varfunc (fixedarg, x, y, __VA_ARGS__)" \ 602 "define second varargs helper" 603 604gdb_test_no_output "macro define va_gnu(args...) varfunc (fixedarg, args)" \ 605 "define third varargs helper" 606 607gdb_test_no_output "macro define va2_gnu(args...) varfunc (fixedarg, ## args)" \ 608 "define fourth varargs helper" 609 610gdb_test "macro expand va_c99(one, two, three)" \ 611 "expands to: *varfunc \\(fixedarg, *one, two, three\\)" \ 612 "c99 varargs expansion" 613 614gdb_test "macro expand va_c99()" \ 615 "expands to: *varfunc \\(fixedarg, *\\)" \ 616 "c99 varargs expansion without an argument" 617 618gdb_test "macro expand va2_c99(one, two, three, four)" \ 619 "expands to: *varfunc \\(fixedarg, *one, two, three, four\\)" \ 620 "c99 varargs expansion, multiple formal arguments" 621 622gdb_test "macro expand va_gnu(one, two, three, four)" \ 623 "expands to: *varfunc \\(fixedarg, *one, two, three, four\\)" \ 624 "gnu varargs expansion" 625 626gdb_test "macro expand va_gnu()" \ 627 "expands to: *varfunc \\(fixedarg, *\\)" \ 628 "gnu varargs expansion without an argument" 629 630gdb_test "macro expand va2_gnu()" \ 631 "expands to: *varfunc \\(fixedarg\\)" \ 632 "gnu varargs expansion special splicing without an argument" 633 634# Stringification tests. 635 636gdb_test_no_output "macro define str(x) #x" \ 637 "define stringification macro" 638 639gdb_test_no_output "macro define maude 5" \ 640 "define first stringification helper" 641 642gdb_test_no_output "macro define xstr(x) str(x)" \ 643 "define second stringification helper" 644 645gdb_test "print str(5)" \ 646 " = \"5\"" \ 647 "simple stringify" 648 649gdb_test "print str(hi bob)" \ 650 " = \"hi bob\"" \ 651 "stringify with one space" 652 653gdb_test "print str( hi bob )" \ 654 " = \"hi bob\"" \ 655 "stringify with many spaces" 656 657gdb_test "print str(hi \"bob\")" \ 658 " = \"hi \\\\\"bob\\\\\"\"" \ 659 "stringify with quotes" 660 661gdb_test "print str(hi \\bob\\)" \ 662 " = \"hi \\\\\\\\bob\\\\\\\\\"" \ 663 "stringify with backslashes" 664 665gdb_test "print str(maude)" \ 666 " = \"maude\"" \ 667 "stringify without substitution" 668 669gdb_test "print xstr(maude)" \ 670 " = \"5\"" \ 671 "stringify with substitution" 672 673# Regression test for pp-number bug. 674gdb_test_no_output "macro define si_addr fields.fault.si_addr" \ 675 "define si_addr macro" 676 677gdb_test "macro expand siginfo.si_addr" \ 678 "expands to: siginfo.fields.fault.si_addr" \ 679 "macro expand siginfo.si_addr" 680