OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [dejagnu/] [runtest.exp] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
# Test Framework Driver
2
# Copyright (C) 92, 93, 94, 95, 96, 97, 98, 1999 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 2 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, write to the Free Software
16
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
 
18
# Please email any bugs, comments, and/or additions to this file to:
19
# bug-dejagnu@prep.ai.mit.edu
20
 
21
# This file was written by Rob Savoye. (rob@cygnus.com)
22
 
23
set frame_version       1.3.1
24
if ![info exists argv0] {
25
    send_error "Must use a version of Expect greater than 5.0\n"
26
    exit 1
27
}
28
 
29
#
30
# trap some signals so we know whats happening. These definitions are only
31
# temporary until we read in the library stuff
32
#
33
trap { send_user "\nterminated\n";             exit 1 } SIGTERM
34
trap { send_user "\ninterrupted by user\n";    exit 1 } SIGINT
35
trap { send_user "\nsigquit\n";                exit 1 } SIGQUIT
36
 
37
#
38
# Initialize a few global variables used by all tests.
39
# `reset_vars' resets several of these, we define them here to document their
40
# existence.  In fact, it would be nice if all globals used by some interface
41
# of dejagnu proper were documented here.
42
#
43
# Keep these all lowercase.  Interface variables used by the various
44
# testsuites (eg: the gcc testsuite) should be in all capitals
45
# (eg: TORTURE_OPTIONS).
46
#
47
set mail_logs   0               ;# flag for mailing of summary and diff logs
48
set psum_file   "latest"        ;# file name of previous summary to diff against
49
 
50
set exit_status 0                ;# exit code returned by this program
51
 
52
set xfail_flag  0
53
set xfail_prms  0
54
set sum_file    ""              ;# name of the file that contains the summary log
55
set base_dir    ""              ;# the current working directory
56
set logname     ""              ;# the users login name
57
set prms_id     0               ;# GNATS prms id number
58
set bug_id      0               ;# optional bug id number
59
set dir         ""              ;# temp variable for directory names
60
set srcdir      "."             ;# source directory containing the test suite
61
set ignoretests ""              ;# list of tests to not execute
62
set objdir      "."             ;# directory where test case binaries live
63
set reboot      0
64
set configfile  site.exp        ;# (local to this file)
65
set multipass   ""              ;# list of passes and var settings
66
set errno       "";             ;#
67
#
68
# These describe the host and target environments.
69
#
70
set build_triplet  ""           ;# type of architecture to run tests on
71
set build_os       ""           ;# type of os the tests are running on
72
set build_vendor   ""           ;# vendor name of the OS or workstation the test are running on
73
set build_cpu      ""           ;# type of the cpu tests are running on
74
set host_triplet   ""           ;# type of architecture to run tests on, sometimes remotely
75
set host_os        ""           ;# type of os the tests are running on
76
set host_vendor    ""           ;# vendor name of the OS or workstation the test are running on
77
set host_cpu       ""           ;# type of the cpu tests are running on
78
set target_triplet ""           ;# type of architecture to run tests on, final remote
79
set target_os      ""           ;# type of os the tests are running on
80
set target_vendor  ""           ;# vendor name of the OS or workstation the test are running on
81
set target_cpu     ""           ;# type of the cpu tests are running on
82
set target_alias   ""           ;# standard abbreviation of target
83
set compiler_flags ""           ;# the flags used by the compiler
84
 
85
#
86
# some convenience abbreviations
87
#
88
if ![info exists hex] {
89
    set hex "0x\[0-9A-Fa-f\]+"
90
}
91
if ![info exists decimal] {
92
    set decimal "\[0-9\]+"
93
}
94
 
95
#
96
# set the base dir (current working directory)
97
#
98
set base_dir [pwd]
99
 
100
#
101
# These are tested in case they are not initialized in $configfile. They are
102
# tested here instead of the init module so they can be overridden by command
103
# line options.
104
#
105
if ![info exists all_flag] {
106
    set all_flag 0
107
}
108
if ![info exists binpath] {
109
    set binpath ""
110
}
111
if ![info exists debug] {
112
    set debug 0
113
}
114
if ![info exists options] {
115
    set options ""
116
}
117
if ![info exists outdir] {
118
    set outdir "."
119
}
120
if ![info exists reboot] {
121
    set reboot 1
122
}
123
if ![info exists tracelevel] {
124
    set tracelevel 0
125
}
126
if ![info exists verbose] {
127
    set verbose 0
128
}
129
 
130
#
131
# verbose [-n] [-log] [--] message [level]
132
#
133
# Print MESSAGE if the verbose level is >= LEVEL.
134
# The default value of LEVEL is 1.
135
# "-n" says to not print a trailing newline.
136
# "-log" says to add the text to the log file even if it won't be printed.
137
# Note that the apparent behaviour of `send_user' dictates that if the message
138
# is printed it is also added to the log file.
139
# Use "--" if MESSAGE begins with "-".
140
#
141
# This is defined here rather than in framework.exp so we can use it
142
# while still loading in the support files.
143
#
144
proc verbose { args } {
145
    global verbose
146
    set newline 1
147
    set logfile 0
148
 
149
    set i 0
150
    if { [string index [lindex $args 0] 0] == "-" } {
151
        for { set i 0 } { $i < [llength $args] } { incr i } {
152
            if { [lindex $args $i] == "--" } {
153
                incr i
154
                break
155
            } elseif { [lindex $args $i] == "-n" } {
156
                set newline 0
157
            } elseif { [lindex $args $i] == "-log" } {
158
                set logfile 1
159
            } elseif { [string index [lindex $args $i] 0] == "-" } {
160
                clone_output "ERROR: verbose: illegal argument: [lindex $args $i]"
161
                return
162
            } else {
163
                break
164
            }
165
        }
166
        if { [llength $args] == $i } {
167
            clone_output "ERROR: verbose: nothing to print"
168
            return
169
        }
170
    }
171
 
172
    set level 1
173
    if { [llength $args] > $i + 1 } {
174
        set level [lindex $args [expr $i+1]]
175
    }
176
    set message [lindex $args $i]
177
 
178
    if { $verbose >= $level } {
179
        # There is no need for the "--" argument here, but play it safe.
180
        # We assume send_user also sends the text to the log file (which
181
        # appears to be the case though the docs aren't clear on this).
182
        if { $newline } {
183
            send_user -- "$message\n"
184
        } else {
185
            send_user -- "$message"
186
        }
187
    } elseif { $logfile } {
188
        if { $newline } {
189
            send_log "$message\n"
190
        } else {
191
            send_log "$message"
192
        }
193
    }
194
}
195
 
196
#
197
# Transform a tool name to get the installed name.
198
# target_triplet is the canonical target name.  target_alias is the
199
# target name used when configure was run.
200
#
201
proc transform { name } {
202
    global target_triplet
203
    global target_alias
204
    global host_triplet
205
    global board;
206
 
207
    if [string match $target_triplet $host_triplet] {
208
        return $name
209
    }
210
    if [string match "native" $target_triplet] {
211
        return $name
212
    }
213
    if [board_info host exists no_transform_name] {
214
        return $name
215
    }
216
    if [string match "" $target_triplet] {
217
        return $name
218
    } else {
219
        if [info exists board] {
220
            if [board_info $board exists target_install] {
221
                set target_install [board_info $board target_install];
222
            }
223
        }
224
        if [target_info exists target_install] {
225
            set target_install [target_info target_install];
226
        }
227
        if [info exists target_alias] {
228
            set tmp ${target_alias}-${name};
229
        } elseif [info exists target_install] {
230
            if { [lsearch -exact $target_install $target_alias] >= 0 } {
231
                set tmp ${target_alias}-${name};
232
            } else {
233
                set tmp "[lindex $target_install 0]-${name}";
234
            }
235
        }
236
        verbose "Transforming $name to $tmp";
237
        return $tmp;
238
    }
239
}
240
 
