Full Documentation: Basic Procedures

Library version 9.4.3



abkform.icn: Procedures to process HP95LX appointment books

link abkform
May 2, 2001; Robert J. Alexander
See also: bkutil.icn, pbkform.icn
This file is in the public domain.

 Procedures set to read and write HP95LX appointment book (.abk) files.


Notes:

1. Files created by the Appointment Book application may contain
some padding following the last field of some data records.  Hence,
the RecordLength field must be used to determine the start of the
next record.  Appointment book files created by other programs need not
have any padding.

2. ApptState has several bit fields.  Only bit 0 is meaningful to software
processing an appointment book file.  Bit 0 being set or cleared
corresponds to the alarm being enabled or disabled, respectively.
Programs creating Appointment book files should clear all bits, except
perhaps bit 0.

3. ToDoState has two one-bit bit fields.  Bit 0 being set or cleared
corresponds to carry forward being enabled or disabled for this todo
item, respectively.  Bit 1 being set or cleared corresponds to the doto
being checked off or not checked off, respectively.

4. Appointment and ToDo texts are each limited to a maximum of 27
characters.

5. Note text is limited to a maximum of 11 lines of 39 characters per line
(not counting the line terminator).

[ Summary entry | Source code ]


adjuncts.icn: Procedures for gettext and idxtext

procedure Set_OS:          set global OS features
procedure Basename:        obtain base filename
procedure Pathname:        obtain path of filename
procedure getidxname:      obtain index from datafile name
procedure Strip:           remove chars from string

link adjuncts
June 21, 2000; Richard L. Goerwitz
See also: gettext.icn, idxtext,icn
This file is in the public domain.

Pretty mundane stuff.  Set_OS(), Basename(), Pathname(), Strip(), and
   a utility for creating index filenames.

[ Summary entry | Source code ]


adlutils.icn: Procedures to process address lists

link adlutils
January 3, 1994; Ralph E. Griswold
This file is in the public domain.

Procedures used by programs that process address lists:

   nextadd()              get next address
   writeadd(add)          write address
   get_country(add)       get country
   get_state(add)         get state (U.S. addresses only)
   get_city(add)          get city (U.S. addresses only)
   get_zipcode(add)       get ZIP code (U.S. addresses only)
   get_lastname(add)      get last name
   get_namepfx(add)       get name prefix
   get_title(add)         get name title
   format_country(s)      format country name

[ Summary entry | Source code ]


allof.icn: Procedure for conjunction control operation

link allof
April 28, 1990; Robert J. Alexander
Requires: co-expressions
This file is in the public domain.

allof{expr1,expr2} -- Control operation that performs iterative
                      conjunction.

   Iterative conjunction permits a conjunction expression to be built
at run time which supports full backtracking among the created terms
of the expression.  The computed expression can be of arbitrary
length, and is built via an iterative loop in which one term is
appended to the expression (as if connected with a "&" operator) per
iteration.

   Expr1 works like the control expression of "every-do"; it controls
iteration by being resumed to produce all of its possible results.
The allof{} expression produces the outcome of conjunction of all of
the resulting instances of expr2.

   For example:

     global c
     ...
     pattern := "ab*"
     "abcdef" ? {
        allof { c := !pattern ,
           if c == "*" then move(0 to *&subject - &pos + 1) else =c
           } & pos(0)
        }

This example will perform a wild card match on "abcdef" against
pattern "ab*", where "*" in a pattern matches 0 or more characters.
Since pos(0) will fail the first time it is evaluated, the allof{}
expression will be resumed just as a conjunction expression would,
and backtracking will propagate through all of the instances of
expr2; the expression will ultimately succeed (as its conjunctive
equivalent would).

   Note that, due to the scope of variables in co-expressions,
variables shared between expr1 and expr2 must have global scope,
hence c in the above example must be global.

   The allof{} procedure models Icon's expression evaluation
mechanism in that it explicitly performs backtracking.  The author of
this procedure knows of no way to invoke Icon's built-in goal
directed evaluation to perform conjunction of a arbitrary number of
computed expressions (suggestions welcome).

[ Summary entry | Source code ]


allpat.icn: Procedure to produce all n-character patterns of characters

link allpat
May 14, 1996; Ralph E. Griswold
Requires:
This file is in the public domain.


[ Summary entry | Source code ]


ansi.icn: Procedures for ANSI-based terminal control

link ansi
August 14, 1996; Ralph E. Griswold and Richard Goerwitz
This file is in the public domain.

   This package of procedures implements a subset of the ANSI terminal
control sequences.  The names of the procedures are taken directly from
the ANSI names.  If it is necessary to use these routines with non-ANSI
devices, link in iolib.icn, and (optionally) iscreen.icn as well.  Use
will be made of whatever routines are made available via either of these
libraries.  Be careful of naming conflicts if you link in iscreen.icn.
It contains procedures like "clear" and "boldface."

      CUB(i)         Moves the cursor left i columns
      CUD(i)         Moves the cursor down i rows
      CUF(i)         Moves the cursor right i columns
      CUP(i,j)       Moves the cursor to row i, column j
      CUU(i)         Moves the cursor up i rows
      ED(i)          Erases screen: i = 0, cursor to end; i = 1,
                        beginning to cursor; i = 2, all (default 2)
      EL(i)          Erases data in cursor row: i = 0, cursor to
                        end; i = 1, beginning to cursor; i = 2, all
                        (default 0)
      SGR(i)         Sets video attributes: 0 = off; 1 = bold; 4 =
                        underscore; 5 = blink; 7 = reverse (default
                        0)

   Note that not all so-called ANSI terminals support every ANSI
screen control sequence - not even the limited subset included in
this file.

   If you plan on using these routines with non-ANSI magic-cookie
terminals (e.g. a Wyse-50) then it is strongly recommended that you
link in iolib or itlib *and* iscreen (not just iolib or itlib by
itself).  The routines WILL WORK with most magic cookie terminals;
they just don't always get all the modes displayed (because they
are basically too busy erasing the cookies).

[ Summary entry | Source code ]


apply.icn: Procedure to apply a list of functions to an argument

link apply
March 4, 1995; Ralph E. Griswold
This file is in the public domain.

This procedure applies a list of functions to an argument.  An example is

     apply([integer, log], 10)

which is equivalent to integer(log(10)).

[ Summary entry | Source code ]


argparse.icn: Procedure to parse pseudo-command-line

link argparse
November 14, 1991; Ralph E. Griswold
This file is in the public domain.

argparse(s) parses s as if it were a command line and puts the components in
in a list, which is returned.

At present, it does not accept any escape conventions.

[ Summary entry | Source code ]


array.icn: Procedures for n-dimensional arrays

link array
April 30, 1993; Ralph E. Griswold
This file is in the public domain.

create_array([lbs], [ubs], value) creates a n-dimensional array
with the specified lower bounds, upper bounds, and with each array element
having the specified initial value.

ref_array(A, i1, i2, ...) references the i1-th i2-th ... element of A.

[ Summary entry | Source code ]


asciinam.icn: Procedure for ASCII name of unprintable character

link asciinam
August 14, 1996; Robert J. Alexander
This file is in the public domain.

asciiname(s) returns the mnemonic name of the single unprintable
ASCII character s.

[ Summary entry | Source code ]


base64.icn: Procedures for base64 encodings for MIME (RFC 2045)

procedure base64encode:    encode a string into base 64 (MIME)
procedure base64decode:    decode a string from base 64 (MIME)

link base64
May 2, 2001; David A. Gamey
This file is in the public domain.

Descriptions:

base64encode( s1 ) : s2

   returns the base64 encoding of a string s1

base64decode( s1 ) : s2

   returns the base64 decoding of a string s1
   fails if s1 isn't base64 encoded

references:  MIME encoding Internet RFC 2045

[ Summary entry | Source code ]


basename.icn: Procedures to produce base name of a file

procedure basename:        base name of file

link basename
September 22, 1998; Ralph E. Griswold
Contributor: Charles Shartsis
This file is in the public domain.

This procedure is based on the UNIX basename(1) utility.  It strips off
any path information and removes the specified suffix, if present.

If no suffix is provided, the portion of the name up to the first
"." is returned.

It should work under UNIX, MS-DOS, and the Macintosh.

[ Summary entry | Source code ]


binary.icn: Procedures to pack and unpack values

procedure pack:            pack values into a string
procedure unpack:          unpack values from string

link binary
August 14, 1996; Robert J. Alexander
This file is in the public domain.

This is a collection of procedures that support conversion of Icon
data elements to and from binary data formats.  The purpose is to
facilitate dealing with binary data files.

The procedures can be used individually or via the "control"
procedures pack() and unpack().
____________________________________________________________

The individual conversion functions are prefixed by either "pack_" or
"unpack_" and are identified in comments by their format character(s).
The "pack_" procedures convert from Icon to binary and take a single
argument:  the value to be converted.  The "unpack_" procedures
convert from binary to Icon and usually take no parameters -- they are
executed within a string-scanning context and scan the necessary
amount from the &subject string.  Some of the "unpack_" functions take
a parameter that specifies the length of the output string.  The
individual conversion procedures are minimally commented, but their
action is apparent from their procedure names and the documentation
of the pack() and unpack() procedures.

The control procedures pack() and unpack() take a format string that
controls conversions of several values (similar to the "printf" C
library function).  pack() and unpack() are patterned after the Perl
(programming language) functions of the same names, and are documented
below.


pack(template,value1,...) : packed_binary_string
------------------------------------------------

This procedure packs the "values" into a binary structure, returning
the string containing the structure.  The elements of any lists in the
"value" parameters are processed individually as if they were
"spliced" into the "value" parameter list.  The "template" is a
sequence of characters that give the order and type of values, as
follows" (using C language terminology):

  a  An ascii string, will be null padded (unstripped for unpack()).
  A  An ascii string, will be space padded (trailing nulls and
     spaces will be stripped for unpack()).
  b  A bit string, low-to-high order.
  B  A bit string, high-to-low order.
  h  A hexadecimal string, low-nybble-first.
  H  A hexadecimal string, high-nybble-first.
  c  A signed char value.
  C  An unsigned char value.
  s  A signed short value.
  S  An unsigned short value.
  i  A signed int value.
  I  An unsigned int value.
  l  A signed long value.
  L  An unsigned long value.
  n  A short in "network" order (big-endian).
  N  A long in "network" order (big-endian).
  v  A short in "vax" order (little-endian).
  V  A long in "vax" order (little-endian).
  f  A single-precision float in IEEE Motorola format.
  d  A double-precision float in IEEE Motorola format.
  e  An extended-precision float in IEEE Motorola format 80-bit.
  E  An extended-precision float in IEEE Motorola format 96-bit.
  x  Skip forward a byte (null-fill for pack()).
  X  Back up a byte.
  @  Go to absolute position (null-fill if necessary for pack()).
  u  A uu-encoded/decoded string.

Each letter may optionally be followed by a number which gives a
count.  Together the letter and the count make a field specifier.
Letters and numbers can be separated by white space which will be
ignored.  Types A, a, B, b, H, and h consume one value from the
"value" list and produce a string of the length given as the
field-specifier-count.  The other types consume
"field-specifier-count" values from the "value" list and append the
appropriate data to the packed string.


unpack(template,string) : value_list
------------------------------------

This procedure does the reverse of pack():  it takes a string
representing a structure and expands it out into a list of values.
The template has mostly the same format as for pack() -- see pack(),
above.


Endianicity of integers
-----------------------

Integer values can be packed and unpacked in either big-endian
(Motorola) or little-endian (Intel) order.  The default is big-endian.
Procedures pack_little_endian() and pack_big_endian() set the
mode for future packs and unpacks.


Size of ints
------------

The "i" (signed int) and "I" (unsigned int) types can pack and unpack
either 16-bit or 32-bit values.  32-bit is the default.  Procedures
pack_int_as_short() and pack_int_as_long() change the mode for
future packs and unpacks.

[ Summary entry | Source code ]


bincvt.icn: Procedures to convert binary data

link bincvt
October 16, 1996; Robert J. Alexander
This file is in the public domain.

unsigned() -- Converts binary byte string into unsigned integer.
Detects overflow if number is too large.

This procedure is normally used for processing of binary data
read from a file.

raw() -- Puts raw bits of characters of string s into an integer.  If
the size of s is less than the size of an integer, the bytes are put
into the low order part of the integer, with the remaining high order
bytes filled with zero.  If the string is too large, the most
significant bytes will be lost -- no overflow detection.

This procedure is normally used for processing of binary data
read from a file.

rawstring() -- Creates a string consisting of the raw bits in the low
order "size" bytes of integer i.

This procedure is normally used for processing of binary data
to be written to a file.

[ Summary entry | Source code ]


binop.icn: Procedure to apply binary operation to list of values

procedure binop:           apply binary operation

link binop
July 15, 1995; Ralph E. Griswold
This file is in the public domain.

This procedure applies a binary operation to a list of arguments.
For example,

     binop("+", 1, 2, 3)

returns 6.

[ Summary entry | Source code ]


bitint.icn: Procedures to convert integers and bit strings

link bitint
May 25, 1994; Ralph E. Griswold
This file is in the public domain.

int2bit(i) produces a string with the bit representation of i.

bit2int(s) produces an integer corresponding to the bit representation i.

[ Summary entry | Source code ]


bitstr.icn: Procedures for bits in Icon strings

link bitstr
August 14, 1996; Robert J. Alexander
See also: bitstrm.icn
This file is in the public domain.

Procedures for working with strings made up of numeric values
represented by strings of an arbitrary number of bits, stored without
regard to character boundaries.

In conjunction with the "large integers" feature of Icon, this
facility can deal with bitstring segments of arbitrary size.  If
"large integers" are not supported, bitstring segments (i.e.  the
nbits parameter of BitStringGet and BitStringPut) wider that the
integer size of the platform are likely to produce incorrect results.
____________________________________________________________

Usage of BitStringPut, by example:

     record bit_value(value, nbits)
     ...
     bitString := BitString("")
     while value := get_new_value() do       # loop to append to string
             BitStringPut(bitString, value.nbits, value.value)
     resultString := BitStringPut(bitString) # output any buffered bits

Note the interesting effect that BitStringPut(bitString), as well as
producing the complete string, pads the buffered string to an even
character boundary.  This can be dune during construction of a bit
string if the effect is desired.

The "value" argument defaults to zero.
____________________________________________________________

Usage of BitStringGet, by example:

     record bit_value(value, nbits)
     ...
     bitString := BitString(string_of_bits)
     while value := BitStringGet(bitString, nbits) do
             # do something with value

BitStringGet fails when too few bits remain to satisfy a request.
However, if bits remain in the string, subsequent calls with fewer
bits requested may succeed.  A negative "nbits" value gets the value
of the entire remainder of the string, to the byte boundary at its
end.

[ Summary entry | Source code ]


bitstrm.icn: Procedures to read and write strings of bits in files

link bitstrm
August 14, 1996; Robert J. Alexander
See also: bitstr.icn
This file is in the public domain.

Procedures for reading and writing integer values made up of an
arbitrary number of bits, stored without regard to character
boundaries.
____________________________________________________________

Usage of BitStreamWrite, by example:

     record bit_value(value, nbits)
     ...
     BitStreamWrite()                        #initialize
     while value := get_new_value() do       # loop to output values
             BitStreamWrite(outfile, value.nbits, value.value)
     BitStreamWrite(outfile)                 # output any buffered bits

Note the interesting effect that BitStreamWrite(outproc), as well as
outputting the complete string, pads the output to an even character
boundary.  This can be dune during construction of a bit string if
the effect is desired.

The "value" argument defaults to zero.
____________________________________________________________

Usage of BitStreamRead, by example:

     BitStreamRead()
     while value := BitStreamRead(infile, nbits) do
             # do something with value

BitStringRead fails when too few bits remain to satisfy a request.

[ Summary entry | Source code ]


bkutil.icn: Procedures for HP95LX phone books and appointment books

link bkutil
August 14, 1996; Robert J. Alexander
See also: abkform.icn, pbkform.icn
This file is in the public domain.

Utility procedures for HP95LX phone book and appointment book processing.

[ Summary entry | Source code ]


bold.icn: Procedures to embolden and underscore text

link bold
March 25, 2002; Ralph E. Griswold
This file is in the public domain.

These procedures produce text with interspersed characters suit-
able for printing to produce the effect of boldface (by over-
striking) and underscoring (using backspaces).

     bold(s)        bold version of s

     uscore(s)      underscored version of s

[ Summary entry | Source code ]


boolops.icn: Procedure to perform Boolean operations on row patterns

procedure b01:             complement pattern
procedure b0110:           "xor" of two patterns
procedure b1000:           "and" of two patterns
procedure b1110:           "or" of two patterns

link boolops
June 26, 2002; Ralph E. Griswold
This file is in the public domain.

Limitation:  Assumes square patterns.

[ Summary entry | Source code ]


bufread.icn: Procedures for buffered read and lookahead

link bufread
March 11,1995; Charles A. Shartsis
This file is in the public domain.

Synopsis:

    bufopen(s)      Open a file name s for buffered read and lookahead
    bufread(f)      Read the next line from file f
    bufnext(f, n)   Return the next nth record from file f
                    without changing the next record to be read by
                    bufread
    bufclose(f)     Close file f
____________________________________________________________

These procedures provide a mechanism for looking ahead an
arbitrary number of records in an open file while still
keeping track of the logical current record and end-of-file.
Although similar in intent to the procedures in buffer.icn, these
procedures are used differently.  The procedures bufopen,
bufread, and bufclose were designed to closely mirror the
built-in open, read, and close.

A code segment like

        file := open("name", "r") | stop("open failed")
        while line := read(file) do {
            ...process current line...
        }
        close(file)

can be changed to the following with no difference in behavior:

        file := bufopen("name", "r") | stop("open failed")
        while line := bufread(file) do {
            ...process current line...
        }
        bufclose(file)

However in addition to processing the current line, one may
also process subsequent lines BEFORE they are logically
read:

        file := bufopen("name", "r") | stop("open failed")
        while line := bufread(file) do {
            ...process current line...
            line := bufnext(file,1) # return next line
            ...process next line...
            line := bufnext(file,2) # return 2nd next line
            ...process 2nd next line...
            ...etc...
        }
        bufclose(file)

In the code above, calls to bufnext do not affect the results of
subsequent bufread's.  The bufread procedure always steps through
the input file a line at a time without skipping lines whether or
not bufnext is called.
____________________________________________________________

Here is a more detailed description of the procedures:

bufopen(s)
==========
Produces a file resulting from opening s for reading ("r" option),
but fails if the file cannot be opened.  if s is missing or
the value of s is &null, then standard input is opened and
&input is returned.  Unlike the Icon open function, bufopen()
can and must be called prior to any call to bufread or bufnext
involving standard input.  Unlike named files, only one buffered
standard input may be open at any given time.

Default:
s   &null   (indicates &input should be opened for buffered
            reading)

Errors (from open):
103     s not string

Errors (new):
Attempt to open standard input when currently open


bufread(f)
==========
Produces a string consisting of the next line from f, but fails on
end of file.   Calls to bufnext do not affect the results of
subsequent bufread's.  The procedure bufread always steps
through a file a line at a time without skipping lines.  The
procedure bufread fails when a logical end of file is
reached, i.e., when the physical end of file has
been reached AND the internal buffer is empty.

Default:
f   &input

Errors:
f is not a file
f not opened for buffered reads (includes &input)


bufnext(f, n)
=============
Produces a string consisting of the nth next line from f after
the current line.  It fails when the physical end of file
has been reached.

Default:
f   &input
n   1 (the next line after the current one)

Errors:
f is not a file
f not opened for buffered reads (includes &input)
n not convertible to integer
n not positive


bufclose(f)
===========
Produces f after closing it.  Standard input must
be closed before it can be reopened using bufopen.
If standard input is closed, all lines read using bufnext
are lost when it is reopened.  In general, there is no
practical reason to bufclose and then bufopen standard input.
One may want to bufclose standard input to release its
internal buffer for garbage collection.

Default:
f   &input

Errors (from close):
105     f not file

[ Summary entry | Source code ]


calendar.icn: Procedures for data and time calculation and conversion

procedure Cal_Init:        initialize calendar globals
procedure Cal_IsLeapYear:  determine if year is leap
procedure Cal_IsDST:       determines if seconds (local) is DST
procedure Cal_NthWeekdayTo gets seconds of nth specified weekday of month
procedure Cal_DateLineToSe convert &dateline to seconds
procedure Cal_DateToSec:   convert &date to seconds
procedure Cal_SecToDate:   convert seconds to &date
procedure Cal_SecToDateLin convert seconds to &dateline
procedure Cal_SecToUnixDat convert seconds to UNIX time
procedure Cal_ClockToSec:  convert &date to seconds
procedure Cal_SecToClock:  convert seconds to &clock

link calendar
March 25, 2002; Robert J. Alexander
See also: datetime.icn, datefns.icn
This file is in the public domain.

Procedures in this file supersede several procedures in datetime.icn.
____________________________________________________________

Setting up
----------
You will probably want to set a platform environment variable
"Cal_TimeZone" to an appropriate local time zone ID string
before using this library. Look at the time zone data at the
end of this source file and choose an ID for your locale.
Common ones for USA are "PST", "MST", "CST", and "EST", although
there are more specific ones such as "America/Arizona" that
handle special rules. If environment variables are not supported
for your platform or your implementation of Icon, explicitly specify
the default time zone in your program: e.g.

        Cal_CurrentTimeZone := Cal_GetTimeZone("PST").

If your system uses a base year for date calculation that is
different from 1970, your can specify it in an environment
variable "Cal_DateBaseYear" or set it directly in the global
variable by the same name. Unix and Windows use the library's
default value of 1970, but Macintosh used to use 1984 (I'm
not sure if Apple have yet seen fit to conform to
the 1970 quasi-standard). This setting doesn't matter unless you
want your "seconds" values to be the same as your system's.

GMT and local time
------------------
GMT (Greenwich Mean Time) is a universal time standard (virtually
equivalent to "Coordinated Universal Time" (UTC), except for some
millisecond differences).

Time forms
----------
There are two fundamental date/time forms supported by this
library: a form in which computation is easy (the "seconds" form)
and a form in which formatting is easy (the "calendar record"
form).
  - Seconds -- the time is be represented as an integer that is
    the number of seconds relative to the beginning of
    Cal_DateBaseYear, GMT. Cal_DateBaseYear is
    usually 1970, but can be changed). The "seconds" form is
    a universal time, independent of locale.
  - Cal_Rec -- a "calendar record", which has fields for date and
    time components: year, month, day, hour, minutes, seconds,and
    day-of-week.
    The "Cal_Rec" form is usually in terms of local time, including
    accounting for daylight savings time according to local rules.

Notes
-----
  - Several procedures have a final "timeZone" parameter. In those
    procedures the timeZone parameter is optional and, if omitted,
    Cal_CurrentTimeZone is used.

  - The time zone table and list consume around 30KB that can be
    "freed" by setting both Cal_TimeZoneTable and Cal_TimeZoneList
    to &null. Procedures Cal_GetTimeZoneTable() and
    Cal_GetTimeZoneList() will re-create the structures and assign
    them back to their globals. For many applications, those
    structures are no longer needed after program initialization.

  - The global variables are automatically initialized by
    the Cal_ procedures. However, if you want to use the globals
    before using any procedures, they must be explicitly initialized
    by calling Cal_Init().

  - Time zone records in the time zone structures should be viewed
    as read-only. If you want to make temporary changes to the
    fields, copy() the time zone record.

Global variables
----------------
The following global variables are useful in date and time
operations (R/O means please don't change it):

  - Cal_SecPerMin       - (R/O) Seconds per minute.
  - Cal_SecPerHour      - (R/O) Seconds per hour.
  - Cal_SecPerDay       - (R/O) Seconds per day.
  - Cal_SecPerWeek      - (R/O) Seconds per week.
  - Cal_MonthNames      - (R/O) List of month names.
  - Cal_DayNames        - (R/O) List of day names.
  - Cal_CurrentTimeZone - Current default time zone record --
                          can be changed at any time. Initialized
                          to the time zone whose ID is in
                          environment variable "Cal_TimeZone" if
                          set, or to GMT.
  - Cal_TimeZoneGMT     - (R/O) The GMT time zone record. Can be used
                          as a timeZone parameter to "turn off"
                          conversion to or from local.
  - Cal_DateBaseYear - The base year from which the "seconds"
                          form is calculated, initialized to
                          the value of environment variable
                          "Cal_DateBaseYear" if set, or 1970 (the
                          year used by both Unix and MS-Windows)
  - Cal_TimeZoneTable - A table of time zones keyed by the
                          time zone's ID string
  - Cal_TimeZoneList - A list of time zones ordered by
                          increasing offset from GMT

Initialization procedure
------------------------
Cal_Init()
        Initializes global variables. Called implicitly by
        the Cal_ procedures.

Cal_Rec (calendar record) procedures
------------------------------------
Cal_Rec(year,month,day,hour,min,sec,weekday)                     =20
        Cal_Rec record constructor. All values are integers in
        customary US usage (months are 1-12, weekdays are 1-7 with
        1 -> Sunday)

Cal_SecToRec(seconds,timeZone)
        Converts seconds to a Cal_Rec, applying conversion rules
        of "timeZone". To suppress conversion, specify timeZone =
        Cal_TimeZoneGMT.

Cal_RecToSec(calRec,timeZone)
        Converts a Cal_Rec to seconds, applying conversion rules
        of "timeZone". To suppress conversion, specify timeZone =
        Cal_TimeZoneGMT.

Time zone procedures
--------------------
Cal_GetTimeZone(timeZoneName)
        Gets a time zone given a time zone ID string. Fails if
        a time zone for the given ID cannot be produced.

Cal_GetTimeZoneList()
        Returns the tine zone list that is the value of
        Cal_TimeZoneList, unless that global has been explicitly
        set to &null. If the global is null, a new list is built,
        assigned to Cal_TimeZoneList, and returned.

Cal_GetTimeZoneTable()
        Returns the tine zone table that is the value of
        Cal_TimeZoneTable, unless that global has been explicitly
        set to &null. If the global is null, a new table is built,
        assigned to Cal_TimeZoneTable, and returned. In building
        the table, Cal_GetTimeZoneList() is called so global
        variable Cal_TimeZoneList is also set.

Date/time calculation procedures
--------------------------------
Cal_LocalToGMTSec(seconds,timeZone)
        Converts seconds from local to GMT using the rules of
        timeZone.

Cal_GMTToLocalSec(seconds,timeZone)
        Converts seconds from GMT to local using the rules of
        timeZone.

Cal_IsLeapYear(year)
        Returns the number of seconds in a day if year is a leap
        year, otherwise fails.

Cal_LeapYearsBetween(loYear,hiYear)
        Returns the count of leap years in the range of years n
        where loYear <= n < hiYear.

Cal_IsDST(seconds,timeZone)
        Returns the DST offset in hours if seconds (local time)
        is in the DST period, otherwise fails.

Cal_NthWeekdayToSec(year,month,weekday,n,fromDay)
        Returns seconds of nth specified weekday of month, or fails
        if no such day. This is mainly an internal procedure for
        DST calculations, but might have other application.

Date/time formatting procedures
-------------------------------
Cal_DateLineToSec(dateline,timeZone)
        Converts a date in something like Icon's &dateline format
        (Wednesday, February 11, 1998  12:00 am) to "seconds" form.

Cal_DateToSec(date,timeZone)
        Converts a date string in something like Icon &date format
        (1998/02/11) to "seconds" form.

Cal_SecToDate(seconds,timeZone)
        Converts "seconds" form to a string in Icon's
        &date format (1998/02/11).

Cal_SecToDateLine(seconds,timeZone)
        Converts "seconds" form to a string in Icon's &dateline
        format (Wednesday, February 11, 1998  12:00 am).

Cal_SecToUnixDate(seconds,timeZone)
        Converts "seconds" form to a string in typical UNIX
        date/time format (Jan 14 10:24 1991).

Time-only formatting procedures
-------------------------------
Cal_ClockToSec(seconds)
        Converts a time in the format of &clock (19:34:56) to
        seconds past midnight.

Cal_SecToClock(seconds)
        Converts seconds past midnight to a string in the format of
        &clock (19:34:56).

[ Summary entry | Source code ]


calendat.icn: Procedure to get date from Julian Day Number

link calendat
March 25, 2002; Ralph E. Griswold
This file is in the public domain.

calendat(j) return a record with the month, day, and year corresponding
to the Julian Date Number j.
____________________________________________________________

Acknowledgement:  This procedure is based on an algorithm given in
"Numerical Recipes; The Art of Scientific Computing"; William H. Press,
Brian P. Flannery, Saul A. Teukolsky. and William T. Vetterling;
Cambridge University Press, 1986.

[ Summary entry | Source code ]


calls.icn: Procedures for calls as objects

link calls
March 25, 2002; Ralph E. Griswold
This file is in the public domain.

These procedures deal with procedure invocations that are encapsulated
in records.

[ Summary entry | Source code ]


capture.icn: Procedures to echo output to a second file

link capture
March 25, 2002; David A. Gamey
This file is in the public domain.

Capture is initially called by the user with one argument, the open file
to contain the echoed output. Then it places itself and several shadow
procedures between all calls to write, writes & stop.  The user never
need call capture again.

Subsequently, during calls to write, writes, and stop, the appropriate
shadow procedure gains control and calls capture internally.  Capture
then constructs a list of only those elements that direct output to
&output and calls the original builtin function via the saved name.
Upon return the shadow routine calls the the original builtin function
with the full list.

A series of uncaptured output functions have been added to allow output
to be directed only to &output.  These are handy for placing progress
messages and other comforting information on the screen.

Example:

   otherfile := open(...,"w")

   capfile :=  capture(open(filename,"w"))

   write("Hello there.",var1,var2," - this should be echoed",
      otherfile,"This should appear once in the other file only")

   uncaptured_writes("This will appear once only.")

   every i := 1 to 10000 do
      if ( i % 100 ) = 0 then

         uncaptured_writes("Progress is ",i,"\r")

   close(capfile)
   close(otherfile)
____________________________________________________________

Notes:

1.    stop must be handled specially in its shadow function
2.    capture is not designed to be turned off
3.    This may be most useful in systems other than Unix
      (i.e. that don't have a "tee" command)
4.    Display has not been captured because
      a) display is usually a debugging aid, and capture was
         originally intended to capture screen output to a file
         where a record or audit trail might be required
      b) the display output would be 'down a level' showing the
         locals at the display_capture_ level, although the depth
         argument could easily be incremented to adjust for this
      c) write, writes, and stop handle arguments the same way
5.    An alternative to having two calls would be to have capture
      call the desired procedure with :
         push(&output,x) ; return p!(y ||| x )
      While this would remove the complexity with stop it would
      probably be slower
____________________________________________________________

History:

10Jun94  -  D.Gamey  -  added uncaptured i/o routines
05Oct94  -  D.Gamey  -  temporarily suspend tracing
20Oct94  -  D.Gamey  -  fix no output for f(&null)
                     -  eliminated global variable and select procedure

[ Summary entry | Source code ]


cartog.icn: Procedures for cartographic projection

procedure project:         project a list of coordinates
procedure invp:            return inversion of projection
procedure sbsize:          calculate scalebar size
procedure rectp:           define rectangular projection
procedure pptrans:         define planar projective transformation
procedure utm:             define UTM projection
procedure compose:         define composite projection

link cartog
February 19, 2003; Gregg M. Townsend and William S. Evans
This file is in the public domain.

These procedures project geographic coordinates.

rectp(x1, y1, x2, y2, xm, ym) defines a rectangular projection.
pptrans(L1, L2) defines a planar projective transformation.
utm(a, f) defines a latitude/longitude to UTM projection.

project(p, L) projects a list of coordinates.
invp(p) returns the inverse of projection p.
compose(p1, p2, ...) creates a composite projection.
____________________________________________________________

rectp(x1, y1, x2, y2, xm, ym) returns a rectangular projection
in which the point (x1, y1) maps to (x2, y2).  If xm is specified,
distances in the projected coordinate system are scaled by xm.  If
ym is also specified, xm scales x values while ym scales y values.
____________________________________________________________

pptrans(L1, L2) returns a planar projective transform that maps
the four points in L1 to the four points in L2.  Each of the two
lists contains 8 coordinates: [x1, y1, x2, y2, x3, y3, x4, y4].
____________________________________________________________

utm(a, f) returns a projection from latitude and longitude to
Universal Transverse Mercator (UTM) representation.  The reference
ellipsoid is specified by a, the equatorial radius in metres, and f,
the flattening.  Alternatively, f can be omitted with a specifying
a string, such as "Clarke66"; if a is also omitted, "WGS84" is used.
See ellipsoid() in geodat.icn for the list of possible strings.

The input list contains signed numeric values: longitude and
latitude, in degrees, in that order (x before y).  The output list
contains triples: an integer zone number followed by real-valued
UTM x and y distances in metres.  No "false easting" is applied.

UTM conversions are valid between latitudes 72S and 84N, except
for those portions of Norway where the UTM grid is irregular.
____________________________________________________________

project(p, L) applies a projection, reading a list of coordinates
and returning a new list of transformed coordinates.
____________________________________________________________

invp(p) returns the inverse of projection p, or fails if no
inverse projection is available.
____________________________________________________________

