File: random.tcl

package info (click to toggle)
moodss 19.7-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 6,136 kB
  • ctags: 3,149
  • sloc: tcl: 49,048; ansic: 187; perl: 178; makefile: 166; sh: 109; python: 65
file content (182 lines) | stat: -rw-r--r-- 13,140 bytes parent folder | download
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
# copyright (C) 1997-2005 Jean-Luc Fontaine (mailto:jfontain@free.fr)
# this program is free software: please read the COPYRIGHT file enclosed in this package or use the Help Copyright menu

# $Id: random.tcl,v 1.61 2005/01/02 00:45:07 jfontain Exp $

# module sample file with random data

# corresponding pkgIndex.tcl file content:
# package ifneeded random 1.45 [list source [file join $dir random.tcl]]

# Note: see version number management requirements in moodss HTML documentation (Module Development section)
package provide random [lindex {$Revision: 1.61 $} 1]

namespace eval random {                                                                    ;# namespace name must match package name
    # Module data is arranged in a single array that can be used by many views, such as tables, graphs, pies,...
    # It contains configuration values as well as dynamic data (see below and update procedure).

    # Array members are:
    # - updates: a counter traced on write by viewers monitoring this module data. Must be incremented as soon as the data has been
    #   updated. Must be initialized in the namespace body in all cases as it is used for automatic module detection (may not be
    #   changed in the initialize procedure).
    # Column numbers must be positive, starting from 0 included. Column members are:
    #   - label: the title displayed on the top cell of the data column.
    #   - type: valid types are those that the lsort command can handle, plus the clock type
    #   - message: help text that appears in a widget tip when the mouse cursor is left over the column title cell for a short
    #     while.
    #   - anchor: optional member. Column data is either centered by default (center), tucked to the left (left) or right side
    #     (right) of the column.
    # - pollTimes: in seconds. A list with the default poll time in first position. The other times can be in any order, as the core
    #   will sort them and use the lowest value as the minimum poll time value.
    #   The minimum poll seconds must be a reasonable value depending on the processing time of the update procedure.
    # - indices: an optional list that specifies the data columns that should be displayed. If not specified, all the data columns
    #   are visible. Note: visibleColumns, the previous keyword for that function, is OBSOLETE (but still supported) after moodss
    #   versions 8.22 and 11.7.
    # - columns: total number of data columns to be displayed (OBSOLETE, no longer required).
    # - sort: an optional list that defines the initial column to be used for sorting the table data and in which direction. The
    #   specified column must be visible (see indices member above).
    # - indexColumns: a list that specifies the columns required to uniquely identify a row in the table. It is optional and
    #   defaults to the column 0, unless of course you do not have a 0 column index, in which case it is mandatory to specify this
    #   list. When specified, all the columns in the list must be visible (see indices member above and in views below).
    # - helpText: displayed when the module help is launched from the main window help menu. Can be plain text or HTML formatted
    #   (<HTML> and <BODY> tags required), in which case it is properly rendered in the module help window (note: tables, frames,
    #   and may other tags are not supported: stick to formatted text at the moment).
    # - views: optional. If specified, it defines one or more views to be used in place of the default view. One table will be
    #   displayed per view. Each view is a list of array members, suitable as an argument to an "array set" command. For each view,
    #   1 member must be defined: indices (syntax and usage identical to the corresponding table member).
    #   2 members are optional: sort (syntax and usage identical to the corresponding table member), and swap, a boolean, specifies
    #   whether the data is displayed in a table with columns and rows swapped (useful when data has only a single or a couple of
    #   rows permanently).
    # - switches: optional. A list of switch / boolean pairs. A switch is a single letter or a string prepended with the - or +
    #   sign. The boolean value (0 or 1) specifies whether the switch takes an argument. If the switches member exists, an
    #   appropriate initialize procedure must be provided by the module (see initialize procedure example in this module).
    #   The core will take care of parsing the command line and reject any invalid switch / value combination for the module.
    #   The switches value may not be changed in the initialize procedure.
    #   Note: if a --daemon special option exists (must take no arguments), it is automatically set when in daemon mode (moomps).
    # - identifier: optional, ignore for moodss versions before 8.0. A string that uniquely identifies this module. It will be
    #   displayed by the core in the initial data tables title area and data cell labels in viewers. This feature can be used for
    #   example in modules that gather data from a remote host: in such a case, the identifier could be set to dataType(hostName).
    # - resizableColumns: optional. A boolean value (0 or 1) which specifies whether displayed data table(s) columns can be manually
    #   resized by the user with the mouse. Not available on a per view basis.
    # - persistent: optional (considered false if missing). A boolean value that tells whether row numbers (used by the core, along
    #   with the column numbers, to identify data cells) are identically mapped from data row keys across module instances.
    # - 64Bits: optional. A boolean value (0 or 1) which specifies whether row numbers are unsigned 64 bit integers (which requires
    #   a Tcl 8.4 or above core version). If absent or false, row numbers as unsigned 32 bit integers are assumed.
    array set data {
        updates 0
        0,label name 0,type ascii 0,message {user name}
        1,label cpu 1,type real 1,message {cpu usage in percent}
        2,label disk 2,type integer 2,message {disk usage in megabytes}
        3,label memory 3,type integer 3,message {memory usage in kilobytes}
        4,label command 4,type dictionary 4,message {command name} 4,anchor left
        pollTimes {10 5 20 30 60 120 300}
        indexColumns {0 4}
        views {
            {indices {0 1 3 4} sort {1 decreasing}}
            {indices {0 2 4} sort {2 decreasing}}
        }
        persistent 1
        switches {-a 0 --asynchronous 0 -i 0 --identify 0 --daemon 0}
    }
    if {\
       ([info exists ::env(LC_ALL)] && [string match ja* $::env(LC_ALL)]) ||\
       ([info exists ::env(LANG)] && [string match ja* $::env(LANG)])\
    } {
        set file [open random-ja.htm]
    } else {
        set file [open random.htm]                                           ;# module directory is current during the loading phase
    }
    set data(helpText) [read $file]                                   ;# initialize HTML help data from file in module sub-directory
    close $file

