ADDED embedded/www/tcllib/files/modules/clay/clay.html Index: embedded/www/tcllib/files/modules/clay/clay.html ================================================================== --- /dev/null +++ embedded/www/tcllib/files/modules/clay/clay.html @@ -0,0 +1,491 @@ + +
clay - A minimalist framework for large scale OO Projects
+Clay introduces a method ensemble to both oo::class and oo::object called +clay. This ensemble handles all of the high level interactions within the framework. +Clay stores structured data. Clan manages method delegation. Clay has facilities to +manage the complex interactions that come about with mixins.
+The central concept is that inside of every object and class +(which are actually objects too) is a dict called clay. What is stored in that dict is +left to the imagination. But because this dict is exposed via a public method, we can +share structured data between object, classes, and mixins.
+Clay uses a standardized set of method interactions and introspection that TclOO already provides to perform on-the-fly searches. On-the-fly searches mean that the data is never stale, and we avoid many of the sorts of collisions that would arise when objects start mixing in other classes during operation.
+The clay methods for both classes and objects have a get and a set method. For objects, get will search through the local clay dict. If the requested leaf is not found, or the query is for a branch, the system will then begin to poll the clay methods of all of the class that implements the object, all of that classes’ ancestors, as well as all of the classes that have been mixed into this object, and all of their ancestors.
+Intended branches on a tree end with a directory slash (/). Intended leaves are left unadorned. This is a guide for the tool that builds the search +results to know what parts of a dict are intended to be branches and which are intended to be leaves. +For simple cases, branch marking can be ignored:
++::oo::class create ::foo { } +::foo clay set property/ color blue +::foo clay set property/ shape round +set A [::foo new] +$A clay get property/ +{color blue shape round} +$A clay set property/ shape square +$A clay get property/ +{color blue shape square} ++
But when you start storing blocks of text, guessing what field is a dict and what isn’t gets messy:
++::foo clay set description {A generic thing of designated color and shape} +$A clay get description +{A generic thing of designated color and shape} +Without a convention for discerning branches for leaves what should have been a value can be accidentally parsed as a dictionary, and merged with all of the other values that were never intended to be merge. Here is an example of it all going wrong: +::oo::class create ::foo { } +# Add description as a leaf +::foo clay set description {A generic thing of designated color and shape} +# Add description as a branch +::foo clay set description/ {A generic thing of designated color and shape} +::oo::class create ::bar { + superclass foo +} +# Add description as a leaf +::bar clay set description {A drinking establishment of designated color and shape and size} +# Add description as a branch +::bar clay set description/ {A drinking establishment of designated color and shape and size} +set B [::bar new] +# As a leaf we get the value verbatim from he nearest ancestor +$B clay get description + {A drinking establishment of designated color and shape and size} +# As a branch we get a recursive merge +$B clay get description/ +{A drinking establishment of designated color and size thing of} ++
Clay is built using the oo::dialect module from Tcllib. oo::dialect allows you to either add keywords directly to clay, or to create your own +metaclass and keyword set using Clay as a foundation. For details on the keywords and what they do, consult the functions in the ::clay::define namespace.
+Method Delegation +It is sometimes useful to have an external object that can be invoked as if it were a method of the object. Clay provides a delegate ensemble method to perform that delegation, as well as introspect which methods are delegated in that manner. All delegated methods are marked with html-like tag markings (< >) around them.
++::clay::define counter { + Variable counter 0 + method incr {{howmuch 1}} { + my variable counter + incr counter $howmuch + } + method value {} { + my variable counter + return $counter + } + method reset {} { + my variable counter + set counter 0 + } +} +::clay::define example { + variable buffer + constructor {} { + # Build a counter object + set obj [namespace current]::counter + ::counter create $obj + # Delegate the counter + my delegate <counter> $obj + } + method line {text} { + my <counter> incr + append buffer $text + } +} +set A [example new] +$A line {Who’s line is it anyway?} +$A <counter> value +1 ++
New OO Keywords for clay
This keyword can also be expressed:
+property variable NAME {default DEFAULT}+
Variables registered in the variable property are also initialized + (if missing) when the object changes class via the morph method.
Methods
+Return this class and all ancestors in search order.
Return a complete dump of this object's clay data, but only this object's clay data.
Pull a chunk of data from the clay system. If the last element of path is a branch, + returns a recursive merge of all data from this object and it's constituent classes of the data in that branch. + If the last element is a leaf, search this object for a matching leaf, or search all constituent classes for a matching + leaf and return the first value found. + If no value is found, returns an empty string. + If a branch is returned the topmost . entry is omitted.
Pull a chunk of data from the class's clay system. + If no value is found, returns an empty string. + If a branch is returned the topmost . entry is omitted.
Pull a chunk of data from the class's clay system. + If no value is found, returns an empty string.
Recursively merge the dictionaries given into the object's local clay storage.
Replace the contents of the internal clay storage with the dictionary given.
Return the first matching value for the path in either this class's clay data or one of its ancestors
Merge the conents of value with the object's clay storage at path.
Methods
+Return the class this object belongs to, all classes mixed into this object, and all ancestors of those classes in search order.
Pull a value from either the object's clay structure or one of its constituent classes that matches the field name. + The order of search us:
+1. The as a value in local dict variable config
+2. The as a value in local dict variable clay
+3. As a leaf in any ancestor as a root of the clay tree
+4. As a leaf in any ancestor as const field
+5. As a leaf in any ancestor as option field default
Introspect or control method delegation. With no arguments, the method will return a + key/value list of stubs and objects. With just the stub argument, the method will + return the object (if any) attached to the stub. With a stub and an object + this command will forward all calls to the method stub to the object.
Return a complete dump of this object's clay data, as well as the data from all constituent classes recursively blended in.
Return a dictionary describing the method ensembles to be assembled for this object
Evaluated a script in the namespace of this object
Trigger the InitializePublic private method
Returns 1 if path exists in either the object's clay data. Values greater than one indicate the element exists in one of the object's constituent classes. A value of zero indicates the path could not be found.
Wipe any caches built by the clay implementation
A convenience wrapper for
+oo::objdefine [self] forward {*}$args+
Pull a chunk of data from the clay system. If the last element of path is a branch (ends in a slash /), + returns a recursive merge of all data from this object and it's constituent classes of the data in that branch. + If the last element is a leaf, search this object for a matching leaf, or search all constituent classes for a matching + leaf and return the first value found. + If no value is found, returns an empty string.
A modified get which is tailored to pull only leaf elements
Recursively merge the dictionaries given into the object's local clay storage.
Perform [oo::objdefine [self] mixin] on this object, with a few additional rules: + Prior to the call, for any class was previously mixed in, but not in the new result, execute the script registered to mixin/ unmap-script (if given.) + For all new classes, that were not present prior to this call, after the native TclOO mixin is invoked, execute the script registered to mixin/ map-script (if given.) + Fall all classes that are now present and “mixed in”, execute the script registered to mixin/ react-script (if given.)
With no arguments returns the map of stubs and classes mixed into the current object. When only stub is given, + returns the classes mixed in on that stub. When stub and classlist given, replace the classes currently on that stub with the given + classes and invoke clay mixin on the new matrix of mixed in classes.
Return either self if that path exists in the current object, or return the first class (if any) along the clay search path which contains that element.
Replace the contents of the internal clay storage with the dictionary given.
Source the given filename within the object's namespace
Merge the conents of value with the object's clay storage at path.
Instantiate variables. Called on object creation and during clay mixin.
clay::object + This class is inherited by all classes that have options.
+Methods
+Instantiate variables and build ensemble methods.
Sean Woods mailto:<yoda@etoyoc.com>
+This document, and the package it describes, will undoubtedly contain +bugs and other problems. +Please report such in the category oo of the +Tcllib Trackers. +Please also report any ideas for enhancements you may have for either +package and/or documentation.
+When proposing code changes, please provide unified diffs, +i.e the output of diff -u.
+Note further that attachments are strongly preferred over +inlined patches. Attachments can be made by going to the Edit +form of the ticket immediately after its creation, and then using the +left-most button in the secondary navigation bar.
+Programming tools
+Copyright © 2018 Sean Woods <yoda@etoyoc.com>
+math::trig - Trigonometric anf hyperbolic functions
+The math::trig package defines a set of trigonomic and hyperbolic functions +and their inverses. In addition it defines versions of the trigonomic functions +that take arguments in degrees instead of radians.
+For easy use these functions may be imported into the tcl::mathfunc namespace, +so that they can be used directly in the expr command.
+The functions radian_reduced and degree_reduced return a reduced angle, in +respectively radians and degrees, in the intervals [0, 2pi) and [0, 360):
+Return the equivalent angle in the interval [0, 2pi).
+Angle (in radians)
Return the equivalent angle in the interval [0, 360).
+Angle (in degrees)
The following trigonomic functions are defined in addition to the ones defined +in the expr command:
+Calculate the cosecant of the angle (1/cos(angle))
+Angle (in radians)
Calculate the secant of the angle (1/sin(angle))
+Angle (in radians)
Calculate the cotangent of the angle (1/tan(angle))
+Angle (in radians)
For these functions also the inverses are defined:
+Calculate the arc cosecant of the value
+Value of the argument
Calculate the arc secant of the value
+Value of the argument
Calculate the arc cotangent of the value
+Value of the argument
The following hyperbolic and inverse hyperbolic functions are defined:
+Calculate the hyperbolic cosecant of the value (1/sinh(value))
+Value of the argument
Calculate the hyperbolic secant of the value (1/cosh(value))
+Value of the argument
Calculate the hyperbolic cotangent of the value (1/tanh(value))
+Value of the argument
Calculate the arc hyperbolic sine of the value
+Value of the argument
Calculate the arc hyperbolic cosine of the value
+Value of the argument
Calculate the arc hyperbolic tangent of the value
+Value of the argument
Calculate the arc hyperbolic cosecant of the value
+Value of the argument
Calculate the arc hyperbolic secant of the value
+Value of the argument
Calculate the arc hyperbolic cotangent of the value
+Value of the argument
The following versions of the common trigonometric functions and their +inverses are defined:
+Calculate the sine of the angle (in degrees)
+Angle (in degrees)
Calculate the cosine of the angle (in degrees)
+Angle (in radians)
Calculate the cotangent of the angle (in degrees)
+Angle (in degrees)
Calculate the cosecant of the angle (in degrees)
+Angle (in degrees)
Calculate the secant of the angle (in degrees)
+Angle (in degrees)
Calculate the cotangent of the angle (in degrees)
+Angle (in degrees)
This document, and the package it describes, will undoubtedly contain +bugs and other problems. +Please report such in the category math :: trig of the +Tcllib Trackers. +Please also report any ideas for enhancements you may have for either +package and/or documentation.
+When proposing code changes, please provide unified diffs, +i.e the output of diff -u.
+Note further that attachments are strongly preferred over +inlined patches. Attachments can be made by going to the Edit +form of the ticket immediately after its creation, and then using the +left-most button in the secondary navigation bar.
+Mathematics
+Copyright © 2018 Arjen Markus
+dicttool - Dictionary Tools
The dicttool package enhances the standard dict command with several new commands. In addition, the package also defines several "creature comfort" list commands as well. Each command checks to see if a command already exists of the same name before adding itself, just in case any of these slip into the core.
+This command will add a new instance of each element in args to varname, but only if that element is not already present.
Return a dict which is the product of a recursive merge of all of the arguments. Unlike dict merge, this command descends into all of the levels of a dict. Dict keys which end in a : indicate a leaf, which will be interpreted as a literal value, and not descended into further.
-set items [dict merge { - option {color {default: green}} -} { - option {fruit {default: mango}} -} { - option {color {default: blue} fruit {widget: select values: {mango apple cherry grape}}} -}] -puts [dict print $items] + if {[dict exists $dictionary {*}$args]} { + return [dict get $dictionary {*}$args] + } else { + return {} + } ++
Example:
+set value [dict getnull $arglist $option] ++
Test if value is a dict.
+This command is added to the dict ensemble as dict is_dict
Return true if the element with the value + is a dict. is given as a list to descend into sub-dicts of + the current dict. + The rules are as follows:
+If the last character of the last element of is a colon (:) + return false
If the last character of the last element of is a slash (/) + return true
If a sub-element if named .info is present return true
This command is added to the dict ensemble as dicttool::is_branch
+Example:
+> set mydict {sub/ {sub/ {field {A block of text}}} + > dicttool::is_branch $mydict sub/ + 1 + > dicttool::is_branch $mydict {sub/ sub/} + 1 + > dicttool::is_branch $mydict {sub/ sub/ field} + 0 ++
Output a dictionary as an indented stream of + data suitable for output to the screen. The system uses + the rules for dicttool::is_branch to determine if + an value in a dictionary is a leaf or a branch.
+Example:
+> set mydict {sub/ {sub/ {field {A block of text}}} + > dicttool::print $mydict + sub/ { + sub/ { + field {A block of text} + } + } ++
Helper function for ::dicttool::print + Formats the string representation for a dictionary element within + a human readable stream of lines, and determines if it needs to call itself + with further indentation to express a sub-branch
Output a dictionary removing any . entries added by dicttool::merge
Helper function for ::dicttool::sanitize + Formats the string representation for a dictionary element within + a human readable stream of lines, and determines if it needs to call itself + with further indentation to express a sub-branch
Return the path as a canonical path for dicttool + with all branch keys + ending in a / and the final element ending in a / + if the final element in the path ended in a / + This command will also break arguments up if they + contain /.
+Example:
+> dicttool::canonical foo bar baz bang + foo/ bar/ baz/ bang + > dicttool::canonical foo bar baz bang/ + foo/ bar/ baz/ bang/ + > dicttool::canonical foo bar baz bang: + foo/ bar/ baz/ bang + > dicttool::canonical foo/bar/baz bang: + foo/ bar/ baz/ bang + > dicttool::canonical foo/bar/baz/bang + foo/ bar/ baz/ bang ++
Return the path as a storage path for dicttool + with all branch terminators removed. + This command will also break arguments up if they + contain /.
+Example:
+> dicttool::storage foo bar baz bang + foo bar baz bang + > dicttool::storage foo bar baz bang/ + foo bar baz bang + > dicttool::storage foo bar baz bang: + foo bar baz bang + > dicttool::storage foo/bar/baz bang: + foo bar baz bang + > dicttool::storage foo/bar/baz/bang + foo bar baz bang ++
Set an element with a recursive dictionary, + marking all branches on the way down to the + final element. + If the value does not exists in the nested dictionary + it is added as a leaf. If the value already exists as a branch + the value given is merged if the value is a valid dict. If the + incoming value is not a valid dict, the value overrides the value + stored, and the value is treated as a leaf from then on.
+Example:
+> set r {} + > ::dicttool::dictset r option color default Green + . 1 option {. 1 color {. 1 default Green}} + > ::dicttool::dictset r option {Something not dictlike} + . 1 option {Something not dictlike} + # Note that if the value is not a dict, and you try to force it to be + # an error with be thrown on the merge + > ::dicttool::dictset r option color default Blue + missing value to go with key ++
A recursive form of dict merge, intended for modifying variables in place.
+Example:
+> set mydict {sub/ {sub/ {description {a block of text}}}} + > ::dicttool::dictmerge mydict {sub/ {sub/ {field {another block of text}}}}] + > dicttool::print $mydict + sub/ { + sub/ { + description {a block of text} + field {another block of text} + } + } ++
A recursive form of dict merge
+A routine to recursively dig through dicts and merge + adapted from http://stevehavelka.com/tcl-dict-operation-nested-merge/
+Example:
+> set mydict {sub/ {sub/ {description {a block of text}}}} + > set odict [dicttool::merge $mydict {sub/ {sub/ {field {another block of text}}}}] + > dicttool::print $odict + sub/ { + sub/ { + description {a block of text} + field {another block of text} + } + } ++
Returns true if the path specified by args either does not exist, + if exists and contains an empty string or the value of NULL or null.
+This function is added to the global dict ensemble as dict isnull
Add elements to a list if that are not already present in the list. + As a side effect, if variable does not exists, + create it as an empty list.
+Example:
+ladd contents foo bar + puts $contents + > foo bar + ladd contents foo bar baz bang + puts $contents + > foo bar baz bang-
Prints the following result:
--option { - color { - default: blue - } - fruit { - widget: select - values: {mango apple cherry grape} - } -} +
Delete all instances of the elements given from a list contained in . + If the variable does exist this is a noop.
+Example:
+set contents {foo bar baz bang foo foo foo} + ldelete contents foo + puts $contents + > bar baz bang
Return a random element from
Sean Woods mailto:<yoda@etoyoc.com>
+This document, and the package it describes, will undoubtedly contain bugs and other problems. Please report such in the category dict of the Tcllib Trackers. Please also report any ideas for enhancements you may have for either @@ -206,8 +386,8 @@
Utilities
Copyright © 2017 Sean Woods <yoda@etoyoc.com>
+Copyright © 2018 Sean Woods <yoda@etoyoc.com>
This command takes the paths of one or more files and directories and -compiles all the files, and the files in all the directories into a -single recognizer for all the file types specified in these files.
+This command takes the paths of one or more files and directories and compiles +all the files, and the files in all the directories into a single analyzer for +all the file types specified in these files. It returns a list whose first +item is a list per-file dictionaries of analyzer scripts and whose second item +is a list of analyzer commands.
All the files have to be in the format specified by magic(5).
The result of the command is a Tcl script containing the generated recognizer.
This command behaves like ::fileutil::magic::cfront::compile Index: idoc/www/tcllib/files/modules/fumagic/rtcore.html ================================================================== --- idoc/www/tcllib/files/modules/fumagic/rtcore.html +++ idoc/www/tcllib/files/modules/fumagic/rtcore.html @@ -129,76 +129,51 @@
This package provides the runtime core for file type recognition engines written in pure Tcl and is thus used by all other packages in -this module, i.e. the two frontend packages -fileutil::magic::mimetypes and -fileutil::magic::filetypes, and the two engine compiler +this module such as fileutil::magic::filetype and the two compiler packages fileutil::magic::cgen and fileutil::magic::cfront.
Shorthand for incr level.
Increment the level and perform related housekeeping
Shorthand for incr level -1.
This command initializes the runtime and prepares the file -filename for use by the system. -This command has to be invoked first, before any other command of this -package.
-The command returns the channel handle of the opened file as its -result.
This command closes the last file opened via -::fileutil::magic::rt::open and shuts the runtime down. -This command has to be invoked last, after the file has been dealt -with completely. -Afterward another invokation of ::fileutil::magic::rt::open is -required to process another file.
-This command returns the empty string as its result.
Decrement the level and perform related housekeeping
Create a new command which returns one description of the file each time it is +called, and a code of break when there are no more descriptions. +chan is the channel containing the data to describe. The channel +configuration is then managed as needed. +named is a dictionary of named tests, as generated by +fileutil::magic::cfront::compile. +test is a command prefix for a routine composed of the list of commands +as returned by fileutil::magic::cfront::compile.
This command marks the start of a magic file when debugging. It returns the empty string as its result.
This command returns the current result and stops processing.
-If msg is specified its text is added to the result before it is -returned. See ::fileutil::magic::rt::emit for the allowed -special character sequences.
This command returns the current result. -In contrast to ::fileutil::magic::rt::result processing -continues.
-If msg is specified its text is added to the result before it is -returned. See ::fileutil::magic::rt::emit for the allowed -special character sequences.
This command adds the text msg to the result buffer. The message may contain the following special character sequences. They will be replaced with buffered values before the message is added to the result. The command returns the empty string as its result.
Replaced with the last buffered string value.
Replaced with the last buffered numeric value.
See above.
This command fetches the numeric value with type from the -absolute location offset and returns it as its result. The -fetched value is further stored in the numeric buffer.
-If qual is specified it is considered to be a mask and applied -to the fetched value before it is stored and returned. It has to have -the form of a partial Tcl bit-wise expression, i.e.
-- & number --
For example:
-- Nv lelong 0 &0x8080ffff --
For the possible types see section NUMERIC TYPES.
This command behaves mostly like ::fileutil::magic::rt::Nv, -except that it compares the fetched and masked value against val -as specified with comp and returns the result of that -comparison.
-The argument comp has to contain one of Tcl's comparison -operators, and the comparison made will be
-- <val> <comp> <fetched-and-masked-value> +
Substitute one string if the file is executable, and +another string otherwise.
Produce an offset from where, relative to the cursor one level up. +Produce an offset from where, relative to the offset one level up.
A limited form of ::fileutile::magic::rt::N that only checks for +equality and can't be told to invert the test.
Fetch the numeric value with type from the absolute location +offset, compare it with expected using comp as the comparision +operator, and returns the result.
+The argument comp must be one of Tcl's comparison +operators.
++ <comp> <fetched-and-masked-value> <comp> <expected>
The special comparison operator x signals that no comparison should be done, or, in other words, that the fetched value will always match val.
This command behaves like ::fileutil::magic::rt::Nv, except that -it additionally remembers the location in the file after the fetch in -the calling context, for the current level, for later use by -::fileutil::magic::rt::R.
This command behaves like ::fileutil::magic::rt::N, except that -it additionally remembers the location in the file after the fetch in -the calling context, for the current, for later use by -::fileutil::magic::rt::R.
This command behaves like ::fileutil::magic::rt::N, except that -it fetches and compares strings, not numeric data. The fetched value -is also stored in the internal string buffer instead of the numeric -buffer.
This command behaves like ::fileutil::magic::rt::S, except that -it additionally remembers the location in the file after the fetch in -the calling context, for the current level, for later use by -::fileutil::magic::rt::R.
This command sets the current level in the calling context to +
Like ::fileutil::magic::rt::N except that it fetches and compares string +types , not numeric data.
Sets the current level in the calling context to newlevel. The command returns the empty string as its result.
This command handles base locations specified indirectly through the -contents of the inspected file. It returns the sum of delta and -the value of numeric type fetched from the absolute location -base.
-For the possible types see section NUMERIC TYPES.
This command handles base locations specified relative to the end of -the last field one level above.
-In other words, the command computes an absolute location in the file -based on the relative offset and returns it as its result. The -base the offset is added to is the last location remembered for the -level in the calling context.
Use a named test script at the current level.
Calculates an offset based on an initial offset and the provided modifiers.
Given an initial offset, calculates an offset relative to the cursor at the +next level up. The cursor is the position in the data one character after the +data extracted from the file one level up.
Add a level and use a named test script.