compose(p1, p2, ..., pn) returns the projection that is the
composition of the projections p1, p2, ..., pn.  The composition
applies pn first.
____________________________________________________________

sbsize(p, x, y, u, maxl) calculates a scale bar size for use with
projection p at input coordinates (x, y).  Given u, the size of
an unprojected convenient unit (meter, foot, mile, etc.) at (x, y),
sbsize() returns the maximum "round number" N such that
   -- N is of the form  i * 10 ^ k  for i in {1,2,3,4,5}
   -- the projected length of the segment (x, y, x + N * u, y)
      does not exceed maxl
____________________________________________________________

UTM conversion algorithms are based on:

        Map Projections: A Working Manual
        John P. Snyder
        U.S. Geological Survey Professional Paper 1395
        Washington: Superintendent of Documents, 1987

Planar projective transformation calculations come from:

        Computing Plane Projective Transformations (Method 1)
        Andrew Zisserman, Robotics Research Group, Oxford
        in CVOnline (R. Fisher, ed.), found 22 February 2000 at:
http://www.dai.ed.ac.uk/CVonline/LOCAL_COPIES/EPSRC_SSAZ/node11.html

[ Summary entry | Source code ]


caseless.icn: Procedures to perform caseless scanning

procedure anycl:           Caseless version of any()
procedure balcl:           Caseless version of bal()
procedure findcl:          Caseless version of find()
procedure manycl:          Caseless version of many()
procedure matchcl:         Caseless version of match()
procedure uptocl:          Caseless version of upto()

link caseless
August 19, 1996; Nevin J. Liber
This file is in the public domain.

These procedures are analogous to the standard string-analysis
functions except that uppercase letters are considered equivalent to
lowercase letters.

anycl(c, s, i1, i2)     succeeds and produces i1 + 1, provided
                        map(s[i1]) is in cset(map(c)) and i2 is
                        greater than i1.  It fails otherwise.

balcl(c1, c2, c3, s, i1, i2)    generates the sequence of integer
                                positions in s preceding a
                                character of cset(map(c1)) in
                                map(s[i1:i2]) that is balanced with
                                respect to characters in cset(map(c2))
                                and cset(map(c3)), but fails if there
                                is no such position.

findcl(s1, s2, i1, i2)  generates the sequence of integer positions in
                        s2 at which map(s1) occurs as a substring
                        in map(s2[i1:i2]), but fails if there is no
                        such position.

manycl(c, s, i1, i2)    succeeds and produces the position in s
                        after the longest initial sequence of
                        characters in cset(map(c)) within
                        map(s[i1:i2]).  It fails if map(s[i1]) is not
                        in cset(map(c)).

matchcl(s1, s2, i1, i2) produces i1 + *s1 if
                        map(s1) == map(s2[i1+:=*s1]) but fails
                        otherwise.

uptocl(c, s, i1, i2)    generates the sequence of integer positions in
                        s preceding a character of cset(map(c)) in
                        map(s[i1:i2]).  It fails if there is no such
                        position.

Defaults:       s, s2   &subject
                i1      &pos if s or s2 is defaulted; otherwise 1
                i2      0
                c1      &cset
                c2      '('
                c3      ')'

Errors: 101     i1 or i2 not integer
        103     s or s1 or s2 not string
        104     c or c1 or c2 or c3 not cset

[ Summary entry | Source code ]


codeobj.icn: Procedures to encode and decode Icon data

link codeobj
March 25, 2002; Ralph E. Griswold
Requires: co-expressions
This file is in the public domain.

   These procedures provide a way of storing Icon values as strings and
retrieving them.  The procedure encode(x) converts x to a string s that
can be converted back to x by decode(s). These procedures handle all
kinds of values, including structures of arbitrary complexity and even
loops.  For "scalar" types -- null, integer, real, cset, and string --

     decode(encode(x)) === x

   For structures types -- list, set, table, and record types --
decode(encode(x)) is, for course, not identical to x, but it has the
same "shape" and its elements bear the same relation to the original
as if they were encoded and decode individually.

   No much can be done with files, functions and procedures, and
co-expressions except to preserve type and identification.

   The encoding of strings and csets handles all characters in a way
that it is safe to write the encoding to a file and read it back.

   No particular effort was made to use an encoding of value that
minimizes the length of the resulting string. Note, however, that
as of Version 7 of Icon, there are no limits on the length of strings
that can be written out or read in.
____________________________________________________________

   The encoding of a value consists of four parts:  a tag, a length,
a type code, and a string of the specified length that encodes the value
itself.

   The tag is omitted for scalar values that are self-defining.
For other values, the tag serves as a unique identification. If such a
value appears more than once, only its tag appears after the first encoding.
There is, therefore, a type code that distinguishes a label for a previously
encoded value from other encodings. Tags are strings of lowercase
letters. Since the tag is followed by a digit that starts the length, the
two can be distinguished.

   The length is simply the length of the encoded value that follows.

   The type codes consist of single letters taken from the first character
of the type name, with lower- and uppercase used to avoid ambiguities.

   Where a structure contains several elements, the encodings of the
elements are concatenated. Note that the form of the encoding contains
the information needed to separate consecutive elements.

   Here are some examples of values and their encodings:

     x                     encode(x)
-------------------------------------------------------

     1                     "1i1"
     2.0                   "3r2.0"
     &null                 "0n"
     "\377"                "4s\\377"
     '\376\377'            "8c\\376\\377"
     procedure main        "a4pmain"
     co-expression #1 (0)  "b0C"
     []                    "c0L"
     set()                 "d0S"
     table("a")            "e3T1sa"
     L1 := ["hi","there"]  "f11L2shi5sthere"

A loop is illustrated by

     L2 := []
     put(L2,L2)

for which

     x                     encode(x)
-------------------------------------------------------

     L2                    "g3L1lg"

   Of course, you don't have to know all this to use encode and decode.

[ Summary entry | Source code ]


colmize.icn: Procedures to arrange data into columns

link colmize
June 15, 1990; Robert J. Alexander
This file is in the public domain.

colmize() -- Arrange data into columns.

Procedure to arrange a number of data items into multiple columns.
Items are arranged in column-wise order, that is, the sequence runs
down the first column, then down the second, etc.

This procedure goes to great lengths to print the items in as few
vertical lines as possible.

[ Summary entry | Source code ]


complete.icn: Procedure to complete partial input string

link complete
August 14, 1996; Richard L. Goerwitz
This file is in the public domain.

complete(s,st)  completes a s relative to a set or list of strings, st.
                Put differently, complete() lets you supply a
                partial string, s, and get back those strings in st
                that s is either equal to or a  substring of.
____________________________________________________________

 Lots of command interfaces allow completion of partial input.
 Complete() simply represents my personal sentiments about how this
 might best be done in Icon.  If you strip away the profuse comments
 below, you end up with only about thirty lines of actual source
 code.

 I have arranged things so that only that portion of an automaton
 which is needed to complete a given string is actually created and
 stored.  Storing automata for later use naturally makes complete()
 eat up more memory.  The performance gains can make it worth the
 trouble, though.  If, for some reason, there comes a time when it
 is advisable to reclaim the space occupied by complete's static
 structures, you can just call it without arguments.  This
 "resets" complete() and forces an immediate garbage collection.

