pkg://jultaf-0.0.4-1.i386.rpm:140767/
usr/
doc/
jultaf-0.0.4/jultaf.sgml
info downloads
<!-- This is a -*- SGML -*- file.
jultaf.sgml: SGML source file for `Jumble Library for Tcl and Friends'
Copyright (C) 1996, 1997, 1998 Stefan Hornburg
Author: Stefan Hornburg <racke@gundel.han.de>
Maintainer: Stefan Hornburg <racke@gundel.han.de>
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This file is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this file; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-->
<!DOCTYPE manual PUBLIC "-//Witware//DTD InfoPrism//EN">
<PREAMBLE>
<CATEGORY>Tcl and Friends<NAME>Jultaf
<TOPIC>The Jumble Library for Tcl and Friends
<MAKEINDEX NAME=cp>
<MAKEINDEX NAME=fn>
<MAKEINDEX NAME=vr>
<MAKEINDEX NAME=pkg>
</PREAMBLE>
<TITLE>Jumble Library for Tcl and Friends</TITLE>
<AUTHOR EMAIL="racke@gundel.han.de">Stefan Hornburg</AUTHOR>
<STAMP YEAR=1998 MONTH=9 DAY=3 HOUR=2 MINUTE=22 SECS=11 TZ="met dst">
The <EM>Jumble Library for Tcl and Friends</EM> is a collection of Tcl and
[incr Tcl] scripts and
provides procedures resp. classes with various purposes. Additionally
a shared library for accessing GDBM databases from Tcl can be build
with this package.
<P>
This document corresponds to version 0.0.4 of the library.
Up-to-date information about Jultaf can be found via
<HTMLURL URL="http://www.han.de/~racke/jultaf/"
NAME="http://www.han.de/~racke/jultaf/">.
<P>
<TOC DEPTH=2>
<SECTION><!--
************
Introduction
************
--><SHORT>Introduction</SHORT>
<TITLE>Important information about this package</TITLE>
Jultaf is <EM>alpha</EM> software. It is not tested by anyone but me and
documentation is not as good as required for a decent package. However, it
works for me.
<P>
Jultaf is <EM>free</EM> software. This means that everyone may
use it, redistribute it and/or modify it under the terms of the
GNU General Public License, as published by the Free Software
Foundation.
<SECTION><!--
=======================
How to Read This Manual
=======================
--><TITLE>How to Read This Manual</TITLE>
<SHORT>Conventions</SHORT>
<INDEX NAME=CP>new items</INDEX>
<INDEX NAME=CP>features<SUBI>new</INDEX>
Items introduced in one of the last revisions are marked as new in this
manual as shown in the example below:
<DL>
<DT><CODE>fresh</CODE> <LABEL NAME="new"><IMG SRC=new.gif ALT="*NEW*"></LABEL>
<DD>Returns a list with new functions in this release.
</DL>
Jultaf is a work in progress and several items will be a moving target.
Their syntax may change in a not backward compatible way and are marked as
<INDEX NAME=CP>unstable items</INDEX>
<INDEX NAME=CP>features<SUBI>unstable</INDEX>
<DFN>unstable</DFN>:
<DL>
<DT><CODE>hacks</CODE>
<LABEL NAME="exp"><IMG SRC=exp.gif ALT="*EXPERIMENTAL*"></LABEL>
<DD>Returns a list with bug-prone functions in this release.
</DL>
</SECTION> <!-- How to Read This Manual -->
<SECTION LABEL=buildconf><!--
===================
Build Configuration
===================
--><TITLE>Build Configuration</TITLE>
<P>
<SECTION><!--
+++++++++++++++++
Optional Features
+++++++++++++++++
--><TITLE>Optional Features</TITLE>
<DESCR><CODE>&com;enable-</CODE> and <CODE>&com;with-</CODE> options</DESCR>
<INDEX NAME=cp>features<SUBI>optional</INDEX>
<DL>
<!-- enable-itcl -->
<DT><CODE><LABEL NAME="enable-itcl" INDEX=cp>
&com;enable-itcl</LABEL></CODE>=
<CODE>yes</CODE>|<CODE>no</CODE>|<VAR>PATH</VAR>
<DD>Indicates if the [incr Tcl] library files should be installed as well
as the vanilla Tcl library files. If set to <CODE>yes</CODE> or the
<VAR>PATH</VAR> to the [incr Tcl] interpreter, this files will be installed.
The default value depends on the fact if <CODE>configure</CODE> detects
<CODE>itclsh</CODE> in the path.
<!-- with-gdbm -->
<DT><CODE><LABEL NAME=withgdbm INDEX=cp>&com;with-gdbm</LABEL></CODE>
<DD>Enables compiling and installing of the Jufgdbm library.
<!-- with-prof -->
<DT><CODE><LABEL NAME=withprof INDEX=cp>&com;with-prof</LABEL></CODE>
<DD>Enables compiling and installing of the Jufprof library.
<!-- with-pq -->
<DT><CODE><LABEL NAME=withpq INDEX=cp>&com;with-pq</LABEL></CODE>
<DD>Enables compiling and installing of the Jufpq library.
<!-- with-rpm -->
<DT><CODE><LABEL NAME=withrpm INDEX=cp>&com;with-rpm</LABEL></CODE>
<DD>Enables compiling and installing of the Jufrpm library.
</DL>
</SECTION> <!-- Optional Features -->
<SECTION><!--
========================
Installation Directories
========================
--><TITLE>Installation Directories</TITLE>
This section describes where the various files of the Jultaf distribution
get installed by <CODE>make install</CODE>.
<TABLE>
<TR><TH>Symbolic Name<TH>Default value<TH>Files
<TR><!-- DATADIR -->
<TD><CODE><INDEX NAME=cp><EP>DATADIR</INDEX></CODE>
<TD>/usr/local/share/jultaf
<TD>Tcl and [incr Tcl] files
<TR><!-- LIBDIR -->
<TD><CODE><INDEX NAME=cp><EP>LIBDIR</INDEX></CODE>
<TD>/usr/local/lib
<TD>library files (Jufprof and Jufgdbm)
<TR><!-- INFODIR -->
<TD><CODE><INDEX NAME=cp><EP>INFODIR</INDEX></CODE>
<TD>/usr/local/info
<TD><INDEX NAME=CP>Info</INDEX>
<INDEX NAME=CP><EP>documentation<SUBI>GNU Info files</INDEX>
(<INDEX NAME=cp><EP>GNU Info</INDEX> format)
<TR><!-- DOCDIR -->
<TD><CODE><INDEX NAME=cp><EP>DOCDIR</INDEX></CODE>
<TD>/usr/local/doc/jultaf
<TD><INDEX NAME=CP>HTML documentation</INDEX>
<INDEX NAME=CP><EP>documentation<SUBI>HTML</INDEX>
(<INDEX NAME=cp><EP>HTML</INDEX> format)
</TABLE>
</SECTION> <!-- Installation Directories -->
</SECTION> <!-- Installation -->
</SECTION> <!-- Introduction -->
<SECTION><!--
*****
Error
*****
--><TITLE><INDEX NAME=pkg><EP>Error</INDEX></TITLE>
<DESCR>Error Handling</DESCR>
The functions provided by the <CODE>Error</CODE> package
can be divided into error handling functions and error
evaluation functions.
<P>
<DL>
<!-- fault -->
<DT><CODE><INDEX NAME=fn><EP>fault</INDEX></CODE>
<VAR>TYPE</VAR> <VAR>[ARG ...]</VAR>
<DD>Generates an Tcl error. The message is composed of an template specified
by TYPE and the remaining arguments:
<DL>
<!-- juf_fault/badoption -->
<DT><CODE><INDEX NAME=vr><EP>badoption</INDEX></CODE>
<DD><CODE>bad option "%s": must be %s</CODE>
<!-- juf_fault/wrongargs -->
<DT><CODE><INDEX NAME=vr><EP>wrongargs</INDEX></CODE>
<DD><CODE>wrong # args: should be "%s"</CODE>
</DL>
</DL>
The following error handling functions concatenates the given arguments
together with
the <SAMP>: </SAMP> separator string between them. The scriptname is
prepended if running non-interactively.
<DL>
<DT><CODE><INDEX NAME=fn><EP>fatal</INDEX></CODE> [<VAR>ARGS</VAR>...]
<DD>Prints an error message on <CODE>stderr</CODE> and exits the current
process.
<DT><CODE><INDEX NAME=fn><EP>error</INDEX></CODE> [<VAR>ARGS</VAR>...]
<DD>Print an error message on <CODE>stderr</CODE>.
<DT><CODE><INDEX NAME=fn><EP>warning</INDEX></CODE> [<VAR>ARGS</VAR>...]
<DD>Print an error message on <CODE>stderr</CODE> with the text "warning"
preprended.
</DL>
<P>
Only one error evaluation function exists by now:
<DL>
<DT><CODE><INDEX NAME=fn><EP>tclmsg</INDEX></CODE>
<DD>Evaluates the Tcl variable
<CODE><INDEX NAME=vr><EP>errorCode</INDEX></CODE>
and generates an appropriate error message.
</DL>
This is useful for reporting errors on file operations:
<EXAMPLE>
package require Error
if {[catch "open [lindex $argv 0]" fileid] != 0} {
Juf::Error::fatal [lindex $argv 0] [Juf::Error::tclmsg]
}
</EXAMPLE>
</SECTION> <!-- Error -->
<SECTION><!--
***********************
Command Line Processing
***********************
--><TITLE>Command Line Processing</TITLE>
<P>
<SECTION><!--
=====================
Option Specifications
=====================
--><TITLE>Option Specifications</TITLE>
<DESCR>How to specify and describe an option</DESCR>
The <REF NAME=getopts><CODE>juf_getopts</CODE></REF> function and the
<REF NAME=listopts><CODE>juf_getopts_listspecs</CODE></REF> function expect
a list of <DFN><LABEL NAME=optspecs>option specifications</LABEL></DFN> as
one of their arguments.
<P>
Each option specification
consists of an option processing description, an option description and an
argument description. Only the processing description is mandatory. The other
two elements of a option specification are optional and evaluated only by
the <CODE>juf_getopts_listspecs</CODE> function.
<SECTION><!--
:::::::::::::::::::::::::::::
Option Processing Description
:::::::::::::::::::::::::::::
--><TITLE>Option Processing Description</TITLE>
Each option can be specified through usage of different names, e.g.
<CODE>-h</CODE> and <CODE>&com;help</CODE>. The processing description
starts with these names, concatenated by the
<CODE><INDEX NAME=cp><EP>|</INDEX></CODE>-sign.
</SECTION> <!-- Option Processing Description -->
</SECTION> <!-- Option Specifications -->
<SECTION><!--
==============
Option Listing
==============
--><TITLE>Option Listing</TITLE>
An option listing can be produced with the <CODE>juf_getopts_listspecs</CODE>
function:
<DL>
<DT><CODE><LABEL NAME=listopts><INDEX NAME =fn><EP>
juf_getopts_listspecs</INDEX></LABEL></CODE> <VAR>OPTSPECS</VAR>
<VAR>OUTID</VAR>
<DD>
Writes a option listing to the file bound to the file identifier
<VAR>OUTID</VAR>. Expects as <VAR>OPTSPECS</VAR> a list of
<REF NAME=optspecs>option specifications</REF>.
</DL>
</SECTION> <!-- Option Listing -->
<SECTION><!--
=================
Option Processing
=================
--><TITLE>Option Processing</TITLE>
<DL>
<DT><CODE><LABEL NAME=getopts><INDEX NAME =fn>
<EP>juf_getopts</INDEX></LABEL></CODE> <VAR>OPTSPECS</VAR> <VAR>OPTARR</VAR>
<VAR>NEWARGV</VAR> <VAR>OLDARGV</VAR>
<DD>Processes the command line arguments in <VAR>OLDARGV</VAR>. Any options
(preceded with <SAMP>-</SAMP> or <SAMP>&com;</SAMP>) are evaluated according to
the <REF NAME=optspecs>option specifications</REF> <VAR>OPTSPECS</VAR>.
This function stores the remaining arguments in the array <VAR>OPTARR</VAR>.
</DL>
</SECTION> <!-- Option Processing -->
<SECTION><!--
========
Examples
========
--><TITLE>Examples</TITLE>
<INDEX NAME=CP>option specifications<SUBI>base set</INDEX>
I recommend the following set of option specifications as base set (make
sure to replace <CODE>make</CODE> with the actual script name):
<EXAMPLE>
{{help|h {Print this message and exit.}}
{version|v {Print the version number of make and exit}}}
</EXAMPLE>
</SECTION> <!-- Examples -->
</SECTION> <!-- Command Line Processing -->
<SECTION><!--
**********************
New Control Structures
**********************
--><TITLE>New Control Structures</TITLE>
<INDEX NAME=cp>control structures</INDEX>
<DFN>Control structures</DFN> are commands that direct the flow of control
like the Tcl builtins <CODE>if</CODE>, <CODE>while</CODE> and
<CODE>switch</CODE>.
<DL><!-- juf_branch -->
<DT><CODE><INDEX NAME=fn><EP>juf_branch</INDEX></CODE>
<VAR>VALUE</VAR> [<VAR>PATTERN</VAR> <VAR>SCRIPT</VAR>] ...
2<DD>Creates and evaluates <CODE><INDEX NAME=fn><EP>switch</INDEX></CODE>
statement. Causes error if <VAR>VALUE</VAR> matches with none of the
<VAR>PATTERN</VAR> arguments. To override this behaviour you may add
<CODE>default {}</CODE> to the arguments.
</DL>
Example for this command:
<EXAMPLE>
% proc version {subcmd number} {
set parts [split $number .]
juf_branch $subcmd major {lindex $parts 0} minor {lindex $parts 1} \
minuscule {lindex $parts 2}
}
% version minor 1.2.3
2
% version patch 1.2.3
bad option "patch": must be major, minor, or minuscule
</EXAMPLE>
</SECTION> <!-- New Control Structures -->
<SECTION><!--
******
String
******
--><TITLE><INDEX NAME=pkg><EP>String</INDEX></TITLE>
<DESCR>String manipulation functions</DESCR>
The functions provided by the <CODE>String</CODE> package perform several
operations on array variables:
<DL>
<!-- juf_split -->
<DT><CODE><INDEX NAME=fn><EP>juf_split</INDEX></CODE>
[<VAR>OPTIONS</VAR>] <VAR>STRING</VAR> [<VAR>EXP</VAR> <VAR>LIMIT</VAR>]
<DD>Returns a list created by splitting <VAR>STRING</VAR> at each
match of the regular expression <VAR>EXP</VAR>. If <VAR>EXP</VAR> is omitted
or an empty string is given, it defaults to whitespace. If <VAR>LIMIT</VAR>
is given, it stops the matching process, so that the size of the resulting
list is equal or lesser than <VAR>LIMIT</VAR>.
<P>
A regular expression matching the <INDEX NAME=CP><EP>null string</INDEX>
will split <VAR>STRING</VAR> into separate characters at each point it
matches that way:
<EXAMPLE>
% juf_split "hello world" " *"
h e l l o w o r l d
</EXAMPLE>
If the initial arguments to <CODE>juf_split</CODE> start with <SAMP>-</SAMP>,
they are treated as options. The following options are supported:
<DL>
<DT><CODE><INDEX NAME=CP><EP>-showempty</INDEX></CODE>
<DD>Adds an empty element to the list for each match of the regular
expression:
<EXAMPLE>
% juf_split -showempty {\|\|bla\|arg\|rab\|} {\\\|}
{} {} bla {} arg {} rab {}
</EXAMPLE>
<DT><CODE>&com;</CODE>
<DD>Marks the end of the options. The argument following this one will be
treated as <VAR>STRING</VAR> even if it starts with a <SAMP>-</SAMP>.
</DL>
<!-- juf_compose -->
<DT><CODE><INDEX NAME=fn><EP>juf_compose</INDEX></CODE>
<VAR>STRING</VAR> <VAR>NUMBER</VAR>
<DD>Composes a string of <VAR>NUMBER</VAR> times of <VAR>STRING</VAR>.
<!-- juf_strcasecmp -->
<DT><CODE><INDEX NAME=fn><EP>juf_strcasecmp</INDEX></CODE>
<VAR>STRING1</VAR> <VAR>STRING2</VAR>
<INDEX NAME=CP>strings<SUBI>comparing<SUBI>case insensitive</INDEX>
<DD>Performs a case insensitive string comparison.
Returns -1, 0, or 1, depending on whether <VAR>STRING1</VAR> is
considered less than, equal to, or greater than <VAR>STRING2</VAR>.
<!-- juf_string_count -->
<DT><CODE><INDEX NAME=fn><EP>juf_string_count</INDEX></CODE>
<VAR>STRING</VAR> [<VAR>ARRNAME</VAR>]
<DD>Returns the number of different characters in <VAR>STRING</VAR>.
If <VAR>ARRNAME</VAR> is given, an array <VAR>ARRNAME</VAR> will
be created with characters as keys and character counts as values.
<EXAMPLE>
% juf_string_count example count
6
% array get count
l 1 p 1 x 1 m 1 a 1 e 2
</EXAMPLE>
</DL>
</SECTION> <!-- Strings -->
<SECTION><!--
*****
Lists
*****
--><TITLE>Lists</TITLE>
<DESCR>How to manipulate lists</DESCR>
Jultaf provides two packages working on lists, <CODE>Sequence</CODE> for all
lists and <CODE>LOL</CODE> for lists inside of lists.
<SECTION><!--
========
Sequence
========
--><TITLE><INDEX NAME=pkg><EP>Sequence</INDEX></TITLE>
<DESCR>Generic list operations</DESCR>
The functions provided by the <CODE>Sequence</CODE> package perform several
operations on lists:
<DL>
<!-- Juf::Sequence::shift -->
<DT><CODE>Juf::Sequence::<INDEX NAME=fn><EP>shift</INDEX></CODE> <VAR>NAME</VAR>
[<VAR>COUNT</VAR>]
<INDEX NAME=CP>lists<SUBI>removing elements<SUBI>Juf::Sequence::shift</INDEX>
<INDEX NAME=CP>removing list elements<SUBI>Juf::Sequence::shift</INDEX>
<DD>Removes <VAR>COUNT</VAR> element from the list stored in the variable
<VAR>NAME</VAR> and returns the last element removed.
<VAR>COUNT</VAR> defaults to 1.
<!-- Juf::Sequence::pop -->
<DT><CODE>Juf::Sequence::<INDEX NAME=fn><EP>pop</INDEX></CODE> <VAR>NAME</VAR>
[<VAR>COUNT</VAR>]
<INDEX NAME=CP>lists<SUBI>removing elements<SUBI>Juf::Sequence::pop</INDEX>
<INDEX NAME=CP>removing list elements<SUBI>Juf::Sequence::pop</INDEX>
<DD>Removes <VAR>COUNT</VAR> element from the end of the list stored in the variable <VAR>NAME</VAR> and returns the last element removed.
<VAR>COUNT</VAR> defaults to 1.
<!-- Juf::Sequence::append -->
<DT><CODE>Juf::Sequence::<INDEX NAME=fn><EP>append</INDEX></CODE>
[<VAR>OPTION</VAR> ...] <VAR>NAME</VAR> [<VAR>VALUE</VAR> ...]
<INDEX NAME=CP>lists<SUBI>appending elements</INDEX>
<INDEX NAME=CP>appending list elements</INDEX>
<DD>Works like the Tcl builtin
<CODE><INDEX NAME=fn><EP>lappend</INDEX></CODE>, but considers
these options:
<DL>
<DT><CODE><INDEX NAME=cp><EP>-nonempty</INDEX></CODE>
<DD>Append only non-empty values.
<DT><CODE>&com;</CODE>
<DD>Marks the end of the options. The argument following this one will be
treated as <VAR>NAME</VAR> even if it starts with a <SAMP>-</SAMP>.
</DL>
<!-- Juf::Sequence::assign -->
<DT><CODE>Juf::Sequence::<INDEX NAME=fn><EP>assign</INDEX></CODE>
<VAR>LIST</VAR> [<VAR>NAME</VAR> ...]
<DD>Sets value of the variables specified by the <VAR>NAME</VAR> arguments to
that of the existing elements of <VAR>LIST</VAR>. Returns remaining list
elements. If the number of variables exceeds the list length,
the remaining variables will be removed.
</DL>
</SECTION> <!-- Sequence -->
<SECTION><!--
===
LOL
===
--><TITLE><INDEX NAME=pkg>LOL</INDEX>List of Lists</TITLE>
<DESCR>Operations on nested lists</DESCR>
<INDEX NAME=cp>list of lists</INDEX>
Each hierarchy level is a list with keys as odd elements and inferior lists
as even elements. The empty string is a special key. The accompanying element
is list of values instead of a inferior list.
<DL>
<!-- insert -->
<DT><CODE><INDEX NAME=fn><EP>insert</INDEX></CODE>
<IMG SRC=new.gif ALT="*NEW*">
<IMG SRC=exp.gif ALT="*EXPERIMENTAL*">
<VAR>NAME</VAR> <VAR>LIST</VAR> <VAR>VALUE</VAR>
<DD>Inserts <VAR>VALUE</VAR> into list of lists stored within variable
<VAR>NAME</VAR> as specified by the keys <VAR>LIST</VAR>.
<EXAMPLE>
% package require LOL
% set grplist ""
% Juf::LOL::insert grplist "Development Languages Tcl" Jultaf
Development {Languages {Tcl {{} Jultaf}}}
</EXAMPLE>
</DL>
</SECTION> <!-- LOL -->
</SECTION> <!-- Lists -->
<SECTION><!--
*****
Array
*****
--><TITLE><INDEX NAME=pkg><EP>Array</INDEX></TITLE>
<DESCR>Array manipulation functions</DESCR>
The functions provided by the <CODE>Array</CODE> package perform several
operations on array variables:
<DL>
<!-- values -->
<DT><CODE><INDEX NAME=fn><EP>values</INDEX></CODE>
[<VAR>SWITCH</VAR> ...] [<VAR>NAME</VAR> ...]
<DD><INDEX NAME=CP>arrays<SUBI>list of values</INDEX>
Returns a list containing the values of all of the elements in the
array(s) specified by the <VAR>NAME</VAR> arguments. If invoked with the
<CODE><INDEX NAME=FN>values<SUBI><EP>-unique</INDEX></CODE>
switch, a specific value appears only once in the list.
<EXAMPLE>
% array set test {whiskey drink beer drink fish food}
% Juf::Array::values test
drink food drink
% Juf::Array::values -unique test
drink food
</EXAMPLE>
<!-- sort -->
<DT><CODE><INDEX NAME=fn><EP>sort</INDEX></CODE>
<VAR>NAME</VAR>
<DD><INDEX NAME=CP>arrays<SUBI>sorting<SUBI>by value</INDEX>
Returns list of element names of array <VAR>NAME</VAR>,
sorted according to the element values.
<EXAMPLE>
% array set test {whiskey drink beer drink fish food}
% Juf::Array::sort test
whiskey beer fish
</EXAMPLE>
</DL>
</SECTION> <!-- Array -->
<SECTION><!--
*****
Files
*****
--><TITLE>Files</TITLE>
<DESCR>File manipulation functions</DESCR>
<DL>
<!-- juf_file_slurp -->
<DT><CODE><INDEX NAME=fn><EP>juf_file_slurp</INDEX></CODE>
<VAR>FILE</VAR> <VAR>NAME</VAR>
<INDEX NAME=CP>files<SUBI>reading</INDEX>
<DD>Reads complete FILE into variable NAME.
Returns 1 in case of success, 0 otherwise.
<!-- juf_file_mkdirs -->
<DT><CODE><INDEX NAME=fn><EP>juf_file_mkdirs</INDEX></CODE>
[<VAR>DIR</VAR> ...]
<INDEX NAME=CP>directories<SUBI>creating</INDEX>
<DD>Creates all directories given as arguments. Any
missing parent directories are created too. Considers an existing argument
directory not as an error.
<!-- juf_file_iscwd -->
<DT><CODE><INDEX NAME=fn><EP>juf_file_iscwd</INDEX></CODE>
<VAR>FILENAME</VAR>
<DD>Checks if <VAR>FILENAME</VAR> corresponds to the
<INDEX NAME=CP><EP>current working directory</INDEX>.
Returns 1 if successful, 0 otherwise.
</DL>
<SECTION><!--
======================
File Name Manipulation
======================
--><TITLE>File Name Manipulation</TITLE>
<SHORT>File Names</SHORT>
<DESCR>Dealing with <INDEX NAME=cp><EP>file names</INDEX></DESCR>
<DL>
<!-- juf_file_expand -->
<DT><INDEX NAME=cp>expanding file names</INDEX>
<INDEX NAME=cp>file names<SUBI>expanding</INDEX>
<CODE><LABEL NAME=expand INDEX=fn>juf_file_expand</LABEL></CODE>
<VAR>NAME</VAR> [<VAR>DIR</VAR>]
<IMG SRC=new.gif ALT="*NEW*">
<IMG SRC=exp.gif ALT="*EXPERIMENTAL*">
<DD><INDEX NAME=cp>file names<SUBI>absolute</INDEX>
<INDEX NAME=cp>absolute<SUBI>file names</INDEX>
Converts file name NAME to the corresponding absolute filename,
<INDEX NAME=cp>tilde substitution</INDEX>
<INDEX NAME=cp>substitution<SUBI>tilde</INDEX>
performs tilde substitution and returns the result. Please note that
<SAMP>..</SAMP> and <SAMP>.</SAMP> will not expanded (yet).
If <VAR>NAME</VAR> is a relative name, the function assumes that
<VAR>DIR</VAR> is the directory where the file corresponding to
<VAR>NAME</VAR> resides in. In the case that no value for <VAR>DIR</VAR> is
passed, the current working directory is used.
</DL>
</SECTION> <!-- File Name Manipulation -->
<SECTION><!--
=============
Finding Files
=============
--><TITLE>Finding Files</TITLE>
<SHORT>find</SHORT>
<INDEX NAME=CP>files<SUBI>searching</INDEX>
<INDEX NAME=CP>searching files</INDEX>
This section describes the procedure
<CODE><INDEX NAME=FN><EP>find</INDEX></CODE>, which
searches for files matching certain criteria.
<CODE>find</CODE> is available only if Jultaf has been configured with
<CODE><REF NAME="enable-itcl">&com;enable-itcl</REF></CODE>.
<P>
<CODE>find</CODE> expects as arguments any number of "directory trees" and
options with or without values. The procedure searches all files in the
given directory trees and returns all files that matches the criteria
specified by the options. A
<DFN><INDEX NAME=CP><EP>directory tree</INDEX></DFN> is a directory and the
files it contains, all of its subdirectories and the files they contain,
etc. It can also be a single non-directory file.
<P>
Valid options are:
<DL>
<!-- name -->
<DT><CODE>-name</CODE> <VAR>PATTERN</VAR>
<DD>Qualifies files that match <VAR>PATTERN</VAR> in a <CODE>string
match</CODE>-like fashion. Only the last component of the file name is
considered for the match.
<!-- type -->
<DT><CODE>-type</CODE> <VAR>CHAR</VAR>
<DD>Qualifies files that are of type <VAR>CHAR</VAR>:
<DL>
<!-- type/b -->
<DT><CODE>b</CODE><DD>block (buffered) special
<!-- type/c -->
<DT><CODE>c</CODE><DD>character (buffered) special
<!-- type/d -->
<DT><CODE>d</CODE><DD>directory
<!-- type/f -->
<DT><CODE>f</CODE><DD>regular file
<!-- type/l -->
<DT><CODE>l</CODE><DD>
<INDEX NAME=CP>symbolic link</INDEX>
<INDEX NAME=CP>link<SUBI>symbolic</INDEX>
symbolic link
<!-- type/p -->
<DT><CODE>p</CODE><DD>
<INDEX NAME=CP>named pipe</INDEX>
<INDEX NAME=CP>FIFO</INDEX>
<INDEX NAME=CP>pipe<SUBI>named</INDEX>
pipe (FIFO)
<!-- type/s -->
<DT><CODE>s</CODE><DD><INDEX NAME=CP><EP>socket</INDEX>
</DL>
</DL>
</SECTION> <!-- Finding Files -->
</SECTION> <!-- Manipulating files -->
<SECTION><!--
***************
Code Processing
***************
--><TITLE>Code Processing</TITLE>
<DESCR>Evaluating Tcl code</DESCR>
<DL>
<!-- juf_safe_eval -->
<DT><CODE><INDEX NAME=fn><EP>juf_safe_eval</INDEX></CODE>
[<VAR>OPTIONS</VAR>] <VAR>SCRIPT</VAR>
<DD>
<INDEX NAME=cp>safe interpreter</INDEX>
<INDEX NAME=cp>temporary interpreter</INDEX>
<INDEX NAME=cp>interpreter<SUBI>safe</INDEX>
<INDEX NAME=cp>interpreter<SUBI>temporary</INDEX>
Evaluates <VAR>SCRIPT</VAR> as Tcl script in a temporary safe
interpreter and returns the result.
<P>
Valid options are:
<DL>
<!-- -aliases -->
<DT><CODE><INDEX NAME=CP><EP>-aliases</INDEX> <VAR>NAME</VAR></CODE>
<DD>Creates an <INDEX NAME=CP><EP>alias</INDEX> for each key in array
<VAR>NAME</VAR> within the safe interpreter.
<!-- -exit -->
<DT><CODE><INDEX NAME=CP><EP>-exit</INDEX> <VAR>COMMAND</VAR></CODE>
<DD><INDEX NAME=CP><EP>exit handler</INDEX><VAR>COMMAND</VAR> will be called
with the interpreter as argument after processing <VAR>SCRIPT</VAR>.
<!-- -interp -->
<DT><CODE><INDEX NAME=CP><EP>-interp</INDEX> <VAR>NAME</VAR></CODE>
<DD>Stores interpreter into variable <VAR>NAME</VAR>. Useful with the
<CODE>-unknown</CODE> option.
<!-- -nosafe -->
<DT><CODE><INDEX NAME=CP><EP>-nosafe</INDEX></CODE>
<DD>Use an ordinary slave interpreter.
<!-- -renames -->
<DT><CODE><INDEX NAME=CP><EP>-renames</INDEX> <VAR>NAME</VAR></CODE>
<DD>Renames commands stored as keys in array
<VAR>NAME</VAR> to the corresponding values within the safe interpreter.
<!-- -stats -->
<DT><CODE><INDEX NAME=CP><EP>-stats</INDEX> <VAR>NAME</VAR></CODE>
<DD>Fills array <VAR>NAME</VAR> with statistics:
<DL>
<DT><INDEX NAME=CP><EP>cmdcount</INDEX>
<DD>number of commands executed within the safe interpreter.
</DL>
<!-- -unknown -->
<DT><CODE><INDEX NAME=CP><EP>-unknown</INDEX> <VAR>NAME</VAR></CODE>
<DD>Function <VAR>NAME</VAR> will be called if the safe interpreter stumbles
over an unknown command.
<!-- -variables -->
<DT><CODE><INDEX NAME=CP><EP>-variables</INDEX> <VAR>NAME</VAR></CODE>
<DD>Creates a variable for each key in array <VAR>NAME</VAR> within the safe
interpreter. The initial value of the variable is the corresponding array
element.
<DT><CODE>&com;</CODE>
<DD>Marks the end of the options. The argument following this one will be
treated as <VAR>NAME</VAR> even if it starts with a <SAMP>-</SAMP>.
</DL>
<!-- juf_safe_source -->
<DT><CODE><INDEX NAME=fn><EP>juf_safe_source</INDEX></CODE>
[<VAR>OPTIONS</VAR>] <VAR>FILE</VAR> [<VAR>NAME</VAR>]
<DD>
<INDEX NAME=cp>source<SUBI>Tcl scripts</INDEX>
<INDEX NAME=cp>scripts<SUBI>evaluating</INDEX>
Evaluate <VAR>FILE</VAR> as Tcl script in a temporary safe interpreter.
Accepts the same options as <CODE>juf_safe_eval</CODE>.
</DL>
</SECTION> <!-- Code Processing -->
<SECTION><!--
*********************
Invoking subprocesses
*********************
--><TITLE>Invoking subprocesses</TITLE>
<DESCR>Shell interaction</DESCR>
The <INDEX NAME=cp><EP><CODE>shell</CODE> module</INDEX> consists only of
one function:
<DL>
<DT><CODE><INDEX NAME=fn><EP>juf_shell_run</INDEX></CODE> <VAR>args</VAR>
<DD>Passes its arguments to <CODE><INDEX NAME=fn><EP>exec</INDEX></CODE> and
returns 1 if successful, 0 otherwise.
</DL>
</SECTION> <!-- Invoking subprocesses -->
<SECTION><!--
************************
Accessing GDBM Databases
************************
--><TITLE>Accessing GDBM Databases</TITLE>
<SHORT>GNU dbm</SHORT>
<INDEX NAME=CP>databases<SUBI>GDBM</INDEX>
<INDEX NAME=CP>GDBM</INDEX>
<INDEX NAME=CP>GNU<SUBI>dbm</INDEX>
GNU dbm databases can be manipulated with the <CODE>juf_gdbm</CODE>
command. Note that this command is available only if Jultaf is
configured with the <REF NAME=withgdbm>&com;with-gdbm</REF> option.
<DL>
<!-- open -->
<DT><INDEX NAME=FN>juf_gdbm<SUBI>open</INDEX><CODE>juf_gdbm open</CODE>
<VAR>NAME</VAR> <VAR>FLAGS</VAR>
<DD>Opens database file <VAR>NAME</VAR> and returns database identifier.
The access mode is specified by <VAR>FLAGS</VAR>:
<DL>
<DT><SAMP>r</SAMP>
<DD>Database is opened for reading. Any call to <CODE>juf_gdbm</CODE>
with the options <CODE>delete</CODE> or <CODE>store</CODE> will fail.
<DT><SAMP>rw</SAMP>
<DD>Database is opened for reading and writing.
<DT><SAMP>rwc</SAMP>
<DD>Same as <CODE>rw</CODE>, if the database does not exist, a new one
will be created.
<DT><SAMP>rwn</SAMP>
<DD>Same as <CODE>rw</CODE>, a new database
will be created in any case.
</DL>
<!-- close-->
<DT><INDEX NAME=FN>juf_gdbm<SUBI>close</INDEX><CODE>juf_gdbm close</CODE>
<VAR>DBID</VAR>
<DD>Closes database specified by <VAR>DBID</VAR>.
<!-- store-->
<DT><INDEX NAME=FN>juf_gdbm<SUBI>store</INDEX><CODE>juf_gdbm store</CODE>
<VAR>DBID</VAR> <VAR>KEY</VAR> <VAR>VALUE</VAR>
<DD>Stores <VAR>KEY</VAR> with the associated <VAR>VALUE</VAR> in database
specified by <VAR>DBID</VAR>.
<!-- insert-->
<DT><INDEX NAME=FN>juf_gdbm<SUBI>insert</INDEX><CODE>juf_gdbm insert</CODE>
<VAR>DBID</VAR> <VAR>KEY</VAR> <VAR>VALUE</VAR>
<DD>Inserts <VAR>KEY</VAR> with the associated <VAR>VALUE</VAR> in database
specified by <VAR>DBID</VAR>. Generates an error if <VAR>KEY</VAR> exists
already.
<!-- fetch-->
<DT><INDEX NAME=FN>juf_gdbm<SUBI>fetch</INDEX><CODE>juf_gdbm fetch</CODE>
<VAR>DBID</VAR> <VAR>KEY</VAR>
<DD>Returns associated value for <VAR>KEY</VAR> in database
specified by <VAR>DBID</VAR>. If <VAR>KEY</VAR> doesn't exist, a empty
string is returned.
<!-- delete -->
<DT><INDEX NAME=FN>juf_gdbm<SUBI>delete</INDEX><CODE>juf_gdbm delete</CODE>
<VAR>DBID</VAR> <VAR>KEY</VAR>
<DD>Removes <VAR>KEY</VAR> from database
specified by <VAR>DBID</VAR>.
<!-- exists -->
<DT><INDEX NAME=FN>juf_gdbm<SUBI>exists</INDEX><CODE>juf_gdbm exists</CODE>
<VAR>DBID</VAR> <VAR>KEY</VAR>
<DD>Returns 1, if <VAR>KEY</VAR> exists in database
specified by <VAR>DBID</VAR>, 0 otherwise.
<!-- list -->
<DT><INDEX NAME=FN>juf_gdbm<SUBI>list</INDEX><CODE>juf_gdbm list</CODE>
<VAR>DBID</VAR>
<DD>Returns a list containing all keys in database
specified by <VAR>DBID</VAR>.
</DL>
</SECTION> <!-- Accessing GDBM Databases -->
<SECTION><!--
*************
RPM Interface
*************
--><TITLE>RPM Interface</TITLE>
<DL>
<!-- query -->
<DT><CODE><INDEX NAME=FN><EP>query</INDEX></CODE> <VAR>PACKAGE</VAR>
<VAR>TAG</VAR>
<DD>Queries <VAR>PACKAGE</VAR> for the value of <VAR>TAG</VAR>.
If a file <VAR>PACKAGE</VAR> doesn't exist, the RPM database will be searched
for <VAR>PACKAGE</VAR>. Supported tags are:
<DL>
<!-- NAME -->
<DT><CODE>name</CODE>
<DD>name of package
<!-- GROUP -->
<DT><CODE>group</CODE>
<DD>slash separated list of group names
</DL>
Queries looks like:
<EXAMPLE>
% package require RPM
% Juf::RPM::query rpm name
rpm
% Juf::RPM::query file group
Utilities/File
</EXAMPLE>
</DL>
</SECTION> <!-- RPM Interface -->
<SECTION><!--
***********************
Miscellaneous Functions
***********************
--><TITLE>Miscellaneous Functions</TITLE>
<DESCR>Functions not fitting elsewhere</DESCR>
<SHORT>Miscellaneous</SHORT>
<DL>
<!-- Juf::deprecate -->
<DT><CODE><INDEX NAME=fn>deprecate</INDEX>Juf::deprecate</CODE>
<VAR>OLD</VAR> <VAR>NEW</VAR>
<DD>Deprecates function <VAR>OLD</VAR> in favor of function <VAR>NEW</VAR>.
Maps <VAR>OLD</VAR> to <VAR>NEW</VAR> and prints error message at
the first call of <VAR>OLD</VAR>.
<EXAMPLE>
% package require Jufbase
% 0.0.4
Juf::deprecate juf_compose Juf::String::compose
% juf_compose foo 5
juf_compose: deprecated function
foofoofoofoofoo
</EXAMPLE>
<!-- juf_misc_scriptname -->
<DT><CODE><INDEX NAME=fn><EP>juf_misc_scriptname</INDEX></CODE>
<DD>Returns name of the current <INDEX NAME=CP><EP>script</EP> name</INDEX>
with leading directories and extension(s) removed.
<!-- juf_misc_shell -->
<DT><CODE><INDEX NAME=fn><EP>juf_misc_shell</INDEX></CODE> [<VAR>PROMPT</VAR>]
<DD>Displays the prompt given in <VAR>PROMPT</VAR> which defaults to "% "
and evaluates the user input in the current interpreter until the user types
<CODE>exit</CODE> or the demanded command invokes the <CODE>exit</CODE>
command.
<INDEX NAME=CP>testing<SUBI>libraries</INDEX>
<INDEX NAME=CP>testing<SUBI>Tcl applications</INDEX>
This command is very useful for testing libraries and/or Tcl
applications. The following script can be adapted to your needs:
<EXAMPLE>
#!/usr/bin/tclsh
lappend auto_path "/usr/share/jultaf"
juf_misc_shell "jultaflib% "
</EXAMPLE>
</DL>
</SECTION> <!-- Miscellaneous Functions -->
<SECTION><!--
**************
Package Index
**************
--><TITLE>Package Index</TITLE>
<SHORT>Packages</SHORT>
<DESCR>Index of Jultaf´s Packages</DESCR>
<INSERTINDEX NAME=pkg>
</SECTION> <!-- Package Index -->
<SECTION><!--
**************
Variable Index
**************
--><TITLE>Variable Index</TITLE>
<INSERTINDEX NAME=vr>
</SECTION> <!-- Variable Index -->
<SECTION><!--
**************
Function Index
**************
--><TITLE>Function Index</TITLE>
<INSERTINDEX NAME=fn>
</SECTION> <!-- Function Index -->
<SECTION><!--
*************
Concept Index
*************
--><TITLE>Concept Index</TITLE>
<INSERTINDEX NAME=cp>
</SECTION> <!-- Concept Index -->