os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/tools/regexpTestLib.tcl
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
# regexpTestLib.tcl --
sl@0
     2
#
sl@0
     3
# This file contains tcl procedures used by spencer2testregexp.tcl and
sl@0
     4
# spencer2regexp.tcl, which are programs written to convert Henry
sl@0
     5
# Spencer's test suite to tcl test files.
sl@0
     6
#
sl@0
     7
# Copyright (c) 1996 by Sun Microsystems, Inc.
sl@0
     8
#
sl@0
     9
# SCCS: @(#) regexpTestLib.tcl 1.4 98/01/22 14:48:34
sl@0
    10
# 
sl@0
    11
sl@0
    12
proc readInputFile {} {
sl@0
    13
    global inFileName
sl@0
    14
    global lineArray
sl@0
    15
sl@0
    16
    set fileId [open $inFileName r]
sl@0
    17
sl@0
    18
    set i 0
sl@0
    19
    while {[gets $fileId line] >= 0} {
sl@0
    20
sl@0
    21
	set len [string length $line]
sl@0
    22
sl@0
    23
	if {($len > 0) && ([string index $line [expr $len - 1]] == "\\")} {
sl@0
    24
	    if {[info exists lineArray(c$i)] == 0} {
sl@0
    25
		set lineArray(c$i) 1
sl@0
    26
	    } else {
sl@0
    27
		incr lineArray(c$i)
sl@0
    28
	    }
sl@0
    29
	    set line [string range $line 0 [expr $len - 2]]
sl@0
    30
	    append lineArray($i) $line
sl@0
    31
	    continue
sl@0
    32
	}
sl@0
    33
	if {[info exists lineArray(c$i)] == 0} {
sl@0
    34
	    set lineArray(c$i) 1
sl@0
    35
	} else {
sl@0
    36
	    incr lineArray(c$i)
sl@0
    37
	}
sl@0
    38
	append lineArray($i) $line
sl@0
    39
	incr i
sl@0
    40
    }
sl@0
    41
sl@0
    42
    close $fileId
sl@0
    43
    return $i
sl@0
    44
}
sl@0
    45
sl@0
    46
#
sl@0
    47
# strings with embedded @'s are truncated
sl@0
    48
# unpreceeded @'s are replaced by {}
sl@0
    49
# 
sl@0
    50
proc removeAts {ls} {
sl@0
    51
    set len [llength $ls]
sl@0
    52
    set newLs {}
sl@0
    53
    foreach item $ls {
sl@0
    54
	regsub @.* $item "" newItem
sl@0
    55
	lappend newLs $newItem
sl@0
    56
    }
sl@0
    57
    return $newLs
sl@0
    58
}
sl@0
    59
sl@0
    60
proc convertErrCode {code} {
sl@0
    61
sl@0
    62
    set errMsg "couldn't compile regular expression pattern:"
sl@0
    63
sl@0
    64
    if {[string compare $code "INVARG"] == 0} {
sl@0
    65
	return "$errMsg invalid argument to regex routine"
sl@0
    66
    } elseif {[string compare $code "BADRPT"] == 0} {
sl@0
    67
	return "$errMsg ?+* follows nothing"
sl@0
    68
    } elseif {[string compare $code "BADBR"] == 0} {
sl@0
    69
	return "$errMsg invalid repetition count(s)"
sl@0
    70
    } elseif {[string compare $code "BADOPT"] == 0} {
sl@0
    71
	return "$errMsg invalid embedded option"
sl@0
    72
    } elseif {[string compare $code "EPAREN"] == 0} {
sl@0
    73
	return "$errMsg unmatched ()"
sl@0
    74
    } elseif {[string compare $code "EBRACE"] == 0} {
sl@0
    75
	return "$errMsg unmatched {}"
sl@0
    76
    } elseif {[string compare $code "EBRACK"] == 0} {
sl@0
    77
	return "$errMsg unmatched \[\]"
sl@0
    78
    } elseif {[string compare $code "ERANGE"] == 0} {
sl@0
    79
	return "$errMsg invalid character range"
sl@0
    80
    } elseif {[string compare $code "ECTYPE"] == 0} {
sl@0
    81
	return "$errMsg invalid character class"
sl@0
    82
    } elseif {[string compare $code "ECOLLATE"] == 0} {
sl@0
    83
	return "$errMsg invalid collating element"
sl@0
    84
    } elseif {[string compare $code "EESCAPE"] == 0} {
sl@0
    85
	return "$errMsg invalid escape sequence"
sl@0
    86
    } elseif {[string compare $code "BADPAT"] == 0} {
sl@0
    87
	return "$errMsg invalid regular expression"
sl@0
    88
    } elseif {[string compare $code "ESUBREG"] == 0} {
sl@0
    89
	return "$errMsg invalid backreference number"
sl@0
    90
    } elseif {[string compare $code "IMPOSS"] == 0} {
sl@0
    91
	return "$errMsg can never match"
sl@0
    92
    }
sl@0
    93
    return "$errMsg $code"
sl@0
    94
}
sl@0
    95
