Annotation For lib/xvfs/xvfs.tcl

Origin for each line in lib/xvfs/xvfs.tcl from check-in f615eecc64:

47dcf5fc27 2019-05-01        rkeene: #! /usr/bin/env tclsh
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: namespace eval ::xvfs {}
0e8537c65f 2019-09-20        rkeene: namespace eval ::xvfs::callback {}
2b7fa3a8fa 2019-09-20        rkeene: 
2b7fa3a8fa 2019-09-20        rkeene: set ::xvfs::_xvfsDir [file dirname [info script]]
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: # Functions
0bdbe4333e 2019-09-20        rkeene: proc ::xvfs::_emitLine {line} {
12383d30b7 2019-09-20        rkeene: 	if {[info command ::minirivet::_emitOutput] ne ""} {
12383d30b7 2019-09-20        rkeene: 		::minirivet::_emitOutput "${line}\n"
12383d30b7 2019-09-20        rkeene: 	} else {
12383d30b7 2019-09-20        rkeene: 		puts $line
12383d30b7 2019-09-20        rkeene: 	}
0bdbe4333e 2019-09-20        rkeene: }
0bdbe4333e 2019-09-20        rkeene: 
47dcf5fc27 2019-05-01        rkeene: proc ::xvfs::printHelp {channel {errors ""}} {
47dcf5fc27 2019-05-01        rkeene: 	if {[llength $errors] != 0} {
47dcf5fc27 2019-05-01        rkeene: 		foreach error $errors {
702c74c153 2019-09-20        rkeene: 			puts $channel "error: $error"
47dcf5fc27 2019-05-01        rkeene: 		}
702c74c153 2019-09-20        rkeene: 		puts $channel ""
47dcf5fc27 2019-05-01        rkeene: 	}
702c74c153 2019-09-20        rkeene: 	puts $channel "Usage: dir2c \[--help\] \[--output <filename>\] --directory <rootDirectory> --name <fsName>"
47dcf5fc27 2019-05-01        rkeene: 	flush $channel
47dcf5fc27 2019-05-01        rkeene: }
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: proc ::xvfs::sanitizeCString {string} {
47dcf5fc27 2019-05-01        rkeene: 	set output [join [lmap char [split $string ""] {
47dcf5fc27 2019-05-01        rkeene: 		if {![regexp {[A-Za-z0-9./-]} $char]} {
47dcf5fc27 2019-05-01        rkeene: 			binary scan $char H* char
47dcf5fc27 2019-05-01        rkeene: 			set char "\\[format %03o 0x$char]"
47dcf5fc27 2019-05-01        rkeene: 		}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 		set char
47dcf5fc27 2019-05-01        rkeene: 	}] ""]
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 	return $output
47dcf5fc27 2019-05-01        rkeene: }
47dcf5fc27 2019-05-01        rkeene: 
32b55a907b 2019-05-02        rkeene: proc ::xvfs::sanitizeCStringList {list {prefix ""} {width 80}} {
32b55a907b 2019-05-02        rkeene: 	set lines [list]
32b55a907b 2019-05-02        rkeene: 	set row [list]
32b55a907b 2019-05-02        rkeene: 	foreach item $list {
32b55a907b 2019-05-02        rkeene: 		lappend row "\"[sanitizeCString $item]\""
32b55a907b 2019-05-02        rkeene: 		
32b55a907b 2019-05-02        rkeene: 		set rowString [join $row {, }]
32b55a907b 2019-05-02        rkeene: 		set rowString "${prefix}${rowString}"
32b55a907b 2019-05-02        rkeene: 		if {[string length $rowString] > $width} {
32b55a907b 2019-05-02        rkeene: 			set row [list]
d961175fd9 2019-09-20        rkeene: 			lappend lines "${rowString},"
32b55a907b 2019-05-02        rkeene: 			unset rowString
32b55a907b 2019-05-02        rkeene: 		}
32b55a907b 2019-05-02        rkeene: 	}
32b55a907b 2019-05-02        rkeene: 	if {[info exists rowString]} {
32b55a907b 2019-05-02        rkeene: 		lappend lines $rowString
32b55a907b 2019-05-02        rkeene: 	}
32b55a907b 2019-05-02        rkeene: 	
32b55a907b 2019-05-02        rkeene: 	return [join $lines "\n"]
32b55a907b 2019-05-02        rkeene: }
32b55a907b 2019-05-02        rkeene: 
47dcf5fc27 2019-05-01        rkeene: proc ::xvfs::binaryToCHex {binary {prefix ""} {width 10}} {
2176e9cacf 2019-09-18        rkeene: 	set binary [binary encode hex $binary]
47dcf5fc27 2019-05-01        rkeene: 	set output [list]
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 	set width [expr {$width * 2}]
47dcf5fc27 2019-05-01        rkeene: 	set stopAt [expr {$width - 1}]
47dcf5fc27 2019-05-01        rkeene: 
2176e9cacf 2019-09-18        rkeene: 	set offset 0
2176e9cacf 2019-09-18        rkeene: 	while 1 {
2176e9cacf 2019-09-18        rkeene: 		set row [string range $binary $offset [expr {$offset + $stopAt}]]
2176e9cacf 2019-09-18        rkeene: 		if {[string length $row] == 0} {
2176e9cacf 2019-09-18        rkeene: 			break
2176e9cacf 2019-09-18        rkeene: 		}
2176e9cacf 2019-09-18        rkeene: 		incr offset [string length $row]
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 		set rowOutput [list]
47dcf5fc27 2019-05-01        rkeene: 		while {$row ne ""} {
47dcf5fc27 2019-05-01        rkeene: 			set value [string range $row 0 1]
47dcf5fc27 2019-05-01        rkeene: 			set row [string range $row 2 end]
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 			lappend rowOutput "\\x$value"
47dcf5fc27 2019-05-01        rkeene: 		}
47dcf5fc27 2019-05-01        rkeene: 		set rowOutput [join $rowOutput {}]
47dcf5fc27 2019-05-01        rkeene: 		set rowOutput "${prefix}\"${rowOutput}\""
47dcf5fc27 2019-05-01        rkeene: 		lappend output $rowOutput
47dcf5fc27 2019-05-01        rkeene: 	}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 	if {[llength $output] == 0} {
47dcf5fc27 2019-05-01        rkeene: 		return "${prefix}\"\""
47dcf5fc27 2019-05-01        rkeene: 	}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 	set output [join $output "\n"]
47dcf5fc27 2019-05-01        rkeene: }
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: proc ::xvfs::processFile {fsName inputFile outputFile fileInfoDict} {
47dcf5fc27 2019-05-01        rkeene: 	array set fileInfo $fileInfoDict
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 	switch -exact -- $fileInfo(type) {
47dcf5fc27 2019-05-01        rkeene: 		"file" {
47dcf5fc27 2019-05-01        rkeene: 			set type "XVFS_FILE_TYPE_REG"
d8e00cd4a3 2019-09-20        rkeene: 			if {[info exists fileInfo(fileContents)]} {
d8e00cd4a3 2019-09-20        rkeene: 				set data $fileInfo(fileContents)
d8e00cd4a3 2019-09-20        rkeene: 			} else {
d8e00cd4a3 2019-09-20        rkeene: 				set fd [open $inputFile]
d8e00cd4a3 2019-09-20        rkeene: 				fconfigure $fd -encoding binary -translation binary -blocking true
d8e00cd4a3 2019-09-20        rkeene: 				set data [read $fd]
d8e00cd4a3 2019-09-20        rkeene: 				close $fd
d8e00cd4a3 2019-09-20        rkeene: 			}
47dcf5fc27 2019-05-01        rkeene: 			set size [string length $data]
47dcf5fc27 2019-05-01        rkeene: 			set data [string trimleft [binaryToCHex $data "\t\t\t"]]
47dcf5fc27 2019-05-01        rkeene: 		}
47dcf5fc27 2019-05-01        rkeene: 		"directory" {
47dcf5fc27 2019-05-01        rkeene: 			set type "XVFS_FILE_TYPE_DIR"
32b55a907b 2019-05-02        rkeene: 			set children $fileInfo(children)
32b55a907b 2019-05-02        rkeene: 			set size [llength $children]
32b55a907b 2019-05-02        rkeene: 			
32b55a907b 2019-05-02        rkeene: 			if {$size == 0} {
32b55a907b 2019-05-02        rkeene: 				set children "NULL"
32b55a907b 2019-05-02        rkeene: 			} else {
32b55a907b 2019-05-02        rkeene: 				set children [string trimleft [sanitizeCStringList $children "\t\t\t"]]
32b55a907b 2019-05-02        rkeene: 				# This initializes it using a C99 compound literal, C99 is required
32b55a907b 2019-05-02        rkeene: 				set children "(const char *\[\]) \{$children\}"
32b55a907b 2019-05-02        rkeene: 			}
47dcf5fc27 2019-05-01        rkeene: 		}
47dcf5fc27 2019-05-01        rkeene: 		default {
47dcf5fc27 2019-05-01        rkeene: 			return -code error "Unable to process $inputFile, unknown type: $fileInfo(type)"
47dcf5fc27 2019-05-01        rkeene: 		}
47dcf5fc27 2019-05-01        rkeene: 	}
47dcf5fc27 2019-05-01        rkeene: 
0bdbe4333e 2019-09-20        rkeene: 	::xvfs::_emitLine "\t\{"
0bdbe4333e 2019-09-20        rkeene: 	::xvfs::_emitLine "\t\t.name = \"[sanitizeCString $outputFile]\","
0bdbe4333e 2019-09-20        rkeene: 	::xvfs::_emitLine "\t\t.type = $type,"
0bdbe4333e 2019-09-20        rkeene: 	::xvfs::_emitLine "\t\t.size = $size,"
32b55a907b 2019-05-02        rkeene: 	switch -exact -- $fileInfo(type) {
32b55a907b 2019-05-02        rkeene: 		"file" {
0bdbe4333e 2019-09-20        rkeene: 			::xvfs::_emitLine "\t\t.data.fileContents = (const unsigned char *) $data"
32b55a907b 2019-05-02        rkeene: 		}
32b55a907b 2019-05-02        rkeene: 		"directory" {
0bdbe4333e 2019-09-20        rkeene: 			::xvfs::_emitLine "\t\t.data.dirChildren  = $children"
32b55a907b 2019-05-02        rkeene: 		}
32b55a907b 2019-05-02        rkeene: 	}
0bdbe4333e 2019-09-20        rkeene: 	::xvfs::_emitLine "\t\},"
47dcf5fc27 2019-05-01        rkeene: }
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: proc ::xvfs::processDirectory {fsName directory {subDirectory ""}} {
47dcf5fc27 2019-05-01        rkeene: 	set subDirectories [list]
47dcf5fc27 2019-05-01        rkeene: 	set outputFiles [list]
47dcf5fc27 2019-05-01        rkeene: 	set workingDirectory [file join $directory $subDirectory]
47dcf5fc27 2019-05-01        rkeene: 	set outputDirectory $subDirectory
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 	if {$subDirectory eq ""} {
47dcf5fc27 2019-05-01        rkeene: 		set isTopLevel true
47dcf5fc27 2019-05-01        rkeene: 	} else {
47dcf5fc27 2019-05-01        rkeene: 		set isTopLevel false
47dcf5fc27 2019-05-01        rkeene: 	}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 	if {$isTopLevel} {
0bdbe4333e 2019-09-20        rkeene: 		::xvfs::_emitLine "static const struct xvfs_file_data xvfs_${fsName}_data\[\] = \{"
47dcf5fc27 2019-05-01        rkeene: 	}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 	# XXX:TODO: Include hidden files ?
32b55a907b 2019-05-02        rkeene: 	set children [list]
47dcf5fc27 2019-05-01        rkeene: 	foreach file [glob -nocomplain -tails -directory $workingDirectory *] {
47dcf5fc27 2019-05-01        rkeene: 		if {$file in {. ..}} {
47dcf5fc27 2019-05-01        rkeene: 			continue
47dcf5fc27 2019-05-01        rkeene: 		}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 		set inputFile [file join $workingDirectory $file]
d99958bdd3 2019-05-03        rkeene: 		set outputFile [file join $outputDirectory [encoding convertto utf-8 $file]]
30c469fcf7 2019-09-20        rkeene: 		set subDirectoryName [file join $outputDirectory $file]
0e8537c65f 2019-09-20        rkeene: 
0e8537c65f 2019-09-20        rkeene: 		if {[info command ::xvfs::callback::setOutputFileName] ne ""} {
ed3da129b8 2019-09-20        rkeene: 			set outputFile [::xvfs::callback::setOutputFileName $file $workingDirectory $inputFile $outputDirectory $outputFile]
e592c85e70 2019-09-20        rkeene: 			if {$outputFile eq "/"} {
0e8537c65f 2019-09-20        rkeene: 				continue
0e8537c65f 2019-09-20        rkeene: 			}
0e8537c65f 2019-09-20        rkeene: 		}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 		unset -nocomplain fileInfo
47dcf5fc27 2019-05-01        rkeene: 		catch {
47dcf5fc27 2019-05-01        rkeene: 			file lstat $inputFile fileInfo
47dcf5fc27 2019-05-01        rkeene: 		}
47dcf5fc27 2019-05-01        rkeene: 		if {![info exists fileInfo]} {
30ffb49c05 2019-09-20        rkeene: 			puts stderr "warning: Unable to access $inputFile, skipping"
47dcf5fc27 2019-05-01        rkeene: 		}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 		if {$fileInfo(type) eq "directory"} {
30c469fcf7 2019-09-20        rkeene: 			lappend subDirectories $subDirectoryName
32b55a907b 2019-05-02        rkeene: 			continue
47dcf5fc27 2019-05-01        rkeene: 		}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 		processFile $fsName $inputFile $outputFile [array get fileInfo]
47dcf5fc27 2019-05-01        rkeene: 		lappend outputFiles $outputFile
47dcf5fc27 2019-05-01        rkeene: 	}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 	foreach subDirectory $subDirectories {
47dcf5fc27 2019-05-01        rkeene: 		lappend outputFiles {*}[processDirectory $fsName $directory $subDirectory]
47dcf5fc27 2019-05-01        rkeene: 	}
32b55a907b 2019-05-02        rkeene: 	
32b55a907b 2019-05-02        rkeene: 	set inputFile $directory
32b55a907b 2019-05-02        rkeene: 	set outputFile $outputDirectory
e592c85e70 2019-09-20        rkeene: 	if {[info command ::xvfs::callback::setOutputFileName] ne ""} {
e592c85e70 2019-09-20        rkeene: 		set outputFile [::xvfs::callback::setOutputFileName $directory $directory $inputFile $outputDirectory $outputFile]
e592c85e70 2019-09-20        rkeene: 	}
e592c85e70 2019-09-20        rkeene: 
e592c85e70 2019-09-20        rkeene: 	if {$outputFile ne "/"} {
e592c85e70 2019-09-20        rkeene: 		unset -nocomplain fileInfo
e592c85e70 2019-09-20        rkeene: 		file stat $inputFile fileInfo
30c469fcf7 2019-09-20        rkeene: 		set children [list]
30c469fcf7 2019-09-20        rkeene: 		set outputFileLen [string length $outputFile]
30c469fcf7 2019-09-20        rkeene: 		foreach child $outputFiles {
30c469fcf7 2019-09-20        rkeene: 			if {[string range /$child 0 $outputFileLen] eq "/${outputFile}"} {
30c469fcf7 2019-09-20        rkeene: 				set child [string trimleft [string range $child $outputFileLen end] /]
30c469fcf7 2019-09-20        rkeene: 				if {![string match "*/*" $child]} {
30c469fcf7 2019-09-20        rkeene: 					lappend children $child
30c469fcf7 2019-09-20        rkeene: 				}
30c469fcf7 2019-09-20        rkeene: 			}
30c469fcf7 2019-09-20        rkeene: 		}
e592c85e70 2019-09-20        rkeene: 		set fileInfo(children) $children
32b55a907b 2019-05-02        rkeene: 
e592c85e70 2019-09-20        rkeene: 		processFile $fsName $inputFile $outputFile [array get fileInfo]
e592c85e70 2019-09-20        rkeene: 		lappend outputFiles $outputFile
e592c85e70 2019-09-20        rkeene: 	}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 	if {$isTopLevel} {
d8e00cd4a3 2019-09-20        rkeene: 		if {[info command ::xvfs::callback::addOutputFiles] ne ""} {
e592c85e70 2019-09-20        rkeene: 			lappend outputFiles {*}[::xvfs::callback::addOutputFiles $fsName]
d8e00cd4a3 2019-09-20        rkeene: 		}
d8e00cd4a3 2019-09-20        rkeene: 
0bdbe4333e 2019-09-20        rkeene: 		::xvfs::_emitLine "\};"
47dcf5fc27 2019-05-01        rkeene: 	}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 	return $outputFiles
47dcf5fc27 2019-05-01        rkeene: }
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: proc ::xvfs::main {argv} {
47dcf5fc27 2019-05-01        rkeene: 	# Main entry point
47dcf5fc27 2019-05-01        rkeene: 	## 1. Parse arguments
47dcf5fc27 2019-05-01        rkeene: 	if {[llength $argv] % 2 != 0} {
47dcf5fc27 2019-05-01        rkeene: 		lappend argv ""
47dcf5fc27 2019-05-01        rkeene: 	}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 	foreach {arg val} $argv {
47dcf5fc27 2019-05-01        rkeene: 		switch -exact -- $arg {
47dcf5fc27 2019-05-01        rkeene: 			"--help" {
47dcf5fc27 2019-05-01        rkeene: 				printHelp stdout
47dcf5fc27 2019-05-01        rkeene: 				exit 0
47dcf5fc27 2019-05-01        rkeene: 			}
47dcf5fc27 2019-05-01        rkeene: 			"--directory" {
47dcf5fc27 2019-05-01        rkeene: 				set rootDirectory $val
47dcf5fc27 2019-05-01        rkeene: 			}
47dcf5fc27 2019-05-01        rkeene: 			"--name" {
47dcf5fc27 2019-05-01        rkeene: 				set fsName $val
0bdbe4333e 2019-09-20        rkeene: 			}
09e53d3c38 2019-09-20        rkeene: 			"--output" - "--header" {
0bdbe4333e 2019-09-20        rkeene: 				# Ignored, handled as part of some other process
32b55a907b 2019-05-02        rkeene: 			}
47dcf5fc27 2019-05-01        rkeene: 			default {
47dcf5fc27 2019-05-01        rkeene: 				printHelp stderr [list "Invalid option: $arg $val"]
47dcf5fc27 2019-05-01        rkeene: 				exit 1
47dcf5fc27 2019-05-01        rkeene: 			}
47dcf5fc27 2019-05-01        rkeene: 		}
47dcf5fc27 2019-05-01        rkeene: 	}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 	## 2. Validate arguments
47dcf5fc27 2019-05-01        rkeene: 	set errors [list]
47dcf5fc27 2019-05-01        rkeene: 	if {![info exists rootDirectory]} {
47dcf5fc27 2019-05-01        rkeene: 		lappend errors "--directory must be specified"
47dcf5fc27 2019-05-01        rkeene: 	}
47dcf5fc27 2019-05-01        rkeene: 	if {![info exists fsName]} {
47dcf5fc27 2019-05-01        rkeene: 		lappend errors "--name must be specified"
47dcf5fc27 2019-05-01        rkeene: 	}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 	if {[llength $errors] != 0} {
47dcf5fc27 2019-05-01        rkeene: 		printHelp stderr $errors
47dcf5fc27 2019-05-01        rkeene: 		exit 1
47dcf5fc27 2019-05-01        rkeene: 	}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 	## 3. Start processing directory and producing initial output
32b55a907b 2019-05-02        rkeene: 	set ::xvfs::outputFiles [processDirectory $fsName $rootDirectory]
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 	set ::xvfs::fsName $fsName
47dcf5fc27 2019-05-01        rkeene: 	set ::xvfs::rootDirectory $rootDirectory
2b7fa3a8fa 2019-09-20        rkeene: }
2b7fa3a8fa 2019-09-20        rkeene: 
e592c85e70 2019-09-20        rkeene: proc ::xvfs::run {args} {
d36db7c01b 2019-09-20        rkeene: 	uplevel #0 { package require minirivet }
3cb72a0d20 2019-09-20        rkeene: 
e592c85e70 2019-09-20        rkeene: 	set ::xvfs::argv $args
2b7fa3a8fa 2019-09-20        rkeene: 	::minirivet::parse [file join $::xvfs::_xvfsDir xvfs.c.rvt]
2b7fa3a8fa 2019-09-20        rkeene: }
2b7fa3a8fa 2019-09-20        rkeene: 
d36db7c01b 2019-09-20        rkeene: proc ::xvfs::setOutputChannel {channel} {
d36db7c01b 2019-09-20        rkeene: 	uplevel #0 { package require minirivet }
d36db7c01b 2019-09-20        rkeene: 	tailcall ::minirivet::setOutputChannel $channel
d36db7c01b 2019-09-20        rkeene: }
d36db7c01b 2019-09-20        rkeene: 
d36db7c01b 2019-09-20        rkeene: proc ::xvfs::setOutputVariable {variable} {
d36db7c01b 2019-09-20        rkeene: 	uplevel #0 { package require minirivet }
d36db7c01b 2019-09-20        rkeene: 	tailcall ::minirivet::setOutputVariable $variable
09e53d3c38 2019-09-20        rkeene: }
09e53d3c38 2019-09-20        rkeene: 
09e53d3c38 2019-09-20        rkeene: proc ::xvfs::staticIncludeHeaderData {headerData} {
09e53d3c38 2019-09-20        rkeene: 	set ::xvfs::xvfsCoreH $headerData
09e53d3c38 2019-09-20        rkeene: }
09e53d3c38 2019-09-20        rkeene: 
09e53d3c38 2019-09-20        rkeene: proc ::xvfs::staticIncludeHeader {pathToHeaderFile} {
09e53d3c38 2019-09-20        rkeene: 	set fd [open $pathToHeaderFile]
09e53d3c38 2019-09-20        rkeene: 	::xvfs::staticIncludeHeaderData [read $fd]
09e53d3c38 2019-09-20        rkeene: 	close $fd
a719156faf 2019-10-09        rkeene: }
a719156faf 2019-10-09        rkeene: 
f615eecc64 2019-10-10        rkeene: proc ::xvfs::generatePerfectHashFunctionCall {cVarName cVarLength invalidValue nameList args} {
f615eecc64 2019-10-10        rkeene: 	array set config {
f615eecc64 2019-10-10        rkeene: 		preferMinimalHashSize   8
f615eecc64 2019-10-10        rkeene: 		switchToNonMinimalHash  1048576
f615eecc64 2019-10-10        rkeene: 		triesAtHashSize         1024
f615eecc64 2019-10-10        rkeene: 		maxIntermediateMultiple 8
f615eecc64 2019-10-10        rkeene: 	}
f615eecc64 2019-10-10        rkeene: 
f615eecc64 2019-10-10        rkeene: 	foreach {configKey configVal} $args {
f615eecc64 2019-10-10        rkeene: 		if {![info exists config($configKey)]} {
f615eecc64 2019-10-10        rkeene: 			error "Invalid option: $configKey"
f615eecc64 2019-10-10        rkeene: 		}
f615eecc64 2019-10-10        rkeene: 	}
f615eecc64 2019-10-10        rkeene: 	array set config $args
f615eecc64 2019-10-10        rkeene: 
a719156faf 2019-10-09        rkeene: 	set minVal 0
a719156faf 2019-10-09        rkeene: 	set maxVal [llength $nameList]
f615eecc64 2019-10-10        rkeene: 	set testExpr(0) {([zlib adler32 $nameItem $alpha] + $beta) % $gamma}
f615eecc64 2019-10-10        rkeene: 	set testExpr(1) {([zlib crc32 $nameItem $alpha] + $beta) % $gamma}
f615eecc64 2019-10-10        rkeene: 	set testExpr(2) {([zlib adler32 $nameItem [zlib crc32 $nameItem $alpha]] + $beta) % $gamma}
f615eecc64 2019-10-10        rkeene: 	set testExprC(0) {((Tcl_ZlibAdler32(${alpha}LU, (unsigned char *) $cVarName, $cVarLength) + ${beta}LU) % ${gamma}LU)}
f615eecc64 2019-10-10        rkeene: 	set testExprC(1) {((Tcl_ZlibCRC32(${alpha}LU, (unsigned char *) $cVarName, $cVarLength) + ${beta}LU) % ${gamma}LU)}
f615eecc64 2019-10-10        rkeene: 	set testExprC(2) {((Tcl_ZlibAdler32(Tcl_ZlibCRC32(${alpha}LU, (unsigned char *) $cVarName, $cVarLength), (unsigned char *) $cVarName, $cVarLength) + ${beta}LU) % ${gamma}LU)}
f615eecc64 2019-10-10        rkeene: 
f615eecc64 2019-10-10        rkeene: 	set minimal false
f615eecc64 2019-10-10        rkeene: 	if {$maxVal < $config(preferMinimalHashSize)} {
f615eecc64 2019-10-10        rkeene: 		set minimal true
f615eecc64 2019-10-10        rkeene: 	}
a719156faf 2019-10-09        rkeene: 
a719156faf 2019-10-09        rkeene: 	set round -1
a719156faf 2019-10-09        rkeene: 
f615eecc64 2019-10-10        rkeene: 	set gammaRoundMod [expr {$maxVal * ($config(maxIntermediateMultiple) - 1)}]
a719156faf 2019-10-09        rkeene: 
a719156faf 2019-10-09        rkeene: 	while true {
f615eecc64 2019-10-10        rkeene: 		if {$minimal && $round > $config(switchToNonMinimalHash)} {
f615eecc64 2019-10-10        rkeene: 			set minimal false
f615eecc64 2019-10-10        rkeene: 			set round -1
f615eecc64 2019-10-10        rkeene: 		}
a719156faf 2019-10-09        rkeene: 		incr round
a719156faf 2019-10-09        rkeene: 
f615eecc64 2019-10-10        rkeene: 		if {$minimal} {
f615eecc64 2019-10-10        rkeene: 			set gamma [expr {$maxVal + ($round % ($maxVal * 4))}]
f615eecc64 2019-10-10        rkeene: 		} else {
f615eecc64 2019-10-10        rkeene: 			set gamma [expr {$maxVal + ($round % $gammaRoundMod)}]
f615eecc64 2019-10-10        rkeene: 		}
f615eecc64 2019-10-10        rkeene: 
f615eecc64 2019-10-10        rkeene: 		for {set try 0} {$try < $config(triesAtHashSize)} {incr try} {
f615eecc64 2019-10-10        rkeene: 			set alpha [expr {entier(rand() * (2**31))}]
f615eecc64 2019-10-10        rkeene: 			set beta  [expr {entier(rand() * (2**31))}]
f615eecc64 2019-10-10        rkeene: 
f615eecc64 2019-10-10        rkeene: 			foreach {testExprID testExprContents} [array get testExpr] {
f615eecc64 2019-10-10        rkeene: 				set idx -1
f615eecc64 2019-10-10        rkeene: 				set seenIndexes [list]
f615eecc64 2019-10-10        rkeene: 				set failed false
f615eecc64 2019-10-10        rkeene: 				foreach nameItem $nameList {
f615eecc64 2019-10-10        rkeene: 
f615eecc64 2019-10-10        rkeene: 					set testExprVal [expr $testExprContents]
f615eecc64 2019-10-10        rkeene: 
f615eecc64 2019-10-10        rkeene: 					if {$minimal} {
f615eecc64 2019-10-10        rkeene: 						incr idx
f615eecc64 2019-10-10        rkeene: 
f615eecc64 2019-10-10        rkeene: 						if {$testExprVal != $idx} {
f615eecc64 2019-10-10        rkeene: 							set failed true
f615eecc64 2019-10-10        rkeene: 							break
f615eecc64 2019-10-10        rkeene: 						}
f615eecc64 2019-10-10        rkeene: 					} else {
f615eecc64 2019-10-10        rkeene: 						if {$testExprVal in $seenIndexes} {
f615eecc64 2019-10-10        rkeene: 							set failed true
f615eecc64 2019-10-10        rkeene: 							break
f615eecc64 2019-10-10        rkeene: 						}
f615eecc64 2019-10-10        rkeene: 
f615eecc64 2019-10-10        rkeene: 						lappend seenIndexes $testExprVal
f615eecc64 2019-10-10        rkeene: 					}
f615eecc64 2019-10-10        rkeene: 				}
f615eecc64 2019-10-10        rkeene: 
f615eecc64 2019-10-10        rkeene: 				if {!$failed} {
f615eecc64 2019-10-10        rkeene: 					break
f615eecc64 2019-10-10        rkeene: 				}
f615eecc64 2019-10-10        rkeene: 			}
f615eecc64 2019-10-10        rkeene: 
f615eecc64 2019-10-10        rkeene: 			if {!$failed} {
f615eecc64 2019-10-10        rkeene: 				break
f615eecc64 2019-10-10        rkeene: 			}
a719156faf 2019-10-09        rkeene: 		}
a719156faf 2019-10-09        rkeene: 
a719156faf 2019-10-09        rkeene: 		if {!$failed} {
a719156faf 2019-10-09        rkeene: 			break
a719156faf 2019-10-09        rkeene: 		}
a719156faf 2019-10-09        rkeene: 	}
a719156faf 2019-10-09        rkeene: 
f615eecc64 2019-10-10        rkeene: 	if {$minimal} {
f615eecc64 2019-10-10        rkeene: 		set phfCall [subst $testExprC($testExprID)]
f615eecc64 2019-10-10        rkeene: 	} else {
f615eecc64 2019-10-10        rkeene: 		unset -nocomplain mapArray
f615eecc64 2019-10-10        rkeene: 		for {set idx 0} {$idx < $gamma} {incr idx} {
f615eecc64 2019-10-10        rkeene: 			set mapArray($idx) $invalidValue
f615eecc64 2019-10-10        rkeene: 		}
f615eecc64 2019-10-10        rkeene: 
f615eecc64 2019-10-10        rkeene: 		set idx -1
f615eecc64 2019-10-10        rkeene: 		foreach nameItem $nameList {
f615eecc64 2019-10-10        rkeene: 			incr idx
f615eecc64 2019-10-10        rkeene: 
f615eecc64 2019-10-10        rkeene: 			set mapArray([expr $testExpr($testExprID)]) $idx
f615eecc64 2019-10-10        rkeene: 		}
f615eecc64 2019-10-10        rkeene: 
f615eecc64 2019-10-10        rkeene: 		set map "(long\[\])\{"
f615eecc64 2019-10-10        rkeene: 		for {set idx 0} {$idx < $gamma} {incr idx} {
f615eecc64 2019-10-10        rkeene: 			append map "$mapArray($idx), "
f615eecc64 2019-10-10        rkeene: 		}
f615eecc64 2019-10-10        rkeene: 		set map [string range $map 0 end-2]
f615eecc64 2019-10-10        rkeene: 		append map "\}\[[subst $testExprC($testExprID)]\]"
f615eecc64 2019-10-10        rkeene: 
f615eecc64 2019-10-10        rkeene: 		set phfCall $map
f615eecc64 2019-10-10        rkeene: 	}
a719156faf 2019-10-09        rkeene: 
a719156faf 2019-10-09        rkeene: 	return $phfCall
d36db7c01b 2019-09-20        rkeene: }
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: package provide xvfs 1