241
#
242
# findfile arg0 [arg1] [arg2]
243
#
244
# Find a file and see if it exists. If you only care about the false
245
# condition, then you'll need to pass a null "" for arg1.
246
#       arg0 is the filename to look for. If the only arg,
247
#            then that's what gets returned. If this is the
248
#            only arg, then if it exists, arg0 gets returned.
249
#            if it doesn't exist, return only the prog name.
250
#       arg1 is optional, and it's what gets returned if
251
#            the file exists.
252
#       arg2 is optional, and it's what gets returned if
253
#            the file doesn't exist.
254
#
255
proc findfile { args } {
256
    # look for the file
257
    verbose "Seeing if [lindex $args 0] exists." 2
258
    if [file exists [lindex $args 0]] {
259
        if { [llength $args] > 1 } {
260
            verbose "Found file, returning [lindex $args 1]"
261
            return [lindex $args 1]
262
        } else {
263
            verbose "Found file, returning [lindex $args 0]"
264
            return [lindex $args 0]
265
        }
266
    } else {
267
        if { [llength $args] > 2 } {
268
            verbose "Didn't find file [lindex $args 0], returning [lindex $args 2]"
269
            return [lindex $args 2]
270
        } else {
271
            verbose "Didn't find file, returning [file tail [lindex $args 0]]"
272
            return [transform [file tail [lindex $args 0]]]
273
        }
274
    }
275
}
276
 
277
#
278
# load_file [-1] [--] file1 [ file2 ... ]
279
#
280
# Utility to source a file.  All are sourced in order unless the flag "-1"
281
# is given in which case we stop after finding the first one.
282
# The result is 1 if a file was found, 0 if not.
283
# If a tcl error occurs while sourcing a file, we print an error message
284
# and exit.
285
#
286
# ??? Perhaps add an optional argument of some descriptive text to add to
287
# verbose and error messages (eg: -t "library file" ?).
288
#
289
proc load_file { args } {
290
    set i 0
291
    set only_one 0
292
    if { [lindex $args $i] == "-1" } {
293
        set only_one 1
294
        incr i
295
    }
296
    if { [lindex $args $i] == "--" } {
297
        incr i
298
    }
299
 
300
    set found 0
301
    foreach file [lrange $args $i end] {
302
        verbose "Looking for $file" 2
303
        # In Tcl7.5a2, "file exists" can fail if the filename looks
304
        # like ~/FILE and the environment variable HOME does not
305
        # exist.
306
        if {! [catch {file exists $file} result] && $result} {
307
            set found 1
308
            verbose "Found $file"
309
            if { [catch "uplevel #0 source $file"] == 1 } {
310
                send_error "ERROR: tcl error sourcing $file.\n"
311
                global errorInfo
312
                if [info exists errorInfo] {
313
                    send_error "$errorInfo\n"
314
                }
315
                exit 1
316
            }
317
            if $only_one {
318
                break
319
            }
320
        }
321
    }
322
    return $found
323
}
324
 
325
#
326
# search_and_load_file -- search DIRLIST looking for FILELIST.
327
# TYPE is used when displaying error and progress messages.
328
#
329
proc search_and_load_file { type filelist dirlist } {
330
    set found 0;
331
 
332
    foreach dir $dirlist {
333
        foreach initfile $filelist {
334
            verbose "Looking for $type ${dir}/${initfile}" 1
335
            if [file exists ${dir}/${initfile}] {
336
                set found 1
337
                set error ""
338
                if { ${type} != "library file" } {
339
                    send_user "Using ${dir}/${initfile} as ${type}.\n"
340
                } else {
341
                    verbose "Loading ${dir}/${initfile}"
342
                }
343
                if [catch "uplevel #0 source ${dir}/${initfile}" error]==1 {
344
                    global errorInfo
345
                    send_error "ERROR: tcl error sourcing ${type} ${dir}/${initfile}.\n${error}\n"
346
                    if [info exists errorInfo] {
347
                        send_error "$errorInfo\n"
348
                    }
349
                    exit 1
350
                }
351
                break
352
            }
353
        }
354
        if $found {
355
            break
356
        }
357
    }
358
    return $found;
359
}
360
 
361
#
362
# Give a usage statement.
363
#
364
proc usage { } {
365
    global tool;
366
 
367
    send_user "USAGE: runtest \[options...\]\n"
368
    send_user "\t--all (-a)\t\tPrint all test output to screen\n"
369
    send_user "\t--build \[string\]\tThe canonical config name of the build machine\n"
370
    send_user "\t--host \[string\]\t\tThe canonical config name of the host machine\n"
371
    send_user "\t--host_board \[name\]\tThe host board to use\n"
372
    send_user "\t--target \[string\]\tThe canonical config name of the target board\n"
373
    send_user "\t--debug (-de)\t\tSet expect debugging ON\n"
374
    send_user "\t--help (-he)\t\tPrint help text\n"
375
    send_user "\t--mail \[name(s)\]\tWhom to mail the results to\n"
376
    send_user "\t--ignore \[name(s)\]\tThe names of specific tests to ignore\n"
377
    send_user "\t--objdir \[name\]\t\tThe test suite binary directory\n"
378
    send_user "\t--outdir \[name\]\t\tThe directory to put logs in\n"
379
    send_user "\t--reboot \[name\]\t\tReboot the target (if supported)\n"
380
    send_user "\t--srcdir \[name\]\t\tThe test suite source code directory\n"
381
    send_user "\t--strace \[number\]\tSet expect tracing ON\n"
382
    send_user "\t--target_board \[name(s)\] The list of target boards to run tests on\n"
383
    send_user "\t--tool\[name(s)\]\t\tRun tests on these tools\n"
384
    send_user "\t--tool_exec \[name\]\tThe path to the tool executable to test\n"
385
    send_user "\t--tool_opts \[options\]\tA list of additional options to pass to the tool\n"
386
    send_user "\t--directory (-di) name\tRun only the tests in directory 'name'\n"
387
    send_user "\t--verbose (-v)\t\tEmit verbose output\n"
388
    send_user "\t--version (-V)\t\tEmit all version numbers\n"
389
    send_user "\t--D\[0-1\]\t\tTcl debugger\n"
390
    send_user "\tscript.exp\[=arg(s)\]\tRun these tests only\n"
391
    if { [info exists tool] } {
392
        if { [info proc ${tool}_option_help] != "" } {
393
            ${tool}_option_help;
394
        }
395
    }
396
}
397
 
398
#
399
# Parse the arguments the first time looking for these.  We will ultimately
400
# parse them twice.  Things are complicated because:
401
# - we want to parse --verbose early on
402
# - we don't want config files to override command line arguments
403
#   (eg: $base_dir/$configfile vs --host/--target)
404
# - we need some command line arguments before we can process some config files
405
#   (eg: --objdir before $objdir/$configfile, --host/--target before $DEJAGNU)
406
# The use of `arg_host_triplet' and `arg_target_triplet' lets us avoid parsing
407
# the arguments three times.
408
#
409
 
