This file documents the RLSystems Swing Library V1 and contains a
complete documentation of this library. Additional documentation is
provided in libSwing.doc and in the engine model.

   This file should always accompany and be accompanied by the rest of
the package of which the Swing library is a part, as distributed by
Dlanor Blytkerchan and/or RLSystems. It may be re-distributed free of
charge by anyone who cares to do so, as long as the package remains in
tact.

   Copyright (c) 2000 Dlanor Blytkerchan <dlanor@dds.nl>

The RLSystems Swing library V1
******************************

   This is the documentation for the RLSystems Swing library V1 (LSW1)
by Dlanor Blytkerchan.

   Hopefully, this will guide you through the library and it's
functions.  Should you have any question after reading this, please
don't hestitate to contact Dlanor at <dlanor@dds.nl>

The Engine Model
****************

   The Engine Model is an article written by Dlanor Blytkerchan and is
available in PDF format for free, if you mail him. It is accompanied by
a Software Development Kit which includes this library, and is meant to
make it easier to implement the model in your own software.

   The Engine Model was written primarily for beginning programmers
with no set programming style of their own, and for programmers in
general who would like to organize their source files a bit better. it
is platform- and langauge-independant and contains a lot of examples in
C, to elucidate the implementation of the model.

   The Engine Model itself took about a decade to develop, having been
in development from the very first time I ever wrote a program, and is a
collection of ideas and notions that have matured throughout that
decade to a full-fledged system in which any program can be implemented
in any language, no matter whether it is functional, imperitive or
object-oriented, and no matter what platform the programs are compiled
to.

   *Note The Author::.

Installing the library
**********************

   Installing this library is very simple: just unzip the library into
your DJGPP directory, and all the files will be put into place. That
includes this info file, which is included as of version 1.1.1 release
1 for the library.

   If you're installing the library for the very first time, you should
type the following from your DJGPP/INFO directory:

     install-info -d dir -i libSwing

