@DATABASE Libraries Manual
@NODE MAIN "Amiga RKM Libraries: 37 Utility Library"
@INDEX Lib_Index/MAIN
@TOC Libraries_Manual/MAIN
Utility library is the home for all the OS functions which don't fit in
the other libraries.  Among the calls in utility library are calls to
manage tags and tag lists, callback hooks, and some generic 32-bit math
functions, all discussed below.

@{" Tags " link 37-1}                           @{" International String Functions " link 37-4}
@{" Callback Hooks " link 37-2}                 @{" Date Functions " link 37-5}
@{" 32-bit Integer Math Functions " link 37-3}  @{" Function Reference " link 37-6}

@ENDNODE

@NODE 37-1 "37 Utility Library / Tags"
The implementation of tags is one of the many new features of Release 2.
Tags make it possible to add new parameters to system functions without
interfering with the original parameters.  They also make specifying
parameter lists much clearer and easier.

@{" Tag Functions and Structures " link 37-1-1}  @{" Simple Tag Usage Example " link ADCD_v1.2:Reference_Library/Libraries/lib_examples/tag1.c/MAIN}
@{" Simple Tag Usage " link 37-1-2}              @{" Advanced Tag Usage " link 37-1-4}

@ENDNODE

@NODE 37-1-1 "37 / Tags / Tag Functions and Structures"
A tag is made up of an attribute/value pair as defined below (from
<utility/@{"tagitem.h" link ADCD_v1.2:Inc&AD2.1/includes/utility/tagitem.h/MAIN 18}>):

    struct TagItem
    {
        ULONG  ti_Tag;    /* identifies the type of this item */
        ULONG  ti_Data;   /* type-specific data, can be a pointer */
    };

The ti_Tag field specifies an attribute to set.  The possible values of
ti_Tag are implementation specific.  System tags are defined in the
include files.  The value the attribute is set to is specified in ti_Data.
An example of the attribute/value pair that will specify a window's name
is:

    ti_Tag  = WA_Title;
    ti_Data = "My Window's Name";

The ti_Data field often contains 32-bit data as well as pointers.

These are brief descriptions of the utility functions you can use to
manipulate and access tags.  For complete descriptions, see the
"@{"Simple Tag Usage" link 37-1-2}" and "@{"Advanced Tag Usage" link 37-1-4}" sections.

The following utility library calls are for supporting tags:


                Table 37-1: Utility Library Tag Functions
  ______________________________________________________________________
 |                                                                      |
 |     @{"AllocateTagItems()" link 37-1-4-1}  Allocate a TagItem array (or chain).         |
 |         @{"FreeTagItems()" link 37-1-4-1}  Frees allocated TagItem lists.               |
 |----------------------------------------------------------------------|
 |        @{"CloneTagItems()" link 37-1-4-2}  Copies a TagItem list.                       |
 | @{"RefreshTagItemClones()" link 37-1-4-3}  Rejuvenates a clone from the original.       |
 |----------------------------------------------------------------------|
 |          @{"FindTagItem()" link 37-1-4-4 13}  Scans TagItem list for a tag.                |
 |           @{"GetTagData()" link 37-1-4-6}  Obtain data corresponding to tag.            |
 |          @{"NextTagItem()" link 37-1-4-5}  Iterate TagItem lists.                       |
 |           @{"TagInArray()" link 37-1-4-4}  Check if a tag value appears in a Tag array. |
 |----------------------------------------------------------------------|
 |     @{"FilterTagChanges()" link 37-1-4-3}  Eliminate TagItems which specify no change.  |
 |       @{"FilterTagItems()" link 37-1-4-3}  Remove selected items from a TagItem list.   |
 |              @{"MapTags()" link 37-1-4-8}  Convert ti_Tag values in a list via map      |
 |                         pairing.                                     |
 |         @{"PackBoolTags()" link 37-1-4-7}  Builds a "Flag" word from a TagItem list.    |
 |______________________________________________________________________|

@ENDNODE