410
set arg_host_triplet ""
411
set arg_target_triplet ""
412
set arg_build_triplet ""
413
set argc [ llength $argv ]
414
for { set i 0 } { $i < $argc } { incr i } {
415
    set option [lindex $argv $i]
416
 
417
    # make all options have two hyphens
418
    switch -glob -- $option {
419
        "--*" {
420
        }
421
        "-*" {
422
            set option "-$option"
423
        }
424
    }
425
 
426
    # split out the argument for options that take them
427
    switch -glob -- $option {
428
        "--*=*" {
429
            regexp {^[^=]*=(.*)$} $option nil optarg
430
        }
431
        "--bu*" -
432
        "--ho*" -
433
        "--ig*"  -
434
        "--m*"  -
435
        "--n*"  -
436
        "--ob*" -
437
        "--ou*" -
438
        "--sr*" -
439
        "--st*" -
440
        "--ta*" -
441
        "--di*" -
442
        "--to*" {
443
            incr i
444
            set optarg [lindex $argv $i]
445
        }
446
    }
447
 
448
    switch -glob -- $option {
449
        "--bu*" {                       # (--build) the build host configuration
450
            set arg_build_triplet $optarg
451
            continue
452
        }
453
 
454
        "--host_bo*" {
455
            set host_board $optarg
456
            continue
457
        }
458
 
459
        "--ho*" {                       # (--host) the host configuration
460
            set arg_host_triplet $optarg
461
            continue
462
        }
463
 
464
        "--ob*" {                       # (--objdir) where the test case object code lives
465
            set objdir $optarg
466
            continue
467
        }
468
 
469
        "--sr*" {                       # (--srcdir) where the testsuite source code lives
470
            set srcdir $optarg
471
            continue
472
        }
473
 
474
        "--target_bo*" {
475
            set target_list $optarg;
476
            continue;
477
        }
478
 
479
        "--ta*" {                       # (--target) the target configuration
480
            set arg_target_triplet $optarg
481
            continue
482
        }
483
 
484
        "--tool_opt*" {
485
            set TOOL_OPTIONS $optarg
486
            continue
487
        }
488
 
489
        "--tool_exec*" {
490
            set TOOL_EXECUTABLE $optarg
491
            continue
492
        }
493
 
494
        "--tool_ro*" {
495
            set tool_root_dir $optarg
496
            continue;
497
        }
498
 
499
        "--to*" {                       # (--tool) specify tool name
500
            set tool $optarg
501
            set comm_line_tool $optarg;
502
            continue
503
        }
504
 
505
        "--di*" {
506
            set cmdline_dir_to_run $optarg
507
            puts "cmdline_dir_to_run = $cmdline_dir_to_run"
508
            continue
509
        }
510
 
511
        "--v" -
512
        "--verb*" {                     # (--verbose) verbose output
513
            incr verbose
514
            continue
515
        }
516
    }
517
}
518
verbose "Verbose level is $verbose"
519
 
520
#
521
# get the users login name
522
#
523
if [string match "" $logname] {
524
    if [info exists env(USER)] {
525
        set logname $env(USER)
526
    } else {
527
        if [info exists env(LOGNAME)] {
528
            set logname $env(LOGNAME)
529
        } else {
530
            # try getting it with whoami
531
            catch "set logname [exec whoami]" tmp
532
            if [string match "*couldn't find*to execute*" $tmp] {
533
                # try getting it with who am i
534
                unset tmp
535
                catch "set logname [exec who am i]" tmp
536
                if [string match "*Command not found*" $tmp] {
537
                    send_user "ERROR: couldn't get the users login name\n"
538
                    set logname "Unknown"
539
                } else {
540
                    set logname [lindex [split $logname " !"] 1]
541
                }
542
            }
543
        }
544
    }
545
}
546
 
547
#
548
# lookfor_file -- try to find a file by searching up multiple directory levels
549
#
550
proc lookfor_file { dir name } {
551
    foreach x ".. ../.. ../../.. ../../../.." {
552
        verbose "$dir/$name"
553
        if [file exists $dir/$name] {
554
            return $dir/$name;
555
        }
556
        set dir [remote_file build dirname $dir];
557
    }
558
    return ""
559
}
560
 
561
#
562
# load_lib -- load a library by sourcing it
563
#
564
# If there a multiple files with the same name, stop after the first one found.
565
# The order is first look in the install dir, then in a parallel dir in the
566
# source tree, (up one or two levels), then in the current dir.
567
#
568
proc load_lib { file } {
569
    global verbose libdir srcdir base_dir execpath tool
570
    global loaded_libs
571
 
572
    if [info exists loaded_libs($file)] {
573
        return;
574
    }
575
 
576
    set loaded_libs($file) "";
577
 
578
    if { [search_and_load_file "library file" $file [list $libdir $libdir/lib [file dirname [file dirname $srcdir]]/dejagnu/lib $srcdir/lib . [file dirname [file dirname [file dirname $srcdir]]]/dejagnu/lib]] == 0 } {
579
        send_error "ERROR: Couldn't find library file $file.\n"
580
        exit 1
581
    }
582
}
583
 
584
verbose "Login name is $logname"
585
 
586
#
587
# Begin sourcing the config files.
588
# All are sourced in order.
589
#
590
# Search order:
591
#       $HOME/.dejagnurc -> $base_dir/$configfile -> $objdir/$configfile
592
#       -> installed -> $DEJAGNU
593
#
594
# ??? It might be nice to do $HOME last as it would allow it to be the
595
# ultimate override.  Though at present there is still $DEJAGNU.
596
#
597
# For the normal case, we rely on $base_dir/$configfile to set
598
# host_triplet and target_triplet.
599
#
600
 
601
load_file ~/.dejagnurc $base_dir/$configfile
602
 
603
#
604
# If objdir didn't get set in $base_dir/$configfile, set it to $base_dir.
605
# Make sure we source $objdir/$configfile in case $base_dir/$configfile doesn't
606
# exist and objdir was given on the command line.
607
#
608
 
609
if [expr [string match "." $objdir] || [string match $srcdir $objdir]] {
610
    set objdir $base_dir
611
} else {
612
    load_file $objdir/$configfile
613
}
614
 
615
# Well, this just demonstrates the real problem...
616
if ![info exists tool_root_dir] {
617
    set tool_root_dir [file dirname $objdir];
618
    if [file exists "$tool_root_dir/testsuite"] {
619
        set tool_root_dir [file dirname $tool_root_dir];
620
    }
621
}
622
 
623
verbose "Using test sources in $srcdir"
624
verbose "Using test binaries in $objdir"
625
verbose "Tool root directory is $tool_root_dir"
626
 
627
set execpath [file dirname $argv0]
628
set libdir   [file dirname $execpath]/dejagnu
629
if [info exists env(DEJAGNULIBS)] {
630
    set libdir $env(DEJAGNULIBS)
631
}
632
 
633
verbose "Using $libdir to find libraries"
634
 
635
#
636
# If the host or target was given on the command line, override the above
637
# config files.  We allow $DEJAGNU to massage them though in case it would
638
# ever want to do such a thing.
639
#
640
if { $arg_host_triplet != "" } {
641
    set host_triplet $arg_host_triplet
642
}
643
if { $arg_build_triplet != "" } {
644
    set build_triplet $arg_build_triplet
645
}
646
 
647
# if we only specify --host, then that must be the build machne too, and we're
648
# stuck using the old functionality of a simple cross test
649
if [expr { $build_triplet == ""  &&  $host_triplet != "" } ] {
650
    set build_triplet $host_triplet
651
}
652
# if we only specify --build, then we'll use that as the host too
653
if [expr { $build_triplet != "" && $host_triplet == "" } ] {
654
    set host_triplet $build_triplet
655
}
656
unset arg_host_triplet arg_build_triplet
657
 
658
#
659
# If the build machine type hasn't been specified by now, use config.guess.
660
#
661
 
662
if [expr  { $build_triplet == ""  &&  $host_triplet == ""} ] {
663
    # find config.guess
664
    foreach dir "$libdir $libdir/.. $srcdir/.. $srcdir/../.." {
665
        verbose "Looking for ${dir}/config.guess" 2
666
        if [file exists ${dir}/config.guess] {
667
            set config_guess ${dir}/config.guess
668
            verbose "Found ${dir}/config.guess"
669
            break
670
        }
671
    }
672
 
673
    # get the canonical config name
674
    if ![info exists config_guess] {
675
        send_error "ERROR: Couldn't find config.guess program.\n"
676
        exit 1
677
    }
678
    catch "exec $config_guess" build_triplet
679
    case $build_triplet in {
680
        { "No uname command or uname output not recognized" "Unable to guess system type" } {
681
            verbose "WARNING: Uname output not recognized"
682
            set build_triplet unknown
683
        }
684
    }
685
    verbose "Assuming build host is $build_triplet"
686
    if { $host_triplet == "" } {
687
        set host_triplet $build_triplet
688
    }
689
 
690
}
691
 
