This file is indexed.

/usr/share/tcltk/xotcl1.6.7-serialize/Serializer.xotcl is in xotcl 1.6.7-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
# $Id: Serializer.xotcl,v 1.19 2007/10/05 09:06:00 neumann Exp $
package require XOTcl 1.5
package provide xotcl::serializer 1.0

namespace eval ::xotcl::serializer {

  namespace import -force ::xotcl::*

  @ @File {
    description {
      This package provides the class Serializer, which can be used to
      generate a snapshot of the current state of the workspace
      in the form of XOTcl source code.
    }
    authors {
      Gustaf Neumann, Gustaf.Neumann@wu-wien.ac.at
    }
    date { $Date: 2007/10/05 09:06:00 $ }
  }
  
  @ Serializer proc all {
		 ?-ignoreVarsRE RE? 
		 "provide regular expression; matching vars are ignored"
		 ?-ignore obj1 obj2 ...? 
		 "provide a list of objects to be omitted"} {
    Description {
      Serialize all objects and classes that are currently 
      defined (except the specified omissions and the current
	       Serializer object). 
      <p>Examples:<@br>
      <@pre class='code'>Serializer all -ignoreVarsRE {::b$}</@pre>
      Do not serialize any instance variable named b (of any object).<p>
      <@pre class='code'>Serializer all -ignoreVarsRE {^::o1::.*text.*$|^::o2::x$}</@pre>
      Do not serialize any variable of c1 whose name contains 
      the string "text" and do not serialze the variable x of o2.<p>
      <@pre class='code'>Serializer all -ignore obj1 obj2 ... </@pre>
      do not serizalze the specified objects
    }
    return "script"
  }
  
  @ Serializer proc deepSerialize {
		   objs "Objects to be serialized"
		   ?-ignoreVarsRE&nbsp;RE? 
		   "provide regular expression; matching vars are ignored"
		   ?-ignore&nbsp;obj1&nbsp;obj2&nbsp;...? 
		   "provide a list of objects to be omitted"
		   ?-map&nbsp;list? "translate object names in serialized code"
				 } {
    Description {
      Serialize object with all child objects (deep operation) 
      except the specified omissions. For the description of 
      <@tt>ignore</@tt> and <@tt>igonoreVarsRE</@tt> see 
      <@tt>Serizalizer all</@tt>. <@tt>map</@tt> can be used
      in addition to provide pairs of old-string and new-string
      (like in the tcl command <@tt>string map</@tt>). This option
      can be used to regenerate the serialized object under a different
      object or under an different name, or to translate relative
      object names in the serialized code.<p>
      
      Examples:  
      <@pre class='code'>Serializer deepSerialize ::a::b::c -map {::a::b ::x::y}</@pre>
      Serialize the object <@tt>c</@tt> which is a child of <@tt>a::b</@tt>; 
      the object will be reinitialized as object <@tt>::x::y::c</@tt>,
      all references <@tt>::a::b</@tt> will be replaced by <@tt>::x::y</@tt>.<p>
      
      <@pre class='code'>Serializer deepSerialize ::a::b::c -map {::a::b [self]}</@pre>
      The serizalized object can be reinstantiated under some current object,
      under which the script is evaluated.<p>
      
      <@pre class='code'>Serializer deepSerialize ::a::b::c -map {::a::b::c ${var}}</@pre>
      The serizalized object will be reinstantiated under a name specified
      by the variable <@tt>var<@tt> in the recreation context.
    }
    return "script"
  }
  
  @ Serializer proc methodSerialize {
		     object "object or class"
		     method "name of method"
		     prefix "either empty or 'inst' (latter for instprocs)"
				   } {
    Description {
      Serialize the specified method. In order to serialize 
      an instproc, <@tt>prefix</@tt> should be 'inst'; to serialze
      procs, it should be empty.<p> 
      
      Examples:
      <@pre class='code'>Serializer methodSerialize Serializer deepSerialize ""</@pre>
      This command serializes the proc <@tt>deepSerialize</@tt> 
      of the Class <@tt>Serializer</@tt>.<p>
      
      <@pre class='code'>Serializer methodSerialize Serializer serialize inst</@pre>
      This command serializes the instproc <@tt>serialize</@tt> 
      of the Class <@tt>Serializer</@tt>.<p>
    }
    return {Script, which can be used to recreate the specified method}
  }
  @ Serializer proc exportMethods {
	list "list of methods of the form 'object proc|instproc methodname'" 
      } {
    Description {
      This method can be used to specify methods that should be
      exported in every <@tt>Serializer all<@/tt>. The rationale
      behind this is that the serializer does not serialize objects
      from the ::xotcl:: namespace, which is used for XOTcl internals
      and volatile objects. It is however often useful to define
      methods on ::xotcl::Class or ::xotcl::Objects, which should
      be exported. One can export procs, instprocs, forward and instforward<p>
      Example:
      <@pre class='code'>      Serializer exportMethods {
	::xotcl::Object instproc __split_arguments
	::xotcl::Object instproc __make_doc
	::xotcl::Object instproc ad_proc
	::xotcl::Class  instproc ad_instproc
	::xotcl::Object forward  expr
      }<@/pre>
    }
  }
  
  
  @ Serializer instproc serialize {entity "Object or Class"} {
    Description {
      Serialize the specified object or class.
    }
    return {Object or Class with all currently defined methods, 
      variables, invariants, filters and mixins}
  }
  
  ##################################################################################
  # real clode starts here.....
  # ################################################################################
  Class Serializer -parameter {ignoreVarsRE map}
  namespace export Serializer

  Serializer proc ignore args {
    my set skip $args
  }
  Serializer instproc ignore args {
    foreach i $args { 
      my set skip($i) 1
      # skip children of ignored objects as well
      foreach j [$i info children] {
	my ignore $j
      }
    }
  }
  Serializer instproc init {} {
    my ignore [self] 
    if {[[self class] exists skip]} {
      eval my ignore [[self class] set skip]
    }
  }
  Serializer instproc method-serialize {o m prefix} {
    my pcmd [my unescaped-method-serialize $o $m $prefix]
  }
  Serializer instproc unescaped-method-serialize {o m prefix} {
    set arglist [list]
    foreach v [$o info ${prefix}args $m] {
      if {[$o info ${prefix}default $m $v x]} {
	lappend arglist [list $v $x] } {lappend arglist $v}
    }
    lappend r ${prefix}proc $m \
	[concat [$o info ${prefix}nonposargs $m] $arglist] \
	[$o info ${prefix}body $m]
    foreach p {pre post} {
      if {[$o info ${prefix}$p $m]!=""} {lappend r [$o info ${prefix}$p $m]}
    }
    return $r
  }
  Serializer instproc pcmd list {
    foreach a $list {
      if {[regexp -- {^-[[:alpha:]]} $a]} {
	set mustEscape 1
	break
      }
    }
    if {[info exists mustEscape]} {
      return "\[list -$list\]"
    } else {
      return -$list
    }
  }
  Serializer instproc collect-var-traces o {
    my instvar traces
    foreach v [$o info vars] {
      set t [$o __trace__ info variable $v]
      if {$t ne ""} {
	foreach ops $t { 
	  foreach {op cmd} $ops break
	  # save traces in post_cmds
	  my append post_cmds [list $o trace add variable $v $op $cmd] "\n"
	  # remove trace from object
	  $o trace remove variable $v $op $cmd
	}
      }
    }
  }
  Serializer instproc Object-serialize o {
    my collect-var-traces $o
    append cmd [list [$o info class] create [$o self]]
    # slots needs to be initialized when optimized, since
    # parametercmds are not serialized
    #if {![$o istype ::xotcl::Slot]} {append cmd " -noinit"}
    append cmd " -noinit"
    append cmd " \\\n"
    foreach i [$o info procs] {
      append cmd " " [my method-serialize $o $i ""] " \\\n"
    }
    foreach i [$o info forward] {
      set fwd [concat [list forward $i] [$o info forward -definition $i]]
      append cmd \t [my pcmd $fwd] " \\\n"
    }
    foreach i [$o info parametercmd] {
      append cmd \t [my pcmd [list parametercmd $i]] " \\\n"
    }
    set vset {}
    set nrVars 0
    foreach v [$o info vars] {
      set setcmd [list]
      if {![my exists ignoreVarsRE] || 
	  ![regexp [my set ignoreVarsRE] ${o}::$v]} {
	if {[$o array exists $v]} {
	  lappend setcmd array set $v [$o array get $v]
	} else {
	  lappend setcmd set $v [$o set $v]
	}
	incr nrVars
	append cmd \t [my pcmd $setcmd] " \\\n"
      }
    }
    foreach x {mixin invar} {
      set v [$o info $x]
      if {$v ne ""} {my append post_cmds [list $o $x set $v] "\n"}
    }
    set v [$o info filter -guards]
    if {$v ne ""} {append cmd [my pcmd [list filter $v]] " \\\n"}
    return $cmd
  }
  Serializer instproc Class-serialize o {
    set cmd [my Object-serialize $o]
    #set p [$o info parameter]
    #if {$p ne ""} {
    #  append cmd " " [my pcmd [list parameter $p]] " \\\n"
    #}
    foreach i [$o info instprocs] {
      append cmd " " [my method-serialize $o $i inst] " \\\n"
    }
    foreach i [$o info instforward] {
      set fwd [concat [list instforward $i] [$o info instforward -definition $i]]
      append cmd \t [my pcmd $fwd] " \\\n"
    }
    foreach i [$o info instparametercmd] {
      append cmd \t [my pcmd [list instparametercmd $i]] " \\\n"
    }
    foreach x {superclass instinvar} {
      set v [$o info $x]
      if {$v ne "" && "::xotcl::Object" ne $v } {
	append cmd " " [my pcmd [list $x $v]] " \\\n"
      }
    }
    foreach x {instmixin} {
      set v [$o info $x]
      if {$v ne "" && "::xotcl::Object" ne $v } {
        my append post_cmds [list $o $x set $v] "\n"
	#append cmd " " [my pcmd [list $x $v]] " \\\n"
      }
    }
    set v [$o info instfilter -guards]
    if {$v ne ""} {append cmd [my pcmd [list instfilter $v]] " \\\n"}
    return $cmd\n
  }
  
  Serializer instproc args {o prefix m} {
    foreach v [$o info ${prefix}args $m] {
      if {[$o info ${prefix}default $m $v x]} {
	lappend arglist [list $v $x] } {
	  lappend arglist $v }
    }
    return $arglist
  }
  Serializer instproc category c {
    if {[$c istype ::xotcl::Class]} {return Class} {return Object}
  }
  Serializer instproc allChildren o {
    set set $o
    foreach c [$o info children] {
      foreach c2 [my allChildren $c] {
	lappend set $c2
      }
    }
    return $set
  }
  Serializer instproc allInstances C {
    set set [$C info instances]
    foreach sc [$C info subclass] {
      foreach c2 [my allInstances $sc] {
	lappend set $c2
      }
    }
    return $set
  }
  Serializer instproc exportedObject o {
    # check, whether o is exported. for exported objects.
    # we export the object tree.
    set oo $o
    while {1} {
      if {[[self class] exists exportObjects($o)]} {
        #puts stderr "exported: $o -> exported $oo"
        return 1
      }
      # we do this for object trees without object-less name spaces
      if {![my isobject $o]} {return 0}
      set o [$o info parent]
    }
  }
  
  Serializer instproc topoSort {set all} {
    if {[my array exists s]} {my array unset s}
    if {[my array exists level]} {my array unset level}
    foreach c $set {
      if {!$all &&
	  [string match "::xotcl::*" $c] && 
	  ![my exportedObject $c]} continue
      if {[my exists skip($c)]} continue
      my set s($c) 1
    }
    set stratum 0
    while {1} {
      set set [my array names s]
      if {[llength $set] == 0} break
      incr stratum
      #my warn "$stratum set=$set"
      my set level($stratum) {}
      foreach c $set {
	if {[my [my category $c]-needsNothing $c]} {
	  my lappend level($stratum) $c
	}
      }
      if {[my set level($stratum)] eq ""} {
	my set level($stratum) $set
	my warn "Cyclic dependency in $set"
      }
      foreach i [my set level($stratum)] {my unset s($i)}
    }
  }
  Serializer instproc warn msg {
    if {[info command ns_log] ne ""} {
      ns_log Notice $msg
    } else {
      puts stderr "!!! $msg"
    }
  }
  
  Serializer instproc Class-needsNothing x {
    if {![my Object-needsNothing $x]}         {return 0}
    set scs [$x info superclass]
    if {[my needsOneOf $scs]} {return 0}
    foreach sc $scs {if {[my needsOneOf [$sc info slots]]} {return 0}}
    #if {[my needsOneOf [$x info instmixin ]]} {return 0}
    return 1
  }
  Serializer instproc Object-needsNothing x {
    set p [$x info parent]
    if {$p ne "::"  && [my needsOneOf $p]} {return 0}
    if {[my needsOneOf [$x info class]]}  {return 0}
    if {[my needsOneOf [[$x info class] info slots]]}  {return 0}
    #if {[my needsOneOf [$x info mixin ]]} {return 0}
    return 1
  }
  Serializer instproc needsOneOf list {
    foreach e $list {if {[my exists s($e)]} {
      #upvar x x; puts stderr "$x needs $e"
      return 1
    }}
    return 0
  }
  Serializer instproc serialize {objectOrClass} {
    string trimright [my [my category $objectOrClass]-serialize $objectOrClass] "\\\n"
  }
  Serializer instproc serialize-objects {list all} {
    my instvar post_cmds
    set post_cmds ""
    # register for introspection purposes "trace" under a different name
    ::xotcl::alias ::xotcl::Object __trace__ -objscope ::trace
    my topoSort $list $all
    #foreach i [lsort [my array names level]] {my warn "$i: [my set level($i)]"}
    set result ""
    foreach l [lsort -integer [my array names level]] {
      foreach i [my set level($l)] {
	#my warn "serialize $i"
        #append result "# Stratum $l\n"
	append result [my serialize $i] \n
      }
    }
    foreach e $list {
      set namespace($e) 1
      set namespace([namespace qualifiers $e]) 1
    }
    ::xotcl::Object instproc __trace__ {} {}

    # Handling of variable traces: traces might require a 
    # different topological sort, which is hard to handle.
    # Similar as with filters, we deactivate the variable
    # traces during initialization. This happens by
    # (1) replacing the XOTcl's trace method by a no-op
    # (2) collecting variable traces through collect-var-traces
    # (3) re-activating the traces after variable initialization

    set exports ""
    set pre_cmds ""

    # delete ::xotcl from the namespace list, if it exists...
    catch {unset namespace(::xotcl)}
    foreach ns [array name namespace] {
      if {![namespace exists $ns]} continue
      if {![my isobject $ns]} {
	append pre_cmds "namespace eval $ns {}\n"
      } elseif {$ns ne [namespace origin $ns] } {
	append pre_cmds "namespace eval $ns {}\n"
      }
      set exp [namespace eval $ns {namespace export}]
      if {$exp ne ""} {
	append exports "namespace eval $ns {namespace export $exp}" \n
      }
    }

    #append post_cmds "::xotcl::alias ::xotcl::Object trace -objscope ::trace\n"
    return $pre_cmds$result$post_cmds$exports
  }
  Serializer instproc deepSerialize o {
    # assumes $o to be fully qualified
    my serialize-objects [my allChildren $o] 1
  }
  Serializer instproc serializeMethod {object kind name} {
    set code ""
    switch $kind {
      proc {
	if {[$object info procs $name] ne ""} {
	  set code [my method-serialize $object $name ""]
	}
      }
      instproc {
	if {[$object info instprocs $name] ne ""} {
	  set code [my method-serialize $object $name inst]
	}
      }
      forward - instforward {
	if {[$object info $kind $name] ne ""} {
	  set fwd [concat [list $kind $name] [$object info $kind -definition $name]]
	  set code [my pcmd $fwd]
	}
      }
    }
    return $code
  } 

 
  Serializer proc exportMethods list {
    foreach {o p m} $list {my set exportMethods($o,$p,$m) 1}
  }
  Serializer proc exportObjects list {
    foreach o $list {my set exportObjects($o) 1}
  }

  Serializer proc serializeExportedMethods {s} {
    set r ""
    foreach k [my array names exportMethods] {
      foreach {o p m} [split $k ,] break
      #if {$o ne "::xotcl::Object" && $o ne "::xotcl::Class"} {
	#error "method export only for ::xotcl::Object and\
	#	::xotcl::Class implemented, not for $o"
      #}
      if {![string match "::xotcl::*" $o]} {
        error "method export is only for ::xotcl::* \
          object an classes implemented, not for $o"
      }
      append methods($o) [$s serializeMethod $o $p $m] " \\\n "      
    }
    set objects [array names methods]
    foreach o [list ::xotcl::Object ::xotcl::Class] {
      set p [lsearch $o $objects]
      if {$p == -1} continue
      set objects [lreplace $objects $p $p]
    }
    foreach o [concat ::xotcl::Object ::xotcl::Class $objects] {
      if {![info exists methods($o)]} continue
      append r \n "$o configure \\\n " \
	  [string trimright $methods($o) "\\\n "] 
    }
    #puts stderr "... exportedMethods <$r\n>"
    return "$r\n"
  }

  Serializer proc all {args} {
    # don't filter anything during serialization
    set filterstate [::xotcl::configure filter off]
    set s [eval my new -childof [self] -volatile $args]
    # always export __exitHandler
    my exportMethods [list ::xotcl::Object proc __exitHandler]
    set r {
      set ::xotcl::__filterstate [::xotcl::configure filter off]
      ::xotcl::Object instproc trace args {}
      ::xotcl::Slot instmixin add ::xotcl::Slot::Nocheck
    } 
    append r "::xotcl::configure softrecreate [::xotcl::configure softrecreate]"
    append r \n [my serializeExportedMethods $s]
    # export the objects and classes
    #$s warn "export objects = [my array names exportObjects]"
    #$s warn "export objects = [my array names exportMethods]"
    append r [$s serialize-objects [$s allInstances ::xotcl::Object] 0]    
    foreach o [list ::xotcl::Object ::xotcl::Class] {
      foreach x {mixin instmixin invar instinvar} {
	set v [$o info $x]
	if {$v ne ""  && $v ne "::xotcl::Object"} {
	  append r "$o configure " [$s pcmd [list $x $v]] "\n"
	}
      }
    }
    append r {
      ::xotcl::alias ::xotcl::Object trace -objscope ::trace
      ::xotcl::Slot instmixin delete ::xotcl::Slot::Nocheck
      ::xotcl::configure filter $::xotcl::__filterstate
      unset ::xotcl::__filterstate
    }
    ::xotcl::configure filter $filterstate
    return $r
  }
  Serializer proc methodSerialize {object method prefix} {
    set s [my new -childof [self] -volatile]
    concat $object [$s unescaped-method-serialize $object $method $prefix]
  }
  Serializer proc deepSerialize args {
    set s [my new -childof [self] -volatile]
    set nr [eval $s configure $args]
    foreach o [lrange $args 0 [incr nr -1]] {
      append r [$s deepSerialize [$o]]
  }
    if {[$s exists map]} {return [string map [$s map] $r]}
    return $r
  }

  # register serialize a global method
  ::xotcl::Object instproc serialize {} {
    ::Serializer deepSerialize [self]
  }

  # include this method in the serialized code
  Serializer exportMethods {
    ::xotcl::Object instproc contains
  }

  # include Serializer in the serialized code
  Serializer exportObjects [namespace current]::Serializer

  namespace eval :: "namespace import -force [namespace current]::*"
}