sl@0
    96
proc writeOutputFile {numLines fcn} {
sl@0
    97
    global outFileName
sl@0
    98
    global lineArray
sl@0
    99
sl@0
   100
    # open output file and write file header info to it. 
sl@0
   101
sl@0
   102
    set fileId [open $outFileName w]
sl@0
   103
sl@0
   104
    puts $fileId "# Commands covered:  $fcn"
sl@0
   105
    puts $fileId "#"
sl@0
   106
    puts $fileId "# This Tcl-generated file contains tests for the $fcn tcl command."
sl@0
   107
    puts $fileId "# Sourcing this file into Tcl runs the tests and generates output for"
sl@0
   108
    puts $fileId "# errors.  No output means no errors were found.  Setting VERBOSE to"
sl@0
   109
    puts $fileId "# -1 will run tests that are known to fail."
sl@0
   110
    puts $fileId "#"
sl@0
   111
    puts $fileId "# Copyright (c) 1998 Sun Microsystems, Inc."
sl@0
   112
    puts $fileId "#"
sl@0
   113
    puts $fileId "# See the file \"license.terms\" for information on usage and redistribution"
sl@0
   114
    puts $fileId "# of this file, and for a DISCLAIMER OF ALL WARRANTIES."
sl@0
   115
    puts $fileId "#"
sl@0
   116
    puts $fileId "\# SCCS: \%Z\% \%M\% \%I\% \%E\% \%U\%"
sl@0
   117
    puts $fileId "\nproc print \{arg\} \{puts \$arg\}\n"
sl@0
   118
    puts $fileId "if \{\[string compare test \[info procs test\]\] == 1\} \{"
sl@0
   119
    puts $fileId "    source defs ; set VERBOSE -1\n\}\n"
sl@0
   120
    puts $fileId "if \{\$VERBOSE != -1\} \{"
sl@0
   121
    puts $fileId "    proc print \{arg\} \{\}\n\}\n"
sl@0
   122
    puts $fileId "#"
sl@0
   123
    puts $fileId "# The remainder of this file is Tcl tests that have been"
sl@0
   124
    puts $fileId "# converted from Henry Spencer's regexp test suite."
sl@0
   125
    puts $fileId "#\n"
sl@0
   126
sl@0
   127
    set lineNum 0
sl@0
   128
    set srcLineNum 1
sl@0
   129
    while {$lineNum < $numLines} {
sl@0
   130
sl@0
   131
	set currentLine $lineArray($lineNum)
sl@0
   132
sl@0
   133
	# copy comment string to output file and continue
sl@0
   134
sl@0
   135
	if {[string index $currentLine 0] == "#"} {
sl@0
   136
	    puts $fileId $currentLine
sl@0
   137
	    incr srcLineNum $lineArray(c$lineNum)
sl@0
   138
	    incr lineNum
sl@0
   139
	    continue	    
sl@0
   140
	}
sl@0
   141
sl@0
   142
	set len [llength $currentLine]
sl@0
   143
sl@0
   144
	# copy empty string to output file and continue
sl@0
   145
sl@0
   146
	if {$len == 0} {
sl@0
   147
	    puts $fileId "\n"
sl@0
   148
	    incr srcLineNum $lineArray(c$lineNum)
sl@0
   149
	    incr lineNum
sl@0
   150
	    continue	    
sl@0
   151
	}
sl@0
   152
	if {($len < 3)} {
sl@0
   153
	    puts "warning: test is too short --\n\t$currentLine"
sl@0
   154
	    incr srcLineNum $lineArray(c$lineNum)
sl@0
   155
	    incr lineNum
sl@0
   156
	    continue
sl@0
   157
	}
sl@0
   158
sl@0
   159
	puts $fileId [convertTestLine $currentLine $len $lineNum $srcLineNum]
sl@0
   160
sl@0
   161
	incr srcLineNum $lineArray(c$lineNum)
sl@0
   162
	incr lineNum
sl@0
   163
    }
sl@0
   164
sl@0
   165
    close $fileId
sl@0
   166
}
sl@0
   167
sl@0
   168
