teklib : IndexToc

TEKlib / Link library documentation

By Timm S. Müller - Copyright © 2005 TEK neoscientists. All rights reserved.

Overview

The majority of TEKlib's functionality is located in shared modules. The link libraries provide functions to operate on elementary datatypes such as Lists, Handles and Tagitems, and they help to ease the Setup of applications and modules.
Setup Setup of applications and modules
Lists Lists and nodes
Handles Generic object headers with destructor
Tagitems Key/value pairs

Libraries


teklib : SetupToc

TEKlib can be embedded into regular applications using TEKCreate and provide an entrypoint for a freestanding C/C++ application, TEKMain:

Function overview

Entrypoints and startup
TEKMain Entrypoint for a freestanding application
TEKCreate Create an initial TEKlib context
Support functions for module initialization
TNewInstance Allocate a module instance
TFreeInstance Free a module instance
TInitVectors Init a module function vector table

teklib : TagitemsToc

Function overview

TGetTag Get tag value from a list of tag items
TForEachTag Call function for each item in a taglist

Introduction

One of the most versatile data structures in TEKlib are arrays of key/value pairs. These pairs are called tags, hence the term tagitem for the resulting data structure, and taglist for an array composed of tagitems:
struct TTagItem my_taglist[5] =
{
    MY_Points, vertices,
    MY_NumPoints, (TTAG) 3,
    MY_Color, (TTAG) 0xff0000,
    MY_Name, "Red triangle",
    TTAG_DONE
};
The TTAG type has the guaranteed ability to carry pointers on all architectures. This allows, in essence, to transport any kind of data in tagitems. The tti_Tag field can contain user codes and control codes. User codes are identified by their combination with TTAG_USER, for example
#define MY_Points    (TTAG_USER + 0x10001)
#define MY_NumPoints (TTAG_USER + 0x10002)
#define MY_Color     (TTAG_USER + 0x10003)
#define MY_Name      (TTAG_USER + 0x10004)
A tag not containing TTAG_USER is considered a control tag, which determines how a single item is to be interpreted, or how an array of tagitems should be traversed. The meanings of control tags are:
TTAG_DONE
End of the taglist; traversal stops at this item.
TTAG_IGNORE
tti_Value of this item is to be ignored.
TTAG_SKIP
The current item plus the number of items in tti_Value is to be ignored.
TTAG_MORE
tti_Value points to another taglist, at which traversal is to be continued. The control does not return to the current item.
TTAG_GOSUB
tti_Value points to another taglist, which is traversed recursively. After traversal, control returns to the current item.
Once a function is designed to accept a taglist argument, it becomes more invulnerable towards future API changes. By assigning a default value to each tag argument, any number of new taglist arguments can be added to the function, without ever breaking existing code:
TVOID cool_func(TTAGITEM *tags)
{
    TINT numv = (TINT) TGetTag(tags, MY_NumPoints, (TTAG) 3);
    TFLOAT *v = (TFLOAT *) TGetTag(tags, MY_Points, default_vertices);
    TSTRPTR n = (TSTRPTR) TGetTag(tags, MY_Name, "Default Triangle");
    TUINT rgb = (TUINT) TGetTag(tags, MY_Color, (TTAG) 0xff0000);
    /* ... */
}
Notes:

teklib : HandlesToc

Function overview

TDestroy Invoke destructor on a generic handle
TDestroyList Unlink and invoke destructor on handles in a list
TForEachTag Find a named handle in a list

Introduction

Handles are an extension to regular nodes, and as such they can be linked into regular Lists. Handles are headed by a node structure and carry an additional data field and a pointer to a destroy function, from now on also referred to as a destructor:
struct THandle
{
    struct TNode thn_Node;
    TAPTR thn_Data;
    TDFUNC thn_DestroyFunc;
};
Many TEKlib objects are headed by a handle structure, or use the handle's data pointer to hide their inner workings from the user. By convention, the destructor is a function that knows how to dispose the object and data that might be associated with it. The destructor is invoked by passing the handle to TDestroy.
struct Foo
{
    struct THandle foo_Handle;
    struct Stuff foo_Stuff;
};
A destructor for this kind of object may look like this:
TCALLBACK TVOID
destroy_foo(struct Foo *object)
{
    close_things(&object->foo_Stuff);
    TFree(object);
}
This function must be defined and declared using TCALLBACK, as this may be the only way for hiding compiler- or platform-specific calling conventions for a function that may be invoked outside the scope of the current library or application. If you don't want to get a compiler warning from the usage of the mismatching datatype, you can conveniently place the function into a handle using a typecast, which is aware of the TCALLBACK definition also:
handle->thn_DestroyFunc = (TDFUNC) destroy_foo;
By convention, a destructor cleans up as much of the object as possible, i.e. it usually de-initializes and frees it, but this is nowhere strictly regulated.
The data field may be a pointer to arbitrary user data, but it is most commonly used for a pointer to a C string containing a name for the object at hand. Handles conforming to this convention can be searched for in Lists using TFindHandle.
See also: Lists

