⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 genstubs.tcl

📁 tcl是工具命令语言
💻 TCL
📖 第 1 页 / 共 2 页
字号:
# genStubs.tcl --##	This script generates a set of stub files for a given#	interface.  #	## Copyright (c) 1998-1999 by Scriptics Corporation.# See the file "license.terms" for information on usage and redistribution# of this file, and for a DISCLAIMER OF ALL WARRANTIES.# # RCS: @(#) $Id: genStubs.tcl,v 1.13 2002/10/04 08:25:14 dkf Exp $package require Tcl 8namespace eval genStubs {    # libraryName --    #    #	The name of the entire library.  This value is used to compute    #	the USE_*_STUB_PROCS macro and the name of the init file.    variable libraryName "UNKNOWN"    # interfaces --    #    #	An array indexed by interface name that is used to maintain    #   the set of valid interfaces.  The value is empty.    array set interfaces {}    # curName --    #    #	The name of the interface currently being defined.    variable curName "UNKNOWN"    # hooks --    #    #	An array indexed by interface name that contains the set of    #	subinterfaces that should be defined for a given interface.    array set hooks {}    # stubs --    #    #	This three dimensional array is indexed first by interface name,    #	second by platform name, and third by a numeric offset or the    #	constant "lastNum".  The lastNum entry contains the largest    #	numeric offset used for a given interface/platform combo.  Each    #	numeric offset contains the C function specification that    #	should be used for the given entry in the stub table.  The spec    #	consists of a list in the form returned by parseDecl.    array set stubs {}    # outDir --    #    #	The directory where the generated files should be placed.    variable outDir .}# genStubs::library --##	This function is used in the declarations file to set the name#	of the library that the interfaces are associated with (e.g. "tcl").#	This value will be used to define the inline conditional macro.## Arguments:#	name	The library name.## Results:#	None.proc genStubs::library {name} {    variable libraryName $name}# genStubs::interface --##	This function is used in the declarations file to set the name#	of the interface currently being defined.## Arguments:#	name	The name of the interface.## Results:#	None.proc genStubs::interface {name} {    variable curName $name    variable interfaces    set interfaces($name) {}    return}# genStubs::hooks --##	This function defines the subinterface hooks for the current#	interface.## Arguments:#	names	The ordered list of interfaces that are reachable through the#		hook vector.## Results:#	None.proc genStubs::hooks {names} {    variable curName    variable hooks    set hooks($curName) $names    return}# genStubs::declare --##	This function is used in the declarations file to declare a new#	interface entry.## Arguments:#	index		The index number of the interface.#	platform	The platform the interface belongs to.  Should be one#			of generic, win, unix, or mac, or macosx or aqua or x11.#	decl		The C function declaration, or {} for an undefined#			entry.## Results:#	None.proc genStubs::declare {args} {    variable stubs    variable curName    if {[llength $args] != 3} {	puts stderr "wrong # args: declare $args"    }    lassign $args index platformList decl    # Check for duplicate declarations, then add the declaration and    # bump the lastNum counter if necessary.    foreach platform $platformList {	if {[info exists stubs($curName,$platform,$index)]} {	    puts stderr "Duplicate entry: declare $args"	}    }    regsub -all "\[ \t\n\]+" [string trim $decl] " " decl    set decl [parseDecl $decl]    foreach platform $platformList {	if {$decl != ""} {	    set stubs($curName,$platform,$index) $decl	    if {![info exists stubs($curName,$platform,lastNum)] \		    || ($index > $stubs($curName,$platform,lastNum))} {		set stubs($curName,$platform,lastNum) $index	    }	}    }    return}# genStubs::rewriteFile --##	This function replaces the machine generated portion of the#	specified file with new contents.  It looks for the !BEGIN! and#	!END! comments to determine where to place the new text.## Arguments:#	file	The name of the file to modify.#	text	The new text to place in the file.## Results:#	None.proc genStubs::rewriteFile {file text} {    if {![file exists $file]} {	puts stderr "Cannot find file: $file"	return    }    set in [open ${file} r]    set out [open ${file}.new w]    while {![eof $in]} {	set line [gets $in]	if {[regexp {!BEGIN!} $line]} {	    break	}	puts $out $line    }    puts $out "/* !BEGIN!: Do not edit below this line. */"    puts $out $text    while {![eof $in]} {	set line [gets $in]	if {[regexp {!END!} $line]} {	    break	}    }    puts $out "/* !END!: Do not edit above this line. */"    puts -nonewline $out [read $in]    close $in    close $out    file rename -force ${file}.new ${file}    return}# genStubs::addPlatformGuard --##	Wrap a string inside a platform #ifdef.## Arguments:#	plat	Platform to test.## Results:#	Returns the original text inside an appropriate #ifdef.proc genStubs::addPlatformGuard {plat text} {    switch $plat {	win {	    return "#ifdef __WIN32__\n${text}#endif /* __WIN32__ */\n"	}	unix {	    return "#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */\n${text}#endif /* UNIX */\n"	}		    	mac {	    return "#ifdef MAC_TCL\n${text}#endif /* MAC_TCL */\n"	}	macosx {	    return "#ifdef MAC_OSX_TCL\n${text}#endif /* MAC_OSX_TCL */\n"	}	aqua {	    return "#ifdef MAC_OSX_TK\n${text}#endif /* MAC_OSX_TK */\n"	}	x11 {	    return "#if !(defined(__WIN32__) || defined(MAC_TCL) || defined(MAC_OSX_TK)) /* X11 */\n${text}#endif /* X11 */\n"	}    }    return "$text"}# genStubs::emitSlots --##	Generate the stub table slots for the given interface.  If there#	are no generic slots, then one table is generated for each#	platform, otherwise one table is generated for all platforms.## Arguments:#	name	The name of the interface being emitted.#	textVar	The variable to use for output.## Results:#	None.proc genStubs::emitSlots {name textVar} {    variable stubs    upvar $textVar text    forAllStubs $name makeSlot 1 text {"    void *reserved$i;\n"}    return}# genStubs::parseDecl --##	Parse a C function declaration into its component parts.## Arguments:#	decl	The function declaration.## Results:#	Returns a list of the form {returnType name args}.  The args#	element consists of a list of type/name pairs, or a single#	element "void".  If the function declaration is malformed#	then an error is displayed and the return value is {}.proc genStubs::parseDecl {decl} {    if {![regexp {^(.*)\((.*)\)$} $decl all prefix args]} {	puts stderr "Malformed declaration: $decl"	return    }    set prefix [string trim $prefix]    if {![regexp {^(.+[ ][*]*)([^ *]+)$} $prefix all rtype fname]} {	puts stderr "Bad return type: $decl"	return    }    set rtype [string trim $rtype]    foreach arg [split $args ,] {	lappend argList [string trim $arg]    }    if {![string compare [lindex $argList end] "..."]} {	if {[llength $argList] != 2} {	    puts stderr "Only one argument is allowed in varargs form: $decl"	}	set arg [parseArg [lindex $argList 0]]	if {$arg == "" || ([llength $arg] != 2)} {	    puts stderr "Bad argument: '[lindex $argList 0]' in '$decl'"	    return	}	set args [list TCL_VARARGS $arg]    } else {	set args {}	foreach arg $argList {	    set argInfo [parseArg $arg]	    if {![string compare $argInfo "void"]} {		lappend args "void"		break	    } elseif {[llength $argInfo] == 2 || [llength $argInfo] == 3} {		lappend args $argInfo	    } else {		puts stderr "Bad argument: '$arg' in '$decl'"		return	    }	}    }    return [list $rtype $fname $args]}# genStubs::parseArg --##	This function parses a function argument into a type and name.## Arguments:#	arg	The argument to parse.## Results:#	Returns a list of type and name with an optional third array#	indicator.  If the argument is malformed, returns "".proc genStubs::parseArg {arg} {    if {![regexp {^(.+[ ][*]*)([^][ *]+)(\[\])?$} $arg all type name array]} {	if {$arg == "void"} {	    return $arg	} else {	    return	}    }    set result [list [string trim $type] $name]    if {$array != ""} {	lappend result $array    }    return $result}# genStubs::makeDecl --##	Generate the prototype for a function.## Arguments:#	name	The interface name.#	decl	The function declaration.#	index	The slot index for this function.## Results:#	Returns the formatted declaration string.proc genStubs::makeDecl {name decl index} {    lassign $decl rtype fname args    append text "/* $index */\n"    set line "EXTERN $rtype"    set count [expr {2 - ([string length $line] / 8)}]    append line [string range "\t\t\t" 0 $count]    set pad [expr {24 - [string length $line]}]    if {$pad <= 0} {	append line " "	set pad 0    }    append line "$fname _ANSI_ARGS_("    set arg1 [lindex $args 0]    switch -exact $arg1 {	void {	    append line "(void)"	}	TCL_VARARGS {	    set arg [lindex $args 1]	    append line "TCL_VARARGS([lindex $arg 0],[lindex $arg 1])"	}	default {	    set sep "("	    foreach arg $args {		append line $sep		set next {}		append next [lindex $arg 0] " " [lindex $arg 1] \			[lindex $arg 2]		if {[string length $line] + [string length $next] \			+ $pad > 76} {		    append text $line \n		    set line "\t\t\t\t"		    set pad 28		}		append line $next		set sep ", "	    }	    append line ")"	}    }    append text $line        append text ");\n"    return $text}# genStubs::makeMacro --##	Generate the inline macro for a function.## Arguments:#	name	The interface name.#	decl	The function declaration.#	index	The slot index for this function.## Results:#	Returns the formatted macro definition.proc genStubs::makeMacro {name decl index} {    lassign $decl rtype fname args    set lfname [string tolower [string index $fname 0]]    append lfname [string range $fname 1 end]    set text "#ifndef $fname\n#define $fname"    set arg1 [lindex $args 0]    set argList ""    switch -exact $arg1 {	void {	    set argList "()"	}	TCL_VARARGS {	}	default {	    set sep "("	    foreach arg $args {		append argList $sep [lindex $arg 1]		set sep ", "	    }	    append argList ")"	}    }    append text " \\\n\t(${name}StubsPtr->$lfname)"    append text " /* $index */\n#endif\n"    return $text}# genStubs::makeStub --##	Emits a stub function definition.## Arguments:#	name	The interface name.#	decl	The function declaration.#	index	The slot index for this function.## Results:#	Returns the formatted stub function definition.proc genStubs::makeStub {name decl index} {    lassign $decl rtype fname args    set lfname [string tolower [string index $fname 0]]    append lfname [string range $fname 1 end]    append text "/* Slot $index */\n" $rtype "\n" $fname    set arg1 [lindex $args 0]    if {![string compare $arg1 "TCL_VARARGS"]} {	lassign [lindex $args 1] type argName 	append text " TCL_VARARGS_DEF($type,$argName)\n\{\n"	append text "    " $type " var;\n    va_list argList;\n"	if {[string compare $rtype "void"]} {	    append text "    " $rtype " resultValue;\n"	}	append text "\n    var = (" $type ") TCL_VARARGS_START(" \		$type "," $argName ",argList);\n\n    "	if {[string compare $rtype "void"]} {	    append text "resultValue = "	}	append text "(" $name "StubsPtr->" $lfname "VA)(var, argList);\n"	append text "    va_end(argList);\n"	if {[string compare $rtype "void"]} {	    append text "return resultValue;\n"	}	append text "\}\n\n"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -