This file is indexed.

/usr/share/tcltk/tklib0.6/diagrams/application.tcl is in tklib 0.6-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
## -*- tcl -*-
## (C) 2010 Andreas Kupries <andreas_kupries@users.sourceforge.net>
## BSD Licensed
# # ## ### ##### ######## ############# ######################

#
# application on top of the diagram drawing package.
#

## Use Cases
## (1) Reading a single diagram file and showing it on a canvas.

## (1a) Like (1), for multiple input files. This requires an additional
##     selection step before the diagram is shown.

## (2) Convert one or more diagram files into raster images in various
##     formats.

# # ## ### ##### ######## ############# #####################
## Command syntax

## (Ad 1)  show picfile
## (Ad 1a) show picfile picfile...

## (Ad 2)  convert -o output-file-or-dir format picfile
##         convert -o output-dir         format picfile picfile...

# # ## ### ##### ######## ############# #####################
## Requirements

package require Tcl 8.5
package require Tk  8.5
package require fileutil

wm withdraw . ; # Hide the main toplevel until we actually need it, if
		# ever.
namespace eval ::diagram::application {}

# # ## ### ##### ######## ############# #####################
## Implementation

proc ::diagram::application {arguments} {
    variable application::mode
    application::ProcessCmdline $arguments
    application::Run::$mode
    return
}

proc ::diagram::application::showerror {text} {
    global argv0
    puts stderr "$argv0: $text"
    exit 1
}

# # ## ### ##### ######## ############# #####################
## Internal data and status

namespace eval ::diagram::application {
    # Path to where the output goes to. Depending on the chosen mode
    # this information may be irrelevant, a file, or a directory.
    # Specified through the option '-o' where suitable.

    variable  output ""

    # Paths of the documents to convert. Always a list, even in the
    # case of a single input file. Specified through the trailing
    # arguments on the command line. The relative path of a file under
    # 'input' also becomes its relative path under 'output'.

    variable  input  ""

    # The name of the format to convert the diagram documents
    # into. Used as extension for the generated files as well when
    # converting multiple files. Internally this is the name of the
    # canvas::* or img::* package for the image format. The two cases
    # are distinguished by the value of the boolean flag "snap". True
    # indicates a raster format via img::*, false a canvas::* dump
    # package ... FUTURE :: Should have a 'canvas::write::*' or
    # somesuch family of packages which hide this type of difference
    # from us.

    variable  format ""
    variable  snap   0

    # Name of the found processing mode. Derived during processing all
    # arguments on the command line. This value is used during the
    # dispatch to the command implementing the mode, after processing
    # the command line.
    #
    # Possible/Legal values:	Meaning
    # ---------------------	-------
    # ---------------------	-------

    variable  mode   ""
}

# # ## ### ##### ######## ############# #####################
##

proc ::diagram::application::ProcessCmdline {arguments} {
    variable input  {} ; # Set defaults.
    variable output "" ; #
    variable format "" ; #
    variable mode   "" ; #

    # syntax: show file...
    #         convert -o output format file...

    if {[llength $arguments] < 2} Usage
    set arguments [lassign $arguments command]

    switch -exact -- $command {
	show    {ProcessShow    $arguments}
	convert {ProcessConvert $arguments}
	default Usage
    }

    set mode $command
    return
}

proc ::diagram::application::ProcessShow {arguments} {
    if {[llength $arguments] < 1} Usage
    variable input   {}
    variable trusted 0

    # Basic option processing and validation.
    while {[llength $arguments]} {
        set opt [lindex $arguments 0]
        if {![string match "-*" $opt]} break

        switch -exact -- $opt {
            -t {
                if {[llength $arguments] < 1} Usage
                set arguments [lassign $arguments _opt_]
                set trusted 1
            }
            default Usage
        }
    }

    set input $arguments
    CheckInput
    return
}