This will install this documentation, in INFO format, into the
directory of your info files (the one you see if you only type `info'
on the command-line).

Introduction
************

   The Swing Library was designed to aid in the application of the
model, and contains a collection of housekeeping methods and methods I
found lacking from the language C. It consists of a number of modules,
all written in C.

   No knowledge of the Engine Model is required to use this library,
and this library is not required to use the Engine Model. The only link
between the two is that the Swing library was designed to aid in the
implementation of the Engine Model, for which purpose the Housekeeping
methods were created.

   As you read this documentation, you will probably find there's
nothing in this library you could not have written yourself. The only
reason this library might come in handy, is that these methods, though
simple and straightforward by nature, are really very flexible, and
have already been written so you don't have to do it yourself. Though I
try re-inventing the wheel every chance I get, I don't think it's
really necessary for you to have to do the same..

   If you find anything lacking from this library, or have something
you would like to add, please contact me (*Note The Author::.).

The Setup of The Swing Library
******************************

   The Swing Library is set up in such a way that you can use a single
header file, <swing.h>, to use all the features of the library. You can
simply add #include <swing.h> to your source code to access the
features. The <swing.h> header doesn't contain much - just definitions
of some variable types common to other languages, but not to C, and the
initSwing() (*Note initSwing::.)  method, to initialize the library.
The rest of the features if accessible from the other modules in the
Swing library, which are included using the LSW1_* defines before
including the <swing.h> file. All can be included simultaniously using
LSW1_All like this:

     #define LSW1_All
     #include <swing.h>

For more info, read the next node, about the modules of the library.

The Modules in the Swing Library
********************************

   The Swing Library consists of the following modules:

   These modules can be used seporatly, with only their own headers
being included, using the LSW1_* defines. The easiest way to use them,
is by including them all, using this code to begin your source code:

     #define LSW1_All
     #include <swing.h>

This will include all the modules.

The Swing Module
****************

   The Swing module consists of only one method you should call:
initSwing() (*Note initSwing::.).

initSwing()
***********

Syntax
======

     #include <swing.h>
     
     bool initSwing(void);

Description
===========

   initSwing() initializes the library. You MUST call this method
before you do anything else with the library.

Return value
============

   true if successful, false if not.

The Housekeeping Module
***********************

   This module contains the methods used to implement the Engine Model.
All that is needed to trap and identify errors is located here. The
actual trapping will still be your job, as will the actual identifying,
but this module should point the way on how to do it, and help you
handle errors using the generic error handler (Note: generic, not
general.)

   Use the module with `#define LSW1_houseKeeping'. The <houseKeeping.h>
header file defines a lot of errors that may occur in this library
(predominantly when used wrong or your computer fails), and some
significant for the VPL3 library (which you probably won't need unless
you're programming for VGA Planets).

initHousekeeping()
******************

Syntax
======

     #define LSW1_houseKeeping
     #include <swing.h>
     
     bool initHousekeeping(void);

Description
===========

   This initializes the housekeeping module of the Swing library. As it
is called by initSwing(), you will not need to call it yourself - ever
- so don't.

Return value
============

   true if successful, false if not

doneHousekeeping()
******************

Syntax
======

     #define LSW1_houseKeeping
     #include <swing.h>
     
     void doneHousekeeping(void);

Description
===========

   This shuts down the housekeeping module of the Swing library. As it
is called by doneSwing(), you will not need to call it yourself - ever
- so don't.

Return value
============

   none

addError()
**********

Syntax
======

     #define LSW1_houseKeeping
     #include <swing.h>
     
     bool addError(errorType *e);

Description
===========

   Adds an error to the error list. The error list is a list of error
descriptors of type `errorType', which is defined as:
     typedef struct _errorType {
       bool  isDefined;          // always true (except in empty error)
       int   code;               // number of the error
       char  *errorMessage;      // message displayed for the error
       bool  (*handler)(void);   // handler for the error
       bool  isFatal;            // is this error always fatal?
     } errorType;
    The `isDefined' field is used only by the housekeeping module
itself - you should not try to alter it, and for new errors, it should
always be true. The `code' field holds a unique identifyer of the error,
which can best be represented by a define somewhere in your own source
code.  The `errorMessage' field holds an error message, which is
displayed when the error has occured, was trapped and identified, and
the generic handler was called. The `handler' field is a pointer to the
handler of the error or NULL if none is available. The error handler
should handle the error and be able to do so at any time. It is part of
your own program, and you should write it yourself. The `isFatal' field
signifies whether the error is fatal or not, even if handled correctly.
If no handler is specified and the error is not fatal, the generic
handler only displays a warning message. If the error is not fatal but
a handler has been specified, the handler is invoked and, if
successful, a warning message is displayed. If the handler is not
successful, the error is considered to be fatal anyway. If the error is
fatal and a handler has been specified, the handler is invoked and an
error message is displayed, after which the program is shut down,
regardless of whether or not the handler was successful.

Example code
============

     #define LSW1_houseKeeping
     #include <swing.h>
     
     /* ... */
     bool handleMyError(void) {
       bool rv = true;
     
       /* ... do what ever it takes ... */
     
       return(rv);
     } // handleMyError()
     
     bool initErrorList(void) {
       bool rv = true;
       errorType eList[] = {
         {true,  EMYERROR, "My error has occured!", handleMyError, false},
         {false, 0,        NULL,                    NULL,          true},
       } // eList[]
       int i;
     
       for (i = 0; rv && eList[i].isDefined; i++) {
         if (rv) rv = addError(&(eList[i]));
       } // for
     
       return(rv);
     } // initErrorList()

Return value
============

   true if successful, false if not

removeError()
*************

Syntax
======

     #define LSW1_houseKeeping
     #include <swing.h>
     
     bool removeError(int e);

Description
===========

   Removes an error from the error list (For more information about the
error list, *Note addError::.) by it's unique ID number. This method is
almost never used, and I frankly don't see how it could come in handy,
as it is rather easy to maintain a list of different error numbers
without having them overlap, but what you can add, you should be able
to remove..

Return value
============

   true if successful, false if not.

beep()
******

Syntax
======

     #define LSW1_houseKeeping
     #include <swing.h>
     
     void beep(void);

Description
===========

   Makes the computer beep, through normal speakers.

Example
=======

     #define LSW1_houseKeeping
     #include <swing.h>
     
     /* ... */
     
     int myBleepingMethod(/* ... */) {
       /* ... */
       beep();
       /* ... */
     } // myBleepingMethod()
     
     /* ... */

Return value
============

   none.

isFatal()
*********

Syntax
======

     #define LSW1_houseKeeping
     #include <swing.h>
     
     bool isFatal(int e);

Description
===========

   Checks the error list for a certain error, and returns whether it is
fatal (true) or not (false). If the error is undefined, it is fatal by
default.

Return value
============

   true if the error is fatal or undefined, false if it isn't fatal.

done()
******

Syntax
======

     #define LSW1_houseKeeping
     #include <swing.h>
     
     void done(int e);

Description
===========

   Shuts down the program with an error message beginning with: `Error:
'.  The actual error message is defined by the type of error that has
occured, which is passed to the method.

Example
=======

     #define LSW1_houseKeeping
     #include <swing.h>
     
     /* ... */
     bool rv = true; // global RunControl variable
     /* ... */
     int main(int argc, char **argv) {
       /* ... */
       if (rc) {
         return(0);
       } else done(errCode);
     } // main()

Note that errCode is a standard variable from the Engine Model, as is
the RunControl variable. The model defines that, if an error has
occured, errCode is set to the error, if trapped and identified, and
the RunControl variable (usually called `rc') is cleared. As long as rc
is set, the program can continue with whatever it is doing. If it's
cleared, handle() should be called if it's possible that the error is
non-fatal. Otherwise, the program should shut down. Unidentified errors
leave errCode at 0 (EUNKN) which would have done() display a message:
`Error: an unknown error has occured (EUNKN)';

Return value
============

   Doesn't return.

cancel()
********

Syntax
======

     #define LSW1_houseKeeping
     #include <swing.h>
     
     void cancel(int e);

Description
===========

   Very much like done() (*Note done::.) it shuts down the program. In
stead of a message starting with `Error: ' it starts the message with
`Abort: ', but aside from that, it does exactly the same.

   It is most often used when the user aborts the program for some
reason, while done() is most often used to shut down the program when
an error has occured.

Return value
============

   Doesn't return.

warning()
*********

Syntax
======

     #define LSW1_houseKeeping
     #include <swing.h>
     
     void warning(int e);

Description
===========

   Displays a warning message starting with `Warning: '. The actual
message is defined by the error number passed to the method, which
should appear in the error list. It is most often used if some
non-fatal error has occured.

Return value
============

   none

handle()
********

Syntax
======

     #define LSW1_houseKeeping
     #include <swing.h>
     
     bool handle(int e);

Description
===========

   Generic error handler. If an error has occured that might be
non-fatal (or might have a handler), pass the error code to this
handler. It will look the error up in the error list and invoke the
handler (if any).

Example
=======

     #define LSW1_houseKeeping
     #include <swing.h>
     
     /* ... */
     bool myDispatcher(void) {
       bool rv = true;
     
       /* ... */
       if (rv) rv = someFunction();
       if (!rv) rv = handle(errCode);
       /* ... */
     
       return(rv);
     } // myDispatcher()
     /* ... */

Return value
============

   true if the error was handled successfully, and non-fatal, false if
the error was not handled successfully, or it was fatal.

The User I/O Module
*******************

   The User I/O Module contains a number of methods designed to take
some of the hassle involved in user I/O away. It contains two types of
methods: user input methods, and user output methods.

   The user input methods allow you to get any type of input from the
user, in a way that doesn't require the user to adhere to any specific
formats, as the standard C methods do. As you cannot actually control
the type of input the user will give you, formatted input doesn't
always cut it, and unformatted input is often more of a hassle that
you'd like. The user input methods of this module are designed to only
take the input allowed by you, and beep on anything else. If you want a
number between two boundaries, and only between those two, (like a
percentage, a time, a valid date, etc.)  these will allow the user to
only input those allowable values, and nothing else.

   The user output methods allow you to easily handle LOG files: just
open a LOG file and use duelprint() in stead of printf() and fprintf().
Regardless of whether you have or have not opened a LOF file, duelprint
will always produce output on the screen. If a LOG file is open, it
will also put the output in the LOG file. The only restriction is that
you use the logFile file pointer for your LOG file. the openLogFile()
and closeLogFile() methods make this natural.

   Use this module with `LSW1_userIO' when include <swing.h>

openLogFile
***********

Syntax
======

     #define LSW1_userIO
     #include <swing.h>
     
     bool openLogFile(char *fN, bool doCreate);

Description
===========

   Opens a LOG file, creates it if wanted (if doCreate is set to true)

Return value
============

   true if successful, false if not. If the LOG file does not exist and
doCreate was not set, it will always fail, so handling that error would
consist of another call to openLogFile() with doCreate set.

closeLogFile
************

Syntax
======

     #define LSW1_userIO
     #include <swing.h>
     
     bool closeLogFile(void);

Description
===========

   Closes the LOG file and clears the logFile pointer.

Return value
============

   true if successful, false if not. Regardless whether the actual
closing of the file succeeded, logFile will be cleared on return from
this method.

duelprint
*********

Syntax
======

     #define LSW1_userIO
     #include <swing.h>
     
     bool duelprint(char *fmt, ...);

Description
===========

   Outputs a formatted string (formatted just like the printf() family)
to the screen and (if open) the LOG file. It checks the global logFile
pointer to see if the LOG file is opened. logFile should be NULL if the
LOG file is closed.

Example
=======

     #define LSW1_userIO
     #include <swing.h>
     
     /* ... */
     
     /* ... */ myMethod(/* ... */) {
       bool rv = true;
     
       /* ... */
       if (rv) rv = duelprint("Hello, world!\nIt\'s %d degrees outside, and I'm %s happy about it!", temp, ((temp < 25) ? ("not") : ("very")));
       /* ... */
     } // myMethod()

Return value
============

   true if successful, false if not. If logFile is not open, it is
always successful.

duelprinterror
**************

Syntax
======

     #define LSW1_userIO
     #include <swing.h>
     
     bool duelprinterror(char *fmt, ...);

Description
===========

   Outputs a formatted string (formatted just like the printf() family)
to stderr and (if open) the LOG file. It checks the global logFile
pointer to see if the LOG file is opened. logFile should be NULL if the
LOG file is closed.

Notes
=====

   Available from version 1, revision 1, edition 1, release 1 of this
library.

scan
****

Syntax
======

     #define LSW1_userIO
     #include <swing.h>
     
     bool scan(char*, int);

Description
===========

   Let's the user input a number of characters through the keyboard -
unformatted - and puts them in the character array..

Example
=======

     #define LSW1_userIO
     #include <swing.h>
     
     /* ... */
     /* ... */ myMethod(/* ... */) {
       bool rv = true;
       char theInput[21];
       /* ... */
     
       if (rv) printf("Now input up to 20 characters");
       if (rv) rv = scan(theInput, 20);
     
       /* ... */
     } // myMethod()

Return value
============

   true if successful, false if not. Pressing ESC or control-C will
abort the input. Pressing enter will finish the input regardless of the
length.

scanKey
*******

Syntax
======

     #define LSW1_userIO
     #include <swing.h>
     
     char scanKey(char *keys);

Description
===========

   Let's the user input a single character and will only accept
characters from a pre-defined set.

Example
=======

From UUE:
     #define LSW1_userIO
     #include <swing.h>
     
     /* ... */
     bool ask(char *fmt, ...) {
       bool rv = true;
       short count;
       va_list arg;
       char c;
     
       va_start(arg, fmt);
       count = vprintf(fmt, arg);
       if (rc && logFile) rv = (vfprintf(logFile, fmt, arg) == count);
       if (rc) rc = (fflush(stdout) == 0);
       if (rc && logFile) rc = (fflush(logFile) == 0);
       va_end(arg);
       if (rc && assumeYes) {
         duelprint(" YES\n");
       } else if (rc && assumeNo) {
         duelprint(" NO\n");
       } else if (rc) {
         c = scanKey("yYnN");
         if ((c == 'y') || (c == 'Y')) {
           rv = true;
           duelprint(" YES\n");
         } else {
           rv = false;
           duelprint(" NO\n");
         } // if
       } // if
     
       return(rv);
     } // ask()
     
     /* ... */

Return value
============

   The character entered.

scanDate
********

Syntax
======

     #define LSW1_userIO
     #include <swing.h>
     
     bool scanDate(long *date);

Description
===========

   Allows the user to input a valid date and puts it's value in the DATE
parameter. Using the Date and Time module in this library (*Note The
Date and Time Module::.), you can change the value to a readable date.
The value is the number of days since 01-01-0001.

Return value
============

   true if successful, false if not (user aborted with ESC or ctrl-C).

scanTime
********

Syntax
======

     #define LSW1_userIO
     #include <swing.h>
     
     bool scanTime(long *time);

Description
===========

   Allows the user to input a valid time and puts it's value in the TIME
parameter. Using the Date and Time module in this library (*Note The
Date and Time Module::.), you can change the value to a readable time.
The value is the amount of seconds since midnight.

Return value
============

   true if succesful, false if not (user aborted with ESC or ctrl-C).

scanPercentage
**************

Syntax
======

     #define LSW1_userIO
     #include <swing.h>
     
     bool scanPercentage(byte *P);

Description
===========

   Allows the user to input a valid percentage (0 - 100%), and returns
it in P.

Return value
============

   true if succesful, false if not (user aborted with ESC or ctrl-C).

scanNumber
**********

Syntax
======

     #define LSW1_userIO
     #include <swing.h>
     
     int scanNumber(int lo, int hi);

Description
===========

   Allows the user to input an integer between LO and HI and returns
the value.

Return value
============

   the value entered, or (LO - 1) on failure (user aborted with ESC or
ctrl-C).

The File I/O Module
*******************

   This module contains just one method at the moment, which I found
lacking from the C language. ANSI-C doesn't give you any "nice" way to
hget the length of a file, and filelength() isn't ANSI or POSIX, so I
made flength, which uses an ANSI-compliant way to get the file length.

   Use this module with `LSW1_fileIO' when including <swing.h>

flength()
*********

Syntax
======

     #define LSW1_fileIO
     #include <swing.h>
     
     long flength(FILE *F);

Description
===========

   Gets the length of an open file F.

Return value
============

   The length of the file, or -1 on error.

The Date and Time Module
************************

   The Date and Time Module allows for intuitive date and time handling,
without having to think about Y2K, computer ticks, milliseconds, etc.
etc.

   I've always found the "standard" ways of handling dates and times a
bit too complicated to explain to the computing dummies, so I decided
to make it a bit more intuitive: this module regards any time of day as
the number of seconds since midnight, and the date as the number of
days since the start of our calendar. This makes it very easy to handle
times and dates and to calculate what day it is, what date it is
(keeping leapyears in mind) etc.  It is completely Y2K
compliant/compatible, so you never have to think about any of this
again.

   On request, the chistian and muslim holidays can be implemented. I
know the christian ones, but not the muslim ones, so if someone wants
them implemented, I'll need a list of them..

   I'll also be happy to implement other calendars (the lunar calendar,
jewish calendar, etc.) on request, if someone can provide me with the
specs..

   Use this module with `LSW1_dateAndTime' when including <swing.h>

isLeap
******

Syntax
======

     #define LSW1_dateAndTime
     #include <swing.h>
     
     bool isLeap(unsigned int Y); // actually: it's a macro

Description
===========

   Determines whether or not the input year Y is a leapyear (has an
extra day in February). It is actually a macro, but you should consider
it as the method `bool isLeap(unsigned int Y)'.

Return value
============

   true (actually: 1) if the year is a leapyear, false if not.

daysInYear
**********

Syntax
======

     #define LSW1_dateAndTime
     #include <swing.h>
     
     int daysInYear(unsigned int Y); // actually: it's a macro

Description
===========

   Determines the number of days in a given year. Though it is actually
a macro, you should handle it as if it's defined as `int
daysInYear(unsigned int Y);'.

Return value
============

   The number of days in the given year.

daysInMonth
***********

Syntax
======

     #define LSW1_dateAndTime
     #include <swing.h>
     
     int daysInMonth(unsigned int M, unsigned int Y); // actually a macro

Description
===========

   Determines the number of days (28, 29, 30 or 31) in a given month.

Return value
============

   The number of days in the given month. Note that if the month is
invalid, the macro still returns 30 by default!

isValidYear
***********

Syntax
======

     #define LSW1_dateAndTime
     #include <swing.h>
     
     bool isValidYear(int Y); // actually a macro

Description
===========

   Determines whether a given year is in the calendar (is higher than
0).

Return value
============

   true if Y > 0, else false.

isValidMonth
************

Syntax
======

     #define LSW1_dateAndTime
     #include <swing.h>
     
     bool isValidMonth(int M); // actually a macro

Description
===========

   Determines whether a given month is valid (greater than or equal to
1; smaller than or equal to 12).

Return value
============

   true if the given month is valid, false if not.

isValidDay
**********

Syntax
======

     #define LSW1_dateAndTime
     #include <swing.h>
     
     bool isValidDay(int D, int M, int Y); // actually a macro

Description
===========

   Determines whether the given day is possible in the given month, in
the given year, but does not check the month and year for validity.

Return value
============

   true if valid, false if not.

isValidDate
***********

Syntax
======

     #define LSW1_dateAndTime
     #include <swing.h>
     
     bool isValidDate(int D, int M, int Y); // actually a macro

Description
===========

   Determines whether a given date is valid. Checks whether the year is
valid, whether the month is valid, whether the day is valid, and wether
the month had enough days for the given day: while `isValidDate(29, 2,
1996)' will return true, `isValidDate(29, 2, 1997)' will not, because
the 29th of February never existed in 1997, while it did in 1996.

Return value
============

   true if the date is valid, false if not.

numToDate
*********

Syntax
======

     #define LSW1_dateAndTime
     #include <swing.h>
     
     void numToDate(int N, int *D, int *M, int *Y);

Description
===========

   Converts a date number to a date. The date number is the amount of
days passed since 01-01-0001, and is the standard way the Swing library
uses to calculate dates. numToDate() takes leap years etc. into
account, and is Y2K compliant.

Return value
============

   none

dateToNum
*********

Syntax
======

     #define LSW1_dateAndTime
     #include <swing.h>
     
     int dateToNum(int D, int M, int Y);

Description
===========

   Converts a date to a date number. The date number is the amount of
days passed since 01-01-0001, taking leap years etc. into account. This
is the standard way the Swing library handles dates, and is Y2K
compliant.

Return value
============

   The date number corresponding to the given date.

numToDay
********

Syntax
======

     #define LSW1_dateAndTime
     #include <swing.h>
     
     dayType numToDay(int n);

Description
===========

   Converts a given date number to the corresponding day. dayType is
defined as:
     typedef enum {
       _sunday_,
       _monday_,
       _tuesday_,
       _wednesday_,
       _thursday_,
       _friday_,
       _saturday_
     } dayType;

Return value
============

   The day corresponding to the given date number.

dateToDay
*********

Syntax
======

     #define LSW1_dateAndTime
     #include <swing.h>
     
     dayType dateToDay(int D, int M, int Y);

Description
===========

   Converts a given date to the corresponding day. dayType is defined
as:
     typedef enum {
       _sunday_,
       _monday_,
       _tuesday_,
       _wednesday_,
       _thursday_,
       _friday_,
       _saturday_
     } dayType;
    This is Y2K compliant.

Return value
============

The day corresponding to the given date,

timeToNum
*********

Syntax
======

     #define LSW1_dateAndTime
     #include <swing.h>
     
     long timeToNum(int H, int M, int S);

Description
===========

   Converts a given time to a time number, which is the number of
seconds passed since midnight.

Return value
============

   The time number corresponding to the given time.

isValidTime
***********

Syntax
======

     #define LSW1_dateAndTime
     #include <swing.h>
     
     bool isValidTime(int H, int M, int S);

Description
===========

   Determines whether a given time is valid.

Return value
============

   true if the time is valid, false if not.

numToTime
*********

Syntax
======

     #define LSW1_dateAndTime
     #include <swing.h>
     
     void numToTime(int N, int *H, int *M, int *S);

Description
===========

   Converts a given time number to a valid time. If the time number is
greater than the amount of seconds in a day, the time on the next day
is returned.

Return value
============

   none

currentTimeNum
**************

Syntax
======

     #define LSW1_dateAndTime
     #include <swing.h>
     
     long currentTimeNum(void);

Description
===========

   Gets the time number of the current time.

Return value
============

   The number of seconds passed since midnight, now.

currentTime
***********

Syntax
======

     #define LSW1_dateAndTime
     #include <swing.h>
     
     void currentTime(int *H, int *M, int *S);

Description
===========

   Gets the current time.

Return value
============

   none

The Str_ngs Module
******************

   This module contains a couple of methods I found lacking frm the C
language.  These primarily include methods found in the BASIC language.
Some of them actually do have C counterparts, but not all of them.

   You should probably know that BASIC was the first language I started
programming in. I've made most of these methods in every other language
I programmed in ever since.

   Use this module with `LSW1_strings' when including <swing.h>

copyPath()
**********

Syntax
======

     #define LSW1_strings
     #include <swing.h>
     
     void copyPath(char s1[], char s2[]);

Description
===========

   Copies the path-part from S2 to S1 and converts backslashes (\) to
forward slashes as it does so.

Return value
============

   none

invert()
********

Syntax
======

     #define LSW1_strings
     #include <swing.h>
     
     char *invert(char s[]);

Description
===========

   Inverts a string.

Return value
============

   The inverted string (pointer to S).

left()
******

Syntax
======

     #define LSW1_strings
     #include <swing.h>
     
     char *left(char s[], short length);

Description
===========

   Strips anything off S that doesn't fit within the first LENGTH
characters.

Return value
============

   A pointer to S

right()
*******

Syntax
======

     #define LSW1_strings
     #include <swing.h>
     
     char *right(char s[], short length);

Description
===========

   Takes the first characters out of S, as far as required to leave the
last LENGTH characters. It does not to so by simply increasing the
pointer to S, so you can still use `free()' on it.

Return value
============

   A pointer to S.

uCase()
*******

Syntax
======

     #define LSW1_strings
     #include <swing.h>
     
     char *uCase(char *s);

Description
===========

   Converts S to upper case. This does not handle high-bit characters,
because they vary in different charsets.

Return value
============

   A pointer to S.

lCase()
*******

Syntax
======

     #define LSW1_strings
     #include <swing.h>
     
     char *lCase(char *s);

Description
===========

   Converts S to lower-case characters. This does not handle high-bit
characters because they vary in different charsets.

Return value
============

   A pointer to S.

val()
*****

Syntax
======

     #define LSW1_strings
     #include <swing.h>
     
     int val(char s[]);

Description
===========

   Gets the value of the string S.

Return value
============

   The value of S, or 0 if it contains non-digit characters.

str()
*****

Syntax
======

     #define LSW1_strings
     #include <swing.h>
     
     char *str(int i, char s[]);

Description
===========

   Makes a string with an integer value.

Example
=======

     #define LSW1_strings
     #include <swing.h>
     /* ... */
     char s[6]
     printf("%s", str(65536, s));
     /* ... */

This would put `65536' on the screen, and leave it in s.

Return value
============

   A pointer to S.

hex()
*****

Syntax
======

     #define LSW1_strings
     #include <swing.h>
     
     char *hex(int n, char s[]);

Description
===========

   Puts the hexadecimal representation of N in S.

Return value
============

   A pointer to S.

hex2Int()
*********

Syntax
======

     #define LSW1_strings
     #include <swing.h>
     
     unsigned int hex2Int(char *s);

Description
===========

   Calculates the integer value represented by the hex string S.

Return value
============

   The integer value represented by S or 0xFFFFFFFFL if S is not a
valid hex number.

The Memory I/O Module
*********************

   This module contains a number of methods I found lacking from C.
Most of them are available in C for NULL-terminated strings, but not
for any-length memory buffers. They are named after their
string-counterparts and behave mostly the same.

   Use this module with `LSW1_memIO' when including <swing.h>

memstr()
********

Syntax
======

     #define LSW1_memIO
     #include <swing.h>
     
     void *memstr(const void *buffer, const char *sFind, const int length);

Description
===========

   Finds a string `sFind' in a memory block `buffer' of length `length'.

Return value
============

   A pointer to the first character of `sFind' in `buffer' or NULL if
it wasn't found.

memspn()
********

Syntax
======

     #define LSW1_memIO
     #include <swing.h>
     
     void *memspn(const void *buffer, const char *sFind, const int length);

Description
===========

   Finds the first character that matches any of the characters from
`sFind' in memory block `buffer' of length `length'.

Return value
============

   A pointer to the first character from `sFind' found in `buffer' or
NULL if it wasn't there.

memrchr()
*********

Syntax
======

     #define LSW1_memIO
     #include <swing.h>
     
     void *memrchr(const void *buffer, const char cFind, const int length);

Description
===========

   Finds the character `cFind' in memory block `buffer' of length
`length'.

Return value
============

   A pointer to `cFind' in `buffer' or NULL if it wasn't found.

memind()
********

Syntax
======

     #define LSW1_memIO
     #include <swing.h>
     
     int memind(const void *buffer, const char cFind, const int length);

Description
===========

   Finds the character `cFind' in memory block `buffer' of length
`length'.

Return value
============

   The index of `cFind' in `buffer' or -1 if it isn't there.

strind()
********

Syntax
======

     #define LSW1_memIO
     #include <swing.h>
     
     int strind(const void *buffer, const char cFind);

Description
===========

   Finds a character `cFind' in NULL-terminated string `buffer'.

Return value
============

   The index of `cFind' in `buffer' or -1 if it isn't there.

The Source Code
***************

   Contrary to most libraries available for DJGPP today, this library
was not published under GNU Public License or GNU Library Public
License. I'm still thinking about doing that, but for the time being, I
won't. Still, I do believe in the concept of sharing source code, and I
am willing to do so.  Should you want to have parts of the source code
of this library, you can mail me about it, and tell me why you want the
source code - what you want to use it for. I will the consider your
request and possibly send you the source code and/or the algorithm it
was based on.

Registering
***********

   You can register your copy of the RLSystems Swing Library V1 FOR
FREE by mailing me at <dlanor@dds.nl>

Why register?
=============

   There are two very simple reasons why you should register this
library:
  1. It may save you money: you will also be registered if this library
     ever becomes shareware in stead of freeware (what it is now), so
     you won't ever have to pay for it.

  2. It saves time: you will be updated whenever I release a new version
     of this library, so you won't have to go to the trouble of mailing
     me to ask for a new version, or looking up my site to see if I've
     put it on the web yet - which I do far less often than I release
     new versions, which I don't do very often either.

How do I register?
==================

   First, there are four things you can register, which all include this
library and any of which you can register (for free at this time):
   * The RLSystems Swing Library V1 - the library, it's documentation,
     and nothing more. You will receive only lsw1???b.zip when I
     release a new version of the library.

   * The RLSystems Software Development Kit for DJGPP V1 - the library,
     it's documentation and the source code for the UUE project (a
     character encoder/decoder). You will receive sdk1???b.zip when
     ever either LSW1 or UUE is changed.

   * The Engine Model by Dlanor Blytkerchan - The Engine Model article
     in PDF format, this library, it's documentation and source code of
     the UUE project. You will receive model???.zip whenever I release
     an update of the article, or a follow-up article referencing the
     Engine Model. You will also receive sdk1???b.zip when ever either
     LSW1 or UUE is changed.

   * The RLSystems VGA Planets Software Development Kit for DJGPP - the
     VGA Planets I/O Library for VGA Planets V3 by Tim Wisseman, it's
     documentation, this library, it's documentation, the Gator Watcher
     utility for VGA Planets w/ complete source code under GPL. You
     will receive vsd1???.zip whenever VPL3, LSW1, or the Gator Watcher
     changes.
   Registering is very simple: just mail me at <dlanor@dds.nl> and tell
me what you want to register. You will receive the most recent copy and
be added to the binary distribution list, so you will receive a new
version whenever I release one.

Contributing to this library
****************************

   You can contribute to this library in one of four ways:

  1. Send me source code! - Just send me the source code of what ever
     you want added to the library, and tell me to which module it
     should be added, and why. I will decide whether or not to install
     it, and might alter it here or there, but in any case, I will tell
     you what I did with it.

  2. Send me the specs - Just send me the specs of something you would
     like to see added to the library - e.g. the christian/muslim/jewish
     holidays to the Date and Time module. Tell me why you want it to
     be added and to which module, and I'll let you know what I did
     with it.

  3. Send me money! - Just mail me for my address, and send money so I
     can keep going.

  4. Send me your comments! - Tell me what you think of the library, and
     what I should alter about it (if anything). I'll take any comment
     into account.

   Currently, the contributers to this library (including myself) are:

   * Dlanor Blytkerchan <dlanor@dds.nl> - responsible for the entire
     library, it's setup, and the supervision.

   * Ayalp <ayalp_dc@hotmail.com> - author of part of the Date and Time
     module, under Dlanor's supervision.

About The Author
****************

   The author of this library and of The Engine Model is known to the
internet community as Dlanor Blytkerchan. You can reach him by sending
an E-mail to <dlanor@dds.nl>.

   Dlanor Blytkerchan has been alive as such since the end of the '80s
- before that he was only known by his name IRL. All the significant
software Dlanor ever produced was produced under the name Dlanor
Blytkerchan and/or RLSystems. The very first of the RLSystems software
was published in a local BBS, which no longer exists. At later times,
the software was primarily put on the web, at a page that is still in
use to a certain extent. It's URL is <http://huizen.dds.nl/~dlanor>.

   Other useful things from this author are:
   * Libraries
        - The RLSystems VGA Planets I/O Library for DJGPP - provides
          nigh complete access to the host data files for VGA Planets
          V3 by Tim Wisseman.

        - The RLSystems CRC Library - provides 16-bit, 32-bit, 32-bit
          Adler and 64-bit CRCs to make sure your data is safe from
          corruption - unlike the government.

   * Software Development Kits
        - The RLSystems Software Development Kit for DJGPP - anything
          you need to write programs according to the Engine Model and
          an example program.

        - The RLSystems VGA Planets Software Development Kit for DJGPP -
          anything you need to write host-side add-ons for VGA Planets
          V3 by Tim Wisseman

   * VGA Planets software:
        - RLSystems Gators

        - RLSystems Starbase Enhancer

        - RLSystems Trampoline Device

        - RLSystems Spy add-on

        - RLSystems Host Data Validator

        - RLSystems CheckTurn

   * and more..