692
#
693
# Figure out the target. If the target hasn't been specified, then we have to
694
# assume we are native.
695
#
696
if { $arg_target_triplet != "" } {
697
    set target_triplet $arg_target_triplet
698
} elseif { $target_triplet == "" } {
699
    set target_triplet $build_triplet
700
    verbose "Assuming native target is $target_triplet" 2
701
}
702
unset arg_target_triplet
703
#
704
# Default target_alias to target_triplet.
705
#
706
if ![info exists target_alias] {
707
    set target_alias $target_triplet
708
}
709
 
710
proc get_local_hostname { } {
711
    if [catch "info hostname" hb] {
712
        set hb ""
713
    } else {
714
        regsub "\\..*$" $hb "" hb;
715
    }
716
    verbose "hostname=$hb" 3;
717
    return $hb;
718
}
719
 
720
#
721
# We put these here so that they can be overridden later by site.exp or
722
# friends.
723
#
724
# Set up the target as machine NAME. We also load base-config.exp as a
725
# default configuration. The config files are sourced with the global
726
# variable $board set to the name of the current target being defined.
727
#
728
proc setup_target_hook { whole_name name } {
729
    global board;
730
    global host_board;
731
 
732
    if [info exists host_board] {
733
        set hb $host_board;
734
    } else {
735
        set hb [get_local_hostname];
736
    }
737
 
738
    set board $whole_name;
739
 
740
    global board_type;
741
    set board_type "target";
742
 
743
    load_config base-config.exp;
744
    if ![load_board_description ${name} ${whole_name} ${hb}] {
745
        if { $name != "unix" } {
746
            perror "couldn't load description file for ${name}";
747
            exit 1;
748
        } else {
749
            load_generic_config "unix"
750
        }
751
    }
752
 
753
    if [board_info $board exists generic_name] {
754
        load_tool_target_config [board_info $board generic_name];
755
    }
756
 
757
    unset board;
758
    unset board_type;
759
 
760
    push_target $whole_name;
761
 
762
    if { [info procs ${whole_name}_init] != "" } {
763
        ${whole_name}_init $whole_name;
764
    }
765
 
766
    if { ![isnative] && ![is_remote target] } {
767
        global env build_triplet target_triplet
768
        if { (![info exists env(DEJAGNU)]) && ($build_triplet != $target_triplet) } {
769
            warning "Assuming target board is the local machine (which is probably wrong).\nYou may need to set your DEJAGNU environment variable."
770
        }
771
    }
772
}
773
 
774
#
775
# Clean things up afterwards.
776
#
777
proc cleanup_target_hook { name } {
778
    global tool;
779
    # Clean up the target board.
780
    if { [info procs "${name}_exit"] != "" } {
781
        ${name}_exit;
782
    }
783
    # We also call the tool exit routine here.
784
    if [info exists tool] {
785
        if { [info procs "${tool}_exit"] != "" } {
786
            ${tool}_exit;
787
        }
788
    }
789
    remote_close target;
790
    pop_target;
791
}
792
 
793
proc setup_host_hook { name } {
794
    global board;
795
    global board_info;
796
    global board_type;
797
 
798
    set board $name;
799
    set board_type "host";
800
 
801
    load_board_description $name;
802
    unset board;
803
    unset board_type;
804
    push_host $name;
805
    if { [info proc ${name}_init] != "" } {
806
        ${name}_init $name;
807
    }
808
}
809
 
810
proc setup_build_hook { name } {
811
    global board;
812
    global board_info;
813
    global board_type;
814
 
815
    set board $name;
816
    set board_type "build";
817
 
818
    load_board_description $name;
819
    unset board;
820
    unset board_type;
821
    push_build $name;
822
    if { [info proc ${name}_init] != "" } {
823
        ${name}_init $name;
824
    }
825
}
826
 
827
#
828
# Find and load the global config file if it exists.
829
# The global config file is used to set the connect mode and other
830
# parameters specific to each particular target.
831
# These files assume the host and target have been set.
832
#
833
 
834
if { [load_file -- $libdir/$configfile] == 0 } {
835
    # If $DEJAGNU isn't set either then there isn't any global config file.
836
    # Warn the user as there really should be one.
837
    if { ! [info exists env(DEJAGNU)] } {
838
        send_error "WARNING: Couldn't find the global config file.\n"
839
    }
840
}
841
 
842
if [info exists env(DEJAGNU)] {
843
    if { [load_file -- $env(DEJAGNU)] == 0 } {
844
        # It may seem odd to only issue a warning if there isn't a global
845
        # config file, but issue an error if $DEJAGNU is erroneously defined.
846
        # Since $DEJAGNU is set there is *supposed* to be a global config file,
847
        # so the current behaviour seems reasonable.
848
        send_error "WARNING: global config file $env(DEJAGNU) not found.\n"
849
    }
850
    if ![info exists boards_dir] {
851
        set boards_dir "[file dirname $env(DEJAGNU)]/boards";
852
    }
853
}
854
 
855
if ![info exists boards_dir] {
856
    set boards_dir ""
857
}
858
 
859
#
860
# parse out the config parts of the triplet name
861
#
862
 
863
# build values
864
if { $build_cpu == "" } {
865
    regsub -- "-.*-.*" ${build_triplet} "" build_cpu
866
}
867
if { $build_vendor == "" } {
868
    regsub -- "^\[a-z0-9\]*-" ${build_triplet} "" build_vendor
869
    regsub -- "-.*" ${build_vendor} "" build_vendor
870
}
871
if { $build_os == "" } {
872
    regsub -- ".*-.*-" ${build_triplet} "" build_os
873
}
874
 
875
# host values
876
if { $host_cpu == "" } {
877
    regsub -- "-.*-.*" ${host_triplet} "" host_cpu
878
}
879
if { $host_vendor == "" } {
880
    regsub -- "^\[a-z0-9\]*-" ${host_triplet} "" host_vendor
881
    regsub -- "-.*" ${host_vendor} "" host_vendor
882
}
883
if { $host_os == "" } {
884
    regsub -- ".*-.*-" ${host_triplet} "" host_os
885
}
886
 
887
# target values
888
if { $target_cpu == "" } {
889
    regsub -- "-.*-.*" ${target_triplet} "" target_cpu
890
}
891
if { $target_vendor == "" } {
892
    regsub -- "^\[a-z0-9\]*-" ${target_triplet} "" target_vendor
893
    regsub -- "-.*" ${target_vendor} "" target_vendor
894
}
895
if { $target_os == "" } {
896
    regsub -- ".*-.*-" ${target_triplet} "" target_os
897
}
898
 
899
#
900
# Load the primary tool initialization file.
901
#
902
 
903
proc load_tool_init { file } {
904
    global srcdir
905
    global loaded_libs
906
 
907
    if [info exists loaded_libs($file)] {
908
        return;
909
    }
910
 
911
    set loaded_libs($file) "";
912
 
913
    if [file exists ${srcdir}/lib/$file] {
914
        verbose "Loading library file ${srcdir}/lib/$file"
915
        if { [catch "uplevel #0 source ${srcdir}/lib/$file"] == 1 } {
916
            send_error "ERROR: tcl error sourcing library file ${srcdir}/lib/$file.\n"
917
            global errorInfo
918
            if [info exists errorInfo] {
919
                send_error "$errorInfo\n"
920
            }
921
            exit 1
922
        }
923
    } else {
924
        warning "Couldn't find tool init file"
925
    }
926
}
927
 
928
#
929
# load the testing framework libraries
930
#
931
load_lib utils.exp
932
load_lib framework.exp
933
load_lib debugger.exp
934
load_lib remote.exp
935
load_lib target.exp
936
load_lib targetdb.exp
937
load_lib libgloss.exp
938
 
939
# Initialize the test counters and reset them to 0.
940
init_testcounts;
941
reset_vars;
942
 
943
#
944
# Parse the command line arguments.
945
#
946
 
947
# Load the tool initialization file. Allow the --tool option to override
948
# what's set in the site.exp file.
949
if [info exists comm_line_tool] {
950
    set tool $comm_line_tool;
951
}
952
 
953
if [info exists tool] {
954
    load_tool_init ${tool}.exp;
955
}
956
 