proc ::diagram::application::ProcessConvert {arguments} {
    variable output ""
    variable input  {}
    variable format ""
    variable trusted 0

    if {[llength $arguments] < 4} Usage

    # Basic option processing and validation.
    while {[llength $arguments]} {
	set opt [lindex $arguments 0]
	if {![string match "-*" $opt]} break

	switch -exact -- $opt {
	    -o {
		if {[llength $arguments] < 2} Usage
		set arguments [lassign $arguments _opt_ output]
	    }
            -t {
                if {[llength $arguments] < 1} Usage
                set arguments [lassign $arguments _opt_]
                set trusted 1
            }
	    default Usage
	}
    }
    # Format and at least one file are expected.
    if {[llength $arguments] < 2} Usage
    set input [lassign $arguments format]

    ValidateFormat
    CheckInput
    CheckOutput
    return
}

# # ## ### ##### ######## ############# #####################

proc ::diagram::application::Usage {} {
    showerror "wrong#args, expected: show file...|convert -o outputpath format file..."
    # not reached ...
}

# # ## ### ##### ######## ############# #####################
## Various complex checks on the arguments

proc ::diagram::application::ValidateFormat {} {
    variable format
    variable snap
    if {![catch {
	package require canvas::snap
	package require img::$format
	set snap 1
    } msgA]} return

    if {![catch {
	package require canvas::$format
    } msgB]} return

    showerror "Unable to handle format \"$format\", because of: $msgA and $msgB"
    return
}

proc ::diagram::application::CheckInput {} {
    variable input
    foreach f $input {
	if {![file exists $f]} {
	    showerror "Unable to find picture \"$f\""
	} elseif {![file readable $f]} {
	    showerror "picture \"$f\" not readable (permission denied)"
	}
    }
    if {[llength $input] < 1} {
	showerror "No picture(s) specified"
    }
    return
}

proc ::diagram::application::CheckOutput {} {
    variable input
    variable output

    if {$output eq ""} {
	showerror "No output path specified"
    }

    set base [file dirname $output]
    if {$base eq ""} {set base [pwd]}

    # Multiple inputs: Output must either exist as directory, or
    # output base writable so that we can create the directory.
    # Single input: As above except existence as file.

    if {![file exists $output]} {
	if {![file exists $base]} {
	    showerror "Output base path \"$base\" not found"
	}
	if {![file writable $base]} {
	    showerror "Output base path \"$base\" not writable (permission denied)"
	}
    } else {
	if {![file writable $output]} {
	    showerror "Output path \"$output\" not writable (permission denied)"
	}

	if {[llength $input] > 1} {
	    if {![file isdirectory $output]} {
		showerror "Output path \"$output\" not a directory"
	    }
	} else {
	    if {![file isfile $output]} {
		showerror "Output path \"$output\" not a file"
	    }
	}
    }
    return
}

# # ## ### ##### ######## ############# #####################
##

namespace eval ::diagram::application::Run::GUI {}

proc ::diagram::application::Run::show {} {
    variable ::diagram::application::input

    GUI::Show

    if {[llength $input] == 1} {
	after 100 {
	    .l selection clear 0 end
	    .l selection set   0
	    event generate .l <<ListboxSelect>>
	}
    }

    vwait __forever__
    return
}

proc ::diagram::application::Run::convert {} {
    variable ::diagram::application::input
    variable ::diagram::application::output

    set dip [MakeInterpreter]
    GUI::Convert
    PrepareOutput

    if {[llength $input] > 1} {
	foreach f $input {
	    Convert $dip $f [GetDestination $f]
	}
    } else {
	set f [lindex $input 0]
	if {[file exists $output] && [file isdirectory $output]} {
	    Convert $dip $f [GetExtension $output/[file tail $input]]
	} else {
	    Convert $dip $f $output
	}
    }

    interp delete $dip
    GUI::Close
    return
}

proc ::diagram::application::Run::Convert {dip src dst} {
    variable ::diagram::application::format
    variable ::diagram::application::snap

    puts ${src}...
    set pic [fileutil::cat $src]

    if {[catch {
	$dip eval [list D draw $pic]
    } msg]} {
	puts "FAIL $msg : $src"
    } elseif {$snap} {
	set DIA [canvas::snap .c]
	$DIA write $dst -format $format
	image delete $DIA
    } else {
	# Direct canvas dump ...
	fileutil::writeFile $dst [canvas::$format .c]
    }

    # Wipe controller state, no information transfer between pictures.
    $dip eval {D reset}
    return
}

