Index: .github/CONTRIBUTING.md ================================================================== --- .github/CONTRIBUTING.md +++ .github/CONTRIBUTING.md @@ -1,17 +1,17 @@ -Hello. +Hello. __Attention please__ You are currently using the github __mirror__ of the Tcllib sources. -This is __not__ the location where development takes place. +This is __not__ the location where Tcllib development takes place. -We are not tracking issues entered here. With the exception of the +We are __not tracking issues entered here__. With the exception of the maintainer of the mirroring setup nobody will even see such issues. Please go to the -[official location of the sources](https://core.tcl.tk/tcllib) +[official location of the sources](https://core.tcl-lang.org/tcllib) and enter your ticket into the -[official ticket tracker](https://core.tcl.tk/tcllib/reportlist) +[official ticket tracker](https://core.tcl-lang.org/tcllib/reportlist) instead. Thank you for your consideration. Index: .github/ISSUE_TEMPLATE.md ================================================================== --- .github/ISSUE_TEMPLATE.md +++ .github/ISSUE_TEMPLATE.md @@ -1,17 +1,17 @@ -Hello. +Hello. __Attention please__ You are currently using the github __mirror__ of the Tcllib sources. -This is __not__ the location where development takes place. +This is __not__ the location where Tcllib development takes place. -We are not tracking issues entered here. With the exception of the +We are __not tracking issues entered here__. With the exception of the maintainer of the mirroring setup nobody will even see such issues. Please go to the -[official location of the sources](https://core.tcl.tk/tcllib) +[official location of the sources](https://core.tcl-lang.org/tcllib) and enter your ticket into the -[official ticket tracker](https://core.tcl.tk/tcllib/reportlist) +[official ticket tracker](https://core.tcl-lang.org/tcllib/reportlist) instead. Thank you for your consideration. Index: .github/PULL_REQUEST_TEMPLATE.md ================================================================== --- .github/PULL_REQUEST_TEMPLATE.md +++ .github/PULL_REQUEST_TEMPLATE.md @@ -1,17 +1,17 @@ -Hello. +Hello. __Attention please__ You are currently using the github __mirror__ of the Tcllib sources. -This is __not__ the location where development takes place. +This is __not__ the location where Tcllib development takes place. -We are not tracking issues entered here. With the exception of the +We are __not tracking issues entered here__. With the exception of the maintainer of the mirroring setup nobody will even see such issues. Please go to the -[official location of the sources](https://core.tcl.tk/tcllib) +[official location of the sources](https://core.tcl-lang.org/tcllib) and enter your ticket into the -[official ticket tracker](https://core.tcl.tk/tcllib/reportlist) +[official ticket tracker](https://core.tcl-lang.org/tcllib/reportlist) instead. Thank you for your consideration. DELETED INSTALL.txt Index: INSTALL.txt ================================================================== --- INSTALL.txt +++ /dev/null @@ -1,77 +0,0 @@ -How to install Tcllib -===================== - -Introduction ------------- - -The tcllib distribution, whether a snapshot directly from CVS, or -officially released, offers a single method for installing tcllib, -based on Tcl itself. - -This is based on the assumption that for tcllib to be of use Tcl has -to be present, and therefore can be used. - -This single method however can be used in a variety of ways. - -0 For an unwrapped (= directory) distribution or CVS snapshot - - a. either call the application 'installer.tcl' directly, - b or use - - % configure ; make install - - The latter is provided for people which are used to - this method and more comfortable with it. In end this - boils down into a call of 'installer.tcl' too. - -1. A starpack distribution (window-only) is a self-extracting - installer which internally uses the aforementioned installer. - -2. A starkit distribution is very much like a starpack, but - required an external interpreyter to run. This can be any tcl - interpreter which has all the packages to support starkits - (tclvfs, memchan, trf). - -3. A distribution in a tarball has to be unpacked first, then any - of the methods described in (0) can be used. - - -Usage of the installer ----------------------- - -The installer selects automatically either a gui based mode, or a -command line based mode. If the package Tk is present and can be -loaded, then the GUI mode is entered, else the system falls back to -the command line. - -Note that it is possible to specify options on the command line even -if the installer ultimatively selects a gui mode. In that case the -hardwired defaults and the options determine the data presented to the -user for editing. - -Command line help can be asked for by using the option -help when -running the installer (3) or the distribution itself in the case of -(1) or (2). - -The installer will select a number of defaults for the locations of -packages, examples, and documentation, and also the format of the -documentation. The user can overide these defaults in the GUI, or by -specifying additional options. - -The defaults depend on the platform detected (unix/windows) and the -executable used to run the installer. In the case of a starpack -distribution (1) this means that _no defaults_ are possible for the -various locations as the executable is part of the distribution and -has no knowledge of its environment. - -In all other cases the intepreter executable is outside of the -distribution, which means that its location can be used to determine -sensible defaults. - -Notes ------ - -The installer will overwrite an existing installation of tcllib 1.6 -without asking back after the initial confirmation is given. And if -the user chooses the same directory as for tcllib 1.4, or 1.3, etc. -then the installer will overwrite that too. DELETED README Index: README ================================================================== --- README +++ /dev/null @@ -1,96 +0,0 @@ -RCS: @(#) $Id: README,v 1.9 2007/08/30 17:24:13 andreas_kupries Exp $ - -Welcome to the Tcllib, the Tcl Standard Library. This package is -intended to be a collection of Tcl packages that provide utility -functions useful to a large collection of Tcl programmers. - -The home web site for this code is http://core.tcl.tk/tcllib/ . -At this web site, you will find mailing lists, web forums, databases -for bug reports and feature requests, the CVS repository (browsable on -the web, or read-only accessible via CVS ), and more. - -The structure of the tcllib source hierarchy is: - -tcllib - +- modules - +- - +- - +- ... - - -The install hierarchy is: - -.../lib/tcllib - +- - +- - +- ... - -There are some base requirements that a module must meet before it -will be added to tcllib: - -* the module must be a proper Tcl package -* the module must use a namespace for its commands and variables -* the name of the package must be the same as the name of the - namespace -* the module must reside in a subdirectory of the modules directory in - the source hierarchy, and that subdirectory must have the same name - as the package and namespace -* the module must be released under the BSD License, the terms of - which can be found in the toplevel tcllib source directory in the file - license.terms -* the module should have both documentation ([*]) and a test suite - (in the form of a group of *.test files in the module directory). - - [*] Possible forms: doctools, TMML/XML, nroff (man), or HTML. - The first format is the most preferred as it can be processed with - tools provided by tcllib itself (See module doctools). The first - two are preferred in general as they are semantic markup and thus - easier to convert into other formats. - -* the module must have either documentation or a test suite. It can - not have neither. -* the module should adhere to Tcl coding standards - -When adding a module to tcllib, be sure to add it to the files listed below. - -* installed_modules.tcl - - contains a table listing all modules to be installed, modules - excluded, and names the actions to be taken during installation - of each module. Add a line to this table naming your module and - its actions. - - Three actions have to be specified, for the package itself, its - documentation, and the examples demonstrating it. - - The _null action can be used everywhere and signals that there is - nothing to do. Although it is possible to use it for the package - action it does make no sense there, as that means that no package - code is installed. - - Other package actions are _tcl, _tci, and _text. The first causes - the installer to copy all .tcl files from the source directory for - the module into the appropriate module directory. _tci does all that - and also expects a tclIndex file to copy. _tex is like _tcl, however - it also copies all .tex files found in the source directory for the - module. - - There is currently only one true documentation action. This action - is _doc. It converts all documentation in doctools format into the - format chosen by the user for installation and copies the result - into the appropriate directory. - - There is currently one true action for examples, _exa. It copies all - files in the source directory for examples into the directory chosen - by the user as destination for examples. - -Each module source directory should have no subdirectories (other than -the CVS directory), and should contain the following files: - -* source code *.tcl -* package index pkgIndex.tcl -* tests *.test -* documentation *.man, *.n, *.xml - -If you do not follow this directory structure, the tcllib Makefile -will fail to locate the files from the new module. DELETED README.developer Index: README.developer ================================================================== --- README.developer +++ /dev/null @@ -1,396 +0,0 @@ -RCS: @(#) $Id: README.developer,v 1.6 2009/06/02 22:49:55 andreas_kupries Exp $ - -Welcome to the tcllib, the Tcl Standard Library. -================================================ - -Introduction ------------- - -This README is intended to be a guide to the tools available to a - - Developer - -working on Tcllib to help him with his tasks, i.e. making the tasks easier -to perform. It is our hope that this will improve the quality of even -non-released revisions of Tcllib, and make the work of the release -manager easier as well. - -Audience --------- - -The intended audience are, first and foremost, developers beginning to -work on Tcllib. To an experienced developer this document will be less -of a guide and more of a reference. Anybody else interested in working -on Tcllib is invited as well. - - -Directory hierarchy and file basics ------------------------------------- - -The main directories under the tcllib top directory are - - modules/ - examples/ -and apps/ - -Each directory FOO under modules/ represents one package, sometimes -more. In the case of the latter the packages are usually related in -some way. Examples are the base64, math, and struct modules, with -loose (base64) to strong (math) relations between the packages. - -Examples associated with a module FOO, if there are any, are placed -into the directory - - examples/FOO - -Any type of distributable application can be found under apps/, -together with their documentation, if any. Note that the apps/ -directory is currently not split into sub-directories. - -Regarding the files in Tcllib, the most common types found are - - .tcl Tcl code for a package. - - .man Documentation for a package, in doctools format. - - .test Test suite for a package, or part of. Based on tcltest. - - .bench Performance benchmarks for a package, or part of. - Based on modules/bench - - .pcx Syntax rules for TclDevKit's tclchecker. Using these - rules allows tclchecker to check the use of commands - of a Tcllib package X without having to scan the - implementation of X, i.e. its .tcl files. - - -Adding a new module -------------------- - -Assuming that FOO is the name of the new module, and T is the toplevel -directory of the Tcllib sources - -(1) Create the directory T/modules/FOO and put all the files of - the module into it. Note: - - * The file 'pkgIndex.tcl' is required. - - * Implementation files should have the extension '.tcl', - naturally. - - * If available, documentation should be in doctools format, - and the files should have the extension '.man' for SAK to - recognize them. - - * If available the testsuite(s) should use 'tcltest' and the - general format as used by the other modules in Tcllib - (declaration of minimally needed Tcl, tcltest, supporting - packages, etc.). The file(s) should have the extension - '.test' for SAK to recognize them. - - Note that an empty testsuite, or a testsuite which does not - perform any tests is less than useful and will not be - accepted. - - * If available the benchmark(s) should use 'bench' and the - general format as used by the other modules in Tcllib. The - file(s) should have the extension '.bench' for SAK to - recognize them. - - * Other files can be named and placed as the module sees fit. - -(2) If the new module has an example application A which is - polished enough for general use, put this application into the - file "T/apps/A.tcl", and its documentation into the file - "T/apps/A.man". While documentation for the application is - optional, it is preferred. - - For examples which are not full-fledged applications, a - skeleton, or not really polished for use, etc., create the - directory T/examples/FOO/ and put them there. - - A key difference is what happens to them on installation, and - what the target audience is. - - The examples are for developers using packages in Tcllib, - whereas the applications are also for users of Tcllib which do - not have an interest in developing for and with it. As such, - they are installed as regular commands, accessible through the - PATH, and example files are not installed. - -(3) To make Tcllib's installer aware of FOO, edit the file - - T/support/installation/modules.tcl - - Add a line 'Module FOO $impaction $docaction $exaction'. The - various actions describe to the installer how to install the - implementation files, the documentation, and the examples. - - Add a line 'Application A' for any application A which was - added to T/apps for FOO. - - The following actions are available: - - Implementation - - _tcl - Copy all .tcl files in T/modules/FOO into the installation. - _tcr - See above, does it for .tcl files in subdirectories as well. - _tci - _tcl + Copying of a tclIndex - special to modules 'math', 'control'. - _msg - _tcl + Copying of subdir 'msgs' - special to modules 'dns', 'log'. - _doc - _tcl + Copying of subdir 'mpformats' - special to module 'doctools'. - _tex - _tcl + Copying of .tex files - special to module 'textutil'. - - The _null action, see below, is available in principle - too, but a module without implementation does not make - sense. - - Documentation - - _null - Module has no documentation, do nothing. - _man - Process the .man files in T/modules/FOO and - install the results (nroff and/or HTML) in the - proper location, as given to the installer. - - Examples - - _null - Module has no examples, do nothing - _exa - Copy the directory T/examples/FOO - (recursively) to the install location for - examples. - - -Testing modules ---------------- - -To run the testsuite of a module FOO in tcllib use the 'test run' -argument of sak.tcl, like so: - - % pwd - /the/tcllib/toplevel/directory - - % ./sak.tcl test run FOO -or % ./sak.tcl test run modules/FOO - -To run the testsuites of all modules either invoke 'test run' without a -module name, or use 'make test'. The latter assumes that configure was -run for Tcllib before, i.e.: - - % ./sak.tcl test run -or % ./sak.tcl test run - % make test - -In all of the above cases the result will be a combination of progress -display and testsuite log, showing for each module the tests that pass -or failed and how many of each in a summary at the end. - -To get a detailed log, it is necessary to invoke 'test run' with -additional options. - -First example: - % ./sak.tcl test run -l LOG FOO - -This shows the same short log on the terminal, and writes a detailed -log to the file LOG.log, and excerpts to other files (LOG.summary, -LOG.failures, etc.). - -Second example: - % ./sak.tcl test run -v FOO - % make test > LOG - -This writes the detailed log to stdout, or to the file LOG, instead of -the short log. In all cases, the detailed log contains a list of all -test cases executed, which failed, and how they failed (expected -versus actual results). - -Note: -The commands - % make test -and % make test > LOG - -are able to generate different output (short vs long log) because the -Makefile target contains code which detects that stdout has been -redirected to a file and acts accordingly. - -Non-developers should reports problems in Tcllib's bug tracker. -Information about its location and the relevant category can be found -in the section 'BUGS, IDEAS, FEEDBACK' of the manpage of the module -and/or package. - -Module documentation --------------------- - -The main format used for the documentation of packages in Tcllib is -'doctools', the support packages of which are part of Tcllib, see the -module 'doctools'. - -To convert this documentation to HTML or nroff manpages, or some other -format use the 'doc' argument of sak.tcl, like so: - - % pwd - /the/tcllib/toplevel/directory - - % ./sak.tcl doc html FOO -or % ./sak.tcl doc html modules/FOO - -The result of the conversion can be found in the newly-created 'doc' -directory in the current working directory. - -The set of formats the documentation can be converted into can be -queried via - - % ./sak.tcl help doc - - -To convert the documentation of all modules either invoke 'test run' -without a module name, or use 'make html-doc', etc.. The latter -assumes that configure was run for Tcllib before, i.e.: - - % ./sak.tcl doc html - % make html-doc - -Note the special format 'validate'. Using this format does not convert -the documentation to anything (and the sub-directory 'doc' will not be -created), it just checks that the documentation is syntactically -correct. I.e. - - % ./sak.tcldoc validate modules/FOO - % ./sak.tcldoc validate - - -Validating modules ------------------- - -Running the testsuite of a module, or checking the syntax of its -documentation (see the previous sections) are two forms of validation. - -The 'validate' command of sak.tcl provides a few more. The online -documentation of this command is available via - - % ./sak.tcl help validate - -The validated parts are man pages, testsuites, version information, -and syntax. The latter only if various static syntax checkers are -available on the PATH, like TclDevKit's tclchecker. - -Note that testsuite validation is not the execution of the testsuites, -only if a package has a testsuite or not. - -It is strongly recommended to validate a module before committing any -type of change made to it. - -It is recommended to validate all modules before committing any type -of change made to one of them. We have package inter-dependencies -between packages in Tcllib, thus changing one package may break -others, and just validating the changed package will not catch such -problems. - - -Writing Tests -------------- - -While a previous section talked about running the testsuite for a -module and the packages therein this has no meaning if the module in -question has no testsuites at all. - -This section gives a very basic overview on methodologies for writing -tests and testsuites. - -First there are "drudgery" tests. Written to check absolutely basic -assumptions which should never fail. - -Example: - - For a command FOO taking two arguments, three tests calling it - with zero, one, and three arguments. The basic checks that the - command fails if it has not enough arguments, or too many. - -After that come the tests checking things based on our knowledge of -the command, about its properties and assumptions. Some examples based -on the graph operations added during Google's Summer of Code 2009. - -** The BellmanFord command in struct::graph::ops takes a - _startnode_ as argument, and this node should be a node of the - graph. equals one test case checking the behavior when the - specified node is not a node a graph. - - This often gives rise to code in the implementation which - explicitly checks the assumption and throws a nice error. - Instead of letting the algorithm fails later in some weird - non-deterministic way. - - Such checks cannot be done always. The graph argument for - example is just a command in itself, and while we expect it to - exhibit a certain interface, i.e. set of sub-commands aka - methods, we cannot check that it has them, except by actually - trying to use them. That is done by the algorithm anyway, so - an explicit check is just overhead we can get by without. - -** IIRC one of the distinguishing characteristic of either - BellmanFord and/or Johnson is that they are able to handle - negative weights. Whereas Dijkstra requires positive weights. - - This induces (at least) three testcases ... Graph with all - positive weights, all negative, and a mix of positive and - negative weights. - - Thinking further does the algorithm handle the weight '0' as - well ? Another test case, or several, if we mix zero with - positive and negative weights. - -** The two algorithms we are currently thinking about are about - distances between nodes, and distance can be 'Inf'inity, - i.e. nodes may not be connected. This means that good test - cases are - - (1) Strongly connected graph - (2) Connected graph - (3) Disconnected graph. - - At the extremes of (1) and (3) we have the fully connected - graphs and graphs without edges, only nodes, i.e. completely - disconnected. - -** IIRC both of the algorithms take weighted arcs, and fill in a - default if arcs are left unweighted in the input graph. - - This also induces three test cases: - - (1) Graph will all arcs with explicit weights. - (2) Graph without weights at all. - (3) Graph with mixture of weighted and unweighted graphs. - - -What was described above via examples is called 'black-box' testing. -Test cases are designed and written based on our knowledge of the -properties of the algorithm and its inputs, without referencing a -particular implementation. - -Going further, a complement to 'black-box' testing is 'white-box'. For -this we know the implementation of the algorithm, we look at it and -design our tests cases so that they force the code through all -possible paths in the implementation. Wherever a decision is made we -have a test cases forcing a specific direction of the decision, for -all possible directions. - -In practice I often hope that the black-box tests I have made are -enough to cover all the paths, obviating the need for white-box tests. - -So, if you, dear reader, now believe that writing tests for an -algorithm takes at least as much time as coding the algorithm, and -often more time, then you are completely right. It does. Much more -time. See for example also http://sqlite.org/testing.html, a writeup -on how the Sqlite database engine is tested. - - - -An interesting connection is to documentation. In one direction, the -properties you are checking with black-box testing are properties -which should be documented in the algorithm man page. And conversely, -if you have documentation of properties of an algorithm then this is a -good reference to base black-box tests on. - -In practice test cases and documentation often get written together, -cross-influencing each other. And the actual writing of test cases is -a mix of black and white box, possibly influencing the implementation -while writing the tests. Like writing test for 'startnode not in input -graph' serving as reminder to put in a check for this into the code. Index: README.md ================================================================== --- README.md +++ README.md @@ -1,17 +1,44 @@ - -Hello. - -If you are reading this then you are very likely at the github -__mirror__ of the Tcllib sources. - -This means that the -[official location of the sources](https://core.tcl.tk/tcllib) -is somewhere else, just follow the link. - -This is also where our issue tracking is done. We are not tracking -issues at github. With the exeception of the maintainer of the -mirroring setup nobody will even see issues created at github. +# Attention + +:warning: +This repository is mirrored to [github](https://github.com/tcltk/tcllib). + +We are __not tracking issues at github__. With the exeception of the +maintainer of the mirroring setup nobody will even see issues created +at github. Please use the -[official ticket tracker](https://core.tcl.tk/tcllib/reportlist) +[official ticket tracker](https://core.tcl-lang.org/tcllib/reportlist) instead. + +# Welcome + +Welcome to Tcllib, the Tcl Standard Library. Note that Tcllib is not a +package itself. It is a collection of (semi-independent) Tcl packages +that provide utility functions useful to a large collection of Tcl +programmers. + +At our [home site](http://core.tcl-lang.org/tcllib) you will find the +official fossil repository used to manage our sources, together with +the bug tracker. This is also the main location for releases to +download from. + +We have a +[secondary download location](https://sourceforge.net/projects/tcllib/files) +where the Tcllib sources were hosted in the past. SourceForge is also +where our [mailing lists](https://sourceforge.net/p/tcllib/mailman) +are (still) hosted. + +Another location to find these sources at is the +[github mirror](https://github.com/tcltk/tcllib). + +Please note the :warning: at the top. + +# Guides To Tcllib + + * [Tcl Community - Kind Communication](embedded/www/tcllib/files/devdoc/tcl_community_communication.html) + * [License](embedded/www/tcllib/files/devdoc/tcllib_license.html) + * [How To Get The Sources](embedded/www/tcllib/files/devdoc/tcllib_sources.html) + * [How To Build And Install Tcllib](embedded/www/tcllib/files/devdoc/tcllib_installer.html) + * [The Developer's Guide](embedded/www/tcllib/files/devdoc/tcllib_devguide.html) + * [The Release Manager's Guide](embedded/www/tcllib/files/devdoc/tcllib_releasemgr.html) DELETED README.releasemgr Index: README.releasemgr ================================================================== --- README.releasemgr +++ /dev/null @@ -1,65 +0,0 @@ -RCS: @(#) $Id: README.releasemgr,v 1.2 2009/07/10 16:33:31 andreas_kupries Exp $ - -Welcome to the tcllib, the Tcl Standard Library. -================================================ - -Introduction ------------- - -This README is intended to be a guide to the tools available to a - - Release manager - -working on the creation of a release of Tcllib. - -Audience --------- - -The intended audience is the release manager of Tcllib, his deputies, -and anybody else interested in the task. - -Basics ------- - -< Flesh this out > - - sak.tcl validate - sak.tcl test run - sak.tcl review - sak.tcl readme - sak.tcl localdoc - sak.tcl release (change to include rpmspec+gentip55+yml) - -< Tasks, and how to perform them > - - Making a release (candidate) branch. - Readying the release in the branch. - Make the release official, merging the branch back. - -Uploading and releasing files --------------------------------------------- - -(1) Create a proper fossil event for the release, via - - http://core.tcl.tk/tcllib/eventedit - - See existing events (*) for a template - - (Ad *) http://core.tcl.tk/tcllib/event/dac0ddcd2e990234143196b4dc438fe01e7b9817 - -(2) Update the following web locations - - (a) Home page: http://core.tcl.tk/tcllib/home - (b) Downloads: http://core.tcl.tk/tcllib/wiki?name=Downloads - (c) Past Releases: http://core.tcl.tk/tcllib/wiki?name=Past+Releases - - Admin access to the fossil repository required - - (d) http://www.tcl.tk/home/release.txt - (e) http://www.tcl.tk/software/tcllib/*.tml - - ssh access to tcl.activestate.com - aka www.tcl.tk - required. - - (f) http://wiki.tcl.tk/1246 Index: apps/dtplite.man ================================================================== --- apps/dtplite.man +++ apps/dtplite.man @@ -441,7 +441,7 @@ of doctoc and docidx markup. [list_end] [vset CATEGORY doctools] -[include ../modules/doctools2base/include/feedback.inc] +[include ../modules/common-text/feedback.inc] [manpage_end] Index: apps/nns.man ================================================================== --- apps/nns.man +++ apps/nns.man @@ -137,7 +137,7 @@ requests. [list_end] [vset CATEGORY nameserv] -[include ../modules/doctools2base/include/feedback.inc] +[include ../modules/common-text/feedback.inc] [manpage_end] Index: apps/nnsd.man ================================================================== --- apps/nnsd.man +++ apps/nnsd.man @@ -85,7 +85,7 @@ specifies the TCP port the server has to listen on for requests. [list_end] [vset CATEGORY nameserv] -[include ../modules/doctools2base/include/feedback.inc] +[include ../modules/common-text/feedback.inc] [manpage_end] Index: apps/nnslog.man ================================================================== --- apps/nnslog.man +++ apps/nnslog.man @@ -87,7 +87,7 @@ requests. [list_end] [vset CATEGORY nameserv] -[include ../modules/doctools2base/include/feedback.inc] +[include ../modules/common-text/feedback.inc] [manpage_end] Index: apps/page.man ================================================================== --- apps/page.man +++ apps/page.man @@ -461,7 +461,7 @@ The contents of both environment variables and registry entries are interpreted as a list of paths, with the elements separated by either colon (Unix), or semicolon (Windows). [vset CATEGORY page] -[include ../modules/doctools2base/include/feedback.inc] +[include ../modules/common-text/feedback.inc] [manpage_end] Index: apps/tcldocstrip.man ================================================================== --- apps/tcldocstrip.man +++ apps/tcldocstrip.man @@ -191,7 +191,7 @@ written after the actual content of a generated file. [list_end] [vset CATEGORY docstrip] -[include ../modules/doctools2base/include/feedback.inc] +[include ../modules/common-text/feedback.inc] [manpage_end] ADDED devdoc/README.developer Index: devdoc/README.developer ================================================================== --- /dev/null +++ devdoc/README.developer @@ -0,0 +1,396 @@ +RCS: @(#) $Id: README.developer,v 1.6 2009/06/02 22:49:55 andreas_kupries Exp $ + +Welcome to the tcllib, the Tcl Standard Library. +================================================ + +Introduction +------------ + +This README is intended to be a guide to the tools available to a + + Developer + +working on Tcllib to help him with his tasks, i.e. making the tasks easier +to perform. It is our hope that this will improve the quality of even +non-released revisions of Tcllib, and make the work of the release +manager easier as well. + +Audience +-------- + +The intended audience are, first and foremost, developers beginning to +work on Tcllib. To an experienced developer this document will be less +of a guide and more of a reference. Anybody else interested in working +on Tcllib is invited as well. + + +Directory hierarchy and file basics +------------------------------------ + +The main directories under the tcllib top directory are + + modules/ + examples/ +and apps/ + +Each directory FOO under modules/ represents one package, sometimes +more. In the case of the latter the packages are usually related in +some way. Examples are the base64, math, and struct modules, with +loose (base64) to strong (math) relations between the packages. + +Examples associated with a module FOO, if there are any, are placed +into the directory + + examples/FOO + +Any type of distributable application can be found under apps/, +together with their documentation, if any. Note that the apps/ +directory is currently not split into sub-directories. + +Regarding the files in Tcllib, the most common types found are + + .tcl Tcl code for a package. + + .man Documentation for a package, in doctools format. + + .test Test suite for a package, or part of. Based on tcltest. + + .bench Performance benchmarks for a package, or part of. + Based on modules/bench + + .pcx Syntax rules for TclDevKit's tclchecker. Using these + rules allows tclchecker to check the use of commands + of a Tcllib package X without having to scan the + implementation of X, i.e. its .tcl files. + + +Adding a new module +------------------- + +Assuming that FOO is the name of the new module, and T is the toplevel +directory of the Tcllib sources + +(1) Create the directory T/modules/FOO and put all the files of + the module into it. Note: + + * The file 'pkgIndex.tcl' is required. + + * Implementation files should have the extension '.tcl', + naturally. + + * If available, documentation should be in doctools format, + and the files should have the extension '.man' for SAK to + recognize them. + + * If available the testsuite(s) should use 'tcltest' and the + general format as used by the other modules in Tcllib + (declaration of minimally needed Tcl, tcltest, supporting + packages, etc.). The file(s) should have the extension + '.test' for SAK to recognize them. + + Note that an empty testsuite, or a testsuite which does not + perform any tests is less than useful and will not be + accepted. + + * If available the benchmark(s) should use 'bench' and the + general format as used by the other modules in Tcllib. The + file(s) should have the extension '.bench' for SAK to + recognize them. + + * Other files can be named and placed as the module sees fit. + +(2) If the new module has an example application A which is + polished enough for general use, put this application into the + file "T/apps/A.tcl", and its documentation into the file + "T/apps/A.man". While documentation for the application is + optional, it is preferred. + + For examples which are not full-fledged applications, a + skeleton, or not really polished for use, etc., create the + directory T/examples/FOO/ and put them there. + + A key difference is what happens to them on installation, and + what the target audience is. + + The examples are for developers using packages in Tcllib, + whereas the applications are also for users of Tcllib which do + not have an interest in developing for and with it. As such, + they are installed as regular commands, accessible through the + PATH, and example files are not installed. + +(3) To make Tcllib's installer aware of FOO, edit the file + + T/support/installation/modules.tcl + + Add a line 'Module FOO $impaction $docaction $exaction'. The + various actions describe to the installer how to install the + implementation files, the documentation, and the examples. + + Add a line 'Application A' for any application A which was + added to T/apps for FOO. + + The following actions are available: + + Implementation + + _tcl - Copy all .tcl files in T/modules/FOO into the installation. + _tcr - See above, does it for .tcl files in subdirectories as well. + _tci - _tcl + Copying of a tclIndex - special to modules 'math', 'control'. + _msg - _tcl + Copying of subdir 'msgs' - special to modules 'dns', 'log'. + _doc - _tcl + Copying of subdir 'mpformats' - special to module 'doctools'. + _tex - _tcl + Copying of .tex files - special to module 'textutil'. + + The _null action, see below, is available in principle + too, but a module without implementation does not make + sense. + + Documentation + + _null - Module has no documentation, do nothing. + _man - Process the .man files in T/modules/FOO and + install the results (nroff and/or HTML) in the + proper location, as given to the installer. + + Examples + + _null - Module has no examples, do nothing + _exa - Copy the directory T/examples/FOO + (recursively) to the install location for + examples. + + +Testing modules +--------------- + +To run the testsuite of a module FOO in tcllib use the 'test run' +argument of sak.tcl, like so: + + % pwd + /the/tcllib/toplevel/directory + + % ./sak.tcl test run FOO +or % ./sak.tcl test run modules/FOO + +To run the testsuites of all modules either invoke 'test run' without a +module name, or use 'make test'. The latter assumes that configure was +run for Tcllib before, i.e.: + + % ./sak.tcl test run +or % ./sak.tcl test run + % make test + +In all of the above cases the result will be a combination of progress +display and testsuite log, showing for each module the tests that pass +or failed and how many of each in a summary at the end. + +To get a detailed log, it is necessary to invoke 'test run' with +additional options. + +First example: + % ./sak.tcl test run -l LOG FOO + +This shows the same short log on the terminal, and writes a detailed +log to the file LOG.log, and excerpts to other files (LOG.summary, +LOG.failures, etc.). + +Second example: + % ./sak.tcl test run -v FOO + % make test > LOG + +This writes the detailed log to stdout, or to the file LOG, instead of +the short log. In all cases, the detailed log contains a list of all +test cases executed, which failed, and how they failed (expected +versus actual results). + +Note: +The commands + % make test +and % make test > LOG + +are able to generate different output (short vs long log) because the +Makefile target contains code which detects that stdout has been +redirected to a file and acts accordingly. + +Non-developers should reports problems in Tcllib's bug tracker. +Information about its location and the relevant category can be found +in the section 'BUGS, IDEAS, FEEDBACK' of the manpage of the module +and/or package. + +Module documentation +-------------------- + +The main format used for the documentation of packages in Tcllib is +'doctools', the support packages of which are part of Tcllib, see the +module 'doctools'. + +To convert this documentation to HTML or nroff manpages, or some other +format use the 'doc' argument of sak.tcl, like so: + + % pwd + /the/tcllib/toplevel/directory + + % ./sak.tcl doc html FOO +or % ./sak.tcl doc html modules/FOO + +The result of the conversion can be found in the newly-created 'doc' +directory in the current working directory. + +The set of formats the documentation can be converted into can be +queried via + + % ./sak.tcl help doc + + +To convert the documentation of all modules either invoke 'test run' +without a module name, or use 'make html-doc', etc.. The latter +assumes that configure was run for Tcllib before, i.e.: + + % ./sak.tcl doc html + % make html-doc + +Note the special format 'validate'. Using this format does not convert +the documentation to anything (and the sub-directory 'doc' will not be +created), it just checks that the documentation is syntactically +correct. I.e. + + % ./sak.tcldoc validate modules/FOO + % ./sak.tcldoc validate + + +Validating modules +------------------ + +Running the testsuite of a module, or checking the syntax of its +documentation (see the previous sections) are two forms of validation. + +The 'validate' command of sak.tcl provides a few more. The online +documentation of this command is available via + + % ./sak.tcl help validate + +The validated parts are man pages, testsuites, version information, +and syntax. The latter only if various static syntax checkers are +available on the PATH, like TclDevKit's tclchecker. + +Note that testsuite validation is not the execution of the testsuites, +only if a package has a testsuite or not. + +It is strongly recommended to validate a module before committing any +type of change made to it. + +It is recommended to validate all modules before committing any type +of change made to one of them. We have package inter-dependencies +between packages in Tcllib, thus changing one package may break +others, and just validating the changed package will not catch such +problems. + + +Writing Tests +------------- + +While a previous section talked about running the testsuite for a +module and the packages therein this has no meaning if the module in +question has no testsuites at all. + +This section gives a very basic overview on methodologies for writing +tests and testsuites. + +First there are "drudgery" tests. Written to check absolutely basic +assumptions which should never fail. + +Example: + + For a command FOO taking two arguments, three tests calling it + with zero, one, and three arguments. The basic checks that the + command fails if it has not enough arguments, or too many. + +After that come the tests checking things based on our knowledge of +the command, about its properties and assumptions. Some examples based +on the graph operations added during Google's Summer of Code 2009. + +** The BellmanFord command in struct::graph::ops takes a + _startnode_ as argument, and this node should be a node of the + graph. equals one test case checking the behavior when the + specified node is not a node a graph. + + This often gives rise to code in the implementation which + explicitly checks the assumption and throws a nice error. + Instead of letting the algorithm fails later in some weird + non-deterministic way. + + Such checks cannot be done always. The graph argument for + example is just a command in itself, and while we expect it to + exhibit a certain interface, i.e. set of sub-commands aka + methods, we cannot check that it has them, except by actually + trying to use them. That is done by the algorithm anyway, so + an explicit check is just overhead we can get by without. + +** IIRC one of the distinguishing characteristic of either + BellmanFord and/or Johnson is that they are able to handle + negative weights. Whereas Dijkstra requires positive weights. + + This induces (at least) three testcases ... Graph with all + positive weights, all negative, and a mix of positive and + negative weights. + + Thinking further does the algorithm handle the weight '0' as + well ? Another test case, or several, if we mix zero with + positive and negative weights. + +** The two algorithms we are currently thinking about are about + distances between nodes, and distance can be 'Inf'inity, + i.e. nodes may not be connected. This means that good test + cases are + + (1) Strongly connected graph + (2) Connected graph + (3) Disconnected graph. + + At the extremes of (1) and (3) we have the fully connected + graphs and graphs without edges, only nodes, i.e. completely + disconnected. + +** IIRC both of the algorithms take weighted arcs, and fill in a + default if arcs are left unweighted in the input graph. + + This also induces three test cases: + + (1) Graph will all arcs with explicit weights. + (2) Graph without weights at all. + (3) Graph with mixture of weighted and unweighted graphs. + + +What was described above via examples is called 'black-box' testing. +Test cases are designed and written based on our knowledge of the +properties of the algorithm and its inputs, without referencing a +particular implementation. + +Going further, a complement to 'black-box' testing is 'white-box'. For +this we know the implementation of the algorithm, we look at it and +design our tests cases so that they force the code through all +possible paths in the implementation. Wherever a decision is made we +have a test cases forcing a specific direction of the decision, for +all possible directions. + +In practice I often hope that the black-box tests I have made are +enough to cover all the paths, obviating the need for white-box tests. + +So, if you, dear reader, now believe that writing tests for an +algorithm takes at least as much time as coding the algorithm, and +often more time, then you are completely right. It does. Much more +time. See for example also http://sqlite.org/testing.html, a writeup +on how the Sqlite database engine is tested. + + + +An interesting connection is to documentation. In one direction, the +properties you are checking with black-box testing are properties +which should be documented in the algorithm man page. And conversely, +if you have documentation of properties of an algorithm then this is a +good reference to base black-box tests on. + +In practice test cases and documentation often get written together, +cross-influencing each other. And the actual writing of test cases is +a mix of black and white box, possibly influencing the implementation +while writing the tests. Like writing test for 'startnode not in input +graph' serving as reminder to put in a check for this into the code. DELETED devdoc/cvs.branches.fig Index: devdoc/cvs.branches.fig ================================================================== --- devdoc/cvs.branches.fig +++ /dev/null @@ -1,32 +0,0 @@ -#FIG 3.2 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -6 3000 2025 5400 2400 -4 0 12 50 0 0 14 0.0000 4 150 2385 3000 2175 Point releases are branched\001 -4 0 12 50 0 0 14 0.0000 4 150 1530 3000 2370 from RELEASES\001 --6 -6 2400 750 5700 1200 -4 0 1 50 0 0 14 0.0000 4 195 3225 2400 900 Developer performs internal releases,\001 -4 0 1 50 0 0 14 0.0000 4 195 3285 2400 1095 merging from HEAD into RELEASES\001 --6 -2 1 0 4 0 7 50 0 -1 0.000 0 0 7 1 0 2 - 2 1 4.00 240.00 480.00 - 300 600 5700 600 -2 1 0 2 1 7 50 0 -1 0.000 0 0 -1 1 0 2 - 2 1 2.00 120.00 240.00 - 2100 600 2400 1800 -2 1 0 5 12 7 50 0 -1 0.000 0 0 -1 1 0 3 - 2 1 5.00 300.00 600.00 - 2700 1800 3000 3000 5700 3000 -2 1 0 4 17 7 50 0 -1 0.000 0 0 7 1 0 3 - 2 1 4.00 240.00 480.00 - 1200 600 1500 1800 5700 1800 -4 0 0 50 0 0 14 0.0000 4 195 2835 3150 1575 Staging for release : RELEASES\001 -4 0 0 50 0 0 14 0.0000 4 195 1905 3900 300 Development : HEAD\001 -4 0 0 50 0 0 14 0.0000 4 150 930 4800 2700 Tcllib 1.2.0\001 DELETED devdoc/devguide.html Index: devdoc/devguide.html ================================================================== --- devdoc/devguide.html +++ /dev/null @@ -1,50 +0,0 @@ - - -

Guide for Tcllib developers. -

-
- -

CVS Repository -

-
- - -

- -The CVS repository for Tcllib contains two main branches, the HEAD for -development, and RELEASES as the staging area for official -releases. At RELEASES the minor branches containing the various -official releases are anchored at. -

- -

All the branches are of interest to the developers for - Tcllib. Ongoing development happens in HEAD, which can be - unstable or may not work at all. Whenever a developer considers - a piece of code, or module, he is responsible for as - sufficiently stable she has to perform an internal release which - merges this part from HEAD into RELEASES. Tools to help with - this will be provided. -

- -

The branches for the official releases of tcllib are of interest to - a developer because it is expected that fixes for important bugs - not only go into the HEAD branch but also into the release - branches for the release they were found in and all releases - following that one. This is to allow the release manager to - create patch releases of existing releases distributing important - bugfixes as well. -

- -

Version numbers for modules are handled as described below. This - way of handling them was chosen so that the modules in the - development branch always uses version numbers different from - the version numbers in the official releases made so far. -

-
    -
  • Whenever an internal release of a module FOO is done, the - developer performing this internal release has to increment - the version number of the module after the release was - executed. -
DELETED devdoc/installation.txt Index: devdoc/installation.txt ================================================================== --- devdoc/installation.txt +++ /dev/null @@ -1,85 +0,0 @@ -Tcllib installation directory layout -==================================== - -This document describes the possible layouts for an installed tcllib, -discusses their pro and contra and makes a choice for Tcllib 1.4. A -roadmap of changes in the future is made available as appendix. - -[L1/D] Deep layout ------------------- - - This is the layout of Tcllib 1.3 (and versions before that). - - A single directory tcllib is created, and all - subdirectories of the 'modules' subdirectory in the - distribution is copied into it. This is restricted at large to - *.tcl files, with exception made for some modules with special - needs. - - Pro: - Contra: - Makes the handling of the various package indices, - well, not difficult, but uncomfortable. - - -[L2/Fa] Flat layout 1 ---------------------- - - A directory is created for each module of tcllib. - - Pro: - Handling of package indices is easier than for L1/D, a - toplevel index file with all its problems is not - required anymore. - - Contra: - Directories should be versioned to avoid conflicts - between multiple releases. modules have no - version. This can be faked for modules containing one - package, but not for the modules with more. - - -[L2/Fb] Flat layout 2 ---------------------- - - A directory is created for each package in tcllib. - - Pro - Handling of package indices is easy, one per package. - - Contra: - Modules containing more than one package are difficult - to handle. The system has to split them into the - individual packages. This rendered very difficult - because of shared package index files. - - This can be solved by moving tcllib (back) towards of - one package per module. When that goal is reached - L2/Fa and L2/Fb become the same, and the contra for - L2/Fa vanishes too as an exact version number can be - associated with each directory. - -Chosen layout for Tcllib 1.4 ----------------------------- - - L2/D - - Despite the problems with package indices the contras against - the flat structures are too strong at this point in - time. Automatic solutions are not really possible, or require - a very high effort. - -Roadmap -------- - Change the module directories of tcllib to contain exactly one - package per directory, with appropriate index (and meta data). - - This not only makes sense for easier handling of installation - and package indices, but also in the greater context of - wrapping code for deployment. - - ------------------------------------ -This document is in the public domain. - - Andreas Kupries ADDED devdoc/parts/b_critcl.inc Index: devdoc/parts/b_critcl.inc ================================================================== --- /dev/null +++ devdoc/parts/b_critcl.inc @@ -0,0 +1,38 @@ + +While the majority of Tcllib consists of packages written in pure Tcl +a number of packages also have [term accelerators] associated with them. + +These are [syscmd critcl]-based C packages whose use will boost the +performance of the packages using them. + +These accelerators are optional, and they are not installed by +default. + +[para] To build the accelerators the normally optional dependency on + [syscmd critcl] becomes required. + +[para] To build and install Tcllib with the accelerators in a + Unix-like environment invoke: + +[example { + ./configure + make critcl # This builds the shared library holding + # the accelerators + make install +}] + +[para] The underlying tool is [file sak.tcl] in the toplevel directory +of Tcllib and the command [cmd {make critcl}] is just a wrapper around + +[example { + ./sak.tcl critcl +}] + +[para] Therefore in a Windows environment instead invoke + +[example { + ./sak.tcl critcl + ./installer.tcl +}] + +from within a DOS window, i.e. [syscmd cmd.exe]. ADDED devdoc/parts/b_tooling.inc Index: devdoc/parts/b_tooling.inc ================================================================== --- /dev/null +++ devdoc/parts/b_tooling.inc @@ -0,0 +1,109 @@ + +The core of Tcllib's build system is the script [file installer.tcl] +found in the toplevel directory of a checkout or release. + +[para] The + [example { + configure ; make install + }] + setup available to + developers on Unix-like systems is just a wrapper around it. + + To go beyond the standard embodied in the wrapper it is + necessary to directly invoke this script. + +[para] On Windows system using it directly is the only way to invoke + it. + +[para] For basic help invoke it as + + [example { + ./installer.tcl -help + }] + + This will print a short list of all the available options to + the standard output channel. + +[para] The commands associated with the various [term install] targets + in the [term Makefile.in] for Unix can be used as additional + examples on how to use this tool as well. + +[para] The installer can operate in GUI and CLI modes. + + By default it chooses the mode automatically, based on if the + Tcl package [package Tk] can be used or not. + + The option [option -no-gui] can be used to force CLI mode. + +[para] Note that it is possible to specify options on the command line + even if the installer ultimatively selects GUI mode. In that + case the hardwired defaults and the options determine the data + presented to the user for editing. + +[para] The installer will select a number of defaults for the + locations of packages, examples, and documentation, and also + the format of the documentation. The user can overide these + defaults in the GUI, or by specifying additional options. + + The defaults depend on the platform detected (Unix/Windows) and + on the [syscmd tclsh] executable used to run the installer. + +[para][emph Options] + +[list_begin options] +[opt_def -help] + +Show the list of options explained here on the standard output channel +and exit. + +[opt_def +excluded] + +Include deprecated packages in the installation. + +[opt_def -no-gui] + +Force command line operation of the installer + +[opt_def -no-wait] + +In CLI mode the installer will by default ask the user to confirm that +the chosen configuration (destination paths, things to install) is +correct before performing any action. Using this option causes the +installer to skip this query and immediately jump to installation. + +[opt_def -app-path [arg path]] +[opt_def -example-path [arg path]] +[opt_def -html-path [arg path]] +[opt_def -nroff-path [arg path]] +[opt_def -pkg-path [arg path]] + +Declare the destination paths for the applications, examples, html +documentation, nroff manpages, and packages. The defaults are derived +from the location of the [syscmd tclsh] used to run the installer. + +[opt_def -dry-run] +[opt_def -simulate] + +Run the installer without modifying the destination directories. + +[opt_def -apps] +[opt_def -no-apps] +[opt_def -examples] +[opt_def -no-examples] +[opt_def -pkgs] +[opt_def -no-pkgs] +[opt_def -html] +[opt_def -no-html] +[opt_def -nroff] +[opt_def -no-nroff] + +(De)activate the installation of applications, examples, packages, +html documentation, and nroff manpages. + +[para] Applications, examples, and packages are installed by default. + +[para] On Windows the html documentation is installed by default. + +[para] On Unix the nroff manpages are installed by default. + +[list_end] ADDED devdoc/parts/b_unix.inc Index: devdoc/parts/b_unix.inc ================================================================== --- /dev/null +++ devdoc/parts/b_unix.inc @@ -0,0 +1,22 @@ + +For [term Unix]-like environments Tcllib comes with the standard set +of files to make + +[example { + ./configure + make install +}] + +a suitable way of installing it. + +This is a standard non-interactive install automatically figuring out +where to place everything, i.e. packages, applications, and the +manpages. + +[para] To get a graphical installer invoke + +[example { + ./installer.tcl +}] + +instead. ADDED devdoc/parts/b_windows.inc Index: devdoc/parts/b_windows.inc ================================================================== --- /dev/null +++ devdoc/parts/b_windows.inc @@ -0,0 +1,18 @@ + +In a Windows environment we have the [cmd installer.tcl] script to +perform installation. + +[para] If the desired [syscmd tclsh] is associated [file .tcl] files + then double-clicking / opening the [cmd installer.tcl] is + enough to invoke it in graphical mode. + + This assumes that [term Tk] is installed and available as well. + +[para] Without [term Tk] the only way to invoke the installer are to + open a DOS window, i.e. [syscmd cmd.exe], and then to invoke + +[example { + ./installer.tcl +}] + +inside it. ADDED devdoc/parts/d_bf_branchcmds.inc Index: devdoc/parts/d_bf_branchcmds.inc ================================================================== --- /dev/null +++ devdoc/parts/d_bf_branchcmds.inc @@ -0,0 +1,29 @@ + +In the hope of engendering good work practices now a few example +operations which will come up with branches, and their associated +fossil command (sequences). + +[list_begin definitions] + +[comment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] +[def [emph Awareness]] +[include d_op_aware.inc] + +[comment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] +[def [emph {Clean checkouts}]] +[include d_op_clean.inc] + +[comment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] +[def [emph {Starting a new branch}]] +[include d_op_branch_open.inc] + +[comment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] +[def [emph {Merging a branch into trunk}]] +[include d_op_branch_close.inc] + +[comment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] +[def [emph {Merging from trunk}]] +[include d_op_branch_import.inc] + +[list_end] + ADDED devdoc/parts/d_bf_branches.inc Index: devdoc/parts/d_bf_branches.inc ================================================================== --- /dev/null +++ devdoc/parts/d_bf_branches.inc @@ -0,0 +1,37 @@ + +Given the constraints placed on the [term trunk] branch of the +repository it is (strongly) recommended to perform any development +going beyond trivial changes on a non-trunk branch. + +[para] Outside of the trunk developers are allowed to commit + intermediate broken states of their work. + + Only at the end of a development cycle, when the relevant + branch is considered ready for merging, will it be necessary to + perform full the set of validations ensuring that the merge to + come will create a good commit on trunk. + +[para] Note that while a review from a second developer is not a + required condition for merging a branch it is recommended to + seek out such an independent opinion as a means of + cross-checking the work. + +[para] It also recommended to give any new branch a name which aids in + determining additional details about it. Examples of good + things to stick into a branch name would be + +[list_begin itemized] +[item] Developer (nick)name +[item] Ticket hash/reference +[item] One or two keywords applicable to the work +[item] ... +[list_end] + +[para] Further, while most development branches are likely quite + short-lived, no prohibitions exist against making longer-lived + branches. + + Creators should however be mindful that the longer such a + branch exists without merges the more divergent they will tend + to be, with an associated increase in the effort which will + have to be spent on either merging from and merging to trunk. ADDED devdoc/parts/d_bf_dependencies.inc Index: devdoc/parts/d_bf_dependencies.inc ================================================================== --- /dev/null +++ devdoc/parts/d_bf_dependencies.inc @@ -0,0 +1,61 @@ + +Regarding packages and dependencies between them Tcllib occupies a +middle position between two extremes: + +[list_begin enumerated] + +[enum] On one side a strongly interdependent set of packages, usually + by a single author, for a single project. Looking at my + (Andreas Kupries) own work examples of such are + [uri https://core.tcl.tk/akupries/marpa/index Marpa], + [uri https://core.tcl.tk/akupries/crimp/index CRIMP], + [uri https://core.tcl.tk/akupries/kinetcl/index Kinetcl], etc. + +[para] For every change the author of the project handles all the + modifications cascading from any incompatibilities it + introduced to the system. + +[enum] On the other side, the world of semi-independent projects by + many different authors where authors know what packages their + own creations depend on, yet usually do not know who else + depends on them. + +[para] The best thing an author making an (incompatible) change to + their project can do is to for one announce such changes in + some way, and for two use versioning to distinguish the code + before and after the change. + +[para] The world is then responsible for adapting, be it by updating + their own projects to the new version, or by sticking to the + old. + +[list_end] + +As mentioned already, Tcllib lives in the middle of that. + +[para] While we as maintainers cannot be aware of all users of + Tcllib's packages, and thus have to rely on the mechanisms + touched on in point 2 above for that, the dependencies between + the packages contained in Tcllib are a different matter. + +[para] As we are collectively responsible for the usability of Tcllib + in toto to the outside world, it behooves us to be individually + mindful even of Tcllib packages we are not directly + maintaining, when they depend on packages under our + maintainership. + + This may be as simple as coordinating with the maintainers of + the affected packages. + + It may also require us to choose how to adapt affected packages + which do not have maintainers, i.e. modify them to use our + changed package properly, or modify them to properly depend on + the unchanged version of our package. + +[para] Note that the above is not only a chore but an opportunity as + well. + + Additional insight can be had by forcing ourselves to look at + our package and the planned change(s) from an outside + perspective, to consider the ramifications of our actions on + others in general, and on dependent packages in particular. ADDED devdoc/parts/d_bf_trunk.inc Index: devdoc/parts/d_bf_trunk.inc ================================================================== --- /dev/null +++ devdoc/parts/d_bf_trunk.inc @@ -0,0 +1,30 @@ + +The management and use of branches is an important part of working +with a [term {Distributed Version Control System}] ([term DVCS]) like +[uri https://www.fossil-scm.org/ fossil]. + +[para] For Tcllib the main branch of the collection is + [term trunk]. In [term git] this branch would be called + [term master], and this is exactly the case in the + [uri https://github.com/tcltk/tcllib/ {github mirror}] of + Tcllib. + +[para] To properly support debugging [emph {each commit}] on this + branch [emph {has to pass the entire testsuite}] of the + collection. Using bisection to determine when an issue appeared + is an example of an action made easier by this constraint. + +[para] This is part of our collective responsibility for the usability + of Tcllib in toto to the outside world. + + As [term fossil] has no mechanism to enforce this condition + this is handled on the honor system for developers and maintainers. + +[para] To make the task easier Tcllib comes with a tool + ([file sak.tcl]) providing a number of commands in + support. These commands are explained in the following sections + of this guide. + +[para] While it is possible and allowed to commit directly to trunk + remember the above constraint regarding the testsuite, and the + coming notes about other possible issues with a commit. ADDED devdoc/parts/d_bf_versions.inc Index: devdoc/parts/d_bf_versions.inc ================================================================== --- /dev/null +++ devdoc/parts/d_bf_versions.inc @@ -0,0 +1,44 @@ +In Tcllib all changes to a package have to come with an increment of +its version number. What part is incremented (patchlevel, minor, major +version) depends on the kind of change made. With multiple changes in +a commit the highest "wins". + +[para] When working in a development branch the version change can be + deferred until it is time to merge, and then has to cover all + the changes in the branch. + +[para] Below a list of the kinds of changes and their associated + version increments: + +[list_begin definitions] +[def [term {D - documentation}]] No increment +[def [term {T - testsuite}]] No increment +[def [term {B - bugfix}]] Patchlevel +[def [term {I - implementation tweak}]] Patchlevel +[def [term {P - performance tweak}]] Patchlevel +[def [term {E - backward-compatible extension}]] Minor +[def [term {API - incompatible change}]] Major +[list_end] + +[para] Note that a commit containing a version increment has to + mention the new version number in its commit message, as well + as the kind of change which caused it. + +[para] Note further that the version number of a package currently + exists in three places. An increment has to update all of them: + +[list_begin enumerated] +[enum] The package implementation. +[enum] The package index ([file pkgIndex.tcl]) +[enum] The package documentation. +[list_end] + +[para] The [file sak.tcl] command [cmd {validate version}] helps + finding discrepancies between the first two. + + All the other [cmd validate] methods are also of interest to + any developer. Invoke it with + + [example { sak.tcl help validate }] + + to see their documentation. ADDED devdoc/parts/d_branchflow.inc Index: devdoc/parts/d_branchflow.inc ================================================================== --- /dev/null +++ devdoc/parts/d_branchflow.inc @@ -0,0 +1,19 @@ +[comment {===================================================================}] +[subsection {Package Dependencies}] +[include d_bf_dependencies.inc] + +[comment {===================================================================}] +[subsection Trunk] +[include d_bf_trunk.inc] + +[comment {===================================================================}] +[subsection Branches] +[include d_bf_branches.inc] + +[comment {===================================================================}] +[subsection {Working with Branches}] +[include d_bf_branchcmds.inc] + +[comment {===================================================================}] +[subsection {Version numbers}] +[include d_bf_versions.inc] ADDED devdoc/parts/d_contrib.inc Index: devdoc/parts/d_contrib.inc ================================================================== --- /dev/null +++ devdoc/parts/d_contrib.inc @@ -0,0 +1,18 @@ + +As a contributor to Tcllib you are committing yourself to: + +[list_begin enumerated] + +[enum] keep the guidelines written down in + [term {Tcl Community - Kind Communication}] in your mind. + The main point to take away from there is + [emph {to be kind to each other}]. + +[enum] Your contributions getting distributed under a BSD/MIT license. + For the details see [term {Tcllib - License}] + +[list_end] + +Contributions are made by entering tickets into our tracker, providing +patches, bundles or branches of code for inclusion, or posting to the +Tcllib related mailing lists. ADDED devdoc/parts/d_dirlayout.inc Index: devdoc/parts/d_dirlayout.inc ================================================================== --- /dev/null +++ devdoc/parts/d_dirlayout.inc @@ -0,0 +1,149 @@ + +[subsection {Main Directories}] + +The main directories in the Tcllib toplevel directory and of interest +to a developer are: + +[list_begin definitions] + +[def [file modules]] + +Each child directory represents one or more packages. + +In the case of the latter the packages are usually related in some +way. Examples are [file base64], [file math], and [file struct], with +loose (base64) to strong (math) relations between the packages in the +directory. + +[def [file apps]] + +This directory contains all the installable applications, with their +documentation. Note that this directory is currently [emph not] split +into sub-directories. + +[def [file examples]] + +Each child directory [file foo] contains one or more example +application for the packages in [file modules/foo]. These examples are +generally not polished enough to be considered for installation. + +[list_end] + +[subsection {More Directories}] + +[list_begin definitions] + +[def [file config]] + +This directory contains files supporting the Unix build system, +i.e. [file configure] and [file Makefile.in]. + +[def [file devdoc]] + +This directories contains the doctools sources for the global +documentation, like this document and its sibling guides. + +[def [file embedded]] + +This directory contains the entire documentation formatted for +[term HTML] and styled to properly mix into the web site generated by +fossil for the repository. + +[para] This is the documentation accessible from the Tcllib home +directory, represented in the repository as [file embedded/index.md]. + +[def [file idoc]] + +This directory contains the entire documentation formatted for +[term nroff] and [term HTML], the latter without any styling. +This is the documentation which will be installed. + +[def [file support]] + +This directory contains the sources of internal packages and utilities +used in the implementation of the [file installer.tcl] and +[file sak.tcl] scripts/tools. + +[list_end] + +[subsection {Top Files}] + +[list_begin definitions] +[def [file aclocal.m4]] +[def [file configure]] +[def [file configure.in]] +[def [file Makefile.in]] + +These four files comprise the Unix build system layered on top of the +[file installer.tcl] script. + +[def [file installer.tcl]] + +The Tcl-based installation script/tool. + +[def [file project.shed]] + +Configuration file for [term {Sean Wood}]'s [syscmd PracTcl] +buildsystem. + +[def [file sak.tcl]] +This is the main tool for developers and release managers, the +[term {Swiss Army Knife}] of management operations on the collection. + +[def [file ChangeLog]] + +The log of changes to the global support, when the sources were held +in [term CVS]. Not relevant any longer with the switch to the +[term fossil] SCM. + +[def [file license.terms]] + +The license in plain ASCII. See also [term {Tcllib - License}] for the +nicely formatted form. The text is identical. + +[def [file README.md]] +[def [file .github/CONTRIBUTING.md]] +[def [file .github/ISSUE_TEMPLATE.md]] +[def [file .github/PULL_REQUEST_TEMPLATE.md]] + +These markdown-formatted documents are used and shown by the github +mirror of these sources, pointing people back to the official location +and issue trackers. + +[def [file DESCRIPTION.txt]] +[def [file STATUS]] +[def [file tcllib.spec]] +[def [file tcllib.tap]] +[def [file tcllib.yml]] + +???? + +[list_end] + +[subsection {File Types}] + +The most common file types, by file extension, are: + +[list_begin definitions] + +[def [file .tcl]] +Tcl code for a package, application, or example. + +[def [file .man]] +Doctools-formatted documentation, usually for a package. + +[def [file .test]] +Test suite for a package, or part of. +Based on [package tcltest]. + +[def [file .bench]] +Performance benchmarks for a package, or part of. +Based on [file modules/bench]. + +[def [file .pcx]] +Syntax rules for [term TclDevKit]'s [syscmd tclchecker]. Using these +rules allows the checker to validate the use of commands of a Tcllib +package [package foo] without having to scan the [file .tcl] files +implementing it. + +[list_end] ADDED devdoc/parts/d_documentation.inc Index: devdoc/parts/d_documentation.inc ================================================================== --- /dev/null +++ devdoc/parts/d_documentation.inc @@ -0,0 +1,76 @@ + +The standard format used for documentation of packages and other +things in Tcllib is [term doctools]. + +Its supporting packages are a part of Tcllib, see the directories +[file modules/doctools] and [file modules/dtplite]. The latter is +an application package, with the actual application +[file apps/dtplite] a light wrapper around it. + +[para] Tcllib developers gain access to these through the [cmd doc] +method of the [file sak.tcl] tool, another (internal) wrapper around +the [file modules/dtplite] application package. + +[comment {===================================================================}] +[subsection {Generate documentation for a specific module}] + +Invoke either + +[example { ./sak.tcl doc html foo }] + +or + +[example { ./sak.tcl doc html modules/foo }] + +to generate HTML for the documentation found in the module [file foo]. + +Instead of [const html] any other supported format can be used here, +of course. + +[para] The generated formatted documentation will be placed into a +directory [file doc] in the current working directory. + +[comment {===================================================================}] +[subsection {Generate documentation for all modules}] + +Invoke the tool without a module name, i.e. + +[example { ./sak.tcl doc html }] + +to generate HTML for the documentation found in all modules. + +Instead of [const html] any other supported format can be used here, +of course. + +[para] The generated formatted documentation will be placed into a +directory [file doc] in the current working directory. + +[comment {===================================================================}] +[subsection {Available output formats, help}] + +Invoke the tool as + +[example { ./sak.tcl help doc }] + +to see the entire set of supported output formats which can be +generated. + +[comment {===================================================================}] +[subsection {Validation without output}] + +Note the special format [const validate]. + +[para] Using this value as the name of the format to generate forces +the tool to simply check that the documentation is syntactically +correct, without generating actual output. + +[para] Invoke it as either + +[example { ./sak.tcl doc validate (modules/)foo }] + +or + +[example { ./sak.tcl doc validate }] + +to either check the packages of a specific module or check all of +them. ADDED devdoc/parts/d_installation.inc Index: devdoc/parts/d_installation.inc ================================================================== --- /dev/null +++ devdoc/parts/d_installation.inc @@ -0,0 +1,94 @@ +A last thing to consider when adding a new package to the collection +is installation. + +[para] How to [emph use] the [file installer.tcl] script is documented +in [term {Tcllib - The Installer's Guide}]. + +[para] Here we document how to extend said installer so that it may +install new package(s) and/or application(s). + +[para] In most cases only a single file has to be modified, the +[file support/installation/modules.tcl] holding one command per module +and application to install. + +[para] The relevant commands are: + +[list_begin definitions] + +[call [cmd Module] [arg name] \ + [arg code-action] \ + [arg doc-action] \ + [arg example-action]] + +Install the packages of module [arg name], found in +[file modules/[arg name]]. + +[para] The [arg code-action] is responsible for installing the +packages and their index. The system currently provides + +[list_begin definitions] + +[def [cmd _tcl]] Copy all [file .tcl] files found in +[file modules/[arg name]] into the installation. + +[def [cmd _tcr]] As [cmd _tcl], copy the [file .tcl] files found in +the subdirectories of [file modules/[arg name]] as well. + +[def [cmd _tci]] As [cmd _tcl], and copy the [file tclIndex.tcl] file +as well. + +[def [cmd _msg]] As [cmd _tcl], and copy the subdirectory [file msgs] +as well. + +[def [cmd _doc]] As [cmd _tcl], and copy the subdirectory +[file mpformats] as well. + +[def [cmd _tex]] As [cmd _tcl], and copy [file .tex] files as well. + +[list_end] + +[para] The [arg doc-action] is responsible for installing the package +documentation. The system currently provides + +[list_begin definitions] +[def [cmd _null]] No documentation available, do nothing. + +[def [cmd _man]] Process the [file .man] files found in +[file modules/[arg name]] and install the results (nroff and/or HTML) +in the proper location, as given to the installer. + +[para] This is actually a fallback, normally the installer uses the +pre-made formatted documentation found under [file idoc]. + +[list_end] + +[para] The [arg example-action] is responsible for installing the +examples. The system currently provides + +[list_begin definitions] +[def [cmd _null]] No examples available, do nothing. + +[def [cmd _exa]] Copy the the directory [file examples/[arg name]] +recursively to the install location for examples. + +[list_end] + +[call [cmd Application] [arg name]] + +Install the application with [arg name], found in [file apps]. + + +[call [cmd Exclude] [arg name]] + +This command signals to the installer which of the listed modules to +[emph not] install. I.e. they name the deprecated modules of Tcllib. + +[list_end] + +[para] If, and only if the above actions are not suitable for the new +module then a second file has to be modified, +[file support/installation/actions.tcl]. + +[para] This file contains the implementations of the available +actions, and is the place where any custom action needed to handle the +special circumstances of module has to be added. ADDED devdoc/parts/d_maintain.inc Index: devdoc/parts/d_maintain.inc ================================================================== --- /dev/null +++ devdoc/parts/d_maintain.inc @@ -0,0 +1,71 @@ + +When contributing one or more packages for full inclusion into Tcllib +you are committing yourself to + +[list_begin enumerated] + +[enum] Keep the guidelines written down in + [term {Tcl Community - Kind Communication}] + (as any contributor) in your mind. The main point to take away + from there is [emph {to be kind to each other}]. + +[enum] Your packages getting distributed under a BSD/MIT license. For + the details see [term {Tcllib - License}] + +[enum] Maintenance of the new packages for a period of two years under + the following rules, and responsibilities: + + [list_begin enumerated] + + [enum] A maintainer may step down after the mandatory period as + they see fit. + + [enum] A maintainer may step down before the end of the + mandatory period, under the condition that a replacement + maintainer is immediately available and has agreed to + serve the remainder of the period, plus their own + mandatory period (see below). + + [enum] When stepping down without a replacement maintainer + taking over the relevant packages have to be flagged as + [const unmaintained]. + + [enum] When a replacement mantainer is brought in for a package + it is (kept) marked as [const maintained] (again). + + [para] A replacement maintainer is bound by the same rules as + the original maintainer, except that the mandatory + period of maintenance is shortened to one year. + + [enum] For any [const unmaintained] package a contributor + interested in becoming its maintainer can become so by + flagging them as [const maintained] with their name and + contact information, committing themselves to the rules + of a replacement maintainer (see previous point). + + [enum] For any already [const maintained] package a contributor + interested in becoming a co-maintainer can become so + with the agreement of the existing maintainer(s), + committing themselves to the rules of a replacement + maintainer (see two points previous). + + [list_end] + + [para] The responsibilities as a maintainer include: + + [list_begin enumerated] + + [enum] Watching Tcllib's ticket tracker for bugs, bug fixes, + and feature requests related to the new packages. + + [enum] Reviewing the aforementioned tickets, rejecting or + applying them + + [enum] Coordination and discussion with ticket submitter during + the development and/or application of bug fixes. + + [list_end] + +[enum] Follow the [sectref {Branching and Workflow}] of this guide. + +[list_end] ADDED devdoc/parts/d_op_aware.inc Index: devdoc/parts/d_op_aware.inc ================================================================== --- /dev/null +++ devdoc/parts/d_op_aware.inc @@ -0,0 +1,57 @@ + +When developing we have to keep ourselves aware of the context of our +work. On what branch are we ? What files have we changed ? What new +files are not yet known to the repository ? What has happened remotely +since we used our checkout ? + +The answers to these questions become especially important when using +a long-lived checkout and coming back to it after some time away. + +[para] Commands to answer questions like the above are: + +[list_begin definitions] + +[def [cmd {fossil pull}]] + + Get all changes done on the remote since the last pull or sync + from it. This has to be done first, before any of the commands + below. + +[para] Even if the commit in our checkout refers to the branch we want + right now control operations committed to the remote may have + changed that from underneath us. + +[def [cmd {fossil info | grep tags}]] +[def [cmd {fossil branch list | grep '\*'}]] + + Two different ways of determining the branch our checkout is + on. + +[def [cmd {fossil timeline}]] + + What have we (and others) done recently ? + +[para] [emph Attention], this information is very likely outdated, the + more the longer we did not use this checkout. + + Run [cmd {fossil pull}] first to get latest information from + the remote repository of the project. + +[def [cmd {fossil timeline current}]] + + Place the commit our checkout is based on at the top of the + timeline. + +[def [cmd {fossil changes}]] + + Lists the files we have changed compared to the commit the + checkout is based on. + +[def [cmd {fossil extra}]] + + Lists the files we have in the checkout the repository does not + know about. This may be leftover chaff from our work, or + something we have forgotten to [cmd {fossil add}] to the + repository yet. + +[list_end] ADDED devdoc/parts/d_op_branch_close.inc Index: devdoc/parts/d_op_branch_close.inc ================================================================== --- /dev/null +++ devdoc/parts/d_op_branch_close.inc @@ -0,0 +1,73 @@ + +Be aware of where you are (see first definition). + +[para] Ensure that you have clean checkout (see second definition). + + In the full-blown sequence (zig-zag) it is [emph required], due + to the merging from trunk. In the shorter sequence it is only + desired. That said, keeping the checkout clean before + any major operations is a good habit to have, in my opinion. + +[para] The full-blown sequencing with checks all the way is to + +[list_begin enumerated] + +[enum] Validate the checkout, i.e. last commit on your branch. Run the + full test suite and other validations, fix all the issues which + have cropped up. + +[enum] Merge the latest state of the [term trunk] (see next definition). + +[enum] Validate the checkout again. The incoming trunk changes may + have broken something now. Do any required fixes. + +[enum] Now merge to the trunk using + +[example { + fossil update trunk + fossil merge --integrate YOUR_BRANCH +}] + +[enum] At this point the checkout should be in the same state as at + the end of point (3) above, because we resolved any issues with + the trunk already. Thus a simple + +[example { + fossil commit ... +}] + + should be sufficient now to commit the merge back and close the + branch (due to the [option --integrate] we used on the merge). + +[para] The more paranoid may validate the checkout a third time before + commiting. +[list_end] + +[para] I call this a [term {zig-zag merge}] because of how the arrows + look in the timeline, from trunk to feature branch for the + first merge, and then back for the final merge. + +[para] A less paranoid can do what I call a [term {simple merge}], + which moves step (2) after step (4) and skips step (3) + entirely. The resulting shorter sequence is + +[list_begin enumerated] +[enum] Validate +[enum] Merge to trunk +[enum] Validate again +[enum] Commit to trunk +[list_end] + +The last step after either zig-zag or plain merge is to + +[example { + fossil sync +}] + +This saves our work to the remote side, and further gives us any other +work done while we were doing our merge. It especially allows us to +check if we raced somebody else, resulting in a split trunk. + +[para] When that happens we should coordinate with the other developer + on who fixes the split, to ensure that we do not race each + other again. ADDED devdoc/parts/d_op_branch_import.inc Index: devdoc/parts/d_op_branch_import.inc ================================================================== --- /dev/null +++ devdoc/parts/d_op_branch_import.inc @@ -0,0 +1,32 @@ + +Be aware of where you are (see first definition). + +[para] Ensure that you have clean checkout (see second definition). + It is [emph required]. + +[para] In most situations you want to import the latest commit of + branch [term trunk] (or other origin). To get it use + +[example { + fossil pull +}] + +[para] With that done we can now import this commit into our current + branch with + +[example { + fossil merge trunk +}] + +[para] Even if [syscmd fossil] does not report any conflicts it is a + good idea to check that the operation has not broken the new + and/or changed functionality we are working on. + +[para] With the establishment of a good merge we then save the state + with + +[example { + fossil commit ... +}] + +before continuing development. ADDED devdoc/parts/d_op_branch_open.inc Index: devdoc/parts/d_op_branch_open.inc ================================================================== --- /dev/null +++ devdoc/parts/d_op_branch_open.inc @@ -0,0 +1,59 @@ + +Be aware of where you are (see first definition). + +[para] Ensure that you have clean checkout (see second definition). + It is [emph required]. + +[para] In most situations you want to be on branch [term trunk], and + you want to be on the latest commit for it. To get there use + +[example { + fossil pull + fossil update trunk +}] + +If some other branch is desired as the starting point for the coming +work replace [term trunk] in the commands above with the name of that +branch. + +[para] With the base line established we now have two ways of creating + the new branch, with differing (dis)advantages. + + The simpler way is to + +[example { + fossil branch new NAME_OF_NEW_BRANCH +}] + +and start developing. The advantage here is that you cannot forget to +create the branch. The disadvantages are that we have a branch commit +unchanged from where we branched from, and that we have to use +high-handed techniques like hiding or shunning to get rid of the +commit should we decide to abandon the work before the first actual +commit on the branch. + +[para] The other way of creating the branch is to start developing, +and then on the first commit use the option [option --branch] to tell +[syscmd fossil] that we are starting a branch now. I.e. run + +[example { + fossil commit --branch NAME_OF_NEW_BRANCH ... +}] + +where [term ...] are any other options used to supply the commit +message, files to commit, etc. + +[para] The (dis)advantages are now reversed. + +[para] We have no superflous commit, only what is actually + developed. The work is hidden until we commit to make our first + commit. + +[para] We may forget to use [option {--branch NAME_OF_NEW_BRANCH}] and + then have to correct that oversight via the fossil web + interface (I am currently unaware of ways of doing such from + the command line, although some magic incantantion of + [cmd {fossil tag create}] may work). + +[para] It helps to keep awareness, like checking before any commit + that we are on the desired branch. ADDED devdoc/parts/d_op_clean.inc Index: devdoc/parts/d_op_clean.inc ================================================================== --- /dev/null +++ devdoc/parts/d_op_clean.inc @@ -0,0 +1,14 @@ + +Be aware of where you are (see first definition). + +[para] For pretty much all the operation recipes below a clean + checkout is at least desired, often required. + To check that a checkout is clean invoke + +[example { + fossil changes + fossil extra +}] + +How to clean up when uncommitted changes of all sorts are found is +context-specific and outside of the scope of this guide. ADDED devdoc/parts/d_testing.inc Index: devdoc/parts/d_testing.inc ================================================================== --- /dev/null +++ devdoc/parts/d_testing.inc @@ -0,0 +1,90 @@ + +Testsuites in Tcllib are based on Tcl's standard test package +[package tcltest], plus utilities found in the directory +[file modules/devtools] + +[para] Tcllib developers invoke the suites through the +[cmd {test run}] method of the [file sak.tcl] tool, with other methods +of [cmd test] providing management operations, for example setting a +list of standard Tcl shells to use. + +[comment {===================================================================}] +[subsection {Invoke the testsuites of a specific module}] + +Invoke either + +[example { ./sak.tcl test run foo }] + +or + +[example { ./sak.tcl test run modules/foo }] + +to invoke the testsuites found in a specific module [file foo]. + +[comment {===================================================================}] +[subsection {Invoke the testsuites of all modules}] + +Invoke the tool without a module name, i.e. + +[example { ./sak.tcl test run }] + +to invoke the testsuites of all modules. + +[comment {===================================================================}] +[subsection {Detailed Test Logs}] + +In all the previous examples the test runner will write a combination +of progress display and testsuite log to the standard output, showing +for each module only the tests that passed or failed and how many of +each in a summary at the end. + +[para] To get a detailed log, it is necessary to invoke the test +runner with additional options. + +[para] For one: + +[example { + ./sak.tcl test run --log LOG foo +}] + +While this shows the same short log on the terminal as before, it also +writes a detailed log to the file [file LOG.log], and excerpts to +other files ([file LOG.summary], [file LOG.failures], etc.). + +[para] For two: + +[example { + ./sak.tcl test run -v foo +}] + +This writes the detailed log to the standard output, instead of the +short log. + +[para] Regardless of form, the detailed log contains a list of all test +cases executed, which failed, and how they failed (expected versus +actual results). + +[comment {===================================================================}] +[subsection {Shell Selection}] + +By default the test runner will use all the Tcl shells specified via +[cmd {test add}] to invoke the specified testsuites, if any. If no +such are specified it will fall back to the Tcl shell used to run the +tool itself. + +[para] Use option [option --shell] to explicitly specify the Tcl shell +to use, like + +[example { + ./sak.tcl test run --shell /path/to/tclsh ... +}] + +[comment {===================================================================}] +[subsection Help] + +Invoke the tool as + +[example { ./sak.tcl help test }] + +to see the detailed help for all methods of [cmd test], and the +associated options. ADDED devdoc/parts/d_testwrite.inc Index: devdoc/parts/d_testwrite.inc ================================================================== --- /dev/null +++ devdoc/parts/d_testwrite.inc @@ -0,0 +1,119 @@ + +While previous sections talked about running the testsuites for a +module and the packages therein, this has no meaning if the module in +question has no testsuites at all. + +[para] This section gives a very basic overview on possible +methodologies for writing tests and testsuites. + +[para] First there are "drudgery" tests. Written to check absolutely +basic assumptions which should never fail. + +[para] For example for a command FOO taking two arguments, three tests +calling it with zero, one, and three arguments. The basic checks that +the command fails if it has not enough arguments, or too many. + +[para] After that come the tests checking things based on our +knowledge of the command, about its properties and assumptions. Some +examples based on the graph operations added during Google's Summer of +Code 2009 are: + +[list_begin itemized] + +[item] The BellmanFord command in struct::graph::ops takes a + [arg startnode] as argument, and this node should be a node of + the graph. This equals one test case checking the behavior when the + specified node is not a node of the graph. + +[para] This often gives rise to code in the implementation which + explicitly checks the assumption and throws an understandable error, + instead of letting the algorithm fail later in some weird + non-deterministic way. + +[para] It is not always possible to do such checks. The graph argument + for example is just a command in itself, and while we expect + it to exhibit a certain interface, i.e. a set of sub-commands + aka methods, we cannot check that it has them, except by + actually trying to use them. That is done by the algorithm + anyway, so an explicit check is just overhead we can get by + without. + +[item] IIRC one of the distinguishing characteristic of either + BellmanFord and/or Johnson is that they are able to handle + negative weights. Whereas Dijkstra requires positive weights. + +[para] This induces (at least) three testcases ... Graph with all + positive weights, all negative, and a mix of positive and + negative weights. + + Thinking further does the algorithm handle the weight + [const 0] as well ? Another test case, or several, if we mix + zero with positive and negative weights. + +[item] The two algorithms we are currently thinking about are about + distances between nodes, and distance can be 'Inf'inity, + i.e. nodes may not be connected. This means that good test + cases are + + [list_begin enumerated] + [enum] Strongly connected graph + [enum] Connected graph + [enum] Disconnected graph. + [list_end] + + [para] At the extremes of strongly connected and disconnected + we have the fully connected graphs and graphs without edges, + only nodes, i.e. completely disconnected. + +[item] IIRC both of the algorithms take weighted arcs, and fill in a + default if arcs are left unweighted in the input graph. + + [para] This also induces three test cases: + + [list_begin enumerated] + [enum] Graph will all arcs with explicit weights. + [enum] Graph without weights at all. + [enum] Graph with mixture of weighted and unweighted graphs. + [list_end] +[list_end] + +[para] What was described above via examples is called +[term black-box] testing. Test cases are designed and written based on +the developer's knowledge of the properties of the algorithm and its +inputs, without referencing a particular implementation. + +[para] Going further, a complement to [term black-box] testing is +[term white-box]. For this we know the implementation of the +algorithm, we look at it and design our tests cases so that they force +the code through all possible paths in the implementation. Wherever a +decision is made we have a test case forcing a specific direction of +the decision, for all possible combinations and directions. It is easy +to get a combinatorial explosion in the number of needed test-cases. + +[para] In practice I often hope that the black-box tests I have made +are enough to cover all the paths, obviating the need for white-box +tests. + +[para] The above should be enough to make it clear that writing tests +for an algorithm takes at least as much time as coding the algorithm, +and often more time. Much more time. + +See for example also [uri http://sqlite.org/testing.html], a writeup +on how the Sqlite database engine is tested. Another article of +interest might be [uri https://www.researchgate.net/publication/298896236]. +While geared to a particular numerical algorithm it still shows that +even a simple-looking algorithm can lead to an incredible number of +test cases. + +[para] An interesting connection is to documentation. In one +direction, the properties checked with black-box testing are exactly +the properties which should be documented in the algorithm's man +page. And conversely, the documentation of the properties of an +algorithm makes a good reference to base the black-box tests on. + +[para] In practice test cases and documentation often get written +together, cross-influencing each other. And the actual writing of test +cases is a mix of black and white box, possibly influencing the +implementation while writing the tests. Like writing a test for a +condition like [term {startnode not in input graph}] serving as +reminder to put a check for this condition into the code. ADDED devdoc/parts/rm_distribute.inc Index: devdoc/parts/rm_distribute.inc ================================================================== --- /dev/null +++ devdoc/parts/rm_distribute.inc @@ -0,0 +1,39 @@ + +With the release made it has to be published and the world notified of +its existence. + +[list_begin enumerated] + +[enum] Create a proper fossil event for the release, via + [uri http://core.tcl-lang.org/tcllib/eventedit]. + +[para] An [uri http://core.tcl-lang.org/tcllib/event/dac0ddcd2e990234143196b4dc438fe01e7b9817 {existing event}] should be used as template. + +[enum] Update a number of web locations: + +[list_begin enumerated] +[enum] [uri http://core.tcl-lang.org/tcllib/doc/trunk/embedded/index.md {Home page}] +[enum] [uri http://core.tcl-lang.org/tcllib/wiki?name=Downloads Downloads] +[enum] [uri http://core.tcl-lang.org/tcllib/wiki?name=Past+Releases {Past Releases}] +[enum] [uri http://www.tcl-lang.org/home/release.txt ] +[enum] [uri http://www.tcl-lang.org/software/tcllib/*.tml] +[enum] [uri http://wiki.tcl-lang.org/page/Tcllib] +[list_end] + +The first location maps to the file [file embedded/index.md] in the +repository itself, as such it can edited as part of the release +process. This is where reference to the new fossil event is added, as +the new current release. + +[para] The next two locations are in the fossil tcllib wiki and +require admin or wiki write permissions for +[uri http://core.tcl-lang.org/tcllib]. + +[para] The last two locations require ssh access to +[uri http://www.tcl-lang.org] and permission to edit +files in the web area. + + +[enum] ***TODO*** mailing lists and other places to send notes to. + +[list_end] ADDED devdoc/parts/rm_final.inc Index: devdoc/parts/rm_final.inc ================================================================== --- /dev/null +++ devdoc/parts/rm_final.inc @@ -0,0 +1,1 @@ +todo: finalize release, make candidate official ADDED devdoc/parts/rm_start.inc Index: devdoc/parts/rm_start.inc ================================================================== --- /dev/null +++ devdoc/parts/rm_start.inc @@ -0,0 +1,1 @@ +todo: open a candidate for release ADDED devdoc/parts/rm_tooling.inc Index: devdoc/parts/rm_tooling.inc ================================================================== --- /dev/null +++ devdoc/parts/rm_tooling.inc @@ -0,0 +1,18 @@ + +The [file sak.tcl] script in the toplevel directory of a Tcllib +checkout is the one tool used by the release manager to perform its +[sectref Tasks]. + +[para] The main commands to be used are + +[example { + sak.tcl validate + sak.tcl test run + sak.tcl review + sak.tcl readme + sak.tcl localdoc + sak.tcl release +}] + +More detail will be provided in the explanations of the various +[sectref Tasks]. ADDED devdoc/parts/rm_work.inc Index: devdoc/parts/rm_work.inc ================================================================== --- /dev/null +++ devdoc/parts/rm_work.inc @@ -0,0 +1,7 @@ +todo: test, validate and check that the candidate is worthy of release +fix testsuites, possibly fix packages, documentation +regenerate docs +coordinate with package maintainers wrt fixes + +big thing: going over the packages, classify changes since last +release to generate a nice readme. ADDED devdoc/parts/rq_critcl.inc Index: devdoc/parts/rq_critcl.inc ================================================================== --- /dev/null +++ devdoc/parts/rq_critcl.inc @@ -0,0 +1,35 @@ + +[subsection Critcl] + +The [syscmd critcl] tool is an [emph optional] dependency. + +[para] It is only required when trying to build the C-based +[term accelerators] for a number of packages, as explained in +[sectref {Critcl & Accelerators}] + +[para] Tcllib's build system looks for it in the [variable PATH], +using the name [syscmd critcl]. This is for Unix. + +On Windows on the other hand the search is more complex. First we look +for a proper application [syscmd critcl.exe]. When that is not found +we look for a combination of interpreter ([syscmd tclkitsh.exe], +[syscmd tclsh.exe]) and starkit ([syscmd critcl.kit], [syscmd critcl]) +instead. [emph Note] that the choice of starkit can be overriden via +the environment variable [variable CRITCL]. + +[para] Tcllib requires Critcl version 2 or higher. + +[para] The github repository providing releases of version 2 and +higher, and the associated sources, can be found at +[uri http://andreas-kupries.github.com/critcl]. + +[para] Any branch of the repository can be used (if not using the +prebuild starkit or starpack), although the use of the stable branch +[emph master] is recommended. + +[para] At the above url is also an explanation on how to build and +install Critcl, including a list of its dependencies. + +[para] Its instructions will not be repeated here. If there are +problems with these directions please file a ticket against the +[term Critcl] project, and not Tcllib. ADDED devdoc/parts/rq_tcl.inc Index: devdoc/parts/rq_tcl.inc ================================================================== --- /dev/null +++ devdoc/parts/rq_tcl.inc @@ -0,0 +1,46 @@ + +[subsection Tcl] + +As we are installing a number of Tcl packages and applications it +should be pretty much obvious that a working installation of Tcl +itself is needed, and I will not belabor the point. + +[para] Out of the many possibilities use whatever you are comfortable +with, as long as it provides at the very least Tcl 8.2, or higher. + +This may be a Tcl installation provided by your operating system +distribution, from a distribution-independent vendor, or built by +yourself. + +[para] [emph Note] that the packages in Tcllib have begun to require +8.4, 8.5, and even 8.6. Older versions of Tcl will not be able to use +such packages. Trying to use them will result in +[emph {package not found}] errors, as their package index files will +not register them in versions of the core unable to use them. + +[para] Myself, I used (and still use) +[uri http://www.activestate.com ActiveState's] +ActiveTcl 8.5 distribution during development, as I am most familiar +with it. + +[para] [emph {(Disclosure: I, Andreas Kupries, worked for ActiveState until 2016, maintaining ActiveTcl and TclDevKit for them).}]. +I am currently working for SUSE Software Canada ULC, although not in +Tcl-related areas. + +[para] This distribution can be found at +[uri http://www.activestate.com/activetcl]. Retrieve the archive of +ActiveTcl 8.5 (or higher) for your platform and install it as directed +by ActiveState. + +[para] For those wishing to build and install Tcl on their own, the +relevant sources can be found at + +[list_begin definitions] +[def Tcl] [uri http://core.tcl-lang.org/tcl/] +[list_end] + +together with the necessary instructions on how to build it. + +[para] If there are problems with building, installing, or using Tcl, +please file a ticket against [term Tcl], or the vendor of your +distribution, and [emph not] [term Tcllib]. ADDED devdoc/parts/welcome.inc Index: devdoc/parts/welcome.inc ================================================================== --- /dev/null +++ devdoc/parts/welcome.inc @@ -0,0 +1,6 @@ + +Welcome to Tcllib, the Tcl Standard Library. Note that Tcllib is not a +package itself. It is a collection of (semi-independent) [term Tcl] +packages that provide utility functions useful to a large collection +of Tcl programmers. + DELETED devdoc/releaseguide.html Index: devdoc/releaseguide.html ================================================================== --- devdoc/releaseguide.html +++ /dev/null @@ -1,72 +0,0 @@ - - -

Guide to the creation of source releases for Tcllib -

-
- -

Recap -

-
- - -

-The CVS repository for Tcllib contains two main branches, - the HEAD for development, and RELEASES as the staging area for - official releases. -

- -

Dependencies -

- -

Creation of a new official release -

- -

To create a new official release of Tcllib the release manager has - to perform the steps described below: -

- - -
    -
  1. Retrieve the sources at the current head - from the CVS repository, using a command like -
    -	  CVSROOT=:pserver:anonymous@cvs.tcllib.sourceforge.net:/cvsroot/tcllib
    -	  cvs -d${CVSROOT} co tcllib
    -
    - Vary this command according to taste as long as the overall - meaning is not changed. Compression options and the like. - -
  2. Tag these sources with a new branch tag for the new release of - tcllib, like -
    -	  cvs -d${CVSROOT} rtag tcllib
    -
    - -
  3. Commit the changes, then update the working directory. - -
  4. Use a tclsh to run the sak tool with the argument gendist, like -
    -    tclsh /path/to/tcllib/sak.tcl gendist
    -
    - -
  5. This results in the creation of a tcllib-VERSION directory -in the current working directory, and of two archives, .zip, -and .tar.gz. A starkit will be created if sdx is present -in the PATH. If additionally a file named tclkit is present in -the current working directory a starpack will be created too, using -this tclkit as the runtime. - - -
  6. Now follow the instructions in the Sourceforge site documentation - for uploading the archives generated by the last - step to - ftp://upload.sourceforge.net/incoming, and - follow the procedures for creating packages and - releases at Sourceforge. -
- -

At last notify the relevant persons in other communities like -Debian (See list of contacts) about the new release. -

ADDED devdoc/tcl_community_communication.man Index: devdoc/tcl_community_communication.man ================================================================== --- /dev/null +++ devdoc/tcl_community_communication.man @@ -0,0 +1,178 @@ +[comment {-*- tcl -*- doctools manpage}] +[manpage_begin tcl_community_communication n 1] +[titledesc {Tcl Community - Kind Communication}] +[description] + +The Tcl Community encourages contributions from anyone who wishes to +advance the development of: + +[list_begin itemized] +[item] The Tcl Language +[item] Tcl derived languages +[item] Tcl related libraries +[item] Tcl extensions +[item] External Projects that Integrate Tcl +[list_end] + +[para] We welcome those contributions from anyone. We are blind to +gender, race, religion, cultural background, cybernetic nature, and +any other demographic characteristics, as well as personal political +views. + +[para] A community lives and dies by communications. And occasionally +our communications are peppered with patterns that are harsh, +unfriendly, unwelcoming and/or otherwise unkind. As a volunteer +community, we need all of the help we can get. Therefore, we ask all +contributors to make a conscious effort, in Tcl Community discussions, +to communicate in ways that are welcoming. Ways that are +friendly. Ways that are, in a word: kind. + +[para] These guidelines suggest specific ways to accomplish that goal. + +[para] Please note: for the balance of this document any reference to +"People", "Persons", "anybody" or "somebody" can refer to any sentient +being, not merely corporeal members of the species Homo Sapien. + +[list_begin definitions] + +[def {We are a Sanctuary not a Clubhouse}] + +The Tcl Community is a collective of amateurs and professionals who +code, test, and use tools. Our community is open to all. There is no +velvet rope. There is no bouncer at the door. There are no secret +handshakes. Any sentient being who enters our midst is welcome. If +someone is ever asked to leave, it is only because they are being +disruptive to the functioning of the community. + +[def {We Merit Ideas, Not People}] + +A good idea can come from anyone, regardless of how little time they +have been with us. A bad idea can come from anyone, regardless of how +much time or how little time they have been with us. We judge a +concept by how it stands up to scrutiny of logic, implementation, and +regression testing. We don’t judge ideas based on who had the idea +first, who agrees with the idea, or who disagrees with it. + +[def {Treat Everyone with Respect}] + +Everyone is deserving of respect and courtesy at all times. + +[def {Refer to people by the names they use.}] + +If grammar requires you to state a gender for a person, honor their +preferences about their gender identity. If you are unsure as to the +gender of an individual, ask. If someone had to guess about your +gender and got it wrong, please correct them and do not take it +personally. + +[def {Do not take a harsh tone towards other participants.}] + +Do not make personal attacks against anyone (participant or not.) + +[para] Criticize statements and actions, never people. + +[def {Don’t Take Things Personally}] + +When in doubt, assume the best in people. A criticism of your +statements is not a personal attack on you. + +[def {Persons, not People}] + +Stereotypes are an unhelpful tool on many accounts. They are generally +oversimplified. They are usually flat out wrong. And even if "right" +they are of absolutely no utility in determining the capabilities, +motivations, or fitness of an individual. + +[para] Don’t use them in Tcl Community communications. + +[def {Mistakes Happen}] + +The human condition is a series of trials and errors. Progress is when +we get one more trial than error. Being wrong or making a mistake is +the default state of humanity. Accept the errors of your fellow +sentient beings, and be aware that you are also fallible. + +[def {Keep it Real}] + +Please respond to what people actually say. We are all amazing +individuals, but none among us are mind readers. If you find yourself +responding to what you imagine someone is thinking, odds are you are +going to be wrong. + +[para] If you must criticize someone, stick to things they have +actually done. Never criticize for something you speculate they have +done. Or imagine they have done. Or something someone who shares some +attribute with them has done in the past. + +[para] Keep discussions about any non-Tcl subjects to what can be +stated factually and without emotion or judgement. + +[def {When Trouble Arises, Don’t Escalate}] + +If you feel you are being personally attacked or offended, take the +high road. Punching back in a public forum will only makes things +worse. Address the matter in a private correspondence. Be +polite. Express your feelings, but note that you are expressing your +feelings. When writing, look for a way to calm matters down. And when +in doubt, sleep on your letter before pressing send. And when not in +doubt, sleep on it for another day after that. + +[para] If you are a spectator to a fight in progress, politely request +the two parties take the matter to a more private forum. + +[def {Always get the Last Word: I’m Sorry}] + +If an personal argument does arise, be the first to apologize. An +apology does not concede a logical point. It merely acknowledges that +at some point the discussion left either logic, community decency, or +both. Return to the topic when cooler heads can prevail. + +[def {Nobody is Keeping Score}] + +There is no prize for being right. There is no cost for being wrong. A +hard sell is not going to advance your idea along any more than a +logical argument. You aren’t running for office. This isn’t debate +club. If you find yourself continuing a discussion beyond where a +topic can be logically discussed, stop. + +[def {No Evangelizing}] + +The Tcl Community is not the place to promote your chosen operating +system, political outlook, religion, marketing scheme, or economic +model. Period. + +[para] (And if you do bring it up, be prepared to have your chosen +topic discussed logically. And odds are, not favorably.) + +[def {Respect the Community}] + +If the Community has come to a decision on a course of action, please +stop arguing. + +[para] If someone complains about how you are expressing your ideas, +listen. + +[para] If your words are hurting people, stop. There is no amount of +being "right" that makes up for someone leaving our midst because they +felt insulted, threatened, or ignored. + +[list_end] + +By following these guidelines, we will build our community, encourage +more contribution to our projects, and our discussions will be +friendlier and reach conclusions more easily. + +[para] Thank You. + +[section Signatories] +[list_begin itemized] +[item] Sean "the Hypnotoad" Woods +[item] Andreas Kupries +[list_end] + +[section Authors] +[list_begin definitions] +[def Primary] Sean "the Hypnotoad" Woods +[def {Light editing}] Andreas Kupries +[list_end] +[manpage_end] ADDED devdoc/tcllib_devguide.man Index: devdoc/tcllib_devguide.man ================================================================== --- /dev/null +++ devdoc/tcllib_devguide.man @@ -0,0 +1,62 @@ +[comment {-*- tcl -*- doctools manpage}] +[manpage_begin tcllib_devguide n 1] +[titledesc {Tcllib - The Developer's Guide}] +[description] +[include parts/welcome.inc] + +[para] + +This document is a guide for developers working on Tcllib, +i.e. maintainers fixing bugs, extending the collection's +functionality, etc. + +[para] + +Please read + +[list_begin enum] +[enum] [term {Tcllib - How To Get The Sources}] and +[enum] [term {Tcllib - The Installer's Guide}] +[list_end] + +first, if that was not done already. + +[para] Here we assume that the sources are already available in a +directory of your choice, and that you not only know how to build and +install them, but also have all the necessary requisites to actually +do so. The guide to the sources in particular also explains which +source code management system is used, where to find it, how to set it +up, etc. + +[comment {===================================================================}] +[section Commitments] +[subsection Contributor][include parts/d_contrib.inc] +[subsection Maintainer][include parts/d_maintain.inc] + +[comment {===================================================================}] +[section {Branching and Workflow}] +[include parts/d_branchflow.inc] + +[comment {===================================================================}] +[section {Structural Overview}] +[include parts/d_dirlayout.inc] + +[comment {===================================================================}] +[section {Testsuite Tooling}] +[include parts/d_testing.inc] + +[comment {===================================================================}] +[section {Documentation Tooling}] +[include parts/d_documentation.inc] + +[comment {===================================================================}] +[section {Notes On Writing A Testsuite}] +[include parts/d_testwrite.inc] + +[comment {===================================================================}] +[section {Installation Tooling}] +[include parts/d_installation.inc] + +[comment {===================================================================}] +[manpage_end] + ADDED devdoc/tcllib_installer.man Index: devdoc/tcllib_installer.man ================================================================== --- /dev/null +++ devdoc/tcllib_installer.man @@ -0,0 +1,90 @@ +[comment {-*- tcl -*- doctools manpage}] +[manpage_begin tcllib_install_guide n 1] +[titledesc {Tcllib - The Installer's Guide}] +[description] +[include parts/welcome.inc] + +[para] + +The audience of this document is anyone wishing to build and install +the packages found in Tcllib, for either themselves, or others. + +[para] + +For developers intending to work on the packages themselves we +additionally provide + +[list_begin enum] +[enum] [term {Tcllib - The Developer's Guide}]. +[list_end] + +[para] + +Please read [term {Tcllib - How To Get The Sources}] first, if that +was not done already. Here we assume that the sources are already +available in a directory of your choice. + +[para] + +[comment {===================================================================}] +[section Requisites] + +Before Tcllib can be build and used a number of requisites must be installed. + +These are: + +[list_begin enumerated] +[enum] The scripting language Tcl. + For details see [sectref Tcl]. +[enum] Optionally, the [package critcl] package (C embedding) for [syscmd Tcl]. + For details see [sectref CriTcl]. +[list_end] + +This list assumes that the machine where Tcllib is to be installed is +essentially clean. Of course, if parts of the dependencies listed +below are already installed the associated steps can be skipped. It is +still recommended to read their sections though, to validate that the +dependencies they talk about are indeed installed. + +[include parts/rq_tcl.inc] +[include parts/rq_critcl.inc] + +[comment {= build instructions ==============================================}] +[section {Build & Installation Instructions}] + +As Tcllib is mainly a bundle of packages written in pure Tcl building +it is the same as installing it. The exceptions to this have their own +subsection, [sectref {Critcl & Accelerators}], later on. + +[para] Before that however comes the standard case, differentiated by + the platforms with material differences in the instruction, i.e. + [term Unix]-like, versus [term Windows]. + +[para] Regarding the latter it should also be noted that it is + possible set up an [term Unix]-like environment using projects + like [term MSYS], [term Cygwin], and others. In that case the + user has the choice of which instructions to follow. + +[para] Regardless of environment or platform, a suitable [term Tcl] + has to be installed, and its [syscmd tclsh] should be placed on + the [variable PATH] ([term Unix]) or associated with + [file .tcl] files ([term Windows]). + +[comment %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%] +[subsection {Installing on Unix}] +[include parts/b_unix.inc] + +[comment %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%] +[subsection {Installing on Windows}] +[include parts/b_windows.inc] + +[comment %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%] +[subsection {Critcl & Accelerators}] +[include parts/b_critcl.inc] + +[comment %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%] +[subsection Tooling] +[include parts/b_tooling.inc] + +[manpage_end] + ADDED devdoc/tcllib_license.man Index: devdoc/tcllib_license.man ================================================================== --- /dev/null +++ devdoc/tcllib_license.man @@ -0,0 +1,61 @@ +[comment {-*- tcl -*- doctools manpage}] +[manpage_begin tcllib_license n 1] +[titledesc {Tcllib - License}] +[description] +[include parts/welcome.inc] + +[para] The collection is under the BSD license. + +[section License] + +[para] + +This software is copyrighted by Ajuba Solutions and other parties. +The following terms apply to all files associated with the software +unless explicitly disclaimed in individual files. + +[para] + +The authors hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, +provided that existing copyright notices are retained in all copies +and that this notice is included verbatim in any distributions. No +written agreement, license, or royalty fee is required for any of the +authorized uses. Modifications to this software may be copyrighted by +their authors and need not follow the licensing terms described here, +provided that the new terms are clearly indicated on the first page of +each file where they apply. + +[para] + +IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +[para] + +THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND +THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE +MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +[para] + +GOVERNMENT USE: If you are acquiring this software on behalf of the +U.S. government, the Government shall have only "Restricted Rights" in +the software and related documentation as defined in the Federal +Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you +are acquiring the software on behalf of the Department of Defense, the +software shall be classified as "Commercial Computer Software" and the +Government shall have only "Restricted Rights" as defined in Clause +252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the +authors grant the U.S. Government and others acting in its behalf +permission to use and distribute the software in accordance with the +terms specified in this license. + +[manpage_end] + ADDED devdoc/tcllib_releasemgr.man Index: devdoc/tcllib_releasemgr.man ================================================================== --- /dev/null +++ devdoc/tcllib_releasemgr.man @@ -0,0 +1,45 @@ +[comment {-*- tcl -*- doctools manpage}] +[manpage_begin tcllib_releasemgr n 1] +[titledesc {Tcllib - The Release Manager's Guide}] +[description] +[include parts/welcome.inc] + +[para] + +The audience of this document is the release manager for Tcllib, their +deputies, and anybody else interested in the task of creating +an official release of Tcllib for distribution. + +[para] + +Please read [term {Tcllib - How To Get The Sources}] first, if that +was not done already. Here we assume that the sources are already +available in a directory of your choice. + +[para] + +[comment {===================================================================}] +[section Tools] +[include parts/rm_tooling.inc] + +[comment {===================================================================}] +[section Tasks] + +[comment {===================================================================}] +[subsection {Start a release candidate}] +[include parts/rm_start.inc] + +[comment {===================================================================}] +[subsection {Ready the candidate}] +[include parts/rm_work.inc] + +[comment {===================================================================}] +[subsection {Make it official}] +[include parts/rm_final.inc] + +[comment {===================================================================}] +[subsection {Distribute the release}] +[include parts/rm_distribute.inc] + +[manpage_end] + ADDED devdoc/tcllib_sources.man Index: devdoc/tcllib_sources.man ================================================================== --- /dev/null +++ devdoc/tcllib_sources.man @@ -0,0 +1,69 @@ +[comment {-*- tcl -*- doctools manpage}] +[manpage_begin tcllib_sources n 1] +[titledesc {Tcllib - How To Get The Sources}] +[description] +[include parts/welcome.inc] + +[para] + +The audience of this document is anyone wishing to either have just a +look at Tcllib's source code, or build the packages, or to extend and +modify them. + +[para] For builders and developers we additionally provide + +[list_begin enum] +[enum] [term {Tcllib - The Installer's Guide}]. +[enum] [term {Tcllib - The Developer's Guide}]. +[list_end] + +respectively. + +[section {Source Location}] + +The official repository for Tcllib can be found at +[uri http://core.tcl-lang.org/tcllib] + +[section Retrieval] + +Assuming that you simply wish to look at the sources, or build a +specific revision, the easiest way of retrieving it is to: + +[list_begin enum] +[enum] Log into this site, as "anonymous", using the semi-random password in the captcha. +[enum] Go to the "Timeline". +[enum] Choose the revision you wish to have. +[enum] Follow its link to its detailed information page. +[enum] On that page, choose either the "ZIP" or "Tarball" link to get +a copy of this revision in the format of your choice. +[list_end] + +[section {Source Code Management}] + +For the curious (or a developer-to-be), the sources are managed by the +[uri http://www.fossil-scm.org {Fossil SCM}]. + +Binaries for popular platforms can be found directly at its +[uri http://www.fossil-scm.org/download.html {download page}]. + +[para] + +With that tool available the full history can be retrieved via: + +[example { + fossil clone \ + http://core.tcl-lang.org/tcllib \ + tcllib.fossil +}] + +followed by + +[example { + mkdir tcllib + cd tcllib + fossil open ../tcllib.fossil +}] + +to get a checkout of the head of the trunk. + +[manpage_end] Index: embedded/index.md ================================================================== --- embedded/index.md +++ embedded/index.md @@ -1,22 +1,31 @@

Tcl Library Source Code

-Packages -- [Table Of Contents](md/toc.md) -- [Keyword Index](md/index.md) +Packages - [Table Of Contents](md/toc.md) +    +[Keyword Index](md/index.md)
+## Guides to Tcllib + + * [Tcl Community - Kind Communication](md/tcllib/files/devdoc/tcl_community_communication.md) + * [License](md/tcllib/files/devdoc/tcllib_license.md) + * [How To Get The Sources](md/tcllib/files/devdoc/tcllib_sources.md) + * [How To Build And Install Tcllib](md/tcllib/files/devdoc/tcllib_installer.md) + * [The Developer's Guide](md/tcllib/files/devdoc/tcllib_devguide.md) + * [The Release Manager's Guide](md/tcllib/files/devdoc/tcllib_releasemgr.md) + ## Discussion & Contact Tcllib has two [mailing lists](https://sourceforge.net/p/tcllib/mailman/). Index: embedded/md/index.md ================================================================== --- embedded/md/index.md +++ embedded/md/index.md @@ -394,14 +394,14 @@ |histogram|[counter](tcllib/files/modules/counter/counter\.md)| |hook|[hook](tcllib/files/modules/hook/hook\.md) · [uevent](tcllib/files/modules/uev/uevent\.md)| |horspool|[grammar::aycock](tcllib/files/modules/grammar\_aycock/aycock\.md)| |HTML|[doctools](tcllib/files/modules/doctools/doctools\.md) · [doctools::html::cssdefaults](tcllib/files/modules/doctools2base/html\_cssdefaults\.md) · [doctools::idx](tcllib/files/modules/doctools/docidx\.md) · [doctools::idx](tcllib/files/modules/doctools2idx/idx\_container\.md) · [doctools::idx::export](tcllib/files/modules/doctools2idx/idx\_export\.md) · [doctools::idx::export::html](tcllib/files/modules/doctools2idx/idx\_export\_html\.md) · [doctools::toc](tcllib/files/modules/doctools2toc/toc\_container\.md) · [doctools::toc](tcllib/files/modules/doctools/doctoc\.md) · [doctools::toc::export](tcllib/files/modules/doctools2toc/toc\_export\.md) · [doctools::toc::export::html](tcllib/files/modules/doctools2toc/toc\_export\_html\.md) · [dtplite](tcllib/files/modules/dtplite/pkg\_dtplite\.md) · [dtplite](tcllib/files/apps/dtplite\.md) · [mpexpand](tcllib/files/modules/doctools/mpexpand\.md)| |html|[html](tcllib/files/modules/html/html\.md) · [htmlparse](tcllib/files/modules/htmlparse/htmlparse\.md) · [javascript](tcllib/files/modules/javascript/javascript\.md) · [ncgi](tcllib/files/modules/ncgi/ncgi\.md)| -|http|[autoproxy](tcllib/files/modules/http/autoproxy\.md) · [map::geocode::nominatim](tcllib/files/modules/map/map\_geocode\_nominatim\.md) · [map::slippy::fetcher](tcllib/files/modules/map/map\_slippy\_fetcher\.md) · [tool](tcllib/files/modules/httpd/httpd\.md) · [uri](tcllib/files/modules/uri/uri\.md) · [websocket](tcllib/files/modules/websocket/websocket\.md)| -|httpd|[tool](tcllib/files/modules/httpd/httpd\.md)| +|http|[autoproxy](tcllib/files/modules/http/autoproxy\.md) · [httpd](tcllib/files/modules/httpd/httpd\.md) · [map::geocode::nominatim](tcllib/files/modules/map/map\_geocode\_nominatim\.md) · [map::slippy::fetcher](tcllib/files/modules/map/map\_slippy\_fetcher\.md) · [uri](tcllib/files/modules/uri/uri\.md) · [websocket](tcllib/files/modules/websocket/websocket\.md)| +|httpd|[httpd](tcllib/files/modules/httpd/httpd\.md)| |https|[uri](tcllib/files/modules/uri/uri\.md)| -|httpserver|[tool](tcllib/files/modules/httpd/httpd\.md)| +|httpserver|[httpd](tcllib/files/modules/httpd/httpd\.md)| |huddle|[huddle](tcllib/files/modules/yaml/huddle\.md) · [yaml](tcllib/files/modules/yaml/yaml\.md)| |human readable|[bench::in](tcllib/files/modules/bench/bench\_read\.md) · [bench::out::text](tcllib/files/modules/bench/bench\_wtext\.md)| |hyphenation|[textutil](tcllib/files/modules/textutil/textutil\.md) · [textutil::adjust](tcllib/files/modules/textutil/adjust\.md)| @@ -531,11 +531,11 @@ |markdown|[doctools](tcllib/files/modules/doctools/doctools\.md) · [doctools::idx](tcllib/files/modules/doctools/docidx\.md) · [doctools::toc](tcllib/files/modules/doctools/doctoc\.md)| |markup|[docidx\_intro](tcllib/files/modules/doctools/docidx\_intro\.md) · [docidx\_lang\_cmdref](tcllib/files/modules/doctools/docidx\_lang\_cmdref\.md) · [docidx\_lang\_faq](tcllib/files/modules/doctools/docidx\_lang\_faq\.md) · [docidx\_lang\_intro](tcllib/files/modules/doctools/docidx\_lang\_intro\.md) · [docidx\_lang\_syntax](tcllib/files/modules/doctools/docidx\_lang\_syntax\.md) · [docidx\_plugin\_apiref](tcllib/files/modules/doctools/docidx\_plugin\_apiref\.md) · [doctoc\_intro](tcllib/files/modules/doctools/doctoc\_intro\.md) · [doctoc\_lang\_cmdref](tcllib/files/modules/doctools/doctoc\_lang\_cmdref\.md) · [doctoc\_lang\_faq](tcllib/files/modules/doctools/doctoc\_lang\_faq\.md) · [doctoc\_lang\_intro](tcllib/files/modules/doctools/doctoc\_lang\_intro\.md) · [doctoc\_lang\_syntax](tcllib/files/modules/doctools/doctoc\_lang\_syntax\.md) · [doctoc\_plugin\_apiref](tcllib/files/modules/doctools/doctoc\_plugin\_apiref\.md) · [doctools](tcllib/files/modules/doctools/doctools\.md) · [doctools2idx\_introduction](tcllib/files/modules/doctools2idx/idx\_introduction\.md) · [doctools2toc\_introduction](tcllib/files/modules/doctools2toc/toc\_introduction\.md) · [doctools::idx](tcllib/files/modules/doctools/docidx\.md) · [doctools::idx](tcllib/files/modules/doctools2idx/idx\_container\.md) · [doctools::idx::export](tcllib/files/modules/doctools2idx/idx\_export\.md) · [doctools::idx::import](tcllib/files/modules/doctools2idx/idx\_import\.md) · [doctools::toc](tcllib/files/modules/doctools2toc/toc\_container\.md) · [doctools::toc](tcllib/files/modules/doctools/doctoc\.md) · [doctools::toc::export](tcllib/files/modules/doctools2toc/toc\_export\.md) · [doctools::toc::import](tcllib/files/modules/doctools2toc/toc\_import\.md) · [doctools\_intro](tcllib/files/modules/doctools/doctools\_intro\.md) · [doctools\_lang\_cmdref](tcllib/files/modules/doctools/doctools\_lang\_cmdref\.md) · [doctools\_lang\_faq](tcllib/files/modules/doctools/doctools\_lang\_faq\.md) · [doctools\_lang\_intro](tcllib/files/modules/doctools/doctools\_lang\_intro\.md) · [doctools\_lang\_syntax](tcllib/files/modules/doctools/doctools\_lang\_syntax\.md) · [doctools\_plugin\_apiref](tcllib/files/modules/doctools/doctools\_plugin\_apiref\.md) · [dtplite](tcllib/files/modules/dtplite/pkg\_dtplite\.md) · [dtplite](tcllib/files/apps/dtplite\.md) · [mpexpand](tcllib/files/modules/doctools/mpexpand\.md) · [tcldocstrip](tcllib/files/apps/tcldocstrip\.md)| |MasterCard|[valtype::creditcard::mastercard](tcllib/files/modules/valtype/cc\_mastercard\.md)| |matching|[grammar::me\_intro](tcllib/files/modules/grammar\_me/me\_intro\.md) · [grammar::peg::interp](tcllib/files/modules/grammar\_peg/peg\_interp\.md) · [pt](tcllib/files/apps/pt\.md) · [pt::ast](tcllib/files/modules/pt/pt\_astree\.md) · [pt::cparam::configuration::critcl](tcllib/files/modules/pt/pt\_cparam\_config\_critcl\.md) · [pt::cparam::configuration::tea](tcllib/files/modules/pt/pt\_cparam\_config\_tea\.md) · [pt::json\_language](tcllib/files/modules/pt/pt\_json\_language\.md) · [pt::param](tcllib/files/modules/pt/pt\_param\.md) · [pt::pe](tcllib/files/modules/pt/pt\_pexpression\.md) · [pt::pe::op](tcllib/files/modules/pt/pt\_pexpr\_op\.md) · [pt::peg](tcllib/files/modules/pt/pt\_pegrammar\.md) · [pt::peg::container](tcllib/files/modules/pt/pt\_peg\_container\.md) · [pt::peg::container::peg](tcllib/files/modules/pt/pt\_peg\_container\_peg\.md) · [pt::peg::export](tcllib/files/modules/pt/pt\_peg\_export\.md) · [pt::peg::export::container](tcllib/files/modules/pt/pt\_peg\_export\_container\.md) · [pt::peg::export::json](tcllib/files/modules/pt/pt\_peg\_export\_json\.md) · [pt::peg::export::peg](tcllib/files/modules/pt/pt\_peg\_export\_peg\.md) · [pt::peg::from::container](tcllib/files/modules/pt/pt\_peg\_from\_container\.md) · [pt::peg::from::json](tcllib/files/modules/pt/pt\_peg\_from\_json\.md) · [pt::peg::from::peg](tcllib/files/modules/pt/pt\_peg\_from\_peg\.md) · [pt::peg::import](tcllib/files/modules/pt/pt\_peg\_import\.md) · [pt::peg::import::container](tcllib/files/modules/pt/pt\_peg\_import\_container\.md) · [pt::peg::import::json](tcllib/files/modules/pt/pt\_peg\_import\_json\.md) · [pt::peg::import::peg](tcllib/files/modules/pt/pt\_peg\_import\_peg\.md) · [pt::peg::interp](tcllib/files/modules/pt/pt\_peg\_interp\.md) · [pt::peg::to::container](tcllib/files/modules/pt/pt\_peg\_to\_container\.md) · [pt::peg::to::cparam](tcllib/files/modules/pt/pt\_peg\_to\_cparam\.md) · [pt::peg::to::json](tcllib/files/modules/pt/pt\_peg\_to\_json\.md) · [pt::peg::to::param](tcllib/files/modules/pt/pt\_peg\_to\_param\.md) · [pt::peg::to::peg](tcllib/files/modules/pt/pt\_peg\_to\_peg\.md) · [pt::peg::to::tclparam](tcllib/files/modules/pt/pt\_peg\_to\_tclparam\.md) · [pt::peg\_language](tcllib/files/modules/pt/pt\_peg\_language\.md) · [pt::pegrammar](tcllib/files/modules/pt/pt\_peg\_introduction\.md) · [pt::pgen](tcllib/files/modules/pt/pt\_pgen\.md) · [pt::rde](tcllib/files/modules/pt/pt\_rdengine\.md) · [pt::tclparam::configuration::nx](tcllib/files/modules/pt/pt\_tclparam\_config\_nx\.md) · [pt::tclparam::configuration::snit](tcllib/files/modules/pt/pt\_tclparam\_config\_snit\.md) · [pt::tclparam::configuration::tcloo](tcllib/files/modules/pt/pt\_tclparam\_config\_tcloo\.md) · [pt::util](tcllib/files/modules/pt/pt\_util\.md) · [pt\_export\_api](tcllib/files/modules/pt/pt\_to\_api\.md) · [pt\_import\_api](tcllib/files/modules/pt/pt\_from\_api\.md) · [pt\_introduction](tcllib/files/modules/pt/pt\_introduction\.md) · [pt\_parse\_peg](tcllib/files/modules/pt/pt\_parse\_peg\.md) · [pt\_parser\_api](tcllib/files/modules/pt/pt\_parser\_api\.md) · [pt\_peg\_op](tcllib/files/modules/pt/pt\_peg\_op\.md) · [struct::graph::op](tcllib/files/modules/struct/graphops\.md)| |math|[math](tcllib/files/modules/math/math\.md) · [math::bigfloat](tcllib/files/modules/math/bigfloat\.md) · [math::bignum](tcllib/files/modules/math/bignum\.md) · [math::calculus](tcllib/files/modules/math/calculus\.md) · [math::complexnumbers](tcllib/files/modules/math/qcomplex\.md) · [math::constants](tcllib/files/modules/math/constants\.md) · [math::decimal](tcllib/files/modules/math/decimal\.md) · [math::fuzzy](tcllib/files/modules/math/fuzzy\.md) · [math::geometry](tcllib/files/modules/math/math\_geometry\.md) · [math::interpolate](tcllib/files/modules/math/interpolate\.md) · [math::linearalgebra](tcllib/files/modules/math/linalg\.md) · [math::optimize](tcllib/files/modules/math/optimize\.md) · [math::PCA](tcllib/files/modules/math/pca\.md) · [math::polynomials](tcllib/files/modules/math/polynomials\.md) · [math::rationalfunctions](tcllib/files/modules/math/rational\_funcs\.md) · [math::special](tcllib/files/modules/math/special\.md) · [math::trig](tcllib/files/modules/math/trig\.md) · [simulation::annealing](tcllib/files/modules/simulation/annealing\.md) · [simulation::montecarlo](tcllib/files/modules/simulation/montecarlo\.md) · [simulation::random](tcllib/files/modules/simulation/simulation\_random\.md)| -|mathematics|[math::fourier](tcllib/files/modules/math/fourier\.md) · [math::statistics](tcllib/files/modules/math/statistics\.md)| +|mathematics|[math::fourier](tcllib/files/modules/math/fourier\.md) · [math::quasirandom](tcllib/files/modules/math/quasirandom\.md) · [math::statistics](tcllib/files/modules/math/statistics\.md)| |matrices|[math::linearalgebra](tcllib/files/modules/math/linalg\.md)| |matrix|[csv](tcllib/files/modules/csv/csv\.md) · [math::linearalgebra](tcllib/files/modules/math/linalg\.md) · [report](tcllib/files/modules/report/report\.md) · [struct::matrix](tcllib/files/modules/struct/matrix\.md) · [struct::matrix\_v1](tcllib/files/modules/struct/matrix1\.md) · [struct::queue](tcllib/files/modules/struct/queue\.md) · [struct::stack](tcllib/files/modules/struct/stack\.md)| |max cut|[struct::graph::op](tcllib/files/modules/struct/graphops\.md)| |maximum|[math::optimize](tcllib/files/modules/math/optimize\.md)| |maximum flow|[struct::graph::op](tcllib/files/modules/struct/graphops\.md)| @@ -612,10 +612,11 @@ |object oriented|[snit](tcllib/files/modules/snit/snit\.md) · [snitfaq](tcllib/files/modules/snit/snitfaq\.md) · [stooop](tcllib/files/modules/stooop/stooop\.md) · [switched](tcllib/files/modules/stooop/switched\.md)| |observer|[hook](tcllib/files/modules/hook/hook\.md) · [tcl::transform::observe](tcllib/files/modules/virtchannel\_transform/observe\.md)| |odie|[cron](tcllib/files/modules/cron/cron\.md) · [nettool](tcllib/files/modules/nettool/nettool\.md) · [processman](tcllib/files/modules/processman/processman\.md)| |on\-idle|[uevent::onidle](tcllib/files/modules/uev/uevent\_onidle\.md)| |one time pad|[tcl::transform::otp](tcllib/files/modules/virtchannel\_transform/vt\_otp\.md)| +|oo|[clay](tcllib/files/modules/clay/clay\.md)| |optimization|[math::optimize](tcllib/files/modules/math/optimize\.md) · [simulation::annealing](tcllib/files/modules/simulation/annealing\.md)| |ordered list|[struct::prioqueue](tcllib/files/modules/struct/prioqueue\.md)| |otp|[tcl::transform::otp](tcllib/files/modules/virtchannel\_transform/vt\_otp\.md)| |outer join|[struct::list](tcllib/files/modules/struct/struct\_list\.md)| @@ -685,10 +686,11 @@ #### Keywords: Q ||| |---|---| +|quasi\-random|[math::quasirandom](tcllib/files/modules/math/quasirandom\.md)| |queue|[csv](tcllib/files/modules/csv/csv\.md) · [htmlparse](tcllib/files/modules/htmlparse/htmlparse\.md) · [struct::stack](tcllib/files/modules/struct/stack\.md) · [transfer::copy::queue](tcllib/files/modules/transfer/tqueue\.md)| |quoting|[page\_util\_quote](tcllib/files/modules/page/page\_util\_quote\.md)| #### Keywords: R @@ -797,11 +799,11 @@ |semantic markup|[docidx\_intro](tcllib/files/modules/doctools/docidx\_intro\.md) · [docidx\_lang\_cmdref](tcllib/files/modules/doctools/docidx\_lang\_cmdref\.md) · [docidx\_lang\_faq](tcllib/files/modules/doctools/docidx\_lang\_faq\.md) · [docidx\_lang\_intro](tcllib/files/modules/doctools/docidx\_lang\_intro\.md) · [docidx\_lang\_syntax](tcllib/files/modules/doctools/docidx\_lang\_syntax\.md) · [docidx\_plugin\_apiref](tcllib/files/modules/doctools/docidx\_plugin\_apiref\.md) · [doctoc\_intro](tcllib/files/modules/doctools/doctoc\_intro\.md) · [doctoc\_lang\_cmdref](tcllib/files/modules/doctools/doctoc\_lang\_cmdref\.md) · [doctoc\_lang\_faq](tcllib/files/modules/doctools/doctoc\_lang\_faq\.md) · [doctoc\_lang\_intro](tcllib/files/modules/doctools/doctoc\_lang\_intro\.md) · [doctoc\_lang\_syntax](tcllib/files/modules/doctools/doctoc\_lang\_syntax\.md) · [doctoc\_plugin\_apiref](tcllib/files/modules/doctools/doctoc\_plugin\_apiref\.md) · [doctools2idx\_introduction](tcllib/files/modules/doctools2idx/idx\_introduction\.md) · [doctools2toc\_introduction](tcllib/files/modules/doctools2toc/toc\_introduction\.md) · [doctools\_intro](tcllib/files/modules/doctools/doctools\_intro\.md) · [doctools\_lang\_cmdref](tcllib/files/modules/doctools/doctools\_lang\_cmdref\.md) · [doctools\_lang\_faq](tcllib/files/modules/doctools/doctools\_lang\_faq\.md) · [doctools\_lang\_intro](tcllib/files/modules/doctools/doctools\_lang\_intro\.md) · [doctools\_lang\_syntax](tcllib/files/modules/doctools/doctools\_lang\_syntax\.md) · [doctools\_plugin\_apiref](tcllib/files/modules/doctools/doctools\_plugin\_apiref\.md)| |send|[comm](tcllib/files/modules/comm/comm\.md)| |serialization|[bee](tcllib/files/modules/bee/bee\.md) · [doctools::idx::export::docidx](tcllib/files/modules/doctools2idx/export\_docidx\.md) · [doctools::idx::export::html](tcllib/files/modules/doctools2idx/idx\_export\_html\.md) · [doctools::idx::export::json](tcllib/files/modules/doctools2idx/idx\_export\_json\.md) · [doctools::idx::export::nroff](tcllib/files/modules/doctools2idx/idx\_export\_nroff\.md) · [doctools::idx::export::text](tcllib/files/modules/doctools2idx/idx\_export\_text\.md) · [doctools::idx::export::wiki](tcllib/files/modules/doctools2idx/idx\_export\_wiki\.md) · [doctools::idx::structure](tcllib/files/modules/doctools2idx/idx\_structure\.md) · [doctools::toc::export::doctoc](tcllib/files/modules/doctools2toc/export\_doctoc\.md) · [doctools::toc::export::html](tcllib/files/modules/doctools2toc/toc\_export\_html\.md) · [doctools::toc::export::json](tcllib/files/modules/doctools2toc/toc\_export\_json\.md) · [doctools::toc::export::nroff](tcllib/files/modules/doctools2toc/toc\_export\_nroff\.md) · [doctools::toc::export::text](tcllib/files/modules/doctools2toc/toc\_export\_text\.md) · [doctools::toc::export::wiki](tcllib/files/modules/doctools2toc/toc\_export\_wiki\.md) · [doctools::toc::structure](tcllib/files/modules/doctools2toc/toc\_structure\.md) · [pt::peg::export::container](tcllib/files/modules/pt/pt\_peg\_export\_container\.md) · [pt::peg::export::json](tcllib/files/modules/pt/pt\_peg\_export\_json\.md) · [pt::peg::export::peg](tcllib/files/modules/pt/pt\_peg\_export\_peg\.md) · [pt::peg::from::json](tcllib/files/modules/pt/pt\_peg\_from\_json\.md) · [pt::peg::from::peg](tcllib/files/modules/pt/pt\_peg\_from\_peg\.md) · [pt::peg::import::json](tcllib/files/modules/pt/pt\_peg\_import\_json\.md) · [pt::peg::import::peg](tcllib/files/modules/pt/pt\_peg\_import\_peg\.md) · [pt::peg::to::container](tcllib/files/modules/pt/pt\_peg\_to\_container\.md) · [pt::peg::to::cparam](tcllib/files/modules/pt/pt\_peg\_to\_cparam\.md) · [pt::peg::to::json](tcllib/files/modules/pt/pt\_peg\_to\_json\.md) · [pt::peg::to::param](tcllib/files/modules/pt/pt\_peg\_to\_param\.md) · [pt::peg::to::peg](tcllib/files/modules/pt/pt\_peg\_to\_peg\.md) · [pt::peg::to::tclparam](tcllib/files/modules/pt/pt\_peg\_to\_tclparam\.md) · [struct::graph](tcllib/files/modules/struct/graph\.md) · [struct::tree](tcllib/files/modules/struct/struct\_tree\.md)| |server|[map::geocode::nominatim](tcllib/files/modules/map/map\_geocode\_nominatim\.md) · [map::slippy::fetcher](tcllib/files/modules/map/map\_slippy\_fetcher\.md) · [nameserv::common](tcllib/files/modules/nns/nns\_common\.md) · [nameserv::server](tcllib/files/modules/nns/nns\_server\.md) · [nns\_intro](tcllib/files/modules/nns/nns\_intro\.md) · [nnsd](tcllib/files/apps/nnsd\.md) · [udpcluster](tcllib/files/modules/udpcluster/udpcluster\.md)| |service|[logger](tcllib/files/modules/log/logger\.md)| -|services|[ftpd](tcllib/files/modules/ftpd/ftpd\.md) · [smtpd](tcllib/files/modules/smtpd/smtpd\.md) · [tool](tcllib/files/modules/httpd/httpd\.md)| +|services|[ftpd](tcllib/files/modules/ftpd/ftpd\.md) · [httpd](tcllib/files/modules/httpd/httpd\.md) · [smtpd](tcllib/files/modules/smtpd/smtpd\.md)| |set|[struct::queue](tcllib/files/modules/struct/queue\.md) · [struct::set](tcllib/files/modules/struct/struct\_set\.md)| |sha1|[sha1](tcllib/files/modules/sha1/sha1\.md)| |sha256|[sha256](tcllib/files/modules/sha1/sha256\.md)| |shell|[string::token::shell](tcllib/files/modules/string/token\_shell\.md)| |shortest path|[struct::graph::op](tcllib/files/modules/struct/graphops\.md)| @@ -873,11 +875,11 @@ |tcl|[math::bigfloat](tcllib/files/modules/math/bigfloat\.md) · [math::bignum](tcllib/files/modules/math/bignum\.md) · [math::decimal](tcllib/files/modules/math/decimal\.md) · [math::PCA](tcllib/files/modules/math/pca\.md)| |Tcl module|[docstrip\_util](tcllib/files/modules/docstrip/docstrip\_util\.md)| |Tcl syntax|[doctools::tcl::parse](tcllib/files/modules/doctools2base/tcl\_parse\.md)| |tcler's wiki|[doctools::idx](tcllib/files/modules/doctools2idx/idx\_container\.md) · [doctools::idx::export](tcllib/files/modules/doctools2idx/idx\_export\.md) · [doctools::toc](tcllib/files/modules/doctools2toc/toc\_container\.md) · [doctools::toc::export](tcllib/files/modules/doctools2toc/toc\_export\.md)| |tcllib|[csv](tcllib/files/modules/csv/csv\.md)| -|TclOO|[oo::util](tcllib/files/modules/tool/meta\.md) · [oo::util](tcllib/files/modules/ooutil/ooutil\.md) · [oometa](tcllib/files/modules/oometa/oometa\.md) · [tool](tcllib/files/modules/httpd/httpd\.md) · [tool](tcllib/files/modules/tool/tool\.md) · [tool::dict\_ensemble](tcllib/files/modules/tool/tool\_dict\_ensemble\.md)| +|TclOO|[clay](tcllib/files/modules/clay/clay\.md) · [httpd](tcllib/files/modules/httpd/httpd\.md) · [oo::util](tcllib/files/modules/tool/meta\.md) · [oo::util](tcllib/files/modules/ooutil/ooutil\.md) · [oometa](tcllib/files/modules/oometa/oometa\.md) · [tool](tcllib/files/modules/tool/tool\.md) · [tool::dict\_ensemble](tcllib/files/modules/tool/tool\_dict\_ensemble\.md)| |TCLPARAM|[pt::peg::to::tclparam](tcllib/files/modules/pt/pt\_peg\_to\_tclparam\.md)| |TDPL|[grammar::peg](tcllib/files/modules/grammar\_peg/peg\.md) · [grammar::peg::interp](tcllib/files/modules/grammar\_peg/peg\_interp\.md) · [pt](tcllib/files/apps/pt\.md) · [pt::ast](tcllib/files/modules/pt/pt\_astree\.md) · [pt::cparam::configuration::critcl](tcllib/files/modules/pt/pt\_cparam\_config\_critcl\.md) · [pt::cparam::configuration::tea](tcllib/files/modules/pt/pt\_cparam\_config\_tea\.md) · [pt::json\_language](tcllib/files/modules/pt/pt\_json\_language\.md) · [pt::param](tcllib/files/modules/pt/pt\_param\.md) · [pt::pe](tcllib/files/modules/pt/pt\_pexpression\.md) · [pt::pe::op](tcllib/files/modules/pt/pt\_pexpr\_op\.md) · [pt::peg](tcllib/files/modules/pt/pt\_pegrammar\.md) · [pt::peg::container](tcllib/files/modules/pt/pt\_peg\_container\.md) · [pt::peg::container::peg](tcllib/files/modules/pt/pt\_peg\_container\_peg\.md) · [pt::peg::export](tcllib/files/modules/pt/pt\_peg\_export\.md) · [pt::peg::export::container](tcllib/files/modules/pt/pt\_peg\_export\_container\.md) · [pt::peg::export::json](tcllib/files/modules/pt/pt\_peg\_export\_json\.md) · [pt::peg::export::peg](tcllib/files/modules/pt/pt\_peg\_export\_peg\.md) · [pt::peg::from::container](tcllib/files/modules/pt/pt\_peg\_from\_container\.md) · [pt::peg::from::json](tcllib/files/modules/pt/pt\_peg\_from\_json\.md) · [pt::peg::from::peg](tcllib/files/modules/pt/pt\_peg\_from\_peg\.md) · [pt::peg::import](tcllib/files/modules/pt/pt\_peg\_import\.md) · [pt::peg::import::container](tcllib/files/modules/pt/pt\_peg\_import\_container\.md) · [pt::peg::import::json](tcllib/files/modules/pt/pt\_peg\_import\_json\.md) · [pt::peg::import::peg](tcllib/files/modules/pt/pt\_peg\_import\_peg\.md) · [pt::peg::interp](tcllib/files/modules/pt/pt\_peg\_interp\.md) · [pt::peg::to::container](tcllib/files/modules/pt/pt\_peg\_to\_container\.md) · [pt::peg::to::cparam](tcllib/files/modules/pt/pt\_peg\_to\_cparam\.md) · [pt::peg::to::json](tcllib/files/modules/pt/pt\_peg\_to\_json\.md) · [pt::peg::to::param](tcllib/files/modules/pt/pt\_peg\_to\_param\.md) · [pt::peg::to::peg](tcllib/files/modules/pt/pt\_peg\_to\_peg\.md) · [pt::peg::to::tclparam](tcllib/files/modules/pt/pt\_peg\_to\_tclparam\.md) · [pt::peg\_language](tcllib/files/modules/pt/pt\_peg\_language\.md) · [pt::pegrammar](tcllib/files/modules/pt/pt\_peg\_introduction\.md) · [pt::pgen](tcllib/files/modules/pt/pt\_pgen\.md) · [pt::rde](tcllib/files/modules/pt/pt\_rdengine\.md) · [pt::tclparam::configuration::nx](tcllib/files/modules/pt/pt\_tclparam\_config\_nx\.md) · [pt::tclparam::configuration::snit](tcllib/files/modules/pt/pt\_tclparam\_config\_snit\.md) · [pt::tclparam::configuration::tcloo](tcllib/files/modules/pt/pt\_tclparam\_config\_tcloo\.md) · [pt::util](tcllib/files/modules/pt/pt\_util\.md) · [pt\_export\_api](tcllib/files/modules/pt/pt\_to\_api\.md) · [pt\_import\_api](tcllib/files/modules/pt/pt\_from\_api\.md) · [pt\_introduction](tcllib/files/modules/pt/pt\_introduction\.md) · [pt\_parse\_peg](tcllib/files/modules/pt/pt\_parse\_peg\.md) · [pt\_parser\_api](tcllib/files/modules/pt/pt\_parser\_api\.md) · [pt\_peg\_op](tcllib/files/modules/pt/pt\_peg\_op\.md)| |temp file|[fileutil](tcllib/files/modules/fileutil/fileutil\.md)| |template processing|[textutil::expander](tcllib/files/modules/textutil/expander\.md)| |terminal|[term](tcllib/files/modules/term/term\.md) · [term::ansi::code](tcllib/files/modules/term/ansi\_code\.md) · [term::ansi::code::attr](tcllib/files/modules/term/ansi\_cattr\.md) · [term::ansi::code::ctrl](tcllib/files/modules/term/ansi\_cctrl\.md) · [term::ansi::code::macros](tcllib/files/modules/term/ansi\_cmacros\.md) · [term::ansi::ctrl::unix](tcllib/files/modules/term/ansi\_ctrlu\.md) · [term::ansi::send](tcllib/files/modules/term/ansi\_send\.md) · [term::interact::menu](tcllib/files/modules/term/imenu\.md) · [term::interact::pager](tcllib/files/modules/term/ipager\.md) · [term::receive](tcllib/files/modules/term/receive\.md) · [term::receive::bind](tcllib/files/modules/term/term\_bind\.md) · [term::send](tcllib/files/modules/term/term\_send\.md)| @@ -983,11 +985,11 @@ |wais|[uri](tcllib/files/modules/uri/uri\.md)| |widget|[snit](tcllib/files/modules/snit/snit\.md) · [snitfaq](tcllib/files/modules/snit/snitfaq\.md)| |widget adaptors|[snit](tcllib/files/modules/snit/snit\.md) · [snitfaq](tcllib/files/modules/snit/snitfaq\.md)| |wiki|[doctools::idx](tcllib/files/modules/doctools/docidx\.md) · [doctools::idx](tcllib/files/modules/doctools2idx/idx\_container\.md) · [doctools::idx::export](tcllib/files/modules/doctools2idx/idx\_export\.md) · [doctools::idx::export::wiki](tcllib/files/modules/doctools2idx/idx\_export\_wiki\.md) · [doctools::toc](tcllib/files/modules/doctools2toc/toc\_container\.md) · [doctools::toc](tcllib/files/modules/doctools/doctoc\.md) · [doctools::toc::export](tcllib/files/modules/doctools2toc/toc\_export\.md) · [doctools::toc::export::wiki](tcllib/files/modules/doctools2toc/toc\_export\_wiki\.md)| |word|[doctools::tcl::parse](tcllib/files/modules/doctools2base/tcl\_parse\.md) · [wip](tcllib/files/modules/wip/wip\.md)| -|WWW|[tool](tcllib/files/modules/httpd/httpd\.md)| +|WWW|[httpd](tcllib/files/modules/httpd/httpd\.md)| |www|[uri](tcllib/files/modules/uri/uri\.md)| #### Keywords: X ADDED embedded/md/tcllib/files/devdoc/tcl_community_communication.md Index: embedded/md/tcllib/files/devdoc/tcl_community_communication.md ================================================================== --- /dev/null +++ embedded/md/tcllib/files/devdoc/tcl_community_communication.md @@ -0,0 +1,196 @@ + +[//000000001]: # (tcl\_community\_communication \- ) +[//000000002]: # (Generated from file 'tcl\_community\_communication\.man' by tcllib/doctools with format 'markdown') +[//000000003]: # (tcl\_community\_communication\(n\) 1 tcllib "") + +
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | Modules | Applications ]
+ +# NAME + +tcl\_community\_communication \- Tcl Community \- Kind Communication + +# Table Of Contents + + - [Table Of Contents](#toc) + + - [Description](#section1) + + - [Signatories](#section2) + + - [Authors](#section3) + +# DESCRIPTION + +The Tcl Community encourages contributions from anyone who wishes to advance the +development of: + + - The Tcl Language + + - Tcl derived languages + + - Tcl related libraries + + - Tcl extensions + + - External Projects that Integrate Tcl + +We welcome those contributions from anyone\. We are blind to gender, race, +religion, cultural background, cybernetic nature, and any other demographic +characteristics, as well as personal political views\. + +A community lives and dies by communications\. And occasionally our +communications are peppered with patterns that are harsh, unfriendly, +unwelcoming and/or otherwise unkind\. As a volunteer community, we need all of +the help we can get\. Therefore, we ask all contributors to make a conscious +effort, in Tcl Community discussions, to communicate in ways that are welcoming\. +Ways that are friendly\. Ways that are, in a word: kind\. + +These guidelines suggest specific ways to accomplish that goal\. + +Please note: for the balance of this document any reference to "People", +"Persons", "anybody" or "somebody" can refer to any sentient being, not merely +corporeal members of the species Homo Sapien\. + + - We are a Sanctuary not a Clubhouse + + The Tcl Community is a collective of amateurs and professionals who code, + test, and use tools\. Our community is open to all\. There is no velvet rope\. + There is no bouncer at the door\. There are no secret handshakes\. Any + sentient being who enters our midst is welcome\. If someone is ever asked to + leave, it is only because they are being disruptive to the functioning of + the community\. + + - We Merit Ideas, Not People + + A good idea can come from anyone, regardless of how little time they have + been with us\. A bad idea can come from anyone, regardless of how much time + or how little time they have been with us\. We judge a concept by how it + stands up to scrutiny of logic, implementation, and regression testing\. We + don’t judge ideas based on who had the idea first, who agrees with the idea, + or who disagrees with it\. + + - Treat Everyone with Respect + + Everyone is deserving of respect and courtesy at all times\. + + - Refer to people by the names they use\. + + If grammar requires you to state a gender for a person, honor their + preferences about their gender identity\. If you are unsure as to the gender + of an individual, ask\. If someone had to guess about your gender and got it + wrong, please correct them and do not take it personally\. + + - Do not take a harsh tone towards other participants\. + + Do not make personal attacks against anyone \(participant or not\.\) + + Criticize statements and actions, never people\. + + - Don’t Take Things Personally + + When in doubt, assume the best in people\. A criticism of your statements is + not a personal attack on you\. + + - Persons, not People + + Stereotypes are an unhelpful tool on many accounts\. They are generally + oversimplified\. They are usually flat out wrong\. And even if "right" they + are of absolutely no utility in determining the capabilities, motivations, + or fitness of an individual\. + + Don’t use them in Tcl Community communications\. + + - Mistakes Happen + + The human condition is a series of trials and errors\. Progress is when we + get one more trial than error\. Being wrong or making a mistake is the + default state of humanity\. Accept the errors of your fellow sentient beings, + and be aware that you are also fallible\. + + - Keep it Real + + Please respond to what people actually say\. We are all amazing individuals, + but none among us are mind readers\. If you find yourself responding to what + you imagine someone is thinking, odds are you are going to be wrong\. + + If you must criticize someone, stick to things they have actually done\. + Never criticize for something you speculate they have done\. Or imagine they + have done\. Or something someone who shares some attribute with them has done + in the past\. + + Keep discussions about any non\-Tcl subjects to what can be stated factually + and without emotion or judgement\. + + - When Trouble Arises, Don’t Escalate + + If you feel you are being personally attacked or offended, take the high + road\. Punching back in a public forum will only makes things worse\. Address + the matter in a private correspondence\. Be polite\. Express your feelings, + but note that you are expressing your feelings\. When writing, look for a way + to calm matters down\. And when in doubt, sleep on your letter before + pressing send\. And when not in doubt, sleep on it for another day after + that\. + + If you are a spectator to a fight in progress, politely request the two + parties take the matter to a more private forum\. + + - Always get the Last Word: I’m Sorry + + If an personal argument does arise, be the first to apologize\. An apology + does not concede a logical point\. It merely acknowledges that at some point + the discussion left either logic, community decency, or both\. Return to the + topic when cooler heads can prevail\. + + - Nobody is Keeping Score + + There is no prize for being right\. There is no cost for being wrong\. A hard + sell is not going to advance your idea along any more than a logical + argument\. You aren’t running for office\. This isn’t debate club\. If you find + yourself continuing a discussion beyond where a topic can be logically + discussed, stop\. + + - No Evangelizing + + The Tcl Community is not the place to promote your chosen operating system, + political outlook, religion, marketing scheme, or economic model\. Period\. + + \(And if you do bring it up, be prepared to have your chosen topic discussed + logically\. And odds are, not favorably\.\) + + - Respect the Community + + If the Community has come to a decision on a course of action, please stop + arguing\. + + If someone complains about how you are expressing your ideas, listen\. + + If your words are hurting people, stop\. There is no amount of being "right" + that makes up for someone leaving our midst because they felt insulted, + threatened, or ignored\. + +By following these guidelines, we will build our community, encourage more +contribution to our projects, and our discussions will be friendlier and reach +conclusions more easily\. + +Thank You\. + +# Signatories + + - Sean "the Hypnotoad" Woods + + - Andreas Kupries + +# Authors + + - Primary + + Sean "the Hypnotoad" Woods + + - Light editing + + Andreas Kupries ADDED embedded/md/tcllib/files/devdoc/tcllib_devguide.md Index: embedded/md/tcllib/files/devdoc/tcllib_devguide.md ================================================================== --- /dev/null +++ embedded/md/tcllib/files/devdoc/tcllib_devguide.md @@ -0,0 +1,1043 @@ + +[//000000001]: # (tcllib\_devguide \- ) +[//000000002]: # (Generated from file 'tcllib\_devguide\.man' by tcllib/doctools with format 'markdown') +[//000000003]: # (tcllib\_devguide\(n\) 1 tcllib "") + +
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | Modules | Applications ]
+ +# NAME + +tcllib\_devguide \- Tcllib \- The Developer's Guide + +# Table Of Contents + + - [Table Of Contents](#toc) + + - [Synopsis](#synopsis) + + - [Description](#section1) + + - [Commitments](#section2) + + - [Contributor](#subsection1) + + - [Maintainer](#subsection2) + + - [Branching and Workflow](#section3) + + - [Package Dependencies](#subsection3) + + - [Trunk](#subsection4) + + - [Branches](#subsection5) + + - [Working with Branches](#subsection6) + + - [Version numbers](#subsection7) + + - [Structural Overview](#section4) + + - [Main Directories](#subsection8) + + - [More Directories](#subsection9) + + - [Top Files](#subsection10) + + - [File Types](#subsection11) + + - [Testsuite Tooling](#section5) + + - [Invoke the testsuites of a specific module](#subsection12) + + - [Invoke the testsuites of all modules](#subsection13) + + - [Detailed Test Logs](#subsection14) + + - [Shell Selection](#subsection15) + + - [Help](#subsection16) + + - [Documentation Tooling](#section6) + + - [Generate documentation for a specific module](#subsection17) + + - [Generate documentation for all modules](#subsection18) + + - [Available output formats, help](#subsection19) + + - [Validation without output](#subsection20) + + - [Notes On Writing A Testsuite](#section7) + + - [Installation Tooling](#section8) + +# SYNOPSIS + +[__[Module](\.\./\.\./\.\./index\.md\#module)__ *name* *code\-action* *doc\-action* *example\-action*](#1) +[__[Application](\.\./\.\./\.\./index\.md\#application)__ *name*](#2) +[__Exclude__ *name*](#3) + +# DESCRIPTION + +Welcome to Tcllib, the Tcl Standard Library\. Note that Tcllib is not a package +itself\. It is a collection of \(semi\-independent\) +*[Tcl](\.\./\.\./\.\./index\.md\#tcl)* packages that provide utility functions +useful to a large collection of Tcl programmers\. + +This document is a guide for developers working on Tcllib, i\.e\. maintainers +fixing bugs, extending the collection's functionality, etc\. + +Please read + + 1. *[Tcllib \- How To Get The Sources](tcllib\_sources\.md)* and + + 1. *[Tcllib \- The Installer's Guide](tcllib\_installer\.md)* + +first, if that was not done already\. + +Here we assume that the sources are already available in a directory of your +choice, and that you not only know how to build and install them, but also have +all the necessary requisites to actually do so\. The guide to the sources in +particular also explains which source code management system is used, where to +find it, how to set it up, etc\. + +# Commitments + +## Contributor + +As a contributor to Tcllib you are committing yourself to: + + 1. keep the guidelines written down in *[Tcl Community \- Kind + Communication](tcl\_community\_communication\.md)* in your mind\. The main + point to take away from there is *to be kind to each other*\. + + 1. Your contributions getting distributed under a BSD/MIT license\. For the + details see *[Tcllib \- License](tcllib\_license\.md)* + +Contributions are made by entering tickets into our tracker, providing patches, +bundles or branches of code for inclusion, or posting to the Tcllib related +mailing lists\. + +## Maintainer + +When contributing one or more packages for full inclusion into Tcllib you are +committing yourself to + + 1. Keep the guidelines written down in *[Tcl Community \- Kind + Communication](tcl\_community\_communication\.md)* \(as any contributor\) in + your mind\. The main point to take away from there is *to be kind to each + other*\. + + 1. Your packages getting distributed under a BSD/MIT license\. For the details + see *[Tcllib \- License](tcllib\_license\.md)* + + 1. Maintenance of the new packages for a period of two years under the + following rules, and responsibilities: + + 1) A maintainer may step down after the mandatory period as they see fit\. + + 1) A maintainer may step down before the end of the mandatory period, + under the condition that a replacement maintainer is immediately + available and has agreed to serve the remainder of the period, plus + their own mandatory period \(see below\)\. + + 1) When stepping down without a replacement maintainer taking over the + relevant packages have to be flagged as __unmaintained__\. + + 1) When a replacement mantainer is brought in for a package it is \(kept\) + marked as __maintained__ \(again\)\. + + A replacement maintainer is bound by the same rules as the original + maintainer, except that the mandatory period of maintenance is + shortened to one year\. + + 1) For any __unmaintained__ package a contributor interested in + becoming its maintainer can become so by flagging them as + __maintained__ with their name and contact information, committing + themselves to the rules of a replacement maintainer \(see previous + point\)\. + + 1) For any already __maintained__ package a contributor interested in + becoming a co\-maintainer can become so with the agreement of the + existing maintainer\(s\), committing themselves to the rules of a + replacement maintainer \(see two points previous\)\. + + The responsibilities as a maintainer include: + + 1) Watching Tcllib's ticket tracker for bugs, bug fixes, and feature + requests related to the new packages\. + + 1) Reviewing the aforementioned tickets, rejecting or applying them + + 1) Coordination and discussion with ticket submitter during the + development and/or application of bug fixes\. + + 1. Follow the [Branching and Workflow](#section3) of this guide\. + +# Branching and Workflow + +## Package Dependencies + +Regarding packages and dependencies between them Tcllib occupies a middle +position between two extremes: + + 1. On one side a strongly interdependent set of packages, usually by a single + author, for a single project\. Looking at my \(Andreas Kupries\) own work + examples of such are [Marpa](https://core\.tcl\.tk/akupries/marpa/index), + [CRIMP](https://core\.tcl\.tk/akupries/crimp/index), + [Kinetcl](https://core\.tcl\.tk/akupries/kinetcl/index), etc\. + + For every change the author of the project handles all the modifications + cascading from any incompatibilities it introduced to the system\. + + 1. On the other side, the world of semi\-independent projects by many different + authors where authors know what packages their own creations depend on, yet + usually do not know who else depends on them\. + + The best thing an author making an \(incompatible\) change to their project + can do is to for one announce such changes in some way, and for two use + versioning to distinguish the code before and after the change\. + + The world is then responsible for adapting, be it by updating their own + projects to the new version, or by sticking to the old\. + +As mentioned already, Tcllib lives in the middle of that\. + +While we as maintainers cannot be aware of all users of Tcllib's packages, and +thus have to rely on the mechanisms touched on in point 2 above for that, the +dependencies between the packages contained in Tcllib are a different matter\. + +As we are collectively responsible for the usability of Tcllib in toto to the +outside world, it behooves us to be individually mindful even of Tcllib packages +we are not directly maintaining, when they depend on packages under our +maintainership\. This may be as simple as coordinating with the maintainers of +the affected packages\. It may also require us to choose how to adapt affected +packages which do not have maintainers, i\.e\. modify them to use our changed +package properly, or modify them to properly depend on the unchanged version of +our package\. + +Note that the above is not only a chore but an opportunity as well\. Additional +insight can be had by forcing ourselves to look at our package and the planned +change\(s\) from an outside perspective, to consider the ramifications of our +actions on others in general, and on dependent packages in particular\. + +## Trunk + +The management and use of branches is an important part of working with a +*Distributed Version Control System* \(*DVCS*\) like +[fossil](https://www\.fossil\-scm\.org/)\. + +For Tcllib the main branch of the collection is *trunk*\. In *git* this +branch would be called *master*, and this is exactly the case in the [github +mirror](https://github\.com/tcltk/tcllib/) of Tcllib\. + +To properly support debugging *each commit* on this branch *has to pass the +entire testsuite* of the collection\. Using bisection to determine when an issue +appeared is an example of an action made easier by this constraint\. + +This is part of our collective responsibility for the usability of Tcllib in +toto to the outside world\. As *fossil* has no mechanism to enforce this +condition this is handled on the honor system for developers and maintainers\. + +To make the task easier Tcllib comes with a tool \("sak\.tcl"\) providing a number +of commands in support\. These commands are explained in the following sections +of this guide\. + +While it is possible and allowed to commit directly to trunk remember the above +constraint regarding the testsuite, and the coming notes about other possible +issues with a commit\. + +## Branches + +Given the constraints placed on the *trunk* branch of the repository it is +\(strongly\) recommended to perform any development going beyond trivial changes +on a non\-trunk branch\. + +Outside of the trunk developers are allowed to commit intermediate broken states +of their work\. Only at the end of a development cycle, when the relevant branch +is considered ready for merging, will it be necessary to perform full the set of +validations ensuring that the merge to come will create a good commit on trunk\. + +Note that while a review from a second developer is not a required condition for +merging a branch it is recommended to seek out such an independent opinion as a +means of cross\-checking the work\. + +It also recommended to give any new branch a name which aids in determining +additional details about it\. Examples of good things to stick into a branch name +would be + + - Developer \(nick\)name + + - Ticket hash/reference + + - One or two keywords applicable to the work + + - \.\.\. + +Further, while most development branches are likely quite short\-lived, no +prohibitions exist against making longer\-lived branches\. Creators should however +be mindful that the longer such a branch exists without merges the more +divergent they will tend to be, with an associated increase in the effort which +will have to be spent on either merging from and merging to trunk\. + +## Working with Branches + +In the hope of engendering good work practices now a few example operations +which will come up with branches, and their associated fossil command +\(sequences\)\. + + - *Awareness* + + When developing we have to keep ourselves aware of the context of our work\. + On what branch are we ? What files have we changed ? What new files are not + yet known to the repository ? What has happened remotely since we used our + checkout ? The answers to these questions become especially important when + using a long\-lived checkout and coming back to it after some time away\. + + Commands to answer questions like the above are: + + * __fossil pull__ + + Get all changes done on the remote since the last pull or sync from it\. + This has to be done first, before any of the commands below\. + + Even if the commit in our checkout refers to the branch we want right + now control operations committed to the remote may have changed that + from underneath us\. + + * __fossil info | grep tags__ + + * __fossil branch list | grep '\\\*'__ + + Two different ways of determining the branch our checkout is on\. + + * __fossil timeline__ + + What have we \(and others\) done recently ? + + *Attention*, this information is very likely outdated, the more the + longer we did not use this checkout\. Run __fossil pull__ first to + get latest information from the remote repository of the project\. + + * __fossil timeline current__ + + Place the commit our checkout is based on at the top of the timeline\. + + * __fossil changes__ + + Lists the files we have changed compared to the commit the checkout is + based on\. + + * __fossil extra__ + + Lists the files we have in the checkout the repository does not know + about\. This may be leftover chaff from our work, or something we have + forgotten to __fossil add__ to the repository yet\. + + - *Clean checkouts* + + Be aware of where you are \(see first definition\)\. + + For pretty much all the operation recipes below a clean checkout is at least + desired, often required\. To check that a checkout is clean invoke + + fossil changes + fossil extra + + How to clean up when uncommitted changes of all sorts are found is + context\-specific and outside of the scope of this guide\. + + - *Starting a new branch* + + Be aware of where you are \(see first definition\)\. + + Ensure that you have clean checkout \(see second definition\)\. It is + *required*\. + + In most situations you want to be on branch *trunk*, and you want to be on + the latest commit for it\. To get there use + + fossil pull + fossil update trunk + + If some other branch is desired as the starting point for the coming work + replace *trunk* in the commands above with the name of that branch\. + + With the base line established we now have two ways of creating the new + branch, with differing \(dis\)advantages\. The simpler way is to + + fossil branch new NAME_OF_NEW_BRANCH + + and start developing\. The advantage here is that you cannot forget to create + the branch\. The disadvantages are that we have a branch commit unchanged + from where we branched from, and that we have to use high\-handed techniques + like hiding or shunning to get rid of the commit should we decide to abandon + the work before the first actual commit on the branch\. + + The other way of creating the branch is to start developing, and then on the + first commit use the option __\-\-branch__ to tell __fossil__ that we + are starting a branch now\. I\.e\. run + + fossil commit --branch NAME_OF_NEW_BRANCH ... + + where *\.\.\.* are any other options used to supply the commit message, files + to commit, etc\. + + The \(dis\)advantages are now reversed\. + + We have no superflous commit, only what is actually developed\. The work is + hidden until we commit to make our first commit\. + + We may forget to use __\-\-branch NAME\_OF\_NEW\_BRANCH__ and then have to + correct that oversight via the fossil web interface \(I am currently unaware + of ways of doing such from the command line, although some magic + incantantion of __fossil tag create__ may work\)\. + + It helps to keep awareness, like checking before any commit that we are on + the desired branch\. + + - *Merging a branch into trunk* + + Be aware of where you are \(see first definition\)\. + + Ensure that you have clean checkout \(see second definition\)\. In the + full\-blown sequence \(zig\-zag\) it is *required*, due to the merging from + trunk\. In the shorter sequence it is only desired\. That said, keeping the + checkout clean before any major operations is a good habit to have, in my + opinion\. + + The full\-blown sequencing with checks all the way is to + + 1. Validate the checkout, i\.e\. last commit on your branch\. Run the full + test suite and other validations, fix all the issues which have cropped + up\. + + 1. Merge the latest state of the *trunk* \(see next definition\)\. + + 1. Validate the checkout again\. The incoming trunk changes may have broken + something now\. Do any required fixes\. + + 1. Now merge to the trunk using + + fossil update trunk + fossil merge --integrate YOUR_BRANCH + + 1. At this point the checkout should be in the same state as at the end of + point \(3\) above, because we resolved any issues with the trunk already\. + Thus a simple + + fossil commit ... + + should be sufficient now to commit the merge back and close the branch + \(due to the __\-\-integrate__ we used on the merge\)\. + + The more paranoid may validate the checkout a third time before + commiting\. + + I call this a *zig\-zag merge* because of how the arrows look in the + timeline, from trunk to feature branch for the first merge, and then back + for the final merge\. + + A less paranoid can do what I call a *simple merge*, which moves step \(2\) + after step \(4\) and skips step \(3\) entirely\. The resulting shorter sequence + is + + 1. Validate + + 1. Merge to trunk + + 1. Validate again + + 1. Commit to trunk + + The last step after either zig\-zag or plain merge is to + + fossil sync + + This saves our work to the remote side, and further gives us any other work + done while we were doing our merge\. It especially allows us to check if we + raced somebody else, resulting in a split trunk\. + + When that happens we should coordinate with the other developer on who fixes + the split, to ensure that we do not race each other again\. + + - *Merging from trunk* + + Be aware of where you are \(see first definition\)\. + + Ensure that you have clean checkout \(see second definition\)\. It is + *required*\. + + In most situations you want to import the latest commit of branch *trunk* + \(or other origin\)\. To get it use + + fossil pull + + With that done we can now import this commit into our current branch with + + fossil merge trunk + + Even if __fossil__ does not report any conflicts it is a good idea to + check that the operation has not broken the new and/or changed functionality + we are working on\. + + With the establishment of a good merge we then save the state with + + fossil commit ... + + before continuing development\. + +## Version numbers + +In Tcllib all changes to a package have to come with an increment of its version +number\. What part is incremented \(patchlevel, minor, major version\) depends on +the kind of change made\. With multiple changes in a commit the highest "wins"\. + +When working in a development branch the version change can be deferred until it +is time to merge, and then has to cover all the changes in the branch\. + +Below a list of the kinds of changes and their associated version increments: + + - *D \- documentation* + + No increment + + - *T \- testsuite* + + No increment + + - *B \- bugfix* + + Patchlevel + + - *I \- implementation tweak* + + Patchlevel + + - *P \- performance tweak* + + Patchlevel + + - *E \- backward\-compatible extension* + + Minor + + - *API \- incompatible change* + + Major + +Note that a commit containing a version increment has to mention the new version +number in its commit message, as well as the kind of change which caused it\. + +Note further that the version number of a package currently exists in three +places\. An increment has to update all of them: + + 1. The package implementation\. + + 1. The package index \("pkgIndex\.tcl"\) + + 1. The package documentation\. + +The "sak\.tcl" command __validate version__ helps finding discrepancies +between the first two\. All the other __validate__ methods are also of +interest to any developer\. Invoke it with + + sak.tcl help validate + +to see their documentation\. + +# Structural Overview + +## Main Directories + +The main directories in the Tcllib toplevel directory and of interest to a +developer are: + + - "modules" + + Each child directory represents one or more packages\. In the case of the + latter the packages are usually related in some way\. Examples are "base64", + "math", and "struct", with loose \(base64\) to strong \(math\) relations between + the packages in the directory\. + + - "apps" + + This directory contains all the installable applications, with their + documentation\. Note that this directory is currently *not* split into + sub\-directories\. + + - "examples" + + Each child directory "foo" contains one or more example application for the + packages in "modules/foo"\. These examples are generally not polished enough + to be considered for installation\. + +## More Directories + + - "config" + + This directory contains files supporting the Unix build system, i\.e\. + "configure" and "Makefile\.in"\. + + - "devdoc" + + This directories contains the doctools sources for the global documentation, + like this document and its sibling guides\. + + - "embedded" + + This directory contains the entire documentation formatted for + *[HTML](\.\./\.\./\.\./index\.md\#html)* and styled to properly mix into the + web site generated by fossil for the repository\. + + This is the documentation accessible from the Tcllib home directory, + represented in the repository as "embedded/index\.md"\. + + - "idoc" + + This directory contains the entire documentation formatted for + *[nroff](\.\./\.\./\.\./index\.md\#nroff)* and + *[HTML](\.\./\.\./\.\./index\.md\#html)*, the latter without any styling\. This + is the documentation which will be installed\. + + - "support" + + This directory contains the sources of internal packages and utilities used + in the implementation of the "installer\.tcl" and "sak\.tcl" scripts/tools\. + +## Top Files + + - "aclocal\.m4" + + - "configure" + + - "configure\.in" + + - "Makefile\.in" + + These four files comprise the Unix build system layered on top of the + "installer\.tcl" script\. + + - "installer\.tcl" + + The Tcl\-based installation script/tool\. + + - "project\.shed" + + Configuration file for *Sean Wood*'s + __[PracTcl](\.\./modules/practcl/practcl\.md)__ buildsystem\. + + - "sak\.tcl" + + This is the main tool for developers and release managers, the *Swiss Army + Knife* of management operations on the collection\. + + - "ChangeLog" + + The log of changes to the global support, when the sources were held in + *[CVS](\.\./\.\./\.\./index\.md\#cvs)*\. Not relevant any longer with the + switch to the *fossil* SCM\. + + - "license\.terms" + + The license in plain ASCII\. See also *[Tcllib \- + License](tcllib\_license\.md)* for the nicely formatted form\. The text is + identical\. + + - "README\.md" + + - "\.github/CONTRIBUTING\.md" + + - "\.github/ISSUE\_TEMPLATE\.md" + + - "\.github/PULL\_REQUEST\_TEMPLATE\.md" + + These markdown\-formatted documents are used and shown by the github mirror + of these sources, pointing people back to the official location and issue + trackers\. + + - "DESCRIPTION\.txt" + + - "STATUS" + + - "tcllib\.spec" + + - "tcllib\.tap" + + - "tcllib\.yml" + + ???? + +## File Types + +The most common file types, by file extension, are: + + - "\.tcl" + + Tcl code for a package, application, or example\. + + - "\.man" + + Doctools\-formatted documentation, usually for a package\. + + - "\.test" + + Test suite for a package, or part of\. Based on __tcltest__\. + + - "\.bench" + + Performance benchmarks for a package, or part of\. Based on "modules/bench"\. + + - "\.pcx" + + Syntax rules for *TclDevKit*'s __tclchecker__\. Using these rules + allows the checker to validate the use of commands of a Tcllib package + __foo__ without having to scan the "\.tcl" files implementing it\. + +# Testsuite Tooling + +Testsuites in Tcllib are based on Tcl's standard test package __tcltest__, +plus utilities found in the directory "modules/devtools" + +Tcllib developers invoke the suites through the __test run__ method of the +"sak\.tcl" tool, with other methods of __[test](\.\./\.\./\.\./index\.md\#test)__ +providing management operations, for example setting a list of standard Tcl +shells to use\. + +## Invoke the testsuites of a specific module + +Invoke either + + ./sak.tcl test run foo + +or + + ./sak.tcl test run modules/foo + +to invoke the testsuites found in a specific module "foo"\. + +## Invoke the testsuites of all modules + +Invoke the tool without a module name, i\.e\. + + ./sak.tcl test run + +to invoke the testsuites of all modules\. + +## Detailed Test Logs + +In all the previous examples the test runner will write a combination of +progress display and testsuite log to the standard output, showing for each +module only the tests that passed or failed and how many of each in a summary at +the end\. + +To get a detailed log, it is necessary to invoke the test runner with additional +options\. + +For one: + + ./sak.tcl test run --log LOG foo + +While this shows the same short log on the terminal as before, it also writes a +detailed log to the file "LOG\.log", and excerpts to other files \("LOG\.summary", +"LOG\.failures", etc\.\)\. + +For two: + + ./sak.tcl test run -v foo + +This writes the detailed log to the standard output, instead of the short log\. + +Regardless of form, the detailed log contains a list of all test cases executed, +which failed, and how they failed \(expected versus actual results\)\. + +## Shell Selection + +By default the test runner will use all the Tcl shells specified via __test +add__ to invoke the specified testsuites, if any\. If no such are specified it +will fall back to the Tcl shell used to run the tool itself\. + +Use option __\-\-shell__ to explicitly specify the Tcl shell to use, like + + ./sak.tcl test run --shell /path/to/tclsh ... + +## Help + +Invoke the tool as + + ./sak.tcl help test + +to see the detailed help for all methods of +__[test](\.\./\.\./\.\./index\.md\#test)__, and the associated options\. + +# Documentation Tooling + +The standard format used for documentation of packages and other things in +Tcllib is *[doctools](\.\./\.\./\.\./index\.md\#doctools)*\. Its supporting +packages are a part of Tcllib, see the directories "modules/doctools" and +"modules/dtplite"\. The latter is an application package, with the actual +application "apps/dtplite" a light wrapper around it\. + +Tcllib developers gain access to these through the __doc__ method of the +"sak\.tcl" tool, another \(internal\) wrapper around the "modules/dtplite" +application package\. + +## Generate documentation for a specific module + +Invoke either + + ./sak.tcl doc html foo + +or + + ./sak.tcl doc html modules/foo + +to generate HTML for the documentation found in the module "foo"\. Instead of +__html__ any other supported format can be used here, of course\. + +The generated formatted documentation will be placed into a directory "doc" in +the current working directory\. + +## Generate documentation for all modules + +Invoke the tool without a module name, i\.e\. + + ./sak.tcl doc html + +to generate HTML for the documentation found in all modules\. Instead of +__html__ any other supported format can be used here, of course\. + +The generated formatted documentation will be placed into a directory "doc" in +the current working directory\. + +## Available output formats, help + +Invoke the tool as + + ./sak.tcl help doc + +to see the entire set of supported output formats which can be generated\. + +## Validation without output + +Note the special format __validate__\. + +Using this value as the name of the format to generate forces the tool to simply +check that the documentation is syntactically correct, without generating actual +output\. + +Invoke it as either + + ./sak.tcl doc validate (modules/)foo + +or + + ./sak.tcl doc validate + +to either check the packages of a specific module or check all of them\. + +# Notes On Writing A Testsuite + +While previous sections talked about running the testsuites for a module and the +packages therein, this has no meaning if the module in question has no +testsuites at all\. + +This section gives a very basic overview on possible methodologies for writing +tests and testsuites\. + +First there are "drudgery" tests\. Written to check absolutely basic assumptions +which should never fail\. + +For example for a command FOO taking two arguments, three tests calling it with +zero, one, and three arguments\. The basic checks that the command fails if it +has not enough arguments, or too many\. + +After that come the tests checking things based on our knowledge of the command, +about its properties and assumptions\. Some examples based on the graph +operations added during Google's Summer of Code 2009 are: + + - The BellmanFord command in struct::graph::ops takes a *startnode* as + argument, and this node should be a node of the graph\. This equals one test + case checking the behavior when the specified node is not a node of the + graph\. + + This often gives rise to code in the implementation which explicitly checks + the assumption and throws an understandable error, instead of letting the + algorithm fail later in some weird non\-deterministic way\. + + It is not always possible to do such checks\. The graph argument for example + is just a command in itself, and while we expect it to exhibit a certain + interface, i\.e\. a set of sub\-commands aka methods, we cannot check that it + has them, except by actually trying to use them\. That is done by the + algorithm anyway, so an explicit check is just overhead we can get by + without\. + + - IIRC one of the distinguishing characteristic of either BellmanFord and/or + Johnson is that they are able to handle negative weights\. Whereas Dijkstra + requires positive weights\. + + This induces \(at least\) three testcases \.\.\. Graph with all positive weights, + all negative, and a mix of positive and negative weights\. Thinking further + does the algorithm handle the weight __0__ as well ? Another test case, + or several, if we mix zero with positive and negative weights\. + + - The two algorithms we are currently thinking about are about distances + between nodes, and distance can be 'Inf'inity, i\.e\. nodes may not be + connected\. This means that good test cases are + + 1. Strongly connected graph + + 1. Connected graph + + 1. Disconnected graph\. + + At the extremes of strongly connected and disconnected we have the fully + connected graphs and graphs without edges, only nodes, i\.e\. completely + disconnected\. + + - IIRC both of the algorithms take weighted arcs, and fill in a default if + arcs are left unweighted in the input graph\. + + This also induces three test cases: + + 1. Graph will all arcs with explicit weights\. + + 1. Graph without weights at all\. + + 1. Graph with mixture of weighted and unweighted graphs\. + +What was described above via examples is called *black\-box* testing\. Test +cases are designed and written based on the developer's knowledge of the +properties of the algorithm and its inputs, without referencing a particular +implementation\. + +Going further, a complement to *black\-box* testing is *white\-box*\. For this +we know the implementation of the algorithm, we look at it and design our tests +cases so that they force the code through all possible paths in the +implementation\. Wherever a decision is made we have a test case forcing a +specific direction of the decision, for all possible combinations and +directions\. It is easy to get a combinatorial explosion in the number of needed +test\-cases\. + +In practice I often hope that the black\-box tests I have made are enough to +cover all the paths, obviating the need for white\-box tests\. + +The above should be enough to make it clear that writing tests for an algorithm +takes at least as much time as coding the algorithm, and often more time\. Much +more time\. See for example also +[http://sqlite\.org/testing\.html](http://sqlite\.org/testing\.html), a writeup +on how the Sqlite database engine is tested\. Another article of interest might +be +[https://www\.researchgate\.net/publication/298896236](https://www\.researchgate\.net/publication/298896236)\. +While geared to a particular numerical algorithm it still shows that even a +simple\-looking algorithm can lead to an incredible number of test cases\. + +An interesting connection is to documentation\. In one direction, the properties +checked with black\-box testing are exactly the properties which should be +documented in the algorithm's man page\. And conversely, the documentation of the +properties of an algorithm makes a good reference to base the black\-box tests +on\. + +In practice test cases and documentation often get written together, +cross\-influencing each other\. And the actual writing of test cases is a mix of +black and white box, possibly influencing the implementation while writing the +tests\. Like writing a test for a condition like *startnode not in input graph* +serving as reminder to put a check for this condition into the code\. + +# Installation Tooling + +A last thing to consider when adding a new package to the collection is +installation\. + +How to *use* the "installer\.tcl" script is documented in *[Tcllib \- The +Installer's Guide](tcllib\_installer\.md)*\. + +Here we document how to extend said installer so that it may install new +package\(s\) and/or application\(s\)\. + +In most cases only a single file has to be modified, the +"support/installation/modules\.tcl" holding one command per module and +application to install\. + +The relevant commands are: + + - __[Module](\.\./\.\./\.\./index\.md\#module)__ *name* *code\-action* *doc\-action* *example\-action* + + Install the packages of module *name*, found in "modules/*name*"\. + + The *code\-action* is responsible for installing the packages and their + index\. The system currently provides + + * __\_tcl__ + + Copy all "\.tcl" files found in "modules/*name*" into the installation\. + + * __\_tcr__ + + As __\_tcl__, copy the "\.tcl" files found in the subdirectories of + "modules/*name*" as well\. + + * __\_tci__ + + As __\_tcl__, and copy the "tclIndex\.tcl" file as well\. + + * __\_msg__ + + As __\_tcl__, and copy the subdirectory "msgs" as well\. + + * __\_doc__ + + As __\_tcl__, and copy the subdirectory "mpformats" as well\. + + * __\_tex__ + + As __\_tcl__, and copy "\.tex" files as well\. + + The *doc\-action* is responsible for installing the package documentation\. + The system currently provides + + * __\_null__ + + No documentation available, do nothing\. + + * __\_man__ + + Process the "\.man" files found in "modules/*name*" and install the + results \(nroff and/or HTML\) in the proper location, as given to the + installer\. + + This is actually a fallback, normally the installer uses the pre\-made + formatted documentation found under "idoc"\. + + The *example\-action* is responsible for installing the examples\. The + system currently provides + + * __\_null__ + + No examples available, do nothing\. + + * __\_exa__ + + Copy the the directory "examples/*name*" recursively to the install + location for examples\. + + - __[Application](\.\./\.\./\.\./index\.md\#application)__ *name* + + Install the application with *name*, found in "apps"\. + + - __Exclude__ *name* + + This command signals to the installer which of the listed modules to *not* + install\. I\.e\. they name the deprecated modules of Tcllib\. + +If, and only if the above actions are not suitable for the new module then a +second file has to be modified, "support/installation/actions\.tcl"\. + +This file contains the implementations of the available actions, and is the +place where any custom action needed to handle the special circumstances of +module has to be added\. ADDED embedded/md/tcllib/files/devdoc/tcllib_installer.md Index: embedded/md/tcllib/files/devdoc/tcllib_installer.md ================================================================== --- /dev/null +++ embedded/md/tcllib/files/devdoc/tcllib_installer.md @@ -0,0 +1,339 @@ + +[//000000001]: # (tcllib\_install\_guide \- ) +[//000000002]: # (Generated from file 'tcllib\_installer\.man' by tcllib/doctools with format 'markdown') +[//000000003]: # (tcllib\_install\_guide\(n\) 1 tcllib "") + +
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | Modules | Applications ]
+ +# NAME + +tcllib\_install\_guide \- Tcllib \- The Installer's Guide + +# Table Of Contents + + - [Table Of Contents](#toc) + + - [Description](#section1) + + - [Requisites](#section2) + + - [Tcl](#subsection1) + + - [Critcl](#subsection2) + + - [Build & Installation Instructions](#section3) + + - [Installing on Unix](#subsection3) + + - [Installing on Windows](#subsection4) + + - [Critcl & Accelerators](#subsection5) + + - [Tooling](#subsection6) + +# DESCRIPTION + +Welcome to Tcllib, the Tcl Standard Library\. Note that Tcllib is not a package +itself\. It is a collection of \(semi\-independent\) +*[Tcl](\.\./\.\./\.\./index\.md\#tcl)* packages that provide utility functions +useful to a large collection of Tcl programmers\. + +The audience of this document is anyone wishing to build and install the +packages found in Tcllib, for either themselves, or others\. + +For developers intending to work on the packages themselves we additionally +provide + + 1. *[Tcllib \- The Developer's Guide](tcllib\_devguide\.md)*\. + +Please read *[Tcllib \- How To Get The Sources](tcllib\_sources\.md)* first, +if that was not done already\. Here we assume that the sources are already +available in a directory of your choice\. + +# Requisites + +Before Tcllib can be build and used a number of requisites must be installed\. +These are: + + 1. The scripting language Tcl\. For details see [Tcl](#subsection1)\. + + 1. Optionally, the __critcl__ package \(C embedding\) for + __[Tcl](\.\./\.\./\.\./index\.md\#tcl)__\. For details see __CriTcl__\. + +This list assumes that the machine where Tcllib is to be installed is +essentially clean\. Of course, if parts of the dependencies listed below are +already installed the associated steps can be skipped\. It is still recommended +to read their sections though, to validate that the dependencies they talk about +are indeed installed\. + +## Tcl + +As we are installing a number of Tcl packages and applications it should be +pretty much obvious that a working installation of Tcl itself is needed, and I +will not belabor the point\. + +Out of the many possibilities use whatever you are comfortable with, as long as +it provides at the very least Tcl 8\.2, or higher\. This may be a Tcl installation +provided by your operating system distribution, from a distribution\-independent +vendor, or built by yourself\. + +*Note* that the packages in Tcllib have begun to require 8\.4, 8\.5, and even +8\.6\. Older versions of Tcl will not be able to use such packages\. Trying to use +them will result in *package not found* errors, as their package index files +will not register them in versions of the core unable to use them\. + +Myself, I used \(and still use\) [ActiveState's](http://www\.activestate\.com) +ActiveTcl 8\.5 distribution during development, as I am most familiar with it\. + +*\(Disclosure: I, Andreas Kupries, worked for ActiveState until 2016, +maintaining ActiveTcl and TclDevKit for them\)\.*\. I am currently working for +SUSE Software Canada ULC, although not in Tcl\-related areas\. + +This distribution can be found at +[http://www\.activestate\.com/activetcl](http://www\.activestate\.com/activetcl)\. +Retrieve the archive of ActiveTcl 8\.5 \(or higher\) for your platform and install +it as directed by ActiveState\. + +For those wishing to build and install Tcl on their own, the relevant sources +can be found at + + - Tcl + + [http://core\.tcl\-lang\.org/tcl/](http://core\.tcl\-lang\.org/tcl/) + +together with the necessary instructions on how to build it\. + +If there are problems with building, installing, or using Tcl, please file a +ticket against *[Tcl](\.\./\.\./\.\./index\.md\#tcl)*, or the vendor of your +distribution, and *not* *[Tcllib](\.\./\.\./\.\./index\.md\#tcllib)*\. + +## Critcl + +The __critcl__ tool is an *optional* dependency\. + +It is only required when trying to build the C\-based *accelerators* for a +number of packages, as explained in [Critcl & Accelerators](#subsection5) + +Tcllib's build system looks for it in the , using the name __critcl__\. This +is for Unix\. On Windows on the other hand the search is more complex\. First we +look for a proper application __critcl\.exe__\. When that is not found we look +for a combination of interpreter \(__tclkitsh\.exe__, __tclsh\.exe__\) and +starkit \(__critcl\.kit__, __critcl__\) instead\. *Note* that the choice +of starkit can be overriden via the environment variable \. + +Tcllib requires Critcl version 2 or higher\. + +The github repository providing releases of version 2 and higher, and the +associated sources, can be found at +[http://andreas\-kupries\.github\.com/critcl](http://andreas\-kupries\.github\.com/critcl)\. + +Any branch of the repository can be used \(if not using the prebuild starkit or +starpack\), although the use of the stable branch *master* is recommended\. + +At the above url is also an explanation on how to build and install Critcl, +including a list of its dependencies\. + +Its instructions will not be repeated here\. If there are problems with these +directions please file a ticket against the *Critcl* project, and not Tcllib\. + +# Build & Installation Instructions + +As Tcllib is mainly a bundle of packages written in pure Tcl building it is the +same as installing it\. The exceptions to this have their own subsection, +[Critcl & Accelerators](#subsection5), later on\. + +Before that however comes the standard case, differentiated by the platforms +with material differences in the instruction, i\.e\. *Unix*\-like, versus +*Windows*\. + +Regarding the latter it should also be noted that it is possible set up an +*Unix*\-like environment using projects like *MSYS*, *Cygwin*, and others\. +In that case the user has the choice of which instructions to follow\. + +Regardless of environment or platform, a suitable +*[Tcl](\.\./\.\./\.\./index\.md\#tcl)* has to be installed, and its __tclsh__ +should be placed on the \(*Unix*\) or associated with "\.tcl" files +\(*Windows*\)\. + +## Installing on Unix + +For *Unix*\-like environments Tcllib comes with the standard set of files to +make + + ./configure + make install + +a suitable way of installing it\. This is a standard non\-interactive install +automatically figuring out where to place everything, i\.e\. packages, +applications, and the manpages\. + +To get a graphical installer invoke + + ./installer.tcl + +instead\. + +## Installing on Windows + +In a Windows environment we have the __installer\.tcl__ script to perform +installation\. + +If the desired __tclsh__ is associated "\.tcl" files then double\-clicking / +opening the __installer\.tcl__ is enough to invoke it in graphical mode\. This +assumes that *[Tk](\.\./\.\./\.\./index\.md\#tk)* is installed and available as +well\. + +Without *[Tk](\.\./\.\./\.\./index\.md\#tk)* the only way to invoke the installer +are to open a DOS window, i\.e\. __cmd\.exe__, and then to invoke + + ./installer.tcl + +inside it\. + +## Critcl & Accelerators + +While the majority of Tcllib consists of packages written in pure Tcl a number +of packages also have *accelerators* associated with them\. These are +__critcl__\-based C packages whose use will boost the performance of the +packages using them\. These accelerators are optional, and they are not installed +by default\. + +To build the accelerators the normally optional dependency on __critcl__ +becomes required\. + +To build and install Tcllib with the accelerators in a Unix\-like environment +invoke: + + ./configure + make critcl # This builds the shared library holding + # the accelerators + make install + +The underlying tool is "sak\.tcl" in the toplevel directory of Tcllib and the +command __make critcl__ is just a wrapper around + + ./sak.tcl critcl + +Therefore in a Windows environment instead invoke + + ./sak.tcl critcl + ./installer.tcl + +from within a DOS window, i\.e\. __cmd\.exe__\. + +## Tooling + +The core of Tcllib's build system is the script "installer\.tcl" found in the +toplevel directory of a checkout or release\. + +The + + configure ; make install + +setup available to developers on Unix\-like systems is just a wrapper around it\. +To go beyond the standard embodied in the wrapper it is necessary to directly +invoke this script\. + +On Windows system using it directly is the only way to invoke it\. + +For basic help invoke it as + + ./installer.tcl -help + +This will print a short list of all the available options to the standard output +channel\. + +The commands associated with the various *install* targets in the +*Makefile\.in* for Unix can be used as additional examples on how to use this +tool as well\. + +The installer can operate in GUI and CLI modes\. By default it chooses the mode +automatically, based on if the Tcl package +__[Tk](\.\./\.\./\.\./index\.md\#tk)__ can be used or not\. The option +__\-no\-gui__ can be used to force CLI mode\. + +Note that it is possible to specify options on the command line even if the +installer ultimatively selects GUI mode\. In that case the hardwired defaults and +the options determine the data presented to the user for editing\. + +The installer will select a number of defaults for the locations of packages, +examples, and documentation, and also the format of the documentation\. The user +can overide these defaults in the GUI, or by specifying additional options\. The +defaults depend on the platform detected \(Unix/Windows\) and on the __tclsh__ +executable used to run the installer\. + +*Options* + + - __\-help__ + + Show the list of options explained here on the standard output channel and + exit\. + + - __\+excluded__ + + Include deprecated packages in the installation\. + + - __\-no\-gui__ + + Force command line operation of the installer + + - __\-no\-wait__ + + In CLI mode the installer will by default ask the user to confirm that the + chosen configuration \(destination paths, things to install\) is correct + before performing any action\. Using this option causes the installer to skip + this query and immediately jump to installation\. + + - __\-app\-path__ *path* + + - __\-example\-path__ *path* + + - __\-html\-path__ *path* + + - __\-nroff\-path__ *path* + + - __\-pkg\-path__ *path* + + Declare the destination paths for the applications, examples, html + documentation, nroff manpages, and packages\. The defaults are derived from + the location of the __tclsh__ used to run the installer\. + + - __\-dry\-run__ + + - __\-simulate__ + + Run the installer without modifying the destination directories\. + + - __\-apps__ + + - __\-no\-apps__ + + - __\-examples__ + + - __\-no\-examples__ + + - __\-pkgs__ + + - __\-no\-pkgs__ + + - __\-html__ + + - __\-no\-html__ + + - __\-nroff__ + + - __\-no\-nroff__ + + \(De\)activate the installation of applications, examples, packages, html + documentation, and nroff manpages\. + + Applications, examples, and packages are installed by default\. + + On Windows the html documentation is installed by default\. + + On Unix the nroff manpages are installed by default\. ADDED embedded/md/tcllib/files/devdoc/tcllib_license.md Index: embedded/md/tcllib/files/devdoc/tcllib_license.md ================================================================== --- /dev/null +++ embedded/md/tcllib/files/devdoc/tcllib_license.md @@ -0,0 +1,69 @@ + +[//000000001]: # (tcllib\_license \- ) +[//000000002]: # (Generated from file 'tcllib\_license\.man' by tcllib/doctools with format 'markdown') +[//000000003]: # (tcllib\_license\(n\) 1 tcllib "") + +
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | Modules | Applications ]
+ +# NAME + +tcllib\_license \- Tcllib \- License + +# Table Of Contents + + - [Table Of Contents](#toc) + + - [Description](#section1) + + - [License](#section2) + +# DESCRIPTION + +Welcome to Tcllib, the Tcl Standard Library\. Note that Tcllib is not a package +itself\. It is a collection of \(semi\-independent\) +*[Tcl](\.\./\.\./\.\./index\.md\#tcl)* packages that provide utility functions +useful to a large collection of Tcl programmers\. + +The collection is under the BSD license\. + +# License + +This software is copyrighted by Ajuba Solutions and other parties\. The following +terms apply to all files associated with the software unless explicitly +disclaimed in individual files\. + +The authors hereby grant permission to use, copy, modify, distribute, and +license this software and its documentation for any purpose, provided that +existing copyright notices are retained in all copies and that this notice is +included verbatim in any distributions\. No written agreement, license, or +royalty fee is required for any of the authorized uses\. Modifications to this +software may be copyrighted by their authors and need not follow the licensing +terms described here, provided that the new terms are clearly indicated on the +first page of each file where they apply\. + +IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, +INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE +OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE +AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\. + +THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE, AND NON\-INFRINGEMENT\. THIS SOFTWARE IS PROVIDED ON AN "AS +IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE +MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS\. + +GOVERNMENT USE: If you are acquiring this software on behalf of the U\.S\. +government, the Government shall have only "Restricted Rights" in the software +and related documentation as defined in the Federal Acquisition Regulations +\(FARs\) in Clause 52\.227\.19 \(c\) \(2\)\. If you are acquiring the software on behalf +of the Department of Defense, the software shall be classified as "Commercial +Computer Software" and the Government shall have only "Restricted Rights" as +defined in Clause 252\.227\-7013 \(c\) \(1\) of DFARs\. Notwithstanding the foregoing, +the authors grant the U\.S\. Government and others acting in its behalf permission +to use and distribute the software in accordance with the terms specified in +this license\. ADDED embedded/md/tcllib/files/devdoc/tcllib_releasemgr.md Index: embedded/md/tcllib/files/devdoc/tcllib_releasemgr.md ================================================================== --- /dev/null +++ embedded/md/tcllib/files/devdoc/tcllib_releasemgr.md @@ -0,0 +1,124 @@ + +[//000000001]: # (tcllib\_releasemgr \- ) +[//000000002]: # (Generated from file 'tcllib\_releasemgr\.man' by tcllib/doctools with format 'markdown') +[//000000003]: # (tcllib\_releasemgr\(n\) 1 tcllib "") + +
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | Modules | Applications ]
+ +# NAME + +tcllib\_releasemgr \- Tcllib \- The Release Manager's Guide + +# Table Of Contents + + - [Table Of Contents](#toc) + + - [Description](#section1) + + - [Tools](#section2) + + - [Tasks](#section3) + + - [Start a release candidate](#subsection1) + + - [Ready the candidate](#subsection2) + + - [Make it official](#subsection3) + + - [Distribute the release](#subsection4) + +# DESCRIPTION + +Welcome to Tcllib, the Tcl Standard Library\. Note that Tcllib is not a package +itself\. It is a collection of \(semi\-independent\) +*[Tcl](\.\./\.\./\.\./index\.md\#tcl)* packages that provide utility functions +useful to a large collection of Tcl programmers\. + +The audience of this document is the release manager for Tcllib, their deputies, +and anybody else interested in the task of creating an official release of +Tcllib for distribution\. + +Please read *[Tcllib \- How To Get The Sources](tcllib\_sources\.md)* first, +if that was not done already\. Here we assume that the sources are already +available in a directory of your choice\. + +# Tools + +The "sak\.tcl" script in the toplevel directory of a Tcllib checkout is the one +tool used by the release manager to perform its [Tasks](#section3)\. + +The main commands to be used are + + sak.tcl validate + sak.tcl test run + sak.tcl review + sak.tcl readme + sak.tcl localdoc + sak.tcl release + +More detail will be provided in the explanations of the various +[Tasks](#section3)\. + +# Tasks + +## Start a release candidate + +todo: open a candidate for release + +## Ready the candidate + +todo: test, validate and check that the candidate is worthy of release fix +testsuites, possibly fix packages, documentation regenerate docs coordinate with +package maintainers wrt fixes big thing: going over the packages, classify +changes since last release to generate a nice readme\. + +## Make it official + +todo: finalize release, make candidate official + +## Distribute the release + +With the release made it has to be published and the world notified of its +existence\. + + 1. Create a proper fossil event for the release, via + [http://core\.tcl\-lang\.org/tcllib/eventedit](http://core\.tcl\-lang\.org/tcllib/eventedit)\. + + An [existing + event](http://core\.tcl\-lang\.org/tcllib/event/dac0ddcd2e990234143196b4dc438fe01e7b9817) + should be used as template\. + + 1. Update a number of web locations: + + 1) [Home + page](http://core\.tcl\-lang\.org/tcllib/doc/trunk/embedded/index\.md) + + 1) [Downloads](http://core\.tcl\-lang\.org/tcllib/wiki?name=Downloads) + + 1) [Past + Releases](http://core\.tcl\-lang\.org/tcllib/wiki?name=Past\+Releases) + + 1) [http://www\.tcl\-lang\.org/home/release\.txt](http://www\.tcl\-lang\.org/home/release\.txt) + + 1) [http://www\.tcl\-lang\.org/software/tcllib/\*\.tml](http://www\.tcl\-lang\.org/software/tcllib/\*\.tml) + + 1) [http://wiki\.tcl\-lang\.org/page/Tcllib](http://wiki\.tcl\-lang\.org/page/Tcllib) + + The first location maps to the file "embedded/index\.md" in the repository + itself, as such it can edited as part of the release process\. This is where + reference to the new fossil event is added, as the new current release\. + + The next two locations are in the fossil tcllib wiki and require admin or + wiki write permissions for + [http://core\.tcl\-lang\.org/tcllib](http://core\.tcl\-lang\.org/tcllib)\. + + The last two locations require ssh access to + [http://www\.tcl\-lang\.org](http://www\.tcl\-lang\.org) and permission to + edit files in the web area\. + + 1. \*\*\*TODO\*\*\* mailing lists and other places to send notes to\. ADDED embedded/md/tcllib/files/devdoc/tcllib_sources.md Index: embedded/md/tcllib/files/devdoc/tcllib_sources.md ================================================================== --- /dev/null +++ embedded/md/tcllib/files/devdoc/tcllib_sources.md @@ -0,0 +1,85 @@ + +[//000000001]: # (tcllib\_sources \- ) +[//000000002]: # (Generated from file 'tcllib\_sources\.man' by tcllib/doctools with format 'markdown') +[//000000003]: # (tcllib\_sources\(n\) 1 tcllib "") + +
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | Modules | Applications ]
+ +# NAME + +tcllib\_sources \- Tcllib \- How To Get The Sources + +# Table Of Contents + + - [Table Of Contents](#toc) + + - [Description](#section1) + + - [Source Location](#section2) + + - [Retrieval](#section3) + + - [Source Code Management](#section4) + +# DESCRIPTION + +Welcome to Tcllib, the Tcl Standard Library\. Note that Tcllib is not a package +itself\. It is a collection of \(semi\-independent\) +*[Tcl](\.\./\.\./\.\./index\.md\#tcl)* packages that provide utility functions +useful to a large collection of Tcl programmers\. + +The audience of this document is anyone wishing to either have just a look at +Tcllib's source code, or build the packages, or to extend and modify them\. + +For builders and developers we additionally provide + + 1. *[Tcllib \- The Installer's Guide](tcllib\_installer\.md)*\. + + 1. *[Tcllib \- The Developer's Guide](tcllib\_devguide\.md)*\. + +respectively\. + +# Source Location + +The official repository for Tcllib can be found at +[http://core\.tcl\-lang\.org/tcllib](http://core\.tcl\-lang\.org/tcllib) + +# Retrieval + +Assuming that you simply wish to look at the sources, or build a specific +revision, the easiest way of retrieving it is to: + + 1. Log into this site, as "anonymous", using the semi\-random password in the + captcha\. + + 1. Go to the "Timeline"\. + + 1. Choose the revision you wish to have\. + + 1. Follow its link to its detailed information page\. + + 1. On that page, choose either the "ZIP" or "Tarball" link to get a copy of + this revision in the format of your choice\. + +# Source Code Management + +For the curious \(or a developer\-to\-be\), the sources are managed by the [Fossil +SCM](http://www\.fossil\-scm\.org)\. Binaries for popular platforms can be found +directly at its [download page](http://www\.fossil\-scm\.org/download\.html)\. + +With that tool available the full history can be retrieved via: + + fossil clone http://core.tcl-lang.org/tcllib tcllib.fossil + +followed by + + mkdir tcllib + cd tcllib + fossil open ../tcllib.fossil + +to get a checkout of the head of the trunk\. Index: embedded/md/tcllib/files/modules/aes/aes.md ================================================================== --- embedded/md/tcllib/files/modules/aes/aes.md +++ embedded/md/tcllib/files/modules/aes/aes.md @@ -1,11 +1,11 @@ [//000000001]: # (aes \- Advanced Encryption Standard \(AES\)) [//000000002]: # (Generated from file 'aes\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2005, Pat Thoyts -Copyright © 2012\-2014, Andreas Kupries ) -[//000000004]: # (aes\(n\) 1\.2\.1 tcllib "Advanced Encryption Standard \(AES\)") +[//000000003]: # (Copyright © 2005, Pat Thoyts ) +[//000000004]: # (Copyright © 2012\-2014, Andreas Kupries ) +[//000000005]: # (aes\(n\) 1\.2\.1 tcllib "Advanced Encryption Standard \(AES\)")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | -Copyright © 2004 Jochen Loewer -Copyright © 2004\-2011 Michael Schlenker ) -[//000000004]: # (asn\(n\) 0\.8 tcllib "ASN\.1 processing") +[//000000003]: # (Copyright © 2004 Andreas Kupries ) +[//000000004]: # (Copyright © 2004 Jochen Loewer ) +[//000000005]: # (Copyright © 2004\-2011 Michael Schlenker ) +[//000000006]: # (asn\(n\) 0\.8 tcllib "ASN\.1 processing")
[
Main Table Of Contents | Table Of Contents | Keyword Index | Categories | [ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | bench \-desc "AES\-$\{len\} ECB encryption core" __\-pre__ \{ +>     set key \[aes::Init ecb $k $i\] +> \} \-body \{ +>     aes::Encrypt $key $p +> \} __\-post__ \{ +>     aes::Final $key +> \} ## Advanced pre\- and postprocessing Our last example again deals with initialization and cleanup code\. To see the difference to the regular initialization and cleanup discussed in the last @@ -129,18 +129,18 @@ variable refering to a set with specific properties \(The set has a string representation, which is shared\) affecting the speed of the inclusion command, and the cleanup code releases the temporary variables created by this initialization\. - bench -desc "set include, missing x$times $n" __-ipre__ { - set A $sx($times,$n) - set B $A - } -body { - struct::set include A x - } __-ipost__ { - unset A B - } +> bench \-desc "set include, missing x$times $n" __\-ipre__ \{ +>     set A $sx\($times,$n\) +>     set B $A +> \} \-body \{ +>     struct::set include A x +> \} __\-ipost__ \{ +>     unset A B +> \} # FURTHER READING Now that this document has been digested the reader, assumed to be a *writer* of benchmarks, he should be fortified enough to be able to understand the formal Index: embedded/md/tcllib/files/modules/comm/comm.md ================================================================== --- embedded/md/tcllib/files/modules/comm/comm.md +++ embedded/md/tcllib/files/modules/comm/comm.md @@ -1,12 +1,12 @@ [//000000001]: # (comm \- Remote communication) [//000000002]: # (Generated from file 'comm\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 1995\-1998 The Open Group\. All Rights Reserved\. -Copyright © 2003\-2004 ActiveState Corporation\. -Copyright © 2006\-2009 Andreas Kupries ) -[//000000004]: # (comm\(n\) 4\.6\.3 tcllib "Remote communication") +[//000000003]: # (Copyright © 1995\-1998 The Open Group\. All Rights Reserved\.) +[//000000004]: # (Copyright © 2003\-2004 ActiveState Corporation\.) +[//000000005]: # (Copyright © 2006\-2009 Andreas Kupries ) +[//000000006]: # (comm\(n\) 4\.6\.3 tcllib "Remote communication")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | ) -[//000000004]: # (debug\(n\) 1\.0\.6 tcllib "debug narrative") +[//000000003]: # (Copyright © 200?, Colin McCormack, Wub Server Utilities) +[//000000004]: # (Copyright © 2012\-2014, Andreas Kupries ) +[//000000005]: # (debug\(n\) 1\.0\.6 tcllib "debug narrative")
[
Main Table Of Contents | Table Of Contents | Keyword Index | Categories | ) -[//000000004]: # (debug::heartbeat\(n\) 1 tcllib "debug narrative") +[//000000003]: # (Copyright © 200?, Colin McCormack, Wub Server Utilities) +[//000000004]: # (Copyright © 2012, Andreas Kupries ) +[//000000005]: # (debug::heartbeat\(n\) 1 tcllib "debug narrative")
[
Main Table Of Contents | Table Of Contents | Keyword Index | Categories | ) -[//000000004]: # (debug::timestamp\(n\) 1 tcllib "debug narrative") +[//000000003]: # (Copyright © 200?, Colin McCormack, Wub Server Utilities) +[//000000004]: # (Copyright © 2012, Andreas Kupries ) +[//000000005]: # (debug::timestamp\(n\) 1 tcllib "debug narrative")
[
Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS package require Tcl 8\.5 +package require dicttool ?1\.0? [__ladd__ *varname* *args*](#1) [__ldelete__ *varname* *args*](#2) [__dict getnull__ *args*](#3) [__dict print__ *dict*](#4) @@ -55,12 +56,12 @@ This command will add a new instance of each element in *args* to *varname*, but only if that element is not already present\. - __ldelete__ *varname* *args* - This command will add a delete all instances of each element in *args* - from *varname*\. + This command will delete all instances of each element in *args* from + *varname*\. - __dict getnull__ *args* Operates like __dict get__, however if the key *args* does not exist, it returns an empty list instead of throwing an error\. Index: embedded/md/tcllib/files/modules/dns/tcllib_ip.md ================================================================== --- embedded/md/tcllib/files/modules/dns/tcllib_ip.md +++ embedded/md/tcllib/files/modules/dns/tcllib_ip.md @@ -1,11 +1,11 @@ [//000000001]: # (tcllib\_ip \- Domain Name Service) [//000000002]: # (Generated from file 'tcllib\_ip\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2004, Pat Thoyts -Copyright © 2005 Aamer Akhter ) -[//000000004]: # (tcllib\_ip\(n\) 1\.4 tcllib "Domain Name Service") +[//000000003]: # (Copyright © 2004, Pat Thoyts) +[//000000004]: # (Copyright © 2005 Aamer Akhter ) +[//000000005]: # (tcllib\_ip\(n\) 1\.4 tcllib "Domain Name Service")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | - \documentclass{tclldoc} - \begin{document} - \DocInput{*filename.dtx*} - \end{document} - % - % \fi +>    % \\iffalse +>    %<\*driver> +>    \\documentclass\{tclldoc\} +>    \\begin\{document\} +>    \\DocInput\{*filename\.dtx*\} +>    \\end\{document\} +>    % +>    % \\fi or some variation thereof\. The trick is that the file gets read twice\. With normal LaTeX reading rules, the first two lines are comments and therefore ignored\. The third line is the document preamble, the fourth line begins the document body, and the sixth line ends the document, so LaTeX stops there — Index: embedded/md/tcllib/files/modules/doctools/docidx_lang_intro.md ================================================================== --- embedded/md/tcllib/files/modules/doctools/docidx_lang_intro.md +++ embedded/md/tcllib/files/modules/doctools/docidx_lang_intro.md @@ -61,11 +61,11 @@ apply with regard to word quotation, nested commands, continuation lines, etc\. I\.e\. ... [key {markup language}] ... - ... [manpage thefile \\ + ... [manpage thefile \ {file description}] ... ## Basic structure The most simple document which can be written in docidx is @@ -77,42 +77,42 @@ of only one part where we will list all keys and their references\. A more useful index will contain at least keywords, or short 'keys', i\.e\. the phrases which were indexed\. So: - [index_begin GROUPTITLE TITLE] - [__key markup__] - [__key {semantic markup}]__] - [__key {docidx markup}__] - [__key {docidx language}__] - [__key {docidx commands}__] - [index_end] +> \[index\_begin GROUPTITLE TITLE\] +> \[__key markup__\] +> \[__key \{semantic markup\}\]__\] +> \[__key \{docidx markup\}__\] +> \[__key \{docidx language\}__\] +> \[__key \{docidx commands\}__\] +> \[index\_end\] In the above example the command __key__ is used to declare the keyword phrases we wish to be part of the index\. However a truly useful index does not only list the keyword phrases, but will also contain references to documents associated with the keywords\. Here is a made\-up index for all the manpages in the module *[base64](\.\./\.\./\.\./\.\./index\.md\#base64)*: - [index_begin tcllib/base64 {De- & Encoding}] - [key base64] - [__manpage base64__] - [key encoding] - [__manpage base64__] - [__manpage uuencode__] - [__manpage yencode__] - [key uuencode] - [__manpage uuencode__] - [key yEnc] - [__manpage yencode__] - [key ydecode] - [__manpage yencode__] - [key yencode] - [__manpage yencode__] - [index_end] +> \[index\_begin tcllib/base64 \{De\- & Encoding\}\] +> \[key base64\] +> \[__manpage base64__\] +> \[key encoding\] +> \[__manpage base64__\] +> \[__manpage uuencode__\] +> \[__manpage yencode__\] +> \[key uuencode\] +> \[__manpage uuencode__\] +> \[key yEnc\] +> \[__manpage yencode__\] +> \[key ydecode\] +> \[__manpage yencode__\] +> \[key yencode\] +> \[__manpage yencode__\] +> \[index\_end\] In the above example the command __[manpage](\.\./\.\./\.\./\.\./index\.md\#manpage)__ is used to insert references to documents, using symbolic file names, with each command belonging to the last __key__ command coming before it\. @@ -132,24 +132,24 @@ Instead of only whitespace the two templating commands __include__ and __vset__ are also allowed, to enable the writer to either set and/or import configuration settings relevant to the table of contents\. I\.e\. it is possible to write - [__include FILE__] - [__vset VAR VALUE__] - [index_begin GROUPTITLE TITLE] - ... - [index_end] +> \[__include FILE__\] +> \[__vset VAR VALUE__\] +> \[index\_begin GROUPTITLE TITLE\] +> \.\.\. +> \[index\_end\] Even more important, these two commands are allowed anywhere where a markup command is allowed, without regard for any other structure\. - [index_begin GROUPTITLE TITLE] - [__include FILE__] - [__vset VAR VALUE__] - ... - [index_end] +> \[index\_begin GROUPTITLE TITLE\] +> \[__include FILE__\] +> \[__vset VAR VALUE__\] +> \.\.\. +> \[index\_end\] The only restriction __include__ has to obey is that the contents of the included file must be valid at the place of the inclusion\. I\.e\. a file included before __index\_begin__ may contain only the templating commands __vset__ and __include__, a file included after a key may contain only manape or url @@ -164,15 +164,15 @@ markup commands makes it impossible to directly use \[ and \] within the text\. Our example of their use are the sources of the last sentence in the previous paragraph, with some highlighting added\. - ... - These commands, [cmd lb] and [cmd lb] respectively, are required - because our use of [__lb__] and [__rb__] to bracket markup commands makes it - impossible to directly use [__lb__] and [__rb__] within the text. - ... +>   \.\.\. +>   These commands, \[cmd lb\] and \[cmd lb\] respectively, are required +>   because our use of \[__lb__\] and \[__rb__\] to bracket markup commands makes it +>   impossible to directly use \[__lb__\] and \[__rb__\] within the text\. +>   \.\.\. # FURTHER READING Now that this document has been digested the reader, assumed to be a *writer* of documentation should be fortified enough to be able to understand the formal Index: embedded/md/tcllib/files/modules/doctools/doctoc_lang_intro.md ================================================================== --- embedded/md/tcllib/files/modules/doctools/doctoc_lang_intro.md +++ embedded/md/tcllib/files/modules/doctools/doctoc_lang_intro.md @@ -65,11 +65,11 @@ apply with regard to word quotation, nested commands, continuation lines, etc\. I\.e\. ... [division_start {Appendix 1}] ... - ... [item thefile \\ + ... [item thefile \ label {file description}] ... ## Basic structure The most simple document which can be written in doctoc is @@ -100,17 +100,17 @@ formatting engine when converting the input, based on a mapping from symbolic to actual names given to the engine\. Here a made up example for a table of contents of this document: - [toc_begin Doctoc {Language Introduction}] - [__item 1 DESCRIPTION__] - [__item 1.1 {Basic structure}__] - [__item 1.2 Items__] - [__item 1.3 Divisions__] - [__item 2 {FURTHER READING}__] - [toc_end] +> \[toc\_begin Doctoc \{Language Introduction\}\] +> \[__item 1 DESCRIPTION__\] +> \[__item 1\.1 \{Basic structure\}__\] +> \[__item 1\.2 Items__\] +> \[__item 1\.3 Divisions__\] +> \[__item 2 \{FURTHER READING\}__\] +> \[toc\_end\] ## Divisions One thing of notice in the last example in the previous section is that the referenced sections actually had a nested structure, something which was @@ -139,62 +139,62 @@ This command closes the last opened and not yet closed division\. Using this we can recast the last example like this - [toc_begin Doctoc {Language Introduction}] - [__division_start DESCRIPTION__] - [item 1 {Basic structure}] - [item 2 Items] - [item 3 Divisions] - [__division_end__] - [__division_start {FURTHER READING}__] - [__division_end__] - [toc_end] +> \[toc\_begin Doctoc \{Language Introduction\}\] +> \[__division\_start DESCRIPTION__\] +> \[item 1 \{Basic structure\}\] +> \[item 2 Items\] +> \[item 3 Divisions\] +> \[__division\_end__\] +> \[__division\_start \{FURTHER READING\}__\] +> \[__division\_end__\] +> \[toc\_end\] Or, to demonstrate deeper nesting - [toc_begin Doctoc {Language Introduction}] - [__division_start DESCRIPTION__] - [__division_start {Basic structure}__] - [item 1 Do] - [item 2 Re] - [__division_end__] - [__division_start Items__] - [item a Fi] - [item b Fo] - [item c Fa] - [__division_end__] - [__division_start Divisions__] - [item 1 Sub] - [item 1 Zero] - [__division_end__] - [__division_end__] - [__division_start {FURTHER READING}__] - [__division_end__] - [toc_end] +> \[toc\_begin Doctoc \{Language Introduction\}\] +> \[__division\_start DESCRIPTION__\] +> \[__division\_start \{Basic structure\}__\] +> \[item 1 Do\] +> \[item 2 Re\] +> \[__division\_end__\] +> \[__division\_start Items__\] +> \[item a Fi\] +> \[item b Fo\] +> \[item c Fa\] +> \[__division\_end__\] +> \[__division\_start Divisions__\] +> \[item 1 Sub\] +> \[item 1 Zero\] +> \[__division\_end__\] +> \[__division\_end__\] +> \[__division\_start \{FURTHER READING\}__\] +> \[__division\_end__\] +> \[toc\_end\] And do not forget, it is possible to freely mix items and divisions, and to have empty divisions\. - [toc_begin Doctoc {Language Introduction}] - [item 1 Do] - [__division_start DESCRIPTION__] - [__division_start {Basic structure}__] - [item 2 Re] - [__division_end__] - [item a Fi] - [__division_start Items__] - [item b Fo] - [item c Fa] - [__division_end__] - [__division_start Divisions__] - [__division_end__] - [__division_end__] - [__division_start {FURTHER READING}__] - [__division_end__] - [toc_end] +> \[toc\_begin Doctoc \{Language Introduction\}\] +> \[item 1 Do\] +> \[__division\_start DESCRIPTION__\] +> \[__division\_start \{Basic structure\}__\] +> \[item 2 Re\] +> \[__division\_end__\] +> \[item a Fi\] +> \[__division\_start Items__\] +> \[item b Fo\] +> \[item c Fa\] +> \[__division\_end__\] +> \[__division\_start Divisions__\] +> \[__division\_end__\] +> \[__division\_end__\] +> \[__division\_start \{FURTHER READING\}__\] +> \[__division\_end__\] +> \[toc\_end\] ## Advanced structure In all previous examples we fudged a bit regarding the markup actually allowed to be used before the __toc\_begin__ command opening the document\. @@ -202,24 +202,24 @@ Instead of only whitespace the two templating commands __include__ and __vset__ are also allowed, to enable the writer to either set and/or import configuration settings relevant to the table of contents\. I\.e\. it is possible to write - [__include FILE__] - [__vset VAR VALUE__] - [toc_begin GROUPTITLE TITLE] - ... - [toc_end] +> \[__include FILE__\] +> \[__vset VAR VALUE__\] +> \[toc\_begin GROUPTITLE TITLE\] +> \.\.\. +> \[toc\_end\] Even more important, these two commands are allowed anywhere where a markup command is allowed, without regard for any other structure\. - [toc_begin GROUPTITLE TITLE] - [__include FILE__] - [__vset VAR VALUE__] - ... - [toc_end] +> \[toc\_begin GROUPTITLE TITLE\] +> \[__include FILE__\] +> \[__vset VAR VALUE__\] +> \.\.\. +> \[toc\_end\] The only restriction __include__ has to obey is that the contents of the included file must be valid at the place of the inclusion\. I\.e\. a file included before __toc\_begin__ may contain only the templating commands __vset__ and __include__, a file included in a division may contain only items or @@ -234,15 +234,15 @@ markup commands makes it impossible to directly use \[ and \] within the text\. Our example of their use are the sources of the last sentence in the previous paragraph, with some highlighting added\. - ... - These commands, [cmd lb] and [cmd lb] respectively, are required - because our use of [__lb__] and [__rb__] to bracket markup commands makes it - impossible to directly use [__lb__] and [__rb__] within the text. - ... +>   \.\.\. +>   These commands, \[cmd lb\] and \[cmd lb\] respectively, are required +>   because our use of \[__lb__\] and \[__rb__\] to bracket markup commands makes it +>   impossible to directly use \[__lb__\] and \[__rb__\] within the text\. +>   \.\.\. # FURTHER READING Now that this document has been digested the reader, assumed to be a *writer* of documentation should be fortified enough to be able to understand the formal Index: embedded/md/tcllib/files/modules/doctools/doctools.md ================================================================== --- embedded/md/tcllib/files/modules/doctools/doctools.md +++ embedded/md/tcllib/files/modules/doctools/doctools.md @@ -1,10 +1,10 @@ [//000000001]: # (doctools \- Documentation tools) [//000000002]: # (Generated from file 'doctools\.man' by tcllib/doctools with format 'markdown') [//000000003]: # (Copyright © 2003\-2019 Andreas Kupries ) -[//000000004]: # (doctools\(n\) 1\.5\.2 tcllib "Documentation tools") +[//000000004]: # (doctools\(n\) 1\.5\.6 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS package require Tcl 8\.2 -package require doctools ?1\.5\.2? +package require doctools ?1\.5\.6? [__::doctools::new__ *objectName* ?*option value*\.\.\.?](#1) [__::doctools::help__](#2) [__::doctools::search__ *path*](#3) [__objectName__ __method__ ?*arg arg \.\.\.*?](#4) Index: embedded/md/tcllib/files/modules/doctools/doctools_lang_intro.md ================================================================== --- embedded/md/tcllib/files/modules/doctools/doctools_lang_intro.md +++ embedded/md/tcllib/files/modules/doctools/doctools_lang_intro.md @@ -70,11 +70,11 @@ apply with regard to word quotation, nested commands, continuation lines, etc\. I\.e\. ... [list_begin enumerated] ... - ... [call [cmd foo] \\ + ... [call [cmd foo] \ [arg bar]] ... ... [term {complex concept}] ... ... [opt "[arg key] [arg value]"] ... @@ -94,11 +94,11 @@ [keywords {doctools syntax}] [keywords markup] [keywords {semantic markup}] [description] [vset CATEGORY doctools] - [include ../doctools2base/include/feedback.inc] + [include ../common-text/feedback.inc] [manpage_end] This also shows us that all doctools documents are split into two parts, the *header* and the *body*\. Everything coming before \[__description__\] belongs to the header, and everything coming after belongs to the body, with the @@ -130,45 +130,45 @@ specified information is accumulated, in the given order\. Regular text is not allowed within the header\. Given the above a less minimal example of a document is - [manpage_begin NAME SECTION VERSION] - [__copyright {YEAR AUTHOR}__] - [__titledesc TITLE__] - [__moddesc MODULE_TITLE__] - [__require PACKAGE VERSION__] - [__require PACKAGE__] - [description] - [manpage_end] +> \[manpage\_begin NAME SECTION VERSION\] +> \[__copyright \{YEAR AUTHOR\}__\] +> \[__titledesc TITLE__\] +> \[__moddesc MODULE\_TITLE__\] +> \[__require PACKAGE VERSION__\] +> \[__require PACKAGE__\] +> \[description\] +> \[manpage\_end\] Remember that the whitespace is optional\. The document [manpage_begin NAME SECTION VERSION] [copyright {YEAR AUTHOR}][titledesc TITLE][moddesc MODULE_TITLE] [require PACKAGE VERSION][require PACKAGE][description] [vset CATEGORY doctools] - [include ../doctools2base/include/feedback.inc] + [include ../common-text/feedback.inc] [manpage_end] has the same meaning as the example before\. On the other hand, if *whitespace* is present it consists not only of any sequence of characters containing the space character, horizontal and vertical tabs, carriage return, and newline, but it may contain comment markup as well, in the form of the __[comment](\.\./\.\./\.\./\.\./index\.md\#comment)__ command\. - [__comment { ... }__] - [manpage_begin NAME SECTION VERSION] - [copyright {YEAR AUTHOR}] - [titledesc TITLE] - [moddesc MODULE_TITLE][__comment { ... }__] - [require PACKAGE VERSION] - [require PACKAGE] - [description] - [manpage_end] - [__comment { ... }__] +> \[__comment \{ \.\.\. \}__\] +> \[manpage\_begin NAME SECTION VERSION\] +> \[copyright \{YEAR AUTHOR\}\] +> \[titledesc TITLE\] +> \[moddesc MODULE\_TITLE\]\[__comment \{ \.\.\. \}__\] +> \[require PACKAGE VERSION\] +> \[require PACKAGE\] +> \[description\] +> \[manpage\_end\] +> \[__comment \{ \.\.\. \}__\] ## Advanced structure In the simple examples of the last section we fudged a bit regarding the markup actually allowed to be used before the __manpage\_begin__ command opening the @@ -176,25 +176,25 @@ Instead of only whitespace the two templating commands __include__ and __vset__ are also allowed, to enable the writer to either set and/or import configuration settings relevant to the document\. I\.e\. it is possible to write - [__include FILE__] - [__vset VAR VALUE__] - [manpage_begin NAME SECTION VERSION] - [description] - [manpage_end] +> \[__include FILE__\] +> \[__vset VAR VALUE__\] +> \[manpage\_begin NAME SECTION VERSION\] +> \[description\] +> \[manpage\_end\] Even more important, these two commands are allowed anywhere where a markup command is allowed, without regard for any other structure\. I\.e\. for example in the header as well\. - [manpage_begin NAME SECTION VERSION] - [__include FILE__] - [__vset VAR VALUE__] - [description] - [manpage_end] +> \[manpage\_begin NAME SECTION VERSION\] +> \[__include FILE__\] +> \[__vset VAR VALUE__\] +> \[description\] +> \[manpage\_end\] The only restriction __include__ has to obey is that the contents of the included file must be valid at the place of the inclusion\. I\.e\. a file included before __manpage\_begin__ may contain only the templating commands __vset__ and __include__, a file included in the header may contain only @@ -215,18 +215,18 @@ command closes the previous paragraph and automatically opens the next\. The first paragraph is automatically opened at the beginning of the body, by __description__\. In the same manner the last paragraph automatically ends at __manpage\_end__\. - [manpage_begin NAME SECTION VERSION] - [description] - ... - [__para__] - ... - [__para__] - ... - [manpage_end] +> \[manpage\_begin NAME SECTION VERSION\] +> \[description\] +>  \.\.\. +> \[__para__\] +>  \.\.\. +> \[__para__\] +>  \.\.\. +> \[manpage\_end\] Empty paragraphs are ignored\. A structure coarser than paragraphs are sections, which allow the writer to split a document into larger, and labeled, pieces\. The command for doing so is @@ -237,20 +237,20 @@ automatically ends at __manpage\_end__\. Empty sections are *not* ignored\. We are free to \(not\) use paragraphs within sections\. - [manpage_begin NAME SECTION VERSION] - [description] - ... - [__section {Section A}__] - ... - [para] - ... - [__section {Section B}__] - ... - [manpage_end] +> \[manpage\_begin NAME SECTION VERSION\] +> \[description\] +>  \.\.\. +> \[__section \{Section A\}__\] +>  \.\.\. +> \[para\] +>  \.\.\. +> \[__section \{Section B\}__\] +>  \.\.\. +> \[manpage\_end\] Between sections and paragraphs we have subsections, to split sections\. The command for doing so is __subsection__\. Each occurrence of this command closes the previous subsection and automatically opens the next, including its first paragraph\. A subsection is automatically opened at the beginning of the @@ -258,24 +258,24 @@ manner the last subsection automatically ends at __manpage\_end__\. Empty subsections are *not* ignored\. We are free to \(not\) use paragraphs within subsections\. - [manpage_begin NAME SECTION VERSION] - [description] - ... - [section {Section A}] - ... - [__subsection {Sub 1}__] - ... - [para] - ... - [__subsection {Sub 2}__] - ... - [section {Section B}] - ... - [manpage_end] +> \[manpage\_begin NAME SECTION VERSION\] +> \[description\] +>  \.\.\. +> \[section \{Section A\}\] +>  \.\.\. +> \[__subsection \{Sub 1\}__\] +>  \.\.\. +> \[para\] +>  \.\.\. +> \[__subsection \{Sub 2\}__\] +>  \.\.\. +> \[section \{Section B\}\] +>  \.\.\. +> \[manpage\_end\] ## Text markup Having handled the overall structure a writer can impose on the document we now take a closer at the text in a paragraph\. @@ -377,18 +377,18 @@ The example demonstrating the use of text markup is an excerpt from the *[doctools language command reference](doctools\_lang\_cmdref\.md)*, with some highlighting added\. It shows their use within a block of text, as the arguments of a list item command \(__call__\), and our ability to nest them\. - ... - [call [__cmd arg_def__] [__arg type__] [__arg name__] [__opt__ [__arg mode__]]] - - Text structure. List element. Argument list. Automatically closes the - previous list element. Specifies the data-[__arg type__] of the described - argument of a command, its [__arg name__] and its i/o-[__arg mode__]. The - latter is optional. - ... +>   \.\.\. +>   \[call \[__cmd arg\_def__\] \[__arg type__\] \[__arg name__\] \[__opt__ \[__arg mode__\]\]\] +> +>   Text structure\. List element\. Argument list\. Automatically closes the +>   previous list element\. Specifies the data\-\[__arg type__\] of the described +>   argument of a command, its \[__arg name__\] and its i/o\-\[__arg mode__\]\. The +>   latter is optional\. +>   \.\.\. ## Escapes Beyond the 20 commands for simple markup shown in the previous section we have two more available which are technically simple markup\. However their function @@ -398,15 +398,15 @@ markup commands makes it impossible to directly use \[ and \] within the text\. Our example of their use are the sources of the last sentence in the previous paragraph, with some highlighting added\. - ... - These commands, [cmd lb] and [cmd lb] respectively, are required - because our use of [__lb__] and [__rb__] to bracket markup commands makes it - impossible to directly use [__lb__] and [__rb__] within the text. - ... +>   \.\.\. +>   These commands, \[cmd lb\] and \[cmd lb\] respectively, are required +>   because our use of \[__lb__\] and \[__rb__\] to bracket markup commands makes it +>   impossible to directly use \[__lb__\] and \[__rb__\] within the text\. +>   \.\.\. ## Cross\-references The last two commands we have to discuss are for the declaration of cross\-references between documents, explicit and implicit\. They are @@ -434,18 +434,18 @@ considers them as meta data which should be in the header, etc\. Our example shows the sources for the cross\-references of this document, with some highlighting added\. Incidentally they are found at the end of the body\. - ... - [__see_also doctools_intro__] - [__see_also doctools_lang_syntax__] - [__see_also doctools_lang_cmdref__] - [__keywords markup {semantic markup}__] - [__keywords {doctools markup} {doctools language}__] - [__keywords {doctools syntax} {doctools commands}__] - [manpage_end] +>   \.\.\. +>   \[__see\_also doctools\_intro__\] +>   \[__see\_also doctools\_lang\_syntax__\] +>   \[__see\_also doctools\_lang\_cmdref__\] +>   \[__keywords markup \{semantic markup\}__\] +>   \[__keywords \{doctools markup\} \{doctools language\}__\] +>   \[__keywords \{doctools syntax\} \{doctools commands\}__\] +>   \[manpage\_end\] ## Examples Where ever we can write plain text we can write examples too\. For simple examples we have the command __example__ which takes a single argument, the @@ -461,19 +461,19 @@ \(Remember section [Advanced structure](#subsection3)\)\. The source for the very first example in this document \(see section [Fundamentals](#subsection1)\), with some highlighting added, is - [__example__ { - ... [list_begin enumerated] ... - }] +> \[__example__ \{ +>     \.\.\. \[list\_begin enumerated\] \.\.\. +>   \}\] Using __example\_begin__ / __example\_end__ this would look like - [__example_begin__] - ... [list_begin enumerated] ... - [__example_end__] +> \[__example\_begin__\] +>     \.\.\. \[list\_begin enumerated\] \.\.\. +>   \[__example\_end__\] ## Lists Where ever we can write plain text we can write lists too\. The main commands are __list\_begin__ to start a list, and __list\_end__ to close one\. The @@ -532,46 +532,46 @@ option database\. Our example is the source of the definition list in the previous paragraph, with most of the content in the middle removed\. - ... - [__list_begin__ definitions] - [__def__ [const arg]] - - ([cmd arg_def]) This opens an argument (declaration) list. It is a - specialized form of a definition list where the term is an argument - name, with its type and i/o-mode. - - [__def__ [const itemized]] - - ([cmd item]) - This opens a general itemized list. - - ... - [__def__ [const tkoption]] - - ([cmd tkoption_def]) This opens a widget option (declaration) list. It - is a specialized form of a definition list where the term is the name - of a configuration option for a widget, with its name and class in the - option database. - - [__list_end__] - ... +>   \.\.\. +>   \[__list\_begin__ definitions\] +>   \[__def__ \[const arg\]\] +> +>   \(\[cmd arg\_def\]\) This opens an argument \(declaration\) list\. It is a +>   specialized form of a definition list where the term is an argument +>   name, with its type and i/o\-mode\. +> +>   \[__def__ \[const itemized\]\] +> +>   \(\[cmd item\]\) +>   This opens a general itemized list\. +> +>   \.\.\. +>   \[__def__ \[const tkoption\]\] +> +>   \(\[cmd tkoption\_def\]\) This opens a widget option \(declaration\) list\. It +>   is a specialized form of a definition list where the term is the name +>   of a configuration option for a widget, with its name and class in the +>   option database\. +> +>   \[__list\_end__\] +>   \.\.\. Note that a list cannot begin in one \(sub\)section and end in another\. Differently said, \(sub\)section breaks are not allowed within lists and list items\. An example of this *illegal* construct is - ... - [list_begin itemized] - [item] - ... - [__section {ILLEGAL WITHIN THE LIST}__] - ... - [list_end] - ... +>   \.\.\. +>   \[list\_begin itemized\] +>   \[item\] +>   \.\.\. +>   \[__section \{ILLEGAL WITHIN THE LIST\}__\] +>   \.\.\. +>   \[list\_end\] +>   \.\.\. # FURTHER READING Now that this document has been digested the reader, assumed to be a *writer* of documentation should be fortified enough to be able to understand the formal Index: embedded/md/tcllib/files/modules/doctools/mpexpand.md ================================================================== --- embedded/md/tcllib/files/modules/doctools/mpexpand.md +++ embedded/md/tcllib/files/modules/doctools/mpexpand.md @@ -1,11 +1,11 @@ [//000000001]: # (mpexpand \- Documentation toolbox) [//000000002]: # (Generated from file 'mpexpand\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2002 Andreas Kupries -Copyright © 2003 Andreas Kupries ) -[//000000004]: # (mpexpand\(n\) 1\.0 tcllib "Documentation toolbox") +[//000000003]: # (Copyright © 2002 Andreas Kupries ) +[//000000004]: # (Copyright © 2003 Andreas Kupries ) +[//000000005]: # (mpexpand\(n\) 1\.0 tcllib "Documentation toolbox")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | ) -[//000000004]: # (doctools::idx::export::docidx\(n\) 0\.1 tcllib "Documentation tools") +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) +[//000000004]: # (doctools::idx::export::docidx\(n\) 0\.2\.1 tcllib "Documentation tools")
[
Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS package require Tcl 8\.4 -package require doctools::idx::export::docidx ?0\.1? +package require doctools::idx::export::docidx ?0\.2\.1? [__[export](\.\./\.\./\.\./\.\./index\.md\#export)__ *serial* *configuration*](#1) # DESCRIPTION @@ -248,6 +248,6 @@ Text formatter plugin # COPYRIGHT -Copyright © 2009 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2idx/idx_export.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2idx/idx_export.md +++ embedded/md/tcllib/files/modules/doctools2idx/idx_export.md @@ -1,10 +1,10 @@ [//000000001]: # (doctools::idx::export \- Documentation tools) [//000000002]: # (Generated from file 'idx\_export\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009\-2018 Andreas Kupries ) -[//000000004]: # (doctools::idx::export\(n\) 0\.2 tcllib "Documentation tools") +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) +[//000000004]: # (doctools::idx::export\(n\) 0\.2\.1 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS -package require doctools::idx::export ?0\.2? +package require doctools::idx::export ?0\.2\.1? package require Tcl 8\.4 -package require doctools::config +package require struct::map package require doctools::idx::structure package require snit package require pluginmgr [__::doctools::idx::export__ *objectName*](#1) @@ -467,6 +467,6 @@ Documentation tools # COPYRIGHT -Copyright © 2009\-2018 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2idx/idx_export_html.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2idx/idx_export_html.md +++ embedded/md/tcllib/files/modules/doctools2idx/idx_export_html.md @@ -1,9 +1,9 @@ [//000000001]: # (doctools::idx::export::html \- Documentation tools) [//000000002]: # (Generated from file 'plugin\.inc' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009 Andreas Kupries ) +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) [//000000004]: # (doctools::idx::export::html\(n\) 0\.2 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | COPYRIGHT -Copyright © 2009 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2idx/idx_export_json.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2idx/idx_export_json.md +++ embedded/md/tcllib/files/modules/doctools2idx/idx_export_json.md @@ -1,9 +1,9 @@ [//000000001]: # (doctools::idx::export::json \- Documentation tools) [//000000002]: # (Generated from file 'plugin\.inc' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009 Andreas Kupries ) +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) [//000000004]: # (doctools::idx::export::json\(n\) 0\.1 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | COPYRIGHT -Copyright © 2009 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2idx/idx_export_nroff.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2idx/idx_export_nroff.md +++ embedded/md/tcllib/files/modules/doctools2idx/idx_export_nroff.md @@ -1,9 +1,9 @@ [//000000001]: # (doctools::idx::export::nroff \- Documentation tools) [//000000002]: # (Generated from file 'plugin\.inc' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009 Andreas Kupries ) +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) [//000000004]: # (doctools::idx::export::nroff\(n\) 0\.3 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | COPYRIGHT -Copyright © 2009 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2idx/idx_export_text.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2idx/idx_export_text.md +++ embedded/md/tcllib/files/modules/doctools2idx/idx_export_text.md @@ -1,9 +1,9 @@ [//000000001]: # (doctools::idx::export::text \- Documentation tools) [//000000002]: # (Generated from file 'plugin\.inc' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009 Andreas Kupries ) +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) [//000000004]: # (doctools::idx::export::text\(n\) 0\.2 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | COPYRIGHT -Copyright © 2009 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2idx/idx_export_wiki.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2idx/idx_export_wiki.md +++ embedded/md/tcllib/files/modules/doctools2idx/idx_export_wiki.md @@ -1,9 +1,9 @@ [//000000001]: # (doctools::idx::export::wiki \- Documentation tools) [//000000002]: # (Generated from file 'plugin\.inc' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009 Andreas Kupries ) +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) [//000000004]: # (doctools::idx::export::wiki\(n\) 0\.2 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | COPYRIGHT -Copyright © 2009 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2idx/idx_import.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2idx/idx_import.md +++ embedded/md/tcllib/files/modules/doctools2idx/idx_import.md @@ -1,10 +1,10 @@ [//000000001]: # (doctools::idx::import \- Documentation tools) [//000000002]: # (Generated from file 'idx\_import\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009\-2018 Andreas Kupries ) -[//000000004]: # (doctools::idx::import\(n\) 0\.2 tcllib "Documentation tools") +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) +[//000000004]: # (doctools::idx::import\(n\) 0\.2\.1 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS -package require doctools::idx::import ?0\.2? +package require doctools::idx::import ?0\.2\.1? package require Tcl 8\.4 -package require doctools::config +package require struct::map package require doctools::idx::structure package require snit package require pluginmgr [__::doctools::idx::import__ *objectName*](#1) @@ -524,6 +524,6 @@ Documentation tools # COPYRIGHT -Copyright © 2009\-2018 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2idx/idx_import_json.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2idx/idx_import_json.md +++ embedded/md/tcllib/files/modules/doctools2idx/idx_import_json.md @@ -1,10 +1,10 @@ [//000000001]: # (doctools::idx::import::json \- Documentation tools) [//000000002]: # (Generated from file 'plugin\.inc' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009 Andreas Kupries ) -[//000000004]: # (doctools::idx::import::json\(n\) 0\.1 tcllib "Documentation tools") +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) +[//000000004]: # (doctools::idx::import::json\(n\) 0\.2\.1 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS -package require Tcl 8\.4 -package require doctools::idx::import::json ?0\.1? +package require Tcl 8\.5 +package require doctools::idx::import::json ?0\.2\.1? package require doctools::idx::structure package require json [__[import](\.\./\.\./\.\./\.\./index\.md\#import)__ *string* *configuration*](#1) @@ -227,6 +227,6 @@ Text formatter plugin # COPYRIGHT -Copyright © 2009 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2idx/idx_introduction.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2idx/idx_introduction.md +++ embedded/md/tcllib/files/modules/doctools2idx/idx_introduction.md @@ -133,17 +133,17 @@ ~~ | ~~ doctools::idx::export ~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ doctools::idx::import | | | +---------------+-------------------------+ | +------------------+---------------+-----------------------+---------------+ | | | | | | | | | - doctools::config = | | | = doctools::include doctools::config doctools::paths + struct::map = | | | = doctools::include struct::map fileutil::paths | | | | | doctools::idx::export::<*> | | | doctools::idx::import::<*> docidx | | | docidx, json - json | | | | \\ - html | | | doctools::idx::parse \\ - nroff | | | | \\ + json | | | | \ + html | | | doctools::idx::parse \ + nroff | | | | \ wiki | | | +---------------+ json text | | | | | doctools::idx::structure | | +-------+---------------+ Index: embedded/md/tcllib/files/modules/doctools2idx/import_docidx.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2idx/import_docidx.md +++ embedded/md/tcllib/files/modules/doctools2idx/import_docidx.md @@ -1,10 +1,10 @@ [//000000001]: # (doctools::idx::import::docidx \- Documentation tools) [//000000002]: # (Generated from file 'plugin\.inc' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009 Andreas Kupries ) -[//000000004]: # (doctools::idx::import::docidx\(n\) 0\.1 tcllib "Documentation tools") +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) +[//000000004]: # (doctools::idx::import::docidx\(n\) 0\.2\.1 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS -package require Tcl 8\.4 -package require doctools::idx::import::docidx ?0\.1? +package require Tcl 8\.5 +package require doctools::idx::import::docidx ?0\.2\.1? package require doctools::idx::parse package require doctools::idx::structure package require doctools::msgcat package require doctools::tcl::parse package require fileutil @@ -206,6 +206,6 @@ Text formatter plugin # COPYRIGHT -Copyright © 2009 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2toc/export_doctoc.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2toc/export_doctoc.md +++ embedded/md/tcllib/files/modules/doctools2toc/export_doctoc.md @@ -1,10 +1,10 @@ [//000000001]: # (doctools::toc::export::doctoc \- Documentation tools) [//000000002]: # (Generated from file 'plugin\.inc' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009 Andreas Kupries ) -[//000000004]: # (doctools::toc::export::doctoc\(n\) 0\.1 tcllib "Documentation tools") +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) +[//000000004]: # (doctools::toc::export::doctoc\(n\) 0\.2\.1 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS package require Tcl 8\.4 -package require doctools::toc::export::doctoc ?0\.1? +package require doctools::toc::export::doctoc ?0\.2\.1? [__[export](\.\./\.\./\.\./\.\./index\.md\#export)__ *serial* *configuration*](#1) # DESCRIPTION @@ -276,6 +276,6 @@ Text formatter plugin # COPYRIGHT -Copyright © 2009 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2toc/import_doctoc.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2toc/import_doctoc.md +++ embedded/md/tcllib/files/modules/doctools2toc/import_doctoc.md @@ -1,10 +1,10 @@ [//000000001]: # (doctools::toc::import::doctoc \- Documentation tools) [//000000002]: # (Generated from file 'plugin\.inc' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009 Andreas Kupries ) -[//000000004]: # (doctools::toc::import::doctoc\(n\) 0\.1 tcllib "Documentation tools") +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) +[//000000004]: # (doctools::toc::import::doctoc\(n\) 0\.2\.1 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS -package require Tcl 8\.4 -package require doctools::toc::import::doctoc ?0\.1? +package require Tcl 8\.5 +package require doctools::toc::import::doctoc ?0\.2\.1? package require doctools::toc::parse package require doctools::toc::structure package require doctools::msgcat package require doctools::tcl::parse package require fileutil @@ -235,6 +235,6 @@ Text formatter plugin # COPYRIGHT -Copyright © 2009 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2toc/toc_export.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2toc/toc_export.md +++ embedded/md/tcllib/files/modules/doctools2toc/toc_export.md @@ -1,10 +1,10 @@ [//000000001]: # (doctools::toc::export \- Documentation tools) [//000000002]: # (Generated from file 'toc\_export\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009\-2018 Andreas Kupries ) -[//000000004]: # (doctools::toc::export\(n\) 0\.2 tcllib "Documentation tools") +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) +[//000000004]: # (doctools::toc::export\(n\) 0\.2\.1 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS -package require doctools::toc::export ?0\.2? +package require doctools::toc::export ?0\.2\.1? package require Tcl 8\.4 -package require doctools::config +package require struct::map package require doctools::toc::structure package require snit package require pluginmgr [__::doctools::toc::export__ *objectName*](#1) @@ -481,6 +481,6 @@ Documentation tools # COPYRIGHT -Copyright © 2009\-2018 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2toc/toc_export_html.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2toc/toc_export_html.md +++ embedded/md/tcllib/files/modules/doctools2toc/toc_export_html.md @@ -1,9 +1,9 @@ [//000000001]: # (doctools::toc::export::html \- Documentation tools) [//000000002]: # (Generated from file 'plugin\.inc' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009 Andreas Kupries ) +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) [//000000004]: # (doctools::toc::export::html\(n\) 0\.1 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | COPYRIGHT -Copyright © 2009 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2toc/toc_export_json.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2toc/toc_export_json.md +++ embedded/md/tcllib/files/modules/doctools2toc/toc_export_json.md @@ -1,9 +1,9 @@ [//000000001]: # (doctools::toc::export::json \- Documentation tools) [//000000002]: # (Generated from file 'plugin\.inc' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009 Andreas Kupries ) +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) [//000000004]: # (doctools::toc::export::json\(n\) 0\.1 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | COPYRIGHT -Copyright © 2009 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2toc/toc_export_nroff.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2toc/toc_export_nroff.md +++ embedded/md/tcllib/files/modules/doctools2toc/toc_export_nroff.md @@ -1,9 +1,9 @@ [//000000001]: # (doctools::toc::export::nroff \- Documentation tools) [//000000002]: # (Generated from file 'plugin\.inc' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009 Andreas Kupries ) +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) [//000000004]: # (doctools::toc::export::nroff\(n\) 0\.2 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | COPYRIGHT -Copyright © 2009 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2toc/toc_export_text.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2toc/toc_export_text.md +++ embedded/md/tcllib/files/modules/doctools2toc/toc_export_text.md @@ -1,9 +1,9 @@ [//000000001]: # (doctools::toc::export::text \- Documentation tools) [//000000002]: # (Generated from file 'plugin\.inc' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009 Andreas Kupries ) +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) [//000000004]: # (doctools::toc::export::text\(n\) 0\.1 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | COPYRIGHT -Copyright © 2009 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2toc/toc_export_wiki.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2toc/toc_export_wiki.md +++ embedded/md/tcllib/files/modules/doctools2toc/toc_export_wiki.md @@ -1,9 +1,9 @@ [//000000001]: # (doctools::toc::export::wiki \- Documentation tools) [//000000002]: # (Generated from file 'plugin\.inc' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009 Andreas Kupries ) +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) [//000000004]: # (doctools::toc::export::wiki\(n\) 0\.1 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | COPYRIGHT -Copyright © 2009 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2toc/toc_import.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2toc/toc_import.md +++ embedded/md/tcllib/files/modules/doctools2toc/toc_import.md @@ -1,10 +1,10 @@ [//000000001]: # (doctools::toc::import \- Documentation tools) [//000000002]: # (Generated from file 'toc\_import\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009\-2018 Andreas Kupries ) -[//000000004]: # (doctools::toc::import\(n\) 0\.2 tcllib "Documentation tools") +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) +[//000000004]: # (doctools::toc::import\(n\) 0\.2\.1 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS -package require doctools::toc::import ?0\.2? +package require doctools::toc::import ?0\.2\.1? package require Tcl 8\.4 -package require doctools::config +package require struct::map package require doctools::toc::structure package require snit package require pluginmgr [__::doctools::toc::import__ *objectName*](#1) @@ -541,6 +541,6 @@ Documentation tools # COPYRIGHT -Copyright © 2009\-2018 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2toc/toc_import_json.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2toc/toc_import_json.md +++ embedded/md/tcllib/files/modules/doctools2toc/toc_import_json.md @@ -1,10 +1,10 @@ [//000000001]: # (doctools::toc::import::json \- Documentation tools) [//000000002]: # (Generated from file 'plugin\.inc' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2009 Andreas Kupries ) -[//000000004]: # (doctools::toc::import::json\(n\) 0\.1 tcllib "Documentation tools") +[//000000003]: # (Copyright © 2009\-2019 Andreas Kupries ) +[//000000004]: # (doctools::toc::import::json\(n\) 0\.2\.1 tcllib "Documentation tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS -package require Tcl 8\.4 -package require doctools::toc::import::json ?0\.1? +package require Tcl 8\.5 +package require doctools::toc::import::json ?0\.2\.1? package require doctools::toc::structure package require json [__[import](\.\./\.\./\.\./\.\./index\.md\#import)__ *string* *configuration*](#1) @@ -276,6 +276,6 @@ Text formatter plugin # COPYRIGHT -Copyright © 2009 Andreas Kupries +Copyright © 2009\-2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/doctools2toc/toc_introduction.md ================================================================== --- embedded/md/tcllib/files/modules/doctools2toc/toc_introduction.md +++ embedded/md/tcllib/files/modules/doctools2toc/toc_introduction.md @@ -133,17 +133,17 @@ ~~ | ~~ doctools::toc::export ~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ doctools::toc::import | | | +---------------+-------------------------+ | +------------------+---------------+-----------------------+---------------+ | | | | | | | | | - doctools::config = | | | = doctools::include doctools::config doctools::paths + struct:map = | | | = doctools::include struct::map fileutil::paths | | | | | doctools::toc::export::<*> | | | doctools::toc::import::<*> doctoc | | | doctoc, json - json | | | | \\ - html | | | doctools::toc::parse \\ - nroff | | | | \\ + json | | | | \ + html | | | doctools::toc::parse \ + nroff | | | | \ wiki | | | +---------------+ json text | | | | | doctools::toc::structure | | +-------+---------------+ Index: embedded/md/tcllib/files/modules/fileutil/multiop.md ================================================================== --- embedded/md/tcllib/files/modules/fileutil/multiop.md +++ embedded/md/tcllib/files/modules/fileutil/multiop.md @@ -400,44 +400,44 @@ # EXAMPLES The following examples assume that the variable __F__ contains a reference to a multi\-file operation object\. - $F do copy \\ - the *.dll \\ - from c:/TDK/PrivateOpenSSL/bin \\ + $F do copy \ + the *.dll \ + from c:/TDK/PrivateOpenSSL/bin \ to [installdir_of tls] - $F do move \\ - the * \\ - from /sources \\ - into /scratch \\ + $F do move \ + the * \ + from /sources \ + into /scratch \ but not *.html # Alternatively use 'except for *.html'. - $F do \\ - move \\ - the index \\ - from /sources \\ - into /scratch \\ + $F do \ + move \ + the index \ + from /sources \ + into /scratch \ as pkgIndex.tcl - $F do \\ - remove \\ - the *.txt \\ + $F do \ + remove \ + the *.txt \ in /scratch Note that the fact that most commands just modify the object state allows us to use more off forms as specifications instead of just nearly\-natural language sentences\. For example the second example in this section can re\-arranged into: - $F do \\ - from /sources \\ - into /scratch \\ - but not *.html \\ - move \\ + $F do \ + from /sources \ + into /scratch \ + but not *.html \ + move \ the * and the result is not only still a valid specification, but even stays relatively readable\. @@ -446,17 +446,17 @@ __the__ was executed\. However no other state is reset in that manner, allowing the user to avoid repetitions of unchanging information\. For example the second and third examples of this section can be merged and rewritten into the equivalent: - $F do \\ - move \\ - the * \\ - from /sources \\ - into /scratch \\ - but not *.html not index \\ - the index \\ + $F do \ + move \ + the * \ + from /sources \ + into /scratch \ + but not *.html not index \ + the index \ as pkgIndex.tcl # Bugs, Ideas, Feedback This document, and the package it describes, will undoubtedly contain bugs and ADDED embedded/md/tcllib/files/modules/fileutil/paths.md Index: embedded/md/tcllib/files/modules/fileutil/paths.md ================================================================== --- /dev/null +++ embedded/md/tcllib/files/modules/fileutil/paths.md @@ -0,0 +1,100 @@ + +[//000000001]: # (fileutil::paths \- ) +[//000000002]: # (Generated from file 'paths\.man' by tcllib/doctools with format 'markdown') +[//000000003]: # (fileutil::paths\(n\) 1 tcllib "") + +
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | Modules | Applications ]
+ +# NAME + +fileutil::paths \- Manage search path pools + +# Table Of Contents + + - [Table Of Contents](#toc) + + - [Synopsis](#synopsis) + + - [Description](#section1) + + - [API](#section2) + + - [Bugs, Ideas, Feedback](#section3) + +# SYNOPSIS + +package require Tcl 8\.4 +package require fileutil::paths ?1? + +[__::fileutil::paths__ *poolName*](#1) +[__poolName__ __method__ ?*arg arg \.\.\.*?](#2) +[*poolName* __add__ *path*](#3) +[*poolName* __clear__](#4) +[*poolName* __paths__](#5) +[*poolName* __remove__ *path*](#6) + +# DESCRIPTION + +Provides a snit class whose instances manage a pool of \(search\) paths\. + +# API + +The main command provides construction of search path pools: + + - __::fileutil::paths__ *poolName* + + Creates a new, empty pool of search paths with an associated global Tcl + command whose name is *poolName*\. It may be used to invoke various + operations on the pool\. It has the following general form: + + * __poolName__ __method__ ?*arg arg \.\.\.*? + + __method__ and *arg*uments determine the exact behavior of the + command\. + + If *poolName* is specified as __%AUTO%__ a unique name will be + generated by the package itself\. The result of the command is the + fully\-qualified name of the instance command\. + +The following commands are possible for pool objects: + + - *poolName* __add__ *path* + + Adds the *path* to the pool\. Nothing is done if the *path* is already + known to the pool\. The result of the command is the empty string\. + + - *poolName* __clear__ + + Clears the entire pool\. In other words, removes all paths from it\. The + result of the command is the empty string\. + + - *poolName* __paths__ + + Returns the list of all paths known to the pool, in the order they were + added\. + + - *poolName* __remove__ *path* + + Removes the *path* from the pool, if it is known to the pool\. Unknown + paths are ignored without error\. The result of the command is the empty + string\. + +# Bugs, Ideas, Feedback + +This document, and the package it describes, will undoubtedly contain bugs and +other problems\. Please report such in the category *fileutil* of the [Tcllib +Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. 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\. Index: embedded/md/tcllib/files/modules/grammar_aycock/aycock.md ================================================================== --- embedded/md/tcllib/files/modules/grammar_aycock/aycock.md +++ embedded/md/tcllib/files/modules/grammar_aycock/aycock.md @@ -1,11 +1,11 @@ [//000000001]: # (grammar::aycock \- Aycock\-Horspool\-Earley parser generator for Tcl) [//000000002]: # (Generated from file 'aycock\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2006 by Kevin B\. Kenny -Redistribution permitted under the terms of the Open Publication License ) -[//000000004]: # (grammar::aycock\(n\) 1\.0 tcllib "Aycock\-Horspool\-Earley parser generator for Tcl") +[//000000003]: # (Copyright © 2006 by Kevin B\. Kenny ) +[//000000004]: # (Redistribution permitted under the terms of the Open Publication License ) +[//000000005]: # (grammar::aycock\(n\) 1\.0 tcllib "Aycock\-Horspool\-Earley parser generator for Tcl")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | -Copyright © 2007 Bogdan ) -[//000000004]: # (grammar::fa::dexec\(n\) 0\.2 tcllib "Finite automaton operations and usage") +[//000000003]: # (Copyright © 2004 Andreas Kupries ) +[//000000004]: # (Copyright © 2007 Bogdan ) +[//000000005]: # (grammar::fa::dexec\(n\) 0\.2 tcllib "Finite automaton operations and usage")
[
Main Table Of Contents | Table Of Contents | Keyword Index | Categories | *faName* __deserialize__ \[*srcFA* __serialize__\] - *faName* __\-\->__ *dstFA* This is the reverse assignment operator for automatons\. It copies the automation contained in the object *faName* over the automaton definition @@ -178,11 +178,11 @@ in the object *dstFA*\. The old contents of *dstFA* are deleted by this operation\. This operation is in effect equivalent to - *dstFA* __deserialize__ [*faName* __serialize__] + > *dstFA* __deserialize__ \[*faName* __serialize__\] - *faName* __serialize__ This method serializes the automaton stored in *faName*\. In other words it returns a tcl *value* completely describing that automaton\. This allows, @@ -227,15 +227,15 @@ Drive -- yellow --> Brake -- red --> (Stop) -- red/yellow --> Attention -- green --> Drive (...) is the start state. a possible serialization is - grammar::fa \\ - {yellow red green red/yellow} \\ - {Drive {0 0 {yellow Brake}} \\ - Brake {0 0 {red Stop}} \\ - Stop {1 0 {red/yellow Attention}} \\ + grammar::fa \ + {yellow red green red/yellow} \ + {Drive {0 0 {yellow Brake}} \ + Brake {0 0 {red Stop}} \ + Stop {1 0 {red/yellow Attention}} \ Attention {0 0 {green Drive}}} A possible one, because I did not care about creation order here - *faName* __deserialize__ *serialization* Index: embedded/md/tcllib/files/modules/grammar_peg/peg.md ================================================================== --- embedded/md/tcllib/files/modules/grammar_peg/peg.md +++ embedded/md/tcllib/files/modules/grammar_peg/peg.md @@ -221,11 +221,11 @@ over the grammar definition in *pegName*\. The old contents of *pegName* are deleted by this operation\. This operation is in effect equivalent to - *pegName* __deserialize__ [*srcPEG* __serialize__] + > *pegName* __deserialize__ \[*srcPEG* __serialize__\] - *pegName* __\-\->__ *dstPEG* This is the reverse assignment operator for grammars\. It copies the automation contained in the object *pegName* over the grammar definition @@ -232,11 +232,11 @@ in the object *dstPEG*\. The old contents of *dstPEG* are deleted by this operation\. This operation is in effect equivalent to - *dstPEG* __deserialize__ [*pegName* __serialize__] + > *dstPEG* __deserialize__ \[*pegName* __serialize__\] - *pegName* __serialize__ This method serializes the grammar stored in *pegName*\. In other words it returns a tcl *value* completely describing that grammar\. This allows, for @@ -275,24 +275,24 @@ AddOp <- '+'/'-' Term <- Number a possible serialization is - grammar::peg \\ - {Expression {/ {x ( Expression )} {x Factor {* {x MulOp Factor}}}} \\ - Factor {x Term {* {x AddOp Term}}} \\ - Term Number \\ - MulOp {/ * /} \\ - AddOp {/ + -} \\ - Number {x {? Sign} {+ Digit}} \\ - Sign {/ + -} \\ - Digit {/ 0 1 2 3 4 5 6 7 8 9} \\ - } \\ - {Expression value Factor value \\ - Term value MulOp value \\ - AddOp value Number value \\ - Sign value Digit value \\ + grammar::peg \ + {Expression {/ {x ( Expression )} {x Factor {* {x MulOp Factor}}}} \ + Factor {x Term {* {x AddOp Term}}} \ + Term Number \ + MulOp {/ * /} \ + AddOp {/ + -} \ + Number {x {? Sign} {+ Digit}} \ + Sign {/ + -} \ + Digit {/ 0 1 2 3 4 5 6 7 8 9} \ + } \ + {Expression value Factor value \ + Term value MulOp value \ + AddOp value Number value \ + Sign value Digit value \ } Expression A possible one, because the order of the nonterminals in the dictionary is not relevant\. Index: embedded/md/tcllib/files/modules/hook/hook.md ================================================================== --- embedded/md/tcllib/files/modules/hook/hook.md +++ embedded/md/tcllib/files/modules/hook/hook.md @@ -80,15 +80,15 @@ coupling between the modules sending and receiving the notification\. Loose coupling between sender and receiver is often desirable, however\. In Model/View/Controller terms, a View can send a command \(stemming from user input\) to the Controller, which updates the Model\. The Model can then call a -hook *to which all relevant Views subscribe\.* The Model is decoupled from the -Views, and indeed need not know whether any Views actually exist\. At present, -Tcl/Tk has no standard mechanism for implementing loose coupling of this kind\. -This package defines a new command, __hook__, which implements just such a -mechanism\. +hook *to which all relevant* *Views subscribe\.* The Model is decoupled from +the Views, and indeed need not know whether any Views actually exist\. At +present, Tcl/Tk has no standard mechanism for implementing loose coupling of +this kind\. This package defines a new command, __hook__, which implements +just such a mechanism\. ## Bindings The __hook__ command manages a collection of hook bindings\. A hook binding has four elements: Index: embedded/md/tcllib/files/modules/httpd/httpd.md ================================================================== --- embedded/md/tcllib/files/modules/httpd/httpd.md +++ embedded/md/tcllib/files/modules/httpd/httpd.md @@ -1,10 +1,10 @@ -[//000000001]: # (tool \- Tcl Web Server) +[//000000001]: # (httpd \- Tcl Web Server) [//000000002]: # (Generated from file 'httpd\.man' by tcllib/doctools with format 'markdown') [//000000003]: # (Copyright © 2018 Sean Woods ) -[//000000004]: # (tool\(n\) 4\.1\.1 tcllib "Tcl Web Server") +[//000000004]: # (httpd\(n\) 4\.3\.3 tcllib "Tcl Web Server")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | Modules | Applications ]
# NAME -tool \- A TclOO and coroutine based web server +httpd \- A TclOO and coroutine based web server # Table Of Contents - [Table Of Contents](#toc) @@ -23,45 +23,53 @@ - [Description](#section1) - [Minimal Example](#section2) - - [Class ::httpd::server](#section3) - - - [Class ::httpd::reply](#section4) - - - [Reply Method Ensembles](#section5) - - - [Reply Method Ensemble: http\_info](#section6) - - - [Reply Method Ensemble: request](#section7) - - - [Reply Method Ensemble: reply](#section8) - - - [Reply Methods](#section9) - - - [Class ::httpd::content](#section10) - - - [Class ::httpd::content\.cgi](#section11) - - - [Class ::httpd::content\.file](#section12) - - - [Class ::httpd::content\.proxy](#section13) - - - [Class ::httpd::content\.scgi](#section14) - - - [Class ::httpd::content\.websocket](#section15) - - - [SCGI Server Functions](#section16) - - - [Class ::httpd::reply\.scgi](#section17) - - - [Class ::httpd::server\.scgi](#section18) - - - [AUTHORS](#section19) - - - [Bugs, Ideas, Feedback](#section20) + - [Classes](#section3) + + - [Class httpd::mime](#subsection1) + + - [Class httpd::reply](#subsection2) + + - [Class httpd::server](#subsection3) + + - [Class httpd::server::dispatch](#subsection4) + + - [Class httpd::content\.redirect](#subsection5) + + - [Class httpd::content\.cache](#subsection6) + + - [Class httpd::content\.template](#subsection7) + + - [Class httpd::content\.file](#subsection8) + + - [Class httpd::content\.exec](#subsection9) + + - [Class httpd::content\.proxy](#subsection10) + + - [Class httpd::content\.cgi](#subsection11) + + - [Class httpd::protocol\.scgi](#subsection12) + + - [Class httpd::content\.scgi](#subsection13) + + - [Class httpd::server\.scgi](#subsection14) + + - [Class httpd::content\.websocket](#subsection15) + + - [Class httpd::plugin](#subsection16) + + - [Class httpd::plugin\.dict\_dispatch](#subsection17) + + - [Class httpd::reply\.memchan](#subsection18) + + - [Class httpd::plugin\.local\_memchan](#subsection19) + + - [AUTHORS](#section4) + + - [Bugs, Ideas, Feedback](#section5) - [Keywords](#keywords) - [Category](#category) @@ -68,72 +76,127 @@ - [Copyright](#copyright) # SYNOPSIS package require Tcl 8\.6 -package require httpd ?4\.1\.1? -package require sha1 -package require dicttool -package require oo::meta -package require oo::dialect -package require tool +package require uuid +package require clay package require coroutine package require fileutil package require fileutil::magic::filetype package require websocket package require mime package require cron package require uri package require Markdown -[constructor ?port ?port?? ?myaddr ?ipaddr?|all? ?server\_string ?string?? ?server\_name ?string??](#1) -[method __add\_uri__ *pattern* *dict*](#2) -[method __connect__ *sock* *ip* *port*](#3) -[method __Connect__ *uuid* *sock* *ip*](#4) -[method __[counter](\.\./counter/counter\.md)__ *which*](#5) -[method __CheckTimeout__](#6) -[method __dispatch__ *header\_dict*](#7) -[method __[log](\.\./log/log\.md)__ *args*](#8) -[method __port\_listening__](#9) -[method __PrefixNormalize__ *prefix*](#10) -[method __start__](#11) -[method __stop__](#12) -[method __template__ *page*](#13) -[method __TemplateSearch__ *page*](#14) -[method __Validate\_Connection__ *sock* *ip*](#15) -[method __ENSEMBLE::add__ *field* *element*](#16) -[method __ENSEMBLE::dump__](#17) -[method __ENSEMBLE::get__ *field*](#18) -[method __ENSEMBLE::reset__](#19) -[method __ENSEMBLE::remove__ *field* *element*](#20) -[method __ENSEMBLE::replace__ *keyvaluelist*](#21) -[method __ENSEMBLE::reset__](#22) -[method __ENSEMBLE::set__ *field* *value*](#23) -[method __http\_info::netstring__](#24) -[method __request::parse__ *string*](#25) -[method __reply::output__](#26) -[method __close__](#27) -[method __HttpHeaders__ *sock* *?debug?*](#28) -[method __dispatch__ *newsock* *datastate*](#29) -[method __[error](\.\./\.\./\.\./\.\./index\.md\#error)__ *code* *?message?* *?errorInfo?*](#30) -[method __content__](#31) -[method __EncodeStatus__ *status*](#32) -[method FormData](#33) -[method MimeParse *mimetext*](#34) -[method __DoOutput__](#35) -[method PostData *length*](#36) -[method __puts__ *string*](#37) +[method __ChannelCopy__ *in* *out* ?*args*?](#1) +[method __html\_header__ ?*title* ____? ?*args*?](#2) +[method __html\_footer__ ?*args*?](#3) +[method __http\_code\_string__ *code*](#4) +[method __HttpHeaders__ *sock* ?*debug* ____?](#5) +[method __HttpHeaders\_Default__](#6) +[method __HttpServerHeaders__](#7) +[method __MimeParse__ *mimetext*](#8) +[method __Url\_Decode__ *data*](#9) +[method __Url\_PathCheck__ *urlsuffix*](#10) +[method __wait__ *mode* *sock*](#11) +[variable __ChannelRegister__](#12) +[variable __reply__](#13) +[variable __request__](#14) +[delegate ____](#15) +[method __constructor__ *ServerObj* ?*args*?](#16) +[method __destructor__ ?*dictargs*?](#17) +[method __ChannelRegister__ ?*args*?](#18) +[method __close__](#19) +[method __Log\_Dispatched__](#20) +[method __dispatch__ *newsock* *datastate*](#21) +[method __Dispatch__](#22) +[method __html\_header__ *title* ?*args*?](#23) +[method __html\_footer__ ?*args*?](#24) +[method __[error](\.\./\.\./\.\./\.\./index\.md\#error)__ *code* ?*msg* ____? ?*errorInfo* ____?](#25) +[method __content__](#26) +[method __EncodeStatus__ *status*](#27) +[method __[log](\.\./log/log\.md)__ *type* ?*info* ____?](#28) +[method __CoroName__](#29) +[method __DoOutput__](#30) +[method __FormData__](#31) +[method __PostData__ *length*](#32) +[method __Session\_Load__](#33) +[method __puts__ *line*](#34) +[method __RequestFind__ *field*](#35) +[method __request__ *subcommand* ?*args*?](#36) +[method __reply__ *subcommand* ?*args*?](#37) [method __reset__](#38) [method __timeOutCheck__](#39) [method __[timestamp](\.\./\.\./\.\./\.\./index\.md\#timestamp)__](#40) -[method __TransferComplete__ *args*](#41) -[method __Url\_Decode__ *string*](#42) -[method cgi\_info](#43) -[option __path__](#44) -[option __[prefix](\.\./\.\./\.\./\.\./index\.md\#prefix)__](#45) -[method proxy\_info](#46) -[method scgi\_info](#47) +[variable __template__](#41) +[variable __url\_patterns__](#42) +[method __constructor__ *args* ?*port* __auto__? ?*myaddr* __127\.0\.0\.1__? ?*string* __auto__? ?*name* __auto__? ?*doc\_root* ____? ?*reverse\_dns* __0__? ?*configuration\_file* ____? ?*protocol* __HTTP/1\.1__?](#43) +[method __destructor__ ?*dictargs*?](#44) +[method __connect__ *sock* *ip* *port*](#45) +[method __ServerHeaders__ *ip* *http\_request* *mimetxt*](#46) +[method __Connect__ *uuid* *sock* *ip*](#47) +[method __[counter](\.\./counter/counter\.md)__ *which*](#48) +[method __CheckTimeout__](#49) +[method __[debug](\.\./debug/debug\.md)__ ?*args*?](#50) +[method __dispatch__ *data*](#51) +[method __Dispatch\_Default__ *reply*](#52) +[method __Dispatch\_Local__ *data*](#53) +[method __Headers\_Local__ *varname*](#54) +[method __Headers\_Process__ *varname*](#55) +[method __HostName__ *ipaddr*](#56) +[method __[log](\.\./log/log\.md)__ ?*args*?](#57) +[method __[plugin](\.\./\.\./\.\./\.\./index\.md\#plugin)__ *slot* ?*class* ____?](#58) +[method __port\_listening__](#59) +[method __PrefixNormalize__ *prefix*](#60) +[method __[source](\.\./\.\./\.\./\.\./index\.md\#source)__ *filename*](#61) +[method __start__](#62) +[method __stop__](#63) +[method __SubObject \{\} db__](#64) +[method __SubObject \{\} default__](#65) +[method __template__ *page*](#66) +[method __TemplateSearch__ *page*](#67) +[method __Thread\_start__](#68) +[method __Uuid\_Generate__](#69) +[method __Validate\_Connection__ *sock* *ip*](#70) +[method __reset__](#71) +[method __content__](#72) +[method __Dispatch__](#73) +[method __content__](#74) +[method __FileName__](#75) +[method __DirectoryListing__ *local\_file*](#76) +[method __content__](#77) +[method __Dispatch__](#78) +[variable __exename__](#79) +[method __CgiExec__ *execname* *script* *arglist*](#80) +[method __Cgi\_Executable__ *script*](#81) +[method __proxy\_channel__](#82) +[method __proxy\_path__](#83) +[method __ProxyRequest__ *chana* *chanb*](#84) +[method __ProxyReply__ *chana* *chanb* ?*args*?](#85) +[method __Dispatch__](#86) +[method __FileName__](#87) +[method __proxy\_channel__](#88) +[method __ProxyRequest__ *chana* *chanb*](#89) +[method __ProxyReply__ *chana* *chanb* ?*args*?](#90) +[method __DirectoryListing__ *local\_file*](#91) +[method __EncodeStatus__ *status*](#92) +[method __scgi\_info__](#93) +[method __proxy\_channel__](#94) +[method __ProxyRequest__ *chana* *chanb*](#95) +[method __ProxyReply__ *chana* *chanb* ?*args*?](#96) +[method __[debug](\.\./debug/debug\.md)__ ?*args*?](#97) +[method __Connect__ *uuid* *sock* *ip*](#98) +[method __Dispatch\_Dict__ *data*](#99) +[method __uri \{\} add__ *vhosts* *patterns* *info*](#100) +[method __uri \{\} direct__ *vhosts* *patterns* *info* *body*](#101) +[method __output__](#102) +[method __DoOutput__](#103) +[method __close__](#104) +[method __local\_memchan__ *command* ?*args*?](#105) +[method __Connect\_Local__ *uuid* *sock* ?*args*?](#106) # DESCRIPTION This module implements a web server, suitable for embedding in an application\. The server is object oriented, and contains all of the fundamentals needed for a @@ -143,111 +206,80 @@ Starting a web service requires starting a class of type __httpd::server__, and providing that server with one or more URIs to service, and __httpd::reply__ derived classes to generate them\. - tool::define ::reply.hello { + oo::class create ::reply.hello { method content {} { my puts "IRM Dispatch Server" my puts "

Hello World!

" my puts } } - ::docserver::server create HTTPD port 8015 myaddr 127.0.0.1 - HTTPD add_uri /* [list mixin reply.hello] - -# Class ::httpd::server - -This class is the root object of the webserver\. It is responsible for opening -the socket and providing the initial connection negotiation\. - - - constructor ?port ?port?? ?myaddr ?ipaddr?|all? ?server\_string ?string?? ?server\_name ?string?? - - Build a new server object\. ?port? is the port to listen on - - - method __add\_uri__ *pattern* *dict* - - Set the hander for a URI pattern\. Information given in the *dict* is - stored in the data structure the __dispatch__ method uses\. If a field - called *mixin* is given, that class will be mixed into the reply object - immediately after construction\. - - - method __connect__ *sock* *ip* *port* - - Reply to an open socket\. This method builds a coroutine to manage the - remainder of the connection\. The coroutine's operations are driven by the - __Connect__ method\. - - - method __Connect__ *uuid* *sock* *ip* - - This method reads HTTP headers, and then consults the __dispatch__ - method to determine if the request is valid, and/or what kind of reply to - generate\. Under normal cases, an object of class __::http::reply__ is - created\. Fields the server are looking for in particular are: class: A class - to use instead of the server's own *reply\_class* mixin: A class to be - mixed into the new object after construction\. All other fields are passed - along to the __http\_info__ structure of the reply object\. After the - class is created and the mixin is mixed in, the server invokes the reply - objects __dispatch__ method\. This action passes control of the socket to - the reply object\. The reply object manages the rest of the transaction, - including closing the socket\. - - - method __[counter](\.\./counter/counter\.md)__ *which* - - Increment an internal counter\. - - - method __CheckTimeout__ - - Check open connections for a time out event\. - - - method __dispatch__ *header\_dict* - - Given a key/value list of information, return a data structure describing - how the server should reply\. - - - method __[log](\.\./log/log\.md)__ *args* - - Log an event\. The input for args is free form\. This method is intended to be - replaced by the user, and is a noop for a stock http::server object\. - - - method __port\_listening__ - - Return the actual port that httpd is listening on\. - - - method __PrefixNormalize__ *prefix* - - For the stock version, trim trailing /'s and \*'s from a prefix\. This method - can be replaced by the end user to perform any other transformations needed - for the application\. - - - method __start__ - - Open the socket listener\. - - - method __stop__ - - Shut off the socket listener, and destroy any pending replies\. - - - method __template__ *page* - - Return a template for the string *page* - - - method __TemplateSearch__ *page* - - Perform a search for the template that best matches *page*\. This can - include local file searches, in\-memory structures, or even database lookups\. - The stock implementation simply looks for files with a \.tml or \.html - extension in the ?doc\_root? directory\. - - - method __Validate\_Connection__ *sock* *ip* - - Given a socket and an ip address, return true if this connection should be - terminated, or false if it should be allowed to continue\. The stock - implementation always returns 0\. This is intended for applications to be - able to implement black lists and/or provide security based on IP address\. - -# Class ::httpd::reply + ::httpd::server create HTTPD port 8015 myaddr 127.0.0.1 doc_root ~/htdocs + HTTPD plugin dispatch httpd::server::dispatch + HTTPD uri add * /hello [list mixin reply.hello] + +The bare module does have facilities to hose a files from a file system\. Files +that end in a \.tml will be substituted in the style of Tclhttpd: + + + [my html_header {Hello World!}] + Your Server is running. +

+ The time is now [clock format [clock seconds]] + [my html_footer] + +A complete example of an httpd server is in the /examples directory of Tcllib\. +It also show how to dispatch URIs to other processes via SCGI and HTTP proxies\. + + cd ~/tcl/sandbox/tcllib + tclsh examples/httpd.tcl + +# Classes + +## Class httpd::mime + +A metaclass for MIME handling behavior across a live socket + +__Methods__ + + - method __ChannelCopy__ *in* *out* ?*args*? + + - method __html\_header__ ?*title* ____? ?*args*? + + Returns a block of HTML + + - method __html\_footer__ ?*args*? + + - method __http\_code\_string__ *code* + + - method __HttpHeaders__ *sock* ?*debug* ____? + + - method __HttpHeaders\_Default__ + + - method __HttpServerHeaders__ + + - method __MimeParse__ *mimetext* + + Converts a block of mime encoded text to a key/value list\. If an exception + is encountered, the method will generate its own call to the + __[error](\.\./\.\./\.\./\.\./index\.md\#error)__ method, and immediately + invoke the __output__ method to produce an error code and close the + connection\. + + - method __Url\_Decode__ *data* + + De\-httpizes a string\. + + - method __Url\_PathCheck__ *urlsuffix* + + - method __wait__ *mode* *sock* + +## Class httpd::reply + +*ancestors*: __httpd::mime__ A class which shephards a request through the process of generating a reply\. The socket associated with the reply is available at all times as the *chan* variable\. The process of generating a reply begins with an __httpd::server__ generating a __http::class__ object, mixing in a set of behaviors and then @@ -270,155 +302,59 @@ the __[error](\.\./\.\./\.\./\.\./index\.md\#error)__ method if an exception is raised\. 1. Invokes the __output__ method for the object -# Reply Method Ensembles - -The __http::reply__ class and its derivatives maintain several variables as -dictionaries internally\. Access to these dictionaries is managed through a -dedicated ensemble\. The ensemble implements most of the same behaviors as the -__[dict](\.\./\.\./\.\./\.\./index\.md\#dict)__ command\. Each ensemble implements -the following methods above, beyond, or modifying standard dicts: - - - method __ENSEMBLE::add__ *field* *element* - - Add *element* to a list stored in *field*, but only if it is not already - present om the list\. - - - method __ENSEMBLE::dump__ - - Return the current contents of the data structure as a key/value list\. - - - method __ENSEMBLE::get__ *field* - - Return the value of the field *field*, or an empty string if it does not - exist\. - - - method __ENSEMBLE::reset__ - - Return a key/value list of the default contents for this data structure\. - - - method __ENSEMBLE::remove__ *field* *element* - - Remove all instances of *element* from the list stored in *field*\. - - - method __ENSEMBLE::replace__ *keyvaluelist* - - Replace the internal dict with the contents of *keyvaluelist* - - - method __ENSEMBLE::reset__ - - Replace the internal dict with the default state\. - - - method __ENSEMBLE::set__ *field* *value* - - Set the value of *field* to *value*\. - -# Reply Method Ensemble: http\_info - -Manages HTTP headers passed in by the server\. Ensemble Methods: - - - method __http\_info::netstring__ - - Return the contents of this data structure as a netstring encoded block\. - -# Reply Method Ensemble: request - -Managed data from MIME headers of the request\. - - - method __request::parse__ *string* - - Replace the contents of the data structure with information encoded in a - MIME formatted block of text \(*string*\)\. - -# Reply Method Ensemble: reply - -Manage the headers sent in the reply\. - - - method __reply::output__ - - Return the contents of this data structure as a MIME encoded block - appropriate for an HTTP response\. - -# Reply Methods - - - method __close__ - - Terminate the transaction, and close the socket\. - - - method __HttpHeaders__ *sock* *?debug?* - - Stream MIME headers from the socket *sock*, stopping at an empty line\. - Returns the stream as a block of text\. - - - method __dispatch__ *newsock* *datastate* - - Take over control of the socket *newsock*, and store that as the *chan* - variable for the object\. This method runs through all of the steps of - reading HTTP headers, generating content, and closing the connection\. \(See - class writetup\)\. - - - method __[error](\.\./\.\./\.\./\.\./index\.md\#error)__ *code* *?message?* *?errorInfo?* - - Generate an error message of the specified *code*, and display the - *message* as the reason for the exception\. *errorInfo* is passed in from - calls, but how or if it should be displayed is a prerogative of the - developer\. - - - method __content__ - - Generate the content for the reply\. This method is intended to be replaced - by the mixin\. Developers have the option of streaming output to a buffer via - the __puts__ method of the reply, or simply populating the - *reply\_body* variable of the object\. The information returned by the - __content__ method is not interpreted in any way\. If an exception is - thrown \(via the __[error](\.\./\.\./\.\./\.\./index\.md\#error)__ command in - Tcl, for example\) the caller will auto\-generate a 500 \{Internal Error\} - message\. A typical implementation of __content__ look like: - - tool::define ::test::content.file { +Developers have the option of streaming output to a buffer via the __puts__ +method of the reply, or simply populating the *reply\_body* variable of the +object\. The information returned by the __content__ method is not +interpreted in any way\. If an exception is thrown \(via the +__[error](\.\./\.\./\.\./\.\./index\.md\#error)__ command in Tcl, for example\) the +caller will auto\-generate a 500 \{Internal Error\} message\. A typical +implementation of __content__ look like: + + clay::define ::test::content.file { superclass ::httpd::content.file # Return a file # Note: this is using the content.file mixin which looks for the reply_file variable # and will auto-compute the Content-Type method content {} { my reset - set doc_root [my http_info get doc_root] + set doc_root [my request get DOCUMENT_ROOT] my variable reply_file set reply_file [file join $doc_root index.html] } } - tool::define ::test::content.time { + clay::define ::test::content.time { # return the current system time method content {} { my variable reply_body my reply set Content-Type text/plain set reply_body [clock seconds] } } - tool::define ::test::content.echo { + clay::define ::test::content.echo { method content {} { my variable reply_body my reply set Content-Type [my request get CONTENT_TYPE] set reply_body [my PostData [my request get CONTENT_LENGTH]] } } - tool::define ::test::content.form_handler { + clay::define ::test::content.form_handler { method content {} { set form [my FormData] my reply set Content-Type {text/html; charset=UTF-8} - my puts [my html header {My Dynamic Page}] + my puts [my html_header {My Dynamic Page}] my puts "" my puts "You Sent

" my puts "" foreach {f v} $form { my puts "" } my puts "
$f$v

" my puts "Send some info:

" - my puts "

" + my puts "" my puts "" foreach field {name rank serial_number} { set line " + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + @@ -3441,11 +3451,11 @@ logger + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + @@ -579,185 +587,193 @@ + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + @@ -1251,185 +1267,193 @@ + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + @@ -1438,134 +1462,150 @@ + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - Index: idoc/www/toc.html ================================================================== --- idoc/www/toc.html +++ idoc/www/toc.html @@ -797,38 +797,42 @@ + + + + - + - + - + - + - + - + - +
$field" my puts [my html footer] } } - - method __EncodeStatus__ *status* +__Variable__ + + - variable __ChannelRegister__ + + - variable __reply__ + + A dictionary which will converted into the MIME headers of the reply + + - variable __request__ + + A dictionary containing the SCGI transformed HTTP headers for the request + +__Delegate__ + + - delegate ____ + + The server object which spawned this reply + +__Methods__ + + - method __constructor__ *ServerObj* ?*args*? + + - method __destructor__ ?*dictargs*? + + clean up on exit + + - method __ChannelRegister__ ?*args*? + + Registers a channel to be closed by the close method + + - method __close__ + + Close channels opened by this object + + - method __Log\_Dispatched__ + + Record a dispatch event + + - method __dispatch__ *newsock* *datastate* + + Accept the handoff from the server object of the socket *newsock* and feed + it the state *datastate*\. Fields the *datastate* are looking for in + particular are: + + \* __mixin__ \- A key/value list of slots and classes to be mixed into the + object prior to invoking __Dispatch__\. + + \* __http__ \- A key/value list of values to populate the object's + *request* ensemble + + All other fields are passed along to the __clay__ structure of the + object\. + + - method __Dispatch__ + + - method __html\_header__ *title* ?*args*? + + - method __html\_footer__ ?*args*? + + - method __[error](\.\./\.\./\.\./\.\./index\.md\#error)__ *code* ?*msg* ____? ?*errorInfo* ____? + + - method __content__ + + REPLACE ME: This method is the "meat" of your application\. It writes to the + result buffer via the "puts" method and can tweak the headers via "clay put + header\_reply" + + - method __EncodeStatus__ *status* Formulate a standard HTTP status header from he string provided\. - - method FormData + - method __[log](\.\./log/log\.md)__ *type* ?*info* ____? + + - method __CoroName__ + + - method __DoOutput__ + + Generates the the HTTP reply, streams that reply back across *chan*, and + destroys the object\. + + - method __FormData__ For GET requests, converts the QUERY\_DATA header into a key/value list\. For POST requests, reads the Post data and converts that information to a key/value list for application/x\-www\-form\-urlencoded posts\. For multipart posts, it composites all of the MIME headers of the post to a singular key/value list, and provides MIME\_\* information as computed by the __[mime](\.\./mime/mime\.md)__ package, including the MIME\_TOKEN, which can be fed back into the mime package to read out the contents\. - - method MimeParse *mimetext* - - Converts a block of mime encoded text to a key/value list\. If an exception - is encountered, the method will generate its own call to the - __[error](\.\./\.\./\.\./\.\./index\.md\#error)__ method, and immediately - invoke the __output__ method to produce an error code and close the - connection\. - - - method __DoOutput__ - - Generates the the HTTP reply, and streams that reply back across *chan*\. - - - method PostData *length* + - method __PostData__ *length* Stream *length* bytes from the *chan* socket, but only of the request is a POST or PUSH\. Returns an empty string otherwise\. - - method __puts__ *string* + - method __Session\_Load__ + + Manage session data + + - method __puts__ *line* Appends the value of *string* to the end of *reply\_body*, as well as a trailing newline character\. + - method __RequestFind__ *field* + + - method __request__ *subcommand* ?*args*? + + - method __reply__ *subcommand* ?*args*? + - method __reset__ Clear the contents of the *reply\_body* variable, and reset all headers in the __reply__ structure back to the defaults for this object\. @@ -483,117 +493,339 @@ Return the current system time in the format: %a, %d %b %Y %T %Z - - method __TransferComplete__ *args* - - Intended to be invoked from __chan copy__ as a callback\. This closes - every channel fed to it on the command line, and then destroys the object\. - - ### - # Output the body - ### - chan configure $sock -translation binary -blocking 0 -buffering full -buffersize 4096 - chan configure $chan -translation binary -blocking 0 -buffering full -buffersize 4096 - if {$length} { - ### - # Send any POST/PUT/etc content - ### - chan copy $sock $chan -size $SIZE -command [info coroutine] - yield - } - catch {close $sock} - chan flush $chan - - - method __Url\_Decode__ *string* - - De\-httpizes a string\. - -# Class ::httpd::content - -The httpd module includes several ready to use implementations of content mixins -for common use cases\. Options are passed in to the __add\_uri__ method of the -server\. - -# Class ::httpd::content\.cgi - -An implementation to relay requests to process which will accept post data -streamed in vie stdin, and sent a reply streamed to stdout\. - - - method cgi\_info - - Mandatory method to be replaced by the end user\. If needed, activates the - process to proxy, and then returns a list of three values: *exec* \- The - arguments to send to exec to fire off the responding process, minus the - stdin/stdout redirection\. - -# Class ::httpd::content\.file - -An implementation to deliver files from the local file system\. - - - option __path__ - - The root directory on the local file system to be exposed via http\. - - - option __[prefix](\.\./\.\./\.\./\.\./index\.md\#prefix)__ - - The prefix of the URI portion to ignore when calculating relative file - paths\. - -# Class ::httpd::content\.proxy - -An implementation to relay requests to another HTTP server, and relay the -results back across the request channel\. - - - method proxy\_info - - Mandatory method to be replaced by the end user\. If needed, activates the - process to proxy, and then returns a list of three values: *proxyhost* \- - The hostname where the proxy is located *proxyport* \- The port to connect - to *proxyscript* \- A pre\-amble block of text to send prior to the mirrored - request - -# Class ::httpd::content\.scgi - -An implementation to relay requests to a server listening on a socket expecting -SCGI encoded requests, and relay the results back across the request channel\. - - - method scgi\_info - - Mandatory method to be replaced by the end user\. If needed, activates the - process to proxy, and then returns a list of three values: *scgihost* \- - The hostname where the scgi listener is located *scgiport* \- The port to - connect to *scgiscript* \- The contents of the *SCRIPT\_NAME* header to be - sent - -# Class ::httpd::content\.websocket - -A placeholder for a future implementation to manage requests that can expect to -be promoted to a Websocket\. Currently it is an empty class\. - -# SCGI Server Functions - -The HTTP module also provides an SCGI server implementation, as well as an HTTP -implementation\. To use the SCGI functions, create an object of the -__http::server\.scgi__ class instead of the __http::server__ class\. - -# Class ::httpd::reply\.scgi - -An modified __http::reply__ implementation that understands how to deal with -netstring encoded headers\. - -# Class ::httpd::server\.scgi - -A modified __http::server__ which is tailored to replying to request -according to the SCGI standard instead of the HTTP standard\. - -# AUTHORS +## Class httpd::server + +*ancestors*: __httpd::mime__ + +__Variable__ + + - variable __template__ + + - variable __url\_patterns__ + +__Methods__ + + - method __constructor__ *args* ?*port* __auto__? ?*myaddr* __127\.0\.0\.1__? ?*string* __auto__? ?*name* __auto__? ?*doc\_root* ____? ?*reverse\_dns* __0__? ?*configuration\_file* ____? ?*protocol* __HTTP/1\.1__? + + - method __destructor__ ?*dictargs*? + + - method __connect__ *sock* *ip* *port* + + Reply to an open socket\. This method builds a coroutine to manage the + remainder of the connection\. The coroutine's operations are driven by the + __Connect__ method\. + + - method __ServerHeaders__ *ip* *http\_request* *mimetxt* + + - method __Connect__ *uuid* *sock* *ip* + + This method reads HTTP headers, and then consults the __dispatch__ + method to determine if the request is valid, and/or what kind of reply to + generate\. Under normal cases, an object of class __::http::reply__ is + created, and that class's __dispatch__ method\. This action passes + control of the socket to the reply object\. The reply object manages the rest + of the transaction, including closing the socket\. + + - method __[counter](\.\./counter/counter\.md)__ *which* + + Increment an internal counter\. + + - method __CheckTimeout__ + + Check open connections for a time out event\. + + - method __[debug](\.\./debug/debug\.md)__ ?*args*? + + - method __dispatch__ *data* + + Given a key/value list of information, return a data structure describing + how the server should reply\. + + - method __Dispatch\_Default__ *reply* + + Method dispatch method of last resort before returning a 404 NOT FOUND + error\. The default behavior is to look for a file in *DOCUMENT\_ROOT* which + matches the query\. + + - method __Dispatch\_Local__ *data* + + Method dispatch method invoked prior to invoking methods implemented by + plugins\. If this method returns a non\-empty dictionary, that structure will + be passed to the reply\. The default is an empty implementation\. + + - method __Headers\_Local__ *varname* + + Introspect and possibly modify a data structure destined for a reply\. This + method is invoked before invoking Header methods implemented by plugins\. The + default implementation is empty\. + + - method __Headers\_Process__ *varname* + + Introspect and possibly modify a data structure destined for a reply\. This + method is built dynamically by the + __[plugin](\.\./\.\./\.\./\.\./index\.md\#plugin)__ method\. + + - method __HostName__ *ipaddr* + + Convert an ip address to a host name\. If the server/ reverse\_dns flag is + false, this method simply returns the IP address back\. Internally, this + method uses the *dns* module from tcllib\. + + - method __[log](\.\./log/log\.md)__ ?*args*? + + Log an event\. The input for args is free form\. This method is intended to be + replaced by the user, and is a noop for a stock http::server object\. + + - method __[plugin](\.\./\.\./\.\./\.\./index\.md\#plugin)__ *slot* ?*class* ____? + + Incorporate behaviors from a plugin\. This method dynamically rebuilds the + __Dispatch__ and __Headers__ method\. For every plugin, the server + looks for the following entries in *clay plugin/*: + + *load* \- A script to invoke in the server's namespace during the + __[plugin](\.\./\.\./\.\./\.\./index\.md\#plugin)__ method invokation\. + + *dispatch* \- A script to stitch into the server's __Dispatch__ method\. + + *headers* \- A script to stitch into the server's __Headers__ method\. + + *thread* \- A script to stitch into the server's __Thread\_start__ + method\. + + - method __port\_listening__ + + Return the actual port that httpd is listening on\. + + - method __PrefixNormalize__ *prefix* + + For the stock version, trim trailing /'s and \*'s from a prefix\. This method + can be replaced by the end user to perform any other transformations needed + for the application\. + + - method __[source](\.\./\.\./\.\./\.\./index\.md\#source)__ *filename* + + - method __start__ + + Open the socket listener\. + + - method __stop__ + + Shut off the socket listener, and destroy any pending replies\. + + - method __SubObject \{\} db__ + + - method __SubObject \{\} default__ + + - method __template__ *page* + + Return a template for the string *page* + + - method __TemplateSearch__ *page* + + Perform a search for the template that best matches *page*\. This can + include local file searches, in\-memory structures, or even database lookups\. + The stock implementation simply looks for files with a \.tml or \.html + extension in the ?doc\_root? directory\. + + - method __Thread\_start__ + + Built by the __[plugin](\.\./\.\./\.\./\.\./index\.md\#plugin)__ method\. + Called by the __start__ method\. Intended to allow plugins to spawn + worker threads\. + + - method __Uuid\_Generate__ + + Generate a GUUID\. Used to ensure every request has a unique ID\. The default + implementation is: + + return [::clay::uuid generate] + + - method __Validate\_Connection__ *sock* *ip* + + Given a socket and an ip address, return true if this connection should be + terminated, or false if it should be allowed to continue\. The stock + implementation always returns 0\. This is intended for applications to be + able to implement black lists and/or provide security based on IP address\. + +## Class httpd::server::dispatch + +*ancestors*: __httpd::server__ + +Provide a backward compadible alias + +## Class httpd::content\.redirect + +__Methods__ + + - method __reset__ + + - method __content__ + +## Class httpd::content\.cache + +__Methods__ + + - method __Dispatch__ + +## Class httpd::content\.template + +__Methods__ + + - method __content__ + +## Class httpd::content\.file + +Class to deliver Static content When utilized, this class is fed a local +filename by the dispatcher + +__Methods__ + + - method __FileName__ + + - method __DirectoryListing__ *local\_file* + + - method __content__ + + - method __Dispatch__ + +## Class httpd::content\.exec + +__Variable__ + + - variable __exename__ + +__Methods__ + + - method __CgiExec__ *execname* *script* *arglist* + + - method __Cgi\_Executable__ *script* + +## Class httpd::content\.proxy + +*ancestors*: __httpd::content\.exec__ + +Return data from an proxy process + +__Methods__ + + - method __proxy\_channel__ + + - method __proxy\_path__ + + - method __ProxyRequest__ *chana* *chanb* + + - method __ProxyReply__ *chana* *chanb* ?*args*? + + - method __Dispatch__ + +## Class httpd::content\.cgi + +*ancestors*: __httpd::content\.proxy__ + +__Methods__ + + - method __FileName__ + + - method __proxy\_channel__ + + - method __ProxyRequest__ *chana* *chanb* + + - method __ProxyReply__ *chana* *chanb* ?*args*? + + - method __DirectoryListing__ *local\_file* + + For most CGI applications a directory list is vorboten + +## Class httpd::protocol\.scgi + +Return data from an SCGI process + +__Methods__ + + - method __EncodeStatus__ *status* + +## Class httpd::content\.scgi + +*ancestors*: __httpd::content\.proxy__ + +__Methods__ + + - method __scgi\_info__ + + - method __proxy\_channel__ + + - method __ProxyRequest__ *chana* *chanb* + + - method __ProxyReply__ *chana* *chanb* ?*args*? + +## Class httpd::server\.scgi + +*ancestors*: __httpd::server__ + +Act as an SCGI Server + +__Methods__ + + - method __[debug](\.\./debug/debug\.md)__ ?*args*? + + - method __Connect__ *uuid* *sock* *ip* + +## Class httpd::content\.websocket + +Upgrade a connection to a websocket + +## Class httpd::plugin + +httpd plugin template + +## Class httpd::plugin\.dict\_dispatch + +A rudimentary plugin that dispatches URLs from a dict data structure + +__Methods__ + + - method __Dispatch\_Dict__ *data* + + Implementation of the dispatcher + + - method __uri \{\} add__ *vhosts* *patterns* *info* + + - method __uri \{\} direct__ *vhosts* *patterns* *info* *body* + +## Class httpd::reply\.memchan + +*ancestors*: __httpd::reply__ + +__Methods__ + + - method __output__ + + - method __DoOutput__ + + - method __close__ + +## Class httpd::plugin\.local\_memchan + +__Methods__ + + - method __local\_memchan__ *command* ?*args*? + + - method __Connect\_Local__ *uuid* *sock* ?*args*? + + A modified connection method that passes simple GET request to an object and + pulls data directly from the reply\_body data variable in the object Needed + because memchan is bidirectional, and we can't seem to communicate that the + server is one side of the link and the reply is another + +# AUTHORS Sean Woods -# Bugs, Ideas, Feedback +# Bugs, Ideas, Feedback This document, and the package it describes, will undoubtedly contain bugs and other problems\. Please report such in the category *network* of the [Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas for enhancements you may have for either package and/or documentation\. Index: embedded/md/tcllib/files/modules/imap4/imap4.md ================================================================== --- embedded/md/tcllib/files/modules/imap4/imap4.md +++ embedded/md/tcllib/files/modules/imap4/imap4.md @@ -33,15 +33,17 @@ - [Bugs, Ideas, Feedback](#section6) - [See Also](#seealso) - [Keywords](#keywords) + + - [Category](#category) # SYNOPSIS package require Tcl 8\.5 -package require imap4 ?0\.5\.2? +package require imap4 ?0\.5\.3? [__::imap4::open__ *hostname* ?*port*?](#1) [__::imap4::starttls__ *chan*](#2) [__::imap4::login__ *chan* *user* *pass*](#3) [__::imap4::folders__ *chan* ?*\-inline*? ?*mboxref*? ?*mboxname*?](#4) @@ -511,5 +513,9 @@ [email](\.\./\.\./\.\./\.\./index\.md\#email), [imap](\.\./\.\./\.\./\.\./index\.md\#imap), [internet](\.\./\.\./\.\./\.\./index\.md\#internet), [mail](\.\./\.\./\.\./\.\./index\.md\#mail), [net](\.\./\.\./\.\./\.\./index\.md\#net), [rfc3501](\.\./\.\./\.\./\.\./index\.md\#rfc3501), [ssl](\.\./\.\./\.\./\.\./index\.md\#ssl), [tls](\.\./\.\./\.\./\.\./index\.md\#tls) + +# CATEGORY + +Networking Index: embedded/md/tcllib/files/modules/jpeg/jpeg.md ================================================================== --- embedded/md/tcllib/files/modules/jpeg/jpeg.md +++ embedded/md/tcllib/files/modules/jpeg/jpeg.md @@ -1,13 +1,13 @@ [//000000001]: # (jpeg \- JPEG image manipulation) [//000000002]: # (Generated from file 'jpeg\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2004\-2005, Code: Aaron Faupell -Copyright © 2007, Code: Andreas Kupries -Copyright © 2004\-2009, Doc: Andreas Kupries -Copyright © 2011, Code: Pat Thoyts ) -[//000000004]: # (jpeg\(n\) 0\.5 tcllib "JPEG image manipulation") +[//000000003]: # (Copyright © 2004\-2005, Code: Aaron Faupell ) +[//000000004]: # (Copyright © 2007, Code: Andreas Kupries ) +[//000000005]: # (Copyright © 2004\-2009, Doc: Andreas Kupries ) +[//000000006]: # (Copyright © 2011, Code: Pat Thoyts ) +[//000000007]: # (jpeg\(n\) 0\.5 tcllib "JPEG image manipulation")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | [ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | -Copyright © 2004 Jochen Loewer -Copyright © 2006 Michael Schlenker ) -[//000000004]: # (ldap\(n\) 1\.9\.2 tcllib "LDAP client") +[//000000003]: # (Copyright © 2004 Andreas Kupries ) +[//000000004]: # (Copyright © 2004 Jochen Loewer ) +[//000000005]: # (Copyright © 2006 Michael Schlenker ) +[//000000006]: # (ldap\(n\) 1\.9\.2 tcllib "LDAP client")
[
Main Table Of Contents | Table Of Contents | Keyword Index | Categories | -Copyright © 2004 Arjen Markus ) -[//000000004]: # (math::bignum\(n\) 3\.1 tcllib "Tcl Math Library") +[//000000003]: # (Copyright © 2004 Salvatore Sanfilippo ) +[//000000004]: # (Copyright © 2004 Arjen Markus ) +[//000000005]: # (math::bignum\(n\) 3\.1 tcllib "Tcl Math Library")
[
Main Table Of Contents | Table Of Contents | Keyword Index | Categories | -Redistribution permitted under the terms of the Open Publication License ) -[//000000004]: # (math::exact\(n\) 1\.0\.1 tcllib "Tcl Math Library") +[//000000003]: # (Copyright © 2015 Kevin B\. Kenny ) +[//000000004]: # (Redistribution permitted under the terms of the Open Publication License ) +[//000000005]: # (math::exact\(n\) 1\.0\.1 tcllib "Tcl Math Library")
[
Main Table Of Contents | Table Of Contents | Keyword Index | Categories | -Copyright © 2004 Kevn B\. Kenny ) -[//000000004]: # (math::interpolate\(n\) 1\.1 tcllib "Tcl Math Library") +[//000000003]: # (Copyright © 2004 Arjen Markus ) +[//000000004]: # (Copyright © 2004 Kevn B\. Kenny ) +[//000000005]: # (math::interpolate\(n\) 1\.1 tcllib "Tcl Math Library")
[
Main Table Of Contents | Table Of Contents | Keyword Index | Categories | -Copyright © 2004 Ed Hume -Copyright © 2008 Michael Buadin ) -[//000000004]: # (math::linearalgebra\(n\) 1\.1\.5 tcllib "Tcl Math Library") +[//000000003]: # (Copyright © 2004\-2008 Arjen Markus ) +[//000000004]: # (Copyright © 2004 Ed Hume ) +[//000000005]: # (Copyright © 2008 Michael Buadin ) +[//000000006]: # (math::linearalgebra\(n\) 1\.1\.5 tcllib "Tcl Math Library")
[
Main Table Of Contents | Table Of Contents | Keyword Index | Categories | [ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | DESCRIPTION This package is for collecting various number\-theoretic operations, with a slight bias to prime numbers\. @@ -215,27 +216,40 @@ Estimate the number of primes according the formula by Gauss\. * integer *N* \(in\) - Number in question + Number in question, should be larger than 0 - __math::numtheory::numberPrimesLegendre__ *N* Estimate the number of primes according the formula by Legendre\. * integer *N* \(in\) - Number in question + Number in question, should be larger than 0 - __math::numtheory::numberPrimesLegendreModified__ *N* Estimate the number of primes according the modified formula by Legendre\. * integer *N* \(in\) - Number in question + Number in question, should be larger than 0 + + - __math::numtheory::differenceNumberPrimesLegendreModified__ *lower* *upper* + + Estimate the number of primes between tow limits according the modified + formula by Legendre\. + + * integer *lower* \(in\) + + Lower limit for the primes, should be larger than 0 + + * integer *upper* \(in\) + + Upper limit for the primes, should be larger than 0 # Bugs, Ideas, Feedback This document, and the package it describes, will undoubtedly contain bugs and other problems\. Please report such in the category *math :: numtheory* of the Index: embedded/md/tcllib/files/modules/math/optimize.md ================================================================== --- embedded/md/tcllib/files/modules/math/optimize.md +++ embedded/md/tcllib/files/modules/math/optimize.md @@ -1,11 +1,11 @@ [//000000001]: # (math::optimize \- Tcl Math Library) [//000000002]: # (Generated from file 'optimize\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2004 Arjen Markus -Copyright © 2004,2005 Kevn B\. Kenny ) -[//000000004]: # (math::optimize\(n\) 1\.0 tcllib "Tcl Math Library") +[//000000003]: # (Copyright © 2004 Arjen Markus ) +[//000000004]: # (Copyright © 2004,2005 Kevn B\. Kenny ) +[//000000005]: # (math::optimize\(n\) 1\.0 tcllib "Tcl Math Library")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | [ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | Modules | Applications ]
+ +# NAME + +math::quasirandom \- Quasi\-random points for integration and Monte Carlo type +methods + +# Table Of Contents + + - [Table Of Contents](#toc) + + - [Synopsis](#synopsis) + + - [Description](#section1) + + - [COMMANDS](#section2) + + - [TODO](#section3) + + - [References](#section4) + + - [Keywords](#keywords) + + - [Category](#category) + +# SYNOPSIS + +package require Tcl 8\.5 +package require TclOO +package require math::quasirandom 1 + +[__::math::quasirandom::qrpoint create__ *NAME* *DIM* ?ARGS?](#1) +[__gen next__](#2) +[__gen set\-start__ *index*](#3) +[__gen set\-evaluations__ *number*](#4) +[__gen integral__ *func* *minmax* *args*](#5) + +# DESCRIPTION + +In many applications pseudo\-random numbers and pseudo\-random points in a +\(limited\) sample space play an important role\. For instance in any type of Monte +Carlo simulation\. Pseudo\-random numbers, however, may be too random and as a +consequence a large number of data points is required to reduce the error or +fluctuation in the results to the desired value\. + +Quasi\-random numbers can be used as an alternative: instead of "completely" +arbitrary points, points are generated that are diverse enough to cover the +entire sample space in a more or less uniform way\. As a consequence convergence +to the limit can be much faster, when such quasi\-random numbers are well\-chosen\. + +The package defines a *[class](\.\./\.\./\.\./\.\./index\.md\#class)* "qrpoint" that +creates a command to generate quasi\-random points in 1, 2 or more dimensions\. +The command can either generate separate points, so that they can be used in a +user\-defined algorithm or use these points to calculate integrals of functions +defined over 1, 2 or more dimensions\. It also holds several other common +algorithms\. \(NOTE: these are not implemented yet\) + +One particular characteristic of the generators is that there are no tuning +parameters involved, which makes the use particularly simple\. + +# COMMANDS + +A quasi\-random point generator is created using the *qrpoint* class: + + - __::math::quasirandom::qrpoint create__ *NAME* *DIM* ?ARGS? + + This command takes the following arguments: + + * string *NAME* + + The name of the command to be created \(alternatively: the *new* + subcommand will generate a unique name\) + + * integer/string *DIM* + + The number of dimensions or one of: "circle", "disk", "sphere" or "ball" + + * strings *ARGS* + + Zero or more key\-value pairs\. The supported options are: + + + *\-start index*: The index for the next point to be generated + \(default: 1\) + + + *\-evaluations number*: The number of evaluations to be used by + default \(default: 100\) + +The points that are returned lie in the hyperblock \[0,1\[^n \(n the number of +dimensions\) or on the unit circle, within the unit disk, on the unit sphere or +within the unit ball\. + +Each generator supports the following subcommands: + + - __gen next__ + + Return the coordinates of the next quasi\-random point + + - __gen set\-start__ *index* + + Reset the index for the next quasi\-random point\. This is useful to control + which list of points is returned\. Returns the new or the current value, if + no value is given\. + + - __gen set\-evaluations__ *number* + + Reset the default number of evaluations in compound algorithms\. Note that + the actual number is the smallest 4\-fold larger or equal to the given + number\. \(The 4\-fold plays a role in the detailed integration routine\.\) + + - __gen integral__ *func* *minmax* *args* + + Calculate the integral of the given function over the block \(or the circle, + sphere etc\.\) + + * string *func* + + The name of the function to be integrated + + * list *minmax* + + List of pairs of minimum and maximum coordinates\. This can be used to + map the quasi\-random coordinates to the desired hyper\-block\. + + If the space is a circle, disk etc\. then this argument should be a + single value, the radius\. The circle, disk, etc\. is centred at the + origin\. If this is not what is required, then a coordinate + transformation should be made within the function\. + + * strings *args* + + Zero or more key\-value pairs\. The following options are supported: + + + *\-evaluations number*: The number of evaluations to be used\. If + not specified use the default of the generator object\. + +# TODO + +Implement other algorithms and variants + +Implement more unit tests\. + +Comparison to pseudo\-random numbers for integration\. + +# References + +Various algorithms exist for generating quasi\-random numbers\. The generators +created in this package are based on: +[http://extremelearning\.com\.au/unreasonable\-effectiveness\-of\-quasirandom\-sequences/](http://extremelearning\.com\.au/unreasonable\-effectiveness\-of\-quasirandom\-sequences/) + +# KEYWORDS + +[mathematics](\.\./\.\./\.\./\.\./index\.md\#mathematics), +[quasi\-random](\.\./\.\./\.\./\.\./index\.md\#quasi\_random) + +# CATEGORY + +Mathematics Index: embedded/md/tcllib/files/modules/math/symdiff.md ================================================================== --- embedded/md/tcllib/files/modules/math/symdiff.md +++ embedded/md/tcllib/files/modules/math/symdiff.md @@ -1,11 +1,11 @@ [//000000001]: # (math::calculus::symdiff \- Symbolic differentiation for Tcl) [//000000002]: # (Generated from file 'symdiff\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2010 by Kevin B\. Kenny -Redistribution permitted under the terms of the Open Publication License ) -[//000000004]: # (math::calculus::symdiff\(n\) 1\.0\.1 tcllib "Symbolic differentiation for Tcl") +[//000000003]: # (Copyright © 2010 by Kevin B\. Kenny ) +[//000000004]: # (Redistribution permitted under the terms of the Open Publication License ) +[//000000005]: # (math::calculus::symdiff\(n\) 1\.0\.1 tcllib "Symbolic differentiation for Tcl")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | [ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS package require Tcl 8\.5 -package require mime ?1\.6? +package require mime ?1\.6\.1? [__::mime::initialize__ ?__\-canonical__ *type/subtype* ?__\-param__ \{*key value*\}\.\.\.? ?__\-encoding__ *value*? ?__\-header__ \{*key value*\}\.\.\.?? \(__\-file__ *name* | __\-string__ *value* | __\-parts__ \{*token1* \.\.\. *tokenN*\}\)](#1) [__::mime::finalize__ *token* ?__\-subordinates__ __all__ | __dynamic__ | __none__?](#2) [__::mime::getproperty__ *token* ?*property* | __\-names__?](#3) [__::mime::getheader__ *token* ?*key* | __\-names__?](#4) Index: embedded/md/tcllib/files/modules/mime/smtp.md ================================================================== --- embedded/md/tcllib/files/modules/mime/smtp.md +++ embedded/md/tcllib/files/modules/mime/smtp.md @@ -181,19 +181,19 @@ proc send_simple_message {recipient email_server subject body} { package require smtp package require mime - set token [mime::initialize -canonical text/plain \\ + set token [mime::initialize -canonical text/plain \ -string $body] mime::setheader $token Subject $subject - smtp::sendmessage $token \\ + smtp::sendmessage $token \ -recipients $recipient -servers $email_server mime::finalize $token } - send_simple_message someone@somewhere.com localhost \\ + send_simple_message someone@somewhere.com localhost \ "This is the subject." "This is the message." # TLS Security Considerations This package uses the __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ package to Index: embedded/md/tcllib/files/modules/namespacex/namespacex.md ================================================================== --- embedded/md/tcllib/files/modules/namespacex/namespacex.md +++ embedded/md/tcllib/files/modules/namespacex/namespacex.md @@ -1,12 +1,12 @@ [//000000001]: # (namespacex \- Namespace utility commands) [//000000002]: # (Generated from file 'namespacex\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 200? Neil Madden \(http://wiki\.tcl\.tk/12790\) -Copyright © 200? Various \(http://wiki\.tcl\.tk/1489\) -Copyright © 2010 Documentation, Andreas Kupries) -[//000000004]: # (namespacex\(n\) 0\.2 tcllib "Namespace utility commands") +[//000000003]: # (Copyright © 200? Neil Madden \(http://wiki\.tcl\.tk/12790\)) +[//000000004]: # (Copyright © 200? Various \(http://wiki\.tcl\.tk/1489\)) +[//000000005]: # (Copyright © 2010 Documentation, Andreas Kupries) +[//000000006]: # (namespacex\(n\) 0\.2 tcllib "Namespace utility commands")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | ) -[//000000004]: # (oauth\(n\) 1\.0\.2 tcllib "oauth") +[//000000004]: # (oauth\(n\) 1\.0\.3 tcllib "oauth")
[
Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS package require Tcl 8\.5 -package require oauth ?1\.0\.2? +package require oauth ?1\.0\.3? [__::oauth::config__](#1) [__::oauth::config__ ?*options*\.\.\.?](#2) [__::oauth::header__ *baseURL* ?*postQuery*?](#3) [__::oauth::query__ *baseURL* ?*postQuery*?](#4) Index: embedded/md/tcllib/files/modules/pki/pki.md ================================================================== --- embedded/md/tcllib/files/modules/pki/pki.md +++ embedded/md/tcllib/files/modules/pki/pki.md @@ -203,10 +203,14 @@ be children of this CA in a depth\-wise fashion\. A value of "0" for the *caDepth* argument means that this CA cannot sign a CA certificate and have the result be valid\. A value of "\-1" indicates infinite depth\. # EXAMPLES + + + + # REFERENCES # AUTHORS Index: embedded/md/tcllib/files/modules/png/png.md ================================================================== --- embedded/md/tcllib/files/modules/png/png.md +++ embedded/md/tcllib/files/modules/png/png.md @@ -1,11 +1,11 @@ [//000000001]: # (png \- Image manipulation) [//000000002]: # (Generated from file 'png\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2004, Code: Aaron Faupell -Copyright © 2004, Doc: Andreas Kupries ) -[//000000004]: # (png\(n\) 0\.3 tcllib "Image manipulation") +[//000000003]: # (Copyright © 2004, Code: Aaron Faupell ) +[//000000004]: # (Copyright © 2004, Doc: Andreas Kupries ) +[//000000005]: # (png\(n\) 0\.3 tcllib "Image manipulation")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | Bugs, Ideas, Feedback Index: embedded/md/tcllib/files/modules/pop3d/pop3d.md ================================================================== --- embedded/md/tcllib/files/modules/pop3d/pop3d.md +++ embedded/md/tcllib/files/modules/pop3d/pop3d.md @@ -1,11 +1,11 @@ [//000000001]: # (pop3d \- Tcl POP3 Server Package) [//000000002]: # (Generated from file 'pop3d\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2002\-2009 Andreas Kupries -Copyright © 2005 Reinhard Max ) -[//000000004]: # (pop3d\(n\) 1\.1\.0 tcllib "Tcl POP3 Server Package") +[//000000003]: # (Copyright © 2002\-2009 Andreas Kupries ) +[//000000004]: # (Copyright © 2005 Reinhard Max ) +[//000000005]: # (pop3d\(n\) 1\.1\.0 tcllib "Tcl POP3 Server Package")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | ) -[//000000004]: # (practcl\(n\) 0\.11 tcllib "The The Proper Rational API for C to Tool Command Language Module") +[//000000004]: # (practcl\(n\) 0\.16\.3 tcllib "The The Proper Rational API for C to Tool Command Language Module")
[
Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS package require TclOO 1\.0 -package require practcl 0\.11 - -[__CPUTS__ *varname* *body* ?*body*\.\.\.?](#1) -[__practcl::\_isdirectory__ *path*](#2) -[__practcl::object__ *parent* ?*keyvaluelist*?](#3) -[__practcl::library__ ?*keyvaluelist*?](#4) -[__practcl::exe__ ?*keyvaluelist*?](#5) -[__practcl::product__ *parent* ?*keyvaluelist*?](#6) -[__practcl::cheader__ *parent* ?*keyvaluelist*?](#7) -[__practcl::csource__ *parent* ?*keyvaluelist*?](#8) -[__practcl::module__ *parent* ?*keyvaluelist*?](#9) -[__practcl::submodule__ *parent* ?*keyvaluelist*?](#10) + +[proc __practcl::cat__ *fname*](#1) +[proc __practcl::docstrip__ *text*](#2) +[proc __putb__ ?*map*? *text*](#3) +[proc __[Proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ *name* *arglist* *body*](#4) +[proc __noop__ ?*args*?](#5) +[proc __practcl::debug__ ?*args*?](#6) +[proc __practcl::doexec__ ?*args*?](#7) +[proc __practcl::doexec\_in__ *path* ?*args*?](#8) +[proc __practcl::dotclexec__ ?*args*?](#9) +[proc __practcl::domake__ *path* ?*args*?](#10) +[proc __practcl::domake\.tcl__ *path* ?*args*?](#11) +[proc __practcl::fossil__ *path* ?*args*?](#12) +[proc __practcl::fossil\_status__ *dir*](#13) +[proc __practcl::os__](#14) +[proc __practcl::mkzip__ *exename* *barekit* *vfspath*](#15) +[proc __practcl::sort\_dict__ *list*](#16) +[proc __practcl::local\_os__](#17) +[proc __practcl::config\.tcl__ *path*](#18) +[proc __practcl::read\_configuration__ *path*](#19) +[proc __practcl::tcllib\_require__ *pkg* ?*args*?](#20) +[proc __practcl::platform::tcl\_core\_options__ *os*](#21) +[proc __practcl::platform::tk\_core\_options__ *os*](#22) +[proc __practcl::read\_rc\_file__ *filename* ?*localdat* ____?](#23) +[proc __practcl::read\_sh\_subst__ *line* *info*](#24) +[proc __practcl::read\_sh\_file__ *filename* ?*localdat* ____?](#25) +[proc __practcl::read\_Config\.sh__ *filename*](#26) +[proc __practcl::read\_Makefile__ *filename*](#27) +[proc __practcl::cputs__ *varname* ?*args*?](#28) +[proc __practcl::tcl\_to\_c__ *body*](#29) +[proc __practcl::\_tagblock__ *text* ?*style* __tcl__? ?*note* ____?](#30) +[proc __practcl::de\_shell__ *data*](#31) +[proc __practcl::grep__ *pattern* ?*files* ____?](#32) +[proc __practcl::file\_lexnormalize__ *sp*](#33) +[proc __practcl::file\_relative__ *base* *dst*](#34) +[proc __practcl::findByPattern__ *basedir* *patterns*](#35) +[proc __practcl::log__ *fname* *comment*](#36) +[proc __practcl::\_pkgindex\_simpleIndex__ *path*](#37) +[proc __practcl::\_pkgindex\_directory__ *path*](#38) +[proc __practcl::\_pkgindex\_path\_subdir__ *path*](#39) +[proc __practcl::pkgindex\_path__ ?*args*?](#40) +[proc __practcl::installDir__ *d1* *d2*](#41) +[proc __practcl::copyDir__ *d1* *d2* ?*toplevel* __1__?](#42) +[proc __practcl::buildModule__ *modpath*](#43) +[proc __practcl::installModule__ *modpath* *DEST*](#44) +[proc __practcl::trigger__ ?*args*?](#45) +[proc __practcl::depends__ ?*args*?](#46) +[proc __practcl::target__ *name* *info* ?*action* ____?](#47) +[method __constructor__](#48) +[method __argspec__ *argspec*](#49) +[method __[comment](\.\./\.\./\.\./\.\./index\.md\#comment)__ *block*](#50) +[method __keyword\.Annotation__ *resultvar* *commentblock* *type* *name* *body*](#51) +[method __keyword\.Class__ *resultvar* *commentblock* *name* *body*](#52) +[method __keyword\.class__ *resultvar* *commentblock* *name* *body*](#53) +[method __keyword\.Class\_Method__ *resultvar* *commentblock* *name* ?*args*?](#54) +[method __keyword\.method__ *resultvar* *commentblock* *name* ?*args*?](#55) +[method __keyword\.proc__ *commentblock* *name* *argspec*](#56) +[method __reset__](#57) +[method __Main__](#58) +[method __section\.method__ *keyword* *method* *minfo*](#59) +[method __section\.annotation__ *type* *name* *iinfo*](#60) +[method __section\.class__ *class\_name* *class\_info*](#61) +[method __section\.command__ *procinfo*](#62) +[method __[manpage](\.\./\.\./\.\./\.\./index\.md\#manpage)__ ?__header *value*__? ?__footer *value*__? ?__authors *list*__?](#63) +[method __scan\_text__ *text*](#64) +[method __scan\_file__ *filename*](#65) +[method __\_MorphPatterns__](#66) +[method __[define](\.\./\.\./\.\./\.\./index\.md\#define)__ *submethod* ?*args*?](#67) +[method __graft__ ?*args*?](#68) +[method __initialize__](#69) +[method __link__ *command* ?*args*?](#70) +[method __morph__ *classname*](#71) +[method __script__ *script*](#72) +[method __select__](#73) +[method __[source](\.\./\.\./\.\./\.\./index\.md\#source)__ *filename*](#74) +[classmethod __select__ *object*](#75) +[method __config\.sh__](#76) +[method __BuildDir__ *PWD*](#77) +[method __MakeDir__ *srcdir*](#78) +[method __read\_configuration__](#79) +[method __build\-cflags__ *PROJECT* *DEFS* *namevar* *versionvar* *defsvar*](#80) +[method __critcl__ ?*args*?](#81) +[method __Autoconf__](#82) +[method __BuildDir__ *PWD*](#83) +[method __ConfigureOpts__](#84) +[method __MakeDir__ *srcdir*](#85) +[method __make \{\} autodetect__](#86) +[method __make \{\} clean__](#87) +[method __make \{\} compile__](#88) +[method __make \{\} install__ *DEST*](#89) +[method __build\-compile\-sources__ *PROJECT* *COMPILE* *CPPCOMPILE* *INCLUDES*](#90) +[method __build\-Makefile__ *path* *PROJECT*](#91) +[method __build\-library__ *outfile* *PROJECT*](#92) +[method __build\-tclsh__ *outfile* *PROJECT* ?*path* __auto__?](#93) +[method __BuildDir__ *PWD*](#94) +[method __make \{\} autodetect__](#95) +[method __make \{\} clean__](#96) +[method __make \{\} compile__](#97) +[method __make \{\} install__ *DEST*](#98) +[method __MakeDir__ *srcdir*](#99) +[method __NmakeOpts__](#100) +[method __constructor__ *module\_object* *name* *info* ?*action\_body* ____?](#101) +[method __[do](\.\./\.\./\.\./\.\./index\.md\#do)__](#102) +[method __check__](#103) +[method __output__](#104) +[method __reset__](#105) +[method __triggers__](#106) +[method __constructor__ *parent* ?*args*?](#107) +[method __child__ *method*](#108) +[method __go__](#109) +[method __cstructure__ *name* *definition* ?*argdat* ____?](#110) +[method __include__ *header*](#111) +[method __include\_dir__ ?*args*?](#112) +[method __include\_directory__ ?*args*?](#113) +[method __c\_header__ *body*](#114) +[method __c\_code__ *body*](#115) +[method __c\_function__ *header* *body* ?*info* ____?](#116) +[method __c\_tcloomethod__ *name* *body* ?*arginfo* ____?](#117) +[method __cmethod__ *name* *body* ?*arginfo* ____?](#118) +[method __c\_tclproc\_nspace__ *nspace*](#119) +[method __c\_tclcmd__ *name* *body* ?*arginfo* ____?](#120) +[method __c\_tclproc\_raw__ *name* *body* ?*arginfo* ____?](#121) +[method __tcltype__ *name* *argdat*](#122) +[method __project\-compile\-products__](#123) +[method __implement__ *path*](#124) +[method __initialize__](#125) +[method __linktype__](#126) +[method __generate\-cfile\-constant__](#127) +[method __generate\-cfile\-header__](#128) +[method __generate\-cfile\-tclapi__](#129) +[method __generate\-loader\-module__](#130) +[method __Collate\_Source__ *CWD*](#131) +[method __select__](#132) +[classmethod __select__ *object*](#133) +[method __code__ *section* *body*](#134) +[method __Collate\_Source__ *CWD*](#135) +[method __project\-compile\-products__](#136) +[method __generate\-debug__ ?*spaces* ____?](#137) +[method __generate\-cfile\-constant__](#138) +[method __generate\-cfile\-public\-structure__](#139) +[method __generate\-cfile\-header__](#140) +[method __generate\-cfile\-global__](#141) +[method __generate\-cfile\-private\-typedef__](#142) +[method __generate\-cfile\-private\-structure__](#143) +[method __generate\-cfile\-functions__](#144) +[method __generate\-cfile\-tclapi__](#145) +[method __generate\-hfile\-public\-define__](#146) +[method __generate\-hfile\-public\-macro__](#147) +[method __generate\-hfile\-public\-typedef__](#148) +[method __generate\-hfile\-public\-structure__](#149) +[method __generate\-hfile\-public\-headers__](#150) +[method __generate\-hfile\-public\-function__](#151) +[method __generate\-hfile\-public\-includes__](#152) +[method __generate\-hfile\-public\-verbatim__](#153) +[method __generate\-loader\-external__](#154) +[method __generate\-loader\-module__](#155) +[method __generate\-stub\-function__](#156) +[method __IncludeAdd__ *headervar* ?*args*?](#157) +[method __generate\-tcl\-loader__](#158) +[method __generate\-tcl\-pre__](#159) +[method __generate\-tcl\-post__](#160) +[method __linktype__](#161) +[method __Ofile__ *filename*](#162) +[method __project\-static\-packages__](#163) +[method __toolset\-include\-directory__](#164) +[method __target__ *method* ?*args*?](#165) +[method __project\-compile\-products__](#166) +[method __generate\-loader\-module__](#167) +[method __project\-compile\-products__](#168) +[method __linker\-products__ *configdict*](#169) +[method __initialize__](#170) +[variable __make\_object__](#171) +[method __\_MorphPatterns__](#172) +[method __add__ ?*args*?](#173) +[method __install\-headers__ ?*args*?](#174) +[method __make \{\} \_preamble__](#175) +[method __make \{\} pkginfo__](#176) +[method __make \{\} objects__](#177) +[method __make \{\} object__ *name*](#178) +[method __make \{\} reset__](#179) +[method __make \{\} trigger__ ?*args*?](#180) +[method __make \{\} depends__ ?*args*?](#181) +[method __make \{\} filename__ *name*](#182) +[method __make \{\} target__ *name* *Info* *body*](#183) +[method __make \{\} todo__](#184) +[method __make \{\} do__](#185) +[method __child__ *which*](#186) +[method __generate\-c__](#187) +[method __generate\-h__](#188) +[method __generate\-loader__](#189) +[method __initialize__](#190) +[method __implement__ *path*](#191) +[method __linktype__](#192) +[method __\_MorphPatterns__](#193) +[method __constructor__ ?*args*?](#194) +[method __add\_object__ *object*](#195) +[method __add\_project__ *pkg* *info* ?*oodefine* ____?](#196) +[method __add\_tool__ *pkg* *info* ?*oodefine* ____?](#197) +[method __build\-tclcore__](#198) +[method __child__ *which*](#199) +[method __linktype__](#200) +[method __project__ *pkg* ?*args*?](#201) +[method __tclcore__](#202) +[method __tkcore__](#203) +[method __[tool](\.\./tool/tool\.md)__ *pkg* ?*args*?](#204) +[method __clean__ *PATH*](#205) +[method __project\-compile\-products__](#206) +[method __go__](#207) +[method __generate\-decls__ *pkgname* *path*](#208) +[method __implement__ *path*](#209) +[method __generate\-make__ *path*](#210) +[method __linktype__](#211) +[method __package\-ifneeded__ ?*args*?](#212) +[method __shared\_library__ ?*filename* ____?](#213) +[method __static\_library__ ?*filename* ____?](#214) +[method __build\-tclkit\_main__ *PROJECT* *PKG\_OBJS*](#215) +[method __Collate\_Source__ *CWD*](#216) +[method __wrap__ *PWD* *exename* *vfspath* ?*args*?](#217) +[classmethod __Sandbox__ *object*](#218) +[classmethod __select__ *object*](#219) +[classmethod __claim\_option__](#220) +[classmethod __claim\_object__ *object*](#221) +[classmethod __claim\_path__ *path*](#222) +[method __scm\_info__](#223) +[method __DistroMixIn__](#224) +[method __Sandbox__](#225) +[method __SrcDir__](#226) +[method __ScmTag__](#227) +[method __ScmClone__](#228) +[method __ScmUnpack__](#229) +[method __ScmUpdate__](#230) +[method __Unpack__](#231) +[classmethod __claim\_object__ *object*](#232) +[classmethod __claim\_option__](#233) +[classmethod __claim\_path__ *path*](#234) +[method __ScmUnpack__](#235) +[classmethod __claim\_object__ *obj*](#236) +[classmethod __claim\_option__](#237) +[classmethod __claim\_path__ *path*](#238) +[method __scm\_info__](#239) +[method __ScmClone__](#240) +[method __ScmTag__](#241) +[method __ScmUnpack__](#242) +[method __ScmUpdate__](#243) +[classmethod __claim\_object__ *obj*](#244) +[classmethod __claim\_option__](#245) +[classmethod __claim\_path__ *path*](#246) +[method __ScmTag__](#247) +[method __ScmUnpack__](#248) +[method __ScmUpdate__](#249) +[method __\_MorphPatterns__](#250) +[method __BuildDir__ *PWD*](#251) +[method __child__ *which*](#252) +[method __compile__](#253) +[method __go__](#254) +[method __install__ ?*args*?](#255) +[method __linktype__](#256) +[method __linker\-products__ *configdict*](#257) +[method __linker\-external__ *configdict*](#258) +[method __linker\-extra__ *configdict*](#259) +[method __env\-bootstrap__](#260) +[method __env\-exec__](#261) +[method __env\-install__](#262) +[method __env\-load__](#263) +[method __env\-present__](#264) +[method __sources__](#265) +[method __[update](\.\./\.\./\.\./\.\./index\.md\#update)__](#266) +[method __unpack__](#267) +[method __env\-bootstrap__](#268) +[method __env\-present__](#269) +[method __linktype__](#270) +[method __env\-bootstrap__](#271) +[method __env\-install__](#272) +[method __env\-present__](#273) +[method __install__ *DEST*](#274) +[method __kettle__ *path* ?*args*?](#275) +[method __install__ *DEST*](#276) +[method __install__ *DEST*](#277) +[method __env\-bootstrap__](#278) +[method __env\-install__](#279) +[method __env\-present__](#280) +[method __install__ *DEST*](#281) +[method __install\-module__ *DEST* ?*args*?](#282) +[method __env\-bootstrap__](#283) +[method __env\-install__](#284) +[method __install__ *DEST*](#285) +[method __install\-module__ *DEST* ?*args*?](#286) +[method __clean__](#287) +[method __env\-install__](#288) +[method __project\-compile\-products__](#289) +[method __ComputeInstall__](#290) +[method __go__](#291) +[method __linker\-products__ *configdict*](#292) +[method __project\-static\-packages__](#293) +[method __BuildDir__ *PWD*](#294) +[method __compile__](#295) +[method __Configure__](#296) +[method __install__ *DEST*](#297) +[method __install__ *DEST*](#298) +[method __install__ *DEST*](#299) +[method __env\-bootstrap__](#300) +[method __env\-present__](#301) +[method __env\-install__](#302) +[method __go__](#303) +[method __linktype__](#304) # DESCRIPTION The Practcl module is a tool for integrating large modules for C API Tcl code that requires custom Tcl types and TclOO objects\. -# COMMANDS - - - __CPUTS__ *varname* *body* ?*body*\.\.\.? - - Appends blocks of text to a buffer\. This command tries to reduce the number - of line breaks between bodies\. - - - __practcl::\_isdirectory__ *path* - - Returns true if *path* is a directory, using the test - - - __practcl::object__ *parent* ?*keyvaluelist*? - - A generic Practcl object - - - __practcl::library__ ?*keyvaluelist*? - - A Practcl object representing a library container - - - __practcl::exe__ ?*keyvaluelist*? - - A Practcl object representing a wrapped executable - - - __practcl::product__ *parent* ?*keyvaluelist*? - - A Practcl object representing a compiled product - - - __practcl::cheader__ *parent* ?*keyvaluelist*? - - A Practcl object representing an externally generated c header - - - __practcl::csource__ *parent* ?*keyvaluelist*? - - A Practcl object representing an externally generated c source file - - - __practcl::module__ *parent* ?*keyvaluelist*? - - A Practcl object representing a dynamically generated C/H/Tcl suite - - - __practcl::submodule__ *parent* ?*keyvaluelist*? - - A Practcl object representing a dynamically generated C/H/Tcl suite, - subordinate to a module - -# Bugs, Ideas, Feedback +The concept with Practcl is that is a single file package that can assist any +tcl based project with distribution, compilation, linking, VFS preparation, +executable assembly, and installation\. Practcl also allows one project to invoke +the build system from another project, allowing complex projects such as a +statically linked basekit to be assembled with relative ease\. + +Practcl ships as a single file, and aside from a Tcl 8\.6 interpreter, has no +external dependencies\. + +Making a practcl project + +# Commands + + - proc __practcl::cat__ *fname* + + Concatenate a file + + - proc __practcl::docstrip__ *text* + + Strip the global comments from tcl code\. Used to prevent the documentation + markup comments from clogging up files intended for distribution in machine + readable format\. + + - proc __putb__ ?*map*? *text* + + Append a line of text to a variable\. Optionally apply a string mapping\. + + - proc __[Proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ *name* *arglist* *body* + + Generate a proc if no command already exists by that name + + - proc __noop__ ?*args*? + + A command to do nothing\. A handy way of negating an instruction without + having to comment it completely out\. It's also a handy attachment point for + an object to be named later + + - proc __practcl::debug__ ?*args*? + + - proc __practcl::doexec__ ?*args*? + + Drop in a static copy of Tcl + + - proc __practcl::doexec\_in__ *path* ?*args*? + + - proc __practcl::dotclexec__ ?*args*? + + - proc __practcl::domake__ *path* ?*args*? + + - proc __practcl::domake\.tcl__ *path* ?*args*? + + - proc __practcl::fossil__ *path* ?*args*? + + - proc __practcl::fossil\_status__ *dir* + + - proc __practcl::os__ + + - proc __practcl::mkzip__ *exename* *barekit* *vfspath* + + Build a zipfile\. On tcl8\.6 this invokes the native Zip implementation on + older interpreters this invokes zip via exec + + - proc __practcl::sort\_dict__ *list* + + Dictionary sort a key/value list\. Needed because pre tcl8\.6 does not have + *lsort \-stride 2* + + - proc __practcl::local\_os__ + + - proc __practcl::config\.tcl__ *path* + + Detect local platform + + - proc __practcl::read\_configuration__ *path* + + - proc __practcl::tcllib\_require__ *pkg* ?*args*? + + Try to load a package, and failing that retrieve tcllib + + - proc __practcl::platform::tcl\_core\_options__ *os* + + - proc __practcl::platform::tk\_core\_options__ *os* + + - proc __practcl::read\_rc\_file__ *filename* ?*localdat* ____? + + Read a stylized key/value list stored in a file + + - proc __practcl::read\_sh\_subst__ *line* *info* + + Converts a XXX\.sh file into a series of Tcl variables + + - proc __practcl::read\_sh\_file__ *filename* ?*localdat* ____? + + - proc __practcl::read\_Config\.sh__ *filename* + + A simpler form of read\_sh\_file tailored to pulling data from + \(tcl|tk\)Config\.sh + + - proc __practcl::read\_Makefile__ *filename* + + A simpler form of read\_sh\_file tailored to pulling data from a Makefile + + - proc __practcl::cputs__ *varname* ?*args*? + + Append arguments to a buffer The command works like puts in that each call + will also insert a line feed\. Unlike puts, blank links in the interstitial + are suppressed + + - proc __practcl::tcl\_to\_c__ *body* + + - proc __practcl::\_tagblock__ *text* ?*style* __tcl__? ?*note* ____? + + - proc __practcl::de\_shell__ *data* + + - proc __practcl::grep__ *pattern* ?*files* ____? + + Search for the pattern *pattern* amongst $files + + - proc __practcl::file\_lexnormalize__ *sp* + + - proc __practcl::file\_relative__ *base* *dst* + + Calculate a relative path between base and dst + + Example: + + ::practcl::file_relative ~/build/tcl/unix ~/build/tcl/library + > ../library + + - proc __practcl::findByPattern__ *basedir* *patterns* + + - proc __practcl::log__ *fname* *comment* + + Record an event in the practcl log + + - proc __practcl::\_pkgindex\_simpleIndex__ *path* + + - proc __practcl::\_pkgindex\_directory__ *path* + + Return true if the pkgindex file contains any statement other than "package + ifneeded" and/or if any package ifneeded loads a DLL + + - proc __practcl::\_pkgindex\_path\_subdir__ *path* + + Helper function for ::practcl::pkgindex\_path + + - proc __practcl::pkgindex\_path__ ?*args*? + + Index all paths given as though they will end up in the same virtual file + system + + - proc __practcl::installDir__ *d1* *d2* + + Delete the contents of *d2*, and then recusively Ccopy the contents of + *d1* to *d2*\. + + - proc __practcl::copyDir__ *d1* *d2* ?*toplevel* __1__? + + Recursively copy the contents of *d1* to *d2* + + - proc __practcl::buildModule__ *modpath* + + - proc __practcl::installModule__ *modpath* *DEST* + + - proc __practcl::trigger__ ?*args*? + + Trigger build targets, and recompute dependencies + + Internals: + + ::practcl::LOCAL make trigger {*}$args + foreach {name obj} [::practcl::LOCAL make objects] { + set ::make($name) [$obj do] + } + + - proc __practcl::depends__ ?*args*? + + Calculate if a dependency for any of the arguments needs to be fulfilled or + rebuilt\. + + Internals: + + ::practcl::LOCAL make depends {*}$args + + - proc __practcl::target__ *name* *info* ?*action* ____? + + Declare a build product\. This proc is just a shorthand for + *::practcl::LOCAL make task $name $info $action* + + Registering a build product with this command will create an entry in the + global array, and populate a value in the global array\. + + Internals: + + set obj [::practcl::LOCAL make task $name $info $action] + set ::make($name) 0 + set filename [$obj define get filename] + if {$filename ne {}} { + set ::target($name) $filename + } + +# Classes + +## Class practcl::doctool + + { set authors { + {John Doe} {jdoe@illustrious.edu} + {Tom RichardHarry} {tomdickharry@illustrius.edu} + } + # Create the object + ::practcl::doctool create AutoDoc + set fout [open [file join $moddir module.tcl] w] + foreach file [glob [file join $srcdir *.tcl]] { + set content [::practcl::cat [file join $srcdir $file]] + # Scan the file + AutoDoc scan_text $content + # Strip the comments from the distribution + puts $fout [::practcl::docstrip $content] + } + # Write out the manual page + set manout [open [file join $moddir module.man] w] + dict set args header [string map $modmap [::practcl::cat [file join $srcdir manual.txt]]] + dict set args footer [string map $modmap [::practcl::cat [file join $srcdir footer.txt]]] + dict set args authors $authors + puts $manout [AutoDoc manpage {*}$args] + close $manout + + + } + +Tool for build scripts to dynamically generate manual files from comments in +source code files + +__Methods__ + + - method __constructor__ + + - method __argspec__ *argspec* + + Process an argument list into an informational dict\. This method also + understands non\-positional arguments expressed in the notation of Tip 471 + [https://core\.tcl\-lang\.org/tips/doc/trunk/tip/479\.md](https://core\.tcl\-lang\.org/tips/doc/trunk/tip/479\.md)\. + + The output will be a dictionary of all of the fields and whether the fields + are __positional__, __mandatory__, and whether they have a + __default__ value\. + + Example: + + my argspec {a b {c 10}} + + > a {positional 1 mandatory 1} b {positional 1 mandatory 1} c {positional 1 mandatory 0 default 10} + + - method __[comment](\.\./\.\./\.\./\.\./index\.md\#comment)__ *block* + + Convert a block of comments into an informational dictionary\. If lines in + the comment start with a single word ending in a colon, all subsequent lines + are appended to a dictionary field of that name\. If no fields are given, all + of the text is appended to the __description__ field\. + + Example: + + my comment {Does something cool} + > description {Does something cool} + + my comment { + title : Something really cool + author : Sean Woods + author : John Doe + description : + This does something really cool! + } + > description {This does something really cool!} + title {Something really cool} + author {Sean Woods + John Doe} + + - method __keyword\.Annotation__ *resultvar* *commentblock* *type* *name* *body* + + - method __keyword\.Class__ *resultvar* *commentblock* *name* *body* + + Process an oo::objdefine call that modifies the class object itself + + - method __keyword\.class__ *resultvar* *commentblock* *name* *body* + + Process an oo::define, clay::define, etc statement\. + + - method __keyword\.Class\_Method__ *resultvar* *commentblock* *name* ?*args*? + + Process a statement for a clay style class method + + - method __keyword\.method__ *resultvar* *commentblock* *name* ?*args*? + + Process a statement for a tcloo style object method + + - method __keyword\.proc__ *commentblock* *name* *argspec* + + Process a proc statement + + - method __reset__ + + Reset the state of the object and its embedded coroutine + + - method __Main__ + + Main body of the embedded coroutine for the object + + - method __section\.method__ *keyword* *method* *minfo* + + Generate the manual page text for a method or proc + + - method __section\.annotation__ *type* *name* *iinfo* + + - method __section\.class__ *class\_name* *class\_info* + + Generate the manual page text for a class + + - method __section\.command__ *procinfo* + + Generate the manual page text for the commands section + + - method __[manpage](\.\./\.\./\.\./\.\./index\.md\#manpage)__ ?__header *value*__? ?__footer *value*__? ?__authors *list*__? + + Generate the manual page\. Returns the completed text suitable for saving in + \.man file\. The header argument is a block of doctools text to go in before + the machine generated section\. footer is a block of doctools text to go in + after the machine generated section\. authors is a list of individual authors + and emails in the form of AUTHOR EMAIL ?AUTHOR EMAIL?\.\.\. + + - method __scan\_text__ *text* + + Scan a block of text + + - method __scan\_file__ *filename* + + Scan a file of text + +## Class practcl::metaclass + +The metaclass for all practcl objects + +__Methods__ + + - method __\_MorphPatterns__ + + - method __[define](\.\./\.\./\.\./\.\./index\.md\#define)__ *submethod* ?*args*? + + - method __graft__ ?*args*? + + - method __initialize__ + + - method __link__ *command* ?*args*? + + - method __morph__ *classname* + + - method __script__ *script* + + - method __select__ + + - method __[source](\.\./\.\./\.\./\.\./index\.md\#source)__ *filename* + +## Class practcl::toolset + +Ancestor\-less class intended to be a mixin which defines a family of build +related behaviors that are modified when targetting either gcc or msvc + +__Class Methods__ + + - classmethod __select__ *object* + + Perform the selection for the toolset mixin + +__Methods__ + + - method __config\.sh__ + + find or fake a key/value list describing this project + + - method __BuildDir__ *PWD* + + Compute the location where the product will be built + + - method __MakeDir__ *srcdir* + + Return where the Makefile is located relative to *srcdir*\. For this + implementation the MakeDir is always srcdir\. + + - method __read\_configuration__ + + Read information about the build process for this package\. For this + implementation, data is sought in the following locations in the following + order: config\.tcl \(generated by practcl\.\) PKGConfig\.sh\. The Makefile + + If the Makefile needs to be consulted, but does not exist, the Configure + method is invoked + + - method __build\-cflags__ *PROJECT* *DEFS* *namevar* *versionvar* *defsvar* + + method DEFS This method populates 4 variables: name \- The name of the + package version \- The version of the package defs \- C flags passed to the + compiler includedir \- A list of paths to feed to the compiler for finding + headers + + - method __critcl__ ?*args*? + + Invoke critcl in an external process + +## Class practcl::toolset\.gcc + +*ancestors*: __practcl::toolset__ + +__Methods__ + + - method __Autoconf__ + + - method __BuildDir__ *PWD* + + - method __ConfigureOpts__ + + - method __MakeDir__ *srcdir* + + Detect what directory contains the Makefile template + + - method __make \{\} autodetect__ + + - method __make \{\} clean__ + + - method __make \{\} compile__ + + - method __make \{\} install__ *DEST* + + - method __build\-compile\-sources__ *PROJECT* *COMPILE* *CPPCOMPILE* *INCLUDES* + + - method __build\-Makefile__ *path* *PROJECT* + + - method __build\-library__ *outfile* *PROJECT* + + Produce a static or dynamic library + + - method __build\-tclsh__ *outfile* *PROJECT* ?*path* __auto__? + + Produce a static executable + +## Class practcl::toolset\.msvc + +*ancestors*: __practcl::toolset__ + +__Methods__ + + - method __BuildDir__ *PWD* + + MSVC always builds in the source directory + + - method __make \{\} autodetect__ + + Do nothing + + - method __make \{\} clean__ + + - method __make \{\} compile__ + + - method __make \{\} install__ *DEST* + + - method __MakeDir__ *srcdir* + + Detect what directory contains the Makefile template + + - method __NmakeOpts__ + +## Class practcl::make\_obj + +*ancestors*: __practcl::metaclass__ + +A build deliverable object\. Normally an object file, header, or tcl script which +must be compiled or generated in some way + +__Methods__ + + - method __constructor__ *module\_object* *name* *info* ?*action\_body* ____? + + - method __[do](\.\./\.\./\.\./\.\./index\.md\#do)__ + + - method __check__ + + - method __output__ + + - method __reset__ + + - method __triggers__ + +## Class practcl::object + +*ancestors*: __practcl::metaclass__ + +A generic Practcl object + +__Methods__ + + - method __constructor__ *parent* ?*args*? + + - method __child__ *method* + + - method __go__ + +## Class practcl::dynamic + +Dynamic blocks do not generate their own \.c files, instead the contribute to the +amalgamation of the main library file + +__Methods__ + + - method __cstructure__ *name* *definition* ?*argdat* ____? + + Parser functions + + - method __include__ *header* + + - method __include\_dir__ ?*args*? + + - method __include\_directory__ ?*args*? + + - method __c\_header__ *body* + + - method __c\_code__ *body* + + - method __c\_function__ *header* *body* ?*info* ____? + + - method __c\_tcloomethod__ *name* *body* ?*arginfo* ____? + + - method __cmethod__ *name* *body* ?*arginfo* ____? + + Alias to classic name + + - method __c\_tclproc\_nspace__ *nspace* + + - method __c\_tclcmd__ *name* *body* ?*arginfo* ____? + + - method __c\_tclproc\_raw__ *name* *body* ?*arginfo* ____? + + Alias to classic name + + - method __tcltype__ *name* *argdat* + + - method __project\-compile\-products__ + + Module interactions + + - method __implement__ *path* + + - method __initialize__ + + Practcl internals + + - method __linktype__ + + - method __generate\-cfile\-constant__ + + - method __generate\-cfile\-header__ + + - method __generate\-cfile\-tclapi__ + + Generate code that provides implements Tcl API calls + + - method __generate\-loader\-module__ + + Generate code that runs when the package/module is initialized into the + interpreter + + - method __Collate\_Source__ *CWD* + + - method __select__ + + Once an object marks itself as some flavor of dynamic, stop trying to morph + it into something else + +## Class practcl::product + +A deliverable for the build system + +__Class Methods__ + + - classmethod __select__ *object* + +__Methods__ + + - method __code__ *section* *body* + + - method __Collate\_Source__ *CWD* + + - method __project\-compile\-products__ + + - method __generate\-debug__ ?*spaces* ____? + + - method __generate\-cfile\-constant__ + + - method __generate\-cfile\-public\-structure__ + + Populate const static data structures + + - method __generate\-cfile\-header__ + + - method __generate\-cfile\-global__ + + - method __generate\-cfile\-private\-typedef__ + + - method __generate\-cfile\-private\-structure__ + + - method __generate\-cfile\-functions__ + + Generate code that provides subroutines called by Tcl API methods + + - method __generate\-cfile\-tclapi__ + + Generate code that provides implements Tcl API calls + + - method __generate\-hfile\-public\-define__ + + - method __generate\-hfile\-public\-macro__ + + - method __generate\-hfile\-public\-typedef__ + + - method __generate\-hfile\-public\-structure__ + + - method __generate\-hfile\-public\-headers__ + + - method __generate\-hfile\-public\-function__ + + - method __generate\-hfile\-public\-includes__ + + - method __generate\-hfile\-public\-verbatim__ + + - method __generate\-loader\-external__ + + - method __generate\-loader\-module__ + + - method __generate\-stub\-function__ + + - method __IncludeAdd__ *headervar* ?*args*? + + - method __generate\-tcl\-loader__ + + - method __generate\-tcl\-pre__ + + This methods generates any Tcl script file which is required to + pre\-initialize the C library + + - method __generate\-tcl\-post__ + + - method __linktype__ + + - method __Ofile__ *filename* + + - method __project\-static\-packages__ + + Methods called by the master project + + - method __toolset\-include\-directory__ + + Methods called by the toolset + + - method __target__ *method* ?*args*? + +## Class practcl::product\.cheader + +*ancestors*: __practcl::product__ + +A product which generated from a C header file\. Which is to say, nothing\. + +__Methods__ + + - method __project\-compile\-products__ + + - method __generate\-loader\-module__ + +## Class practcl::product\.csource + +*ancestors*: __practcl::product__ + +A product which generated from a C source file\. Normally an object \(\.o\) file\. + +__Methods__ + + - method __project\-compile\-products__ + +## Class practcl::product\.clibrary + +*ancestors*: __practcl::product__ + +A product which is generated from a compiled C library\. Usually a \.a or a \.dylib +file, but in complex cases may actually just be a conduit for one project to +integrate the source code of another + +__Methods__ + + - method __linker\-products__ *configdict* + +## Class practcl::product\.dynamic + +*ancestors*: __practcl::dynamic__ __practcl::product__ + +A product which is generated from C code that itself is generated by practcl or +some other means\. This C file may or may not produce its own \.o file, depending +on whether it is eligible to become part of an amalgamation + +__Methods__ + + - method __initialize__ + +## Class practcl::product\.critcl + +*ancestors*: __practcl::dynamic__ __practcl::product__ + +A binary product produced by critcl\. Note: The implementation is not written +yet, this class does nothing\. + +## Class practcl::module + +*ancestors*: __practcl::object__ __practcl::product\.dynamic__ + +In the end, all C code must be loaded into a module This will either be a +dynamically loaded library implementing a tcl extension, or a compiled in +segment of a custom shell/app + +__Variable__ + + - variable __make\_object__ + +__Methods__ + + - method __\_MorphPatterns__ + + - method __add__ ?*args*? + + - method __install\-headers__ ?*args*? + + - method __make \{\} \_preamble__ + + - method __make \{\} pkginfo__ + + - method __make \{\} objects__ + + Return a dictionary of all handles and associated objects + + - method __make \{\} object__ *name* + + Return the object associated with handle *name* + + - method __make \{\} reset__ + + Reset all deputy objects + + - method __make \{\} trigger__ ?*args*? + + Exercise the triggers method for all handles listed + + - method __make \{\} depends__ ?*args*? + + Exercise the check method for all handles listed + + - method __make \{\} filename__ *name* + + Return the file name of the build product for the listed handle + + - method __make \{\} target__ *name* *Info* *body* + + - method __make \{\} todo__ + + Return a list of handles for object which return true for the do method + + - method __make \{\} do__ + + For each target exercise the action specified in the *action* definition + if the *do* method returns true + + - method __child__ *which* + + - method __generate\-c__ + + This methods generates the contents of an amalgamated \.c file which + implements the loader for a batch of tools + + - method __generate\-h__ + + This methods generates the contents of an amalgamated \.h file which + describes the public API of this module + + - method __generate\-loader__ + + - method __initialize__ + + - method __implement__ *path* + + - method __linktype__ + +## Class practcl::project + +*ancestors*: __practcl::module__ + +A toplevel project that is a collection of other projects + +__Methods__ + + - method __\_MorphPatterns__ + + - method __constructor__ ?*args*? + + - method __add\_object__ *object* + + - method __add\_project__ *pkg* *info* ?*oodefine* ____? + + - method __add\_tool__ *pkg* *info* ?*oodefine* ____? + + - method __build\-tclcore__ + + Compile the Tcl core\. If the define *tk* is true, compile the Tk core as + well + + - method __child__ *which* + + - method __linktype__ + + - method __project__ *pkg* ?*args*? + + Exercise the methods of a sub\-object + + - method __tclcore__ + + - method __tkcore__ + + - method __[tool](\.\./tool/tool\.md)__ *pkg* ?*args*? + +## Class practcl::library + +*ancestors*: __practcl::project__ + +A toplevel project that produces a library + +__Methods__ + + - method __clean__ *PATH* + + - method __project\-compile\-products__ + + - method __go__ + + - method __generate\-decls__ *pkgname* *path* + + - method __implement__ *path* + + - method __generate\-make__ *path* + + Backward compadible call + + - method __linktype__ + + - method __package\-ifneeded__ ?*args*? + + Create a "package ifneeded" Args are a list of aliases for which this + package will answer to + + - method __shared\_library__ ?*filename* ____? + + - method __static\_library__ ?*filename* ____? + +## Class practcl::tclkit + +*ancestors*: __practcl::library__ + +A toplevel project that produces a self\-contained executable + +__Methods__ + + - method __build\-tclkit\_main__ *PROJECT* *PKG\_OBJS* + + - method __Collate\_Source__ *CWD* + + - method __wrap__ *PWD* *exename* *vfspath* ?*args*? + + Wrap an executable + +## Class practcl::distribution + +Standalone class to manage code distribution This class is intended to be mixed +into another class \(Thus the lack of ancestors\) + +__Class Methods__ + + - classmethod __Sandbox__ *object* + + - classmethod __select__ *object* + + - classmethod __claim\_option__ + + - classmethod __claim\_object__ *object* + + - classmethod __claim\_path__ *path* + +__Methods__ + + - method __scm\_info__ + + - method __DistroMixIn__ + + - method __Sandbox__ + + - method __SrcDir__ + + - method __ScmTag__ + + - method __ScmClone__ + + - method __ScmUnpack__ + + - method __ScmUpdate__ + + - method __Unpack__ + +## Class practcl::distribution\.snapshot + +*ancestors*: __practcl::distribution__ + +A file distribution from zip, tarball, or other non\-scm archive format + +__Class Methods__ + + - classmethod __claim\_object__ *object* + + - classmethod __claim\_option__ + + - classmethod __claim\_path__ *path* + +__Methods__ + + - method __ScmUnpack__ + +## Class practcl::distribution\.fossil + +*ancestors*: __practcl::distribution__ + +A file distribution based on fossil + +__Class Methods__ + + - classmethod __claim\_object__ *obj* + + Check for markers in the metadata + + - classmethod __claim\_option__ + + - classmethod __claim\_path__ *path* + + Check for markers in the source root + +__Methods__ + + - method __scm\_info__ + + - method __ScmClone__ + + Clone the source + + - method __ScmTag__ + + - method __ScmUnpack__ + + - method __ScmUpdate__ + +## Class practcl::distribution\.git + +*ancestors*: __practcl::distribution__ + +A file distribution based on git + +__Class Methods__ + + - classmethod __claim\_object__ *obj* + + - classmethod __claim\_option__ + + - classmethod __claim\_path__ *path* + +__Methods__ + + - method __ScmTag__ + + - method __ScmUnpack__ + + - method __ScmUpdate__ + +## Class practcl::subproject + +*ancestors*: __practcl::module__ + +A subordinate project + +__Methods__ + + - method __\_MorphPatterns__ + + - method __BuildDir__ *PWD* + + - method __child__ *which* + + - method __compile__ + + - method __go__ + + - method __install__ ?*args*? + + Install project into the local build system + + - method __linktype__ + + - method __linker\-products__ *configdict* + + - method __linker\-external__ *configdict* + + - method __linker\-extra__ *configdict* + + - method __env\-bootstrap__ + + Methods for packages/tools that can be downloaded possibly built and used + internally by this Practcl process Load the facility into the interpreter + + - method __env\-exec__ + + Return a file path that exec can call + + - method __env\-install__ + + Install the tool into the local environment + + - method __env\-load__ + + Do whatever is necessary to get the tool into the local environment + + - method __env\-present__ + + Check if tool is available for load/already loaded + + - method __sources__ + + - method __[update](\.\./\.\./\.\./\.\./index\.md\#update)__ + + - method __unpack__ + +## Class practcl::subproject\.source + +*ancestors*: __practcl::subproject__ __practcl::library__ + +A project which the kit compiles and integrates the source for itself + +__Methods__ + + - method __env\-bootstrap__ + + - method __env\-present__ + + - method __linktype__ + +## Class practcl::subproject\.teapot + +*ancestors*: __practcl::subproject__ + +a copy from the teapot + +__Methods__ + + - method __env\-bootstrap__ + + - method __env\-install__ + + - method __env\-present__ + + - method __install__ *DEST* + +## Class practcl::subproject\.kettle + +*ancestors*: __practcl::subproject__ + +__Methods__ + + - method __kettle__ *path* ?*args*? + + - method __install__ *DEST* + +## Class practcl::subproject\.critcl + +*ancestors*: __practcl::subproject__ + +__Methods__ + + - method __install__ *DEST* + +## Class practcl::subproject\.sak + +*ancestors*: __practcl::subproject__ + +__Methods__ + + - method __env\-bootstrap__ + + - method __env\-install__ + + - method __env\-present__ + + - method __install__ *DEST* + + - method __install\-module__ *DEST* ?*args*? + +## Class practcl::subproject\.practcl + +*ancestors*: __practcl::subproject__ + +__Methods__ + + - method __env\-bootstrap__ + + - method __env\-install__ + + - method __install__ *DEST* + + - method __install\-module__ *DEST* ?*args*? + +## Class practcl::subproject\.binary + +*ancestors*: __practcl::subproject__ + +A subordinate binary package + +__Methods__ + + - method __clean__ + + - method __env\-install__ + + - method __project\-compile\-products__ + + - method __ComputeInstall__ + + - method __go__ + + - method __linker\-products__ *configdict* + + - method __project\-static\-packages__ + + - method __BuildDir__ *PWD* + + - method __compile__ + + - method __Configure__ + + - method __install__ *DEST* + +## Class practcl::subproject\.tea + +*ancestors*: __practcl::subproject\.binary__ + +A subordinate TEA based binary package + +## Class practcl::subproject\.library + +*ancestors*: __practcl::subproject\.binary__ __practcl::library__ + +A subordinate C library built by this project + +__Methods__ + + - method __install__ *DEST* + +## Class practcl::subproject\.external + +*ancestors*: __practcl::subproject\.binary__ + +A subordinate external C library + +__Methods__ + + - method __install__ *DEST* + +## Class practcl::subproject\.core + +*ancestors*: __practcl::subproject\.binary__ + +__Methods__ + + - method __env\-bootstrap__ + + - method __env\-present__ + + - method __env\-install__ + + - method __go__ + + - method __linktype__ + +# Bugs, Ideas, Feedback This document, and the package it describes, will undoubtedly contain bugs and other problems\. Please report such in the category *practcl* of the [Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas for enhancements you may have for either package and/or documentation\. Index: embedded/md/tcllib/files/modules/pt/pt_peg_container.md ================================================================== --- embedded/md/tcllib/files/modules/pt/pt_peg_container.md +++ embedded/md/tcllib/files/modules/pt/pt_peg_container.md @@ -189,21 +189,21 @@ overwriting the existing definition\. This is the assignment operator for grammars\. This operation is in effect equivalent to - *objectName* __deserialize =__ [*source* __serialize__] + > *objectName* __deserialize =__ \[*source* __serialize__\] - *objectName* __\-\->__ *destination* This method assigns our contents to the PEG object *destination*, overwriting the existing definition\. This is the reverse assignment operator for grammars\. This operation is in effect equivalent to - *destination* __deserialize =__ [*objectName* __serialize__] + > *destination* __deserialize =__ \[*objectName* __serialize__\] - *objectName* __serialize__ ?*format*? This method returns our grammar in some textual form usable for transfer, persistent storage, etc\. If no *format* is not specified the returned Index: embedded/md/tcllib/files/modules/pt/pt_peg_export.md ================================================================== --- embedded/md/tcllib/files/modules/pt/pt_peg_export.md +++ embedded/md/tcllib/files/modules/pt/pt_peg_export.md @@ -1,10 +1,10 @@ [//000000001]: # (pt::peg::export \- Parser Tools) [//000000002]: # (Generated from file 'pt\_peg\_export\.man' by tcllib/doctools with format 'markdown') [//000000003]: # (Copyright © 2009 Andreas Kupries ) -[//000000004]: # (pt::peg::export\(n\) 1 tcllib "Parser Tools") +[//000000004]: # (pt::peg::export\(n\) 1\.0\.1 tcllib "Parser Tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS package require Tcl 8\.5 package require snit -package require configuration +package require struct::map package require pt::peg package require pluginmgr -package require pt::peg::export ?1? +package require pt::peg::export ?1\.0\.1? [__::pt::peg::export__ *objectName*](#1) [__objectName__ __method__ ?*arg arg \.\.\.*?](#2) [*objectName* __destroy__](#3) [*objectName* __export serial__ *serial* ?*format*?](#4) Index: embedded/md/tcllib/files/modules/pt/pt_peg_import.md ================================================================== --- embedded/md/tcllib/files/modules/pt/pt_peg_import.md +++ embedded/md/tcllib/files/modules/pt/pt_peg_import.md @@ -1,10 +1,10 @@ [//000000001]: # (pt::peg::import \- Parser Tools) [//000000002]: # (Generated from file 'pt\_peg\_import\.man' by tcllib/doctools with format 'markdown') [//000000003]: # (Copyright © 2009 Andreas Kupries ) -[//000000004]: # (pt::peg::import\(n\) 1 tcllib "Parser Tools") +[//000000004]: # (pt::peg::import\(n\) 1\.0\.1 tcllib "Parser Tools")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS package require Tcl 8\.5 +package require Tcl 8\.5 package require snit -package require configuration +package require fileutil::paths package require pt::peg package require pluginmgr -package require pt::peg::import ?1? +package require pt::peg::import ?1\.0\.1? [__::pt::peg::import__ *objectName*](#1) [__objectName__ __method__ ?*arg arg \.\.\.*?](#2) [*objectName* __destroy__](#3) [*objectName* __import text__ *text* ?*format*?](#4) Index: embedded/md/tcllib/files/modules/pt/pt_peg_to_tclparam.md ================================================================== --- embedded/md/tcllib/files/modules/pt/pt_peg_to_tclparam.md +++ embedded/md/tcllib/files/modules/pt/pt_peg_to_tclparam.md @@ -248,11 +248,12 @@ Generated parsers are classes based on the __[snit](\.\./snit/snit\.md)__ package, i\.e\. snit::type's\. - __[pt::tclparam::configuration::tcloo](pt\_tclparam\_config\_tcloo\.md)__ - Generated parsers are classes based on the __OO__ package\. + Generated parsers are classes based on the + __[OO](\.\./\.\./\.\./\.\./index\.md\#oo)__ package\. # Tcl/PARAM code representation of parsing expression grammars The Tcl/PARAM representation of parsing expression grammars is Tcl code whose execution will parse input per the grammar\. The code is based on the virtual Index: embedded/md/tcllib/files/modules/pt/pt_tclparam_config_tcloo.md ================================================================== --- embedded/md/tcllib/files/modules/pt/pt_tclparam_config_tcloo.md +++ embedded/md/tcllib/files/modules/pt/pt_tclparam_config_tcloo.md @@ -50,11 +50,11 @@ This package is an adjunct to __[pt::peg::to::tclparam](pt\_peg\_to\_tclparam\.md)__, to make the use of this highly configurable package easier by providing a canned configuration\. When applied this configuration causes the package __[pt::peg::to::tclparam](pt\_peg\_to\_tclparam\.md)__ to generate -__OO__\-based parser packages\. +__[OO](\.\./\.\./\.\./\.\./index\.md\#oo)__\-based parser packages\. It is a supporting package in the Core Layer of Parser Tools\. ![](\.\./\.\./\.\./\.\./image/arch\_core\_support\.png) @@ -61,12 +61,13 @@ # API - __::pt::tclparam::configuration::tcloo__ __def__ *name* *pkg* *version* *cmdprefix* The command applies the configuration provided by this package to the - *cmdprefix*, causing the creation of __OO__\-based parsers whose class - is *name*, in package *pkg* with *version*\. + *cmdprefix*, causing the creation of + __[OO](\.\./\.\./\.\./\.\./index\.md\#oo)__\-based parsers whose class is + *name*, in package *pkg* with *version*\. The use of a command prefix as API allows application of the configuration to not only __[pt::peg::to::tclparam](pt\_peg\_to\_tclparam\.md)__ \(__pt::peg::to::tclparam configure__\), but also export manager instances and PEG containers \(__$export configuration set__ and __\[$container Index: embedded/md/tcllib/files/modules/rcs/rcs.md ================================================================== --- embedded/md/tcllib/files/modules/rcs/rcs.md +++ embedded/md/tcllib/files/modules/rcs/rcs.md @@ -1,11 +1,11 @@ [//000000001]: # (rcs \- RCS low level utilities) [//000000002]: # (Generated from file 'rcs\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2005, Andreas Kupries -Copyright © 2005, Colin McCormack ) -[//000000004]: # (rcs\(n\) 2\.0\.2 tcllib "RCS low level utilities") +[//000000003]: # (Copyright © 2005, Andreas Kupries ) +[//000000004]: # (Copyright © 2005, Colin McCormack ) +[//000000005]: # (rcs\(n\) 2\.0\.2 tcllib "RCS low level utilities")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | ) -[//000000004]: # (sha1\(n\) 2\.0\.3 tcllib "SHA\-x Message\-Digest Algorithm") +[//000000004]: # (sha1\(n\) 2\.0\.4 tcllib "SHA\-x Message\-Digest Algorithm")
[
Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS package require Tcl 8\.2 -package require sha1 ?2\.0\.3? +package require sha1 ?2\.0\.4? [__::sha1::sha1__ ?__\-hex|\-bin__? \[ __\-channel channel__ | __\-file filename__ | ?__\-\-__? *string* \]](#1) [__::sha1::hmac__ *key* *string*](#2) [__::sha1::hmac__ ?__\-hex|\-bin__? __\-key key__ \[ __\-channel channel__ | __\-file filename__ | ?__\-\-__? *string* \]](#3) [__::sha1::SHA1Init__](#4) Index: embedded/md/tcllib/files/modules/sha1/sha256.md ================================================================== --- embedded/md/tcllib/files/modules/sha1/sha256.md +++ embedded/md/tcllib/files/modules/sha1/sha256.md @@ -1,10 +1,10 @@ [//000000001]: # (sha256 \- SHA\-x Message\-Digest Algorithm) [//000000002]: # (Generated from file 'sha256\.man' by tcllib/doctools with format 'markdown') [//000000003]: # (Copyright © 2008, Andreas Kupries ) -[//000000004]: # (sha256\(n\) 1\.0\.3 tcllib "SHA\-x Message\-Digest Algorithm") +[//000000004]: # (sha256\(n\) 1\.0\.4 tcllib "SHA\-x Message\-Digest Algorithm")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS package require Tcl 8\.2 -package require sha256 ?1\.0\.3? +package require sha256 ?1\.0\.4? [__::sha2::sha256__ ?__\-hex|\-bin__? \[ __\-channel channel__ | __\-file filename__ | ?__\-\-__? *string* \]](#1) [__::sha2::sha224__ ?__\-hex|\-bin__? \[ __\-channel channel__ | __\-file filename__ | ?__\-\-__? *string* \]](#2) [__::sha2::hmac__ *key* *string*](#3) [__::sha2::hmac__ ?__\-hex|\-bin__? __\-key key__ \[ __\-channel channel__ | __\-file filename__ | ?__\-\-__? *string* \]](#4) Index: embedded/md/tcllib/files/modules/soundex/soundex.md ================================================================== --- embedded/md/tcllib/files/modules/soundex/soundex.md +++ embedded/md/tcllib/files/modules/soundex/soundex.md @@ -1,12 +1,12 @@ [//000000001]: # (soundex \- Soundex) [//000000002]: # (Generated from file 'soundex\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © ????, Algorithm: Donald E\. Knuth -Copyright © 2003, Documentation: Andreas Kupries -Copyright © 1998, Tcl port: Evan Rempel ) -[//000000004]: # (soundex\(n\) 1\.0 tcllib "Soundex") +[//000000003]: # (Copyright © ????, Algorithm: Donald E\. Knuth) +[//000000004]: # (Copyright © 2003, Documentation: Andreas Kupries ) +[//000000005]: # (Copyright © 1998, Tcl port: Evan Rempel ) +[//000000006]: # (soundex\(n\) 1\.0 tcllib "Soundex")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | ) -[//000000004]: # (struct::graph\(n\) 2\.4\.1 tcllib "Tcl Data Structures") +[//000000003]: # (Copyright © 2002\-2009,2019 Andreas Kupries ) +[//000000004]: # (struct::graph\(n\) 2\.4\.2 tcllib "Tcl Data Structures")
[
Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS package require Tcl 8\.4 -package require struct::graph ?2\.4\.1? +package require struct::graph ?2\.4\.2? package require struct::list ?1\.5? package require struct::set ?2\.2\.3? [__::struct::graph__ ?*graphName*? ?__=__|__:=__|__as__|__deserialize__ *source*?](#1) [__graphName__ *option* ?*arg arg \.\.\.*?](#2) @@ -196,11 +196,11 @@ *graphName*\. The old contents of *graphName* are deleted by this operation\. This operation is in effect equivalent to - *graphName* __deserialize__ [*sourcegraph* __serialize__] + > *graphName* __deserialize__ \[*sourcegraph* __serialize__\] The operation assumes that the *sourcegraph* provides the method __serialize__ and that this method returns a valid graph serialization\. - *graphName* __\-\->__ *destgraph* @@ -210,11 +210,11 @@ object *destgraph*\. The old contents of *destgraph* are deleted by this operation\. This operation is in effect equivalent to - *destgraph* __deserialize__ [*graphName* __serialize__] + > *destgraph* __deserialize__ \[*graphName* __serialize__\] The operation assumes that the *destgraph* provides the method __deserialize__ and that this method takes a graph serialization\. - *graphName* __append__ *key* *value* @@ -405,12 +405,12 @@ associated with the arc, or both\. A general filter command can be used as well\. The restrictions that involve connected nodes take a variable number of nodes as argument, specified after the name of the restriction itself\. The restrictions imposed by either __\-in__, __\-out__, __\-adj__, - __\-inner__, or __\-embedded__ are applied first\. Specifying more than - one of them is illegal\. + __\-inner__, or __\-embedding__ are applied first\. Specifying more + than one of them is illegal\. After that the restrictions set via __\-key__ \(and __\-value__\) are applied\. Specifying more than one __\-key__ \(and __\-value__\) is illegal\. Specifying __\-value__ alone, without __\-key__ is illegal as well\. @@ -448,10 +448,18 @@ * __\-embedding__ Return a list of all arcs adjacent to exactly one of the nodes in the set\. This is the set of arcs connecting the subgraph spawned by the specified nodes to the rest of the graph\. + + *Attention*: After the above options any word with a leading dash which is + not a valid option is treated as a node name instead of an invalid option to + error out on\. This condition holds until either a valid option terminates + the list of nodes, or the end of the command is reached, whichever comes + first\. + + The remaining filter options are: * __\-key__ *key* Limit the list of arcs that are returned to those arcs that have an associated key *key*\. @@ -590,13 +598,16 @@ returned nodes based on neighboring nodes, or based on the keyed values associated with the node\. The restrictions that involve neighboring nodes have a list of nodes as argument, specified after the name of the restriction itself\. - The possible restrictions are the same as for method __arcs__\. The exact - meanings change slightly, as they operate on nodes instead of arcs\. The - command recognizes: + The possible restrictions are the same as for method __arcs__\. Note that + while the exact meanings change slightly, as they operate on nodes instead + of arcs, the general behaviour is the same, especially when it comes to the + handling of words with a leading dash in node lists\. + + The command recognizes: * __\-in__ Return a list of all nodes with at least one outgoing arc ending in a node found in the specified set of nodes\. Alternatively specified as the @@ -729,14 +740,14 @@ has the order of the arcs per node\. # A possible serialization for the graph structure # # d -----> %2 - # / ^ \\ - # / / \\ - # / b \\ - # / / \\ + # / ^ \ + # / / \ + # / b \ + # / / \ # %1 <- a - %0 e # ^ \\ / # \\ c / # \\ \\ / # \\ v v @@ -869,6 +880,6 @@ Data structures # COPYRIGHT -Copyright © 2002\-2009 Andreas Kupries +Copyright © 2002\-2009,2019 Andreas Kupries Index: embedded/md/tcllib/files/modules/struct/graphops.md ================================================================== --- embedded/md/tcllib/files/modules/struct/graphops.md +++ embedded/md/tcllib/files/modules/struct/graphops.md @@ -1,12 +1,12 @@ [//000000001]: # (struct::graph::op \- Tcl Data Structures) [//000000002]: # (Generated from file 'graphops\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2008 Alejandro Paz -Copyright © 2008 \(docs\) Andreas Kupries -Copyright © 2009 Michal Antoniewski ) -[//000000004]: # (struct::graph::op\(n\) 0\.11\.3 tcllib "Tcl Data Structures") +[//000000003]: # (Copyright © 2008 Alejandro Paz ) +[//000000004]: # (Copyright © 2008 \(docs\) Andreas Kupries ) +[//000000005]: # (Copyright © 2009 Michal Antoniewski ) +[//000000006]: # (struct::graph::op\(n\) 0\.11\.3 tcllib "Tcl Data Structures")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | *matrixName* __deserialize__ \[*sourcematrix* __serialize__\] - *matrixName* __\-\->__ *destmatrix* This is the reverse assignment operator for matrix objects\. It copies the matrix contained in the matrix object *matrixName* over the matrix data in @@ -160,11 +160,11 @@ the object *destmatrix*\. The old contents of *destmatrix* are deleted by this operation\. This operation is in effect equivalent to - *destmatrix* __deserialize__ [*matrixName* __serialize__] + > *destmatrix* __deserialize__ \[*matrixName* __serialize__\] - *matrixName* __add column__ ?*values*? Extends the matrix by one column and then acts like __set column__ \(see below\) on this new column if there were *values* supplied\. Without Index: embedded/md/tcllib/files/modules/struct/struct_list.md ================================================================== --- embedded/md/tcllib/files/modules/struct/struct_list.md +++ embedded/md/tcllib/files/modules/struct/struct_list.md @@ -1,11 +1,11 @@ [//000000001]: # (struct::list \- Tcl Data Structures) [//000000002]: # (Generated from file 'struct\_list\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2003\-2005 by Kevin B\. Kenny\. All rights reserved -Copyright © 2003\-2012 Andreas Kupries ) -[//000000004]: # (struct::list\(n\) 1\.8\.4 tcllib "Tcl Data Structures") +[//000000003]: # (Copyright © 2003\-2005 by Kevin B\. Kenny\. All rights reserved) +[//000000004]: # (Copyright © 2003\-2012 Andreas Kupries ) +[//000000005]: # (struct::list\(n\) 1\.8\.4 tcllib "Tcl Data Structures")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | [ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | Modules | Applications ]
+ +# NAME + +struct::map \- Manage key/value maps + +# Table Of Contents + + - [Table Of Contents](#toc) + + - [Synopsis](#synopsis) + + - [Description](#section1) + + - [API](#section2) + + - [Bugs, Ideas, Feedback](#section3) + +# SYNOPSIS + +package require struct::map ?1? + +[__::struct::map__ *mapName*](#1) +[__mapName__ __method__ ?*arg arg \.\.\.*?](#2) +[*mapName* __get__](#3) +[*mapName* __names__](#4) +[*mapName* __set__ *name* ?*value*?](#5) +[*mapName* __unset__ ?*pattern*\.\.\.?](#6) + +# DESCRIPTION + +Provides a snit class whose instances manage a key/value map\. In other words, an +object wrapper around Tcl arrays\. + +# API + +The main command provides construction of maps: + + - __::struct::map__ *mapName* + + Creates a new, empty map with an associated global Tcl command whose name is + *mapName*\. It may be used to invoke various operations on the map\. It has + the following general form: + + * __mapName__ __method__ ?*arg arg \.\.\.*? + + __method__ and *arg*uments determine the exact behavior of the + command\. + + If *mapName* is specified as __%AUTO%__ a unique name will be + generated by the package itself\. The result of the command is the + fully\-qualified name of the instance command\. + +The following commands are possible for map objects: + + - *mapName* __get__ + + Returns the entire map as a Tcl dictionary\. + + - *mapName* __names__ + + Returns the list of all keys known to the map, in arbitrary order\. + + - *mapName* __set__ *name* ?*value*? + + Sets key *name* to the specified *value*, if the value specified\. + Returns the value for the key\. Throws an error if the key is not known\. + + - *mapName* __unset__ ?*pattern*\.\.\.? + + Removes all keys matching at least one of the glob *pattern*s from the + map\. If no pattern is specified all keys are removed\. In other words, the + default pattern is __\*__\. The result of the command is the empty string\. + +# Bugs, Ideas, Feedback + +This document, and the package it describes, will undoubtedly contain bugs and +other problems\. Please report such in the category *struct :: list* of the +[Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. 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\. Index: embedded/md/tcllib/files/modules/struct/struct_tree.md ================================================================== --- embedded/md/tcllib/files/modules/struct/struct_tree.md +++ embedded/md/tcllib/files/modules/struct/struct_tree.md @@ -196,11 +196,11 @@ *treeName*\. The old contents of *treeName* are deleted by this operation\. This operation is in effect equivalent to - *treeName* __deserialize__ [*sourcetree* __serialize__] + > *treeName* __deserialize__ \[*sourcetree* __serialize__\] - *treeName* __\-\->__ *desttree* This is the reverse assignment operator for tree objects\. It copies the tree contained in the tree object *treeName* over the tree data in the object @@ -207,11 +207,11 @@ *desttree*\. The old contents of *desttree* are deleted by this operation\. This operation is in effect equivalent to - *desttree* __deserialize__ [*treeName* __serialize__] + > *desttree* __deserialize__ \[*treeName* __serialize__\] - *treeName* __ancestors__ *node* This method extends the method __parent__ and returns a list containing all ancestor nodes to the specified *node*\. The immediate ancestor, in Index: embedded/md/tcllib/files/modules/tepam/tepam_argument_dialogbox.md ================================================================== --- embedded/md/tcllib/files/modules/tepam/tepam_argument_dialogbox.md +++ embedded/md/tcllib/files/modules/tepam/tepam_argument_dialogbox.md @@ -79,33 +79,33 @@ __argument\_dialogbox__ returns __cancel__\. A small example illustrates how the __argument\_dialogbox__ can be employed: - set DialogResult [__tepam::argument_dialogbox__ \ - __-title__ "Itinerary selection" \ - __-file__ {*-label "Itinerary report" -variable report_file*} \ - __-frame__ {*-label "Itinerary start"*} \ - __-comment__ {*-text "Specify your itinerary start location"*} \ - __-entry__ {*-label "City" -variable start_city -type string*} \ - __-entry__ {*-label "Street" -variable start_street -type string -optional 1*} \ - __-entry__ {*-label "Street number" -variable start_street_nbr -type integer -optional 1*} \ - __-frame__ {*-label "Itinerary destination"*} \ - __-comment__ {*-text "Specify your itinerary destination"*} \ - __-entry__ {*-label "City" -variable dest_city -type string*} \ - __-entry__ {*-label "Street" -variable dest_street -type string -optional 1*} \ - __-entry__ {*-label "Street number" -variable dest_street_nbr -type integer -optional 1*} \ - __-frame__ {} \ - __-checkbutton__ {*-label "Don't use highways" -variable no_highway*} - - \] This example opens a dialog box that has the title *Itinerary - selection*\. A first entry widget in this box allows selecting a report - file\. It follows two frames to define respectively an itinerary start and - end location\. Each of these locations that are described with a comment has - three entry widgets to specify respectively the city, street and the street - number\. Bellow the second frame there is a check button that allows - specifying if eventual highways should be ignored\. + > set DialogResult \[__tepam::argument\_dialogbox__ \\ + >    __\-title__ "Itinerary selection" \\ + >    __\-file__ \{*\-label "Itinerary report" \-variable report\_file*\} \\ + >    __\-frame__ \{*\-label "Itinerary start"*\} \\ + >       __\-comment__ \{*\-text "Specify your itinerary start location"*\} \\ + >       __\-entry__ \{*\-label "City" \-variable start\_city \-type string*\} \\ + >       __\-entry__ \{*\-label "Street" \-variable start\_street \-type string \-optional 1*\} \\ + >       __\-entry__ \{*\-label "Street number" \-variable start\_street\_nbr \-type integer \-optional 1*\} \\ + >    __\-frame__ \{*\-label "Itinerary destination"*\} \\ + >       __\-comment__ \{*\-text "Specify your itinerary destination"*\} \\ + >       __\-entry__ \{*\-label "City" \-variable dest\_city \-type string*\} \\ + >       __\-entry__ \{*\-label "Street" \-variable dest\_street \-type string \-optional 1*\} \\ + >       __\-entry__ \{*\-label "Street number" \-variable dest\_street\_nbr \-type integer \-optional 1*\} \\ + >    __\-frame__ \{\} \\ + >    __\-checkbutton__ \{*\-label "Don't use highways" \-variable no\_highway*\}\] + + This example opens a dialog box that has the title *Itinerary selection*\. + A first entry widget in this box allows selecting a report file\. It follows + two frames to define respectively an itinerary start and end location\. Each + of these locations that are described with a comment has three entry widgets + to specify respectively the city, street and the street number\. Bellow the + second frame there is a check button that allows specifying if eventual + highways should be ignored\. - __tepam::argument\_dialogbox__ \{*item\_name item\_attributes ?item\_name item\_attributes? ?\.\.\.?*\} Sometimes it is simpler to provide all the data entry item definitions in form of a single list to __argument\_dialogbox__, and not as individual @@ -112,28 +112,26 @@ arguments\. The second format that is supported by __argument\_dialogbox__ corresponds exactly to the first one, except that all item definitions are packed into a single list that is provided to __argument\_dialogbox__\. The previous example can therefore also be written in the following way: - set DialogResult [__tepam::argument_dialogbox {__ - __-title__ "Itinerary selection" - __-file__ {*-label "Itinerary report" -variable report_file*} - ... - __-checkbutton__ {*-label "Don't use highways" -variable no_highway*} - - __\}__\] + > set DialogResult \[__tepam::argument\_dialogbox \{__ + >    __\-title__ "Itinerary selection" + >    __\-file__ \{*\-label "Itinerary report" \-variable report\_file*\} + >    \.\.\. + >    __\-checkbutton__ \{*\-label "Don't use highways" \-variable no\_highway*\} __\}__\] The commands __argument\_dialogbox__ as well as __[procedure](\.\./\.\./\.\./\.\./index\.md\#procedure)__ are exported from the namespace __tepam__\. To use these commands without the __tepam::__ namespace prefix, it is sufficient to import them into the main namespace: - __namespace import tepam::*__ - - set DialogResult [__argument_dialogbox__ \ - -title "Itinerary selection" - ... +> __namespace import tepam::\*__ +> +> set DialogResult \[__argument\_dialogbox__ \\ +>    \-title "Itinerary selection" +>    \.\.\. The following subsections explain the different argument item types that are accepted by the __argument\_dialogbox__, classified into three groups\. The first data entry item definition format will be used in the remaining document, knowing that this format can always be transformed into the second format by @@ -143,55 +141,55 @@ ## Context Definition Items The first item group allows specifying some context aspects of an argument dialog box\. These items are taking a simple character string as item attribute: - tepam::argument_dialogbox \ - __-__ *string* \ - ... +> tepam::argument\_dialogbox \\ +>    __\-__ *string* \\ +>    \.\.\. The following items are classified into this group: - \-title *string* The dialog box window title which is by default *Dialog* can be changed with the *\-title* item: - tepam::argument_dialogbox \ - __-title__ "System configuration" \ - ... +> tepam::argument\_dialogbox \\ +>    __\-title__ "System configuration" \\ +>    \.\.\. - \-window *string* The argument dialog box uses by default *\.dialog* as dialog top level window\. This path can be changed with the *\-window* item: - tepam::argument_dialogbox \ - __-window__ .dialog \ - ... +> tepam::argument\_dialogbox \\ +>    __\-window__ \.dialog \\ +>    \.\.\. - \-parent *string* By defining a parent window, the argument dialog box will be displayed beside this one\. Without explicit parent window definition, the top\-level window will be considered as parent window\. - tepam::argument_dialogbox \ - __-parent__ .my_appl \ - ... +> tepam::argument\_dialogbox \\ +>    __\-parent__ \.my\_appl \\ +>    \.\.\. - \-context *string* If a context is defined the dialog box state, e\.g\. the entered data as well as the window size and position, is restored the next time the argument dialog box is called\. The assignment of a context allows saving the dialog box state in its context to distinguish between different usages of the argument dialog box\. - tepam::argument_dialogbox \ - __-context__ destination_definitions \ - ... +> tepam::argument\_dialogbox \\ +>    __\-context__ destination\_definitions \\ +>    \.\.\. ## Formatting and Display Options Especially for big, complex forms it becomes important that the different data entry widgets are graphically well organized and commented to provide an @@ -199,18 +197,19 @@ and commenting the dialog boxes\. The items of this classification group require as item attributes a definition list, which contains itself attribute name and value pairs: - tepam::argument_dialogbox \ - ... - __-__ { * - ?- ? - ?- ? - ?...?* - } - ... +> tepam::argument\_dialogbox \\ +>    \.\.\. +>    __\-__ \{ +>       *?\- ?* +>       *?\- ?* +>       *?\.\.\.?* +> +>    \} +>    \.\.\. The following items are classified into this group: - \-frame *list* @@ -223,59 +222,59 @@ An optional frame label can be specified with the *\-label* statement\. Example: - tepam::argument_dialogbox \ - ... - __-frame__ {*-label "Destination address"*} - ... +> tepam::argument\_dialogbox \\ +>    \.\.\. +>    __\-frame__ \{*\-label "Destination address"*\} +>    \.\.\. To close an open frame without opening a new one, an empty list has to be provided to the *\-frame* statement\. - tepam::argument_dialogbox \ - ... - __-frame__ {} - ... +> tepam::argument\_dialogbox \\ +>    \.\.\. +>    __\-frame__ \{\} +>    \.\.\. - \-sep \[const \{\{\}\}\] Entry widgets can be separated with the *\-sep* statement which doesn't require additional definitions\. The related definition list has to exist, but its content is ignored\. - tepam::argument_dialogbox \ - ... - __-sep__ {} - ... +> tepam::argument\_dialogbox \\ +>    \.\.\. +>    __\-sep__ \{\} +>    \.\.\. - \-comment *string* Comments and descriptions can be added with the *\-text* attribute of the *\-comment* item\. Please note that each entry widget itself can also contain a *\-text* attribute for comments and descriptions\. But the *\-comment* item allows for example adding a description between two frames\. - tepam::argument_dialogbox \ - ... - __-comment__ {*-text "Specify bellow the destination address"*} - ... +> tepam::argument\_dialogbox \\ +>    \.\.\. +>    __\-comment__ \{*\-text "Specify bellow the destination address"*\} +>    \.\.\. - \-yscroll __0__|__1__|__auto__ This attribute allows controlling an eventual vertical scrollbar\. Setting it to __0__ will permanently disable the scrollbar, setting it to __1__ will enable it\. By default it is set to __auto__\. The scrollbar is enabled in this mode only if the vertical data entry form size exceeds 66% of the screen height\. - tepam::argument_dialogbox \ - ... - __-yscroll__ __auto__ - ... +> tepam::argument\_dialogbox \\ +>    \.\.\. +>    __\-yscroll__ __auto__ +>    \.\.\. ## Global Custom Data Validation This item group allows specifying global custom checks to validate the entered data\. @@ -283,13 +282,13 @@ - \-validatecommand *script* Custom data checks can be performed via validation commands that are defined with the *\-validatecommand* item\. Example: - tepam::argument_dialogbox \ - -entry {-label "Your comment" -variable YourCom} \ - __-validatecommand__ {IllegalWordDetector $YourCom} +> tepam::argument\_dialogbox \\ +>    \-entry \{\-label "Your comment" \-variable YourCom\} \\ +>    __\-validatecommand__ \{IllegalWordDetector $YourCom\} The validation command is executed in the context of the calling procedure, once all the basic data checks have been performed and data variables are assigned\. All data is accessed via the data variables\. Note that there is also an entry widget specific attribute *\-validatecommand* that allows @@ -318,18 +317,19 @@ Data entry widgets are created with the widget items\. These items require as item attributes a definition list, which contains itself attribute name and value pairs: - tepam::argument_dialogbox \ - ... - __-__ { * - ?- ? - ?- ? - ?...?* - } - ... +> tepam::argument\_dialogbox \\ +>    \.\.\. +>    __\-__ \{ +>       *?\- ?* +>       *?\- ?* +>       *?\.\.\.?* +> +>    \} +>    \.\.\. The attribute list can contain various attributes to describe and comment an entry widget and to constrain its entered value\. All entry widgets are accepting a common set of attributes that are described in the section [Entry Widget Item Attributes](#subsection5)\. @@ -341,40 +341,40 @@ - \-entry *list* The *\-entry* item generates the simplest but most universal data entry widget\. It allows entering any kind of data in form of single line strings\. - tepam::argument_dialogbox \ - __-entry__ {-label Name -variable Entry} +> tepam::argument\_dialogbox \\ +>    __\-entry__ \{\-label Name \-variable Entry\} - \-text *list* The *\-text* item generates a multi line text entry widget\. The widget height can be selected with the *\-height* attribute\. - tepam::argument_dialogbox \ - __-text__ {-label Name -variable Text -height 5} +> tepam::argument\_dialogbox \\ +>    __\-text__ \{\-label Name \-variable Text \-height 5\} - \-checkbox *list* A group of check boxes is created with the *\-checkbox* item\. The number of check boxes and their option values are specified with a list assigned to the *\-choices* attribute or via a variable declared with the *\-choicevariable* attribute: - tepam::argument_dialogbox \ - __-checkbox__ {-label "Font sytle" -variable FontStyle \ - -choices {bold italic underline} -default italic} +> tepam::argument\_dialogbox \\ +>    __\-checkbox__ \{\-label "Font sytle" \-variable FontStyle \\ +>                \-choices \{bold italic underline\} \-default italic\} If the labels of the check boxes should differ from the option values, their labels can be defined with the *\-choicelabels* attribute: - tepam::argument_dialogbox \ - __-checkbox__ {-label "Font sytle" -variable FontStyle \ - -choices {bold italic underline} \ - -choicelabels {Bold Italic Underline} \ - -default italic} +> tepam::argument\_dialogbox \\ +>    __\-checkbox__ \{\-label "Font sytle" \-variable FontStyle \\ +>               \-choices \{bold italic underline\} \\ +>               \-choicelabels \{Bold Italic Underline\} \\ +>               \-default italic\} In contrast to a radio box group, a check box group allows selecting simultaneously several choice options\. The selection is stored for this reason inside the defined variable in form of a list, even if only one choice option has been selected\. @@ -388,32 +388,32 @@ In contrast to a check box group, a radio box group allows selecting simultaneously only one choice option\. The selected option value is stored directly, and not in form of a list, inside the defined variable\. - tepam::argument_dialogbox \ - __-radiobox__ {-label "Text adjustment" -variable Adjustment \ - -choices {left center right} -default left} +> tepam::argument\_dialogbox \\ +>    __\-radiobox__ \{\-label "Text adjustment" \-variable Adjustment \\ +>               \-choices \{left center right\} \-default left\} If the labels of the radio boxes should differ from the option values, their labels can be defined with the *\-choicelabels* attribute: - tepam::argument_dialogbox \ - __-radiobox__ {-label "Text adjustment" -variable Adjustment \ - -choices {left center right} \ - -choicelabels {Left Center Right} -default left} +> tepam::argument\_dialogbox \\ +>    __\-radiobox__ \{\-label "Text adjustment" \-variable Adjustment \\ +>               \-choices \{left center right\} \\ +>               \-choicelabels \{Left Center Right\} \-default left\} - \-checkbutton *list* The *\-checkbutton* entry widget allows activating or deactivating a single choice option\. The result written into the variable will either be __0__ if the check button was not activated or __1__ if it was activated\. An eventually provided default value has also to be either __0__ or __1__\. - tepam::argument_dialogbox \ - __-checkbutton__ {-label Capitalize -variable Capitalize -default 1} +> tepam::argument\_dialogbox \\ +>    __\-checkbutton__ \{\-label Capitalize \-variable Capitalize \-default 1\} Several types of list and combo boxes are available to handle selection lists\. - \-combobox *list* @@ -421,18 +421,18 @@ drop\-down list box\. The combobox allows selecting from this drop\-down list box a single element\. The list of the available elements can be provided either as a list to the *\-choices* attribute, or via a variable that is specified with the *\-choicevariable* attribute\. - tepam::argument_dialogbox \ - __-combobox__ {-label "Text size" -variable Size -choices {8 9 10 12 15 18} -default 12} +> tepam::argument\_dialogbox \\ +>    __\-combobox__ \{\-label "Text size" \-variable Size \-choices \{8 9 10 12 15 18\} \-default 12\} And here is an example of using a variable to define the selection list: - set TextSizes {8 9 10 12 15 18} - tepam::argument_dialogbox \ - __-combobox__ {-label "Text size" -variable Size -choicevariable TextSizes -default 12} +> set TextSizes \{8 9 10 12 15 18\} +> tepam::argument\_dialogbox \\ +>    __\-combobox__ \{\-label "Text size" \-variable Size \-choicevariable TextSizes \-default 12\} - \-listbox *list* In contrast to the combo box, the list box is always displayed by the *listbox* entry widget\. Only one element is selectable unless the @@ -439,26 +439,26 @@ *\-multiple\_selection* attribute is set\. The list box height can be selected with the *\-height* attribute\. If the height is not explicitly defined, the list box height is automatically adapted to the argument dialog box size\. The first example uses a variable to define the available choices: - set set AvailableSizes - for {set k 0} {$k<16} {incr k} {lappend AvailableSizes [expr 1<<$k]} - - tepam::argument_dialogbox \ - __-listbox__ {-label "Distance" -variable Distance \ - -choicevariable AvailableSizes -default 6 -height 5} +> set set AvailableSizes +> for \{set k 0\} \{$k<16\} \{incr k\} \{lappend AvailableSizes \[expr 1<<$k\]\} +> +> tepam::argument\_dialogbox \\ +>    __\-listbox__ \{\-label "Distance" \-variable Distance \\ +>              \-choicevariable AvailableSizes \-default 6 \-height 5\} Here is a multi\-element selection example\. Please note that also the default selection can contain multiple elements: - tepam::argument_dialogbox \ - __-listbox__ {-label "Text styles" -variable Styles \ - -choices {bold italic underline overstrike} \ - -choicelabels {Bold Italic Underline Overstrike} \ - -default {bold underline} -multiple_selection 1 \ - -height 3} +> tepam::argument\_dialogbox \\ +>    __\-listbox__ \{\-label "Text styles" \-variable Styles \\ +>              \-choices \{bold italic underline overstrike\} \\ +>              \-choicelabels \{Bold Italic Underline Overstrike\} \\ +>              \-default \{bold underline\} \-multiple\_selection 1 \\ +>              \-height 3\} - \-disjointlistbox *list* A disjoint list box has to be used instead of a normal list box if the selection order is important\. The disjoint list box entry widget has in fact @@ -468,15 +468,15 @@ Disjoint listboxes allow always selecting multiple elements\. With the exception of the *\-multiple\_selection* attribute, disjointed list boxes are accepting the same attributes as the normal listbox, e\.g\. *\-height, \-choices, \-choicevariable, \-default*\. - tepam::argument_dialogbox \ - __-disjointlistbox__ {-label "Preferred scripting languages" -variable Languages \ - -comment "Please select your preferred languages in the order" \ - -choices {JavaScript Lisp Lua Octave PHP Perl Python Ruby Scheme Tcl} \ - -default {Tcl Perl Python}} +> tepam::argument\_dialogbox \\ +>    __\-disjointlistbox__ \{\-label "Preferred scripting languages" \-variable Languages \\ +>              \-comment "Please select your preferred languages in the order" \\ +>              \-choices \{JavaScript Lisp Lua Octave PHP Perl Python Ruby Scheme Tcl\} \\ +>              \-default \{Tcl Perl Python\}\} The file and directory selectors are building a next group of data entry widgets\. A paragraph of section [Entry Widget Item Attributes](#subsection5) explains the widget specific attributes that allow specifying the targeted file types, active directory etc\. @@ -486,48 +486,48 @@ The item *\-file* creates a group composed by an entry widget together with a button that allows opening a file browser\. The data type *file* is automatically selected for this entry if no data type has been explicitly defined with the *\-type* attribute\. - tepam::argument_dialogbox \ - __-file__ {-label "Image file" -variable ImageF \ - -filetypes {{"GIF" {*.gif}} {"JPG" {*.jpg}}} \ - -initialfile "picture.gif"} +> tepam::argument\_dialogbox \\ +>    __\-file__ \{\-label "Image file" \-variable ImageF \\ +>           \-filetypes \{\{"GIF" \{\*\.gif\}\} \{"JPG" \{\*\.jpg\}\}\} \\ +>           \-initialfile "picture\.gif"\} - \-existingfile *list* The item *\-existingfile* creates a group composed by an entry widget together with a button that allows opening a browser to select an existing file\. The data type *existingfile* is automatically selected for this entry if no data type has been explicitly defined with the *\-type* attribute\. - tepam::argument_dialogbox \ - __-existingfile__ {-label "Image file" -variable ImageF \ - -filetypes {{"GIF" {*.gif}} {"JPG" {*.jpg}}} \ - -initialfile "picture.gif"} +> tepam::argument\_dialogbox \\ +>    __\-existingfile__ \{\-label "Image file" \-variable ImageF \\ +>                   \-filetypes \{\{"GIF" \{\*\.gif\}\} \{"JPG" \{\*\.jpg\}\}\} \\ +>                   \-initialfile "picture\.gif"\} - \-directory *list* The item *\-directory* creates a group composed by an entry widget together with a button that allows opening a directory browser\. The data type *directory* is automatically selected for this entry if no data type has been explicitly defined with the *\-type* attribute\. - tepam::argument_dialogbox \ - __-directory__ {-label "Report directory" -variable ReportDir} +> tepam::argument\_dialogbox \\ +>    __\-directory__ \{\-label "Report directory" \-variable ReportDir\} - \-existingdirectory *list* The item *\-existingdirectory* creates a group composed by an entry widget together with a button that allows opening a browser to select an existing directory\. The data type *existingdirectory* is automatically selected for this entry if no data type has been explicitly defined with the *\-type* attribute\. - tepam::argument_dialogbox \ - __-existingdirectory__ {-label "Report directory" -variable ReportDir} +> tepam::argument\_dialogbox \\ +>    __\-existingdirectory__ \{\-label "Report directory" \-variable ReportDir\} Finally, there is a last group of some other special data entry widgets\. - \-color *list* @@ -534,12 +534,12 @@ The color selector is composed by an entry widget together with a button that allows opening a color browser\. The data type *color* is automatically selected for this entry widget type if no data type has been explicitly defined with the *\-type* attribute\. - tepam::argument_dialogbox \ - __-color__ {-label "Background color" -variable Color -default red} +> tepam::argument\_dialogbox \\ +>    __\-color__ \{\-label "Background color" \-variable Color \-default red\} - \-font *list* The font selector is composed by an entry widget together with a button that allows opening a font browser\. The data type *font* is automatically @@ -558,14 +558,14 @@ default selected font\. If the font family of this label widget is not part of the available families the first available family is used as default\. If the font size of this label widget is not part of the available sizes the next close available size is selected as default size\. - tepam::argument_dialogbox \ - __-font__ {-label "Font" -variable Font \ - -font_sizes {8 10 12 16} \ - -default {Arial 20 italic}} +> tepam::argument\_dialogbox \\ +>    __\-font__ \{\-label "Font" \-variable Font \\ +>           \-font\_sizes \{8 10 12 16\} \\ +>           \-default \{Arial 20 italic\}\} ## Entry Widget Item Attributes All the entry widget items are accepting the following attributes: @@ -572,40 +572,40 @@ - \-text *string* Eventual descriptions and comments specified with the *\-text* attribute are displayed above the entry widget\. - tepam::argument_dialogbox \ - -entry {__-text "Please enter your name bellow"__ -variable Name} +> tepam::argument\_dialogbox \\ +>    \-entry \{__\-text "Please enter your name bellow"__ \-variable Name\} - \-label *string* The label attribute creates left to the entry widget a label using the provided string as label text: - tepam::argument_dialogbox \ - -entry {__-label Name__ -variable Name} +> tepam::argument\_dialogbox \\ +>    \-entry \{__\-label Name__ \-variable Name\} - \-variable *string* All entry widgets require a specified variable\. After accepting the entered information with the OK button, the entry widget data is stored inside the defined variables\. - tepam::argument_dialogbox \ - -existingdirectory {-label "Report directory" __-variable ReportDir__} +> tepam::argument\_dialogbox \\ +>    \-existingdirectory \{\-label "Report directory" __\-variable ReportDir__\} - \-default *string* Eventual default data for the entry widgets can be provided via the *\-default* attribute\. The default value is overridden if an argument dialog box with a defined context is called another time\. The value acknowledged in a previous call will be used in this case as default value\. - tepam::argument_dialogbox \ - -checkbox {-label "Font sytle" -variable FontStyle \ - -choices {bold italic underline} __-default italic__} +> tepam::argument\_dialogbox \\ +>    \-checkbox \{\-label "Font sytle" \-variable FontStyle \\ +>                \-choices \{bold italic underline\} __\-default italic__\} - \-optional __0__|__1__ Data can be specified as optional or mandatory with the *\-optional* attribute that requires either __0__ \(mandatory\) or __1__ \(optional\) @@ -613,14 +613,14 @@ In case an entry is optional and no data has been entered, e\.g\. the entry contains an empty character string, the entry will be considered as undefined and the assigned variable will not be defined\. - tepam::argument_dialogbox \ - -entry {-label "City" -variable start_city -type string} \ - -entry {-label "Street" -variable start_street -type string __-optional 0__} \ - -entry {-label "Street number" -variable start_street_nbr -type integer __-optional 1__} \ +> tepam::argument\_dialogbox \\ +>    \-entry \{\-label "City" \-variable start\_city \-type string\} \\ +>    \-entry \{\-label "Street" \-variable start\_street \-type string __\-optional 0__\} \\ +>    \-entry \{\-label "Street number" \-variable start\_street\_nbr \-type integer __\-optional 1__\} \\ - \-type *string* If the data type is defined with the *\-type* attribute the argument dialog box will automatically perform a data type check after acknowledging the @@ -635,12 +635,12 @@ Some entry widgets like the file and directory widgets, as well as the color and font widgets are specifying automatically the default data type if no type has been specified explicitly with the *\-type* attribute\. - tepam::argument_dialogbox \ - __-entry__ {-label "Street number" -variable start_street_nbr __-type integer__} \ +> tepam::argument\_dialogbox \\ +>    __\-entry__ \{\-label "Street number" \-variable start\_street\_nbr __\-type integer__\} \\ - \-range *string* Values can be constrained with the *\-range* attribute\. The valid range is defined with a list containing the minimum valid value and a maximum valid @@ -647,23 +647,23 @@ value\. The *\-range* attribute has to be used only for numerical arguments, like integers and doubles\. - tepam::argument_dialogbox \ - -entry {-label Month -variable Month -type integer __-range {1 12}__} +> tepam::argument\_dialogbox \\ +>    \-entry \{\-label Month \-variable Month \-type integer __\-range \{1 12\}__\} - \-validatecommand *string* Custom argument value validations can be performed via specific validation commands that are defined with the *\-validatecommand* attribute\. The provided validation command can be a complete script in which the pattern *%P* is placeholder for the argument value that has to be validated\. - tepam::argument_dialogbox \ - -entry {-label "Your comment" -variable YourCom \ - __-validatecommand__ "IllegalWordDetector %P"} +> tepam::argument\_dialogbox \\ +>    \-entry \{\-label "Your comment" \-variable YourCom \\ +>            __\-validatecommand__ "IllegalWordDetector %P"\} While the purpose of this custom argument validation attribute is the validation of a specific argument, there is also a global data validation attribute *\-validatecommand* that allows performing validation that involves multiple arguments\. @@ -680,44 +680,44 @@ Choice lists can directly be defined with the *\-choices* attribute\. This way to define choice lists is especially adapted for smaller, fixed selection lists\. - tepam::argument_dialogbox \ - -listbox {-label "Text styles" -variable Styles \ - __-choices {bold italic underline}__ -default underline +> tepam::argument\_dialogbox \\ +>    \-listbox \{\-label "Text styles" \-variable Styles \\ +>              __\-choices \{bold italic underline\}__ \-default underline - \-choicelabels *string* *\(only check and radio buttons\)* If the labels of the check and radio boxes should differ from the option values, they can be defined with the *\-choicelabels* attribute: - tepam::argument_dialogbox \ - -checkbox {-label "Font sytle" -variable FontStyle \ - -choices {bold italic underline} \ - __-choicelabels {Bold Italic Underline}__ +> tepam::argument\_dialogbox \\ +>    \-checkbox \{\-label "Font sytle" \-variable FontStyle \\ +>               \-choices \{bold italic underline\} \\ +>               __\-choicelabels \{Bold Italic Underline\}__ - \-choicevariable *string* Another way to define the choice lists is using the *\-choicevariable* attribute\. This way to define choice lists is especially adapted for huge and eventually variable selection lists\. - set TextSizes {8 9 10 12 15 18} - tepam::argument_dialogbox \ - -combobox {-label "Text size" -variable Size __-choicevariable TextSizes__} +> set TextSizes \{8 9 10 12 15 18\} +> tepam::argument\_dialogbox \\ +>    \-combobox \{\-label "Text size" \-variable Size __\-choicevariable TextSizes__\} - \-multiple\_selection __0__|__1__ The list box item \(__\-listbox__\) allows by default selecting only one list element\. By setting the *\-multiple\_selection* attribute to __1__, multiple elements can be selected\. - tepam::argument_dialogbox \ - -listbox {-label "Text styles" -variable Styles \ - -choices {bold italic underline} -default underline \ - __-multiple_selection 1__ -height 3} +> tepam::argument\_dialogbox \\ +>    \-listbox \{\-label "Text styles" \-variable Styles \\ +>              \-choices \{bold italic underline\} \-default underline \\ +>              __\-multiple\_selection 1__ \-height 3\} Some additional attributes are supported by the file and directory selection widgets\. - \-filetypes *string* @@ -724,23 +724,23 @@ The file type attribute is used by the __\-file__ and __\-existingfile__ items to define the file endings that are searched by the file browser\. - tepam::argument_dialogbox \ - -file {-label "Image file" -variable ImageF \ - __-filetypes {{"GIF" {*.gif}} {"JPG" {*.jpg}}}__} +> tepam::argument\_dialogbox \\ +>    \-file \{\-label "Image file" \-variable ImageF \\ +>           __\-filetypes \{\{"GIF" \{\*\.gif\}\} \{"JPG" \{\*\.jpg\}\}\}__\} - \-initialfile *string* The initial file used by the file browsers of the __\-file__ and __\-existingfile__ widgets are by default the file defined with the *\-default* attribute, unless a file is specified with the *\-initialfile* attribute\. - tepam::argument_dialogbox \ - -file {-variable ImageF __-initialfile "picture.gif"__} +> tepam::argument\_dialogbox \\ +>    \-file \{\-variable ImageF __\-initialfile "picture\.gif"__\} - \-activedir *string* The *\-activedir* attribute will override the default active search directory used by the file browsers of all file and directory entry widgets\. @@ -747,12 +747,12 @@ The default active search directory is defined by the directory of a specified initial file \(*\-initialfile*\) if defined, and otherwise by the directory of the default file/directory, specified with the *\-default* attribute\. - tepam::argument_dialogbox \ - -file "-variable ImageF __-activedir $pwd__" +> tepam::argument\_dialogbox \\ +>    \-file "\-variable ImageF __\-activedir $pwd__" Finally, there is a last attribute supported by some widgets: - \-height *string* @@ -759,13 +759,13 @@ All widgets containing a selection list \(__\-listbox__, __\-disjointlistbox__, __\-font__\) as well as the multi line __\-text__ widget are accepting the *\-height* attribute that defines the number of displayed rows of the selection lists\. - tepam::argument_dialogbox \ - -listbox {-label "Text size" -variable Size \ - -choices {8 9 10 12 15 18} -default 12 __-height 3__} +> tepam::argument\_dialogbox \\ +>    \-listbox \{\-label "Text size" \-variable Size \\ +>              \-choices \{8 9 10 12 15 18\} \-default 12 __\-height 3__\} If the no height has been explicitly specified the height of the widget will be dynamically adapted to the argument dialog box size\. # APPLICATION SPECIFIC ENTRY WIDGETS @@ -773,20 +773,20 @@ An application specific entry widget can be made available to the argument dialog box by adding a dedicated procedure to the __tepam__ namespace\. This procedure has three arguments; the first one is the widget path, the second one a subcommand and the third argument has various purposes: - *proc* tepam::ad_form() {W Command {Par ""}} { - *upvar Option Option; # if required* - *variable argument_dialogbox; # if required* - switch $Command { - "create" - "set_choice" - "set" - "get" - } - } +> *proc* tepam::ad\_form\(\) \{W Command \{Par ""\}\} \{ +>    *upvar Option Option; \# if required* +>    *variable argument\_dialogbox; \# if required* +>    switch $Command \{ +>       "create" +>       "set\_choice" +>       "set" +>       "get" +>    \} +> \} __Argument\_dialogbox__ takes care about the *\-label* and *\-text* attributes for all entry widgets\. For any data entry widget it creates a frame into which the data entry widget components can be placed\. The path to this frame is provided via the *W* argument\. Index: embedded/md/tcllib/files/modules/tepam/tepam_doc_gen.md ================================================================== --- embedded/md/tcllib/files/modules/tepam/tepam_doc_gen.md +++ embedded/md/tcllib/files/modules/tepam/tepam_doc_gen.md @@ -242,39 +242,39 @@ document components\. The following documentation listing contains tokens that refer to the different document generation procedures: - * <01>* - *<03> <20s>* NAME*<20e>* - * <30s>* message_box - Displays text in a message box*<30e>* - * <20s>* SYNOPSYS*<20e>* - * <40s>* message_box [-mtype ] *<40e>* - * <20s>* DESCRIPTION*<20e>* - * <21s> message_box<21e>* - * <54s> message_box [-mtype ] <54e>* - * <50s>* This procedure allows displaying a text in an message box. The following - * * message types are supported:*<50e>* - *<51> <53s>* * Info*<53e>* - * <53s>* * Warning*<53e>* - * <53s>* * Error*<53e>* *<52>* - * <50s>* If the text parameter is use multiple times the different texts are - * * concatenated to create the message text.*<50e>* - * <20s>* ARGUMENTS*<20e>* - *<60> <62s>* [-mtype ]*<62e>* - *<63> <65s>* Message type*<65e>* - * <66s>* Default: "Warning"*<66e>* - * <66s>* Multiple: yes*<66e>* - * <66s>* Choices: Info, Warning, Error*<66e>* *<64>* - * <62s>* *<62e>* - *<63> <65s>* One or multiple text lines to display*<65e>* - * <66s>* Type: string*<66e>* - * <66s>* Multiple: yes*<66e>* *<64><61>* - * <20s>* EXAMPLE*<20e>* - *<70> <72s>* message_box "Please save first the document"*<72e>* - * <73s>* -> 1*<73e>* *<71><04>* - * <02>* +>       *<01>* +>  *<03> <20s>* NAME*<20e>* +>       *<30s>* message\_box \- Displays text in a message box*<30e>* +>       *<20s>* SYNOPSYS*<20e>* +>       *<40s>* message\_box \[\-mtype \] *<40e>* +>       *<20s>* DESCRIPTION*<20e>* +>       *<21s> message\_box<21e>* +>       *<54s> message\_box \[\-mtype \] <54e>* +>       *<50s>* This procedure allows displaying a text in an message box\. The following +>            ** message types are supported:*<50e>* +>  *<51> <53s>* \* Info*<53e>* +>       *<53s>* \* Warning*<53e>* +>       *<53s>* \* Error*<53e>* *<52>* +>       *<50s>* If the text parameter is use multiple times the different texts are +>            ** concatenated to create the message text\.*<50e>* +>       *<20s>* ARGUMENTS*<20e>* +>  *<60> <62s>* \[\-mtype \]*<62e>* +>  *<63> <65s>* Message type*<65e>* +>       *<66s>* Default: "Warning"*<66e>* +>       *<66s>* Multiple: yes*<66e>* +>       *<66s>* Choices: Info, Warning, Error*<66e>* *<64>* +>       *<62s>* *<62e>* +>  *<63> <65s>* One or multiple text lines to display*<65e>* +>       *<66s>* Type: string*<66e>* +>       *<66s>* Multiple: yes*<66e>* *<64><61>* +>       *<20s>* EXAMPLE*<20e>* +>  *<70> <72s>* message\_box "Please save first the document"*<72e>* +>       *<73s>* \-> 1*<73e>* *<71><04>* +>       *<02>* There are 2 types of document generation procedures: - Content generation procedures \(e\.g\. <40s>\.\.\.<40e>\) @@ -430,80 +430,74 @@ If true \(=__1__\) the argument is optional which should be indicated by the generated string \(for example by putting the argument into brackets \{\[\]\} or into question marks '?'\): - gen(TXT,ArgumentString) mtype 1 0 string -> - - *"\[mtype\]"* +> gen\(TXT,ArgumentString\) mtype 1 0 string \-> *"\[mtype\]"* * *IsNamed* If true \(=__1__\) an argument is a named argument \(option\)\. The generated string should in this case contain the argument/option name, followed by the argument itself: - gen(TXT,ArgumentString) mtype 0 1 string -> +> gen\(TXT,ArgumentString\) mtype 0 1 string \-> *"\-mtype "* - *"\-mtype "* Named arguments can also be optional: + Named arguments can also be optional: - gen(TXT,ArgumentString) mtype 1 1 string -> - - *"\[\-mtype \]"* +> gen\(TXT,ArgumentString\) mtype 1 1 string \-> *"\[\-mtype \]"* * *Type* Indicates the type of the argument\. If the type is set to __none__ the argument is a flag, which needs to be indicated by the generated string\. Example: - gen(TXT,ArgumentString) close 1 1 none -> - - *"\[\-close\]"* +> gen\(TXT,ArgumentString\) close 1 1 none \-> *"\[\-close\]"* # EXAMPLES ## tepam::doc\_gen::generate The __TEPAM Doc Gen__ package can be explored by generating the documentation of the command __tepam::doc\_gen::generate__\. The following example generates the document in text format \(default format\): - __tepam::doc_gen::generate__ tepam::doc_gen::generate +> __tepam::doc\_gen::generate__ tepam::doc\_gen::generate The next example generates the documentation in HTML format: - __tepam::doc_gen::generate__ -format HTML tepam::doc_gen::generate +> __tepam::doc\_gen::generate__ \-format HTML tepam::doc\_gen::generate The flag ?header\_footer? adds also the file header and footer: - __tepam::doc_gen::generate__ -format HTML -header_footer tepam::doc_gen::generate +> __tepam::doc\_gen::generate__ \-format HTML \-header\_footer tepam::doc\_gen::generate The documentation can directly be stored in a file\. The file header and footer are automatically generated in this way: - __tepam::doc_gen::generate__ -format HTML -dest_file doc_gen.html tepam::doc_gen::generate +> __tepam::doc\_gen::generate__ \-format HTML \-dest\_file doc\_gen\.html tepam::doc\_gen::generate The generated HTML file refers a CSS stylesheet file \(default: tepam\_doc\_stylesheet\.css\)\. To display the HTML file correctly this CSS stylesheet file needs to be copied into the directory of the generated HTML file\. The Tcl DOC Tools format can be used as intermediate format to generate other formats, for example HTML: - *# Generate the documentation in Tcl Doc Tool format* - set dt [__tepam::doc_gen::generate__ -format DT -header_footer tepam::doc_gen::generate] - ** - *# Create a new doc tools object (HTML format)* - package require doctools - ::doctools::new myDoc -format html - ** - *# Open the HTML file, and write the HTML formatted documentation* - set fHtml [open doc_gen.dt.html w] - puts $fHtml [myDoc format $dt] - close $fHtml +> *\# Generate the documentation in Tcl Doc Tool format* +> set dt \[__tepam::doc\_gen::generate__ \-format DT \-header\_footer tepam::doc\_gen::generate\] +> ** +> *\# Create a new doc tools object \(HTML format\)* +> package require doctools +> ::doctools::new myDoc \-format html +> ** +> *\# Open the HTML file, and write the HTML formatted documentation* +> set fHtml \[open doc\_gen\.dt\.html w\] +> puts $fHtml \[myDoc format $dt\] +> close $fHtml ## tepam::doc\_gen::patch While __generate__ provides a limited number of possibilities to vary the document structure, __[patch](\.\./\.\./\.\./\.\./index\.md\#patch)__ offers more @@ -517,32 +511,33 @@ __[patch](\.\./\.\./\.\./\.\./index\.md\#patch)__ with the generated documentation of the referred procedures\. Since nonstandard placeholders are used, __[patch](\.\./\.\./\.\./\.\./index\.md\#patch)__ is called with an explicit placeholder pattern definition \(argument *search\_pattern*\)\. - *# Define the HTML master document* - set HtmlMasterDoc {\ - - - tepam::doc_gen - - - - -

tepam::doc_gen

-

Generate

- __{*tepam::doc_gen::generate*}__ -

Patch

- __{*tepam::doc_gen::patch*}__ - - \ - } - ** - *# Patch the master document: This will replace the placeholders by the - # procedure documentation divisions:* - __tepam::doc_gen::patch__ -format HTML -search_pattern {\{\*(.*?)\*\}} \ - -src_string $HtmlMasterDoc -dest_file tepam_doc_gen.html +> *\# Define the HTML master document* +> set HtmlMasterDoc \{\\ +> +>    +>     tepam::doc\_gen +>      +>      +>    +>    +>     

tepam::doc\_gen

+>       

Generate

+> __\{\*tepam::doc\_gen::generate\*\}__ +>       

Patch

+> __\{\*tepam::doc\_gen::patch\*\}__ +>    +> \\ +> \} +> ** +> *\# Patch the master document: This will replace the placeholders by the * +> *\# procedure documentation divisions:* +> +> __tepam::doc\_gen::patch__ \-format HTML \-search\_pattern \{\\\{\\\*\(\.\*?\)\\\*\\\}\} \\ +>                       \-src\_string $HtmlMasterDoc \-dest\_file tepam\_doc\_gen\.html # SEE ALSO [tepam\(n\)](tepam\_introduction\.md), [tepam::procedure\(n\)](tepam\_procedure\.md) Index: embedded/md/tcllib/files/modules/tepam/tepam_introduction.md ================================================================== --- embedded/md/tcllib/files/modules/tepam/tepam_introduction.md +++ embedded/md/tcllib/files/modules/tepam/tepam_introduction.md @@ -132,32 +132,32 @@ The following example declares the subcommand __[message](\.\./\.\./\.\./\.\./index\.md\#message)__ of the procedure __display__\. This command has several named and unnamed arguments: - __[tepam::procedure](tepam_procedure.md)__ {display message} { - -return - - -short_description "Displays a simple message box" - -description "This procedure allows displaying a configurable message box." - -args { - {-mtype -default Warning -choices {Info Warning Error} -description "Message type"} - {-font -type font -default {Arial 10 italic} -description "Message text font"} - {-level -type integer -optional -range {1 10} -description "Message level"} - {-fg -type color -default black -description "Message color"} - {-bg -type color -optional -description "Background color"} - {-no_border -type none -description "Use a splash window style (no border)"} - {-log_file -type file -optional -description "Optional message log file"} - {text -type string -multiple -description "Multiple text lines to display"} - } - } { - * puts "display message:" - foreach var {mtype font level fg bg no_border log_file text} { - if {[info exists $var]} { - puts " $var=[set $var]" - } - } - *} +> __[tepam::procedure](tepam\_procedure\.md)__ \{display message\} \{ +>    \-return \- +>    \-short\_description "Displays a simple message box" +>    \-description "This procedure allows displaying a configurable message box\." +>    \-args \{ +>       \{\-mtype \-default Warning \-choices \{Info Warning Error\} \-description "Message type"\} +>       \{\-font \-type font \-default \{Arial 10 italic\} \-description "Message text font"\} +>       \{\-level \-type integer \-optional \-range \{1 10\} \-description "Message level"\} +>       \{\-fg \-type color \-default black \-description "Message color"\} +>       \{\-bg \-type color \-optional \-description "Background color"\} +>       \{\-no\_border \-type none \-description "Use a splash window style \(no border\)"\} +>       \{\-log\_file \-type file \-optional \-description "Optional message log file"\} +>       \{text \-type string \-multiple \-description "Multiple text lines to display"\} +>    \} +> \} \{ +>    *puts "display message:"* +>    *foreach var \{mtype font level fg bg no\_border log\_file text\} \{* +>       *if \{\[info exists $var\]\} \{* +>          *puts " $var=\[set $var\]"* +>       *\}* +>    *\}* +> \} A call of procedure that has been declared in this way will first invoke the TEPAM argument manager, before the procedure body is executed\. The argument manager parses the provided arguments, validates them, completes them eventually with some default values, and makes them finally available to the procedure body @@ -203,93 +203,113 @@ # PROCEDURE HELP The declared procedure can simply be called with the *\-help* option to get the information about the usage of the procedure and its arguments: - __display message__ -help - -* \-> NAME display message \- Displays a simple message box SYNOPSYS display -message \[\-mtype \] : Message type, default: "Warning", choices: \{Info -Warning Error\} \[\-font \] : Message text font, type: font, default: Arial 10 -italic \[\-level \] : Message level, type: integer, range: 1\.\.10 \[\-fg \] -: Message color, type: color, default: black \[\-bg \] : Background color, -type: color \[\-no\_border \] : Use a splash window style \(no border\) \[\-log\_file -\] : Optional message log file, type: file : Multiple text lines -to display, type: string DESCRIPTION This procedure allows displaying a -configurable message box\.* +> __display message__ \-help +>   *\->* +> *NAME* +>       *display message \- Displays a simple message box* +> *SYNOPSYS* +>       *display message* +>             *\[\-mtype \] :* +>                *Message type, default: "Warning", choices: \{Info Warning Error\}* +>             *\[\-font \] :* +>                *Message text font, type: font, default: Arial 10 italic* +>             *\[\-level \] :* +>                *Message level, type: integer, range: 1\.\.10* +>             *\[\-fg \] :* +>                *Message color, type: color, default: black* +>             *\[\-bg \] :* +>                *Background color, type: color* +>             *\[\-no\_border \] :* +>                *Use a splash window style \(no border\)* +>             *\[\-log\_file \] :* +>                *Optional message log file, type: file* +>             * :* +>                *Multiple text lines to display, type: string* +> *DESCRIPTION* +>       *This procedure allows displaying a configurable message box\.* # PROCEDURE CALL The specified procedure can be called in many ways\. The following listing shows some valid procedure calls: - __display message__ "The document hasn't yet been saved!" - *-> display message: - mtype=Warning - font=Arial 10 italic - fg=black - no_border=0 - text={The document hasn't yet been saved!}* - - __display message__ -fg red -bg black "Please save first the document" - *-> display message: - mtype=Warning - font=Arial 10 italic - fg=red - bg=black - no_border=0 - text={Please save first the document}* - - __display message__ -mtype Error -no_border "Why is here no border?" - *-> display message: - mtype=Error - font=Arial 10 italic - fg=black - no_border=1 - text={Why is here no border?}* - - __display message__ -font {Courier 12} -level 10 \ - "Is there enough space?" "Reduce otherwise the font size!" - -*\-> display message: mtype=Warning font=Courier 12 level=10 fg=black -no\_border=0 text=\{Is there enough space?\} \{Reduce otherwise the font size\!\}* +> __display message__ "The document hasn't yet been saved\!" +> *\-> display message:* +>      *mtype=Warning* +>      *font=Arial 10 italic* +>      *fg=black* +>      *no\_border=0* +>      *text=\{The document hasn't yet been saved\!\}* +> +> +> __display message__ \-fg red \-bg black "Please save first the document" +> *\-> display message:* +>      *mtype=Warning* +>      *font=Arial 10 italic* +>      *fg=red* +>      *bg=black* +>      *no\_border=0* +>      *text=\{Please save first the document\}* +> +> +> __display message__ \-mtype Error \-no\_border "Why is here no border?" +> *\-> display message:* +>      *mtype=Error* +>      *font=Arial 10 italic* +>      *fg=black* +>      *no\_border=1* +>      *text=\{Why is here no border?\}* +> +> +> __display message__ \-font \{Courier 12\} \-level 10 \\ +>    "Is there enough space?" "Reduce otherwise the font size\!" +> *\-> display message:* +>      *mtype=Warning* +>      *font=Courier 12* +>      *level=10* +>      *fg=black* +>      *no\_border=0* +>      *text=\{Is there enough space?\} \{Reduce otherwise the font size\!\}* + The next lines show how wrong arguments are recognized\. The *text* argument that is mandatory is missing in the first procedure call: - __display message__ -font {Courier 12} - -* \-> display message: Required argument is missing: text* Only known arguments -are accepted: - - __display message__ -category warning Hello - -* \-> display message: Argument '\-category' not known* Argument types are -automatically checked and an error message is generated in case the argument -value has not the expected type: - - __display message__ -fg MyColor "Hello" - -* \-> display message: Argument 'fg' requires type 'color'\. Provided value: -'MyColor'* Selection choices have to be respected \.\.\. - - __display message__ -mtype Fatal Hello - -* \-> display message: Argument \(mtype\) has to be one of the following elements: -Info, Warning, Error* \.\.\. as well as valid value ranges: - - __display message__ -level 12 Hello - -* \-> display message: Argument \(level\) has to be between 1 and 10* +> __display message__ \-font \{Courier 12\} +>   *\-> display message: Required argument is missing: text* + +Only known arguments are accepted: + +> __display message__ \-category warning Hello +>   *\-> display message: Argument '\-category' not known* + +Argument types are automatically checked and an error message is generated in +case the argument value has not the expected type: + +> __display message__ \-fg MyColor "Hello" +>   *\-> display message: Argument 'fg' requires type 'color'\. Provided value: 'MyColor'* + +Selection choices have to be respected \.\.\. + +> __display message__ \-mtype Fatal Hello +>   *\-> display message: Argument \(mtype\) has to be one of the following elements: Info, Warning, Error* + +\.\.\. as well as valid value ranges: + +> __display message__ \-level 12 Hello +>   *\-> display message: Argument \(level\) has to be between 1 and 10* # INTERACTIVE PROCEDURE CALLS The most intuitive way to call the procedure is using an form that allows specifying all arguments interactively\. This form will automatically be generated if the declared procedure is called with the *\-interactive* flag\. To use this feature the Tk library has to be loaded\. - __display message__ -interactive +> __display message__ \-interactive The generated form contains for each argument a data entry widget that is adapted to the argument type\. Check buttons are used to specify flags, radio boxes for tiny choice lists, disjoint list boxes for larger choice lists and files, directories, fonts and colors can be selected with dedicated browsers\. @@ -316,14 +336,14 @@ existing file can be overwritten\. Comfortable browsers can be used to select files and directories\. And finally, the form offers also the possibility to accept and decline the selection\. Here is the code snippet that is doing all this: - __[tepam::argument_dialogbox](tepam_argument_dialogbox.md)__ \ - __-existingfile__ {-label "Source file" -variable SourceFile} \ - __-existingdirectory__ {-label "Destination folder" -variable DestDir} \ - __-checkbutton__ {-label "Overwrite existing file" -variable Overwrite} +> __[tepam::argument\_dialogbox](tepam\_argument\_dialogbox\.md)__ \\ +>    __\-existingfile__ \{\-label "Source file" \-variable SourceFile\} \\ +>    __\-existingdirectory__ \{\-label "Destination folder" \-variable DestDir\} \\ +>    __\-checkbutton__ \{\-label "Overwrite existing file" \-variable Overwrite\} The __argument\_dialogbox__ returns __ok__ if the entered data are validated\. It will return __cancel__ if the data entry has been canceled\. After the validation of the entered data, the __argument\_dialogbox__ defines all the specified variables with the entered data inside the calling context\. @@ -348,74 +368,83 @@ The next example of a more complex argument dialog box provides a good overview about the different available entry widget types and parameter attributes\. The example contains also some formatting instructions like *\-frame* and *\-sep* which allows organizing the different entry widgets in frames and sections: - set ChoiceList {"Choice 1" "Choice 2" "Choice 3" "Choice 4" "Choice 5" "Choice 6"} - - set Result [__[tepam::argument_dialogbox](tepam_argument_dialogbox.md)__ \ - __-title__ "System configuration" \ - __-context__ test_1 \ - __-frame__ {-label "Entries"} \ - __-entry__ {-label Entry1 -variable Entry1} \ - __-entry__ {-label Entry2 -variable Entry2 -default "my default"} \ - __-frame__ {-label "Listbox & combobox"} \ - __-listbox__ {-label "Listbox, single selection" -variable Listbox1 \ - -choices {1 2 3 4 5 6 7 8} -default 1 -height 3} \ - __-listbox__ {-label "Listbox, multiple selection" -variable Listbox2 - -choicevariable ChoiceList -default {"Choice 2" "Choice 3"} - -multiple_selection 1 -height 3} \ - __-disjointlistbox__ {-label "Disjoined listbox" -variable DisJntListbox - -choicevariable ChoiceList \ - -default {"Choice 3" "Choice 5"} -height 3} \ - __-combobox__ {-label "Combobox" -variable Combobox \ - -choices {1 2 3 4 5 6 7 8} -default 3} \ - __-frame__ {-label "Checkbox, radiobox and checkbutton"} \ - __-checkbox__ {-label Checkbox -variable Checkbox - -choices {bold italic underline} -choicelabels {Bold Italic Underline} \ - -default italic} \ - __-radiobox__ {-label Radiobox -variable Radiobox - -choices {bold italic underline} -choicelabels {Bold Italic Underline} \ - -default underline} \ - __-checkbutton__ {-label CheckButton -variable Checkbutton -default 1} \ - __-frame__ {-label "Files & directories"} \ - __-existingfile__ {-label "Input file" -variable InputFile} \ - __-file__ {-label "Output file" -variable OutputFile} \ - __-sep__ {} \ - __-existingdirectory__ {-label "Input directory" -variable InputDirectory} \ - __-directory__ {-label "Output irectory" -variable OutputDirectory} \ - __-frame__ {-label "Colors and fonts"} \ - __-color__ {-label "Background color" -variable Color -default red} \ - __-sep__ {} \ - __-font__ {-label "Font" -variable Font -default {Courier 12 italic}} - -\] The __argument\_dialogbox__ defines all the specified variables with the +> set ChoiceList \{"Choice 1" "Choice 2" "Choice 3" "Choice 4" "Choice 5" "Choice 6"\} +> +> set Result \[__[tepam::argument\_dialogbox](tepam\_argument\_dialogbox\.md)__ \\ +>    __\-title__ "System configuration" \\ +>    __\-context__ test\_1 \\ +>    __\-frame__ \{\-label "Entries"\} \\ +>       __\-entry__ \{\-label Entry1 \-variable Entry1\} \\ +>       __\-entry__ \{\-label Entry2 \-variable Entry2 \-default "my default"\} \\ +>    __\-frame__ \{\-label "Listbox & combobox"\} \\ +>       __\-listbox__ \{\-label "Listbox, single selection" \-variable Listbox1 \\ +>                 \-choices \{1 2 3 4 5 6 7 8\} \-default 1 \-height 3\} \\ +>       __\-listbox__ \{\-label "Listbox, multiple selection" \-variable Listbox2 +>                 \-choicevariable ChoiceList \-default \{"Choice 2" "Choice 3"\} +>                 \-multiple\_selection 1 \-height 3\} \\ +>       __\-disjointlistbox__ \{\-label "Disjoined listbox" \-variable DisJntListbox +>                         \-choicevariable ChoiceList \\ +>                         \-default \{"Choice 3" "Choice 5"\} \-height 3\} \\ +>       __\-combobox__ \{\-label "Combobox" \-variable Combobox \\ +>                  \-choices \{1 2 3 4 5 6 7 8\} \-default 3\} \\ +>    __\-frame__ \{\-label "Checkbox, radiobox and checkbutton"\} \\ +>       __\-checkbox__ \{\-label Checkbox \-variable Checkbox +>                  \-choices \{bold italic underline\} \-choicelabels \{Bold Italic Underline\} \\ +>                  \-default italic\} \\ +>       __\-radiobox__ \{\-label Radiobox \-variable Radiobox +>                  \-choices \{bold italic underline\} \-choicelabels \{Bold Italic Underline\} \\ +>                  \-default underline\} \\ +>       __\-checkbutton__ \{\-label CheckButton \-variable Checkbutton \-default 1\} \\ +>    __\-frame__ \{\-label "Files & directories"\} \\ +>       __\-existingfile__ \{\-label "Input file" \-variable InputFile\} \\ +>       __\-file__ \{\-label "Output file" \-variable OutputFile\} \\ +>       __\-sep__ \{\} \\ +>       __\-existingdirectory__ \{\-label "Input directory" \-variable InputDirectory\} \\ +>       __\-directory__ \{\-label "Output irectory" \-variable OutputDirectory\} \\ +>    __\-frame__ \{\-label "Colors and fonts"\} \\ +>       __\-color__ \{\-label "Background color" \-variable Color \-default red\} \\ +>       __\-sep__ \{\} \\ +>       __\-font__ \{\-label "Font" \-variable Font \-default \{Courier 12 italic\}\}\] + +The __argument\_dialogbox__ defines all the specified variables with the entered data and returns __ok__ if the data have been validated via the Ok button\. If the data entry is cancelled by activating the Cancel button, the __argument\_dialogbox__ returns __cancel__\. - if {$Result=="cancel"} { - puts "Canceled" - } else { # $Result=="ok" - puts "Arguments: " - foreach Var { - Entry1 Entry2 - Listbox1 Listbox2 DisJntListbox - Combobox Checkbox Radiobox Checkbutton - InputFile OutputFile InputDirectory OutputDirectory - Color Font - } { - puts " $Var: '[set $Var]'" - } - } - -*\-> Arguments: Entry1: 'Hello, this is a trial' Entry2: 'my default' Listbox1: -'1' Listbox2: '\{Choice 2\} \{Choice 3\}' DisJntListbox: '\{Choice 3\} \{Choice 5\}' -Combobox: '3' Checkbox: 'italic' Radiobox: 'underline' Checkbutton: '1' -InputFile: 'c:\\tepam\\in\.txt' OutputFile: 'c:\\tepam\\out\.txt' InputDirectory: -'c:\\tepam\\input' OutputDirectory: 'c:\\tepam\\output' Color: 'red' Font: 'Courier -12 italic'* +> if \{$Result=="cancel"\} \{ +>    puts "Canceled" +> \} else \{ \# $Result=="ok" +>    puts "Arguments: " +>    foreach Var \{ +>       Entry1 Entry2 +>       Listbox1 Listbox2 DisJntListbox +>       Combobox Checkbox Radiobox Checkbutton +>       InputFile OutputFile InputDirectory OutputDirectory +>       Color Font +>    \} \{ +>       puts " $Var: '\[set $Var\]'" +>    \} +> \} +> *\-> Arguments:* +>    *Entry1: 'Hello, this is a trial'* +>    *Entry2: 'my default'* +>    *Listbox1: '1'* +>    *Listbox2: '\{Choice 2\} \{Choice 3\}'* +>    *DisJntListbox: '\{Choice 3\} \{Choice 5\}'* +>    *Combobox: '3'* +>    *Checkbox: 'italic'* +>    *Radiobox: 'underline'* +>    *Checkbutton: '1'* +>    *InputFile: 'c:\\tepam\\in\.txt'* +>    *OutputFile: 'c:\\tepam\\out\.txt'* +>    *InputDirectory: 'c:\\tepam\\input'* +>    *OutputDirectory: 'c:\\tepam\\output'* +>    *Color: 'red'* +>    *Font: 'Courier 12 italic'* # SEE ALSO [tepam::argument\_dialogbox\(n\)](tepam\_argument\_dialogbox\.md), [tepam::procedure\(n\)](tepam\_procedure\.md) Index: embedded/md/tcllib/files/modules/tepam/tepam_procedure.md ================================================================== --- embedded/md/tcllib/files/modules/tepam/tepam_procedure.md +++ embedded/md/tcllib/files/modules/tepam/tepam_procedure.md @@ -108,25 +108,25 @@ The __string__ command is an example of such a command that implements for example subcommands to check a character string length, to compare strings, to extract substrings, etc: - __string length__ *string* - __string compare__ *string* *string* - __string range__ *string* *first* *last* - ... + > __string length__ *string* + > __string compare__ *string* *string* + > __string range__ *string* *first* *last* + > \.\.\. TEPAM provides a framework that allows implementing easily such subcommands in form of Tcl procedures\. It allows not only defining a first level of subcommands, but also a higher level of subcommands\. The __string__ command class check could be implemented as independent sub\-sub\-commands of the __string__ command: - __string is alnum__ *string* - __string is integer__ *string* - __string is double__ *string* - ... + > __string is alnum__ *string* + > __string is integer__ *string* + > __string is double__ *string* + > \.\.\. - *Procedure attribute* TEPAM allows attaching to a declared procedure different kind of attributes\. Some of these attributes are *just* used for documentation purposes, but @@ -138,14 +138,13 @@ TEPAM uses the term *argument* for the parameters of a procedure\. The following example calls the subcommand __string compare__ with several arguments: - __string compare__ + > __string compare__ *\-nocase \-length 3 "emphasized" "emphasised"* - *\-nocase \-length 3 "emphasized" "emphasised"* The following paragraphs - discuss these different argument types\. + The following paragraphs discuss these different argument types\. - *Named argument* Some parameters, as *\-length 3* of the subcommand __string compare__ have to be provided as pairs of argument names and argument values\. This @@ -183,27 +182,26 @@ The __string compare__ command of the previous example requires that the *named arguments* \(options, flags\) are provided first\. The two mandatory \(unnamed\) arguments have to be provided as last argument\. - __string compare__ + > __string compare__ *\-nocase \-length 3 Water $Text* - *\-nocase \-length 3 Water $Text* This is the usual Tcl style \(exceptions - exist\) which is referred in the TEPAM documentation as *named arguments - first, unnamed arguments later style*\. + This is the usual Tcl style \(exceptions exist\) which is referred in the + TEPAM documentation as *named arguments first, unnamed arguments later + style*\. - *Unnamed arguments first, named arguments later* In contrast to most Tcl commands, Tk uses generally \(exceptions exist also here\) a different calling style where the *unnamed arguments* have to be provided first, before the *named arguments* have to be provided: - __pack__ + > __pack__ *\.ent1 \.ent2 \-fill x \-expand yes \-side left* - *\.ent1 \.ent2 \-fill x \-expand yes \-side left* This style is referred in the - TEPAM documentation as *unnamed arguments first, named arguments later - style*\. + This style is referred in the TEPAM documentation as *unnamed arguments + first, named arguments later style*\. # PROCEDURE DECLARATION TEPAM allows declaring new Tcl procedures with the command __tepam::procedure__ that has similar to the standard Tcl command @@ -211,31 +209,31 @@ - __tepam::procedure__ *name* *attributes* *body* The TEPAM procedure declaration syntax is demonstrated by the following example: - __tepam::procedure__ {display message} { - -short_description - "Displays a simple message box" - -description - "This procedure allows displaying a configurable\ - message box. The default message type that is\ - created is a warning, but also errors and info can\ - be generated. - The procedure accepts multiple text lines." - -example - {display message -mtype Warning "Save first your job"} - -args { - {-mtype -choices {Info Warning Error} \ - -default Warning -description "Message type"} - {text -type string -multiple \ - -description "Multiple text lines to display"} - } - } { - puts "Message type: $mtype" - puts "Message: $text" - } +> __tepam::procedure__ \{display message\} \{ +>    \-short\_description +>       "Displays a simple message box" +>    \-description +>       "This procedure allows displaying a configurable\\ +>        message box\. The default message type that is\\ +>        created is a warning, but also errors and info can\\ +>        be generated\. +>        The procedure accepts multiple text lines\." +>    \-example +>       \{display message \-mtype Warning "Save first your job"\} +>    \-args \{ +>       \{\-mtype \-choices \{Info Warning Error\} \\ +>               \-default Warning \-description "Message type"\} +>       \{text \-type string \-multiple \\ +>               \-description "Multiple text lines to display"\} +>    \} +> \} \{ +>    puts "Message type: $mtype" +>    puts "Message: $text" +> \} The 3 arguments of __procedure__ are: - *name* @@ -246,21 +244,21 @@ elements\. Here are some valid procedure declarations using different procedure names \(the attribute and body arguments are empty for simplicity\): - *# Simple procedure name:* - tepam::procedure __display_message__ {} {} - ** - *# Procedure declared in the main namespace:* - tepam::procedure __::display_message__ {} {} - ** - *# Procedure in the namespace* __::ns__*:* - tepam::procedure __::ns::display_message__ {} {} - ** - *# Declaration of the subcommand* __message__ *of the procedure* __display__*:* - tepam::procedure __{display message}__ {} {} +> *\# Simple procedure name:* +> tepam::procedure __display\_message__ \{\} \{\} +> ** +> *\# Procedure declared in the main namespace:* +> tepam::procedure __::display\_message__ \{\} \{\} +> ** +> *\# Procedure in the namespace* __::ns__*:* +> tepam::procedure __::ns::display\_message__ \{\} \{\} +> ** +> *\# Declaration of the subcommand* __message__ *of the procedure* __display__*:* +> tepam::procedure __\{display message\}__ \{\} \{\} - *attributes* All procedure attributes are provided in form of an option list that contains pairs of option names and option values\. The example above has as @@ -286,30 +284,30 @@ to the procedure body in form of variables\. The procedure body will only be executed if the provided set of arguments could be validated by the TEPAM argument manager\. - tepam::procedure {display_message} { - -args { - {-__mtype__ -default Warning -choices {Warning Error}} - {__text__ -type string} - } - } { - puts "Message type: __$mtype__" - puts "Message: __$text__" - } +> tepam::procedure \{display\_message\} \{ +>    \-args \{ +>       \{\-__mtype__ \-default Warning \-choices \{Warning Error\}\} +>       \{__text__ \-type string\} +>    \} +> \} \{ +>    puts "Message type: __$mtype__" +>    puts "Message: __$text__" +> \} The commands __[procedure](\.\./\.\./\.\./\.\./index\.md\#procedure)__ as well as __argument\_dialogbox__ are exported from the namespace __tepam__\. To use these commands without the __tepam::__ namespace prefix, it is sufficient to import them into the main namespace: - __namespace import tepam::*__ - - __[procedure](../../../../index.md#procedure)__ {display_message} { - -args { - ... +> __namespace import tepam::\*__ +> +> __[procedure](\.\./\.\./\.\./\.\./index\.md\#procedure)__ \{display\_message\} \{ +>    \-args \{ +>       \.\.\. ## Procedure Attributes The first group of attributes affect the behavior of the declared procedure: @@ -365,16 +363,16 @@ Custom argument validations can be performed via specific validation commands that are defined with the *\-validatecommand* attribute\. Validation command declaration example: - tepam::procedure {display_message} { - -args { - {text -type string -description "Message text"} } - __-validatecommand {IllegalWordDetector $text}__ - } { - } +> tepam::procedure \{display\_message\} \{ +>    \-args \{ +>       \{text \-type string \-description "Message text"\} \} +>    __\-validatecommand \{IllegalWordDetector $text\}__ +> \} \{ +> \} The validation command is executed in the context of the declared procedure body\. The different argument values are accessed via the argument names\. Note there is also an argument attribute *\-validatecommand* that allows declaring custom checks for specific arguments\. @@ -435,33 +433,35 @@ ## Argument Declaration The following example shows the structure that is used for the argument definitions in the context of a procedure declaration: - tepam::procedure {display_message} { - -args __{ - {-mtype -default Warning -choices {Info Warning Error} -description "Message type"} - {-font -type font -default {Arial 10 italic} -description "Message text font"} - {-level -type integer -optional -range {1 10} -description "Message level"} - {-fg -type color -optional -description "Message color"} - {-log_file -type file -optional -description "Optional message log file"} - {text -type string -multiple -description "Multiple text lines to display"} - }__ - } { - } +> tepam::procedure \{display\_message\} \{ +>    \-args __\{__ +>       __\{\-mtype \-default Warning \-choices \{Info Warning Error\} \-description "Message type"\}__ +>       __\{\-font \-type font \-default \{Arial 10 italic\} \-description "Message text font"\}__ +>       __\{\-level \-type integer \-optional \-range \{1 10\} \-description "Message level"\}__ +>       __\{\-fg \-type color \-optional \-description "Message color"\}__ +>       __\{\-log\_file \-type file \-optional \-description "Optional message log file"\}__ +>       __\{text \-type string \-multiple \-description "Multiple text lines to display"\}__ +>    __\}__ +> +> \} \{ +> \} Each of the procedure arguments is declared with a list that has as first element the argument name, followed by eventual attributes\. The argument definition syntax can be formalized in the following way: - tepam::procedure { - -args __{ - { ...} - { ...} - ... - }__ - } +> tepam::procedure \{ +>    \-args __\{__ +>       __\{ \.\.\.\}__ +>       __\{ \.\.\.\}__ +>       __\.\.\.__ +>    __\}__ +> +> \} The argument names and attributes have to be used in the following way: - Argument name \(*>*\) @@ -475,39 +475,37 @@ This is the simplest form of an argument name: An argument whose name is not starting with '\-' is an *unnamed argument*\. The parameter provided during a procedure call will be assigned to a variable with the name **\. - tepam::procedure {print_string} { - -args { - {__[text](../../../../index.md#text)__ -type string -description "This is an unnamed argument"} - } - } { - puts __$text__ - } - - print_string __"Hello"__ - - * \-> Hello* +> tepam::procedure \{print\_string\} \{ +>    \-args \{ +>       \{__[text](\.\./\.\./\.\./\.\./index\.md\#text)__ \-type string \-description "This is an unnamed argument"\} +>    \} +> \} \{ +>    puts __$text__ +> \} +> +> print\_string __"Hello"__ +>  *\-> Hello* * *"\-"* An argument whose name starts with '\-' is a *named argument* \(also called *option*\)\. The parameter provided during a procedure call will be assigned to a variable with the name ** \(not *\-*\)\. - tepam::procedure {print_string} { - -args { - {__-text__ -type string -description "This is a named argument"} - } - } { - puts __$text__ - } - - print_string __-text "Hello"__ - - * \-> Hello* +> tepam::procedure \{print\_string\} \{ +>    \-args \{ +>       \{__\-text__ \-type string \-description "This is a named argument"\} +>    \} +> \} \{ +>    puts __$text__ +> \} +> +> print\_string __\-text "Hello"__ +>  *\-> Hello* * *"\-\-"* This flag allows clearly specifying the end of the named arguments and the beginning of the unnamed arguments, in case the *named arguments @@ -521,23 +519,23 @@ * *"\-"* or *""* A blank argument name \(either '\-' or *''*\) starts a comment for the following arguments\. - tepam::procedure {print_time} { - -interactive_display_format short - -args { - {hours -type integer -description "Hour"} - {minutes -type integer -description "Minute"} - - __{- The following arguments are optional:}__ - {seconds -type integer -default 0 -description "Seconds"} - {milliseconds -type integer -default 0 -description "Milliseconds"} - } - } { - puts "${hour}h${minutes}:[expr $seconds+0.001*$milliseconds]" - } +> tepam::procedure \{print\_time\} \{ +>    \-interactive\_display\_format short +>    \-args \{ +>       \{hours \-type integer \-description "Hour"\} +>       \{minutes \-type integer \-description "Minute"\} +> +>       __\{\- The following arguments are optional:\}__ +>       \{seconds \-type integer \-default 0 \-description "Seconds"\} +>       \{milliseconds \-type integer \-default 0 \-description "Milliseconds"\} +>    \} +> \} \{ +>    puts "$\{hour\}h$\{minutes\}:\[expr $seconds\+0\.001\*$milliseconds\]" +> \} Argument comments are basically used in the graphical argument definition forms that are created if a procedure is called interactively\. @@ -549,24 +547,24 @@ Section comments can be used to structure visually the argument definition code\. Section comments are also used to structure the generated help texts and the interactive argument definition forms\. - tepam::procedure {complex_multiply} { - -description "This function perform a complex multiplication" - -args { - __{#### First complex number ####}__ - {-r0 -type double -description "First number real part"} - {-i0 -type double -description "First number imaginary part"} - - __{#### Second complex number ####}__ - {-r1 -type double -description "Second number real part"} - {-i1 -type double -description "Second number imaginary part"} - } - } { - return [expr $r0*$r1 - $i0*$i1] - } +> tepam::procedure \{complex\_multiply\} \{ +>    \-description "This function perform a complex multiplication" +>    \-args \{ +>       __\{\#\#\#\# First complex number \#\#\#\#\}__ +>       \{\-r0 \-type double \-description "First number real part"\} +>       \{\-i0 \-type double \-description "First number imaginary part"\} +> +>       __\{\#\#\#\# Second complex number \#\#\#\#\}__ +>       \{\-r1 \-type double \-description "Second number real part"\} +>       \{\-i1 \-type double \-description "Second number imaginary part"\} +>    \} +> \} \{ +>    return \[expr $r0\*$r1 \- $i0\*$i1\] +> \} - Argument attributes \(*> >*\) The following argument attributes are supported: @@ -653,16 +651,16 @@ which the pattern *%P* is replaced by the argument value that has to be validated\. Validation command declaration example: - tepam::procedure {display_message} { - -args { - {text -type string -description "Message text" \ - __-validatecommand {IllegalWordDetector %P}__} - } { - } +> tepam::procedure \{display\_message\} \{ +>    \-args \{ +>       \{text \-type string \-description "Message text" \\ +>             __\-validatecommand \{IllegalWordDetector %P\}__\} +> \} \{ +> \} While the purpose of this custom argument validation attribute is the validation of a specific argument, there is also a global attribute *\-validatecommand* that allows performing validation that involves multiple arguments\. @@ -684,27 +682,27 @@ In case a procedure is called interactively, additional argument attributes can be provided to the interactive argument definition form via the *\-auxargs* attribute that is itself a list of attribute name/attribute value pairs: - -auxargs {- \ - - - ... - } + -auxargs {- \ + - + ... + } For example, if a procedure takes as argument a file name it may be beneficial to specify the required file type for the interactive argument definition form\. This information can be provided via the *\-auxargs* attribute to the argument definition form: - tepam::procedure LoadPicture { - -args { - {FileName -type existingfile -description "Picture file" \ - __-auxargs {-filetypes {{"GIF" {*.gif}} {"JPG" {*.jpg}} }}__} - } - } { - } +> tepam::procedure LoadPicture \{ +>    \-args \{ +>       \{FileName \-type existingfile \-description "Picture file" \\ +>                  __\-auxargs \{\-filetypes \{\{"GIF" \{\*\.gif\}\} \{"JPG" \{\*\.jpg\}\} \}\}__\} +>    \} +> \} \{ +> \} * \-auxargs\_commands *script* If the auxiliary argument attributes are not static but have to be dynamically adaptable, the *\-auxargs\_commands* allows defining them @@ -711,14 +709,14 @@ via commands that are executed during a procedure call\. A list of pairs of auxiliary attribute names and commands has to be provided to the *\-auxargs\_commands* attribute\. The provided commands are executed in the context of the calling procedure\. - -auxargs_commands {- \ - - - ... - } + -auxargs_commands {- \ + - + ... + } # VARIABLES Several variables defined inside the __::tepam__ namespace impact the mode of operation of the procedures that have been declared with the TEPAM @@ -731,11 +729,11 @@ arguments later* style \(Tcl style\)\. By setting this variable to __0__, the *named arguments first, unnamed arguments later* style is globally selected \(Tk style\): - set tepam::named_arguments_first 0 + set tepam::named_arguments_first 0 While this variable defines the general calling style, the procedure attribute *\-named\_arguments\_first* can adapt this style individually for each declared procedure\. @@ -747,11 +745,11 @@ argument names\. By setting this variable to __0__ the automatic argument name matching mode is disabled: - set tepam::auto_argument_name_completion 0 + set tepam::auto_argument_name_completion 0 While this variable defines the general matching mode, the procedure attribute *\-auto\_argument\_name\_completion* can adapt this mode individually for each declared procedure\. @@ -765,11 +763,11 @@ There are two display modes for these interactive forms\. The *extended* mode which is the default mode is more adapted for small procedure argument sets\. The __short__ form is more adequate for huge procedure argument sets: - set tepam::interactive_display_format "short" + set tepam::interactive_display_format "short" The choice to use short or extended forms can be globally configured via the variable __interactive\_display\_format__\. This global setting can be changed individually for a procedure with the procedure attribute *\-interactive\_display\_format*\. @@ -778,11 +776,11 @@ The maximum line length used by the procedure help text generator can be specified with this variable\. The default length which is set to 80 \(characters\) can easily be adapted to the need of an application: - set tepam::help_line_length 120 + set tepam::help_line_length 120 Since this variable is applied directly during the help text generation, its value can continuously be adapted to the current need\. - __command\_log__ @@ -810,20 +808,20 @@ ## Predefined Argument Types To remember, a type can be assigned to each specified procedure argument: - tepam::procedure {warning} { - -args { - {-font __-type font__ -default {Arial 10 italic}} - {-severity_level __-type integer__ -optional -range {1 10}} - {-fg __-type color__ -optional -description "Message color"} - {text __-type string__ -multiple -description "Multiple text lines to display"} - } - } { - ... - } +> tepam::procedure \{warning\} \{ +>    \-args \{ +>       \{\-font __\-type font__ \-default \{Arial 10 italic\}\} +>       \{\-severity\_level __\-type integer__ \-optional \-range \{1 10\}\} +>       \{\-fg __\-type color__ \-optional \-description "Message color"\} +>       \{text __\-type string__ \-multiple \-description "Multiple text lines to display"\} +>    \} +> \} \{ +>    \.\.\. +> \} There are some *special purpose types* that are building the first category of predefined argument types: - __none__ A *flag*, also called *switch*, is defined as a named @@ -830,24 +828,23 @@ argument that has the type __none__\. Flags are always optional and the default value of the assigned variable is set to __0__\. In contrast to the \(normal\) named arguments, no argument value has to be provided to a flag\. - tepam::procedure flag_test { - -args { - __{-flag -type none -description "This is a flag"}__ - } - } { - puts __$flag__ - } - - flag_test - *-> 0* - - flag_test -flag - - *\-> 1* +> tepam::procedure flag\_test \{ +>    \-args \{ +>       __\{\-flag \-type none \-description "This is a flag"\}__ +>    \} +> \} \{ +>    puts __$flag__ +> \} +> +> flag\_test +> *\-> 0* +> +> flag\_test \-flag +> *\-> 1* Since no argument value has to be provided to a flag, also no data check is performed for this argument type\. - __string__ __String__ is a generic argument data type\. Any data @@ -871,13 +868,11 @@ are using the __string is \-strict__ commands to check the validity of the provided arguments, which assures that no empty strings are accepted as argument value\. The type validation expression for the numerical types and the argument types to which this expression is applied are: - string is ____ -strict - -** +> string is ____ \-strict ** - *boolean* - *integer* @@ -885,13 +880,11 @@ Empty strings are accepted as argument value for all the alpha numeric argument types\. The argument types that are falling into this category and validation expression used for them are: - string is ** - -** +> string is ** ** - *alnum* - *alpha* @@ -921,54 +914,48 @@ commands, TEPAM specifies some other useful data types: - *char* Each string that has a length of 1 character meets the *character* type\. The type check is made with the following expression: - expr [string length **]==1 +> expr \[string length **\]==1 - *color* Any character strings that are accepted by Tk as a color are considered as valid color argument\. Please note that the Tk package has to be loaded to use the type *color*\. TEPAM is using the following command to validate the color type: - expr ![catch {winfo rgb . **} - - \] +> expr \!\[catch \{winfo rgb \. **\}\] - *font* Any character strings that are accepted by Tk as a font are considered as valid font argument\. Please note that the Tk package has to be loaded to use the *font* type\. TEPAM is using the following command to validate the color type: - expr ![catch {font measure ""} - - \] + expr ![catch {font measure ""}] - *file* Any strings that are not containing one of the following characters are considered as valid file names: \* ? " < >\. It is not necessary that the file and its containing directory exist\. Zero\-length strings are not considered as valid file names\. The following expression is used to validate the file names: - expr [string length ]>0 && ![regexp {[\"*?<>:]} - - \] + expr [string length ]>0 && ![regexp {[\"*?<>:]} ] - *existingfile* The argument is valid if it matches with an existing file\. The following check is performed to validate the arguments of this type: - file exists + file exists - *directory* The directory argument is validated exactly in the same way as the file arguments\. - *existingdirectory* The argument is valid if it matches with an existing directory\. The following check is performed to validate the arguments of this type: - file isdirectory + file isdirectory ## Defining Application Specific Argument Types To add support for a new application specific argument type it is just necessary to add into the namespace __tepam__ a validation function @@ -995,47 +982,57 @@ performing any additional actions\. Taking the first procedure declared in [PROCEDURE CALLS](#section6), the help request and the printed help text would be: - __display message -help__ - -*\-> NAME display message \- Displays a simple message box SYNOPSIS display -message \[\-mtype \] Message type, default: "Warning", choices: \{Info, -Warning, Error\} Multiple text lines to display, type: string DESCRIPTION -This procedure allows displaying a configurable message box\. The default message -type that is created is a warning, but also errors and info can be generated\. -The procedure accepts multiple text lines\. EXAMPLE display message \-mtype -Warning "Save first your job"* The argument manager is checking if the last -provided argument is *\-help* and generates the requested help message if this -is the case\. So, also the following example will print the help message: - -__display message \-mtype Info "It is 7:00" \-help__ On the other hand, the -following call will result in an error: - - __display message -help -mtype Info "It is 7:00"__ - -*\-> display message: Argument '\-help' not known* +> __display message \-help__ +> *\->* +> *NAME* +>       *display message \- Displays a simple message box* +> *SYNOPSIS* +>       *display message* +>             *\[\-mtype \]* +>                *Message type, default: "Warning", choices: \{Info, Warning, Error\}* +>             ** +>                *Multiple text lines to display, type: string* +> *DESCRIPTION* +>       *This procedure allows displaying a configurable message box\. The default* +>       *message type that is created is a warning, but also errors and info can* +>       *be generated\.* +>       *The procedure accepts multiple text lines\.* +> *EXAMPLE* +>       *display message \-mtype Warning "Save first your job"* + +The argument manager is checking if the last provided argument is *\-help* and +generates the requested help message if this is the case\. So, also the following +example will print the help message: + +> __display message \-mtype Info "It is 7:00" \-help__ + +On the other hand, the following call will result in an error: + +> __display message \-help \-mtype Info "It is 7:00"__ +> *\->* +> *display message: Argument '\-help' not known* ## Interactive Procedure Call If Tk has been loaded a procedure can be called with the *\-interactive* flag to open a graphical form that allows specifying interactively all procedure arguments\. The following example assures that the Tk library is loaded and shows the command line to call interactively the procedure declared in [PROCEDURE CALLS](#section6): - package require Tk - -__display message \-interactive__ Also the *\-interactive* flag has to be -placed at the last argument position as this is also required for the *\-help* -flag\. Arguments defined before the *\-interactive* flag will be ignored\. The -following example is therefore also a valid interactive procedure call: - - __display message__ -mtype Info "It is 7:00" - -__\-interactive__ +> package require Tk +> __display message \-interactive__ + +Also the *\-interactive* flag has to be placed at the last argument position as +this is also required for the *\-help* flag\. Arguments defined before the +*\-interactive* flag will be ignored\. The following example is therefore also a +valid interactive procedure call: + +> __display message__ \-mtype Info "It is 7:00" __\-interactive__ ## Unnamed Arguments Unnamed arguments are typically provided to the called procedure as simple parameters\. This procedure calling form requires that the provided arguments are @@ -1052,31 +1049,31 @@ puts "$mtype: [join $text]" } \.\.\. can for example be called in the following ways: - __display_message Info "It is PM 7:00."__ - *-> Info: It is PM 7:00.* - - __display_message Info "It is PM 7:00." "You should go home."__ - -*\-> Info: It is PM 7:00\. You should go home\.* The nice thing is that unnamed -arguments can also be called as named arguments, which can be handy, for example -if the exact specified argument order is not known to a user: - - __display_message -mtype Info -text "It is PM 7:00."__ - *-> Info: It is PM 7:00.* - - __display_message -text "It is PM 7:00." -mtype Info__ - *-> Info: It is PM 7:00.* - - __display_message -mtype Info -text "It is PM 7:00." -text "You should go home."__ - *-> Info: It is PM 7:00. You should go home.* - - __display_message -text "It is PM 7:00." -text "You should go home." -mtype Info__ - -*\-> Info: It is PM 7:00\. You should go home\.* +> __display\_message Info "It is PM 7:00\."__ +> *\-> Info: It is PM 7:00\.* +> +> __display\_message Info "It is PM 7:00\." "You should go home\."__ +> *\-> Info: It is PM 7:00\. You should go home\.* + +The nice thing is that unnamed arguments can also be called as named arguments, +which can be handy, for example if the exact specified argument order is not +known to a user: + +> __display\_message \-mtype Info \-text "It is PM 7:00\."__ +> *\-> Info: It is PM 7:00\.* +> +> __display\_message \-text "It is PM 7:00\." \-mtype Info__ +> *\-> Info: It is PM 7:00\.* +> +> __display\_message \-mtype Info \-text "It is PM 7:00\." \-text "You should go home\."__ +> *\-> Info: It is PM 7:00\. You should go home\.* +> +> __display\_message \-text "It is PM 7:00\." \-text "You should go home\." \-mtype Info__ +> *\-> Info: It is PM 7:00\. You should go home\.* ## Named Arguments Named arguments have to be provided to a procedure in form of a parameter pairs composed by the argument names and the argument values\. The order how they are @@ -1094,120 +1091,118 @@ puts "$mtype: [join $text]" } \.\.\. can be called in the following ways: - __display_message -mtype Info -text "It is PM 7:00."__ - *-> Info: It is PM 7:00.* - - __display_message -text "It is PM 7:00." -mtype Info__ - *-> Info: It is PM 7:00.* - - __display_message -mtype Info -text "It is PM 7:00." -text "You should go home."__ - *-> Info: It is PM 7:00. You should go home.* - - __display_message -text "It is PM 7:00." -text "You should go home." -mtype Info__ - -*\-> Info: It is PM 7:00\. You should go home\.* Also named arguments that have -not the *\-multiple* attribute can be provided multiple times\. Only the last -provided argument will be retained in such a case: - - __display_message -mtype Info -text "It is PM 7:00." -mtype Warning__ - -*\-> Warning: It is PM 7:00\.* +> __display\_message \-mtype Info \-text "It is PM 7:00\."__ +> *\-> Info: It is PM 7:00\.* +> +> __display\_message \-text "It is PM 7:00\." \-mtype Info__ +> *\-> Info: It is PM 7:00\.* +> +> __display\_message \-mtype Info \-text "It is PM 7:00\." \-text "You should go home\."__ +> *\-> Info: It is PM 7:00\. You should go home\.* +> +> __display\_message \-text "It is PM 7:00\." \-text "You should go home\." \-mtype Info__ +> *\-> Info: It is PM 7:00\. You should go home\.* + +Also named arguments that have not the *\-multiple* attribute can be provided +multiple times\. Only the last provided argument will be retained in such a case: + +> __display\_message \-mtype Info \-text "It is PM 7:00\." \-mtype Warning__ +> *\-> Warning: It is PM 7:00\.* ## Unnamed Arguments First, Named Arguments Later \(Tk Style\) A procedure that has been defined while the variable __tepam::named\_arguments\_first__ was set to 1, or with the procedure attribute *\-named\_arguments\_first* set to 1 has to be called in the Tcl style\. The following procedure declaration will be used in this section to illustrate the meaning of this calling style: - __set tepam::named_arguments_first 1__ - tepam::procedure my_proc { - -args { - {-n1 -default ""} - {-n2 -default ""} - {u1 -default ""} - {u2 -default ""} - } - } { - puts "n1:'$n1', n2:'$n2', u1:'$u1', u2:'$u2'" - } +> __set tepam::named\_arguments\_first 1__ +> tepam::procedure my\_proc \{ +>    \-args \{ +>       \{\-n1 \-default ""\} +>       \{\-n2 \-default ""\} +>       \{u1 \-default ""\} +>       \{u2 \-default ""\} +>    \} +> \} \{ +>    puts "n1:'$n1', n2:'$n2', u1:'$u1', u2:'$u2'" +> \} The unnamed arguments are placed at the end of procedure call, after the named arguments: - my_proc __-n1 N1 -n2 N2 U1 U2__ - -*\-> n1:'N1', n2:'N2', u1:'U1', u2:'U2'* The argument parser considers the -first argument that doesn't start with the '\-' character as well as all -following arguments as unnamed argument: - - my_proc __U1 U2__ - -*\-> n1:'', n2:'', u1:'U1', u2:'U2'* Named arguments can be defined multiple -times\. If the named argument has the *\-multiply* attribute, all argument -values will be collected in a list\. Otherwise, only the last provided attribute -value will be retained: - - my_proc __-n1 N1 -n2 N2 -n1 M1 U1 U2__ - -*\-> n1:'M1', n2:'N2', u1:'U1', u2:'U2'* The name of the first unnamed argument -has therefore not to start with the '\-' character\. The unnamed argument is -otherwise considered as name of another named argument\. This is especially -important if the first unnamed argument is given by a variable that can contain -any character strings: - - my_proc __-n1 N1 -n2 N2 "->" "<-"__ - *-> my_proc: Argument '->' not known* - - set U1 "->" - my_proc __-n1 N1 -n2 N2 $U1 U2__ - my_proc: Argument '->' not known +> my\_proc __\-n1 N1 \-n2 N2 U1 U2__ +> *\-> n1:'N1', n2:'N2', u1:'U1', u2:'U2'* + +The argument parser considers the first argument that doesn't start with the '\-' +character as well as all following arguments as unnamed argument: + +> my\_proc __U1 U2__ +> *\-> n1:'', n2:'', u1:'U1', u2:'U2'* + +Named arguments can be defined multiple times\. If the named argument has the +*\-multiply* attribute, all argument values will be collected in a list\. +Otherwise, only the last provided attribute value will be retained: + +> my\_proc __\-n1 N1 \-n2 N2 \-n1 M1 U1 U2__ +> *\-> n1:'M1', n2:'N2', u1:'U1', u2:'U2'* + +The name of the first unnamed argument has therefore not to start with the '\-' +character\. The unnamed argument is otherwise considered as name of another named +argument\. This is especially important if the first unnamed argument is given by +a variable that can contain any character strings: + +> my\_proc __\-n1 N1 \-n2 N2 "\->" "<\-"__ +> *\-> my\_proc: Argument '\->' not known* +> +> set U1 "\->" +> my\_proc __\-n1 N1 \-n2 N2 $U1 U2__ +> my\_proc: Argument '\->' not known The '\-\-' flag allows separating unambiguously the unnamed arguments from the named arguments\. All data after the '\-\-' flag will be considered as unnamed argument: - my_proc __-n1 N1 -n2 N2 -- "->" "<-"__ - *-> n1:'N1', n2:'N2', u1:'->', u2:'<-'* - - set U1 "->" - my_proc __-n1 N1 -n2 N2 -- $U1 U2__ - -*\-> n1:'N1', n2:'N2', u1:'\->', u2:'<\-'* +> my\_proc __\-n1 N1 \-n2 N2 \-\- "\->" "<\-"__ +> *\-> n1:'N1', n2:'N2', u1:'\->', u2:'<\-'* +> +> set U1 "\->" +> my\_proc __\-n1 N1 \-n2 N2 \-\- $U1 U2__ +> *\-> n1:'N1', n2:'N2', u1:'\->', u2:'<\-'* ## Named Arguments First, Unnamed Arguments Later \(Tcl Style\) The Tk calling style will be chosen if a procedure is defined while the variable __tepam::named\_arguments\_first__ is set to 0, or if the procedure attribute *\-named\_arguments\_first* has been set to 0\. The following procedure will be used in this section to illustrate this calling style: - __set tepam::named_arguments_first 0__ - tepam::procedure my_proc { - -args { - {-n1 -default ""} - {-n2 -default ""} - {u1} - {u2 -default "" -multiple} - } - } { - puts "n1:'$n1', n2:'$n2', u1:'$u1', u2:'$u2'" - } +> __set tepam::named\_arguments\_first 0__ +> tepam::procedure my\_proc \{ +>    \-args \{ +>       \{\-n1 \-default ""\} +>       \{\-n2 \-default ""\} +>       \{u1\} +>       \{u2 \-default "" \-multiple\} +>    \} +> \} \{ +>    puts "n1:'$n1', n2:'$n2', u1:'$u1', u2:'$u2'" +> \} The unnamed arguments have to be provided first in this case\. The named arguments are provided afterwards: - my_proc __U1 U2 -n1 N1 -n2 N2__ +> my\_proc __U1 U2 \-n1 N1 \-n2 N2__ +> *\-> n1:'N1', n1:'N1', u1:'U1', u2:'U2'* -*\-> n1:'N1', n1:'N1', u1:'U1', u2:'U2'* The argument parser will assign to -each defined unnamed argument a value before it switches to read the named -arguments\. This default behavior changes a bit if there are unnamed arguments -that are optional or that can take multiple values\. +The argument parser will assign to each defined unnamed argument a value before +it switches to read the named arguments\. This default behavior changes a bit if +there are unnamed arguments that are optional or that can take multiple values\. An argument value will only be assigned to an unnamed argument that is optional \(that has either the *\-optional* attribute or that has a default value\), if the value is not beginning with the '\-' character or if no named arguments are defined\. The value that starts with '\-' is otherwise considered as the name of a @@ -1224,85 +1219,87 @@ Let's explore in a bit less theoretically the ways how the previously defined procedure can be called: The first example calls the procedure without any parameters, which leads to an error since *u1* is a mandatory argument: - my_proc - -*\-> my\_proc: Required argument is missing: u1* The procedure call is valid if -one parameter is provided for *u1*: - - my_proc __U1__ - -*\-> n1:'', n2:'', u1:'U1', u2:''* If more parameters are provided that are not -starting with the '\-' character, they will be attributed to the unnamed -arguments\. *U2* will receive 3 of these parameters, since it accepts multiple -values: - - my_proc __U1 U2 U3 U4__ - -*\-> n1:'', n2:'', u1:'U1', u2:'U2 U3 U4'* As soon as one parameter starts with -'\-' and all unnamed arguments have been assigned, the argument manager tries to -interpret the parameter as name of a named argument\. The procedure call will -fail if a value beginning with '\-' is assigned to an unnamed argument: - - my_proc __U1 U2 U3 U4 -U5__ - -*\-> my\_proc: Argument '\-U5' not known* The attribution of a parameter to a -named argument will fail if there are undefined unnamed \(non optional\) -arguments\. The name specification will in this case simply be considered as a -parameter value that is attributed to the *next* unnamed argument\. This was -certainly not the intention in the following example: - - my_proc __-n1 N1__ - -*\-> n1:'', n2:'', u1:'\-n1', u2:'N1'* The situation is completely different if -values have already been assigned to all mandatory unnamed arguments\. A -parameter beginning with the '\-' character will in this case be considered as a -name identifier for a named argument: - - my_proc __U1 -n1 N1__ - -*\-> n1:'N1', n2:'', u1:'U1', u2:''* No unnamed arguments are allowed behind +> my\_proc +> *\-> my\_proc: Required argument is missing: u1* + +The procedure call is valid if one parameter is provided for *u1*: + +> my\_proc __U1__ +> *\-> n1:'', n2:'', u1:'U1', u2:''* + +If more parameters are provided that are not starting with the '\-' character, +they will be attributed to the unnamed arguments\. *U2* will receive 3 of these +parameters, since it accepts multiple values: + +> my\_proc __U1 U2 U3 U4__ +> *\-> n1:'', n2:'', u1:'U1', u2:'U2 U3 U4'* + +As soon as one parameter starts with '\-' and all unnamed arguments have been +assigned, the argument manager tries to interpret the parameter as name of a +named argument\. The procedure call will fail if a value beginning with '\-' is +assigned to an unnamed argument: + +> my\_proc __U1 U2 U3 U4 \-U5__ +> *\-> my\_proc: Argument '\-U5' not known* + +The attribution of a parameter to a named argument will fail if there are +undefined unnamed \(non optional\) arguments\. The name specification will in this +case simply be considered as a parameter value that is attributed to the +*next* unnamed argument\. This was certainly not the intention in the following +example: + +> my\_proc __\-n1 N1__ +> *\-> n1:'', n2:'', u1:'\-n1', u2:'N1'* + +The situation is completely different if values have already been assigned to +all mandatory unnamed arguments\. A parameter beginning with the '\-' character +will in this case be considered as a name identifier for a named argument: + +> my\_proc __U1 \-n1 N1__ +> *\-> n1:'N1', n2:'', u1:'U1', u2:''* + +No unnamed arguments are allowed behind the named arguments: + +> my\_proc __U1 \-n1 N1 U2__ +> *\-> my\_proc: Argument 'U2' is not an option* + +The '\-\-' flag has no special meaning if not all mandatory arguments have got +assigned a value\. This flag will simply be attributed to one of the unnamed +arguments: + +> my\_proc __\-\- \-n1 N1__ +> *\-> n1:'N1', n2:'', u1:'\-\-', u2:''* + +But the '\-\-' flag is simply ignored if the argument parser has started to handle the named arguments: - my_proc __U1 -n1 N1 U2__ - -*\-> my\_proc: Argument 'U2' is not an option* The '\-\-' flag has no special -meaning if not all mandatory arguments have got assigned a value\. This flag will -simply be attributed to one of the unnamed arguments: - - my_proc __-- -n1 N1__ - -*\-> n1:'N1', n2:'', u1:'\-\-', u2:''* But the '\-\-' flag is simply ignored if the -argument parser has started to handle the named arguments: - - my_proc __U1 -- -n1 N1__ - *-> n1:'N1', n2:'', u1:'U1', u2:''* - - my_proc __U1 -n1 N1 -- -n2 N2__ - -*\-> n1:'N1', n2:'N2', u1:'U1', u2:''* +> my\_proc __U1 \-\- \-n1 N1__ +> *\-> n1:'N1', n2:'', u1:'U1', u2:''* +> +> my\_proc __U1 \-n1 N1 \-\- \-n2 N2__ +> *\-> n1:'N1', n2:'N2', u1:'U1', u2:''* ## Raw Argument List It may be necessary sometimes that the procedure body is able to access the entire list of arguments provided during a procedure call\. This can happen via the __args__ variable that contains always the unprocessed argument list: - tepam::procedure {display_message} { - -args { - {-mtype -choices {Warning Error} -default Warning} - {text -type string -multiple} - - } - } { - puts "args: __$args__" - } - display_message -mtype Warning "It is 7:00" - -*\-> args: \-mtype Warning \{It is 7:00\}* +> tepam::procedure \{display\_message\} \{ +>    \-args \{ +>       \{\-mtype \-choices \{Warning Error\} \-default Warning\} +>       \{text \-type string \-multiple\} +> +>    \} +> \} \{ +>    puts "args: __$args__" +> \} +> display\_message \-mtype Warning "It is 7:00" +> *\-> args: \-mtype Warning \{It is 7:00\}* # SEE ALSO [tepam\(n\)](tepam\_introduction\.md), [tepam::argument\_dialogbox\(n\)](tepam\_argument\_dialogbox\.md) Index: embedded/md/tcllib/files/modules/textutil/expander.md ================================================================== --- embedded/md/tcllib/files/modules/textutil/expander.md +++ embedded/md/tcllib/files/modules/textutil/expander.md @@ -128,11 +128,11 @@ whose name is *expanderName*\. This command may be used to invoke various operations on the graph\. If the *expanderName* is not fully qualified it is interpreted as relative to the current namespace\. The command has the following general form: - *expanderName* option ?*arg arg ...*? + > *expanderName* option ?*arg arg \.\.\.*? *Option* and the *arg*s determine the exact behavior of the command\. The following commands are possible for expander objects: Index: embedded/md/tcllib/files/modules/treeql/treeql.md ================================================================== --- embedded/md/tcllib/files/modules/treeql/treeql.md +++ embedded/md/tcllib/files/modules/treeql/treeql.md @@ -1,11 +1,11 @@ [//000000001]: # (treeql \- Tree Query Language) [//000000002]: # (Generated from file 'treeql\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2004 Colin McCormack -Copyright © 2004 Andreas Kupries ) -[//000000004]: # (treeql\(n\) 1\.3\.1 tcllib "Tree Query Language") +[//000000003]: # (Copyright © 2004 Colin McCormack ) +[//000000004]: # (Copyright © 2004 Andreas Kupries ) +[//000000005]: # (treeql\(n\) 1\.3\.1 tcllib "Tree Query Language")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | EXAMPLES - __throw__ {MYERROR CODE} "My error message" +> __throw__ \{MYERROR CODE\} "My error message" # Bugs, Ideas, Feedback This document, and the package it describes, will undoubtedly contain bugs and other problems\. Please report such in the category *try* of the [Tcllib Index: embedded/md/tcllib/files/modules/try/tcllib_try.md ================================================================== --- embedded/md/tcllib/files/modules/try/tcllib_try.md +++ embedded/md/tcllib/files/modules/try/tcllib_try.md @@ -108,27 +108,27 @@ # EXAMPLES Ensure that a file is closed no matter what: - set f [open /some/file/name a] - __try__ { - puts \$f "some message" - # ... - } __finally__ { - close \$f - } +> set f \[open /some/file/name a\] +> __try__ \{ +>     puts \\$f "some message" +>     \# \.\.\. +> \} __finally__ \{ +>     close \\$f +> \} Handle different reasons for a file to not be openable for reading: - __try__ { - set f [open /some/file/name] - } __trap__ {POSIX EISDIR} {} { - puts "failed to open /some/file/name: it's a directory" - } __trap__ {POSIX ENOENT} {} { - puts "failed to open /some/file/name: it doesn't exist" - } +> __try__ \{ +>     set f \[open /some/file/name\] +> \} __trap__ \{POSIX EISDIR\} \{\} \{ +>     puts "failed to open /some/file/name: it's a directory" +> \} __trap__ \{POSIX ENOENT\} \{\} \{ +>     puts "failed to open /some/file/name: it doesn't exist" +> \} # Bugs, Ideas, Feedback This document, and the package it describes, will undoubtedly contain bugs and other problems\. Please report such in the category *try* of the [Tcllib Index: embedded/md/tcllib/files/modules/units/units.md ================================================================== --- embedded/md/tcllib/files/modules/units/units.md +++ embedded/md/tcllib/files/modules/units/units.md @@ -180,14 +180,14 @@ 30 seconds 30.0 second 200*meter/20.5*second 9.75609756098 meter / second # SI UNITS -The standard SI units are predefined according to *NIST Special Publication -330*\. Standard units for both SI Base Units \(Table 1\) and SI Derived Units with -Special Names \(Tables 3a and 3b\) are included here for reference\. Each standard -unit name and abbreviation are included in this package\. +The standard SI units are predefined according to *NIST Special* *Publication +330* \. Standard units for both SI Base Units \(Table 1\) and SI Derived Units +with Special Names \(Tables 3a and 3b\) are included here for reference\. Each +standard unit name and abbreviation are included in this package\. ## SI Base Units Quantity Unit Name Abbr. --------------------------------------------- @@ -237,11 +237,11 @@ to add to the units library\. SI Units can have a multiple or sub\-multiple prefix\. The prefix or its abbreviation should appear before the unit, without spaces\. Compound prefixes are not allowed, and a prefix should never be used alone\. These prefixes are -defined in Table 5 of *Special Publication 330*\. +defined in Table 5 of *Special Publication* *330* \. ## SI Prefixes Prefix Name Abbr. Factor --------------------------------------- @@ -339,22 +339,22 @@ defined for each quantity type, and are applied to any unit\-less quantity strings\. A units system enhanced with quantity type checking might benefit from inclusion of other derived types which are expressed in terms of special units, as -illustrated in Table 2 of *NIST Publication 330*\. The quantity *area*, for -example, could be defined as units properly reducing to *meter^2*, although -the utility of defining a unit named *square meter* is arguable\. +illustrated in Table 2 of *NIST Publication* *330* \. The quantity *area*, +for example, could be defined as units properly reducing to *meter^2*, +although the utility of defining a unit named *square meter* is arguable\. # REFERENCES The unit names, abbreviations, and conversion values are derived from those published by the United States Department of Commerce Technology Administration, National Institute of Standards and Technology \(NIST\) in *NIST Special -Publication 330: The International System of Units \(SI\)* and *NIST Special -Publication 811: Guide for the Use of the International System of Units \(SI\)*\. -Both of these publications are available \(as of December 2000\) from +Publication 330: The International System of* *Units \(SI\)* and *NIST Special +Publication 811: Guide for* *the Use of the International System of Units +\(SI\)* \. Both of these publications are available \(as of December 2000\) from [http://physics\.nist\.gov/cuu/Reference/contents\.html](http://physics\.nist\.gov/cuu/Reference/contents\.html) The ideas behind implementation of this package is based in part on code written in 1993 by Adrian Mariano which performed dimensional analysis of unit strings using fixed size tables of C structs\. After going missing in the late 1990's, Index: embedded/md/tcllib/files/modules/virtchannel_base/cat.md ================================================================== --- embedded/md/tcllib/files/modules/virtchannel_base/cat.md +++ embedded/md/tcllib/files/modules/virtchannel_base/cat.md @@ -1,10 +1,10 @@ [//000000001]: # (tcl::chan::cat \- Reflected/virtual channel support) [//000000002]: # (Generated from file 'cat\.man' by tcllib/doctools with format 'markdown') [//000000003]: # (Copyright © 2011 Andreas Kupries ) -[//000000004]: # (tcl::chan::cat\(n\) 1 tcllib "Reflected/virtual channel support") +[//000000004]: # (tcl::chan::cat\(n\) 1\.0\.3 tcllib "Reflected/virtual channel support")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS package require Tcl 8\.5 package require TclOO package require tcl::chan::core ?1? -package require tcl::chan::cat ?1? +package require tcl::chan::cat ?1\.0\.3? [__::tcl::chan::cat__ *chan*\.\.\.](#1) # DESCRIPTION Index: embedded/md/tcllib/files/modules/yaml/huddle.md ================================================================== --- embedded/md/tcllib/files/modules/yaml/huddle.md +++ embedded/md/tcllib/files/modules/yaml/huddle.md @@ -1,11 +1,11 @@ [//000000001]: # (huddle \- HUDDLE) [//000000002]: # (Generated from file 'huddle\.man' by tcllib/doctools with format 'markdown') -[//000000003]: # (Copyright © 2008\-2011 KATO Kanryu -Copyright © 2015 Miguel Martínez López ) -[//000000004]: # (huddle\(n\) 0\.3 tcllib "HUDDLE") +[//000000003]: # (Copyright © 2008\-2011 KATO Kanryu ) +[//000000004]: # (Copyright © 2015 Miguel Martínez López ) +[//000000005]: # (huddle\(n\) 0\.3 tcllib "HUDDLE")
[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | [ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | SYNOPSIS package require Tcl 8\.6 -package require zipfile::mkzip ?1\.2? +package require zipfile::mkzip ?1\.2\.1? [__::zipfile::mkzip::mkzip__ *zipfile* ?__\-zipkit__? ?__\-runtime__ *prefix*? ?__\-comment__ *string*? ?__\-directory__ *rootpath*? ?__\-exclude__ *exclude*? ?__\-\-__? ?*path*\.\.\.?](#1) # DESCRIPTION @@ -60,11 +60,11 @@ The __7\-Zip__ program does correctly display utf8 filenames however and the __vfs::zip__ package will use these of course\. If you use - __::mkzip::mkzip__ mystuff.tm -zipkit -directory mystuff.vfs + > __::mkzip::mkzip__ mystuff\.tm \-zipkit \-directory mystuff\.vfs it will pack your "mystuff\.vfs/" virtual filesystem tree into a zip archive with a suitable header such that on unix you may mark it executable and it should run with tclkit\. Or you can run it with __tclsh__ or __wish__ 8\.6 if you like\. Index: embedded/md/tcllib/toc.md ================================================================== --- embedded/md/tcllib/toc.md +++ embedded/md/tcllib/toc.md @@ -41,10 +41,12 @@ - [cache::async](tcllib/files/modules/cache/async\.md) Asynchronous in\-memory cache - [cksum](tcllib/files/modules/crc/cksum\.md) Calculate a cksum\(1\) compatible checksum + - [clay](tcllib/files/modules/clay/clay\.md) A minimalist framework for large scale OO Projects + - [clock\_iso8601](tcllib/files/modules/clock/iso8601\.md) Parsing ISO 8601 dates/times - [clock\_rfc2822](tcllib/files/modules/clock/rfc2822\.md) Parsing ISO 8601 dates/times - [cmdline](tcllib/files/modules/cmdline/cmdline\.md) Procedures to process command lines and options\. @@ -234,10 +236,12 @@ - [fileutil::magic::rt](tcllib/files/modules/fumagic/rtcore\.md) Runtime core for file type recognition engines written in pure Tcl - [fileutil::multi](tcllib/files/modules/fileutil/multi\.md) Multi\-file operation, scatter/gather, standard object - [fileutil::multi::op](tcllib/files/modules/fileutil/multiop\.md) Multi\-file operation, scatter/gather + + - [fileutil::paths](tcllib/files/modules/fileutil/paths\.md) Manage search path pools - [fileutil\_traverse](tcllib/files/modules/fileutil/traverse\.md) Iterative directory traversal - [ftp](tcllib/files/modules/ftp/ftp\.md) Client\-side tcl implementation of the ftp protocol @@ -282,10 +286,12 @@ - [hook](tcllib/files/modules/hook/hook\.md) Hooks - [html](tcllib/files/modules/html/html\.md) Procedures to generate HTML structures - [htmlparse](tcllib/files/modules/htmlparse/htmlparse\.md) Procedures to parse HTML strings + + - [httpd](tcllib/files/modules/httpd/httpd\.md) A TclOO and coroutine based web server - [huddle](tcllib/files/modules/yaml/huddle\.md) Create and manipulate huddle object - [ident](tcllib/files/modules/ident/ident\.md) Ident protocol client @@ -370,10 +376,12 @@ - [math::optimize](tcllib/files/modules/math/optimize\.md) Optimisation routines - [math::PCA](tcllib/files/modules/math/pca\.md) Package for Principal Component Analysis - [math::polynomials](tcllib/files/modules/math/polynomials\.md) Polynomial functions + + - [math::quasirandom](tcllib/files/modules/math/quasirandom\.md) Quasi\-random points for integration and Monte Carlo type methods - [math::rationalfunctions](tcllib/files/modules/math/rational\_funcs\.md) Polynomial functions - [math::roman](tcllib/files/modules/math/roman\.md) Tools for creating and manipulating roman numerals @@ -618,10 +626,12 @@ - [struct::graph::op](tcllib/files/modules/struct/graphops\.md) Operation for \(un\)directed graph objects - [struct::graph\_v1](tcllib/files/modules/struct/graph1\.md) Create and manipulate directed graph objects - [struct::list](tcllib/files/modules/struct/struct\_list\.md) Procedures for manipulating lists + + - [struct::map](tcllib/files/modules/struct/struct\_map\.md) Manage key/value maps - [struct::matrix](tcllib/files/modules/struct/matrix\.md) Create and manipulate matrix objects - [struct::matrix\_v1](tcllib/files/modules/struct/matrix1\.md) Create and manipulate matrix objects @@ -707,18 +717,30 @@ - [tcl::transform::spacer](tcllib/files/modules/virtchannel\_transform/spacer\.md) Space insertation and removal - [tcl::transform::zlib](tcllib/files/modules/virtchannel\_transform/tcllib\_zlib\.md) zlib \(de\)compression + - [tcl\_community\_communication](tcllib/files/devdoc/tcl\_community\_communication\.md) Tcl Community \- Kind Communication + - [tclDES](tcllib/files/modules/des/tcldes\.md) Implementation of the DES and triple\-DES ciphers - [tclDESjr](tcllib/files/modules/des/tcldesjr\.md) Implementation of the DES and triple\-DES ciphers - [tcldocstrip](tcllib/files/apps/tcldocstrip\.md) Tcl\-based Docstrip Processor + - [tcllib\_devguide](tcllib/files/devdoc/tcllib\_devguide\.md) Tcllib \- The Developer's Guide + + - [tcllib\_install\_guide](tcllib/files/devdoc/tcllib\_installer\.md) Tcllib \- The Installer's Guide + - [tcllib\_ip](tcllib/files/modules/dns/tcllib\_ip\.md) IPv4 and IPv6 address manipulation + - [tcllib\_license](tcllib/files/devdoc/tcllib\_license\.md) Tcllib \- License + + - [tcllib\_releasemgr](tcllib/files/devdoc/tcllib\_releasemgr\.md) Tcllib \- The Release Manager's Guide + + - [tcllib\_sources](tcllib/files/devdoc/tcllib\_sources\.md) Tcllib \- How To Get The Sources + - [tclrep/machineparameters](tcllib/files/modules/math/machineparameters\.md) Compute double precision machine parameters\. - [tepam](tcllib/files/modules/tepam/tepam\_introduction\.md) An introduction into TEPAM, Tcl's Enhanced Procedure and Argument Manager - [tepam::argument\_dialogbox](tcllib/files/modules/tepam/tepam\_argument\_dialogbox\.md) TEPAM argument\_dialogbox, reference manual @@ -773,12 +795,10 @@ - [tie](tcllib/files/modules/tie/tie\.md) Array persistence - [tiff](tcllib/files/modules/tiff/tiff\.md) TIFF reading, writing, and querying and manipulation of meta data - - [tool](tcllib/files/modules/httpd/httpd\.md) A TclOO and coroutine based web server - - [tool](tcllib/files/modules/tool/tool\.md) TclOO Library \(TOOL\) Framework - [tool::dict\_ensemble](tcllib/files/modules/tool/tool\_dict\_ensemble\.md) Dictionary Tools - [transfer::connect](tcllib/files/modules/transfer/connect\.md) Connection setup Index: embedded/md/toc.md ================================================================== --- embedded/md/toc.md +++ embedded/md/toc.md @@ -401,10 +401,12 @@ + [math::PCA](tcllib/files/modules/math/pca\.md) Package for Principal Component Analysis + [math::polynomials](tcllib/files/modules/math/polynomials\.md) Polynomial functions + + [math::quasirandom](tcllib/files/modules/math/quasirandom\.md) Quasi\-random points for integration and Monte Carlo type methods + + [math::rationalfunctions](tcllib/files/modules/math/rational\_funcs\.md) Polynomial functions + [math::roman](tcllib/files/modules/math/roman\.md) Tools for creating and manipulating roman numerals + [math::special](tcllib/files/modules/math/special\.md) Special mathematical functions @@ -433,11 +435,15 @@ + [ftp::geturl](tcllib/files/modules/ftp/ftp\_geturl\.md) Uri handler for ftp urls + [ftpd](tcllib/files/modules/ftpd/ftpd\.md) Tcl FTP server implementation + + [httpd](tcllib/files/modules/httpd/httpd\.md) A TclOO and coroutine based web server + + [ident](tcllib/files/modules/ident/ident\.md) Ident protocol client + + + [imap4](tcllib/files/modules/imap4/imap4\.md) imap client\-side tcl implementation of imap protocol + [irc](tcllib/files/modules/irc/irc\.md) Create IRC connection and interface\. + [ldap](tcllib/files/modules/ldap/ldap\.md) LDAP client @@ -493,12 +499,10 @@ + [smtpd](tcllib/files/modules/smtpd/smtpd\.md) Tcl SMTP server implementation + [tcllib\_ip](tcllib/files/modules/dns/tcllib\_ip\.md) IPv4 and IPv6 address manipulation - + [tool](tcllib/files/modules/httpd/httpd\.md) A TclOO and coroutine based web server - + [udpcluster](tcllib/files/modules/udpcluster/udpcluster\.md) UDP Peer\-to\-Peer cluster + [uri](tcllib/files/modules/uri/uri\.md) URI utilities + [uri\_urn](tcllib/files/modules/uri/urn\-scheme\.md) URI utilities, URN scheme @@ -616,10 +620,12 @@ + [tepam](tcllib/files/modules/tepam/tepam\_introduction\.md) An introduction into TEPAM, Tcl's Enhanced Procedure and Argument Manager + [tepam::procedure](tcllib/files/modules/tepam/tepam\_procedure\.md) TEPAM procedure, reference manual * [Programming tools]() + + + [clay](tcllib/files/modules/clay/clay\.md) A minimalist framework for large scale OO Projects + [cmdline](tcllib/files/modules/cmdline/cmdline\.md) Procedures to process command lines and options\. + [comm](tcllib/files/modules/comm/comm\.md) A remote communication facility for Tcl \(8\.3 and later\) @@ -828,17 +834,17 @@ + [transfer::transmitter](tcllib/files/modules/transfer/transmitter\.md) Data source * [Unfiled]() + [cache::async](tcllib/files/modules/cache/async\.md) Asynchronous in\-memory cache + + + [fileutil::paths](tcllib/files/modules/fileutil/paths\.md) Manage search path pools + [generator](tcllib/files/modules/generator/generator\.md) Procedures for creating and using generators\. + [huddle](tcllib/files/modules/yaml/huddle\.md) Create and manipulate huddle object - + [imap4](tcllib/files/modules/imap4/imap4\.md) imap client\-side tcl implementation of imap protocol - + [map::geocode::nominatim](tcllib/files/modules/map/map\_geocode\_nominatim\.md) Resolving geographical names with a Nominatim service + [map::slippy](tcllib/files/modules/map/map\_slippy\.md) Common code for slippy based map packages + [map::slippy::cache](tcllib/files/modules/map/map\_slippy\_cache\.md) Management of a tile cache in the local filesystem @@ -854,10 +860,12 @@ + [rest](tcllib/files/modules/rest/rest\.md) define REST web APIs and call them inline or asychronously + [stringprep](tcllib/files/modules/stringprep/stringprep\.md) Implementation of stringprep + [stringprep::data](tcllib/files/modules/stringprep/stringprep\_data\.md) stringprep data tables, generated, internal + + + [struct::map](tcllib/files/modules/struct/struct\_map\.md) Manage key/value maps + [tclrep/machineparameters](tcllib/files/modules/math/machineparameters\.md) Compute double precision machine parameters\. + [uevent::onidle](tcllib/files/modules/uev/uevent\_onidle\.md) Request merging and deferal to idle time @@ -1001,10 +1009,14 @@ + [cache]() - [cache::async](tcllib/files/modules/cache/async\.md) Asynchronous in\-memory cache + + [clay]() + + - [clay](tcllib/files/modules/clay/clay\.md) A minimalist framework for large scale OO Projects + + [clock]() - [clock\_iso8601](tcllib/files/modules/clock/iso8601\.md) Parsing ISO 8601 dates/times - [clock\_rfc2822](tcllib/files/modules/clock/rfc2822\.md) Parsing ISO 8601 dates/times @@ -1234,10 +1246,12 @@ - [fileutil](tcllib/files/modules/fileutil/fileutil\.md) Procedures implementing some file utilities - [fileutil::multi](tcllib/files/modules/fileutil/multi\.md) Multi\-file operation, scatter/gather, standard object - [fileutil::multi::op](tcllib/files/modules/fileutil/multiop\.md) Multi\-file operation, scatter/gather + + - [fileutil::paths](tcllib/files/modules/fileutil/paths\.md) Manage search path pools - [fileutil\_traverse](tcllib/files/modules/fileutil/traverse\.md) Iterative directory traversal + [ftp]() @@ -1321,11 +1335,11 @@ - [autoproxy](tcllib/files/modules/http/autoproxy\.md) Automatic HTTP proxy usage and authentication + [httpd]() - - [tool](tcllib/files/modules/httpd/httpd\.md) A TclOO and coroutine based web server + - [httpd](tcllib/files/modules/httpd/httpd\.md) A TclOO and coroutine based web server + [ident]() - [ident](tcllib/files/modules/ident/ident\.md) Ident protocol client @@ -1446,10 +1460,12 @@ - [math::optimize](tcllib/files/modules/math/optimize\.md) Optimisation routines - [math::PCA](tcllib/files/modules/math/pca\.md) Package for Principal Component Analysis - [math::polynomials](tcllib/files/modules/math/polynomials\.md) Polynomial functions + + - [math::quasirandom](tcllib/files/modules/math/quasirandom\.md) Quasi\-random points for integration and Monte Carlo type methods - [math::rationalfunctions](tcllib/files/modules/math/rational\_funcs\.md) Polynomial functions - [math::roman](tcllib/files/modules/math/roman\.md) Tools for creating and manipulating roman numerals @@ -1766,10 +1782,12 @@ - [struct::graph::op](tcllib/files/modules/struct/graphops\.md) Operation for \(un\)directed graph objects - [struct::graph\_v1](tcllib/files/modules/struct/graph1\.md) Create and manipulate directed graph objects - [struct::list](tcllib/files/modules/struct/struct\_list\.md) Procedures for manipulating lists + + - [struct::map](tcllib/files/modules/struct/struct\_map\.md) Manage key/value maps - [struct::matrix](tcllib/files/modules/struct/matrix\.md) Create and manipulate matrix objects - [struct::matrix\_v1](tcllib/files/modules/struct/matrix1\.md) Create and manipulate matrix objects Index: embedded/md/toc0.md ================================================================== --- embedded/md/toc0.md +++ embedded/md/toc0.md @@ -401,10 +401,12 @@ + [math::PCA](tcllib/files/modules/math/pca\.md) Package for Principal Component Analysis + [math::polynomials](tcllib/files/modules/math/polynomials\.md) Polynomial functions + + [math::quasirandom](tcllib/files/modules/math/quasirandom\.md) Quasi\-random points for integration and Monte Carlo type methods + + [math::rationalfunctions](tcllib/files/modules/math/rational\_funcs\.md) Polynomial functions + [math::roman](tcllib/files/modules/math/roman\.md) Tools for creating and manipulating roman numerals + [math::special](tcllib/files/modules/math/special\.md) Special mathematical functions @@ -433,11 +435,15 @@ + [ftp::geturl](tcllib/files/modules/ftp/ftp\_geturl\.md) Uri handler for ftp urls + [ftpd](tcllib/files/modules/ftpd/ftpd\.md) Tcl FTP server implementation + + [httpd](tcllib/files/modules/httpd/httpd\.md) A TclOO and coroutine based web server + + [ident](tcllib/files/modules/ident/ident\.md) Ident protocol client + + + [imap4](tcllib/files/modules/imap4/imap4\.md) imap client\-side tcl implementation of imap protocol + [irc](tcllib/files/modules/irc/irc\.md) Create IRC connection and interface\. + [ldap](tcllib/files/modules/ldap/ldap\.md) LDAP client @@ -493,12 +499,10 @@ + [smtpd](tcllib/files/modules/smtpd/smtpd\.md) Tcl SMTP server implementation + [tcllib\_ip](tcllib/files/modules/dns/tcllib\_ip\.md) IPv4 and IPv6 address manipulation - + [tool](tcllib/files/modules/httpd/httpd\.md) A TclOO and coroutine based web server - + [udpcluster](tcllib/files/modules/udpcluster/udpcluster\.md) UDP Peer\-to\-Peer cluster + [uri](tcllib/files/modules/uri/uri\.md) URI utilities + [uri\_urn](tcllib/files/modules/uri/urn\-scheme\.md) URI utilities, URN scheme @@ -616,10 +620,12 @@ + [tepam](tcllib/files/modules/tepam/tepam\_introduction\.md) An introduction into TEPAM, Tcl's Enhanced Procedure and Argument Manager + [tepam::procedure](tcllib/files/modules/tepam/tepam\_procedure\.md) TEPAM procedure, reference manual * [Programming tools]() + + + [clay](tcllib/files/modules/clay/clay\.md) A minimalist framework for large scale OO Projects + [cmdline](tcllib/files/modules/cmdline/cmdline\.md) Procedures to process command lines and options\. + [comm](tcllib/files/modules/comm/comm\.md) A remote communication facility for Tcl \(8\.3 and later\) @@ -828,17 +834,17 @@ + [transfer::transmitter](tcllib/files/modules/transfer/transmitter\.md) Data source * [Unfiled]() + [cache::async](tcllib/files/modules/cache/async\.md) Asynchronous in\-memory cache + + + [fileutil::paths](tcllib/files/modules/fileutil/paths\.md) Manage search path pools + [generator](tcllib/files/modules/generator/generator\.md) Procedures for creating and using generators\. + [huddle](tcllib/files/modules/yaml/huddle\.md) Create and manipulate huddle object - + [imap4](tcllib/files/modules/imap4/imap4\.md) imap client\-side tcl implementation of imap protocol - + [map::geocode::nominatim](tcllib/files/modules/map/map\_geocode\_nominatim\.md) Resolving geographical names with a Nominatim service + [map::slippy](tcllib/files/modules/map/map\_slippy\.md) Common code for slippy based map packages + [map::slippy::cache](tcllib/files/modules/map/map\_slippy\_cache\.md) Management of a tile cache in the local filesystem @@ -854,10 +860,12 @@ + [rest](tcllib/files/modules/rest/rest\.md) define REST web APIs and call them inline or asychronously + [stringprep](tcllib/files/modules/stringprep/stringprep\.md) Implementation of stringprep + [stringprep::data](tcllib/files/modules/stringprep/stringprep\_data\.md) stringprep data tables, generated, internal + + + [struct::map](tcllib/files/modules/struct/struct\_map\.md) Manage key/value maps + [tclrep/machineparameters](tcllib/files/modules/math/machineparameters\.md) Compute double precision machine parameters\. + [uevent::onidle](tcllib/files/modules/uev/uevent\_onidle\.md) Request merging and deferal to idle time Index: embedded/md/toc1.md ================================================================== --- embedded/md/toc1.md +++ embedded/md/toc1.md @@ -67,10 +67,14 @@ * [cache]() + [cache::async](tcllib/files/modules/cache/async\.md) Asynchronous in\-memory cache + * [clay]() + + + [clay](tcllib/files/modules/clay/clay\.md) A minimalist framework for large scale OO Projects + * [clock]() + [clock\_iso8601](tcllib/files/modules/clock/iso8601\.md) Parsing ISO 8601 dates/times + [clock\_rfc2822](tcllib/files/modules/clock/rfc2822\.md) Parsing ISO 8601 dates/times @@ -300,10 +304,12 @@ + [fileutil](tcllib/files/modules/fileutil/fileutil\.md) Procedures implementing some file utilities + [fileutil::multi](tcllib/files/modules/fileutil/multi\.md) Multi\-file operation, scatter/gather, standard object + [fileutil::multi::op](tcllib/files/modules/fileutil/multiop\.md) Multi\-file operation, scatter/gather + + + [fileutil::paths](tcllib/files/modules/fileutil/paths\.md) Manage search path pools + [fileutil\_traverse](tcllib/files/modules/fileutil/traverse\.md) Iterative directory traversal * [ftp]() @@ -387,11 +393,11 @@ + [autoproxy](tcllib/files/modules/http/autoproxy\.md) Automatic HTTP proxy usage and authentication * [httpd]() - + [tool](tcllib/files/modules/httpd/httpd\.md) A TclOO and coroutine based web server + + [httpd](tcllib/files/modules/httpd/httpd\.md) A TclOO and coroutine based web server * [ident]() + [ident](tcllib/files/modules/ident/ident\.md) Ident protocol client @@ -512,10 +518,12 @@ + [math::optimize](tcllib/files/modules/math/optimize\.md) Optimisation routines + [math::PCA](tcllib/files/modules/math/pca\.md) Package for Principal Component Analysis + [math::polynomials](tcllib/files/modules/math/polynomials\.md) Polynomial functions + + + [math::quasirandom](tcllib/files/modules/math/quasirandom\.md) Quasi\-random points for integration and Monte Carlo type methods + [math::rationalfunctions](tcllib/files/modules/math/rational\_funcs\.md) Polynomial functions + [math::roman](tcllib/files/modules/math/roman\.md) Tools for creating and manipulating roman numerals @@ -832,10 +840,12 @@ + [struct::graph::op](tcllib/files/modules/struct/graphops\.md) Operation for \(un\)directed graph objects + [struct::graph\_v1](tcllib/files/modules/struct/graph1\.md) Create and manipulate directed graph objects + [struct::list](tcllib/files/modules/struct/struct\_list\.md) Procedures for manipulating lists + + + [struct::map](tcllib/files/modules/struct/struct\_map\.md) Manage key/value maps + [struct::matrix](tcllib/files/modules/struct/matrix\.md) Create and manipulate matrix objects + [struct::matrix\_v1](tcllib/files/modules/struct/matrix1\.md) Create and manipulate matrix objects ADDED idoc/man/files/devdoc/tcl_community_communication.n Index: idoc/man/files/devdoc/tcl_community_communication.n ================================================================== --- /dev/null +++ idoc/man/files/devdoc/tcl_community_communication.n @@ -0,0 +1,434 @@ +'\" +'\" Generated from file 'tcl_community_communication\&.man' by tcllib/doctools with format 'nroff' +'\" +.TH "tcl_community_communication" n 1 tcllib "" +.\" The -*- nroff -*- definitions below are for supplemental macros used +.\" in Tcl/Tk manual entries. +.\" +.\" .AP type name in/out ?indent? +.\" Start paragraph describing an argument to a library procedure. +.\" type is type of argument (int, etc.), in/out is either "in", "out", +.\" or "in/out" to describe whether procedure reads or modifies arg, +.\" and indent is equivalent to second arg of .IP (shouldn't ever be +.\" needed; use .AS below instead) +.\" +.\" .AS ?type? ?name? +.\" Give maximum sizes of arguments for setting tab stops. Type and +.\" name are examples of largest possible arguments that will be passed +.\" to .AP later. If args are omitted, default tab stops are used. +.\" +.\" .BS +.\" Start box enclosure. From here until next .BE, everything will be +.\" enclosed in one large box. +.\" +.\" .BE +.\" End of box enclosure. +.\" +.\" .CS +.\" Begin code excerpt. +.\" +.\" .CE +.\" End code excerpt. +.\" +.\" .VS ?version? ?br? +.\" Begin vertical sidebar, for use in marking newly-changed parts +.\" of man pages. The first argument is ignored and used for recording +.\" the version when the .VS was added, so that the sidebars can be +.\" found and removed when they reach a certain age. If another argument +.\" is present, then a line break is forced before starting the sidebar. +.\" +.\" .VE +.\" End of vertical sidebar. +.\" +.\" .DS +.\" Begin an indented unfilled display. +.\" +.\" .DE +.\" End of indented unfilled display. +.\" +.\" .SO ?manpage? +.\" Start of list of standard options for a Tk widget. The manpage +.\" argument defines where to look up the standard options; if +.\" omitted, defaults to "options". The options follow on successive +.\" lines, in three columns separated by tabs. +.\" +.\" .SE +.\" End of list of standard options for a Tk widget. +.\" +.\" .OP cmdName dbName dbClass +.\" Start of description of a specific option. cmdName gives the +.\" option's name as specified in the class command, dbName gives +.\" the option's name in the option database, and dbClass gives +.\" the option's class in the option database. +.\" +.\" .UL arg1 arg2 +.\" Print arg1 underlined, then print arg2 normally. +.\" +.\" .QW arg1 ?arg2? +.\" Print arg1 in quotes, then arg2 normally (for trailing punctuation). +.\" +.\" .PQ arg1 ?arg2? +.\" Print an open parenthesis, arg1 in quotes, then arg2 normally +.\" (for trailing punctuation) and then a closing parenthesis. +.\" +.\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages. +.if t .wh -1.3i ^B +.nr ^l \n(.l +.ad b +.\" # Start an argument description +.de AP +.ie !"\\$4"" .TP \\$4 +.el \{\ +. ie !"\\$2"" .TP \\n()Cu +. el .TP 15 +.\} +.ta \\n()Au \\n()Bu +.ie !"\\$3"" \{\ +\&\\$1 \\fI\\$2\\fP (\\$3) +.\".b +.\} +.el \{\ +.br +.ie !"\\$2"" \{\ +\&\\$1 \\fI\\$2\\fP +.\} +.el \{\ +\&\\fI\\$1\\fP +.\} +.\} +.. +.\" # define tabbing values for .AP +.de AS +.nr )A 10n +.if !"\\$1"" .nr )A \\w'\\$1'u+3n +.nr )B \\n()Au+15n +.\" +.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n +.nr )C \\n()Bu+\\w'(in/out)'u+2n +.. +.AS Tcl_Interp Tcl_CreateInterp in/out +.\" # BS - start boxed text +.\" # ^y = starting y location +.\" # ^b = 1 +.de BS +.br +.mk ^y +.nr ^b 1u +.if n .nf +.if n .ti 0 +.if n \l'\\n(.lu\(ul' +.if n .fi +.. +.\" # BE - end boxed text (draw box now) +.de BE +.nf +.ti 0 +.mk ^t +.ie n \l'\\n(^lu\(ul' +.el \{\ +.\" Draw four-sided box normally, but don't draw top of +.\" box if the box started on an earlier page. +.ie !\\n(^b-1 \{\ +\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.el \}\ +\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.\} +.fi +.br +.nr ^b 0 +.. +.\" # VS - start vertical sidebar +.\" # ^Y = starting y location +.\" # ^v = 1 (for troff; for nroff this doesn't matter) +.de VS +.if !"\\$2"" .br +.mk ^Y +.ie n 'mc \s12\(br\s0 +.el .nr ^v 1u +.. +.\" # VE - end of vertical sidebar +.de VE +.ie n 'mc +.el \{\ +.ev 2 +.nf +.ti 0 +.mk ^t +\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n' +.sp -1 +.fi +.ev +.\} +.nr ^v 0 +.. +.\" # Special macro to handle page bottom: finish off current +.\" # box/sidebar if in box/sidebar mode, then invoked standard +.\" # page bottom macro. +.de ^B +.ev 2 +'ti 0 +'nf +.mk ^t +.if \\n(^b \{\ +.\" Draw three-sided box if this is the box's first page, +.\" draw two sides but no top otherwise. +.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.\} +.if \\n(^v \{\ +.nr ^x \\n(^tu+1v-\\n(^Yu +\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c +.\} +.bp +'fi +.ev +.if \\n(^b \{\ +.mk ^y +.nr ^b 2 +.\} +.if \\n(^v \{\ +.mk ^Y +.\} +.. +.\" # DS - begin display +.de DS +.RS +.nf +.sp +.. +.\" # DE - end display +.de DE +.fi +.RE +.sp +.. +.\" # SO - start of list of standard options +.de SO +'ie '\\$1'' .ds So \\fBoptions\\fR +'el .ds So \\fB\\$1\\fR +.SH "STANDARD OPTIONS" +.LP +.nf +.ta 5.5c 11c +.ft B +.. +.\" # SE - end of list of standard options +.de SE +.fi +.ft R +.LP +See the \\*(So manual entry for details on the standard options. +.. +.\" # OP - start of full description for a single option +.de OP +.LP +.nf +.ta 4c +Command-Line Name: \\fB\\$1\\fR +Database Name: \\fB\\$2\\fR +Database Class: \\fB\\$3\\fR +.fi +.IP +.. +.\" # CS - begin code excerpt +.de CS +.RS +.nf +.ta .25i .5i .75i 1i +.. +.\" # CE - end code excerpt +.de CE +.fi +.RE +.. +.\" # UL - underline word +.de UL +\\$1\l'|0\(ul'\\$2 +.. +.\" # QW - apply quotation marks to word +.de QW +.ie '\\*(lq'"' ``\\$1''\\$2 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\$2 +.. +.\" # PQ - apply parens and quotation marks to word +.de PQ +.ie '\\*(lq'"' (``\\$1''\\$2)\\$3 +.\"" fix emacs highlighting +.el (\\*(lq\\$1\\*(rq\\$2)\\$3 +.. +.\" # QR - quoted range +.de QR +.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3 +.. +.\" # MT - "empty" string +.de MT +.QW "" +.. +.BS +.SH NAME +tcl_community_communication \- Tcl Community - Kind Communication +.SH DESCRIPTION +The Tcl Community encourages contributions from anyone who wishes to +advance the development of: +.IP \(bu +The Tcl Language +.IP \(bu +Tcl derived languages +.IP \(bu +Tcl related libraries +.IP \(bu +Tcl extensions +.IP \(bu +External Projects that Integrate Tcl +.PP +.PP +We welcome those contributions from anyone\&. We are blind to +gender, race, religion, cultural background, cybernetic nature, and +any other demographic characteristics, as well as personal political +views\&. +.PP +A community lives and dies by communications\&. And occasionally +our communications are peppered with patterns that are harsh, +unfriendly, unwelcoming and/or otherwise unkind\&. As a volunteer +community, we need all of the help we can get\&. Therefore, we ask all +contributors to make a conscious effort, in Tcl Community discussions, +to communicate in ways that are welcoming\&. Ways that are +friendly\&. Ways that are, in a word: kind\&. +.PP +These guidelines suggest specific ways to accomplish that goal\&. +.PP +Please note: for the balance of this document any reference to +"People", "Persons", "anybody" or "somebody" can refer to any sentient +being, not merely corporeal members of the species Homo Sapien\&. +.TP +We are a Sanctuary not a Clubhouse +The Tcl Community is a collective of amateurs and professionals who +code, test, and use tools\&. Our community is open to all\&. There is no +velvet rope\&. There is no bouncer at the door\&. There are no secret +handshakes\&. Any sentient being who enters our midst is welcome\&. If +someone is ever asked to leave, it is only because they are being +disruptive to the functioning of the community\&. +.TP +We Merit Ideas, Not People +A good idea can come from anyone, regardless of how little time they +have been with us\&. A bad idea can come from anyone, regardless of how +much time or how little time they have been with us\&. We judge a +concept by how it stands up to scrutiny of logic, implementation, and +regression testing\&. We don’t judge ideas based on who had the idea +first, who agrees with the idea, or who disagrees with it\&. +.TP +Treat Everyone with Respect +Everyone is deserving of respect and courtesy at all times\&. +.TP +Refer to people by the names they use\&. +If grammar requires you to state a gender for a person, honor their +preferences about their gender identity\&. If you are unsure as to the +gender of an individual, ask\&. If someone had to guess about your +gender and got it wrong, please correct them and do not take it +personally\&. +.TP +Do not take a harsh tone towards other participants\&. +Do not make personal attacks against anyone (participant or not\&.) +.sp +Criticize statements and actions, never people\&. +.TP +Don’t Take Things Personally +When in doubt, assume the best in people\&. A criticism of your +statements is not a personal attack on you\&. +.TP +Persons, not People +Stereotypes are an unhelpful tool on many accounts\&. They are generally +oversimplified\&. They are usually flat out wrong\&. And even if "right" +they are of absolutely no utility in determining the capabilities, +motivations, or fitness of an individual\&. +.sp +Don’t use them in Tcl Community communications\&. +.TP +Mistakes Happen +The human condition is a series of trials and errors\&. Progress is when +we get one more trial than error\&. Being wrong or making a mistake is +the default state of humanity\&. Accept the errors of your fellow +sentient beings, and be aware that you are also fallible\&. +.TP +Keep it Real +Please respond to what people actually say\&. We are all amazing +individuals, but none among us are mind readers\&. If you find yourself +responding to what you imagine someone is thinking, odds are you are +going to be wrong\&. +.sp +If you must criticize someone, stick to things they have +actually done\&. Never criticize for something you speculate they have +done\&. Or imagine they have done\&. Or something someone who shares some +attribute with them has done in the past\&. +.sp +Keep discussions about any non-Tcl subjects to what can be +stated factually and without emotion or judgement\&. +.TP +When Trouble Arises, Don’t Escalate +If you feel you are being personally attacked or offended, take the +high road\&. Punching back in a public forum will only makes things +worse\&. Address the matter in a private correspondence\&. Be +polite\&. Express your feelings, but note that you are expressing your +feelings\&. When writing, look for a way to calm matters down\&. And when +in doubt, sleep on your letter before pressing send\&. And when not in +doubt, sleep on it for another day after that\&. +.sp +If you are a spectator to a fight in progress, politely request +the two parties take the matter to a more private forum\&. +.TP +Always get the Last Word: I’m Sorry +If an personal argument does arise, be the first to apologize\&. An +apology does not concede a logical point\&. It merely acknowledges that +at some point the discussion left either logic, community decency, or +both\&. Return to the topic when cooler heads can prevail\&. +.TP +Nobody is Keeping Score +There is no prize for being right\&. There is no cost for being wrong\&. A +hard sell is not going to advance your idea along any more than a +logical argument\&. You aren’t running for office\&. This isn’t debate +club\&. If you find yourself continuing a discussion beyond where a +topic can be logically discussed, stop\&. +.TP +No Evangelizing +The Tcl Community is not the place to promote your chosen operating +system, political outlook, religion, marketing scheme, or economic +model\&. Period\&. +.sp +(And if you do bring it up, be prepared to have your chosen +topic discussed logically\&. And odds are, not favorably\&.) +.TP +Respect the Community +If the Community has come to a decision on a course of action, please +stop arguing\&. +.sp +If someone complains about how you are expressing your ideas, +listen\&. +.sp +If your words are hurting people, stop\&. There is no amount of +being "right" that makes up for someone leaving our midst because they +felt insulted, threatened, or ignored\&. +.PP +By following these guidelines, we will build our community, encourage +more contribution to our projects, and our discussions will be +friendlier and reach conclusions more easily\&. +.PP +Thank You\&. +.SH SIGNATORIES +.IP \(bu +Sean "the Hypnotoad" Woods +.IP \(bu +Andreas Kupries +.PP +.SH AUTHORS +.TP +Primary +Sean "the Hypnotoad" Woods +.TP +Light editing +Andreas Kupries +.PP ADDED idoc/man/files/devdoc/tcllib_devguide.n Index: idoc/man/files/devdoc/tcllib_devguide.n ================================================================== --- /dev/null +++ idoc/man/files/devdoc/tcllib_devguide.n @@ -0,0 +1,1307 @@ +'\" +'\" Generated from file 'tcllib_devguide\&.man' by tcllib/doctools with format 'nroff' +'\" +.TH "tcllib_devguide" n 1 tcllib "" +.\" The -*- nroff -*- definitions below are for supplemental macros used +.\" in Tcl/Tk manual entries. +.\" +.\" .AP type name in/out ?indent? +.\" Start paragraph describing an argument to a library procedure. +.\" type is type of argument (int, etc.), in/out is either "in", "out", +.\" or "in/out" to describe whether procedure reads or modifies arg, +.\" and indent is equivalent to second arg of .IP (shouldn't ever be +.\" needed; use .AS below instead) +.\" +.\" .AS ?type? ?name? +.\" Give maximum sizes of arguments for setting tab stops. Type and +.\" name are examples of largest possible arguments that will be passed +.\" to .AP later. If args are omitted, default tab stops are used. +.\" +.\" .BS +.\" Start box enclosure. From here until next .BE, everything will be +.\" enclosed in one large box. +.\" +.\" .BE +.\" End of box enclosure. +.\" +.\" .CS +.\" Begin code excerpt. +.\" +.\" .CE +.\" End code excerpt. +.\" +.\" .VS ?version? ?br? +.\" Begin vertical sidebar, for use in marking newly-changed parts +.\" of man pages. The first argument is ignored and used for recording +.\" the version when the .VS was added, so that the sidebars can be +.\" found and removed when they reach a certain age. If another argument +.\" is present, then a line break is forced before starting the sidebar. +.\" +.\" .VE +.\" End of vertical sidebar. +.\" +.\" .DS +.\" Begin an indented unfilled display. +.\" +.\" .DE +.\" End of indented unfilled display. +.\" +.\" .SO ?manpage? +.\" Start of list of standard options for a Tk widget. The manpage +.\" argument defines where to look up the standard options; if +.\" omitted, defaults to "options". The options follow on successive +.\" lines, in three columns separated by tabs. +.\" +.\" .SE +.\" End of list of standard options for a Tk widget. +.\" +.\" .OP cmdName dbName dbClass +.\" Start of description of a specific option. cmdName gives the +.\" option's name as specified in the class command, dbName gives +.\" the option's name in the option database, and dbClass gives +.\" the option's class in the option database. +.\" +.\" .UL arg1 arg2 +.\" Print arg1 underlined, then print arg2 normally. +.\" +.\" .QW arg1 ?arg2? +.\" Print arg1 in quotes, then arg2 normally (for trailing punctuation). +.\" +.\" .PQ arg1 ?arg2? +.\" Print an open parenthesis, arg1 in quotes, then arg2 normally +.\" (for trailing punctuation) and then a closing parenthesis. +.\" +.\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages. +.if t .wh -1.3i ^B +.nr ^l \n(.l +.ad b +.\" # Start an argument description +.de AP +.ie !"\\$4"" .TP \\$4 +.el \{\ +. ie !"\\$2"" .TP \\n()Cu +. el .TP 15 +.\} +.ta \\n()Au \\n()Bu +.ie !"\\$3"" \{\ +\&\\$1 \\fI\\$2\\fP (\\$3) +.\".b +.\} +.el \{\ +.br +.ie !"\\$2"" \{\ +\&\\$1 \\fI\\$2\\fP +.\} +.el \{\ +\&\\fI\\$1\\fP +.\} +.\} +.. +.\" # define tabbing values for .AP +.de AS +.nr )A 10n +.if !"\\$1"" .nr )A \\w'\\$1'u+3n +.nr )B \\n()Au+15n +.\" +.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n +.nr )C \\n()Bu+\\w'(in/out)'u+2n +.. +.AS Tcl_Interp Tcl_CreateInterp in/out +.\" # BS - start boxed text +.\" # ^y = starting y location +.\" # ^b = 1 +.de BS +.br +.mk ^y +.nr ^b 1u +.if n .nf +.if n .ti 0 +.if n \l'\\n(.lu\(ul' +.if n .fi +.. +.\" # BE - end boxed text (draw box now) +.de BE +.nf +.ti 0 +.mk ^t +.ie n \l'\\n(^lu\(ul' +.el \{\ +.\" Draw four-sided box normally, but don't draw top of +.\" box if the box started on an earlier page. +.ie !\\n(^b-1 \{\ +\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.el \}\ +\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.\} +.fi +.br +.nr ^b 0 +.. +.\" # VS - start vertical sidebar +.\" # ^Y = starting y location +.\" # ^v = 1 (for troff; for nroff this doesn't matter) +.de VS +.if !"\\$2"" .br +.mk ^Y +.ie n 'mc \s12\(br\s0 +.el .nr ^v 1u +.. +.\" # VE - end of vertical sidebar +.de VE +.ie n 'mc +.el \{\ +.ev 2 +.nf +.ti 0 +.mk ^t +\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n' +.sp -1 +.fi +.ev +.\} +.nr ^v 0 +.. +.\" # Special macro to handle page bottom: finish off current +.\" # box/sidebar if in box/sidebar mode, then invoked standard +.\" # page bottom macro. +.de ^B +.ev 2 +'ti 0 +'nf +.mk ^t +.if \\n(^b \{\ +.\" Draw three-sided box if this is the box's first page, +.\" draw two sides but no top otherwise. +.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.\} +.if \\n(^v \{\ +.nr ^x \\n(^tu+1v-\\n(^Yu +\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c +.\} +.bp +'fi +.ev +.if \\n(^b \{\ +.mk ^y +.nr ^b 2 +.\} +.if \\n(^v \{\ +.mk ^Y +.\} +.. +.\" # DS - begin display +.de DS +.RS +.nf +.sp +.. +.\" # DE - end display +.de DE +.fi +.RE +.sp +.. +.\" # SO - start of list of standard options +.de SO +'ie '\\$1'' .ds So \\fBoptions\\fR +'el .ds So \\fB\\$1\\fR +.SH "STANDARD OPTIONS" +.LP +.nf +.ta 5.5c 11c +.ft B +.. +.\" # SE - end of list of standard options +.de SE +.fi +.ft R +.LP +See the \\*(So manual entry for details on the standard options. +.. +.\" # OP - start of full description for a single option +.de OP +.LP +.nf +.ta 4c +Command-Line Name: \\fB\\$1\\fR +Database Name: \\fB\\$2\\fR +Database Class: \\fB\\$3\\fR +.fi +.IP +.. +.\" # CS - begin code excerpt +.de CS +.RS +.nf +.ta .25i .5i .75i 1i +.. +.\" # CE - end code excerpt +.de CE +.fi +.RE +.. +.\" # UL - underline word +.de UL +\\$1\l'|0\(ul'\\$2 +.. +.\" # QW - apply quotation marks to word +.de QW +.ie '\\*(lq'"' ``\\$1''\\$2 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\$2 +.. +.\" # PQ - apply parens and quotation marks to word +.de PQ +.ie '\\*(lq'"' (``\\$1''\\$2)\\$3 +.\"" fix emacs highlighting +.el (\\*(lq\\$1\\*(rq\\$2)\\$3 +.. +.\" # QR - quoted range +.de QR +.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3 +.. +.\" # MT - "empty" string +.de MT +.QW "" +.. +.BS +.SH NAME +tcllib_devguide \- Tcllib - The Developer's Guide +.SH SYNOPSIS +\fBModule\fR \fIname\fR \fIcode-action\fR \fIdoc-action\fR \fIexample-action\fR +.sp +\fBApplication\fR \fIname\fR +.sp +\fBExclude\fR \fIname\fR +.sp +.BE +.SH DESCRIPTION +Welcome to Tcllib, the Tcl Standard Library\&. Note that Tcllib is not a +package itself\&. It is a collection of (semi-independent) \fITcl\fR +packages that provide utility functions useful to a large collection +of Tcl programmers\&. +.PP +This document is a guide for developers working on Tcllib, +i\&.e\&. maintainers fixing bugs, extending the collection's +functionality, etc\&. +.PP +Please read +.IP [1] +\fITcllib - How To Get The Sources\fR and +.IP [2] +\fITcllib - The Installer's Guide\fR +.PP +first, if that was not done already\&. +.PP +Here we assume that the sources are already available in a +directory of your choice, and that you not only know how to build and +install them, but also have all the necessary requisites to actually +do so\&. The guide to the sources in particular also explains which +source code management system is used, where to find it, how to set it +up, etc\&. +.SH COMMITMENTS +.SS CONTRIBUTOR +As a contributor to Tcllib you are committing yourself to: +.IP [1] +keep the guidelines written down in +\fITcl Community - Kind Communication\fR in your mind\&. +The main point to take away from there is +\fIto be kind to each other\fR\&. +.IP [2] +Your contributions getting distributed under a BSD/MIT license\&. +For the details see \fITcllib - License\fR +.PP +Contributions are made by entering tickets into our tracker, providing +patches, bundles or branches of code for inclusion, or posting to the +Tcllib related mailing lists\&. +.SS MAINTAINER +When contributing one or more packages for full inclusion into Tcllib +you are committing yourself to +.IP [1] +Keep the guidelines written down in +\fITcl Community - Kind Communication\fR +(as any contributor) in your mind\&. The main point to take away +from there is \fIto be kind to each other\fR\&. +.IP [2] +Your packages getting distributed under a BSD/MIT license\&. For +the details see \fITcllib - License\fR +.IP [3] +Maintenance of the new packages for a period of two years under +the following rules, and responsibilities: +.RS +.IP [1] +A maintainer may step down after the mandatory period as +they see fit\&. +.IP [2] +A maintainer may step down before the end of the +mandatory period, under the condition that a replacement +maintainer is immediately available and has agreed to +serve the remainder of the period, plus their own +mandatory period (see below)\&. +.IP [3] +When stepping down without a replacement maintainer +taking over the relevant packages have to be flagged as +\fBunmaintained\fR\&. +.IP [4] +When a replacement mantainer is brought in for a package +it is (kept) marked as \fBmaintained\fR (again)\&. +.sp +A replacement maintainer is bound by the same rules as +the original maintainer, except that the mandatory +period of maintenance is shortened to one year\&. +.IP [5] +For any \fBunmaintained\fR package a contributor +interested in becoming its maintainer can become so by +flagging them as \fBmaintained\fR with their name and +contact information, committing themselves to the rules +of a replacement maintainer (see previous point)\&. +.IP [6] +For any already \fBmaintained\fR package a contributor +interested in becoming a co-maintainer can become so +with the agreement of the existing maintainer(s), +committing themselves to the rules of a replacement +maintainer (see two points previous)\&. +.RE +.sp +The responsibilities as a maintainer include: +.RS +.IP [1] +Watching Tcllib's ticket tracker for bugs, bug fixes, +and feature requests related to the new packages\&. +.IP [2] +Reviewing the aforementioned tickets, rejecting or +applying them +.IP [3] +Coordination and discussion with ticket submitter during +the development and/or application of bug fixes\&. +.RE +.IP [4] +Follow the \fBBranching and Workflow\fR of this guide\&. +.PP +.SH "BRANCHING AND WORKFLOW" +.SS "PACKAGE DEPENDENCIES" +Regarding packages and dependencies between them Tcllib occupies a +middle position between two extremes: +.IP [1] +On one side a strongly interdependent set of packages, usually +by a single author, for a single project\&. Looking at my +(Andreas Kupries) own work examples of such are +\fIMarpa\fR [https://core\&.tcl\&.tk/akupries/marpa/index], +\fICRIMP\fR [https://core\&.tcl\&.tk/akupries/crimp/index], +\fIKinetcl\fR [https://core\&.tcl\&.tk/akupries/kinetcl/index], etc\&. +.sp +For every change the author of the project handles all the +modifications cascading from any incompatibilities it +introduced to the system\&. +.IP [2] +On the other side, the world of semi-independent projects by +many different authors where authors know what packages their +own creations depend on, yet usually do not know who else +depends on them\&. +.sp +The best thing an author making an (incompatible) change to +their project can do is to for one announce such changes in +some way, and for two use versioning to distinguish the code +before and after the change\&. +.sp +The world is then responsible for adapting, be it by updating +their own projects to the new version, or by sticking to the +old\&. +.PP +As mentioned already, Tcllib lives in the middle of that\&. +.PP +While we as maintainers cannot be aware of all users of +Tcllib's packages, and thus have to rely on the mechanisms +touched on in point 2 above for that, the dependencies between +the packages contained in Tcllib are a different matter\&. +.PP +As we are collectively responsible for the usability of Tcllib +in toto to the outside world, it behooves us to be individually +mindful even of Tcllib packages we are not directly +maintaining, when they depend on packages under our +maintainership\&. +This may be as simple as coordinating with the maintainers of +the affected packages\&. +It may also require us to choose how to adapt affected packages +which do not have maintainers, i\&.e\&. modify them to use our +changed package properly, or modify them to properly depend on +the unchanged version of our package\&. +.PP +Note that the above is not only a chore but an opportunity as +well\&. +Additional insight can be had by forcing ourselves to look at +our package and the planned change(s) from an outside +perspective, to consider the ramifications of our actions on +others in general, and on dependent packages in particular\&. +.SS TRUNK +The management and use of branches is an important part of working +with a \fIDistributed Version Control System\fR (\fIDVCS\fR) like +\fIfossil\fR [https://www\&.fossil-scm\&.org/]\&. +.PP +For Tcllib the main branch of the collection is +\fItrunk\fR\&. In \fIgit\fR this branch would be called +\fImaster\fR, and this is exactly the case in the +\fIgithub mirror\fR [https://github\&.com/tcltk/tcllib/] of +Tcllib\&. +.PP +To properly support debugging \fIeach commit\fR on this +branch \fIhas to pass the entire testsuite\fR of the +collection\&. Using bisection to determine when an issue appeared +is an example of an action made easier by this constraint\&. +.PP +This is part of our collective responsibility for the usability +of Tcllib in toto to the outside world\&. +As \fIfossil\fR has no mechanism to enforce this condition +this is handled on the honor system for developers and maintainers\&. +.PP +To make the task easier Tcllib comes with a tool +("\fIsak\&.tcl\fR") providing a number of commands in +support\&. These commands are explained in the following sections +of this guide\&. +.PP +While it is possible and allowed to commit directly to trunk +remember the above constraint regarding the testsuite, and the +coming notes about other possible issues with a commit\&. +.SS BRANCHES +Given the constraints placed on the \fItrunk\fR branch of the +repository it is (strongly) recommended to perform any development +going beyond trivial changes on a non-trunk branch\&. +.PP +Outside of the trunk developers are allowed to commit +intermediate broken states of their work\&. +Only at the end of a development cycle, when the relevant +branch is considered ready for merging, will it be necessary to +perform full the set of validations ensuring that the merge to +come will create a good commit on trunk\&. +.PP +Note that while a review from a second developer is not a +required condition for merging a branch it is recommended to +seek out such an independent opinion as a means of +cross-checking the work\&. +.PP +It also recommended to give any new branch a name which aids in +determining additional details about it\&. Examples of good +things to stick into a branch name would be +.IP \(bu +Developer (nick)name +.IP \(bu +Ticket hash/reference +.IP \(bu +One or two keywords applicable to the work +.IP \(bu +\&.\&.\&. +.PP +.PP +Further, while most development branches are likely quite +short-lived, no prohibitions exist against making longer-lived +branches\&. +Creators should however be mindful that the longer such a +branch exists without merges the more divergent they will tend +to be, with an associated increase in the effort which will +have to be spent on either merging from and merging to trunk\&. +.SS "WORKING WITH BRANCHES" +In the hope of engendering good work practices now a few example +operations which will come up with branches, and their associated +fossil command (sequences)\&. +.TP +\fIAwareness\fR +When developing we have to keep ourselves aware of the context of our +work\&. On what branch are we ? What files have we changed ? What new +files are not yet known to the repository ? What has happened remotely +since we used our checkout ? +The answers to these questions become especially important when using +a long-lived checkout and coming back to it after some time away\&. +.sp +Commands to answer questions like the above are: +.RS +.TP +\fBfossil pull\fR +Get all changes done on the remote since the last pull or sync +from it\&. This has to be done first, before any of the commands +below\&. +.sp +Even if the commit in our checkout refers to the branch we want +right now control operations committed to the remote may have +changed that from underneath us\&. +.TP +\fBfossil info | grep tags\fR +.TP +\fBfossil branch list | grep '\\*'\fR +Two different ways of determining the branch our checkout is +on\&. +.TP +\fBfossil timeline\fR +What have we (and others) done recently ? +.sp +\fIAttention\fR, this information is very likely outdated, the +more the longer we did not use this checkout\&. +Run \fBfossil pull\fR first to get latest information from +the remote repository of the project\&. +.TP +\fBfossil timeline current\fR +Place the commit our checkout is based on at the top of the +timeline\&. +.TP +\fBfossil changes\fR +Lists the files we have changed compared to the commit the +checkout is based on\&. +.TP +\fBfossil extra\fR +Lists the files we have in the checkout the repository does not +know about\&. This may be leftover chaff from our work, or +something we have forgotten to \fBfossil add\fR to the +repository yet\&. +.RE +.TP +\fIClean checkouts\fR +Be aware of where you are (see first definition)\&. +.sp +For pretty much all the operation recipes below a clean +checkout is at least desired, often required\&. +To check that a checkout is clean invoke +.CS + + + fossil changes + fossil extra + +.CE +.IP +How to clean up when uncommitted changes of all sorts are found is +context-specific and outside of the scope of this guide\&. +.TP +\fIStarting a new branch\fR +Be aware of where you are (see first definition)\&. +.sp +Ensure that you have clean checkout (see second definition)\&. +It is \fIrequired\fR\&. +.sp +In most situations you want to be on branch \fItrunk\fR, and +you want to be on the latest commit for it\&. To get there use +.CS + + + fossil pull + fossil update trunk + +.CE +.IP +If some other branch is desired as the starting point for the coming +work replace \fItrunk\fR in the commands above with the name of that +branch\&. +.sp +With the base line established we now have two ways of creating +the new branch, with differing (dis)advantages\&. +The simpler way is to +.CS + + + fossil branch new NAME_OF_NEW_BRANCH + +.CE +.IP +and start developing\&. The advantage here is that you cannot forget to +create the branch\&. The disadvantages are that we have a branch commit +unchanged from where we branched from, and that we have to use +high-handed techniques like hiding or shunning to get rid of the +commit should we decide to abandon the work before the first actual +commit on the branch\&. +.sp +The other way of creating the branch is to start developing, +and then on the first commit use the option \fB--branch\fR to tell +\fBfossil\fR that we are starting a branch now\&. I\&.e\&. run +.CS + + + fossil commit --branch NAME_OF_NEW_BRANCH \&.\&.\&. + +.CE +.IP +where \fI\&.\&.\&.\fR are any other options used to supply the commit +message, files to commit, etc\&. +.sp +The (dis)advantages are now reversed\&. +.sp +We have no superflous commit, only what is actually +developed\&. The work is hidden until we commit to make our first +commit\&. +.sp +We may forget to use \fB--branch NAME_OF_NEW_BRANCH\fR and +then have to correct that oversight via the fossil web +interface (I am currently unaware of ways of doing such from +the command line, although some magic incantantion of +\fBfossil tag create\fR may work)\&. +.sp +It helps to keep awareness, like checking before any commit +that we are on the desired branch\&. +.TP +\fIMerging a branch into trunk\fR +Be aware of where you are (see first definition)\&. +.sp +Ensure that you have clean checkout (see second definition)\&. +In the full-blown sequence (zig-zag) it is \fIrequired\fR, due +to the merging from trunk\&. In the shorter sequence it is only +desired\&. That said, keeping the checkout clean before +any major operations is a good habit to have, in my opinion\&. +.sp +The full-blown sequencing with checks all the way is to +.RS +.IP [1] +Validate the checkout, i\&.e\&. last commit on your branch\&. Run the +full test suite and other validations, fix all the issues which +have cropped up\&. +.IP [2] +Merge the latest state of the \fItrunk\fR (see next definition)\&. +.IP [3] +Validate the checkout again\&. The incoming trunk changes may +have broken something now\&. Do any required fixes\&. +.IP [4] +Now merge to the trunk using +.CS + + + fossil update trunk + fossil merge --integrate YOUR_BRANCH + +.CE +.IP [5] +At this point the checkout should be in the same state as at +the end of point (3) above, because we resolved any issues with +the trunk already\&. Thus a simple +.CS + + + fossil commit \&.\&.\&. + +.CE +.IP +should be sufficient now to commit the merge back and close the +branch (due to the \fB--integrate\fR we used on the merge)\&. +.sp +The more paranoid may validate the checkout a third time before +commiting\&. +.RE +.sp +I call this a \fIzig-zag merge\fR because of how the arrows +look in the timeline, from trunk to feature branch for the +first merge, and then back for the final merge\&. +.sp +A less paranoid can do what I call a \fIsimple merge\fR, +which moves step (2) after step (4) and skips step (3) +entirely\&. The resulting shorter sequence is +.RS +.IP [1] +Validate +.IP [2] +Merge to trunk +.IP [3] +Validate again +.IP [4] +Commit to trunk +.RE +.IP +The last step after either zig-zag or plain merge is to +.CS + + + fossil sync + +.CE +.IP +This saves our work to the remote side, and further gives us any other +work done while we were doing our merge\&. It especially allows us to +check if we raced somebody else, resulting in a split trunk\&. +.sp +When that happens we should coordinate with the other developer +on who fixes the split, to ensure that we do not race each +other again\&. +.TP +\fIMerging from trunk\fR +Be aware of where you are (see first definition)\&. +.sp +Ensure that you have clean checkout (see second definition)\&. +It is \fIrequired\fR\&. +.sp +In most situations you want to import the latest commit of +branch \fItrunk\fR (or other origin)\&. To get it use +.CS + + + fossil pull + +.CE +.sp +With that done we can now import this commit into our current +branch with +.CS + + + fossil merge trunk + +.CE +.sp +Even if \fBfossil\fR does not report any conflicts it is a +good idea to check that the operation has not broken the new +and/or changed functionality we are working on\&. +.sp +With the establishment of a good merge we then save the state +with +.CS + + + fossil commit \&.\&.\&. + +.CE +.IP +before continuing development\&. +.PP +.SS "VERSION NUMBERS" +In Tcllib all changes to a package have to come with an increment of +its version number\&. What part is incremented (patchlevel, minor, major +version) depends on the kind of change made\&. With multiple changes in +a commit the highest "wins"\&. +.PP +When working in a development branch the version change can be +deferred until it is time to merge, and then has to cover all +the changes in the branch\&. +.PP +Below a list of the kinds of changes and their associated +version increments: +.TP +\fID - documentation\fR +No increment +.TP +\fIT - testsuite\fR +No increment +.TP +\fIB - bugfix\fR +Patchlevel +.TP +\fII - implementation tweak\fR +Patchlevel +.TP +\fIP - performance tweak\fR +Patchlevel +.TP +\fIE - backward-compatible extension\fR +Minor +.TP +\fIAPI - incompatible change\fR +Major +.PP +.PP +Note that a commit containing a version increment has to +mention the new version number in its commit message, as well +as the kind of change which caused it\&. +.PP +Note further that the version number of a package currently +exists in three places\&. An increment has to update all of them: +.IP [1] +The package implementation\&. +.IP [2] +The package index ("\fIpkgIndex\&.tcl\fR") +.IP [3] +The package documentation\&. +.PP +.PP +The "\fIsak\&.tcl\fR" command \fBvalidate version\fR helps +finding discrepancies between the first two\&. +All the other \fBvalidate\fR methods are also of interest to +any developer\&. Invoke it with +.CS + + sak\&.tcl help validate +.CE +to see their documentation\&. +.SH "STRUCTURAL OVERVIEW" +.SS "MAIN DIRECTORIES" +The main directories in the Tcllib toplevel directory and of interest +to a developer are: +.TP +"\fImodules\fR" +Each child directory represents one or more packages\&. +In the case of the latter the packages are usually related in some +way\&. Examples are "\fIbase64\fR", "\fImath\fR", and "\fIstruct\fR", with +loose (base64) to strong (math) relations between the packages in the +directory\&. +.TP +"\fIapps\fR" +This directory contains all the installable applications, with their +documentation\&. Note that this directory is currently \fInot\fR split +into sub-directories\&. +.TP +"\fIexamples\fR" +Each child directory "\fIfoo\fR" contains one or more example +application for the packages in "\fImodules/foo\fR"\&. These examples are +generally not polished enough to be considered for installation\&. +.PP +.SS "MORE DIRECTORIES" +.TP +"\fIconfig\fR" +This directory contains files supporting the Unix build system, +i\&.e\&. "\fIconfigure\fR" and "\fIMakefile\&.in\fR"\&. +.TP +"\fIdevdoc\fR" +This directories contains the doctools sources for the global +documentation, like this document and its sibling guides\&. +.TP +"\fIembedded\fR" +This directory contains the entire documentation formatted for +\fIHTML\fR and styled to properly mix into the web site generated by +fossil for the repository\&. +.sp +This is the documentation accessible from the Tcllib home +directory, represented in the repository as "\fIembedded/index\&.md\fR"\&. +.TP +"\fIidoc\fR" +This directory contains the entire documentation formatted for +\fInroff\fR and \fIHTML\fR, the latter without any styling\&. +This is the documentation which will be installed\&. +.TP +"\fIsupport\fR" +This directory contains the sources of internal packages and utilities +used in the implementation of the "\fIinstaller\&.tcl\fR" and +"\fIsak\&.tcl\fR" scripts/tools\&. +.PP +.SS "TOP FILES" +.TP +"\fIaclocal\&.m4\fR" +.TP +"\fIconfigure\fR" +.TP +"\fIconfigure\&.in\fR" +.TP +"\fIMakefile\&.in\fR" +These four files comprise the Unix build system layered on top of the +"\fIinstaller\&.tcl\fR" script\&. +.TP +"\fIinstaller\&.tcl\fR" +The Tcl-based installation script/tool\&. +.TP +"\fIproject\&.shed\fR" +Configuration file for \fISean Wood\fR's \fBPracTcl\fR +buildsystem\&. +.TP +"\fIsak\&.tcl\fR" +This is the main tool for developers and release managers, the +\fISwiss Army Knife\fR of management operations on the collection\&. +.TP +"\fIChangeLog\fR" +The log of changes to the global support, when the sources were held +in \fICVS\fR\&. Not relevant any longer with the switch to the +\fIfossil\fR SCM\&. +.TP +"\fIlicense\&.terms\fR" +The license in plain ASCII\&. See also \fITcllib - License\fR for the +nicely formatted form\&. The text is identical\&. +.TP +"\fIREADME\&.md\fR" +.TP +"\fI\&.github/CONTRIBUTING\&.md\fR" +.TP +"\fI\&.github/ISSUE_TEMPLATE\&.md\fR" +.TP +"\fI\&.github/PULL_REQUEST_TEMPLATE\&.md\fR" +These markdown-formatted documents are used and shown by the github +mirror of these sources, pointing people back to the official location +and issue trackers\&. +.TP +"\fIDESCRIPTION\&.txt\fR" +.TP +"\fISTATUS\fR" +.TP +"\fItcllib\&.spec\fR" +.TP +"\fItcllib\&.tap\fR" +.TP +"\fItcllib\&.yml\fR" +???? +.PP +.SS "FILE TYPES" +The most common file types, by file extension, are: +.TP +"\fI\&.tcl\fR" +Tcl code for a package, application, or example\&. +.TP +"\fI\&.man\fR" +Doctools-formatted documentation, usually for a package\&. +.TP +"\fI\&.test\fR" +Test suite for a package, or part of\&. +Based on \fBtcltest\fR\&. +.TP +"\fI\&.bench\fR" +Performance benchmarks for a package, or part of\&. +Based on "\fImodules/bench\fR"\&. +.TP +"\fI\&.pcx\fR" +Syntax rules for \fITclDevKit\fR's \fBtclchecker\fR\&. Using these +rules allows the checker to validate the use of commands of a Tcllib +package \fBfoo\fR without having to scan the "\fI\&.tcl\fR" files +implementing it\&. +.PP +.SH "TESTSUITE TOOLING" +Testsuites in Tcllib are based on Tcl's standard test package +\fBtcltest\fR, plus utilities found in the directory +"\fImodules/devtools\fR" +.PP +Tcllib developers invoke the suites through the +\fBtest run\fR method of the "\fIsak\&.tcl\fR" tool, with other methods +of \fBtest\fR providing management operations, for example setting a +list of standard Tcl shells to use\&. +.SS "INVOKE THE TESTSUITES OF A SPECIFIC MODULE" +Invoke either +.CS + + \&./sak\&.tcl test run foo +.CE +or +.CS + + \&./sak\&.tcl test run modules/foo +.CE +to invoke the testsuites found in a specific module "\fIfoo\fR"\&. +.SS "INVOKE THE TESTSUITES OF ALL MODULES" +Invoke the tool without a module name, i\&.e\&. +.CS + + \&./sak\&.tcl test run +.CE +to invoke the testsuites of all modules\&. +.SS "DETAILED TEST LOGS" +In all the previous examples the test runner will write a combination +of progress display and testsuite log to the standard output, showing +for each module only the tests that passed or failed and how many of +each in a summary at the end\&. +.PP +To get a detailed log, it is necessary to invoke the test +runner with additional options\&. +.PP +For one: +.CS + + + \&./sak\&.tcl test run --log LOG foo + +.CE +While this shows the same short log on the terminal as before, it also +writes a detailed log to the file "\fILOG\&.log\fR", and excerpts to +other files ("\fILOG\&.summary\fR", "\fILOG\&.failures\fR", etc\&.)\&. +.PP +For two: +.CS + + + \&./sak\&.tcl test run -v foo + +.CE +This writes the detailed log to the standard output, instead of the +short log\&. +.PP +Regardless of form, the detailed log contains a list of all test +cases executed, which failed, and how they failed (expected versus +actual results)\&. +.SS "SHELL SELECTION" +By default the test runner will use all the Tcl shells specified via +\fBtest add\fR to invoke the specified testsuites, if any\&. If no +such are specified it will fall back to the Tcl shell used to run the +tool itself\&. +.PP +Use option \fB--shell\fR to explicitly specify the Tcl shell +to use, like +.CS + + + \&./sak\&.tcl test run --shell /path/to/tclsh \&.\&.\&. + +.CE +.SS HELP +Invoke the tool as +.CS + + \&./sak\&.tcl help test +.CE +to see the detailed help for all methods of \fBtest\fR, and the +associated options\&. +.SH "DOCUMENTATION TOOLING" +The standard format used for documentation of packages and other +things in Tcllib is \fIdoctools\fR\&. +Its supporting packages are a part of Tcllib, see the directories +"\fImodules/doctools\fR" and "\fImodules/dtplite\fR"\&. The latter is +an application package, with the actual application +"\fIapps/dtplite\fR" a light wrapper around it\&. +.PP +Tcllib developers gain access to these through the \fBdoc\fR +method of the "\fIsak\&.tcl\fR" tool, another (internal) wrapper around +the "\fImodules/dtplite\fR" application package\&. +.SS "GENERATE DOCUMENTATION FOR A SPECIFIC MODULE" +Invoke either +.CS + + \&./sak\&.tcl doc html foo +.CE +or +.CS + + \&./sak\&.tcl doc html modules/foo +.CE +to generate HTML for the documentation found in the module "\fIfoo\fR"\&. +Instead of \fBhtml\fR any other supported format can be used here, +of course\&. +.PP +The generated formatted documentation will be placed into a +directory "\fIdoc\fR" in the current working directory\&. +.SS "GENERATE DOCUMENTATION FOR ALL MODULES" +Invoke the tool without a module name, i\&.e\&. +.CS + + \&./sak\&.tcl doc html +.CE +to generate HTML for the documentation found in all modules\&. +Instead of \fBhtml\fR any other supported format can be used here, +of course\&. +.PP +The generated formatted documentation will be placed into a +directory "\fIdoc\fR" in the current working directory\&. +.SS "AVAILABLE OUTPUT FORMATS, HELP" +Invoke the tool as +.CS + + \&./sak\&.tcl help doc +.CE +to see the entire set of supported output formats which can be +generated\&. +.SS "VALIDATION WITHOUT OUTPUT" +Note the special format \fBvalidate\fR\&. +.PP +Using this value as the name of the format to generate forces +the tool to simply check that the documentation is syntactically +correct, without generating actual output\&. +.PP +Invoke it as either +.CS + + \&./sak\&.tcl doc validate (modules/)foo +.CE +or +.CS + + \&./sak\&.tcl doc validate +.CE +to either check the packages of a specific module or check all of +them\&. +.SH "NOTES ON WRITING A TESTSUITE" +While previous sections talked about running the testsuites for a +module and the packages therein, this has no meaning if the module in +question has no testsuites at all\&. +.PP +This section gives a very basic overview on possible +methodologies for writing tests and testsuites\&. +.PP +First there are "drudgery" tests\&. Written to check absolutely +basic assumptions which should never fail\&. +.PP +For example for a command FOO taking two arguments, three tests +calling it with zero, one, and three arguments\&. The basic checks that +the command fails if it has not enough arguments, or too many\&. +.PP +After that come the tests checking things based on our +knowledge of the command, about its properties and assumptions\&. Some +examples based on the graph operations added during Google's Summer of +Code 2009 are: +.IP \(bu +The BellmanFord command in struct::graph::ops takes a +\fIstartnode\fR as argument, and this node should be a node of +the graph\&. This equals one test case checking the behavior when the +specified node is not a node of the graph\&. +.sp +This often gives rise to code in the implementation which +explicitly checks the assumption and throws an understandable error, +instead of letting the algorithm fail later in some weird +non-deterministic way\&. +.sp +It is not always possible to do such checks\&. The graph argument +for example is just a command in itself, and while we expect +it to exhibit a certain interface, i\&.e\&. a set of sub-commands +aka methods, we cannot check that it has them, except by +actually trying to use them\&. That is done by the algorithm +anyway, so an explicit check is just overhead we can get by +without\&. +.IP \(bu +IIRC one of the distinguishing characteristic of either +BellmanFord and/or Johnson is that they are able to handle +negative weights\&. Whereas Dijkstra requires positive weights\&. +.sp +This induces (at least) three testcases \&.\&.\&. Graph with all +positive weights, all negative, and a mix of positive and +negative weights\&. +Thinking further does the algorithm handle the weight +\fB0\fR as well ? Another test case, or several, if we mix +zero with positive and negative weights\&. +.IP \(bu +The two algorithms we are currently thinking about are about +distances between nodes, and distance can be 'Inf'inity, +i\&.e\&. nodes may not be connected\&. This means that good test +cases are +.RS +.IP [1] +Strongly connected graph +.IP [2] +Connected graph +.IP [3] +Disconnected graph\&. +.RE +.sp +At the extremes of strongly connected and disconnected +we have the fully connected graphs and graphs without edges, +only nodes, i\&.e\&. completely disconnected\&. +.IP \(bu +IIRC both of the algorithms take weighted arcs, and fill in a +default if arcs are left unweighted in the input graph\&. +.sp +This also induces three test cases: +.RS +.IP [1] +Graph will all arcs with explicit weights\&. +.IP [2] +Graph without weights at all\&. +.IP [3] +Graph with mixture of weighted and unweighted graphs\&. +.RE +.PP +.PP +What was described above via examples is called +\fIblack-box\fR testing\&. Test cases are designed and written based on +the developer's knowledge of the properties of the algorithm and its +inputs, without referencing a particular implementation\&. +.PP +Going further, a complement to \fIblack-box\fR testing is +\fIwhite-box\fR\&. For this we know the implementation of the +algorithm, we look at it and design our tests cases so that they force +the code through all possible paths in the implementation\&. Wherever a +decision is made we have a test case forcing a specific direction of +the decision, for all possible combinations and directions\&. It is easy +to get a combinatorial explosion in the number of needed test-cases\&. +.PP +In practice I often hope that the black-box tests I have made +are enough to cover all the paths, obviating the need for white-box +tests\&. +.PP +The above should be enough to make it clear that writing tests +for an algorithm takes at least as much time as coding the algorithm, +and often more time\&. Much more time\&. +See for example also \fIhttp://sqlite\&.org/testing\&.html\fR, a writeup +on how the Sqlite database engine is tested\&. Another article of +interest might be \fIhttps://www\&.researchgate\&.net/publication/298896236\fR\&. +While geared to a particular numerical algorithm it still shows that +even a simple-looking algorithm can lead to an incredible number of +test cases\&. +.PP +An interesting connection is to documentation\&. In one +direction, the properties checked with black-box testing are exactly +the properties which should be documented in the algorithm's man +page\&. And conversely, the documentation of the properties of an +algorithm makes a good reference to base the black-box tests on\&. +.PP +In practice test cases and documentation often get written +together, cross-influencing each other\&. And the actual writing of test +cases is a mix of black and white box, possibly influencing the +implementation while writing the tests\&. Like writing a test for a +condition like \fIstartnode not in input graph\fR serving as +reminder to put a check for this condition into the code\&. +.SH "INSTALLATION TOOLING" +A last thing to consider when adding a new package to the collection +is installation\&. +.PP +How to \fIuse\fR the "\fIinstaller\&.tcl\fR" script is documented +in \fITcllib - The Installer's Guide\fR\&. +.PP +Here we document how to extend said installer so that it may +install new package(s) and/or application(s)\&. +.PP +In most cases only a single file has to be modified, the +"\fIsupport/installation/modules\&.tcl\fR" holding one command per module +and application to install\&. +.PP +The relevant commands are: +.TP +\fBModule\fR \fIname\fR \fIcode-action\fR \fIdoc-action\fR \fIexample-action\fR +Install the packages of module \fIname\fR, found in +"\fImodules/\fIname\fR\fR"\&. +.sp +The \fIcode-action\fR is responsible for installing the +packages and their index\&. The system currently provides +.RS +.TP +\fB_tcl\fR +Copy all "\fI\&.tcl\fR" files found in +"\fImodules/\fIname\fR\fR" into the installation\&. +.TP +\fB_tcr\fR +As \fB_tcl\fR, copy the "\fI\&.tcl\fR" files found in +the subdirectories of "\fImodules/\fIname\fR\fR" as well\&. +.TP +\fB_tci\fR +As \fB_tcl\fR, and copy the "\fItclIndex\&.tcl\fR" file +as well\&. +.TP +\fB_msg\fR +As \fB_tcl\fR, and copy the subdirectory "\fImsgs\fR" +as well\&. +.TP +\fB_doc\fR +As \fB_tcl\fR, and copy the subdirectory +"\fImpformats\fR" as well\&. +.TP +\fB_tex\fR +As \fB_tcl\fR, and copy "\fI\&.tex\fR" files as well\&. +.RE +.sp +The \fIdoc-action\fR is responsible for installing the package +documentation\&. The system currently provides +.RS +.TP +\fB_null\fR +No documentation available, do nothing\&. +.TP +\fB_man\fR +Process the "\fI\&.man\fR" files found in +"\fImodules/\fIname\fR\fR" and install the results (nroff and/or HTML) +in the proper location, as given to the installer\&. +.sp +This is actually a fallback, normally the installer uses the +pre-made formatted documentation found under "\fIidoc\fR"\&. +.RE +.sp +The \fIexample-action\fR is responsible for installing the +examples\&. The system currently provides +.RS +.TP +\fB_null\fR +No examples available, do nothing\&. +.TP +\fB_exa\fR +Copy the the directory "\fIexamples/\fIname\fR\fR" +recursively to the install location for examples\&. +.RE +.TP +\fBApplication\fR \fIname\fR +Install the application with \fIname\fR, found in "\fIapps\fR"\&. +.TP +\fBExclude\fR \fIname\fR +This command signals to the installer which of the listed modules to +\fInot\fR install\&. I\&.e\&. they name the deprecated modules of Tcllib\&. +.PP +.PP +If, and only if the above actions are not suitable for the new +module then a second file has to be modified, +"\fIsupport/installation/actions\&.tcl\fR"\&. +.PP +This file contains the implementations of the available +actions, and is the place where any custom action needed to handle the +special circumstances of module has to be added\&. ADDED idoc/man/files/devdoc/tcllib_installer.n Index: idoc/man/files/devdoc/tcllib_installer.n ================================================================== --- /dev/null +++ idoc/man/files/devdoc/tcllib_installer.n @@ -0,0 +1,596 @@ +'\" +'\" Generated from file 'tcllib_installer\&.man' by tcllib/doctools with format 'nroff' +'\" +.TH "tcllib_install_guide" n 1 tcllib "" +.\" The -*- nroff -*- definitions below are for supplemental macros used +.\" in Tcl/Tk manual entries. +.\" +.\" .AP type name in/out ?indent? +.\" Start paragraph describing an argument to a library procedure. +.\" type is type of argument (int, etc.), in/out is either "in", "out", +.\" or "in/out" to describe whether procedure reads or modifies arg, +.\" and indent is equivalent to second arg of .IP (shouldn't ever be +.\" needed; use .AS below instead) +.\" +.\" .AS ?type? ?name? +.\" Give maximum sizes of arguments for setting tab stops. Type and +.\" name are examples of largest possible arguments that will be passed +.\" to .AP later. If args are omitted, default tab stops are used. +.\" +.\" .BS +.\" Start box enclosure. From here until next .BE, everything will be +.\" enclosed in one large box. +.\" +.\" .BE +.\" End of box enclosure. +.\" +.\" .CS +.\" Begin code excerpt. +.\" +.\" .CE +.\" End code excerpt. +.\" +.\" .VS ?version? ?br? +.\" Begin vertical sidebar, for use in marking newly-changed parts +.\" of man pages. The first argument is ignored and used for recording +.\" the version when the .VS was added, so that the sidebars can be +.\" found and removed when they reach a certain age. If another argument +.\" is present, then a line break is forced before starting the sidebar. +.\" +.\" .VE +.\" End of vertical sidebar. +.\" +.\" .DS +.\" Begin an indented unfilled display. +.\" +.\" .DE +.\" End of indented unfilled display. +.\" +.\" .SO ?manpage? +.\" Start of list of standard options for a Tk widget. The manpage +.\" argument defines where to look up the standard options; if +.\" omitted, defaults to "options". The options follow on successive +.\" lines, in three columns separated by tabs. +.\" +.\" .SE +.\" End of list of standard options for a Tk widget. +.\" +.\" .OP cmdName dbName dbClass +.\" Start of description of a specific option. cmdName gives the +.\" option's name as specified in the class command, dbName gives +.\" the option's name in the option database, and dbClass gives +.\" the option's class in the option database. +.\" +.\" .UL arg1 arg2 +.\" Print arg1 underlined, then print arg2 normally. +.\" +.\" .QW arg1 ?arg2? +.\" Print arg1 in quotes, then arg2 normally (for trailing punctuation). +.\" +.\" .PQ arg1 ?arg2? +.\" Print an open parenthesis, arg1 in quotes, then arg2 normally +.\" (for trailing punctuation) and then a closing parenthesis. +.\" +.\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages. +.if t .wh -1.3i ^B +.nr ^l \n(.l +.ad b +.\" # Start an argument description +.de AP +.ie !"\\$4"" .TP \\$4 +.el \{\ +. ie !"\\$2"" .TP \\n()Cu +. el .TP 15 +.\} +.ta \\n()Au \\n()Bu +.ie !"\\$3"" \{\ +\&\\$1 \\fI\\$2\\fP (\\$3) +.\".b +.\} +.el \{\ +.br +.ie !"\\$2"" \{\ +\&\\$1 \\fI\\$2\\fP +.\} +.el \{\ +\&\\fI\\$1\\fP +.\} +.\} +.. +.\" # define tabbing values for .AP +.de AS +.nr )A 10n +.if !"\\$1"" .nr )A \\w'\\$1'u+3n +.nr )B \\n()Au+15n +.\" +.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n +.nr )C \\n()Bu+\\w'(in/out)'u+2n +.. +.AS Tcl_Interp Tcl_CreateInterp in/out +.\" # BS - start boxed text +.\" # ^y = starting y location +.\" # ^b = 1 +.de BS +.br +.mk ^y +.nr ^b 1u +.if n .nf +.if n .ti 0 +.if n \l'\\n(.lu\(ul' +.if n .fi +.. +.\" # BE - end boxed text (draw box now) +.de BE +.nf +.ti 0 +.mk ^t +.ie n \l'\\n(^lu\(ul' +.el \{\ +.\" Draw four-sided box normally, but don't draw top of +.\" box if the box started on an earlier page. +.ie !\\n(^b-1 \{\ +\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.el \}\ +\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.\} +.fi +.br +.nr ^b 0 +.. +.\" # VS - start vertical sidebar +.\" # ^Y = starting y location +.\" # ^v = 1 (for troff; for nroff this doesn't matter) +.de VS +.if !"\\$2"" .br +.mk ^Y +.ie n 'mc \s12\(br\s0 +.el .nr ^v 1u +.. +.\" # VE - end of vertical sidebar +.de VE +.ie n 'mc +.el \{\ +.ev 2 +.nf +.ti 0 +.mk ^t +\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n' +.sp -1 +.fi +.ev +.\} +.nr ^v 0 +.. +.\" # Special macro to handle page bottom: finish off current +.\" # box/sidebar if in box/sidebar mode, then invoked standard +.\" # page bottom macro. +.de ^B +.ev 2 +'ti 0 +'nf +.mk ^t +.if \\n(^b \{\ +.\" Draw three-sided box if this is the box's first page, +.\" draw two sides but no top otherwise. +.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.\} +.if \\n(^v \{\ +.nr ^x \\n(^tu+1v-\\n(^Yu +\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c +.\} +.bp +'fi +.ev +.if \\n(^b \{\ +.mk ^y +.nr ^b 2 +.\} +.if \\n(^v \{\ +.mk ^Y +.\} +.. +.\" # DS - begin display +.de DS +.RS +.nf +.sp +.. +.\" # DE - end display +.de DE +.fi +.RE +.sp +.. +.\" # SO - start of list of standard options +.de SO +'ie '\\$1'' .ds So \\fBoptions\\fR +'el .ds So \\fB\\$1\\fR +.SH "STANDARD OPTIONS" +.LP +.nf +.ta 5.5c 11c +.ft B +.. +.\" # SE - end of list of standard options +.de SE +.fi +.ft R +.LP +See the \\*(So manual entry for details on the standard options. +.. +.\" # OP - start of full description for a single option +.de OP +.LP +.nf +.ta 4c +Command-Line Name: \\fB\\$1\\fR +Database Name: \\fB\\$2\\fR +Database Class: \\fB\\$3\\fR +.fi +.IP +.. +.\" # CS - begin code excerpt +.de CS +.RS +.nf +.ta .25i .5i .75i 1i +.. +.\" # CE - end code excerpt +.de CE +.fi +.RE +.. +.\" # UL - underline word +.de UL +\\$1\l'|0\(ul'\\$2 +.. +.\" # QW - apply quotation marks to word +.de QW +.ie '\\*(lq'"' ``\\$1''\\$2 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\$2 +.. +.\" # PQ - apply parens and quotation marks to word +.de PQ +.ie '\\*(lq'"' (``\\$1''\\$2)\\$3 +.\"" fix emacs highlighting +.el (\\*(lq\\$1\\*(rq\\$2)\\$3 +.. +.\" # QR - quoted range +.de QR +.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3 +.. +.\" # MT - "empty" string +.de MT +.QW "" +.. +.BS +.SH NAME +tcllib_install_guide \- Tcllib - The Installer's Guide +.SH DESCRIPTION +Welcome to Tcllib, the Tcl Standard Library\&. Note that Tcllib is not a +package itself\&. It is a collection of (semi-independent) \fITcl\fR +packages that provide utility functions useful to a large collection +of Tcl programmers\&. +.PP +The audience of this document is anyone wishing to build and install +the packages found in Tcllib, for either themselves, or others\&. +.PP +For developers intending to work on the packages themselves we +additionally provide +.IP [1] +\fITcllib - The Developer's Guide\fR\&. +.PP +.PP +Please read \fITcllib - How To Get The Sources\fR first, if that +was not done already\&. Here we assume that the sources are already +available in a directory of your choice\&. +.PP +.SH REQUISITES +Before Tcllib can be build and used a number of requisites must be installed\&. +These are: +.IP [1] +The scripting language Tcl\&. +For details see \fBTcl\fR\&. +.IP [2] +Optionally, the \fBcritcl\fR package (C embedding) for \fBTcl\fR\&. +For details see \fBCriTcl\fR\&. +.PP +This list assumes that the machine where Tcllib is to be installed is +essentially clean\&. Of course, if parts of the dependencies listed +below are already installed the associated steps can be skipped\&. It is +still recommended to read their sections though, to validate that the +dependencies they talk about are indeed installed\&. +.SS TCL +As we are installing a number of Tcl packages and applications it +should be pretty much obvious that a working installation of Tcl +itself is needed, and I will not belabor the point\&. +.PP +Out of the many possibilities use whatever you are comfortable +with, as long as it provides at the very least Tcl 8\&.2, or higher\&. +This may be a Tcl installation provided by your operating system +distribution, from a distribution-independent vendor, or built by +yourself\&. +.PP +\fINote\fR that the packages in Tcllib have begun to require +8\&.4, 8\&.5, and even 8\&.6\&. Older versions of Tcl will not be able to use +such packages\&. Trying to use them will result in +\fIpackage not found\fR errors, as their package index files will +not register them in versions of the core unable to use them\&. +.PP +Myself, I used (and still use) +\fIActiveState's\fR [http://www\&.activestate\&.com] +ActiveTcl 8\&.5 distribution during development, as I am most familiar +with it\&. +.PP +\fI(Disclosure: I, Andreas Kupries, worked for ActiveState until 2016, maintaining ActiveTcl and TclDevKit for them)\&.\fR\&. +I am currently working for SUSE Software Canada ULC, although not in +Tcl-related areas\&. +.PP +This distribution can be found at +\fIhttp://www\&.activestate\&.com/activetcl\fR\&. Retrieve the archive of +ActiveTcl 8\&.5 (or higher) for your platform and install it as directed +by ActiveState\&. +.PP +For those wishing to build and install Tcl on their own, the +relevant sources can be found at +.TP +Tcl +\fIhttp://core\&.tcl-lang\&.org/tcl/\fR +.PP +together with the necessary instructions on how to build it\&. +.PP +If there are problems with building, installing, or using Tcl, +please file a ticket against \fITcl\fR, or the vendor of your +distribution, and \fInot\fR \fITcllib\fR\&. +.SS CRITCL +The \fBcritcl\fR tool is an \fIoptional\fR dependency\&. +.PP +It is only required when trying to build the C-based +\fIaccelerators\fR for a number of packages, as explained in +\fBCritcl & Accelerators\fR +.PP +Tcllib's build system looks for it in the , +using the name \fBcritcl\fR\&. This is for Unix\&. +On Windows on the other hand the search is more complex\&. First we look +for a proper application \fBcritcl\&.exe\fR\&. When that is not found +we look for a combination of interpreter (\fBtclkitsh\&.exe\fR, +\fBtclsh\&.exe\fR) and starkit (\fBcritcl\&.kit\fR, \fBcritcl\fR) +instead\&. \fINote\fR that the choice of starkit can be overriden via +the environment variable \&. +.PP +Tcllib requires Critcl version 2 or higher\&. +.PP +The github repository providing releases of version 2 and +higher, and the associated sources, can be found at +\fIhttp://andreas-kupries\&.github\&.com/critcl\fR\&. +.PP +Any branch of the repository can be used (if not using the +prebuild starkit or starpack), although the use of the stable branch +\fImaster\fR is recommended\&. +.PP +At the above url is also an explanation on how to build and +install Critcl, including a list of its dependencies\&. +.PP +Its instructions will not be repeated here\&. If there are +problems with these directions please file a ticket against the +\fICritcl\fR project, and not Tcllib\&. +.SH "BUILD & INSTALLATION INSTRUCTIONS" +As Tcllib is mainly a bundle of packages written in pure Tcl building +it is the same as installing it\&. The exceptions to this have their own +subsection, \fBCritcl & Accelerators\fR, later on\&. +.PP +Before that however comes the standard case, differentiated by +the platforms with material differences in the instruction, i\&.e\&. +\fIUnix\fR-like, versus \fIWindows\fR\&. +.PP +Regarding the latter it should also be noted that it is +possible set up an \fIUnix\fR-like environment using projects +like \fIMSYS\fR, \fICygwin\fR, and others\&. In that case the +user has the choice of which instructions to follow\&. +.PP +Regardless of environment or platform, a suitable \fITcl\fR +has to be installed, and its \fBtclsh\fR should be placed on +the (\fIUnix\fR) or associated with +"\fI\&.tcl\fR" files (\fIWindows\fR)\&. +.SS "INSTALLING ON UNIX" +For \fIUnix\fR-like environments Tcllib comes with the standard set +of files to make +.CS + + + \&./configure + make install + +.CE +a suitable way of installing it\&. +This is a standard non-interactive install automatically figuring out +where to place everything, i\&.e\&. packages, applications, and the +manpages\&. +.PP +To get a graphical installer invoke +.CS + + + \&./installer\&.tcl + +.CE +instead\&. +.SS "INSTALLING ON WINDOWS" +In a Windows environment we have the \fBinstaller\&.tcl\fR script to +perform installation\&. +.PP +If the desired \fBtclsh\fR is associated "\fI\&.tcl\fR" files +then double-clicking / opening the \fBinstaller\&.tcl\fR is +enough to invoke it in graphical mode\&. +This assumes that \fITk\fR is installed and available as well\&. +.PP +Without \fITk\fR the only way to invoke the installer are to +open a DOS window, i\&.e\&. \fBcmd\&.exe\fR, and then to invoke +.CS + + + \&./installer\&.tcl + +.CE +inside it\&. +.SS "CRITCL & ACCELERATORS" +While the majority of Tcllib consists of packages written in pure Tcl +a number of packages also have \fIaccelerators\fR associated with them\&. +These are \fBcritcl\fR-based C packages whose use will boost the +performance of the packages using them\&. +These accelerators are optional, and they are not installed by +default\&. +.PP +To build the accelerators the normally optional dependency on +\fBcritcl\fR becomes required\&. +.PP +To build and install Tcllib with the accelerators in a +Unix-like environment invoke: +.CS + + + \&./configure + make critcl # This builds the shared library holding + # the accelerators + make install + +.CE +.PP +The underlying tool is "\fIsak\&.tcl\fR" in the toplevel directory +of Tcllib and the command \fBmake critcl\fR is just a wrapper around +.CS + + + \&./sak\&.tcl critcl + +.CE +.PP +Therefore in a Windows environment instead invoke +.CS + + + \&./sak\&.tcl critcl + \&./installer\&.tcl + +.CE +from within a DOS window, i\&.e\&. \fBcmd\&.exe\fR\&. +.SS TOOLING +The core of Tcllib's build system is the script "\fIinstaller\&.tcl\fR" +found in the toplevel directory of a checkout or release\&. +.PP +The +.CS + + + configure ; make install + +.CE +setup available to +developers on Unix-like systems is just a wrapper around it\&. +To go beyond the standard embodied in the wrapper it is +necessary to directly invoke this script\&. +.PP +On Windows system using it directly is the only way to invoke +it\&. +.PP +For basic help invoke it as +.CS + + + \&./installer\&.tcl -help + +.CE +This will print a short list of all the available options to +the standard output channel\&. +.PP +The commands associated with the various \fIinstall\fR targets +in the \fIMakefile\&.in\fR for Unix can be used as additional +examples on how to use this tool as well\&. +.PP +The installer can operate in GUI and CLI modes\&. +By default it chooses the mode automatically, based on if the +Tcl package \fBTk\fR can be used or not\&. +The option \fB-no-gui\fR can be used to force CLI mode\&. +.PP +Note that it is possible to specify options on the command line +even if the installer ultimatively selects GUI mode\&. In that +case the hardwired defaults and the options determine the data +presented to the user for editing\&. +.PP +The installer will select a number of defaults for the +locations of packages, examples, and documentation, and also +the format of the documentation\&. The user can overide these +defaults in the GUI, or by specifying additional options\&. +The defaults depend on the platform detected (Unix/Windows) and +on the \fBtclsh\fR executable used to run the installer\&. +.PP +\fIOptions\fR +.TP +\fB-help\fR +Show the list of options explained here on the standard output channel +and exit\&. +.TP +\fB+excluded\fR +Include deprecated packages in the installation\&. +.TP +\fB-no-gui\fR +Force command line operation of the installer +.TP +\fB-no-wait\fR +In CLI mode the installer will by default ask the user to confirm that +the chosen configuration (destination paths, things to install) is +correct before performing any action\&. Using this option causes the +installer to skip this query and immediately jump to installation\&. +.TP +\fB-app-path\fR \fIpath\fR +.TP +\fB-example-path\fR \fIpath\fR +.TP +\fB-html-path\fR \fIpath\fR +.TP +\fB-nroff-path\fR \fIpath\fR +.TP +\fB-pkg-path\fR \fIpath\fR +Declare the destination paths for the applications, examples, html +documentation, nroff manpages, and packages\&. The defaults are derived +from the location of the \fBtclsh\fR used to run the installer\&. +.TP +\fB-dry-run\fR +.TP +\fB-simulate\fR +Run the installer without modifying the destination directories\&. +.TP +\fB-apps\fR +.TP +\fB-no-apps\fR +.TP +\fB-examples\fR +.TP +\fB-no-examples\fR +.TP +\fB-pkgs\fR +.TP +\fB-no-pkgs\fR +.TP +\fB-html\fR +.TP +\fB-no-html\fR +.TP +\fB-nroff\fR +.TP +\fB-no-nroff\fR +(De)activate the installation of applications, examples, packages, +html documentation, and nroff manpages\&. +.sp +Applications, examples, and packages are installed by default\&. +.sp +On Windows the html documentation is installed by default\&. +.sp +On Unix the nroff manpages are installed by default\&. +.PP ADDED idoc/man/files/devdoc/tcllib_license.n Index: idoc/man/files/devdoc/tcllib_license.n ================================================================== --- /dev/null +++ idoc/man/files/devdoc/tcllib_license.n @@ -0,0 +1,321 @@ +'\" +'\" Generated from file 'tcllib_license\&.man' by tcllib/doctools with format 'nroff' +'\" +.TH "tcllib_license" n 1 tcllib "" +.\" The -*- nroff -*- definitions below are for supplemental macros used +.\" in Tcl/Tk manual entries. +.\" +.\" .AP type name in/out ?indent? +.\" Start paragraph describing an argument to a library procedure. +.\" type is type of argument (int, etc.), in/out is either "in", "out", +.\" or "in/out" to describe whether procedure reads or modifies arg, +.\" and indent is equivalent to second arg of .IP (shouldn't ever be +.\" needed; use .AS below instead) +.\" +.\" .AS ?type? ?name? +.\" Give maximum sizes of arguments for setting tab stops. Type and +.\" name are examples of largest possible arguments that will be passed +.\" to .AP later. If args are omitted, default tab stops are used. +.\" +.\" .BS +.\" Start box enclosure. From here until next .BE, everything will be +.\" enclosed in one large box. +.\" +.\" .BE +.\" End of box enclosure. +.\" +.\" .CS +.\" Begin code excerpt. +.\" +.\" .CE +.\" End code excerpt. +.\" +.\" .VS ?version? ?br? +.\" Begin vertical sidebar, for use in marking newly-changed parts +.\" of man pages. The first argument is ignored and used for recording +.\" the version when the .VS was added, so that the sidebars can be +.\" found and removed when they reach a certain age. If another argument +.\" is present, then a line break is forced before starting the sidebar. +.\" +.\" .VE +.\" End of vertical sidebar. +.\" +.\" .DS +.\" Begin an indented unfilled display. +.\" +.\" .DE +.\" End of indented unfilled display. +.\" +.\" .SO ?manpage? +.\" Start of list of standard options for a Tk widget. The manpage +.\" argument defines where to look up the standard options; if +.\" omitted, defaults to "options". The options follow on successive +.\" lines, in three columns separated by tabs. +.\" +.\" .SE +.\" End of list of standard options for a Tk widget. +.\" +.\" .OP cmdName dbName dbClass +.\" Start of description of a specific option. cmdName gives the +.\" option's name as specified in the class command, dbName gives +.\" the option's name in the option database, and dbClass gives +.\" the option's class in the option database. +.\" +.\" .UL arg1 arg2 +.\" Print arg1 underlined, then print arg2 normally. +.\" +.\" .QW arg1 ?arg2? +.\" Print arg1 in quotes, then arg2 normally (for trailing punctuation). +.\" +.\" .PQ arg1 ?arg2? +.\" Print an open parenthesis, arg1 in quotes, then arg2 normally +.\" (for trailing punctuation) and then a closing parenthesis. +.\" +.\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages. +.if t .wh -1.3i ^B +.nr ^l \n(.l +.ad b +.\" # Start an argument description +.de AP +.ie !"\\$4"" .TP \\$4 +.el \{\ +. ie !"\\$2"" .TP \\n()Cu +. el .TP 15 +.\} +.ta \\n()Au \\n()Bu +.ie !"\\$3"" \{\ +\&\\$1 \\fI\\$2\\fP (\\$3) +.\".b +.\} +.el \{\ +.br +.ie !"\\$2"" \{\ +\&\\$1 \\fI\\$2\\fP +.\} +.el \{\ +\&\\fI\\$1\\fP +.\} +.\} +.. +.\" # define tabbing values for .AP +.de AS +.nr )A 10n +.if !"\\$1"" .nr )A \\w'\\$1'u+3n +.nr )B \\n()Au+15n +.\" +.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n +.nr )C \\n()Bu+\\w'(in/out)'u+2n +.. +.AS Tcl_Interp Tcl_CreateInterp in/out +.\" # BS - start boxed text +.\" # ^y = starting y location +.\" # ^b = 1 +.de BS +.br +.mk ^y +.nr ^b 1u +.if n .nf +.if n .ti 0 +.if n \l'\\n(.lu\(ul' +.if n .fi +.. +.\" # BE - end boxed text (draw box now) +.de BE +.nf +.ti 0 +.mk ^t +.ie n \l'\\n(^lu\(ul' +.el \{\ +.\" Draw four-sided box normally, but don't draw top of +.\" box if the box started on an earlier page. +.ie !\\n(^b-1 \{\ +\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.el \}\ +\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.\} +.fi +.br +.nr ^b 0 +.. +.\" # VS - start vertical sidebar +.\" # ^Y = starting y location +.\" # ^v = 1 (for troff; for nroff this doesn't matter) +.de VS +.if !"\\$2"" .br +.mk ^Y +.ie n 'mc \s12\(br\s0 +.el .nr ^v 1u +.. +.\" # VE - end of vertical sidebar +.de VE +.ie n 'mc +.el \{\ +.ev 2 +.nf +.ti 0 +.mk ^t +\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n' +.sp -1 +.fi +.ev +.\} +.nr ^v 0 +.. +.\" # Special macro to handle page bottom: finish off current +.\" # box/sidebar if in box/sidebar mode, then invoked standard +.\" # page bottom macro. +.de ^B +.ev 2 +'ti 0 +'nf +.mk ^t +.if \\n(^b \{\ +.\" Draw three-sided box if this is the box's first page, +.\" draw two sides but no top otherwise. +.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.\} +.if \\n(^v \{\ +.nr ^x \\n(^tu+1v-\\n(^Yu +\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c +.\} +.bp +'fi +.ev +.if \\n(^b \{\ +.mk ^y +.nr ^b 2 +.\} +.if \\n(^v \{\ +.mk ^Y +.\} +.. +.\" # DS - begin display +.de DS +.RS +.nf +.sp +.. +.\" # DE - end display +.de DE +.fi +.RE +.sp +.. +.\" # SO - start of list of standard options +.de SO +'ie '\\$1'' .ds So \\fBoptions\\fR +'el .ds So \\fB\\$1\\fR +.SH "STANDARD OPTIONS" +.LP +.nf +.ta 5.5c 11c +.ft B +.. +.\" # SE - end of list of standard options +.de SE +.fi +.ft R +.LP +See the \\*(So manual entry for details on the standard options. +.. +.\" # OP - start of full description for a single option +.de OP +.LP +.nf +.ta 4c +Command-Line Name: \\fB\\$1\\fR +Database Name: \\fB\\$2\\fR +Database Class: \\fB\\$3\\fR +.fi +.IP +.. +.\" # CS - begin code excerpt +.de CS +.RS +.nf +.ta .25i .5i .75i 1i +.. +.\" # CE - end code excerpt +.de CE +.fi +.RE +.. +.\" # UL - underline word +.de UL +\\$1\l'|0\(ul'\\$2 +.. +.\" # QW - apply quotation marks to word +.de QW +.ie '\\*(lq'"' ``\\$1''\\$2 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\$2 +.. +.\" # PQ - apply parens and quotation marks to word +.de PQ +.ie '\\*(lq'"' (``\\$1''\\$2)\\$3 +.\"" fix emacs highlighting +.el (\\*(lq\\$1\\*(rq\\$2)\\$3 +.. +.\" # QR - quoted range +.de QR +.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3 +.. +.\" # MT - "empty" string +.de MT +.QW "" +.. +.BS +.SH NAME +tcllib_license \- Tcllib - License +.SH DESCRIPTION +Welcome to Tcllib, the Tcl Standard Library\&. Note that Tcllib is not a +package itself\&. It is a collection of (semi-independent) \fITcl\fR +packages that provide utility functions useful to a large collection +of Tcl programmers\&. +.PP +The collection is under the BSD license\&. +.SH LICENSE +.PP +This software is copyrighted by Ajuba Solutions and other parties\&. +The following terms apply to all files associated with the software +unless explicitly disclaimed in individual files\&. +.PP +The authors hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, +provided that existing copyright notices are retained in all copies +and that this notice is included verbatim in any distributions\&. No +written agreement, license, or royalty fee is required for any of the +authorized uses\&. Modifications to this software may be copyrighted by +their authors and need not follow the licensing terms described here, +provided that the new terms are clearly indicated on the first page of +each file where they apply\&. +.PP +IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE\&. +.PP +THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT\&. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND +THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE +MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS\&. +.PP +GOVERNMENT USE: If you are acquiring this software on behalf of the +U\&.S\&. government, the Government shall have only "Restricted Rights" in +the software and related documentation as defined in the Federal +Acquisition Regulations (FARs) in Clause 52\&.227\&.19 (c) (2)\&. If you +are acquiring the software on behalf of the Department of Defense, the +software shall be classified as "Commercial Computer Software" and the +Government shall have only "Restricted Rights" as defined in Clause +252\&.227-7013 (c) (1) of DFARs\&. Notwithstanding the foregoing, the +authors grant the U\&.S\&. Government and others acting in its behalf +permission to use and distribute the software in accordance with the +terms specified in this license\&. ADDED idoc/man/files/devdoc/tcllib_releasemgr.n Index: idoc/man/files/devdoc/tcllib_releasemgr.n ================================================================== --- /dev/null +++ idoc/man/files/devdoc/tcllib_releasemgr.n @@ -0,0 +1,359 @@ +'\" +'\" Generated from file 'tcllib_releasemgr\&.man' by tcllib/doctools with format 'nroff' +'\" +.TH "tcllib_releasemgr" n 1 tcllib "" +.\" The -*- nroff -*- definitions below are for supplemental macros used +.\" in Tcl/Tk manual entries. +.\" +.\" .AP type name in/out ?indent? +.\" Start paragraph describing an argument to a library procedure. +.\" type is type of argument (int, etc.), in/out is either "in", "out", +.\" or "in/out" to describe whether procedure reads or modifies arg, +.\" and indent is equivalent to second arg of .IP (shouldn't ever be +.\" needed; use .AS below instead) +.\" +.\" .AS ?type? ?name? +.\" Give maximum sizes of arguments for setting tab stops. Type and +.\" name are examples of largest possible arguments that will be passed +.\" to .AP later. If args are omitted, default tab stops are used. +.\" +.\" .BS +.\" Start box enclosure. From here until next .BE, everything will be +.\" enclosed in one large box. +.\" +.\" .BE +.\" End of box enclosure. +.\" +.\" .CS +.\" Begin code excerpt. +.\" +.\" .CE +.\" End code excerpt. +.\" +.\" .VS ?version? ?br? +.\" Begin vertical sidebar, for use in marking newly-changed parts +.\" of man pages. The first argument is ignored and used for recording +.\" the version when the .VS was added, so that the sidebars can be +.\" found and removed when they reach a certain age. If another argument +.\" is present, then a line break is forced before starting the sidebar. +.\" +.\" .VE +.\" End of vertical sidebar. +.\" +.\" .DS +.\" Begin an indented unfilled display. +.\" +.\" .DE +.\" End of indented unfilled display. +.\" +.\" .SO ?manpage? +.\" Start of list of standard options for a Tk widget. The manpage +.\" argument defines where to look up the standard options; if +.\" omitted, defaults to "options". The options follow on successive +.\" lines, in three columns separated by tabs. +.\" +.\" .SE +.\" End of list of standard options for a Tk widget. +.\" +.\" .OP cmdName dbName dbClass +.\" Start of description of a specific option. cmdName gives the +.\" option's name as specified in the class command, dbName gives +.\" the option's name in the option database, and dbClass gives +.\" the option's class in the option database. +.\" +.\" .UL arg1 arg2 +.\" Print arg1 underlined, then print arg2 normally. +.\" +.\" .QW arg1 ?arg2? +.\" Print arg1 in quotes, then arg2 normally (for trailing punctuation). +.\" +.\" .PQ arg1 ?arg2? +.\" Print an open parenthesis, arg1 in quotes, then arg2 normally +.\" (for trailing punctuation) and then a closing parenthesis. +.\" +.\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages. +.if t .wh -1.3i ^B +.nr ^l \n(.l +.ad b +.\" # Start an argument description +.de AP +.ie !"\\$4"" .TP \\$4 +.el \{\ +. ie !"\\$2"" .TP \\n()Cu +. el .TP 15 +.\} +.ta \\n()Au \\n()Bu +.ie !"\\$3"" \{\ +\&\\$1 \\fI\\$2\\fP (\\$3) +.\".b +.\} +.el \{\ +.br +.ie !"\\$2"" \{\ +\&\\$1 \\fI\\$2\\fP +.\} +.el \{\ +\&\\fI\\$1\\fP +.\} +.\} +.. +.\" # define tabbing values for .AP +.de AS +.nr )A 10n +.if !"\\$1"" .nr )A \\w'\\$1'u+3n +.nr )B \\n()Au+15n +.\" +.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n +.nr )C \\n()Bu+\\w'(in/out)'u+2n +.. +.AS Tcl_Interp Tcl_CreateInterp in/out +.\" # BS - start boxed text +.\" # ^y = starting y location +.\" # ^b = 1 +.de BS +.br +.mk ^y +.nr ^b 1u +.if n .nf +.if n .ti 0 +.if n \l'\\n(.lu\(ul' +.if n .fi +.. +.\" # BE - end boxed text (draw box now) +.de BE +.nf +.ti 0 +.mk ^t +.ie n \l'\\n(^lu\(ul' +.el \{\ +.\" Draw four-sided box normally, but don't draw top of +.\" box if the box started on an earlier page. +.ie !\\n(^b-1 \{\ +\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.el \}\ +\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.\} +.fi +.br +.nr ^b 0 +.. +.\" # VS - start vertical sidebar +.\" # ^Y = starting y location +.\" # ^v = 1 (for troff; for nroff this doesn't matter) +.de VS +.if !"\\$2"" .br +.mk ^Y +.ie n 'mc \s12\(br\s0 +.el .nr ^v 1u +.. +.\" # VE - end of vertical sidebar +.de VE +.ie n 'mc +.el \{\ +.ev 2 +.nf +.ti 0 +.mk ^t +\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n' +.sp -1 +.fi +.ev +.\} +.nr ^v 0 +.. +.\" # Special macro to handle page bottom: finish off current +.\" # box/sidebar if in box/sidebar mode, then invoked standard +.\" # page bottom macro. +.de ^B +.ev 2 +'ti 0 +'nf +.mk ^t +.if \\n(^b \{\ +.\" Draw three-sided box if this is the box's first page, +.\" draw two sides but no top otherwise. +.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.\} +.if \\n(^v \{\ +.nr ^x \\n(^tu+1v-\\n(^Yu +\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c +.\} +.bp +'fi +.ev +.if \\n(^b \{\ +.mk ^y +.nr ^b 2 +.\} +.if \\n(^v \{\ +.mk ^Y +.\} +.. +.\" # DS - begin display +.de DS +.RS +.nf +.sp +.. +.\" # DE - end display +.de DE +.fi +.RE +.sp +.. +.\" # SO - start of list of standard options +.de SO +'ie '\\$1'' .ds So \\fBoptions\\fR +'el .ds So \\fB\\$1\\fR +.SH "STANDARD OPTIONS" +.LP +.nf +.ta 5.5c 11c +.ft B +.. +.\" # SE - end of list of standard options +.de SE +.fi +.ft R +.LP +See the \\*(So manual entry for details on the standard options. +.. +.\" # OP - start of full description for a single option +.de OP +.LP +.nf +.ta 4c +Command-Line Name: \\fB\\$1\\fR +Database Name: \\fB\\$2\\fR +Database Class: \\fB\\$3\\fR +.fi +.IP +.. +.\" # CS - begin code excerpt +.de CS +.RS +.nf +.ta .25i .5i .75i 1i +.. +.\" # CE - end code excerpt +.de CE +.fi +.RE +.. +.\" # UL - underline word +.de UL +\\$1\l'|0\(ul'\\$2 +.. +.\" # QW - apply quotation marks to word +.de QW +.ie '\\*(lq'"' ``\\$1''\\$2 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\$2 +.. +.\" # PQ - apply parens and quotation marks to word +.de PQ +.ie '\\*(lq'"' (``\\$1''\\$2)\\$3 +.\"" fix emacs highlighting +.el (\\*(lq\\$1\\*(rq\\$2)\\$3 +.. +.\" # QR - quoted range +.de QR +.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3 +.. +.\" # MT - "empty" string +.de MT +.QW "" +.. +.BS +.SH NAME +tcllib_releasemgr \- Tcllib - The Release Manager's Guide +.SH DESCRIPTION +Welcome to Tcllib, the Tcl Standard Library\&. Note that Tcllib is not a +package itself\&. It is a collection of (semi-independent) \fITcl\fR +packages that provide utility functions useful to a large collection +of Tcl programmers\&. +.PP +The audience of this document is the release manager for Tcllib, their +deputies, and anybody else interested in the task of creating +an official release of Tcllib for distribution\&. +.PP +Please read \fITcllib - How To Get The Sources\fR first, if that +was not done already\&. Here we assume that the sources are already +available in a directory of your choice\&. +.PP +.SH TOOLS +The "\fIsak\&.tcl\fR" script in the toplevel directory of a Tcllib +checkout is the one tool used by the release manager to perform its +\fBTasks\fR\&. +.PP +The main commands to be used are +.CS + + + sak\&.tcl validate + sak\&.tcl test run + sak\&.tcl review + sak\&.tcl readme + sak\&.tcl localdoc + sak\&.tcl release + +.CE +More detail will be provided in the explanations of the various +\fBTasks\fR\&. +.SH TASKS +.SS "START A RELEASE CANDIDATE" +todo: open a candidate for release +.SS "READY THE CANDIDATE" +todo: test, validate and check that the candidate is worthy of release +fix testsuites, possibly fix packages, documentation +regenerate docs +coordinate with package maintainers wrt fixes +big thing: going over the packages, classify changes since last +release to generate a nice readme\&. +.SS "MAKE IT OFFICIAL" +todo: finalize release, make candidate official +.SS "DISTRIBUTE THE RELEASE" +With the release made it has to be published and the world notified of +its existence\&. +.IP [1] +Create a proper fossil event for the release, via +\fIhttp://core\&.tcl-lang\&.org/tcllib/eventedit\fR\&. +.sp +An \fIexisting event\fR [http://core\&.tcl-lang\&.org/tcllib/event/dac0ddcd2e990234143196b4dc438fe01e7b9817] should be used as template\&. +.IP [2] +Update a number of web locations: +.RS +.IP [1] +\fIHome page\fR [http://core\&.tcl-lang\&.org/tcllib/doc/trunk/embedded/index\&.md] +.IP [2] +\fIDownloads\fR [http://core\&.tcl-lang\&.org/tcllib/wiki?name=Downloads] +.IP [3] +\fIPast Releases\fR [http://core\&.tcl-lang\&.org/tcllib/wiki?name=Past+Releases] +.IP [4] +\fIhttp://www\&.tcl-lang\&.org/home/release\&.txt\fR +.IP [5] +\fIhttp://www\&.tcl-lang\&.org/software/tcllib/*\&.tml\fR +.IP [6] +\fIhttp://wiki\&.tcl-lang\&.org/page/Tcllib\fR +.RE +.IP +The first location maps to the file "\fIembedded/index\&.md\fR" in the +repository itself, as such it can edited as part of the release +process\&. This is where reference to the new fossil event is added, as +the new current release\&. +.sp +The next two locations are in the fossil tcllib wiki and +require admin or wiki write permissions for +\fIhttp://core\&.tcl-lang\&.org/tcllib\fR\&. +.sp +The last two locations require ssh access to +\fIhttp://www\&.tcl-lang\&.org\fR and permission to edit +files in the web area\&. +.IP [3] +***TODO*** mailing lists and other places to send notes to\&. +.PP ADDED idoc/man/files/devdoc/tcllib_sources.n Index: idoc/man/files/devdoc/tcllib_sources.n ================================================================== --- /dev/null +++ idoc/man/files/devdoc/tcllib_sources.n @@ -0,0 +1,332 @@ +'\" +'\" Generated from file 'tcllib_sources\&.man' by tcllib/doctools with format 'nroff' +'\" +.TH "tcllib_sources" n 1 tcllib "" +.\" The -*- nroff -*- definitions below are for supplemental macros used +.\" in Tcl/Tk manual entries. +.\" +.\" .AP type name in/out ?indent? +.\" Start paragraph describing an argument to a library procedure. +.\" type is type of argument (int, etc.), in/out is either "in", "out", +.\" or "in/out" to describe whether procedure reads or modifies arg, +.\" and indent is equivalent to second arg of .IP (shouldn't ever be +.\" needed; use .AS below instead) +.\" +.\" .AS ?type? ?name? +.\" Give maximum sizes of arguments for setting tab stops. Type and +.\" name are examples of largest possible arguments that will be passed +.\" to .AP later. If args are omitted, default tab stops are used. +.\" +.\" .BS +.\" Start box enclosure. From here until next .BE, everything will be +.\" enclosed in one large box. +.\" +.\" .BE +.\" End of box enclosure. +.\" +.\" .CS +.\" Begin code excerpt. +.\" +.\" .CE +.\" End code excerpt. +.\" +.\" .VS ?version? ?br? +.\" Begin vertical sidebar, for use in marking newly-changed parts +.\" of man pages. The first argument is ignored and used for recording +.\" the version when the .VS was added, so that the sidebars can be +.\" found and removed when they reach a certain age. If another argument +.\" is present, then a line break is forced before starting the sidebar. +.\" +.\" .VE +.\" End of vertical sidebar. +.\" +.\" .DS +.\" Begin an indented unfilled display. +.\" +.\" .DE +.\" End of indented unfilled display. +.\" +.\" .SO ?manpage? +.\" Start of list of standard options for a Tk widget. The manpage +.\" argument defines where to look up the standard options; if +.\" omitted, defaults to "options". The options follow on successive +.\" lines, in three columns separated by tabs. +.\" +.\" .SE +.\" End of list of standard options for a Tk widget. +.\" +.\" .OP cmdName dbName dbClass +.\" Start of description of a specific option. cmdName gives the +.\" option's name as specified in the class command, dbName gives +.\" the option's name in the option database, and dbClass gives +.\" the option's class in the option database. +.\" +.\" .UL arg1 arg2 +.\" Print arg1 underlined, then print arg2 normally. +.\" +.\" .QW arg1 ?arg2? +.\" Print arg1 in quotes, then arg2 normally (for trailing punctuation). +.\" +.\" .PQ arg1 ?arg2? +.\" Print an open parenthesis, arg1 in quotes, then arg2 normally +.\" (for trailing punctuation) and then a closing parenthesis. +.\" +.\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages. +.if t .wh -1.3i ^B +.nr ^l \n(.l +.ad b +.\" # Start an argument description +.de AP +.ie !"\\$4"" .TP \\$4 +.el \{\ +. ie !"\\$2"" .TP \\n()Cu +. el .TP 15 +.\} +.ta \\n()Au \\n()Bu +.ie !"\\$3"" \{\ +\&\\$1 \\fI\\$2\\fP (\\$3) +.\".b +.\} +.el \{\ +.br +.ie !"\\$2"" \{\ +\&\\$1 \\fI\\$2\\fP +.\} +.el \{\ +\&\\fI\\$1\\fP +.\} +.\} +.. +.\" # define tabbing values for .AP +.de AS +.nr )A 10n +.if !"\\$1"" .nr )A \\w'\\$1'u+3n +.nr )B \\n()Au+15n +.\" +.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n +.nr )C \\n()Bu+\\w'(in/out)'u+2n +.. +.AS Tcl_Interp Tcl_CreateInterp in/out +.\" # BS - start boxed text +.\" # ^y = starting y location +.\" # ^b = 1 +.de BS +.br +.mk ^y +.nr ^b 1u +.if n .nf +.if n .ti 0 +.if n \l'\\n(.lu\(ul' +.if n .fi +.. +.\" # BE - end boxed text (draw box now) +.de BE +.nf +.ti 0 +.mk ^t +.ie n \l'\\n(^lu\(ul' +.el \{\ +.\" Draw four-sided box normally, but don't draw top of +.\" box if the box started on an earlier page. +.ie !\\n(^b-1 \{\ +\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.el \}\ +\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.\} +.fi +.br +.nr ^b 0 +.. +.\" # VS - start vertical sidebar +.\" # ^Y = starting y location +.\" # ^v = 1 (for troff; for nroff this doesn't matter) +.de VS +.if !"\\$2"" .br +.mk ^Y +.ie n 'mc \s12\(br\s0 +.el .nr ^v 1u +.. +.\" # VE - end of vertical sidebar +.de VE +.ie n 'mc +.el \{\ +.ev 2 +.nf +.ti 0 +.mk ^t +\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n' +.sp -1 +.fi +.ev +.\} +.nr ^v 0 +.. +.\" # Special macro to handle page bottom: finish off current +.\" # box/sidebar if in box/sidebar mode, then invoked standard +.\" # page bottom macro. +.de ^B +.ev 2 +'ti 0 +'nf +.mk ^t +.if \\n(^b \{\ +.\" Draw three-sided box if this is the box's first page, +.\" draw two sides but no top otherwise. +.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.\} +.if \\n(^v \{\ +.nr ^x \\n(^tu+1v-\\n(^Yu +\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c +.\} +.bp +'fi +.ev +.if \\n(^b \{\ +.mk ^y +.nr ^b 2 +.\} +.if \\n(^v \{\ +.mk ^Y +.\} +.. +.\" # DS - begin display +.de DS +.RS +.nf +.sp +.. +.\" # DE - end display +.de DE +.fi +.RE +.sp +.. +.\" # SO - start of list of standard options +.de SO +'ie '\\$1'' .ds So \\fBoptions\\fR +'el .ds So \\fB\\$1\\fR +.SH "STANDARD OPTIONS" +.LP +.nf +.ta 5.5c 11c +.ft B +.. +.\" # SE - end of list of standard options +.de SE +.fi +.ft R +.LP +See the \\*(So manual entry for details on the standard options. +.. +.\" # OP - start of full description for a single option +.de OP +.LP +.nf +.ta 4c +Command-Line Name: \\fB\\$1\\fR +Database Name: \\fB\\$2\\fR +Database Class: \\fB\\$3\\fR +.fi +.IP +.. +.\" # CS - begin code excerpt +.de CS +.RS +.nf +.ta .25i .5i .75i 1i +.. +.\" # CE - end code excerpt +.de CE +.fi +.RE +.. +.\" # UL - underline word +.de UL +\\$1\l'|0\(ul'\\$2 +.. +.\" # QW - apply quotation marks to word +.de QW +.ie '\\*(lq'"' ``\\$1''\\$2 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\$2 +.. +.\" # PQ - apply parens and quotation marks to word +.de PQ +.ie '\\*(lq'"' (``\\$1''\\$2)\\$3 +.\"" fix emacs highlighting +.el (\\*(lq\\$1\\*(rq\\$2)\\$3 +.. +.\" # QR - quoted range +.de QR +.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3 +.. +.\" # MT - "empty" string +.de MT +.QW "" +.. +.BS +.SH NAME +tcllib_sources \- Tcllib - How To Get The Sources +.SH DESCRIPTION +Welcome to Tcllib, the Tcl Standard Library\&. Note that Tcllib is not a +package itself\&. It is a collection of (semi-independent) \fITcl\fR +packages that provide utility functions useful to a large collection +of Tcl programmers\&. +.PP +The audience of this document is anyone wishing to either have just a +look at Tcllib's source code, or build the packages, or to extend and +modify them\&. +.PP +For builders and developers we additionally provide +.IP [1] +\fITcllib - The Installer's Guide\fR\&. +.IP [2] +\fITcllib - The Developer's Guide\fR\&. +.PP +respectively\&. +.SH "SOURCE LOCATION" +The official repository for Tcllib can be found at +\fIhttp://core\&.tcl-lang\&.org/tcllib\fR +.SH RETRIEVAL +Assuming that you simply wish to look at the sources, or build a +specific revision, the easiest way of retrieving it is to: +.IP [1] +Log into this site, as "anonymous", using the semi-random password in the captcha\&. +.IP [2] +Go to the "Timeline"\&. +.IP [3] +Choose the revision you wish to have\&. +.IP [4] +Follow its link to its detailed information page\&. +.IP [5] +On that page, choose either the "ZIP" or "Tarball" link to get +a copy of this revision in the format of your choice\&. +.PP +.SH "SOURCE CODE MANAGEMENT" +For the curious (or a developer-to-be), the sources are managed by the +\fIFossil SCM\fR [http://www\&.fossil-scm\&.org]\&. +Binaries for popular platforms can be found directly at its +\fIdownload page\fR [http://www\&.fossil-scm\&.org/download\&.html]\&. +.PP +With that tool available the full history can be retrieved via: +.CS + + + fossil clone http://core\&.tcl-lang\&.org/tcllib tcllib\&.fossil + +.CE +followed by +.CS + + + mkdir tcllib + cd tcllib + fossil open \&.\&./tcllib\&.fossil + +.CE +to get a checkout of the head of the trunk\&. Index: idoc/man/files/modules/dicttool/dicttool.n ================================================================== --- idoc/man/files/modules/dicttool/dicttool.n +++ idoc/man/files/modules/dicttool/dicttool.n @@ -274,10 +274,12 @@ .SH NAME dicttool \- Dictionary Tools .SH SYNOPSIS package require \fBTcl 8\&.5\fR .sp +package require \fBdicttool ?1\&.0?\fR +.sp \fBladd\fR \fIvarname\fR \fIargs\fR .sp \fBldelete\fR \fIvarname\fR \fIargs\fR .sp \fBdict getnull\fR \fIargs\fR @@ -299,11 +301,11 @@ \fBladd\fR \fIvarname\fR \fIargs\fR This command will add a new instance of each element in \fIargs\fR to \fIvarname\fR, but only if that element is not already present\&. .TP \fBldelete\fR \fIvarname\fR \fIargs\fR -This command will add a delete all instances of each element in \fIargs\fR from \fIvarname\fR\&. +This command will delete all instances of each element in \fIargs\fR from \fIvarname\fR\&. .TP \fBdict getnull\fR \fIargs\fR Operates like \fBdict get\fR, however if the key \fIargs\fR does not exist, it returns an empty list instead of throwing an error\&. .TP Index: idoc/man/files/modules/doctools/docidx_lang_intro.n ================================================================== --- idoc/man/files/modules/doctools/docidx_lang_intro.n +++ idoc/man/files/modules/doctools/docidx_lang_intro.n @@ -299,11 +299,11 @@ .CE .CS - \&.\&.\&. [manpage thefile \\\\ + \&.\&.\&. [manpage thefile \\ {file description}] \&.\&.\&. .CE .SS "BASIC STRUCTURE" The most simple document which can be written in docidx is Index: idoc/man/files/modules/doctools/doctoc_lang_intro.n ================================================================== --- idoc/man/files/modules/doctools/doctoc_lang_intro.n +++ idoc/man/files/modules/doctools/doctoc_lang_intro.n @@ -299,11 +299,11 @@ .CE .CS - \&.\&.\&. [item thefile \\\\ + \&.\&.\&. [item thefile \\ label {file description}] \&.\&.\&. .CE .SS "BASIC STRUCTURE" The most simple document which can be written in doctoc is Index: idoc/man/files/modules/doctools/doctools.n ================================================================== --- idoc/man/files/modules/doctools/doctools.n +++ idoc/man/files/modules/doctools/doctools.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'doctools\&.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 2003-2019 Andreas Kupries '\" -.TH "doctools" n 1\&.5\&.2 tcllib "Documentation tools" +.TH "doctools" n 1\&.5\&.6 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -274,11 +274,11 @@ .SH NAME doctools \- doctools - Processing documents .SH SYNOPSIS package require \fBTcl 8\&.2\fR .sp -package require \fBdoctools ?1\&.5\&.2?\fR +package require \fBdoctools ?1\&.5\&.6?\fR .sp \fB::doctools::new\fR \fIobjectName\fR ?\fIoption value\fR\&.\&.\&.? .sp \fB::doctools::help\fR .sp Index: idoc/man/files/modules/doctools/doctools_lang_intro.n ================================================================== --- idoc/man/files/modules/doctools/doctools_lang_intro.n +++ idoc/man/files/modules/doctools/doctools_lang_intro.n @@ -298,11 +298,11 @@ .CE .CS - \&.\&.\&. [call [cmd foo] \\\\ + \&.\&.\&. [call [cmd foo] \\ [arg bar]] \&.\&.\&. .CE .CS @@ -332,11 +332,11 @@ [keywords {doctools syntax}] [keywords markup] [keywords {semantic markup}] [description] [vset CATEGORY doctools] -[include \&.\&./doctools2base/include/feedback\&.inc] +[include \&.\&./common-text/feedback\&.inc] [manpage_end] .CE This also shows us that all doctools documents are split into two parts, the \fIheader\fR and the \fIbody\fR\&. Everything coming before @@ -391,11 +391,11 @@ [manpage_begin NAME SECTION VERSION] [copyright {YEAR AUTHOR}][titledesc TITLE][moddesc MODULE_TITLE] [require PACKAGE VERSION][require PACKAGE][description] [vset CATEGORY doctools] -[include \&.\&./doctools2base/include/feedback\&.inc] +[include \&.\&./common-text/feedback\&.inc] [manpage_end] .CE has the same meaning as the example before\&. .PP Index: idoc/man/files/modules/doctools2idx/export_docidx.n ================================================================== --- idoc/man/files/modules/doctools2idx/export_docidx.n +++ idoc/man/files/modules/doctools2idx/export_docidx.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'plugin\&.inc' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" -.TH "doctools::idx::export::docidx" n 0\&.1 tcllib "Documentation tools" +.TH "doctools::idx::export::docidx" n 0\&.2\&.1 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -274,11 +274,11 @@ .SH NAME doctools::idx::export::docidx \- docidx export plugin .SH SYNOPSIS package require \fBTcl 8\&.4\fR .sp -package require \fBdoctools::idx::export::docidx ?0\&.1?\fR +package require \fBdoctools::idx::export::docidx ?0\&.2\&.1?\fR .sp \fBexport\fR \fIserial\fR \fIconfiguration\fR .sp .BE .SH DESCRIPTION @@ -466,8 +466,8 @@ docidx, doctools, export, index, serialization .SH CATEGORY Text formatter plugin .SH COPYRIGHT .nf -Copyright (c) 2009 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2idx/idx_export.n ================================================================== --- idoc/man/files/modules/doctools2idx/idx_export.n +++ idoc/man/files/modules/doctools2idx/idx_export.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'idx_export\&.man' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009-2018 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" -.TH "doctools::idx::export" n 0\&.2 tcllib "Documentation tools" +.TH "doctools::idx::export" n 0\&.2\&.1 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -272,15 +272,15 @@ .. .BS .SH NAME doctools::idx::export \- Exporting keyword indices .SH SYNOPSIS -package require \fBdoctools::idx::export ?0\&.2?\fR +package require \fBdoctools::idx::export ?0\&.2\&.1?\fR .sp package require \fBTcl 8\&.4\fR .sp -package require \fBdoctools::config \fR +package require \fBstruct::map \fR .sp package require \fBdoctools::idx::structure \fR .sp package require \fBsnit \fR .sp @@ -672,8 +672,8 @@ HTML, conversion, docidx, documentation, export, formatting, generation, index, json, keyword index, manpage, markup, nroff, plugin, reference, tcler's wiki, text, url, wiki .SH CATEGORY Documentation tools .SH COPYRIGHT .nf -Copyright (c) 2009-2018 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2idx/idx_export_html.n ================================================================== --- idoc/man/files/modules/doctools2idx/idx_export_html.n +++ idoc/man/files/modules/doctools2idx/idx_export_html.n @@ -1,8 +1,8 @@ '\" '\" Generated from file 'plugin\&.inc' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" .TH "doctools::idx::export::html" n 0\&.2 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" @@ -551,8 +551,8 @@ HTML, doctools, export, index, serialization .SH CATEGORY Text formatter plugin .SH COPYRIGHT .nf -Copyright (c) 2009 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2idx/idx_export_json.n ================================================================== --- idoc/man/files/modules/doctools2idx/idx_export_json.n +++ idoc/man/files/modules/doctools2idx/idx_export_json.n @@ -1,8 +1,8 @@ '\" '\" Generated from file 'plugin\&.inc' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" .TH "doctools::idx::export::json" n 0\&.1 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" @@ -483,8 +483,8 @@ JSON, doctools, export, index, serialization .SH CATEGORY Text formatter plugin .SH COPYRIGHT .nf -Copyright (c) 2009 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2idx/idx_export_nroff.n ================================================================== --- idoc/man/files/modules/doctools2idx/idx_export_nroff.n +++ idoc/man/files/modules/doctools2idx/idx_export_nroff.n @@ -1,8 +1,8 @@ '\" '\" Generated from file 'plugin\&.inc' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" .TH "doctools::idx::export::nroff" n 0\&.3 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" @@ -434,8 +434,8 @@ doctools, export, index, nroff, serialization .SH CATEGORY Text formatter plugin .SH COPYRIGHT .nf -Copyright (c) 2009 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2idx/idx_export_text.n ================================================================== --- idoc/man/files/modules/doctools2idx/idx_export_text.n +++ idoc/man/files/modules/doctools2idx/idx_export_text.n @@ -1,8 +1,8 @@ '\" '\" Generated from file 'plugin\&.inc' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" .TH "doctools::idx::export::text" n 0\&.2 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" @@ -418,8 +418,8 @@ doctools, export, index, plain text, serialization .SH CATEGORY Text formatter plugin .SH COPYRIGHT .nf -Copyright (c) 2009 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2idx/idx_export_wiki.n ================================================================== --- idoc/man/files/modules/doctools2idx/idx_export_wiki.n +++ idoc/man/files/modules/doctools2idx/idx_export_wiki.n @@ -1,8 +1,8 @@ '\" '\" Generated from file 'plugin\&.inc' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" .TH "doctools::idx::export::wiki" n 0\&.2 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" @@ -431,8 +431,8 @@ doctools, export, index, serialization, wiki .SH CATEGORY Text formatter plugin .SH COPYRIGHT .nf -Copyright (c) 2009 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2idx/idx_import.n ================================================================== --- idoc/man/files/modules/doctools2idx/idx_import.n +++ idoc/man/files/modules/doctools2idx/idx_import.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'idx_import\&.man' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009-2018 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" -.TH "doctools::idx::import" n 0\&.2 tcllib "Documentation tools" +.TH "doctools::idx::import" n 0\&.2\&.1 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -272,15 +272,15 @@ .. .BS .SH NAME doctools::idx::import \- Importing keyword indices .SH SYNOPSIS -package require \fBdoctools::idx::import ?0\&.2?\fR +package require \fBdoctools::idx::import ?0\&.2\&.1?\fR .sp package require \fBTcl 8\&.4\fR .sp -package require \fBdoctools::config \fR +package require \fBstruct::map \fR .sp package require \fBdoctools::idx::structure \fR .sp package require \fBsnit \fR .sp @@ -751,8 +751,8 @@ conversion, docidx, documentation, import, index, json, keyword index, manpage, markup, parsing, plugin, reference, url .SH CATEGORY Documentation tools .SH COPYRIGHT .nf -Copyright (c) 2009-2018 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2idx/idx_import_json.n ================================================================== --- idoc/man/files/modules/doctools2idx/idx_import_json.n +++ idoc/man/files/modules/doctools2idx/idx_import_json.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'plugin\&.inc' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" -.TH "doctools::idx::import::json" n 0\&.1 tcllib "Documentation tools" +.TH "doctools::idx::import::json" n 0\&.2\&.1 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -272,13 +272,13 @@ .. .BS .SH NAME doctools::idx::import::json \- JSON import plugin .SH SYNOPSIS -package require \fBTcl 8\&.4\fR +package require \fBTcl 8\&.5\fR .sp -package require \fBdoctools::idx::import::json ?0\&.1?\fR +package require \fBdoctools::idx::import::json ?0\&.2\&.1?\fR .sp package require \fBdoctools::idx::structure \fR .sp package require \fBjson \fR .sp @@ -460,8 +460,8 @@ JSON, deserialization, doctools, import, index .SH CATEGORY Text formatter plugin .SH COPYRIGHT .nf -Copyright (c) 2009 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2idx/idx_introduction.n ================================================================== --- idoc/man/files/modules/doctools2idx/idx_introduction.n +++ idoc/man/files/modules/doctools2idx/idx_introduction.n @@ -371,17 +371,17 @@ ~~ | ~~ doctools::idx::export ~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ doctools::idx::import | | | +---------------+-------------------------+ | +------------------+---------------+-----------------------+---------------+ | | | | | | | | | -doctools::config = | | | = doctools::include doctools::config doctools::paths +struct::map = | | | = doctools::include struct::map fileutil::paths | | | | | doctools::idx::export::<*> | | | doctools::idx::import::<*> docidx | | | docidx, json - json | | | | \\\\ - html | | | doctools::idx::parse \\\\ - nroff | | | | \\\\ + json | | | | \\ + html | | | doctools::idx::parse \\ + nroff | | | | \\ wiki | | | +---------------+ json text | | | | | doctools::idx::structure | | +-------+---------------+ Index: idoc/man/files/modules/doctools2idx/import_docidx.n ================================================================== --- idoc/man/files/modules/doctools2idx/import_docidx.n +++ idoc/man/files/modules/doctools2idx/import_docidx.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'plugin\&.inc' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" -.TH "doctools::idx::import::docidx" n 0\&.1 tcllib "Documentation tools" +.TH "doctools::idx::import::docidx" n 0\&.2\&.1 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -272,13 +272,13 @@ .. .BS .SH NAME doctools::idx::import::docidx \- docidx import plugin .SH SYNOPSIS -package require \fBTcl 8\&.4\fR +package require \fBTcl 8\&.5\fR .sp -package require \fBdoctools::idx::import::docidx ?0\&.1?\fR +package require \fBdoctools::idx::import::docidx ?0\&.2\&.1?\fR .sp package require \fBdoctools::idx::parse \fR .sp package require \fBdoctools::idx::structure \fR .sp @@ -442,8 +442,8 @@ deserialization, docidx, doctools, import, index .SH CATEGORY Text formatter plugin .SH COPYRIGHT .nf -Copyright (c) 2009 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2toc/export_doctoc.n ================================================================== --- idoc/man/files/modules/doctools2toc/export_doctoc.n +++ idoc/man/files/modules/doctools2toc/export_doctoc.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'plugin\&.inc' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" -.TH "doctools::toc::export::doctoc" n 0\&.1 tcllib "Documentation tools" +.TH "doctools::toc::export::doctoc" n 0\&.2\&.1 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -274,11 +274,11 @@ .SH NAME doctools::toc::export::doctoc \- doctoc export plugin .SH SYNOPSIS package require \fBTcl 8\&.4\fR .sp -package require \fBdoctools::toc::export::doctoc ?0\&.1?\fR +package require \fBdoctools::toc::export::doctoc ?0\&.2\&.1?\fR .sp \fBexport\fR \fIserial\fR \fIconfiguration\fR .sp .BE .SH DESCRIPTION @@ -493,8 +493,8 @@ doctoc, doctools, export, serialization, table of contents, toc .SH CATEGORY Text formatter plugin .SH COPYRIGHT .nf -Copyright (c) 2009 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2toc/import_doctoc.n ================================================================== --- idoc/man/files/modules/doctools2toc/import_doctoc.n +++ idoc/man/files/modules/doctools2toc/import_doctoc.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'plugin\&.inc' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" -.TH "doctools::toc::import::doctoc" n 0\&.1 tcllib "Documentation tools" +.TH "doctools::toc::import::doctoc" n 0\&.2\&.1 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -272,13 +272,13 @@ .. .BS .SH NAME doctools::toc::import::doctoc \- doctoc import plugin .SH SYNOPSIS -package require \fBTcl 8\&.4\fR +package require \fBTcl 8\&.5\fR .sp -package require \fBdoctools::toc::import::doctoc ?0\&.1?\fR +package require \fBdoctools::toc::import::doctoc ?0\&.2\&.1?\fR .sp package require \fBdoctools::toc::parse \fR .sp package require \fBdoctools::toc::structure \fR .sp @@ -470,8 +470,8 @@ deserialization, doctoc, doctools, import, table of contents, toc .SH CATEGORY Text formatter plugin .SH COPYRIGHT .nf -Copyright (c) 2009 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2toc/toc_export.n ================================================================== --- idoc/man/files/modules/doctools2toc/toc_export.n +++ idoc/man/files/modules/doctools2toc/toc_export.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'toc_export\&.man' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009-2018 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" -.TH "doctools::toc::export" n 0\&.2 tcllib "Documentation tools" +.TH "doctools::toc::export" n 0\&.2\&.1 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -272,15 +272,15 @@ .. .BS .SH NAME doctools::toc::export \- Exporting tables of contents .SH SYNOPSIS -package require \fBdoctools::toc::export ?0\&.2?\fR +package require \fBdoctools::toc::export ?0\&.2\&.1?\fR .sp package require \fBTcl 8\&.4\fR .sp -package require \fBdoctools::config \fR +package require \fBstruct::map \fR .sp package require \fBdoctools::toc::structure \fR .sp package require \fBsnit \fR .sp @@ -689,8 +689,8 @@ HTML, conversion, doctoc, documentation, export, formatting, generation, json, manpage, markup, nroff, plugin, reference, table, table of contents, tcler's wiki, text, url, wiki .SH CATEGORY Documentation tools .SH COPYRIGHT .nf -Copyright (c) 2009-2018 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2toc/toc_export_html.n ================================================================== --- idoc/man/files/modules/doctools2toc/toc_export_html.n +++ idoc/man/files/modules/doctools2toc/toc_export_html.n @@ -1,8 +1,8 @@ '\" '\" Generated from file 'plugin\&.inc' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" .TH "doctools::toc::export::html" n 0\&.1 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" @@ -543,8 +543,8 @@ HTML, doctools, export, serialization, table of contents, toc .SH CATEGORY Text formatter plugin .SH COPYRIGHT .nf -Copyright (c) 2009 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2toc/toc_export_json.n ================================================================== --- idoc/man/files/modules/doctools2toc/toc_export_json.n +++ idoc/man/files/modules/doctools2toc/toc_export_json.n @@ -1,8 +1,8 @@ '\" '\" Generated from file 'plugin\&.inc' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" .TH "doctools::toc::export::json" n 0\&.1 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" @@ -531,8 +531,8 @@ JSON, doctools, export, serialization, table of contents, toc .SH CATEGORY Text formatter plugin .SH COPYRIGHT .nf -Copyright (c) 2009 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2toc/toc_export_nroff.n ================================================================== --- idoc/man/files/modules/doctools2toc/toc_export_nroff.n +++ idoc/man/files/modules/doctools2toc/toc_export_nroff.n @@ -1,8 +1,8 @@ '\" '\" Generated from file 'plugin\&.inc' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" .TH "doctools::toc::export::nroff" n 0\&.2 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" @@ -462,8 +462,8 @@ doctools, export, nroff, serialization, table of contents, toc .SH CATEGORY Text formatter plugin .SH COPYRIGHT .nf -Copyright (c) 2009 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2toc/toc_export_text.n ================================================================== --- idoc/man/files/modules/doctools2toc/toc_export_text.n +++ idoc/man/files/modules/doctools2toc/toc_export_text.n @@ -1,8 +1,8 @@ '\" '\" Generated from file 'plugin\&.inc' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" .TH "doctools::toc::export::text" n 0\&.1 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" @@ -445,8 +445,8 @@ doctools, export, plain text, serialization, table of contents, toc .SH CATEGORY Text formatter plugin .SH COPYRIGHT .nf -Copyright (c) 2009 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2toc/toc_export_wiki.n ================================================================== --- idoc/man/files/modules/doctools2toc/toc_export_wiki.n +++ idoc/man/files/modules/doctools2toc/toc_export_wiki.n @@ -1,8 +1,8 @@ '\" '\" Generated from file 'plugin\&.inc' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" .TH "doctools::toc::export::wiki" n 0\&.1 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" @@ -451,8 +451,8 @@ doctools, export, serialization, table of contents, toc, wiki .SH CATEGORY Text formatter plugin .SH COPYRIGHT .nf -Copyright (c) 2009 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2toc/toc_import.n ================================================================== --- idoc/man/files/modules/doctools2toc/toc_import.n +++ idoc/man/files/modules/doctools2toc/toc_import.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'toc_import\&.man' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009-2018 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" -.TH "doctools::toc::import" n 0\&.2 tcllib "Documentation tools" +.TH "doctools::toc::import" n 0\&.2\&.1 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -272,15 +272,15 @@ .. .BS .SH NAME doctools::toc::import \- Importing keyword indices .SH SYNOPSIS -package require \fBdoctools::toc::import ?0\&.2?\fR +package require \fBdoctools::toc::import ?0\&.2\&.1?\fR .sp package require \fBTcl 8\&.4\fR .sp -package require \fBdoctools::config \fR +package require \fBstruct::map \fR .sp package require \fBdoctools::toc::structure \fR .sp package require \fBsnit \fR .sp @@ -770,8 +770,8 @@ conversion, doctoc, documentation, import, json, manpage, markup, parsing, plugin, reference, table, table of contents, url .SH CATEGORY Documentation tools .SH COPYRIGHT .nf -Copyright (c) 2009-2018 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2toc/toc_import_json.n ================================================================== --- idoc/man/files/modules/doctools2toc/toc_import_json.n +++ idoc/man/files/modules/doctools2toc/toc_import_json.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'plugin\&.inc' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2009 Andreas Kupries +'\" Copyright (c) 2009-2019 Andreas Kupries '\" -.TH "doctools::toc::import::json" n 0\&.1 tcllib "Documentation tools" +.TH "doctools::toc::import::json" n 0\&.2\&.1 tcllib "Documentation tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -272,13 +272,13 @@ .. .BS .SH NAME doctools::toc::import::json \- JSON import plugin .SH SYNOPSIS -package require \fBTcl 8\&.4\fR +package require \fBTcl 8\&.5\fR .sp -package require \fBdoctools::toc::import::json ?0\&.1?\fR +package require \fBdoctools::toc::import::json ?0\&.2\&.1?\fR .sp package require \fBdoctools::toc::structure \fR .sp package require \fBjson \fR .sp @@ -508,8 +508,8 @@ JSON, deserialization, doctools, import, table of contents, toc .SH CATEGORY Text formatter plugin .SH COPYRIGHT .nf -Copyright (c) 2009 Andreas Kupries +Copyright (c) 2009-2019 Andreas Kupries .fi Index: idoc/man/files/modules/doctools2toc/toc_introduction.n ================================================================== --- idoc/man/files/modules/doctools2toc/toc_introduction.n +++ idoc/man/files/modules/doctools2toc/toc_introduction.n @@ -371,17 +371,17 @@ ~~ | ~~ doctools::toc::export ~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ doctools::toc::import | | | +---------------+-------------------------+ | +------------------+---------------+-----------------------+---------------+ | | | | | | | | | -doctools::config = | | | = doctools::include doctools::config doctools::paths +struct:map = | | | = doctools::include struct::map fileutil::paths | | | | | doctools::toc::export::<*> | | | doctools::toc::import::<*> doctoc | | | doctoc, json - json | | | | \\\\ - html | | | doctools::toc::parse \\\\ - nroff | | | | \\\\ + json | | | | \\ + html | | | doctools::toc::parse \\ + nroff | | | | \\ wiki | | | +---------------+ json text | | | | | doctools::toc::structure | | +-------+---------------+ Index: idoc/man/files/modules/fileutil/multiop.n ================================================================== --- idoc/man/files/modules/fileutil/multiop.n +++ idoc/man/files/modules/fileutil/multiop.n @@ -634,45 +634,45 @@ The following examples assume that the variable \fBF\fR contains a reference to a multi-file operation object\&. .CS - $F do copy \\\\ - the *\&.dll \\\\ - from c:/TDK/PrivateOpenSSL/bin \\\\ + $F do copy \\ + the *\&.dll \\ + from c:/TDK/PrivateOpenSSL/bin \\ to [installdir_of tls] .CE .CS - $F do move \\\\ - the * \\\\ - from /sources \\\\ - into /scratch \\\\ + $F do move \\ + the * \\ + from /sources \\ + into /scratch \\ but not *\&.html # Alternatively use 'except for *\&.html'\&. .CE .CS - $F do \\\\ - move \\\\ - the index \\\\ - from /sources \\\\ - into /scratch \\\\ + $F do \\ + move \\ + the index \\ + from /sources \\ + into /scratch \\ as pkgIndex\&.tcl .CE .CS - $F do \\\\ - remove \\\\ - the *\&.txt \\\\ + $F do \\ + remove \\ + the *\&.txt \\ in /scratch .CE Note that the fact that most commands just modify the object state allows us to use more off forms as specifications instead of just @@ -679,15 +679,15 @@ nearly-natural language sentences\&. For example the second example in this section can re-arranged into: .CS - $F do \\\\ - from /sources \\\\ - into /scratch \\\\ - but not *\&.html \\\\ - move \\\\ + $F do \\ + from /sources \\ + into /scratch \\ + but not *\&.html \\ + move \\ the * .CE and the result is not only still a valid specification, but even stays relatively readable\&. @@ -699,17 +699,17 @@ information\&. For example the second and third examples of this section can be merged and rewritten into the equivalent: .CS -$F do \\\\ - move \\\\ - the * \\\\ - from /sources \\\\ - into /scratch \\\\ - but not *\&.html not index \\\\ - the index \\\\ +$F do \\ + move \\ + the * \\ + from /sources \\ + into /scratch \\ + but not *\&.html not index \\ + the index \\ as pkgIndex\&.tcl .CE .SH "BUGS, IDEAS, FEEDBACK" This document, and the package it describes, will undoubtedly contain ADDED idoc/man/files/modules/fileutil/paths.n Index: idoc/man/files/modules/fileutil/paths.n ================================================================== --- /dev/null +++ idoc/man/files/modules/fileutil/paths.n @@ -0,0 +1,350 @@ +'\" +'\" Generated from file 'paths\&.man' by tcllib/doctools with format 'nroff' +'\" +.TH "fileutil::paths" n 1 tcllib "" +.\" The -*- nroff -*- definitions below are for supplemental macros used +.\" in Tcl/Tk manual entries. +.\" +.\" .AP type name in/out ?indent? +.\" Start paragraph describing an argument to a library procedure. +.\" type is type of argument (int, etc.), in/out is either "in", "out", +.\" or "in/out" to describe whether procedure reads or modifies arg, +.\" and indent is equivalent to second arg of .IP (shouldn't ever be +.\" needed; use .AS below instead) +.\" +.\" .AS ?type? ?name? +.\" Give maximum sizes of arguments for setting tab stops. Type and +.\" name are examples of largest possible arguments that will be passed +.\" to .AP later. If args are omitted, default tab stops are used. +.\" +.\" .BS +.\" Start box enclosure. From here until next .BE, everything will be +.\" enclosed in one large box. +.\" +.\" .BE +.\" End of box enclosure. +.\" +.\" .CS +.\" Begin code excerpt. +.\" +.\" .CE +.\" End code excerpt. +.\" +.\" .VS ?version? ?br? +.\" Begin vertical sidebar, for use in marking newly-changed parts +.\" of man pages. The first argument is ignored and used for recording +.\" the version when the .VS was added, so that the sidebars can be +.\" found and removed when they reach a certain age. If another argument +.\" is present, then a line break is forced before starting the sidebar. +.\" +.\" .VE +.\" End of vertical sidebar. +.\" +.\" .DS +.\" Begin an indented unfilled display. +.\" +.\" .DE +.\" End of indented unfilled display. +.\" +.\" .SO ?manpage? +.\" Start of list of standard options for a Tk widget. The manpage +.\" argument defines where to look up the standard options; if +.\" omitted, defaults to "options". The options follow on successive +.\" lines, in three columns separated by tabs. +.\" +.\" .SE +.\" End of list of standard options for a Tk widget. +.\" +.\" .OP cmdName dbName dbClass +.\" Start of description of a specific option. cmdName gives the +.\" option's name as specified in the class command, dbName gives +.\" the option's name in the option database, and dbClass gives +.\" the option's class in the option database. +.\" +.\" .UL arg1 arg2 +.\" Print arg1 underlined, then print arg2 normally. +.\" +.\" .QW arg1 ?arg2? +.\" Print arg1 in quotes, then arg2 normally (for trailing punctuation). +.\" +.\" .PQ arg1 ?arg2? +.\" Print an open parenthesis, arg1 in quotes, then arg2 normally +.\" (for trailing punctuation) and then a closing parenthesis. +.\" +.\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages. +.if t .wh -1.3i ^B +.nr ^l \n(.l +.ad b +.\" # Start an argument description +.de AP +.ie !"\\$4"" .TP \\$4 +.el \{\ +. ie !"\\$2"" .TP \\n()Cu +. el .TP 15 +.\} +.ta \\n()Au \\n()Bu +.ie !"\\$3"" \{\ +\&\\$1 \\fI\\$2\\fP (\\$3) +.\".b +.\} +.el \{\ +.br +.ie !"\\$2"" \{\ +\&\\$1 \\fI\\$2\\fP +.\} +.el \{\ +\&\\fI\\$1\\fP +.\} +.\} +.. +.\" # define tabbing values for .AP +.de AS +.nr )A 10n +.if !"\\$1"" .nr )A \\w'\\$1'u+3n +.nr )B \\n()Au+15n +.\" +.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n +.nr )C \\n()Bu+\\w'(in/out)'u+2n +.. +.AS Tcl_Interp Tcl_CreateInterp in/out +.\" # BS - start boxed text +.\" # ^y = starting y location +.\" # ^b = 1 +.de BS +.br +.mk ^y +.nr ^b 1u +.if n .nf +.if n .ti 0 +.if n \l'\\n(.lu\(ul' +.if n .fi +.. +.\" # BE - end boxed text (draw box now) +.de BE +.nf +.ti 0 +.mk ^t +.ie n \l'\\n(^lu\(ul' +.el \{\ +.\" Draw four-sided box normally, but don't draw top of +.\" box if the box started on an earlier page. +.ie !\\n(^b-1 \{\ +\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.el \}\ +\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.\} +.fi +.br +.nr ^b 0 +.. +.\" # VS - start vertical sidebar +.\" # ^Y = starting y location +.\" # ^v = 1 (for troff; for nroff this doesn't matter) +.de VS +.if !"\\$2"" .br +.mk ^Y +.ie n 'mc \s12\(br\s0 +.el .nr ^v 1u +.. +.\" # VE - end of vertical sidebar +.de VE +.ie n 'mc +.el \{\ +.ev 2 +.nf +.ti 0 +.mk ^t +\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n' +.sp -1 +.fi +.ev +.\} +.nr ^v 0 +.. +.\" # Special macro to handle page bottom: finish off current +.\" # box/sidebar if in box/sidebar mode, then invoked standard +.\" # page bottom macro. +.de ^B +.ev 2 +'ti 0 +'nf +.mk ^t +.if \\n(^b \{\ +.\" Draw three-sided box if this is the box's first page, +.\" draw two sides but no top otherwise. +.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.\} +.if \\n(^v \{\ +.nr ^x \\n(^tu+1v-\\n(^Yu +\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c +.\} +.bp +'fi +.ev +.if \\n(^b \{\ +.mk ^y +.nr ^b 2 +.\} +.if \\n(^v \{\ +.mk ^Y +.\} +.. +.\" # DS - begin display +.de DS +.RS +.nf +.sp +.. +.\" # DE - end display +.de DE +.fi +.RE +.sp +.. +.\" # SO - start of list of standard options +.de SO +'ie '\\$1'' .ds So \\fBoptions\\fR +'el .ds So \\fB\\$1\\fR +.SH "STANDARD OPTIONS" +.LP +.nf +.ta 5.5c 11c +.ft B +.. +.\" # SE - end of list of standard options +.de SE +.fi +.ft R +.LP +See the \\*(So manual entry for details on the standard options. +.. +.\" # OP - start of full description for a single option +.de OP +.LP +.nf +.ta 4c +Command-Line Name: \\fB\\$1\\fR +Database Name: \\fB\\$2\\fR +Database Class: \\fB\\$3\\fR +.fi +.IP +.. +.\" # CS - begin code excerpt +.de CS +.RS +.nf +.ta .25i .5i .75i 1i +.. +.\" # CE - end code excerpt +.de CE +.fi +.RE +.. +.\" # UL - underline word +.de UL +\\$1\l'|0\(ul'\\$2 +.. +.\" # QW - apply quotation marks to word +.de QW +.ie '\\*(lq'"' ``\\$1''\\$2 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\$2 +.. +.\" # PQ - apply parens and quotation marks to word +.de PQ +.ie '\\*(lq'"' (``\\$1''\\$2)\\$3 +.\"" fix emacs highlighting +.el (\\*(lq\\$1\\*(rq\\$2)\\$3 +.. +.\" # QR - quoted range +.de QR +.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3 +.. +.\" # MT - "empty" string +.de MT +.QW "" +.. +.BS +.SH NAME +fileutil::paths \- Manage search path pools +.SH SYNOPSIS +package require \fBTcl 8\&.4\fR +.sp +package require \fBfileutil::paths ?1?\fR +.sp +\fB::fileutil::paths\fR \fIpoolName\fR +.sp +\fBpoolName\fR \fBmethod\fR ?\fIarg arg \&.\&.\&.\fR? +.sp +\fIpoolName\fR \fBadd\fR \fIpath\fR +.sp +\fIpoolName\fR \fBclear\fR +.sp +\fIpoolName\fR \fBpaths\fR +.sp +\fIpoolName\fR \fBremove\fR \fIpath\fR +.sp +.BE +.SH DESCRIPTION +Provides a snit class whose instances manage a pool of (search) paths\&. +.SH API +The main command provides construction of search path pools: +.TP +\fB::fileutil::paths\fR \fIpoolName\fR +Creates a new, empty pool of search paths with an associated global +Tcl command whose name is \fIpoolName\fR\&. +It may be used to invoke various operations on the pool\&. +It has the following general form: +.RS +.TP +\fBpoolName\fR \fBmethod\fR ?\fIarg arg \&.\&.\&.\fR? +\fBmethod\fR and \fIarg\fRuments determine the exact behavior of +the command\&. +.RE +.IP +If \fIpoolName\fR is specified as \fB%AUTO%\fR a unique name will be +generated by the package itself\&. +The result of the command is the fully-qualified name of the instance +command\&. +.PP +.PP +The following commands are possible for pool objects: +.TP +\fIpoolName\fR \fBadd\fR \fIpath\fR +Adds the \fIpath\fR to the pool\&. +Nothing is done if the \fIpath\fR is already known to the pool\&. +The result of the command is the empty string\&. +.TP +\fIpoolName\fR \fBclear\fR +Clears the entire pool\&. In other words, removes all paths from it\&. +The result of the command is the empty string\&. +.TP +\fIpoolName\fR \fBpaths\fR +Returns the list of all paths known to the pool, in the order they +were added\&. +.TP +\fIpoolName\fR \fBremove\fR \fIpath\fR +Removes the \fIpath\fR from the pool, if it is known to the pool\&. +Unknown paths are ignored without error\&. +The result of the command is the empty string\&. +.PP +.SH "BUGS, IDEAS, FEEDBACK" +This document, and the package it describes, will undoubtedly contain +bugs and other problems\&. +Please report such in the category \fIfileutil\fR of the +\fITcllib Trackers\fR [http://core\&.tcl\&.tk/tcllib/reportlist]\&. +Please also report any ideas for enhancements you may have for either +package and/or documentation\&. +.PP +When proposing code changes, please provide \fIunified diffs\fR, +i\&.e the output of \fBdiff -u\fR\&. +.PP +Note further that \fIattachments\fR are strongly preferred over +inlined patches\&. Attachments can be made by going to the \fBEdit\fR +form of the ticket immediately after its creation, and then using the +left-most button in the secondary navigation bar\&. Index: idoc/man/files/modules/grammar_fa/fa.n ================================================================== --- idoc/man/files/modules/grammar_fa/fa.n +++ idoc/man/files/modules/grammar_fa/fa.n @@ -547,15 +547,15 @@ a possible serialization is .sp .CS - grammar::fa \\\\ - {yellow red green red/yellow} \\\\ - {Drive {0 0 {yellow Brake}} \\\\ - Brake {0 0 {red Stop}} \\\\ - Stop {1 0 {red/yellow Attention}} \\\\ + grammar::fa \\ + {yellow red green red/yellow} \\ + {Drive {0 0 {yellow Brake}} \\ + Brake {0 0 {red Stop}} \\ + Stop {1 0 {red/yellow Attention}} \\ Attention {0 0 {green Drive}}} .CE .sp A possible one, because I did not care about creation order here Index: idoc/man/files/modules/grammar_peg/peg.n ================================================================== --- idoc/man/files/modules/grammar_peg/peg.n +++ idoc/man/files/modules/grammar_peg/peg.n @@ -556,24 +556,24 @@ a possible serialization is .sp .CS - grammar::peg \\\\ - {Expression {/ {x ( Expression )} {x Factor {* {x MulOp Factor}}}} \\\\ - Factor {x Term {* {x AddOp Term}}} \\\\ - Term Number \\\\ - MulOp {/ * /} \\\\ - AddOp {/ + -} \\\\ - Number {x {? Sign} {+ Digit}} \\\\ - Sign {/ + -} \\\\ - Digit {/ 0 1 2 3 4 5 6 7 8 9} \\\\ - } \\\\ - {Expression value Factor value \\\\ - Term value MulOp value \\\\ - AddOp value Number value \\\\ - Sign value Digit value \\\\ + grammar::peg \\ + {Expression {/ {x ( Expression )} {x Factor {* {x MulOp Factor}}}} \\ + Factor {x Term {* {x AddOp Term}}} \\ + Term Number \\ + MulOp {/ * /} \\ + AddOp {/ + -} \\ + Number {x {? Sign} {+ Digit}} \\ + Sign {/ + -} \\ + Digit {/ 0 1 2 3 4 5 6 7 8 9} \\ + } \\ + {Expression value Factor value \\ + Term value MulOp value \\ + AddOp value Number value \\ + Sign value Digit value \\ } Expression .CE .sp Index: idoc/man/files/modules/httpd/httpd.n ================================================================== --- idoc/man/files/modules/httpd/httpd.n +++ idoc/man/files/modules/httpd/httpd.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'httpd\&.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 2018 Sean Woods '\" -.TH "tool" n 4\&.1\&.1 tcllib "Tcl Web Server" +.TH "httpd" n 4\&.3\&.3 tcllib "Tcl Web Server" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -270,25 +270,17 @@ .de MT .QW "" .. .BS .SH NAME -tool \- A TclOO and coroutine based web server +httpd \- A TclOO and coroutine based web server .SH SYNOPSIS package require \fBTcl 8\&.6\fR .sp -package require \fBhttpd ?4\&.1\&.1?\fR -.sp -package require \fBsha1 \fR -.sp -package require \fBdicttool \fR -.sp -package require \fBoo::meta \fR -.sp -package require \fBoo::dialect \fR -.sp -package require \fBtool \fR +package require \fBuuid \fR +.sp +package require \fBclay \fR .sp package require \fBcoroutine \fR .sp package require \fBfileutil \fR .sp @@ -302,103 +294,221 @@ .sp package require \fBuri \fR .sp package require \fBMarkdown \fR .sp -constructor ?port ?port?? ?myaddr ?ipaddr?|all? ?server_string ?string?? ?server_name ?string?? -.sp -method \fBadd_uri\fR \fIpattern\fR \fIdict\fR -.sp -method \fBconnect\fR \fIsock\fR \fIip\fR \fIport\fR -.sp -method \fBConnect\fR \fIuuid\fR \fIsock\fR \fIip\fR -.sp -method \fBcounter\fR \fIwhich\fR -.sp -method \fBCheckTimeout\fR -.sp -method \fBdispatch\fR \fIheader_dict\fR -.sp -method \fBlog\fR \fIargs\fR -.sp -method \fBport_listening\fR -.sp -method \fBPrefixNormalize\fR \fIprefix\fR -.sp -method \fBstart\fR -.sp -method \fBstop\fR -.sp -method \fBtemplate\fR \fIpage\fR -.sp -method \fBTemplateSearch\fR \fIpage\fR -.sp -method \fBValidate_Connection\fR \fIsock\fR \fIip\fR -.sp -method \fBENSEMBLE::add\fR \fIfield\fR \fIelement\fR -.sp -method \fBENSEMBLE::dump\fR -.sp -method \fBENSEMBLE::get\fR \fIfield\fR -.sp -method \fBENSEMBLE::reset\fR -.sp -method \fBENSEMBLE::remove\fR \fIfield\fR \fIelement\fR -.sp -method \fBENSEMBLE::replace\fR \fIkeyvaluelist\fR -.sp -method \fBENSEMBLE::reset\fR -.sp -method \fBENSEMBLE::set\fR \fIfield\fR \fIvalue\fR -.sp -method \fBhttp_info::netstring\fR -.sp -method \fBrequest::parse\fR \fIstring\fR -.sp -method \fBreply::output\fR +method \fBChannelCopy\fR \fIin\fR \fIout\fR ?\fIargs\fR? +.sp +method \fBhtml_header\fR ?\fItitle\fR \fB\fR? ?\fIargs\fR? +.sp +method \fBhtml_footer\fR ?\fIargs\fR? +.sp +method \fBhttp_code_string\fR \fIcode\fR +.sp +method \fBHttpHeaders\fR \fIsock\fR ?\fIdebug\fR \fB\fR? +.sp +method \fBHttpHeaders_Default\fR +.sp +method \fBHttpServerHeaders\fR +.sp +method \fBMimeParse\fR \fImimetext\fR +.sp +method \fBUrl_Decode\fR \fIdata\fR +.sp +method \fBUrl_PathCheck\fR \fIurlsuffix\fR +.sp +method \fBwait\fR \fImode\fR \fIsock\fR +.sp +variable \fBChannelRegister\fR +.sp +variable \fBreply\fR +.sp +variable \fBrequest\fR +.sp +delegate \fB\fR +.sp +method \fBconstructor\fR \fIServerObj\fR ?\fIargs\fR? +.sp +method \fBdestructor\fR ?\fIdictargs\fR? +.sp +method \fBChannelRegister\fR ?\fIargs\fR? .sp method \fBclose\fR .sp -method \fBHttpHeaders\fR \fIsock\fR \fI?debug?\fR +method \fBLog_Dispatched\fR .sp method \fBdispatch\fR \fInewsock\fR \fIdatastate\fR .sp -method \fBerror\fR \fIcode\fR \fI?message?\fR \fI?errorInfo?\fR +method \fBDispatch\fR +.sp +method \fBhtml_header\fR \fItitle\fR ?\fIargs\fR? +.sp +method \fBhtml_footer\fR ?\fIargs\fR? +.sp +method \fBerror\fR \fIcode\fR ?\fImsg\fR \fB\fR? ?\fIerrorInfo\fR \fB\fR? .sp method \fBcontent\fR .sp method \fBEncodeStatus\fR \fIstatus\fR .sp -method FormData +method \fBlog\fR \fItype\fR ?\fIinfo\fR \fB\fR? .sp -method MimeParse \fImimetext\fR +method \fBCoroName\fR .sp method \fBDoOutput\fR .sp -method PostData \fIlength\fR +method \fBFormData\fR .sp -method \fBputs\fR \fIstring\fR +method \fBPostData\fR \fIlength\fR +.sp +method \fBSession_Load\fR +.sp +method \fBputs\fR \fIline\fR +.sp +method \fBRequestFind\fR \fIfield\fR +.sp +method \fBrequest\fR \fIsubcommand\fR ?\fIargs\fR? +.sp +method \fBreply\fR \fIsubcommand\fR ?\fIargs\fR? .sp method \fBreset\fR .sp method \fBtimeOutCheck\fR .sp method \fBtimestamp\fR .sp -method \fBTransferComplete\fR \fIargs\fR -.sp -method \fBUrl_Decode\fR \fIstring\fR -.sp -method cgi_info -.sp -option \fBpath\fR -.sp -option \fBprefix\fR -.sp -method proxy_info -.sp -method scgi_info +variable \fBtemplate\fR +.sp +variable \fBurl_patterns\fR +.sp +method \fBconstructor\fR \fIargs\fR ?\fIport\fR \fBauto\fR? ?\fImyaddr\fR \fB127\&.0\&.0\&.1\fR? ?\fIstring\fR \fBauto\fR? ?\fIname\fR \fBauto\fR? ?\fIdoc_root\fR \fB\fR? ?\fIreverse_dns\fR \fB0\fR? ?\fIconfiguration_file\fR \fB\fR? ?\fIprotocol\fR \fBHTTP/1\&.1\fR? +.sp +method \fBdestructor\fR ?\fIdictargs\fR? +.sp +method \fBconnect\fR \fIsock\fR \fIip\fR \fIport\fR +.sp +method \fBServerHeaders\fR \fIip\fR \fIhttp_request\fR \fImimetxt\fR +.sp +method \fBConnect\fR \fIuuid\fR \fIsock\fR \fIip\fR +.sp +method \fBcounter\fR \fIwhich\fR +.sp +method \fBCheckTimeout\fR +.sp +method \fBdebug\fR ?\fIargs\fR? +.sp +method \fBdispatch\fR \fIdata\fR +.sp +method \fBDispatch_Default\fR \fIreply\fR +.sp +method \fBDispatch_Local\fR \fIdata\fR +.sp +method \fBHeaders_Local\fR \fIvarname\fR +.sp +method \fBHeaders_Process\fR \fIvarname\fR +.sp +method \fBHostName\fR \fIipaddr\fR +.sp +method \fBlog\fR ?\fIargs\fR? +.sp +method \fBplugin\fR \fIslot\fR ?\fIclass\fR \fB\fR? +.sp +method \fBport_listening\fR +.sp +method \fBPrefixNormalize\fR \fIprefix\fR +.sp +method \fBsource\fR \fIfilename\fR +.sp +method \fBstart\fR +.sp +method \fBstop\fR +.sp +method \fBSubObject {} db\fR +.sp +method \fBSubObject {} default\fR +.sp +method \fBtemplate\fR \fIpage\fR +.sp +method \fBTemplateSearch\fR \fIpage\fR +.sp +method \fBThread_start\fR +.sp +method \fBUuid_Generate\fR +.sp +method \fBValidate_Connection\fR \fIsock\fR \fIip\fR +.sp +method \fBreset\fR +.sp +method \fBcontent\fR +.sp +method \fBDispatch\fR +.sp +method \fBcontent\fR +.sp +method \fBFileName\fR +.sp +method \fBDirectoryListing\fR \fIlocal_file\fR +.sp +method \fBcontent\fR +.sp +method \fBDispatch\fR +.sp +variable \fBexename\fR +.sp +method \fBCgiExec\fR \fIexecname\fR \fIscript\fR \fIarglist\fR +.sp +method \fBCgi_Executable\fR \fIscript\fR +.sp +method \fBproxy_channel\fR +.sp +method \fBproxy_path\fR +.sp +method \fBProxyRequest\fR \fIchana\fR \fIchanb\fR +.sp +method \fBProxyReply\fR \fIchana\fR \fIchanb\fR ?\fIargs\fR? +.sp +method \fBDispatch\fR +.sp +method \fBFileName\fR +.sp +method \fBproxy_channel\fR +.sp +method \fBProxyRequest\fR \fIchana\fR \fIchanb\fR +.sp +method \fBProxyReply\fR \fIchana\fR \fIchanb\fR ?\fIargs\fR? +.sp +method \fBDirectoryListing\fR \fIlocal_file\fR +.sp +method \fBEncodeStatus\fR \fIstatus\fR +.sp +method \fBscgi_info\fR +.sp +method \fBproxy_channel\fR +.sp +method \fBProxyRequest\fR \fIchana\fR \fIchanb\fR +.sp +method \fBProxyReply\fR \fIchana\fR \fIchanb\fR ?\fIargs\fR? +.sp +method \fBdebug\fR ?\fIargs\fR? +.sp +method \fBConnect\fR \fIuuid\fR \fIsock\fR \fIip\fR +.sp +method \fBDispatch_Dict\fR \fIdata\fR +.sp +method \fBuri {} add\fR \fIvhosts\fR \fIpatterns\fR \fIinfo\fR +.sp +method \fBuri {} direct\fR \fIvhosts\fR \fIpatterns\fR \fIinfo\fR \fIbody\fR +.sp +method \fBoutput\fR +.sp +method \fBDoOutput\fR +.sp +method \fBclose\fR +.sp +method \fBlocal_memchan\fR \fIcommand\fR ?\fIargs\fR? +.sp +method \fBConnect_Local\fR \fIuuid\fR \fIsock\fR ?\fIargs\fR? .sp .BE .SH DESCRIPTION .PP This module implements a web server, suitable for embedding in an @@ -410,97 +520,79 @@ \fBhttpd::server\fR, and providing that server with one or more URIs to service, and \fBhttpd::reply\fR derived classes to generate them\&. .CS -tool::define ::reply\&.hello { +oo::class create ::reply\&.hello { method content {} { my puts "IRM Dispatch Server" my puts "

Hello World!

" my puts } } -::docserver::server create HTTPD port 8015 myaddr 127\&.0\&.0\&.1 -HTTPD add_uri /* [list mixin reply\&.hello] +::httpd::server create HTTPD port 8015 myaddr 127\&.0\&.0\&.1 doc_root ~/htdocs +HTTPD plugin dispatch httpd::server::dispatch +HTTPD uri add * /hello [list mixin reply\&.hello] + +.CE +The bare module does have facilities to hose a files from a file system\&. Files that end in a \&.tml will be substituted in the style of Tclhttpd: +.CS + + + +[my html_header {Hello World!}] +Your Server is running\&. +

+The time is now [clock format [clock seconds]] +[my html_footer] + +.CE +A complete example of an httpd server is in the /examples directory of Tcllib\&. It also show how to dispatch URIs to other processes via SCGI and HTTP proxies\&. +.CS + + +cd ~/tcl/sandbox/tcllib +tclsh examples/httpd\&.tcl .CE -.SH "CLASS ::HTTPD::SERVER" -This class is the root object of the webserver\&. It is responsible -for opening the socket and providing the initial connection negotiation\&. -.TP -constructor ?port ?port?? ?myaddr ?ipaddr?|all? ?server_string ?string?? ?server_name ?string?? -Build a new server object\&. ?port? is the port to listen on -.TP -method \fBadd_uri\fR \fIpattern\fR \fIdict\fR -Set the hander for a URI pattern\&. Information given in the \fIdict\fR is stored -in the data structure the \fBdispatch\fR method uses\&. If a field called -\fImixin\fR is given, that class will be mixed into the reply object immediately -after construction\&. -.TP -method \fBconnect\fR \fIsock\fR \fIip\fR \fIport\fR -Reply to an open socket\&. This method builds a coroutine to manage the remainder -of the connection\&. The coroutine's operations are driven by the \fBConnect\fR method\&. -.TP -method \fBConnect\fR \fIuuid\fR \fIsock\fR \fIip\fR -This method reads HTTP headers, and then consults the \fBdispatch\fR method to -determine if the request is valid, and/or what kind of reply to generate\&. Under -normal cases, an object of class \fB::http::reply\fR is created\&. -Fields the server are looking for in particular are: -class: A class to use instead of the server's own \fIreply_class\fR -mixin: A class to be mixed into the new object after construction\&. -All other fields are passed along to the \fBhttp_info\fR structure of the -reply object\&. -After the class is created and the mixin is mixed in, the server invokes the -reply objects \fBdispatch\fR method\&. This action passes control of the socket to -the reply object\&. The reply object manages the rest of the transaction, including -closing the socket\&. -.TP -method \fBcounter\fR \fIwhich\fR -Increment an internal counter\&. -.TP -method \fBCheckTimeout\fR -Check open connections for a time out event\&. -.TP -method \fBdispatch\fR \fIheader_dict\fR -Given a key/value list of information, return a data structure describing how -the server should reply\&. -.TP -method \fBlog\fR \fIargs\fR -Log an event\&. The input for args is free form\&. This method is intended -to be replaced by the user, and is a noop for a stock http::server object\&. -.TP -method \fBport_listening\fR -Return the actual port that httpd is listening on\&. -.TP -method \fBPrefixNormalize\fR \fIprefix\fR -For the stock version, trim trailing /'s and *'s from a prefix\&. This -method can be replaced by the end user to perform any other transformations -needed for the application\&. -.TP -method \fBstart\fR -Open the socket listener\&. -.TP -method \fBstop\fR -Shut off the socket listener, and destroy any pending replies\&. -.TP -method \fBtemplate\fR \fIpage\fR -Return a template for the string \fIpage\fR -.TP -method \fBTemplateSearch\fR \fIpage\fR -Perform a search for the template that best matches \fIpage\fR\&. This -can include local file searches, in-memory structures, or even -database lookups\&. The stock implementation simply looks for files -with a \&.tml or \&.html extension in the ?doc_root? directory\&. -.TP -method \fBValidate_Connection\fR \fIsock\fR \fIip\fR -Given a socket and an ip address, return true if this connection should -be terminated, or false if it should be allowed to continue\&. The stock -implementation always returns 0\&. This is intended for applications to -be able to implement black lists and/or provide security based on IP -address\&. -.PP -.SH "CLASS ::HTTPD::REPLY" +.SH CLASSES +.SS "CLASS HTTPD::MIME" +A metaclass for MIME handling behavior across a live socket +.PP +\fBMethods\fR +.TP +method \fBChannelCopy\fR \fIin\fR \fIout\fR ?\fIargs\fR? +.TP +method \fBhtml_header\fR ?\fItitle\fR \fB\fR? ?\fIargs\fR? +Returns a block of HTML +.TP +method \fBhtml_footer\fR ?\fIargs\fR? +.TP +method \fBhttp_code_string\fR \fIcode\fR +.TP +method \fBHttpHeaders\fR \fIsock\fR ?\fIdebug\fR \fB\fR? +.TP +method \fBHttpHeaders_Default\fR +.TP +method \fBHttpServerHeaders\fR +.TP +method \fBMimeParse\fR \fImimetext\fR +Converts a block of mime encoded text to a key/value list\&. If an exception is encountered, +the method will generate its own call to the \fBerror\fR method, and immediately invoke +the \fBoutput\fR method to produce an error code and close the connection\&. +.TP +method \fBUrl_Decode\fR \fIdata\fR +De-httpizes a string\&. +.TP +method \fBUrl_PathCheck\fR \fIurlsuffix\fR +.TP +method \fBwait\fR \fImode\fR \fIsock\fR +.PP +.PP +.SS "CLASS HTTPD::REPLY" +\fIancestors\fR: \fBhttpd::mime\fR +.PP A class which shephards a request through the process of generating a reply\&. The socket associated with the reply is available at all times as the \fIchan\fR variable\&. The process of generating a reply begins with an \fBhttpd::server\fR generating a @@ -521,82 +613,10 @@ method if an exception is raised\&. .IP [6] Invokes the \fBoutput\fR method for the object .PP .PP -.SH "REPLY METHOD ENSEMBLES" -The \fBhttp::reply\fR class and its derivatives maintain several variables as dictionaries -internally\&. Access to these dictionaries is managed through a dedicated ensemble\&. The -ensemble implements most of the same behaviors as the \fBdict\fR command\&. -Each ensemble implements the following methods above, beyond, or modifying standard dicts: -.TP -method \fBENSEMBLE::add\fR \fIfield\fR \fIelement\fR -Add \fIelement\fR to a list stored in \fIfield\fR, but only if it is not already present om the list\&. -.TP -method \fBENSEMBLE::dump\fR -Return the current contents of the data structure as a key/value list\&. -.TP -method \fBENSEMBLE::get\fR \fIfield\fR -Return the value of the field \fIfield\fR, or an empty string if it does not exist\&. -.TP -method \fBENSEMBLE::reset\fR -Return a key/value list of the default contents for this data structure\&. -.TP -method \fBENSEMBLE::remove\fR \fIfield\fR \fIelement\fR -Remove all instances of \fIelement\fR from the list stored in \fIfield\fR\&. -.TP -method \fBENSEMBLE::replace\fR \fIkeyvaluelist\fR -Replace the internal dict with the contents of \fIkeyvaluelist\fR -.TP -method \fBENSEMBLE::reset\fR -Replace the internal dict with the default state\&. -.TP -method \fBENSEMBLE::set\fR \fIfield\fR \fIvalue\fR -Set the value of \fIfield\fR to \fIvalue\fR\&. -.PP -.SH "REPLY METHOD ENSEMBLE: HTTP_INFO" -Manages HTTP headers passed in by the server\&. -Ensemble Methods: -.TP -method \fBhttp_info::netstring\fR -Return the contents of this data structure as a netstring encoded block\&. -.PP -.SH "REPLY METHOD ENSEMBLE: REQUEST" -Managed data from MIME headers of the request\&. -.TP -method \fBrequest::parse\fR \fIstring\fR -Replace the contents of the data structure with information encoded in a MIME -formatted block of text (\fIstring\fR)\&. -.PP -.SH "REPLY METHOD ENSEMBLE: REPLY" -Manage the headers sent in the reply\&. -.TP -method \fBreply::output\fR -Return the contents of this data structure as a MIME encoded block appropriate -for an HTTP response\&. -.PP -.SH "REPLY METHODS" -.TP -method \fBclose\fR -Terminate the transaction, and close the socket\&. -.TP -method \fBHttpHeaders\fR \fIsock\fR \fI?debug?\fR -Stream MIME headers from the socket \fIsock\fR, stopping at an empty line\&. Returns -the stream as a block of text\&. -.TP -method \fBdispatch\fR \fInewsock\fR \fIdatastate\fR -Take over control of the socket \fInewsock\fR, and store that as the \fIchan\fR variable -for the object\&. This method runs through all of the steps of reading HTTP headers, generating -content, and closing the connection\&. (See class writetup)\&. -.TP -method \fBerror\fR \fIcode\fR \fI?message?\fR \fI?errorInfo?\fR -Generate an error message of the specified \fIcode\fR, and display the \fImessage\fR as the -reason for the exception\&. \fIerrorInfo\fR is passed in from calls, but how or if it should be -displayed is a prerogative of the developer\&. -.TP -method \fBcontent\fR -Generate the content for the reply\&. This method is intended to be replaced by the mixin\&. Developers have the option of streaming output to a buffer via the \fBputs\fR method of the reply, or simply populating the \fIreply_body\fR variable of the object\&. The information returned by the \fBcontent\fR method is not interpreted in any way\&. If an exception is thrown (via the \fBerror\fR command in Tcl, for example) the caller will auto-generate a 500 {Internal Error} message\&. @@ -603,95 +623,164 @@ A typical implementation of \fBcontent\fR look like: .CS -tool::define ::test::content\&.file { - superclass ::httpd::content\&.file - # Return a file - # Note: this is using the content\&.file mixin which looks for the reply_file variable - # and will auto-compute the Content-Type - method content {} { - my reset - set doc_root [my http_info get doc_root] - my variable reply_file - set reply_file [file join $doc_root index\&.html] - } -} -tool::define ::test::content\&.time { - # return the current system time - method content {} { - my variable reply_body - my reply set Content-Type text/plain - set reply_body [clock seconds] - } -} -tool::define ::test::content\&.echo { - method content {} { - my variable reply_body - my reply set Content-Type [my request get CONTENT_TYPE] - set reply_body [my PostData [my request get CONTENT_LENGTH]] - } -} -tool::define ::test::content\&.form_handler { - method content {} { - set form [my FormData] - my reply set Content-Type {text/html; charset=UTF-8} - my puts [my html header {My Dynamic Page}] - my puts "" - my puts "You Sent

" - my puts "" - foreach {f v} $form { - my puts "" - } - my puts "
$f$v

" - my puts "Send some info:

" - my puts "" - my puts "" - foreach field {name rank serial_number} { - set line "" - my puts $line - } - my puts "
$field
" - my puts [my html footer] - } -} + clay::define ::test::content\&.file { + superclass ::httpd::content\&.file + # Return a file + # Note: this is using the content\&.file mixin which looks for the reply_file variable + # and will auto-compute the Content-Type + method content {} { + my reset + set doc_root [my request get DOCUMENT_ROOT] + my variable reply_file + set reply_file [file join $doc_root index\&.html] + } + } + clay::define ::test::content\&.time { + # return the current system time + method content {} { + my variable reply_body + my reply set Content-Type text/plain + set reply_body [clock seconds] + } + } + clay::define ::test::content\&.echo { + method content {} { + my variable reply_body + my reply set Content-Type [my request get CONTENT_TYPE] + set reply_body [my PostData [my request get CONTENT_LENGTH]] + } + } + clay::define ::test::content\&.form_handler { + method content {} { + set form [my FormData] + my reply set Content-Type {text/html; charset=UTF-8} + my puts [my html_header {My Dynamic Page}] + my puts "" + my puts "You Sent

" + my puts "" + foreach {f v} $form { + my puts "" + } + my puts "
$f$v

" + my puts "Send some info:

" + my puts "" + my puts "" + foreach field {name rank serial_number} { + set line "" + my puts $line + } + my puts "
$field
" + my puts [my html footer] + } + } .CE +.PP +\fBVariable\fR +.TP +variable \fBChannelRegister\fR +.TP +variable \fBreply\fR +A dictionary which will converted into the MIME headers of the reply +.TP +variable \fBrequest\fR +A dictionary containing the SCGI transformed HTTP headers for the request +.PP +.PP +\fBDelegate\fR +.TP +delegate \fB\fR +The server object which spawned this reply +.PP +.PP +\fBMethods\fR +.TP +method \fBconstructor\fR \fIServerObj\fR ?\fIargs\fR? +.TP +method \fBdestructor\fR ?\fIdictargs\fR? +clean up on exit +.TP +method \fBChannelRegister\fR ?\fIargs\fR? +Registers a channel to be closed by the close method +.TP +method \fBclose\fR +Close channels opened by this object +.TP +method \fBLog_Dispatched\fR +Record a dispatch event +.TP +method \fBdispatch\fR \fInewsock\fR \fIdatastate\fR +Accept the handoff from the server object of the socket +\fInewsock\fR and feed it the state \fIdatastate\fR\&. +Fields the \fIdatastate\fR are looking for in particular are: +.sp +* \fBmixin\fR - A key/value list of slots and classes to be mixed into the +object prior to invoking \fBDispatch\fR\&. +.sp +* \fBhttp\fR - A key/value list of values to populate the object's \fIrequest\fR +ensemble +.sp +All other fields are passed along to the \fBclay\fR structure of the object\&. +.TP +method \fBDispatch\fR +.TP +method \fBhtml_header\fR \fItitle\fR ?\fIargs\fR? +.TP +method \fBhtml_footer\fR ?\fIargs\fR? +.TP +method \fBerror\fR \fIcode\fR ?\fImsg\fR \fB\fR? ?\fIerrorInfo\fR \fB\fR? +.TP +method \fBcontent\fR +REPLACE ME: +This method is the "meat" of your application\&. +It writes to the result buffer via the "puts" method +and can tweak the headers via "clay put header_reply" .TP method \fBEncodeStatus\fR \fIstatus\fR Formulate a standard HTTP status header from he string provided\&. .TP -method FormData +method \fBlog\fR \fItype\fR ?\fIinfo\fR \fB\fR? +.TP +method \fBCoroName\fR +.TP +method \fBDoOutput\fR +Generates the the HTTP reply, streams that reply back across \fIchan\fR, +and destroys the object\&. +.TP +method \fBFormData\fR For GET requests, converts the QUERY_DATA header into a key/value list\&. For POST requests, reads the Post data and converts that information to a key/value list for application/x-www-form-urlencoded posts\&. For multipart posts, it composites all of the MIME headers of the post to a singular key/value list, and provides MIME_* information as computed by the \fBmime\fR package, including the MIME_TOKEN, which can be fed back into the mime package to read out the contents\&. .TP -method MimeParse \fImimetext\fR -Converts a block of mime encoded text to a key/value list\&. If an exception is encountered, -the method will generate its own call to the \fBerror\fR method, and immediately invoke -the \fBoutput\fR method to produce an error code and close the connection\&. -.TP -method \fBDoOutput\fR -Generates the the HTTP reply, and streams that reply back across \fIchan\fR\&. -.TP -method PostData \fIlength\fR +method \fBPostData\fR \fIlength\fR Stream \fIlength\fR bytes from the \fIchan\fR socket, but only of the request is a POST or PUSH\&. Returns an empty string otherwise\&. .TP -method \fBputs\fR \fIstring\fR +method \fBSession_Load\fR +Manage session data +.TP +method \fBputs\fR \fIline\fR Appends the value of \fIstring\fR to the end of \fIreply_body\fR, as well as a trailing newline character\&. .TP +method \fBRequestFind\fR \fIfield\fR +.TP +method \fBrequest\fR \fIsubcommand\fR ?\fIargs\fR? +.TP +method \fBreply\fR \fIsubcommand\fR ?\fIargs\fR? +.TP method \fBreset\fR Clear the contents of the \fIreply_body\fR variable, and reset all headers in the \fBreply\fR structure back to the defaults for this object\&. .TP method \fBtimeOutCheck\fR @@ -704,94 +793,324 @@ Return the current system time in the format: .CS %a, %d %b %Y %T %Z .CE +.PP +.PP +.SS "CLASS HTTPD::SERVER" +\fIancestors\fR: \fBhttpd::mime\fR +.PP +.PP +\fBVariable\fR +.TP +variable \fBtemplate\fR +.TP +variable \fBurl_patterns\fR +.PP +.PP +\fBMethods\fR +.TP +method \fBconstructor\fR \fIargs\fR ?\fIport\fR \fBauto\fR? ?\fImyaddr\fR \fB127\&.0\&.0\&.1\fR? ?\fIstring\fR \fBauto\fR? ?\fIname\fR \fBauto\fR? ?\fIdoc_root\fR \fB\fR? ?\fIreverse_dns\fR \fB0\fR? ?\fIconfiguration_file\fR \fB\fR? ?\fIprotocol\fR \fBHTTP/1\&.1\fR? +.TP +method \fBdestructor\fR ?\fIdictargs\fR? +.TP +method \fBconnect\fR \fIsock\fR \fIip\fR \fIport\fR +Reply to an open socket\&. This method builds a coroutine to manage the remainder +of the connection\&. The coroutine's operations are driven by the \fBConnect\fR method\&. +.TP +method \fBServerHeaders\fR \fIip\fR \fIhttp_request\fR \fImimetxt\fR +.TP +method \fBConnect\fR \fIuuid\fR \fIsock\fR \fIip\fR +This method reads HTTP headers, and then consults the \fBdispatch\fR method to +determine if the request is valid, and/or what kind of reply to generate\&. Under +normal cases, an object of class \fB::http::reply\fR is created, and that class's +\fBdispatch\fR method\&. +This action passes control of the socket to +the reply object\&. The reply object manages the rest of the transaction, including +closing the socket\&. +.TP +method \fBcounter\fR \fIwhich\fR +Increment an internal counter\&. +.TP +method \fBCheckTimeout\fR +Check open connections for a time out event\&. +.TP +method \fBdebug\fR ?\fIargs\fR? +.TP +method \fBdispatch\fR \fIdata\fR +Given a key/value list of information, return a data structure describing how +the server should reply\&. +.TP +method \fBDispatch_Default\fR \fIreply\fR +Method dispatch method of last resort before returning a 404 NOT FOUND error\&. +The default behavior is to look for a file in \fIDOCUMENT_ROOT\fR which +matches the query\&. +.TP +method \fBDispatch_Local\fR \fIdata\fR +Method dispatch method invoked prior to invoking methods implemented by plugins\&. +If this method returns a non-empty dictionary, that structure will be passed to +the reply\&. The default is an empty implementation\&. +.TP +method \fBHeaders_Local\fR \fIvarname\fR +Introspect and possibly modify a data structure destined for a reply\&. This +method is invoked before invoking Header methods implemented by plugins\&. +The default implementation is empty\&. +.TP +method \fBHeaders_Process\fR \fIvarname\fR +Introspect and possibly modify a data structure destined for a reply\&. This +method is built dynamically by the \fBplugin\fR method\&. +.TP +method \fBHostName\fR \fIipaddr\fR +Convert an ip address to a host name\&. If the server/ reverse_dns flag +is false, this method simply returns the IP address back\&. +Internally, this method uses the \fIdns\fR module from tcllib\&. +.TP +method \fBlog\fR ?\fIargs\fR? +Log an event\&. The input for args is free form\&. This method is intended +to be replaced by the user, and is a noop for a stock http::server object\&. +.TP +method \fBplugin\fR \fIslot\fR ?\fIclass\fR \fB\fR? +Incorporate behaviors from a plugin\&. +This method dynamically rebuilds the \fBDispatch\fR and \fBHeaders\fR +method\&. For every plugin, the server looks for the following entries in +\fIclay plugin/\fR: +.sp +\fIload\fR - A script to invoke in the server's namespace during the \fBplugin\fR method invokation\&. +.sp +\fIdispatch\fR - A script to stitch into the server's \fBDispatch\fR method\&. +.sp +\fIheaders\fR - A script to stitch into the server's \fBHeaders\fR method\&. +.sp +\fIthread\fR - A script to stitch into the server's \fBThread_start\fR method\&. +.TP +method \fBport_listening\fR +Return the actual port that httpd is listening on\&. +.TP +method \fBPrefixNormalize\fR \fIprefix\fR +For the stock version, trim trailing /'s and *'s from a prefix\&. This +method can be replaced by the end user to perform any other transformations +needed for the application\&. +.TP +method \fBsource\fR \fIfilename\fR +.TP +method \fBstart\fR +Open the socket listener\&. +.TP +method \fBstop\fR +Shut off the socket listener, and destroy any pending replies\&. +.TP +method \fBSubObject {} db\fR +.TP +method \fBSubObject {} default\fR +.TP +method \fBtemplate\fR \fIpage\fR +Return a template for the string \fIpage\fR +.TP +method \fBTemplateSearch\fR \fIpage\fR +Perform a search for the template that best matches \fIpage\fR\&. This +can include local file searches, in-memory structures, or even +database lookups\&. The stock implementation simply looks for files +with a \&.tml or \&.html extension in the ?doc_root? directory\&. +.TP +method \fBThread_start\fR +Built by the \fBplugin\fR method\&. Called by the \fBstart\fR method\&. Intended +to allow plugins to spawn worker threads\&. .TP -method \fBTransferComplete\fR \fIargs\fR -Intended to be invoked from \fBchan copy\fR as a callback\&. This closes every channel -fed to it on the command line, and then destroys the object\&. +method \fBUuid_Generate\fR +Generate a GUUID\&. Used to ensure every request has a unique ID\&. +The default implementation is: .CS - ### - # Output the body - ### - chan configure $sock -translation binary -blocking 0 -buffering full -buffersize 4096 - chan configure $chan -translation binary -blocking 0 -buffering full -buffersize 4096 - if {$length} { - ### - # Send any POST/PUT/etc content - ### - chan copy $sock $chan -size $SIZE -command [info coroutine] - yield - } - catch {close $sock} - chan flush $chan + return [::clay::uuid generate] .CE .TP -method \fBUrl_Decode\fR \fIstring\fR -De-httpizes a string\&. -.PP -.SH "CLASS ::HTTPD::CONTENT" -The httpd module includes several ready to use implementations of content mixins -for common use cases\&. Options are passed in to the \fBadd_uri\fR method of the server\&. -.SH "CLASS ::HTTPD::CONTENT\&.CGI" -An implementation to relay requests to process which will accept post data -streamed in vie stdin, and sent a reply streamed to stdout\&. -.TP -method cgi_info -Mandatory method to be replaced by the end user\&. If needed, activates the -process to proxy, and then returns a list of three values: -\fIexec\fR - The arguments to send to exec to fire off the responding process, minus the stdin/stdout redirection\&. -.PP -.SH "CLASS ::HTTPD::CONTENT\&.FILE" -An implementation to deliver files from the local file system\&. -.TP -option \fBpath\fR -The root directory on the local file system to be exposed via http\&. -.TP -option \fBprefix\fR -The prefix of the URI portion to ignore when calculating relative file paths\&. -.PP -.SH "CLASS ::HTTPD::CONTENT\&.PROXY" -An implementation to relay requests to another HTTP server, and relay -the results back across the request channel\&. -.TP -method proxy_info -Mandatory method to be replaced by the end user\&. If needed, activates the -process to proxy, and then returns a list of three values: -\fIproxyhost\fR - The hostname where the proxy is located -\fIproxyport\fR - The port to connect to -\fIproxyscript\fR - A pre-amble block of text to send prior to the mirrored request -.PP -.SH "CLASS ::HTTPD::CONTENT\&.SCGI" -An implementation to relay requests to a server listening on a socket -expecting SCGI encoded requests, and relay -the results back across the request channel\&. -.TP -method scgi_info -Mandatory method to be replaced by the end user\&. If needed, activates the -process to proxy, and then returns a list of three values: -\fIscgihost\fR - The hostname where the scgi listener is located -\fIscgiport\fR - The port to connect to -\fIscgiscript\fR - The contents of the \fISCRIPT_NAME\fR header to be sent -.PP -.SH "CLASS ::HTTPD::CONTENT\&.WEBSOCKET" -A placeholder for a future implementation to manage requests that can expect to be -promoted to a Websocket\&. Currently it is an empty class\&. -.SH "SCGI SERVER FUNCTIONS" -The HTTP module also provides an SCGI server implementation, as well as an HTTP -implementation\&. To use the SCGI functions, create an object of the \fBhttp::server\&.scgi\fR -class instead of the \fBhttp::server\fR class\&. -.SH "CLASS ::HTTPD::REPLY\&.SCGI" -An modified \fBhttp::reply\fR implementation that understands how to deal with -netstring encoded headers\&. -.SH "CLASS ::HTTPD::SERVER\&.SCGI" -A modified \fBhttp::server\fR which is tailored to replying to request according to -the SCGI standard instead of the HTTP standard\&. +method \fBValidate_Connection\fR \fIsock\fR \fIip\fR +Given a socket and an ip address, return true if this connection should +be terminated, or false if it should be allowed to continue\&. The stock +implementation always returns 0\&. This is intended for applications to +be able to implement black lists and/or provide security based on IP +address\&. +.PP +.PP +.SS "CLASS HTTPD::SERVER::DISPATCH" +\fIancestors\fR: \fBhttpd::server\fR +.PP +Provide a backward compadible alias +.PP +.SS "CLASS HTTPD::CONTENT\&.REDIRECT" +.PP +\fBMethods\fR +.TP +method \fBreset\fR +.TP +method \fBcontent\fR +.PP +.PP +.SS "CLASS HTTPD::CONTENT\&.CACHE" +.PP +\fBMethods\fR +.TP +method \fBDispatch\fR +.PP +.PP +.SS "CLASS HTTPD::CONTENT\&.TEMPLATE" +.PP +\fBMethods\fR +.TP +method \fBcontent\fR +.PP +.PP +.SS "CLASS HTTPD::CONTENT\&.FILE" +Class to deliver Static content +When utilized, this class is fed a local filename +by the dispatcher +.PP +\fBMethods\fR +.TP +method \fBFileName\fR +.TP +method \fBDirectoryListing\fR \fIlocal_file\fR +.TP +method \fBcontent\fR +.TP +method \fBDispatch\fR +.PP +.PP +.SS "CLASS HTTPD::CONTENT\&.EXEC" +.PP +\fBVariable\fR +.TP +variable \fBexename\fR +.PP +.PP +\fBMethods\fR +.TP +method \fBCgiExec\fR \fIexecname\fR \fIscript\fR \fIarglist\fR +.TP +method \fBCgi_Executable\fR \fIscript\fR +.PP +.PP +.SS "CLASS HTTPD::CONTENT\&.PROXY" +\fIancestors\fR: \fBhttpd::content\&.exec\fR +.PP +Return data from an proxy process +.PP +\fBMethods\fR +.TP +method \fBproxy_channel\fR +.TP +method \fBproxy_path\fR +.TP +method \fBProxyRequest\fR \fIchana\fR \fIchanb\fR +.TP +method \fBProxyReply\fR \fIchana\fR \fIchanb\fR ?\fIargs\fR? +.TP +method \fBDispatch\fR +.PP +.PP +.SS "CLASS HTTPD::CONTENT\&.CGI" +\fIancestors\fR: \fBhttpd::content\&.proxy\fR +.PP +.PP +\fBMethods\fR +.TP +method \fBFileName\fR +.TP +method \fBproxy_channel\fR +.TP +method \fBProxyRequest\fR \fIchana\fR \fIchanb\fR +.TP +method \fBProxyReply\fR \fIchana\fR \fIchanb\fR ?\fIargs\fR? +.TP +method \fBDirectoryListing\fR \fIlocal_file\fR +For most CGI applications a directory list is vorboten +.PP +.PP +.SS "CLASS HTTPD::PROTOCOL\&.SCGI" +Return data from an SCGI process +.PP +\fBMethods\fR +.TP +method \fBEncodeStatus\fR \fIstatus\fR +.PP +.PP +.SS "CLASS HTTPD::CONTENT\&.SCGI" +\fIancestors\fR: \fBhttpd::content\&.proxy\fR +.PP +.PP +\fBMethods\fR +.TP +method \fBscgi_info\fR +.TP +method \fBproxy_channel\fR +.TP +method \fBProxyRequest\fR \fIchana\fR \fIchanb\fR +.TP +method \fBProxyReply\fR \fIchana\fR \fIchanb\fR ?\fIargs\fR? +.PP +.PP +.SS "CLASS HTTPD::SERVER\&.SCGI" +\fIancestors\fR: \fBhttpd::server\fR +.PP +Act as an SCGI Server +.PP +\fBMethods\fR +.TP +method \fBdebug\fR ?\fIargs\fR? +.TP +method \fBConnect\fR \fIuuid\fR \fIsock\fR \fIip\fR +.PP +.PP +.SS "CLASS HTTPD::CONTENT\&.WEBSOCKET" +Upgrade a connection to a websocket +.PP +.SS "CLASS HTTPD::PLUGIN" +httpd plugin template +.PP +.SS "CLASS HTTPD::PLUGIN\&.DICT_DISPATCH" +A rudimentary plugin that dispatches URLs from a dict +data structure +.PP +\fBMethods\fR +.TP +method \fBDispatch_Dict\fR \fIdata\fR +Implementation of the dispatcher +.TP +method \fBuri {} add\fR \fIvhosts\fR \fIpatterns\fR \fIinfo\fR +.TP +method \fBuri {} direct\fR \fIvhosts\fR \fIpatterns\fR \fIinfo\fR \fIbody\fR +.PP +.PP +.SS "CLASS HTTPD::REPLY\&.MEMCHAN" +\fIancestors\fR: \fBhttpd::reply\fR +.PP +.PP +\fBMethods\fR +.TP +method \fBoutput\fR +.TP +method \fBDoOutput\fR +.TP +method \fBclose\fR +.PP +.PP +.SS "CLASS HTTPD::PLUGIN\&.LOCAL_MEMCHAN" +.PP +\fBMethods\fR +.TP +method \fBlocal_memchan\fR \fIcommand\fR ?\fIargs\fR? +.TP +method \fBConnect_Local\fR \fIuuid\fR \fIsock\fR ?\fIargs\fR? +A modified connection method that passes simple GET request to an object +and pulls data directly from the reply_body data variable in the object +Needed because memchan is bidirectional, and we can't seem to communicate that +the server is one side of the link and the reply is another +.PP +.PP .SH AUTHORS Sean Woods .SH "BUGS, IDEAS, FEEDBACK" This document, and the package it describes, will undoubtedly contain bugs and other problems\&. Index: idoc/man/files/modules/imap4/imap4.n ================================================================== --- idoc/man/files/modules/imap4/imap4.n +++ idoc/man/files/modules/imap4/imap4.n @@ -273,11 +273,11 @@ .SH NAME imap4 \- imap client-side tcl implementation of imap protocol .SH SYNOPSIS package require \fBTcl 8\&.5\fR .sp -package require \fBimap4 ?0\&.5\&.2?\fR +package require \fBimap4 ?0\&.5\&.3?\fR .sp \fB::imap4::open\fR \fIhostname\fR ?\fIport\fR? .sp \fB::imap4::starttls\fR \fIchan\fR .sp @@ -811,5 +811,7 @@ Only a small part of rfc3501 implemented\&. .SH "SEE ALSO" ftp, http, imap, mime, pop3, tls .SH KEYWORDS email, imap, internet, mail, net, rfc3501, ssl, tls +.SH CATEGORY +Networking Index: idoc/man/files/modules/math/numtheory.n ================================================================== --- idoc/man/files/modules/math/numtheory.n +++ idoc/man/files/modules/math/numtheory.n @@ -310,10 +310,12 @@ .sp \fBmath::numtheory::numberPrimesLegendre\fR \fIN\fR .sp \fBmath::numtheory::numberPrimesLegendreModified\fR \fIN\fR .sp +\fBmath::numtheory::differenceNumberPrimesLegendreModified\fR \fIlower\fR \fIupper\fR +.sp .BE .SH DESCRIPTION .PP This package is for collecting various number-theoretic operations, with a slight bias to prime numbers\&. @@ -469,27 +471,38 @@ \fBmath::numtheory::numberPrimesGauss\fR \fIN\fR Estimate the number of primes according the formula by Gauss\&. .RS .TP integer \fIN\fR (in) -Number in question +Number in question, should be larger than 0 .RE .TP \fBmath::numtheory::numberPrimesLegendre\fR \fIN\fR Estimate the number of primes according the formula by Legendre\&. .RS .TP integer \fIN\fR (in) -Number in question +Number in question, should be larger than 0 .RE .TP \fBmath::numtheory::numberPrimesLegendreModified\fR \fIN\fR Estimate the number of primes according the modified formula by Legendre\&. .RS .TP integer \fIN\fR (in) -Number in question +Number in question, should be larger than 0 +.RE +.TP +\fBmath::numtheory::differenceNumberPrimesLegendreModified\fR \fIlower\fR \fIupper\fR +Estimate the number of primes between tow limits according the modified formula by Legendre\&. +.RS +.TP +integer \fIlower\fR (in) +Lower limit for the primes, should be larger than 0 +.TP +integer \fIupper\fR (in) +Upper limit for the primes, should be larger than 0 .RE .PP .SH "BUGS, IDEAS, FEEDBACK" This document, and the package it describes, will undoubtedly contain bugs and other problems\&. ADDED idoc/man/files/modules/math/quasirandom.n Index: idoc/man/files/modules/math/quasirandom.n ================================================================== --- /dev/null +++ idoc/man/files/modules/math/quasirandom.n @@ -0,0 +1,394 @@ +'\" +'\" Generated from file 'quasirandom\&.man' by tcllib/doctools with format 'nroff' +'\" +.TH "math::quasirandom" n 1 tcllib "Tcl Math Library" +.\" The -*- nroff -*- definitions below are for supplemental macros used +.\" in Tcl/Tk manual entries. +.\" +.\" .AP type name in/out ?indent? +.\" Start paragraph describing an argument to a library procedure. +.\" type is type of argument (int, etc.), in/out is either "in", "out", +.\" or "in/out" to describe whether procedure reads or modifies arg, +.\" and indent is equivalent to second arg of .IP (shouldn't ever be +.\" needed; use .AS below instead) +.\" +.\" .AS ?type? ?name? +.\" Give maximum sizes of arguments for setting tab stops. Type and +.\" name are examples of largest possible arguments that will be passed +.\" to .AP later. If args are omitted, default tab stops are used. +.\" +.\" .BS +.\" Start box enclosure. From here until next .BE, everything will be +.\" enclosed in one large box. +.\" +.\" .BE +.\" End of box enclosure. +.\" +.\" .CS +.\" Begin code excerpt. +.\" +.\" .CE +.\" End code excerpt. +.\" +.\" .VS ?version? ?br? +.\" Begin vertical sidebar, for use in marking newly-changed parts +.\" of man pages. The first argument is ignored and used for recording +.\" the version when the .VS was added, so that the sidebars can be +.\" found and removed when they reach a certain age. If another argument +.\" is present, then a line break is forced before starting the sidebar. +.\" +.\" .VE +.\" End of vertical sidebar. +.\" +.\" .DS +.\" Begin an indented unfilled display. +.\" +.\" .DE +.\" End of indented unfilled display. +.\" +.\" .SO ?manpage? +.\" Start of list of standard options for a Tk widget. The manpage +.\" argument defines where to look up the standard options; if +.\" omitted, defaults to "options". The options follow on successive +.\" lines, in three columns separated by tabs. +.\" +.\" .SE +.\" End of list of standard options for a Tk widget. +.\" +.\" .OP cmdName dbName dbClass +.\" Start of description of a specific option. cmdName gives the +.\" option's name as specified in the class command, dbName gives +.\" the option's name in the option database, and dbClass gives +.\" the option's class in the option database. +.\" +.\" .UL arg1 arg2 +.\" Print arg1 underlined, then print arg2 normally. +.\" +.\" .QW arg1 ?arg2? +.\" Print arg1 in quotes, then arg2 normally (for trailing punctuation). +.\" +.\" .PQ arg1 ?arg2? +.\" Print an open parenthesis, arg1 in quotes, then arg2 normally +.\" (for trailing punctuation) and then a closing parenthesis. +.\" +.\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages. +.if t .wh -1.3i ^B +.nr ^l \n(.l +.ad b +.\" # Start an argument description +.de AP +.ie !"\\$4"" .TP \\$4 +.el \{\ +. ie !"\\$2"" .TP \\n()Cu +. el .TP 15 +.\} +.ta \\n()Au \\n()Bu +.ie !"\\$3"" \{\ +\&\\$1 \\fI\\$2\\fP (\\$3) +.\".b +.\} +.el \{\ +.br +.ie !"\\$2"" \{\ +\&\\$1 \\fI\\$2\\fP +.\} +.el \{\ +\&\\fI\\$1\\fP +.\} +.\} +.. +.\" # define tabbing values for .AP +.de AS +.nr )A 10n +.if !"\\$1"" .nr )A \\w'\\$1'u+3n +.nr )B \\n()Au+15n +.\" +.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n +.nr )C \\n()Bu+\\w'(in/out)'u+2n +.. +.AS Tcl_Interp Tcl_CreateInterp in/out +.\" # BS - start boxed text +.\" # ^y = starting y location +.\" # ^b = 1 +.de BS +.br +.mk ^y +.nr ^b 1u +.if n .nf +.if n .ti 0 +.if n \l'\\n(.lu\(ul' +.if n .fi +.. +.\" # BE - end boxed text (draw box now) +.de BE +.nf +.ti 0 +.mk ^t +.ie n \l'\\n(^lu\(ul' +.el \{\ +.\" Draw four-sided box normally, but don't draw top of +.\" box if the box started on an earlier page. +.ie !\\n(^b-1 \{\ +\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.el \}\ +\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.\} +.fi +.br +.nr ^b 0 +.. +.\" # VS - start vertical sidebar +.\" # ^Y = starting y location +.\" # ^v = 1 (for troff; for nroff this doesn't matter) +.de VS +.if !"\\$2"" .br +.mk ^Y +.ie n 'mc \s12\(br\s0 +.el .nr ^v 1u +.. +.\" # VE - end of vertical sidebar +.de VE +.ie n 'mc +.el \{\ +.ev 2 +.nf +.ti 0 +.mk ^t +\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n' +.sp -1 +.fi +.ev +.\} +.nr ^v 0 +.. +.\" # Special macro to handle page bottom: finish off current +.\" # box/sidebar if in box/sidebar mode, then invoked standard +.\" # page bottom macro. +.de ^B +.ev 2 +'ti 0 +'nf +.mk ^t +.if \\n(^b \{\ +.\" Draw three-sided box if this is the box's first page, +.\" draw two sides but no top otherwise. +.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.\} +.if \\n(^v \{\ +.nr ^x \\n(^tu+1v-\\n(^Yu +\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c +.\} +.bp +'fi +.ev +.if \\n(^b \{\ +.mk ^y +.nr ^b 2 +.\} +.if \\n(^v \{\ +.mk ^Y +.\} +.. +.\" # DS - begin display +.de DS +.RS +.nf +.sp +.. +.\" # DE - end display +.de DE +.fi +.RE +.sp +.. +.\" # SO - start of list of standard options +.de SO +'ie '\\$1'' .ds So \\fBoptions\\fR +'el .ds So \\fB\\$1\\fR +.SH "STANDARD OPTIONS" +.LP +.nf +.ta 5.5c 11c +.ft B +.. +.\" # SE - end of list of standard options +.de SE +.fi +.ft R +.LP +See the \\*(So manual entry for details on the standard options. +.. +.\" # OP - start of full description for a single option +.de OP +.LP +.nf +.ta 4c +Command-Line Name: \\fB\\$1\\fR +Database Name: \\fB\\$2\\fR +Database Class: \\fB\\$3\\fR +.fi +.IP +.. +.\" # CS - begin code excerpt +.de CS +.RS +.nf +.ta .25i .5i .75i 1i +.. +.\" # CE - end code excerpt +.de CE +.fi +.RE +.. +.\" # UL - underline word +.de UL +\\$1\l'|0\(ul'\\$2 +.. +.\" # QW - apply quotation marks to word +.de QW +.ie '\\*(lq'"' ``\\$1''\\$2 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\$2 +.. +.\" # PQ - apply parens and quotation marks to word +.de PQ +.ie '\\*(lq'"' (``\\$1''\\$2)\\$3 +.\"" fix emacs highlighting +.el (\\*(lq\\$1\\*(rq\\$2)\\$3 +.. +.\" # QR - quoted range +.de QR +.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3 +.. +.\" # MT - "empty" string +.de MT +.QW "" +.. +.BS +.SH NAME +math::quasirandom \- Quasi-random points for integration and Monte Carlo type methods +.SH SYNOPSIS +package require \fBTcl 8\&.5\fR +.sp +package require \fBTclOO \fR +.sp +package require \fBmath::quasirandom 1\fR +.sp +\fB::math::quasirandom::qrpoint create\fR \fINAME\fR \fIDIM\fR ?ARGS? +.sp +\fBgen next\fR +.sp +\fBgen set-start\fR \fIindex\fR +.sp +\fBgen set-evaluations\fR \fInumber\fR +.sp +\fBgen integral\fR \fIfunc\fR \fIminmax\fR \fIargs\fR +.sp +.BE +.SH DESCRIPTION +.PP +In many applications pseudo-random numbers and pseudo-random points in a (limited) +sample space play an important role\&. For instance in any type of Monte Carlo simulation\&. +Pseudo-random numbers, however, may be too random and as a consequence a large +number of data points is required to reduce the error or fluctuation in the results +to the desired value\&. +.PP +Quasi-random numbers can be used as an alternative: instead of "completely" arbitrary +points, points are generated that are diverse enough to cover the entire sample space +in a more or less uniform way\&. As a consequence convergence to the limit can be +much faster, when such quasi-random numbers are well-chosen\&. +.PP +The package defines a \fIclass\fR "qrpoint" that creates a command to generate +quasi-random points in 1, 2 or more dimensions\&. The command can either generate +separate points, so that they can be used in a user-defined algorithm or use these +points to calculate integrals of functions defined over 1, 2 or more dimensions\&. +It also holds several other common algorithms\&. (NOTE: these are not implemented yet) +.PP +One particular characteristic of the generators is that there are no tuning parameters +involved, which makes the use particularly simple\&. +.SH COMMANDS +A quasi-random point generator is created using the \fIqrpoint\fR class: +.TP +\fB::math::quasirandom::qrpoint create\fR \fINAME\fR \fIDIM\fR ?ARGS? +This command takes the following arguments: +.RS +.TP +string \fINAME\fR +The name of the command to be created (alternatively: the \fInew\fR subcommand +will generate a unique name) +.TP +integer/string \fIDIM\fR +The number of dimensions or one of: "circle", "disk", "sphere" or "ball" +.TP +strings \fIARGS\fR +Zero or more key-value pairs\&. The supported options are: +.RS +.IP \(bu +\fI-start index\fR: The index for the next point to be generated (default: 1) +.IP \(bu +\fI-evaluations number\fR: The number of evaluations to be used by default (default: 100) +.RE +.RE +.PP +The points that are returned lie in the hyperblock [0,1[^n (n the number of dimensions) +or on the unit circle, within the unit disk, on the unit sphere or within the unit ball\&. +.PP +Each generator supports the following subcommands: +.TP +\fBgen next\fR +Return the coordinates of the next quasi-random point +.sp +.TP +\fBgen set-start\fR \fIindex\fR +Reset the index for the next quasi-random point\&. This is useful to control which list of points is returned\&. +Returns the new or the current value, if no value is given\&. +.sp +.TP +\fBgen set-evaluations\fR \fInumber\fR +Reset the default number of evaluations in compound algorithms\&. Note that the actual number is the +smallest 4-fold larger or equal to the given number\&. (The 4-fold plays a role in the detailed integration +routine\&.) +.sp +.TP +\fBgen integral\fR \fIfunc\fR \fIminmax\fR \fIargs\fR +Calculate the integral of the given function over the block (or the circle, sphere etc\&.) +.RS +.TP +string \fIfunc\fR +The name of the function to be integrated +.TP +list \fIminmax\fR +List of pairs of minimum and maximum coordinates\&. This can be used to +map the quasi-random coordinates to the desired hyper-block\&. +.sp +If the space is a circle, disk etc\&. then this argument should be a single value, the radius\&. +The circle, disk, etc\&. is centred at the origin\&. If this is not what is required, then a coordinate +transformation should be made within the function\&. +.TP +strings \fIargs\fR +Zero or more key-value pairs\&. The following options are supported: +.RS +.IP \(bu +\fI-evaluations number\fR: The number of evaluations to be used\&. If not specified use the +default of the generator object\&. +.RE +.RE +.PP +.SH TODO +Implement other algorithms and variants +.PP +Implement more unit tests\&. +.PP +Comparison to pseudo-random numbers for integration\&. +.SH REFERENCES +Various algorithms exist for generating quasi-random numbers\&. The generators created in this package are based on: +\fIhttp://extremelearning\&.com\&.au/unreasonable-effectiveness-of-quasirandom-sequences/\fR +.SH KEYWORDS +mathematics, quasi-random +.SH CATEGORY +Mathematics Index: idoc/man/files/modules/mime/mime.n ================================================================== --- idoc/man/files/modules/mime/mime.n +++ idoc/man/files/modules/mime/mime.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'mime\&.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1999-2000 Marshall T\&. Rose '\" -.TH "mime" n 1\&.6 tcllib "Mime" +.TH "mime" n 1\&.6\&.1 tcllib "Mime" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -274,11 +274,11 @@ .SH NAME mime \- Manipulation of MIME body parts .SH SYNOPSIS package require \fBTcl 8\&.5\fR .sp -package require \fBmime ?1\&.6?\fR +package require \fBmime ?1\&.6\&.1?\fR .sp \fB::mime::initialize\fR ?\fB-canonical\fR \fItype/subtype\fR ?\fB-param\fR {\fIkey value\fR}\&.\&.\&.? ?\fB-encoding\fR \fIvalue\fR? ?\fB-header\fR {\fIkey value\fR}\&.\&.\&.?? (\fB-file\fR \fIname\fR | \fB-string\fR \fIvalue\fR | \fB-parts\fR {\fItoken1\fR \&.\&.\&. \fItokenN\fR}) .sp \fB::mime::finalize\fR \fItoken\fR ?\fB-subordinates\fR \fBall\fR | \fBdynamic\fR | \fBnone\fR? .sp Index: idoc/man/files/modules/mime/smtp.n ================================================================== --- idoc/man/files/modules/mime/smtp.n +++ idoc/man/files/modules/mime/smtp.n @@ -405,19 +405,19 @@ proc send_simple_message {recipient email_server subject body} { package require smtp package require mime - set token [mime::initialize -canonical text/plain \\\\ + set token [mime::initialize -canonical text/plain \\ -string $body] mime::setheader $token Subject $subject - smtp::sendmessage $token \\\\ + smtp::sendmessage $token \\ -recipients $recipient -servers $email_server mime::finalize $token } -send_simple_message someone@somewhere\&.com localhost \\\\ +send_simple_message someone@somewhere\&.com localhost \\ "This is the subject\&." "This is the message\&." .CE .SH "TLS SECURITY CONSIDERATIONS" .PP Index: idoc/man/files/modules/oauth/oauth.n ================================================================== --- idoc/man/files/modules/oauth/oauth.n +++ idoc/man/files/modules/oauth/oauth.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'oauth\&.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 2014 Javi P\&. '\" -.TH "oauth" n 1\&.0\&.2 tcllib "oauth" +.TH "oauth" n 1\&.0\&.3 tcllib "oauth" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -274,11 +274,11 @@ .SH NAME oauth \- oauth API base signature .SH SYNOPSIS package require \fBTcl 8\&.5\fR .sp -package require \fBoauth ?1\&.0\&.2?\fR +package require \fBoauth ?1\&.0\&.3?\fR .sp \fB::oauth::config\fR .sp \fB::oauth::config\fR ?\fIoptions\fR\&.\&.\&.? .sp Index: idoc/man/files/modules/pop3/pop3.n ================================================================== --- idoc/man/files/modules/pop3/pop3.n +++ idoc/man/files/modules/pop3/pop3.n @@ -501,11 +501,11 @@ package require tls tls::init -cafile /path/to/ca/cert -keyfile \&.\&.\&. # Create secured pop3 channel - pop3::open -socketcmd tls::socket \\\\ + pop3::open -socketcmd tls::socket \\ $thehost $theuser $thepassword \&.\&.\&. .CE @@ -519,11 +519,11 @@ package require tls tls::init -cafile /path/to/ca/cert -keyfile \&.\&.\&. # Create secured pop3 channel - pop3::open -stls 1 \\\\ + pop3::open -stls 1 \\ $thehost $theuser $thepassword \&.\&.\&. .CE Index: idoc/man/files/modules/pop3d/pop3d.n ================================================================== --- idoc/man/files/modules/pop3d/pop3d.n +++ idoc/man/files/modules/pop3d/pop3d.n @@ -491,11 +491,11 @@ command, see package \fBtls\fR, to secure the communication\&. .CS package require tls - tls::init \\\\ + tls::init \\ \&.\&.\&. pop3d::new S -socket tls::socket \&.\&.\&. Index: idoc/man/files/modules/practcl/practcl.n ================================================================== --- idoc/man/files/modules/practcl/practcl.n +++ idoc/man/files/modules/practcl/practcl.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'practcl\&.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 2016-2018 Sean Woods '\" -.TH "practcl" n 0\&.11 tcllib "The The Proper Rational API for C to Tool Command Language Module" +.TH "practcl" n 0\&.16\&.3 tcllib "The The Proper Rational API for C to Tool Command Language Module" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -274,69 +274,1795 @@ .SH NAME practcl \- The Practcl Module .SH SYNOPSIS package require \fBTclOO 1\&.0\fR .sp -package require \fBpractcl 0\&.11\fR -.sp -\fBCPUTS\fR \fIvarname\fR \fIbody\fR ?\fIbody\fR\&.\&.\&.? -.sp -\fBpractcl::_isdirectory\fR \fIpath\fR -.sp -\fBpractcl::object\fR \fIparent\fR ?\fIkeyvaluelist\fR? -.sp -\fBpractcl::library\fR ?\fIkeyvaluelist\fR? -.sp -\fBpractcl::exe\fR ?\fIkeyvaluelist\fR? -.sp -\fBpractcl::product\fR \fIparent\fR ?\fIkeyvaluelist\fR? -.sp -\fBpractcl::cheader\fR \fIparent\fR ?\fIkeyvaluelist\fR? -.sp -\fBpractcl::csource\fR \fIparent\fR ?\fIkeyvaluelist\fR? -.sp -\fBpractcl::module\fR \fIparent\fR ?\fIkeyvaluelist\fR? -.sp -\fBpractcl::submodule\fR \fIparent\fR ?\fIkeyvaluelist\fR? +proc \fBpractcl::cat\fR \fIfname\fR +.sp +proc \fBpractcl::docstrip\fR \fItext\fR +.sp +proc \fBputb\fR ?\fImap\fR? \fItext\fR +.sp +proc \fBProc\fR \fIname\fR \fIarglist\fR \fIbody\fR +.sp +proc \fBnoop\fR ?\fIargs\fR? +.sp +proc \fBpractcl::debug\fR ?\fIargs\fR? +.sp +proc \fBpractcl::doexec\fR ?\fIargs\fR? +.sp +proc \fBpractcl::doexec_in\fR \fIpath\fR ?\fIargs\fR? +.sp +proc \fBpractcl::dotclexec\fR ?\fIargs\fR? +.sp +proc \fBpractcl::domake\fR \fIpath\fR ?\fIargs\fR? +.sp +proc \fBpractcl::domake\&.tcl\fR \fIpath\fR ?\fIargs\fR? +.sp +proc \fBpractcl::fossil\fR \fIpath\fR ?\fIargs\fR? +.sp +proc \fBpractcl::fossil_status\fR \fIdir\fR +.sp +proc \fBpractcl::os\fR +.sp +proc \fBpractcl::mkzip\fR \fIexename\fR \fIbarekit\fR \fIvfspath\fR +.sp +proc \fBpractcl::sort_dict\fR \fIlist\fR +.sp +proc \fBpractcl::local_os\fR +.sp +proc \fBpractcl::config\&.tcl\fR \fIpath\fR +.sp +proc \fBpractcl::read_configuration\fR \fIpath\fR +.sp +proc \fBpractcl::tcllib_require\fR \fIpkg\fR ?\fIargs\fR? +.sp +proc \fBpractcl::platform::tcl_core_options\fR \fIos\fR +.sp +proc \fBpractcl::platform::tk_core_options\fR \fIos\fR +.sp +proc \fBpractcl::read_rc_file\fR \fIfilename\fR ?\fIlocaldat\fR \fB\fR? +.sp +proc \fBpractcl::read_sh_subst\fR \fIline\fR \fIinfo\fR +.sp +proc \fBpractcl::read_sh_file\fR \fIfilename\fR ?\fIlocaldat\fR \fB\fR? +.sp +proc \fBpractcl::read_Config\&.sh\fR \fIfilename\fR +.sp +proc \fBpractcl::read_Makefile\fR \fIfilename\fR +.sp +proc \fBpractcl::cputs\fR \fIvarname\fR ?\fIargs\fR? +.sp +proc \fBpractcl::tcl_to_c\fR \fIbody\fR +.sp +proc \fBpractcl::_tagblock\fR \fItext\fR ?\fIstyle\fR \fBtcl\fR? ?\fInote\fR \fB\fR? +.sp +proc \fBpractcl::de_shell\fR \fIdata\fR +.sp +proc \fBpractcl::grep\fR \fIpattern\fR ?\fIfiles\fR \fB\fR? +.sp +proc \fBpractcl::file_lexnormalize\fR \fIsp\fR +.sp +proc \fBpractcl::file_relative\fR \fIbase\fR \fIdst\fR +.sp +proc \fBpractcl::findByPattern\fR \fIbasedir\fR \fIpatterns\fR +.sp +proc \fBpractcl::log\fR \fIfname\fR \fIcomment\fR +.sp +proc \fBpractcl::_pkgindex_simpleIndex\fR \fIpath\fR +.sp +proc \fBpractcl::_pkgindex_directory\fR \fIpath\fR +.sp +proc \fBpractcl::_pkgindex_path_subdir\fR \fIpath\fR +.sp +proc \fBpractcl::pkgindex_path\fR ?\fIargs\fR? +.sp +proc \fBpractcl::installDir\fR \fId1\fR \fId2\fR +.sp +proc \fBpractcl::copyDir\fR \fId1\fR \fId2\fR ?\fItoplevel\fR \fB1\fR? +.sp +proc \fBpractcl::buildModule\fR \fImodpath\fR +.sp +proc \fBpractcl::installModule\fR \fImodpath\fR \fIDEST\fR +.sp +proc \fBpractcl::trigger\fR ?\fIargs\fR? +.sp +proc \fBpractcl::depends\fR ?\fIargs\fR? +.sp +proc \fBpractcl::target\fR \fIname\fR \fIinfo\fR ?\fIaction\fR \fB\fR? +.sp +method \fBconstructor\fR +.sp +method \fBargspec\fR \fIargspec\fR +.sp +method \fBcomment\fR \fIblock\fR +.sp +method \fBkeyword\&.Annotation\fR \fIresultvar\fR \fIcommentblock\fR \fItype\fR \fIname\fR \fIbody\fR +.sp +method \fBkeyword\&.Class\fR \fIresultvar\fR \fIcommentblock\fR \fIname\fR \fIbody\fR +.sp +method \fBkeyword\&.class\fR \fIresultvar\fR \fIcommentblock\fR \fIname\fR \fIbody\fR +.sp +method \fBkeyword\&.Class_Method\fR \fIresultvar\fR \fIcommentblock\fR \fIname\fR ?\fIargs\fR? +.sp +method \fBkeyword\&.method\fR \fIresultvar\fR \fIcommentblock\fR \fIname\fR ?\fIargs\fR? +.sp +method \fBkeyword\&.proc\fR \fIcommentblock\fR \fIname\fR \fIargspec\fR +.sp +method \fBreset\fR +.sp +method \fBMain\fR +.sp +method \fBsection\&.method\fR \fIkeyword\fR \fImethod\fR \fIminfo\fR +.sp +method \fBsection\&.annotation\fR \fItype\fR \fIname\fR \fIiinfo\fR +.sp +method \fBsection\&.class\fR \fIclass_name\fR \fIclass_info\fR +.sp +method \fBsection\&.command\fR \fIprocinfo\fR +.sp +method \fBmanpage\fR ?\fBheader \fIvalue\fR\fR? ?\fBfooter \fIvalue\fR\fR? ?\fBauthors \fIlist\fR\fR? +.sp +method \fBscan_text\fR \fItext\fR +.sp +method \fBscan_file\fR \fIfilename\fR +.sp +method \fB_MorphPatterns\fR +.sp +method \fBdefine\fR \fIsubmethod\fR ?\fIargs\fR? +.sp +method \fBgraft\fR ?\fIargs\fR? +.sp +method \fBinitialize\fR +.sp +method \fBlink\fR \fIcommand\fR ?\fIargs\fR? +.sp +method \fBmorph\fR \fIclassname\fR +.sp +method \fBscript\fR \fIscript\fR +.sp +method \fBselect\fR +.sp +method \fBsource\fR \fIfilename\fR +.sp +classmethod \fBselect\fR \fIobject\fR +.sp +method \fBconfig\&.sh\fR +.sp +method \fBBuildDir\fR \fIPWD\fR +.sp +method \fBMakeDir\fR \fIsrcdir\fR +.sp +method \fBread_configuration\fR +.sp +method \fBbuild-cflags\fR \fIPROJECT\fR \fIDEFS\fR \fInamevar\fR \fIversionvar\fR \fIdefsvar\fR +.sp +method \fBcritcl\fR ?\fIargs\fR? +.sp +method \fBAutoconf\fR +.sp +method \fBBuildDir\fR \fIPWD\fR +.sp +method \fBConfigureOpts\fR +.sp +method \fBMakeDir\fR \fIsrcdir\fR +.sp +method \fBmake {} autodetect\fR +.sp +method \fBmake {} clean\fR +.sp +method \fBmake {} compile\fR +.sp +method \fBmake {} install\fR \fIDEST\fR +.sp +method \fBbuild-compile-sources\fR \fIPROJECT\fR \fICOMPILE\fR \fICPPCOMPILE\fR \fIINCLUDES\fR +.sp +method \fBbuild-Makefile\fR \fIpath\fR \fIPROJECT\fR +.sp +method \fBbuild-library\fR \fIoutfile\fR \fIPROJECT\fR +.sp +method \fBbuild-tclsh\fR \fIoutfile\fR \fIPROJECT\fR ?\fIpath\fR \fBauto\fR? +.sp +method \fBBuildDir\fR \fIPWD\fR +.sp +method \fBmake {} autodetect\fR +.sp +method \fBmake {} clean\fR +.sp +method \fBmake {} compile\fR +.sp +method \fBmake {} install\fR \fIDEST\fR +.sp +method \fBMakeDir\fR \fIsrcdir\fR +.sp +method \fBNmakeOpts\fR +.sp +method \fBconstructor\fR \fImodule_object\fR \fIname\fR \fIinfo\fR ?\fIaction_body\fR \fB\fR? +.sp +method \fBdo\fR +.sp +method \fBcheck\fR +.sp +method \fBoutput\fR +.sp +method \fBreset\fR +.sp +method \fBtriggers\fR +.sp +method \fBconstructor\fR \fIparent\fR ?\fIargs\fR? +.sp +method \fBchild\fR \fImethod\fR +.sp +method \fBgo\fR +.sp +method \fBcstructure\fR \fIname\fR \fIdefinition\fR ?\fIargdat\fR \fB\fR? +.sp +method \fBinclude\fR \fIheader\fR +.sp +method \fBinclude_dir\fR ?\fIargs\fR? +.sp +method \fBinclude_directory\fR ?\fIargs\fR? +.sp +method \fBc_header\fR \fIbody\fR +.sp +method \fBc_code\fR \fIbody\fR +.sp +method \fBc_function\fR \fIheader\fR \fIbody\fR ?\fIinfo\fR \fB\fR? +.sp +method \fBc_tcloomethod\fR \fIname\fR \fIbody\fR ?\fIarginfo\fR \fB\fR? +.sp +method \fBcmethod\fR \fIname\fR \fIbody\fR ?\fIarginfo\fR \fB\fR? +.sp +method \fBc_tclproc_nspace\fR \fInspace\fR +.sp +method \fBc_tclcmd\fR \fIname\fR \fIbody\fR ?\fIarginfo\fR \fB\fR? +.sp +method \fBc_tclproc_raw\fR \fIname\fR \fIbody\fR ?\fIarginfo\fR \fB\fR? +.sp +method \fBtcltype\fR \fIname\fR \fIargdat\fR +.sp +method \fBproject-compile-products\fR +.sp +method \fBimplement\fR \fIpath\fR +.sp +method \fBinitialize\fR +.sp +method \fBlinktype\fR +.sp +method \fBgenerate-cfile-constant\fR +.sp +method \fBgenerate-cfile-header\fR +.sp +method \fBgenerate-cfile-tclapi\fR +.sp +method \fBgenerate-loader-module\fR +.sp +method \fBCollate_Source\fR \fICWD\fR +.sp +method \fBselect\fR +.sp +classmethod \fBselect\fR \fIobject\fR +.sp +method \fBcode\fR \fIsection\fR \fIbody\fR +.sp +method \fBCollate_Source\fR \fICWD\fR +.sp +method \fBproject-compile-products\fR +.sp +method \fBgenerate-debug\fR ?\fIspaces\fR \fB\fR? +.sp +method \fBgenerate-cfile-constant\fR +.sp +method \fBgenerate-cfile-public-structure\fR +.sp +method \fBgenerate-cfile-header\fR +.sp +method \fBgenerate-cfile-global\fR +.sp +method \fBgenerate-cfile-private-typedef\fR +.sp +method \fBgenerate-cfile-private-structure\fR +.sp +method \fBgenerate-cfile-functions\fR +.sp +method \fBgenerate-cfile-tclapi\fR +.sp +method \fBgenerate-hfile-public-define\fR +.sp +method \fBgenerate-hfile-public-macro\fR +.sp +method \fBgenerate-hfile-public-typedef\fR +.sp +method \fBgenerate-hfile-public-structure\fR +.sp +method \fBgenerate-hfile-public-headers\fR +.sp +method \fBgenerate-hfile-public-function\fR +.sp +method \fBgenerate-hfile-public-includes\fR +.sp +method \fBgenerate-hfile-public-verbatim\fR +.sp +method \fBgenerate-loader-external\fR +.sp +method \fBgenerate-loader-module\fR +.sp +method \fBgenerate-stub-function\fR +.sp +method \fBIncludeAdd\fR \fIheadervar\fR ?\fIargs\fR? +.sp +method \fBgenerate-tcl-loader\fR +.sp +method \fBgenerate-tcl-pre\fR +.sp +method \fBgenerate-tcl-post\fR +.sp +method \fBlinktype\fR +.sp +method \fBOfile\fR \fIfilename\fR +.sp +method \fBproject-static-packages\fR +.sp +method \fBtoolset-include-directory\fR +.sp +method \fBtarget\fR \fImethod\fR ?\fIargs\fR? +.sp +method \fBproject-compile-products\fR +.sp +method \fBgenerate-loader-module\fR +.sp +method \fBproject-compile-products\fR +.sp +method \fBlinker-products\fR \fIconfigdict\fR +.sp +method \fBinitialize\fR +.sp +variable \fBmake_object\fR +.sp +method \fB_MorphPatterns\fR +.sp +method \fBadd\fR ?\fIargs\fR? +.sp +method \fBinstall-headers\fR ?\fIargs\fR? +.sp +method \fBmake {} _preamble\fR +.sp +method \fBmake {} pkginfo\fR +.sp +method \fBmake {} objects\fR +.sp +method \fBmake {} object\fR \fIname\fR +.sp +method \fBmake {} reset\fR +.sp +method \fBmake {} trigger\fR ?\fIargs\fR? +.sp +method \fBmake {} depends\fR ?\fIargs\fR? +.sp +method \fBmake {} filename\fR \fIname\fR +.sp +method \fBmake {} target\fR \fIname\fR \fIInfo\fR \fIbody\fR +.sp +method \fBmake {} todo\fR +.sp +method \fBmake {} do\fR +.sp +method \fBchild\fR \fIwhich\fR +.sp +method \fBgenerate-c\fR +.sp +method \fBgenerate-h\fR +.sp +method \fBgenerate-loader\fR +.sp +method \fBinitialize\fR +.sp +method \fBimplement\fR \fIpath\fR +.sp +method \fBlinktype\fR +.sp +method \fB_MorphPatterns\fR +.sp +method \fBconstructor\fR ?\fIargs\fR? +.sp +method \fBadd_object\fR \fIobject\fR +.sp +method \fBadd_project\fR \fIpkg\fR \fIinfo\fR ?\fIoodefine\fR \fB\fR? +.sp +method \fBadd_tool\fR \fIpkg\fR \fIinfo\fR ?\fIoodefine\fR \fB\fR? +.sp +method \fBbuild-tclcore\fR +.sp +method \fBchild\fR \fIwhich\fR +.sp +method \fBlinktype\fR +.sp +method \fBproject\fR \fIpkg\fR ?\fIargs\fR? +.sp +method \fBtclcore\fR +.sp +method \fBtkcore\fR +.sp +method \fBtool\fR \fIpkg\fR ?\fIargs\fR? +.sp +method \fBclean\fR \fIPATH\fR +.sp +method \fBproject-compile-products\fR +.sp +method \fBgo\fR +.sp +method \fBgenerate-decls\fR \fIpkgname\fR \fIpath\fR +.sp +method \fBimplement\fR \fIpath\fR +.sp +method \fBgenerate-make\fR \fIpath\fR +.sp +method \fBlinktype\fR +.sp +method \fBpackage-ifneeded\fR ?\fIargs\fR? +.sp +method \fBshared_library\fR ?\fIfilename\fR \fB\fR? +.sp +method \fBstatic_library\fR ?\fIfilename\fR \fB\fR? +.sp +method \fBbuild-tclkit_main\fR \fIPROJECT\fR \fIPKG_OBJS\fR +.sp +method \fBCollate_Source\fR \fICWD\fR +.sp +method \fBwrap\fR \fIPWD\fR \fIexename\fR \fIvfspath\fR ?\fIargs\fR? +.sp +classmethod \fBSandbox\fR \fIobject\fR +.sp +classmethod \fBselect\fR \fIobject\fR +.sp +classmethod \fBclaim_option\fR +.sp +classmethod \fBclaim_object\fR \fIobject\fR +.sp +classmethod \fBclaim_path\fR \fIpath\fR +.sp +method \fBscm_info\fR +.sp +method \fBDistroMixIn\fR +.sp +method \fBSandbox\fR +.sp +method \fBSrcDir\fR +.sp +method \fBScmTag\fR +.sp +method \fBScmClone\fR +.sp +method \fBScmUnpack\fR +.sp +method \fBScmUpdate\fR +.sp +method \fBUnpack\fR +.sp +classmethod \fBclaim_object\fR \fIobject\fR +.sp +classmethod \fBclaim_option\fR +.sp +classmethod \fBclaim_path\fR \fIpath\fR +.sp +method \fBScmUnpack\fR +.sp +classmethod \fBclaim_object\fR \fIobj\fR +.sp +classmethod \fBclaim_option\fR +.sp +classmethod \fBclaim_path\fR \fIpath\fR +.sp +method \fBscm_info\fR +.sp +method \fBScmClone\fR +.sp +method \fBScmTag\fR +.sp +method \fBScmUnpack\fR +.sp +method \fBScmUpdate\fR +.sp +classmethod \fBclaim_object\fR \fIobj\fR +.sp +classmethod \fBclaim_option\fR +.sp +classmethod \fBclaim_path\fR \fIpath\fR +.sp +method \fBScmTag\fR +.sp +method \fBScmUnpack\fR +.sp +method \fBScmUpdate\fR +.sp +method \fB_MorphPatterns\fR +.sp +method \fBBuildDir\fR \fIPWD\fR +.sp +method \fBchild\fR \fIwhich\fR +.sp +method \fBcompile\fR +.sp +method \fBgo\fR +.sp +method \fBinstall\fR ?\fIargs\fR? +.sp +method \fBlinktype\fR +.sp +method \fBlinker-products\fR \fIconfigdict\fR +.sp +method \fBlinker-external\fR \fIconfigdict\fR +.sp +method \fBlinker-extra\fR \fIconfigdict\fR +.sp +method \fBenv-bootstrap\fR +.sp +method \fBenv-exec\fR +.sp +method \fBenv-install\fR +.sp +method \fBenv-load\fR +.sp +method \fBenv-present\fR +.sp +method \fBsources\fR +.sp +method \fBupdate\fR +.sp +method \fBunpack\fR +.sp +method \fBenv-bootstrap\fR +.sp +method \fBenv-present\fR +.sp +method \fBlinktype\fR +.sp +method \fBenv-bootstrap\fR +.sp +method \fBenv-install\fR +.sp +method \fBenv-present\fR +.sp +method \fBinstall\fR \fIDEST\fR +.sp +method \fBkettle\fR \fIpath\fR ?\fIargs\fR? +.sp +method \fBinstall\fR \fIDEST\fR +.sp +method \fBinstall\fR \fIDEST\fR +.sp +method \fBenv-bootstrap\fR +.sp +method \fBenv-install\fR +.sp +method \fBenv-present\fR +.sp +method \fBinstall\fR \fIDEST\fR +.sp +method \fBinstall-module\fR \fIDEST\fR ?\fIargs\fR? +.sp +method \fBenv-bootstrap\fR +.sp +method \fBenv-install\fR +.sp +method \fBinstall\fR \fIDEST\fR +.sp +method \fBinstall-module\fR \fIDEST\fR ?\fIargs\fR? +.sp +method \fBclean\fR +.sp +method \fBenv-install\fR +.sp +method \fBproject-compile-products\fR +.sp +method \fBComputeInstall\fR +.sp +method \fBgo\fR +.sp +method \fBlinker-products\fR \fIconfigdict\fR +.sp +method \fBproject-static-packages\fR +.sp +method \fBBuildDir\fR \fIPWD\fR +.sp +method \fBcompile\fR +.sp +method \fBConfigure\fR +.sp +method \fBinstall\fR \fIDEST\fR +.sp +method \fBinstall\fR \fIDEST\fR +.sp +method \fBinstall\fR \fIDEST\fR +.sp +method \fBenv-bootstrap\fR +.sp +method \fBenv-present\fR +.sp +method \fBenv-install\fR +.sp +method \fBgo\fR +.sp +method \fBlinktype\fR .sp .BE .SH DESCRIPTION The Practcl module is a tool for integrating large modules for C API Tcl code that requires custom Tcl types and TclOO objects\&. +.PP +The concept with Practcl is that is a single file package that can +assist any tcl based project with distribution, compilation, linking, +VFS preparation, executable assembly, and installation\&. Practcl also +allows one project to invoke the build system from another project, +allowing complex projects such as a statically linked basekit to be +assembled with relative ease\&. +.PP +Practcl ships as a single file, and aside from a Tcl 8\&.6 interpreter, +has no external dependencies\&. +.PP +Making a practcl project .SH COMMANDS .TP -\fBCPUTS\fR \fIvarname\fR \fIbody\fR ?\fIbody\fR\&.\&.\&.? -Appends blocks of text to a buffer\&. This command tries to reduce the number -of line breaks between bodies\&. -.TP -\fBpractcl::_isdirectory\fR \fIpath\fR -Returns true if \fIpath\fR is a directory, using the test -.PP -.TP -\fBpractcl::object\fR \fIparent\fR ?\fIkeyvaluelist\fR? +proc \fBpractcl::cat\fR \fIfname\fR +Concatenate a file +.TP +proc \fBpractcl::docstrip\fR \fItext\fR +Strip the global comments from tcl code\&. Used to +prevent the documentation markup comments from clogging +up files intended for distribution in machine readable format\&. +.TP +proc \fBputb\fR ?\fImap\fR? \fItext\fR +Append a line of text to a variable\&. Optionally apply a string mapping\&. +.TP +proc \fBProc\fR \fIname\fR \fIarglist\fR \fIbody\fR +Generate a proc if no command already exists by that name +.TP +proc \fBnoop\fR ?\fIargs\fR? +A command to do nothing\&. A handy way of +negating an instruction without +having to comment it completely out\&. +It's also a handy attachment point for +an object to be named later +.TP +proc \fBpractcl::debug\fR ?\fIargs\fR? +.TP +proc \fBpractcl::doexec\fR ?\fIargs\fR? +Drop in a static copy of Tcl +.TP +proc \fBpractcl::doexec_in\fR \fIpath\fR ?\fIargs\fR? +.TP +proc \fBpractcl::dotclexec\fR ?\fIargs\fR? +.TP +proc \fBpractcl::domake\fR \fIpath\fR ?\fIargs\fR? +.TP +proc \fBpractcl::domake\&.tcl\fR \fIpath\fR ?\fIargs\fR? +.TP +proc \fBpractcl::fossil\fR \fIpath\fR ?\fIargs\fR? +.TP +proc \fBpractcl::fossil_status\fR \fIdir\fR +.TP +proc \fBpractcl::os\fR +.TP +proc \fBpractcl::mkzip\fR \fIexename\fR \fIbarekit\fR \fIvfspath\fR +Build a zipfile\&. On tcl8\&.6 this invokes the native Zip implementation +on older interpreters this invokes zip via exec +.TP +proc \fBpractcl::sort_dict\fR \fIlist\fR +Dictionary sort a key/value list\&. Needed because pre tcl8\&.6 +does not have \fIlsort -stride 2\fR +.TP +proc \fBpractcl::local_os\fR +.TP +proc \fBpractcl::config\&.tcl\fR \fIpath\fR +Detect local platform +.TP +proc \fBpractcl::read_configuration\fR \fIpath\fR +.TP +proc \fBpractcl::tcllib_require\fR \fIpkg\fR ?\fIargs\fR? +Try to load a package, and failing that +retrieve tcllib +.TP +proc \fBpractcl::platform::tcl_core_options\fR \fIos\fR +.TP +proc \fBpractcl::platform::tk_core_options\fR \fIos\fR +.TP +proc \fBpractcl::read_rc_file\fR \fIfilename\fR ?\fIlocaldat\fR \fB\fR? +Read a stylized key/value list stored in a file +.TP +proc \fBpractcl::read_sh_subst\fR \fIline\fR \fIinfo\fR +Converts a XXX\&.sh file into a series of Tcl variables +.TP +proc \fBpractcl::read_sh_file\fR \fIfilename\fR ?\fIlocaldat\fR \fB\fR? +.TP +proc \fBpractcl::read_Config\&.sh\fR \fIfilename\fR +A simpler form of read_sh_file tailored +to pulling data from (tcl|tk)Config\&.sh +.TP +proc \fBpractcl::read_Makefile\fR \fIfilename\fR +A simpler form of read_sh_file tailored +to pulling data from a Makefile +.TP +proc \fBpractcl::cputs\fR \fIvarname\fR ?\fIargs\fR? +Append arguments to a buffer +The command works like puts in that each call will also insert +a line feed\&. Unlike puts, blank links in the interstitial are +suppressed +.TP +proc \fBpractcl::tcl_to_c\fR \fIbody\fR +.TP +proc \fBpractcl::_tagblock\fR \fItext\fR ?\fIstyle\fR \fBtcl\fR? ?\fInote\fR \fB\fR? +.TP +proc \fBpractcl::de_shell\fR \fIdata\fR +.TP +proc \fBpractcl::grep\fR \fIpattern\fR ?\fIfiles\fR \fB\fR? +Search for the pattern \fIpattern\fR amongst $files +.TP +proc \fBpractcl::file_lexnormalize\fR \fIsp\fR +.TP +proc \fBpractcl::file_relative\fR \fIbase\fR \fIdst\fR +Calculate a relative path between base and dst +.sp +Example: +.CS + + ::practcl::file_relative ~/build/tcl/unix ~/build/tcl/library + > \&.\&./library + + + +.CE +.TP +proc \fBpractcl::findByPattern\fR \fIbasedir\fR \fIpatterns\fR +.TP +proc \fBpractcl::log\fR \fIfname\fR \fIcomment\fR +Record an event in the practcl log +.TP +proc \fBpractcl::_pkgindex_simpleIndex\fR \fIpath\fR +.TP +proc \fBpractcl::_pkgindex_directory\fR \fIpath\fR +Return true if the pkgindex file contains +any statement other than "package ifneeded" +and/or if any package ifneeded loads a DLL +.TP +proc \fBpractcl::_pkgindex_path_subdir\fR \fIpath\fR +Helper function for ::practcl::pkgindex_path +.TP +proc \fBpractcl::pkgindex_path\fR ?\fIargs\fR? +Index all paths given as though they will end up in the same +virtual file system +.TP +proc \fBpractcl::installDir\fR \fId1\fR \fId2\fR +Delete the contents of \fId2\fR, and then +recusively Ccopy the contents of \fId1\fR to \fId2\fR\&. +.TP +proc \fBpractcl::copyDir\fR \fId1\fR \fId2\fR ?\fItoplevel\fR \fB1\fR? +Recursively copy the contents of \fId1\fR to \fId2\fR +.TP +proc \fBpractcl::buildModule\fR \fImodpath\fR +.TP +proc \fBpractcl::installModule\fR \fImodpath\fR \fIDEST\fR +.TP +proc \fBpractcl::trigger\fR ?\fIargs\fR? +Trigger build targets, and recompute dependencies +.sp +Internals: +.CS + + + ::practcl::LOCAL make trigger {*}$args + foreach {name obj} [::practcl::LOCAL make objects] { + set ::make($name) [$obj do] + } + +.CE +.TP +proc \fBpractcl::depends\fR ?\fIargs\fR? +Calculate if a dependency for any of the arguments needs to +be fulfilled or rebuilt\&. +.sp +Internals: +.CS + + + ::practcl::LOCAL make depends {*}$args + +.CE +.TP +proc \fBpractcl::target\fR \fIname\fR \fIinfo\fR ?\fIaction\fR \fB\fR? +Declare a build product\&. This proc is just a shorthand for +\fI::practcl::LOCAL make task $name $info $action\fR +.sp +Registering a build product with this command will create +an entry in the global array, and populate +a value in the global array\&. +.sp +Internals: +.CS + + + set obj [::practcl::LOCAL make task $name $info $action] + set ::make($name) 0 + set filename [$obj define get filename] + if {$filename ne {}} { + set ::target($name) $filename + } + +.CE +.PP +.SH CLASSES +.SS "CLASS PRACTCL::DOCTOOL" +.CS + +{ set authors { + {John Doe} {jdoe@illustrious\&.edu} + {Tom RichardHarry} {tomdickharry@illustrius\&.edu} + } + # Create the object + ::practcl::doctool create AutoDoc + set fout [open [file join $moddir module\&.tcl] w] + foreach file [glob [file join $srcdir *\&.tcl]] { + set content [::practcl::cat [file join $srcdir $file]] + # Scan the file + AutoDoc scan_text $content + # Strip the comments from the distribution + puts $fout [::practcl::docstrip $content] + } + # Write out the manual page + set manout [open [file join $moddir module\&.man] w] + dict set args header [string map $modmap [::practcl::cat [file join $srcdir manual\&.txt]]] + dict set args footer [string map $modmap [::practcl::cat [file join $srcdir footer\&.txt]]] + dict set args authors $authors + puts $manout [AutoDoc manpage {*}$args] + close $manout + + +} +.CE +.PP +Tool for build scripts to dynamically generate manual files from comments +in source code files +.PP +\fBMethods\fR +.TP +method \fBconstructor\fR +.TP +method \fBargspec\fR \fIargspec\fR +Process an argument list into an informational dict\&. +This method also understands non-positional +arguments expressed in the notation of Tip 471 +\fIhttps://core\&.tcl-lang\&.org/tips/doc/trunk/tip/479\&.md\fR\&. +.sp +The output will be a dictionary of all of the fields and whether the fields +are \fBpositional\fR, \fBmandatory\fR, and whether they have a +\fBdefault\fR value\&. +.sp +.sp +Example: +.CS + + my argspec {a b {c 10}} + + > a {positional 1 mandatory 1} b {positional 1 mandatory 1} c {positional 1 mandatory 0 default 10} + + + +.CE +.TP +method \fBcomment\fR \fIblock\fR +Convert a block of comments into an informational dictionary\&. +If lines in the comment start with a single word ending in a colon, +all subsequent lines are appended to a dictionary field of that name\&. +If no fields are given, all of the text is appended to the \fBdescription\fR +field\&. +.sp +Example: +.CS + + my comment {Does something cool} + > description {Does something cool} + + my comment { + title : Something really cool + author : Sean Woods + author : John Doe + description : + This does something really cool! + } + > description {This does something really cool!} + title {Something really cool} + author {Sean Woods + John Doe} + + + +.CE +.TP +method \fBkeyword\&.Annotation\fR \fIresultvar\fR \fIcommentblock\fR \fItype\fR \fIname\fR \fIbody\fR +.TP +method \fBkeyword\&.Class\fR \fIresultvar\fR \fIcommentblock\fR \fIname\fR \fIbody\fR +Process an oo::objdefine call that modifies the class object +itself +.TP +method \fBkeyword\&.class\fR \fIresultvar\fR \fIcommentblock\fR \fIname\fR \fIbody\fR +Process an oo::define, clay::define, etc statement\&. +.TP +method \fBkeyword\&.Class_Method\fR \fIresultvar\fR \fIcommentblock\fR \fIname\fR ?\fIargs\fR? +Process a statement for a clay style class method +.TP +method \fBkeyword\&.method\fR \fIresultvar\fR \fIcommentblock\fR \fIname\fR ?\fIargs\fR? +Process a statement for a tcloo style object method +.TP +method \fBkeyword\&.proc\fR \fIcommentblock\fR \fIname\fR \fIargspec\fR +Process a proc statement +.TP +method \fBreset\fR +Reset the state of the object and its embedded coroutine +.TP +method \fBMain\fR +Main body of the embedded coroutine for the object +.TP +method \fBsection\&.method\fR \fIkeyword\fR \fImethod\fR \fIminfo\fR +Generate the manual page text for a method or proc +.TP +method \fBsection\&.annotation\fR \fItype\fR \fIname\fR \fIiinfo\fR +.TP +method \fBsection\&.class\fR \fIclass_name\fR \fIclass_info\fR +Generate the manual page text for a class +.TP +method \fBsection\&.command\fR \fIprocinfo\fR +Generate the manual page text for the commands section +.TP +method \fBmanpage\fR ?\fBheader \fIvalue\fR\fR? ?\fBfooter \fIvalue\fR\fR? ?\fBauthors \fIlist\fR\fR? +Generate the manual page\&. Returns the completed text suitable for saving in \&.man file\&. +The header argument is a block of doctools text to go in before the machine generated +section\&. footer is a block of doctools text to go in after the machine generated +section\&. authors is a list of individual authors and emails in the form of AUTHOR EMAIL ?AUTHOR EMAIL?\&.\&.\&. +.TP +method \fBscan_text\fR \fItext\fR +Scan a block of text +.TP +method \fBscan_file\fR \fIfilename\fR +Scan a file of text +.PP +.PP +.SS "CLASS PRACTCL::METACLASS" +The metaclass for all practcl objects +.PP +\fBMethods\fR +.TP +method \fB_MorphPatterns\fR +.TP +method \fBdefine\fR \fIsubmethod\fR ?\fIargs\fR? +.TP +method \fBgraft\fR ?\fIargs\fR? +.TP +method \fBinitialize\fR +.TP +method \fBlink\fR \fIcommand\fR ?\fIargs\fR? +.TP +method \fBmorph\fR \fIclassname\fR +.TP +method \fBscript\fR \fIscript\fR +.TP +method \fBselect\fR +.TP +method \fBsource\fR \fIfilename\fR +.PP +.PP +.SS "CLASS PRACTCL::TOOLSET" +Ancestor-less class intended to be a mixin +which defines a family of build related behaviors +that are modified when targetting either gcc or msvc +.PP +\fBClass Methods\fR +.TP +classmethod \fBselect\fR \fIobject\fR +Perform the selection for the toolset mixin +.PP +.PP +\fBMethods\fR +.TP +method \fBconfig\&.sh\fR +find or fake a key/value list describing this project +.TP +method \fBBuildDir\fR \fIPWD\fR +Compute the location where the product will be built +.TP +method \fBMakeDir\fR \fIsrcdir\fR +Return where the Makefile is located relative to \fIsrcdir\fR\&. +For this implementation the MakeDir is always srcdir\&. +.TP +method \fBread_configuration\fR +Read information about the build process for this package\&. +For this implementation, data is sought in the following locations +in the following order: +config\&.tcl (generated by practcl\&.) PKGConfig\&.sh\&. The Makefile +.sp +If the Makefile needs to be consulted, but does not exist, the +Configure method is invoked +.TP +method \fBbuild-cflags\fR \fIPROJECT\fR \fIDEFS\fR \fInamevar\fR \fIversionvar\fR \fIdefsvar\fR +method DEFS +This method populates 4 variables: +name - The name of the package +version - The version of the package +defs - C flags passed to the compiler +includedir - A list of paths to feed to the compiler for finding headers +.TP +method \fBcritcl\fR ?\fIargs\fR? +Invoke critcl in an external process +.PP +.PP +.SS "CLASS PRACTCL::TOOLSET\&.GCC" +\fIancestors\fR: \fBpractcl::toolset\fR +.PP +.PP +\fBMethods\fR +.TP +method \fBAutoconf\fR +.TP +method \fBBuildDir\fR \fIPWD\fR +.TP +method \fBConfigureOpts\fR +.TP +method \fBMakeDir\fR \fIsrcdir\fR +Detect what directory contains the Makefile template +.TP +method \fBmake {} autodetect\fR +.TP +method \fBmake {} clean\fR +.TP +method \fBmake {} compile\fR +.TP +method \fBmake {} install\fR \fIDEST\fR +.TP +method \fBbuild-compile-sources\fR \fIPROJECT\fR \fICOMPILE\fR \fICPPCOMPILE\fR \fIINCLUDES\fR +.TP +method \fBbuild-Makefile\fR \fIpath\fR \fIPROJECT\fR +.TP +method \fBbuild-library\fR \fIoutfile\fR \fIPROJECT\fR +Produce a static or dynamic library +.TP +method \fBbuild-tclsh\fR \fIoutfile\fR \fIPROJECT\fR ?\fIpath\fR \fBauto\fR? +Produce a static executable +.PP +.PP +.SS "CLASS PRACTCL::TOOLSET\&.MSVC" +\fIancestors\fR: \fBpractcl::toolset\fR +.PP +.PP +\fBMethods\fR +.TP +method \fBBuildDir\fR \fIPWD\fR +MSVC always builds in the source directory +.TP +method \fBmake {} autodetect\fR +Do nothing +.TP +method \fBmake {} clean\fR +.TP +method \fBmake {} compile\fR +.TP +method \fBmake {} install\fR \fIDEST\fR +.TP +method \fBMakeDir\fR \fIsrcdir\fR +Detect what directory contains the Makefile template +.TP +method \fBNmakeOpts\fR +.PP +.PP +.SS "CLASS PRACTCL::MAKE_OBJ" +\fIancestors\fR: \fBpractcl::metaclass\fR +.PP +A build deliverable object\&. Normally an object file, header, or tcl script +which must be compiled or generated in some way +.PP +\fBMethods\fR +.TP +method \fBconstructor\fR \fImodule_object\fR \fIname\fR \fIinfo\fR ?\fIaction_body\fR \fB\fR? +.TP +method \fBdo\fR +.TP +method \fBcheck\fR +.TP +method \fBoutput\fR +.TP +method \fBreset\fR +.TP +method \fBtriggers\fR +.PP +.PP +.SS "CLASS PRACTCL::OBJECT" +\fIancestors\fR: \fBpractcl::metaclass\fR +.PP A generic Practcl object -.TP -\fBpractcl::library\fR ?\fIkeyvaluelist\fR? -A Practcl object representing a library container -.TP -\fBpractcl::exe\fR ?\fIkeyvaluelist\fR? -A Practcl object representing a wrapped executable -.TP -\fBpractcl::product\fR \fIparent\fR ?\fIkeyvaluelist\fR? -A Practcl object representing a compiled product -.TP -\fBpractcl::cheader\fR \fIparent\fR ?\fIkeyvaluelist\fR? -A Practcl object representing an externally generated c header -.TP -\fBpractcl::csource\fR \fIparent\fR ?\fIkeyvaluelist\fR? -A Practcl object representing an externally generated c source file -.TP -\fBpractcl::module\fR \fIparent\fR ?\fIkeyvaluelist\fR? -A Practcl object representing a dynamically generated C/H/Tcl suite -.TP -\fBpractcl::submodule\fR \fIparent\fR ?\fIkeyvaluelist\fR? -A Practcl object representing a dynamically generated C/H/Tcl suite, subordinate to a module +.PP +\fBMethods\fR +.TP +method \fBconstructor\fR \fIparent\fR ?\fIargs\fR? +.TP +method \fBchild\fR \fImethod\fR +.TP +method \fBgo\fR +.PP +.PP +.SS "CLASS PRACTCL::DYNAMIC" +Dynamic blocks do not generate their own \&.c files, +instead the contribute to the amalgamation +of the main library file +.PP +\fBMethods\fR +.TP +method \fBcstructure\fR \fIname\fR \fIdefinition\fR ?\fIargdat\fR \fB\fR? +Parser functions +.TP +method \fBinclude\fR \fIheader\fR +.TP +method \fBinclude_dir\fR ?\fIargs\fR? +.TP +method \fBinclude_directory\fR ?\fIargs\fR? +.TP +method \fBc_header\fR \fIbody\fR +.TP +method \fBc_code\fR \fIbody\fR +.TP +method \fBc_function\fR \fIheader\fR \fIbody\fR ?\fIinfo\fR \fB\fR? +.TP +method \fBc_tcloomethod\fR \fIname\fR \fIbody\fR ?\fIarginfo\fR \fB\fR? +.TP +method \fBcmethod\fR \fIname\fR \fIbody\fR ?\fIarginfo\fR \fB\fR? +Alias to classic name +.TP +method \fBc_tclproc_nspace\fR \fInspace\fR +.TP +method \fBc_tclcmd\fR \fIname\fR \fIbody\fR ?\fIarginfo\fR \fB\fR? +.TP +method \fBc_tclproc_raw\fR \fIname\fR \fIbody\fR ?\fIarginfo\fR \fB\fR? +Alias to classic name +.TP +method \fBtcltype\fR \fIname\fR \fIargdat\fR +.TP +method \fBproject-compile-products\fR +Module interactions +.TP +method \fBimplement\fR \fIpath\fR +.TP +method \fBinitialize\fR +Practcl internals +.TP +method \fBlinktype\fR +.TP +method \fBgenerate-cfile-constant\fR +.TP +method \fBgenerate-cfile-header\fR +.TP +method \fBgenerate-cfile-tclapi\fR +Generate code that provides implements Tcl API +calls +.TP +method \fBgenerate-loader-module\fR +Generate code that runs when the package/module is +initialized into the interpreter +.TP +method \fBCollate_Source\fR \fICWD\fR +.TP +method \fBselect\fR +Once an object marks itself as some +flavor of dynamic, stop trying to morph +it into something else +.PP +.PP +.SS "CLASS PRACTCL::PRODUCT" +A deliverable for the build system +.PP +\fBClass Methods\fR +.TP +classmethod \fBselect\fR \fIobject\fR +.PP +.PP +\fBMethods\fR +.TP +method \fBcode\fR \fIsection\fR \fIbody\fR +.TP +method \fBCollate_Source\fR \fICWD\fR +.TP +method \fBproject-compile-products\fR +.TP +method \fBgenerate-debug\fR ?\fIspaces\fR \fB\fR? +.TP +method \fBgenerate-cfile-constant\fR +.TP +method \fBgenerate-cfile-public-structure\fR +Populate const static data structures +.TP +method \fBgenerate-cfile-header\fR +.TP +method \fBgenerate-cfile-global\fR +.TP +method \fBgenerate-cfile-private-typedef\fR +.TP +method \fBgenerate-cfile-private-structure\fR +.TP +method \fBgenerate-cfile-functions\fR +Generate code that provides subroutines called by +Tcl API methods +.TP +method \fBgenerate-cfile-tclapi\fR +Generate code that provides implements Tcl API +calls +.TP +method \fBgenerate-hfile-public-define\fR +.TP +method \fBgenerate-hfile-public-macro\fR +.TP +method \fBgenerate-hfile-public-typedef\fR +.TP +method \fBgenerate-hfile-public-structure\fR +.TP +method \fBgenerate-hfile-public-headers\fR +.TP +method \fBgenerate-hfile-public-function\fR +.TP +method \fBgenerate-hfile-public-includes\fR +.TP +method \fBgenerate-hfile-public-verbatim\fR +.TP +method \fBgenerate-loader-external\fR +.TP +method \fBgenerate-loader-module\fR +.TP +method \fBgenerate-stub-function\fR +.TP +method \fBIncludeAdd\fR \fIheadervar\fR ?\fIargs\fR? +.TP +method \fBgenerate-tcl-loader\fR +.TP +method \fBgenerate-tcl-pre\fR +This methods generates any Tcl script file +which is required to pre-initialize the C library +.TP +method \fBgenerate-tcl-post\fR +.TP +method \fBlinktype\fR +.TP +method \fBOfile\fR \fIfilename\fR +.TP +method \fBproject-static-packages\fR +Methods called by the master project +.TP +method \fBtoolset-include-directory\fR +Methods called by the toolset +.TP +method \fBtarget\fR \fImethod\fR ?\fIargs\fR? +.PP +.PP +.SS "CLASS PRACTCL::PRODUCT\&.CHEADER" +\fIancestors\fR: \fBpractcl::product\fR +.PP +A product which generated from a C header file\&. Which is to say, nothing\&. +.PP +\fBMethods\fR +.TP +method \fBproject-compile-products\fR +.TP +method \fBgenerate-loader-module\fR +.PP +.PP +.SS "CLASS PRACTCL::PRODUCT\&.CSOURCE" +\fIancestors\fR: \fBpractcl::product\fR +.PP +A product which generated from a C source file\&. Normally an object (\&.o) file\&. +.PP +\fBMethods\fR +.TP +method \fBproject-compile-products\fR +.PP +.PP +.SS "CLASS PRACTCL::PRODUCT\&.CLIBRARY" +\fIancestors\fR: \fBpractcl::product\fR +.PP +A product which is generated from a compiled C library\&. +Usually a \&.a or a \&.dylib file, but in complex cases may +actually just be a conduit for one project to integrate the +source code of another +.PP +\fBMethods\fR +.TP +method \fBlinker-products\fR \fIconfigdict\fR +.PP +.PP +.SS "CLASS PRACTCL::PRODUCT\&.DYNAMIC" +\fIancestors\fR: \fBpractcl::dynamic\fR \fBpractcl::product\fR +.PP +A product which is generated from C code that itself is generated +by practcl or some other means\&. This C file may or may not produce +its own \&.o file, depending on whether it is eligible to become part +of an amalgamation +.PP +\fBMethods\fR +.TP +method \fBinitialize\fR +.PP +.PP +.SS "CLASS PRACTCL::PRODUCT\&.CRITCL" +\fIancestors\fR: \fBpractcl::dynamic\fR \fBpractcl::product\fR +.PP +A binary product produced by critcl\&. Note: The implementation is not +written yet, this class does nothing\&. +.PP +.SS "CLASS PRACTCL::MODULE" +\fIancestors\fR: \fBpractcl::object\fR \fBpractcl::product\&.dynamic\fR +.PP +In the end, all C code must be loaded into a module +This will either be a dynamically loaded library implementing +a tcl extension, or a compiled in segment of a custom shell/app +.PP +\fBVariable\fR +.TP +variable \fBmake_object\fR +.PP +.PP +\fBMethods\fR +.TP +method \fB_MorphPatterns\fR +.TP +method \fBadd\fR ?\fIargs\fR? +.TP +method \fBinstall-headers\fR ?\fIargs\fR? +.TP +method \fBmake {} _preamble\fR +.TP +method \fBmake {} pkginfo\fR +.TP +method \fBmake {} objects\fR +Return a dictionary of all handles and associated objects +.TP +method \fBmake {} object\fR \fIname\fR +Return the object associated with handle \fIname\fR +.TP +method \fBmake {} reset\fR +Reset all deputy objects +.TP +method \fBmake {} trigger\fR ?\fIargs\fR? +Exercise the triggers method for all handles listed +.TP +method \fBmake {} depends\fR ?\fIargs\fR? +Exercise the check method for all handles listed +.TP +method \fBmake {} filename\fR \fIname\fR +Return the file name of the build product for the listed +handle +.TP +method \fBmake {} target\fR \fIname\fR \fIInfo\fR \fIbody\fR +.TP +method \fBmake {} todo\fR +Return a list of handles for object which return true for the +do method +.TP +method \fBmake {} do\fR +For each target exercise the action specified in the \fIaction\fR +definition if the \fIdo\fR method returns true +.TP +method \fBchild\fR \fIwhich\fR +.TP +method \fBgenerate-c\fR +This methods generates the contents of an amalgamated \&.c file +which implements the loader for a batch of tools +.TP +method \fBgenerate-h\fR +This methods generates the contents of an amalgamated \&.h file +which describes the public API of this module +.TP +method \fBgenerate-loader\fR +.TP +method \fBinitialize\fR +.TP +method \fBimplement\fR \fIpath\fR +.TP +method \fBlinktype\fR +.PP +.PP +.SS "CLASS PRACTCL::PROJECT" +\fIancestors\fR: \fBpractcl::module\fR +.PP +A toplevel project that is a collection of other projects +.PP +\fBMethods\fR +.TP +method \fB_MorphPatterns\fR +.TP +method \fBconstructor\fR ?\fIargs\fR? +.TP +method \fBadd_object\fR \fIobject\fR +.TP +method \fBadd_project\fR \fIpkg\fR \fIinfo\fR ?\fIoodefine\fR \fB\fR? +.TP +method \fBadd_tool\fR \fIpkg\fR \fIinfo\fR ?\fIoodefine\fR \fB\fR? +.TP +method \fBbuild-tclcore\fR +Compile the Tcl core\&. If the define \fItk\fR is true, compile the +Tk core as well +.TP +method \fBchild\fR \fIwhich\fR +.TP +method \fBlinktype\fR +.TP +method \fBproject\fR \fIpkg\fR ?\fIargs\fR? +Exercise the methods of a sub-object +.TP +method \fBtclcore\fR +.TP +method \fBtkcore\fR +.TP +method \fBtool\fR \fIpkg\fR ?\fIargs\fR? +.PP +.PP +.SS "CLASS PRACTCL::LIBRARY" +\fIancestors\fR: \fBpractcl::project\fR +.PP +A toplevel project that produces a library +.PP +\fBMethods\fR +.TP +method \fBclean\fR \fIPATH\fR +.TP +method \fBproject-compile-products\fR +.TP +method \fBgo\fR +.TP +method \fBgenerate-decls\fR \fIpkgname\fR \fIpath\fR +.TP +method \fBimplement\fR \fIpath\fR +.TP +method \fBgenerate-make\fR \fIpath\fR +Backward compadible call +.TP +method \fBlinktype\fR +.TP +method \fBpackage-ifneeded\fR ?\fIargs\fR? +Create a "package ifneeded" +Args are a list of aliases for which this package will answer to +.TP +method \fBshared_library\fR ?\fIfilename\fR \fB\fR? +.TP +method \fBstatic_library\fR ?\fIfilename\fR \fB\fR? +.PP +.PP +.SS "CLASS PRACTCL::TCLKIT" +\fIancestors\fR: \fBpractcl::library\fR +.PP +A toplevel project that produces a self-contained executable +.PP +\fBMethods\fR +.TP +method \fBbuild-tclkit_main\fR \fIPROJECT\fR \fIPKG_OBJS\fR +.TP +method \fBCollate_Source\fR \fICWD\fR +.TP +method \fBwrap\fR \fIPWD\fR \fIexename\fR \fIvfspath\fR ?\fIargs\fR? +Wrap an executable +.PP +.PP +.SS "CLASS PRACTCL::DISTRIBUTION" +Standalone class to manage code distribution +This class is intended to be mixed into another class +(Thus the lack of ancestors) +.PP +\fBClass Methods\fR +.TP +classmethod \fBSandbox\fR \fIobject\fR +.TP +classmethod \fBselect\fR \fIobject\fR +.TP +classmethod \fBclaim_option\fR +.TP +classmethod \fBclaim_object\fR \fIobject\fR +.TP +classmethod \fBclaim_path\fR \fIpath\fR +.PP +.PP +\fBMethods\fR +.TP +method \fBscm_info\fR +.TP +method \fBDistroMixIn\fR +.TP +method \fBSandbox\fR +.TP +method \fBSrcDir\fR +.TP +method \fBScmTag\fR +.TP +method \fBScmClone\fR +.TP +method \fBScmUnpack\fR +.TP +method \fBScmUpdate\fR +.TP +method \fBUnpack\fR +.PP +.PP +.SS "CLASS PRACTCL::DISTRIBUTION\&.SNAPSHOT" +\fIancestors\fR: \fBpractcl::distribution\fR +.PP +A file distribution from zip, tarball, or other non-scm archive format +.PP +\fBClass Methods\fR +.TP +classmethod \fBclaim_object\fR \fIobject\fR +.TP +classmethod \fBclaim_option\fR +.TP +classmethod \fBclaim_path\fR \fIpath\fR +.PP +.PP +\fBMethods\fR +.TP +method \fBScmUnpack\fR +.PP +.PP +.SS "CLASS PRACTCL::DISTRIBUTION\&.FOSSIL" +\fIancestors\fR: \fBpractcl::distribution\fR +.PP +A file distribution based on fossil +.PP +\fBClass Methods\fR +.TP +classmethod \fBclaim_object\fR \fIobj\fR +Check for markers in the metadata +.TP +classmethod \fBclaim_option\fR +.TP +classmethod \fBclaim_path\fR \fIpath\fR +Check for markers in the source root +.PP +.PP +\fBMethods\fR +.TP +method \fBscm_info\fR +.TP +method \fBScmClone\fR +Clone the source +.TP +method \fBScmTag\fR +.TP +method \fBScmUnpack\fR +.TP +method \fBScmUpdate\fR +.PP +.PP +.SS "CLASS PRACTCL::DISTRIBUTION\&.GIT" +\fIancestors\fR: \fBpractcl::distribution\fR +.PP +A file distribution based on git +.PP +\fBClass Methods\fR +.TP +classmethod \fBclaim_object\fR \fIobj\fR +.TP +classmethod \fBclaim_option\fR +.TP +classmethod \fBclaim_path\fR \fIpath\fR +.PP +.PP +\fBMethods\fR +.TP +method \fBScmTag\fR +.TP +method \fBScmUnpack\fR +.TP +method \fBScmUpdate\fR +.PP +.PP +.SS "CLASS PRACTCL::SUBPROJECT" +\fIancestors\fR: \fBpractcl::module\fR +.PP +A subordinate project +.PP +\fBMethods\fR +.TP +method \fB_MorphPatterns\fR +.TP +method \fBBuildDir\fR \fIPWD\fR +.TP +method \fBchild\fR \fIwhich\fR +.TP +method \fBcompile\fR +.TP +method \fBgo\fR +.TP +method \fBinstall\fR ?\fIargs\fR? +Install project into the local build system +.TP +method \fBlinktype\fR +.TP +method \fBlinker-products\fR \fIconfigdict\fR +.TP +method \fBlinker-external\fR \fIconfigdict\fR +.TP +method \fBlinker-extra\fR \fIconfigdict\fR +.TP +method \fBenv-bootstrap\fR +Methods for packages/tools that can be downloaded +possibly built and used internally by this Practcl +process +Load the facility into the interpreter +.TP +method \fBenv-exec\fR +Return a file path that exec can call +.TP +method \fBenv-install\fR +Install the tool into the local environment +.TP +method \fBenv-load\fR +Do whatever is necessary to get the tool +into the local environment +.TP +method \fBenv-present\fR +Check if tool is available for load/already loaded +.TP +method \fBsources\fR +.TP +method \fBupdate\fR +.TP +method \fBunpack\fR +.PP +.PP +.SS "CLASS PRACTCL::SUBPROJECT\&.SOURCE" +\fIancestors\fR: \fBpractcl::subproject\fR \fBpractcl::library\fR +.PP +A project which the kit compiles and integrates +the source for itself +.PP +\fBMethods\fR +.TP +method \fBenv-bootstrap\fR +.TP +method \fBenv-present\fR +.TP +method \fBlinktype\fR +.PP +.PP +.SS "CLASS PRACTCL::SUBPROJECT\&.TEAPOT" +\fIancestors\fR: \fBpractcl::subproject\fR +.PP +a copy from the teapot +.PP +\fBMethods\fR +.TP +method \fBenv-bootstrap\fR +.TP +method \fBenv-install\fR +.TP +method \fBenv-present\fR +.TP +method \fBinstall\fR \fIDEST\fR +.PP +.PP +.SS "CLASS PRACTCL::SUBPROJECT\&.KETTLE" +\fIancestors\fR: \fBpractcl::subproject\fR +.PP +.PP +\fBMethods\fR +.TP +method \fBkettle\fR \fIpath\fR ?\fIargs\fR? +.TP +method \fBinstall\fR \fIDEST\fR +.PP +.PP +.SS "CLASS PRACTCL::SUBPROJECT\&.CRITCL" +\fIancestors\fR: \fBpractcl::subproject\fR +.PP +.PP +\fBMethods\fR +.TP +method \fBinstall\fR \fIDEST\fR +.PP +.PP +.SS "CLASS PRACTCL::SUBPROJECT\&.SAK" +\fIancestors\fR: \fBpractcl::subproject\fR +.PP +.PP +\fBMethods\fR +.TP +method \fBenv-bootstrap\fR +.TP +method \fBenv-install\fR +.TP +method \fBenv-present\fR +.TP +method \fBinstall\fR \fIDEST\fR +.TP +method \fBinstall-module\fR \fIDEST\fR ?\fIargs\fR? +.PP +.PP +.SS "CLASS PRACTCL::SUBPROJECT\&.PRACTCL" +\fIancestors\fR: \fBpractcl::subproject\fR +.PP +.PP +\fBMethods\fR +.TP +method \fBenv-bootstrap\fR +.TP +method \fBenv-install\fR +.TP +method \fBinstall\fR \fIDEST\fR +.TP +method \fBinstall-module\fR \fIDEST\fR ?\fIargs\fR? +.PP +.PP +.SS "CLASS PRACTCL::SUBPROJECT\&.BINARY" +\fIancestors\fR: \fBpractcl::subproject\fR +.PP +A subordinate binary package +.PP +\fBMethods\fR +.TP +method \fBclean\fR +.TP +method \fBenv-install\fR +.TP +method \fBproject-compile-products\fR +.TP +method \fBComputeInstall\fR +.TP +method \fBgo\fR +.TP +method \fBlinker-products\fR \fIconfigdict\fR +.TP +method \fBproject-static-packages\fR +.TP +method \fBBuildDir\fR \fIPWD\fR +.TP +method \fBcompile\fR +.TP +method \fBConfigure\fR +.TP +method \fBinstall\fR \fIDEST\fR +.PP +.PP +.SS "CLASS PRACTCL::SUBPROJECT\&.TEA" +\fIancestors\fR: \fBpractcl::subproject\&.binary\fR +.PP +A subordinate TEA based binary package +.PP +.SS "CLASS PRACTCL::SUBPROJECT\&.LIBRARY" +\fIancestors\fR: \fBpractcl::subproject\&.binary\fR \fBpractcl::library\fR +.PP +A subordinate C library built by this project +.PP +\fBMethods\fR +.TP +method \fBinstall\fR \fIDEST\fR +.PP +.PP +.SS "CLASS PRACTCL::SUBPROJECT\&.EXTERNAL" +\fIancestors\fR: \fBpractcl::subproject\&.binary\fR +.PP +A subordinate external C library +.PP +\fBMethods\fR +.TP +method \fBinstall\fR \fIDEST\fR +.PP +.PP +.SS "CLASS PRACTCL::SUBPROJECT\&.CORE" +\fIancestors\fR: \fBpractcl::subproject\&.binary\fR +.PP +.PP +\fBMethods\fR +.TP +method \fBenv-bootstrap\fR +.TP +method \fBenv-present\fR +.TP +method \fBenv-install\fR +.TP +method \fBgo\fR +.TP +method \fBlinktype\fR +.PP .PP .SH "BUGS, IDEAS, FEEDBACK" This document, and the package it describes, will undoubtedly contain bugs and other problems\&. Please report such in the category \fIpractcl\fR of the Index: idoc/man/files/modules/pt/pt_peg_export.n ================================================================== --- idoc/man/files/modules/pt/pt_peg_export.n +++ idoc/man/files/modules/pt/pt_peg_export.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'pt_peg_export\&.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 2009 Andreas Kupries '\" -.TH "pt::peg::export" n 1 tcllib "Parser Tools" +.TH "pt::peg::export" n 1\&.0\&.1 tcllib "Parser Tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -276,17 +276,17 @@ .SH SYNOPSIS package require \fBTcl 8\&.5\fR .sp package require \fBsnit \fR .sp -package require \fBconfiguration \fR +package require \fBstruct::map \fR .sp package require \fBpt::peg \fR .sp package require \fBpluginmgr \fR .sp -package require \fBpt::peg::export ?1?\fR +package require \fBpt::peg::export ?1\&.0\&.1?\fR .sp \fB::pt::peg::export\fR \fIobjectName\fR .sp \fBobjectName\fR \fBmethod\fR ?\fIarg arg \&.\&.\&.\fR? .sp Index: idoc/man/files/modules/pt/pt_peg_import.n ================================================================== --- idoc/man/files/modules/pt/pt_peg_import.n +++ idoc/man/files/modules/pt/pt_peg_import.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'pt_peg_import\&.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 2009 Andreas Kupries '\" -.TH "pt::peg::import" n 1 tcllib "Parser Tools" +.TH "pt::peg::import" n 1\&.0\&.1 tcllib "Parser Tools" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -274,19 +274,21 @@ .SH NAME pt::peg::import \- PEG Import .SH SYNOPSIS package require \fBTcl 8\&.5\fR .sp +package require \fBTcl 8\&.5\fR +.sp package require \fBsnit \fR .sp -package require \fBconfiguration \fR +package require \fBfileutil::paths \fR .sp package require \fBpt::peg \fR .sp package require \fBpluginmgr \fR .sp -package require \fBpt::peg::import ?1?\fR +package require \fBpt::peg::import ?1\&.0\&.1?\fR .sp \fB::pt::peg::import\fR \fIobjectName\fR .sp \fBobjectName\fR \fBmethod\fR ?\fIarg arg \&.\&.\&.\fR? .sp Index: idoc/man/files/modules/sha1/sha1.n ================================================================== --- idoc/man/files/modules/sha1/sha1.n +++ idoc/man/files/modules/sha1/sha1.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'sha1\&.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 2005, Pat Thoyts '\" -.TH "sha1" n 2\&.0\&.3 tcllib "SHA-x Message-Digest Algorithm" +.TH "sha1" n 2\&.0\&.4 tcllib "SHA-x Message-Digest Algorithm" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -274,11 +274,11 @@ .SH NAME sha1 \- SHA1 Message-Digest Algorithm .SH SYNOPSIS package require \fBTcl 8\&.2\fR .sp -package require \fBsha1 ?2\&.0\&.3?\fR +package require \fBsha1 ?2\&.0\&.4?\fR .sp \fB::sha1::sha1\fR ?\fB-hex|-bin\fR? [ \fB-channel channel\fR | \fB-file filename\fR | ?\fB--\fR? \fIstring\fR ] .sp \fB::sha1::hmac\fR \fIkey\fR \fIstring\fR .sp Index: idoc/man/files/modules/sha1/sha256.n ================================================================== --- idoc/man/files/modules/sha1/sha256.n +++ idoc/man/files/modules/sha1/sha256.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'sha256\&.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 2008, Andreas Kupries '\" -.TH "sha256" n 1\&.0\&.3 tcllib "SHA-x Message-Digest Algorithm" +.TH "sha256" n 1\&.0\&.4 tcllib "SHA-x Message-Digest Algorithm" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -274,11 +274,11 @@ .SH NAME sha256 \- SHA256 Message-Digest Algorithm .SH SYNOPSIS package require \fBTcl 8\&.2\fR .sp -package require \fBsha256 ?1\&.0\&.3?\fR +package require \fBsha256 ?1\&.0\&.4?\fR .sp \fB::sha2::sha256\fR ?\fB-hex|-bin\fR? [ \fB-channel channel\fR | \fB-file filename\fR | ?\fB--\fR? \fIstring\fR ] .sp \fB::sha2::sha224\fR ?\fB-hex|-bin\fR? [ \fB-channel channel\fR | \fB-file filename\fR | ?\fB--\fR? \fIstring\fR ] .sp Index: idoc/man/files/modules/struct/graph.n ================================================================== --- idoc/man/files/modules/struct/graph.n +++ idoc/man/files/modules/struct/graph.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'graph\&.man' by tcllib/doctools with format 'nroff' -'\" Copyright (c) 2002-2009 Andreas Kupries +'\" Copyright (c) 2002-2009,2019 Andreas Kupries '\" -.TH "struct::graph" n 2\&.4\&.1 tcllib "Tcl Data Structures" +.TH "struct::graph" n 2\&.4\&.2 tcllib "Tcl Data Structures" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -274,11 +274,11 @@ .SH NAME struct::graph \- Create and manipulate directed graph objects .SH SYNOPSIS package require \fBTcl 8\&.4\fR .sp -package require \fBstruct::graph ?2\&.4\&.1?\fR +package require \fBstruct::graph ?2\&.4\&.2?\fR .sp package require \fBstruct::list ?1\&.5?\fR .sp package require \fBstruct::set ?2\&.2\&.3?\fR .sp @@ -725,11 +725,11 @@ command can be used as well\&. The restrictions that involve connected nodes take a variable number of nodes as argument, specified after the name of the restriction itself\&. .sp The restrictions imposed by either \fB-in\fR, \fB-out\fR, -\fB-adj\fR, \fB-inner\fR, or \fB-embedded\fR are applied +\fB-adj\fR, \fB-inner\fR, or \fB-embedding\fR are applied first\&. Specifying more than one of them is illegal\&. .sp After that the restrictions set via \fB-key\fR (and \fB-value\fR) are applied\&. Specifying more than one \fB-key\fR (and \fB-value\fR) is illegal\&. Specifying \fB-value\fR alone, @@ -764,10 +764,21 @@ .TP \fB-embedding\fR Return a list of all arcs adjacent to exactly one of the nodes in the set\&. This is the set of arcs connecting the subgraph spawned by the specified nodes to the rest of the graph\&. +.RE +.IP +\fIAttention\fR: After the above options any word with a leading dash +which is not a valid option is treated as a node name instead of an +invalid option to error out on\&. This condition holds until either a +valid option terminates the list of nodes, or the end of the command +is reached, whichever comes first\&. +.sp +The remaining filter options are: +.sp +.RS .TP \fB-key\fR \fIkey\fR Limit the list of arcs that are returned to those arcs that have an associated key \fIkey\fR\&. .TP @@ -894,13 +905,17 @@ of returned nodes based on neighboring nodes, or based on the keyed values associated with the node\&. The restrictions that involve neighboring nodes have a list of nodes as argument, specified after the name of the restriction itself\&. .sp -The possible restrictions are the same as for method -\fBarcs\fR\&. The exact meanings change slightly, as they operate on -nodes instead of arcs\&. The command recognizes: +The possible restrictions are the same as for method \fBarcs\fR\&. +Note that while the exact meanings change slightly, as they operate on +nodes instead of arcs, the general behaviour is the same, especially +when it comes to the handling of words with a leading dash in node +lists\&. +.sp +The command recognizes: .RS .TP \fB-in\fR Return a list of all nodes with at least one outgoing arc ending in a node found in the specified set of nodes\&. Alternatively specified as @@ -1033,14 +1048,14 @@ # A possible serialization for the graph structure # # d -----> %2 - # / ^ \\\\ - # / / \\\\ - # / b \\\\ - # / / \\\\ + # / ^ \\ + # / / \\ + # / b \\ + # / / \\ # %1 <- a - %0 e # ^ \\\\ / # \\\\ c / # \\\\ \\\\ / # \\\\ v v @@ -1162,8 +1177,8 @@ adjacent, arc, cgraph, degree, edge, graph, loop, neighbour, node, serialization, subgraph, vertex .SH CATEGORY Data structures .SH COPYRIGHT .nf -Copyright (c) 2002-2009 Andreas Kupries +Copyright (c) 2002-2009,2019 Andreas Kupries .fi ADDED idoc/man/files/modules/struct/struct_map.n Index: idoc/man/files/modules/struct/struct_map.n ================================================================== --- /dev/null +++ idoc/man/files/modules/struct/struct_map.n @@ -0,0 +1,349 @@ +'\" +'\" Generated from file 'struct_map\&.man' by tcllib/doctools with format 'nroff' +'\" +.TH "struct::map" n 1 tcllib "" +.\" The -*- nroff -*- definitions below are for supplemental macros used +.\" in Tcl/Tk manual entries. +.\" +.\" .AP type name in/out ?indent? +.\" Start paragraph describing an argument to a library procedure. +.\" type is type of argument (int, etc.), in/out is either "in", "out", +.\" or "in/out" to describe whether procedure reads or modifies arg, +.\" and indent is equivalent to second arg of .IP (shouldn't ever be +.\" needed; use .AS below instead) +.\" +.\" .AS ?type? ?name? +.\" Give maximum sizes of arguments for setting tab stops. Type and +.\" name are examples of largest possible arguments that will be passed +.\" to .AP later. If args are omitted, default tab stops are used. +.\" +.\" .BS +.\" Start box enclosure. From here until next .BE, everything will be +.\" enclosed in one large box. +.\" +.\" .BE +.\" End of box enclosure. +.\" +.\" .CS +.\" Begin code excerpt. +.\" +.\" .CE +.\" End code excerpt. +.\" +.\" .VS ?version? ?br? +.\" Begin vertical sidebar, for use in marking newly-changed parts +.\" of man pages. The first argument is ignored and used for recording +.\" the version when the .VS was added, so that the sidebars can be +.\" found and removed when they reach a certain age. If another argument +.\" is present, then a line break is forced before starting the sidebar. +.\" +.\" .VE +.\" End of vertical sidebar. +.\" +.\" .DS +.\" Begin an indented unfilled display. +.\" +.\" .DE +.\" End of indented unfilled display. +.\" +.\" .SO ?manpage? +.\" Start of list of standard options for a Tk widget. The manpage +.\" argument defines where to look up the standard options; if +.\" omitted, defaults to "options". The options follow on successive +.\" lines, in three columns separated by tabs. +.\" +.\" .SE +.\" End of list of standard options for a Tk widget. +.\" +.\" .OP cmdName dbName dbClass +.\" Start of description of a specific option. cmdName gives the +.\" option's name as specified in the class command, dbName gives +.\" the option's name in the option database, and dbClass gives +.\" the option's class in the option database. +.\" +.\" .UL arg1 arg2 +.\" Print arg1 underlined, then print arg2 normally. +.\" +.\" .QW arg1 ?arg2? +.\" Print arg1 in quotes, then arg2 normally (for trailing punctuation). +.\" +.\" .PQ arg1 ?arg2? +.\" Print an open parenthesis, arg1 in quotes, then arg2 normally +.\" (for trailing punctuation) and then a closing parenthesis. +.\" +.\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages. +.if t .wh -1.3i ^B +.nr ^l \n(.l +.ad b +.\" # Start an argument description +.de AP +.ie !"\\$4"" .TP \\$4 +.el \{\ +. ie !"\\$2"" .TP \\n()Cu +. el .TP 15 +.\} +.ta \\n()Au \\n()Bu +.ie !"\\$3"" \{\ +\&\\$1 \\fI\\$2\\fP (\\$3) +.\".b +.\} +.el \{\ +.br +.ie !"\\$2"" \{\ +\&\\$1 \\fI\\$2\\fP +.\} +.el \{\ +\&\\fI\\$1\\fP +.\} +.\} +.. +.\" # define tabbing values for .AP +.de AS +.nr )A 10n +.if !"\\$1"" .nr )A \\w'\\$1'u+3n +.nr )B \\n()Au+15n +.\" +.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n +.nr )C \\n()Bu+\\w'(in/out)'u+2n +.. +.AS Tcl_Interp Tcl_CreateInterp in/out +.\" # BS - start boxed text +.\" # ^y = starting y location +.\" # ^b = 1 +.de BS +.br +.mk ^y +.nr ^b 1u +.if n .nf +.if n .ti 0 +.if n \l'\\n(.lu\(ul' +.if n .fi +.. +.\" # BE - end boxed text (draw box now) +.de BE +.nf +.ti 0 +.mk ^t +.ie n \l'\\n(^lu\(ul' +.el \{\ +.\" Draw four-sided box normally, but don't draw top of +.\" box if the box started on an earlier page. +.ie !\\n(^b-1 \{\ +\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.el \}\ +\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' +.\} +.\} +.fi +.br +.nr ^b 0 +.. +.\" # VS - start vertical sidebar +.\" # ^Y = starting y location +.\" # ^v = 1 (for troff; for nroff this doesn't matter) +.de VS +.if !"\\$2"" .br +.mk ^Y +.ie n 'mc \s12\(br\s0 +.el .nr ^v 1u +.. +.\" # VE - end of vertical sidebar +.de VE +.ie n 'mc +.el \{\ +.ev 2 +.nf +.ti 0 +.mk ^t +\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n' +.sp -1 +.fi +.ev +.\} +.nr ^v 0 +.. +.\" # Special macro to handle page bottom: finish off current +.\" # box/sidebar if in box/sidebar mode, then invoked standard +.\" # page bottom macro. +.de ^B +.ev 2 +'ti 0 +'nf +.mk ^t +.if \\n(^b \{\ +.\" Draw three-sided box if this is the box's first page, +.\" draw two sides but no top otherwise. +.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c +.\} +.if \\n(^v \{\ +.nr ^x \\n(^tu+1v-\\n(^Yu +\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c +.\} +.bp +'fi +.ev +.if \\n(^b \{\ +.mk ^y +.nr ^b 2 +.\} +.if \\n(^v \{\ +.mk ^Y +.\} +.. +.\" # DS - begin display +.de DS +.RS +.nf +.sp +.. +.\" # DE - end display +.de DE +.fi +.RE +.sp +.. +.\" # SO - start of list of standard options +.de SO +'ie '\\$1'' .ds So \\fBoptions\\fR +'el .ds So \\fB\\$1\\fR +.SH "STANDARD OPTIONS" +.LP +.nf +.ta 5.5c 11c +.ft B +.. +.\" # SE - end of list of standard options +.de SE +.fi +.ft R +.LP +See the \\*(So manual entry for details on the standard options. +.. +.\" # OP - start of full description for a single option +.de OP +.LP +.nf +.ta 4c +Command-Line Name: \\fB\\$1\\fR +Database Name: \\fB\\$2\\fR +Database Class: \\fB\\$3\\fR +.fi +.IP +.. +.\" # CS - begin code excerpt +.de CS +.RS +.nf +.ta .25i .5i .75i 1i +.. +.\" # CE - end code excerpt +.de CE +.fi +.RE +.. +.\" # UL - underline word +.de UL +\\$1\l'|0\(ul'\\$2 +.. +.\" # QW - apply quotation marks to word +.de QW +.ie '\\*(lq'"' ``\\$1''\\$2 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\$2 +.. +.\" # PQ - apply parens and quotation marks to word +.de PQ +.ie '\\*(lq'"' (``\\$1''\\$2)\\$3 +.\"" fix emacs highlighting +.el (\\*(lq\\$1\\*(rq\\$2)\\$3 +.. +.\" # QR - quoted range +.de QR +.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3 +.\"" fix emacs highlighting +.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3 +.. +.\" # MT - "empty" string +.de MT +.QW "" +.. +.BS +.SH NAME +struct::map \- Manage key/value maps +.SH SYNOPSIS +package require \fBstruct::map ?1?\fR +.sp +\fB::struct::map\fR \fImapName\fR +.sp +\fBmapName\fR \fBmethod\fR ?\fIarg arg \&.\&.\&.\fR? +.sp +\fImapName\fR \fBget\fR +.sp +\fImapName\fR \fBnames\fR +.sp +\fImapName\fR \fBset\fR \fIname\fR ?\fIvalue\fR? +.sp +\fImapName\fR \fBunset\fR ?\fIpattern\fR\&.\&.\&.? +.sp +.BE +.SH DESCRIPTION +Provides a snit class whose instances manage a key/value map\&. +In other words, an object wrapper around Tcl arrays\&. +.SH API +The main command provides construction of maps: +.TP +\fB::struct::map\fR \fImapName\fR +Creates a new, empty map with an associated global Tcl command whose +name is \fImapName\fR\&. +It may be used to invoke various operations on the map\&. +It has the following general form: +.RS +.TP +\fBmapName\fR \fBmethod\fR ?\fIarg arg \&.\&.\&.\fR? +\fBmethod\fR and \fIarg\fRuments determine the exact behavior of +the command\&. +.RE +.IP +If \fImapName\fR is specified as \fB%AUTO%\fR a unique name will be +generated by the package itself\&. +The result of the command is the fully-qualified name of the instance +command\&. +.PP +.PP +The following commands are possible for map objects: +.TP +\fImapName\fR \fBget\fR +Returns the entire map as a Tcl dictionary\&. +.TP +\fImapName\fR \fBnames\fR +Returns the list of all keys known to the map, in arbitrary order\&. +.TP +\fImapName\fR \fBset\fR \fIname\fR ?\fIvalue\fR? +Sets key \fIname\fR to the specified \fIvalue\fR, if the value specified\&. +Returns the value for the key\&. +Throws an error if the key is not known\&. +.TP +\fImapName\fR \fBunset\fR ?\fIpattern\fR\&.\&.\&.? +Removes all keys matching at least one of the glob \fIpattern\fRs from +the map\&. +If no pattern is specified all keys are removed\&. +In other words, the default pattern is \fB*\fR\&. +The result of the command is the empty string\&. +.PP +.SH "BUGS, IDEAS, FEEDBACK" +This document, and the package it describes, will undoubtedly contain +bugs and other problems\&. +Please report such in the category \fIstruct :: list\fR of the +\fITcllib Trackers\fR [http://core\&.tcl\&.tk/tcllib/reportlist]\&. +Please also report any ideas for enhancements you may have for either +package and/or documentation\&. +.PP +When proposing code changes, please provide \fIunified diffs\fR, +i\&.e the output of \fBdiff -u\fR\&. +.PP +Note further that \fIattachments\fR are strongly preferred over +inlined patches\&. Attachments can be made by going to the \fBEdit\fR +form of the ticket immediately after its creation, and then using the +left-most button in the secondary navigation bar\&. Index: idoc/man/files/modules/treeql/treeql.n ================================================================== --- idoc/man/files/modules/treeql/treeql.n +++ idoc/man/files/modules/treeql/treeql.n @@ -406,13 +406,13 @@ # Below we can see the same query, but rewritten # to show the structure as it is seen by the query # interpreter\&. - q query \\\\ - root \\\\ - children \\\\ + q query \\ + root \\ + children \\ get data .CE .sp The operators of the TreeQL language available for this are explained Index: idoc/man/files/modules/virtchannel_base/cat.n ================================================================== --- idoc/man/files/modules/virtchannel_base/cat.n +++ idoc/man/files/modules/virtchannel_base/cat.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'cat\&.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 2011 Andreas Kupries '\" -.TH "tcl::chan::cat" n 1 tcllib "Reflected/virtual channel support" +.TH "tcl::chan::cat" n 1\&.0\&.3 tcllib "Reflected/virtual channel support" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -278,11 +278,11 @@ .sp package require \fBTclOO \fR .sp package require \fBtcl::chan::core ?1?\fR .sp -package require \fBtcl::chan::cat ?1?\fR +package require \fBtcl::chan::cat ?1\&.0\&.3?\fR .sp \fB::tcl::chan::cat\fR \fIchan\fR\&.\&.\&. .sp .BE .SH DESCRIPTION Index: idoc/man/files/modules/zip/mkzip.n ================================================================== --- idoc/man/files/modules/zip/mkzip.n +++ idoc/man/files/modules/zip/mkzip.n @@ -1,10 +1,10 @@ '\" '\" Generated from file 'mkzip\&.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 2009 Pat Thoyts '\" -.TH "zipfile::mkzip" n 1\&.2 tcllib "Zip archive creation" +.TH "zipfile::mkzip" n 1\&.2\&.1 tcllib "Zip archive creation" .\" The -*- nroff -*- definitions below are for supplemental macros used .\" in Tcl/Tk manual entries. .\" .\" .AP type name in/out ?indent? .\" Start paragraph describing an argument to a library procedure. @@ -274,11 +274,11 @@ .SH NAME zipfile::mkzip \- Build a zip archive .SH SYNOPSIS package require \fBTcl 8\&.6\fR .sp -package require \fBzipfile::mkzip ?1\&.2?\fR +package require \fBzipfile::mkzip ?1\&.2\&.1?\fR .sp \fB::zipfile::mkzip::mkzip\fR \fIzipfile\fR ?\fB-zipkit\fR? ?\fB-runtime\fR \fIprefix\fR? ?\fB-comment\fR \fIstring\fR? ?\fB-directory\fR \fIrootpath\fR? ?\fB-exclude\fR \fIexclude\fR? ?\fB--\fR? ?\fIpath\fR\&.\&.\&.? .sp .BE .SH DESCRIPTION Index: idoc/man/index.n ================================================================== --- idoc/man/index.n +++ idoc/man/index.n @@ -1472,10 +1472,16 @@ \fBfiles/modules/doctools2base/tcl_parse\&.n\fR doctools::tcl::parse .RE TclOO .RS +.TP +\fBfiles/modules/clay/clay\&.n\fR +clay +.TP +\fBfiles/modules/httpd/httpd\&.n\fR +httpd .TP \fBfiles/modules/tool/meta\&.n\fR oo::util .TP \fBfiles/modules/ooutil/ooutil\&.n\fR @@ -1485,13 +1491,10 @@ oometa .TP \fBfiles/modules/tool/tool\&.n\fR tool .TP -\fBfiles/modules/httpd/httpd\&.n\fR -tool -.TP \fBfiles/modules/tool/tool_dict_ensemble\&.n\fR tool::dict_ensemble .RE TeX .RS @@ -1702,11 +1705,11 @@ .RE WWW .RS .TP \fBfiles/modules/httpd/httpd\&.n\fR -tool +httpd .RE XGoogleToken .RS .TP \fBfiles/modules/sasl/gtoken\&.n\fR @@ -5264,20 +5267,20 @@ http .RS .TP \fBfiles/modules/http/autoproxy\&.n\fR autoproxy +.TP +\fBfiles/modules/httpd/httpd\&.n\fR +httpd .TP \fBfiles/modules/map/map_geocode_nominatim\&.n\fR map::geocode::nominatim .TP \fBfiles/modules/map/map_slippy_fetcher\&.n\fR map::slippy::fetcher .TP -\fBfiles/modules/httpd/httpd\&.n\fR -tool -.TP \fBfiles/modules/uri/uri\&.n\fR uri .TP \fBfiles/modules/websocket/websocket\&.n\fR websocket @@ -5284,11 +5287,11 @@ .RE httpd .RS .TP \fBfiles/modules/httpd/httpd\&.n\fR -tool +httpd .RE https .RS .TP \fBfiles/modules/uri/uri\&.n\fR @@ -5296,11 +5299,11 @@ .RE httpserver .RS .TP \fBfiles/modules/httpd/httpd\&.n\fR -tool +httpd .RE huddle .RS .TP \fBfiles/modules/yaml/huddle\&.n\fR @@ -6605,10 +6608,13 @@ mathematics .RS .TP \fBfiles/modules/math/fourier\&.n\fR math::fourier +.TP +\fBfiles/modules/math/quasirandom\&.n\fR +math::quasirandom .TP \fBfiles/modules/math/statistics\&.n\fR math::statistics .RE matrices @@ -7281,10 +7287,16 @@ .RS .TP \fBfiles/modules/virtchannel_transform/vt_otp\&.n\fR tcl::transform::otp .RE +oo +.RS +.TP +\fBfiles/modules/clay/clay\&.n\fR +clay +.RE optimization .RS .TP \fBfiles/modules/math/optimize\&.n\fR math::optimize @@ -8412,10 +8424,16 @@ pt_parser_api .TP \fBfiles/modules/pt/pt_peg_op\&.n\fR pt_peg_op .RE +quasi-random +.RS +.TP +\fBfiles/modules/math/quasirandom\&.n\fR +math::quasirandom +.RE queue .RS .TP \fBfiles/modules/csv/csv\&.n\fR csv @@ -9581,16 +9599,16 @@ services .RS .TP \fBfiles/modules/ftpd/ftpd\&.n\fR ftpd +.TP +\fBfiles/modules/httpd/httpd\&.n\fR +httpd .TP \fBfiles/modules/smtpd/smtpd\&.n\fR smtpd -.TP -\fBfiles/modules/httpd/httpd\&.n\fR -tool .RE set .RS .TP \fBfiles/modules/struct/queue\&.n\fR Index: idoc/man/toc.n ================================================================== --- idoc/man/toc.n +++ idoc/man/toc.n @@ -331,10 +331,13 @@ \fIfiles/modules/cache/async\&.n\fR: Asynchronous in-memory cache .TP \fBcksum\fR \fIfiles/modules/crc/cksum\&.n\fR: Calculate a cksum(1) compatible checksum .TP +\fBclay\fR +\fIfiles/modules/clay/clay\&.n\fR: A minimalist framework for large scale OO Projects +.TP \fBclock_iso8601\fR \fIfiles/modules/clock/iso8601\&.n\fR: Parsing ISO 8601 dates/times .TP \fBclock_rfc2822\fR \fIfiles/modules/clock/rfc2822\&.n\fR: Parsing ISO 8601 dates/times @@ -622,10 +625,13 @@ \fIfiles/modules/fileutil/multi\&.n\fR: Multi-file operation, scatter/gather, standard object .TP \fBfileutil::multi::op\fR \fIfiles/modules/fileutil/multiop\&.n\fR: Multi-file operation, scatter/gather .TP +\fBfileutil::paths\fR +\fIfiles/modules/fileutil/paths\&.n\fR: Manage search path pools +.TP \fBfileutil_traverse\fR \fIfiles/modules/fileutil/traverse\&.n\fR: Iterative directory traversal .TP \fBftp\fR \fIfiles/modules/ftp/ftp\&.n\fR: Client-side tcl implementation of the ftp protocol @@ -694,10 +700,13 @@ \fIfiles/modules/html/html\&.n\fR: Procedures to generate HTML structures .TP \fBhtmlparse\fR \fIfiles/modules/htmlparse/htmlparse\&.n\fR: Procedures to parse HTML strings .TP +\fBhttpd\fR +\fIfiles/modules/httpd/httpd\&.n\fR: A TclOO and coroutine based web server +.TP \fBhuddle\fR \fIfiles/modules/yaml/huddle\&.n\fR: Create and manipulate huddle object .TP \fBident\fR \fIfiles/modules/ident/ident\&.n\fR: Ident protocol client @@ -826,10 +835,13 @@ \fIfiles/modules/math/pca\&.n\fR: Package for Principal Component Analysis .TP \fBmath::polynomials\fR \fIfiles/modules/math/polynomials\&.n\fR: Polynomial functions .TP +\fBmath::quasirandom\fR +\fIfiles/modules/math/quasirandom\&.n\fR: Quasi-random points for integration and Monte Carlo type methods +.TP \fBmath::rationalfunctions\fR \fIfiles/modules/math/rational_funcs\&.n\fR: Polynomial functions .TP \fBmath::roman\fR \fIfiles/modules/math/roman\&.n\fR: Tools for creating and manipulating roman numerals @@ -1198,10 +1210,13 @@ \fIfiles/modules/struct/graph1\&.n\fR: Create and manipulate directed graph objects .TP \fBstruct::list\fR \fIfiles/modules/struct/struct_list\&.n\fR: Procedures for manipulating lists .TP +\fBstruct::map\fR +\fIfiles/modules/struct/struct_map\&.n\fR: Manage key/value maps +.TP \fBstruct::matrix\fR \fIfiles/modules/struct/matrix\&.n\fR: Create and manipulate matrix objects .TP \fBstruct::matrix_v1\fR \fIfiles/modules/struct/matrix1\&.n\fR: Create and manipulate matrix objects @@ -1330,22 +1345,40 @@ \fIfiles/modules/virtchannel_transform/spacer\&.n\fR: Space insertation and removal .TP \fBtcl::transform::zlib\fR \fIfiles/modules/virtchannel_transform/tcllib_zlib\&.n\fR: zlib (de)compression .TP +\fBtcl_community_communication\fR +\fIfiles/devdoc/tcl_community_communication\&.n\fR: Tcl Community - Kind Communication +.TP \fBtclDES\fR \fIfiles/modules/des/tcldes\&.n\fR: Implementation of the DES and triple-DES ciphers .TP \fBtclDESjr\fR \fIfiles/modules/des/tcldesjr\&.n\fR: Implementation of the DES and triple-DES ciphers .TP \fBtcldocstrip\fR \fIfiles/apps/tcldocstrip\&.n\fR: Tcl-based Docstrip Processor .TP +\fBtcllib_devguide\fR +\fIfiles/devdoc/tcllib_devguide\&.n\fR: Tcllib - The Developer's Guide +.TP +\fBtcllib_install_guide\fR +\fIfiles/devdoc/tcllib_installer\&.n\fR: Tcllib - The Installer's Guide +.TP \fBtcllib_ip\fR \fIfiles/modules/dns/tcllib_ip\&.n\fR: IPv4 and IPv6 address manipulation .TP +\fBtcllib_license\fR +\fIfiles/devdoc/tcllib_license\&.n\fR: Tcllib - License +.TP +\fBtcllib_releasemgr\fR +\fIfiles/devdoc/tcllib_releasemgr\&.n\fR: Tcllib - The Release Manager's Guide +.TP +\fBtcllib_sources\fR +\fIfiles/devdoc/tcllib_sources\&.n\fR: Tcllib - How To Get The Sources +.TP \fBtclrep/machineparameters\fR \fIfiles/modules/math/machineparameters\&.n\fR: Compute double precision machine parameters\&. .TP \fBtepam\fR \fIfiles/modules/tepam/tepam_introduction\&.n\fR: An introduction into TEPAM, Tcl's Enhanced Procedure and Argument Manager @@ -1432,13 +1465,10 @@ \fIfiles/modules/tiff/tiff\&.n\fR: TIFF reading, writing, and querying and manipulation of meta data .TP \fBtool\fR \fIfiles/modules/tool/tool\&.n\fR: TclOO Library (TOOL) Framework .TP -\fBtool\fR -\fIfiles/modules/httpd/httpd\&.n\fR: A TclOO and coroutine based web server -.TP \fBtool::dict_ensemble\fR \fIfiles/modules/tool/tool_dict_ensemble\&.n\fR: Dictionary Tools .TP \fBtransfer::connect\fR \fIfiles/modules/transfer/connect\&.n\fR: Connection setup Index: idoc/www/index.html ================================================================== --- idoc/www/index.html +++ idoc/www/index.html @@ -1723,26 +1723,26 @@ html · htmlparse · javascript · ncgi

http - autoproxy · map::geocode::nominatim · map::slippy::fetcher · tool · uri · websocket + autoproxy · httpd · map::geocode::nominatim · map::slippy::fetcher · uri · websocket
httpd - tool + httpd
https uri
httpserver - tool + httpd
huddle huddle · yaml @@ -2273,11 +2273,11 @@ math · math::bigfloat · math::bignum · math::calculus · math::complexnumbers · math::constants · math::decimal · math::fuzzy · math::geometry · math::interpolate · math::linearalgebra · math::optimize · math::PCA · math::polynomials · math::rationalfunctions · math::special · math::trig · simulation::annealing · simulation::montecarlo · simulation::random
mathematics - math::fourier · math::statistics + math::fourier · math::quasirandom · math::statistics
matrices math::linearalgebra @@ -2622,320 +2622,330 @@ one time pad tcl::transform::otp
oo + clay +
optimization math::optimize · simulation::annealing
ordered list struct::prioqueue
otp tcl::transform::otp
outer join struct::list
Keywords: P
package csv
package indexing docstrip_util
page page_intro · page_pluginmgr · page_util_flow · page_util_norm_lemon · page_util_norm_peg · page_util_peg · page_util_quote
pager term::interact::pager
paragraph textutil · textutil::adjust
PARAM pt::peg::to::param
parameter entry form tepam · tepam::argument_dialogbox
parser doctools::idx::parse · doctools::tcl::parse · doctools::toc::parse · grammar::aycock · pt · pt::ast · pt::cparam::configuration::critcl · pt::cparam::configuration::tea · pt::json_language · pt::param · pt::pe · pt::pe::op · pt::peg · pt::peg::container · pt::peg::container::peg · pt::peg::export · pt::peg::export::container · pt::peg::export::json · pt::peg::export::peg · pt::peg::from::container · pt::peg::from::json · pt::peg::from::peg · pt::peg::import · pt::peg::import::container · pt::peg::import::json · pt::peg::import::peg · pt::peg::interp · pt::peg::to::container · pt::peg::to::cparam · pt::peg::to::json · pt::peg::to::param · pt::peg::to::peg · pt::peg::to::tclparam · pt::peg_language · pt::pegrammar · pt::pgen · pt::rde · pt::tclparam::configuration::nx · pt::tclparam::configuration::snit · pt::tclparam::configuration::tcloo · pt::util · pt_export_api · pt_import_api · pt_introduction · pt_parse_peg · pt_parser_api · pt_peg_op · xsxp
parser generator page · page_intro · page_pluginmgr · page_util_flow · page_util_norm_lemon · page_util_norm_peg · page_util_peg · page_util_quote
parsing bench::in · bibtex · doctools2idx_introduction · doctools2toc_introduction · doctools::idx · doctools::idx::import · doctools::toc · doctools::toc::import · grammar::aycock · grammar::fa · grammar::fa::dacceptor · grammar::fa::dexec · grammar::fa::op · grammar::me::cpu · grammar::me::cpu::core · grammar::me::cpu::gasm · grammar::me::tcl · grammar::me_intro · grammar::me_vm · grammar::peg · grammar::peg::interp · htmlparse · huddle · string::token::shell · yaml
parsing expression grammar::peg · grammar::peg::interp · pt · pt::ast · pt::cparam::configuration::critcl · pt::cparam::configuration::tea · pt::json_language · pt::param · pt::pe · pt::pe::op · pt::peg · pt::peg::container · pt::peg::container::peg · pt::peg::export · pt::peg::export::container · pt::peg::export::json · pt::peg::export::peg · pt::peg::from::container · pt::peg::from::json · pt::peg::from::peg · pt::peg::import · pt::peg::import::container · pt::peg::import::json · pt::peg::import::peg · pt::peg::interp · pt::peg::to::container · pt::peg::to::cparam · pt::peg::to::json · pt::peg::to::param · pt::peg::to::peg · pt::peg::to::tclparam · pt::peg_language · pt::pegrammar · pt::pgen · pt::rde · pt::tclparam::configuration::nx · pt::tclparam::configuration::snit · pt::tclparam::configuration::tcloo · pt::util · pt_export_api · pt_import_api · pt_introduction · pt_parse_peg · pt_parser_api · pt_peg_op
parsing expression grammar grammar::me_intro · grammar::peg · grammar::peg::interp · page_util_peg · pt · pt::ast · pt::cparam::configuration::critcl · pt::cparam::configuration::tea · pt::json_language · pt::param · pt::pe · pt::pe::op · pt::peg · pt::peg::container · pt::peg::container::peg · pt::peg::export · pt::peg::export::container · pt::peg::export::json · pt::peg::export::peg · pt::peg::from::container · pt::peg::from::json · pt::peg::from::peg · pt::peg::import · pt::peg::import::container · pt::peg::import::json · pt::peg::import::peg · pt::peg::interp · pt::peg::to::container · pt::peg::to::cparam · pt::peg::to::json · pt::peg::to::param · pt::peg::to::peg · pt::peg::to::tclparam · pt::peg_language · pt::pegrammar · pt::pgen · pt::rde · pt::tclparam::configuration::nx · pt::tclparam::configuration::snit · pt::tclparam::configuration::tcloo · pt::util · pt_export_api · pt_import_api · pt_introduction · pt_parse_peg · pt_parser_api · pt_peg_op
partial application lambda
partition struct::disjointset
partitioned set struct::disjointset
passive transfer::connect
password otp
patch docstrip_util
patching rcs
PCA math::PCA
PEG grammar::me_intro · page_util_norm_peg · page_util_peg · pt · pt::ast · pt::cparam::configuration::critcl · pt::cparam::configuration::tea · pt::json_language · pt::param · pt::pe · pt::pe::op · pt::peg · pt::peg::container · pt::peg::container::peg · pt::peg::export · pt::peg::export::container · pt::peg::export::json · pt::peg::export::peg · pt::peg::from::container · pt::peg::from::json · pt::peg::from::peg · pt::peg::import · pt::peg::import::container · pt::peg::import::json · pt::peg::import::peg · pt::peg::interp · pt::peg::to::container · pt::peg::to::cparam · pt::peg::to::json · pt::peg::to::param · pt::peg::to::peg · pt::peg::to::tclparam · pt::peg_language · pt::pegrammar · pt::pgen · pt::rde · pt::tclparam::configuration::nx · pt::tclparam::configuration::snit · pt::tclparam::configuration::tcloo · pt::util · pt_export_api · pt_import_api · pt_introduction · pt_parse_peg · pt_parser_api · pt_peg_op
performance bench · bench::in · bench::out::csv · bench::out::text · bench_intro · bench_lang_intro · bench_lang_spec · profiler
permutation struct::list
persistence tie · tie
phone valtype::imei
pi math::constants
plain text doctools::idx::export::text · doctools::toc::export::text
plane geometry math::geometry
plugin docidx_plugin_apiref · doctoc_plugin_apiref · doctools2idx_introduction · doctools2toc_introduction · doctools::html::cssdefaults · doctools::idx · doctools::idx::export · doctools::idx::import · doctools::nroff::man_macros · doctools::toc · doctools::toc::export · doctools::toc::import · pt::peg::export::container · pt::peg::export::json · pt::peg::export::peg · pt::peg::import::json · pt::peg::import::peg
plugin management pluginmgr
plugin search pluginmgr
png png
point math::geometry
polynomial functions math::polynomials
pool struct::pool · struct::queue
pop pop3
pop3 pop3 · pop3d · pop3d::dbox · pop3d::udb
post-order struct::tree
practcl practcl
pre-order struct::tree
prefix textutil::string · textutil::trim
prime math::numtheory
prioqueue struct::prioqueue · struct::queue
priority queue struct::prioqueue
proc lambda
procedure deleg_proc · tepam · tepam::procedure
procedure documentation tepam::doc_gen
processman processman
producer hook
profile profiler
projection mapproj
prospero uri
protocol asn · ldap · ldapx · nameserv::protocol · pop3d · pop3d::dbox · pop3d::udb
proxy autoproxy
public key cipher pki
publisher hook
push down automaton grammar::me_intro · grammar::peg · grammar::peg::interp · pt · pt::ast · pt::cparam::configuration::critcl · pt::cparam::configuration::tea · pt::json_language · pt::param · pt::pe · pt::pe::op · pt::peg · pt::peg::container · pt::peg::container::peg · pt::peg::export · pt::peg::export::container · pt::peg::export::json · pt::peg::export::peg · pt::peg::from::container · pt::peg::from::json · pt::peg::from::peg · pt::peg::import · pt::peg::import::container · pt::peg::import::json · pt::peg::import::peg · pt::peg::interp · pt::peg::to::container · pt::peg::to::cparam · pt::peg::to::json · pt::peg::to::param · pt::peg::to::peg · pt::peg::to::tclparam · pt::peg_language · pt::pegrammar · pt::pgen · pt::rde · pt::tclparam::configuration::nx · pt::tclparam::configuration::snit · pt::tclparam::configuration::tcloo · pt::util · pt_export_api · pt_import_api · pt_introduction · pt_parse_peg · pt_parser_api · pt_peg_op
Keywords: Q
quasi-random + math::quasirandom +
queue csv · htmlparse · struct::stack · transfer::copy::queue
services - ftpd · smtpd · tool + ftpd · httpd · smtpd
set struct::queue · struct::set @@ -3794,11 +3804,11 @@ csv
TclOO - oo::util · oo::util · oometa · tool · tool · tool::dict_ensemble + clay · httpd · oo::util · oo::util · oometa · tool · tool::dict_ensemble
TCLPARAM pt::peg::to::tclparam @@ -4263,11 +4273,11 @@ doctools::tcl::parse · wip
WWW - tool + httpd
www uri ADDED idoc/www/tcllib/files/devdoc/tcl_community_communication.html Index: idoc/www/tcllib/files/devdoc/tcl_community_communication.html ================================================================== --- /dev/null +++ idoc/www/tcllib/files/devdoc/tcl_community_communication.html @@ -0,0 +1,251 @@ + +tcl_community_communication - + + + + +
[ + Tcllib Home +| Main Table Of Contents +| Table Of Contents +| Keyword Index +| Categories +| Modules +| Applications + ]
+
+

tcl_community_communication(n) 1 tcllib ""

+

Name

+

tcl_community_communication - Tcl Community - Kind Communication

+
+ +

Description

+

The Tcl Community encourages contributions from anyone who wishes to +advance the development of:

+
    +
  • The Tcl Language

  • +
  • Tcl derived languages

  • +
  • Tcl related libraries

  • +
  • Tcl extensions

  • +
  • External Projects that Integrate Tcl

  • +
+

We welcome those contributions from anyone. We are blind to +gender, race, religion, cultural background, cybernetic nature, and +any other demographic characteristics, as well as personal political +views.

+

A community lives and dies by communications. And occasionally +our communications are peppered with patterns that are harsh, +unfriendly, unwelcoming and/or otherwise unkind. As a volunteer +community, we need all of the help we can get. Therefore, we ask all +contributors to make a conscious effort, in Tcl Community discussions, +to communicate in ways that are welcoming. Ways that are +friendly. Ways that are, in a word: kind.

+

These guidelines suggest specific ways to accomplish that goal.

+

Please note: for the balance of this document any reference to +"People", "Persons", "anybody" or "somebody" can refer to any sentient +being, not merely corporeal members of the species Homo Sapien.

+
+
We are a Sanctuary not a Clubhouse
+

The Tcl Community is a collective of amateurs and professionals who +code, test, and use tools. Our community is open to all. There is no +velvet rope. There is no bouncer at the door. There are no secret +handshakes. Any sentient being who enters our midst is welcome. If +someone is ever asked to leave, it is only because they are being +disruptive to the functioning of the community.

+
We Merit Ideas, Not People
+

A good idea can come from anyone, regardless of how little time they +have been with us. A bad idea can come from anyone, regardless of how +much time or how little time they have been with us. We judge a +concept by how it stands up to scrutiny of logic, implementation, and +regression testing. We don’t judge ideas based on who had the idea +first, who agrees with the idea, or who disagrees with it.

+
Treat Everyone with Respect
+

Everyone is deserving of respect and courtesy at all times.

+
Refer to people by the names they use.
+

If grammar requires you to state a gender for a person, honor their +preferences about their gender identity. If you are unsure as to the +gender of an individual, ask. If someone had to guess about your +gender and got it wrong, please correct them and do not take it +personally.

+
Do not take a harsh tone towards other participants.
+

Do not make personal attacks against anyone (participant or not.)

+

Criticize statements and actions, never people.

+
Don’t Take Things Personally
+

When in doubt, assume the best in people. A criticism of your +statements is not a personal attack on you.

+
Persons, not People
+

Stereotypes are an unhelpful tool on many accounts. They are generally +oversimplified. They are usually flat out wrong. And even if "right" +they are of absolutely no utility in determining the capabilities, +motivations, or fitness of an individual.

+

Don’t use them in Tcl Community communications.

+
Mistakes Happen
+

The human condition is a series of trials and errors. Progress is when +we get one more trial than error. Being wrong or making a mistake is +the default state of humanity. Accept the errors of your fellow +sentient beings, and be aware that you are also fallible.

+
Keep it Real
+

Please respond to what people actually say. We are all amazing +individuals, but none among us are mind readers. If you find yourself +responding to what you imagine someone is thinking, odds are you are +going to be wrong.

+

If you must criticize someone, stick to things they have +actually done. Never criticize for something you speculate they have +done. Or imagine they have done. Or something someone who shares some +attribute with them has done in the past.

+

Keep discussions about any non-Tcl subjects to what can be +stated factually and without emotion or judgement.

+
When Trouble Arises, Don’t Escalate
+

If you feel you are being personally attacked or offended, take the +high road. Punching back in a public forum will only makes things +worse. Address the matter in a private correspondence. Be +polite. Express your feelings, but note that you are expressing your +feelings. When writing, look for a way to calm matters down. And when +in doubt, sleep on your letter before pressing send. And when not in +doubt, sleep on it for another day after that.

+

If you are a spectator to a fight in progress, politely request +the two parties take the matter to a more private forum.

+
Always get the Last Word: I’m Sorry
+

If an personal argument does arise, be the first to apologize. An +apology does not concede a logical point. It merely acknowledges that +at some point the discussion left either logic, community decency, or +both. Return to the topic when cooler heads can prevail.

+
Nobody is Keeping Score
+

There is no prize for being right. There is no cost for being wrong. A +hard sell is not going to advance your idea along any more than a +logical argument. You aren’t running for office. This isn’t debate +club. If you find yourself continuing a discussion beyond where a +topic can be logically discussed, stop.

+
No Evangelizing
+

The Tcl Community is not the place to promote your chosen operating +system, political outlook, religion, marketing scheme, or economic +model. Period.

+

(And if you do bring it up, be prepared to have your chosen +topic discussed logically. And odds are, not favorably.)

+
Respect the Community
+

If the Community has come to a decision on a course of action, please +stop arguing.

+

If someone complains about how you are expressing your ideas, +listen.

+

If your words are hurting people, stop. There is no amount of +being "right" that makes up for someone leaving our midst because they +felt insulted, threatened, or ignored.

+
+

By following these guidelines, we will build our community, encourage +more contribution to our projects, and our discussions will be +friendlier and reach conclusions more easily.

+

Thank You.

+
+

Signatories

+
    +
  • Sean "the Hypnotoad" Woods

  • +
  • Andreas Kupries

  • +
+
+

Authors

+
+
Primary
+

Sean "the Hypnotoad" Woods

+
Light editing
+

Andreas Kupries

+
+
+
ADDED idoc/www/tcllib/files/devdoc/tcllib_devguide.html Index: idoc/www/tcllib/files/devdoc/tcllib_devguide.html ================================================================== --- /dev/null +++ idoc/www/tcllib/files/devdoc/tcllib_devguide.html @@ -0,0 +1,982 @@ + +tcllib_devguide - + + + + +
[ + Tcllib Home +| Main Table Of Contents +| Table Of Contents +| Keyword Index +| Categories +| Modules +| Applications + ]
+
+

tcllib_devguide(n) 1 tcllib ""

+

Name

+

tcllib_devguide - Tcllib - The Developer's Guide

+
+ +

Synopsis

+
+ +
+
+

Description

+

Welcome to Tcllib, the Tcl Standard Library. Note that Tcllib is not a +package itself. It is a collection of (semi-independent) Tcl +packages that provide utility functions useful to a large collection +of Tcl programmers.

+

This document is a guide for developers working on Tcllib, +i.e. maintainers fixing bugs, extending the collection's +functionality, etc.

+

Please read

+
    +
  1. Tcllib - How To Get The Sources and

  2. +
  3. Tcllib - The Installer's Guide

  4. +
+

first, if that was not done already.

+

Here we assume that the sources are already available in a +directory of your choice, and that you not only know how to build and +install them, but also have all the necessary requisites to actually +do so. The guide to the sources in particular also explains which +source code management system is used, where to find it, how to set it +up, etc.

+
+

Commitments

+

Contributor

+

As a contributor to Tcllib you are committing yourself to:

+
    +
  1. keep the guidelines written down in + Tcl Community - Kind Communication in your mind. + The main point to take away from there is + to be kind to each other.

  2. +
  3. Your contributions getting distributed under a BSD/MIT license. + For the details see Tcllib - License

  4. +
+

Contributions are made by entering tickets into our tracker, providing +patches, bundles or branches of code for inclusion, or posting to the +Tcllib related mailing lists.

+
+

Maintainer

+

When contributing one or more packages for full inclusion into Tcllib +you are committing yourself to

+
    +
  1. Keep the guidelines written down in + Tcl Community - Kind Communication + (as any contributor) in your mind. The main point to take away + from there is to be kind to each other.

  2. +
  3. Your packages getting distributed under a BSD/MIT license. For + the details see Tcllib - License

  4. +
  5. Maintenance of the new packages for a period of two years under + the following rules, and responsibilities:

    +
      + +
    1. A maintainer may step down after the mandatory period as + they see fit.

    2. +
    3. A maintainer may step down before the end of the + mandatory period, under the condition that a replacement + maintainer is immediately available and has agreed to + serve the remainder of the period, plus their own + mandatory period (see below).

    4. +
    5. When stepping down without a replacement maintainer + taking over the relevant packages have to be flagged as + unmaintained.

    6. +
    7. When a replacement mantainer is brought in for a package + it is (kept) marked as maintained (again).

      +

      A replacement maintainer is bound by the same rules as + the original maintainer, except that the mandatory + period of maintenance is shortened to one year.

    8. +
    9. For any unmaintained package a contributor + interested in becoming its maintainer can become so by + flagging them as maintained with their name and + contact information, committing themselves to the rules + of a replacement maintainer (see previous point).

    10. +
    11. For any already maintained package a contributor + interested in becoming a co-maintainer can become so + with the agreement of the existing maintainer(s), + committing themselves to the rules of a replacement + maintainer (see two points previous).

    12. +
    +

    The responsibilities as a maintainer include:

    +
      + +
    1. Watching Tcllib's ticket tracker for bugs, bug fixes, + and feature requests related to the new packages.

    2. +
    3. Reviewing the aforementioned tickets, rejecting or + applying them

    4. +
    5. Coordination and discussion with ticket submitter during + the development and/or application of bug fixes.

    6. +
    +
  6. +
  7. Follow the Branching and Workflow of this guide.

  8. +
+
+
+

Branching and Workflow

+

Package Dependencies

+

Regarding packages and dependencies between them Tcllib occupies a +middle position between two extremes:

+
    +
  1. On one side a strongly interdependent set of packages, usually + by a single author, for a single project. Looking at my + (Andreas Kupries) own work examples of such are + Marpa, + CRIMP, + Kinetcl, etc.

    +

    For every change the author of the project handles all the + modifications cascading from any incompatibilities it + introduced to the system.

  2. +
  3. On the other side, the world of semi-independent projects by + many different authors where authors know what packages their + own creations depend on, yet usually do not know who else + depends on them.

    +

    The best thing an author making an (incompatible) change to + their project can do is to for one announce such changes in + some way, and for two use versioning to distinguish the code + before and after the change.

    +

    The world is then responsible for adapting, be it by updating + their own projects to the new version, or by sticking to the + old.

  4. +
+

As mentioned already, Tcllib lives in the middle of that.

+

While we as maintainers cannot be aware of all users of + Tcllib's packages, and thus have to rely on the mechanisms + touched on in point 2 above for that, the dependencies between + the packages contained in Tcllib are a different matter.

+

As we are collectively responsible for the usability of Tcllib + in toto to the outside world, it behooves us to be individually + mindful even of Tcllib packages we are not directly + maintaining, when they depend on packages under our + maintainership. + This may be as simple as coordinating with the maintainers of + the affected packages. + It may also require us to choose how to adapt affected packages + which do not have maintainers, i.e. modify them to use our + changed package properly, or modify them to properly depend on + the unchanged version of our package.

+

Note that the above is not only a chore but an opportunity as + well. + Additional insight can be had by forcing ourselves to look at + our package and the planned change(s) from an outside + perspective, to consider the ramifications of our actions on + others in general, and on dependent packages in particular.

+
+

Trunk

+

The management and use of branches is an important part of working +with a Distributed Version Control System (DVCS) like +fossil.

+

For Tcllib the main branch of the collection is + trunk. In git this branch would be called + master, and this is exactly the case in the + github mirror of + Tcllib.

+

To properly support debugging each commit on this + branch has to pass the entire testsuite of the + collection. Using bisection to determine when an issue appeared + is an example of an action made easier by this constraint.

+

This is part of our collective responsibility for the usability + of Tcllib in toto to the outside world. + As fossil has no mechanism to enforce this condition + this is handled on the honor system for developers and maintainers.

+

To make the task easier Tcllib comes with a tool + ("sak.tcl") providing a number of commands in + support. These commands are explained in the following sections + of this guide.

+

While it is possible and allowed to commit directly to trunk + remember the above constraint regarding the testsuite, and the + coming notes about other possible issues with a commit.

+
+

Branches

+

Given the constraints placed on the trunk branch of the +repository it is (strongly) recommended to perform any development +going beyond trivial changes on a non-trunk branch.

+

Outside of the trunk developers are allowed to commit + intermediate broken states of their work. + Only at the end of a development cycle, when the relevant + branch is considered ready for merging, will it be necessary to + perform full the set of validations ensuring that the merge to + come will create a good commit on trunk.

+

Note that while a review from a second developer is not a + required condition for merging a branch it is recommended to + seek out such an independent opinion as a means of + cross-checking the work.

+

It also recommended to give any new branch a name which aids in + determining additional details about it. Examples of good + things to stick into a branch name would be

+
    +
  • Developer (nick)name

  • +
  • Ticket hash/reference

  • +
  • One or two keywords applicable to the work

  • +
  • ...

  • +
+

Further, while most development branches are likely quite + short-lived, no prohibitions exist against making longer-lived + branches. + Creators should however be mindful that the longer such a + branch exists without merges the more divergent they will tend + to be, with an associated increase in the effort which will + have to be spent on either merging from and merging to trunk.

+
+

Working with Branches

+

In the hope of engendering good work practices now a few example +operations which will come up with branches, and their associated +fossil command (sequences).

+
+
Awareness
+

When developing we have to keep ourselves aware of the context of our +work. On what branch are we ? What files have we changed ? What new +files are not yet known to the repository ? What has happened remotely +since we used our checkout ? +The answers to these questions become especially important when using +a long-lived checkout and coming back to it after some time away.

+

Commands to answer questions like the above are:

+
+
fossil pull
+

Get all changes done on the remote since the last pull or sync + from it. This has to be done first, before any of the commands + below.

+

Even if the commit in our checkout refers to the branch we want + right now control operations committed to the remote may have + changed that from underneath us.

+
fossil info | grep tags
+
+
fossil branch list | grep '\*'
+

Two different ways of determining the branch our checkout is + on.

+
fossil timeline
+

What have we (and others) done recently ?

+

Attention, this information is very likely outdated, the + more the longer we did not use this checkout. + Run fossil pull first to get latest information from + the remote repository of the project.

+
fossil timeline current
+

Place the commit our checkout is based on at the top of the + timeline.

+
fossil changes
+

Lists the files we have changed compared to the commit the + checkout is based on.

+
fossil extra
+

Lists the files we have in the checkout the repository does not + know about. This may be leftover chaff from our work, or + something we have forgotten to fossil add to the + repository yet.

+
+
Clean checkouts
+

Be aware of where you are (see first definition).

+

For pretty much all the operation recipes below a clean + checkout is at least desired, often required. + To check that a checkout is clean invoke

+
+    fossil changes
+    fossil extra
+
+

How to clean up when uncommitted changes of all sorts are found is +context-specific and outside of the scope of this guide.

+
Starting a new branch
+

Be aware of where you are (see first definition).

+

Ensure that you have clean checkout (see second definition). + It is required.

+

In most situations you want to be on branch trunk, and + you want to be on the latest commit for it. To get there use

+
+    fossil pull
+    fossil update trunk
+
+

If some other branch is desired as the starting point for the coming +work replace trunk in the commands above with the name of that +branch.

+

With the base line established we now have two ways of creating + the new branch, with differing (dis)advantages. + The simpler way is to

+
+    fossil branch new NAME_OF_NEW_BRANCH
+
+

and start developing. The advantage here is that you cannot forget to +create the branch. The disadvantages are that we have a branch commit +unchanged from where we branched from, and that we have to use +high-handed techniques like hiding or shunning to get rid of the +commit should we decide to abandon the work before the first actual +commit on the branch.

+

The other way of creating the branch is to start developing, +and then on the first commit use the option --branch to tell +fossil that we are starting a branch now. I.e. run

+
+    fossil commit --branch NAME_OF_NEW_BRANCH ...
+
+

where ... are any other options used to supply the commit +message, files to commit, etc.

+

The (dis)advantages are now reversed.

+

We have no superflous commit, only what is actually + developed. The work is hidden until we commit to make our first + commit.

+

We may forget to use --branch NAME_OF_NEW_BRANCH and + then have to correct that oversight via the fossil web + interface (I am currently unaware of ways of doing such from + the command line, although some magic incantantion of + fossil tag create may work).

+

It helps to keep awareness, like checking before any commit + that we are on the desired branch.

+
Merging a branch into trunk
+

Be aware of where you are (see first definition).

+

Ensure that you have clean checkout (see second definition). + In the full-blown sequence (zig-zag) it is required, due + to the merging from trunk. In the shorter sequence it is only + desired. That said, keeping the checkout clean before + any major operations is a good habit to have, in my opinion.

+

The full-blown sequencing with checks all the way is to

+
    +
  1. Validate the checkout, i.e. last commit on your branch. Run the + full test suite and other validations, fix all the issues which + have cropped up.

  2. +
  3. Merge the latest state of the trunk (see next definition).

  4. +
  5. Validate the checkout again. The incoming trunk changes may + have broken something now. Do any required fixes.

  6. +
  7. Now merge to the trunk using

    +
    +    fossil update trunk
    +    fossil merge --integrate YOUR_BRANCH
    +
    +
  8. +
  9. At this point the checkout should be in the same state as at + the end of point (3) above, because we resolved any issues with + the trunk already. Thus a simple

    +
    +    fossil commit ...
    +
    +

    should be sufficient now to commit the merge back and close the + branch (due to the --integrate we used on the merge).

    +

    The more paranoid may validate the checkout a third time before + commiting.

  10. +
+

I call this a zig-zag merge because of how the arrows + look in the timeline, from trunk to feature branch for the + first merge, and then back for the final merge.

+

A less paranoid can do what I call a simple merge, + which moves step (2) after step (4) and skips step (3) + entirely. The resulting shorter sequence is

+
    +
  1. Validate

  2. +
  3. Merge to trunk

  4. +
  5. Validate again

  6. +
  7. Commit to trunk

  8. +
+

The last step after either zig-zag or plain merge is to

+
+    fossil sync
+
+

This saves our work to the remote side, and further gives us any other +work done while we were doing our merge. It especially allows us to +check if we raced somebody else, resulting in a split trunk.

+

When that happens we should coordinate with the other developer + on who fixes the split, to ensure that we do not race each + other again.

+
Merging from trunk
+

Be aware of where you are (see first definition).

+

Ensure that you have clean checkout (see second definition). + It is required.

+

In most situations you want to import the latest commit of + branch trunk (or other origin). To get it use

+
+    fossil pull
+
+

With that done we can now import this commit into our current + branch with

+
+    fossil merge trunk
+
+

Even if fossil does not report any conflicts it is a + good idea to check that the operation has not broken the new + and/or changed functionality we are working on.

+

With the establishment of a good merge we then save the state + with

+
+    fossil commit ...
+
+

before continuing development.

+
+
+

Version numbers

+

In Tcllib all changes to a package have to come with an increment of +its version number. What part is incremented (patchlevel, minor, major +version) depends on the kind of change made. With multiple changes in +a commit the highest "wins".

+

When working in a development branch the version change can be + deferred until it is time to merge, and then has to cover all + the changes in the branch.

+

Below a list of the kinds of changes and their associated + version increments:

+
+
D - documentation
+

No increment

+
T - testsuite
+

No increment

+
B - bugfix
+

Patchlevel

+
I - implementation tweak
+

Patchlevel

+
P - performance tweak
+

Patchlevel

+
E - backward-compatible extension
+

Minor

+
API - incompatible change
+

Major

+
+

Note that a commit containing a version increment has to + mention the new version number in its commit message, as well + as the kind of change which caused it.

+

Note further that the version number of a package currently + exists in three places. An increment has to update all of them:

+
    +
  1. The package implementation.

  2. +
  3. The package index ("pkgIndex.tcl")

  4. +
  5. The package documentation.

  6. +
+

The "sak.tcl" command validate version helps + finding discrepancies between the first two. + All the other validate methods are also of interest to + any developer. Invoke it with

+
 sak.tcl help validate 
+

to see their documentation.

+
+
+

Structural Overview

+

Main Directories

+

The main directories in the Tcllib toplevel directory and of interest +to a developer are:

+
+
"modules"
+

Each child directory represents one or more packages. +In the case of the latter the packages are usually related in some +way. Examples are "base64", "math", and "struct", with +loose (base64) to strong (math) relations between the packages in the +directory.

+
"apps"
+

This directory contains all the installable applications, with their +documentation. Note that this directory is currently not split +into sub-directories.

+
"examples"
+

Each child directory "foo" contains one or more example +application for the packages in "modules/foo". These examples are +generally not polished enough to be considered for installation.

+
+
+

More Directories

+
+
"config"
+

This directory contains files supporting the Unix build system, +i.e. "configure" and "Makefile.in".

+
"devdoc"
+

This directories contains the doctools sources for the global +documentation, like this document and its sibling guides.

+
"embedded"
+

This directory contains the entire documentation formatted for +HTML and styled to properly mix into the web site generated by +fossil for the repository.

+

This is the documentation accessible from the Tcllib home +directory, represented in the repository as "embedded/index.md".

+
"idoc"
+

This directory contains the entire documentation formatted for +nroff and HTML, the latter without any styling. +This is the documentation which will be installed.

+
"support"
+

This directory contains the sources of internal packages and utilities +used in the implementation of the "installer.tcl" and +"sak.tcl" scripts/tools.

+
+
+

Top Files

+
+
"aclocal.m4"
+
+
"configure"
+
+
"configure.in"
+
+
"Makefile.in"
+

These four files comprise the Unix build system layered on top of the +"installer.tcl" script.

+
"installer.tcl"
+

The Tcl-based installation script/tool.

+
"project.shed"
+

Configuration file for Sean Wood's PracTcl +buildsystem.

+
"sak.tcl"
+

This is the main tool for developers and release managers, the +Swiss Army Knife of management operations on the collection.

+
"ChangeLog"
+

The log of changes to the global support, when the sources were held +in CVS. Not relevant any longer with the switch to the +fossil SCM.

+
"license.terms"
+

The license in plain ASCII. See also Tcllib - License for the +nicely formatted form. The text is identical.

+
"README.md"
+
+
".github/CONTRIBUTING.md"
+
+
".github/ISSUE_TEMPLATE.md"
+
+
".github/PULL_REQUEST_TEMPLATE.md"
+

These markdown-formatted documents are used and shown by the github +mirror of these sources, pointing people back to the official location +and issue trackers.

+
"DESCRIPTION.txt"
+
+
"STATUS"
+
+
"tcllib.spec"
+
+
"tcllib.tap"
+
+
"tcllib.yml"
+

????

+
+
+

File Types

+

The most common file types, by file extension, are:

+
+
".tcl"
+

Tcl code for a package, application, or example.

+
".man"
+

Doctools-formatted documentation, usually for a package.

+
".test"
+

Test suite for a package, or part of. +Based on tcltest.

+
".bench"
+

Performance benchmarks for a package, or part of. +Based on "modules/bench".

+
".pcx"
+

Syntax rules for TclDevKit's tclchecker. Using these +rules allows the checker to validate the use of commands of a Tcllib +package foo without having to scan the ".tcl" files +implementing it.

+
+
+
+

Testsuite Tooling

+

Testsuites in Tcllib are based on Tcl's standard test package +tcltest, plus utilities found in the directory +"modules/devtools"

+

Tcllib developers invoke the suites through the +test run method of the "sak.tcl" tool, with other methods +of test providing management operations, for example setting a +list of standard Tcl shells to use.

+

Invoke the testsuites of a specific module

+

Invoke either

+
  ./sak.tcl test run foo 
+

or

+
  ./sak.tcl test run modules/foo 
+

to invoke the testsuites found in a specific module "foo".

+
+

Invoke the testsuites of all modules

+

Invoke the tool without a module name, i.e.

+
  ./sak.tcl test run 
+

to invoke the testsuites of all modules.

+
+

Detailed Test Logs

+

In all the previous examples the test runner will write a combination +of progress display and testsuite log to the standard output, showing +for each module only the tests that passed or failed and how many of +each in a summary at the end.

+

To get a detailed log, it is necessary to invoke the test +runner with additional options.

+

For one:

+
+   ./sak.tcl test run --log LOG foo
+
+

While this shows the same short log on the terminal as before, it also +writes a detailed log to the file "LOG.log", and excerpts to +other files ("LOG.summary", "LOG.failures", etc.).

+

For two:

+
+  ./sak.tcl test run -v foo
+
+

This writes the detailed log to the standard output, instead of the +short log.

+

Regardless of form, the detailed log contains a list of all test +cases executed, which failed, and how they failed (expected versus +actual results).

+
+

Shell Selection

+

By default the test runner will use all the Tcl shells specified via +test add to invoke the specified testsuites, if any. If no +such are specified it will fall back to the Tcl shell used to run the +tool itself.

+

Use option --shell to explicitly specify the Tcl shell +to use, like

+
+  ./sak.tcl test run --shell /path/to/tclsh ...
+
+
+

Help

+

Invoke the tool as

+
  ./sak.tcl help test 
+

to see the detailed help for all methods of test, and the +associated options.

+
+
+

Documentation Tooling

+

The standard format used for documentation of packages and other +things in Tcllib is doctools. +Its supporting packages are a part of Tcllib, see the directories +"modules/doctools" and "modules/dtplite". The latter is +an application package, with the actual application +"apps/dtplite" a light wrapper around it.

+

Tcllib developers gain access to these through the doc +method of the "sak.tcl" tool, another (internal) wrapper around +the "modules/dtplite" application package.

+

Generate documentation for a specific module

+

Invoke either

+
  ./sak.tcl doc html foo 
+

or

+
  ./sak.tcl doc html modules/foo 
+

to generate HTML for the documentation found in the module "foo". +Instead of html any other supported format can be used here, +of course.

+

The generated formatted documentation will be placed into a +directory "doc" in the current working directory.

+
+

Generate documentation for all modules

+

Invoke the tool without a module name, i.e.

+
  ./sak.tcl doc html 
+

to generate HTML for the documentation found in all modules. +Instead of html any other supported format can be used here, +of course.

+

The generated formatted documentation will be placed into a +directory "doc" in the current working directory.

+
+

Available output formats, help

+

Invoke the tool as

+
  ./sak.tcl help doc 
+

to see the entire set of supported output formats which can be +generated.

+
+

Validation without output

+

Note the special format validate.

+

Using this value as the name of the format to generate forces +the tool to simply check that the documentation is syntactically +correct, without generating actual output.

+

Invoke it as either

+
  ./sak.tcl doc validate (modules/)foo 
+

or

+
  ./sak.tcl doc validate 
+

to either check the packages of a specific module or check all of +them.

+
+
+

Notes On Writing A Testsuite

+

While previous sections talked about running the testsuites for a +module and the packages therein, this has no meaning if the module in +question has no testsuites at all.

+

This section gives a very basic overview on possible +methodologies for writing tests and testsuites.

+

First there are "drudgery" tests. Written to check absolutely +basic assumptions which should never fail.

+

For example for a command FOO taking two arguments, three tests +calling it with zero, one, and three arguments. The basic checks that +the command fails if it has not enough arguments, or too many.

+

After that come the tests checking things based on our +knowledge of the command, about its properties and assumptions. Some +examples based on the graph operations added during Google's Summer of +Code 2009 are:

+
    +
  • The BellmanFord command in struct::graph::ops takes a + startnode as argument, and this node should be a node of + the graph. This equals one test case checking the behavior when the + specified node is not a node of the graph.

    +

    This often gives rise to code in the implementation which + explicitly checks the assumption and throws an understandable error, + instead of letting the algorithm fail later in some weird + non-deterministic way.

    +

    It is not always possible to do such checks. The graph argument + for example is just a command in itself, and while we expect + it to exhibit a certain interface, i.e. a set of sub-commands + aka methods, we cannot check that it has them, except by + actually trying to use them. That is done by the algorithm + anyway, so an explicit check is just overhead we can get by + without.

  • +
  • IIRC one of the distinguishing characteristic of either + BellmanFord and/or Johnson is that they are able to handle + negative weights. Whereas Dijkstra requires positive weights.

    +

    This induces (at least) three testcases ... Graph with all + positive weights, all negative, and a mix of positive and + negative weights. + Thinking further does the algorithm handle the weight + 0 as well ? Another test case, or several, if we mix + zero with positive and negative weights.

  • +
  • The two algorithms we are currently thinking about are about + distances between nodes, and distance can be 'Inf'inity, + i.e. nodes may not be connected. This means that good test + cases are

    +
      + +
    1. Strongly connected graph

    2. +
    3. Connected graph

    4. +
    5. Disconnected graph.

    6. +
    +

    At the extremes of strongly connected and disconnected + we have the fully connected graphs and graphs without edges, + only nodes, i.e. completely disconnected.

  • +
  • IIRC both of the algorithms take weighted arcs, and fill in a + default if arcs are left unweighted in the input graph.

    +

    This also induces three test cases:

    +
      + +
    1. Graph will all arcs with explicit weights.

    2. +
    3. Graph without weights at all.

    4. +
    5. Graph with mixture of weighted and unweighted graphs.

    6. +
    +
  • +
+

What was described above via examples is called +black-box testing. Test cases are designed and written based on +the developer's knowledge of the properties of the algorithm and its +inputs, without referencing a particular implementation.

+

Going further, a complement to black-box testing is +white-box. For this we know the implementation of the +algorithm, we look at it and design our tests cases so that they force +the code through all possible paths in the implementation. Wherever a +decision is made we have a test case forcing a specific direction of +the decision, for all possible combinations and directions. It is easy +to get a combinatorial explosion in the number of needed test-cases.

+

In practice I often hope that the black-box tests I have made +are enough to cover all the paths, obviating the need for white-box +tests.

+

The above should be enough to make it clear that writing tests +for an algorithm takes at least as much time as coding the algorithm, +and often more time. Much more time. +See for example also http://sqlite.org/testing.html, a writeup +on how the Sqlite database engine is tested. Another article of +interest might be https://www.researchgate.net/publication/298896236. +While geared to a particular numerical algorithm it still shows that +even a simple-looking algorithm can lead to an incredible number of +test cases.

+

An interesting connection is to documentation. In one +direction, the properties checked with black-box testing are exactly +the properties which should be documented in the algorithm's man +page. And conversely, the documentation of the properties of an +algorithm makes a good reference to base the black-box tests on.

+

In practice test cases and documentation often get written +together, cross-influencing each other. And the actual writing of test +cases is a mix of black and white box, possibly influencing the +implementation while writing the tests. Like writing a test for a +condition like startnode not in input graph serving as +reminder to put a check for this condition into the code.

+
+

Installation Tooling

+

A last thing to consider when adding a new package to the collection +is installation.

+

How to use the "installer.tcl" script is documented +in Tcllib - The Installer's Guide.

+

Here we document how to extend said installer so that it may +install new package(s) and/or application(s).

+

In most cases only a single file has to be modified, the +"support/installation/modules.tcl" holding one command per module +and application to install.

+

The relevant commands are:

+
+
Module name code-action doc-action example-action
+

Install the packages of module name, found in +"modules/name".

+

The code-action is responsible for installing the +packages and their index. The system currently provides

+
+
_tcl
+

Copy all ".tcl" files found in +"modules/name" into the installation.

+
_tcr
+

As _tcl, copy the ".tcl" files found in +the subdirectories of "modules/name" as well.

+
_tci
+

As _tcl, and copy the "tclIndex.tcl" file +as well.

+
_msg
+

As _tcl, and copy the subdirectory "msgs" +as well.

+
_doc
+

As _tcl, and copy the subdirectory +"mpformats" as well.

+
_tex
+

As _tcl, and copy ".tex" files as well.

+
+

The doc-action is responsible for installing the package +documentation. The system currently provides

+
+
_null
+

No documentation available, do nothing.

+
_man
+

Process the ".man" files found in +"modules/name" and install the results (nroff and/or HTML) +in the proper location, as given to the installer.

+

This is actually a fallback, normally the installer uses the +pre-made formatted documentation found under "idoc".

+
+

The example-action is responsible for installing the +examples. The system currently provides

+
+
_null
+

No examples available, do nothing.

+
_exa
+

Copy the the directory "examples/name" +recursively to the install location for examples.

+
+
Application name
+

Install the application with name, found in "apps".

+
Exclude name
+

This command signals to the installer which of the listed modules to +not install. I.e. they name the deprecated modules of Tcllib.

+
+

If, and only if the above actions are not suitable for the new +module then a second file has to be modified, +"support/installation/actions.tcl".

+

This file contains the implementations of the available +actions, and is the place where any custom action needed to handle the +special circumstances of module has to be added.

+
+
ADDED idoc/www/tcllib/files/devdoc/tcllib_installer.html Index: idoc/www/tcllib/files/devdoc/tcllib_installer.html ================================================================== --- /dev/null +++ idoc/www/tcllib/files/devdoc/tcllib_installer.html @@ -0,0 +1,392 @@ + +tcllib_install_guide - + + + + +
[ + Tcllib Home +| Main Table Of Contents +| Table Of Contents +| Keyword Index +| Categories +| Modules +| Applications + ]
+
+

tcllib_install_guide(n) 1 tcllib ""

+

Name

+

tcllib_install_guide - Tcllib - The Installer's Guide

+
+ +

Description

+

Welcome to Tcllib, the Tcl Standard Library. Note that Tcllib is not a +package itself. It is a collection of (semi-independent) Tcl +packages that provide utility functions useful to a large collection +of Tcl programmers.

+

The audience of this document is anyone wishing to build and install +the packages found in Tcllib, for either themselves, or others.

+

For developers intending to work on the packages themselves we +additionally provide

+
    +
  1. Tcllib - The Developer's Guide.

  2. +
+

Please read Tcllib - How To Get The Sources first, if that +was not done already. Here we assume that the sources are already +available in a directory of your choice.

+
+

Requisites

+

Before Tcllib can be build and used a number of requisites must be installed. +These are:

+
    +
  1. The scripting language Tcl. + For details see Tcl.

  2. +
  3. Optionally, the critcl package (C embedding) for Tcl. + For details see CriTcl.

  4. +
+

This list assumes that the machine where Tcllib is to be installed is +essentially clean. Of course, if parts of the dependencies listed +below are already installed the associated steps can be skipped. It is +still recommended to read their sections though, to validate that the +dependencies they talk about are indeed installed.

+

Tcl

+

As we are installing a number of Tcl packages and applications it +should be pretty much obvious that a working installation of Tcl +itself is needed, and I will not belabor the point.

+

Out of the many possibilities use whatever you are comfortable +with, as long as it provides at the very least Tcl 8.2, or higher. +This may be a Tcl installation provided by your operating system +distribution, from a distribution-independent vendor, or built by +yourself.

+

Note that the packages in Tcllib have begun to require +8.4, 8.5, and even 8.6. Older versions of Tcl will not be able to use +such packages. Trying to use them will result in +package not found errors, as their package index files will +not register them in versions of the core unable to use them.

+

Myself, I used (and still use) +ActiveState's +ActiveTcl 8.5 distribution during development, as I am most familiar +with it.

+

(Disclosure: I, Andreas Kupries, worked for ActiveState until 2016, maintaining ActiveTcl and TclDevKit for them).. +I am currently working for SUSE Software Canada ULC, although not in +Tcl-related areas.

+

This distribution can be found at +http://www.activestate.com/activetcl. Retrieve the archive of +ActiveTcl 8.5 (or higher) for your platform and install it as directed +by ActiveState.

+

For those wishing to build and install Tcl on their own, the +relevant sources can be found at

+
+
Tcl
+

http://core.tcl-lang.org/tcl/

+
+

together with the necessary instructions on how to build it.

+

If there are problems with building, installing, or using Tcl, +please file a ticket against Tcl, or the vendor of your +distribution, and not Tcllib.

+
+

Critcl

+

The critcl tool is an optional dependency.

+

It is only required when trying to build the C-based +accelerators for a number of packages, as explained in +Critcl & Accelerators

+

Tcllib's build system looks for it in the , +using the name critcl. This is for Unix. +On Windows on the other hand the search is more complex. First we look +for a proper application critcl.exe. When that is not found +we look for a combination of interpreter (tclkitsh.exe, +tclsh.exe) and starkit (critcl.kit, critcl) +instead. Note that the choice of starkit can be overriden via +the environment variable .

+

Tcllib requires Critcl version 2 or higher.

+

The github repository providing releases of version 2 and +higher, and the associated sources, can be found at +http://andreas-kupries.github.com/critcl.

+

Any branch of the repository can be used (if not using the +prebuild starkit or starpack), although the use of the stable branch +master is recommended.

+

At the above url is also an explanation on how to build and +install Critcl, including a list of its dependencies.

+

Its instructions will not be repeated here. If there are +problems with these directions please file a ticket against the +Critcl project, and not Tcllib.

+
+
+

Build & Installation Instructions

+

As Tcllib is mainly a bundle of packages written in pure Tcl building +it is the same as installing it. The exceptions to this have their own +subsection, Critcl & Accelerators, later on.

+

Before that however comes the standard case, differentiated by + the platforms with material differences in the instruction, i.e. + Unix-like, versus Windows.

+

Regarding the latter it should also be noted that it is + possible set up an Unix-like environment using projects + like MSYS, Cygwin, and others. In that case the + user has the choice of which instructions to follow.

+

Regardless of environment or platform, a suitable Tcl + has to be installed, and its tclsh should be placed on + the (Unix) or associated with + ".tcl" files (Windows).

+

Installing on Unix

+

For Unix-like environments Tcllib comes with the standard set +of files to make

+
+  ./configure
+  make install
+
+

a suitable way of installing it. +This is a standard non-interactive install automatically figuring out +where to place everything, i.e. packages, applications, and the +manpages.

+

To get a graphical installer invoke

+
+  ./installer.tcl
+
+

instead.

+
+

Installing on Windows

+

In a Windows environment we have the installer.tcl script to +perform installation.

+

If the desired tclsh is associated ".tcl" files + then double-clicking / opening the installer.tcl is + enough to invoke it in graphical mode. + This assumes that Tk is installed and available as well.

+

Without Tk the only way to invoke the installer are to + open a DOS window, i.e. cmd.exe, and then to invoke

+
+  ./installer.tcl
+
+

inside it.

+
+

Critcl & Accelerators

+

While the majority of Tcllib consists of packages written in pure Tcl +a number of packages also have accelerators associated with them. +These are critcl-based C packages whose use will boost the +performance of the packages using them. +These accelerators are optional, and they are not installed by +default.

+

To build the accelerators the normally optional dependency on + critcl becomes required.

+

To build and install Tcllib with the accelerators in a + Unix-like environment invoke:

+
+  ./configure
+  make critcl # This builds the shared library holding
+              # the accelerators
+  make install
+
+

The underlying tool is "sak.tcl" in the toplevel directory +of Tcllib and the command make critcl is just a wrapper around

+
+  ./sak.tcl critcl
+
+

Therefore in a Windows environment instead invoke

+
+  ./sak.tcl critcl
+  ./installer.tcl
+
+

from within a DOS window, i.e. cmd.exe.

+
+

Tooling

+

The core of Tcllib's build system is the script "installer.tcl" +found in the toplevel directory of a checkout or release.

+

The

+
+         configure ; make install
+       
+

setup available to + developers on Unix-like systems is just a wrapper around it. + To go beyond the standard embodied in the wrapper it is + necessary to directly invoke this script.

+

On Windows system using it directly is the only way to invoke + it.

+

For basic help invoke it as

+
+         ./installer.tcl -help
+       
+

This will print a short list of all the available options to + the standard output channel.

+

The commands associated with the various install targets + in the Makefile.in for Unix can be used as additional + examples on how to use this tool as well.

+

The installer can operate in GUI and CLI modes. + By default it chooses the mode automatically, based on if the + Tcl package Tk can be used or not. + The option -no-gui can be used to force CLI mode.

+

Note that it is possible to specify options on the command line + even if the installer ultimatively selects GUI mode. In that + case the hardwired defaults and the options determine the data + presented to the user for editing.

+

The installer will select a number of defaults for the + locations of packages, examples, and documentation, and also + the format of the documentation. The user can overide these + defaults in the GUI, or by specifying additional options. + The defaults depend on the platform detected (Unix/Windows) and + on the tclsh executable used to run the installer.

+

Options

+
+
-help
+

Show the list of options explained here on the standard output channel +and exit.

+
+excluded
+

Include deprecated packages in the installation.

+
-no-gui
+

Force command line operation of the installer

+
-no-wait
+

In CLI mode the installer will by default ask the user to confirm that +the chosen configuration (destination paths, things to install) is +correct before performing any action. Using this option causes the +installer to skip this query and immediately jump to installation.

+
-app-path path
+
+
-example-path path
+
+
-html-path path
+
+
-nroff-path path
+
+
-pkg-path path
+

Declare the destination paths for the applications, examples, html +documentation, nroff manpages, and packages. The defaults are derived +from the location of the tclsh used to run the installer.

+
-dry-run
+
+
-simulate
+

Run the installer without modifying the destination directories.

+
-apps
+
+
-no-apps
+
+
-examples
+
+
-no-examples
+
+
-pkgs
+
+
-no-pkgs
+
+
-html
+
+
-no-html
+
+
-nroff
+
+
-no-nroff
+

(De)activate the installation of applications, examples, packages, +html documentation, and nroff manpages.

+

Applications, examples, and packages are installed by default.

+

On Windows the html documentation is installed by default.

+

On Unix the nroff manpages are installed by default.

+
+
+
+
ADDED idoc/www/tcllib/files/devdoc/tcllib_license.html Index: idoc/www/tcllib/files/devdoc/tcllib_license.html ================================================================== --- /dev/null +++ idoc/www/tcllib/files/devdoc/tcllib_license.html @@ -0,0 +1,162 @@ + +tcllib_license - + + + + +
[ + Tcllib Home +| Main Table Of Contents +| Table Of Contents +| Keyword Index +| Categories +| Modules +| Applications + ]
+
+

tcllib_license(n) 1 tcllib ""

+

Name

+

tcllib_license - Tcllib - License

+
+ +

Description

+

Welcome to Tcllib, the Tcl Standard Library. Note that Tcllib is not a +package itself. It is a collection of (semi-independent) Tcl +packages that provide utility functions useful to a large collection +of Tcl programmers.

+

The collection is under the BSD license.

+
+

License

+

This software is copyrighted by Ajuba Solutions and other parties. +The following terms apply to all files associated with the software +unless explicitly disclaimed in individual files.

+

The authors hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, +provided that existing copyright notices are retained in all copies +and that this notice is included verbatim in any distributions. No +written agreement, license, or royalty fee is required for any of the +authorized uses. Modifications to this software may be copyrighted by +their authors and need not follow the licensing terms described here, +provided that the new terms are clearly indicated on the first page of +each file where they apply.

+

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE.

+

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND +THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE +MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

+

GOVERNMENT USE: If you are acquiring this software on behalf of the +U.S. government, the Government shall have only "Restricted Rights" in +the software and related documentation as defined in the Federal +Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you +are acquiring the software on behalf of the Department of Defense, the +software shall be classified as "Commercial Computer Software" and the +Government shall have only "Restricted Rights" as defined in Clause +252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the +authors grant the U.S. Government and others acting in its behalf +permission to use and distribute the software in accordance with the +terms specified in this license.

+
+
ADDED idoc/www/tcllib/files/devdoc/tcllib_releasemgr.html Index: idoc/www/tcllib/files/devdoc/tcllib_releasemgr.html ================================================================== --- /dev/null +++ idoc/www/tcllib/files/devdoc/tcllib_releasemgr.html @@ -0,0 +1,199 @@ + +tcllib_releasemgr - + + + + +
[ + Tcllib Home +| Main Table Of Contents +| Table Of Contents +| Keyword Index +| Categories +| Modules +| Applications + ]
+
+

tcllib_releasemgr(n) 1 tcllib ""

+

Name

+

tcllib_releasemgr - Tcllib - The Release Manager's Guide

+
+ +

Description

+

Welcome to Tcllib, the Tcl Standard Library. Note that Tcllib is not a +package itself. It is a collection of (semi-independent) Tcl +packages that provide utility functions useful to a large collection +of Tcl programmers.

+

The audience of this document is the release manager for Tcllib, their +deputies, and anybody else interested in the task of creating +an official release of Tcllib for distribution.

+

Please read Tcllib - How To Get The Sources first, if that +was not done already. Here we assume that the sources are already +available in a directory of your choice.

+
+

Tools

+

The "sak.tcl" script in the toplevel directory of a Tcllib +checkout is the one tool used by the release manager to perform its +Tasks.

+

The main commands to be used are

+
+    sak.tcl validate
+    sak.tcl test run
+    sak.tcl review
+    sak.tcl readme
+    sak.tcl localdoc
+    sak.tcl release
+
+

More detail will be provided in the explanations of the various +Tasks.

+
+

Tasks

+

Start a release candidate

+

todo: open a candidate for release

+
+

Ready the candidate

+

todo: test, validate and check that the candidate is worthy of release +fix testsuites, possibly fix packages, documentation +regenerate docs +coordinate with package maintainers wrt fixes +big thing: going over the packages, classify changes since last +release to generate a nice readme.

+
+

Make it official

+

todo: finalize release, make candidate official

+
+

Distribute the release

+

With the release made it has to be published and the world notified of +its existence.

+
    +
  1. Create a proper fossil event for the release, via + http://core.tcl-lang.org/tcllib/eventedit.

    +

    An existing event should be used as template.

  2. +
  3. Update a number of web locations:

    +
      +
    1. Home page

    2. +
    3. Downloads

    4. +
    5. Past Releases

    6. +
    7. http://www.tcl-lang.org/home/release.txt

    8. +
    9. http://www.tcl-lang.org/software/tcllib/*.tml

    10. +
    11. http://wiki.tcl-lang.org/page/Tcllib

    12. +
    +

    The first location maps to the file "embedded/index.md" in the +repository itself, as such it can edited as part of the release +process. This is where reference to the new fossil event is added, as +the new current release.

    +

    The next two locations are in the fossil tcllib wiki and +require admin or wiki write permissions for +http://core.tcl-lang.org/tcllib.

    +

    The last two locations require ssh access to +http://www.tcl-lang.org and permission to edit +files in the web area.

  4. +
  5. ***TODO*** mailing lists and other places to send notes to.

  6. +
+
+
+
ADDED idoc/www/tcllib/files/devdoc/tcllib_sources.html Index: idoc/www/tcllib/files/devdoc/tcllib_sources.html ================================================================== --- /dev/null +++ idoc/www/tcllib/files/devdoc/tcllib_sources.html @@ -0,0 +1,169 @@ + +tcllib_sources - + + + + +
[ + Tcllib Home +| Main Table Of Contents +| Table Of Contents +| Keyword Index +| Categories +| Modules +| Applications + ]
+
+

tcllib_sources(n) 1 tcllib ""

+

Name

+

tcllib_sources - Tcllib - How To Get The Sources

+
+ +

Description

+

Welcome to Tcllib, the Tcl Standard Library. Note that Tcllib is not a +package itself. It is a collection of (semi-independent) Tcl +packages that provide utility functions useful to a large collection +of Tcl programmers.

+

The audience of this document is anyone wishing to either have just a +look at Tcllib's source code, or build the packages, or to extend and +modify them.

+

For builders and developers we additionally provide

+
    +
  1. Tcllib - The Installer's Guide.

  2. +
  3. Tcllib - The Developer's Guide.

  4. +
+

respectively.

+
+

Source Location

+

The official repository for Tcllib can be found at +http://core.tcl-lang.org/tcllib

+
+

Retrieval

+

Assuming that you simply wish to look at the sources, or build a +specific revision, the easiest way of retrieving it is to:

+
    +
  1. Log into this site, as "anonymous", using the semi-random password in the captcha.

  2. +
  3. Go to the "Timeline".

  4. +
  5. Choose the revision you wish to have.

  6. +
  7. Follow its link to its detailed information page.

  8. +
  9. On that page, choose either the "ZIP" or "Tarball" link to get +a copy of this revision in the format of your choice.

  10. +
+
+

Source Code Management

+

For the curious (or a developer-to-be), the sources are managed by the +Fossil SCM. +Binaries for popular platforms can be found directly at its +download page.

+

With that tool available the full history can be retrieved via:

+
+    fossil clone  http://core.tcl-lang.org/tcllib  tcllib.fossil
+
+

followed by

+
+    mkdir tcllib
+    cd tcllib
+    fossil open ../tcllib.fossil
+
+

to get a checkout of the head of the trunk.

+
+
Index: idoc/www/tcllib/files/modules/dicttool/dicttool.html ================================================================== --- idoc/www/tcllib/files/modules/dicttool/dicttool.html +++ idoc/www/tcllib/files/modules/dicttool/dicttool.html @@ -124,10 +124,11 @@

Synopsis

  • package require Tcl 8.5
  • +
  • package require dicttool ?1.0?
  • ladd varname args
  • ldelete varname args
  • dict getnull args
  • @@ -145,11 +146,11 @@
    ladd varname args

    This command will add a new instance of each element in args to varname, but only if that element is not already present.

    ldelete varname args
    -

    This command will add a delete all instances of each element in args from varname.

    +

    This command will delete all instances of each element in args from varname.

    dict getnull args

    Operates like dict get, however if the key args does not exist, it returns an empty list instead of throwing an error.

    dict print dict

    This command will produce a string representation of dict, with each nested branch on Index: idoc/www/tcllib/files/modules/doctools/docidx_lang_intro.html ================================================================== --- idoc/www/tcllib/files/modules/doctools/docidx_lang_intro.html +++ idoc/www/tcllib/files/modules/doctools/docidx_lang_intro.html @@ -148,11 +148,11 @@ commands, continuation lines, etc. I.e.

         ... [key {markup language}] ...
     
    -  ... [manpage thefile \\
    +  ... [manpage thefile \
               {file description}] ...
     

Basic structure

The most simple document which can be written in docidx is

Index: idoc/www/tcllib/files/modules/doctools/doctoc_lang_intro.html ================================================================== --- idoc/www/tcllib/files/modules/doctools/doctoc_lang_intro.html +++ idoc/www/tcllib/files/modules/doctools/doctoc_lang_intro.html @@ -150,11 +150,11 @@ commands, continuation lines, etc. I.e.

     ... [division_start {Appendix 1}] ...
 
-  ... [item thefile \\
+  ... [item thefile \
           label {file description}] ...
 

Basic structure

The most simple document which can be written in doctoc is

Index: idoc/www/tcllib/files/modules/doctools/doctools.html ================================================================== --- idoc/www/tcllib/files/modules/doctools/doctools.html +++ idoc/www/tcllib/files/modules/doctools/doctools.html @@ -105,11 +105,11 @@ | Categories | Modules | Applications ]
-

doctools(n) 1.5.2 tcllib "Documentation tools"

+

doctools(n) 1.5.6 tcllib "Documentation tools"

Name

doctools - doctools - Processing documents

Table Of Contents

    @@ -135,11 +135,11 @@

Synopsis

  • package require Tcl 8.2
  • -
  • package require doctools ?1.5.2?
  • +
  • package require doctools ?1.5.6?
  • ::doctools::new objectName ?option value...?
  • ::doctools::help
  • ::doctools::search path
  • Index: idoc/www/tcllib/files/modules/doctools/doctools_lang_intro.html ================================================================== --- idoc/www/tcllib/files/modules/doctools/doctools_lang_intro.html +++ idoc/www/tcllib/files/modules/doctools/doctools_lang_intro.html @@ -152,11 +152,11 @@ commands, continuation lines, etc. I.e.

       ... [list_begin enumerated] ...
     
    -  ... [call [cmd foo] \\
    +  ... [call [cmd foo] \
               [arg bar]] ...
     
       ... [term {complex concept}] ...
     
    @@ -178,11 +178,11 @@ [keywords {doctools syntax}] [keywords markup] [keywords {semantic markup}] [description] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end]

    This also shows us that all doctools documents are split into two parts, the header and the body. Everything coming before [description] belongs to the header, and everything coming @@ -229,11 +229,11 @@

         [manpage_begin NAME SECTION VERSION]
         [copyright {YEAR AUTHOR}][titledesc TITLE][moddesc MODULE_TITLE]
         [require PACKAGE VERSION][require PACKAGE][description]
         [vset CATEGORY doctools]
    -[include ../doctools2base/include/feedback.inc]
    +[include ../common-text/feedback.inc]
     [manpage_end]
     

    has the same meaning as the example before.

    On the other hand, if whitespace is present it consists not only of any sequence of characters containing the space character, Index: idoc/www/tcllib/files/modules/doctools2idx/export_docidx.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2idx/export_docidx.html +++ idoc/www/tcllib/files/modules/doctools2idx/export_docidx.html @@ -91,11 +91,11 @@ } --> -


    [ Tcllib Home @@ -105,11 +105,11 @@ | Categories | Modules | Applications ]
    -

    doctools::idx::export::docidx(n) 0.1 tcllib "Documentation tools"

    +

    doctools::idx::export::docidx(n) 0.2.1 tcllib "Documentation tools"

    Name

    doctools::idx::export::docidx - docidx export plugin

    Table Of Contents

      @@ -128,11 +128,11 @@

    Synopsis

    • package require Tcl 8.4
    • -
    • package require doctools::idx::export::docidx ?0.1?
    • +
    • package require doctools::idx::export::docidx ?0.2.1?
    @@ -302,8 +302,8 @@

    Category

    Text formatter plugin

    Index: idoc/www/tcllib/files/modules/doctools2idx/idx_export.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2idx/idx_export.html +++ idoc/www/tcllib/files/modules/doctools2idx/idx_export.html @@ -91,11 +91,11 @@ } --> -
    [ Tcllib Home @@ -105,11 +105,11 @@ | Categories | Modules | Applications ]
    -

    doctools::idx::export(n) 0.2 tcllib "Documentation tools"

    +

    doctools::idx::export(n) 0.2.1 tcllib "Documentation tools"

    Name

    doctools::idx::export - Exporting keyword indices

    Table Of Contents

      @@ -133,13 +133,13 @@

    Synopsis

      -
    • package require doctools::idx::export ?0.2?
    • +
    • package require doctools::idx::export ?0.2.1?
    • package require Tcl 8.4
    • -
    • package require doctools::config
    • +
    • package require struct::map
    • package require doctools::idx::structure
    • package require snit
    • package require pluginmgr
      @@ -460,8 +460,8 @@

    Category

    Documentation tools

    Index: idoc/www/tcllib/files/modules/doctools2idx/idx_export_html.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2idx/idx_export_html.html +++ idoc/www/tcllib/files/modules/doctools2idx/idx_export_html.html @@ -91,11 +91,11 @@ } --> -
    [ Tcllib Home @@ -364,8 +364,8 @@

    Category

    Text formatter plugin

Index: idoc/www/tcllib/files/modules/doctools2idx/idx_export_json.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2idx/idx_export_json.html +++ idoc/www/tcllib/files/modules/doctools2idx/idx_export_json.html @@ -91,11 +91,11 @@ } --> -
[ Tcllib Home @@ -317,8 +317,8 @@

Category

Text formatter plugin

Index: idoc/www/tcllib/files/modules/doctools2idx/idx_export_nroff.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2idx/idx_export_nroff.html +++ idoc/www/tcllib/files/modules/doctools2idx/idx_export_nroff.html @@ -91,11 +91,11 @@ } --> -
[ Tcllib Home @@ -271,8 +271,8 @@

Category

Text formatter plugin

Index: idoc/www/tcllib/files/modules/doctools2idx/idx_export_text.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2idx/idx_export_text.html +++ idoc/www/tcllib/files/modules/doctools2idx/idx_export_text.html @@ -91,11 +91,11 @@ } --> -
[ Tcllib Home @@ -258,8 +258,8 @@

Category

Text formatter plugin

Index: idoc/www/tcllib/files/modules/doctools2idx/idx_export_wiki.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2idx/idx_export_wiki.html +++ idoc/www/tcllib/files/modules/doctools2idx/idx_export_wiki.html @@ -91,11 +91,11 @@ } --> -
[ Tcllib Home @@ -271,8 +271,8 @@

Category

Text formatter plugin

Index: idoc/www/tcllib/files/modules/doctools2idx/idx_import.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2idx/idx_import.html +++ idoc/www/tcllib/files/modules/doctools2idx/idx_import.html @@ -91,11 +91,11 @@ } --> -
[ Tcllib Home @@ -105,11 +105,11 @@ | Categories | Modules | Applications ]
-

doctools::idx::import(n) 0.2 tcllib "Documentation tools"

+

doctools::idx::import(n) 0.2.1 tcllib "Documentation tools"

Name

doctools::idx::import - Importing keyword indices

Table Of Contents

    @@ -133,13 +133,13 @@

Synopsis

    -
  • package require doctools::idx::import ?0.2?
  • +
  • package require doctools::idx::import ?0.2.1?
  • package require Tcl 8.4
  • -
  • package require doctools::config
  • +
  • package require struct::map
  • package require doctools::idx::structure
  • package require snit
  • package require pluginmgr
    @@ -519,8 +519,8 @@

Category

Documentation tools

Index: idoc/www/tcllib/files/modules/doctools2idx/idx_import_json.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2idx/idx_import_json.html +++ idoc/www/tcllib/files/modules/doctools2idx/idx_import_json.html @@ -91,11 +91,11 @@ } --> -
[ Tcllib Home @@ -105,11 +105,11 @@ | Categories | Modules | Applications ]
-

doctools::idx::import::json(n) 0.1 tcllib "Documentation tools"

+

doctools::idx::import::json(n) 0.2.1 tcllib "Documentation tools"

Name

doctools::idx::import::json - JSON import plugin

Table Of Contents

    @@ -126,12 +126,12 @@

Synopsis

    -
  • package require Tcl 8.4
  • -
  • package require doctools::idx::import::json ?0.1?
  • +
  • package require Tcl 8.5
  • +
  • package require doctools::idx::import::json ?0.2.1?
  • package require doctools::idx::structure
  • package require json
  • import string configuration
  • @@ -294,8 +294,8 @@

Category

Text formatter plugin

Index: idoc/www/tcllib/files/modules/doctools2idx/idx_introduction.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2idx/idx_introduction.html +++ idoc/www/tcllib/files/modules/doctools2idx/idx_introduction.html @@ -208,17 +208,17 @@ ~~ | ~~ doctools::idx::export ~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ doctools::idx::import | | | +---------------+-------------------------+ | +------------------+---------------+-----------------------+---------------+ | | | | | | | | | -doctools::config = | | | = doctools::include doctools::config doctools::paths +struct::map = | | | = doctools::include struct::map fileutil::paths | | | | | doctools::idx::export::<*> | | | doctools::idx::import::<*> docidx | | | docidx, json - json | | | | \\ - html | | | doctools::idx::parse \\ - nroff | | | | \\ + json | | | | \ + html | | | doctools::idx::parse \ + nroff | | | | \ wiki | | | +---------------+ json text | | | | | doctools::idx::structure | | +-------+---------------+ Index: idoc/www/tcllib/files/modules/doctools2idx/import_docidx.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2idx/import_docidx.html +++ idoc/www/tcllib/files/modules/doctools2idx/import_docidx.html @@ -91,11 +91,11 @@ } --> -
[ Tcllib Home @@ -105,11 +105,11 @@ | Categories | Modules | Applications ]
-

doctools::idx::import::docidx(n) 0.1 tcllib "Documentation tools"

+

doctools::idx::import::docidx(n) 0.2.1 tcllib "Documentation tools"

Name

doctools::idx::import::docidx - docidx import plugin

Table Of Contents

    @@ -126,12 +126,12 @@

Synopsis

    -
  • package require Tcl 8.4
  • -
  • package require doctools::idx::import::docidx ?0.1?
  • +
  • package require Tcl 8.5
  • +
  • package require doctools::idx::import::docidx ?0.2.1?
  • package require doctools::idx::parse
  • package require doctools::idx::structure
  • package require doctools::msgcat
  • package require doctools::tcl::parse
  • package require fileutil
  • @@ -271,8 +271,8 @@

Category

Text formatter plugin

Index: idoc/www/tcllib/files/modules/doctools2toc/export_doctoc.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2toc/export_doctoc.html +++ idoc/www/tcllib/files/modules/doctools2toc/export_doctoc.html @@ -91,11 +91,11 @@ } --> -
[ Tcllib Home @@ -105,11 +105,11 @@ | Categories | Modules | Applications ]
-

doctools::toc::export::doctoc(n) 0.1 tcllib "Documentation tools"

+

doctools::toc::export::doctoc(n) 0.2.1 tcllib "Documentation tools"

Name

doctools::toc::export::doctoc - doctoc export plugin

Table Of Contents

    @@ -128,11 +128,11 @@

Synopsis

  • package require Tcl 8.4
  • -
  • package require doctools::toc::export::doctoc ?0.1?
  • +
  • package require doctools::toc::export::doctoc ?0.2.1?
@@ -325,8 +325,8 @@

Category

Text formatter plugin

Index: idoc/www/tcllib/files/modules/doctools2toc/import_doctoc.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2toc/import_doctoc.html +++ idoc/www/tcllib/files/modules/doctools2toc/import_doctoc.html @@ -91,11 +91,11 @@ } --> -
[ Tcllib Home @@ -105,11 +105,11 @@ | Categories | Modules | Applications ]
-

doctools::toc::import::doctoc(n) 0.1 tcllib "Documentation tools"

+

doctools::toc::import::doctoc(n) 0.2.1 tcllib "Documentation tools"

Name

doctools::toc::import::doctoc - doctoc import plugin

Table Of Contents

    @@ -126,12 +126,12 @@

Synopsis

    -
  • package require Tcl 8.4
  • -
  • package require doctools::toc::import::doctoc ?0.1?
  • +
  • package require Tcl 8.5
  • +
  • package require doctools::toc::import::doctoc ?0.2.1?
  • package require doctools::toc::parse
  • package require doctools::toc::structure
  • package require doctools::msgcat
  • package require doctools::tcl::parse
  • package require fileutil
  • @@ -295,8 +295,8 @@

Category

Text formatter plugin

Index: idoc/www/tcllib/files/modules/doctools2toc/toc_export.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2toc/toc_export.html +++ idoc/www/tcllib/files/modules/doctools2toc/toc_export.html @@ -91,11 +91,11 @@ } --> -
[ Tcllib Home @@ -105,11 +105,11 @@ | Categories | Modules | Applications ]
-

doctools::toc::export(n) 0.2 tcllib "Documentation tools"

+

doctools::toc::export(n) 0.2.1 tcllib "Documentation tools"

Name

doctools::toc::export - Exporting tables of contents

Table Of Contents

    @@ -133,13 +133,13 @@

Synopsis

    -
  • package require doctools::toc::export ?0.2?
  • +
  • package require doctools::toc::export ?0.2.1?
  • package require Tcl 8.4
  • -
  • package require doctools::config
  • +
  • package require struct::map
  • package require doctools::toc::structure
  • package require snit
  • package require pluginmgr
    @@ -476,8 +476,8 @@

Category

Documentation tools

Index: idoc/www/tcllib/files/modules/doctools2toc/toc_export_html.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2toc/toc_export_html.html +++ idoc/www/tcllib/files/modules/doctools2toc/toc_export_html.html @@ -91,11 +91,11 @@ } --> -
[ Tcllib Home @@ -358,8 +358,8 @@

Category

Text formatter plugin

Index: idoc/www/tcllib/files/modules/doctools2toc/toc_export_json.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2toc/toc_export_json.html +++ idoc/www/tcllib/files/modules/doctools2toc/toc_export_json.html @@ -91,11 +91,11 @@ } --> -
[ Tcllib Home @@ -361,8 +361,8 @@

Category

Text formatter plugin

Index: idoc/www/tcllib/files/modules/doctools2toc/toc_export_nroff.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2toc/toc_export_nroff.html +++ idoc/www/tcllib/files/modules/doctools2toc/toc_export_nroff.html @@ -91,11 +91,11 @@ } --> -
[ Tcllib Home @@ -295,8 +295,8 @@

Category

Text formatter plugin

Index: idoc/www/tcllib/files/modules/doctools2toc/toc_export_text.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2toc/toc_export_text.html +++ idoc/www/tcllib/files/modules/doctools2toc/toc_export_text.html @@ -91,11 +91,11 @@ } --> -
[ Tcllib Home @@ -281,8 +281,8 @@

Category

Text formatter plugin

Index: idoc/www/tcllib/files/modules/doctools2toc/toc_export_wiki.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2toc/toc_export_wiki.html +++ idoc/www/tcllib/files/modules/doctools2toc/toc_export_wiki.html @@ -91,11 +91,11 @@ } --> -
[ Tcllib Home @@ -288,8 +288,8 @@

Category

Text formatter plugin

Index: idoc/www/tcllib/files/modules/doctools2toc/toc_import.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2toc/toc_import.html +++ idoc/www/tcllib/files/modules/doctools2toc/toc_import.html @@ -91,11 +91,11 @@ } --> -
[ Tcllib Home @@ -105,11 +105,11 @@ | Categories | Modules | Applications ]
-

doctools::toc::import(n) 0.2 tcllib "Documentation tools"

+

doctools::toc::import(n) 0.2.1 tcllib "Documentation tools"

Name

doctools::toc::import - Importing keyword indices

Table Of Contents

    @@ -133,13 +133,13 @@

Synopsis

    -
  • package require doctools::toc::import ?0.2?
  • +
  • package require doctools::toc::import ?0.2.1?
  • package require Tcl 8.4
  • -
  • package require doctools::config
  • +
  • package require struct::map
  • package require doctools::toc::structure
  • package require snit
  • package require pluginmgr
    @@ -537,8 +537,8 @@

Category

Documentation tools

Index: idoc/www/tcllib/files/modules/doctools2toc/toc_import_json.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2toc/toc_import_json.html +++ idoc/www/tcllib/files/modules/doctools2toc/toc_import_json.html @@ -91,11 +91,11 @@ } --> -
[ Tcllib Home @@ -105,11 +105,11 @@ | Categories | Modules | Applications ]
-

doctools::toc::import::json(n) 0.1 tcllib "Documentation tools"

+

doctools::toc::import::json(n) 0.2.1 tcllib "Documentation tools"

Name

doctools::toc::import::json - JSON import plugin

Table Of Contents

    @@ -126,12 +126,12 @@

Synopsis

    -
  • package require Tcl 8.4
  • -
  • package require doctools::toc::import::json ?0.1?
  • +
  • package require Tcl 8.5
  • +
  • package require doctools::toc::import::json ?0.2.1?
  • package require doctools::toc::structure
  • package require json
  • import string configuration
  • @@ -338,8 +338,8 @@

Category

Text formatter plugin

Index: idoc/www/tcllib/files/modules/doctools2toc/toc_introduction.html ================================================================== --- idoc/www/tcllib/files/modules/doctools2toc/toc_introduction.html +++ idoc/www/tcllib/files/modules/doctools2toc/toc_introduction.html @@ -208,17 +208,17 @@ ~~ | ~~ doctools::toc::export ~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ doctools::toc::import | | | +---------------+-------------------------+ | +------------------+---------------+-----------------------+---------------+ | | | | | | | | | -doctools::config = | | | = doctools::include doctools::config doctools::paths +struct:map = | | | = doctools::include struct::map fileutil::paths | | | | | doctools::toc::export::<*> | | | doctools::toc::import::<*> doctoc | | | doctoc, json - json | | | | \\ - html | | | doctools::toc::parse \\ - nroff | | | | \\ + json | | | | \ + html | | | doctools::toc::parse \ + nroff | | | | \ wiki | | | +---------------+ json text | | | | | doctools::toc::structure | | +-------+---------------+ Index: idoc/www/tcllib/files/modules/fileutil/multiop.html ================================================================== --- idoc/www/tcllib/files/modules/fileutil/multiop.html +++ idoc/www/tcllib/files/modules/fileutil/multiop.html @@ -383,47 +383,47 @@

EXAMPLES

The following examples assume that the variable F contains a reference to a multi-file operation object.

-    $F do copy                       \\
-	the  *.dll                    \\
-	from c:/TDK/PrivateOpenSSL/bin \\
+    $F do copy                       \
+	the  *.dll                    \
+	from c:/TDK/PrivateOpenSSL/bin \
 	to   [installdir_of tls]
 
-    $F do move      \\
-	the  *       \\
-	from /sources \\
-	into /scratch  \\
+    $F do move      \
+	the  *       \
+	from /sources \
+	into /scratch  \
 	but not *.html
     # Alternatively use 'except for *.html'.
 
-    $F do           \\
-	move         \\
-	the  index    \\
-	from /sources  \\
-	into /scratch   \\
+    $F do           \
+	move         \
+	the  index    \
+	from /sources  \
+	into /scratch   \
 	as   pkgIndex.tcl
 
-    $F do         \\
-	remove     \\
-	the *.txt  \\
+    $F do         \
+	remove     \
+	the *.txt  \
 	in /scratch
 

Note that the fact that most commands just modify the object state allows us to use more off forms as specifications instead of just nearly-natural language sentences. For example the second example in this section can re-arranged into:

-    $F do            \\
-	from /sources \\
-	into /scratch  \\
-	but not *.html \\
-	move           \\
+    $F do            \
+	from /sources \
+	into /scratch  \
+	but not *.html \
+	move           \
 	the  *
 

and the result is not only still a valid specification, but even stays relatively readable.

Further note that the information collected by the commands but, @@ -431,17 +431,17 @@ the was executed. However no other state is reset in that manner, allowing the user to avoid repetitions of unchanging information. For example the second and third examples of this section can be merged and rewritten into the equivalent:

-$F do                   \\
-    move                 \\
-    the  *                \\
-    from /sources          \\
-    into /scratch           \\
-    but not *.html not index \\
-    the  index               \\
+$F do                   \
+    move                 \
+    the  *                \
+    from /sources          \
+    into /scratch           \
+    but not *.html not index \
+    the  index               \
     as   pkgIndex.tcl
 

Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain ADDED idoc/www/tcllib/files/modules/fileutil/paths.html Index: idoc/www/tcllib/files/modules/fileutil/paths.html ================================================================== --- /dev/null +++ idoc/www/tcllib/files/modules/fileutil/paths.html @@ -0,0 +1,190 @@ + +fileutil::paths - + + + + +


[ + Tcllib Home +| Main Table Of Contents +| Table Of Contents +| Keyword Index +| Categories +| Modules +| Applications + ]
+
+

fileutil::paths(n) 1 tcllib ""

+

Name

+

fileutil::paths - Manage search path pools

+
+ +

Synopsis

+
+
    +
  • package require Tcl 8.4
  • +
  • package require fileutil::paths ?1?
  • +
+ +
+
+

Description

+

Provides a snit class whose instances manage a pool of (search) paths.

+
+

API

+

The main command provides construction of search path pools:

+
+
::fileutil::paths poolName
+

Creates a new, empty pool of search paths with an associated global +Tcl command whose name is poolName. +It may be used to invoke various operations on the pool. +It has the following general form:

+
+
poolName method ?arg arg ...?
+

method and arguments determine the exact behavior of +the command.

+
+

If poolName is specified as %AUTO% a unique name will be +generated by the package itself. +The result of the command is the fully-qualified name of the instance +command.

+
+

The following commands are possible for pool objects:

+
+
poolName add path
+

Adds the path to the pool. +Nothing is done if the path is already known to the pool. +The result of the command is the empty string.

+
poolName clear
+

Clears the entire pool. In other words, removes all paths from it. +The result of the command is the empty string.

+
poolName paths
+

Returns the list of all paths known to the pool, in the order they +were added.

+
poolName remove path
+

Removes the path from the pool, if it is known to the pool. +Unknown paths are ignored without error. +The result of the command is the empty string.

+
+
+

Bugs, Ideas, Feedback

+

This document, and the package it describes, will undoubtedly contain +bugs and other problems. +Please report such in the category fileutil 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.

+
+
Index: idoc/www/tcllib/files/modules/grammar_fa/fa.html ================================================================== --- idoc/www/tcllib/files/modules/grammar_fa/fa.html +++ idoc/www/tcllib/files/modules/grammar_fa/fa.html @@ -311,15 +311,15 @@ Drive -- yellow --> Brake -- red --> (Stop) -- red/yellow --> Attention -- green --> Drive (...) is the start state.

a possible serialization is

-    grammar::fa \\
-    {yellow red green red/yellow} \\
-    {Drive     {0 0 {yellow     Brake}} \\
-     Brake     {0 0 {red        Stop}} \\
-     Stop      {1 0 {red/yellow Attention}} \\
+    grammar::fa \
+    {yellow red green red/yellow} \
+    {Drive     {0 0 {yellow     Brake}} \
+     Brake     {0 0 {red        Stop}} \
+     Stop      {1 0 {red/yellow Attention}} \
      Attention {0 0 {green      Drive}}}
 

A possible one, because I did not care about creation order here

faName deserialize serialization

This is the complement to serialize. It replaces the Index: idoc/www/tcllib/files/modules/grammar_peg/peg.html ================================================================== --- idoc/www/tcllib/files/modules/grammar_peg/peg.html +++ idoc/www/tcllib/files/modules/grammar_peg/peg.html @@ -348,24 +348,24 @@ AddOp <- '+'/'-' Term <- Number

a possible serialization is

-    grammar::peg \\
-    {Expression {/ {x ( Expression )} {x Factor {* {x MulOp Factor}}}} \\
-     Factor     {x Term {* {x AddOp Term}}} \\
-     Term       Number \\
-     MulOp      {/ * /} \\
-     AddOp      {/ + -} \\
-     Number     {x {? Sign} {+ Digit}} \\
-     Sign       {/ + -} \\
-     Digit      {/ 0 1 2 3 4 5 6 7 8 9} \\
-    } \\
-    {Expression value     Factor     value \\
-     Term       value     MulOp      value \\
-     AddOp      value     Number     value \\
-     Sign       value     Digit      value \\
+    grammar::peg \
+    {Expression {/ {x ( Expression )} {x Factor {* {x MulOp Factor}}}} \
+     Factor     {x Term {* {x AddOp Term}}} \
+     Term       Number \
+     MulOp      {/ * /} \
+     AddOp      {/ + -} \
+     Number     {x {? Sign} {+ Digit}} \
+     Sign       {/ + -} \
+     Digit      {/ 0 1 2 3 4 5 6 7 8 9} \
+    } \
+    {Expression value     Factor     value \
+     Term       value     MulOp      value \
+     AddOp      value     Number     value \
+     Sign       value     Digit      value \
     }
     Expression
 

A possible one, because the order of the nonterminals in the dictionary is not relevant.

Index: idoc/www/tcllib/files/modules/httpd/httpd.html ================================================================== --- idoc/www/tcllib/files/modules/httpd/httpd.html +++ idoc/www/tcllib/files/modules/httpd/httpd.html @@ -1,7 +1,7 @@ -tool - Tcl Web Server +httpd - Tcl Web Server + + + +
[ + Tcllib Home +| Main Table Of Contents +| Table Of Contents +| Keyword Index +| Categories +| Modules +| Applications + ]
+
+

math::quasirandom(n) 1 tcllib "Tcl Math Library"

+

Name

+

math::quasirandom - Quasi-random points for integration and Monte Carlo type methods

+
+ +

Synopsis

+
+
    +
  • package require Tcl 8.5
  • +
  • package require TclOO
  • +
  • package require math::quasirandom 1
  • +
+ +
+
+

Description

+

In many applications pseudo-random numbers and pseudo-random points in a (limited) +sample space play an important role. For instance in any type of Monte Carlo simulation. +Pseudo-random numbers, however, may be too random and as a consequence a large +number of data points is required to reduce the error or fluctuation in the results +to the desired value.

+

Quasi-random numbers can be used as an alternative: instead of "completely" arbitrary +points, points are generated that are diverse enough to cover the entire sample space +in a more or less uniform way. As a consequence convergence to the limit can be +much faster, when such quasi-random numbers are well-chosen.

+

The package defines a class "qrpoint" that creates a command to generate +quasi-random points in 1, 2 or more dimensions. The command can either generate +separate points, so that they can be used in a user-defined algorithm or use these +points to calculate integrals of functions defined over 1, 2 or more dimensions. +It also holds several other common algorithms. (NOTE: these are not implemented yet)

+

One particular characteristic of the generators is that there are no tuning parameters +involved, which makes the use particularly simple.

+
+

COMMANDS

+

A quasi-random point generator is created using the qrpoint class:

+
+
::math::quasirandom::qrpoint create NAME DIM ?ARGS?
+

This command takes the following arguments:

+
+
string NAME
+

The name of the command to be created (alternatively: the new subcommand +will generate a unique name)

+
integer/string DIM
+

The number of dimensions or one of: "circle", "disk", "sphere" or "ball"

+
strings ARGS
+

Zero or more key-value pairs. The supported options are:

+
    +
  • -start index: The index for the next point to be generated (default: 1)

  • +
  • -evaluations number: The number of evaluations to be used by default (default: 100)

  • +
+
+
+

The points that are returned lie in the hyperblock [0,1[^n (n the number of dimensions) +or on the unit circle, within the unit disk, on the unit sphere or within the unit ball.

+

Each generator supports the following subcommands:

+
+
gen next
+

Return the coordinates of the next quasi-random point

+
gen set-start index
+

Reset the index for the next quasi-random point. This is useful to control which list of points is returned. +Returns the new or the current value, if no value is given.

+
gen set-evaluations number
+

Reset the default number of evaluations in compound algorithms. Note that the actual number is the +smallest 4-fold larger or equal to the given number. (The 4-fold plays a role in the detailed integration +routine.)

+
gen integral func minmax args
+

Calculate the integral of the given function over the block (or the circle, sphere etc.)

+
+
string func
+

The name of the function to be integrated

+
list minmax
+

List of pairs of minimum and maximum coordinates. This can be used to +map the quasi-random coordinates to the desired hyper-block.

+

If the space is a circle, disk etc. then this argument should be a single value, the radius. +The circle, disk, etc. is centred at the origin. If this is not what is required, then a coordinate +transformation should be made within the function.

+
strings args
+

Zero or more key-value pairs. The following options are supported:

+
    +
  • -evaluations number: The number of evaluations to be used. If not specified use the +default of the generator object.

  • +
+
+
+
+

TODO

+

Implement other algorithms and variants

+

Implement more unit tests.

+

Comparison to pseudo-random numbers for integration.

+
+

References

+

Various algorithms exist for generating quasi-random numbers. The generators created in this package are based on: +http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/

+
+ +

Category

+

Mathematics

+
+
Index: idoc/www/tcllib/files/modules/mime/mime.html ================================================================== --- idoc/www/tcllib/files/modules/mime/mime.html +++ idoc/www/tcllib/files/modules/mime/mime.html @@ -105,11 +105,11 @@ | Categories | Modules | Applications ]
-

mime(n) 1.6 tcllib "Mime"

+

mime(n) 1.6.1 tcllib "Mime"

Name

mime - Manipulation of MIME body parts

Table Of Contents

    @@ -126,11 +126,11 @@

Synopsis

  • package require Tcl 8.5
  • -
  • package require mime ?1.6?
  • +
  • package require mime ?1.6.1?
cksum Calculate a cksum(1) compatible checksum
clayA minimalist framework for large scale OO Projects
clock_iso8601 Parsing ISO 8601 dates/times
clock_rfc2822 Parsing ISO 8601 dates/times
cmdline Procedures to process command lines and options.
comm A remote communication facility for Tcl (8.3 and later)
comm_wire The comm wire protocol
control Procedures for control flow structures.
coroutine Coroutine based event and IO handling
coroutine::auto Automatic event and IO coroutine awareness
counter Procedures for counters and histograms
crc16 Perform a 16bit Cyclic Redundancy Check
crc32 Perform a 32bit Cyclic Redundancy Check
cron Tool for automating the period callback of commands
csv Procedures to handle CSV data.
debug debug narrative - core
debug::caller debug narrative - caller
debug::heartbeat debug narrative - heartbeat
debug::timestamp debug narrative - timestamping
defer Defered execution
deleg_method Creation of comm delegates (snit methods)
deleg_proc Creation of comm delegates (procedures)
des Implementation of the DES and triple-DES ciphers
dicttool Dictionary Tools
dns Tcl Domain Name Service Client
docidx_intro docidx introduction
docidx_lang_cmdref docidx language command reference
docidx_lang_faq docidx language faq
docidx_lang_intro docidx language introduction
docidx_lang_syntax docidx language syntax
docidx_plugin_apiref docidx plugin API reference
docstrip Docstrip style source code extraction
docstrip_util Docstrip-related utilities
doctoc_intro doctoc introduction
doctoc_lang_cmdref doctoc language command reference
doctoc_lang_faq doctoc language faq
doctoc_lang_intro doctoc language introduction
doctoc_lang_syntax doctoc language syntax
doctoc_plugin_apiref doctoc plugin API reference
doctools doctools - Processing documents
doctools2idx_introduction DocTools - Keyword indices
doctools2toc_introduction DocTools - Tables of Contents
doctools::changelog Processing text in Emacs ChangeLog format
doctools::cvs Processing text in 'cvs log' format
doctools::html::cssdefaults Default CSS style for HTML export plugins
doctools::idx docidx - Processing indices
doctools::idx Holding keyword indices
doctools::idx::export Exporting keyword indices
doctools::idx::export::docidx docidx export plugin
doctools::idx::export::html HTML export plugin
doctools::idx::export::json JSON export plugin
doctools::idx::export::nroff nroff export plugin
doctools::idx::export::text plain text export plugin
doctools::idx::export::wiki wiki export plugin
doctools::idx::import Importing keyword indices
doctools::idx::import::docidx docidx import plugin
doctools::idx::import::json JSON import plugin
doctools::idx::parse Parsing text in docidx format
doctools::idx::structure Docidx serialization utilities
doctools::msgcat Message catalog management for the various document parsers
doctools::msgcat::idx::c Message catalog for the docidx parser (C)
doctools::msgcat::idx::de Message catalog for the docidx parser (DE)
doctools::msgcat::idx::en Message catalog for the docidx parser (EN)
doctools::msgcat::idx::fr Message catalog for the docidx parser (FR)
doctools::msgcat::toc::c Message catalog for the doctoc parser (C)
doctools::msgcat::toc::de Message catalog for the doctoc parser (DE)
doctools::msgcat::toc::en Message catalog for the doctoc parser (EN)
doctools::msgcat::toc::fr Message catalog for the doctoc parser (FR)
doctools::nroff::man_macros Default CSS style for NROFF export plugins
doctools::tcl::parse Processing text in 'subst -novariables' format
doctools::toc Holding tables of contents
doctools::toc doctoc - Processing tables of contents
doctools::toc::export Exporting tables of contents
doctools::toc::export::doctoc doctoc export plugin
doctools::toc::export::html HTML export plugin
doctools::toc::export::json JSON export plugin
doctools::toc::export::nroff nroff export plugin
doctools::toc::export::text plain text export plugin
doctools::toc::export::wiki wiki export plugin
doctools::toc::import Importing keyword indices
doctools::toc::import::doctoc doctoc import plugin
doctools::toc::import::json JSON import plugin
doctools::toc::parse Parsing text in doctoc format
doctools::toc::structure Doctoc serialization utilities
doctools_intro doctools introduction
doctools_lang_cmdref doctools language command reference
doctools_lang_faq doctools language faq
doctools_lang_intro doctools language introduction
doctools_lang_syntax doctools language syntax
doctools_plugin_apiref doctools plugin API reference
dtplite Lightweight DocTools Markup Processor
dtplite Lightweight DocTools Markup Processor
fileutil Procedures implementing some file utilities
fileutil::magic::cfront Generator core for compiler of magic(5) files
fileutil::magic::cgen Generator core for compiler of magic(5) files
fileutil::magic::filetype Procedures implementing file-type recognition
fileutil::magic::rt Runtime core for file type recognition engines written in pure Tcl
fileutil::multi Multi-file operation, scatter/gather, standard object
fileutil::multi::op Multi-file operation, scatter/gather
fileutil::pathsManage search path pools
fileutil_traverse Iterative directory traversal
htmlparse Procedures to parse HTML strings
httpdA TclOO and coroutine based web server
huddle Create and manipulate huddle object
ident Ident protocol client
imap4 imap client-side tcl implementation of imap protocol
inifile Parsing of Windows INI files
interp Interp creation and aliasing
irc Create IRC connection and interface.
javascript Procedures to generate HTML and Java Script structures.
jpeg JPEG querying and manipulation of meta data
json JSON parser
json::write JSON generation
lambda Utility commands for anonymous procedures
lazyset Lazy evaluation
ldap LDAP client
ldapx LDAP extended object interface
log Procedures to log messages of libraries and applications.
logger System to control logging of events.
logger::appender Collection of predefined appenders for logger
logger::utils Utilities for logger
map::geocode::nominatim Resolving geographical names with a Nominatim service
map::slippy Common code for slippy based map packages
map::slippy::cache Management of a tile cache in the local filesystem
map::slippy::fetcher Accessing a server providing tiles for slippy-based maps
mapproj Map projection routines
markdown Converts Markdown text to HTML
math Tcl Math Library
math::bigfloat Arbitrary precision floating-point numbers
math::bignum Arbitrary precision integer numbers
math::calculus Integration and ordinary differential equations
math::calculus::romberg Romberg integration
math::calculus::symdiff Symbolic differentiation for Tcl
math::combinatorics Combinatorial functions in the Tcl Math Library
math::complexnumbers Straightforward complex number package
math::constants Mathematical and numerical constants
math::decimal General decimal arithmetic
math::exact Exact Real Arithmetic
math::fourier Discrete and fast fourier transforms
math::fuzzy Fuzzy comparison of floating-point numbers
math::geometry Geometrical computations
math::interpolate Interpolation routines
math::linearalgebra Linear Algebra
math::numtheory Number Theory
math::optimize Optimisation routines
math::PCA Package for Principal Component Analysis
math::polynomials Polynomial functions
math::quasirandomQuasi-random points for integration and Monte Carlo type methods
math::rationalfunctions Polynomial functions
struct::list Procedures for manipulating lists
struct::mapManage key/value maps
struct::matrix Create and manipulate matrix objects
struct::matrix_v1 Create and manipulate matrix objects
struct::pool Create and manipulate pool objects (of discrete items)
struct::prioqueue Create and manipulate prioqueue objects
struct::queue Create and manipulate queue objects
struct::record Define and create records (similar to 'C' structures)
struct::set Procedures for manipulating sets
struct::skiplist Create and manipulate skiplists
struct::stack Create and manipulate stack objects
struct::tree Create and manipulate tree objects
struct::tree_v1 Create and manipulate tree objects
sum Calculate a sum(1) compatible checksum
switched switch/option management.
tar Tar file creation, extraction & manipulation
tcl::chan::cat Concatenation channel
tcl::chan::core Basic reflected/virtual channel support
tcl::chan::events Event support for reflected/virtual channels
tcl::chan::facade Facade channel
tcl::chan::fifo In-memory fifo channel
tcl::chan::fifo2 In-memory interconnected fifo channels
tcl::chan::halfpipe In-memory channel, half of a fifo2
tcl::chan::memchan In-memory channel
tcl::chan::null Null channel
tcl::chan::nullzero Null/Zero channel combination
tcl::chan::random Random channel
tcl::chan::std Standard I/O, unification of stdin and stdout
tcl::chan::string Read-only in-memory channel
tcl::chan::textwindow Textwindow channel
tcl::chan::variable In-memory channel using variable for storage
tcl::chan::zero Zero channel
tcl::randomseed Utilities for random channels
tcl::transform::adler32 Adler32 transformation
tcl::transform::base64 Base64 encoding transformation
tcl::transform::core Basic reflected/virtual channel transform support
tcl::transform::counter Counter transformation
tcl::transform::crc32 Crc32 transformation
tcl::transform::hex Hexadecimal encoding transformation
tcl::transform::identity Identity transformation
tcl::transform::limitsize limiting input
tcl::transform::observe Observer transformation, stream copy
tcl::transform::otp Encryption via one-time pad
tcl::transform::rot rot-encryption
tcl::transform::spacer Space insertation and removal
tcl::transform::zlib zlib (de)compression
tcl_community_communicationTcl Community - Kind Communication
tclDES Implementation of the DES and triple-DES ciphers
tcldocstrip Tcl-based Docstrip Processor
tcllib_devguideTcllib - The Developer's Guide
tcllib_install_guideTcllib - The Installer's Guide
tcllib_ip IPv4 and IPv6 address manipulation
tcllib_licenseTcllib - License
tcllib_releasemgrTcllib - The Release Manager's Guide
tcllib_sourcesTcllib - How To Get The Sources
tclrep/machineparameters Compute double precision machine parameters.
tepam An introduction into TEPAM, Tcl's Enhanced Procedure and Argument Manager
tepam::argument_dialogbox TEPAM argument_dialogbox, reference manual
tepam::doc_gen TEPAM DOC Generation, reference manual
tepam::procedure TEPAM procedure, reference manual
term General terminal control
term::ansi::code Helper for control sequences
term::ansi::code::attr ANSI attribute sequences
term::ansi::code::ctrl ANSI control sequences
term::ansi::code::macros Macro sequences
term::ansi::ctrl::unix Control operations and queries
term::ansi::send Output of ANSI control sequences to terminals
term::interact::menu Terminal widget, menu
term::interact::pager Terminal widget, paging
term::receive General input from terminals
term::receive::bind Keyboard dispatch from terminals
term::send General output to terminals
textutil Procedures to manipulate texts and strings.
textutil::adjust Procedures to adjust, indent, and undent paragraphs
textutil::expander Procedures to process templates and expand text.
textutil::repeat Procedures to repeat strings.
textutil::split Procedures to split texts
textutil::string Procedures to manipulate texts and strings.
textutil::tabify Procedures to (un)tabify strings
textutil::trim Procedures to trim strings
throw throw - Throw an error exception with a message
tie Array persistence, standard data sources
tie Array persistence
tiff TIFF reading, writing, and querying and manipulation of meta data
toolA TclOO and coroutine based web server
tool TclOO Library (TOOL) Framework
math::polynomials Polynomial functions
math::quasirandomQuasi-random points for integration and Monte Carlo type methods
math::rationalfunctions Polynomial functions
math::roman Tools for creating and manipulating roman numerals
math::special Special mathematical functions
math::statistics Basic statistical functions and procedures
math::trig Trigonometric anf hyperbolic functions
simulation::annealing Simulated annealing
simulation::montecarlo Monte Carlo simulations
simulation::random Pseudo-random number generators
Networking
@@ -860,13 +864,21 @@ ftpd Tcl FTP server implementation +httpd +A TclOO and coroutine based web server + + ident Ident protocol client + +imap4 +imap client-side tcl implementation of imap protocol + irc Create IRC connection and interface. @@ -980,26 +992,22 @@ tcllib_ip IPv4 and IPv6 address manipulation -tool -A TclOO and coroutine based web server - - udpcluster UDP Peer-to-Peer cluster - + uri URI utilities - + uri_urn URI utilities, URN scheme - + websocket Tcl implementation of the websocket protocol
Page Parser Generator
@@ -1224,130 +1232,134 @@
Programming tools
+ + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
clayA minimalist framework for large scale OO Projects
cmdline Procedures to process command lines and options.
comm A remote communication facility for Tcl (8.3 and later)
comm_wire The comm wire protocol
control Procedures for control flow structures.
deleg_method Creation of comm delegates (snit methods)
deleg_proc Creation of comm delegates (procedures)
fileutil Procedures implementing some file utilities
fileutil::magic::cfront Generator core for compiler of magic(5) files
fileutil::magic::cgen Generator core for compiler of magic(5) files
fileutil::magic::filetype Procedures implementing file-type recognition
fileutil::magic::rt Runtime core for file type recognition engines written in pure Tcl
fileutil::multi Multi-file operation, scatter/gather, standard object
fileutil::multi::op Multi-file operation, scatter/gather
fileutil_traverse Iterative directory traversal
hook Hooks
interp Interp creation and aliasing
log Procedures to log messages of libraries and applications.
logger System to control logging of events.
logger::appender Collection of predefined appenders for logger
logger::utils Utilities for logger
multiplexer One-to-many communication with sockets.
pluginmgr Manage a plugin
profiler Tcl source code profiler
snit Snit's Not Incr Tcl
snitfaq Snit Frequently Asked Questions
stooop Object oriented extension.
switched switch/option management.
tie Array persistence
tie Array persistence, standard data sources
uevent User events
wip Word Interpreter
System
@@ -1641,21 +1653,21 @@ cache::async Asynchronous in-memory cache +fileutil::paths +Manage search path pools + + generator Procedures for creating and using generators. - + huddle Create and manipulate huddle object - -imap4 -imap client-side tcl implementation of imap protocol - map::geocode::nominatim Resolving geographical names with a Nominatim service @@ -1693,30 +1705,34 @@ stringprep::data stringprep data tables, generated, internal +struct::map +Manage key/value maps + + tclrep/machineparameters Compute double precision machine parameters. - + uevent::onidle Request merging and deferal to idle time - + unicode Implementation of Unicode normalization - + unicode::data unicode data tables, generated, internal - + units unit conversion - + yaml YAML Format Encoder/Decoder
Utilities
@@ -1965,10 +1981,17 @@ +
cache::async Asynchronous in-memory cache
+
clay
+ + + + +
clayA minimalist framework for large scale OO Projects
clock
@@ -2413,10 +2436,14 @@ + + + +
clock_iso8601
fileutil::multi::op Multi-file operation, scatter/gather
fileutil::pathsManage search path pools
fileutil_traverse Iterative directory traversal
ftp
@@ -2571,11 +2598,11 @@
httpd
- +
toolhttpd A TclOO and coroutine based web server
ident
@@ -2807,30 +2834,34 @@ + + + + - + - + - + - + - +
math::polynomials Polynomial functions
math::quasirandomQuasi-random points for integration and Monte Carlo type methods
math::rationalfunctions Polynomial functions
math::roman Tools for creating and manipulating roman numerals
math::special Special mathematical functions
math::statistics Basic statistical functions and procedures
math::trig Trigonometric anf hyperbolic functions
tclrep/machineparameters Compute double precision machine parameters.
md4
@@ -3406,50 +3437,54 @@ struct::list Procedures for manipulating lists +struct::map +Manage key/value maps + + struct::matrix Create and manipulate matrix objects - + struct::matrix_v1 Create and manipulate matrix objects - + struct::pool Create and manipulate pool objects (of discrete items) - + struct::prioqueue Create and manipulate prioqueue objects - + struct::queue Create and manipulate queue objects - + struct::record Define and create records (similar to 'C' structures) - + struct::set Procedures for manipulating sets - + struct::skiplist Create and manipulate skiplists - + struct::stack Create and manipulate stack objects - + struct::tree Create and manipulate tree objects - + struct::tree_v1 Create and manipulate tree objects
tar
Index: idoc/www/toc0.html ================================================================== --- idoc/www/toc0.html +++ idoc/www/toc0.html @@ -797,38 +797,42 @@ math::polynomials Polynomial functions +math::quasirandom +Quasi-random points for integration and Monte Carlo type methods + + math::rationalfunctions Polynomial functions - + math::roman Tools for creating and manipulating roman numerals - + math::special Special mathematical functions - + math::statistics Basic statistical functions and procedures - + math::trig Trigonometric anf hyperbolic functions - + simulation::annealing Simulated annealing - + simulation::montecarlo Monte Carlo simulations - + simulation::random Pseudo-random number generators
Networking
@@ -860,13 +864,21 @@ ftpd Tcl FTP server implementation +httpd +A TclOO and coroutine based web server + + ident Ident protocol client + +imap4 +imap client-side tcl implementation of imap protocol + irc Create IRC connection and interface. @@ -980,26 +992,22 @@ tcllib_ip IPv4 and IPv6 address manipulation -tool -A TclOO and coroutine based web server - - udpcluster UDP Peer-to-Peer cluster - + uri URI utilities - + uri_urn URI utilities, URN scheme - + websocket Tcl implementation of the websocket protocol
Page Parser Generator
@@ -1224,130 +1232,134 @@
Programming tools
+ + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
clayA minimalist framework for large scale OO Projects
cmdline Procedures to process command lines and options.
comm A remote communication facility for Tcl (8.3 and later)
comm_wire The comm wire protocol
control Procedures for control flow structures.
deleg_method Creation of comm delegates (snit methods)
deleg_proc Creation of comm delegates (procedures)
fileutil Procedures implementing some file utilities
fileutil::magic::cfront Generator core for compiler of magic(5) files
fileutil::magic::cgen Generator core for compiler of magic(5) files
fileutil::magic::filetype Procedures implementing file-type recognition
fileutil::magic::rt Runtime core for file type recognition engines written in pure Tcl
fileutil::multi Multi-file operation, scatter/gather, standard object
fileutil::multi::op Multi-file operation, scatter/gather
fileutil_traverse Iterative directory traversal
hook Hooks
interp Interp creation and aliasing
log Procedures to log messages of libraries and applications.
logger System to control logging of events.
logger::appender Collection of predefined appenders for logger
logger::utils Utilities for logger
multiplexer One-to-many communication with sockets.
pluginmgr Manage a plugin
profiler Tcl source code profiler
snit Snit's Not Incr Tcl
snitfaq Snit Frequently Asked Questions
stooop Object oriented extension.
switched switch/option management.
tie Array persistence
tie Array persistence, standard data sources
uevent User events
wip Word Interpreter
System
@@ -1641,21 +1653,21 @@ cache::async Asynchronous in-memory cache +fileutil::paths +Manage search path pools + + generator Procedures for creating and using generators. - + huddle Create and manipulate huddle object - -imap4 -imap client-side tcl implementation of imap protocol - map::geocode::nominatim Resolving geographical names with a Nominatim service @@ -1693,30 +1705,34 @@ stringprep::data stringprep data tables, generated, internal +struct::map +Manage key/value maps + + tclrep/machineparameters Compute double precision machine parameters. - + uevent::onidle Request merging and deferal to idle time - + unicode Implementation of Unicode normalization - + unicode::data unicode data tables, generated, internal - + units unit conversion - + yaml YAML Format Encoder/Decoder
Utilities
Index: idoc/www/toc1.html ================================================================== --- idoc/www/toc1.html +++ idoc/www/toc1.html @@ -131,10 +131,17 @@ +
cache::async Asynchronous in-memory cache
+
clay
+ + + + +
clayA minimalist framework for large scale OO Projects
clock
@@ -579,10 +586,14 @@ + + + +
clock_iso8601
fileutil::multi::op Multi-file operation, scatter/gather
fileutil::pathsManage search path pools
fileutil_traverse Iterative directory traversal
ftp
@@ -737,11 +748,11 @@
httpd
- +
toolhttpd A TclOO and coroutine based web server
ident
@@ -973,30 +984,34 @@ + + + + - + - + - + - + - +
math::polynomials Polynomial functions
math::quasirandomQuasi-random points for integration and Monte Carlo type methods
math::rationalfunctions Polynomial functions
math::roman Tools for creating and manipulating roman numerals
math::special Special mathematical functions
math::statistics Basic statistical functions and procedures
math::trig Trigonometric anf hyperbolic functions
tclrep/machineparameters Compute double precision machine parameters.
md4
@@ -1572,50 +1587,54 @@ struct::list Procedures for manipulating lists +struct::map +Manage key/value maps + + struct::matrix Create and manipulate matrix objects - + struct::matrix_v1 Create and manipulate matrix objects - + struct::pool Create and manipulate pool objects (of discrete items) - + struct::prioqueue Create and manipulate prioqueue objects - + struct::queue Create and manipulate queue objects - + struct::record Define and create records (similar to 'C' structures) - + struct::set Procedures for manipulating sets - + struct::skiplist Create and manipulate skiplists - + struct::stack Create and manipulate stack objects - + struct::tree Create and manipulate tree objects - + struct::tree_v1 Create and manipulate tree objects
tar
Index: installer.tcl ================================================================== --- installer.tcl +++ installer.tcl @@ -280,11 +280,11 @@ # Starkit, or unwrapped. Derive defaults location from the # location of the executable running the installer, or the # location of its library. # For a starkit [info library] is inside the running - # tclkit. Detect this and derive the lcoation from the + # tclkit. Detect this and derive the location from the # location of the executable itself for that case. if {[string match [info nameofexecutable]* [info library]]} { # Starkit set libdir [file join [file dirname [file dirname [info nameofexecutable]]] lib] Index: license.terms ================================================================== --- license.terms +++ license.terms @@ -1,38 +1,38 @@ This software is copyrighted by Ajuba Solutions and other parties. -The following terms apply to all files associated with the software unless -explicitly disclaimed in individual files. +The following terms apply to all files associated with the software +unless explicitly disclaimed in individual files. The authors hereby grant permission to use, copy, modify, distribute, -and license this software and its documentation for any purpose, provided -that existing copyright notices are retained in all copies and that this -notice is included verbatim in any distributions. No written agreement, -license, or royalty fee is required for any of the authorized uses. -Modifications to this software may be copyrighted by their authors -and need not follow the licensing terms described here, provided that -the new terms are clearly indicated on the first page of each file where -they apply. +and license this software and its documentation for any purpose, +provided that existing copyright notices are retained in all copies +and that this notice is included verbatim in any distributions. No +written agreement, license, or royalty fee is required for any of the +authorized uses. Modifications to this software may be copyrighted by +their authors and need not follow the licensing terms described here, +provided that the new terms are clearly indicated on the first page of +each file where they apply. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE -IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE -NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR -MODIFICATIONS. +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND +THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE +MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. GOVERNMENT USE: If you are acquiring this software on behalf of the -U.S. government, the Government shall have only "Restricted Rights" -in the software and related documentation as defined in the Federal +U.S. government, the Government shall have only "Restricted Rights" in +the software and related documentation as defined in the Federal Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you are acquiring the software on behalf of the Department of Defense, the software shall be classified as "Commercial Computer Software" and the Government shall have only "Restricted Rights" as defined in Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the authors grant the U.S. Government and others acting in its behalf permission to use and distribute the software in accordance with the -terms specified in this license. +terms specified in this license. ADDED modules/0compatibility/d_config.tcl Index: modules/0compatibility/d_config.tcl ================================================================== --- /dev/null +++ modules/0compatibility/d_config.tcl @@ -0,0 +1,16 @@ +# (c) 2019 Andreas Kupries +# Redirection wrapper for deprecated package +# Deprecated: +# - doctools::config +# Replacement: +# - struct::map + +package require Tcl 8.4 +package require struct::map + +namespace eval ::doctools {} + +proc ::doctools::config {args} { uplevel 1 [linsert $args 0 ::struct::map] } + +package provide doctools::config 0.1 +return ADDED modules/0compatibility/d_config.test Index: modules/0compatibility/d_config.test ================================================================== --- /dev/null +++ modules/0compatibility/d_config.test @@ -0,0 +1,144 @@ +# -*- tcl -*- +# config.test: Testsuite for DEPRECATED package doctools::config +# +# Copyright (c) 2019 by Andreas Kupries +# All rights reserved. + +# ------------------------------------------------------------------------- + +source [file join \ + [file dirname [file dirname [file join [pwd] [info script]]]] \ + devtools testutilities.tcl] + +testsNeedTcl 8.4 +testsNeedTcltest 2.0 + +support { + use snit/snit.tcl snit + use struct/map.tcl struct::map +} +testing { + useLocal d_config.tcl doctools::config +} + +# --------------------------------------------------------------------- +# [] constructor +# [] destructor +# [] get +# [] names +# [] set +# [] unset + +#---------------------------------------------------------------------- +## Constructor, destructor + +test doctools-config-1.0 {constructor, wrong args, too many} -body { + doctools::config M X +} -returnCodes error -result {Error in constructor: wrong # args: should be "::struct::map::I::Snit_constructor type selfns win self"} + +test doctools-config-1.1 {instance, bogus method} -setup { + doctools::config M +} -cleanup { + M destroy +} -body { + M bogus +} -returnCodes error -result {"::M bogus" is not defined} + +#---------------------------------------------------------------------- +## get + +test doctools-config-2.0 {get, wrong args, too many} -setup { + doctools::config M +} -cleanup { + M destroy +} -body { + M get X +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodget type selfns win self"} + +test doctools-config-2.1 {get, base state, none} -setup { + doctools::config M +} -cleanup { + M destroy +} -body { + M get +} -result {} + +#---------------------------------------------------------------------- +## names + +test doctools-config-3.0 {names, wrong args, too many} -setup { + doctools::config M +} -cleanup { + M destroy +} -body { + M names X +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodnames type selfns win self"} + +test doctools-config-3.1 {names, base state, none} -setup { + doctools::config M +} -cleanup { + M destroy +} -body { + M names +} -result {} + +#---------------------------------------------------------------------- +## set + +test doctools-config-4.0 {set, wrong args, not enough} -setup { + doctools::config M +} -cleanup { + M destroy +} -body { + M set +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodset type selfns win self name ?value?"} + +test doctools-config-4.1 {set, wrong args, too many} -setup { + doctools::config M +} -cleanup { + M destroy +} -body { + M set K V X +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodset type selfns win self name ?value?"} + +test doctools-config-4.2 {set, state change, result} -setup { + doctools::config M +} -cleanup { + M destroy +} -body { + list [M names] [M get] [M set K V] [M names] [M get] +} -result {{} {} V K {K V}} + +#---------------------------------------------------------------------- +## unset + +test doctools-config-5.2 {unset, known key, state change, result} -setup { + doctools::config M + M set K V +} -cleanup { + M destroy +} -body { + list [M names] [M get] [M unset K] [M names] [M get] +} -result {K {K V} {} {} {}} + +test doctools-config-5.3 {unset, missing key, no state change, result} -setup { + doctools::config M + M set K V +} -cleanup { + M destroy +} -body { + list [M names] [M get] [M unset K'] [M names] [M get] +} -result {K {K V} {} K {K V}} + +test doctools-config-5.4 {unset, no pattern, clear, result} -setup { + doctools::config M + M set K V +} -cleanup { + M destroy +} -body { + list [M names] [M get] [M unset] [M names] [M get] +} -result {K {K V} {} {} {}} + +#---------------------------------------------------------------------- +testsuiteCleanup +return ADDED modules/0compatibility/d_paths.tcl Index: modules/0compatibility/d_paths.tcl ================================================================== --- /dev/null +++ modules/0compatibility/d_paths.tcl @@ -0,0 +1,16 @@ +# (c) 2019 Andreas Kupries +# Redirection wrapper for deprecated package +# Deprecated: +# - doctools::paths +# Replacement: +# - fileutil::paths + +package require Tcl 8.4 +package require fileutil::paths + +namespace eval ::doctools {} + +proc ::doctools::paths {args} { uplevel 1 [linsert $args 0 ::fileutil::paths] } + +package provide doctools::paths 0.1 +return ADDED modules/0compatibility/d_paths.test Index: modules/0compatibility/d_paths.test ================================================================== --- /dev/null +++ modules/0compatibility/d_paths.test @@ -0,0 +1,152 @@ +# -*- tcl -*- +# paths.test: Testsuite for DEPRECATED package doctools::paths +# +# Copyright (c) 2019 by Andreas Kupries +# All rights reserved. + +# ------------------------------------------------------------------------- + +source [file join \ + [file dirname [file dirname [file join [pwd] [info script]]]] \ + devtools testutilities.tcl] + +testsNeedTcl 8.4 +testsNeedTcltest 2.0 + +support { + use snit/snit.tcl snit + use fileutil/paths.tcl fileutil::paths +} +testing { + useLocal d_paths.tcl doctools::paths +} + +# --------------------------------------------------------------------- +# [] constructor +# [] destructor +# [] paths +# [] add +# [] remove +# [] clear + +#---------------------------------------------------------------------- +## Constructor, destructor + +test doctools-paths-1.0 {constructor, wrong args, too many} -body { + doctools::paths P X +} -returnCodes error -result {Error in constructor: wrong # args: should be "::fileutil::paths::Snit_constructor type selfns win self"} + +test doctools-paths-1.1 {instance, bogus method} -setup { + doctools::paths P +} -cleanup { + P destroy +} -body { + P bogus +} -returnCodes error -result {"::P bogus" is not defined} + +#---------------------------------------------------------------------- +## paths + +test doctools-paths-2.0 {paths, wrong args, too many} -setup { + doctools::paths P +} -cleanup { + P destroy +} -body { + P paths X +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodpaths type selfns win self"} + +test doctools-paths-2.1 {paths, base state, none} -setup { + doctools::paths P +} -cleanup { + P destroy +} -body { + P paths +} -result {} + +#---------------------------------------------------------------------- +## add + +test doctools-paths-3.0 {add, wrong args, not enough} -setup { + doctools::paths P +} -cleanup { + P destroy +} -body { + P add +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodadd type selfns win self path"} + +test doctools-paths-3.1 {add, wrong args, too many} -setup { + doctools::paths P +} -cleanup { + P destroy +} -body { + P add F X +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodadd type selfns win self path"} + +test doctools-paths-3.2 {add, state change, result} -setup { + doctools::paths P +} -cleanup { + P destroy +} -body { + list [P add F] [P paths] +} -result {{} F} + +#---------------------------------------------------------------------- +## remove + +test doctools-paths-4.0 {remove, wrong args, not enough} -setup { + doctools::paths P +} -cleanup { + P destroy +} -body { + P remove +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodremove type selfns win self path"} + +test doctools-paths-4.1 {remove, wrong args, too many} -setup { + doctools::paths P +} -cleanup { + P destroy +} -body { + P remove F X +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodremove type selfns win self path"} + +test doctools-paths-4.2 {remove, known path, state change, result} -setup { + doctools::paths P + P add F +} -cleanup { + P destroy +} -body { + list [P remove F] [P paths] +} -result {{} {}} + +test doctools-paths-4.3 {remove, missing path, no state change, result} -setup { + doctools::paths P + P add Z +} -cleanup { + P destroy +} -body { + list [P remove F] [P paths] +} -result {{} Z} + +#---------------------------------------------------------------------- +## clear + +test doctools-paths-5.0 {clear, wrong args, too many} -setup { + doctools::paths P +} -cleanup { + P destroy +} -body { + P clear X +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodclear type selfns win self"} + +test doctools-paths-5.1 {clear, return to base state} -setup { + doctools::paths P + P add F +} -cleanup { + P destroy +} -body { + list [P clear] [P paths] +} -result {{} {}} + +#---------------------------------------------------------------------- +testsuiteCleanup +return ADDED modules/0compatibility/p_config.tcl Index: modules/0compatibility/p_config.tcl ================================================================== --- /dev/null +++ modules/0compatibility/p_config.tcl @@ -0,0 +1,14 @@ +# (c) 2019 Andreas Kupries +# Redirection wrapper for deprecated package +# Deprecated: +# - configuration +# Replacement: +# - struct::map + +package require Tcl 8.4 +package require struct::map + +proc ::configuration {args} { uplevel 1 [linsert $args 0 ::struct::map] } + +package provide configuration 1 +return ADDED modules/0compatibility/p_config.test Index: modules/0compatibility/p_config.test ================================================================== --- /dev/null +++ modules/0compatibility/p_config.test @@ -0,0 +1,144 @@ +# -*- tcl -*- +# config.test: Testsuite for DEPRECATED package configuration +# +# Copyright (c) 2019 by Andreas Kupries +# All rights reserved. + +# ------------------------------------------------------------------------- + +source [file join \ + [file dirname [file dirname [file join [pwd] [info script]]]] \ + devtools testutilities.tcl] + +testsNeedTcl 8.4 +testsNeedTcltest 2.0 + +support { + use snit/snit.tcl snit + use struct/map.tcl struct::map +} +testing { + useLocal p_config.tcl configuration +} + +# --------------------------------------------------------------------- +# [] constructor +# [] destructor +# [] get +# [] names +# [] set +# [] unset + +#---------------------------------------------------------------------- +## Constructor, destructor + +test configuration-1.0 {constructor, wrong args, too many} -body { + configuration M X +} -returnCodes error -result {Error in constructor: wrong # args: should be "::struct::map::I::Snit_constructor type selfns win self"} + +test configuration-1.1 {instance, bogus method} -setup { + configuration M +} -cleanup { + M destroy +} -body { + M bogus +} -returnCodes error -result {"::M bogus" is not defined} + +#---------------------------------------------------------------------- +## get + +test configuration-2.0 {get, wrong args, too many} -setup { + configuration M +} -cleanup { + M destroy +} -body { + M get X +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodget type selfns win self"} + +test configuration-2.1 {get, base state, none} -setup { + configuration M +} -cleanup { + M destroy +} -body { + M get +} -result {} + +#---------------------------------------------------------------------- +## names + +test configuration-3.0 {names, wrong args, too many} -setup { + configuration M +} -cleanup { + M destroy +} -body { + M names X +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodnames type selfns win self"} + +test configuration-3.1 {names, base state, none} -setup { + configuration M +} -cleanup { + M destroy +} -body { + M names +} -result {} + +#---------------------------------------------------------------------- +## set + +test configuration-4.0 {set, wrong args, not enough} -setup { + configuration M +} -cleanup { + M destroy +} -body { + M set +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodset type selfns win self name ?value?"} + +test configuration-4.1 {set, wrong args, too many} -setup { + configuration M +} -cleanup { + M destroy +} -body { + M set K V X +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodset type selfns win self name ?value?"} + +test configuration-4.2 {set, state change, result} -setup { + configuration M +} -cleanup { + M destroy +} -body { + list [M names] [M get] [M set K V] [M names] [M get] +} -result {{} {} V K {K V}} + +#---------------------------------------------------------------------- +## unset + +test configuration-5.2 {unset, known key, state change, result} -setup { + configuration M + M set K V +} -cleanup { + M destroy +} -body { + list [M names] [M get] [M unset K] [M names] [M get] +} -result {K {K V} {} {} {}} + +test configuration-5.3 {unset, missing key, no state change, result} -setup { + configuration M + M set K V +} -cleanup { + M destroy +} -body { + list [M names] [M get] [M unset K'] [M names] [M get] +} -result {K {K V} {} K {K V}} + +test configuration-5.4 {unset, no pattern, clear, result} -setup { + configuration M + M set K V +} -cleanup { + M destroy +} -body { + list [M names] [M get] [M unset] [M names] [M get] +} -result {K {K V} {} {} {}} + +#---------------------------------------------------------------------- +testsuiteCleanup +return ADDED modules/0compatibility/p_paths.tcl Index: modules/0compatibility/p_paths.tcl ================================================================== --- /dev/null +++ modules/0compatibility/p_paths.tcl @@ -0,0 +1,14 @@ +# (c) 2019 Andreas Kupries +# Redirection wrapper for deprecated package +# Deprecated: +# - paths +# Replacement: +# - fileutil::paths + +package require Tcl 8.4 +package require fileutil::paths + +proc ::paths {args} { uplevel 1 [linsert $args 0 ::fileutil::paths] } + +package provide paths 1 +return ADDED modules/0compatibility/p_paths.test Index: modules/0compatibility/p_paths.test ================================================================== --- /dev/null +++ modules/0compatibility/p_paths.test @@ -0,0 +1,152 @@ +# -*- tcl -*- +# paths.test: Testsuite for DEPRECATED package paths (pt) +# +# Copyright (c) 2019 by Andreas Kupries +# All rights reserved. + +# ------------------------------------------------------------------------- + +source [file join \ + [file dirname [file dirname [file join [pwd] [info script]]]] \ + devtools testutilities.tcl] + +testsNeedTcl 8.4 +testsNeedTcltest 2.0 + +support { + use snit/snit.tcl snit + use fileutil/paths.tcl fileutil::paths +} +testing { + useLocal p_paths.tcl paths +} + +# --------------------------------------------------------------------- +# [] constructor +# [] destructor +# [] paths +# [] add +# [] remove +# [] clear + +#---------------------------------------------------------------------- +## Constructor, destructor + +test paths-1.0 {constructor, wrong args, too many} -body { + paths P X +} -returnCodes error -result {Error in constructor: wrong # args: should be "::fileutil::paths::Snit_constructor type selfns win self"} + +test paths-1.1 {instance, bogus method} -setup { + paths P +} -cleanup { + P destroy +} -body { + P bogus +} -returnCodes error -result {"::P bogus" is not defined} + +#---------------------------------------------------------------------- +## paths + +test paths-2.0 {paths, wrong args, too many} -setup { + paths P +} -cleanup { + P destroy +} -body { + P paths X +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodpaths type selfns win self"} + +test paths-2.1 {paths, base state, none} -setup { + paths P +} -cleanup { + P destroy +} -body { + P paths +} -result {} + +#---------------------------------------------------------------------- +## add + +test paths-3.0 {add, wrong args, not enough} -setup { + paths P +} -cleanup { + P destroy +} -body { + P add +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodadd type selfns win self path"} + +test paths-3.1 {add, wrong args, too many} -setup { + paths P +} -cleanup { + P destroy +} -body { + P add F X +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodadd type selfns win self path"} + +test paths-3.2 {add, state change, result} -setup { + paths P +} -cleanup { + P destroy +} -body { + list [P add F] [P paths] +} -result {{} F} + +#---------------------------------------------------------------------- +## remove + +test paths-4.0 {remove, wrong args, not enough} -setup { + paths P +} -cleanup { + P destroy +} -body { + P remove +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodremove type selfns win self path"} + +test paths-4.1 {remove, wrong args, too many} -setup { + paths P +} -cleanup { + P destroy +} -body { + P remove F X +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodremove type selfns win self path"} + +test paths-4.2 {remove, known path, state change, result} -setup { + paths P + P add F +} -cleanup { + P destroy +} -body { + list [P remove F] [P paths] +} -result {{} {}} + +test paths-4.3 {remove, missing path, no state change, result} -setup { + paths P + P add Z +} -cleanup { + P destroy +} -body { + list [P remove F] [P paths] +} -result {{} Z} + +#---------------------------------------------------------------------- +## clear + +test paths-5.0 {clear, wrong args, too many} -setup { + paths P +} -cleanup { + P destroy +} -body { + P clear X +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodclear type selfns win self"} + +test paths-5.1 {clear, return to base state} -setup { + paths P + P add F +} -cleanup { + P destroy +} -body { + list [P clear] [P paths] +} -result {{} {}} + +#---------------------------------------------------------------------- +testsuiteCleanup +return ADDED modules/0compatibility/pkgIndex.tcl Index: modules/0compatibility/pkgIndex.tcl ================================================================== --- /dev/null +++ modules/0compatibility/pkgIndex.tcl @@ -0,0 +1,29 @@ +# Compatibility wrapper for deprecated packages. +## +# Stages +# [D1] Next Release - Noted deprecated, with redirection wrappers +# [D2] Release After - Wrappers become Boockers, throwing error noting redirection +# [D3] Release Beyond - All removed. +## +# Currently in deprecation +# - D1 doctools::path (doctools2base) +# - D1 doctools::config (doctools2base) +# - D1 configuration (pt) +# - D1 paths (pt) +# +# :Attention: +# - Original `doctools::paths` Tcl 8.4 required +# Replacement `fileutilutil::paths` Tcl 8.5 required! + +if {![package vsatisfies [package provide Tcl] 8.4]} {return} + +package ifneeded configuration 1 [list source [file join $dir p_config.tcl]] +package ifneeded doctools::config 0.1 [list source [file join $dir d_config.tcl]] +package ifneeded doctools::paths 0.1 [list source [file join $dir d_paths.tcl]] +package ifneeded paths 1 [list source [file join $dir p_paths.tcl]] + +if {![package vsatisfies [package provide Tcl] 8.5]} {return} + + +if {![package vsatisfies [package provide Tcl] 8.6]} {return} + Index: modules/aes/aes.man ================================================================== --- modules/aes/aes.man +++ modules/aes/aes.man @@ -162,7 +162,7 @@ [section AUTHORS] Thorsten Schloermann, Pat Thoyts [vset CATEGORY aes] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/amazon-s3/S3.man ================================================================== --- modules/amazon-s3/S3.man +++ modules/amazon-s3/S3.man @@ -1444,7 +1444,7 @@ to be run on Amazon's Elastic Compute Cloud. [include ../common-text/tls-security-notes.inc] [vset CATEGORY amazon-s3] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/amazon-s3/xsxp.man ================================================================== --- modules/amazon-s3/xsxp.man +++ modules/amazon-s3/xsxp.man @@ -131,7 +131,7 @@ version of [arg pxml]. [list_end] [vset CATEGORY amazon-s3] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/asn/asn.man ================================================================== --- modules/asn/asn.man +++ modules/asn/asn.man @@ -458,7 +458,7 @@ Examples for the usage of this package can be found in the implementation of package [package ldap]. [vset CATEGORY asn] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/base32/base32.man ================================================================== --- modules/base32/base32.man +++ modules/base32/base32.man @@ -69,7 +69,7 @@ 7 H 16 Q 25 Z 8 I 17 R 26 2 }] [vset CATEGORY base32] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/base32/base32core.man ================================================================== --- modules/base32/base32core.man +++ modules/base32/base32core.man @@ -60,7 +60,7 @@ [enum] The padding has not of length six, four, three, or one characters, [list_end] [list_end] [vset CATEGORY base32] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/base32/base32hex.man ================================================================== --- modules/base32/base32hex.man +++ modules/base32/base32hex.man @@ -72,7 +72,7 @@ 7 7 16 G 25 P 8 8 17 H 26 Q }] [vset CATEGORY base32] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/base64/ascii85.man ================================================================== --- modules/base64/ascii85.man +++ modules/base64/ascii85.man @@ -69,7 +69,7 @@ [enum] Postscript Language Reference Manual, 3rd Edition, page 131. [uri http://www.adobe.com/devnet/postscript/pdfs/PLRM.pdf] [list_end] [vset CATEGORY base64] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/base64/base64.man ================================================================== --- modules/base64/base64.man +++ modules/base64/base64.man @@ -64,7 +64,7 @@ Q+KCiEjigoHigoBO4oKET+KCgg== % set caffeine [encoding convertfrom utf-8 [base64::decode $encoded]] }] [vset CATEGORY base64] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/base64/uuencode.man ================================================================== --- modules/base64/uuencode.man +++ modules/base64/uuencode.man @@ -91,7 +91,7 @@ % uuencode::uudecode $d {hello.txt 644 {Hello World}} }] [vset CATEGORY base64] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/base64/yencode.man ================================================================== --- modules/base64/yencode.man +++ modules/base64/yencode.man @@ -90,7 +90,7 @@ [list_begin enum] [enum] [uri http://www.yenc.org/yenc-draft.1.3.txt] [list_end] [vset CATEGORY base64] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/bee/bee.man ================================================================== --- modules/bee/bee.man +++ modules/bee/bee.man @@ -337,7 +337,7 @@ a digit. [section EXAMPLES] [vset CATEGORY bee] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/bench/bench.man ================================================================== --- modules/bench/bench.man +++ modules/bench/bench.man @@ -290,7 +290,7 @@ [list_end] [list_end] [vset CATEGORY bench] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/bench/bench_intro.man ================================================================== --- modules/bench/bench_intro.man +++ modules/bench/bench_intro.man @@ -85,7 +85,7 @@ This module and package have been derived from Jeff Hobbs' [syscmd tclbench] application for the benchmarking of the Tcl core and its ancestor [file runbench.tcl]. [vset CATEGORY bench] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/bench/bench_lang_intro.man ================================================================== --- modules/bench/bench_lang_intro.man +++ modules/bench/bench_lang_intro.man @@ -147,7 +147,7 @@ available commands and their syntax. [para] [vset CATEGORY bench] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/bench/bench_lang_spec.man ================================================================== --- modules/bench/bench_lang_spec.man +++ modules/bench/bench_lang_spec.man @@ -126,7 +126,7 @@ [list_end] [list_end] [vset CATEGORY bench] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/bench/bench_read.man ================================================================== --- modules/bench/bench_read.man +++ modules/bench/bench_read.man @@ -59,7 +59,7 @@ and automatically detects which format is used by the input file. [list_end] [vset CATEGORY bench] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/bench/bench_wcsv.man ================================================================== --- modules/bench/bench_wcsv.man +++ modules/bench/bench_wcsv.man @@ -48,7 +48,7 @@ results in raw form, or for human consumption, respectively. [list_end] [vset CATEGORY bench] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/bench/bench_wtext.man ================================================================== --- modules/bench/bench_wtext.man +++ modules/bench/bench_wtext.man @@ -49,7 +49,7 @@ results in raw form, or as importable CSV data, respectively. [list_end] [vset CATEGORY bench] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/bibtex/bibtex.man ================================================================== --- modules/bibtex/bibtex.man +++ modules/bibtex/bibtex.man @@ -174,7 +174,7 @@ [cmd ::bibtex::parse]. [list_end] [vset CATEGORY bibtex] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/blowfish/blowfish.man ================================================================== --- modules/blowfish/blowfish.man +++ modules/blowfish/blowfish.man @@ -158,7 +158,7 @@ [section AUTHORS] Frank Pilhofer, Pat Thoyts [vset CATEGORY blowfish] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/cache/async.man ================================================================== --- modules/cache/async.man +++ modules/cache/async.man @@ -138,7 +138,7 @@ [method get]-requests to reload the information from the provider. [list_end] [vset CATEGORY cache] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/clay/build/event.tcl ================================================================== --- modules/clay/build/event.tcl +++ modules/clay/build/event.tcl @@ -1,19 +1,11 @@ -::namespace eval ::clay::event {} - -### -# Mark an object for destruction on the next cleanup -### -proc ::clay::destroy args { - if {![info exists ::clay::idle_destroy]} { - set ::clay::idle_destroy {} - } - foreach object $args { - if {$object in $::clay::idle_destroy} continue - lappend ::clay::idle_destroy $object - } -} +if {[info commands ::cron::object_destroy] eq {}} { + # Provide a noop if we aren't running with the cron scheduler + namespace eval ::cron {} + proc ::cron::object_destroy args {} +} +::namespace eval ::clay::event {} ### # Process the queue of objects to be destroyed ### proc ::clay::cleanup {} { @@ -23,10 +15,39 @@ catch {$obj destroy} } } set ::clay::idle_destroy {} } + +proc ::clay::object_create {objname {class {}}} { + #if {$::clay::trace>0} { + # puts [list $objname CREATE] + #} +} + +proc ::clay::object_rename {object newname} { + if {$::clay::trace>0} { + puts [list $object RENAME -> $newname] + } +} + +### +# Mark an objects for destruction on the next cleanup +### +proc ::clay::object_destroy args { + if {![info exists ::clay::idle_destroy]} { + set ::clay::idle_destroy {} + } + foreach objname $args { + if {$::clay::trace>0} { + puts [list $objname DESTROY] + } + ::cron::object_destroy $objname + if {$objname in $::clay::idle_destroy} continue + lappend ::clay::idle_destroy $objname + } +} ### # description: Cancel a scheduled event ### proc ::clay::event::cancel {self {task *}} { Index: modules/clay/build/footer.txt ================================================================== --- modules/clay/build/footer.txt +++ modules/clay/build/footer.txt @@ -1,2 +1,2 @@ [vset CATEGORY oo] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] Index: modules/clay/build/metaclass.tcl ================================================================== --- modules/clay/build/metaclass.tcl +++ modules/clay/build/metaclass.tcl @@ -107,11 +107,10 @@ # Run the destructor once and only once set self [self] my variable DestroyEvent if {$DestroyEvent} return set DestroyEvent 1 -::clay::object_destroy $self } append body $rawbody ::oo::define [current_class] destructor $body } @@ -193,25 +192,5 @@ proc ::clay::define::Variable {name {default {}}} { set class [current_class] set name [string trimright $name :/] $class clay set variable/ $name $default } - -proc ::clay::object_create {objname {class {}}} { - #if {$::clay::trace>0} { - # puts [list $objname CREATE] - #} -} - -proc ::clay::object_rename {object newname} { - if {$::clay::trace>0} { - puts [list $object RENAME -> $newname] - } -} - -proc ::clay::object_destroy objname { - if {$::clay::trace>0} { - puts [list $objname DESTROY] - } - #::cron::object_destroy $objname -} - Index: modules/clay/build/object.tcl ================================================================== --- modules/clay/build/object.tcl +++ modules/clay/build/object.tcl @@ -459,10 +459,28 @@ if {[$class clay exists {*}$args]} { return $class } } return {} + } + refcount { + my variable refcount + if {![info exists refcount]} { + return 0 + } + return $refcount + } + refcount_incr { + my variable refcount + incr refcount + } + refcount_decr { + my variable refcount + incr refcount -1 + if {$refcount <= 0} { + ::clay::object_destroy [self] + } } replace { set clay [lindex $args 0] } source { Index: modules/clay/clay.man ================================================================== --- modules/clay/clay.man +++ modules/clay/clay.man @@ -445,37 +445,34 @@ Variables registered in the variable property are also initialized (if missing) when the object changes class via the [emph morph] method. - -[call proc [cmd clay::object_create] [arg objname] [opt "[arg class] [const ""]"]] - - -[call proc [cmd clay::object_rename] [arg object] [arg newname]] - - -[call proc [cmd clay::object_destroy] [arg objname]] - [call proc [cmd clay::ensemble_methodbody] [arg ensemble] [arg einfo]] [call proc [cmd clay::define::Ensemble] [arg rawmethod] [opt "[arg args]"]] - -[call proc [cmd clay::destroy] [opt "[arg args]"]] - - Mark an object for destruction on the next cleanup - - - [call proc [cmd clay::cleanup]] Process the queue of objects to be destroyed + + + +[call proc [cmd clay::object_create] [arg objname] [opt "[arg class] [const ""]"]] + + +[call proc [cmd clay::object_rename] [arg object] [arg newname]] + + +[call proc [cmd clay::object_destroy] [opt "[arg args]"]] + + Mark an objects for destruction on the next cleanup + [call proc [cmd clay::event::cancel] [arg self] [opt "[arg task] [const "*"]"]] @@ -699,9 +696,9 @@ [para] [section AUTHORS] Sean Woods [uri mailto:][para] [vset CATEGORY oo] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/clay/clay.tcl ================================================================== --- modules/clay/clay.tcl +++ modules/clay/clay.tcl @@ -1027,11 +1027,10 @@ # Run the destructor once and only once set self [self] my variable DestroyEvent if {$DestroyEvent} return set DestroyEvent 1 -::clay::object_destroy $self } append body $rawbody ::oo::define [current_class] destructor $body } proc ::clay::define::Dict {name {values {}}} { @@ -1090,26 +1089,10 @@ proc ::clay::define::Variable {name {default {}}} { set class [current_class] set name [string trimright $name :/] $class clay set variable/ $name $default } -proc ::clay::object_create {objname {class {}}} { - #if {$::clay::trace>0} { - # puts [list $objname CREATE] - #} -} -proc ::clay::object_rename {object newname} { - if {$::clay::trace>0} { - puts [list $object RENAME -> $newname] - } -} -proc ::clay::object_destroy objname { - if {$::clay::trace>0} { - puts [list $objname DESTROY] - } - #::cron::object_destroy $objname -} ### # END: metaclass.tcl ### ### @@ -1771,10 +1754,28 @@ if {[$class clay exists {*}$args]} { return $class } } return {} + } + refcount { + my variable refcount + if {![info exists refcount]} { + return 0 + } + return $refcount + } + refcount_incr { + my variable refcount + incr refcount + } + refcount_decr { + my variable refcount + incr refcount -1 + if {$refcount <= 0} { + ::clay::object_destroy [self] + } } replace { set clay [lindex $args 0] } source { @@ -1907,29 +1908,48 @@ # END: object.tcl ### ### # START: event.tcl ### -::namespace eval ::clay::event { -} -proc ::clay::destroy args { - if {![info exists ::clay::idle_destroy]} { - set ::clay::idle_destroy {} - } - foreach object $args { - if {$object in $::clay::idle_destroy} continue - lappend ::clay::idle_destroy $object - } +if {[info commands ::cron::object_destroy] eq {}} { + # Provide a noop if we aren't running with the cron scheduler + namespace eval ::cron {} + proc ::cron::object_destroy args {} +} +::namespace eval ::clay::event { } proc ::clay::cleanup {} { if {![info exists ::clay::idle_destroy]} return foreach obj $::clay::idle_destroy { if {[info commands $obj] ne {}} { catch {$obj destroy} } } set ::clay::idle_destroy {} +} +proc ::clay::object_create {objname {class {}}} { + #if {$::clay::trace>0} { + # puts [list $objname CREATE] + #} +} +proc ::clay::object_rename {object newname} { + if {$::clay::trace>0} { + puts [list $object RENAME -> $newname] + } +} +proc ::clay::object_destroy args { + if {![info exists ::clay::idle_destroy]} { + set ::clay::idle_destroy {} + } + foreach objname $args { + if {$::clay::trace>0} { + puts [list $objname DESTROY] + } + ::cron::object_destroy $objname + if {$objname in $::clay::idle_destroy} continue + lappend ::clay::idle_destroy $objname + } } proc ::clay::event::cancel {self {task *}} { variable timer_event variable timer_script Index: modules/clock/iso8601.man ================================================================== --- modules/clock/iso8601.man +++ modules/clock/iso8601.man @@ -41,7 +41,7 @@ of the builtin command [cmd {clock scan}]. [list_end] [vset CATEGORY clock::iso8601] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/clock/rfc2822.man ================================================================== --- modules/clock/rfc2822.man +++ modules/clock/rfc2822.man @@ -21,7 +21,7 @@ if the command is unable to parse the date. [list_end] [vset CATEGORY clock::rfc2822] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/cmdline/cmdline.man ================================================================== --- modules/cmdline/cmdline.man +++ modules/cmdline/cmdline.man @@ -198,7 +198,7 @@ options is created, then the 'args' list is passed to cmdline for processing. Subsequently, different options are checked to see if they have been passed to the script, and what their value is. [vset CATEGORY cmdline] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/comm/comm.man ================================================================== --- modules/comm/comm.man +++ modules/comm/comm.man @@ -1226,7 +1226,7 @@ Andreas Kupries uses [package comm] and has built a simple nameserver as part of his Pool library. See [uri http://www.purl.org/net/akupries/soft/pool/index.htm]. [vset CATEGORY comm] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/comm/comm_wire.man ================================================================== --- modules/comm/comm_wire.man +++ modules/comm/comm_wire.man @@ -278,7 +278,7 @@ IOW if v2 is used the client will not see a version reply during the negotiation handshake. }] [vset CATEGORY comm] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] ADDED modules/common-text/feedback.inc Index: modules/common-text/feedback.inc ================================================================== --- /dev/null +++ modules/common-text/feedback.inc @@ -0,0 +1,23 @@ +[section {Bugs, Ideas, Feedback}] +[vset TRACKER http://core.tcl.tk/tcllib/reportlist] +[vset LABEL {Tcllib Trackers}] + +This document, and the package it describes, will undoubtedly contain +bugs and other problems. + +Please report such in the category [emph [vset CATEGORY]] of the +[uri [vset TRACKER] [vset LABEL]]. + +Please also report any ideas for enhancements you may have for either +package and/or documentation. + +[para] +When proposing code changes, please provide [emph {unified diffs}], +i.e the output of [const {diff -u}]. + +[para] +Note further that [emph attachments] are strongly preferred over +inlined patches. Attachments can be made by going to the [const Edit] +form of the ticket immediately after its creation, and then using the +left-most button in the secondary navigation bar. + Index: modules/control/control.man ================================================================== --- modules/control/control.man +++ modules/control/control.man @@ -159,7 +159,7 @@ % catch b 0 }] [vset CATEGORY control] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/coroutine/coro_auto.man ================================================================== --- modules/coroutine/coro_auto.man +++ modules/coroutine/coro_auto.man @@ -40,7 +40,7 @@ [def [cmd update]] [def [cmd vwait]] [list_end] [vset CATEGORY coroutine] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/coroutine/coroutine.tcl ================================================================== --- modules/coroutine/coroutine.tcl +++ modules/coroutine/coroutine.tcl @@ -96,11 +96,11 @@ } # - -- --- ----- -------- ------------- proc ::coroutine::util::after {delay} { - ::after $delay [info coroutine] + ::after $delay [list [info coroutine]] yield return } # - -- --- ----- -------- ------------- @@ -127,11 +127,11 @@ # idle handler to defer it until the trace is definitely # done. This trick by Peter Spjuth. # # (*) At this point we are in VWaitTrace running the coroutine. - ::after idle [info coroutine] + ::after idle [list [info coroutine]] yield return } proc ::coroutine::util::VWaitTrace {coroutine args} { @@ -141,16 +141,16 @@ # - -- --- ----- -------- ------------- proc ::coroutine::util::update {{what {}}} { if {$what eq "idletasks"} { - ::after idle [info coroutine] + ::after idle [list [info coroutine]] } elseif {$what ne {}} { # Force proper error message for bad call. tailcall ::tcl::update $what } else { - ::after 0 [info coroutine] + ::after 0 [list [info coroutine]] } yield return } @@ -378,11 +378,11 @@ # idle handler to defer it until the trace is definitely # done. This trick by Peter Spjuth. # # (*) At this point we are in AWaitSignal running the coroutine. - ::after idle [info coroutine] + ::after idle [list [info coroutine]] yield return $choice } Index: modules/coroutine/tcllib_coroutine.man ================================================================== --- modules/coroutine/tcllib_coroutine.man +++ modules/coroutine/tcllib_coroutine.man @@ -111,7 +111,7 @@ the named namespace variable [arg varname]. [list_end] [vset CATEGORY coroutine] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/counter/counter.man ================================================================== --- modules/counter/counter.man +++ modules/counter/counter.man @@ -244,7 +244,7 @@ the same meaning as described for [cmd ::counter::init]. [list_end] [vset CATEGORY counter] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/crc/cksum.man ================================================================== --- modules/crc/cksum.man +++ modules/crc/cksum.man @@ -125,7 +125,7 @@ [section AUTHORS] Pat Thoyts [vset CATEGORY crc] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/crc/crc16.man ================================================================== --- modules/crc/crc16.man +++ modules/crc/crc16.man @@ -143,7 +143,7 @@ [section AUTHORS] Pat Thoyts [vset CATEGORY crc] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/crc/crc32.man ================================================================== --- modules/crc/crc32.man +++ modules/crc/crc32.man @@ -146,7 +146,7 @@ [section AUTHORS] Pat Thoyts [vset CATEGORY crc] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/crc/sum.man ================================================================== --- modules/crc/sum.man +++ modules/crc/sum.man @@ -102,7 +102,7 @@ [section AUTHORS] Pat Thoyts [vset CATEGORY crc] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/cron/cron.man ================================================================== --- modules/cron/cron.man +++ modules/cron/cron.man @@ -180,7 +180,7 @@ [list_end] [para] [vset CATEGORY odie] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/csv/csv.man ================================================================== --- modules/csv/csv.man +++ modules/csv/csv.man @@ -241,7 +241,7 @@ instead. As can be seen only item (d) is different, now the empty string instead of a ". [vset CATEGORY csv] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/debug/debug.man ================================================================== --- modules/debug/debug.man +++ modules/debug/debug.man @@ -241,7 +241,7 @@ [comment {= = == === ===== ======== ============= =====================}] [list_end] [vset CATEGORY debug] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/debug/debug_caller.man ================================================================== --- modules/debug/debug_caller.man +++ modules/debug/debug_caller.man @@ -38,7 +38,7 @@ dictionaries, etc. to prevent them from overwhelming the narrative. [list_end] [vset CATEGORY debug] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/debug/debug_heartbeat.man ================================================================== --- modules/debug/debug_heartbeat.man +++ modules/debug/debug_heartbeat.man @@ -37,7 +37,7 @@ nominal [arg delta]. [list_end] [vset CATEGORY debug] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/debug/debug_timestamp.man ================================================================== --- modules/debug/debug_timestamp.man +++ modules/debug/debug_timestamp.man @@ -28,7 +28,7 @@ when only specific places need such detail. [list_end] [vset CATEGORY debug] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/defer/defer.man ================================================================== --- modules/defer/defer.man +++ modules/defer/defer.man @@ -96,7 +96,7 @@ [section AUTHORS] Roy Keene [vset CATEGORY defer] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/des/des.man ================================================================== --- modules/des/des.man +++ modules/des/des.man @@ -200,7 +200,7 @@ Jochen C Loewer, Mac Cody, Pat Thoyts [vset CATEGORY des] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/des/tcldes.man ================================================================== --- modules/des/tcldes.man +++ modules/des/tcldes.man @@ -20,7 +20,7 @@ The [package tclDES] package is a helper package for [package des]. [para] Please see the documentation of [package des] for details. [vset CATEGORY des] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/des/tcldesjr.man ================================================================== --- modules/des/tcldesjr.man +++ modules/des/tcldesjr.man @@ -20,7 +20,7 @@ The [package tclDESjr] package is a helper package for [package des]. [para] Please see the documentation of [package des] for details. [vset CATEGORY des] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/dicttool/dicttool.man ================================================================== --- modules/dicttool/dicttool.man +++ modules/dicttool/dicttool.man @@ -1,13 +1,15 @@ +[vset VERSION 1.0] [comment {-*- tcl -*- doctools manpage}] -[manpage_begin dicttool n 1.0] +[manpage_begin dicttool n [vset VERSION]] [keywords dict] [copyright {2017 Sean Woods }] [moddesc {Extensions to the standard "dict" command}] [category Utilities] [titledesc {Dictionary Tools}] [require Tcl 8.5] +[require dicttool [opt [vset VERSION]]] [description] [para] The [package dicttool] package enhances the standard [emph 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, @@ -19,11 +21,11 @@ This command will add a new instance of each element in [arg args] to [arg varname], but only if that element is not already present. [call [cmd ldelete] [arg varname] [arg args]] -This command will add a delete all instances of each element in [arg args] from [arg varname]. +This command will delete all instances of each element in [arg args] from [arg varname]. [call [cmd {dict getnull}] [arg args]] Operates like [cmd {dict get}], however if the key [arg args] does not exist, it returns an empty list instead of throwing an error. @@ -70,7 +72,7 @@ }] [list_end] [vset CATEGORY dict] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/dicttool/dicttool.md ================================================================== --- modules/dicttool/dicttool.md +++ modules/dicttool/dicttool.md @@ -1,62 +1,62 @@ -The dicttool Package -==================== - -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. - -#### ladd *varname* *args* - -This command will add a new instance of each element in *args* to *varname*, -but only if that element is not already present. - -#### ldelete] *varname* *args* - -This command will add a delete all instances of each element in *args* from *varname*. - -#### dict getnull *args* - -Operates like **dict get**, however if the key *args* does not exist, it returns an empty -list instead of throwing an error. - -#### dict print *dict* - -This command will produce a string representation of *dict*, with each nested branch on -a newline, and indented with two spaces for every level. - -#### dict is_dict *value* - -This command will return true if *value* can be interpreted as a dict. The command operates in -such a way as to not force an existing dict representation to shimmer into another internal rep. - -#### dict rmerge *args* - -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]
-
- - -Prints the following result: -

-option {
-  color {
-    default: blue
-  }
-  fruit {
-    widget: select
-    values: {mango apple cherry grape}
-  }
-}
-
+The dicttool Package +==================== + +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. + +#### ladd *varname* *args* + +This command will add a new instance of each element in *args* to *varname*, +but only if that element is not already present. + +#### ldelete] *varname* *args* + +This command will delete all instances of each element in *args* from *varname*. + +#### dict getnull *args* + +Operates like **dict get**, however if the key *args* does not exist, it returns an empty +list instead of throwing an error. + +#### dict print *dict* + +This command will produce a string representation of *dict*, with each nested branch on +a newline, and indented with two spaces for every level. + +#### dict is_dict *value* + +This command will return true if *value* can be interpreted as a dict. The command operates in +such a way as to not force an existing dict representation to shimmer into another internal rep. + +#### dict rmerge *args* + +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]
+
+ + +Prints the following result: +

+option {
+  color {
+    default: blue
+  }
+  fruit {
+    widget: select
+    values: {mango apple cherry grape}
+  }
+}
+
Index: modules/dns/tcllib_dns.man ================================================================== --- modules/dns/tcllib_dns.man +++ modules/dns/tcllib_dns.man @@ -285,7 +285,7 @@ [section AUTHORS] Pat Thoyts [vset CATEGORY dns] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/dns/tcllib_ip.man ================================================================== --- modules/dns/tcllib_ip.man +++ modules/dns/tcllib_ip.man @@ -445,7 +445,7 @@ [section AUTHORS] Pat Thoyts [vset CATEGORY dns] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/changelog.man ================================================================== --- modules/doctools/changelog.man +++ modules/doctools/changelog.man @@ -81,7 +81,7 @@ new structure is returned as the result of the command. [list_end] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/checker.tcl ================================================================== --- modules/doctools/checker.tcl +++ modules/doctools/checker.tcl @@ -614,11 +614,11 @@ } } } # If we have no text take the section title as text, if we - # can. Last fallback for thext is the id. + # can. Last fallback for text is the id. if {$title == {}} { if {$pid != {}} { set title $sectt($fid) } else { set title $id Index: modules/doctools/cvs.man ================================================================== --- modules/doctools/cvs.man +++ modules/doctools/cvs.man @@ -95,7 +95,7 @@ constructed text is returned as the result of the command. [list_end] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/docidx.man ================================================================== --- modules/doctools/docidx.man +++ modules/doctools/docidx.man @@ -404,7 +404,7 @@ Wippler's [syscmd wikit] application. [list_end] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/docidx_intro.man ================================================================== --- modules/doctools/docidx_intro.man +++ modules/doctools/docidx_intro.man @@ -100,7 +100,7 @@ They are described in their own sets of documents, starting at the [term {doctoc introduction}] and the [term {doctools introduction}], respectively. [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/docidx_lang_cmdref.man ================================================================== --- modules/doctools/docidx_lang_cmdref.man +++ modules/doctools/docidx_lang_cmdref.man @@ -110,7 +110,7 @@ named document variable [list_end] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/docidx_lang_faq.man ================================================================== --- modules/doctools/docidx_lang_faq.man +++ modules/doctools/docidx_lang_faq.man @@ -22,7 +22,7 @@ [include include/placeholder.inc] [include include/examples.inc] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/docidx_lang_intro.man ================================================================== --- modules/doctools/docidx_lang_intro.man +++ modules/doctools/docidx_lang_intro.man @@ -208,7 +208,7 @@ easy and simple [syscmd dtplite] goes, creating an index for a set of documents behind the scenes, without the writer having to do so on their own. [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/docidx_lang_syntax.man ================================================================== --- modules/doctools/docidx_lang_syntax.man +++ modules/doctools/docidx_lang_syntax.man @@ -114,7 +114,7 @@ [list_end] [list_end] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/docidx_plugin_apiref.man ================================================================== --- modules/doctools/docidx_plugin_apiref.man +++ modules/doctools/docidx_plugin_apiref.man @@ -415,7 +415,7 @@ to simply return its argument without change. [list_end] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/doctoc.man ================================================================== --- modules/doctools/doctoc.man +++ modules/doctools/doctoc.man @@ -404,7 +404,7 @@ Wippler's [syscmd wikit] application. [list_end] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/doctoc_intro.man ================================================================== --- modules/doctools/doctoc_intro.man +++ modules/doctools/doctoc_intro.man @@ -99,7 +99,7 @@ They are described in their own sets of documents, starting at the [term {docidx introduction}] and the [term {doctools introduction}], respectively. [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/doctoc_lang_cmdref.man ================================================================== --- modules/doctools/doctoc_lang_cmdref.man +++ modules/doctools/doctoc_lang_cmdref.man @@ -121,7 +121,7 @@ named document variable [list_end] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/doctoc_lang_faq.man ================================================================== --- modules/doctools/doctoc_lang_faq.man +++ modules/doctools/doctoc_lang_faq.man @@ -22,7 +22,7 @@ [include include/placeholder.inc] [include include/examples.inc] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/doctoc_lang_intro.man ================================================================== --- modules/doctools/doctoc_lang_intro.man +++ modules/doctools/doctoc_lang_intro.man @@ -291,7 +291,7 @@ easy and simple [syscmd dtplite] goes, creating a table of contents for a set of documents behind the scenes, without the writer having to do so on their own. [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/doctoc_lang_syntax.man ================================================================== --- modules/doctools/doctoc_lang_syntax.man +++ modules/doctools/doctoc_lang_syntax.man @@ -99,7 +99,7 @@ contents DIVISION_END }] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/doctoc_plugin_apiref.man ================================================================== --- modules/doctools/doctoc_plugin_apiref.man +++ modules/doctools/doctoc_plugin_apiref.man @@ -415,7 +415,7 @@ to simply return its argument without change. [list_end] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/doctools.man ================================================================== --- modules/doctools/doctools.man +++ modules/doctools/doctools.man @@ -1,7 +1,7 @@ [comment {-*- tcl -*- doctools manpage}] -[vset PACKAGE_VERSION 1.5.2] +[vset PACKAGE_VERSION 1.5.6] [manpage_begin doctools n [vset PACKAGE_VERSION]] [see_also doctools_intro] [see_also doctools_lang_cmdref] [see_also doctools_lang_intro] [see_also doctools_lang_syntax] @@ -569,7 +569,7 @@ Wippler's [syscmd wikit] application. [list_end] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/doctools.tcl ================================================================== --- modules/doctools/doctools.tcl +++ modules/doctools/doctools.tcl @@ -1356,6 +1356,6 @@ #catch {search [file join $here lib doctools mpformats]} #catch {search [file join [file dirname $here] lib doctools mpformats]} catch {search [file join $here mpformats]} } -package provide doctools 1.5.2 +package provide doctools 1.5.6 Index: modules/doctools/doctools_intro.man ================================================================== --- modules/doctools/doctools_intro.man +++ modules/doctools/doctools_intro.man @@ -97,7 +97,7 @@ They are described in their own sets of documents, starting at the [term {docidx introduction}] and the [term {doctoc introduction}], respectively. [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/doctools_lang_cmdref.man ================================================================== --- modules/doctools/doctools_lang_cmdref.man +++ modules/doctools/doctools_lang_cmdref.man @@ -464,7 +464,7 @@ it. Main use is the highlighting of widget names in free-form text. [list_end] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/doctools_lang_faq.man ================================================================== --- modules/doctools/doctools_lang_faq.man +++ modules/doctools/doctools_lang_faq.man @@ -22,7 +22,7 @@ [include include/placeholder.inc] [include include/examples.inc] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/doctools_lang_intro.man ================================================================== --- modules/doctools/doctools_lang_intro.man +++ modules/doctools/doctools_lang_intro.man @@ -71,11 +71,11 @@ [keywords {doctools syntax}] [keywords markup] [keywords {semantic markup}] [description] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] }] This also shows us that all doctools documents are split into two parts, the [term header] and the [term body]. Everything coming before @@ -134,11 +134,11 @@ [example { [manpage_begin NAME SECTION VERSION] [copyright {YEAR AUTHOR}][titledesc TITLE][moddesc MODULE_TITLE] [require PACKAGE VERSION][require PACKAGE][description] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] }] has the same meaning as the example before. @@ -611,7 +611,7 @@ the processing and conversion of doctools documents, i.e. either Tcllib's easy and simple [syscmd dtplite], or Tclapps' ultra-configurable [syscmd dtp]. [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/doctools_lang_syntax.man ================================================================== --- modules/doctools/doctools_lang_syntax.man +++ modules/doctools/doctools_lang_syntax.man @@ -136,7 +136,7 @@ optd_list = [ ] { OPT_DEF paras } tkoptd_list = [ ] { TKOPTION_DEF paras } }] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/doctools_plugin_apiref.man ================================================================== --- modules/doctools/doctools_plugin_apiref.man +++ modules/doctools/doctools_plugin_apiref.man @@ -472,7 +472,7 @@ to simply return its argument without change. [list_end] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/mpexpand.man ================================================================== --- modules/doctools/mpexpand.man +++ modules/doctools/mpexpand.man @@ -101,7 +101,7 @@ [para] Possible future formats are plain text, pdf and postscript. [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools/mpformats/_markdown.tcl ================================================================== --- modules/doctools/mpformats/_markdown.tcl +++ modules/doctools/mpformats/_markdown.tcl @@ -32,12 +32,12 @@ upvar 1 $lb lines lappend lines "[Hash][Hash][Hash][Hash] $title" return } -proc Strong {text} { return [Undr][Undr]${text}[Undr][Undr] } -proc Em {text} { return [Star]${text}[Star] } +proc _Strong {text} { return [Undr][Undr]${text}[Undr][Undr] } +proc _Em {text} { return [Star]${text}[Star] } ## # # ## ### ##### ######## ## Index: modules/doctools/mpformats/_text.tcl ================================================================== --- modules/doctools/mpformats/_text.tcl +++ modules/doctools/mpformats/_text.tcl @@ -119,12 +119,40 @@ lappend lines $title lappend lines [RepeatM - $title] return } -proc Strong {text} { return *${text}* } -proc Em {text} { return _${text}_ } +proc Strong {text} { SplitLine $text _Strong } +proc Em {text} { SplitLine $text _Em } + +proc _Strong {text} { return *${text}* } +proc _Em {text} { return _${text}_ } + +proc SplitLine {text cmd} { + #puts_stderr AAA/SLI=[string map [list \1 \\1 \t \\t { } \\s] <<[join [split $text \n] >>\n<<]>>] + if {![string match *\n* $text]} { + foreach {lead content} [LeadSplit $text] break + return ${lead}[uplevel 1 [list $cmd $content]] + } + set r {} + foreach line [split $text \n] { + foreach {lead content} [LeadSplit $line] break + if {$content == {}} { + lappend r {} + continue + } + lappend r ${lead}[uplevel 1 [list $cmd $content]] + } + set text [string trimright [join $r \n]]\n + #puts_stderr AAA/SLE=[string map [list \1 \\1 \t \\t { } \\s] <<[join [split $text \n] >>\n<<]>>] + return $text +} + +proc LeadSplit {line} { + regexp {^([ \t]*)(.*)([ \t]*)$} $line -> lead content _ + list $lead $content +} # # ## ### ##### ######## ## Bulleting # # itembullet = index of the bullet to use in the next itemized list Index: modules/doctools/mpformats/_text_para.tcl ================================================================== --- modules/doctools/mpformats/_text_para.tcl +++ modules/doctools/mpformats/_text_para.tcl @@ -22,17 +22,22 @@ proc Text? {} { global __currentp ; return $__currentp } proc TextClear {} { global __currentp ; set __currentp "" } proc TextTrimLeadingSpace {} { global __currentp - regsub {^([ \t\v\f]*\n)*} $__currentp {} __currentp + regsub {^([ \t\v\f]*\x01?\n)*} $__currentp {} __currentp + return +} + +proc TextTrimTrailingSpace {} { + global __currentp + regsub {([ \t\v\f]*\x01?\n)*$} $__currentp {} __currentp + append __currentp \n return } proc TextPlain {text} { - #puts_stderr "<>" - if {[IsOff]} {return} # Note: Whenever we get plain text it is possible that a macro for # visual markup actually generated output before the expander got # to the current text. This output was captured by the expander in @@ -42,10 +47,12 @@ # which retrieves the data and also clears the capture buffer. The # latter to prevent us from retrieving it again later, after the # next macro added more data. set text [ex_ctopandclear]$text + + #puts_stderr "<>=<<[string map [list \t \\t { } \\s \n \\n \r \\r \v \\v \f \\f \1 \\1] $text]>>" # ... TODO ... Handling of example => verbatim if {[string length [string trim $text]] == 0} return Index: modules/doctools/mpformats/fmt.html ================================================================== --- modules/doctools/mpformats/fmt.html +++ modules/doctools/mpformats/fmt.html @@ -1,10 +1,10 @@ # -*- tcl -*- # # fmt.html # -# Copyright (c) 2001-2008 Andreas Kupries +# Copyright (c) 2001-2019 Andreas Kupries # # Definitions to convert a tcl based manpage definition into # a manpage based upon HTML markup. # ################################################################ @@ -12,10 +12,13 @@ dt_source _common.tcl ; # Shared code dt_source _html.tcl ; # HTML basic formatting dt_source _xref.tcl ; # xref management +global _in_example +set _in_example 0 + proc c_copyrightsymbol {} {return "[markup "&"]copy;"} proc bgcolor {} {return ""} proc border {} {return 0} proc Year {} {clock format [clock seconds] -format %Y} @@ -47,10 +50,14 @@ litc_set $l return $t } proc fmt_plain_text {text} { + global _in_example + if {$_in_example} { + set text [string map [list \\\\\n \\\n] $text] + } return $text } ################################################################ # Formatting commands. @@ -350,13 +357,15 @@ } ################################################################ proc fmt_example_begin {} { - return [para_close]\n[tag* pre class doctools_example] + global _in_example ; set _in_example 1 + return [para_close]\n[tag* pre class doctools_example] } proc fmt_example_end {} { + global _in_example ; set _in_example 0 return [tag/ pre]\n[para_open] } proc fmt_example {code} { return "[fmt_example_begin][fmt_plain_text $code][fmt_example_end]" } Index: modules/doctools/mpformats/fmt.latex ================================================================== --- modules/doctools/mpformats/fmt.latex +++ modules/doctools/mpformats/fmt.latex @@ -17,14 +17,20 @@ set _in_example 0 global _has_images set _has_images 0 +global _has_examples +set _has_examples 0 + # Called to handle plain text from the input proc fmt_plain_text {text} { global _in_example - if {$_in_example} { + if {$_in_example} { + lappend map \\\\\n \1\\textbackslash\n + lappend map \\\n \1\\textbackslash\n + set text [string map $map $text] return $text } return [texEscape $text] } @@ -50,11 +56,11 @@ ################################################################ ## Backend for LaTeX markup c_pass 1 fmt_manpage_begin {title section version} NOP c_pass 2 fmt_manpage_begin {title section version} { - global _has_images + global _has_images _has_examples set module [dt_module] set shortdesc [c_get_module] set description [c_get_title] set copyright [c_get_copyright] @@ -70,10 +76,13 @@ if {$_has_images} { append hdr "\1\\usepackage{epsfig}" \n append hdr "\1\\usepackage{epstopdf}" \n } + if {$_has_examples} { + append hdr "\1\\usepackage{alltt}" \n + } append hdr "\1\\begin\{document\}" \n append hdr "\1\\author\{[dt_user]\}" \n set titletext "" @@ -300,21 +309,24 @@ } ################################################################ proc fmt_example_begin {} { - global _in_example + global _has_examples _in_example + set _has_examples 1 set _in_example 1 - return {\begin{verbatim}} + return "\1\\begin{alltt}\n" } proc fmt_example_end {} { global _in_example set _in_example 0 - return {\end{verbatim}} + return "\1\\end{alltt}\n" } # No mapping of special characters -proc fmt_example {code} { return "\1\\begin\{verbatim\}\n${code}\n\1\\end\{verbatim\}\n" } +proc fmt_example {code} { + return [fmt_example_begin][fmt_plain_text $code][fmt_example_end] +} proc fmt_arg {text} {Underline $text} proc fmt_cmd {text} {Bold $text} proc fmt_emph {text} {Italic $text} proc fmt_opt {text} {return ?$text?} Index: modules/doctools/mpformats/fmt.markdown ================================================================== --- modules/doctools/mpformats/fmt.markdown +++ modules/doctools/mpformats/fmt.markdown @@ -35,17 +35,37 @@ if {![CAttrHas mdindent]} { CAttrSet mdindent "" } CAttrGet mdindent } + proc In! {ws} { CAttrSet mdindent $ws } -proc NewExample {} { - return [ContextNew Example { - VerbatimOn ; Example! ; Prefix+ " " +proc Example {complex} { + if {![CAttrHas exenv$complex]} { + ContextPush + set exenv [NewExample $complex] + ContextPop + CAttrSet exenv$complex $exenv + ContextCommit + } + return [CAttrGet exenv$complex] +} + +proc NewExample {complex} { + return [ContextNew Example$complex { + VerbatimOn + Example! + if {$complex} { + # Block quote + Prefix+ "> " + } else { + # Code block + Prefix+ " " + } }] ; # {} } proc NewUnorderedList {} { # Itemized list - unordered list - bullet @@ -276,11 +296,19 @@ set copyright [c_get_copyright] set pagetitle "$title - $shortdesc" MDComment "$title - $shortdesc" MDComment [c_provenance] - if {$copyright != {}} { MDComment $copyright } + if {$copyright != {}} { + # Note, multiple copyright clauses => multiple lines, comments + # are single-line => split for generation, strip MD markup for + # linebreaks, will be re-added when committing the complete + # comment block. + foreach line [split $copyright \n] { + MDComment [string trimright $line " \t\1"] + } + } MDComment "[string trimleft $title :]($section) $version $module \"$shortdesc\"" MDCDone Text [GetT header @TITLE@ $pagetitle] CloseParagraph @@ -344,41 +372,80 @@ set ct [c_get_copyright] CloseParagraph if {[llength $sa]} { Special {SEE ALSO} seealso [join [XrefList [lsort $sa] sa] ", "] } if {[llength $kw]} { Special KEYWORDS keywords [join [XrefList [lsort $kw] kw] ", "] } - if {$ca ne ""} { Special CATEGORY category $ca } - if {$ct != {}} { Special COPYRIGHT copyright $ct [Verbatim] } + if {$ca ne ""} { Special CATEGORY category $ca } + if {$ct != {}} { Special COPYRIGHT copyright $ct [Verbatim] } return } + +proc Breaks {lines} { + set r {} + foreach line $lines { lappend r $line[LB] } + return $r +} + +proc LeadSpaces {lines} { + set r {} + foreach line $lines { lappend r [LeadSpace $line] } + return $r +} + +proc LeadSpace {line} { + # Split into leading and trailing whitespace, plus content + regexp {^([ \t]*)(.*)([ \t]*)$} $line -> lead content _ + # Drop trailing spaces, make leading non-breaking, keep content (and inner spaces). + return [RepeatM " " $lead]$content +} c_pass 2 fmt_example_end {} { #puts_stderr "AAA/fmt_example_end" + # Flush markup from preceding commands into the text buffer. + TextPlain "" + TextTrimLeadingSpace + # Check for protected markdown markup in the input. If present + # this is a complex example with highlighted parts. + set complex [string match *\1* [Text?]] + + #puts_stderr "AAA/fmt_example_end/$complex" + # In examples (verbatim markup) markdown's special characters are # no such by default, thus must not be quoted. Mark them as - # protected from quoting. - set t [Mark [Text?]] + # protected from quoting. Further look for and convert + # continuation lines protected from Tcl substitution into a + # regular continuation line. + set t [Text?] + set t [string map [list \\\\\n \\\n] $t] + if {$complex} { + # Process for block quote + # - make leading spaces non-breaking + # - force linebreaks + set t [join [Breaks [LeadSpaces [split $t \n]]] {}] + } else { + # Process for code block (verbatim) + set t [Mark $t] + } TextClear Text $t + TextTrimTrailingSpace set penv [GetCurrent] if {$penv != {}} { # In a list we save the current list context, activate the # proper paragraph context and create its example # variant. After closing the paragraph using the example we # restore and reactivate the list context. ContextPush ContextSet $penv - #if {[CloseParagraph [Example]]} PAdvance - CloseParagraph [Example] + CloseParagraph [Example $complex] ContextPop } else { # In a regular paragraph we simple close the example - #if {[CloseParagraph [Example]]} PAdvance - CloseParagraph [Example] + CloseParagraph [Example $complex] } #puts_stderr "AAA/fmt_example_end/Done" return } Index: modules/doctools/mpformats/fmt.nroff ================================================================== --- modules/doctools/mpformats/fmt.nroff +++ modules/doctools/mpformats/fmt.nroff @@ -13,12 +13,24 @@ # Load shared code, load nroff support. dt_source _common.tcl dt_source _nroff.tcl +global _in_example +set _in_example 0 + ################################################################ # Define the API commands. + +# Called to handle plain text from the input +proc fmt_plain_text {text} { + global _in_example + if {$_in_example} { + set text [string map [list \\\\\n \\\n] $text] + } + return $text +} c_pass 1 fmt_manpage_begin {title section version} c_begin c_pass 2 fmt_manpage_begin {title section version} { c_begin @@ -187,24 +199,28 @@ } ################################################################ proc fmt_example_begin {} { + global _in_example ; set _in_example 1 return [nr_cs]\n } proc fmt_example_end {} { + global _in_example ; set _in_example 0 if {[dt_lnesting]} { return [nr_ce][nr_item] } nr_ce } -proc fmt_example {code} { +proc fmt_example {code} { + global _in_example ; set _in_example 1 set lines [list "" [nr_cs]] foreach line [split $code "\n"] { lappend lines [fmt_plain_text $line] } lappend lines [nr_ce] "" + set _in_example 0 return [join $lines "\n"] } proc fmt_nl {} {nr_vspace} proc fmt_arg {text} {underline $text} Index: modules/doctools/mpformats/fmt.text ================================================================== --- modules/doctools/mpformats/fmt.text +++ modules/doctools/mpformats/fmt.text @@ -463,11 +463,24 @@ } c_pass 1 fmt_example_end {} NOP c_pass 2 fmt_example_end {} { #puts_stderr "AAA/fmt_example_end" + #puts_stderr AAA/EIN=[string map [list \1 \\1 \t \\t { } \\s] <<[join [split [Text?] \n] >>\n<<]>>] + + # Flush markup from preceding commands into the text buffer. + TextPlain "" + TextTrimLeadingSpace + + # Look for and convert continuation lines protected from Tcl + # substitution into a regular continuation line. + set t [string map [list \\\\\n \\\n] [Text?]] + TextClear + Text $t + + #puts_stderr AAA/EFT=[string map [list \1\\1 \t \\t { } \\s] <<[join [split [Text?] \n] >>\n<<]>>] set penv [GetCurrent] if {$penv != {}} { # In a list we save the current list context, activate the # proper paragraph context and create its example Index: modules/doctools/mpformats/fmt.tmml ================================================================== --- modules/doctools/mpformats/fmt.tmml +++ modules/doctools/mpformats/fmt.tmml @@ -38,13 +38,33 @@ proc fmt_opt {text} { wrap $text o } c_pass 1 fmt_example_begin {} NOP c_pass 1 fmt_example_end {} NOP c_pass 1 fmt_example {code} NOP -c_pass 2 fmt_example_begin {} { sequence [xmlContext $::block] [start example] } -c_pass 2 fmt_example_end {} { end example } -c_pass 2 fmt_example {code} { sequence [xmlContext $::block] [wrap $code example] } +c_pass 2 fmt_example_begin {} { + global inexample ; set inexample 1 + sequence [xmlContext $::block] [start example] +} +c_pass 2 fmt_example_end {} { + global inexample ; set inexample 0 + end example +} +c_pass 2 fmt_example {code} { + set code [string map [list \\\\\n \\\n] $code] + sequence [xmlContext $::block] [wrap $code example] +} + +global inexample +set inexample 0 + +proc fmt_plain_text {text} { + global inexample + if {$inexample} { + set text [string map [list \\\\\n \\\n] $text] + } + return $text +} proc fmt_comment {text} {xmlComment $text} proc fmt_sectref {text {id {}}} { global SectionNames if {$id == {}} { Index: modules/doctools/mpformats/fmt.wiki ================================================================== --- modules/doctools/mpformats/fmt.wiki +++ modules/doctools/mpformats/fmt.wiki @@ -200,10 +200,18 @@ ################################################################ global textmode set textmode "" + +# NOTE: The example_begin/end combo allows for the example +# text to contain markup. The currently used verbatim +# environment will cause show the wiki markup of the example, +# instead of formatting per that markup. +# +# TODO: Strip internal markup from the example text, wiki cannot +# handle such at all. proc fmt_example_begin {} { global mode_save textmode lappend mode_save $textmode set textmode example @@ -214,11 +222,12 @@ set textmode [lindex $mode_save end] set mode_save [lrange $mode_save 0 end-1] return "\n======\n" } proc fmt_example {code} { - return "$code" + set code [string map [list \\\\\n \\\n] $code] + return "\n======\n$code\n======\n" } proc emph {text} {return ''$text''} proc strong {text} {return '''$text'''} @@ -283,13 +292,14 @@ # the initiator (i.e. list bullet). global textmode if {"$textmode" == "example"} { + set text [string map [list \\\\\n \\\n] $text] return "$text" } regsub -all "\[ \t\n\]+" $text { } text return $text } ################################################################ Index: modules/doctools/pkgIndex.tcl ================================================================== --- modules/doctools/pkgIndex.tcl +++ modules/doctools/pkgIndex.tcl @@ -1,6 +1,6 @@ if {![package vsatisfies [package provide Tcl] 8.2]} {return} -package ifneeded doctools 1.5.2 [list source [file join $dir doctools.tcl]] +package ifneeded doctools 1.5.6 [list source [file join $dir doctools.tcl]] package ifneeded doctools::toc 1.2 [list source [file join $dir doctoc.tcl]] package ifneeded doctools::idx 1.1 [list source [file join $dir docidx.tcl]] package ifneeded doctools::cvs 1 [list source [file join $dir cvs.tcl]] package ifneeded doctools::changelog 1.1 [list source [file join $dir changelog.tcl]] ADDED modules/doctools/tests/fmt/desc/26 Index: modules/doctools/tests/fmt/desc/26 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/desc/26 ADDED modules/doctools/tests/fmt/desc/27 Index: modules/doctools/tests/fmt/desc/27 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/desc/27 ADDED modules/doctools/tests/fmt/desc/28 Index: modules/doctools/tests/fmt/desc/28 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/desc/28 ADDED modules/doctools/tests/fmt/html/26 Index: modules/doctools/tests/fmt/html/26 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/html/26 @@ -0,0 +1,133 @@ + +TEST - + + + + + +
+

TEST(z) 3.14.15.926 .MODULE. ""

+

Name

+

TEST -

+
+ +

Description

+
+Example Block  More Lines \
+Ever More
+Never
+
+

............... Weiter .............

+
+Second \
+Continuing Lines \
+Done
+
+

............... Vorwaerts ..........

+
+   command    x \
+-- command --
+
+
+ +
ADDED modules/doctools/tests/fmt/html/27 Index: modules/doctools/tests/fmt/html/27 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/html/27 @@ -0,0 +1,127 @@ + +TEST - + + + + + +
+

TEST(T) 0 .MODULE. ""

+

Name

+

TEST -

+
+ +

Description

+

= = == === ===== ======== =============

+
[bar \
+  foo]
+

= = == === ===== ======== =============

+
+  many lines
+  highlighted
+
+
+

= = == === ===== ======== =============

+
+ +
ADDED modules/doctools/tests/fmt/html/28 Index: modules/doctools/tests/fmt/html/28 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/html/28 @@ -0,0 +1,119 @@ + +TEST - + + + + + +
+

TEST(z) 1.1.23.58132.1 .MODULE. ""

+

Name

+

TEST -

+
+ + + +
Index: modules/doctools/tests/fmt/latex/04 ================================================================== --- modules/doctools/tests/fmt/latex/04 +++ modules/doctools/tests/fmt/latex/04 @@ -1,23 +1,24 @@ % Generated from file '.FILE.' by tcllib/doctools with format 'latex' % Copyright (c) .COPYRIGHT. % TEST.z \documentclass{article} +\usepackage{alltt} \begin{document} -\author{@USR@} +\author{aku} \title{.MODULE. / TEST -- : } \maketitle \section{Description}\label{section1} BEGINNE HIER -\begin{verbatim} - Example Block More Lines -\end{verbatim} - -\begin{verbatim} -Inlined Example \ -Next Line -\end{verbatim} +\begin{alltt} + Example Block More Lines +\end{alltt} + +\begin{alltt} +Inlined Example \textbackslash +Next Line +\end{alltt} FERTIG \section{Copyright}\label{copyright} \begin{flushleft} Copyright (c) .COPYRIGHT.\linebreak \end{flushleft} Index: modules/doctools/tests/fmt/latex/08 ================================================================== --- modules/doctools/tests/fmt/latex/08 +++ modules/doctools/tests/fmt/latex/08 @@ -1,11 +1,12 @@ % Generated from file '.FILE.' by tcllib/doctools with format 'latex' % Copyright (c) **Copyright** % ALL.a \documentclass{article} +\usepackage{alltt} \begin{document} -\author{@USR@} +\author{aku} \title{.MODULE. / ALL -- ..THE\_MODULE.. : ..THE\_TITLE..} \maketitle \section{Synopsis}\label{synopsis} \begin{flushleft} package require {\bf AAA} @@ -81,14 +82,14 @@ DESCRIPTION ::{\bf Option}:: % \item[] \underline{NAME} TYPE (MODE) % DESCRIPTION ::?Optional?:: -\begin{verbatim} +\begin{alltt} THE ARGUMENT IS USED IN THIS AND/OR THAT MANNER -\end{verbatim} +\end{alltt} \end{itemize} % \item[] CMDNAME ... % DESCRIPTION ::{\bf Package}:: Index: modules/doctools/tests/fmt/latex/09 ================================================================== --- modules/doctools/tests/fmt/latex/09 +++ modules/doctools/tests/fmt/latex/09 @@ -1,30 +1,33 @@ % Generated from file '.FILE.' by tcllib/doctools with format 'latex' % Copyright (c) .COPYRIGHT. % TEST.z \documentclass{article} +\usepackage{alltt} \begin{document} -\author{@USR@} +\author{aku} \title{.MODULE. / TEST -- : } \maketitle \section{Description}\label{section1} lorem -\begin{verbatim} +\begin{alltt} 1 lorem ipsum dolores -\end{verbatim} +\end{alltt} ipsum -\begin{verbatim} 2 lorem ipsum dolores \end{verbatim} +\begin{alltt} + 2 lorem ipsum dolores \end{alltt} dolores -\begin{verbatim} +\begin{alltt} 3 lorem ipsum dolores -\end{verbatim} +\end{alltt} lorem -\begin{verbatim} 4 lorem ipsum dolores -\end{verbatim} +\begin{alltt} + 4 lorem ipsum dolores +\end{alltt} ipsum -\begin{verbatim} -5 lorem ipsum dolores \end{verbatim} +\begin{alltt} +5 lorem ipsum dolores \end{alltt} dolores \section{Copyright}\label{copyright} \begin{flushleft} Copyright (c) .COPYRIGHT.\linebreak \end{flushleft} Index: modules/doctools/tests/fmt/latex/13 ================================================================== --- modules/doctools/tests/fmt/latex/13 +++ modules/doctools/tests/fmt/latex/13 @@ -1,31 +1,35 @@ % Generated from file '.FILE.' by tcllib/doctools with format 'latex' % Copyright (c) .COPYRIGHT. % test-itemized-examples.1 \documentclass{article} +\usepackage{alltt} \begin{document} -\author{@USR@} +\author{aku} \title{.MODULE. / test-itemized-examples -- : } \maketitle \section{Description}\label{section1} lorem ipsum dolores \begin{itemize} % \item % -\begin{verbatim} A lorem ipsum dolores \end{verbatim} +\begin{alltt} + A lorem ipsum dolores \end{alltt} % \item % lorem ipsum dolores -\begin{verbatim} B lorem ipsum dolores \end{verbatim} +\begin{alltt} + B lorem ipsum dolores \end{alltt} lorem ipsum dolores % \item % lorem ipsum dolores -\begin{verbatim} C lorem ipsum dolores \end{verbatim} +\begin{alltt} + C lorem ipsum dolores \end{alltt} % \item % lorem ipsum dolores \end{itemize} Index: modules/doctools/tests/fmt/latex/14 ================================================================== --- modules/doctools/tests/fmt/latex/14 +++ modules/doctools/tests/fmt/latex/14 @@ -1,31 +1,35 @@ % Generated from file '.FILE.' by tcllib/doctools with format 'latex' % Copyright (c) .COPYRIGHT. % test-enumerated-examples.1 \documentclass{article} +\usepackage{alltt} \begin{document} -\author{@USR@} +\author{aku} \title{.MODULE. / test-enumerated-examples -- : } \maketitle \section{Description}\label{section1} lorem ipsum dolores \begin{enumerate} % \item % -\begin{verbatim} A1 lorem ipsum dolores \end{verbatim} +\begin{alltt} + A1 lorem ipsum dolores \end{alltt} % \item % lorem ipsum dolores -\begin{verbatim} B2 lorem ipsum dolores \end{verbatim} +\begin{alltt} + B2 lorem ipsum dolores \end{alltt} lorem ipsum dolores % \item % lorem ipsum dolores -\begin{verbatim} C3 lorem ipsum dolores \end{verbatim} +\begin{alltt} + C3 lorem ipsum dolores \end{alltt} % \item % lorem ipsum dolores \end{enumerate} Index: modules/doctools/tests/fmt/latex/15 ================================================================== --- modules/doctools/tests/fmt/latex/15 +++ modules/doctools/tests/fmt/latex/15 @@ -1,31 +1,35 @@ % Generated from file '.FILE.' by tcllib/doctools with format 'latex' % Copyright (c) .COPYRIGHT. % test-definition-examples.1 \documentclass{article} +\usepackage{alltt} \begin{document} -\author{@USR@} +\author{aku} \title{.MODULE. / test-definition-examples -- : } \maketitle \section{Description}\label{section1} lorem ipsum dolores \begin{itemize} % \item[] lorem % -\begin{verbatim} A1 lorem ipsum dolores \end{verbatim} +\begin{alltt} + A1 lorem ipsum dolores \end{alltt} % \item[] lorem % ipsum dolores -\begin{verbatim} B2 lorem ipsum dolores \end{verbatim} +\begin{alltt} + B2 lorem ipsum dolores \end{alltt} lorem ipsum dolores % \item[] lorem % ipsum dolores -\begin{verbatim} C3 lorem ipsum dolores \end{verbatim} +\begin{alltt} + C3 lorem ipsum dolores \end{alltt} % \item[] lorem % ipsum dolores \end{itemize} Index: modules/doctools/tests/fmt/latex/25 ================================================================== --- modules/doctools/tests/fmt/latex/25 +++ modules/doctools/tests/fmt/latex/25 @@ -1,17 +1,18 @@ % Generated from file '.FILE.' by tcllib/doctools with format 'latex' % Copyright (c) .COPYRIGHT. % TEST.z \documentclass{article} +\usepackage{alltt} \begin{document} \author{aku} \title{.MODULE. / TEST -- : } \maketitle \section{Description}\label{section1} -\begin{verbatim} +\begin{alltt} Special markdown __non-special__ -\end{verbatim} +\end{alltt} \section{Copyright}\label{copyright} \begin{flushleft} Copyright (c) .COPYRIGHT.\linebreak \end{flushleft} \end{document} ADDED modules/doctools/tests/fmt/latex/26 Index: modules/doctools/tests/fmt/latex/26 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/latex/26 @@ -0,0 +1,33 @@ +% Generated from file '.FILE.' by tcllib/doctools with format 'latex' +% Copyright (c) .COPYRIGHT. +% TEST.z +\documentclass{article} +\usepackage{alltt} +\begin{document} +\author{aku} +\title{.MODULE. / TEST -- : } +\maketitle +\section{Description}\label{section1} +\begin{alltt} +Example Block More Lines \textbackslash +Ever More +Never +\end{alltt} + +............... Weiter ............. + +\begin{alltt} +Second \textbackslash +Continuing Lines \textbackslash +Done +\end{alltt} +............... Vorwaerts .......... +\begin{alltt} + {\bf command} x \textbackslash +-- {\bf command} -- +\end{alltt} +\section{Copyright}\label{copyright} +\begin{flushleft} +Copyright (c) .COPYRIGHT.\linebreak +\end{flushleft} +\end{document} ADDED modules/doctools/tests/fmt/latex/27 Index: modules/doctools/tests/fmt/latex/27 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/latex/27 @@ -0,0 +1,26 @@ +% Generated from file '.FILE.' by tcllib/doctools with format 'latex' +% Copyright (c) .COPYRIGHT. +% TEST.T +\documentclass{article} +\usepackage{alltt} +\begin{document} +\author{aku} +\title{.MODULE. / TEST -- : } +\maketitle +\section{Description}\label{section1} += = == === ===== ======== ============= +\begin{alltt} +[{\bf bar} \textbackslash + foo]\end{alltt} += = == === ===== ======== ============= +\begin{alltt} +{\it many lines + highlighted +} +\end{alltt} += = == === ===== ======== ============= +\section{Copyright}\label{copyright} +\begin{flushleft} +Copyright (c) .COPYRIGHT.\linebreak +\end{flushleft} +\end{document} ADDED modules/doctools/tests/fmt/latex/28 Index: modules/doctools/tests/fmt/latex/28 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/latex/28 @@ -0,0 +1,18 @@ +% Generated from file '.FILE.' by tcllib/doctools with format 'latex' +% Copyright (c) 2019 Me +% Copyright (c) 2019 Myself +% Copyright (c) 2019 And I +% TEST.z +\documentclass{article} +\begin{document} +\author{aku} +\title{.MODULE. / TEST -- : } +\maketitle +\section{Description}\label{section1} +\section{Copyright}\label{copyright} +\begin{flushleft} +Copyright (c) 2019 Me\linebreak +Copyright (c) 2019 Myself\linebreak +Copyright (c) 2019 And I\linebreak +\end{flushleft} +\end{document} ADDED modules/doctools/tests/fmt/list/26 Index: modules/doctools/tests/fmt/list/26 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/list/26 @@ -0,0 +1,1 @@ +manpage {seealso {} keywords {} file .FILE. section z category {} module .MODULE. version 3.14.15.926 title TEST shortdesc {} desc {} fid .FILE} ADDED modules/doctools/tests/fmt/list/27 Index: modules/doctools/tests/fmt/list/27 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/list/27 @@ -0,0 +1,1 @@ +manpage {seealso {} keywords {} file .FILE. section T category {} module .MODULE. version 0 title TEST shortdesc {} desc {} fid .FILE} ADDED modules/doctools/tests/fmt/list/28 Index: modules/doctools/tests/fmt/list/28 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/list/28 @@ -0,0 +1,1 @@ +manpage {seealso {} keywords {} file .FILE. section z category {} module .MODULE. version 1.1.23.58132.1 title TEST shortdesc {} desc {} fid .FILE} Index: modules/doctools/tests/fmt/man/25 ================================================================== --- modules/doctools/tests/fmt/man/25 +++ modules/doctools/tests/fmt/man/25 @@ -1,6 +1,6 @@ -[comment { -- Example 1 }] +[comment { -- Example 2 }] [manpage_begin TEST z 3.14.15.926] [description] [example { Special markdown __non-special__ }] ADDED modules/doctools/tests/fmt/man/26 Index: modules/doctools/tests/fmt/man/26 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/man/26 @@ -0,0 +1,23 @@ +[comment { -- Example 3 }] +[manpage_begin TEST z 3.14.15.926] +[description] +[example { +Example Block \ +More Lines \\ +Ever More +Never +}] +[para] +............... Weiter ............. +[para] +[example_begin] +Second \ +Continuing Lines \\ +Done +[example_end] +............... Vorwaerts .......... +[example_begin] + [cmd command] x \\ +-- [cmd command] -- +[example_end] +[manpage_end] ADDED modules/doctools/tests/fmt/man/27 Index: modules/doctools/tests/fmt/man/27 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/man/27 @@ -0,0 +1,14 @@ +[comment { -- Example 4 }] +[manpage_begin TEST T 0] +[description] += = == === ===== ======== ============= +[example_begin][lb][cmd bar] \ + foo[rb][example_end] += = == === ===== ======== ============= +[example_begin] +[emph { many lines + highlighted +}] +[example_end] += = == === ===== ======== ============= +[manpage_end] ADDED modules/doctools/tests/fmt/man/28 Index: modules/doctools/tests/fmt/man/28 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/man/28 @@ -0,0 +1,7 @@ +[comment { -- Multi copyright }] +[manpage_begin TEST z 1.1.23.58132.1] +[copyright {2019 Me}] +[copyright {2019 Myself}] +[copyright {2019 And I}] +[description] +[manpage_end] ADDED modules/doctools/tests/fmt/markdown/26 Index: modules/doctools/tests/fmt/markdown/26 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/markdown/26 @@ -0,0 +1,38 @@ + +[//000000001]: # (TEST \- ) +[//000000002]: # (Generated from file '\.FILE\.' by tcllib/doctools with format 'markdown') +[//000000003]: # (Copyright © \.COPYRIGHT\.) +[//000000004]: # (TEST\(z\) 3\.14\.15\.926 \.MODULE\. "") + +# NAME + +TEST \- + +# Table Of Contents + + - [Table Of Contents](#toc) + + - [Description](#section1) + + - [Copyright](#copyright) + +# DESCRIPTION + + Example Block More Lines \ + Ever More + Never + +\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Weiter \.\.\.\.\.\.\.\.\.\.\.\.\. + + Second \ + Continuing Lines \ + Done + +\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Vorwaerts \.\.\.\.\.\.\.\.\.\. + +> __command__ x \\ +> \-\- __command__ \-\- + +# COPYRIGHT + +Copyright © \.COPYRIGHT\. ADDED modules/doctools/tests/fmt/markdown/27 Index: modules/doctools/tests/fmt/markdown/27 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/markdown/27 @@ -0,0 +1,35 @@ + +[//000000001]: # (TEST \- ) +[//000000002]: # (Generated from file '\.FILE\.' by tcllib/doctools with format 'markdown') +[//000000003]: # (Copyright © \.COPYRIGHT\.) +[//000000004]: # (TEST\(T\) 0 \.MODULE\. "") + +# NAME + +TEST \- + +# Table Of Contents + + - [Table Of Contents](#toc) + + - [Description](#section1) + + - [Copyright](#copyright) + +# DESCRIPTION + += = == === ===== ======== ============= + +> \[__bar__ \\ +>   foo\] + += = == === ===== ======== ============= + +>   *many lines* +>   *highlighted* + += = == === ===== ======== ============= + +# COPYRIGHT + +Copyright © \.COPYRIGHT\. ADDED modules/doctools/tests/fmt/markdown/28 Index: modules/doctools/tests/fmt/markdown/28 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/markdown/28 @@ -0,0 +1,27 @@ + +[//000000001]: # (TEST \- ) +[//000000002]: # (Generated from file '\.FILE\.' by tcllib/doctools with format 'markdown') +[//000000003]: # (Copyright © 2019 Me) +[//000000004]: # (Copyright © 2019 Myself) +[//000000005]: # (Copyright © 2019 And I) +[//000000006]: # (TEST\(z\) 1\.1\.23\.58132\.1 \.MODULE\. "") + +# NAME + +TEST \- + +# Table Of Contents + + - [Table Of Contents](#toc) + + - [Description](#section1) + + - [Copyright](#copyright) + +# DESCRIPTION + +# COPYRIGHT + +Copyright © 2019 Me +Copyright © 2019 Myself +Copyright © 2019 And I Index: modules/doctools/tests/fmt/nroff/25 ================================================================== --- modules/doctools/tests/fmt/nroff/25 +++ modules/doctools/tests/fmt/nroff/25 @@ -1,277 +1,11 @@ '\" '\" Generated from file '\&.FILE\&.' by tcllib/doctools with format 'nroff' '\" Copyright (c) \&.COPYRIGHT\&. '\" .TH "TEST" z 3\&.14\&.15\&.926 \&.MODULE\&. "" -.\" The -*- nroff -*- definitions below are for supplemental macros used -.\" in Tcl/Tk manual entries. -.\" -.\" .AP type name in/out ?indent? -.\" Start paragraph describing an argument to a library procedure. -.\" type is type of argument (int, etc.), in/out is either "in", "out", -.\" or "in/out" to describe whether procedure reads or modifies arg, -.\" and indent is equivalent to second arg of .IP (shouldn't ever be -.\" needed; use .AS below instead) -.\" -.\" .AS ?type? ?name? -.\" Give maximum sizes of arguments for setting tab stops. Type and -.\" name are examples of largest possible arguments that will be passed -.\" to .AP later. If args are omitted, default tab stops are used. -.\" -.\" .BS -.\" Start box enclosure. From here until next .BE, everything will be -.\" enclosed in one large box. -.\" -.\" .BE -.\" End of box enclosure. -.\" -.\" .CS -.\" Begin code excerpt. -.\" -.\" .CE -.\" End code excerpt. -.\" -.\" .VS ?version? ?br? -.\" Begin vertical sidebar, for use in marking newly-changed parts -.\" of man pages. The first argument is ignored and used for recording -.\" the version when the .VS was added, so that the sidebars can be -.\" found and removed when they reach a certain age. If another argument -.\" is present, then a line break is forced before starting the sidebar. -.\" -.\" .VE -.\" End of vertical sidebar. -.\" -.\" .DS -.\" Begin an indented unfilled display. -.\" -.\" .DE -.\" End of indented unfilled display. -.\" -.\" .SO ?manpage? -.\" Start of list of standard options for a Tk widget. The manpage -.\" argument defines where to look up the standard options; if -.\" omitted, defaults to "options". The options follow on successive -.\" lines, in three columns separated by tabs. -.\" -.\" .SE -.\" End of list of standard options for a Tk widget. -.\" -.\" .OP cmdName dbName dbClass -.\" Start of description of a specific option. cmdName gives the -.\" option's name as specified in the class command, dbName gives -.\" the option's name in the option database, and dbClass gives -.\" the option's class in the option database. -.\" -.\" .UL arg1 arg2 -.\" Print arg1 underlined, then print arg2 normally. -.\" -.\" .QW arg1 ?arg2? -.\" Print arg1 in quotes, then arg2 normally (for trailing punctuation). -.\" -.\" .PQ arg1 ?arg2? -.\" Print an open parenthesis, arg1 in quotes, then arg2 normally -.\" (for trailing punctuation) and then a closing parenthesis. -.\" -.\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages. -.if t .wh -1.3i ^B -.nr ^l \n(.l -.ad b -.\" # Start an argument description -.de AP -.ie !"\\$4"" .TP \\$4 -.el \{\ -. ie !"\\$2"" .TP \\n()Cu -. el .TP 15 -.\} -.ta \\n()Au \\n()Bu -.ie !"\\$3"" \{\ -\&\\$1 \\fI\\$2\\fP (\\$3) -.\".b -.\} -.el \{\ -.br -.ie !"\\$2"" \{\ -\&\\$1 \\fI\\$2\\fP -.\} -.el \{\ -\&\\fI\\$1\\fP -.\} -.\} -.. -.\" # define tabbing values for .AP -.de AS -.nr )A 10n -.if !"\\$1"" .nr )A \\w'\\$1'u+3n -.nr )B \\n()Au+15n -.\" -.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n -.nr )C \\n()Bu+\\w'(in/out)'u+2n -.. -.AS Tcl_Interp Tcl_CreateInterp in/out -.\" # BS - start boxed text -.\" # ^y = starting y location -.\" # ^b = 1 -.de BS -.br -.mk ^y -.nr ^b 1u -.if n .nf -.if n .ti 0 -.if n \l'\\n(.lu\(ul' -.if n .fi -.. -.\" # BE - end boxed text (draw box now) -.de BE -.nf -.ti 0 -.mk ^t -.ie n \l'\\n(^lu\(ul' -.el \{\ -.\" Draw four-sided box normally, but don't draw top of -.\" box if the box started on an earlier page. -.ie !\\n(^b-1 \{\ -\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' -.\} -.el \}\ -\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' -.\} -.\} -.fi -.br -.nr ^b 0 -.. -.\" # VS - start vertical sidebar -.\" # ^Y = starting y location -.\" # ^v = 1 (for troff; for nroff this doesn't matter) -.de VS -.if !"\\$2"" .br -.mk ^Y -.ie n 'mc \s12\(br\s0 -.el .nr ^v 1u -.. -.\" # VE - end of vertical sidebar -.de VE -.ie n 'mc -.el \{\ -.ev 2 -.nf -.ti 0 -.mk ^t -\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n' -.sp -1 -.fi -.ev -.\} -.nr ^v 0 -.. -.\" # Special macro to handle page bottom: finish off current -.\" # box/sidebar if in box/sidebar mode, then invoked standard -.\" # page bottom macro. -.de ^B -.ev 2 -'ti 0 -'nf -.mk ^t -.if \\n(^b \{\ -.\" Draw three-sided box if this is the box's first page, -.\" draw two sides but no top otherwise. -.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c -.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c -.\} -.if \\n(^v \{\ -.nr ^x \\n(^tu+1v-\\n(^Yu -\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c -.\} -.bp -'fi -.ev -.if \\n(^b \{\ -.mk ^y -.nr ^b 2 -.\} -.if \\n(^v \{\ -.mk ^Y -.\} -.. -.\" # DS - begin display -.de DS -.RS -.nf -.sp -.. -.\" # DE - end display -.de DE -.fi -.RE -.sp -.. -.\" # SO - start of list of standard options -.de SO -'ie '\\$1'' .ds So \\fBoptions\\fR -'el .ds So \\fB\\$1\\fR -.SH "STANDARD OPTIONS" -.LP -.nf -.ta 5.5c 11c -.ft B -.. -.\" # SE - end of list of standard options -.de SE -.fi -.ft R -.LP -See the \\*(So manual entry for details on the standard options. -.. -.\" # OP - start of full description for a single option -.de OP -.LP -.nf -.ta 4c -Command-Line Name: \\fB\\$1\\fR -Database Name: \\fB\\$2\\fR -Database Class: \\fB\\$3\\fR -.fi -.IP -.. -.\" # CS - begin code excerpt -.de CS -.RS -.nf -.ta .25i .5i .75i 1i -.. -.\" # CE - end code excerpt -.de CE -.fi -.RE -.. -.\" # UL - underline word -.de UL -\\$1\l'|0\(ul'\\$2 -.. -.\" # QW - apply quotation marks to word -.de QW -.ie '\\*(lq'"' ``\\$1''\\$2 -.\"" fix emacs highlighting -.el \\*(lq\\$1\\*(rq\\$2 -.. -.\" # PQ - apply parens and quotation marks to word -.de PQ -.ie '\\*(lq'"' (``\\$1''\\$2)\\$3 -.\"" fix emacs highlighting -.el (\\*(lq\\$1\\*(rq\\$2)\\$3 -.. -.\" # QR - quoted range -.de QR -.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3 -.\"" fix emacs highlighting -.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3 -.. -.\" # MT - "empty" string -.de MT -.QW "" -.. +.so man.macros .BS .SH NAME TEST \- .SH DESCRIPTION .CS ADDED modules/doctools/tests/fmt/nroff/26 Index: modules/doctools/tests/fmt/nroff/26 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/nroff/26 @@ -0,0 +1,42 @@ +'\" +'\" Generated from file '\&.FILE\&.' by tcllib/doctools with format 'nroff' +'\" Copyright (c) \&.COPYRIGHT\&. +'\" +.TH "TEST" z 3\&.14\&.15\&.926 \&.MODULE\&. "" +.so man.macros +.BS +.SH NAME +TEST \- +.SH DESCRIPTION +.CS + + +Example Block More Lines \\ +Ever More +Never + +.CE +.PP +\&.\&.\&.\&.\&.\&.\&.\&.\&.\&.\&.\&.\&.\&.\&. Weiter \&.\&.\&.\&.\&.\&.\&.\&.\&.\&.\&.\&.\&. +.PP +.CS + + +Second \\ +Continuing Lines \\ +Done + +.CE +\&.\&.\&.\&.\&.\&.\&.\&.\&.\&.\&.\&.\&.\&.\&. Vorwaerts \&.\&.\&.\&.\&.\&.\&.\&.\&.\&. +.CS + + + \fBcommand\fR x \\ +-- \fBcommand\fR -- + +.CE +.SH COPYRIGHT +.nf +Copyright (c) \&.COPYRIGHT\&. + +.fi ADDED modules/doctools/tests/fmt/nroff/27 Index: modules/doctools/tests/fmt/nroff/27 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/nroff/27 @@ -0,0 +1,31 @@ +'\" +'\" Generated from file '\&.FILE\&.' by tcllib/doctools with format 'nroff' +'\" Copyright (c) \&.COPYRIGHT\&. +'\" +.TH "TEST" T 0 \&.MODULE\&. "" +.so man.macros +.BS +.SH NAME +TEST \- +.SH DESCRIPTION += = == === ===== ======== ============= +.CS + +[\fBbar\fR \\ + foo] +.CE += = == === ===== ======== ============= +.CS + + +\fI many lines + highlighted +\fR + +.CE += = == === ===== ======== ============= +.SH COPYRIGHT +.nf +Copyright (c) \&.COPYRIGHT\&. + +.fi ADDED modules/doctools/tests/fmt/nroff/28 Index: modules/doctools/tests/fmt/nroff/28 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/nroff/28 @@ -0,0 +1,19 @@ +'\" +'\" Generated from file '\&.FILE\&.' by tcllib/doctools with format 'nroff' +'\" Copyright (c) 2019 Me +'\" Copyright (c) 2019 Myself +'\" Copyright (c) 2019 And I +'\" +.TH "TEST" z 1\&.1\&.23\&.58132\&.1 \&.MODULE\&. "" +.so man.macros +.BS +.SH NAME +TEST \- +.SH DESCRIPTION +.SH COPYRIGHT +.nf +Copyright (c) 2019 Me +Copyright (c) 2019 Myself +Copyright (c) 2019 And I + +.fi ADDED modules/doctools/tests/fmt/null/26 Index: modules/doctools/tests/fmt/null/26 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/null/26 ADDED modules/doctools/tests/fmt/null/27 Index: modules/doctools/tests/fmt/null/27 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/null/27 ADDED modules/doctools/tests/fmt/null/28 Index: modules/doctools/tests/fmt/null/28 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/null/28 ADDED modules/doctools/tests/fmt/syntax/26 Index: modules/doctools/tests/fmt/syntax/26 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/syntax/26 ADDED modules/doctools/tests/fmt/syntax/28 Index: modules/doctools/tests/fmt/syntax/28 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/syntax/28 ADDED modules/doctools/tests/fmt/text/26 Index: modules/doctools/tests/fmt/text/26 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/text/26 @@ -0,0 +1,32 @@ + +TEST - +Generated from file '.FILE.' by tcllib/doctools with format 'text' +TEST(z) 3.14.15.926 .MODULE. "" + +NAME +==== + +TEST - + +DESCRIPTION +=========== + +| Example Block More Lines \ +| Ever More +| Never + +............... Weiter ............. + +| Second \ +| Continuing Lines \ +| Done + +............... Vorwaerts .......... + +| command x \ +| -- command -- + +COPYRIGHT +========= + +Copyright (c) .COPYRIGHT. ADDED modules/doctools/tests/fmt/text/27 Index: modules/doctools/tests/fmt/text/27 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/text/27 @@ -0,0 +1,29 @@ + +TEST - +Generated from file '.FILE.' by tcllib/doctools with format 'text' +TEST(T) 0 .MODULE. "" + +NAME +==== + +TEST - + +DESCRIPTION +=========== + += = == === ===== ======== ============= + +| [bar \ +| foo] + += = == === ===== ======== ============= + +| _many lines_ +| _highlighted_ + += = == === ===== ======== ============= + +COPYRIGHT +========= + +Copyright (c) .COPYRIGHT. ADDED modules/doctools/tests/fmt/text/28 Index: modules/doctools/tests/fmt/text/28 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/text/28 @@ -0,0 +1,19 @@ + +TEST - +Generated from file '.FILE.' by tcllib/doctools with format 'text' +TEST(z) 1.1.23.58132.1 .MODULE. "" + +NAME +==== + +TEST - + +DESCRIPTION +=========== + +COPYRIGHT +========= + +Copyright (c) 2019 Me +Copyright (c) 2019 Myself +Copyright (c) 2019 And I ADDED modules/doctools/tests/fmt/tmml/26 Index: modules/doctools/tests/fmt/tmml/26 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/tmml/26 @@ -0,0 +1,45 @@ + + + + + + +TEST + + + + + +
+DESCRIPTION + + +Example Block More Lines \ +Ever More +Never + + + +

+............... Weiter ............. +

+

+

+ +Second \ +Continuing Lines \ +Done + + +............... Vorwaerts .......... + + + command x \ +-- command -- + + +
+ + + +
ADDED modules/doctools/tests/fmt/tmml/27 Index: modules/doctools/tests/fmt/tmml/27 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/tmml/27 @@ -0,0 +1,33 @@ + + + + + + +TEST + + + + + +
+DESCRIPTION += = == === ===== ======== ============= + +[bar \ + foo] + += = == === ===== ======== ============= + + + many lines + highlighted + + + += = == === ===== ======== ============= +
+ + + +
ADDED modules/doctools/tests/fmt/tmml/28 Index: modules/doctools/tests/fmt/tmml/28 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/tmml/28 @@ -0,0 +1,24 @@ + + + + + + + + +TEST + + + + + + + + +
+DESCRIPTION +
+ + + +
ADDED modules/doctools/tests/fmt/wiki/26 Index: modules/doctools/tests/fmt/wiki/26 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/wiki/26 @@ -0,0 +1,37 @@ +'''TEST 3.14.15.926''' '''.MODULE.''' + + + + +**DESCRIPTION** + + +====== + +Example Block More Lines \ +Ever More +Never + +====== + +............... Weiter ............. + +====== + +Second \ +Continuing Lines \ +Done + +====== +............... Vorwaerts .......... +====== + + '''command''' x \ +-- '''command''' -- + +====== + + +**COPYRIGHT** + + Copyright (c) .COPYRIGHT. ADDED modules/doctools/tests/fmt/wiki/27 Index: modules/doctools/tests/fmt/wiki/27 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/wiki/27 @@ -0,0 +1,25 @@ +'''TEST 0''' '''.MODULE.''' + + + + +**DESCRIPTION** + += = == === ===== ======== ============= +====== +['''bar''' \ + foo] +====== += = == === ===== ======== ============= +====== + +'' many lines + highlighted +'' + +====== += = == === ===== ======== ============= + +**COPYRIGHT** + + Copyright (c) .COPYRIGHT. ADDED modules/doctools/tests/fmt/wiki/28 Index: modules/doctools/tests/fmt/wiki/28 ================================================================== --- /dev/null +++ modules/doctools/tests/fmt/wiki/28 @@ -0,0 +1,14 @@ +'''TEST 1.1.23.58132.1''' '''.MODULE.''' + + + + +**DESCRIPTION** + + + +**COPYRIGHT** + + Copyright (c) 2019 Me + Copyright (c) 2019 Myself + Copyright (c) 2019 And I DELETED modules/doctools2base/config.tcl Index: modules/doctools2base/config.tcl ================================================================== --- modules/doctools2base/config.tcl +++ /dev/null @@ -1,81 +0,0 @@ -# docidx.tcl -- -# -# Generic configuration management, for use by import and export -# managers. -# -# Copyright (c) 2009 Andreas Kupries -# -# See the file "license.terms" for information on usage and redistribution -# of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# RCS: @(#) $Id: config.tcl,v 1.2 2011/11/17 08:00:45 andreas_kupries Exp $ - -# Each object manages a set of configuration variables. - -# ### ### ### ######### ######### ######### -## Requisites - -package require Tcl 8.4 -package require snit - -# ### ### ### ######### ######### ######### -## API - -snit::type ::doctools::config { - - # ### ### ### ######### ######### ######### - ## Options :: None - - # ### ### ### ######### ######### ######### - ## Creating, destruction - - # Default constructor. - # Default destructor. - - # ### ### ### ######### ######### ######### - ## Public methods. Reading and writing the configuration. - - method names {} { - return [array names myconfiguration] - } - - method get {} { - return [array get myconfiguration] - } - - method set {name {value {}}} { - # 7 instead of 3 in the condition below, because of the 4 - # implicit arguments snit is providing to each method. - if {[llength [info level 0]] == 7} { - set myconfiguration($name) $value - } elseif {![info exists myconfiguration($name)]} { - return -code error "can't read \"$name\": no such variable" - } - return $myconfiguration($name) - } - - method unset {args} { - if {![llength $args]} { lappend args * } - foreach pattern $args { - array unset myconfiguration $pattern - } - return - } - - # ### ### ### ######### ######### ######### - ## Internal methods :: None. - - # ### ### ### ######### ######### ######### - ## State :: Configuration data, Tcl array - - variable myconfiguration -array {} - - ## - # ### ### ### ######### ######### ######### -} - -# ### ### ### ######### ######### ######### -## Ready - -package provide doctools::config 0.1 -return Index: modules/doctools2base/html_cssdefaults.man ================================================================== --- modules/doctools2base/html_cssdefaults.man +++ modules/doctools2base/html_cssdefaults.man @@ -34,7 +34,7 @@ markup generated by the various HTML export plugins. [list_end] [vset CATEGORY doctools] -[include include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] DELETED modules/doctools2base/include/feedback.inc Index: modules/doctools2base/include/feedback.inc ================================================================== --- modules/doctools2base/include/feedback.inc +++ /dev/null @@ -1,23 +0,0 @@ -[section {Bugs, Ideas, Feedback}] -[vset TRACKER http://core.tcl.tk/tcllib/reportlist] -[vset LABEL {Tcllib Trackers}] - -This document, and the package it describes, will undoubtedly contain -bugs and other problems. - -Please report such in the category [emph [vset CATEGORY]] of the -[uri [vset TRACKER] [vset LABEL]]. - -Please also report any ideas for enhancements you may have for either -package and/or documentation. - -[para] -When proposing code changes, please provide [emph {unified diffs}], -i.e the output of [const {diff -u}]. - -[para] -Note further that [emph attachments] are strongly preferred over -inlined patches. Attachments can be made by going to the [const Edit] -form of the ticket immediately after its creation, and then using the -left-most button in the secondary navigation bar. - Index: modules/doctools2base/nroff_manmacros.man ================================================================== --- modules/doctools2base/nroff_manmacros.man +++ modules/doctools2base/nroff_manmacros.man @@ -34,7 +34,7 @@ generated by the various NROFF export plugins. [list_end] [vset CATEGORY doctools] -[include include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] DELETED modules/doctools2base/paths.tcl Index: modules/doctools2base/paths.tcl ================================================================== --- modules/doctools2base/paths.tcl +++ /dev/null @@ -1,76 +0,0 @@ -# docidx.tcl -- -# -# Generic path list management, for use by import management. -# -# Copyright (c) 2009 Andreas Kupries -# -# See the file "license.terms" for information on usage and redistribution -# of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# RCS: @(#) $Id: paths.tcl,v 1.2 2009/04/29 02:09:46 andreas_kupries Exp $ - -# Each object manages a list of paths. - -# ### ### ### ######### ######### ######### -## Requisites - -package require Tcl 8.4 -package require snit - -# ### ### ### ######### ######### ######### -## API - -snit::type ::doctools::paths { - - # ### ### ### ######### ######### ######### - ## Options :: None - - # ### ### ### ######### ######### ######### - ## Creation, destruction - - # Default constructor. - # Default destructor. - - # ### ### ### ######### ######### ######### - ## Methods :: Querying and manipulating the list of paths. - - method paths {} { - return $mypaths - } - - method add {path} { - set pos [lsearch $mypaths $path] - if {$pos >= 0 } return - lappend mypaths $path - return - } - - method remove {path} { - set pos [lsearch $mypaths $path] - if {$pos < 0} return - set mypaths [lreplace $mypaths $pos $pos] - return - } - - method clear {} { - set mypaths {} - return - } - - # ### ### ### ######### ######### ######### - ## Internal methods :: None - - # ### ### ### ######### ######### ######### - ## State :: List of paths. - - variable mypaths {} - - ## - # ### ### ### ######### ######### ######### -} - -# ### ### ### ######### ######### ######### -## Ready - -package provide doctools::paths 0.1 -return Index: modules/doctools2base/pkgIndex.tcl ================================================================== --- modules/doctools2base/pkgIndex.tcl +++ modules/doctools2base/pkgIndex.tcl @@ -2,18 +2,15 @@ # Packages for the doctools {idx,toc,doc} v2 implementation # (still v1.1 doc{idx,toc} languages). # Supporting packages -# - Handling configuration variables, and include paths. # - Handling text generation, the nroff man.macros definitions, # HTML/XML generation, and the default CSS style # - Handling of message catalogs as packages. # - Recursive descent parser for Tcl strings (as expected by 'subst -novariables'). -package ifneeded doctools::config 0.1 [list source [file join $dir config.tcl]] -package ifneeded doctools::paths 0.1 [list source [file join $dir paths.tcl]] package ifneeded doctools::text 0.1 [list source [file join $dir text.tcl]] package ifneeded doctools::nroff::man_macros 0.1 [list source [file join $dir nroff_manmacros.tcl]] package ifneeded doctools::html 0.1 [list source [file join $dir html.tcl]] package ifneeded doctools::html::cssdefaults 0.1 [list source [file join $dir html_cssdefaults.tcl]] package ifneeded doctools::msgcat 0.1 [list source [file join $dir msgcat.tcl]] Index: modules/doctools2base/tcl_parse.man ================================================================== --- modules/doctools2base/tcl_parse.man +++ modules/doctools2base/tcl_parse.man @@ -178,7 +178,7 @@ All leaves of the tree are either Text or Command nodes. Word nodes cannot be leaves. [list_end] [vset CATEGORY doctools] -[include include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools2base/tcllib_msgcat.man ================================================================== --- modules/doctools2base/tcllib_msgcat.man +++ modules/doctools2base/tcllib_msgcat.man @@ -61,7 +61,7 @@ result of [cmd msgcat::mcpreferences]. [list_end] [vset CATEGORY doctools] -[include include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools2idx/container.test ================================================================== --- modules/doctools2idx/container.test +++ modules/doctools2idx/container.test @@ -1,12 +1,10 @@ # -*- tcl -*- # idx.test: Tests for the doctools::idx package. Index management. # -# Copyright (c) 2009 by Andreas Kupries +# Copyright (c) 2009-2019 by Andreas Kupries # All rights reserved. -# -# RCS: @(#) $Id: container.test,v 1.2 2009/04/29 02:10:34 andreas_kupries Exp $ # ------------------------------------------------------------------------- source [file join \ [file dirname [file dirname [file join [pwd] [info script]]]] \ @@ -17,15 +15,15 @@ support { use struct/list.tcl struct::list use snit/snit.tcl snit use fileutil/fileutil.tcl fileutil + use fileutil/paths.tcl fileutil::paths use log/logger.tcl logger use pluginmgr/pluginmgr.tcl pluginmgr + use struct/map.tcl struct::map - use doctools2base/config.tcl doctools::config - use doctools2base/paths.tcl doctools::paths useLocal export.tcl doctools::idx::export useLocal import.tcl doctools::idx::import use doctools2base/nroff_manmacros.tcl doctools::nroff::man_macros source [tcllibPath doctools2base/tests/common] Index: modules/doctools2idx/export.tcl ================================================================== --- modules/doctools2idx/export.tcl +++ modules/doctools2idx/export.tcl @@ -1,25 +1,23 @@ # export.tcl -- # # Exporting indices into other formats. # -# Copyright (c) 2009-2018 Andreas Kupries +# Copyright (c) 2009-2019 Andreas Kupries # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# RCS: @(#) $Id: export.tcl,v 1.1 2009/04/01 04:28:37 andreas_kupries Exp $ # Each object manages a set of plugins for the conversion of keyword # indices into some textual representation. I.e. this object manages # the conversion to specialized serializations of keyword indices. # ### ### ### ######### ######### ######### ## Requisites package require Tcl 8.4 -package require doctools::config +package require struct::map package require doctools::idx::structure package require pluginmgr package require snit # ### ### ### ######### ######### ######### @@ -32,11 +30,11 @@ # ### ### ### ######### ######### ######### ## Creation, destruction. constructor {} { - install myconfig using ::doctools::config ${selfns}::config + install myconfig using ::struct::map ${selfns}::config return } destructor { $myconfig destroy @@ -119,7 +117,7 @@ } # ### ### ### ######### ######### ######### ## Ready -package provide doctools::idx::export 0.2 +package provide doctools::idx::export 0.2.1 return Index: modules/doctools2idx/export.test ================================================================== --- modules/doctools2idx/export.test +++ modules/doctools2idx/export.test @@ -1,12 +1,10 @@ # -*- tcl -*- # idx.test: tests for the doctools::idx package. # -# Copyright (c) 2009 by Andreas Kupries +# Copyright (c) 2009-2019 by Andreas Kupries # All rights reserved. -# -# RCS: @(#) $Id: export.test,v 1.2 2009/04/29 02:10:34 andreas_kupries Exp $ # ------------------------------------------------------------------------- source [file join \ [file dirname [file dirname [file join [pwd] [info script]]]] \ @@ -20,12 +18,12 @@ use struct/list.tcl struct::list use snit/snit.tcl snit use log/logger.tcl logger use pluginmgr/pluginmgr.tcl pluginmgr + use struct/map.tcl struct::map - use doctools2base/config.tcl doctools::config useLocal structure.tcl doctools::idx::structure use doctools2base/nroff_manmacros.tcl doctools::nroff::man_macros source [tcllibPath doctools2base/tests/common] } @@ -75,35 +73,35 @@ doctools::idx::export E } -body { E config names X } -cleanup { E destroy -} -returnCodes error -result {wrong # args: should be "::doctools::config::Snit_methodnames type selfns win self"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodnames type selfns win self"} test doctools-idx-export-6.0 {config get, wrong#args} -setup { doctools::idx::export E } -body { E config get X } -cleanup { E destroy -} -returnCodes error -result {wrong # args: should be "::doctools::config::Snit_methodget type selfns win self"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodget type selfns win self"} test doctools-idx-export-7.0 {config set, wrong#args} -setup { doctools::idx::export E } -body { E config set } -cleanup { E destroy -} -returnCodes error -result {wrong # args: should be "::doctools::config::Snit_methodset type selfns win self name ?value?"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodset type selfns win self name ?value?"} test doctools-idx-export-7.1 {config set, wrong#args} -setup { doctools::idx::export E } -body { E config set N V X } -cleanup { E destroy -} -returnCodes error -result {wrong # args: should be "::doctools::config::Snit_methodset type selfns win self name ?value?"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodset type selfns win self name ?value?"} # ------------------------------------------------------------------------- test doctools-idx-export-12.0 {config set, define single var} -setup { doctools::idx::export E Index: modules/doctools2idx/export_docidx.man ================================================================== --- modules/doctools2idx/export_docidx.man +++ modules/doctools2idx/export_docidx.man @@ -1,7 +1,7 @@ [comment {-*- tcl -*- --- doctools ---}] [vset PACKAGE docidx] [vset NAME docidx] [vset REQUIRE null] [vset CONFIG docidx] -[vset VERSION 0.1] +[vset VERSION 0.2.1] [include include/export/plugin.inc] Index: modules/doctools2idx/idx_container.man ================================================================== --- modules/doctools2idx/idx_container.man +++ modules/doctools2idx/idx_container.man @@ -290,7 +290,7 @@ [list_end] [include include/serialization.inc] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools2idx/idx_export.man ================================================================== --- modules/doctools2idx/idx_export.man +++ modules/doctools2idx/idx_export.man @@ -1,6 +1,6 @@ -[vset VERSION 0.2] +[vset VERSION 0.2.1] [comment {-*- tcl -*- doctools manpage}] [manpage_begin doctools::idx::export n [vset VERSION]] [keywords conversion] [keywords docidx] [keywords documentation] @@ -18,17 +18,17 @@ [keywords reference] [keywords {tcler's wiki}] [keywords text] [keywords url] [keywords wiki] -[copyright {2009-2018 Andreas Kupries }] +[copyright {2009-2019 Andreas Kupries }] [moddesc {Documentation tools}] [titledesc {Exporting keyword indices}] [category {Documentation tools}] [require doctools::idx::export [opt [vset VERSION]]] [require Tcl 8.4] -[require doctools::config] +[require struct::map] [require doctools::idx::structure] [require snit] [require pluginmgr] [description] @@ -303,7 +303,7 @@ [list_end] [include include/serialization.inc] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools2idx/idx_import.man ================================================================== --- modules/doctools2idx/idx_import.man +++ modules/doctools2idx/idx_import.man @@ -1,6 +1,6 @@ -[vset VERSION 0.2] +[vset VERSION 0.2.1] [comment {-*- tcl -*- doctools manpage}] [manpage_begin doctools::idx::import n [vset VERSION]] [keywords conversion] [keywords docidx] [keywords documentation] @@ -12,17 +12,17 @@ [keywords markup] [keywords parsing] [keywords plugin] [keywords reference] [keywords url] -[copyright {2009-2018 Andreas Kupries }] +[copyright {2009-2019 Andreas Kupries }] [moddesc {Documentation tools}] [titledesc {Importing keyword indices}] [category {Documentation tools}] [require doctools::idx::import [opt [vset VERSION]]] [require Tcl 8.4] -[require doctools::config] +[require struct::map] [require doctools::idx::structure] [require snit] [require pluginmgr] [description] @@ -389,7 +389,7 @@ [list_end] [include include/serialization.inc] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools2idx/idx_introduction.man ================================================================== --- modules/doctools2idx/idx_introduction.man +++ modules/doctools2idx/idx_introduction.man @@ -140,7 +140,7 @@ [section {Package Overview}] [include include/dependencies.inc] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools2idx/idx_parse.man ================================================================== --- modules/doctools2idx/idx_parse.man +++ modules/doctools2idx/idx_parse.man @@ -169,7 +169,7 @@ [include include/format/docidx.inc] [include include/serialization.inc] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools2idx/idx_structure.man ================================================================== --- modules/doctools2idx/idx_structure.man +++ modules/doctools2idx/idx_structure.man @@ -123,7 +123,7 @@ [list_end] [include include/serialization.inc] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools2idx/import.tcl ================================================================== --- modules/doctools2idx/import.tcl +++ modules/doctools2idx/import.tcl @@ -1,27 +1,25 @@ # import.tcl -- # # Importing indices into other formats. # -# Copyright (c) 2009-2018 Andreas Kupries +# Copyright (c) 2009-2019 Andreas Kupries # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# RCS: @(#) $Id: import.tcl,v 1.2 2011/11/17 08:00:45 andreas_kupries Exp $ # Each object manages a set of plugins for the conversion of keyword # indices into some textual representation. I.e. this object manages # the conversion to specialized serializations of keyword indices. # ### ### ### ######### ######### ######### ## Requisites package require Tcl 8.4 -package require doctools::config +package require struct::map package require doctools::idx::structure -package require doctools::paths +package require fileutil::paths package require pluginmgr package require snit # ### ### ### ######### ######### ######### ## API @@ -33,12 +31,12 @@ # ### ### ### ######### ######### ######### ## Creation, destruction. constructor {} { - install myconfig using ::doctools::config ${selfns}::config - install myinclude using ::doctools::paths ${selfns}::include + install myconfig using ::struct::map ${selfns}::config + install myinclude using ::fileutil::paths ${selfns}::include return } destructor { $myconfig destroy @@ -185,7 +183,7 @@ } # ### ### ### ######### ######### ######### ## Ready -package provide doctools::idx::import 0.2 +package provide doctools::idx::import 0.2.1 return Index: modules/doctools2idx/import.test ================================================================== --- modules/doctools2idx/import.test +++ modules/doctools2idx/import.test @@ -1,13 +1,11 @@ # -*- tcl -*- # -- idx_import.test: # -- Tests for package "doctools::idx::import": Management of import plugins. # -# Copyright (c) 2009 by Andreas Kupries +# Copyright (c) 2009-2019 by Andreas Kupries # All rights reserved. -# -# RCS: @(#) $Id: import.test,v 1.1 2009/04/01 04:28:37 andreas_kupries Exp $ # ------------------------------------------------------------------------- source [file join \ [file dirname [file dirname [file join [pwd] [info script]]]] \ @@ -18,15 +16,14 @@ support { use struct/list.tcl struct::list use snit/snit.tcl snit use fileutil/fileutil.tcl fileutil + use fileutil/paths.tcl fileutil::paths use log/logger.tcl logger use pluginmgr/pluginmgr.tcl pluginmgr - - use doctools2base/config.tcl doctools::config - use doctools2base/paths.tcl doctools::paths + use struct/map.tcl struct::map source [tcllibPath doctools2base/tests/common] } testing { useLocalKeep import.tcl doctools::idx::import @@ -122,85 +119,88 @@ doctools::idx::import I } -body { I config names X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::config::Snit_methodnames type selfns win self"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodnames type selfns win self"} test doctools-idx-import-6.0 {config get, wrong#args} -setup { doctools::idx::import I } -body { I config get X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::config::Snit_methodget type selfns win self"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodget type selfns win self"} test doctools-idx-import-7.0 {config set, wrong#args} -setup { doctools::idx::import I } -body { I config set } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::config::Snit_methodset type selfns win self name ?value?"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodset type selfns win self name ?value?"} test doctools-idx-import-7.1 {config set, wrong#args} -setup { doctools::idx::import I } -body { I config set N V X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::config::Snit_methodset type selfns win self name ?value?"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodset type selfns win self name ?value?"} # config unset - accepts any number of arguments. +# ------------------------------------------------------------------------- +## `include paths` component, provided via fileutil::paths, search path for includes + test doctools-idx-import-8.0 {include paths, wrong#args} -setup { doctools::idx::import I } -body { I include paths X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::paths::Snit_methodpaths type selfns win self"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodpaths type selfns win self"} test doctools-idx-import-9.0 {include clear, wrong#args} -setup { doctools::idx::import I } -body { I include clear X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::paths::Snit_methodclear type selfns win self"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodclear type selfns win self"} test doctools-idx-import-10.0 {include add, wrong#args} -setup { doctools::idx::import I } -body { I include add } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::paths::Snit_methodadd type selfns win self path"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodadd type selfns win self path"} test doctools-idx-import-10.1 {include add, wrong#args} -setup { doctools::idx::import I } -body { I include add P X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::paths::Snit_methodadd type selfns win self path"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodadd type selfns win self path"} test doctools-idx-import-11.0 {include remove, wrong#args} -setup { doctools::idx::import I } -body { I include remove } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::paths::Snit_methodremove type selfns win self path"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodremove type selfns win self path"} test doctools-idx-import-11.1 {include remove, wrong#args} -setup { doctools::idx::import I } -body { I include remove P X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::paths::Snit_methodremove type selfns win self path"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodremove type selfns win self path"} # ------------------------------------------------------------------------- test doctools-idx-import-12.0 {config set, define single var} -setup { doctools::idx::import I Index: modules/doctools2idx/include/dependencies.inc ================================================================== --- modules/doctools2idx/include/dependencies.inc +++ modules/doctools2idx/include/dependencies.inc @@ -6,11 +6,11 @@ ~~ | ~~ doctools::idx::export ~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ doctools::idx::import | | | +---------------+-------------------------+ | +------------------+---------------+-----------------------+---------------+ | | | | | | | | | -doctools::config = | | | = doctools::include doctools::config doctools::paths +struct::map = | | | = doctools::include struct::map fileutil::paths | | | | | doctools::idx::export::<*> | | | doctools::idx::import::<*> docidx | | | docidx, json json | | | | \\ html | | | doctools::idx::parse \\ Index: modules/doctools2idx/include/export/plugin.inc ================================================================== --- modules/doctools2idx/include/export/plugin.inc +++ modules/doctools2idx/include/export/plugin.inc @@ -1,8 +1,8 @@ [comment {-*- tcl -*- --- !doctools ---}] [manpage_begin doctools::idx::export::[vset PACKAGE] n [vset VERSION]] -[copyright {2009 Andreas Kupries }] +[copyright {2009-2019 Andreas Kupries }] [moddesc {Documentation tools}] [titledesc "[vset NAME] export plugin"] [category {Text formatter plugin}] [require Tcl 8.4] [require doctools::idx::export::[vset PACKAGE] [opt [vset VERSION]]] @@ -49,7 +49,7 @@ [include config/[vset CONFIG].inc] [include ../serialization.inc] [vset CATEGORY doctools] -[include ../../../doctools2base/include/feedback.inc] +[include ../../../common-text/feedback.inc] [manpage_end] Index: modules/doctools2idx/include/import/plugin.inc ================================================================== --- modules/doctools2idx/include/import/plugin.inc +++ modules/doctools2idx/include/import/plugin.inc @@ -1,13 +1,14 @@ [comment {-*- tcl -*- --- !doctools ---}] -[manpage_begin doctools::idx::import::[vset PACKAGE] n 0.1] -[copyright {2009 Andreas Kupries }] +[vset VERSION 0.2.1] +[manpage_begin doctools::idx::import::[vset PACKAGE] n [vset VERSION]] +[copyright {2009-2019 Andreas Kupries }] [moddesc {Documentation tools}] [titledesc "[vset NAME] import plugin"] [category {Text formatter plugin}] -[require Tcl 8.4] -[require doctools::idx::import::[vset PACKAGE] [opt 0.1]] +[require Tcl 8.5] +[require doctools::idx::import::[vset PACKAGE] [opt [vset VERSION]]] [include format/[vset REQUIRE].inc] [keywords doctools index deserialization import [vset NAME]] [description] This package implements the doctools keyword index import plugin for @@ -49,7 +50,7 @@ [include config/[vset CONFIG].inc] [include ../serialization.inc] [vset CATEGORY doctools] -[include ../../../doctools2base/include/feedback.inc] +[include ../../../common-text/feedback.inc] [manpage_end] Index: modules/doctools2idx/include/msgcat.inc ================================================================== --- modules/doctools2idx/include/msgcat.inc +++ modules/doctools2idx/include/msgcat.inc @@ -40,7 +40,7 @@ This package has no exported API. [vset CATEGORY doctools] -[include ../../doctools2base/include/feedback.inc] +[include ../../common-text/feedback.inc] [manpage_end] Index: modules/doctools2idx/pkgIndex.tcl ================================================================== --- modules/doctools2idx/pkgIndex.tcl +++ modules/doctools2idx/pkgIndex.tcl @@ -7,14 +7,12 @@ # - Export and import management # - Export and import plugins # - Parser for docidx markup, and handling serializations # - Message catalogs for the parser -package ifneeded doctools::idx 2 [list source [file join $dir container.tcl]] - -package ifneeded doctools::idx::export 0.2 [list source [file join $dir export.tcl]] -package ifneeded doctools::idx::import 0.2 [list source [file join $dir import.tcl]] +package ifneeded doctools::idx 2 [list source [file join $dir container.tcl]] +package ifneeded doctools::idx::export 0.2.1 [list source [file join $dir export.tcl]] package ifneeded doctools::idx::export::docidx 0.1 [list source [file join $dir export_docidx.tcl]] package ifneeded doctools::idx::export::html 0.2 [list source [file join $dir export_html.tcl]] package ifneeded doctools::idx::export::json 0.1 [list source [file join $dir export_json.tcl]] package ifneeded doctools::idx::export::nroff 0.3 [list source [file join $dir export_nroff.tcl]] @@ -29,5 +27,9 @@ package ifneeded doctools::msgcat::idx::c 0.1 [list source [file join $dir msgcat_c.tcl]] package ifneeded doctools::msgcat::idx::de 0.1 [list source [file join $dir msgcat_de.tcl]] package ifneeded doctools::msgcat::idx::en 0.1 [list source [file join $dir msgcat_en.tcl]] package ifneeded doctools::msgcat::idx::fr 0.1 [list source [file join $dir msgcat_fr.tcl]] + +if {![package vsatisfies [package provide Tcl] 8.5]} {return} + +package ifneeded doctools::idx::import 0.2.1 [list source [file join $dir import.tcl]] Index: modules/doctools2toc/container.test ================================================================== --- modules/doctools2toc/container.test +++ modules/doctools2toc/container.test @@ -1,12 +1,10 @@ # -*- tcl -*- # toc.test: Tests for the doctools::toc package. ToC management. # -# Copyright (c) 2009 by Andreas Kupries +# Copyright (c) 2009-2019 by Andreas Kupries # All rights reserved. -# -# RCS: @(#) $Id: container.test,v 1.3 2009/11/15 05:50:03 andreas_kupries Exp $ # ------------------------------------------------------------------------- source [file join \ [file dirname [file dirname [file join [pwd] [info script]]]] \ @@ -20,15 +18,15 @@ TestAccelInit struct::tree use struct/list.tcl struct::list use snit/snit.tcl snit use fileutil/fileutil.tcl fileutil + use fileutil/paths.tcl fileutil::paths use log/logger.tcl logger use pluginmgr/pluginmgr.tcl pluginmgr + use struct/map.tcl struct::map - use doctools2base/config.tcl doctools::config - use doctools2base/paths.tcl doctools::paths useLocal export.tcl doctools::toc::export useLocal import.tcl doctools::toc::import use doctools2base/nroff_manmacros.tcl doctools::nroff::man_macros source [tcllibPath doctools2base/tests/common] Index: modules/doctools2toc/export.tcl ================================================================== --- modules/doctools2toc/export.tcl +++ modules/doctools2toc/export.tcl @@ -1,25 +1,23 @@ # export.tcl -- # # Exporting indices into other formats. # -# Copyright (c) 2009-2018 Andreas Kupries +# Copyright (c) 2009-2019 Andreas Kupries # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# RCS: @(#) $Id: export.tcl,v 1.2 2009/11/15 05:50:03 andreas_kupries Exp $ # Each object manages a set of plugins for the conversion of keyword # indices into some textual representation. I.e. this object manages # the conversion to specialized serializations of keyword indices. # ### ### ### ######### ######### ######### ## Requisites package require Tcl 8.4 -package require doctools::config +package require struct::map package require doctools::toc::structure package require pluginmgr package require snit # ### ### ### ######### ######### ######### @@ -32,11 +30,11 @@ # ### ### ### ######### ######### ######### ## Creation, destruction. constructor {} { - install myconfig using ::doctools::config ${selfns}::config + install myconfig using ::struct::map ${selfns}::config return } destructor { $myconfig destroy @@ -119,7 +117,7 @@ } # ### ### ### ######### ######### ######### ## Ready -package provide doctools::toc::export 0.2 +package provide doctools::toc::export 0.2.1 return Index: modules/doctools2toc/export.test ================================================================== --- modules/doctools2toc/export.test +++ modules/doctools2toc/export.test @@ -1,12 +1,10 @@ # -*- tcl -*- # toc.test: tests for the doctools::toc package. # -# Copyright (c) 2009 by Andreas Kupries +# Copyright (c) 2009-2019 by Andreas Kupries # All rights reserved. -# -# RCS: @(#) $Id: export.test,v 1.2 2009/04/29 02:10:56 andreas_kupries Exp $ # ------------------------------------------------------------------------- source [file join \ [file dirname [file dirname [file join [pwd] [info script]]]] \ @@ -20,12 +18,12 @@ use struct/list.tcl struct::list use snit/snit.tcl snit use log/logger.tcl logger use pluginmgr/pluginmgr.tcl pluginmgr + use struct/map.tcl struct::map - use doctools2base/config.tcl doctools::config useLocal structure.tcl doctools::toc::structure use doctools2base/nroff_manmacros.tcl doctools::nroff::man_macros source [tcllibPath doctools2base/tests/common] } @@ -75,35 +73,35 @@ doctools::toc::export E } -body { E config names X } -cleanup { E destroy -} -returnCodes error -result {wrong # args: should be "::doctools::config::Snit_methodnames type selfns win self"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodnames type selfns win self"} test doctools-toc-export-6.0 {config get, wrong#args} -setup { doctools::toc::export E } -body { E config get X } -cleanup { E destroy -} -returnCodes error -result {wrong # args: should be "::doctools::config::Snit_methodget type selfns win self"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodget type selfns win self"} test doctools-toc-export-7.0 {config set, wrong#args} -setup { doctools::toc::export E } -body { E config set } -cleanup { E destroy -} -returnCodes error -result {wrong # args: should be "::doctools::config::Snit_methodset type selfns win self name ?value?"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodset type selfns win self name ?value?"} test doctools-toc-export-7.1 {config set, wrong#args} -setup { doctools::toc::export E } -body { E config set N V X } -cleanup { E destroy -} -returnCodes error -result {wrong # args: should be "::doctools::config::Snit_methodset type selfns win self name ?value?"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodset type selfns win self name ?value?"} # ------------------------------------------------------------------------- test doctools-toc-export-12.0 {config set, define single var} -setup { doctools::toc::export E Index: modules/doctools2toc/export_doctoc.man ================================================================== --- modules/doctools2toc/export_doctoc.man +++ modules/doctools2toc/export_doctoc.man @@ -1,7 +1,7 @@ [comment {-*- tcl -*- --- doctools ---}] [vset PACKAGE doctoc] [vset NAME doctoc] [vset REQUIRE null] [vset CONFIG doctoc] -[vset VERSION 0.1] +[vset VERSION 0.2.1] [include include/export/plugin.inc] Index: modules/doctools2toc/import.tcl ================================================================== --- modules/doctools2toc/import.tcl +++ modules/doctools2toc/import.tcl @@ -1,27 +1,25 @@ # import.tcl -- # # Importing indices into other formats. # -# Copyright (c) 2009-2018 Andreas Kupries +# Copyright (c) 2009-2019 Andreas Kupries # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# RCS: @(#) $Id: import.tcl,v 1.3 2011/11/17 08:00:45 andreas_kupries Exp $ # Each object manages a set of plugins for the conversion of keyword # indices into some textual representation. I.e. this object manages # the conversion to specialized serializations of keyword indices. # ### ### ### ######### ######### ######### ## Requisites package require Tcl 8.4 -package require doctools::config +package require struct::map package require doctools::toc::structure -package require doctools::paths +package require fileutil::paths package require pluginmgr package require snit # ### ### ### ######### ######### ######### ## API @@ -33,12 +31,12 @@ # ### ### ### ######### ######### ######### ## Creation, destruction. constructor {} { - install myconfig using ::doctools::config ${selfns}::config - install myinclude using ::doctools::paths ${selfns}::include + install myconfig using ::struct::map ${selfns}::config + install myinclude using ::fileutil::paths ${selfns}::include return } destructor { $myconfig destroy @@ -185,7 +183,7 @@ } # ### ### ### ######### ######### ######### ## Ready -package provide doctools::toc::import 0.2 +package provide doctools::toc::import 0.2.1 return Index: modules/doctools2toc/import.test ================================================================== --- modules/doctools2toc/import.test +++ modules/doctools2toc/import.test @@ -1,13 +1,11 @@ # -*- tcl -*- # -- toc_import.test: # -- Tests for package "doctools::toc::import": Management of import plugins. # -# Copyright (c) 2009 by Andreas Kupries +# Copyright (c) 2009-2019 by Andreas Kupries # All rights reserved. -# -# RCS: @(#) $Id: import.test,v 1.1 2009/04/18 21:14:18 andreas_kupries Exp $ # ------------------------------------------------------------------------- source [file join \ [file dirname [file dirname [file join [pwd] [info script]]]] \ @@ -18,15 +16,14 @@ support { use struct/list.tcl struct::list use snit/snit.tcl snit use fileutil/fileutil.tcl fileutil + use fileutil/paths.tcl fileutil::paths use log/logger.tcl logger use pluginmgr/pluginmgr.tcl pluginmgr - - use doctools2base/config.tcl doctools::config - use doctools2base/paths.tcl doctools::paths + use struct/map.tcl struct::map source [tcllibPath doctools2base/tests/common] } testing { useLocalKeep import.tcl doctools::toc::import @@ -122,85 +119,88 @@ doctools::toc::import I } -body { I config names X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::config::Snit_methodnames type selfns win self"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodnames type selfns win self"} test doctools-toc-import-6.0 {config get, wrong#args} -setup { doctools::toc::import I } -body { I config get X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::config::Snit_methodget type selfns win self"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodget type selfns win self"} test doctools-toc-import-7.0 {config set, wrong#args} -setup { doctools::toc::import I } -body { I config set } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::config::Snit_methodset type selfns win self name ?value?"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodset type selfns win self name ?value?"} test doctools-toc-import-7.1 {config set, wrong#args} -setup { doctools::toc::import I } -body { I config set N V X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::config::Snit_methodset type selfns win self name ?value?"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodset type selfns win self name ?value?"} # config unset - accepts any number of arguments. +# ------------------------------------------------------------------------- +## `include paths` component, provided via fileutil::paths, search path for includes + test doctools-toc-import-8.0 {include paths, wrong#args} -setup { doctools::toc::import I } -body { I include paths X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::paths::Snit_methodpaths type selfns win self"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodpaths type selfns win self"} test doctools-toc-import-9.0 {include clear, wrong#args} -setup { doctools::toc::import I } -body { I include clear X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::paths::Snit_methodclear type selfns win self"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodclear type selfns win self"} test doctools-toc-import-10.0 {include add, wrong#args} -setup { doctools::toc::import I } -body { I include add } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::paths::Snit_methodadd type selfns win self path"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodadd type selfns win self path"} test doctools-toc-import-10.1 {include add, wrong#args} -setup { doctools::toc::import I } -body { I include add P X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::paths::Snit_methodadd type selfns win self path"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodadd type selfns win self path"} test doctools-toc-import-11.0 {include remove, wrong#args} -setup { doctools::toc::import I } -body { I include remove } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::paths::Snit_methodremove type selfns win self path"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodremove type selfns win self path"} test doctools-toc-import-11.1 {include remove, wrong#args} -setup { doctools::toc::import I } -body { I include remove P X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::doctools::paths::Snit_methodremove type selfns win self path"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodremove type selfns win self path"} # ------------------------------------------------------------------------- test doctools-toc-import-12.0 {config set, define single var} -setup { doctools::toc::import I Index: modules/doctools2toc/include/dependencies.inc ================================================================== --- modules/doctools2toc/include/dependencies.inc +++ modules/doctools2toc/include/dependencies.inc @@ -6,11 +6,11 @@ ~~ | ~~ doctools::toc::export ~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ doctools::toc::import | | | +---------------+-------------------------+ | +------------------+---------------+-----------------------+---------------+ | | | | | | | | | -doctools::config = | | | = doctools::include doctools::config doctools::paths +struct:map = | | | = doctools::include struct::map fileutil::paths | | | | | doctools::toc::export::<*> | | | doctools::toc::import::<*> doctoc | | | doctoc, json json | | | | \\ html | | | doctools::toc::parse \\ Index: modules/doctools2toc/include/export/plugin.inc ================================================================== --- modules/doctools2toc/include/export/plugin.inc +++ modules/doctools2toc/include/export/plugin.inc @@ -1,8 +1,8 @@ [comment {-*- tcl -*- --- !doctools ---}] [manpage_begin doctools::toc::export::[vset PACKAGE] n [vset VERSION]] -[copyright {2009 Andreas Kupries }] +[copyright {2009-2019 Andreas Kupries }] [moddesc {Documentation tools}] [titledesc "[vset NAME] export plugin"] [category {Text formatter plugin}] [require Tcl 8.4] [require doctools::toc::export::[vset PACKAGE] [opt [vset VERSION]]] @@ -49,7 +49,7 @@ [include config/[vset CONFIG].inc] [include ../serialization.inc] [vset CATEGORY doctools] -[include ../../../doctools2base/include/feedback.inc] +[include ../../../common-text/feedback.inc] [manpage_end] Index: modules/doctools2toc/include/import/plugin.inc ================================================================== --- modules/doctools2toc/include/import/plugin.inc +++ modules/doctools2toc/include/import/plugin.inc @@ -1,13 +1,14 @@ [comment {-*- tcl -*- --- !doctools ---}] -[manpage_begin doctools::toc::import::[vset PACKAGE] n 0.1] -[copyright {2009 Andreas Kupries }] +[vset VERSION 0.2.1] +[manpage_begin doctools::toc::import::[vset PACKAGE] n [vset VERSION]] +[copyright {2009-2019 Andreas Kupries }] [moddesc {Documentation tools}] [titledesc "[vset NAME] import plugin"] [category {Text formatter plugin}] -[require Tcl 8.4] -[require doctools::toc::import::[vset PACKAGE] [opt 0.1]] +[require Tcl 8.5] +[require doctools::toc::import::[vset PACKAGE] [opt [vset VERSION]]] [include format/[vset REQUIRE].inc] [keywords doctools toc {table of contents} deserialization import [vset NAME]] [description] This package implements the doctools table of contents import plugin @@ -49,7 +50,7 @@ [include config/[vset CONFIG].inc] [include ../serialization.inc] [vset CATEGORY doctools] -[include ../../../doctools2base/include/feedback.inc] +[include ../../../common-text/feedback.inc] [manpage_end] Index: modules/doctools2toc/include/msgcat.inc ================================================================== --- modules/doctools2toc/include/msgcat.inc +++ modules/doctools2toc/include/msgcat.inc @@ -40,7 +40,7 @@ This package has no exported API. [vset CATEGORY doctools] -[include ../../doctools2base/include/feedback.inc] +[include ../../common-text/feedback.inc] [manpage_end] Index: modules/doctools2toc/pkgIndex.tcl ================================================================== --- modules/doctools2toc/pkgIndex.tcl +++ modules/doctools2toc/pkgIndex.tcl @@ -7,14 +7,12 @@ # - Export and import management # - Export and import plugins # - Parser for doctoc markup, and handling serializations # - Message catalogs for the parser -package ifneeded doctools::toc 2 [list source [file join $dir container.tcl]] - -package ifneeded doctools::toc::export 0.2 [list source [file join $dir export.tcl]] -package ifneeded doctools::toc::import 0.2 [list source [file join $dir import.tcl]] +package ifneeded doctools::toc 2 [list source [file join $dir container.tcl]] +package ifneeded doctools::toc::export 0.2.1 [list source [file join $dir export.tcl]] package ifneeded doctools::toc::export::doctoc 0.1 [list source [file join $dir export_doctoc.tcl]] package ifneeded doctools::toc::export::html 0.1 [list source [file join $dir export_html.tcl]] package ifneeded doctools::toc::export::json 0.1 [list source [file join $dir export_json.tcl]] package ifneeded doctools::toc::export::nroff 0.2 [list source [file join $dir export_nroff.tcl]] @@ -29,5 +27,9 @@ package ifneeded doctools::msgcat::toc::c 0.1 [list source [file join $dir msgcat_c.tcl]] package ifneeded doctools::msgcat::toc::de 0.1 [list source [file join $dir msgcat_de.tcl]] package ifneeded doctools::msgcat::toc::en 0.1 [list source [file join $dir msgcat_en.tcl]] package ifneeded doctools::msgcat::toc::fr 0.1 [list source [file join $dir msgcat_fr.tcl]] + +if {![package vsatisfies [package provide Tcl] 8.5]} {return} + +package ifneeded doctools::toc::import 0.2.1 [list source [file join $dir import.tcl]] Index: modules/doctools2toc/toc_container.man ================================================================== --- modules/doctools2toc/toc_container.man +++ modules/doctools2toc/toc_container.man @@ -364,7 +364,7 @@ [list_end] [include include/serialization.inc] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools2toc/toc_export.man ================================================================== --- modules/doctools2toc/toc_export.man +++ modules/doctools2toc/toc_export.man @@ -1,6 +1,6 @@ -[vset VERSION 0.2] +[vset VERSION 0.2.1] [comment {-*- tcl -*- doctools manpage}] [manpage_begin doctools::toc::export n [vset VERSION]] [keywords conversion] [keywords doctoc] [keywords documentation] @@ -18,17 +18,17 @@ [keywords {table of contents}] [keywords {tcler's wiki}] [keywords text] [keywords url] [keywords wiki] -[copyright {2009-2018 Andreas Kupries }] +[copyright {2009-2019 Andreas Kupries }] [moddesc {Documentation tools}] [titledesc {Exporting tables of contents}] [category {Documentation tools}] [require doctools::toc::export [opt [vset VERSION]]] [require Tcl 8.4] -[require doctools::config] +[require struct::map] [require doctools::toc::structure] [require snit] [require pluginmgr] [description] @@ -301,7 +301,7 @@ [list_end] [include include/serialization.inc] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools2toc/toc_import.man ================================================================== --- modules/doctools2toc/toc_import.man +++ modules/doctools2toc/toc_import.man @@ -1,6 +1,6 @@ -[vset VERSION 0.2] +[vset VERSION 0.2.1] [comment {-*- tcl -*- doctools manpage}] [manpage_begin doctools::toc::import n [vset VERSION]] [keywords conversion] [keywords doctoc] [keywords documentation] @@ -12,17 +12,17 @@ [keywords plugin] [keywords reference] [keywords table] [keywords {table of contents}] [keywords url] -[copyright {2009-2018 Andreas Kupries }] +[copyright {2009-2019 Andreas Kupries }] [moddesc {Documentation tools}] [titledesc {Importing keyword indices}] [category {Documentation tools}] [require doctools::toc::import [opt [vset VERSION]]] [require Tcl 8.4] -[require doctools::config] +[require struct::map] [require doctools::toc::structure] [require snit] [require pluginmgr] [description] @@ -389,7 +389,7 @@ [list_end] [include include/serialization.inc] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools2toc/toc_introduction.man ================================================================== --- modules/doctools2toc/toc_introduction.man +++ modules/doctools2toc/toc_introduction.man @@ -137,7 +137,7 @@ [section {Package Overview}] [include include/dependencies.inc] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools2toc/toc_parse.man ================================================================== --- modules/doctools2toc/toc_parse.man +++ modules/doctools2toc/toc_parse.man @@ -169,7 +169,7 @@ [include include/format/doctoc.inc] [include include/serialization.inc] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/doctools2toc/toc_structure.man ================================================================== --- modules/doctools2toc/toc_structure.man +++ modules/doctools2toc/toc_structure.man @@ -145,7 +145,7 @@ [list_end] [include include/serialization.inc] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/dtplite/pkg_dtplite.man ================================================================== --- modules/dtplite/pkg_dtplite.man +++ modules/dtplite/pkg_dtplite.man @@ -443,7 +443,7 @@ of doctoc and docidx markup. [list_end] [vset CATEGORY doctools] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/exif/exif.man ================================================================== --- modules/exif/exif.man +++ modules/exif/exif.man @@ -74,7 +74,7 @@ This code is a direct translation of version 1.3 of exif.pl by Chris Breeze. See the source for full headers, references, etc. [vset CATEGORY exif] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/fileutil/fileutil.man ================================================================== --- modules/fileutil/fileutil.man +++ modules/fileutil/fileutil.man @@ -516,7 +516,7 @@ [include include/cross-index-trav.inc] [list_end] [vset CATEGORY fileutil] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/fileutil/multi.man ================================================================== --- modules/fileutil/multi.man +++ modules/fileutil/multi.man @@ -50,7 +50,7 @@ command it executed. [list_end] [vset CATEGORY fileutil] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/fileutil/multiop.man ================================================================== --- modules/fileutil/multiop.man +++ modules/fileutil/multiop.man @@ -396,7 +396,7 @@ the index \\ as pkgIndex.tcl }] [vset CATEGORY fileutil] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] ADDED modules/fileutil/paths.man Index: modules/fileutil/paths.man ================================================================== --- /dev/null +++ modules/fileutil/paths.man @@ -0,0 +1,76 @@ +[comment {-*- text -*- doctools manpage}] +[vset VERSION 1] +[manpage_begin fileutil::paths n [vset VERSION]] +[titledesc {Manage search path pools}] +[require Tcl 8.4] +[require fileutil::paths [opt [vset VERSION]]] +[description] + +Provides a snit class whose instances manage a pool of (search) paths. + +[section API] + +The main command provides construction of search path pools: + +[list_begin definitions] + +[call [cmd ::fileutil::paths] [arg poolName]] + +Creates a new, empty pool of search paths with an associated global +Tcl command whose name is [arg poolName]. + +It may be used to invoke various operations on the pool. + +It has the following general form: + +[list_begin definitions] +[call [cmd poolName] [method method] [opt [arg "arg arg ..."]]] +[method method] and [arg arg]uments determine the exact behavior of +the command. +[list_end][comment --instance-command--] + +If [arg poolName] is specified as [const %AUTO%] a unique name will be +generated by the package itself. + +The result of the command is the fully-qualified name of the instance +command. + +[list_end][comment --class-command--] + +[para] + +The following commands are possible for pool objects: + +[list_begin definitions] + +[call [arg poolName] [method add] [arg path]] + +Adds the [arg path] to the pool. + +Nothing is done if the [arg path] is already known to the pool. + +The result of the command is the empty string. + +[call [arg poolName] [method clear]] + +Clears the entire pool. In other words, removes all paths from it. + +The result of the command is the empty string. + +[call [arg poolName] [method paths]] + +Returns the list of all paths known to the pool, in the order they +were added. + +[call [arg poolName] [method remove] [arg path]] + +Removes the [arg path] from the pool, if it is known to the pool. + +Unknown paths are ignored without error. + +The result of the command is the empty string. + +[list_end] + +[include ../common-text/feedback.inc] +[manpage_end] ADDED modules/fileutil/paths.tcl Index: modules/fileutil/paths.tcl ================================================================== --- /dev/null +++ modules/fileutil/paths.tcl @@ -0,0 +1,74 @@ +# paths.tcl -- +# +# Manage lists of search paths. +# +# Copyright (c) 2009-2019 Andreas Kupries +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. + +# Each object instance manages a list of paths. + +# ### ### ### ######### ######### ######### +## Requisites + +package require Tcl 8.4 +package require snit + +# ### ### ### ######### ######### ######### +## API + +snit::type ::fileutil::paths { + + # ### ### ### ######### ######### ######### + ## Options :: None + + # ### ### ### ######### ######### ######### + ## Creation, destruction + + # Default constructor. + # Default destructor. + + # ### ### ### ######### ######### ######### + ## Methods :: Querying and manipulating the list of paths. + + method paths {} { + return $mypaths + } + + method add {path} { + set pos [lsearch $mypaths $path] + if {$pos >= 0 } return + lappend mypaths $path + return + } + + method remove {path} { + set pos [lsearch $mypaths $path] + if {$pos < 0} return + set mypaths [lreplace $mypaths $pos $pos] + return + } + + method clear {} { + set mypaths {} + return + } + + # ### ### ### ######### ######### ######### + ## Internal methods :: None + + # ### ### ### ######### ######### ######### + ## State :: List of paths. + + variable mypaths {} + + ## + # ### ### ### ######### ######### ######### +} + +# ### ### ### ######### ######### ######### +## Ready + +package provide fileutil::paths 1 +return ADDED modules/fileutil/paths.test Index: modules/fileutil/paths.test ================================================================== --- /dev/null +++ modules/fileutil/paths.test @@ -0,0 +1,151 @@ +# -*- tcl -*- +# paths.test: Testsuite for package fileutil::paths +# +# Copyright (c) 2019 by Andreas Kupries +# All rights reserved. + +# ------------------------------------------------------------------------- + +source [file join \ + [file dirname [file dirname [file join [pwd] [info script]]]] \ + devtools testutilities.tcl] + +testsNeedTcl 8.4 +testsNeedTcltest 2.0 + +support { + use snit/snit.tcl snit +} +testing { + useLocal paths.tcl fileutil::paths +} + +# --------------------------------------------------------------------- +# [] constructor +# [] destructor +# [] paths +# [] add +# [] remove +# [] clear + +#---------------------------------------------------------------------- +## Constructor, destructor + +test fileutil-paths-1.0 {constructor, wrong args, too many} -body { + fileutil::paths P X +} -returnCodes error -result {Error in constructor: wrong # args: should be "::fileutil::paths::Snit_constructor type selfns win self"} + +test fileutil-paths-1.1 {instance, bogus method} -setup { + fileutil::paths P +} -cleanup { + P destroy +} -body { + P bogus +} -returnCodes error -result {"::P bogus" is not defined} + +#---------------------------------------------------------------------- +## paths + +test fileutil-paths-2.0 {paths, wrong args, too many} -setup { + fileutil::paths P +} -cleanup { + P destroy +} -body { + P paths X +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodpaths type selfns win self"} + +test fileutil-paths-2.1 {paths, base state, none} -setup { + fileutil::paths P +} -cleanup { + P destroy +} -body { + P paths +} -result {} + +#---------------------------------------------------------------------- +## add + +test fileutil-paths-3.0 {add, wrong args, not enough} -setup { + fileutil::paths P +} -cleanup { + P destroy +} -body { + P add +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodadd type selfns win self path"} + +test fileutil-paths-3.1 {add, wrong args, too many} -setup { + fileutil::paths P +} -cleanup { + P destroy +} -body { + P add F X +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodadd type selfns win self path"} + +test fileutil-paths-3.2 {add, state change, result} -setup { + fileutil::paths P +} -cleanup { + P destroy +} -body { + list [P add F] [P paths] +} -result {{} F} + +#---------------------------------------------------------------------- +## remove + +test fileutil-paths-4.0 {remove, wrong args, not enough} -setup { + fileutil::paths P +} -cleanup { + P destroy +} -body { + P remove +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodremove type selfns win self path"} + +test fileutil-paths-4.1 {remove, wrong args, too many} -setup { + fileutil::paths P +} -cleanup { + P destroy +} -body { + P remove F X +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodremove type selfns win self path"} + +test fileutil-paths-4.2 {remove, known path, state change, result} -setup { + fileutil::paths P + P add F +} -cleanup { + P destroy +} -body { + list [P remove F] [P paths] +} -result {{} {}} + +test fileutil-paths-4.3 {remove, missing path, no state change, result} -setup { + fileutil::paths P + P add Z +} -cleanup { + P destroy +} -body { + list [P remove F] [P paths] +} -result {{} Z} + +#---------------------------------------------------------------------- +## clear + +test fileutil-paths-5.0 {clear, wrong args, too many} -setup { + fileutil::paths P +} -cleanup { + P destroy +} -body { + P clear X +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodclear type selfns win self"} + +test fileutil-paths-5.1 {clear, return to base state} -setup { + fileutil::paths P + P add F +} -cleanup { + P destroy +} -body { + list [P clear] [P paths] +} -result {{} {}} + +#---------------------------------------------------------------------- +testsuiteCleanup +return Index: modules/fileutil/pkgIndex.tcl ================================================================== --- modules/fileutil/pkgIndex.tcl +++ modules/fileutil/pkgIndex.tcl @@ -6,5 +6,10 @@ if {![package vsatisfies [package provide Tcl] 8.4]} {return} package ifneeded fileutil::multi 0.1 [list source [file join $dir multi.tcl]] package ifneeded fileutil::multi::op 0.5.3 [list source [file join $dir multiop.tcl]] package ifneeded fileutil::decode 0.2.1 [list source [file join $dir decode.tcl]] +package ifneeded fileutil::paths 1 [list source [file join $dir paths.tcl]] + +if {![package vsatisfies [package provide Tcl] 8.5]} return + +if {![package vsatisfies [package provide Tcl] 8.6]} return Index: modules/fileutil/traverse.man ================================================================== --- modules/fileutil/traverse.man +++ modules/fileutil/traverse.man @@ -159,7 +159,7 @@ [include include/cross-index-trav.inc] [list_end] [vset CATEGORY fileutil] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/ftp/ftp.man ================================================================== --- modules/ftp/ftp.man +++ modules/ftp/ftp.man @@ -434,7 +434,7 @@ An update command placed in the procedure [cmd ::ftp::DisplayMsg] may run into persistent errors or infinite loops. The solution to this problem is to use [cmd {update idletasks}] instead of [cmd update]. [vset CATEGORY ftp] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/ftp/ftp_geturl.man ================================================================== --- modules/ftp/ftp_geturl.man +++ modules/ftp/ftp_geturl.man @@ -51,7 +51,7 @@ [list_end] [list_end] [vset CATEGORY ftp] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/ftpd/ftpd.man ================================================================== --- modules/ftpd/ftpd.man +++ modules/ftpd/ftpd.man @@ -273,7 +273,7 @@ channel which was active when the callback was invoked. [list_end] [vset CATEGORY ftpd] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/fumagic/cfront.man ================================================================== --- modules/fumagic/cfront.man +++ modules/fumagic/cfront.man @@ -65,7 +65,7 @@ causing the creation of procedure [const ::fileutil::magic::/FOO::run]. [list_end] [vset CATEGORY {fileutil :: magic}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/fumagic/cgen.man ================================================================== --- modules/fumagic/cgen.man +++ modules/fumagic/cgen.man @@ -57,7 +57,7 @@ perform its duties. [list_end] [vset CATEGORY {fileutil :: magic}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/fumagic/filetypes.man ================================================================== --- modules/fumagic/filetypes.man +++ modules/fumagic/filetypes.man @@ -56,7 +56,7 @@ generate this recognizer. [list_end] [vset CATEGORY {fileutil :: magic}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/fumagic/rtcore.man ================================================================== --- modules/fumagic/rtcore.man +++ modules/fumagic/rtcore.man @@ -245,7 +245,7 @@ [def [const beldate]] see above, stored in big endian [def [const leldate]] see above, stored in small/little endian [list_end] [vset CATEGORY {fileutil :: magic}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/gpx/gpx.man ================================================================== --- modules/gpx/gpx.man +++ modules/gpx/gpx.man @@ -152,7 +152,7 @@ [section AUTHOR] Keith Vetter [vset CATEGORY gpx] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/grammar_fa/dacceptor.man ================================================================== --- modules/grammar_fa/dacceptor.man +++ modules/grammar_fa/dacceptor.man @@ -96,7 +96,7 @@ [para] [section EXAMPLES] [vset CATEGORY grammar_fa] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/grammar_fa/dexec.man ================================================================== --- modules/grammar_fa/dexec.man +++ modules/grammar_fa/dexec.man @@ -177,7 +177,7 @@ [para] [section EXAMPLES] [vset CATEGORY grammar_fa] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/grammar_fa/fa.man ================================================================== --- modules/grammar_fa/fa.man +++ modules/grammar_fa/fa.man @@ -646,7 +646,7 @@ Transducers are not handled by this package. They will get their own package in the future. [vset CATEGORY grammar_fa] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/grammar_fa/faop.man ================================================================== --- modules/grammar_fa/faop.man +++ modules/grammar_fa/faop.man @@ -474,7 +474,7 @@ [para] [section EXAMPLES] [vset CATEGORY grammar_fa] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/grammar_me/gasm.man ================================================================== --- modules/grammar_me/gasm.man +++ modules/grammar_me/gasm.man @@ -433,7 +433,7 @@ The command returns the empty string as its result. [list_end] [vset CATEGORY grammar_me] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/grammar_me/me_ast.man ================================================================== --- modules/grammar_me/me_ast.man +++ modules/grammar_me/me_ast.man @@ -128,7 +128,7 @@ column index. Lines are counted from 1, columns are counted from 0. [list_end] [vset CATEGORY grammar_me] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/grammar_me/me_cpu.man ================================================================== --- modules/grammar_me/me_cpu.man +++ modules/grammar_me/me_cpu.man @@ -283,7 +283,7 @@ This method deletes the object and releases all resurces it claimed. [list_end] [vset CATEGORY grammar_me] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/grammar_me/me_cpucore.man ================================================================== --- modules/grammar_me/me_cpucore.man +++ modules/grammar_me/me_cpucore.man @@ -368,7 +368,7 @@ [term nc], the nonterminal cache is keyed by nonterminal name and location, each value a four-element list containing current location, match status, semantic value, and error status, in this order. [vset CATEGORY grammar_me] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/grammar_me/me_intro.man ================================================================== --- modules/grammar_me/me_intro.man +++ modules/grammar_me/me_intro.man @@ -88,7 +88,7 @@ [list_end] [para] [vset CATEGORY grammar_me] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/grammar_me/me_tcl.man ================================================================== --- modules/grammar_me/me_tcl.man +++ modules/grammar_me/me_tcl.man @@ -337,7 +337,7 @@ [list_end] [para] [vset CATEGORY grammar_me] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/grammar_me/me_util.man ================================================================== --- modules/grammar_me/me_util.man +++ modules/grammar_me/me_util.man @@ -77,7 +77,7 @@ starting point. [list_end] [vset CATEGORY grammar_me] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/grammar_me/me_vm.man ================================================================== --- modules/grammar_me/me_vm.man +++ modules/grammar_me/me_vm.man @@ -657,7 +657,7 @@ discards it. [list_end] [vset CATEGORY grammar_me] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/grammar_peg/peg.man ================================================================== --- modules/grammar_peg/peg.man +++ modules/grammar_peg/peg.man @@ -715,7 +715,7 @@ {Compilers and Compiler Generators}], an online book using CoCo/R, a generator for recursive descent parsers. [list_end] [vset CATEGORY grammar_peg] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/grammar_peg/peg_interp.man ================================================================== --- modules/grammar_peg/peg_interp.man +++ modules/grammar_peg/peg_interp.man @@ -116,7 +116,7 @@ [list_end] [para] [vset CATEGORY grammar_peg] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/hook/hook.man ================================================================== --- modules/hook/hook.man +++ modules/hook/hook.man @@ -369,7 +369,7 @@ [section Credits] Hook has been designed and implemented by William H. Duquette. [vset CATEGORY hook] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/html/html.man ================================================================== --- modules/html/html.man +++ modules/html/html.man @@ -470,7 +470,7 @@ [list_end] [list_end] [vset CATEGORY html] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/htmlparse/htmlparse.man ================================================================== --- modules/htmlparse/htmlparse.man +++ modules/htmlparse/htmlparse.man @@ -260,7 +260,7 @@ form elements. Its only argument is the name of the tree to cut down. [list_end] [vset CATEGORY htmlparse] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/http/autoproxy.man ================================================================== --- modules/http/autoproxy.man +++ modules/http/autoproxy.man @@ -210,7 +210,7 @@ [section AUTHORS] Pat Thoyts [vset CATEGORY {http :: autoproxy}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] ADDED modules/httpd/assets/test_cgi.tcl Index: modules/httpd/assets/test_cgi.tcl ================================================================== --- /dev/null +++ modules/httpd/assets/test_cgi.tcl @@ -0,0 +1,14 @@ +#!/usr/bin/tclsh + +puts stdout "Status: 200 OK" +if {$::env(CONTENT_LENGTH) > 0} { + puts stdout "Content-Type: $::env(CONTENT_TYPE)" + set dat [read stdin $::env(CONTENT_LENGTH)] +} else { + puts stdout "Content-Type: text/plain" + set dat "Hi!" +} +puts stdout "Content-Length: [string length $dat]" +puts stdout {} +puts stdout $dat +exit 0 Index: modules/httpd/build/cgi.tcl ================================================================== --- modules/httpd/build/cgi.tcl +++ modules/httpd/build/cgi.tcl @@ -92,10 +92,11 @@ ### my ChannelCopy $chana $chanb -size $length } else { chan flush $chanb } + my clay refcount_incr chan event $chanb readable [info coroutine] yield } @@ -122,10 +123,11 @@ # Output the body. With no -size flag, channel will copy until EOF ### chan configure $chana -translation binary -blocking 0 -buffering full -buffersize 4096 chan configure $chanb -translation binary -blocking 0 -buffering full -buffersize 4096 my ChannelCopy $chana $chanb -chunk 4096 + my clay refcount_decr } ### # For most CGI applications a directory list is vorboten ### Index: modules/httpd/build/core.tcl ================================================================== --- modules/httpd/build/core.tcl +++ modules/httpd/build/core.tcl @@ -32,46 +32,51 @@ ### clay::define ::httpd::mime { method ChannelCopy {in out args} { - set chunk 4096 - set size -1 - foreach {f v} $args { - set [string trim $f -] $v - } - dict set info coroutine [info coroutine] - if {$size>0 && $chunk>$size} { - set chunk $size - } - set bytes 0 - set sofar 0 - set method [self method] - while 1 { - set command {} - set error {} - if {$size>=0} { - incr sofar $bytes - set remaining [expr {$size-$sofar}] - if {$remaining <= 0} { - break - } elseif {$chunk > $remaining} { - set chunk $remaining - } - } - lassign [yieldto chan copy $in $out -size $chunk \ - -command [list [info coroutine] $method]] \ - command bytes error - if {$command ne $method} { - error "Subroutine $method interrupted" - } - if {[string length $error]} { - error $error - } - if {[chan eof $in]} { - break - } + try { + my clay refcount_incr + set chunk 4096 + set size -1 + foreach {f v} $args { + set [string trim $f -] $v + } + dict set info coroutine [info coroutine] + if {$size>0 && $chunk>$size} { + set chunk $size + } + set bytes 0 + set sofar 0 + set method [self method] + while 1 { + set command {} + set error {} + if {$size>=0} { + incr sofar $bytes + set remaining [expr {$size-$sofar}] + if {$remaining <= 0} { + break + } elseif {$chunk > $remaining} { + set chunk $remaining + } + } + lassign [yieldto chan copy $in $out -size $chunk \ + -command [list [info coroutine] $method]] \ + command bytes error + if {$command ne $method} { + error "Subroutine $method interrupted" + } + if {[string length $error]} { + error $error + } + if {[chan eof $in]} { + break + } + } + } finally { + my clay refcount_decr } } ### # Returns a block of HTML @@ -299,16 +304,18 @@ return $pathlist } method wait {mode sock} { + my clay refcount_incr if {[info coroutine] eq {}} { chan event $sock $mode [list set ::httpd::lock_$sock $mode] vwait ::httpd::lock_$sock } else { chan event $sock $mode [info coroutine] yield } chan event $sock $mode {} + my clay refcount_decr } } Index: modules/httpd/build/dispatch.tcl ================================================================== --- modules/httpd/build/dispatch.tcl +++ modules/httpd/build/dispatch.tcl @@ -27,19 +27,13 @@ ::clay::define ::httpd::content.cache { method Dispatch {} { my variable chan - try { - my wait writable $chan - chan configure $chan -translation {binary binary} - chan puts -nonewline $chan [my clay get cache/ data] - } on error {err info} { - my debug [dict get $info -errorinfo] - } finally { - my TransferComplete $chan - } + my wait writable $chan + chan configure $chan -translation {binary binary} + chan puts -nonewline $chan [my clay get cache/ data] } } ::clay::define ::httpd::content.template { Index: modules/httpd/build/file.tcl ================================================================== --- modules/httpd/build/file.tcl +++ modules/httpd/build/file.tcl @@ -129,27 +129,24 @@ if {$chan eq {}} return my wait writable $chan if {![info exists reply_file]} { tailcall my DoOutput } - try { - chan configure $chan -translation {binary binary} - my log HttpAccess {} - ### - # Return a stream of data from a file - ### - set size [file size $reply_file] - my reply set Content-Length $size - append result [my reply output] \n - chan puts -nonewline $chan $result - set reply_chan [open $reply_file r] - my log SendReply [list length $size] - ### - # Output the file contents. With no -size flag, channel will copy until EOF - ### - chan configure $reply_chan -translation {binary binary} -buffersize 4096 -buffering full -blocking 0 - my ChannelCopy $reply_chan $chan -chunk 4096 - } finally { - my TransferComplete $reply_chan $chan - } + chan configure $chan -translation {binary binary} + my log HttpAccess {} + ### + # Return a stream of data from a file + ### + set size [file size $reply_file] + my reply set Content-Length $size + append result [my reply output] \n + chan puts -nonewline $chan $result + set reply_chan [open $reply_file r] + my ChannelRegister $reply_chan + my log SendReply [list length $size] + ### + # Output the file contents. With no -size flag, channel will copy until EOF + ### + chan configure $reply_chan -translation {binary binary} -buffersize 4096 -buffering full -blocking 0 + my ChannelCopy $reply_chan $chan -chunk 4096 } } Index: modules/httpd/build/footer.txt ================================================================== --- modules/httpd/build/footer.txt +++ modules/httpd/build/footer.txt @@ -1,5 +1,5 @@ [section AUTHORS] Sean Woods [vset CATEGORY network] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] Index: modules/httpd/build/plugin.tcl ================================================================== --- modules/httpd/build/plugin.tcl +++ modules/httpd/build/plugin.tcl @@ -201,10 +201,10 @@ if {[dict exists $reply delegate]} { $pageobj clay delegate {*}[dict get $reply delegate] } $pageobj dispatch $sock $reply set output [$pageobj output] - catch {$pageobj destroy} + $pageobj clay refcount_decr return $output } } Index: modules/httpd/build/proxy.tcl ================================================================== --- modules/httpd/build/proxy.tcl +++ modules/httpd/build/proxy.tcl @@ -157,13 +157,10 @@ tailcall my DoOutput } my log HttpAccess {} chan event $sock writable [info coroutine] yield - try { - my ProxyRequest $chan $sock - my ProxyReply $sock $chan - } finally { - my TransferComplete $chan $sock - } + my ChannelRegister $sock + my ProxyRequest $chan $sock + my ProxyReply $sock $chan } } Index: modules/httpd/build/reply.man ================================================================== --- modules/httpd/build/reply.man +++ modules/httpd/build/reply.man @@ -131,10 +131,15 @@ [call method [cmd HttpHeaders] [arg sock] [arg ?debug?]] Stream MIME headers from the socket [arg sock], stopping at an empty line. Returns the stream as a block of text. + +[call method [cmd ChannelRegister] [arg chan]] + +Registers a channel that will need to be flushed and closed when the object's destructor +invokes the close method. [call method [cmd dispatch] [arg newsock] [arg datastate]] Take over control of the socket [arg newsock], and store that as the [arg chan] variable for the object. This method runs through all of the steps of reading HTTP headers, generating @@ -266,32 +271,10 @@ [call method [cmd timestamp]] Return the current system time in the format: [example {%a, %d %b %Y %T %Z}] -[call method [cmd TransferComplete] [arg args]] - -Intended to be invoked from [cmd {chan copy}] as a callback. This closes every channel -fed to it on the command line, and then destroys the object. - -[example { - ### - # Output the body - ### - chan configure $sock -translation binary -blocking 0 -buffering full -buffersize 4096 - chan configure $chan -translation binary -blocking 0 -buffering full -buffersize 4096 - if {$length} { - ### - # Send any POST/PUT/etc content - ### - chan copy $sock $chan -size $SIZE -command [info coroutine] - yield - } - catch {close $sock} - chan flush $chan -}] - [call method [cmd Url_Decode] [arg string]] De-httpizes a string. [list_end] Index: modules/httpd/build/reply.tcl ================================================================== --- modules/httpd/build/reply.tcl +++ modules/httpd/build/reply.tcl @@ -97,10 +97,11 @@ # # }] ### ::clay::define ::httpd::reply { superclass ::httpd::mime + Variable ChannelRegister {} Delegate { description {The server object which spawned this reply} } @@ -123,11 +124,11 @@ USER_AGENT {} SESSION {} } constructor {ServerObj args} { - my variable chan dispatched_time uuid + my variable dispatched_time uuid set uuid [namespace tail [self]] set dispatched_time [clock milliseconds] my clay delegate $ServerObj foreach {field value} [::clay::args_to_options {*}$args] { my clay set config $field: $value @@ -138,23 +139,39 @@ # clean up on exit ### destructor { my close } + + # Registers a channel to be closed by the close method + method ChannelRegister args { + my variable ChannelRegister + if {![info exists ChannelRegister]} { + set ChannelRegister {} + } + foreach c $args { + if {$c ni $ChannelRegister} { + lappend ChannelRegister $c + } + } + } ### # Close channels opened by this object ### method close {} { - my variable chan - if {[info exists chan] && $chan ne {}} { - catch {chan event $chan readable {}} - catch {chan event $chan writable {}} - catch {chan flush $chan} - catch {chan close $chan} - set chan {} - } + my variable ChannelRegister + if {![info exists ChannelRegister]} { + return + } + foreach c $ChannelRegister { + catch {chan event $c readable {}} + catch {chan event $c writable {}} + catch {chan flush $c} + catch {chan close $c} + } + set ChannelRegister {} } ### # Record a dispatch event ### @@ -185,11 +202,13 @@ # All other fields are passed along to the [method clay] structure of the object. ### method dispatch {newsock datastate} { my variable chan request try { + my clay refcount_incr set chan $newsock + my ChannelRegister $chan chan event $chan readable {} chan configure $chan -translation {auto crlf} -buffering line if {[dict exists $datastate mixin]} { set mixinmap [dict get $datastate mixin] } else { @@ -221,10 +240,13 @@ my Log_Dispatched my Dispatch } on error {err errdat} { my error 500 $err [dict get $errdat -errorinfo] my DoOutput + } finally { + my close + my clay refcount_decr } } method Dispatch {} { # Invoke the URL implementation. @@ -336,11 +358,10 @@ append result [my reply output] } chan puts -nonewline $chan $result my log HttpAccess {} } - my destroy } ### # For GET requests, converts the QUERY_DATA header into a key/value list. # @@ -421,43 +442,10 @@ } # Manage session data method Session_Load {} {} - - - # Intended to be invoked from [cmd {chan copy}] as a callback. This closes every channel - # fed to it on the command line, and then destroys the object. - # - # [example { - # ### - # # Output the body - # ### - # chan configure $sock -translation binary -blocking 0 -buffering full -buffersize 4096 - # chan configure $chan -translation binary -blocking 0 -buffering full -buffersize 4096 - # if {$length} { - # ### - # # Send any POST/PUT/etc content - # ### - # chan copy $sock $chan -size $SIZE -command [info coroutine] - # yield - # } - # catch {close $sock} - # chan flush $chan - # }] - method TransferComplete args { - my log TransferComplete - set chan {} - foreach c $args { - catch {chan event $c readable {}} - catch {chan event $c writable {}} - catch {chan flush $c} - catch {chan close $c} - } - my destroy - } - # Appends the value of [arg string] to the end of [arg reply_body], as well as a trailing newline # character. method puts line { my variable reply_body append reply_body $line \n Index: modules/httpd/build/scgi.tcl ================================================================== --- modules/httpd/build/scgi.tcl +++ modules/httpd/build/scgi.tcl @@ -119,10 +119,11 @@ # Read the SCGI request on byte at a time until we reach a ":" dict set query http HTTP_HOST {} dict set query http CONTENT_LENGTH 0 dict set query http REQUEST_URI / dict set query http REMOTE_ADDR $ip + dict set query http DOCUMENT_ROOT [my clay get server/ doc_root] set size {} while 1 { set char [::coroutine::util::read $sock 1] if {[chan eof $sock]} { catch {close $sock} @@ -131,11 +132,11 @@ if {$char eq ":"} break append size $char } # With length in hand, read the netstring encoded headers set inbuffer [::coroutine::util::read $sock [expr {$size+1}]] - chan configure $sock -blocking 0 -buffersize 4096 -buffering full + chan configure $sock -translation {auto crlf} -blocking 0 -buffersize 4096 -buffering full foreach {f v} [lrange [split [string range $inbuffer 0 end-1] \0] 0 end-1] { dict set query http $f $v } if {![dict exists $query http REQUEST_PATH]} { set uri [dict get $query http REQUEST_URI] @@ -163,13 +164,13 @@ dict set reply mixin protocol ::httpd::protocol.scgi $pageobj dispatch $sock $reply } on error {err errdat} { my debug [list ip: $ip error: $err errorinfo: [dict get $errdat -errorinfo]] my log BadRequest $uuid [list ip: $ip error: $err errorinfo: [dict get $errdat -errorinfo]] - catch {$pageobj destroy} + $pageobj clay refcount_decr catch {chan event readable $sock {}} catch {chan event writeable $sock {}} catch {chan close $sock} return } } } Index: modules/httpd/build/server.tcl ================================================================== --- modules/httpd/build/server.tcl +++ modules/httpd/build/server.tcl @@ -112,10 +112,11 @@ # This action passes control of the socket to # the reply object. The reply object manages the rest of the transaction, including # closing the socket. ### method Connect {uuid sock ip} { + ::clay::cleanup yield [info coroutine] chan event $sock readable {} chan configure $sock \ -blocking 0 \ -translation {auto crlf} \ @@ -160,13 +161,14 @@ method CheckTimeout {} { foreach obj [info commands ::httpd::object::*] { try { $obj timeOutCheck } on error {} { - catch {$obj destroy} + $obj clay refcount_decr } } + ::clay::cleanup } method debug args {} ### Index: modules/httpd/httpd.man ================================================================== --- modules/httpd/httpd.man +++ modules/httpd/httpd.man @@ -228,18 +228,14 @@ }] [para] -[class {Delegate}] -[list_begin definitions] -[call delegate [cmd ]]The server object which spawned this reply - -[list_end] -[para] [class {Variable}] [list_begin definitions] +[call variable [cmd ChannelRegister]] + [call variable [cmd reply]] A dictionary which will converted into the MIME headers of the reply @@ -248,10 +244,16 @@ A dictionary containing the SCGI transformed HTTP headers for the request +[list_end] +[para] +[class {Delegate}] +[list_begin definitions] +[call delegate [cmd ]]The server object which spawned this reply + [list_end] [para] [class {Methods}] [list_begin definitions] [call method [cmd "constructor"] [arg ServerObj] [opt "[arg args]"]] @@ -260,10 +262,15 @@ [call method [cmd "destructor"] [opt "[arg dictargs]"]] clean up on exit + + +[call method [cmd "ChannelRegister"] [opt "[arg args]"]] + Registers a channel to be closed by the close method + [call method [cmd "close"]] Close channels opened by this object @@ -358,33 +365,10 @@ [call method [cmd "Session_Load"]] Manage session data - - -[call method [cmd "TransferComplete"] [opt "[arg args]"]] - Intended to be invoked from [cmd {chan copy}] as a callback. This closes every channel - fed to it on the command line, and then destroys the object. - - [example { - ### - # Output the body - ### - chan configure $sock -translation binary -blocking 0 -buffering full -buffersize 4096 - chan configure $chan -translation binary -blocking 0 -buffering full -buffersize 4096 - if {$length} { - ### - # Send any POST/PUT/etc content - ### - chan copy $sock $chan -size $SIZE -command [info coroutine] - yield - } - catch {close $sock} - chan flush $chan - }] - [call method [cmd "puts"] [arg line]] Appends the value of [arg string] to the end of [arg reply_body], as well as a trailing newline character. @@ -934,9 +918,9 @@ [section AUTHORS] Sean Woods [vset CATEGORY network] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/httpd/httpd.tcl ================================================================== --- modules/httpd/httpd.tcl +++ modules/httpd/httpd.tcl @@ -28,46 +28,51 @@ } namespace eval ::scgi { } clay::define ::httpd::mime { method ChannelCopy {in out args} { - set chunk 4096 - set size -1 - foreach {f v} $args { - set [string trim $f -] $v - } - dict set info coroutine [info coroutine] - if {$size>0 && $chunk>$size} { - set chunk $size - } - set bytes 0 - set sofar 0 - set method [self method] - while 1 { - set command {} - set error {} - if {$size>=0} { - incr sofar $bytes - set remaining [expr {$size-$sofar}] - if {$remaining <= 0} { - break - } elseif {$chunk > $remaining} { - set chunk $remaining - } - } - lassign [yieldto chan copy $in $out -size $chunk \ - -command [list [info coroutine] $method]] \ - command bytes error - if {$command ne $method} { - error "Subroutine $method interrupted" - } - if {[string length $error]} { - error $error - } - if {[chan eof $in]} { - break - } + try { + my clay refcount_incr + set chunk 4096 + set size -1 + foreach {f v} $args { + set [string trim $f -] $v + } + dict set info coroutine [info coroutine] + if {$size>0 && $chunk>$size} { + set chunk $size + } + set bytes 0 + set sofar 0 + set method [self method] + while 1 { + set command {} + set error {} + if {$size>=0} { + incr sofar $bytes + set remaining [expr {$size-$sofar}] + if {$remaining <= 0} { + break + } elseif {$chunk > $remaining} { + set chunk $remaining + } + } + lassign [yieldto chan copy $in $out -size $chunk \ + -command [list [info coroutine] $method]] \ + command bytes error + if {$command ne $method} { + error "Subroutine $method interrupted" + } + if {[string length $error]} { + error $error + } + if {[chan eof $in]} { + break + } + } + } finally { + my clay refcount_decr } } method html_header {{title {}} args} { set result {} append result "\n" @@ -276,18 +281,20 @@ } } return $pathlist } method wait {mode sock} { + my clay refcount_incr if {[info coroutine] eq {}} { chan event $sock $mode [list set ::httpd::lock_$sock $mode] vwait ::httpd::lock_$sock } else { chan event $sock $mode [info coroutine] yield } chan event $sock $mode {} + my clay refcount_decr } } ### # END: core.tcl @@ -295,10 +302,11 @@ ### # START: reply.tcl ### ::clay::define ::httpd::reply { superclass ::httpd::mime + Variable ChannelRegister {} Delegate { description {The server object which spawned this reply} } Dict reply {} Dict request { @@ -311,30 +319,44 @@ REMOTE_HOST {} USER_AGENT {} SESSION {} } constructor {ServerObj args} { - my variable chan dispatched_time uuid + my variable dispatched_time uuid set uuid [namespace tail [self]] set dispatched_time [clock milliseconds] my clay delegate $ServerObj foreach {field value} [::clay::args_to_options {*}$args] { my clay set config $field: $value } } destructor { my close + } + method ChannelRegister args { + my variable ChannelRegister + if {![info exists ChannelRegister]} { + set ChannelRegister {} + } + foreach c $args { + if {$c ni $ChannelRegister} { + lappend ChannelRegister $c + } + } } method close {} { - my variable chan - if {[info exists chan] && $chan ne {}} { - catch {chan event $chan readable {}} - catch {chan event $chan writable {}} - catch {chan flush $chan} - catch {chan close $chan} - set chan {} - } + my variable ChannelRegister + if {![info exists ChannelRegister]} { + return + } + foreach c $ChannelRegister { + catch {chan event $c readable {}} + catch {chan event $c writable {}} + catch {chan flush $c} + catch {chan close $c} + } + set ChannelRegister {} } method Log_Dispatched {} { my log Dispatched [dict create \ REMOTE_ADDR [my request get REMOTE_ADDR] \ REMOTE_HOST [my request get REMOTE_HOST] \ @@ -347,11 +369,13 @@ ] } method dispatch {newsock datastate} { my variable chan request try { + my clay refcount_incr set chan $newsock + my ChannelRegister $chan chan event $chan readable {} chan configure $chan -translation {auto crlf} -buffering line if {[dict exists $datastate mixin]} { set mixinmap [dict get $datastate mixin] } else { @@ -383,10 +407,13 @@ my Log_Dispatched my Dispatch } on error {err errdat} { my error 500 $err [dict get $errdat -errorinfo] my DoOutput + } finally { + my close + my clay refcount_decr } } method Dispatch {} { # Invoke the URL implementation. my content @@ -475,11 +502,10 @@ append result [my reply output] } chan puts -nonewline $chan $result my log HttpAccess {} } - my destroy } method FormData {} { my variable chan formdata # Run this only once if {[info exists formdata]} { @@ -544,21 +570,10 @@ set postdata [::coroutine::util::read $chan $length] } return $postdata } method Session_Load {} {} - method TransferComplete args { - my log TransferComplete - set chan {} - foreach c $args { - catch {chan event $c readable {}} - catch {chan event $c writable {}} - catch {chan flush $c} - catch {chan close $c} - } - my destroy - } method puts line { my variable reply_body append reply_body $line \n } method RequestFind {field} { @@ -784,10 +799,11 @@ dict set result LOCALHOST [expr {[lindex [split [dict getnull $result HTTP_HOST] :] 0] eq "localhost"}] } return $result } method Connect {uuid sock ip} { + ::clay::cleanup yield [info coroutine] chan event $sock readable {} chan configure $sock \ -blocking 0 \ -translation {auto crlf} \ @@ -826,13 +842,14 @@ method CheckTimeout {} { foreach obj [info commands ::httpd::object::*] { try { $obj timeOutCheck } on error {} { - catch {$obj destroy} + $obj clay refcount_decr } } + ::clay::cleanup } method debug args {} method dispatch {data} { set reply [my Dispatch_Local $data] if {[dict size $reply]} { @@ -1090,19 +1107,13 @@ } } ::clay::define ::httpd::content.cache { method Dispatch {} { my variable chan - try { - my wait writable $chan - chan configure $chan -translation {binary binary} - chan puts -nonewline $chan [my clay get cache/ data] - } on error {err info} { - my debug [dict get $info -errorinfo] - } finally { - my TransferComplete $chan - } + my wait writable $chan + chan configure $chan -translation {binary binary} + chan puts -nonewline $chan [my clay get cache/ data] } } ::clay::define ::httpd::content.template { method content {} { if {[my request get HTTP_STATUS] ne {}} { @@ -1240,30 +1251,27 @@ if {$chan eq {}} return my wait writable $chan if {![info exists reply_file]} { tailcall my DoOutput } - try { - chan configure $chan -translation {binary binary} - my log HttpAccess {} - ### - # Return a stream of data from a file - ### - set size [file size $reply_file] - my reply set Content-Length $size - append result [my reply output] \n - chan puts -nonewline $chan $result - set reply_chan [open $reply_file r] - my log SendReply [list length $size] - ### - # Output the file contents. With no -size flag, channel will copy until EOF - ### - chan configure $reply_chan -translation {binary binary} -buffersize 4096 -buffering full -blocking 0 - my ChannelCopy $reply_chan $chan -chunk 4096 - } finally { - my TransferComplete $reply_chan $chan - } + chan configure $chan -translation {binary binary} + my log HttpAccess {} + ### + # Return a stream of data from a file + ### + set size [file size $reply_file] + my reply set Content-Length $size + append result [my reply output] \n + chan puts -nonewline $chan $result + set reply_chan [open $reply_file r] + my ChannelRegister $reply_chan + my log SendReply [list length $size] + ### + # Output the file contents. With no -size flag, channel will copy until EOF + ### + chan configure $reply_chan -translation {binary binary} -buffersize 4096 -buffering full -blocking 0 + my ChannelCopy $reply_chan $chan -chunk 4096 } } ### # END: file.tcl @@ -1419,16 +1427,13 @@ tailcall my DoOutput } my log HttpAccess {} chan event $sock writable [info coroutine] yield - try { - my ProxyRequest $chan $sock - my ProxyReply $sock $chan - } finally { - my TransferComplete $chan $sock - } + my ChannelRegister $sock + my ProxyRequest $chan $sock + my ProxyReply $sock $chan } } ### # END: proxy.tcl @@ -1527,10 +1532,11 @@ ### my ChannelCopy $chana $chanb -size $length } else { chan flush $chanb } + my clay refcount_incr chan event $chanb readable [info coroutine] yield } method ProxyReply {chana chanb args} { my log ProxyReply [list args $args] @@ -1555,10 +1561,11 @@ # Output the body. With no -size flag, channel will copy until EOF ### chan configure $chana -translation binary -blocking 0 -buffering full -buffersize 4096 chan configure $chanb -translation binary -blocking 0 -buffering full -buffersize 4096 my ChannelCopy $chana $chanb -chunk 4096 + my clay refcount_decr } method DirectoryListing {local_file} { my error 403 {Not Allowed} tailcall my DoOutput } @@ -1686,11 +1693,11 @@ if {$char eq ":"} break append size $char } # With length in hand, read the netstring encoded headers set inbuffer [::coroutine::util::read $sock [expr {$size+1}]] - chan configure $sock -blocking 0 -buffersize 4096 -buffering full + chan configure $sock -translation {auto crlf} -blocking 0 -buffersize 4096 -buffering full foreach {f v} [lrange [split [string range $inbuffer 0 end-1] \0] 0 end-1] { dict set query http $f $v } if {![dict exists $query http REQUEST_PATH]} { set uri [dict get $query http REQUEST_URI] @@ -1718,11 +1725,11 @@ dict set reply mixin protocol ::httpd::protocol.scgi $pageobj dispatch $sock $reply } on error {err errdat} { my debug [list ip: $ip error: $err errorinfo: [dict get $errdat -errorinfo]] my log BadRequest $uuid [list ip: $ip error: $err errorinfo: [dict get $errdat -errorinfo]] - catch {$pageobj destroy} + $pageobj clay refcount_decr catch {chan event readable $sock {}} catch {chan event writeable $sock {}} catch {chan close $sock} return } @@ -1889,11 +1896,11 @@ if {[dict exists $reply delegate]} { $pageobj clay delegate {*}[dict get $reply delegate] } $pageobj dispatch $sock $reply set output [$pageobj output] - catch {$pageobj destroy} + $pageobj clay refcount_decr return $output } } ### Index: modules/httpd/httpd.test ================================================================== --- modules/httpd/httpd.test +++ modules/httpd/httpd.test @@ -11,688 +11,625 @@ } source [file join $TCLLIBMOD devtools testutilities.tcl] testsNeedTcl 8.6 ;# tool requires 8.6 testsNeedTcltest 2 - +set NOW [clock seconds] testsNeed TclOO 1 support { - use [file join ${TCLLIBMOD} fumagic rtcore.tcl] fileutil::magic::rt - use [file join ${TCLLIBMOD} fumagic filetypes.tcl] fileutil::magic::filetype - use [file join ${TCLLIBMOD} textutil string.tcl] textutil::string - use [file join ${TCLLIBMOD} textutil repeat.tcl] textutil::repeat - use [file join ${TCLLIBMOD} textutil tabify.tcl] textutil::tabify - use [file join ${TCLLIBMOD} markdown markdown.tcl] Markdown - use [file join ${TCLLIBMOD} ncgi ncgi.tcl] ncgi - use [file join ${TCLLIBMOD} log logger.tcl] logger - use [file join ${TCLLIBMOD} base64 base64.tcl] base64 - use [file join ${TCLLIBMOD} md5 md5x.tcl] md5 - use [file join ${TCLLIBMOD} mime mime.tcl] mime - use [file join ${TCLLIBMOD} uuid uuid.tcl] uuid - use [file join ${TCLLIBMOD} cmdline cmdline.tcl] cmdline - use [file join ${TCLLIBMOD} fileutil fileutil.tcl] fileutil - use [file join ${TCLLIBMOD} sha1 sha1.tcl] sha1 - use [file join ${TCLLIBMOD} uri uri.tcl] uri - use [file join ${TCLLIBMOD} ncgi ncgi.tcl] ncgi - use [file join ${TCLLIBMOD} dns ip.tcl] ip - use [file join ${TCLLIBMOD} nettool nettool.tcl] nettool - use [file join ${TCLLIBMOD} coroutine coroutine.tcl] coroutine - use [file join ${TCLLIBMOD} dicttool dicttool.tcl] dicttool - use [file join ${TCLLIBMOD} cron cron.tcl] cron - use [file join ${TCLLIBMOD} virtchannel_core core.tcl] tcl::chan::core - use [file join ${TCLLIBMOD} virtchannel_core events.tcl] tcl::chan::events - use [file join ${TCLLIBMOD} virtchannel_base memchan.tcl] tcl::chan::memchan - use [file join ${TCLLIBMOD} websocket websocket.tcl] websocket - use [file join ${MODDIR} clay clay.tcl] clay + use [file join ${TCLLIBMOD} fumagic rtcore.tcl] fileutil::magic::rt + use [file join ${TCLLIBMOD} fumagic filetypes.tcl] fileutil::magic::filetype + use [file join ${TCLLIBMOD} textutil string.tcl] textutil::string + use [file join ${TCLLIBMOD} textutil repeat.tcl] textutil::repeat + use [file join ${TCLLIBMOD} textutil tabify.tcl] textutil::tabify + use [file join ${TCLLIBMOD} markdown markdown.tcl] Markdown + use [file join ${TCLLIBMOD} ncgi ncgi.tcl] ncgi + use [file join ${TCLLIBMOD} log logger.tcl] logger + use [file join ${TCLLIBMOD} base64 base64.tcl] base64 + use [file join ${TCLLIBMOD} md5 md5x.tcl] md5 + use [file join ${TCLLIBMOD} mime mime.tcl] mime + use [file join ${TCLLIBMOD} uuid uuid.tcl] uuid + use [file join ${TCLLIBMOD} cmdline cmdline.tcl] cmdline + use [file join ${TCLLIBMOD} fileutil fileutil.tcl] fileutil + use [file join ${TCLLIBMOD} sha1 sha1.tcl] sha1 + use [file join ${TCLLIBMOD} uri uri.tcl] uri + use [file join ${TCLLIBMOD} ncgi ncgi.tcl] ncgi + use [file join ${TCLLIBMOD} dns ip.tcl] ip + use [file join ${TCLLIBMOD} nettool nettool.tcl] nettool + use [file join ${TCLLIBMOD} coroutine coroutine.tcl] coroutine + use [file join ${TCLLIBMOD} dicttool dicttool.tcl] dicttool + use [file join ${TCLLIBMOD} cron cron.tcl] cron + use [file join ${TCLLIBMOD} virtchannel_core core.tcl] tcl::chan::core + use [file join ${TCLLIBMOD} virtchannel_core events.tcl] tcl::chan::events + use [file join ${TCLLIBMOD} virtchannel_base memchan.tcl] tcl::chan::memchan + use [file join ${TCLLIBMOD} websocket websocket.tcl] websocket + use [file join ${MODDIR} clay clay.tcl] clay } testing { - useLocal httpd.tcl httpd + useLocal httpd.tcl httpd } # Set to true for debugging and traces set ::DEBUG 0 set ::clay::debug $::DEBUG proc DEBUG args { - if {$::DEBUG} { + if {!$::DEBUG} return uplevel 1 $args - } +} + +# ------------------------------------------------------------------------- +# Constructors for various expected replies. +proc IndexReply {{head {HTTP/1.0}}} { + global TESTDIR + set fin [open [file join $TESTDIR pkgIndex.tcl] r] + set replyfile [read $fin] + close $fin + + append checkreply "$head 200 OK" \n + append checkreply "Content-Type: text/plain" \n + append checkreply "Connection: close" \n + append checkreply "Content-Length: [string length $replyfile]" \n + append checkreply \n + append checkreply $replyfile + + return $checkreply +} + +proc 404 {} { + lappend map " " "" + lappend map " " "" + # The map removes the indentation of the value + return [string map $map {HTTP/1.0 404 Not Found + Content-Type: text/plain + Connection: close + Content-Length: * + + 404 Not Found + }] +} + +proc 200 {text {len *}} { + lappend map " " "" + # The map removes the indentation of the value + # and inserts the dynamic parts + lappend map @C $text + lappend map @L $len + return [string map $map {HTTP/1.0 200 OK + Content-Type: text/plain + Connection: close + Content-Length: @L + + @C}] +} + +proc 200+status-head {text {len *}} { + lappend map " " "" + # The map removes the indentation of the value + # and inserts the dynamic parts + lappend map @C $text + lappend map @L $len + return [string map $map {Status: 200 OK + Content-Type: text/plain + Connection: close + Content-Length: @L + + @C}] +} + +proc 200+status-conn {text {len *}} { + lappend map " " "" + # The map removes the indentation of the value + # and inserts the dynamic parts + lappend map @C $text + lappend map @L $len + return [string map $map {HTTP/1.0 200 OK + Status: 200 OK + Content-Type: text/plain + Content-Length: @L + + @C}] +} + +proc 500 {} { + lappend map " " "" + lappend map " " "" + # The map removes the indentation of the value + return [string map $map {HTTP/1.0 500 Server Internal Error + Content-Type: text/plain + Connection: close + Content-Length: * + + 500 Server Internal Error + }] +} + +proc 500+status-head {} { + lappend map " " "" + lappend map " " "" + # The map removes the indentation of the value + return [string map $map {Status: 500 Server Internal Error + Content-Type: text/plain + Connection: close + Content-Length: * + + 500 Server Internal Error + }] } +# Likely a band aid, see AKU +proc norm-eol {x} { string map [list "\r\n" "\n"] $x } + # ------------------------------------------------------------------------- namespace eval ::httpd {} namespace eval ::httpd::test {} -### -# Minimal test harness for the .tests -# Not intended for public consumption -# (But if you find it handy, please steal!) -proc ::httpd::test::compare {actual correct} { - set result {} - set cbuf [split $correct \n] - set abuf [split $actual \n] - for {set i 0} {$i < [llength $cbuf]} {incr i} { - set cline [string trim [lindex $cbuf $i]] - set aline [string trim [lindex $abuf $i]] - if {![string match $cline $aline]} { - if {$cline ne $aline} { - append result "Line $i differs [list $aline] != [list $cline]" \n - } - } - } - if {[llength $result]} { - puts [list ACTUAL $actual] - puts [list CORRECT $correct] - } - return $result -} - proc ::httpd::test::send {port http headers body} { - set sock [socket localhost $port] - variable reply - set reply($sock) {} - chan configure $sock -translation {crlf crlf} -blocking 0 -buffering full -buffersize 4096 - chan event $sock readable [list ::httpd::test::get_reply $sock] - - puts $sock $http - if {![dict exists $headers Host]} { - dict set headers Host localhost - } - if {[string length $body]} { - if {![dict exists $headers Content-Type]} { - dict set headers Content_Type text/plain - } - dict set headers Content-Length [string length $body] - } - foreach {f v} $headers { - puts $sock "${f}: $v" - } - puts $sock {} - if {[string length $body]} { - chan configure $sock -translation binary -blocking 0 -buffering full -buffersize 4096 - puts -nonewline $sock $body - } - flush $sock - while {$reply($sock) eq {}} { - update - } - #vwait [namespace current]::reply($sock) - return $reply($sock) + set sock [socket localhost $port] + variable reply + set reply($sock) {} + chan configure $sock -translation {crlf crlf} -blocking 0 -buffering full -buffersize 4096 + chan event $sock readable [list ::httpd::test::get_reply $sock] + + puts $sock $http + if {![dict exists $headers Host]} { + dict set headers Host localhost + } + if {[string length $body]} { + if {![dict exists $headers Content-Type]} { + dict set headers Content_Type text/plain + } + dict set headers Content-Length [string length $body] + } + foreach {f v} $headers { + puts $sock "${f}: $v" + } + puts $sock {} + if {[string length $body]} { + chan configure $sock -translation binary -blocking 0 -buffering full -buffersize 4096 + puts -nonewline $sock $body + } + flush $sock + while {$reply($sock) eq {}} { + update + } + #vwait [namespace current]::reply($sock) + + #puts ZZ\t[join [split $reply($sock) \n] "|\nZZ\t"]| + return $reply($sock) } proc ::httpd::test::get_reply {sock} { - variable buffer - set data [read $sock] - append buffer($sock) $data - if {[eof $sock]} { - chan event $sock readable {} - set [namespace current]::reply($sock) $buffer($sock) - unset buffer($sock) - } -} - + variable buffer + set data [read $sock] + append buffer($sock) $data + if {[eof $sock]} { + chan event $sock readable {} + set [namespace current]::reply($sock) $buffer($sock) + unset buffer($sock) + } +} clay::define ::httpd::server { - method log args {} - - method TemplateSearch page { - set doc_root [my clay get server/ doc_root] - if {$doc_root ne {} && [file exists [file join $doc_root $page.tml]]} { - return [::fileutil::cat [file join $doc_root $page.tml]] - } - if {$doc_root ne {} && [file exists [file join $doc_root $page.html]]} { - return [::fileutil::cat [file join $doc_root $page.html]] - } - switch $page { - redirect { - return {300 Redirect} - } - notfound { - return {404 Not Found} - } - internal_error { - return {500 Server Internal Error} - } - } - } - - - ::DEBUG method debug args { - puts stderr $args - } - - ::DEBUG method log args { - puts stdout $args - } + method log args {} + + method TemplateSearch page { + set doc_root [my clay get server/ doc_root] + if {$doc_root ne {} && [file exists [file join $doc_root $page.tml]]} { + return [::fileutil::cat [file join $doc_root $page.tml]] + } + if {$doc_root ne {} && [file exists [file join $doc_root $page.html]]} { + return [::fileutil::cat [file join $doc_root $page.html]] + } + switch $page { + redirect { + return {300 Redirect} + } + notfound { + return {404 Not Found} + } + internal_error { + return {500 Server Internal Error} + } + } + } + + + ::DEBUG method debug args { + puts stderr $args + } + + ::DEBUG method log args { + puts stdout $args + } } ### # Modify the reply class to return plain text ### clay::define ::httpd::reply { - method HttpHeaders_Default {} { - return {Status {200 OK} - Content-Type {text/plain} - Connection close} - } - - method reset {} { - my variable reply_body - my reply replace [my HttpHeaders_Default] - set reply_body {} - } - - method error {code {msg {}} {errorInfo {}}} { - my clay set HTTP_ERROR $code - my reset - set errorstring [my http_code_string $code] - set qheaders [my clay dump] - dict with qheaders {} - my reply replace {} - my reply set Status "$code $errorstring" - my reply set Content-Type text/plain - my puts "$code $errorstring" - } + method HttpHeaders_Default {} { + return { + Status {200 OK} + Content-Type {text/plain} + Connection close + } + } + + method reset {} { + my variable reply_body + my reply replace [my HttpHeaders_Default] + set reply_body {} + } + + method error {code {msg {}} {errorInfo {}}} { + my clay set HTTP_ERROR $code + my reset + set errorstring [my http_code_string $code] + set qheaders [my clay dump] + dict with qheaders {} + my reply replace {} + my reply set Status "$code $errorstring" + my reply set Content-Type text/plain + my puts "$code $errorstring" + } } clay::define ::test::content.echo { - method content {} { - my variable reply_body - set reply_body [my PostData [my request get CONTENT_LENGTH]] - #puts [list REPLY BODY WAS $reply_body] - } + method content {} { + my variable reply_body + set reply_body [my PostData [my request get CONTENT_LENGTH]] + #puts [list REPLY BODY WAS $reply_body] + } } clay::define ::test::content.file { - superclass ::httpd::content.file - method content {} { - my reset - set doc_root [my request get DOCUMENT_ROOT] - my variable reply_file - set reply_file [file join $doc_root pkgIndex.tcl] - } + superclass ::httpd::content.file + method content {} { + my reset + set doc_root [my clay get path] + my variable reply_file + set reply_file [file join $doc_root pkgIndex.tcl] + } } clay::define ::test::content.time { - method content {} { - my variable reply_body - set reply_body [clock seconds] - } + method content {} { + my variable reply_body + set reply_body $::NOW + } } clay::define ::test::content.error { - method content {} { - error {The programmer asked me to die this way} - } + method content {} { + error {The programmer asked me to die this way} + } } clay::define ::test::content.cgi { - superclass ::httpd::content.cgi - + superclass ::httpd::content.cgi } - +clay::define ::test::content.string { + method content {} { + my variable reply_body + set reply_body [my clay get hardcoded_string] + } +} clay::define ::httpd::test::reply { - superclass ::httpd::reply ::test::content.echo + superclass ::httpd::reply ::test::content.echo } ### # Build the server ### + ::httpd::server create TESTAPP port 10001 doc_root $::TESTDIR TESTAPP plugin dict_dispatch -TESTAPP uri add * / [list mixin {reply ::test::content.echo}] -TESTAPP uri add * /echo [list mixin {reply ::test::content.echo}] -TESTAPP uri add * /file [list mixin {reply ::test::content.file}] -TESTAPP uri add * /time [list mixin {reply ::test::content.time}] -TESTAPP uri add * /error [list mixin {replyy ::test::content.error}] +TESTAPP uri add * / [list mixin {reply ::test::content.echo}] +TESTAPP uri add * /echo [list mixin {reply ::test::content.echo}] +TESTAPP uri add * /file [list mixin {reply ::test::content.file} path $::TESTDIR] +TESTAPP uri add * /time [list mixin {reply ::test::content.time}] +TESTAPP uri add * /error [list mixin {reply ::test::content.error}] +TESTAPP uri add * /string [list mixin {reply ::test::content.string} hardcoded_string apple] # Catch all #TESTAPP uri add * * [list mixin {reply httpd::content.echo}] ::DEBUG puts httpd-client-0001 -test httpd-client-0001 {Do an echo request} { - -set reply [::httpd::test::send 10001 {POST /echo HTTP/1.0} {} {THIS IS MY CODE}] -::httpd::test::compare $reply {HTTP/1.0 200 OK -Content-Type: text/plain -Connection: close -Content-Length: * - -THIS IS MY CODE} -} {} +test httpd-client-0001 {Do an echo request} -body { + ::httpd::test::send 10001 {POST /echo HTTP/1.0} {} {THIS IS MY CODE} +} -match glob -result [200 {THIS IS MY CODE}] ::DEBUG puts httpd-client-0002 test httpd-client-0002 {Do another echo request} { -set reply [::httpd::test::send 10001 {POST /echo HTTP/1.0} {} {THOUGH THERE ARE MANY LIKE IT}] -::httpd::test::compare $reply {HTTP/1.0 200 OK -Content-Type: text/plain -Connection: close -Content-Length: 29 - -THOUGH THERE ARE MANY LIKE IT} -} {} + ::httpd::test::send 10001 {POST /echo HTTP/1.0} {} {THOUGH THERE ARE MANY LIKE IT} +} [200 {THOUGH THERE ARE MANY LIKE IT} 29] ::DEBUG puts httpd-client-0003 -test httpd-client-0003 {Do another echo request} { -set reply [::httpd::test::send 10001 {POST /echo HTTP/1.0} {} {THIS ONE ALONE IS MINE}] -::httpd::test::compare $reply {HTTP/1.0 200 OK -Content-Type: text/plain -Connection: close -Content-Length: * - -THIS ONE ALONE IS MINE} -} {} +test httpd-client-0003 {Do another echo request} -body { + ::httpd::test::send 10001 {POST /echo HTTP/1.0} {} {THIS ONE ALONE IS MINE} +} -match glob -result [200 {THIS ONE ALONE IS MINE}] ::DEBUG puts httpd-client-0004 -test httpd-client-0004 {URL Generates Error} { - -set reply [::httpd::test::send 10001 {POST /error HTTP/1.0} {} {THIS ONE ALONE IS MINE}] - -::httpd::test::compare $reply {HTTP/1.0 500 Server Internal Error -Content-Type: text/plain -Connection: close -Content-Length: * - -500 Server Internal Error} -} {} - -set checkreply [subst {HTTP/1.0 200 OK -Content-Type: text/plain -Connection: close -Content-Length: * - -[clock seconds]}] +test httpd-client-0004 {URL Generates Error} -body { + ::httpd::test::send 10001 {POST /error HTTP/1.0} {} {THIS ONE ALONE IS MINE} +} -match glob -result [500] ::DEBUG puts httpd-client-0005 -test httpd-client-0005 {URL Different output with a different request} { -set reply [::httpd::test::send 10001 {POST /time HTTP/1.0} {} {THIS ONE ALONE IS MINE}] -::httpd::test::compare $reply $checkreply -} {} - -set fin [open [file join $TESTDIR pkgIndex.tcl] r] -set replyfile [read $fin] -close $fin -set checkreply "HTTP/1.0 200 OK -Content-Type: text/plain -Connection: close -Content-Length: [string length $replyfile] - -$replyfile" +test httpd-client-0005 {URL Different output with a different request} -body { + ::httpd::test::send 10001 {POST /time HTTP/1.0} {} {THIS ONE ALONE IS MINE} +} -match glob -result [200 $::NOW] ::DEBUG puts httpd-client-0006 -test httpd-client-0006 {Return a file} { -set reply [::httpd::test::send 10001 {GET /file HTTP/1.0} {} {}] -::httpd::test::compare $reply $checkreply -} {} +test httpd-client-0006 {Return a file} -body { + ::httpd::test::send 10001 {GET /file HTTP/1.0} {} {} +} -result [IndexReply] ::DEBUG puts httpd-client-0007 -test httpd-client-0007 {URL Generates Not Found} { - -set reply [::httpd::test::send 10001 {POST /doesnotexist HTTP/1.0} {} {THIS ONE ALONE IS MINE}] - -::httpd::test::compare $reply {HTTP/1.0 404 Not Found -Content-Type: text/plain -Connection: close -Content-Length: * - -404 Not Found} -} {} - +test httpd-client-0007 {URL Generates Not Found} -body { + ::httpd::test::send 10001 {POST /doesnotexist HTTP/1.0} {} {THIS ONE ALONE IS MINE} +} -match glob -result [404] + +::DEBUG puts httpd-client-0008 +test httpd-client-0008 {Pull a constant string} -body { + ::httpd::test::send 10001 {GET /string HTTP/1.0} {} {} +} -match glob -result [200 apple] # ------------------------------------------------------------------------- # Test proxies clay::define ::test::content.proxy { - superclass ::httpd::content.proxy + superclass ::httpd::content.proxy - method proxy_channel {} { - return [::socket localhost [my clay get proxy_port]] - } + method proxy_channel {} { + return [::socket localhost [my clay get proxy_port]] + } } - ::httpd::server create TESTPROXY port 10002 doc_root $::TESTDIR -TESTAPP uri add * /proxy* [list mixin {reply ::test::content.proxy} proxy_port [TESTPROXY port_listening]] +TESTAPP uri add * /proxy* [list mixin {reply ::test::content.proxy} proxy_port [TESTPROXY port_listening]] TESTPROXY plugin dict_dispatch -TESTPROXY uri add * / [list mixin {reply ::test::content.echo}] -TESTPROXY uri add * /echo [list mixin {reply ::test::content.echo}] -TESTPROXY uri add * /file [list mixin {reply ::test::content.file}] -TESTPROXY uri add * /time [list mixin {reply ::test::content.time}] -TESTPROXY uri add * /error [list mixin {reply ::test::content.error}] +TESTPROXY uri add * / [list mixin {reply ::test::content.echo}] +TESTPROXY uri add * /echo [list mixin {reply ::test::content.echo}] +TESTPROXY uri add * /file [list mixin {reply ::test::content.file} path $::TESTDIR] +TESTPROXY uri add * /time [list mixin {reply ::test::content.time}] +TESTPROXY uri add * /error [list mixin {reply ::test::content.error}] +TESTPROXY uri add * /string [list mixin {reply ::test::content.string} hardcoded_string banana] + +## AKU ## +# +# Note: Proxy replies are not normalized to \n. They contain \r\n +# endings. The old test::compare was ok with that due to running a +# trim on the lines it was comparing. Here we properly normalize +# before feeding into the comparison. +# +# Note 2: I suspect that this leakage / non-normalization of of \r\n +# in the server is a bug which should be fixed. If so, norm-eol +# becomes superfluous. Right now it feels like a band-aid ::DEBUG puts httpd-proxy-0001 -test httpd-proxy-0001 {Do an echo request} { - -set reply [::httpd::test::send 10001 {POST /proxy/echo HTTP/1.0} {} {THIS IS MY CODE}] -::httpd::test::compare $reply {HTTP/1.0 200 OK -Content-Type: text/plain -Connection: close -Content-Length: * - -THIS IS MY CODE} -} {} +test httpd-proxy-0001 {Do an echo request} -body { + norm-eol [::httpd::test::send 10001 {POST /proxy/echo HTTP/1.0} {} {THIS IS MY CODE}] +} -match glob -result [200 {THIS IS MY CODE}] ::DEBUG puts httpd-proxy-0002 -test httpd-proxy-0002 {Do another echo request} { -set reply [::httpd::test::send 10001 {POST /proxy/echo HTTP/1.0} {} {THOUGH THERE ARE MANY LIKE IT}] -::httpd::test::compare $reply {HTTP/1.0 200 OK -Content-Type: text/plain -Connection: close -Content-Length: 29 - -THOUGH THERE ARE MANY LIKE IT} -} {} +test httpd-proxy-0002 {Do another echo request} -body { + norm-eol [::httpd::test::send 10001 {POST /proxy/echo HTTP/1.0} {} {THOUGH THERE ARE MANY LIKE IT}] +} -result [200 {THOUGH THERE ARE MANY LIKE IT} 29] ::DEBUG puts httpd-proxy-0003 -test httpd-proxy-0003 {Do another echo request} { -set reply [::httpd::test::send 10001 {POST /proxy/echo HTTP/1.0} {} {THIS ONE ALONE IS MINE}] -::httpd::test::compare $reply {HTTP/1.0 200 OK -Content-Type: text/plain -Connection: close -Content-Length: * - -THIS ONE ALONE IS MINE} -} {} +test httpd-proxy-0003 {Do another echo request} -body { + norm-eol [::httpd::test::send 10001 {POST /proxy/echo HTTP/1.0} {} {THIS ONE ALONE IS MINE}] +} -match glob -result [200 {THIS ONE ALONE IS MINE}] ::DEBUG puts httpd-proxy-0004 -test httpd-proxy-0004 {URL Generates Error} { - -set reply [::httpd::test::send 10001 {POST /proxy/error HTTP/1.0} {} {THIS ONE ALONE IS MINE}] - -::httpd::test::compare $reply {HTTP/1.0 500 Server Internal Error -Content-Type: text/plain -Connection: close -Content-Length: * - -500 Server Internal Error} -} {} - -set checkreply [subst {HTTP/1.0 200 OK -Content-Type: text/plain -Connection: close -Content-Length: * - -[clock seconds]}] +test httpd-proxy-0004 {URL Generates Error} -body { + norm-eol [::httpd::test::send 10001 {POST /proxy/error HTTP/1.0} {} {THIS ONE ALONE IS MINE}] +} -match glob -result [500] ::DEBUG puts httpd-proxy-0005 -test httpd-proxy-0005 {URL Different output with a different request} { -set reply [::httpd::test::send 10001 {POST /proxy/time HTTP/1.0} {} {THIS ONE ALONE IS MINE}] -::httpd::test::compare $reply $checkreply -} {} - -set fin [open [file join $TESTDIR pkgIndex.tcl] r] -set replyfile [read $fin] -close $fin -set checkreply "HTTP/1.0 200 OK -Content-Type: text/plain -Connection: close -Content-Length: [string length $replyfile] - -$replyfile" +test httpd-proxy-0005 {URL Different output with a different request} -body { + norm-eol [::httpd::test::send 10001 {POST /proxy/time HTTP/1.0} {} {THIS ONE ALONE IS MINE}] +} -match glob -result [200 $::NOW] ::DEBUG puts httpd-proxy-0006 -test httpd-proxy-0006 {Return a file} { -set reply [::httpd::test::send 10001 {GET /proxy/file HTTP/1.0} {} {}] -::httpd::test::compare $reply $checkreply -} {} +test httpd-proxy-0006 {Return a file} -body { + norm-eol [::httpd::test::send 10001 {GET /proxy/file HTTP/1.0} {} {}] +} -result [IndexReply] +::DEBUG puts httpd-proxy-0008 +test httpd-proxy-0008 {Pull a constant string} -body { + norm-eol [::httpd::test::send 10001 {GET /proxy/string HTTP/1.0} {} {}] +} -result [200 banana 6] # ------------------------------------------------------------------------- # cgi + TESTAPP plugin local_memchan - -TESTAPP uri add * /cgi-bin* [list mixin {reply ::test::content.cgi} path $::TESTDIR] - -set fout [open [file join $TESTDIR test.tcl] w] -puts $fout {#!/usr/bin/tclsh - -puts stdout "Status: 200 OK" -if {$::env(CONTENT_LENGTH) > 0} { - puts stdout "Content-Type: $::env(CONTENT_TYPE)" - set dat [read stdin $::env(CONTENT_LENGTH)] -} else { - puts stdout "Content-Type: text/plain" - set dat "Hi!" -} -puts stdout "Content-Length: [string length $dat]" -puts stdout {} -puts stdout $dat -exit 0 -} -close $fout +TESTAPP uri add * /cgi-bin* [list mixin {reply ::test::content.cgi} path $::TESTDIR/assets] ::DEBUG puts httpd-cgi-0001 -test httpd-cgi-0001 {CGI Post} { - -set reply [::httpd::test::send 10001 {POST /cgi-bin/test.tcl HTTP/1.0} {} {THIS IS MY CODE}] -::httpd::test::compare $reply {HTTP/1.0 200 OK -Status: 200 OK -Content-Type: text/plain -Content-Length: * - -THIS IS MY CODE} -} {} +test httpd-cgi-0001 {CGI Post} -body { + norm-eol [::httpd::test::send 10001 {POST /cgi-bin/test_cgi.tcl HTTP/1.0} {} {THIS IS MY CODE}] +} -match glob -result [200+status-conn {THIS IS MY CODE +}] ::DEBUG puts httpd-cgi-0002 -test httpd-cgi-0002 {CGI Get} { - -set reply [::httpd::test::send 10001 {GET /cgi-bin/test.tcl HTTP/1.0} {} {}] -::httpd::test::compare $reply {HTTP/1.0 200 OK -Status: 200 OK -Content-Type: text/plain -Content-Length: * - -Hi!} -} {} +test httpd-cgi-0002 {CGI Get} -body { + ::httpd::test::send 10001 {GET /cgi-bin/test_cgi.tcl HTTP/1.0} {} {} +} -match glob -result [200+status-conn {Hi! +}] ### # Test the local geturl method ### -set now [clock seconds] -set dat [TESTAPP local_memchan geturl /time] test httpd-memchan-0001 {Memchan GET} { - TESTAPP local_memchan geturl /time -} $now + TESTAPP local_memchan geturl /time +} $NOW # ------------------------------------------------------------------------- namespace eval ::scgi {} namespace eval ::scgi::test {} ### # Minimal test harness for the .tests # Not intended for public consumption # (But if you find it handy, please steal!) -namespace eval ::scgi::test {} proc ::scgi::encode_request {headers body info} { - variable server_block - - dict set outdict CONTENT_LENGTH [string length $body] - set outdict [dict merge $outdict $server_block $info] - dict set outdict PWD [pwd] - foreach {key value} $headers { - if {$key in { - DOCUMENT_ROOT - HTTPS - PATH - REQUEST_METHOD REQUEST_URI - REMOTE_HOST REMOTE_ADDR REMOTE_PORT - SCRIPT_NAME - } || [string range $key 0 5] eq "HTTP_"} { - dict set outdict $key $value - } else { - dict set outdict HTTP_[string map {"-" "_"} [string toupper $key]] $value - } - } - set result {} - foreach {name value} $outdict { - append result $name \x00 $value \x00 - } - return "[string length $result]:$result," + variable server_block + + dict set outdict CONTENT_LENGTH [string length $body] + set outdict [dict merge $outdict $server_block $info] + dict set outdict PWD [pwd] + + foreach {key value} $headers { + if {$key in { + DOCUMENT_ROOT + HTTPS + PATH + REQUEST_METHOD REQUEST_URI + REMOTE_HOST REMOTE_ADDR REMOTE_PORT + SCRIPT_NAME + } || [string range $key 0 5] eq "HTTP_"} { + dict set outdict $key $value + } else { + dict set outdict HTTP_[string map {"-" "_"} [string toupper $key]] $value + } + } + set result {} + foreach {name value} $outdict { + append result $name \x00 $value \x00 + } + return "[string length $result]:$result," } proc ::scgi::test::send {port headers body} { - set sock [socket localhost $port] - variable reply - set reply($sock) {} - if {![dict exists $headers HOST]} { - dict set headers HOST localhost - } - dict set headers REMOTE_IP 127.0.0.1 - dict set headers REMOTE_HOST localhost - - chan configure $sock -translation binary -blocking 0 -buffering full -buffersize 4096 - chan event $sock readable [list ::scgi::test::get_reply $sock] - set block [::scgi::encode_request $headers $body {}] - puts -nonewline $sock $block - flush $sock - puts -nonewline $sock $body - flush $sock - while {$reply($sock) eq {}} { - update - } - #vwait [namespace current]::reply($sock) - return $reply($sock) + set sock [socket localhost $port] + variable reply + set reply($sock) {} + + if {![dict exists $headers HOST]} { + dict set headers HOST localhost + } + dict set headers REMOTE_IP 127.0.0.1 + dict set headers REMOTE_HOST localhost + + chan configure $sock -translation binary -blocking 0 -buffering full -buffersize 4096 + chan event $sock readable [list ::scgi::test::get_reply $sock] + + set block [::scgi::encode_request $headers $body {}] + + puts -nonewline $sock $block + flush $sock + puts -nonewline $sock $body + flush $sock + + while {$reply($sock) eq {}} { + update + } + + #vwait [namespace current]::reply($sock) + + #puts ZZ\t[join [split $reply($sock) \n] "|\nZZ\t"]| + return $reply($sock) } proc ::scgi::test::get_reply {sock} { - variable buffer - set data [read $sock] - append buffer($sock) $data - if {[eof $sock]} { - chan event $sock readable {} - set [namespace current]::reply($sock) $buffer($sock) - unset buffer($sock) - } + variable buffer + set data [read $sock] + append buffer($sock) $data + if {[eof $sock]} { + chan event $sock readable {} + set [namespace current]::reply($sock) $buffer($sock) + unset buffer($sock) + } } namespace eval ::scgi { variable server_block {SCGI 1.0 SERVER_SOFTWARE {TclScgiServer/0.1}} } ### # Build the reply class ### + ::clay::define ::scgi::test::reply { - superclass ::httpd::reply + superclass ::httpd::reply - method reset {} { - my variable reply_body - my reply replace [my HttpHeaders_Default] - set reply_body {} - } + method reset {} { + my variable reply_body + my reply replace [my HttpHeaders_Default] + set reply_body {} + } } ### # Build the server ### + ::clay::define scgi::test::app { - superclass ::httpd::server.scgi + superclass ::httpd::server.scgi - clay set reply_class ::scgi::test::reply + clay set reply_class ::scgi::test::reply } -puts [list ::test::content.file [info commands ::test::content.file]] +::DEBUG puts [list ::test::content.file [info commands ::test::content.file]] + scgi::test::app create TESTSCGI port 10003 doc_root $::TESTDIR + TESTSCGI plugin dict_dispatch -TESTSCGI uri add * / [list mixin {reply ::test::content.echo}] -TESTSCGI uri add * /echo [list mixin {reply ::test::content.echo}] -TESTSCGI uri add * /file [list mixin {reply ::test::content.file}] -TESTSCGI uri add * /time [list mixin {reply ::test::content.time}] +TESTSCGI uri add * / [list mixin {reply ::test::content.echo}] +TESTSCGI uri add * /echo [list mixin {reply ::test::content.echo}] +TESTSCGI uri add * /file [list mixin {reply ::test::content.file} path $::TESTDIR] +TESTSCGI uri add * /time [list mixin {reply ::test::content.time}] TESTSCGI uri add * /error [list mixin {reply ::test::content.error}] +TESTSCGI uri add * /string [list mixin {reply ::test::content.string} hardcoded_string cherry] ::DEBUG puts scgi-client-0001 -test scgi-client-0001 {Do an echo request} { - -set reply [::scgi::test::send 10003 {REQUEST_METHOD POST REQUEST_URI /echo} {THIS IS MY CODE}] -set checkreply {Status: 200 OK -Content-Type: text/plain -Connection: close -Content-Length: * - -THIS IS MY CODE} -::httpd::test::compare $reply $checkreply -} {} - +test scgi-client-0001 {Do an echo request} -body { + ::scgi::test::send 10003 {REQUEST_METHOD POST REQUEST_URI /echo} {THIS IS MY CODE} +} -match glob -result [200+status-head {THIS IS MY CODE}] ::DEBUG puts scgi-client-0002 -test scgi-client-0002 {Do another echo request} { -set reply [::scgi::test::send 10003 {REQUEST_METHOD POST REQUEST_URI /echo} {THOUGH THERE ARE MANY LIKE IT}] -set checkreply {Status: 200 OK -Content-Type: text/plain -Connection: close -Content-Length: * - -THOUGH THERE ARE MANY LIKE IT} -::httpd::test::compare $reply $checkreply -} {} +test scgi-client-0002 {Do another echo request} -body { + ::scgi::test::send 10003 {REQUEST_METHOD POST REQUEST_URI /echo} {THOUGH THERE ARE MANY LIKE IT} +} -match glob -result [200+status-head {THOUGH THERE ARE MANY LIKE IT}] ::DEBUG puts scgi-client-0003 -test scgi-client-0003 {Do another echo request} { -set reply [::scgi::test::send 10003 {REQUEST_METHOD POST REQUEST_URI /echo} {THIS ONE ALONE IS MINE}] -set checkreply {Status: 200 OK -Content-Type: text/plain -Connection: close -Content-Length: * - -THIS ONE ALONE IS MINE} -::httpd::test::compare $reply $checkreply -} {} +test scgi-client-0003 {Do another echo request} -body { + ::scgi::test::send 10003 {REQUEST_METHOD POST REQUEST_URI /echo} {THIS ONE ALONE IS MINE} +} -match glob -result [200+status-head {THIS ONE ALONE IS MINE}] ::DEBUG puts scgi-client-0004 -test scgi-client-0004 {URL Generates Error} { - -set reply [::scgi::test::send 10003 {REQUEST_METHOD POST REQUEST_URI /error} {THIS ONE ALONE IS MINE}] - -set checkreply {Status: 500 Server Internal Error -Content-Type: text/plain -Connection: close -Content-Length: * - -500 Server Internal Error -} -::httpd::test::compare $reply $checkreply -} {} - -set checkreply [subst {Status: 200 OK -Content-Type: text/plain -Connection: close -Content-Length: * - -[clock seconds]}] +test scgi-client-0004 {URL Generates Error} -body { + ::scgi::test::send 10003 {REQUEST_METHOD POST REQUEST_URI /error} {THIS ONE ALONE IS MINE} +} -match glob -result [500+status-head] ::DEBUG puts scgi-client-0005 -test scgi-client-0005 {URL Different output with a different request} { -set reply [::scgi::test::send 10003 {REQUEST_METHOD POST REQUEST_URI /time} {THIS ONE ALONE IS MINE}] - -::httpd::test::compare $reply $checkreply -} {} - -set fin [open [file join $TESTDIR pkgIndex.tcl] r] -set checkfile [read $fin] -close $fin - -### -# Nerfed: There is something screwy that is preventing this test from working -# properly in Sak. But only this test, and not the other two (normal client and proxy) -# who are doing essentially the same operation -# Investigate at some point - Sean -### -#::DEBUG puts scgi-client-0006 -#test scgi-client-0006 {Return a file} { -#set reply [::scgi::test::send 10003 {REQUEST_METHOD GET REQUEST_URI /file} {}] - -#set checkreply "Status: 200 OK -#Content-Type: text/plain -#Connection: close -#Content-Length: [string length $checkfile] - -#$checkfile" -#::httpd::test::compare $reply $checkreply -#} {} +test scgi-client-0005 {URL Different output with a different request} -body { + ::scgi::test::send 10003 {REQUEST_METHOD POST REQUEST_URI /time} {THIS ONE ALONE IS MINE} +} -match glob -result [200+status-head $::NOW] + +::DEBUG puts scgi-client-0006 +test scgi-client-0006 {Return a file} -body { + ::scgi::test::send 10003 {REQUEST_METHOD GET REQUEST_URI /file} {} +} -result [IndexReply Status:] + + +::DEBUG puts scgi-client-0008 +test scgi-client-0008 {Pull a constant string} -body { + ::scgi::test::send 10003 {REQUEST_METHOD GET REQUEST_URI /string} {} +} -match glob -result [200+status-head cherry] +### +# Test the all object have been destroyed after ::clay::cleanup +### +test httpd-garbage-collection {Test that garbage collection leaves nothing behind} -body { + ::clay::cleanup + info commands ::httpd::object::* +} -result {} ::DEBUG puts all-tests-finished -file delete [file join $TESTDIR test.tcl] # ------------------------------------------------------------------------- testsuiteCleanup # Local variables: Index: modules/ident/ident.man ================================================================== --- modules/ident/ident.man +++ modules/ident/ident.man @@ -48,7 +48,7 @@ [list_end] [list_end] [vset CATEGORY ident] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/imap4/imap4.man ================================================================== --- modules/imap4/imap4.man +++ modules/imap4/imap4.man @@ -1,6 +1,7 @@ -[manpage_begin imap4 n 0.5.3] +[vset VERSION 0.5.3] +[manpage_begin imap4 n [vset VERSION]] [see_also ftp] [see_also http] [see_also imap] [see_also mime] [see_also pop3] @@ -13,13 +14,13 @@ [keywords rfc3501] [keywords ssl] [keywords tls] [moddesc {imap client}] [titledesc {imap client-side tcl implementation of imap protocol}] - +[category Networking] [require Tcl 8.5] -[require imap4 [opt 0.5.2]] +[require imap4 [opt [vset VERSION]]] [description] The [package imap4] library package provides the client side of the [emph "Internet Message Access Protocol"] (IMAP) using standard @@ -359,9 +360,9 @@ [para] OpenSSL, [uri http://www.openssl.org/] [vset CATEGORY imap4] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] Only a small part of rfc3501 implemented. [manpage_end] Index: modules/inifile/ini.man ================================================================== --- modules/inifile/ini.man +++ modules/inifile/ini.man @@ -94,7 +94,7 @@ is [const \;]. [list_end] [vset CATEGORY inifile] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/interp/deleg_method.man ================================================================== --- modules/interp/deleg_method.man +++ modules/interp/deleg_method.man @@ -43,7 +43,7 @@ method will not wait for a result and return immediately. [list_end] [vset CATEGORY interp] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/interp/deleg_proc.man ================================================================== --- modules/interp/deleg_proc.man +++ modules/interp/deleg_proc.man @@ -41,7 +41,7 @@ procedure will not wait for a result and return immediately. [list_end] [vset CATEGORY interp] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/interp/tcllib_interp.man ================================================================== --- modules/interp/tcllib_interp.man +++ modules/interp/tcllib_interp.man @@ -68,7 +68,7 @@ The result of the command is the empty string. [list_end] [vset CATEGORY interp] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/irc/irc.man ================================================================== --- modules/irc/irc.man +++ modules/irc/irc.man @@ -234,7 +234,7 @@ Returns the message portion of the command (the part after the :). [list_end] [vset CATEGORY irc] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/javascript/javascript.man ================================================================== --- modules/javascript/javascript.man +++ modules/javascript/javascript.man @@ -90,7 +90,7 @@ of child html checkbox object to create. [list_end] [vset CATEGORY javascript] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/jpeg/jpeg.man ================================================================== --- modules/jpeg/jpeg.man +++ modules/jpeg/jpeg.man @@ -190,7 +190,7 @@ cant write exif data gps exif data not parsed makernote data not yet implemented [vset CATEGORY jpeg] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/json/json.man ================================================================== --- modules/json/json.man +++ modules/json/json.man @@ -108,7 +108,7 @@ [section RELATED] To write json, instead of parsing it, see package [package json::write]. [vset CATEGORY json] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/json/json_write.man ================================================================== --- modules/json/json_write.man +++ modules/json/json_write.man @@ -86,7 +86,7 @@ [section RELATED] To parse json, instead of writing it, see package [package json]. [vset CATEGORY json] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/lambda/lambda.man ================================================================== --- modules/lambda/lambda.man +++ modules/lambda/lambda.man @@ -83,7 +83,7 @@ [section AUTHORS] Andreas Kupries [vset CATEGORY lambda] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/lazyset/lazyset.man ================================================================== --- modules/lazyset/lazyset.man +++ modules/lazyset/lazyset.man @@ -74,7 +74,7 @@ [section AUTHORS] Roy Keene [vset CATEGORY utility] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/ldap/ldap.man ================================================================== --- modules/ldap/ldap.man +++ modules/ldap/ldap.man @@ -543,7 +543,7 @@ ldap::unbind $handle ldap::disconnect $handle }] [vset CATEGORY ldap] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/ldap/ldapx.man ================================================================== --- modules/ldap/ldapx.man +++ modules/ldap/ldapx.man @@ -768,7 +768,7 @@ }] [section References] [vset CATEGORY ldap] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/log/log.man ================================================================== --- modules/log/log.man +++ modules/log/log.man @@ -283,7 +283,7 @@ [const debug] are suppressed. This is done intentionally, because (we believe that) in most situations debugging output is not wanted. Most people wish to have such output only when actually debugging an application. [vset CATEGORY log] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/log/logger.man ================================================================== --- modules/log/logger.man +++ modules/log/logger.man @@ -391,7 +391,7 @@ ${log}::logproc debug log_local_var } ] [vset CATEGORY logger] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/log/loggerAppender.man ================================================================== --- modules/log/loggerAppender.man +++ modules/log/loggerAppender.man @@ -59,7 +59,7 @@ applicable options. [list_end] [vset CATEGORY logger] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/log/loggerUtils.man ================================================================== --- modules/log/loggerUtils.man +++ modules/log/loggerUtils.man @@ -143,7 +143,7 @@ ${log}::error "this is an error" }] [list_end] [vset CATEGORY logger] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/markdown/markdown.man ================================================================== --- modules/markdown/markdown.man +++ modules/markdown/markdown.man @@ -47,7 +47,7 @@ Reset the language counters. [list_end] [vset CATEGORY textutil] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/ChangeLog ================================================================== --- modules/math/ChangeLog +++ modules/math/ChangeLog @@ -1,5 +1,24 @@ +2019-05-07 Arjen Markus + * quasirandom.test: Add tests to deal with procedures in a different namespace + * quasirandom.tcl: Deal with procedures in a different namespace + +2019-04-24 Arjen Markus + * quasirandom.test: Add support code + * numtheory.tcl: Add estimation of the number of primes between two limits + * numtheory.test: Add tests regarding the estimated number of primes + +2019-04-23 Arjen Markus + * quasirandom.tcl: New package - generate quasi-random numbers (for instance for estimating multidimensional integrals) + * quasirandom.test: Tests for the new package + * quasirandom.man: Documentation for the new package + * pkgIndex.tcl: Add the new package + +2019-04-18 Arjen Markus + * misc.tcl: Add double() to calculation of mean and standard deviation in proc stats (ticket 0a030f850d4e3fc05da98aa954a6ec1b16e655d9) + * math.test: Correct the outcome of the test for stats (consequence of ticket 0a030f850d4e3fc05da98aa954a6ec1b16e655d9) + 2018-08-04 Arjen Markus * statistics.tcl: Source stat_wasserstein.tcl and stat_logit.tcl - for new commands * statistics.test: Add corresponding tests * statistics.man: Add description of these commands * pkgIndex.tcl: Bump the version to 1.3.0 Index: modules/math/bigfloat.man ================================================================== --- modules/math/bigfloat.man +++ modules/math/bigfloat.man @@ -426,7 +426,7 @@ set angle3 [lb]asin [lb]add [lb]mul $sinProduct [lb]cos $opposite3[rb][rb] $cosProduct[rb][rb] puts "angle3 : [lb]tostr [lb]rad2deg $angle3[rb][rb]" [example_end] [vset CATEGORY {math :: bignum :: float}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/bignum.man ================================================================== --- modules/math/bignum.man +++ modules/math/bignum.man @@ -222,7 +222,7 @@ [list_end] [para] [vset CATEGORY {math :: bignum}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/calculus.man ================================================================== --- modules/math/calculus.man +++ modules/math/calculus.man @@ -445,7 +445,7 @@ set y [lb]::math::calculus::boundaryValueSecondOrder \ coeffs force {0.0 1.0} [lb]list $length 0.0[rb] 100[rb] [example_end] [vset CATEGORY {math :: calculus}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/combinatorics.man ================================================================== --- modules/math/combinatorics.man +++ modules/math/combinatorics.man @@ -102,7 +102,7 @@ least 1. [list_end] [vset CATEGORY math] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/constants.man ================================================================== --- modules/math/constants.man +++ modules/math/constants.man @@ -130,7 +130,7 @@ [def [const tiny]] (Approximately) smallest number not equal zero [def [const eps]] Smallest number such that 1+eps != 1 [list_end] [vset CATEGORY {math :: constants}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/decimal.man ================================================================== --- modules/math/decimal.man +++ modules/math/decimal.man @@ -193,7 +193,7 @@ [list_end] [para] [vset CATEGORY decimal] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/decimal.test ================================================================== --- modules/math/decimal.test +++ modules/math/decimal.test @@ -3,12 +3,10 @@ # # This file contains a collection of tests for one or more of the Tcllib # procedures. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # -# $Id: decimal.test,v 1.3 2011/11/09 18:33:22 andreas_kupries Exp $ -# # Copyright (c) 2011 by Mark Alston # All rights reserved. # # ------------------------------------------------------------------------- Index: modules/math/fourier.man ================================================================== --- modules/math/fourier.man +++ modules/math/fourier.man @@ -128,7 +128,7 @@ [para] [list_end] [vset CATEGORY {math :: fourier}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/fuzzy.man ================================================================== --- modules/math/fuzzy.man +++ modules/math/fuzzy.man @@ -127,7 +127,7 @@ D. Knuth, Art of Computer Programming, Vol. 1, Problem 1.2.4-5. [vset CATEGORY {math :: fuzzy}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/interpolate.man ================================================================== --- modules/math/interpolate.man +++ modules/math/interpolate.man @@ -293,7 +293,7 @@ 1.0: 4.12 }] As you can see, the values at the abscissae are reproduced perfectly. [vset CATEGORY {math :: interpolate}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/linalg.man ================================================================== --- modules/math/linalg.man +++ modules/math/linalg.man @@ -962,7 +962,7 @@ scaleTk .scale ... } }] [vset CATEGORY {math :: linearalgebra}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/machineparameters.man ================================================================== --- modules/math/machineparameters.man +++ modules/math/machineparameters.man @@ -185,7 +185,7 @@ Print machine parameters on standard output. [list_end] [vset CATEGORY math] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/math.man ================================================================== --- modules/math/math.man +++ modules/math/math.man @@ -120,7 +120,7 @@ Return the sum of one or more numeric values. [list_end] [vset CATEGORY math] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/math.test ================================================================== --- modules/math/math.test +++ modules/math/math.test @@ -216,11 +216,11 @@ foreach {a b c} [ math::stats 100 100 100 110 ] { break } set a [ expr round($a) ] set b [ expr round($b) ] set c [ expr round($c) ] list $a $b $c -} {102 5 5} +} {103 5 5} test math-9.1 { math::integrate, insufficient data points } { catch { math::integrate {1 10 2 20 3 30 4 40} } msg set msg } "at least 5 x,y pairs must be given" Index: modules/math/math_geometry.man ================================================================== --- modules/math/math_geometry.man +++ modules/math/math_geometry.man @@ -609,7 +609,7 @@ [enum] [uri http://en.wikipedia.org/wiki/Line-line_intersection] [enum] [uri http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/] [list_end] [vset CATEGORY {math :: geometry}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/misc.tcl ================================================================== --- modules/math/misc.tcl +++ modules/math/misc.tcl @@ -4,11 +4,11 @@ # # Copyright (c) 1998-2000 by Ajuba Solutions. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# +# # RCS: @(#) $Id: misc.tcl,v 1.6 2005/10/10 14:02:47 arjenmarkus Exp $ package require Tcl 8.2 ;# uses [lindex $l end-$integer] namespace eval ::math { } @@ -34,13 +34,13 @@ set mean [ expr { $sum/$N } ] set sigma_sq 0 foreach val [ concat $val1 $val2 $args ] { set sigma_sq [ expr { $sigma_sq+pow(($val-$mean),2) } ] } - set sigma_sq [ expr { $sigma_sq/($N-1) } ] + set sigma_sq [ expr { $sigma_sq/($N-1) } ] set sigma [ expr { sqrt($sigma_sq) } ] - if { $mean != 0.0 } { + if { $mean != 0.0 } { set cov [ expr { ($sigma/$mean)*100 } ] } else { return -code error -errorinfo "Cov undefined for data with zero mean" -errorcode {ARITH DOMAIN} } set cov @@ -72,61 +72,61 @@ } # ::math::integrate -- # # calculate the area under a curve defined by a set of (x,y) data pairs. -# the x data must increase monotonically throughout the data set for the +# the x data must increase monotonically throughout the data set for the # calculation to be meaningful, therefore the monotonic condition is # tested, and an error is thrown if the x value is found to be # decreasing. # # Arguments: # xy_pairs list of x y pairs (eg, 0 0 10 10 20 20 ...); at least 5 # data pairs are required, and if the number of data # pairs is even, a padding value of (x0, 0) will be # added. -# +# # Results: # result A two-element list consisting of the area and error # bound (calculation is "Simpson's rule") proc ::math::integrate { xy_pairs } { - + set length [ llength $xy_pairs ] - + if { $length < 10 } { return -code error "at least 5 x,y pairs must be given" - } - + } + ;## are we dealing with x,y pairs? if { [ expr {$length % 2} ] } { return -code error "unmatched xy pair in input" } - + ;## are there an even number of pairs? Augment. if { ! [ expr {$length % 4} ] } { set xy_pairs [ concat [ lindex $xy_pairs 0 ] 0 $xy_pairs ] } set x0 [ lindex $xy_pairs 0 ] set x1 [ lindex $xy_pairs 2 ] set xn [ lindex $xy_pairs end-1 ] set xnminus1 [ lindex $xy_pairs end-3 ] - + if { $x1 < $x0 } { return -code error "monotonicity broken by x1" } if { $xn < $xnminus1 } { return -code error "monotonicity broken by xn" - } - + } + ;## handle the assymetrical elements 0, n, and n-1. set sum [ expr {[ lindex $xy_pairs 1 ] + [ lindex $xy_pairs end ]} ] set sum [ expr {$sum + (4*[ lindex $xy_pairs end-2 ])} ] set data [ lrange $xy_pairs 2 end-4 ] - + set xmax $x1 set i 1 foreach {x1 y1 x2 y2} $data { incr i if { $x1 < $xmax } { @@ -137,19 +137,19 @@ if { $x2 < $xmax } { return -code error "monotonicity broken by x$i" } set xmax $x2 set sum [ expr {$sum + (4*$y1) + (2*$y2)} ] - } - + } + if { $xmax > $xnminus1 } { return -code error "monotonicity broken by xn-1" - } - + } + set h [ expr { ( $xn - $x0 ) / $i } ] set area [ expr { ( $h / 3.0 ) * $sum } ] - set err_bound [ expr { ( ( $xn - $x0 ) / 180.0 ) * pow($h,4) * $xn } ] + set err_bound [ expr { ( ( $xn - $x0 ) / 180.0 ) * pow($h,4) * $xn } ] return [ list $area $err_bound ] } # ::math::max -- # @@ -283,14 +283,14 @@ set mean [ expr { $sum/$N } ] set sigma_sq 0 foreach val [ concat $val1 $val2 $args ] { set sigma_sq [ expr { $sigma_sq+pow(($val-$mean),2) } ] } - set sigma_sq [ expr { $sigma_sq/($N-1) } ] + set sigma_sq [ expr { $sigma_sq/($N-1) } ] set sigma [ expr { sqrt($sigma_sq) } ] set sigma -} +} # ::math::stats -- # # Return the mean, standard deviation, and coefficient of variation as # percent, as a list. @@ -307,16 +307,16 @@ set sum [ expr { $val1+$val2 } ] set N [ expr { [ llength $args ] + 2 } ] foreach val $args { set sum [ expr { $sum+$val } ] } - set mean [ expr { $sum/$N } ] + set mean [ expr { $sum/double($N) } ] set sigma_sq 0 foreach val [ concat $val1 $val2 $args ] { set sigma_sq [ expr { $sigma_sq+pow(($val-$mean),2) } ] } - set sigma_sq [ expr { $sigma_sq/($N-1) } ] + set sigma_sq [ expr { $sigma_sq/double($N-1) } ] set sigma [ expr { sqrt($sigma_sq) } ] set cov [ expr { ($sigma/$mean)*100 } ] return [ list $mean $sigma $cov ] } Index: modules/math/numtheory.dtx ================================================================== --- modules/math/numtheory.dtx +++ modules/math/numtheory.dtx @@ -1763,11 +1763,11 @@ % \begin{tcl} %<*man> [list_end] [vset CATEGORY {math :: numtheory}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] % % \end{tcl} % % \begin{tcl} Index: modules/math/numtheory.man ================================================================== --- modules/math/numtheory.man +++ modules/math/numtheory.man @@ -177,29 +177,37 @@ [call [cmd math::numtheory::numberPrimesGauss] [arg N]] Estimate the number of primes according the formula by Gauss. [list_begin arguments] [arg_def integer N in] -Number in question +Number in question, should be larger than 0 [list_end] [call [cmd math::numtheory::numberPrimesLegendre] [arg N]] Estimate the number of primes according the formula by Legendre. [list_begin arguments] [arg_def integer N in] -Number in question +Number in question, should be larger than 0 [list_end] [call [cmd math::numtheory::numberPrimesLegendreModified] [arg N]] Estimate the number of primes according the modified formula by Legendre. [list_begin arguments] [arg_def integer N in] -Number in question +Number in question, should be larger than 0 +[list_end] + +[call [cmd math::numtheory::differenceNumberPrimesLegendreModified] [arg lower] [arg upper]] +Estimate the number of primes between tow limits according the modified formula by Legendre. + +[list_begin arguments] +[arg_def integer lower in] Lower limit for the primes, should be larger than 0 +[arg_def integer upper in] Upper limit for the primes, should be larger than 0 [list_end] [list_end] [vset CATEGORY {math :: numtheory}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/numtheory.test ================================================================== --- modules/math/numtheory.test +++ modules/math/numtheory.test @@ -1,14 +1,14 @@ -## +## ## This is the file `numtheory.test', ## generated with the SAK utility ## (sak docstrip/regen). -## +## ## The original source files were: -## +## ## numtheory.dtx (with options: `test test_common') -## +## ## In other words: ## ************************************** ## * This Source is not the True Source * ## ************************************** ## the true source is the file from which this one was generated. @@ -22,10 +22,16 @@ testing { useLocal numtheory.tcl math::numtheory } +proc compareRounded {expected actual} { + return [expr {int($expected-$actual) == 0} ] +} + +::tcltest::customMatch rounded compareRounded + test prime_trialdivision-1 "Trial division of 1" -body { ::math::numtheory::prime_trialdivision 1 } -returnCodes 2 -result 0 test prime_trialdivision-2 "Trial division of 2" -body { ::math::numtheory::prime_trialdivision 2 @@ -205,9 +211,30 @@ namespace eval ::math::numtheory { rename Miller--Rabin "" rename _orig_Miller--Rabin Miller--Rabin } } + +test numberPrimes-1.0 "Number of primes below 100" -match rounded -body { + set result [::math::numtheory::numberPrimesLegendre 100] +} -result 28 + +test numberPrimes-1.1 "Number of primes below 100 (modified)" -match rounded -body { + set result [::math::numtheory::numberPrimesLegendreModified 100] +} -result 28 + +test numberPrimes-1.2 "Number of primes below 0 (modified)" -body { + set result [::math::numtheory::numberPrimesLegendreModified 0] +} -result "The limit must be larger than 1" -returnCodes 1 + +test numberPrimes-1.3 "Number of primes between 100 and 200" -match rounded -body { + set result [::math::numtheory::differenceNumberPrimesLegendreModified 100 200] +} -result 19 + +test numberPrimes-1.4 "Number of primes between 100 and 0 - error expected" -body { + set result [::math::numtheory::differenceNumberPrimesLegendreModified 100 0] +} -result "The upper limit must be larger than 1" -returnCodes 1 + testsuiteCleanup -## -## +## +## ## End of file `numtheory.test'. Index: modules/math/optimize.man ================================================================== --- modules/math/optimize.man +++ modules/math/optimize.man @@ -319,7 +319,7 @@ The theory of linear programming is the subject of many a text book and the Simplex algorithm that is implemented here is the best-known method to solve this type of problems, but it is not the only one. [vset CATEGORY {math :: optimize}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/pca.man ================================================================== --- modules/math/pca.man +++ modules/math/pca.man @@ -130,7 +130,7 @@ TODO: NIST example [vset CATEGORY PCA] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/pkgIndex.tcl ================================================================== --- modules/math/pkgIndex.tcl +++ modules/math/pkgIndex.tcl @@ -28,9 +28,10 @@ package ifneeded math::bigfloat 2.0.2 [list source [file join $dir bigfloat2.tcl]] package ifneeded math::numtheory 1.1.1 [list source [file join $dir numtheory.tcl]] package ifneeded math::decimal 1.0.3 [list source [file join $dir decimal.tcl]] package ifneeded math::geometry 1.3.0 [list source [file join $dir geometry.tcl]] package ifneeded math::trig 1.0 [list source [file join $dir trig.tcl]] +package ifneeded math::quasirandom 1.0 [list source [file join $dir quasirandom.tcl]] if {![package vsatisfies [package require Tcl] 8.6]} {return} -package ifneeded math::exact 1.0 [list source [file join $dir exact.tcl]] +package ifneeded math::exact 1.0.1 [list source [file join $dir exact.tcl]] package ifneeded math::PCA 1.0 [list source [file join $dir pca.tcl]] Index: modules/math/polynomials.man ================================================================== --- modules/math/polynomials.man +++ modules/math/polynomials.man @@ -213,7 +213,7 @@ definition, it consists of a list of two elements: the keyword "POLYNOMIAL" and the list of coefficients in descending order. The latter makes it easier to implement Horner's rule. [vset CATEGORY {math :: polynomials}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/primes.tcl ================================================================== --- modules/math/primes.tcl +++ modules/math/primes.tcl @@ -1,14 +1,14 @@ -## +## ## This is the file `primes.tcl', ## generated with the SAK utility ## (sak docstrip/regen). -## +## ## The original source files were: -## +## ## numtheory.dtx (with options: `pkg_primes pkg_common') -## +## ## In other words: ## ************************************** ## * This Source is not the True Source * ## ************************************** ## the true source is the file from which this one was generated. @@ -24,11 +24,12 @@ variable nextPrimeCandidate 19 variable nextPrimeIncrement 1 ;# Examine numbers 6n+1 and 6n+5 namespace export firstNprimes primesLowerThan primeFactors uniquePrimeFactors factors \ totient moebius legendre jacobi gcd lcm \ - numberPrimesGauss numberPrimesLegendre numberPrimesLegendreModified + numberPrimesGauss numberPrimesLegendre numberPrimesLegendreModified \ + differenceNumberPrimesLegendreModified } # ComputeNextPrime -- # Determine the next prime # @@ -463,8 +464,35 @@ if { $limit <= 1 } { return -code error "The limit must be larger than 1" } expr {$limit / (log($limit) - 1.08366)} } -## -## + +# differenceNumberPrimesLegendreModified -- +# Return the approximate difference number of primes +# between a lower and higher limit as given values +# for approximate number of primes based on the +# modified formula by Legendre +# +# Arguments: +# limit1 The lower limit for the interval, largest prime to be included in the l.limit +# limit2 The upper limit for the interval, largest prime to be included in the u.mlimit +# +# Returns: +# Approximate difference number of primes +# +proc ::math::numtheory::differenceNumberPrimesLegendreModified {limit1 limit2} { + if { $limit1 <= 1 } { + return -code error "The lower limit must be larger than 1" + } + if { $limit2 <= 1 } { + return -code error "The upper limit must be larger than 1" + } + + set aa [::math::numtheory::numberPrimesLegendreModified [expr ($limit1)]] + set bb [::math::numtheory::numberPrimesLegendreModified [expr ($limit2)]] + expr {abs($bb-$aa)} +} + +## +## ## End of file `primes.tcl'. Index: modules/math/qcomplex.man ================================================================== --- modules/math/qcomplex.man +++ modules/math/qcomplex.man @@ -296,7 +296,7 @@ [list_end] [list_end] [vset CATEGORY {math :: complexnumbers}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] ADDED modules/math/quasirandom.man Index: modules/math/quasirandom.man ================================================================== --- /dev/null +++ modules/math/quasirandom.man @@ -0,0 +1,118 @@ +[vset VERSION 1] +[manpage_begin math::quasirandom n [vset VERSION]] +[keywords {quasi-random}] +[keywords mathematics] +[moddesc {Tcl Math Library}] +[titledesc {Quasi-random points for integration and Monte Carlo type methods}] +[category Mathematics] +[require Tcl 8.5] +[require TclOO] +[require math::quasirandom [vset VERSION]] +[description] +[para] + +In many applications pseudo-random numbers and pseudo-random points in a (limited) +sample space play an important role. For instance in any type of Monte Carlo simulation. +Pseudo-random numbers, however, may be too random and as a consequence a large +number of data points is required to reduce the error or fluctuation in the results +to the desired value. +[para] + +Quasi-random numbers can be used as an alternative: instead of "completely" arbitrary +points, points are generated that are diverse enough to cover the entire sample space +in a more or less uniform way. As a consequence convergence to the limit can be +much faster, when such quasi-random numbers are well-chosen. +[para] + +The package defines a [term class] "qrpoint" that creates a command to generate +quasi-random points in 1, 2 or more dimensions. The command can either generate +separate points, so that they can be used in a user-defined algorithm or use these +points to calculate integrals of functions defined over 1, 2 or more dimensions. +It also holds several other common algorithms. (NOTE: these are not implemented yet) +[para] +One particular characteristic of the generators is that there are no tuning parameters +involved, which makes the use particularly simple. + + +[section "COMMANDS"] +A quasi-random point generator is created using the [term qrpoint] class: + +[list_begin definitions] + +[call [cmd "::math::quasirandom::qrpoint create"] [arg NAME] [arg DIM] [opt ARGS]] +This command takes the following arguments: + +[list_begin arguments] +[arg_def string NAME] The name of the command to be created (alternatively: the [term new] subcommand +will generate a unique name) +[arg_def integer/string DIM] The number of dimensions or one of: "circle", "disk", "sphere" or "ball" +[arg_def strings ARGS] Zero or more key-value pairs. The supported options are: + +[list_begin itemized] +[item] [term {-start index}]: The index for the next point to be generated (default: 1) +[item] [term {-evaluations number}]: The number of evaluations to be used by default (default: 100) +[list_end] + +[list_end] + +[list_end] + +The points that are returned lie in the hyperblock [lb]0,1[lb]^n (n the number of dimensions) +or on the unit circle, within the unit disk, on the unit sphere or within the unit ball. +[para] + +Each generator supports the following subcommands: +[list_begin definitions] + +[call [cmd "gen next"]] +Return the coordinates of the next quasi-random point +[nl] + +[call [cmd "gen set-start"] [arg index]] +Reset the index for the next quasi-random point. This is useful to control which list of points is returned. +Returns the new or the current value, if no value is given. +[nl] + +[call [cmd "gen set-evaluations"] [arg number]] +Reset the default number of evaluations in compound algorithms. Note that the actual number is the +smallest 4-fold larger or equal to the given number. (The 4-fold plays a role in the detailed integration +routine.) +[nl] + +[call [cmd "gen integral"] [arg func] [arg minmax] [arg args]] +Calculate the integral of the given function over the block (or the circle, sphere etc.) + +[list_begin arguments] +[arg_def string func] The name of the function to be integrated + +[arg_def list minmax] List of pairs of minimum and maximum coordinates. This can be used to +map the quasi-random coordinates to the desired hyper-block. +[nl] +If the space is a circle, disk etc. then this argument should be a single value, the radius. +The circle, disk, etc. is centred at the origin. If this is not what is required, then a coordinate +transformation should be made within the function. + +[arg_def strings args] Zero or more key-value pairs. The following options are supported: +[list_begin itemized] +[item] [term {-evaluations number}]: The number of evaluations to be used. If not specified use the +default of the generator object. +[list_end] + +[list_end] + +[list_end] + +[section TODO] +Implement other algorithms and variants +[para] +Implement more unit tests. +[para] +Comparison to pseudo-random numbers for integration. + + +[section References] + +Various algorithms exist for generating quasi-random numbers. The generators created in this package are based on: +[uri http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/] + +[manpage_end] ADDED modules/math/quasirandom.tcl Index: modules/math/quasirandom.tcl ================================================================== --- /dev/null +++ modules/math/quasirandom.tcl @@ -0,0 +1,517 @@ +# quasirandom.tcl -- +# Generate quasi-random points in n dimensions and provide simple +# methods to evaluate an integral +# +# Note: provide a OO-style interface +# +# TODO: integral-detailed, minimum, maximum +# +# Based on the blog "The Unreasonable Effectiveness of Quasirandom Sequences" by Martin Roberts, +# http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/ +# + +package require Tcl 8.5 +package require TclOO + +package provide math::quasirandom 1.0 + +namespace eval ::math::quasirandom { + +# qrpoints -- +# Create the class +# +::oo::class create qrpoints { + + # constructor -- + # Construct a new instance of the qrpoints class + # + # Arguments: + # dim Number of dimensions, or one of: circle, disk, sphere, ball + # args Zero or more key-value pairs: + # -start - start the generation with the given multiplier (integer) + # -evaluations - default number of evaluations for the integration + # (possibly others as well) + # + constructor {dimin args} { + my variable dim + my variable coord_factors + my variable step + my variable evaluations + my variable use_radius + my variable effective_dim + + if { ( ![string is integer -strict $dimin] || $dimin <= 0 ) && $dimin ni {circle disk sphere ball} } { + return -code error "The dimension argument should be a positive integer value or one of circle, disk, sphere or ball" + } + + set use_radius 1 + switch -- $dimin { + "circle" { + set dim 1 + set effective_dim 2 + ::oo::objdefine [self] { + forward next my CircleNext + forward Volume my CircleVolume + } + } + "disk" { + set dim 2 + set effective_dim 2 + ::oo::objdefine [self] { + forward next my DiskNext + forward Volume my DiskVolume + } + } + "sphere" { + set dim 2 + set effective_dim 3 + ::oo::objdefine [self] { + forward next my SphereNext + forward Volume my SphereVolume + } + } + "ball" { + set dim 3 + set effective_dim 3 + ::oo::objdefine [self] { + forward next my BallNext + forward Volume my BallVolume + } + } + default { + set dim $dimin + set use_radius 0 + ::oo::objdefine [self] { + forward next my PlainNext + forward Volume my PlainVolume + } + } + } + + set step 1 + set evaluations 100 + + set coord_factors [::math::quasirandom::CoordFactors $dim] + + foreach {key value} $args { + switch -- $key { + "-start" { + + my set-step $value + } + "-evaluations" { + if { ![string is -strict integer $value] || $value <= 0 } { + return -code error "The value for the option $key should be a positive integer value" + } + + my set-evaluations $value + } + default { + return -code error "Unknown option: $key -- value: $value" + } + } + } + } + + # PlainNext -- + # Generate the next point - for a hyperblock + # + method PlainNext {} { + my variable step + my variable coord_factors + + set coords {} + foreach f $coord_factors { + lappend coords [expr {fmod( $f * $step, 1.0 )}] + } + + incr step + + return $coords + } + + # PlainVolume -- + # Calculate the volume of a hyperblock + # + # Arguments: + # minmax List of minimum and maximum per dimension + # + # Returns: + # The volume + # + method PlainVolume {minmax} { + set volume 1.0 + foreach range $minmax { + lassign $range xmin xmax + set volume [expr {$volume * ($xmax-$xmin)}] + } + return $volume + } + + # CircleNext -- + # Generate the next point on a unit circle + # + method CircleNext {} { + + set f [lindex [my PlainNext] 0] + set rad [expr {2.0 * acos(-1.0) * $f}] + + set coords [list [expr {cos($rad)}] [expr {sin($rad)}]] + + return $coords + } + + # CircleVolume -- + # Calculate the "volume" of the unit circle + # + # Arguments: + # radius Radius of the circle + # + method CircleVolume {radius} { + return [expr {$radius * 2.0*cos(-1.0)}] + } + + # DiskNext -- + # Generate the next point on a unit disk + # + method DiskNext {} { + + while {1} { + set coords [my PlainNext] + + lassign $coords x y + + if { hypot($x-0.5,$y-0.5) <= 0.25 } { + set coords [list [expr {2.0*$x-1.0}] [expr {2.0*$y-1.0}]] + break + } + } + return $coords + } + + # DiskVolume -- + # Calculate the "volume" of the unit disk + # + # Arguments: + # radius Radius of the disk + # + method DiskVolume {radius} { + return [expr {$radius**2 * cos(-1.0)}] + } + + # BallNext -- + # Generate the next point on a unit ball + # + method BallNext {} { + + while {1} { + set coords [my PlainNext] + + lassign $coords x y z + + set r [expr {($x-0.5)**2 + ($y-0.5)**2 + ($z-0.5)**2}] + if { $r <= 0.25 } { + set coords [list [expr {2.0*$x-1.0}] [expr {2.0*$y-1.0}] [expr {2.0*$z-1.0}]] + break + } + } + + return $coords + } + + # BallVolume -- + # Calculate the volume of the unit ball + # + # Arguments: + # radius Radius of the ball + # + method BallVolume {radius} { + return [expr {4.0/3.0 * $radius**3 * cos(-1.0)}] + } + + # SphereNext -- + # Generate the next point on a unit sphere + # + method SphereNext {} { + + set coords [my PlainNext] + + lassign $coords u v + + set phi [expr {2.0 * acos(-1.0) * $v}] + set lambda [expr {acos(2.0 * $u - 1.0) + 0.5 * acos(-1.0)}] + + set x [expr {cos($lambda) * cos($phi)}] + set y [expr {cos($lambda) * sin($phi)}] + set z [expr {sin($lambda)}] + + return [list $x $y $z] + } + + # SphereVolume -- + # Calculate the "volume" of the unit sphere + # + # Arguments: + # radius Radius of the sphere + # + method SphereVolume {radius} { + return [expr {4.0 * $radius**2 * cos(-1.0)}] + } + + # set-step -- + # Set the first step to be used + # + method set-step {{value ""}} { + my variable step + + if { $value eq "" } { + return $step + } + + if { ![string is integer -strict $value] } { + return -code error "The value for the option $key should be an integer value" + } + + set step [expr {int($value)}] + } + + # set-evaluations -- + # Set the number of evaluations for integration + # + method set-evaluations {{value ""}} { + my variable evaluations + + if { $value eq "" } { + return $evaluations + } + + if { ![string is integer -strict $value] || $value <= 0 } { + return -code error "The value for the option $key should be a positive integer value" + } + + set evaluations [expr {4*int(($value+3)/4)}] ;# Make sure it is a 4-fold + } + + # integral -- + # Evaluate the integral of a function over a given (rectangular) domain + # + # Arguments: + # func Function to be integrated + # minmax List of minimum and maximum bounds for each coordinate + # args Key-value pair: number of evaluations + # + # Returns: + # Estimate of the integral based on "evaluations" evaluations + # Note: no error estimate + # + method integral {func minmax args} { + my variable dim + my variable step + my variable coord_factors + my variable evaluations + my variable use_radius + my variable effective_dim + + set evals $evaluations + + set func [uplevel 1 [list namespace which -command $func]] + + foreach {key value} $args { + switch -- $key { + "-evaluations" { + if { ![string is integer -strict $value] || $value <= 0 } { + return -code error "The value for the option $key should be a positive integer value" + } + + set evals $value ;# Local only! + } + default { + return -code error "Unknown option: $key -- value: $value" + } + } + } + + if { ! $use_radius } { + if { [llength $minmax] != $dim } { + return -code error "The number of ranges (minmax) should be equal to the dimension ($dim)" + } else { + set volume [my Volume $minmax] + } + } else { + if { ! [string is double $minmax] } { + return -code error "For a circle, disk, sphere or ball only the radius should be given" + } else { + set radius $minmax + set minmax [lrepeat $effective_dim [list 0.0 $radius]] + set volume [my Volume $radius] + } + } + + set sum 0.0 + + for {set i 0} {$i < $evals} {incr i} { + set coords {} + foreach c [my next] range $minmax { + lassign $range xmin xmax + lappend coords [expr {$xmin + ($xmax-$xmin) * $c}] + } + set sum [expr {$sum + [$func $coords]}] + } + + return [expr {$sum * $volume / $evals}] + } + + # integral-detailed -- + # Evaluate the integral of a function over a given (rectangular) domain + # and provide detailed information + # + # Arguments: + # func Function to be integrated + # minmax List of minimum and maximum bounds for each coordinate + # args Key-value pair: number of evaluations + # + # Returns: + # Dictionary of: + # -estimate value - estimate of the integral + # -evaluations number - total number of evaluations + # -error value - estimate of the error + # -rawvalues list - list of raw values obtained for the integral + # + method integral-detailed {func minmax args} { + my variable evaluations + + set evals $evaluations + + set func [uplevel 1 [list namespace which -command $func]] + + foreach {key value} $args { + switch -- $key { + "-evaluations" { + if { ![string is integer -strict $value] || $value <= 0 } { + return -code error "The value for the option $key should be a positive integer value" + } + + set evals $value ;# Local only! + } + default { + return -code error "Unknown option: $key -- value: $value" + } + } + } + + lappend args -evaluations [expr {($evals+3)/4}] + + for {set i 0} {$i < 4} {incr i} { + lappend rawvalues [my integral $func $minmax {*}$args] + } + + set sum 0.0 + set sqsum 0.0 + + foreach value $rawvalues { + set sum [expr {$sum + $value}] + set sqsum [expr {$sqsum + $value**2}] + } + + set stdev [expr {sqrt(($sqsum - $sum**2/4.0)/3.0)}] + set sum [expr {$sum / 4.0}] + # Standard error of mean + return [dict create -estimate $sum -error [expr {$stdev/2.0}] -rawvalues $rawvalues -evaluations [expr {4*(($evals+3)/4)}]] + } + +} ;# End of class + +} ;# End of namespace eval + +# CoordFactors -- +# Determine the factors for the coordinates +# +# Arguments: +# dim Number of dimensions +# +proc ::math::quasirandom::CoordFactors {dim} { + set n [expr {$dim + 1}] + + set f 1.0 + for {set i 0} {$i < 10} {incr i} { + set f [expr {$f - ($f**$n-$f-1.0) / ($n*$f**($n-1)-1.0)}] + } + + set factors {} + set af 1.0 + + for {set i 0} {$i < $dim} {incr i} { + set af [expr {$af/$f}] + lappend factors $af + } + + return $factors +} + +# End of code for package + +# -------------------------------------------- +# test -- +# + +if {0} { + +::math::quasirandom::qrpoints create square 2 + +puts [square next] +puts [square next] +puts [square next] + + +proc f {coords} { + lassign $coords x y + + expr {$x**2+$y**2} +} + +proc g {coords} { + lassign $coords x y + + expr {(1.0-cos($x))**2 * (1.0-cos($y))**2} +} + +# Print four estimates - should not deviate too much from 10.0 +puts [square integral f {{0 1} {0 3}}] +puts [square integral f {{0 1} {0 3}}] +puts [square integral f {{0 1} {0 3}}] +puts [square integral f {{0 1} {0 3}}] + +# Print a sequence of estimates - should converge to (3pi/2)**2 +foreach n {20 40 100 300 1000} { + square set-evaluations $n + + puts "$n: [square integral g [list [list 0.0 [expr {acos(-1)}]] [list 0.0 [expr {acos(-1)}]]]]" +} + + +::math::quasirandom::qrpoints create block 3 +puts [block next] + +puts "Circle ..." +::math::quasirandom::qrpoints create circle circle +puts [circle next] +puts [circle next] +puts [circle next] + +# Test values for CoordFactors +# dim = 1: 1.6180339887498948482045... +# dim = 2: 1.3247179572447460259609... +# dim = 3: 1.2207440846057594753616... + +set f [::math::quasirandom::CoordFactors 1] +puts 1.6180339887498948482045... +puts [expr {1.0/$f}] + +set f [lindex [::math::quasirandom::CoordFactors 2] 0] +puts 1.3247179572447460259609... +puts [expr {1.0/$f}] + +set f [lindex [::math::quasirandom::CoordFactors 3] 0] +puts 1.2207440846057594753616... +puts [expr {1.0/$f}] +} ADDED modules/math/quasirandom.test Index: modules/math/quasirandom.test ================================================================== --- /dev/null +++ modules/math/quasirandom.test @@ -0,0 +1,498 @@ +# -*- tcl -*- +# quasirandom.test -- +# Tests for the quasi-random numbers package +# + +source [file join \ + [file dirname [file dirname [file join [pwd] [info script]]]] \ + devtools testutilities.tcl] + +testsNeedTcl 8.5 +testsNeedTcltest 2.1 + +testing { + useLocal quasirandom.tcl math::quasirandom +} + +# +# Functions for integration tests +# +proc const {coords} { + return 1.0 +} + +proc fx {coords} { + set x [lindex $coords 0] + return $x +} + +proc fy {coords} { + set y [lindex $coords 1] + return $y +} + +proc fz {coords} { + set z [lindex $coords 2] + return $z +} + +proc fxyz4 {coords} { + lassign $coords x y z + return [expr {($x*$y*$z)**4}] +} + +# +# Auxiliary proc +# +proc equalCoords {coords1 coords2} { + set equal 1 + foreach c1 $coords1 c2 $coords2 { + if { $c1 != $c2 } { + set equal 0 + break + } + } + return $equal +} + +# +# Create and register (in that order!) custom matching procedures +# +proc matchTolerant { expected actual } { + set match 1 + foreach a $actual e $expected { + if { $e != 0.0 } { + if { abs($e-$a)>1.0e-7*abs($e) && + abs($e-$a)>1.0e-7*abs($a) } { + set match 0 + break + } + } else { + if { abs($a) > 1.0e-7 } { + set match 0 + } + } + } + return $match +} +proc matchOnePercent { expected actual } { + set match 1 + foreach a $actual e $expected { + if { $e != 0.0 } { + if { abs($e-$a)>1.0e-2*abs($e) && + abs($e-$a)>1.0e-2*abs($a) } { + set match 0 + break + } + } else { + if { abs($a) > 1.0e-2 } { + set match 0 + } + } + } + return $match +} + +::tcltest::customMatch tolerant matchTolerant +::tcltest::customMatch error1percent matchOnePercent +::tcltest::customMatch equal equalCoords + + +# +# Testing CoordFactors: the basis of the algorithm +# Note: exact matching +# +test "Quasirandom-0.1" "Check basic factor for 1 dimension" -body { + set f [::math::quasirandom::CoordFactors 1] + return [expr {1.0/$f}] +} -result 1.618033988749895 + +test "Quasirandom-0.2" "Check basic factor for 2 dimensions" -body { + set f [lindex [::math::quasirandom::CoordFactors 2] 0] + return [expr {1.0/$f}] +} -result 1.324717957244746 + +test "Quasirandom-0.3" "Check basic factor for 3 dimensions" -body { + set f [lindex [::math::quasirandom::CoordFactors 3] 0] + return [expr {1.0/$f}] +} -result 1.2207440846057596 + +test "Quasirandom-0.4" "Check number of factors for 10 dimensions" -body { + return [llength [::math::quasirandom::CoordFactors 10]] +} -result 10 + +# +# Basic interface to the qrpoints class +# +test "Quasirandom-1.0" "Simple QR generator for two dimensions" -match tolerant -body { + ::math::quasirandom::qrpoints create simple 2 + + return [simple next] +} -result {0.7548776662466927 0.5698402909980532} -cleanup {simple destroy} + +test "Quasirandom-1.1" "Simple QR generator - negative dimension" -body { + ::math::quasirandom::qrpoints create simple -1 +} -returnCodes {error} -result {The dimension argument should be a positive integer value or one of circle, disk, sphere or ball} + +test "Quasirandom-1.2" "Simple QR generator - set start" -body { + ::math::quasirandom::qrpoints create simple 2 + ::math::quasirandom::qrpoints create simple2 2 -start 2 + + simple next + set coords [simple next] + + set coords2 [simple2 next] ;# Should be equal to the second point for the [simple] generator + + equalCoords $coords $coords2 +} -result 1 -cleanup {simple destroy; simple2 destroy} + +# +# Test simple methods +# +test "Quasirandom-2.1" "set-step sets and returns the value" -match equal -body { + ::math::quasirandom::qrpoints create simple 2 + + simple set-step 100 +} -result 100 -cleanup {simple destroy} + +test "Quasirandom-2.2" "set-evaluations sets and returns the value" -match equal -body { + ::math::quasirandom::qrpoints create simple 2 + + simple set-evaluations 100 +} -result 100 -cleanup {simple destroy} + +test "Quasirandom-2.3" "set-step returns the value" -match equal -body { + ::math::quasirandom::qrpoints create simple 2 + + simple set-step 100 + simple set-step +} -result 100 -cleanup {simple destroy} + +test "Quasirandom-2.4" "set-evaluations returns the value" -match equal -body { + ::math::quasirandom::qrpoints create simple 2 + + simple set-evaluations 100 + simple set-evaluations +} -result 100 -cleanup {simple destroy} + +# +# Test of bounds on points +# +test "Quasirandom-3.1" "Points should fall within block" -body { + ::math::quasirandom::qrpoints create simple 10 + + set correct_bound 1 + + for {set i 0} {$i < 100} {incr i} { + set coords [simple next] + + foreach c $coords { + if { $c < 0.0 || $c > 1.0 } { + set correct_bound 0 + break + } + } + } + + return $correct_bound +} -result 1 -cleanup {simple destroy} + +test "Quasirandom-3.2" "Points should fall on a circle" -match tolerant -body { + ::math::quasirandom::qrpoints create simple circle + + set correct_bound 1 + set radii {} + + for {set i 0} {$i < 100} {incr i} { + set coords [simple next] + + lassign $coords x y + lappend radii [expr {hypot($x,$y)}] + } + + return $radii +} -result [lrepeat 100 1.0] -cleanup {simple destroy} + +test "Quasirandom-3.3" "Points should fall within a disk" -match equal -body { + ::math::quasirandom::qrpoints create simple disk + + set correct_bounds {} + for {set i 0} {$i < 100} {incr i} { + set coords [simple next] + + lassign $coords x y + lappend correct_bounds [expr {hypot($x,$y) <= 1.0}] + } + + return $correct_bounds +} -result [lrepeat 100 1] -cleanup {simple destroy} + +test "Quasirandom-3.4" "Points should fall on a sphere" -match tolerant -body { + ::math::quasirandom::qrpoints create simple sphere + + set correct_bound 1 + set radii {} + + for {set i 0} {$i < 100} {incr i} { + set coords [simple next] + + lassign $coords x y z + lappend radii [expr {sqrt($x**2 + $y**2 + $z**2)}] + } + + return $radii +} -result [lrepeat 100 1.0] -cleanup {simple destroy} + +test "Quasirandom-3.5" "Points should fall within a ball" -match equal -body { + ::math::quasirandom::qrpoints create simple ball + + set correct_bounds {} + for {set i 0} {$i < 100} {incr i} { + set coords [simple next] + + lassign $coords x y + lappend correct_bounds [expr {sqrt($x**2 + $y**2 + $z**2) <= 1.0}] + } + + return $correct_bounds +} -result [lrepeat 100 1] -cleanup {simple destroy} + + + + +# +# Test of integral methods +# +# Integrating a constant function means the result is the volume +# +test "Quasirandom-4.1" "Integrate constant function - volume = 1" -match tolerant -body { + ::math::quasirandom::qrpoints create simple 3 + + set result [simple integral const {{0.0 1.0} {0.0 1.0} {0.0 1.0}}] + +} -result 1.0 -cleanup {simple destroy} + +test "Quasirandom-4.2" "Integrate constant function - volume = 8" -match tolerant -body { + ::math::quasirandom::qrpoints create simple 3 + + set result [simple integral const {{0.0 2.0} {0.0 2.0} {0.0 2.0}}] + +} -result 8.0 -cleanup {simple destroy} + +test "Quasirandom-4.3" "Integrate constant function - circle" -match tolerant -body { + ::math::quasirandom::qrpoints create simple circle + + set result [simple integral const 2.0] + +} -result [expr {2.0 * 2.0 * cos(-1.0)}] -cleanup {simple destroy} + +test "Quasirandom-4.3" "Integrate constant function - disk" -match tolerant -body { + ::math::quasirandom::qrpoints create simple disk + + set result [simple integral const 2.0] + +} -result [expr {2.0**2 * cos(-1.0)}] -cleanup {simple destroy} + +test "Quasirandom-4.4" "Integrate constant function - sphere" -match tolerant -body { + ::math::quasirandom::qrpoints create simple sphere + + set result [simple integral const 2.0] + +} -result [expr {4.0 * 2.0**2 * cos(-1.0)}] -cleanup {simple destroy} + +test "Quasirandom-4.5" "Integrate constant function - ball" -match tolerant -body { + ::math::quasirandom::qrpoints create simple ball + + set result [simple integral const 2.0] + +} -result [expr {4.0/3.0 * 2.0**3 * cos(-1.0)}] -cleanup {simple destroy} + +# We do not use too many evaluations ... error less than 1% +test "Quasirandom-4.6" "Integrate linear function (x, y, z)" -match error1percent -body { + ::math::quasirandom::qrpoints create simple 3 + + set result [list [simple integral fx {{0.0 1.0} {0.0 1.0} {0.0 1.0}}] \ + [simple integral fy {{0.0 1.0} {0.0 1.0} {0.0 1.0}}] \ + [simple integral fz {{0.0 1.0} {0.0 1.0} {0.0 1.0}}] ] + +} -result {0.5 0.5 0.5} -cleanup {simple destroy} + +# +# The function varies "sharply", so we need more evaluations +# +test "Quasirandom-4.7" "Integrate (xyz)**4" -match error1percent -body { + ::math::quasirandom::qrpoints create simple 3 + + # Exact answer is 1/125 + set result [simple integral fxyz4 {{0.0 1.0} {0.0 1.0} {0.0 1.0}} -evaluations 1000] + +} -result 0.0080 -cleanup {simple destroy} + + +# +# Detailed integration: provides error estimates but also an indication that +# the values can differ quite a bit +# +test "Quasirandom-5.1" "Integrate constant function with details - volume = 1" -match tolerant -body { + ::math::quasirandom::qrpoints create simple 3 + + set result [simple integral-detailed const {{0.0 1.0} {0.0 1.0} {0.0 1.0}}] + + set rawvalues [dict get $result -rawvalues] + +} -result {1.0 1.0 1.0 1.0} -cleanup {simple destroy} + + +test "Quasirandom-5.2" "Integrate linear function with details - volume = 1" -match tolerant -body { + ::math::quasirandom::qrpoints create simple 3 + + set result [simple integral-detailed fx {{0.0 1.0} {0.0 1.0} {0.0 1.0}}] + + set rawvalues [dict get $result -rawvalues] + +} -result {0.48924267415013695 0.48855550905424594 0.5278683439583554 0.48718117886246404} -cleanup {simple destroy} + + +test "Quasirandom-5.3" "Integrate (xyz)**4 with details - volume = 1" -match tolerant -body { + ::math::quasirandom::qrpoints create simple 3 + + set result [simple integral-detailed fxyz4 {{0.0 1.0} {0.0 1.0} {0.0 1.0}}] + + set rawvalues [dict get $result -rawvalues] + +} -result {0.0022115062627913935 0.009840104253511376 0.014937934937801888 0.007838969739655276} -cleanup {simple destroy} + + +# +# Test integration procedures in a different namespace +# +test "Quasirandom-6.1" "Integrate ::func::func" -match tolerant -body { + namespace eval ::func { + + proc func {xy} { + lassign $xy x y + expr {$x**2+$y**2} + } + + ::math::quasirandom::qrpoints create simple 2 + + set ::result [simple integral func {{0.0 1.0} {0.0 1.0}}] + } + + return $result + +} -result {0.67353777} -cleanup {::func::simple destroy} + + +test "Quasirandom-6.2" "Integrate (details) ::func::func" -match tolerant -body { + namespace eval ::func { + + proc func {xy} { + lassign $xy x y + expr {$x**2+$y**2} + } + + ::math::quasirandom::qrpoints create simple 2 + + set ::result [simple integral-detailed func {{0.0 1.0} {0.0 1.0}}] + } + + return [dict get $result -estimate] + +} -result {0.67353777} -cleanup {::func::simple destroy} + + +# TODO: +# - func in different namespace +# - implement detailed integration and test the details +# - implement minimization + +# +# Hm, the less than 1% error in the above test is a coincidence. The error is more +# likely to be 10%. +# +if {0} { + ::math::quasirandom::qrpoints create simple 3 + # Exact answer is 1/125 + set result [simple integral fxyz4 {{0.0 1.0} {0.0 1.0} {0.0 1.0}} -evaluations 100] + puts "fxyz4: $result" + simple set-step 0 + set result [simple integral fxyz4 {{0.0 1.0} {0.0 1.0} {0.0 1.0}} -evaluations 1000] + puts "fxyz4: $result" + set result [simple integral fxyz4 {{0.0 1.0} {0.0 1.0} {0.0 1.0}} -evaluations 1000] + puts "fxyz4: $result" + set result [simple integral fxyz4 {{0.0 1.0} {0.0 1.0} {0.0 1.0}} -evaluations 1000] + puts "fxyz4: $result" + + package require math::statistics + set samples {} + for {set trial 0} {$trial < 10} {incr trial} { + set sum 0.0 + + for {set p 0} {$p < 100} {incr p} { + set x [expr {rand()}] + set y [expr {rand()}] + set z [expr {rand()}] + set sum [expr {$sum + [fxyz4 [list $x $y $z]]}] + } + + puts "Trial $trial: [expr {$sum/100.0}]" + + lappend samples [expr {$sum/100.0}] + } + + puts "MonteCarlo (100):" + puts [::math::statistics::mean $samples] + puts [::math::statistics::stdev $samples] + + set samples {} + for {set trial 0} {$trial < 10} {incr trial} { + set sum 0.0 + + for {set p 0} {$p < 1000} {incr p} { + set x [expr {rand()}] + set y [expr {rand()}] + set z [expr {rand()}] + set sum [expr {$sum + [fxyz4 [list $x $y $z]]}] + } + + puts "Trial $trial: [expr {$sum/1000.0}]" + + lappend samples [expr {$sum/1000.0}] + } + + puts "MonteCarlo (1000):" + puts [::math::statistics::mean $samples] + puts [::math::statistics::stdev $samples] + + set samples {} + for {set trial 0} {$trial < 10} {incr trial} { + set result [simple integral fxyz4 {{0.0 1.0} {0.0 1.0} {0.0 1.0}} -evaluations 100] + + lappend samples $result + } + + puts "Quasi-random (100):" + puts [::math::statistics::mean $samples] + puts [::math::statistics::stdev $samples] + + set samples {} + for {set trial 0} {$trial < 10} {incr trial} { + set result [simple integral fxyz4 {{0.0 1.0} {0.0 1.0} {0.0 1.0}} -evaluations 1000] + + lappend samples $result + } + + puts "Quasi-random (1000):" + puts [::math::statistics::mean $samples] + puts [::math::statistics::stdev $samples] + + + puts [simple integral-detailed fx {{0.0 1.0} {0.0 1.0} {0.0 1.0}}] +} + + +# ------------------------------------------------------------------------- + +# End of test cases +testsuiteCleanup Index: modules/math/rational_funcs.man ================================================================== --- modules/math/rational_funcs.man +++ modules/math/rational_funcs.man @@ -180,7 +180,7 @@ The implementation of the rational functions relies on the math::polynomials package. For further remarks see the documentation on that package. [vset CATEGORY {math :: rationalfunctions}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/roman.man ================================================================== --- modules/math/roman.man +++ modules/math/roman.man @@ -45,7 +45,7 @@ Of these commands both [emph toroman] and [emph tointeger] are exported for easier use. The other two are not, as they could interfer or be confused with existing Tcl commands. [vset CATEGORY {math :: roman}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/romberg.man ================================================================== --- modules/math/romberg.man +++ modules/math/romberg.man @@ -334,7 +334,7 @@ integral is 3.97746 +/- 2.3557e-010 }] [vset CATEGORY {math :: calculus}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/special.man ================================================================== --- modules/math/special.man +++ modules/math/special.man @@ -466,7 +466,7 @@ [para] Abramowitz and Stegun: [emph "Handbook of Mathematical Functions"] (Dover, ISBN 486-61272-4) [vset CATEGORY {math :: special}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/statistics.man ================================================================== --- modules/math/statistics.man +++ modules/math/statistics.man @@ -1633,7 +1633,7 @@ The histograms are not very useful in identifying the nature of the time series - they do not show the periodic nature. [list_end] [vset CATEGORY {math :: statistics}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/symdiff.man ================================================================== --- modules/math/symdiff.man +++ modules/math/symdiff.man @@ -66,7 +66,7 @@ y {$c * $x + $d * $y}} ==> {{$a} {$b}} {{$c} {$d}} }] [vset CATEGORY {math :: calculus}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/math/trig.man ================================================================== --- modules/math/trig.man +++ modules/math/trig.man @@ -189,7 +189,7 @@ [list_end] [list_end] [vset CATEGORY {math :: trig}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/md4/md4.man ================================================================== --- modules/md4/md4.man +++ modules/md4/md4.man @@ -162,7 +162,7 @@ ([uri http://www.rfc-editor.org/rfc/rfc2104.txt]) [list_end] [vset CATEGORY md4] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/md5/md5.man ================================================================== --- modules/md5/md5.man +++ modules/md5/md5.man @@ -168,7 +168,7 @@ ([uri http://www.rfc-editor.org/rfc/rfc2104.txt]) [list_end] [vset CATEGORY md5] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/md5crypt/md5crypt.man ================================================================== --- modules/md5crypt/md5crypt.man +++ modules/md5crypt/md5crypt.man @@ -79,7 +79,7 @@ % md5crypt::md5crypt password [md5crypt::salt] $1$dFmvyRmO$T.V3OmzqeEf3hqJp2WFcb. }] [vset CATEGORY md5crypt] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] DELETED modules/mime/badmail1.txt Index: modules/mime/badmail1.txt ================================================================== --- modules/mime/badmail1.txt +++ /dev/null @@ -1,10 +0,0 @@ -Date: Tue, 10 Jun 2003 10:32:05 +0200 -Message-Id: <200306100832.h5A8W5S16670@hmif.hellmann.pol.pl> -From: Magnus Fisch -Subject: Meeting tomorrow -MIME-Version: 1.0 -Content-Type: multipart/mixed; boundary="----------CSFNU9QKPGZL79" -Bcc: - -------------CSFNU9QKPGZL79-- - DELETED modules/mime/badmail2.txt Index: modules/mime/badmail2.txt ================================================================== --- modules/mime/badmail2.txt +++ /dev/null @@ -1,31 +0,0 @@ -From: "Kelsey " -To: "gdylgzCsurvd1lw" -Date: Fri, 28 Feb 2003 03:12:35 -0500 -Subject: no subject gdylgzCsurvd1lw -MIME-Version: 1.0 -Content-Type: multipart/related; - boundary="----=_NextPart_000_0000_2CBA2CBA.150C56D2" -X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N -X-Spam-Rating: icarus.apache.org 1.6.2 0/1000/N -Lines: 19 -Xref: localhost private-mail:14167 - -------=_NextPart_000_0000_2CBA2CBA.150C56D2 -Content-Type: text/html; -Content-Transfer-Encoding: base64 - -PCEtLTE1MTQ3LS0+PGJvZHk+DQpJdCdzIG1lIEplPCEtLTI5MDY0LS0+bm5pZmVyLDxicj4g -SSBqdXN0IHdhbjwhLS0xOTE0OS0tPnRlZCB0byBzZW5kIHlvdSB0aGF0IHBpYyB5b3UgYXNr -ZTwhLS0xNTAxMC0tPmQgZm9yIHRoZSBvdDwhLS0yNjUxMi0tPmhlcg0KZGF5LiA8YnI+IDxh -IGhyZWY9Imh0dHA6Ly93d3cuaG90aG9zdC5iei9hYmMvamVubmlmZXIvP1JJRD1jaW5nd2Yi -PkNsaTwhLS0yNzE1My0tPmNrDQpIPCEtLTI2NjcwLS0+ZXJlIHRvIGNhdDwhLS03NDg5LS0+ -Y2ggbWUgb24gbXkgd2ViPCEtLTI0ODExLS0+Y2FtICYgc2VlIG1vcmUgcGljcyBvZiBtZS48 -L2E+IDxicj48YnI+DQo8YSBocmVmPSJodHRwOi8vd3d3LmhvdGhvc3QuYnovYWJjL2plbm5p -ZmVyLz9SSUQ9Y2luZ3dmIj48aW1nIHNyYz0iaHR0cDovLzIwNy40NC4xODMuMjU0L2FiYy9q -ZW5uaWZlci93b29ob28uanBnIiBib3JkZXI9IjAiPjwvYT4NCjxicj48YnI+PGk+LSB4bzwh -LS0yMzQwMi0tPnhvIEplbm5pZmVyPC9pPjwvcD48YnI+PGJyPjxicj48YnI+PGJyPjxicj48 -YnI+PGJyPjxicj48YnI+PGJyPjxicj48YnI+PGJyPjxicj48YnI+PGJyPjxicj48YnI+PGJy -Pjxicj48YnI+PGJyPjxicj48YnI+PGJyPjxicj48YnI+PGJyPjxicj48YnI+DQo8L2JvZHk+ - - - Index: modules/mime/mime.man ================================================================== --- modules/mime/mime.man +++ modules/mime/mime.man @@ -1,7 +1,8 @@ +[vset VERSION 1.6.1] [comment {-*- tcl -*- doctools manpage}] -[manpage_begin mime n 1.6] +[manpage_begin mime n [vset VERSION]] [see_also ftp] [see_also http] [see_also pop3] [see_also smtp] [keywords email] @@ -18,11 +19,11 @@ [copyright {1999-2000 Marshall T. Rose}] [moddesc {Mime}] [titledesc {Manipulation of MIME body parts}] [category {Text processing}] [require Tcl 8.5] -[require mime [opt 1.6]] +[require mime [opt [vset VERSION]]] [description] [para] The [package mime] library package provides the commands to create and manipulate MIME body parts. @@ -399,7 +400,7 @@ See [uri {/tktview?name=447037} {Ticket 447037}] for additional information. [list_end] [vset CATEGORY mime] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/mime/mime.tcl ================================================================== --- modules/mime/mime.tcl +++ modules/mime/mime.tcl @@ -21,11 +21,11 @@ # # new string features and inline scan are used, requiring 8.3. package require Tcl 8.5 -package provide mime 1.6 +package provide mime 1.6.1 if {[catch {package require Trf 2.0}]} { # Fall-back to tcl-based procedures of base64 and quoted-printable encoders # Warning! @@ -377,11 +377,13 @@ set token [namespace current]::[incr mime(uid)] # FRINK: nocheck variable $token upvar 0 $token state - if {[catch {{*}[list mime::initializeaux $token {*}$args]} result eopts]} { + if {[catch { + mime::initializeaux $token {*}$args + } result eopts]} { catch {mime::finalize $token -subordinates dynamic} return -options $eopts $result } return $token } @@ -656,29 +658,27 @@ set blankP 1 } else { incr pos [expr {$x + 1}] } } else { - - if {$state(lines.current) >= $state(lines.count)} { - set blankP 1 - set line {} - } else { - set line [lindex $state(lines) $state(lines.current)] - incr state(lines.current) - set x [string length $line] - if {$x == 0} {set blankP 1} - } - - } - - if {(!$blankP) && ([string last \r $line] == {$x - 1})} { - set line [string range $line 0 [expr {$x - 2}]] - if {$x == 1} { - set blankP 1 - } - } + if {$state(lines.current) >= $state(lines.count)} { + set blankP 1 + set line {} + } else { + set line [lindex $state(lines) $state(lines.current)] + incr state(lines.current) + set x [string length $line] + if {$x == 0} {set blankP 1} + } + } + + if {(!$blankP) && ([string last \r $line] == ($x - 1))} { + set line [string range $line 0 [expr {$x - 2}]] + if {$x == 1} { + set blankP 1 + } + } if {(!$blankP) && (([ string first { } $line] == 0) || ([ string first \t $line] == 0))} { append vline \n $line Index: modules/mime/mime.test ================================================================== --- modules/mime/mime.test +++ modules/mime/mime.test @@ -24,10 +24,15 @@ use md5/md5x.tcl md5 } testing { useLocal mime.tcl mime } + +# Shorthand for access to assets. +proc A {path} { + file join $::tcltest::testsDirectory test-assets $path +} # ------------------------------------------------------------------------- namespace import mime::* @@ -167,24 +172,21 @@ Content-Type: text/plain\r \r foo}" test mime-3.7 {Test mime with a bad email [SF Bug 631314 ]} { - set tok [mime::initialize -file \ - [file join $tcltest::testsDirectory badmail1.txt]] - + set tok [mime::initialize -file [A badmail1.txt]] set res {} set ctok [lindex [mime::getproperty $tok parts] 0] lappend res [dictsort [mime::getproperty $tok]] lappend res [dictsort [mime::getproperty $ctok]] mime::finalize $tok string map [list $ctok CHILD] $res } {{content multipart/mixed encoding {} params {boundary ----------CSFNU9QKPGZL79} parts CHILD size 0} {content application/octet-stream encoding {} params {charset us-ascii} size 0}} test mime-3.8 {Test mime with another bad email [SF Bug 631314 ]} { - set tok [mime::initialize -file \ - [file join $tcltest::testsDirectory badmail2.txt]] + set tok [mime::initialize -file [A badmail2.txt]] set res {} set ctok [lindex [mime::getproperty $tok parts] 0] lappend res [dictsort [mime::getproperty $tok]] lappend res [dictsort [mime::getproperty $ctok]] mime::finalize $tok @@ -600,10 +602,19 @@ b3RlLU1UQTogNTMuMjQuMjgyLjE1MA== }] set parts [mime::getproperty $token parts] mime::getheader [lindex $parts end] Remote-MTA } 53.24.282.150 + +# ------------------------------------------------------------------------- + +test mime-12.1 {Fossil ticket 57909d2e1c} -cleanup { + mime::finalize $token + unset -nocomplain token +} -body { + set token [::mime::initialize -file [A mail-57909d2e1c.txt]] +} -result {::mime::*} -match glob # ------------------------------------------------------------------------- testsuiteCleanup return Index: modules/mime/pkgIndex.tcl ================================================================== --- modules/mime/pkgIndex.tcl +++ modules/mime/pkgIndex.tcl @@ -1,4 +1,4 @@ if {![package vsatisfies [package provide Tcl] 8.3]} {return} package ifneeded smtp 1.5 [list source [file join $dir smtp.tcl]] if {![package vsatisfies [package provide Tcl] 8.5]} {return} -package ifneeded mime 1.6 [list source [file join $dir mime.tcl]] +package ifneeded mime 1.6.1 [list source [file join $dir mime.tcl]] Index: modules/mime/smtp.man ================================================================== --- modules/mime/smtp.man +++ modules/mime/smtp.man @@ -201,10 +201,10 @@ ([uri http://www.rfc-editor.org/rfc/rfc2554.txt]) [list_end] [vset CATEGORY smtp] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [keywords mail mail email smtp mime tls \ {rfc 821} {rfc 822} {rfc 2821} {rfc 3207} {rfc 2554} internet net] [manpage_end] ADDED modules/mime/test-assets/badmail1.txt Index: modules/mime/test-assets/badmail1.txt ================================================================== --- /dev/null +++ modules/mime/test-assets/badmail1.txt @@ -0,0 +1,10 @@ +Date: Tue, 10 Jun 2003 10:32:05 +0200 +Message-Id: <200306100832.h5A8W5S16670@hmif.hellmann.pol.pl> +From: Magnus Fisch +Subject: Meeting tomorrow +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="----------CSFNU9QKPGZL79" +Bcc: + +------------CSFNU9QKPGZL79-- + ADDED modules/mime/test-assets/badmail2.txt Index: modules/mime/test-assets/badmail2.txt ================================================================== --- /dev/null +++ modules/mime/test-assets/badmail2.txt @@ -0,0 +1,31 @@ +From: "Kelsey " +To: "gdylgzCsurvd1lw" +Date: Fri, 28 Feb 2003 03:12:35 -0500 +Subject: no subject gdylgzCsurvd1lw +MIME-Version: 1.0 +Content-Type: multipart/related; + boundary="----=_NextPart_000_0000_2CBA2CBA.150C56D2" +X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N +X-Spam-Rating: icarus.apache.org 1.6.2 0/1000/N +Lines: 19 +Xref: localhost private-mail:14167 + +------=_NextPart_000_0000_2CBA2CBA.150C56D2 +Content-Type: text/html; +Content-Transfer-Encoding: base64 + +PCEtLTE1MTQ3LS0+PGJvZHk+DQpJdCdzIG1lIEplPCEtLTI5MDY0LS0+bm5pZmVyLDxicj4g +SSBqdXN0IHdhbjwhLS0xOTE0OS0tPnRlZCB0byBzZW5kIHlvdSB0aGF0IHBpYyB5b3UgYXNr +ZTwhLS0xNTAxMC0tPmQgZm9yIHRoZSBvdDwhLS0yNjUxMi0tPmhlcg0KZGF5LiA8YnI+IDxh +IGhyZWY9Imh0dHA6Ly93d3cuaG90aG9zdC5iei9hYmMvamVubmlmZXIvP1JJRD1jaW5nd2Yi +PkNsaTwhLS0yNzE1My0tPmNrDQpIPCEtLTI2NjcwLS0+ZXJlIHRvIGNhdDwhLS03NDg5LS0+ +Y2ggbWUgb24gbXkgd2ViPCEtLTI0ODExLS0+Y2FtICYgc2VlIG1vcmUgcGljcyBvZiBtZS48 +L2E+IDxicj48YnI+DQo8YSBocmVmPSJodHRwOi8vd3d3LmhvdGhvc3QuYnovYWJjL2plbm5p +ZmVyLz9SSUQ9Y2luZ3dmIj48aW1nIHNyYz0iaHR0cDovLzIwNy40NC4xODMuMjU0L2FiYy9q +ZW5uaWZlci93b29ob28uanBnIiBib3JkZXI9IjAiPjwvYT4NCjxicj48YnI+PGk+LSB4bzwh +LS0yMzQwMi0tPnhvIEplbm5pZmVyPC9pPjwvcD48YnI+PGJyPjxicj48YnI+PGJyPjxicj48 +YnI+PGJyPjxicj48YnI+PGJyPjxicj48YnI+PGJyPjxicj48YnI+PGJyPjxicj48YnI+PGJy +Pjxicj48YnI+PGJyPjxicj48YnI+PGJyPjxicj48YnI+PGJyPjxicj48YnI+DQo8L2JvZHk+ + + + ADDED modules/mime/test-assets/mail-57909d2e1c.txt Index: modules/mime/test-assets/mail-57909d2e1c.txt ================================================================== --- /dev/null +++ modules/mime/test-assets/mail-57909d2e1c.txt @@ -0,0 +1,53 @@ +MIME-Version: 1.0 +Content-ID: <10177.1554980513.8@mousetrap.lan> +Content-Type: multipart/mixed; + boundary="----- =_U9Pw/kikzJT5t8pT5pl5Pw==" + +------- =_U9Pw/kikzJT5t8pT5pl5Pw== +MIME-Version: 1.0 +Content-ID: <10177.1554980513.4@mousetrap.lan> +Content-Disposition: inline; filename="/model.pl" +Content-Description: Simile model +Date-Modified: 2019-04-11 11:01:36 GMT +Authentication-Code: c0c651af192d709b2757cb9ef0d8c19d +Content-Type: application/x-simile +Content-Transfer-Encoding: base64 + +c291cmNlKHByb2dyYW09J0FNRScsdmVyc2lvbj0gMTAuOSxlZGl0aW9uPWVudGVycHJpc2UsZGF0 +KG5vbmUsaW5faGllcmFyY2h5LGRlc3QsMSldXSxbY3VydmU9Wy05LDFdXSkuCg== + +------- =_U9Pw/kikzJT5t8pT5pl5Pw== +MIME-Version: 1.0 +Content-ID: <10177.1554980513.5@mousetrap.lan> +Content-Disposition: attachment; filename="/model.cnv" +Content-Description: Simile canvas description +Date-Modified: 2019-04-11 11:01:36 GMT +Content-Type: application/x-simile +Content-Transfer-Encoding: base64 + +IyB3cml0dGVuIG9uIFRodSBBcHIgMTEgMTE6MDE6MzYgR01UIDIwMTkKTG9hZE1vZGVsTG9va3Mg +bl90aGlzIHJlYWx3aWR0aCgxMDguMCkgY3VycmVudGx5X2VkaXRhYmxlfSAtdGV4dCBmbG93MwoK + + +------- =_U9Pw/kikzJT5t8pT5pl5Pw== +MIME-Version: 1.0 +Content-ID: <10177.1554980513.6@mousetrap.lan> +Content-Disposition: attachment; filename="/model.spj" +Content-Description: Simile package description +Date-Modified: 2019-04-11 11:01:53 GMT +Content-Type: application/x-simile +Content-Transfer-Encoding: base64 + +Cg== + +------- =_U9Pw/kikzJT5t8pT5pl5Pw== +MIME-Version: 1.0 +Content-Description: Run Status +Content-ID: <10177.1554980513.7@mousetrap.lan> +Content-Type: application/x-simile +Content-Transfer-Encoding: base64 + +ZXhlY1RpbWUgMTAwLjAgdGltZVVuaXQgdW5pdCBkaXNwbGF5SW50IDEgaW50TWV0aG9kIEV1bGVy +IHBoYXNlTGlzdCAwLjE= + +------- =_U9Pw/kikzJT5t8pT5pl5Pw==-- Index: modules/multiplexer/multiplexer.man ================================================================== --- modules/multiplexer/multiplexer.man +++ modules/multiplexer/multiplexer.man @@ -124,7 +124,7 @@ [list_end] [list_end] [vset CATEGORY multiplexer] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/namespacex/namespacex.man ================================================================== --- modules/namespacex/namespacex.man +++ modules/namespacex/namespacex.man @@ -168,7 +168,7 @@ Returns the corresponding list of relative names of child namespaces. [list_end] [vset CATEGORY namespacex] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/ncgi/ncgi.man ================================================================== --- modules/ncgi/ncgi.man +++ modules/ncgi/ncgi.man @@ -307,7 +307,7 @@ }] [para] [vset CATEGORY ncgi] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/nettool/nettool.man ================================================================== --- modules/nettool/nettool.man +++ modules/nettool/nettool.man @@ -137,7 +137,7 @@ The path is not created, only computed, by this command. [list_end] [para] [vset CATEGORY odie] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/nmea/nmea.man ================================================================== --- modules/nmea/nmea.man +++ modules/nmea/nmea.man @@ -96,7 +96,7 @@ }] [list_end] [vset CATEGORY nmea] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/nns/nns_auto.man ================================================================== --- modules/nns/nns_auto.man +++ modules/nns/nns_auto.man @@ -113,7 +113,7 @@ Another loss of the connection, be it during or after re-entering the remembered information simply restarts the timer and subsequent reconnection attempts. [vset CATEGORY nameserv] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/nns/nns_client.man ================================================================== --- modules/nns/nns_client.man +++ modules/nns/nns_client.man @@ -332,7 +332,7 @@ [def 0.1] Initial implementation of the client. [list_end] [vset CATEGORY nameserv] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/nns/nns_common.man ================================================================== --- modules/nns/nns_common.man +++ modules/nns/nns_common.man @@ -41,7 +41,7 @@ will try to connect to. [list_end] [vset CATEGORY nameserv] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/nns/nns_intro.man ================================================================== --- modules/nns/nns_intro.man +++ modules/nns/nns_intro.man @@ -122,7 +122,7 @@ Developers wishing to modify and/or extend or to just understand the internals of the nameservice facility however are strongly advised to read it. [vset CATEGORY nameserv] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/nns/nns_protocol.man ================================================================== --- modules/nns/nns_protocol.man +++ modules/nns/nns_protocol.man @@ -176,7 +176,7 @@ names in the response were added or removed from the service. [list_end] [vset CATEGORY nameserv] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/nns/nns_server.man ================================================================== --- modules/nns/nns_server.man +++ modules/nns/nns_server.man @@ -139,7 +139,7 @@ [def 0.1] Initial implementation of the server. [list_end] [vset CATEGORY nameserv] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/nntp/nntp.man ================================================================== --- modules/nntp/nntp.man +++ modules/nntp/nntp.man @@ -332,7 +332,7 @@ Test message body" }] [vset CATEGORY nntp] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/ntp/ntp_time.man ================================================================== --- modules/ntp/ntp_time.man +++ modules/ntp/ntp_time.man @@ -125,7 +125,7 @@ [section AUTHORS] Pat Thoyts [vset CATEGORY ntp] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/oauth/oauth.man ================================================================== --- modules/oauth/oauth.man +++ modules/oauth/oauth.man @@ -1,7 +1,7 @@ [comment {-*- tcl -*- doctools manpage}] -[vset PACKAGE_VERSION 1.0.2] +[vset PACKAGE_VERSION 1.0.3] [manpage_begin oauth n [vset PACKAGE_VERSION]] [keywords {oauth}] [keywords {RFC 5849}] [keywords {RFC 2718}] [keywords twitter] @@ -185,7 +185,7 @@ [list_end] [para] [vset CATEGORY oauth] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/oauth/oauth.tcl ================================================================== --- modules/oauth/oauth.tcl +++ modules/oauth/oauth.tcl @@ -23,11 +23,11 @@ # 1.7 Version (oauth_version) the OAuth version, actually 1.0 # TODO: create online documentation package require Tcl 8.5 -package provide oauth 1.0.2 +package provide oauth 1.0.3 package require http package require tls package require base64 package require sha1 @@ -281,11 +281,11 @@ # Split - # Split the string on the first separator # and return both parts as a list. proc ::oauth::Split {string sep} { - regexp "\{^(\[^${sep}\]+)${sep}(.*)\$" $string -> key value + regexp "^(\[^${sep}\]+)${sep}(.*)\$" $string -> key value list $key $value } # PercentEncode -- # Encoding process in http://tools.ietf.org/html/rfc3986#section-2.1 Index: modules/oauth/pkgIndex.tcl ================================================================== --- modules/oauth/pkgIndex.tcl +++ modules/oauth/pkgIndex.tcl @@ -1,2 +1,2 @@ if {![package vsatisfies [package provide Tcl] 8.5]} {return} -package ifneeded oauth 1.0.2 [list source [file join $dir oauth.tcl]] +package ifneeded oauth 1.0.3 [list source [file join $dir oauth.tcl]] Index: modules/oometa/oometa.man ================================================================== --- modules/oometa/oometa.man +++ modules/oometa/oometa.man @@ -145,8 +145,8 @@ between the class metadata, the local [emph meta] variable, and THEN performing the search. [list_end] [vset CATEGORY tcloo] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/ooutil/ooutil.man ================================================================== --- modules/ooutil/ooutil.man +++ modules/ooutil/ooutil.man @@ -159,7 +159,7 @@ [section AUTHORS] Donal Fellows, Andreas Kupries [vset CATEGORY oo::util] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/otp/otp.man ================================================================== --- modules/otp/otp.man +++ modules/otp/otp.man @@ -89,7 +89,7 @@ ([uri http://www.itl.nist.gov/fipspubs/fip180-1.htm]) [list_end] [vset CATEGORY otp] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/page/page_intro.man ================================================================== --- modules/page/page_intro.man +++ modules/page/page_intro.man @@ -29,7 +29,7 @@ packages, as they cannot be loaded into a general interpreter, like tclsh, without extensive preparation of the interpreter. Preparation which is done for them by the plugin manager. [vset CATEGORY page] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/page/page_pluginmgr.man ================================================================== --- modules/page/page_pluginmgr.man +++ modules/page/page_pluginmgr.man @@ -794,7 +794,7 @@ The plugin manager currently checks the plugins for only one feature, [const timeable]. A plugin supporting this feature is assumed to be able to collect timing statistics on request. [vset CATEGORY page] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/page/page_util_flow.man ================================================================== --- modules/page/page_util_flow.man +++ modules/page/page_util_flow.man @@ -90,7 +90,7 @@ above. [list_end] [vset CATEGORY page] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/page/page_util_norm_lemon.man ================================================================== --- modules/page/page_util_norm_lemon.man +++ modules/page/page_util_norm_lemon.man @@ -45,7 +45,7 @@ The exact operations performed are left undocumented for the moment. [list_end] [vset CATEGORY page] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/page/page_util_norm_peg.man ================================================================== --- modules/page/page_util_norm_peg.man +++ modules/page/page_util_norm_peg.man @@ -99,7 +99,7 @@ [list_end] [list_end] [vset CATEGORY page] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/page/page_util_peg.man ================================================================== --- modules/page/page_util_peg.man +++ modules/page/page_util_peg.man @@ -102,7 +102,7 @@ [arg pe]. [list_end] [vset CATEGORY page] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/page/page_util_quote.man ================================================================== --- modules/page/page_util_quote.man +++ modules/page/page_util_quote.man @@ -56,7 +56,7 @@ this command. [list_end] [vset CATEGORY page] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/pki/pki.man ================================================================== --- modules/pki/pki.man +++ modules/pki/pki.man @@ -296,7 +296,7 @@ [section AUTHORS] Roy Keene [vset CATEGORY rsa] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/pluginmgr/pluginmgr.man ================================================================== --- modules/pluginmgr/pluginmgr.man +++ modules/pluginmgr/pluginmgr.man @@ -421,7 +421,7 @@ loaded. [list_end] [vset CATEGORY pluginmgr] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/png/png.man ================================================================== --- modules/png/png.man +++ modules/png/png.man @@ -149,7 +149,7 @@ to [arg file]. [list_end] [vset CATEGORY png] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/pop3/pop3.man ================================================================== --- modules/pop3/pop3.man +++ modules/pop3/pop3.man @@ -268,7 +268,7 @@ ... }] [vset CATEGORY pop3] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/pop3d/pop3d.man ================================================================== --- modules/pop3d/pop3d.man +++ modules/pop3d/pop3d.man @@ -267,7 +267,7 @@ [enum] [uri http://www.rfc-editor.org/rfc/rfc1939.txt {RFC 1939}] [enum] [uri http://www.rfc-editor.org/rfc/rfc2449.txt {RFC 2449}] [list_end] [vset CATEGORY pop3d] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/pop3d/pop3d_dbox.man ================================================================== --- modules/pop3d/pop3d_dbox.man +++ modules/pop3d/pop3d_dbox.man @@ -158,7 +158,7 @@ that there are zero messages in the mailbox. [list_end] [vset CATEGORY pop3d] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/pop3d/pop3d_udb.man ================================================================== --- modules/pop3d/pop3d_udb.man +++ modules/pop3d/pop3d_udb.man @@ -106,7 +106,7 @@ [arg dbName] [method save] without an argument. [list_end] [vset CATEGORY pop3d] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/practcl/build/footer.txt ================================================================== --- modules/practcl/build/footer.txt +++ modules/practcl/build/footer.txt @@ -1,2 +1,2 @@ [vset CATEGORY practcl] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] Index: modules/practcl/practcl.man ================================================================== --- modules/practcl/practcl.man +++ modules/practcl/practcl.man @@ -1841,9 +1841,9 @@ [list_end] [para] [vset CATEGORY practcl] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/practcl/practcl.tcl ================================================================== --- modules/practcl/practcl.tcl +++ modules/practcl/practcl.tcl @@ -8,50 +8,10 @@ namespace eval ::practcl {} ### # START: httpwget/wget.tcl ### -package provide http::wget 0.1 -package require http -::namespace eval ::http { -} -proc ::http::_followRedirects {url args} { - while 1 { - set token [geturl $url -validate 1] - set ncode [ncode $token] - if { $ncode eq "404" } { - error "URL Not found" - } - switch -glob $ncode { - 30[1237] {### redirect - see below ###} - default {cleanup $token ; return $url} - } - upvar #0 $token state - array set meta [set ${token}(meta)] - cleanup $token - if {![info exists meta(Location)]} { - return $url - } - set url $meta(Location) - unset meta - } - return $url -} -proc ::http::wget {url destfile {verbose 1}} { - set tmpchan [open $destfile w] - fconfigure $tmpchan -translation binary - if { $verbose } { - puts [list GETTING [file tail $destfile] from $url] - } - set real_url [_followRedirects $url] - set token [geturl $real_url -channel $tmpchan -binary yes] - if {[ncode $token] != "200"} { - error "DOWNLOAD FAILED" - } - cleanup $token - close $tmpchan -} ### # END: httpwget/wget.tcl ### ### @@ -1008,11 +968,10 @@ # Run the destructor once and only once set self [self] my variable DestroyEvent if {$DestroyEvent} return set DestroyEvent 1 -::clay::object_destroy $self } append body $rawbody ::oo::define [current_class] destructor $body } proc ::clay::define::Dict {name {values {}}} { @@ -1071,26 +1030,10 @@ proc ::clay::define::Variable {name {default {}}} { set class [current_class] set name [string trimright $name :/] $class clay set variable/ $name $default } -proc ::clay::object_create {objname {class {}}} { - #if {$::clay::trace>0} { - # puts [list $objname CREATE] - #} -} -proc ::clay::object_rename {object newname} { - if {$::clay::trace>0} { - puts [list $object RENAME -> $newname] - } -} -proc ::clay::object_destroy objname { - if {$::clay::trace>0} { - puts [list $objname DESTROY] - } - #::cron::object_destroy $objname -} ::namespace eval ::clay::define { } proc ::clay::ensemble_methodbody {ensemble einfo} { set default standard set preamble {} @@ -1731,10 +1674,28 @@ if {[$class clay exists {*}$args]} { return $class } } return {} + } + refcount { + my variable refcount + if {![info exists refcount]} { + return 0 + } + return $refcount + } + refcount_incr { + my variable refcount + incr refcount + } + refcount_decr { + my variable refcount + incr refcount -1 + if {$refcount <= 0} { + ::clay::object_destroy [self] + } } replace { set clay [lindex $args 0] } source { @@ -1860,29 +1821,48 @@ ::clay::object clay branch array ::clay::object clay branch mixin ::clay::object clay branch option ::clay::object clay branch dict clay ::clay::object clay set variable DestroyEvent 0 +if {[info commands ::cron::object_destroy] eq {}} { + # Provide a noop if we aren't running with the cron scheduler + namespace eval ::cron {} + proc ::cron::object_destroy args {} +} ::namespace eval ::clay::event { } -proc ::clay::destroy args { - if {![info exists ::clay::idle_destroy]} { - set ::clay::idle_destroy {} - } - foreach object $args { - if {$object in $::clay::idle_destroy} continue - lappend ::clay::idle_destroy $object - } -} proc ::clay::cleanup {} { if {![info exists ::clay::idle_destroy]} return foreach obj $::clay::idle_destroy { if {[info commands $obj] ne {}} { catch {$obj destroy} } } set ::clay::idle_destroy {} +} +proc ::clay::object_create {objname {class {}}} { + #if {$::clay::trace>0} { + # puts [list $objname CREATE] + #} +} +proc ::clay::object_rename {object newname} { + if {$::clay::trace>0} { + puts [list $object RENAME -> $newname] + } +} +proc ::clay::object_destroy args { + if {![info exists ::clay::idle_destroy]} { + set ::clay::idle_destroy {} + } + foreach objname $args { + if {$::clay::trace>0} { + puts [list $objname DESTROY] + } + ::cron::object_destroy $objname + if {$objname in $::clay::idle_destroy} continue + lappend ::clay::idle_destroy $objname + } } proc ::clay::event::cancel {self {task *}} { variable timer_event variable timer_script Index: modules/processman/processman.man ================================================================== --- modules/processman/processman.man +++ modules/processman/processman.man @@ -68,7 +68,7 @@ of the command to execute. [arg args] are arguments to pass to that command. [list_end] [para] [vset CATEGORY odie] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/profiler/profiler.man ================================================================== --- modules/profiler/profiler.man +++ modules/profiler/profiler.man @@ -115,7 +115,7 @@ that function. [list_end] [vset CATEGORY profiler] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] DELETED modules/pt/configuration.tcl Index: modules/pt/configuration.tcl ================================================================== --- modules/pt/configuration.tcl +++ /dev/null @@ -1,81 +0,0 @@ -# configuration.tcl -- -# -# Generic configuration management, for use by import and export -# managers. -# -# Copyright (c) 2009 Andreas Kupries -# -# See the file "license.terms" for information on usage and redistribution -# of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# RCS: @(#) $Id: configuration.tcl,v 1.1 2010/03/26 05:07:24 andreas_kupries Exp $ - -# Each object manages a set of configuration variables. - -# ### ### ### ######### ######### ######### -## Requisites - -package require Tcl 8.5 -package require snit - -# ### ### ### ######### ######### ######### -## API - -snit::type ::configuration { - - # ### ### ### ######### ######### ######### - ## Options :: None - - # ### ### ### ######### ######### ######### - ## Creating, destruction - - # Default constructor. - # Default destructor. - - # ### ### ### ######### ######### ######### - ## Public methods. Reading and writing the configuration. - - method names {} { - return [array names myconfiguration] - } - - method get {} { - return [array get myconfiguration] - } - - method set {name {value {}}} { - # 7 instead of 3 in the condition below, because of the 4 - # implicit arguments snit is providing to each method. - if {[llength [info level 0]] == 7} { - set myconfiguration($name) $value - } elseif {![info exists myconfiguration($name)]} { - return -code error "can't read \"$name\": no such variable" - } - return $myconfiguration($name) - } - - method unset {args} { - if {![llength $args]} { lappend args * } - foreach pattern $args { - array unset myconfiguration $pattern - } - return - } - - # ### ### ### ######### ######### ######### - ## Internal methods :: None. - - # ### ### ### ######### ######### ######### - ## State :: Configuration data, Tcl array - - variable myconfiguration -array {} - - ## - # ### ### ### ######### ######### ######### -} - -# ### ### ### ######### ######### ######### -## Ready - -package provide configuration 1 -return Index: modules/pt/include/feedback.inc ================================================================== --- modules/pt/include/feedback.inc +++ modules/pt/include/feedback.inc @@ -1,3 +1,3 @@ [comment {--- Standard trailer for all manpages in this module --}] [vset CATEGORY pt] -[include ../../doctools2base/include/feedback.inc] +[include ../../common-text/feedback.inc] DELETED modules/pt/paths.tcl Index: modules/pt/paths.tcl ================================================================== --- modules/pt/paths.tcl +++ /dev/null @@ -1,75 +0,0 @@ -# paths.tcl -- -# -# Generic path list management, for use by import management. -# -# Copyright (c) 2009 Andreas Kupries -# -# See the file "license.terms" for information on usage and redistribution -# of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# RCS: @(#) $Id: paths.tcl,v 1.1 2010/03/26 05:07:24 andreas_kupries Exp $ - -# Each object manages a list of paths. - -# ### ### ### ######### ######### ######### -## Requisites - -package require Tcl 8.5 -package require snit - -# ### ### ### ######### ######### ######### -## API - -snit::type ::paths { - - # ### ### ### ######### ######### ######### - ## Options :: None - - # ### ### ### ######### ######### ######### - ## Creation, destruction - - # Default constructor. - # Default destructor. - - # ### ### ### ######### ######### ######### - ## Methods :: Querying and manipulating the list of paths. - - method paths {} { - return $mypaths - } - - method add {path} { - if {$path in $mypaths} return - lappend mypaths $path - return - } - - method remove {path} { - set pos [lsearch $mypaths $path] - if {$pos < 0} return - set mypaths [lreplace $mypaths $pos $pos] - return - } - - method clear {} { - set mypaths {} - return - } - - # ### ### ### ######### ######### ######### - ## Internal methods :: None - - # ### ### ### ######### ######### ######### - ## State :: List of paths. - - variable mypaths {} - - ## - # ### ### ### ######### ######### ######### -} - -# ### ### ### ######### ######### ######### -## Ready - -package provide paths 1 -return Index: modules/pt/pkgIndex.tcl ================================================================== --- modules/pt/pkgIndex.tcl +++ modules/pt/pkgIndex.tcl @@ -1,11 +1,9 @@ if {![package vsatisfies [package provide Tcl] 8.5]} return # General utilities. package ifneeded char 1.0.1 [list source [file join $dir char.tcl]] -package ifneeded configuration 1 [list source [file join $dir configuration.tcl]] -package ifneeded paths 1 [list source [file join $dir paths.tcl]] package ifneeded text::write 1 [list source [file join $dir text_write.tcl]] # AST support package ifneeded pt::ast 1.1 [list source [file join $dir pt_astree.tcl]] @@ -24,12 +22,12 @@ package ifneeded pt::peg::op 1.1.0 [list source [file join $dir pt_peg_op.tcl]] package ifneeded pt::parse::peg 1.0.1 [list source [file join $dir pt_parse_peg.tcl]] # Export/import managers. Assumes an untrusted environment. -package ifneeded pt::peg::export 1 [list source [file join $dir pt_peg_export.tcl]] -package ifneeded pt::peg::import 1 [list source [file join $dir pt_peg_import.tcl]] +package ifneeded pt::peg::export 1.0.1 [list source [file join $dir pt_peg_export.tcl]] +package ifneeded pt::peg::import 1.0.1 [list source [file join $dir pt_peg_import.tcl]] # Export plugins, connecting manager to the core conversion packages. package ifneeded pt::peg::export::container 1 [list source [file join $dir pt_peg_export_container.tcl]] package ifneeded pt::peg::export::json 1 [list source [file join $dir pt_peg_export_json.tcl]] package ifneeded pt::peg::export::peg 1 [list source [file join $dir pt_peg_export_peg.tcl]] Index: modules/pt/pt_peg_export.man ================================================================== --- modules/pt/pt_peg_export.man +++ modules/pt/pt_peg_export.man @@ -1,14 +1,15 @@ [comment {-*- tcl -*- doctools manpage}] -[manpage_begin pt::peg::export n 1] +[vset VERSION 1.0.1] +[manpage_begin pt::peg::export n [vset VERSION]] [include include/module.inc] [titledesc {PEG Export}] [require snit] -[require configuration] +[require struct::map] [require pt::peg] [require pluginmgr] -[require pt::peg::export [opt 1]] +[require pt::peg::export [opt [vset VERSION]]] [description] [include include/ref_intro.inc] This package provides a manager for parsing expression grammars, with each instance handling a set of plugins for the export of them to Index: modules/pt/pt_peg_export.tcl ================================================================== --- modules/pt/pt_peg_export.tcl +++ modules/pt/pt_peg_export.tcl @@ -4,12 +4,10 @@ # # Copyright (c) 2009 Andreas Kupries # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# RCS: @(#) $Id: pt_peg_export.tcl,v 1.1 2010/03/26 05:07:24 andreas_kupries Exp $ # Each object manages a set of plugins for the conversion of parsing # expression grammars into some textual representation. I.e. this # object manages the conversion to specialized serializations of # parsing expression grammars. @@ -16,14 +14,14 @@ # ### ### ### ######### ######### ######### ## Requisites package require Tcl 8.5 -package require configuration +package require snit package require pt::peg package require pluginmgr -package require snit +package require struct::map # ### ### ### ######### ######### ######### ## API snit::type ::pt::peg::export { @@ -33,11 +31,11 @@ # ### ### ### ######### ######### ######### ## Creation, destruction. constructor {} { - install myconfig using ::configuration ${selfns}::CONFIG + install myconfig using ::struct::map ${selfns}::CONFIG return } destructor { $myconfig destroy @@ -113,7 +111,7 @@ } # ### ### ### ######### ######### ######### ## Ready -package provide pt::peg::export 1 +package provide pt::peg::export 1.0.1 return Index: modules/pt/pt_peg_export.test ================================================================== --- modules/pt/pt_peg_export.test +++ modules/pt/pt_peg_export.test @@ -1,12 +1,10 @@ # -*- tcl -*- # peg_export.test: tests for the pt::peg::export package. # -# Copyright (c) 2009 by Andreas Kupries +# Copyright (c) 2009-2019 by Andreas Kupries # All rights reserved. -# -# RCS: @(#) $Id: pt_peg_export.test,v 1.1 2010/03/26 05:07:24 andreas_kupries Exp $ # ------------------------------------------------------------------------- source [file join \ [file dirname [file dirname [file join [pwd] [info script]]]] \ @@ -20,12 +18,12 @@ TestAccelInit struct::set use fileutil/fileutil.tcl fileutil ;# tests/common use snit/snit.tcl snit use pluginmgr/pluginmgr.tcl pluginmgr + use struct/map.tcl struct::map - useLocal configuration.tcl configuration useLocal pt_pexpression.tcl pt::pe useLocal pt_pegrammar.tcl pt::peg source [localPath tests/common] } Index: modules/pt/pt_peg_import.man ================================================================== --- modules/pt/pt_peg_import.man +++ modules/pt/pt_peg_import.man @@ -1,14 +1,16 @@ [comment {-*- tcl -*- doctools manpage}] -[manpage_begin pt::peg::import n 1] +[vset VERSION 1.0.1] +[manpage_begin pt::peg::import n [vset VERSION]] [include include/module.inc] [titledesc {PEG Import}] +[require Tcl 8.5] [require snit] -[require configuration] +[require fileutil::paths] [require pt::peg] [require pluginmgr] -[require pt::peg::import [opt 1]] +[require pt::peg::import [opt [vset VERSION]]] [description] [include include/ref_intro.inc] This package provides a manager for parsing expression grammars, with each instance handling a set of plugins for the import of them from Index: modules/pt/pt_peg_import.tcl ================================================================== --- modules/pt/pt_peg_import.tcl +++ modules/pt/pt_peg_import.tcl @@ -1,26 +1,24 @@ # import.tcl -- # # Importing parsing expression grammars from other formats. # -# Copyright (c) 2009 Andreas Kupries +# Copyright (c) 2009-2019 Andreas Kupries # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# RCS: @(#) $Id: pt_peg_import.tcl,v 1.1 2010/03/26 05:07:24 andreas_kupries Exp $ # Each object manages a set of plugins for the creation of parsing # expression grammars from some textual representation. I.e. this # object manages the conversion from specialized serializations of # parsing expression grammars into their standard form. # ### ### ### ######### ######### ######### ## Requisites -package require Tcl 8.5 -package require paths +package require Tcl 8.4 +package require fileutil::paths package require pt::peg package require pluginmgr package require snit # ### ### ### ######### ######### ######### @@ -33,11 +31,11 @@ # ### ### ### ######### ######### ######### ## Creation, destruction. constructor {} { - install myinclude using ::paths ${selfns}::INCLUDE + install myinclude using ::fileutil::paths ${selfns}::INCLUDE return } destructor { $myinclude destroy @@ -184,7 +182,7 @@ } # ### ### ### ######### ######### ######### ## Ready -package provide pt::peg::import 1 +package provide pt::peg::import 1.0.1 return Index: modules/pt/pt_peg_import.test ================================================================== --- modules/pt/pt_peg_import.test +++ modules/pt/pt_peg_import.test @@ -1,12 +1,10 @@ # -*- tcl -*- # peg_import.test: tests for the pt::peg::import package. # -# Copyright (c) 2009 by Andreas Kupries +# Copyright (c) 2009-2019 by Andreas Kupries # All rights reserved. -# -# RCS: @(#) $Id: pt_peg_import.test,v 1.1 2010/03/26 05:07:24 andreas_kupries Exp $ # ------------------------------------------------------------------------- source [file join \ [file dirname [file dirname [file join [pwd] [info script]]]] \ @@ -16,13 +14,13 @@ testsNeedTcltest 2 support { use fileutil/fileutil.tcl fileutil ;# tests/common use snit/snit.tcl snit + use fileutil/paths.tcl fileutil::paths use pluginmgr/pluginmgr.tcl pluginmgr - useLocal paths.tcl paths useLocal pt_pexpression.tcl pt::pe useLocal pt_pegrammar.tcl pt::peg source [localPath tests/common] } Index: modules/pt/tests/pt_peg_export.tests ================================================================== --- modules/pt/tests/pt_peg_export.tests +++ modules/pt/tests/pt_peg_export.tests @@ -36,35 +36,35 @@ pt::peg::export E } -body { E configuration names X } -cleanup { E destroy -} -returnCodes error -result {wrong # args: should be "::configuration::Snit_methodnames type selfns win self"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodnames type selfns win self"} test pt-peg-export-set:${setimpl}-6.0 {configuration get, wrong#args} -setup { pt::peg::export E } -body { E configuration get X } -cleanup { E destroy -} -returnCodes error -result {wrong # args: should be "::configuration::Snit_methodget type selfns win self"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodget type selfns win self"} test pt-peg-export-set:${setimpl}-7.0 {configuration set, wrong#args} -setup { pt::peg::export E } -body { E configuration set } -cleanup { E destroy -} -returnCodes error -result {wrong # args: should be "::configuration::Snit_methodset type selfns win self name ?value?"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodset type selfns win self name ?value?"} test pt-peg-export-set:${setimpl}-7.1 {configuration set, wrong#args} -setup { pt::peg::export E } -body { E configuration set N V X } -cleanup { E destroy -} -returnCodes error -result {wrong # args: should be "::configuration::Snit_methodset type selfns win self name ?value?"} +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodset type selfns win self name ?value?"} # ------------------------------------------------------------------------- test pt-peg-export-set:${setimpl}-12.0 {configuration set, define single var} -setup { pt::peg::export E Index: modules/pt/tests/pt_peg_import.tests ================================================================== --- modules/pt/tests/pt_peg_import.tests +++ modules/pt/tests/pt_peg_import.tests @@ -80,57 +80,60 @@ I destroy } -returnCodes error -result {wrong # args: should be "::pt::peg::import::Snit_hmethodimport_object_file type selfns win self obj path ?format?"} # config unset - accepts any number of arguments. +# ------------------------------------------------------------------------- +## `include` component, provided via fileutil::paths, search path for includes + test pt-peg-import-5.0 {include paths, wrong#args} -setup { pt::peg::import I } -body { I include paths X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::paths::Snit_methodpaths type selfns win self"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodpaths type selfns win self"} test pt-peg-import-6.0 {include clear, wrong#args} -setup { pt::peg::import I } -body { I include clear X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::paths::Snit_methodclear type selfns win self"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodclear type selfns win self"} test pt-peg-import-7.0 {include add, wrong#args} -setup { pt::peg::import I } -body { I include add } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::paths::Snit_methodadd type selfns win self path"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodadd type selfns win self path"} test pt-peg-import-7.1 {include add, wrong#args} -setup { pt::peg::import I } -body { I include add P X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::paths::Snit_methodadd type selfns win self path"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodadd type selfns win self path"} test pt-peg-import-8.0 {include remove, wrong#args} -setup { pt::peg::import I } -body { I include remove } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::paths::Snit_methodremove type selfns win self path"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodremove type selfns win self path"} test pt-peg-import-8.1 {include remove, wrong#args} -setup { pt::peg::import I } -body { I include remove P X } -cleanup { I destroy -} -returnCodes error -result {wrong # args: should be "::paths::Snit_methodremove type selfns win self path"} +} -returnCodes error -result {wrong # args: should be "::fileutil::paths::Snit_methodremove type selfns win self path"} # ------------------------------------------------------------------------- test pt-peg-import9.0 {include paths, empty} -setup { pt::peg::import I Index: modules/rc4/rc4.man ================================================================== --- modules/rc4/rc4.man +++ modules/rc4/rc4.man @@ -114,7 +114,7 @@ [section "AUTHORS"] Pat Thoyts [vset CATEGORY rc4] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/rcs/rcs.man ================================================================== --- modules/rcs/rcs.man +++ modules/rcs/rcs.man @@ -324,7 +324,7 @@ }} {a 11 {They both may be called deep and profound. Deeper and more profound, The door of all subtleties!}}}}] [vset CATEGORY rcs] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/report/report.man ================================================================== --- modules/report/report.man +++ modules/report/report.man @@ -470,7 +470,7 @@ % # alternate way of doing the above % m format 2string r }] [vset CATEGORY report] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/rest/rest.man ================================================================== --- modules/rest/rest.man +++ modules/rest/rest.man @@ -547,11 +547,11 @@ }] [include ../common-text/tls-security-notes.inc] [vset CATEGORY rest] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [comment { TOKENS the value is substituted into the url at call time. tokens in the form of %name:default_value% will be an optional argument with a default value. Index: modules/ripemd/ripemd128.man ================================================================== --- modules/ripemd/ripemd128.man +++ modules/ripemd/ripemd128.man @@ -185,7 +185,7 @@ ([uri http://www.rfc-editor.org/rfc/rfc2104.txt]) [list_end] [vset CATEGORY ripemd] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/ripemd/ripemd160.man ================================================================== --- modules/ripemd/ripemd160.man +++ modules/ripemd/ripemd160.man @@ -169,7 +169,7 @@ ([uri http://www.rfc-editor.org/rfc/rfc2104.txt]) [list_end] [vset CATEGORY ripemd] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/sasl/gtoken.man ================================================================== --- modules/sasl/gtoken.man +++ modules/sasl/gtoken.man @@ -21,7 +21,7 @@ [section AUTHORS] Pat Thoyts [vset CATEGORY sasl] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/sasl/ntlm.man ================================================================== --- modules/sasl/ntlm.man +++ modules/sasl/ntlm.man @@ -30,7 +30,7 @@ [section AUTHORS] Pat Thoyts [vset CATEGORY sasl] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/sasl/sasl.man ================================================================== --- modules/sasl/sasl.man +++ modules/sasl/sasl.man @@ -334,7 +334,7 @@ [section AUTHORS] Pat Thoyts [vset CATEGORY sasl] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/sasl/scram.man ================================================================== --- modules/sasl/scram.man +++ modules/sasl/scram.man @@ -30,7 +30,7 @@ [section AUTHORS] Sergei Golovan [vset CATEGORY sasl] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/sha1/pkgIndex.tcl ================================================================== --- modules/sha1/pkgIndex.tcl +++ modules/sha1/pkgIndex.tcl @@ -7,8 +7,8 @@ # in response to "package require" commands. When this # script is sourced, the variable $dir must contain the # full path name of this file's directory. if {![package vsatisfies [package provide Tcl] 8.2]} {return} -package ifneeded sha256 1.0.3 [list source [file join $dir sha256.tcl]] -package ifneeded sha1 2.0.3 [list source [file join $dir sha1.tcl]] +package ifneeded sha256 1.0.4 [list source [file join $dir sha256.tcl]] +package ifneeded sha1 2.0.4 [list source [file join $dir sha1.tcl]] package ifneeded sha1 1.1.1 [list source [file join $dir sha1v1.tcl]] Index: modules/sha1/sha1.man ================================================================== --- modules/sha1/sha1.man +++ modules/sha1/sha1.man @@ -1,6 +1,7 @@ -[manpage_begin sha1 n 2.0.3] +[vset VERSION 2.0.4] +[manpage_begin sha1 n [vset VERSION]] [see_also md4] [see_also md5] [see_also ripemd128] [see_also ripemd160] [keywords {FIPS 180-1}] @@ -12,11 +13,11 @@ [moddesc {SHA-x Message-Digest Algorithm}] [copyright {2005, Pat Thoyts }] [titledesc {SHA1 Message-Digest Algorithm}] [category {Hashes, checksums, and encryption}] [require Tcl 8.2] -[require sha1 [opt 2.0.3]] +[require sha1 [opt [vset VERSION]]] [description] [para] This package provides an implementation in Tcl of the SHA1 message-digest algorithm as specified by FIPS PUB 180-1 (1). This @@ -176,7 +177,7 @@ ([uri http://www.rfc-editor.org/rfc/rfc2104.txt]) [list_end] [vset CATEGORY sha1] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/sha1/sha1.tcl ================================================================== --- modules/sha1/sha1.tcl +++ modules/sha1/sha1.tcl @@ -642,16 +642,17 @@ # fileevent handler for chunked file hashing. # proc ::sha1::Chunk {token channel {chunksize 4096}} { upvar #0 $token state + SHA1Update $token [read $channel $chunksize] + if {[eof $channel]} { fileevent $channel readable {} set state(reading) 0 } - - SHA1Update $token [read $channel $chunksize] + return } # ------------------------------------------------------------------------- proc ::sha1::sha1 {args} { @@ -802,12 +803,12 @@ } } unset e } -package provide sha1 2.0.3 +package provide sha1 2.0.4 # ------------------------------------------------------------------------- # Local Variables: # mode: tcl # indent-tabs-mode: nil # End: Index: modules/sha1/sha256.man ================================================================== --- modules/sha1/sha256.man +++ modules/sha1/sha256.man @@ -1,6 +1,7 @@ -[manpage_begin sha256 n 1.0.3] +[vset VERSION 1.0.4] +[manpage_begin sha256 n [vset VERSION]] [see_also md4] [see_also md5] [see_also ripemd128] [see_also ripemd160] [see_also sha1] @@ -13,11 +14,11 @@ [moddesc {SHA-x Message-Digest Algorithm}] [copyright {2008, Andreas Kupries }] [titledesc {SHA256 Message-Digest Algorithm}] [category {Hashes, checksums, and encryption}] [require Tcl 8.2] -[require sha256 [opt 1.0.3]] +[require sha256 [opt [vset VERSION]]] [description] [para] This package provides an implementation in Tcl of the SHA256 and SHA224 message-digest algorithms as specified by FIPS PUB 180-1 @@ -188,7 +189,7 @@ ([uri http://www.rfc-editor.org/rfc/rfc2104.txt]) [list_end] [vset CATEGORY sha1] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/sha1/sha256.tcl ================================================================== --- modules/sha1/sha256.tcl +++ modules/sha1/sha256.tcl @@ -29,10 +29,11 @@ array set accel {tcl 0 critcl 0} variable loaded {} namespace export sha256 hmac \ SHA256Init SHA256Update SHA256Final + variable uid if {![info exists uid]} { set uid 0 } @@ -173,11 +174,11 @@ foreach c { SHA256Init SHA224Init SHA256Final SHA224Final SHA256Update } { - rename ::sha2::$c ::sha2::${c}-${loaded} + interp alias {} ::sha2::$c {} } } # Activate the new implementation, if there is any. @@ -185,11 +186,11 @@ foreach c { SHA256Init SHA224Init SHA256Final SHA224Final SHA256Update } { - rename ::sha2::${c}-${key} ::sha2::$c + interp alias {} ::sha2::$c {} ::sha2::${c}-${key} } } # Remember the active implementation, for deactivation by future # switches. @@ -657,16 +658,17 @@ # fileevent handler for chunked file hashing. # proc ::sha2::Chunk {token channel {chunksize 4096}} { upvar #0 $token state + SHA256Update $token [read $channel $chunksize] + if {[eof $channel]} { fileevent $channel readable {} set state(reading) 0 } - - SHA256Update $token [read $channel $chunksize] + return } # ------------------------------------------------------------------------- proc ::sha2::_sha256 {ver args} { @@ -697,11 +699,10 @@ set opts(-channel) [open $opts(-filename) r] fconfigure $opts(-channel) -translation binary } if {$opts(-channel) == {}} { - if {[llength $args] != 1} { return -code error "wrong # args: should be\ \"[namespace current]::sha$ver ?-hex|-bin? -filename file\ | -channel channel | string\"" } @@ -821,12 +822,12 @@ } } unset e } -package provide sha256 1.0.3 +package provide sha256 1.0.4 # ------------------------------------------------------------------------- # Local Variables: # mode: tcl # indent-tabs-mode: nil # End: Index: modules/smtpd/smtpd.man ================================================================== --- modules/smtpd/smtpd.man +++ modules/smtpd/smtpd.man @@ -288,7 +288,7 @@ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file [file license.terms] for more details. [vset CATEGORY smtpd] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/snit/snit.man ================================================================== --- modules/snit/snit.man +++ modules/snit/snit.man @@ -2833,7 +2833,7 @@ and Anton Kovalenko. If I've forgotten anyone, my apologies; let me know and I'll add your name to the list. [vset CATEGORY snit] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/snit/snitfaq.man ================================================================== --- modules/snit/snitfaq.man +++ modules/snit/snitfaq.man @@ -4108,7 +4108,7 @@ mylib::propagate -foreground to {comp1 comp2 comp3} } }] [vset CATEGORY snit] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/soundex/soundex.man ================================================================== --- modules/soundex/soundex.man +++ modules/soundex/soundex.man @@ -39,7 +39,7 @@ % ::soundex::knuth Knuth K530 }] [vset CATEGORY soundex] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/stooop/stooop.man ================================================================== --- modules/stooop/stooop.man +++ modules/stooop/stooop.man @@ -217,7 +217,7 @@ [section EXAMPLES] Please see the full HTML documentation in [uri stooop_man.html]. [vset CATEGORY stooop] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/stooop/switched.man ================================================================== --- modules/stooop/switched.man +++ modules/stooop/switched.man @@ -322,7 +322,7 @@ }] [list_end] [vset CATEGORY stooop] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/string/token.man ================================================================== --- modules/string/token.man +++ modules/string/token.man @@ -91,7 +91,7 @@ exactly at the character index found in [arg startvar]. [list_end] [vset CATEGORY textutil] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/string/token_shell.man ================================================================== --- modules/string/token_shell.man +++ modules/string/token_shell.man @@ -135,7 +135,7 @@ [list_end] [list_end] [vset CATEGORY textutil] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/stringprep/stringprep.man ================================================================== --- modules/stringprep/stringprep.man +++ modules/stringprep/stringprep.man @@ -145,7 +145,7 @@ [section "AUTHORS"] Sergei Golovan [vset CATEGORY stringprep] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/stringprep/stringprep_data.man ================================================================== --- modules/stringprep/stringprep_data.man +++ modules/stringprep/stringprep_data.man @@ -15,7 +15,7 @@ perform its functions. It is an [emph internal] package which should not be accessed on its own. Because of that it has no publicly documented API either. Its implementation is generated by a script. [vset CATEGORY stringprep] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/stringprep/unicode.man ================================================================== --- modules/stringprep/unicode.man +++ modules/stringprep/unicode.man @@ -77,7 +77,7 @@ [section "AUTHORS"] Sergei Golovan [vset CATEGORY stringprep] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/stringprep/unicode_data.man ================================================================== --- modules/stringprep/unicode_data.man +++ modules/stringprep/unicode_data.man @@ -15,7 +15,7 @@ perform its functions. It is an [emph internal] package which should not be accessed on its own. Because of that it has no publicly documented API either. Its implementation is generated by a script. [vset CATEGORY stringprep] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/struct/disjointset.man ================================================================== --- modules/struct/disjointset.man +++ modules/struct/disjointset.man @@ -230,7 +230,7 @@ Destroys the disjoint set object and all associated memory. [list_end] [vset CATEGORY {struct :: disjointset}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/struct/graph.man ================================================================== --- modules/struct/graph.man +++ modules/struct/graph.man @@ -1,6 +1,6 @@ -[comment {-*- tcl -*-}][vset VERSION 2.4.1] +[comment {-*- tcl -*-}][vset VERSION 2.4.2] [manpage_begin struct::graph n [vset VERSION]] [keywords adjacent] [keywords arc] [keywords cgraph] [keywords degree] @@ -10,11 +10,11 @@ [keywords neighbour] [keywords node] [keywords serialization] [keywords subgraph] [keywords vertex] -[copyright {2002-2009 Andreas Kupries }] +[copyright {2002-2009,2019 Andreas Kupries }] [moddesc {Tcl Data Structures}] [titledesc {Create and manipulate directed graph objects}] [category {Data structures}] [require Tcl 8.4] [require struct::graph [opt [vset VERSION]]] @@ -395,11 +395,11 @@ name of the restriction itself. [para] The restrictions imposed by either [option -in], [option -out], -[option -adj], [option -inner], or [option -embedded] are applied +[option -adj], [option -inner], or [option -embedding] are applied first. Specifying more than one of them is illegal. [para] After that the restrictions set via [option -key] (and @@ -446,10 +446,26 @@ Return a list of all arcs adjacent to exactly one of the nodes in the set. This is the set of arcs connecting the subgraph spawned by the specified nodes to the rest of the graph. +[list_end] + +[emph Attention]: After the above options any word with a leading dash +which is not a valid option is treated as a node name instead of an +invalid option to error out on. This condition holds until either a +valid option terminates the list of nodes, or the end of the command +is reached, whichever comes first. + +[para] + +The remaining filter options are: + +[para] + +[list_begin definitions] + [def "[option -key] [arg key]"] Limit the list of arcs that are returned to those arcs that have an associated key [arg key]. @@ -607,13 +623,19 @@ neighboring nodes have a list of nodes as argument, specified after the name of the restriction itself. [para] -The possible restrictions are the same as for method -[method arcs]. The exact meanings change slightly, as they operate on -nodes instead of arcs. The command recognizes: +The possible restrictions are the same as for method [method arcs]. + +Note that while the exact meanings change slightly, as they operate on +nodes instead of arcs, the general behaviour is the same, especially +when it comes to the handling of words with a leading dash in node +lists. + +[para] +The command recognizes: [list_begin definitions] [def [option -in]] Return a list of all nodes with at least one outgoing arc ending in a @@ -936,7 +958,7 @@ criterium. [list_end] [vset CATEGORY {struct :: graph}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/struct/graph.tcl ================================================================== --- modules/struct/graph.tcl +++ modules/struct/graph.tcl @@ -175,6 +175,6 @@ namespace eval ::struct { # Export the constructor command. namespace export graph } -package provide struct::graph 2.4.1 +package provide struct::graph 2.4.2 Index: modules/struct/graph.test ================================================================== --- modules/struct/graph.test +++ modules/struct/graph.test @@ -4,14 +4,12 @@ # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1998-2000 by Ajuba Solutions. -# Copyright (c) 2017-2017 Andreas Kupries +# Copyright (c) 2017,2019 Andreas Kupries # All rights reserved. -# -# RCS: @(#) $Id: graph.test,v 1.27 2007/04/12 03:01:54 andreas_kupries Exp $ # ------------------------------------------------------------------------- source [file join \ [file dirname [file dirname [file join [pwd] [info script]]]] \ Index: modules/struct/graph/tests/nodes.test ================================================================== --- modules/struct/graph/tests/nodes.test +++ modules/struct/graph/tests/nodes.test @@ -13,10 +13,15 @@ # graph nodes -adj NODE... # graph nodes -inner NODE... # graph nodes -embedded NODE... # We can use one in each group (1,2,3) + +# Note: node names may have a leading dash ('-'). + +# Heuristics: Unknown options after (3) are considered node names +# until we reach a valid option. # ------------------------------------------------------------------------- # Wrong # args: Missing, Too many # Cannot have missing arguments (zero is fine), @@ -234,53 +239,71 @@ # ------------------------------------------------------------------------- # Ok arguments. set n 0 foreach {switch nodes expected} { - -in {1 2 3} {1 2 3 4 5 6} -in {4 5 6} {} + -in {1 2 3} {-1 1 2 3 4 5 6} -in {4 5 6} {} -out {1 2 3} {1 2 3} -out {4 5 6} {1 2 3} - -adj {1 2 3} {1 2 3 4 5 6} -adj {4 5 6} {1 2 3} + -adj {1 2 3} {-1 1 2 3 4 5 6} -adj {4 5 6} {1 2 3} -inner {1 2 3} {1 2 3} -inner {4 5 6} {} - -embedding {1 2 3} {4 5 6} -embedding {4 5 6} {1 2 3} - -in {1 2} {1 3 4 5} -in {4 5} {} + -embedding {1 2 3} {-1 4 5 6} -embedding {4 5 6} {1 2 3} + -in {1 2} {-1 1 3 4 5} -in {4 5} {} -out {1 2} {2 3} -out {4 5} {1 2} - -adj {1 2} {1 2 3 4 5} -adj {4 5} {1 2} + -adj {1 2} {-1 1 2 3 4 5} -adj {4 5} {1 2} -inner {1 2} {1 2} -inner {4 5} {} - -embedding {1 2} {3 4 5} -embedding {4 5} {1 2} + -embedding {1 2} {-1 3 4 5} -embedding {4 5} {1 2} -in {1} {3 4} -in {4} {} -out {1} {2} -out {4} {1} -adj {1} {2 3 4} -adj {4} {1} -inner {1} {} -inner {4} {} -embedding {1} {2 3 4} -embedding {4} {1} - -in {1 4} {3 4} -in {4 2} {1 5} + -in {1 4} {3 4} -in {4 2} {-1 1 5} -out {1 4} {1 2} -out {4 2} {1 3} - -adj {1 4} {1 2 3 4} -adj {4 2} {1 3 5} + -adj {1 4} {1 2 3 4} -adj {4 2} {-1 1 3 5} -inner {1 4} {1 4} -inner {4 2} {} - -embedding {1 4} {2 3} -embedding {4 2} {1 3 5} + -embedding {1 4} {2 3} -embedding {4 2} {-1 1 3 5} + -in {1 -1} {3 4} + -out {1 -1} 2 + -adj {1 -1} {2 3 4} + -inner {1 -1} {} + -embedding {1 -1} {2 3 4} } { + lappend expected $switch $nodes + test graph-${impl}-${setimpl}-nodes-ioaie-3.$n "nodes, $switch" { SETUP - - mygraph node insert 1 2 3 4 5 6 + # Nodes (digits -1,1-6) and arcs (letters A-G), no direction + # 4 + # |A + # 1 -1 + # D/ \ /G + # / \E/ + # 3 --- 2 + # C/ F \B + # 6 5 + + mygraph node insert 1 2 3 4 5 6 -1 mygraph arc insert 4 1 A mygraph arc insert 5 2 B mygraph arc insert 6 3 C mygraph arc insert 3 1 D mygraph arc insert 1 2 E mygraph arc insert 2 3 F + mygraph arc insert -1 2 G set result [lsort [eval [linsert $nodes 0 mygraph nodes $switch]]] mygraph destroy + lappend result $switch $nodes set result } $expected ; # {} incr n } # --------------------------------------------------- # Test with many parallel arcs, beyond the number of nodes, i.e. lots -# of duplicates sources and destinations, to check that the dup +# of duplicated sources and destinations, to check that the dup # removal works correctly. See bug [SF 1923685]. set n 0 foreach {switch nodes expected} { -in 2 1 @@ -287,10 +310,12 @@ -out 2 3 -adj 2 {1 3} -inner {1 2 3} {1 2 3} -embedding 2 {1 3} } { + lappend expected $switch $nodes + test graph-${impl}-${setimpl}-nodes-parallel-ioaie-bug1923685-4.$n "nodes, $switch, parallel arcs, bug 1923685" { SETUP mygraph node insert 1 2 3 4 mygraph arc insert 1 2 A ; mygraph arc insert 2 3 A. @@ -302,12 +327,13 @@ mygraph arc insert 1 2 G ; mygraph arc insert 2 3 G. mygraph arc insert 1 2 H ; mygraph arc insert 2 3 H. set result [lsort [eval [linsert $nodes 0 mygraph nodes $switch]]] mygraph destroy + lappend result $switch $nodes set result } $expected ; # {} incr n } # --------------------------------------------------- Index: modules/struct/graph1.man ================================================================== --- modules/struct/graph1.man +++ modules/struct/graph1.man @@ -369,7 +369,7 @@ a node [const enter]s it, the second visit [const leave]s it. [list_end] [vset CATEGORY {struct :: graph}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/struct/graph_tcl.tcl ================================================================== --- modules/struct/graph_tcl.tcl +++ modules/struct/graph_tcl.tcl @@ -1,16 +1,14 @@ # graph_tcl.tcl -- # # Implementation of a graph data structure for Tcl. # -# Copyright (c) 2000-2009 by Andreas Kupries -# Copyright (c) 2008 by Alejandro Paz +# Copyright (c) 2000-2009,2019 by Andreas Kupries +# Copyright (c) 2008 by Alejandro Paz # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# RCS: @(#) $Id: graph_tcl.tcl,v 1.5 2009/11/26 04:42:16 andreas_kupries Exp $ package require Tcl 8.4 package require struct::list package require struct::set @@ -2999,11 +2997,12 @@ upvar 1 fcmd fcmd ; set fcmd {} upvar 1 cond cond ; set cond "none" upvar 1 condNodes condNodes ; set condNodes {} set wa_usage "wrong # args: should be \"$name $what ?-key key? ?-value value? ?-filter cmd? ?-in|-out|-adj|-inner|-embedding node node...?\"" - + set seenodes 0 + for {set i 0} {$i < [llength $arguments]} {incr i} { set arg [lindex $arguments $i] switch -glob -- $arg { -in - -out - @@ -3016,10 +3015,11 @@ \"-in\"|\"-out\"|\"-adj\"|\"-inner\"|\"-embedding\"" } set haveCond 1 set cond [string range $arg 1 end] + set seenodes 1 } -key { if {($i + 1) == [llength $arguments]} { return -code error $wa_usage } @@ -3028,10 +3028,11 @@ } incr i set key [lindex $arguments $i] set haveKey 1 + set seenodes 0 } -value { if {($i + 1) == [llength $arguments]} { return -code error $wa_usage } @@ -3040,10 +3041,11 @@ } incr i set value [lindex $arguments $i] set haveValue 1 + set seenodes 0 } -filter { if {($i + 1) == [llength $arguments]} { return -code error $wa_usage } @@ -3052,14 +3054,19 @@ } incr i set fcmd [lindex $arguments $i] set haveFilter 1 + set seenodes 0 } -* { - return -code error "bad restriction \"$arg\": must be -adj, -embedding,\ + if {$seenodes} { + lappend condNodes $arg + } else { + return -code error "bad restriction \"$arg\": must be -adj, -embedding,\ -filter, -in, -inner, -key, -out, or -value" + } } default { lappend condNodes $arg } } Index: modules/struct/graphops.man ================================================================== --- modules/struct/graphops.man +++ modules/struct/graphops.man @@ -1313,7 +1313,7 @@ [enum] [uri http://en.wikipedia.org/wiki/Degree-constrained_spanning_tree {Minimum Degree Spanning Tree}] [enum] [uri http://en.wikipedia.org/wiki/Approximation_algorithm {Approximation algorithm}] [list_end] [vset CATEGORY {struct :: graph}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] ADDED modules/struct/map.tcl Index: modules/struct/map.tcl ================================================================== --- /dev/null +++ modules/struct/map.tcl @@ -0,0 +1,104 @@ +# map.tcl -- +# Copyright (c) 2009-2019 Andreas Kupries +# +# Object wrapper around array/dict. Useful as key/value store in +# larger systems. +# +# Examples: +# - configuration mgmt in doctools v2 import/export managers +# - pt import/export managers +# +# Each object manages a key/value map. + +# ### ### ### ######### ######### ######### +## Requisites + +package require Tcl 8.4 +package require snit + +# ### ### ### ######### ######### ######### +## API + +# ATTENTION: +## +# From an API point of view the code below is equivalent to the much +# shorter `snit::type struct::map { ... }`. +# +# Then why the more complex form ? +# +# When snit compiles the class to Tcl code, and later on when methods +# are executed it will happen in the `struct` namespace. The moment +# this package is used together with `struct::set` all unqualified +# `set` statements will go bonkers, eiter in snit, or, here, in method +# `set`, because they get resolved to the `struct::set` dispatcher +# instead of `::set`. Moving the implementation a level deeper makes +# the `struct::map` namespace the context, with no conflict. + +# Future / TODO: Convert all the OO stuff here over to TclOO, as much +# as possible (snit configure/cget support is currently still better, +# ditto hierarchical methods). + +namespace eval ::struct {} + +proc ::struct::map {args} { + uplevel 1 [linsert $args 0 struct::map::I] +} + +snit::type ::struct::map::I { + + # ### ### ### ######### ######### ######### + ## Options :: None + + # ### ### ### ######### ######### ######### + ## Creating, destruction + + # Default constructor. + # Default destructor. + + # ### ### ### ######### ######### ######### + ## Public methods. Reading and writing the map. + + method names {} { + return [array names mymap] + } + + method get {} { + return [array get mymap] + } + + method set {name {value {}}} { + # 7 instead of 3 in the condition below, because of the 4 + # implicit arguments snit is providing to each method. + if {[llength [info level 0]] == 7} { + ::set mymap($name) $value + } elseif {![info exists mymap($name)]} { + return -code error "can't read \"$name\": no such variable" + } + return $mymap($name) + } + + method unset {args} { + if {![llength $args]} { lappend args * } + foreach pattern $args { + array unset mymap $pattern + } + return + } + + # ### ### ### ######### ######### ######### + ## Internal methods :: None. + + # ### ### ### ######### ######### ######### + ## State :: Map data, Tcl array + + variable mymap -array {} + + ## + # ### ### ### ######### ######### ######### +} + +# ### ### ### ######### ######### ######### +## Ready + +package provide struct::map 1 +return ADDED modules/struct/map.test Index: modules/struct/map.test ================================================================== --- /dev/null +++ modules/struct/map.test @@ -0,0 +1,143 @@ +# -*- tcl -*- +# map.test: Testsuite for package struct::map +# +# Copyright (c) 2019 by Andreas Kupries +# All rights reserved. + +# ------------------------------------------------------------------------- + +source [file join \ + [file dirname [file dirname [file join [pwd] [info script]]]] \ + devtools testutilities.tcl] + +testsNeedTcl 8.4 +testsNeedTcltest 2.0 + +support { + use snit/snit.tcl snit +} +testing { + useLocal map.tcl struct::map +} + +# --------------------------------------------------------------------- +# [] constructor +# [] destructor +# [] get +# [] names +# [] set +# [] unset + +#---------------------------------------------------------------------- +## Constructor, destructor + +test struct-map-1.0 {constructor, wrong args, too many} -body { + struct::map M X +} -returnCodes error -result {Error in constructor: wrong # args: should be "::struct::map::I::Snit_constructor type selfns win self"} + +test struct-map-1.1 {instance, bogus method} -setup { + struct::map M +} -cleanup { + M destroy +} -body { + M bogus +} -returnCodes error -result {"::M bogus" is not defined} + +#---------------------------------------------------------------------- +## get + +test struct-map-2.0 {get, wrong args, too many} -setup { + struct::map M +} -cleanup { + M destroy +} -body { + M get X +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodget type selfns win self"} + +test struct-map-2.1 {get, base state, none} -setup { + struct::map M +} -cleanup { + M destroy +} -body { + M get +} -result {} + +#---------------------------------------------------------------------- +## names + +test struct-map-3.0 {names, wrong args, too many} -setup { + struct::map M +} -cleanup { + M destroy +} -body { + M names X +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodnames type selfns win self"} + +test struct-map-3.1 {names, base state, none} -setup { + struct::map M +} -cleanup { + M destroy +} -body { + M names +} -result {} + +#---------------------------------------------------------------------- +## set + +test struct-map-4.0 {set, wrong args, not enough} -setup { + struct::map M +} -cleanup { + M destroy +} -body { + M set +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodset type selfns win self name ?value?"} + +test struct-map-4.1 {set, wrong args, too many} -setup { + struct::map M +} -cleanup { + M destroy +} -body { + M set K V X +} -returnCodes error -result {wrong # args: should be "::struct::map::I::Snit_methodset type selfns win self name ?value?"} + +test struct-map-4.2 {set, state change, result} -setup { + struct::map M +} -cleanup { + M destroy +} -body { + list [M names] [M get] [M set K V] [M names] [M get] +} -result {{} {} V K {K V}} + +#---------------------------------------------------------------------- +## unset + +test struct-map-5.2 {unset, known key, state change, result} -setup { + struct::map M + M set K V +} -cleanup { + M destroy +} -body { + list [M names] [M get] [M unset K] [M names] [M get] +} -result {K {K V} {} {} {}} + +test struct-map-5.3 {unset, missing key, no state change, result} -setup { + struct::map M + M set K V +} -cleanup { + M destroy +} -body { + list [M names] [M get] [M unset K'] [M names] [M get] +} -result {K {K V} {} K {K V}} + +test struct-map-5.4 {unset, no pattern, clear, result} -setup { + struct::map M + M set K V +} -cleanup { + M destroy +} -body { + list [M names] [M get] [M unset] [M names] [M get] +} -result {K {K V} {} {} {}} + +#---------------------------------------------------------------------- +testsuiteCleanup +return Index: modules/struct/matrix.man ================================================================== --- modules/struct/matrix.man +++ modules/struct/matrix.man @@ -533,7 +533,7 @@ % # alternate way of doing the above % r printmatrix m }] [vset CATEGORY {struct :: matrix}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/struct/matrix1.man ================================================================== --- modules/struct/matrix1.man +++ modules/struct/matrix1.man @@ -375,7 +375,7 @@ % # alternate way of doing the above % r printmatrix m }] [vset CATEGORY {struct :: matrix}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/struct/pkgIndex.tcl ================================================================== --- modules/struct/pkgIndex.tcl +++ modules/struct/pkgIndex.tcl @@ -16,11 +16,12 @@ package ifneeded struct::tree 1.2.2 [list source [file join $dir tree1.tcl]] package ifneeded struct::matrix 1.2.1 [list source [file join $dir matrix1.tcl]] if {![package vsatisfies [package provide Tcl] 8.4]} {return} package ifneeded struct::list 1.8.4 [list source [file join $dir list.tcl]] -package ifneeded struct::graph 2.4.1 [list source [file join $dir graph.tcl]] +package ifneeded struct::graph 2.4.2 [list source [file join $dir graph.tcl]] +package ifneeded struct::map 1 [list source [file join $dir map.tcl]] if {![package vsatisfies [package provide Tcl] 8.5]} {return} if {![package vsatisfies [package provide Tcl] 8.6]} {return} package ifneeded struct::disjointset 1.1 [list source [file join $dir disjointset.tcl]] Index: modules/struct/pool.man ================================================================== --- modules/struct/pool.man +++ modules/struct/pool.man @@ -437,7 +437,7 @@ # or return a 'Server busy' message to the client. } }] [vset CATEGORY {struct :: pool}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/struct/prioqueue.man ================================================================== --- modules/struct/prioqueue.man +++ modules/struct/prioqueue.man @@ -105,7 +105,7 @@ Return the number of items in the prioqueue. [list_end] [vset CATEGORY {struct :: prioqueue}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/struct/queue.man ================================================================== --- modules/struct/queue.man +++ modules/struct/queue.man @@ -90,7 +90,7 @@ Return the number of items in the queue. [list_end] [vset CATEGORY {struct :: queue}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/struct/record.man ================================================================== --- modules/struct/record.man +++ modules/struct/record.man @@ -387,7 +387,7 @@ }] [para] [vset CATEGORY {struct :: record}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/struct/skiplist.man ================================================================== --- modules/struct/skiplist.man +++ modules/struct/skiplist.man @@ -80,7 +80,7 @@ current node appended. [list_end] [vset CATEGORY {struct :: skiplist}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/struct/stack.man ================================================================== --- modules/struct/stack.man +++ modules/struct/stack.man @@ -102,7 +102,7 @@ Return the number of items on the stack. [list_end] [vset CATEGORY {struct :: stack}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/struct/struct_list.man ================================================================== --- modules/struct/struct_list.man +++ modules/struct/struct_list.man @@ -824,7 +824,7 @@ [uri http://www-cs-faculty.stanford.edu/~knuth/fasc2b.ps.gz]. [list_end] [vset CATEGORY {struct :: list}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] ADDED modules/struct/struct_map.man Index: modules/struct/struct_map.man ================================================================== --- /dev/null +++ modules/struct/struct_map.man @@ -0,0 +1,75 @@ +[comment {-*- text -*- doctools manpage}] +[vset VERSION 1] +[manpage_begin struct::map n [vset VERSION]] +[titledesc {Manage key/value maps}] +[require struct::map [opt [vset VERSION]]] +[description] + +Provides a snit class whose instances manage a key/value map. +In other words, an object wrapper around Tcl arrays. + +[section API] + +The main command provides construction of maps: + +[list_begin definitions] + +[call [cmd ::struct::map] [arg mapName]] + +Creates a new, empty map with an associated global Tcl command whose +name is [arg mapName]. + +It may be used to invoke various operations on the map. + +It has the following general form: + +[list_begin definitions] +[call [cmd mapName] [method method] [opt [arg "arg arg ..."]]] +[method method] and [arg arg]uments determine the exact behavior of +the command. +[list_end][comment --instance-command--] + +If [arg mapName] is specified as [const %AUTO%] a unique name will be +generated by the package itself. + +The result of the command is the fully-qualified name of the instance +command. + +[list_end][comment --class-command--] + +[para] + +The following commands are possible for map objects: + +[list_begin definitions] + +[call [arg mapName] [method get]] + +Returns the entire map as a Tcl dictionary. + +[call [arg mapName] [method names]] + +Returns the list of all keys known to the map, in arbitrary order. + +[call [arg mapName] [method set] [arg name] [opt [arg value]]] + +Sets key [arg name] to the specified [arg value], if the value specified. + +Returns the value for the key. + +Throws an error if the key is not known. + +[call [arg mapName] [method unset] [opt [arg pattern]...]] + +Removes all keys matching at least one of the glob [arg pattern]s from +the map. + +If no pattern is specified all keys are removed. +In other words, the default pattern is [const *]. + +The result of the command is the empty string. + +[list_end] + +[include ../common-text/feedback.inc] +[manpage_end] Index: modules/struct/struct_set.man ================================================================== --- modules/struct/struct_set.man +++ modules/struct/struct_set.man @@ -130,7 +130,7 @@ [list_end] [section REFERENCES] [vset CATEGORY {struct :: set}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/struct/struct_tree.man ================================================================== --- modules/struct/struct_tree.man +++ modules/struct/struct_tree.man @@ -786,7 +786,7 @@ # generated name. The name is returned # as the result of the command. }] [vset CATEGORY {struct :: tree}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/struct/struct_tree1.man ================================================================== --- modules/struct/struct_tree1.man +++ modules/struct/struct_tree1.man @@ -286,7 +286,7 @@ [list_end] [list_end] [vset CATEGORY {struct :: tree}] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/tar/tar.man ================================================================== --- modules/tar/tar.man +++ modules/tar/tar.man @@ -163,7 +163,7 @@ }] [list_end] [vset CATEGORY tar] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/term/ansi_cattr.man ================================================================== --- modules/term/ansi_cattr.man +++ modules/term/ansi_cattr.man @@ -77,7 +77,7 @@ [call [cmd ::term::ansi::code::attr::nostrike]] Strike-through off. [call [cmd ::term::ansi::code::attr::reset]] Reset all attributes to their default values. [list_end] [vset CATEGORY term] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/term/ansi_cctrl.man ================================================================== --- modules/term/ansi_cctrl.man +++ modules/term/ansi_cctrl.man @@ -193,7 +193,7 @@ Format the block of text for display at the specified location. [list_end] [vset CATEGORY term] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/term/ansi_cmacros.man ================================================================== --- modules/term/ansi_cmacros.man +++ modules/term/ansi_cmacros.man @@ -60,7 +60,7 @@ the command. [list_end] [vset CATEGORY term] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/term/ansi_code.man ================================================================== --- modules/term/ansi_code.man +++ modules/term/ansi_code.man @@ -40,7 +40,7 @@ sequence [arg code]. [list_end] [vset CATEGORY term] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/term/ansi_ctrlu.man ================================================================== --- modules/term/ansi_ctrlu.man +++ modules/term/ansi_ctrlu.man @@ -73,7 +73,7 @@ the number of rows (aka lines) available for display. [list_end] [vset CATEGORY term] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/term/ansi_send.man ================================================================== --- modules/term/ansi_send.man +++ modules/term/ansi_send.man @@ -260,7 +260,7 @@ Show the block of text at the specified location. [list_end] [vset CATEGORY term] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/term/imenu.man ================================================================== --- modules/term/imenu.man +++ modules/term/imenu.man @@ -149,7 +149,7 @@ The interaction with the object is terminated. [list_end] [vset CATEGORY term] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/term/ipager.man ================================================================== --- modules/term/ipager.man +++ modules/term/ipager.man @@ -148,7 +148,7 @@ The interaction with the object is terminated. [list_end] [vset CATEGORY term] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/term/receive.man ================================================================== --- modules/term/receive.man +++ modules/term/receive.man @@ -71,7 +71,7 @@ If not specified [arg chan] defaults to [const stdin]. [list_end] [vset CATEGORY term] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/term/term.man ================================================================== --- modules/term/term.man +++ modules/term/term.man @@ -14,7 +14,7 @@ commands, in the vein of ncurses or similar packages. Currently nothing has been implemented however. I.e. this package is empty. It can be loaded, yet provides nothing. [vset CATEGORY term] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/term/term_bind.man ================================================================== --- modules/term/term_bind.man +++ modules/term/term_bind.man @@ -118,7 +118,7 @@ In other words, the set of recognized strings has to form a [term {prefix code}]. [vset CATEGORY term] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/term/term_send.man ================================================================== --- modules/term/term_send.man +++ modules/term/term_send.man @@ -30,7 +30,7 @@ destination channel is fixed to [emph stdout]. [list_end] [vset CATEGORY term] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/textutil/adjust.man ================================================================== --- modules/textutil/adjust.man +++ modules/textutil/adjust.man @@ -202,7 +202,7 @@ create properly wrapped paragraphs with arbitrary indentations. [list_end] [vset CATEGORY textutil] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/textutil/expander.man ================================================================== --- modules/textutil/expander.man +++ modules/textutil/expander.man @@ -505,7 +505,7 @@ [cmd expander] was written by William H. Duquette; it is a repackaging of the central algorithm of the expand macro processing tool. [vset CATEGORY textutil] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/textutil/repeat.man ================================================================== --- modules/textutil/repeat.man +++ modules/textutil/repeat.man @@ -40,7 +40,7 @@ A convenience command. Returns a string of [arg num] spaces. [list_end] [vset CATEGORY textutil] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/textutil/tabify.man ================================================================== --- modules/textutil/tabify.man +++ modules/textutil/tabify.man @@ -66,7 +66,7 @@ space, but not the other way around. [list_end] [vset CATEGORY textutil] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/textutil/textutil.man ================================================================== --- modules/textutil/textutil.man +++ modules/textutil/textutil.man @@ -382,7 +382,7 @@ own longest common prefix. [list_end] [vset CATEGORY textutil] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/textutil/textutil_split.man ================================================================== --- modules/textutil/textutil_split.man +++ modules/textutil/textutil_split.man @@ -50,7 +50,7 @@ The regular expression [arg regexp] defaults to "[lb]\\t \\r\\n[rb]+". [list_end] [vset CATEGORY textutil] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/textutil/textutil_string.man ================================================================== --- modules/textutil/textutil_string.man +++ modules/textutil/textutil_string.man @@ -67,7 +67,7 @@ own longest common prefix. [list_end] [vset CATEGORY textutil] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/textutil/trim.man ================================================================== --- modules/textutil/trim.man +++ modules/textutil/trim.man @@ -69,7 +69,7 @@ string is returned as the result of the command. [list_end] [vset CATEGORY textutil] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/tie/tie.man ================================================================== --- modules/tie/tie.man +++ modules/tie/tie.man @@ -529,7 +529,7 @@ $a($idx) ds getv idx ----------- ----------- }] [vset CATEGORY tie] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/tie/tie_std.man ================================================================== --- modules/tie/tie_std.man +++ modules/tie/tie_std.man @@ -29,7 +29,7 @@ They are automatically loaded and registered by [package tie] when it itself is requested, and as such there is no need to request them on their own, although it is possible to do so. [vset CATEGORY tie] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/tiff/tiff.man ================================================================== --- modules/tiff/tiff.man +++ modules/tiff/tiff.man @@ -168,7 +168,7 @@ [enum] Reading limited to uncompressed 8 bit rgb and 8 bit palletized images [enum] Writing limited to uncompressed 8 bit rgb [list_end] [vset CATEGORY tiff] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/tool/meta.man ================================================================== --- modules/tool/meta.man +++ modules/tool/meta.man @@ -159,7 +159,7 @@ [section AUTHORS] Donal Fellows, Andreas Kupries [vset CATEGORY oo::util] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/tool/tool.man ================================================================== --- modules/tool/tool.man +++ modules/tool/tool.man @@ -228,9 +228,9 @@ [section AUTHORS] Sean Woods [vset CATEGORY tcloo] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/tool/tool_dict_ensemble.man ================================================================== --- modules/tool/tool_dict_ensemble.man +++ modules/tool/tool_dict_ensemble.man @@ -1,34 +1,34 @@ -[comment {-*- tcl -*- doctools manpage}] -[manpage_begin tool::dict_ensemble n 0.4.2] -[keywords TOOL] -[copyright {2015 Sean Woods }] -[moddesc {Standardized OO Framework for development}] -[titledesc {Dictionary Tools}] -[category Utility] -[keywords TclOO] -[keywords TOOL] -[require tool [opt 0.4.2]] -[description] -[para] -The [cmd dict_ensemble] command is a keyword added by [package tool]. It defines -a public variable (stored as a dict), and an access function to manipulated and -access the values stored in that dict. -[list_begin definitions] - -[call [emph object] [arg ensemble] [cmd add] [arg field]]] [arg value] [arg {value ...}]] - -Adds elements to a list maintained with the [arg field] leaf of the dict maintained -my this ensemble. - - -Declares a variable [arg name] which will be initialized as an array, populated with [arg contents] for objects of this class, as well as any -objects for classes which are descendents of this class. - -[list_end] - -[section AUTHORS] -Sean Woods - -[vset CATEGORY tool] -[include ../doctools2base/include/feedback.inc] +[comment {-*- tcl -*- doctools manpage}] +[manpage_begin tool::dict_ensemble n 0.4.2] +[keywords TOOL] +[copyright {2015 Sean Woods }] +[moddesc {Standardized OO Framework for development}] +[titledesc {Dictionary Tools}] +[category Utility] +[keywords TclOO] +[keywords TOOL] +[require tool [opt 0.4.2]] +[description] +[para] +The [cmd dict_ensemble] command is a keyword added by [package tool]. It defines +a public variable (stored as a dict), and an access function to manipulated and +access the values stored in that dict. +[list_begin definitions] + +[call [emph object] [arg ensemble] [cmd add] [arg field]]] [arg value] [arg {value ...}]] + +Adds elements to a list maintained with the [arg field] leaf of the dict maintained +my this ensemble. + + +Declares a variable [arg name] which will be initialized as an array, populated with [arg contents] for objects of this class, as well as any +objects for classes which are descendents of this class. + +[list_end] + +[section AUTHORS] +Sean Woods + +[vset CATEGORY tool] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/transfer/connect.man ================================================================== --- modules/transfer/connect.man +++ modules/transfer/connect.man @@ -162,7 +162,7 @@ [vset OBJCREATE {transfer::connect C}] [include include/secure.inc] [vset CATEGORY transfer] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/transfer/copyops.man ================================================================== --- modules/transfer/copyops.man +++ modules/transfer/copyops.man @@ -157,7 +157,7 @@ [list_end][comment options] [list_end][comment definitions/api] [vset CATEGORY transfer] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/transfer/ddest.man ================================================================== --- modules/transfer/ddest.man +++ modules/transfer/ddest.man @@ -116,7 +116,7 @@ [list_begin options] [include include/ddest_options.inc] [list_end] [vset CATEGORY transfer] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/transfer/dsource.man ================================================================== --- modules/transfer/dsource.man +++ modules/transfer/dsource.man @@ -148,7 +148,7 @@ [list_begin options] [include include/dsource_options.inc] [list_end] [vset CATEGORY transfer] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/transfer/receiver.man ================================================================== --- modules/transfer/receiver.man +++ modules/transfer/receiver.man @@ -176,11 +176,11 @@ [vset OBJCREATE {transfer::receiver R}] [include include/secure.inc] [vset CATEGORY transfer] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [comment { This option specifies the command to invoke when the transmission of the information in the data source has been completed. The arguments given to this command are the same as given to the completion callback Index: modules/transfer/tqueue.man ================================================================== --- modules/transfer/tqueue.man +++ modules/transfer/tqueue.man @@ -168,7 +168,7 @@ additional data structure which keeps track of outstanding results as they may come back in a different order than the requests from the client, and releases them to the actual queue in the proper order. [vset CATEGORY transfer] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/transfer/transmitter.man ================================================================== --- modules/transfer/transmitter.man +++ modules/transfer/transmitter.man @@ -178,7 +178,7 @@ [vset OBJCREATE {transfer::transmitter T}] [include include/secure.inc] [vset CATEGORY transfer] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/treeql/treeql.man ================================================================== --- modules/treeql/treeql.man +++ modules/treeql/treeql.man @@ -813,7 +813,7 @@ this package there. [list_end] [vset CATEGORY treeql] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/try/tcllib_throw.man ================================================================== --- modules/try/tcllib_throw.man +++ modules/try/tcllib_throw.man @@ -34,7 +34,7 @@ [para][example_begin] [cmd throw] {MYERROR CODE} "My error message" [example_end] [vset CATEGORY try] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/try/tcllib_try.man ================================================================== --- modules/try/tcllib_try.man +++ modules/try/tcllib_try.man @@ -117,7 +117,7 @@ puts "failed to open /some/file/name: it doesn't exist" } [example_end] [vset CATEGORY try] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/udpcluster/udpcluster.man ================================================================== --- modules/udpcluster/udpcluster.man +++ modules/udpcluster/udpcluster.man @@ -53,7 +53,7 @@ [para] This tool was originally known as nns::cluster, but as development progressed, it was clear that it wasn't interacting with any of the other facilities in NNS. [vset CATEGORY nameserv] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/uev/uevent.man ================================================================== --- modules/uev/uevent.man +++ modules/uev/uevent.man @@ -190,7 +190,7 @@ [comment ============================================================] [list_end] [vset CATEGORY uevent] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/uev/uevent_onidle.man ================================================================== --- modules/uev/uevent_onidle.man +++ modules/uev/uevent_onidle.man @@ -58,7 +58,7 @@ Examples of this type of deferal are buried in the (C-level) implementations all the Tk widgets, defering geometry calculations and window redraw activity in this manner. [vset CATEGORY uevent] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/units/units.man ================================================================== --- modules/units/units.man +++ modules/units/units.man @@ -386,7 +386,7 @@ [section "AUTHORS"] Robert W. Techentin [vset CATEGORY units] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/uri/uri.man ================================================================== --- modules/uri/uri.man +++ modules/uri/uri.man @@ -387,7 +387,7 @@ Original code (regular expressions) by Andreas Kupries. Modularisation by Steve Ball, also the split/join/resolve functionality. RFC 3986 conformance by Keith Nash. [vset CATEGORY uri] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/uri/urn-scheme.man ================================================================== --- modules/uri/urn-scheme.man +++ modules/uri/urn-scheme.man @@ -35,7 +35,7 @@ characters, and returns the modified urls as its result. [list_end] [vset CATEGORY uri] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/uuid/uuid.man ================================================================== --- modules/uuid/uuid.man +++ modules/uuid/uuid.man @@ -49,7 +49,7 @@ ([uri http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt]) [list_end] [vset CATEGORY uuid] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/valtype/include/vtype.inc ================================================================== --- modules/valtype/include/vtype.inc +++ modules/valtype/include/vtype.inc @@ -96,7 +96,7 @@ [include [vset CODES].inc] [list_end] [vset CATEGORY valtype] -[include ../../doctools2base/include/feedback.inc] +[include ../../common-text/feedback.inc] [manpage_end] Index: modules/valtype/valtype_common.man ================================================================== --- modules/valtype/valtype_common.man +++ modules/valtype/valtype_common.man @@ -104,7 +104,7 @@ [include include/c_lenpfx.inc] [list_end] [vset CATEGORY valtype] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_base/ChangeLog ================================================================== --- modules/virtchannel_base/ChangeLog +++ modules/virtchannel_base/ChangeLog @@ -1,5 +1,9 @@ +2019-03-12 Aldo Buratti + + * cat.tcl - BUGFIX in event-handling . Version bumped to 1.0.3 + * 2013-12-17 Andreas Kupries * randseed.man: Fixed package name. 2013-11-22 Andreas Kupries Index: modules/virtchannel_base/cat.man ================================================================== --- modules/virtchannel_base/cat.man +++ modules/virtchannel_base/cat.man @@ -1,7 +1,8 @@ [comment {-*- tcl -*- doctools manpage}] -[manpage_begin tcl::chan::cat n 1] +[vset Version 1.0.3] +[manpage_begin tcl::chan::cat n [vset Version]] [keywords {concatenation channel}] [keywords {reflected channel}] [keywords {tip 219}] [keywords {virtual channel}] [copyright {2011 Andreas Kupries }] @@ -9,11 +10,11 @@ [category Channels] [titledesc {Concatenation channel}] [require Tcl 8.5] [require TclOO] [require tcl::chan::core [opt 1]] -[require tcl::chan::cat [opt 1]] +[require tcl::chan::cat [opt [vset Version]]] [description] [para] The [package tcl::chan::cat] package provides a command creating concatenation channels. These are non-seekable channels owning a list @@ -41,7 +42,7 @@ channels, and returns its handle. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_base/cat.tcl ================================================================== --- modules/virtchannel_base/cat.tcl +++ modules/virtchannel_base/cat.tcl @@ -1,15 +1,15 @@ # -*- tcl -*- # # ## ### ##### ######## ############# -# (C) 2011 Andreas Kupries +# (C) 2011,2019 Andreas Kupries # Facade concatenating the contents of the channels it was constructed # with. Owns the sub-ordinate channels and closes them on exhaustion and/or # when closed itself. # @@ Meta Begin -# Package tcl::chan::cat 1.0.1 +# Package tcl::chan::cat 1.0.3 # Meta as::author {Andreas Kupries} # Meta as::copyright 2011 # Meta as::license BSD # Meta description Facade concatenating the contents of the channels it # Meta description was constructed with. Owns the sub-ordinate channels @@ -41,14 +41,13 @@ # it will not be timer-driven. We propagate anything related to # events to catin and catout instead and let them handle things. constructor {args} { set channels $args - # Disable encoding and translation processing in the wrapped channels. + # Disable translation (and hence encoding) in the wrapped channels. # This will happen in our generic layer instead. foreach c $channels { - fconfigure $c -translation binary fconfigure $c -translation binary } set delay 10 set watching 0 return @@ -68,33 +67,31 @@ # Activate event handling. Either drive an eof home via # timers, or activate things in the foremost sub-ordinate. set watching 1 if {![llength $channels]} { - set timer [after $delay \ - [namespace code [list my Post $c]]] + set timer [after $delay [namespace code [list my Post $c]]] } else { - set c [lindex $channels 0] - fileevent readable $c [list chan postevent $c read] + chan event [lindex $channels 0] readable [list chan postevent $c read] } } else { - # Stop events. Kill timer, or disable in the foremost - # sub-ordinate. + # Stop events. Either kill timer, or disable in the + # foremost sub-ordinate. set watching 0 if {![llength $channels]} { catch { after cancel $timer } } else { - fileevent readable [lindex $channels 0] {} + chan event [lindex $channels 0] readable {} } } return } method read {c n} { if {![llength $channels]} { - # Actually should be EOF signal. + # This signals EOF higher up. return {} } set buf {} while {([string length $buf] < $n) && @@ -106,34 +103,33 @@ if {[eof $in]} { close $in set channels [lrange $channels 1 end] - # The close above also killed any fileevent handling - # we might have attached to this channel. We may have - # to update the settings (i.e. move to next channel, - # or to timer-based, to drive the eof home). + # The close of the exhausted subordinate killed any + # fileevent handling we may have had attached to this + # channel. Update the settings (i.e. move to the next + # subordinate, or to timer-based, to drive the eof + # home). if {$watching} { my watch $c read } } } - if {$buf eq {}} { - return -code error EAGAIN - } - + # When `buf` is empty, all channels have been exhausted and + # closed, therefore returning this empty string will cause an + # EOF higher up. return $buf } method Post {c} { - set timer [after $delay \ - [namespace code [list my Post $c]]] + set timer [after $delay [namespace code [list my Post $c]]] chan postevent $c read return } } # # ## ### ##### ######## ############# -package provide tcl::chan::cat 1.0.2 +package provide tcl::chan::cat 1.0.3 return ADDED modules/virtchannel_base/cat.test Index: modules/virtchannel_base/cat.test ================================================================== --- /dev/null +++ modules/virtchannel_base/cat.test @@ -0,0 +1,69 @@ +#- - -- --- ----- -------- ------------- --------------------- +# cat.test -*- tcl -*- +# (C) 2019 Andreas Kupries. BSD licensed. +#- - -- --- ----- -------- ------------- --------------------- + +source [file join \ + [file dirname [file dirname [file join [pwd] [info script]]]] \ + devtools testutilities.tcl] + +testsNeedTcl 8.5 +testsNeedTcltest 2.0 +testsNeed TclOO 1 + +support { + use virtchannel_core/core.tcl tcl::chan::core + use virtchannel_core/events.tcl tcl::chan::events + useLocal string.tcl tcl::chan::string +} +testing { + useLocal cat.tcl tcl::chan::cat +} + +#- - -- --- ----- -------- ------------- --------------------- +## No wrong#args, allowed to zero and up + +#- - -- --- ----- -------- ------------- --------------------- + +test tcl-chan-cat-2.0 {tell, nothing} -setup { + set c [tcl::chan::cat] +} -body { + tell $c +} -cleanup { + close $c + unset c +} -result -1 + +test tcl-chan-cat-2.1 {ticket 1975182bdd - file events} -setup { + # setup a cat'enated channel + set fa [tcl::chan::string "ABCDE..XYZ"] + set fb [tcl::chan::string "0123456789"] + set ch [tcl::chan::cat $fa $fb] +} -body { + set r {} + chan event $ch readable { + if { [eof $ch] } { + set done . + } else { + lappend r [read $ch 4] + } + } + vwait done + set r +} -cleanup { + close $ch + unset ch fa fb r +} -result {ABCD E..X YZ01 2345 6789 {}} + +#- - -- --- ----- -------- ------------- --------------------- +# Explicit cleanup of loaded support classes. + +rename tcl::chan::events {} +rename tcl::chan::core {} +testsuiteCleanup +return + +# Local Variables: +# mode: tcl +# indent-tabs-mode: nil +# End: Index: modules/virtchannel_base/facade.man ================================================================== --- modules/virtchannel_base/facade.man +++ modules/virtchannel_base/facade.man @@ -67,7 +67,7 @@ channel [arg chan], and returns its handle. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_base/halfpipe.man ================================================================== --- modules/virtchannel_base/halfpipe.man +++ modules/virtchannel_base/halfpipe.man @@ -75,7 +75,7 @@ A single argument is supplied, the handle of the channel. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_base/nullzero.man ================================================================== --- modules/virtchannel_base/nullzero.man +++ modules/virtchannel_base/nullzero.man @@ -38,7 +38,7 @@ This command creates a new nullzero channel and returns its handle. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_base/pkgIndex.tcl ================================================================== --- modules/virtchannel_base/pkgIndex.tcl +++ modules/virtchannel_base/pkgIndex.tcl @@ -1,8 +1,8 @@ if {![package vsatisfies [package provide Tcl] 8.5]} {return} -package ifneeded tcl::chan::cat 1.0.2 [list source [file join $dir cat.tcl]] +package ifneeded tcl::chan::cat 1.0.3 [list source [file join $dir cat.tcl]] package ifneeded tcl::chan::facade 1.0.1 [list source [file join $dir facade.tcl]] package ifneeded tcl::chan::fifo 1 [list source [file join $dir fifo.tcl]] package ifneeded tcl::chan::fifo2 1 [list source [file join $dir fifo2.tcl]] package ifneeded tcl::chan::halfpipe 1 [list source [file join $dir halfpipe.tcl]] package ifneeded tcl::chan::memchan 1.0.4 [list source [file join $dir memchan.tcl]] Index: modules/virtchannel_base/randseed.man ================================================================== --- modules/virtchannel_base/randseed.man +++ modules/virtchannel_base/randseed.man @@ -37,7 +37,7 @@ length the shorter of the two is padded with 0s before merging. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_base/std.man ================================================================== --- modules/virtchannel_base/std.man +++ modules/virtchannel_base/std.man @@ -37,7 +37,7 @@ future calls simply return this handle. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_base/tcllib_fifo.man ================================================================== --- modules/virtchannel_base/tcllib_fifo.man +++ modules/virtchannel_base/tcllib_fifo.man @@ -37,7 +37,7 @@ This command creates a new fifo channel and returns its handle. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_base/tcllib_fifo2.man ================================================================== --- modules/virtchannel_base/tcllib_fifo2.man +++ modules/virtchannel_base/tcllib_fifo2.man @@ -44,7 +44,7 @@ their handles, as a list containing two elements. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_base/tcllib_memchan.man ================================================================== --- modules/virtchannel_base/tcllib_memchan.man +++ modules/virtchannel_base/tcllib_memchan.man @@ -39,7 +39,7 @@ This command creates a new memchan channel and returns its handle. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_base/tcllib_null.man ================================================================== --- modules/virtchannel_base/tcllib_null.man +++ modules/virtchannel_base/tcllib_null.man @@ -39,7 +39,7 @@ This command creates a new null channel and returns its handle. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_base/tcllib_random.man ================================================================== --- modules/virtchannel_base/tcllib_random.man +++ modules/virtchannel_base/tcllib_random.man @@ -40,7 +40,7 @@ internal feedback shift register of the generator. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_base/tcllib_string.man ================================================================== --- modules/virtchannel_base/tcllib_string.man +++ modules/virtchannel_base/tcllib_string.man @@ -40,7 +40,7 @@ channel provides random read-only access to the [arg content] string. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_base/tcllib_variable.man ================================================================== --- modules/virtchannel_base/tcllib_variable.man +++ modules/virtchannel_base/tcllib_variable.man @@ -41,7 +41,7 @@ variable [arg varname]. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_base/tcllib_zero.man ================================================================== --- modules/virtchannel_base/tcllib_zero.man +++ modules/virtchannel_base/tcllib_zero.man @@ -39,7 +39,7 @@ This command creates a new zero channel and returns its handle. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_base/textwindow.man ================================================================== --- modules/virtchannel_base/textwindow.man +++ modules/virtchannel_base/textwindow.man @@ -33,7 +33,7 @@ Data written to this channel will appear in the associated [arg widget]. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_core/core.man ================================================================== --- modules/virtchannel_core/core.man +++ modules/virtchannel_core/core.man @@ -66,7 +66,7 @@ the assumption that the channel is being destroyed by Tcl. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_core/events.man ================================================================== --- modules/virtchannel_core/events.man +++ modules/virtchannel_core/events.man @@ -73,7 +73,7 @@ accordingly. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_core/transformcore.man ================================================================== --- modules/virtchannel_core/transformcore.man +++ modules/virtchannel_core/transformcore.man @@ -66,7 +66,7 @@ the assumption that the channel and transform are being destroyed by Tcl. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_transform/adler32.man ================================================================== --- modules/virtchannel_transform/adler32.man +++ modules/virtchannel_transform/adler32.man @@ -64,7 +64,7 @@ [list_end] [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_transform/hex.man ================================================================== --- modules/virtchannel_transform/hex.man +++ modules/virtchannel_transform/hex.man @@ -37,7 +37,7 @@ [arg chan] and returns its handle. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_transform/identity.man ================================================================== --- modules/virtchannel_transform/identity.man +++ modules/virtchannel_transform/identity.man @@ -44,7 +44,7 @@ [arg chan] and returns its handle. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_transform/limitsize.man ================================================================== --- modules/virtchannel_transform/limitsize.man +++ modules/virtchannel_transform/limitsize.man @@ -40,7 +40,7 @@ popping the transformation clears the EOF it generated as well. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_transform/observe.man ================================================================== --- modules/virtchannel_transform/observe.man +++ modules/virtchannel_transform/observe.man @@ -44,7 +44,7 @@ [arg logw] are there the data is copied to. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_transform/rot.man ================================================================== --- modules/virtchannel_transform/rot.man +++ modules/virtchannel_transform/rot.man @@ -51,7 +51,7 @@ through unchanged. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_transform/spacer.man ================================================================== --- modules/virtchannel_transform/spacer.man +++ modules/virtchannel_transform/spacer.man @@ -39,7 +39,7 @@ defaults to a single space character (ASCII 32). [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_transform/tcllib_zlib.man ================================================================== --- modules/virtchannel_transform/tcllib_zlib.man +++ modules/virtchannel_transform/tcllib_zlib.man @@ -40,7 +40,7 @@ compression, from [const 0] to [const 9], and defaults to [const 4]. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_transform/vt_base64.man ================================================================== --- modules/virtchannel_transform/vt_base64.man +++ modules/virtchannel_transform/vt_base64.man @@ -38,7 +38,7 @@ [arg chan] and returns its handle. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_transform/vt_counter.man ================================================================== --- modules/virtchannel_transform/vt_counter.man +++ modules/virtchannel_transform/vt_counter.man @@ -62,7 +62,7 @@ [list_end] [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_transform/vt_crc32.man ================================================================== --- modules/virtchannel_transform/vt_crc32.man +++ modules/virtchannel_transform/vt_crc32.man @@ -64,7 +64,7 @@ [list_end] [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/virtchannel_transform/vt_otp.man ================================================================== --- modules/virtchannel_transform/vt_otp.man +++ modules/virtchannel_transform/vt_otp.man @@ -47,7 +47,7 @@ the channel. [list_end] [vset CATEGORY virtchannel] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/websocket/websocket.man ================================================================== --- modules/websocket/websocket.man +++ modules/websocket/websocket.man @@ -379,7 +379,7 @@ [example_end] [include ../common-text/tls-security-notes.inc] [vset CATEGORY websocket] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/wip/wip.man ================================================================== --- modules/wip/wip.man +++ modules/wip/wip.man @@ -378,7 +378,7 @@ [section EXAMPLES] No examples yet. [vset CATEGORY wip] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/yaml/huddle.man ================================================================== --- modules/yaml/huddle.man +++ modules/yaml/huddle.man @@ -552,7 +552,7 @@ [para] now printing. [vset CATEGORY huddle] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/yaml/yaml.man ================================================================== --- modules/yaml/yaml.man +++ modules/yaml/yaml.man @@ -183,7 +183,7 @@ [para] Not enough character set of line feeds. Please use only "\n" as line breaks. [vset CATEGORY yaml] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/zip/decode.man ================================================================== --- modules/zip/decode.man +++ modules/zip/decode.man @@ -129,7 +129,7 @@ [para] The result of the command is the empty string. [list_end] [vset CATEGORY zipfile] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/zip/encode.man ================================================================== --- modules/zip/encode.man +++ modules/zip/encode.man @@ -86,7 +86,7 @@ a specific order of files in the archive, for example [file .epub]. [list_end] [vset CATEGORY zipfile] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/zip/mkzip.man ================================================================== --- modules/zip/mkzip.man +++ modules/zip/mkzip.man @@ -1,6 +1,6 @@ -[vset ZIP_mkzip_VERSION 1.2] +[vset ZIP_mkzip_VERSION 1.2.1] [comment {-*- tcl -*- doctools manpage}] [manpage_begin zipfile::mkzip n [vset ZIP_mkzip_VERSION]] [keywords decompression zip] [copyright {2009 Pat Thoyts}] [moddesc {Zip archive creation}] @@ -98,7 +98,7 @@ [list_end] [list_end] [vset CATEGORY zipfile] -[include ../doctools2base/include/feedback.inc] +[include ../common-text/feedback.inc] [manpage_end] Index: modules/zip/mkzip.tcl ================================================================== --- modules/zip/mkzip.tcl +++ modules/zip/mkzip.tcl @@ -7,11 +7,11 @@ # or a zipfile using mkzip filename.zip -directory dirname -exclude "*~" # ## BSD License ## # Package providing commands for the generation of a zip archive. -# version 1.2 +# version 1.2.1 package require Tcl 8.6 namespace eval ::zipfile {} namespace eval ::zipfile::decode {} @@ -62,11 +62,11 @@ # eg: walk library {CVS/* *~ .#*} to exclude CVS and emacs cruft. # proc ::zipfile::mkzip::walk {base {excludes ""} {match *} {path {}}} { set result {} set imatch [file join $path $match] - set files [glob -nocomplain -tails -types f -directory $base $imatch] + set files [glob -nocomplain -tails -types f -directory $base -- $imatch] foreach file $files { set excluded 0 foreach glob $excludes { if {[string match $glob $file]} { set excluded 1 @@ -73,11 +73,11 @@ break } } if {!$excluded} {lappend result $file} } - foreach dir [glob -nocomplain -tails -types d -directory $base $imatch] { + foreach dir [glob -nocomplain -tails -types d -directory $base -- $imatch] { set subdir [walk $base $excludes $match $dir] if {[llength $subdir]>0} { set result [concat $result [list $dir] $subdir] } } @@ -277,6 +277,6 @@ return } # ### ### ### ######### ######### ######### ## Ready -package provide zipfile::mkzip 1.2 +package provide zipfile::mkzip 1.2.1 ADDED modules/zip/mkzip.test Index: modules/zip/mkzip.test ================================================================== --- /dev/null +++ modules/zip/mkzip.test @@ -0,0 +1,40 @@ +# mkzip.test - Copyright (C) 2019 Andreas Kupries + +# ------------------------------------------------------------------------- + +source [file join \ + [file dirname [file dirname [file join [pwd] [info script]]]] \ + devtools testutilities.tcl] + +testsNeedTcl 8.6 +testsNeedTcltest 2 + +testing { + useLocal mkzip.tcl zipfile::mkzip +} + +# ------------------------------------------------------------------------- + +test zipfile-mkzip-mkzip-1.0 {mkzip, wrong args, not enough} -body { + zipfile::mkzip::mkzip +} -returnCodes error -result {wrong # args: should be "zipfile::mkzip::mkzip filename ?arg ...?"} + +test zipfile-mkzip-mkzip-2.0 {mkzip, tkt b9725d990b} -setup { + tcltest::makeDirectory foo + tcltest::makeDirectory foo/-1 +} -cleanup { + tcltest::removeDirectory foo + file delete foo.zip +} -body { + zipfile::mkzip::mkzip foo.zip -directory foo +} -result {} + +# ------------------------------------------------------------------------- + +testsuiteCleanup + +# ------------------------------------------------------------------------- +# Local Variables: +# mode: tcl +# indent-tabs-mode: nil +# End: Index: modules/zip/pkgIndex.tcl ================================================================== --- modules/zip/pkgIndex.tcl +++ modules/zip/pkgIndex.tcl @@ -3,6 +3,6 @@ package ifneeded zipfile::decode 0.7.1 [list source [file join $dir decode.tcl]] package ifneeded zipfile::encode 0.4 [list source [file join $dir encode.tcl]] if {![package vsatisfies [package provide Tcl] 8.6]} {return} -package ifneeded zipfile::mkzip 1.2 [list source [file join $dir mkzip.tcl]] +package ifneeded zipfile::mkzip 1.2.1 [list source [file join $dir mkzip.tcl]] Index: support/devel/sak/doc/kwic.txt ================================================================== --- support/devel/sak/doc/kwic.txt +++ support/devel/sak/doc/kwic.txt @@ -1348,21 +1348,21 @@ [manpage modules/htmlparse/htmlparse.man htmlparse] [manpage modules/javascript/javascript.man javascript] [manpage modules/ncgi/ncgi.man ncgi] [key http] [manpage modules/http/autoproxy.man autoproxy] +[manpage modules/httpd/httpd.man httpd] [manpage modules/map/map_geocode_nominatim.man map::geocode::nominatim] [manpage modules/map/map_slippy_fetcher.man map::slippy::fetcher] -[manpage modules/httpd/httpd.man tool] [manpage modules/uri/uri.man uri] [manpage modules/websocket/websocket.man websocket] [key httpd] -[manpage modules/httpd/httpd.man tool] +[manpage modules/httpd/httpd.man httpd] [key https] [manpage modules/uri/uri.man uri] [key httpserver] -[manpage modules/httpd/httpd.man tool] +[manpage modules/httpd/httpd.man httpd] [key huddle] [manpage modules/yaml/huddle.man huddle] [manpage modules/yaml/yaml.man yaml] [key {human readable}] [manpage modules/bench/bench_read.man bench::in] @@ -1874,12 +1874,13 @@ [manpage modules/math/trig.man math::trig] [manpage modules/simulation/annealing.man simulation::annealing] [manpage modules/simulation/montecarlo.man simulation::montecarlo] [manpage modules/simulation/simulation_random.man simulation::random] [key mathematics] -[manpage modules/math/fourier.man math::fourier] -[manpage modules/math/statistics.man math::statistics] +[manpage modules/math/fourier.man math::fourier] +[manpage modules/math/quasirandom.man math::quasirandom] +[manpage modules/math/statistics.man math::statistics] [key matrices] [manpage modules/math/linalg.man math::linearalgebra] [key matrix] [manpage modules/csv/csv.man csv] [manpage modules/math/linalg.man math::linearalgebra] @@ -2108,10 +2109,12 @@ [manpage modules/processman/processman.man processman] [key on-idle] [manpage modules/uev/uevent_onidle.man uevent::onidle] [key {one time pad}] [manpage modules/virtchannel_transform/vt_otp.man tcl::transform::otp] +[key oo] +[manpage modules/clay/clay.man clay] [key optimization] [manpage modules/math/optimize.man math::optimize] [manpage modules/simulation/annealing.man simulation::annealing] [key {ordered list}] [manpage modules/struct/prioqueue.man struct::prioqueue] @@ -2536,10 +2539,12 @@ [manpage modules/pt/pt_from_api.man pt_import_api] [manpage modules/pt/pt_introduction.man pt_introduction] [manpage modules/pt/pt_parse_peg.man pt_parse_peg] [manpage modules/pt/pt_parser_api.man pt_parser_api] [manpage modules/pt/pt_peg_op.man pt_peg_op] +[key quasi-random] +[manpage modules/math/quasirandom.man math::quasirandom] [key queue] [manpage modules/csv/csv.man csv] [manpage modules/htmlparse/htmlparse.man htmlparse] [manpage modules/struct/stack.man struct::stack] [manpage modules/transfer/tqueue.man transfer::copy::queue] @@ -2946,12 +2951,12 @@ [manpage modules/udpcluster/udpcluster.man udpcluster] [key service] [manpage modules/log/logger.man logger] [key services] [manpage modules/ftpd/ftpd.man ftpd] +[manpage modules/httpd/httpd.man httpd] [manpage modules/smtpd/smtpd.man smtpd] -[manpage modules/httpd/httpd.man tool] [key set] [manpage modules/struct/queue.man struct::queue] [manpage modules/struct/struct_set.man struct::set] [key sha1] [manpage modules/sha1/sha1.man sha1] @@ -3194,15 +3199,16 @@ [manpage modules/doctools2toc/toc_container.man doctools::toc] [manpage modules/doctools2toc/toc_export.man doctools::toc::export] [key tcllib] [manpage modules/csv/csv.man csv] [key TclOO] +[manpage modules/clay/clay.man clay] +[manpage modules/httpd/httpd.man httpd] [manpage modules/ooutil/ooutil.man oo::util] [manpage modules/tool/meta.man oo::util] [manpage modules/oometa/oometa.man oometa] [manpage modules/tool/tool.man tool] -[manpage modules/httpd/httpd.man tool] [manpage modules/tool/tool_dict_ensemble.man tool::dict_ensemble] [key TCLPARAM] [manpage modules/pt/pt_peg_to_tclparam.man pt::peg::to::tclparam] [key TDPL] [manpage modules/grammar_peg/peg.man grammar::peg] @@ -3762,11 +3768,11 @@ [manpage modules/doctools2toc/toc_export_wiki.man doctools::toc::export::wiki] [key word] [manpage modules/doctools2base/tcl_parse.man doctools::tcl::parse] [manpage modules/wip/wip.man wip] [key WWW] -[manpage modules/httpd/httpd.man tool] +[manpage modules/httpd/httpd.man httpd] [key www] [manpage modules/uri/uri.man uri] [key x.208] [manpage modules/asn/asn.man asn] [key x.209] Index: support/devel/sak/doc/manpages.txt ================================================================== --- support/devel/sak/doc/manpages.txt +++ support/devel/sak/doc/manpages.txt @@ -25,10 +25,11 @@ modules/bench/bench_wcsv.man modules/bench/bench_wtext.man modules/bibtex/bibtex.man modules/blowfish/blowfish.man modules/cache/async.man +modules/clay/clay.man modules/clock/iso8601.man modules/clock/rfc2822.man modules/cmdline/cmdline.man modules/comm/comm.man modules/comm/comm_wire.man @@ -121,10 +122,11 @@ modules/doctools2toc/toc_structure.man modules/dtplite/pkg_dtplite.man modules/fileutil/fileutil.man modules/fileutil/multi.man modules/fileutil/multiop.man +modules/fileutil/paths.man modules/fileutil/traverse.man modules/ftp/ftp.man modules/ftp/ftp_geturl.man modules/ftpd/ftpd.man modules/fumagic/cfront.man @@ -196,10 +198,11 @@ modules/math/numtheory.man modules/math/optimize.man modules/math/pca.man modules/math/polynomials.man modules/math/qcomplex.man +modules/math/quasirandom.man modules/math/rational_funcs.man modules/math/roman.man modules/math/romberg.man modules/math/special.man modules/math/statistics.man @@ -324,10 +327,11 @@ modules/struct/queue.man modules/struct/record.man modules/struct/skiplist.man modules/struct/stack.man modules/struct/struct_list.man +modules/struct/struct_map.man modules/struct/struct_set.man modules/struct/struct_tree.man modules/struct/struct_tree1.man modules/tar/tar.man modules/tepam/tepam_argument_dialogbox.man Index: support/devel/sak/doc/toc.txt ================================================================== --- support/devel/sak/doc/toc.txt +++ support/devel/sak/doc/toc.txt @@ -209,10 +209,11 @@ [item modules/math/linalg.man math::linearalgebra {Linear Algebra}] [item modules/math/numtheory.man math::numtheory {Number Theory}] [item modules/math/optimize.man math::optimize {Optimisation routines}] [item modules/math/pca.man math::PCA {Package for Principal Component Analysis}] [item modules/math/polynomials.man math::polynomials {Polynomial functions}] +[item modules/math/quasirandom.man math::quasirandom {Quasi-random points for integration and Monte Carlo type methods}] [item modules/math/rational_funcs.man math::rationalfunctions {Polynomial functions}] [item modules/math/roman.man math::roman {Tools for creating and manipulating roman numerals}] [item modules/math/special.man math::special {Special mathematical functions}] [item modules/math/statistics.man math::statistics {Basic statistical functions and procedures}] [item modules/math/trig.man math::trig {Trigonometric anf hyperbolic functions}] @@ -226,11 +227,13 @@ [item modules/bee/bee.man bee {BitTorrent Serialization Format Encoder/Decoder}] [item modules/dns/tcllib_dns.man dns {Tcl Domain Name Service Client}] [item modules/ftp/ftp.man ftp {Client-side tcl implementation of the ftp protocol}] [item modules/ftp/ftp_geturl.man ftp::geturl {Uri handler for ftp urls}] [item modules/ftpd/ftpd.man ftpd {Tcl FTP server implementation}] +[item modules/httpd/httpd.man httpd {A TclOO and coroutine based web server}] [item modules/ident/ident.man ident {Ident protocol client}] +[item modules/imap4/imap4.man imap4 {imap client-side tcl implementation of imap protocol}] [item modules/irc/irc.man irc {Create IRC connection and interface.}] [item modules/ldap/ldap.man ldap {LDAP client}] [item modules/ldap/ldapx.man ldapx {LDAP extended object interface}] [item modules/nns/nns_client.man nameserv {Name service facility, Client}] [item modules/nns/nns_auto.man nameserv::auto {Name service facility, Client Extension}] @@ -256,11 +259,10 @@ [item modules/sasl/scram.man SASL::SCRAM {Implementation of SASL SCRAM mechanism for Tcl}] [item modules/sasl/gtoken.man SASL::XGoogleToken {Implementation of SASL NTLM mechanism for Tcl}] [item modules/mime/smtp.man smtp {Client-side tcl implementation of the smtp protocol}] [item modules/smtpd/smtpd.man smtpd {Tcl SMTP server implementation}] [item modules/dns/tcllib_ip.man tcllib_ip {IPv4 and IPv6 address manipulation}] -[item modules/httpd/httpd.man tool {A TclOO and coroutine based web server}] [item modules/udpcluster/udpcluster.man udpcluster {UDP Peer-to-Peer cluster}] [item modules/uri/uri.man uri {URI utilities}] [item modules/uri/urn-scheme.man uri_urn {URI utilities, URN scheme}] [item modules/websocket/websocket.man websocket {Tcl implementation of the websocket protocol}] [division_end] @@ -322,10 +324,11 @@ [division_start {Procedures, arguments, parameters, options}] [item modules/tepam/tepam_introduction.man tepam {An introduction into TEPAM, Tcl's Enhanced Procedure and Argument Manager}] [item modules/tepam/tepam_procedure.man tepam::procedure {TEPAM procedure, reference manual}] [division_end] [division_start {Programming tools}] +[item modules/clay/clay.man clay {A minimalist framework for large scale OO Projects}] [item modules/cmdline/cmdline.man cmdline {Procedures to process command lines and options.}] [item modules/comm/comm.man comm {A remote communication facility for Tcl (8.3 and later)}] [item modules/comm/comm_wire.man comm_wire {The comm wire protocol}] [item modules/control/control.man control {Procedures for control flow structures.}] [item modules/interp/deleg_method.man deleg_method {Creation of comm delegates (snit methods)}] @@ -435,13 +438,13 @@ [item modules/transfer/receiver.man transfer::receiver {Data source}] [item modules/transfer/transmitter.man transfer::transmitter {Data source}] [division_end] [division_start Unfiled] [item modules/cache/async.man cache::async {Asynchronous in-memory cache}] +[item modules/fileutil/paths.man fileutil::paths {Manage search path pools}] [item modules/generator/generator.man generator {Procedures for creating and using generators.}] [item modules/yaml/huddle.man huddle {Create and manipulate huddle object}] -[item modules/imap4/imap4.man imap4 {imap client-side tcl implementation of imap protocol}] [item modules/map/map_geocode_nominatim.man map::geocode::nominatim {Resolving geographical names with a Nominatim service}] [item modules/map/map_slippy.man map::slippy {Common code for slippy based map packages}] [item modules/map/map_slippy_cache.man map::slippy::cache {Management of a tile cache in the local filesystem}] [item modules/map/map_slippy_fetcher.man map::slippy::fetcher {Accessing a server providing tiles for slippy-based maps}] [item modules/mapproj/mapproj.man mapproj {Map projection routines}] @@ -448,10 +451,11 @@ [item modules/math/symdiff.man math::calculus::symdiff {Symbolic differentiation for Tcl}] [item modules/namespacex/namespacex.man namespacex {Namespace utility commands}] [item modules/rest/rest.man rest {define REST web APIs and call them inline or asychronously}] [item modules/stringprep/stringprep.man stringprep {Implementation of stringprep}] [item modules/stringprep/stringprep_data.man stringprep::data {stringprep data tables, generated, internal}] +[item modules/struct/struct_map.man struct::map {Manage key/value maps}] [item modules/math/machineparameters.man tclrep/machineparameters {Compute double precision machine parameters.}] [item modules/uev/uevent_onidle.man uevent::onidle {Request merging and deferal to idle time}] [item modules/stringprep/unicode.man unicode {Implementation of Unicode normalization}] [item modules/stringprep/unicode_data.man unicode::data {unicode data tables, generated, internal}] [item modules/units/units.man units {unit conversion}] @@ -537,10 +541,13 @@ [item modules/blowfish/blowfish.man blowfish {Implementation of the Blowfish block cipher}] [division_end] [division_start cache] [item modules/cache/async.man cache::async {Asynchronous in-memory cache}] [division_end] +[division_start clay] +[item modules/clay/clay.man clay {A minimalist framework for large scale OO Projects}] +[division_end] [division_start clock] [item modules/clock/iso8601.man clock_iso8601 {Parsing ISO 8601 dates/times}] [item modules/clock/rfc2822.man clock_rfc2822 {Parsing ISO 8601 dates/times}] [division_end] [division_start cmdline] @@ -674,10 +681,11 @@ [division_end] [division_start fileutil] [item modules/fileutil/fileutil.man fileutil {Procedures implementing some file utilities}] [item modules/fileutil/multi.man fileutil::multi {Multi-file operation, scatter/gather, standard object}] [item modules/fileutil/multiop.man fileutil::multi::op {Multi-file operation, scatter/gather}] +[item modules/fileutil/paths.man fileutil::paths {Manage search path pools}] [item modules/fileutil/traverse.man fileutil_traverse {Iterative directory traversal}] [division_end] [division_start ftp] [item modules/ftp/ftp.man ftp {Client-side tcl implementation of the ftp protocol}] [item modules/ftp/ftp_geturl.man ftp::geturl {Uri handler for ftp urls}] @@ -731,11 +739,11 @@ [division_end] [division_start http] [item modules/http/autoproxy.man autoproxy {Automatic HTTP proxy usage and authentication}] [division_end] [division_start httpd] -[item modules/httpd/httpd.man tool {A TclOO and coroutine based web server}] +[item modules/httpd/httpd.man httpd {A TclOO and coroutine based web server}] [division_end] [division_start ident] [item modules/ident/ident.man ident {Ident protocol client}] [division_end] [division_start imap4] @@ -810,10 +818,11 @@ [item modules/math/linalg.man math::linearalgebra {Linear Algebra}] [item modules/math/numtheory.man math::numtheory {Number Theory}] [item modules/math/optimize.man math::optimize {Optimisation routines}] [item modules/math/pca.man math::PCA {Package for Principal Component Analysis}] [item modules/math/polynomials.man math::polynomials {Polynomial functions}] +[item modules/math/quasirandom.man math::quasirandom {Quasi-random points for integration and Monte Carlo type methods}] [item modules/math/rational_funcs.man math::rationalfunctions {Polynomial functions}] [item modules/math/roman.man math::roman {Tools for creating and manipulating roman numerals}] [item modules/math/special.man math::special {Special mathematical functions}] [item modules/math/statistics.man math::statistics {Basic statistical functions and procedures}] [item modules/math/trig.man math::trig {Trigonometric anf hyperbolic functions}] @@ -1011,10 +1020,11 @@ [item modules/struct/disjointset.man struct::disjointset {Disjoint set data structure}] [item modules/struct/graph.man struct::graph {Create and manipulate directed graph objects}] [item modules/struct/graphops.man struct::graph::op {Operation for (un)directed graph objects}] [item modules/struct/graph1.man struct::graph_v1 {Create and manipulate directed graph objects}] [item modules/struct/struct_list.man struct::list {Procedures for manipulating lists}] +[item modules/struct/struct_map.man struct::map {Manage key/value maps}] [item modules/struct/matrix.man struct::matrix {Create and manipulate matrix objects}] [item modules/struct/matrix1.man struct::matrix_v1 {Create and manipulate matrix objects}] [item modules/struct/pool.man struct::pool {Create and manipulate pool objects (of discrete items)}] [item modules/struct/prioqueue.man struct::prioqueue {Create and manipulate prioqueue objects}] [item modules/struct/queue.man struct::queue {Create and manipulate queue objects}] Index: support/devel/sak/doc/toc_cats.txt ================================================================== --- support/devel/sak/doc/toc_cats.txt +++ support/devel/sak/doc/toc_cats.txt @@ -209,10 +209,11 @@ [item modules/math/linalg.man math::linearalgebra {Linear Algebra}] [item modules/math/numtheory.man math::numtheory {Number Theory}] [item modules/math/optimize.man math::optimize {Optimisation routines}] [item modules/math/pca.man math::PCA {Package for Principal Component Analysis}] [item modules/math/polynomials.man math::polynomials {Polynomial functions}] +[item modules/math/quasirandom.man math::quasirandom {Quasi-random points for integration and Monte Carlo type methods}] [item modules/math/rational_funcs.man math::rationalfunctions {Polynomial functions}] [item modules/math/roman.man math::roman {Tools for creating and manipulating roman numerals}] [item modules/math/special.man math::special {Special mathematical functions}] [item modules/math/statistics.man math::statistics {Basic statistical functions and procedures}] [item modules/math/trig.man math::trig {Trigonometric anf hyperbolic functions}] @@ -226,11 +227,13 @@ [item modules/bee/bee.man bee {BitTorrent Serialization Format Encoder/Decoder}] [item modules/dns/tcllib_dns.man dns {Tcl Domain Name Service Client}] [item modules/ftp/ftp.man ftp {Client-side tcl implementation of the ftp protocol}] [item modules/ftp/ftp_geturl.man ftp::geturl {Uri handler for ftp urls}] [item modules/ftpd/ftpd.man ftpd {Tcl FTP server implementation}] +[item modules/httpd/httpd.man httpd {A TclOO and coroutine based web server}] [item modules/ident/ident.man ident {Ident protocol client}] +[item modules/imap4/imap4.man imap4 {imap client-side tcl implementation of imap protocol}] [item modules/irc/irc.man irc {Create IRC connection and interface.}] [item modules/ldap/ldap.man ldap {LDAP client}] [item modules/ldap/ldapx.man ldapx {LDAP extended object interface}] [item modules/nns/nns_client.man nameserv {Name service facility, Client}] [item modules/nns/nns_auto.man nameserv::auto {Name service facility, Client Extension}] @@ -256,11 +259,10 @@ [item modules/sasl/scram.man SASL::SCRAM {Implementation of SASL SCRAM mechanism for Tcl}] [item modules/sasl/gtoken.man SASL::XGoogleToken {Implementation of SASL NTLM mechanism for Tcl}] [item modules/mime/smtp.man smtp {Client-side tcl implementation of the smtp protocol}] [item modules/smtpd/smtpd.man smtpd {Tcl SMTP server implementation}] [item modules/dns/tcllib_ip.man tcllib_ip {IPv4 and IPv6 address manipulation}] -[item modules/httpd/httpd.man tool {A TclOO and coroutine based web server}] [item modules/udpcluster/udpcluster.man udpcluster {UDP Peer-to-Peer cluster}] [item modules/uri/uri.man uri {URI utilities}] [item modules/uri/urn-scheme.man uri_urn {URI utilities, URN scheme}] [item modules/websocket/websocket.man websocket {Tcl implementation of the websocket protocol}] [division_end] @@ -322,10 +324,11 @@ [division_start {Procedures, arguments, parameters, options}] [item modules/tepam/tepam_introduction.man tepam {An introduction into TEPAM, Tcl's Enhanced Procedure and Argument Manager}] [item modules/tepam/tepam_procedure.man tepam::procedure {TEPAM procedure, reference manual}] [division_end] [division_start {Programming tools}] +[item modules/clay/clay.man clay {A minimalist framework for large scale OO Projects}] [item modules/cmdline/cmdline.man cmdline {Procedures to process command lines and options.}] [item modules/comm/comm.man comm {A remote communication facility for Tcl (8.3 and later)}] [item modules/comm/comm_wire.man comm_wire {The comm wire protocol}] [item modules/control/control.man control {Procedures for control flow structures.}] [item modules/interp/deleg_method.man deleg_method {Creation of comm delegates (snit methods)}] @@ -435,13 +438,13 @@ [item modules/transfer/receiver.man transfer::receiver {Data source}] [item modules/transfer/transmitter.man transfer::transmitter {Data source}] [division_end] [division_start Unfiled] [item modules/cache/async.man cache::async {Asynchronous in-memory cache}] +[item modules/fileutil/paths.man fileutil::paths {Manage search path pools}] [item modules/generator/generator.man generator {Procedures for creating and using generators.}] [item modules/yaml/huddle.man huddle {Create and manipulate huddle object}] -[item modules/imap4/imap4.man imap4 {imap client-side tcl implementation of imap protocol}] [item modules/map/map_geocode_nominatim.man map::geocode::nominatim {Resolving geographical names with a Nominatim service}] [item modules/map/map_slippy.man map::slippy {Common code for slippy based map packages}] [item modules/map/map_slippy_cache.man map::slippy::cache {Management of a tile cache in the local filesystem}] [item modules/map/map_slippy_fetcher.man map::slippy::fetcher {Accessing a server providing tiles for slippy-based maps}] [item modules/mapproj/mapproj.man mapproj {Map projection routines}] @@ -448,10 +451,11 @@ [item modules/math/symdiff.man math::calculus::symdiff {Symbolic differentiation for Tcl}] [item modules/namespacex/namespacex.man namespacex {Namespace utility commands}] [item modules/rest/rest.man rest {define REST web APIs and call them inline or asychronously}] [item modules/stringprep/stringprep.man stringprep {Implementation of stringprep}] [item modules/stringprep/stringprep_data.man stringprep::data {stringprep data tables, generated, internal}] +[item modules/struct/struct_map.man struct::map {Manage key/value maps}] [item modules/math/machineparameters.man tclrep/machineparameters {Compute double precision machine parameters.}] [item modules/uev/uevent_onidle.man uevent::onidle {Request merging and deferal to idle time}] [item modules/stringprep/unicode.man unicode {Implementation of Unicode normalization}] [item modules/stringprep/unicode_data.man unicode::data {unicode data tables, generated, internal}] [item modules/units/units.man units {unit conversion}] Index: support/devel/sak/doc/toc_mods.txt ================================================================== --- support/devel/sak/doc/toc_mods.txt +++ support/devel/sak/doc/toc_mods.txt @@ -40,10 +40,13 @@ [item modules/blowfish/blowfish.man blowfish {Implementation of the Blowfish block cipher}] [division_end] [division_start cache] [item modules/cache/async.man cache::async {Asynchronous in-memory cache}] [division_end] +[division_start clay] +[item modules/clay/clay.man clay {A minimalist framework for large scale OO Projects}] +[division_end] [division_start clock] [item modules/clock/iso8601.man clock_iso8601 {Parsing ISO 8601 dates/times}] [item modules/clock/rfc2822.man clock_rfc2822 {Parsing ISO 8601 dates/times}] [division_end] [division_start cmdline] @@ -177,10 +180,11 @@ [division_end] [division_start fileutil] [item modules/fileutil/fileutil.man fileutil {Procedures implementing some file utilities}] [item modules/fileutil/multi.man fileutil::multi {Multi-file operation, scatter/gather, standard object}] [item modules/fileutil/multiop.man fileutil::multi::op {Multi-file operation, scatter/gather}] +[item modules/fileutil/paths.man fileutil::paths {Manage search path pools}] [item modules/fileutil/traverse.man fileutil_traverse {Iterative directory traversal}] [division_end] [division_start ftp] [item modules/ftp/ftp.man ftp {Client-side tcl implementation of the ftp protocol}] [item modules/ftp/ftp_geturl.man ftp::geturl {Uri handler for ftp urls}] @@ -234,11 +238,11 @@ [division_end] [division_start http] [item modules/http/autoproxy.man autoproxy {Automatic HTTP proxy usage and authentication}] [division_end] [division_start httpd] -[item modules/httpd/httpd.man tool {A TclOO and coroutine based web server}] +[item modules/httpd/httpd.man httpd {A TclOO and coroutine based web server}] [division_end] [division_start ident] [item modules/ident/ident.man ident {Ident protocol client}] [division_end] [division_start imap4] @@ -313,10 +317,11 @@ [item modules/math/linalg.man math::linearalgebra {Linear Algebra}] [item modules/math/numtheory.man math::numtheory {Number Theory}] [item modules/math/optimize.man math::optimize {Optimisation routines}] [item modules/math/pca.man math::PCA {Package for Principal Component Analysis}] [item modules/math/polynomials.man math::polynomials {Polynomial functions}] +[item modules/math/quasirandom.man math::quasirandom {Quasi-random points for integration and Monte Carlo type methods}] [item modules/math/rational_funcs.man math::rationalfunctions {Polynomial functions}] [item modules/math/roman.man math::roman {Tools for creating and manipulating roman numerals}] [item modules/math/special.man math::special {Special mathematical functions}] [item modules/math/statistics.man math::statistics {Basic statistical functions and procedures}] [item modules/math/trig.man math::trig {Trigonometric anf hyperbolic functions}] @@ -514,10 +519,11 @@ [item modules/struct/disjointset.man struct::disjointset {Disjoint set data structure}] [item modules/struct/graph.man struct::graph {Create and manipulate directed graph objects}] [item modules/struct/graphops.man struct::graph::op {Operation for (un)directed graph objects}] [item modules/struct/graph1.man struct::graph_v1 {Create and manipulate directed graph objects}] [item modules/struct/struct_list.man struct::list {Procedures for manipulating lists}] +[item modules/struct/struct_map.man struct::map {Manage key/value maps}] [item modules/struct/matrix.man struct::matrix {Create and manipulate matrix objects}] [item modules/struct/matrix1.man struct::matrix_v1 {Create and manipulate matrix objects}] [item modules/struct/pool.man struct::pool {Create and manipulate pool objects (of discrete items)}] [item modules/struct/prioqueue.man struct::prioqueue {Create and manipulate prioqueue objects}] [item modules/struct/queue.man struct::queue {Create and manipulate queue objects}] Index: support/devel/sak/localdoc/localdoc.tcl ================================================================== --- support/devel/sak/localdoc/localdoc.tcl +++ support/devel/sak/localdoc/localdoc.tcl @@ -42,14 +42,14 @@ puts "Reindex the documentation..." sak::doc::imake __dummy__ $excluded sak::doc::index __dummy__ $excluded puts "Removing old documentation..." - # but keep the main index around, manually created, edited, not to be touched + # Keep the main index around however, manually created, edited, + # not to be touched # TODO: catch errors and restore automatically file rename embedded/index.md e_index.md - file delete -force embedded file mkdir embedded/md # Put the saved main page back into place, early. file rename e_index.md embedded/index.md Index: support/installation/modules.tcl ================================================================== --- support/installation/modules.tcl +++ support/installation/modules.tcl @@ -31,10 +31,15 @@ # @@ Registration START Exclude calendar Exclude exif +# name pkg doc example +Module 0compatibility _tcl _null _null +# Wrapper packages redirecting deprecated/moved packages to their old +# implementations. See pkgIndex.tcl for more notes. + # name pkg doc example Module aes _tcl _man _null Module amazon-s3 _tcl _man _null Module asn _tcl _man _null Module base32 _tcl _man _null