Function Index
**************

addError:
          See ``addError()''.
beep:
          See ``beep()''.
cancel:
          See ``cancel()''.
closeLogFile:
          See ``closeLogFile''.
copyPath:
          See ``copyPath()''.
currentTime:
          See ``currentTime''.
currentTimeNum:
          See ``currentTimeNum''.
dateToDay:
          See ``dateToDay''.
dateToNum:
          See ``dateToNum''.
daysInMonth:
          See ``daysInMonth''.
daysInYear:
          See ``daysInYear''.
done:
          See ``done()''.
doneHousekeeping:
          See ``doneHousekeeping()''.
duelprint:
          See ``duelprint''.
duelprinterror:
          See ``duelprinterror''.
flength:
          See ``flength()''.
handle:
          See ``handle()''.
hex:
          See ``hex()''.
hex2Int:
          See ``hex2Int()''.
initHousekeeping:
          See ``initHousekeeping()''.
initSwing:
          See ``initSwing()''.
invert:
          See ``invert()''.
isFatal:
          See ``isFatal()''.
isLeap:
          See ``isLeap''.
isValidDate:
          See ``isValidDate''.
isValidDay:
          See ``isValidDay''.
isValidMonth:
          See ``isValidMonth''.
isValidTime:
          See ``isValidTime''.
isValidYear:
          See ``isValidYear''.
lCase:
          See ``lCase()''.
left:
          See ``left()''.
memind:
          See ``memind()''.
memrchr:
          See ``memrchr()''.
memspn:
          See ``memspn()''.
memstr:
          See ``memstr()''.
numToDate:
          See ``numToDate''.
numToDay:
          See ``numToDay''.
numToTime:
          See ``numToTime''.
openLogFile:
          See ``openLogFile''.
removeError:
          See ``removeError()''.
right:
          See ``right()''.
scan:
          See ``scan''.
scanDate:
          See ``scanDate''.
scanKey:
          See ``scanKey''.
scanNumber:
          See ``scanNumber''.
scanPercentage:
          See ``scanPercentage''.
scanTime:
          See ``scanTime''.
str:
          See ``str()''.
strind:
          See ``strind()''.
timeToNum:
          See ``timeToNum''.
uCase:
          See ``uCase()''.
val:
          See ``val()''.
warning:
          See ``warning()''.