proc ::diagram::application::Run::GUI::Show {} {
    package require widget::scrolledwindow
    #package require crosshair

    set dip [::diagram::application::Run::MakeInterpreter]

    ttk::notebook          .n
    button                 .e -text Exit -command ::exit
    widget::scrolledwindow .sl -borderwidth 1 -relief sunken
    widget::scrolledwindow .sc -borderwidth 1 -relief sunken
    widget::scrolledwindow .st -borderwidth 1 -relief sunken
    listbox                .l -width 40 -selectmode single -listvariable ::diagram::application::input
    canvas                 .c -width 800 -height 600 -scrollregion {-4000 -4000 4000 4000}
    text                   .t -font {Arial 20}

    .sl setwidget .l
    .sc setwidget .c
    .st setwidget .t

    pack .e  -fill none -expand 0 -side bottom -anchor e

    #panedwindow .p -orient vertical
    #.p add .sl .sc
    #.p paneconfigure .sl -width 100

    pack .sl -fill both -expand 1 -padx 4 -pady 4 -side left
    pack .n -fill both -expand 1 -padx 4 -pady 4 -side right

    .n add .sc -state normal -sticky swen -text Diagram
    .n add .st -state normal -sticky swen -text Code

    bind .l <<ListboxSelect>> [list ::diagram::application::Run::GUI::ShowPicture $dip]

    # Panning via mouse
    bind .c <ButtonPress-2> {%W scan mark   %x %y}
    bind .c <B2-Motion>     {%W scan dragto %x %y}

    # Cross hairs ...
    #.c configure -cursor tcross
    #crosshair::crosshair .c -width 0 -fill \#999999 -dash {.}
    #crosshair::track on  .c TRACK

    wm deiconify .
    return
}

proc ::diagram::application::Run::GUI::ShowPicture {dip} {

    set selection [.l curselection]
    if {![llength $selection]} return

    $dip eval {catch {D destroy}}
    $dip eval {diagram D .c}

    set pic [fileutil::cat [.l get $selection]]

    .t delete 0.1 end
    .t insert 0.1 $pic

    after 0 [list $dip eval [list D draw $pic]]
    return
}

proc ::diagram::application::Run::GUI::Convert {} {
    canvas .c -width 800 -height 600 -scrollregion {0 0 1200 1000}
    grid   .c -row 0 -column 0 -sticky swen

    grid rowconfigure    . 0 -weight 1
    grid columnconfigure . 0 -weight 1

    wm attributes     . -fullscreen 1
    wm deiconify      .
    tkwait visibility .
    return
}

proc ::diagram::application::Run::GUI::Close {} {
    wm withdraw .
    destroy     .
    return
}

proc ::diagram::application::Run::PrepareOutput {} {
    variable ::diagram::application::input
    variable ::diagram::application::output

    if {[llength $input] > 1} {
	file mkdir [file dirname $output]
    }
    return
}

proc ::diagram::application::Run::GetDestination {f} {
    variable ::diagram::application::output

    if {[file pathtype $f] ne "relative"} {
	return set f [file join $output {*}[lrange [file split $f] 1 end]]
    } else {
       set f $output/$f
    }
    file mkdir [file dirname $f]
    return [GetExtension $f]
}

proc ::diagram::application::Run::GetExtension {f} {
    variable ::diagram::application::format
    return [file rootname $f].$format
}

proc ::diagram::application::Run::MakeInterpreter {} {
    variable ::diagram::application::trusted
    set sec [expr {[lindex [time {
        if {$trusted} {
            puts {Creating trusted environment, please wait...}
            set dip [interp create]
            $dip eval [list set auto_path $::auto_path]
        } else {
            puts {Creating safe environment, please wait...}
	    set dip [::safe::interpCreate]
        }
	interp alias $dip .c {} .c ; # Import of canvas
	interp alias $dip tk {} tk ; # enable tk scaling
	$dip eval {package require diagram}
	$dip eval {diagram D .c}
    }] 0]/double(1e6)}]
    puts "... completed in $sec seconds."
    after 100
    return $dip
}

# # ## ### ##### ######## ############# #####################
package provide diagram::application 1.2
return