@NODE 37-1-2 "37 / Tags / Simple Tag Usage"
One way tags are passed to system functions is in the form of tag lists. A
tag list is an array or chain of arrays of @{"TagItem" link 37-1-1} structures.  Within
this array, different data items are identified by the value of @{"ti_Tag" link 37-1-1 5}.
Items specific to a subsystem (Intuition, Graphics,...) have a ti_Tag
value which has the TAG_USER bit set. Global system tags have a ti_Tag
value with TAG_USER bit clear.  The global system tags include:


                      Table 37-2: Global System Tags
  ____________________________________________________________________
 |                                                                    |
 | Tag Value   Meaning                                                |
 |====================================================================|
 | TAG_IGNORE  A no-op.  The data item is ignored.                    |
 |                                                                    |
 | TAG_MORE    The @{"ti_Data" link 37-1-1 5} points to another tag list, to support     |
 |             chaining of @{"TagItem" link 37-1-1} arrays.                            |
 |                                                                    |
 | TAG_DONE    Terminates the @{"TagItem" link 37-1-1} array (or chain).               |
 |                                                                    |
 | TAG_SKIP    Ignore the current tag item, and skip the next n array |
 |             elements, where n is kept in @{"ti_Data" link 37-1-1 5}.                  |
 |____________________________________________________________________|


Note that user tags need only be unique within the particular context of
their use.  For example, the attribute tags defined for @{"OpenWindow()" link ADCD_v1.2:Reference_Library/Libraries/Lib_4/4-2-1} have
the same numeric value as some tags used by @{"OpenScreen()" link ADCD_v1.2:Reference_Library/Libraries/Lib_3/3-3 6}, but the same
numeric value has different meaning in the different contexts.

System functions receive @{"TagItem" link 37-1-1}s in several ways.  One way is illustrated
in the Intuition function @{"OpenWindow()" link ADCD_v1.2:Reference_Library/Libraries/Lib_4/4-2-1}.  This function supports an
extented @{"NewWindow" link ADCD_v1.2:Reference_Library/Libraries/Lib_4/4-2 8} structure called @{"ExtNewWindow" link ADCD_v1.2:Reference_Library/Libraries/Lib_4/4-2 8}.  When the @{"NW_EXTENDED" link ADCD_v1.2:Reference_Library/Libraries/Lib_4/4-7-1}
flag is set in the ExtNewWindow.Flags field, OpenWindow() assumes that the
ExtNewWindow.Extension field contains a pointer to a tag list.

Another method of passing a tag list is to directly pass a pointer to a
tag list, as @{"OpenWindowTagList()" link ADCD_v1.2:Reference_Library/Libraries/Lib_4/4-2-1} does in the following code fragment.

    struct TagItem tagitem[3];
    struct Screen *screen;
    struct Window *window;

    tagitem[0].ti_Tag = WA_CustomScreen;
    tagitem[0].ti_Data = screen;    /* Open on my own screen */
    tagitem[1].ti_Tag = WA_Title;
    tagitem[1].ti_Data = "RKM Test Window";
    tagitem[2].ti_Tag = TAG_DONE;   /* Marks the end of the tag array. */

    /* Use defaults for everything else. Will open as big as the screen. */
    /* Because all window parameters are specified using tags, we don't  */
    /* need a NewWindow structure                                        */

    if (window = OpenWindowTagList(NULL, tagitem))
    {
        /* rest of code */
        CloseWindow(window);
    }

Notice that window parameters need not be explicitly specified. Functions
that utilize tags have reasonable defaults to fall back on in case no
valid attribute/value pair was supplied for a particular parameter. This
fall back capability is a useful feature. An application only has to
specify the attributes that differ from the default, rather than
unnecessarily listing all the possible attributes.

The amiga.lib support library offers another way to pass @{"TagItem" link 37-1-1}s to a
function.  Rather than passing a tag list, the function @{"OpenWindowTags()" link ADCD_v1.2:Reference_Library/Libraries/Lib_4/4-2-1}
receives the attribute/value pairs in the argument list, much like
@{"printf()" link ADCD_v1.2:Inc&AD2.1/autodocs/amiga_lib/printf()} receives its arguments.  Any number of attribute/value pairs can
be specified.  This type of argument passing is called VarArgs. The
following code fragment illustrates the usage of OpenWindowTags().

    struct Window *window;

    /* Just pass NULL to show we aren't using a NewWindow */
    window = OpenWindowTags( NULL,
                             WA_CustomScreen, screen,
                             WA_Title, "RKM Test Window",
                             TAG_DONE );

