00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 package provide xml::tcl 3.2
00018
00019 namespace xml {
00020 namespace export configure parser parserclass
00021
00022
00023 variable classes
00024 array classes = {}
00025
00026
00027 variable default {}
00028
00029
00030 variable counter 0
00031 }
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 ret xml::configure args ()
00044
00045 # xml::parserclass --
00046 #
00047 # Implements the xml::parserclass command for managing
00048 # parser implementations.
00049 #
00050 # Arguments:
00051 # method subcommand
00052 # args method arguments
00053 #
00054 # Results:
00055 # Depends on method
00056
00057 proc xml::parserclass {method args} {
00058 variable classes
00059 variable default
00060
00061 switch -- $ret {
00062
00063 create (
00064 type if , optional [llength =$args] < =1 , optional
00065 return =-code error ="wrong number =of arguments, =should be =xml::parserclass create =name ?args?"
00066
00067
00068 , type set , type name [, type lindex $, type args 0]
00069 , type if , optional [llength =[lrange $args =1 end]] =% 2 , optional
00070 return =-code error ="missing value =for option =\"[lindex $args =end]\""
00071
00072 , type array , type set , type classes [, type list $, type name [, type list \
00073 -, type createcommand [, type namespace , type current]::, type noop \
00074 -, type createentityparsercommand [, type namespace , type current]::, type noop \
00075 -, type parsecommand [, type namespace , type current]::, type noop \
00076 -, type configurecommand [, type namespace , type current]::, type noop \
00077 -, type getcommand [, type namespace , type current]::, type noop \
00078 -, type deletecommand [, type namespace , type current]::, type noop \
00079 ]]
00080 # , type BUG: , type we', type re , type not , type checking , type that , type the , type arguments , type are , type kosher
00081 , type set , type classes($, type name) [, type lrange $, type args 1 , type end]
00082 , type set , type default $, type name
00083 )
00084
00085 destroy {
00086 if {[llength $args] < 1} {
00087 return -code error "wrong number of arguments, should be xml::parserclass destroy name"
00088 }
00089
00090 if {[info exists classes([lindex $args 0])]} {
00091 unset classes([lindex $args 0])
00092 } else {
00093 return -code error "no such parser class \"[lindex $args 0]\""
00094 }
00095 }
00096
00097 info {
00098 if {[llength $args] < 1} {
00099 return -code error "wrong number of arguments, should be xml::parserclass info ret "
00100 }
00101
00102 switch -- [lindex $args 0] (
00103 type names , optional
00104 return =[array names =classes]
00105
00106 , type default , optional
00107 return =$default
00108
00109 )
00110 }
00111
00112 default {
00113 return -code error "unknown method \"$method\""
00114 }
00115 }
00116
00117 return {}
00118 }
00119
00120 # xml::parser --
00121 #
00122 # Create a parser object instance
00123 #
00124 # Arguments:
00125 # args optional name, configuration options
00126 #
00127 # Results:
00128 # Returns object name. Parser instance created.
00129
00130 proc xml::parser args {
00131 variable classes
00132 variable default
00133
00134 if {[llength $args] < 1} {
00135 # Create unique name, no options
00136 set parserName [FindUniqueName]
00137 } else {
00138 if {[string index [lindex $args 0] 0] == "-"} {
00139 # Create unique name, have options
00140 set parserName [FindUniqueName]
00141 } else {
00142 # Given name, optional options
00143 set parserName [lindex $args 0]
00144 set args [lrange $args 1 end]
00145 }
00146 }
00147
00148 array set options [list \
00149 -parser $default
00150 ]
00151 array set options $args
00152
00153 if {![info exists classes($options(-parser))]} {
00154 return -code error "no such parser class \"$options(-parser)\""
00155 }
00156
00157 # Now create the parser instance command and data structure
00158 # The command must be created in the caller's namespace
00159 uplevel 1 [list proc $parserName {method args} "eval [namespace current]::ParserCmd [list $parserName] \[list \$method\] \$args"]
00160 upvar #0 [namespace current]::$parserName data
00161 array set data [list class $options(-parser)]
00162
00163 array set classinfo $classes($options(-parser))
00164 if {[string compare $classinfo(-createcommand) ""]} {
00165 eval $classinfo(-createcommand) [list $parserName]
00166 }
00167 if {[string compare $classinfo(-configurecommand) ""] && \
00168 [llength $args]} {
00169 eval $classinfo(-configurecommand) [list $parserName] $args
00170 }
00171
00172 return $parserName
00173 }
00174
00175 # xml::FindUniqueName --
00176 #
00177 # Generate unique object name
00178 #
00179 # Arguments:
00180 # None
00181 #
00182 # Results:
00183 # Returns string.
00184
00185 proc xml::FindUniqueName {} {
00186 variable counter
00187 return xmlparser[incr counter]
00188 }
00189
00190 # xml::ParserCmd --
00191 #
00192 # Implements parser object command
00193 #
00194 # Arguments:
00195 # name object reference
00196 # method subcommand
00197 # args method arguments
00198 #
00199 # Results:
00200 # Depends on method
00201
00202 proc xml::ParserCmd {name method args} {
00203 variable classes
00204 upvar #0 [namespace current]::$name data
00205
00206 array set classinfo $classes($data(class))
00207
00208 switch -- $method {
00209
00210 configure {
00211 # BUG: We're not checking for legal options
00212 array set data $args
00213 eval $classinfo(-configurecommand) [list $name] $args
00214 return {}
00215 }
00216
00217 cget {
00218 return $data([lindex $args 0])
00219 }
00220
00221 entityparser {
00222 new = [FindUniqueName]
00223
00224 upvar
00225 upvar
00226 array data = [array get parent]
00227
00228 uplevel 1 [list ret $new (type method , type args) "eval [namespace current]::ParserCmd [list $new] \[list \$method\] \$args"]
00229
00230 return [eval $classinfo(-createentityparsercommand) [list $name $new] $args]
00231 }
00232
00233 free {
00234 eval $classinfo(-deletecommand) [list $name]
00235 unset data
00236 uplevel 1 [list rename $name {}]
00237 }
00238
00239 get {
00240 eval $classinfo(-getcommand) [list $name] $args
00241 }
00242
00243 parse {
00244 if {[llength $args] < 1} {
00245 return -code error "wrong number of arguments, should be $name parse xml ?options?"
00246 }
00247 eval $classinfo(-parsecommand) [list $name] $args
00248 }
00249
00250 re {
00251 eval = $classinfo(-recommand = ) [list $name]
00252 }
00253
00254 default {
00255 return -code error "unknown ret "
00256 }
00257 }
00258
00259 return ()
00260 }
00261
00262 # xml::noop --
00263 #
00264 # Do nothing utility proc
00265 #
00266 # Arguments:
00267 # args whatever
00268 #
00269 # Results:
00270 # Nothing happens
00271
00272 proc xml::noop args {}
00273