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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [host/] [infra/] [hosttest.exp] - Blame information for rev 790

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
#===============================================================================
2
#
3
#    hosttest.exp
4
#
5
#    Support for host-side testing
6
#
7
#===============================================================================
8
# ####ECOSHOSTGPLCOPYRIGHTBEGIN####
9
# -------------------------------------------
10
# This file is part of the eCos host tools.
11
# Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
12
#
13
# This program is free software; you can redistribute it and/or modify
14
# it under the terms of the GNU General Public License as published by
15
# the Free Software Foundation; either version 2 or (at your option) any
16
# later version.
17
#
18
# This program is distributed in the hope that it will be useful, but
19
# WITHOUT ANY WARRANTY; without even the implied warranty of
20
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21
# General Public License for more details.
22
#
23
# You should have received a copy of the GNU General Public License
24
# along with this program; if not, write to the
25
# Free Software Foundation, Inc., 51 Franklin Street,
26
# Fifth Floor, Boston, MA  02110-1301, USA.
27
# -------------------------------------------
28
# ####ECOSHOSTGPLCOPYRIGHTEND####
29
#===============================================================================
30
######DESCRIPTIONBEGIN####
31
#
32
# Author(s):    bartv
33
# Contributors: bartv
34
# Date:         1998-11-25
35
# Note:         Arguably this should be a loadable package
36
#
37
#####DESCRIPTIONEND####
38
#===============================================================================
39
#
40
 
41
# ----------------------------------------------------------------------------
42
# This script gets loaded by host-side DejaGnu test harnesses to provide
43
# various utilities for testing eCos host applications. It lives in the
44
# host-side infrastructure directory and gets installed in
45
# $(PREFIX)/share/dejagnu.
46
#
47
# The script can assume that a number of globals from the site.exp
48
# file have been read in. These include:
49
#     tool           - name of the tool (i.e. the package)
50
#     srcdir         - location of the source directory
51
#     objdir         - location of the build tree
52
#     host_alias     - config triplet
53
#     host_triplet   - ditto
54
#
55
# The generated Makefile has some additional information that is useful.
56
#     CC             - name of the C compiler that is used
57
#     CXX            - name of the C++ compiler
58
#     prefix         - where everything gets installed
59
#     OBJEXT         - either o or obj
60
#     EXEEXT         - either nothing or .exe
61
#     VERSION        - the version number
62
#     CFLAGS         - flags to use when compiling C code
63
#     CXXFLAGS       - flags to use when compiling C++ code
64
#
65
# Some additional variables should be present in any generated
66
# makefiles in the eCos tree.
67
#     INCLUDES       - header file search path
68
#     LIBS           - libraries, search paths, ...
69
#
70
# hosttest_initialize
71
#     Perform any initialization steps that are needed. Currently this
72
#     means reading in the Makefile from the top-level of the build tree
73
#     and figuring out the values of CC, CXX, and anything else that is
74
#     useful. Any errors should be reported via perror and then the
75
#     script should exit.
76
#
77
#     There is an optional argument, a list of additional variables which
78
#     should be present in the makefile and whose values are desired.
79
 
