Annotation For lib/xvfs/xvfs.tcl

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

47dcf5fc27 2019-05-01        rkeene: #! /usr/bin/env tclsh
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: namespace eval ::xvfs {}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: # Functions
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 {
47dcf5fc27 2019-05-01        rkeene: 			puts $channel "error: $error"
47dcf5fc27 2019-05-01        rkeene: 		}
47dcf5fc27 2019-05-01        rkeene: 		puts $channel ""
47dcf5fc27 2019-05-01        rkeene: 	}
47dcf5fc27 2019-05-01        rkeene: 	puts $channel "Usage: dir2c \[--help\] --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: 
47dcf5fc27 2019-05-01        rkeene: proc ::xvfs::binaryToCHex {binary {prefix ""} {width 10}} {
47dcf5fc27 2019-05-01        rkeene: 	binary scan $binary H* 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: 
47dcf5fc27 2019-05-01        rkeene: 	while {$binary ne ""} {
47dcf5fc27 2019-05-01        rkeene: 		set row [string range $binary 0 $stopAt]
47dcf5fc27 2019-05-01        rkeene: 		set binary [string range $binary $width end]
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"
47dcf5fc27 2019-05-01        rkeene: 			set fd [open $inputFile]
47dcf5fc27 2019-05-01        rkeene: 			fconfigure $fd -encoding binary -translation binary -blocking true
47dcf5fc27 2019-05-01        rkeene: 			set data [read $fd]
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: 			close $fd
47dcf5fc27 2019-05-01        rkeene: 		}
47dcf5fc27 2019-05-01        rkeene: 		"directory" {
47dcf5fc27 2019-05-01        rkeene: 			set data "NULL"
47dcf5fc27 2019-05-01        rkeene: 			set type "XVFS_FILE_TYPE_DIR"
47dcf5fc27 2019-05-01        rkeene: 			set size "0"
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: 
47dcf5fc27 2019-05-01        rkeene: 	puts "\t\{"
47dcf5fc27 2019-05-01        rkeene: 	puts "\t\t.name = \"[sanitizeCString $outputFile]\","
47dcf5fc27 2019-05-01        rkeene: 	puts "\t\t.type = $type,"
47dcf5fc27 2019-05-01        rkeene: 	puts "\t\t.size = $size,"
47dcf5fc27 2019-05-01        rkeene: 	puts "\t\t.data = $data"
47dcf5fc27 2019-05-01        rkeene: 	puts "\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} {
47dcf5fc27 2019-05-01        rkeene: 		puts {
47dcf5fc27 2019-05-01        rkeene: /*
47dcf5fc27 2019-05-01        rkeene:  * XXX:TODO: Move this header information
47dcf5fc27 2019-05-01        rkeene:  */
47dcf5fc27 2019-05-01        rkeene: #include <unistd.h>
47dcf5fc27 2019-05-01        rkeene: #include <tcl.h>
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: typedef enum {
47dcf5fc27 2019-05-01        rkeene: 	XVFS_FILE_TYPE_REG,
47dcf5fc27 2019-05-01        rkeene: 	XVFS_FILE_TYPE_DIR
47dcf5fc27 2019-05-01        rkeene: } xvfs_file_type_t;
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: typedef Tcl_WideInt xvfs_size_t;
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: struct xvfs_file_data {
47dcf5fc27 2019-05-01        rkeene: 	const char          *name;
47dcf5fc27 2019-05-01        rkeene: 	xvfs_file_type_t    type;
47dcf5fc27 2019-05-01        rkeene: 	xvfs_size_t         size;
47dcf5fc27 2019-05-01        rkeene: 	const unsigned char *data;
47dcf5fc27 2019-05-01        rkeene: };}
47dcf5fc27 2019-05-01        rkeene: 		puts "static 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 ?
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]
47dcf5fc27 2019-05-01        rkeene: 		set outputFile [file join $outputDirectory $file]
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]} {
47dcf5fc27 2019-05-01        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"} {
47dcf5fc27 2019-05-01        rkeene: 			lappend subDirectories $outputFile
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: 	}
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: 	if {$isTopLevel} {
47dcf5fc27 2019-05-01        rkeene: 		puts "\};"
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: if {0} {
47dcf5fc27 2019-05-01        rkeene: 		puts ""
47dcf5fc27 2019-05-01        rkeene: 		puts "static <type> xvfs_${fsName}_nameToIndex\[\] = \{"
47dcf5fc27 2019-05-01        rkeene: 		foreach outputFile $outputFiles {
47dcf5fc27 2019-05-01        rkeene: 			puts "\t\"$outputFile\","
47dcf5fc27 2019-05-01        rkeene: 		}
47dcf5fc27 2019-05-01        rkeene: 		puts "\};"
47dcf5fc27 2019-05-01        rkeene: }
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
47dcf5fc27 2019-05-01        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
47dcf5fc27 2019-05-01        rkeene: 	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
47dcf5fc27 2019-05-01        rkeene: }
47dcf5fc27 2019-05-01        rkeene: 
47dcf5fc27 2019-05-01        rkeene: package provide xvfs 1