teklib : ListsToc

Function overview

TAddHead Link a node to the head of a list
TAddTail Link a node to the tail of a list
TInitList Init a list header structure
TInsert Insert a node into a list
TNodeUp Move a node one position up in a list
TRemHead Unlink a node from the head of a list
TRemove Unlink a node from whatever list it is linked to
TRemTail Unlink a node from the tail of a list

Iterator

A forward iterator for a TEKlib list may look like this:
struct TNode *next, *node = list->tlh_Head;
for (; (next = node->tln_Succ); node = next)
{
    /*
     * you can operate on 'node' here, remove it safely,
     * insert past it, as well as 'break' out from and
     * 'continue' the loop.
     */
}

Introduction

Lists and nodes are among the most common data structures in TEKlib. The node structure is normally heading a user's own data structure. It is also formally extended in numerous ways, such as for Handles and module objects.
TEKlib lists are doubly-linked, with a header that acts as a marker for the head and the tail of the list. When a list header is newly initialized, its layout in memory looks like this:
list:          ,----> ,--------------.
               |  ,-- |     head     |
               |  `-> |     tail     | --> TNULL
               `----- |   tailpred   |
                      `--------------'
Initially, the head field contains a pointer to the tail and tailpred fields inside the header, which could be interpreted as a node also:
list:          ,----> ,--------------.
               |  ,-- |     head     |
               |  `-> | ,----------. |
               |      | |   succ   | | --> TNULL
               `----- | |   pred   | |
                      | `----------' |
                      `--------------'
From that perspective, the list header contains a Null node, i.e. one whose successor is TNULL. This picture remains consistent after the insertion of the first real node:
list:          ,----> ,--------------.
               |  ,-- |     head     |
               |  |   | ,----------. | <----------.
               |  |   | |   succ   | | --> TNULL  |
               |  |   | |   pred   | |            |
               |  |   | `----------' |            |
               |  |   `--------------'            |
node:          |  `---> ,----------.              |
               |        |   succ   | -------------'
               `------- |   pred   |
                        `----------'
If we were iterating the list, we came from list->head to the first real node, then from node->succ to a Null node (whose successor is TNULL), which in turns indicates the end of the list.
The same works when the list is iterated backwards. node->pred points to the head and tail fields inside the header, which can be interpreted as a node also:
list:                 ,--------------.
               ,----> | ,----------. |
               |      | |   succ   | |
               |      | |   pred   | | --> TNULL
               |      | `----------' |
               |  ,-- |   tailpred   |
               |  |   `--------------'