80
proc hosttest_initialize { { pkg_vars {} } } {
81
 
82
    # First check that this script is actually running inside DejaGnu
83
    if { [info exists ::objdir] == 0 } {
84
        puts "Variable ::objdir is not defined, is this script really running inside DejaGnu?"
85
        exit 1
86
    }
87
 
88
    # The information is stored in an array hosttest_data. Make sure this
89
    # array exists.
90
    array set ::hosttest_data {}
91
 
92
    # Now clear out any entries in the array
93
    foreach entry [array names ::hosttest_data] {
94
        unset ::hosttest_data($entry)
95
    }
96
 
97
    # Now read in the build tree's Makefile (and not the testsuite's Makefile)
98
    set filename [file join $::objdir .. Makefile]
99
    if { [file exists $filename] == 0 } {
100
        perror "Initialization error: the build tree's Makefile $filename does not exist."
101
        exit 1
102
    }
103
    set status [ catch {
104
        set fd [open $filename r]
105
        set contents [read $fd]
106
        close $fd
107
    } message]
108
    if { $status != 0 } {
109
        perror "Error reading $filename.\n$message"
110
        exit 1
111
    }
112
 
113
    # The data is available. Search it for each of the variables of
114
    # interest. Some variables are optional and are given default
115
    # values.
116
    set ::hosttest_data(CFLAGS) ""
117
    set ::hosttest_data(CXXFLAGS) ""
118
 
119
    set lines [split $contents "\n"]
120
 
121
    foreach var [concat { CC CXX prefix OBJEXT EXEEXT VERSION CFLAGS CXXFLAGS INCLUDES LIBS } $pkg_vars] {
122
 
123
        set pattern "^$var\[ \t\]*:?=\[ \t\]* (.*)\$"
124
        set dummy ""
125
        set match ""
126
 
127
        foreach line $lines {
128
            if { [regexp -- $pattern $line dummy match] == 1 } {
129
                set ::hosttest_data($var) $match
130
                break
131
            }
132
        }
133
        if { [info exists ::hosttest_data($var)] == 0 } {
134
            perror "Variable $var is not defined in $filename"
135
            exit 1
136
        }
137
    }
138
 
139
    # If compiling with VC++ remove any cygwin-isms from the prefix
140
    if { [string match "cl*" $::hosttest_data(CC)] } {
141
        set status [catch "exec cygpath -w $::hosttest_data(prefix)" message]
142
        if { $status == 0 } {
143
            regsub -all -- {\\} $message {/} ::hosttest_data(prefix)
144
        } else {
145
            perror "Converting cygwin pathname $::hosttest_data(prefix)\n$message"
146
            exit 1
147
        }
148
    }
149
}
150
 
151
 
152
# ----------------------------------------------------------------------------
153
# hosttest_extract_version
154
#     Assuming there has been a call to initialize, the required information
155
#     should be available in the hosttest_data array. The initialize
156
#     function should have aborted if the data is not available.
157
 
158
proc hosttest_extract_version { } {
159
 
160
    if { [info exists ::hosttest_data(VERSION)] == 0 } {
161
        error "No version information - host testing has not been properly initialized."
162
    }
163
 
164
    if { [info exists ::objdir] == 0 } {
165
        error "Variable ::objdir is not defined, is this script really running inside DejaGnu?"
166
    }
167
    return $::hosttest_data(VERSION)
168
}
169
 
170
# ----------------------------------------------------------------------------
171
# hosttest_compile
172
#    compile and link one or more source files. The arguments are:
173
#    1) the name of the test case
174
#    2) a list of one or more source files that need to be compiled.
175
#       Both .c and .cxx files are supported, and the appropriate
176
#       compiler will be used. If this list is empty then the
177
#       code will look for a .c or a .cxx file which matches the
178
#       name of the test executable. Source files are assumed to
179
#       be relative to $::srcdir/$::subdir
180
#    3) a list (possibly empty) of directories that should be in the
181
#       include path. The build tree's directory is automatically in
182
#       the path, as is $(PREFIX)/include. Note that the build tree
183
#       is actually one level above objdir, on the assumption that
184
#       objdir is the testsuite subdirectory of the real objdir.
185
#    4) ditto for library search paths.
186
#    5) and a list of additional libraries that should be linked.
187
#
188
# Currently it is not possible to pass compiler flags since those
189
# might need translating between gcc and VC++. This may have to be
190
# resolved.
191
#
192
# Currently linking is not done via libtool. This may have to change.
193
#
194
# The various object files and the executable are placed in a directory
195
# testcase in the build tree, to avoid the risk of name clashes. This
196
# directory must not exist yet. There is a separate routine hosttest_clean
197
# which simply expunges the entire testcase directory.
198
#
199
# The output of a succesful compile or built is reported using
200
# verbose at level 2. Unsuccesful compiles or builts are reported using
201
# level 1.
202
 