957
set argc [ llength $argv ]
958
for { set i 0 } { $i < $argc } { incr i } {
959
    set option [ lindex $argv $i ]
960
 
961
    # make all options have two hyphens
962
    switch -glob -- $option {
963
        "--*" {
964
        }
965
        "-*" {
966
            set option "-$option"
967
        }
968
    }
969
 
970
    # split out the argument for options that take them
971
    switch -glob -- $option {
972
        "--*=*" {
973
            regexp {^[^=]*=(.*)$} $option nil optarg
974
        }
975
        "--bu*" -
976
        "--ho*" -
977
        "--ig*"  -
978
        "--m*"  -
979
        "--n*"  -
980
        "--ob*" -
981
        "--ou*" -
982
        "--sr*" -
983
        "--st*" -
984
        "--ta*" -
985
        "--di*" -
986
        "--to*" {
987
            incr i
988
            set optarg [lindex $argv $i]
989
        }
990
    }
991
 
992
    switch -glob -- $option {
993
        "--V*" -
994
        "--vers*" {                     # (--version) version numbers
995
            send_user "Expect version is\t[exp_version]\n"
996
            send_user "Tcl version is\t\t[ info tclversion ]\n"
997
            send_user "Framework version is\t$frame_version\n"
998
            exit
999
        }
1000
 
1001
        "--v*" {                        # (--verbose) verbose output
1002
            # Already parsed.
1003
            continue
1004
        }
1005
 
1006
        "--bu*" {                       # (--build) the build host configuration
1007
            # Already parsed (and don't set again).  Let $DEJAGNU rename it.
1008
            continue
1009
        }
1010
 
1011
        "--ho*" {                       # (--host) the host configuration
1012
            # Already parsed (and don't set again).  Let $DEJAGNU rename it.
1013
            continue
1014
        }
1015
 
1016
        "--target_bo*" {
1017
            # Set it again, father knows best.
1018
            set target_list $optarg;
1019
            continue;
1020
        }
1021
 
1022
        "--ta*" {                       # (--target) the target configuration
1023
            # Already parsed (and don't set again).  Let $DEJAGNU rename it.
1024
            continue
1025
        }
1026
 
1027
        "--a*" {                        # (--all) print all test output to screen
1028
            set all_flag 1
1029
            verbose "Print all test output to screen"
1030
            continue
1031
        }
1032
 
1033
        "--di*" {
1034
            # Already parsed (and don't set again).  Let $DEJAGNU rename it.
1035
            # set cmdline_dir_to_run $optarg
1036
            continue
1037
        }
1038
 
1039
 
1040
        "--de*" {                       # (--debug) expect internal debugging
1041
            if [file exists ./dbg.log] {
1042
                catch "exec rm -f ./dbg.log"
1043
            }
1044
            if { $verbose > 2 } {
1045
                exp_internal -f dbg.log 1
1046
            } else {
1047
                exp_internal -f dbg.log 0
1048
            }
1049
            verbose "Expect Debugging is ON"
1050
            continue
1051
        }
1052
 
1053
        "--D[01]" {                     # (-Debug) turn on Tcl debugger
1054
            verbose "Tcl debugger is ON"
1055
            continue
1056
        }
1057
 
1058
        "--m*" {                        # (--mail) mail the output
1059
            set mailing_list $optarg
1060
            set mail_logs 1
1061
            verbose "Mail results to $mailing_list"
1062
            continue
1063
        }
1064
 
1065
        "--r*" {                        # (--reboot) reboot the target
1066
            set reboot 1
1067
            verbose "Will reboot the target (if supported)"
1068
            continue
1069
        }
1070
 
1071
        "--ob*" {                       # (--objdir) where the test case object code lives
1072
            # Already parsed, but parse again to make sure command line
1073
            # options override any config file.
1074
            set objdir $optarg
1075
            verbose "Using test binaries in $objdir"
1076
            continue
1077
        }
1078
 
1079
        "--ou*" {                       # (--outdir) where to put the output files
1080
            set outdir $optarg
1081
            verbose "Test output put in $outdir"
1082
            continue
1083
        }
1084
 
1085
        "*.exp" {                       #  specify test names to run
1086
            set all_runtests($option) ""
1087
            verbose "Running only tests $option"
1088
            continue
1089
        }
1090
 
1091
        "*.exp=*" {                     #  specify test names to run
1092
            set tmp [split $option "="]
1093
            set all_runtests([lindex $tmp 0]) [lindex $tmp 1]
1094
            verbose "Running only tests $option"
1095
            unset tmp
1096
            continue
1097
        }
1098
 
1099
        "--ig*" {                       #  (--ignore) specify test names to exclude
1100
            set ignoretests $optarg
1101
            verbose "Ignoring test $ignoretests"
1102
            continue
1103
        }
1104
 
1105
        "--sr*" {                       # (--srcdir) where the testsuite source code lives
1106
            # Already parsed, but parse again to make sure command line
1107
            # options override any config file.
1108
 
1109
            set srcdir $optarg
1110
            continue
1111
        }
1112
 
1113
        "--st*" {                       # (--strace) expect trace level
1114
            set tracelevel $optarg
1115
            strace $tracelevel
1116
            verbose "Source Trace level is now $tracelevel"
1117
            continue
1118
        }
1119
 
1120
        "--tool_opt*" {
1121
            continue
1122
        }
1123
 
1124
        "--tool_exec*" {
1125
            set TOOL_EXECUTABLE $optarg
1126
            continue
1127
        }
1128
 
1129
        "--tool_ro*" {
1130
            set tool_root_dir $optarg
1131
            continue;
1132
        }
1133
 
1134
        "--to*" {                       # (--tool) specify tool name
1135
            set tool $optarg
1136
            verbose "Testing $tool"
1137
            continue
1138
        }
1139
 
1140
        "[A-Z0-9_-.]*=*" { # process makefile style args like CC=gcc, etc...
1141
            if [regexp "^(\[A-Z0-9_-\]+)=(.*)$" $option junk var val] {
1142
                set $var $val
1143
                verbose "$var is now $val"
1144
                append makevars "set $var $val;" ;# FIXME: Used anywhere?
1145
                unset junk var val
1146
            } else {
1147
                send_error "Illegal variable specification:\n"
1148
                send_error "$option\n"
1149
            }
1150
            continue
1151
        }
1152
 
1153
        "--he*" {                       # (--help) help text
1154
            usage;
1155
            exit 0
1156
        }
1157
 
1158
        default {
1159
            if [info exists tool] {
1160
                if { [info proc ${tool}_option_proc] != "" } {
1161
                    if [${tool}_option_proc $option] {
1162
                        continue;
1163
                    }
1164
                }
1165
            }
1166
            send_error "\nIllegal Argument \"$option\"\n"
1167
            send_error "try \"runtest --help\" for option list\n"
1168
            exit 1
1169
        }
1170
    }
1171
}
1172
 
1173
#
1174
# check for a few crucial variables
1175
#
1176
if ![info exists tool] {
1177
    send_error "WARNING: No tool specified\n"
1178
    set tool ""
1179
}
1180
 
1181
#
1182
# initialize a few Tcl variables to something other than their default
1183
#
1184
if { $verbose > 2 } {
1185
    log_user 1
1186
} else {
1187
    log_user 0
1188
}
1189
 
1190
set timeout 10
1191
 
1192
 
1193
 
1194
#
1195
# open log files
1196
#
1197
open_logs
1198
 
1199
# print the config info
1200
clone_output "Test Run By $logname on [timestamp -format %c]"
1201
if [is3way]  {
1202
    clone_output "Target is $target_triplet"
1203
    clone_output "Host   is $host_triplet"
1204
    clone_output "Build  is $build_triplet"
1205
} else {
1206
    if [isnative] {
1207
        clone_output "Native configuration is $target_triplet"
1208
    } else {
1209
        clone_output "Target is $target_triplet"
1210
        clone_output "Host   is $host_triplet"
1211
    }
1212
}
1213
 
1214
clone_output "\n\t\t=== $tool tests ===\n"
1215
 