    # The initialize procedure, if it exists, is invoked by the core before any update occurs (update procedure invocation if the
    # module is synchronous). It can be used for module setup, although it is rather redundant with inline module namespace code
    # (namespace code outside of any module namespace procedure) for a module with no command line arguments support.
    # The initialize procedure is optional when the module does not support command line arguments, and in such a case takes no
    # arguments.
    # The initialize procedure is mandatory when the module supports command line arguments, and in such a case takes an array name
    # as sole argument. The array contains the switched options values, indexed by switch. For example, if the command line was:
    # $ moodss random --asynchronous --other-option value -x 1234
    # the options array will contain:
    #   options(--asynchronous) =
    #   options(--other-option) = value
    #   options(-x)             = 1234
    # Note that the --asynchronous member value is empty as that switch takes no argument.
    # For the above example, switches would have been defined as:
    #   switches {-a 0 --asynchronous 0 --other-option 1 -x 1}
    # In all cases, data members other than updates and switches can be set or updated in the initialize procedure, and taken into
    # account by the core.
    proc initialize {optionsName} {
        upvar 1 $optionsName options
        variable asynchronous
        variable data

        set asynchronous [expr {[info exists options(-a)] || [info exists options(--asynchronous)]}]
        if {$asynchronous} {
            # for a module to be asynchronous, the pollTimes member must be a single negative integer value. It then represents the
            # preferred time interval for viewers that require one.
            array set data {pollTimes -10}
            after 3000 random::update                                                                             ;# boot simulation
        }
        if {[info exists options(-i)] || [info exists options(--identify)]} {                 ;# generate a unique module identifier
            set data(identifier) "random [expr {int(rand() * 100)}]"
        }
        if {[package vcompare $::tcl_version 8.4] < 0} {
            set data(64Bits) 0
        } else {                                                                                                ;# Tcl 8.4 and above
            set data(64Bits) 1
        }
    }

    # The terminate procedure if it exists is invoked by the core when the module is unloaded dynamically.
    proc terminate {} {
        # We could do some cleanup chores right here.
    }

    # The dynamic data array index is the row number followed by the column number separated by a comma.
    # The column number must start from 0 up to the total number of columns minus 1 (no holes are allowed in the column sequence)
    # The row number can take any positive integer value (between 0 and 4294967295) and be defined in any order. Holes in the rows
    # sequence are allowed as well: row numbers need not be consecutive (also see HTML developer documentation on handling unsigned
    # 32 bit integers, database implications and row/key relationship)
    # If a row has to disappear, all data cells for that row must disappear, that is cells for all columns.
    # Voidness for numeric data cells (integer or real type) takes the form of the ? character. Reminder: as long as a data row
    # exists, all its data cells must exist. Thus voidness cannot be expressed by non-existence.

    # The update procedure is mandatory only for synchronous modules, as it is never invoked by the core for asynchronous modules.
    # Its function is to update module data.
    proc update {} {
        variable data
        variable asynchronous

        array set data "
            0,0 John\\nWo 0,1 [format %.1f [expr {rand() * 30}]] 0,2 [expr {100 + int(rand() * 50)}]
                0,3 [expr {10 + int(rand() * 50)}] 0,4 cc
            1,0 Bill 1,1 [format %.1f [expr {rand() * 3}]] 1,2 [expr {300 + int(rand() * 100)}]
                1,3 [expr {30 + int(rand() * 100)}] 1,4 xedit
            2,0 Anny\\nDoe 2,1 [format %.1f [expr {rand() * 5}]] 2,2 [expr {200 + int(rand() * 30)}]
                2,3 [expr {20 + int(rand() * 30)}] 2,4 ps
            4,0 Peter\\nWard 4,1 [format %.1f [expr {rand() * 8}]] 4,2 [expr {50 + int(rand() * 10)}]
                4,3 [expr {5 + int(rand() * 10)}] 4,4 ls
            2147483647,0 Laura 2147483647,1 [format %.1f [expr {rand() * 20}]] 2147483647,2 [expr {90 + int(rand() * 20)}]
                2147483647,3 [expr {9 + int(rand() * 20)}] 2147483647,4 emacs
            2147483648,0 Robert 2147483648,1 [format %.1f [expr {rand() * 10}]] 2147483648,2 [expr {500 + int(rand() * 150)}]
                2147483648,3 [expr {50 + int(rand() * 150)}] 2147483648,4 top
        "
        if {[package vcompare $::tcl_version 8.4] < 0} {
            array set data "
                4294967295,0 Laura 4294967295,1 [format %.1f [expr {rand() * 30}]] 4294967295,2 [expr {100 + int(rand() * 50)}]
                    4294967295,3 [expr {10 + int(rand() * 50)}] 4294967295,4 cc
            "
        } else {                                                                                     ;# Tcl 8.4, with 64 bit support
            array set data "
                18446744073709551615,0 Laura 18446744073709551615,1 [format %.1f [expr {rand() * 30}]]
                    18446744073709551615,2 [expr {100 + int(rand() * 50)}] 18446744073709551615,3 [expr {10 + int(rand() * 50)}]
                    18446744073709551615,4 cc
            "
        }
        incr data(updates)                                   ;# increment updates counter so that update can be detected by the core
        if {$asynchronous} {                                                         ;# simulate asynchronous operation if requested
            after [expr {2000 + round(rand() * 9000)}] random::update
        }
    }
}