203
proc hosttest_compile { name sources includes libdirs libs } {
204
 
205
    # Make sure that the testcase directory does not yet exist, then
206
    # create it. This guarantees a clean system and reasonable access
207
    # permissions. Each testcase invocation should involve a call to
208
    # the clean function.
209
    set dirname [file join $::objdir "testcase"]
210
    if { [file exists $dirname] != 0 } {
211
        # An empty directory is ok.
212
        if { [llength [glob -nocomplain -- [file join $dirname "*"]]] != 0 } {
213
            error "hosttest_compile: $dirname already exists"
214
        }
215
    }
216
 
217
    set status [catch { file mkdir $dirname } message]
218
    if { $status != 0 } {
219
        error "hosttest_compile: unable to create directory $dirname"
220
    }
221
 
222
    # The only argument that must be valid is the test name.
223
    if { $name == "" } {
224
        error "hosttest_compile: invalid test case name"
225
    }
226
 
227
    # If the list of sources is empty then look for a suitable
228
    # file in the appropriate directory.
229
    if { [llength $sources] == 0 } {
230
        set filename [file join $::srcdir $::subdir "${name}.c"]
231
        if { [file exists $filename] && [file isfile $filename] } {
232
            lappend sources [file tail $filename]
233
        } else {
234
            set filename [file join $::srcdir $::subdir "${name}.cxx"]
235
            if { [file exists $filename] && [file isfile $filename] } {
236
                lappend sources [file tail $filename]
237
            } else {
238
                error "hosttest_compile: no sources listed and unable to find ${name}.c or ${name}.cxx"
239
            }
240
        }
241
    }
242
 
243
    # For each source file, generate a compile command line and try to execute
244
    # it. The command line takes the form:
245
    #  (CC|CXX) -c (CFLAGS|CXXFLAGS) (INCDIRS) -o xxx yyy
246
    #
247
    # It is also useful to produce a list of the object files that need to
248
    # linked later on, and to work out which tool should be invoked for
249
    # linking.
250
    set object_files {}
251
    set has_cxx_files 0
252
 
253
    foreach source $sources {
254
        set commandline ""
255
        if { [file extension $source] == ".c" } {
256
            append commandline "$::hosttest_data(CC) -c $::hosttest_data(CFLAGS) "
257
        } elseif { [file extension $source] == ".cxx" } {
258
            set has_cxx_files 1
259
            append commandline "$::hosttest_data(CXX) -c $::hosttest_data(CXXFLAGS) "
260
        } else {
261
            error "hosttest_compile: files of type [file extension $source] ($source) are not yet supported."
262
        }
263
 
264
        # Include path: start with the source tree. Then the build tree.
265
        # Then the makefile's INCLUDES variable.
266
        # Then any additional directories specified explicitly by the
267
        # testcase. Finish off with the prefix. Note that header files
268
        # in the prefix directory may be out of date, depending on whether
269
        # or not there has been an install recently.
270
        append commandline "-I[file join [pwd] [file dirname $::srcdir]] "
271
        append commandline "-I[file join [pwd] [file dirname $::objdir]] "
272
        append commandline "$::hosttest_data(INCLUDES) "
273
        foreach dir $includes {
274
            append commandline "-I[file join [pwd] $dir] "
275
        }
276
        append commandline "-I[file join [pwd] $::hosttest_data(prefix) include] "
277
 
278
        # The output file must go into the testcase directory and have the right suffix
279
        set objfile "[file root [file tail $source]].$::hosttest_data(OBJEXT)"
280
        lappend object_files $objfile
281
        if { [string match "cl*" $::hosttest_data(CC)] } {
282
            append commandline "-Fo[file join $::objdir testcase $objfile] "
283
        } else {
284
            append commandline "-o [file join $::objdir testcase $objfile] "
285
        }
286
 
287
        # Finally provide the source file.
288
        append commandline "[file join $::srcdir $::subdir $source]"
289
        verbose -log -- $commandline
290
 
291
        # Time to invoke the compiler.
292
        set status [catch { set result [eval exec -keepnewline -- $commandline] } message]
293
        if { $status == 0 } {
294
            # The compile succeeded and the output is in result. Report the
295
            # output.
296
            verbose -log -- $result
297
        } else {
298
            # The compile failed and the output is in message.
299
            verbose -log -- $message
300
            error "hosttest_compile: failed to compile $source"
301
        }
302
    }
303
 
304
    # At this stage all the source files have been compiled, a list of
305
    # object files has been constructed, and it is known whether or
306
    # not any of the sources were c++. Time to construct a new command
307
    # line.
308
    set commandline ""
309
    if { $has_cxx_files == 0 } {
310
        append commandline "$::hosttest_data(CC) $::hosttest_data(CFLAGS) "
311
    } else {
312
        append commandline "$::hosttest_data(CXX) $::hosttest_data(CXXFLAGS) "
313
    }
314
    set exename [file join $::objdir "testcase" "$name$::hosttest_data(EXEEXT)"]
315
 
316
    # List all of the object files
317
    foreach obj $object_files {
318
        append commandline "[file join $::objdir "testcase" $obj] "
319
    }
320
 
321
    # Now take care of libraries and search paths. This requires different
322
    # code for gcc and VC++.
323
 
324
    if { [string match "cl*" $::hosttest_data(CC)] } {
325
        append commandline "-Fe$exename "
326
 
327
        foreach lib $libs {
328
            append commandline "${lib}.lib "
329
        }
330
        append commandline "$::hosttest_data(LIBS) "
331
        append commandline "-libpath=[file join [pwd] [file dirname $::objdir]] "
332
        foreach dir $libdirs {
333
            append commandline "-libpath=[file join [pwd] $dir] "
334
        }
335
        append commandline "-libpath=[file join [pwd] $::hosttest_data(prefix) lib] "
336
    } else {
337
        append commandline "-o $exename "
338
        append commandline "-L[file join [pwd] [file dirname $::objdir]] "
339
        foreach dir $libdirs {
340
            append commandline "-L[file join [pwd] $dir] "
341
        }
342
        append commandline "-L[file join [pwd] $::hosttest_data(prefix) lib] "
343
        foreach lib $libs {
344
            append commandline "-l$lib "
345
        }
346
        append commandline "$::hosttest_data(LIBS) "
347
    }
348
 
349
    # We have a command line, go for it.
350
    verbose -log -- $commandline
351
    set status [catch { set result [eval exec -keepnewline -- $commandline] } message]
352
    if { $status == 0 } {
353
        # The link has succeeded, we have an executable.
354
        verbose -log -- $result
355
    } else {
356
        # The link failed and the output is in message.
357
        # Report things are per compilation failures
358
        verbose -log -- $message
359
        error "hosttest_compile: failed to link $exename"
360
    }
361
 
362
    # There should be a test executable.
363
}
364
 