1216
#
1217
# Look for the generic board configuration file. It searches in several
1218
# places: ${libdir}/config, ${libdir}/../config, and $boards_dir.
1219
#
1220
 
1221
proc load_generic_config { name } {
1222
    global srcdir;
1223
    global configfile;
1224
    global libdir;
1225
    global env;
1226
    global board;
1227
    global board_info;
1228
    global boards_dir;
1229
    global board_type;
1230
 
1231
    if [info exists board] {
1232
        if ![info exists board_info($board,generic_name)] {
1233
            set board_info($board,generic_name) $name;
1234
        }
1235
    }
1236
 
1237
    if [info exists board_type] {
1238
        set type "for $board_type";
1239
    } else {
1240
        set type ""
1241
    }
1242
 
1243
    set dirlist [concat ${libdir}/config [file dirname $libdir]/config $boards_dir];
1244
    set result [search_and_load_file "generic interface file $type" ${name}.exp $dirlist];
1245
 
1246
    return $result;
1247
}
1248
 
1249
#
1250
# Load the tool-specific target description.
1251
#
1252
proc load_config { args } {
1253
    global srcdir;
1254
    global board_type;
1255
 
1256
    set found 0;
1257
 
1258
    return [search_and_load_file "tool-and-target-specific interface file" $args [list ${srcdir}/config ${srcdir}/../config ${srcdir}/../../config ${srcdir}/../../../config]];
1259
}
1260
 
1261
#
1262
# Find the files that set up the configuration for the target. There
1263
# are assumed to be two of them; one defines a basic set of
1264
# functionality for the target that can be used by all tool
1265
# testsuites, and the other defines any necessary tool-specific
1266
# functionality. These files are loaded via load_config.
1267
#
1268
# These used to all be named $target_abbrev-$tool.exp, but as the
1269
# $tool variable goes away, it's now just $target_abbrev.exp.  First
1270
# we look for a file named with both the abbrev and the tool names.
1271
# Then we look for one named with just the abbrev name. Finally, we
1272
# look for a file called default, which is the default actions, as
1273
# some tools could be purely host based. Unknown is mostly for error
1274
# trapping.
1275
#
1276
 
1277
proc load_tool_target_config { name } {
1278
    global target_os
1279
 
1280
    set found [load_config "${name}.exp" "${target_os}.exp" "default.exp" "unknown.exp"];
1281
 
1282
    if { $found == 0 } {
1283
        send_error "ERROR: Couldn't find tool config file for $name.\n"
1284
    }
1285
}
1286
 
1287
 
1288
#
1289
# Find the file that describes the machine specified by board_name.
1290
#
1291
 
1292
proc load_board_description { board_name args } {
1293
    global srcdir;
1294
    global configfile;
1295
    global libdir;
1296
    global env;
1297
    global board;
1298
    global board_info
1299
    global boards_dir;
1300
    global board_type;
1301
 
1302
    set dejagnu ""
1303
 
1304
    if { [llength $args] > 0 } {
1305
        set whole_name [lindex $args 0];
1306
    } else {
1307
        set whole_name $board_name;
1308
    }
1309
 
1310
    set board_info($whole_name,name) $whole_name;
1311
    if ![info exists board] {
1312
        set board $whole_name;
1313
        set board_set 1;
1314
    } else {
1315
        set board_set 0;
1316
    }
1317
 
1318
    set dirlist {};
1319
    if { [llength $args] > 1 } {
1320
        set suffix [lindex $args 1];
1321
        if { ${suffix} != "" } {
1322
            foreach x ${boards_dir} {
1323
                lappend dirlist ${x}/${suffix}
1324
            }
1325
            lappend dirlist ${libdir}/baseboards/${suffix};
1326
        }
1327
    }
1328
    set dirlist [concat $dirlist $boards_dir];
1329
    lappend dirlist ${libdir}/baseboards;
1330
    verbose "dirlist is $dirlist"
1331
    if [info exists board_type] {
1332
        set type "for $board_type";
1333
    } else {
1334
        set type "";
1335
    }
1336
    if ![info exists board_info($whole_name,isremote)] {
1337
        set board_info($whole_name,isremote) 1;
1338
        if [info exists board_type] {
1339
            if { $board_type == "build" } {
1340
                set board_info($whole_name,isremote) 0;
1341
            }
1342
        }
1343
        if { ${board_name} == [get_local_hostname] } {
1344
            set board_info($whole_name,isremote) 0;
1345
        }
1346
    }
1347
    search_and_load_file "standard board description file $type" standard.exp $dirlist;
1348
    set found [search_and_load_file "board description file $type" ${board_name}.exp $dirlist];
1349
    if { $board_set != 0 } {
1350
        unset board;
1351
    }
1352
 
1353
    return $found;
1354
}
1355
 
1356
#
1357
# Find the base-level file that describes the machine specified by args. We
1358
# only look in one directory, ${libdir}/baseboards.
1359
#
1360
 
1361
proc load_base_board_description { board_name } {
1362
    global srcdir;
1363
    global configfile;
1364
    global libdir;
1365
    global env;
1366
    global board;
1367
    global board_info
1368
    global board_type;
1369
 
1370
    set board_set 0;
1371
    set board_info($board_name,name) $board_name;
1372
    if ![info exists board] {
1373
        set board $board_name;
1374
        set board_set 1;
1375
    }
1376
    if [info exists board_type] {
1377
        set type "for $board_type";
1378
    } else {
1379
        set type ""
1380
    };
1381
    if ![info exists board_info($board_name,isremote)] {
1382
        set board_info($board_name,isremote) 1;
1383
        if [info exists board_type] {
1384
            if { $board_type == "build" } {
1385
                set board_info($board_name,isremote) 0;
1386
            }
1387
        }
1388
    }
1389
 
1390
    if { ${board_name} == [get_local_hostname] } {
1391
        set board_info($board_name,isremote) 0;
1392
    }
1393
    set found [search_and_load_file "board description file $type" ${board_name}.exp ${libdir}/baseboards];
1394
    if { $board_set != 0 } {
1395
        unset board;
1396
    }
1397
 
1398
    return $found;
1399
}
1400
 
1401
#
1402
# Source the testcase in TEST_FILE_NAME.
1403
#
1404
 
1405
proc runtest { test_file_name } {
1406
    global prms_id
1407
    global bug_id
1408
    global test_result
1409
    global errcnt
1410
    global errorInfo
1411
    global tool
1412
 
1413
    clone_output "Running $test_file_name ..."
1414
    set prms_id 0
1415
    set bug_id  0
1416
    set test_result ""
1417
 
1418
    if [file exists $test_file_name] {
1419
        set timestart [timestamp];
1420
 
1421
        if [info exists tool] {
1422
            if { [info procs "${tool}_init"] != "" } {
1423
                ${tool}_init $test_file_name;
1424
            }
1425
        }
1426
 
1427
        if { [catch "uplevel #0 source $test_file_name"] == 1 } {
1428
            # We can't call `perror' here, it resets `errorInfo'
1429
            # before we want to look at it.  Also remember that perror
1430
            # increments `errcnt'.  If we do call perror we'd have to
1431
            # reset errcnt afterwards.
1432
            clone_output "ERROR: tcl error sourcing $test_file_name."
1433
            if [info exists errorInfo] {
1434
                clone_output "ERROR: $errorInfo"
1435
                unset errorInfo
1436
            }
1437
        }
1438
 
1439
        if [info exists tool] {
1440
            if { [info procs "${tool}_finish"] != "" } {
1441
                ${tool}_finish;
1442
            }
1443
        }
1444
        set timeend [timestamp];
1445
        set timediff [expr $timeend - $timestart];
1446
        verbose -log "testcase $test_file_name completed in $timediff seconds" 4
1447
    } else {
1448
        # This should never happen, but maybe if the file got removed
1449
        # between the `find' above and here.
1450
        perror "$test_file_name does not exist."
1451
        # ??? This is a hack.  We want to send a message to stderr and
1452
        # to the summary file (just like perror does), but we don't
1453
        # want the next testcase to get a spurious "unresolved" because
1454
        # errcnt != 0.  Calling `clone_output' is also supposed to be a
1455
        # no-no (see the comments for clone_output).
1456
        set errcnt 0
1457
    }
1458
}
1459
 