proc convertTestLine {currentLine len lineNum srcLineNum} {
sl@0
   169
sl@0
   170
    regsub -all {(?b)\\} $currentLine {\\\\} currentLine
sl@0
   171
    set re [lindex $currentLine 0]
sl@0
   172
    set flags [lindex $currentLine 1]
sl@0
   173
    set str [lindex $currentLine 2]
sl@0
   174
sl@0
   175
    # based on flags, decide whether to skip the test
sl@0
   176
sl@0
   177
    if {[findSkipFlag $flags]} {
sl@0
   178
	regsub -all {\[|\]|\(|\)|\{|\}|\#} $currentLine {\&} line
sl@0
   179
	set msg "\# skipping char mapping test from line $srcLineNum\n"
sl@0
   180
	append msg "print \{... skip test from line $srcLineNum:  $line\}"
sl@0
   181
	return $msg
sl@0
   182
    }
sl@0
   183
sl@0
   184
    # perform mapping if '=' flag exists
sl@0
   185
sl@0
   186
    set noBraces 0
sl@0
   187
    if {[regexp {=|>} $flags] == 1} {
sl@0
   188
	regsub -all {_} $currentLine {\\ } currentLine
sl@0
   189
	regsub -all {A} $currentLine {\\007} currentLine
sl@0
   190
	regsub -all {B} $currentLine {\\b} currentLine
sl@0
   191
	regsub -all {E} $currentLine {\\033} currentLine
sl@0
   192
	regsub -all {F} $currentLine {\\f} currentLine
sl@0
   193
	regsub -all {N} $currentLine {\\n} currentLine
sl@0
   194
sl@0
   195
	# if and \r substitutions are made, do not wrap re, flags,
sl@0
   196
	# str, and result in braces
sl@0
   197
sl@0
   198
	set noBraces [regsub -all {R} $currentLine {\\\u000D} currentLine]
sl@0
   199
	regsub -all {T} $currentLine {\\t} currentLine
sl@0
   200
	regsub -all {V} $currentLine {\\v} currentLine
sl@0
   201
	if {[regexp {=} $flags] == 1} {
sl@0
   202
	    set re [lindex $currentLine 0]
sl@0
   203
	}
sl@0
   204
	set str [lindex $currentLine 2]
sl@0
   205
    }
sl@0
   206
    set flags [removeFlags $flags]
sl@0
   207
sl@0
   208
    # find the test result
sl@0
   209
sl@0
   210
    set numVars [expr $len - 3]
sl@0
   211
    set vars {}
sl@0
   212
    set vals {}
sl@0
   213
    set result 0
sl@0
   214
    set v 0
sl@0
   215
    
sl@0
   216
    if {[regsub {\*} "$flags" "" newFlags] == 1} {
sl@0
   217
	# an error is expected
sl@0
   218
	
sl@0
   219
	if {[string compare $str "EMPTY"] == 0} {
sl@0
   220
	    # empty regexp is not an error
sl@0
   221
	    # skip this test
sl@0
   222
	    
sl@0
   223
	    return "\# skipping the empty-re test from line $srcLineNum\n"
sl@0
   224
	}
sl@0
   225
	set flags $newFlags
sl@0
   226
	set result "\{1 \{[convertErrCode $str]\}\}"
sl@0
   227
    } elseif {$numVars > 0} {
sl@0
   228
	# at least 1 match is made
sl@0
   229
	
sl@0
   230
	if {[regexp {s} $flags] == 1} {
sl@0
   231
	    set result "\{0 1\}"
sl@0
   232
	} else {
sl@0
   233
	    while {$v < $numVars} {
sl@0
   234
		append vars " var($v)"
sl@0
   235
		append vals " \$var($v)"
sl@0
   236
		incr v
sl@0
   237
	    }
sl@0
   238
	    set tmp [removeAts [lrange $currentLine 3 $len]]
sl@0
   239
	    set result "\{0 \{1 $tmp\}\}"
sl@0
   240
	    if {$noBraces} {
sl@0
   241
		set result "\[subst $result\]"
sl@0
   242
	    }
sl@0
   243
	}
sl@0
   244
    } else {
sl@0
   245
	# no match is made
sl@0
   246
	
sl@0
   247
	set result "\{0 0\}"
sl@0
   248
    }
sl@0
   249
sl@0
   250
    # set up the test and write it to the output file
sl@0
   251
sl@0
   252
    set cmd [prepareCmd $flags $re $str $vars $noBraces]
sl@0
   253
    if {$cmd == -1} {
sl@0
   254
	return "\# skipping test with metasyntax from line $srcLineNum\n"	    
sl@0
   255
    }
sl@0
   256
sl@0
   257
    set test "test regexp-1.$srcLineNum \{converted from line $srcLineNum\} \{\n"
sl@0
   258
    append test "\tcatch {unset var}\n"
sl@0
   259
    append test "\tlist \[catch \{ \n"
sl@0
   260
    append test "\t\tset match \[$cmd\] \n"
sl@0
   261
    append test "\t\tlist \$match $vals \n"
sl@0
   262
    append test "\t\} msg\] \$msg \n"
sl@0
   263
    append test "\} $result \n"
sl@0
   264
    return $test
sl@0
   265
}
sl@0
   266