365
# ----------------------------------------------------------------------------
366
# hosttest_clean
367
#    Clean up a testcase directory.
368
 
369
proc hosttest_clean { } {
370
 
371
    set dirname [file join $::objdir "testcase"]
372
    if { [file exists $dirname] == 0 } {
373
 
374
        # Something must have gone seriously wrong during the build phase,
375
        # there is nothing there.
376
        return
377
    }
378
 
379
    if { [file isdirectory $dirname] == 0 } {
380
        error "hosttest_clean: $dirname should be a directory"
381
    }
382
 
383
    foreach entry [glob -nocomplain -- [file join $dirname "*"]] {
384
        set filename [file join $dirname $entry]
385
        if { [file isfile $filename] == 0 } {
386
            error "hosttest_clean: $filename is not a file"
387
        }
388
        set status [catch { file delete -force -- $filename } message]
389
        if { $status != 0 } {
390
            error "hosttest_clean: unable to delete $filename, $message"
391
        }
392
    }
393
    set status [catch { file delete -force -- $dirname } message]
394
    if { $status != 0 } {
395
        error "hosttest_clean: unable to delete directory $dirname, $message"
396
    }
397
}
398
 
399
# ----------------------------------------------------------------------------
400
# Run a test executable, returning the status code and the output.
401
# The results are returned in variables. It is assumed that some test cases
402
# will fail, so raising an exception is appropriate only if something
403
# has gone wrong at the test harness level. The argument list
404
# should be the name of the test case (from which the executable file name
405
# can be derived) and a list of arguments.
406
 
407
proc hosttest_run { result_arg output_arg test args } {
408
 
409
    upvar $result_arg result
410
    upvar $output_arg output
411
 
412
    # Figure out the filename corresponding to the test and make
413
    # sure it exists.
414
    set filename [file join $::objdir "testcase" $test]
415
    append filename $::hosttest_data(EXEEXT)
416
    if { ([file exists $filename] == 0) || ([file isfile $filename] == 0) } {
417
        error "hosttest_run: testcase file $filename does not exist"
418
    }
419
 
420
    # There is no need to worry about interacting with the program,
421
    # just exec it. It is a good idea to do this in the testcase directory,
422
    # so that any core dumps get cleaned up as well.
423
    set current_dir [pwd]
424
    set status [ catch { cd [file join $::objdir "testcase"] } message ]
425
    if { $status != 0 } {
426
        error "unable to change directory to [file join $::objdir testcase]\n$message"
427
    }
428
 
429
    verbose -log -- $filename $args
430
    set status [ catch { set result [eval exec -keepnewline -- $filename $args] } output]
431
    if { $status == 0 } {
432
        # The command has succeeded. The exit code is 0 and the output
433
        # was returned by the exec.
434
        set output $result
435
        set result 0
436
    } else {
437
        # The command has failed. The exit code is 1 and the output is
438
        # already in the right place.
439
        verbose -log -- $output
440
        set result 1
441
    }
442
    set status [catch { cd $current_dir } message]
443
    if { $status != 0 } {
444
        error "unable to change directory back to $current_dir"
445
    }
446
}
447
 
448
# ----------------------------------------------------------------------------
449
# Given some test output, look through it for pass and fail messages.
450
# These should result in appropriate DejaGnu pass and fail calls.
451
# In addition, if the program exited with a non-zero status code but
452
# did not report any failures then a special failure is reported.
453
 
454
proc hosttest_handle_output { name result output } {
455
 
456
    set passes 0
457
    set fails  0
458
 
459
    foreach line [split $output "\n"] {
460
 
461
        # The output should be of one of the following forms:
462
        #    PASS:
463
        #    FAIL: Line: xx File: xx
464
        #    Whatever
465
        #
466
        # PASS and FAIL messages will be reported via DejaGnu pass and fail
467
        # calls. Everything else gets passed to verbose, so the user gets
468
        # to choose how much information gets reported.
469
 
470
        set dummy   ""
471
        set match1  ""
472
        set match2  ""
473
 
474
        if { [regexp -- {^PASS:<(.*)>.*$} $line dummy match1] == 1 } {
475
            pass $match1
476
            incr passes
477
        } elseif { [regexp -- {^FAIL:<(.*)>(.*)$} $line dummy match1 match2] == 1 } {
478
            fail "$match1 $match2"
479
            incr fails
480
        } else {
481
            verbose $line
482
        }
483
    }
484
 
485
    if { ($result != 0) && ($fails == 0) } {
486
        fail "program terminated with non-zero exit code but did not report any failures"
487
    } elseif { ($passes == 0) && ($fails == 0) } {
488
        unresolved "test case $name did not report any passes or failures"
489
    }
490
}
491
 
492
# ----------------------------------------------------------------------------
493
# hosttest_run_test_with_filter
494
#    This routines combines the compile, run and clean operations,
495
#    plus it invokes a supplied callback to filter the output. The
496
#    callback is passed three arguments: the test name, the exit code,
497
#    and all of the program output.
498
 
499
proc hosttest_run_test_with_filter { name filter sources incdirs libdirs libs args } {
500
 
501
    set result 0
502
    set output ""
503
 
504
    set status [ catch { hosttest_compile $name $sources $incdirs $libdirs $libs } message]
505
    if { $status != 0 } {
506
        fail "unable to compile test case $name, $message"
507
        hosttest_clean
508
        return
509
    }
510
    set status [ catch { hosttest_run result output $name $args } message]
511
    if { $status != 0 } {
512
        fail "unable to run test case $name, $message"
513
        hosttest_clean
514
        return
515
    }
516
    set status [ catch { $filter $name $result $output } message]
517
    if { $status != 0 } {
518
        fail "unable to parse output from test case $name"
519
        hosttest_clean
520
        return
521
    }
522
 
523
    hosttest_clean
524
}
525
 
526
# ----------------------------------------------------------------------------
527
# hosttest_run_simple_test
528
#    This routine combines the compile, run, output, and clean operations.
529
#    The arguments are the same as for compilation, plus an additional
530
#    list for run-time parameters to the test case.
531
 
532
proc hosttest_run_simple_test { name sources incdirs libdirs libs args } {
533
 
534
 
535
    set result 0
536
    set output ""
537
 
538
    set status [ catch { hosttest_compile $name $sources $incdirs $libdirs $libs } message]
539
    if { $status != 0 } {
540
        fail "unable to compile test case $name, $message"
541
        hosttest_clean
542
        return
543
    }
544
    set status [ catch { hosttest_run result output $name $args } message]
545
    if { $status != 0 } {
546
        fail "unable to run test case $name, $message"
547
        hosttest_clean
548
        return
549
    }
550
    set status [ catch { hosttest_handle_output $name $result $output } message]
551
    if { $status != 0 } {
552
        fail "unable to parse output from test case $name"
553
        hosttest_clean
554
        return
555
    }
556
 
557
    hosttest_clean
558
}
559
 
560
# ----------------------------------------------------------------------------
561
# Filename translation. A particular file has been created and must now
562
# be accessed from Tcl.
563
#
564
# Under Unix everything just works.
565
#
566
# Under Windows, well there is cygwin and there is the Windows world.
567
# A file may have come from either. cygtclsh80 and hence DejaGnu is not
568
# fully integrated with cygwin, for example it does not know about
569
# cygwin mount points. There are also complications because of
570
# volume-relative filenames.
571
#
572
# The code here tries a number of different ways of finding a file which
573
# matches the name. It is possible that the result is not actually what
574
# was intended, but hopefully this case will never arise.
575
 
576
proc hosttest_translate_existing_filename { name } {
577
 
578
    if { $::tcl_platform(platform) == "unix" } {
579
        # The file should exist. It is worth checking just in case.
580
        if { [file exists $name] == 0 } {
581
            return ""
582
        } else {
583
            return $name
584
        }
585
    }
586
 
587
    if { $::tcl_platform(platform) != "windows" } {
588
        perror "The testing framework does not know about platform $::tcl_platform(platform)"
589
        return ""
590
    }
591
 
592
    # Always get rid of any backslashes, they just cause trouble
593
    regsub -all -- {\\} $name {/} name
594
 
595
    # If the name is already valid, great.
596
    if { [file exists $name] } {
597
        return $name
598
    }
599
 
600
    # OK, try to use cygwin's cygpath utility to convert it.
601
    set status [catch "exec cygpath -w $name" message]
602
    if { $status == 0 } {
603
        set cygwin_name ""
604
        regsub -all -- {\\} $message {/} cygwin_name
605
        if { [file exists $cygwin_name] } {
606
            return $cygwin_name
607
        }
608
    }
609
 
610
    # Is the name volumerelative? If so work out the current volume
611
    # from the current directory and prepend this.
612
    if { [file pathtype $name] == "volumerelative" } {
613
        append fullname [string range [pwd] 0 1] $name
614
        if { [file exists $fullname] } {
615
            return $fullname
616
        }
617
    }
618
 
619
    # There are other possibilities, e.g. d:xxx indicating a file
620
    # relative to the current directory on drive d:. For now such
621
    # Lovecraftian abominations are ignored.
622
    return ""
623
}
624
 