node:          |  `---> ,----------.
               |        |   succ   |
               `------- |   pred   |
                        `----------'
The list header fulfills the requirements of both a list's heading and trailing end marker, depending on whether it is accessed as a first node's predecessor, or as a last node's successor.
See also: Handles

teklib : TEKCreateToc

NAME
TEKCreate - Create an initial TEKlib context

SYNOPSIS
basetask = TEKCreate(tags)
TAPTR                TTAGITEM*

FUNCTION
This function creates an initial TEKlib context. All further functionality is related to and derived from this handle.
This kind of startup allows for integratation of TEKlib into foreign environments, and you can use it for writing your own startup library.
Once you are finished using TEKlib, the basetask handle is destroyed with a call to TDestroy.

INPUTS
tags Pointer to an array of tag items, or TNULL

TAGS
TExecBase_ArgC, (TUINT)
Submit a main() entrypoint's number of arguments to the framework. If applicable, argc/argv will be made available in a named atom sys.argv. See also util:TGetArgC. Default: undefined
TExecBase_ArgV, (TSTRPTR)
Submit a main() entrypoint's array of arguments to the framework. If applicable, argc/argv will be made available in a named atom sys.argv. See also util:TGetArgV. Default: undefined
TExecBase_RetValP, (TUINT *)
Submit a pointer to a possible return value. The pointer will be made available in a named atom sys.returnvalue. The variable being pointed to should be initialized with zero. See also util:TSetRetVal for setting the return value in an application. Default: undefined
TExecBase_ModInit, (struct TInitModule *)
Submit a TNULL-terminated array of internal startup modules to your application. This allows you to link modules to applications statically. Internal modules will be looked up first, i.e. before any of the search strategies for modules from disk apply. Default: TNULL
TExecBase_ProgDir, (TSTRPTR)
Override the path to TEKlib's logical PROGDIR: volume, which by default resembles to the directory in which the application resides. Default: the application directory
TExecBase_ModDir, (TSTRPTR)
Some platforms support this tag argument for setting a global search path for modules, overriding the hardcoded internal default (e.g. /opt/tek/mod). Local modules (those in PROGDIR:mod) are not affected, as those will always be probed first. Default: platform-specific.
TExecBase_SysDir, (TSTRPTR)
Some platforms support this tag argument for setting a global system directory, overriding the hardcoded internal default (e.g. C:\Programs\Common Shared Files\tek), which also resembles to the logical SYS: volume in TEKlib's filesystem namespace. Default: platform-specific.

RESULTS
basetask initial context handle
If initialization fails, this function returns TNULL. If successful, this function returns an initial task handle, referring to the process/thread context in which the caller is running. The handle is being destroyed with a call to TDestroy, which will clean up and free all resources.

NOTES
  • It is platform-specific whether you are allowed to create more than one instances of TEKlib per application. Most currently supported platforms allow this, but this would be something unadvisable to depend on.
  • Applications running in the Unix environment depend on the argv vector to determine their logical program directory. You are advised to pass the tags TExecBase_ArgC and TExecBase_ArgV. If unavailable, use TExecBase_ProgDir to supply this information directly.
  • Not all platforms support this kind of startup, since a fully-fledged TEKlib context cannot be described by the basetask handle alone. For example, if associating thread-specific data would require a manipulated stack layout, then it's possible that the respective platform can only provide TEKMain.

SEE ALSO


teklib : TEKMainToc

NAME
TEKMain - TEKlib application entrypoint

SYNOPSIS
TTASKENTRY TVOID TEKMain(TAPTR task)

FUNCTION
In a freestanding application, TEKlib resolves a platform-specific entrypoint like main() or intercepts the entrypoint provided by the platform's binary loader, performs initializations with reasonable defaults, and then enters TEKMain.
Resources such as argc, argv, return values and other properties are made available to the framework in named atoms. See TEKCreate, util:TGetArgC, util:TGetArgV, util:TSetRetVal for details.
If you need more control over the startup procedure then you can write your own startup library using TEKCreate.

EXAMPLE
Unless you write a more convenient C++ startup library of your own, the TEKlib application entrypoint for a C++ application would look like this:
extern "C" TTASKENTRY TVOID TEKMain(TAPTR task)
{
    /* ... */
}

SEE ALSO


teklib : TAddHeadToc

NAME
TAddHead - Add a node at the head of a list

SYNOPSIS
TAddHead(list,  node)
         TLIST* TNODE*

FUNCTION
Add a node at the head of a doubly linked list.

INPUTS
list Pointer to a list header
node Pointer to a node to be added

SEE ALSO


teklib : TAddTailToc

NAME
TAddTail - Add node at the tail of a list

SYNOPSIS
TAddTail(list, node) TLIST* TNODE*

FUNCTION
Add a node at the tail of a doubly linked list.

INPUTS
list Pointer to a list header
node Pointer to a node to be added

SEE ALSO


teklib : TRemoveToc

NAME
TRemove - Unlink a node from a list

SYNOPSIS
TRemove(node) TNODE*

FUNCTION
Unlink a node from whatever list it is linked to.

INPUTS
node Pointer to a node to be removed

NOTES
  • Using this function with a node not being part of a list will be fatal.

SEE ALSO


teklib : TRemHeadToc

NAME
TRemHead - Unlink the first node from a list.

SYNOPSIS
node = TRemHead(list)
TNODE*          TLIST*

FUNCTION
Unlink and return the first node from a doubly linked list.

INPUTS
list Pointer to a list header

RESULTS
node Pointer to the node being unlinked from the list, or TNULL

SEE ALSO


teklib : TRemTailToc

NAME
TRemTail - Unlink the last node from a list

SYNOPSIS
node = TRemTail(list)
TNODE*          TLIST*

FUNCTION
Unlink and return the last node from a doubly linked list.

INPUTS
list Pointer to a list header

RESULTS
node Pointer to the node being unlinked from the list, or TNULL

SEE ALSO


teklib : TDestroyToc

NAME
TDestroy - Invoke destructor on a handle

SYNOPSIS
TDestroy(handle)
         THNDL*

FUNCTION
Destroy a generic handle by calling its destructor. If either handle or handle->thn_DestroyFunc is TNULL then nothing will happen.

INPUTS
handle Pointer to a generic object handle

NOTES
  • No memory whatsoever will be freed by this function outside the destructor.

SEE ALSO


teklib : TInitListToc

NAME
TInitList - Prepare list header

SYNOPSIS
TInitList(list)
          TLIST*

FUNCTION
Prepare a list header structure. After initialization the list will be empty and ready for use.

INPUTS
list Pointer to a list structure

SEE ALSO


teklib : TInsertToc

NAME
TInsert - Insert a node into a list

SYNOPSIS
TInsert(list,  node,  prednode)
        TLIST* TNODE* TNODE*

FUNCTION
Insert a node into a list after prednode. If prednode is TNULL, then this function is equivalent to TAddTail.

INPUTS
list Pointer to a list to insert to
node Pointer to a node to insert
prednode Pointer to a node in the list after which to insert

SEE ALSO


teklib : TNodeUpToc

NAME
TNodeUp - Move a node upwards

SYNOPSIS
TNodeUp(node)
        TNODE*

FUNCTION
Move a node one position towards the head of the list it is linked to. In other words, if the node is not already at the head of the list, swap its position with its predecessor.

INPUTS
node Pointer to a node

NOTES
Using this function with a node not being part of a list will be fatal.

SEE ALSO


teklib : TGetTagToc

NAME
TGetTag - Get tag value from a tag list

SYNOPSIS
value = TGetTag(taglist,  tag,  defvalue)
TTAG            TTAGITEM* TUINT TTAG

FUNCTION
Parse a list of tag items and return the value associated with the first matching tag identifier. If the specified tag is not contained in the list, then the default value is returned.
A taglist is a pointer to an array of tagitems. Each tagitem is composed from a tag/value pair. Many TEKlib functions accept a taglist argument for making them more robust for future extensions.
The tag field can contain control tags and user tags. User tags must be combined with the TTAG_USER flag. Control tags are:
TTAG_DONE
This is the last entry of the array. traversal stops here.
TTAG_IGNORE
This item is being ignored.
TTAG_SKIP
Skip this item plus the number of items contained in value.
TTAG_MORE
Value is a pointer to another array oftagitems. Traversal is continued at the new array, and does not return.
TTAG_GOSUB
Value is a pointer to another array of tagitems. After return from the sub-array, traversal continues here.

INPUTS
taglist Pointer to an array of tag items
tag Tag to be queried
defvalue Default value

RESULTS
value Value associated with the tag in the taglist, otherwise the default value

NOTES
  • The TTAG type is capable of carrying pointers. This allows, in essence, to transport any kind of data in tag items, even on 64bit architectures. An unfortunate side-effect is that assigning a value to tti_Value may require a typecast to TTAG for getting rid of complaints from the compiler.

SEE ALSO


teklib : TDestroyListToc

NAME
TDestroyList - Destroy handles in a list

SYNOPSIS
TDestroyList(list)
             TLIST*

FUNCTION
Unlinks all nodes from a list (in first-to-last order) and calls TDestroy on each individual entry. Note that this function expects all nodes (or their heading structure) to be of the generic handle datatype, otherwise the consequences would be nasty.
Nothing will happen if list is TNULL or if the list is empty.

INPUTS
list list to clear

SEE ALSO


teklib : TNewInstanceToc

NAME
TNewInstance - Get a module instance copy

SYNOPSIS
inst = TNewInstance(mod,  possize, negsize)
TAPTR               TAPTR TUINT    TUINT

FUNCTION
This function creates a module instance copy. The module base can be duplicated alongside with a preceding function table.
Possize and negsize determine the size of the module base and the size of a preceding function table, respectively. Usually these arguments will be set to mod->tmd_PosSize and mod->tmd_NegSize, which will create an exact copy a of the module. However this function can be used to extend the module base and function table as well.
A pointer to the duplicated module base is returned. TNewInstance is typically used in a module's instance open function.

INPUTS
mod Pointer to module base
possize Positive size of the module, in bytes
negsize Negative size of the module, in bytes
The negative size is the size of the function table that normally precedes the module base.

RESULTS
inst A copy of the module base and function table, or TNULL

SEE ALSO


teklib : TFreeInstanceToc

NAME
TFreeInstance - Free a module instance copy

SYNOPSIS
TFreeInstance(inst)
              TAPTR

FUNCTION
This function frees a module instance. It takes into account the size of the module base as well as its 'negative size', i.e. the size of the function table that may be located in front of it.
This function is normally used in a module's instance close function.

INPUTS
inst Pointer to a module instance

SEE ALSO


teklib : TInitVectorsToc

NAME
TInitVectors - Copy module vector table

SYNOPSIS
TInitVectors(mod,  vectors, numv)
             TAPTR TAPTR*   TUINT

FUNCTION
This function takes a pointer to a table of function pointers and places them in front of a module base (in reverse order - a simple memory copy would be insufficient here). This function is normally used in a module's init function.

INPUTS
mod Module base pointer
vectors Pointer to a table of function pointers
numv Number of entries

SEE ALSO


teklib : TFindHandleToc

NAME
TFindHandle - Find a named handle in a list

SYNOPSIS
handle = TFindHandle(list,  name)
TAPTR                TLIST* TSTRPTR

FUNCTION
Find the first occurance of a named handle in a list. The name is expected in each node's handle->thn_Data field. Only lists containing only nodes with a conforming object handle may be searched with this function. Name comparison is case-sensitive.

INPUTS
list Pointer to a list structure
name Name of a handle to look up

RESULTS
handle Ptr to named handle, or TNULL if not found in the list

SEE ALSO


teklib : TForEachTagToc

NAME
TForEachTag - Call user function for each item in a taglist

SYNOPSIS
complete = TForEachTag(taglist,  function,       userdata)
TBOOL                  TTAGITEM* TTAGFOREACHFUNC TAPTR

FUNCTION
This function traverses a list of tagitems, and for each item it calls a user-supplied function according of the following type:
TCALLBACK TBOOL function(TAPTR userdata, TTAGITEM *item)
The userdata argument is passed to the callback function and otherwise remains invisible to TForEachTag. The callback function has to return TTRUE to continue traversal, or TFALSE to abort.
When all items were traversed without interruption, then the return value from TForEachTag will be TTRUE. TFALSE will be returned otherwise.

INPUTS
taglist an array of tagitems to traverse
function callback function to call for each item traversed
userdata user data argument passed to the callback function

RESULTS
complete TTRUE if the list was traversed completely
The return value will be TFALSE if the callback function returned TFALSE.

SEE ALSO


teklib : ABOUTToc

SHORT
Documentation of TEKlib link libraries, and introduction to elementary datatypes (lists, handles, tagitems)

VERSION
$Id: teklib.html,v 1.10 2005/07/11 21:14:33 tmueller Exp $

REVISION HISTORY
$Log: teklib.html,v $ Revision 1.10 2005/07/11 21:14:33 tmueller fixed, re-generated Revision 1.2 2005/06/28 16:15:05 tmueller updated, rerendered
Revision 1.1 2005/06/19 20:46:04 tmueller moved
Revision 1.8 2004/06/04 00:19:31 tmueller Minor fixes
Revision 1.7 2004/04/14 22:33:41 tmueller Improvements
Revision 1.6 2004/04/14 12:46:58 tmueller Improved wording and corrections
Revision 1.5 2004/02/13 04:53:21 tmueller Improved wording
Revision 1.4 2004/02/11 15:23:26 tmueller Improved
Revision 1.3 2004/02/07 05:00:42 tmueller Fixed and improved
Revision 1.2 2004/02/06 22:16:13 tmueller Cleanup, redesign, introductory chapters added. TForEachTag documented.
Revision 1.1.1.1 2003/12/11 07:17:19 tmueller Krypton import


teklib : Table of contents


Generated Mon Jul 11 22:13:30 2005 from teklib.doc