You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
677 lines
21 KiB
677 lines
21 KiB
'\" |
|
'\" Generated from file '_module_lib-0\&.1\&.1\&.tm\&.man' by tcllib/doctools with format 'nroff' |
|
'\" Copyright (c) 2024 |
|
'\" |
|
.TH "punkshell_module_punk::lib" 0 0\&.1\&.1 doc "punk 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 |
|
punkshell_module_punk::lib \- punk general utility functions |
|
.SH SYNOPSIS |
|
package require \fBpunk::lib \fR |
|
.sp |
|
\fBlremove\fR \fIlist\fR ?index \&.\&.\&.? |
|
.sp |
|
\fBlpop\fR \fIlistvar\fR ?index? |
|
.sp |
|
\fBinvoke\fR \fIcommand\fR |
|
.sp |
|
\fBlindex_resolve\fR \fIlist\fR \fIindex\fR |
|
.sp |
|
\fBlindex_resolve_basic\fR \fIlist\fR \fIindex\fR |
|
.sp |
|
\fBK\fR \fIx\fR \fIy\fR |
|
.sp |
|
\fBis_utf8_multibyteprefix\fR \fIstr\fR |
|
.sp |
|
\fBis_utf8_single\fR \fI1234bytes\fR |
|
.sp |
|
\fBget_utf8_leading\fR \fIrawbytes\fR |
|
.sp |
|
\fBhex2dec\fR ?option value\&.\&.\&.? \fIlist_largeHex\fR |
|
.sp |
|
\fBdex2hex\fR ?option value\&.\&.\&.? \fIlist_decimals\fR |
|
.sp |
|
\fBlog2\fR \fIx\fR |
|
.sp |
|
\fBlogbase\fR \fIb\fR \fIx\fR |
|
.sp |
|
\fBfactors\fR \fIx\fR |
|
.sp |
|
\fBoddFactors\fR \fIx\fR |
|
.sp |
|
\fBgreatestFactorBelow\fR \fIx\fR |
|
.sp |
|
\fBgreatestOddFactorBelow\fR \fIx\fR |
|
.sp |
|
\fBgreatestOddFactor\fR \fIx\fR |
|
.sp |
|
\fBgcd\fR \fIn\fR \fIm\fR |
|
.sp |
|
\fBgcd\fR \fIn\fR \fIm\fR |
|
.sp |
|
\fBcommonDivisors\fR \fIx\fR \fIy\fR |
|
.sp |
|
\fBhasglobs\fR \fIstr\fR |
|
.sp |
|
\fBtrimzero\fR \fInumber\fR |
|
.sp |
|
\fBsubstring_count\fR \fIstr\fR \fIsubstring\fR |
|
.sp |
|
\fBdict_merge_ordered\fR \fIdefaults\fR \fImain\fR |
|
.sp |
|
\fBaskuser\fR \fIquestion\fR |
|
.sp |
|
\fBlinesort\fR ?sortoption ?val?\&.\&.\&.? \fItextblock\fR |
|
.sp |
|
\fBlist_as_lines\fR ?-joinchar char? \fIlinelist\fR |
|
.sp |
|
\fBlines_as_list\fR ?option value \&.\&.\&.? \fItext\fR |
|
.sp |
|
.BE |
|
.SH DESCRIPTION |
|
.PP |
|
This is a set of utility functions that are commonly used across punk modules or are just considered to be general-purpose functions\&. |
|
.PP |
|
The base set includes string and math functions but has no specific theme |
|
.SH OVERVIEW |
|
.PP |
|
overview of punk::lib |
|
.SS CONCEPTS |
|
.PP |
|
The punk::lib modules should have no strong dependencies other than Tcl |
|
.PP |
|
Dependendencies that only affect display or additional functionality may be included - but should fail gracefully if not present, and only when a function is called that uses one of these soft dependencies\&. |
|
.PP |
|
This requirement for no strong dependencies, means that many utility functions that might otherwise seem worthy of inclusion here are not present\&. |
|
.SS DEPENDENCIES |
|
.PP |
|
packages used by punk::lib |
|
.IP \(bu |
|
\fBTcl 8\&.6-\fR |
|
.PP |
|
.SH API |
|
.SS "NAMESPACE PUNK::LIB::COMPAT" |
|
.PP |
|
compatibility functions for features that may not be available in earlier Tcl versions |
|
.PP |
|
These are generally 'forward compatibility' functions ie allowing earlier versions to use later features/idioms by using a Tcl-only version of a missing builtin\&. |
|
.PP |
|
Such Tcl-only versions will inevitably be less performant - perhaps significantly so\&. |
|
.TP |
|
\fBlremove\fR \fIlist\fR ?index \&.\&.\&.? |
|
.sp |
|
Forwards compatible lremove for versions 8\&.6 or less to support equivalent 8\&.7 lremove |
|
.TP |
|
\fBlpop\fR \fIlistvar\fR ?index? |
|
.sp |
|
Forwards compatible lpop for versions 8\&.6 or less to support equivalent 8\&.7 lpop |
|
.PP |
|
.SS "NAMESPACE PUNK::LIB" |
|
.PP |
|
Core API functions for punk::lib |
|
.TP |
|
\fBinvoke\fR \fIcommand\fR |
|
.sp |
|
Invoke an external command (using tcl open command) capturing stdout,stderr and the exitcode |
|
.CS |
|
|
|
|
|
set script { |
|
puts stdout {hello on stdout} |
|
puts stderr {hello on stderr} |
|
exit 42 |
|
} |
|
invoke [list tclsh <<$script] |
|
|
|
.CE |
|
.TP |
|
\fBlindex_resolve\fR \fIlist\fR \fIindex\fR |
|
.sp |
|
Resolve an index which may be of the forms accepted by Tcl list commands such as end-2 or 2+2 to the actual integer index for the supplied list |
|
.sp |
|
Users may define procs which accept a list index and wish to accept the forms understood by Tcl\&. |
|
.sp |
|
This means the proc may be called with something like $x+2 end-$y etc |
|
.sp |
|
Sometimes the actual integer index is desired\&. |
|
.sp |
|
We want to resolve the index used, without passing arbitrary expressions into the 'expr' function - which could have security risks\&. |
|
.sp |
|
lindex_resolve will parse the index expression and return: |
|
.sp |
|
a) -3 if the supplied index expression is below the lower bound for the supplied list\&. (< 0) |
|
.sp |
|
b) -2 if the supplied index expression is above the upper bound for the supplied list\&. (> end) |
|
.sp |
|
We don't return -1 - as the similar function lindex_resolve_basic uses this to denote out of range at either end of the list |
|
.sp |
|
Otherwise it will return an integer corresponding to the position in the list\&. |
|
.sp |
|
This is in stark contrast to Tcl list function indices which will return empty strings for out or bounds indices, or in the case of lrange, return results anyway\&. |
|
.sp |
|
Like Tcl list commands - it will produce an error if the form of the index is not acceptable |
|
.sp |
|
For empty lists, end and end+x indices are considered to be out of bounds on the upper side - thus returning -2 |
|
.TP |
|
\fBlindex_resolve_basic\fR \fIlist\fR \fIindex\fR |
|
.sp |
|
Accepts index of the forms accepted by Tcl's list commands\&. (e\&.g compound indices such as 3+1 end-2) |
|
.sp |
|
returns -1 for out of range at either end, or a valid integer index |
|
.sp |
|
Unlike lindex_resolve; lindex_resolve_basic can't determine if an out of range index was out of range at the lower or upper bound |
|
.sp |
|
This is only likely to be faster than average over lindex_resolve for Tcl which has the builtin lseq command |
|
.sp |
|
The performance advantage is more likely to be present when using compound indexes such as $x+1 or end-1 |
|
.sp |
|
For pure integer indices the performance should be equivalent |
|
.TP |
|
\fBK\fR \fIx\fR \fIy\fR |
|
.sp |
|
The K-combinator function - returns the first argument, x and discards y |
|
.sp |
|
see \fIhttps://wiki\&.tcl-lang\&.org/page/K\fR |
|
.sp |
|
It is used in cases where command-substitution at the calling-point performs some desired effect\&. |
|
.TP |
|
\fBis_utf8_multibyteprefix\fR \fIstr\fR |
|
.sp |
|
Returns a boolean if str is potentially a prefix for a multibyte utf-8 character |
|
.sp |
|
ie - tests if it is possible that appending more data will result in a utf-8 codepoint |
|
.sp |
|
Will return false for an already complete utf-8 codepoint |
|
.sp |
|
It is assumed the incomplete sequence is at the beginning of the bytes argument |
|
.sp |
|
Suitable input for this might be from the unreturned tail portion of get_utf8_leading $testbytes |
|
.sp |
|
e\&.g using: set head [get_utf8_leading $testbytes] ; set tail [string range $testbytes [string length $head] end] |
|
.TP |
|
\fBis_utf8_single\fR \fI1234bytes\fR |
|
.sp |
|
Tests input of 1,2,3 or 4 bytes and responds with a boolean indicating if it is a valid utf-8 character (codepoint) |
|
.TP |
|
\fBget_utf8_leading\fR \fIrawbytes\fR |
|
.sp |
|
return the leading portion of rawbytes that is a valid utf8 sequence\&. |
|
.sp |
|
This will stop at the point at which the bytes can't be interpreted as a complete utf-8 codepoint |
|
.sp |
|
e\&.g It will not return the first byte or 2 of a 3-byte utf-8 character if the last byte is missing, and will return only the valid utf-8 string from before the first byte of the incomplete character\&. |
|
.sp |
|
It will also only return the prefix before any bytes that cannot be part of a utf-8 sequence at all\&. |
|
.sp |
|
Note that while this will return valid utf8 - it has no knowledge of grapheme clusters or diacritics |
|
.sp |
|
This means if it is being used to process bytes split at some arbitrary point - the trailing data that isn't returned could be part of a grapheme cluster that belongs with the last character of the leading string already returned |
|
.sp |
|
The utf-8 BOM \\xEF\\xBB\\xBF is a valid UTF8 3-byte sequence and so can also be returned as part of the leading utf8 bytes |
|
.TP |
|
\fBhex2dec\fR ?option value\&.\&.\&.? \fIlist_largeHex\fR |
|
.sp |
|
Convert a list of (possibly large) unprefixed hex strings to their decimal values |
|
.sp |
|
hex2dec accepts and ignores internal underscores in the same manner as Tcl 8\&.7+ numbers e\&.g hex2dec FF_FF returns 65535 |
|
.sp |
|
Leading and trailing underscores are ignored as a matter of implementation convenience - but this shouldn't be relied upon\&. |
|
.sp |
|
Leading or trailing whitespace in each list member is allowed e\&.g hex2dec " F" returns 15 |
|
.sp |
|
Internal whitespace e\&.g "F F" is not permitted - but a completely empty element "" is allowed and will return 0 |
|
.TP |
|
\fBdex2hex\fR ?option value\&.\&.\&.? \fIlist_decimals\fR |
|
.sp |
|
Convert a list of decimal integers to a list of hex values |
|
.sp |
|
-width <int> can be used to make each hex value at least int characters wide, with leading zeroes\&. |
|
.sp |
|
-case upper|lower determines the case of the hex letters in the output |
|
.TP |
|
\fBlog2\fR \fIx\fR |
|
.sp |
|
log base2 of x |
|
.sp |
|
This uses a 'live' proc body - the divisor for the change of base is computed once at definition time |
|
.sp |
|
(courtesy of RS \fIhttps://wiki\&.tcl-lang\&.org/page/Additional+math+functions\fR) |
|
.TP |
|
\fBlogbase\fR \fIb\fR \fIx\fR |
|
.sp |
|
log base b of x |
|
.sp |
|
This function uses expr's natural log and the change of base division\&. |
|
.sp |
|
This means for example that we can get results like: logbase 10 1000 = 2\&.9999999999999996 |
|
.sp |
|
Use expr's log10() function or tcl::mathfunc::log10 for base 10 |
|
.TP |
|
\fBfactors\fR \fIx\fR |
|
.sp |
|
Return a sorted list of the positive factors of x where x > 0 |
|
.sp |
|
For x = 0 we return only 0 and 1 as technically any number divides zero and there are an infinite number of factors\&. (including zero itself in this context)* |
|
.sp |
|
This is a simple brute-force implementation that iterates all numbers below the square root of x to check the factors |
|
.sp |
|
Because the implementation is so simple - the performance is very reasonable for numbers below at least a few 10's of millions |
|
.sp |
|
See tcllib math::numtheory::factors for a more complex implementation - which seems to be slower for 'small' numbers |
|
.sp |
|
Comparisons were done with some numbers below 17 digits long |
|
.sp |
|
For seriously big numbers - this simple algorithm would no doubt be outperformed by more complex algorithms\&. |
|
.sp |
|
The numtheory library stores some data about primes etc with each call - so may become faster when being used on more numbers |
|
but has the disadvantage of being slower for 'small' numbers and using more memory\&. |
|
.sp |
|
If the largest factor below x is needed - the greatestOddFactorBelow and GreatestFactorBelow functions are a faster way to get there than computing the whole list, even for small values of x |
|
.sp |
|
* Taking x=0; Notion of x being divisible by integer y being: There exists an integer p such that x = py |
|
.sp |
|
In other mathematical contexts zero may be considered not to divide anything\&. |
|
.TP |
|
\fBoddFactors\fR \fIx\fR |
|
.sp |
|
Return a list of odd integer factors of x, sorted in ascending order |
|
.TP |
|
\fBgreatestFactorBelow\fR \fIx\fR |
|
.sp |
|
Return the largest factor of x excluding itself |
|
.sp |
|
factor functions can be useful for console layout calculations |
|
.sp |
|
See Tcllib math::numtheory for more extensive implementations |
|
.TP |
|
\fBgreatestOddFactorBelow\fR \fIx\fR |
|
.sp |
|
Return the largest odd integer factor of x excluding x itself |
|
.TP |
|
\fBgreatestOddFactor\fR \fIx\fR |
|
.sp |
|
Return the largest odd integer factor of x |
|
.sp |
|
For an odd value of x - this will always return x |
|
.TP |
|
\fBgcd\fR \fIn\fR \fIm\fR |
|
.sp |
|
Return the greatest common divisor of m and n |
|
.sp |
|
Straight from Lars Hellström's math::numtheory library in Tcllib |
|
.sp |
|
Graphical use: |
|
.sp |
|
An a by b rectangle can be covered with square tiles of side-length c, |
|
.sp |
|
only if c is a common divisor of a and b |
|
.TP |
|
\fBgcd\fR \fIn\fR \fIm\fR |
|
.sp |
|
Return the lowest common multiple of m and n |
|
.sp |
|
Straight from Lars Hellström's math::numtheory library in Tcllib |
|
.sp |
|
.TP |
|
\fBcommonDivisors\fR \fIx\fR \fIy\fR |
|
.sp |
|
Return a list of all the common factors of x and y |
|
.sp |
|
(equivalent to factors of their gcd) |
|
.TP |
|
\fBhasglobs\fR \fIstr\fR |
|
.sp |
|
Return a boolean indicating whether str contains any of the glob characters: * ? [ ] |
|
.sp |
|
hasglobs uses append to preserve Tcls internal representation for str - so it should help avoid shimmering in the few cases where this may matter\&. |
|
.TP |
|
\fBtrimzero\fR \fInumber\fR |
|
.sp |
|
Return number with left-hand-side zeros trimmed off - unless all zero |
|
.sp |
|
If number is all zero - a single 0 is returned |
|
.TP |
|
\fBsubstring_count\fR \fIstr\fR \fIsubstring\fR |
|
.sp |
|
Search str and return number of occurrences of substring |
|
.TP |
|
\fBdict_merge_ordered\fR \fIdefaults\fR \fImain\fR |
|
.sp |
|
The standard dict merge accepts multiple dicts with values from dicts to the right (2nd argument) taking precedence\&. |
|
.sp |
|
When merging with a dict of default values - this means that any default key/vals that weren't in the main dict appear in the output before the main data\&. |
|
.sp |
|
This function merges the two dicts whilst maintaining the key order of main followed by defaults\&. |
|
.TP |
|
\fBaskuser\fR \fIquestion\fR |
|
.sp |
|
A basic utility to read an answer from stdin |
|
.sp |
|
The prompt is written to the terminal and then it waits for a user to type something |
|
.sp |
|
stdin is temporarily configured to blocking and then put back in its original state in case it wasn't already so\&. |
|
.sp |
|
If the terminal is using punk::console and is in raw mode - the terminal will temporarily be put in line mode\&. |
|
.sp |
|
(Generic terminal raw vs linemode detection not yet present) |
|
.sp |
|
The user must hit enter to submit the response |
|
.sp |
|
The return value is the string if any that was typed prior to hitting enter\&. |
|
.sp |
|
The question argument can be manually colourised using the various punk::ansi funcitons |
|
.CS |
|
|
|
|
|
set answer [punk::lib::askuser "[a+ green bold]Do you want to proceed? (Y|N)[a]"] |
|
if {[string match y* [string tolower $answer]]} { |
|
puts "Proceeding" |
|
} else { |
|
puts "Cancelled by user" |
|
} |
|
|
|
.CE |
|
.TP |
|
\fBlinesort\fR ?sortoption ?val?\&.\&.\&.? \fItextblock\fR |
|
.sp |
|
Sort lines in textblock |
|
.sp |
|
Returns another textblock with lines sorted |
|
.sp |
|
options are flags as accepted by lsort ie -ascii -command -decreasing -dictionary -index -indices -integer -nocase -real -stride -unique |
|
.TP |
|
\fBlist_as_lines\fR ?-joinchar char? \fIlinelist\fR |
|
.sp |
|
This simply joines the elements of the list with -joinchar |
|
.sp |
|
It is mainly intended for use in pipelines where the primary argument comes at the end - but it can also be used as a general replacement for join $lines <le> |
|
.sp |
|
The sister function lines_as_list takes a block of text and splits it into lines - but with more options related to trimming the block and/or each line\&. |
|
.TP |
|
\fBlines_as_list\fR ?option value \&.\&.\&.? \fItext\fR |
|
.sp |
|
Returns a list of possibly trimmed lines depeding on options |
|
.sp |
|
The concept of lines is raw lines from splitting on newline after crlf is mapped to lf |
|
.sp |
|
- not console lines which may be entirely different due to control characters such as vertical tabs or ANSI movements |
|
.PP |
|
.SH INTERNAL |
|
.SS "NAMESPACE PUNK::LIB::SYSTEM" |
|
.PP |
|
Internal functions that are not part of the API |
|
.PP |
|
.SH KEYWORDS |
|
lib, module, utility |
|
.SH COPYRIGHT |
|
.nf |
|
Copyright (c) 2024 |
|
|
|
.fi
|
|
|