625
# ----------------------------------------------------------------------------
626
# Support for assertion dumps. The infrastructure allows other subsystems
627
# to add their own callbacks which get invoked during a panic and which
628
# can write additional output to the dump file. For example it would be
629
# possible to output full details of the current configuration. These
630
# routines make it easier to write test cases for such callbacks.
631
#
632
# hosttest_assert_check(result output)
633
#     Make sure that the test case really triggered an assertion.
634
#
635
# hosttest_assert_read_dump(output)
636
#     Identify the temporary file used for the dump, read it in, delete
637
#     it (no point in leaving such temporaries lying around when running
638
#     testcases) and return the contents of the file.
639
#
640
# hosttest_assert_extract_callback(dump title)
641
#     Given a dump output as returned by read_dump, look for a section
642
#     generated by a callback with the given title. Return the contents
643
#     of the callback.
644
 
645
proc hosttest_assert_check { result output } {
646
 
647
    if { $result == 0 } {
648
        return 0
649
    }
650
 
651
    foreach line [split $output "\n"] {
652
        if { [string match "Assertion failure*" $line] } {
653
            return 1
654
        }
655
    }
656
    return 0
657
}
658
 
659
# This routine assumes that assert_check has already been called.
660
proc hosttest_assert_read_dump { output } {
661
 
662
    foreach line [split $output "\n"] {
663
        set dummy ""
664
        set match ""
665
 
666
        if { [regexp -nocase -- {^writing additional output to (.*)$} $line dummy match] } {
667
 
668
            # The filename is in match, but it may not be directly accessible.
669
            set filename [hosttest_translate_existing_filename $match]
670
            if { $filename == "" } {
671
                return ""
672
            }
673
            set status [ catch {
674
                set fd   [open $filename r]
675
                set data [read $fd]
676
                close $fd
677
                file delete $filename
678
            } message]
679
            if { $status != 0 } {
680
                unresolved "Unable to process assertion dump file $filename"
681
                unresolved "File $filename may have to be deleted manually"
682
                return ""
683
            }
684
            return $data
685
        }
686
    }
687
    return ""
688
}
689
 
690
# Look for the appropriate markers. Also clean up blank lines
691
# at the start and end.
692
proc hosttest_assert_extract_callback { dump title } {
693
 
694
    set lines [split $dump "\n"]
695
    set result ""
696
 
697
    while { [llength $lines] > 0 } {
698
        set line  [lindex $lines 0]
699
        set lines [lreplace $lines 0 0]
700
 
701
        if { [regexp -nocase -- "^\# \{\{\{.*${title}.*\$" $line] } {
702
 
703
            # Skip any blank lines at the start
704
            while { [llength $lines] > 0 } {
705
                set line  [lindex $lines 0]
706
                if { [regexp -- {^ *$} $line] == 0} {
707
                    break
708
                }
709
                set lines [lreplace $lines 0 0]
710
            }
711
 
712
            # Now add any lines until the close marker.
713
            # Nested folds are not supported yet.
714
            while { [llength $lines] > 0 } {
715
                set line  [lindex $lines 0]
716
                set lines [lreplace $lines 0 0]
717
                if { [regexp -nocase -- {^\# \}\}\}.*$} $line] } {
718
                    break
719
                }
720
                append result $line "\n"
721
            }
722
 
723
            return $result
724
        }
725
    }
726
 
727
    return ""
728
}
729
 
730
 
731
 
732
 

powered by: WebSVN 2.1.0

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