Example code:

     commands := ["run","stop","quit","save","load","continue"]
     while line := read(&input) do {
         cmds := list()
         every put(cmds, complete(line, commands))
         case *cmds of {
             0 : input_error(line)
             1 : do_command(cmds[1])
             default : display_possible_completions(cmds)
         }
         etc...

 More Iconish methods might include displaying successive
 alternatives each time the user presses the tab key (this would,
 however, require using the nonportable getch() routine).  Another
 method might be to use the first string suspended by complete().

 NOTE: This entire shebang could be replaced with a slightly slower
 and much smaller program suggested to me by Jerry Nowlin and Bob
 Alexander.

     procedure terscompl(s, st)
         suspend match(s, p := !st) & p
     end

 This program will work fine for lists with just a few members, and
 also for cases where s is fairly large.  It will also use much less
 memory.

[ Summary entry | Source code ]


complex.icn: Procedures to perform complex arithmetic

link complex
June 21, 2000; Ralph E. Griswold
This file is in the public domain.

The following procedures perform operations on complex numbers.

     complex(r,i)    create complex number with real part r and
                     imaginary part i

     cpxadd(z1, z2)  add complex numbers z1 and z2

     cpxdiv(z1, z2)  divide complex number z1 by complex number z2

     cpxmul(z1, z2)  multiply complex number z1 by complex number z2

     cpxsub(z1, z2)  subtract complex number z2 from complex number z1

     cpxstr(z)      convert complex number z to string representation

     strcpx(s)      convert string representation s of complex
                    number to complex number

[ Summary entry | Source code ]


conffile.icn: Procedures to read initialization directives

procedure Directive:       Wrapper to build directive specification
procedure ReadDirectives:  Builds icon data structures from a config file
procedure Directive_table_ build table of sets: action key value(s)
procedure Directive_table: build table: action key value
procedure Directive_set:   build set: action value(s)
procedure Directive_list:  build list: action value(s)
procedure Directive_value: build value: action value
procedure Directive_exists build existence flag: action
procedure Directive_ignore quietly ignore any directive
procedure Directive_warnin flag directive with a warning

link conffile
March 25, 2002; David A. Gamey

Thanks to Clint Jeffery for suggesting the Directive wrapper and
making defining a specification much cleaner looking and easier!
____________________________________________________________

This file is in the public domain.
____________________________________________________________

Description:

   At Some point certain procedures become indispensable.  Anyone who
   has used 'options' from the Icon program library will probably agree.
   I found a need to be able to quickly, change the format and
   interpretation of a set of configuration and rules files.  And so, I
   hope this collection of procedures will become similarly indispensable.


Directive( p1, p2, i1, i2 ) : r1

   returns a specification record for a table required by ReadDirectives

   p1 is the build procedure used to extract the data from the file.
      The table below describes the build procedures and the default
      minimum and maximum number of arguments for each.  If the included
      procedures don't meet your needs then you can easily add your own
      and still use Directive to build the specification.

         build procedure              minargs     maxargs

         Directive_table_of_sets         2            -
         Directive_table                 2            -
         Directive_value                 1            1
         Directive_set                   1            -
         Directive_list                  1            -
         < user defined >                1            -
         Directive_exists                0            0
         Directive_ignore                0            -
         Directive_warning               0            -

   p2 is an edit procedure that allows you to preprocess the data or null
   i1 is the minimum number of arguments for this directive, default is 1
   i2 is the maximum number of arguments for this directive

   Run-time Errors:
   - 123 if p1 isn't a procedure
   - 123 if p2 isn't null or a procedure
   - 101 if i1, i2 aren't integers and not ( 0 <= i1 <= i2 ) after defaults


ReadDirectives( l1, t1, s1, s2, c1, c2, p1 ) : t2

   returns a table containing parsed directives for the specified file

   l1 is a list of file names or open files, each element of l1 is tried
      in turn until a file is opened or an open file is encountered.

         For example: [ "my/rules", "/etc/rules", &input ]

   t1 is a table of specifications for parsing and handling each directive
   s1 the comment character, default "#"
   s2 the continuation character, default "_"
   c1 the escape character, default "\"
   c2 the cset of whitespace, default ' \b\t\v\f\r'
   p1 stop | an error procedure to be called, fail if null

   t2 is a table containing the parsed results keyed by tag

   Notes:
      - the special key "*file*" is a list containing the original
        text of input file with interspersed diagnostic messages.
      - the comment, escape, continuation and whitespace characters
        must not overlap (unpredictable)
      - the end of a directive statement will forcibly close an open
        quote (no warning)
      - the end of file will forcibly close a continuation (no warning)

   Run-time Errors:
      - 103, 104, 107, 108, 500
        500 errors occur if:
        - arguments are too big/small
        - the specification table is improper

Directive file syntax:

   - blank lines are ignored
   - all syntactic characters are parameterized
   - everything after a comment character is ignored (discarded)
   - to include a comment character in the directive,
     precede it with an escape
   - to continue a directive,
     place a continue character at the end of the line (before comments)
   - trailing whitespace is NOT ignored in continuations
   - quoted strings are supported,
   - to include a quote within a quoted string,
     precede the enclosed quote with an escape

Usage:

-- Config file, example: --

   # comment line

   var1 "This string, w/o quotes, will be in cfgspec[\"var\"]"
   cset1 "abcdefffffffffffff"   # type of quotes isn't important
   int1  12345
   lcase1 "Hello There THIs iS CasE inSENsITive"
   list1 one two three _ # continues
        four five one three zero
   set1 one one one two three 3 'a b c' # one two three 3 'a b c'
   table1 k1 v1
   table1 k2 v2
   t/set1 key1 v1 v2 v3 v4
   t/set1 key2 v5 v6
   t/set1 key3 "1 2 \#3"  # comment
   warn1  this will produce _
          a warning

-- Coding example: --

   # 1. Define a specification table using Directive.
   #    Directive has four fields:
   #    - the procedure to handle the tag
   #    - an optional edit procedure to preprocess the data
   #    - the minimum number of values following the tag,
   #      default is dependent on the &null is treated as 0
   #    - the maximum number of values following the tag,
   #      &null is treated as unlimited
   #    The table's keys are the directives of the configuration file
   #    The default specification should be either warning of ignore

        cfgspec    := table( Directive( Directive_warning ) )
        cfgspec["var1"]   := Directive( Directive_value )
        cfgspec["cset1"]  := Directive( Directive_value, cset )
        cfgspec["int1"]   := Directive( Directive_value, integer )
        cfgspec["lcase1"] := Directive( Directive_value, map )
        cfgspec["list1"]  := Directive( Directive_list )
        cfgspec["set1"]   := Directive( Directive_set )
        cfgspec["table1"] := Directive( Directive_table )
        cfgspec["t/set1"] := Directive( Directive_table_of_sets )

   # 2. Read, parse and build a table based upon the spec and the file

        cfg := ReadDirectives( ["my.conf",&input], cfgspec )

   # 3. Process the output

        write("Input:\n")
        every write(!cfg["*file*"])
        write("\nBuilt:\n")
        every  k :=key(cfg) do
        if k ~== "*file*" then write(k, " := ",ximage(cfg[k]))

-- Output: --

   Input:

   # comment line

   var1 "This string, w/o quotes, will be in cfgspec[\"var\"]"
   cset1 "abcdefffffffffffff"   # type of quotes isn't important
   int1  12345
   lcase1 "Hello There THIs iS CasE inSENsITive"
   list1 one two three _ # continues
       four five one three zero
   set1 one one one two three 3 'a b c' # one two three 3 'a b c'
         table1 k1 v1
         table1 k2 v2
         t/set1 key1 v1 v2 v3 v4
         t/set1 key2 v5 v6
         t/set1 key3 "1 2 \#3"  # comment
   warn This will produce a _
        warning
   -- Directive isn't defined in specification.

   Built:

   set1 := S1 := set()
      insert(S1,"3")
      insert(S1,"a b c")
      insert(S1,"one")
      insert(S1,"three")
      insert(S1,"two")
   cset1 := 'abcdef'
   t/set1 := T4 := table(&null)
      T4["key1"] := S2 := set()
         insert(S2,"v1")
         insert(S2,"v2")
         insert(S2,"v3")
         insert(S2,"v4")
      T4["key2"] := S3 := set()
         insert(S3,"v5")
         insert(S3,"v6")
      T4["key3"] := S4 := set()
         insert(S4,"1 2 #3")
   list1 := L12 := list(8)
      L12[1] := "one"
      L12[2] := "two"
      L12[3] := "three"
      L12[4] := "four"
      L12[5] := "five"
      L12[6] := "one"
      L12[7] := "three"
      L12[8] := "zero"
   lcase1 := "hello there this is case insensitive"
   int1 := 12345
   var1 := "This string, w/o quotes, will be in cfgspec[\"var\"]"
   table1 := T3 := table(&null)
      T3["k1"] := "v1"
      T3["k2"] := "v2"

[ Summary entry | Source code ]


converge.icn: Procedure to produce continued-fraction convergents

procedure converge:        continued-fraction convergents

link converge
June 7, 2000; Ralph E. Griswold
This file is in the public domain.

This procedure produces continued-fraction convergents from a list
of partial quotients.

[ Summary entry | Source code ]


convert.icn: Procedures for various conversions

procedure exbase10:        convert base 10 to arbitrary base
procedure inbase10:        convert arbitrary base to base 10
procedure radcon:          convert between bases

link convert
March 19, 1998; Ralph E. Griswold
This file is in the public domain.

     exbase10(i, j)  converts base-10 integer i to base j.

     inbase10(s, i)  convert base-i integer s to base 10.

     radcon(s, i, j) convert base-i integer s to base j.

There are several other procedures related to conversion that are
not yet part of this module.

[ Summary entry | Source code ]


core.icn: Procedures for general application

link core
August 4, 2000; Gregg M. Townsend
This file is in the public domain.

Links to core modules of the basic part of the library, as defined
in the Icon Language book (3/e, p.179) and Graphics book (p.47).

[ Summary entry | Source code ]


created.icn: Procedure to determine number of structures created

procedure created:         number of structures created

link created
March 25, 2002; Ralph E. Griswold
This file is in the public domain.

This program returns the number of structures of a given type that have
been created.

[ Summary entry | Source code ]


currency.icn: Procedures for formatting currency

link currency
September 21, 1993; Robert J. Alexander
This file is in the public domain.

currency() -- Formats "amount" in standard American currency format.
"amount" can be a real, integer, or numeric string.  "width" is the
output field width, in which the amount is right adjusted.  The
returned string will be longer than "width" if necessary to preserve
significance.  "minus" is the character string to be used for
negative amounts (default "-"), and is placed to the right of the
amount.

[ Summary entry | Source code ]


curves.icn: Procedures to generate points on plain curves

link curves
March 25, 2002; Ralph E. Griswold
This file is in the public domain.

This file links procedure files that generate traces of points on various
plain curves.

The first two parameters determine the defining position of the
curve:

     x       x coordinate
     y       y coordinate

The meaning of "definition position" depends on the curve.  In some
cases it is the position at which plotting starts.  In others, it
is a "center" for the curve.

The next arguments vary and generally refer to parameters of the
curve.  There is no practical way to describe these here.  If they
are not obvious, the best reference is

     A Catalog of Special Plane Curves, J. Dennis Lawrence,
     Dover Publications, Inc., New York, 1972.

This book, which is in print at the time of this writing, is a
marvelous source of information about plane curves and is inexpensive
as well.

The trailing parameters give the number of steps and the end points
(generally in angles) of the curves:

     steps   number of points, default varies
     lo      beginning of plotting range, default varies
     hi      end of plotting range, default varies

Because of floating-point roundoff, the number of steps
may not be exactly the number specified.

Note:  Some of the curves may be "upside down" when plotted on
coordinate systems in which the y axis increases in a downward direction.

Caution:  Some of these procedures generate very large values
in portions of their ranges.  These may cause run-time errors when
used in versions of Icon prior to 8.10.  One work-around is to
turn on error conversion in such cases.

Warning:  The procedures that follow have not been tested thoroughly.
Corrections and additions are most welcome.

These  procedures are, in fact, probably most useful for the parametric
equations they contain.

[ Summary entry | Source code ]


datefns.icn: Procedure for dates

link datefns
August 14, 1995; Charles Hethcoat
This file is in the public domain.

datefns.icn - a collection of date functions

Adaptor:  Charles L Hethcoat III
June 12, 1995
Taken from various sources as attributed below.

All date and calendar functions use the "date_rec" structure defined
below.

Note:  I adapted the procedures "julian" and "unjulian" sometime in 1994
from "Numerical Recipes in C."  Some time later I discovered them
(under slightly different names) in Version 9 of the Icon Library
(Ralph Griswold, author).  I am including mine for what they are worth.
That'll teach me to wait!

[ Summary entry | Source code ]


datetime.icn: Procedures for date and time operations

procedure ClockToSec:      convert &date to seconds
procedure DateLineToSec:   convert &dateline to seconds
procedure DateToSec:       convert &date to seconds
procedure SecToClock:      convert seconds to &clock
procedure SecToDate:       convert seconds to &date
procedure SecToDateLine:   convert seconds to &dateline
procedure SecToUnixDate:   convert seconds to UNIX time
procedure IsLeapYear:      determine if year is leap
procedure calendat:        Julian date
procedure date:            date in natural English
procedure dayoweek:        day of the week
procedure full13th:        full moons on Friday 13ths
procedure julian:          Julian date
procedure pom:             phase of moon
procedure saytime:         time in natural English
procedure walltime:        time since midnight

link datetime
August 9, 2000; Robert J. Alexander and Ralph E. Griswold
See also: datefns.icn
This file is in the public domain.

Notes:
        - the default value for function parameters named
          "hoursFromGmt" is the value of global variable
          "HoursFromGmt" if nonnull, or environment variable
          "HoursFromGmt" if set, or 0.
        - The base year from which the "seconds" representation
          of a date is calculated is by default 1970 (the ad hoc
          standard used by both Unix and MS-Windows), but can be
          changed by either setting the global variable
          "DateBaseYear" or environment variable "DateBaseYear".
        - There are some procedures not mentioned in this summary
          that are useful: DateRecToSec(), SecToDateRec(). See the
          source code for details.

ClockToSec(seconds)
        converts a time in the format of &clock to seconds past
        midnight.

DateLineToSec(dateline,hoursFromGmt)
        converts a date in &dateline format to seconds since start of
        dateBaseYear.

DateToSec(date,hoursFromGmt)
        converts a date string in Icon &date format (yyyy/mm/dd)
        to seconds past DateBaseYear.

SecToClock(seconds)
        converts seconds past midnight to a string in the format of
        &clock.

SecToDate(seconds,hoursFromGmt)
        converts seconds past DateBaseYear to a string in Icon
        &date format (yyyy/mm/dd).

SecToDateLine(seconds,hoursFromGmt)
        produces a date in the same format as Icon's &dateline.

SecToUnixDate(seconds,hoursFromGmt)
        returns a date and time in typical UNIX format:
        Jan 14 10:24 1991.

IsLeapYear(year)
        succeeds if year is a leap year, otherwise fails.

calendat(j)
        returns a record with the month, day, and year corresponding
        to the Julian Date Number j.

date()  natural date in English.

dayoweek(day, month, year)
        produces the day of the week for the given date.
        Note carefully the parameter order.

full13th(year1, year2)
        generates records giving the days on which a full moon occurs
        on Friday the 13th in the range from year1 though year2.

julian(m, d, y)
        returns the Julian Day Number for the specified
        month, day, and year.

pom(n, phase)
        returns record with the Julian Day number of fractional
        part of the day for which the nth such phase since
        January, 1900.  Phases are encoded as:

                0 - new moon
                1 - first quarter
                2 - full moon
                3 - last quarter#

        GMT is assumed.

saytime()
        computes the time in natural English.  If an argument is
        supplied it is used as a test value to check the operation
         the program.

walltime()
        produces the number of seconds since midnight.  Beware
        wrap-around when used in programs that span midnight.
____________________________________________________________

Acknowledgement:  Some of these procedures are based on an algorithm
given in "Numerical Recipes; The Art of Scientific Computing";
William H. Press, Brian P. Flannery, Saul A. Teukolsky, and William
T. Vetterling;#  Cambridge University Press, 1986.

[ Summary entry | Source code ]


ddfread.icn: Procedures for reading ISO 8211 DDF files

procedure ddfopen:         open DDF file
procedure ddfread:         read DDF record
procedure ddfclose:        close DDF file

link ddfread
August 2, 2001; Gregg M. Townsend
This file is in the public domain.

These procedures read DDF files ("Data Descriptive Files",
ISO standard 8211) such as those specified by the US Geological
Survey's "Spatial Data Transfer Standard" for digital maps.
ISO8211 files from other sources may contain additional data
encodings not recognized by these procedures.

ddfopen(filename) opens a file and returns a handle.
ddfdda(handle) returns a list of header records.
ddfread(handle) reads the next data record.
ddfclose(handle) closes the  file.
____________________________________________________________

ddfopen(filename) opens a DDF file, decodes the header, and
returns an opaque handle for use with subsequent calls.  It
fails if any problems are encountered.  Instead of a filename,
an already-open file can be supplied.
____________________________________________________________

ddfdda(handle) returns a list of records containing data
from the Data Descriptive Area (DDA) of the file header.
Each record contains the following fields:

        tag     DDR entry tag
        control field control data
        name    field name
        labels  list of field labels
        format  data format

The records may also contain other fields used internally.
____________________________________________________________

ddfread(handle) reads the next data record from the file.
It returns a list of lists, with each sublist containing
a tag name followed by the associated data values, already
decoded according to the specification given in the header.
____________________________________________________________

ddfclose(handle) closes a DDF file.

[ Summary entry | Source code ]


dif.icn: Procedure to check for differences

link dif
August 14, 1996; Robert J. Alexander
This file is in the public domain.

     dif(stream, compare, eof, group)
             generates a sequence of differences between an  arbitrary
             number of input streams.  Each result is returned as a list
             of diff_recs, one for each input stream, with each diff_rec
             containing a list of items that differ and their position
             in the input stream.

The diff_rec type is declared as:

             record diff_rec(pos,diffs)

dif() fails if there are no differences, i.e. it produces an empty
result sequence.
____________________________________________________________

For example, if two input streams are:

     a b c d e f g h
     a b d e f i j

the output sequence would be:

     [diff_rec(3,[c]),diff_rec(3,[])]
     [diff_rec(7,[g,h]),diff_rec(6,[i,j])

The arguments to dif(stream,compare,eof,group) are:

     stream          A list of data objects that represent input streams
                     from which dif will extract its input "records".
                     The elements can be of several different types which
                     result in different actions, as follows:

                        Type                    Action
                     ===========     =============================
                     file            file is "read" to get records

                     co-expression   co-expression is activated to
                                     get records

                     list            records are "gotten" (get()) from
                                     the list

                     diff_proc       a record type defined in "dif" to
                                     allow a procedure (or procedures)
                                     suppled by dif's caller to be called
                                     to get records.  Diff_proc has two
                                     fields, the procedure to call and the
                                     argument to call it with.  Its
                                     definition looks like this:

                                        record diff_proc(proc,arg)


Optional arguments:

     compare         Item comparison procedure -- succeeds if
                     "equal", otherwise fails (default is the
                     identity "===" comparison).  The comparison
                     must allow for the fact that the eof object
                     (see next) might be an argument, and a pair of
                     eofs must compare equal.

     eof             An object that is distinguishable from other
                     objects in the stream.  Default is &null.

     group           A procedure that is called with the current number
                     of unmatched items as its argument.  It must
                     return the number of matching items required
                     for file synchronization to occur.  Default is
                     the formula Trunc((2.0 * Log(M)) + 2.0) where
                     M is the number of unmatched items.

[ Summary entry | Source code ]


digitcnt.icn: Procedure to count number of digits in file

procedure digitcnt:        count digits in file

link digitcnt
July 15, 1995; Ralph E. Griswold
This file is in the public domain.

This procedure counts the number of each digit in a file and returns
a ten-element list with the counts.

[ Summary entry | Source code ]


dijkstra.icn: Procedures for Dijkstra's "Discipline" control structures

procedure do_od:           Dijkstra's do_od construct
procedure if_fi:           Dijkstra's if_fi construct

link dijkstra
December 9, 2003; Frank J. Lhota
This file is in the public domain.

The procedures do_od and if_fi implement the "do ... od" and "if ... fi"
control structures used in the book "A Discipline of Programming" by
Edsger W. Dijkstra. This book uses a programming language designed to
delay implementation details, such as the order in which tests are
performed.

Dijkstra's programming language uses two non-ASCII characters, a box and
a right arrow. In the following discussion, the box and right arrow
characters are represented as "[]" and "->" respectively.

The "if ... fi" control structure is similar to multi-branch "if" statements
found in many languages, including the Bourne shell (i.e. the
"if / elif / fi" construct). The major difference is that in Dijkstra's
notation, there is no specified order in which the "if / elif" tests are
performed. The "if ... fi" structure has the form

      if
            Guard1 -> List1
         [] Guard2 -> List2
         [] Guard3 -> List3
         ...
         [] GuardN -> ListN
      fi

where

     Guard1, Guard2, Guard3 ... GuardN are boolean expressions, and
     List1, List2, List3 ... ListN are lists of statements.

When this "if ... fi" statement is performed, the guard expressions are
evaluated, in some order not specified by the language, until one of the
guard expressions evaluates to true. Once a true guard is found, the list
of statements following the guard is evaluated.  It is a fatal error
for none of the guards in an "if ... fi" statement to be true.

The "do ... od" control is a "while" loop structure, but with multiple
loop conditions, in style similar to "if ... fi". The form of a Dijkstra
"do" statement is

      do
            Guard1 -> List1
         [] Guard2 -> List2
         [] Guard3 -> List3
         ...
         [] GuardN -> ListN
      od

where

     Guard1, Guard2, Guard3 ... GuardN are boolean expressions, and
     List1, List2, List3 ... ListN are lists of statements.

To perform this "do ... od" statement, the guard expressions are
evaluated, in some order not specified by the language, until either a
guard evaluates to true, or all guards have been evaluated as false.

- If all the guards are false, we exit the loop.
- If a guard evaluates to true, then the list of statements following this
  guard is performed, and then we loop back to perform this "do ... od"
  statement again.

The procedures if_fi{} and do_od{} implement Dijkstra's "if ... fi" and
"do ... od" control structures respectively. In keeping with Icon
conventions, the guard expressions are arbitrary Icon expressions. A guard
is considered to be true precisely when it succeeds. Similarly, a statement
list can be represented by a single Icon expression. The Icon call

      if_fi{
          Guard1, List1,
          Guard2, List2,
          ...
          GuardN, ListN
         }

suspends with each result produced by the expression following the true
guard. If none of the guards succeed, runerr() is called with an appropriate
message.

Similarly, the Icon call

      do_od{
          Guard1, List1,
          Guard2, List2,
          ...
          GuardN, ListN
         }

parallels the "do ... od" statement. As long as at least one guard
succeeds, another iteration is performed. When all guards fail, we exit
the loop and do_od fails.

The test section of this file includes a guarded command implementation of
Euclid's algorithm for calculating the greatest common denominator. Unlike
most implementations of Euclid's algorithm, this version handles its
parameters in a completely symmetrical fashion.

[ Summary entry | Source code ]


divide.icn: Procedure to perform long division

link divide
March 29, 2000; Ralph E. Griswold
Requires: Large integer arithmetic, potentially
This file is in the public domain.

Doesn't get the decimal point.  Not sure what the padding does;
to study.

[ Summary entry | Source code ]


ebcdic.icn: Procedures to convert between ASCII and EBCDIC

link ebcdic
August 14, 1996; Alan Beale
This file is in the public domain.

These procedures assist in use of the ASCII and EBCDIC character sets,
regardless of the native character set of the host:

Ascii128()    Returns a 128-byte string of ASCII characters in
              numerical order.  Ascii128() should be used in
              preference to &ascii for applications which might
              run on an EBCDIC host.

Ascii256()    Returns a 256-byte string representing the 256-
              character ASCII character set.  On an EBCDIC host,
              the order of the second 128 characters is essentially
              arbitrary.

Ebcdic()      Returns a 256-byte string of EBCDIC characters in
              numerical order.

AsciiChar(i)  Returns the character whose ASCII representation is i.

AsciiOrd(c)   Returns the position of the character c in the ASCII
              collating sequence.

EbcdicChar(i) Returns the character whose EBCDIC representation is i.

EbcdicOrd(c)  Returns the position of the character c in the EBCDIC
              collating sequence.

MapEtoA(s)    Maps a string of EBCDIC characters to the equivalent
              ASCII string, according to a plausible mapping.

MapAtoE(s)    Maps a string of ASCII characters to the equivalent
              EBCDIC string, according to a plausible mapping.

Control(c)    Returns the "control character" associated with the
              character c.  On an EBCDIC host, with $ representing
              an EBCDIC character with no 7-bit ASCII equivalent,
              Control("$") may not be identical to "\^$", as
              translated by ICONT (and neither result is particularly
              meaningful).
____________________________________________________________

Notes:

    There is no universally accepted mapping between ASCII and EBCDIC.
    See the SHARE Inc. publication "ASCII and EBCDIC Character Set and
    Code Issues in Systems Application Architecture" for more information
    than you would ever want to have on this subject.

    The mapping of the first 128 characters defined below by Ascii128()
    is the most commonly accepted mapping, even though it probably
    is not exactly like the mapping used by your favorite PC to mainframe
    file transfer utility.  The mapping of the second 128 characters
    is quite arbitrary, except that where an alternate translation of
    ASCII char(n) is popular, this translation is assigned to
    Ascii256()[n+129].

    The behavior of all functions in this package is controlled solely
    by the string literals in the _Eascii() procedure.  Therefore you
    may modify these strings to taste, and still obtain consistent
    results, provided that each character appears exactly once in the
    result of _Eascii().

    Yes, it's really true that the EBCDIC "\n" (NL, char(16r15)) is not
    the same as "\l" (LF, char(16r25)).  How can that be?  "Don't blame
    me, man, I didn't do it."

[ Summary entry | Source code ]


empgsup.icn: Procedure to support empg

link empgsup
May 30, 1993; Ralph E. Griswold
This file is in the public domain.

This procedure is called by timing programs produced by empg.  It
a "delta" timing value used to adjust timings.

[ Summary entry | Source code ]