1460
#
1461
# Trap some signals so we know what's happening.  These replace the previous
1462
# ones because we've now loaded the library stuff.
1463
#
1464
if ![exp_debug] {
1465
    foreach sig "{SIGTERM {terminated}} \
1466
             {SIGINT  {interrupted by user}} \
1467
             {SIGQUIT {interrupted by user}} \
1468
             {SIGSEGV {segmentation violation}}" {
1469
         set signal [lindex $sig 0];
1470
         set str [lindex $sig 1];
1471
         trap "send_error \"got a \[trap -name\] signal, $str \\n\"; log_and_exit;" $signal;
1472
         verbose "setting trap for $signal to $str" 1
1473
    }
1474
    unset signal str sig;
1475
}
1476
 
1477
#
1478
# Given a list of targets, process any iterative lists.
1479
#
1480
proc process_target_variants { target_list } {
1481
    set result {};
1482
    foreach x $target_list {
1483
        if [regexp "\\(" $x] {
1484
            regsub "^.*\\((\[^()\]*)\\)$" "$x" "\\1" variant_list;
1485
            regsub "\\(\[^(\]*$" "$x" "" x;
1486
            set list [process_target_variants $x];
1487
            set result {}
1488
            foreach x $list {
1489
                set result [concat $result [iterate_target_variants $x [split $variant_list ","]]];
1490
            }
1491
        } elseif [regexp "\{" $x] {
1492
            regsub "^.*\{(\[^\{\}\]*)\}$" "$x" "\\1" variant_list;
1493
            regsub "\{\[^\{\]*$" "$x" "" x;
1494
            set list [process_target_variants $x];
1495
            foreach x $list {
1496
                foreach i [split $variant_list ","] {
1497
                    set name $x;
1498
                    if { $i != "" } {
1499
                        append name "/" $i;
1500
                    }
1501
                    lappend result $name;
1502
                }
1503
            }
1504
        } else {
1505
            lappend result "$x";
1506
        }
1507
    }
1508
    return $result;
1509
}
1510
 
1511
proc iterate_target_variants { target variants } {
1512
    return [iterate_target_variants_two $target $target $variants];
1513
}
1514
 
1515
#
1516
# Given a list of variants, produce the list of all possible combinations.
1517
#
1518
proc iterate_target_variants_two { orig_target target variants } {
1519
 
1520
    if { [llength $variants] == 0 } {
1521
        return [list $target];
1522
    } else {
1523
        if { [llength $variants] > 1 } {
1524
            set result [iterate_target_variants_two $orig_target $target [lrange $variants 1 end]];
1525
        } else {
1526
            if { $target != $orig_target } {
1527
                set result [list $target];
1528
            } else {
1529
                set result {};
1530
            }
1531
        }
1532
        if { [lindex $variants 0] != "" } {
1533
            append target "/" [lindex $variants 0];
1534
            return [concat $result [iterate_target_variants_two $orig_target $target [lrange $variants 1 end]]];
1535
        } else {
1536
            return [concat $result $target];
1537
        }
1538
    }
1539
}
1540
 
1541
setup_build_hook [get_local_hostname];
1542
 
1543
if [info exists host_board] {
1544
    setup_host_hook $host_board;
1545
} else {
1546
    set hb [get_local_hostname];
1547
    if { $hb != "" } {
1548
        setup_host_hook $hb;
1549
    }
1550
}
1551
 
1552
#
1553
# main test execution loop
1554
#
1555
 
1556
if [info exists errorInfo] {
1557
    unset errorInfo
1558
}
1559
# make sure we have only single path delimiters
1560
regsub -all "\(\[^/\]\)//*" $srcdir "\\1/" srcdir
1561
 
1562
if ![info exists target_list] {
1563
# Make sure there is at least one target machine. It's probably a Unix box,
1564
# but that's just a guess.
1565
    set target_list { "unix" }
1566
} else {
1567
    verbose "target list is $target_list"
1568
}
1569
 
1570
#
1571
# Iterate through the list of targets.
1572
#
1573
global current_target;
1574
 
1575
set target_list [process_target_variants $target_list];
1576
 
1577
set target_count [llength $target_list]
1578
 
1579
clone_output "Schedule of variations:"
1580
foreach current_target $target_list {
1581
    clone_output "    $current_target"
1582
}
1583
clone_output ""
1584
 
1585
 
