Annotation For lib/xvfs/xvfs.tcl

Lines of lib/xvfs/xvfs.tcl from check-in 47dcf5fc27 that are changed by the sequence of edits moving toward check-in 303b2de493:

                         1: #! /usr/bin/env tclsh
                         2: 
                         3: namespace eval ::xvfs {}
                         4: 
                         5: # Functions
                         6: proc ::xvfs::printHelp {channel {errors ""}} {
                         7: 	if {[llength $errors] != 0} {
                         8: 		foreach error $errors {
                         9: 			puts $channel "error: $error"
                        10: 		}
                        11: 		puts $channel ""
                        12: 	}
                        13: 	puts $channel "Usage: dir2c \[--help\] --directory <rootDirectory> --name <fsName>"
                        14: 	flush $channel
                        15: }
                        16: 
                        17: proc ::xvfs::sanitizeCString {string} {
                        18: 	set output [join [lmap char [split $string ""] {
                        19: 		if {![regexp {[A-Za-z0-9./-]} $char]} {
                        20: 			binary scan $char H* char
                        21: 			set char "\\[format %03o 0x$char]"
                        22: 		}
                        23: 
                        24: 		set char
                        25: 	}] ""]
                        26: 
                        27: 	return $output
                        28: }
                        29: 
                        30: proc ::xvfs::binaryToCHex {binary {prefix ""} {width 10}} {
                        31: 	binary scan $binary H* binary
                        32: 	set output [list]
                        33: 
                        34: 	set width [expr {$width * 2}]
                        35: 	set stopAt [expr {$width - 1}]
                        36: 
                        37: 	while {$binary ne ""} {
                        38: 		set row [string range $binary 0 $stopAt]
                        39: 		set binary [string range $binary $width end]
                        40: 
                        41: 		set rowOutput [list]
                        42: 		while {$row ne ""} {
                        43: 			set value [string range $row 0 1]
                        44: 			set row [string range $row 2 end]
                        45: 
                        46: 			lappend rowOutput "\\x$value"
                        47: 		}
                        48: 		set rowOutput [join $rowOutput {}]
                        49: 		set rowOutput "${prefix}\"${rowOutput}\""
                        50: 		lappend output $rowOutput
                        51: 	}
                        52: 
                        53: 	if {[llength $output] == 0} {
                        54: 		return "${prefix}\"\""
                        55: 	}
                        56: 
                        57: 	set output [join $output "\n"]
                        58: }
                        59: 
                        60: proc ::xvfs::processFile {fsName inputFile outputFile fileInfoDict} {
                        61: 	array set fileInfo $fileInfoDict
                        62: 
                        63: 	switch -exact -- $fileInfo(type) {
                        64: 		"file" {
                        65: 			set type "XVFS_FILE_TYPE_REG"
                        66: 			set fd [open $inputFile]
                        67: 			fconfigure $fd -encoding binary -translation binary -blocking true
                        68: 			set data [read $fd]
                        69: 			set size [string length $data]
                        70: 			set data [string trimleft [binaryToCHex $data "\t\t\t"]]
                        71: 			close $fd
                        72: 		}
                        73: 		"directory" {
                        74: 			set data "NULL"
                        75: 			set type "XVFS_FILE_TYPE_DIR"
                        76: 			set size "0"
                        77: 		}
                        78: 		default {
                        79: 			return -code error "Unable to process $inputFile, unknown type: $fileInfo(type)"
                        80: 		}
                        81: 	}
                        82: 
                        83: 	puts "\t\{"
                        84: 	puts "\t\t.name = \"[sanitizeCString $outputFile]\","
                        85: 	puts "\t\t.type = $type,"
                        86: 	puts "\t\t.size = $size,"
                        87: 	puts "\t\t.data = $data"
                        88: 	puts "\t\},"
                        89: }
                        90: 
                        91: proc ::xvfs::processDirectory {fsName directory {subDirectory ""}} {
                        92: 	set subDirectories [list]
                        93: 	set outputFiles [list]
                        94: 	set workingDirectory [file join $directory $subDirectory]
                        95: 	set outputDirectory $subDirectory
                        96: 
                        97: 	if {$subDirectory eq ""} {
                        98: 		set isTopLevel true
                        99: 	} else {
                       100: 		set isTopLevel false
                       101: 	}
                       102: 
                       103: 	if {$isTopLevel} {
47dcf5fc27 2019-05-01  104: 		puts {
47dcf5fc27 2019-05-01  105: /*
47dcf5fc27 2019-05-01  106:  * XXX:TODO: Move this header information
47dcf5fc27 2019-05-01  107:  */
47dcf5fc27 2019-05-01  108: #include <unistd.h>
47dcf5fc27 2019-05-01  109: #include <tcl.h>
47dcf5fc27 2019-05-01  110: 
47dcf5fc27 2019-05-01  111: typedef enum {
47dcf5fc27 2019-05-01  112: 	XVFS_FILE_TYPE_REG,
47dcf5fc27 2019-05-01  113: 	XVFS_FILE_TYPE_DIR
47dcf5fc27 2019-05-01  114: } xvfs_file_type_t;
47dcf5fc27 2019-05-01  115: 
47dcf5fc27 2019-05-01  116: typedef Tcl_WideInt xvfs_size_t;
47dcf5fc27 2019-05-01  117: 
47dcf5fc27 2019-05-01  118: struct xvfs_file_data {
47dcf5fc27 2019-05-01  119: 	const char          *name;
47dcf5fc27 2019-05-01  120: 	xvfs_file_type_t    type;
47dcf5fc27 2019-05-01  121: 	xvfs_size_t         size;
47dcf5fc27 2019-05-01  122: 	const unsigned char *data;
47dcf5fc27 2019-05-01  123: };}
                       124: 		puts "static struct xvfs_file_data xvfs_${fsName}_data\[\] = \{"
                       125: 	}
                       126: 
                       127: 	# XXX:TODO: Include hidden files ?
                       128: 	foreach file [glob -nocomplain -tails -directory $workingDirectory *] {
                       129: 		if {$file in {. ..}} {
                       130: 			continue
                       131: 		}
                       132: 
                       133: 		set inputFile [file join $workingDirectory $file]
                       134: 		set outputFile [file join $outputDirectory $file]
                       135: 
                       136: 		unset -nocomplain fileInfo
                       137: 		catch {
                       138: 			file lstat $inputFile fileInfo
                       139: 		}
                       140: 		if {![info exists fileInfo]} {
                       141: 			puts stderr "warning: Unable to access $inputFile, skipping"
                       142: 		}
                       143: 
                       144: 		if {$fileInfo(type) eq "directory"} {
                       145: 			lappend subDirectories $outputFile
                       146: 		}
                       147: 
                       148: 		processFile $fsName $inputFile $outputFile [array get fileInfo]
                       149: 		lappend outputFiles $outputFile
                       150: 	}
                       151: 
                       152: 	foreach subDirectory $subDirectories {
                       153: 		lappend outputFiles {*}[processDirectory $fsName $directory $subDirectory]
                       154: 	}
                       155: 
                       156: 	if {$isTopLevel} {
                       157: 		puts "\};"
                       158: 
                       159: if {0} {
                       160: 		puts ""
                       161: 		puts "static <type> xvfs_${fsName}_nameToIndex\[\] = \{"
                       162: 		foreach outputFile $outputFiles {
                       163: 			puts "\t\"$outputFile\","
                       164: 		}
                       165: 		puts "\};"
                       166: }
                       167: 	}
                       168: 
                       169: 	return $outputFiles
                       170: }
                       171: 
                       172: proc ::xvfs::main {argv} {
                       173: 	# Main entry point
                       174: 	## 1. Parse arguments
                       175: 	if {[llength $argv] % 2 != 0} {
                       176: 		lappend argv ""
                       177: 	}
                       178: 
                       179: 	foreach {arg val} $argv {
                       180: 		switch -exact -- $arg {
                       181: 			"--help" {
                       182: 				printHelp stdout
                       183: 				exit 0
                       184: 			}
                       185: 			"--directory" {
                       186: 				set rootDirectory $val
                       187: 			}
                       188: 			"--name" {
                       189: 				set fsName $val
                       190: 			}
                       191: 			default {
                       192: 				printHelp stderr [list "Invalid option: $arg $val"]
                       193: 				exit 1
                       194: 			}
                       195: 		}
                       196: 	}
                       197: 
                       198: 	## 2. Validate arguments
                       199: 	set errors [list]
                       200: 	if {![info exists rootDirectory]} {
                       201: 		lappend errors "--directory must be specified"
                       202: 	}
                       203: 	if {![info exists fsName]} {
                       204: 		lappend errors "--name must be specified"
                       205: 	}
                       206: 
                       207: 	if {[llength $errors] != 0} {
                       208: 		printHelp stderr $errors
                       209: 		exit 1
                       210: 	}
                       211: 
                       212: 	## 3. Start processing directory and producing initial output
                       213: 	processDirectory $fsName $rootDirectory 
                       214: 
                       215: 	set ::xvfs::fsName $fsName
                       216: 	set ::xvfs::rootDirectory $rootDirectory
                       217: }
                       218: 
                       219: package provide xvfs 1