Tags are not exclusively for use with the operating system; the programmer
can implement them as well.  The run-time utility library contains several
functions to make using tags easier.

@ENDNODE

@NODE 37-1-4 "37 / Tags / Advanced Tag Usage"
The @{"previous section" link 37-1-2} provided the background material necessary to start
using tags.  This section will show how to use the more advanced features
of tags using functions within utility library.

@{" Creating a New Tag List " link 37-1-4-1}         @{" Sequential Access of Tag Lists " link 37-1-4-5}
@{" Copying an Existing Tag List " link 37-1-4-2}    @{" Random Access of Tag Lists " link 37-1-4-6}
@{" Filtering an Existing Tag List " link 37-1-4-3}  @{" Obtaining Boolean Values " link 37-1-4-7}
@{" Locating an Attribute " link 37-1-4-4}           @{" Mapping Tag Attributes " link 37-1-4-8}

@ENDNODE

@NODE 37-1-4-1 "37 / / Advanced Tag Usage / Creating a New Tag List"
The @{"AllocateTagItems()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/AllocateTagItems()} function can be used to create a new tag array
ready for use.  The tag array should be passed to @{"FreeTagItems()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/FreeTagItems()} when the
application is done with it.

    struct TagItem *tags;
    ULONG tags_needed;

    /* Indicate how many tags we need */
    tags_needed = 10;

    /* Allocate a tag array */
    if (tags = AllocateTagItems(tags_needed))
    {
        /* ...do something with the array... */

        /* Free the array when your done with it */
        FreeTagItems (tags);
    }

@ENDNODE

@NODE 37-1-4-2 "37 / / Advanced Tag Usage / Copying an Existing Tag List"
The @{"CloneTagItems()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/CloneTagItems()} function is used to copy an existing tag array into a
new tag array.

    struct TagItem *otags;      /* Original tag array */
    struct TagItem *ntags;      /* New tag array */

    /* Make sure there is a TagItem array */
    if (otags)
    {
        /* Copy the original tags into a new tag array */
        if (ntags = CloneTagItems(otags))
        {
            /* ...do something with the array... */

            /* Free the array when your done with it */
            FreeTagItems (ntags);
        }
    }

This function can also be used to implement a function that will insert
tag items into an array.

    struct TagItem *otags;      /* Original tag array */
    struct TagItem *tags;       /* New tag array */

    /* Insert a couple of tags into an existing tag array */
    if (tags = MakeNewTagList (GA_LeftEdge, 10,
                               GA_TopEdge, 20,
                               TAG_MORE, otags))
    {
        /* ...do something with the array... */

        /* Free the array when your done with it */
        FreeTagItems (tags);
    }

    /* This function will create a tag array from tag pairs placed on
     * the stack */
    struct TagItem *MakeNewTagList (ULONG data,...)
    {
        struct TagItem *tags = (struct TagItem *) &data;

        return (CloneTagItems (tags));
    }

@ENDNODE

@NODE 37-1-4-3 "37 / / Advanced Tag Usage / Filtering an Existing Tag List"
Sometimes it is necessary to only allow certain attributes to be visible
in a tag list.  In order to achieve this, the tag array would need to be
filtered.

A number of functions are provided for filtering items in a tag array.
They are @{"FilterTagChanges()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/FilterTagChanges()}, @{"FilterTagItems()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/FilterTagItems()} and @{"RefreshTagItemClones()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/RefreshTagItemClones()}.


    /* We want the text entry gadget to receive the following tags */
    Tag string_attrs[] =
    {
        STRINGA_MaxChars,
        STRINGA_Buffer,
        STRINGA_TextVal,
        TAG_END,
    };

    /* These are attributes that the model understands */
    Tag model_attrs[] =
    {
        CGTA_Total,
        CGTA_Visible,
        CGTA_Top,
        ICA_TARGET,
        ICA_MAP,
        TAG_END,
    };

    struct TagItem *otags;      /* Original tag list */
    struct TagItem *ntags;      /* New, work, tag list */

    /* Make a copy of the original for us to work with */
    ntags = CloneTagItems (otags);

    /* Create a tag list that only contains attributes that are
     * listed in the model_attrs list. */
    if (FilterTagItems (ntags, model_attrs, TAGFILTER_AND))
    {
        /* Work with filtered tag list (ntags) */

        /* Restore the tag list */
        RefreshTagItemClones (ntags, otags);

        /* Create a tag list that only contains attributes that
         * aren't in the model_attrs list. */
        if (FilterTagItems (ntags, model_attrs, TAGFILTER_NOT))
        {
            /* Work with filtered tag list (ntags) */
        }

        /* Restore the tag list */
        RefreshTagItemClones (ntags, otags);

        /* Create a tag list that only contains attributes that
         * are in the string_attrs list. */
        if (FilterTagItems (ntags, string_attrs, TAGFILTER_AND))
        {
            /* Work with filtered tag list (ntags) */
        }
    }

    /* Free work tag list. */
    FreeTagItems (ntags);

@ENDNODE

@NODE 37-1-4-4 "37 / / Advanced Tag Usage / Locating an Attribute"
To see if an attribute is in a tag array, the @{"TagInArray()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/TagInArray()} function is
used.

    /* See if the listview labels attribute is located in a tag array */
    if (TagItemArray(GTLV_Labels, tags))
    {
        /* Yes, the attribute is in the list */
    }
    else
    {
        /* No, the attribute isn't in the list */
    }

The @{"FindTagItem()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/FindTagItem()} function will return a pointer to the actual tag that
has the desired attribute.  This allows you to manipulate the tag or to
determine if the attribute exists but just has a NULL value.

    struct TagItem *tag;

    /* See if they are trying to set a sound */
    if (tag = FindTagItem(MGA_Sound, attrs))
    {
        /* Set the sound attribute to point to the specified sound data */
        tag->ti_Data = sound;
    }

@ENDNODE

@NODE 37-1-4-5 "37 / / Advanced Tag Usage / Sequential Access of Tag Lists"
In order to sequentially access the members of a tag array, the
@{"NextTagItem()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/NextTagItem()} function is used.

    struct TagItem *tags = msg->ops_AttrList;
    struct TagItem *tstate;
    struct TagItem *tag;
    ULONG tidata;

    /* Start at the beginning */
    tstate = tags;

    /* Step through the tag list while there are still items in the
     * list */
    while (tag = NextTagItem (&tstate))
    {
        /* Cache the data for the current element */
        tidata = tag->ti_Data;

        /* Handle each attribute that we understand */
        switch (tag->ti_Tag)
        {
            /* Put a case statement here for each attribute that your
             * function understands */
            case PGA_Freedom:
                lod->lod_Flags |= tidata;
                break;

            case GTLV_Labels:
                lod->lod_List = (struct List *) tidata;
                break;

            /* We don't understand this attribute */
            default:
                break;
        }
    }

@ENDNODE

@NODE 37-1-4-6 "37 / / Advanced Tag Usage / Random Access of Tag Lists"
The @{"GetTagData()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/GetTagData()} function will return the data for the specified
attribute.  If there isn't a tag that matches, then the default value is
returned.

    APTR sound;

    /* Get the sound data that our function will use. */
    sound = (APTR) GetTagData (MGA_Sound, (ULONG) DefaultSound, attrs);

@ENDNODE

@NODE 37-1-4-7 "37 / / Advanced Tag Usage / Obtaining Boolean Values"
Often times data is best represented as simple boolean (TRUE or FALSE)
values.  The @{"PackBoolTags()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/PackBoolTags()} function provides an easy method for
converting a tag list to bit fields.

    /* These are the attributes that we understand, with the
     * corresponding flag value. */
    struct TagItem activation_bools[] =
    {
        /* Attribute            Flags */
        {GA_ENDGADGET,          ENDGADGET},
        {GA_IMMEDIATE,          GADGIMMEDIATE},
        {GA_RELVERIFY,          RELVERIFY},
        {GA_FOLLOWMOUSE,        FOLLOWMOUSE},
        {GA_RIGHTBORDER,        RIGHTBORDER},
        {GA_LEFTBORDER,         LEFTBORDER},
        {GA_TOPBORDER,          TOPBORDER},
        {GA_BOTTOMBORDER,       BOTTOMBORDER},
        {GA_TOGGLESELECT,       TOGGLESELECT},

        /* Terminate the array */
        {TAG_END}
    };

    /* Set the activation field, based on the attributes passed */
    g->Activation = PackBoolTags(g->Activation, tags, activation_bools);

@ENDNODE

@NODE 37-1-4-8 "37 / / Advanced Tag Usage / Mapping Tag Attributes"
To translate all occurrences of an attribute to another attribute, the
@{"MapTags()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/MapTags()} function is used.

For Release 2, the third parameter of this function is always TRUE (tags
remain in the array even if they can't be mapped).

    struct TagItem map_list[] =
    {
        /* Original     New */
        {MGA_LeftEdge,  GA_LeftEdge},
        {MGA_TopEdge,   GA_TopEdge},
        {MGA_Width,     GA_Width},
        {MGA_Height,    GA_Height},

        /* Terminate the array */
        {TAG_END},
    }

    /* Map the tags to the new attributes, keeping all attributes that
     * aren't included in the mapping array */
    MapTags(tags, map_list, TRUE);

@ENDNODE

@NODE 37-2 "37 Utility Library / Callback Hooks"
The callback features of Release 2 provide a standard means for
applications to extend the functionality of libraries, devices, and
applications.  This standard makes it easy for the operating system to use
custom modules from different high level programming languages as part of
the operating system.  For example, the layers library, which takes care
of treating a display as a series of layered regions, allows an
application to attach a pattern function to a display layer.  Instead of
filling in the background of a layer with the background color, the layers
library calls the custom pattern function which fills in the layer display
with a custom background pattern.

@{" Callback Hook Structure and Function " link 37-2-1}

@ENDNODE

@NODE 37-2-1 "37 / Callback Hooks / Callback Hook Structure and Function"
An application passes a custom function in the form of a callback Hook
(from <utility/@{"hooks.h" link ADCD_v1.2:Inc&AD2.1/includes/utility/hooks.h/MAIN 22}>):

    struct Hook
    {
        struct MinNode h_MinNode;
        ULONG (*h_Entry)();     /* stub function entry point */
        ULONG (*h_SubEntry)();  /* the custom function entry point */
        VOID *h_Data;           /* owner specific */
    };

h_MinNode
    This field is reserved for use by the module that will call the Hook.

h_Entry
    This is the address of the Hook stub.  When the OS calls a callback
    function, it puts parameters for the callback function in CPU
    registers A0, A1, and A2.  This makes it tough for higher level
    language programmers to use a callback function because most higher
    level languages don't have a way to manipulate CPU registers
    directly.  The solution is a stub function which first copies the
    parameters from the CPU registers to a place where a high level
    language function can get to them.   The stub function then calls the
    callback function.  Typically, the stub pushes the registers onto the
    stack in a specific order and the callback function pops them off the
    stack.

h_SubEntry
    This is the address of the actual callback function that the
    application has defined.  The stub calls this function.

h_Data
    This field is for the application to use.  It could point to a global
    storage structure that the callback function utilizes.

There is only one function defined in utility library that relates to
callback hooks:

    ULONG CallHookPkt(struct Hook *hook, VOID *object, VOID *paramPkt);

This function calls a standard callback Hook function.

@{" Simple Callback Hook Usage " link 37-2-1-1}

@ENDNODE

@NODE 37-2-1-1 "37 / / Hook Structure And Function / Simple Callback Hook Usage"
A @{"Hook" link 37-2-1} function must accept the following three parameters in these
specific registers:


      A0 - Pointer to the @{"Hook" link 37-2-1} structure.
      A2 - Pointer to an object to manipulate. The object is
           context specific.
      A1 - Pointer to a message packet. This is also context
           specific.


For a callback function written in C, the parameters should appear in this
order:

    myCallbackFunction(Pointer to Hook (A0),
                       Pointer to Object (A2),
                       Pointer to message (A1));

This is because the standard C stub pushes the parameters onto the stack
in the following order: A1, A2, A0.  The following assembly language
routine is a callback stub for C:

    INCLUDE 'exec/types.i'
    INCLUDE 'utility/hooks.i'

    xdef        _hookEntry

    _hookEntry:
        move.l  a1,-(sp)                ; push message packet pointer
        move.l  a2,-(sp)                ; push object pointer
        move.l  a0,-(sp)                ; push hook pointer
        move.l  h_SubEntry(a0),a0       ; fetch actual Hook entry point ...
        jsr     (a0)                    ; and call it
        lea     12(sp),sp               ; fix stack
        rts

If your C compiler supports registerized parameters, your callback
functions can get the parameters directly from the CPU registers instead
of having to use a stub to push them on the stack.  The following C
language routine uses registerized parameters to put parameters in the
right registers.  This routine requires a C compiler that supports
registerized parameters.

    #include <exec/types.h>
    #include <utility/hooks.h>

    #define     ASM     __asm
    #define     REG(x)  register __ ## x

    /* This function converts register-parameter hook calling
     * convention into standard C conventions.  It requires a C
     * compiler that supports registerized parameters, such as
     * SAS/C 5.xx or greater.
     */
    ULONG ASM
    hookEntry(REG(a0) struct Hook *h, REG(a2) VOID *o, REG(a1) VOID *msg)
    {
        return ((*h->h_SubEntry)(h, o, msg));
    }

A callback function is executed on the context of the module that invoked
it.  This usually means that callback functions cannot call functions that
need to look at environment specific data.  For example, @{"printf()" link ADCD_v1.2:Inc&AD2.1/autodocs/amiga_lib/printf()} needs to
look at the current process's input and output stream.  Entities like
Intuition have no input and output stream.  This also means that in order
for the function to access any of its global data, it needs to make sure
the CPU can find the function's data segment.  It does this by forcing the
function to load the offset for the program's data segment into CPU
register A4.  See your compiler documentation for details.

The following is a simple function that can be used in a callback hook.

    ULONG MyFunction (struct Hook *h, VOID *o, VOID *msg)
    {
        /* A SASC and Manx function that obtains access to the global
           data segment */
        geta4();

        /* Debugging function to send a string to the serial port */
        KPrintF("Inside MyFunction()\n");

        return (1);
    }

The next step is to initialize the @{"Hook" link 37-2-1} for use.  This basically means
that the fields of the Hook structure must be filled with appropriate
values.

The following simple function initializes a @{"Hook" link 37-2-1} structure.

    /* This simple function is used to initialize a Hook */
    VOID InitHook (struct Hook *h, ULONG (*func)(), VOID *data)
    {
        /* Make sure a pointer was passed */
        if (h)
        {
            /* Fill in the hook fields */
            h->h_Entry = (ULONG (*)()) hookEntry;
            h->h_SubEntry = func;
            h->h_Data = data;
        }
    }

The following is a simple example of a callback hook function.

    @{" hooks1.c " link ADCD_v1.2:Reference_Library/Libraries/lib_examples/hooks1.c/MAIN}

@ENDNODE

@NODE 37-3 "37 Utility Library / 32-bit Integer Math Functions"
Utility library contains some high-speed math functions for 32-bit integer
division and multiplication. These functions will take advantage of
available processor instructions (like DIVUL), if a 68020 processor or
higher is present. If not, these functions will mimic those instructions
in 68000 only instructions, thus providing processor independency.

Currently the following functions are implemented:

  ____________________________________________________________
 |                                                            |
 |  @{"SDivMod32()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/SDivMod32()}  Signed 32 by 32-bit division and modulus.    |
 |    @{"SMult32()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/SMult32()}  Signed 32 by 32-bit multiplication.          |
 |  @{"UDivMod32()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/UDivMod32()}  Unsigned 32 by 32-bit division and modulus.  |
 |    @{"UMult32()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/UMult32()}  Unsigned 32 by 32-bit multiplication.        |
 |____________________________________________________________|

       Table 37-3: Utility Library 32-bit Math Functions


The division functions return the quotient in D0 and the remainder in D1.
To obtain the remainder in a higher level language, either a compiler
specific instruction to fetch the contents of a specific register must be
used (like getreg() in SAS C) or a small assembler stub.

Following a simple example of the usage of the 32-bit integer math
functions in C.

    @{" uptime.c " link ADCD_v1.2:Reference_Library/Libraries/lib_examples/uptime.c/MAIN}

@ENDNODE

@NODE 37-4 "37 Utility Library / International String Functions"
The international string functions in utility library are a way to make
use of a future localization library which Commodore-Amiga will provide.
When the localization library is opened, the functions will be replaced by
ones which will take the locale as defined by the user into account. This
means that the compare order may change according to the locale, so care
should be taken not to rely on obtaining specific compare sequences.

Currently implemented are:

  _______________________________________________________________
 |                                                               |
 |  @{"Stricmp()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/Stricmp()}  Compare string case-insensitive.                  |
 | @{"Strnicmp()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/Strnicmp()}  Compare string case-insensitive, with a specified |
 |             length.                                           |
 |  @{"ToLower()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/ToLower()}  Convert a character to lower case.                |
 |  @{"ToUpper()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/ToUpper()}  Convert a character to upper case.                |
 |_______________________________________________________________|

    Table 37-4: Utility Library International String Functions


These functions operate in the same manner as their ANSI C equivalents,
for the most part.  For more information, see the "@{"Utility Library" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/MAIN}"
Autodocs in the Amiga ROM Kernel Reference Manual: Includes and Autodocs.
Here is a simple example of the usage of the international string
functions.

    @{" istr.c " link ADCD_v1.2:Reference_Library/Libraries/lib_examples/istr.c/MAIN}

@ENDNODE

@NODE 37-5 "37 Utility Library / Date Functions"
To ease date-related calculations, the utility library has some functions
to convert a date, specified in a ClockData structure, in the number of
seconds since 00:00:00 01-Jan-78 and vice versa. To indicate the date, the
ClockData structure (in <utility/@{"date.h" link ADCD_v1.2:Inc&AD2.1/includes/utility/date.h/MAIN 18}>) is used.

    struct ClockData
    {
        UWORD sec;     /* seconds (0 - 59)*/
        UWORD min;     /* minutes (0 - 59) */
        UWORD hour;    /* hour (0 - 23) */
        UWORD mday;    /* day of the month (1 - 31) */
        UWORD month;   /* month of the year (1 - 12)
        UWORD year;    /* 1978 - */
        UWORD wday;    /* day of the week (0 - 6, where 0 is Sunday) */
    };

The following functions are available to operate on ClockData:

  ________________________________________________________________
 |                                                                |
 | @{"Amiga2Date()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/Amiga2Date()}  Calculate the date from the specified timestamp  |
 |               (in seconds).                                    |
 |  @{"CheckDate()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/CheckDate()}  Check the legality of a date.                    |
 | @{"Date2Amiga()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/Date2Amiga()}  Calculate the timestamp from the specified date. |
 |________________________________________________________________|

            Table 37-5: Utility Library Date Functins


@{"Amiga2Date()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/Amiga2Date()} takes a number of seconds from 01-Jan-78 as argument and
fills in the supplied ClockData structure with the date and time.

@{"CheckDate()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/CheckDate()} checks if the supplied ClockData structure is valid, and
returns the number of seconds from 01-Jan-78 if it is. Note that this
function currently does not take the supplied day of the week in account.

@{"Date2Amiga()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/Date2Amiga()} takes a ClockData structure as argument and returns the
number of seconds since 01-Jan-78. The supplied ClockData structure MUST
be valid, since no checking is done.

The following example shows various uses of the utility library date
functions.

    @{" a2d.c " link ADCD_v1.2:Reference_Library/Libraries/lib_examples/a2d.c/MAIN}

@ENDNODE

@NODE 37-6 "37 Utility Library / Function Reference"
The tables which follow contain breif descriptions of the functions inside
the utility library.  All these functions require Release2 or a later
version of the Amiga operating system.  See the Amiga ROM Kernel Reference
Manual: Includes and Autodocs for details on each function call.

@{" Tag Function Reference " link 37-6-1}
@{" Callback Hook Function Reference " link 37-6-2}
@{" 32-Bit Integer Math Function Reference " link 37-6-3}
@{" International String Function Reference " link 37-6-4}
@{" Date Function Reference " link 37-6-5}

@ENDNODE

@NODE 37-6-1 "37 / Function Reference / Tag Function Reference"
The following are brief descriptions of the utility library functions
which pertain to tags and tag lusts.


                    Table 37-6: Utility Tag Functions
  ______________________________________________________________________
 |                                                                      |
 |           Function                 Description                       |
 |======================================================================|
 |     @{"AllocateTagItems()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/AllocateTagItems()}  Allocate a @{"TagItem" link 37-1-1} array (or chain).         |
 |         @{"FreeTagItems()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/FreeTagItems()}  Frees allocated TagItem lists.               |
 |----------------------------------------------------------------------|
 |        @{"CloneTagItems()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/CloneTagItems()}  Copies a @{"TagItem" link 37-1-1} list.                       |
 | @{"RefreshTagItemClones()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/RefreshTagItemClones()}  Rejuvenates a clone from the original.       |
 |----------------------------------------------------------------------|
 |          @{"FindTagItem()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/FindTagItem()}  Scans @{"TagItem" link 37-1-1} list for a tag.                |
 |           @{"GetTagData()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/GetTagData()}  Obtain data corresponding to tag.            |
 |          @{"NextTagItem()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/NextTagItem()}  Iterate TagItem lists.                       |
 |           @{"TagInArray()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/TagInArray()}  Check if a tag value appears in a Tag array. |
 |----------------------------------------------------------------------|
 |     @{"FilterTagChanges()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/FilterTagChanges()}  Eliminate @{"TagItem" link 37-1-1}s which specify no change.  |
 |       @{"FilterTagItems()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/FilterTagItems()}  Remove selected items from a TagItem list.   |
 |              @{"MapTags()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/MapTags()}  Convert @{"ti_Tag" link 37-1-1 5} values in a list via map      |
 |----------------------------------------------------------------------|
 |         @{"PackBoolTags()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/PackBoolTags()}  Builds a "Flag" word from a @{"TagItem" link 37-1-1} list.    |
 |______________________________________________________________________|

@ENDNODE

@NODE 37-6-2 "37 / Function Reference / Callback Hook Function Reference"
The following are brief descriptions of the utility library functions
which pertain to callback hooks.


                   Table 37-7: Utility Hook Functions
     ___________________________________________________________
    |                                                           |
    |    Function                 Description                   |
    |===========================================================|
    |  @{"CallHookPkt()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/CallHookPkt()}  Call a standard callback @{"Hook" link 37-2-1} function.   |
    |___________________________________________________________|

@ENDNODE

@NODE 37-6-3 "37 / Function Reference / 32-Bit Integer Math Function Reference"
The following are brief descriptions of the utility library functions
which pertain to 32-bit integer math.


              Table 37-8: Utility 32-Bit Math Functions
     ___________________________________________________________
    |                                                           |
    |   Function                 Description                    |
    |===========================================================|
    |  @{"SDivMod32()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/SDivMod32()}  Signed 32 by 32-bit division and modulus.   |
    |    @{"SMult32()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/SMult32()}  Signed 32 by 32-bit multiplication.         |
    |-----------------------------------------------------------|
    |  @{"UDivMod32()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/UDivMod32()}  Unsigned 32 by 32-bit division modulus.     |
    |    @{"UMult32()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/UMult32()}  Unsigned 32 by 32-bit multiplication.       |
    |___________________________________________________________|

@ENDNODE

@NODE 37-6-4 "37 / Function Reference / International String Function Reference"
The following are brief descriptions of the utility library functions
which pertain to string operations using the international ASCII character
set.

          Table 37-9: Utility International String Functions
   _________________________________________________________________
  |                                                                 |
  |   Function               Description                            |
  |=================================================================|
  |   @{"Stricmp()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/Stricmp()}  Compare strings, case-insensitive.                 |
  |  @{"Strnicmp()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/Strnicmp()}  Compare strings, case-insensitive, with specified  |
  |              length.                                            |
  |-----------------------------------------------------------------|
  |   @{"ToLower()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/ToLower()}  Convert a character to lower case.                 |
  |   @{"ToUpper()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/ToUpper()}  Convert a character to upper case.                 |
  |_________________________________________________________________|

@ENDNODE

@NODE 37-6-5 "37 / Function Reference / Date Function Reference"
The following are brief descriptions of the utility library functions
which pertain to date conversion.


                   Table 37-10: Utility Date Functions
   ________________________________________________________________
  |                                                                |
  |    Function           Description                              |
  |================================================================|
  |   @{"CheckDate()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/CheckDate()}  Check the legality of a date.                   |
  |----------------------------------------------------------------|
  |  @{"Amiga2Date()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/Amiga2Date()}  Calculate the date from a specified timestamp.  |
  |  @{"Date2Amiga()" link ADCD_v1.2:Inc&AD2.1/autodocs/utility/Date2Amiga()}  Calculate the timestamp from a specified date.  |
  |________________________________________________________________|

@ENDNODE