1586
foreach current_target $target_list {
1587
    verbose "target is $current_target";
1588
    set current_target_name $current_target;
1589
    set tlist [split $current_target /];
1590
    set current_target [lindex $tlist 0];
1591
    set board_variant_list [lrange $tlist 1 end];
1592
 
1593
    # Set the counts for this target to 0.
1594
    reset_vars;
1595
    clone_output "Running target $current_target_name"
1596
 
1597
    setup_target_hook $current_target_name $current_target;
1598
 
1599
# If multiple passes requested, set them up.  Otherwise prepare just one.
1600
# The format of `MULTIPASS' is a list of elements containing
1601
# "{ name var1=value1 ... }" where `name' is a generic name for the pass and
1602
# currently has no other meaning.
1603
 
1604
    global env
1605
 
1606
    if { [info exists MULTIPASS] } {
1607
        set multipass $MULTIPASS
1608
    }
1609
    if { $multipass == "" } {
1610
        set multipass { "" }
1611
    }
1612
 
1613
# If PASS is specified, we want to run only the tests specified.
1614
# Its value should be a number or a list of numbers that specify
1615
# the passes that we want to run.
1616
    if [info exists PASS] {
1617
        set pass $PASS
1618
    } else {
1619
        set pass ""
1620
    }
1621
 
1622
    if {$pass != ""} {
1623
        set passes [list]
1624
        foreach p $pass {
1625
            foreach multipass_elem $multipass {
1626
                set multipass_name [lindex $multipass_elem 0]
1627
                if {$p == $multipass_name} {
1628
                    lappend passes $multipass_elem
1629
                    break;
1630
                }
1631
            }
1632
        }
1633
        set multipass $passes
1634
    }
1635
 
1636
    foreach pass $multipass {
1637
 
1638
        # multipass_name is set for `record_test' to use (see framework.exp).
1639
        if { [lindex $pass 0] != "" } {
1640
            set multipass_name [lindex $pass 0]
1641
            clone_output "Running pass `$multipass_name' ..."
1642
        } else {
1643
            set multipass_name ""
1644
        }
1645
        set restore ""
1646
        foreach varval [lrange $pass 1 end] {
1647
            set tmp [string first "=" $varval]
1648
            set var [string range $varval 0 [expr $tmp - 1]]
1649
            # Save previous value.
1650
            if [info exists $var] {
1651
                lappend restore "$var [list [eval concat \$$var]]"
1652
            } else {
1653
                lappend restore "$var"
1654
            }
1655
            # Handle "CFLAGS=$CFLAGS foo".
1656
            # FIXME: Do we need to `catch' this?
1657
            eval set $var \[string range \"$varval\" [expr $tmp + 1] end\]
1658
            verbose "$var is now [eval concat \$$var]"
1659
            unset tmp var
1660
        }
1661
 
1662
        # look for the top level testsuites. if $tool doesn't
1663
        # exist and there are no subdirectories in $srcdir, then
1664
        # we default to srcdir.
1665
        set test_top_dirs [lsort [getdirs -all ${srcdir} "${tool}*"]]
1666
        if { ${test_top_dirs} == "" } {
1667
            set test_top_dirs ${srcdir}
1668
        } else {
1669
            # JYG:
1670
            # DejaGNU's notion of test tree and test files is very
1671
            # general:
1672
            # given ${srcdir} and ${tool}, any subdirectory (at any
1673
            # level deep) with the "${tool}" prefix starts a test tree;
1674
            # given a test tree, any *.exp file underneath (at any
1675
            # level deep) is a test file.
1676
            #
1677
            # For test tree layouts with ${tool} prefix on
1678
            # both a parent and a child directory, we need to eliminate
1679
            # the child directory entry from test_top_dirs list.
1680
            # e.g. gdb.hp/gdb.base-hp/ would result in two entries
1681
            # in the list: gdb.hp, gdb.hp/gdb.base-hp.
1682
            # If the latter not eliminated, test files under
1683
            # gdb.hp/gdb.base-hp would be run twice (since test files
1684
            # are gathered from all sub-directories underneath a
1685
            # directory).
1686
            #
1687
            # Since ${tool} may be g++, etc. which could confuse
1688
            # regexp, we cannot do the simpler test:
1689
            #     ...
1690
            #     if [regexp "${srcdir}/.*${tool}.*/.*${tool}.*" ${dir}]
1691
            #     ...
1692
            # instead, we rely on the fact that test_top_dirs is
1693
            # a sorted list of entries, and any entry that contains
1694
            # the previous valid test top dir entry in its own pathname
1695
            # must be excluded.
1696
 
1697
            set temp_top_dirs ""
1698
            set prev_dir ""
1699
            foreach dir "${test_top_dirs}" {
1700
                if { [string length ${prev_dir}] == 0 ||
1701
                     [string first "${prev_dir}/" ${dir}] == -1} {
1702
                    # the first top dir entry, or an entry that
1703
                    # does not share the previous entry's entire
1704
                    # pathname, record it as a valid top dir entry.
1705
                    #
1706
                    lappend temp_top_dirs ${dir}
1707
                    set prev_dir ${dir}
1708
                }
1709
            }
1710
            set test_top_dirs ${temp_top_dirs}
1711
        }
1712
        verbose "Top level testsuite dirs are ${test_top_dirs}" 2
1713
        set testlist "";
1714
        if [info exists all_runtests] {
1715
            foreach x [array names all_runtests] {
1716
                verbose "trying to glob ${srcdir}/${x}" 2
1717
                set s [glob -nocomplain ${srcdir}/$x];
1718
                if { $s != "" } {
1719
                    set testlist [concat $testlist $s];
1720
                }
1721
            }
1722
        }
1723
        #
1724
        # If we have a list of tests, run all of them.
1725
        #
1726
        if { $testlist != "" } {
1727
            foreach test_name $testlist {
1728
                if { ${ignoretests} != "" } {
1729
                    if { 0 <= [lsearch ${ignoretests} [file tail ${test_name}]]} {
1730
                        continue
1731
                    }
1732
                }
1733
 
1734
                # set subdir to the tail of the dirname after $srcdir,
1735
                # for the driver files that want it.  XXX this is silly.
1736
                # drivers should get a single var, not "$srcdir/$subdir"
1737
                set subdir [file dirname $test_name]
1738
                set p [expr [string length $srcdir]-1]
1739
                while {0 < $p && [string index $srcdir $p] == "/"} {
1740
                    incr p -1
1741
                }
1742
                if {[string range $subdir 0 $p] == $srcdir} {
1743
                    set subdir [string range $subdir [expr $p+1] end];
1744
                    regsub "^/" $subdir "" subdir
1745
                }
1746
 
1747
                # XXX not the right thing to do.
1748
                set runtests [list [file tail $test_name] ""]
1749
 
1750
                runtest $test_name;
1751
            }
1752
        } else {
1753
            #
1754
            # Go digging for tests.
1755
            #
1756
            foreach dir "${test_top_dirs}" {
1757
                if { ${dir} != ${srcdir} } {
1758
                    # Ignore this directory if is a directory to be
1759
                    # ignored.
1760
                    if {[info exists ignoredirs] && $ignoredirs != ""} {
1761
                        set found 0
1762
                        foreach directory $ignoredirs {
1763
                            if [string match "*${directory}*" $dir] {
1764
                                set found 1
1765
                                break
1766
                            }
1767
                        }
1768
                        if {$found} {
1769
                            continue
1770
                        }
1771
                    }
1772
 
1773
                    # Run the test if dir_to_run was specified as a
1774
                    # value (for example in MULTIPASS) and the test
1775
                    # directory matches that directory.
1776
                    if {[info exists dir_to_run] && $dir_to_run != ""} {
1777
                        # JYG: dir_to_run might be a space delimited list
1778
                        # of directories.  Look for match on each item.
1779
                        set found 0
1780
                        foreach directory $dir_to_run {
1781
                            if [string match "*${directory}*" $dir] {
1782
                                set found 1
1783
                                break
1784
                            }
1785
                        }
1786
                        if {!$found} {
1787
                            continue
1788
                        }
1789
                    }
1790
 
1791
                    # Run the test if cmdline_dir_to_run was specified
1792
                    # by the user using --directory and the test
1793
                    # directory matches that directory
1794
                    if {[info exists cmdline_dir_to_run] \
1795
                            && $cmdline_dir_to_run != ""} {
1796
                        # JYG: cmdline_dir_to_run might be a space delimited
1797
                        # list of directories.  Look for match on each item.
1798
                        set found 0
1799
                        foreach directory $cmdline_dir_to_run {
1800
                            if [string match "*${directory}*" $dir] {
1801
                                set found 1
1802
                                break
1803
                            }
1804
                        }
1805
                        if {!$found} {
1806
                            continue
1807
                        }
1808
                    }
1809
 
1810
                    foreach test_name [lsort [find ${dir} *.exp]] {
1811
                        if { ${test_name} == "" } {
1812
                            continue
1813
                        }
1814
                        # Ignore this one if asked to.
1815
                        if { ${ignoretests} != "" } {
1816
                            if { 0 <= [lsearch ${ignoretests} [file tail ${test_name}]]} {
1817
                                continue
1818
                            }
1819
                        }
1820
 
1821
                        # Get the path after the $srcdir so we know
1822
                        # the subdir we're in.
1823
                        set subdir [file dirname $test_name]
1824
                        # We used to do
1825
                        # regsub $srcdir [file dirname $test_name] "" subdir
1826
                        # but what if [file dirname $test_name] contains regexp
1827
                        # characters? We lose. Instead...
1828
                        set first [string first $srcdir $subdir]
1829
                        if { $first >= 0 } {
1830
                            set first [expr $first + [string length $srcdir]];
1831
                            set subdir [string range $subdir $first end];
1832
                            regsub "^/" "$subdir" "" subdir;
1833
                        }
1834
                        if { "$srcdir" == "$subdir" || "$srcdir" == "$subdir/" } {
1835
                            set subdir ""
1836
                        }
1837
                        # Check to see if the range of tests is limited,
1838
                        # set `runtests' to a list of two elements: the script name
1839
                        # and any arguments ("" if none).
1840
                        if [info exists all_runtests] {
1841
                            verbose "searching for $test_name in [array names all_runtests]"
1842
                            if { 0 > [lsearch [array names all_runtests] [file tail $test_name]]} {
1843
                                if { 0 > [lsearch [array names all_runtests] $test_name] } {
1844
                                    continue
1845
                                }
1846
                            }
1847
                            set runtests [list [file tail $test_name] $all_runtests([file tail $test_name])]
1848
                        } else {
1849
                            set runtests [list [file tail $test_name] ""]
1850
                        }
1851
                        runtest $test_name;
1852
                    }
1853
                }
1854
            }
1855
            # Restore the variables set by this pass.
1856
            foreach varval $restore {
1857
                if { [llength $varval] > 1 } {
1858
                    verbose "Restoring [lindex $varval 0] to [lindex $varval 1]" 4;
1859
                    set [lindex $varval 0] [lindex $varval 1];
1860
                } else {
1861
                    verbose "Restoring [lindex $varval 0] to `unset'" 4;
1862
                    unset [lindex $varval 0];
1863
                }
1864
            }
1865
        }
1866
    }
1867
    cleanup_target_hook $current_target;
1868
    if { $target_count > 1 } {
1869
        log_summary;
1870
    }
1871
}
1872
 
1873
log_and_exit;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.